PluginProbe
Essential Widgets / 1.3
Essential Widgets v1.3
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 / our-themes.php

our-themes.php in Essential Widgets 1.3, at includes/our-themes.php

386 lines 14.0 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /* Adds Catch Themes tab in Add Theme page to show all themes by Catch Themes in wordpress.org */
3 if( ! function_exists( 'wp_ajax_custom_query_themes' ) ) {
4 function wp_ajax_custom_query_themes() {
5 global $themes_allowedtags, $theme_field_defaults;
6
7 if ( ! current_user_can( 'install_themes' ) ) {
8 wp_send_json_error();
9 }
10
11 $args = wp_parse_args( wp_unslash( $_REQUEST['request'] ), array(
12 'per_page' => 20,
13 'fields' => $theme_field_defaults
14 ) );
15
16 if ( isset( $args['browse'] ) && 'catchthemes' === $args['browse'] && ! isset( $args['user'] ) ) {
17 $args['author'] = 'catchthemes';
18 }
19
20 if ( isset( $args['browse'] ) && 'favorites' === $args['browse'] && ! isset( $args['user'] ) ) {
21 $user = get_user_option( 'wporg_favorites' );
22 if ( $user ) {
23 $args['user'] = $user;
24 }
25 }
26
27 $old_filter = isset( $args['browse'] ) ? $args['browse'] : 'search';
28
29 /** This filter is documented in wp-admin/includes/class-wp-theme-install-list-table.php */
30 $args = apply_filters( 'install_themes_table_api_args_' . $old_filter, $args );
31
32 $api = themes_api( 'query_themes', $args );
33
34 if ( is_wp_error( $api ) ) {
35 wp_send_json_error();
36 }
37
38 $update_php = network_admin_url( 'update.php?action=install-theme' );
39 foreach ( $api->themes as &$theme ) {
40 $theme->install_url = add_query_arg( array(
41 'theme' => $theme->slug,
42 '_wpnonce' => wp_create_nonce( 'install-theme_' . $theme->slug )
43 ), $update_php );
44
45 if ( current_user_can( 'switch_themes' ) ) {
46 if ( is_multisite() ) {
47 $theme->activate_url = add_query_arg( array(
48 'action' => 'enable',
49 '_wpnonce' => wp_create_nonce( 'enable-theme_' . $theme->slug ),
50 'theme' => $theme->slug,
51 ), network_admin_url( 'themes.php' ) );
52 } else {
53 $theme->activate_url = add_query_arg( array(
54 'action' => 'activate',
55 '_wpnonce' => wp_create_nonce( 'switch-theme_' . $theme->slug ),
56 'stylesheet' => $theme->slug,
57 ), admin_url( 'themes.php' ) );
58 }
59 }
60
61 if ( ! is_multisite() && current_user_can( 'edit_theme_options' ) && current_user_can( 'customize' ) ) {
62 $theme->customize_url = add_query_arg( array(
63 'return' => urlencode( network_admin_url( 'theme-install.php', 'relative' ) ),
64 ), wp_customize_url( $theme->slug ) );
65 }
66
67 $theme->name = wp_kses( $theme->name, $themes_allowedtags );
68 $theme->author = wp_kses( $theme->author, $themes_allowedtags );
69 $theme->version = wp_kses( $theme->version, $themes_allowedtags );
70 $theme->description = wp_kses( $theme->description, $themes_allowedtags );
71 $theme->stars = wp_star_rating( array( 'rating' => $theme->rating, 'type' => 'percent', 'number' => $theme->num_ratings, 'echo' => false ) );
72 $theme->num_ratings = number_format_i18n( $theme->num_ratings );
73 $theme->preview_url = set_url_scheme( $theme->preview_url );
74 }
75
76 wp_send_json_success( $api );
77 }
78 remove_action( 'wp_ajax_query-themes', 'wp_ajax_query_themes', 1 );
79 add_action( 'wp_ajax_query-themes', 'wp_ajax_custom_query_themes', 1 );
80 }
81
82 if( ! function_exists( 'catchthemes_our_themes_script' ) ) {
83 function catchthemes_our_themes_script( $hook_suffix ) {
84
85 if( 'theme-install.php' == $hook_suffix ) {
86 wp_enqueue_script( 'our-themes-script', ESSENTIAL_WIDGETS_URL . 'admin/js/our-themes.js', array( 'jquery' ), '2018-05-16' );
87 }
88 }
89 add_action( 'admin_enqueue_scripts', 'catchthemes_our_themes_script' );
90 }
91
92
93 /* Add Catch Themes Section in Theme in Customizer */
94 if( ! function_exists( 'catchthemes_customize_register' ) ) {
95 function catchthemes_customize_register($wp_customize) {
96 $wp_customize->add_section( new WP_Customize_Themes_Section( $wp_customize, 'catchthemes', array(
97 'title' => __( 'Themes by CatchThemes', 'catch-web-tools' ),
98 'action' => 'catchthemes',
99 'capability' => 'install_themes',
100 'panel' => 'themes',
101 'priority' => 6,
102 ) ) );
103 }
104 if ( ! is_multisite() ) {
105 add_action( 'customize_register', 'catchthemes_customize_register' );
106 }
107 }
108
109 if( ! function_exists( 'catchthemes_handle_load_themes_request' ) ) {
110 global $wp_customize;
111 remove_action( 'wp_ajax_customize_load_themes', array( $wp_customize, 'handle_load_themes_request' ) );
112 add_action( 'wp_ajax_customize_load_themes', 'catchthemes_handle_load_themes_request' );
113 /**
114 * Load themes into the theme browsing/installation UI.
115 * taken from wp-includes/cllass-wp-customize-manager.php
116 * @since 4.9.0
117 */
118 function catchthemes_handle_load_themes_request() {
119 check_ajax_referer( 'switch_themes', 'nonce' );
120 if ( ! current_user_can( 'switch_themes' ) ) {
121 wp_die( -1 );
122 }
123
124 if ( empty( $_POST['theme_action'] ) ) {
125 wp_send_json_error( 'missing_theme_action' );
126 }
127 $theme_action = sanitize_key( $_POST['theme_action'] );
128 $themes = array();
129 $args = array();
130
131 // Define query filters based on user input.
132 if ( ! array_key_exists( 'search', $_POST ) ) {
133 $args['search'] = '';
134 } else {
135 $args['search'] = sanitize_text_field( wp_unslash( $_POST['search'] ) );
136 }
137
138 if ( ! array_key_exists( 'tags', $_POST ) ) {
139 $args['tag'] = '';
140 } else {
141 $args['tag'] = array_map( 'sanitize_text_field', wp_unslash( (array) $_POST['tags'] ) );
142 }
143
144 if ( ! array_key_exists( 'page', $_POST ) ) {
145 $args['page'] = 1;
146 } else {
147 $args['page'] = absint( $_POST['page'] );
148 }
149
150 require_once ABSPATH . 'wp-admin/includes/theme.php';
151
152 if ( 'installed' === $theme_action ) {
153
154 // Load all installed themes from wp_prepare_themes_for_js().
155 $themes = array( 'themes' => wp_prepare_themes_for_js() );
156 foreach ( $themes['themes'] as &$theme ) {
157 $theme['type'] = 'installed';
158 $theme['active'] = ( isset( $_POST['customized_theme'] ) && $_POST['customized_theme'] === $theme['id'] );
159 }
160
161 } elseif ( 'catchthemes' === $theme_action ) {
162
163 // Load WordPress.org themes from the .org API and normalize data to match installed theme objects.
164 if ( ! current_user_can( 'install_themes' ) ) {
165 wp_die( -1 );
166 }
167
168 // Arguments for all queries.
169 $wporg_args = array(
170 'per_page' => -1,
171 'fields' => array(
172 'screenshot_url' => true,
173 'description' => true,
174 'rating' => true,
175 'downloaded' => true,
176 'downloadlink' => true,
177 'last_updated' => true,
178 'homepage' => true,
179 'num_ratings' => true,
180 'tags' => true,
181 'parent' => true,
182 // 'extended_author' => true, @todo: WordPress.org throws a 500 server error when this is here.
183 ),
184 );
185
186 $args = array_merge( $wporg_args, $args );
187
188 if ( '' === $args['search'] && '' === $args['tag'] ) {
189 $args['browse'] = 'new'; // Sort by latest themes by default.
190 }
191
192 $args['author'] = 'catchthemes';
193
194 // Load themes from the .org API.
195 $themes = themes_api( 'query_themes', $args );
196 if ( is_wp_error( $themes ) ) {
197 wp_send_json_error();
198 }
199
200 // This list matches the allowed tags in wp-admin/includes/theme-install.php.
201 $themes_allowedtags = array_fill_keys(
202 array( 'a', 'abbr', 'acronym', 'code', 'pre', 'em', 'strong', 'div', 'p', 'ul', 'ol', 'li', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'img' ),
203 array()
204 );
205 $themes_allowedtags['a'] = array_fill_keys( array( 'href', 'title', 'target' ), true );
206 $themes_allowedtags['acronym']['title'] = true;
207 $themes_allowedtags['abbr']['title'] = true;
208 $themes_allowedtags['img'] = array_fill_keys( array( 'src', 'class', 'alt' ), true );
209
210 // Prepare a list of installed themes to check against before the loop.
211 $installed_themes = array();
212 $wp_themes = wp_get_themes();
213 foreach ( $wp_themes as $theme ) {
214 $installed_themes[] = $theme->get_stylesheet();
215 }
216 $update_php = network_admin_url( 'update.php?action=install-theme' );
217
218 // Set up properties for themes available on WordPress.org.
219 foreach ( $themes->themes as &$theme ) {
220 $theme->install_url = add_query_arg( array(
221 'theme' => $theme->slug,
222 '_wpnonce' => wp_create_nonce( 'install-theme_' . $theme->slug ),
223 ), $update_php );
224
225 $theme->name = wp_kses( $theme->name, $themes_allowedtags );
226 $theme->author = wp_kses( $theme->author, $themes_allowedtags );
227 $theme->version = wp_kses( $theme->version, $themes_allowedtags );
228 $theme->description = wp_kses( $theme->description, $themes_allowedtags );
229 $theme->tags = implode( ', ', $theme->tags );
230 $theme->stars = wp_star_rating( array(
231 'rating' => $theme->rating,
232 'type' => 'percent',
233 'number' => $theme->num_ratings,
234 'echo' => false,
235 ) );
236 $theme->num_ratings = number_format_i18n( $theme->num_ratings );
237 $theme->preview_url = set_url_scheme( $theme->preview_url );
238
239 // Handle themes that are already installed as installed themes.
240 if ( in_array( $theme->slug, $installed_themes, true ) ) {
241 $theme->type = 'installed';
242 } else {
243 $theme->type = $theme_action;
244 }
245
246 // Set active based on customized theme.
247 $theme->active = ( isset( $_POST['customized_theme'] ) && $_POST['customized_theme'] === $theme->slug );
248
249 // Map available theme properties to installed theme properties.
250 $theme->id = $theme->slug;
251 $theme->screenshot = array( $theme->screenshot_url );
252 $theme->authorAndUri = $theme->author;
253 // 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.
254 if ( isset( $theme->parent ) ) {
255 $theme->parent = $theme->parent['slug'];
256 } else {
257 $theme->parent = false;
258 }
259 unset( $theme->slug );
260 unset( $theme->screenshot_url );
261 unset( $theme->author );
262 } // End foreach().
263 } elseif ( 'wporg' === $theme_action ) {
264
265 // Load WordPress.org themes from the .org API and normalize data to match installed theme objects.
266 if ( ! current_user_can( 'install_themes' ) ) {
267 wp_die( -1 );
268 }
269
270 // Arguments for all queries.
271 $wporg_args = array(
272 'per_page' => 100,
273 'fields' => array(
274 'screenshot_url' => true,
275 'description' => true,
276 'rating' => true,
277 'downloaded' => true,
278 'downloadlink' => true,
279 'last_updated' => true,
280 'homepage' => true,
281 'num_ratings' => true,
282 'tags' => true,
283 'parent' => true,
284 // 'extended_author' => true, @todo: WordPress.org throws a 500 server error when this is here.
285 ),
286 );
287
288 $args = array_merge( $wporg_args, $args );
289
290 if ( '' === $args['search'] && '' === $args['tag'] ) {
291 $args['browse'] = 'new'; // Sort by latest themes by default.
292 }
293
294 // Load themes from the .org API.
295 $themes = themes_api( 'query_themes', $args );
296 if ( is_wp_error( $themes ) ) {
297 wp_send_json_error();
298 }
299
300 // This list matches the allowed tags in wp-admin/includes/theme-install.php.
301 $themes_allowedtags = array_fill_keys(
302 array( 'a', 'abbr', 'acronym', 'code', 'pre', 'em', 'strong', 'div', 'p', 'ul', 'ol', 'li', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'img' ),
303 array()
304 );
305 $themes_allowedtags['a'] = array_fill_keys( array( 'href', 'title', 'target' ), true );
306 $themes_allowedtags['acronym']['title'] = true;
307 $themes_allowedtags['abbr']['title'] = true;
308 $themes_allowedtags['img'] = array_fill_keys( array( 'src', 'class', 'alt' ), true );
309
310 // Prepare a list of installed themes to check against before the loop.
311 $installed_themes = array();
312 $wp_themes = wp_get_themes();
313 foreach ( $wp_themes as $theme ) {
314 $installed_themes[] = $theme->get_stylesheet();
315 }
316 $update_php = network_admin_url( 'update.php?action=install-theme' );
317
318 // Set up properties for themes available on WordPress.org.
319 foreach ( $themes->themes as &$theme ) {
320 $theme->install_url = add_query_arg( array(
321 'theme' => $theme->slug,
322 '_wpnonce' => wp_create_nonce( 'install-theme_' . $theme->slug ),
323 ), $update_php );
324
325 $theme->name = wp_kses( $theme->name, $themes_allowedtags );
326 $theme->author = wp_kses( $theme->author, $themes_allowedtags );
327 $theme->version = wp_kses( $theme->version, $themes_allowedtags );
328 $theme->description = wp_kses( $theme->description, $themes_allowedtags );
329 $theme->tags = implode( ', ', $theme->tags );
330 $theme->stars = wp_star_rating( array(
331 'rating' => $theme->rating,
332 'type' => 'percent',
333 'number' => $theme->num_ratings,
334 'echo' => false,
335 ) );
336 $theme->num_ratings = number_format_i18n( $theme->num_ratings );
337 $theme->preview_url = set_url_scheme( $theme->preview_url );
338
339 // Handle themes that are already installed as installed themes.
340 if ( in_array( $theme->slug, $installed_themes, true ) ) {
341 $theme->type = 'installed';
342 } else {
343 $theme->type = $theme_action;
344 }
345
346 // Set active based on customized theme.
347 $theme->active = ( isset( $_POST['customized_theme'] ) && $_POST['customized_theme'] === $theme->slug );
348
349 // Map available theme properties to installed theme properties.
350 $theme->id = $theme->slug;
351 $theme->screenshot = array( $theme->screenshot_url );
352 $theme->authorAndUri = $theme->author;
353 // 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.
354 if ( isset( $theme->parent ) ) {
355 $theme->parent = $theme->parent['slug'];
356 } else {
357 $theme->parent = false;
358 }
359 unset( $theme->slug );
360 unset( $theme->screenshot_url );
361 unset( $theme->author );
362 } // End foreach().
363 } // End if().
364
365 /**
366 * Filters the theme data loaded in the customizer.
367 *
368 * This allows theme data to be loading from an external source,
369 * or modification of data loaded from `wp_prepare_themes_for_js()`
370 * or WordPress.org via `themes_api()`.
371 *
372 * @since 4.9.0
373 *
374 * @see wp_prepare_themes_for_js()
375 * @see themes_api()
376 * @see WP_Customize_Manager::__construct()
377 *
378 * @param array $themes Nested array of theme data.
379 * @param array $args List of arguments, such as page, search term, and tags to query for.
380 * @param WP_Customize_Manager $manager Instance of Customize manager.
381 */
382 $themes = apply_filters( 'customize_load_themes', $themes, $args, $wp_customize );
383
384 wp_send_json_success( $themes );
385 }
386 }