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