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 | main/shortcode_functions.php +2024 -1844 2.1.62.2.0 View file →
@@ -1,1844 +1,2024 @@
1 -<?php
2 -
3 -//////////////////////////////////////////////////////////////
4 -//===========================================================
5 -// class.php
6 -//===========================================================
7 -// PAGELAYER
8 -// Inspired by the DESIRE to be the BEST OF ALL
9 -// ----------------------------------------------------------
10 -// Started by: Pulkit Gupta
11 -// Date: 23rd Jan 2017
12 -// Time: 23:00 hrs
13 -// Site: http://pagelayer.com/wordpress (PAGELAYER)
14 -// ----------------------------------------------------------
15 -// Please Read the Terms of use at http://pagelayer.com/tos
16 -// ----------------------------------------------------------
17 -//===========================================================
18 -// (c)Pagelayer Team
19 -//===========================================================
20 -//////////////////////////////////////////////////////////////
21 -
22 -// Are we being accessed directly ?
23 -if(!defined('PAGELAYER_VERSION')) {
24 - exit('Hacking Attempt !');
25 -}
26 -
27 -// Is there a block ?
28 -function pagelayer_render_blocks($pre_render, $parsed_block){
29 -
30 - global $pagelayer;
31 -
32 - if(empty($parsed_block)){
33 - return $pre_render;
34 - }
35 -
36 - $block_name = $parsed_block['blockName'];
37 - $tag = '';
38 - $content = $parsed_block['innerHTML'];
39 - $inner_blocks = array(
40 - 'blocks' => $parsed_block['innerBlocks'],
41 - 'content' => $parsed_block['innerContent']
42 - );
43 - $atts = $parsed_block['attrs'];
44 - $atts['is_not_sc'] = 1;
45 -
46 - if ( is_string( $block_name ) && 0 === strpos( $block_name, 'pagelayer/' ) ) {
47 - $tag = substr( $block_name, 10 );
48 - }
49 -
50 - $allowed_tags = ['pl_inner_row', 'pl_inner_col'];
51 -
52 - if( (empty($tag) || !array_key_exists($tag, $pagelayer->shortcodes) ) && ! in_array( $tag, $allowed_tags) ){
53 - return $pre_render;
54 - }
55 -
56 - return pagelayer_render_shortcode($atts, $content, $tag, $inner_blocks);
57 -}
58 -
59 -// Is there a tag ?
60 -function pagelayer_render_shortcode($atts, $content = '', $tag = '', $inner_blocks = array()){
61 -
62 - global $pagelayer;
63 -
64 - $is_block = 0;
65 - $el = [];
66 -
67 - // Is block ?
68 - if(!empty($atts['is_not_sc'])){
69 - $is_block = 1;
70 - unset($atts['is_not_sc']);
71 - }
72 -
73 - $_tag = $class = $tag;
74 - $final_tag = $tag;
75 -
76 - // Check if the tag is inner row and col then change it to row and col tag
77 - if($tag == 'pl_inner_row'){
78 - $tag = 'pl_row';
79 - }elseif($tag == 'pl_inner_col'){
80 - $tag = 'pl_col';
81 - $final_tag = $tag;
82 - }
83 -
84 - // Clear the pagelayer tags
85 - if(substr($tag, 0, 3) == 'pl_'){
86 - $_tag = str_replace('pl_', '', $final_tag);
87 - $class = 'pagelayer-'.$_tag;
88 - }
89 -
90 - if(empty($atts)){
91 - $atts = array();
92 - }else{
93 - $atts = (array) $atts;
94 - }
95 -
96 - // If global - > Get the post and replace $atts
97 - if(!empty($atts['global_id'])){
98 -
99 - if(!empty($pagelayer->global_widgets[$atts['global_id']])){
100 - $content = $pagelayer->global_widgets[$atts['global_id']]['$'];
101 - return pagelayer_change_id($content);
102 - }
103 -
104 - if(!empty($pagelayer->global_sections[$atts['global_id']])){
105 - $content = $pagelayer->global_sections[$atts['global_id']]['$'];
106 - return pagelayer_change_id($content);
107 - }
108 -
109 - // Set the global id as attr
110 - $el['attr'][] = 'pagelayer-global-id="'.$atts['global_id'].'"';
111 - }
112 -
113 - // Is there any function ?
114 - $func = pagelayer_isset($pagelayer->shortcodes[$tag], 'func');
115 -
116 - // If not, we will search for a default func if prefix of tag is pl_
117 - if(empty($func) && substr($tag, 0, 3) == 'pl_'){
118 - $func = 'pagelayer_sc_'.substr($tag, 3);
119 - }
120 -
121 - // UnescapeHTML for the attributes, Fix for old shortcode method
122 - if(empty($is_block)){
123 - $atts = array_map('pagelayer_unescapeHTML', $atts);
124 - }
125 -
126 - // Create the element array. NOTE : This is similar to the JS el and is temporary
127 - $el['atts'] = $atts;
128 - $el['oAtts'] = $atts;
129 - $el['id'] = !empty($atts['pagelayer-id']) ? $atts['pagelayer-id'] : pagelayer_create_id();
130 - $el['tmp'] = [];
131 - $el['tag'] = $final_tag;
132 - $el['content'] = $content;
133 - $el['inner_blocks'] = $inner_blocks;
134 - $el['selector'] = '[pagelayer-id="'.$el['id'].'"]';
135 - $el['cssSel'] = '.p-'.$el['id'];
136 - $el['wrap'] = '[pagelayer-wrap-id="'.$el['id'].'"]';
137 -
138 - // Remove pagelayer-id from attr
139 - if( !empty($atts['pagelayer-id']) ){
140 - unset($el['atts']['pagelayer-id']);
141 - unset($el['oAtts']['pagelayer-id']);
142 - }
143 -
144 - $innerHTML = pagelayer_isset($pagelayer->shortcodes[$tag], 'innerHTML');
145 - if(!empty($innerHTML) && !empty($content)){
146 - $el['oAtts'][$innerHTML] = $content;
147 - $el['atts'][$innerHTML] = $content;
148 - }
149 -
150 - // The default class
151 - $el['classes'][] = 'p-'.$el['id'];
152 - $el['classes'][] = $class;
153 -
154 - // Register hook to filter $el
155 - $el = apply_filters('pagelayer_do_shortcode_el', $el);
156 -
157 - //pagelayer_print($el);
158 -
159 - // Lets create the CSS, Classes, Attr. Also clean the dependent atts
160 - foreach($pagelayer->tabs as $tab){
161 -
162 - if(empty($pagelayer->shortcodes[$tag][$tab])){
163 - continue;
164 - }
165 -
166 - foreach($pagelayer->shortcodes[$tag][$tab] as $section => $Lsection){
167 -
168 - $props = empty($pagelayer->shortcodes[$tag][$section]) ? @$pagelayer->styles[$section] : @$pagelayer->shortcodes[$tag][$section];
169 -
170 - //echo $tab.' - '.$section.' - <br>';
171 -
172 - if(empty($props)){
173 - continue;
174 - }
175 -
176 - foreach($props as $prop => $param){
177 -
178 - //echo $tab.' - '.$section.' - '.$prop.'<br>';
179 -
180 - // Handle the edit fields
181 - if(!empty($param['edit'])){
182 - $el['edit'][$prop] = $param['edit'];
183 - }
184 -
185 - // No value set
186 - if(empty($el['atts'][$prop]) && empty($el['atts'][$prop.'_tablet']) && empty($el['atts'][$prop.'_mobile'])){
187 - continue;
188 - }
189 -
190 - // Clean the not required atts
191 - if(!empty($param['req'])){
192 -
193 - $set = true;
194 -
195 - foreach($param['req'] as $rk => $reqval){
196 - $except = $rk[0] == '!' ? true : false;
197 - $rk = $except ? substr($rk, 1) : $rk;
198 - $val = pagelayer_isset($el['atts'], $rk);
199 -
200 - //echo $prop.' - '.$rk.' : '.$reqval.' == '.$val.'<br>';
201 -
202 - // The value should not be there
203 - if($except){
204 -
205 - if(!is_array($reqval) && $reqval == $val){
206 - $set = false;
207 - break;
208 - }
209 -
210 - // Its an array and a value is found, then dont show
211 - if(is_array($reqval) && in_array($val, $reqval)){
212 - $set = false;
213 - break;
214 - }
215 -
216 - // The value must be equal
217 - }else{
218 -
219 - if(!is_array($reqval) && $reqval != $val){
220 - $set = false;
221 - break;
222 - }
223 -
224 - // Its an array and no value is found, then dont show
225 - if(is_array($reqval) && !in_array($val, $reqval)){
226 - $set = false;
227 - break;
228 - }
229 - }
230 -
231 - }
232 -
233 - // Unset as we dont need
234 - if(empty($set)){
235 - unset($el['atts'][$prop]);
236 - unset($el['atts'][$prop.'_tablet']);
237 - unset($el['atts'][$prop.'_mobile']);
238 - unset($el['tmp'][$prop]);
239 - unset($el['tmp'][$prop.'_tablet']);
240 - unset($el['tmp'][$prop.'_mobile']);
241 - }
242 -
243 - }
244 -
245 - // We could have unset the value above, so we need to check again if the value is there
246 - if(empty($el['atts'][$prop]) && empty($el['atts'][$prop.'_tablet']) && empty($el['atts'][$prop.'_mobile'])){
247 - continue;
248 - }
249 -
250 - // Load any attachment values - This should go on top in the newer version @TODO
251 - if( pagelayer_is_comment_mode() && !empty($param['edit']) && !(isset($param['ai']) && $param['ai'] === false) && !empty($el['atts'][$prop])){
252 - $el['atts'][$prop] = $el['oAtts'][$prop] = !empty($el['atts']['comment_atts'][$prop]) ? $el['atts']['comment_atts'][$prop] : $el['atts'][$prop];
253 - }
254 -
255 - // Any image are skipped
256 - if( pagelayer_is_comment_mode() && $param['type'] == 'image' && isset($el['atts']['comment_atts'][$prop])){
257 - $el['atts'][$prop.'_ai'] = $el['oAtts'][$prop.'_ai'] = $el['atts']['comment_atts'][$prop];
258 - }
259 -
260 - if(in_array($param['type'], ['image', 'video', 'audio', 'media'])){
261 -
262 - $attachment = ($param['type'] == 'image') ? pagelayer_image(@$el['atts'][$prop]) : pagelayer_attachment(@$el['atts'][$prop]);
263 -
264 - if(!empty($attachment)){
265 - foreach($attachment as $k => $v){
266 - $el['tmp'][$prop.'-'.$k] = $v;
267 - }
268 - }
269 -
270 - }
271 -
272 - // Load any attachment values - This should go on top in the newer version @TODO
273 - if($param['type'] == 'multi_image'){
274 -
275 - $img_ids = pagelayer_maybe_explode(',', $el['atts'][$prop]);
276 - $img_urls = [];
277 -
278 - // Make the image URL
279 - foreach($img_ids as $k => $v){
280 - $image = pagelayer_image($v);
281 - $img_urls['i'.$v] = @$image['url'];
282 - }
283 -
284 - $el['tmp'][$prop.'-urls'] = json_encode($img_urls);
285 - }
286 -
287 - // Backward compatibility of row
288 - if($el['tag'] == 'pl_row' && $prop == 'content_pos' && !empty($el['atts'][$prop])){
289 - if($el['atts'][$prop] == 'baseline'){
290 - $el['atts'][$prop] = $el['oAtts'][$prop] = 'flex-start';
291 - }else if($el['atts'][$prop] == 'end'){
292 - $el['atts'][$prop] = $el['oAtts'][$prop] = 'flex-end';
293 - }
294 - }
295 -
296 - // Backward compatibility of Icons
297 - if($param['type'] == 'icon' && !empty($el['atts'][$prop]) && !preg_match('/\s/', $el['atts'][$prop])){
298 - $el['atts'][$prop] = $el['oAtts'][$prop] = 'fa fa-'.$el['atts'][$prop];
299 - }
300 -
301 - // Backward compatibility of Box Shadow
302 - if($param['type'] == 'box_shadow' && !empty($el['atts'][$prop])){
303 - $shadow_atts = pagelayer_maybe_explode(',', $el['atts'][$prop]);
304 - if(count($shadow_atts) == 4){
305 - $shadow_atts[] = '0';
306 - $shadow_atts[] = '';
307 - $el['atts'][$prop] = $el['oAtts'][$prop] = $shadow_atts;
308 - }
309 - }
310 -
311 - // Backward compatibility of units. And also for the default set value if it is numeric
312 - if(!empty($param['units']) && isset($el['atts'][$prop]) && is_numeric($el['atts'][$prop])){
313 - $el['atts'][$prop] = $el['oAtts'][$prop] = $el['atts'][$prop].$param['units'][0];
314 - }
315 -
316 - // Load permalink values
317 - if($param['type'] == 'link'){
318 -
319 - $link = $el['atts'][$prop];
320 -
321 - if( is_array($el['atts'][$prop]) ){
322 -
323 - // Link is required for check IF and IF-EXT in html
324 - if(!isset($el['atts'][$prop]['link']) || strlen(trim($el['atts'][$prop]['link'])) < 1){
325 - $link = '';
326 - unset($el['atts'][$prop]);
327 - continue;
328 - }
329 -
330 - $link = $el['atts'][$prop]['link'];
331 -
332 - if(!empty($el['atts'][$prop]['target'])){
333 - $el['attr'][][$param['selector']] = 'target="_blank"';
334 - }
335 -
336 - if(!empty($el['atts'][$prop]['rel'])){
337 - $el['attr'][][$param['selector']] = 'rel="nofollow"';
338 - }
339 -
340 - if(!empty($el['atts'][$prop]['attrs'])){
341 -
342 - $atts_ar = pagelayer_string_to_attributes($el['atts'][$prop]['attrs']);
343 -
344 - if(!empty($atts_ar)){
345 - foreach($atts_ar as $att => $value){
346 - $el['attr'][][$param['selector']] = $att.'="'.esc_attr($value).'"';
347 - }
348 - }
349 - }
350 - }
351 -
352 - $el['tmp'][$prop] = esc_url(pagelayer_permalink($link));
353 - }
354 -
355 - // Handle the AddClasses
356 - if(!empty($param['addClass']) && !empty($el['atts'][$prop])){
357 -
358 - // Convert to an array
359 - if(!is_array($param['addClass'])){
360 - $param['addClass'] = array($param['addClass']);
361 - }
362 -
363 - // Loop through
364 - foreach($param['addClass'] as $k => $v){
365 - $k = str_replace('{{element}}', '', $k);
366 - $el['classes'][] = [trim($k) => str_replace('{{val}}', $el['atts'][$prop], $v)];
367 - }
368 -
369 - }
370 -
371 - // Handle the AddAttributes
372 - if(!empty($param['addAttr']) && !empty($el['atts'][$prop])){
373 -
374 - // Convert to an array
375 - if(!is_array($param['addAttr'])){
376 - $param['addAttr'] = array($param['addAttr']);
377 - }
378 -
379 - // Loop through
380 - foreach($param['addAttr'] as $k => $v){
381 - $k = str_replace('{{element}}', '', $k);
382 - $el['attr'][] = [trim($k) => $v];
383 - }
384 -
385 - }
386 -
387 - $modes = [
388 - 'desktop' => '',
389 - 'tablet' => '_tablet',
390 - 'mobile' => '_mobile'
391 - ];
392 -
393 - $global_typo = ($param['type'] == 'typography') ? pagelayer_is_global_typo(@$el['atts'][$prop]) : '';
394 -
395 - // Handle the CSS
396 - if(!empty($param['css'])){
397 - //echo $prop.'<br>';
398 - // Convert to an array
399 - if(!is_array($param['css'])){
400 - $param['css'] = array($param['css']);
401 - }
402 -
403 - // Loop the modes and check for values
404 - foreach($modes as $mk => $mv){
405 -
406 - $M_prop = $prop.$mv;
407 -
408 - $prop_val = pagelayer_isset($el['atts'], $M_prop);
409 -
410 - // If is global font
411 - if( $param['type'] == 'typography' && (!empty($prop_val) || !empty($global_typo)) ){
412 - $prop_val = pagelayer_parse_typo($prop_val, $global_typo, $mk);
413 - }
414 -
415 - // Any value ?
416 - if(empty($prop_val)){
417 - continue;
418 - }
419 -
420 - // Global color handler
421 - if($param['type'] == 'color'){
422 - $prop_val = pagelayer_parse_color($prop_val);
423 - }
424 -
425 - // If there is global gradient color
426 - if($param['type'] == 'gradient'){
427 -
428 - $prop_val = pagelayer_maybe_explode(',', $prop_val);
429 -
430 - foreach($prop_val as $grad_key => $grad_val){
431 -
432 - if($grad_val[0] != '$'){
433 - continue;
434 - }
435 -
436 - $prop_val[$grad_key] = pagelayer_parse_color($grad_val);
437 -
438 - }
439 -
440 - }
441 -
442 - // Loop through
443 - foreach($param['css'] as $k => $v){
444 -
445 - // Make the selector
446 - $selector = (!is_numeric($k) ? $k : $el['cssSel']);
447 - $selector = pagelayer_parse_el_vars($selector, $el);
448 -
449 - if($mk == 'tablet'){
450 - $selector = '|pl_tablet|'.$selector;
451 - }
452 -
453 - if($mk == 'mobile'){
454 - $selector = '|pl_mobile|'.$selector;
455 - }
456 -
457 - // Make the CSS
458 - if(!empty($selector)){
459 - $el['css'][$selector][] = rtrim( trim( pagelayer_css_render($v, $prop_val, pagelayer_isset($param, 'sep')) ), ';' );
460 - }else{
461 - $el['css'][][] = pagelayer_parse_el_vars($el['atts'][$M_prop],$el);
462 - }
463 - }
464 -
465 - }
466 -
467 - }
468 -
469 - $font_cache = '';
470 - // Loop the modes and check for values
471 - foreach($modes as $mk => $mv){
472 -
473 - $M_prop = $prop.$mv;
474 -
475 - if($param['type'] == 'typography' && !empty($el['atts'][$M_prop])){
476 -
477 - $prop_val = pagelayer_parse_typo($el['atts'][$M_prop], $global_typo, $mk);
478 -
479 - $val = pagelayer_maybe_explode(',', $prop_val);
480 -
481 - //For backward comaptibility
482 - if($mk == 'desktop'){
483 - $font_cache = $val[0];
484 - }
485 -
486 - $val[0] = empty($val[0]) ? $font_cache : $val[0];
487 -
488 - if(!empty($val[0])){
489 - pagelayer_load_font_family($val[0], pagelayer_isset($val, 3), pagelayer_isset($val, 2));
490 -
491 - //pagelayer_print($pagelayer->runtime_fonts);
492 - }
493 - }
494 -
495 - if($prop == 'font_family' && !empty($el['atts'][$M_prop])){
496 - $val = $el['atts'][$M_prop];
497 - if(!empty($val)){
498 - pagelayer_load_font_family($val, pagelayer_isset($el['atts'], 'font_weight'.$mv), pagelayer_isset($el['atts'], 'font_style'.$mv));
499 - }
500 - }
501 - }
502 - }
503 -
504 - }
505 -
506 - }
507 -
508 - //@pagelayer_print($el['css']);
509 -
510 - // Is there a function of the tag ?
511 - if(function_exists($func)){
512 - call_user_func_array($func, array(&$el));
513 - }
514 -
515 - // Create the default atts and tmp atts
516 - if(pagelayer_is_live()){
517 - pagelayer_create_sc($el, $is_block);
518 - }
519 -
520 - $div = '<div pagelayer-id="'.$el['id'].'">
521 -<style pagelayer-style-id="'.$el['id'].'"></style>';
522 -
523 - $is_group = !empty($pagelayer->shortcodes[$tag]['has_group']) ? true : false;
524 -
525 - // If there is an HTML AND you are not a GROUP, then make use of it, or append the real content
526 - if(!empty($pagelayer->shortcodes[$tag]['html'])){
527 -
528 - // Create the HTML object
529 - $node = pagelayerQuery::parseStr($pagelayer->shortcodes[$tag]['html']);
530 -
531 - // Remove the if-ext
532 - foreach($node('[if-ext]') as $v){
533 - $reqvar = pagelayer_var($v->attr('if-ext'));
534 - $v->removeAttr('if-ext');
535 -
536 - // Is the element there ?
537 - if(empty($el['atts'][$reqvar])){
538 - $ext_html = $v->html();
539 - if(strlen($ext_html) > 0){
540 - $v->after($ext_html);
541 - }
542 - $v->remove();
543 - }
544 - }
545 -
546 - // Remove the if
547 - foreach($node('[if]') as $v){
548 - $reqvar = pagelayer_var($v->attr('if'));
549 - $v->removeAttr('if');
550 -
551 - // Is the element there ?
552 - if(empty($el['atts'][$reqvar])){
553 - $v->remove();
554 - }
555 - }
556 -
557 - //die($node->html());
558 -
559 - // Do we have a holder ? Mainly for groups
560 - if(!empty($pagelayer->shortcodes[$tag]['holder'])){
561 - $node->query($pagelayer->shortcodes[$tag]['holder'])->html('{{pagelayer_do_shortcode}}');
562 - $do_shortcode = 1;
563 - }
564 -
565 - $html = pagelayer_parse_vars($node->html(), $el);
566 -
567 - // Append to the DIV
568 - $div .= $html;
569 -
570 - // Is it a widget ?
571 - }elseif(!empty($pagelayer->shortcodes[$tag]['widget'])){
572 -
573 - $class = $pagelayer->shortcodes[$tag]['widget'];
574 - $instance = [];
575 -
576 - // Is there any existing data ?
577 - if(!empty($el['atts']['widget_data'])){
578 - $json = trim($el['atts']['widget_data']);
579 - $json = json_decode($json, true);
580 - //pagelayer_print($json);die();
581 - if(!empty($json)){
582 - $instance = $json;
583 - }
584 - }
585 -
586 - ob_start();
587 - the_widget($class, $instance, array('widget_id'=>'arbitrary-instance-'.$el['id'],
588 - 'before_widget' => '',
589 - 'after_widget' => '',
590 - 'before_title' => '',
591 - 'after_title' => ''
592 - ));
593 -
594 - $div .= ob_get_contents();
595 - ob_end_clean();
596 -
597 - }else{
598 - $div .= '{{pagelayer_do_shortcode}}';
599 - $do_shortcode = 1;
600 - }
601 -
602 - // End the tag
603 - $div .= '</div>';
604 -
605 - // Add classes and attributes
606 - if(!empty($el['classes']) || !empty($el['attr']) || !empty($el['atts']['ele_attributes'])){
607 -
608 - // Create the HTML object
609 - $node = pagelayerQuery::parseStr($div);
610 -
611 - // Add the editable values
612 - if(!empty($el['edit']) && pagelayer_is_live()){
613 -
614 - foreach($el['edit'] as $k => $v){
615 - $node->query($v)->attr('pagelayer-editable', $k);
616 - }
617 -
618 - }
619 -
620 - // Add the post data editable
621 - if(pagelayer_is_live() && !empty($pagelayer->shortcodes[$tag]['edit_props']) && is_array($pagelayer->shortcodes[$tag]['edit_props'])){
622 -
623 - $edit_props = $pagelayer->shortcodes[$tag]['edit_props'];
624 -
625 - foreach($edit_props as $k => $v){
626 - $node->query($k)->attr('pagelayer-props-editable', $v);
627 - }
628 -
629 - }
630 -
631 - // Add the classes
632 - if(!empty($el['classes'])){
633 -
634 - //pagelayer_print($el['classes']);
635 -
636 - foreach($el['classes'] as $k => $v){
637 -
638 - if(!is_array($v)){
639 - $v = [$v];
640 - }
641 -
642 - foreach($v as $kk => $vv){
643 - //echo $kk.' - '.$vv."\n";
644 - if(is_numeric($kk)){
645 - $node->query($el['selector'])->addClass($vv);
646 - }else{
647 - $node->query($kk)->addClass($vv);
648 - }
649 -
650 - }
651 -
652 - }
653 -
654 - //echo $node->html();
655 - //die();
656 -
657 - }
658 -
659 - // Add the attributes
660 - if(!empty($el['attr'])){
661 -
662 - //pagelayer_print($el['attr']);
663 -
664 - foreach($el['attr'] as $k => $v){
665 -
666 - if(!is_array($v)){
667 - $v = [$v];
668 - }
669 -
670 - foreach($v as $kk => $vv){
671 -
672 - $att = explode('=', $vv, 2);
673 - $att[1] = pagelayer_parse_vars($att[1], $el);
674 - $att[1] = trim($att[1], '"');
675 -
676 - if(is_numeric($kk)){
677 - $node->query($el['selector'])->attr($att[0], $att[1]);
678 - }else{
679 - $node->query($kk)->attr($att[0], $att[1]);
680 - }
681 -
682 - }
683 -
684 - }
685 -
686 - }
687 -
688 - // Adding Custom Attributes
689 - if(!empty($el['atts']['ele_attributes'])){
690 -
691 - $val = pagelayer_string_to_attributes($el['atts']['ele_attributes']);
692 - if(!empty($val)){
693 - foreach($val as $att => $value ){
694 - $node->query($el['selector'])->attr($att, $value);
695 - }
696 - }
697 -
698 - }
699 -
700 - // Get font family form inline style
701 - foreach($node->query('[style]') as $snode){
702 - $ss = $snode->attr('style');
703 -
704 - if(strpos($ss, 'font-family') === false){
705 - continue;
706 - }
707 -
708 - $ss = explode(';', html_entity_decode($snode->attr('style')));
709 - foreach($ss as $sss){
710 -
711 - if(strpos($sss, 'font-family') === false){
712 - continue;
713 - }
714 -
715 - $ff = explode(':', $sss);
716 - $val = trim( trim($ff[1]), '"' );
717 - $fw = array('100', '100i', '200', '200i', '300', '300i', '400', '400i', '500', '500i', '600', '600i', '700', '700i', '800', '800i', '900', '900i');
718 -
719 - foreach($fw as $ww){
720 - $pagelayer->runtime_fonts[$val][$ww] = $ww;
721 - }
722 - }
723 - }
724 -
725 - $div = $node->html();
726 - //die($div);
727 -
728 - }
729 -
730 - // Add the CSS if any or remove it
731 - $style = '';
732 - if(!empty($el['css'])){
733 -
734 - $screen_style = array('tablet' => '', 'mobile' => '');
735 - $style = '<style pagelayer-style-id="'.$el['id'].'">';
736 - foreach($el['css'] as $ck => $cv){
737 - preg_match('/\|pl_(mobile|tablet)\|/is', $ck, $screen_matches);
738 - $ck = str_replace(['|pl_mobile|', '|pl_tablet|'], '', $ck);
739 - $media = pagelayer_isset($screen_matches, 1);
740 -
741 - $merge_css = implode(';', $cv);
742 - $combine_css = (!is_numeric($ck) ? $ck.'{'.$merge_css.'}' : $merge_css ).PHP_EOL;
743 -
744 - // Mobile or tablet ?
745 - if(!empty($media)){
746 - $screen_style[$media] .= $combine_css;
747 - continue;
748 - }
749 -
750 - $style .= $combine_css;
751 - }
752 -
753 - if(!empty($screen_style['tablet'])){
754 - $style .= '@media (max-width: '.$pagelayer->settings['tablet_breakpoint'].'px) and (min-width: '.($pagelayer->settings['mobile_breakpoint'] + 1).'px){'.$screen_style['tablet'].'}'.PHP_EOL;
755 - }
756 -
757 - if(!empty($screen_style['mobile'])){
758 - $style .= '@media (max-width: '.$pagelayer->settings['mobile_breakpoint'].'px){'.$screen_style['mobile'].'}'.PHP_EOL;
759 - }
760 -
761 - $style .= '</style>';
762 - $style = pagelayer_parse_vars($style, $el);
763 -
764 - if(!empty($pagelayer->shortcodes[$tag]['overide_css_selector'])){
765 - $overide_css_selector = pagelayer_parse_el_vars($pagelayer->shortcodes[$tag]['overide_css_selector'], $el);
766 - $style = str_replace($el['cssSel'], $overide_css_selector, $style);
767 - $style = str_replace($el['wrap'], $overide_css_selector, $style);
768 - }
769 -
770 - $style = pagelayer_unescapeHTML($style);
771 - }
772 -
773 - $div = str_replace('<style pagelayer-style-id="'.$el['id'].'"></style>', $style, $div);
774 -
775 - // Is there an inner content which requires a SHORTCODE ?
776 - if(!empty($do_shortcode)){
777 -
778 - $inner_content = pagelayer_render_inner_content($el);
779 -
780 - $div = str_replace('{{pagelayer_do_shortcode}}', $inner_content, $div);
781 - }
782 -
783 - // Sanitize the content
784 - $div = apply_filters( 'pagelayer_sanitize_do_shortcode', $div );
785 -
786 - return $div;
787 -
788 -}
789 -
790 -// Render inner content
791 -function pagelayer_render_inner_content(&$el){
792 -
793 - $inner_content = '';
794 -
795 - // Is block code?
796 - if( !empty($el['inner_blocks']) ){
797 -
798 - $index = 0;
799 -
800 - foreach ( $el['inner_blocks']['content'] as $chunk ) {
801 - if ( is_string( $chunk ) ) {
802 -
803 - // If any string in Column the conver this is text widget in pagelayer live
804 - if(!empty(trim($chunk)) && pagelayer_is_live() && $el['tag'] == 'pl_col'){
805 - $parsed_block['blockName'] = 'pagelayer/pl_text';
806 - $parsed_block['innerHTML'] = $chunk;
807 - $parsed_block['attrs'] = [];
808 - $inner_content .= render_block($parsed_block);
809 - continue;
810 - }
811 -
812 - $inner_content .= $chunk;
813 - continue;
814 - }
815 -
816 - $inner_block = $el['inner_blocks']['blocks'][ $index ];
817 - $inner_content .= render_block($inner_block);
818 - ++$index;
819 - }
820 - }else{
821 - $inner_content .= do_shortcode($el['content']);
822 - }
823 -
824 - return $inner_content;
825 -}
826 -
827 -// Change pagelayer id in html
828 -function pagelayer_change_id($content){
829 - global $pagelayer;
830 -
831 - preg_match_all('/pagelayer-id="(.*?)"/', $content, $matches);
832 - $matches = array_unique($matches[1]);
833 -
834 - foreach($matches as $val){
835 - $id = pagelayer_create_id();
836 - $content = str_replace($val, $id, $content);
837 - }
838 -
839 - return $content;
840 -}
841 -
842 -// Creates the shortcode and returns a base64 encoded files
843 -function pagelayer_create_sc(&$el, $is_block = 0){
844 -
845 - global $pagelayer;
846 -
847 - $a = $tmp = array();
848 -
849 - $pagelayer->data_attr[$el['id']] = ['attr' => $el['oAtts'], 'tmp' => $el['tmp']];
850 -
851 - /*if(!empty($el['oAtts'])){
852 -
853 - foreach($el['oAtts'] as $k => $v){
854 - $v = str_replace('&', '&amp;', $v);
855 - if($is_block){
856 - $v = pagelayer_escapeHTML($v);
857 - }
858 - $el['attr'][] = 'pagelayer-a-'.$k.'="'.$v.'"';
859 - }
860 -
861 - }
862 -
863 - // Tmp atts
864 - if(!empty($el['tmp'])){
865 -
866 - foreach($el['tmp'] as $k => $v){
867 - $v = str_replace('&', '&amp;', $v);
868 - if($is_block){
869 - $v = pagelayer_escapeHTML($v);
870 - }
871 - $el['attr'][] = 'pagelayer-tmp-'.$k.'="'.$v.'"';
872 - }
873 -
874 - }*/
875 -
876 - // Add the tag
877 - $el['attr'][] = 'pagelayer-tag="'.$el['tag'].'"';
878 -
879 - // Make it a Pagelayer element for editing
880 - $el['classes'][] = 'pagelayer-ele';
881 -
882 -}
883 -
884 -// Converts {{val}} to val
885 -function pagelayer_var($var){
886 - return substr($var, 2, -2);
887 -}
888 -
889 -// Is the given global color
890 -function pagelayer_is_global_typo($value){
891 - global $pagelayer;
892 -
893 - $typo_key = '';
894 -
895 - // Backward compatibility
896 - if(is_string($value) && $value[0] == '$'){
897 - $typo_key = substr($value, 1);
898 - }
899 -
900 - if(is_array($value) && isset($value['global-font'])){
901 - $typo_key = $value['global-font'];
902 - }
903 -
904 - // If global color not exist
905 - if(!empty($typo_key)){
906 - $typo_key = isset($pagelayer->global_fonts[$typo_key]) ? $typo_key : 'primary';
907 - }
908 -
909 - return $typo_key;
910 -
911 -}
912 -
913 -// Parse typography and handle Backward compatibility
914 -function pagelayer_parse_typo($value, $desk_global = '', $mk = 'desktop'){
915 - global $pagelayer;
916 -
917 - $value = empty($value)? [] : $value;
918 -
919 - // Backward compatibility for comma seperated val
920 - if(!is_array($value) && $value[0] != '$'){
921 - return $value;
922 - }
923 -
924 - $val = ['','','','','','','','','','',''];
925 - $global_typo = pagelayer_is_global_typo($value);
926 - $_desk_global = false;
927 -
928 - if( empty($global_typo) ){
929 - $global_typo = $desk_global;
930 - $_desk_global = true;
931 - }
932 -
933 - // Apply global typo
934 - foreach($pagelayer->typo_props as $typo => $typo_key){
935 -
936 - // Backspace compatibility for normal array and if is set global in '$' format like $primary
937 - if(is_array($value) && !empty($value[$typo])){
938 - $val[$typo] = $value[$typo];
939 - }
940 -
941 - if(!empty($value[$typo_key])){
942 - $val[$typo] = $value[$typo_key];
943 - }
944 -
945 - if(!empty($val[$typo]) || empty($global_typo)){
946 - continue;
947 - }
948 -
949 - $global_val = $pagelayer->global_fonts[$global_typo]['value'];
950 -
951 - if( empty($global_val[$typo_key]) || (is_array($global_val[$typo_key]) && empty($global_val[$typo_key][$mk])) || (!is_array($global_val[$typo_key]) && !empty($_desk_global) && $mk != 'desktop') ){
952 - continue;
953 - }
954 -
955 - $val[$typo] = 'var(--pagelayer-font-'.$global_typo.'-'.$typo_key.')';
956 - }
957 -
958 - return $val;
959 -}
960 -
961 -// Parse color for global color
962 -function pagelayer_parse_color($value, $var = true){
963 - global $pagelayer;
964 -
965 - // Global color handler
966 - if($value[0] != '$' ){
967 - return $value;
968 - }
969 -
970 - $gkey = substr($value, 1);
971 - $gkey = isset($pagelayer->global_colors[$gkey]) ? $gkey : 'primary';
972 -
973 - if(empty($var)){
974 - return @$pagelayer->global_colors[$gkey]['value'];
975 - }
976 -
977 - return 'var(--pagelayer-color-'.$gkey.')';
978 -}
979 -
980 -// Replace the variables
981 -function pagelayer_parse_el_vars($str, &$el){
982 -
983 - global $pagelayer, $post;
984 -
985 - // if is 404 then @$post->ID
986 - if(!empty( $pagelayer->rendering_template_id ) && @$post->ID != $pagelayer->rendering_template_id){
987 - $is_editable = false;
988 - }else{
989 - $is_editable = true;
990 - }
991 -
992 - $str = str_replace('{{element}}', $el['cssSel'], $str);
993 - $is_live = pagelayer_is_live();
994 - if(!empty($is_live) && $is_editable){
995 - $str = str_replace('{{wrap}}', $el['wrap'], $str);
996 - }else{
997 - $str = str_replace('{{wrap}}', $el['cssSel'], $str);
998 - }
999 - $str = str_replace('{{ele_id}}', $el['id'], $str);
1000 -
1001 - return $str;
1002 -
1003 -}
1004 -
1005 -// Parse the variables
1006 -function pagelayer_parse_vars($str, &$el){
1007 -
1008 - if(empty($str)){
1009 - return $str;
1010 - }
1011 -
1012 - //pagelayer_print($el);
1013 - if(!empty($el['tmp']) && is_array($el['tmp'])){
1014 - foreach($el['tmp'] as $k => $v){
1015 - $str = str_replace('{{{'.$k.'}}}', pagelayer_maybe_implode($el['tmp'][$k]), $str);
1016 - }
1017 - }
1018 -
1019 - if(is_array($el['atts'])){
1020 - foreach($el['atts'] as $k => $v){
1021 - $str = str_replace('{{'.$k.'}}', pagelayer_maybe_implode($el['atts'][$k]), $str);
1022 - }
1023 - }
1024 -
1025 - return $str;
1026 -}
1027 -
1028 -// Make the rule
1029 -function pagelayer_css_render($rule, $val, $sep = ','){
1030 -
1031 - // Seperator
1032 - $sep = empty($sep) ? ',' : $sep;
1033 -
1034 - if(is_array($val)){
1035 - $val = implode($sep, $val);
1036 - }
1037 -
1038 - // Replace the val
1039 - $rule = pagelayer_css_val_replace('{{val}}', pagelayer_hex8_to_rgba($val), $rule);
1040 -
1041 - // If there is an array
1042 - if(preg_match('/\{val\[\d/is', $rule)){
1043 - $val = explode($sep, $val);
1044 - foreach($val as $k => $v){
1045 - $rule = pagelayer_css_val_replace('{{val['.$k.']}}', pagelayer_hex8_to_rgba($v), $rule);
1046 - }
1047 - }
1048 -
1049 - return $rule;
1050 -}
1051 -
1052 -// Make the rule
1053 -function pagelayer_css_val_replace($val, $v, $rule){
1054 -
1055 - // If value has css var then we remove units
1056 - if(strripos($v, 'var(') !== false){
1057 - $pattern = '/'.preg_quote($val, '/').'?[^\s|;]+/is';
1058 - $rule = preg_replace($pattern, $v, $rule);
1059 - return $rule;
1060 - }
1061 -
1062 - $rule = str_replace($val, $v, $rule);
1063 - return $rule;
1064 -}
1065 -
1066 -// Post Property Handler
1067 -function pagelayer_sc_post_props(&$el){
1068 -
1069 - global $post;
1070 -
1071 - if(empty($post)){
1072 - return;
1073 - }
1074 -
1075 - $el['oAtts']['post_title'] = $post->post_title;
1076 - $el['oAtts']['post_name'] = $post->post_name;
1077 - $el['oAtts']['post_excerpt'] = $post->post_excerpt;
1078 - $el['oAtts']['post_status'] = (empty($post->post_password)) ? $post->post_status : 'pass_protected';
1079 - $el['oAtts']['post_password'] = $post->post_password;
1080 - $el['oAtts']['featured_image'] = get_post_thumbnail_id($post);
1081 - $el['oAtts']['comment_status'] = ($post->comment_status == 'open') ? 'true' : '';
1082 - $el['oAtts']['ping_status'] = ($post->ping_status == 'open') ? 'true' : '';
1083 - $el['oAtts']['post_date'] = $post->post_date;
1084 - $el['oAtts']['post_sticky'] = is_sticky($post->ID) ? 'true' : '';
1085 - $el['oAtts']['post_parent'] = $post->post_parent;
1086 - $el['oAtts']['menu_order'] = $post->menu_order;
1087 - $el['oAtts']['post_author'] = $post->post_author;
1088 - $el['oAtts']['post_category'] = '';
1089 - $el['oAtts']['post_tags'] = '';
1090 -
1091 - $tag_name = pagelayer_post_type_tag($post->post_type);
1092 - if(!empty($tag_name)){
1093 - $postTags = wp_get_post_terms( $post->ID, $tag_name );
1094 - $el['oAtts']['post_tags'] = array_column((array)$postTags, 'name');
1095 - }
1096 -
1097 - $cat_name = pagelayer_post_type_category($post->post_type);
1098 - if(!empty($cat_name)){
1099 - $category = get_the_terms( $post->ID, $cat_name );
1100 - $el['oAtts']['post_category'] = array_column((array)$category, 'term_id');
1101 - }
1102 -
1103 - // Load featured image details
1104 - if(!empty($el['oAtts']['featured_image'])){
1105 -
1106 - $attachment = pagelayer_image($el['oAtts']['featured_image']);
1107 -
1108 - if(!empty($attachment)){
1109 - foreach($attachment as $k => $v){
1110 - $el['tmp']['featured_image-'.$k] = $v;
1111 - }
1112 - }
1113 -
1114 - }
1115 -
1116 -}
1117 -
1118 -// ROW Handler
1119 -function pagelayer_sc_row(&$el){
1120 -
1121 - pagelayer_bg_video($el);
1122 -
1123 - if(!empty($el['atts']['row_shape_type_top'])){
1124 - $path_top = PAGELAYER_DIR.'/images/shapes/'.$el['atts']['row_shape_type_top'].'-top.svg';
1125 - $el['atts']['svg_top'] = file_get_contents($path_top);
1126 - }
1127 -
1128 - if(!empty($el['atts']['row_shape_type_bottom'])){
1129 - $path_bottom = PAGELAYER_DIR.'/images/shapes/'.$el['atts']['row_shape_type_bottom'].'-bottom.svg';
1130 - $el['atts']['svg_bottom'] = file_get_contents($path_bottom);
1131 - }
1132 -
1133 - // Row background slider
1134 - if(!empty($el['atts']['bg_slider'])){
1135 - $ids = pagelayer_maybe_explode(',', $el['atts']['bg_slider']);
1136 - $urls = [];
1137 - $el['atts']['slider'] = '';
1138 -
1139 - // Make the image URL
1140 - foreach($ids as $k => $v){
1141 -
1142 - $image = pagelayer_image($v);
1143 - $urls['i'.$v] = @$image['url'];
1144 -
1145 - $el['atts']['slider'] .= '<div class="pagelayer-bgimg-slide" style="background-image:url(\''.$image['url'].'\')"></div>';
1146 -
1147 - }
1148 -
1149 - if(!empty($urls)){
1150 - $el['tmp']['bg_slider-urls'] = json_encode($urls);
1151 - }
1152 -
1153 - }
1154 -
1155 - // Row background parallax image.
1156 - if(!empty($el['atts']['parallax_img'])){
1157 - $img_size = @$el['tmp']['parallax_img-'.$el['atts']['parallax_id_size'].'-url'];
1158 - $el['atts']['parallax_img_src'] = empty($img_size) ? @$el['tmp']['parallax_img-url'] : $img_size;
1159 - }
1160 -
1161 -}
1162 -
1163 -// Column Handler
1164 -function pagelayer_sc_col(&$el){
1165 -
1166 - // Add the default col class
1167 - $el['classes'][] = 'pagelayer-col';
1168 -
1169 - //return do_shortcode($el['content']);
1170 -
1171 - pagelayer_bg_video($el);
1172 -
1173 - // Column background slider
1174 - if(!empty($el['atts']['bg_slider'])){
1175 - $ids = pagelayer_maybe_explode(',', $el['atts']['bg_slider']);
1176 - $urls = [];
1177 - $el['atts']['slider'] = '';
1178 -
1179 - // Make the image URL
1180 - foreach($ids as $k => $v){
1181 -
1182 - $image = pagelayer_image($v);
1183 - $urls['i'.$v] = @$image['url'];
1184 -
1185 - $el['atts']['slider'] .= '<div class="pagelayer-bgimg-slide" style="background-image:url(\''.$image['url'].'\')"></div>';
1186 -
1187 - }
1188 -
1189 - if(!empty($urls)){
1190 - $el['tmp']['bg_slider-urls'] = json_encode($urls);
1191 - }
1192 -
1193 - }
1194 -
1195 - // Col background parallax image.
1196 - if(!empty($el['atts']['parallax_img'])){
1197 - $img_size = @$el['tmp']['parallax_img-'.$el['atts']['parallax_id_size'].'-url'];
1198 - $el['atts']['parallax_img_src'] = empty($img_size) ? @$el['tmp']['parallax_img-url'] : $img_size;
1199 - }
1200 -
1201 -}
1202 -
1203 -// Just for BG handling
1204 -function pagelayer_bg_video(&$el){
1205 -
1206 - if(empty($el['tmp']['bg_video_src-url'])){
1207 - return false;
1208 - }
1209 -
1210 - // Get the video URL for the iframe
1211 - $iframe_atts = pagelayer_video_url($el['tmp']['bg_video_src-url'], true);
1212 -
1213 - $source = esc_url( $el['tmp']['bg_video_src-url'] );
1214 - $source = str_replace('&amp;', '&', $source);
1215 - $url = parse_url($source);
1216 -
1217 - $iframe_atts['src'] .= substr_count($iframe_atts['src'], '?') > 0 ? '' : '?';
1218 -
1219 - if(!empty($el['atts']['mute'])){
1220 - $iframe_atts['src'] .= "&mute=1";
1221 - $el['atts']['mute'] = " muted ";
1222 - }else{
1223 - $iframe_atts['src'] .= "&mute=0";
1224 - $el['atts']['mute'] = "";
1225 - }
1226 -
1227 - if(empty($el['atts']['stop_loop'])){
1228 - $iframe_atts['src'] .= "&loop=1";
1229 - $el['atts']['stop_loop'] = " loop ";
1230 - }else{
1231 - $iframe_atts['src'] .= "&loop=0";
1232 - $el['atts']['stop_loop'] = "";
1233 - }
1234 -
1235 - if (!empty($source)) {
1236 -
1237 - if ($iframe_atts['type'] == 'youtube') {
1238 -
1239 - $settings = ' data-loop="'.( !empty($el['atts']['stop_loop']) ? 1 : 0 ).'" data-mute="'.( !empty($el['atts']['mute']) ? 1 : 0 ).'" data-videoid = "'.( $iframe_atts['id'] ).'"';
1240 -
1241 - $el['atts']['vid_src'] = '<div class = "pagelayer-youtube-video" '. $settings .'></div>';
1242 -
1243 - } else if ($iframe_atts['type'] == 'vimeo') {
1244 -
1245 - $el['atts']['vid_src'] = '<iframe src="'.$iframe_atts['src'].'&background=1&autoplay=1&byline=0&title=0" allowfullscreen="1" webkitallowfullscreen="1" mozallowfullscreen="1" frameborder="0"></iframe>';
1246 -
1247 - }else{
1248 -
1249 - $el['atts']['vid_src'] = '<video autoplay playsinline '.$el['atts']['mute'].$el['atts']['stop_loop'].'>'.
1250 - '<source src="'.$iframe_atts['src'].'" type="video/mp4">'.
1251 - '</video>';
1252 -
1253 - }
1254 - }
1255 -}
1256 -
1257 -// Heading Handler
1258 -function pagelayer_sc_heading(&$el){
1259 - //Backward compatibility for new link props
1260 - pagelayer_add_link_backward($el, array('rel' => '', 'selector' => '.pagelayer-link-sel'));
1261 -}
1262 -
1263 -// Heading Handler
1264 -function pagelayer_sc_icon(&$el){
1265 - //Backward compatibility for new link props
1266 - pagelayer_add_link_backward($el, array('rel' => '', 'selector' => '.pagelayer-ele-link'));
1267 -}
1268 -
1269 -// Heading Handler
1270 -function pagelayer_sc_badge(&$el){
1271 - //Backward compatibility for new link props
1272 - pagelayer_add_link_backward($el, array(
1273 - 'link' => 'badge_url',
1274 - 'rel' => '',
1275 - 'target' => 'badge_target',
1276 - 'selector' => '.pagelayer-ele-link'
1277 - ));
1278 -}
1279 -
1280 -// Heading Handler
1281 -function pagelayer_sc_btn(&$el){
1282 - //Backward compatibility for new link props
1283 - pagelayer_add_link_backward($el, array('selector' => '.pagelayer-btn-holder'));
1284 -}
1285 -
1286 -// Image Handler
1287 -function pagelayer_sc_social(&$el){
1288 -
1289 - //Backward compatibility for new link props
1290 - pagelayer_add_link_backward($el, array(
1291 - 'link' => 'social_url',
1292 - 'rel' => '',
1293 - 'selector' => '.pagelayer-ele-link'
1294 - ));
1295 -
1296 - if(empty($el['atts']['icon'])) return;
1297 - $icon = explode(' fa-', $el['atts']['icon']);
1298 - $el['classes'][] = ['.pagelayer-icon-holder' => 'pagelayer-'.$icon[1]];
1299 -}
1300 -
1301 -// Image Handler
1302 -function pagelayer_sc_image(&$el){
1303 -
1304 - // Decide the image URL
1305 - $el['atts']['func_id'] = @$el['tmp']['id-'.$el['atts']['id-size'].'-url'];
1306 - $el['atts']['func_id'] = empty($el['atts']['func_id']) ? @$el['tmp']['id-url'] : $el['atts']['func_id'];
1307 - $el['atts']['pagelayer-srcset'] = $el['atts']['func_id'].', '.$el['atts']['func_id'].' 1x, ';
1308 -
1309 - $image_atts = array(
1310 - 'name' => 'id',
1311 - 'size' => 'id-size'
1312 - );
1313 -
1314 - pagelayer_get_img_srcset($el, $image_atts);
1315 -
1316 - // What is the link ?
1317 - if(!empty($el['atts']['link_type'])){
1318 -
1319 - // Custom url
1320 - if($el['atts']['link_type'] == 'custom_url'){
1321 -
1322 - // Backward compatibility for new link props
1323 - pagelayer_add_link_backward($el, array( 'rel' => '', 'selector' => '.pagelayer-ele-link'));
1324 -
1325 - $el['atts']['func_link'] = @$el['tmp']['link'];
1326 - }
1327 -
1328 - // Link to the media file itself
1329 - if($el['atts']['link_type'] == 'media_file'){
1330 - $el['atts']['func_link'] = $el['atts']['func_id'];
1331 - }
1332 -
1333 - // Lightbox
1334 - if($el['atts']['link_type'] == 'lightbox'){
1335 - $el['atts']['func_link'] = $el['atts']['func_id'];
1336 - }
1337 -
1338 - }
1339 -
1340 - //pagelayer_print($el);
1341 -
1342 -}
1343 -
1344 -// Image Slider Handler
1345 -function pagelayer_sc_image_slider(&$el){
1346 -
1347 - // Backward compatibility for new link props
1348 - if( !empty($el['atts']['link_type']) && $el['atts']['link_type'] == 'custom_url' ){
1349 - pagelayer_add_link_backward($el, array( 'rel' => '', 'selector' => '.pagelayer-link-sel'));
1350 - }
1351 -
1352 - if(empty($el['atts']['ids'])){
1353 - $el['atts']['ids'] = '';
1354 - }
1355 -
1356 - $ids = pagelayer_maybe_explode(',', $el['atts']['ids']);
1357 - $urls = [];
1358 - $all_urls = [];
1359 - $final_urls = [];
1360 - $ul = [];
1361 - $size = $el['atts']['size'];
1362 -
1363 - // Make the image URL
1364 - foreach($ids as $k => $v){
1365 -
1366 - $image = pagelayer_image($v);
1367 -
1368 - $final_urls[$v] = empty($image[$size.'-url']) ? @$image['url'] : $image[$size.'-url'];
1369 -
1370 - $urls['i'.$v] = @$image['url'];
1371 -
1372 - foreach($image as $kk => $vv){
1373 - $si = strstr($kk, '-url', true);
1374 - if(!empty($si)){
1375 - $all_urls['i'.$v][$si] = $vv;
1376 - }
1377 - }
1378 -
1379 - $li = '<li class="pagelayer-slider-item">';
1380 -
1381 - // Any Link ?
1382 - if(!empty($el['atts']['link_type'])){
1383 - $link = ($el['atts']['link_type'] == 'media_file' ? (!empty($image['url']) ? $image['url'] : $final_urls[$v]) : @$el['tmp']['link']);
1384 - $li .= '<a href="'.$link.'" class="pagelayer-link-sel">';
1385 - }
1386 -
1387 - // The Image
1388 - $li .= '<img class="pagelayer-img" src="'.$final_urls[$v].'" title="'.$image['title'].'" alt="'.$image['alt'].'">';
1389 -
1390 - if(!empty($el['atts']['link_type'])){
1391 - $li .= '</a>';
1392 - }
1393 -
1394 - $li .= '</li>';
1395 -
1396 - $ul[] = $li;
1397 -
1398 - }
1399 -
1400 - //pagelayer_print($urls);
1401 - //pagelayer_print($final_urls);
1402 - //pagelayer_print($all_urls);
1403 -
1404 - // Make the TMP vars
1405 - if(!empty($urls)){
1406 - $el['tmp']['ids-urls'] = json_encode($urls);
1407 - $el['tmp']['ids-all-urls'] = json_encode($all_urls);
1408 - $el['atts']['ul'] = implode('', $ul);
1409 -
1410 - // Which arrows to show
1411 - if(in_array(@$el['atts']['controls'], ['arrows', 'none'])){
1412 - $el['attr'][] = ['.pagelayer-image-slider-ul' => 'data-pager="false"'];
1413 - }
1414 -
1415 - if(in_array(@$el['atts']['controls'], ['pager', 'none'])){
1416 - $el['attr'][] = ['.pagelayer-image-slider-ul' => 'data-controls="false"'];
1417 - }
1418 - }
1419 -
1420 -};
1421 -
1422 -//Grid Gallery Handler
1423 -function pagelayer_sc_grid_gallery(&$el){
1424 -
1425 - if(empty($el['atts']['ids'])){
1426 - $el['atts']['ids'] = '';
1427 - }
1428 -
1429 - $ids = pagelayer_maybe_explode(',', $el['atts']['ids']);
1430 - $urls = [];
1431 - $all_urls = [];
1432 - $final_urls = [];
1433 - $ul = [];
1434 - $pagin = '<li class="pagelayer-grid-page-item active">1</li>';
1435 - $size = $el['atts']['size'];
1436 - $i = 0;
1437 - $j = 1;
1438 - $img_Page = $el['atts']['images_no'];
1439 - $gallery_rand = 'gallery-id-'.floor((rand() * 100) + 1);
1440 -
1441 - $ul[] = '<ul class="pagelayer-grid-gallery-ul">';
1442 - // Make the image URL
1443 - foreach($ids as $k => $v){
1444 -
1445 - $image = pagelayer_image($v);
1446 -
1447 - $final_urls[$v] = empty($image[$size.'-url']) ? @$image['url'] : $image[$size.'-url'];
1448 -
1449 - $urls['i'.$v] = @$image['url'];
1450 - $links['i'.$v] = @$image['link'];
1451 - $titles['i'.$v] = @$image['title'];
1452 - $captions['i'.$v] = @$image['caption'];
1453 -
1454 - foreach($image as $kk => $vv){
1455 - $si = strstr($kk, '-url', true);
1456 - if(!empty($si)){
1457 - $all_urls['i'.$v][$si] = $vv;
1458 - }
1459 - }
1460 -
1461 - if($img_Page != 0 && ($i % $img_Page) == 0 && $i != 0 ){
1462 - $ul[] = '</ul><ul class="pagelayer-grid-gallery-ul">';
1463 - $j++;
1464 - $pagin .= '<li class="pagelayer-grid-page-item">'.$j.'</li>';
1465 - }
1466 -
1467 - $li = '<li class="pagelayer-gallery-item" >';
1468 -
1469 - if(empty($el['atts']['link_to'])){
1470 - $li .= '<div>';
1471 - }
1472 -
1473 - // Any Link ?
1474 - if(!empty($el['atts']['link_to']) && $el['atts']['link_to'] == 'media_file'){
1475 - $link = ($el['atts']['link_to'] == 'media_file' ? $final_urls[$v] : @$el['atts']['link']);
1476 - $li .= '<a href="'.$link.'" class="pagelayer-ele-link">';
1477 - }
1478 -
1479 - // Any Link ?
1480 - if(!empty($el['atts']['link_to']) && $el['atts']['link_to'] == 'attachment' ){
1481 - $link = $image['link'];
1482 - $li .= '<a href="'.$link.'" class="pagelayer-ele-link">';
1483 - }
1484 -
1485 - if(!empty($el['atts']['link_to']) && $el['atts']['link_to'] == 'lightbox'){
1486 - $li .= '<a href="'.$image['url'].'" data-lightbox-gallery="'.$gallery_rand.'" alt="'.$image['alt'].'" class="pagelayer-ele-link" pagelayer-grid-gallery-type="'.$el['atts']['link_to'].'">';
1487 - }
1488 - // The Image
1489 - $li .= '<img class="pagelayer-img" src="'.$final_urls[$v].'" title="'.$image['title'].'" alt="'.$image['alt'].'">';
1490 -
1491 - if(!empty($el['atts']['caption'])){
1492 - $li .= '<span class="pagelayer-grid-gallery-caption">'.$image['caption'].'</span>';
1493 - }
1494 -
1495 - if(!empty($el['atts']['link_to'])){
1496 - $li .= '</a>';
1497 - }
1498 -
1499 - if(empty($el['atts']['link_to'])){
1500 - $li .= '</div>';
1501 - }
1502 -
1503 - $li .= '</li>';
1504 -
1505 - $ul[] = $li;
1506 - $i++;
1507 - }
1508 -
1509 - $ul[] = '</ul>';
1510 -
1511 - $pagiComplete[] = '<div class="pagelayer-grid-gallery-pagination"><ul class="pagelayer-grid-page-ul">'.'<li class="pagelayer-grid-page-item">&laquo;</li>'.$pagin.'<li class="pagelayer-grid-page-item">&raquo;</li>'.'</ul></div>';
1512 - //pagelayer_print($urls);
1513 - //pagelayer_print($final_urls);
1514 - //pagelayer_print($all_urls);
1515 -
1516 - // Make the TMP vars
1517 - if(!empty($urls)){
1518 - $el['tmp']['ids-urls'] = json_encode($urls);
1519 - $el['tmp']['ids-all-urls'] = json_encode($all_urls);
1520 - $el['tmp']['ids-all-links'] = json_encode($links);
1521 - $el['tmp']['ids-all-titles'] = json_encode($titles);
1522 - $el['tmp']['ids-all-captions'] = json_encode($captions);
1523 - $el['atts']['ul'] = implode('', $ul);
1524 - $el['atts']['pagin'] = ($j>1) ? implode('', $pagiComplete) : '';
1525 - $el['tmp']['gallery-random-id'] = $gallery_rand;
1526 -
1527 - }
1528 -}
1529 -
1530 -// Testimonial Handler
1531 -function pagelayer_sc_testimonial(&$el){
1532 -
1533 - if(empty($el['atts']['avatar']) || !empty($el['tmp']['avatar-no-image-set'])){
1534 - $el['atts']['avatar'] = '';
1535 - }
1536 -
1537 - $custom_size = empty($el['atts']['custom_size']) ? '' : @$el['tmp']['avatar-'.$el['atts']['custom_size'].'-url'];
1538 - $el['atts']['func_image'] = empty($custom_size) ? @$el['tmp']['avatar-url'] : $custom_size;
1539 -
1540 -}
1541 -
1542 -// Video Handler
1543 -function pagelayer_sc_video(&$el){
1544 -
1545 - $el['atts']['custom_size'] = empty($el['atts']['custom_size']) ? '' : $el['atts']['custom_size'];
1546 - $el['tmp']['video_overlay_image-url'] = empty($el['tmp']['video_overlay_image-url']) ? '' : $el['tmp']['video_overlay_image-url'];
1547 - $el['atts']['video_overlay_image'] = empty($el['atts']['video_overlay_image']) ? '' : $el['atts']['video_overlay_image'];
1548 -
1549 - $el['atts']['video_overlay_image-url'] = empty($el['tmp']['video_overlay_image-'.$el['atts']['custom_size'].'-url']) ? $el['tmp']['video_overlay_image-url'] : $el['tmp']['video_overlay_image-'.$el['atts']['custom_size'].'-url'];
1550 - $el['atts']['video_overlay_image-url'] = empty($el['atts']['video_overlay_image-url']) ? $el['atts']['video_overlay_image'] : $el['atts']['video_overlay_image-url'];
1551 -
1552 - // Get the video URL for the iframe
1553 - $vid_atts = pagelayer_video_url($el['tmp']['src-url'], true);
1554 -
1555 - $vid_atts['src'] .= substr_count($vid_atts['src'], '?') > 0 ? '' : '?';
1556 -
1557 - $vid_atts['src'] .= !empty($el['atts']['autoplay']) ? '&autoplay=1' : '&autoplay=0' ;
1558 -
1559 - $mute = !empty($el['atts']['mute']) ? 1 : 0;
1560 - $vid_atts['src'] .='&'.($vid_atts['type'] == 'vimeo' ? 'muted' : 'mute').'='.$mute;
1561 -
1562 - $vid_atts['src'] .= !empty($el['atts']['loop']) == 'true' ? '&loop=1' : '&loop=0' ;
1563 -
1564 - $el['atts']['vid_src'] = $vid_atts['src'].($vid_atts['type'] == 'youtube' ? '&playlist='.$vid_atts['id'] : '');
1565 -
1566 - $el['tmp']['ele_id'] = $el['id'];
1567 -
1568 -}
1569 -
1570 -// Shortcodes Handler
1571 -function pagelayer_sc_shortcodes(&$el){
1572 - $is_live = pagelayer_is_live();
1573 - if(empty($is_live)){
1574 - $el['tmp']['shortcode'] = pagelayer_the_content($el['atts']['data']);
1575 - }
1576 -}
1577 -
1578 -// Missing Handler
1579 -function pagelayer_sc_missing(&$el){
1580 - if(pagelayer_is_live()){
1581 - $el['tmp']['missing_msg'] = __('The pagelayer doesn’t support this content. You can leave this block intact or remove it completely.');
1582 - }
1583 -}
1584 -
1585 -// Shortcodes Handler
1586 -function pagelayer_sc_wp_widgets(&$el){
1587 -
1588 - global $wp_registered_sidebars;
1589 -
1590 - $data = '';
1591 - foreach($wp_registered_sidebars as $v){
1592 - if($el['atts']['sidebar'] == $v['id']){
1593 - ob_start();
1594 - dynamic_sidebar($v['id']);
1595 - $data = ob_get_clean();
1596 - }
1597 - }
1598 -
1599 - $el['tmp']['data'] = $data;
1600 -}
1601 -
1602 -// Service Handler
1603 -function pagelayer_sc_service(&$el){
1604 -
1605 - //Backward compatibility for new link props
1606 - pagelayer_add_link_backward($el, array(
1607 - 'link' => 'box_url',
1608 - 'rel' => '',
1609 - 'target' => 'box_target',
1610 - 'selector' => '.pagelayer-box-link'
1611 - ));
1612 -
1613 - //Backward compatibility for new link props
1614 - pagelayer_add_link_backward($el, array(
1615 - 'link' => 'heading_url',
1616 - 'rel' => '',
1617 - 'target' => 'heading_target',
1618 - 'selector' => '.pagelayer-service-heading-link'
1619 - ));
1620 -
1621 - //Backward compatibility for new link props
1622 - pagelayer_add_link_backward($el, array(
1623 - 'link' => 'service_button_url',
1624 - 'rel' => '',
1625 - 'target' => 'service_button_target',
1626 - 'selector' => '.pagelayer-service-btn'
1627 - ));
1628 -
1629 - if(!empty($el['atts']['service_image'])){
1630 -
1631 - // Decide the image URL
1632 - $el['atts']['func_image'] = @$el['tmp']['service_image-'.$el['atts']['service_image_size'].'-url'];
1633 - $el['atts']['func_image'] = empty($el['atts']['func_image']) ? @$el['tmp']['service_image-url'] : $el['atts']['func_image'];
1634 - $el['atts']['pagelayer-srcset'] = $el['atts']['func_image'].', '.$el['atts']['func_image'].' 1x, ';
1635 -
1636 - $image_atts = array(
1637 - 'name' => 'service_image',
1638 - 'size' => 'service_image_size'
1639 - );
1640 -
1641 - pagelayer_get_img_srcset($el, $image_atts);
1642 -
1643 - }
1644 -}
1645 -
1646 -// Icon box Handler
1647 -function pagelayer_sc_iconbox(&$el){
1648 -
1649 - //Backward compatibility for new link props
1650 - pagelayer_add_link_backward($el, array(
1651 - 'link' => 'box_url',
1652 - 'rel' => '',
1653 - 'target' => 'box_target',
1654 - 'selector' => '.pagelayer-box-link'
1655 - ));
1656 -
1657 - //Backward compatibility for new link props
1658 - pagelayer_add_link_backward($el, array(
1659 - 'link' => 'heading_url',
1660 - 'rel' => '',
1661 - 'target' => 'heading_target',
1662 - 'selector' => '.pagelayer-service-heading-link',
1663 - ));
1664 -
1665 -}
1666 -
1667 -// Anchor Handler
1668 -function pagelayer_sc_anchor(&$el){
1669 - $el['atts']['title'] = empty($el['atts']['title']) ? '' : esc_attr(sanitize_html_class( $el['atts']['title']));
1670 -}
1671 -
1672 -function pagelayer_sc_google_maps(&$el){
1673 -
1674 - $el['atts']['show_v2'] = true;
1675 -
1676 - if(empty($el['atts']['api_version'])){
1677 - $el['atts']['src_code'] = '';
1678 - return;
1679 - }
1680 -
1681 - $el['atts']['show_v2'] = false;
1682 - $api_key = @$el['atts']['api_key'];
1683 -
1684 - $gmaps_api = get_option('pagelayer-gmaps-api-key');
1685 -
1686 - if( empty($api_key) && !empty($gmaps_api) ){
1687 - $api_key = $gmaps_api;
1688 - }
1689 -
1690 - if($el['atts']['map_modes'] == 'view'){
1691 - $el['atts']['center'] = empty($el['atts']['center']) ? '-33.8569,151.2152' : $el['atts']['center'];
1692 - }
1693 -
1694 - $src_code = (empty($el['atts']['center']) ? '' : '&center='.$el['atts']['center']).($el['atts']['map_modes'] == 'streetview' ? '' : '&maptype='.$el['atts']['map_type'].'&zoom='.$el['atts']['zoom']);
1695 -
1696 - switch($el['atts']['map_modes']){
1697 - case 'place':
1698 - $src_code .= '&q='.(empty($el['atts']['address']) ? 'New York, New York, USA' : urlencode($el['atts']['address']) );
1699 - break;
1700 -
1701 - case 'directions':
1702 - $src_code .= '&origin='.(empty($el['atts']['direction_origin']) ? 'Oslow Norway' : urlencode($el['atts']['direction_origin']) );
1703 - $src_code .= '&destination='.(empty($el['atts']['direction_destination']) ? 'Telemark Norway' : urlencode($el['atts']['direction_destination']) );
1704 - $src_code .= (empty($el['atts']['direction_waypoints']) ? '' : '&waypoints='.join('|', explode(' ', trim($el['atts']['direction_waypoints']))) );
1705 - $src_code .= (empty($el['atts']['direction_modes']) ? '' : '&mode='.$el['atts']['direction_modes'] );
1706 - $src_code .= (empty($el['atts']['direction_avoid']) ? '' : '&avoid='.join('|', explode(',', $el['atts']['direction_avoid'])) );
1707 - $src_code .= (empty($el['atts']['direction_units']) ? '' : '&units='.$el['atts']['direction_units'] );
1708 - break;
1709 -
1710 - case 'streetview':
1711 - $src_code .= '&pano='.(empty($el['atts']['streetview_pano']) ? 'eTnPNGoy4bxR9LpjjfFuOw' : $el['atts']['streetview_pano'] );
1712 - $src_code .= '&location='.(empty($el['atts']['streetview_location']) ? '46.414382,10.013988' : $el['atts']['streetview_location'] );
1713 - $src_code .= (empty($el['atts']['streetview_heading']) ? '' : '&heading='.$el['atts']['streetview_heading'] );
1714 - $src_code .= (empty($el['atts']['streetview_pitch']) ? '' : '&pitch='.$el['atts']['streetview_pitch'] );
1715 - $src_code .= (empty($el['atts']['streetview_fov']) ? '' : '&fov='.$el['atts']['streetview_fov'] );
1716 - break;
1717 -
1718 - case 'search':
1719 - $src_code .= '&q='.(empty($el['atts']['search_term']) ? 'Record stores in Seattle' : urlencode($el['atts']['search_term']) );
1720 - break;
1721 -
1722 - }
1723 -
1724 - $src_iframe = 'https://www.google.com/maps/embed/v1/'.$el['atts']['map_modes'].'?key='.$api_key.$src_code;
1725 -
1726 - $el['atts']['src_code'] = '<iframe width="600" height="450" style="border:0" loading="lazy" allowfullscreen src="'.$src_iframe.'"></iframe>';
1727 -
1728 -}
1729 -
1730 -/*pagelayer_print($atts);
1731 -pagelayer_print($content);
1732 -die();*/
1733 -
1734 -/////////////////////////////////////
1735 -// Miscellaneous Shortcode Functions
1736 -/////////////////////////////////////
1737 -
1738 -// The font family list
1739 -function pagelayer_font_family(){
1740 - return array(
1741 - 'arial' => 'Arial',
1742 - 'terminal' => 'Terminal'
1743 - );
1744 -}
1745 -
1746 -// Supported Icons
1747 -function pagelayer_icon_class_list(){
1748 - return array();
1749 -}
1750 -
1751 -// Function to convert string into set of attributes and their corresponding values.
1752 -function pagelayer_string_to_attributes($val){
1753 -
1754 - $final_att = [];
1755 - $semi_arr = explode(';', $val);
1756 -
1757 - foreach($semi_arr as $att){
1758 -
1759 - $attrs = preg_split("/=/", trim($att), 2);
1760 -
1761 - if(empty($attrs[0]) || !preg_match("/^[a-z_]+[\w:.-]*$/i", $attrs[0]) ){
1762 - continue;
1763 - }
1764 -
1765 - if(!isset( $attrs[1])){
1766 - $final_att[$attrs[0]] = '';
1767 - continue;
1768 - }
1769 -
1770 - $final_att[$attrs[0]] = $attrs[1];
1771 - }
1772 -
1773 - return $final_att;
1774 -
1775 -}
1776 -
1777 -// Retina image setting attribute.
1778 -function pagelayer_get_img_srcset(&$el, $image_atts){
1779 -
1780 - // Check if retina images is set
1781 - if(isset($el['tmp'][$image_atts['name'].'-retina-url']) && strpos($el['tmp'][$image_atts['name'].'-retina-url'],'default-image') == false){
1782 - $retina_image = @$el['tmp'][$image_atts['name'].'-retina-'.$el['atts'][$image_atts['size']].'-url'];
1783 - $retina_image = empty($retina_image) ? @$el['tmp'][$image_atts['name'].'-retina-url'] : $retina_image;
1784 - $el['atts']['pagelayer-srcset'] .= $retina_image.' 2x, ';
1785 - }
1786 -
1787 - // Check if retina mobile images is set
1788 - if(isset($el['tmp'][$image_atts['name'].'-retina-mobile-url']) && strpos($el['tmp'][$image_atts['name'].'-retina-mobile-url'],'default-image') == false){
1789 - $retina_image_mobile = @$el['tmp'][$image_atts['name'].'-retina-mobile-'.$el['atts'][$image_atts['size']].'-url'];
1790 - $retina_image_mobile = empty($retina_image_mobile) ? @$el['tmp'][$image_atts['name'].'-retina-mobile-url'] : $retina_image_mobile;
1791 - $el['atts']['pagelayer-srcset'] .= $retina_image_mobile.' 3x';
1792 - }
1793 -}
1794 -
1795 -// Backward compatibility of target and rel attrs for link
1796 -function pagelayer_add_link_backward(&$el, $atts = array()){
1797 - global $pagelayer;
1798 -
1799 - $defaults = array(
1800 - 'link' => 'link',
1801 - 'target' => 'target',
1802 - 'rel' => 'rel',
1803 - 'selector' => 0,
1804 - );
1805 -
1806 - $_atts = wp_parse_args( $atts, $defaults );
1807 -
1808 - if(empty($el['atts'][$_atts['link']])){
1809 - return;
1810 - }
1811 -
1812 - $link = array();
1813 -
1814 - if(!empty($_atts['target']) && !empty($el['atts'][$_atts['target']]) ){
1815 - $link['target'] = true;
1816 - unset($el['oAtts'][$_atts['target']]);
1817 - }
1818 -
1819 - if(!empty($_atts['rel']) && !empty($el['atts'][$_atts['rel']]) ){
1820 - $link['attrs'] = 'rel='.$el['atts'][$_atts['rel']];
1821 - unset($el['oAtts'][$_atts['rel']]);
1822 - }
1823 -
1824 - if(empty($link)){
1825 - return;
1826 - }
1827 -
1828 - // Set Attributes for backward compatibility
1829 - if(!empty($link['target'])){
1830 - $el['attr'][][$_atts['selector']] = 'target="_blank"';
1831 - }
1832 -
1833 - // Set Attributes for backward compatibility
1834 - if(!empty($link['attrs']) ){
1835 - $el['attr'][][$_atts['selector']] = $link['attrs'];
1836 - }
1837 -
1838 - if(!is_array($el['atts'][$_atts['link']])){
1839 - $link['link'] = @$el['atts'][$_atts['link']];
1840 - }
1841 -
1842 - $el['oAtts'][$_atts['link']] = $link;
1843 - $el['atts'][$_atts['link']] = $link;
1844 -}
1 +<?php
2 +
3 +//////////////////////////////////////////////////////////////
4 +//===========================================================
5 +// class.php
6 +//===========================================================
7 +// PAGELAYER
8 +// Inspired by the DESIRE to be the BEST OF ALL
9 +// ----------------------------------------------------------
10 +// Started by: Pulkit Gupta
11 +// Date: 23rd Jan 2017
12 +// Time: 23:00 hrs
13 +// Site: http://pagelayer.com/wordpress (PAGELAYER)
14 +// ----------------------------------------------------------
15 +// Please Read the Terms of use at http://pagelayer.com/tos
16 +// ----------------------------------------------------------
17 +//===========================================================
18 +// (c)Pagelayer Team
19 +//===========================================================
20 +//////////////////////////////////////////////////////////////
21 +
22 +// Are we being accessed directly ?
23 +if(!defined('PAGELAYER_VERSION')) {
24 + exit('Hacking Attempt !');
25 +}
26 +
27 +// Is there a block ?
28 +function pagelayer_render_blocks($pre_render, $parsed_block){
29 +
30 + global $pagelayer;
31 +
32 + if(empty($parsed_block)){
33 + return $pre_render;
34 + }
35 +
36 + $block_name = $parsed_block['blockName'];
37 + $tag = '';
38 + $content = $parsed_block['innerHTML'];
39 + $inner_blocks = array(
40 + 'blocks' => $parsed_block['innerBlocks'],
41 + 'content' => $parsed_block['innerContent']
42 + );
43 + $atts = $parsed_block['attrs'];
44 + $atts['is_not_sc'] = 1;
45 +
46 + if ( is_string( $block_name ) && 0 === strpos( $block_name, 'pagelayer/' ) ) {
47 + $tag = substr( $block_name, 10 );
48 + }
49 +
50 + $allowed_tags = ['pl_inner_row', 'pl_inner_col'];
51 +
52 + if( (empty($tag) || !array_key_exists($tag, $pagelayer->shortcodes) ) && ! in_array( $tag, $allowed_tags) ){
53 + return $pre_render;
54 + }
55 +
56 + return pagelayer_render_shortcode($atts, $content, $tag, $inner_blocks);
57 +}
58 +
59 +// Is there a tag ?
60 +function pagelayer_render_shortcode($atts, $content = '', $tag = '', $inner_blocks = array()){
61 +
62 + global $pagelayer;
63 +
64 + $is_block = 0;
65 + $el = [];
66 +
67 + // Is block ?
68 + if(!empty($atts['is_not_sc'])){
69 + $is_block = 1;
70 + unset($atts['is_not_sc']);
71 + }
72 +
73 + $_tag = $class = $tag;
74 + $final_tag = $tag;
75 +
76 + // Check if the tag is inner row and col then change it to row and col tag
77 + if($tag == 'pl_inner_row'){
78 + $tag = 'pl_row';
79 + }elseif($tag == 'pl_inner_col'){
80 + $tag = 'pl_col';
81 + $final_tag = $tag;
82 + }
83 +
84 + // Clear the pagelayer tags
85 + if(substr($tag, 0, 3) == 'pl_'){
86 + $_tag = str_replace('pl_', '', $final_tag);
87 + $class = 'pagelayer-'.$_tag;
88 + }
89 +
90 + if(empty($atts)){
91 + $atts = array();
92 + }else{
93 + $atts = (array) $atts;
94 + }
95 +
96 + // If global - > Get the post and replace $atts
97 + if(!empty($atts['global_id'])){
98 +
99 + if(!empty($pagelayer->global_widgets[$atts['global_id']])){
100 + $content = $pagelayer->global_widgets[$atts['global_id']]['$'];
101 + return pagelayer_change_id($content);
102 + }
103 +
104 + if(!empty($pagelayer->global_sections[$atts['global_id']])){
105 + $content = $pagelayer->global_sections[$atts['global_id']]['$'];
106 + return pagelayer_change_id($content);
107 + }
108 +
109 + // Set the global id as attr
110 + $el['attr'][] = 'pagelayer-global-id="'.$atts['global_id'].'"';
111 + }
112 +
113 + // Is there any function ?
114 + $func = pagelayer_isset($pagelayer->shortcodes[$tag], 'func');
115 +
116 + // If not, we will search for a default func if prefix of tag is pl_
117 + if(empty($func) && substr($tag, 0, 3) == 'pl_'){
118 + $func = 'pagelayer_sc_'.substr($tag, 3);
119 + }
120 +
121 + // UnescapeHTML for the attributes, Fix for old shortcode method
122 + if(empty($is_block)){
123 + $atts = array_map('pagelayer_unescapeHTML', $atts);
124 + }
125 +
126 + // Create the element array. NOTE : This is similar to the JS el and is temporary
127 + $el['atts'] = $atts;
128 + $el['oAtts'] = $atts;
129 + $el['id'] = !empty($atts['pagelayer-id']) ? $atts['pagelayer-id'] : pagelayer_create_id();
130 + $el['tmp'] = [];
131 + $el['tag'] = $final_tag;
132 + $el['content'] = $content;
133 + $el['inner_blocks'] = $inner_blocks;
134 + $el['selector'] = '[pagelayer-id="'.$el['id'].'"]';
135 + $el['cssSel'] = '.p-'.$el['id'];
136 + $el['wrap'] = '[pagelayer-wrap-id="'.$el['id'].'"]';
137 +
138 + // Remove pagelayer-id from attr
139 + if( !empty($atts['pagelayer-id']) ){
140 + unset($el['atts']['pagelayer-id']);
141 + unset($el['oAtts']['pagelayer-id']);
142 + }
143 +
144 + $innerHTML = pagelayer_isset($pagelayer->shortcodes[$tag], 'innerHTML');
145 + if(!empty($innerHTML) && !empty($content)){
146 + $el['oAtts'][$innerHTML] = $content;
147 + $el['atts'][$innerHTML] = $content;
148 + }
149 +
150 + // The default class
151 + $el['classes'][] = 'p-'.$el['id'];
152 + $el['classes'][] = $class;
153 +
154 + // Register hook to filter $el
155 + $el = apply_filters('pagelayer_do_shortcode_el', $el);
156 +
157 + //pagelayer_print($el);
158 +
159 + // Lets create the CSS, Classes, Attr. Also clean the dependent atts
160 + foreach($pagelayer->tabs as $tab){
161 +
162 + if(empty($pagelayer->shortcodes[$tag][$tab])){
163 + continue;
164 + }
165 +
166 + foreach($pagelayer->shortcodes[$tag][$tab] as $section => $Lsection){
167 +
168 + $props = empty($pagelayer->shortcodes[$tag][$section]) ? @$pagelayer->styles[$section] : @$pagelayer->shortcodes[$tag][$section];
169 +
170 + //echo $tab.' - '.$section.' - <br>';
171 +
172 + if(empty($props)){
173 + continue;
174 + }
175 +
176 + foreach($props as $prop => $param){
177 +
178 + //echo $tab.' - '.$section.' - '.$prop.'<br>';
179 +
180 + // Handle the edit fields
181 + if(!empty($param['edit'])){
182 + $el['edit'][$prop] = $param['edit'];
183 + }
184 +
185 + // No value set
186 + if(empty($el['atts'][$prop]) && empty($el['atts'][$prop.'_tablet']) && empty($el['atts'][$prop.'_mobile'])){
187 + continue;
188 + }
189 +
190 + // Clean the not required atts
191 + if(!empty($param['req'])){
192 +
193 + $set = true;
194 +
195 + foreach($param['req'] as $rk => $reqval){
196 + $except = $rk[0] == '!' ? true : false;
197 + $rk = $except ? substr($rk, 1) : $rk;
198 + $val = pagelayer_isset($el['atts'], $rk);
199 +
200 + //echo $prop.' - '.$rk.' : '.$reqval.' == '.$val.'<br>';
201 +
202 + // The value should not be there
203 + if($except){
204 +
205 + if(!is_array($reqval) && $reqval == $val){
206 + $set = false;
207 + break;
208 + }
209 +
210 + // Its an array and a value is found, then dont show
211 + if(is_array($reqval) && in_array($val, $reqval)){
212 + $set = false;
213 + break;
214 + }
215 +
216 + // The value must be equal
217 + }else{
218 +
219 + if(!is_array($reqval) && $reqval != $val){
220 + $set = false;
221 + break;
222 + }
223 +
224 + // Its an array and no value is found, then dont show
225 + if(is_array($reqval) && !in_array($val, $reqval)){
226 + $set = false;
227 + break;
228 + }
229 + }
230 +
231 + }
232 +
233 + // Unset as we dont need
234 + if(empty($set)){
235 + unset($el['atts'][$prop]);
236 + unset($el['atts'][$prop.'_tablet']);
237 + unset($el['atts'][$prop.'_mobile']);
238 + unset($el['tmp'][$prop]);
239 + unset($el['tmp'][$prop.'_tablet']);
240 + unset($el['tmp'][$prop.'_mobile']);
241 + }
242 +
243 + }
244 +
245 + // We could have unset the value above, so we need to check again if the value is there
246 + if(empty($el['atts'][$prop]) && empty($el['atts'][$prop.'_tablet']) && empty($el['atts'][$prop.'_mobile'])){
247 + continue;
248 + }
249 +
250 + // Load any attachment values - This should go on top in the newer version @TODO
251 + if( pagelayer_is_comment_mode() && !empty($param['edit']) && !(isset($param['ai']) && $param['ai'] === false) && !empty($el['atts'][$prop])){
252 + $el['atts'][$prop] = $el['oAtts'][$prop] = !empty($el['atts']['comment_atts'][$prop]) ? $el['atts']['comment_atts'][$prop] : $el['atts'][$prop];
253 + }
254 +
255 + // Any image are skipped
256 + if( pagelayer_is_comment_mode() && $param['type'] == 'image' && isset($el['atts']['comment_atts'][$prop])){
257 + $el['atts'][$prop.'_ai'] = $el['oAtts'][$prop.'_ai'] = $el['atts']['comment_atts'][$prop];
258 + }
259 +
260 + if(in_array($param['type'], ['image', 'video', 'audio', 'media'])){
261 +
262 + $attachment = ($param['type'] == 'image') ? pagelayer_image(@$el['atts'][$prop]) : pagelayer_attachment(@$el['atts'][$prop]);
263 +
264 + if(!empty($attachment)){
265 + foreach($attachment as $k => $v){
266 + $el['tmp'][$prop.'-'.$k] = $v;
267 + }
268 + }
269 +
270 + }
271 +
272 + // Load any attachment values - This should go on top in the newer version @TODO
273 + if($param['type'] == 'multi_image'){
274 +
275 + $img_ids = pagelayer_maybe_explode(',', $el['atts'][$prop]);
276 + $img_urls = [];
277 +
278 + // Make the image URL
279 + foreach($img_ids as $k => $v){
280 + $image = pagelayer_image($v);
281 + $img_urls['i'.$v] = @$image['url'];
282 + }
283 +
284 + $el['tmp'][$prop.'-urls'] = json_encode($img_urls);
285 + }
286 +
287 + // Backward compatibility of row
288 + if($el['tag'] == 'pl_row' && $prop == 'content_pos' && !empty($el['atts'][$prop])){
289 + if($el['atts'][$prop] == 'baseline'){
290 + $el['atts'][$prop] = $el['oAtts'][$prop] = 'flex-start';
291 + }else if($el['atts'][$prop] == 'end'){
292 + $el['atts'][$prop] = $el['oAtts'][$prop] = 'flex-end';
293 + }
294 + }
295 +
296 + // Backward compatibility of Icons
297 + if($param['type'] == 'icon' && !empty($el['atts'][$prop]) && !preg_match('/\s/', $el['atts'][$prop])){
298 + $el['atts'][$prop] = $el['oAtts'][$prop] = 'fa fa-'.$el['atts'][$prop];
299 + }
300 +
301 + // Backward compatibility of Box Shadow
302 + if($param['type'] == 'box_shadow' && !empty($el['atts'][$prop])){
303 + $shadow_atts = pagelayer_maybe_explode(',', $el['atts'][$prop]);
304 + if(count($shadow_atts) == 4){
305 + $shadow_atts[] = '0';
306 + $shadow_atts[] = '';
307 + $el['atts'][$prop] = $el['oAtts'][$prop] = $shadow_atts;
308 + }
309 + }
310 +
311 + // Backward compatibility of units. And also for the default set value if it is numeric
312 + if(!empty($param['units']) && isset($el['atts'][$prop]) && is_numeric($el['atts'][$prop])){
313 + $el['atts'][$prop] = $el['oAtts'][$prop] = $el['atts'][$prop].$param['units'][0];
314 + }
315 +
316 + // Load permalink values
317 + if($param['type'] == 'link'){
318 +
319 + $link = $el['atts'][$prop];
320 +
321 + if( is_array($el['atts'][$prop]) ){
322 +
323 + // Link is required for check IF and IF-EXT in html
324 + if(!isset($el['atts'][$prop]['link']) || strlen(trim($el['atts'][$prop]['link'])) < 1){
325 + $link = '';
326 + unset($el['atts'][$prop]);
327 + continue;
328 + }
329 +
330 + $link = $el['atts'][$prop]['link'];
331 +
332 + if(!empty($el['atts'][$prop]['target'])){
333 + $el['attr'][][$param['selector']] = 'target="_blank"';
334 + }
335 +
336 + if(!empty($el['atts'][$prop]['rel'])){
337 + $el['attr'][][$param['selector']] = 'rel="nofollow"';
338 + }
339 +
340 + if(!empty($el['atts'][$prop]['attrs'])){
341 +
342 + $atts_ar = pagelayer_string_to_attributes($el['atts'][$prop]['attrs']);
343 +
344 + if(!empty($atts_ar)){
345 + foreach($atts_ar as $att => $value){
346 + $el['attr'][][$param['selector']] = $att.'="'.esc_attr($value).'"';
347 + }
348 + }
349 + }
350 + }
351 +
352 + $el['tmp'][$prop] = esc_url(pagelayer_permalink($link));
353 + }
354 +
355 + // Handle the AddClasses
356 + if(!empty($param['addClass']) && !empty($el['atts'][$prop])){
357 +
358 + // Convert to an array
359 + if(!is_array($param['addClass'])){
360 + $param['addClass'] = array($param['addClass']);
361 + }
362 +
363 + // Loop through
364 + foreach($param['addClass'] as $k => $v){
365 + $k = str_replace('{{element}}', '', $k);
366 + $el['classes'][] = [trim($k) => str_replace('{{val}}', $el['atts'][$prop], $v)];
367 + }
368 +
369 + }
370 +
371 + // Handle the AddAttributes
372 + if(!empty($param['addAttr']) && !empty($el['atts'][$prop])){
373 +
374 + // Convert to an array
375 + if(!is_array($param['addAttr'])){
376 + $param['addAttr'] = array($param['addAttr']);
377 + }
378 +
379 + // Loop through
380 + foreach($param['addAttr'] as $k => $v){
381 + $k = str_replace('{{element}}', '', $k);
382 + $el['attr'][] = [trim($k) => $v];
383 + }
384 +
385 + }
386 +
387 + $modes = [
388 + 'desktop' => '',
389 + 'tablet' => '_tablet',
390 + 'mobile' => '_mobile'
391 + ];
392 +
393 + $global_typo = ($param['type'] == 'typography') ? pagelayer_is_global_typo(@$el['atts'][$prop]) : '';
394 +
395 + // Handle the CSS
396 + if(!empty($param['css'])){
397 + //echo $prop.'<br>';
398 + // Convert to an array
399 + if(!is_array($param['css'])){
400 + $param['css'] = array($param['css']);
401 + }
402 +
403 + // Loop the modes and check for values
404 + foreach($modes as $mk => $mv){
405 +
406 + $M_prop = $prop.$mv;
407 +
408 + $prop_val = pagelayer_isset($el['atts'], $M_prop);
409 +
410 + // If is global font
411 + if( $param['type'] == 'typography' && (!empty($prop_val) || !empty($global_typo)) ){
412 + $prop_val = pagelayer_parse_typo($prop_val, $global_typo, $mk);
413 + }
414 +
415 + // Any value ?
416 + if(empty($prop_val)){
417 + continue;
418 + }
419 +
420 + // Global color handler
421 + if($param['type'] == 'color'){
422 + $prop_val = pagelayer_parse_color($prop_val);
423 + }
424 +
425 + // If there is global gradient color
426 + if($param['type'] == 'gradient'){
427 +
428 + $prop_val = pagelayer_maybe_explode(',', $prop_val);
429 +
430 + foreach($prop_val as $grad_key => $grad_val){
431 +
432 + if($grad_val[0] != '$'){
433 + continue;
434 + }
435 +
436 + $prop_val[$grad_key] = pagelayer_parse_color($grad_val);
437 +
438 + }
439 +
440 + }
441 +
442 + // Loop through
443 + foreach($param['css'] as $k => $v){
444 +
445 + // Make the selector
446 + $selector = (!is_numeric($k) ? $k : $el['cssSel']);
447 + $selector = pagelayer_parse_el_vars($selector, $el);
448 +
449 + if($mk == 'tablet'){
450 + $selector = '|pl_tablet|'.$selector;
451 + }
452 +
453 + if($mk == 'mobile'){
454 + $selector = '|pl_mobile|'.$selector;
455 + }
456 +
457 + // Make the CSS
458 + if(!empty($selector)){
459 + $el['css'][$selector][] = rtrim( trim( pagelayer_css_render($v, $prop_val, pagelayer_isset($param, 'sep')) ), ';' );
460 + }else{
461 + $el['css'][][] = pagelayer_parse_el_vars($el['atts'][$M_prop],$el);
462 + }
463 + }
464 +
465 + }
466 +
467 + }
468 +
469 + $font_cache = '';
470 + // Loop the modes and check for values
471 + foreach($modes as $mk => $mv){
472 +
473 + $M_prop = $prop.$mv;
474 +
475 + if($param['type'] == 'typography' && !empty($el['atts'][$M_prop])){
476 +
477 + $prop_val = pagelayer_parse_typo($el['atts'][$M_prop], $global_typo, $mk);
478 +
479 + $val = pagelayer_maybe_explode(',', $prop_val);
480 +
481 + //For backward comaptibility
482 + if($mk == 'desktop'){
483 + $font_cache = $val[0];
484 + }
485 +
486 + $val[0] = empty($val[0]) ? $font_cache : $val[0];
487 +
488 + if(!empty($val[0])){
489 + pagelayer_load_font_family($val[0], pagelayer_isset($val, 3), pagelayer_isset($val, 2));
490 +
491 + //pagelayer_print($pagelayer->runtime_fonts);
492 + }
493 + }
494 +
495 + if($prop == 'font_family' && !empty($el['atts'][$M_prop])){
496 + $val = $el['atts'][$M_prop];
497 + if(!empty($val)){
498 + pagelayer_load_font_family($val, pagelayer_isset($el['atts'], 'font_weight'.$mv), pagelayer_isset($el['atts'], 'font_style'.$mv));
499 + }
500 + }
501 + }
502 + }
503 +
504 + }
505 +
506 + }
507 +
508 + //@pagelayer_print($el['css']);
509 +
510 + // Is there a function of the tag ?
511 + if(function_exists($func)){
512 + call_user_func_array($func, array(&$el));
513 + }
514 +
515 + // Create the default atts and tmp atts
516 + if(pagelayer_is_live()){
517 + pagelayer_create_sc($el, $is_block);
518 + }
519 +
520 + $div = '<div pagelayer-id="'.$el['id'].'">
521 +<style pagelayer-style-id="'.$el['id'].'"></style>';
522 +
523 + $is_group = !empty($pagelayer->shortcodes[$tag]['has_group']) ? true : false;
524 +
525 + // If there is an HTML AND you are not a GROUP, then make use of it, or append the real content
526 + if(!empty($pagelayer->shortcodes[$tag]['html'])){
527 +
528 + // Create the HTML object
529 + $node = pagelayerQuery::parseStr($pagelayer->shortcodes[$tag]['html']);
530 +
531 + // Remove the if-ext
532 + foreach($node('[if-ext]') as $v){
533 + $reqvar = pagelayer_var($v->attr('if-ext'));
534 + $v->removeAttr('if-ext');
535 +
536 + // Is the element there ?
537 + if(empty($el['atts'][$reqvar])){
538 + $ext_html = $v->html();
539 + if(strlen($ext_html) > 0){
540 + $v->after($ext_html);
541 + }
542 + $v->remove();
543 + }
544 + }
545 +
546 + // Remove the if
547 + foreach($node('[if]') as $v){
548 + $reqvar = pagelayer_var($v->attr('if'));
549 + $v->removeAttr('if');
550 +
551 + // Is the element there ?
552 + if(empty($el['atts'][$reqvar])){
553 + $v->remove();
554 + }
555 + }
556 +
557 + //die($node->html());
558 +
559 + // Do we have a holder ? Mainly for groups
560 + if(!empty($pagelayer->shortcodes[$tag]['holder'])){
561 + $node->query($pagelayer->shortcodes[$tag]['holder'])->html('{{pagelayer_do_shortcode}}');
562 + $do_shortcode = 1;
563 + }
564 +
565 + $html = pagelayer_parse_vars($node->html(), $el);
566 +
567 + // Append to the DIV
568 + $div .= $html;
569 +
570 + // Is it a widget ?
571 + }elseif(!empty($pagelayer->shortcodes[$tag]['widget'])){
572 +
573 + $class = $pagelayer->shortcodes[$tag]['widget'];
574 + $instance = [];
575 +
576 + // Is there any existing data ?
577 + if(!empty($el['atts']['widget_data'])){
578 + $json = trim($el['atts']['widget_data']);
579 + $json = json_decode($json, true);
580 + //pagelayer_print($json);die();
581 + if(!empty($json)){
582 + $instance = $json;
583 + }
584 + }
585 +
586 + ob_start();
587 + the_widget($class, $instance, array('widget_id'=>'arbitrary-instance-'.$el['id'],
588 + 'before_widget' => '',
589 + 'after_widget' => '',
590 + 'before_title' => '',
591 + 'after_title' => ''
592 + ));
593 +
594 + $div .= ob_get_contents();
595 + ob_end_clean();
596 +
597 + }else{
598 + $div .= '{{pagelayer_do_shortcode}}';
599 + $do_shortcode = 1;
600 + }
601 +
602 + // End the tag
603 + $div .= '</div>';
604 +
605 + // Add classes and attributes
606 + if(!empty($el['classes']) || !empty($el['attr']) || !empty($el['atts']['ele_attributes'])){
607 +
608 + // Create the HTML object
609 + $node = pagelayerQuery::parseStr($div);
610 +
611 + // Add the editable values
612 + if(!empty($el['edit']) && pagelayer_is_live()){
613 +
614 + foreach($el['edit'] as $k => $v){
615 + $node->query($v)->attr('pagelayer-editable', $k);
616 + }
617 +
618 + }
619 +
620 + // Add the post data editable
621 + if(pagelayer_is_live() && !empty($pagelayer->shortcodes[$tag]['edit_props']) && is_array($pagelayer->shortcodes[$tag]['edit_props'])){
622 +
623 + $edit_props = $pagelayer->shortcodes[$tag]['edit_props'];
624 +
625 + foreach($edit_props as $k => $v){
626 + $node->query($k)->attr('pagelayer-props-editable', $v);
627 + }
628 +
629 + }
630 +
631 + // Add the classes
632 + if(!empty($el['classes'])){
633 +
634 + //pagelayer_print($el['classes']);
635 +
636 + foreach($el['classes'] as $k => $v){
637 +
638 + if(!is_array($v)){
639 + $v = [$v];
640 + }
641 +
642 + foreach($v as $kk => $vv){
643 + //echo $kk.' - '.$vv."\n";
644 + if(is_numeric($kk)){
645 + $node->query($el['selector'])->addClass($vv);
646 + }else{
647 + $node->query($kk)->addClass($vv);
648 + }
649 +
650 + }
651 +
652 + }
653 +
654 + //echo $node->html();
655 + //die();
656 +
657 + }
658 +
659 + // Add the attributes
660 + if(!empty($el['attr'])){
661 +
662 + //pagelayer_print($el['attr']);
663 +
664 + foreach($el['attr'] as $k => $v){
665 +
666 + if(!is_array($v)){
667 + $v = [$v];
668 + }
669 +
670 + foreach($v as $kk => $vv){
671 +
672 + $att = explode('=', $vv, 2);
673 + $att[1] = pagelayer_parse_vars($att[1], $el);
674 + $att[1] = trim($att[1], '"');
675 +
676 + if(is_numeric($kk)){
677 + $node->query($el['selector'])->attr($att[0], $att[1]);
678 + }else{
679 + $node->query($kk)->attr($att[0], $att[1]);
680 + }
681 +
682 + }
683 +
684 + }
685 +
686 + }
687 +
688 + // Adding Custom Attributes
689 + if(!empty($el['atts']['ele_attributes'])){
690 +
691 + $val = pagelayer_string_to_attributes($el['atts']['ele_attributes']);
692 + if(!empty($val)){
693 + foreach($val as $att => $value ){
694 +
695 + // Defense in depth at the sink. Unconditional : it must not
696 + // depend on the viewer, the post author or a save time scan.
697 + if(pagelayer_should_show_xss_warning() && !pagelayer_is_allowed_attribute($att)){
698 + continue;
699 + }
700 +
701 + $node->query($el['selector'])->attr($att, esc_attr($value));
702 + }
703 + }
704 +
705 + }
706 +
707 + // Get font family form inline style
708 + foreach($node->query('[style]') as $snode){
709 + $ss = $snode->attr('style');
710 +
711 + if(strpos($ss, 'font-family') === false){
712 + continue;
713 + }
714 +
715 + $ss = explode(';', html_entity_decode($snode->attr('style')));
716 + foreach($ss as $sss){
717 +
718 + if(strpos($sss, 'font-family') === false){
719 + continue;
720 + }
721 +
722 + $ff = explode(':', $sss);
723 + $val = trim( trim($ff[1]), '"' );
724 + $fw = array('100', '100i', '200', '200i', '300', '300i', '400', '400i', '500', '500i', '600', '600i', '700', '700i', '800', '800i', '900', '900i');
725 +
726 + foreach($fw as $ww){
727 + $pagelayer->runtime_fonts[$val][$ww] = $ww;
728 + }
729 + }
730 + }
731 +
732 + $div = $node->html();
733 + //die($div);
734 +
735 + }
736 +
737 + // Add the CSS if any or remove it
738 + $style = '';
739 + if(!empty($el['css'])){
740 +
741 + $screen_style = array('tablet' => '', 'mobile' => '');
742 + $style = '<style pagelayer-style-id="'.$el['id'].'">';
743 + foreach($el['css'] as $ck => $cv){
744 + preg_match('/\|pl_(mobile|tablet)\|/is', $ck, $screen_matches);
745 + $ck = str_replace(['|pl_mobile|', '|pl_tablet|'], '', $ck);
746 + $media = pagelayer_isset($screen_matches, 1);
747 +
748 + $merge_css = implode(';', $cv);
749 + $combine_css = (!is_numeric($ck) ? $ck.'{'.$merge_css.'}' : $merge_css ).PHP_EOL;
750 +
751 + // Mobile or tablet ?
752 + if(!empty($media)){
753 + $screen_style[$media] .= $combine_css;
754 + continue;
755 + }
756 +
757 + $style .= $combine_css;
758 + }
759 +
760 + if(!empty($screen_style['tablet'])){
761 + $style .= '@media (max-width: '.$pagelayer->settings['tablet_breakpoint'].'px) and (min-width: '.($pagelayer->settings['mobile_breakpoint'] + 1).'px){'.$screen_style['tablet'].'}'.PHP_EOL;
762 + }
763 +
764 + if(!empty($screen_style['mobile'])){
765 + $style .= '@media (max-width: '.$pagelayer->settings['mobile_breakpoint'].'px){'.$screen_style['mobile'].'}'.PHP_EOL;
766 + }
767 +
768 + $style .= '</style>';
769 + $style = pagelayer_parse_vars($style, $el);
770 +
771 + if(!empty($pagelayer->shortcodes[$tag]['overide_css_selector'])){
772 + $overide_css_selector = pagelayer_parse_el_vars($pagelayer->shortcodes[$tag]['overide_css_selector'], $el);
773 + $style = str_replace($el['cssSel'], $overide_css_selector, $style);
774 + $style = str_replace($el['wrap'], $overide_css_selector, $style);
775 + }
776 +
777 + $style = pagelayer_unescapeHTML($style);
778 + }
779 +
780 + $div = str_replace('<style pagelayer-style-id="'.$el['id'].'"></style>', $style, $div);
781 +
782 + // Is there an inner content which requires a SHORTCODE ?
783 + if(!empty($do_shortcode)){
784 +
785 + $inner_content = pagelayer_render_inner_content($el);
786 +
787 + $div = str_replace('{{pagelayer_do_shortcode}}', $inner_content, $div);
788 + }
789 +
790 + // Sanitize the content
791 + $div = apply_filters( 'pagelayer_sanitize_do_shortcode', $div );
792 +
793 + return $div;
794 +
795 +}
796 +
797 +// Render inner content
798 +function pagelayer_render_inner_content(&$el){
799 +
800 + $inner_content = '';
801 +
802 + // Is block code?
803 + if( !empty($el['inner_blocks']) ){
804 +
805 + $index = 0;
806 +
807 + foreach ( $el['inner_blocks']['content'] as $chunk ) {
808 + if ( is_string( $chunk ) ) {
809 +
810 + // If any string in Column the conver this is text widget in pagelayer live
811 + if(!empty(trim($chunk)) && pagelayer_is_live() && $el['tag'] == 'pl_col'){
812 + $parsed_block['blockName'] = 'pagelayer/pl_text';
813 + $parsed_block['innerHTML'] = $chunk;
814 + $parsed_block['attrs'] = [];
815 + $inner_content .= render_block($parsed_block);
816 + continue;
817 + }
818 +
819 + $inner_content .= $chunk;
820 + continue;
821 + }
822 +
823 + $inner_block = $el['inner_blocks']['blocks'][ $index ];
824 + $inner_content .= render_block($inner_block);
825 + ++$index;
826 + }
827 + }else{
828 + $inner_content .= do_shortcode($el['content']);
829 + }
830 +
831 + return $inner_content;
832 +}
833 +
834 +// Change pagelayer id in html
835 +function pagelayer_change_id($content){
836 + global $pagelayer;
837 +
838 + preg_match_all('/pagelayer-id="(.*?)"/', $content, $matches);
839 + $matches = array_unique($matches[1]);
840 +
841 + foreach($matches as $val){
842 + $id = pagelayer_create_id();
843 + $content = str_replace($val, $id, $content);
844 + }
845 +
846 + return $content;
847 +}
848 +
849 +// Creates the shortcode and returns a base64 encoded files
850 +function pagelayer_create_sc(&$el, $is_block = 0){
851 +
852 + global $pagelayer;
853 +
854 + $a = $tmp = array();
855 +
856 + $pagelayer->data_attr[$el['id']] = ['attr' => $el['oAtts'], 'tmp' => $el['tmp']];
857 +
858 + /*if(!empty($el['oAtts'])){
859 +
860 + foreach($el['oAtts'] as $k => $v){
861 + $v = str_replace('&', '&amp;', $v);
862 + if($is_block){
863 + $v = pagelayer_escapeHTML($v);
864 + }
865 + $el['attr'][] = 'pagelayer-a-'.$k.'="'.$v.'"';
866 + }
867 +
868 + }
869 +
870 + // Tmp atts
871 + if(!empty($el['tmp'])){
872 +
873 + foreach($el['tmp'] as $k => $v){
874 + $v = str_replace('&', '&amp;', $v);
875 + if($is_block){
876 + $v = pagelayer_escapeHTML($v);
877 + }
878 + $el['attr'][] = 'pagelayer-tmp-'.$k.'="'.$v.'"';
879 + }
880 +
881 + }*/
882 +
883 + // Add the tag
884 + $el['attr'][] = 'pagelayer-tag="'.$el['tag'].'"';
885 +
886 + // Make it a Pagelayer element for editing
887 + $el['classes'][] = 'pagelayer-ele';
888 +
889 +}
890 +
891 +// Converts {{val}} to val
892 +function pagelayer_var($var){
893 + return substr($var, 2, -2);
894 +}
895 +
896 +// Is the given global color
897 +function pagelayer_is_global_typo($value){
898 + global $pagelayer;
899 +
900 + $typo_key = '';
901 +
902 + // Backward compatibility
903 + if(is_string($value) && $value[0] == '$'){
904 + $typo_key = substr($value, 1);
905 + }
906 +
907 + if(is_array($value) && isset($value['global-font'])){
908 + $typo_key = $value['global-font'];
909 + }
910 +
911 + // If global color not exist
912 + if(!empty($typo_key)){
913 + $typo_key = isset($pagelayer->global_fonts[$typo_key]) ? $typo_key : 'primary';
914 + }
915 +
916 + return $typo_key;
917 +
918 +}
919 +
920 +// Parse typography and handle Backward compatibility
921 +function pagelayer_parse_typo($value, $desk_global = '', $mk = 'desktop'){
922 + global $pagelayer;
923 +
924 + $value = empty($value)? [] : $value;
925 +
926 + // Backward compatibility for comma seperated val
927 + if(!is_array($value) && $value[0] != '$'){
928 + return $value;
929 + }
930 +
931 + $val = ['','','','','','','','','','',''];
932 + $global_typo = pagelayer_is_global_typo($value);
933 + $_desk_global = false;
934 +
935 + if( empty($global_typo) ){
936 + $global_typo = $desk_global;
937 + $_desk_global = true;
938 + }
939 +
940 + // Apply global typo
941 + foreach($pagelayer->typo_props as $typo => $typo_key){
942 +
943 + // Backspace compatibility for normal array and if is set global in '$' format like $primary
944 + if(is_array($value) && !empty($value[$typo])){
945 + $val[$typo] = $value[$typo];
946 + }
947 +
948 + if(!empty($value[$typo_key])){
949 + $val[$typo] = $value[$typo_key];
950 + }
951 +
952 + if(!empty($val[$typo]) || empty($global_typo)){
953 + continue;
954 + }
955 +
956 + $global_val = $pagelayer->global_fonts[$global_typo]['value'];
957 +
958 + if( empty($global_val[$typo_key]) || (is_array($global_val[$typo_key]) && empty($global_val[$typo_key][$mk])) || (!is_array($global_val[$typo_key]) && !empty($_desk_global) && $mk != 'desktop') ){
959 + continue;
960 + }
961 +
962 + $val[$typo] = 'var(--pagelayer-font-'.$global_typo.'-'.$typo_key.')';
963 + }
964 +
965 + return $val;
966 +}
967 +
968 +// Parse color for global color
969 +function pagelayer_parse_color($value, $var = true){
970 + global $pagelayer;
971 +
972 + // Global color handler
973 + if($value[0] != '$' ){
974 + return $value;
975 + }
976 +
977 + $gkey = substr($value, 1);
978 + $gkey = isset($pagelayer->global_colors[$gkey]) ? $gkey : 'primary';
979 +
980 + if(empty($var)){
981 + return @$pagelayer->global_colors[$gkey]['value'];
982 + }
983 +
984 + return 'var(--pagelayer-color-'.$gkey.')';
985 +}
986 +
987 +// Replace the variables
988 +function pagelayer_parse_el_vars($str, &$el){
989 +
990 + global $pagelayer, $post;
991 +
992 + // if is 404 then @$post->ID
993 + if(!empty( $pagelayer->rendering_template_id ) && @$post->ID != $pagelayer->rendering_template_id){
994 + $is_editable = false;
995 + }else{
996 + $is_editable = true;
997 + }
998 +
999 + $str = str_replace('{{element}}', $el['cssSel'], $str);
1000 + $is_live = pagelayer_is_live();
1001 + if(!empty($is_live) && $is_editable){
1002 + $str = str_replace('{{wrap}}', $el['wrap'], $str);
1003 + }else{
1004 + $str = str_replace('{{wrap}}', $el['cssSel'], $str);
1005 + }
1006 + $str = str_replace('{{ele_id}}', $el['id'], $str);
1007 +
1008 + return $str;
1009 +
1010 +}
1011 +
1012 +// Parse the variables
1013 +function pagelayer_parse_vars($str, &$el){
1014 +
1015 + if(empty($str)){
1016 + return $str;
1017 + }
1018 +
1019 + //pagelayer_print($el);
1020 + if(!empty($el['tmp']) && is_array($el['tmp'])){
1021 + foreach($el['tmp'] as $k => $v){
1022 + $str = str_replace('{{{'.$k.'}}}', pagelayer_maybe_implode($el['tmp'][$k]), $str);
1023 + }
1024 + }
1025 +
1026 + if(is_array($el['atts'])){
1027 + foreach($el['atts'] as $k => $v){
1028 + $str = str_replace('{{'.$k.'}}', pagelayer_maybe_implode($el['atts'][$k]), $str);
1029 + }
1030 + }
1031 +
1032 + return $str;
1033 +}
1034 +
1035 +// Make the rule
1036 +function pagelayer_css_render($rule, $val, $sep = ','){
1037 +
1038 + // Seperator
1039 + $sep = empty($sep) ? ',' : $sep;
1040 +
1041 + if(is_array($val)){
1042 + $val = implode($sep, $val);
1043 + }
1044 +
1045 + // Replace the val
1046 + $rule = pagelayer_css_val_replace('{{val}}', pagelayer_hex8_to_rgba($val), $rule);
1047 +
1048 + // If there is an array
1049 + if(preg_match('/\{val\[\d/is', $rule)){
1050 + $val = explode($sep, $val);
1051 + foreach($val as $k => $v){
1052 + $rule = pagelayer_css_val_replace('{{val['.$k.']}}', pagelayer_hex8_to_rgba($v), $rule);
1053 + }
1054 + }
1055 +
1056 + return $rule;
1057 +}
1058 +
1059 +// Make the rule
1060 +function pagelayer_css_val_replace($val, $v, $rule){
1061 +
1062 + // If value has css var then we remove units
1063 + if(strripos($v, 'var(') !== false){
1064 + $pattern = '/'.preg_quote($val, '/').'?[^\s|;]+/is';
1065 + $rule = preg_replace($pattern, $v, $rule);
1066 + return $rule;
1067 + }
1068 +
1069 + $rule = str_replace($val, $v, $rule);
1070 + return $rule;
1071 +}
1072 +
1073 +// Post Property Handler
1074 +function pagelayer_sc_post_props(&$el){
1075 +
1076 + global $post;
1077 +
1078 + if(empty($post)){
1079 + return;
1080 + }
1081 +
1082 + $el['oAtts']['post_title'] = $post->post_title;
1083 + $el['oAtts']['post_name'] = $post->post_name;
1084 + $el['oAtts']['post_excerpt'] = $post->post_excerpt;
1085 + $el['oAtts']['post_status'] = (empty($post->post_password)) ? $post->post_status : 'pass_protected';
1086 + $el['oAtts']['post_password'] = $post->post_password;
1087 + $el['oAtts']['featured_image'] = get_post_thumbnail_id($post);
1088 + $el['oAtts']['comment_status'] = ($post->comment_status == 'open') ? 'true' : '';
1089 + $el['oAtts']['ping_status'] = ($post->ping_status == 'open') ? 'true' : '';
1090 + $el['oAtts']['post_date'] = $post->post_date;
1091 + $el['oAtts']['post_sticky'] = is_sticky($post->ID) ? 'true' : '';
1092 + $el['oAtts']['post_parent'] = $post->post_parent;
1093 + $el['oAtts']['menu_order'] = $post->menu_order;
1094 + $el['oAtts']['post_author'] = $post->post_author;
1095 + $el['oAtts']['post_category'] = '';
1096 + $el['oAtts']['post_tags'] = '';
1097 +
1098 + $tag_name = pagelayer_post_type_tag($post->post_type);
1099 + if(!empty($tag_name)){
1100 + $postTags = wp_get_post_terms( $post->ID, $tag_name );
1101 + $el['oAtts']['post_tags'] = array_column((array)$postTags, 'name');
1102 + }
1103 +
1104 + $cat_name = pagelayer_post_type_category($post->post_type);
1105 + if(!empty($cat_name)){
1106 + $category = get_the_terms( $post->ID, $cat_name );
1107 + $el['oAtts']['post_category'] = array_column((array)$category, 'term_id');
1108 + }
1109 +
1110 + // Load featured image details
1111 + if(!empty($el['oAtts']['featured_image'])){
1112 +
1113 + $attachment = pagelayer_image($el['oAtts']['featured_image']);
1114 +
1115 + if(!empty($attachment)){
1116 + foreach($attachment as $k => $v){
1117 + $el['tmp']['featured_image-'.$k] = $v;
1118 + }
1119 + }
1120 +
1121 + }
1122 +
1123 +}
1124 +
1125 +// ROW Handler
1126 +function pagelayer_sc_row(&$el){
1127 +
1128 + pagelayer_bg_video($el);
1129 +
1130 + if(!empty($el['atts']['row_shape_type_top'])){
1131 + $path_top = PAGELAYER_DIR.'/images/shapes/'.$el['atts']['row_shape_type_top'].'-top.svg';
1132 + $el['atts']['svg_top'] = file_get_contents($path_top);
1133 + }
1134 +
1135 + if(!empty($el['atts']['row_shape_type_bottom'])){
1136 + $path_bottom = PAGELAYER_DIR.'/images/shapes/'.$el['atts']['row_shape_type_bottom'].'-bottom.svg';
1137 + $el['atts']['svg_bottom'] = file_get_contents($path_bottom);
1138 + }
1139 +
1140 + // Row background slider
1141 + if(!empty($el['atts']['bg_slider'])){
1142 + $ids = pagelayer_maybe_explode(',', $el['atts']['bg_slider']);
1143 + $urls = [];
1144 + $el['atts']['slider'] = '';
1145 +
1146 + // Make the image URL
1147 + foreach($ids as $k => $v){
1148 +
1149 + $image = pagelayer_image($v);
1150 + $urls['i'.$v] = @$image['url'];
1151 +
1152 + $el['atts']['slider'] .= '<div class="pagelayer-bgimg-slide" style="background-image:url(\''.$image['url'].'\')"></div>';
1153 +
1154 + }
1155 +
1156 + if(!empty($urls)){
1157 + $el['tmp']['bg_slider-urls'] = json_encode($urls);
1158 + }
1159 +
1160 + }
1161 +
1162 + // Row background parallax image.
1163 + if(!empty($el['atts']['parallax_img'])){
1164 + $img_size = @$el['tmp']['parallax_img-'.$el['atts']['parallax_id_size'].'-url'];
1165 + $el['atts']['parallax_img_src'] = empty($img_size) ? @$el['tmp']['parallax_img-url'] : $img_size;
1166 + }
1167 +
1168 +}
1169 +
1170 +// Column Handler
1171 +function pagelayer_sc_col(&$el){
1172 +
1173 + // Add the default col class
1174 + $el['classes'][] = 'pagelayer-col';
1175 +
1176 + //return do_shortcode($el['content']);
1177 +
1178 + pagelayer_bg_video($el);
1179 +
1180 + // Column background slider
1181 + if(!empty($el['atts']['bg_slider'])){
1182 + $ids = pagelayer_maybe_explode(',', $el['atts']['bg_slider']);
1183 + $urls = [];
1184 + $el['atts']['slider'] = '';
1185 +
1186 + // Make the image URL
1187 + foreach($ids as $k => $v){
1188 +
1189 + $image = pagelayer_image($v);
1190 + $urls['i'.$v] = @$image['url'];
1191 +
1192 + $el['atts']['slider'] .= '<div class="pagelayer-bgimg-slide" style="background-image:url(\''.$image['url'].'\')"></div>';
1193 +
1194 + }
1195 +
1196 + if(!empty($urls)){
1197 + $el['tmp']['bg_slider-urls'] = json_encode($urls);
1198 + }
1199 +
1200 + }
1201 +
1202 + // Col background parallax image.
1203 + if(!empty($el['atts']['parallax_img'])){
1204 + $img_size = @$el['tmp']['parallax_img-'.$el['atts']['parallax_id_size'].'-url'];
1205 + $el['atts']['parallax_img_src'] = empty($img_size) ? @$el['tmp']['parallax_img-url'] : $img_size;
1206 + }
1207 +
1208 +}
1209 +
1210 +// Just for BG handling
1211 +function pagelayer_bg_video(&$el){
1212 +
1213 + if(empty($el['tmp']['bg_video_src-url'])){
1214 + return false;
1215 + }
1216 +
1217 + // Get the video URL for the iframe
1218 + $iframe_atts = pagelayer_video_url($el['tmp']['bg_video_src-url'], true);
1219 +
1220 + $source = esc_url( $el['tmp']['bg_video_src-url'] );
1221 + $source = str_replace('&amp;', '&', $source);
1222 + $url = parse_url($source);
1223 +
1224 + $iframe_atts['src'] .= substr_count($iframe_atts['src'], '?') > 0 ? '' : '?';
1225 +
1226 + if(!empty($el['atts']['mute'])){
1227 + $iframe_atts['src'] .= "&mute=1";
1228 + $el['atts']['mute'] = " muted ";
1229 + }else{
1230 + $iframe_atts['src'] .= "&mute=0";
1231 + $el['atts']['mute'] = "";
1232 + }
1233 +
1234 + if(empty($el['atts']['stop_loop'])){
1235 + $iframe_atts['src'] .= "&loop=1";
1236 + $el['atts']['stop_loop'] = " loop ";
1237 + }else{
1238 + $iframe_atts['src'] .= "&loop=0";
1239 + $el['atts']['stop_loop'] = "";
1240 + }
1241 +
1242 + if (!empty($source)) {
1243 +
1244 + if ($iframe_atts['type'] == 'youtube') {
1245 +
1246 + $settings = ' data-loop="'.( !empty($el['atts']['stop_loop']) ? 1 : 0 ).'" data-mute="'.( !empty($el['atts']['mute']) ? 1 : 0 ).'" data-videoid = "'.( $iframe_atts['id'] ).'"';
1247 +
1248 + $el['atts']['vid_src'] = '<div class = "pagelayer-youtube-video" '. $settings .'></div>';
1249 +
1250 + } else if ($iframe_atts['type'] == 'vimeo') {
1251 +
1252 + $el['atts']['vid_src'] = '<iframe src="'.$iframe_atts['src'].'&background=1&autoplay=1&byline=0&title=0" allowfullscreen="1" webkitallowfullscreen="1" mozallowfullscreen="1" frameborder="0"></iframe>';
1253 +
1254 + }else{
1255 +
1256 + $el['atts']['vid_src'] = '<video autoplay playsinline '.$el['atts']['mute'].$el['atts']['stop_loop'].'>'.
1257 + '<source src="'.$iframe_atts['src'].'" type="video/mp4">'.
1258 + '</video>';
1259 +
1260 + }
1261 + }
1262 +}
1263 +
1264 +// Heading Handler
1265 +function pagelayer_sc_heading(&$el){
1266 + //Backward compatibility for new link props
1267 + pagelayer_add_link_backward($el, array('rel' => '', 'selector' => '.pagelayer-link-sel'));
1268 +}
1269 +
1270 +// Heading Handler
1271 +function pagelayer_sc_icon(&$el){
1272 + //Backward compatibility for new link props
1273 + pagelayer_add_link_backward($el, array('rel' => '', 'selector' => '.pagelayer-ele-link'));
1274 +}
1275 +
1276 +// Heading Handler
1277 +function pagelayer_sc_badge(&$el){
1278 + //Backward compatibility for new link props
1279 + pagelayer_add_link_backward($el, array(
1280 + 'link' => 'badge_url',
1281 + 'rel' => '',
1282 + 'target' => 'badge_target',
1283 + 'selector' => '.pagelayer-ele-link'
1284 + ));
1285 +}
1286 +
1287 +// Heading Handler
1288 +function pagelayer_sc_btn(&$el){
1289 + //Backward compatibility for new link props
1290 + pagelayer_add_link_backward($el, array('selector' => '.pagelayer-btn-holder'));
1291 +}
1292 +
1293 +// Image Handler
1294 +function pagelayer_sc_social(&$el){
1295 +
1296 + //Backward compatibility for new link props
1297 + pagelayer_add_link_backward($el, array(
1298 + 'link' => 'social_url',
1299 + 'rel' => '',
1300 + 'selector' => '.pagelayer-ele-link'
1301 + ));
1302 +
1303 + if(empty($el['atts']['icon'])) return;
1304 + $icon = explode(' fa-', $el['atts']['icon']);
1305 + $el['classes'][] = ['.pagelayer-icon-holder' => 'pagelayer-'.$icon[1]];
1306 +}
1307 +
1308 +// Image Handler
1309 +function pagelayer_sc_image(&$el){
1310 +
1311 + // Decide the image URL
1312 + $el['atts']['func_id'] = @$el['tmp']['id-'.$el['atts']['id-size'].'-url'];
1313 + $el['atts']['func_id'] = empty($el['atts']['func_id']) ? @$el['tmp']['id-url'] : $el['atts']['func_id'];
1314 + $el['atts']['pagelayer-srcset'] = $el['atts']['func_id'].', '.$el['atts']['func_id'].' 1x, ';
1315 +
1316 + $image_atts = array(
1317 + 'name' => 'id',
1318 + 'size' => 'id-size'
1319 + );
1320 +
1321 + pagelayer_get_img_srcset($el, $image_atts);
1322 +
1323 + // What is the link ?
1324 + if(!empty($el['atts']['link_type'])){
1325 +
1326 + // Custom url
1327 + if($el['atts']['link_type'] == 'custom_url'){
1328 +
1329 + // Backward compatibility for new link props
1330 + pagelayer_add_link_backward($el, array( 'rel' => '', 'selector' => '.pagelayer-ele-link'));
1331 +
1332 + $el['atts']['func_link'] = @$el['tmp']['link'];
1333 + }
1334 +
1335 + // Link to the media file itself
1336 + if($el['atts']['link_type'] == 'media_file'){
1337 + $el['atts']['func_link'] = $el['atts']['func_id'];
1338 + }
1339 +
1340 + // Lightbox
1341 + if($el['atts']['link_type'] == 'lightbox'){
1342 + $el['atts']['func_link'] = $el['atts']['func_id'];
1343 + }
1344 +
1345 + }
1346 +
1347 + //pagelayer_print($el);
1348 +
1349 +}
1350 +
1351 +// Image Slider Handler
1352 +function pagelayer_sc_image_slider(&$el){
1353 +
1354 + // Backward compatibility for new link props
1355 + if( !empty($el['atts']['link_type']) && $el['atts']['link_type'] == 'custom_url' ){
1356 + pagelayer_add_link_backward($el, array( 'rel' => '', 'selector' => '.pagelayer-link-sel'));
1357 + }
1358 +
1359 + if(empty($el['atts']['ids'])){
1360 + $el['atts']['ids'] = '';
1361 + }
1362 +
1363 + $ids = pagelayer_maybe_explode(',', $el['atts']['ids']);
1364 + $urls = [];
1365 + $all_urls = [];
1366 + $final_urls = [];
1367 + $ul = [];
1368 + $size = $el['atts']['size'];
1369 +
1370 + // Make the image URL
1371 + foreach($ids as $k => $v){
1372 +
1373 + $image = pagelayer_image($v);
1374 +
1375 + $final_urls[$v] = empty($image[$size.'-url']) ? @$image['url'] : $image[$size.'-url'];
1376 +
1377 + $urls['i'.$v] = @$image['url'];
1378 +
1379 + foreach($image as $kk => $vv){
1380 + $si = strstr($kk, '-url', true);
1381 + if(!empty($si)){
1382 + $all_urls['i'.$v][$si] = $vv;
1383 + }
1384 + }
1385 +
1386 + $li = '<li class="pagelayer-slider-item">';
1387 +
1388 + // Any Link ?
1389 + if(!empty($el['atts']['link_type'])){
1390 + $link = ($el['atts']['link_type'] == 'media_file' ? (!empty($image['url']) ? $image['url'] : $final_urls[$v]) : @$el['tmp']['link']);
1391 + $li .= '<a href="'.$link.'" class="pagelayer-link-sel">';
1392 + }
1393 +
1394 + // The Image
1395 + $li .= '<img class="pagelayer-img" src="'.$final_urls[$v].'" title="'.$image['title'].'" alt="'.$image['alt'].'">';
1396 +
1397 + if(!empty($el['atts']['link_type'])){
1398 + $li .= '</a>';
1399 + }
1400 +
1401 + $li .= '</li>';
1402 +
1403 + $ul[] = $li;
1404 +
1405 + }
1406 +
1407 + //pagelayer_print($urls);
1408 + //pagelayer_print($final_urls);
1409 + //pagelayer_print($all_urls);
1410 +
1411 + // Make the TMP vars
1412 + if(!empty($urls)){
1413 + $el['tmp']['ids-urls'] = json_encode($urls);
1414 + $el['tmp']['ids-all-urls'] = json_encode($all_urls);
1415 + $el['atts']['ul'] = implode('', $ul);
1416 +
1417 + // Which arrows to show
1418 + if(in_array(@$el['atts']['controls'], ['arrows', 'none'])){
1419 + $el['attr'][] = ['.pagelayer-image-slider-ul' => 'data-pager="false"'];
1420 + }
1421 +
1422 + if(in_array(@$el['atts']['controls'], ['pager', 'none'])){
1423 + $el['attr'][] = ['.pagelayer-image-slider-ul' => 'data-controls="false"'];
1424 + }
1425 + }
1426 +
1427 +};
1428 +
1429 +//Grid Gallery Handler
1430 +function pagelayer_sc_grid_gallery(&$el){
1431 +
1432 + if(empty($el['atts']['ids'])){
1433 + $el['atts']['ids'] = '';
1434 + }
1435 +
1436 + $ids = pagelayer_maybe_explode(',', $el['atts']['ids']);
1437 + $urls = [];
1438 + $all_urls = [];
1439 + $final_urls = [];
1440 + $ul = [];
1441 + $pagin = '<li class="pagelayer-grid-page-item active">1</li>';
1442 + $size = $el['atts']['size'];
1443 + $i = 0;
1444 + $j = 1;
1445 + $img_Page = $el['atts']['images_no'];
1446 + $gallery_rand = 'gallery-id-'.floor((rand() * 100) + 1);
1447 +
1448 + $ul[] = '<ul class="pagelayer-grid-gallery-ul">';
1449 + // Make the image URL
1450 + foreach($ids as $k => $v){
1451 +
1452 + $image = pagelayer_image($v);
1453 +
1454 + $final_urls[$v] = empty($image[$size.'-url']) ? @$image['url'] : $image[$size.'-url'];
1455 +
1456 + $urls['i'.$v] = @$image['url'];
1457 + $links['i'.$v] = @$image['link'];
1458 + $titles['i'.$v] = @$image['title'];
1459 + $captions['i'.$v] = @$image['caption'];
1460 +
1461 + foreach($image as $kk => $vv){
1462 + $si = strstr($kk, '-url', true);
1463 + if(!empty($si)){
1464 + $all_urls['i'.$v][$si] = $vv;
1465 + }
1466 + }
1467 +
1468 + if($img_Page != 0 && ($i % $img_Page) == 0 && $i != 0 ){
1469 + $ul[] = '</ul><ul class="pagelayer-grid-gallery-ul">';
1470 + $j++;
1471 + $pagin .= '<li class="pagelayer-grid-page-item">'.$j.'</li>';
1472 + }
1473 +
1474 + $li = '<li class="pagelayer-gallery-item" >';
1475 +
1476 + if(empty($el['atts']['link_to'])){
1477 + $li .= '<div>';
1478 + }
1479 +
1480 + // Any Link ?
1481 + if(!empty($el['atts']['link_to']) && $el['atts']['link_to'] == 'media_file'){
1482 + $link = ($el['atts']['link_to'] == 'media_file' ? $final_urls[$v] : @$el['atts']['link']);
1483 + $li .= '<a href="'.$link.'" class="pagelayer-ele-link">';
1484 + }
1485 +
1486 + // Any Link ?
1487 + if(!empty($el['atts']['link_to']) && $el['atts']['link_to'] == 'attachment' ){
1488 + $link = $image['link'];
1489 + $li .= '<a href="'.$link.'" class="pagelayer-ele-link">';
1490 + }
1491 +
1492 + if(!empty($el['atts']['link_to']) && $el['atts']['link_to'] == 'lightbox'){
1493 + $li .= '<a href="'.$image['url'].'" data-lightbox-gallery="'.$gallery_rand.'" alt="'.$image['alt'].'" class="pagelayer-ele-link" pagelayer-grid-gallery-type="'.$el['atts']['link_to'].'">';
1494 + }
1495 + // The Image
1496 + $li .= '<img class="pagelayer-img" src="'.$final_urls[$v].'" title="'.$image['title'].'" alt="'.$image['alt'].'">';
1497 +
1498 + if(!empty($el['atts']['caption'])){
1499 + $li .= '<span class="pagelayer-grid-gallery-caption">'.$image['caption'].'</span>';
1500 + }
1501 +
1502 + if(!empty($el['atts']['link_to'])){
1503 + $li .= '</a>';
1504 + }
1505 +
1506 + if(empty($el['atts']['link_to'])){
1507 + $li .= '</div>';
1508 + }
1509 +
1510 + $li .= '</li>';
1511 +
1512 + $ul[] = $li;
1513 + $i++;
1514 + }
1515 +
1516 + $ul[] = '</ul>';
1517 +
1518 + $pagiComplete[] = '<div class="pagelayer-grid-gallery-pagination"><ul class="pagelayer-grid-page-ul">'.'<li class="pagelayer-grid-page-item">&laquo;</li>'.$pagin.'<li class="pagelayer-grid-page-item">&raquo;</li>'.'</ul></div>';
1519 + //pagelayer_print($urls);
1520 + //pagelayer_print($final_urls);
1521 + //pagelayer_print($all_urls);
1522 +
1523 + // Make the TMP vars
1524 + if(!empty($urls)){
1525 + $el['tmp']['ids-urls'] = json_encode($urls);
1526 + $el['tmp']['ids-all-urls'] = json_encode($all_urls);
1527 + $el['tmp']['ids-all-links'] = json_encode($links);
1528 + $el['tmp']['ids-all-titles'] = json_encode($titles);
1529 + $el['tmp']['ids-all-captions'] = json_encode($captions);
1530 + $el['atts']['ul'] = implode('', $ul);
1531 + $el['atts']['pagin'] = ($j>1) ? implode('', $pagiComplete) : '';
1532 + $el['tmp']['gallery-random-id'] = $gallery_rand;
1533 +
1534 + }
1535 +}
1536 +
1537 +// Testimonial Handler
1538 +function pagelayer_sc_testimonial(&$el){
1539 +
1540 + if(empty($el['atts']['avatar']) || !empty($el['tmp']['avatar-no-image-set'])){
1541 + $el['atts']['avatar'] = '';
1542 + }
1543 +
1544 + $custom_size = empty($el['atts']['custom_size']) ? '' : @$el['tmp']['avatar-'.$el['atts']['custom_size'].'-url'];
1545 + $el['atts']['func_image'] = empty($custom_size) ? @$el['tmp']['avatar-url'] : $custom_size;
1546 +
1547 +}
1548 +
1549 +// Video Handler
1550 +function pagelayer_sc_video(&$el){
1551 +
1552 + $el['atts']['custom_size'] = empty($el['atts']['custom_size']) ? '' : $el['atts']['custom_size'];
1553 + $el['tmp']['video_overlay_image-url'] = empty($el['tmp']['video_overlay_image-url']) ? '' : $el['tmp']['video_overlay_image-url'];
1554 + $el['atts']['video_overlay_image'] = empty($el['atts']['video_overlay_image']) ? '' : $el['atts']['video_overlay_image'];
1555 +
1556 + $el['atts']['video_overlay_image-url'] = empty($el['tmp']['video_overlay_image-'.$el['atts']['custom_size'].'-url']) ? $el['tmp']['video_overlay_image-url'] : $el['tmp']['video_overlay_image-'.$el['atts']['custom_size'].'-url'];
1557 + $el['atts']['video_overlay_image-url'] = empty($el['atts']['video_overlay_image-url']) ? $el['atts']['video_overlay_image'] : $el['atts']['video_overlay_image-url'];
1558 +
1559 + // Get the video URL for the iframe
1560 + $vid_atts = pagelayer_video_url($el['tmp']['src-url'], true);
1561 +
1562 + $vid_atts['src'] .= substr_count($vid_atts['src'], '?') > 0 ? '' : '?';
1563 +
1564 + $vid_atts['src'] .= !empty($el['atts']['autoplay']) ? '&autoplay=1' : '&autoplay=0' ;
1565 +
1566 + $mute = !empty($el['atts']['mute']) ? 1 : 0;
1567 + $vid_atts['src'] .='&'.($vid_atts['type'] == 'vimeo' ? 'muted' : 'mute').'='.$mute;
1568 +
1569 + $vid_atts['src'] .= !empty($el['atts']['loop']) == 'true' ? '&loop=1' : '&loop=0' ;
1570 +
1571 + $el['atts']['vid_src'] = $vid_atts['src'].($vid_atts['type'] == 'youtube' ? '&playlist='.$vid_atts['id'] : '');
1572 +
1573 + $el['tmp']['ele_id'] = $el['id'];
1574 +
1575 +}
1576 +
1577 +// Shortcodes Handler
1578 +function pagelayer_sc_shortcodes(&$el){
1579 + $is_live = pagelayer_is_live();
1580 + if(empty($is_live)){
1581 + $el['tmp']['shortcode'] = pagelayer_the_content($el['atts']['data']);
1582 + }
1583 +}
1584 +
1585 +// Missing Handler
1586 +function pagelayer_sc_missing(&$el){
1587 + if(pagelayer_is_live()){
1588 + $el['tmp']['missing_msg'] = __('The pagelayer doesn’t support this content. You can leave this block intact or remove it completely.');
1589 + }
1590 +}
1591 +
1592 +// Shortcodes Handler
1593 +function pagelayer_sc_wp_widgets(&$el){
1594 +
1595 + global $wp_registered_sidebars;
1596 +
1597 + $data = '';
1598 + foreach($wp_registered_sidebars as $v){
1599 + if($el['atts']['sidebar'] == $v['id']){
1600 + ob_start();
1601 + dynamic_sidebar($v['id']);
1602 + $data = ob_get_clean();
1603 + }
1604 + }
1605 +
1606 + $el['tmp']['data'] = $data;
1607 +}
1608 +
1609 +// Service Handler
1610 +function pagelayer_sc_service(&$el){
1611 +
1612 + //Backward compatibility for new link props
1613 + pagelayer_add_link_backward($el, array(
1614 + 'link' => 'box_url',
1615 + 'rel' => '',
1616 + 'target' => 'box_target',
1617 + 'selector' => '.pagelayer-box-link'
1618 + ));
1619 +
1620 + //Backward compatibility for new link props
1621 + pagelayer_add_link_backward($el, array(
1622 + 'link' => 'heading_url',
1623 + 'rel' => '',
1624 + 'target' => 'heading_target',
1625 + 'selector' => '.pagelayer-service-heading-link'
1626 + ));
1627 +
1628 + //Backward compatibility for new link props
1629 + pagelayer_add_link_backward($el, array(
1630 + 'link' => 'service_button_url',
1631 + 'rel' => '',
1632 + 'target' => 'service_button_target',
1633 + 'selector' => '.pagelayer-service-btn'
1634 + ));
1635 +
1636 + if(!empty($el['atts']['service_image'])){
1637 +
1638 + // Decide the image URL
1639 + $el['atts']['func_image'] = @$el['tmp']['service_image-'.$el['atts']['service_image_size'].'-url'];
1640 + $el['atts']['func_image'] = empty($el['atts']['func_image']) ? @$el['tmp']['service_image-url'] : $el['atts']['func_image'];
1641 + $el['atts']['pagelayer-srcset'] = $el['atts']['func_image'].', '.$el['atts']['func_image'].' 1x, ';
1642 +
1643 + $image_atts = array(
1644 + 'name' => 'service_image',
1645 + 'size' => 'service_image_size'
1646 + );
1647 +
1648 + pagelayer_get_img_srcset($el, $image_atts);
1649 +
1650 + }
1651 +}
1652 +
1653 +// Icon box Handler
1654 +function pagelayer_sc_iconbox(&$el){
1655 +
1656 + //Backward compatibility for new link props
1657 + pagelayer_add_link_backward($el, array(
1658 + 'link' => 'box_url',
1659 + 'rel' => '',
1660 + 'target' => 'box_target',
1661 + 'selector' => '.pagelayer-box-link'
1662 + ));
1663 +
1664 + //Backward compatibility for new link props
1665 + pagelayer_add_link_backward($el, array(
1666 + 'link' => 'heading_url',
1667 + 'rel' => '',
1668 + 'target' => 'heading_target',
1669 + 'selector' => '.pagelayer-service-heading-link',
1670 + ));
1671 +
1672 +}
1673 +
1674 +// Anchor Handler
1675 +function pagelayer_sc_anchor(&$el){
1676 + $el['atts']['title'] = empty($el['atts']['title']) ? '' : esc_attr(sanitize_html_class( $el['atts']['title']));
1677 +}
1678 +
1679 +function pagelayer_sc_google_maps(&$el){
1680 +
1681 + $el['atts']['show_v2'] = true;
1682 +
1683 + if(empty($el['atts']['api_version'])){
1684 + $el['atts']['src_code'] = '';
1685 + return;
1686 + }
1687 +
1688 + $el['atts']['show_v2'] = false;
1689 + $api_key = @$el['atts']['api_key'];
1690 +
1691 + $gmaps_api = get_option('pagelayer-gmaps-api-key');
1692 +
1693 + if( empty($api_key) && !empty($gmaps_api) ){
1694 + $api_key = $gmaps_api;
1695 + }
1696 +
1697 + if($el['atts']['map_modes'] == 'view'){
1698 + $el['atts']['center'] = empty($el['atts']['center']) ? '-33.8569,151.2152' : $el['atts']['center'];
1699 + }
1700 +
1701 + $src_code = (empty($el['atts']['center']) ? '' : '&center='.$el['atts']['center']).($el['atts']['map_modes'] == 'streetview' ? '' : '&maptype='.$el['atts']['map_type'].'&zoom='.$el['atts']['zoom']);
1702 +
1703 + switch($el['atts']['map_modes']){
1704 + case 'place':
1705 + $src_code .= '&q='.(empty($el['atts']['address']) ? 'New York, New York, USA' : urlencode($el['atts']['address']) );
1706 + break;
1707 +
1708 + case 'directions':
1709 + $src_code .= '&origin='.(empty($el['atts']['direction_origin']) ? 'Oslow Norway' : urlencode($el['atts']['direction_origin']) );
1710 + $src_code .= '&destination='.(empty($el['atts']['direction_destination']) ? 'Telemark Norway' : urlencode($el['atts']['direction_destination']) );
1711 + $src_code .= (empty($el['atts']['direction_waypoints']) ? '' : '&waypoints='.join('|', explode(' ', trim($el['atts']['direction_waypoints']))) );
1712 + $src_code .= (empty($el['atts']['direction_modes']) ? '' : '&mode='.$el['atts']['direction_modes'] );
1713 + $src_code .= (empty($el['atts']['direction_avoid']) ? '' : '&avoid='.join('|', explode(',', $el['atts']['direction_avoid'])) );
1714 + $src_code .= (empty($el['atts']['direction_units']) ? '' : '&units='.$el['atts']['direction_units'] );
1715 + break;
1716 +
1717 + case 'streetview':
1718 + $src_code .= '&pano='.(empty($el['atts']['streetview_pano']) ? 'eTnPNGoy4bxR9LpjjfFuOw' : $el['atts']['streetview_pano'] );
1719 + $src_code .= '&location='.(empty($el['atts']['streetview_location']) ? '46.414382,10.013988' : $el['atts']['streetview_location'] );
1720 + $src_code .= (empty($el['atts']['streetview_heading']) ? '' : '&heading='.$el['atts']['streetview_heading'] );
1721 + $src_code .= (empty($el['atts']['streetview_pitch']) ? '' : '&pitch='.$el['atts']['streetview_pitch'] );
1722 + $src_code .= (empty($el['atts']['streetview_fov']) ? '' : '&fov='.$el['atts']['streetview_fov'] );
1723 + break;
1724 +
1725 + case 'search':
1726 + $src_code .= '&q='.(empty($el['atts']['search_term']) ? 'Record stores in Seattle' : urlencode($el['atts']['search_term']) );
1727 + break;
1728 +
1729 + }
1730 +
1731 + $src_iframe = 'https://www.google.com/maps/embed/v1/'.$el['atts']['map_modes'].'?key='.$api_key.$src_code;
1732 +
1733 + $el['atts']['src_code'] = '<iframe width="600" height="450" style="border:0" loading="lazy" allowfullscreen src="'.$src_iframe.'"></iframe>';
1734 +
1735 +}
1736 +
1737 +/*pagelayer_print($atts);
1738 +pagelayer_print($content);
1739 +die();*/
1740 +
1741 +/////////////////////////////////////
1742 +// Miscellaneous Shortcode Functions
1743 +/////////////////////////////////////
1744 +
1745 +// The font family list
1746 +function pagelayer_font_family(){
1747 + return array(
1748 + 'arial' => 'Arial',
1749 + 'terminal' => 'Terminal'
1750 + );
1751 +}
1752 +
1753 +// Supported Icons
1754 +function pagelayer_icon_class_list(){
1755 + return array();
1756 +}
1757 +
1758 +// The attribute names Pagelayer is allowed to emit from a user supplied
1759 +// attribute string. This is an ALLOWLIST and it is enforced at parse time,
1760 +// so it applies to every call site (Custom Attributes, link attrs, anything
1761 +// added later), to every visitor and to content stored by any version.
1762 +function pagelayer_allowed_attributes(){
1763 +
1764 + static $allowed = null;
1765 +
1766 + if(!is_null($allowed)){
1767 + return $allowed;
1768 + }
1769 +
1770 + $allowed = array(
1771 + // Generic / structural
1772 + 'id', 'class', 'style', 'title', 'lang', 'dir', 'tabindex', 'hidden',
1773 + 'role', 'name', 'value', 'type', 'slot', 'translate', 'draggable',
1774 + 'spellcheck', 'accesskey', 'itemprop', 'itemtype', 'itemscope', 'itemid',
1775 + // Links
1776 + 'href', 'target', 'rel', 'download', 'hreflang', 'referrerpolicy', 'ping',
1777 + // Media / images
1778 + 'src', 'srcset', 'sizes', 'alt', 'width', 'height', 'loading', 'decoding',
1779 + 'crossorigin', 'usemap', 'ismap', 'poster', 'preload', 'controls',
1780 + 'controlslist', 'loop', 'muted', 'autoplay', 'playsinline', 'kind',
1781 + 'srclang', 'label', 'default', 'disablepictureinpicture',
1782 + 'disableremoteplayback',
1783 + // Forms
1784 + 'placeholder', 'required', 'disabled', 'readonly', 'pattern', 'min',
1785 + 'max', 'step', 'maxlength', 'minlength', 'multiple', 'size', 'checked',
1786 + 'selected', 'autocomplete', 'autofocus', 'for', 'form', 'action',
1787 + 'method', 'enctype', 'novalidate', 'accept', 'accept-charset', 'cols',
1788 + 'rows', 'wrap', 'list', 'inputmode', 'formaction', 'formmethod',
1789 + 'formenctype', 'formtarget', 'formnovalidate',
1790 + // Tables
1791 + 'colspan', 'rowspan', 'headers', 'scope', 'abbr', 'span',
1792 + // Misc
1793 + 'datetime', 'cite', 'open', 'start', 'reversed', 'coords', 'shape',
1794 + 'high', 'low', 'optimum', 'media', 'content'
1795 + );
1796 +
1797 + // Add-ons can register extra attribute names. Event handlers are dropped
1798 + // by pagelayer_is_allowed_attribute() whatever this filter returns.
1799 + $allowed = apply_filters('pagelayer_allowed_attributes', $allowed);
1800 + $allowed = array_map('strtolower', (array) $allowed);
1801 +
1802 + return $allowed;
1803 +}
1804 +
1805 +// Can this attribute name be emitted ?
1806 +function pagelayer_is_allowed_attribute($att){
1807 +
1808 + $att = strtolower(trim((string) $att));
1809 +
1810 + if($att === ''){
1811 + return false;
1812 + }
1813 +
1814 + // Never emit an event handler, whatever the allowlist says
1815 + if(strpos($att, 'on') === 0){
1816 + return false;
1817 + }
1818 +
1819 + // data-* and aria-* never execute
1820 + if(strpos($att, 'data-') === 0 || strpos($att, 'aria-') === 0){
1821 + return true;
1822 + }
1823 +
1824 + return in_array($att, pagelayer_allowed_attributes());
1825 +}
1826 +
1827 +// Does this URL carry a scheme that can execute script ?
1828 +function pagelayer_attribute_url_is_safe($url){
1829 +
1830 + $url = pagelayer_optimized_decode_entities((string) $url);
1831 +
1832 + // Browsers also decode a numeric entity that was not closed with a
1833 + // semicolon (jav&#x09ascript:), so decode those the same way
1834 + $url = preg_replace_callback('/&#x([0-9a-f]+);?/i', function($m){
1835 + return chr(hexdec($m[1]) & 0xFF);
1836 + }, $url);
1837 +
1838 + $url = preg_replace_callback('/&#(\d+);?/', function($m){
1839 + return chr(((int) $m[1]) & 0xFF);
1840 + }, $url);
1841 +
1842 + // Browsers ignore control characters and whitespace inside a scheme
1843 + $url = preg_replace('/[\x00-\x20\x7f]/', '', $url);
1844 +
1845 + if($url === ''){
1846 + return true;
1847 + }
1848 +
1849 + // No colon means a relative URL, nothing to check
1850 + $scheme = strstr($url, ':', true);
1851 +
1852 + if($scheme === false){
1853 + return true;
1854 + }
1855 +
1856 + // A colon inside a path, a query or a fragment is not a scheme
1857 + if(preg_match('#[/?\#]#', $scheme)){
1858 + return true;
1859 + }
1860 +
1861 + // What is left is flattened to letters, so that a stray character cannot
1862 + // hide the scheme from us
1863 + $scheme = strtolower(preg_replace('/[^a-z]/i', '', $scheme));
1864 +
1865 + // javascript:, vbscript:, livescript: and any other script scheme
1866 + if(strpos($scheme, 'script') !== false){
1867 + return false;
1868 + }
1869 +
1870 + // Only plain raster data URIs are allowed, no SVG and no blob/file/about
1871 + if(in_array($scheme, array('data', 'blob', 'about', 'file', 'filesystem'))){
1872 + return (bool) preg_match('/^data:image\/(png|jpe?g|gif|webp|bmp|x-icon|vnd\.microsoft\.icon);base64,[a-z0-9+\/=]+$/i', $url);
1873 + }
1874 +
1875 + return true;
1876 +}
1877 +
1878 +// Sanitize the value of an allowed attribute. Returns NULL if the whole
1879 +// attribute must be dropped.
1880 +function pagelayer_sanitize_attribute_value($att, $value){
1881 +
1882 + $att = strtolower(trim((string) $att));
1883 + $value = (string) $value;
1884 +
1885 + // Attributes that hold one or more URLs
1886 + $url_atts = array('href', 'src', 'srcset', 'poster', 'action', 'formaction',
1887 + 'cite', 'ping', 'usemap', 'itemtype', 'itemid');
1888 +
1889 + if(in_array($att, $url_atts)){
1890 +
1891 + // srcset and ping can hold a list of URLs
1892 + $parts = preg_split('/[,\s]+/', trim($value), -1, PREG_SPLIT_NO_EMPTY);
1893 +
1894 + if(!empty($parts)){
1895 + foreach($parts as $part){
1896 + if(!pagelayer_attribute_url_is_safe($part)){
1897 + return null;
1898 + }
1899 + }
1900 + }
1901 +
1902 + return $value;
1903 + }
1904 +
1905 + // Inline CSS can execute in some engines
1906 + if($att == 'style'){
1907 +
1908 + $test = pagelayer_optimized_decode_entities($value);
1909 + $test = preg_replace('/[\x00-\x20\x7f]/', '', $test);
1910 +
1911 + if(preg_match('/(expression\(|-moz-binding|behavior:|@import|script:)/i', $test)){
1912 + return null;
1913 + }
1914 + }
1915 +
1916 + return $value;
1917 +}
1918 +
1919 +// Function to convert string into set of attributes and their corresponding values.
1920 +function pagelayer_string_to_attributes($val){
1921 +
1922 + $final_att = [];
1923 + $semi_arr = explode(';', $val);
1924 +
1925 + foreach($semi_arr as $att){
1926 +
1927 + $attrs = preg_split("/=/", trim($att), 2);
1928 +
1929 + if(empty($attrs[0]) || !preg_match("/^[a-z_]+[\w:.-]*$/i", $attrs[0]) ){
1930 + continue;
1931 + }
1932 +
1933 + $name = strtolower(trim($attrs[0]));
1934 +
1935 + // SECURITY : only attribute names we support are emitted. The check
1936 + // lives here, at the parser, so it does not depend on the call site,
1937 + // on who is viewing the page or on when the content was stored.
1938 + if(pagelayer_should_show_xss_warning() && !pagelayer_is_allowed_attribute($name)){
1939 + continue;
1940 + }
1941 +
1942 + $value = isset($attrs[1]) ? $attrs[1] : '';
1943 + $value = pagelayer_sanitize_attribute_value($name, $value);
1944 +
1945 + // Dropped by the value check ?
1946 + if(is_null($value)){
1947 + continue;
1948 + }
1949 +
1950 + $final_att[$name] = $value;
1951 + }
1952 +
1953 + return $final_att;
1954 +
1955 +}
1956 +
1957 +// Retina image setting attribute.
1958 +function pagelayer_get_img_srcset(&$el, $image_atts){
1959 +
1960 + // Check if retina images is set
1961 + if(isset($el['tmp'][$image_atts['name'].'-retina-url']) && strpos($el['tmp'][$image_atts['name'].'-retina-url'],'default-image') == false){
1962 + $retina_image = @$el['tmp'][$image_atts['name'].'-retina-'.$el['atts'][$image_atts['size']].'-url'];
1963 + $retina_image = empty($retina_image) ? @$el['tmp'][$image_atts['name'].'-retina-url'] : $retina_image;
1964 + $el['atts']['pagelayer-srcset'] .= $retina_image.' 2x, ';
1965 + }
1966 +
1967 + // Check if retina mobile images is set
1968 + if(isset($el['tmp'][$image_atts['name'].'-retina-mobile-url']) && strpos($el['tmp'][$image_atts['name'].'-retina-mobile-url'],'default-image') == false){
1969 + $retina_image_mobile = @$el['tmp'][$image_atts['name'].'-retina-mobile-'.$el['atts'][$image_atts['size']].'-url'];
1970 + $retina_image_mobile = empty($retina_image_mobile) ? @$el['tmp'][$image_atts['name'].'-retina-mobile-url'] : $retina_image_mobile;
1971 + $el['atts']['pagelayer-srcset'] .= $retina_image_mobile.' 3x';
1972 + }
1973 +}
1974 +
1975 +// Backward compatibility of target and rel attrs for link
1976 +function pagelayer_add_link_backward(&$el, $atts = array()){
1977 + global $pagelayer;
1978 +
1979 + $defaults = array(
1980 + 'link' => 'link',
1981 + 'target' => 'target',
1982 + 'rel' => 'rel',
1983 + 'selector' => 0,
1984 + );
1985 +
1986 + $_atts = wp_parse_args( $atts, $defaults );
1987 +
1988 + if(empty($el['atts'][$_atts['link']])){
1989 + return;
1990 + }
1991 +
1992 + $link = array();
1993 +
1994 + if(!empty($_atts['target']) && !empty($el['atts'][$_atts['target']]) ){
1995 + $link['target'] = true;
1996 + unset($el['oAtts'][$_atts['target']]);
1997 + }
1998 +
1999 + if(!empty($_atts['rel']) && !empty($el['atts'][$_atts['rel']]) ){
2000 + $link['attrs'] = 'rel='.$el['atts'][$_atts['rel']];
2001 + unset($el['oAtts'][$_atts['rel']]);
2002 + }
2003 +
2004 + if(empty($link)){
2005 + return;
2006 + }
2007 +
2008 + // Set Attributes for backward compatibility
2009 + if(!empty($link['target'])){
2010 + $el['attr'][][$_atts['selector']] = 'target="_blank"';
2011 + }
2012 +
2013 + // Set Attributes for backward compatibility
2014 + if(!empty($link['attrs']) ){
2015 + $el['attr'][][$_atts['selector']] = $link['attrs'];
2016 + }
2017 +
2018 + if(!is_array($el['atts'][$_atts['link']])){
2019 + $link['link'] = @$el['atts'][$_atts['link']];
2020 + }
2021 +
2022 + $el['oAtts'][$_atts['link']] = $link;
2023 + $el['atts'][$_atts['link']] = $link;
2024 +}