PluginProbe
Themify Builder / trunk
Themify Builder vtrunk
7.8.1 7.8.0 7.7.9 7.7.8 7.7.7 7.7.6 7.7.5 7.7.4 7.7.3 7.7.2 trunk 7.6.0 7.6.1 7.6.2 7.6.3 7.6.4 7.6.5 7.6.6 7.6.7 7.6.8 7.6.9 7.7.0 7.7.1
themify-builder / themify / themify-wpajax.php

themify-wpajax.php in Themify Builder trunk, at themify/themify-wpajax.php

1,064 lines 42.5 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /***************************************************************************
3 *
4 * ----------------------------------------------------------------------
5 * DO NOT EDIT THIS FILE
6 * ----------------------------------------------------------------------
7 *
8 * Copyright (C) Themify
9 *
10 * ----------------------------------------------------------------------
11 *
12 ***************************************************************************/
13
14 defined( 'ABSPATH' ) || exit;
15
16 // Initialize actions
17
18 $themify_ajax_actions = array(
19 'import_settings',
20 'plupload',
21 'get_404_pages',
22 'save',
23 'reset_settings',
24 'add_link_field',
25 'media_lib_browse',
26 'clear_all_webp',
27 'clear_all_menu',
28 'clear_all_concate',
29 'clear_all_html',
30 'clear_gfonts',
31 'search_autocomplete',
32 'ajax_load_more',
33 'required_plugins_modal',
34 'news_widget',
35 'activate_plugin',
36 'update_license',
37 'upload_json'
38 );
39 foreach($themify_ajax_actions as $action){
40 add_action('wp_ajax_themify_' . $action, 'themify_' . $action);
41 }
42
43 //Show 404 page in autocomplete
44 function themify_get_404_pages(){
45 if ( ! empty( $_POST['term'] ) && current_user_can( 'manage_options' ) ) {
46 $args = array(
47 'sort_order' => 'asc',
48 'sort_column' => 'post_title',
49 'post_type' => 'page',
50 's'=> sanitize_text_field($_POST['term']),
51 'no_found_rows'=>true,
52 'ignore_sticky_posts'=>true,
53 'cache_results'=>false,
54 'update_post_term_cache'=>false,
55 'update_post_meta_cache'=>false,
56 'post_status' => 'publish',
57 'posts_per_page' => 15
58 );
59 add_filter( 'posts_search', 'themify_posts_where', 10, 2 );
60 $terms = new WP_Query($args);
61 $items = array();
62 if($terms->have_posts()){
63 while ($terms->have_posts()){
64 $terms->the_post();
65 $items[] = array('value'=> get_the_ID(),'label'=> get_the_title());
66 }
67 }
68 echo wp_json_encode($items);
69 }
70 wp_die();
71 }
72
73 //Search only by post title
74 function themify_posts_where($search,$wp_query ){
75 if ( ! empty( $search ) && ! empty( $wp_query->query_vars['search_terms'] ) ) {
76 global $wpdb;
77
78 $q = $wp_query->query_vars;
79 $n = ! empty( $q['exact'] ) ? '' : '%';
80
81 $search = array();
82 $search[] = $wpdb->prepare( "$wpdb->posts.post_title LIKE %s", $wpdb->esc_like( implode(' ',$q['search_terms']) ) . $n );
83
84 if ( ! is_user_logged_in() )
85 $search[] = "$wpdb->posts.post_password = ''";
86
87 $search = ' AND ' . implode( ' AND ', $search );
88 }
89 return $search;
90 }
91
92 /**
93 * Handles theme settings import via file
94 */
95 function themify_import_settings() {
96 if ( ! current_user_can( 'manage_options' ) ) {
97 die;
98 }
99 check_ajax_referer( 'themify_import_settings' );
100
101 if ( ! empty( $_POST['data'] ) ) {
102 $data = stripslashes( $_POST['data'] );
103 $data = is_serialized( $data ) ? unserialize( $data, [ 'allowed_classes' => false ] ) : json_decode( $data, true );
104 if ( ! empty( $data ) ) {
105 themify_set_data( $data );
106 }
107 }
108
109 wp_send_json_success();
110 }
111
112 /**
113 * AJAX - Plupload execution routines
114 * @since 1.2.2
115 * @package themify
116 */
117 function themify_plupload() {
118 if ( ! current_user_can( 'upload_files' ) ) {
119 wp_send_json_error( __( 'You are not allowed to upload files.', 'themify' ), 403 );
120 }
121
122 $imgid = isset( $_POST['imgid'] ) ? sanitize_text_field( wp_unslash( $_POST['imgid'] ) ) : '';
123 $nonce = isset( $_REQUEST['_ajax_nonce'] ) ? sanitize_text_field( wp_unslash( $_REQUEST['_ajax_nonce'] ) ) : '';
124 if ( $nonce === '' || ( ! wp_verify_nonce( $nonce, 'themify-plupload' ) && ! wp_verify_nonce( $nonce, $imgid . 'themify-plupload' ) ) ) {
125 wp_send_json_error( __( 'Upload verification failed.', 'themify' ), 403 );
126 }
127 /** Decide whether to send this image to Media. @var String */
128 $add_to_media_library = isset( $_POST['tomedia'] ) ? $_POST['tomedia'] : false;
129 /** If post ID is set, uploaded image will be attached to it. @var String */
130 $postid = isset( $_POST['topost'] )? $_POST['topost'] : '';
131
132 /** Handle file upload storing file|url|type. @var Array */
133 $file = wp_handle_upload($_FILES[$imgid . 'async-upload'], array('test_form' => true, 'action' => 'themify_plupload'));
134
135 // if $file returns error, return it and exit the function
136 if ( isset( $file['error'] ) && ! empty( $file['error'] ) ) {
137 wp_send_json_error( $file['error'] );
138 }
139
140 $type = isset( $_POST['type'] ) ? sanitize_key( $_POST['type'] ) : '';
141 $allowed_extensions = [
142 'image' => [ 'jpg', 'jpeg', 'gif', 'png', 'ico', 'svg' ],
143 'audio' => [ 'mp3', 'm4a', 'ogg', 'wav', 'wma' ],
144 'video' => [ 'mp4', 'm4v', 'webm', 'ogv', 'wmv', 'flv' ],
145 'font' => [ 'woff', 'woff2', 'ttf', 'otf', 'svg', 'eot' ]
146 ];
147
148 // Validate $type before using it as an array key to prevent PHP warnings
149 // and potential type-confusion attacks.
150 if ( ! isset( $allowed_extensions[ $type ] ) ) {
151 Themify_Filesystem::delete( $file['file'], 'f' );
152 wp_send_json_error( __( 'Invalid file type.', 'themify' ) );
153 }
154
155 // let's see if it's a valid file type
156 $extension = pathinfo( $file['file'], PATHINFO_EXTENSION );
157 if ( ! in_array( $extension, $allowed_extensions[ $type ], true ) ) {
158 Themify_Filesystem::delete( $file['file'], 'f' );
159 wp_send_json_error( __( 'Invalid file type.', 'themify' ) );
160 }
161
162 //Image Upload routines
163 if( 'tomedia' === $add_to_media_library ){
164
165 // Insert into Media Library
166 // Set up options array to add this file as an attachment
167 $attachment = array(
168 'post_mime_type' => sanitize_mime_type($file['type']),
169 'post_title' => str_replace('-', ' ', sanitize_file_name(pathinfo($file['file'], PATHINFO_FILENAME))),
170 'post_status' => 'inherit'
171 );
172
173 if( $postid ){
174 $attach_id = wp_insert_attachment( $attachment, $file['file'], $postid );
175 } else {
176 $attach_id = wp_insert_attachment( $attachment, $file['file'] );
177 }
178 $file['id'] = $attach_id;
179
180 // Common attachment procedures
181 require_once(ABSPATH . 'wp-admin/includes/image.php');
182 $attach_data = wp_generate_attachment_metadata( $attach_id, $file['file'] );
183 wp_update_attachment_metadata($attach_id, $attach_data);
184
185 if( $postid ) {
186
187 $full = wp_get_attachment_image_src( $attach_id, 'full' );
188 $fields_key = isset( $_POST['fields'] ) ? sanitize_text_field( $_POST['fields'] ) : '';
189 if ( $fields_key !== '' && preg_match( '/^[\w\-\[\]]+$/', $fields_key ) ) {
190 update_post_meta($postid, $fields_key, $full[0]);
191 update_post_meta($postid, '_'.$fields_key . '_attach_id', $attach_id);
192 }
193 }
194
195 /* Return URL for the image field in meta box */
196 if ( $type === 'image' ) {
197 $thumb = wp_get_attachment_image_src( $attach_id, 'thumbnail' );
198 $file['thumb'] = $thumb[0];
199 }
200 }
201
202 $file['type'] = $extension;
203 wp_send_json_success( $file );
204 }
205
206 /**
207 * AJAX - Save user settings
208 * @since 1.1.3
209 * @package themify
210 */
211 function themify_save(){
212 check_ajax_referer( 'tf_nonce', 'nonce' );
213 if ( ! current_user_can( 'manage_options' ) ) {
214 die;
215 }
216
217 $previous_data = themify_get_data();
218 $temp = themify_normalize_save_data( $_POST['data'] );
219 unset($temp['tmp_cache_network'],$temp['tmp_cache_concte_network'],$temp['tmp_regenerate_all_css']);
220 themify_set_data( $temp );
221 _e('Your settings were saved', 'themify');
222
223 if (
224 Themify_Enqueue_Assets::$mobileMenuActive !== intval( $temp['setting-mobile_menu_trigger_point'] )
225 || ( isset( $previous_data['skin'] ) && $previous_data['skin'] !== $temp['skin'])
226 || ( isset( $previous_data['setting-header_design'] ) && $previous_data['setting-header_design'] !== $temp['setting-header_design'])
227 || ( isset( $previous_data['setting-exclude_menu_navigation'] ) && $previous_data['setting-exclude_menu_navigation'] !== $temp['setting-exclude_menu_navigation'])
228 ) {
229 Themify_Enqueue_Assets::clearConcateCss();
230 }
231
232 /* clear webP image cache when changing image quality */
233 if ( (empty( $previous_data['setting-gf'] ) && !empty($temp['setting-gf'])) || (!empty( $previous_data['setting-gf'] ) && empty($temp['setting-gf']))) {
234 Themify_Storage::deleteByPrefix('tf_fg_css_');
235 }
236 /* clear google fonts cache*/
237
238 if ( class_exists( 'Themify_Builder_Stylesheet',false ) ) {
239 $breakpoints=themify_get_breakpoints('all',true);
240 foreach ( $breakpoints as $bp=>$v ) {
241 if ( isset( $previous_data["setting-customizer_responsive_design_{$bp}"] ) && $previous_data["setting-customizer_responsive_design_{$bp}"] !== $temp["setting-customizer_responsive_design_{$bp}"] ) {
242 Themify_Builder_Stylesheet::regenerate_css_files();
243 break;
244 }
245 }
246 }
247 unset($previous_data);
248 if(themify_get_server()==='nginx'){
249 if(empty($temp['setting-webp'])){
250 Themify_Enqueue_Assets::removeWebp();
251 }
252 }
253 else{
254 $isDev=!empty($temp['setting-dev-mode']);
255 $gzip=$isDev?true:empty($temp['setting-cache_gzip']);
256 $browser=$isDev?true:empty($temp['setting-cache_browser']);
257 Themify_Enqueue_Assets::rewrite_htaccess($gzip,empty($temp['setting-webp']),$browser);
258 }
259 TFCache::remove_cache();
260 if(empty($temp['setting-dev-mode'])){
261 TFCache::create_config($temp);
262 }
263 else{
264 TFCache::disable_cache();
265 }
266 TFCache::clear_3rd_plugins_cache();
267
268 do_action( 'themify_settings_save' );
269
270 wp_die();
271 }
272
273 function themify_normalize_save_data($data){
274 $data = explode('&', $data);
275 $temp = array();
276 foreach($data as $a){
277 $v = explode('=', $a);
278 $temp[$v[0]] = urldecode( str_replace('+',' ',preg_replace_callback('/%([0-9a-f]{2})/i', 'themify_save_replace_cb', urlencode($v[1]))) );
279 }
280
281 /* cleanup Hook Content data, remove empty hooks */
282 if ( ! empty( $temp['setting-hooks_field_ids'] ) ) {
283 $ids = json_decode( $temp['setting-hooks_field_ids'] );
284 if ( ! empty( $ids ) ) {
285 $new_ids = [];
286 foreach ( $ids as $id ) {
287 if ( empty( $temp["setting-hooks-{$id}-code"] ) ) {
288 unset( $temp["setting-hooks-{$id}-code"], $temp["setting-hooks-{$id}-location"], $temp["setting-hooks-{$id}-r"], $temp["setting-hooks-{$id}-visibility"] );
289 } else {
290 $new_ids[] = $id;
291 }
292 }
293 $temp['setting-hooks_field_ids'] = json_encode( $new_ids );
294 }
295 }
296
297 return $temp;
298 }
299
300 /**
301 * Replace callback for preg_replace_callback used in themify_save().
302 *
303 * @since 2.2.5
304 *
305 * @param array $matches 0 complete match 1 first match enclosed in (...)
306 *
307 * @return string One character specified by ascii.
308 */
309 function themify_save_replace_cb( $matches ) {
310 // "chr(hexdec('\\1'))"
311 return chr( hexdec( $matches[1] ) );
312 }
313
314 /**
315 * AJAX - Reset Settings
316 * @since 1.1.3
317 * @package themify
318 */
319 function themify_reset_settings(){
320 check_ajax_referer( 'tf_nonce', 'nonce' );
321 if ( ! current_user_can( 'manage_options' ) ) {
322 die;
323 }
324
325 $temp_data = themify_normalize_save_data($_POST['data']);
326 $temp = array();
327 foreach($temp_data as $key => $val){
328 // Don't reset if it's not a setting or the # of social links or a social link or the Hook Contents
329 if(strpos($key, 'setting') === false || strpos($key, 'hooks') || strpos($key, 'link_field_ids') || strpos($key, 'themify-link') || strpos($key, 'custom_css')){
330 $temp[$key] = $val;
331 }
332 }
333 $temp['setting-script_minification'] = 'disable';
334 wp_send_json( themify_set_data( $temp ) );
335 }
336
337 function themify_add_link_field(){
338 check_ajax_referer( 'tf_nonce', 'nonce' );
339 if ( ! current_user_can( 'manage_options' ) ) {
340 die;
341 }
342
343 if( isset($_POST['fid']) ) {
344 // $hash is used as an HTML id attribute - sanitize to alphanumeric/dashes only
345 $hash = preg_replace( '/[^a-zA-Z0-9_\-]/', '', sanitize_text_field( $_POST['fid'] ) );
346 if ( $hash === '' ) {
347 wp_die();
348 }
349 $type = isset( $_POST['type'] ) ? sanitize_key( $_POST['type'] ) : 'image-icon';
350 echo themify_add_link_template( 'themify-link-'.$hash, array(), true, $type);
351 wp_die();
352 }
353 }
354
355 /**
356 * Set image from wp library
357 * @since 1.2.9
358 * @package themify
359 */
360 function themify_media_lib_browse() {
361 if ( ! wp_verify_nonce( $_POST['media_lib_nonce'], 'media_lib_nonce' ) ) die(-1);
362 if ( ! current_user_can( 'upload_files' ) ) {
363 die;
364 }
365
366 $file = array();
367 $postid = absint( $_POST['post_id'] );
368 $attach_id = absint( $_POST['attach_id'] );
369
370 // Capability check: the user must be able to edit the target post.
371 if ( ! current_user_can( 'edit_post', $postid ) ) {
372 die( -1 );
373 }
374
375 // Restrict meta_key to safe characters used by all Themify metabox fields
376 // (word chars, hyphens, brackets). Rejects injected or empty keys.
377 $field_name = isset( $_POST['field_name'] ) ? sanitize_text_field( $_POST['field_name'] ) : '';
378 if ( $field_name === '' || ! preg_match( '/^[\w\-\[\]]+$/', $field_name ) ) {
379 die( -1 );
380 }
381
382 $full = wp_get_attachment_image_src( $attach_id, 'full' );
383 if ( ! empty( $_POST['featured'] ) ) {
384 //Set the featured image for the post
385 set_post_thumbnail( $postid, $attach_id );
386 }
387 update_post_meta( $postid, $field_name, $full[0] );
388 update_post_meta( $postid, '_' . $field_name . '_attach_id', $attach_id );
389
390 $thumb = wp_get_attachment_image_src( $attach_id, 'thumbnail' );
391
392 //Return URL for the image field in meta box
393 $file['thumb'] = $thumb[0];
394
395 echo json_encode($file);
396
397 exit();
398 }
399
400
401 function themify_clear_all_webp(){
402 check_ajax_referer('tf_nonce', 'nonce');
403 if ( ! current_user_can( 'manage_options' ) ) {
404 die;
405 }
406
407 wp_send_json_success(Themify_Enqueue_Assets::removeWebp());
408 }
409
410 function themify_clear_all_concate(){
411 check_ajax_referer('tf_nonce', 'nonce');
412 if ( ! current_user_can( 'manage_options' ) ) {
413 die;
414 }
415
416 $type=false;
417 if(is_multisite()){
418 if(!empty($_POST['all'])){
419 $type='all';
420 }
421 else{
422 $data = themify_normalize_save_data($_POST['data']);
423 if(!empty($data['tmp_cache_concte_network'])){
424 $type='all';
425 }
426 $data=null;
427 }
428 }
429 if ( class_exists( 'Themify_Builder_Stylesheet', false ) ) {
430 Themify_Builder_Stylesheet::regenerate_css_files( 'all' === $type ? 'all' : '' );
431 }
432 Themify_Enqueue_Assets::clearConcateCss($type);
433 wp_send_json_success();
434 }
435
436 function themify_clear_all_menu(){
437 check_ajax_referer('tf_nonce', 'nonce');
438 if ( ! current_user_can( 'manage_options' ) ) {
439 die;
440 }
441
442 TFCache::remove_cache();
443 TFCache::clear_3rd_plugins_cache();
444 themify_clear_menu_cache();
445 die('1');
446 }
447
448 function themify_clear_all_html(){
449 check_ajax_referer('tf_nonce', 'nonce');
450 if ( ! current_user_can( 'manage_options' ) ) {
451 die;
452 }
453 $type='blog';
454 if(is_multisite()){
455 $data = themify_normalize_save_data($_POST['data']);
456 if(!empty($data['tmp_cache_network'])){
457 $type='all';
458 }
459 $data=null;
460 }
461 TFCache::remove_cache($type);
462 die('1');
463 }
464 function themify_clear_gfonts(){
465 check_ajax_referer('tf_nonce', 'nonce');
466 if ( ! current_user_can( 'manage_options' ) ) {
467 die;
468 }
469
470 Themify_Storage::deleteByPrefix('tf_fg_css_');
471 wp_send_json_success();
472 }
473 add_action('wp_ajax_nopriv_themify_search_autocomplete','themify_search_autocomplete');
474 function themify_search_autocomplete(){
475 if(!empty($_POST['s'])){
476 $s = sanitize_text_field($_POST['s']);
477 if(!empty($s)){
478 global $query,$found_types;
479 if(!empty($_POST['post_type'])){
480 $post_types = array(sanitize_text_field($_POST['post_type']));
481 }else{
482 if(true===themify_is_woocommerce_active() && 'product' === themify_get( 'setting-search_post_type','all',true )){
483 $post_types = array('product');
484 }else{
485 $post_types = Themify_Builder_Model::get_post_types();
486 unset($post_types['attachment']);
487 $post_types=array_keys($post_types);
488 }
489 }
490 $query_args = array(
491 'post_type'=>$post_types,
492 'post_status'=>'publish',
493 'posts_per_page'=>22,
494 's'=>$s
495 );
496
497 $query_args = apply_filters('themify_search_args',$query_args);
498 wp_reset_postdata();
499 $query = new WP_Query( $query_args );
500 $found_types=array();
501 while ( $query->have_posts() ){
502 $query->the_post();
503 $post_type = get_post_type();
504 if (($key = array_search($post_type, $query_args['post_type'])) !== false) {
505 unset($query_args['post_type'][$key]);
506 $found_types[]=$post_type;
507 }
508 if(empty($query_args['post_type'])){
509 break;
510 }
511 }
512 $query->rewind_posts();
513
514 // SKU Search Addition.
515 if (function_exists('wc_get_products') && in_array('product', $post_types)) {
516 $sku_products = wc_get_products([
517 'limit' => 22,
518 'status' => 'publish',
519 'sku' => $s,
520 ]);
521 if (!empty($sku_products)) {
522 $sku_ids = array();
523 foreach ($sku_products as $sku_product) {
524 $sku_ids[] = $sku_product->get_id();
525 }
526 // Merge with existing query results
527 $existing_ids = $query->posts ? wp_list_pluck($query->posts, 'ID') : array();
528 $all_ids = array_unique(array_merge($existing_ids, $sku_ids));
529 // Re-query to get all posts in correct order
530 if (!empty($all_ids)) {
531 $query = new WP_Query(array(
532 'post_type' => $post_types,
533 'post_status' => 'publish',
534 'post__in' => $all_ids,
535 'orderby' => 'post__in',
536 'posts_per_page' => 22
537 ));
538 // Update found_types for all post types present in the results
539 foreach ($query->posts as $post) {
540 $type = get_post_type($post);
541 if (!in_array($type, $found_types)) {
542 $found_types[] = $type;
543 }
544 }
545 }
546 }
547 }
548
549 ob_start();
550 include( THEMIFY_DIR.'/includes/search-box-result.php' );
551 ob_end_flush();
552 }
553 }
554 wp_die();
555 }
556
557 /*Load More Ajax - Used for module ajax load more*/
558 if(!function_exists('themify_ajax_load_more')){
559 function themify_ajax_load_more(){
560 // The nonce is output into themify_vars.nonce for every page load
561 // (see class-themify-enqueue.php) and sent by infinite.js / isotop.js.
562 // Using check_ajax_referer with die=false lets us handle the failure
563 // gracefully rather than outputting "-1" mid-stream.
564 if ( false === check_ajax_referer( 'tf_nonce', 'nonce', false ) ) {
565 wp_die();
566 }
567
568 if(!empty($_POST['module']) && !empty($_POST['id'])){
569 $builder_id=(int)($_POST['id']);
570
571 // Block non-logged-in access to unpublished or private post content.
572 if ( ! is_user_logged_in() ) {
573 $post = get_post( $builder_id );
574 if ( ! $post ) {
575 wp_die();
576 }
577 $post_type_obj = get_post_type_object( $post->post_type );
578 // tbp_template is non-public by design but serves public archive content; exempt it from the public-type check.
579 $is_tbp_template = defined( 'TBP_Templates::SLUG' )
580 ? $post->post_type === TBP_Templates::SLUG
581 : $post->post_type === 'tbp_template';
582 if (
583 $post->post_status !== 'publish'
584 || post_password_required( $post )
585 || ( ! $is_tbp_template && empty( $post_type_obj->public ) )
586 ) {
587 wp_die();
588 }
589 }
590
591 $mod_id=str_replace('tb_','',$_POST['module']);
592 $data = Themify_Builder::get_builder_modules_list( (int)$_POST['id'] );
593 if ( ! empty( $data ) ) {
594 foreach ( $data as $module ) {
595 if ( isset( $module['element_id'], $module['mod_settings'] ) && $module['element_id'] === $mod_id ) {
596 $mod_setting = $module;
597 break;
598 }
599 }
600 }
601 if(!empty($mod_setting)){
602 if ( class_exists( 'Themify_Hooks', false ) ) {
603 Themify_Hooks::hooks_setup();
604 }
605 global $paged;
606 $paged=(int)$_POST['page'];
607 $paged=$paged<1?1:$paged;
608 if(themify_is_themify_theme() && is_file(THEME_DIR.'/theme-options.php')){
609 require_once( THEME_DIR.'/theme-options.php' );
610 global $themify;
611 if(isset($themify) && method_exists($themify,'template_redirect')){
612 $themify->template_redirect();
613 }
614 }
615 Themify_Builder_Component_Module::template($mod_setting, $builder_id);
616 }
617 }
618 wp_die();
619 }
620 // Ajax filter actions
621 add_action('wp_ajax_nopriv_themify_ajax_load_more','themify_ajax_load_more');
622 }
623
624
625 function themify_required_plugins_modal() {
626 check_ajax_referer( 'tf_nonce', 'nonce' );
627 if(!current_user_can('manage_options')){
628 wp_send_json_error(__( 'You are not allowed to import data.','themify' ));
629 }
630 $required_plugins = !empty($_POST['plugins'])?sanitize_text_field($_POST['plugins']):'';
631 $result=array('plugins'=>array());
632 if( ! empty( $required_plugins )) {
633 $required_plugins = explode( ',', $required_plugins );
634 $all_plugins = get_plugins();
635 $can_install=current_user_can( 'install_plugins' ) ;
636 $themify_updater = class_exists('Themify_Updater',false)?Themify_Updater::get_instance():null;
637 foreach($required_plugins as $plugin){
638 $plugin=trim($plugin);
639 $plugin_info = themify_get_known_plugin_info($plugin);
640 if($plugin_info!==false){
641 if(isset($all_plugins[$plugin_info['path']])){
642 if(is_plugin_active( $plugin_info['path'] )){
643 $plugin_info['active']=1;
644 }
645 elseif(current_user_can( 'activate_plugin', $plugin )){
646 $valid= function_exists('validate_plugin_requirements')?validate_plugin_requirements($plugin_info['path']):true;
647 if(is_wp_error( $valid )){
648 $plugin_info['error']=$valid->get_error_message();
649 }
650 else{
651 $plugin_info['active']=0;
652 }
653 }
654 else{
655 $plugin_info['error']=__( 'You are not allowed to activate this plugin.','themify' );
656 }
657 }
658 elseif($can_install===true){
659 $plugin_info['install']=$themify_updater===null || $themify_updater->has_error() || !empty($plugin_info['wp_hosted']) || $themify_updater->has_access( $plugin )?1:'buy';
660 }
661 else{
662 $plugin_info['error']= __( 'You are not allowed to install plugins on this site.' ,'themify' );
663
664 }
665 unset($plugin_info['desc'],$plugin_info['image'],$plugin_info['path'],$plugin_info['wp_hosted']);
666 $result['plugins'][$plugin]=$plugin_info;
667 }
668 else{
669 $result['plugins'][$plugin]=array(
670 'error'=> __( 'Unknown plugin.','themify' ),
671 'name'=>$plugin
672 );
673 }
674 }
675 unset($required_plugins,$all_plugins,$can_install);
676 }
677 $result['labels']=array(
678 'head'=>__( 'This demo requires these plugins/addons:', 'themify' ),
679 'import_warning'=>__( 'Proceed import without the required addons/plugins might show incomplete/missing content.', 'themify' ),
680 'proceed_import'=> __( 'Proceed Import', 'themify' ),
681 'erase'=>__( 'Erase ALL previously imported demo content', 'themify' ),
682 'modify'=> __( 'Keep modified posts/pages', 'themify' ),
683 'builder_img'=>__('Import Builder layout images (will take longer)','themify'),
684 'install'=>__( 'Install', 'themify' ),
685 'activate'=>__( 'Activate', 'themify' ),
686 'buy'=>__( 'Buy', 'themify' ),
687 'note'=>__('WARNING: Importing the demo content will override your Themify settings, including your menu and widget configurations. It will also add content (posts, pages, featured images, widgets, menus, etc.) to your site based on our demo setup. It is recommended to perform this only on a fresh or development site.','themify'),
688 'plugins'=>array(
689 'activate_done'=>__('%plugin% successfully activated','themify'),
690 'activate_fail'=>__('Failed to activate %plugin%: %error%','themify'),
691 'install_fail'=>__('Failed to install %plugin%: %error%','themify'),
692 'install_done'=>__('%plugin% successfully installed','themify'),
693 'install'=>__('Installing %plugin%','themify'),
694 'activate'=>__('Activating %plugin%','themify'),
695 )
696 );
697 $result['has_demo']=Themify_Import_Helper::has_demo_content();
698 wp_send_json_success($result);
699 }
700
701 /**
702 * Install or Activate plugin for skin demo import and themify updater
703 */
704 function themify_activate_plugin() {
705 check_ajax_referer( 'tf_nonce', 'nonce' );
706 $err='';
707 if(!empty($_POST['plugin']) && current_user_can( 'edit_theme_options' ) ){
708 $plugin=sanitize_key($_POST['plugin']);
709 $plugin_info = themify_get_known_plugin_info($plugin);
710 if($plugin_info!==false){
711 $allPlugins= get_plugins();
712 if(isset($allPlugins[$plugin_info['path']])){
713 unset($allPlugins);
714 if(!is_plugin_active( $plugin_info['path'] )){
715 if(current_user_can( 'activate_plugin', $plugin )){
716 $result =activate_plugin($plugin_info['path'],false,false);
717 if(is_wp_error($result)){
718 $err=$result->get_error_message();
719 }
720 }
721 else{
722 $err=__( 'You are not allowed to activate this plugin.','themify' );
723 }
724 }
725 }
726 elseif(current_user_can( 'install_plugins' )){
727 $isFree=!empty($plugin_info['wp_hosted']);
728 if($isFree===false){
729 if($plugin==='themify-updater'){
730 $zip_path = '';
731 $unlink_zip = false;
732 if ( ! empty( $_FILES['data'] ) && is_file( $_FILES['data']['tmp_name'] ) ) {
733 $zip_path = $_FILES['data']['tmp_name'];
734 } elseif ( $err === '' ) {
735 require_once ABSPATH . 'wp-admin/includes/file.php';
736 $updater_zip_url = apply_filters(
737 'themify_updater_zip_url',
738 'https://themify.me/files/themify-updater/themify-updater.zip'
739 );
740 $tmp_zip = download_url( $updater_zip_url );
741 if ( is_wp_error( $tmp_zip ) ) {
742 $err = $tmp_zip->get_error_message();
743 } else {
744 $zip_path = $tmp_zip;
745 $unlink_zip = true;
746 }
747 }
748 if ( $err === '' && $zip_path !== '' ) {
749 require_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php';
750 $updgrader = new Plugin_Upgrader();
751 $result = $updgrader->install( $zip_path, array( 'overwrite_package' => true ) );
752 if ( $unlink_zip && is_string( $zip_path ) && is_file( $zip_path ) ) {
753 unlink( $zip_path );
754 }
755 if ( $result === true ) {
756 $result = activate_plugin( $plugin_info['path'], false, false );
757 if ( is_wp_error( $result ) ) {
758 $err = $result->get_error_message();
759 }
760 } else {
761 $err = is_wp_error( $result ) ? $result->get_error_message() : __( 'Themify Updater installation failed', 'themify' );
762 }
763 }
764 }
765 else{
766 if(!class_exists('Themify_Updater',false)){
767 $updater=themify_get_known_plugin_info('themify-updater');
768 if(isset($allPlugins[$updater['path']]) && !is_plugin_active( $updater['path'] )){
769 $result =activate_plugin($updater['path'],false,false);
770 if(is_wp_error($result)){
771 $err=$result->get_error_message();
772 }
773 elseif(!class_exists('Themify_Updater',false) && function_exists('themify_updater_init')){//plugins_loaded event already fired
774 themify_updater_init();
775 }
776 }
777 unset($updater);
778 }
779 unset($allPlugins);
780 if($err===''){
781 $themify_updater = class_exists('Themify_Updater',false)?Themify_Updater::get_instance():null;
782 if($themify_updater && method_exists($themify_updater, 'get_versions')){
783 $versions = $themify_updater->get_versions();
784 $isFree=!empty($versions)?$versions->has_attribute($plugin, 'wp_hosted'):false;
785 unset($versions);
786 }
787 else{
788 $themify_updater=null;
789 }
790 }
791 }
792 }
793 if($err==='' && $plugin!=='themify-updater'){
794 if($isFree===true){
795 $_POST['slug']=$plugin;
796 $_REQUEST['_ajax_nonce']=wp_create_nonce( 'updates' );
797 wp_ajax_install_plugin();
798 }
799 elseif(empty($themify_updater)){
800 $err=array('install_updater'=>1);
801 }
802 else{
803 if($themify_updater->has_error()){
804 $err=array('check_license'=>1,'errorMessage'=>sprintf(__('A valid membership is required to install %s','themify'),$plugin_info['name']));
805 }
806 elseif(!$themify_updater->has_access( $plugin )){
807 $err=array('buy'=>1,'errorMessage'=>sprintf(__('Your membership/license does not include %s','themify'),$plugin_info['name']),'url'=>$plugin_info['page']);
808 }
809 else{
810 $nonce=wp_create_nonce( 'install-plugin_'. str_replace('-plugin', '', $plugin) );
811 $installUrl= add_query_arg(array('action'=>'install-plugin','plugin'=>$plugin,'_wpnonce'=>$nonce),self_admin_url( 'update.php' ));
812 wp_send_json_success(array('install_plugin_url'=>$installUrl));
813 }
814
815 }
816 unset($themify_updater,$plugin_info);
817 }
818 }
819 else{
820 $err=__( 'You are not allowed to install plugins on this site.','themify' );
821 }
822 if($err===''){
823 wp_send_json_success();
824 }
825 }
826 else{
827 $err=__('Unknown Plugin.','themify');
828 }
829 }
830 wp_send_json_error($err);
831 }
832
833 /**
834 * Handle the display of the Themify News admin dashboard widget
835 *
836 * Hooked to wp_ajax_themify_news_widget
837 */
838 function themify_news_widget() {
839 ob_start();
840 wp_widget_rss_output( 'https://themify.me/blog/feed', array(
841 'title' => esc_html__( 'Themify News', 'themify' ),
842 'items' => 4,
843 'show_summary' => 1,
844 'show_author' => 0,
845 'show_date' => 1
846 ) );
847 $cache_key = 'themify_news_dashboard_widget';
848 Themify_Storage::set( $cache_key, ob_get_flush(), 12 * HOUR_IN_SECONDS ); // Default lifetime in cache of 12 hours (same as the feeds)
849 wp_die();
850 }
851
852
853 /**
854 * Handle the upload json file
855 */
856 function themify_upload_json(){
857 check_ajax_referer( 'tf_nonce', 'nonce' );
858 if (!empty($_POST['file'])) {
859 if (!current_user_can('upload_files')) {
860 $error = __('You aren`t allowed to upload file', 'themify');
861 } else {
862 if ( isset( $_POST['data'] ) ) {
863 $data = stripslashes_deep( $_POST['data'] );
864 }
865 elseif ( isset( $_FILES['data'] ) ) {
866 $data = file_get_contents( $_FILES['data']['tmp_name'] );
867 }
868 if(!empty($data)){
869 global $wpdb;
870 $slug = sanitize_file_name(pathinfo( $_POST['file'],PATHINFO_FILENAME));
871 $filename= $slug.'.json';
872 $sql= sprintf('post_name="%1$s" OR post_name="%1$s-1" OR post_name="%1$s-2" OR post_name="%1$s-3"',esc_sql($slug));
873 $query = $wpdb->get_row("SELECT ID FROM {$wpdb->prefix}posts WHERE ({$sql}) AND post_type='attachment' LIMIT 1" );
874 $attach_id=!empty($query) ? $query->ID : null;
875 if($attach_id!==null) {
876 $duplicate = get_attached_file($attach_id);
877 if(!$duplicate ||!is_file($duplicate) || sha1_file($duplicate)!==sha1($data)){
878 if($duplicate && !is_file($duplicate)){
879 wp_delete_attachment($attach_id);
880 }
881 $attach_id=null;
882 }
883 unset($duplicate);
884 }
885 unset($query,$sql);
886 if(empty($attach_id)){
887 $tmp = trailingslashit(sys_get_temp_dir()).$filename;
888 if(file_put_contents($tmp,$data)){
889 $file = array(
890 'size' => filesize($tmp),
891 'name'=> $filename,
892 'error'=>0,
893 'tmp_name' => $tmp
894 );
895 $title=!empty($_POST['title'])?sanitize_textarea_field($_POST['title']):'';
896 $attach_id=media_handle_sideload( $file, 0,$title,array(
897 'post_mime_type'=>'application/json',
898 'post_name'=>$slug
899 ) );
900 if(is_wp_error($attach_id)){
901 $error=$attach_id->get_error_message();
902 $attach_id=null;
903 if(is_file($tmp)){
904 unlink($tmp);
905 }
906 }
907 unset($tmp,$file);
908 }else{
909 $error = __('Can`t write tmp file', 'themify');
910 }
911 }
912 if(!empty($attach_id)){
913 wp_send_json_success(wp_get_attachment_url($attach_id));
914 }
915 }else{
916 $error = __('Upload data is corrupted', 'themify');
917 }
918 }
919 wp_send_json_error($error);
920 }
921 }
922
923 function themify_license_require_updater_utils() {
924 if ( class_exists( 'Themify_Updater_utils', false ) ) {
925 return;
926 }
927 $path = WP_PLUGIN_DIR . '/themify-updater/includes/class.utils.php';
928 if ( is_readable( $path ) ) {
929 require_once $path;
930 }
931 }
932
933 function themify_license_default_settings_row() {
934 return array(
935 'username' => '',
936 'key' => '',
937 'hideKey' => false,
938 'hideName' => false,
939 'autoUpdate' => false,
940 'hideNotice' => false,
941 'notification' => false,
942 'noticeEmail' => '',
943 );
944 }
945
946 function themify_license_sanitize_settings_payload_theme( $settings ) {
947 if ( ! is_array( $settings ) ) {
948 return themify_license_default_settings_row();
949 }
950 return array(
951 'username' => isset( $settings['username'] ) ? preg_replace( '/[^0-9A-Za-z_-]/', '', (string) $settings['username'] ) : '',
952 'key' => isset( $settings['key'] ) ? preg_replace( '/[^0-9A-Za-z]/', '', (string) $settings['key'] ) : '',
953 'hideKey' => ! empty( $settings['hideKey'] ),
954 'hideName' => ! empty( $settings['hideName'] ),
955 'autoUpdate' => ! empty( $settings['autoUpdate'] ),
956 'hideNotice' => ! empty( $settings['hideNotice'] ),
957 'notification' => ! empty( $settings['notification'] ),
958 'noticeEmail' => isset( $settings['noticeEmail'] ) && is_email( $settings['noticeEmail'] ) ? sanitize_email( $settings['noticeEmail'] ) : '',
959 );
960 }
961
962 function themify_license_load_stored_settings_row() {
963 $raw = get_option( 'themify_updater_licence', '' );
964 if ( ! is_string( $raw ) || $raw === '' ) {
965 return themify_license_default_settings_row();
966 }
967 $decoded = json_decode( $raw, true );
968
969 return themify_license_sanitize_settings_payload_theme( is_array( $decoded ) ? $decoded : array() );
970 }
971
972 function themify_license_get_effective_credentials_for_resolve() {
973 if ( class_exists( 'Themify_Updater', false ) && method_exists( 'Themify_Updater', 'get_instance' ) ) {
974 $tu = Themify_Updater::get_instance();
975
976 return array(
977 'username' => (string) $tu->get_setting( 'username' ),
978 'key' => (string) $tu->get_setting( 'key' ),
979 'hideKey' => (bool) $tu->get_setting( 'hideKey' ),
980 'hideName' => (bool) $tu->get_setting( 'hideName' ),
981 );
982 }
983 $opt = themify_license_load_stored_settings_row();
984
985 return array(
986 'username' => isset( $opt['username'] ) ? $opt['username'] : '',
987 'key' => isset( $opt['key'] ) ? $opt['key'] : '',
988 'hideKey' => ! empty( $opt['hideKey'] ),
989 'hideName' => ! empty( $opt['hideName'] ),
990 );
991 }
992
993 function themify_license_resolve_posted_credentials( $posted_username, $posted_key ) {
994 themify_license_require_updater_utils();
995 $posted_username = isset( $posted_username ) ? wp_unslash( (string) $posted_username ) : '';
996 $posted_key = isset( $posted_key ) ? wp_unslash( (string) $posted_key ) : '';
997
998 if ( ! class_exists( 'Themify_Updater_utils', false ) ) {
999 $u = preg_replace( '/[^0-9A-Za-z_-]/', '', $posted_username );
1000 $k = preg_replace( '/[^0-9A-Za-z]/', '', $posted_key );
1001
1002 return array( $u, $k );
1003 }
1004
1005 $stored = themify_license_get_effective_credentials_for_resolve();
1006 $cred_username = $stored['username'];
1007 $cred_key = $stored['key'];
1008 $hide_name = $stored['hideName'];
1009 $hide_key = $stored['hideKey'];
1010
1011 $temp_username_mask = Themify_Updater_utils::preg_replace( $cred_username, 'username', '*' );
1012 $temp_key_mask = Themify_Updater_utils::preg_replace( $cred_key, 'key', '*' );
1013
1014 if ( $hide_name ) {
1015 $resolved_u = ( $posted_username === $temp_username_mask ) ? $cred_username : Themify_Updater_utils::preg_replace( $posted_username, 'username' );
1016 } else {
1017 $resolved_u = Themify_Updater_utils::preg_replace( $posted_username, 'username' );
1018 }
1019
1020 if ( $hide_key ) {
1021 $resolved_k = ( $posted_key === $temp_key_mask ) ? $cred_key : Themify_Updater_utils::preg_replace( $posted_key, 'key' );
1022 } else {
1023 $resolved_k = Themify_Updater_utils::preg_replace( $posted_key, 'key' );
1024 }
1025
1026 return array( $resolved_u, $resolved_k );
1027 }
1028
1029 function themify_update_license() {
1030 check_ajax_referer( 'tf_nonce', 'nonce' );
1031 if ( ! current_user_can( 'manage_options' ) ) {
1032 return;
1033 }
1034 $posted_username = isset( $_POST['themify_username'] ) ? $_POST['themify_username'] : '';
1035 $posted_key = isset( $_POST['updater_licence'] ) ? $_POST['updater_licence'] : '';
1036
1037 list( $username, $key ) = themify_license_resolve_posted_credentials( $posted_username, $posted_key );
1038
1039 if ( $username === '' || $key === '' ) {
1040 wp_send_json_error( __( 'Invalid license key. Please enter your Themify username and a valid license key.', 'themify' ) );
1041 }
1042
1043 if ( class_exists( 'Themify_Updater', false ) && method_exists( 'Themify_Updater', 'get_instance' ) ) {
1044 $themify_updater = Themify_Updater::get_instance();
1045 if ( ! method_exists( $themify_updater, 'save_license_credentials_from_themify_theme' ) ) {
1046 wp_send_json_error( __( 'You need the latest Themify Updater plugin for this feature. Please update your Themify Updater plugin.', 'themify' ) );
1047 }
1048 $saved = $themify_updater->save_license_credentials_from_themify_theme( $username, $key );
1049 if ( is_wp_error( $saved ) ) {
1050 $msg = 'empty' === $saved->get_error_code()
1051 ? __( 'Invalid license key. Please enter your Themify username and a valid license key.', 'themify' )
1052 : $saved->get_error_message();
1053 wp_send_json_error( $msg );
1054 }
1055 wp_send_json_success( array() );
1056 }
1057
1058 $row = themify_license_load_stored_settings_row();
1059 $row['username'] = $username;
1060 $row['key'] = $key;
1061 update_option( 'themify_updater_licence', wp_json_encode( themify_license_sanitize_settings_payload_theme( $row ) ), false );
1062 wp_send_json_success( array() );
1063 }
1064