abstract.llms.shortcode.php 4.78 KB
Newer Older
cyrille's avatar
cyrille committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220
<?php
/**
 * Base Shortcode
 *
 * @package LifterLMS/Abstracts/Classes
 *
 * @since 3.4.3
 * @version 5.0.0
 */

defined( 'ABSPATH' ) || exit;

/**
 * LLMS_Shortcode Abstract.
 *
 * @since 3.4.3
 */
abstract class LLMS_Shortcode {

	/**
	 * Shortcode tag
	 *
	 * @var  string
	 */
	public $tag = '';

	/**
	 * Retrieve the actual content of the shortcode
	 *
	 * $atts & $content are both filtered before being passed to get_output()
	 * output is filtered so the return of get_output() doesn't need its own filter
	 *
	 * @return   string
	 * @since    3.4.3
	 * @version  3.4.3
	 */
	abstract protected function get_output();

	/**
	 * Retrieves an array of default attributes which are automatically merged
	 * with the user submitted attributes and passed to $this->get_output()
	 *
	 * @return   array
	 * @since    3.4.3
	 * @version  3.4.3
	 */
	protected function get_default_attributes() {
		return array();
	}

	/**
	 * Retrieves a string used for default content which is used if no content is supplied
	 *
	 * @return   string
	 * @since    3.4.3
	 * @version  3.4.3
	 */
	protected function get_default_content() {
		return '';
	}

	/**
	 * Holds singletons for extending classes
	 *
	 * @var  array
	 */
	private static $_instances = array();

	private $attributes = array();
	private $content    = '';

	/**
	 * Get the singleton instance for the extending class
	 *
	 * @return   obj
	 * @since    3.4.3
	 * @version  3.4.3
	 */
	public static function instance() {

		$class = get_called_class();

		if ( ! isset( self::$_instances[ $class ] ) ) {
			self::$_instances[ $class ] = new $class();
		}

		return self::$_instances[ $class ];

	}

	/**
	 * Private constructor
	 *
	 * @since 3.4.3
	 */
	private function __construct() {
		add_shortcode( $this->tag, array( $this, 'output' ) );
	}

	/**
	 * Allow shortcodes to enqueue scripts only when the shortcode is used
	 * Enqueues a registered script IF that script isn't already enqueued
	 *
	 * @param    string $handle  script handle
	 * @return   void
	 * @since    3.4.3
	 * @version  3.4.3
	 */
	protected function enqueue_script( $handle ) {

		if ( wp_script_is( $handle, 'registered' ) && ! wp_script_is( $handle, 'enqueued' ) ) {

			wp_enqueue_script( $handle );

		}

	}

	/**
	 * Get the array of attributes
	 *
	 * @return   array
	 * @since    3.4.3
	 * @version  3.5.1
	 */
	public function get_attributes() {
		return apply_filters( $this->get_filter( 'get_attributes' ), $this->attributes, $this );
	}

	/**
	 * Get a specific attribute from the attributes array
	 *
	 * @param    string $key      attribute key to retrieve
	 * @param    string $default  if no attribute is set, this value will be used
	 * @return   mixed
	 * @since    3.4.3
	 * @version  3.5.1
	 */
	public function get_attribute( $key, $default = '' ) {
		$attributes = $this->get_attributes();
		if ( isset( $attributes[ $key ] ) ) {
			return $attributes[ $key ];
		}
		return $default;
	}

	/**
	 * Retrieve the content of the shortcode
	 *
	 * @return   string
	 * @since    3.4.3
	 * @version  3.5.1
	 */
	public function get_content() {
		return apply_filters( $this->get_filter( 'get_content' ), $this->content, $this );
	}

	/**
	 * Retrieve a string that can be used for apply_filters()
	 * Ensures that all shortcode related filters follow the same naming convention
	 *
	 * @param    string $filter  filter name / suffix
	 * @return   string
	 * @since    3.4.3
	 * @version  3.4.3
	 */
	protected function get_filter( $filter ) {
		return $this->tag . '_' . $filter;
	}

	/**
	 * Output the actual content of the shortcode
	 * This is the callback function used by add_shortcode
	 * and can also be used programmatically, used in some widgets
	 *
	 * $atts & $content are both filtered before being passed to get_output()
	 * output is filtered so the return of get_output() doesn't need its own filter
	 *
	 * @since 3.4.3
	 * @since 3.5.1 Unknown.
	 * @since 5.0.0 Merge attributes in a separate method.
	 *
	 * @param    array  $atts     user submitted shortcode attributes
	 * @param    string $content  user submitted content
	 * @return   string
	 */
	public function output( $atts = array(), $content = '' ) {

		$this->attributes = $this->set_attributes( $atts );

		if ( ! $content ) {
			$content = apply_filters( $this->get_filter( 'get_default_content' ), $this->get_default_content(), $this );
		}

		$this->content = $content;

		return apply_filters( $this->get_filter( 'output' ), $this->get_output(), $this );

	}

	/**
	 * Merge user attributes with default attributes.
	 *
	 * @since 5.0.0
	 *
	 * @param array $atts User-submitted shortcode attributes.
	 *
	 * @return array
	 */
	protected function set_attributes( $atts = array() ) {

		return shortcode_atts(
			apply_filters( $this->get_filter( 'get_default_attributes' ), $this->get_default_attributes(), $this ),
			$atts,
			$this->tag
		);

	}

}