C_NextGen_Shortcode_Manager

Class C_NextGen_Shortcode_Manager.

Defined (1)

The class is defined in the following location(s).

/non_pope/class.nextgen_shortcode_manager.php  
  1. class C_NextGen_Shortcode_Manager 
  2. private static $_instance = NULL; 
  3. private $_shortcodes = array(); 
  4. private $_found = array(); 
  5. private $_placeholder_text = 'ngg_shortcode_%d_placeholder'; 
  6.  
  7. /** 
  8. * Gets an instance of the class 
  9. * @return C_NextGen_Shortcode_Manager 
  10. */ 
  11. static function get_instance() 
  12. if (is_null(self::$_instance)) { 
  13. $klass = get_class(); 
  14. self::$_instance = new $klass; 
  15. return self::$_instance; 
  16.  
  17. /** 
  18. * Adds a shortcode 
  19. * @param $name 
  20. * @param $callback 
  21. */ 
  22. static function add($name, $callback) 
  23. $manager = self::get_instance(); 
  24. $manager->add_shortcode($name, $callback); 
  25.  
  26. /** 
  27. * Removes a previously added shortcode 
  28. * @param $name 
  29. */ 
  30. static function remove($name) 
  31. $manager = self::get_instance(); 
  32. $manager->remove_shortcode($name); 
  33.  
  34. /** 
  35. * Constructor 
  36. */ 
  37. private function __construct() 
  38. // For theme & plugin compatibility and to prevent the output of our shortcodes from being 
  39. // altered we substitute our shortcodes with placeholders at the start of the the_content() filter 
  40. // queue and then at the end of the the_content() queue, we substitute the placeholders with our 
  41. // actual markup 
  42. add_filter('the_content', array(&$this, 'fix_nested_shortcodes'), -1); 
  43. add_filter('the_content', array(&$this, 'parse_content'), PHP_INT_MAX); 
  44. add_filter('widget_text', array(&$this, 'fix_nested_shortcodes'), -1); 
  45.  
  46. /** 
  47. * We're parsing our own shortcodes because WP can't yet handle nested shortcodes 
  48. * [ngg_images param="[slideshow]"] 
  49. * @param $content 
  50. */ 
  51. function fix_nested_shortcodes($content) 
  52. // Try to find each registered shortcode in the content 
  53. foreach ($this->_shortcodes as $tag => $callback) { 
  54. $shortcode_start_tag = "[{$tag}"; 
  55. $offset = 0; 
  56.  
  57. // Find each occurance of the shortcode 
  58. while(($start_of_shortcode = strpos($content, $shortcode_start_tag, $offset)) !== FALSE) { 
  59. $index = $start_of_shortcode + strlen($shortcode_start_tag); 
  60. $found_attribute_assignment = FALSE; 
  61. $current_attribute_enclosure = NULL; 
  62. $last_found_char = ''; 
  63. $content_length = strlen($content) - 1; 
  64.  
  65. while (TRUE) { 
  66. // Parse out the shortcode, character-by-character 
  67. $char = $content[$index]; 
  68. if ($char == '"' || $char == "'" && $last_found_char == '=') { 
  69. // Is this the closing quote for an already found attribute assignment? 
  70. if ($found_attribute_assignment && $current_attribute_enclosure == $char) { 
  71. $found_attribute_assignment = FALSE; 
  72. $current_attribute_enclosure = NULL; 
  73. } else { 
  74. $found_attribute_assignment = TRUE; 
  75. $current_attribute_enclosure = $char; 
  76. else if ($char == ']') { 
  77. // we've found a shortcode closing tag. But, we need to ensure 
  78. // that this ] isn't within the value of a shortcode attribute 
  79. if (!$found_attribute_assignment) { 
  80. break; //exit loop - we've found the shortcode 
  81.  
  82. $last_found_char = $char; 
  83.  
  84. // Prevent infinite loops in our while(TRUE) 
  85. if ($index == $content_length) 
  86. break; 
  87.  
  88. $index++; 
  89.  
  90. // Get the shortcode 
  91. $shortcode = substr($content, $start_of_shortcode+1, --$index-$start_of_shortcode); 
  92. $shortcode_replacement = str_replace( 
  93. array('[', ']'), array('[', ']'), $shortcode 
  94. ); 
  95.  
  96. // Replace the shortcode with one that doesn't have nested shortcodes 
  97. $content = str_replace( 
  98. $shortcode,  
  99. $shortcode_replacement,  
  100. $content 
  101. ); 
  102.  
  103. // Calculate the offset for the next loop iteration 
  104. $offset = $index+1+strlen($shortcode_replacement)-strlen($shortcode); 
  105. reset($this->_shortcodes); 
  106.  
  107. return $content; 
  108.  
  109. /** 
  110. * Deactivates all shortcodes 
  111. */ 
  112. function deactivate_all() 
  113. foreach (array_keys($this->_shortcodes) as $shortcode) { 
  114. $this->deactivate($shortcode); 
  115.  
  116. /** 
  117. * Parses the content for shortcodes and returns the substituted content 
  118. * @param $content 
  119. * @return string 
  120. */ 
  121. function parse_content($content) 
  122. $regex = str_replace('%d', '(\d+)', $this->_placeholder_text); 
  123.  
  124. if (preg_match_all("/{$regex}/m", $content, $matches, PREG_SET_ORDER)) { 
  125. foreach ($matches as $match) { 
  126. $placeholder = array_shift($match); 
  127. $id = array_shift($match); 
  128. $content = str_replace($placeholder, $this->execute_found_shortcode($id), $content); 
  129.  
  130. return $content; 
  131.  
  132. function execute_found_shortcode($found_id) 
  133. $details = $this->_found[$found_id]; 
  134. if (isset($this->_shortcodes[$details['shortcode']])) { 
  135. return call_user_func($this->_shortcodes[$details['shortcode']], $details['params'], $details['inner_content']); 
  136. return "Invalid shortcode"; 
  137.  
  138. /** 
  139. * Adds a shortcode 
  140. * @param $name 
  141. * @param $callback 
  142. */ 
  143. function add_shortcode($name, $callback) 
  144. $this->_shortcodes[$name] = $callback; 
  145. add_shortcode($name, array(&$this, $name.'____wrapper')); 
  146.  
  147. /** 
  148. * Removes a shortcode 
  149. * @param $name 
  150. */ 
  151. function remove_shortcode($name) 
  152. unset($this->_shortcodes[$name]); 
  153. $this->deactivate($name); 
  154.  
  155. /** 
  156. * De-activates a shortcode 
  157. * @param $shortcode 
  158. */ 
  159. function deactivate($shortcode) 
  160. if (isset($this->_shortcodes[$shortcode])) 
  161. remove_shortcode($shortcode); 
  162.  
  163. function __call($method, $args) 
  164. $params = array_shift($args); 
  165. $inner_content = array_shift($args); 
  166. $parts = explode('____', $method); 
  167. $shortcode = array_shift($parts); 
  168. if (doing_filter('the_content') && !doing_filter('widget_text')) { 
  169. return $this->replace_with_placeholder($shortcode, $params, $inner_content); 
  170.  
  171. // For widgets, don't use placeholders 
  172. else { 
  173. $callback = $this->_shortcodes[$shortcode]; 
  174. return call_user_func($callback, $params, $inner_content); 
  175.  
  176.  
  177. function replace_with_placeholder($shortcode, $params=array(), $inner_content='') 
  178. $id = count($this->_found); 
  179. $this->_found[$id] = array( 
  180. 'shortcode' => $shortcode,  
  181. 'params' => $params,  
  182. 'inner_content' => $inner_content 
  183. ); 
  184.  
  185. return sprintf($this->_placeholder_text, $id); // try to wptexturize this! ha!