diff --git a/.github/workflows/cypress.yml b/.github/workflows/cypress.yml index 09ee3b5a..ec6043bc 100644 --- a/.github/workflows/cypress.yml +++ b/.github/workflows/cypress.yml @@ -66,10 +66,10 @@ jobs: - name: Test run: npm run cypress:run env: - CYPRESS_TWITTER_API_KEY: ${{ secrets.TWITTER_API_KEY }} - CYPRESS_TWITTER_API_SECRET: ${{ secrets.TWITTER_API_SECRET }} - CYPRESS_TWITTER_ACCESS_TOKEN: ${{ secrets.TWITTER_ACCESS_TOKEN }} - CYPRESS_TWITTER_ACCESS_SECRET: ${{ secrets.TWITTER_ACCESS_SECRET }} + CYPRESS_TWITTER_API_KEY: ${{ secrets.TWITTER_API_KEY_V2 }} + CYPRESS_TWITTER_API_SECRET: ${{ secrets.TWITTER_API_SECRET_V2 }} + CYPRESS_TWITTER_ACCESS_TOKEN: ${{ secrets.TWITTER_ACCESS_TOKEN_V2 }} + CYPRESS_TWITTER_ACCESS_SECRET: ${{ secrets.TWITTER_ACCESS_SECRET_V2 }} - name: Upload artifacts uses: actions/upload-artifact@v2 diff --git a/.wordpress-org/screenshot-1.png b/.wordpress-org/screenshot-1.png index 06ee489a..ecda3116 100644 Binary files a/.wordpress-org/screenshot-1.png and b/.wordpress-org/screenshot-1.png differ diff --git a/.wordpress-org/screenshot-2.png b/.wordpress-org/screenshot-2.png index ecda3116..e28a5636 100644 Binary files a/.wordpress-org/screenshot-2.png and b/.wordpress-org/screenshot-2.png differ diff --git a/.wordpress-org/screenshot-3.gif b/.wordpress-org/screenshot-3.gif new file mode 100644 index 00000000..3ac28044 Binary files /dev/null and b/.wordpress-org/screenshot-3.gif differ diff --git a/.wordpress-org/screenshot-3.png b/.wordpress-org/screenshot-3.png deleted file mode 100644 index e28a5636..00000000 Binary files a/.wordpress-org/screenshot-3.png and /dev/null differ diff --git a/.wordpress-org/screenshot-4.png b/.wordpress-org/screenshot-4.png new file mode 100644 index 00000000..06ee489a Binary files /dev/null and b/.wordpress-org/screenshot-4.png differ diff --git a/CHANGELOG.md b/CHANGELOG.md index d7d86429..deea3aed 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,7 +6,24 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), ## [Unreleased] - TBD -## [1.3.0] - 2023-01-19 +## [2.0.0] - 2023-05-16 +**Autoshare for Twitter 2.0.0 utilizes [Twitter's v2 API](https://developer.twitter.com/en/products/twitter-api). If you have not already done so, please [migrate your app](https://developer.twitter.com/en/portal/projects-and-apps) to Twitter's v2 API to continue using Autoshare for Twitter. [Learn more about migrating here](https://developer.twitter.com/en/docs/twitter-api/migrate/ready-to-migrate).** + +### Added +- Migrated to Twitter API v2 (props [@iamdharmesh](https://github.com/iamdharmesh), [@jeffpaul](https://github.com/jeffpaul), [@ravinderk](https://github.com/ravinderk), [@Sidsector9](https://github.com/Sidsector9) via [#229](https://github.com/10up/autoshare-for-twitter/pull/229)). + +### Changed +- Bump WordPress "tested up to" version 6.2 (props [@Sidsector9](https://github.com/Sidsector9), [@iamdharmesh](https://github.com/iamdharmesh) via [#228](https://github.com/10up/autoshare-for-twitter/pull/228)). +- Update plugin settings and guidelines to set up a Twitter app (props [@iamdharmesh](https://github.com/iamdharmesh), [@jeffpaul](https://github.com/jeffpaul), [@ravinderk](https://github.com/ravinderk) [@Sidsector9](https://github.com/Sidsector9) via [#229](https://github.com/10up/autoshare-for-twitter/pull/229)). +- Updated documentation (props [@jeffpaul](https://github.com/jeffpaul), [@iamdharmesh](https://github.com/iamdharmesh) via [#231](https://github.com/10up/autoshare-for-twitter/pull/231)). + +### Security +- Bump `simple-git` from 3.15.1 to 3.16.0 (props [@dependabot](https://github.com/apps/dependabot), [@iamdharmesh](https://github.com/iamdharmesh) via [#221](https://github.com/10up/autoshare-for-twitter/pull/221)). +- Bump `http-cache-semantics` from 4.1.0 to 4.1.1 (props [@dependabot](https://github.com/apps/dependabot), [@iamdharmesh](https://github.com/iamdharmesh) via [#222](https://github.com/10up/autoshare-for-twitter/pull/222)). +- Bump `@sideway/formula` from 3.0.0 to 3.0.1 (props [@dependabot](https://github.com/apps/dependabot), [@iamdharmesh](https://github.com/iamdharmesh) via [#223](https://github.com/10up/autoshare-for-twitter/pull/223)). +- Bump `webpack` from 5.74.0 to 5.76.0 (props [@dependabot](https://github.com/apps/dependabot), [@iamdharmesh](https://github.com/iamdharmesh) via [#224](https://github.com/10up/autoshare-for-twitter/pull/224)). + +## [1.3.0] - 2023-01-20 ### Added - "Tweet now" functionality (props [@Sidsector9](https://github.com/Sidsector9), [@iamdharmesh](https://github.com/iamdharmesh), [@cadic](https://github.com/cadic), [@jeffpaul](https://github.com/jeffpaul), [@linawiezkowiak](https://github.com/linawiezkowiak), [@oszkarnagy](https://github.com/oszkarnagy) via [#188](https://github.com/10up/autoshare-for-twitter/pull/188)). - Toggle for adding/removing featured image from the tweet (props [@Sidsector9](https://github.com/Sidsector9), [@iamdharmesh](https://github.com/iamdharmesh), [@cadic](https://github.com/cadic), [@jeffpaul](https://github.com/jeffpaul), [@linawiezkowiak](https://github.com/linawiezkowiak), [@oszkarnagy](https://github.com/oszkarnagy) via [#188](https://github.com/10up/autoshare-for-twitter/pull/188)). @@ -180,6 +197,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), - Initial closed source release (props [@scottlee](https://github.com/scottlee/)). [Unreleased]: https://github.com/10up/autoshare-for-twitter/compare/trunk...develop +[2.0.0]: https://github.com/10up/autoshare-for-twitter/compare/1.3.0...2.0.0 [1.3.0]: https://github.com/10up/autoshare-for-twitter/compare/1.2.1...1.3.0 [1.2.1]: https://github.com/10up/autoshare-for-twitter/compare/1.2.0...1.2.1 [1.2.0]: https://github.com/10up/autoshare-for-twitter/compare/1.1.2...1.2.0 diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 6d7a60fd..ff5075e5 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -34,11 +34,12 @@ The develop branch is the development branch which means it contains the next ve 4. Props: update `CREDITS.md` file with any new contributors, confirm maintainers are accurate. 5. New files: Check to be sure any new files/paths that are unnecessary in the production version are included in `.distignore`. 6. Readme updates: Make any other readme changes as necessary. `README.md` is geared toward GitHub and `readme.txt` contains WordPress.org-specific content. The two are slightly different. -7. Merge: Make a non-fast-forward merge from your release branch to `develop` (or merge the pull request), then do the same for `develop` into `trunk` (`git checkout trunk && git merge --no-ff develop`). `trunk` contains the stable development version. +7. Merge: Make a non-fast-forward merge from your release branch to `develop` (or merge the pull request), then do the same for `develop` into `trunk`, ensuring you pull the most recent changes into `develop` first (`git checkout develop && git pull origin develop && git checkout trunk && git merge --no-ff develop`). `trunk` contains the stable development version. 8. Push: Push your `trunk` branch to GitHub (e.g. `git push origin trunk`). -9. Test the pre-release ZIP locally by downloading it from the **Build release zip** action artifact to ensure the plugin doesn't break after release. -10. Release: Create a [new release](https://github.com/10up/autoshare-for-twitter/releases/new), naming the tag and the release with the new version number, and targeting the `trunk` branch. Paste the changelog from `CHANGELOG.md` into the body of the release and include a link to the [closed issues on the milestone](https://github.com/10up/autoshare-for-twitter/milestone/#?closed=1). -11. SVN: Wait for the [GitHub Action](https://github.com/10up/autoshare-for-twitter/actions/workflows/deploy-to-wpdotorg.yml) to finish deploying to the WordPress.org repository. If all goes well, users with SVN commit access for that plugin will receive an emailed diff of changes. -12. Check WordPress.org: Ensure that the changes are live on https://wordpress.org/plugins/autoshare-for-twitter/. This may take a few minutes. -13. Close the milestone: Edit the [milestone](https://github.com/10up/autoshare-for-twitter/milestone/#) with release date (in the `Due date (optional)` field) and link to GitHub release (in the `Description` field), then close the milestone. -14. Punt incomplete items: If any open issues or PRs which were milestoned for `X.Y.Z` do not make it into the release, update their milestone to `X+1.0.0`, `X.Y+1.0`, `X.Y.Z+1`, or `Future Release` +9. [Compare](https://github.com/10up/autoshare-for-twitter/compare/trunk...develop) `trunk` to `develop` to ensure no additional changes were missed. +10. Test the pre-release ZIP locally by [downloading](https://github.com/10up/autoshare-for-twitter/actions/workflows/build-release-zip.yml) it from the Build release zip action artifact and installing it locally. Ensure this zip has all the files we expect, that it installs and activates correctly and that all basic functionality is working. +11. Release: Create a [new release](https://github.com/10up/autoshare-for-twitter/releases/new), naming the tag and the release with the new version number, and targeting the `trunk` branch. Paste the changelog from `CHANGELOG.md` into the body of the release and include a link to the [closed issues on the milestone](https://github.com/10up/autoshare-for-twitter/milestone/#?closed=1). +12. SVN: Wait for the [GitHub Action](https://github.com/10up/autoshare-for-twitter/actions/workflows/deploy-to-wpdotorg.yml) to finish deploying to the WordPress.org repository. If all goes well, users with SVN commit access for that plugin will receive an emailed diff of changes. +13. Check WordPress.org: Ensure that the changes are live on [WordPress.org](https://wordpress.org/plugins/autoshare-for-twitter/). This may take a few minutes. +14. Close the milestone: Edit the [milestone](https://github.com/10up/autoshare-for-twitter/milestone/#) with release date (in the `Due date (optional)` field) and link to GitHub release (in the `Description` field), then close the milestone. +15. Punt incomplete items: If any open issues or PRs which were milestoned for `X.Y.Z` do not make it into the release, update their milestone to `X+1.0.0`, `X.Y+1.0`, `X.Y.Z+1`, or `Future Release` diff --git a/README.md b/README.md index 10af0ffa..aa41b66e 100644 --- a/README.md +++ b/README.md @@ -11,8 +11,54 @@ ## Overview +Autoshare for Twitter automatically tweets your posts as soon as they’re published. Once you hit the Publish button, the plugin sends your post’s title, featured image, and link to Twitter, along with a custom message. + +| Create post screen with Autoshare for Twitter options | Published post screen with Autoshare for Twitter options. | +| -------------- | ---------------- | +| [](.wordpress-org/screenshot-1.png) | [](.wordpress-org/screenshot-2.png) | + +Unlike a myriad of other social media, multitool solutions, Autoshare for Twitter is built solely for Twitter. It focuses on doing one thing and does it well, with the code and interface craftsmanship we apply to every project. + +With Autoshare for Twitter, developers can further customize nearly everything about the tweets, including the image, author, and link, using an extensive set of hooks built into the code. Among its other features, the WordPress plugin: + +* Works in both the classic and new block editors. +* Becomes part of the pre-publish checklist step that’s part of the new block editor. +* Posts a high-quality featured image with your tweet. +* Counts characters to keep you under the tweet limit. +* Adds a link to the tweet in the block editor sidebar. + +| Autoshare For Twitter block editor sidebar panel | Autoshare for Twitter Settings, found under `Settings` > `Autoshare for Twitter`. | +| --------------- | --------------- | +|[](.wordpress-org/screenshot-3.gif) | [](.wordpress-org/screenshot-4.png)| + **Disclaimer:** _TWITTER, TWEET, RETWEET and the Twitter logo are trademarks of Twitter, Inc. or its affiliates._ +## Requirements + +- PHP 7.4+ +- [WordPress](http://wordpress.org) 5.7+ + +## Installation + +1. Install the plugin via the plugin installer, either by searching for it or uploading a .ZIP file. +2. Activate the plugin. +3. Save Twitter connection settings, found under `Settings` > `Autoshare for Twitter`. + +## Plugin Compatibility + +### Distributor + +When using with 10up's [Distributor plugin](https://github.com/10up/distributor), posts that are distributed will not be autoshared if they are already tweeted from the origin site. Autoshare for Twitter tracks posts that have been tweeted in post meta to avoid "double tweeting". To avoid this behavior, use the `dt_blacklisted_meta` filter to exclude the 'autoshare_for_twitter_status' meta value from being distributed : + +```php +add_filter( 'dt_blacklisted_meta', function( $blacklisted_metas ) { + $blacklisted_metas[] = 'autoshare_for_twitter_status'; + return $blacklisted_metas; +} ) +``` + +## Developers + **Note:** Posts and pages are supported by default. Developers can use the `autoshare_for_twitter_default_post_types` filter to change the default supported post types (for more, see #25). The plugin namespace changed to just 'autoshare' as of version 1.0.0. Custom post types can now be opted into autoshare features like so: @@ -41,38 +87,6 @@ function enable_autoshare_by_default_for_core_post_type( $enabled, $post_type ) add_filter( 'autoshare_for_twitter_enabled_default', 'enable_autoshare_by_default_for_core_post_type', 10, 2 ); ``` -## Plugin Compatibility - -### Distributor - -When using with 10up's [Distributor plugin](https://github.com/10up/distributor), posts that are distributed will not be autoshared if they are already tweeted from the origin site. Autoshare for Twitter tracks posts that have been tweeted in post meta to avoid "double tweeting". To avoid this behavior, use the `dt_blacklisted_meta` filter to exclude the 'autoshare_for_twitter_status' meta value from being distributed : - -```php -add_filter( 'dt_blacklisted_meta', function( $blacklisted_metas ) { - $blacklisted_metas[] = 'autoshare_for_twitter_status'; - return $blacklisted_metas; -} ) -``` - -| Autoshare for Twitter Settings, found under `Settings` > `Autoshare for Twitter`. | -| --------------- | -|[](.wordpress-org/screenshot-1.png)| - -| Create post screen with Autoshare for Twitter options | Published post screen with Autoshare for Twitter options. | -| -------------- | ---------------- | -| [](.wordpress-org/screenshot-2.png) | [](.wordpress-org/screenshot-3.png) | - -## Requirements - -- PHP 7.4+ -- [WordPress](http://wordpress.org) 5.7+ - -## Installation - -1. Install the plugin via the plugin installer, either by searching for it or uploading a .ZIP file. -2. Activate the plugin. -3. Save Twitter connection settings, found under `Settings` > `Autoshare for Twitter`. - ## FAQs ### Does this plugin work with Gutenberg? diff --git a/assets/js/admin-autoshare-for-twitter-classic-editor.js b/assets/js/admin-autoshare-for-twitter-classic-editor.js new file mode 100644 index 00000000..473f6da0 --- /dev/null +++ b/assets/js/admin-autoshare-for-twitter-classic-editor.js @@ -0,0 +1,246 @@ +/** + * Handles the Autoshare JS. + * + * @todo soooo much dependency :facepalm: + */ +(function($) { + 'use strict'; + + var $tweetPost = $('#autoshare-for-twitter-enable'), + $icon = $('#autoshare-for-twitter-icon'), + $tweetText = $('#autoshare-for-twitter-text'), + $editLink = $('#autoshare-for-twitter-edit'), + $editBody = $('#autoshare-for-twitter-override-body'), + $hideLink = $('.cancel-tweet-text'), + $allowTweetImage = $('#autoshare-for-twitter-tweet-allow-image'), + errorMessageContainer = document.getElementById('autoshare-for-twitter-error-message'), + counterWrap = document.getElementById('autoshare-for-twitter-counter-wrap'), + allowTweetImageWrap = $('.autoshare-for-twitter-tweet-allow-image-wrap'), + limit = 280; + const { __, sprintf } = wp.i18n; + + // Add enabled class if checked + if ($tweetPost.prop('checked')) { + $icon.addClass('enabled'); + } + + // Event handlers. + $tweetPost.on('click', handleRequest); + $tweetText.change(handleRequest); + $tweetPost.change(toggleAllowImageVisibility); + $allowTweetImage.change(handleRequest); + $editLink.on('click', function() { + $editBody.slideToggle(); + updateRemainingField(); + $(this).hide(); + }); + $tweetText.on('keyup', function() { + updateRemainingField(); + }); + $hideLink.on('click', function(e) { + e.preventDefault(); + $('#autoshare-for-twitter-override-body').slideToggle(); + $editLink.show(); + }); + + // Runs on page load to auto-enable posts to be tweeted + window.onload = function(event) { + if ('' === adminAutoshareForTwitter.currentStatus) { + handleRequest(event, true); + } + updateRemainingField(); + }; + + /** + * Callback for failed requests. + */ + function onRequestFail(error) { + var errorText = ''; + if ('statusText' in error && 'status' in error) { + errorText = `${adminAutoshareForTwitter.errorText} ${error.status}: ${error.statusText}`; + } else { + errorText = adminAutoshareForTwitter.unkonwnErrorText; + } + + errorMessageContainer.innerText = errorText; + + $icon.removeClass('pending'); + $tweetPost.prop('checked', false); + $('#submit').attr('disabled', true); + } + + /** + * AJAX handler + * @param event + */ + function handleRequest(event, status = $tweetPost.prop('checked')) { + var data = {}; + data[adminAutoshareForTwitter.enableAutoshareKey] = status; + data[adminAutoshareForTwitter.tweetBodyKey] = $tweetText.val(); + data[adminAutoshareForTwitter.allowTweetImageKey] = $allowTweetImage.prop('checked'); + $('#submit').attr('disabled', true); + + wp.apiFetch({ + url: adminAutoshareForTwitter.restUrl, + data: data, + method: 'POST', + parse: false, // We'll check the response for errors. + }) + .then(function(response) { + if (!response.ok) { + throw response; + } + + return response.json(); + }) + .then(function(data) { + errorMessageContainer.innerText = ''; + + $icon.removeClass('pending'); + if (data.enabled) { + $icon.removeClass('disabled'); + $icon.addClass('enabled'); + $tweetPost.prop('checked', true); + } else { + $icon.removeClass('enabled'); + $icon.addClass('disabled'); + $tweetPost.prop('checked', false); + } + + if (data.allowImage) { + $allowTweetImage.prop('checked', true); + } else { + $allowTweetImage.prop('checked', false); + } + + $('#submit').attr('disabled', false); + }) + .catch(onRequestFail); + } + + /** + * Updates the counter + */ + function updateRemainingField() { + let permalinkLength = 0; + if ( $('#sample-permalink').length ) { + permalinkLength = $('#sample-permalink').text().length + } + // +5 because of the space between body and URL and the ellipsis. + permalinkLength += 5; + + var count = $tweetText.val().length + permalinkLength; + $tweetText.attr('maxlength', limit - permalinkLength); + + $(counterWrap).text(count); + + // Toggle the .over-limit class. + if (limit <= count) { + counterWrap.classList.remove('near-limit'); + counterWrap.classList.add('over-limit'); + /* translators: %d is tweet message character count */ + $(counterWrap).text( sprintf( __( '%d - Too Long!', 'autoshare-for-twitter' ), count ) ); + } else if (240 <= count) { + counterWrap.classList.remove('over-limit'); + counterWrap.classList.add('near-limit'); + /* translators: %d is tweet message character count */ + $(counterWrap).text( sprintf( __( '%d - Getting Long!', 'autoshare-for-twitter' ), count ) ); + } else { + counterWrap.classList.remove('near-limit'); + counterWrap.classList.remove('over-limit'); + } + } + + // Update the counter when the permalink is changed. + $( '#titlediv' ).on( 'focus', '.edit-slug', function() { + updateRemainingField(); + }); + + /** + * Helper for toggling classes to indicate something is happening. + */ + function pendingStatus() { + $icon.toggleClass('pending'); + $icon.removeClass('enabled'); + $icon.removeClass('disabled'); + } + + // Show/Hide "Use featured image in Tweet" checkbox. + if ( allowTweetImageWrap && wp.media.featuredImage ) { + toggleAllowImageVisibility(); + // Listen event for add/remove featured image. + wp.media.featuredImage.frame().on( 'select', toggleAllowImageVisibility ); + $('#postimagediv').on( 'click', '#remove-post-thumbnail', toggleAllowImageVisibility ); + } + + /** + * Show/Hide "Use featured image in Tweet" checkbox. + */ + function toggleAllowImageVisibility( event ) { + let hasMedia = wp.media.featuredImage.get(); + // Handle remove post thumbnail click + if( event && event.target && 'remove-post-thumbnail' === event.target.id && 'click' === event.type ) { + hasMedia = -1; + } + + const tweetNow = $('#tweet_now').length; + const autoshareEnabled = $tweetPost.prop('checked'); + // Autoshare is enabled and post has featured image. + if ( hasMedia > 0 && ( autoshareEnabled || tweetNow ) ) { + allowTweetImageWrap.show(); + } else { + allowTweetImageWrap.hide(); + } + } + + // Tweet Now functionality. + $('#tweet_now').on('click', function() { + $("#autoshare-for-twitter-error-message").html(''); + $(this).addClass("disabled"); + $(".autoshare-for-twitter-tweet-now-wrapper span.spinner").addClass("is-active"); + + const postId = $("#post_ID").val(); + const body = new FormData(); + body.append( 'action', adminAutoshareForTwitter.retweetAction ); + body.append( 'nonce', adminAutoshareForTwitter.nonce ); + body.append( 'post_id', postId ); + body.append( 'is_classic', 1 ); + + // Send request to Tweet now. + fetch( ajaxurl, { + method: 'POST', + body, + } ) + .then((response) => response.json()) + .then((response) => { + if ( + response && response.data && + ( ( response.success && response.data.message ) || ( false === response.success && false === response.data.is_retweeted) ) + ) { + $('.autoshare-for-twitter-status-logs-wrapper').html(response.data.message); + } else { + $("#autoshare-for-twitter-error-message").html(adminAutoshareForTwitter.unknownErrorText); + } + }) + .catch((error) => { + if(error.message){ + $("#autoshare-for-twitter-error-message").html(error.message); + } else { + $("#autoshare-for-twitter-error-message").html(adminAutoshareForTwitter.unknownErrorText); + } + }) + .finally(() => { + $(this).removeClass("disabled"); + $(".autoshare-for-twitter-tweet-now-wrapper span.spinner").removeClass("is-active"); + }); + }); + + // Toggle Tweet Now panel + jQuery("#autoshare_for_twitter_metabox .tweet-now-button").on("click", function(e){ + e.preventDefault(); + $editBody.show(); + jQuery(this).find('span').toggleClass('dashicons-arrow-up-alt2'); + jQuery(".autoshare-for-twitter-tweet-now-wrapper").slideToggle(); + }); + +})(jQuery); diff --git a/assets/js/admin-autoshare-for-twitter.js b/assets/js/admin-autoshare-for-twitter.js index cf38e319..c7718511 100644 --- a/assets/js/admin-autoshare-for-twitter.js +++ b/assets/js/admin-autoshare-for-twitter.js @@ -1,245 +1,14 @@ -/** - * Handles the Autoshare JS. - * - * @todo soooo much dependency :facepalm: - */ (function($) { 'use strict'; - var $tweetPost = $('#autoshare-for-twitter-enable'), - $icon = $('#autoshare-for-twitter-icon'), - $tweetText = $('#autoshare-for-twitter-text'), - $editLink = $('#autoshare-for-twitter-edit'), - $editBody = $('#autoshare-for-twitter-override-body'), - $hideLink = $('.cancel-tweet-text'), - $allowTweetImage = $('#autoshare-for-twitter-tweet-allow-image'), - errorMessageContainer = document.getElementById('autoshare-for-twitter-error-message'), - counterWrap = document.getElementById('autoshare-for-twitter-counter-wrap'), - allowTweetImageWrap = $('.autoshare-for-twitter-tweet-allow-image-wrap'), - limit = 280; - const { __, sprintf } = wp.i18n; - - // Add enabled class if checked - if ($tweetPost.prop('checked')) { - $icon.addClass('enabled'); - } - - // Event handlers. - $tweetPost.on('click', handleRequest); - $tweetText.change(handleRequest); - $tweetPost.change(toggleAllowImageVisibility); - $allowTweetImage.change(handleRequest); - $editLink.on('click', function() { - $editBody.slideToggle(); - updateRemainingField(); - $(this).hide(); - }); - $tweetText.on('keyup', function() { - updateRemainingField(); - }); - $hideLink.on('click', function(e) { - e.preventDefault(); - $('#autoshare-for-twitter-override-body').slideToggle(); - $editLink.show(); - }); - - // Runs on page load to auto-enable posts to be tweeted - window.onload = function(event) { - if ('' === adminAutoshareForTwitter.currentStatus) { - handleRequest(event, true); - } - updateRemainingField(); - }; - - /** - * Callback for failed requests. - */ - function onRequestFail(error) { - var errorText = ''; - if ('statusText' in error && 'status' in error) { - errorText = `${adminAutoshareForTwitter.errorText} ${error.status}: ${error.statusText}`; - } else { - errorText = adminAutoshareForTwitter.unkonwnErrorText; - } - - errorMessageContainer.innerText = errorText; - - $icon.removeClass('pending'); - $tweetPost.prop('checked', false); - $('#submit').attr('disabled', true); - } - - /** - * AJAX handler - * @param event - */ - function handleRequest(event, status = $tweetPost.prop('checked')) { - var data = {}; - data[adminAutoshareForTwitter.enableAutoshareKey] = status; - data[adminAutoshareForTwitter.tweetBodyKey] = $tweetText.val(); - data[adminAutoshareForTwitter.allowTweetImageKey] = $allowTweetImage.prop('checked'); - $('#submit').attr('disabled', true); - - wp.apiFetch({ - url: adminAutoshareForTwitter.restUrl, - data: data, - method: 'POST', - parse: false, // We'll check the response for errors. - }) - .then(function(response) { - if (!response.ok) { - throw response; - } - - return response.json(); - }) - .then(function(data) { - errorMessageContainer.innerText = ''; - - $icon.removeClass('pending'); - if (data.enabled) { - $icon.removeClass('disabled'); - $icon.addClass('enabled'); - $tweetPost.prop('checked', true); - } else { - $icon.removeClass('enabled'); - $icon.addClass('disabled'); - $tweetPost.prop('checked', false); - } - - if (data.allowImage) { - $allowTweetImage.prop('checked', true); - } else { - $allowTweetImage.prop('checked', false); - } - - $('#submit').attr('disabled', false); - }) - .catch(onRequestFail); - } - - /** - * Updates the counter - */ - function updateRemainingField() { - let permalinkLength = 0; - if ( $('#sample-permalink').length ) { - permalinkLength = $('#sample-permalink').text().length - } - // +5 because of the space between body and URL and the ellipsis. - permalinkLength += 5; - - var count = $tweetText.val().length + permalinkLength; - $tweetText.attr('maxlength', limit - permalinkLength); - - $(counterWrap).text(count); - - // Toggle the .over-limit class. - if (limit <= count) { - counterWrap.classList.remove('near-limit'); - counterWrap.classList.add('over-limit'); - /* translators: %d is tweet message character count */ - $(counterWrap).text( sprintf( __( '%d - Too Long!', 'autoshare-for-twitter' ), count ) ); - } else if (240 <= count) { - counterWrap.classList.remove('over-limit'); - counterWrap.classList.add('near-limit'); - /* translators: %d is tweet message character count */ - $(counterWrap).text( sprintf( __( '%d - Getting Long!', 'autoshare-for-twitter' ), count ) ); - } else { - counterWrap.classList.remove('near-limit'); - counterWrap.classList.remove('over-limit'); - } - } - - // Update the counter when the permalink is changed. - $( '#titlediv' ).on( 'focus', '.edit-slug', function() { - updateRemainingField(); - }); - - /** - * Helper for toggling classes to indicate something is happening. - */ - function pendingStatus() { - $icon.toggleClass('pending'); - $icon.removeClass('enabled'); - $icon.removeClass('disabled'); - } - - // Show/Hide "Use featured image in Tweet" checkbox. - if ( allowTweetImageWrap && wp.media.featuredImage ) { - toggleAllowImageVisibility(); - // Listen event for add/remove featured image. - wp.media.featuredImage.frame().on( 'select', toggleAllowImageVisibility ); - $('#postimagediv').on( 'click', '#remove-post-thumbnail', toggleAllowImageVisibility ); - } - - /** - * Show/Hide "Use featured image in Tweet" checkbox. - */ - function toggleAllowImageVisibility( event ) { - let hasMedia = wp.media.featuredImage.get(); - // Handle remove post thumbnail click - if( event && event.target && 'remove-post-thumbnail' === event.target.id && 'click' === event.type ) { - hasMedia = -1; - } - - const tweetNow = $('#tweet_now').length; - const autoshareEnabled = $tweetPost.prop('checked'); - // Autoshare is enabled and post has featured image. - if ( hasMedia > 0 && ( autoshareEnabled || tweetNow ) ) { - allowTweetImageWrap.show(); - } else { - allowTweetImageWrap.hide(); - } - } - - // Tweet Now functionality. - $('#tweet_now').on('click', function() { - $("#autoshare-for-twitter-error-message").html(''); - $(this).addClass("disabled"); - $(".autoshare-for-twitter-tweet-now-wrapper span.spinner").addClass("is-active"); - - const postId = $("#post_ID").val(); - const body = new FormData(); - body.append( 'action', adminAutoshareForTwitter.retweetAction ); - body.append( 'nonce', adminAutoshareForTwitter.nonce ); - body.append( 'post_id', postId ); - body.append( 'is_classic', 1 ); - - // Send request to Tweet now. - fetch( ajaxurl, { - method: 'POST', - body, - } ) - .then((response) => response.json()) - .then((response) => { - if ( - response && response.data && - ( ( response.success && response.data.message ) || ( false === response.success && false === response.data.is_retweeted) ) - ) { - $('.autoshare-for-twitter-status-logs-wrapper').html(response.data.message); - } else { - $("#autoshare-for-twitter-error-message").html(adminAutoshareForTwitter.unknownErrorText); - } - }) - .catch((error) => { - if(error.message){ - $("#autoshare-for-twitter-error-message").html(error.message); - } else { - $("#autoshare-for-twitter-error-message").html(adminAutoshareForTwitter.unknownErrorText); - } - }) - .finally(() => { - $(this).removeClass("disabled"); - $(".autoshare-for-twitter-tweet-now-wrapper span.spinner").removeClass("is-active"); - }); - }); - - // Toggle Tweet Now panel - jQuery("#autoshare_for_twitter_metabox .tweet-now-button").on("click", function(e){ - e.preventDefault(); - $editBody.show(); - jQuery(this).find('span').toggleClass('dashicons-arrow-up-alt2'); - jQuery(".autoshare-for-twitter-tweet-now-wrapper").slideToggle(); - }); + // Dismiss migrate to Twitter API v2 notice + $( function() { + $( '.ast_notice' ).on( 'click', '.notice-dismiss', function( event, el ) { + var $notice = $(this).parent('.notice.is-dismissible'); + var dismiss_url = $notice.attr('data-dismiss-url'); + if ( dismiss_url ) { + $.get( dismiss_url ); + } + }); + } ); })(jQuery); diff --git a/autoshare-for-twitter.php b/autoshare-for-twitter.php index b6cd7b50..b89b570a 100644 --- a/autoshare-for-twitter.php +++ b/autoshare-for-twitter.php @@ -3,7 +3,7 @@ * Plugin Name: Autoshare for Twitter * Description: Automatically tweets the post title or custom message and a link to the post. * Disclaimer: TWITTER, TWEET, RETWEET and the Twitter logo are trademarks of Twitter, Inc. or its affiliates. - * Version: 1.3.0 + * Version: 2.0.0 * Requires at least: 5.7 * Requires PHP: 7.4 * Author: 10up @@ -20,7 +20,7 @@ } define( 'AUTOSHARE_FOR_TWITTER', __FILE__ ); -define( 'AUTOSHARE_FOR_TWITTER_VERSION', '1.3.0' ); +define( 'AUTOSHARE_FOR_TWITTER_VERSION', '2.0.0' ); define( 'AUTOSHARE_FOR_TWITTER_URL', plugin_dir_url( __FILE__ ) ); define( 'AUTOSHARE_FOR_TWITTER_PATH', plugin_dir_path( __FILE__ ) ); define( 'AUTOSHARE_FOR_TWITTER_INC', AUTOSHARE_FOR_TWITTER_PATH . 'includes/' ); @@ -41,3 +41,14 @@ * Play nice with others. */ do_action( 'autoshare_for_twitter_loaded' ); + +/** + * Register an activation hook that we can hook into. + */ +register_activation_hook( + __FILE__, + function () { + // Don't need to show migration notice to new users. + update_option( 'autoshare_migrate_to_v2_api_notice_dismissed', true ); + } +); diff --git a/composer.json b/composer.json index c6362de0..92db6e5c 100644 --- a/composer.json +++ b/composer.json @@ -15,10 +15,10 @@ ], "require-dev": { "wp-coding-standards/wpcs": "^2.2", - "dealerdirect/phpcodesniffer-composer-installer": "dev-master", + "dealerdirect/phpcodesniffer-composer-installer": "^0.7", "10up/phpcs-composer": "dev-master", - "phpunit/phpunit": "9.5.x-dev", - "yoast/phpunit-polyfills": "1.x-dev" + "phpunit/phpunit": "9.6.x-dev", + "yoast/phpunit-polyfills": "2.x-dev" }, "scripts": { "test": "phpunit", @@ -29,12 +29,15 @@ }, "minimum-stability": "dev", "config": { - "autoloader-suffix": "10upAutoshareForTwitterV130", + "platform": { + "php": "7.4" + }, + "autoloader-suffix": "10upAutoshareForTwitterV200", "allow-plugins": { "dealerdirect/phpcodesniffer-composer-installer": true } }, "require": { - "abraham/twitteroauth": "2.0.0" + "abraham/twitteroauth": "4.0.1" } } diff --git a/composer.lock b/composer.lock index b5e742d6..a6dc3497 100644 --- a/composer.lock +++ b/composer.lock @@ -4,32 +4,33 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "7813b96ab9db2d3c052d9d767ff6fd02", + "content-hash": "cc6e4242cfc2df2ee3c988aa552f8c64", "packages": [ { "name": "abraham/twitteroauth", - "version": "2.0.0", + "version": "4.0.1", "source": { "type": "git", "url": "https://github.com/abraham/twitteroauth.git", - "reference": "96f49e67baec10f5e5cb703d87be16ba01a798a5" + "reference": "b9302599e416e5c00742cf7f4455220897f8291d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/abraham/twitteroauth/zipball/96f49e67baec10f5e5cb703d87be16ba01a798a5", - "reference": "96f49e67baec10f5e5cb703d87be16ba01a798a5", + "url": "https://api.github.com/repos/abraham/twitteroauth/zipball/b9302599e416e5c00742cf7f4455220897f8291d", + "reference": "b9302599e416e5c00742cf7f4455220897f8291d", "shasum": "" }, "require": { "composer/ca-bundle": "^1.2", "ext-curl": "*", - "php": "^7.2 || ^7.3 || ^7.4 || ^8.0" + "php": "^7.4 || ^8.0 || ^8.1" }, "require-dev": { "php-vcr/php-vcr": "^1", "php-vcr/phpunit-testlistener-vcr": "dev-php-8", "phpmd/phpmd": "^2", - "phpunit/phpunit": "^8", + "phpunit/phpunit": "^8 || ^9", + "rector/rector": "^0.12.19 || ^0.13.0", "squizlabs/php_codesniffer": "^3" }, "type": "library", @@ -65,7 +66,7 @@ "issues": "https://github.com/abraham/twitteroauth/issues", "source": "https://github.com/abraham/twitteroauth" }, - "time": "2020-12-02T01:27:06+00:00" + "time": "2022-08-18T23:30:33+00:00" }, { "name": "composer/ca-bundle", @@ -73,12 +74,12 @@ "source": { "type": "git", "url": "https://github.com/composer/ca-bundle.git", - "reference": "27284c08ba8518c92516784a034817bfa0ab1cc2" + "reference": "74780ccf8c19d6acb8d65c5f39cd72110e132bbd" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/composer/ca-bundle/zipball/27284c08ba8518c92516784a034817bfa0ab1cc2", - "reference": "27284c08ba8518c92516784a034817bfa0ab1cc2", + "url": "https://api.github.com/repos/composer/ca-bundle/zipball/74780ccf8c19d6acb8d65c5f39cd72110e132bbd", + "reference": "74780ccf8c19d6acb8d65c5f39cd72110e132bbd", "shasum": "" }, "require": { @@ -126,7 +127,7 @@ "support": { "irc": "irc://irc.freenode.org/composer", "issues": "https://github.com/composer/ca-bundle/issues", - "source": "https://github.com/composer/ca-bundle/tree/main" + "source": "https://github.com/composer/ca-bundle/tree/1.3.5" }, "funding": [ { @@ -142,7 +143,7 @@ "type": "tidelift" } ], - "time": "2022-10-12T12:09:58+00:00" + "time": "2023-01-11T08:27:00+00:00" } ], "packages-dev": [ @@ -152,18 +153,19 @@ "source": { "type": "git", "url": "https://github.com/10up/phpcs-composer.git", - "reference": "2f5c3608bc03fe1ca65acf462dd7b5008f6829a0" + "reference": "2d03ba19ad5259275aa4f2287340e3d7d270196b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/10up/phpcs-composer/zipball/2f5c3608bc03fe1ca65acf462dd7b5008f6829a0", - "reference": "2f5c3608bc03fe1ca65acf462dd7b5008f6829a0", + "url": "https://api.github.com/repos/10up/phpcs-composer/zipball/2d03ba19ad5259275aa4f2287340e3d7d270196b", + "reference": "2d03ba19ad5259275aa4f2287340e3d7d270196b", "shasum": "" }, "require": { + "automattic/vipwpcs": "^2.3", "dealerdirect/phpcodesniffer-composer-installer": "*", "phpcompatibility/phpcompatibility-wp": "^2", - "squizlabs/php_codesniffer": "^3.4.0", + "squizlabs/php_codesniffer": "3.7.1", "wp-coding-standards/wpcs": "*" }, "default-branch": true, @@ -182,36 +184,84 @@ "issues": "https://github.com/10up/phpcs-composer/issues", "source": "https://github.com/10up/phpcs-composer/tree/master" }, - "time": "2021-01-08T03:03:06+00:00" + "time": "2023-04-27T01:31:26+00:00" + }, + { + "name": "automattic/vipwpcs", + "version": "2.3.3", + "source": { + "type": "git", + "url": "https://github.com/Automattic/VIP-Coding-Standards.git", + "reference": "6cd0a6a82bc0ac988dbf9d6a7c2e293dc8ac640b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Automattic/VIP-Coding-Standards/zipball/6cd0a6a82bc0ac988dbf9d6a7c2e293dc8ac640b", + "reference": "6cd0a6a82bc0ac988dbf9d6a7c2e293dc8ac640b", + "shasum": "" + }, + "require": { + "dealerdirect/phpcodesniffer-composer-installer": "^0.4.1 || ^0.5 || ^0.6.2 || ^0.7", + "php": ">=5.4", + "sirbrillig/phpcs-variable-analysis": "^2.11.1", + "squizlabs/php_codesniffer": "^3.5.5", + "wp-coding-standards/wpcs": "^2.3" + }, + "require-dev": { + "php-parallel-lint/php-console-highlighter": "^0.5", + "php-parallel-lint/php-parallel-lint": "^1.0", + "phpcompatibility/php-compatibility": "^9", + "phpcsstandards/phpcsdevtools": "^1.0", + "phpunit/phpunit": "^4 || ^5 || ^6 || ^7" + }, + "type": "phpcodesniffer-standard", + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Contributors", + "homepage": "https://github.com/Automattic/VIP-Coding-Standards/graphs/contributors" + } + ], + "description": "PHP_CodeSniffer rules (sniffs) to enforce WordPress VIP minimum coding conventions", + "keywords": [ + "phpcs", + "standards", + "wordpress" + ], + "support": { + "issues": "https://github.com/Automattic/VIP-Coding-Standards/issues", + "source": "https://github.com/Automattic/VIP-Coding-Standards", + "wiki": "https://github.com/Automattic/VIP-Coding-Standards/wiki" + }, + "time": "2021-09-29T16:20:23+00:00" }, { "name": "dealerdirect/phpcodesniffer-composer-installer", - "version": "dev-master", + "version": "v0.7.2", "source": { "type": "git", - "url": "https://github.com/PHPCSStandards/composer-installer.git", - "reference": "9838aa941e2c71d7b627be577ba1fdaf32f4f4f0" + "url": "https://github.com/Dealerdirect/phpcodesniffer-composer-installer.git", + "reference": "1c968e542d8843d7cd71de3c5c9c3ff3ad71a1db" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/PHPCSStandards/composer-installer/zipball/9838aa941e2c71d7b627be577ba1fdaf32f4f4f0", - "reference": "9838aa941e2c71d7b627be577ba1fdaf32f4f4f0", + "url": "https://api.github.com/repos/Dealerdirect/phpcodesniffer-composer-installer/zipball/1c968e542d8843d7cd71de3c5c9c3ff3ad71a1db", + "reference": "1c968e542d8843d7cd71de3c5c9c3ff3ad71a1db", "shasum": "" }, "require": { "composer-plugin-api": "^1.0 || ^2.0", - "php": ">=5.4", + "php": ">=5.3", "squizlabs/php_codesniffer": "^2.0 || ^3.1.0 || ^4.0" }, "require-dev": { "composer/composer": "*", - "ext-json": "*", - "ext-zip": "*", "php-parallel-lint/php-parallel-lint": "^1.3.1", - "phpcompatibility/php-compatibility": "^9.0", - "yoast/phpunit-polyfills": "^1.0" + "phpcompatibility/php-compatibility": "^9.0" }, - "default-branch": true, "type": "composer-plugin", "extra": { "class": "Dealerdirect\\Composer\\Plugin\\Installers\\PHPCodeSniffer\\Plugin" @@ -234,7 +284,7 @@ }, { "name": "Contributors", - "homepage": "https://github.com/PHPCSStandards/composer-installer/graphs/contributors" + "homepage": "https://github.com/Dealerdirect/phpcodesniffer-composer-installer/graphs/contributors" } ], "description": "PHP_CodeSniffer Standards Composer Installer Plugin", @@ -258,10 +308,10 @@ "tests" ], "support": { - "issues": "https://github.com/PHPCSStandards/composer-installer/issues", - "source": "https://github.com/PHPCSStandards/composer-installer" + "issues": "https://github.com/dealerdirect/phpcodesniffer-composer-installer/issues", + "source": "https://github.com/dealerdirect/phpcodesniffer-composer-installer" }, - "time": "2022-10-03T16:10:17+00:00" + "time": "2022-02-04T12:51:07+00:00" }, { "name": "doctrine/instantiator", @@ -269,27 +319,28 @@ "source": { "type": "git", "url": "https://github.com/doctrine/instantiator.git", - "reference": "10dcfce151b967d20fde1b34ae6640712c3891bc" + "reference": "0a0fa9780f5d4e507415a065172d26a98d02047b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/instantiator/zipball/10dcfce151b967d20fde1b34ae6640712c3891bc", - "reference": "10dcfce151b967d20fde1b34ae6640712c3891bc", + "url": "https://api.github.com/repos/doctrine/instantiator/zipball/0a0fa9780f5d4e507415a065172d26a98d02047b", + "reference": "0a0fa9780f5d4e507415a065172d26a98d02047b", "shasum": "" }, "require": { "php": "^7.1 || ^8.0" }, "require-dev": { - "doctrine/coding-standard": "^9", + "doctrine/coding-standard": "^9 || ^11", "ext-pdo": "*", "ext-phar": "*", "phpbench/phpbench": "^0.16 || ^1", "phpstan/phpstan": "^1.4", "phpstan/phpstan-phpunit": "^1", "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5", - "vimeo/psalm": "^4.22" + "vimeo/psalm": "^4.30 || ^5.4" }, + "default-branch": true, "type": "library", "autoload": { "psr-4": { @@ -315,7 +366,7 @@ ], "support": { "issues": "https://github.com/doctrine/instantiator/issues", - "source": "https://github.com/doctrine/instantiator/tree/1.4.x" + "source": "https://github.com/doctrine/instantiator/tree/1.5.0" }, "funding": [ { @@ -331,7 +382,7 @@ "type": "tidelift" } ], - "time": "2022-03-03T08:28:38+00:00" + "time": "2022-12-30T00:15:36+00:00" }, { "name": "myclabs/deep-copy", @@ -339,12 +390,12 @@ "source": { "type": "git", "url": "https://github.com/myclabs/DeepCopy.git", - "reference": "14daed4296fae74d9e3201d2c4925d1acb7aa614" + "reference": "928a96f585b86224ebc78f8f09d0482cf15b04f5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/14daed4296fae74d9e3201d2c4925d1acb7aa614", - "reference": "14daed4296fae74d9e3201d2c4925d1acb7aa614", + "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/928a96f585b86224ebc78f8f09d0482cf15b04f5", + "reference": "928a96f585b86224ebc78f8f09d0482cf15b04f5", "shasum": "" }, "require": { @@ -352,11 +403,12 @@ }, "conflict": { "doctrine/collections": "<1.6.8", - "doctrine/common": "<2.13.3 || >=3,<3.2.2" + "doctrine/common": "<2.13.3 || >=3 <3.2.2" }, "require-dev": { "doctrine/collections": "^1.6.8", "doctrine/common": "^2.13.3 || ^3.2.2", + "phpspec/prophecy": "^1.10", "phpunit/phpunit": "^7.5.20 || ^8.5.23 || ^9.5.13" }, "default-branch": true, @@ -383,7 +435,7 @@ ], "support": { "issues": "https://github.com/myclabs/DeepCopy/issues", - "source": "https://github.com/myclabs/DeepCopy/tree/1.11.0" + "source": "https://github.com/myclabs/DeepCopy/tree/1.x" }, "funding": [ { @@ -391,7 +443,7 @@ "type": "tidelift" } ], - "time": "2022-03-03T13:19:32+00:00" + "time": "2023-03-08T17:24:01+00:00" }, { "name": "nikic/php-parser", @@ -399,12 +451,12 @@ "source": { "type": "git", "url": "https://github.com/nikic/PHP-Parser.git", - "reference": "2f1fd784fe5560675722a1e5cbbcece5f43bf3a0" + "reference": "0ffddce52d816f72d0efc4d9b02e276d3309ef01" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/2f1fd784fe5560675722a1e5cbbcece5f43bf3a0", - "reference": "2f1fd784fe5560675722a1e5cbbcece5f43bf3a0", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/0ffddce52d816f72d0efc4d9b02e276d3309ef01", + "reference": "0ffddce52d816f72d0efc4d9b02e276d3309ef01", "shasum": "" }, "require": { @@ -415,6 +467,7 @@ "ircmaxell/php-yacc": "^0.0.7", "phpunit/phpunit": "^6.5 || ^7.0 || ^8.0 || ^9.0" }, + "default-branch": true, "bin": [ "bin/php-parse" ], @@ -447,7 +500,7 @@ "issues": "https://github.com/nikic/PHP-Parser/issues", "source": "https://github.com/nikic/PHP-Parser/tree/4.x" }, - "time": "2022-09-10T20:41:13+00:00" + "time": "2023-03-06T22:12:36+00:00" }, { "name": "phar-io/manifest", @@ -632,16 +685,16 @@ }, { "name": "phpcompatibility/phpcompatibility-paragonie", - "version": "1.3.1", + "version": "1.3.2", "source": { "type": "git", "url": "https://github.com/PHPCompatibility/PHPCompatibilityParagonie.git", - "reference": "ddabec839cc003651f2ce695c938686d1086cf43" + "reference": "bba5a9dfec7fcfbd679cfaf611d86b4d3759da26" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/PHPCompatibility/PHPCompatibilityParagonie/zipball/ddabec839cc003651f2ce695c938686d1086cf43", - "reference": "ddabec839cc003651f2ce695c938686d1086cf43", + "url": "https://api.github.com/repos/PHPCompatibility/PHPCompatibilityParagonie/zipball/bba5a9dfec7fcfbd679cfaf611d86b4d3759da26", + "reference": "bba5a9dfec7fcfbd679cfaf611d86b4d3759da26", "shasum": "" }, "require": { @@ -678,13 +731,14 @@ "paragonie", "phpcs", "polyfill", - "standards" + "standards", + "static analysis" ], "support": { "issues": "https://github.com/PHPCompatibility/PHPCompatibilityParagonie/issues", "source": "https://github.com/PHPCompatibility/PHPCompatibilityParagonie" }, - "time": "2021-02-15T10:24:51+00:00" + "time": "2022-10-25T01:46:02+00:00" }, { "name": "phpcompatibility/phpcompatibility-wp", @@ -747,19 +801,19 @@ "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "74b7413e8d9788df77e296adabd7c1f6ca801a99" + "reference": "db887088b40ae43d17b9913886df860a7035145d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/74b7413e8d9788df77e296adabd7c1f6ca801a99", - "reference": "74b7413e8d9788df77e296adabd7c1f6ca801a99", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/db887088b40ae43d17b9913886df860a7035145d", + "reference": "db887088b40ae43d17b9913886df860a7035145d", "shasum": "" }, "require": { "ext-dom": "*", "ext-libxml": "*", "ext-xmlwriter": "*", - "nikic/php-parser": "^4.14", + "nikic/php-parser": "^4.15", "php": ">=7.3", "phpunit/php-file-iterator": "^3.0.3", "phpunit/php-text-template": "^2.0.2", @@ -774,8 +828,8 @@ "phpunit/phpunit": "^9.3" }, "suggest": { - "ext-pcov": "*", - "ext-xdebug": "*" + "ext-pcov": "PHP extension that provides line coverage", + "ext-xdebug": "PHP extension that provides line coverage as well as branch and path coverage" }, "type": "library", "extra": { @@ -808,6 +862,7 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues", + "security": "https://github.com/sebastianbergmann/php-code-coverage/security/policy", "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2" }, "funding": [ @@ -816,7 +871,7 @@ "type": "github" } ], - "time": "2022-10-21T12:10:51+00:00" + "time": "2023-04-04T09:22:25+00:00" }, { "name": "phpunit/php-file-iterator", @@ -1061,20 +1116,20 @@ }, { "name": "phpunit/phpunit", - "version": "9.5.x-dev", + "version": "9.6.x-dev", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "7847a4a920f686db261da1ccc92120800822661f" + "reference": "c993f0d3b0489ffc42ee2fe0bd645af1538a63b2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/7847a4a920f686db261da1ccc92120800822661f", - "reference": "7847a4a920f686db261da1ccc92120800822661f", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/c993f0d3b0489ffc42ee2fe0bd645af1538a63b2", + "reference": "c993f0d3b0489ffc42ee2fe0bd645af1538a63b2", "shasum": "" }, "require": { - "doctrine/instantiator": "^1.3.1", + "doctrine/instantiator": "^1.3.1 || ^2", "ext-dom": "*", "ext-json": "*", "ext-libxml": "*", @@ -1103,8 +1158,8 @@ "sebastian/version": "^3.0.2" }, "suggest": { - "ext-soap": "*", - "ext-xdebug": "*" + "ext-soap": "To be able to generate mocks based on WSDL files", + "ext-xdebug": "PHP extension that provides line coverage as well as branch and path coverage" }, "bin": [ "phpunit" @@ -1112,7 +1167,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "9.5-dev" + "dev-master": "9.6-dev" } }, "autoload": { @@ -1143,7 +1198,8 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/phpunit/issues", - "source": "https://github.com/sebastianbergmann/phpunit/tree/9.5" + "security": "https://github.com/sebastianbergmann/phpunit/security/policy", + "source": "https://github.com/sebastianbergmann/phpunit/tree/9.6.7" }, "funding": [ { @@ -1159,7 +1215,7 @@ "type": "tidelift" } ], - "time": "2022-10-19T10:44:50+00:00" + "time": "2023-04-14T08:58:40+00:00" }, { "name": "sebastian/cli-parser", @@ -1531,12 +1587,12 @@ "source": { "type": "git", "url": "https://github.com/sebastianbergmann/environment.git", - "reference": "3fade0c8462024d0426a00dc1ad0a2fda0df733f" + "reference": "830c43a844f1f8d5b7a1f6d6076b784454d8b7ed" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/3fade0c8462024d0426a00dc1ad0a2fda0df733f", - "reference": "3fade0c8462024d0426a00dc1ad0a2fda0df733f", + "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/830c43a844f1f8d5b7a1f6d6076b784454d8b7ed", + "reference": "830c43a844f1f8d5b7a1f6d6076b784454d8b7ed", "shasum": "" }, "require": { @@ -1586,7 +1642,7 @@ "type": "github" } ], - "time": "2022-04-14T11:24:33+00:00" + "time": "2023-02-03T06:03:51+00:00" }, { "name": "sebastian/exporter", @@ -1904,12 +1960,12 @@ "source": { "type": "git", "url": "https://github.com/sebastianbergmann/recursion-context.git", - "reference": "e3a614438af7f71eaa6fc8e406be8a3aa5c34595" + "reference": "e75bd0f07204fec2a0af9b0f3cfe97d05f92efc1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/e3a614438af7f71eaa6fc8e406be8a3aa5c34595", - "reference": "e3a614438af7f71eaa6fc8e406be8a3aa5c34595", + "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/e75bd0f07204fec2a0af9b0f3cfe97d05f92efc1", + "reference": "e75bd0f07204fec2a0af9b0f3cfe97d05f92efc1", "shasum": "" }, "require": { @@ -1951,7 +2007,7 @@ "homepage": "https://github.com/sebastianbergmann/recursion-context", "support": { "issues": "https://github.com/sebastianbergmann/recursion-context/issues", - "source": "https://github.com/sebastianbergmann/recursion-context/tree/4.0" + "source": "https://github.com/sebastianbergmann/recursion-context/tree/4.0.5" }, "funding": [ { @@ -1959,7 +2015,7 @@ "type": "github" } ], - "time": "2022-07-30T08:13:09+00:00" + "time": "2023-02-03T06:07:39+00:00" }, { "name": "sebastian/resource-operations", @@ -1967,12 +2023,12 @@ "source": { "type": "git", "url": "https://github.com/sebastianbergmann/resource-operations.git", - "reference": "b7a390ae3651f7ba3675d8364bff396e87931554" + "reference": "20bdda85c7c585ab265c0c37ec052a019bae29c4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/b7a390ae3651f7ba3675d8364bff396e87931554", - "reference": "b7a390ae3651f7ba3675d8364bff396e87931554", + "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/20bdda85c7c585ab265c0c37ec052a019bae29c4", + "reference": "20bdda85c7c585ab265c0c37ec052a019bae29c4", "shasum": "" }, "require": { @@ -2014,7 +2070,7 @@ "type": "github" } ], - "time": "2022-06-14T05:05:56+00:00" + "time": "2023-03-25T08:11:39+00:00" }, { "name": "sebastian/type", @@ -2022,12 +2078,12 @@ "source": { "type": "git", "url": "https://github.com/sebastianbergmann/type.git", - "reference": "4d34b23933f255b0822758a44272222cac593eb4" + "reference": "75e2c2a32f5e0b3aef905b9ed0b179b953b3d7c7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/4d34b23933f255b0822758a44272222cac593eb4", - "reference": "4d34b23933f255b0822758a44272222cac593eb4", + "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/75e2c2a32f5e0b3aef905b9ed0b179b953b3d7c7", + "reference": "75e2c2a32f5e0b3aef905b9ed0b179b953b3d7c7", "shasum": "" }, "require": { @@ -2070,7 +2126,7 @@ "type": "github" } ], - "time": "2022-10-01T05:56:17+00:00" + "time": "2023-02-03T06:13:03+00:00" }, { "name": "sebastian/version", @@ -2125,18 +2181,77 @@ ], "time": "2020-09-28T06:39:44+00:00" }, + { + "name": "sirbrillig/phpcs-variable-analysis", + "version": "2.x-dev", + "source": { + "type": "git", + "url": "https://github.com/sirbrillig/phpcs-variable-analysis.git", + "reference": "dc5582dc5a93a235557af73e523c389aac9a8e88" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sirbrillig/phpcs-variable-analysis/zipball/dc5582dc5a93a235557af73e523c389aac9a8e88", + "reference": "dc5582dc5a93a235557af73e523c389aac9a8e88", + "shasum": "" + }, + "require": { + "php": ">=5.4.0", + "squizlabs/php_codesniffer": "^3.5.6" + }, + "require-dev": { + "dealerdirect/phpcodesniffer-composer-installer": "^0.7 || ^1.0", + "phpcsstandards/phpcsdevcs": "^1.1", + "phpstan/phpstan": "^1.7", + "phpunit/phpunit": "^4.8.36 || ^5.7.21 || ^6.5 || ^7.0 || ^8.0 || ^9.0", + "sirbrillig/phpcs-import-detection": "^1.1", + "vimeo/psalm": "^0.2 || ^0.3 || ^1.1 || ^4.24 || ^5.0@beta" + }, + "default-branch": true, + "type": "phpcodesniffer-standard", + "autoload": { + "psr-4": { + "VariableAnalysis\\": "VariableAnalysis/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-2-Clause" + ], + "authors": [ + { + "name": "Sam Graham", + "email": "php-codesniffer-variableanalysis@illusori.co.uk" + }, + { + "name": "Payton Swick", + "email": "payton@foolord.com" + } + ], + "description": "A PHPCS sniff to detect problems with variables.", + "keywords": [ + "phpcs", + "static analysis" + ], + "support": { + "issues": "https://github.com/sirbrillig/phpcs-variable-analysis/issues", + "source": "https://github.com/sirbrillig/phpcs-variable-analysis", + "wiki": "https://github.com/sirbrillig/phpcs-variable-analysis/wiki" + }, + "time": "2023-03-31T16:46:32+00:00" + }, { "name": "squizlabs/php_codesniffer", - "version": "dev-master", + "version": "3.7.1", "source": { "type": "git", "url": "https://github.com/squizlabs/PHP_CodeSniffer.git", - "reference": "cd5acaa651df870e8a3207926f236400361219e0" + "reference": "1359e176e9307e906dc3d890bcc9603ff6d90619" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/cd5acaa651df870e8a3207926f236400361219e0", - "reference": "cd5acaa651df870e8a3207926f236400361219e0", + "url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/1359e176e9307e906dc3d890bcc9603ff6d90619", + "reference": "1359e176e9307e906dc3d890bcc9603ff6d90619", "shasum": "" }, "require": { @@ -2148,7 +2263,6 @@ "require-dev": { "phpunit/phpunit": "^4.0 || ^5.0 || ^6.0 || ^7.0" }, - "default-branch": true, "bin": [ "bin/phpcs", "bin/phpcbf" @@ -2173,15 +2287,14 @@ "homepage": "https://github.com/squizlabs/PHP_CodeSniffer", "keywords": [ "phpcs", - "standards", - "static analysis" + "standards" ], "support": { "issues": "https://github.com/squizlabs/PHP_CodeSniffer/issues", "source": "https://github.com/squizlabs/PHP_CodeSniffer", "wiki": "https://github.com/squizlabs/PHP_CodeSniffer/wiki" }, - "time": "2022-10-21T05:57:32+00:00" + "time": "2022-06-18T07:21:10+00:00" }, { "name": "theseer/tokenizer", @@ -2286,16 +2399,16 @@ }, { "name": "yoast/phpunit-polyfills", - "version": "dev-develop", + "version": "dev-main", "source": { "type": "git", "url": "https://github.com/Yoast/PHPUnit-Polyfills.git", - "reference": "b0c727ed3fb2a6c4528c676af69651ec4f579655" + "reference": "3b59adeef77fb1c03ff5381dbb9d68b0aaff3171" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Yoast/PHPUnit-Polyfills/zipball/b0c727ed3fb2a6c4528c676af69651ec4f579655", - "reference": "b0c727ed3fb2a6c4528c676af69651ec4f579655", + "url": "https://api.github.com/repos/Yoast/PHPUnit-Polyfills/zipball/3b59adeef77fb1c03ff5381dbb9d68b0aaff3171", + "reference": "3b59adeef77fb1c03ff5381dbb9d68b0aaff3171", "shasum": "" }, "require": { @@ -2303,14 +2416,12 @@ "phpunit/phpunit": "^4.8.36 || ^5.7.21 || ^6.0 || ^7.0 || ^8.0 || ^9.0" }, "require-dev": { - "yoast/yoastcs": "^2.2.1" + "yoast/yoastcs": "^2.3.0" }, - "default-branch": true, "type": "library", "extra": { "branch-alias": { - "dev-main": "1.x-dev", - "dev-develop": "1.x-dev" + "dev-main": "2.x-dev" } }, "autoload": { @@ -2344,13 +2455,12 @@ "issues": "https://github.com/Yoast/PHPUnit-Polyfills/issues", "source": "https://github.com/Yoast/PHPUnit-Polyfills" }, - "time": "2022-08-03T05:59:50+00:00" + "time": "2023-03-30T23:39:05+00:00" } ], "aliases": [], "minimum-stability": "dev", "stability-flags": { - "dealerdirect/phpcodesniffer-composer-installer": 20, "10up/phpcs-composer": 20, "phpunit/phpunit": 20, "yoast/phpunit-polyfills": 20 @@ -2359,5 +2469,8 @@ "prefer-lowest": false, "platform": [], "platform-dev": [], - "plugin-api-version": "2.1.0" + "platform-overrides": { + "php": "7.4" + }, + "plugin-api-version": "2.3.0" } diff --git a/includes/admin/assets.php b/includes/admin/assets.php index dcb0aa15..5dc4568a 100644 --- a/includes/admin/assets.php +++ b/includes/admin/assets.php @@ -48,6 +48,14 @@ function enqueue_shared_assets() { [], AUTOSHARE_FOR_TWITTER_VERSION ); + + wp_enqueue_script( + 'admin_autoshare_for_twitter', + trailingslashit( AUTOSHARE_FOR_TWITTER_URL ) . 'assets/js/admin-autoshare-for-twitter.js', + [ 'jquery' ], + AUTOSHARE_FOR_TWITTER_VERSION, + true + ); } /** @@ -127,22 +135,15 @@ function maybe_enqueue_classic_editor_assets( $hook ) { ); } - $handle = 'admin_autoshare_for_twitter'; + $handle = 'admin_autoshare_for_twitter_classic_editor'; wp_enqueue_script( $handle, - trailingslashit( AUTOSHARE_FOR_TWITTER_URL ) . 'assets/js/admin-autoshare-for-twitter.js', + trailingslashit( AUTOSHARE_FOR_TWITTER_URL ) . 'assets/js/admin-autoshare-for-twitter-classic-editor.js', [ 'jquery', 'wp-api-fetch' ], AUTOSHARE_FOR_TWITTER_VERSION, true ); - wp_enqueue_style( - $handle, - trailingslashit( AUTOSHARE_FOR_TWITTER_URL ) . 'assets/css/admin-autoshare-for-twitter.css', - [], - AUTOSHARE_FOR_TWITTER_VERSION - ); - localize_data( $handle ); } diff --git a/includes/admin/post-meta.php b/includes/admin/post-meta.php index 12c2fb39..673e1d40 100644 --- a/includes/admin/post-meta.php +++ b/includes/admin/post-meta.php @@ -317,7 +317,7 @@ function get_tweet_status_message( $post ) { case 'error': $response_array[] = [ - 'message' => __( 'Failed to tweet: ', 'autoshare-for-twitter' ) . $tweet_meta['message'], + 'message' => __( 'Failed to tweet; ', 'autoshare-for-twitter' ) . $tweet_meta['message'], 'status' => $status, ]; @@ -434,11 +434,19 @@ function markup_published( $status_meta ) { * @return string */ function markup_error( $status_meta ) { + $learn_more = ''; + if ( 'When authenticating requests to the Twitter API v2 endpoints, you must use keys and tokens from a Twitter developer App that is attached to a Project. You can create a project via the developer portal.' === $status_meta['message'] ) { + $learn_more = sprintf( + ' %s', + esc_url( 'https://developer.twitter.com/en/docs/twitter-api/migrate/ready-to-migrate' ), + esc_html__( 'Learn more here.', 'autoshare-for-twitter' ) + ); + } return sprintf( '
', esc_html__( 'Failed to tweet', 'autoshare-for-twitter' ), - esc_html( $status_meta['message'] ) + esc_html( $status_meta['message'] ) . $learn_more ); } diff --git a/includes/admin/post-transition.php b/includes/admin/post-transition.php index 1159e316..344576ae 100644 --- a/includes/admin/post-transition.php +++ b/includes/admin/post-transition.php @@ -190,14 +190,23 @@ function validate_response( $response ) { if ( ! empty( $response->id ) ) { $validated_response = array( 'id' => $response->id, - 'created_at' => $response->created_at, + 'created_at' => gmdate( 'c' ), // Twitter API v2 doesn't return created_at. ); } else { + $errors = $response->errors; + if ( empty( $response->errors ) && ! empty( $response->detail ) ) { + $errors = array( + (object) array( + 'code' => $response->status, + 'message' => $response->detail, + ), + ); + } $validated_response = new \WP_Error( 'autoshare_for_twitter_failed', __( 'Something happened during Twitter update.', 'autoshare-for-twitter' ), - $response->errors + $errors ); } @@ -223,9 +232,12 @@ function update_autoshare_for_twitter_meta_from_response( $post_id, $data ) { // Twitter sent back an error. Most likely a duplicate message. } elseif ( is_wp_error( $data ) ) { $error_message = $data->error_data['autoshare_for_twitter_failed'][0]; - $response = array( + // translators: %d is the error code. + $error_code_text = $error_message->code ? sprintf( __( 'Error: %d. ', 'autoshare-for-twitter' ), $error_message->code ) : ''; + + $response = array( 'status' => 'error', - 'message' => sanitize_text_field( 'Error: ' . $error_message->code . '. ' . $error_message->message ), + 'message' => sanitize_text_field( $error_code_text . $error_message->message ), ); // The default fallback message. diff --git a/includes/admin/settings.php b/includes/admin/settings.php index 5999a0fc..da35a26c 100644 --- a/includes/admin/settings.php +++ b/includes/admin/settings.php @@ -125,56 +125,56 @@ function register_settings() { // API Key. add_settings_field( 'autoshare-api_key', - __( 'API key', 'autoshare-for-twitter' ), + __( 'API Key', 'autoshare-for-twitter' ), __NAMESPACE__ . '\text_field_cb', 'autoshare-for-twitter', 'autoshare-cred_section', [ 'name' => 'api_key', 'class' => 'large-text', - 'placeholder' => __( 'paste your API key here', 'autoshare-for-twitter' ), + 'placeholder' => __( 'paste your API Key here', 'autoshare-for-twitter' ), ] ); // API Secret. add_settings_field( 'autoshare-api_secret', - __( 'API secret', 'autoshare-for-twitter' ), + __( 'API Key Secret', 'autoshare-for-twitter' ), __NAMESPACE__ . '\text_field_cb', 'autoshare-for-twitter', 'autoshare-cred_section', [ 'name' => 'api_secret', 'class' => 'large-text', - 'placeholder' => __( 'paste your API secret key here', 'autoshare-for-twitter' ), + 'placeholder' => __( 'paste your API Key Secret here', 'autoshare-for-twitter' ), ] ); // Access Token. add_settings_field( 'autoshare-access_token', - __( 'Access token', 'autoshare-for-twitter' ), + __( 'Access Token', 'autoshare-for-twitter' ), __NAMESPACE__ . '\text_field_cb', 'autoshare-for-twitter', 'autoshare-cred_section', [ 'name' => 'access_token', 'class' => 'large-text', - 'placeholder' => __( 'paste your Access token secret here', 'autoshare-for-twitter' ), + 'placeholder' => __( 'paste your Access Token here', 'autoshare-for-twitter' ), ] ); // Access Secret. add_settings_field( 'autoshare-access_secret', - __( 'Access secret', 'autoshare-for-twitter' ), + __( 'Access Token Secret', 'autoshare-for-twitter' ), __NAMESPACE__ . '\text_field_cb', 'autoshare-for-twitter', 'autoshare-cred_section', [ 'name' => 'access_secret', 'class' => 'large-text', - 'placeholder' => __( 'paste your Access token secret here', 'autoshare-for-twitter' ), + 'placeholder' => __( 'paste your Access Token Secret here', 'autoshare-for-twitter' ), ] ); @@ -190,7 +190,6 @@ function register_settings() { 'placeholder' => __( 'enter your Twitter handle here', 'autoshare-for-twitter' ), ] ); - } /** @@ -326,17 +325,20 @@ function cred_section_cb() {API key and API secret key
values and paste them below. In case you skipped the onboarding process, you can create a project and an app by following Step 2. Otherwise, please skip Step 2.', 'autoshare-for-twitter' ); ?>
API secret key
values and paste them below. you can Regenerate these keys any time from the Twitter developer portal.', 'autoshare-for-twitter' ) ); ?>Callback URLs
fields to https://yourdomain.yourdomainextension and click Save
.', 'autoshare-for-twitter' ); ?>Callback URLs
fields to https://yourdomain.yourdomainextension and click Save
.', 'autoshare-for-twitter' ) ); ?>API Key and Secret
section.', 'autoshare-for-twitter' ) ); ?>API Key Secret
values and paste them below.', 'autoshare-for-twitter' ) ); ?>Access Token and Secret
section.', 'autoshare-for-twitter' ) ); ?>Access token secret
values and paste them below.', 'autoshare-for-twitter' ) ); ?>How will you use the Twitter API or Twitter Data?
section. You can find an example response below.', 'autoshare-for-twitter' ) ); ?>
- Are you planning to analyze Twitter data?
', 'autoshare-for-twitter' ) ); ?>Will your App use Tweet, Retweet, Like, Follow, or Direct Message functionality?
and fill out the Please describe your planned use of these features.
field. You can find the example response below.', 'autoshare-for-twitter' ) ); ?>Do you plan to display Tweets or aggregate data about Twitter content outside Twitter?
', 'autoshare-for-twitter' ) ); ?>Will your product, service, or analysis make Twitter content or derived information available to a government entity?
', 'autoshare-for-twitter' ) ); ?>Access Token Secret
values and paste them below.', 'autoshare-for-twitter' ) ); ?>+ tags for Twitter V2 API, 3$-4$: Opening and closing tags for migrate app, 5$-6$: Opening and closing tags for learn more. + wp_kses_post( __( 'Autoshare for Twitter now utilizes the %1$sTwitter v2 API%2$s. If you have not already done so, please %3$smigrate your app%4$s to Twitter v2 API to continue using Autoshare for Twitter. %5$sLearn more about migrating here%6$s.', 'autoshare-for-twitter' ) ), + '', + '', + '', + '', + '', + '' + ); + ?> +
+