PluginProbe ʕ •ᴥ•ʔ
Shortcoder — Create Shortcodes for Anything / trunk
Shortcoder — Create Shortcodes for Anything vtrunk
6.5.4 trunk 3.0 3.0.1 3.1 3.2 3.3 3.4 3.4.1 4.0 4.0.1 4.0.2 4.0.3 4.1 4.1.1 4.1.2 4.1.3 4.1.4 4.1.5 4.1.6 4.1.7 4.1.8 4.1.9 4.2 4.3 4.4 4.5 4.6 5.0 5.0.1 5.0.2 5.0.3 5.0.4 5.1 5.2 5.2.1 5.3 5.3.1 5.3.2 5.3.3 5.3.4 5.4 5.5 5.6 5.7 5.8 6.0 6.1 6.2 6.3 6.3.1 6.3.2 6.4 6.5 6.5.1 6.5.2 6.5.3
shortcoder / shortcoder.php
shortcoder Last commit date
admin 4 weeks ago includes 4 weeks ago languages 4 weeks ago readme.txt 4 weeks ago shortcoder.php 4 weeks ago
shortcoder.php
451 lines
1 <?php
2 /*
3 Plugin Name: Shortcoder
4 Plugin URI: https://www.aakashweb.com/wordpress-plugins/shortcoder/
5 Description: Shortcoder plugin allows to create a custom shortcodes for HTML, JavaScript and other snippets. Now the shortcodes can be used in posts/pages and the snippet will be replaced in place.
6 Author: Aakash Chakravarthy
7 Version: 6.5.4
8 Author URI: https://www.aakashweb.com/
9 Text Domain: shortcoder
10 Domain Path: /languages
11 */
12
13 define( 'SC_VERSION', '6.5.4' );
14 define( 'SC_PATH', plugin_dir_path( __FILE__ ) ); // All have trailing slash
15 define( 'SC_URL', plugin_dir_url( __FILE__ ) );
16 define( 'SC_ADMIN_URL', trailingslashit( plugin_dir_url( __FILE__ ) . 'admin' ) );
17 define( 'SC_BASE_NAME', plugin_basename( __FILE__ ) );
18 define( 'SC_POST_TYPE', 'shortcoder' );
19
20 // error_reporting(E_ALL);
21
22 final class Shortcoder{
23
24 static public $shortcodes = array();
25
26 static public $current_shortcode = false;
27
28 public static function init(){
29
30 // Include the required
31 self::includes();
32
33 add_shortcode( 'sc', array( __CLASS__, 'execute_shortcode' ) );
34
35 }
36
37 public static function includes(){
38
39 include_once( SC_PATH . 'includes/updates.php' );
40 include_once( SC_PATH . 'includes/metadata.php' );
41 include_once( SC_PATH . 'admin/admin.php' );
42 include_once( SC_PATH . 'admin/form.php' );
43 include_once( SC_PATH . 'admin/edit.php' );
44 include_once( SC_PATH . 'admin/settings.php' );
45 include_once( SC_PATH . 'admin/manage.php' );
46 include_once( SC_PATH . 'admin/tools.php' );
47
48 }
49
50 public static function execute_shortcode( $atts, $enclosed_content = null ){
51
52 $atts = (array) $atts;
53 $shortcodes = self::get_shortcodes();
54
55 if( empty( $shortcodes ) ){
56 return '<!-- No shortcodes are defined -->';
57 }
58
59 $shortcode = self::find_shortcode( $atts, $shortcodes );
60
61 $shortcode = apply_filters( 'sc_mod_shortcode', $shortcode, $atts, $enclosed_content );
62 do_action( 'sc_do_before', $shortcode, $atts );
63
64 if( !is_array( $shortcode ) ){
65 return $shortcode;
66 }
67
68 // Prevent same shortcode nested loop
69 if( self::$current_shortcode == $shortcode[ 'name' ] ){
70 return '';
71 }
72 self::$current_shortcode = $shortcode[ 'name' ];
73
74 $sc_content = $shortcode[ 'content' ];
75 $sc_settings = $shortcode[ 'settings' ];
76
77 if( !self::can_display( $shortcode ) ){
78 $sc_content = sprintf( '<!-- Shortcode [%s] does not match the conditions -->', self::$current_shortcode );
79 }else{
80 $sc_content = self::replace_sc_params( $sc_content, $atts );
81 $sc_content = self::replace_wp_params( $sc_content, $enclosed_content );
82 $sc_content = self::replace_custom_fields( $sc_content );
83 $sc_content = self::process_content( $sc_content, $sc_settings );
84 }
85
86 $sc_content = apply_filters( 'sc_mod_output', $sc_content, $atts, $sc_settings, $enclosed_content );
87 do_action( 'sc_do_after', $shortcode, $atts );
88
89 self::$current_shortcode = false;
90
91 return $sc_content;
92
93 }
94
95 public static function get_shortcodes(){
96
97 if( !empty( self::$shortcodes ) ){
98 return self::$shortcodes;
99 }
100
101 $shortcodes = array();
102 $shortcode_posts = get_posts(array(
103 'post_type' => SC_POST_TYPE,
104 'posts_per_page' => -1,
105 'post_status' => 'publish'
106 ));
107
108 foreach( $shortcode_posts as $index => $post ){
109 $shortcodes[ $post->post_name ] = array(
110 'id' => $post->ID,
111 'name' => $post->post_name,
112 'content' => $post->post_content,
113 'settings' => self::get_sc_settings( $post->ID )
114 );
115 }
116
117 self::$shortcodes = $shortcodes;
118
119 return $shortcodes;
120
121 }
122
123 public static function default_sc_settings(){
124
125 return apply_filters( 'sc_mod_sc_settings', array(
126 '_sc_description' => '',
127 '_sc_disable_sc' => 'no',
128 '_sc_disable_admin' => 'no',
129 '_sc_editor' => '',
130 '_sc_allowed_devices' => 'all',
131 '_sc_execute_blocks' => 'no'
132 ));
133
134 }
135
136 public static function default_settings(){
137
138 return apply_filters( 'sc_mod_settings', array(
139 'default_editor' => 'code',
140 'default_content' => '',
141 'list_content' => 'no',
142 'sanitize_custom_parameters' => 'yes',
143 'sanitize_custom_fields' => 'yes'
144 ));
145
146 }
147
148 public static function get_settings(){
149
150 $settings = get_option( 'sc_settings', array() );
151 $default_settings = self::default_settings();
152
153 return self::set_defaults( $settings, $default_settings );
154
155 }
156
157 public static function get_sc_settings( $post_id ){
158
159 $meta_vals = get_post_meta( $post_id, '', true );
160 $default_vals = self::default_sc_settings();
161 $settings = array();
162
163 if( !is_array( $meta_vals ) ){
164 return $default_vals;
165 }
166
167 foreach( $default_vals as $key => $val ){
168 $settings[ $key ] = array_key_exists( $key, $meta_vals ) ? $meta_vals[$key][0] : $val;
169 }
170
171 $settings[ '_sc_title' ] = get_the_title( $post_id );
172
173 return $settings;
174
175 }
176
177 public static function get_sc_tag( $post_id ){
178 $post = get_post( $post_id );
179 return '[sc name="' . $post->post_name . '"][/sc]';
180 }
181
182 public static function find_shortcode( $atts, $shortcodes ){
183
184 $sc_name = false;
185
186 // Find by shortcode ID
187 if( array_key_exists( 'sc_id', $atts ) ){
188 $sc_id = $atts[ 'sc_id' ];
189 foreach( $shortcodes as $temp_name => $temp_props ){
190 if( $temp_props[ 'id' ] == $sc_id ){
191 $sc_name = $temp_name;
192 break;
193 }
194 }
195 }
196
197 // If shortcode ID is not passed, then get the shortcode name
198 if( !$sc_name ){
199 if( !array_key_exists( 'name', $atts ) ){
200 return '<!-- Shortcode is missing "name" attribute -->';
201 }
202 $sc_name = $atts[ 'name' ];
203 }
204
205 // Check if the shortcode name exists
206 if( !array_key_exists( $sc_name, $shortcodes ) ){
207 $sc_name = sanitize_title_with_dashes( $sc_name );
208 if( !array_key_exists( $sc_name, $shortcodes ) ){
209 return sprintf( '<!-- Shortcode [%s] does not exist -->', $sc_name );
210 }
211 }
212
213 return $shortcodes[ $sc_name ];
214
215 }
216
217 public static function can_display( $sc_props ){
218
219 $settings = $sc_props['settings'];
220
221 if( $settings[ '_sc_disable_sc' ] == 'yes' ){
222 return false;
223 }
224
225 $devices = $settings[ '_sc_allowed_devices' ];
226
227 if( $devices == 'mobile_only' && !wp_is_mobile() ){
228 return false;
229 }
230
231 if( $devices == 'desktop_only' && wp_is_mobile() ){
232 return false;
233 }
234
235 if( current_user_can( 'manage_options' ) && $settings[ '_sc_disable_admin' ] == 'yes' ){
236 return false;
237 }
238
239 return true;
240
241 }
242
243 public static function replace_sc_params( $content, $params ){
244
245 $params = array_change_key_case( $params, CASE_LOWER );
246 $general_settings = self::get_settings();
247
248 preg_match_all('/%%([a-zA-Z0-9_\-]+)\:?(.*?)%%/', $content, $matches);
249
250 $cp_tags = $matches[0];
251 $cp_names = $matches[1];
252 $cp_defaults = $matches[2];
253 $to_replace = array();
254
255 for( $i = 0; $i < count( $cp_names ); $i++ ){
256
257 $name = strtolower( $cp_names[ $i ] );
258 $default = $cp_defaults[ $i ];
259 $value = '';
260
261 if( array_key_exists( $name, $params ) ){
262 $value = $params[ $name ];
263
264 // Handle scenario when the attributes are added with paragraph tags by autop
265 if( substr( $value, 0, 4 ) == '</p>' ){
266 $value = substr( $value, 4 );
267 if( substr( $value, -3 ) == '<p>' ){
268 $value = substr( $value, 0, -3 );
269 }
270 }
271
272 if ( isset( $general_settings[ 'sanitize_custom_parameters' ] ) && $general_settings[ 'sanitize_custom_parameters' ] === 'yes' ) {
273 $value = wp_kses_post( $value );
274 }
275
276 }
277
278 if( $value == '' ){
279 array_push( $to_replace, $default );
280 }else{
281 array_push( $to_replace, $value );
282 }
283
284 }
285
286 $content = str_ireplace( $cp_tags, $to_replace, $content );
287
288 return $content;
289
290 }
291
292 public static function replace_wp_params( $content, $enc_content = null ){
293
294 $params = self::wp_params_list();
295 $metadata = Shortcoder_Metadata::metadata();
296 $metadata[ 'enclosed_content' ] = $enc_content;
297 $all_params = array();
298 $to_replace = array();
299
300 foreach( $params as $group => $group_info ){
301 $all_params = array_merge( $group_info[ 'params' ], $all_params );
302 }
303
304 foreach( $all_params as $id => $name ){
305 if( array_key_exists( $id, $metadata ) ){
306 $placeholder = '$$' . $id . '$$';
307 $to_replace[ $placeholder ] = $metadata[ $id ];
308 }
309 }
310
311 $content = strtr( $content, $to_replace );
312
313 return $content;
314
315 }
316
317 public static function replace_custom_fields( $content ){
318
319 global $post;
320
321 preg_match_all('/\$\$custom_field\:(.*?)\$\$/', $content, $matches );
322
323 if( empty( $matches[0] ) ){
324 return $content;
325 }
326
327 $general_settings = self::get_settings();
328 $cf_tags = $matches[1];
329
330 foreach( $cf_tags as $cf_tag ){
331
332 $cf_data = explode( ':', $cf_tag, 2 );
333 $cf_name = trim( $cf_data[0] );
334 $cf_default_val = count( $cf_data ) == 2 ? trim( $cf_data[1] ) : '';
335
336 if( empty( $cf_name ) ){
337 continue;
338 }
339
340 if( is_object( $post ) ){
341 $cf_actual_val = get_post_meta( $post->ID, $cf_name, true );
342 $value = $cf_actual_val == '' ? $cf_default_val : $cf_actual_val;
343 }else{
344 $value = $cf_default_val;
345 }
346
347 if ( isset( $general_settings[ 'sanitize_custom_fields' ] ) && $general_settings[ 'sanitize_custom_fields' ] === 'yes' ) {
348 $value = wp_kses_post( $value );
349 }
350
351 $full_tag = '$$custom_field:' . $cf_tag . '$$';
352 $content = str_replace( $full_tag, $value, $content );
353
354 }
355
356 return $content;
357
358 }
359
360 public static function process_content( $content, $settings ){
361
362 $content = do_shortcode( $content );
363
364 if( $settings[ '_sc_execute_blocks' ] == 'yes' ){
365 $content = do_blocks( $content );
366 }
367
368 return $content;
369
370 }
371
372 public static function wp_params_list(){
373
374 return apply_filters( 'sc_mod_wp_params', array(
375 'wp_info' => array(
376 'name' => __( 'WordPress information', 'shortcoder' ),
377 'icon' => 'wordpress-alt',
378 'params' => array(
379 'url' => __( 'URL of the post/location', 'shortcoder' ),
380 'title' => __( 'Title of the post/location', 'shortcoder' ),
381 'short_url' => __( 'Short URL of the post/location', 'shortcoder' ),
382
383 'post_id' => __( 'Post ID', 'shortcoder' ),
384 'post_image' => __( 'Post featured image URL', 'shortcoder' ),
385 'post_excerpt' => __( 'Post excerpt', 'shortcoder' ),
386 'post_author' => __( 'Post author', 'shortcoder' ),
387 'post_date' => __( 'Post date', 'shortcoder' ),
388 'post_modified_date' => __( 'Post modified date', 'shortcoder' ),
389 'post_comments_count' => __( 'Post comments count', 'shortcoder' ),
390 'post_slug' => __( 'Post slug', 'shortcoder' ),
391
392 'site_name' => __( 'Site title', 'shortcoder' ),
393 'site_description' => __( 'Site description', 'shortcoder' ),
394 'site_url' => __( 'Site URL', 'shortcoder' ),
395 'site_wpurl' => __( 'WordPress URL', 'shortcoder' ),
396 'site_charset' => __( 'Site character set', 'shortcoder' ),
397 'wp_version' => __( 'WordPress version', 'shortcoder' ),
398 'stylesheet_url' => __( 'Active theme\'s stylesheet URL', 'shortcoder' ),
399 'stylesheet_directory' => __( 'Active theme\'s directory', 'shortcoder' ),
400 'atom_url' => __( 'Atom feed URL', 'shortcoder' ),
401 'rss_url' => __( 'RSS 2.0 feed URL', 'shortcoder' )
402 )
403 ),
404 'date_info' => array(
405 'name' => __( 'Date parameters', 'shortcoder' ),
406 'icon' => 'calendar-alt',
407 'params' => array(
408 'day' => __( 'Day', 'shortcoder' ),
409 'day_lz' => __( 'Day - leading zeros', 'shortcoder' ),
410 'day_ws' => __( 'Day - words - short form', 'shortcoder' ),
411 'day_wf' => __( 'Day - words - full form', 'shortcoder' ),
412 'month' => __( 'Month', 'shortcoder' ),
413 'month_lz' => __( 'Month - leading zeros', 'shortcoder' ),
414 'month_ws' => __( 'Month - words - short form', 'shortcoder' ),
415 'month_wf' => __( 'Month - words - full form', 'shortcoder' ),
416 'year' => __( 'Year', 'shortcoder' ),
417 'year_2d' => __( 'Year - 2 digit', 'shortcoder' ),
418 )
419 ),
420 'sc_cnt' => array(
421 'name' => __( 'Shortcode enclosed content', 'shortcoder' ),
422 'icon' => 'text',
423 'params' => array(
424 'enclosed_content' => __( 'Shortcode enclosed content', 'shortcoder' )
425 )
426 )
427 ));
428
429 }
430
431 public static function set_defaults( $a, $b ){
432
433 $a = (array) $a;
434 $b = (array) $b;
435 $result = $b;
436
437 foreach ( $a as $k => &$v ) {
438 if ( is_array( $v ) && isset( $result[ $k ] ) ) {
439 $result[ $k ] = self::set_defaults( $v, $result[ $k ] );
440 } else {
441 $result[ $k ] = $v;
442 }
443 }
444 return $result;
445 }
446
447 }
448
449 Shortcoder::init();
450
451 ?>