PluginProbe ʕ •ᴥ•ʔ
Shortcoder — Create Shortcodes for Anything / 6.5.3
Shortcoder — Create Shortcodes for Anything v6.5.3
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 1 month ago includes 1 month ago languages 1 month ago readme.txt 1 month ago shortcoder.php 1 month ago
shortcoder.php
445 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.3
8 Author URI: https://www.aakashweb.com/
9 Text Domain: shortcoder
10 Domain Path: /languages
11 */
12
13 define( 'SC_VERSION', '6.5.3' );
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_fields' => 'yes'
143 ));
144
145 }
146
147 public static function get_settings(){
148
149 $settings = get_option( 'sc_settings', array() );
150 $default_settings = self::default_settings();
151
152 return self::set_defaults( $settings, $default_settings );
153
154 }
155
156 public static function get_sc_settings( $post_id ){
157
158 $meta_vals = get_post_meta( $post_id, '', true );
159 $default_vals = self::default_sc_settings();
160 $settings = array();
161
162 if( !is_array( $meta_vals ) ){
163 return $default_vals;
164 }
165
166 foreach( $default_vals as $key => $val ){
167 $settings[ $key ] = array_key_exists( $key, $meta_vals ) ? $meta_vals[$key][0] : $val;
168 }
169
170 $settings[ '_sc_title' ] = get_the_title( $post_id );
171
172 return $settings;
173
174 }
175
176 public static function get_sc_tag( $post_id ){
177 $post = get_post( $post_id );
178 return '[sc name="' . $post->post_name . '"][/sc]';
179 }
180
181 public static function find_shortcode( $atts, $shortcodes ){
182
183 $sc_name = false;
184
185 // Find by shortcode ID
186 if( array_key_exists( 'sc_id', $atts ) ){
187 $sc_id = $atts[ 'sc_id' ];
188 foreach( $shortcodes as $temp_name => $temp_props ){
189 if( $temp_props[ 'id' ] == $sc_id ){
190 $sc_name = $temp_name;
191 break;
192 }
193 }
194 }
195
196 // If shortcode ID is not passed, then get the shortcode name
197 if( !$sc_name ){
198 if( !array_key_exists( 'name', $atts ) ){
199 return '<!-- Shortcode is missing "name" attribute -->';
200 }
201 $sc_name = $atts[ 'name' ];
202 }
203
204 // Check if the shortcode name exists
205 if( !array_key_exists( $sc_name, $shortcodes ) ){
206 $sc_name = sanitize_title_with_dashes( $sc_name );
207 if( !array_key_exists( $sc_name, $shortcodes ) ){
208 return sprintf( '<!-- Shortcode [%s] does not exist -->', $sc_name );
209 }
210 }
211
212 return $shortcodes[ $sc_name ];
213
214 }
215
216 public static function can_display( $sc_props ){
217
218 $settings = $sc_props['settings'];
219
220 if( $settings[ '_sc_disable_sc' ] == 'yes' ){
221 return false;
222 }
223
224 $devices = $settings[ '_sc_allowed_devices' ];
225
226 if( $devices == 'mobile_only' && !wp_is_mobile() ){
227 return false;
228 }
229
230 if( $devices == 'desktop_only' && wp_is_mobile() ){
231 return false;
232 }
233
234 if( current_user_can( 'manage_options' ) && $settings[ '_sc_disable_admin' ] == 'yes' ){
235 return false;
236 }
237
238 return true;
239
240 }
241
242 public static function replace_sc_params( $content, $params ){
243
244 $params = array_change_key_case( $params, CASE_LOWER );
245
246 preg_match_all('/%%([a-zA-Z0-9_\-]+)\:?(.*?)%%/', $content, $matches);
247
248 $cp_tags = $matches[0];
249 $cp_names = $matches[1];
250 $cp_defaults = $matches[2];
251 $to_replace = array();
252
253 for( $i = 0; $i < count( $cp_names ); $i++ ){
254
255 $name = strtolower( $cp_names[ $i ] );
256 $default = $cp_defaults[ $i ];
257 $value = '';
258
259 if( array_key_exists( $name, $params ) ){
260 $value = $params[ $name ];
261
262 // Handle scenario when the attributes are added with paragraph tags by autop
263 if( substr( $value, 0, 4 ) == '</p>' ){
264 $value = substr( $value, 4 );
265 if( substr( $value, -3 ) == '<p>' ){
266 $value = substr( $value, 0, -3 );
267 }
268 }
269
270 }
271
272 if( $value == '' ){
273 array_push( $to_replace, $default );
274 }else{
275 array_push( $to_replace, $value );
276 }
277
278 }
279
280 $content = str_ireplace( $cp_tags, $to_replace, $content );
281
282 return $content;
283
284 }
285
286 public static function replace_wp_params( $content, $enc_content = null ){
287
288 $params = self::wp_params_list();
289 $metadata = Shortcoder_Metadata::metadata();
290 $metadata[ 'enclosed_content' ] = $enc_content;
291 $all_params = array();
292 $to_replace = array();
293
294 foreach( $params as $group => $group_info ){
295 $all_params = array_merge( $group_info[ 'params' ], $all_params );
296 }
297
298 foreach( $all_params as $id => $name ){
299 if( array_key_exists( $id, $metadata ) ){
300 $placeholder = '$$' . $id . '$$';
301 $to_replace[ $placeholder ] = $metadata[ $id ];
302 }
303 }
304
305 $content = strtr( $content, $to_replace );
306
307 return $content;
308
309 }
310
311 public static function replace_custom_fields( $content ){
312
313 global $post;
314
315 preg_match_all('/\$\$custom_field\:(.*?)\$\$/', $content, $matches );
316
317 if( empty( $matches[0] ) ){
318 return $content;
319 }
320
321 $general_settings = self::get_settings();
322 $cf_tags = $matches[1];
323
324 foreach( $cf_tags as $cf_tag ){
325
326 $cf_data = explode( ':', $cf_tag, 2 );
327 $cf_name = trim( $cf_data[0] );
328 $cf_default_val = count( $cf_data ) == 2 ? trim( $cf_data[1] ) : '';
329
330 if( empty( $cf_name ) ){
331 continue;
332 }
333
334 if( is_object( $post ) ){
335 $cf_actual_val = get_post_meta( $post->ID, $cf_name, true );
336 $value = $cf_actual_val == '' ? $cf_default_val : $cf_actual_val;
337 }else{
338 $value = $cf_default_val;
339 }
340
341 if ( isset( $general_settings['sanitize_custom_fields'] ) && $general_settings['sanitize_custom_fields'] === 'yes' ) {
342 $value = wp_kses_post( $value );
343 }
344
345 $full_tag = '$$custom_field:' . $cf_tag . '$$';
346 $content = str_replace( $full_tag, $value, $content );
347
348 }
349
350 return $content;
351
352 }
353
354 public static function process_content( $content, $settings ){
355
356 $content = do_shortcode( $content );
357
358 if( $settings[ '_sc_execute_blocks' ] == 'yes' ){
359 $content = do_blocks( $content );
360 }
361
362 return $content;
363
364 }
365
366 public static function wp_params_list(){
367
368 return apply_filters( 'sc_mod_wp_params', array(
369 'wp_info' => array(
370 'name' => __( 'WordPress information', 'shortcoder' ),
371 'icon' => 'wordpress-alt',
372 'params' => array(
373 'url' => __( 'URL of the post/location', 'shortcoder' ),
374 'title' => __( 'Title of the post/location', 'shortcoder' ),
375 'short_url' => __( 'Short URL of the post/location', 'shortcoder' ),
376
377 'post_id' => __( 'Post ID', 'shortcoder' ),
378 'post_image' => __( 'Post featured image URL', 'shortcoder' ),
379 'post_excerpt' => __( 'Post excerpt', 'shortcoder' ),
380 'post_author' => __( 'Post author', 'shortcoder' ),
381 'post_date' => __( 'Post date', 'shortcoder' ),
382 'post_modified_date' => __( 'Post modified date', 'shortcoder' ),
383 'post_comments_count' => __( 'Post comments count', 'shortcoder' ),
384 'post_slug' => __( 'Post slug', 'shortcoder' ),
385
386 'site_name' => __( 'Site title', 'shortcoder' ),
387 'site_description' => __( 'Site description', 'shortcoder' ),
388 'site_url' => __( 'Site URL', 'shortcoder' ),
389 'site_wpurl' => __( 'WordPress URL', 'shortcoder' ),
390 'site_charset' => __( 'Site character set', 'shortcoder' ),
391 'wp_version' => __( 'WordPress version', 'shortcoder' ),
392 'stylesheet_url' => __( 'Active theme\'s stylesheet URL', 'shortcoder' ),
393 'stylesheet_directory' => __( 'Active theme\'s directory', 'shortcoder' ),
394 'atom_url' => __( 'Atom feed URL', 'shortcoder' ),
395 'rss_url' => __( 'RSS 2.0 feed URL', 'shortcoder' )
396 )
397 ),
398 'date_info' => array(
399 'name' => __( 'Date parameters', 'shortcoder' ),
400 'icon' => 'calendar-alt',
401 'params' => array(
402 'day' => __( 'Day', 'shortcoder' ),
403 'day_lz' => __( 'Day - leading zeros', 'shortcoder' ),
404 'day_ws' => __( 'Day - words - short form', 'shortcoder' ),
405 'day_wf' => __( 'Day - words - full form', 'shortcoder' ),
406 'month' => __( 'Month', 'shortcoder' ),
407 'month_lz' => __( 'Month - leading zeros', 'shortcoder' ),
408 'month_ws' => __( 'Month - words - short form', 'shortcoder' ),
409 'month_wf' => __( 'Month - words - full form', 'shortcoder' ),
410 'year' => __( 'Year', 'shortcoder' ),
411 'year_2d' => __( 'Year - 2 digit', 'shortcoder' ),
412 )
413 ),
414 'sc_cnt' => array(
415 'name' => __( 'Shortcode enclosed content', 'shortcoder' ),
416 'icon' => 'text',
417 'params' => array(
418 'enclosed_content' => __( 'Shortcode enclosed content', 'shortcoder' )
419 )
420 )
421 ));
422
423 }
424
425 public static function set_defaults( $a, $b ){
426
427 $a = (array) $a;
428 $b = (array) $b;
429 $result = $b;
430
431 foreach ( $a as $k => &$v ) {
432 if ( is_array( $v ) && isset( $result[ $k ] ) ) {
433 $result[ $k ] = self::set_defaults( $v, $result[ $k ] );
434 } else {
435 $result[ $k ] = $v;
436 }
437 }
438 return $result;
439 }
440
441 }
442
443 Shortcoder::init();
444
445 ?>