PluginProbe
UsersWP – Front-end login form, User Registration, User Profile & Members Directory plugin for WP / 1.2.75
UsersWP – Front-end login form, User Registration, User Profile & Members Directory plugin for WP v1.2.75
1.2.76 1.2.75 1.2.74 1.2.73 1.2.72 1.2.71 1.2.70 1.2.69 1.2.68 1.2.67 1.2.66 1.2.65 1.2.64 1.2.63 trunk 1.0.10 1.0.11 1.0.12 1.0.13 1.0.14 1.0.15 1.0.16 1.0.17 1.0.18 1.0.19 All 176 releases
userswp / vendor / ayecode / wp-super-duper / wp-super-duper.php

wp-super-duper.php in UsersWP – Front-end login form, User Registration, User Profile & Members Directory plugin for WP 1.2.75, at vendor/ayecode/wp-super-duper/wp-super-duper.php

5,536 lines 194.7 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 if ( ! defined( 'ABSPATH' ) ) {
3 exit;
4 }
5
6 if ( ! class_exists( 'WP_Super_Duper' ) ) {
7
8 define( 'SUPER_DUPER_VER', '1.2.37' );
9
10 /**
11 * A Class to be able to create a Widget, Shortcode or Block to be able to output content for WordPress.
12 *
13 * Should not be called direct but extended instead.
14 *
15 * Class WP_Super_Duper
16 * @since 1.0.16 change log moved to file change-log.txt - CHANGED
17 * @ver 1.1.1
18 */
19 class WP_Super_Duper extends WP_Widget {
20
21 public $version = SUPER_DUPER_VER;
22 public $font_awesome_icon_version = "5.11.2";
23 public $block_code;
24 public $options;
25 public $base_id;
26 public $settings_hash;
27 public $arguments = array();
28 public $instance = array();
29 private $class_name;
30
31 /**
32 * The relative url to the current folder.
33 *
34 * @var string
35 */
36 public $url = '';
37
38 /**
39 * Take the array options and use them to build.
40 */
41 public function __construct( $options ) {
42 global $sd_widgets;
43
44 $sd_widgets[ $options['base_id'] ] = array(
45 'name' => $options['name'],
46 'class_name' => $options['class_name'],
47 'output_types' => !empty($options['output_types']) ? $options['output_types'] : array()
48 );
49 $this->base_id = $options['base_id'];
50 // lets filter the options before we do anything
51 $options = apply_filters( "wp_super_duper_options", $options );
52 $options = apply_filters( "wp_super_duper_options_{$this->base_id}", $options );
53 $options = $this->add_name_from_key( $options );
54 $this->options = $options;
55
56 $this->base_id = $options['base_id'];
57 $this->arguments = isset( $options['arguments'] ) ? $options['arguments'] : array();
58
59 // nested blocks can't work as a widget
60 if(!empty($this->options['nested-block'])){
61 if(empty($this->options['output_types'])){
62 $this->options['output_types'] = array('shortcode','block');
63 }elseif (($key = array_search('widget', $this->options['output_types'])) !== false) {
64 unset($this->options['output_types'][$key]);
65 }
66 }
67
68 // init parent
69 if(empty($this->options['output_types']) || in_array('widget',$this->options['output_types'])){
70 parent::__construct( $options['base_id'], $options['name'], $options['widget_ops'] );
71 }
72
73
74 if ( isset( $options['class_name'] ) ) {
75 // register widget
76 $this->class_name = $options['class_name'];
77
78 // register shortcode, this needs to be done even for blocks and widgets
79 $this->register_shortcode();
80
81
82 // Fusion Builder (avada) support
83 if ( function_exists( 'fusion_builder_map' ) ) {
84 add_action( 'init', array( $this, 'register_fusion_element' ) );
85 }
86
87 // maybe load the Bricks transformer class
88 if( class_exists('\Bricks\Elements', false) ){
89 add_action( 'init', array( $this, 'load_bricks_element_class' ) );
90 }
91
92 // register block
93 if(empty($this->options['output_types']) || in_array('block',$this->options['output_types'])){
94 add_action( 'admin_enqueue_scripts', array( $this, 'register_block' ) );
95 }
96 }
97
98 // add the CSS and JS we need ONCE
99 global $sd_widget_scripts;
100
101 if ( ! $sd_widget_scripts ) {
102 wp_add_inline_script( 'admin-widgets', $this->widget_js() );
103 wp_add_inline_script( 'customize-controls', $this->widget_js() );
104 wp_add_inline_style( 'widgets', $this->widget_css() );
105
106 // maybe add elementor editor styles
107 add_action( 'elementor/editor/after_enqueue_styles', array( $this, 'elementor_editor_styles' ) );
108
109 $sd_widget_scripts = true;
110
111 // add shortcode insert button once
112 add_action( 'media_buttons', array( $this, 'wp_media_buttons' ), 1 );
113 add_action( 'media_buttons', array( $this, 'shortcode_insert_button' ) );
114 // generatepress theme sections compatibility
115 if ( function_exists( 'generate_sections_sections_metabox' ) ) {
116 add_action( 'generate_sections_metabox', array( $this, 'shortcode_insert_button_script' ) );
117 }
118
119 /* Load script on Divi theme builder page */
120 if ( ( function_exists( 'et_builder_is_tb_admin_screen' ) && et_builder_is_tb_admin_screen() ) || ( function_exists( 'et_builder_d5_enabled' ) && et_builder_d5_enabled() && isset( $_GET['et_fb'] ) && '1' === $_GET['et_fb'] && et_pb_is_allowed( 'use_visual_builder' ) ) ) {
121 add_thickbox();
122 add_action( 'admin_footer', array( $this, 'shortcode_insert_button_script' ) );
123 }
124
125 if ( $this->is_preview() ) {
126 add_action( 'wp_footer', array( $this, 'shortcode_insert_button_script' ) );
127 // this makes the insert button work for elementor
128 add_action( 'elementor/editor/after_enqueue_scripts', array(
129 $this,
130 'shortcode_insert_button_script'
131 ) ); // for elementor
132 }
133 // this makes the insert button work for cornerstone
134 add_action( 'wp_print_footer_scripts', array( __CLASS__, 'maybe_cornerstone_builder' ) );
135
136 add_action( 'wp_ajax_super_duper_get_widget_settings', array( __CLASS__, 'get_widget_settings' ) );
137 add_action( 'wp_ajax_super_duper_get_picker', array( __CLASS__, 'get_picker' ) );
138
139 // add generator text to head
140 add_action( 'admin_head', array( $this, 'generator' ), 99 );
141 add_action( 'wp_head', array( $this, 'generator' ), 99 );
142 }
143
144 do_action( 'wp_super_duper_widget_init', $options, $this );
145 }
146
147 /**
148 * Load the Bricks conversion class if we are running Bricks.
149 * @return void
150 */
151 public function load_bricks_element_class() {
152 include_once __DIR__ . '/includes/class-super-duper-bricks-element.php';
153 }
154
155 /**
156 * The register widget function
157 * @return void
158 */
159 public function _register() {
160 if(empty($this->options['output_types']) || in_array('widget',$this->options['output_types'])){
161 parent::_register();
162 }
163 }
164
165 /**
166 * Add our widget CSS to elementor editor.
167 */
168 public function elementor_editor_styles() {
169 wp_add_inline_style( 'elementor-editor', $this->widget_css( false ) );
170 }
171
172 public function register_fusion_element() {
173
174 $options = $this->options;
175
176 if ( $this->base_id ) {
177
178 $params = $this->get_fusion_params();
179
180 $args = array(
181 'name' => $options['name'],
182 'shortcode' => $this->base_id,
183 'icon' => $options['block-icon'] ? $options['block-icon'] : 'far fa-square',
184 'allow_generator' => true,
185 );
186
187 if ( ! empty( $params ) ) {
188 $args['params'] = $params;
189 }
190
191 fusion_builder_map( $args );
192 }
193
194 }
195
196 public function get_fusion_params() {
197 $params = array();
198 $arguments = $this->get_arguments();
199
200 if ( ! empty( $arguments ) ) {
201 foreach ( $arguments as $key => $val ) {
202 $param = array();
203 // type
204 $param['type'] = str_replace(
205 array(
206 "text",
207 "number",
208 "email",
209 "color",
210 "checkbox"
211 ),
212 array(
213 "textfield",
214 "textfield",
215 "textfield",
216 "colorpicker",
217 "select",
218
219 ),
220 $val['type'] );
221
222 // multiselect
223 if ( $val['type'] == 'multiselect' || ( ( $param['type'] == 'select' || $val['type'] == 'select' ) && ! empty( $val['multiple'] ) ) ) {
224 $param['type'] = 'multiple_select';
225 $param['multiple'] = true;
226 }
227
228 // heading
229 $param['heading'] = isset( $val['title'] ) ? $val['title'] : '';
230
231 // description
232 $param['description'] = isset( $val['desc'] ) ? $val['desc'] : '';
233
234 // param_name
235 $param['param_name'] = $key;
236
237 // Default
238 $param['default'] = isset( $val['default'] ) ? $val['default'] : '';
239
240 // Group
241 if ( isset( $val['group'] ) ) {
242 $param['group'] = $val['group'];
243
244 if ( ! empty( $param['group'] ) ) {
245 // Fusion Builder converts the group name into a tab ID without sanitization and assigns it to the href.
246 // Replace some punctuation symbols.
247 $param['group'] = preg_replace( '/[\&,\(\)\:\/\\\\]/u', ' ', $param['group'] );
248 // Remove ' ".
249 $param['group'] = preg_replace( '/[\'\"]/u', '', $param['group'] );
250 // Replace consecutive spaces with single space.
251 $param['group'] = preg_replace( '/\s+/', ' ', $param['group'] );
252 }
253 }
254
255 // value
256 if ( $val['type'] == 'checkbox' ) {
257 if ( isset( $val['default'] ) && $val['default'] == '0' ) {
258 unset( $param['default'] );
259 }
260 $param['value'] = array( '0' => __( "No", 'ayecode-connect' ), '1' => __( "Yes", 'ayecode-connect' ) );
261 } elseif ( $param['type'] == 'select' || $param['type'] == 'multiple_select' ) {
262 $param['value'] = isset( $val['options'] ) ? $val['options'] : array();
263 } else {
264 $param['value'] = isset( $val['default'] ) ? $val['default'] : '';
265 }
266
267 // setup the param
268 $params[] = $param;
269
270 }
271 }
272
273
274 return $params;
275 }
276
277 /**
278 * Maybe insert the shortcode inserter button in the footer if we are in the cornerstone builder
279 */
280 public static function maybe_cornerstone_builder() {
281 if ( did_action( 'cornerstone_before_boot_app' ) ) {
282 self::shortcode_insert_button_script();
283 }
284 }
285
286 /**
287 * A function to ge the shortcode builder picker html.
288 *
289 * @param string $editor_id
290 *
291 * @return string
292 */
293 public static function get_picker( $editor_id = '' ) {
294 global $sd_widgets;
295
296 if ( wp_doing_ajax() ) {
297 check_ajax_referer( 'super_duper_picker', '_ajax_nonce' );
298 }
299
300 if ( isset( $_POST['editor_id'] ) ) {
301 $editor_id = sanitize_text_field( wp_unslash( $_POST['editor_id'] ) );
302 } elseif ( isset( $_REQUEST['et_fb'] ) ) {
303 $editor_id = 'main_content_content_vb_tiny_mce';
304 }
305
306 ksort( $sd_widgets );
307
308 ob_start();
309 ?>
310 <div class="sd-shortcode-left-wrap">
311 <?php
312 if ( ! empty( $sd_widgets ) ) {
313 echo '<select class="widefat" onchange="sd_get_shortcode_options(this);">';
314 echo "<option>" . __( 'Select shortcode', 'ayecode-connect' ) . "</option>";
315 foreach ( $sd_widgets as $shortcode => $class ) {
316 if ( ! empty( $class['output_types'] ) && ! in_array( 'shortcode', $class['output_types'] ) ) {
317 continue;
318 }
319 echo "<option value='" . esc_attr( $shortcode ) . "'>" . esc_html( $shortcode ) . " (" . esc_html( $class['name'] ) . ")</option>";
320 }
321 echo "</select>";
322 }
323 ?>
324 <div class="sd-shortcode-settings"></div>
325 </div>
326 <div class="sd-shortcode-right-wrap">
327 <textarea id='sd-shortcode-output' disabled></textarea>
328 <div id='sd-shortcode-output-actions'>
329 <?php if ( $editor_id != '' ) { ?>
330 <button class="button sd-insert-shortcode-button" onclick="sd_insert_shortcode(<?php if ( ! empty( $editor_id ) ) { echo "'" . esc_js( $editor_id ) . "'"; } ?>)"><?php esc_html_e( 'Insert Shortcode', 'ayecode-connect' ); ?></button>
331 <?php } ?>
332 <button class="button" onclick="sd_copy_to_clipboard()"><?php esc_html_e( 'Copy Shortcode', 'ayecode-connect' ); ?></button>
333 </div>
334 </div>
335 <?php
336 $html = ob_get_clean();
337
338 if ( wp_doing_ajax() ) {
339 echo $html;
340 $should_die = true;
341
342 // some builder get the editor via ajax so we should not die on those occasions
343 $dont_die = array(
344 'parent_tag',// WP Bakery
345 'avia_request' // enfold
346 );
347
348 foreach ( $dont_die as $request ) {
349 if ( isset( $_REQUEST[ $request ] ) ) {
350 $should_die = false;
351 }
352 }
353
354 if ( $should_die ) {
355 wp_die();
356 }
357 } else {
358 return $html;
359 }
360
361 return '';
362 }
363
364 /**
365 * Output the version in the header.
366 */
367 public function generator() {
368 $file = str_replace( array( "/", "\\" ), "/", realpath( __FILE__ ) );
369 $plugins_dir = str_replace( array( "/", "\\" ), "/", realpath( WP_PLUGIN_DIR ) );
370
371 // Find source plugin/theme of SD
372 $source = array();
373 if ( strpos( $file, $plugins_dir ) !== false ) {
374 $source = explode( "/", plugin_basename( $file ) );
375 } else if ( function_exists( 'get_theme_root' ) ) {
376 $themes_dir = str_replace( array( "/", "\\" ), "/", realpath( get_theme_root() ) );
377
378 if ( strpos( $file, $themes_dir ) !== false ) {
379 $source = explode( "/", ltrim( str_replace( $themes_dir, "", $file ), "/" ) );
380 }
381 }
382
383 echo '<meta name="generator" content="WP Super Duper v' . esc_attr( $this->version ) . '"' . ( ! empty( $source[0] ) ? ' data-sd-source="' . esc_attr( $source[0] ) . '"' : '' ) . ' />';
384 }
385
386 /**
387 * Get widget settings.
388 *
389 * @since 1.0.0
390 */
391 public static function get_widget_settings() {
392 global $sd_widgets;
393
394 $shortcode = isset( $_REQUEST['shortcode'] ) && $_REQUEST['shortcode'] ? sanitize_title_with_dashes( wp_unslash( $_REQUEST['shortcode'] ) ) : '';
395 if ( ! $shortcode ) {
396 wp_die();
397 }
398 $widget_args = isset( $sd_widgets[ $shortcode ] ) ? $sd_widgets[ $shortcode ] : '';
399 if ( ! $widget_args ) {
400 wp_die();
401 }
402 $class_name = isset( $widget_args['class_name'] ) && $widget_args['class_name'] ? $widget_args['class_name'] : '';
403 if ( ! $class_name ) {
404 wp_die();
405 }
406
407 // invoke an instance method
408 $widget = new $class_name;
409
410 ob_start();
411 $widget->form( array() );
412 $form = ob_get_clean();
413 echo "<form id='" . esc_attr( $shortcode ) . "'>" . $form . "<div class=\"widget-control-save\"></div></form>";
414 echo "<style>" . $widget->widget_css() . "</style>";
415 echo "<script>" . $widget->widget_js() . "</script>";
416 ?>
417 <?php
418 wp_die();
419 }
420
421 /**
422 * Insert shortcode builder button to classic editor (not inside Gutenberg, not needed).
423 *
424 * @param string $editor_id Optional. Shortcode editor id. Default null.
425 * @param string $insert_shortcode_function Optional. Insert shortcode function. Default null.
426 *
427 *@since 1.0.0
428 *
429 */
430 public static function shortcode_insert_button( $editor_id = '', $insert_shortcode_function = '' ) {
431 global $sd_widgets, $shortcode_insert_button_once;
432 if ( $shortcode_insert_button_once ) {
433 return;
434 }
435 add_thickbox();
436
437 /**
438 * Cornerstone makes us play dirty tricks :/
439 * All media_buttons are removed via JS unless they are two specific id's so we wrap our content in this ID so it is not removed.
440 */
441 if ( function_exists( 'cornerstone_plugin_init' ) && ! is_admin() ) {
442 echo '<span id="insert-media-button">';
443 }
444
445 echo self::shortcode_button( 'this', 'true' );
446
447 // see opening note
448 if ( function_exists( 'cornerstone_plugin_init' ) && ! is_admin() ) {
449 echo '</span>'; // end #insert-media-button
450 }
451
452 // Add separate script for generatepress theme sections
453 if ( function_exists( 'generate_sections_sections_metabox' ) && did_action( 'generate_sections_metabox' ) ) {
454 } else {
455 self::shortcode_insert_button_script( $editor_id, $insert_shortcode_function );
456 }
457
458 $shortcode_insert_button_once = true;
459 }
460
461 /**
462 * Gets the shortcode insert button html.
463 *
464 * @param string $id
465 * @param string $search_for_id
466 *
467 * @return mixed
468 */
469 public static function shortcode_button( $id = '', $search_for_id = '' ) {
470 ob_start();
471 ?>
472 <span class="sd-lable-shortcode-inserter">
473 <a onclick="sd_ajax_get_picker(<?php echo $id;
474 if ( $search_for_id ) {
475 echo "," . $search_for_id;
476 } ?>);" href="#TB_inline?width=100%&height=550&inlineId=super-duper-content-ajaxed"
477 class="thickbox button super-duper-content-open" title="Add Shortcode">
478 <span style="vertical-align: middle;line-height: 18px;font-size: 20px;"
479 class="dashicons dashicons-screenoptions"></span>
480 </a>
481 <div id="super-duper-content-ajaxed" style="display:none;">
482 <span>Loading</span>
483 </div>
484 </span>
485
486 <?php
487 $html = ob_get_clean();
488
489 // remove line breaks so we can use it in js
490 return preg_replace( "/\r|\n/", "", trim( $html ) );
491 }
492
493 /**
494 * Makes SD work with the siteOrigin page builder.
495 *
496 * @return mixed
497 *@since 1.0.6
498 */
499 public static function siteorigin_js() {
500 ob_start();
501 ?>
502 <script>
503 /**
504 * Check a form to see what items should be shown or hidden.
505 */
506 function sd_so_show_hide(form) {
507 jQuery(form).find(".sd-argument").each(function () {
508 var $element_require = jQuery(this).data('element_require');
509
510 if ($element_require) {
511 $element_require = $element_require.replace("&#039;", "'"); // replace single quotes
512 $element_require = $element_require.replace("&quot;", '"'); // replace double quotes
513
514 if (eval($element_require)) {
515 jQuery(this).removeClass('sd-require-hide');
516 } else {
517 jQuery(this).addClass('sd-require-hide');
518 }
519 }
520 });
521 }
522
523 /**
524 * Toggle advanced settings visibility.
525 */
526 function sd_so_toggle_advanced($this) {
527 var form = jQuery($this).parents('form,.form,.so-content');
528 form.find('.sd-advanced-setting').toggleClass('sd-adv-show');
529 return false;// prevent form submit
530 }
531
532 /**
533 * Initialise a individual widget.
534 */
535 function sd_so_init_widget($this, $selector) {
536 if (!$selector) {
537 $selector = 'form';
538 }
539 // only run once.
540 if (jQuery($this).data('sd-widget-enabled')) {
541 return;
542 } else {
543 jQuery($this).data('sd-widget-enabled', true);
544 }
545
546 var $button = '<button title="<?php _e( 'Advanced Settings', 'ayecode-connect' );?>" class="button button-primary right sd-advanced-button" onclick="sd_so_toggle_advanced(this);return false;"><i class="fas fa-sliders-h" aria-hidden="true"></i></button>';
547 var form = jQuery($this).parents('' + $selector + '');
548
549 if (jQuery($this).val() == '1' && jQuery(form).find('.sd-advanced-button').length == 0) {
550 jQuery(form).append($button);
551 }
552
553 // show hide on form change
554 jQuery(form).on("change", function () {
555 sd_so_show_hide(form);
556 });
557
558 // show hide on load
559 sd_so_show_hide(form);
560 }
561
562 jQuery(function () {
563 jQuery(document).on('open_dialog', function (w, e) {
564 setTimeout(function () {
565 if (jQuery('.so-panels-dialog-wrapper:visible .so-content.panel-dialog .sd-show-advanced').length) {
566 if (jQuery('.so-panels-dialog-wrapper:visible .so-content.panel-dialog .sd-show-advanced').val() == '1') {
567 sd_so_init_widget('.so-panels-dialog-wrapper:visible .so-content.panel-dialog .sd-show-advanced', 'div');
568 }
569 }
570 }, 200);
571 });
572 });
573 </script>
574 <?php
575 $output = ob_get_clean();
576
577 /*
578 * We only add the <script> tags for code highlighting, so we strip them from the output.
579 */
580
581 return str_replace( array(
582 '<script>',
583 '</script>'
584 ), '', $output );
585 }
586
587 /**
588 * Output the JS and CSS for the shortcode insert button.
589 *
590 * @param string $editor_id
591 * @param string $insert_shortcode_function
592 *
593 *@since 1.0.6
594 *
595 */
596 public static function shortcode_insert_button_script( $editor_id = '', $insert_shortcode_function = '' ) {
597 ?>
598 <style>
599 .sd-shortcode-left-wrap {
600 float: left;
601 width: calc(60% - .75rem);
602 padding-top: .75rem;
603 }
604
605 .sd-shortcode-left-wrap .gd-help-tip {
606 float: none;
607 }
608
609 .sd-shortcode-left-wrap .widefat {
610 border-spacing: 0;
611 width: 100%;
612 clear: both;
613 margin: 0;
614 border: 1px solid #ddd;
615 box-shadow: inset 0 1px 2px rgba(0, 0, 0, .07);
616 background-color: #fff;
617 color: #32373c;
618 outline: 0;
619 transition: 50ms border-color ease-in-out;
620 padding: 3px 5px;
621 }
622
623 .sd-shortcode-left-wrap input[type=checkbox].widefat {
624 border: 1px solid #b4b9be;
625 background: #fff;
626 color: #555;
627 clear: none;
628 cursor: pointer;
629 display: inline-block;
630 line-height: 0;
631 height: 16px;
632 margin: -4px 4px 0 0;
633 margin-top: 0;
634 outline: 0;
635 padding: 0 !important;
636 text-align: center;
637 vertical-align: middle;
638 width: 16px;
639 min-width: 16px;
640 -webkit-appearance: none;
641 box-shadow: inset 0 1px 2px rgba(0, 0, 0, .1);
642 transition: .05s border-color ease-in-out;
643 }
644
645 .sd-shortcode-left-wrap input[type=checkbox]:checked:before {
646 content: "\f147";
647 margin: -3px 0 0 -4px;
648 color: #1e8cbe;
649 float: left;
650 display: inline-block;
651 vertical-align: middle;
652 width: 16px;
653 font: normal 21px/1 dashicons;
654 speak: none;
655 -webkit-font-smoothing: antialiased;
656 -moz-osx-font-smoothing: grayscale;
657 }
658
659 #sd-shortcode-output-actions button,
660 .sd-advanced-button {
661 color: #555;
662 border-color: #ccc;
663 background: #f7f7f7;
664 box-shadow: 0 1px 0 #ccc;
665 vertical-align: top;
666 display: inline-block;
667 text-decoration: none;
668 font-size: 13px;
669 line-height: 26px;
670 height: 28px;
671 margin: 0;
672 padding: 0 10px 1px;
673 cursor: pointer;
674 border-width: 1px;
675 border-style: solid;
676 -webkit-appearance: none;
677 border-radius: 3px;
678 white-space: nowrap;
679 box-sizing: border-box;
680 }
681
682 button.sd-advanced-button {
683 background: #0073aa;
684 border-color: #006799;
685 box-shadow: inset 0 2px 0 #006799;
686 vertical-align: top;
687 color: #fff;
688 text-decoration: none;
689 text-shadow: 0 -1px 1px #006799, 1px 0 1px #006799, 0 1px 1px #006799, -1px 0 1px #006799;
690 float: right;
691 margin-right: 3px !important;
692 font-size: 20px !important;
693 }
694
695 .sd-shortcode-right-wrap {
696 float: right;
697 width: 40%;
698 padding-top: .75rem;
699 }
700
701 #sd-shortcode-output {
702 background: rgba(255, 255, 255, .5);
703 border-color: rgba(222, 222, 222, .75);
704 box-shadow: inset 0 1px 2px rgba(0, 0, 0, .04);
705 color: rgba(51, 51, 51, .5);
706 overflow: auto;
707 padding: 2px 6px;
708 line-height: 1.4;
709 resize: vertical;
710 height: 250px;
711 width: 100%;
712 margin-bottom: .75rem;
713 }
714
715 <?php if ( function_exists( 'generate_sections_sections_metabox' ) ) { ?>
716 .generate-sections-modal #custom-media-buttons > .sd-lable-shortcode-inserter {
717 display: inline;
718 }
719 <?php } ?>
720 <?php if ( function_exists( 'et_builder_is_tb_admin_screen' ) && et_builder_is_tb_admin_screen() ) { ?>
721 body.divi_page_et_theme_builder div#TB_window.gd-tb-window{z-index:9999999}
722 <?php } ?>
723 </style>
724 <?php
725 if ( class_exists( 'SiteOrigin_Panels' ) ) {
726 echo "<script>" . self::siteorigin_js() . "</script>";
727 }
728 ?>
729 <script>
730 <?php
731 if(! empty( $insert_shortcode_function )){
732 echo $insert_shortcode_function;
733 }else{
734
735 /**
736 * Function for super duper insert shortcode.
737 *
738 * @since 1.0.0
739 */
740 ?>
741 function sd_insert_shortcode($editor_id) {
742 $shortcode = jQuery('#TB_ajaxContent #sd-shortcode-output').val();
743 if ($shortcode) {
744 if (!$editor_id) {
745 <?php
746 if ( isset( $_REQUEST['et_fb'] ) ) {
747 echo '$editor_id = "#main_content_content_vb_tiny_mce";';
748 } elseif ( isset( $_REQUEST['action'] ) && $_REQUEST['action'] == 'elementor' ) {
749 echo '$editor_id = "#elementor-controls .wp-editor-container textarea";';
750 } else {
751 echo '$editor_id = "#wp-content-editor-container textarea";';
752 }
753 ?>
754 } else {
755 $editor_id = '#' + $editor_id;
756 }
757 tmceActive = jQuery($editor_id).attr("aria-hidden") == "true" ? true : false;
758 /* GeneratePress */
759 if (jQuery('#generate-sections-modal-dialog ' + $editor_id).length) {
760 $editor_id = '#generate-sections-modal-dialog ' + $editor_id;
761 tmceActive = jQuery($editor_id).closest('.wp-editor-wrap').hasClass('tmce-active') ? true : false;
762 }
763 if (typeof tinyMCE !== 'undefined' && tinyMCE.activeEditor && tmceActive) {
764 tinyMCE.execCommand('mceInsertContent', false, $shortcode);
765 } else {
766 var $txt = jQuery($editor_id);
767 var caretPos = $txt[0].selectionStart;
768 var textAreaTxt = $txt.val();
769 var txtToAdd = $shortcode;
770 var textareaValue = textAreaTxt.substring(0, caretPos) + txtToAdd + textAreaTxt.substring(caretPos);
771 $txt.focus().val(textareaValue).change().keydown().blur().keyup().keypress().trigger('input').trigger('change');
772
773 // set Divi react input value
774 var input = document.getElementById("main_content_content_vb_tiny_mce");
775 if (input) {
776 sd_setNativeValue(input, textareaValue);
777 }
778 }
779 tb_remove();
780 }
781 }
782
783 /*
784 Set the value of elements controlled via react.
785 */
786 function sd_setNativeValue(element, value) {
787 let lastValue = element.value;
788 element.value = value;
789 let event = new Event("input", {target: element, bubbles: true});
790 // React 15
791 event.simulated = true;
792 // React 16
793 let tracker = element._valueTracker;
794 if (tracker) {
795 tracker.setValue(lastValue);
796 }
797 element.dispatchEvent(event);
798 }
799 <?php } ?>
800
801 /*
802 Copies the shortcode to the clipboard.
803 */
804 function sd_copy_to_clipboard() {
805 /* Get the text field */
806 var copyText = document.querySelector("#TB_ajaxContent #sd-shortcode-output");
807 //un-disable the field
808 copyText.disabled = false;
809 /* Select the text field */
810 copyText.select();
811 /* Copy the text inside the text field */
812 document.execCommand("Copy");
813 //re-disable the field
814 copyText.disabled = true;
815 /* Alert the copied text */
816 alert("Copied the text: " + copyText.value);
817 }
818
819 /*
820 Gets the shortcode options.
821 */
822 function sd_get_shortcode_options($this) {
823 $short_code = jQuery($this).val();
824 if ($short_code) {
825 var data = {
826 'action': 'super_duper_get_widget_settings',
827 'shortcode': $short_code,
828 'attributes': 123,
829 'post_id': 321,
830 '_ajax_nonce': '<?php echo wp_create_nonce( 'super_duper_output_shortcode' );?>'
831 };
832
833 if (typeof ajaxurl === 'undefined') {
834 var ajaxurl = "<?php echo admin_url( 'admin-ajax.php' );?>";
835 }
836
837 jQuery.post(ajaxurl, data, function (response) {
838 jQuery('#TB_ajaxContent .sd-shortcode-settings').html(response);
839
840 jQuery('#' + $short_code).on('change', 'select', function () {
841 sd_build_shortcode($short_code);
842 }); // take care of select tags
843
844 jQuery('#' + $short_code).on('change keypress keyup', 'input,textarea', function () {
845 sd_build_shortcode($short_code);
846 });
847
848 sd_build_shortcode($short_code);
849
850 // resize the window to fit
851 setTimeout(function () {
852 jQuery('#TB_ajaxContent').css('width', 'auto').css('height', '75vh');
853 }, 200);
854
855 return response;
856 });
857 }
858 }
859
860 /*
861 Builds and inserts the shortcode into the viewer.
862 */
863 function sd_build_shortcode($id) {
864 var multiSelects = {};
865 var multiSelectsRemove = [];
866
867 $output = "[" + $id;
868
869 $form_data = jQuery("#" + $id).serializeArray();
870
871 // run checks for multiselects
872 jQuery.each($form_data, function (index, element) {
873 if (element && element.value) {
874 $field_name = element.name.substr(element.name.indexOf("][") + 2);
875 $field_name = $field_name.replace("]", "");
876 // check if its a multiple
877 if ($field_name.includes("[]")) {
878 multiSelectsRemove[multiSelectsRemove.length] = index;
879 $field_name = $field_name.replace("[]", "");
880 if ($field_name in multiSelects) {
881 multiSelects[$field_name] = multiSelects[$field_name] + "," + element.value;
882 } else {
883 multiSelects[$field_name] = element.value;
884 }
885 }
886 }
887 });
888
889 // fix multiselects if any are found
890 if (multiSelectsRemove.length) {
891
892 // remove all multiselects
893 multiSelectsRemove.reverse();
894 multiSelectsRemove.forEach(function (index) {
895 $form_data.splice(index, 1);
896 });
897
898 $ms_arr = [];
899 // add multiselets back
900 jQuery.each(multiSelects, function (index, value) {
901 $ms_arr[$ms_arr.length] = {"name": "[][" + index + "]", "value": value};
902 });
903 $form_data = $form_data.concat($ms_arr);
904 }
905
906 if ($form_data) {
907 $content = '';
908 $form_data.forEach(function (element) {
909 if (element.value) {
910 $field_name = element.name.substr(element.name.indexOf("][") + 2);
911 $field_name = $field_name.replace("]", "");
912 if ($field_name == 'html') {
913 $content = element.value;
914 } else {
915 $output = $output + " " + $field_name + '="' + element.value + '"';
916 }
917 }
918 });
919 }
920 $output = $output + "]";
921
922 // check for content field
923 if ($content) {
924 $output = $output + $content + "[/" + $id + "]";
925 }
926
927 jQuery('#TB_ajaxContent #sd-shortcode-output').html($output);
928 }
929
930 /*
931 Delay the init of the textareas for 1 second.
932 */
933 (function () {
934 setTimeout(function () {
935 sd_init_textareas();
936 }, 1000);
937 })();
938
939 /*
940 Init the textareas to be able to show the shortcode builder button.
941 */
942 function sd_init_textareas() {
943 // General textareas
944 jQuery(document).on('focus', 'textarea', function () {
945 if (jQuery(this).hasClass('wp-editor-area')) {
946 // insert the shortcode button to the textarea lable if not there already
947 if (!(jQuery(this).parent().find('.sd-lable-shortcode-inserter').length || (jQuery(this).closest('.wp-editor-wrap').length && jQuery(this).closest('.wp-editor-wrap').find('.sd-lable-shortcode-inserter').length))) {
948 jQuery(this).parent().find('.quicktags-toolbar').append(sd_shortcode_button(jQuery(this).attr('id')));
949 }
950 } else {
951 // insert the shortcode button to the textarea lable if not there already
952 if (!jQuery("label[for='" + jQuery(this).attr('id') + "']").find('.sd-lable-shortcode-inserter').length) {
953 jQuery("label[for='" + jQuery(this).attr('id') + "']").append(sd_shortcode_button(jQuery(this).attr('id')));
954 }
955 }
956 });
957
958 // The below tries to add the shortcode builder button to the builders own raw/shortcode sections.
959 <?php if ( function_exists( 'et_setup_theme' ) ) { ?>
960 // DIVI
961 jQuery(document).on('focusin', '.et-fb-codemirror', function () {
962 // insert the shortcode button to the textarea lable if not there already
963 if (!jQuery(this).closest('.et-fb-form__group').find('.sd-lable-shortcode-inserter').length) {
964 jQuery(this).closest('.et-fb-form__group').find('.et-fb-form__label-text').append(sd_shortcode_button());
965 }
966 });
967 /* Divi 5 */
968 jQuery(document).on('focusin', '.et-vb-tinymce-html-input', function () {
969 var $etEl = jQuery(this).closest('.et-vb-field-richtext').find('.et-vb-field-richtext-buttons');
970 if (!$etEl.find('.sd-lable-shortcode-inserter').length) {
971 if ($etEl.find('.et-vb-switch-editor-mode').length) {
972 $etEl.find('.et-vb-switch-editor-mode').before(sd_shortcode_button());
973 } else {
974 $etEl.append(sd_shortcode_button());
975 }
976 }
977 });
978 jQuery(document).on('focusin', '.et-vb-code', function() {
979 var $etEl = jQuery(this).closest('.et-vb-field').find('.et-vb-field-label .et-vb-field-label-buttons');
980 if (!$etEl.find('.sd-lable-shortcode-inserter').length) {
981 $etEl.prepend(sd_shortcode_button());
982 $etEl.find('.sd-lable-shortcode-inserter').addClass('et-vb-field-button');
983 }
984 });
985 <?php } ?>
986
987 // Beaver
988 jQuery(document).on('focusin', '.fl-code-field', function () {
989 // insert the shortcode button to the textarea lable if not there already
990 if (!jQuery(this).closest('.fl-field-control-wrapper').find('.sd-lable-shortcode-inserter').length) {
991 jQuery(this).closest('.fl-field-control-wrapper').prepend(sd_shortcode_button());
992 }
993 });
994
995 // Fusion builder (avada)
996 jQuery(document).on('focusin', '.CodeMirror.cm-s-default', function () {
997 // insert the shortcode button to the textarea lable if not there already
998 if (!jQuery(this).parent().find('.sd-lable-shortcode-inserter').length) {
999 jQuery(sd_shortcode_button()).insertBefore(this);
1000 }
1001 });
1002
1003 // Avia builder (enfold)
1004 jQuery(document).on('focusin', '#aviaTBcontent', function () {
1005 // insert the shortcode button to the textarea lable if not there already
1006 if (!jQuery(this).parent().parent().find('.avia-name-description ').find('.sd-lable-shortcode-inserter').length) {
1007 jQuery(this).parent().parent().find('.avia-name-description strong').append(sd_shortcode_button(jQuery(this).attr('id')));
1008 }
1009 });
1010
1011 // Cornerstone textareas
1012 jQuery(document).on('focusin', '.cs-control.cs-control-textarea', function () {
1013 // insert the shortcode button to the textarea lable if not there already
1014 if (!jQuery(this).find('.cs-control-header label').find('.sd-lable-shortcode-inserter').length) {
1015 jQuery(this).find('.cs-control-header label').append(sd_shortcode_button());
1016 }
1017 });
1018
1019 // Cornerstone main bar
1020 setTimeout(function () {
1021 // insert the shortcode button to the textarea lable if not there already
1022 if (!jQuery('.cs-bar-btns').find('.sd-lable-shortcode-inserter').length) {
1023 jQuery('<li style="text-align: center;padding: 5px;list-style: none;">' + sd_shortcode_button() + '</li>').insertBefore('.cs-action-toggle-custom-css');
1024 }
1025 }, 2000);
1026
1027 // WP Bakery, code editor does not render shortcodes.
1028 // jQuery(document).on('focusin', '.wpb-textarea_raw_html', function () {
1029 // // insert the shortcode button to the textarea lable if not there already
1030 // if(!jQuery(this).parent().parent().find('.wpb_element_label').find('.sd-lable-shortcode-inserter').length){
1031 // jQuery(this).parent().parent().find('.wpb_element_label').append(sd_shortcode_button());
1032 // }
1033 // });
1034 }
1035
1036 /**
1037 * Gets the html for the picker via ajax and updates it on the fly.
1038 *
1039 * @param $id
1040 * @param $search
1041 */
1042 function sd_ajax_get_picker($id, $search) {
1043 if ($search) {
1044 $this = $id;
1045 $id = jQuery($this).closest('.wp-editor-wrap').find('.wp-editor-container textarea').attr('id');
1046 }
1047
1048 var data = {
1049 'action': 'super_duper_get_picker',
1050 'editor_id': $id,
1051 '_ajax_nonce': '<?php echo wp_create_nonce( 'super_duper_picker' );?>'
1052 };
1053
1054 if (!ajaxurl) {
1055 var ajaxurl = "<?php echo admin_url( 'admin-ajax.php' ); ?>";
1056 }
1057
1058 jQuery.post(ajaxurl, data, function (response) {
1059 jQuery('#TB_ajaxContent').closest('#TB_window').addClass('gd-tb-window');
1060 jQuery('#TB_ajaxContent').html(response);
1061 //return response;
1062 }).then(function (env) {
1063 jQuery('body').on('thickbox:removed', function () {
1064 jQuery('#super-duper-content-ajaxed').html('');
1065 });
1066 });
1067 }
1068
1069 /**
1070 * Get the html for the shortcode inserter button depending on if a textarea id is available.
1071 *
1072 * @param $id string The textarea id.
1073 * @returns {string}
1074 */
1075 function sd_shortcode_button($id) {
1076 if ($id) {
1077 return '<?php echo self::shortcode_button( "\\''+\$id+'\\'" );?>';
1078 } else {
1079 return '<?php echo self::shortcode_button();?>';
1080 }
1081 }
1082 </script>
1083 <?php
1084 }
1085
1086 /**
1087 * Gets some CSS for the widgets screen.
1088 *
1089 * @param bool $advanced If we should include advanced CSS.
1090 *
1091 * @return mixed
1092 */
1093 public function widget_css( $advanced = true ) {
1094 ob_start();
1095 ?>
1096 <style>
1097 <?php if( $advanced ){ ?>
1098 .sd-advanced-setting {
1099 display: none;
1100 }
1101
1102 .sd-advanced-setting.sd-adv-show {
1103 display: block;
1104 }
1105
1106 .sd-argument.sd-require-hide,
1107 .sd-advanced-setting.sd-require-hide {
1108 display: none;
1109 }
1110
1111 button.sd-advanced-button {
1112 margin-right: 3px !important;
1113 font-size: 20px !important;
1114 }
1115
1116 <?php } ?>
1117
1118 button.sd-toggle-group-button {
1119 background-color: #f3f3f3;
1120 color: #23282d;
1121 cursor: pointer;
1122 padding: 10px;
1123 width: 100%;
1124 border: none;
1125 text-align: left;
1126 outline: none;
1127 font-size: 13px;
1128 font-weight: bold;
1129 margin-bottom: 1px;
1130 }
1131 .elementor-control .sd-argument select[multiple]{height:100px}
1132 .elementor-control .sd-argument select[multiple] option{padding:3px}
1133 </style>
1134 <?php
1135 $output = ob_get_clean();
1136
1137 /*
1138 * We only add the <script> tags for code highlighting, so we strip them from the output.
1139 */
1140
1141 return str_replace( array(
1142 '<style>',
1143 '</style>'
1144 ), '', $output );
1145 }
1146
1147 /**
1148 * Gets some JS for the widgets screen.
1149 *
1150 * @return mixed
1151 */
1152 public function widget_js() {
1153 ob_start();
1154 ?>
1155 <script>
1156
1157 /**
1158 * Toggle advanced settings visibility.
1159 */
1160 function sd_toggle_advanced($this) {
1161 var form = jQuery($this).parents('form,.form');
1162 form.find('.sd-advanced-setting').toggleClass('sd-adv-show');
1163 return false;// prevent form submit
1164 }
1165
1166 /**
1167 * Check a form to see what items should be shown or hidden.
1168 */
1169 function sd_show_hide(form) {
1170 jQuery(form).find(".sd-argument").each(function () {
1171
1172 var $element_require = jQuery(this).data('element_require');
1173
1174 if ($element_require) {
1175
1176 $element_require = $element_require.replace("&#039;", "'"); // replace single quotes
1177 $element_require = $element_require.replace("&quot;", '"'); // replace double quotes
1178
1179 if (eval($element_require)) {
1180 jQuery(this).removeClass('sd-require-hide');
1181 } else {
1182 jQuery(this).addClass('sd-require-hide');
1183 }
1184 }
1185 });
1186 }
1187
1188 /**
1189 * Initialise widgets from the widgets screen.
1190 */
1191 function sd_init_widgets($selector) {
1192 jQuery(".sd-show-advanced").each(function (index) {
1193 sd_init_widget(this, $selector);
1194 });
1195 }
1196
1197 /**
1198 * Initialise a individual widget.
1199 */
1200 function sd_init_widget($this, $selector, $form) {
1201 if (!$selector) {
1202 $selector = 'form';
1203 }
1204 // Only run once.
1205 if (jQuery($this).data('sd-widget-enabled')) {
1206 return;
1207 } else {
1208 jQuery($this).data('sd-widget-enabled', true);
1209 }
1210
1211 var $button = '<button title="<?php esc_attr_e( 'Advanced Settings', 'ayecode-connect' );?>" style="line-height:1.5rem;margin:.5rem 0 0 0!important;" class="button button-primary right sd-advanced-button" onclick="sd_toggle_advanced(this);return false;"><span class="dashicons dashicons-admin-settings" style="width:1.5rem;font-size:1.5rem;height:1.5rem;line-height:1.5rem;margin:0;padding:0"></span></button>';
1212 var form = $form ? $form : jQuery($this).parents('' + $selector + '');
1213
1214 if (jQuery($this).val() == '1' && jQuery(form).find('.sd-advanced-button').length == 0) {
1215 console.log('add advanced button');
1216 if (jQuery(form).find('.widget-control-save').length > 0) {
1217 jQuery(form).find('.widget-control-save').after($button);
1218 } else {
1219 jQuery(form).find('.sd-show-advanced').after($button);
1220 }
1221 } else {
1222 console.log('no advanced button, ' + jQuery($this).val() + ', ' + jQuery(form).find('.sd-advanced-button').length);
1223 }
1224
1225 /* Show hide on form change */
1226 jQuery(form).on("change", function() {
1227 sd_show_hide(form);
1228 });
1229
1230 /* Show hide on load */
1231 sd_show_hide(form);
1232 }
1233
1234 /**
1235 * Init a customizer widget.
1236 */
1237 function sd_init_customizer_widget(section) {
1238 if (section.expanded) {
1239 section.expanded.bind(function (isExpanding) {
1240 if (isExpanding) {
1241 // is it a SD widget?
1242 if (jQuery(section.container).find('.sd-show-advanced').length) {
1243 // init the widget
1244 sd_init_widget(jQuery(section.container).find('.sd-show-advanced'), ".form");
1245 }
1246 }
1247 });
1248 }
1249 }
1250
1251 /**
1252 * If on widgets screen.
1253 */
1254 jQuery(function () {
1255 // if not in customizer.
1256 if (!wp.customize) {
1257 sd_init_widgets("form");
1258 }
1259
1260 /* Init on widget added */
1261 jQuery(document).on('widget-added', function (e, widget) {
1262 /* Is it a SD widget? */
1263 if (jQuery(widget).find('.sd-show-advanced').length) {
1264 var widgetId = jQuery(widget).find('[name="widget-id"]').length ? ': ' + jQuery(widget).find('[name="widget-id"]').val() : '';
1265 console.log('widget added' + widgetId);
1266 /* Init the widget */
1267 sd_init_widget(jQuery(widget).find('.sd-show-advanced'), "form", jQuery(widget).find('.sd-show-advanced').closest('form'));
1268 }
1269 });
1270
1271 /* Init on widget updated */
1272 jQuery(document).on('widget-updated', function (e, widget) {
1273 /* Is it a SD widget? */
1274 if (jQuery(widget).find('.sd-show-advanced').length) {
1275 var widgetId = jQuery(widget).find('[name="widget-id"]').length ? ': ' + jQuery(widget).find('[name="widget-id"]').val() : '';
1276 console.log('widget updated' + widgetId);
1277 /* Init the widget */
1278 sd_init_widget(jQuery(widget).find('.sd-show-advanced'), "form", jQuery(widget).find('.sd-show-advanced').closest('form'));
1279 }
1280 });
1281 });
1282
1283 /**
1284 * We need to run this before jQuery is ready
1285 */
1286 if (wp.customize) {
1287 wp.customize.bind('ready', function () {
1288
1289 // init widgets on load
1290 wp.customize.control.each(function (section) {
1291 sd_init_customizer_widget(section);
1292 });
1293
1294 // init widgets on add
1295 wp.customize.control.bind('add', function (section) {
1296 sd_init_customizer_widget(section);
1297 });
1298
1299 });
1300
1301 }
1302 <?php do_action( 'wp_super_duper_widget_js', $this ); ?>
1303 </script>
1304 <?php
1305 $output = ob_get_clean();
1306
1307 /*
1308 * We only add the <script> tags for code highlighting, so we strip them from the output.
1309 */
1310
1311 return str_replace( array(
1312 '<script>',
1313 '</script>'
1314 ), '', $output );
1315 }
1316
1317
1318 /**
1319 * Set the name from the argument key.
1320 *
1321 * @param $options
1322 *
1323 * @return mixed
1324 */
1325 private function add_name_from_key( $options, $arguments = false ) {
1326 if ( ! empty( $options['arguments'] ) ) {
1327 foreach ( $options['arguments'] as $key => $val ) {
1328 $options['arguments'][ $key ]['name'] = $key;
1329 }
1330 } elseif ( $arguments && is_array( $options ) && ! empty( $options ) ) {
1331 foreach ( $options as $key => $val ) {
1332 $options[ $key ]['name'] = $key;
1333 }
1334 }
1335
1336 return $options;
1337 }
1338
1339 /**
1340 * Register the parent shortcode.
1341 *
1342 * @since 1.0.0
1343 */
1344 public function register_shortcode() {
1345 add_shortcode( $this->base_id, array( $this, 'shortcode_output' ) );
1346 add_action( 'wp_ajax_super_duper_output_shortcode', array( $this, 'render_shortcode' ) );
1347 }
1348
1349 /**
1350 * Render the shortcode via ajax so we can return it to Gutenberg.
1351 *
1352 * @since 1.0.0
1353 */
1354 public function render_shortcode() {
1355 check_ajax_referer( 'super_duper_output_shortcode', '_ajax_nonce', true );
1356 if ( ! current_user_can( 'manage_options' ) ) {
1357 wp_die();
1358 }
1359
1360 // we might need the $post value here so lets set it.
1361 if ( isset( $_POST['post_id'] ) && $_POST['post_id'] ) {
1362 $post_obj = get_post( absint( $_POST['post_id'] ) );
1363 if ( ! empty( $post_obj ) && empty( $post ) ) {
1364 global $post;
1365 $post = $post_obj;
1366 }
1367 }
1368
1369 if ( isset( $_POST['shortcode'] ) && $_POST['shortcode'] ) {
1370 $is_preview = $this->is_preview();
1371 $shortcode_name = sanitize_title_with_dashes( $_POST['shortcode'] );
1372 $attributes_array = isset( $_POST['attributes'] ) && $_POST['attributes'] ? $_POST['attributes'] : array();
1373 $attributes = '';
1374 if ( ! empty( $attributes_array ) ) {
1375 foreach ( $attributes_array as $key => $value ) {
1376 if ( is_array( $value ) ) {
1377 $value = implode( ",", $value );
1378 }
1379
1380 if ( ! empty( $value ) ) {
1381 $value = wp_unslash( $value );
1382
1383 // Encode [ and ].
1384 if ( $is_preview ) {
1385 $value = $this->encode_shortcodes( $value );
1386 }
1387 }
1388 $attributes .= " " . esc_attr( sanitize_title_with_dashes( $key ) ) . "='" . esc_attr( $value ) . "' ";
1389 }
1390 }
1391
1392 $shortcode = "[" . esc_attr( $shortcode_name ) . " " . $attributes . "]";
1393
1394 $content = do_shortcode( $shortcode );
1395
1396 // Decode [ and ].
1397 if ( ! empty( $content ) && $is_preview ) {
1398 $content = $this->decode_shortcodes( $content );
1399 }
1400
1401 echo $content;
1402 }
1403 wp_die();
1404 }
1405
1406 /**
1407 * Output the shortcode.
1408 *
1409 * @param array $args
1410 * @param string $content
1411 *
1412 * @return string
1413 */
1414 public function shortcode_output( $args = array(), $content = '' ) {
1415 $_instance = $args;
1416
1417 $args = $this->argument_values( $args );
1418
1419 // add extra argument so we know its a output to gutenberg
1420 //$args
1421 $args = $this->string_to_bool( $args );
1422
1423 // if we have a enclosed shortcode we add it to the special `html` argument
1424 if ( ! empty( $content ) ) {
1425 $args['html'] = $content;
1426 }
1427
1428 if ( ! $this->is_preview() ) {
1429 /**
1430 * Filters the settings for a particular widget args.
1431 *
1432 * @param array $args The current widget instance's settings.
1433 * @param WP_Super_Duper $widget The current widget settings.
1434 * @param array $_instance An array of default widget arguments.
1435 *
1436 *@since 1.0.28
1437 *
1438 */
1439 $args = apply_filters( 'wp_super_duper_widget_display_callback', $args, $this, $_instance );
1440
1441 if ( ! is_array( $args ) ) {
1442 return $args;
1443 }
1444 }
1445
1446 $class = isset( $this->options['widget_ops']['classname'] ) ? esc_attr( $this->options['widget_ops']['classname'] ) : '';
1447 $class .= " sdel-".$this->get_instance_hash();
1448
1449 $class = apply_filters( 'wp_super_duper_div_classname', $class, $args, $this );
1450 $class = apply_filters( 'wp_super_duper_div_classname_' . $this->base_id, $class, $args, $this );
1451
1452 $attrs = apply_filters( 'wp_super_duper_div_attrs', '', $args, $this );
1453 $attrs = apply_filters( 'wp_super_duper_div_attrs_' . $this->base_id, '', $args, $this );
1454
1455 $shortcode_args = array();
1456 $output = '';
1457 $no_wrap = isset( $this->options['no_wrap'] ) && $this->options['no_wrap'] ? true : false;
1458 if ( isset( $args['no_wrap'] ) && $args['no_wrap'] ) {
1459 $no_wrap = true;
1460 }
1461 $main_content = $this->output( $args, $shortcode_args, $content );
1462 if ( $main_content && ! $no_wrap ) {
1463 // wrap the shortcode in a div with the same class as the widget
1464 $output .= '<div class="' . $class . '" ' . $attrs . '>';
1465 if ( ! empty( $args['title'] ) ) {
1466 // if its a shortcode and there is a title try to grab the title wrappers
1467 $shortcode_args = array( 'before_title' => '', 'after_title' => '' );
1468 if ( empty( $instance ) ) {
1469 global $wp_registered_sidebars;
1470 if ( ! empty( $wp_registered_sidebars ) ) {
1471 foreach ( $wp_registered_sidebars as $sidebar ) {
1472 if ( ! empty( $sidebar['before_title'] ) ) {
1473 $shortcode_args['before_title'] = $sidebar['before_title'];
1474 $shortcode_args['after_title'] = $sidebar['after_title'];
1475 break;
1476 }
1477 }
1478 }
1479 }
1480 $output .= $this->output_title( $shortcode_args, $args );
1481 }
1482 $output .= $main_content;
1483 $output .= '</div>';
1484 } elseif ( $main_content && $no_wrap ) {
1485 $output .= $main_content;
1486 }
1487
1488 // if preview show a placeholder if empty
1489 if ( $this->is_preview() && $output == '' ) {
1490 $output = $this->preview_placeholder_text( "{{" . $this->base_id . "}}" );
1491 }
1492
1493 return apply_filters( 'wp_super_duper_widget_output', $output, $args, $shortcode_args, $this );
1494 }
1495
1496 /**
1497 * Placeholder text to show if output is empty and we are on a preview/builder page.
1498 *
1499 * @param string $name
1500 *
1501 * @return string
1502 */
1503 public function preview_placeholder_text( $name = '' ) {
1504 return "<div style='background:#0185ba33;padding: 10px;border: 4px #ccc dashed;'>" . wp_sprintf( __( 'Placeholder for: %s', 'ayecode-connect' ), $name ) . "</div>";
1505 }
1506
1507 /**
1508 * Sometimes booleans values can be turned to strings, so we fix that.
1509 *
1510 * @param $options
1511 *
1512 * @return mixed
1513 */
1514 public function string_to_bool( $options ) {
1515 // convert bool strings to booleans
1516 foreach ( $options as $key => $val ) {
1517 if ( $val == 'false' ) {
1518 $options[ $key ] = false;
1519 } elseif ( $val == 'true' ) {
1520 $options[ $key ] = true;
1521 }
1522 }
1523
1524 return $options;
1525 }
1526
1527 /**
1528 * Get the argument values that are also filterable.
1529 *
1530 * @param $instance
1531 *
1532 * @return array
1533 *@since 1.0.12 Don't set checkbox default value if the value is empty.
1534 *
1535 */
1536 public function argument_values( $instance ) {
1537 $argument_values = array();
1538
1539 // set widget instance
1540 $this->instance = $instance;
1541
1542 if ( empty( $this->arguments ) ) {
1543 $this->arguments = $this->get_arguments();
1544 }
1545
1546 if ( ! empty( $this->arguments ) ) {
1547 foreach ( $this->arguments as $key => $args ) {
1548 // set the input name from the key
1549 $args['name'] = $key;
1550 //
1551 $argument_values[ $key ] = isset( $instance[ $key ] ) ? $instance[ $key ] : '';
1552 if ( $args['type'] == 'checkbox' && $argument_values[ $key ] == '' ) {
1553 // don't set default for an empty checkbox
1554 } elseif ( $argument_values[ $key ] == '' && isset( $args['default'] ) ) {
1555 $argument_values[ $key ] = $args['default'];
1556 }
1557 }
1558 }
1559
1560 return $argument_values;
1561 }
1562
1563 /**
1564 * Set arguments in super duper.
1565 *
1566 * @return array Set arguments.
1567 *@since 1.0.0
1568 *
1569 */
1570 public function set_arguments() {
1571 return $this->arguments;
1572 }
1573
1574 /**
1575 * Get arguments in super duper.
1576 *
1577 * @return array Get arguments.
1578 *@since 1.0.0
1579 *
1580 */
1581 public function get_arguments() {
1582 if ( empty( $this->arguments ) ) {
1583 $this->arguments = $this->set_arguments();
1584 }
1585
1586 $this->arguments = apply_filters( 'wp_super_duper_arguments', $this->arguments, $this->options, $this->instance );
1587 $this->arguments = $this->add_name_from_key( $this->arguments, true );
1588
1589 if( !empty( $this->arguments['title']['value'] ) ){
1590 $this->arguments['title']['value'] = wp_kses_post( $this->arguments['title']['value'] );
1591 }
1592
1593 return $this->arguments;
1594 }
1595
1596 /**
1597 * This is the main output class for all 3 items, widget, shortcode and block, it is extended in the calling class.
1598 *
1599 * @param array $args
1600 * @param array $widget_args
1601 * @param string $content
1602 */
1603 public function output( $args = array(), $widget_args = array(), $content = '' ) {
1604
1605 }
1606
1607 /**
1608 * Add the dynamic block code inline when the wp-block in enqueued.
1609 */
1610 public function register_block() {
1611 wp_add_inline_script( 'wp-blocks', $this->block() );
1612 if ( class_exists( 'SiteOrigin_Panels' ) ) {
1613 wp_add_inline_script( 'wp-blocks', $this->siteorigin_js() );
1614 }
1615 }
1616
1617 /**
1618 * Check if we need to show advanced options.
1619 *
1620 * @return bool
1621 */
1622 public function block_show_advanced() {
1623
1624 $show = false;
1625 $arguments = $this->get_arguments();
1626
1627 if ( ! empty( $arguments ) ) {
1628 foreach ( $arguments as $argument ) {
1629 if ( isset( $argument['advanced'] ) && $argument['advanced'] ) {
1630 $show = true;
1631 break; // no need to continue if we know we have it
1632 }
1633 }
1634 }
1635
1636 return $show;
1637 }
1638
1639 /**
1640 * Get the url path to the current folder.
1641 *
1642 * @return string
1643 */
1644 public function get_url() {
1645 $url = $this->url;
1646
1647 if ( ! $url ) {
1648 $content_dir = wp_normalize_path( untrailingslashit( WP_CONTENT_DIR ) );
1649 $content_url = untrailingslashit( WP_CONTENT_URL );
1650
1651 // Replace http:// to https://.
1652 if ( strpos( $content_url, 'http://' ) === 0 && strpos( plugins_url(), 'https://' ) === 0 ) {
1653 $content_url = str_replace( 'http://', 'https://', $content_url );
1654 }
1655
1656 // Check if we are inside a plugin
1657 $file_dir = str_replace( "/includes", "", wp_normalize_path( dirname( __FILE__ ) ) );
1658 $url = str_replace( $content_dir, $content_url, $file_dir );
1659 $url = trailingslashit( $url );
1660 $this->url = $url;
1661 }
1662
1663 return $url;
1664 }
1665
1666 /**
1667 * Get the url path to the current folder.
1668 *
1669 * @return string
1670 */
1671 public function get_url_old() {
1672
1673 $url = $this->url;
1674
1675 if ( ! $url ) {
1676 // check if we are inside a plugin
1677 $file_dir = str_replace( "/includes", "", dirname( __FILE__ ) );
1678
1679 $dir_parts = explode( "/wp-content/", $file_dir );
1680 $url_parts = explode( "/wp-content/", plugins_url() );
1681
1682 if ( ! empty( $url_parts[0] ) && ! empty( $dir_parts[1] ) ) {
1683 $url = trailingslashit( $url_parts[0] . "/wp-content/" . $dir_parts[1] );
1684 $this->url = $url;
1685 }
1686 }
1687
1688
1689 return $url;
1690 }
1691
1692 /**
1693 * Generate the block icon.
1694 *
1695 * Enables the use of Font Awesome icons.
1696 *
1697 * @note xlink:href is actually deprecated but href is not supported by all so we use both.
1698 *
1699 * @param $icon
1700 *
1701 * @return string
1702 *@since 1.1.0
1703 */
1704 public function get_block_icon( $icon ) {
1705
1706 // check if we have a Font Awesome icon
1707 $fa_type = '';
1708 if ( substr( $icon, 0, 7 ) === "fas fa-" ) {
1709 $fa_type = 'solid';
1710 } elseif ( substr( $icon, 0, 7 ) === "far fa-" ) {
1711 $fa_type = 'regular';
1712 } elseif ( substr( $icon, 0, 7 ) === "fab fa-" ) {
1713 $fa_type = 'brands';
1714 } else {
1715 $icon = "'" . $icon . "'";
1716 }
1717
1718 // set the icon if we found one
1719 if ( $fa_type ) {
1720 $fa_icon = str_replace( array( "fas fa-", "far fa-", "fab fa-" ), "", $icon );
1721 $icon = "el('svg',{width: 20, height: 20, viewBox: '0 0 20 20'},el('use', {'xlink:href': '" . $this->get_url() . "icons/" . $fa_type . ".svg#" . $fa_icon . "','href': '" . $this->get_url() . "icons/" . $fa_type . ".svg#" . $fa_icon . "'}))";
1722 }
1723
1724 return $icon;
1725 }
1726
1727 public function group_arguments( $arguments ) {
1728 if ( ! empty( $arguments ) ) {
1729 $temp_arguments = array();
1730 $general = __( "General", 'ayecode-connect' );
1731 $add_sections = false;
1732 foreach ( $arguments as $key => $args ) {
1733 if ( isset( $args['group'] ) ) {
1734 $temp_arguments[ $args['group'] ][ $key ] = $args;
1735 $add_sections = true;
1736 } else {
1737 $temp_arguments[ $general ][ $key ] = $args;
1738 }
1739 }
1740
1741 // only add sections if more than one
1742 if ( $add_sections ) {
1743 $arguments = $temp_arguments;
1744 }
1745 }
1746
1747 return $arguments;
1748 }
1749
1750 /**
1751 * Parse used group tabs.
1752 *
1753 * @since 1.1.17
1754 */
1755 public function group_block_tabs( $tabs, $arguments ) {
1756 if ( ! empty( $tabs ) && ! empty( $arguments ) ) {
1757 $has_sections = false;
1758
1759 foreach ( $this->arguments as $key => $args ) {
1760 if ( isset( $args['group'] ) ) {
1761 $has_sections = true;
1762 break;
1763 }
1764 }
1765
1766 if ( ! $has_sections ) {
1767 return $tabs;
1768 }
1769
1770 $new_tabs = array();
1771
1772 foreach ( $tabs as $tab_key => $tab ) {
1773 $new_groups = array();
1774
1775 if ( ! empty( $tab['groups'] ) && is_array( $tab['groups'] ) ) {
1776 foreach ( $tab['groups'] as $group ) {
1777 if ( isset( $arguments[ $group ] ) ) {
1778 $new_groups[] = $group;
1779 }
1780 }
1781 }
1782
1783 if ( ! empty( $new_groups ) ) {
1784 $tab['groups'] = $new_groups;
1785
1786 $new_tabs[ $tab_key ] = $tab;
1787 }
1788 }
1789
1790 $tabs = $new_tabs;
1791 }
1792
1793 return $tabs;
1794 }
1795
1796 /**
1797 * Output the JS for building the dynamic Guntenberg block.
1798 *
1799 * @return mixed
1800 *@since 1.0.9 Save numbers as numbers and not strings.
1801 * @since 1.1.0 Font Awesome classes can be used for icons.
1802 * @since 1.0.4 Added block_wrap property which will set the block wrapping output element ie: div, span, p or empty for no wrap.
1803 */
1804 public function block() {
1805 global $wp_version, $sd_is_js_functions_loaded, $aui_bs5;
1806
1807 $show_advanced = $this->block_show_advanced();
1808 $block_api_version = version_compare( $wp_version, '6.9', '>=' ) ? 3 : 2; // Block apiVersion
1809
1810 if ( isset( $this->options['block-api-version'] ) && absint( $this->options['block-api-version'] ) > 0 ) {
1811 $block_api_version = absint( $this->options['block-api-version'] );
1812 }
1813
1814 ob_start();
1815 ?>
1816 <script>
1817 <?php
1818 if ( ! $sd_is_js_functions_loaded ) {
1819 $sd_is_js_functions_loaded = true;
1820 ?>
1821 function sd_show_view_options($this){
1822 if(jQuery($this).html().length){
1823 jQuery($this).html('');
1824 }else{
1825 jQuery($this).html('<div class="position-absolute d-flex flex-column bg-white p-1 rounded border shadow-lg " style="top:-80px;left:-5px;"><div class="dashicons dashicons-desktop mb-1" onclick="sd_set_view_type(\'Desktop\');"></div><div class="dashicons dashicons-tablet mb-1" onclick="sd_set_view_type(\'Tablet\');"></div><div class="dashicons dashicons-smartphone" onclick="sd_set_view_type(\'Mobile\');"></div></div>');
1826 }
1827 }
1828
1829 function sd_set_view_type($device){
1830 const wpVersion = '<?php global $wp_version; echo esc_attr($wp_version); ?>';
1831 if (parseFloat(wpVersion) < 6.5) {
1832 wp.data.dispatch('core/edit-site') ? wp.data.dispatch('core/edit-site').__experimentalSetPreviewDeviceType($device) : wp.data.dispatch('core/edit-post').__experimentalSetPreviewDeviceType($device);
1833 } else {
1834 const editorDispatch = wp.data.dispatch('core/editor');
1835 if (editorDispatch) {
1836 editorDispatch.setDeviceType($device);
1837 }
1838 }
1839 }
1840
1841 jQuery(function(){
1842 sd_block_visibility_init();
1843 });
1844 function sd_block_visibility_init() {
1845 jQuery(document).off('change', '.bs-vc-modal-form').on('change', '.bs-vc-modal-form', function() {
1846 try {
1847 aui_conditional_fields('.bs-vc-modal-form');
1848 } catch(err) {
1849 console.log(err.message);
1850 }
1851 });
1852
1853 jQuery(document).off('click', '.bs-vc-save').on('click', '.bs-vc-save', function() {
1854 var $bsvcModal = jQuery(this).closest('.bs-vc-modal'), $bsvcForm = $bsvcModal.find('.bs-vc-modal-form'), vOutput = jQuery('#bsvc_output', $bsvcForm).val(), vOutputN = jQuery('#bsvc_output_n', $bsvcForm).val(), rawValue = '', oVal = {}, oOut = {}, oOutN = {}, iRule = 0;
1855 jQuery(this).addClass('disabled');
1856 jQuery('.bs-vc-modal-form .bs-vc-rule-sets .bs-vc-rule').each(function(){
1857 vRule = jQuery(this).find('.bsvc_rule').val(), oRule = {};
1858 if (vRule == 'logged_in' || vRule == 'logged_out' || vRule == 'post_author') {
1859 oRule.type = vRule;
1860 } else if (vRule == 'user_roles') {
1861 oRule.type = vRule;
1862 if (jQuery(this).find('.bsvc_user_roles:checked').length) {
1863 var user_roles = jQuery(this).find('.bsvc_user_roles:checked').map(function() {
1864 return jQuery(this).val();
1865 }).get();
1866 if (user_roles && user_roles.length) {
1867 oRule.user_roles = user_roles.join(",");
1868 }
1869 }
1870 } else if (vRule == 'gd_field') {
1871 if (jQuery(this).find('.bsvc_gd_field ').val() && jQuery(this).find('.bsvc_gd_field_condition').val()) {
1872 oRule.type = vRule;
1873 oRule.field = jQuery(this).find('.bsvc_gd_field ').val();
1874 oRule.condition = jQuery(this).find('.bsvc_gd_field_condition').val();
1875 if (oRule.condition != 'is_empty' && oRule.condition != 'is_not_empty') {
1876 oRule.search = jQuery(this).find('.bsvc_gd_field_search').val();
1877 }
1878 }
1879 } else {
1880 oRule = jQuery(document).triggerHandler('sd_block_visibility_init', [vRule, oRule, jQuery(this)]);
1881 }
1882
1883 if (Object.keys(oRule).length > 0) {
1884 iRule++;
1885 oVal['rule'+iRule] = oRule;
1886 }
1887 });
1888 if (vOutput == 'hide') {
1889 oOut.type = vOutput;
1890 } else if (vOutput == 'message') {
1891 if (jQuery('#bsvc_message', $bsvcForm).val()) {
1892 oOut.type = vOutput;
1893 oOut.message = jQuery('#bsvc_message', $bsvcForm).val();
1894 if (jQuery('#bsvc_message_type', $bsvcForm).val()) {
1895 oOut.message_type = jQuery('#bsvc_message_type', $bsvcForm).val();
1896 }
1897 }
1898 } else if (vOutput == 'page') {
1899 if (jQuery('#bsvc_page', $bsvcForm).val()) {
1900 oOut.type = vOutput;
1901 oOut.page = jQuery('#bsvc_page', $bsvcForm).val();
1902 }
1903 } else if (vOutput == 'template_part') {
1904 if (jQuery('#bsvc_tmpl_part', $bsvcForm).val()) {
1905 oOut.type = vOutput;
1906 oOut.template_part = jQuery('#bsvc_tmpl_part', $bsvcForm).val();
1907 }
1908 }
1909 if (Object.keys(oOut).length > 0) {
1910 oVal.output = oOut;
1911 }
1912 if (vOutputN == 'hide') {
1913 oOutN.type = vOutputN;
1914 } else if (vOutputN == 'message') {
1915 if (jQuery('#bsvc_message_n', $bsvcForm).val()) {
1916 oOutN.type = vOutputN;
1917 oOutN.message = jQuery('#bsvc_message_n', $bsvcForm).val();
1918 if (jQuery('#bsvc_message_type_n', $bsvcForm).val()) {
1919 oOutN.message_type = jQuery('#bsvc_message_type_n', $bsvcForm).val();
1920 }
1921 }
1922 } else if (vOutputN == 'page') {
1923 if (jQuery('#bsvc_page_n', $bsvcForm).val()) {
1924 oOutN.type = vOutputN;
1925 oOutN.page = jQuery('#bsvc_page_n', $bsvcForm).val();
1926 }
1927 } else if (vOutputN == 'template_part') {
1928 if (jQuery('#bsvc_tmpl_part_n', $bsvcForm).val()) {
1929 oOutN.type = vOutputN;
1930 oOutN.template_part = jQuery('#bsvc_tmpl_part_n', $bsvcForm).val();
1931 }
1932 }
1933 if (Object.keys(oOutN).length > 0) {
1934 oVal.outputN = oOutN;
1935 }
1936 if (Object.keys(oVal).length > 0) {
1937 rawValue = JSON.stringify(oVal);
1938 }
1939 $bsvcModal.find('[name="bsvc_raw_value"]').val(rawValue).trigger('change');
1940 $bsvcModal.find('.bs-vc-close').trigger('click');
1941 });
1942 jQuery(document).off('click', '.bs-vc-add-rule').on('click', '.bs-vc-add-rule', function() {
1943 var bsvcTmpl = jQuery('.bs-vc-rule-template').html();
1944 var c = parseInt(jQuery('.bs-vc-modal-form .bs-vc-rule-sets .bs-vc-rule:last').data('bs-index'));
1945 if (c > 0) {
1946 c++;
1947 } else {
1948 c = 1;
1949 }
1950 bsvcTmpl = bsvcTmpl.replace(/BSVCINDEX/g, c);
1951 jQuery('.bs-vc-modal-form .bs-vc-rule-sets').append(bsvcTmpl);
1952 jQuery('.bs-vc-modal-form .bs-vc-rule-sets .bs-vc-rule .bs-vc-sep-wrap').removeClass('d-none');
1953 jQuery('.bs-vc-modal-form .bs-vc-rule-sets .bs-vc-rule:first .bs-vc-sep-wrap').addClass('d-none');
1954 jQuery('.bs-vc-modal-form .bs-vc-rule-sets .bs-vc-rule:last').find('select').each(function(){
1955 if (!jQuery(this).hasClass('no-select2')) {
1956 jQuery(this).addClass('aui-select2');
1957 }
1958 });
1959 if (!jQuery(this).hasClass('bs-vc-rendering')) {
1960 if(typeof aui_init_select2 == 'function') {
1961 aui_init_select2();
1962 }
1963 if(typeof aui_conditional_fields == 'function') {
1964 aui_conditional_fields('.bs-vc-modal-form');
1965 }
1966 }
1967 });
1968 jQuery(document).off('click', '.bs-vc-remove-rule').on('click', '.bs-vc-remove-rule', function() {
1969 jQuery(this).closest('.bs-vc-rule').remove();
1970 });
1971 }
1972 function sd_block_visibility_render_fields(oValue) {
1973 if (typeof oValue == 'object' && oValue.rule1 && typeof oValue.rule1 == 'object') {
1974 for(k = 1; k <= Object.keys(oValue).length; k++) {
1975 if (oValue['rule' + k] && oValue['rule' + k].type) {
1976 var oRule = oValue['rule' + k];
1977 jQuery('.bs-vc-modal-form .bs-vc-add-rule').addClass('bs-vc-rendering').trigger('click');
1978 var elRule = jQuery('.bs-vc-modal-form .bs-vc-rule-sets .bs-vc-rule:last');
1979 jQuery('select.bsvc_rule', elRule).val(oRule.type);
1980 if (oRule.type == 'user_roles' && oRule.user_roles) {
1981 var user_roles = oRule.user_roles;
1982 if (typeof user_roles == 'string') {
1983 user_roles = user_roles.split(",");
1984 }
1985 if (user_roles.length) {
1986 jQuery.each(user_roles, function(i, role){
1987 elRule.find("input[value='" + role + "']").prop('checked', true);
1988 });
1989 }
1990 jQuery('select.bsvc_user_roles', elRule).val(oRule.user_roles);
1991 } else if (oRule.type == 'gd_field') {
1992 if (oRule.field) {
1993 jQuery('select.bsvc_gd_field', elRule).val(oRule.field);
1994 if (oRule.condition) {
1995 jQuery('select.bsvc_gd_field_condition', elRule).val(oRule.condition);
1996 if (typeof oRule.search != 'undefined' && oRule.condition != 'is_empty' && oRule.condition != 'is_not_empty') {
1997 jQuery('input.bsvc_gd_field_search', elRule).val(oRule.search);
1998 }
1999 }
2000 }
2001 } else {
2002 jQuery(document).trigger('sd_block_visibility_render_fields', [oRule, elRule]);
2003 }
2004
2005 jQuery('.bs-vc-modal-form .bs-vc-add-rule').removeClass('bs-vc-rendering');
2006 }
2007 }
2008
2009 if (oValue.output && oValue.output.type) {
2010 jQuery('.bs-vc-modal-form #bsvc_output').val(oValue.output.type);
2011 if (oValue.output.type == 'message' && typeof oValue.output.message != 'undefined') {
2012 jQuery('.bs-vc-modal-form #bsvc_message').val(oValue.output.message);
2013 if (typeof oValue.output.message_type != 'undefined') {
2014 jQuery('.bs-vc-modal-form #bsvc_message_type').val(oValue.output.message_type);
2015 }
2016 } else if (oValue.output.type == 'page' && typeof oValue.output.page != 'undefined') {
2017 jQuery('.bs-vc-modal-form #bsvc_page').val(oValue.output.page);
2018 } else if (oValue.output.type == 'template_part' && typeof oValue.output.template_part != 'undefined') {
2019 jQuery('.bs-vc-modal-form #bsvc_template_part').val(oValue.output.template_part);
2020 }
2021 }
2022
2023 if (oValue.outputN && oValue.outputN.type) {
2024 jQuery('.bs-vc-modal-form #bsvc_output_n').val(oValue.outputN.type);
2025 if (oValue.outputN.type == 'message' && typeof oValue.outputN.message != 'undefined') {
2026 jQuery('.bs-vc-modal-form #bsvc_message_n').val(oValue.outputN.message);
2027 if (typeof oValue.outputN.message_type != 'undefined') {
2028 jQuery('.bs-vc-modal-form #bsvc_message_type_n').val(oValue.outputN.message_type);
2029 }
2030 } else if (oValue.outputN.type == 'page' && typeof oValue.outputN.page != 'undefined') {
2031 jQuery('.bs-vc-modal-form #bsvc_page_n').val(oValue.outputN.page);
2032 } else if (oValue.outputN.type == 'template_part' && typeof oValue.outputN.template_part != 'undefined') {
2033 jQuery('.bs-vc-modal-form #bsvc_template_part_n').val(oValue.outputN.template_part);
2034 }
2035 }
2036 }
2037 }
2038 /**
2039 * Try to auto-recover blocks.
2040 */
2041 function sd_auto_recover_blocks() {
2042 var recursivelyRecoverInvalidBlockList = blocks => {
2043 const _blocks = [...blocks]
2044 let recoveryCalled = false
2045 const recursivelyRecoverBlocks = willRecoverBlocks => {
2046 willRecoverBlocks.forEach(_block => {
2047 if (!_block.isValid) {
2048 recoveryCalled = true
2049 const newBlock = recoverBlock(_block)
2050 for (const key in newBlock) {
2051 _block[key] = newBlock[key]
2052 }
2053 }
2054 if (_block.innerBlocks.length) {
2055 recursivelyRecoverBlocks(_block.innerBlocks)
2056 }
2057 })
2058 }
2059 recursivelyRecoverBlocks(_blocks)
2060 return [_blocks, recoveryCalled]
2061 }
2062 var recoverBlock = ({ name, attributes, innerBlocks }) => wp.blocks.createBlock(name, attributes, innerBlocks);
2063 var recoverBlocks = blocks => {
2064 return blocks.map(_block => {
2065 const block = _block;
2066 // If the block is a reusable block, recover the Stackable blocks inside it.
2067 if (_block.name === 'core/block') {
2068 const { attributes: { ref } } = _block
2069 const parsedBlocks = wp.blocks.parse(wp.data.select('core').getEntityRecords('postType', 'wp_block', { include: [ref] })?.[0]?.content?.raw) || []
2070 const [recoveredBlocks, recoveryCalled] = recursivelyRecoverInvalidBlockList(parsedBlocks)
2071 if (recoveryCalled) {
2072 console.log('Stackable notice: block ' + block.name + ' (' + block.clientId + ') was auto-recovered, you should not see this after saving your page.');
2073 return { blocks: recoveredBlocks, isReusable: true, ref }
2074 }
2075 } else if (_block.name === 'core/template-part' && _block.attributes && _block.attributes.theme) {
2076 var tmplPart = wp.data.select('core').getEntityRecord('postType', 'wp_template_part', _block.attributes.theme + '//' + _block.attributes.slug);
2077 var tmplPartBlocks = block.innerBlocks && block.innerBlocks.length ? block.innerBlocks : wp.blocks.parse(tmplPart?.content?.raw) || [];
2078 if (tmplPartBlocks && tmplPartBlocks.length && tmplPartBlocks.some(block => !block.isValid)) {
2079 block.innerBlocks = tmplPartBlocks;
2080 block.tmplPartId = _block.attributes.theme + '//' + _block.attributes.slug;
2081 }
2082 }
2083 if (block.innerBlocks && block.innerBlocks.length) {
2084 if (block.tmplPartId) {
2085 console.log('Template part ' + block.tmplPartId + ' block ' + block.name + ' (' + block.clientId + ') starts');
2086 }
2087 const newInnerBlocks = recoverBlocks(block.innerBlocks)
2088 if (newInnerBlocks.some(block => block.recovered)) {
2089 block.innerBlocks = newInnerBlocks
2090 block.replacedClientId = block.clientId
2091 block.recovered = true
2092 }
2093 if (block.tmplPartId) {
2094 console.log('Template part ' + block.tmplPartId + ' block ' + block.name + ' (' + block.clientId + ') ends');
2095 }
2096 }
2097 if (!block.isValid) {
2098 const newBlock = recoverBlock(block)
2099 newBlock.replacedClientId = block.clientId
2100 newBlock.recovered = true
2101 console.log('Stackable notice: block ' + block.name + ' (' + block.clientId + ') was auto-recovered, you should not see this after saving your page.');
2102 return newBlock
2103 }
2104 return block
2105 })
2106 }
2107 // Recover all the blocks that we can find.
2108 var sdBlockEditor = wp.data.select('core/block-editor');
2109 var mainBlocks = sdBlockEditor ? recoverBlocks(sdBlockEditor.getBlocks()) : null;
2110 // Replace the recovered blocks with the new ones.
2111 if (mainBlocks) {
2112 mainBlocks.forEach(block => {
2113 if (block.isReusable && block.ref) {
2114 // Update the reusable blocks.
2115 wp.data.dispatch('core').editEntityRecord('postType', 'wp_block', block.ref, {
2116 content: wp.blocks.serialize(block.blocks)
2117 }).then(() => {
2118 // But don't save them, let the user do the saving themselves. Our goal is to get rid of the block error visually.
2119 })
2120 }
2121 if (block.recovered && block.replacedClientId) {
2122 wp.data.dispatch('core/block-editor').replaceBlock(block.replacedClientId, block)
2123 }
2124 })
2125 }
2126 }
2127
2128 /**
2129 * Try to auto-recover OUR blocks if traditional way fails.
2130 */
2131 function sd_auto_recover_blocks_fallback(editTmpl) {
2132 console.log('sd_auto_recover_blocks_fallback()');
2133 var $bsRecoverBtn = jQuery(".edit-site-visual-editor__editor-canvas").contents().find('div[class*=" wp-block-blockstrap-"] .block-editor-warning__actions .block-editor-warning__action .components-button.is-primary').not(":contains('Keep as HTML')");
2134 if ($bsRecoverBtn.length) {
2135 if(jQuery('.edit-site-layout.is-full-canvas').length || jQuery('.edit-site-layout.is-edit-mode').length){
2136 $bsRecoverBtn.removeAttr('disabled').trigger('click');
2137 }
2138 }
2139 }
2140
2141 <?php if( !isset( $_REQUEST['sd-block-recover-debug'] ) ){ ?>
2142 // Wait will window is loaded before calling.
2143 window.onload = function() {
2144 sd_auto_recover_blocks();
2145 // fire a second time incase of load delays.
2146 setTimeout(function() {
2147 sd_auto_recover_blocks();
2148 }, 5000);
2149
2150 setTimeout(function() {
2151 sd_auto_recover_blocks_fallback();
2152 }, 6000);
2153
2154 setTimeout(function() {
2155 sd_auto_recover_blocks_fallback();
2156 }, 10000);
2157
2158 setTimeout(function() {
2159 sd_auto_recover_blocks_fallback();
2160 }, 15000);
2161
2162 setTimeout(function() {
2163 sd_auto_recover_blocks_fallback();
2164 }, 20000);
2165
2166 setTimeout(function() {
2167 sd_auto_recover_blocks_fallback();
2168 }, 30000);
2169
2170 setTimeout(function() {
2171 sd_auto_recover_blocks_fallback();
2172 }, 60000);
2173
2174 jQuery('.edit-site-page-panels__edit-template-button, .edit-site-visual-editor__editor-canvas').on('click', function() {
2175 setTimeout(function() {
2176 sd_auto_recover_blocks_fallback(true);
2177 jQuery('.edit-site-page-panels__edit-template-button, .edit-site-visual-editor__editor-canvas').addClass('bs-edit-tmpl-clicked');
2178 }, 100);
2179 });
2180 };
2181 <?php } ?>
2182
2183 // fire when URL changes also.
2184 let lastUrl = location.href;
2185 new MutationObserver(() => {
2186 const url = location.href;
2187 if (url !== lastUrl) {
2188 lastUrl = url;
2189 sd_auto_recover_blocks();
2190 // fire a second time incase of load delays.
2191 setTimeout(function() {
2192 sd_auto_recover_blocks();
2193 sd_auto_recover_blocks_fallback();
2194 }, 2000);
2195
2196 setTimeout(function() {
2197 sd_auto_recover_blocks_fallback();
2198 }, 10000);
2199
2200 setTimeout(function() {
2201 sd_auto_recover_blocks_fallback();
2202 }, 15000);
2203
2204 setTimeout(function() {
2205 sd_auto_recover_blocks_fallback();
2206 }, 20000);
2207
2208 }
2209 }).observe(document, {
2210 subtree: true,
2211 childList: true
2212 });
2213
2214
2215 /**
2216 *
2217 * @param $args
2218 * @returns {*|{}}
2219 */
2220 function sd_build_aui_styles($args){
2221
2222 $styles = {};
2223 // background color
2224 if ( $args['bg'] !== undefined && $args['bg'] !== '' ) {
2225 if( $args['bg'] == 'custom-color' ){
2226 $styles['background-color']= $args['bg_color'];
2227 }else if( $args['bg'] == 'custom-gradient' ){
2228 $styles['background-image']= $args['bg_gradient'];
2229
2230 // use background on text
2231 if( $args['bg_on_text'] !== undefined && $args['bg_on_text'] ){
2232 $styles['backgroundClip'] = "text";
2233 $styles['WebkitBackgroundClip'] = "text";
2234 $styles['text-fill-color'] = "transparent";
2235 $styles['WebkitTextFillColor'] = "transparent";
2236 }
2237 }
2238
2239 }
2240
2241 let $bg_image = $args['bg_image'] !== undefined && $args['bg_image'] !== '' ? $args['bg_image'] : '';
2242
2243 // maybe use featured image.
2244 if( $args['bg_image_use_featured'] !== undefined && $args['bg_image_use_featured'] ){
2245 $bg_image = 'data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiID8+CjxzdmcgYmFzZVByb2ZpbGU9InRpbnkiIGhlaWdodD0iNDAwIiB2ZXJzaW9uPSIxLjIiIHdpZHRoPSI0MDAiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6ZXY9Imh0dHA6Ly93d3cudzMub3JnLzIwMDEveG1sLWV2ZW50cyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiPjxkZWZzIC8+PHJlY3QgZmlsbD0iI2QzZDNkMyIgaGVpZ2h0PSI0MDAiIHdpZHRoPSI0MDAiIHg9IjAiIHk9IjAiIC8+PGxpbmUgc3Ryb2tlPSJ3aGl0ZSIgc3Ryb2tlLXdpZHRoPSIxMCIgeDE9IjAiIHgyPSI0MDAiIHkxPSIwIiB5Mj0iNDAwIiAvPjxsaW5lIHN0cm9rZT0id2hpdGUiIHN0cm9rZS13aWR0aD0iMTAiIHgxPSIwIiB4Mj0iNDAwIiB5MT0iNDAwIiB5Mj0iMCIgLz48cmVjdCBmaWxsPSIjZDNkM2QzIiBoZWlnaHQ9IjUwIiB3aWR0aD0iMjE4LjAiIHg9IjkxLjAiIHk9IjE3NS4wIiAvPjx0ZXh0IGZpbGw9IndoaXRlIiBmb250LXNpemU9IjMwIiBmb250LXdlaWdodD0iYm9sZCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgeD0iMjAwLjAiIHk9IjIwNy41Ij5QTEFDRUhPTERFUjwvdGV4dD48L3N2Zz4=';
2246 }
2247
2248 if( $bg_image !== undefined && $bg_image !== '' ){
2249 var hasImage = true
2250 if($styles['background-color'] !== undefined && $args['bg'] == 'custom-color'){
2251 $styles['background-image'] = "url("+$bg_image+")";
2252 $styles['background-blend-mode'] = "overlay";
2253 }else if($styles['background-image'] !== undefined && $args['bg'] == 'custom-gradient'){
2254 $styles['background-image'] += ",url("+$bg_image+")";
2255 }else if($args['bg'] !== undefined && $args['bg'] != '' && $args['bg'] != 'transparent' ){
2256 // do nothing as we already have a preset
2257 hasImage = false;
2258 }else{
2259 $styles['background-image'] = "url("+$bg_image+")";
2260 }
2261
2262 if( hasImage){
2263 $styles['background-size'] = "cover";
2264
2265 if( $args['bg_image_fixed'] !== undefined && $args['bg_image_fixed'] ){
2266 $styles['background-attachment'] = "fixed";
2267 }
2268 }
2269
2270 if( hasImage && $args['bg_image_xy'].x !== undefined && $args['bg_image_xy'].x >=0 ){
2271 $styles['background-position'] = ($args['bg_image_xy'].x * 100 ) + "% " + ( $args['bg_image_xy'].y * 100) + "%";
2272 }
2273 }
2274
2275
2276
2277 // sticky offset top
2278 if( $args['sticky_offset_top'] !== undefined && $args['sticky_offset_top'] !== '' ){
2279 $styles['top'] = $args['sticky_offset_top'];
2280 }
2281
2282 // sticky offset bottom
2283 if( $args['sticky_offset_bottom'] !== undefined && $args['sticky_offset_bottom'] !== '' ){
2284 $styles['bottom'] = $args['sticky_offset_bottom'];
2285 }
2286
2287 // font size
2288 if( $args['font_size'] === undefined || $args['font_size'] === 'custom' ){
2289 if( $args['font_size_custom'] !== undefined && $args['font_size_custom'] !== '' ){
2290 $styles['fontSize'] = $args['font_size_custom'] + "rem";
2291 }
2292 }
2293
2294 // font color
2295 if( $args['text_color'] === undefined || $args['text_color'] === 'custom' ){
2296 if( $args['text_color_custom'] !== undefined && $args['text_color_custom'] !== '' ){
2297 $styles['color'] = $args['text_color_custom'];
2298 }
2299 }
2300
2301 // font line height
2302 if( $args['font_line_height'] !== undefined && $args['font_line_height'] !== '' ){
2303 $styles['lineHeight'] = $args['font_line_height'];
2304 }
2305
2306 // max height
2307 if( $args['max_height'] !== undefined && $args['max_height'] !== '' ){
2308 $styles['maxHeight'] = $args['max_height'];
2309 }
2310
2311 return $styles;
2312
2313 }
2314
2315 function sd_build_aui_class($args){
2316
2317 $classes = [];
2318
2319 <?php
2320 if($aui_bs5){
2321 ?>
2322 $aui_bs5 = true;
2323 $p_ml = 'ms-';
2324 $p_mr = 'me-';
2325
2326 $p_pl = 'ps-';
2327 $p_pr = 'pe-';
2328 <?php
2329 }else{
2330 ?>
2331 $aui_bs5 = false;
2332 $p_ml = 'ml-';
2333 $p_mr = 'mr-';
2334
2335 $p_pl = 'pl-';
2336 $p_pr = 'pr-';
2337 <?php
2338 }
2339 ?>
2340
2341 // margins
2342 if ( $args['mt'] !== undefined && $args['mt'] !== '' ) { $classes.push( "mt-" + $args['mt'] ); $mt = $args['mt']; }else{$mt = null;}
2343 if ( $args['mr'] !== undefined && $args['mr'] !== '' ) { $classes.push( $p_mr + $args['mr'] ); $mr = $args['mr']; }else{$mr = null;}
2344 if ( $args['mb'] !== undefined && $args['mb'] !== '' ) { $classes.push( "mb-" + $args['mb'] ); $mb = $args['mb']; }else{$mb = null;}
2345 if ( $args['ml'] !== undefined && $args['ml'] !== '' ) { $classes.push( $p_ml + $args['ml'] ); $ml = $args['ml']; }else{$ml = null;}
2346
2347 // margins tablet
2348 if ( $args['mt_md'] !== undefined && $args['mt_md'] !== '' ) { $classes.push( "mt-md-" + $args['mt_md'] ); $mt_md = $args['mt_md']; }else{$mt_md = null;}
2349 if ( $args['mr_md'] !== undefined && $args['mr_md'] !== '' ) { $classes.push( $p_mr + "md-" + $args['mr_md'] ); $mt_md = $args['mr_md']; }else{$mr_md = null;}
2350 if ( $args['mb_md'] !== undefined && $args['mb_md'] !== '' ) { $classes.push( "mb-md-" + $args['mb_md'] ); $mt_md = $args['mb_md']; }else{$mb_md = null;}
2351 if ( $args['ml_md'] !== undefined && $args['ml_md'] !== '' ) { $classes.push( $p_ml + "md-" + $args['ml_md'] ); $mt_md = $args['ml_md']; }else{$ml_md = null;}
2352
2353 // margins desktop
2354 if ( $args['mt_lg'] !== undefined && $args['mt_lg'] !== '' ) { if($mt == null && $mt_md == null){ $classes.push( "mt-" + $args['mt_lg'] ); }else{$classes.push( "mt-lg-" + $args['mt_lg'] ); } }
2355 if ( $args['mr_lg'] !== undefined && $args['mr_lg'] !== '' ) { if($mr == null && $mr_md == null){ $classes.push( $p_mr + $args['mr_lg'] ); }else{$classes.push( $p_mr + "lg-" + $args['mr_lg'] ); } }
2356 if ( $args['mb_lg'] !== undefined && $args['mb_lg'] !== '' ) { if($mb == null && $mb_md == null){ $classes.push( "mb-" + $args['mb_lg'] ); }else{$classes.push( "mb-lg-" + $args['mb_lg'] ); } }
2357 if ( $args['ml_lg'] !== undefined && $args['ml_lg'] !== '' ) { if($ml == null && $ml_md == null){ $classes.push( $p_ml + $args['ml_lg'] ); }else{$classes.push( $p_ml + "lg-" + $args['ml_lg'] ); } }
2358
2359 // padding
2360 if ( $args['pt'] !== undefined && $args['pt'] !== '' ) { $classes.push( "pt-" + $args['pt'] ); $pt = $args['pt']; }else{$pt = null;}
2361 if ( $args['pr'] !== undefined && $args['pr'] !== '' ) { $classes.push( $p_pr + $args['pr'] ); $pr = $args['pt']; }else{$pr = null;}
2362 if ( $args['pb'] !== undefined && $args['pb'] !== '' ) { $classes.push( "pb-" + $args['pb'] ); $pb = $args['pt']; }else{$pb = null;}
2363 if ( $args['pl'] !== undefined && $args['pl'] !== '' ) { $classes.push( $p_pl + $args['pl'] ); $pl = $args['pt']; }else{$pl = null;}
2364
2365 // padding tablet
2366 if ( $args['pt_md'] !== undefined && $args['pt_md'] !== '' ) { $classes.push( "pt-md-" + $args['pt_md'] ); $pt_md = $args['pt_md']; }else{$pt_md = null;}
2367 if ( $args['pr_md'] !== undefined && $args['pr_md'] !== '' ) { $classes.push( $p_pr + "md-" + $args['pr_md'] ); $pr_md = $args['pt_md']; }else{$pr_md = null;}
2368 if ( $args['pb_md'] !== undefined && $args['pb_md'] !== '' ) { $classes.push( "pb-md-" + $args['pb_md'] ); $pb_md = $args['pt_md']; }else{$pb_md = null;}
2369 if ( $args['pl_md'] !== undefined && $args['pl_md'] !== '' ) { $classes.push( $p_pl + "md-" + $args['pl_md'] ); $pl_md = $args['pt_md']; }else{$pl_md = null;}
2370
2371 // padding desktop
2372 if ( $args['pt_lg'] !== undefined && $args['pt_lg'] !== '' ) { if($pt == null && $pt_md == null){ $classes.push( "pt-" + $args['pt_lg'] ); }else{$classes.push( "pt-lg-" + $args['pt_lg'] ); } }
2373 if ( $args['pr_lg'] !== undefined && $args['pr_lg'] !== '' ) { if($pr == null && $pr_md == null){ $classes.push( $p_pr + $args['pr_lg'] ); }else{$classes.push( $p_pr + "lg-" + $args['pr_lg'] ); } }
2374 if ( $args['pb_lg'] !== undefined && $args['pb_lg'] !== '' ) { if($pb == null && $pb_md == null){ $classes.push( "pb-" + $args['pb_lg'] ); }else{$classes.push( "pb-lg-" + $args['pb_lg'] ); } }
2375 if ( $args['pl_lg'] !== undefined && $args['pl_lg'] !== '' ) { if($pl == null && $pl_md == null){ $classes.push( $p_pl + $args['pl_lg'] ); }else{$classes.push( $p_pl + "lg-" + $args['pl_lg'] ); } }
2376
2377 // row cols, mobile, tablet, desktop
2378 if ( $args['row_cols'] !== undefined && $args['row_cols'] !== '' ) { $classes.push( "row-cols-" + $args['row_cols'] ); $row_cols = $args['row_cols']; }else{$row_cols = null;}
2379 if ( $args['row_cols_md'] !== undefined && $args['row_cols_md'] !== '' ) { $classes.push( "row-cols-md-" + $args['row_cols_md'] ); $row_cols_md = $args['row_cols_md']; }else{$row_cols_md = null;}
2380 if ( $args['row_cols_lg'] !== undefined && $args['row_cols_lg'] !== '' ) { if($row_cols == null && $row_cols_md == null){ $classes.push( "row-cols-" + $args['row_cols_lg'] ); }else{$classes.push( "row-cols-lg-" + $args['row_cols_lg'] ); } }
2381
2382 // columns , mobile, tablet, desktop
2383 if ( $args['col'] !== undefined && $args['col'] !== '' ) { $classes.push( "col-" + $args['col'] ); $col = $args['col']; }else{$col = null;}
2384 if ( $args['col_md'] !== undefined && $args['col_md'] !== '' ) { $classes.push( "col-md-" + $args['col_md'] ); $col_md = $args['col_md']; }else{$col_md = null;}
2385 if ( $args['col_lg'] !== undefined && $args['col_lg'] !== '' ) { if($col == null && $col_md == null){ $classes.push( "col-" + $args['col_lg'] ); }else{$classes.push( "col-lg-" + $args['col_lg'] ); } }
2386
2387
2388 // border
2389 if ( $args['border'] === undefined || $args['border']=='') { }
2390 else if ( $args['border'] !== undefined && ( $args['border']=='none' || $args['border']==='0') ) { $classes.push( "border-0" ); }
2391 else if ( $args['border'] !== undefined ) {
2392 if($aui_bs5 && $args['border_type'] !== undefined){
2393 $args['border_type'] = $args['border_type'].replace('-left','-start').replace('-right','-end');
2394 }
2395 $border_class = 'border';
2396 if ( $args['border_type'] !== undefined && ! $args['border_type'].includes( '-0' ) ) {
2397 $border_class = '';
2398 }
2399 $classes.push( $border_class + " border-" + $args['border'] );
2400 }
2401
2402 // border radius type
2403 // if ( $args['rounded'] !== undefined && $args['rounded'] !== '' ) { $classes.push($args['rounded']); }
2404
2405 // border radius size
2406 if( $args['rounded_size'] !== undefined && ( $args['rounded_size']==='sm' || $args['rounded_size']==='lg' ) ){
2407 if ( $args['rounded_size'] !== undefined && $args['rounded_size'] !== '' ) {
2408 $classes.push("rounded-" + $args['rounded_size']);
2409 // if we set a size then we need to remove "rounded" if set
2410 var index = $classes.indexOf("rounded");
2411 if (index !== -1) {
2412 $classes.splice(index, 1);
2413 }
2414 }
2415 }else{
2416 // rounded_size , mobile, tablet, desktop
2417 if ( $args['rounded_size'] !== undefined && $args['rounded_size'] !== '' ) { $classes.push( "rounded-" + $args['rounded_size'] ); $rounded_size = $args['rounded_size']; }else{$rounded_size = null;}
2418 if ( $args['rounded_size_md'] !== undefined && $args['rounded_size_md'] !== '' ) { $classes.push( "rounded-md-" + $args['rounded_size_md'] ); $rounded_size_md = $args['rounded_size_md']; }else{$rounded_size_md = null;}
2419 if ( $args['rounded_size_lg'] !== undefined && $args['rounded_size_lg'] !== '' ) { if($rounded_size == null && $rounded_size_md == null){ $classes.push( "rounded-" + $args['rounded_size_lg'] ); }else{$classes.push( "rounded-lg-" + $args['rounded_size_lg'] ); } }
2420 }
2421
2422
2423 // shadow
2424 // if ( $args['shadow'] !== undefined && $args['shadow'] !== '' ) { $classes.push($args['shadow']); }
2425
2426 // background
2427 if ( $args['bg'] !== undefined && $args['bg'] !== '' ) { $classes.push("bg-" + $args['bg']); }
2428
2429 // background image fixed bg_image_fixed
2430 if ( $args['bg_image_fixed'] !== undefined && $args['bg_image_fixed'] !== '' ) { $classes.push("bg-image-fixed"); }
2431
2432 // text_color
2433 if ( $args['text_color'] !== undefined && $args['text_color'] !== '' ) { $classes.push( "text-" + $args['text_color']); }
2434
2435 // text_align
2436 if ( $args['text_justify'] !== undefined && $args['text_justify'] ) { $classes.push('text-justify'); }
2437 else{
2438 if ( $args['text_align'] !== undefined && $args['text_align'] !== '' ) {
2439 if($aui_bs5){ $args['text_align'] = $args['text_align'].replace('-left','-start').replace('-right','-end'); }
2440 $classes.push($args['text_align']); $text_align = $args['text_align'];
2441 }else{$text_align = null;}
2442 if ( $args['text_align_md'] !== undefined && $args['text_align_md'] !== '' ) {
2443 if($aui_bs5){ $args['text_align_md'] = $args['text_align_md'].replace('-left','-start').replace('-right','-end'); }
2444 $classes.push($args['text_align_md']); $text_align_md = $args['text_align_md'];
2445 }else{$text_align_md = null;}
2446 if ( $args['text_align_lg'] !== undefined && $args['text_align_lg'] !== '' ) {
2447 if($aui_bs5){ $args['text_align_lg'] = $args['text_align_lg'].replace('-left','-start').replace('-right','-end'); }
2448 if($text_align == null && $text_align_md == null){ $classes.push($args['text_align_lg'].replace("-lg", ""));
2449 }else{$classes.push($args['text_align_lg']);} }
2450 }
2451
2452 // display
2453 if ( $args['display'] !== undefined && $args['display'] !== '' ) { $classes.push($args['display']); $display = $args['display']; }else{$display = null;}
2454 if ( $args['display_md'] !== undefined && $args['display_md'] !== '' ) { $classes.push($args['display_md']); $display_md = $args['display_md']; }else{$display_md = null;}
2455 if ( $args['display_lg'] !== undefined && $args['display_lg'] !== '' ) { if($display == null && $display_md == null){ $classes.push($args['display_lg'].replace("-lg", "")); }else{$classes.push($args['display_lg']);} }
2456
2457 // bgtus - background transparent until scroll
2458 if ( $args['bgtus'] !== undefined && $args['bgtus'] ) { $classes.push("bg-transparent-until-scroll"); }
2459
2460 // cscos - change color scheme on scroll
2461 if ( $args['bgtus'] !== undefined && $args['bgtus'] && $args['cscos'] !== undefined && $args['cscos'] ) { $classes.push("color-scheme-flip-on-scroll"); }
2462
2463 // hover animations
2464 if ( $args['hover_animations'] !== undefined && $args['hover_animations'] ) { $classes.push($args['hover_animations'].toString().replace(',',' ')); }
2465
2466 // absolute_position
2467 if ( $args['absolute_position'] !== undefined ) {
2468 if ( 'top-left' === $args['absolute_position'] ) {
2469 $classes.push('start-0 top-0');
2470 } else if ( 'top-center' === $args['absolute_position'] ) {
2471 $classes.push('start-50 top-0 translate-middle');
2472 } else if ( 'top-right' === $args['absolute_position'] ) {
2473 $classes.push('end-0 top-0');
2474 } else if ( 'center-left' === $args['absolute_position'] ) {
2475 $classes.push('start-0 bottom-50');
2476 } else if ( 'center' === $args['absolute_position'] ) {
2477 $classes.push('start-50 top-50 translate-middle');
2478 } else if ( 'center-right' === $args['absolute_position'] ) {
2479 $classes.push('end-0 top-50');
2480 } else if ( 'bottom-left' === $args['absolute_position'] ) {
2481 $classes.push('start-0 bottom-0');
2482 } else if ( 'bottom-center' === $args['absolute_position'] ) {
2483 $classes.push('start-50 bottom-0 translate-middle');
2484 } else if ( 'bottom-right' === $args['absolute_position'] ) {
2485 $classes.push('end-0 bottom-0');
2486 }
2487 }
2488
2489 // build classes from build keys
2490 $build_keys = sd_get_class_build_keys();
2491 if ( $build_keys.length ) {
2492 $build_keys.forEach($key => {
2493
2494 if($key.endsWith("-MTD")){
2495
2496 $k = $key.replace("-MTD","");
2497
2498 // Mobile, Tablet, Desktop
2499 if ( $args[$k] !== undefined && $args[$k] !== '' ) { $classes.push( $args[$k] ); $v = $args[$k]; }else{$v = null;}
2500 if ( $args[$k + '_md'] !== undefined && $args[$k + '_md'] !== '' ) { $classes.push( $args[$k + '_md'] ); $v_md = $args[$k + '_md']; }else{$v_md = null;}
2501 if ( $args[$k + '_lg'] !== undefined && $args[$k + '_lg'] !== '' ) { if($v == null && $v_md == null){ $classes.push( $args[$k + '_lg'].replace('-lg','') ); }else{$classes.push( $args[$k + '_lg'] ); } }
2502
2503 }else{
2504 if ( $key == 'font_size' && ( $args[ $key ] == 'custom' || $args[ $key ] === '0' ) ) {
2505 return;
2506 }
2507 if ( $args[$key] !== undefined && $args[$key] !== '' ) { $classes.push($args[$key]); }
2508 }
2509
2510 });
2511 }
2512
2513 return $classes.join(" ");
2514 }
2515
2516 function sd_get_class_build_keys(){
2517 return <?php echo json_encode(sd_get_class_build_keys());?>;
2518 }
2519
2520 <?php
2521
2522
2523 }
2524
2525 if(method_exists($this,'block_global_js')){
2526 echo $this->block_global_js();
2527 }
2528 ?>
2529
2530 jQuery(function() {
2531
2532 /**
2533 * BLOCK: Basic
2534 *
2535 * Registering a basic block with Gutenberg.
2536 * Simple block, renders and saves the same content without any interactivity.
2537 *
2538 * Styles:
2539 * editor.css — Editor styles for the block.
2540 * style.css — Editor & Front end styles for the block.
2541 */
2542 (function (blocksx, elementx, blockEditor) {
2543 if (typeof blockEditor === 'undefined') {
2544 return;<?php /* Yoast SEO load blocks.js without block-editor.js on post edit pages */ ?>
2545 }
2546 var __ = wp.i18n.__; // The __() for internationalization.
2547 var el = wp.element.createElement; // The wp.element.createElement() function to create elements.
2548 var editable = wp.blocks.Editable;
2549 var blocks = wp.blocks;
2550 var registerBlockType = wp.blocks.registerBlockType; // The registerBlockType() to register blocks.
2551 var is_fetching = false;
2552 var prev_attributes = [];
2553
2554 var InnerBlocks = blockEditor.InnerBlocks;
2555
2556 var term_query_type = '';
2557 var post_type_rest_slugs = <?php if(! empty( $this->arguments ) && isset($this->arguments['post_type']['onchange_rest']['values'])){echo "[".json_encode($this->arguments['post_type']['onchange_rest']['values'])."]";}else{echo "[]";} ?>;
2558 const taxonomies_<?php echo str_replace("-","_", $this->id);?> = [{label: "Please wait", value: 0}];
2559 const sort_by_<?php echo str_replace("-","_", $this->id);?> = [{label: "Please wait", value: 0}];
2560 const MediaUpload = wp.blockEditor.MediaUpload;
2561
2562 /**
2563 * Register Basic Block.
2564 *
2565 * Registers a new block provided a unique name and an object defining its
2566 * behavior. Once registered, the block is made available as an option to any
2567 * editor interface where blocks are implemented.
2568 *
2569 * @param {string} name Block name.
2570 * @param {Object} settings Block settings.
2571 * @return {?WPBlock} The block, if it has been successfully
2572 * registered; otherwise `undefined`.
2573 */
2574 registerBlockType('<?php echo str_replace( "_", "-", sanitize_title_with_dashes( $this->options['textdomain'] ) . '/' . sanitize_title_with_dashes( $this->options['class_name'] ) ); ?>', { // Block name. Block names must be string that contains a namespace prefix. Example: my-plugin/my-custom-block.
2575 apiVersion: <?php echo absint( $block_api_version ); ?>,
2576 title: '<?php echo addslashes( $this->options['name'] ); ?>', // Block title.
2577 description: '<?php echo addslashes( $this->options['widget_ops']['description'] )?>', // Block title.
2578 icon: <?php echo $this->get_block_icon( $this->options['block-icon'] );?>,//'<?php echo isset( $this->options['block-icon'] ) ? esc_attr( $this->options['block-icon'] ) : 'shield-alt';?>', // Block icon from Dashicons → https://developer.wordpress.org/resource/dashicons/.
2579 supports: {
2580 <?php
2581 if(!isset($this->options['block-supports']['renaming'])){
2582 $this->options['block-supports']['renaming'] = false;
2583 }
2584 if ( isset( $this->options['block-supports'] ) ) {
2585 echo $this->array_to_attributes( $this->options['block-supports'] );
2586 }
2587 ?>
2588 },
2589 __experimentalLabel( attributes, { context } ) {
2590 var visibility_html = attributes && attributes.visibility_conditions ? ' &#128065;' : '';
2591 var metadata_name = attributes && attributes.metadata && attributes.metadata.name ? attributes.metadata.name : '';
2592 var label_name = <?php echo !empty($this->options['block-label']) ? $this->options['block-label'] : "'" . esc_attr( addslashes( $this->options['name'] ) ) . "'"; ?>;
2593 return metadata_name ? metadata_name + visibility_html : label_name + visibility_html;
2594 },
2595 category: '<?php echo isset( $this->options['block-category'] ) ? esc_attr( $this->options['block-category'] ) : 'common';?>', // Block category — Group blocks together based on common traits E.g. common, formatting, layout widgets, embed.
2596 <?php if ( isset( $this->options['block-keywords'] ) ) {
2597 echo "keywords : " . $this->options['block-keywords'] . ",";
2598 }
2599
2600
2601 // block hover preview.
2602 $example_args = array();
2603 if(!empty($this->arguments)){
2604 foreach($this->arguments as $key => $a_args){
2605 if(isset($a_args['example'])){
2606 $example_args[$key] = $a_args['example'];
2607 }
2608 }
2609 }
2610 $viewport_width = isset($this->options['example']['viewportWidth']) ? 'viewportWidth: '.absint($this->options['example']['viewportWidth']) : '';
2611 $example_inner_blocks = !empty($this->options['example']['innerBlocks']) && is_array($this->options['example']['innerBlocks']) ? 'innerBlocks: ' . wp_json_encode($this->options['example']['innerBlocks']) : '';
2612 if( isset( $this->options['example'] ) && $this->options['example'] === false ){
2613 // no preview if set to false
2614 }elseif( !empty( $example_args ) ){
2615 echo "example : {attributes:{".$this->array_to_attributes( $example_args )."},$viewport_width},";
2616 }elseif( !empty( $this->options['example'] ) ){
2617 unset($this->options['example']['viewportWidth']);
2618 unset($this->options['example']['innerBlocks']);
2619 $example_atts = $this->array_to_attributes( $this->options['example'] );
2620 $example_parts = array();
2621 if($example_atts){
2622 $example_parts[] = rtrim($example_atts,",");
2623 }
2624 if($viewport_width){
2625 $example_parts[] = $viewport_width;
2626 }
2627 if($example_inner_blocks){
2628 $example_parts[] = $example_inner_blocks;
2629 }
2630 if(!empty($example_parts)){
2631 echo "example : {".implode(',', $example_parts)."},";
2632 }
2633 }else{
2634 echo 'example : {viewportWidth: 500},';
2635 }
2636
2637
2638
2639 // limit to parent
2640 if( !empty( $this->options['parent'] ) ){
2641 echo "parent : " . wp_json_encode( $this->options['parent'] ) . ",";
2642 }
2643
2644 // limit allowed blocks
2645 if( !empty( $this->options['allowed-blocks'] ) ){
2646 echo "allowedBlocks : " . wp_json_encode( $this->options['allowed-blocks'] ) . ",";
2647 }
2648
2649 // maybe set no_wrap
2650 $no_wrap = isset( $this->options['no_wrap'] ) && $this->options['no_wrap'] ? true : false;
2651 if ( isset( $this->arguments['no_wrap'] ) && $this->arguments['no_wrap'] ) {
2652 $no_wrap = true;
2653 }
2654 if ( $no_wrap ) {
2655 $this->options['block-wrap'] = '';
2656 }
2657
2658 // Maybe load the drag/drop functions.
2659 $img_drag_drop = false;
2660 $show_alignment = false;
2661
2662 echo "attributes : {";
2663
2664 if ( $show_advanced ) {
2665 echo "show_advanced: {";
2666 echo " type: 'boolean',";
2667 echo " default: false";
2668 echo "},";
2669 }
2670
2671 // Block wrap element
2672 if ( ! empty( $this->options['block-wrap'] ) ) { //@todo we should validate this?
2673 echo "block_wrap: {";
2674 echo " type: 'string',";
2675 echo " default: '" . esc_attr( $this->options['block-wrap'] ) . "'";
2676 echo "},";
2677 }
2678
2679 if ( ! empty( $this->arguments ) ) {
2680 foreach ( $this->arguments as $key => $args ) {
2681 if ( $args['type'] == 'image' || $args['type'] == 'images' ) {
2682 $img_drag_drop = true;
2683 }
2684
2685 // Set if we should show alignment.
2686 if ( $key == 'alignment' ) {
2687 $show_alignment = true;
2688 }
2689
2690 $extra = '';
2691 $_default = isset( $args['default'] ) && ! is_null( $args['default'] ) ? $args['default'] : '';
2692
2693 if ( ! empty( $_default ) ) {
2694 $_default = wp_slash( $_default );
2695 }
2696
2697 if ( $args['type'] == 'notice' || $args['type'] == 'tab' ) {
2698 continue;
2699 } else if ( $args['type'] == 'checkbox' ) {
2700 $type = 'boolean';
2701 $default = $_default ? 'true' : 'false';
2702 } else if ( $args['type'] == 'number' ) {
2703 $type = 'number';
2704 $default = "'" . $_default . "'";
2705 } else if ( $args['type'] == 'select' && ! empty( $args['multiple'] ) ) {
2706 $type = 'array';
2707 if ( isset( $args['default'] ) && is_array( $args['default'] ) ) {
2708 $default = ! empty( $_default ) ? "['" . implode( "','", $_default ) . "']" : "[]";
2709 } else {
2710 $default = "'" . $_default . "'";
2711 }
2712 } else if ( $args['type'] == 'tagselect' ) {
2713 $type = 'array';
2714 $default = "'" . $_default . "'";
2715 } else if ( $args['type'] == 'multiselect' ) {
2716 $type = 'array';
2717 $default = "'" . $_default . "'";
2718 } else if ( $args['type'] == 'image_xy' ) {
2719 $type = 'object';
2720 $default = "'" . $_default . "'";
2721 } else if ( $args['type'] == 'image' ) {
2722 $type = 'string';
2723 $default = "'" . $_default . "'";
2724 } else {
2725 $type = ! empty( $args['hidden_type'] ) ? esc_attr( $args['hidden_type'] ) : 'string';
2726 $default = "'" . $_default . "'";
2727 }
2728
2729 echo $key . " : {";
2730 echo "type : '$type',";
2731 echo "default : $default";
2732 echo "},";
2733 }
2734 }
2735
2736 echo "content : {type : 'string',default: 'Please select the attributes in the block settings'},";
2737 echo "sd_shortcode : {type : 'string',default: ''},";
2738
2739 if ( ! empty( $this->options['nested-block'] ) || ! empty( $this->arguments['html'] ) ) {
2740 echo "sd_shortcode_close : {type : 'string',default: ''},";
2741 }
2742
2743 echo "className: { type: 'string', default: '' }";
2744 echo "},";
2745 ?>
2746 // The "edit" property must be a valid function.
2747 edit: function (props) {
2748 const selectedBlock = wp.data.select('core/block-editor').getSelectedBlock();
2749 <?php
2750 // only include the drag/drop functions if required.
2751 if ( $img_drag_drop ) {
2752 ?>
2753
2754 function enableDragSort(listClass) {
2755 setTimeout(function(){
2756 const sortableLists = document.getElementsByClassName(listClass);
2757 Array.prototype.map.call(sortableLists, (list) => {enableDragList(list)});
2758 }, 300);
2759 }
2760
2761 function enableDragList(list) {
2762 Array.prototype.map.call(list.children, (item) => {enableDragItem(item)});
2763 }
2764
2765 function enableDragItem(item) {
2766 item.setAttribute('draggable', true)
2767 item.ondrag = handleDrag;
2768 item.ondragend = handleDrop;
2769 }
2770
2771 function handleDrag(item) {
2772 const selectedItem = item.target,
2773 list = selectedItem.parentNode,
2774 x = event.clientX,
2775 y = event.clientY;
2776
2777 selectedItem.classList.add('drag-sort-active');
2778 let swapItem = document.elementFromPoint(x, y) === null ? selectedItem : document.elementFromPoint(x, y);
2779
2780 if (list === swapItem.parentNode) {
2781 swapItem = swapItem !== selectedItem.nextSibling ? swapItem : swapItem.nextSibling;
2782 list.insertBefore(selectedItem, swapItem);
2783 }
2784 }
2785
2786 function handleDrop(item) {
2787
2788 item.target.classList.remove('drag-sort-active');
2789
2790 const newOrder = [];
2791 let $parent = item.target.parentNode;
2792 let $field = $parent.dataset.field;
2793 let $imgs = JSON.parse('[' + props.attributes[$field] + ']');
2794 item.target.parentNode.classList.add('xxx');
2795 $children = $parent.children;
2796
2797 Object.keys($children).forEach(function(key) {
2798 let $nKey = $children[key].dataset.index
2799 newOrder.push($imgs[$nKey]);
2800 });
2801
2802 // @todo find out why we need to empty the value first otherwise the order is wrong.
2803 props.setAttributes({ [$field]: '' });
2804 setTimeout(function(){
2805 props.setAttributes({ [$field]: JSON.stringify(newOrder).replace('[','').replace(']','') });
2806 }, 100);
2807
2808 }
2809 <?php } ?>
2810
2811 if (typeof(props.attributes.styleid) !== 'undefined') {
2812 var _styleId = props.attributes.styleid, setStyleId;
2813 if (!window.sdStyleId) {
2814 window.sdStyleId = [];
2815 }
2816 if (_styleId) {
2817 if (window.sdStyleId && window.sdStyleId[_styleId] && window.sdStyleId[_styleId] != props.clientId) {
2818 setStyleId = true;
2819 }
2820 } else {
2821 setStyleId = true;
2822 }
2823 if (setStyleId) {
2824 _styleId = 'block-' + (Math.random() + 1).toString(36).substring(2);
2825 }
2826 window.sdStyleId[_styleId] = props.clientId;
2827 if (setStyleId) {
2828 props.setAttributes({'styleid': _styleId});
2829 }
2830 }
2831
2832 <?php
2833 if(!empty($this->options['block-edit-raw'])) {
2834 echo $this->options['block-edit-raw']; // strings have to be in single quotes, may cause issues
2835 }else{
2836 ?>
2837
2838 function hasSelectedInnerBlock(props) {
2839 const select = wp.data.select('core/editor');
2840 const selected = select.getBlockSelectionStart();
2841 const inner = select.getBlock(props.clientId).innerBlocks;
2842 for (let i = 0; i < inner.length; i++) {
2843 if (inner[i].clientId === selected || inner[i].innerBlocks.length && hasSelectedInnerBlock(inner[i])) {
2844 return true;
2845 }
2846 }
2847 return false;
2848 };
2849
2850 const parentBlocksIDs = wp.data.select( 'core/block-editor' ).getBlockParents(props.clientId);
2851 const parentBlocks = wp.data.select('core/block-editor').getBlocksByClientId(parentBlocksIDs);
2852 // const isParentOfSelectedBlock = useSelect( ( select ) => wp.data.select( 'core/block-editor' ).hasSelectedInnerBlock( props.clientId, true ) ):
2853 const block = wp.data.select('core/block-editor').getBlocksByClientId(props.clientId);//.[0].innerBlocks;
2854 const childBlocks = block[0] == null ? '' : block[0].innerBlocks;
2855
2856 var $value = '';
2857 <?php
2858 // if we have a post_type and a category then link them
2859 if( isset($this->arguments['post_type']) && isset($this->arguments['category']) && !empty($this->arguments['category']['post_type_linked']) ){
2860 ?>
2861 if(typeof(prev_attributes[props.clientId]) != 'undefined' && selectedBlock && selectedBlock.clientId === props.clientId){
2862 $pt = props.attributes.post_type;
2863 if(post_type_rest_slugs.length){
2864 $value = post_type_rest_slugs[0][$pt];
2865 }
2866 var run = false;
2867
2868 if($pt != term_query_type){
2869 run = true;
2870 term_query_type = $pt;
2871 }
2872 <?php
2873 $cat_path = '';
2874 if ( ! empty( $this->arguments['post_type']['onchange_rest']['path'] ) ) {
2875 $cat_path = esc_js( strip_tags( $this->arguments['post_type']['onchange_rest']['path'] ) );
2876 $cat_path = str_replace( array( '&quot;', '&#039;' ), array( '"', "'" ), $cat_path );
2877 }
2878 ?>
2879 /* taxonomies */
2880 if($value && 'post_type' in prev_attributes[props.clientId] && 'category' in prev_attributes[props.clientId] && run){
2881 if (!window.gdCPTCats) {
2882 window.gdCPTCats = [];
2883 }
2884 var gdCatPath = "<?php echo ( ! empty( $cat_path ) ? $cat_path : "/wp/v2/" + $value + "/categories/?per_page=100" ); ?>";
2885 if (window.gdCPTCats[gdCatPath]) {
2886 terms = window.gdCPTCats[gdCatPath];
2887 while (taxonomies_<?php echo str_replace("-","_", $this->id);?>.length) {
2888 taxonomies_<?php echo str_replace("-","_", $this->id);?>.pop();
2889 }
2890 taxonomies_<?php echo str_replace("-","_", $this->id);?>.push({label: "All", value: 0});
2891 jQuery.each( terms, function( key, val ) {
2892 taxonomies_<?php echo str_replace("-","_", $this->id);?>.push({label: val.name, value: val.id});
2893 });
2894
2895 /* Setting the value back and fourth fixes the no update issue that sometimes happens where it won't update the options. */
2896 var $old_cat_value = props.attributes.category
2897 props.setAttributes({category: [0] });
2898 props.setAttributes({category: $old_cat_value });
2899 } else {
2900 wp.apiFetch({path: gdCatPath}).then(terms => {
2901 window.gdCPTCats[gdCatPath] = terms;
2902 while (taxonomies_<?php echo str_replace("-","_", $this->id);?>.length) {
2903 taxonomies_<?php echo str_replace("-","_", $this->id);?>.pop();
2904 }
2905 taxonomies_<?php echo str_replace("-","_", $this->id);?>.push({label: "All", value: 0});
2906 jQuery.each( terms, function( key, val ) {
2907 taxonomies_<?php echo str_replace("-","_", $this->id);?>.push({label: val.name, value: val.id});
2908 });
2909
2910 /* Setting the value back and fourth fixes the no update issue that sometimes happens where it won't update the options. */
2911 var $old_cat_value = props.attributes.category
2912 props.setAttributes({category: [0] });
2913 props.setAttributes({category: $old_cat_value });
2914
2915 return taxonomies_<?php echo str_replace("-","_", $this->id);?>;
2916 });
2917 }
2918 }
2919
2920 /* sort_by */
2921 if($value && 'post_type' in prev_attributes[props.clientId] && 'sort_by' in prev_attributes[props.clientId] && run){
2922 if (!window.gdCPTSort) {
2923 window.gdCPTSort = [];
2924 }
2925 if (window.gdCPTSort[$pt]) {
2926 response = window.gdCPTSort[$pt];
2927 while (sort_by_<?php echo str_replace("-","_", $this->id);?>.length) {
2928 sort_by_<?php echo str_replace("-","_", $this->id);?>.pop();
2929 }
2930
2931 jQuery.each( response, function( key, val ) {
2932 sort_by_<?php echo str_replace("-","_", $this->id);?>.push({label: val, value: key});
2933 });
2934
2935 // setting the value back and fourth fixes the no update issue that sometimes happens where it won't update the options.
2936 var $old_sort_by_value = props.attributes.sort_by
2937 props.setAttributes({sort_by: [0] });
2938 props.setAttributes({sort_by: $old_sort_by_value });
2939 } else {
2940 var data = {
2941 'action': 'geodir_get_sort_options',
2942 'post_type': $pt
2943 };
2944 jQuery.post(ajaxurl, data, function(response) {
2945 response = JSON.parse(response);
2946 window.gdCPTSort[$pt] = response;
2947 while (sort_by_<?php echo str_replace("-","_", $this->id);?>.length) {
2948 sort_by_<?php echo str_replace("-","_", $this->id);?>.pop();
2949 }
2950
2951 jQuery.each( response, function( key, val ) {
2952 sort_by_<?php echo str_replace("-","_", $this->id);?>.push({label: val, value: key});
2953 });
2954
2955 // setting the value back and fourth fixes the no update issue that sometimes happens where it won't update the options.
2956 var $old_sort_by_value = props.attributes.sort_by
2957 props.setAttributes({sort_by: [0] });
2958 props.setAttributes({sort_by: $old_sort_by_value });
2959
2960 return sort_by_<?php echo str_replace("-","_", $this->id);?>;
2961 });
2962 }
2963 }
2964 }
2965 <?php } ?>
2966 <?php
2967 $current_screen = function_exists('get_current_screen') ? get_current_screen() : '';
2968 if(!empty($current_screen->base) && $current_screen->base==='widgets'){
2969 echo 'const { deviceType } = "";';
2970 }else{
2971 ?>
2972 /** Get device type const. */
2973 const wpVersion = '<?php global $wp_version; echo esc_attr($wp_version); ?>';
2974 const { deviceType } = typeof wp.data.useSelect !== 'undefined' ? wp.data.useSelect(select => {
2975 if (parseFloat(wpVersion) < 6.5) {
2976 const { __experimentalGetPreviewDeviceType } = select('core/edit-site') ? select('core/edit-site') : select('core/edit-post') ? select('core/edit-post') : '';
2977 return {
2978 deviceType: __experimentalGetPreviewDeviceType(),
2979 };
2980 } else {
2981 const editorSelect = select('core/editor');
2982 if (editorSelect) {
2983 return {
2984 deviceType: editorSelect.getDeviceType(),
2985 };
2986 } else {
2987 return {
2988 deviceType: 'Desktop', // Default value if device type is not available
2989 };
2990 }
2991 }
2992 }, []) : '';
2993 <?php } ?>
2994 var content = props.attributes.content, shortcode = '';
2995
2996 function onChangeContent($type) {
2997 $refresh = false;
2998 // Set the old content the same as the new one so we only compare all other attributes
2999 if(typeof(prev_attributes[props.clientId]) != 'undefined'){
3000 prev_attributes[props.clientId].content = props.attributes.content;
3001
3002 // don't compare the sd_shortcode as it is changed later
3003 prev_attributes[props.clientId].sd_shortcode = props.attributes.sd_shortcode;
3004 }else if(props.attributes.content === ""){
3005 // if first load and content empty then refresh
3006 $refresh = true;
3007 } else {
3008 // if not new and has content then set it so we dont go fetch it
3009 if(props.attributes.content && props.attributes.content !== 'Please select the attributes in the block settings'){
3010 prev_attributes[props.clientId] = props.attributes;
3011 }
3012 }
3013
3014 if ( ( !is_fetching && JSON.stringify(prev_attributes[props.clientId]) != JSON.stringify(props.attributes) ) || $refresh ) {
3015 is_fetching = true;
3016
3017 var data = {
3018 'action': 'super_duper_output_shortcode',
3019 'shortcode': '<?php echo $this->options['base_id'];?>',
3020 'attributes': props.attributes,
3021 'block_parent_name': parentBlocks.length ? parentBlocks[parentBlocks.length - 1].name : '',
3022 'post_id': <?php global $post; if ( isset( $post->ID ) ) {
3023 echo $post->ID;
3024 }else{echo '0';}?>,
3025 '_ajax_nonce': '<?php echo wp_create_nonce( 'super_duper_output_shortcode' );?>'
3026 };
3027
3028 jQuery.post(ajaxurl, data, function (response) {
3029 return response;
3030 }).then(function (env) {
3031 // if the content is empty then we place some placeholder text
3032 if (env == '') {
3033 env = "<div style='background:#0185ba33;padding: 10px;border: 4px #ccc dashed;'>" + "<?php _e( 'Placeholder for:', 'ayecode-connect' );?> " + props.name + "</div>";
3034 }
3035
3036 <?php
3037 if(!empty($this->options['nested-block'])){
3038 ?>
3039 // props.setAttributes({content: env});
3040 is_fetching = false;
3041 prev_attributes[props.clientId] = props.attributes;
3042 <?php
3043 }else{
3044 ?>
3045 props.setAttributes({content: env});
3046 is_fetching = false;
3047 prev_attributes[props.clientId] = props.attributes;
3048 <?php
3049 }
3050 ?>
3051
3052 // if AUI is active call the js init function
3053 if (typeof aui_init === "function") {
3054 aui_init();
3055 }
3056 });
3057 }
3058
3059 return props.attributes.content;
3060 }
3061
3062 <?php
3063 if(!empty($this->options['block-edit-js'])) {
3064 echo $this->options['block-edit-js'] ; // strings have to be in single quotes, may cause issues
3065 }
3066
3067 if(empty($this->options['block-save-return'])){
3068 ?>
3069 ///////////////////////////////////////////////////////////////////////
3070
3071 // build the shortcode.
3072 shortcode = "[<?php echo $this->options['base_id'];?>";
3073 <?php
3074
3075 if(! empty( $this->arguments )){
3076
3077 foreach($this->arguments as $key => $args){
3078 // if($args['type']=='tabs'){continue;}
3079
3080 // don't add metadata arguments
3081 if (substr($key, 0, 9 ) === 'metadata_') {
3082 continue;
3083 }
3084 ?>
3085 if (props.attributes.hasOwnProperty("<?php echo esc_attr( $key );?>")) {
3086 if ('<?php echo esc_attr( $key );?>' == 'html') {
3087 } else if ('<?php echo esc_attr( $args['type'] );?>' == 'image_xy') {
3088 shortcode += props.attributes.<?php echo esc_attr( $key );?>.length && ( props.attributes.<?php echo esc_attr( $key );?>.x.length || props.attributes.<?php echo esc_attr( $key );?>.y.length ) ? " <?php echo esc_attr( $key );?>='{x:" + props.attributes.<?php echo esc_attr( $key );?>.x + ",y:"+props.attributes.<?php echo esc_attr( $key );?>.y +"}' " : "";
3089 } else {
3090 //shortcode += props.attributes.<?php echo esc_attr( $key );?>.length ? " <?php echo esc_attr( $key );?>='" + props.attributes.<?php echo esc_attr( $key );?>.toString().replace('\'','&#39;') + "' " : "";
3091 shortcode += " <?php echo esc_attr( $key );?>='" + props.attributes.<?php echo esc_attr( $key );?>.toString().replace('\'','&#39;') + "' ";
3092 }
3093 }
3094 <?php
3095 }
3096 }
3097
3098 ?>
3099 shortcode += "]";
3100
3101 if(shortcode){
3102
3103 // can cause a react exception when selecting multile blocks of the same type when the settings are not the same
3104 if (props.attributes.sd_shortcode !== shortcode) {
3105 props.setAttributes({ sd_shortcode: shortcode });
3106 }
3107
3108
3109 <?php
3110 if(!empty($this->options['nested-block']) || !empty($this->arguments['html']) ){
3111 echo "props.setAttributes({sd_shortcode_close: '[/".esc_attr( $this->options['base_id'] )."]'});";
3112 }
3113 ?>
3114 }
3115
3116
3117 ///////////////////////////////////////////////////////////////////////
3118 <?php
3119 } // end nested block check
3120 ?>
3121
3122 return [
3123
3124 el(wp.blockEditor.BlockControls, {key: 'controls'},
3125
3126 <?php if($show_alignment){?>
3127 el(
3128 wp.blockEditor.AlignmentToolbar,
3129 {
3130 value: props.attributes.alignment,
3131 onChange: function (alignment) {
3132 props.setAttributes({alignment: alignment})
3133 }
3134 }
3135 )
3136 <?php }?>
3137
3138 ),
3139
3140 el(wp.blockEditor.InspectorControls, {key: 'inspector'},
3141
3142 <?php
3143
3144 if(! empty( $this->arguments )){
3145
3146 if ( $show_advanced ) {
3147 ?>
3148 el('div', {
3149 style: {'paddingLeft': '16px','paddingRight': '16px'}
3150 },
3151 el(
3152 wp.components.ToggleControl,
3153 {
3154 label: 'Show Advanced Settings?',
3155 checked: props.attributes.show_advanced,
3156 onChange: function (show_advanced) {
3157 props.setAttributes({show_advanced: !props.attributes.show_advanced})
3158 }
3159 }
3160 )
3161 )
3162 ,
3163 <?php
3164 }
3165
3166 $arguments = $this->group_arguments( $this->arguments );
3167 $block_group_tabs = ! empty( $this->options['block_group_tabs'] ) ? $this->group_block_tabs( $this->options['block_group_tabs'], $arguments ) : array();
3168
3169 // Do we have sections?
3170 $has_sections = $arguments == $this->arguments ? false : true;
3171
3172 if($has_sections){
3173 $panel_count = 0;
3174 $open_tab = '';
3175
3176 $open_tab_groups = array();
3177 $used_tabs = array();
3178
3179 foreach ( $arguments as $key => $args ) {
3180 $close_tab = false;
3181 $close_tabs = false;
3182
3183 if ( ! empty( $block_group_tabs ) ) {
3184 foreach ( $block_group_tabs as $tab_name => $tab_args ) {
3185 if ( in_array( $key, $tab_args['groups'] ) ) {
3186 $open_tab_groups[] = $key;
3187
3188 if ( $open_tab != $tab_name ) {
3189 $tab_args['tab']['tabs_open'] = $open_tab == '' ? true : false;
3190 $tab_args['tab']['open'] = true;
3191
3192 $this->block_tab_start( '', $tab_args );
3193 $open_tab = $tab_name;
3194 $used_tabs[] = $tab_name;
3195 }
3196
3197 if ( $open_tab_groups == $tab_args['groups'] ) {
3198 $close_tab = true;
3199 $open_tab_groups = array();
3200
3201 if ( $used_tabs == array_keys( $block_group_tabs ) ) {
3202 $close_tabs = true;
3203 }
3204 }
3205 }
3206 }
3207 }
3208 ?>
3209 el(wp.components.PanelBody, {
3210 title: '<?php esc_attr_e( $key ); ?>',
3211 initialOpen: <?php if ( $panel_count ) {
3212 echo "false";
3213 } else {
3214 echo "true";
3215 }?>
3216 },
3217 <?php
3218 foreach ( $args as $k => $a ) {
3219 $this->block_tab_start( $k, $a );
3220 $this->block_row_start( $k, $a );
3221 $this->build_block_arguments( $k, $a );
3222 $this->block_row_end( $k, $a );
3223 $this->block_tab_end( $k, $a );
3224 }
3225 ?>
3226 ),
3227 <?php
3228 $panel_count ++;
3229
3230 if($close_tab || $close_tabs){
3231 $tab_args = array(
3232 'tab' => array(
3233 'tabs_close' => $close_tabs,
3234 'close' => true,
3235 )
3236
3237 );
3238 $this->block_tab_end( '', $tab_args );
3239 // echo '###close'; print_r($tab_args);
3240 $panel_count = 0;
3241 }
3242 //
3243
3244 }
3245 }else {
3246 ?>
3247 el(wp.components.PanelBody, {
3248 title: '<?php esc_attr_e( "Settings", 'ayecode-connect' ); ?>',
3249 initialOpen: true
3250 },
3251 <?php
3252 foreach ( $this->arguments as $key => $args ) {
3253 $this->block_row_start( $key, $args );
3254 $this->build_block_arguments( $key, $args );
3255 $this->block_row_end( $key, $args );
3256 }
3257 ?>
3258 ),
3259 <?php
3260 }
3261
3262 }
3263 ?>
3264
3265 ),
3266
3267 <?php
3268 // If the user sets block-output array then build it
3269 if ( ! empty( $this->options['block-output'] ) ) {
3270 $this->block_element( $this->options['block-output'] );
3271 }elseif(!empty($this->options['block-edit-return'])){
3272 echo $this->options['block-edit-return'];
3273 }else{
3274 // if no block-output is set then we try and get the shortcode html output via ajax.
3275 $block_edit_wrap_tag = !empty($this->options['block_edit_wrap_tag']) ? esc_attr($this->options['block_edit_wrap_tag']) : 'div';
3276 ?>
3277 el('<?php echo esc_attr($block_edit_wrap_tag); ?>', wp.blockEditor.useBlockProps({
3278 dangerouslySetInnerHTML: {__html: onChangeContent()},
3279 className: props.className,
3280 <?php //if(isset($this->arguments['visibility_conditions'])){ echo 'dataVisibilityConditionSD: props.visibility_conditions ? true : false,';} //@todo we need to implement this in the other outputs also ?>
3281 style: {'minHeight': '30px'}
3282 }))
3283 <?php
3284 }
3285 ?>
3286 ]; // end return
3287
3288 <?php
3289 } // end block-edit-raw else
3290 ?>
3291 },
3292
3293 // The "save" property must be specified and must be a valid function.
3294 save: function (props) {
3295
3296 var attr = props.attributes;
3297 var align = '';
3298
3299 // build the shortcode.
3300 var content = "[<?php echo $this->options['base_id'];?>";
3301 $html = '';
3302 <?php
3303
3304 if(! empty( $this->arguments )){
3305
3306 foreach($this->arguments as $key => $args){
3307 // if($args['type']=='tabs'){continue;}
3308
3309 // don't add metadata arguments
3310 if (substr($key, 0, 9 ) === 'metadata_') {
3311 continue;
3312 }
3313 ?>
3314 if (attr.hasOwnProperty("<?php echo esc_attr( $key );?>")) {
3315 if ('<?php echo esc_attr( $key );?>' == 'html') {
3316 $html = attr.<?php echo esc_attr( $key );?>;
3317 } else if ('<?php echo esc_attr( $args['type'] );?>' == 'image_xy') {
3318 content += " <?php echo esc_attr( $key );?>='{x:" + attr.<?php echo esc_attr( $key );?>.x + ",y:"+attr.<?php echo esc_attr( $key );?>.y +"}' ";
3319 } else {
3320 content += " <?php echo esc_attr( $key );?>='" + attr.<?php echo esc_attr( $key );?>.toString().replace('\'','&#39;') + "' ";
3321 }
3322 }
3323 <?php
3324 }
3325 }
3326
3327 ?>
3328 content += "]";
3329 content = '';
3330
3331 <?php
3332 // if(!empty($this->options['nested-block'])){
3333 // ?>
3334 // $html = 'el( InnerBlocks.Content )';
3335 // <?php
3336 // }
3337 ?>
3338 // if has html element
3339 if ($html) {
3340 //content += $html + "[/<?php echo $this->options['base_id'];?>]";
3341 }
3342
3343 // @todo should we add inline style here or just css classes?
3344 if (attr.alignment) {
3345 if (attr.alignment == 'left') {
3346 align = 'alignleft';
3347 }
3348 if (attr.alignment == 'center') {
3349 align = 'aligncenter';
3350 }
3351 if (attr.alignment == 'right') {
3352 align = 'alignright';
3353 }
3354 }
3355
3356 <?php
3357 // if(!empty($this->options['nested-block'])){
3358 // ?x>
3359 // return el(
3360 // 'div',
3361 // { className: props.className,
3362 // style: {'minHeight': '300px','position':'relative','overflow':'hidden','backgroundImage': 'url(https://s.w.org/images/core/5.5/don-quixote-06.jpg)'}
3363 // },
3364 // el( InnerBlocks.Content ),
3365 // el('div', {dangerouslySetInnerHTML: {__html: content}, className: align})
3366 // );
3367 // <x?php
3368 // }else
3369
3370 if(!empty($this->options['block-output'])){
3371 // echo "return";
3372 // $this->block_element( $this->options['block-output'], true );
3373 // echo ";";
3374
3375 ?>
3376 return el(
3377 '',
3378 {},
3379 // el('', {dangerouslySetInnerHTML: {__html: content}}),
3380 <?php $this->block_element( $this->options['block-output'], true ); ?>
3381 // el('', {dangerouslySetInnerHTML: {__html: "[/<?php echo $this->options['base_id'];?>]"}})
3382 );
3383 <?php
3384
3385 }elseif(!empty($this->options['block-save-return'])){
3386 echo 'return ' . $this->options['block-save-return'];
3387 }elseif(!empty($this->options['nested-block'])){
3388 ?>
3389 return el(
3390 '',
3391 {},
3392 el('', {dangerouslySetInnerHTML: {__html: content+"\n"}}),
3393 InnerBlocks.Content ? el( InnerBlocks.Content ) : '', // @todo i think we need a comma here
3394 // el('', {dangerouslySetInnerHTML: {__html: "[/<?php echo $this->options['base_id'];?>]"}})
3395 );
3396 <?php
3397 }elseif(!empty( $this->options['block-save-return'] ) ){
3398 echo "return ". $this->options['block-edit-return'].";";
3399 }elseif(isset( $this->options['block-wrap'] ) && $this->options['block-wrap'] == ''){
3400 ?>
3401 return content;
3402 <?php
3403 }else{
3404 ?>
3405 var block_wrap = 'div';
3406 if (attr.hasOwnProperty("block_wrap")) {
3407 block_wrap = attr.block_wrap;
3408 }
3409 return el(block_wrap, wp.blockEditor.useBlockProps.save( {dangerouslySetInnerHTML: {__html: content}, className: align} ));
3410 <?php
3411 }
3412 ?>
3413
3414
3415 }
3416 });
3417 })(
3418 window.wp.blocks,
3419 window.wp.element,
3420 window.wp.blockEditor
3421 );
3422
3423 });
3424 </script>
3425 <?php
3426 $output = ob_get_clean();
3427
3428 /*
3429 * We only add the <script> tags for code highlighting, so we strip them from the output.
3430 */
3431
3432 return str_replace( array(
3433 '<script>',
3434 '</script>'
3435 ), '', $output );
3436 }
3437
3438
3439
3440 public function block_row_start($key, $args){
3441
3442 // check for row
3443 if(!empty($args['row'])){
3444
3445 if(!empty($args['row']['open'])){
3446
3447 // element require
3448 $element_require = ! empty( $args['element_require'] ) ? $this->block_props_replace( $args['element_require'], true ) . " && " : "";
3449 $device_type = ! empty( $args['device_type'] ) ? esc_attr($args['device_type']) : '';
3450 $device_type_require = ! empty( $args['device_type'] ) ? " deviceType == '" . esc_attr($device_type) . "' && " : '';
3451 $device_type_icon = '';
3452 if($device_type=='Desktop'){
3453 $device_type_icon = '<span class="dashicons dashicons-desktop" style="font-size: 18px;" onclick="sd_show_view_options(this);"></span>';
3454 }elseif($device_type=='Tablet'){
3455 $device_type_icon = '<span class="dashicons dashicons-tablet" style="font-size: 18px;" onclick="sd_show_view_options(this);"></span>';
3456 }elseif($device_type=='Mobile'){
3457 $device_type_icon = '<span class="dashicons dashicons-smartphone" style="font-size: 18px;" onclick="sd_show_view_options(this);"></span>';
3458 }
3459 echo $element_require;
3460 echo $device_type_require;
3461
3462 if(false){?><script><?php }?>
3463 el('div', {
3464 className: 'bsui components-base-control',
3465 },
3466 <?php if(!empty($args['row']['title'])){ ?>
3467 el('label', {
3468 className: 'components-base-control__label position-relative',
3469 style: {width:"100%"}
3470 },
3471 el('span',{dangerouslySetInnerHTML: {__html: '<?php echo addslashes( $args['row']['title'] ) ?>'}}),
3472 <?php if($device_type_icon){ ?>
3473 deviceType == '<?php echo $device_type;?>' && el('span',{dangerouslySetInnerHTML: {__html: '<?php echo $device_type_icon; ?>'},title: deviceType + ": Set preview mode to change",style: {right:"0",position:"absolute",color:"var(--wp-admin-theme-color)"}})
3474 <?php
3475 }
3476 ?>
3477
3478
3479 ),
3480 <?php }?>
3481 <?php if(!empty($args['row']['desc'])){ ?>
3482 el('p', {
3483 className: 'components-base-control__help mb-0',
3484 },
3485 '<?php echo addslashes( $args['row']['desc'] ); ?>'
3486 ),
3487 <?php }?>
3488 el(
3489 'div',
3490 {
3491 className: 'row mb-n2 <?php if(!empty($args['row']['class'])){ echo esc_attr($args['row']['class']);} ?>',
3492 },
3493 el(
3494 'div',
3495 {
3496 className: 'col pr-2 pe-2',
3497 },
3498
3499 <?php
3500 if(false){?></script><?php }
3501 }elseif(!empty($args['row']['close'])){
3502 if(false){?><script><?php }?>
3503 el(
3504 'div',
3505 {
3506 className: 'col pl-0 ps-0',
3507 },
3508 <?php
3509 if(false){?></script><?php }
3510 }else{
3511 if(false){?><script><?php }?>
3512 el(
3513 'div',
3514 {
3515 className: 'col pl-0 ps-0 pr-2 pe-2',
3516 },
3517 <?php
3518 if(false){?></script><?php }
3519 }
3520
3521 }
3522
3523 }
3524
3525 public function block_row_end($key, $args){
3526
3527 if(!empty($args['row'])){
3528 // maybe close
3529 if(!empty($args['row']['close'])){
3530 echo "))";
3531 }
3532
3533 echo "),";
3534 }
3535 }
3536
3537 public function block_tab_start($key, $args){
3538
3539 // check for row
3540 if(!empty($args['tab'])){
3541
3542 if(!empty($args['tab']['tabs_open'])){
3543
3544 if(false){?><script><?php }?>
3545
3546 el('div',{className: 'bsui'},
3547
3548 el('hr', {className: 'm-0'}), el(
3549 wp.components.TabPanel,
3550 {
3551 activeClass: 'is-active',
3552 className: 'btn-groupx',
3553 initialTabName: '<?php echo addslashes( esc_attr( $args['tab']['key']) ); ?>',
3554 tabs: [
3555
3556 <?php
3557 if(false){?></script><?php }
3558 }
3559
3560 if(!empty($args['tab']['open'])){
3561
3562 if(false){?><script><?php }?>
3563 {
3564 name: '<?php echo addslashes( esc_attr( $args['tab']['key']) ); ?>',
3565 title: el('div', {dangerouslySetInnerHTML: {__html: '<?php echo addslashes( esc_attr( $args['tab']['title']) ); ?>'}}),
3566 className: '<?php echo addslashes( esc_attr( $args['tab']['class']) ); ?>',
3567 content: el('div',{}, <?php if(!empty($args['tab']['desc'])){ ?>el('p', {
3568 className: 'components-base-control__help mb-0',
3569 dangerouslySetInnerHTML: {__html:'<?php echo addslashes( $args['tab']['desc'] ); ?>'}
3570 }),<?php }
3571 if(false){?></script><?php }
3572 }
3573
3574 }
3575
3576 }
3577
3578 public function block_tab_end($key, $args){
3579
3580 if(!empty($args['tab'])){
3581 // maybe close
3582 if(!empty($args['tab']['close'])){
3583 echo ")}, /* tab close */";
3584 }
3585
3586 if(!empty($args['tab']['tabs_close'])){
3587 if(false){?><script><?php }?>
3588 ]}, ( tab ) => {
3589 return tab.content;
3590 }
3591 )), /* tabs close */
3592 <?php if(false){ ?></script><?php }
3593 }
3594 }
3595 }
3596
3597 public function build_block_arguments( $key, $args ) {
3598 global $aui_bs5;
3599
3600 $custom_attributes = ! empty( $args['custom_attributes'] ) ? $this->array_to_attributes( $args['custom_attributes'] ) : '';
3601 $options = '';
3602 $extra = '';
3603 $require = '';
3604 $inside_elements = '';
3605 $after_elements = '';
3606
3607 // `content` is a protected and special argument
3608 if ( $key == 'content' ) {
3609 return;
3610 }
3611
3612 $device_type = ! empty( $args['device_type'] ) ? esc_attr($args['device_type']) : '';
3613 $device_type_require = ! empty( $args['device_type'] ) ? " deviceType == '" . esc_attr($device_type) . "' && " : '';
3614 $device_type_icon = '';
3615 if($device_type=='Desktop'){
3616 $device_type_icon = '<span class="dashicons dashicons-desktop" style="font-size: 18px;" onclick="sd_show_view_options(this);"></span>';
3617 }elseif($device_type=='Tablet'){
3618 $device_type_icon = '<span class="dashicons dashicons-tablet" style="font-size: 18px;" onclick="sd_show_view_options(this);"></span>';
3619 }elseif($device_type=='Mobile'){
3620 $device_type_icon = '<span class="dashicons dashicons-smartphone" style="font-size: 18px;" onclick="sd_show_view_options(this);"></span>';
3621 }
3622
3623 // icon
3624 $icon = '';
3625 if( !empty( $args['icon'] ) ){
3626 $icon .= "el('div', {";
3627 $icon .= "dangerouslySetInnerHTML: {__html: '".self::get_widget_icon( esc_attr($args['icon']))."'},";
3628 $icon .= "className: 'text-center',";
3629 $icon .= "title: '".addslashes( $args['title'] )."',";
3630 $icon .= "}),";
3631
3632 // blank title as its added to the icon.
3633 $args['title'] = '';
3634 }
3635
3636 // require advanced
3637 $require_advanced = ! empty( $args['advanced'] ) ? "props.attributes.show_advanced && " : "";
3638
3639 // element require
3640 $element_require = ! empty( $args['element_require'] ) ? $this->block_props_replace( $args['element_require'], true ) . " && " : "";
3641
3642
3643 $onchange = "props.setAttributes({ $key: $key } )";
3644 $onchangecomplete = "";
3645 $value = "props.attributes.$key";
3646 $text_type = array( 'text', 'password', 'number', 'email', 'tel', 'url', 'colorx','range' );
3647 if ( in_array( $args['type'], $text_type ) ) {
3648 $type = 'TextControl';
3649 // Save numbers as numbers and not strings
3650 if ( $args['type'] == 'number' ) {
3651 $onchange = "props.setAttributes({ $key: $key ? Number($key) : '' } )";
3652 }
3653
3654 if (substr($key, 0, 9 ) === 'metadata_') {
3655 $real_key = str_replace('metadata_','', $key );
3656 $onchange = "props.setAttributes({ metadata: { $real_key: $key } } )";
3657 $value = "props.attributes.metadata && props.attributes.metadata.$real_key ? props.attributes.metadata.$real_key : ''";
3658 }
3659 }
3660 // else if ( $args['type'] == 'popup' ) {
3661 // $type = 'TextControl';
3662 // $args['type'] == 'text';
3663 // $after_elements .= "el( wp.components.Button, {
3664 // className: 'components-button components-circular-option-picker__clear is-primary is-smallx',
3665 // onClick: function(){
3666 // aui_modal('','<input id=\'zzz\' value= />');
3667 // const source = document.getElementById('zzz');
3668 // source.value = props.attributes.$key;
3669 // source.addEventListener('input', function(e){props.setAttributes({ $key: e.target.value });});
3670 // }
3671 // },
3672 // 'test'
3673 // ),";
3674 //
3675 // $value = "props.attributes.$key ? props.attributes.$key : ''";
3676 // }
3677 else if ( $args['type'] == 'styleid' ) {
3678 $type = 'TextControl';
3679 $args['type'] == 'text';
3680 // Save numbers as numbers and not strings
3681 $value = "props.attributes.$key ? props.attributes.$key : ''";
3682 }else if ( $args['type'] == 'notice' ) {
3683
3684 $notice_message = !empty($args['desc']) ? addslashes($args['desc']) : '';
3685 $notice_status = !empty($args['status']) ? esc_attr($args['status']) : 'info';
3686
3687 $notice = "el('div',{className:'bsui'},el(wp.components.Notice, {status: '$notice_status',isDismissible: false,className: 'm-0 pr-0 pe-0 mb-3'},el('div',{dangerouslySetInnerHTML: {__html: '$notice_message'}}))),";
3688 echo $notice_message ? $element_require . $notice : '';
3689 return;
3690 }
3691 /*
3692 * https://www.wptricks.com/question/set-current-tab-on-a-gutenberg-tabpanel-component-from-outside-that-component/ es5 layout
3693 elseif($args['type']=='tabs'){
3694 ?>
3695 el(
3696 wp.components.TabPanel,
3697 {
3698 activeClass: 'active-tab',
3699 initialTabName: deviceType,
3700 tabs: [
3701 {
3702 name: 'Desktop',
3703 title: el('div', {dangerouslySetInnerHTML: {__html: '<i class="fas fa-desktop"></i>'}}),
3704 className: 'tab-one' + deviceType == 'Desktop' ? ' active-tab' : '',
3705 content: el('div', {dangerouslySetInnerHTML: {__html: 'ddd'}})
3706 },
3707 {
3708 name: 'Tablet',
3709 title: el('div', {dangerouslySetInnerHTML: {__html: '<i class="fas fa-tablet-alt"></i>'}}),
3710 className: 'tab-two' + deviceType == 'Tablet' ? ' active-tab' : '',
3711 content: el('div', {dangerouslySetInnerHTML: {__html: 'ttt'}})
3712 },
3713 {
3714 name: 'Mobile',
3715 title: el('div', {dangerouslySetInnerHTML: {__html: '<i class="fas fa-mobile-alt"></i>'}}),
3716 className: 'tab-two' + deviceType == 'Mobile' ? ' active-tab' : '',
3717 content: el('div', {dangerouslySetInnerHTML: {__html: 'mmm'}})
3718 },
3719 ],
3720 },
3721 ( tab ) => {
3722
3723 // @todo https://github.com/WordPress/gutenberg/issues/39248
3724 if(tab.name=='Desktop'){
3725 wp.data.dispatch('core/edit-post').__experimentalSetPreviewDeviceType('Desktop');
3726 wp.data.select('core/edit-post').__experimentalGetPreviewDeviceType();
3727 }else if(tab.name=='Tablet'){
3728 wp.data.dispatch('core/edit-post').__experimentalSetPreviewDeviceType('Tablet');
3729 wp.data.select('core/edit-post').__experimentalGetPreviewDeviceType();
3730 }else if(tab.name=='Mobile'){
3731 wp.data.dispatch('core/edit-post').__experimentalSetPreviewDeviceType('Mobile');
3732 wp.data.select('core/edit-post').__experimentalGetPreviewDeviceType();
3733 }
3734
3735 return tab.content;
3736
3737 }
3738 ),
3739
3740 <?php
3741 return;
3742 }
3743 */
3744 elseif ( $args['type'] == 'color' ) {
3745 $type = 'ColorPicker';
3746 $onchange = "";
3747 $extra = "color: $value,";
3748 if(!empty($args['disable_alpha'])){
3749 $extra .= "disableAlpha: true,";
3750 }
3751 $onchangecomplete = "onChangeComplete: function($key) {
3752 value = $key.rgb.a && $key.rgb.a < 1 ? \"rgba(\"+$key.rgb.r+\",\"+$key.rgb.g+\",\"+$key.rgb.b+\",\"+$key.rgb.a+\")\" : $key.hex;
3753 props.setAttributes({
3754 $key: value
3755 });
3756 },";
3757 }elseif ( $args['type'] == 'gradient' ) {
3758 $type = 'GradientPicker';
3759 $extra .= "gradients: [{
3760 name: 'Vivid cyan blue to vivid purple',
3761 gradient:
3762 'linear-gradient(135deg,rgba(6,147,227,1) 0%,rgb(155,81,224) 100%)',
3763 slug: 'vivid-cyan-blue-to-vivid-purple',
3764 },
3765 {
3766 name: 'Light green cyan to vivid green cyan',
3767 gradient:
3768 'linear-gradient(135deg,rgb(122,220,180) 0%,rgb(0,208,130) 100%)',
3769 slug: 'light-green-cyan-to-vivid-green-cyan',
3770 },
3771 {
3772 name: 'Luminous vivid amber to luminous vivid orange',
3773 gradient:
3774 'linear-gradient(135deg,rgba(252,185,0,1) 0%,rgba(255,105,0,1) 100%)',
3775 slug: 'luminous-vivid-amber-to-luminous-vivid-orange',
3776 },
3777 {
3778 name: 'Luminous vivid orange to vivid red',
3779 gradient:
3780 'linear-gradient(135deg,rgba(255,105,0,1) 0%,rgb(207,46,46) 100%)',
3781 slug: 'luminous-vivid-orange-to-vivid-red',
3782 },
3783 {
3784 name: 'Very light gray to cyan bluish gray',
3785 gradient:
3786 'linear-gradient(135deg,rgb(238,238,238) 0%,rgb(169,184,195) 100%)',
3787 slug: 'very-light-gray-to-cyan-bluish-gray',
3788 },
3789 {
3790 name: 'Cool to warm spectrum',
3791 gradient:
3792 'linear-gradient(135deg,rgb(74,234,220) 0%,rgb(151,120,209) 20%,rgb(207,42,186) 40%,rgb(238,44,130) 60%,rgb(251,105,98) 80%,rgb(254,248,76) 100%)',
3793 slug: 'cool-to-warm-spectrum',
3794 }],";
3795
3796 }elseif ( $args['type'] == 'image' ) {
3797 // print_r($args);
3798
3799 $img_preview = isset($args['focalpoint']) && !$args['focalpoint'] ? " props.attributes.$key && el('img', { src: props.attributes.$key,style: {maxWidth:'100%',background: '#ccc'}})," : " ( props.attributes.$key || props.attributes.{$key}_use_featured ) && el(wp.components.FocalPointPicker,{
3800 url: props.attributes.{$key}_use_featured === true ? 'data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiID8+CjxzdmcgYmFzZVByb2ZpbGU9InRpbnkiIGhlaWdodD0iNDAwIiB2ZXJzaW9uPSIxLjIiIHdpZHRoPSI0MDAiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6ZXY9Imh0dHA6Ly93d3cudzMub3JnLzIwMDEveG1sLWV2ZW50cyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiPjxkZWZzIC8+PHJlY3QgZmlsbD0iI2QzZDNkMyIgaGVpZ2h0PSI0MDAiIHdpZHRoPSI0MDAiIHg9IjAiIHk9IjAiIC8+PGxpbmUgc3Ryb2tlPSJ3aGl0ZSIgc3Ryb2tlLXdpZHRoPSIxMCIgeDE9IjAiIHgyPSI0MDAiIHkxPSIwIiB5Mj0iNDAwIiAvPjxsaW5lIHN0cm9rZT0id2hpdGUiIHN0cm9rZS13aWR0aD0iMTAiIHgxPSIwIiB4Mj0iNDAwIiB5MT0iNDAwIiB5Mj0iMCIgLz48cmVjdCBmaWxsPSIjZDNkM2QzIiBoZWlnaHQ9IjUwIiB3aWR0aD0iMjE4LjAiIHg9IjkxLjAiIHk9IjE3NS4wIiAvPjx0ZXh0IGZpbGw9IndoaXRlIiBmb250LXNpemU9IjMwIiBmb250LXdlaWdodD0iYm9sZCIgdGV4dC1hbmNob3I9Im1pZGRsZSIgeD0iMjAwLjAiIHk9IjIwNy41Ij5QTEFDRUhPTERFUjwvdGV4dD48L3N2Zz4=' : props.attributes.$key,
3801 value: props.attributes.{$key}_xy.x !== undefined && props.attributes.{$key}_xy.x >= 0 ? props.attributes.{$key}_xy : {x: 0.5,y: 0.5,},
3802 // value: props.attributes.{$key}_xy,
3803 onChange: function(focalPoint){
3804 console.log(props.attributes);
3805 return props.setAttributes({
3806 {$key}_xy: focalPoint
3807 });
3808 },
3809 // @todo for some reason this does not work as expected.
3810 // onDrag: function(focalPointTemp){
3811 // return props.setAttributes({
3812 // {$key}_xy: focalPointTemp
3813 // });
3814 // }
3815
3816
3817 }), ";
3818
3819
3820 $value = '""';
3821 $type = 'MediaUpload';
3822 $extra .= "onSelect: function(media){
3823 return props.setAttributes({
3824 $key: media.url,
3825 {$key}_id: media.id
3826 });
3827 },";
3828 $extra .= "type: 'image',";
3829 $extra .= "render: function (obj) {
3830 return el( 'div',{},
3831 ( !props.attributes.$key && !props.attributes.{$key}_use_featured ) && el( wp.components.Button, {
3832 className: 'components-button components-circular-option-picker__clear is-primary is-smallx',
3833 onClick: obj.open
3834 },
3835 'Upload Image'
3836 ),
3837 $img_preview
3838 props.attributes.$key && el( wp.components.Button, {
3839 className: 'components-button components-circular-option-picker__clear is-secondary is-small',
3840 style: {margin:'8px 0',display: 'block'},
3841 onClick: function(){
3842 return props.setAttributes({
3843 $key: '',
3844 {$key}_id: ''
3845 });
3846 }
3847 },
3848 props.attributes.$key? 'Clear' : ''
3849 )
3850 )
3851
3852
3853
3854 }";
3855 $onchange = "";
3856
3857 //$inside_elements = ",el('div',{},'file upload')";
3858 } else if ( $args['type'] == 'images' ) {
3859 $img_preview = "props.attributes.$key && (function() {
3860 let uploads = JSON.parse('['+props.attributes.$key+']');
3861 let images = [];
3862 uploads.map((upload, index) => (
3863 images.push( el('div',{ className: 'col p-2', draggable: 'true', 'data-index': index },
3864 el('img', {
3865 src: (upload.sizes && upload.sizes.thumbnail ? upload.sizes.thumbnail.url : upload.url),
3866 style: { maxWidth:'100%', background: '#ccc', pointerEvents:'none' }
3867 }),
3868 el('i',{
3869 className: 'fas fa-times-circle text-danger position-absolute ml-n2 mt-n1 bg-white rounded-circle c-pointer',
3870 onClick: function() {
3871 aui_confirm('".esc_attr__('Are you sure?')."', '".esc_attr__('Delete')."', '".esc_attr__('Cancel')."', true).then(function(confirmed) {
3872 if (confirmed) {
3873 let new_uploads = JSON.parse('['+props.attributes.$key+']');
3874 new_uploads.splice(index, 1);
3875 return props.setAttributes({ {$key}: JSON.stringify( new_uploads ).replace('[','').replace(']','') });
3876 }
3877 });
3878 }},
3879 '')
3880 ))
3881 ));
3882 return images;
3883 })(),";
3884
3885
3886 $value = '""';
3887 $type = 'MediaUpload';
3888 $extra .= "onSelect: function(media){
3889 let slim_images = props.attributes.$key ? JSON.parse('['+props.attributes.$key+']') : [];
3890 if(media.length){
3891 for (var i=0; i < media.length; i++) {
3892 slim_images.push({id: media[i].id, caption: media[i].caption, description: media[i].description,title: media[i].title,alt: media[i].alt,sizes: media[i].sizes, url: media[i].url});
3893 }
3894 }
3895 var slimImagesV = JSON.stringify(slim_images);
3896 if (slimImagesV) {
3897 slimImagesV = slimImagesV.replace('[','').replace(']','').replace(/'/g, '&#39;');
3898 }
3899 return props.setAttributes({ $key: slimImagesV});
3900 },";
3901 $extra .= "type: 'image',";
3902 $extra .= "multiple: true,";
3903 $extra .= "render: function (obj) {
3904 /* Init the sort */
3905 enableDragSort('sd-sortable');
3906 return el( 'div',{},
3907 el( wp.components.Button, {
3908 className: 'components-button components-circular-option-picker__clear is-primary is-smallx',
3909 onClick: obj.open
3910 },
3911 'Upload Images'
3912 ),
3913 el('div',{
3914 className: 'row row-cols-3 px-2 sd-sortable',
3915 'data-field':'$key'
3916 },
3917 $img_preview
3918 ),
3919 props.attributes.$key && el( wp.components.Button, {
3920 className: 'components-button components-circular-option-picker__clear is-secondary is-small',
3921 style: {margin:'8px 0'},
3922 onClick: function(){
3923 return props.setAttributes({ $key: '' });
3924 }
3925 },
3926 props.attributes.$key ? 'Clear All' : ''
3927 )
3928 )
3929 }";
3930 $onchange = "";
3931
3932 //$inside_elements = ",el('div',{},'file upload')";
3933 }
3934 elseif ( $args['type'] == 'checkbox' ) {
3935 $type = 'CheckboxControl';
3936 $extra .= "checked: props.attributes.$key,";
3937 $onchange = "props.setAttributes({ $key: ! props.attributes.$key } )";
3938 } elseif ( $args['type'] == 'textarea' ) {
3939 $type = 'TextareaControl';
3940
3941 } elseif ( $args['type'] == 'select' || $args['type'] == 'multiselect' ) {
3942 $type = 'SelectControl';
3943
3944 if($args['name'] == 'category' && !empty($args['post_type_linked'])){
3945 $options .= "options: taxonomies_".str_replace("-","_", $this->id).",";
3946 }elseif($args['name'] == 'sort_by' && !empty($args['post_type_linked'])){
3947 $options .= "options: sort_by_".str_replace("-","_", $this->id).",";
3948 }else {
3949
3950 if ( ! empty( $args['options'] ) ) {
3951 $options .= "options: [";
3952 foreach ( $args['options'] as $option_val => $option_label ) {
3953 $options .= "{ value: '" . esc_attr( $option_val ) . "', label: '" . esc_js( addslashes( $option_label ) ) . "' },";
3954 }
3955 $options .= "],";
3956 }
3957 }
3958 if ( isset( $args['multiple'] ) && $args['multiple'] ) { //@todo multiselect does not work at the moment: https://github.com/WordPress/gutenberg/issues/5550
3959 $extra .= ' multiple:true,style:{height:"auto",paddingRight:"8px","overflow-y":"auto"}, ';
3960 }
3961
3962 if($args['type'] == 'multiselect' || ( isset( $args['multiple'] ) && $args['multiple'] ) ){
3963 $after_elements .= "props.attributes.$key && el( wp.components.Button, {
3964 className: 'components-button components-circular-option-picker__clear is-secondary is-small',
3965 style: {margin:'-8px 0 8px 0',display: 'block'},
3966 onClick: function(){
3967 return props.setAttributes({
3968 $key: '',
3969 });
3970 }
3971 },
3972 'Clear'
3973 ),";
3974 }
3975 } elseif ( $args['type'] == 'tagselect' ) {
3976 // $type = 'FormTokenField';
3977 //
3978 // if ( ! empty( $args['options'] ) ) {
3979 // $options .= "suggestions: [";
3980 // foreach ( $args['options'] as $option_val => $option_label ) {
3981 // $options .= "{ value: '" . esc_attr( $option_val ) . "', title: '" . addslashes( $option_label ) . "' },";
3982 //// $options .= "'" . esc_attr( $option_val ) . "':'" . addslashes( $option_label ) . "',";
3983 // }
3984 // $options .= "],";
3985 // }
3986 //
3987 // $onchangex = "{ ( selectedItems ) => {
3988 // // Build array of selected posts.
3989 // let selectedPostsArray = [];
3990 // selectedPosts.map(
3991 // ( postName ) => {
3992 // const matchingPost = posts.find( ( post ) => {
3993 // return post.title.raw === postName;
3994 //
3995 // } );
3996 // if ( matchingPost !== undefined ) {
3997 // selectedPostsArray.push( matchingPost.id );
3998 // }
3999 // }
4000 // )
4001 //
4002 // setAttributes( { selectedPosts: selectedPostsArray } );
4003 // } } ";
4004 // $onchange = '';// "props.setAttributes({ $key: [ props.attributes.$key ] } )";
4005 //
4006 //// $options = "";
4007 // $value = "[]";
4008 // $extra .= ' __experimentalExpandOnFocus: true,';
4009
4010 } else if ( $args['type'] == 'alignment' ) {
4011 $type = 'AlignmentToolbar'; // @todo this does not seem to work but cant find a example
4012 } else if ( $args['type'] == 'margins' ) {
4013
4014 } else if ( $args['type'] == 'visibility_conditions' && $this->supports_block_visibility() ) {
4015 $type = 'TextControl';
4016 $value = "(props.attributes.$key ? props.attributes.$key : '')";
4017 $args['type'] = 'text';
4018 $options .= 'disabled:true,';
4019 $bsvc_title = esc_attr( addslashes( $args['title'] ) );
4020 $bsvc_body = $this->block_visibility_fields( $args );
4021 // @TODO reset button
4022 $bsvc_footer = '<button type="button" class="btn btn-danger d-none">' . __( 'Reset', 'ayecode-connect' ) . '</button>' . ( $aui_bs5 ? '<button type="button" class="btn btn-secondary bs-vc-close text-white" data-bs-dismiss="modal">' . __( 'Close', 'ayecode-connect' ) . '</button>' : '<button type="button" class="close btn btn-secondary bs-vc-close text-white" data-dismiss="modal" aria-label="' . esc_attr__( 'Close', 'ayecode-connect' ) . '"><span aria-hidden="true">&times;</span></button>' ) . '<button type="button" class="btn btn-primary bs-vc-save">' . __( 'Save Rules', 'ayecode-connect' ) . '</button>';
4023 $after_elements .= "el('div', {className: 'components-base-control bs-vc-button-wrap'}, el(wp.components.Button, {
4024 className: 'components-button components-circular-option-picker__clear is-primary is-smallx',
4025 onClick: function() {
4026 var sValue = props.attributes." . $key . ";
4027 var oValue;
4028 try {oValue = JSON.parse(sValue);} catch(err) {}
4029 jQuery(document).off('show.bs.modal', '.bs-vc-modal').on('show.bs.modal', '.bs-vc-modal', function (e) {
4030 if (e.target && jQuery(e.target).hasClass('bs-vc-modal')) {
4031 sd_block_visibility_render_fields(oValue);
4032 if (!jQuery('.bs-vc-modal-form .bs-vc-rule-sets .bs-vc-rule').length) {
4033 jQuery('.bs-vc-modal-form .bs-vc-add-rule').trigger('click');
4034 }
4035 if(typeof aui_init_select2 == 'function') {
4036 aui_init_select2();
4037 }
4038 jQuery('.bs-vc-modal-form').trigger('change');
4039 }
4040 });
4041 aui_modal('" . $bsvc_title . "', '" . addslashes( $bsvc_body ) . "', '" . $bsvc_footer . "', true, 'bs-vc-modal', 'modal-lg', '');
4042 jQuery(document).off('change', '#bsvc_raw_value').on('change', '#bsvc_raw_value', function(e) {
4043 props.setAttributes({" . $key . ": e.target.value});
4044 });
4045 }
4046 },
4047 '" . addslashes( ! empty( $args['button_title'] ) ? $args['button_title'] : $args['title'] ) . "'
4048 ) ),";
4049 } else {
4050 return;// if we have not implemented the control then don't break the JS.
4051 }
4052
4053 // color input does not show the labels so we add them
4054 if($args['type']=='color'){
4055 // add show only if advanced
4056 echo $require_advanced;
4057 // add setting require if defined
4058 echo $element_require;
4059 echo "el('div', {style: {'marginBottom': '8px'}}, '".addslashes( $args['title'] )."'),";
4060 }
4061
4062 // add show only if advanced
4063 echo $require_advanced;
4064 // add setting require if defined
4065 echo $element_require;
4066 echo $device_type_require;
4067
4068 // icon
4069 echo $icon;
4070 ?>
4071 el( <?php echo $args['type'] == 'image' || $args['type'] == 'images' ? $type : "wp.components.".$type; ?>, {
4072 label: <?php if ( empty( $args['title'] ) ) { echo "''"; } else if ( empty( $args['row'] ) && ! empty( $args['device_type'] ) ) { ?>el('label',{className:'components-base-control__label',style:{width:"100%"}},el('span',{dangerouslySetInnerHTML: {__html: '<?php echo addslashes( $args['title'] ) ?>'}}),<?php if ( $device_type_icon ) { ?>deviceType == '<?php echo $device_type;?>' && el('span',{dangerouslySetInnerHTML: {__html: '<?php echo $device_type_icon; ?>'},title: deviceType + ": Set preview mode to change",style: {right:"0",position:"absolute",color:"var(--wp-admin-theme-color)"}})<?php } ?>)<?php
4073 } else { ?>'<?php echo addslashes( trim( esc_html( $args['title'] ) ) ); ?>'<?php } ?>,
4074 help: <?php echo ( isset( $args['desc'] ) ? "el('span', {dangerouslySetInnerHTML: {__html: '" . trim( wp_kses_post( addslashes( $args['desc'] ) ) ) . "'}})" : "''" ); ?>,
4075 value: <?php echo $value; ?>,
4076 <?php if ( $type == 'TextControl' && $args['type'] != 'text' ) {
4077 echo "type: '" . addslashes( $args['type'] ) . "',";
4078 } ?>
4079 <?php if ( ! empty( $args['placeholder'] ) ) {
4080 echo "placeholder: '" . esc_js( addslashes( trim( esc_html( $args['placeholder'] ) ) ) ) . "',";
4081 } ?>
4082 <?php echo $options; ?>
4083 <?php echo $extra; ?>
4084 <?php echo $custom_attributes; ?>
4085 <?php echo $onchangecomplete; ?>
4086 <?php if ( $onchange ) { ?>
4087 onChange: function ( <?php echo $key; ?> ) {
4088 <?php echo $onchange; ?>
4089 }
4090 <?php } ?>
4091 } <?php echo $inside_elements; ?> ),
4092 <?php
4093 echo $after_elements;
4094 }
4095
4096 /**
4097 * Convert an array of attributes to block string.
4098 *
4099 * @param $custom_attributes
4100 *
4101 * @return string
4102 *@todo there is prob a faster way to do this, also we could add some validation here.
4103 *
4104 */
4105 public function array_to_attributes( $custom_attributes, $html = false ) {
4106 $attributes = '';
4107 if ( ! empty( $custom_attributes ) ) {
4108
4109 foreach ( $custom_attributes as $key => $val ) {
4110 if(is_array($val)){
4111 $attributes .= $key.': {'.$this->array_to_attributes( $val, $html ).'},';
4112 }else{
4113 $attributes .= $html ? " $key='$val' " : "'$key': '$val',";
4114 }
4115 }
4116
4117 }
4118
4119 return $attributes;
4120 }
4121
4122
4123
4124 /**
4125 * A self looping function to create the output for JS block elements.
4126 *
4127 * This is what is output in the WP Editor visual view.
4128 *
4129 * @param $args
4130 */
4131 public function block_element( $args, $save = false ) {
4132
4133 // print_r($args);echo '###';exit;
4134
4135 if ( ! empty( $args ) ) {
4136 foreach ( $args as $element => $new_args ) {
4137
4138 if ( is_array( $new_args ) ) { // its an element
4139
4140
4141 if ( isset( $new_args['element'] ) ) {
4142
4143 if ( isset( $new_args['element_require'] ) ) {
4144 echo str_replace( array(
4145 "'+",
4146 "+'"
4147 ), '', $this->block_props_replace( $new_args['element_require'] ) ) . " && ";
4148 unset( $new_args['element_require'] );
4149 }
4150
4151 if($new_args['element']=='InnerBlocks'){
4152 echo "\n el( InnerBlocks, {";
4153 }elseif($new_args['element']=='innerBlocksProps'){
4154 $element = isset($new_args['inner_element']) ? esc_attr($new_args['inner_element']) : 'div';
4155 // echo "\n el( 'section', wp.blockEditor.useInnerBlocksProps( blockProps, {";
4156 // echo $save ? "\n el( '$element', wp.blockEditor.useInnerBlocksProps.save( " : "\n el( '$element', wp.blockEditor.useInnerBlocksProps( ";
4157 echo $save ? "\n el( '$element', wp.blockEditor.useInnerBlocksProps.save( " : "\n el( '$element', wp.blockEditor.useInnerBlocksProps( ";
4158 echo $save ? "wp.blockEditor.useBlockProps.save( {" : "wp.blockEditor.useBlockProps( {";
4159 echo !empty($new_args['blockProps']) ? $this->block_element( $new_args['blockProps'],$save ) : '';
4160
4161 echo "} ), {";
4162 echo !empty($new_args['innerBlocksProps']) && !$save ? $this->block_element( $new_args['innerBlocksProps'],$save ) : '';
4163 // echo '###';
4164
4165 // echo '###';
4166 }elseif($new_args['element']=='BlocksProps'){
4167
4168 if ( isset($new_args['if_inner_element']) ) {
4169 $element = $new_args['if_inner_element'];
4170 }else {
4171 $element = isset($new_args['inner_element']) ? "'".esc_attr($new_args['inner_element'])."'" : "'div'";
4172 }
4173
4174 unset($new_args['inner_element']);
4175 echo $save ? "\n el( $element, wp.blockEditor.useBlockProps.save( {" : "\n el( $element, wp.blockEditor.useBlockProps( {";
4176 echo !empty($new_args['blockProps']) ? $this->block_element( $new_args['blockProps'],$save ) : '';
4177
4178
4179 // echo "} ),";
4180
4181 }else{
4182 echo "\n el( '" . $new_args['element'] . "', {";
4183 }
4184
4185
4186 // get the attributes
4187 foreach ( $new_args as $new_key => $new_value ) {
4188
4189
4190 if ( $new_key == 'element' || $new_key == 'content'|| $new_key == 'if_content' || $new_key == 'element_require' || $new_key == 'element_repeat' || is_array( $new_value ) ) {
4191 // do nothing
4192 } else {
4193 echo $this->block_element( array( $new_key => $new_value ),$save );
4194 }
4195 }
4196
4197 echo $new_args['element']=='BlocksProps' ? '} ),' : "},";// end attributes
4198
4199 // get the content
4200 $first_item = 0;
4201 foreach ( $new_args as $new_key => $new_value ) {
4202 if ( $new_key === 'content' || $new_key === 'if_content' || is_array( $new_value ) ) {
4203
4204 if ( $new_key === 'content' ) {
4205 echo "'" . $this->block_props_replace( wp_slash( $new_value ) ) . "'";
4206 }else if ( $new_key === 'if_content' ) {
4207 echo $this->block_props_replace( $new_value );
4208 }
4209
4210 if ( is_array( $new_value ) ) {
4211
4212 if ( isset( $new_value['element_require'] ) ) {
4213 echo str_replace( array(
4214 "'+",
4215 "+'"
4216 ), '', $this->block_props_replace( $new_value['element_require'] ) ) . " && ";
4217 unset( $new_value['element_require'] );
4218 }
4219
4220 if ( isset( $new_value['element_repeat'] ) ) {
4221 $x = 1;
4222 while ( $x <= absint( $new_value['element_repeat'] ) ) {
4223 $this->block_element( array( '' => $new_value ),$save );
4224 $x ++;
4225 }
4226 } else {
4227 $this->block_element( array( '' => $new_value ),$save );
4228 }
4229 }
4230 $first_item ++;
4231 }
4232 }
4233
4234 if($new_args['element']=='innerBlocksProps' || $new_args['element']=='xBlocksProps'){
4235 echo "))";// end content
4236 }else{
4237 echo ")";// end content
4238 }
4239
4240
4241 echo ", \n";
4242
4243 }
4244 } else {
4245
4246 if ( substr( $element, 0, 3 ) === "if_" ) {
4247 $extra = '';
4248 if( strpos($new_args, '[%WrapClass%]') !== false ){
4249 $new_args = str_replace('[%WrapClass%]"','" + sd_build_aui_class(props.attributes)',$new_args);
4250 $new_args = str_replace('[%WrapClass%]','+ sd_build_aui_class(props.attributes)',$new_args);
4251 }
4252 echo str_replace( "if_", "", $element ) . ": " . $this->block_props_replace( $new_args, true ) . ",";
4253 } elseif ( $element == 'style' && strpos($new_args, '[%WrapStyle%]') !== false ) {
4254 $new_args = str_replace('[%WrapStyle%]','',$new_args);
4255 echo $element . ": {..." . $this->block_props_replace( $new_args ) . " , ...sd_build_aui_styles(props.attributes) },";
4256 // echo $element . ": " . $this->block_props_replace( $new_args ) . ",";
4257 } elseif ( $element == 'style' ) {
4258 echo $element . ": " . $this->block_props_replace( $new_args ) . ",";
4259 } elseif ( ( $element == 'class' || $element == 'className' ) && strpos($new_args, '[%WrapClass%]') !== false ) {
4260 $new_args = str_replace('[%WrapClass%]','',$new_args);
4261 echo $element . ": '" . $this->block_props_replace( $new_args ) . "' + sd_build_aui_class(props.attributes),";
4262 } elseif ( $element == 'template' && $new_args ) {
4263 echo $element . ": $new_args,";
4264 } else {
4265 echo $element . ": '" . $this->block_props_replace( $new_args ) . "',";
4266 }
4267
4268 }
4269 }
4270 }
4271 }
4272
4273 /**
4274 * Replace block attributes placeholders with the proper naming.
4275 *
4276 * @param $string
4277 *
4278 * @return mixed
4279 */
4280 public function block_props_replace( $string, $no_wrap = false ) {
4281 if ( $no_wrap ) {
4282 $string = str_replace( array( "[%", "%]", "%:checked]" ), array( "props.attributes.", "", "" ), $string );
4283 } else {
4284 $string = str_replace( array( "![%", "[%", "%]", "%:checked]" ), array( "'+!props.attributes.", "'+props.attributes.", "+'", "+'" ), $string );
4285 }
4286
4287 return $string;
4288 }
4289
4290 /**
4291 * Outputs the content of the widget
4292 *
4293 * @param array $args
4294 * @param array $instance
4295 */
4296 public function widget( $args, $instance ) {
4297 if ( ! is_array( $args ) ) {
4298 $args = array();
4299 }
4300
4301 // Get the filtered values
4302 $argument_values = $this->argument_values( $instance );
4303 $argument_values = $this->string_to_bool( $argument_values );
4304 $output = $this->output( $argument_values, $args );
4305
4306 $no_wrap = false;
4307 if ( isset( $argument_values['no_wrap'] ) && $argument_values['no_wrap'] ) {
4308 $no_wrap = true;
4309 }
4310
4311 ob_start();
4312 if ( $output && ! $no_wrap ) {
4313
4314 $class_original = $this->options['widget_ops']['classname'];
4315 $class = $this->options['widget_ops']['classname']." sdel-".$this->get_instance_hash();
4316
4317 // Before widget
4318 $before_widget = ! empty( $args['before_widget'] ) ? $args['before_widget'] : '';
4319 $before_widget = $before_widget ? str_replace( $class_original, $class, $before_widget ) : $before_widget;
4320 $before_widget = apply_filters( 'wp_super_duper_before_widget', $before_widget, $args, $instance, $this );
4321 $before_widget = apply_filters( 'wp_super_duper_before_widget_' . $this->base_id, $before_widget, $args, $instance, $this );
4322
4323 // After widget
4324 $after_widget = ! empty( $args['after_widget'] ) ? $args['after_widget'] : '';
4325 $after_widget = apply_filters( 'wp_super_duper_after_widget', $after_widget, $args, $instance, $this );
4326 $after_widget = apply_filters( 'wp_super_duper_after_widget_' . $this->base_id, $after_widget, $args, $instance, $this );
4327
4328 echo $before_widget;
4329 // elementor strips the widget wrapping div so we check for and add it back if needed
4330 if ( $this->is_elementor_widget_output() ) {
4331 // Filter class & attrs for elementor widget output.
4332 $class = apply_filters( 'wp_super_duper_div_classname', $class, $args, $this );
4333 $class = apply_filters( 'wp_super_duper_div_classname_' . $this->base_id, $class, $args, $this );
4334
4335 $attrs = apply_filters( 'wp_super_duper_div_attrs', '', $args, $this );
4336 $attrs = apply_filters( 'wp_super_duper_div_attrs_' . $this->base_id, '', $args, $this );
4337
4338 echo "<span class='" . esc_attr( $class ) . "' " . $attrs . ">";
4339 }
4340 echo $this->output_title( $args, $instance );
4341 echo $output;
4342 if ( $this->is_elementor_widget_output() ) {
4343 echo "</span>";
4344 }
4345 echo $after_widget;
4346 } elseif ( $this->is_preview() && $output == '' ) {// if preview show a placeholder if empty
4347 $output = $this->preview_placeholder_text( "{{" . $this->base_id . "}}" );
4348 echo $output;
4349 } elseif ( $output && $no_wrap ) {
4350 echo $output;
4351 }
4352 $output = ob_get_clean();
4353
4354 $output = apply_filters( 'wp_super_duper_widget_output', $output, $instance, $args, $this );
4355
4356 echo $output;
4357 }
4358
4359 /**
4360 * Tests if the current output is inside a elementor container.
4361 *
4362 * @return bool
4363 *@since 1.0.4
4364 */
4365 public function is_elementor_widget_output() {
4366 $result = false;
4367 if ( defined( 'ELEMENTOR_VERSION' ) && isset( $this->number ) && $this->number == 'REPLACE_TO_ID' ) {
4368 $result = true;
4369 }
4370
4371 return $result;
4372 }
4373
4374 /**
4375 * Tests if the current output is inside a elementor preview.
4376 *
4377 * @return bool
4378 *@since 1.0.4
4379 */
4380 public function is_elementor_preview() {
4381 $result = false;
4382 if ( isset( $_REQUEST['elementor-preview'] ) || ( is_admin() && isset( $_REQUEST['action'] ) && $_REQUEST['action'] == 'elementor' ) || ( isset( $_REQUEST['action'] ) && $_REQUEST['action'] == 'elementor_ajax' ) ) {
4383 $result = true;
4384 }
4385
4386 return $result;
4387 }
4388
4389 /**
4390 * Tests if the current output is inside a Divi preview.
4391 *
4392 * @return bool
4393 *@since 1.0.6
4394 */
4395 public function is_divi_preview() {
4396 $result = false;
4397 if ( isset( $_REQUEST['et_fb'] ) || isset( $_REQUEST['et_pb_preview'] ) || ( is_admin() && isset( $_REQUEST['action'] ) && $_REQUEST['action'] == 'elementor' ) ) {
4398 $result = true;
4399 }
4400
4401 return $result;
4402 }
4403
4404 /**
4405 * Tests if the current output is inside a Beaver builder preview.
4406 *
4407 * @return bool
4408 *@since 1.0.6
4409 */
4410 public function is_beaver_preview() {
4411 $result = false;
4412 if ( isset( $_REQUEST['fl_builder'] ) ) {
4413 $result = true;
4414 }
4415
4416 return $result;
4417 }
4418
4419 /**
4420 * Tests if the current output is inside a siteorigin builder preview.
4421 *
4422 * @return bool
4423 *@since 1.0.6
4424 */
4425 public function is_siteorigin_preview() {
4426 $result = false;
4427 if ( ! empty( $_REQUEST['siteorigin_panels_live_editor'] ) ) {
4428 $result = true;
4429 }
4430
4431 return $result;
4432 }
4433
4434 /**
4435 * Tests if the current output is inside a cornerstone builder preview.
4436 *
4437 * @return bool
4438 *@since 1.0.8
4439 */
4440 public function is_cornerstone_preview() {
4441 $result = false;
4442 if ( ! empty( $_REQUEST['cornerstone_preview'] ) || basename( $_SERVER['REQUEST_URI'] ) == 'cornerstone-endpoint' ) {
4443 $result = true;
4444 }
4445
4446 return $result;
4447 }
4448
4449 /**
4450 * Tests if the current output is inside a fusion builder preview.
4451 *
4452 * @return bool
4453 *@since 1.1.0
4454 */
4455 public function is_fusion_preview() {
4456 $result = false;
4457 if ( ! empty( $_REQUEST['fb-edit'] ) || ! empty( $_REQUEST['fusion_load_nonce'] ) ) {
4458 $result = true;
4459 }
4460
4461 return $result;
4462 }
4463
4464 /**
4465 * Tests if the current output is inside a Oxygen builder preview.
4466 *
4467 * @return bool
4468 *@since 1.0.18
4469 */
4470 public function is_oxygen_preview() {
4471 $result = false;
4472 if ( ! empty( $_REQUEST['ct_builder'] ) || ( ! empty( $_REQUEST['action'] ) && ( substr( $_REQUEST['action'], 0, 11 ) === "oxy_render_" || substr( $_REQUEST['action'], 0, 10 ) === "ct_render_" ) ) ) {
4473 $result = true;
4474 }
4475
4476 return $result;
4477 }
4478
4479 /**
4480 * Check for Kallyas theme Zion builder preview.
4481 *
4482 * @since 1.1.22
4483 *
4484 * @return bool True when preview page otherwise false.
4485 */
4486 public function is_kallyas_zion_preview() {
4487 $result = false;
4488
4489 if ( function_exists( 'znhg_kallyas_theme_config' ) && ! empty( $_REQUEST['zn_pb_edit'] ) ) {
4490 $result = true;
4491 }
4492
4493 return $result;
4494 }
4495
4496 /**
4497 * Check for Bricks theme builder preview.
4498 *
4499 * @since 1.1.31
4500 *
4501 * @return bool True when preview page otherwise false.
4502 */
4503 public function is_bricks_preview() {
4504 $result = false;
4505
4506 if ( function_exists( 'bricks_is_builder' ) && ( bricks_is_builder() || bricks_is_builder_call() ) ) {
4507 $result = true;
4508 }
4509
4510 return $result;
4511 }
4512
4513 /**
4514 * Check for Breakdance builder preview.
4515 *
4516 * @since 1.2.28
4517 *
4518 * @return bool True when preview page otherwise false.
4519 */
4520 public function is_breakdance_preview() {
4521 return ( \function_exists( 'Breakdance\\isRequestFromBuilderIframe' ) && ( \Breakdance\isRequestFromBuilderIframe() || \Breakdance\isRequestFromBuilderSsr() ) );
4522 }
4523
4524 /**
4525 * General function to check if we are in a preview situation.
4526 *
4527 * @return bool
4528 *@since 1.0.6
4529 */
4530 public function is_preview() {
4531 $preview = false;
4532 if ( $this->is_divi_preview() ) {
4533 $preview = true;
4534 } elseif ( $this->is_elementor_preview() ) {
4535 $preview = true;
4536 } elseif ( $this->is_beaver_preview() ) {
4537 $preview = true;
4538 } elseif ( $this->is_siteorigin_preview() ) {
4539 $preview = true;
4540 } elseif ( $this->is_cornerstone_preview() ) {
4541 $preview = true;
4542 } elseif ( $this->is_fusion_preview() ) {
4543 $preview = true;
4544 } elseif ( $this->is_oxygen_preview() ) {
4545 $preview = true;
4546 } elseif( $this->is_kallyas_zion_preview() ) {
4547 $preview = true;
4548 } elseif( $this->is_block_content_call() ) {
4549 $preview = true;
4550 } elseif( $this->is_bricks_preview() ) {
4551 $preview = true;
4552 } elseif( $this->is_breakdance_preview() ) {
4553 $preview = true;
4554 }
4555
4556 return $preview;
4557 }
4558
4559 /**
4560 * Output the super title.
4561 *
4562 * @param $args
4563 * @param array $instance
4564 *
4565 * @return string
4566 */
4567 public function output_title( $args, $instance = array() ) {
4568 $output = '';
4569 if ( ! empty( $instance['title'] ) ) {
4570 /** This filter is documented in wp-includes/widgets/class-wp-widget-pages.php */
4571 $title = apply_filters( 'widget_title', $instance['title'], $instance, $this->id_base );
4572
4573 if ( empty( $instance['widget_title_tag'] ) ) {
4574 if ( ! isset( $args['before_title'] ) ) {
4575 $args['before_title'] = '';
4576 }
4577
4578 if ( ! isset( $args['after_title'] ) ) {
4579 $args['after_title'] = '';
4580 }
4581
4582 $output = $args['before_title'] . $title . $args['after_title'];
4583 } else {
4584 $tag = esc_attr( $instance['widget_title_tag'] );
4585 $allowed_tags = array( 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'span', 'div', 'p' );
4586 $title_tag = in_array( $tag, $allowed_tags, true ) ? esc_attr( $tag ) : 'h2';
4587
4588 // classes
4589 $title_classes = array();
4590 $title_classes[] = !empty( $instance['widget_title_size_class'] ) ? sanitize_html_class( $instance['widget_title_size_class'] ) : '';
4591 $title_classes[] = !empty( $instance['widget_title_align_class'] ) ? sanitize_html_class( $instance['widget_title_align_class'] ) : '';
4592 $title_classes[] = !empty( $instance['widget_title_color_class'] ) ? "text-".sanitize_html_class( $instance['widget_title_color_class'] ) : '';
4593 $title_classes[] = !empty( $instance['widget_title_border_class'] ) ? sanitize_html_class( $instance['widget_title_border_class'] ) : '';
4594 $title_classes[] = !empty( $instance['widget_title_border_color_class'] ) ? "border-".sanitize_html_class( $instance['widget_title_border_color_class'] ) : '';
4595 $title_classes[] = !empty( $instance['widget_title_mt_class'] ) ? "mt-".absint( $instance['widget_title_mt_class'] ) : '';
4596 $title_classes[] = !empty( $instance['widget_title_mr_class'] ) ? "mr-".absint( $instance['widget_title_mr_class'] ) : '';
4597 $title_classes[] = !empty( $instance['widget_title_mb_class'] ) ? "mb-".absint( $instance['widget_title_mb_class'] ) : '';
4598 $title_classes[] = !empty( $instance['widget_title_ml_class'] ) ? "ml-".absint( $instance['widget_title_ml_class'] ) : '';
4599 $title_classes[] = !empty( $instance['widget_title_pt_class'] ) ? "pt-".absint( $instance['widget_title_pt_class'] ) : '';
4600 $title_classes[] = !empty( $instance['widget_title_pr_class'] ) ? "pr-".absint( $instance['widget_title_pr_class'] ) : '';
4601 $title_classes[] = !empty( $instance['widget_title_pb_class'] ) ? "pb-".absint( $instance['widget_title_pb_class'] ) : '';
4602 $title_classes[] = !empty( $instance['widget_title_pl_class'] ) ? "pl-".absint( $instance['widget_title_pl_class'] ) : '';
4603
4604 $class = !empty( $title_classes ) ? implode(" ",$title_classes) : '';
4605 $output = "<$title_tag class='$class' >$title</$title_tag>";
4606 }
4607
4608 }
4609
4610 return $output;
4611 }
4612
4613 /**
4614 * Outputs the options form inputs for the widget.
4615 *
4616 * @param array $instance The widget options.
4617 */
4618 public function form( $instance ) {
4619
4620 // set widget instance
4621 $this->instance = $instance;
4622
4623 // set it as a SD widget
4624 echo $this->widget_advanced_toggle();
4625
4626 echo "<p>" . esc_attr( $this->options['widget_ops']['description'] ) . "</p>";
4627 $arguments_raw = $this->get_arguments();
4628
4629 if ( is_array( $arguments_raw ) ) {
4630
4631 $arguments = $this->group_arguments( $arguments_raw );
4632
4633 // Do we have sections?
4634 $has_sections = $arguments == $arguments_raw ? false : true;
4635
4636
4637 if ( $has_sections ) {
4638 $panel_count = 0;
4639 foreach ( $arguments as $key => $args ) {
4640
4641 ?>
4642 <script>
4643 // jQuery(this).find("i").toggleClass("fas fa-chevron-up fas fa-chevron-down");jQuery(this).next().toggle();
4644 </script>
4645 <?php
4646
4647 $hide = $panel_count ? ' style="display:none;" ' : '';
4648 $icon_class = $panel_count ? 'fas fa-chevron-up' : 'fas fa-chevron-down';
4649 echo "<button onclick='jQuery(this).find(\"i\").toggleClass(\"fas fa-chevron-up fas fa-chevron-down\");jQuery(this).next().slideToggle();' type='button' class='sd-toggle-group-button sd-input-group-toggle" . sanitize_title_with_dashes( $key ) . "'>" . esc_attr( $key ) . " <i style='float:right;' class='" . $icon_class . "'></i></button>";
4650 echo "<div class='sd-toggle-group sd-input-group-" . sanitize_title_with_dashes( $key ) . "' $hide>";
4651
4652 foreach ( $args as $k => $a ) {
4653
4654 $this->widget_inputs_row_start($k, $a);
4655 $this->widget_inputs( $a, $instance );
4656 $this->widget_inputs_row_end($k, $a);
4657
4658 }
4659
4660 echo "</div>";
4661
4662 $panel_count ++;
4663
4664 }
4665 } else {
4666 foreach ( $arguments as $key => $args ) {
4667 $this->widget_inputs_row_start($key, $args);
4668 $this->widget_inputs( $args, $instance );
4669 $this->widget_inputs_row_end($key, $args);
4670 }
4671 }
4672
4673 }
4674 }
4675
4676 public function widget_inputs_row_start( $key, $args ) {
4677 if ( ! empty( $args['row'] ) ) {
4678 // Maybe open
4679 if ( ! empty( $args['row']['open'] ) ) {
4680 ?>
4681 <div class='bsui sd-argument' data-argument='<?php echo esc_attr( $args['row']['key'] ); ?>' data-element_require='<?php echo ( ! empty( $args['row']['element_require'] ) ? $this->convert_element_require( $args['row']['element_require'] ) : '' ); ?>'>
4682 <?php if ( ! empty( $args['row']['title'] ) ) { ?>
4683 <?php
4684 if ( isset( $args['row']['icon'] ) ) {
4685 $args['row']['icon'] = '';
4686 }
4687
4688 if ( ! isset( $args['row']['device_type'] ) && isset( $args['device_type'] ) ) {
4689 $args['row']['device_type'] = $args['device_type'];
4690 }
4691 ?>
4692 <label class="mb-0"><?php echo $this->widget_field_title( $args['row'] ); ?><?php echo $this->widget_field_desc( $args['row'] ); ?></label>
4693 <?php } ?>
4694 <div class='row<?php echo ( ! empty( $args['row']['class'] ) ? ' ' . esc_attr( $args['row']['class'] ) : '' ); ?>'>
4695 <div class='col pr-2'>
4696 <?php
4697 } else if ( ! empty( $args['row']['close'] ) ) {
4698 echo "<div class='col pl-0 ps-0'>";
4699 } else {
4700 echo "<div class='col pl-0 ps-0 pr-2 pe-2'>";
4701 }
4702 }
4703 }
4704
4705 public function widget_inputs_row_end( $key, $args ) {
4706 if ( ! empty( $args['row'] ) ) {
4707 // Maybe close
4708 if ( ! empty( $args['row']['close'] ) ) {
4709 echo "</div></div>";
4710 }
4711 echo "</div>";
4712 }
4713 }
4714
4715 /**
4716 * Get the hidden input that when added makes the advanced button show on widget settings.
4717 *
4718 * @return string
4719 */
4720 public function widget_advanced_toggle() {
4721
4722 $output = '';
4723 if ( $this->block_show_advanced() ) {
4724 $val = 1;
4725 } else {
4726 $val = 0;
4727 }
4728
4729 $output .= "<input type='hidden' class='sd-show-advanced' value='$val' />";
4730
4731 return $output;
4732 }
4733
4734 /**
4735 * Convert require element.
4736 *
4737 * @param string $input Input element.
4738 *
4739 * @return string $output
4740 *@since 1.0.0
4741 *
4742 */
4743 public function convert_element_require( $input ) {
4744 $input = str_replace( "'", '"', $input );// we only want double quotes
4745
4746 $output = esc_attr( str_replace( array( "[%", "%]", "%:checked]" ), array(
4747 "jQuery(form).find('[data-argument=\"",
4748 "\"]').find('input,select,textarea').val()",
4749 "\"]').find('input:checked').val()"
4750 ), $input ) );
4751
4752 return $output;
4753 }
4754
4755 /**
4756 * Builds the inputs for the widget options.
4757 *
4758 * @param $args
4759 * @param $instance
4760 */
4761 public function widget_inputs( $args, $instance ) {
4762
4763 $class = "";
4764 $element_require = "";
4765 $custom_attributes = "";
4766
4767 // get value
4768 if ( isset( $instance[ $args['name'] ] ) ) {
4769 $value = $instance[ $args['name'] ];
4770 } elseif ( ! isset( $instance[ $args['name'] ] ) && ! empty( $args['default'] ) ) {
4771 $value = is_array( $args['default'] ) ? array_map( "esc_html", $args['default'] ) : esc_html( $args['default'] );
4772 } else {
4773 $value = '';
4774 }
4775
4776 // get placeholder
4777 if ( ! empty( $args['placeholder'] ) ) {
4778 $placeholder = "placeholder='" . esc_html( $args['placeholder'] ) . "'";
4779 } else {
4780 $placeholder = '';
4781 }
4782
4783 // get if advanced
4784 if ( isset( $args['advanced'] ) && $args['advanced'] ) {
4785 $class .= " sd-advanced-setting ";
4786 }
4787
4788 // element_require
4789 if ( isset( $args['element_require'] ) && $args['element_require'] ) {
4790 $element_require = $args['element_require'];
4791 }
4792
4793 // custom_attributes
4794 if ( isset( $args['custom_attributes'] ) && $args['custom_attributes'] ) {
4795 $custom_attributes = $this->array_to_attributes( $args['custom_attributes'], true );
4796 }
4797
4798 // before wrapper
4799 ?>
4800 <p class="sd-argument <?php echo esc_attr( $class ); ?>" data-argument='<?php echo esc_attr( $args['name'] ); ?>' data-element_require='<?php if ( $element_require ) { echo $this->convert_element_require( $element_require );} ?>'>
4801 <?php
4802 switch ( $args['type'] ) {
4803 //array('text','password','number','email','tel','url','color')
4804 case "text":
4805 case "password":
4806 case "number":
4807 case "email":
4808 case "tel":
4809 case "url":
4810 case "color":
4811 ?>
4812 <label for="<?php echo esc_attr( $this->get_field_id( $args['name'] ) ); ?>"><?php echo $this->widget_field_title( $args );?><?php echo $this->widget_field_desc( $args ); ?></label>
4813 <input <?php echo $placeholder; ?> class="widefat" <?php echo $custom_attributes; ?> id="<?php echo esc_attr( $this->get_field_id( $args['name'] ) ); ?>" name="<?php echo esc_attr( $this->get_field_name( $args['name'] ) ); ?>" type="<?php echo esc_attr( $args['type'] ); ?>" value="<?php echo esc_attr( $value ); ?>">
4814 <?php
4815
4816 break;
4817 case "select":
4818 $multiple = isset( $args['multiple'] ) && $args['multiple'] ? true : false;
4819 if ( $multiple ) {
4820 if ( empty( $value ) ) {
4821 $value = array();
4822 }
4823 }
4824 ?>
4825 <label for="<?php echo esc_attr( $this->get_field_id( $args['name'] ) ); ?>"><?php echo $this->widget_field_title( $args ); ?><?php echo $this->widget_field_desc( $args ); ?></label>
4826 <select <?php echo $placeholder; ?> class="widefat" <?php echo $custom_attributes; ?> id="<?php echo esc_attr( $this->get_field_id( $args['name'] ) ); ?>" name="<?php echo esc_attr( $this->get_field_name( $args['name'] ) ); if ( $multiple ) { echo "[]"; } ?>"
4827 <?php if ( $multiple ) {
4828 echo "multiple";
4829 } //@todo not implemented yet due to gutenberg not supporting it
4830 ?>>
4831 <?php
4832
4833 if ( ! empty( $args['options'] ) ) {
4834 foreach ( $args['options'] as $val => $label ) {
4835 if ( $multiple ) {
4836 $selected = in_array( $val, $value ) ? 'selected="selected"' : '';
4837 } else {
4838 $selected = selected( $value, $val, false );
4839 }
4840 echo "<option value='$val' " . $selected . ">$label</option>";
4841 }
4842 }
4843 ?>
4844 </select>
4845 <?php
4846 break;
4847 case "checkbox":
4848 ?>
4849 <input <?php echo $placeholder; ?> <?php checked( 1, $value, true ) ?> <?php echo $custom_attributes; ?> class="widefat" id="<?php echo esc_attr( $this->get_field_id( $args['name'] ) ); ?>" name="<?php echo esc_attr( $this->get_field_name( $args['name'] ) ); ?>" type="checkbox" value="1">
4850 <label for="<?php echo esc_attr( $this->get_field_id( $args['name'] ) ); ?>"><?php echo $this->widget_field_title( $args );?><?php echo $this->widget_field_desc( $args ); ?></label>
4851 <?php
4852 break;
4853 case "textarea":
4854 ?>
4855 <label for="<?php echo esc_attr( $this->get_field_id( $args['name'] ) ); ?>"><?php echo $this->widget_field_title( $args ); ?><?php echo $this->widget_field_desc( $args ); ?></label>
4856 <textarea <?php echo $placeholder; ?> class="widefat" <?php echo $custom_attributes; ?> id="<?php echo esc_attr( $this->get_field_id( $args['name'] ) ); ?>" name="<?php echo esc_attr( $this->get_field_name( $args['name'] ) ); ?>"><?php echo esc_attr( $value ); ?></textarea>
4857 <?php
4858
4859 break;
4860 case "hidden":
4861 ?>
4862 <input id="<?php echo esc_attr( $this->get_field_id( $args['name'] ) ); ?>" name="<?php echo esc_attr( $this->get_field_name( $args['name'] ) ); ?>" type="hidden" value="<?php echo esc_attr( $value ); ?>">
4863 <?php
4864 break;
4865 default:
4866 echo "No input type found!"; // @todo we need to add more input types.
4867 }
4868 // after wrapper
4869 ?></p><?php
4870 }
4871
4872 public function get_widget_icon($icon = 'box-top', $title = ''){
4873 if($icon=='box-top'){
4874 return '<svg title="'.esc_attr($title).'" width="20px" height="20px" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg" fill-rule="evenodd" clip-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="1.414" role="img" aria-hidden="true" focusable="false"><rect x="2.714" y="5.492" width="1.048" height="9.017" fill="#555D66"></rect><rect x="16.265" y="5.498" width="1.023" height="9.003" fill="#555D66"></rect><rect x="5.518" y="2.186" width="8.964" height="2.482" fill="#272B2F"></rect><rect x="5.487" y="16.261" width="9.026" height="1.037" fill="#555D66"></rect></svg>';
4875 }elseif($icon=='box-right'){
4876 return '<svg title="'.esc_attr($title).'" width="20px" height="20px" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg" fill-rule="evenodd" clip-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="1.414" role="img" aria-hidden="true" focusable="false"><rect x="2.714" y="5.492" width="1.046" height="9.017" fill="#555D66"></rect><rect x="15.244" y="5.498" width="2.518" height="9.003" fill="#272B2F"></rect><rect x="5.518" y="2.719" width="8.964" height="0.954" fill="#555D66"></rect><rect x="5.487" y="16.308" width="9.026" height="0.99" fill="#555D66"></rect></svg>';
4877 }elseif($icon=='box-bottom'){
4878 return '<svg title="'.esc_attr($title).'" width="20px" height="20px" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg" fill-rule="evenodd" clip-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="1.414" role="img" aria-hidden="true" focusable="false"><rect x="2.714" y="5.492" width="1" height="9.017" fill="#555D66"></rect><rect x="16.261" y="5.498" width="1.027" height="9.003" fill="#555D66"></rect><rect x="5.518" y="2.719" width="8.964" height="0.968" fill="#555D66"></rect><rect x="5.487" y="15.28" width="9.026" height="2.499" fill="#272B2F"></rect></svg>';
4879 }elseif($icon=='box-left'){
4880 return '<svg title="'.esc_attr($title).'" width="20px" height="20px" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg" fill-rule="evenodd" clip-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="1.414" role="img" aria-hidden="true" focusable="false"><rect x="2.202" y="5.492" width="2.503" height="9.017" fill="#272B2F"></rect><rect x="16.276" y="5.498" width="1.012" height="9.003" fill="#555D66"></rect><rect x="5.518" y="2.719" width="8.964" height="0.966" fill="#555D66"></rect><rect x="5.487" y="16.303" width="9.026" height="0.995" fill="#555D66"></rect></svg>';
4881 }
4882 }
4883
4884 /**
4885 * Get the widget input description html.
4886 *
4887 * @param $args
4888 *
4889 * @return string
4890 * @todo, need to make its own tooltip script
4891 */
4892 public function widget_field_desc( $args ) {
4893
4894 $description = '';
4895 if ( isset( $args['desc'] ) && $args['desc'] ) {
4896 if ( isset( $args['desc_tip'] ) && $args['desc_tip'] ) {
4897 $description = $this->desc_tip( $args['desc'] );
4898 } else {
4899 $description = '<span class="description">' . wp_kses_post( $args['desc'] ) . '</span>';
4900 }
4901 }
4902
4903 return $description;
4904 }
4905
4906 /**
4907 * Get the widget input title html.
4908 *
4909 * @param $args
4910 *
4911 * @return string
4912 */
4913 public function widget_field_title( $args ) {
4914 $title = '';
4915
4916 if ( isset( $args['title'] ) && $args['title'] ) {
4917 if ( ! empty( $args['device_type'] ) ) {
4918 $args['title'] .= ' (' . $args['device_type'] . ')'; // Append device type to title.
4919 }
4920
4921 if ( isset( $args['icon'] ) && $args['icon'] ) {
4922 $title = self::get_widget_icon( $args['icon'], $args['title'] );
4923 } else {
4924 $title = esc_attr( $args['title'] );
4925 }
4926 }
4927
4928 return $title;
4929 }
4930
4931 /**
4932 * Get the tool tip html.
4933 *
4934 * @param $tip
4935 * @param bool $allow_html
4936 *
4937 * @return string
4938 */
4939 function desc_tip( $tip, $allow_html = false ) {
4940 if ( $allow_html ) {
4941 $tip = $this->sanitize_tooltip( $tip );
4942 } else {
4943 $tip = esc_attr( $tip );
4944 }
4945
4946 return '<span class="gd-help-tip dashicons dashicons-editor-help" title="' . $tip . '"></span>';
4947 }
4948
4949 /**
4950 * Sanitize a string destined to be a tooltip.
4951 *
4952 * @param string $var
4953 *
4954 * @return string
4955 */
4956 public function sanitize_tooltip( $var ) {
4957 return htmlspecialchars( wp_kses( html_entity_decode( $var ), array(
4958 'br' => array(),
4959 'em' => array(),
4960 'strong' => array(),
4961 'small' => array(),
4962 'span' => array(),
4963 'ul' => array(),
4964 'li' => array(),
4965 'ol' => array(),
4966 'p' => array(),
4967 ) ) );
4968 }
4969
4970 /**
4971 * Processing widget options on save
4972 *
4973 * @param array $new_instance The new options
4974 * @param array $old_instance The previous options
4975 *
4976 * @return array
4977 * @todo we should add some sanitation here.
4978 */
4979 public function update( $new_instance, $old_instance ) {
4980
4981 //save the widget
4982 $instance = array_merge( (array) $old_instance, (array) $new_instance );
4983
4984 // set widget instance
4985 $this->instance = $instance;
4986
4987 if ( empty( $this->arguments ) ) {
4988 $this->get_arguments();
4989 }
4990
4991 // check for checkboxes
4992 if ( ! empty( $this->arguments ) ) {
4993 foreach ( $this->arguments as $argument ) {
4994 if ( isset( $argument['type'] ) && $argument['type'] == 'checkbox' && ! isset( $new_instance[ $argument['name'] ] ) ) {
4995 $instance[ $argument['name'] ] = '0';
4996 }
4997 }
4998 }
4999
5000 // maybe sanitize widget title
5001 if(!empty($instance['title'])) {
5002 $instance['title'] = wp_kses_post( $instance['title'] );
5003 }
5004
5005 return $instance;
5006 }
5007
5008 /**
5009 * Checks if the current call is a ajax call to get the block content.
5010 *
5011 * This can be used in your widget to return different content as the block content.
5012 *
5013 * @return bool
5014 *@since 1.0.3
5015 */
5016 public function is_block_content_call() {
5017 $result = false;
5018 if ( wp_doing_ajax() && isset( $_REQUEST['action'] ) && $_REQUEST['action'] == 'super_duper_output_shortcode' ) {
5019 $result = true;
5020 }
5021
5022 return $result;
5023 }
5024
5025 /**
5026 * Get an instance hash that will be unique to the type and settings.
5027 *
5028 * @return string
5029 *@since 1.0.20
5030 */
5031 public function get_instance_hash(){
5032 $instance_string = $this->base_id.serialize($this->instance);
5033 return hash('crc32b',$instance_string);
5034 }
5035
5036 /**
5037 * Generate and return inline styles from CSS rules that will match the unique class of the instance.
5038 *
5039 * @param array $rules
5040 *
5041 * @return string
5042 *@since 1.0.20
5043 */
5044 public function get_instance_style($rules = array()){
5045 $css = '';
5046
5047 if(!empty($rules)){
5048 $rules = array_unique($rules);
5049 $instance_hash = $this->get_instance_hash();
5050 $css .= "<style>";
5051 foreach($rules as $rule){
5052 $css .= ".sdel-$instance_hash $rule";
5053 }
5054 $css .= "</style>";
5055 }
5056
5057 return $css;
5058 }
5059
5060 /**
5061 * Encode shortcodes tags.
5062 *
5063 * @since 1.0.28
5064 *
5065 * @param string $content Content to search for shortcode tags.
5066 *
5067 * @return string Content with shortcode tags removed.
5068 */
5069 public function encode_shortcodes( $content ) {
5070 // Avoids existing encoded tags.
5071 $trans = array(
5072 '&#91;' => '&#091;',
5073 '&#93;' => '&#093;',
5074 '&amp;#91;' => '&#091;',
5075 '&amp;#93;' => '&#093;',
5076 '&lt;' => '&0lt;',
5077 '&gt;' => '&0gt;',
5078 '&amp;lt;' => '&0lt;',
5079 '&amp;gt;' => '&0gt;',
5080 );
5081
5082 $content = strtr( $content, $trans );
5083
5084 $trans = array(
5085 '[' => '&#91;',
5086 ']' => '&#93;',
5087 '<' => '&lt;',
5088 '>' => '&gt;',
5089 '"' => '&quot;',
5090 "'" => '&#39;',
5091 );
5092
5093 $content = strtr( $content, $trans );
5094
5095 return $content;
5096 }
5097
5098 /**
5099 * Remove encoded shortcod tags.
5100 *
5101 * @since 1.0.28
5102 *
5103 * @param string $content Content to search for shortcode tags.
5104 *
5105 * @return string Content with decoded shortcode tags.
5106 */
5107 public function decode_shortcodes( $content ) {
5108 $trans = array(
5109 '&#91;' => '[',
5110 '&#93;' => ']',
5111 '&amp;#91;' => '[',
5112 '&amp;#93;' => ']',
5113 '&lt;' => '<',
5114 '&gt;' => '>',
5115 '&amp;lt;' => '<',
5116 '&amp;gt;' => '>',
5117 '&quot;' => '"',
5118 '&apos;' => "'",
5119 );
5120
5121 $content = strtr( $content, $trans );
5122
5123 $trans = array(
5124 '&#091;' => '&#91;',
5125 '&#093;' => '&#93;',
5126 '&amp;#091;' => '&#91;',
5127 '&amp;#093;' => '&#93;',
5128 '&0lt;' => '&lt;',
5129 '&0gt;' => '&gt;',
5130 '&amp;0lt;' => '&lt;',
5131 '&amp;0gt;' => '&gt;',
5132 );
5133
5134 $content = strtr( $content, $trans );
5135
5136 return $content;
5137 }
5138
5139 public function block_visibility_fields( $args ) {
5140 global $aui_bs5;
5141
5142 $value = ! empty( $args['value'] ) ? esc_attr( $args['value'] ) : '';
5143 $content = '<div class="bs-vc-rule-template d-none">';
5144 $content .= '<div class="px-3 pt-3 pb-0 mb-3 border border-1 rounded-1 position-relative bs-vc-rule" data-bs-index="BSVCINDEX" >';
5145 $content .= '<div class="row">';
5146 $content .= '<div class="col-sm-12">';
5147 $content .= '<div class="bs-rule-action position-absolute top-0 end-0 right-0 p-2 zindex-5"' . ( $aui_bs5 ? '' : ' style="top:0!important;right:0!important;z-index:5!important;"' ) . '><span class="text-danger c-pointer bs-vc-remove-rule" title="' . esc_attr__( 'Remove Rule', 'ayecode-connect' ) . '"><i class="fas fa-circle-minus fs-6"></i></span></div>';
5148 $content .= aui()->select(
5149 array(
5150 'id' => 'bsvc_rule_BSVCINDEX',
5151 'name' => 'bsvc_rule_BSVCINDEX',
5152 'label' => __( 'Rule', 'ayecode-connect' ),
5153 'placeholder' => __( 'Select Rule...', 'ayecode-connect' ),
5154 'class' => 'bsvc_rule ' . ( $aui_bs5 ? 'form-select-sm' : 'custom-select-sm' ) . ' no-select2 mw-100',
5155 'options' => sd_visibility_rules_options(),
5156 'default' => '',
5157 'value' => '',
5158 'label_type' => '',
5159 'select2' => false,
5160 'input_group_left' => __( 'Rule:', 'ayecode-connect' ),
5161 'extra_attributes' => array(
5162 'data-minimum-results-for-search' => '-1'
5163 )
5164 )
5165 );
5166
5167 $content .= '</div>';
5168
5169 if ( ! $aui_bs5 ) {
5170 $content = str_replace( 'input-group"', 'input-group input-group-sm"', $content );
5171 }
5172
5173 if ( class_exists( 'GeoDirectory' ) ) {
5174 $content .= '<div class="col-md-7 col-sm-12">';
5175
5176 $content .= aui()->select(
5177 array(
5178 'id' => 'bsvc_gd_field_BSVCINDEX',
5179 'name' => 'bsvc_gd_field_BSVCINDEX',
5180 'label' => __( 'FIELD', 'ayecode-connect' ),
5181 'placeholder' => __( 'FIELD', 'ayecode-connect' ),
5182 'class' => 'bsvc_gd_field ' . ( $aui_bs5 ? 'form-select-sm' : 'custom-select-sm' ) . ' no-select2 mw-100',
5183 'options' => sd_visibility_gd_field_options(),
5184 'default' => '',
5185 'value' => '',
5186 'label_type' => '',
5187 'select2' => false,
5188 'element_require' => '[%bsvc_rule_BSVCINDEX%]=="gd_field"',
5189 'extra_attributes' => array(
5190 'data-minimum-results-for-search' => '-1'
5191 )
5192 )
5193 );
5194
5195 $content .= '</div>';
5196 $content .= '<div class="col-md-5 col-sm-12">';
5197
5198 $content .= aui()->select(
5199 array(
5200 'id' => 'bsvc_gd_field_condition_BSVCINDEX',
5201 'name' => 'bsvc_gd_field_condition_BSVCINDEX',
5202 'label' => __( 'CONDITION', 'ayecode-connect' ),
5203 'placeholder' => __( 'CONDITION', 'ayecode-connect' ),
5204 'class' => 'bsvc_gd_field_condition ' . ( $aui_bs5 ? 'form-select-sm' : 'custom-select-sm' ) . ' no-select2 mw-100',
5205 'options' => sd_visibility_field_condition_options(),
5206 'default' => '',
5207 'value' => '',
5208 'label_type' => '',
5209 'select2' => false,
5210 'element_require' => '[%bsvc_rule_BSVCINDEX%]=="gd_field"',
5211 'extra_attributes' => array(
5212 'data-minimum-results-for-search' => '-1'
5213 )
5214 )
5215 );
5216
5217 $content .= '</div>';
5218 $content .= '<div class="col-sm-12">';
5219
5220 $content .= aui()->input(
5221 array(
5222 'type' => 'text',
5223 'id' => 'bsvc_gd_field_search_BSVCINDEX',
5224 'name' => 'bsvc_gd_field_search_BSVCINDEX',
5225 'label' => __( 'VALUE TO MATCH', 'ayecode-connect' ),
5226 'class' => 'bsvc_gd_field_search form-control-sm',
5227 'placeholder' => __( 'VALUE TO MATCH', 'ayecode-connect' ),
5228 'label_type' => '',
5229 'value' => '',
5230 'element_require' => '([%bsvc_rule_BSVCINDEX%]=="gd_field" && [%bsvc_gd_field_condition_BSVCINDEX%] && [%bsvc_gd_field_condition_BSVCINDEX%]!="is_empty" && [%bsvc_gd_field_condition_BSVCINDEX%]!="is_not_empty")'
5231 )
5232 );
5233
5234 $content .= '</div>';
5235 }
5236
5237 $content .= apply_filters( 'sd_block_visibility_fields', '', $args );
5238
5239 $content .= '</div>';
5240
5241 $content .= '<div class="row aui-conditional-field" data-element-require="jQuery(form).find(\'[name=bsvc_rule_BSVCINDEX]\').val()==\'user_roles\'" data-argument="bsvc_user_roles_BSVCINDEX_1"><label for="bsvc_user_roles_BSVCINDEX_1" class="form-label mb-3' . ( $aui_bs5 ? '' : ' ml-3 w-100' ) . '">' . __( 'Select User Roles:', 'ayecode-connect' ) . '</label>';
5242 $role_options = sd_user_roles_options();
5243
5244 $role_option_i = 0;
5245 foreach ( $role_options as $role_option_key => $role_option_name ) {
5246 $role_option_i++;
5247
5248 $content .= '<div class="col-sm-6' . ( $aui_bs5 ? '' : ' mb-2' ) . '">';
5249 $content .= aui()->input(
5250 array(
5251 'id' => 'bsvc_user_roles_BSVCINDEX_' . $role_option_i,
5252 'name' => 'bsvc_user_roles_BSVCINDEX[]',
5253 'type' => 'checkbox',
5254 'label' => $role_option_name,
5255 'label_type' => 'hidden',
5256 'class' => 'bsvc_user_roles',
5257 'value' => $role_option_key,
5258 'switch' => 'md',
5259 'no_wrap' => true
5260 )
5261 );
5262 $content .= '</div>';
5263 }
5264 $content .= '</div>';
5265 $content .= '<div class="bs-vc-sep-wrap text-center position-absolute top-0 mt-n3"' . ( $aui_bs5 ? '' : ' style="top:0!important;"' ) . '><div class="bs-vc-sep-cond d-inline-block badge text-dark bg-gray mt-1">' . esc_html__( 'AND', 'ayecode-connect' ) . '</div></div>';
5266 $content .= '</div>';
5267 $content .= '</div>';
5268 $content .= '<form id="bs-vc-modal-form" class="bs-vc-modal-form">';
5269 $content .= '<div class="bs-vc-rule-sets"></div>';
5270 $content .= '<div class="row"><div class="col-sm-12 text-center pt-1 pb-4"><button type="button" class="btn btn-sm btn-primary d-block w-100 bs-vc-add-rule"><i class="fas fa-plus"></i> ' . __( 'Add Rule', 'ayecode-connect' ) . '</button></div></div>';
5271 $content .= '<div class="row"><div class="col-md-6 col-sm-12">';
5272 $content .= aui()->select(
5273 array(
5274 'id' => 'bsvc_output',
5275 'name' => 'bsvc_output',
5276 'label' => __( 'What should happen if rules met.', 'ayecode-connect' ),
5277 'placeholder' => __( 'Show Block', 'ayecode-connect' ),
5278 'class' => 'bsvc_output ' . ( $aui_bs5 ? 'form-select-sm' : 'custom-select-sm' ) . ' no-select2 mw-100',
5279 'options' => sd_visibility_output_options(),
5280 'default' => '',
5281 'value' => '',
5282 'label_type' => 'top',
5283 'select2' => false,
5284 'extra_attributes' => array(
5285 'data-minimum-results-for-search' => '-1'
5286 )
5287 )
5288 );
5289
5290 $content .= '</div><div class="col-md-6 col-sm-12">';
5291
5292 $content .= aui()->select(
5293 array(
5294 'id' => 'bsvc_page',
5295 'name' => 'bsvc_page',
5296 'label' => __( 'Page Content', 'ayecode-connect' ),
5297 'placeholder' => __( 'Select Page ID...', 'ayecode-connect' ),
5298 'class' => 'bsvc_page ' . ( $aui_bs5 ? 'form-select-sm' : 'custom-select-sm' ) . ' no-select2 mw-100',
5299 'options' => sd_template_page_options(),
5300 'default' => '',
5301 'value' => '',
5302 'label_type' => 'top',
5303 'select2' => false,
5304 'element_require' => '[%bsvc_output%]=="page"'
5305 )
5306 );
5307
5308 $content .= aui()->select(
5309 array(
5310 'id' => 'bsvc_tmpl_part',
5311 'name' => 'bsvc_tmpl_part',
5312 'label' => __( 'Template Part', 'ayecode-connect' ),
5313 'placeholder' => __( 'Select Template Part...', 'ayecode-connect' ),
5314 'class' => 'bsvc_tmpl_part ' . ( $aui_bs5 ? 'form-select-sm' : 'custom-select-sm' ) . ' no-select2 mw-100',
5315 'options' => sd_template_part_options(),
5316 'default' => '',
5317 'value' => '',
5318 'label_type' => 'top',
5319 'select2' => false,
5320 'element_require' => '[%bsvc_output%]=="template_part"',
5321 'extra_attributes' => array(
5322 'data-minimum-results-for-search' => '-1'
5323 )
5324 )
5325 );
5326
5327 $content .= aui()->select(
5328 array(
5329 'id' => 'bsvc_message_type',
5330 'name' => 'bsvc_message_type',
5331 'label' => __( 'Custom Message Type', 'ayecode-connect' ),
5332 'placeholder' => __( 'Default (none)', 'ayecode-connect' ),
5333 'class' => 'bsvc_message_type ' . ( $aui_bs5 ? 'form-select-sm' : 'custom-select-sm' ) . ' no-select2 mw-100',
5334 'options' => sd_aui_colors(),
5335 'default' => '',
5336 'value' => '',
5337 'label_type' => 'top',
5338 'select2' => false,
5339 'element_require' => '[%bsvc_output%]=="message"',
5340 'extra_attributes' => array(
5341 'data-minimum-results-for-search' => '-1'
5342 )
5343 )
5344 );
5345
5346 $content .= '</div><div class="col-sm-12">';
5347
5348 $content .= aui()->input(
5349 array(
5350 'type' => 'text',
5351 'id' => 'bsvc_message',
5352 'name' => 'bsvc_message',
5353 'label' => '',
5354 'class' => 'bsvc_message form-control-sm mb-3',
5355 'placeholder' => __( 'CUSTOM MESSAGE TO SHOW', 'ayecode-connect' ),
5356 'label_type' => '',
5357 'value' => '',
5358 'form_group_class' => ' ',
5359 'element_require' => '[%bsvc_output%]=="message"',
5360 )
5361 );
5362
5363 $content .= '</div></div><div class="row"><div class="col col-12"><div class="pt-3 mt-1 border-top"></div></div><div class="col-md-6 col-sm-12">';
5364 $content .= aui()->select(
5365 array(
5366 'id' => 'bsvc_output_n',
5367 'name' => 'bsvc_output_n',
5368 'label' => __( 'What should happen if rules NOT met.', 'ayecode-connect' ),
5369 'placeholder' => __( 'Show Block', 'ayecode-connect' ),
5370 'class' => 'bsvc_output_n ' . ( $aui_bs5 ? 'form-select-sm' : 'custom-select-sm' ) . ' no-select2 mw-100',
5371 'options' => sd_visibility_output_options(),
5372 'default' => '',
5373 'value' => '',
5374 'label_type' => 'top',
5375 'select2' => false,
5376 'extra_attributes' => array(
5377 'data-minimum-results-for-search' => '-1'
5378 )
5379 )
5380 );
5381
5382 $content .= '</div><div class="col-md-6 col-sm-12">';
5383
5384 $content .= aui()->select(
5385 array(
5386 'id' => 'bsvc_page_n',
5387 'name' => 'bsvc_page_n',
5388 'label' => __( 'Page Content', 'ayecode-connect' ),
5389 'placeholder' => __( 'Select Page ID...', 'ayecode-connect' ),
5390 'class' => 'bsvc_page_n ' . ( $aui_bs5 ? 'form-select-sm' : 'custom-select-sm' ) . ' no-select2 mw-100',
5391 'options' => sd_template_page_options(),
5392 'default' => '',
5393 'value' => '',
5394 'label_type' => 'top',
5395 'select2' => false,
5396 'element_require' => '[%bsvc_output_n%]=="page"'
5397 )
5398 );
5399
5400 $content .= aui()->select(
5401 array(
5402 'id' => 'bsvc_tmpl_part_n',
5403 'name' => 'bsvc_tmpl_part_n',
5404 'label' => __( 'Template Part', 'ayecode-connect' ),
5405 'placeholder' => __( 'Select Template Part...', 'ayecode-connect' ),
5406 'class' => 'bsvc_tmpl_part_n ' . ( $aui_bs5 ? 'form-select-sm' : 'custom-select-sm' ) . ' no-select2 mw-100',
5407 'options' => sd_template_part_options(),
5408 'default' => '',
5409 'value' => '',
5410 'label_type' => 'top',
5411 'select2' => false,
5412 'element_require' => '[%bsvc_output_n%]=="template_part"',
5413 'extra_attributes' => array(
5414 'data-minimum-results-for-search' => '-1'
5415 )
5416 )
5417 );
5418
5419 $content .= aui()->select(
5420 array(
5421 'id' => 'bsvc_message_type_n',
5422 'name' => 'bsvc_message_type_n',
5423 'label' => __( 'Custom Message Type', 'ayecode-connect' ),
5424 'placeholder' => __( 'Default (none)', 'ayecode-connect' ),
5425 'class' => 'bsvc_message_type_n ' . ( $aui_bs5 ? 'form-select-sm' : 'custom-select-sm' ) . ' no-select2 mw-100',
5426 'options' => sd_aui_colors(),
5427 'default' => '',
5428 'value' => '',
5429 'label_type' => 'top',
5430 'select2' => false,
5431 'element_require' => '[%bsvc_output_n%]=="message"',
5432 'extra_attributes' => array(
5433 'data-minimum-results-for-search' => '-1'
5434 )
5435 )
5436 );
5437
5438 $content .= '</div><div class="col-sm-12">';
5439
5440 $content .= aui()->input(
5441 array(
5442 'type' => 'text',
5443 'id' => 'bsvc_message_n',
5444 'name' => 'bsvc_message_n',
5445 'label' => '',
5446 'class' => 'bsvc_message_n form-control-sm',
5447 'placeholder' => __( 'CUSTOM MESSAGE TO SHOW', 'ayecode-connect' ),
5448 'label_type' => '',
5449 'value' => '',
5450 'form_group_class' => ' ',
5451 'element_require' => '[%bsvc_output_n%]=="message"',
5452 )
5453 );
5454
5455 $content .= '</div></div></form><input type="hidden" id="bsvc_raw_value" name="bsvc_raw_value" value="' . $value . '">';
5456
5457 return $content;
5458 }
5459
5460 /**
5461 * Handle media_buttons hook.
5462 *
5463 * @since 1.2.7
5464 */
5465 public function wp_media_buttons() {
5466 global $shortcode_insert_button_once;
5467
5468 // Fix conflicts with UpSolution Core in header template edit element.
5469 if ( defined( 'US_CORE_DIR' ) && ! empty( $_REQUEST['action'] ) && $_REQUEST['action'] == 'us_ajax_hb_get_ebuilder_html' ) {
5470 $shortcode_insert_button_once = true;
5471 }
5472 }
5473
5474 /**
5475 * Check if supports block visibility.
5476 *
5477 * @since 1.2.28
5478 * @return bool True if site supports block visibility else False.
5479 */
5480 public function supports_block_visibility() {
5481 // FSE Theme.
5482 if ( function_exists( 'wp_is_block_theme' ) && wp_is_block_theme() ) {
5483 return true;
5484 }
5485
5486 // BlockStrap Block Builder.
5487 if ( defined( 'BLOCKSTRAP_BLOCKS_VERSION' ) ) {
5488 return true;
5489 }
5490
5491 return $this->is_gutenberg();
5492 }
5493
5494 /**
5495 * Check if Gutenberg is in use.
5496 *
5497 * @since 1.2.28
5498 * @return bool True if site uses Gutenberg else False.
5499 */
5500 public function is_gutenberg() {
5501 global $wp_version;
5502
5503 $is_gutenberg = true;
5504
5505 // If less than v5.
5506 if ( version_compare( $wp_version, '5.0.0', '<' ) ) {
5507 $is_gutenberg = false;
5508 }
5509
5510 if ( class_exists( 'Classic_Editor' ) ) {
5511 $is_gutenberg = false; // Classic Editor plugin is active.
5512 } else if ( $this->is_classicpress() ) {
5513 $is_gutenberg = false; // Site is using ClassicPress.
5514 }
5515
5516 return $is_gutenberg;
5517 }
5518
5519 /**
5520 * Check if ClassicPress is in use.
5521 *
5522 * @since 1.2.29
5523 * @return bool True if site uses ClassicPress else False.
5524 */
5525 public function is_classicpress() {
5526 if ( function_exists( 'classicpress_version' ) ) {
5527 $is_classicpress = true;
5528 } else {
5529 $is_classicpress = false;
5530 }
5531
5532 return $is_classicpress;
5533 }
5534 }
5535 }
5536