| 1 |
<?php |
| 2 |
defined('ABSPATH') || exit; |
| 3 |
|
| 4 |
class Themify_Builder_Active{ |
| 5 |
|
| 6 |
public static function init():void{ |
| 7 |
self::includes(); |
| 8 |
self::run(); |
| 9 |
} |
| 10 |
|
| 11 |
private static function run():void{ |
| 12 |
if (Themify_Builder_Model::is_front_builder_activate()) { |
| 13 |
// load module panel frontend |
| 14 |
add_action('wp_footer', array(__CLASS__, 'load_javascript_template_front'), 1); |
| 15 |
add_filter('show_admin_bar', '__return_false'); // Custom CSS |
| 16 |
add_filter('themify_dev_mode', '__return_false'); |
| 17 |
global $wp_actions; |
| 18 |
$wp_actions['wp_enqueue_media'] = true; |
| 19 |
themify_set_headers(array( |
| 20 |
'X-FRAME-OPTIONS' => 'SAMEORIGIN', |
| 21 |
'CONTENT-SECURITY-POLICY' => array( |
| 22 |
'img-src' => "https://themify.org https://placehold.co 'unsafe-inline' blob:", |
| 23 |
'default-src' => "https://placehold.co 'unsafe-inline' blob:" |
| 24 |
) |
| 25 |
)); |
| 26 |
} |
| 27 |
else { |
| 28 |
$is_admin = is_admin(); |
| 29 |
$is_ajax=themify_is_ajax(); |
| 30 |
// Ajax Actions |
| 31 |
if ($is_ajax===true) { |
| 32 |
add_action('wp_ajax_tb_load_editor', array(__CLASS__, 'load_editor'), 10); |
| 33 |
|
| 34 |
add_action('wp_ajax_tb_load_module_partial', array(__CLASS__, 'load_module_partial_ajaxify'), 10); |
| 35 |
add_action('wp_ajax_tb_render_element', array(__CLASS__, 'render_element_ajaxify'), 10); |
| 36 |
add_action('wp_ajax_tb_get_post_types', array(__CLASS__, 'get_ajax_post_types'), 10); |
| 37 |
add_action('wp_ajax_tb_render_element_shortcode', array(__CLASS__, 'render_element_shortcode_ajaxify'), 10); |
| 38 |
// Builder Save Data |
| 39 |
add_action('wp_ajax_tb_save_data', array(__CLASS__, 'save_data_builder'), 10); |
| 40 |
add_action('wp_ajax_tb_save_css', array(__CLASS__, 'save_builder_css'), 10); |
| 41 |
// AJAX Action Save Module Favorite Data |
| 42 |
add_action('wp_ajax_tb_module_favorite', array(__CLASS__, 'save_module_favorite_data')); |
| 43 |
//AJAX Action update ticks and TakeOver |
| 44 |
add_action('wp_ajax_tb_update_tick', array(__CLASS__, 'update_tick')); |
| 45 |
add_action('wp_ajax_tb_help', array(__CLASS__, 'help')); |
| 46 |
// Replace URL |
| 47 |
add_action('wp_ajax_tb_get_ajax_builder_posts', array(__CLASS__, 'get_ajax_builder_posts')); |
| 48 |
add_action('wp_ajax_tb_get_ajax_data', array(__CLASS__, 'get_ajax_data')); |
| 49 |
add_action('wp_ajax_tb_validate_captcha', array(__CLASS__, 'ajax_validate_captcha')); |
| 50 |
add_action('wp_ajax_tb_get_pages', array(__CLASS__, 'tb_get_pages')); |
| 51 |
add_action('wp_ajax_tb_set_fullwidth', array(__CLASS__, 'set_fullwidth')); |
| 52 |
} |
| 53 |
if ($is_admin === false || $is_ajax===true) { |
| 54 |
add_action('admin_bar_menu', array(__CLASS__, 'builder_admin_bar_menu'), 100); |
| 55 |
if ($is_admin === false) { |
| 56 |
add_action('wp_footer', array(__CLASS__, 'async_footer')); |
| 57 |
} |
| 58 |
} |
| 59 |
// Import Export |
| 60 |
Themify_Builder_Import_Export::init(); |
| 61 |
} |
| 62 |
|
| 63 |
// Library Module, Rows and Layout Parts |
| 64 |
Themify_Builder_Library_Items::init(); |
| 65 |
|
| 66 |
// Themify Builder Revisions |
| 67 |
Themify_Builder_Revisions::init(); |
| 68 |
|
| 69 |
// Fix security restrictions |
| 70 |
add_filter('user_can_richedit', '__return_true'); |
| 71 |
} |
| 72 |
|
| 73 |
/** |
| 74 |
* Load interface js and css |
| 75 |
*/ |
| 76 |
private static function load_frontend_interface():void { |
| 77 |
|
| 78 |
// load only when builder is turn on |
| 79 |
$editorUrl = THEMIFY_BUILDER_URI . '/css/editor/'; |
| 80 |
themify_enque_style('themify-builder-admin-ui', $editorUrl . 'themify-builder-admin-ui.css', array(), THEMIFY_VERSION, '', true); |
| 81 |
$grids = array_diff(scandir(THEMIFY_DIR . '/css/grids/', SCANDIR_SORT_NONE), array('..', '.')); |
| 82 |
foreach ($grids as $g) { |
| 83 |
Themify_Enqueue_Assets::loadGridCss(str_replace('.css', '', $g), true); |
| 84 |
} |
| 85 |
unset($grids); |
| 86 |
|
| 87 |
$editorUrl = THEMIFY_BUILDER_URI . '/js/editor/'; |
| 88 |
Themify_Icon_Font::enqueue(); |
| 89 |
|
| 90 |
wp_enqueue_script( 'jquery' ); |
| 91 |
themify_enque_script('themify-colorpicker', THEMIFY_METABOX_URI . 'js/themify.minicolors.js'); |
| 92 |
themify_enque_script('themify-combobox', $editorUrl . 'themify-combobox.min.js'); |
| 93 |
|
| 94 |
themify_enque_script('themify-builder-js', THEMIFY_BUILDER_URI . '/js/themify-builder-script.js'); |
| 95 |
themify_enque_script('tb_builder_js_style', THEMIFY_URI . '/js/generate-style.js'); |
| 96 |
themify_enque_script('themify-builder-app-js', $editorUrl . 'build/components.min.js', THEMIFY_VERSION, array('tb_builder_js_style')); |
| 97 |
themify_enque_script('themify-builder-modules-js', $editorUrl . 'build/modules.min.js', THEMIFY_VERSION, array('themify-builder-app-js')); |
| 98 |
|
| 99 |
themify_enque_script('themify-builder-front-ui-js', $editorUrl . 'frontend/themify-builder-visual.js', THEMIFY_VERSION, array('themify-builder-app-js')); |
| 100 |
themify_enque_style('tb-display-conditions-css', THEMIFY_BUILDER_URI . '/css/editor/display-conditions.css', array(), THEMIFY_VERSION, 'all', true); |
| 101 |
themify_enque_script('tb-display-conditions-js', THEMIFY_BUILDER_URI . '/js/editor/display-conditions.js', THEMIFY_VERSION, array('themify-builder-app-js')); |
| 102 |
|
| 103 |
global $shortcode_tags; |
| 104 |
$builderData = self::get_active_builder_vars(); |
| 105 |
$builderData['upload_url'] = themify_upload_dir('baseurl'); |
| 106 |
$builderData['available_shortcodes'] = array_keys($shortcode_tags); |
| 107 |
$builderData['post_ID'] = (int) Themify_Builder::$builder_active_id; |
| 108 |
|
| 109 |
do_action('themify_builder_active_enqueue', 'visual'); |
| 110 |
wp_localize_script('themify-colorpicker', 'themifyCM', Themify_Metabox::themify_localize_cm_data()); |
| 111 |
wp_localize_script('themify-builder-app-js', 'themifyBuilder', $builderData); |
| 112 |
} |
| 113 |
|
| 114 |
private static function load_admin_interface():void { |
| 115 |
$editorUrl = THEMIFY_BUILDER_URI . '/css/editor/'; |
| 116 |
themify_enque_style('tf_base', THEMIFY_URI . '/css/base.min.css', null, THEMIFY_VERSION, '', true); |
| 117 |
themify_enque_style('themify-builder-loader', $editorUrl . 'themify-builder-loader.css', null, THEMIFY_VERSION, '', true); |
| 118 |
themify_enque_style('themify-builder-style', THEMIFY_BUILDER_URI . '/css/themify-builder-style.css', null, THEMIFY_VERSION, '', true); |
| 119 |
themify_enque_style('themify-builder-lightbox', $editorUrl . 'components/lightbox.css', null, THEMIFY_VERSION, '', true); |
| 120 |
themify_enque_style('themify-builder-admin-ui', $editorUrl . 'themify-builder-admin-ui.css', null, THEMIFY_VERSION, '', true); |
| 121 |
themify_enque_style('themify-backend-mode', $editorUrl . 'backend-mode.css', null, THEMIFY_VERSION, '', true); |
| 122 |
themify_enque_style('themify-backend-ui', $editorUrl . 'backend/backend-ui.css', null, THEMIFY_VERSION, '', true); |
| 123 |
$editorUrl = THEMIFY_BUILDER_URI . '/js/editor/'; |
| 124 |
|
| 125 |
Themify_Enqueue_Assets::loadMainScript(); |
| 126 |
|
| 127 |
themify_enque_script('themify-combobox', $editorUrl . 'themify-combobox.min.js'); |
| 128 |
|
| 129 |
themify_enque_script('tb_builder_js_style', THEMIFY_URI . '/js/generate-style.js'); |
| 130 |
|
| 131 |
themify_enque_script('themify-builder-app-js', $editorUrl . 'build/components.min.js', THEMIFY_VERSION, array('tb_builder_js_style')); |
| 132 |
themify_enque_script('themify-builder-modules-js', $editorUrl . 'build/modules.min.js', THEMIFY_VERSION, array('themify-builder-app-js')); |
| 133 |
|
| 134 |
themify_enque_script('themify-builder-backend-js', $editorUrl . 'backend/themify-builder-backend.js', THEMIFY_VERSION, array('themify-builder-app-js')); |
| 135 |
themify_enque_style('tb-display-conditions-css', THEMIFY_BUILDER_URI . '/css/editor/display-conditions.css', array(), THEMIFY_VERSION, 'all', true); |
| 136 |
themify_enque_script('tb-display-conditions-js', THEMIFY_BUILDER_URI . '/js/editor/display-conditions.js', THEMIFY_VERSION, array('themify-builder-app-js')); |
| 137 |
|
| 138 |
themify_enque_script('themify-static-badge', THEMIFY_BUILDER_URI . '/js/editor/backend/themify-builder-static-badge.js', THEMIFY_VERSION, array('mce-view', 'themify-builder-backend-js')); |
| 139 |
|
| 140 |
|
| 141 |
|
| 142 |
$builderData = self::get_active_builder_vars(); |
| 143 |
$builderData['post_ID'] = get_the_ID(); |
| 144 |
$builderData['is_gutenberg_editor'] = Themify_Builder_Model::is_gutenberg_editor(); |
| 145 |
do_action('themify_builder_active_enqueue', 'admin'); |
| 146 |
|
| 147 |
wp_localize_script('themify-builder-app-js', 'themifyBuilder', $builderData); |
| 148 |
} |
| 149 |
|
| 150 |
|
| 151 |
private static function get_active_builder_vars():array { |
| 152 |
Themify_Builder_Component_Module::load_modules(); |
| 153 |
$video=$audio=$image=[]; |
| 154 |
if(current_user_can('upload_files')){ |
| 155 |
$tmp_extensions = get_allowed_mime_types(); |
| 156 |
$allowed_extensions=[]; |
| 157 |
foreach($tmp_extensions as $ext=>$v){ |
| 158 |
if(strpos($ext,'|')!==false){ |
| 159 |
$ext=explode('|',$ext); |
| 160 |
foreach($ext as $ex){ |
| 161 |
$allowed_extensions[$ex]=$v; |
| 162 |
} |
| 163 |
}else{ |
| 164 |
$allowed_extensions[$ext]=$v; |
| 165 |
} |
| 166 |
} |
| 167 |
$extensions=wp_get_ext_types(); |
| 168 |
$_video= $extensions['video']; |
| 169 |
$_audio=$extensions['audio']; |
| 170 |
$_image= $extensions['image']; |
| 171 |
$tmp_extensions=$extensions=null; |
| 172 |
foreach($_video as $v){ |
| 173 |
if ( isset($allowed_extensions[$v]) ) { |
| 174 |
$mime=explode('/',$allowed_extensions[$v])[1]; |
| 175 |
if(!isset($video[$mime])){ |
| 176 |
$video[$mime]=''; |
| 177 |
} |
| 178 |
$video[$mime].=$v.'|'; |
| 179 |
} |
| 180 |
} |
| 181 |
foreach($_audio as $v){ |
| 182 |
if ( isset($allowed_extensions[$v]) ) { |
| 183 |
$mime=explode('/',$allowed_extensions[$v])[1]; |
| 184 |
if(!isset($audio[$mime])){ |
| 185 |
$audio[$mime]=''; |
| 186 |
} |
| 187 |
$audio[$mime].=$v.'|'; |
| 188 |
} |
| 189 |
} |
| 190 |
foreach($_image as $v){ |
| 191 |
if ( isset($allowed_extensions[$v]) ) { |
| 192 |
$mime=explode('/',$allowed_extensions[$v])[1]; |
| 193 |
if(!isset($image[$mime])){ |
| 194 |
$image[$mime]=''; |
| 195 |
} |
| 196 |
$image[$mime].=$v.'|'; |
| 197 |
} |
| 198 |
} |
| 199 |
$allowed_extensions=$_video=$_audio=$_image=null; |
| 200 |
} |
| 201 |
global $wp_styles; |
| 202 |
$id = is_admin() ? get_the_ID() : Themify_Builder::$builder_active_id; |
| 203 |
$i18n=include THEMIFY_BUILDER_INCLUDES_DIR . '/i18n.php'; |
| 204 |
$vars=apply_filters('themify_builder_active_vars',[ |
| 205 |
'builder_data' => ThemifyBuilder_Data_Manager::get_data($id), |
| 206 |
'addons'=>[], |
| 207 |
'site_url' => get_site_url(), |
| 208 |
'nonce' => wp_create_nonce('tf_nonce'), |
| 209 |
'disableShortcuts' => themify_builder_get('setting-page_builder_disable_shortcuts', 'builder_disable_shortcuts'), |
| 210 |
'widget_css' => array(home_url($wp_styles->registered['widgets']->src), home_url($wp_styles->registered['customize-widgets']->src)), |
| 211 |
'modules' => Themify_Builder_Model::get_modules_localize_settings(), |
| 212 |
'favorite' => Themify_Builder_Model::get_favorite_modules(), |
| 213 |
'gutters' => Themify_Builder_Model::get_gutters(), |
| 214 |
'i18n' => $i18n, |
| 215 |
'layouts' => Themify_Builder_Model::get_layouts(), |
| 216 |
'blocks' => 'https://themify.org/public-api/predesigned-rows/', |
| 217 |
'custom_css' => get_post_meta($id, 'tbp_custom_css', true), |
| 218 |
'custom_js' => get_post_meta($id, 'tbp_custom_js', true), |
| 219 |
'post_title' => get_the_title($id), |
| 220 |
'cf_api_url' => Themify_Custom_Fonts::$api_url, |
| 221 |
'safe' => themify_get_web_safe_font_list(), |
| 222 |
'google' => themify_get_google_web_fonts_list(), |
| 223 |
'cf' => Themify_Custom_Fonts::get_list(), |
| 224 |
'ticks' => Themify_Builder_Model::get_transient_time(), |
| 225 |
'memory' => (int) (wp_convert_hr_to_bytes(WP_MEMORY_LIMIT) * MB_IN_BYTES), |
| 226 |
'imgphp'=>Themify_Builder_Model::is_img_php_disabled(), |
| 227 |
'admin_url'=>rtrim( get_admin_url(), '/' ), |
| 228 |
'ext'=>['video'=>$video,'audio'=>$audio,'image'=>$image] |
| 229 |
], is_admin() ? 'admin' : 'visual' ); |
| 230 |
unset($image,$video,$audio); |
| 231 |
$jsonFiles=Themify_Builder_Component_Module::get_styles_json(); |
| 232 |
$vars['style_json']=$jsonFiles; |
| 233 |
if(!is_admin()){ |
| 234 |
foreach($jsonFiles as $f){ |
| 235 |
Themify_Enqueue_Assets::addPreLoadMedia($f,'prefetch','json'); |
| 236 |
} |
| 237 |
} |
| 238 |
if(!current_user_can('upload_files')){ |
| 239 |
$vars['upload_disable']=1; |
| 240 |
} |
| 241 |
if(!function_exists('gzdecode')){ |
| 242 |
$vars['gzip_disabled']=1; |
| 243 |
} |
| 244 |
if(empty($vars['custom_css'])){ |
| 245 |
unset($vars['custom_css']); |
| 246 |
} |
| 247 |
if(empty($vars['custom_js'])){ |
| 248 |
unset($vars['custom_js']); |
| 249 |
} |
| 250 |
if(empty($vars['imgphp'])){ |
| 251 |
unset($vars['imgphp']); |
| 252 |
} |
| 253 |
if(empty($vars['favorite'])){ |
| 254 |
unset($vars['favorite']); |
| 255 |
} |
| 256 |
if(empty($vars['addons'])){ |
| 257 |
unset($vars['addons']); |
| 258 |
} |
| 259 |
if(empty($vars['disableShortcuts'])){ |
| 260 |
unset($vars['disableShortcuts']); |
| 261 |
} |
| 262 |
if(empty($vars['style_json'])){ |
| 263 |
unset($vars['style_json']); |
| 264 |
} |
| 265 |
if ( ! is_admin() && $id && self::should_suggest_fullwidth( (int) $id ) ) { |
| 266 |
$vars['suggestFullWidth'] = 1; |
| 267 |
} |
| 268 |
return $vars; |
| 269 |
} |
| 270 |
|
| 271 |
private static function should_suggest_fullwidth( int $id ): bool { |
| 272 |
if ( get_post_type( $id ) !== 'page' || ! themify_is_themify_theme() ) { |
| 273 |
return false; |
| 274 |
} |
| 275 |
if ( themify_builder_check( 'setting-page_builder_disable_fullwidth_suggestion', 'builder_disable_fullwidth_suggestion' ) ) { |
| 276 |
return false; |
| 277 |
} |
| 278 |
if ( get_post_meta( $id, 'page_layout', true ) !== 'sidebar-none' ) { |
| 279 |
return false; |
| 280 |
} |
| 281 |
return ! self::is_full_width_layout( $id ); |
| 282 |
} |
| 283 |
|
| 284 |
private static function is_full_width_layout( int $id ): bool { |
| 285 |
$classes = get_body_class(); |
| 286 |
if ( in_array( 'full_width', $classes, true ) || in_array( 'tb_fullwidth', $classes, true ) ) { |
| 287 |
return true; |
| 288 |
} |
| 289 |
if ( get_post_meta( $id, 'content_width', true ) === 'full_width' ) { |
| 290 |
return true; |
| 291 |
} |
| 292 |
$post_type = get_post_type( $id ); |
| 293 |
$key = $post_type === 'page' ? 'page_layout' : 'custom_post_' . $post_type . '_single'; |
| 294 |
return get_post_meta( $id, $key, true ) === 'full_width'; |
| 295 |
} |
| 296 |
|
| 297 |
private static function includes():void { |
| 298 |
include THEMIFY_BUILDER_CLASSES_DIR . '/class-themify-builder-revisions.php'; |
| 299 |
include THEMIFY_BUILDER_CLASSES_DIR . '/class-themify-builder-library-item.php'; |
| 300 |
include THEMIFY_BUILDER_CLASSES_DIR . '/class-builder-duplicate-page.php'; |
| 301 |
include THEMIFY_BUILDER_CLASSES_DIR . '/class-themify-builder-import-export.php'; |
| 302 |
} |
| 303 |
|
| 304 |
|
| 305 |
/** |
| 306 |
* Loads JS templates for front-end editor. |
| 307 |
*/ |
| 308 |
public static function load_javascript_template_front():void { |
| 309 |
add_filter( 'wp_inline_script_attributes', array(__CLASS__, 'exclude_cloudfare_js'), 11,1); |
| 310 |
|
| 311 |
self::load_frontend_interface(); |
| 312 |
include THEMIFY_BUILDER_INCLUDES_DIR . '/tpl/tmpl-common.php'; |
| 313 |
include THEMIFY_BUILDER_INCLUDES_DIR . '/tpl/tmpl-front.php'; |
| 314 |
} |
| 315 |
|
| 316 |
/** |
| 317 |
* Loads JS templates for WordPress admin dashboard editor. |
| 318 |
*/ |
| 319 |
public static function load_javascript_template_admin():void { |
| 320 |
self::load_admin_interface(); |
| 321 |
self::print_static_content_badge_templates(); |
| 322 |
include THEMIFY_BUILDER_INCLUDES_DIR . '/tpl/tmpl-common.php'; |
| 323 |
include THEMIFY_BUILDER_INCLUDES_DIR . '/tpl/tmpl-admin.php'; |
| 324 |
} |
| 325 |
|
| 326 |
|
| 327 |
|
| 328 |
public static function exclude_cloudfare_js(array $attr=array()):array { |
| 329 |
if(isset($attr['id']) && ($attr['id']==='themify-builder-app-js-js-extra' || $attr['id']==='themify-colorpicker-js-extra' || $attr['id']==='tf-icon-picker-js-extra')){ |
| 330 |
$attr['data-cfasync']='false'; |
| 331 |
$attr['data-no-optimize']=$attr['data-noptimize']=1; |
| 332 |
} |
| 333 |
return $attr; |
| 334 |
} |
| 335 |
|
| 336 |
private static function can_edit_builder_post( $post_id = 0 ): bool { |
| 337 |
if ( ! current_user_can( 'edit_posts' ) ) { |
| 338 |
return false; |
| 339 |
} |
| 340 |
$post_id = (int) $post_id; |
| 341 |
return $post_id > 0 ? current_user_can( 'edit_post', $post_id ) : true; |
| 342 |
} |
| 343 |
|
| 344 |
public static function load_editor() { |
| 345 |
if ( ! self::can_edit_builder_post() ) { |
| 346 |
wp_die( -1, 403 ); |
| 347 |
} |
| 348 |
global $wp_scripts, $wp_styles, $concatenate_scripts, $wp_actions; |
| 349 |
if (!defined('CONCATENATE_SCRIPTS')) { |
| 350 |
define('CONCATENATE_SCRIPTS', false); |
| 351 |
} |
| 352 |
$concatenate_scripts = false; |
| 353 |
|
| 354 |
/* ensure $wp_scripts and $wp_styles globals have been initialized */ |
| 355 |
wp_styles(); |
| 356 |
wp_scripts(); |
| 357 |
|
| 358 |
wp_enqueue_script( 'jquery-ui-sortable' ); |
| 359 |
wp_enqueue_script( 'shortcode' ); |
| 360 |
|
| 361 |
/* force a load uncompressed TinyMCE script, fix script issues on frontend editor */ |
| 362 |
$wp_scripts->remove('wp-tinymce'); |
| 363 |
wp_register_tinymce_scripts($wp_scripts, true); // true: $force_uncompressed |
| 364 |
//store original |
| 365 |
if (is_object($wp_styles)) { |
| 366 |
$tmp_styles = clone $wp_styles; |
| 367 |
} |
| 368 |
$tmp_scripts = clone $wp_scripts; |
| 369 |
$new = array(); |
| 370 |
|
| 371 |
foreach ($tmp_scripts->registered as $k => $v) { |
| 372 |
$new[$k] = clone $v; |
| 373 |
} |
| 374 |
|
| 375 |
$scripts_registered = $new; |
| 376 |
if (isset($tmp_styles)) { |
| 377 |
$new = array(); |
| 378 |
foreach ($tmp_styles->registered as $k => $v) { |
| 379 |
$new[$k] = clone $v; |
| 380 |
} |
| 381 |
$styles_registered = $new; |
| 382 |
} |
| 383 |
$new = null; |
| 384 |
//don't allow loading wp_enqueue_media thirdy party plugins |
| 385 |
$wp_actions['wp_enqueue_media'] = true; |
| 386 |
|
| 387 |
//for thirdy party plugins, maybe they use wp_enqueue_scripts hook to add localize data in tinymce, the js files we don't need to check by wp standart they should use mce_external_plugins |
| 388 |
do_action('wp_enqueue_scripts'); |
| 389 |
$data = !empty($wp_scripts->registered['editor']->extra['data']) ? $wp_scripts->registered['editor']->extra['data'] : null; |
| 390 |
|
| 391 |
//restore original because we only need the js/css related with wp editor only,otherwise they will be loaded in wp_footer |
| 392 |
if (isset($tmp_styles)) { |
| 393 |
$tmp_styles->registered = $styles_registered; |
| 394 |
$wp_styles = clone $tmp_styles; |
| 395 |
$tmp_styles = $styles_registered = null; |
| 396 |
} |
| 397 |
$tmp_scripts->registered = $scripts_registered; |
| 398 |
|
| 399 |
$wp_scripts = clone $tmp_scripts; |
| 400 |
$tmp_scripts = $scripts_registered = null; |
| 401 |
|
| 402 |
$wp_scripts->done[] = 'jquery'; |
| 403 |
$wp_scripts->done[] = 'jquery-core'; |
| 404 |
unset($wp_actions['wp_enqueue_media']); |
| 405 |
echo '<div id="tb_tinymce_wrap">'; |
| 406 |
if (current_user_can('upload_files')) { |
| 407 |
wp_enqueue_media(); |
| 408 |
} |
| 409 |
echo '<div style="display:none;">'; |
| 410 |
wp_editor(' ', 'tb_lb_hidden_editor'); |
| 411 |
echo '</div>'; |
| 412 |
if (!empty($wp_scripts->registered['editor']->deps)) { |
| 413 |
$wp_scripts->registered['editor']->deps[] = 'wp-tinymce-root'; |
| 414 |
} else { |
| 415 |
$wp_scripts->registered['editor']->deps = array('wp-tinymce-root'); |
| 416 |
} |
| 417 |
//wp is returing is_admin() true on the ajax call,that is why we have to add these hooks manually |
| 418 |
add_action('wp_print_footer_scripts', array('_WP_Editors', 'editor_js'), 50); |
| 419 |
add_action('wp_print_footer_scripts', array('_WP_Editors', 'force_uncompressed_tinymce'), 1); |
| 420 |
add_action('wp_print_footer_scripts', array('_WP_Editors', 'enqueue_scripts'), 1); |
| 421 |
wp_footer(); |
| 422 |
|
| 423 |
if ($data !== null) { |
| 424 |
echo '<script>', $data, '</script>'; |
| 425 |
} |
| 426 |
echo '</div>'; |
| 427 |
die; |
| 428 |
} |
| 429 |
|
| 430 |
/** |
| 431 |
* Load module partial when update live content |
| 432 |
*/ |
| 433 |
public static function load_module_partial_ajaxify() { |
| 434 |
check_ajax_referer('tf_nonce', 'nonce'); |
| 435 |
if ( ! self::can_edit_builder_post( $_POST['bid'] ?? 0 ) ) { |
| 436 |
wp_die( -1, 403 ); |
| 437 |
} |
| 438 |
themify_disable_other_lazy(); |
| 439 |
Themify_Builder::$frontedit_active = true; |
| 440 |
Themify_Builder::$builder_active_id = (int) $_POST['bid']; |
| 441 |
$new_modules = apply_filters('themify_builder_load_module_partial', array( |
| 442 |
'mod_name' => $_POST['tb_module_slug'], |
| 443 |
'mod_settings' => json_decode(stripslashes($_POST['tb_module_data']), true), |
| 444 |
'element_id' => $_POST['element_id'] |
| 445 |
)); |
| 446 |
|
| 447 |
Themify_Builder_Component_Module::template($new_modules, Themify_Builder::$builder_active_id); |
| 448 |
$css = Themify_Enqueue_Assets::get_css(); |
| 449 |
if (!empty($css)) { |
| 450 |
echo '<script type="text/template" id="tb_module_styles">', json_encode($css), '</script>'; |
| 451 |
} |
| 452 |
wp_die(); |
| 453 |
} |
| 454 |
|
| 455 |
public static function render_element_ajaxify() { |
| 456 |
check_ajax_referer('tf_nonce', 'nonce'); |
| 457 |
if ( ! self::can_edit_builder_post( $_POST['bid'] ?? 0 ) ) { |
| 458 |
wp_die( -1, 403 ); |
| 459 |
} |
| 460 |
themify_disable_other_lazy(); |
| 461 |
$response = array(); |
| 462 |
$batch = json_decode(stripslashes($_POST['batch']), true); |
| 463 |
Themify_Builder::$frontedit_active = true; |
| 464 |
$batch = apply_filters('themify_builder_load_module_partial', $batch); |
| 465 |
Themify_Builder::$builder_active_id = $activeId = (int) $_POST['bid']; |
| 466 |
if (!empty($_POST['tmpGS'])) { |
| 467 |
Themify_Global_Styles::$used_styles[$activeId] = Themify_Global_Styles::addGS($activeId, json_decode(stripslashes($_POST['tmpGS']), true)); |
| 468 |
} |
| 469 |
if (!empty($batch)) { |
| 470 |
$used_gs = array(); |
| 471 |
foreach ($batch as $b) { |
| 472 |
$type = $b['elType']; |
| 473 |
$element_id = $b['element_id']; |
| 474 |
switch ($type) { |
| 475 |
case 'module': |
| 476 |
if (isset($_POST['element_id'])) { |
| 477 |
$element_id = $b['element_id'] = $_POST['element_id']; |
| 478 |
} |
| 479 |
$markup = Themify_Builder_Component_Module::template($b, $activeId, false); |
| 480 |
break; |
| 481 |
|
| 482 |
case 'subrow': |
| 483 |
unset($b['cols']); |
| 484 |
$markup = Themify_Builder_Component_SubRow::template($b, $activeId, false); |
| 485 |
break; |
| 486 |
|
| 487 |
case 'column': |
| 488 |
unset($b['modules']); |
| 489 |
$markup = Themify_Builder_Component_Column::template($b, $activeId, false); |
| 490 |
break; |
| 491 |
|
| 492 |
case 'row': |
| 493 |
unset($b['cols']); |
| 494 |
$markup = Themify_Builder_Component_Row::template($b, $activeId, false); |
| 495 |
break; |
| 496 |
} |
| 497 |
$response[$element_id] = $markup; |
| 498 |
if (!empty($b['attached_gs'])) { |
| 499 |
$used_gs = array_merge($used_gs, $b['attached_gs']); |
| 500 |
} |
| 501 |
} |
| 502 |
} |
| 503 |
$batch = null; |
| 504 |
if (!empty($used_gs)) { |
| 505 |
$used_gs = array_keys(array_flip($used_gs)); |
| 506 |
// Return used gs |
| 507 |
$args = array( |
| 508 |
'exclude' => empty($_POST['loadedGS']) ? array() : $_POST['loadedGS'], |
| 509 |
'include' => $used_gs, |
| 510 |
'limit' => -1, |
| 511 |
'data' => true |
| 512 |
); |
| 513 |
|
| 514 |
$used_gs = Themify_Global_Styles::get_global_styles($args); |
| 515 |
if (!empty($used_gs)) { |
| 516 |
$response['gs'] = $used_gs; |
| 517 |
} |
| 518 |
} |
| 519 |
$css = Themify_Enqueue_Assets::get_css(); |
| 520 |
if (!empty($css)) { |
| 521 |
$response['tb_module_styles'] = $css; |
| 522 |
} |
| 523 |
//don't use wp_send_json it's very heavy,this array can be very large |
| 524 |
header('Content-Type: application/json; charset=' . get_option('blog_charset')); |
| 525 |
die(json_encode($response)); |
| 526 |
} |
| 527 |
|
| 528 |
public static function render_element_shortcode_ajaxify() { |
| 529 |
check_ajax_referer('tf_nonce', 'nonce'); |
| 530 |
if ( ! self::can_edit_builder_post( $_POST['bid'] ?? 0 ) ) { |
| 531 |
wp_die( -1, 403 ); |
| 532 |
} |
| 533 |
$shortcodes = $styles = array(); |
| 534 |
$shortcode_data = json_decode(stripslashes_deep($_POST['shortcode_data']), true); |
| 535 |
|
| 536 |
if (is_array($shortcode_data)) { |
| 537 |
if(!empty($_POST['bid'])){ |
| 538 |
$p=get_post((int)$_POST['bid']); |
| 539 |
if(!empty($p)){ |
| 540 |
$arr=array( |
| 541 |
'no_found_rows'=>false, |
| 542 |
'ignore_sticky_posts'=>true, |
| 543 |
'orderby'=>'none', |
| 544 |
'post_status'=>$p->post_status, |
| 545 |
'post_type'=>$p->post_type |
| 546 |
); |
| 547 |
if($p->post_type==='page'){ |
| 548 |
$arr['page_id']=$p->ID; |
| 549 |
}else{ |
| 550 |
$arr['p']=$p->ID; |
| 551 |
} |
| 552 |
query_posts($arr); |
| 553 |
unset($arr); |
| 554 |
global $post; |
| 555 |
$post=$p; |
| 556 |
setup_postdata( $post ); |
| 557 |
} |
| 558 |
} |
| 559 |
foreach ($shortcode_data as $shortcode) { |
| 560 |
$shortcodes[] = array('key' => $shortcode, 'html' => Themify_Builder_Model::format_text($shortcode)); |
| 561 |
} |
| 562 |
} |
| 563 |
|
| 564 |
global $wp_styles; |
| 565 |
if (isset($wp_styles) && !empty($shortcodes)) { |
| 566 |
ob_start(); |
| 567 |
$tmp = $wp_styles->do_items(); |
| 568 |
ob_end_clean(); |
| 569 |
foreach ($tmp as $handler) { |
| 570 |
if (isset($wp_styles->registered[$handler])) { |
| 571 |
$src = $wp_styles->registered[$handler]->src; |
| 572 |
if (strpos($src, 'http') === false) { |
| 573 |
$src = home_url($src); |
| 574 |
} |
| 575 |
$styles[] = array( |
| 576 |
's' => $src, |
| 577 |
'v' => $wp_styles->registered[$handler]->ver, |
| 578 |
'm' => isset($wp_styles->registered[$handler]->args) ? $wp_styles->registered[$handler]->args : 'all' |
| 579 |
); |
| 580 |
} |
| 581 |
} |
| 582 |
unset($tmp); |
| 583 |
} |
| 584 |
|
| 585 |
wp_send_json_success(array( |
| 586 |
'shortcodes' => $shortcodes, |
| 587 |
'styles' => $styles |
| 588 |
)); |
| 589 |
} |
| 590 |
|
| 591 |
/** |
| 592 |
* Save builder main data |
| 593 |
*/ |
| 594 |
public static function save_data_builder() { |
| 595 |
check_ajax_referer('tf_nonce', 'nonce'); |
| 596 |
if (!empty($_POST['bid'])) { |
| 597 |
// Information about a writing process. |
| 598 |
$results = array(); |
| 599 |
if (isset($_POST['data'])) { |
| 600 |
if(isset($_POST['mode']) && $_POST['mode']==='gzip'){ |
| 601 |
if(!function_exists('gzdecode')){ |
| 602 |
wp_send_json_error(__('gzdecode is disabled', 'themify')); |
| 603 |
} |
| 604 |
$data = function_exists( 'themify_safe_gzbase64_decode' ) ? themify_safe_gzbase64_decode( $_POST['data'] ) : @gzdecode( base64_decode( $_POST['data'] ) ); |
| 605 |
if ( $data === false ) { |
| 606 |
wp_send_json_error( __( 'Invalid data.', 'themify' ) ); |
| 607 |
} |
| 608 |
} |
| 609 |
else{ |
| 610 |
$data = stripslashes_deep($_POST['data']); |
| 611 |
} |
| 612 |
} |
| 613 |
elseif (isset($_FILES['data'])) { |
| 614 |
$data = file_get_contents($_FILES['data']['tmp_name']); |
| 615 |
} |
| 616 |
if (isset($data)) {//don't use empty, when builder is empty need to remove builder data |
| 617 |
$post_id = (int) $_POST['bid']; |
| 618 |
if (current_user_can('edit_post', $post_id)) { |
| 619 |
if (!empty($_POST['images'])) { |
| 620 |
if(isset($_POST['mode']) && $_POST['mode']==='gzip'){ |
| 621 |
$images = function_exists( 'themify_safe_gzbase64_decode' ) ? themify_safe_gzbase64_decode( $_POST['images'], 5242880, 7864320 ) : @gzdecode( base64_decode( $_POST['images'] ) ); |
| 622 |
if ( $images === false ) { |
| 623 |
$images = ''; |
| 624 |
} |
| 625 |
} |
| 626 |
else{ |
| 627 |
$images = stripslashes_deep($_POST['images']); |
| 628 |
} |
| 629 |
if(!empty($images)){ |
| 630 |
$images=json_decode($images,true); |
| 631 |
} |
| 632 |
if (!empty($images) && is_array($images)) { |
| 633 |
foreach ($images as $img) { |
| 634 |
$ext=strtolower(strtok(pathinfo($img,PATHINFO_EXTENSION ),'?')); |
| 635 |
if($ext==='png' || $ext==='jpg' || $ext==='jpeg' || $ext==='webp' || $ext==='gif' ||$ext==='bmp' ){ |
| 636 |
try { |
| 637 |
themify_get_image_size($img); |
| 638 |
// Use generateWebp so Performance > WebP toggle is respected |
| 639 |
themify_generateWebp($img); |
| 640 |
} catch (Throwable $e) { |
| 641 |
// Skip bad/oversized images — do not block Builder save |
| 642 |
} |
| 643 |
} |
| 644 |
} |
| 645 |
} |
| 646 |
unset($images); |
| 647 |
} |
| 648 |
$data = !empty($data) ? json_decode($data, true) : array(); |
| 649 |
if (empty($data) || !is_array($data)) { |
| 650 |
$data = array(); |
| 651 |
} |
| 652 |
Themify_Builder::$builder_is_saving = true; |
| 653 |
$custom_css = isset($_POST['custom_css']) ? $_POST['custom_css'] : null; |
| 654 |
$custom_js = isset($_POST['custom_js']) ? $_POST['custom_js'] : null; |
| 655 |
$results = ThemifyBuilder_Data_Manager::save_data($data, $post_id, $_POST['sourceEditor'], $custom_css, $custom_js); |
| 656 |
if (!empty($results['mid'])) { |
| 657 |
$data = $post_id = null; |
| 658 |
$results['builder_data'] = json_decode($results['builder_data'], true); |
| 659 |
} else { |
| 660 |
wp_send_json_error(__('Can`t Save Builder Data', 'themify')); |
| 661 |
} |
| 662 |
Themify_Builder::$builder_is_saving = false; |
| 663 |
} else { |
| 664 |
wp_send_json_error(__('You Don`t have permission to edit this post', 'themify')); |
| 665 |
} |
| 666 |
} |
| 667 |
wp_send_json_success($results); |
| 668 |
} |
| 669 |
} |
| 670 |
|
| 671 |
|
| 672 |
public static function save_builder_css() { |
| 673 |
if (!empty($_POST['bid']) && current_user_can('edit_post', (int) $_POST['bid'])) { |
| 674 |
Themify_Builder_Stylesheet::save_builder_css(true); |
| 675 |
} |
| 676 |
else { |
| 677 |
wp_send_json_error(__('You Don`t have permission to edit this post', 'themify')); |
| 678 |
} |
| 679 |
} |
| 680 |
|
| 681 |
/** |
| 682 |
* Static badge js template |
| 683 |
*/ |
| 684 |
private static function print_static_content_badge_templates():void { |
| 685 |
?> |
| 686 |
<script type="text/html" id="tmpl-tb-static-badge"> |
| 687 |
<div class="tb_static_badge_box"> |
| 688 |
<?php if (!Themify_Builder_Model::is_gutenberg_editor()): ?> |
| 689 |
<h4><?php esc_html_e('Themify Builder Placeholder', 'themify'); ?></h4> |
| 690 |
<p><?php esc_html_e('This badge represents where the Builder content will append on the frontend. You can move this placeholder anywhere within the editor or add content before or after.', 'themify'); ?></p> |
| 691 |
<p><?php echo sprintf('%s <a href="#" class="tb_mce_view_frontend_btn">%s</a> | <a href="#" class="tb_mce_view_backend_btn">%s</a>', esc_html__('Edit Builder:', 'themify'), esc_html__('Frontend', 'themify'), esc_html__('Backend', 'themify')); ?></p> |
| 692 |
<?php endif; ?> |
| 693 |
</div> |
| 694 |
</script> |
| 695 |
<?php if (Themify_Builder_Model::is_gutenberg_editor()): ?> |
| 696 |
<div style="display: none;"><?php wp_editor(' ', 'tb_lb_hidden_editor'); ?></div> |
| 697 |
<?php endif; ?> |
| 698 |
<?php |
| 699 |
} |
| 700 |
|
| 701 |
|
| 702 |
public static function update_tick() { |
| 703 |
check_ajax_referer('tf_nonce', 'nonce'); |
| 704 |
Themify_Builder::$frontedit_active = true; |
| 705 |
if (!empty($_POST['bid'])) { |
| 706 |
if ( ! self::can_edit_builder_post( $_POST['bid'] ) ) { |
| 707 |
wp_die( -1, 403 ); |
| 708 |
} |
| 709 |
if (!empty($_POST['count'])) { |
| 710 |
global $wp_roles; |
| 711 |
$roles = $wp_roles->get_names(); |
| 712 |
unset($roles['subscriber']); |
| 713 |
$users = get_users(array('role_in' => array_keys($roles), 'orderby' => 'ID', 'number' => 2, 'fields' => array('ID'))); |
| 714 |
if (count($users) < 2) { |
| 715 |
wp_die('cancel'); |
| 716 |
} |
| 717 |
} |
| 718 |
$id = (int) $_POST['bid']; |
| 719 |
$uid = Themify_Builder_Model::get_edit_transient($id); |
| 720 |
$current = get_current_user_id(); |
| 721 |
//print_r($roles); |
| 722 |
if (!$uid || $uid == $current || !empty($_POST['take'])) { |
| 723 |
Themify_Builder_Model::set_edit_transient($id, $current); |
| 724 |
} else { |
| 725 |
include( THEMIFY_BUILDER_INCLUDES_DIR . '/tpl/tmpl-locked.php' ); |
| 726 |
} |
| 727 |
} |
| 728 |
wp_die(); |
| 729 |
} |
| 730 |
|
| 731 |
public static function help():void { |
| 732 |
check_ajax_referer('tf_nonce', 'nonce'); |
| 733 |
include THEMIFY_BUILDER_INCLUDES_DIR . '/tpl/tmpl-help.php'; |
| 734 |
wp_die(); |
| 735 |
} |
| 736 |
|
| 737 |
|
| 738 |
/** |
| 739 |
* Save Module Favorite Data |
| 740 |
* |
| 741 |
* @return void |
| 742 |
*/ |
| 743 |
public static function save_module_favorite_data() { |
| 744 |
check_ajax_referer('tf_nonce', 'nonce'); |
| 745 |
if (isset($_POST['module_state'], $_POST['module_name'])) { |
| 746 |
$module = $_POST['module_name']; |
| 747 |
$module_state = (int) $_POST['module_state']; |
| 748 |
$user_id = get_current_user_id(); |
| 749 |
$key = 'themify_module_favorite'; |
| 750 |
$user_favorite_modules = Themify_Builder_Model::get_favorite_modules(); |
| 751 |
if ($module_state === 1) { |
| 752 |
$user_favorite_modules[] = $module; |
| 753 |
$user_favorite_modules = array_keys(array_flip($user_favorite_modules)); |
| 754 |
} elseif (!empty($user_favorite_modules)) { |
| 755 |
$index = array_search($module, $user_favorite_modules); |
| 756 |
if ($index !== false) { |
| 757 |
array_splice($user_favorite_modules, $index, 1); |
| 758 |
} |
| 759 |
} |
| 760 |
if (!empty($user_favorite_modules)) { |
| 761 |
update_user_option($user_id, $key, json_encode($user_favorite_modules)); |
| 762 |
} else { |
| 763 |
delete_user_option($user_id, $key); |
| 764 |
} |
| 765 |
} |
| 766 |
die('1'); |
| 767 |
} |
| 768 |
|
| 769 |
public static function get_ajax_post_types() { |
| 770 |
check_ajax_referer('tf_nonce', 'nonce'); |
| 771 |
if (isset($_POST['type'])) { |
| 772 |
$result = array(); |
| 773 |
$post_types = false; |
| 774 |
if ($_POST['type'] === 'post_types') { |
| 775 |
if (!empty($_POST['all']) && 'true' === $_POST['all']) { |
| 776 |
$result['any'] = array('name' => __('All', 'themify'), 'options' => ''); |
| 777 |
} |
| 778 |
$taxes = Themify_Builder_Model::get_public_taxonomies(); |
| 779 |
$post_types = Themify_Builder_Model::get_public_post_types(); |
| 780 |
foreach ($post_types as $k => $v) { |
| 781 |
$result[$k] = array('name' => $v); |
| 782 |
$post_type_tax = get_object_taxonomies($k); |
| 783 |
foreach ($post_type_tax as $t) { |
| 784 |
if (isset($taxes[$t])) { |
| 785 |
if (!isset($result[$k]['options'])) { |
| 786 |
$result[$k]['options'] = array(); |
| 787 |
} |
| 788 |
$result[$k]['options'][$t] = array('name' => $taxes[$t]); |
| 789 |
} |
| 790 |
} |
| 791 |
} |
| 792 |
|
| 793 |
/* WooCommerce, ensure Product Category is the default */ |
| 794 |
if (!empty($result['product']['options']['product_cat'])) { |
| 795 |
$result['product']['options'] = array_merge( |
| 796 |
['product_cat' => $result['product']['options']['product_cat']], |
| 797 |
array_diff_key($result['product']['options'], ['product_cat' => null]) |
| 798 |
); |
| 799 |
} |
| 800 |
|
| 801 |
unset($taxes, $exclude); |
| 802 |
} |
| 803 |
elseif ($_POST['type'] === 'terms' && !empty($_POST['v'])) { |
| 804 |
$tax = get_taxonomy($_POST['v']); |
| 805 |
if(!empty($tax)){ |
| 806 |
$args = array( |
| 807 |
'hide_empty' => true, |
| 808 |
'no_found_rows' => true, |
| 809 |
'orderby' => 'name', |
| 810 |
'order' => 'ASC', |
| 811 |
'taxonomy' => $tax->name |
| 812 |
); |
| 813 |
if (!empty($_POST['s'])) { |
| 814 |
$args['name__like'] = sanitize_text_field($_POST['s']); |
| 815 |
} else { |
| 816 |
$args['number'] = 50; |
| 817 |
} |
| 818 |
$terms_by_tax = get_terms($args); |
| 819 |
unset($args); |
| 820 |
$result['0'] = $tax->labels->all_items; |
| 821 |
foreach ($terms_by_tax as $v) { |
| 822 |
$result[$v->slug] = $v->name; |
| 823 |
} |
| 824 |
unset($tax); |
| 825 |
} |
| 826 |
} |
| 827 |
wp_send_json(apply_filters('themify_builder_query_post', $result, $_POST['type'], $post_types)); |
| 828 |
} |
| 829 |
wp_die(); |
| 830 |
} |
| 831 |
|
| 832 |
public static function set_fullwidth(): void { |
| 833 |
check_ajax_referer( 'tf_nonce', 'nonce' ); |
| 834 |
$bid = ! empty( $_POST['bid'] ) ? (int) $_POST['bid'] : 0; |
| 835 |
if ( ! $bid || ! current_user_can( 'edit_post', $bid ) || get_post_type( $bid ) !== 'page' ) { |
| 836 |
wp_send_json_error( 'invalid' ); |
| 837 |
} |
| 838 |
update_post_meta( $bid, 'content_width', 'full_width' ); |
| 839 |
if ( themify_is_themify_theme() ) { |
| 840 |
update_post_meta( $bid, 'page_layout', 'full_width' ); |
| 841 |
update_post_meta( $bid, 'hide_page_title', 'yes' ); |
| 842 |
} |
| 843 |
wp_send_json_success(); |
| 844 |
} |
| 845 |
|
| 846 |
|
| 847 |
/** |
| 848 |
* Get all posts from all post type that has builder data as post meta |
| 849 |
* @return array posts id |
| 850 |
* @since 4.1.2 |
| 851 |
*/ |
| 852 |
public static function get_ajax_builder_posts() { |
| 853 |
check_ajax_referer('tf_nonce', 'nonce'); |
| 854 |
if (current_user_can('edit_pages')) { |
| 855 |
$result = array(); |
| 856 |
$page = !empty($_POST['page']) ? (int) $_POST['page'] : 1; |
| 857 |
$limit = 8; |
| 858 |
$args = array( |
| 859 |
'post_type' => get_post_types(), |
| 860 |
'posts_per_page' => $limit, |
| 861 |
'fields' => 'ids', |
| 862 |
'post_status' => 'any', |
| 863 |
'paged' => $page, |
| 864 |
'order' => 'ASC', |
| 865 |
'orderby' => 'ID', |
| 866 |
'update_post_term_cache' => false, |
| 867 |
'ignore_sticky_posts' => true, |
| 868 |
'update_post_meta_cache' => false, |
| 869 |
'lazy_load_term_meta' => false, |
| 870 |
'cache_results' => false, |
| 871 |
/* WPML, Polylang, etc. can filter WP_Query by current language; URL replace must scan all translations. */ |
| 872 |
'suppress_filters' => apply_filters( 'themify_builder_url_replace_suppress_query_filters', true ), |
| 873 |
'meta_query' => array( |
| 874 |
'relation' => 'OR', |
| 875 |
array( |
| 876 |
'key' => ThemifyBuilder_Data_Manager::META_KEY, |
| 877 |
'compare' => 'EXISTS', |
| 878 |
), |
| 879 |
array( |
| 880 |
'key' => ThemifyBuilder_Data_Manager::LEGACY_META_KEY, |
| 881 |
'compare' => 'EXISTS', |
| 882 |
), |
| 883 |
), |
| 884 |
); |
| 885 |
if ( function_exists( 'pll_languages_list' ) || function_exists( 'pll_current_language' ) ) { |
| 886 |
/* Polylang: empty lang disables the current-language filter. */ |
| 887 |
$args['lang'] = ''; |
| 888 |
} |
| 889 |
$query = new WP_Query($args); |
| 890 |
if ($page === 1) { |
| 891 |
$result['pages'] = $query->max_num_pages; |
| 892 |
$result['total'] = $query->found_posts; |
| 893 |
$result['labels'] = array( |
| 894 |
'same_url' => __('Same Url', 'themify'), |
| 895 |
'searching' => __('Searching "%find%" in posts(%count%/%total%): %posts%', 'themify'), |
| 896 |
'found' => __('Found "%find%" in posts(%count%): %posts%', 'themify'), |
| 897 |
'saving' => __('Saving posts(%count%/%total%): %posts%', 'themify'), |
| 898 |
'no_found' => __('There is no builder containing "%find%"', 'themify'), |
| 899 |
'error' => __('There are some errors: %posts%', 'themify'), |
| 900 |
'wrong_url' => __('Please type url', 'themify'), |
| 901 |
'done' => __('Done', 'themify') |
| 902 |
); |
| 903 |
} |
| 904 |
if (!empty($query->posts)) { |
| 905 |
foreach ($query->posts as $id) { |
| 906 |
$result['posts'][] = array('data' => ThemifyBuilder_Data_Manager::get_data($id), 'title' => get_the_title($id), 'id' => $id); |
| 907 |
} |
| 908 |
} |
| 909 |
wp_send_json_success($result); |
| 910 |
} else { |
| 911 |
wp_send_json_error(__('You Don`t have permission to edit pages', 'themify')); |
| 912 |
} |
| 913 |
wp_send_json_error(); |
| 914 |
} |
| 915 |
|
| 916 |
|
| 917 |
|
| 918 |
|
| 919 |
/** |
| 920 |
* Handles Ajax request to get dynamic values |
| 921 |
* |
| 922 |
* Calls "tb_select_dataset_{$dataset}" filter |
| 923 |
* |
| 924 |
* @since 4.6.5 |
| 925 |
*/ |
| 926 |
public static function get_ajax_data() { |
| 927 |
check_ajax_referer('tf_nonce', 'nonce'); |
| 928 |
if ( ! self::can_edit_builder_post( $_POST['bid'] ?? 0 ) ) { |
| 929 |
wp_send_json_error(); |
| 930 |
} |
| 931 |
if (empty($_POST['dataset']) && empty($_POST['mode'])) { |
| 932 |
wp_send_json_error(); |
| 933 |
} |
| 934 |
$pid = (int) $_POST['bid']; |
| 935 |
$dataset = isset($_POST['dataset']) ? sanitize_text_field($_POST['dataset']) : ''; |
| 936 |
$mode = isset($_POST['mode']) ? $_POST['mode'] : null; |
| 937 |
|
| 938 |
if ($dataset === 'taxonomy') { |
| 939 |
$post_type = ''; |
| 940 |
if (!empty($_POST['args']['post_type'])) { |
| 941 |
$post_type = sanitize_key(wp_unslash($_POST['args']['post_type'])); |
| 942 |
} |
| 943 |
$result = $post_type !== '' |
| 944 |
? Themify_Builder_Model::get_public_taxonomies_for_post_type($post_type) |
| 945 |
: Themify_Builder_Model::get_public_taxonomies(); |
| 946 |
} |
| 947 |
elseif ($dataset === 'post_type') { |
| 948 |
$result =Themify_Builder_Model::get_public_post_types(); |
| 949 |
} |
| 950 |
elseif ($dataset === 'menu') { |
| 951 |
$menu = get_terms(array('taxonomy' => 'nav_menu', 'hide_empty' => false)); |
| 952 |
$result = array('' => __('Select a Menu...', 'themify')); |
| 953 |
foreach ($menu as $m) { |
| 954 |
$result[$m->slug] = $m->name; |
| 955 |
} |
| 956 |
unset($menu); |
| 957 |
} |
| 958 |
elseif ($dataset === 'gallery_shortcode') { |
| 959 |
if (empty($_POST['val'])) { |
| 960 |
wp_send_json_error(); |
| 961 |
} |
| 962 |
$raw = isset($_POST['val']) ? wp_unslash($_POST['val']) : ''; |
| 963 |
$images = themify_get_gallery_shortcode(sanitize_textarea_field($raw)); |
| 964 |
$result = array(); |
| 965 |
if (!empty($images)) { |
| 966 |
foreach ($images as $image) { |
| 967 |
$full=wp_get_attachment_image_src($image->ID, 'full'); |
| 968 |
$large=wp_get_attachment_image_src($image->ID, 'large'); |
| 969 |
$thumb=wp_get_attachment_image_src($image->ID, 'thumbnail'); |
| 970 |
$link=wp_get_attachment_url($image->ID); |
| 971 |
$arr=[ |
| 972 |
'id' => $image->ID |
| 973 |
]; |
| 974 |
if(!empty($large)){ |
| 975 |
array_pop($large); |
| 976 |
$arr['large']=$large; |
| 977 |
} |
| 978 |
if(!empty($full)){ |
| 979 |
array_pop($full); |
| 980 |
$arr['full']=$full; |
| 981 |
} |
| 982 |
if(!empty($thumb)){ |
| 983 |
$arr['thumbnail']=$thumb[0]; |
| 984 |
} |
| 985 |
if(!empty($image->post_excerpt)){ |
| 986 |
$arr['caption']=wp_get_attachment_caption($image->ID); |
| 987 |
} |
| 988 |
if(!empty($image->post_title)){ |
| 989 |
$arr['title']=$image->post_title; |
| 990 |
} |
| 991 |
if(!empty($link)){ |
| 992 |
$arr['link']=$link; |
| 993 |
} |
| 994 |
$result[] = $arr; |
| 995 |
} |
| 996 |
} |
| 997 |
unset($images); |
| 998 |
} |
| 999 |
elseif ($dataset === 'attachment_meta_by_url') { |
| 1000 |
$url = isset($_POST['val']) ? esc_url_raw(wp_unslash($_POST['val'])) : ''; |
| 1001 |
if ($url === '') { |
| 1002 |
$result = array( |
| 1003 |
'title' => '', |
| 1004 |
'caption' => '', |
| 1005 |
'alt' => '', |
| 1006 |
); |
| 1007 |
} else { |
| 1008 |
$attachment_id = attachment_url_to_postid($url); |
| 1009 |
if ($attachment_id) { |
| 1010 |
$result = array( |
| 1011 |
'title' => get_the_title($attachment_id), |
| 1012 |
'caption' => (string) wp_get_attachment_caption($attachment_id), |
| 1013 |
'alt' => (string) get_post_meta($attachment_id, '_wp_attachment_image_alt', true), |
| 1014 |
); |
| 1015 |
} else { |
| 1016 |
$result = array( |
| 1017 |
'title' => '', |
| 1018 |
'caption' => '', |
| 1019 |
'alt' => '', |
| 1020 |
); |
| 1021 |
} |
| 1022 |
} |
| 1023 |
} |
| 1024 |
elseif ($mode === 'autocomplete') { |
| 1025 |
if (empty($_POST['value'])) { |
| 1026 |
wp_send_json_error(); |
| 1027 |
} |
| 1028 |
$value = sanitize_text_field($_POST['value']); |
| 1029 |
if ($dataset === 'authors') { |
| 1030 |
$users = get_users(array( |
| 1031 |
'search' => '*' . $value . '*', |
| 1032 |
'number' => 50, |
| 1033 |
'search_columns' => ['user_login'], |
| 1034 |
'fields' => ['user_login'], |
| 1035 |
)); |
| 1036 |
$logins = wp_list_pluck($users, 'user_login'); |
| 1037 |
$result = array_combine($logins, $logins); |
| 1038 |
} elseif ($dataset === 'custom_fields') { |
| 1039 |
global $wpdb; |
| 1040 |
$arr = $wpdb->get_results( |
| 1041 |
$wpdb->prepare( |
| 1042 |
"SELECT DISTINCT BINARY meta_key FROM {$wpdb->prefix}postmeta WHERE meta_key like %s LIMIT 50", |
| 1043 |
esc_sql($value) . '%' |
| 1044 |
), |
| 1045 |
OBJECT); |
| 1046 |
$result = wp_list_pluck($arr, 'BINARY meta_key', 'BINARY meta_key'); |
| 1047 |
} elseif ($dataset !== '') { |
| 1048 |
$result = apply_filters("tb_autocomplete_dataset_{$dataset}", array(), $value, $pid); |
| 1049 |
} |
| 1050 |
} |
| 1051 |
else { |
| 1052 |
$result = apply_filters("tb_select_dataset_{$dataset}", array(), $pid); |
| 1053 |
} |
| 1054 |
/** |
| 1055 |
* The return value should be in the format of: |
| 1056 |
* |
| 1057 |
* array( |
| 1058 |
* 'options' => array( |
| 1059 |
* {value} => {label}, |
| 1060 |
* ) |
| 1061 |
* ) |
| 1062 |
* |
| 1063 |
* Or for select fields with multiple groups: |
| 1064 |
* |
| 1065 |
* array( |
| 1066 |
* 'optgroup' => true, |
| 1067 |
* 'options' => array( |
| 1068 |
* {group_key} => array( |
| 1069 |
* 'label' => {group_label}, |
| 1070 |
* 'options' => array( |
| 1071 |
* {option_value} => {option_label}, |
| 1072 |
* ) |
| 1073 |
* ), |
| 1074 |
* ) |
| 1075 |
* ) |
| 1076 |
* |
| 1077 |
*/ |
| 1078 |
wp_send_json_success($result); |
| 1079 |
} |
| 1080 |
|
| 1081 |
public static function ajax_validate_captcha() { |
| 1082 |
check_ajax_referer( 'tf_nonce', 'nonce' ); |
| 1083 |
$keys = Themify_Builder_Model::get_captcha_keys( $_POST['provider'] ); |
| 1084 |
if ( ! empty( $keys['public'] ) && ! empty( $keys['private'] ) ) { |
| 1085 |
wp_send_json_success(); |
| 1086 |
} |
| 1087 |
|
| 1088 |
wp_send_json_error( sprintf( __('Requires Captcha keys entered at: <a target="_blank" href="%s">Integration API</a>.', 'themify'), admin_url('admin.php?page=themify#setting-integration-api') ) ); |
| 1089 |
} |
| 1090 |
|
| 1091 |
|
| 1092 |
/** |
| 1093 |
* Display Toggle themify builder |
| 1094 |
* wp admin bar |
| 1095 |
*/ |
| 1096 |
public static function builder_admin_bar_menu($wp_admin_bar):void { |
| 1097 |
if (is_admin_bar_showing()) { |
| 1098 |
$post_id = Themify_Builder::builder_is_available(); |
| 1099 |
$isAvailable = $post_id !== null; |
| 1100 |
$args = array( |
| 1101 |
array( |
| 1102 |
'id' => 'themify_builder', |
| 1103 |
'title' => '', |
| 1104 |
'href' => '#', |
| 1105 |
'meta' => array( |
| 1106 |
'class' => 'toggle_tb_builder', |
| 1107 |
'onclick' => 'javascript:;' |
| 1108 |
) |
| 1109 |
) |
| 1110 |
); |
| 1111 |
$args = apply_filters('themify_builder_admin_bar_menu', $args, $isAvailable); |
| 1112 |
if ($isAvailable === false) { |
| 1113 |
if (isset($args[1])) { |
| 1114 |
foreach ($args as $b) { |
| 1115 |
if (isset($b['id']) && is_numeric($b['id'])) { |
| 1116 |
$post_id = $b['id']; |
| 1117 |
break; |
| 1118 |
} |
| 1119 |
} |
| 1120 |
} |
| 1121 |
if (!$post_id) { |
| 1122 |
$args[0]['meta']['class'] .= ' tb_disabled_turn_on'; |
| 1123 |
} |
| 1124 |
} |
| 1125 |
$args[0]['title'] = '<span data-id="' . ($post_id ? $post_id : '') . '" class="tb_front_icon">' . themify_get_icon('ti-themify-favicon-alt', 'ti', false, false, array('style' => 'width:18px;height:18px;color:#ffcc08')) . '</span>'; |
| 1126 |
$args[0]['title'] .= '<span class="tb_tooltip tf_hide">' . __('Builder is not available on this page', 'themify') . '</span>' . esc_html__('Turn On Builder', 'themify'); |
| 1127 |
foreach ($args as $arg) { |
| 1128 |
$wp_admin_bar->add_node($arg); |
| 1129 |
} |
| 1130 |
} |
| 1131 |
} |
| 1132 |
|
| 1133 |
/** |
| 1134 |
* Load JS and CSs for async loader. |
| 1135 |
* |
| 1136 |
* @since 2.1.9 |
| 1137 |
*/ |
| 1138 |
public static function async_footer():void { |
| 1139 |
wp_deregister_script('wp-embed'); |
| 1140 |
$editorUrl = THEMIFY_BUILDER_URI . '/css/editor/'; |
| 1141 |
themify_enque_style('themify-builder-loader', $editorUrl . 'themify-builder-loader.css', array(), THEMIFY_VERSION, 'all', true); |
| 1142 |
themify_enque_script( 'themify-builder-loader', THEMIFY_BUILDER_URI . '/js/editor/frontend/themify-builder-loader.js', THEMIFY_VERSION, [] ); |
| 1143 |
|
| 1144 |
$st = array( |
| 1145 |
THEMIFY_URI . '/css/base.min.css', |
| 1146 |
$editorUrl . 'workspace.css', |
| 1147 |
$editorUrl . 'components/lightbox.css' |
| 1148 |
); |
| 1149 |
$styles = array(); |
| 1150 |
foreach ($st as $s) { |
| 1151 |
$styles[$s] = THEMIFY_VERSION; |
| 1152 |
} |
| 1153 |
$st = null; |
| 1154 |
wp_localize_script('themify-builder-loader', 'tbLoaderVars', array( |
| 1155 |
'styles' => apply_filters('themify_styles_top_frame', array_reverse($styles)), |
| 1156 |
'turnOnBuilder' => __('Turn On Builder', 'themify'), |
| 1157 |
'turnOnLpBuilder' => __('Edit Layout Part', 'themify'), |
| 1158 |
'editTemplate' => __('Edit Template', 'themify'), |
| 1159 |
'isGlobalStylePost' => Themify_Global_Styles::$isGlobalEditPage |
| 1160 |
)); |
| 1161 |
$styles = null; |
| 1162 |
} |
| 1163 |
|
| 1164 |
public static function tb_get_pages():void { |
| 1165 |
check_ajax_referer('tf_nonce', 'nonce'); |
| 1166 |
if ( ! empty( $_POST['bid'] ) && current_user_can( 'edit_post', $_POST['bid'] ) ) { |
| 1167 |
$data = '<div class="tb_import_result">'; |
| 1168 |
$page = ! empty( $_POST['page'] ) ? (int) $_POST['page'] : 1; |
| 1169 |
$limit = 20; |
| 1170 |
$args = array( |
| 1171 |
'fields' => 'ids', |
| 1172 |
'post_type' => array_keys( Themify_Builder_Model::get_public_post_types() + [ 'page' => 0 ] ), |
| 1173 |
'post_status' => 'publish', |
| 1174 |
'posts_per_page' => $limit, |
| 1175 |
'paged' => $page, |
| 1176 |
'ignore_sticky_posts' => true, |
| 1177 |
'cache_results' => false, |
| 1178 |
'update_post_meta_cache' => false, |
| 1179 |
'update_post_term_cache' => false, |
| 1180 |
'lazy_load_term_meta' => false, |
| 1181 |
'orderby' => 'none', |
| 1182 |
'order' => 'DESC' |
| 1183 |
); |
| 1184 |
if ( ! empty( $_POST['s'] ) ) { |
| 1185 |
$args['s'] = sanitize_text_field( $_POST['s'] ); |
| 1186 |
} |
| 1187 |
$query = new WP_Query( $args ); |
| 1188 |
if ( $query->have_posts() ) { |
| 1189 |
$data .= '<ul>'; |
| 1190 |
while ( $query->have_posts() ) { |
| 1191 |
$query->the_post(); |
| 1192 |
$post_type_object = get_post_type_object( get_post_type() ); |
| 1193 |
$data .= '<li><a href="#" data-id="' . esc_attr( get_the_ID() ) . '" data-permalink="' . esc_url( get_permalink( get_the_ID() ) ) . '">' . esc_html( get_the_title() ) . '<span>' . esc_html( $post_type_object->labels->singular_name ) . '</span></a></li>'; |
| 1194 |
} |
| 1195 |
$data .= '</ul>'; |
| 1196 |
$data .= '<div class="tb_pagination tf_textc">' . paginate_links( array( |
| 1197 |
'base' => '', |
| 1198 |
'format' => '?', |
| 1199 |
'total' => ceil( $query->found_posts / $limit ), |
| 1200 |
'current' => $page, |
| 1201 |
'prev_next' => false |
| 1202 |
) ) . '</div>'; |
| 1203 |
} |
| 1204 |
$data .= '</div>'; |
| 1205 |
|
| 1206 |
die($data); |
| 1207 |
} |
| 1208 |
wp_die(); |
| 1209 |
} |
| 1210 |
} |
| 1211 |
Themify_Builder_Active::init(); |
| 1212 |
|
| 1213 |
|