Advertisement
ygeorgiev

Shortcodes class

Nov 9th, 2013
64
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
PHP 7.14 KB | None | 0 0
  1. <?php
  2.  
  3. /**
  4.  * Shortcodes class
  5.  *
  6.  * @author Yasen Georgiev <avbincco@gmail.com>
  7.  * @link http://framework.maleeby.ygeorgiev.com/
  8.  * @copyright Copyright &copy; 2013 Yasen Georgiev
  9.  * @license http://framework.maleeby.ygeorgiev.com/#license
  10.  * @package sLibraries
  11.  */
  12. class Shortcodes {
  13.  
  14.     /**
  15.      * Loaded string
  16.      * @var string
  17.      */
  18.     private static $_string;
  19.     /**
  20.      * Opened but not closed shortcodes
  21.      * @var array
  22.      */
  23.     private static $_opened_tags = array();
  24.    
  25.     /**
  26.      * Detected shortcodes
  27.      * @var array
  28.      */
  29.     private static $_tags = array();
  30.    
  31.     /**
  32.      * Registered shortcodes and thems settings
  33.      * @var type
  34.      */
  35.     private static $_registered = array();
  36.  
  37.     /**
  38.      * Execute string
  39.      * @param string $string String to execute
  40.      * @return string String in which tags are replaced with thems callback method.
  41.      */
  42.     public static function execute($string) {
  43.         self::$_string = trim($string);
  44.         self::_detectShortCodes();
  45.         self::_replaceShortcodes();
  46.  
  47.         return self::$_string;
  48.     }
  49.  
  50.     /**
  51.      * Detects shortcodes in the string
  52.      * @return array Detected shortcodes
  53.      */
  54.     private static function _detectShortCodes() {
  55.         $str = self::$_string;
  56.         $words = array();
  57.  
  58.         while ($i <= strlen($str)) {
  59.             $i++;
  60.             $symbol = substr($str, $i - 1, 1);
  61.             $last_symbol = $symbols[$i - 1];
  62.  
  63.             if ($symbol == '[' && $last_symbol != '\\') {
  64.                 self::$_opened_tags[] = $i;
  65.             } elseif ($symbol == ']' && $last_symbol != '\\') {
  66.                 $last_opened_array_keys = array_keys(self::$_opened_tags);
  67.  
  68.                 if (!count($last_opened_array_keys)) {
  69.                     continue;
  70.                 }
  71.  
  72.  
  73.                 $last_opened_key = max($last_opened_array_keys);
  74.                 $last_opened = self::$_opened_tags[$last_opened_key]; // Get position of the last opened tag
  75.                 $tag_data_full = substr($str, $last_opened, $i - $last_opened - 1); // Get full tag code
  76.                 $tag_data = explode(' ', $tag_data_full, 2); // Get the tag name and its parameters
  77.  
  78.                 if (array_key_exists($tag_data[0], self::$_registered)) {
  79.                     $params = self::parseParameters($tag_data[1]);
  80.                     self::$_tags[] = array(
  81.                         'name' => $tag_data[0],
  82.                         'full' => '[' . trim($tag_data_full) . ']',
  83.                         'parameters' => $params,
  84.                         'start' => $last_opened,
  85.                         'end' => $i
  86.                     );
  87.                     unset(self::$_opened_tags[$last_opened_key]);
  88.                 }
  89.             }
  90.  
  91.             $symbols[$i] = $symbol;
  92.         }
  93.         return self::$_tags;
  94.     }
  95.  
  96.     /**
  97.      * Parses string's parameters.
  98.      * @param string $string String to find parameters in it.
  99.      * @return array Shortcode parameters
  100.      */
  101.     private static function parseParameters($string) {
  102.         $string = trim($string);
  103.         $_opened_value = array();
  104.         $_global_spaces = array();
  105.  
  106.         $exploded = explode('=', $string); //Parse by =
  107.  
  108.         foreach ($exploded as $exploded_key => $exploded_row) {
  109.             $spaces = explode(' ', $exploded_row);
  110.             foreach ($spaces as $space_key => $space) {
  111.                 $first_symb = substr($space, 0, 1);
  112.                 $last_symb = substr($space, -1);
  113.  
  114.                 if (array_keys($_global_spaces)) {
  115.                     $last_global_space = $_global_spaces[max(array_keys($_global_spaces))];
  116.                 }
  117.  
  118.                 if (($first_symb == '"' && $last_symb != '"') || ($first_symb == "'" && $last_symb != "'")) {
  119.                     $_opened_value[$last_global_space] = substr($space, 1);
  120.                 } elseif (($first_symb == '"' && $last_symb == '"') || ($first_symb == "'" && $last_symb == "'")) {
  121.                     if (array_key_exists($last_global_space, $_opened_value)) {
  122.                         unset($_opened_value[$last_global_space]);
  123.                     }
  124.                     $_tags[$last_global_space] = substr($space, 1, strlen($space) - 2);
  125.                 } elseif (($first_symb != '"' && $last_symb == '"') || ($first_symb != "'" && $last_symb == "'")) {
  126.                     $tag_key = key(array_slice($_opened_value, -1, 1, TRUE));
  127.                     $tag_val = end($_opened_value) . ' ' . substr($space, 0, strlen($space) - 1);
  128.  
  129.                     if (strlen($tag_key)) {
  130.                         $_tags[$tag_key] = $tag_val;
  131.  
  132.                         unset($_opened_value[$tag_key]);
  133.                     }
  134.                 } elseif ($space_key != max(array_keys($spaces)) && !count($_opened_value)) {
  135.                     if (array_key_exists($space, $_opened_value)) {
  136.                         unset($_opened_value[$last_global_space]);
  137.                     }
  138.                     $_tags[$space] = TRUE;
  139.                 } elseif (count($_opened_value)) {
  140.                     $tag_key = key(array_slice($_opened_value, -1, 1, TRUE));
  141.                     $tag_val = end($_opened_value) . ' ' . $space;
  142.                     $_opened_value[$tag_key] = $tag_val;
  143.                 }
  144.                 $_global_spaces[] = $space;
  145.             }
  146.         }
  147.  
  148.         $last_space = end($_global_spaces);
  149.         if (strlen($last_space) && (substr($last_space, 0, 1) != '"' && substr($last_space, -1) != '"') && (substr($last_space, 0, 1) != "'" && substr($last_space, -1) != "'")) {
  150.             if (array_key_exists($last_space, $_opened_value)) {
  151.                 unset($_opened_value[$last_global_space]);
  152.             }
  153.             $_tags[$last_space] = TRUE;
  154.         }
  155.  
  156.         return $_tags;
  157.     }
  158.    
  159.     /**
  160.      * Replaces a shortcode with its callback method
  161.      * @throws \Exception Shortcode is not callable
  162.      */
  163.     private static function _replaceShortcodes() {
  164.         $string = self::$_string;
  165.         $tags = self::$_tags;
  166.  
  167.         foreach ($tags as $tag) {
  168.             $tag_callback_method = self::$_registered[$tag['name']];
  169.             if (is_callable($tag_callback_method)) {
  170.                 $callback_return = call_user_func($tag_callback_method, $tag['parameters']);
  171.                 $string = str_replace($tag['full'], $callback_return, $string);
  172.             } else {
  173.                 throw new \Exception("Defined shortcode method for [$tag[name]] cannot be executed: $tag_callback_method()", 500);
  174.             }
  175.         }
  176.  
  177.         self::$_string = $string;
  178.     }
  179.    
  180.     /**
  181.      * Register a shortcode
  182.      * @param string $shortcode Shortcode name
  183.      * @param string $method Callback method
  184.      * @throws \Exception
  185.      */
  186.  
  187.     public static function registerShortcode($shortcode, $method) {
  188.         if (preg_match('/^[a-z0-9\-\_]+$/i', $shortcode)) {
  189.             if (is_string($method)) {
  190.                 self::$_registered[$shortcode] = $method;
  191.             } else {
  192.                 throw new \Exception("Invalid shortcode method name!", 500);
  193.             }
  194.         } else {
  195.             throw new \Exception("Invalid shortcode name!", 500);
  196.         }
  197.     }
  198.  
  199. }
  200. ?>
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement