1
|
|
|
<?php |
2
|
|
|
if ( ! defined( 'ABSPATH' ) ) { |
3
|
|
|
exit; |
4
|
|
|
} |
5
|
|
|
|
6
|
|
|
if ( ! class_exists( 'WP_Super_Duper' ) ) { |
7
|
|
|
|
8
|
|
|
|
9
|
|
|
/** |
10
|
|
|
* A Class to be able to create a Widget, Shortcode or Block to be able to output content for WordPress. |
11
|
|
|
* |
12
|
|
|
* Should not be called direct but extended instead. |
13
|
|
|
* |
14
|
|
|
* Class WP_Super_Duper |
15
|
|
|
* @since 1.0.3 is_block_content_call() method added. |
16
|
|
|
* @since 1.0.3 Placeholder text will be shown for widget that return no block content. |
17
|
|
|
* @since 1.0.4 is_elementor_widget_output() method added. |
18
|
|
|
* @since 1.0.4 is_elementor_preview() method added. |
19
|
|
|
* @since 1.0.5 Block checkbox options are set as true by default even when set as false - FIXED |
20
|
|
|
* @since 1.0.6 Some refactoring for page builders - CHANGED |
21
|
|
|
* @since 1.0.7 Some refactoring for page builders - CHANGED |
22
|
|
|
* @since 1.0.8 Some refactoring for page builders ( cornerstone builder now supported ) - CHANGED |
23
|
|
|
* @since 1.0.9 Numbers saving as strings and not numbers which can cause block render issues on refresh - FIXED |
24
|
|
|
* @since 1.0.10 Some refactoring for page builders ( Avia builder for Enfold theme now supported ) - CHANGED |
25
|
|
|
* @ver 1.0.10 |
26
|
|
|
*/ |
27
|
|
|
class WP_Super_Duper extends WP_Widget { |
28
|
|
|
|
29
|
|
|
public $version = "1.0.10"; |
30
|
|
|
public $block_code; |
31
|
|
|
public $options; |
32
|
|
|
public $base_id; |
33
|
|
|
public $arguments = array(); |
34
|
|
|
public $instance = array(); |
35
|
|
|
private $class_name; |
36
|
|
|
|
37
|
|
|
/** |
38
|
|
|
* Take the array options and use them to build. |
39
|
|
|
*/ |
40
|
|
|
public function __construct( $options ) { |
41
|
|
|
global $sd_widgets; |
42
|
|
|
|
43
|
|
|
$sd_widgets[ $options['base_id'] ] = array( |
44
|
|
|
'name' => $options['name'], |
45
|
|
|
'class_name' => $options['class_name'] |
46
|
|
|
); |
47
|
|
|
$this->base_id = $options['base_id']; |
48
|
|
|
// lets filter the options before we do anything |
49
|
|
|
$options = apply_filters( "wp_super_duper_options", $options ); |
50
|
|
|
$options = apply_filters( "wp_super_duper_options_{$this->base_id}", $options ); |
51
|
|
|
$options = $this->add_name_from_key( $options ); |
52
|
|
|
$this->options = $options; |
53
|
|
|
|
54
|
|
|
$this->base_id = $options['base_id']; |
55
|
|
|
$this->arguments = isset( $options['arguments'] ) ? $options['arguments'] : array(); |
56
|
|
|
|
57
|
|
|
// init parent |
58
|
|
|
parent::__construct( $options['base_id'], $options['name'], $options['widget_ops'] ); |
59
|
|
|
|
60
|
|
|
if ( isset( $options['class_name'] ) ) { |
61
|
|
|
// register widget |
62
|
|
|
$this->class_name = $options['class_name']; |
63
|
|
|
|
64
|
|
|
// register shortcode |
65
|
|
|
$this->register_shortcode(); |
66
|
|
|
|
67
|
|
|
// register block |
68
|
|
|
add_action( 'admin_enqueue_scripts', array( $this, 'register_block' ) ); |
69
|
|
|
} |
70
|
|
|
|
71
|
|
|
// add the CSS and JS we need ONCE |
72
|
|
|
global $sd_widget_scripts; |
73
|
|
|
|
74
|
|
|
if ( ! $sd_widget_scripts ) { |
75
|
|
|
wp_add_inline_script( 'admin-widgets', $this->widget_js() ); |
76
|
|
|
wp_add_inline_script( 'customize-controls', $this->widget_js() ); |
77
|
|
|
wp_add_inline_style( 'widgets', $this->widget_css() ); |
78
|
|
|
|
79
|
|
|
$sd_widget_scripts = true; |
80
|
|
|
|
81
|
|
|
// add shortcode insert button once |
82
|
|
|
add_action( 'media_buttons', array( $this, 'shortcode_insert_button' ) ); |
83
|
|
|
if ( $this->is_preview() ) { |
84
|
|
|
add_action( 'wp_footer', array( $this, 'shortcode_insert_button_script' ) ); |
85
|
|
|
// this makes the insert button work for elementor |
86
|
|
|
add_action( 'elementor/editor/after_enqueue_scripts', array( |
87
|
|
|
$this, |
88
|
|
|
'shortcode_insert_button_script' |
89
|
|
|
) ); // for elementor |
90
|
|
|
} |
91
|
|
|
// this makes the insert button work for cornerstone |
92
|
|
|
add_action( 'cornerstone_load_builder', array( |
93
|
|
|
$this, |
94
|
|
|
'shortcode_insert_button_script' |
95
|
|
|
) ); // for cornerstone builder (this is the preview) |
96
|
|
|
|
97
|
|
|
add_action( 'wp_ajax_super_duper_get_widget_settings', array( __CLASS__, 'get_widget_settings' ) ); |
98
|
|
|
add_action( 'wp_ajax_super_duper_get_picker', array( __CLASS__, 'get_picker' ) ); |
99
|
|
|
|
100
|
|
|
// add generator text to admin head |
101
|
|
|
add_action( 'admin_head', array( $this, 'generator' ) ); |
102
|
|
|
} |
103
|
|
|
|
104
|
|
|
do_action( 'wp_super_duper_widget_init', $options, $this ); |
105
|
|
|
} |
106
|
|
|
|
107
|
|
|
/** |
108
|
|
|
* A function to ge the shortcode builder picker html. |
109
|
|
|
* |
110
|
|
|
* @param string $editor_id |
111
|
|
|
* |
112
|
|
|
* @return string |
113
|
|
|
*/ |
114
|
|
|
public static function get_picker( $editor_id = '' ) { |
115
|
|
|
|
116
|
|
|
ob_start(); |
117
|
|
|
if ( isset( $_POST['editor_id'] ) ) { |
118
|
|
|
$editor_id = esc_attr( $_POST['editor_id'] ); |
119
|
|
|
} elseif ( isset( $_REQUEST['et_fb'] ) ) { |
120
|
|
|
$editor_id = 'main_content_content_vb_tiny_mce'; |
121
|
|
|
} |
122
|
|
|
|
123
|
|
|
global $sd_widgets; |
124
|
|
|
?> |
125
|
|
|
|
126
|
|
|
<div class="sd-shortcode-left-wrap"> |
127
|
|
|
<?php |
128
|
|
|
asort( $sd_widgets ); |
129
|
|
|
if ( ! empty( $sd_widgets ) ) { |
130
|
|
|
echo '<select class="widefat" onchange="sd_get_shortcode_options(this);">'; |
131
|
|
|
echo "<option>" . __( 'Select shortcode' ) . "</option>"; |
132
|
|
|
foreach ( $sd_widgets as $shortcode => $class ) { |
133
|
|
|
echo "<option value='" . esc_attr( $shortcode ) . "'>" . esc_attr( $shortcode ) . " (" . esc_attr( $class['name'] ) . ")</option>"; |
134
|
|
|
} |
135
|
|
|
echo "</select>"; |
136
|
|
|
|
137
|
|
|
} |
138
|
|
|
?> |
139
|
|
|
<div class="sd-shortcode-settings"></div> |
140
|
|
|
|
141
|
|
|
</div> |
142
|
|
|
|
143
|
|
|
<div class="sd-shortcode-right-wrap"> |
144
|
|
|
<textarea id='sd-shortcode-output' disabled></textarea> |
145
|
|
|
<div id='sd-shortcode-output-actions'> |
146
|
|
|
<?php if ( $editor_id != '' ) { ?> |
147
|
|
|
<button class="button sd-insert-shortcode-button" |
148
|
|
|
onclick="sd_insert_shortcode(<?php if ( ! empty( $editor_id ) ) { |
149
|
|
|
echo "'" . $editor_id . "'"; |
150
|
|
|
} ?>)"><?php _e( 'Insert shortcode' ); ?></button> |
151
|
|
|
<?php } ?> |
152
|
|
|
<button class="button" |
153
|
|
|
onclick="sd_copy_to_clipboard()"><?php _e( 'Copy shortcode' ); ?></button> |
154
|
|
|
</div> |
155
|
|
|
</div> |
156
|
|
|
<?php |
157
|
|
|
|
158
|
|
|
$html = ob_get_clean(); |
159
|
|
|
|
160
|
|
|
if ( wp_doing_ajax() ) { |
161
|
|
|
echo $html; |
162
|
|
|
$should_die = true; |
163
|
|
|
|
164
|
|
|
// some builder get the editor via ajax so we should not die on those ocasions |
165
|
|
|
$dont_die = array( |
166
|
|
|
'parent_tag',// WP Bakery |
167
|
|
|
'avia_request' // enfold |
168
|
|
|
); |
169
|
|
|
|
170
|
|
|
foreach ( $dont_die as $request ) { |
171
|
|
|
if ( isset( $_REQUEST[ $request ] ) ) { |
172
|
|
|
$should_die = false; |
173
|
|
|
} |
174
|
|
|
} |
175
|
|
|
|
176
|
|
|
if ( $should_die ) { |
177
|
|
|
wp_die(); |
178
|
|
|
} |
179
|
|
|
|
180
|
|
|
} else { |
181
|
|
|
return $html; |
182
|
|
|
} |
183
|
|
|
|
184
|
|
|
return ''; |
185
|
|
|
|
186
|
|
|
} |
187
|
|
|
|
188
|
|
|
/** |
189
|
|
|
* Output the version in the admin header. |
190
|
|
|
*/ |
191
|
|
|
public function generator() { |
192
|
|
|
echo '<meta name="generator" content="WP Super Duper v' . $this->version . '" />'; |
193
|
|
|
} |
194
|
|
|
|
195
|
|
|
/** |
196
|
|
|
* Get widget settings. |
197
|
|
|
* |
198
|
|
|
* @since 1.0.0 |
199
|
|
|
*/ |
200
|
|
|
public static function get_widget_settings() { |
201
|
|
|
global $sd_widgets; |
202
|
|
|
|
203
|
|
|
$shortcode = isset( $_REQUEST['shortcode'] ) && $_REQUEST['shortcode'] ? sanitize_title_with_dashes( $_REQUEST['shortcode'] ) : ''; |
204
|
|
|
if ( ! $shortcode ) { |
205
|
|
|
wp_die(); |
206
|
|
|
} |
207
|
|
|
$widget_args = isset( $sd_widgets[ $shortcode ] ) ? $sd_widgets[ $shortcode ] : ''; |
208
|
|
|
if ( ! $widget_args ) { |
209
|
|
|
wp_die(); |
210
|
|
|
} |
211
|
|
|
$class_name = isset( $widget_args['class_name'] ) && $widget_args['class_name'] ? $widget_args['class_name'] : ''; |
212
|
|
|
if ( ! $class_name ) { |
213
|
|
|
wp_die(); |
214
|
|
|
} |
215
|
|
|
|
216
|
|
|
// invoke an instance method |
217
|
|
|
$widget = new $class_name; |
218
|
|
|
|
219
|
|
|
ob_start(); |
220
|
|
|
$widget->form( array() ); |
221
|
|
|
$form = ob_get_clean(); |
222
|
|
|
echo "<form id='$shortcode'>" . $form . "<div class=\"widget-control-save\"></div></form>"; |
223
|
|
|
echo "<style>" . $widget->widget_css() . "</style>"; |
224
|
|
|
echo "<script>" . $widget->widget_js() . "</script>"; |
225
|
|
|
?> |
226
|
|
|
<?php |
227
|
|
|
wp_die(); |
228
|
|
|
} |
229
|
|
|
|
230
|
|
|
/** |
231
|
|
|
* Insert shortcode builder button to classic editor (not inside Gutenberg, not needed). |
232
|
|
|
* |
233
|
|
|
* @since 1.0.0 |
234
|
|
|
* |
235
|
|
|
* @param string $editor_id Optional. Shortcode editor id. Default null. |
236
|
|
|
* @param string $insert_shortcode_function Optional. Insert shotcode function. Default null. |
237
|
|
|
*/ |
238
|
|
|
public static function shortcode_insert_button( $editor_id = '', $insert_shortcode_function = '' ) { |
239
|
|
|
global $sd_widgets, $shortcode_insert_button_once; |
240
|
|
|
if ( $shortcode_insert_button_once ) { |
241
|
|
|
return; |
242
|
|
|
} |
243
|
|
|
add_thickbox(); |
244
|
|
|
|
245
|
|
|
|
246
|
|
|
/** |
247
|
|
|
* Cornerstone makes us play dirty tricks :/ |
248
|
|
|
* 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. |
249
|
|
|
*/ |
250
|
|
|
if ( function_exists( 'cornerstone_plugin_init' ) && ! is_admin() ) { |
251
|
|
|
echo '<span id="insert-media-button">'; |
252
|
|
|
} |
253
|
|
|
|
254
|
|
|
echo self::shortcode_button( 'this', 'true' ); |
255
|
|
|
|
256
|
|
|
// see opening note |
257
|
|
|
if ( function_exists( 'cornerstone_plugin_init' ) && ! is_admin() ) { |
258
|
|
|
echo '</span>'; // end #insert-media-button |
259
|
|
|
} |
260
|
|
|
|
261
|
|
|
self::shortcode_insert_button_script( $editor_id, $insert_shortcode_function ); |
262
|
|
|
$shortcode_insert_button_once = true; |
263
|
|
|
} |
264
|
|
|
|
265
|
|
|
/** |
266
|
|
|
* Gets the shortcode insert button html. |
267
|
|
|
* |
268
|
|
|
* @param string $id |
269
|
|
|
* @param string $search_for_id |
270
|
|
|
* |
271
|
|
|
* @return mixed |
272
|
|
|
*/ |
273
|
|
|
public static function shortcode_button( $id = '', $search_for_id = '' ) { |
274
|
|
|
ob_start(); |
275
|
|
|
?> |
276
|
|
|
<span class="sd-lable-shortcode-inserter"> |
277
|
|
|
<a onclick="sd_ajax_get_picker(<?php echo $id; |
278
|
|
|
if ( $search_for_id ) { |
279
|
|
|
echo "," . $search_for_id; |
280
|
|
|
} ?>);" href="#TB_inline?width=100%&height=550&inlineId=super-duper-content-ajaxed" |
281
|
|
|
class="thickbox button super-duper-content-open" title="Add Shortcode"> |
282
|
|
|
<span style="vertical-align: middle;line-height: 18px;font-size: 20px;" |
283
|
|
|
class="dashicons dashicons-screenoptions"></span> |
284
|
|
|
</a> |
285
|
|
|
<div id="super-duper-content-ajaxed" style="display:none;"> |
286
|
|
|
<span>Loading</span> |
287
|
|
|
</div> |
288
|
|
|
</span> |
289
|
|
|
|
290
|
|
|
<?php |
291
|
|
|
$html = ob_get_clean(); |
292
|
|
|
|
293
|
|
|
// remove line breaks so we can use it in js |
294
|
|
|
return preg_replace( "/\r|\n/", "", trim( $html ) ); |
295
|
|
|
} |
296
|
|
|
|
297
|
|
|
/** |
298
|
|
|
* Makes SD work with the siteOrigin page builder. |
299
|
|
|
* |
300
|
|
|
* @since 1.0.6 |
301
|
|
|
* @return mixed |
302
|
|
|
*/ |
303
|
|
View Code Duplication |
public static function siteorigin_js() { |
|
|
|
|
304
|
|
|
ob_start(); |
305
|
|
|
?> |
306
|
|
|
<script> |
307
|
|
|
/** |
308
|
|
|
* Check a form to see what items shoudl be shown or hidden. |
309
|
|
|
*/ |
310
|
|
|
function sd_so_show_hide(form) { |
311
|
|
|
jQuery(form).find(".sd-argument").each(function () { |
312
|
|
|
|
313
|
|
|
var $element_require = jQuery(this).data('element_require'); |
314
|
|
|
|
315
|
|
|
if ($element_require) { |
316
|
|
|
|
317
|
|
|
$element_require = $element_require.replace("'", "'"); // replace single quotes |
318
|
|
|
$element_require = $element_require.replace(""", '"'); // replace double quotes |
319
|
|
|
|
320
|
|
|
if (eval($element_require)) { |
321
|
|
|
jQuery(this).removeClass('sd-require-hide'); |
322
|
|
|
} else { |
323
|
|
|
jQuery(this).addClass('sd-require-hide'); |
324
|
|
|
} |
325
|
|
|
} |
326
|
|
|
}); |
327
|
|
|
} |
328
|
|
|
|
329
|
|
|
/** |
330
|
|
|
* Toggle advanced settings visibility. |
331
|
|
|
*/ |
332
|
|
|
function sd_so_toggle_advanced($this) { |
333
|
|
|
var form = jQuery($this).parents('form,.form,.so-content'); |
334
|
|
|
form.find('.sd-advanced-setting').toggleClass('sd-adv-show'); |
335
|
|
|
return false;// prevent form submit |
336
|
|
|
} |
337
|
|
|
|
338
|
|
|
/** |
339
|
|
|
* Initialise a individual widget. |
340
|
|
|
*/ |
341
|
|
|
function sd_so_init_widget($this, $selector) { |
342
|
|
|
if (!$selector) { |
343
|
|
|
$selector = 'form'; |
344
|
|
|
} |
345
|
|
|
// only run once. |
346
|
|
|
if (jQuery($this).data('sd-widget-enabled')) { |
347
|
|
|
return; |
348
|
|
|
} else { |
349
|
|
|
jQuery($this).data('sd-widget-enabled', true); |
350
|
|
|
} |
351
|
|
|
|
352
|
|
|
var $button = '<button title="<?php _e( 'Advanced Settings' );?>" 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>'; |
353
|
|
|
var form = jQuery($this).parents('' + $selector + ''); |
354
|
|
|
|
355
|
|
|
if (jQuery($this).val() == '1' && jQuery(form).find('.sd-advanced-button').length == 0) { |
356
|
|
|
jQuery(form).append($button); |
357
|
|
|
} |
358
|
|
|
|
359
|
|
|
// show hide on form change |
360
|
|
|
jQuery(form).change(function () { |
361
|
|
|
sd_so_show_hide(form); |
362
|
|
|
}); |
363
|
|
|
|
364
|
|
|
// show hide on load |
365
|
|
|
sd_so_show_hide(form); |
366
|
|
|
} |
367
|
|
|
|
368
|
|
|
jQuery(function () { |
369
|
|
|
jQuery(document).on('open_dialog', function (w, e) { |
370
|
|
|
setTimeout(function () { |
371
|
|
|
if (jQuery('.so-panels-dialog-wrapper:visible .so-content.panel-dialog .sd-show-advanced').length) { |
372
|
|
|
console.log('exists'); |
373
|
|
|
if (jQuery('.so-panels-dialog-wrapper:visible .so-content.panel-dialog .sd-show-advanced').val() == '1') { |
374
|
|
|
console.log('true'); |
375
|
|
|
sd_so_init_widget('.so-panels-dialog-wrapper:visible .so-content.panel-dialog .sd-show-advanced', 'div'); |
376
|
|
|
} |
377
|
|
|
} |
378
|
|
|
}, 200); |
379
|
|
|
}); |
380
|
|
|
}); |
381
|
|
|
</script> |
382
|
|
|
<?php |
383
|
|
|
$output = ob_get_clean(); |
384
|
|
|
|
385
|
|
|
/* |
386
|
|
|
* We only add the <script> tags for code highlighting, so we strip them from the output. |
387
|
|
|
*/ |
388
|
|
|
|
389
|
|
|
return str_replace( array( |
390
|
|
|
'<script>', |
391
|
|
|
'</script>' |
392
|
|
|
), '', $output ); |
393
|
|
|
} |
394
|
|
|
|
395
|
|
|
/** |
396
|
|
|
* Output the JS and CSS for the shortcode insert button. |
397
|
|
|
* |
398
|
|
|
* @since 1.0.6 |
399
|
|
|
* |
400
|
|
|
* @param string $editor_id |
401
|
|
|
* @param string $insert_shortcode_function |
402
|
|
|
*/ |
403
|
|
|
public static function shortcode_insert_button_script( $editor_id = '', $insert_shortcode_function = '' ) { |
404
|
|
|
?> |
405
|
|
|
<style> |
406
|
|
|
.sd-shortcode-left-wrap { |
407
|
|
|
float: left; |
408
|
|
|
width: 60%; |
409
|
|
|
} |
410
|
|
|
|
411
|
|
|
.sd-shortcode-left-wrap .gd-help-tip { |
412
|
|
|
float: none; |
413
|
|
|
} |
414
|
|
|
|
415
|
|
|
.sd-shortcode-left-wrap .widefat { |
416
|
|
|
border-spacing: 0; |
417
|
|
|
width: 100%; |
418
|
|
|
clear: both; |
419
|
|
|
margin: 0; |
420
|
|
|
border: 1px solid #ddd; |
421
|
|
|
box-shadow: inset 0 1px 2px rgba(0, 0, 0, .07); |
422
|
|
|
background-color: #fff; |
423
|
|
|
color: #32373c; |
424
|
|
|
outline: 0; |
425
|
|
|
transition: 50ms border-color ease-in-out; |
426
|
|
|
padding: 3px 5px; |
427
|
|
|
} |
428
|
|
|
|
429
|
|
|
.sd-shortcode-left-wrap input[type=checkbox].widefat { |
430
|
|
|
border: 1px solid #b4b9be; |
431
|
|
|
background: #fff; |
432
|
|
|
color: #555; |
433
|
|
|
clear: none; |
434
|
|
|
cursor: pointer; |
435
|
|
|
display: inline-block; |
436
|
|
|
line-height: 0; |
437
|
|
|
height: 16px; |
438
|
|
|
margin: -4px 4px 0 0; |
439
|
|
|
margin-top: 0; |
440
|
|
|
outline: 0; |
441
|
|
|
padding: 0 !important; |
442
|
|
|
text-align: center; |
443
|
|
|
vertical-align: middle; |
444
|
|
|
width: 16px; |
445
|
|
|
min-width: 16px; |
446
|
|
|
-webkit-appearance: none; |
447
|
|
|
box-shadow: inset 0 1px 2px rgba(0, 0, 0, .1); |
448
|
|
|
transition: .05s border-color ease-in-out; |
449
|
|
|
} |
450
|
|
|
|
451
|
|
|
.sd-shortcode-left-wrap input[type=checkbox]:checked:before { |
452
|
|
|
content: "\f147"; |
453
|
|
|
margin: -3px 0 0 -4px; |
454
|
|
|
color: #1e8cbe; |
455
|
|
|
float: left; |
456
|
|
|
display: inline-block; |
457
|
|
|
vertical-align: middle; |
458
|
|
|
width: 16px; |
459
|
|
|
font: normal 21px/1 dashicons; |
460
|
|
|
speak: none; |
461
|
|
|
-webkit-font-smoothing: antialiased; |
462
|
|
|
-moz-osx-font-smoothing: grayscale; |
463
|
|
|
} |
464
|
|
|
|
465
|
|
|
#sd-shortcode-output-actions button, |
466
|
|
|
.sd-advanced-button { |
467
|
|
|
color: #555; |
468
|
|
|
border-color: #ccc; |
469
|
|
|
background: #f7f7f7; |
470
|
|
|
box-shadow: 0 1px 0 #ccc; |
471
|
|
|
vertical-align: top; |
472
|
|
|
display: inline-block; |
473
|
|
|
text-decoration: none; |
474
|
|
|
font-size: 13px; |
475
|
|
|
line-height: 26px; |
476
|
|
|
height: 28px; |
477
|
|
|
margin: 0; |
478
|
|
|
padding: 0 10px 1px; |
479
|
|
|
cursor: pointer; |
480
|
|
|
border-width: 1px; |
481
|
|
|
border-style: solid; |
482
|
|
|
-webkit-appearance: none; |
483
|
|
|
border-radius: 3px; |
484
|
|
|
white-space: nowrap; |
485
|
|
|
box-sizing: border-box; |
486
|
|
|
} |
487
|
|
|
|
488
|
|
|
button.sd-advanced-button { |
489
|
|
|
background: #0073aa; |
490
|
|
|
border-color: #006799; |
491
|
|
|
box-shadow: inset 0 2px 0 #006799; |
492
|
|
|
vertical-align: top; |
493
|
|
|
color: #fff; |
494
|
|
|
text-decoration: none; |
495
|
|
|
text-shadow: 0 -1px 1px #006799, 1px 0 1px #006799, 0 1px 1px #006799, -1px 0 1px #006799; |
496
|
|
|
float: right; |
497
|
|
|
margin-right: 3px !important; |
498
|
|
|
font-size: 20px !important; |
499
|
|
|
} |
500
|
|
|
|
501
|
|
|
.sd-shortcode-right-wrap { |
502
|
|
|
float: right; |
503
|
|
|
width: 35%; |
504
|
|
|
} |
505
|
|
|
|
506
|
|
|
#sd-shortcode-output { |
507
|
|
|
background: rgba(255, 255, 255, .5); |
508
|
|
|
border-color: rgba(222, 222, 222, .75); |
509
|
|
|
box-shadow: inset 0 1px 2px rgba(0, 0, 0, .04); |
510
|
|
|
color: rgba(51, 51, 51, .5); |
511
|
|
|
overflow: auto; |
512
|
|
|
padding: 2px 6px; |
513
|
|
|
line-height: 1.4; |
514
|
|
|
resize: vertical; |
515
|
|
|
} |
516
|
|
|
|
517
|
|
|
#sd-shortcode-output { |
518
|
|
|
height: 250px; |
519
|
|
|
width: 100%; |
520
|
|
|
} |
521
|
|
|
</style> |
522
|
|
|
<?php |
523
|
|
|
if ( class_exists( 'SiteOrigin_Panels' ) ) { |
524
|
|
|
echo "<script>" . self::siteorigin_js() . "</script>"; |
525
|
|
|
} |
526
|
|
|
?> |
527
|
|
|
<script> |
528
|
|
|
<?php |
529
|
|
|
if(! empty( $insert_shortcode_function )){ |
530
|
|
|
echo $insert_shortcode_function; |
531
|
|
|
}else{ |
532
|
|
|
|
533
|
|
|
/** |
534
|
|
|
* Function for super duper insert shortcode. |
535
|
|
|
* |
536
|
|
|
* @since 1.0.0 |
537
|
|
|
*/ |
538
|
|
|
?> |
539
|
|
|
function sd_insert_shortcode($editor_id) { |
540
|
|
|
$shortcode = jQuery('#TB_ajaxContent #sd-shortcode-output').val(); |
541
|
|
|
if ($shortcode) { |
542
|
|
|
|
543
|
|
|
if (!$editor_id) { |
544
|
|
|
|
545
|
|
|
<?php |
546
|
|
|
if ( isset( $_REQUEST['et_fb'] ) ) { |
547
|
|
|
echo '$editor_id = "#main_content_content_vb_tiny_mce";'; |
548
|
|
|
} elseif ( isset( $_REQUEST['action'] ) && $_REQUEST['action'] == 'elementor' ) { |
549
|
|
|
echo '$editor_id = "#elementor-controls .wp-editor-container textarea";'; |
550
|
|
|
} else { |
551
|
|
|
echo '$editor_id = "#wp-content-editor-container textarea";'; |
552
|
|
|
} |
553
|
|
|
?> |
554
|
|
|
} else { |
555
|
|
|
$editor_id = '#' + $editor_id; |
556
|
|
|
} |
557
|
|
|
|
558
|
|
|
if (tinyMCE && tinyMCE.activeEditor && jQuery($editor_id).attr("aria-hidden") == "true") { |
559
|
|
|
tinyMCE.execCommand('mceInsertContent', false, $shortcode); |
560
|
|
|
} else { |
561
|
|
|
var $txt = jQuery($editor_id); |
562
|
|
|
var caretPos = $txt[0].selectionStart; |
563
|
|
|
var textAreaTxt = $txt.val(); |
564
|
|
|
var txtToAdd = $shortcode; |
565
|
|
|
var textareaValue = textAreaTxt.substring(0, caretPos) + txtToAdd + textAreaTxt.substring(caretPos); |
566
|
|
|
$txt.focus().val(textareaValue).change().keydown().blur().keyup().keypress().trigger('input').trigger('change'); |
567
|
|
|
|
568
|
|
|
// set Divi react input value |
569
|
|
|
var input = document.getElementById("main_content_content_vb_tiny_mce"); |
570
|
|
|
if (input) { |
571
|
|
|
sd_setNativeValue(input, textareaValue); |
572
|
|
|
} |
573
|
|
|
|
574
|
|
|
} |
575
|
|
|
tb_remove(); |
576
|
|
|
} |
577
|
|
|
} |
578
|
|
|
|
579
|
|
|
/* |
580
|
|
|
Set the value of elements controled via react. |
581
|
|
|
*/ |
582
|
|
|
function sd_setNativeValue(element, value) { |
583
|
|
|
let lastValue = element.value; |
584
|
|
|
element.value = value; |
585
|
|
|
let event = new Event("input", {target: element, bubbles: true}); |
586
|
|
|
// React 15 |
587
|
|
|
event.simulated = true; |
588
|
|
|
// React 16 |
589
|
|
|
let tracker = element._valueTracker; |
590
|
|
|
if (tracker) { |
591
|
|
|
tracker.setValue(lastValue); |
592
|
|
|
} |
593
|
|
|
element.dispatchEvent(event); |
594
|
|
|
} |
595
|
|
|
<?php }?> |
596
|
|
|
|
597
|
|
|
/* |
598
|
|
|
Copies the shortcode to the clipboard. |
599
|
|
|
*/ |
600
|
|
|
function sd_copy_to_clipboard() { |
601
|
|
|
/* Get the text field */ |
602
|
|
|
var copyText = document.querySelector("#TB_ajaxContent #sd-shortcode-output"); |
603
|
|
|
//un-disable the field |
604
|
|
|
copyText.disabled = false; |
605
|
|
|
/* Select the text field */ |
606
|
|
|
copyText.select(); |
607
|
|
|
/* Copy the text inside the text field */ |
608
|
|
|
document.execCommand("Copy"); |
609
|
|
|
//re-disable the field |
610
|
|
|
copyText.disabled = true; |
611
|
|
|
/* Alert the copied text */ |
612
|
|
|
alert("Copied the text: " + copyText.value); |
613
|
|
|
} |
614
|
|
|
|
615
|
|
|
/* |
616
|
|
|
Gets the shortcode options. |
617
|
|
|
*/ |
618
|
|
|
function sd_get_shortcode_options($this) { |
619
|
|
|
|
620
|
|
|
$short_code = jQuery($this).val(); |
621
|
|
|
if ($short_code) { |
622
|
|
|
|
623
|
|
|
var data = { |
624
|
|
|
'action': 'super_duper_get_widget_settings', |
625
|
|
|
'shortcode': $short_code, |
626
|
|
|
'attributes': 123, |
627
|
|
|
'post_id': 321, |
628
|
|
|
'_ajax_nonce': '<?php echo wp_create_nonce( 'super_duper_output_shortcode' );?>' |
629
|
|
|
}; |
630
|
|
|
|
631
|
|
|
if (typeof ajaxurl === 'undefined') { |
632
|
|
|
var ajaxurl = "<?php echo admin_url( 'admin-ajax.php' );?>"; |
633
|
|
|
} |
634
|
|
|
|
635
|
|
|
jQuery.post(ajaxurl, data, function (response) { |
636
|
|
|
jQuery('#TB_ajaxContent .sd-shortcode-settings').html(response); |
637
|
|
|
|
638
|
|
|
jQuery('#' + $short_code).on('change', 'select', function () { |
639
|
|
|
sd_build_shortcode($short_code); |
640
|
|
|
}); // take care of select tags |
641
|
|
|
|
642
|
|
|
jQuery('#' + $short_code).on('change keypress keyup', 'input', function () { |
643
|
|
|
sd_build_shortcode($short_code); |
644
|
|
|
}); |
645
|
|
|
|
646
|
|
|
sd_build_shortcode($short_code); |
647
|
|
|
|
648
|
|
|
// resize the window to fit |
649
|
|
|
setTimeout(function () { |
650
|
|
|
jQuery('#TB_ajaxContent').css('width', 'auto').css('height', '75vh'); |
651
|
|
|
}, 200); |
652
|
|
|
|
653
|
|
|
|
654
|
|
|
return response; |
655
|
|
|
}); |
656
|
|
|
} |
657
|
|
|
|
658
|
|
|
} |
659
|
|
|
|
660
|
|
|
/* |
661
|
|
|
Builds and inserts the shortcode into the viewer. |
662
|
|
|
*/ |
663
|
|
|
function sd_build_shortcode($id) { |
664
|
|
|
|
665
|
|
|
var multiSelects = {}; |
666
|
|
|
var multiSelectsRemove = []; |
667
|
|
|
|
668
|
|
|
$output = "[" + $id; |
669
|
|
|
|
670
|
|
|
$form_data = jQuery("#" + $id).serializeArray(); |
671
|
|
|
|
672
|
|
|
// run checks for multiselects |
673
|
|
|
jQuery.each($form_data, function (index, element) { |
674
|
|
|
if (element && element.value) { |
675
|
|
|
$field_name = element.name.substr(element.name.indexOf("][") + 2); |
676
|
|
|
$field_name = $field_name.replace("]", ""); |
677
|
|
|
// check if its a multiple |
678
|
|
|
if ($field_name.includes("[]")) { |
679
|
|
|
multiSelectsRemove[multiSelectsRemove.length] = index; |
680
|
|
|
$field_name = $field_name.replace("[]", ""); |
681
|
|
|
if ($field_name in multiSelects) { |
682
|
|
|
multiSelects[$field_name] = multiSelects[$field_name] + "," + element.value; |
683
|
|
|
} else { |
684
|
|
|
multiSelects[$field_name] = element.value; |
685
|
|
|
} |
686
|
|
|
} |
687
|
|
|
} |
688
|
|
|
}); |
689
|
|
|
|
690
|
|
|
// fix multiselects if any are found |
691
|
|
|
if (multiSelectsRemove.length) { |
692
|
|
|
|
693
|
|
|
// remove all multiselects |
694
|
|
|
multiSelectsRemove.reverse(); |
695
|
|
|
multiSelectsRemove.forEach(function (index) { |
696
|
|
|
$form_data.splice(index, 1); |
697
|
|
|
}); |
698
|
|
|
|
699
|
|
|
$ms_arr = []; |
700
|
|
|
// add multiselets back |
701
|
|
|
jQuery.each(multiSelects, function (index, value) { |
702
|
|
|
$ms_arr[$ms_arr.length] = {"name": "[][" + index + "]", "value": value}; |
703
|
|
|
}); |
704
|
|
|
$form_data = $form_data.concat($ms_arr); |
705
|
|
|
} |
706
|
|
|
|
707
|
|
|
|
708
|
|
|
if ($form_data) { |
709
|
|
|
$form_data.forEach(function (element) { |
710
|
|
|
|
711
|
|
|
if (element.value) { |
712
|
|
|
$field_name = element.name.substr(element.name.indexOf("][") + 2); |
713
|
|
|
$field_name = $field_name.replace("]", ""); |
714
|
|
|
$output = $output + " " + $field_name + '="' + element.value + '"'; |
715
|
|
|
} |
716
|
|
|
|
717
|
|
|
}); |
718
|
|
|
} |
719
|
|
|
$output = $output + "]"; |
720
|
|
|
jQuery('#TB_ajaxContent #sd-shortcode-output').html($output); |
721
|
|
|
} |
722
|
|
|
|
723
|
|
|
|
724
|
|
|
/* |
725
|
|
|
Delay the init of the textareas for 1 second. |
726
|
|
|
*/ |
727
|
|
|
(function () { |
728
|
|
|
setTimeout(function () { |
729
|
|
|
sd_init_textareas(); |
730
|
|
|
}, 1000); |
731
|
|
|
})(); |
732
|
|
|
|
733
|
|
|
/* |
734
|
|
|
Init the textareas to be able to show the shortcode builder button. |
735
|
|
|
*/ |
736
|
|
|
function sd_init_textareas() { |
737
|
|
|
|
738
|
|
|
// General textareas |
739
|
|
|
jQuery(document).on('focus', 'textarea', function () { |
740
|
|
|
|
741
|
|
|
if (jQuery(this).hasClass('wp-editor-area')) { |
742
|
|
|
// insert the shortcode button to the textarea lable if not there already |
743
|
|
|
if (!jQuery(this).parent().find('.sd-lable-shortcode-inserter').length) { |
744
|
|
|
jQuery(this).parent().find('.quicktags-toolbar').append(sd_shortcode_button(jQuery(this).attr('id'))); |
745
|
|
|
} |
746
|
|
|
} else { |
747
|
|
|
// insert the shortcode button to the textarea lable if not there already |
748
|
|
|
if (!jQuery("label[for='" + jQuery(this).attr('id') + "']").find('.sd-lable-shortcode-inserter').length) { |
749
|
|
|
jQuery("label[for='" + jQuery(this).attr('id') + "']").append(sd_shortcode_button(jQuery(this).attr('id'))); |
750
|
|
|
} |
751
|
|
|
} |
752
|
|
|
}); |
753
|
|
|
|
754
|
|
|
// The below tries to add the shorcode builder button to the builders own raw/shortcode sections. |
755
|
|
|
|
756
|
|
|
// DIVI |
757
|
|
|
jQuery(document).on('focusin', '.et-fb-codemirror', function () { |
758
|
|
|
// insert the shortcode button to the textarea lable if not there already |
759
|
|
|
if (!jQuery(this).closest('.et-fb-form__group').find('.sd-lable-shortcode-inserter').length) { |
760
|
|
|
jQuery(this).closest('.et-fb-form__group').find('.et-fb-form__label-text').append(sd_shortcode_button()); |
761
|
|
|
} |
762
|
|
|
}); |
763
|
|
|
|
764
|
|
|
// Beaver |
765
|
|
|
jQuery(document).on('focusin', '.fl-code-field', function () { |
766
|
|
|
// insert the shortcode button to the textarea lable if not there already |
767
|
|
|
if (!jQuery(this).closest('.fl-field-control-wrapper').find('.sd-lable-shortcode-inserter').length) { |
768
|
|
|
jQuery(this).closest('.fl-field-control-wrapper').prepend(sd_shortcode_button()); |
769
|
|
|
} |
770
|
|
|
}); |
771
|
|
|
|
772
|
|
|
// Fushion builder (avada) |
773
|
|
|
jQuery(document).on('focusin', '.CodeMirror.cm-s-default', function () { |
774
|
|
|
// insert the shortcode button to the textarea lable if not there already |
775
|
|
|
if (!jQuery(this).parent().find('.sd-lable-shortcode-inserter').length) { |
776
|
|
|
jQuery(sd_shortcode_button()).insertBefore(this); |
777
|
|
|
} |
778
|
|
|
}); |
779
|
|
|
|
780
|
|
|
// Avia builder (enfold) |
781
|
|
|
jQuery(document).on('focusin', '#aviaTBcontent', function () { |
782
|
|
|
// insert the shortcode button to the textarea lable if not there already |
783
|
|
|
if (!jQuery(this).parent().parent().find('.avia-name-description ').find('.sd-lable-shortcode-inserter').length) { |
784
|
|
|
jQuery(this).parent().parent().find('.avia-name-description strong').append(sd_shortcode_button(jQuery(this).attr('id'))); |
785
|
|
|
} |
786
|
|
|
}); |
787
|
|
|
|
788
|
|
|
// Cornerstone |
789
|
|
|
jQuery(document).on('focusin', '.cs-control.cs-control-textarea', function () { |
790
|
|
|
// insert the shortcode button to the textarea lable if not there already |
791
|
|
|
if (!jQuery(this).find('.cs-control-header label').find('.sd-lable-shortcode-inserter').length) { |
792
|
|
|
jQuery(this).find('.cs-control-header label').append(sd_shortcode_button()); |
793
|
|
|
} |
794
|
|
|
}); |
795
|
|
|
|
796
|
|
|
// WP Bakery, code editor does not render shortcodes. |
797
|
|
|
// jQuery(document).on('focusin', '.wpb-textarea_raw_html', function () { |
798
|
|
|
// // insert the shortcode button to the textarea lable if not there already |
799
|
|
|
// if(!jQuery(this).parent().parent().find('.wpb_element_label').find('.sd-lable-shortcode-inserter').length){ |
800
|
|
|
// jQuery(this).parent().parent().find('.wpb_element_label').append(sd_shortcode_button()); |
801
|
|
|
// } |
802
|
|
|
// }); |
803
|
|
|
|
804
|
|
|
} |
805
|
|
|
|
806
|
|
|
/** |
807
|
|
|
* Gets the html for the picker via ajax and updates it on the fly. |
808
|
|
|
* |
809
|
|
|
* @param $id |
810
|
|
|
* @param $search |
811
|
|
|
*/ |
812
|
|
|
function sd_ajax_get_picker($id, $search) { |
813
|
|
|
if ($search) { |
814
|
|
|
$this = $id; |
815
|
|
|
$id = jQuery($this).closest('.wp-editor-wrap').find('.wp-editor-container textarea').attr('id'); |
816
|
|
|
} |
817
|
|
|
|
818
|
|
|
var data = { |
819
|
|
|
'action': 'super_duper_get_picker', |
820
|
|
|
'editor_id': $id, |
821
|
|
|
'_ajax_nonce': '<?php echo wp_create_nonce( 'super_duper_picker' );?>' |
822
|
|
|
}; |
823
|
|
|
|
824
|
|
|
if (!ajaxurl) { |
825
|
|
|
var ajaxurl = "<?php echo admin_url( 'admin-ajax.php' ); ?>"; |
826
|
|
|
} |
827
|
|
|
|
828
|
|
|
jQuery.post(ajaxurl, data, function (response) { |
829
|
|
|
jQuery('#TB_ajaxContent').html(response); |
830
|
|
|
//return response; |
831
|
|
|
}).then(function (env) { |
832
|
|
|
jQuery('body').on('thickbox:removed', function () { |
833
|
|
|
jQuery('#super-duper-content-ajaxed').html(''); |
834
|
|
|
}); |
835
|
|
|
}); |
836
|
|
|
} |
837
|
|
|
|
838
|
|
|
/** |
839
|
|
|
* Get the html for the shortcode inserter button depending on if a textarea id is available. |
840
|
|
|
* |
841
|
|
|
* @param $id string The textarea id. |
842
|
|
|
* @returns {string} |
843
|
|
|
*/ |
844
|
|
|
function sd_shortcode_button($id) { |
845
|
|
|
if ($id) { |
846
|
|
|
return '<?php echo self::shortcode_button( "\\''+\$id+'\\'" );?>'; |
847
|
|
|
} else { |
848
|
|
|
return '<?php echo self::shortcode_button();?>'; |
849
|
|
|
} |
850
|
|
|
} |
851
|
|
|
|
852
|
|
|
</script> |
853
|
|
|
|
854
|
|
|
<?php |
855
|
|
|
} |
856
|
|
|
|
857
|
|
|
/** |
858
|
|
|
* Gets some CSS for the widgets screen. |
859
|
|
|
* |
860
|
|
|
* @return mixed |
861
|
|
|
*/ |
862
|
|
View Code Duplication |
public function widget_css() { |
|
|
|
|
863
|
|
|
ob_start(); |
864
|
|
|
?> |
865
|
|
|
<style> |
866
|
|
|
.sd-advanced-setting { |
867
|
|
|
display: none; |
868
|
|
|
} |
869
|
|
|
|
870
|
|
|
.sd-advanced-setting.sd-adv-show { |
871
|
|
|
display: block; |
872
|
|
|
} |
873
|
|
|
|
874
|
|
|
.sd-argument.sd-require-hide, |
875
|
|
|
.sd-advanced-setting.sd-require-hide { |
876
|
|
|
display: none; |
877
|
|
|
} |
878
|
|
|
|
879
|
|
|
button.sd-advanced-button { |
880
|
|
|
margin-right: 3px !important; |
881
|
|
|
font-size: 20px !important; |
882
|
|
|
} |
883
|
|
|
</style> |
884
|
|
|
<?php |
885
|
|
|
$output = ob_get_clean(); |
886
|
|
|
|
887
|
|
|
/* |
888
|
|
|
* We only add the <script> tags for code highlighting, so we strip them from the output. |
889
|
|
|
*/ |
890
|
|
|
|
891
|
|
|
return str_replace( array( |
892
|
|
|
'<style>', |
893
|
|
|
'</style>' |
894
|
|
|
), '', $output ); |
895
|
|
|
} |
896
|
|
|
|
897
|
|
|
/** |
898
|
|
|
* Gets some JS for the widgets screen. |
899
|
|
|
* |
900
|
|
|
* @return mixed |
901
|
|
|
*/ |
902
|
|
View Code Duplication |
public function widget_js() { |
|
|
|
|
903
|
|
|
ob_start(); |
904
|
|
|
?> |
905
|
|
|
<script> |
906
|
|
|
|
907
|
|
|
/** |
908
|
|
|
* Toggle advanced settings visibility. |
909
|
|
|
*/ |
910
|
|
|
function sd_toggle_advanced($this) { |
911
|
|
|
var form = jQuery($this).parents('form,.form'); |
912
|
|
|
form.find('.sd-advanced-setting').toggleClass('sd-adv-show'); |
913
|
|
|
return false;// prevent form submit |
914
|
|
|
} |
915
|
|
|
|
916
|
|
|
/** |
917
|
|
|
* Check a form to see what items shoudl be shown or hidden. |
918
|
|
|
*/ |
919
|
|
|
function sd_show_hide(form) { |
920
|
|
|
console.log('show/hide'); |
921
|
|
|
jQuery(form).find(".sd-argument").each(function () { |
922
|
|
|
|
923
|
|
|
var $element_require = jQuery(this).data('element_require'); |
924
|
|
|
|
925
|
|
|
if ($element_require) { |
926
|
|
|
|
927
|
|
|
$element_require = $element_require.replace("'", "'"); // replace single quotes |
928
|
|
|
$element_require = $element_require.replace(""", '"'); // replace double quotes |
929
|
|
|
|
930
|
|
|
if (eval($element_require)) { |
931
|
|
|
jQuery(this).removeClass('sd-require-hide'); |
932
|
|
|
} else { |
933
|
|
|
jQuery(this).addClass('sd-require-hide'); |
934
|
|
|
} |
935
|
|
|
} |
936
|
|
|
}); |
937
|
|
|
} |
938
|
|
|
|
939
|
|
|
/** |
940
|
|
|
* Initialise widgets from the widgets screen. |
941
|
|
|
*/ |
942
|
|
|
function sd_init_widgets($selector) { |
943
|
|
|
jQuery(".sd-show-advanced").each(function (index) { |
944
|
|
|
sd_init_widget(this, $selector); |
945
|
|
|
}); |
946
|
|
|
} |
947
|
|
|
|
948
|
|
|
/** |
949
|
|
|
* Initialise a individual widget. |
950
|
|
|
*/ |
951
|
|
|
function sd_init_widget($this, $selector) { |
952
|
|
|
console.log($selector); |
953
|
|
|
|
954
|
|
|
if (!$selector) { |
955
|
|
|
$selector = 'form'; |
956
|
|
|
} |
957
|
|
|
// only run once. |
958
|
|
|
if (jQuery($this).data('sd-widget-enabled')) { |
959
|
|
|
return; |
960
|
|
|
} else { |
961
|
|
|
jQuery($this).data('sd-widget-enabled', true); |
962
|
|
|
} |
963
|
|
|
|
964
|
|
|
var $button = '<button title="<?php _e( 'Advanced Settings' );?>" class="button button-primary right sd-advanced-button" onclick="sd_toggle_advanced(this);return false;"><span class="dashicons dashicons-admin-settings" style="width: 28px;font-size: 28px;"></span></button>'; |
965
|
|
|
var form = jQuery($this).parents('' + $selector + ''); |
966
|
|
|
|
967
|
|
|
if (jQuery($this).val() == '1' && jQuery(form).find('.sd-advanced-button').length == 0) { |
968
|
|
|
console.log('add advanced button'); |
969
|
|
|
|
970
|
|
|
jQuery(form).find('.widget-control-save').after($button); |
971
|
|
|
} else { |
972
|
|
|
console.log('no advanced button'); |
973
|
|
|
console.log(jQuery($this).val()); |
974
|
|
|
console.log(jQuery(form).find('.sd-advanced-button').length); |
975
|
|
|
|
976
|
|
|
} |
977
|
|
|
|
978
|
|
|
// show hide on form change |
979
|
|
|
jQuery(form).change(function () { |
980
|
|
|
sd_show_hide(form); |
981
|
|
|
}); |
982
|
|
|
|
983
|
|
|
// show hide on load |
984
|
|
|
sd_show_hide(form); |
985
|
|
|
} |
986
|
|
|
|
987
|
|
|
/** |
988
|
|
|
* Init a customizer widget. |
989
|
|
|
*/ |
990
|
|
|
function sd_init_customizer_widget(section) { |
991
|
|
|
if (section.expanded) { |
992
|
|
|
section.expanded.bind(function (isExpanding) { |
993
|
|
|
if (isExpanding) { |
994
|
|
|
// is it a SD widget? |
995
|
|
|
if (jQuery(section.container).find('.sd-show-advanced').length) { |
996
|
|
|
// init the widget |
997
|
|
|
sd_init_widget(jQuery(section.container).find('.sd-show-advanced'), ".form"); |
998
|
|
|
} |
999
|
|
|
} |
1000
|
|
|
}); |
1001
|
|
|
} |
1002
|
|
|
} |
1003
|
|
|
|
1004
|
|
|
/** |
1005
|
|
|
* If on widgets screen. |
1006
|
|
|
*/ |
1007
|
|
|
jQuery(function () { |
1008
|
|
|
// if not in customizer. |
1009
|
|
|
if (!wp.customize) { |
1010
|
|
|
sd_init_widgets("form"); |
1011
|
|
|
} |
1012
|
|
|
|
1013
|
|
|
// init on widget added |
1014
|
|
|
jQuery(document).on('widget-added', function (e, widget) { |
1015
|
|
|
console.log('widget added'); |
1016
|
|
|
// is it a SD widget? |
1017
|
|
|
if (jQuery(widget).find('.sd-show-advanced').length) { |
1018
|
|
|
// init the widget |
1019
|
|
|
sd_init_widget(jQuery(widget).find('.sd-show-advanced'), "form"); |
1020
|
|
|
} |
1021
|
|
|
}); |
1022
|
|
|
|
1023
|
|
|
// inint on widget updated |
1024
|
|
|
jQuery(document).on('widget-updated', function (e, widget) { |
1025
|
|
|
console.log('widget updated'); |
1026
|
|
|
|
1027
|
|
|
// is it a SD widget? |
1028
|
|
|
if (jQuery(widget).find('.sd-show-advanced').length) { |
1029
|
|
|
// init the widget |
1030
|
|
|
sd_init_widget(jQuery(widget).find('.sd-show-advanced'), "form"); |
1031
|
|
|
} |
1032
|
|
|
}); |
1033
|
|
|
|
1034
|
|
|
}); |
1035
|
|
|
|
1036
|
|
|
|
1037
|
|
|
/** |
1038
|
|
|
* We need to run this before jQuery is ready |
1039
|
|
|
*/ |
1040
|
|
|
if (wp.customize) { |
1041
|
|
|
wp.customize.bind('ready', function () { |
1042
|
|
|
|
1043
|
|
|
// init widgets on load |
1044
|
|
|
wp.customize.control.each(function (section) { |
1045
|
|
|
sd_init_customizer_widget(section); |
1046
|
|
|
}); |
1047
|
|
|
|
1048
|
|
|
// init widgets on add |
1049
|
|
|
wp.customize.control.bind('add', function (section) { |
1050
|
|
|
sd_init_customizer_widget(section); |
1051
|
|
|
}); |
1052
|
|
|
|
1053
|
|
|
}); |
1054
|
|
|
|
1055
|
|
|
} |
1056
|
|
|
<?php do_action( 'wp_super_duper_widget_js', $this ); ?> |
1057
|
|
|
</script> |
1058
|
|
|
<?php |
1059
|
|
|
$output = ob_get_clean(); |
1060
|
|
|
|
1061
|
|
|
/* |
1062
|
|
|
* We only add the <script> tags for code highlighting, so we strip them from the output. |
1063
|
|
|
*/ |
1064
|
|
|
|
1065
|
|
|
return str_replace( array( |
1066
|
|
|
'<script>', |
1067
|
|
|
'</script>' |
1068
|
|
|
), '', $output ); |
1069
|
|
|
} |
1070
|
|
|
|
1071
|
|
|
|
1072
|
|
|
/** |
1073
|
|
|
* Set the name from the argument key. |
1074
|
|
|
* |
1075
|
|
|
* @param $options |
1076
|
|
|
* |
1077
|
|
|
* @return mixed |
1078
|
|
|
*/ |
1079
|
|
|
private function add_name_from_key( $options, $arguments = false ) { |
1080
|
|
|
if ( ! empty( $options['arguments'] ) ) { |
1081
|
|
|
foreach ( $options['arguments'] as $key => $val ) { |
1082
|
|
|
$options['arguments'][ $key ]['name'] = $key; |
1083
|
|
|
} |
1084
|
|
|
} elseif ( $arguments && is_array( $options ) && ! empty( $options ) ) { |
1085
|
|
|
foreach ( $options as $key => $val ) { |
1086
|
|
|
$options[ $key ]['name'] = $key; |
1087
|
|
|
} |
1088
|
|
|
} |
1089
|
|
|
|
1090
|
|
|
return $options; |
1091
|
|
|
} |
1092
|
|
|
|
1093
|
|
|
/** |
1094
|
|
|
* Register the parent shortcode. |
1095
|
|
|
* |
1096
|
|
|
* @since 1.0.0 |
1097
|
|
|
*/ |
1098
|
|
|
public function register_shortcode() { |
1099
|
|
|
add_shortcode( $this->base_id, array( $this, 'shortcode_output' ) ); |
1100
|
|
|
add_action( 'wp_ajax_super_duper_output_shortcode', array( __CLASS__, 'render_shortcode' ) ); |
1101
|
|
|
} |
1102
|
|
|
|
1103
|
|
|
/** |
1104
|
|
|
* Render the shortcode via ajax so we can return it to Gutenberg. |
1105
|
|
|
* |
1106
|
|
|
* @since 1.0.0 |
1107
|
|
|
*/ |
1108
|
|
|
public static function render_shortcode() { |
1109
|
|
|
|
1110
|
|
|
check_ajax_referer( 'super_duper_output_shortcode', '_ajax_nonce', true ); |
1111
|
|
|
if ( ! current_user_can( 'manage_options' ) ) { |
1112
|
|
|
wp_die(); |
1113
|
|
|
} |
1114
|
|
|
|
1115
|
|
|
// we might need the $post value here so lets set it. |
1116
|
|
|
if ( isset( $_POST['post_id'] ) && $_POST['post_id'] ) { |
1117
|
|
|
$post_obj = get_post( absint( $_POST['post_id'] ) ); |
1118
|
|
|
if ( ! empty( $post_obj ) && empty( $post ) ) { |
|
|
|
|
1119
|
|
|
global $post; |
1120
|
|
|
$post = $post_obj; |
1121
|
|
|
} |
1122
|
|
|
} |
1123
|
|
|
|
1124
|
|
|
if ( isset( $_POST['shortcode'] ) && $_POST['shortcode'] ) { |
1125
|
|
|
$shortcode_name = sanitize_title_with_dashes( $_POST['shortcode'] ); |
1126
|
|
|
$attributes_array = isset( $_POST['attributes'] ) && $_POST['attributes'] ? $_POST['attributes'] : array(); |
1127
|
|
|
$attributes = ''; |
1128
|
|
|
if ( ! empty( $attributes_array ) ) { |
1129
|
|
|
foreach ( $attributes_array as $key => $value ) { |
1130
|
|
|
$attributes .= " " . sanitize_title_with_dashes( $key ) . "='" . wp_slash( $value ) . "' "; |
1131
|
|
|
} |
1132
|
|
|
} |
1133
|
|
|
|
1134
|
|
|
$shortcode = "[" . $shortcode_name . " " . $attributes . "]"; |
1135
|
|
|
|
1136
|
|
|
echo do_shortcode( $shortcode ); |
1137
|
|
|
|
1138
|
|
|
} |
1139
|
|
|
wp_die(); |
1140
|
|
|
} |
1141
|
|
|
|
1142
|
|
|
/** |
1143
|
|
|
* Output the shortcode. |
1144
|
|
|
* |
1145
|
|
|
* @param array $args |
1146
|
|
|
* @param string $content |
1147
|
|
|
* |
1148
|
|
|
* @return string |
1149
|
|
|
*/ |
1150
|
|
|
public function shortcode_output( $args = array(), $content = '' ) { |
1151
|
|
|
$args = self::argument_values( $args ); |
1152
|
|
|
|
1153
|
|
|
// add extra argument so we know its a output to gutenberg |
1154
|
|
|
//$args |
1155
|
|
|
$args = $this->string_to_bool( $args ); |
1156
|
|
|
|
1157
|
|
|
|
1158
|
|
|
$calss = isset( $this->options['widget_ops']['classname'] ) ? esc_attr( $this->options['widget_ops']['classname'] ) : ''; |
1159
|
|
|
|
1160
|
|
|
$calss = apply_filters( 'wp_super_duper_div_classname', $calss, $args, $this ); |
1161
|
|
|
$calss = apply_filters( 'wp_super_duper_div_classname_' . $this->base_id, $calss, $args, $this ); |
1162
|
|
|
|
1163
|
|
|
$attrs = apply_filters( 'wp_super_duper_div_attrs', '', $args, $this ); |
|
|
|
|
1164
|
|
|
$attrs = apply_filters( 'wp_super_duper_div_attrs_' . $this->base_id, '', $args, $this ); |
1165
|
|
|
|
1166
|
|
|
$shortcode_args = array(); |
1167
|
|
|
$output = ''; |
1168
|
|
|
$no_wrap = isset( $this->options['no_wrap'] ) && $this->options['no_wrap'] ? true : false; |
1169
|
|
|
$main_content = $this->output( $args, $shortcode_args, $content ); |
|
|
|
|
1170
|
|
|
if ( $main_content && ! $no_wrap ) { |
1171
|
|
|
// wrap the shortcode in a dive with the same class as the widget |
1172
|
|
|
$output .= '<div class="' . $calss . '" ' . $attrs . '>'; |
1173
|
|
|
if ( ! empty( $args['title'] ) ) { |
1174
|
|
|
// if its a shortcode and there is a title try to grab the title wrappers |
1175
|
|
|
$shortcode_args = array( 'before_title' => '', 'after_title' => '' ); |
1176
|
|
|
if ( empty( $instance ) ) { |
|
|
|
|
1177
|
|
|
global $wp_registered_sidebars; |
1178
|
|
|
if ( ! empty( $wp_registered_sidebars ) ) { |
1179
|
|
|
foreach ( $wp_registered_sidebars as $sidebar ) { |
1180
|
|
|
if ( ! empty( $sidebar['before_title'] ) ) { |
1181
|
|
|
$shortcode_args['before_title'] = $sidebar['before_title']; |
1182
|
|
|
$shortcode_args['after_title'] = $sidebar['after_title']; |
1183
|
|
|
break; |
1184
|
|
|
} |
1185
|
|
|
} |
1186
|
|
|
} |
1187
|
|
|
} |
1188
|
|
|
$output .= $this->output_title( $shortcode_args, $args ); |
1189
|
|
|
} |
1190
|
|
|
$output .= $main_content; |
1191
|
|
|
$output .= '</div>'; |
1192
|
|
|
} elseif ( $main_content && $no_wrap ) { |
1193
|
|
|
$output .= $main_content; |
1194
|
|
|
} |
1195
|
|
|
|
1196
|
|
|
// if preview show a placeholder if empty |
1197
|
|
View Code Duplication |
if ( $this->is_preview() && $output == '' ) { |
1198
|
|
|
$output = $this->preview_placeholder_text( "[{" . $this->base_id . "}]" ); |
1199
|
|
|
} |
1200
|
|
|
|
1201
|
|
|
return $output; |
1202
|
|
|
} |
1203
|
|
|
|
1204
|
|
|
/** |
1205
|
|
|
* Placeholder text to show if output is empty and we are on a preview/builder page. |
1206
|
|
|
* |
1207
|
|
|
* @param string $name |
1208
|
|
|
* |
1209
|
|
|
* @return string |
1210
|
|
|
*/ |
1211
|
|
|
public function preview_placeholder_text( $name = '' ) { |
1212
|
|
|
return "<div style='background:#0185ba33;padding: 10px;border: 4px #ccc dashed;'>" . sprintf( __( 'Placeholder for: %s' ), $name ) . "</div>"; |
1213
|
|
|
} |
1214
|
|
|
|
1215
|
|
|
/** |
1216
|
|
|
* Sometimes booleans values can be turned to strings, so we fix that. |
1217
|
|
|
* |
1218
|
|
|
* @param $options |
1219
|
|
|
* |
1220
|
|
|
* @return mixed |
1221
|
|
|
*/ |
1222
|
|
|
public function string_to_bool( $options ) { |
1223
|
|
|
// convert bool strings to booleans |
1224
|
|
|
foreach ( $options as $key => $val ) { |
1225
|
|
|
if ( $val == 'false' ) { |
1226
|
|
|
$options[ $key ] = false; |
1227
|
|
|
} elseif ( $val == 'true' ) { |
1228
|
|
|
$options[ $key ] = true; |
1229
|
|
|
} |
1230
|
|
|
} |
1231
|
|
|
|
1232
|
|
|
return $options; |
1233
|
|
|
} |
1234
|
|
|
|
1235
|
|
|
/** |
1236
|
|
|
* Get the argument values that are also filterable. |
1237
|
|
|
* |
1238
|
|
|
* @param $instance |
1239
|
|
|
* |
1240
|
|
|
* @return array |
1241
|
|
|
*/ |
1242
|
|
|
public function argument_values( $instance ) { |
1243
|
|
|
$argument_values = array(); |
1244
|
|
|
|
1245
|
|
|
// set widget instance |
1246
|
|
|
$this->instance = $instance; |
1247
|
|
|
|
1248
|
|
|
if ( empty( $this->arguments ) ) { |
1249
|
|
|
$this->arguments = $this->get_arguments(); |
1250
|
|
|
} |
1251
|
|
|
|
1252
|
|
|
if ( ! empty( $this->arguments ) ) { |
1253
|
|
|
foreach ( $this->arguments as $key => $args ) { |
1254
|
|
|
// set the input name from the key |
1255
|
|
|
$args['name'] = $key; |
1256
|
|
|
// |
1257
|
|
|
$argument_values[ $key ] = isset( $instance[ $key ] ) ? $instance[ $key ] : ''; |
1258
|
|
|
if ( $argument_values[ $key ] == '' && isset( $args['default'] ) ) { |
1259
|
|
|
$argument_values[ $key ] = $args['default']; |
1260
|
|
|
} |
1261
|
|
|
} |
1262
|
|
|
} |
1263
|
|
|
|
1264
|
|
|
return $argument_values; |
1265
|
|
|
} |
1266
|
|
|
|
1267
|
|
|
/** |
1268
|
|
|
* Set arguments in super duper. |
1269
|
|
|
* |
1270
|
|
|
* @since 1.0.0 |
1271
|
|
|
* |
1272
|
|
|
* @return array Set arguments. |
1273
|
|
|
*/ |
1274
|
|
|
public function set_arguments() { |
1275
|
|
|
return $this->arguments; |
1276
|
|
|
} |
1277
|
|
|
|
1278
|
|
|
/** |
1279
|
|
|
* Get arguments in super duper. |
1280
|
|
|
* |
1281
|
|
|
* @since 1.0.0 |
1282
|
|
|
* |
1283
|
|
|
* @return array Get arguments. |
1284
|
|
|
*/ |
1285
|
|
|
public function get_arguments() { |
1286
|
|
|
if ( empty( $this->arguments ) ) { |
1287
|
|
|
$this->arguments = $this->set_arguments(); |
1288
|
|
|
} |
1289
|
|
|
|
1290
|
|
|
$this->arguments = apply_filters( 'wp_super_duper_arguments', $this->arguments, $this->options, $this->instance ); |
1291
|
|
|
$this->arguments = $this->add_name_from_key( $this->arguments, true ); |
|
|
|
|
1292
|
|
|
|
1293
|
|
|
return $this->arguments; |
1294
|
|
|
} |
1295
|
|
|
|
1296
|
|
|
/** |
1297
|
|
|
* This is the main output class for all 3 items, widget, shortcode and block, it is extended in the calling class. |
1298
|
|
|
* |
1299
|
|
|
* @param array $args |
1300
|
|
|
* @param array $widget_args |
1301
|
|
|
* @param string $content |
1302
|
|
|
*/ |
1303
|
|
|
public function output( $args = array(), $widget_args = array(), $content = '' ) { |
1304
|
|
|
|
1305
|
|
|
} |
1306
|
|
|
|
1307
|
|
|
/** |
1308
|
|
|
* Add the dynamic block code inline when the wp-block in enqueued. |
1309
|
|
|
*/ |
1310
|
|
|
public function register_block() { |
1311
|
|
|
wp_add_inline_script( 'wp-blocks', $this->block() ); |
1312
|
|
|
if ( class_exists( 'SiteOrigin_Panels' ) ) { |
1313
|
|
|
|
1314
|
|
|
wp_add_inline_script( 'wp-blocks', $this->siteorigin_js() ); |
1315
|
|
|
|
1316
|
|
|
} |
1317
|
|
|
} |
1318
|
|
|
|
1319
|
|
|
/** |
1320
|
|
|
* Check if we need to show advanced options. |
1321
|
|
|
* |
1322
|
|
|
* @return bool |
1323
|
|
|
*/ |
1324
|
|
|
public function block_show_advanced() { |
1325
|
|
|
|
1326
|
|
|
$show = false; |
1327
|
|
|
$arguments = $this->arguments; |
1328
|
|
|
|
1329
|
|
|
if ( empty( $arguments ) ) { |
1330
|
|
|
$arguments = $this->get_arguments(); |
1331
|
|
|
} |
1332
|
|
|
|
1333
|
|
|
if ( ! empty( $arguments ) ) { |
1334
|
|
|
foreach ( $arguments as $argument ) { |
1335
|
|
|
if ( isset( $argument['advanced'] ) && $argument['advanced'] ) { |
1336
|
|
|
$show = true; |
1337
|
|
|
} |
1338
|
|
|
} |
1339
|
|
|
} |
1340
|
|
|
|
1341
|
|
|
return $show; |
1342
|
|
|
} |
1343
|
|
|
|
1344
|
|
|
|
1345
|
|
|
/** |
1346
|
|
|
* Output the JS for building the dynamic Guntenberg block. |
1347
|
|
|
* |
1348
|
|
|
* @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. |
1349
|
|
|
* @since 1.0.9 Save numbers as numbers and not strings. |
1350
|
|
|
* @return mixed |
1351
|
|
|
*/ |
1352
|
|
|
public function block() { |
1353
|
|
|
ob_start(); |
1354
|
|
|
?> |
1355
|
|
|
<script> |
1356
|
|
|
/** |
1357
|
|
|
* BLOCK: Basic |
1358
|
|
|
* |
1359
|
|
|
* Registering a basic block with Gutenberg. |
1360
|
|
|
* Simple block, renders and saves the same content without any interactivity. |
1361
|
|
|
* |
1362
|
|
|
* Styles: |
1363
|
|
|
* editor.css — Editor styles for the block. |
1364
|
|
|
* style.css — Editor & Front end styles for the block. |
1365
|
|
|
*/ |
1366
|
|
|
(function () { |
1367
|
|
|
var __ = wp.i18n.__; // The __() for internationalization. |
1368
|
|
|
var el = wp.element.createElement; // The wp.element.createElement() function to create elements. |
1369
|
|
|
var editable = wp.blocks.Editable; |
1370
|
|
|
var blocks = wp.blocks; |
1371
|
|
|
var registerBlockType = wp.blocks.registerBlockType; // The registerBlockType() to register blocks. |
1372
|
|
|
var is_fetching = false; |
1373
|
|
|
var prev_attributes = []; |
1374
|
|
|
|
1375
|
|
|
/** |
1376
|
|
|
* Register Basic Block. |
1377
|
|
|
* |
1378
|
|
|
* Registers a new block provided a unique name and an object defining its |
1379
|
|
|
* behavior. Once registered, the block is made available as an option to any |
1380
|
|
|
* editor interface where blocks are implemented. |
1381
|
|
|
* |
1382
|
|
|
* @param {string} name Block name. |
1383
|
|
|
* @param {Object} settings Block settings. |
1384
|
|
|
* @return {?WPBlock} The block, if it has been successfully |
1385
|
|
|
* registered; otherwise `undefined`. |
1386
|
|
|
*/ |
1387
|
|
|
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. |
1388
|
|
|
title: '<?php echo $this->options['name'];?>', // Block title. |
1389
|
|
|
description: '<?php echo esc_attr( $this->options['widget_ops']['description'] )?>', // Block title. |
1390
|
|
|
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/. |
1391
|
|
|
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. |
1392
|
|
|
<?php if ( isset( $this->options['block-keywords'] ) ) { |
1393
|
|
|
echo "keywords : " . $this->options['block-keywords'] . ","; |
1394
|
|
|
}?> |
1395
|
|
|
|
1396
|
|
|
<?php |
1397
|
|
|
|
1398
|
|
|
$show_advanced = $this->block_show_advanced(); |
1399
|
|
|
|
1400
|
|
|
$show_alignment = false; |
1401
|
|
|
|
1402
|
|
|
if ( ! empty( $this->arguments ) ) { |
1403
|
|
|
echo "attributes : {"; |
1404
|
|
|
|
1405
|
|
|
if ( $show_advanced ) { |
1406
|
|
|
echo "show_advanced: {"; |
1407
|
|
|
echo " type: 'boolean',"; |
1408
|
|
|
echo " default: false,"; |
1409
|
|
|
echo "},"; |
1410
|
|
|
} |
1411
|
|
|
|
1412
|
|
|
// block wrap element |
1413
|
|
|
if ( isset( $this->options['block-wrap'] ) ) { //@todo we should validate this? |
1414
|
|
|
echo "block_wrap: {"; |
1415
|
|
|
echo " type: 'string',"; |
1416
|
|
|
echo " default: '" . esc_attr( $this->options['block-wrap'] ) . "',"; |
1417
|
|
|
echo "},"; |
1418
|
|
|
} |
1419
|
|
|
|
1420
|
|
|
|
1421
|
|
|
foreach ( $this->arguments as $key => $args ) { |
1422
|
|
|
|
1423
|
|
|
// set if we should show alignment |
1424
|
|
|
if ( $key == 'alignment' ) { |
1425
|
|
|
$show_alignment = true; |
1426
|
|
|
} |
1427
|
|
|
|
1428
|
|
|
$extra = ''; |
|
|
|
|
1429
|
|
|
|
1430
|
|
|
if ( $args['type'] == 'checkbox' ) { |
1431
|
|
|
$type = 'boolean'; |
1432
|
|
|
$default = isset( $args['default'] ) && $args['default'] ? 'true' : 'false'; |
1433
|
|
|
} elseif ( $args['type'] == 'number' ) { |
1434
|
|
|
$type = 'number'; |
1435
|
|
|
$default = isset( $args['default'] ) ? "'" . $args['default'] . "'" : "''"; |
1436
|
|
|
} elseif ( $args['type'] == 'select' && ! empty( $args['multiple'] ) ) { |
1437
|
|
|
$type = 'array'; |
1438
|
|
|
if ( is_array( $args['default'] ) ) { |
1439
|
|
|
$default = isset( $args['default'] ) ? "['" . implode( "','", $args['default'] ) . "']" : "[]"; |
1440
|
|
View Code Duplication |
} else { |
1441
|
|
|
$default = isset( $args['default'] ) ? "'" . $args['default'] . "'" : "''"; |
1442
|
|
|
} |
1443
|
|
|
} elseif ( $args['type'] == 'multiselect' ) { |
1444
|
|
|
$type = 'array'; |
1445
|
|
|
$default = isset( $args['default'] ) ? "'" . $args['default'] . "'" : "''"; |
1446
|
|
View Code Duplication |
} else { |
1447
|
|
|
$type = 'string'; |
1448
|
|
|
$default = isset( $args['default'] ) ? "'" . $args['default'] . "'" : "''"; |
1449
|
|
|
} |
1450
|
|
|
echo $key . " : {"; |
1451
|
|
|
echo "type : '$type',"; |
1452
|
|
|
echo "default : $default,"; |
1453
|
|
|
echo "},"; |
1454
|
|
|
} |
1455
|
|
|
|
1456
|
|
|
echo "content : {type : 'string',default: 'Please select the attributes in the block settings'},"; |
1457
|
|
|
|
1458
|
|
|
echo "},"; |
1459
|
|
|
|
1460
|
|
|
} |
1461
|
|
|
|
1462
|
|
|
?> |
1463
|
|
|
|
1464
|
|
|
// The "edit" property must be a valid function. |
1465
|
|
|
edit: function (props) { |
1466
|
|
|
|
1467
|
|
|
var content = props.attributes.content; |
1468
|
|
|
|
1469
|
|
|
function onChangeContent() { |
1470
|
|
|
|
1471
|
|
|
if (!is_fetching && prev_attributes[props.id] != props.attributes) { |
1472
|
|
|
|
1473
|
|
|
//console.log(props); |
1474
|
|
|
|
1475
|
|
|
is_fetching = true; |
1476
|
|
|
var data = { |
1477
|
|
|
'action': 'super_duper_output_shortcode', |
1478
|
|
|
'shortcode': '<?php echo $this->options['base_id'];?>', |
1479
|
|
|
'attributes': props.attributes, |
1480
|
|
|
'post_id': <?php global $post; if ( isset( $post->ID ) ) { |
1481
|
|
|
echo $post->ID; |
1482
|
|
|
}?>, |
1483
|
|
|
'_ajax_nonce': '<?php echo wp_create_nonce( 'super_duper_output_shortcode' );?>' |
1484
|
|
|
}; |
1485
|
|
|
|
1486
|
|
|
jQuery.post(ajaxurl, data, function (response) { |
1487
|
|
|
return response; |
1488
|
|
|
}).then(function (env) { |
1489
|
|
|
|
1490
|
|
|
// if the content is empty then we place some placeholder text |
1491
|
|
|
if (env == '') { |
1492
|
|
|
env = "<div style='background:#0185ba33;padding: 10px;border: 4px #ccc dashed;'>" + "<?php _e( 'Placeholder for: ' );?>" + props.name + "</div>"; |
1493
|
|
|
} |
1494
|
|
|
|
1495
|
|
|
props.setAttributes({content: env}); |
1496
|
|
|
is_fetching = false; |
1497
|
|
|
prev_attributes[props.id] = props.attributes; |
1498
|
|
|
}); |
1499
|
|
|
|
1500
|
|
|
|
1501
|
|
|
} |
1502
|
|
|
|
1503
|
|
|
return props.attributes.content; |
1504
|
|
|
|
1505
|
|
|
} |
1506
|
|
|
|
1507
|
|
|
return [ |
1508
|
|
|
|
1509
|
|
|
el(wp.editor.BlockControls, {key: 'controls'}, |
1510
|
|
|
|
1511
|
|
|
<?php if($show_alignment){?> |
1512
|
|
|
el( |
1513
|
|
|
wp.editor.AlignmentToolbar, |
1514
|
|
|
{ |
1515
|
|
|
value: props.attributes.alignment, |
1516
|
|
|
onChange: function (alignment) { |
1517
|
|
|
props.setAttributes({alignment: alignment}) |
1518
|
|
|
} |
1519
|
|
|
} |
1520
|
|
|
) |
1521
|
|
|
<?php }?> |
1522
|
|
|
|
1523
|
|
|
), |
1524
|
|
|
|
1525
|
|
|
el(wp.editor.InspectorControls, {key: 'inspector'}, |
1526
|
|
|
|
1527
|
|
|
<?php |
1528
|
|
|
|
1529
|
|
|
if(! empty( $this->arguments )){ |
1530
|
|
|
|
1531
|
|
|
if ( $show_advanced ) { |
1532
|
|
|
?> |
1533
|
|
|
el( |
1534
|
|
|
wp.components.ToggleControl, |
1535
|
|
|
{ |
1536
|
|
|
label: 'Show Advanced Settings?', |
1537
|
|
|
checked: props.attributes.show_advanced, |
1538
|
|
|
onChange: function (show_advanced) { |
1539
|
|
|
props.setAttributes({show_advanced: !props.attributes.show_advanced}) |
1540
|
|
|
} |
1541
|
|
|
} |
1542
|
|
|
), |
1543
|
|
|
<?php |
1544
|
|
|
|
1545
|
|
|
} |
1546
|
|
|
|
1547
|
|
|
foreach($this->arguments as $key => $args){ |
1548
|
|
|
$custom_attributes = ! empty( $args['custom_attributes'] ) ? $this->array_to_attributes( $args['custom_attributes'] ) : ''; |
1549
|
|
|
$options = ''; |
1550
|
|
|
$extra = ''; |
1551
|
|
|
$require = ''; |
|
|
|
|
1552
|
|
|
$onchange = "props.setAttributes({ $key: $key } )"; |
1553
|
|
|
$value = "props.attributes.$key"; |
1554
|
|
|
$text_type = array( 'text', 'password', 'number', 'email', 'tel', 'url', 'color' ); |
1555
|
|
|
if ( in_array( $args['type'], $text_type ) ) { |
1556
|
|
|
$type = 'TextControl'; |
1557
|
|
|
// Save numbers as numbers and not strings |
1558
|
|
|
if ( $args['type'] == 'number' ) { |
1559
|
|
|
$onchange = "props.setAttributes({ $key: Number($key) } )"; |
1560
|
|
|
} |
1561
|
|
|
} |
1562
|
|
|
// elseif ( $args['type'] == 'color' ) { //@todo ColorPicker labels are not shown yet, we may have to add our own https://github.com/WordPress/gutenberg/issues/14378 |
1563
|
|
|
// $type = 'ColorPicker'; |
1564
|
|
|
// } |
1565
|
|
|
elseif ( $args['type'] == 'checkbox' ) { |
1566
|
|
|
$type = 'CheckboxControl'; |
1567
|
|
|
$extra .= "checked: props.attributes.$key,"; |
1568
|
|
|
$onchange = "props.setAttributes({ $key: ! props.attributes.$key } )"; |
1569
|
|
|
} elseif ( $args['type'] == 'select' || $args['type'] == 'multiselect' ) { |
1570
|
|
|
$type = 'SelectControl'; |
1571
|
|
|
if ( ! empty( $args['options'] ) ) { |
1572
|
|
|
$options .= "options : ["; |
1573
|
|
|
foreach ( $args['options'] as $option_val => $option_label ) { |
1574
|
|
|
$options .= "{ value : '" . esc_attr( $option_val ) . "', label : '" . esc_attr( $option_label ) . "' },"; |
1575
|
|
|
} |
1576
|
|
|
$options .= "],"; |
1577
|
|
|
} |
1578
|
|
|
if ( isset( $args['multiple'] ) && $args['multiple'] ) { //@todo multiselect does not work at the moment: https://github.com/WordPress/gutenberg/issues/5550 |
1579
|
|
|
$extra .= ' multiple: true, '; |
1580
|
|
|
//$onchange = "props.setAttributes({ $key: ['edit'] } )"; |
1581
|
|
|
//$value = "['edit', 'delete']"; |
1582
|
|
|
} |
1583
|
|
|
} elseif ( $args['type'] == 'alignment' ) { |
1584
|
|
|
$type = 'AlignmentToolbar'; // @todo this does not seem to work but cant find a example |
1585
|
|
|
} else { |
1586
|
|
|
continue;// if we have not implemented the control then don't break the JS. |
1587
|
|
|
} |
1588
|
|
|
|
1589
|
|
|
// add show only if advanced |
1590
|
|
|
if ( ! empty( $args['advanced'] ) ) { |
1591
|
|
|
echo "props.attributes.show_advanced && "; |
1592
|
|
|
} |
1593
|
|
|
// add setting require if defined |
1594
|
|
|
if ( ! empty( $args['element_require'] ) ) { |
1595
|
|
|
echo $this->block_props_replace( $args['element_require'], true ) . " && "; |
1596
|
|
|
} |
1597
|
|
|
?> |
1598
|
|
|
el( |
1599
|
|
|
wp.components.<?php echo esc_attr( $type );?>, |
1600
|
|
|
{ |
1601
|
|
|
label: '<?php echo esc_attr( $args['title'] );?>', |
1602
|
|
|
help: '<?php if ( isset( $args['desc'] ) ) { |
1603
|
|
|
echo esc_attr( $args['desc'] ); |
1604
|
|
|
}?>', |
1605
|
|
|
value: <?php echo $value;?>, |
1606
|
|
|
<?php if ( $type == 'TextControl' && $args['type'] != 'text' ) { |
1607
|
|
|
echo "type: '" . esc_attr( $args['type'] ) . "',"; |
1608
|
|
|
}?> |
1609
|
|
|
<?php if ( ! empty( $args['placeholder'] ) ) { |
1610
|
|
|
echo "placeholder: '" . esc_attr( $args['placeholder'] ) . "',"; |
1611
|
|
|
}?> |
1612
|
|
|
<?php echo $options;?> |
1613
|
|
|
<?php echo $extra;?> |
1614
|
|
|
<?php echo $custom_attributes;?> |
1615
|
|
|
onChange: function ( <?php echo $key;?> ) { |
1616
|
|
|
<?php echo $onchange;?> |
1617
|
|
|
} |
1618
|
|
|
} |
1619
|
|
|
), |
1620
|
|
|
<?php |
1621
|
|
|
} |
1622
|
|
|
} |
1623
|
|
|
?> |
1624
|
|
|
|
1625
|
|
|
), |
1626
|
|
|
|
1627
|
|
|
<?php |
1628
|
|
|
// If the user sets block-output array then build it |
1629
|
|
|
if ( ! empty( $this->options['block-output'] ) ) { |
1630
|
|
|
$this->block_element( $this->options['block-output'] ); |
1631
|
|
|
}else{ |
1632
|
|
|
// if no block-output is set then we try and get the shortcode html output via ajax. |
1633
|
|
|
?> |
1634
|
|
|
el('div', { |
1635
|
|
|
dangerouslySetInnerHTML: {__html: onChangeContent()}, |
1636
|
|
|
className: props.className, |
1637
|
|
|
style: {'min-height': '30px'} |
1638
|
|
|
}) |
1639
|
|
|
<?php |
1640
|
|
|
} |
1641
|
|
|
?> |
1642
|
|
|
]; // end return |
1643
|
|
|
}, |
1644
|
|
|
|
1645
|
|
|
// The "save" property must be specified and must be a valid function. |
1646
|
|
|
save: function (props) { |
1647
|
|
|
|
1648
|
|
|
//console.log(props); |
1649
|
|
|
|
1650
|
|
|
|
1651
|
|
|
var attr = props.attributes; |
1652
|
|
|
var align = ''; |
1653
|
|
|
|
1654
|
|
|
// build the shortcode. |
1655
|
|
|
var content = "[<?php echo $this->options['base_id'];?>"; |
1656
|
|
|
<?php |
1657
|
|
|
|
1658
|
|
|
if(! empty( $this->arguments )){ |
1659
|
|
|
foreach($this->arguments as $key => $args){ |
1660
|
|
|
?> |
1661
|
|
|
if (attr.hasOwnProperty("<?php echo esc_attr( $key );?>")) { |
1662
|
|
|
content += " <?php echo esc_attr( $key );?>='" + attr.<?php echo esc_attr( $key );?>+ "' "; |
1663
|
|
|
} |
1664
|
|
|
<?php |
1665
|
|
|
} |
1666
|
|
|
} |
1667
|
|
|
|
1668
|
|
|
?> |
1669
|
|
|
content += "]"; |
1670
|
|
|
|
1671
|
|
|
|
1672
|
|
|
// @todo should we add inline style here or just css classes? |
1673
|
|
|
if (attr.alignment) { |
1674
|
|
|
if (attr.alignment == 'left') { |
1675
|
|
|
align = 'alignleft'; |
1676
|
|
|
} |
1677
|
|
|
if (attr.alignment == 'center') { |
1678
|
|
|
align = 'aligncenter'; |
1679
|
|
|
} |
1680
|
|
|
if (attr.alignment == 'right') { |
1681
|
|
|
align = 'alignright'; |
1682
|
|
|
} |
1683
|
|
|
} |
1684
|
|
|
|
1685
|
|
|
//console.log(content); |
1686
|
|
|
var block_wrap = 'div'; |
1687
|
|
|
if (attr.hasOwnProperty("block_wrap")) { |
1688
|
|
|
block_wrap = attr.block_wrap; |
1689
|
|
|
} |
1690
|
|
|
return el(block_wrap, {dangerouslySetInnerHTML: {__html: content}, className: align}); |
1691
|
|
|
|
1692
|
|
|
} |
1693
|
|
|
}); |
1694
|
|
|
})(); |
1695
|
|
|
</script> |
1696
|
|
|
<?php |
1697
|
|
|
$output = ob_get_clean(); |
1698
|
|
|
|
1699
|
|
|
/* |
1700
|
|
|
* We only add the <script> tags for code highlighting, so we strip them from the output. |
1701
|
|
|
*/ |
1702
|
|
|
|
1703
|
|
|
return str_replace( array( |
1704
|
|
|
'<script>', |
1705
|
|
|
'</script>' |
1706
|
|
|
), '', $output ); |
1707
|
|
|
} |
1708
|
|
|
|
1709
|
|
|
/** |
1710
|
|
|
* Convert an array of attributes to block string. |
1711
|
|
|
* |
1712
|
|
|
* @todo there is prob a faster way to do this, also we could add some validation here. |
1713
|
|
|
* |
1714
|
|
|
* @param $custom_attributes |
1715
|
|
|
* |
1716
|
|
|
* @return string |
1717
|
|
|
*/ |
1718
|
|
|
public function array_to_attributes( $custom_attributes, $html = false ) { |
1719
|
|
|
$attributes = ''; |
1720
|
|
|
if ( ! empty( $custom_attributes ) ) { |
1721
|
|
|
|
1722
|
|
|
if ( $html ) { |
1723
|
|
|
foreach ( $custom_attributes as $key => $val ) { |
1724
|
|
|
$attributes .= " $key='$val' "; |
1725
|
|
|
} |
1726
|
|
|
} else { |
1727
|
|
|
foreach ( $custom_attributes as $key => $val ) { |
1728
|
|
|
$attributes .= "'$key': '$val',"; |
1729
|
|
|
} |
1730
|
|
|
} |
1731
|
|
|
} |
1732
|
|
|
|
1733
|
|
|
return $attributes; |
1734
|
|
|
} |
1735
|
|
|
|
1736
|
|
|
/** |
1737
|
|
|
* A self looping function to create the output for JS block elements. |
1738
|
|
|
* |
1739
|
|
|
* This is what is output in the WP Editor visual view. |
1740
|
|
|
* |
1741
|
|
|
* @param $args |
1742
|
|
|
*/ |
1743
|
|
|
public function block_element( $args ) { |
1744
|
|
|
|
1745
|
|
|
|
1746
|
|
|
if ( ! empty( $args ) ) { |
1747
|
|
|
foreach ( $args as $element => $new_args ) { |
1748
|
|
|
|
1749
|
|
|
if ( is_array( $new_args ) ) { // its an element |
1750
|
|
|
|
1751
|
|
|
|
1752
|
|
|
if ( isset( $new_args['element'] ) ) { |
1753
|
|
|
|
1754
|
|
View Code Duplication |
if ( isset( $new_args['element_require'] ) ) { |
1755
|
|
|
echo str_replace( array( |
1756
|
|
|
"'+", |
1757
|
|
|
"+'" |
1758
|
|
|
), '', $this->block_props_replace( $new_args['element_require'] ) ) . " && "; |
1759
|
|
|
unset( $new_args['element_require'] ); |
1760
|
|
|
} |
1761
|
|
|
|
1762
|
|
|
echo "\n el( '" . $new_args['element'] . "', {"; |
1763
|
|
|
|
1764
|
|
|
// get the attributes |
1765
|
|
|
foreach ( $new_args as $new_key => $new_value ) { |
1766
|
|
|
|
1767
|
|
|
|
1768
|
|
|
if ( $new_key == 'element' || $new_key == 'content' || $new_key == 'element_require' || $new_key == 'element_repeat' || is_array( $new_value ) ) { |
1769
|
|
|
// do nothing |
1770
|
|
|
} else { |
1771
|
|
|
echo $this->block_element( array( $new_key => $new_value ) ); |
1772
|
|
|
} |
1773
|
|
|
} |
1774
|
|
|
|
1775
|
|
|
echo "},";// end attributes |
1776
|
|
|
|
1777
|
|
|
// get the content |
1778
|
|
|
$first_item = 0; |
1779
|
|
|
foreach ( $new_args as $new_key => $new_value ) { |
1780
|
|
|
if ( $new_key === 'content' || is_array( $new_value ) ) { |
1781
|
|
|
|
1782
|
|
|
if ( $new_key === 'content' ) { |
1783
|
|
|
echo "'" . $this->block_props_replace( $new_value ) . "'"; |
1784
|
|
|
} |
1785
|
|
|
|
1786
|
|
|
if ( is_array( $new_value ) ) { |
1787
|
|
|
|
1788
|
|
View Code Duplication |
if ( isset( $new_value['element_require'] ) ) { |
1789
|
|
|
echo str_replace( array( |
1790
|
|
|
"'+", |
1791
|
|
|
"+'" |
1792
|
|
|
), '', $this->block_props_replace( $new_value['element_require'] ) ) . " && "; |
1793
|
|
|
unset( $new_value['element_require'] ); |
1794
|
|
|
} |
1795
|
|
|
|
1796
|
|
|
if ( isset( $new_value['element_repeat'] ) ) { |
1797
|
|
|
$x = 1; |
1798
|
|
|
while ( $x <= absint( $new_value['element_repeat'] ) ) { |
1799
|
|
|
$this->block_element( array( '' => $new_value ) ); |
1800
|
|
|
$x ++; |
1801
|
|
|
} |
1802
|
|
|
} else { |
1803
|
|
|
$this->block_element( array( '' => $new_value ) ); |
1804
|
|
|
} |
1805
|
|
|
} |
1806
|
|
|
$first_item ++; |
1807
|
|
|
} |
1808
|
|
|
} |
1809
|
|
|
|
1810
|
|
|
echo ")";// end content |
1811
|
|
|
|
1812
|
|
|
echo ", \n"; |
1813
|
|
|
|
1814
|
|
|
} |
1815
|
|
|
} else { |
1816
|
|
|
|
1817
|
|
|
if ( substr( $element, 0, 3 ) === "if_" ) { |
1818
|
|
|
echo str_replace( "if_", "", $element ) . ": " . $this->block_props_replace( $new_args, true ) . ","; |
1819
|
|
|
} elseif ( $element == 'style' ) { |
1820
|
|
|
echo $element . ": " . $this->block_props_replace( $new_args ) . ","; |
1821
|
|
|
} else { |
1822
|
|
|
echo $element . ": '" . $this->block_props_replace( $new_args ) . "',"; |
1823
|
|
|
} |
1824
|
|
|
|
1825
|
|
|
} |
1826
|
|
|
} |
1827
|
|
|
} |
1828
|
|
|
} |
1829
|
|
|
|
1830
|
|
|
/** |
1831
|
|
|
* Replace block attributes placeholders with the proper naming. |
1832
|
|
|
* |
1833
|
|
|
* @param $string |
1834
|
|
|
* |
1835
|
|
|
* @return mixed |
1836
|
|
|
*/ |
1837
|
|
|
public function block_props_replace( $string, $no_wrap = false ) { |
1838
|
|
|
|
1839
|
|
|
if ( $no_wrap ) { |
1840
|
|
|
$string = str_replace( array( "[%", "%]" ), array( "props.attributes.", "" ), $string ); |
1841
|
|
|
} else { |
1842
|
|
|
$string = str_replace( array( "[%", "%]" ), array( "'+props.attributes.", "+'" ), $string ); |
1843
|
|
|
} |
1844
|
|
|
|
1845
|
|
|
return $string; |
1846
|
|
|
} |
1847
|
|
|
|
1848
|
|
|
/** |
1849
|
|
|
* Outputs the content of the widget |
1850
|
|
|
* |
1851
|
|
|
* @param array $args |
1852
|
|
|
* @param array $instance |
1853
|
|
|
*/ |
1854
|
|
|
public function widget( $args, $instance ) { |
1855
|
|
|
|
1856
|
|
|
// get the filtered values |
1857
|
|
|
$argument_values = $this->argument_values( $instance ); |
1858
|
|
|
$argument_values = $this->string_to_bool( $argument_values ); |
1859
|
|
|
$output = $this->output( $argument_values, $args ); |
|
|
|
|
1860
|
|
|
|
1861
|
|
|
if ( $output ) { |
1862
|
|
|
// Before widget |
1863
|
|
|
$before_widget = $args['before_widget']; |
1864
|
|
|
$before_widget = apply_filters( 'wp_super_duper_before_widget', $before_widget, $args, $instance, $this ); |
1865
|
|
|
$before_widget = apply_filters( 'wp_super_duper_before_widget_' . $this->base_id, $before_widget, $args, $instance, $this ); |
1866
|
|
|
|
1867
|
|
|
// After widget |
1868
|
|
|
$after_widget = $args['after_widget']; |
1869
|
|
|
$after_widget = apply_filters( 'wp_super_duper_after_widget', $after_widget, $args, $instance, $this ); |
1870
|
|
|
$after_widget = apply_filters( 'wp_super_duper_after_widget_' . $this->base_id, $after_widget, $args, $instance, $this ); |
1871
|
|
|
|
1872
|
|
|
echo $before_widget; |
1873
|
|
|
// elementor strips the widget wrapping div so we check for and add it back if needed |
1874
|
|
|
if ( $this->is_elementor_widget_output() ) { |
1875
|
|
|
echo ! empty( $this->options['widget_ops']['classname'] ) ? "<span class='" . esc_attr( $this->options['widget_ops']['classname'] ) . "'>" : ''; |
1876
|
|
|
} |
1877
|
|
|
echo $this->output_title( $args, $instance ); |
1878
|
|
|
echo $output; |
1879
|
|
|
if ( $this->is_elementor_widget_output() ) { |
1880
|
|
|
echo ! empty( $this->options['widget_ops']['classname'] ) ? "</span>" : ''; |
1881
|
|
|
} |
1882
|
|
|
echo $after_widget; |
1883
|
|
View Code Duplication |
} elseif ( $this->is_preview() && $output == '' ) {// if preview show a placeholder if empty |
1884
|
|
|
$output = $this->preview_placeholder_text( "{{" . $this->base_id . "}}" ); |
1885
|
|
|
echo $output; |
1886
|
|
|
} |
1887
|
|
|
} |
1888
|
|
|
|
1889
|
|
|
/** |
1890
|
|
|
* Tests if the current output is inside a elementor container. |
1891
|
|
|
* |
1892
|
|
|
* @since 1.0.4 |
1893
|
|
|
* @return bool |
1894
|
|
|
*/ |
1895
|
|
|
public function is_elementor_widget_output() { |
1896
|
|
|
$result = false; |
1897
|
|
|
if ( defined( 'ELEMENTOR_VERSION' ) && isset( $this->number ) && $this->number == 'REPLACE_TO_ID' ) { |
1898
|
|
|
$result = true; |
1899
|
|
|
} |
1900
|
|
|
|
1901
|
|
|
return $result; |
1902
|
|
|
} |
1903
|
|
|
|
1904
|
|
|
/** |
1905
|
|
|
* Tests if the current output is inside a elementor preview. |
1906
|
|
|
* |
1907
|
|
|
* @since 1.0.4 |
1908
|
|
|
* @return bool |
1909
|
|
|
*/ |
1910
|
|
View Code Duplication |
public function is_elementor_preview() { |
|
|
|
|
1911
|
|
|
$result = false; |
1912
|
|
|
if ( isset( $_REQUEST['elementor-preview'] ) || ( is_admin() && isset( $_REQUEST['action'] ) && $_REQUEST['action'] == 'elementor' ) || ( isset( $_REQUEST['action'] ) && $_REQUEST['action'] == 'elementor_ajax' ) ) { |
1913
|
|
|
$result = true; |
1914
|
|
|
} |
1915
|
|
|
|
1916
|
|
|
return $result; |
1917
|
|
|
} |
1918
|
|
|
|
1919
|
|
|
/** |
1920
|
|
|
* Tests if the current output is inside a Divi preview. |
1921
|
|
|
* |
1922
|
|
|
* @since 1.0.6 |
1923
|
|
|
* @return bool |
1924
|
|
|
*/ |
1925
|
|
View Code Duplication |
public function is_divi_preview() { |
|
|
|
|
1926
|
|
|
$result = false; |
1927
|
|
|
if ( isset( $_REQUEST['et_fb'] ) || isset( $_REQUEST['et_pb_preview'] ) || ( is_admin() && isset( $_REQUEST['action'] ) && $_REQUEST['action'] == 'elementor' ) ) { |
1928
|
|
|
$result = true; |
1929
|
|
|
} |
1930
|
|
|
|
1931
|
|
|
return $result; |
1932
|
|
|
} |
1933
|
|
|
|
1934
|
|
|
/** |
1935
|
|
|
* Tests if the current output is inside a Beaver builder preview. |
1936
|
|
|
* |
1937
|
|
|
* @since 1.0.6 |
1938
|
|
|
* @return bool |
1939
|
|
|
*/ |
1940
|
|
|
public function is_beaver_preview() { |
1941
|
|
|
$result = false; |
1942
|
|
|
if ( isset( $_REQUEST['fl_builder'] ) ) { |
1943
|
|
|
$result = true; |
1944
|
|
|
} |
1945
|
|
|
|
1946
|
|
|
return $result; |
1947
|
|
|
} |
1948
|
|
|
|
1949
|
|
|
/** |
1950
|
|
|
* Tests if the current output is inside a siteorigin builder preview. |
1951
|
|
|
* |
1952
|
|
|
* @since 1.0.6 |
1953
|
|
|
* @return bool |
1954
|
|
|
*/ |
1955
|
|
|
public function is_siteorigin_preview() { |
1956
|
|
|
$result = false; |
1957
|
|
|
if ( ! empty( $_REQUEST['siteorigin_panels_live_editor'] ) ) { |
1958
|
|
|
$result = true; |
1959
|
|
|
} |
1960
|
|
|
|
1961
|
|
|
return $result; |
1962
|
|
|
} |
1963
|
|
|
|
1964
|
|
|
/** |
1965
|
|
|
* Tests if the current output is inside a cornerstone builder preview. |
1966
|
|
|
* |
1967
|
|
|
* @since 1.0.8 |
1968
|
|
|
* @return bool |
1969
|
|
|
*/ |
1970
|
|
|
public function is_cornerstone_preview() { |
1971
|
|
|
$result = false; |
1972
|
|
|
if ( ! empty( $_REQUEST['cornerstone_preview'] ) || basename( $_SERVER['REQUEST_URI'] ) == 'cornerstone-endpoint' ) { |
1973
|
|
|
$result = true; |
1974
|
|
|
} |
1975
|
|
|
|
1976
|
|
|
return $result; |
1977
|
|
|
} |
1978
|
|
|
|
1979
|
|
|
/** |
1980
|
|
|
* General function to check if we are in a preview situation. |
1981
|
|
|
* |
1982
|
|
|
* @since 1.0.6 |
1983
|
|
|
* @return bool |
1984
|
|
|
*/ |
1985
|
|
|
public function is_preview() { |
1986
|
|
|
$preview = false; |
1987
|
|
|
if ( $this->is_divi_preview() ) { |
1988
|
|
|
$preview = true; |
1989
|
|
|
} elseif ( $this->is_elementor_preview() ) { |
1990
|
|
|
$preview = true; |
1991
|
|
|
} elseif ( $this->is_beaver_preview() ) { |
1992
|
|
|
$preview = true; |
1993
|
|
|
} elseif ( $this->is_siteorigin_preview() ) { |
1994
|
|
|
$preview = true; |
1995
|
|
|
} elseif ( $this->is_cornerstone_preview() ) { |
1996
|
|
|
$preview = true; |
1997
|
|
|
} |
1998
|
|
|
|
1999
|
|
|
return $preview; |
2000
|
|
|
} |
2001
|
|
|
|
2002
|
|
|
/** |
2003
|
|
|
* Output the super title. |
2004
|
|
|
* |
2005
|
|
|
* @param $args |
2006
|
|
|
* @param array $instance |
2007
|
|
|
* |
2008
|
|
|
* @return string |
2009
|
|
|
*/ |
2010
|
|
|
public function output_title( $args, $instance = array() ) { |
2011
|
|
|
$output = ''; |
2012
|
|
|
if ( ! empty( $instance['title'] ) ) { |
2013
|
|
|
/** This filter is documented in wp-includes/widgets/class-wp-widget-pages.php */ |
2014
|
|
|
$title = apply_filters( 'widget_title', $instance['title'], $instance, $this->id_base ); |
2015
|
|
|
$output = $args['before_title'] . $title . $args['after_title']; |
2016
|
|
|
} |
2017
|
|
|
|
2018
|
|
|
return $output; |
2019
|
|
|
} |
2020
|
|
|
|
2021
|
|
|
/** |
2022
|
|
|
* Outputs the options form inputs for the widget. |
2023
|
|
|
* |
2024
|
|
|
* @param array $instance The widget options. |
2025
|
|
|
*/ |
2026
|
|
|
public function form( $instance ) { |
2027
|
|
|
|
2028
|
|
|
// set widget instance |
2029
|
|
|
$this->instance = $instance; |
2030
|
|
|
|
2031
|
|
|
// set it as a SD widget |
2032
|
|
|
echo $this->widget_advanced_toggle(); |
2033
|
|
|
|
2034
|
|
|
echo "<p>" . esc_attr( $this->options['widget_ops']['description'] ) . "</p>"; |
2035
|
|
|
$arguments = $this->get_arguments(); |
2036
|
|
|
|
2037
|
|
|
if ( is_array( $arguments ) ) { |
2038
|
|
|
foreach ( $arguments as $key => $args ) { |
2039
|
|
|
$this->widget_inputs( $args, $instance ); |
2040
|
|
|
} |
2041
|
|
|
} |
2042
|
|
|
} |
2043
|
|
|
|
2044
|
|
|
/** |
2045
|
|
|
* Get the hidden input that when added makes the advanced button show on widget settings. |
2046
|
|
|
* |
2047
|
|
|
* @return string |
2048
|
|
|
*/ |
2049
|
|
|
public function widget_advanced_toggle() { |
2050
|
|
|
|
2051
|
|
|
$output = ''; |
2052
|
|
|
if ( $this->block_show_advanced() ) { |
2053
|
|
|
$val = 1; |
2054
|
|
|
} else { |
2055
|
|
|
$val = 0; |
2056
|
|
|
} |
2057
|
|
|
|
2058
|
|
|
$output .= "<input type='hidden' class='sd-show-advanced' value='$val' />"; |
2059
|
|
|
|
2060
|
|
|
return $output; |
2061
|
|
|
} |
2062
|
|
|
|
2063
|
|
|
/** |
2064
|
|
|
* Convert require element. |
2065
|
|
|
* |
2066
|
|
|
* @since 1.0.0 |
2067
|
|
|
* |
2068
|
|
|
* @param string $input Input element. |
2069
|
|
|
* |
2070
|
|
|
* @return string $output |
2071
|
|
|
*/ |
2072
|
|
|
public function convert_element_require( $input ) { |
2073
|
|
|
|
2074
|
|
|
$input = str_replace( "'", '"', $input );// we only want double quotes |
2075
|
|
|
|
2076
|
|
|
$output = esc_attr( str_replace( array( "[%", "%]" ), array( |
2077
|
|
|
"jQuery(form).find('[data-argument=\"", |
2078
|
|
|
"\"]').find('input,select').val()" |
2079
|
|
|
), $input ) ); |
2080
|
|
|
|
2081
|
|
|
return $output; |
2082
|
|
|
} |
2083
|
|
|
|
2084
|
|
|
/** |
2085
|
|
|
* Builds the inputs for the widget options. |
2086
|
|
|
* |
2087
|
|
|
* @param $args |
2088
|
|
|
* @param $instance |
2089
|
|
|
*/ |
2090
|
|
|
public function widget_inputs( $args, $instance ) { |
2091
|
|
|
|
2092
|
|
|
$class = ""; |
2093
|
|
|
$element_require = ""; |
2094
|
|
|
$custom_attributes = ""; |
2095
|
|
|
|
2096
|
|
|
// get value |
2097
|
|
|
if ( isset( $instance[ $args['name'] ] ) ) { |
2098
|
|
|
$value = $instance[ $args['name'] ]; |
2099
|
|
|
} elseif ( ! isset( $instance[ $args['name'] ] ) && ! empty( $args['default'] ) ) { |
2100
|
|
|
$value = is_array( $args['default'] ) ? array_map( "esc_html", $args['default'] ) : esc_html( $args['default'] ); |
2101
|
|
|
} else { |
2102
|
|
|
$value = ''; |
2103
|
|
|
} |
2104
|
|
|
|
2105
|
|
|
// get placeholder |
2106
|
|
View Code Duplication |
if ( ! empty( $args['placeholder'] ) ) { |
2107
|
|
|
$placeholder = "placeholder='" . esc_html( $args['placeholder'] ) . "'"; |
2108
|
|
|
} else { |
2109
|
|
|
$placeholder = ''; |
2110
|
|
|
} |
2111
|
|
|
|
2112
|
|
|
// get if advanced |
2113
|
|
|
if ( isset( $args['advanced'] ) && $args['advanced'] ) { |
2114
|
|
|
$class .= " sd-advanced-setting "; |
2115
|
|
|
} |
2116
|
|
|
|
2117
|
|
|
// element_require |
2118
|
|
|
if ( isset( $args['element_require'] ) && $args['element_require'] ) { |
2119
|
|
|
$element_require = $args['element_require']; |
2120
|
|
|
} |
2121
|
|
|
|
2122
|
|
|
// custom_attributes |
2123
|
|
|
if ( isset( $args['custom_attributes'] ) && $args['custom_attributes'] ) { |
2124
|
|
|
$custom_attributes = $this->array_to_attributes( $args['custom_attributes'], true ); |
2125
|
|
|
} |
2126
|
|
|
|
2127
|
|
|
// before wrapper |
2128
|
|
|
?> |
2129
|
|
|
<p class="sd-argument <?php echo esc_attr( $class ); ?>" |
2130
|
|
|
data-argument='<?php echo esc_attr( $args['name'] ); ?>' |
2131
|
|
|
data-element_require='<?php if ( $element_require ) { |
2132
|
|
|
echo $this->convert_element_require( $element_require ); |
2133
|
|
|
} ?>' |
2134
|
|
|
> |
2135
|
|
|
<?php |
2136
|
|
|
|
2137
|
|
|
switch ( $args['type'] ) { |
2138
|
|
|
//array('text','password','number','email','tel','url','color') |
2139
|
|
|
case "text": |
2140
|
|
|
case "password": |
2141
|
|
|
case "number": |
2142
|
|
|
case "email": |
2143
|
|
|
case "tel": |
2144
|
|
|
case "url": |
2145
|
|
View Code Duplication |
case "color": |
2146
|
|
|
?> |
2147
|
|
|
<label |
2148
|
|
|
for="<?php echo esc_attr( $this->get_field_id( $args['name'] ) ); ?>"><?php echo esc_attr( $args['title'] ); ?><?php echo $this->widget_field_desc( $args ); ?></label> |
2149
|
|
|
<input <?php echo $placeholder; ?> class="widefat" |
2150
|
|
|
<?php echo $custom_attributes; ?> |
2151
|
|
|
id="<?php echo esc_attr( $this->get_field_id( $args['name'] ) ); ?>" |
2152
|
|
|
name="<?php echo esc_attr( $this->get_field_name( $args['name'] ) ); ?>" |
2153
|
|
|
type="<?php echo esc_attr( $args['type'] ); ?>" |
2154
|
|
|
value="<?php echo esc_attr( $value ); ?>"> |
2155
|
|
|
<?php |
2156
|
|
|
|
2157
|
|
|
break; |
2158
|
|
|
case "select": |
2159
|
|
|
$multiple = isset( $args['multiple'] ) && $args['multiple'] ? true : false; |
2160
|
|
|
if ( $multiple ) { |
2161
|
|
|
if ( empty( $value ) ) { |
2162
|
|
|
$value = array(); |
2163
|
|
|
} |
2164
|
|
|
} |
2165
|
|
|
?> |
2166
|
|
|
<label |
2167
|
|
|
for="<?php echo esc_attr( $this->get_field_id( $args['name'] ) ); ?>"><?php echo esc_attr( $args['title'] ); ?><?php echo $this->widget_field_desc( $args ); ?></label> |
2168
|
|
|
<select <?php echo $placeholder; ?> class="widefat" |
2169
|
|
|
<?php echo $custom_attributes; ?> |
2170
|
|
|
id="<?php echo esc_attr( $this->get_field_id( $args['name'] ) ); ?>" |
2171
|
|
|
name="<?php echo esc_attr( $this->get_field_name( $args['name'] ) ); |
2172
|
|
|
if ( $multiple ) { |
2173
|
|
|
echo "[]"; |
2174
|
|
|
} ?>" |
2175
|
|
|
<?php if ( $multiple ) { |
2176
|
|
|
echo "multiple"; |
2177
|
|
|
} //@todo not implemented yet due to gutenberg not supporting it |
2178
|
|
|
?> |
2179
|
|
|
> |
2180
|
|
|
<?php |
2181
|
|
|
|
2182
|
|
|
if ( ! empty( $args['options'] ) ) { |
2183
|
|
|
foreach ( $args['options'] as $val => $label ) { |
2184
|
|
|
if ( $multiple ) { |
2185
|
|
|
$selected = in_array( $val, $value ) ? 'selected="selected"' : ''; |
2186
|
|
|
} else { |
2187
|
|
|
$selected = selected( $value, $val, false ); |
2188
|
|
|
} |
2189
|
|
|
echo "<option value='$val' " . $selected . ">$label</option>"; |
2190
|
|
|
} |
2191
|
|
|
} |
2192
|
|
|
?> |
2193
|
|
|
</select> |
2194
|
|
|
<?php |
2195
|
|
|
break; |
2196
|
|
View Code Duplication |
case "checkbox": |
2197
|
|
|
?> |
2198
|
|
|
<input <?php echo $placeholder; ?> |
2199
|
|
|
<?php checked( 1, $value, true ) ?> |
2200
|
|
|
<?php echo $custom_attributes; ?> |
2201
|
|
|
class="widefat" id="<?php echo esc_attr( $this->get_field_id( $args['name'] ) ); ?>" |
2202
|
|
|
name="<?php echo esc_attr( $this->get_field_name( $args['name'] ) ); ?>" type="checkbox" |
2203
|
|
|
value="1"> |
2204
|
|
|
<label |
2205
|
|
|
for="<?php echo esc_attr( $this->get_field_id( $args['name'] ) ); ?>"><?php echo esc_attr( $args['title'] ); ?><?php echo $this->widget_field_desc( $args ); ?></label> |
2206
|
|
|
<?php |
2207
|
|
|
break; |
2208
|
|
|
case "hidden": |
2209
|
|
|
?> |
2210
|
|
|
<input id="<?php echo esc_attr( $this->get_field_id( $args['name'] ) ); ?>" |
2211
|
|
|
name="<?php echo esc_attr( $this->get_field_name( $args['name'] ) ); ?>" type="hidden" |
2212
|
|
|
value="<?php echo esc_attr( $value ); ?>"> |
2213
|
|
|
<?php |
2214
|
|
|
break; |
2215
|
|
|
default: |
2216
|
|
|
echo "No input type found!"; // @todo we need to add more input types. |
2217
|
|
|
} |
2218
|
|
|
|
2219
|
|
|
// after wrapper |
2220
|
|
|
?> |
2221
|
|
|
</p> |
2222
|
|
|
<?php |
2223
|
|
|
|
2224
|
|
|
} |
2225
|
|
|
|
2226
|
|
|
/** |
2227
|
|
|
* Get the widget input description html. |
2228
|
|
|
* |
2229
|
|
|
* @param $args |
2230
|
|
|
* |
2231
|
|
|
* @return string |
2232
|
|
|
* @todo, need to make its own tooltip script |
2233
|
|
|
*/ |
2234
|
|
|
public function widget_field_desc( $args ) { |
2235
|
|
|
|
2236
|
|
|
$description = ''; |
2237
|
|
|
if ( isset( $args['desc'] ) && $args['desc'] ) { |
2238
|
|
|
if ( isset( $args['desc_tip'] ) && $args['desc_tip'] ) { |
2239
|
|
|
$description = $this->desc_tip( $args['desc'] ); |
2240
|
|
|
} else { |
2241
|
|
|
$description = '<span class="description">' . wp_kses_post( $args['desc'] ) . '</span>'; |
2242
|
|
|
} |
2243
|
|
|
} |
2244
|
|
|
|
2245
|
|
|
return $description; |
2246
|
|
|
} |
2247
|
|
|
|
2248
|
|
|
/** |
2249
|
|
|
* Get the tool tip html. |
2250
|
|
|
* |
2251
|
|
|
* @param $tip |
2252
|
|
|
* @param bool $allow_html |
2253
|
|
|
* |
2254
|
|
|
* @return string |
2255
|
|
|
*/ |
2256
|
|
|
function desc_tip( $tip, $allow_html = false ) { |
|
|
|
|
2257
|
|
|
if ( $allow_html ) { |
2258
|
|
|
$tip = $this->sanitize_tooltip( $tip ); |
2259
|
|
|
} else { |
2260
|
|
|
$tip = esc_attr( $tip ); |
2261
|
|
|
} |
2262
|
|
|
|
2263
|
|
|
return '<span class="gd-help-tip dashicons dashicons-editor-help" title="' . $tip . '"></span>'; |
2264
|
|
|
} |
2265
|
|
|
|
2266
|
|
|
/** |
2267
|
|
|
* Sanitize a string destined to be a tooltip. |
2268
|
|
|
* |
2269
|
|
|
* @param string $var |
2270
|
|
|
* |
2271
|
|
|
* @return string |
2272
|
|
|
*/ |
2273
|
|
|
public function sanitize_tooltip( $var ) { |
2274
|
|
|
return htmlspecialchars( wp_kses( html_entity_decode( $var ), array( |
2275
|
|
|
'br' => array(), |
2276
|
|
|
'em' => array(), |
2277
|
|
|
'strong' => array(), |
2278
|
|
|
'small' => array(), |
2279
|
|
|
'span' => array(), |
2280
|
|
|
'ul' => array(), |
2281
|
|
|
'li' => array(), |
2282
|
|
|
'ol' => array(), |
2283
|
|
|
'p' => array(), |
2284
|
|
|
) ) ); |
2285
|
|
|
} |
2286
|
|
|
|
2287
|
|
|
/** |
2288
|
|
|
* Processing widget options on save |
2289
|
|
|
* |
2290
|
|
|
* @param array $new_instance The new options |
2291
|
|
|
* @param array $old_instance The previous options |
2292
|
|
|
* |
2293
|
|
|
* @return array |
2294
|
|
|
* @todo we should add some sanitation here. |
2295
|
|
|
*/ |
2296
|
|
|
public function update( $new_instance, $old_instance ) { |
2297
|
|
|
|
2298
|
|
|
//save the widget |
2299
|
|
|
$instance = array_merge( (array) $old_instance, (array) $new_instance ); |
2300
|
|
|
|
2301
|
|
|
// set widget instance |
2302
|
|
|
$this->instance = $instance; |
2303
|
|
|
|
2304
|
|
|
if ( empty( $this->arguments ) ) { |
2305
|
|
|
$this->get_arguments(); |
2306
|
|
|
} |
2307
|
|
|
|
2308
|
|
|
// check for checkboxes |
2309
|
|
|
if ( ! empty( $this->arguments ) ) { |
2310
|
|
|
foreach ( $this->arguments as $argument ) { |
2311
|
|
|
if ( isset( $argument['type'] ) && $argument['type'] == 'checkbox' && ! isset( $new_instance[ $argument['name'] ] ) ) { |
2312
|
|
|
$instance[ $argument['name'] ] = '0'; |
2313
|
|
|
} |
2314
|
|
|
} |
2315
|
|
|
} |
2316
|
|
|
|
2317
|
|
|
return $instance; |
2318
|
|
|
} |
2319
|
|
|
|
2320
|
|
|
/** |
2321
|
|
|
* Checks if the current call is a ajax call to get the block content. |
2322
|
|
|
* |
2323
|
|
|
* This can be used in your widget to return different content as the block content. |
2324
|
|
|
* |
2325
|
|
|
* @since 1.0.3 |
2326
|
|
|
* @return bool |
2327
|
|
|
*/ |
2328
|
|
|
public function is_block_content_call() { |
2329
|
|
|
$result = false; |
2330
|
|
|
if ( wp_doing_ajax() && isset( $_REQUEST['action'] ) && $_REQUEST['action'] == 'super_duper_output_shortcode' ) { |
2331
|
|
|
$result = true; |
2332
|
|
|
} |
2333
|
|
|
|
2334
|
|
|
return $result; |
2335
|
|
|
} |
2336
|
|
|
|
2337
|
|
|
} |
2338
|
|
|
|
2339
|
|
|
} |
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.