PluginProbe
Cool Timeline (Horizontal & Vertical Timeline) / trunk
Cool Timeline (Horizontal & Vertical Timeline) vtrunk
3.4.0 3.3.6 3.3.5 3.3.4 3.3.3 3.3.2 2.2.3 2.3.3 2.4 2.4.1 2.4.2 2.4.3 2.4.4 2.4.5 2.6.1 2.7.1 2.8.3 2.9.3 2.9.4 2.9.5 2.9.6 2.9.7 2.9.8 2.9.9 3.0.0 All 79 releases
cool-timeline / admin / codestar-framework / classes / shortcode-options.class.php

shortcode-options.class.php in Cool Timeline (Horizontal & Vertical Timeline) trunk, at admin/codestar-framework/classes/shortcode-options.class.php

394 lines 14.8 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php if ( ! defined( 'ABSPATH' ) ) { die; } // Cannot access directly.
2 /**
3 *
4 * Shortcoder Class
5 *
6 * @since 1.0.0
7 * @version 1.0.0
8 *
9 */
10 if ( ! class_exists( 'CSF_Shortcoder' ) ) {
11 // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedClassFound
12 class CSF_Shortcoder extends CSF_Abstract{
13
14 // constans
15 public $unique = '';
16 public $abstract = 'shortcoder';
17 public $blocks = array();
18 public $sections = array();
19 public $pre_tabs = array();
20 public $pre_sections = array();
21 public $args = array(
22 'button_title' => 'Add Shortcode',
23 'select_title' => 'Select a shortcode',
24 'insert_title' => 'Insert Shortcode',
25 'show_in_editor' => true,
26 'show_in_custom' => false,
27 'defaults' => array(),
28 'class' => '',
29 'gutenberg' => array(
30 'title' => 'CSF Shortcodes',
31 'description' => 'CSF Shortcode Block',
32 'icon' => 'screenoptions',
33 'category' => 'widgets',
34 'keywords' => array( 'shortcode', 'csf', 'insert' ),
35 'placeholder' => 'Write shortcode here...',
36 ),
37 );
38
39 // run shortcode construct
40 public function __construct( $key, $params = array() ) {
41
42 $this->unique = $key;
43 // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound
44 $this->args = apply_filters( "csf_{$this->unique}_args", wp_parse_args( $params['args'], $this->args ), $this );
45 // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound
46 $this->sections = apply_filters( "csf_{$this->unique}_sections", $params['sections'], $this );
47 $this->pre_tabs = $this->pre_tabs( $this->sections );
48 $this->pre_sections = $this->pre_sections( $this->sections );
49
50 add_action( 'admin_footer', array( $this, 'add_footer_modal_shortcode' ) );
51 add_action( 'customize_controls_print_footer_scripts', array( $this, 'add_footer_modal_shortcode' ) );
52 add_action( 'wp_ajax_csf-get-shortcode-'. $this->unique, array( $this, 'get_shortcode' ) );
53
54 if ( ! empty( $this->args['show_in_editor'] ) ) {
55
56 $name = str_replace( '_', '-', sanitize_title( $this->unique ) );
57
58 CSF::$shortcode_instances[] = wp_parse_args( array( 'name' => 'csf/'. $name, 'modal_id' => $this->unique ), $this->args );
59
60 // elementor editor support
61 if ( CSF::is_active_plugin( 'elementor/elementor.php' ) ) {
62 add_action( 'elementor/editor/before_enqueue_scripts', array( 'CSF', 'add_admin_enqueue_scripts' ) );
63 add_action( 'elementor/editor/footer', array( 'CSF_Field_icon', 'add_footer_modal_icon' ) );
64 add_action( 'elementor/editor/footer', array( $this, 'add_footer_modal_shortcode' ) );
65 }
66
67 }
68
69 }
70
71 // instance
72 public static function instance( $key, $params = array() ) {
73 return new self( $key, $params );
74 }
75
76 public function pre_tabs( $sections ) {
77
78 $result = array();
79 $parents = array();
80 $count = 100;
81
82 foreach ( $sections as $key => $section ) {
83 if ( ! empty( $section['parent'] ) ) {
84 $section['priority'] = ( isset( $section['priority'] ) ) ? $section['priority'] : $count;
85 $parents[$section['parent']][] = $section;
86 unset( $sections[$key] );
87 }
88 $count++;
89 }
90
91 foreach ( $sections as $key => $section ) {
92 $section['priority'] = ( isset( $section['priority'] ) ) ? $section['priority'] : $count;
93 if ( ! empty( $section['id'] ) && ! empty( $parents[$section['id']] ) ) {
94 $section['subs'] = wp_list_sort( $parents[$section['id']], array( 'priority' => 'ASC' ), 'ASC', true );
95 }
96 $result[] = $section;
97 $count++;
98 }
99
100 return wp_list_sort( $result, array( 'priority' => 'ASC' ), 'ASC', true );
101 }
102
103 public function pre_sections( $sections ) {
104
105 $result = array();
106
107 foreach ( $this->pre_tabs as $tab ) {
108 if ( ! empty( $tab['subs'] ) ) {
109 foreach ( $tab['subs'] as $sub ) {
110 $result[] = $sub;
111 }
112 }
113 if ( empty( $tab['subs'] ) ) {
114 $result[] = $tab;
115 }
116 }
117
118 return $result;
119 }
120
121 // get default value
122 public function get_default( $field ) {
123
124 $default = ( isset( $field['default'] ) ) ? $field['default'] : '';
125 $default = ( isset( $this->args['defaults'][$field['id']] ) ) ? $this->args['defaults'][$field['id']] : $default;
126
127 return $default;
128
129 }
130
131 public function add_footer_modal_shortcode() {
132
133 if( ! wp_script_is( 'csf' ) ) {
134 return;
135 }
136
137 $class = ( $this->args['class'] ) ? ' '. esc_attr( $this->args['class'] ) : '';
138 $has_select = ( count( $this->pre_tabs ) > 1 ) ? true : false;
139 $single_usage = ( ! $has_select ) ? ' csf-shortcode-single' : '';
140 $hide_header = ( ! $has_select ) ? ' hidden' : '';
141
142 ?>
143 <div id="csf-modal-<?php echo esc_attr( $this->unique ); ?>" class="wp-core-ui csf-modal csf-shortcode hidden<?php echo esc_attr( $single_usage . $class ); ?>" data-modal-id="<?php echo esc_attr( $this->unique ); ?>" data-nonce="<?php echo esc_attr( wp_create_nonce( 'csf_shortcode_nonce' ) ); ?>">
144 <div class="csf-modal-table">
145 <div class="csf-modal-table-cell">
146 <div class="csf-modal-overlay"></div>
147 <div class="csf-modal-inner">
148 <div class="csf-modal-title">
149 <?php // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
150 <?php echo $this->args['button_title']; ?>
151 <div class="csf-modal-close"></div>
152 </div>
153 <?php
154
155 echo '<div class="csf-modal-header'. esc_attr( $hide_header ) .'">';
156 echo '<select>';
157 echo ( $has_select ) ? '<option value="">'. esc_attr( $this->args['select_title'] ) .'</option>' : '';
158
159 $tab_key = 1;
160
161 foreach ( $this->pre_tabs as $tab ) {
162
163 if ( ! empty( $tab['subs'] ) ) {
164
165 echo '<optgroup label="'. esc_attr( $tab['title'] ) .'">';
166
167 foreach ( $tab['subs'] as $sub ) {
168
169 $view = ( ! empty( $sub['view'] ) ) ? ' data-view="'. esc_attr( $sub['view'] ) .'"' : '';
170 $shortcode = ( ! empty( $sub['shortcode'] ) ) ? ' data-shortcode="'. esc_attr( $sub['shortcode'] ) .'"' : '';
171 $group = ( ! empty( $sub['group_shortcode'] ) ) ? ' data-group="'. esc_attr( $sub['group_shortcode'] ) .'"' : '';
172
173 // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
174 echo '<option value="'. esc_attr( $tab_key ) .'"'. $view . $shortcode . $group .'>'. esc_attr( $sub['title'] ) .'</option>';
175
176 $tab_key++;
177
178 }
179
180 echo '</optgroup>' ;
181
182 } else {
183
184 $view = ( ! empty( $tab['view'] ) ) ? ' data-view="'. esc_attr( $tab['view'] ) .'"' : '';
185 $shortcode = ( ! empty( $tab['shortcode'] ) ) ? ' data-shortcode="'. esc_attr( $tab['shortcode'] ) .'"' : '';
186 $group = ( ! empty( $tab['group_shortcode'] ) ) ? ' data-group="'. esc_attr( $tab['group_shortcode'] ) .'"' : '';
187
188 // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
189 echo '<option value="'. esc_attr( $tab_key ) .'"'. $view . $shortcode . $group .'>'. esc_attr( $tab['title'] ) .'</option>';
190
191 $tab_key++;
192
193 }
194
195 }
196
197 echo '</select>';
198 echo '</div>';
199
200 ?>
201 <div class="csf-modal-content">
202 <div class="csf-modal-loading"><div class="csf-loading"></div></div>
203 <div class="csf-modal-load"></div>
204 </div>
205 <div class="csf-modal-insert-wrapper hidden"><a href="#" class="button button-primary csf-modal-insert"><?php // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?><?php echo $this->args['insert_title']; ?></a></div>
206 </div>
207 </div>
208 </div>
209 </div>
210 <?php
211 }
212
213 public function get_shortcode() {
214
215 // Check user capabilities
216 if ( ! current_user_can( 'manage_options' ) ) {
217 // phpcs:ignore WordPress.WP.I18n.TextDomainMismatch
218 return wp_send_json_error( array( 'error' => esc_html__( 'Unauthorized access.', 'csf' ) ) );
219
220 }
221
222 ob_start();
223
224 $nonce = ( ! empty( $_POST[ 'nonce' ] ) ) ? sanitize_text_field( wp_unslash( $_POST[ 'nonce' ] ) ) : '';
225 $shortcode_key = ( ! empty( $_POST[ 'shortcode_key' ] ) ) ? sanitize_text_field( wp_unslash( $_POST[ 'shortcode_key' ] ) ) : '';
226
227 if ( ! empty( $shortcode_key ) && wp_verify_nonce( $nonce, 'csf_shortcode_nonce' ) ) {
228
229 $unallows = array( 'group', 'repeater', 'sorter' );
230 $section = $this->pre_sections[$shortcode_key-1];
231 $shortcode = ( ! empty( $section['shortcode'] ) ) ? $section['shortcode'] : '';
232 $view = ( ! empty( $section['view'] ) ) ? $section['view'] : 'normal';
233
234 if ( ! empty( $section ) ) {
235
236 //
237 // View: normal
238 if ( ! empty( $section['fields'] ) && $view !== 'repeater' ) {
239
240 echo '<div class="csf-fields">';
241
242 // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
243 echo ( ! empty( $section['description'] ) ) ? '<div class="csf-field csf-section-description">'. $section['description'] .'</div>' : '';
244
245 foreach ( $section['fields'] as $field ) {
246
247 if ( in_array( $field['type'], $unallows ) ) { $field['_notice'] = true; }
248
249 // Extra tag improves for spesific fields (border, spacing, dimensions etc...)
250 $field['tag_prefix'] = ( ! empty( $field['tag_prefix'] ) ) ? $field['tag_prefix'] .'_' : '';
251
252 $field_default = ( isset( $field['id'] ) ) ? $this->get_default( $field ) : '';
253
254 CSF::field( $field, $field_default, $shortcode, 'shortcode' );
255
256 }
257
258 echo '</div>';
259
260 }
261
262 //
263 // View: group and repeater fields
264 $repeatable_fields = ( $view === 'repeater' && ! empty( $section['fields'] ) ) ? $section['fields'] : array();
265 $repeatable_fields = ( $view === 'group' && ! empty( $section['group_fields'] ) ) ? $section['group_fields'] : $repeatable_fields;
266
267 if ( ! empty( $repeatable_fields ) ) {
268
269 // phpcs:ignore WordPress.WP.I18n.TextDomainMismatch
270 $button_title = ( ! empty( $section['button_title'] ) ) ? ' '. $section['button_title'] : esc_html__( 'Add New', 'csf' );
271 $inner_shortcode = ( ! empty( $section['group_shortcode'] ) ) ? $section['group_shortcode'] : $shortcode;
272
273 echo '<div class="csf--repeatable">';
274
275 echo '<div class="csf--repeat-shortcode">';
276
277 echo '<div class="csf-repeat-remove fas fa-times"></div>';
278
279 echo '<div class="csf-fields">';
280
281 foreach ( $repeatable_fields as $field ) {
282
283 if ( in_array( $field['type'], $unallows ) ) { $field['_notice'] = true; }
284
285 // Extra tag improves for spesific fields (border, spacing, dimensions etc...)
286 $field['tag_prefix'] = ( ! empty( $field['tag_prefix'] ) ) ? $field['tag_prefix'] .'_' : '';
287
288 $field_default = ( isset( $field['id'] ) ) ? $this->get_default( $field ) : '';
289
290 CSF::field( $field, $field_default, $inner_shortcode.'[0]', 'shortcode' );
291
292 }
293
294 echo '</div>';
295
296 echo '</div>';
297
298 echo '</div>';
299
300 // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
301 echo '<div class="csf--repeat-button-block"><a class="button csf--repeat-button" href="#"><i class="fas fa-plus-circle"></i> '. $button_title .'</a></div>';
302
303 }
304
305 }
306
307 } else {
308 // phpcs:ignore WordPress.WP.I18n.TextDomainMismatch
309 echo '<div class="csf-field csf-error-text">'. esc_html__( 'Error: Invalid nonce verification.', 'csf' ) .'</div>';
310 }
311
312 wp_send_json_success( array( 'content' => ob_get_clean() ) );
313
314 }
315
316 // Once editor setup for gutenberg and media buttons
317 public static function once_editor_setup() {
318
319 if ( function_exists( 'register_block_type' ) ) {
320 add_action( 'enqueue_block_editor_assets', array( 'CSF_Shortcoder', 'add_guteberg_blocks' ) );
321 add_action( 'enqueue_block_assets', array( 'CSF_Shortcoder', 'add_gutenberg_block_assets' ) );
322 }
323
324 if ( csf_wp_editor_api() ) {
325 add_action( 'media_buttons', array( 'CSF_Shortcoder', 'add_media_buttons' ) );
326 }
327
328 }
329
330 // Add gutenberg blocks.
331 public static function add_guteberg_blocks() {
332
333 self::enqueue_gutenberg_styles();
334
335 $depends = array( 'wp-blocks', 'wp-element', 'wp-components' );
336
337 if ( wp_script_is( 'wp-edit-widgets' ) ) {
338 $depends[] = 'wp-edit-widgets';
339 } else {
340 $depends[] = 'wp-edit-post';
341 }
342
343 // phpcs:ignore WordPress.WP.EnqueuedResourceParameters.MissingVersion,WordPress.WP.EnqueuedResourceParameters.NotInFooter
344 wp_enqueue_script( 'csf-gutenberg-block', CSF::include_plugin_url( 'assets/js/gutenberg.js' ), $depends ); // phpcs:ignore WordPress.WP.EnqueuedResourceParameters.MissingVersion,WordPress.WP.EnqueuedResourceParameters.NotInFooter
345
346 wp_localize_script( 'csf-gutenberg-block', 'csf_gutenberg_blocks', CSF::$shortcode_instances );
347
348 foreach ( CSF::$shortcode_instances as $block ) {
349
350 register_block_type( $block['name'], array(
351 'editor_script' => 'csf-gutenberg-block',
352 ) );
353
354 }
355
356 }
357
358 // Enqueue shared framework styles inside the iframe editor canvas.
359 public static function add_gutenberg_block_assets() {
360
361 if ( ! is_admin() ) {
362 return;
363 }
364
365 self::enqueue_gutenberg_styles();
366
367 }
368
369 // Shared Gutenberg editor styles.
370 private static function enqueue_gutenberg_styles() {
371
372 $min = ( CSF::$premium && SCRIPT_DEBUG ) ? '' : '.min';
373
374 wp_enqueue_style( 'csf', CSF::include_plugin_url( 'assets/css/style'. $min .'.css' ), array(), CSF::$version, 'all' );
375
376 if ( is_rtl() ) {
377 wp_enqueue_style( 'csf-rtl', CSF::include_plugin_url( 'assets/css/style-rtl'. $min .'.css' ), array(), CSF::$version, 'all' );
378 }
379
380 }
381
382 // Add media buttons
383 public static function add_media_buttons( $editor_id ) {
384
385 foreach ( CSF::$shortcode_instances as $value ) {
386 // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
387 echo '<a href="#" class="button button-primary csf-shortcode-button" data-editor-id="'. esc_attr( $editor_id ) .'" data-modal-id="'. esc_attr( $value['modal_id'] ) .'">'. $value['button_title'] .'</a>';
388 }
389
390 }
391
392 }
393 }
394