PluginProbe
Catch Breadcrumb / trunk
Catch Breadcrumb vtrunk
trunk 1.0.0 1.0.1 1.0.2 1.1 1.2 1.3 1.4 1.5 1.5.1 1.5.2 1.5.3 1.5.4 1.5.5 1.5.6 1.5.7 1.5.8 1.5.9 1.6 1.7 1.8 1.9 2.0 2.1 2.2 All 29 releases
catch-breadcrumb / includes / CatchThemesThemePlugin.php

CatchThemesThemePlugin.php in Catch Breadcrumb trunk, at includes/CatchThemesThemePlugin.php

497 lines 15.9 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 {
9 public function __construct()
10 {
11 remove_action('wp_ajax_query-themes', array($this, 'wp_ajax_query_themes'), 1);
12 add_action('wp_ajax_query-themes', array($this, 'wp_ajax_custom_query_themes'), 1);
13
14 add_action('admin_enqueue_scripts', array($this, 'our_themes_script'));
15
16 if (! is_multisite()) {
17 add_action('customize_register', array($this, 'customize_register'));
18 }
19
20 global $wp_customize;
21 remove_action('wp_ajax_customize_load_themes', array($wp_customize, 'handle_load_themes_request'));
22 add_action('wp_ajax_customize_load_themes', array($this, 'handle_load_themes_request'));
23
24 add_filter('install_plugins_tabs', array($this, 'add_our_plugins_tab'), 1);
25 add_filter('install_plugins_table_api_args_catchplugins', array($this, 'catchplugins'), 1);
26 add_action('install_plugins_catchplugins', array($this, 'plugins_table'));
27 }
28
29 /* Adds Catch Themes tab in Add Theme page to show all themes by Catch Themes in wordpress.org
30 * taken from wp-admin/includes/ajax-action.php wp_ajax_query_themes().
31 * Ajax handler for getting themes from themes_api().
32 *
33 * @since 3.9.0
34 *
35 * @global array $themes_allowedtags
36 * @global array $theme_field_defaults
37 */
38 public function wp_ajax_custom_query_themes()
39 {
40 global $themes_allowedtags, $theme_field_defaults;
41
42 if (! current_user_can('install_themes')) {
43 wp_send_json_error();
44 }
45
46 $args = wp_parse_args(
47 wp_unslash($_REQUEST['request']),
48 array(
49 'per_page' => 20,
50 'fields' => array_merge(
51 (array) $theme_field_defaults,
52 array(
53 'reviews_url' => true, // Explicitly request the reviews URL to be linked from the Add Themes screen.
54 )
55 ),
56 )
57 );
58
59 if (isset($args['browse']) && 'catchthemes' === $args['browse'] && ! isset($args['user'])) {
60 $args['author'] = 'catchthemes';
61 unset($args['browse']);
62 }
63
64 if (isset($args['browse']) && 'favorites' === $args['browse'] && ! isset($args['user'])) {
65 $user = get_user_option('wporg_favorites');
66 if ($user) {
67 $args['user'] = $user;
68 }
69 }
70
71 $old_filter = isset($args['browse']) ? $args['browse'] : 'search';
72
73 /** This filter is documented in wp-admin/includes/class-wp-theme-install-list-table.php */
74 $args = apply_filters('install_themes_table_api_args_' . $old_filter, $args);
75
76 $api = themes_api('query_themes', $args);
77
78 if (is_wp_error($api)) {
79 wp_send_json_error();
80 }
81
82 $update_php = network_admin_url('update.php?action=install-theme');
83 foreach ($api->themes as &$theme) {
84 $theme->install_url = add_query_arg(
85 array(
86 'theme' => $theme->slug,
87 '_wpnonce' => wp_create_nonce('install-theme_' . $theme->slug),
88 ),
89 $update_php
90 );
91
92 if (current_user_can('switch_themes')) {
93 if (is_multisite()) {
94 $theme->activate_url = add_query_arg(
95 array(
96 'action' => 'enable',
97 '_wpnonce' => wp_create_nonce('enable-theme_' . $theme->slug),
98 'theme' => $theme->slug,
99 ),
100 network_admin_url('themes.php')
101 );
102 } else {
103 $theme->activate_url = add_query_arg(
104 array(
105 'action' => 'activate',
106 '_wpnonce' => wp_create_nonce('switch-theme_' . $theme->slug),
107 'stylesheet' => $theme->slug,
108 ),
109 admin_url('themes.php')
110 );
111 }
112 }
113
114 if (! is_multisite() && current_user_can('edit_theme_options') && current_user_can('customize')) {
115 $theme->customize_url = add_query_arg(
116 array(
117 'return' => urlencode(network_admin_url('theme-install.php', 'relative')),
118 ),
119 wp_customize_url($theme->slug)
120 );
121 }
122
123 $theme->name = wp_kses($theme->name, $themes_allowedtags);
124 $theme->author = wp_kses($theme->author['display_name'], $themes_allowedtags);
125 $theme->version = wp_kses($theme->version, $themes_allowedtags);
126 $theme->description = wp_kses($theme->description, $themes_allowedtags);
127
128 $theme->stars = wp_star_rating(
129 array(
130 'rating' => $theme->rating,
131 'type' => 'percent',
132 'number' => $theme->num_ratings,
133 'echo' => false,
134 )
135 );
136
137 $theme->num_ratings = number_format_i18n($theme->num_ratings);
138 $theme->preview_url = set_url_scheme($theme->preview_url);
139 $theme->compatible_wp = is_wp_version_compatible($theme->requires);
140 $theme->compatible_php = is_php_version_compatible($theme->requires_php);
141 }
142
143 wp_send_json_success($api);
144 }
145
146 public function our_themes_script($hook_suffix)
147 {
148
149 if ('theme-install.php' === $hook_suffix) {
150 wp_enqueue_script('our-themes-script', plugin_dir_url(__FILE__) . '../admin/js/our-themes.js', array('jquery'), '2018-05-16');
151 }
152 }
153
154 /* Add Catch Themes Section in Theme in Customizer */
155 public function customize_register($wp_customize)
156 {
157 $wp_customize->add_section(
158 new WP_Customize_Themes_Section(
159 $wp_customize,
160 'catchthemes',
161 array(
162 'title' => __('Themes by CatchThemes', 'catch-breadcrumb'),
163 'action' => 'catchthemes',
164 'capability' => 'install_themes',
165 'panel' => 'themes',
166 'priority' => 6,
167 )
168 )
169 );
170 }
171
172
173
174
175 /**
176 * Load themes into the theme browsing/installation UI.
177 * taken from wp-includes/cllass-wp-customize-manager.php
178 * @since 4.9.0
179 */
180 public function handle_load_themes_request()
181 {
182 check_ajax_referer('switch_themes', 'nonce');
183 if (! current_user_can('switch_themes')) {
184 wp_die(-1);
185 }
186
187 if (empty($_POST['theme_action'])) {
188 wp_send_json_error('missing_theme_action');
189 }
190 $theme_action = sanitize_key($_POST['theme_action']);
191 $themes = array();
192 $args = array();
193
194 // Define query filters based on user input.
195 if (! array_key_exists('search', $_POST)) {
196 $args['search'] = '';
197 } else {
198 $args['search'] = sanitize_text_field(wp_unslash($_POST['search']));
199 }
200
201 if (! array_key_exists('tags', $_POST)) {
202 $args['tag'] = '';
203 } else {
204 $args['tag'] = array_map('sanitize_text_field', wp_unslash((array) $_POST['tags']));
205 }
206
207 if (! array_key_exists('page', $_POST)) {
208 $args['page'] = 1;
209 } else {
210 $args['page'] = absint($_POST['page']);
211 }
212
213 require_once ABSPATH . 'wp-admin/includes/theme.php';
214
215 if ('installed' === $theme_action) {
216
217 // Load all installed themes from wp_prepare_themes_for_js().
218 $themes = array('themes' => wp_prepare_themes_for_js());
219 foreach ($themes['themes'] as &$theme) {
220 $theme['type'] = 'installed';
221 $theme['active'] = (isset($_POST['customized_theme']) && $_POST['customized_theme'] === $theme['id']);
222 }
223 } elseif ('catchthemes' === $theme_action) {
224
225 // Load WordPress.org themes from the .org API and normalize data to match installed theme objects.
226 if (! current_user_can('install_themes')) {
227 wp_die(-1);
228 }
229
230 // Arguments for all queries.
231 $wporg_args = array(
232 'per_page' => 100,
233 'fields' => array(
234 'reviews_url' => true, // Explicitly request the reviews URL to be linked from the customizer.
235 ),
236 );
237
238 $args = array_merge($wporg_args, $args);
239
240 if ('' === $args['search'] && '' === $args['tag']) {
241 $args['browse'] = 'new'; // Sort by latest themes by default.
242 }
243
244 $args['author'] = 'catchthemes';
245
246 // Load themes from the .org API.
247 $themes = themes_api('query_themes', $args);
248 if (is_wp_error($themes)) {
249 wp_send_json_error();
250 }
251
252 // This list matches the allowed tags in wp-admin/includes/theme-install.php.
253 $themes_allowedtags = array_fill_keys(
254 array('a', 'abbr', 'acronym', 'code', 'pre', 'em', 'strong', 'div', 'p', 'ul', 'ol', 'li', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'img'),
255 array()
256 );
257 $themes_allowedtags['a'] = array_fill_keys(array('href', 'title', 'target'), true);
258 $themes_allowedtags['acronym']['title'] = true;
259 $themes_allowedtags['abbr']['title'] = true;
260 $themes_allowedtags['img'] = array_fill_keys(array('src', 'class', 'alt'), true);
261
262 // Prepare a list of installed themes to check against before the loop.
263 $installed_themes = array();
264 $wp_themes = wp_get_themes();
265 foreach ($wp_themes as $theme) {
266 $installed_themes[] = $theme->get_stylesheet();
267 }
268 $update_php = network_admin_url('update.php?action=install-theme');
269
270 // Set up properties for themes available on WordPress.org.
271 foreach ($themes->themes as &$theme) {
272 $theme->install_url = add_query_arg(
273 array(
274 'theme' => $theme->slug,
275 '_wpnonce' => wp_create_nonce('install-theme_' . $theme->slug),
276 ),
277 $update_php
278 );
279
280 $theme->name = wp_kses($theme->name, $themes_allowedtags);
281 $theme->version = wp_kses($theme->version, $themes_allowedtags);
282 $theme->description = wp_kses($theme->description, $themes_allowedtags);
283 $theme->stars = wp_star_rating(
284 array(
285 'rating' => $theme->rating,
286 'type' => 'percent',
287 'number' => $theme->num_ratings,
288 'echo' => false,
289 )
290 );
291 $theme->num_ratings = number_format_i18n($theme->num_ratings);
292 $theme->preview_url = set_url_scheme($theme->preview_url);
293
294 // Handle themes that are already installed as installed themes.
295 if (in_array($theme->slug, $installed_themes, true)) {
296 $theme->type = 'installed';
297 } else {
298 $theme->type = $theme_action;
299 }
300
301 // Set active based on customized theme.
302 $theme->active = (isset($_POST['customized_theme']) && $_POST['customized_theme'] === $theme->slug);
303
304 // Map available theme properties to installed theme properties.
305 $theme->id = $theme->slug;
306 $theme->screenshot = array($theme->screenshot_url);
307 $theme->authorAndUri = wp_kses($theme->author['display_name'], $themes_allowedtags);
308 $theme->compatibleWP = is_wp_version_compatible($theme->requires); // phpcs:ignore WordPress.NamingConventions.ValidVariableName
309 $theme->compatiblePHP = is_php_version_compatible($theme->requires_php); // phpcs:ignore WordPress.NamingConventions.ValidVariableName
310
311 if (isset($theme->parent)) {
312 $theme->parent = $theme->parent['slug'];
313 } else {
314 $theme->parent = false;
315 }
316 unset($theme->slug);
317 unset($theme->screenshot_url);
318 unset($theme->author);
319 } // End foreach().
320 } elseif ('wporg' === $theme_action) {
321
322 // Load WordPress.org themes from the .org API and normalize data to match installed theme objects.
323 if (! current_user_can('install_themes')) {
324 wp_die(-1);
325 }
326
327 // Arguments for all queries.
328 $wporg_args = array(
329 'per_page' => 100,
330 'fields' => array(
331 'reviews_url' => true, // Explicitly request the reviews URL to be linked from the customizer.
332 ),
333 );
334
335 $args = array_merge($wporg_args, $args);
336
337 if ('' === $args['search'] && '' === $args['tag']) {
338 $args['browse'] = 'new'; // Sort by latest themes by default.
339 }
340
341 // Load themes from the .org API.
342 $themes = themes_api('query_themes', $args);
343 if (is_wp_error($themes)) {
344 wp_send_json_error();
345 }
346
347 // This list matches the allowed tags in wp-admin/includes/theme-install.php.
348 $themes_allowedtags = array_fill_keys(
349 array('a', 'abbr', 'acronym', 'code', 'pre', 'em', 'strong', 'div', 'p', 'ul', 'ol', 'li', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'img'),
350 array()
351 );
352 $themes_allowedtags['a'] = array_fill_keys(array('href', 'title', 'target'), true);
353 $themes_allowedtags['acronym']['title'] = true;
354 $themes_allowedtags['abbr']['title'] = true;
355 $themes_allowedtags['img'] = array_fill_keys(array('src', 'class', 'alt'), true);
356
357 // Prepare a list of installed themes to check against before the loop.
358 $installed_themes = array();
359 $wp_themes = wp_get_themes();
360 foreach ($wp_themes as $theme) {
361 $installed_themes[] = $theme->get_stylesheet();
362 }
363 $update_php = network_admin_url('update.php?action=install-theme');
364
365 // Set up properties for themes available on WordPress.org.
366 foreach ($themes->themes as &$theme) {
367 $theme->install_url = add_query_arg(
368 array(
369 'theme' => $theme->slug,
370 '_wpnonce' => wp_create_nonce('install-theme_' . $theme->slug),
371 ),
372 $update_php
373 );
374
375 $theme->name = wp_kses($theme->name, $themes_allowedtags);
376 $theme->version = wp_kses($theme->version, $themes_allowedtags);
377 $theme->description = wp_kses($theme->description, $themes_allowedtags);
378 $theme->stars = wp_star_rating(
379 array(
380 'rating' => $theme->rating,
381 'type' => 'percent',
382 'number' => $theme->num_ratings,
383 'echo' => false,
384 )
385 );
386 $theme->num_ratings = number_format_i18n($theme->num_ratings);
387 $theme->preview_url = set_url_scheme($theme->preview_url);
388
389 // Handle themes that are already installed as installed themes.
390 if (in_array($theme->slug, $installed_themes, true)) {
391 $theme->type = 'installed';
392 } else {
393 $theme->type = $theme_action;
394 }
395
396 // Set active based on customized theme.
397 $theme->active = (isset($_POST['customized_theme']) && $_POST['customized_theme'] === $theme->slug);
398
399 // Map available theme properties to installed theme properties.
400 $theme->id = $theme->slug;
401 $theme->screenshot = array($theme->screenshot_url);
402 $theme->authorAndUri = wp_kses($theme->author['display_name'], $themes_allowedtags);
403 $theme->compatibleWP = is_wp_version_compatible($theme->requires); // phpcs:ignore WordPress.NamingConventions.ValidVariableName
404 $theme->compatiblePHP = is_php_version_compatible($theme->requires_php); // phpcs:ignore WordPress.NamingConventions.ValidVariableName
405
406 if (isset($theme->parent)) {
407 $theme->parent = $theme->parent['slug'];
408 } else {
409 $theme->parent = false;
410 }
411 unset($theme->slug);
412 unset($theme->screenshot_url);
413 unset($theme->author);
414 } // End foreach().
415 } // End if().
416
417 /**
418 * Filters the theme data loaded in the customizer.
419 *
420 * This allows theme data to be loading from an external source,
421 * or modification of data loaded from `wp_prepare_themes_for_js()`
422 * or WordPress.org via `themes_api()`.
423 *
424 * @since 4.9.0
425 *
426 * @see wp_prepare_themes_for_js()
427 * @see themes_api()
428 * @see WP_Customize_Manager::__construct()
429 *
430 * @param array $themes Nested array of theme data.
431 * @param array $args List of arguments, such as page, search term, and tags to query for.
432 * @param WP_Customize_Manager $manager Instance of Customize manager.
433 */
434 $themes = apply_filters('customize_load_themes', $themes, $args, $wp_customize);
435
436 wp_send_json_success($themes);
437 }
438
439 /* Plugins */
440 /* Adds Catch Plugins tab in Add Plugin page to show all plugins by Catch Plugins in wordpress.org */
441 public function add_our_plugins_tab($tabs)
442 {
443 // Add our filter here
444 $tabs['catchplugins'] = _x('Catch Plugins', 'Plugin Installer', 'catch-breadcrumb');
445
446 return $tabs;
447 }
448
449 public function catchplugins()
450 {
451 /* From CORE Start */
452 global $paged, $tab;
453 wp_reset_vars(array('tab'));
454
455 $defined_class = new WP_Plugin_Install_List_Table();
456 $paged = $defined_class->get_pagenum();
457
458 $per_page = 30;
459 //$installed_plugins = catch_get_installed_plugins();
460
461 $args = array(
462 'page' => $paged,
463 'per_page' => $per_page,
464 'fields' => array(
465 'last_updated' => true,
466 'icons' => true,
467 'active_installs' => true,
468 ),
469 // Send the locale and installed plugin slugs to the API so it can provide context-sensitive results.
470 'locale' => get_user_locale(),
471 //'installed_plugins' => array_keys( $installed_plugins ),
472 );
473 /* From CORE End */
474
475 // Add author filter for our plugins
476 $args['author'] = 'catchplugins';
477
478 return $args;
479 }
480
481 public function plugins_table()
482 {
483 global $wp_list_table;
484 printf(
485 '<p class="catch-plugins-list">' . wp_kses_post('You can use any of our free plugins or premium plugins from <a href="%s" target="_blank">Catch Plugins</a>') . '.</p>',
486 'https://catchplugins.com/'
487 );
488 ?>
489 <form id="plugin-filter" method="post">
490 <?php $wp_list_table->display(); ?>
491 </form>
492 <?php
493 }
494 }
495
496 $catchthemes_theme_plugin = new CatchThemesThemePlugin();
497