Changeset 3245133
- Timestamp:
- 02/23/2025 06:32:26 AM (2 weeks ago)
- Location:
- enable-mastodon-apps/trunk
- Files:
-
- 1 added
- 18 edited
Legend:
- Unmodified
- Added
- Removed
-
enable-mastodon-apps/trunk/README.md
r3243595 r3245133 7 7 - Requires PHP: 7.4 8 8 - License: [GPLv2 or later](http://www.gnu.org/licenses/gpl-2.0.html) 9 - Stable tag: 1. 1.09 - Stable tag: 1.2.0 10 10 11 11 Allow accessing your WordPress with Mastodon clients. Just enter your own blog URL as your instance. … … 101 101 ## Changelog 102 102 103 ### 1.2.0 104 - Fixed Boost, Like and Comment notifications ([#216]) 105 - Announce Initial and Changed App Settings ([#207], [#214]) 106 - Added a Welcome message to your feed and explain the EMA plugin ([#210]) 107 - Added missing types to notifications endpoint ([#215]) 108 - Don't set any post formats as default ([#211]) 109 - Updated Mastodon API Tester ([#209]) 110 - Added a setting to disable status updates to be added to the feed ([#208]) 111 - Added support for the OAuth2 Out of Band flow ([#206]) 112 103 113 ### 1.1.0 104 114 - Add an Announcement CPT so that we can inform about the changed app settings ([#204]) … … 171 181 - Fix OAuth rewrite path ([#130]) 172 182 183 [#216]: https://github.com/akirk/enable-mastodon-apps/pull/216 184 [#214]: https://github.com/akirk/enable-mastodon-apps/pull/214 185 [#215]: https://github.com/akirk/enable-mastodon-apps/pull/215 186 [#211]: https://github.com/akirk/enable-mastodon-apps/pull/211 187 [#210]: https://github.com/akirk/enable-mastodon-apps/pull/210 188 [#209]: https://github.com/akirk/enable-mastodon-apps/pull/209 189 [#208]: https://github.com/akirk/enable-mastodon-apps/pull/208 190 [#207]: https://github.com/akirk/enable-mastodon-apps/pull/207 191 [#206]: https://github.com/akirk/enable-mastodon-apps/pull/206 173 192 [#204]: https://github.com/akirk/enable-mastodon-apps/pull/204 174 193 [#203]: https://github.com/akirk/enable-mastodon-apps/pull/203 -
enable-mastodon-apps/trunk/enable-mastodon-apps.php
r3243595 r3245133 4 4 * Plugin author: Alex Kirk 5 5 * Plugin URI: https://github.com/akirk/enable-mastodon-apps 6 * Version: 1. 1.06 * Version: 1.2.0 7 7 * 8 8 * Description: Allow accessing your WordPress with Mastodon clients. Just enter your own blog URL as your instance. … … 20 20 defined( 'ABSPATH' ) || exit; 21 21 define( 'ENABLE_MASTODON_APPS_PLUGIN_DIR', plugin_dir_path( __FILE__ ) ); 22 define( 'ENABLE_MASTODON_APPS_VERSION', '1.1.0' ); 22 define( 'ENABLE_MASTODON_APPS_PLUGIN_BASENAME', plugin_basename( __FILE__ ) ); 23 define( 'ENABLE_MASTODON_APPS_VERSION', '1.2.0' ); 23 24 24 25 require __DIR__ . '/vendor/bshaffer/oauth2-server-php/src/OAuth2/Autoloader.php'; … … 70 71 ); 71 72 72 if ( is_admin() && version_compare( get_option( 'ema_plugin_version' , ENABLE_MASTODON_APPS_VERSION ), '<' ) ) {73 if ( is_admin() && version_compare( get_option( 'ema_plugin_version' ), ENABLE_MASTODON_APPS_VERSION, '<' ) ) { 73 74 add_action( 'admin_init', array( __NAMESPACE__ . '\Mastodon_Admin', 'upgrade_plugin' ) ); 74 75 } -
enable-mastodon-apps/trunk/includes/class-comment-cpt.php
r3158797 r3245133 74 74 75 75 public function mastodon_api_in_reply_to_id( $post_id ) { 76 $comment_id = $this->post_id_to_comment_id( $post_id );76 $comment_id = self::post_id_to_comment_id( $post_id ); 77 77 if ( $comment_id ) { 78 78 return $comment_id; … … 81 81 } 82 82 83 public function post_id_to_comment_id( $post_id ) {83 public static function post_id_to_comment_id( $post_id ) { 84 84 if ( get_post_type( $post_id ) !== self::CPT ) { 85 85 return null; … … 153 153 return; 154 154 } 155 $comment_id = $this->post_id_to_comment_id( $post_id );155 $comment_id = self::post_id_to_comment_id( $post_id ); 156 156 if ( ! $comment_id ) { 157 157 return; -
enable-mastodon-apps/trunk/includes/class-mastodon-admin.php
r3243595 r3245133 20 20 add_action( 'admin_enqueue_scripts', array( $this, 'admin_enqueue_scripts' ) ); 21 21 add_action( 'current_screen', array( $this, 'register_help' ) ); 22 add_filter( 'plugin_action_links_' . ENABLE_MASTODON_APPS_PLUGIN_BASENAME, array( $this, 'plugin_action_links' ) ); 22 23 } 23 24 … … 108 109 } 109 110 110 111 public function plugin_action_links( $links ) { 112 $links[] = '<a href="' . esc_url( admin_url( 'options-general.php?page=enable-mastodon-apps' ) ) . '">' . esc_html__( 'Settings', 'enable-mastodon-apps' ) . '</a>'; 113 return $links; 114 } 111 115 112 116 public function process_admin() { … … 214 218 delete_option( 'mastodon_api_posting_cpt' ); 215 219 216 $supported_post_types = (array) \get_option( 'activitypub_support_post_types', array( 'post' ) ); 217 $supported_post_types[] = $default_ema_post_type; 218 \update_option( 'activitypub_support_post_types', $supported_post_types ); 220 if ( defined( 'ACTIVITYPUB_PLUGIN_VERSION' ) ) { 221 $supported_post_types = (array) \get_option( 'activitypub_support_post_types', array( 'post' ) ); 222 if ( ! in_array( $default_ema_post_type, $supported_post_types, true ) ) { 223 $supported_post_types[] = $default_ema_post_type; 224 \update_option( 'activitypub_support_post_types', $supported_post_types ); 225 } 226 } 219 227 } else { 220 update_option( 'mastodon_api_posting_cpt', 'post' ); 221 222 $supported_post_types = (array) \get_option( 'activitypub_support_post_types', array( 'post' ) ); 223 if ( in_array( $default_ema_post_type, $supported_post_types, true ) ) { 224 $supported_post_types = array_diff( $supported_post_types, array( $default_ema_post_type ) ); 225 \update_option( 'activitypub_support_post_types', $supported_post_types ); 226 } 228 update_option( 'mastodon_api_posting_cpt', 'post', false ); 229 230 if ( defined( 'ACTIVITYPUB_PLUGIN_VERSION' ) ) { 231 $supported_post_types = (array) \get_option( 'activitypub_support_post_types', array( 'post' ) ); 232 if ( in_array( $default_ema_post_type, $supported_post_types, true ) ) { 233 $supported_post_types = array_diff( $supported_post_types, array( $default_ema_post_type ) ); 234 \update_option( 'activitypub_support_post_types', $supported_post_types ); 235 } 236 } 237 } 238 239 if ( isset( $_POST['mastodon_api_disable_ema_announcements'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Missing 240 delete_option( 'mastodon_api_disable_ema_announcements' ); 241 } else { 242 update_option( 'mastodon_api_disable_ema_announcements', true, false ); 243 } 244 245 if ( isset( $_POST['mastodon_api_disable_ema_app_settings_changes'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Missing 246 delete_option( 'mastodon_api_disable_ema_app_settings_changes' ); 247 } else { 248 update_option( 'mastodon_api_disable_ema_app_settings_changes', true, false ); 227 249 } 228 250 … … 653 675 } 654 676 $app->set_post_formats( $post_formats ); 677 $post_formats = $app->get_post_formats(); 655 678 656 679 $post_types = array_flip( … … 686 709 } 687 710 688 wp_insert_post( 689 array( 690 'post_type' => Mastodon_API::ANNOUNCE_CPT, 691 'post_title' => __( 'Only Visible to You', 'enable-mastodon-apps' ), 692 'post_content' => 693 sprintf( 694 // translators: %s: app name. 695 __( 'The settings for %s were changed as follows:', 'enable-mastodon-apps' ), 696 $app->get_client_name() 697 ) . PHP_EOL . 698 'Post Formats: ' . implode( ', ', $post_formats ) . PHP_EOL . 699 'Create Post Type: ' . $create_post_type . PHP_EOL . 700 'Post Types: ' . implode( ', ', array_keys( $view_post_types ) ), 701 'post_status' => 'publish', 702 'meta_input' => array( 703 'ema_app_id' => $app->get_client_id(), 704 ), 705 ) 706 ); 711 if ( isset( $_POST['disable_blocks'] ) ) { 712 $app->set_disable_blocks( true ); 713 } else { 714 $app->set_disable_blocks( false ); 715 } 716 717 $app->post_current_settings(); 707 718 } 708 719 … … 735 746 } 736 747 748 if ( ! get_option( 'mastodon_api_disable_ema_announcements' ) ) { 749 if ( ! $old_version ) { 750 $title = __( 'Welcome to Enable Mastodon Apps!', 'enable-mastodon-apps' ); 751 $content = __( 'This is a message from the Enable Mastodon Apps plugin that you have installed on your WordPress.', 'enable-mastodon-apps' ); 752 $content .= PHP_EOL . '<br>'; 753 $content .= __( 'The plugin allows you to see all posts on your site inside this app.', 'enable-mastodon-apps' ); 754 if ( ! defined( 'ACTIVITYPUB_PLUGIN_VERSION' ) ) { 755 // When standalone, we want to post to your WordPress. 756 update_option( 'mastodon_api_posting_cpt', 'post', false ); 757 $content .= __( 'If you submit a status, it will be posted to your site.', 'enable-mastodon-apps' ); 758 $content .= ' ' . __( "Be aware that this means that it will also be shown in your site's feed.", 'enable-mastodon-apps' ); 759 } else { 760 $default_ema_post_type = apply_filters( 'mastodon_api_default_post_type', \Enable_Mastodon_Apps\Mastodon_API::POST_CPT ); 761 $supported_post_types = (array) \get_option( 'activitypub_support_post_types', array( 'post' ) ); 762 if ( ! in_array( $default_ema_post_type, $supported_post_types, true ) ) { 763 $supported_post_types[] = $default_ema_post_type; 764 \update_option( 'activitypub_support_post_types', $supported_post_types ); 765 } 766 $content .= __( 'If you submit a status, it will be posted so that it is hidden from your site (by using a custom post type).', 'enable-mastodon-apps' ); 767 $content .= ' '; 768 $content .= __( 'By means of the ActivityPub plugin that you also have installed, it will still be federated to your followers.', 'enable-mastodon-apps' ); 769 } 770 $content .= ' '; 771 $content .= __( 'This can be changed individually per app (see the link below).', 'enable-mastodon-apps' ); 772 $content .= PHP_EOL . '<br>'; 773 $content .= __( 'How it works: By providing the same API that Mastodon offers, it brings two worlds together that were not really designed for this interoperability. Thus, while it typically functions well, you might still experience some unexpected behavior.', 'enable-mastodon-apps' ); 774 $content .= ' '; 775 // translators: %s is a clickable URL. 776 $content .= make_clickable( sprintf( __( 'Please visit %s to get help in such a case.', 'enable-mastodon-apps' ), 'https://github.com/akirk/enable-mastodon-apps/issues' ) ); 777 $content .= PHP_EOL . '<br>'; 778 // translators: %s is a URL. 779 $content .= sprintf( __( 'If you enjoy using this plugin, please let us know at the <a href=%s>EMA WordPress.org plugin page</a>.', 'enable-mastodon-apps' ), '"https://wordpress.org/plugins/enable-mastodon-apps/"' ); 780 781 wp_insert_post( 782 array( 783 'post_type' => Mastodon_API::ANNOUNCE_CPT, 784 'post_title' => $title, 785 'post_status' => 'publish', 786 'post_content' => $content, 787 788 ) 789 ); 790 } else { 791 $readme = file_get_contents( ENABLE_MASTODON_APPS_PLUGIN_DIR . 'README.md' ); // phpcs:ignore WordPress.WP.AlternativeFunctions.file_get_contents_file_get_contents 792 $changelog = substr( $readme, strpos( $readme, '## Changelog' ) ); 793 $first_section = strpos( $changelog, '###' ); 794 $changelog = substr( $changelog, $first_section, strpos( $changelog, '###', $first_section + 1 ) - $first_section ); 795 796 $changelog = preg_replace( '/\[#(\d+)\]/', '<a href="https://github.com/akirk/enable-mastodon-apps/pull/\1">#\1</a>', $changelog ); 797 list( $headline, $changes ) = explode( PHP_EOL, $changelog, 2 ); 798 799 // translators: %s: version number. 800 $title = sprintf( __( "What's new in EMA %s?", 'enable-mastodon-apps' ), trim( $headline, ' #' ) ); 801 802 $posts = get_posts( 803 array( 804 'post_type' => Mastodon_API::ANNOUNCE_CPT, 805 'posts_per_page' => 1, 806 'post_status' => 'publish', 807 'title' => $title, 808 ) 809 ); 810 if ( ! $posts ) { 811 $changes = wp_kses( $changes, array( 'a' => array( 'href' => true ) ) ); 812 813 wp_insert_post( 814 array( 815 'post_type' => Mastodon_API::ANNOUNCE_CPT, 816 'post_title' => $title, 817 'post_status' => 'publish', 818 'post_content' => $changes, 819 ) 820 ); 821 } 822 } 823 } 824 737 825 if ( version_compare( $old_version, '1.0.0', '<' ) ) { 738 826 // If the friends plugin is installed, add the friends post type to the list of post types that can be viewed. -
enable-mastodon-apps/trunk/includes/class-mastodon-api.php
r3243595 r3245133 74 74 add_filter( 'template_include', array( $this, 'log_404s' ) ); 75 75 add_filter( 'rest_json_encode_options', array( $this, 'rest_json_encode_options' ), 10, 2 ); 76 add_action( 'default_option_mastodon_api_default_post_formats', array( $this, 'default_option_mastodon_api_default_post_formats' ) );77 76 add_filter( 'rest_request_before_callbacks', array( $this, 'rest_request_before_callbacks' ), 10, 3 ); 78 77 add_filter( 'rest_authentication_errors', array( $this, 'rest_authentication_errors' ) ); … … 193 192 ), 194 193 'description' => __( 'Posted through a Mastodon app.', 'enable-mastodon-apps' ), 195 'public' => ! get_option( 'mastodon_api_posting_cpt' ) ,194 'public' => ! get_option( 'mastodon_api_posting_cpt' ) || ( defined( 'WP_DEBUG' ) && WP_DEBUG ), 196 195 'show_in_rest' => false, 197 196 'rewrite' => false, … … 208 207 ), 209 208 'description' => __( 'Announcement by the Enable Mastodon Apps plugin.', 'enable-mastodon-apps' ), 210 'public' => false,209 'public' => defined( 'WP_DEBUG' ) && WP_DEBUG, 211 210 'show_in_rest' => false, 212 211 'rewrite' => false, … … 648 647 'type' => 'string', 649 648 'enum' => array( 650 ' mention',651 ' status',652 ' reblog',649 'admin.report', 650 'admin.sign_up', 651 'favourite', 653 652 'follow', 654 653 'follow_request', 655 'favourite', 654 'mention', 655 'pleroma:emoji_reaction', 656 656 'poll', 657 'reaction', 658 'reblog', 659 'severed_relationship', 660 'status', 657 661 'update', 658 'admin.sign_up',659 'admin.report',660 'severed_relationship',661 662 ), 662 663 ), … … 1825 1826 1826 1827 /** 1827 * Set the default post format.1828 *1829 * @param mixed $post_formats The default value to return if the option does not exist1830 * in the database.1831 *1832 * @return array The potentially modified default value.1833 */1834 public function default_option_mastodon_api_default_post_formats( $post_formats ) { // phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.Found1835 return array(1836 'standard',1837 );1838 }1839 1840 /**1841 1828 * Converts param validation errors to error codes expected by Mastodon apps. 1842 1829 * -
enable-mastodon-apps/trunk/includes/class-mastodon-app.php
r3243595 r3245133 86 86 $query_args = $this->get_query_args(); 87 87 if ( ! isset( $query_args['post_formats'] ) || ! is_array( $query_args['post_formats'] ) ) { 88 return get_option( 'mastodon_api_default_post_formats', array() ); 88 return array(); 89 } 90 91 if ( array_keys( get_post_format_slugs() ) === $query_args['post_formats'] ) { 92 return array(); 89 93 } 90 94 … … 93 97 94 98 public function get_admin_page() { 95 return add_query_arg( 'app', $this->term->slug, admin_url( ' admin.php?page=enable-mastodon-apps' ) );99 return add_query_arg( 'app', $this->term->slug, admin_url( 'options-general.php?page=enable-mastodon-apps' ) ); 96 100 } 97 101 … … 228 232 } 229 233 update_term_meta( $this->term->term_id, 'last_used', time() ); 234 } 235 236 /** 237 * Posts current settings as an announcement just for this app. 238 * 239 * @param string $title The title. 240 * @param string $intro The intro text. 241 * 242 * @return int|null The post ID. 243 */ 244 public function post_current_settings( string $title = '', string $intro = '' ) { 245 if ( get_option( 'mastodon_api_disable_ema_app_settings_changes' ) ) { 246 return null; 247 } 248 249 if ( ! $title ) { 250 $title = sprintf( 251 // translators: %s: app name. 252 __( 'Settings for %s changed', 'enable-mastodon-apps' ), 253 $this->get_client_name() 254 ); 255 } 256 257 if ( ! $intro ) { 258 $intro = __( 'The current settings for this app are:', 'enable-mastodon-apps' ); 259 } 260 $content = $intro; 261 262 $post_formats = $this->get_post_formats(); 263 $t = PHP_EOL . __( 'Post Formats', 'enable-mastodon-apps' ) . ': '; 264 foreach ( get_post_format_strings() as $slug => $name ) { 265 if ( ! in_array( $slug, $post_formats, true ) ) { 266 continue; 267 } 268 $content .= $t . $name; 269 $t = ', '; 270 } 271 if ( ', ' !== $t ) { 272 $content .= $t . __( 'All' ); // phpcs:ignore WordPress.WP.I18n.MissingArgDomain 273 } 274 275 $content .= PHP_EOL . _x( 'Create new posts as', 'select post type', 'enable-mastodon-apps' ) . ': '; 276 $content .= get_post_type_object( $this->get_create_post_type() )->labels->singular_name; 277 $t = PHP_EOL . __( 'Show these post types', 'enable-mastodon-apps' ) . ': '; 278 foreach ( $this->get_view_post_types() as $post_type ) { 279 if ( in_array( $post_type, array( Mastodon_API::ANNOUNCE_CPT, Mastodon_API::POST_CPT ), true ) ) { 280 continue; 281 } 282 $content .= $t . get_post_type_object( $post_type )->labels->name; 283 $t = ', '; 284 } 285 286 if ( $this->get_disable_blocks() ) { 287 $content .= PHP_EOL . __( 'Automatic conversion to blocks is disabled', 'enable-mastodon-apps' ); 288 } 289 290 $previous_posts = get_posts( 291 array( 292 'post_type' => Mastodon_API::ANNOUNCE_CPT, 293 'post_status' => 'publish', 294 'meta_query' => array( // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_query 295 array( 296 'key' => 'ema_app_id', 297 'value' => $this->get_client_id(), 298 ), 299 ), 300 ) 301 ); 302 303 foreach ( $previous_posts as $previous_post ) { 304 wp_delete_post( $previous_post->ID ); 305 } 306 307 return wp_insert_post( 308 array( 309 'post_type' => Mastodon_API::ANNOUNCE_CPT, 310 'post_title' => $title, 311 'post_content' => nl2br( trim( $content ) ), 312 'post_status' => 'publish', 313 'meta_input' => array( 314 'ema_app_id' => $this->get_client_id(), 315 ), 316 ) 317 ); 230 318 } 231 319 … … 668 756 ); 669 757 670 $post_formats = get_option( 'mastodon_api_default_post_formats', array() );671 758 /** 672 759 * Post formats to be enabled for new apps. … … 684 771 * ``` 685 772 */ 686 $post_formats = apply_filters( 'mastodon_api_new_app_post_formats', $post_formats, $app_metadata );773 $post_formats = apply_filters( 'mastodon_api_new_app_post_formats', array(), $app_metadata ); 687 774 $app_metadata['query_args'] = array( 'post_formats' => $post_formats ); 688 775 … … 722 809 } 723 810 724 return new self( $term ); 811 $app = new self( $term ); 812 $app->post_current_settings( 813 sprintf( 814 // translators: %s: app name. 815 __( 'App %s created', 'enable-mastodon-apps' ), 816 $client_name 817 ), 818 __( 'This app was created with the following settings:', 'enable-mastodon-apps' ) 819 ); 820 return $app; 725 821 } 726 822 } -
enable-mastodon-apps/trunk/includes/class-mastodon-oauth.php
r3129164 r3245133 12 12 use OAuth2\Server; 13 13 use OAuth2\Request; 14 use OAuth2\Response;14 use Enable_Mastodon_Apps\OAuth2\Response; 15 15 16 16 /** -
enable-mastodon-apps/trunk/includes/handler/class-handler.php
r3240587 r3245133 128 128 } 129 129 130 krsort( $statuses ); 130 usort( 131 $statuses, 132 function ( $a, $b ) { 133 return $b->created_at->getTimestamp() - $a->created_at->getTimestamp(); 134 } 135 ); 131 136 132 137 $response = new \WP_REST_Response( array_values( $statuses ) ); -
enable-mastodon-apps/trunk/includes/handler/class-notification.php
r3129164 r3245133 48 48 foreach ( $notifications as $notification ) { 49 49 if ( $notification['status'] ) { 50 wp_set_object_terms( $notification['status'] ['id'], $notification_dismissed_tag, 'post_tag', true );50 wp_set_object_terms( $notification['status']->id, $notification_dismissed_tag, 'post_tag', true ); 51 51 } 52 52 } … … 68 68 } 69 69 if ( $notification['status'] ) { 70 wp_set_object_terms( $notification['status'] ['id'], $notification_dismissed_tag, 'post_tag', true );70 wp_set_object_terms( $notification['status']->id, $notification_dismissed_tag, 'post_tag', true ); 71 71 } 72 72 } … … 91 91 } 92 92 93 return new WP_Error( 'notification_not_found', __( 'Notification not found.', 'enable-mastodon-apps' ) );93 return new \WP_Error( 'notification_not_found', __( 'Notification not found.', 'enable-mastodon-apps' ) ); 94 94 } 95 95 … … 159 159 } 160 160 foreach ( get_posts( $args ) as $post ) { 161 $comment_id = Comment_CPT::post_id_to_comment_id( $post->ID ); 161 162 $account = apply_filters( 'mastodon_api_account', null, $post->post_author, null, $post ); 162 $status = apply_filters( 'mastodon_api_status', null, $post->ID, array() ); 163 switch ( get_comment_type( $comment_id ) ) { 164 case 'like': 165 $type = 'like'; 166 $status = apply_filters( 'mastodon_api_status', null, $post->post_parent, array() ); 167 break; 168 case 'repost': 169 $type = 'reblog'; 170 $status = apply_filters( 'mastodon_api_status', null, $post->post_parent, array() ); 171 break; 172 default: 173 $type = 'mention'; 174 $status = apply_filters( 'mastodon_api_status', null, $post->ID, array() ); 175 } 163 176 if ( $account && $status ) { 164 177 $notifications[] = $this->get_notification_array( 165 'mention',178 $type, 166 179 mysql2date( 'Y-m-d\TH:i:s.000P', $post->post_date, false ), 167 180 $account, … … 188 201 $c = $limit; 189 202 foreach ( $notifications as $notification ) { 203 if ( ! $notification ) { 204 continue; 205 } 190 206 if ( $max_id ) { 191 207 if ( strval( $notification['id'] ) >= strval( $max_id ) ) { -
enable-mastodon-apps/trunk/includes/handler/class-status.php
r3243595 r3245133 10 10 namespace Enable_Mastodon_Apps\Handler; 11 11 12 use Enable_Mastodon_Apps\Entity\Entity;13 12 use Enable_Mastodon_Apps\Handler\Handler; 13 use Enable_Mastodon_Apps\Comment_CPT; 14 14 use Enable_Mastodon_Apps\Mastodon_API; 15 15 use Enable_Mastodon_Apps\Mastodon_App; … … 133 133 if ( Mastodon_API::ANNOUNCE_CPT === $post->post_type ) { 134 134 $meta = get_post_meta( $post->ID, 'ema_app_id', true ); 135 if ( $meta ) { 136 $app = Mastodon_App::get_current_app(); 137 if ( ! $app || $app->get_client_id() !== $meta ) { 138 return null; 139 } 135 $app = Mastodon_App::get_current_app(); 136 if ( $meta && ( ! $app || $app->get_client_id() !== $meta ) ) { 137 return null; 138 } 139 140 // translators: %s: settings page URL. 141 $post->post_content = trim( $post->post_content ) . 142 '<br>' . PHP_EOL . '<br>' . PHP_EOL . 143 // translators: %s: settings page URL. 144 sprintf( __( 'This message has been added by the EMA plugin. You can disable these messages <a href=%s>in the settings</a>.', 'enable-mastodon-apps' ), '"' . esc_url( admin_url( 'options-general.php?page=enable-mastodon-apps&tab=settings' ) ) . '"' ); 145 if ( $app ) { 146 // translators: %s: settings page URL. 147 $post->post_content .= ' ' . sprintf( __( 'Change the <a href=%s>settings for this app here</a>.', 'enable-mastodon-apps' ), '"' . esc_url( admin_url( 'options-general.php?page=enable-mastodon-apps&app=' . $app->get_client_id() ) ) . '"' ); 140 148 } 141 149 } … … 198 206 * @param int|null $min_id Optional minimum status ID. 199 207 * @param int|null $max_id Optional maximum status ID. 200 * @return array208 * @return WP_REST_Response The statuses as a REST response. 201 209 */ 202 public function api_statuses( ?array $statuses, array $args, ?int $min_id = null, ?int $max_id = null ): \WP_REST_Response {210 public function api_statuses( ?array $statuses, array $args, ?int $min_id = null, ?int $max_id = null ): WP_REST_Response { 203 211 if ( $statuses ) { 204 if ( ! $statuses instanceof \WP_REST_Response ) {205 $statuses = new \WP_REST_Response( array_values( $statuses ) );212 if ( ! $statuses instanceof WP_REST_Response ) { 213 $statuses = new WP_REST_Response( array_values( $statuses ) ); 206 214 } 207 215 return $statuses; … … 217 225 public function api_statuses_ensure_numeric_id( $statuses ) { 218 226 $response = null; 219 if ( $statuses instanceof \WP_REST_Response ) {227 if ( $statuses instanceof WP_REST_Response ) { 220 228 $response = $statuses; 221 229 $statuses = $response->data; -
enable-mastodon-apps/trunk/includes/oauth2/class-authenticate-handler.php
r3243595 r3245133 12 12 use Enable_Mastodon_Apps\Mastodon_App; 13 13 use OAuth2\Request; 14 use OAuth2\Response;15 14 16 15 /** … … 209 208 210 209 private function get_cancel_url( Request $request ) { 210 if ( substr( $request->query( 'redirect_uri' ), 0, 25 ) === 'urn:ietf:wg:oauth:2.0:oob' ) { 211 return home_url( '/' ); 212 } 213 211 214 return add_query_arg( 212 215 array( -
enable-mastodon-apps/trunk/includes/oauth2/class-authorize-handler.php
r3243595 r3245133 11 11 12 12 use OAuth2\Request; 13 use OAuth2\Response;14 13 use OAuth2\Server as OAuth2Server; 15 14 -
enable-mastodon-apps/trunk/includes/oauth2/class-mastodon-app-storage.php
r3240587 r3245133 104 104 ); 105 105 106 $post_formats = get_option( 'mastodon_api_default_post_formats', array() ); 107 $post_formats = apply_filters( 'mastodon_api_new_app_post_formats', $post_formats, $app_metadata ); 106 $post_formats = apply_filters( 'mastodon_api_new_app_post_formats', array(), $app_metadata ); 108 107 $app_metadata['query_args'] = array( 'post_formats' => $post_formats ); 109 108 -
enable-mastodon-apps/trunk/includes/oauth2/class-revokation-handler.php
r3035768 r3245133 11 11 12 12 use OAuth2\Request; 13 use OAuth2\Response;14 13 use OAuth2\Server as OAuth2Server; 15 14 -
enable-mastodon-apps/trunk/includes/oauth2/class-token-handler.php
r3129164 r3245133 11 11 12 12 use OAuth2\Request; 13 use OAuth2\Response;14 13 use OAuth2\Server as OAuth2Server; 15 14 -
enable-mastodon-apps/trunk/templates/app.php
r3243595 r3245133 29 29 ) 30 30 ); 31 $app_post_formats = $app->get_post_formats(); 31 32 ?> 32 33 <div class="enable-mastodon-apps-settings enable-mastodon-apps-registered-apps-page <?php echo $args['enable_debug'] ? 'enable-debug' : 'disable-debug'; ?>"> … … 117 118 <fieldset> 118 119 <?php foreach ( get_post_format_strings() as $format => $label ) : ?> 119 <label><input type="checkbox" name="post_formats[]" value="<?php echo esc_attr( $format ); ?>"<?php checked( in_array( $format, $app ->get_post_formats(), true) ); ?> /> <?php echo esc_html( $label ); ?></label>120 <label><input type="checkbox" name="post_formats[]" value="<?php echo esc_attr( $format ); ?>"<?php checked( in_array( $format, $app_post_formats, true ) || empty( $app_post_formats ) ); ?> /> <?php echo esc_html( $label ); ?></label> 120 121 <?php endforeach; ?> 121 122 </fieldset> -
enable-mastodon-apps/trunk/templates/settings.php
r3243595 r3245133 74 74 </tr> 75 75 <tr> 76 <th scope="row"><?php esc_html_e( 'Status Messages', 'enable-mastodon-apps' ); ?></th> 77 <td> 78 <p class="description"><?php esc_html_e( 'Allow this plugin to inform you by adding a status to your feed:', 'enable-mastodon-apps' ); ?></p> 79 <fieldset> 80 <label for="mastodon_api_disable_ema_announcements"> 81 <input name="mastodon_api_disable_ema_announcements" type="checkbox" id="mastodon_api_disable_ema_announcements" value="1" <?php checked( ! get_option( 'mastodon_api_disable_ema_announcements' ) ); ?> /> 82 <span> 83 <?php 84 // translators: Changelog entries won't be translated so they will appear in English. 85 esc_html_e( 'When it is updated to a new version and list the changes (in English).', 'enable-mastodon-apps' ); 86 ?> 87 </span> 88 </label> 89 90 <label for="mastodon_api_disable_ema_app_settings_changes"> 91 <input name="mastodon_api_disable_ema_app_settings_changes" type="checkbox" id="mastodon_api_disable_ema_app_settings_changes" value="1" <?php checked( ! get_option( 'mastodon_api_disable_ema_app_settings_changes' ) ); ?> /> 92 <span><?php esc_html_e( "When changes are made to specific app's settings (only visible in the app's feed).", 'enable-mastodon-apps' ); ?></span> 93 </label> 94 </fieldset> 95 </td> 96 </tr> 97 <tr> 76 98 <th scope="row"><?php esc_html_e( 'Debugging', 'enable-mastodon-apps' ); ?></th> 77 99 <td> -
enable-mastodon-apps/trunk/tester.html
r3157710 r3245133 24 24 } 25 25 26 div.api-endpoint { 26 div.iframe-holder { 27 position: absolute; 28 background-color: white; 29 border: 1px solid black; 30 padding: 10px; 31 z-index: 1000; 32 } 33 div.iframe-holder iframe { 34 border: 0; 35 width: 40em; 36 } 37 div.iframe-holder button { 38 position: absolute; 39 top: 0; 40 right: 0; 41 background-color: white; 42 border: 0; 43 cursor: pointer; 44 45 } 46 47 li.api-endpoint { 27 48 cursor: pointer; 28 49 color: blue; 29 50 text-decoration: underline; 30 } 31 32 #api-endpoints>div { 51 padding-left: .5em; 52 } 53 54 #api-endpoints ul { 55 list-style: none; 56 padding-left: 0; 57 } 58 #api-endpoints li { 33 59 font-weight: bold; 34 60 margin-bottom: 10px; … … 129 155 border: 1px solid #aaa; 130 156 } 157 input#api-custom-endpoint { 158 width: 40em; 159 } 131 160 button#send-api-custom-endpoint { 132 161 font-size: .9em; … … 228 257 <br /> 229 258 230 <input type="reset" id="reset"> <input type="reset" id="delete-local " value="Clear all data">259 <input type="reset" id="reset"> <input type="reset" id="delete-local2" value="Clear all data"> 231 260 </div> 232 261 </details> … … 234 263 <div id="api-endpoints"> 235 264 <h2>Endpoints</h2> 236 <p>Clicking these will send a request to the API and display the response in the box below.</p> 237 <div class="api-endpoint">/api/v1/accounts/verify_credentials</div> 238 <div class="api-endpoint">/api/v1/accounts/relationships</div> 239 <div class="api-endpoint">/api/v1/timelines/home</div> 240 <div class="api-endpoint">/api/v1/notifications</div> 265 <p>Clicking these will send a request to the API and display the response in the box below. Shift-click to remove an item.</p> 266 <ul> 267 </ul> 241 268 <div><input type="text" id="api-custom-endpoint" value="/api/v1/accounts/1/statuses"> <button id="send-api-custom-endpoint">Send</button></div> 242 269 <h2>Endpoints with parameters</h2> … … 261 288 <script> 262 289 function logRequest(data) { 290 document.querySelectorAll('div.iframe-holder').forEach( function( div ) { 291 div.remove(); 292 } ); 293 263 294 const div = document.createElement('div'); 264 295 const timestamp = document.createElement('tt'); … … 405 436 document.getElementById('authorization-status').style.display = 'block'; 406 437 document.getElementById('detailsblock').style.display = 'block'; 407 document.getElementById('authorization-status').textContent = 'Authorized.'; 438 document.getElementById('authorization-status').textContent = 'Authorized with ' + localStorage.getItem('baseURL'); 439 408 440 document.getElementById('authorize').textContent = 'Re-Authorize'; 409 441 } … … 506 538 }); 507 539 540 document.getElementById('delete-local2').addEventListener('click', function () { 541 localStorage.clear(); 542 location.reload(); 543 }); 508 544 509 545 document.getElementById('reset').addEventListener('click', function () { … … 534 570 history.replaceState(null, null, window.location.pathname + (urlParams.toString() ? '?' + urlParams.toString() : '')); 535 571 } 572 573 const customEndpoints = JSON.parse( localStorage.getItem( 'customEndpoints' ) ) || []; 574 if ( ! customEndpoints.length ) { 575 customEndpoints.push( '/api/v1/accounts/verify_credentials' ); 576 customEndpoints.push( '/api/v1/accounts/relationships?id[][email protected]' ); 577 customEndpoints.push( '/api/v1/timelines/home' ); 578 customEndpoints.push( '/api/v1/notifications' ); 579 localStorage.setItem( 'customEndpoints', JSON.stringify( customEndpoints ) ); 580 }; 581 const apiEndpoints = document.getElementById('api-endpoints').querySelector('ul'); 582 customEndpoints.forEach( function( endpoint ) { 583 const li = document.createElement('li'); 584 li.className = 'api-endpoint'; 585 li.textContent = endpoint; 586 apiEndpoints.appendChild( li ); 587 } ); 536 588 537 589 const requestLog = document.getElementById('request-log'); … … 579 631 return text.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>'); 580 632 } 581 633 let showPreview = false; 582 634 583 635 document.addEventListener("mouseover", (event) => { … … 590 642 591 643 link.appendChild(img); 644 } 645 if (event.target.classList.contains('string') && event.target.textContent.match( /</) ) { 646 if ( event.target.querySelector('div.iframe-holder') ) { 647 return; 648 } 649 if ( showPreview ) { 650 clearTimeout( showPreview ); 651 } 652 showPreview = setTimeout( function() { 653 let status = event.target.textContent.substr(1, event.target.textContent.length - 2).replace( /\\"/g, '"' ).replace( /\\n/g, "\n" ).replace( /href=/g, 'target="_blank" href=' ); 654 const iframe = document.createElement('iframe'); 655 iframe.setAttribute('sandbox', 'allow-same-origin allow-popups'); 656 iframe.srcdoc = '<style>body { font-family: sans-serif; line-height: 1.2; white-space: preserve-breaks; } a:any-link { color: #098658; }</style>' + status; 657 const div = document.createElement('div'); 658 div.style.left = event.target.offsetLeft + 'px'; 659 div.style.top = (event.target.offsetTop + 20 ) + 'px'; 660 div.className = 'iframe-holder'; 661 div.appendChild(iframe); 662 const close = document.createElement('button'); 663 close.textContent = 'Close'; 664 close.addEventListener('click', function() { 665 div.remove(); 666 }); 667 div.appendChild(close); 668 669 event.target.appendChild(div); 670 }, 500 ); 592 671 } 593 672 }); … … 623 702 } 624 703 704 document.addEventListener('keyup', function (event) { 705 if ( event.key === 'Enter' ) { 706 if ( event.target.id === 'api-custom-endpoint' ) { 707 document.getElementById('send-api-custom-endpoint').click(); 708 return; 709 } 710 711 if ( event.target.tagName === 'INPUT' ) { 712 const endpoint = event.target.closest('details').querySelector('.api-endpoint'); 713 if ( endpoint ) { 714 endpoint.click(); 715 } 716 } 717 } 718 } ); 719 720 document.addEventListener('mousemove', function (event) { 721 if (event.target.classList.contains('api-endpoint') ) { 722 if ( event.shiftKey ) { 723 event.target.style.textDecoration = 'line-through'; 724 event.target.style.color = 'red'; 725 } else { 726 event.target.style.textDecoration = null; 727 event.target.style.color = null; 728 } 729 } 730 }); 731 document.addEventListener('mouseout', function (event) { 732 if (event.target.classList.contains('api-endpoint') ) { 733 event.target.style.textDecoration = null; 734 event.target.style.color = null; 735 } 736 }); 737 625 738 document.addEventListener('click', function (event) { 626 739 let endpoint = false; … … 628 741 let submitValues = false; 629 742 if (event.target.classList.contains('api-endpoint')) { 743 if ( event.shiftKey ) { 744 event.target.remove(); 745 const customEndpoints = JSON.parse( localStorage.getItem( 'customEndpoints' ) ) || []; 746 const index = customEndpoints.indexOf( event.target.textContent ); 747 if ( index > -1 ) { 748 customEndpoints.splice( index, 1 ); 749 localStorage.setItem( 'customEndpoints', JSON.stringify( customEndpoints ) ); 750 } 751 return; 752 } 630 753 endpoint = event.target.dataset.endpoint || event.target.textContent; 754 document.getElementById('api-custom-endpoint').value = endpoint; 631 755 method = event.target.dataset.method || 'GET'; 632 756 if ( event.target.tagName === 'BUTTON' ) { … … 635 759 } else if (event.target.id === 'send-api-custom-endpoint') { 636 760 endpoint = document.getElementById('api-custom-endpoint').value; 761 if ( '/' !== endpoint.substr( 0, 1 ) ) { 762 endpoint = '/' + endpoint; 763 } 764 let endpointExists = false; 765 document.querySelectorAll('#api-endpoints li.api-endpoint' ).forEach( function( li ) { 766 if ( li.textContent === endpoint ) { 767 endpointExists = true; 768 } 769 } ); 770 if ( ! endpointExists ) { 771 const li = document.createElement('li'); 772 li.className = 'api-endpoint'; 773 li.textContent = endpoint; 774 document.getElementById('api-endpoints').querySelector('ul').appendChild(li); 775 const customEndpoints = JSON.parse( localStorage.getItem( 'customEndpoints' ) ) || []; 776 if ( ! customEndpoints.includes( endpoint ) ) { 777 customEndpoints.push( endpoint ); 778 localStorage.setItem( 'customEndpoints', JSON.stringify( customEndpoints ) ); 779 } 780 } 637 781 method = 'GET'; 638 782 }
Note: See TracChangeset
for help on using the changeset viewer.