PageRenderTime 85ms CodeModel.GetById 25ms RepoModel.GetById 0ms app.codeStats 1ms

/wp-content/plugins/wordpress-bootstrap-css/hlt-bootstrap-shortcodes.php

https://github.com/jgtoriginal/wordpress-bootstrap-1
PHP | 1131 lines | 710 code | 222 blank | 199 comment | 98 complexity | cc254272de0b0365d023ede958f081ba MD5 | raw file
  1. <?php
  2. /**
  3. * Copyright (c) 2012 Worpit <support@worpit.com>
  4. * All rights reserved.
  5. *
  6. * "WordPress Bootstrap CSS" is distributed under the GNU General Public License, Version 2,
  7. * June 1991. Copyright (C) 1989, 1991 Free Software Foundation, Inc., 51 Franklin
  8. * St, Fifth Floor, Boston, MA 02110, USA
  9. *
  10. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  11. * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  12. * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  13. * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  14. * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  15. * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  16. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  17. * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  18. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  19. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  20. *
  21. */
  22. if ( !class_exists('HLT_BootstrapShortcodes') ):
  23. class HLT_BootstrapShortcodes {
  24. protected $m_sFileName;
  25. protected $m_sCollapseParentId;
  26. public function __construct( ) {
  27. $aMethods = get_class_methods( $this );
  28. $aExclude = array( 'idHtml',
  29. 'def',
  30. 'filterTheContent',
  31. 'filterTheContentToFixNamedAnchors',
  32. 'noEmptyHtml',
  33. 'noEmptyElement',
  34. 'PrintJavascriptForTooltips',
  35. 'PrintJavascriptForPopovers' );
  36. foreach ( $aMethods as $sMethod ) {
  37. if ( !in_array( $sMethod, $aExclude ) ) {
  38. if ( basename(__FILE__) == 'hlt-bootstrap-shortcodes.php' )
  39. add_shortcode( 'TBS_'.strtoupper( $sMethod ), array( &$this, $sMethod ) );
  40. }
  41. }
  42. add_filter( 'the_content', array( &$this, 'filterTheContent' ), 10 );
  43. add_filter( 'the_content', array( &$this, 'filterTheContentToFixNamedAnchors' ), 99 );
  44. /**
  45. * Move the wpautop until after the shortcodes have been run!
  46. * remove_filter( 'the_content', 'wpautop' );
  47. * add_filter( 'the_content', 'wpautop' , 99 );
  48. * add_filter( 'the_content', 'shortcode_unautop', 100 );
  49. */
  50. /**
  51. * Disable wpautop globally!
  52. * remove_filter( 'the_content', 'wpautop' );
  53. * remove_filter( 'comment_text', 'wpautop' );
  54. */
  55. }
  56. public function abbr( $inaAtts = array(), $insContent = '' ) {
  57. $aOptions = array(
  58. 'title' => array( '', '', 'This is the text that appears when you hover.' ),
  59. );
  60. if ( isset($inaAtts['help']) ) {
  61. return $this->getHelp($aOptions);
  62. }
  63. $this->processOptions( $inaAtts, $aOptions );
  64. //strip empty parameters
  65. $this->noEmptyElement( $inaAtts, 'id' );
  66. $this->noEmptyElement( $inaAtts, 'style' );
  67. $this->noEmptyElement( $inaAtts, 'class' );
  68. $sReturn = '<abbr title="'.$inaAtts['title'].'" '
  69. .$inaAtts['style']
  70. .$inaAtts['id']
  71. .$inaAtts['class']
  72. .'>'.$insContent.'</abbr>';
  73. return $sReturn;
  74. }
  75. public function text( $inaAtts = array(), $insContent = '' ) {
  76. $aOptions = array(
  77. 'color' => array( '', 'muted|lead|info|success|warning|error', 'Specify color class the text. If you have CSS styles defined they will probably override this.' )
  78. );
  79. if ( isset($inaAtts['help']) ) {
  80. return $this->getHelp($aOptions);
  81. }
  82. $this->processOptions( $inaAtts, $aOptions );
  83. $this->noEmptyElement( $inaAtts, 'id' );
  84. $this->noEmptyElement( $inaAtts, 'style' );
  85. //prefix the first class with "text-" to ensure correct class name for Twitter
  86. if ( $inaAtts['color'] != 'muted' ) {
  87. if ( !empty($inaAtts['color']) && !preg_match( '/^text-/', $inaAtts['color'] ) ) {
  88. $inaAtts['color'] = 'text-'.$inaAtts['color'];
  89. }
  90. }
  91. $inaAtts['color'] =
  92. $sReturn = '<p class="'.$inaAtts['color'].'" '
  93. .$inaAtts['style']
  94. .$inaAtts['id']
  95. .'>'.$insContent.'</p>';
  96. return $sReturn;
  97. }
  98. /**
  99. * Prints the necessary HTML for Twitter Bootstrap Icons.
  100. *
  101. * Defaults to: "icon-star-empty" icon
  102. *
  103. * @param $inaAtts
  104. * @param $insContent
  105. */
  106. public function icon( $inaAtts = array(), $insContent = '' ) {
  107. $aOptions = array(
  108. 'class' => array( 'icon-star-empty', '', 'Simply provide the class name of the icon desired.' ),
  109. 'white' => array( 'n', 'y|n', 'Set the icon to white.' ),
  110. );
  111. if ( isset($inaAtts['help']) ) {
  112. return $this->getHelp($aOptions);
  113. }
  114. $this->processOptions( $inaAtts, $aOptions );
  115. //strip empty parameters
  116. $this->noEmptyElement( $inaAtts, 'id' );
  117. $this->noEmptyElement( $inaAtts, 'style' );
  118. if ( $inaAtts['white'] == 'y' ) {
  119. $inaAtts['class'] .= ' icon-white';
  120. }
  121. $sReturn = '<i class="'.$inaAtts['class'].'"'.$inaAtts['style'].$inaAtts['id'].'></i>';
  122. return $sReturn;
  123. }//icon
  124. /**
  125. * Prints the necessary HTML for Twitter Bootstrap Labels
  126. *
  127. * Class may be one of: Primary Info Success Danger Warning Inverse
  128. *
  129. * @param $inaAtts
  130. * @param $insContent
  131. */
  132. public function button( $inaAtts = array(), $insContent = '' ) {
  133. $aOptions = array(
  134. 'element' => array( 'button', '', 'Manually specify the HTML element for this button' ),
  135. 'class' => array( '', 'btn-large|btn-small|btn-mini|btn-block', 'Specify additional button class styles.' ),
  136. 'color' => array( '', 'primary|info|success|warning|danger|inverse', 'Specify the button color class. Leave blank for default color.' ),
  137. 'link' => array( '', '', 'If specified, the button is a HTML anchor link' ),
  138. 'target' => array( '', '_blank|_parent|_self|_top', 'Specify the target, if link is provided. E.g. _blank .' ),
  139. 'title' => array( '', '', 'Set the link title attribute' ),
  140. 'value' => array( '0', '', 'Set the value of the button' ),
  141. 'text' => array( '', '', 'Set Button text' ),
  142. 'disabled' => array( 'n', 'y|n', 'Specify whether button is disabled.' ),
  143. 'toggle' => array( 'n', 'y|n', 'Specify whether button is a toggle button.' ),
  144. 'type' => array( 'button', '', 'Not used/relevant if "link" is provided.' ),
  145. );
  146. //Print Help if asked for and return
  147. if ( isset($inaAtts['help']) ) {
  148. return $this->getHelp($aOptions);
  149. }
  150. $this->processOptions( $inaAtts, $aOptions );
  151. $sElementType = $inaAtts['element'];
  152. if ( !empty( $inaAtts['link'] ) ) { //i.e. link is defined, force anchor tag
  153. $sElementType = 'a';
  154. $inaAtts['type'] = '';
  155. }
  156. if (empty($inaAtts['title']) && isset($inaAtts['link_title']) ) {
  157. $inaAtts['title'] = $inaAtts['link_title']; // backwards compatibility - originally only "link_title"
  158. }
  159. //strip empty parameters
  160. $this->noEmptyElement( $inaAtts, 'id' );
  161. $this->noEmptyElement( $inaAtts, 'style' );
  162. $this->noEmptyElement( $inaAtts, 'title' );
  163. $this->noEmptyElement( $inaAtts, 'type' );
  164. $this->noEmptyElement( $inaAtts, 'target' );
  165. $sClassString = 'btn';
  166. //Prefix first class with "btn-" to ensure correct class name for Twitter Bootstrap
  167. if ( !preg_match( '/^btn-/', $inaAtts['class'] ) ) {
  168. $sClassString .= ( empty($inaAtts['class']) ) ? '' : ' btn-'.$inaAtts['class'];
  169. } else if ( !empty($inaAtts['class']) ) {
  170. $sClassString .= ' '.$inaAtts['class'];
  171. }
  172. //Add disabled class
  173. $sClassString .= ( strtolower($inaAtts['disabled']) == 'y' ) ? ' disabled' : '';
  174. $sReturn = '<'.$sElementType
  175. .$inaAtts['style']
  176. .$inaAtts['id']
  177. .$inaAtts['type']
  178. .$inaAtts['target']
  179. .' class="'.$sClassString.'"'
  180. ;
  181. if ( $sElementType == 'a' ) {
  182. $sReturn .= ' href="'.$inaAtts['link'].'"'.$inaAtts['title'];
  183. }
  184. else {
  185. $sReturn .= ' value="'.$inaAtts['value'].'"';
  186. }
  187. //Creates a toggle button
  188. if ( strtolower($inaAtts['toggle']) == 'y' )
  189. $sReturn .= ' data-toggle="button"';
  190. //Add disabled field in the case of buttons
  191. if ( $sElementType == 'button' AND strtolower($inaAtts['disabled']) == 'y' ) {
  192. $sReturn .= ' disabled="disabled"';
  193. }
  194. //Final close and insert content
  195. if ( strtolower($sElementType) == 'input') {
  196. //special case for INPUT elements
  197. $sReturn .= ' />';
  198. } else {
  199. //Priority for button text is given to the text parameter
  200. if ( !empty($inaAtts['text']) ) {
  201. $insContent = $inaAtts['text'];
  202. } else if ( empty($insContent) ) {
  203. $insContent = 'button';
  204. }
  205. $sReturn .= '>'.$this->doShortcode( $insContent ).'</'.$sElementType.'>';
  206. }
  207. return $sReturn;
  208. }//button
  209. /**
  210. * Toggle button options are "buttons-checkbox" and "buttons-radio"
  211. *
  212. * @param $inaAtts
  213. * @param $insContent
  214. */
  215. public function buttonGroup( $inaAtts = array(), $insContent = '' ) {
  216. $aOptions = array(
  217. 'toggle' => array( '', 'Toggles whether buttons are in a group or not' ),
  218. );
  219. //Print Help if asked for and return
  220. if ( isset($inaAtts['help']) ) {
  221. return $this->getHelp($aOptions);
  222. }
  223. $this->processOptions( $inaAtts, $aOptions );
  224. //filters out empty elements
  225. $this->noEmptyElement( $inaAtts, 'id' );
  226. $this->noEmptyElement( $inaAtts, 'style' );
  227. $inaAtts['toggle'] = $this->noEmptyHtml( $inaAtts['toggle'], 'data-toggle' );
  228. $sReturn = '<div class="btn-group '.$inaAtts['class']. '"'
  229. .$inaAtts['id']
  230. .$inaAtts['style']
  231. .$inaAtts['toggle']
  232. .'>'.$this->doShortcode( $insContent ).'</div>'
  233. ;
  234. return $sReturn;
  235. }//buttonGroup
  236. /**
  237. * Prints the necessary HTML for Twitter Bootstrap Badges
  238. *
  239. * class may be one of: success, warning, error, info, inverse
  240. *
  241. * only supported in Twitter Bootstrap version 2.0+
  242. *
  243. * @param $inaAtts
  244. * @param $insContent
  245. * @return string
  246. */
  247. public function badge( $inaAtts = array(), $insContent = '' ) {
  248. $aOptions = array(
  249. 'color' => array( '', 'info|success|warning|important|inverse', 'Specify color class of the badge - leave blank for default' )
  250. );
  251. //Print Help if asked for and return
  252. if ( isset($inaAtts['help']) ) {
  253. return $this->getHelp( $aOptions );
  254. }
  255. $this->processOptions( $inaAtts, $aOptions );
  256. //filters out empty elements
  257. $this->noEmptyElement( $inaAtts, 'id' );
  258. $this->noEmptyElement( $inaAtts, 'style' );
  259. //prefix the first class with "badge-" to ensure correct class name for Twitter
  260. if ( !empty($inaAtts['class']) && !preg_match( '/^badge-/', $inaAtts['class'] ) ) {
  261. $inaAtts['class'] = 'badge-'.$inaAtts['class'];
  262. }
  263. $sReturn = '<span class="badge '.$inaAtts['class'].'"'
  264. .$inaAtts['style']
  265. .$inaAtts['id']
  266. .'>'.$this->doShortcode( $insContent ).'</span>'
  267. ;
  268. return $sReturn;
  269. }
  270. /**
  271. * Prints the necessary HTML for Twitter Bootstrap Labels
  272. *
  273. * class may be one of: success, warning, important, notice
  274. *
  275. * @param $inaAtts
  276. * @param $insContent
  277. * @return string
  278. */
  279. public function label( $inaAtts = array(), $insContent = '' ) {
  280. $aOptions = array(
  281. 'color' => array( '', 'info|success|warning|important|inverse', 'Specify color class of the label - leave blank for default.' )
  282. );
  283. //Print Help if asked for and return
  284. if ( isset($inaAtts['help']) ) {
  285. return $this->getHelp( $aOptions );
  286. }
  287. $this->processOptions( $inaAtts, $aOptions );
  288. //filters out empty elements
  289. $this->noEmptyElement( $inaAtts, 'id' );
  290. $this->noEmptyElement( $inaAtts, 'style' );
  291. //prefix the first class with "label-" to ensure correctly class name for Twitter
  292. if ( !empty($inaAtts['class']) && !preg_match( '/^label-/', $inaAtts['class'] ) ) {
  293. $inaAtts['class'] = 'label-'.$inaAtts['class'];
  294. }
  295. $sReturn = '<span class="label '.$inaAtts['class'].'"'
  296. .$inaAtts['style']
  297. .$inaAtts['id']
  298. .'>'.$this->doShortcode( $insContent ).'</span>'
  299. ;
  300. return $sReturn;
  301. }//label
  302. /**
  303. *
  304. * @param $inaAtts
  305. * @param $insContent
  306. * @return string
  307. */
  308. public function blockquote( $inaAtts = array(), $insContent = '' ) {
  309. $aOptions = array(
  310. 'source' => array( '', '', 'Optional source text for the quotation' ),
  311. );
  312. //Print Help if asked for and return
  313. if ( isset($inaAtts['help']) ) {
  314. return $this->getHelp( $aOptions );
  315. }
  316. $this->processOptions( $inaAtts, $aOptions );
  317. //filters out empty elements
  318. $this->noEmptyElement( $inaAtts, 'style' );
  319. $this->noEmptyElement( $inaAtts, 'id' );
  320. $this->noEmptyElement( $inaAtts, 'class' );
  321. $sReturn = '<blockquote '.$inaAtts['style']
  322. .$inaAtts['id']
  323. .$inaAtts['class']
  324. .'><p>'.$this->doShortcode( $insContent ).'</p><small>'.$inaAtts['source'].'</small></blockquote>'
  325. ;
  326. return $sReturn;
  327. }//blockquote
  328. /**
  329. * Returns a DIV with appropriate classes for Twitter Bootstrap Alerts.
  330. *
  331. * Support for Twitter Bootstrap 1.4.x was removed with version 2.0.3 of the plugin.
  332. *
  333. * Class may be one of: error, warning, success, info
  334. *
  335. * @param $inaAtts
  336. * @param $insContent
  337. */
  338. public function alert( $inaAtts = array(), $insContent = '' ) {
  339. $aOptions = array(
  340. 'class' => array( '', 'alert-block', 'Add your desired classes, or alert-block to create larger alert' ),
  341. 'color' => array( '', 'info|success|error', 'Specify color class of the alert box - leave blank for default' ),
  342. 'heading' => array( '', '', 'Optional heading text for the alert box' ),
  343. );
  344. //Print Help if asked for and return
  345. if ( isset($inaAtts['help']) ) {
  346. return $this->getHelp( $aOptions );
  347. }
  348. $this->processOptions( $inaAtts, $aOptions );
  349. //Ensures class starts with "alert-"
  350. if ( !empty($inaAtts['class']) && !preg_match( '/^alert-/', $inaAtts['class'] ) ) {
  351. $inaAtts['class'] = 'alert-'.$inaAtts['class'];
  352. }
  353. //filters out empty elements
  354. $this->noEmptyElement( $inaAtts, 'id' );
  355. $this->noEmptyElement( $inaAtts, 'style' );
  356. $sReturn = '<div class="alert '.$inaAtts['class'].'"'
  357. .$inaAtts['style']
  358. .$inaAtts['id']
  359. .'>';
  360. if ( !empty($inaAtts['heading']) ) {
  361. $sReturn .= '<h4 class="alert-heading">'.$inaAtts['heading'].'</h4>';
  362. }
  363. $sReturn .= $this->doShortcode( $insContent ).'</div>';
  364. return $sReturn ;
  365. }
  366. public function code( $inaAtts = array(), $insContent = '' ) {
  367. $this->def( $inaAtts, 'style' );
  368. $this->def( $inaAtts, 'id' );
  369. $sReturn = '<pre class="prettyprint linenums" '.$this->idHtml( $inaAtts['id'] ).' '.$this->noEmptyHtml( $inaAtts['style'], 'style' ).'>'.$insContent.'</pre>';
  370. return $sReturn;
  371. }
  372. /**
  373. * Options for 'placement' are top | bottom | left | right
  374. */
  375. public function tooltip( $inaAtts = array(), $insContent = '' ) {
  376. $aOptions = array(
  377. 'help_text' => 'Remember to enable Bootstrap Javascript in the options for this to work.',
  378. 'placement' => array( 'top', 'top|bottom|left|right', 'Location of the tooltip.' ),
  379. 'title' => array( '', '', 'Specify content text of the tooltip' ),
  380. 'trigger' => array( 'hover', 'click|hover|focus|manual', 'How you want your Tooltip activated. E.g. when a user clicks or hovers on the item')
  381. );
  382. //Print Help if asked for and return
  383. if ( isset($inaAtts['help']) ) {
  384. return $this->getHelp( $aOptions );
  385. }
  386. $this->processOptions( $inaAtts, $aOptions );
  387. if ( $inaAtts['placement'] == 'above' ) {
  388. $inaAtts['placement'] = 'top';
  389. }
  390. if ( $inaAtts['placement'] == 'below' ) {
  391. $inaAtts['placement'] = 'bottom';
  392. }
  393. //filters out empty elements
  394. $this->noEmptyElement( $inaAtts, 'id' );
  395. $this->noEmptyElement( $inaAtts, 'style' );
  396. $this->noEmptyElement( $inaAtts, 'class' );
  397. $sReturn = $insContent;
  398. if ( $inaAtts['title'] != '' ) {
  399. $sReturn = '<span'
  400. .' rel="tooltip" data-placement="'.$inaAtts['placement'].'" data-original-title="'.$inaAtts['title'].'"'
  401. .' data-trigger="'.$inaAtts['trigger'].'"'
  402. .$inaAtts['style']
  403. .$inaAtts['id']
  404. .$inaAtts['class']
  405. .'>'.$this->doShortcode($insContent).'</span>';
  406. }
  407. remove_action( 'wp_footer', array(__CLASS__, 'PrintJavascriptForTooltips' ) );
  408. add_action( 'wp_footer', array(__CLASS__, 'PrintJavascriptForTooltips' ) );
  409. return $sReturn;
  410. }
  411. /**
  412. * Options for 'placement' are top | bottom | left | right
  413. */
  414. public function popover( $inaAtts = array(), $insContent = '' ) {
  415. $aOptions = array(
  416. 'help_text' => 'Remember to enable Bootstrap Javascript in the options for this to work.',
  417. 'placement' => array( 'right', 'top|bottom|left|right', 'Location of the popover.' ),
  418. 'title' => array( '', '', 'The Title text of the popover' ),
  419. 'content' => array( '', '', 'The main content text of the popover' ),
  420. 'trigger' => array( 'hover', 'click|hover|focus|manual', 'How you want your Popover activated. E.g. when a user clicks or hovers on the item')
  421. );
  422. //Print Help if asked for and return
  423. if ( isset($inaAtts['help']) ) {
  424. return $this->getHelp( $aOptions );
  425. }
  426. $this->processOptions( $inaAtts, $aOptions );
  427. //filters out empty elements
  428. $this->noEmptyElement( $inaAtts, 'id' );
  429. $this->noEmptyElement( $inaAtts, 'style' );
  430. $this->noEmptyElement( $inaAtts, 'class' );
  431. $sReturn = '<span'
  432. .' rel="popover" data-placement="'.$inaAtts['placement'].'" title="'.$inaAtts['title'].'"'
  433. .' data-content="'.$inaAtts['content'].'"'
  434. .' data-trigger="'.$inaAtts['trigger'].'"'
  435. .$inaAtts['style']
  436. .$inaAtts['id']
  437. .$inaAtts['class'].'>'.$this->doShortcode( $insContent ).'</span>';
  438. remove_action( 'wp_footer', array(__CLASS__, 'PrintJavascriptForPopovers' ) );
  439. add_action( 'wp_footer', array(__CLASS__, 'PrintJavascriptForPopovers' ) );
  440. return $sReturn;
  441. }
  442. public function progress_bar( $inaAtts = array(), $insContent = '' ) {
  443. $aOptions = array(
  444. 'color' => array( '', 'info|success|warning|danger', 'Change bar color class.' ),
  445. 'width' => array( '50%', '', 'Specify width of the progress bar, e.g. 10px, 70%' ),
  446. 'striped' => array( 'n', 'y|n', 'Toggles striped progress bar effect.n' ),
  447. 'active' => array( 'n', 'y|n', 'Toggle active progress bar effect.' ),
  448. );
  449. //Print Help if asked for and return
  450. if ( isset($inaAtts['help']) ) {
  451. return $this->getHelp( $aOptions );
  452. }
  453. $this->processOptions( $inaAtts, $aOptions );
  454. //prefix the first class with "badge-" to ensure correct class name for Twitter
  455. if ( !empty($inaAtts['class']) && !preg_match( '/^progress-/', $inaAtts['class'] ) ) {
  456. $inaAtts['class'] = 'progress-'.$inaAtts['class'];
  457. }
  458. $this->noEmptyElement( $inaAtts, 'style' );
  459. $this->noEmptyElement( $inaAtts, 'id' );
  460. if ( strtolower($inaAtts['striped']) == 'y' ) {
  461. $inaAtts['class'] .= ' progress-striped';
  462. if ( strtolower($inaAtts['active']) == 'y' ) {
  463. $inaAtts['class'] .= ' active';
  464. }
  465. }
  466. ob_start();
  467. ?>
  468. <div class="progress <?php echo $inaAtts['class']; ?>">
  469. <div class="bar" style="width: <?php echo $inaAtts['width']; ?>;"><?php echo $this->doShortcode( $insContent ); ?></div>
  470. </div>
  471. <?php
  472. $sContent = ob_get_contents();
  473. ob_end_clean();
  474. return $sContent;
  475. }
  476. /**
  477. * Prints the HTML necessary for Bootstrap Rows. Will also create a container DIV but it has the option
  478. * to not print it with: container=n
  479. *
  480. * There is also the option to make it fluid layout with: fluid=y
  481. *
  482. * @param $inaAtts
  483. * @param $insContent
  484. */
  485. public function row( $inaAtts = array(), $insContent = '' ) {
  486. $aOptions = array(
  487. 'fluid' => array( 'n', 'y|n', 'Toggles whether fluid classes are used.' ),
  488. 'container' => array( 'n', 'y|n', 'Toggles whether to print HTML for surrounding container.' ),
  489. 'cstyle' => array( '', '', 'If you print container, optional inline CSS styling on the container DIV' ),
  490. 'cid' => array( '', '', 'If you print container, optional ID added to the container DIV' ),
  491. 'cclass' => array( '', '', 'If you print container, optional class(es) added to the container DIV' ),
  492. );
  493. //Print Help if asked for and return
  494. if ( isset($inaAtts['help']) ) {
  495. return $this->getHelp( $aOptions );
  496. }
  497. $this->processOptions( $inaAtts, $aOptions );
  498. //filters out empty elements
  499. $this->noEmptyElement( $inaAtts, 'id' );
  500. $this->noEmptyElement( $inaAtts, 'style' );
  501. $sFluid = ( strtolower($inaAtts['fluid']) == 'y' ) ? '-fluid' : '';
  502. $sReturn = '<div class="row'.$sFluid.' '.$inaAtts['class'].'" '
  503. .$inaAtts['style']
  504. .$inaAtts['id'].'>';
  505. $sReturn .= $this->doShortcode( $insContent ) .'</div>';
  506. if ( strtolower($inaAtts['container']) == 'y' ) {
  507. $this->noEmptyElement( $inaAtts, 'cid', 'id' );
  508. $this->noEmptyElement( $inaAtts, 'cstyle', 'style' );
  509. $sReturn = '<div class="container'.$sFluid.' '.$inaAtts['cclass'].'"'
  510. .$inaAtts['cstyle']
  511. .$inaAtts['cid']
  512. .'>'.$sReturn.'</div>';
  513. }
  514. return $sReturn;
  515. }//row
  516. public function column( $inaAtts = array(), $insContent = '' ) {
  517. $aOptions = array(
  518. 'size' => array( '1', '1|2|3|4|5|6|7|8|9|10|11|12', 'Specify the size of the span.' ),
  519. 'offset' => array( '', '1|2|3|4|5|6|7|8|9|10|11|12', 'Specify the size of the offset.' ),
  520. );
  521. //Print Help if asked for and return
  522. if ( isset($inaAtts['help']) ) {
  523. return $this->getHelp( $aOptions );
  524. }
  525. $this->processOptions( $inaAtts, $aOptions );
  526. //filters out empty elements
  527. $this->noEmptyElement( $inaAtts, 'id' );
  528. $this->noEmptyElement( $inaAtts, 'style' );
  529. $sReturn = '<div class="span'.$inaAtts['size'].' '.$inaAtts['offset'].' '.$inaAtts['class']. '"'
  530. .$inaAtts['style']
  531. .$inaAtts['id'].'>';
  532. $sReturn .= $this->doShortcode( $insContent ) .'</div>';
  533. return $sReturn;
  534. }//row
  535. public function span( $inaAtts = array(), $insContent = '' ) {
  536. return $this->column( $inaAtts, $insContent );
  537. }
  538. public function collapse( $inaAtts = array(), $insContent = '' ) {
  539. $aOptions = array(
  540. 'accordion' => array( 'n', 'y|n', 'Toggle Accordion effect (where when one opens, the rest in the group closes).' ),
  541. 'id' => array( 'Randomly Generated', '', 'Specify ID if you need it, otherwise randomly generated.' )
  542. );
  543. //Print Help if asked for and return
  544. if ( isset($inaAtts['help']) ) {
  545. return $this->getHelp( $aOptions );
  546. }
  547. $aOptions['id'][0] = 'TbsCollapseId-'.rand();
  548. $this->processOptions( $inaAtts, $aOptions );
  549. //if accordian is set, set the Parent ID so we can use it later.
  550. $this->m_sCollapseParentId = ( strtolower($inaAtts['accordion']) == 'y' )? '#'.$inaAtts['id'] : '';
  551. $this->noEmptyElement( $inaAtts, 'style' );
  552. $this->noEmptyElement( $inaAtts, 'id' );
  553. ob_start();
  554. ?>
  555. <div class="accordion <?php echo $inaAtts['class']; ?>" <?php echo $inaAtts['id']; ?> <?php echo $inaAtts['style']; ?>>
  556. <?php echo $this->doShortcode( $insContent ); ?>
  557. </div>
  558. <?php
  559. $sContent = ob_get_contents();
  560. ob_end_clean();
  561. return $sContent;
  562. }
  563. public function collapse_group( $inaAtts = array(), $insContent = '' ) {
  564. $aOptions = array(
  565. 'group-id' => array( 'Randomly Generated', '', 'Specify ID if you need it, otherwise randomly generated.' ),
  566. 'title' => array( '"title" Not Set', '', 'Specify text for the link clicked to expand or collapse text' ),
  567. 'open' => array( 'n', 'y|n', 'Toggles whether text is expanded/open when the page loads.' ),
  568. );
  569. //Print Help if asked for and return
  570. if ( isset($inaAtts['help']) ) {
  571. return $this->getHelp( $aOptions );
  572. }
  573. $aOptions['parent'][0] = $this->m_sCollapseParentId; //this will add the accordion effect, or not.
  574. $sCollapseGroupId = 'TbsCollapseGroupId-'.rand();
  575. $aOptions['group-id'][0] = $sCollapseGroupId;
  576. $this->processOptions( $inaAtts, $aOptions );
  577. $this->noEmptyElement( $inaAtts, 'parent', 'data-parent' ); //this should only be printed if accordion=y was set in the parent Shortcode
  578. $this->noEmptyElement( $inaAtts, 'style' );
  579. $this->noEmptyElement( $inaAtts, 'id' );
  580. ob_start();
  581. ?>
  582. <div class="accordion-group <?php echo $inaAtts['class']; ?>" <?php echo $inaAtts['id']; ?> <?php echo $inaAtts['style']; ?>>
  583. <div class="accordion-heading">
  584. <a class="accordion-toggle" data-toggle="collapse" <?php echo $inaAtts['parent']; ?> href="#<?php echo $inaAtts['group-id']; ?>">
  585. <?php echo $inaAtts['title']; ?>
  586. </a>
  587. </div>
  588. <div id="<?php echo $inaAtts['group-id']; ?>" class="accordion-body collapse <?php echo (strtolower($inaAtts['open']) == 'y') ? 'in' : '';?>">
  589. <div class="accordion-inner">
  590. <?php echo $insContent; ?>
  591. </div>
  592. </div>
  593. </div>
  594. <?php
  595. $sContent = ob_get_contents();
  596. ob_end_clean();
  597. return $sContent;
  598. }
  599. public function dropdown( $inaAtts = array(), $insContent = '' ) {
  600. $this->def( $inaAtts, 'name', 'Undefined' );
  601. $insContent = '
  602. <ul class="tabs">
  603. <li class="dropdown" data-dropdown="dropdown">
  604. <a class="dropdown-toggle" href="#">'.$inaAtts['name'].'</a>
  605. <ul class="dropdown-menu">
  606. '.$insContent.'
  607. </ul>
  608. </li>
  609. </ul>
  610. ';
  611. return $this->doShortcode( $insContent );
  612. }
  613. /**
  614. * This is used by both dropdown and tabgroup/tab
  615. */
  616. public function dropdown_option( $inaAtts = array(), $insContent = '' ) {
  617. $this->def( $inaAtts, 'name', 'Undefined' );
  618. $this->def( $inaAtts, 'link', '#' );
  619. $insContent = '<li><a href="'.$inaAtts['link'].'">'.$inaAtts['name'].'</a></li>';
  620. return $this->doShortcode( $insContent );
  621. }
  622. public function tabgroup( $inaAtts = array(), $insContent ) {
  623. $aTabs = array();
  624. $aMatches = array();
  625. $nOffsetAdjustment = 0;
  626. $i = 0;
  627. /**
  628. * Because there are 2 separate sections of HTML for the tabs to work, we need to
  629. * look for the TBS_TAB shortcodes now, to create the buttons. The $insContent is
  630. * passed onwards and will be used to create the tab content panes.
  631. *
  632. * PREG_OFFSET_CAPTURE requires PHP 4.3.0
  633. */
  634. if ( preg_match_all( '/\[TBS_TAB([^\]]*)\]/', $insContent, $aMatches, PREG_SET_ORDER | PREG_OFFSET_CAPTURE ) ) {
  635. foreach ( $aMatches as $aMatch ) {
  636. //aMatch = Array ( [0] => Array ( [0] => [TBS_TAB page_id="53" name="test1"] [1] => 1 ) [1] => Array ( [0] => page_id="53" name="test1" [1] => 9 ) )
  637. if ( !isset( $aMatch[1] ) ) {
  638. continue;
  639. }
  640. $sName = "Undefined";
  641. if ( preg_match( '/name\s*=\s*("|\')(.+)\g{-2}+/i', $aMatch[1][0], $aSubMatches ) ) {
  642. $sName = $aSubMatches[2];
  643. }
  644. $sType = "page";
  645. if ( preg_match( '/type\s*=\s*("|\')(page|dropdown)\g{-2}+/i', $aMatch[1][0], $aSubMatches ) ) {
  646. $sType = $aSubMatches[2];
  647. }
  648. if ( $sType == "page" ) {
  649. $aTabs[] = '<li class="'.($i == 0? 'active': '').'"><a href="#TbsTabId'.$i.'">'.$sName.'</a></li>';
  650. }
  651. else {
  652. /**
  653. * Handle the dropdowns as the tab() shortcode handles the tab contents only
  654. */
  655. $nOffsetTemp = $aMatch[0][1] + $nOffsetAdjustment;
  656. $sRemainder = substr( $insContent, $nOffsetTemp + strlen( $aMatch[0][0] ) );
  657. $nPos = strpos( $sRemainder, '[/TBS_TAB]' );
  658. $sRemainder = substr( $sRemainder, 0, $nPos );
  659. // match all dropdowns until [/TBS_TAB]
  660. if ( !preg_match_all( '/\[TBS_DROPDOWN_OPTION([^\]]*)\]/', $sRemainder, $aSubMatches, PREG_SET_ORDER ) ) {
  661. continue;
  662. }
  663. $aOptions = array();
  664. foreach ( $aSubMatches as $aSubMatch ) {
  665. $sLink = '#';
  666. if ( preg_match( '/link\s*=\s*("|\')(.*)\g{-2}+/i', $aSubMatch[1][0], $aSubMatches ) ) {
  667. $sLink = $aSubMatches[2];
  668. }
  669. $sName = 'Undefined';
  670. if ( preg_match( '/name\s*=\s*("|\')(.*)\g{-2}+/i', $aSubMatch[1][0], $aSubMatches ) ) {
  671. $sName = $aSubMatches[2];
  672. }
  673. $aOptions[] = '<li><a href="'.$sLink.'">'.$sName.'</a></li>';
  674. }
  675. $aTabs[] = '
  676. <li class="dropdown" data-dropdown="dropdown">
  677. <a class="dropdown-toggle" href=" #">'.$sName.'</a>
  678. <ul class="dropdown-menu">
  679. '.implode( '', $aOptions ).'
  680. </ul>
  681. </li>
  682. ';
  683. }
  684. $nOffset = $aMatch[0][1] + $nOffsetAdjustment;
  685. $nLength = strlen( $aMatch[0][0] );
  686. $sAddition = ' id="TbsTabId'.$i.'"';
  687. $insContent = substr_replace( $insContent, '[TBS_TAB'.($aMatch[1][0]).$sAddition.']', $nOffset, $nLength );
  688. $nOffsetAdjustment += strlen( $sAddition );
  689. $i++;
  690. }
  691. }
  692. $insContent = '
  693. <ul class="nav nav-tabs" data-tabs="tabs">
  694. '.implode( "\n", $aTabs ).'
  695. </ul>
  696. <div id="my-tab-content" class="tab-content">
  697. '.$insContent.'
  698. </div>
  699. ';
  700. return $this->doShortcode( $insContent );
  701. }
  702. /**
  703. * Reference: http://codex.wordpress.org/Function_Reference/get_page
  704. */
  705. public function tab( $inaAtts = array(), $insContent = '' ) {
  706. $this->def( $inaAtts, 'page_id', 0 );
  707. $this->def( $inaAtts, 'type', 'page' ); // can be either page or dropdown
  708. // If this value is never not set, then the tabgroup method didn't do it's job!
  709. $this->def( $inaAtts, 'id', 'TbsTabId_' );
  710. // Actually not used as the tab name is used by the TabGroup
  711. $this->def( $inaAtts, 'name', 'Undefined' );
  712. if ( $inaAtts['page_id'] > 0 ) {
  713. $oPage = get_page( $inaAtts['page_id'] );
  714. if ( !is_null( $oPage ) ) {
  715. $insContent = $oPage->post_content;
  716. }
  717. }
  718. $nIndex = intval( str_replace( 'TbsTabId', '', $inaAtts['id'] ) );
  719. $insContent = '<div id="'.$inaAtts['id'].'" class="tab-pane'.($nIndex == 0?' active':'').'">'.$insContent.'</div>';
  720. return $this->doShortcode( $insContent );
  721. }
  722. /**
  723. * Given the array of parameters/attributes and array of options and their defaults, sets them all up.
  724. *
  725. * @param $inaAtts
  726. * @param $inaOptions
  727. */
  728. protected function processOptions( &$inaAtts, &$inaOptions ) {
  729. $aDefaults = array(
  730. 'style' => array( '', '', 'Custom inline styling applied to this element' ),
  731. 'id' => array( '', '', 'Custom ID added to this element' ),
  732. 'class' => array( '', '', 'Custom class(es) added to this element' )
  733. );
  734. if ( empty($inaOptions) ) {
  735. $inaOptions = $aDefaults;
  736. } else {
  737. $inaOptions = array_merge( $aDefaults, $inaOptions );
  738. }
  739. foreach ($inaOptions as $sOption => $aOptionData) {
  740. list( $sDefault, $sDescription ) = $aOptionData;
  741. $this->def( $inaAtts, $sOption, $sDefault );
  742. }
  743. if ( !empty( $inaAtts['color'] ) ) {
  744. $inaAtts['class'] = $inaAtts['color'] .' '. $inaAtts['class'];
  745. }
  746. }
  747. protected function getHelp( &$inaOptions ) {
  748. $aDefaults = array(
  749. 'help_text' => '',
  750. 'style' => array( '', '', 'Custom inline styling applied to this element' ),
  751. 'id' => array( '', '', 'Custom ID added to this element' ),
  752. 'class' => array( '', '', 'Custom class(es) added to this element' )
  753. );
  754. if ( empty($inaOptions) ) {
  755. $inaOptions = $aDefaults;
  756. } else {
  757. $inaOptions = array_merge( $aDefaults, $inaOptions );
  758. }
  759. $sHelp = '
  760. <style>
  761. #BootstrapHelpBlock ul {
  762. margin-left: 0;
  763. }
  764. #BootstrapHelpBlock p,
  765. #BootstrapHelpBlock li {
  766. font-family: arial;
  767. font-size: 12px !important;
  768. }
  769. #BootstrapHelpBlock .option_name,
  770. #BootstrapHelpBlock .option_value {
  771. font-family: courier;
  772. }
  773. #BootstrapHelpBlock .option_value {
  774. background-color: white;
  775. border: 1px dashed #888;
  776. margin-left: 6px;
  777. padding: 3px 3px;
  778. }
  779. </style>
  780. <div class="well" id="BootstrapHelpBlock">
  781. ';
  782. if ( !empty($inaOptions['help_text'] ) ) {
  783. $sHelp .= '<p>'.$inaOptions['help_text'].'</p>';
  784. }
  785. $sHelp .= '<p>Options are as follows (default values in brackets):</p>
  786. <ul>
  787. ';
  788. foreach ($inaOptions as $sOption => $aOptionData) {
  789. if ($sOption == 'help_text') {
  790. continue;
  791. }
  792. list( $sDefault, $sValues, $sDescription ) = $aOptionData;
  793. $sDefault = (empty($sDefault))? 'none' : '"'.$sDefault.'"';
  794. $sHelp .= '<li><span class="option_name">'.$sOption.'</span> ( '.$sDefault.' ) ';
  795. if ( $sValues !== '' ) {
  796. $sHelp .= '- Possible Values:';
  797. $aPossibleValues = explode( '|', $sValues );
  798. foreach( $aPossibleValues as $sValue ) {
  799. $sHelp .= '<span class="option_value">'.$sValue.'</span>';
  800. }
  801. $sHelp .= '. ';
  802. }
  803. $sHelp .= '<em>'.$sDescription.'</em></li>';
  804. }
  805. $sHelp .= '
  806. </ul>
  807. </div>
  808. ';
  809. return $sHelp;
  810. }
  811. public static function PrintJavascriptForPopovers() {
  812. $sJavascript = "
  813. <!-- BEGIN: WordPress Twitter Bootstrap CSS from http://worpit.com/ : Popover-enabling Javascript -->
  814. <script type='text/javascript'>
  815. jQuery( document ).ready(
  816. function () {
  817. jQuery( '*[rel=popover]')
  818. .popover();
  819. jQuery( '*[data-popover=popover]')
  820. .popover();
  821. }
  822. );
  823. </script>
  824. <!-- END: Popovers-enabling Javascript -->
  825. ";
  826. echo $sJavascript;
  827. }//PrintJavascriptForPopovers
  828. public static function PrintJavascriptForTooltips() {
  829. $sJavascript = "
  830. <!-- BEGIN: WordPress Twitter Bootstrap CSS from http://worpit.com/ : Tooltip-enabling Javascript -->
  831. <script type=\"text/javascript\">
  832. jQuery( document ).ready(
  833. function () {
  834. jQuery( '*[rel=tooltip],*[data-tooltip=tooltip]' ).tooltip();
  835. }
  836. );
  837. </script>
  838. <!-- END: Tooltip-enabling Javascript -->
  839. ";
  840. echo $sJavascript;
  841. }//PrintJavascriptForTooltips
  842. /**
  843. * Public, but should never be directly accessed other than by the WP add_filter method.
  844. * @param $insContent
  845. */
  846. public function filterTheContent( $insContent = "" ) {
  847. // Remove <p>'s that get added to [TBS...] by wpautop.
  848. $insContent = preg_replace( '|(<p>\s*)?(\[/?TBS[^\]]+\])(\s*</p>)?|', "$2", $insContent );
  849. $insContent = preg_replace( '|(<br />\s*)?(\[/?TBS[^\]]+\])(\s*</p>)?|', "$2", $insContent );
  850. return $insContent;
  851. }
  852. public function filterTheContentToFixNamedAnchors( $insContent = "" ) {
  853. $sPattern = '/(<a\s+href=")(.*)(#TbsTabId[0-9]+">(.*)<\/a>)/';
  854. $insContent = preg_replace( $sPattern, '$1$3', $insContent );
  855. return $insContent;
  856. }
  857. /**
  858. * name collision on "default"
  859. */
  860. protected function def( &$aSrc, $insKey, $insValue = '' ) {
  861. if ( !isset( $aSrc[$insKey] ) ) {
  862. $aSrc[$insKey] = $insValue;
  863. }
  864. }
  865. protected function idHtml( $insId ) {
  866. return (($insId != '')? ' id="'.$insId.'" ' : '' );
  867. }
  868. protected function noEmptyHtml( $insContent, $insAttr ) {
  869. return (($insContent != '')? ' '.$insAttr.'="'.$insContent.'" ' : '' );
  870. }
  871. protected function noEmptyElement( &$inaArgs, $insAttrKey, $insElement = '' ) {
  872. $sAttrValue = $inaArgs[$insAttrKey];
  873. $insElement = ( $insElement == '' )? $insAttrKey : $insElement;
  874. $inaArgs[$insAttrKey] = ( empty($sAttrValue) ) ? '' : ' '.$insElement.'="'.$sAttrValue.'"';
  875. }
  876. /**
  877. * Only implemented for possible future customisation
  878. * @param unknown_type $insContent
  879. */
  880. protected function doShortcode( $insContent ) {
  881. return do_shortcode( $insContent );
  882. }
  883. /**
  884. * DEPRECATED: To BE EVENTUALLY REMOVED AS UNSUPPORTED IN Twitter Bootstrap 2+
  885. *
  886. * Uses alert() function but just adds the class "block-message"
  887. *
  888. * class may be one of: error, warning, success, info
  889. *
  890. * @param $inaAtts
  891. * @param $insContent
  892. */
  893. public function block( $inaAtts = array(), $insContent = '' ) {
  894. return '<strong>Warning: You are using a deprecated shortcode. Please replace your [TBS_BLOCK] with [TBS_ALERT class="alert-block"]</strong>';
  895. }
  896. /**
  897. * DEPRECATED: To BE EVENTUALLY REMOVED AS UNSUPPORTED IN Twitter Bootstrap 2+
  898. *
  899. * Options for 'placement' are above | below | left | right
  900. *
  901. * @param $inaAtts
  902. * @param $insContent
  903. */
  904. public function twipsy( $inaAtts = array(), $insContent = '' ) {
  905. /* return $this->tooltip($inaAtts, $insContent); */
  906. return '<strong>Warning: You are using a deprecated shortcode. Please replace your [TBS_TWIPSY] with [TBS_TOOLTIP]</strong>';
  907. }
  908. }//class HLT_BootstrapShortcodes
  909. endif;