Plugin Directory

source: shortcoder/trunk/shortcoder.php

Last change on this file was 3331052, checked in by vaakash, 5 months ago

New version 6.5.1

File size: 14.3 KB
Line 
1<?php
2/*
3Plugin Name: Shortcoder
4Plugin URI: https://www.aakashweb.com/wordpress-plugins/shortcoder/
5Description: 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.
6Author: Aakash Chakravarthy
7Version: 6.5.1
8Author URI: https://www.aakashweb.com/
9Text Domain: shortcoder
10Domain Path: /languages
11*/
12
13define( 'SC_VERSION', '6.5.1' );
14define( 'SC_PATH', plugin_dir_path( __FILE__ ) ); // All have trailing slash
15define( 'SC_URL', plugin_dir_url( __FILE__ ) );
16define( 'SC_ADMIN_URL', trailingslashit( plugin_dir_url( __FILE__ ) . 'admin' ) );
17define( 'SC_BASE_NAME', plugin_basename( __FILE__ ) );
18define( 'SC_POST_TYPE', 'shortcoder' );
19
20// error_reporting(E_ALL);
21
22final 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
437Shortcoder::init();
438
439?>
Note: See TracBrowser for help on using the repository browser.