Advertisement
Guest User

Bbcm base formatter extended

a guest
Mar 16th, 2013
63
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
PHP 25.05 KB | None | 0 0
  1. <?php
  2.  
  3. class KingK_BbCodeManager_BbCode_Formatter_Base extends XFCP_KingK_BbCodeManager_BbCode_Formatter_Base
  4. {
  5.     /****
  6.     *   CREATE CUSTOM TAGS
  7.     ***/
  8.     protected $_customTags = null;
  9.    
  10.     //@extended
  11.     public function getTags()
  12.     {
  13.         $parentTags = parent::getTags();
  14.        
  15.         if($this->_customTags === null)
  16.         {
  17.             $this->bakeCustomTags();
  18.         }
  19.        
  20.         if($this->_customTags !== null)
  21.         {
  22.             return array_merge((array) $parentTags, (array) $this->_customTags);
  23.         }
  24.        
  25.         return $parentTags;
  26.     }
  27.  
  28.     public function bakeCustomTags()
  29.     {
  30.         $customTags = XenForo_Model::create('KingK_BbCodeManager_Model_CustomBbCode')->getAllCustomBbCodes('strict');
  31.          
  32.         if(!is_array($customTags))
  33.         {
  34.             return false;
  35.         }
  36.  
  37.         $allCustomTags = array();
  38.  
  39.         foreach($customTags AS $custom)
  40.         {
  41.             if((boolean)$custom['active'])
  42.             {
  43.                     if($custom['replacementBegin'])
  44.                     {
  45.                         if($custom['advancedOptions'])
  46.                         {
  47.                             $allCustomTags[$custom['tag']]['hasOption'] = true;
  48.                             $allCustomTags[$custom['tag']]['numberOfOptions'] = $custom['numberOfOptions'];
  49.                             $allCustomTags[$custom['tag']]['replacementBegin'] = $custom['replacementBegin'];
  50.                             $allCustomTags[$custom['tag']]['replacementEnd'] = $custom['replacementEnd'];
  51.                             $allCustomTags[$custom['tag']]['callback'] = array($this, 'renderAdvancedOptionsTag');
  52.  
  53.                             if($custom['plainCallback'])
  54.                             {
  55.                                 $allCustomTags[$custom['tag']]['parseCallback'] = array($this, 'parseValidatePlainIfNoOption');
  56.                             }
  57.                         }
  58.                         else
  59.                         {
  60.                             /*
  61.                                 We're in the XenForo standard replacement tag system which is using the sprintf cmd
  62.                                 If the user has written a percentage (ie:width, height) and didn't double it, then it will occur an error
  63.                                 Let's fix it
  64.                             */
  65.                             $fixSprintfPattern = '#(?<!%)%(?![%s])#';
  66.                             $custom['replacementBegin'] = preg_replace($fixSprintfPattern, '%%', $custom['replacementBegin']);
  67.                             $custom['replacementEnd'] = preg_replace($fixSprintfPattern, '%%', $custom['replacementEnd']);
  68.  
  69.                             $allCustomTags[$custom['tag']]['hasOption'] = ($custom['requiresOption'] == 0 ? false : true);
  70.                             $allCustomTags[$custom['tag']]['replace'] = array($custom['replacementBegin'], $custom['replacementEnd']);
  71.                         }
  72.                     }
  73.                     elseif($custom['phpcallback_class'])
  74.                     {
  75.                         $allCustomTags[$custom['tag']]['phpcallback_class'] = $custom['phpcallback_class'];
  76.                         $allCustomTags[$custom['tag']]['phpcallback_method'] = $custom['phpcallback_method'];
  77.                         $allCustomTags[$custom['tag']]['callback'] = array($this, 'renderAdvancedTag');
  78.  
  79.                         if($custom['plainCallback'])
  80.                         {
  81.                             $allCustomTags[$custom['tag']]['parseCallback'] = array($this, 'parseValidatePlainIfNoOption');
  82.                         }
  83.                        
  84.                         $this->_preLoadTemplatesFromCallback($custom['phpcallback_class'], $custom['phpcallback_method']);
  85.                     }
  86.                     elseif($custom['template_active'])
  87.                     {
  88.                         $this->_preloadCustomTemplates[] = $custom['template_name'];
  89.                        
  90.                         $allCustomTags[$custom['tag']]['template_name'] = $custom['template_name'];
  91.                         $allCustomTags[$custom['tag']]['callback'] = array($this, 'renderTemplateTag');
  92.  
  93.                         if($custom['template_callback_class'])
  94.                         {
  95.                             $allCustomTags[$custom['tag']]['template_callback']['class'] = $custom['template_callback_class'];
  96.                             $allCustomTags[$custom['tag']]['template_callback']['method'] = $custom['template_callback_method'];
  97.  
  98.                             $this->_preLoadTemplatesFromCallback($custom['template_callback_class'], $custom['template_callback_method']);
  99.                         }
  100.  
  101.                         if($custom['plainCallback'])
  102.                         {
  103.                             $allCustomTags[$custom['tag']]['parseCallback'] = array($this, 'parseValidatePlainIfNoOption');
  104.                         }
  105.                     }
  106.                    
  107.                     if($custom['trimLeadingLinesAfter'] > 0 && $custom['trimLeadingLinesAfter'] < 3)
  108.                     {
  109.                         $allCustomTags[$custom['tag']]['trimLeadingLinesAfter'] = $custom['trimLeadingLinesAfter'];
  110.                     }
  111.                    
  112.                     if($custom['regex'])
  113.                     {
  114.                         $allCustomTags[$custom['tag']]['optionRegex'] = $custom['regex'];
  115.                     }
  116.                    
  117.                     if($custom['plainChildren'])
  118.                     {
  119.                         $allCustomTags[$custom['tag']]['plainChildren'] = true;
  120.                     }
  121.                    
  122.                     if($custom['stopSmilies'])
  123.                     {
  124.                         $allCustomTags[$custom['tag']]['stopSmilies'] = true;
  125.                     }
  126.                    
  127.                     if($custom['stopLineBreakConversion'])
  128.                     {
  129.                         $allCustomTags[$custom['tag']]['stopLineBreakConversion'] = true;
  130.                     }
  131.  
  132.                     if($custom['parseOptions'])
  133.                     {
  134.                         $allCustomTags[$custom['tag']]['parseOptions'] = true;
  135.                     }
  136.  
  137.                     if($custom['parser_has_usr'])
  138.                     {
  139.                         $allCustomTags[$custom['tag']]['parser_perms']['parser_has_usr'] = $custom['parser_has_usr'];                  
  140.                     }
  141.  
  142.                     if($custom['parser_usr'])
  143.                     {
  144.                         $allCustomTags[$custom['tag']]['parser_perms']['parser_usr'] = $custom['parser_usr'];                  
  145.                     }
  146.  
  147.                     if($custom['parser_return'])
  148.                     {
  149.                         $allCustomTags[$custom['tag']]['parser_perms']['parser_return'] = $custom['parser_return'];                
  150.                     }
  151.  
  152.                     if($custom['parser_return_delay'])
  153.                     {
  154.                         $allCustomTags[$custom['tag']]['parser_perms']['parser_return_delay'] = $custom['parser_return_delay'];
  155.                     }
  156.  
  157.                     $allCustomTags[$custom['tag']]['view_perms']['can_view_content'] = true;
  158.                        
  159.                     if($custom['view_has_usr'])
  160.                     {
  161.                         $visitor = XenForo_Visitor::getInstance();
  162.                         $visitorUserGroupIds = array_merge(array((string)$visitor['user_group_id']), (explode(',', $visitor['secondary_group_ids'])));
  163.                         $visitorsOk = unserialize($custom['view_usr']);
  164.                         $canViewBbCode = (array_intersect($visitorUserGroupIds, $visitorsOk)) ? true : false;
  165.                        
  166.                         $allCustomTags[$custom['tag']]['view_perms']['can_view_content'] = $canViewBbCode;
  167.                         $allCustomTags[$custom['tag']]['view_perms']['view_return'] = $custom['view_return'];  
  168.  
  169.                             if($custom['view_return'] == 'default_template' && array_search('bbcm_viewer_content_protected', $this->_preloadCustomTemplates) === false)
  170.                             {
  171.                                 $this->_preloadCustomTemplates[] = 'bbcm_viewer_content_protected';
  172.                             }
  173.  
  174.                         if($custom['view_return_delay'])
  175.                         {
  176.                             $allCustomTags[$custom['tag']]['view_perms']['view_return_delay'] = $custom['view_return_delay'];
  177.                         }
  178.                     }
  179.                 }
  180.         }
  181.  
  182.          $this->_customTags = $allCustomTags;
  183.     }
  184.  
  185.     /****
  186.     *   RENDER TAGS
  187.     ***/
  188.    
  189.     public function renderAdvancedOptionsTag(array $tag, array $rendererStates)
  190.     {
  191.         $this->_bakeCurrentPostParams($tag);
  192.  
  193.         $tagInfo['numberOfOptions'] = $this->_tags[$tag['tag']]['numberOfOptions'];
  194.         $tagInfo['replacementBegin'] = $this->_tags[$tag['tag']]['replacementBegin'];
  195.         $tagInfo['replacementEnd'] = $this->_tags[$tag['tag']]['replacementEnd'];
  196.        
  197.         if (!empty($tag['option']) && $this->parseMultipleOptions($tag['option']))
  198.         {
  199.             $options = $this->parseMultipleOptions($tag['option']);
  200.  
  201.             if( isset($this->_tags[$tag['tag']]['parseOptions']) )
  202.             {
  203.                 //No need to securise the Bb Code (no xen:raw setting here) => second arg is "false"
  204.                 $options = $this->parseAndSecuriseBbCodesInOptions($options, false);
  205.             }
  206.  
  207.             $parserPermissionsReturn = $this->checkBbCodeParsingPerms($tag, $rendererStates);
  208.             if($parserPermissionsReturn !== true)
  209.             {
  210.                 return $parserPermissionsReturn;
  211.             }
  212.  
  213.             $viewPermissionsReturn = $this->checkBbCodeViewPerms($tag, $rendererStates);
  214.             if($viewPermissionsReturn !== true)
  215.             {
  216.                 return $viewPermissionsReturn;
  217.             }
  218.  
  219.             if((int)count($options) == $tagInfo['numberOfOptions'])
  220.             {
  221.                 for($replaceIndex = 0; $replaceIndex <= ($tagInfo['numberOfOptions'] - 1); $replaceIndex++)
  222.                 {
  223.                     if(!(isset($options[$replaceIndex])))
  224.                     {
  225.                         //With the fix in the for loop, this protection shouldn't be needed anymore but let's keep it for safety
  226.                         continue;
  227.                     }
  228.  
  229.                     $replaceNumber = $replaceIndex + 1;
  230.                     $tagInfo['replacementBegin'] = str_replace('{' . $replaceNumber . '}', $options[$replaceIndex], $tagInfo['replacementBegin']);
  231.                     $tagInfo['replacementEnd'] = str_replace('{' . $replaceNumber . '}', $options[$replaceIndex], $tagInfo['replacementEnd']);
  232.                    
  233.                     $content = $this->renderSubTree($tag['children'], $rendererStates);
  234.                 }
  235.                 return $tagInfo['replacementBegin'] . $content . $tagInfo['replacementEnd'];
  236.             }
  237.             else
  238.             {
  239.                 return $tag['original'][0] . $tag['children'][0] . $tag['original'][1];
  240.             }
  241.         }
  242.     }
  243.  
  244.  
  245.     public function renderTemplateTag(array $tag, array $rendererStates, $increment = true)
  246.     {
  247.         if($increment == true)
  248.         {
  249.             $this->_bakeCurrentPostParams($tag);
  250.         }
  251.            
  252.         if(!isset($rendererStates['canUseBbCode']))
  253.         {
  254.             $parserPermissionsReturn = $this->checkBbCodeParsingPerms($tag, $rendererStates);
  255.    
  256.             if($parserPermissionsReturn !== true)
  257.             {
  258.                 //Will a short loop with changing the rendererStates
  259.                 return $parserPermissionsReturn;
  260.             }
  261.  
  262.             $rendererStates['isPost'] = ($this->getPostParams() !== NULL) ? true : false;
  263.             $rendererStates['canUseBbCode'] = true;
  264.         }
  265.  
  266.         if(!isset($rendererStates['canViewBbCode']))
  267.         {
  268.             $viewPermissionsReturn = $this->checkBbCodeViewPerms($tag, $rendererStates);
  269.  
  270.             if($viewPermissionsReturn !== true)
  271.             {
  272.                 return $viewPermissionsReturn;
  273.             }
  274.            
  275.             $rendererStates['canViewBbCode'] = true;
  276.         }
  277.  
  278.         $content = $this->renderSubTree($tag['children'], $rendererStates);
  279.         $options = array();    
  280.         $templateName = $this->_tags[$tag['tag']]['template_name'];
  281.  
  282.         if (!empty($tag['option']) && $this->parseMultipleOptions($tag['option']))
  283.         {
  284.             $options = $this->parseMultipleOptions($tag['option']);
  285.             array_unshift($options, 'killMe');
  286.             unset($options[0]);
  287.            
  288.             if( isset($this->_tags[$tag['tag']]['parseOptions']) )
  289.             {
  290.                 $options = $this->parseAndSecuriseBbCodesInOptions($options);
  291.             }
  292.             else
  293.             {
  294.                 $options = $this->secureBbCodesInOptions($options);
  295.             }
  296.         }
  297.  
  298.         if (!$this->_view)
  299.         {
  300.             $fallBack = true;
  301.         }
  302.  
  303.         if( isset($this->_tags[$tag['tag']]['template_callback']) )
  304.         {
  305.             $template_callback_class = $this->_tags[$tag['tag']]['template_callback']['class'];
  306.             $template_callback_method = $this->_tags[$tag['tag']]['template_callback']['method'];
  307.        
  308.             XenForo_Application::autoload($template_callback_class);
  309.             call_user_func_array(array($template_callback_class, $template_callback_method), array(&$content, &$options, &$templateName, &$fallBack, $rendererStates, $this));
  310.         }
  311.  
  312.         if($fallBack === true)
  313.         {
  314.             //Can me modified by the above template Callback
  315.             $fallBack = '<div class="template_fallback_' . $tag['tag'] . '">' . $this->renderSubTree($tag['children'], $rendererStates) . '</div>';
  316.         }
  317.  
  318.         $templateArguments = array('content' => $content, 'options' => $options, 'rendererStates' => $rendererStates);
  319.  
  320.         return $this->renderCustomTemplate($templateName, $templateArguments, $fallBack);
  321.     }
  322.    
  323.     public function renderAdvancedTag(array $tag, array $rendererStates, $increment = true)
  324.     {
  325.         if($increment == true)
  326.         {
  327.             $this->_bakeCurrentPostParams($tag);
  328.         }
  329.  
  330.         if(!isset($rendererStates['canUseBbCode']))
  331.         {
  332.             $parserPermissionsReturn = $this->checkBbCodeParsingPerms($tag, $rendererStates);
  333.  
  334.             if($parserPermissionsReturn !== true)
  335.             {
  336.                 //Will a short loop with changing the rendererStates
  337.                 return $parserPermissionsReturn;
  338.             }
  339.  
  340.             $rendererStates['isPost'] = ($this->getPostParams() !== NULL) ? true : false;
  341.             $rendererStates['canUseBbCode'] = true;
  342.         }
  343.  
  344.         if(!isset($rendererStates['canViewBbCode']))
  345.         {
  346.             $viewPermissionsReturn = $this->checkBbCodeViewPerms($tag, $rendererStates);
  347.  
  348.             if($viewPermissionsReturn !== true)
  349.             {
  350.                 return $viewPermissionsReturn;
  351.             }
  352.            
  353.             $rendererStates['canViewBbCode'] = true;
  354.         }
  355.        
  356.         $phpcallback_class = $this->_tags[$tag['tag']]['phpcallback_class'];
  357.         $phpcallback_method = $this->_tags[$tag['tag']]['phpcallback_method'];
  358.  
  359.         XenForo_Application::autoload($phpcallback_class);
  360.         return call_user_func_array(array($phpcallback_class, $phpcallback_method), array($tag, $rendererStates, &$this));
  361.     }
  362.  
  363.     //@extended
  364.     public function renderValidTag(array $tagInfo, array $tag, array $rendererStates)
  365.     {
  366.         $parent = parent::renderValidTag($tagInfo, $tag, $rendererStates);
  367.    
  368.         if (!empty($tagInfo['replace']))
  369.         {
  370.             //Implement the tool for "Standard Bb Codes" (Bb Codes which don't use the Advanced Options)
  371.             $this->_bakeCurrentPostParams($tag);
  372.  
  373.             $parserPermissionsReturn = $this->checkBbCodeParsingPerms($tag, $rendererStates);
  374.             if($parserPermissionsReturn !== true)
  375.             {
  376.                 return $parserPermissionsReturn;
  377.             }
  378.  
  379.             $viewPermissionsReturn = $this->checkBbCodeViewPerms($tag, $rendererStates);
  380.             if($viewPermissionsReturn !== true)
  381.             {
  382.                 return $viewPermissionsReturn;
  383.             }
  384.         }
  385.    
  386.         return $parent;
  387.     }
  388.  
  389.     public function parseMultipleOptions($tag)
  390.     {
  391.         $options = XenForo_Application::get('options');
  392.         $separator = (empty($options->Bbcm_BbCode_Options_Separator)) ? ', ' : $options->Bbcm_BbCode_Options_Separator;
  393.  
  394.         $attributes = explode($separator, $tag);
  395.         return $attributes;
  396.     }
  397.  
  398.     /****
  399.     *   PERMISSIONS TOOLS
  400.     ***/
  401.     public function checkBbCodeParsingPerms(array $tag, array $rendererStates)
  402.     {
  403.         if( !isset($this->_tags[$tag['tag']]['parser_perms']) || !isset($this->_tags[$tag['tag']]['parser_perms']['parser_has_usr']) )
  404.         {
  405.             //No need to check parser_has_usr value since the key won't be there if disable (see @bakeCustomTags)
  406.             return true;
  407.         }
  408.  
  409.         $perms = $this->_tags[$tag['tag']]['parser_perms'];
  410.  
  411.         $postParams = $this->getPostParams();
  412.  
  413.         if( $postParams !== NULL)
  414.         {
  415.             $posterUserGroupIds = array_merge(array((string)$postParams['user_group_id']), (explode(',', $postParams['secondary_group_ids'])));
  416.             $postersOk = unserialize($perms['parser_usr']);
  417.        
  418.             if(array_intersect($posterUserGroupIds, $postersOk))
  419.             {
  420.                 return true;   
  421.             }
  422.         }
  423.  
  424.         if( isset($perms['parser_return_delay']) )
  425.         {
  426.             $autorisedLimit = $perms['parser_return_delay'];
  427.             $post_date = $this->getPostParam('post_date');         
  428.  
  429.             if($post_date !== NULL)
  430.             {
  431.                 $interval = XenForo_Application::$time - $post_date;
  432.                 $diff_hours = floor($interval / 3600);
  433.                
  434.                 if($diff_hours <= $autorisedLimit)
  435.                 {
  436.                     return true;
  437.                 }
  438.             }
  439.         }
  440.        
  441.         $output = '';
  442.  
  443.         if($perms['parser_return'] == 'content')
  444.         {
  445.             $output = $this->renderSubTree($tag['children'], $rendererStates);
  446.         }
  447.         elseif($perms['parser_return'] == 'content_bb')
  448.         {
  449.             $output = $tag['original'][0] . $this->renderSubTree($tag['children'], $rendererStates) . $tag['original'][1];
  450.         }
  451.         elseif($perms['parser_return'] == 'callback')
  452.         {
  453.             $rendererStates['isPost'] = ($postParams !== NULL) ? true : false;
  454.             $rendererStates['canUseBbCode'] = false; //Default: if is not a post, no way to get this value anyway
  455.             return $this->renderAdvancedTag($tag, $rendererStates, false);
  456.  
  457.         }
  458.         elseif($perms['parser_return'] == 'template')
  459.         {
  460.             $rendererStates['isPost'] = ($postParams !== NULL) ? true : false;
  461.             $rendererStates['canUseBbCode'] = false;
  462.             return $this->renderTemplateTag($tag, $rendererStates, false);
  463.         }
  464.        
  465.         return $output;
  466.     }
  467.  
  468.  
  469.     public function checkBbCodeViewPerms(array $tag, array $rendererStates)
  470.     {
  471.         if( !isset($this->_tags[$tag['tag']]['view_perms']) )
  472.         {
  473.             return true;
  474.         }
  475.        
  476.         $perms = $this->_tags[$tag['tag']]['view_perms'];
  477.  
  478.         if($perms['can_view_content'] === true)
  479.         {
  480.             return true;
  481.         }
  482.  
  483.         if( isset($perms['view_return_delay']) )
  484.         {
  485.  
  486.             $autorisedLimit = $perms['view_return_delay'];
  487.             $post_date = $this->getPostParam('post_date');         
  488.  
  489.             if($post_date !== NULL)
  490.             {
  491.                 $interval = XenForo_Application::$time - $post_date;
  492.                 $diff_hours = floor($interval / 3600);
  493.  
  494.  
  495.                 if($diff_hours < $autorisedLimit)
  496.                 {
  497.                     return true;
  498.                 }
  499.             }
  500.         }
  501.  
  502.         $rendererStates['canViewBbCode'] = false;
  503.  
  504.         $output = '';
  505.  
  506.         if($perms['view_return'] == 'phrase')
  507.         {
  508.             $output = new XenForo_Phrase('bbcm_viewer_content_protected');
  509.         }
  510.         elseif($perms['view_return'] == 'callback')
  511.         {
  512.             return $this->renderAdvancedTag($tag, $rendererStates, false);
  513.         }
  514.         elseif($perms['view_return'] == 'template')
  515.         {
  516.             return $this->renderTemplateTag($tag, $rendererStates, false);
  517.         }
  518.         elseif($perms['view_return'] == 'default_template')
  519.         {
  520.             $fallBack = new XenForo_Phrase('bbcm_viewer_content_protected');
  521.             $templateArguments = array('phrase' => $fallBack, 'rendererStates' => $rendererStates);
  522.             return $this->renderCustomTemplate('bbcm_viewer_content_protected', $templateArguments, $fallBack);        
  523.         }
  524.        
  525.         return $output;
  526.     }
  527.  
  528.     /****
  529.     *   PARSER TOOLS
  530.     ***/
  531.     protected $_parser;
  532.    
  533.     public function getParser()
  534.     {
  535.         if (!isset($this->_parser))
  536.         {
  537.             $this->_parser = new XenForo_BbCode_Parser($this);
  538.         }
  539.         return $this->_parser;
  540.     }
  541.  
  542.  
  543.     public function secureBbCodesInOptions(array $options)
  544.     {
  545.             foreach ($options as &$option)
  546.             {
  547.             $option = htmlspecialchars($option);
  548.             }
  549.            
  550.             return $options;
  551.     }
  552.  
  553.     public function parseAndSecuriseBbCodesInOptions(array $options, $secure = true)
  554.     {
  555.             foreach ($options as &$option)
  556.             {
  557.             if($secure === true)
  558.             {
  559.                 $option = htmlspecialchars($option); //Protection
  560.             }
  561.            
  562.             $option = $this->ParseMyBBcodesOptions($option);
  563.             }
  564.            
  565.             return $options;
  566.     }
  567.    
  568.     public function ParseMyBBcodesOptions($string)
  569.     {
  570.         $tester = strlen($string) - strlen(strip_tags($string));
  571.  
  572.         if (empty($tester) AND preg_match('#[\[{](.+?)(?:=.+?)?[}\]].+?[{\[]/\1([}\]])#i', $string, $captures))
  573.         {
  574.             if(isset($captures[2]) && $captures[2] == '}')
  575.             {
  576.                 //This is an old special tag {a}...{/a}, convert it back to a normal tag [a]...[/a]
  577.                 $string = preg_replace('#[\[{]((.+?)(?:=.+?)?)[}\]](.+?)[{\[](/\2)[}\]]#i', '[$1]$3[$4]', $string);
  578.             }
  579.  
  580.             $parser = $this->getParser();
  581.             $string = $parser->render($string);
  582.  
  583.             //Fix for htmlspecialchars
  584.             $string = str_replace(array('&amp;lt;', '&amp;gt;', '&amp;amp;'), array('&lt;', '&gt;', '&amp;'), $string);
  585.         }
  586.  
  587.         return $string;
  588.     }
  589.  
  590.     /****
  591.     *   TAG ALIGN FIX @extended
  592.     ***/
  593.     public function renderTagAlign(array $tag, array $rendererStates)
  594.     {
  595.         $options = XenForo_Application::get('options');
  596.        
  597.         if(!$options->Bbcm_PatchAlignBbCode)
  598.         {      
  599.             return parent::renderTagAlign($tag, $rendererStates);
  600.         }
  601.        
  602.         $text = $this->renderSubTree($tag['children'], $rendererStates);
  603.         if (trim($text) === '')
  604.         {
  605.             $text = '<br />';
  606.         }
  607.  
  608.         switch (strtolower($tag['tag']))
  609.         {
  610.             case 'left':
  611.             case 'center':
  612.             case 'right':
  613.                 return '<div align="' . $tag['tag'] . '">' . $text . '</div>';
  614.  
  615.             default:
  616.                 return $text;
  617.         }
  618.     }
  619.  
  620.     /****
  621.     *   PRELOAD & RENDER TEMPLATES TOOL
  622.     ***/
  623.     protected $_preloadCustomTemplates = array();
  624.    
  625.     //@Extended
  626.     public function preLoadTemplates(XenForo_View $view)
  627.     {
  628.          //Preload Custom Templates
  629.          if($this->_view && is_array($this->_preloadCustomTemplates))
  630.          {
  631.             foreach($this->_preloadCustomTemplates as $templateName)
  632.             {
  633.                 $this->_view->preLoadTemplate($templateName);
  634.             }
  635.         }
  636.  
  637.         return parent::preLoadTemplates($view);
  638.     }
  639.  
  640.     protected function _preLoadTemplatesFromCallback($class, $method)
  641.     {
  642.             //Search if the callback has some templates to preload (from the method "preloadTemplates")
  643.             if(method_exists($class, 'preloadTemplates'))
  644.             {
  645.                 $templateNames = $class::preloadTemplates($method);
  646.  
  647.                 if(!is_array($templateNames))
  648.                 {
  649.                     $templateNames = array($templateNames);
  650.                 }
  651.                
  652.                 foreach($templateNames as $templateName)
  653.                 {
  654.                     if(!empty($templateName) && array_search($templateName, $this->_preloadCustomTemplates) === false)
  655.                     {
  656.                         $this->_preloadCustomTemplates[] = $templateName;
  657.                     }
  658.                 }
  659.             }
  660.     }
  661.  
  662.     public function renderCustomTemplate($templateName, array $params = array(), $fallBack = false)
  663.     {
  664.         if ($this->_view)
  665.         {
  666.             //Create and render template
  667.             $template = $this->_view->createTemplateObject($templateName, $params);
  668.             return $template->render();
  669.         }
  670.  
  671.         return $fallBack;
  672.     }
  673.  
  674.  
  675.     /****
  676.     *   GET THREAD/POSTS PARAMS TOOLS
  677.     ***/
  678.     protected $_threadParams = null;
  679.     protected $_postsDatas = null;
  680.     protected $_bbCodesMap = null;
  681.     protected $_bbCodesIncrementation = array();
  682.     protected $_currentPostParams = null;
  683.  
  684.     //@extended
  685.     public function setView(XenForo_View $view = null)
  686.     {
  687.         parent::setView($view);
  688.  
  689.         if ($view)
  690.         {
  691.             $params = $view->getParams();
  692.  
  693.             if(isset($params['posts']))
  694.             {
  695.                 $this->_postsDatas = $params['posts'];
  696.                 $this->_createBbCodesMap($params['posts']);
  697.             }
  698.  
  699.             if(isset($params['thread']))
  700.             {
  701.                 $this->_threadParams = $params['thread'];
  702.             }          
  703.         }
  704.     }
  705.  
  706.     protected function _createBbCodesMap($posts = NULL)
  707.     {
  708.         if( $posts === NULL || !is_array($posts) )
  709.         {
  710.             return;
  711.         }
  712.  
  713.         foreach($posts as $post_id => $post)
  714.         {
  715.             $BbCodesTree = $this->getParser()->parse($post['message']);
  716.  
  717.             $it = new RecursiveIteratorIterator( new RecursiveArrayIterator($BbCodesTree) );
  718.  
  719.             foreach ($it as $tagKey => $tagName)
  720.             {
  721.                 if($tagKey === 'tag')
  722.                 {
  723.                     $this->_bbCodesMap[$tagName][] = $post_id;
  724.                 }
  725.             }
  726.         }
  727.  
  728.         if(self::$debug === true)
  729.         {
  730.             echo "Bb Codes Map:<br />";
  731.             Zend_Debug::dump($this->_bbCodesMap);
  732.         }
  733.     }
  734.  
  735.     protected function _bakeCurrentPostParams($tag)
  736.     {
  737.         $id = $this->_getCurrentTagId($tag);
  738.  
  739.         $tagName = $tag['tag'];
  740.        
  741.         if( !isset($this->_bbCodesMap[$tagName][$id]) )
  742.         {
  743.             self::$debug_phrase_init .= (self::$debug === true) ? "According to the Tag Map, the position '$id' of the '$tag' doesn't exist<br />" : '';
  744.             $this->_currentPostParams = NULL;
  745.             return;
  746.         }
  747.        
  748.         $postId = $this->_bbCodesMap[$tagName][$id];
  749.  
  750.         if ( !isset($this->_postsDatas[$postId]) )
  751.         {
  752.             self::$debug_phrase_init .= (self::$debug === true) ? "The post id ($id) doesn't exist<br />" : '';
  753.             $this->_currentPostParams = NULL;
  754.             return;
  755.         }
  756.        
  757.         $this->_currentPostParams = $this->_postsDatas[$postId];
  758.         $this->_debugInit($tag['tag']);
  759.     }
  760.  
  761.     protected function _getCurrentTagId($tag)
  762.     {
  763.         $tagName = $tag['tag'];
  764.  
  765.         /***
  766.             Let's implement an incrementation fix for identical nested tags
  767.            
  768.             Why? Identical Nested Tags don't recall their parse function (php/template/etc...). Only the parent tag is used.
  769.  
  770.                 #Example: [hl]This is the parent tag [hl=orange]This is a identical nested tag[/hl] Back to the parent[/hl]
  771.                 If we check the renderTemplateTag, we will be able to see that the function will be only call once
  772.                 This is a problem. The function _bakeCurrentPostParams will only be launched once, so is the below incrementation.
  773.                 The ID of the Tag won't be correct anymore according to our Tags Map ($this->_bbCodesMap)
  774.                
  775.             Solution: Check the children of the tag, detect the number of identical nested tags and use it as a fix.
  776.         **/
  777.  
  778.         $fix = 0;
  779.         if( isset($tag['children']) )
  780.         {
  781.             $it = new RecursiveIteratorIterator( new RecursiveArrayIterator($tag['children']) );
  782.    
  783.             foreach ($it as $tagKey => $childTagName)
  784.             {
  785.                 if($tagKey === 'tag')
  786.                 {
  787.                     if($childTagName === $tagName)
  788.                     {
  789.                         $fix++;
  790.                     }
  791.                 }
  792.             }
  793.            
  794.             if($fix)
  795.             {
  796.                 self::$debug_phrase_init .= (self::$debug === true) ? "Fix: $fix<br />" : '';
  797.             }
  798.         }
  799.        
  800.         //End of Fix - $fix is ready to use
  801.        
  802.         if( !isset($this->_bbCodesIncrementation[$tagName]) )
  803.         {
  804.             $this->_bbCodesIncrementation[$tagName] = 0;   
  805.         }
  806.         else
  807.         {
  808.             $this->_bbCodesIncrementation[$tagName] = $this->_bbCodesIncrementation[$tagName]+1+$fix;
  809.         }
  810.        
  811.         return $this->_bbCodesIncrementation[$tagName];
  812.     }
  813.    
  814.     public function getThreadParams()
  815.     {
  816.         return $this->_threadParams;
  817.     }
  818.  
  819.     public function getThreadParam($param)
  820.     {
  821.         if( isset($this->_threadParams[$param]) )
  822.         {
  823.             return $this->_threadParams[$param];
  824.         }
  825.  
  826.         self::$debug_phrase_init .= (self::$debug === true) ? "This Thread parameter is missing: $param <br />" : '';
  827.         return NULL;
  828.     }
  829.  
  830.     public function getPostParams()
  831.     {
  832.         return $this->_currentPostParams;
  833.     }
  834.  
  835.     public function getPostParam($param)
  836.     {
  837.         if( isset($this->_currentPostParams[$param]) )
  838.         {
  839.             return $this->_currentPostParams[$param];
  840.         }
  841.            
  842.         if(self::$debug === true)
  843.         {
  844.             $callers = debug_backtrace();
  845.             $caller = $callers[1]['function'];
  846.             $line = $callers[1]['line'];
  847.             self::$debug_phrase_init .= "This Post parameter is missing: $param (calling function: $caller - line:$line)<br />";
  848.         }
  849.    
  850.         return NULL;
  851.     }  
  852.  
  853.     /****
  854.     *   Debug Module
  855.     *   Yes, it's ugly but it can help a lot when developping - will be removed if no problem occurs
  856.     ***/
  857.     protected static $debug = false;
  858.     protected static $debug_phrase_init;
  859.  
  860.     protected function _debugInit($tagName)
  861.     {
  862.             if(self::$debug === true)
  863.             {
  864.                 $tagId = $this->_bbCodesIncrementation[$tagName];
  865.                 $postId = $this->getPostParam('post_id');
  866.                 $debugPhrase = self::$debug_phrase_init;
  867.                 echo "The tag being processed is $tagName (ID:$tagId - Post ID:$postId)<br />$debugPhrase";
  868.                 self::$debug_phrase_init = '';
  869.             }
  870.     }
  871. }
  872. //Zend_Debug::dump($abc);
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement