PluginProbe
Page Builder: Pagelayer – Drag and Drop website builder / 2.1.3
Page Builder: Pagelayer – Drag and Drop website builder v2.1.3
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
pagelayer / init.php

init.php in Page Builder: Pagelayer – Drag and Drop website builder 2.1.3, at init.php

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