PluginProbe ʕ •ᴥ•ʔ
Catch Scroll Progress Bar / trunk
Catch Scroll Progress Bar vtrunk
trunk 1.0.0 1.1 1.2 1.3 1.4 1.5 1.6 1.6.1 1.6.2 1.6.3 1.6.4 1.6.5 1.6.6 2.0 2.1 2.2
catch-scroll-progress-bar / includes / CatchThemesThemePlugin.php
catch-scroll-progress-bar / includes Last commit date
CatchThemesThemePlugin.php 1 month ago class-catch-scroll-progress-bar-activator.php 7 years ago class-catch-scroll-progress-bar-deactivator.php 7 years ago class-catch-scroll-progress-bar-i18n.php 1 month ago class-catch-scroll-progress-bar-loader.php 5 months ago class-catch-scroll-progress-bar.php 5 months ago ctp-tabs-removal.php 1 month ago index.php 7 years ago
CatchThemesThemePlugin.php
501 lines
1 <?php
2
3 // Exit if accessed directly
4 if (! defined('ABSPATH')) exit;
5
6 class CatchThemesThemePlugin
7 {
8 public function __construct()
9 {
10 remove_action('wp_ajax_query-themes', array($this, 'wp_ajax_query_themes'), 1);
11 add_action('wp_ajax_query-themes', array($this, 'wp_ajax_custom_query_themes'), 1);
12
13 add_action('admin_enqueue_scripts', array($this, 'our_themes_script'));
14
15 if (! is_multisite()) {
16 add_action('customize_register', array($this, 'customize_register'));
17 }
18
19 global $wp_customize;
20 remove_action('wp_ajax_customize_load_themes', array($wp_customize, 'handle_load_themes_request'));
21 add_action('wp_ajax_customize_load_themes', array($this, 'handle_load_themes_request'));
22
23 add_filter('install_plugins_tabs', array($this, 'add_our_plugins_tab'), 1);
24 add_filter('install_plugins_table_api_args_catchplugins', array($this, 'catchplugins'), 1);
25 add_action('install_plugins_catchplugins', array($this, 'plugins_table'));
26 }
27
28 /* Adds Catch Themes tab in Add Theme page to show all themes by Catch Themes in wordpress.org
29 * taken from wp-admin/includes/ajax-action.php wp_ajax_query_themes().
30 * Ajax handler for getting themes from themes_api().
31 *
32 * @since 3.9.0
33 *
34 * @global array $themes_allowedtags
35 * @global array $theme_field_defaults
36 */
37 public function wp_ajax_custom_query_themes()
38 {
39 global $themes_allowedtags, $theme_field_defaults;
40
41 if (! current_user_can('install_themes')) {
42 wp_send_json_error();
43 }
44
45 $request = isset( $_REQUEST['request'] ) ? wp_unslash( $_REQUEST['request'] ) : array(); // phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- Mirrors WordPress core wp_ajax_query_themes(); capability check above is the authorization gate; fields validated downstream by WordPress core themes_api().
46 $args = wp_parse_args(
47 $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); // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound -- WordPress core filter, not a custom hook.
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', true);
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-scroll-progress-bar'),
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); // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound -- WordPress core filter, not a custom hook.
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-scroll-progress-bar');
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">%s</p>',
486 sprintf(
487 // Translators: %s is the URL to the Catch Plugins website.
488 wp_kses_post(__('You can use any of our free plugins or premium plugins from <a href="%s" target="_blank">Catch Plugins</a>.', 'catch-scroll-progress-bar')),
489 esc_url('https://catchplugins.com/')
490 )
491 );
492 ?>
493 <form id="plugin-filter" method="post">
494 <?php $wp_list_table->display(); ?>
495 </form>
496 <?php
497 }
498 }
499
500 $catchthemes_theme_plugin = new CatchThemesThemePlugin();
501