      1: <?php
      2: /**
      3:  *
      4:  */
      5: class Sidecar_Shortcode {
      6:
      7:   /**
      8:    * @var Sidecar_Plugin_Base
      9:    */
     10:   var $plugin;
     11:
     12:   /**
     13:    * @var string
     14:    */
     15:   var $shortcode_name;
     16:
     17:   /**
     18:    * @var array
     19:    */
     20:     protected $_attributes = array();
     21:
     22:   /**
     23:    * @var bool
     24:    */
     25:   var $initialized = false;
     26:
     27:   /**
     28:    * @var string 'yes'/'no' vs. true/false as get_post_meta() returns '' for false and not found.
     29:    *
     30:    */
     31:   var $used = 'no';
     32:
     33:   /**
     34:    * @param       $shortcode_name
     35:    * @param array $args
     36:    */
     37:   function __construct( $shortcode_name, $args = array() ) {
     38:         $this->shortcode_name = $shortcode_name;
     39:
     40:     /**
     41:      * Copy properties in from $args, if they exist.
     42:      */
     43:     foreach( $args as $property => $value )
     44:       if ( property_exists(  $this, $property ) )
     45:         $this->$property = $value;
     46:
     47:     $this->HAS_SHORTCODE_KEY  = "_has_{$this->shortcode_name}_shortcode";
     48:
     49:     }
     50:
     51:   /**
     52:    * @param array $attributes
     53:    * @param string $content
     54:    *
     55:    * @return null|string
     56:    */
     57:   function do_shortcode( $attributes, $content = null ) {
     58:     if ( empty( $attributes ) && ! is_array( $attributes ) )
     59:       $attributes = array();
     60:     $this->used = 'yes';
     61:     return $this->plugin->do_shortcode( $this, $attributes, $content );
     62:   }
     63:
     64:   /**
     65:    * This allows Sidecar_Plugin_Base to add a hook for this shortcode to monitor the content for shortcodes.
     66:    */
     67:   function add_the_content_filter() {
     68:     add_filter( 'the_content', array( $this, 'the_content' ), 12 ); // AFTER WordPress' do_shortcode()
     69:   }
     70:
     71:   /**
     72:   * @param string $content
     73:   * @return string
     74:   */
     75:   function the_content( $content ) {
     76:     global $post;
     77:     if ( '' === get_post_meta( $post->ID, $this->HAS_SHORTCODE_KEY, true ) ) {
     78:       /**
     79:        * This is the first time the shortcode has ever been seen for this post.
     80:        * Save a post_meta key so that next time we'll know this post uses this shortcode
     81:        */
     82:       $this->update_has_shortcode( $post->ID, $this->used );
     83:     }
     84:     remove_filter( 'the_content', array( $this, 'the_content' ), 12 );
     85:     return $content;
     86:   }
     87:
     88:   /**
     89:    * @param $attribute_name
     90:    * @param $args
     91:    */
     92:   function add_attribute( $attribute_name, $args ) {
     93:     $args = wp_parse_args( $args, array(
     94:       'default' => false,
     95:       'sample' => isset( $args['example'] ) ? false : '12345',
     96:       'example' => false,
     97:       'help' => false,
     98:       'setting' => $attribute_name,
     99:       'api_var' => $attribute_name,
    100:     ));
    101:     if ( ! $args['example'] )
    102:       $args['example'] = <<<TEXT
    103: [{$this->shortcode_name} {$attribute_name}="{$args['sample']}"]
    104: TEXT;
    105:     $this->_attributes[$attribute_name] = (object)$args;
    106:   }
    107:
    108:   /**
    109:    * @return array
    110:    */
    111:   function get_attributes() {
    112:     return $this->_attributes;
    113:   }
    114:
    115:   /**
    116:    * @param string $attribute_name
    117:    *
    118:    * @return array
    119:    */
    120:   function has_attribute( $attribute_name ) {
    121:     return isset( $this->_attributes[$attribute_name] );
    122:   }
    123:
    124:   /**
    125:    * Test to see if a given post needs externals by checking to see if shortcode was ever run.
    126:    *
    127:    * @param int $post_id
    128:    *
    129:    * @return bool
    130:    */
    131:   function get_maybe_has_shortcode( $post_id ) {
    132:     global $wp_query;
    133:     if ( ! $wp_query->is_single ) {
    134:       /**
    135:        * @todo optimize for other use-cases beside single post.
    136:        */
    137:       $maybe_has_shortcode = 'yes';
    138:     } else {
    139:       $maybe_has_shortcode = get_post_meta( $post_id, $this->HAS_SHORTCODE_KEY, true );
    140:       /**
    141:        * The following test is a more compact way to test this:
    142:        *
    143:        *    ( true !== $maybe_has_shortcodes && false !== $maybe_has_shortcodes )
    144:        *
    145:        */
    146:       if ( '' == $maybe_has_shortcode ) {
    147:         /**
    148:          * Set to true because it's unknown if we need the script (or style) so better safe then sorry
    149:          */
    150:         $maybe_has_shortcode = 'yes';
    151:       }
    152:     }
    153:     return 'yes' == $maybe_has_shortcode;
    154:   }
    155:
    156:   /**
    157:    * Remove the has shortcode flag. Used by Sidecar_Plugin_Base to clear on a Post Save.
    158:    *
    159:    * @param int $post_id
    160:    */
    161:   function delete_has_shortcode( $post_id ) {
    162:     delete_post_meta( $post_id, $this->HAS_SHORTCODE_KEY  );
    163:   }
    164:
    165:   /**
    166:    * Test to see if a given post has this shortcode.
    167:    *
    168:    * @param int $post_id
    169:    * @param bool $has_shortcodes
    170:    *
    171:    * @return bool
    172:    */
    173:   function update_has_shortcode( $post_id, $has_shortcodes ) {
    174:     update_post_meta( $post_id, $this->HAS_SHORTCODE_KEY, $has_shortcodes );
    175:   }
    176:
    177: }
    178: