| @@ -1,8 +1,12 @@ | ||
| 1 | 1 | <?php |
| 2 | 2 | |
| 3 | -Class CatchThemesThemePlugin { | |
| 4 | - public function __construct(){ | |
| 3 | +if ( ! defined( 'ABSPATH' ) ) { | |
| 4 | + exit; // Exit if accessed directly. | |
| 5 | +} | |
| 6 | + | |
| 7 | +class CatchThemesThemePlugin { | |
| 8 | + public function __construct() { | |
| 5 | 9 | remove_action( 'wp_ajax_query-themes', array( $this, 'wp_ajax_query_themes' ), 1 ); |
| 6 | 10 | add_action( 'wp_ajax_query-themes', array( $this, 'wp_ajax_custom_query_themes' ), 1 ); |
| 7 | 11 | |
| 8 | 12 | add_action( 'admin_enqueue_scripts', array( $this, 'our_themes_script' ) ); |
| @@ -15,40 +19,64 @@ | ||
| 15 | 19 | remove_action( 'wp_ajax_customize_load_themes', array( $wp_customize, 'handle_load_themes_request' ) ); |
| 16 | 20 | add_action( 'wp_ajax_customize_load_themes', array( $this, 'handle_load_themes_request' ) ); |
| 17 | 21 | |
| 18 | 22 | add_filter( 'install_plugins_tabs', array( $this, 'add_our_plugins_tab' ), 1 ); |
| 19 | - add_filter( "install_plugins_table_api_args_catchplugins", array( $this, 'catchplugins' ), 1 ); | |
| 23 | + add_filter( 'install_plugins_table_api_args_catchplugins', array( $this, 'catchplugins' ), 1 ); | |
| 20 | 24 | add_action( 'install_plugins_catchplugins', array( $this, 'plugins_table' ) ); |
| 21 | 25 | } |
| 22 | 26 | |
| 23 | - /* Adds Catch Themes tab in Add Theme page to show all themes by Catch Themes in wordpress.org */ | |
| 27 | + /* Adds Catch Themes tab in Add Theme page to show all themes by Catch Themes in wordpress.org | |
| 28 | + * taken from wp-admin/includes/ajax-action.php wp_ajax_query_themes(). | |
| 29 | + * Ajax handler for getting themes from themes_api(). | |
| 30 | + * | |
| 31 | + * @since 3.9.0 | |
| 32 | + * | |
| 33 | + * @global array $themes_allowedtags | |
| 34 | + * @global array $theme_field_defaults | |
| 35 | + */ | |
| 24 | 36 | public function wp_ajax_custom_query_themes() { |
| 25 | 37 | global $themes_allowedtags, $theme_field_defaults; |
| 26 | 38 | |
| 39 | + // Capability check | |
| 27 | 40 | if ( ! current_user_can( 'install_themes' ) ) { |
| 28 | 41 | wp_send_json_error(); |
| 29 | 42 | } |
| 30 | 43 | |
| 31 | - $args = wp_parse_args( wp_unslash( $_REQUEST['request'] ), array( | |
| 32 | - 'per_page' => 20, | |
| 33 | - 'fields' => $theme_field_defaults | |
| 34 | - ) ); | |
| 44 | + // Nonce verification | |
| 45 | + check_ajax_referer( 'ew_query_themes_nonce', 'nonce' ); | |
| 35 | 46 | |
| 47 | + // Copy superglobal ONCE | |
| 48 | + $post_data = wp_unslash( $_POST ); | |
| 49 | + | |
| 50 | + // Now sanitize | |
| 51 | + $post_data = map_deep( $post_data, 'sanitize_text_field' ); | |
| 52 | + | |
| 53 | + // From this point on, DO NOT use $_POST again | |
| 54 | + if ( empty( $post_data['request'] ) || ! is_array( $post_data['request'] ) ) { | |
| 55 | + wp_send_json_error(); | |
| 56 | + } | |
| 57 | + | |
| 58 | + $args = wp_parse_args( | |
| 59 | + $post_data['request'], | |
| 60 | + array( | |
| 61 | + 'per_page' => 20, | |
| 62 | + 'fields' => array_merge( | |
| 63 | + (array) $theme_field_defaults, | |
| 64 | + array( | |
| 65 | + 'reviews_url' => true, | |
| 66 | + ) | |
| 67 | + ), | |
| 68 | + ) | |
| 69 | + ); | |
| 70 | + | |
| 36 | 71 | if ( isset( $args['browse'] ) && 'catchthemes' === $args['browse'] && ! isset( $args['user'] ) ) { |
| 37 | 72 | $args['author'] = 'catchthemes'; |
| 73 | + unset( $args['browse'] ); | |
| 38 | 74 | } |
| 39 | 75 | |
| 40 | - if ( isset( $args['browse'] ) && 'favorites' === $args['browse'] && ! isset( $args['user'] ) ) { | |
| 41 | - $user = get_user_option( 'wporg_favorites' ); | |
| 42 | - if ( $user ) { | |
| 43 | - $args['user'] = $user; | |
| 44 | - } | |
| 45 | - } | |
| 46 | - | |
| 47 | 76 | $old_filter = isset( $args['browse'] ) ? $args['browse'] : 'search'; |
| 48 | 77 | |
| 49 | - /** This filter is documented in wp-admin/includes/class-wp-theme-install-list-table.php */ | |
| 50 | - $args = apply_filters( 'install_themes_table_api_args_' . $old_filter, $args ); | |
| 78 | + $args = apply_filters( 'install_themes_table_api_args_' . $old_filter, $args ); // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound -- Core WordPress hook, not plugin-defined. | |
| 51 | 79 | |
| 52 | 80 | $api = themes_api( 'query_themes', $args ); |
| 53 | 81 | |
| 54 | 82 | if ( is_wp_error( $api ) ) { |
| @@ -54,70 +82,45 @@ | ||
| 54 | 82 | if ( is_wp_error( $api ) ) { |
| 55 | 83 | wp_send_json_error(); |
| 56 | 84 | } |
| 57 | 85 | |
| 58 | - $update_php = network_admin_url( 'update.php?action=install-theme' ); | |
| 59 | 86 | foreach ( $api->themes as &$theme ) { |
| 60 | - $theme->install_url = add_query_arg( array( | |
| 61 | - 'theme' => $theme->slug, | |
| 62 | - '_wpnonce' => wp_create_nonce( 'install-theme_' . $theme->slug ) | |
| 63 | - ), $update_php ); | |
| 64 | - | |
| 65 | - if ( current_user_can( 'switch_themes' ) ) { | |
| 66 | - if ( is_multisite() ) { | |
| 67 | - $theme->activate_url = add_query_arg( array( | |
| 68 | - 'action' => 'enable', | |
| 69 | - '_wpnonce' => wp_create_nonce( 'enable-theme_' . $theme->slug ), | |
| 70 | - 'theme' => $theme->slug, | |
| 71 | - ), network_admin_url( 'themes.php' ) ); | |
| 72 | - } else { | |
| 73 | - $theme->activate_url = add_query_arg( array( | |
| 74 | - 'action' => 'activate', | |
| 75 | - '_wpnonce' => wp_create_nonce( 'switch-theme_' . $theme->slug ), | |
| 76 | - 'stylesheet' => $theme->slug, | |
| 77 | - ), admin_url( 'themes.php' ) ); | |
| 78 | - } | |
| 79 | - } | |
| 80 | - | |
| 81 | - if ( ! is_multisite() && current_user_can( 'edit_theme_options' ) && current_user_can( 'customize' ) ) { | |
| 82 | - $theme->customize_url = add_query_arg( array( | |
| 83 | - 'return' => urlencode( network_admin_url( 'theme-install.php', 'relative' ) ), | |
| 84 | - ), wp_customize_url( $theme->slug ) ); | |
| 85 | - } | |
| 86 | - | |
| 87 | 87 | $theme->name = wp_kses( $theme->name, $themes_allowedtags ); |
| 88 | - $theme->author = wp_kses( $theme->author, $themes_allowedtags ); | |
| 88 | + $theme->author = wp_kses( $theme->author['display_name'], $themes_allowedtags ); | |
| 89 | 89 | $theme->version = wp_kses( $theme->version, $themes_allowedtags ); |
| 90 | 90 | $theme->description = wp_kses( $theme->description, $themes_allowedtags ); |
| 91 | - $theme->stars = wp_star_rating( array( 'rating' => $theme->rating, 'type' => 'percent', 'number' => $theme->num_ratings, 'echo' => false ) ); | |
| 92 | - $theme->num_ratings = number_format_i18n( $theme->num_ratings ); | |
| 93 | - $theme->preview_url = set_url_scheme( $theme->preview_url ); | |
| 94 | 91 | } |
| 95 | 92 | |
| 96 | 93 | wp_send_json_success( $api ); |
| 97 | 94 | } |
| 98 | - | |
| 95 | + | |
| 99 | 96 | public function our_themes_script( $hook_suffix ) { |
| 100 | 97 | |
| 101 | - if( 'theme-install.php' == $hook_suffix ) { | |
| 102 | - wp_enqueue_script( 'our-themes-script', plugin_dir_url( __FILE__ ) . '../admin/js/our-themes.js', array( 'jquery' ), '2018-05-16' ); | |
| 98 | + if ( 'theme-install.php' === $hook_suffix ) { | |
| 99 | + wp_enqueue_script( 'our-themes-script', plugin_dir_url( __FILE__ ) . '../js/our-themes.js', array( 'jquery' ), '2018-05-16', true ); | |
| 103 | 100 | } |
| 104 | 101 | } |
| 105 | - | |
| 102 | + | |
| 106 | 103 | /* Add Catch Themes Section in Theme in Customizer */ |
| 107 | - public function customize_register($wp_customize) { | |
| 108 | - $wp_customize->add_section( new WP_Customize_Themes_Section( $wp_customize, 'catchthemes', array( | |
| 109 | - 'title' => __( 'Themes by CatchThemes', 'catch-themes-demo-import' ), | |
| 110 | - 'action' => 'catchthemes', | |
| 111 | - 'capability' => 'install_themes', | |
| 112 | - 'panel' => 'themes', | |
| 113 | - 'priority' => 6, | |
| 114 | - ) ) ); | |
| 104 | + public function customize_register( $wp_customize ) { | |
| 105 | + $wp_customize->add_section( | |
| 106 | + new WP_Customize_Themes_Section( | |
| 107 | + $wp_customize, | |
| 108 | + 'catchthemes', | |
| 109 | + array( | |
| 110 | + 'title' => __( 'Themes by CatchThemes', 'essential-widgets' ), | |
| 111 | + 'action' => 'catchthemes', | |
| 112 | + 'capability' => 'install_themes', | |
| 113 | + 'panel' => 'themes', | |
| 114 | + 'priority' => 6, | |
| 115 | + ) | |
| 116 | + ) | |
| 117 | + ); | |
| 115 | 118 | } |
| 116 | - | |
| 117 | 119 | |
| 118 | 120 | |
| 119 | - | |
| 121 | + | |
| 122 | + | |
| 120 | 123 | /** |
| 121 | 124 | * Load themes into the theme browsing/installation UI. |
| 122 | 125 | * taken from wp-includes/cllass-wp-customize-manager.php |
| 123 | 126 | * @since 4.9.0 |
| @@ -131,10 +134,10 @@ | ||
| 131 | 134 | if ( empty( $_POST['theme_action'] ) ) { |
| 132 | 135 | wp_send_json_error( 'missing_theme_action' ); |
| 133 | 136 | } |
| 134 | 137 | $theme_action = sanitize_key( $_POST['theme_action'] ); |
| 135 | - $themes = array(); | |
| 136 | - $args = array(); | |
| 138 | + $themes = array(); | |
| 139 | + $args = array(); | |
| 137 | 140 | |
| 138 | 141 | // Define query filters based on user input. |
| 139 | 142 | if ( ! array_key_exists( 'search', $_POST ) ) { |
| 140 | 143 | $args['search'] = ''; |
| @@ -160,12 +163,11 @@ | ||
| 160 | 163 | |
| 161 | 164 | // Load all installed themes from wp_prepare_themes_for_js(). |
| 162 | 165 | $themes = array( 'themes' => wp_prepare_themes_for_js() ); |
| 163 | 166 | foreach ( $themes['themes'] as &$theme ) { |
| 164 | - $theme['type'] = 'installed'; | |
| 167 | + $theme['type'] = 'installed'; | |
| 165 | 168 | $theme['active'] = ( isset( $_POST['customized_theme'] ) && $_POST['customized_theme'] === $theme['id'] ); |
| 166 | 169 | } |
| 167 | - | |
| 168 | 170 | } elseif ( 'catchthemes' === $theme_action ) { |
| 169 | 171 | |
| 170 | 172 | // Load WordPress.org themes from the .org API and normalize data to match installed theme objects. |
| 171 | 173 | if ( ! current_user_can( 'install_themes' ) ) { |
| @@ -173,21 +175,11 @@ | ||
| 173 | 175 | } |
| 174 | 176 | |
| 175 | 177 | // Arguments for all queries. |
| 176 | 178 | $wporg_args = array( |
| 177 | - 'per_page' => -1, | |
| 178 | - 'fields' => array( | |
| 179 | - 'screenshot_url' => true, | |
| 180 | - 'description' => true, | |
| 181 | - 'rating' => true, | |
| 182 | - 'downloaded' => true, | |
| 183 | - 'downloadlink' => true, | |
| 184 | - 'last_updated' => true, | |
| 185 | - 'homepage' => true, | |
| 186 | - 'num_ratings' => true, | |
| 187 | - 'tags' => true, | |
| 188 | - 'parent' => true, | |
| 189 | - // 'extended_author' => true, @todo: WordPress.org throws a 500 server error when this is here. | |
| 179 | + 'per_page' => 100, | |
| 180 | + 'fields' => array( | |
| 181 | + 'reviews_url' => true, // Explicitly request the reviews URL to be linked from the customizer. | |
| 190 | 182 | ), |
| 191 | 183 | ); |
| 192 | 184 | |
| 193 | 185 | $args = array_merge( $wporg_args, $args ); |
| @@ -204,20 +196,20 @@ | ||
| 204 | 196 | wp_send_json_error(); |
| 205 | 197 | } |
| 206 | 198 | |
| 207 | 199 | // This list matches the allowed tags in wp-admin/includes/theme-install.php. |
| 208 | - $themes_allowedtags = array_fill_keys( | |
| 200 | + $themes_allowedtags = array_fill_keys( | |
| 209 | 201 | array( 'a', 'abbr', 'acronym', 'code', 'pre', 'em', 'strong', 'div', 'p', 'ul', 'ol', 'li', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'img' ), |
| 210 | 202 | array() |
| 211 | 203 | ); |
| 212 | - $themes_allowedtags['a'] = array_fill_keys( array( 'href', 'title', 'target' ), true ); | |
| 204 | + $themes_allowedtags['a'] = array_fill_keys( array( 'href', 'title', 'target' ), true ); | |
| 213 | 205 | $themes_allowedtags['acronym']['title'] = true; |
| 214 | - $themes_allowedtags['abbr']['title'] = true; | |
| 215 | - $themes_allowedtags['img'] = array_fill_keys( array( 'src', 'class', 'alt' ), true ); | |
| 206 | + $themes_allowedtags['abbr']['title'] = true; | |
| 207 | + $themes_allowedtags['img'] = array_fill_keys( array( 'src', 'class', 'alt' ), true ); | |
| 216 | 208 | |
| 217 | 209 | // Prepare a list of installed themes to check against before the loop. |
| 218 | 210 | $installed_themes = array(); |
| 219 | - $wp_themes = wp_get_themes(); | |
| 211 | + $wp_themes = wp_get_themes(); | |
| 220 | 212 | foreach ( $wp_themes as $theme ) { |
| 221 | 213 | $installed_themes[] = $theme->get_stylesheet(); |
| 222 | 214 | } |
| 223 | 215 | $update_php = network_admin_url( 'update.php?action=install-theme' ); |
| @@ -223,24 +215,27 @@ | ||
| 223 | 215 | $update_php = network_admin_url( 'update.php?action=install-theme' ); |
| 224 | 216 | |
| 225 | 217 | // Set up properties for themes available on WordPress.org. |
| 226 | 218 | foreach ( $themes->themes as &$theme ) { |
| 227 | - $theme->install_url = add_query_arg( array( | |
| 228 | - 'theme' => $theme->slug, | |
| 229 | - '_wpnonce' => wp_create_nonce( 'install-theme_' . $theme->slug ), | |
| 230 | - ), $update_php ); | |
| 219 | + $theme->install_url = add_query_arg( | |
| 220 | + array( | |
| 221 | + 'theme' => $theme->slug, | |
| 222 | + '_wpnonce' => wp_create_nonce( 'install-theme_' . $theme->slug ), | |
| 223 | + ), | |
| 224 | + $update_php | |
| 225 | + ); | |
| 231 | 226 | |
| 232 | 227 | $theme->name = wp_kses( $theme->name, $themes_allowedtags ); |
| 233 | - $theme->author = wp_kses( $theme->author, $themes_allowedtags ); | |
| 234 | 228 | $theme->version = wp_kses( $theme->version, $themes_allowedtags ); |
| 235 | 229 | $theme->description = wp_kses( $theme->description, $themes_allowedtags ); |
| 236 | - $theme->tags = implode( ', ', $theme->tags ); | |
| 237 | - $theme->stars = wp_star_rating( array( | |
| 238 | - 'rating' => $theme->rating, | |
| 239 | - 'type' => 'percent', | |
| 240 | - 'number' => $theme->num_ratings, | |
| 241 | - 'echo' => false, | |
| 242 | - ) ); | |
| 230 | + $theme->stars = wp_star_rating( | |
| 231 | + array( | |
| 232 | + 'rating' => $theme->rating, | |
| 233 | + 'type' => 'percent', | |
| 234 | + 'number' => $theme->num_ratings, | |
| 235 | + 'echo' => false, | |
| 236 | + ) | |
| 237 | + ); | |
| 243 | 238 | $theme->num_ratings = number_format_i18n( $theme->num_ratings ); |
| 244 | 239 | $theme->preview_url = set_url_scheme( $theme->preview_url ); |
| 245 | 240 | |
| 246 | 241 | // Handle themes that are already installed as installed themes. |
| @@ -253,12 +248,14 @@ | ||
| 253 | 248 | // Set active based on customized theme. |
| 254 | 249 | $theme->active = ( isset( $_POST['customized_theme'] ) && $_POST['customized_theme'] === $theme->slug ); |
| 255 | 250 | |
| 256 | 251 | // Map available theme properties to installed theme properties. |
| 257 | - $theme->id = $theme->slug; | |
| 258 | - $theme->screenshot = array( $theme->screenshot_url ); | |
| 259 | - $theme->authorAndUri = $theme->author; | |
| 260 | - // The .org API can return the full parent theme details if passed the 'parent' arg, or if passed the 'template' option it'll return that in the event it's a child theme. | |
| 252 | + $theme->id = $theme->slug; | |
| 253 | + $theme->screenshot = array( $theme->screenshot_url ); | |
| 254 | + $theme->authorAndUri = wp_kses( $theme->author['display_name'], $themes_allowedtags ); | |
| 255 | + $theme->compatibleWP = is_wp_version_compatible( $theme->requires ); // phpcs:ignore WordPress.NamingConventions.ValidVariableName | |
| 256 | + $theme->compatiblePHP = is_php_version_compatible( $theme->requires_php ); // phpcs:ignore WordPress.NamingConventions.ValidVariableName | |
| 257 | + | |
| 261 | 258 | if ( isset( $theme->parent ) ) { |
| 262 | 259 | $theme->parent = $theme->parent['slug']; |
| 263 | 260 | } else { |
| 264 | 261 | $theme->parent = false; |
| @@ -277,19 +274,9 @@ | ||
| 277 | 274 | // Arguments for all queries. |
| 278 | 275 | $wporg_args = array( |
| 279 | 276 | 'per_page' => 100, |
| 280 | 277 | 'fields' => array( |
| 281 | - 'screenshot_url' => true, | |
| 282 | - 'description' => true, | |
| 283 | - 'rating' => true, | |
| 284 | - 'downloaded' => true, | |
| 285 | - 'downloadlink' => true, | |
| 286 | - 'last_updated' => true, | |
| 287 | - 'homepage' => true, | |
| 288 | - 'num_ratings' => true, | |
| 289 | - 'tags' => true, | |
| 290 | - 'parent' => true, | |
| 291 | - // 'extended_author' => true, @todo: WordPress.org throws a 500 server error when this is here. | |
| 278 | + 'reviews_url' => true, // Explicitly request the reviews URL to be linked from the customizer. | |
| 292 | 279 | ), |
| 293 | 280 | ); |
| 294 | 281 | |
| 295 | 282 | $args = array_merge( $wporg_args, $args ); |
| @@ -304,9 +291,9 @@ | ||
| 304 | 291 | wp_send_json_error(); |
| 305 | 292 | } |
| 306 | 293 | |
| 307 | 294 | // This list matches the allowed tags in wp-admin/includes/theme-install.php. |
| 308 | - $themes_allowedtags = array_fill_keys( | |
| 295 | + $themes_allowedtags = array_fill_keys( | |
| 309 | 296 | array( 'a', 'abbr', 'acronym', 'code', 'pre', 'em', 'strong', 'div', 'p', 'ul', 'ol', 'li', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'img' ), |
| 310 | 297 | array() |
| 311 | 298 | ); |
| 312 | 299 | $themes_allowedtags['a'] = array_fill_keys( array( 'href', 'title', 'target' ), true ); |
| @@ -315,9 +302,9 @@ | ||
| 315 | 302 | $themes_allowedtags['img'] = array_fill_keys( array( 'src', 'class', 'alt' ), true ); |
| 316 | 303 | |
| 317 | 304 | // Prepare a list of installed themes to check against before the loop. |
| 318 | 305 | $installed_themes = array(); |
| 319 | - $wp_themes = wp_get_themes(); | |
| 306 | + $wp_themes = wp_get_themes(); | |
| 320 | 307 | foreach ( $wp_themes as $theme ) { |
| 321 | 308 | $installed_themes[] = $theme->get_stylesheet(); |
| 322 | 309 | } |
| 323 | 310 | $update_php = network_admin_url( 'update.php?action=install-theme' ); |
| @@ -323,24 +310,27 @@ | ||
| 323 | 310 | $update_php = network_admin_url( 'update.php?action=install-theme' ); |
| 324 | 311 | |
| 325 | 312 | // Set up properties for themes available on WordPress.org. |
| 326 | 313 | foreach ( $themes->themes as &$theme ) { |
| 327 | - $theme->install_url = add_query_arg( array( | |
| 328 | - 'theme' => $theme->slug, | |
| 329 | - '_wpnonce' => wp_create_nonce( 'install-theme_' . $theme->slug ), | |
| 330 | - ), $update_php ); | |
| 314 | + $theme->install_url = add_query_arg( | |
| 315 | + array( | |
| 316 | + 'theme' => $theme->slug, | |
| 317 | + '_wpnonce' => wp_create_nonce( 'install-theme_' . $theme->slug ), | |
| 318 | + ), | |
| 319 | + $update_php | |
| 320 | + ); | |
| 331 | 321 | |
| 332 | 322 | $theme->name = wp_kses( $theme->name, $themes_allowedtags ); |
| 333 | - $theme->author = wp_kses( $theme->author, $themes_allowedtags ); | |
| 334 | 323 | $theme->version = wp_kses( $theme->version, $themes_allowedtags ); |
| 335 | 324 | $theme->description = wp_kses( $theme->description, $themes_allowedtags ); |
| 336 | - $theme->tags = implode( ', ', $theme->tags ); | |
| 337 | - $theme->stars = wp_star_rating( array( | |
| 338 | - 'rating' => $theme->rating, | |
| 339 | - 'type' => 'percent', | |
| 340 | - 'number' => $theme->num_ratings, | |
| 341 | - 'echo' => false, | |
| 342 | - ) ); | |
| 325 | + $theme->stars = wp_star_rating( | |
| 326 | + array( | |
| 327 | + 'rating' => $theme->rating, | |
| 328 | + 'type' => 'percent', | |
| 329 | + 'number' => $theme->num_ratings, | |
| 330 | + 'echo' => false, | |
| 331 | + ) | |
| 332 | + ); | |
| 343 | 333 | $theme->num_ratings = number_format_i18n( $theme->num_ratings ); |
| 344 | 334 | $theme->preview_url = set_url_scheme( $theme->preview_url ); |
| 345 | 335 | |
| 346 | 336 | // Handle themes that are already installed as installed themes. |
| @@ -353,12 +343,14 @@ | ||
| 353 | 343 | // Set active based on customized theme. |
| 354 | 344 | $theme->active = ( isset( $_POST['customized_theme'] ) && $_POST['customized_theme'] === $theme->slug ); |
| 355 | 345 | |
| 356 | 346 | // Map available theme properties to installed theme properties. |
| 357 | - $theme->id = $theme->slug; | |
| 358 | - $theme->screenshot = array( $theme->screenshot_url ); | |
| 359 | - $theme->authorAndUri = $theme->author; | |
| 360 | - // The .org API can return the full parent theme details if passed the 'parent' arg, or if passed the 'template' option it'll return that in the event it's a child theme. | |
| 347 | + $theme->id = $theme->slug; | |
| 348 | + $theme->screenshot = array( $theme->screenshot_url ); | |
| 349 | + $theme->authorAndUri = wp_kses( $theme->author['display_name'], $themes_allowedtags ); | |
| 350 | + $theme->compatibleWP = is_wp_version_compatible( $theme->requires ); // phpcs:ignore WordPress.NamingConventions.ValidVariableName | |
| 351 | + $theme->compatiblePHP = is_php_version_compatible( $theme->requires_php ); // phpcs:ignore WordPress.NamingConventions.ValidVariableName | |
| 352 | + | |
| 361 | 353 | if ( isset( $theme->parent ) ) { |
| 362 | 354 | $theme->parent = $theme->parent['slug']; |
| 363 | 355 | } else { |
| 364 | 356 | $theme->parent = false; |
| @@ -385,22 +377,21 @@ | ||
| 385 | 377 | * @param array $themes Nested array of theme data. |
| 386 | 378 | * @param array $args List of arguments, such as page, search term, and tags to query for. |
| 387 | 379 | * @param WP_Customize_Manager $manager Instance of Customize manager. |
| 388 | 380 | */ |
| 389 | - $themes = apply_filters( 'customize_load_themes', $themes, $args, $wp_customize ); | |
| 381 | + $themes = apply_filters( 'customize_load_themes', $themes, $args, $wp_customize ); // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound -- Core WordPress hook, not plugin-defined. | |
| 390 | 382 | |
| 391 | 383 | wp_send_json_success( $themes ); |
| 392 | 384 | } |
| 393 | 385 | |
| 394 | - /* Plugins */ | |
| 395 | - /* Adds Catch Plugins tab in Add Plugin page to show all plugins by Catch Plugins in wordpress.org */ | |
| 396 | - public function add_our_plugins_tab($tabs) { | |
| 397 | - // Add our filter here | |
| 398 | - $tabs['catchplugins'] = _x( 'Catch Plugins', 'Plugin Installer' ); | |
| 386 | + public function add_our_plugins_tab( $tabs ) { | |
| 387 | + // Translators: Tab label in the Plugin Installer for listing Catch Plugins. | |
| 388 | + $tabs['catchplugins'] = _x( 'Catch Plugins', 'Plugin Installer', 'essential-widgets' ); | |
| 399 | 389 | |
| 400 | - return $tabs; | |
| 390 | + return $tabs; | |
| 401 | 391 | } |
| 402 | 392 | |
| 393 | + | |
| 403 | 394 | public function catchplugins() { |
| 404 | 395 | /* From CORE Start */ |
| 405 | 396 | global $paged, $tab; |
| 406 | 397 | wp_reset_vars( array( 'tab' ) ); |
| @@ -405,9 +396,9 @@ | ||
| 405 | 396 | global $paged, $tab; |
| 406 | 397 | wp_reset_vars( array( 'tab' ) ); |
| 407 | 398 | |
| 408 | 399 | $defined_class = new WP_Plugin_Install_List_Table(); |
| 409 | - $paged = $defined_class->get_pagenum(); | |
| 400 | + $paged = $defined_class->get_pagenum(); | |
| 410 | 401 | |
| 411 | 402 | $per_page = 30; |
| 412 | 403 | //$installed_plugins = catch_get_installed_plugins(); |
| 413 | 404 | |
| @@ -416,12 +407,12 @@ | ||
| 416 | 407 | 'per_page' => $per_page, |
| 417 | 408 | 'fields' => array( |
| 418 | 409 | 'last_updated' => true, |
| 419 | 410 | 'icons' => true, |
| 420 | - 'active_installs' => true | |
| 411 | + 'active_installs' => true, | |
| 421 | 412 | ), |
| 422 | 413 | // Send the locale and installed plugin slugs to the API so it can provide context-sensitive results. |
| 423 | - 'locale' => get_user_locale(), | |
| 414 | + 'locale' => get_user_locale(), | |
| 424 | 415 | //'installed_plugins' => array_keys( $installed_plugins ), |
| 425 | 416 | ); |
| 426 | 417 | /* From CORE End */ |
| 427 | 418 | |
| @@ -433,10 +424,14 @@ | ||
| 433 | 424 | |
| 434 | 425 | public function plugins_table() { |
| 435 | 426 | global $wp_list_table; |
| 436 | 427 | printf( |
| 437 | - '<p class="catch-plugins-list">' . __( 'You can use any of our free plugins or premium plugins from <a href="%s" target="_blank">Catch Plugins</a>' ) . '.</p>', | |
| 438 | - 'https://catchplugins.com/' | |
| 428 | + '<p class="catch-plugins-list">%s</p>', | |
| 429 | + sprintf( | |
| 430 | + // Translators: %s is the URL to the Catch Plugins website. | |
| 431 | + wp_kses_post( __( 'You can use any of our free plugins or premium plugins from <a href="%s" target="_blank">Catch Plugins</a>.', 'essential-widgets' ) ), | |
| 432 | + esc_url( 'https://catchplugins.com/' ) | |
| 433 | + ) | |
| 439 | 434 | ); |
| 440 | 435 | ?> |
| 441 | 436 | <form id="plugin-filter" method="post"> |
| 442 | 437 | <?php $wp_list_table->display(); ?> |
| @@ -444,5 +439,5 @@ | ||
| 444 | 439 | <?php |
| 445 | 440 | } |
| 446 | 441 | } |
| 447 | 442 | |
| 448 | -$catchthemes_theme_plugin = new CatchThemesThemePlugin(); | |
| 443 | +$catchthemes_theme_plugin = new CatchThemesThemePlugin(); // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedVariableFound -- File-scope bootstrap variable used immediately. | |