PluginProbe
Essential Widgets / 3.0
Essential Widgets v3.0
3.2.1 3.3 3.2 trunk 1.0.0 1.0.1 1.1 1.2 1.2.1 1.2.2 1.3 1.4 1.4.1 1.5 1.6 1.7 1.7.1 1.7.2 1.7.3 1.7.4 1.8 1.9 2.0 2.1 2.2 All 31 releases
essential-widgets / includes / CatchThemesThemePlugin.php

CatchThemesThemePlugin.php in Essential Widgets 3.0, at includes/CatchThemesThemePlugin.php

444 lines 14.7 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 if ( ! defined( 'ABSPATH' ) ) {
4 exit; // Exit if accessed directly.
5 }
6
7 class CatchThemesThemePlugin {
8 public function __construct() {
9 remove_action( 'wp_ajax_query-themes', array( $this, 'wp_ajax_query_themes' ), 1 );
10 add_action( 'wp_ajax_query-themes', array( $this, 'wp_ajax_custom_query_themes' ), 1 );
11
12 add_action( 'admin_enqueue_scripts', array( $this, 'our_themes_script' ) );
13
14 if ( ! is_multisite() ) {
15 add_action( 'customize_register', array( $this, 'customize_register' ) );
16 }
17
18 global $wp_customize;
19 remove_action( 'wp_ajax_customize_load_themes', array( $wp_customize, 'handle_load_themes_request' ) );
20 add_action( 'wp_ajax_customize_load_themes', array( $this, 'handle_load_themes_request' ) );
21
22 add_filter( 'install_plugins_tabs', array( $this, 'add_our_plugins_tab' ), 1 );
23 add_filter( 'install_plugins_table_api_args_catchplugins', array( $this, 'catchplugins' ), 1 );
24 add_action( 'install_plugins_catchplugins', array( $this, 'plugins_table' ) );
25 }
26
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 */
36 public function wp_ajax_custom_query_themes() {
37 global $themes_allowedtags, $theme_field_defaults;
38
39 // Capability check
40 if ( ! current_user_can( 'install_themes' ) ) {
41 wp_send_json_error();
42 }
43
44 // Nonce verification
45 check_ajax_referer( 'ew_query_themes_nonce', 'nonce' );
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
71 if ( isset( $args['browse'] ) && 'catchthemes' === $args['browse'] && ! isset( $args['user'] ) ) {
72 $args['author'] = 'catchthemes';
73 unset( $args['browse'] );
74 }
75
76 $old_filter = isset( $args['browse'] ) ? $args['browse'] : 'search';
77
78 $args = apply_filters( 'install_themes_table_api_args_' . $old_filter, $args );
79
80 $api = themes_api( 'query_themes', $args );
81
82 if ( is_wp_error( $api ) ) {
83 wp_send_json_error();
84 }
85
86 foreach ( $api->themes as &$theme ) {
87 $theme->name = wp_kses( $theme->name, $themes_allowedtags );
88 $theme->author = wp_kses( $theme->author['display_name'], $themes_allowedtags );
89 $theme->version = wp_kses( $theme->version, $themes_allowedtags );
90 $theme->description = wp_kses( $theme->description, $themes_allowedtags );
91 }
92
93 wp_send_json_success( $api );
94 }
95
96 public function our_themes_script( $hook_suffix ) {
97
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' );
100 }
101 }
102
103 /* Add Catch Themes Section in Theme in Customizer */
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 );
118 }
119
120
121
122
123 /**
124 * Load themes into the theme browsing/installation UI.
125 * taken from wp-includes/cllass-wp-customize-manager.php
126 * @since 4.9.0
127 */
128 public function handle_load_themes_request() {
129 check_ajax_referer( 'switch_themes', 'nonce' );
130 if ( ! current_user_can( 'switch_themes' ) ) {
131 wp_die( -1 );
132 }
133
134 if ( empty( $_POST['theme_action'] ) ) {
135 wp_send_json_error( 'missing_theme_action' );
136 }
137 $theme_action = sanitize_key( $_POST['theme_action'] );
138 $themes = array();
139 $args = array();
140
141 // Define query filters based on user input.
142 if ( ! array_key_exists( 'search', $_POST ) ) {
143 $args['search'] = '';
144 } else {
145 $args['search'] = sanitize_text_field( wp_unslash( $_POST['search'] ) );
146 }
147
148 if ( ! array_key_exists( 'tags', $_POST ) ) {
149 $args['tag'] = '';
150 } else {
151 $args['tag'] = array_map( 'sanitize_text_field', wp_unslash( (array) $_POST['tags'] ) );
152 }
153
154 if ( ! array_key_exists( 'page', $_POST ) ) {
155 $args['page'] = 1;
156 } else {
157 $args['page'] = absint( $_POST['page'] );
158 }
159
160 require_once ABSPATH . 'wp-admin/includes/theme.php';
161
162 if ( 'installed' === $theme_action ) {
163
164 // Load all installed themes from wp_prepare_themes_for_js().
165 $themes = array( 'themes' => wp_prepare_themes_for_js() );
166 foreach ( $themes['themes'] as &$theme ) {
167 $theme['type'] = 'installed';
168 $theme['active'] = ( isset( $_POST['customized_theme'] ) && $_POST['customized_theme'] === $theme['id'] );
169 }
170 } elseif ( 'catchthemes' === $theme_action ) {
171
172 // Load WordPress.org themes from the .org API and normalize data to match installed theme objects.
173 if ( ! current_user_can( 'install_themes' ) ) {
174 wp_die( -1 );
175 }
176
177 // Arguments for all queries.
178 $wporg_args = array(
179 'per_page' => 100,
180 'fields' => array(
181 'reviews_url' => true, // Explicitly request the reviews URL to be linked from the customizer.
182 ),
183 );
184
185 $args = array_merge( $wporg_args, $args );
186
187 if ( '' === $args['search'] && '' === $args['tag'] ) {
188 $args['browse'] = 'new'; // Sort by latest themes by default.
189 }
190
191 $args['author'] = 'catchthemes';
192
193 // Load themes from the .org API.
194 $themes = themes_api( 'query_themes', $args );
195 if ( is_wp_error( $themes ) ) {
196 wp_send_json_error();
197 }
198
199 // This list matches the allowed tags in wp-admin/includes/theme-install.php.
200 $themes_allowedtags = array_fill_keys(
201 array( 'a', 'abbr', 'acronym', 'code', 'pre', 'em', 'strong', 'div', 'p', 'ul', 'ol', 'li', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'img' ),
202 array()
203 );
204 $themes_allowedtags['a'] = array_fill_keys( array( 'href', 'title', 'target' ), true );
205 $themes_allowedtags['acronym']['title'] = true;
206 $themes_allowedtags['abbr']['title'] = true;
207 $themes_allowedtags['img'] = array_fill_keys( array( 'src', 'class', 'alt' ), true );
208
209 // Prepare a list of installed themes to check against before the loop.
210 $installed_themes = array();
211 $wp_themes = wp_get_themes();
212 foreach ( $wp_themes as $theme ) {
213 $installed_themes[] = $theme->get_stylesheet();
214 }
215 $update_php = network_admin_url( 'update.php?action=install-theme' );
216
217 // Set up properties for themes available on WordPress.org.
218 foreach ( $themes->themes as &$theme ) {
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 );
226
227 $theme->name = wp_kses( $theme->name, $themes_allowedtags );
228 $theme->version = wp_kses( $theme->version, $themes_allowedtags );
229 $theme->description = wp_kses( $theme->description, $themes_allowedtags );
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 );
238 $theme->num_ratings = number_format_i18n( $theme->num_ratings );
239 $theme->preview_url = set_url_scheme( $theme->preview_url );
240
241 // Handle themes that are already installed as installed themes.
242 if ( in_array( $theme->slug, $installed_themes, true ) ) {
243 $theme->type = 'installed';
244 } else {
245 $theme->type = $theme_action;
246 }
247
248 // Set active based on customized theme.
249 $theme->active = ( isset( $_POST['customized_theme'] ) && $_POST['customized_theme'] === $theme->slug );
250
251 // Map available theme properties to installed theme properties.
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
258 if ( isset( $theme->parent ) ) {
259 $theme->parent = $theme->parent['slug'];
260 } else {
261 $theme->parent = false;
262 }
263 unset( $theme->slug );
264 unset( $theme->screenshot_url );
265 unset( $theme->author );
266 } // End foreach().
267 } elseif ( 'wporg' === $theme_action ) {
268
269 // Load WordPress.org themes from the .org API and normalize data to match installed theme objects.
270 if ( ! current_user_can( 'install_themes' ) ) {
271 wp_die( -1 );
272 }
273
274 // Arguments for all queries.
275 $wporg_args = array(
276 'per_page' => 100,
277 'fields' => array(
278 'reviews_url' => true, // Explicitly request the reviews URL to be linked from the customizer.
279 ),
280 );
281
282 $args = array_merge( $wporg_args, $args );
283
284 if ( '' === $args['search'] && '' === $args['tag'] ) {
285 $args['browse'] = 'new'; // Sort by latest themes by default.
286 }
287
288 // Load themes from the .org API.
289 $themes = themes_api( 'query_themes', $args );
290 if ( is_wp_error( $themes ) ) {
291 wp_send_json_error();
292 }
293
294 // This list matches the allowed tags in wp-admin/includes/theme-install.php.
295 $themes_allowedtags = array_fill_keys(
296 array( 'a', 'abbr', 'acronym', 'code', 'pre', 'em', 'strong', 'div', 'p', 'ul', 'ol', 'li', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'img' ),
297 array()
298 );
299 $themes_allowedtags['a'] = array_fill_keys( array( 'href', 'title', 'target' ), true );
300 $themes_allowedtags['acronym']['title'] = true;
301 $themes_allowedtags['abbr']['title'] = true;
302 $themes_allowedtags['img'] = array_fill_keys( array( 'src', 'class', 'alt' ), true );
303
304 // Prepare a list of installed themes to check against before the loop.
305 $installed_themes = array();
306 $wp_themes = wp_get_themes();
307 foreach ( $wp_themes as $theme ) {
308 $installed_themes[] = $theme->get_stylesheet();
309 }
310 $update_php = network_admin_url( 'update.php?action=install-theme' );
311
312 // Set up properties for themes available on WordPress.org.
313 foreach ( $themes->themes as &$theme ) {
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 );
321
322 $theme->name = wp_kses( $theme->name, $themes_allowedtags );
323 $theme->version = wp_kses( $theme->version, $themes_allowedtags );
324 $theme->description = wp_kses( $theme->description, $themes_allowedtags );
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 );
333 $theme->num_ratings = number_format_i18n( $theme->num_ratings );
334 $theme->preview_url = set_url_scheme( $theme->preview_url );
335
336 // Handle themes that are already installed as installed themes.
337 if ( in_array( $theme->slug, $installed_themes, true ) ) {
338 $theme->type = 'installed';
339 } else {
340 $theme->type = $theme_action;
341 }
342
343 // Set active based on customized theme.
344 $theme->active = ( isset( $_POST['customized_theme'] ) && $_POST['customized_theme'] === $theme->slug );
345
346 // Map available theme properties to installed theme properties.
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
353 if ( isset( $theme->parent ) ) {
354 $theme->parent = $theme->parent['slug'];
355 } else {
356 $theme->parent = false;
357 }
358 unset( $theme->slug );
359 unset( $theme->screenshot_url );
360 unset( $theme->author );
361 } // End foreach().
362 } // End if().
363
364 /**
365 * Filters the theme data loaded in the customizer.
366 *
367 * This allows theme data to be loading from an external source,
368 * or modification of data loaded from `wp_prepare_themes_for_js()`
369 * or WordPress.org via `themes_api()`.
370 *
371 * @since 4.9.0
372 *
373 * @see wp_prepare_themes_for_js()
374 * @see themes_api()
375 * @see WP_Customize_Manager::__construct()
376 *
377 * @param array $themes Nested array of theme data.
378 * @param array $args List of arguments, such as page, search term, and tags to query for.
379 * @param WP_Customize_Manager $manager Instance of Customize manager.
380 */
381 $themes = apply_filters( 'customize_load_themes', $themes, $args, $wp_customize );
382
383 wp_send_json_success( $themes );
384 }
385
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' );
389
390 return $tabs;
391 }
392
393
394 public function catchplugins() {
395 /* From CORE Start */
396 global $paged, $tab;
397 wp_reset_vars( array( 'tab' ) );
398
399 $defined_class = new WP_Plugin_Install_List_Table();
400 $paged = $defined_class->get_pagenum();
401
402 $per_page = 30;
403 //$installed_plugins = catch_get_installed_plugins();
404
405 $args = array(
406 'page' => $paged,
407 'per_page' => $per_page,
408 'fields' => array(
409 'last_updated' => true,
410 'icons' => true,
411 'active_installs' => true,
412 ),
413 // Send the locale and installed plugin slugs to the API so it can provide context-sensitive results.
414 'locale' => get_user_locale(),
415 //'installed_plugins' => array_keys( $installed_plugins ),
416 );
417 /* From CORE End */
418
419 // Add author filter for our plugins
420 $args['author'] = 'catchplugins';
421
422 return $args;
423 }
424
425 public function plugins_table() {
426 global $wp_list_table;
427 printf(
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 )
434 );
435 ?>
436 <form id="plugin-filter" method="post">
437 <?php $wp_list_table->display(); ?>
438 </form>
439 <?php
440 }
441 }
442
443 $catchthemes_theme_plugin = new CatchThemesThemePlugin();
444