PluginProbe
Page Builder: Pagelayer – Drag and Drop website builder / 2.2.0
Page Builder: Pagelayer – Drag and Drop website builder v2.2.0
2.2.1 2.2.0 2.1.9 2.1.8 2.1.7 2.1.6 2.1.5 2.1.4 2.1.3 trunk 0.9.0 0.9.1 0.9.2 0.9.3 0.9.4 0.9.5 0.9.6 0.9.7 0.9.8 0.9.9 1.0.0 1.0.2 1.0.3 1.0.4 1.0.5 All 129 releases
← All changes | init.php +1733 -593 0.9.12.2.0 View file →
@@ -1,593 +1,1733 @@
1 -<?php
2 -
3 -// We need the ABSPATH
4 -if (!defined('ABSPATH')) exit;
5 -
6 -define('PAGELAYER_BASE', plugin_basename(__FILE__));
7 -define('PAGELAYER_FILE', __FILE__);
8 -define('PAGELAYER_VERSION', '0.9.1');
9 -define('PAGELAYER_DIR', WP_PLUGIN_DIR.'/'.basename(dirname(PAGELAYER_FILE)));
10 -define('PAGELAYER_SLUG', 'pagelayer');
11 -define('PAGELAYER_URL', plugins_url('', PAGELAYER_FILE));
12 -define('PAGELAYER_CSS', PAGELAYER_URL.'/css');
13 -define('PAGELAYER_JS', PAGELAYER_URL.'/js');
14 -define('PAGELAYER_PRO_URL', 'https://pagelayer.com/features#compare');
15 -define('PAGELAYER_DOCS', 'https://pagelayer.com/docs/');
16 -define('PAGELAYER_API', 'https://api.pagelayer.com/');
17 -define('PAGELAYER_SC_PREFIX', 'pl');
18 -define('PAGELAYER_YOUTUBE_BG', 'https://www.youtube.com/watch?v=Csa6rvCWmLU');
19 -
20 -include_once(PAGELAYER_DIR.'/main/functions.php');
21 -include_once(PAGELAYER_DIR.'/main/class.php');
22 -
23 -// Ok so we are now ready to go
24 -register_activation_hook(PAGELAYER_FILE, 'pagelayer_activation');
25 -
26 -// Is called when the ADMIN enables the plugin
27 -function pagelayer_activation(){
28 -
29 - global $wpdb;
30 -
31 - $sql = array();
32 -
33 - /*$sql[] = "DROP TABLE IF EXISTS `".$wpdb->prefix."pagelayer_logs`";
34 -
35 - foreach($sql as $sk => $sv){
36 - $wpdb->query($sv);
37 - }*/
38 -
39 - add_option('pagelayer_version', PAGELAYER_VERSION);
40 - add_option('pagelayer_options', array());
41 -
42 -}
43 -
44 -// Checks if we are to update ?
45 -function pagelayer_update_check(){
46 -
47 -global $wpdb;
48 -
49 - $sql = array();
50 - $current_version = get_option('pagelayer_version');
51 - $version = (int) str_replace('.', '', $current_version);
52 -
53 - // No update required
54 - if($current_version == PAGELAYER_VERSION){
55 - return true;
56 - }
57 -
58 - // Is it first run ?
59 - if(empty($current_version)){
60 -
61 - // Reinstall
62 - pagelayer_activation();
63 -
64 - // Trick the following if conditions to not run
65 - $version = (int) str_replace('.', '', PAGELAYER_VERSION);
66 -
67 - }
68 -
69 - // Save the new Version
70 - update_option('pagelayer_version', PAGELAYER_VERSION);
71 -
72 -}
73 -
74 -// Add the action to load the plugin
75 -add_action('plugins_loaded', 'pagelayer_load_plugin');
76 -
77 -// The function that will be called when the plugin is loaded
78 -function pagelayer_load_plugin(){
79 -
80 - global $pagelayer;
81 -
82 - // Check if the installed version is outdated
83 - pagelayer_update_check();
84 -
85 - // Set the array
86 - $pagelayer = new PageLayer();
87 -
88 - // Is there any ACTION set ?
89 - $pagelayer->action = pagelayer_optreq('pagelayer-action');
90 -
91 - // Load settings
92 - $options = get_option('pagelayer_options');
93 - $pagelayer->settings['post_types'] = empty($options['post_types']) ? array('post', 'page') : $options['post_types'];
94 - $pagelayer->settings['css_code'] = empty($options['css_code']) ? '' : $options['css_code'];
95 - $pagelayer->settings['animate'] = empty($options['animate']) ? '' : $options['animate'];
96 - $pagelayer->settings['max_width'] = empty($options['max_width']) ? 1170 : $options['max_width'];
97 -
98 - // Load the language
99 - load_plugin_textdomain('pagelayer', false, PAGELAYER_SLUG.'/languages/');
100 -
101 -}
102 -
103 -// This adds the left menu in WordPress Admin page
104 -add_action('admin_menu', 'pagelayer_admin_menu');
105 -
106 -// Shows the admin menu of Pagelayer
107 -function pagelayer_admin_menu() {
108 -
109 - global $wp_version, $pagelayer;
110 -
111 - $capability = 'activate_plugins';// TODO : Capability for accessing this page
112 -
113 - // Add the menu page
114 - add_menu_page(__('PageLayer Editor'), __('PageLayer'), $capability, 'pagelayer', 'pagelayer_page_handler', PAGELAYER_URL.'/images/pagelayer-logo-19.png');
115 -
116 - // Settings Page
117 - add_submenu_page('pagelayer', __('PageLayer Editor'), __('Settings'), $capability, 'pagelayer', 'pagelayer_page_handler');
118 -
119 - // Its premium
120 - if(defined('PAGELAYER_PREMIUM')){
121 -
122 - // Fonts link
123 - add_submenu_page('pagelayer', __('PageLayer Font Settings'), __('PageLayer Font Settings'), $capability, 'pagelayer_fonts', 'pagelayer_page_fonts');
124 -
125 - // Its free
126 - }else{
127 -
128 - // Go Pro link
129 - add_submenu_page('pagelayer', __('PageLayer Go Pro'), __('Go Pro'), $capability, PAGELAYER_PRO_URL);
130 -
131 - }
132 -
133 -}
134 -
135 -// This function will handle the pages in Pages in PageLayer
136 -function pagelayer_page_handler(){
137 -
138 - global $wp_version, $pagelayer;
139 -
140 - include_once(PAGELAYER_DIR.'/main/settings.php');
141 -
142 - // Handle fonts
143 - if($pagelayer->action == 'fonts-manager'){
144 - include_once(PAGELAYER_DIR.'/main/fonts.php');
145 - }
146 -
147 -}
148 -
149 -// Enqueue JS and CSS in Admin Panel for settings
150 -add_action( 'admin_enqueue_scripts', 'pagelayer_admin_script' );
151 -function pagelayer_admin_script() {
152 - wp_enqueue_script( 'pagelayer-admin', PAGELAYER_JS.'/pagelayer-admin.js', array('jquery'), PAGELAYER_VERSION);
153 - wp_enqueue_style( 'pagelayer-admin', PAGELAYER_CSS.'/pagelayer-admin.css', array(), PAGELAYER_VERSION);
154 -}
155 -
156 -// Load the Live Body
157 -add_action('template_redirect', 'pagelayer_load_live_body', 4);
158 -
159 -function pagelayer_load_live_body(){
160 -
161 - global $post;
162 -
163 - // If its not live editing then stop
164 - if(!pagelayer_is_live()){
165 - return;
166 - }
167 -
168 - // If its the iFRAME then return
169 - if(pagelayer_is_live_iframe()){
170 - return;
171 - }
172 -
173 - // Are you allowed to edit ?
174 - if(!pagelayer_user_can_edit()){
175 - return;
176 - }
177 -
178 - // Load the editor live body
179 - include_once(PAGELAYER_DIR.'/main/live-body.php');
180 -
181 - pagelayer_live_body();
182 -
183 -}
184 -
185 -// Add the JS and CSS for Posts and Pages when being viewed ONLY if there is our content called
186 -add_action('template_redirect', 'pagelayer_enqueue_frontend', 5);
187 -
188 -function pagelayer_enqueue_frontend($force = false){
189 -
190 - global $post, $pagelayer;
191 -
192 - if(!empty($pagelayer->cache['enqueue_frontend'])){
193 - return;
194 - }
195 -
196 - if(empty($post->ID)){
197 - return;
198 - }
199 -
200 - // Enqueue the FRONTEND CSS
201 - if(get_post_meta($post->ID , 'pagelayer-data') || $force){
202 -
203 - // We dont need the auto <p> and <br> as they interfere with us
204 - remove_filter('the_content', 'wpautop');
205 -
206 - // No need to add curly codes to the content
207 - remove_filter('the_content', 'wptexturize');
208 -
209 - pagelayer_load_shortcodes();
210 - $pagelayer->cache['enqueue_frontend'] = true;
211 -
212 - // Enqueue our Editor's Frontend JS
213 - wp_register_script('pagelayer-frontend', PAGELAYER_JS.'/givejs.php?give=pagelayer-frontend.js,nivo-lightbox.min.js,slippry.min.js,wow.min.js,jquery-numerator.js,simpleParallax.min.js', array('jquery'), PAGELAYER_VERSION);
214 - wp_enqueue_script('pagelayer-frontend');
215 -
216 - wp_register_style('pagelayer-frontend', PAGELAYER_CSS.'/givecss.php?give=pagelayer-frontend.css,nivo-lightbox.css,slippry.css,animate.min.css', array(), PAGELAYER_VERSION);
217 - wp_enqueue_style('pagelayer-frontend');
218 -
219 - wp_register_style('font-awesome', PAGELAYER_CSS.'/font-awesome.min.css', array(), PAGELAYER_VERSION);
220 - wp_enqueue_style('font-awesome');
221 -
222 - // Load the global styles
223 - add_action('wp_head', 'pagelayer_global_styles', 5);
224 -
225 - }
226 -
227 -}
228 -
229 -// Load the google fonts
230 -add_action('wp_footer', 'pagelayer_enqueue_fonts', 5);
231 -
232 -function pagelayer_enqueue_fonts(){
233 - global $pagelayer;
234 -
235 - if(empty($pagelayer->cache['enqueue_frontend'])){
236 - return;
237 - }
238 -
239 - $url = 'Open Sans:300italic,400italic,600italic,300,400,600&subset=latin,latin-ext';
240 - //pagelayer_print($pagelayer->runtime_fonts);die('alpesh');
241 -
242 - foreach($pagelayer->runtime_fonts as $font){
243 - $url .= '|'.$font.':100,100i,200,200i,300,300i,400,400i,500,500i,600,600i,700,700i,800,800i,900,900i';
244 - }
245 -
246 - //echo '<link href="https://fonts.googleapis.com/css?family='.$url.'" rel="stylesheet">';
247 -
248 - wp_register_style('pagelayer-google-font', 'https://fonts.googleapis.com/css?family='.rawurlencode($url), array(), PAGELAYER_VERSION);
249 - wp_enqueue_style('pagelayer-google-font');
250 -
251 -}
252 -
253 -// We need to handle global styles
254 -function pagelayer_global_styles(){
255 -
256 - $styles = '<style id="pagelayer-global-styles" type="text/css">';
257 - if(get_option('pagelayer_content_width')){
258 - $styles .= '.pagelayer-row-holder{ max-width: '.get_option('pagelayer_content_width').'px;}';
259 - }else{
260 - $styles .= '.pagelayer-row-holder{ max-width: 1170px;}';
261 - }
262 - $styles .= '.pagelayer-row-holder{ margin-left: auto; margin-right: auto;}';
263 - $styles .= '</style>';
264 -
265 - echo $styles;
266 -}
267 -
268 -// Load the live editor if needed
269 -add_action('wp_enqueue_scripts', 'pagelayer_load_live', 9999);
270 -
271 -function pagelayer_load_live(){
272 -
273 - global $post;
274 -
275 - // If its not live editing then stop
276 - if(!pagelayer_is_live_iframe()){
277 - return;
278 - }
279 -
280 - // Are you allowed to edit ?
281 - if(!pagelayer_user_can_edit()){
282 - return;
283 - }
284 -
285 - // Load the editor class
286 - include_once(PAGELAYER_DIR.'/main/live.php');
287 -
288 - // Call the constructor
289 - $pl_editor = new PageLayer_LiveEditor();
290 -
291 -}
292 -
293 -// Show the backend editor options
294 -add_action('edit_form_after_title', 'pagelayer_after_title');
295 -function pagelayer_after_title(){
296 -
297 - global $post;
298 -
299 - // Get the current screen
300 - $current_screen = get_current_screen();
301 -
302 - // For gutenberg
303 - if(method_exists($current_screen, 'is_block_editor') && $current_screen->is_block_editor()){
304 -
305 - // Add the code in the footer
306 - add_action('admin_footer', 'pagelayer_gutenberg_after_title');
307 -
308 - return;
309 - }
310 -
311 - $link = pagelayer_shortlink($post->ID).'&pagelayer-live=1';
312 -
313 - echo '
314 -<div id="pagelayer-editor-button-row" style="margin-top:15px">
315 - <a id="pagelayer-editor-button" href="'.$link.'" class="button button-primary button-large" style="height:auto; padding:6px; font-size:18px;">
316 - <img src="'.PAGELAYER_URL.'/images/pagelayer-logo-40.png" align="top" width="24" /> <span>'.__('Edit with PageLayer').'</span>
317 - </a>
318 -</div>';
319 -
320 -}
321 -
322 -function pagelayer_gutenberg_after_title(){
323 -
324 - global $post;
325 -
326 - $link = pagelayer_shortlink($post->ID).'&pagelayer-live=1';
327 -
328 - echo '
329 -<div id="pagelayer-editor-button-row" style="margin-left:15px; display:none">
330 - <a id="pagelayer-editor-button" href="'.$link.'" class="button button-primary button-large" style="height:auto; padding:6px; font-size:18px;">
331 - <img src="'.PAGELAYER_URL.'/images/pagelayer-logo-40.png" align="top" width="24" /> <span>'.__('Edit with PageLayer').'</span>
332 - </a>
333 -</div>
334 -
335 -<script type="text/javascript">
336 -jQuery(document).ready(function(){
337 -
338 - var pagelayer_timer;
339 - var pagelayer_button = function(){
340 - var button = jQuery("#pagelayer-editor-button-row");
341 - var g = jQuery(".edit-post-header-toolbar");
342 - if(g.length < 1){
343 - return;
344 - }
345 - button.detach();
346 - //console.log(button);
347 - g.append(button);
348 - button.show();
349 - clearInterval(pagelayer_timer);
350 - }
351 - pagelayer_timer = setInterval(pagelayer_button, 100);
352 -});
353 -</script>';
354 -
355 -}
356 -
357 -add_filter( 'post_row_actions', 'pagelayer_quick_link', 10, 2 );
358 -add_filter( 'page_row_actions', 'pagelayer_quick_link', 10, 2 );
359 -function pagelayer_quick_link($actions, $post){
360 - $link = pagelayer_shortlink($post->ID).'&pagelayer-live=1';
361 -
362 - $actions['pagelayer'] = '<a href="'.esc_url( $link ).'">'.__( 'Edit using PageLayer', 'pagelayer') .'</a>';
363 -
364 - return $actions;
365 -}
366 -
367 -// The ajax handler
368 -add_action('wp_ajax_pagelayer_wp_widget', 'pagelayer_wp_widget_ajax');
369 -function pagelayer_wp_widget_ajax(){
370 -
371 - global $pagelayer;
372 -
373 - // Some AJAX security
374 - check_ajax_referer('pagelayer_ajax', 'nonce');
375 -
376 - pagelayer_load_shortcodes();
377 -
378 - header('Content-Type: application/json');
379 -
380 - $ret = [];
381 - $tag = @$_POST['tag'];
382 - //pagelayer_print($pagelayer->shortcodes[$tag]);
383 -
384 - // No tag ?
385 - if(empty($pagelayer->shortcodes[$tag])){
386 - $ret['error'][] = 'No Tag';
387 - echo json_encode($ret);
388 - wp_die();
389 - }
390 -
391 - // Include the widgets
392 - include_once(ABSPATH . 'wp-admin/includes/widgets.php');
393 -
394 - $class = $pagelayer->shortcodes[$tag]['widget'];
395 -
396 - // Check the widget class exists ?
397 - if(empty($class) || !class_exists($class)){
398 - $ret['error'][] = 'No Widget Class';
399 - echo json_encode($ret);
400 - wp_die();
401 - }
402 -
403 - $instance = [];
404 - $widget = new $class();
405 - $widget->_set('pagelayer-widget-1234567890');
406 -
407 - // Is there any existing data ?
408 - if(!empty($_POST['widget_data'])){
409 - $json = json_decode(stripslashes($_POST['widget_data']), true);
410 - //pagelayer_print($json);die();
411 - if(!empty($json)){
412 - $instance = $json;
413 - }
414 - }
415 -
416 - // Are there any form values ?
417 - if(!empty($_POST['values'])){
418 - parse_str(stripslashes($_POST['values']), $data);
419 - //pagelayer_print($data);die();
420 -
421 - // Any data ?
422 - if(!empty($data)){
423 -
424 - // First key is useless
425 - $data = current($data);
426 -
427 - // Do we still have valid data ?
428 - if(!empty($data)){
429 -
430 - // 2nd key is useless and just over-ride instance
431 - $instance = current($data);
432 -
433 - }
434 - }
435 - }
436 -
437 - // Get the form
438 - ob_start();
439 - $widget->form($instance);
440 - $ret['form'] = ob_get_contents();
441 - ob_end_clean();
442 -
443 - // Get the html
444 - ob_start();
445 - $widget->widget([], $instance);
446 - $ret['html'] = ob_get_contents();
447 - ob_end_clean();
448 -
449 - // Widget data to set
450 - if(!empty($instance)){
451 - $ret['widget_data'] = $instance;
452 - }
453 -
454 - echo json_encode($ret);
455 - wp_die();
456 -
457 -}
458 -
459 -// Update Post content
460 -add_action('wp_ajax_pagelayer_save_content', 'pagelayer_save_content');
461 -function pagelayer_save_content(){
462 -
463 - // Some AJAX security
464 - check_ajax_referer('pagelayer_ajax', 'nonce');
465 -
466 - $content = $_POST['pagelayer_update_content'];
467 -
468 - $postID = (int) $_GET['postID'];
469 -
470 - if(empty($postID)){
471 - $msg['error'] = 'Invalid post ID';
472 - }
473 -
474 - // Check if the post exists
475 -
476 - if(!empty($postID) && !empty($content)){
477 -
478 - $post = array(
479 - 'ID' => $postID,
480 - 'post_content' => $content,
481 - );
482 -
483 - // Update the post into the database
484 - wp_update_post($post);
485 -
486 - if (is_wp_error($postID)) {
487 - $msg['error'] = 'Unable to update the Post Content for some reason';
488 - }else{
489 - $msg['success'] = 'Post Content was updated successfully!';
490 - }
491 -
492 - }else{
493 - $msg['error'] = "Unable to update the Post Content for some reason";
494 - }
495 -
496 - echo json_encode($msg);
497 - wp_die();
498 -
499 -}
500 -
501 -// Shortcodes Widget Handler
502 -add_action('wp_ajax_pagelayer_do_shortcodes', 'pagelayer_do_shortcodes');
503 -function pagelayer_do_shortcodes(){
504 -
505 - // Some AJAX security
506 - check_ajax_referer('pagelayer_ajax', 'nonce');
507 -
508 - $data = '';
509 - if(isset($_REQUEST['shortcode_data'])){
510 - $data = stripslashes($_REQUEST['shortcode_data']);
511 - }
512 -
513 - echo do_shortcode($data);
514 - wp_die();
515 -
516 -}
517 -
518 -// Get the Site Title
519 -add_action('wp_ajax_pagelayer_fetch_site_title', 'pagelayer_fetch_site_title');
520 -function pagelayer_fetch_site_title(){
521 -
522 - // Some AJAX security
523 - check_ajax_referer('pagelayer_ajax', 'nonce');
524 -
525 - echo get_bloginfo('name');
526 - wp_die();
527 -}
528 -
529 -// Update the Site Title
530 -add_action('wp_ajax_pagelayer_update_site_title', 'pagelayer_update_site_title');
531 -function pagelayer_update_site_title(){
532 - global $wpdb;
533 -
534 - // Some AJAX security
535 - check_ajax_referer('pagelayer_ajax', 'nonce');
536 -
537 - $site_title = $_POST['site_title'];
538 -
539 - update_option('blogname', $site_title);
540 -
541 - $wpdb->query("UPDATE `sm_sitemeta`
542 - SET meta_value = '".$site_title."'
543 - WHERE meta_key = 'site_name'");
544 - wp_die();
545 -}
546 -
547 -// Show the SideBars
548 -add_action('wp_ajax_pagelayer_fetch_sidebar', 'pagelayer_fetch_sidebar');
549 -function pagelayer_fetch_sidebar(){
550 -
551 - global $wp_registered_sidebars;
552 -
553 - // Some AJAX security
554 - check_ajax_referer('pagelayer_ajax', 'nonce');
555 -
556 - // Create a list
557 - $pagelayer_wp_widgets = array();
558 -
559 - foreach($wp_registered_sidebars as $v){
560 - $pagelayer_wp_widgets[$v['id']] = $v['name'];
561 - }
562 -
563 - $id = @$_REQUEST['sidebar'];
564 -
565 - if(function_exists('dynamic_sidebar') && !empty($pagelayer_wp_widgets[$id])) {
566 - ob_start();
567 - dynamic_sidebar($id);
568 - $result = ob_get_clean();
569 - }else{
570 - $result = 'No such Widget Area !';
571 - }
572 -
573 - echo $result;
574 - wp_die();
575 -
576 -}
577 -
578 -// Show the primary menu !
579 -add_action('wp_ajax_pagelayer_fetch_primary_menu', 'pagelayer_fetch_primary_menu');
580 -function pagelayer_fetch_primary_menu(){
581 -
582 - // Some AJAX security
583 - check_ajax_referer('pagelayer_ajax', 'nonce');
584 -
585 - echo wp_nav_menu( array(
586 - 'menu' => 'primary-menu',
587 - 'menu_id' => 'pagelayer-header-menu',
588 - 'theme_location' => 'primary',
589 - 'menu_class' => 'primary-menu',
590 - ) );
591 -
592 - wp_die();
593 -}
1 +<?php
2 +
3 +// We need the ABSPATH
4 +if (!defined('ABSPATH')) exit;
5 +
6 +define('PAGELAYER_BASE', plugin_basename(PAGELAYER_FILE));
7 +define('PAGELAYER_PREMIUM_BASE', 'pagelayer-pro/pagelayer-pro.php');
8 +define('PAGELAYER_VERSION', '2.2.0');
9 +define('PAGELAYER_DIR', dirname(PAGELAYER_FILE));
10 +define('PAGELAYER_SLUG', 'pagelayer');
11 +define('PAGELAYER_URL', plugins_url('', PAGELAYER_FILE));
12 +define('PAGELAYER_CSS', PAGELAYER_URL.'/css');
13 +define('PAGELAYER_JS', PAGELAYER_URL.'/js');
14 +define('PAGELAYER_PRO_PRICE_URL', 'https://pagelayer.com/pricing?from=plugin');
15 +define('PAGELAYER_WWW_URL', 'https://pagelayer.com/');
16 +define('PAGELAYER_DOCS', 'https://pagelayer.com/docs/');
17 +define('PAGELAYER_API', 'https://api.pagelayer.com/');
18 +define('PAGELAYER_AI_API', 'https://s2.softaculous.com/a/softai/ai.php');
19 +define('PAGELAYER_SC_PREFIX', 'pl');
20 +define('PAGELAYER_YOUTUBE_BG', 'https://www.youtube.com/watch?v=Csa6rvCWmLU');
21 +define('PAGELAYER_CMS_NAME', defined('SITEPAD') ? 'SitePad' : 'WordPress');
22 +define('PAGELAYER_BLOCK_PREFIX', defined('SITEPAD') ? 'sp' : 'wp');
23 +define('PAGELAYER_CMS_DIR_PREFIX', defined('SITEPAD') ? 'site' : 'wp');
24 +define('PAGELAYER_DEV', file_exists(dirname(__FILE__).'/dev.php') ? 1 : 0);
25 +define('PAGELAYER_FONT_POST_TYPE', 'pagelayer-fonts');
26 +
27 +include_once(PAGELAYER_DIR.'/main/functions.php');
28 +include_once(PAGELAYER_DIR.'/main/class.php');
29 +include_once(PAGELAYER_DIR.'/main/ai-controller.php');
30 +
31 +function pagelayer_died(){
32 + print_r(error_get_last());
33 +}
34 +//register_shutdown_function('pagelayer_died');
35 +
36 +// Ok so we are now ready to go
37 +register_activation_hook(PAGELAYER_FILE, 'pagelayer_activation');
38 +
39 +// Is called when the ADMIN enables the plugin
40 +function pagelayer_activation(){
41 +
42 + global $wpdb;
43 +
44 + $sql = array();
45 +
46 + /*$sql[] = "DROP TABLE IF EXISTS `".$wpdb->prefix."pagelayer_logs`";
47 +
48 + foreach($sql as $sk => $sv){
49 + $wpdb->query($sv);
50 + }*/
51 +
52 + add_option('pagelayer_version', PAGELAYER_VERSION);
53 + add_option('pagelayer_options', array());
54 +
55 +}
56 +
57 +// Checks if we are to update ?
58 +function pagelayer_update_check(){
59 +
60 +global $wpdb;
61 +
62 + $sql = array();
63 + $current_version = get_option('pagelayer_version');
64 + $version = (int) str_replace('.', '', $current_version);
65 +
66 + // No update required
67 + if($current_version == PAGELAYER_VERSION){
68 + return true;
69 + }
70 +
71 + // Is it first run ?
72 + if(empty($current_version)){
73 +
74 + // Reinstall
75 + pagelayer_activation();
76 +
77 + // Trick the following if conditions to not run
78 + $version = (int) str_replace('.', '', PAGELAYER_VERSION);
79 +
80 + }
81 +
82 + // Backward compatibility of global typography
83 + if(version_compare($current_version, '1.7.0', '<') && !defined('SITEPAD')){
84 +
85 + // Set the array
86 + $_pagelayer = new PageLayer();
87 +
88 + $post_types = array('' => __('Global'));
89 + $exclude = [ 'attachment', 'pagelayer-template' ];
90 + $pt_objects = get_post_types(['public' => true,], 'objects');
91 +
92 + foreach( $pt_objects as $pt_slug => $type ){
93 +
94 + if ( in_array( $pt_slug, $exclude ) ) {
95 + continue;
96 + }
97 +
98 + $post_types[$pt_slug] = $type->labels->name;
99 + }
100 +
101 + foreach($post_types as $sk => $sv){
102 +
103 + $post_type = empty($sk) ? '' : '_'.$sk;
104 +
105 + // Load CSS settings
106 + foreach($_pagelayer->css_settings as $k => $params){
107 +
108 + foreach($_pagelayer->screens as $sck => $scv){
109 + $suffix = (!empty($scv) ? '_'.$scv : '');
110 + $setting = empty($params['key']) ? 'pagelayer_'.$k.'_css'.$post_type : $params['key'].$post_type;
111 +
112 + $tmp = get_option($setting.$suffix);
113 +
114 + if(empty($tmp) || empty($tmp['global-font'])){
115 + continue;
116 + }
117 +
118 + // Do empty typo if global set
119 + foreach($tmp as $tk => $tv){
120 +
121 + if(!in_array($tk, $_pagelayer->typo_props)){
122 + continue;
123 + }
124 +
125 + $tmp[$tk] = '';
126 + }
127 +
128 + // Update settings
129 + update_option($setting.$suffix, $tmp);
130 + }
131 + }
132 + }
133 + }
134 +
135 + // Show changelog notice
136 + if(version_compare($current_version, '1.8.1', '<') && !defined('SITEPAD')){
137 + update_option('pagelayer_changelog_notice', 1);
138 + }
139 +
140 + // Save the new Version
141 + update_option('pagelayer_version', PAGELAYER_VERSION);
142 +
143 +}
144 +
145 +// Add the action to load the plugin
146 +add_action('plugins_loaded', 'pagelayer_load_plugin', 9);
147 +
148 +// The function that will be called when the plugin is loaded
149 +function pagelayer_load_plugin(){
150 +
151 + // Init MCP Abilities
152 + add_action('wp_abilities_api_categories_init', 'pagelayer_wp_abilities_api_categories_init');
153 + add_action('wp_abilities_api_init', 'pagelayer_wp_abilities_api_init');
154 +
155 + global $pagelayer;
156 +
157 + // Check if the installed version is outdated
158 + pagelayer_update_check();
159 +
160 + // Set the array
161 + $pagelayer = new PageLayer();
162 +
163 + if(empty($pagelayer->BRAND_TEXT)){
164 + $pagelayer->BRAND_TEXT = 'Pagelayer';
165 + }
166 +
167 + if(empty($pagelayer->LOGO)){
168 + $pagelayer->LOGO = PAGELAYER_URL.'/images/pagelayer-logo-40.png';
169 + }
170 +
171 + // Is there any ACTION set ?
172 + $pagelayer->action = pagelayer_optreq('pagelayer-action');
173 +
174 + $tablet_breakpoint = get_option('pagelayer_tablet_breakpoint');
175 + $mobile_breakpoint = get_option('pagelayer_mobile_breakpoint');
176 +
177 + // Load settings
178 + $pagelayer->settings['post_types'] = empty(get_option('pl_support_ept')) ? ['post', 'page'] : get_option('pl_support_ept');
179 + $pagelayer->settings['enable_giver'] = get_option('pagelayer_enable_giver');
180 + $pagelayer->settings['max_width'] = (int) (empty(get_option('pagelayer_content_width')) ? 1170 : get_option('pagelayer_content_width'));
181 + $pagelayer->settings['tablet_breakpoint'] = (int) (empty($tablet_breakpoint) ? 780 : $tablet_breakpoint);
182 + $pagelayer->settings['mobile_breakpoint'] = (int) (empty($mobile_breakpoint) ? 480 : $mobile_breakpoint);
183 + $pagelayer->settings['sidebar'] = get_option('pagelayer_sidebar');
184 + $pagelayer->settings['body_font'] = get_option('pagelayer_body_font');
185 + $pagelayer->settings['color'] = get_option('pagelayer_color');
186 +
187 + // Any custom types
188 + $pagelayer->settings['post_types'] = apply_filters('pagelayer_supported_post_type', $pagelayer->settings['post_types']);
189 +
190 + // Load the language
191 + load_plugin_textdomain('pagelayer', false, PAGELAYER_SLUG.'/languages/');
192 +
193 + // Load our array for builder
194 + pagelayer_builder_array();
195 +
196 + // Its premium
197 + if(!defined('PAGELAYER_PREMIUM')){
198 +
199 + // Show the promo
200 + pagelayer_maybe_promo([
201 + 'after' => 1,// In days
202 + 'interval' => 30,// In days
203 + 'pro_url' => PAGELAYER_PRO_PRICE_URL,
204 + 'rating' => 'https://wordpress.org/plugins/pagelayer/#reviews',
205 + 'twitter' => 'https://twitter.com/pagelayer?status='.rawurlencode('I love #Pagelayer Site Builder by @pagelayer team for my #WordPress site - '.home_url()),
206 + 'facebook' => 'https://www.facebook.com/pagelayer',
207 + 'website' => PAGELAYER_WWW_URL,
208 + 'image' => PAGELAYER_URL.'/images/pagelayer-logo-256.png'
209 + ]);
210 +
211 + }
212 +
213 + // Are we to disable the getting started promo
214 + if(current_user_can('activate_plugins') && isset($_GET['pagelayer-getting-started']) && (int)$_GET['pagelayer-getting-started'] == 0){
215 + check_ajax_referer('pagelayer_getting_started_nonce', 'pagelayer_nonce');
216 + update_option('pagelayer_getting_started', time());
217 + die('DONE');
218 + }
219 +
220 + // === Plugin Update Notice === //
221 + if(is_admin() && current_user_can('manage_options')){
222 + $plugin_update_notice = get_option('softaculous_plugin_update_notice', []);
223 + $available_update_list = get_site_transient('update_plugins');
224 + $plugin_path_slug = 'pagelayer/pagelayer.php';
225 +
226 + if(
227 + !empty($available_update_list) &&
228 + is_object($available_update_list) &&
229 + !empty($available_update_list->response) &&
230 + !empty($available_update_list->response[$plugin_path_slug]) &&
231 + (empty($plugin_update_notice) || empty($plugin_update_notice[$plugin_path_slug]) || (!empty($plugin_update_notice[$plugin_path_slug]) &&
232 + version_compare($plugin_update_notice[$plugin_path_slug], $available_update_list->response[$plugin_path_slug]->new_version, '<')))
233 + ){
234 + add_action('admin_notices', 'pagelayer_update_plugin_notice');
235 + add_filter('softaculous_plugin_update_notice', 'pagelayer_update_plugin_notice_filter');
236 + }
237 + }
238 + // === Plugin Update Notice End === //
239 +
240 + // Show the getting started video option
241 + $seen = get_option('pagelayer_getting_started');
242 + if(empty($seen) && !empty($_GET['page']) && $_GET['page'] != 'pagelayer_getting_started'){
243 + add_action('admin_notices', 'pagelayer_getting_started_notice');
244 + }
245 +
246 + // Are we to disable the changelog notice
247 + if(current_user_can('activate_plugins') && isset($_GET['pagelayer-changelog-notice']) && (int)$_GET['pagelayer-changelog-notice'] == 0){
248 + check_ajax_referer('pagelayer_changelog_nonce', 'pagelayer_nonce');
249 + update_option('pagelayer_changelog_notice', 0);
250 + die('DONE');
251 + }
252 +
253 + // Show the changelog notice
254 + $changelog = get_option('pagelayer_changelog_notice');
255 + if(!empty($changelog)){
256 + add_action('admin_notices', 'pagelayer_show_changelog_notice');
257 + }
258 +
259 + include_once(PAGELAYER_DIR.'/main/customizer.php');
260 +
261 + if(class_exists('WooCommerce')){
262 + include_once(PAGELAYER_DIR.'/main/woocommerce.php');
263 + }
264 +
265 +}
266 +
267 +// This adds the left menu in WordPress Admin page
268 +add_action('admin_menu', 'pagelayer_admin_menu', 5);
269 +
270 +// Shows the admin menu of Pagelayer
271 +add_action('admin_enqueue_scripts', 'pagelayer_admin_enqueue_scripts');
272 +function pagelayer_admin_enqueue_scripts($hook){
273 + global $typenow;
274 +
275 + if(strpos($hook, "pagelayer") === false && $typenow !== 'pagelayer-template' && $typenow !== 'pagelayer-fonts'){
276 + return;
277 + }
278 +
279 + wp_enqueue_script("pagelayer-admin", PAGELAYER_JS."/pagelayer-admin.js", array("jquery"), PAGELAYER_VERSION . '-' . time());
280 + wp_enqueue_script("pagelayer-vanilla-picker", PAGELAYER_JS."/vanilla-picker.min.js", array(), PAGELAYER_VERSION);
281 + wp_enqueue_style("pagelayer-admin", PAGELAYER_CSS."/pagelayer-admin.css", array(), PAGELAYER_VERSION);
282 +
283 + wp_localize_script("pagelayer-admin", "pagelayer_admin_data", array(
284 + 'version' => PAGELAYER_VERSION,
285 + 'logo' => esc_url(PAGELAYER_URL . '/images/pagelayer-logo-40.png'),
286 + 'is_premium' => defined('PAGELAYER_PREMIUM') ? 1 : 0,
287 + 'pricing_url' => PAGELAYER_PRO_PRICE_URL,
288 + 'docs_url' => esc_url(PAGELAYER_DOCS),
289 + 'admin_url' => admin_url(),
290 + 'is_sitepad' => defined('SITEPAD') ? 1 : 0,
291 + ));
292 +
293 + if(strpos($hook, "pagelayer_ai_agents") !== false){
294 + include_once(PAGELAYER_DIR.'/main/abilities.php');
295 + wp_enqueue_style("pagelayer-abilities", PAGELAYER_CSS."/pagelayer-abilities.css", array(), PAGELAYER_VERSION);
296 + wp_enqueue_script("pagelayer-abilities", PAGELAYER_JS."/pagelayer-abilities.js", array("jquery"), PAGELAYER_VERSION, true);
297 +
298 + $site_url = trailingslashit(rtrim(home_url(), '/'));
299 + $username = function_exists('wp_get_current_user') ? wp_get_current_user()->user_login : '';
300 + $mcp_server_url = $site_url . ltrim(Pagelayer_Abilities::$MCP_SERVER_ENDPOINT, '/');
301 +
302 + wp_localize_script("pagelayer-abilities", "pagelayer_abilities_data", array(
303 + 'siteUrl' => $site_url,
304 + 'mcpServerUrl' => $mcp_server_url,
305 + 'username' => $username,
306 + 'nonce' => wp_create_nonce('pagelayer_mcp_nonce')
307 + ));
308 + }
309 +}
310 +
311 +function pagelayer_admin_menu() {
312 +
313 + global $wp_version, $pagelayer;
314 +
315 + $capability = 'activate_plugins';// TODO : Capability for accessing this page
316 +
317 + // Add the menu page
318 + add_menu_page(__('Pagelayer Editor'), __('Pagelayer'), $capability, 'pagelayer', 'pagelayer_page_handler', PAGELAYER_URL.'/images/pagelayer-logo-19.png');
319 +
320 + // Settings Page
321 + add_submenu_page('pagelayer', __('Pagelayer Editor'), __('Settings'), $capability, 'pagelayer', 'pagelayer_page_handler');
322 +
323 + // Meta Settings Page
324 + add_submenu_page('admin.php', __('Meta Settings'), __('Meta Settings'), 'edit_posts', 'pagelayer_meta_setting', 'pagelayer_meta_handler');
325 +
326 + // Add New Template Wizard Page
327 + add_submenu_page('admin.php', __('Add New Template'), __('Add New Template'), $capability, 'pagelayer_template_wizard', 'pagelayer_builder_template_wizard');
328 +
329 + // Export Template Page (accessed from buttons/links)
330 + add_submenu_page('admin.php', __('Export Theme'), __('Export Theme'), $capability, 'pagelayer_template_export', 'pagelayer_builder_export');
331 +
332 + // Import Template Page (accessed from buttons/links)
333 + add_submenu_page('admin.php', __('Import Theme'), __('Import Theme'), $capability, 'pagelayer_import', 'pagelayer_import_page');
334 +
335 + // UI Settings
336 + add_submenu_page('pagelayer', __('Website Settings'), __('Website Settings'), $capability, 'pagelayer_website_settings', 'pagelayer_website_page');
337 +
338 + // Add new template
339 + add_submenu_page('pagelayer', __('Theme Templates'), __('Theme Templates'), $capability, 'edit.php?post_type=pagelayer-template');
340 +
341 + // Add new template Link
342 + //add_submenu_page('pagelayer', __('Add New Template'), __('Add New Template'), $capability, 'edit.php?post_type=pagelayer-template#new');
343 +
344 + // Register Tools Submenu page under pagelayer
345 + add_submenu_page('pagelayer', __('Tools'), __('Tools'), $capability, 'pagelayer_tools', 'pagelayer_tools_page_handler');
346 +
347 + // AI Agents Connection
348 + add_submenu_page('pagelayer', __('AI Agents', 'pagelayer'), __('AI Agents', 'pagelayer') . ' <span style="vertical-align:middle;background:#d63638;font-size:9px;padding:0 6px;border-radius:10px;line-height:18px;color:#fff;">New!</span>' , $capability, 'pagelayer_ai_agents', 'pagelayer_ai_agents_page_handler');
349 +
350 + // Getting Started
351 + add_submenu_page('pagelayer', __('Getting Started'), __('Getting Started'), $capability, 'pagelayer_getting_started', 'pagelayer_getting_started');
352 +
353 + // Its Free
354 + if(!defined('PAGELAYER_PREMIUM')){
355 +
356 + // Go Pro link
357 + add_submenu_page('pagelayer', __('Pagelayer Go Pro'), __('Go Pro'), $capability, PAGELAYER_PRO_PRICE_URL);
358 +
359 + }else{
360 +
361 + // License Page
362 + add_submenu_page('pagelayer', __('Pagelayer License'), __('License'), $capability, 'pagelayer_license', 'pagelayer_license_page');
363 +
364 + }
365 +
366 + // Replace Media
367 + add_submenu_page('admin.php', __('Replace media', 'pagelayer'), __('Replace media', 'pagelayer'), 'upload_files', 'pagelayer_replace_media', 'pagelayer_replace_media');
368 +
369 +}
370 +
371 +// This function will handle the Settings Pages in Pagelayer
372 +function pagelayer_website_page(){
373 +
374 + global $wp_version, $pagelayer;
375 +
376 + include_once(PAGELAYER_DIR.'/main/website.php');
377 +
378 + pagelayer_website_settings();
379 +
380 +}
381 +
382 +function pagelayer_wp_abilities_api_categories_init(){
383 + include_once(PAGELAYER_DIR.'/main/abilities.php');
384 + include_once(PAGELAYER_DIR.'/main/abilitiesregister.php');
385 + if(class_exists('Pagelayer_Abilities_Register')){
386 + Pagelayer_Abilities_Register::register_categories();
387 + }
388 +}
389 +
390 +function pagelayer_wp_abilities_api_init(){
391 + include_once(PAGELAYER_DIR.'/main/abilities.php');
392 + include_once(PAGELAYER_DIR.'/main/abilitiesregister.php');
393 + if(class_exists('Pagelayer_Abilities_Register')){
394 + Pagelayer_Abilities_Register::register_abilities();
395 + }
396 +}
397 +
398 +// This function handles the AI Agents page
399 +function pagelayer_ai_agents_page_handler(){
400 + include_once(PAGELAYER_DIR.'/main/abilities.php');
401 + Pagelayer_Abilities::render_page();
402 +}
403 +
404 +// Getting Started
405 +function pagelayer_getting_started(){
406 +
407 + global $wp_version, $pagelayer;
408 +
409 + update_option('pagelayer_getting_started', time());
410 +
411 + include_once(PAGELAYER_DIR.'/main/getting_started.php');
412 +
413 +}
414 +
415 +// This function will handle the post_metas Pages in Pagelayer
416 +function pagelayer_meta_handler(){
417 +
418 + global $wp_version, $pagelayer;
419 +
420 + include_once(PAGELAYER_DIR.'/main/post_metas.php');
421 +
422 + pagelayer_meta_page();
423 +
424 +}
425 +
426 +// Pagelayer post meta page view handler
427 +add_action('admin_enqueue_scripts', 'pagelayer_post_meta_page');
428 +function pagelayer_post_meta_page() {
429 +
430 + // Set Current screen
431 + $screen = get_current_screen();
432 + $meta_id = 'admin_page_pagelayer_meta_setting';
433 +
434 + if( !is_admin() || trim($screen->id) != $meta_id ) {
435 + return;
436 + }
437 +
438 + if(!isset($_REQUEST['post'])){
439 + return;
440 + }
441 +
442 + // Remove all the notice hooks
443 + remove_all_actions('admin_notices');
444 + remove_all_actions('all_admin_notices');
445 +
446 + $_REQUEST['post'] = (int) $_REQUEST['post'];
447 + $post = get_post( $_REQUEST['post'] );
448 +
449 + // Enqueue Scripts
450 + wp_enqueue_script( 'post' );
451 +
452 + // Is support media
453 + $thumbnail_support = current_theme_supports( 'post-thumbnails', $post->post_type ) && post_type_supports( $post->post_type, 'thumbnail' );
454 + if ( ! $thumbnail_support && 'attachment' === $post->post_type && $post->post_mime_type ) {
455 + if ( wp_attachment_is( 'audio', $post ) ) {
456 + $thumbnail_support = post_type_supports( 'attachment:audio', 'thumbnail' ) || current_theme_supports( 'post-thumbnails', 'attachment:audio' );
457 + } elseif ( wp_attachment_is( 'video', $post ) ) {
458 + $thumbnail_support = post_type_supports( 'attachment:video', 'thumbnail' ) || current_theme_supports( 'post-thumbnails', 'attachment:video' );
459 + }
460 + }
461 +
462 + if ( $thumbnail_support ) {
463 + add_thickbox();
464 + wp_enqueue_media( array( 'post' => $post->ID ) );
465 + }
466 +
467 + $meta_box_url = admin_url( 'post.php' );
468 + $meta_box_url = add_query_arg(
469 + array(
470 + 'post' => $post->ID,
471 + 'action' => 'editpost',
472 + ),
473 + $meta_box_url
474 + );
475 +
476 + echo '<style>
477 +.'.$meta_id.' #adminmenumain, .'.$meta_id.' #wpfooter, .'.$meta_id.' #wpadminbar{
478 +display:none;
479 +}
480 +.'.$meta_id.' #wpcontent{
481 +margin:auto;
482 +}
483 +</style>
484 +
485 +<script type="text/javascript">
486 +
487 +function pagelayer_post_edit(jEle, e){
488 +
489 + e.preventDefault();
490 + var formData = new FormData( jQuery(jEle)[0] );
491 +
492 + jQuery.ajax({
493 + url: "'.$meta_box_url.'",
494 + type: "POST",
495 + data: formData,
496 + processData: false,
497 + contentType: false,
498 + cache:false,
499 + success:function(result){
500 + //window.location.reload();
501 + alert("Post meta has been updated successfully !");
502 + },
503 + error:function(result){
504 + alert("There is an error while updating post meta !");
505 + }
506 + });
507 +}
508 +
509 +</script>';
510 +
511 +}
512 +
513 +// Update post meta via gutenberg handler
514 +add_filter('sanitize_post_meta_pagelayer_header_code', 'pagelayer_sanitize_postmeta', 10, 2);
515 +add_filter('sanitize_post_meta_pagelayer_body_open_code', 'pagelayer_sanitize_postmeta', 10, 2);
516 +add_filter('sanitize_post_meta_pagelayer_footer_code', 'pagelayer_sanitize_postmeta', 10, 2);
517 +function pagelayer_sanitize_postmeta( $meta_value, $meta_key ) {
518 +
519 + // Sanitize Header, body and footer code
520 + if(
521 + in_array( $meta_key, array( 'pagelayer_header_code', 'pagelayer_body_open_code', 'pagelayer_footer_code' ) ) &&
522 + !pagelayer_user_can_add_js_content()
523 + ){
524 + return sanitize_textarea_field($meta_value);
525 + }
526 +
527 + return $meta_value;
528 +}
529 +
530 +// Pre post save handler
531 +add_filter( 'content_save_pre', 'pagelayer_content_save_pre' );
532 +function pagelayer_content_save_pre($content){
533 +
534 + if(!pagelayer_user_can_add_js_content() && strpos($content, '[') !== false){
535 + $content = pagelayer_sanitize_shortcode_atts($content);
536 + }
537 +
538 + if(pagelayer_user_can_add_js_content() || !pagelayer_has_blocks($content)){
539 + return $content;
540 + }
541 +
542 + $blocks = parse_blocks( wp_unslash($content) );
543 + $output = '';
544 +
545 + foreach ( $blocks as $block ) {
546 +
547 + // Sanitize Pagelayer blocks at any depth, they can be nested inside
548 + // any other block
549 + $output .= serialize_block( pagelayer_sanitize_block_tree( $block ) );
550 + }
551 +
552 + return wp_slash($output);
553 +}
554 +
555 +// On post save handler
556 +add_action('save_post', 'pagelayer_save_post', 10, 3);
557 +function pagelayer_save_post( $post_id, $post, $update ) {
558 +
559 + if( !isset($_REQUEST['is_pagelayer_editor']) || !pagelayer_user_can_edit($post_id)){
560 + return;
561 + }
562 +
563 + check_admin_referer('update-post_' . $post_id);
564 +
565 + // Save Header, body and footer code
566 + $header_code = !empty($_REQUEST['pagelayer_header_code']) ? $_REQUEST['pagelayer_header_code'] : '' ;
567 + $body_code = !empty($_REQUEST['pagelayer_body_open_code']) ? $_REQUEST['pagelayer_body_open_code'] : '' ;
568 + $footer_code = !empty($_REQUEST['pagelayer_footer_code']) ? $_REQUEST['pagelayer_footer_code'] : '' ;
569 +
570 + // Set Custom header, body and footer code
571 + if(!empty($header_code)){
572 + update_post_meta($post_id, 'pagelayer_header_code', $header_code);
573 + }else{
574 + delete_post_meta($post_id, 'pagelayer_header_code');
575 + }
576 +
577 + if(!empty($body_code)){
578 + update_post_meta($post_id, 'pagelayer_body_open_code', $body_code);
579 + }else{
580 + delete_post_meta($post_id, 'pagelayer_body_open_code');
581 + }
582 +
583 + if(!empty($footer_code)){
584 + update_post_meta($post_id, 'pagelayer_footer_code', $footer_code);
585 + }else{
586 + delete_post_meta($post_id, 'pagelayer_footer_code');
587 + }
588 +
589 +}
590 +
591 +// This function will handle the Settings Pages in Pagelayer
592 +function pagelayer_page_handler(){
593 +
594 + global $wp_version, $pagelayer;
595 +
596 + include_once(PAGELAYER_DIR.'/main/settings.php');
597 +
598 + pagelayer_settings_page();
599 +
600 +}
601 +
602 +function pagelayer_tools_page_handler(){
603 + global $wp_version, $pagelayer, $pagelayer_header_printed, $pagelayer_footer_printed;
604 +
605 + include_once(PAGELAYER_DIR.'/main/settings.php');
606 +
607 + // Render the single master Pagelayer Tools page header
608 + pagelayer_page_header(__('Tools', 'pagelayer'));
609 +
610 + // 1. Add New Template Tool Panel
611 + echo '<div id="add_new_template" class="pagelayer-tab-panel">';
612 + if (function_exists('pagelayer_builder_template_wizard')) {
613 + $pagelayer_footer_printed = true; // Mute inner footer
614 + pagelayer_builder_template_wizard();
615 + $pagelayer_footer_printed = false; // Reset
616 + }
617 + echo '</div>';
618 +
619 + // 2. Export Theme Tool Panel (Premium only)
620 + if(defined('PAGELAYER_PREMIUM')){
621 + echo '<div id="export_theme" class="pagelayer-tab-panel" style="display:none;">';
622 + if (function_exists('pagelayer_builder_export')) {
623 + $pagelayer_footer_printed = true; // Mute inner footer
624 + pagelayer_builder_export('');
625 + $pagelayer_footer_printed = false; // Reset
626 + }
627 + echo '</div>';
628 +
629 + // 3. Import Theme Tool Panel (Premium only)
630 + echo '<div id="import_theme" class="pagelayer-tab-panel" style="display:none;">';
631 + include_once(PAGELAYER_DIR.'/main/import.php');
632 + if(function_exists('pagelayer_import')){
633 + $pagelayer_footer_printed = true; // Mute inner footer
634 + pagelayer_import();
635 + $pagelayer_footer_printed = false; // Reset
636 + }
637 + echo '</div>';
638 + } else {
639 + // Output high premium promotion templates for export & import tools to enable hash tab switching and prevent page reload in Free version
640 + echo'<div id="export_theme" class="pagelayer-tab-panel" style="display:none;">
641 + <div class="pagelayer-settings-card" style="padding: 40px 24px; text-align: center; max-width: 600px; margin: 40px auto; border-radius: 12px; box-shadow: 0 8px 30px rgba(0,0,0,0.05); background: #fff; border: 1px solid #f0f0f0;">
642 + <span class="dashicons dashicons-upload" style="font-size: 64px; width: 64px; height: 64px; color: #2563eb; margin-bottom: 16px;"></span>
643 + <h2 style="font-size: 24px; margin-top: 0; color: #333; font-weight: 600;">' . __('Export Theme', 'pagelayer') . '</h2>
644 + <p style="color: #666; font-size: 15px; line-height: 1.6; margin-bottom: 24px; max-width: 480px; margin-left: auto; margin-right: auto;">' . __('Exporting your customized Pagelayer designs and layouts directly into a standalone WordPress theme is a Premium feature. Upgrade to Pagelayer Pro to build and export your own custom themes!', 'pagelayer') . '</p>
645 + <a href="' . esc_url(PAGELAYER_PRO_PRICE_URL) . '" target="_blank" class="button-pagelayer" style="text-decoration: none;">' . __('Upgrade to Pagelayer Pro', 'pagelayer') . '</a>
646 + </div>
647 + </div>';
648 +
649 + echo'<div id="import_theme" class="pagelayer-tab-panel" style="display:none;">
650 + <div class="pagelayer-settings-card" style="padding: 40px 24px; text-align: center; max-width: 600px; margin: 40px auto; border-radius: 12px; box-shadow: 0 8px 30px rgba(0,0,0,0.05); background: #fff; border: 1px solid #f0f0f0;">
651 + <span class="dashicons dashicons-download" style="font-size: 64px; width: 64px; height: 64px; color: #2563eb; margin-bottom: 16px;"></span>
652 + <h2 style="font-size: 24px; margin-top: 0; color: #333; font-weight: 600;">' . __('Import Theme', 'pagelayer') . '</h2>
653 + <p style="color: #666; font-size: 15px; line-height: 1.6; margin-bottom: 24px; max-width: 480px; margin-left: auto; margin-right: auto;">' . __('Importing pre-designed custom themes with all layouts, options, and page structures is a Premium feature. Upgrade to Pagelayer Pro to import complete themes with a single click!', 'pagelayer') . '</p>
654 + <a href="' . esc_url(PAGELAYER_PRO_PRICE_URL) . '" target="_blank" class="button-pagelayer" style="text-decoration: none;">' . __('Upgrade to Pagelayer Pro', 'pagelayer') . '</a>
655 + </div>
656 + </div>';
657 +
658 + echo'<div id="custom_fonts" class="pagelayer-tab-panel" style="display:none;">
659 + <div class="pagelayer-settings-card" style="padding: 40px 24px; text-align: center; max-width: 600px; margin: 40px auto; border-radius: 12px; box-shadow: 0 8px 30px rgba(0,0,0,0.05); background: #fff; border: 1px solid #f0f0f0;">
660 + <span class="dashicons dashicons-editor-bold" style="font-size: 64px; width: 64px; height: 64px; color: #2563eb; margin-bottom: 16px;"></span>
661 + <h2 style="font-size: 24px; margin-top: 0; color: #333; font-weight: 600;">' . __('Custom Fonts', 'pagelayer') . '</h2>
662 + <p style="color: #666; font-size: 15px; line-height: 1.6; margin-bottom: 24px; max-width: 480px; margin-left: auto; margin-right: auto;">' . __('Adding and using custom typography/fonts directly in your designs is a Premium feature. Upgrade to Pagelayer Pro to upload and manage your own custom fonts!', 'pagelayer') . '</p>
663 + <a href="' . esc_url(PAGELAYER_PRO_PRICE_URL) . '" target="_blank" class="button-pagelayer" style="text-decoration: none;">' . __('Upgrade to Pagelayer Pro', 'pagelayer') . '</a>
664 + </div>
665 + </div>';
666 + }
667 +
668 + // Reset print flags to allow the final master footer to print correctly
669 + $pagelayer_footer_printed = false;
670 + pagelayer_page_footer();
671 +}
672 +
673 +// This function will handle the Settings Pages in Pagelayer
674 +function pagelayer_license_page(){
675 +
676 + global $wp_version, $pagelayer;
677 +
678 + include_once(PAGELAYER_PRO_DIR.'/main/license.php');
679 +
680 + pagelayer_license();
681 +
682 +}
683 +
684 +// Import Pagelayer Templates
685 +function pagelayer_import_page(){
686 +
687 + global $wp_version, $pagelayer;
688 +
689 + include_once(PAGELAYER_DIR.'/main/import.php');
690 +
691 + pagelayer_import();
692 +
693 +}
694 +
695 +// Load the Live Body
696 +add_action('template_redirect', 'pagelayer_load_live_body', 4);
697 +
698 +function pagelayer_load_live_body(){
699 +
700 + global $post;
701 +
702 + // If its not live editing then stop
703 + if(!pagelayer_is_live()){
704 + return;
705 + }
706 +
707 + // If its the iFRAME then return
708 + if(pagelayer_is_live_iframe()){
709 + return;
710 + }
711 +
712 + // Are you allowed to edit ?
713 + if(!pagelayer_user_can_edit($post->ID)){
714 + return;
715 + }
716 +
717 + // Load the editor live body
718 + include_once(PAGELAYER_DIR.'/main/live-body.php');
719 +
720 + pagelayer_live_body();
721 +
722 +}
723 +
724 +// Add the JS and CSS for Posts and Pages when being viewed ONLY if there is our content called
725 +add_action('template_redirect', 'pagelayer_enqueue_frontend', 5);
726 +function pagelayer_enqueue_frontend($force = false){
727 +
728 + global $post, $pagelayer;
729 +
730 + if(!empty($pagelayer->cache['enqueue_frontend'])){
731 + return;
732 + }
733 +
734 + if(empty($post->ID) && empty($force)){
735 + return;
736 + }
737 +
738 + $is_pagelayer = false;
739 + $is_audio = false;
740 +
741 + // This IF is for Archives mainly as $post->ID is only the first post in the archive
742 + // and we need to make sure that other posts are pagelayer or not
743 + if(!empty($GLOBALS['wp_query']->posts) && is_array($GLOBALS['wp_query']->posts)){
744 + foreach($GLOBALS['wp_query']->posts as $v){
745 + if(get_post_meta($v->ID , 'pagelayer-data')){
746 + $is_pagelayer = true;
747 + }
748 +
749 + if(preg_match('/(\[pl_audio|pagelayer\/pl_audio)/is', $v->post_content)){
750 + $is_audio = true;
751 + }
752 + }
753 + }
754 +
755 + // Enqueue the FRONTEND CSS
756 + if((!empty($post->ID) && get_post_meta($post->ID , 'pagelayer-data')) || pagelayer_has_blocks() || $is_pagelayer || $force){
757 +
758 + // We dont need the auto <p> and <br> as they interfere with us
759 + remove_filter('the_content', 'wpautop');
760 +
761 + // No need to add curly codes to the content
762 + remove_filter('the_content', 'wptexturize');
763 +
764 + pagelayer_load_shortcodes();
765 +
766 + // Load global colors and fonts
767 + pagelayer_load_global_palette();
768 +
769 + $pagelayer->cache['enqueue_frontend'] = true;
770 +
771 + // Load the global styles
772 + add_action('wp_head', 'pagelayer_global_js', 2);
773 +
774 + $premium_js = apply_filters('pagelayer_add_give_js', '');
775 + $premium_css = apply_filters('pagelayer_add_give_css', '');
776 +
777 + // Load this For audio widget
778 + do_action('pagelayer_load_audio_widget', $is_audio);
779 +
780 + if(pagelayer_enable_giver()){
781 +
782 + $write = '';
783 +
784 + // Dev mode - Dynamic JS and CSS
785 + if(defined('PAGELAYER_DEV') && !empty(PAGELAYER_DEV)){
786 + $write = '&write=1';
787 + }
788 +
789 + // Enqueue our Editor's Frontend JS
790 + wp_register_script('pagelayer-frontend', PAGELAYER_JS.'/givejs.php?give=pagelayer-frontend.js,nivo-lightbox.min.js,wow.min.js,jquery-numerator.js,simpleParallax.min.js,owl.carousel.min.js'.$premium_js.$write, array('jquery'), PAGELAYER_VERSION);
791 +
792 + // Get list of enabled icons
793 + $icons_css = '';
794 + $icons = pagelayer_enabled_icons();
795 + foreach($icons as $icon){
796 + $icons_css .= ','.$icon.'.min.css';
797 + }
798 +
799 + wp_register_style('pagelayer-frontend', PAGELAYER_CSS.'/givecss.php?give=pagelayer-frontend.css,nivo-lightbox.css,animate.min.css,owl.carousel.min.css,owl.theme.default.min.css'.$icons_css.$premium_css.$write, array(), PAGELAYER_VERSION);
800 +
801 + // Static Files
802 + }else{
803 +
804 + wp_register_script('pagelayer-frontend', (empty($premium_js) ? PAGELAYER_JS : PAGELAYER_PRO_JS).'/combined.js', array('jquery'), PAGELAYER_VERSION);
805 +
806 + wp_register_style('pagelayer-frontend', PAGELAYER_CSS.'/combined'.(!empty($premium_css) ? '.premium' : '').'.css', array(), PAGELAYER_VERSION);
807 + }
808 +
809 + wp_enqueue_script('pagelayer-frontend');
810 + wp_enqueue_style('pagelayer-frontend');
811 +
812 + // Load the global styles
813 + add_action('wp_head', 'pagelayer_global_styles', 5);
814 + add_filter('body_class', 'pagelayer_body_class', 10, 2);
815 +
816 + // Load the global styles for gutenberg
817 + if(pagelayer_is_gutenberg_editor()){
818 + add_action('admin_print_scripts', 'pagelayer_global_styles', 5);
819 + }
820 +
821 + // Load custom widgets
822 + do_action('pagelayer_custom_frontend_enqueue');
823 +
824 + }
825 +
826 +}
827 +
828 +// Load the google and custom fonts
829 +add_action('wp_footer', 'pagelayer_enqueue_fonts', 5);
830 +function pagelayer_enqueue_fonts($suffix = '-header'){
831 +
832 + global $pagelayer;
833 +
834 + if(empty($pagelayer->cache['enqueue_frontend'])){
835 + return;
836 + }
837 +
838 + $url = [];
839 + $cst = [];
840 +
841 + foreach($pagelayer->css as $k => $set){
842 +
843 + $font_family = pagelayer_isset($set, 'font-family');
844 +
845 + if(empty($font_family)){
846 + $key = str_replace(['_mobile', '_tablet'], '', $k);
847 + $font_family = isset($pagelayer->css[$key]['font-family'])? $pagelayer->css[$key]['font-family']: '';
848 + }
849 +
850 + // Fetch body font if given
851 + if(!empty($font_family)){
852 + pagelayer_load_font_family($font_family, pagelayer_isset($set, 'font-weight'), pagelayer_isset($set, 'font-style'));
853 + }
854 +
855 + }
856 +
857 + foreach($pagelayer->runtime_fonts as $font => $weights){
858 +
859 + if(in_array($font, $pagelayer->system_fonts)){
860 + continue;
861 + }
862 +
863 + if(strpos($font, '_plf')){
864 + if(!in_array($font, $pagelayer->fonts_sent)){
865 + $pagelayer->fonts_sent[] = $font;
866 + $cst[] = preg_replace('/_plf$/is', '', $font);
867 + }
868 + }else{
869 + $v = $font.':'.implode(',', $weights);
870 + if(!in_array($v, $pagelayer->fonts_sent)){
871 + $url[] = $v;
872 + $pagelayer->fonts_sent[] = $v;
873 + }
874 + }
875 + }
876 +
877 + // If no fonts are to be set, then we dont set
878 + if(!empty($url)){
879 + $fonts_url = 'https://fonts.googleapis.com/css?family='.rawurlencode(implode('|', $url));
880 +
881 + $fonts_url = apply_filters('pagelayer_google_fonts_url', $fonts_url);
882 +
883 + wp_register_style('pagelayer-google-font'.$suffix, $fonts_url, array(), PAGELAYER_VERSION);
884 + wp_enqueue_style('pagelayer-google-font'.$suffix);
885 +
886 + echo '<link rel="preload" href="'.$fonts_url.'" as="fetch" crossorigin="anonymous">';
887 + }
888 +
889 + if(empty($cst)){
890 + return;
891 + }
892 +
893 + $args = [
894 + 'post_type' => PAGELAYER_FONT_POST_TYPE,
895 + 'status' => 'publish',
896 + 'post_name__in' => $cst
897 + ];
898 +
899 + //var_dump($args);
900 +
901 + $query = get_posts($args);
902 + //var_dump($query);
903 +
904 + if(empty($query)){
905 + return;
906 + }
907 +
908 + foreach($query as $font){
909 + $meta_box_value = get_post_meta($font->ID, 'pagelayer_font_link', true);
910 + if(empty($meta_box_value)){
911 + continue;
912 + }
913 +
914 + echo '<style id="'.$font->post_name.'_plf" >@font-face { font-family: "'.$font->post_name.'_plf"'.'; src: url("'.$meta_box_value.'"); font-weight: 100 200 300 400 500 600 700 800 900;}</style>';
915 + }
916 +}
917 +
918 +// Load any header we have
919 +function pagelayer_global_js(){
920 + global $pagelayer;
921 +
922 + $pagelayer_recaptch_lang = get_option('pagelayer_google_captcha_lang');
923 + $pagelayer_recaptch_version = get_option('pagelayer_recaptcha_version', '');
924 +
925 + echo '<script>
926 +var pagelayer_ajaxurl = "'.admin_url( 'admin-ajax.php' ).'?";
927 +var pagelayer_global_nonce = "'.wp_create_nonce('pagelayer_global').'";
928 +var pagelayer_server_time = '.time().';
929 +var pagelayer_is_live = "'.pagelayer_is_live().'";
930 +var pagelayer_facebook_id = "'.get_option('pagelayer-fbapp-id').'";
931 +var pagelayer_settings = '.json_encode($pagelayer->settings).';
932 +var pagelayer_recaptch_lang = "'.(!empty($pagelayer_recaptch_lang) ? $pagelayer_recaptch_lang : '').'";
933 +var pagelayer_recaptch_version = "'.(!empty($pagelayer_recaptch_version) ? $pagelayer_recaptch_version : '').'";
934 +</script>';
935 +
936 +}
937 +
938 +// We need to handle global styles
939 +function pagelayer_load_global_css(){
940 + global $pagelayer;
941 +
942 + // Load CSS settings
943 + foreach($pagelayer->css_settings as $k => $params){
944 + $tmp_desk = '';
945 + foreach($pagelayer->screens as $sk => $sv){
946 + $suffix = (!empty($sv) ? '_'.$sv : '');
947 + $setting = empty($params['key']) ? 'pagelayer_'.$k.'_css' : $params['key'];
948 + $tmp = get_option($setting.$suffix);
949 +
950 + if($sk == 'desktop'){
951 + $tmp_desk = $tmp;
952 + }
953 +
954 + $tmp = pagelayer_sanitize_global_style($tmp, $tmp_desk, $sk);
955 +
956 + if(empty($tmp)){
957 + continue;
958 + }
959 +
960 + $pagelayer->css[$k.$suffix] = $tmp;
961 + }
962 + }
963 +
964 + // Backward compat for colors
965 + if(!empty($pagelayer->settings['color']['background']) && empty($pagelayer->css['body']['background-color'])){
966 + $pagelayer->css['body']['background-color'] = $pagelayer->settings['color']['background'];
967 + }
968 +
969 + if(!empty($pagelayer->settings['color']['text']) && empty($pagelayer->css['body']['color'])){
970 + $pagelayer->css['body']['color'] = $pagelayer->settings['color']['text'];
971 + }
972 +
973 + // Link Color
974 + if(!empty($pagelayer->settings['color']['link']) && empty($pagelayer->css['a']['color'])){
975 + $pagelayer->css['a']['color'] = $pagelayer->settings['color']['link'];
976 + }
977 +
978 + // Link Hover Color
979 + if(!empty($pagelayer->settings['color']['link-hover']) && empty($pagelayer->css['a-hover']['color'])){
980 + $pagelayer->css['a-hover']['color'] = $pagelayer->settings['color']['link-hover'];
981 + }
982 +
983 + // Headings Color
984 + if(!empty($pagelayer->settings['color']['heading'])){
985 + $htmp = ['h1', 'h2', 'h3', 'h4', 'h5', 'h6'];
986 + foreach($htmp as $k => $v){
987 + if(empty($pagelayer->css[$v]['color'])){
988 + $pagelayer->css[$v]['color'] = $pagelayer->settings['color']['heading'];
989 + }
990 + }
991 + }
992 +
993 + // Backward compat for body font
994 + if(!empty($pagelayer->settings['body_font'])){
995 + $pagelayer->settings['body']['font-family'] = $pagelayer->settings['body_font'];
996 + }
997 +}
998 +
999 +// We need to handle global styles
1000 +function pagelayer_global_styles(){
1001 +
1002 + global $pagelayer, $post;
1003 +
1004 + // Load css from settings
1005 + pagelayer_load_global_css();
1006 +
1007 + $styles = '<style id="pagelayer-wow-animation-style" type="text/css">.pagelayer-wow{visibility: hidden;}</style>
1008 + <style id="pagelayer-global-styles" type="text/css">'.PHP_EOL;
1009 +
1010 + $screen_style['tablet'] = '';
1011 + $screen_style['mobile'] = '';
1012 +
1013 + // PX suffix
1014 + $pxs = ['font-size', 'letter-spacing', 'word-spacing'];
1015 + $arrays = ['padding', 'margin'];
1016 +
1017 + $styles .= ':root{';
1018 +
1019 + // Set global colors
1020 + foreach($pagelayer->global_colors as $gk => $gv){
1021 + if (isset($gv['value'])) {
1022 + $styles .= '--pagelayer-color-'.$gk.':'.$gv['value'].';';
1023 + }
1024 + }
1025 +
1026 + // Set global fonts
1027 + foreach($pagelayer->global_fonts as $gk => $gv){
1028 +
1029 + if (empty($gv['value']) || !is_array($gv['value'])) {
1030 + continue;
1031 + }
1032 +
1033 + foreach($gv['value'] as $fk => $fv){
1034 +
1035 + if(empty($fv)){
1036 + continue;
1037 + }
1038 +
1039 + $unit = in_array($fk, $pxs) ? 'px' : '';
1040 +
1041 + if(is_array($fv)){
1042 + foreach($fv as $mode => $mv){
1043 +
1044 + if(empty($mv)){
1045 + continue;
1046 + }
1047 +
1048 + $font_css = '--pagelayer-font-'.$gk.'-'.$fk.':'.$mv.$unit.';';
1049 +
1050 + if($mode == 'tablet' || $mode == 'mobile'){
1051 + $screen_style[$mode] .= ':root{'.$font_css.'}';
1052 + continue;
1053 + }
1054 +
1055 + $styles .= $font_css;
1056 + }
1057 + continue;
1058 + }
1059 +
1060 + $styles .= '--pagelayer-font-'.$gk.'-'.$fk .':'.$fv.$unit.';';
1061 + }
1062 + }
1063 +
1064 + $styles .= '}'.PHP_EOL;
1065 +
1066 + // Style for only child row holder
1067 + $styles .= '.pagelayer-row-stretch-auto > .pagelayer-row-holder, .pagelayer-row-stretch-full > .pagelayer-row-holder.pagelayer-width-auto{ max-width: '.$pagelayer->settings['max_width'].'px; margin-left: auto; margin-right: auto;}'.PHP_EOL;
1068 +
1069 + if(!pagelayer_is_live() && !pagelayer_is_gutenberg_editor()){
1070 +
1071 + // Set responsive value
1072 + $styles .= '@media (min-width: '.($pagelayer->settings['tablet_breakpoint'] + 1).'px){
1073 + .pagelayer-hide-desktop{
1074 + display:none !important;
1075 + }
1076 + }
1077 +
1078 + @media (max-width: '.$pagelayer->settings['tablet_breakpoint'].'px) and (min-width: '.($pagelayer->settings['mobile_breakpoint'] + 1).'px){
1079 + .pagelayer-hide-tablet{
1080 + display:none !important;
1081 + }
1082 + .pagelayer-wp-menu-holder[data-drop_breakpoint="tablet"] .pagelayer-wp_menu-ul{
1083 + display:none;
1084 + }
1085 + }
1086 +
1087 + @media (max-width: '.$pagelayer->settings['mobile_breakpoint'].'px){
1088 + .pagelayer-hide-mobile{
1089 + display:none !important;
1090 + }
1091 + .pagelayer-wp-menu-holder[data-drop_breakpoint="mobile"] .pagelayer-wp_menu-ul{
1092 + display:none;
1093 + }
1094 + }'.PHP_EOL;
1095 +
1096 + }
1097 +
1098 + // Setup CSS as per post. This overright the global styles
1099 + foreach($pagelayer->css_settings as $k => $params){
1100 + $tmp_desk = '';
1101 + foreach($pagelayer->screens as $sk => $sv){
1102 + $suffix = (!empty($sv) ? '_'.$sv : '');
1103 + $setting = empty($params['key']) ? 'pagelayer_'.$k.'_css_'.@$post->post_type : $params['key'].'_'.@$post->post_type;
1104 + $tmp = get_option($setting.$suffix);
1105 +
1106 + if($sk == 'desktop'){
1107 + $tmp_desk = $tmp;
1108 + }
1109 +
1110 + $tmp = pagelayer_sanitize_global_style($tmp, $tmp_desk, $sk);
1111 +
1112 + if(empty($tmp)){
1113 + continue;
1114 + }
1115 +
1116 + if(!empty($pagelayer->css[$k.$suffix])){
1117 +
1118 + $typo_on = false;
1119 + $_typo = array();
1120 + $typo = $pagelayer->typo_props;
1121 +
1122 + // Check if all font properties are empty then we do not overright the global typo styles
1123 + foreach($typo as $prop){
1124 +
1125 + if(!empty($tmp[$prop])){
1126 + $typo_on = true;
1127 + }
1128 +
1129 + $_typo[$prop] = empty($tmp[$prop]) ? '' : $tmp[$prop];
1130 + }
1131 +
1132 + foreach($tmp as $tkk => $tvv){
1133 +
1134 + $tvv_is_empty = is_array($tvv) ? pagelayer_is_empty_array($tvv) : empty($tvv);
1135 +
1136 + // Skip update for empty value and if type is empty
1137 + if($tvv_is_empty || in_array($tkk, $typo)){
1138 + continue;
1139 + }
1140 +
1141 + $pagelayer->css[$k.$suffix][$tkk] = $tvv;
1142 + }
1143 +
1144 + if($typo_on){
1145 + $pagelayer->css[$k.$suffix] = array_merge($pagelayer->css[$k.$suffix], $_typo);
1146 + }
1147 +
1148 + continue;
1149 + }
1150 +
1151 + $pagelayer->css[$k.$suffix] = $tmp;
1152 + }
1153 + }
1154 +
1155 + // If is not loaded then the pagelayer_parse_vars, pagelayer_css_render not working
1156 + if(empty($pagelayer->customizer_params)){
1157 + pagelayer_load_shortcodes();
1158 + }
1159 +
1160 + // Customizer CSS
1161 + foreach($pagelayer->customizer_params as $prop => $param){
1162 +
1163 + if(empty($param['customizer_css']) || empty($param['css'])){
1164 + continue;
1165 + }
1166 +
1167 + if(!is_array($param['css'])){
1168 + $param['css'] = array($param['css']);
1169 + }
1170 +
1171 + $customize_el = array();
1172 + $customize_el['atts'] = $pagelayer->customizer_mods;
1173 +
1174 + // Get Image URL
1175 + $attachment = ($param['type'] == 'image') ? pagelayer_image(@$pagelayer->customizer_mods[$prop]) : '';
1176 +
1177 + if(!empty($attachment)){
1178 + foreach($attachment as $k => $v){
1179 + $customize_el['tmp'][$prop.'-'.$k] = $v;
1180 + }
1181 + }
1182 +
1183 + // Loop the modes and check for values
1184 + foreach($pagelayer->screens as $sk => $sv){
1185 +
1186 + $suffix = (!empty($sv) ? '_'.$sv : '');
1187 + $M_prop = $prop.$suffix;
1188 +
1189 + // Any value ?
1190 + if(empty($pagelayer->customizer_mods[$M_prop])){
1191 + continue;
1192 + }
1193 +
1194 + // Loop through
1195 + foreach($param['css'] as $k => $v){
1196 +
1197 + // Make the selector
1198 + $selector = (!is_numeric($k) && !empty($k) ? $k : 'body.pagelayer-body');
1199 +
1200 + // Make the CSS
1201 + $customize_css = $selector.'{'. rtrim( trim( pagelayer_css_render($v, $pagelayer->customizer_mods[$M_prop], @$param['sep']) ), ';' ) .'}' ;
1202 +
1203 + $customize_css = pagelayer_parse_vars($customize_css, $customize_el);
1204 +
1205 + if($sk == 'tablet'){
1206 + $screen_style['tablet'] .= $customize_css;
1207 + continue;
1208 + }
1209 +
1210 + if($sk == 'mobile'){
1211 + $screen_style['mobile'] .= $customize_css;
1212 + continue;
1213 + }
1214 +
1215 + $styles .= $customize_css;
1216 + }
1217 +
1218 + }
1219 + }
1220 +
1221 + // Loop CSS settings
1222 + foreach($pagelayer->css as $k => $v){
1223 +
1224 + $r = [];
1225 +
1226 + foreach($pagelayer->css[$k] as $kk => $vv){
1227 +
1228 + if(empty($vv)){
1229 + continue;
1230 + }
1231 +
1232 + if(in_array($kk, $arrays)){
1233 + $unit = 'px';
1234 +
1235 + if(!empty($vv['unit'])){
1236 + $unit = $vv['unit'];
1237 + unset($vv['unit']);
1238 + }
1239 +
1240 + $vv = array_filter($vv, function($value){ return !empty($value);});
1241 + if(empty($vv)){
1242 + continue;
1243 + }
1244 +
1245 + $skel = [0, 0, 0, 0];
1246 + $vv = array_replace($skel, $vv);
1247 + $vv = implode($unit.' ', $vv).$unit;
1248 + }
1249 +
1250 + $r[] = $kk.':'.$vv.(in_array($kk, $pxs) && strripos($vv, 'var(') === false ? 'px' : '');
1251 +
1252 + }
1253 +
1254 + if(empty($r)){
1255 + continue;
1256 + }
1257 +
1258 + $matches = [];
1259 + preg_match('/_(mobile|tablet)$/is', $k, $matches);
1260 + $key = str_replace(['_mobile', '_tablet'], '', $k);
1261 + $screen = isset($matches[1]) ? $matches[1] : '';
1262 +
1263 + //echo $key.' - '.$k;pagelayer_print($matches);
1264 +
1265 + $params = $pagelayer->css_settings[$key];
1266 +
1267 + $sel = !isset($params['sel']) ? ($key == 'body' ? '' : $key) : $params['sel'];
1268 +
1269 + $style = 'body.pagelayer-body '.$sel.'{'.implode(';', $r)."}\n";
1270 +
1271 + // Mobile or tablet ?
1272 + if(!empty($screen)){
1273 + $screen_style[$screen] .= $style;
1274 + }else{
1275 + $styles .= $style;
1276 + }
1277 + }
1278 +
1279 +// Tablet Styles
1280 +$styles .= '@media (max-width: '.$pagelayer->settings['tablet_breakpoint'].'px){
1281 + [class^="pagelayer-offset-"],
1282 + [class*=" pagelayer-offset-"] {
1283 + margin-left: 0;
1284 + }
1285 +
1286 + .pagelayer-row .pagelayer-col {
1287 + margin-left: 0;
1288 + width: 100%;
1289 + }
1290 + .pagelayer-row.pagelayer-gutters .pagelayer-col {
1291 + margin-bottom: 16px;
1292 + }
1293 + .pagelayer-first-sm {
1294 + order: -1;
1295 + }
1296 + .pagelayer-last-sm {
1297 + order: 1;
1298 + }
1299 +
1300 +'.$screen_style['tablet'].'
1301 +}'.PHP_EOL;
1302 +
1303 +// Any mobile style ?
1304 +if(!empty($screen_style['mobile'])){
1305 + $styles .= '@media (max-width: '.$pagelayer->settings['mobile_breakpoint'].'px){
1306 +'.$screen_style['mobile'].'}'.PHP_EOL;
1307 +}
1308 +
1309 + $styles .= PHP_EOL.'</style>';
1310 +
1311 + // Lets just build a temporary list of fonts so that we can add prefetch !
1312 + pagelayer_enqueue_fonts();
1313 +
1314 + if(!empty($pagelayer->runtime_fonts)){
1315 + echo '<link rel="dns-prefetch" href="https://fonts.gstatic.com">
1316 +<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin="anonymous">';
1317 + }
1318 +
1319 + echo $styles;
1320 +}
1321 +
1322 +function pagelayer_body_class($classes, $class){
1323 + $classes[] = 'pagelayer-body';
1324 + return $classes;
1325 +}
1326 +
1327 +// Load the live editor if needed
1328 +// Changed this hook wp_enqueue_scripts to Template_include to make block theme compatibility
1329 +add_action('template_include', 'pagelayer_load_live');
1330 +function pagelayer_load_live($template){
1331 +
1332 + global $post, $pagelayer;
1333 +
1334 + $pagelayer->load_live_errors = array();
1335 +
1336 + // If its not live editing then stop
1337 + if(!pagelayer_is_live_iframe($pagelayer->load_live_errors)){
1338 +
1339 + // Is it the live mode then lets throw an error ?
1340 + if(pagelayer_optreq('pagelayer-iframe')){
1341 + add_action('wp_head', 'pagelayer_load_live_errors', 999);
1342 + }
1343 +
1344 + return $template;
1345 + }
1346 +
1347 + // Are you allowed to edit ?
1348 + if(!pagelayer_user_can_edit($post->ID)){
1349 + return $template;
1350 + }
1351 +
1352 + // Load the editor class
1353 + include_once(PAGELAYER_DIR.'/main/live.php');
1354 +
1355 + // Call the constructor
1356 + $pl_editor = new PageLayer_LiveEditor();
1357 +
1358 + return $template;
1359 +}
1360 +
1361 +// Show the live errors if any
1362 +function pagelayer_load_live_errors(){
1363 +
1364 + global $post, $pagelayer;
1365 +
1366 + // Any errors ?
1367 + if(empty($pagelayer->load_live_errors)){
1368 + return;
1369 + }
1370 +
1371 + echo '<script>
1372 +alert("'.str_replace('"', '\\"', implode("\n", $pagelayer->load_live_errors)).'");
1373 +</script>';
1374 +
1375 +}
1376 +
1377 +// If we are doing ajax and its a pagelayer ajax
1378 +if(wp_doing_ajax()){
1379 + include_once(PAGELAYER_DIR.'/main/ajax.php');
1380 +}
1381 +
1382 +// Show the backend editor options
1383 +add_action('edit_form_after_title', 'pagelayer_after_title', 10);
1384 +function pagelayer_after_title(){
1385 +
1386 + global $post;
1387 +
1388 + // Get the current screen
1389 + $current_screen = get_current_screen();
1390 +
1391 + // For gutenberg
1392 + if(method_exists($current_screen, 'is_block_editor') && $current_screen->is_block_editor()){
1393 +
1394 + // Add the code in the footer
1395 + add_action('admin_footer', 'pagelayer_gutenberg_after_title');
1396 +
1397 + return;
1398 + }
1399 +
1400 + // Is pagelayer supposed to edit this ?
1401 + if(!pagelayer_user_can_edit($post)){
1402 + return;
1403 + }
1404 +
1405 + $link = pagelayer_shortlink($post->ID).'&pagelayer-live=1';
1406 +
1407 + echo '
1408 +<div id="pagelayer-editor-button-row" style="margin-top:15px; display:inline-block;">
1409 + <a id="pagelayer-editor-button" href="'.$link.'" class="button button-primary button-large" style="height:auto; padding:4px 8px; font-size:13px; display:flex; align-items:center; width: max-content;">
1410 + <img src="'.PAGELAYER_URL.'/images/pagelayer-logo-40.png" width="22" style="margin-right:4px" /> <span>'.__('Edit with Pagelayer').'</span>
1411 + </a>
1412 +</div>';
1413 +
1414 +}
1415 +
1416 +function pagelayer_gutenberg_after_title(){
1417 +
1418 + global $post;
1419 +
1420 + // Is pagelayer supposed to edit this ?
1421 + if(!pagelayer_user_can_edit($post)){
1422 + return;
1423 + }
1424 +
1425 + $link = pagelayer_shortlink($post->ID).'&pagelayer-live=1';
1426 +
1427 + echo '
1428 +<div id="pagelayer-editor-button-row" style="margin-left:15px; display:none">
1429 + <a id="pagelayer-editor-button" href="'.$link.'" class="button button-primary button-large" style="height:auto; font-size:13px; display:flex; align-items:center;width: max-content;">
1430 + <img src="'.PAGELAYER_URL.'/images/pagelayer-logo-40.png" align="top" width="22" style="margin-right:4px"/> <span>'.__('Edit with Pagelayer').'</span>
1431 + </a>
1432 +</div>
1433 +
1434 +<script type="text/javascript">
1435 +jQuery(document).ready(function(){
1436 +
1437 + var pagelayer_timer;
1438 + var pagelayer_button = function(){
1439 + var button = jQuery("#pagelayer-editor-button-row");
1440 + var g = jQuery(".edit-post-header-toolbar");
1441 + if(g.length < 1){
1442 + return;
1443 + }
1444 + button.detach();
1445 + //console.log(button);
1446 + g.parent().append(button);
1447 + button.show();
1448 + clearInterval(pagelayer_timer);
1449 + }
1450 + pagelayer_timer = setInterval(pagelayer_button, 100);
1451 +});
1452 +</script>';
1453 +
1454 +}
1455 +
1456 +// Handle Old Slug URL redirect for live link
1457 +add_filter( 'old_slug_redirect_url', 'pagelayer_old_slug_redirect', 10, 1);
1458 +function pagelayer_old_slug_redirect($link){
1459 +
1460 + if(pagelayer_optreq('pagelayer-live')){
1461 + $link = add_query_arg('pagelayer-live', '1', $link);
1462 + }
1463 +
1464 + return $link;
1465 +}
1466 +
1467 +// Clone Post
1468 +add_action('admin_action_pagelayer_clone_post', 'pagelayer_clone_post');
1469 +function pagelayer_clone_post(){
1470 +
1471 + // Nonce verification
1472 + check_admin_referer('pagelayer-options');
1473 +
1474 + // Get the original post id
1475 + $post_id = (int) $_REQUEST['post'];
1476 + $post = get_post( $post_id );
1477 +
1478 + // If post data exists, create the post clone
1479 + if(empty($post)){
1480 + wp_die('No post found');
1481 + }
1482 +
1483 + if(!current_user_can('edit_post', $post->ID)){
1484 + wp_die('You don\'t have access to clone this post.');
1485 + }
1486 +
1487 + $current_user = wp_get_current_user();
1488 + $new_post_author = $current_user->ID;
1489 +
1490 + unset($post->ID);
1491 + $post->post_author = $new_post_author;
1492 + $post->post_name = '';
1493 + $post->post_status = 'draft';
1494 + $post->post_title = $post->post_title.' Clone';
1495 + $post->post_date = '';
1496 + $post->post_date_gmt = '';
1497 + $post->guid = '';
1498 +
1499 + $new_post_id = wp_insert_post( $post );
1500 +
1501 + if(empty($new_post_id)){
1502 + wp_die('Post creation failed, could not find original post: ' . $post_id);
1503 + }
1504 +
1505 + // Get all current post terms and set them to the new post draft
1506 + $taxonomies = get_object_taxonomies($post->post_type);
1507 + foreach ($taxonomies as $taxonomy) {
1508 + $post_terms = wp_get_object_terms($post_id, $taxonomy, array('fields' => 'slugs'));
1509 + wp_set_object_terms($new_post_id, $post_terms, $taxonomy, false);
1510 + }
1511 +
1512 + // Clone all post meta info
1513 + $post_meta_infos = get_post_meta($post_id);
1514 + if (count($post_meta_infos) > 0) {
1515 + foreach ($post_meta_infos as $meta_key => $meta_value){
1516 + add_post_meta($new_post_id, $meta_key, wp_slash( maybe_unserialize($meta_value[0]) ));
1517 + }
1518 + }
1519 +
1520 + // Finally, redirect to the edit post screen for the new draft
1521 + wp_redirect( get_edit_post_link($new_post_id, '') );
1522 + exit;
1523 +
1524 +}
1525 +
1526 +// Add the clone link to action list for post_row_actions
1527 +add_filter('post_row_actions', 'pagelayer_clone_post_link', 10, 2);
1528 +add_filter('page_row_actions', 'pagelayer_clone_post_link', 10, 2);
1529 +function pagelayer_clone_post_link( $actions, $post ) {
1530 + if (current_user_can('edit_posts') && $post->post_status !== 'trash' && !defined('SITEPAD') && get_option('pagelayer_disable_clone') != 1) {
1531 + $actions['clone'] = '<a href="'.wp_nonce_url('admin.php?action=pagelayer_clone_post&post='.$post->ID, 'pagelayer-options') . '" rel="permalink">'.__( 'Clone', 'pagelayer') .'</a>';
1532 + }
1533 + return $actions;
1534 +}
1535 +
1536 +add_filter( 'post_row_actions', 'pagelayer_quick_link', 10, 2 );
1537 +add_filter( 'page_row_actions', 'pagelayer_quick_link', 10, 2 );
1538 +function pagelayer_quick_link($actions, $post){
1539 + global $pagelayer;
1540 +
1541 + // Some woocommerce pages are not having ID
1542 + if(empty($post->ID)){
1543 + return $actions;
1544 + }
1545 +
1546 + // Is pagelayer supposed to edit this ?
1547 + if(!pagelayer_user_can_edit($post)){
1548 + return $actions;
1549 + }
1550 +
1551 + $link = pagelayer_shortlink($post->ID).'&pagelayer-live=1';
1552 +
1553 + $actions['pagelayer'] = '<a href="'.esc_url( $link ).'">'.__( 'Edit using Pagelayer', 'pagelayer') .'</a>';
1554 +
1555 + return $actions;
1556 +}
1557 +
1558 +// Add settings link on plugin page
1559 +add_filter('plugin_action_links_pagelayer/pagelayer.php', 'pagelayer_plugin_action_links');
1560 +function pagelayer_plugin_action_links($links){
1561 +
1562 + if(!defined('PAGELAYER_PREMIUM')){
1563 + $links[] = '<a href="'.PAGELAYER_PRO_PRICE_URL.'" style="color:#3db634;" target="_blank">'._x('Go Pro', 'Upgrade to Pagelayer Pro for many more features', 'pagelayer').'</a>';
1564 + }
1565 +
1566 + $settings_link = '<a href="admin.php?page=pagelayer">Settings</a>';
1567 + array_unshift($links, $settings_link);
1568 +
1569 + return $links;
1570 +}
1571 +
1572 +// Add custom header
1573 +add_action('wp_head', 'pagelayer_add_custom_head', 102);
1574 +function pagelayer_add_custom_head(){
1575 + global $post;
1576 +
1577 + $global_code = wp_unslash( get_option('pagelayer_header_code') );
1578 +
1579 + if(!empty($post)){
1580 + $header_code = get_post_meta($post->ID , 'pagelayer_header_code', true);
1581 + }
1582 +
1583 + if(!empty($global_code)){
1584 + echo $global_code."\n";
1585 + }
1586 +
1587 + if(!empty($header_code)){
1588 + echo $header_code."\n";
1589 + }
1590 +
1591 +}
1592 +
1593 +// Add custom body
1594 +add_action('wp_body_open', 'pagelayer_body_open');
1595 +function pagelayer_body_open(){
1596 + global $post;
1597 +
1598 + $global_code = wp_unslash( get_option('pagelayer_body_open_code') );
1599 +
1600 + if(!empty($post)){
1601 + $body_code = get_post_meta($post->ID , 'pagelayer_body_open_code', true);
1602 + }
1603 +
1604 + if(!empty($global_code)){
1605 + echo $global_code."\n";
1606 + }
1607 +
1608 + if(!empty($body_code)){
1609 + echo $body_code."\n";
1610 + }
1611 +
1612 +}
1613 +
1614 +// Add custom footer
1615 +add_action('wp_footer', 'pagelayer_add_custom_footer');
1616 +function pagelayer_add_custom_footer(){
1617 + global $post, $pagelayer;
1618 +
1619 + if(!empty($pagelayer->localScript)){
1620 +
1621 + //Add local Script to variable to footer
1622 + wp_register_script('pagelayer-localScript', false, true);
1623 + wp_localize_script('pagelayer-localScript','pagelayer_local_scripts', $pagelayer->localScript);
1624 + wp_enqueue_script( 'pagelayer-localScript');
1625 + }
1626 +
1627 + if($pagelayer->append_yt_api){
1628 + wp_register_script('pagelayer-youtube-script',"https://www.youtube.com/iframe_api", array(), PAGELAYER_VERSION, true);
1629 + wp_enqueue_script('pagelayer-youtube-script');
1630 +
1631 + }
1632 +
1633 + $global_code = wp_unslash( get_option('pagelayer_footer_code') );
1634 +
1635 + if(!empty($post)){
1636 + $footer_code = get_post_meta($post->ID , 'pagelayer_footer_code', true);
1637 + }
1638 +
1639 + if(!empty($global_code)){
1640 + echo $global_code."\n";
1641 + }
1642 +
1643 + if(!empty($footer_code)){
1644 + echo $footer_code."\n";
1645 + }
1646 +
1647 +
1648 +}
1649 +
1650 +// Handle Logout Redirect here
1651 +add_action('wp_logout', 'pagelayer_after_logout');
1652 +function pagelayer_after_logout($user_id){
1653 +
1654 + // Get the URL
1655 + $url = get_user_option('pagelayer_logout_url', $user_id);
1656 +
1657 + // Now blank it
1658 + update_user_option($user_id, 'pagelayer_logout_url', '');
1659 +
1660 + // We will redirect if we have the given item set.
1661 + if(!empty($url)){
1662 + wp_redirect( $url );
1663 + exit();
1664 + }
1665 +
1666 +}
1667 +
1668 +// Replace Media
1669 +$pagelayer_media_replace = get_option( 'pagelayer_disable_media_replace');
1670 +if(empty($pagelayer_media_replace)){
1671 +
1672 +// Add URL to Replace Meda
1673 +add_filter('media_row_actions', 'pagelayer_add_media_action', 10, 2);
1674 +function pagelayer_add_media_action($actions, $post){
1675 +
1676 + $url = admin_url('upload.php');
1677 + $url = add_query_arg(array(
1678 + 'page' => 'pagelayer_replace_media',
1679 + 'id' => $post->ID,
1680 + ), $url);
1681 +
1682 + $actions['pagelayer_replace_media'] = '<a href="'.$url.'" rel="permalink">'.esc_html__('Replace media', 'pagelayer').'</a>';
1683 +
1684 + return $actions;
1685 +
1686 +}
1687 +
1688 +}
1689 +
1690 +// Replace Media Function
1691 +function pagelayer_replace_media(){
1692 +
1693 + include_once(PAGELAYER_DIR.'/main/replace-media.php');
1694 +
1695 + pagelayer_replace_page();
1696 +
1697 +}
1698 +
1699 +// Hide admin bar
1700 +add_action( 'init', 'pagelayer_hide_admin_bar');
1701 +function pagelayer_hide_admin_bar(){
1702 +
1703 + // Is it the live mode ?
1704 + if(!pagelayer_optreq('pagelayer-live', false) || !pagelayer_optreq('pagelayer-iframe', false)){
1705 + return false;
1706 + }
1707 +
1708 + show_admin_bar(false);
1709 +}
1710 +
1711 +// Check is gutenberg editor
1712 +function pagelayer_is_gutenberg_editor(){
1713 +
1714 + if(!function_exists('get_current_screen')){
1715 + return false;
1716 + }
1717 +
1718 + $screen = get_current_screen();
1719 +
1720 + if(empty($screen) || !method_exists($screen, 'is_block_editor')){
1721 + return false;
1722 + }
1723 +
1724 + return $screen->is_block_editor();
1725 +}
1726 +
1727 +// Pagelayer Template Loading Mechanism
1728 +include_once(PAGELAYER_DIR.'/main/template.php');
1729 +
1730 +// Convert Pagelayer widgets to gutenberg block
1731 +if(file_exists(PAGELAYER_DIR.'/main/blocks.php')){
1732 + include_once(PAGELAYER_DIR.'/main/blocks.php');
1733 +}