'myshortcode', // [tagname] 'name' => '', // for VC, shortcode name 'icon' => '', // for VC, url to your .png icon 'category' => '', // for VC 'desc' => '', // for VC, description below the name in the VC selection box /* * Attributes can either be a normal array containing attribute => default value pairs, * or an associative array containing the values of $this->defaultAttributes */ 'attributes' => array(), 'function' => array( 'TitanFrameworkShortcode', 'genericShortcodeFunction' ), // callable ); private $defaultAttributes = array( 'default' => '', // default value 'type' => 'text', // for VC, see http://kb.wpbakery.com/index.php?title=Vc_map for a list of all types, can also be some Titan types 'options' => array(), // for VC, a list of value => label pairs IF the type is select 'name' => '', // for VC, name of the attribute 'desc' => '', 'holder' => '', 'dependency' => '', ); // Hold the list of defined shortcodes public $shortcodes = array(); // Only create a single instance of this class private static $instance; /** * Get the singleton instance of TitanFrameworkShortcode * * @return TitanFrameworkShortcode instance * @since 1.0 **/ public static function getInstance() { if ( empty( self::$instance ) ) { self::$instance = new TitanFrameworkShortcode(); } return self::$instance; } /** * Constructor * * @since 1.0 **/ function __construct() { add_action( 'admin_head', array( $this, 'printDropDownStyle' ) ); add_action( 'admin_head', array( $this, 'printShortcodes' ) ); add_action( 'admin_head', array( $this, 'addTinyMCEDropDown' ) ); add_action( 'admin_head', array( $this, 'printVisualComposerIcons' ) ); } /** * Prints the styles needed for Visual Composer, for icons * * @return void * @since 1.0 **/ public function printVisualComposerIcons() { // Check if Visual Composer is installed if ( ! defined( 'WPB_VC_VERSION' ) || ! function_exists( 'wpb_map' ) ) { return; } echo ""; } /** * Forms a string of a shortcode containing all the attributes * with the default values * * @param array $shortcode Settings array for a shortcode * @return string A shortcode string * @since 1.0 **/ private function formDefaultShortcode( $shortcode ) { $args = array(); if ( is_array( $shortcode['attributes'] ) ) { foreach ( $shortcode['attributes'] as $attribute => $details ) { if ( is_array( $details ) ) { $details = array_merge( $this->defaultAttributes, $details ); $args[] = sprintf( "%s='%s'", $attribute, htmlspecialchars( esc_attr( $details['default'] ) ) // Clean up the value for quotes ); } else { $args[] = sprintf( "%s='%s'", $attribute, htmlspecialchars( esc_attr( $details ) ) // Clean up the value for quotes ); } } } if ( count( $args ) ) { $args = ' ' . implode( ' ', $args ); } else { $args = ''; } return "[{$shortcode['tag']}{$args}]"; } /** * Prints the styles for the drop down in the visual editor * * @return void * @since 1.0 **/ public function printDropDownStyle() { if ( ! count( $this->shortcodes ) ) { return; } ?> shortcodes ) ) { return; } ?> shortcodes ) ) { return; } if ( ( current_user_can('edit_posts') || current_user_can('edit_pages') ) && get_user_option('rich_editing') ) { add_filter( 'mce_external_plugins', array( $this, 'addTinyMCEPlugin' ) ); add_filter( 'mce_buttons', array( $this, 'addTinyMCEButton' ) ); } } /** * Adds the our shortcode drop down plugin to TinyMCE * * @param array $plugins a list of enabled plugins in TinyMCE * @return array TinyMCE plugins * @since 1.0 **/ public function addTinyMCEPlugin( $plugins ) { if ( empty( $plugins[ self::JS_SHORTCODE_VAR ] ) ) { $plugins[ self::JS_SHORTCODE_VAR ] = TitanFramework::getURL( 'admin-shortcodes.js', __FILE__ ); } return $plugins; } /** * Adds the drop down TinyMCE button * * @param array $buttons list of current buttons * @return array TinyMCE buttons * @since 1.0 **/ public function addTinyMCEButton( $buttons ) { array_push( $buttons, self::JS_SHORTCODE_VAR ); return $buttons; } /** * Adds our shortcodes to Visual Composer * * @param array $shortcode shortcode parameter array * @return void * @since 1.0 **/ private function addToVisualComposer( $shortcode ) { // Check if Visual Composer is installed if ( ! defined( 'WPB_VC_VERSION' ) || ! function_exists( 'wpb_map' ) ) { return; } if ( ! is_array( $shortcode['attributes'] ) ) { return; } $params = array(); foreach ( $shortcode['attributes'] as $attribute => $details ) { // We need the detailed shortcode for VC to work properly if ( ! is_array( $details ) ) { return; } // Merge the default values $details = array_merge( $this->defaultAttributes, $details ); // We standardize the type attribute with Titan's own type attribute // to make things easier. Convert it to VC's own types here $type = $details['type']; $default = $details['default']; if ( $type == 'text' ) { $type = 'textfield'; } else if ( $type == 'select' || $type == 'dropdown' ) { $type = 'dropdown'; $default = array(); if ( ! empty( $details['options'] ) && is_array( $details['options'] ) ) { $default = $details['options']; // In VC, the keys are the labels, and the values are the value // We do the reverse in Titan, flip it but only for associative arrays if ( array_keys( $default ) !== range( 0, count( $default ) - 1 ) ) { $default = array_flip( $default ); } } } else if ( $type == 'upload' || $type == 'image' ) { $type = 'attach_image'; } else if ( $type == 'uploads' || $type == 'images' ) { $type = 'attach_images'; } else if ( $type == 'color' ) { $type = 'colorpicker'; } else { // same types with Titan: // checkbox // tetxarea // All other VC specific types will still work } $params[] = array( 'type' => $type, 'heading' => $details['name'], 'param_name' => $attribute, 'value' => $default, 'description' => $details['desc'], 'dependency' => $details['dependency'], ); if ( ! empty( $details['holder'] ) ) { $params[ count($params) - 1 ]['holder'] = $details['holder']; } } // Register the shortcode wpb_map( array( "name" => $shortcode['name'], "base" => $shortcode['tag'], "icon" => TF . '-' . $shortcode['tag'], "description" => $shortcode['desc'], "params" => $params ) ); } /** * Creates a shortcode * * @param array $settings shortcode parameter array * @return boolean True if successfully created shortcode, false otherwise * @since 1.0 **/ public function createShortcode( $settings ) { // Add default settings $settings = array_merge( $this->defaultSettings, $settings ); // Add default attributes (for the advanced usage only) if ( is_array( $settings['attributes'] ) ) { foreach ( $settings['attributes'] as $attribute => $details ) { if ( ! is_array( $value ) ) { break; } // Merge defaults $settings['attributes'][$key][$attribute] = array_merge( $this->defaultAttributes, $details ); // make sure we have a name if ( empty( $details['name'] ) ) { $settings['attributes'][$key][$attribute]['name'] = $attribute; } } } if ( empty( $settings['tag'] ) ) { return false; } if ( empty( $settings['name'] ) ) { $settings['name'] = $settings['tag']; } // If the shortcode already exists, don't overwrite it if ( shortcode_exists( $settings['tag'] ) ) { return false; } // Check before adding the shortcode in our list foreach ( $this->shortcodes as $shortcode ) { if ( $shortcode['tag'] == $settings['tag'] ) { return false; } } // Take note of the new shortcode for future processes $this->shortcodes[] = $settings; // Add shortcode to Visual Composer $this->addToVisualComposer( $settings ); // The our shortcode parse will add the shortcode to WP new TitanFrameworkShortcodeParser( $settings ); return true; } /** * A dummy shortcode handler, just in case nothing was supplied for the shortcode * * @param array $atts An array of shortcode attribute values * @param string $content the contents inside the shortcode * @return string rendered shortcode * @since 1.0 **/ public static function genericShortcodeFunction( $atts, $content ) { return $content; } } } if ( ! class_exists( 'TitanFrameworkShortcodeParser' ) ) { /** * Titan Framework Shortcode Parser * * @since 1.0 **/ class TitanFrameworkShortcodeParser { // Keep all the shortcode settings public $settings; /** * Constructor * * @param array $settings shortcode settings array * @return void * @since 1.0 **/ function __construct( $settings ) { $this->settings = $settings; add_shortcode( $settings['tag'], array( $this, 'doShortcode' ) ); } /** * Returns an array of attributes along with their default values * * @return array attributes with default values * @since 1.0 **/ private function getDefaultAttributes() { $defaults = array(); if ( is_array( $this->settings['attributes'] ) ) { foreach ( $this->settings['attributes'] as $attribute => $details ) { if ( is_array( $details ) ) { $defaults[ $attribute ] = $details['default']; } else { $defaults[ $attribute ] = $details; } } } return $defaults; } /** * Renders the shortcode, prepares the attributes then calls the * function parameter of the shortcode * * @param array $atts An array of shortcode attribute values * @param string $content the contents inside the shortcode * @return string rendered shortcode * @since 1.0 **/ public function doShortcode( $atts, $content = '' ) { // Clean up attributes $atts = shortcode_atts( $this->getDefaultAttributes(), $atts, $this->settings['tag'] ); // Call the callable normally return call_user_func( $this->settings['function'], $atts, $content ); } } } if ( ! function_exists( 'titan_framework_init_shortcodes' ) ) { /** * Initialize the shortcode class when Titan initializes * * @param TitanFramework $frameworkInstance the current framework instance being initialized (not used) * @return void * @since 1.0 **/ function titan_framework_init_shortcodes( $frameworkInstance ) { TitanFrameworkShortcode::getInstance(); } add_action( 'tf_init', 'titan_framework_init_shortcodes' ); } if ( ! function_exists( 'titan_framework_create_shortcode' ) ) { /** * Handles the creation of shortcodes triggered from the framework * * @param array $settings shortcode settings array * @return void * @since 1.0 **/ function titan_framework_create_shortcode( $settings ) { $o = TitanFrameworkShortcode::getInstance(); $o->createShortcode( $settings ); } add_action( 'tf_create_shortcode', 'titan_framework_create_shortcode' ); }