Guest User

bbcode.php

a guest
Nov 7th, 2012
216
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
PHP 63.81 KB | None | 0 0
  1. <?php
  2. /**
  3.  * Kunena Component
  4.  * @package Kunena.Framework
  5.  * @subpackage BBCode
  6.  *
  7.  * @copyright (C) 2008 - 2012 Kunena Team. All rights reserved.
  8.  * @license http://www.gnu.org/copyleft/gpl.html GNU/GPL
  9.  * @link http://www.kunena.org
  10.  **/
  11. defined ( '_JEXEC' ) or die ();
  12.  
  13. require_once KPATH_ADMIN . '/libraries/external/nbbc/nbbc.php';
  14. jimport('joomla.utilities.string');
  15.  
  16. // TODO: add possibility to hide contents from these tags:
  17. // [hide], [confidential], [spoiler], [attachment], [code]
  18.  
  19. /**
  20.  * Kunena BBCode Class
  21.  *
  22.  * @version     2.0
  23.  */
  24. class KunenaBbcode extends BBCode {
  25.     public $autolink_disable = 0;
  26.  
  27.     /**
  28.      * Object Constructor
  29.      *
  30.      * @return  void
  31.      */
  32.     function __construct($relative = true) {
  33.         parent::__construct ();
  34.  
  35.         $this->defaults = new KunenaBbcodeLibrary;
  36.         $this->tag_rules = $this->defaults->default_tag_rules;
  37.  
  38.         $view = JString::strtolower ( JRequest::getCmd ( 'type', JRequest::getCmd ( 'view', '' )) );
  39.  
  40.         $this->smileys = $this->defaults->default_smileys;
  41.         if (empty($this->smileys)) $this->SetEnableSmileys(false);
  42.         $this->SetSmileyDir ( JPATH_ROOT );
  43.         $this->SetSmileyURL ( $relative ? JURI::root(true) : rtrim(JURI::root(), '/') );
  44.         $this->SetDetectURLs ( true );
  45.         $this->SetURLPattern (array($this, 'parseUrl'));
  46.         $this->SetURLTarget('_blank');
  47.  
  48.         $dispatcher = JDispatcher::getInstance();
  49.         JPluginHelper::importPlugin('kunena');
  50.         $dispatcher->trigger( 'onKunenaBbcodeConstruct', array( $this ) );
  51.     }
  52.  
  53.     /**
  54.      * Get Singleton Instance
  55.      *
  56.      * @param
  57.      * @return  KunenaBbcode
  58.      * @since   1.7
  59.      */
  60.     public static function getInstance($relative = true) {
  61.         static $instance = false;
  62.         if (!isset($instance[intval($relative)])) {
  63.             $instance[intval($relative)] = new KunenaBbcode ($relative);
  64.         }
  65.         $instance[intval($relative)]->autolink_disable = 0;
  66.         return $instance[intval($relative)];
  67.     }
  68.  
  69.     public function parseUrl($params) {
  70.         $url = $params['url'];
  71.         $text = $params['text'];
  72.  
  73.         if (preg_match('#^mailto:#ui', $url)) {
  74.             // Cloak email addresses
  75.             $email = substr($text, 7);
  76.             return JHTML::_('email.cloak', $email, $this->IsValidEmail($email));
  77.         }
  78.  
  79.         // Remove http(s):// from the text
  80.         $text = preg_replace ( '#^http(s?)://#ui', '', $text );
  81.  
  82.         $config = KunenaFactory::getConfig ();
  83.         if ($config->trimlongurls) {
  84.             // shorten URL text if they are too long
  85.             $text = preg_replace ( '#^(.{' . $config->trimlongurlsfront . '})(.{4,})(.{' . $config->trimlongurlsback . '})$#u', '\1...\3', $text );
  86.         }
  87.  
  88.         if (!isset($params['query'])) $params['query'] = '';
  89.         if (!isset($params['path'])) $params['path'] = '';
  90.  
  91.         if ($config->autoembedyoutube && isset($params['host'])) {
  92.             // convert youtube links to embedded player
  93.             parse_str($params['query'], $query);
  94.             $path = explode('/', $params['path']);
  95.  
  96.             if (strstr($params['host'], '.youtube.') && !empty($path[1]) && $path[1]=='watch' && !empty($query['v'])) {
  97.                 $video = $query['v'];
  98.             } elseif ($params['host'] == 'youtu.be' && !empty($path[1])) {
  99.                 $video = $path[1];
  100.             }
  101.             if (isset($video)) {
  102.                 return '<object width="425" height="344"><param name="movie" value="http://www.youtube.com/v/'
  103.                     .urlencode($video).'?version=3&feature=player_embedded&fs=1&cc_load_policy=1"></param><param name="allowFullScreen" value="true"></param><embed src="http://www.youtube.com/v/'
  104.                     .urlencode($video).'?version=3&feature=player_embedded&fs=1&cc_load_policy=1" type="application/x-shockwave-flash" allowfullscreen="true" width="425" height="344"></embed></object>';
  105.             }
  106.         }
  107.         if ($config->autoembedebay && isset($params['host']) && strstr($params['host'], '.ebay.')) {
  108.             parse_str($params['query'], $query);
  109.             $path = explode('/', $params['path']);
  110.  
  111.             if (isset($path[3]) && $path[1] == 'itm' && is_numeric($path[3])) {
  112.                 // convert ebay item to embedded widget
  113.                 $itemid = intval($path[3]);
  114.                 return '<object width="355" height="300"><param name="movie" value="http://togo.ebay.com/togo/togo.swf" /><param name="flashvars" value="base=http://togo.ebay.com/togo/&lang='
  115.                     . $config->ebaylanguagecode . '&mode=normal&itemid='.$itemid.'&campid='.$config->ebay_affiliate_id.'" /><embed src="http://togo.ebay.com/togo/togo.swf" type="application/x-shockwave-flash" width="355" height="300" flashvars="base=http://togo.ebay.com/togo/&lang='
  116.                     . $config->ebaylanguagecode . '&mode=normal&itemid='.$itemid.'&campid='.$config->ebay_affiliate_id.'"></embed></object>';
  117.                 /*
  118.                 $text = preg_replace ( '#.*\.ebay\.([^/]+)/.*QQitemZ([0-9]+).+#u', '<object width="355" height="300"><param name="movie" value="http://togo.ebay.$1/togo/togo.swf" /><param name="flashvars" value="base=http://togo.ebay.$1/togo/&lang=' . $config->ebaylanguagecode . '&mode=normal&itemid=$2&campid=5336042350" /><embed src="http://togo.ebay.$1/togo/togo.swf" type="application/x-shockwave-flash" width="355" height="300" flashvars="base=http://togo.ebay.$1/togo/&lang=' . $config->ebaylanguagecode . '&mode=normal&itemid=$2&campid=5336042350"></embed></object>', $text );
  119.                 $text = preg_replace ( '#.*\.ebay\.([^/]+)/.*ViewItem.+Item=([0-9]+).*#u', '<object width="355" height="300"><param name="movie" value="http://togo.ebay.$1/togo/togo.swf" /><param name="flashvars" value="base=http://togo.ebay.$1/togo/&lang=' . $config->ebaylanguagecode . '&mode=normal&itemid=$2&campid=5336042350" /><embed src="http://togo.ebay.$1/togo/togo.swf" type="application/x-shockwave-flash" width="355" height="300" flashvars="base=http://togo.ebay.$1/togo/&lang=' . $config->ebaylanguagecode . '&mode=normal&itemid=$2&campid=5336042350"></embed></object>', $text );
  120.                 */
  121.             }
  122.             if (isset($path[1]) && $path[1] == 'sch') {
  123.                 // convert ebay search to embedded widget
  124.                 parse_str($params['query'], $query);
  125.  
  126.                 if (empty($query['_nkw'])) break;
  127.                 return '<object width="355" height="300"><param name="movie" value="http://togo.ebay.com/togo/togo.swf?2008013100" /><param name="flashvars" value="base=http://togo.ebay.com/togo/&lang=' . $config->ebaylanguagecode . '&mode=search&query='
  128.                     . urlencode($query['_nkw']) .'&campid=5336042350" /><embed src="http://togo.ebay.com/togo/togo.swf?2008013100" type="application/x-shockwave-flash" width="355" height="300" flashvars="base=http://togo.ebay.com/togo/&lang='
  129.                     . $config->ebaylanguagecode . '&mode=search&query=' . urlencode($query['_nkw']) . '&campid=5336042350"></embed></object>';
  130.                 /*
  131.                 $text = preg_replace ( '#.*\.ebay\.([^/]+)/.*satitle=([^&]+).*#u', '<object width="355" height="300"><param name="movie" value="http://togo.ebay.$1/togo/togo.swf?2008013100" /><param name="flashvars" value="base=http://togo.ebay.$1/togo/&lang=' . $config->ebaylanguagecode . '&mode=search&query=$2&campid=5336042350" /><embed src="http://togo.ebay.$1/togo/togo.swf?2008013100" type="application/x-shockwave-flash" width="355" height="300" flashvars="base=http://togo.ebay.$1/togo/&lang=' . $config->ebaylanguagecode . '&mode=search&query=$2&campid=5336042350"></embed></object>', $text );
  132.                 */
  133.             }
  134.             if (strstr($params['host'], 'myworld.') && !empty($path[1])) {
  135.                 // convert seller listing to embedded widget
  136.                 return '<object width="355" height="355"><param name="movie" value="http://togo.ebay.com/togo/seller.swf?2008013100" /><param name="flashvars" value="base=http://togo.ebay.com/togo/&lang='
  137.                     . $config->ebaylanguagecode . '&seller=' . urlencode($path[1]) . '&campid=5336042350" /><embed src="http://togo.ebay.com/togo/seller.swf?2008013100" type="application/x-shockwave-flash" width="355" height="355" flashvars="base=http://togo.ebay.com/togo/&lang='
  138.                     . $config->ebaylanguagecode . '&seller=' . urlencode($path[1]) . '&campid=5336042350"></embed></object>';
  139.                 /*
  140.                 $text = preg_replace ( '#.*\.ebay\.([^/]+)/.*QQsassZ([^&]+).*#u', '<object width="355" height="355"><param name="movie" value="http://togo.ebay.$1/togo/seller.swf?2008013100" /><param name="flashvars" value="base=http://togo.ebay.$1/togo/&lang=' . $config->ebaylanguagecode . '&seller=$2&campid=5336042350" /><embed src="http://togo.ebay.$1/togo/seller.swf?2008013100" type="application/x-shockwave-flash" width="355" height="355" flashvars="base=http://togo.ebay.$1/togo/&lang=' . $config->ebaylanguagecode . '&seller=$2&campid=5336042350"></embed></object>', $text );
  141.                 */
  142.             }
  143.         }
  144.  
  145.         return "<a class=\"bbcode_url\" href=\"{$url}\" target=\"_blank\" rel=\"nofollow\">{$text}</a>";
  146.     }
  147.  
  148.     function Internal_AutoDetectURLs($string) {
  149.         $search = preg_split('/(?xi)
  150.         \b
  151.         (
  152.             (?:
  153.                 (?:https?|ftp):\/\/
  154.                 |
  155.                 www\d{0,3}\.
  156.                 |
  157.                 [a-z0-9\.\-]+\.[a-z]{2,4}\/
  158.                 |
  159.                 mailto:
  160.                 |
  161.                 (?:[a-zA-Z0-9._-]{2,}@)
  162.             )
  163.             (?:
  164.                 [^\s()<>]+
  165.                 |
  166.                 \((?:[^\s()<>]+|(\(?:[^\s()<>]+\)))*\)
  167.             )+
  168.             (?:
  169.                 \((?:[^\s()<>]+|(\(?:[^\s()<>]+\)))*\)
  170.                 |
  171.                 [^\s`!()\[\]{};:\'"\.,<>?«»“”‘’]
  172.             )
  173.         )/u', $string, -1, PREG_SPLIT_DELIM_CAPTURE );
  174.  
  175.         $output = array();
  176.         foreach ($search as $index => $token) {
  177.             if ($index & 1) {
  178.                 if (preg_match("/^(https?|ftp|mailto):/ui", $token)) {
  179.                     // Protocol has been provided, so just use it as-is.
  180.                     $url = $token;
  181.                 } else {
  182.                     // Add scheme to emails and raw domain URLs.
  183.                     $url = (strpos($token, '@') ? 'mailto:' : 'http://') . $token;
  184.                 }
  185.                 // Never start URL from the middle of text (except for punctuation).
  186.                 $invalid = preg_match('#[^\s`!()\[\]{};\'"\.,<>?«»“”‘’]$#u', $search[$index-1]);
  187.                 $invalid |= !$this->IsValidURL($url, true);
  188.  
  189.                 // We have a full, complete, and properly-formatted URL, with protocol.
  190.                 // Now we need to apply the $this->url_pattern template to turn it into HTML.
  191.                 // TODO: report Joomla bug (silence it for now)
  192.                 $params = $this->parse_url($url);
  193.                 if (!$invalid && substr($url, 0, 7) == 'mailto:') {
  194.                     $email = JString::substr($url, 7);
  195.                     $output[$index] = JHTML::_('email.cloak', $email, $this->IsValidEmail($email));
  196.  
  197.                 } elseif ($invalid || empty($params['host']) || !empty($params['pass'])) {
  198.                     $output[$index-1] .= $token;
  199.                     $output[$index] = '';
  200.  
  201.                 } else {
  202.                     $params['url'] = $url;
  203.                     $params['link'] = $url;
  204.                     $params['text'] = $token;
  205.                     $output[$index] = $this->FillTemplate($this->url_pattern, $params);
  206.                 }
  207.             } else {
  208.                 $output[$index] = $token;
  209.             }
  210.         }
  211.         return $output;
  212.     }
  213.  
  214.     /**
  215.      * @see BBCode::IsValidURL()
  216.      * Regular expression taken from https://gist.github.com/729294
  217.      */
  218.     public function IsValidURL($string, $email_too = true, $local_too = false) {
  219.         static $re = '_^(?:(?:https?|ftp)://)(?:\S+(?::\S*)?@)?(?:(?!10(?:\.\d{1,3}){3})(?!127(?:\.\d{1,3}){3})(?!169\.254(?:\.\d{1,3}){2})(?!192\.168(?:\.\d{1,3}){2})(?!172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2})(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z\x{00a1}-\x{ffff}0-9]+-?)*[a-z\x{00a1}-\x{ffff}0-9]+)(?:\.(?:[a-z\x{00a1}-\x{ffff}0-9]+-?)*[a-z\x{00a1}-\x{ffff}0-9]+)*(?:\.(?:[a-z\x{00a1}-\x{ffff}]{2,})))(?::\d{2,5})?(?:/[^\s]*)?$_iuS';
  220.  
  221.         if (empty($string)) return false;
  222.         if ($local_too && $string[0] == '/') $string = 'http://www.domain.com' . $string;
  223.         if ($email_too && substr($string, 0, 7) == "mailto:") return $this->IsValidEmail(substr($string, 7));
  224.         if (preg_match($re, $string)) return true;
  225.         return false;
  226.     }
  227.  
  228.  
  229.     /**
  230.      * @see JString::parse_url()
  231.      * @todo remove when dropping J!1.5 support
  232.      * FYI: there's a bug in J!2.5.6 which has been fixed in GitHub
  233.      */
  234.     public static function parse_url($url)
  235.     {
  236.         $result = false;
  237.  
  238.         // Build arrays of values we need to decode before parsing
  239.         $entities = array('%21', '%2A', '%27', '%28', '%29', '%3B', '%3A', '%40', '%26', '%3D', '%24', '%2C', '%2F', '%3F', '%23', '%5B', '%5D');
  240.         $replacements = array('!', '*', "'", "(", ")", ";", ":", "@", "&", "=", "$", ",", "/", "?", "#", "[", "]");
  241.  
  242.         // Create encoded URL with special URL characters decoded so it can be parsed
  243.         // All other characters will be encoded
  244.         $encodedURL = str_replace($entities, $replacements, urlencode($url));
  245.  
  246.         // Parse the encoded URL
  247.         $encodedParts = parse_url($encodedURL);
  248.  
  249.         // Now, decode each value of the resulting array
  250.         if ($encodedParts)
  251.         {
  252.             foreach ($encodedParts as $key => $value)
  253.             {
  254.                 $result[$key] = urldecode(str_replace($replacements, $entities, $value));
  255.             }
  256.         }
  257.         return $result;
  258.     }
  259. }
  260.  
  261. class KunenaBbcodeLibrary extends BBCodeLibrary {
  262.     var $default_smileys = array();
  263.     var $default_tag_rules = array(
  264.             'b' => array(
  265.                 'simple_start' => "<strong>",
  266.                 'simple_end' => "</strong>",
  267.                 'class' => 'inline',
  268.                 'allow_in' => array('listitem', 'block', 'columns', 'inline', 'link'),
  269.                 'plain_start' => "<strong>",
  270.                 'plain_end' => "</strong>",
  271.             ),
  272.  
  273.             'i' => array(
  274.                 'simple_start' => "<i>",
  275.                 'simple_end' => "</i>",
  276.                 'class' => 'inline',
  277.                 'allow_in' => array('listitem', 'block', 'columns', 'inline', 'link'),
  278.                 'plain_start' => "<i>",
  279.                 'plain_end' => "</i>",
  280.             ),
  281.  
  282.             'u' => array(
  283.                 'simple_start' => "<u>",
  284.                 'simple_end' => "</u>",
  285.                 'class' => 'inline',
  286.                 'allow_in' => array('listitem', 'block', 'columns', 'inline', 'link'),
  287.                 'plain_start' => "<u>",
  288.                 'plain_end' => "</u>",
  289.             ),
  290.  
  291.             's' => array(
  292.                 'simple_start' => "<strike>",
  293.                 'simple_end' => "</strike>",
  294.                 'class' => 'inline',
  295.                 'allow_in' => array('listitem', 'block', 'columns', 'inline', 'link'),
  296.                 'plain_start' => "<i>",
  297.                 'plain_end' => "</i>",
  298.             ),
  299.  
  300.             'strike' => array(
  301.                 'simple_start' => "<strike>",
  302.                 'simple_end' => "</strike>",
  303.                 'class' => 'inline',
  304.                 'allow_in' => array('listitem', 'block', 'columns', 'inline', 'link'),
  305.                 'plain_start' => "<i>",
  306.                 'plain_end' => "</i>",
  307.             ),
  308.  
  309.             'tt' => array(
  310.                 'simple_start' => "<tt>",
  311.                 'simple_end' => "</tt>",
  312.                 'class' => 'inline',
  313.                 'allow_in' => array('listitem', 'block', 'columns', 'inline', 'link'),
  314.                 'plain_start' => "<i>",
  315.                 'plain_end' => "</i>",
  316.             ),
  317.  
  318.             'pre' => array(
  319.                 'simple_start' => "<pre>",
  320.                 'simple_end' => "</pre>",
  321.                 'class' => 'block',
  322.                 'allow_in' => array('listitem', 'block', 'columns'),
  323.                 'plain_start' => "<i>",
  324.                 'plain_end' => "</i>",
  325.             ),
  326.  
  327.             'font' => array(
  328.                 'mode' => BBCODE_MODE_LIBRARY,
  329.                 'allow' => array('_default' => '/^[a-zA-Z0-9._ -]+$/'),
  330.                 'method' => 'DoFont',
  331.                 'class' => 'inline',
  332.                 'allow_in' => array('listitem', 'block', 'columns', 'inline', 'link'),
  333.             ),
  334.  
  335.             'color' => array(
  336.                 'mode' => BBCODE_MODE_ENHANCED,
  337.                 'allow' => array('_default' => '/^#?[a-zA-Z0-9._ -]+$/'),
  338.                 'template' => '<span style="color:{$_default/tw}">{$_content/v}</span>',
  339.                 'class' => 'inline',
  340.                 'allow_in' => array('listitem', 'block', 'columns', 'inline', 'link'),
  341.             ),
  342.  
  343.             'size' => array(
  344.                 'mode' => BBCODE_MODE_LIBRARY,
  345.                 'method' => 'DoSize',
  346.                 'allow' => array('_default' => '/^[0-9.]+(px|em|pt|%)?$/D'),
  347.                 'class' => 'inline',
  348.                 'allow_in' => array('listitem', 'block', 'columns', 'inline', 'link'),
  349.             ),
  350.  
  351.             'sup' => array(
  352.                 'simple_start' => "<sup>",
  353.                 'simple_end' => "</sup>",
  354.                 'class' => 'inline',
  355.                 'allow_in' => array('listitem', 'block', 'columns', 'inline', 'link'),
  356.             ),
  357.  
  358.             'sub' => array(
  359.                 'simple_start' => "<sub>",
  360.                 'simple_end' => "</sub>",
  361.                 'class' => 'inline',
  362.                 'allow_in' => array('listitem', 'block', 'columns', 'inline', 'link')
  363.             ),
  364.  
  365.             'spoiler' => array(
  366.                 'mode' => BBCODE_MODE_LIBRARY,
  367.                 'method' => 'DoSpoiler',
  368.                 'class' => 'block',
  369.                 'allow_in' => array('listitem', 'block', 'columns'),
  370.                 'content' => BBCODE_REQUIRED,
  371.                 'plain_start' => "\nSpoiler:\n<i>",
  372.                 'plain_end' => "</i>",
  373.             ),
  374.  
  375.             'hide' => array(
  376.                 'mode' => BBCODE_MODE_LIBRARY,
  377.                 'method' => 'DoHide',
  378.                 'class' => 'block',
  379.                 'allow_in' => array('listitem', 'block', 'columns'),
  380.                 'content' => BBCODE_REQUIRED,
  381.                 'plain_content' => array(),
  382.             ),
  383.  
  384.             'confidential' => array(
  385.                 'mode' => BBCODE_MODE_LIBRARY,
  386.                 'method' => 'DoConfidential',
  387.                 'class' => 'block',
  388.                 'allow_in' => array('listitem', 'block', 'columns'),
  389.                 'content' => BBCODE_REQUIRED,
  390.                 'plain_content' => array(),
  391.             ),
  392.  
  393.             'map' => array(
  394.                 'mode' => BBCODE_MODE_LIBRARY,
  395.                 'method' => 'DoMap',
  396.                 'class' => 'block',
  397.                 'allow' => array( 'type' => '/^[\w\d.-_]*$/', 'zoom' => '/^\d*$/', 'control' => '/^\d*$/' ),
  398.                 'allow_in' => array('listitem', 'block', 'columns'),
  399.                 'content' => BBCODE_VERBATIM,
  400.             ),
  401.  
  402.             'ebay' => array(
  403.                 'mode' => BBCODE_MODE_LIBRARY,
  404.                 'method' => 'DoEbay',
  405.                 'class' => 'block',
  406.                 'allow_in' => array('listitem', 'block', 'columns'),
  407.                 'content' => BBCODE_VERBATIM,
  408.                 'plain_start' => "[ebay]",
  409.                 'plain_end' => "",
  410.                 'plain_content' => array(),
  411.             ),
  412.  
  413.             'article' => array(
  414.                 'mode' => BBCODE_MODE_LIBRARY,
  415.                 'method' => 'DoArticle',
  416.                 'class' => 'block',
  417.                 'allow_in' => array('listitem', 'block', 'columns'),
  418.                 'content' => BBCODE_REQUIRED,
  419.                 'plain_start' => "\n[article]\n",
  420.                 'plain_end' => "",
  421.                 'plain_content' => array(),
  422.             ),
  423.  
  424.             'tableau' => array(
  425.                 'mode' => BBCODE_MODE_LIBRARY,
  426.                 'method' => 'DoTableau',
  427.                 'class' => 'block',
  428.                 'allow_in' => array('listitem', 'block', 'columns'),
  429.                 'content' => BBCODE_VERBATIM,
  430.                 'plain_start' => "\n[tableau]\n",
  431.                 'plain_end' => "",
  432.                 'plain_content' => array(),
  433.             ),
  434.  
  435.             'video' => array(
  436.                 'mode' => BBCODE_MODE_LIBRARY,
  437.                 'method' => 'DoVideo',
  438.                 'allow' => array( 'type' => '/^[\w\d.-_]*$/', 'param' => '/^[\w]*$/', 'size' => '/^\d*$/', 'width' => '/^\d*$/', 'height' => '/^\d*$/' ),
  439.                 'class' => 'block',
  440.                 'allow_in' => array('listitem', 'block', 'columns'),
  441.                 'content' => BBCODE_VERBATIM,
  442.                 'plain_start' => "[video]",
  443.                 'plain_end' => "",
  444.                 'plain_content' => array(),
  445.             ),
  446.  
  447.             'img' => array(
  448.                 'mode' => BBCODE_MODE_LIBRARY,
  449.                 'method' => 'DoImage',
  450.                 'allow' => array( 'size' => '/^\d*$/' ),
  451.                 'class' => 'block',
  452.                 'allow_in' => array('listitem', 'block', 'columns', 'link'),
  453.                 'content' => BBCODE_VERBATIM,
  454.                 'plain_start' => "[image]",
  455.                 'plain_end' => "",
  456.                 'plain_content' => array(),
  457.             ),
  458.  
  459.             'file' => array(
  460.                 'mode' => BBCODE_MODE_LIBRARY,
  461.                 'method' => 'DoFile',
  462.                 'allow' => array( 'size' => '/^\d*$/' ),
  463.                 'class' => 'block',
  464.                 'allow_in' => array('listitem', 'block', 'columns'),
  465.                 'content' => BBCODE_VERBATIM,
  466.                 'plain_start' => "\n[file]\n",
  467.                 'plain_end' => "",
  468.                 'plain_content' => array(),
  469.             ),
  470.  
  471.             'attachment' => array(
  472.                 'mode' => BBCODE_MODE_LIBRARY,
  473.                 'method' => 'DoAttachment',
  474.                 'allow' => array( '_default' => '/^\d*$/' ),
  475.                 'class' => 'block',
  476.                 'allow_in' => array('listitem', 'block', 'columns'),
  477.                 'content' => BBCODE_VERBATIM,
  478.                 'plain_start' => "\n[attachment]\n",
  479.                 'plain_end' => "",
  480.                 'plain_content' => array(),
  481.             ),
  482.  
  483.             'highlight' => array(
  484.                 'simple_start' => "<span style='font-weight: 700;'>",
  485.                 'simple_end' => "</span>",
  486.                 'class' => 'inline',
  487.                 'allow_in' => array('listitem', 'block', 'columns', 'inline', 'link'),
  488.                 'plain_start' => "<i>",
  489.                 'plain_end' => "</i>",
  490.             ),
  491.  
  492.             'acronym' => array(
  493.                 'mode' => BBCODE_MODE_ENHANCED,
  494.                 'template' => '<span class="bbcode_acronym" title="{$_default/e}">{$_content/v}</span>',
  495.                 'class' => 'inline',
  496.                 'allow_in' => array('listitem', 'block', 'columns', 'inline', 'link'),
  497.             ),
  498.  
  499.             'url' => array(
  500.                 'mode' => BBCODE_MODE_LIBRARY,
  501.                 'method' => 'DoUrl',
  502.                 'class' => 'link',
  503.                 'allow_in' => array('listitem', 'block', 'columns', 'inline'),
  504.                 'content' => BBCODE_REQUIRED,
  505.                 'plain_start' => "<a href=\"{\$link}\" rel=\"nofollow\" target=\"_blank\">",
  506.                 'plain_end' => "</a>",
  507.                 'plain_content' => array('_content', '_default'),
  508.                 'plain_link' => array('_default', '_content'),
  509.             ),
  510.  
  511.             'email' => array(
  512.                 'mode' => BBCODE_MODE_LIBRARY,
  513.                 'method' => 'DoEmail',
  514.                 'class' => 'link',
  515.                 'allow_in' => array('listitem', 'block', 'columns', 'inline'),
  516.                 'content' => BBCODE_VERBATIM,
  517.                 'plain_start' => "<a href=\"mailto:{\$link}\">",
  518.                 'plain_end' => "</a>",
  519.                 'plain_content' => array('_content', '_default'),
  520.                 'plain_link' => array('_default', '_content'),
  521.             ),
  522.  
  523.             'wiki' => array(
  524.                 'mode' => BBCODE_MODE_LIBRARY,
  525.                 'method' => "DoWiki",
  526.                 'class' => 'link',
  527.                 'allow_in' => array('listitem', 'block', 'columns', 'inline'),
  528.                 'end_tag' => BBCODE_PROHIBIT,
  529.                 'content' => BBCODE_PROHIBIT,
  530.                 'plain_start' => "<b>[",
  531.                 'plain_end' => "]</b>",
  532.                 'plain_content' => array('title', '_default'),
  533.                 'plain_link' => array('_default', '_content'),
  534.             ),
  535.  
  536.             'rule' => array(
  537.                 'mode' => BBCODE_MODE_LIBRARY,
  538.                 'method' => "DoRule",
  539.                 'class' => 'block',
  540.                 'allow_in' => array('listitem', 'block', 'columns'),
  541.                 'end_tag' => BBCODE_PROHIBIT,
  542.                 'content' => BBCODE_PROHIBIT,
  543.                 'before_tag' => "sns",
  544.                 'after_tag' => "sns",
  545.                 'plain_start' => "\n-----\n",
  546.                 'plain_end' => "",
  547.                 'plain_content' => array(),
  548.             ),
  549.  
  550.             'br' => array(
  551.                 'mode' => BBCODE_MODE_SIMPLE,
  552.                 'simple_start' => "<br />\n",
  553.                 'simple_end' => "",
  554.                 'class' => 'inline',
  555.                 'allow_in' => array('listitem', 'block', 'columns', 'inline', 'link'),
  556.                 'end_tag' => BBCODE_PROHIBIT,
  557.                 'content' => BBCODE_PROHIBIT,
  558.                 'before_tag' => "s",
  559.                 'after_tag' => "s",
  560.                 'plain_start' => "\n",
  561.                 'plain_end' => "",
  562.                 'plain_content' => array(),
  563.             ),
  564.  
  565.             'hr' => array(
  566.                 'mode' => BBCODE_MODE_SIMPLE,
  567.                 'simple_start' => "<hr />\n",
  568.                 'simple_end' => "",
  569.                 'class' => 'inline',
  570.                 'allow_in' => array('listitem', 'block', 'columns', 'inline', 'link'),
  571.                 'end_tag' => BBCODE_PROHIBIT,
  572.                 'content' => BBCODE_PROHIBIT,
  573.                 'before_tag' => "s",
  574.                 'after_tag' => "s",
  575.                 'plain_start' => "\n-----\n",
  576.                 'plain_end' => "",
  577.                 'plain_content' => array(),
  578.             ),
  579.  
  580.             'left' => array(
  581.                 'simple_start' => "\n<div class=\"bbcode_left\" style=\"text-align:left\">\n",
  582.                 'simple_end' => "\n</div>\n",
  583.                 'allow_in' => array('listitem', 'block', 'columns'),
  584.                 'before_tag' => "sns",
  585.                 'after_tag' => "sns",
  586.                 'before_endtag' => "sns",
  587.                 'after_endtag' => "sns",
  588.                 'plain_start' => "\n",
  589.                 'plain_end' => "\n",
  590.             ),
  591.  
  592.             'right' => array(
  593.                 'simple_start' => "\n<div class=\"bbcode_right\" style=\"text-align:right\">\n",
  594.                 'simple_end' => "\n</div>\n",
  595.                 'allow_in' => array('listitem', 'block', 'columns'),
  596.                 'before_tag' => "sns",
  597.                 'after_tag' => "sns",
  598.                 'before_endtag' => "sns",
  599.                 'after_endtag' => "sns",
  600.                 'plain_start' => "\n",
  601.                 'plain_end' => "\n",
  602.             ),
  603.  
  604.             'center' => array(
  605.                 'simple_start' => "\n<div class=\"bbcode_center\" style=\"text-align:center\">\n",
  606.                 'simple_end' => "\n</div>\n",
  607.                 'allow_in' => array('listitem', 'block', 'columns'),
  608.                 'before_tag' => "sns",
  609.                 'after_tag' => "sns",
  610.                 'before_endtag' => "sns",
  611.                 'after_endtag' => "sns",
  612.                 'plain_start' => "\n",
  613.                 'plain_end' => "\n",
  614.             ),
  615.  
  616.             'indent' => array(
  617.                 'simple_start' => "\n<div class=\"bbcode_indent\" style=\"margin-left:4em\">\n",
  618.                 'simple_end' => "\n</div>\n",
  619.                 'allow_in' => array('listitem', 'block', 'columns'),
  620.                 'before_tag' => "sns",
  621.                 'after_tag' => "sns",
  622.                 'before_endtag' => "sns",
  623.                 'after_endtag' => "sns",
  624.                 'plain_start' => "\n",
  625.                 'plain_end' => "\n",
  626.             ),
  627.  
  628.             'table' => array(
  629.                 'simple_start' => "\n<table>",
  630.                 'simple_end' => "</table>\n",
  631.                 'class' => 'table',
  632.                 'allow_in' => array('listitem', 'block', 'columns'),
  633.                 'end_tag' => BBCODE_REQUIRED,
  634.                 'content' => BBCODE_REQUIRED,
  635.                 'before_tag' => "sns",
  636.                 'after_tag' => "sns",
  637.                 'before_endtag' => "sns",
  638.                 'after_endtag' => "sns",
  639.                 'plain_start' => "\n",
  640.                 'plain_end' => "\n",
  641.             ),
  642.  
  643.             'tr' => array(
  644.                 'simple_start' => "\n<tr>",
  645.                 'simple_end' => "</tr>\n",
  646.                 'class' => 'tr',
  647.                 'allow_in' => array('table'),
  648.                 'end_tag' => BBCODE_REQUIRED,
  649.                 'content' => BBCODE_REQUIRED,
  650.                 'before_tag' => "sns",
  651.                 'after_tag' => "sns",
  652.                 'before_endtag' => "sns",
  653.                 'after_endtag' => "sns",
  654.                 'plain_start' => "\n",
  655.                 'plain_end' => "\n",
  656.             ),
  657.  
  658.             'th' => array(
  659.                 'simple_start' => "<th>",
  660.                 'simple_end' => "</th>",
  661.                 'class' => 'columns',
  662.                 'allow_in' => array('tr'),
  663.                 'before_tag' => "sns",
  664.                 'after_tag' => "sns",
  665.                 'before_endtag' => "sns",
  666.                 'after_endtag' => "sns",
  667.                 'plain_start' => "\n",
  668.                 'plain_end' => "\n",
  669.             ),
  670.  
  671.             'td' => array(
  672.                 'simple_start' => "<td>",
  673.                 'simple_end' => "</td>",
  674.                 'class' => 'columns',
  675.                 'allow_in' => array('tr'),
  676.                 'before_tag' => "sns",
  677.                 'after_tag' => "sns",
  678.                 'before_endtag' => "sns",
  679.                 'after_endtag' => "sns",
  680.                 'plain_start' => "\n",
  681.                 'plain_end' => "\n",
  682.             ),
  683.  
  684.             'columns' => array(
  685.                 'simple_start' => "\n<table class=\"bbcode_columns\"><tbody><tr><td class=\"bbcode_column bbcode_firstcolumn\">\n",
  686.                 'simple_end' => "\n</td></tr></tbody></table>\n",
  687.                 'class' => 'columns',
  688.                 'allow_in' => array('listitem', 'block', 'columns'),
  689.                 'end_tag' => BBCODE_REQUIRED,
  690.                 'content' => BBCODE_REQUIRED,
  691.                 'before_tag' => "sns",
  692.                 'after_tag' => "sns",
  693.                 'before_endtag' => "sns",
  694.                 'after_endtag' => "sns",
  695.                 'plain_start' => "\n",
  696.                 'plain_end' => "\n",
  697.             ),
  698.  
  699.             'nextcol' => array(
  700.                 'simple_start' => "\n</td><td class=\"bbcode_column\">\n",
  701.                 'class' => 'nextcol',
  702.                 'allow_in' => array('columns'),
  703.                 'end_tag' => BBCODE_PROHIBIT,
  704.                 'content' => BBCODE_PROHIBIT,
  705.                 'before_tag' => "sns",
  706.                 'after_tag' => "sns",
  707.                 'before_endtag' => "sns",
  708.                 'after_endtag' => "sns",
  709.                 'plain_start' => "\n",
  710.                 'plain_end' => "",
  711.             ),
  712.  
  713.             'code' => array(
  714.                 'mode' => BBCODE_MODE_LIBRARY,
  715.                 'method' => 'DoCode',
  716.                 'allow' => array( 'type' => '/^[\w]*$/', ),
  717.                 'class' => 'code',
  718.                 'allow_in' => array('listitem', 'block', 'columns'),
  719.                 'content' => BBCODE_VERBATIM,
  720.                 'before_tag' => "sns",
  721.                 'after_tag' => "sn",
  722.                 'before_endtag' => "sn",
  723.                 'after_endtag' => "sns",
  724.                 'plain_start' => "\n",
  725.                 'plain_end' => "\n",
  726.             ),
  727.  
  728.             'quote' => array(
  729.                 'mode' => BBCODE_MODE_LIBRARY,
  730.                 'method' => 'DoQuote',
  731.                 'allow_in' => array('listitem', 'block', 'columns'),
  732.                 'before_tag' => "sns",
  733.                 'after_tag' => "sns",
  734.                 'before_endtag' => "sns",
  735.                 'after_endtag' => "sns",
  736.                 'plain_start' => "\nQuote:\n",
  737.                 'plain_end' => "\n",
  738.             ),
  739.  
  740.             'list' => array(
  741.                 'mode' => BBCODE_MODE_LIBRARY,
  742.                 'method' => 'DoList',
  743.                 'class' => 'list',
  744.                 'allow_in' => array('listitem', 'block', 'columns'),
  745.                 'before_tag' => "sns",
  746.                 'after_tag' => "sns",
  747.                 'before_endtag' => "sns",
  748.                 'after_endtag' => "sns",
  749.                 'plain_start' => "\n",
  750.                 'plain_end' => "\n",
  751.             ),
  752.  
  753.             'ul' => array(
  754.                 'mode' => BBCODE_MODE_LIBRARY,
  755.                 'method' => 'DoList',
  756.                 'default' => array( '_default' => 'circle' ),
  757.                 'class' => 'list',
  758.                 'allow_in' => array('listitem', 'block', 'columns'),
  759.                 'before_tag' => "sns",
  760.                 'after_tag' => "sns",
  761.                 'before_endtag' => "sns",
  762.                 'after_endtag' => "sns",
  763.                 'plain_start' => "\n",
  764.                 'plain_end' => "\n",
  765.             ),
  766.  
  767.             'ol' => array(
  768.                 'mode' => BBCODE_MODE_LIBRARY,
  769.                 'method' => 'DoList',
  770.                 'allow' => array( '_default' => '/^[\d\w]*$/', ),
  771.                 'default' => array( '_default' => '1' ),
  772.                 'class' => 'list',
  773.                 'allow_in' => array('listitem', 'block', 'columns'),
  774.                 'before_tag' => "sns",
  775.                 'after_tag' => "sns",
  776.                 'before_endtag' => "sns",
  777.                 'after_endtag' => "sns",
  778.                 'plain_start' => "\n",
  779.                 'plain_end' => "\n",
  780.             ),
  781.  
  782.             '*' => array(
  783.                 'simple_start' => "<li>",
  784.                 'simple_end' => "</li>\n",
  785.                 'class' => 'listitem',
  786.                 'allow_in' => array('list'),
  787.                 'end_tag' => BBCODE_OPTIONAL,
  788.                 'before_tag' => "s",
  789.                 'after_tag' => "s",
  790.                 'before_endtag' => "sns",
  791.                 'after_endtag' => "sns",
  792.                 'plain_start' => "\n * ",
  793.                 'plain_end' => "\n",
  794.             ),
  795.  
  796.             'li' => array(
  797.                 'simple_start' => "<li>",
  798.                 'simple_end' => "</li>\n",
  799.                 'class' => 'listitem',
  800.                 'allow_in' => array('listitem', 'block', 'columns', 'list'),
  801.                 'before_tag' => "s",
  802.                 'after_tag' => "s",
  803.                 'before_endtag' => "sns",
  804.                 'after_endtag' => "sns",
  805.                 'plain_start' => "\n * ",
  806.                 'plain_end' => "\n",
  807.             ),
  808.  
  809.             'terminal' => array(
  810.                 'mode' => BBCODE_MODE_LIBRARY,
  811.                 'method' => 'DoTerminal',
  812.                 'allow_in' => array('listitem', 'block', 'columns'),
  813.                 'class' => 'block',
  814.                 'allow' => array( 'colortext' => '/^[\w\d.-_]*$/' ),
  815.                 'content' => BBCODE_PROHIBIT,
  816.                 'plain_start' => "\nTerminal:\n",
  817.                 'plain_end' => "\n",
  818.             ),
  819.             'nathtml' => array(
  820.                 'method' => 'DoHtml',
  821.                 'content' => BBCODE_PROHIBIT,
  822.                 'plain_start' => "",
  823.                 'plain_end' => "",
  824.             ),
  825.     );
  826.  
  827.     function __construct() {
  828.         if (!KunenaFactory::getConfig()->disemoticons) {
  829.             $db = JFactory::getDBO ();
  830.             $query = "SELECT code, location FROM #__kunena_smileys";
  831.             $db->setQuery ( $query );
  832.             $smileys = $db->loadObjectList ();
  833.  
  834.             $template = KunenaFactory::getTemplate();
  835.             foreach ( $smileys as $smiley ) {
  836.                 $this->default_smileys [$smiley->code] = $template->getSmileyPath($smiley->location);
  837.             }
  838.         }
  839.     }
  840.  
  841.     function DoEmail($bbcode, $action, $name, $default, $params, $content) {
  842.         if ($action == BBCODE_CHECK) {
  843.             return true;
  844.         }
  845.         $email = is_string ( $default ) ? $default : $content;
  846.         $text = is_string ( $default ) ? $content : $default;
  847.         return JHTML::_('email.cloak', htmlspecialchars ( $email ), $bbcode->IsValidEmail ( $email ), $text, $bbcode->IsValidEmail ( $text ));
  848.     }
  849.  
  850.     // Format a [url] tag by producing an <a>...</a> element.
  851.     // The URL only allows http, https, mailto, and ftp protocols for safety.
  852.     function DoURL($bbcode, $action, $name, $default, $params, $content) {
  853.         // We can't check this with BBCODE_CHECK because we may have no URL before the content
  854.         // has been processed.
  855.         if ($action == BBCODE_CHECK) {
  856.             $bbcode->autolink_disable++;
  857.             return true;
  858.         }
  859.  
  860.         $bbcode->autolink_disable--;
  861.         $url = is_string ( $default ) ? $default : $bbcode->UnHTMLEncode ( strip_tags ( $content ) );
  862.         $url = preg_replace('# #u', '%20', $url);
  863.         if (!preg_match('#^(/|https?:|ftp:)#ui', $url)) {
  864.             // Add scheme to raw domain URLs.
  865.             $url = "http://{$url}";
  866.         }
  867.  
  868.         if ($bbcode->IsValidURL ( $url, false, true )) {
  869.             if ($bbcode->debug)
  870.                 echo "ISVALIDURL<br />";
  871.             if ($bbcode->url_targetable !== false && isset ( $params ['target'] ))
  872.                 $target = " target=\"" . htmlspecialchars ( $params ['target'] ) . "\"";
  873.             elseif ($bbcode->url_target !== false)
  874.                 $target = " target=\"" . htmlspecialchars ( $bbcode->url_target ) . "\"";
  875.             return '<a href="' . htmlspecialchars ( $url ) . '" class="bbcode_url" rel="nofollow"' . $target . '>' . $content . '</a>';
  876.         }
  877.         return htmlspecialchars ( $params ['_tag'] ) . $content . htmlspecialchars ( $params ['_endtag'] );
  878.     }
  879.  
  880.     // Format a [size] tag by producing a <span> with a style with a different font-size.
  881.     function DoSize($bbcode, $action, $name, $default, $params, $content) {
  882.         if ($action == BBCODE_CHECK)
  883.             return true;
  884.  
  885.         $size_css = array (1 => 'kmsgtext-xs', 'kmsgtext-s', 'kmsgtext-m', 'kmsgtext-l', 'kmsgtext-xl', 'kmsgtext-xxl' );
  886.         if (isset ( $size_css [$default] )) {
  887.             $size = "class=\"{$size_css [$default]}\"";
  888.         } elseif (!empty($default)) {
  889.             $size = "style=\"font-size:{$default}\"";
  890.         } else {
  891.             $size = "class=\"{$size_css [3]}\"";
  892.         }
  893.         return "<span {$size}>{$content}</span>";
  894.     }
  895.  
  896.     // Format a [list] tag, which is complicated by the number of different
  897.     // ways a list can be started.  The following parameters are allowed:
  898.     //
  899.     //   [list]           Unordered list, using default marker
  900.     //   [list=circle]    Unordered list, using circle marker
  901.     //   [list=disc]      Unordered list, using disc marker
  902.     //   [list=square]    Unordered list, using square marker
  903.     //
  904.     //   [list=1]         Ordered list, numeric, starting at 1
  905.     //   [list=A]         Ordered list, capital letters, starting at A
  906.     //   [list=a]         Ordered list, lowercase letters, starting at a
  907.     //   [list=I]         Ordered list, capital Roman numerals, starting at I
  908.     //   [list=i]         Ordered list, lowercase Roman numerals, starting at i
  909.     //   [list=greek]     Ordered list, lowercase Greek letters, starting at alpha
  910.     //   [list=01]        Ordered list, two-digit numeric with 0-padding, starting at 01
  911.     function DoList($bbcode, $action, $name, $default, $params, $content) {
  912.         // Allowed list styles, striaght from the CSS 2.1 spec.  The only prohibited
  913.         // list style is that with image-based markers, which often slows down web sites.
  914.         $list_styles = Array ('1' => 'decimal', '01' => 'decimal-leading-zero', 'i' => 'lower-roman', 'I' => 'upper-roman', 'a' => 'lower-alpha', 'A' => 'upper-alpha' );
  915.         $ci_list_styles = Array ('circle' => 'circle', 'disc' => 'disc', 'square' => 'square', 'greek' => 'lower-greek', 'armenian' => 'armenian', 'georgian' => 'georgian' );
  916.         $ul_types = Array ('circle' => 'circle', 'disc' => 'disc', 'square' => 'square' );
  917.         $default = trim ( $default );
  918.         if (! $default)
  919.             $default = $bbcode->tag_rules [$name] ['default'] ['_default'];
  920.  
  921.         if ($action == BBCODE_CHECK) {
  922.             if (! is_string ( $default ) || strlen ( $default ) == "")
  923.                 return true;
  924.             else if (isset ( $list_styles [$default] ))
  925.                 return true;
  926.             else if (isset ( $ci_list_styles [strtolower ( $default )] ))
  927.                 return true;
  928.             else
  929.                 return false;
  930.         }
  931.  
  932.         // Choose a list element (<ul> or <ol>) and a style.
  933.         if (! is_string ( $default ) || strlen ( $default ) == "") {
  934.             $elem = 'ul';
  935.             $type = '';
  936.         } else if ($default == '1') {
  937.             $elem = 'ol';
  938.             $type = '';
  939.         } else if (isset ( $list_styles [$default] )) {
  940.             $elem = 'ol';
  941.             $type = $list_styles [$default];
  942.         } else {
  943.             $default = strtolower ( $default );
  944.             if (isset ( $ul_types [$default] )) {
  945.                 $elem = 'ul';
  946.                 $type = $ul_types [$default];
  947.             } else if (isset ( $ci_list_styles [$default] )) {
  948.                 $elem = 'ol';
  949.                 $type = $ci_list_styles [$default];
  950.             }
  951.         }
  952.  
  953.         // Generate the HTML for it.
  954.         if (strlen ( $type ))
  955.             return "\n<$elem class=\"bbcode_list\" style=\"list-style-type:$type\">\n$content</$elem>\n";
  956.         else
  957.             return "\n<$elem class=\"bbcode_list\">\n$content</$elem>\n";
  958.     }
  959.  
  960.     function DoSpoiler($bbcode, $action, $name, $default, $params, $content) {
  961.         if ($action == BBCODE_CHECK)
  962.             return true;
  963.  
  964.         if (!empty($bbcode->lost_start_tags[$name]) && !$bbcode->was_limited) {
  965.             return "[{$name}]{$content}";
  966.         }
  967.         $document = JFactory::getDocument();
  968.         if (!($document instanceof JDocumentHTML)) {
  969.             // Static version
  970.             return '<div class="kspoiler"><div class="kspoiler-header"><span class="kspoiler-title">' . ($default ? ($default) : (JText::_ ( 'COM_KUNENA_BBCODE_SPOILER' )))
  971.                 . '</span> <span class="kspoiler-hide">' . JText::_ ( 'COM_KUNENA_LIB_BBCODE_SPOILER_HIDE' )
  972.                 . '</span></div><div class="kspoiler-wrapper"><div class="kspoiler-content">' . $content . '</div></div></div>';
  973.         }
  974.  
  975.         return '<div class="kspoiler"><div class="kspoiler-header"><span class="kspoiler-title">' . ($default ? ($default) : (JText::_ ( 'COM_KUNENA_BBCODE_SPOILER' )))
  976.             . '</span> <span class="kspoiler-expand">' . JText::_ ( 'COM_KUNENA_LIB_BBCODE_SPOILER_EXPAND' ) . '</span><span class="kspoiler-hide" style="display:none">'
  977.             . JText::_ ( 'COM_KUNENA_LIB_BBCODE_SPOILER_HIDE' ) . '</span></div><div class="kspoiler-wrapper"><div class="kspoiler-content" style="display:none">' . $content . '</div></div></div>';
  978.     }
  979.  
  980.     function DoHide($bbcode, $action, $name, $default, $params, $content) {
  981.         if ($action == BBCODE_CHECK)
  982.             return true;
  983.  
  984.         if (!empty($bbcode->lost_start_tags[$name]) && !$bbcode->was_limited) {
  985.             return "[{$name}]{$content}";
  986.         }
  987.         if (JFactory::getUser ()->id == 0) {
  988.             // Hide between content from non registered users
  989.             return JText::_ ( 'COM_KUNENA_BBCODE_HIDDENTEXT' );
  990.         } else {
  991.             // Display but highlight the fact that it is hidden from guests
  992.             return '<b>' . JText::_ ( 'COM_KUNENA_BBCODE_HIDE_IN_MESSAGE' ) . '</b>' . '<div class="kmsgtext-hide">' . $content . '</div>';
  993.         }
  994.     }
  995.  
  996.     function DoConfidential($bbcode, $action, $name, $default, $params, $content) {
  997.         if ($action == BBCODE_CHECK)
  998.             return true;
  999.  
  1000.         if (!empty($bbcode->lost_start_tags[$name]) && !$bbcode->was_limited) {
  1001.             return "[{$name}]{$content}";
  1002.         }
  1003.         $me = KunenaUserHelper::getMyself();
  1004.         if (($me->userid && $bbcode->parent->message->userid == $me->userid) || $me->isModerator(isset($bbcode->parent->message) ? $bbcode->parent->message->getCategory() : null)) {
  1005.             // Display but highlight the fact that it is hidden from everyone except admins and mods
  1006.             return '<b>' . JText::_ ( 'COM_KUNENA_BBCODE_CONFIDENTIAL_TEXT' ) . '</b><div class="kmsgtext-confidential">' . $content . '</div>';
  1007.         }
  1008.     }
  1009.  
  1010.     function DoMap($bbcode, $action, $name, $default, $params, $content) {
  1011.         static $id = false;
  1012.         static $sensor = true;
  1013.  
  1014.         if ($action == BBCODE_CHECK)
  1015.             return true;
  1016.  
  1017.         $content = htmlspecialchars($content);
  1018.         $document = JFactory::getDocument();
  1019.         if (!($document instanceof JDocumentHTML)) {
  1020.             return '[MAP]';
  1021.         }
  1022.  
  1023.         if ($id === false) {
  1024.             $document->addScript('http://maps.google.com/maps/api/js?sensor='.($sensor == true ? 'true' : 'false'));
  1025.             $id = 0;
  1026.         }
  1027.  
  1028.         $id ++;
  1029.         $mapid = 'kgooglemap'.$id;
  1030.  
  1031.         $map_type = isset($params ["type"]) ? strtoupper($params ["type"]): 'ROADMAP';
  1032.         $map_typeId = array('HYBRID','ROADMAP','SATELLITE','TERRAIN');
  1033.         if ( !in_array($map_type, $map_typeId) ) $map_type = 'ROADMAP';
  1034.         $map_zoom = isset($params ["zoom"]) ? $params ["zoom"]: '10';
  1035.         $map_control = $params ["control"] ? $params ["control"] : 0;
  1036.  
  1037.         $document->addScriptDeclaration("
  1038.         // <![CDATA[
  1039.             var geocoder;
  1040.             var $mapid;
  1041.  
  1042.             window.addEvent('domready', function() {
  1043.                 geocoder = new google.maps.Geocoder();
  1044.             var latlng = new google.maps.LatLng(37.333586,-121.894684);
  1045.             var myOptions = {
  1046.                 zoom: $map_zoom,
  1047.                 disableDefaultUI: $map_control,
  1048.                 center: latlng,
  1049.                 mapTypeId: google.maps.MapTypeId.$map_type
  1050.             };
  1051.             $mapid = new google.maps.Map(document.id('".$mapid."'), myOptions);
  1052.  
  1053.             var address = '$content';
  1054.             if (geocoder) {
  1055.                 geocoder.geocode( { 'address': address}, function(results, status) {
  1056.                 if (status == google.maps.GeocoderStatus.OK) {
  1057.                     $mapid.setCenter(results[0].geometry.location);
  1058.                     var marker = new google.maps.Marker({
  1059.                         position: results[0].geometry.location,
  1060.                         map: $mapid
  1061.                     });
  1062.                 } else {
  1063.                     var contentString = '<p><strong>".KunenaHtmlParser::JSText('COM_KUNENA_GOOGLE_MAP_NO_GEOCODE')." <i>$content</i></strong></p>';
  1064.                     var infowindow$mapid = new google.maps.InfoWindow({ content: contentString });
  1065.                         infowindow$mapid.open($mapid);
  1066.                 }
  1067.                 });
  1068.             }
  1069.             });
  1070.  
  1071.         // ]]>"
  1072.         );
  1073.  
  1074.         return '<div id="'.$mapid.'" class="kgooglemap">'.KunenaHtmlParser::JSText('COM_KUNENA_GOOGLE_MAP_NOT_VISIBLE').'</div>';
  1075.     }
  1076.  
  1077.     function DoEbay($bbcode, $action, $name, $default, $params, $content) {
  1078.         if ($action == BBCODE_CHECK)
  1079.             return true;
  1080.  
  1081.         $config = KunenaFactory::getConfig();
  1082.         $ebay_maxwidth = (int) (($config->rtewidth * 9) / 10); // Max 90% of text width
  1083.         $ebay_maxheight = (int) ($config->rteheight); // max. display size
  1084.  
  1085.         $content = htmlspecialchars($content);
  1086.         if (is_numeric ( $content )) {
  1087.             // Numeric: we have to assume this is an item id
  1088.             return '<object width="'.$ebay_maxwidth.'" height="'.$ebay_maxheight.'"><param name="movie" value="http://togo.ebay.com/togo/togo.swf" /><param name="flashvars" value="base=http://togo.ebay.com/togo/&lang=' . $config->ebaylanguagecode . '&mode=normal&itemid=' . $content . '&campid=5336042350" /><embed src="http://togo.ebay.com/togo/togo.swf" type="application/x-shockwave-flash" width="355" height="300" flashvars="base=http://togo.ebay.com/togo/&lang=' . $config->ebaylanguagecode . '&mode=normal&itemid=' . $content . '&campid='.$config->ebay_affiliate_id.'"></embed></object>';
  1089.         } else {
  1090.             // Non numeric: we have to assume this is a search
  1091.             return '<object width="'.$ebay_maxwidth.'" height="'.$ebay_maxheight.'"><param name="movie" value="http://togo.ebay.com/togo/togo.swf?2008013100" /><param name="flashvars" value="base=http://togo.ebay.com/togo/&lang=' . $config->ebaylanguagecode . '&mode=search&query=' . $content . '&campid=5336042350" /><embed src="http://togo.ebay.com/togo/togo.swf?2008013100" type="application/x-shockwave-flash" width="355" height="300" flashvars="base=http://togo.ebay.com/togo/&lang=' . $config->ebaylanguagecode . '&mode=search&query=' . $content . '&campid='.$config->ebay_affiliate_id.'"></embed></object>';
  1092.         }
  1093.     }
  1094.  
  1095.     function DoArticle($bbcode, $action, $name, $default, $params, $content) {
  1096.         if ($action == BBCODE_CHECK)
  1097.             return true;
  1098.  
  1099.         $articleid = intval($content);
  1100.  
  1101.         $config = KunenaFactory::getConfig();
  1102.         $user = JFactory::getUser ();
  1103.         $db = JFactory::getDBO ();
  1104.         $site = JFactory::getApplication('site');
  1105.         if (version_compare(JVERSION, '1.6','>')) {
  1106.             // Joomla 1.6+
  1107.             $query = 'SELECT a.*, u.name AS author, u.usertype, cc.title AS category,
  1108.                 0 AS sec_pub, 0 AS sectionid, cc.published AS cat_pub, cc.access AS cat_access
  1109.                 FROM #__content AS a
  1110.                 LEFT JOIN #__categories AS cc ON cc.id = a.catid
  1111.                 LEFT JOIN #__users AS u ON u.id = a.created_by
  1112.                 WHERE a.id='.$db->quote($articleid);
  1113.             $db->setQuery($query);
  1114.             $article = $db->loadObject();
  1115.             if ($article) {
  1116.                 // Get credentials to check if the user has right to see the article
  1117.                 $params = $site->getParams('com_content');
  1118.                 $registry = new JRegistry();
  1119.                 $registry->loadJSON($article->attribs);
  1120.                 $article->params = clone $params;
  1121.                 $article->params->merge($registry);
  1122.                 $params = $article->params;
  1123.  
  1124.                 $viewlevels = $user->getAuthorisedViewLevels();
  1125.                 if ( !in_array($article->access, $viewlevels) ) {
  1126.                     $denied = true;
  1127.                 }
  1128.             }
  1129.         } else {
  1130.             // Joomla 1.5
  1131.             $query = 'SELECT a.*, u.name AS author, u.usertype, cc.title AS category, s.title AS section,
  1132.                 s.published AS sec_pub, cc.published AS cat_pub, s.access AS sec_access, cc.access AS cat_access
  1133.                 FROM #__content AS a
  1134.                 LEFT JOIN #__categories AS cc ON cc.id = a.catid
  1135.                 LEFT JOIN #__sections AS s ON s.id = cc.section AND s.scope = "content"
  1136.                 LEFT JOIN #__users AS u ON u.id = a.created_by
  1137.                 WHERE a.id=' . $db->quote ( $articleid );
  1138.  
  1139.             $db->setQuery ( $query );
  1140.             $article = $db->loadObject ();
  1141.             if ($article) {
  1142.                 // Get credentials to check if the user has right to see the article
  1143.                 $params = clone($site->getParams('com_content'));
  1144.                 $aparams = new JParameter($article->attribs);
  1145.                 $params->merge($aparams);
  1146.  
  1147.                 if (($article->catid && $article->cat_access > $user->get('aid', 0))
  1148.                     || ($article->sectionid && $article->sec_access > $user->get('aid', 0))
  1149.                     || ($article->access > $user->get('aid', 0))) {
  1150.                     $denied = true;
  1151.                 }
  1152.             }
  1153.         }
  1154.  
  1155.         $html = $link = '';
  1156.         if (!$article || (!$article->cat_pub && $article->catid) || (!$article->sec_pub && $article->sectionid)) {
  1157.             $html = JText::_ ( 'COM_KUNENA_LIB_BBCODE_ARTICLE_ERROR_UNPUBLISHED' );
  1158.         } elseif (!empty($denied)) {
  1159.             $html = JText::_( 'COM_KUNENA_LIB_BBCODE_ARTICLE_ERROR_NO_PERMISSIONS' );
  1160.         } else {
  1161.             require_once (JPATH_ROOT.'/components/com_content/helpers/route.php');
  1162.             if (version_compare(JVERSION, '1.6','>')) {
  1163.                 // Joomla 1.6+
  1164.                 $article->slug = !empty($article->alias) ? ($article->id.':'.$article->alias) : $article->id;
  1165.                 $article->catslug = !empty($article->category_alias) ? ($article->catid.':'.$article->category_alias) : $article->catid;
  1166.                 $url = JRoute::_(ContentHelperRoute::getArticleRoute($article->slug, $article->catslug));
  1167.             } else {
  1168.                 // Joomla 1.5
  1169.                 $url = JRoute::_(ContentHelperRoute::getArticleRoute($article->id, $article->catid, $article->sectionid));
  1170.             }
  1171.  
  1172.             if (!$default) $default = $config->article_display;
  1173.             switch ($default) {
  1174.                 case 'full':
  1175.                     if ( !empty($article->fulltext) ) {
  1176.                         $article->text = $article->introtext. ' '. $article->fulltext;
  1177.                         $link = '<a href="'.$url.'" class="readon">'.JText::sprintf('COM_KUNENA_LIB_BBCODE_ARTICLE_READ').'</a>';
  1178.                         break;
  1179.                     }
  1180.                     // continue to intro if fulltext is empty
  1181.                 case 'intro':
  1182.                     if ( !empty($article->introtext) ) {
  1183.                         $article->text = $article->introtext;
  1184.                         $link = '<a href="'.$url.'" class="readon">'.JText::sprintf('COM_KUNENA_LIB_BBCODE_ARTICLE_MORE').'</a>';
  1185.                         break;
  1186.                     }
  1187.                     // continue to link if introtext is empty
  1188.                 case 'link':
  1189.                 default:
  1190.                     $link = '<a href="'.$url.'" class="readon">'.$article->title.'</a>';
  1191.                     break;
  1192.             }
  1193.             if (!empty($article->text)) {
  1194.                 // Identify the source of the event to be Kunena itself
  1195.                 // this is important to avoid recursive event behaviour with our own plugins
  1196.                 $params->set('ksource', 'kunena');
  1197.                 JPluginHelper::importPlugin('content');
  1198.                 $dispatcher = JDispatcher::getInstance();
  1199.                 if (version_compare(JVERSION, '1.6','>')) {
  1200.                     // Joomla 1.6+
  1201.                     $results = $dispatcher->trigger('onContentPrepare', array ('text', &$article, &$params, 0));
  1202.                 } else {
  1203.                     // Joomla 1.5
  1204.                     $results = $dispatcher->trigger('onPrepareContent', array (&$article, &$params, 0));
  1205.                 }
  1206.                 $html = $article->text;
  1207.             }
  1208.         }
  1209.         return '<div class="kmsgtext-article">' . $html . '</div>' . $link;
  1210.     }
  1211.  
  1212.     function DoQuote($bbcode, $action, $name, $default, $params, $content) {
  1213.         if ($action == BBCODE_CHECK)
  1214.             return true;
  1215.  
  1216.         $post = isset($params["post"]) ? $params["post"] : false;
  1217.         $user = isset($default) ? $default : false;
  1218.         $html = '';
  1219.         if ($user) $html .= "<b>" . $user . " " . JText::_ ( 'COM_KUNENA_POST_WROTE' ) . ":</b>\n";
  1220.         $html .= '<div class="kmsgtext-quote">' . $content . '</div>';
  1221.         return $html;
  1222.     }
  1223.  
  1224.     function DoCode($bbcode, $action, $name, $default, $params, $content) {
  1225.         static $enabled = false;
  1226.  
  1227.         if ($action == BBCODE_CHECK) {
  1228.             return true;
  1229.         }
  1230.  
  1231.         $type = isset ( $params ["type"] ) ? $params ["type"] : "php";
  1232.         if ($type == 'js') {
  1233.             $type = 'javascript';
  1234.         } elseif ($type == 'html') {
  1235.             $type = 'html4strict';
  1236.         }
  1237.         if ($enabled === false && KunenaFactory::getConfig ()->highlightcode) {
  1238.             $enabled = true;
  1239.             if (version_compare(JVERSION, '1.6','>')) {
  1240.                 // Joomla 1.6+
  1241.                 $path = JPATH_ROOT.'/plugins/content/geshi/geshi/geshi.php';
  1242.                 if (file_exists($path)) {
  1243.                     require_once $path;
  1244.                 }
  1245.             } else {
  1246.                 // Joomla 1.5
  1247.                 jimport ( 'geshi.geshi' );
  1248.             }
  1249.         }
  1250.         if ($enabled && class_exists('GeSHi')) {
  1251.             $geshi = new GeSHi ( $bbcode->UnHTMLEncode($content), $type );
  1252.             $geshi->enable_keyword_links ( false );
  1253.             $code = $geshi->parse_code ();
  1254.         } else {
  1255.             $type = preg_replace('/[^A-Z0-9_\.-]/i', '', $type);
  1256.             $code = '<pre xml:'.$type.'>'.$content.'</pre>';
  1257.         }
  1258.         return '<div class="highlight">'.$code.'</div>';
  1259.     }
  1260.  
  1261.     function doTableau($bbcode, $action, $name, $default, $params, $content) {
  1262.         if ($action == BBCODE_CHECK) {
  1263.             $bbcode->autolink_disable++;
  1264.             return true;
  1265.         }
  1266.  
  1267.         $bbcode->autolink_disable--;
  1268.         if (!$content)
  1269.             return;
  1270.  
  1271.         $config = KunenaFactory::getConfig();
  1272.  
  1273.         $viz_maxwidth = (int) (($config->rtewidth * 9) / 10); // Max 90% of text width
  1274.         $viz_maxheight = (isset ( $params ["height"] ) && is_numeric($params ["height"])) ? (int) $params ["height"] : (int) $config->rteheight;
  1275.  
  1276.         if(preg_match ('/(https?:\/\/.*?)\/(?:.*\/)*(.*\/.*)\?.*:toolbar=(yes|no)/', $content, $matches)){
  1277.             $tableauserver = $matches[1];
  1278.             $vizualization = $matches[2];
  1279.             $toolbar = $matches[3];
  1280.  
  1281.             return '<script type="text/javascript" src="'.$tableauserver.
  1282.                     '/javascripts/api/viz_v1.js"></script><object class="tableauViz" width="'.$viz_maxwidth.
  1283.                     '" height="'.$viz_maxheight.'" style="display:none;"><param name="name" value="'.$vizualization.
  1284.                     '" /><param name="toolbar" value="'.$toolbar.'" /></object>';
  1285.         }
  1286.     }
  1287.  
  1288.     function DoVideo($bbcode, $action, $name, $default, $params, $content) {
  1289.         if ($action == BBCODE_CHECK) {
  1290.             $bbcode->autolink_disable++;
  1291.             return true;
  1292.         }
  1293.  
  1294.         $bbcode->autolink_disable--;
  1295.         if (! $content)
  1296.             return;
  1297.  
  1298.         $vid_minwidth = 200;
  1299.         $vid_minheight = 44; // min. display size
  1300.         $vid_maxwidth = ( int ) ((KunenaFactory::getConfig()->rtewidth * 9) / 10); // Max 90% of text width
  1301.         $vid_maxheight = 720; // max. display size
  1302.         $vid_sizemax = 100; // max. display zoom in percent
  1303.  
  1304.         $vid ["type"] = (isset ( $params ["type"] )) ? JString::strtolower ( $params ["type"] ) : '';
  1305.         $vid ["param"] = (isset ( $params ["param"] )) ? $params ["param"] : '';
  1306.  
  1307.         if (! $vid ["type"]) {
  1308.             $vid_players = array ('divx' => 'divx', 'flash' => 'swf', 'mediaplayer' => 'avi,mp3,wma,wmv', 'quicktime' => 'mov,qt,qti,qtif,qtvr', 'realplayer', 'rm' );
  1309.             foreach ( $vid_players as $vid_player => $vid_exts )
  1310.                 foreach ( explode ( ',', $vid_exts ) as $vid_ext )
  1311.                     if (preg_match ( '/^(.*\.' . $vid_ext . ')$/i', $content ) > 0) {
  1312.                         $vid ["type"] = $vid_player;
  1313.                         break 2;
  1314.                     }
  1315.             unset ( $vid_players );
  1316.         }
  1317.         if (! $vid ["type"]) {
  1318.             $vid_auto = preg_match ( '#^http://.*?([^.]*)\.[^.]*(/|$)#u', $content, $vid_regs );
  1319.             if ($vid_auto) {
  1320.                 $vid ["type"] = JString::strtolower ( $vid_regs [1] );
  1321.                 switch ($vid ["type"]) {
  1322.                     case 'wideo' :
  1323.                         $vid ["type"] = 'wideo.fr';
  1324.                         break;
  1325.                 }
  1326.             }
  1327.         }
  1328.  
  1329.         $vid_providers = array (
  1330.  
  1331.         'bofunk' => array ('flash', 446, 370, 0, 0, 'http://www.bofunk.com/e/%vcode%', '', '' ),
  1332.  
  1333.         'break' => array ('flash', 464, 392, 0, 0, 'http://embed.break.com/%vcode%', '', '' ),
  1334.  
  1335.         'clipfish' => array ('flash', 464, 380, 0, 0, 'http://www.clipfish.de/videoplayer.swf?as=0&videoid=%vcode%&r=1&c=0067B3', 'videoid=([\w\-]*)', '' ),
  1336.  
  1337.         'metacafe' => array ('flash', 400, 345, 0, 0, 'http://www.metacafe.com/fplayer/%vcode%/.swf', '\/watch\/(\d*\/[\w\-]*)', array (array (6, 'wmode', 'transparent' ) ) ),
  1338.  
  1339.         'myspace' => array ('flash', 430, 346, 0, 0, 'http://lads.myspace.com/videos/vplayer.swf', 'VideoID=(\d*)', array (array (6, 'flashvars', 'm=%vcode%&v=2&type=video' ) ) ),
  1340.  
  1341.         'rutube' => array ('flash', 400, 353, 0, 0, 'http://video.rutube.ru/%vcode%', '\.html\?v=([\w]*)' ),
  1342.  
  1343.         'sapo' => array ('flash', 400, 322, 0, 0, 'http://rd3.videos.sapo.pt/play?file=http://rd3.videos.sapo.pt/%vcode%/mov/1', 'videos\.sapo\.pt\/([\w]*)', array (array (6, 'wmode', 'transparent' ) ) ),
  1344.  
  1345.         'streetfire' => array ('flash', 428, 352, 0, 0, 'http://videos.streetfire.net/vidiac.swf', '\/([\w-]*).htm', array (array (6, 'flashvars', 'video=%vcode%' ) ) ),
  1346.  
  1347.         'veoh' => array ('flash', 540, 438, 0, 0, 'http://www.veoh.com/videodetails2.swf?player=videodetailsembedded&type=v&permalinkId=%vcode%', '\/videos\/([\w-]*)', '' ),
  1348.  
  1349.         'videojug' => array ('flash', 400, 345, 0, 0, 'http://www.videojug.com/film/player?id=%vcode%', '', '' ),
  1350.  
  1351.         'vimeo' => array ('flash', 400, 321, 0, 0, 'http://www.vimeo.com/moogaloop.swf?clip_id=%vcode%&server=www.vimeo.com&fullscreen=1&show_title=1&show_byline=1&show_portrait=0&color=', '\.com\/(\d*)', '' ),
  1352.  
  1353.         'wideo.fr' => array ('flash', 400, 368, 0, 0, 'http://www.wideo.fr/p/fr/%vcode%.html', '\/([\w-]*).html', array (array (6, 'wmode', 'transparent' ) ) ),
  1354.  
  1355.         'youtube' => array ('flash', 425, 355, 0, 0, 'http://www.youtube.com/v/%vcode%?fs=1&hd=0&rel=1&cc_load_policy=1', '\/watch\?v=([\w\-]*)' , array (array (6, 'wmode', 'transparent' ) ) ),
  1356.  
  1357.         // Cannot allow public flash objects as it opens up a whole set of vulnerabilities through hacked flash files
  1358.         //              '_default' => array ($vid ["type"], 480, 360, 0, 25, $content, '', '' )
  1359.         //
  1360.         );
  1361.  
  1362.         if (isset ( $vid_providers [$vid ["type"]] )) {
  1363.             list ( $vid_type, $vid_width, $vid_height, $vid_addx, $vid_addy, $vid_source, $vid_match, $vid_par2 ) = (isset ( $vid_providers [$vid ["type"]] )) ? $vid_providers [$vid ["type"]] : $vid_providers ["_default"];
  1364.         } else {
  1365.             return;
  1366.         }
  1367.  
  1368.         unset ( $vid_providers );
  1369.         if (! empty ( $vid_auto )) {
  1370.             if ($vid_match and (preg_match ( "/$vid_match/i", $content, $vid_regs ) > 0))
  1371.                 $content = $vid_regs [1];
  1372.             else
  1373.                 return;
  1374.         }
  1375.         $vid_source = preg_replace ( '/%vcode%/', $content, $vid_source );
  1376.         if (! is_array ( $vid_par2 ))
  1377.             $vid_par2 = array ();
  1378.  
  1379.         $vid_size = isset ( $params ["size"] ) ? intval ( $params ["size"] ) : 0;
  1380.         if (($vid_size > 0) and ($vid_size < $vid_sizemax)) {
  1381.             $vid_width = ( int ) ($vid_width * $vid_size / 100);
  1382.             $vid_height = ( int ) ($vid_height * $vid_size / 100);
  1383.         }
  1384.         $vid_width += $vid_addx;
  1385.         $vid_height += $vid_addy;
  1386.         if (! isset ( $params ["size"] )) {
  1387.             if (isset ( $params ["width"] ))
  1388.                 if ($params ['width'] == '1') {
  1389.                     $params ['width'] = $vid_minwidth;
  1390.                 }
  1391.             if (isset ( $params ["width"] )) {
  1392.                 $vid_width = intval ( $params ["width"] );
  1393.             }
  1394.             if (isset ( $params ["height"] ))
  1395.                 if ($params ['height'] == '1') {
  1396.                     $params ['height'] = $vid_minheight;
  1397.                 }
  1398.             if (isset ( $params ["height"] )) {
  1399.                 $vid_height = intval ( $params ["height"] );
  1400.             }
  1401.         }
  1402.  
  1403.         if ($vid_width < $vid_minwidth)
  1404.             $vid_width = $vid_minwidth;
  1405.         if ($vid_width > $vid_maxwidth)
  1406.             $vid_width = $vid_maxwidth;
  1407.         if ($vid_height < $vid_minheight)
  1408.             $vid_height = $vid_minheight;
  1409.         if ($vid_height > $vid_maxheight)
  1410.             $vid_height = $vid_maxheight;
  1411.  
  1412.         switch ($vid_type) {
  1413.             case 'divx' :
  1414.                 $vid_par1 = array (array (1, 'classid', 'clsid:67DABFBF-D0AB-41fa-9C46-CC0F21721616' ), array (1, 'codebase', 'http://go.divx.com/plugin/DivXBrowserPlugin.cab' ), array (4, 'type', 'video/divx' ), array (4, 'pluginspage', 'http://go.divx.com/plugin/download/' ), array (6, 'src', $vid_source ), array (6, 'autoplay', 'false' ), array (5, 'width', $vid_width ), array (5, 'height', $vid_height ) );
  1415.                 $vid_allowpar = array ('previewimage' );
  1416.                 break;
  1417.             case 'flash' :
  1418.                 $vid_par1 = array (array (1, 'classid', 'clsid:d27cdb6e-ae6d-11cf-96b8-444553540000' ), array (1, 'codebase', 'http://fpdownload.macromedia.com/pub/shockwave/cabs/flash/swflash.cab' ), array (2, 'movie', $vid_source ), array (4, 'src', $vid_source ), array (4, 'type', 'application/x-shockwave-flash' ), array (4, 'pluginspage', 'http://www.macromedia.com/go/getflashplayer' ), array (6, 'quality', 'high' ), array (6, 'allowFullScreen', 'true' ), array (6, 'allowScriptAccess', 'never' ), array (5, 'width', $vid_width ), array (5, 'height', $vid_height ) );
  1419.                 $vid_allowpar = array ('flashvars', 'wmode', 'bgcolor', 'quality' );
  1420.                 break;
  1421.             case 'mediaplayer' :
  1422.                 $vid_par1 = array (array (1, 'classid', 'clsid:22d6f312-b0f6-11d0-94ab-0080c74c7e95' ), array (1, 'codebase', 'http://activex.microsoft.com/activex/controls/mplayer/en/nsmp2inf.cab' ), array (4, 'type', 'application/x-mplayer2' ), array (4, 'pluginspage', 'http://www.microsoft.com/Windows/MediaPlayer/' ), array (6, 'src', $vid_source ), array (6, 'autostart', 'false' ), array (6, 'autosize', 'true' ), array (5, 'width', $vid_width ), array (5, 'height', $vid_height ) );
  1423.                 $vid_allowpar = array ();
  1424.                 break;
  1425.             case 'quicktime' :
  1426.                 $vid_par1 = array (array (1, 'classid', 'clsid:02BF25D5-8C17-4B23-BC80-D3488ABDDC6B' ), array (1, 'codebase', 'http://www.apple.com/qtactivex/qtplugin.cab' ), array (4, 'type', 'video/quicktime' ), array (4, 'pluginspage', 'http://www.apple.com/quicktime/download/' ), array (6, 'src', $vid_source ), array (6, 'autoplay', 'false' ), array (6, 'scale', 'aspect' ), array (5, 'width', $vid_width ), array (5, 'height', $vid_height ) );
  1427.                 $vid_allowpar = array ();
  1428.                 break;
  1429.             case 'realplayer' :
  1430.                 $vid_par1 = array (array (1, 'classid', 'clsid:CFCDAA03-8BE4-11cf-B84B-0020AFBBCCFA' ), array (4, 'type', 'audio/x-pn-realaudio-plugin' ), array (6, 'src', $vid_source ), array (6, 'autostart', 'false' ), array (6, 'controls', 'ImageWindow,ControlPanel' ), array (5, 'width', $vid_width ), array (5, 'height', $vid_height ) );
  1431.                 $vid_allowpar = array ();
  1432.                 break;
  1433.             default :
  1434.                 return;
  1435.         }
  1436.  
  1437.         $vid_par3 = array ();
  1438.         foreach ( $params as $vid_key => $vid_value ) {
  1439.             if (in_array ( JString::strtolower ( $vid_key ), $vid_allowpar ))
  1440.                 array_push ( $vid_par3, array (6, $vid_key, $bbcode->HTMLEncode ( $vid_value ) ) );
  1441.         }
  1442.  
  1443.         $vid_object = $vid_param = $vid_embed = array ();
  1444.         foreach ( array_merge ( $vid_par1, $vid_par2, $vid_par3 ) as $vid_data ) {
  1445.             list ( $vid_key, $vid_name, $vid_value ) = $vid_data;
  1446.             if ($vid_key & 1)
  1447.                 $vid_object [$vid_name] = ' ' . $vid_name . '="' . preg_replace ( '/%vcode%/', $content, $vid_value ) . '"';
  1448.             if ($vid_key & 2)
  1449.                 $vid_param [$vid_name] = '<param name="' . $vid_name . '" value="' . preg_replace ( '/%vcode%/', $content, $vid_value ) . '" />';
  1450.             if ($vid_key & 4)
  1451.                 $vid_embed [$vid_name] = ' ' . $vid_name . '="' . preg_replace ( '/%vcode%/', $content, $vid_value ) . '"';
  1452.         }
  1453.  
  1454.         $tag_new = '<object';
  1455.         foreach ( $vid_object as $vid_data )
  1456.             $tag_new .= $vid_data;
  1457.         $tag_new .= '>';
  1458.         foreach ( $vid_param as $vid_data )
  1459.             $tag_new .= $vid_data;
  1460.         $tag_new .= '<embed';
  1461.         foreach ( $vid_embed as $vid_data )
  1462.             $tag_new .= $vid_data;
  1463.         $tag_new .= ' /></object>';
  1464.  
  1465.         return $tag_new;
  1466.     }
  1467.  
  1468.     function DoAttachment($bbcode, $action, $name, $default, $params, $content) {
  1469.         if ($action == BBCODE_CHECK)
  1470.             return true;
  1471.  
  1472.         if (! is_object ( $bbcode->parent ) && ! isset ( $bbcode->parent->attachments )) {
  1473.             return '[Attachment]'; // TODO
  1474.         }
  1475.         $attachments = &$bbcode->parent->attachments;
  1476.         $attachment = null;
  1477.         if (! empty ( $default )) {
  1478.             $attachment = KunenaForumMessageAttachmentHelper::get ($default);
  1479.             if (is_object ( $attachment )) {
  1480.                 unset ( $attachments [$attachment->id] );
  1481.             }
  1482.         } elseif (empty ( $content )) {
  1483.             $attachment = array_shift ( $attachments );
  1484.         } elseif (!empty ( $attachments )) {
  1485.             foreach ( $attachments as $att ) {
  1486.                 if ($att->filename == $content) {
  1487.                     $attachment = $att;
  1488.                     unset ( $attachments [$att->id] );
  1489.                     break;
  1490.                 }
  1491.             }
  1492.         }
  1493.         if (! $attachment && ! empty ( $bbcode->parent->inline_attachments )) {
  1494.             foreach ( $bbcode->parent->inline_attachments as $att ) {
  1495.                 if ($att->filename == trim(strip_tags($content))) {
  1496.                     $attachment = $att;
  1497.                     break;
  1498.                 }
  1499.             }
  1500.         }
  1501.  
  1502.         if (!is_object ( $attachment )) {
  1503.             return htmlspecialchars($content);
  1504.  
  1505.         } elseif ($attachment->exists() && !$attachment->authorise()) {
  1506.             // Hide between content from non registered users
  1507.             $link = $attachment->getTextLink();
  1508.             return '<div class="kmsgattach">' . $link . '</div>';
  1509.  
  1510.         } elseif ($attachment->exists() && is_file ( JPATH_ROOT . "/{$attachment->folder}/{$attachment->filename}" )) {
  1511.             $bbcode->parent->inline_attachments [$attachment->id] = $attachment;
  1512.             $link = JURI::base () . "{$attachment->folder}/{$attachment->filename}";
  1513.             $image = $attachment->getImageLink();
  1514.             if (empty ( $image )) {
  1515.                 return "<div class=\"kmsgattach\"><h4>" . JText::_ ( 'COM_KUNENA_FILEATTACH' ) . "</h4>" . JText::_ ( 'COM_KUNENA_FILENAME' ) . " <a href=\"" . $link . "\" target=\"_blank\" rel=\"nofollow\">" . $attachment->filename . "</a><br />" . JText::_ ( 'COM_KUNENA_FILESIZE' ) . ' ' . number_format ( intval ( $attachment->size ) / 1024, 0, '', ',' ) . ' KB' . "</div>";
  1516.             } else {
  1517.                 return "<div class=\"kmsgimage\">{$attachment->getImageLink()}</div>";
  1518.             }
  1519.  
  1520.         } else {
  1521.             return '<div class="kmsgattach"><h4>' . JText::sprintf ( 'COM_KUNENA_ATTACHMENT_DELETED', htmlspecialchars($content) ) . '</h4></div>';
  1522.  
  1523.         }
  1524.     }
  1525.  
  1526.     function DoFile($bbcode, $action, $name, $default, $params, $content) {
  1527.         if ($action == BBCODE_CHECK)
  1528.             return true;
  1529.  
  1530.         if (JFactory::getUser()->id == 0 && KunenaFactory::getConfig()->showfileforguest == 0) {
  1531.             // Hide between content from non registered users
  1532.             return '<b>' . JText::_ ( 'COM_KUNENA_SHOWIMGFORGUEST_HIDEFILE' ) . '</b>';
  1533.         } else {
  1534.             jimport ( 'joomla.filesystem.file' );
  1535.             // Make sure that filename does not contain path or URL
  1536.             $filename = basename(! empty ( $params ["name"] ) ? $params ["name"] : trim(strip_tags($content)));
  1537.  
  1538.             $filepath = "attachments/legacy/files/{$filename}";
  1539.             if (! is_file ( KPATH_MEDIA . '/' . $filepath )) {
  1540.                 // File does not exist (or URL was pointing somewhere else)
  1541.                 return '<div class="kmsgattach"><h4>' . JText::sprintf ( 'COM_KUNENA_ATTACHMENT_DELETED', $bbcode->HTMLEncode ( $filename ) ) . '</h4></div>';
  1542.             } else {
  1543.                 if (isset ( $bbcode->parent->attachments )) {
  1544.                     // Remove attachment from the attachments list
  1545.                     $attachments = &$bbcode->parent->attachments;
  1546.                     foreach ( $attachments as $att ) {
  1547.                         if ($att->filename == $filename && $att->folder == 'media/kunena/attachments/legacy/files') {
  1548.                             $attachment = $att;
  1549.                             unset ( $attachments [$att->id] );
  1550.                             $bbcode->parent->inline_attachments [$attachment->id] = $attachment;
  1551.                             break;
  1552.                         }
  1553.                     }
  1554.                 }
  1555.  
  1556.                 $fileurl = KURL_MEDIA . $filepath;
  1557.                 $filesize = isset ( $params ["size"] ) ? $params ["size"] : filesize ( KPATH_MEDIA . '/' . $filepath );
  1558.  
  1559.                 $tag_new = "<div class=\"kmsgattach\"><h4>" . JText::_ ( 'COM_KUNENA_FILEATTACH' ) . "</h4>";
  1560.                 $tag_new .= JText::_ ( 'COM_KUNENA_FILENAME' ) . " <a href=\"" . $bbcode->HTMLEncode ( $fileurl ) . "\" target=\"_blank\" rel=\"nofollow\">" . $bbcode->HTMLEncode ( $filename ) . "</a><br />";
  1561.                 $tag_new .= JText::_ ( 'COM_KUNENA_FILESIZE' ) . ' ' . $bbcode->HTMLEncode ( $filesize ) . "</div>";
  1562.                 return $tag_new;
  1563.             }
  1564.         }
  1565.     }
  1566.  
  1567.     function DoImage($bbcode, $action, $name, $default, $params, $content) {
  1568.         if ($action == BBCODE_CHECK) {
  1569.             return true;
  1570.         }
  1571.  
  1572.         $config = KunenaFactory::getConfig();
  1573.         if (JFactory::getUser()->id == 0 && $config->showimgforguest == 0) {
  1574.             // Hide between content from non registered users
  1575.             return '<b>' . JText::_ ( 'COM_KUNENA_SHOWIMGFORGUEST_HIDEIMG' ) . '</b>';
  1576.         }
  1577.         $fileurl = trim(strip_tags($content));
  1578.  
  1579.         if ($config->bbcode_img_secure != 'image') {
  1580.             if ($bbcode->autolink_disable == 0 && !preg_match("/\\.(?:gif|jpeg|jpg|jpe|png)$/ui", $fileurl)) {
  1581.                 // If the image has not legal extension, return it as link or text
  1582.                 $fileurl = $bbcode->HTMLEncode ( $fileurl );
  1583.                 if ($config->bbcode_img_secure == 'link') {
  1584.                     if (! preg_match ( '`^(/|https?://)`', $fileurl )) {
  1585.                         $fileurl = 'http://' . $fileurl;
  1586.                     }
  1587.                     return "<a href=\"" . $fileurl . "\" rel=\"nofollow\" target=\"_blank\">" . $fileurl . '</a>';
  1588.                 } else {
  1589.                     return $fileurl;
  1590.                 }
  1591.             }
  1592.         }
  1593.  
  1594.         // Legacy attachments support (mostly used to remove image from attachments list), but also fixes broken links
  1595.         if (isset ( $bbcode->parent->attachments ) && strpos ( $fileurl, '/media/kunena/attachments/legacy/images/' )) {
  1596.             // Make sure that filename does not contain path or URL
  1597.             $filename = basename($fileurl);
  1598.  
  1599.             // Remove attachment from the attachments list and show it if it exists
  1600.             $attachments = &$bbcode->parent->attachments;
  1601.             $attachment = null;
  1602.             foreach ( $attachments as $att ) {
  1603.                 if ($att->filename == $filename && $att->folder == 'media/kunena/attachments/legacy/images') {
  1604.                     $attachment = $att;
  1605.                     unset ( $attachments [$att->id] );
  1606.                     $bbcode->parent->inline_attachments [$attachment->id] = $attachment;
  1607.                     return "<div class=\"kmsgimage\">{$attachment->imagelink}</div>";
  1608.                 }
  1609.             }
  1610.             // No match -- assume that we have normal img tag
  1611.         }
  1612.  
  1613.         // Make sure we add image size if specified
  1614.         $width = ($params ['size'] ? ' width="' . $params ['size'] . '"' : '');
  1615.         $fileurl = $bbcode->HTMLEncode ( $fileurl );
  1616.  
  1617.         // Need to check if we are nested inside a URL code
  1618.         if ($bbcode->autolink_disable == 0 && $config->lightbox) {
  1619.             return '<div class="kmsgimage"><a href="'.$fileurl.'" title="" rel="lightbox[gallery]"><img src="'.$fileurl.'"'.$width.' style="max-height:'.$config->imageheight.'px;" alt="" /></a></div>';
  1620.         }
  1621.         return '<div class="kmsgimage"><img src="' . $fileurl . $width .'" style="max-height:'.$config->imageheight.'px;" alt="" /></div>';
  1622.     }
  1623.  
  1624.     function DoTerminal($bbcode, $action, $name, $default, $params, $content) {
  1625.         if ($action == BBCODE_CHECK)
  1626.             return true;
  1627.  
  1628.         if ( !isset($params ["colortext"])) $colortext = '#ffffff';
  1629.         else $colortext = $params ["colortext"];
  1630.  
  1631.         return "<div class=\"highlight\"><pre style=\"font-family:monospace;background-color:#444444;\"><span style=\"color:{$colortext};\">{$content}</span></pre></div>";
  1632.     }
  1633.     function DoHtml($bbcode, $action, $name, $default, $params, $content) {
  1634.     if ($action == BBCODE_CHECK) return true;
  1635.     return $content;
  1636. }
  1637. }
Advertisement
Add Comment
Please, Sign In to add comment