Source for file html.php

Documentation is available at html.php

  1. <?php
  2. /**
  3.  * @package     Joomla.Platform
  4.  * @subpackage  Document
  5.  *
  6.  * @copyright   Copyright (C) 2005 - 2013 Open Source Matters, Inc. All rights reserved.
  7.  * @license     GNU General Public License version 2 or later; see LICENSE
  8.  */
  9.  
  10. defined('JPATH_PLATFORM'or die;
  11.  
  12. jimport('joomla.utilities.utility');
  13.  
  14. /**
  15.  * DocumentHTML class, provides an easy interface to parse and display a HTML document
  16.  *
  17.  * @package     Joomla.Platform
  18.  * @subpackage  Document
  19.  * @since       11.1
  20.  */
  21. class JDocumentHTML extends JDocument
  22. {
  23.     /**
  24.      * Array of Header <link> tags
  25.      *
  26.      * @var    array 
  27.      * @since  11.1
  28.      */
  29.     public $_links = array();
  30.  
  31.     /**
  32.      * Array of custom tags
  33.      *
  34.      * @var    array 
  35.      * @since  11.1
  36.      */
  37.     public $_custom = array();
  38.  
  39.     /**
  40.      * Name of the template
  41.      *
  42.      * @var    string 
  43.      * @since  11.1
  44.      */
  45.     public $template = null;
  46.  
  47.     /**
  48.      * Base url
  49.      *
  50.      * @var    string 
  51.      * @since  11.1
  52.      */
  53.     public $baseurl = null;
  54.  
  55.     /**
  56.      * Array of template parameters
  57.      *
  58.      * @var    array 
  59.      * @since  11.1
  60.      */
  61.     public $params = null;
  62.  
  63.     /**
  64.      * File name
  65.      *
  66.      * @var    array 
  67.      * @since  11.1
  68.      */
  69.     public $_file = null;
  70.  
  71.     /**
  72.      * String holding parsed template
  73.      *
  74.      * @var    string 
  75.      * @since  11.1
  76.      */
  77.     protected $_template = '';
  78.  
  79.     /**
  80.      * Array of parsed template JDoc tags
  81.      *
  82.      * @var    array 
  83.      * @since  11.1
  84.      */
  85.     protected $_template_tags = array();
  86.  
  87.     /**
  88.      * Integer with caching setting
  89.      *
  90.      * @var    integer 
  91.      * @since  11.1
  92.      */
  93.     protected $_caching = null;
  94.  
  95.     /**
  96.      * Set to true when the document should be output as HTML%
  97.      *
  98.      * @var    boolean 
  99.      * @since  12.1
  100.      */
  101.     private $_html5 null;
  102.  
  103.     /**
  104.      * Class constructor
  105.      *
  106.      * @param   array  $options  Associative array of options
  107.      *
  108.      * @since   11.1
  109.      */
  110.     public function __construct($options array())
  111.     {
  112.         parent::__construct($options);
  113.  
  114.         // Set document type
  115.         $this->_type = 'html';
  116.  
  117.         // Set default mime type and document metadata (meta data syncs with mime type by default)
  118.         $this->setMimeEncoding('text/html');
  119.     }
  120.  
  121.     /**
  122.      * Get the HTML document head data
  123.      *
  124.      * @return  array  The document head data in array form
  125.      *
  126.      * @since   11.1
  127.      */
  128.     public function getHeadData()
  129.     {
  130.         $data array();
  131.         $data['title']       $this->title;
  132.         $data['description'$this->description;
  133.         $data['link']        $this->link;
  134.         $data['metaTags']    $this->_metaTags;
  135.         $data['links']       $this->_links;
  136.         $data['styleSheets'$this->_styleSheets;
  137.         $data['style']       $this->_style;
  138.         $data['scripts']     $this->_scripts;
  139.         $data['script']      $this->_script;
  140.         $data['custom']      $this->_custom;
  141.         $data['scriptText']  JText::script();
  142.         return $data;
  143.     }
  144.  
  145.     /**
  146.      * Set the HTML document head data
  147.      *
  148.      * @param   array  $data  The document head data in array form
  149.      *
  150.      * @return  JDocumentHTML instance of $this to allow chaining
  151.      *
  152.      * @since   11.1
  153.      */
  154.     public function setHeadData($data)
  155.     {
  156.         if (empty($data|| !is_array($data))
  157.         {
  158.             return;
  159.         }
  160.  
  161.         $this->title        = (isset($data['title']&& !empty($data['title'])) $data['title'$this->title;
  162.         $this->description  = (isset($data['description']&& !empty($data['description'])) $data['description'$this->description;
  163.         $this->link         = (isset($data['link']&& !empty($data['link'])) $data['link'$this->link;
  164.         $this->_metaTags    = (isset($data['metaTags']&& !empty($data['metaTags'])) $data['metaTags'$this->_metaTags;
  165.         $this->_links       = (isset($data['links']&& !empty($data['links'])) $data['links'$this->_links;
  166.         $this->_styleSheets = (isset($data['styleSheets']&& !empty($data['styleSheets'])) $data['styleSheets'$this->_styleSheets;
  167.         $this->_style       = (isset($data['style']&& !empty($data['style'])) $data['style'$this->_style;
  168.         $this->_scripts     = (isset($data['scripts']&& !empty($data['scripts'])) $data['scripts'$this->_scripts;
  169.         $this->_script      = (isset($data['script']&& !empty($data['script'])) $data['script'$this->_script;
  170.         $this->_custom      = (isset($data['custom']&& !empty($data['custom'])) $data['custom'$this->_custom;
  171.  
  172.         if (isset($data['scriptText']&& !empty($data['scriptText']))
  173.         {
  174.             foreach ($data['scriptText'as $key => $string)
  175.             {
  176.                 JText::script($key$string);
  177.             }
  178.         }
  179.  
  180.         return $this;
  181.     }
  182.  
  183.     /**
  184.      * Merge the HTML document head data
  185.      *
  186.      * @param   array  $data  The document head data in array form
  187.      *
  188.      * @return  JDocumentHTML instance of $this to allow chaining
  189.      *
  190.      * @since   11.1
  191.      */
  192.     public function mergeHeadData($data)
  193.     {
  194.  
  195.         if (empty($data|| !is_array($data))
  196.         {
  197.             return;
  198.         }
  199.  
  200.         $this->title = (isset($data['title']&& !empty($data['title']&& !stristr($this->title$data['title']))
  201.             ? $this->title . $data['title']
  202.             : $this->title;
  203.         $this->description = (isset($data['description']&& !empty($data['description']&& !stristr($this->description$data['description']))
  204.             ? $this->description . $data['description']
  205.             : $this->description;
  206.         $this->link = (isset($data['link'])) $data['link'$this->link;
  207.  
  208.         if (isset($data['metaTags']))
  209.         {
  210.             foreach ($data['metaTags'as $type1 => $data1)
  211.             {
  212.                 $booldog $type1 == 'http-equiv' true false;
  213.                 foreach ($data1 as $name2 => $data2)
  214.                 {
  215.                     $this->setMetaData($name2$data2$booldog);
  216.                 }
  217.             }
  218.         }
  219.  
  220.         $this->_links = (isset($data['links']&& !empty($data['links']&& is_array($data['links']))
  221.             ? array_unique(array_merge($this->_links$data['links']))
  222.             : $this->_links;
  223.         $this->_styleSheets = (isset($data['styleSheets']&& !empty($data['styleSheets']&& is_array($data['styleSheets']))
  224.             ? array_merge($this->_styleSheets$data['styleSheets'])
  225.             : $this->_styleSheets;
  226.  
  227.         if (isset($data['style']))
  228.         {
  229.             foreach ($data['style'as $type => $stdata)
  230.             {
  231.                 if (!isset($this->_style[strtolower($type)]|| !stristr($this->_style[strtolower($type)]$stdata))
  232.                 {
  233.                     $this->addStyleDeclaration($stdata$type);
  234.                 }
  235.             }
  236.         }
  237.  
  238.         $this->_scripts = (isset($data['scripts']&& !empty($data['scripts']&& is_array($data['scripts']))
  239.             ? array_merge($this->_scripts$data['scripts'])
  240.             : $this->_scripts;
  241.  
  242.         if (isset($data['script']))
  243.         {
  244.             foreach ($data['script'as $type => $sdata)
  245.             {
  246.                 if (!isset($this->_script[strtolower($type)]|| !stristr($this->_script[strtolower($type)]$sdata))
  247.                 {
  248.                     $this->addScriptDeclaration($sdata$type);
  249.                 }
  250.             }
  251.         }
  252.  
  253.         $this->_custom = (isset($data['custom']&& !empty($data['custom']&& is_array($data['custom']))
  254.             ? array_unique(array_merge($this->_custom$data['custom']))
  255.             : $this->_custom;
  256.  
  257.         return $this;
  258.     }
  259.  
  260.     /**
  261.      * Adds <link> tags to the head of the document
  262.      *
  263.      * $relType defaults to 'rel' as it is the most common relation type used.
  264.      * ('rev' refers to reverse relation, 'rel' indicates normal, forward relation.)
  265.      * Typical tag: <link href="index.php" rel="Start">
  266.      *
  267.      * @param   string  $href      The link that is being related.
  268.      * @param   string  $relation  Relation of link.
  269.      * @param   string  $relType   Relation type attribute.  Either rel or rev (default: 'rel').
  270.      * @param   array   $attribs   Associative array of remaining attributes.
  271.      *
  272.      * @return  JDocumentHTML instance of $this to allow chaining
  273.      *
  274.      * @since   11.1
  275.      */
  276.     public function addHeadLink($href$relation$relType 'rel'$attribs array())
  277.     {
  278.         $this->_links[$href]['relation'$relation;
  279.         $this->_links[$href]['relType'$relType;
  280.         $this->_links[$href]['attribs'$attribs;
  281.  
  282.         return $this;
  283.     }
  284.  
  285.     /**
  286.      * Adds a shortcut icon (favicon)
  287.      *
  288.      * This adds a link to the icon shown in the favorites list or on
  289.      * the left of the url in the address bar. Some browsers display
  290.      * it on the tab, as well.
  291.      *
  292.      * @param   string  $href      The link that is being related.
  293.      * @param   string  $type      File type
  294.      * @param   string  $relation  Relation of link
  295.      *
  296.      * @return  JDocumentHTML instance of $this to allow chaining
  297.      *
  298.      * @since   11.1
  299.      */
  300.     public function addFavicon($href$type 'image/vnd.microsoft.icon'$relation 'shortcut icon')
  301.     {
  302.         $href str_replace('\\''/'$href);
  303.         $this->addHeadLink($href$relation'rel'array('type' => $type));
  304.  
  305.         return $this;
  306.     }
  307.  
  308.     /**
  309.      * Adds a custom HTML string to the head block
  310.      *
  311.      * @param   string  $html  The HTML to add to the head
  312.      *
  313.      * @return  JDocumentHTML instance of $this to allow chaining
  314.      *
  315.      * @since   11.1
  316.      */
  317.     public function addCustomTag($html)
  318.     {
  319.         $this->_custom[trim($html);
  320.  
  321.         return $this;
  322.     }
  323.  
  324.     /**
  325.      * Returns whether the document is set up to be output as HTML5
  326.      *
  327.      * @return  Boolean true when HTML5 is used
  328.      *
  329.      * @since   12.1
  330.      */
  331.     public function isHtml5()
  332.     {
  333.         return $this->_html5;
  334.     }
  335.  
  336.     /**
  337.      * Sets whether the document should be output as HTML5
  338.      *
  339.      * @param   bool  $state  True when HTML5 should be output
  340.      *
  341.      * @return  void 
  342.      *
  343.      * @since   12.1
  344.      */
  345.     public function setHtml5($state)
  346.     {
  347.         if (is_bool($state))
  348.         {
  349.             $this->_html5 $state;
  350.         }
  351.     }
  352.  
  353.     /**
  354.      * Get the contents of a document include
  355.      *
  356.      * @param   string  $type     The type of renderer
  357.      * @param   string  $name     The name of the element to render
  358.      * @param   array   $attribs  Associative array of remaining attributes.
  359.      *
  360.      * @return  The output of the renderer
  361.      *
  362.      * @since   11.1
  363.      */
  364.     public function getBuffer($type null$name null$attribs array())
  365.     {
  366.         // If no type is specified, return the whole buffer
  367.         if ($type === null)
  368.         {
  369.             return parent::$_buffer;
  370.         }
  371.  
  372.         $title (isset($attribs['title'])) $attribs['title'null;
  373.         if (isset(parent::$_buffer[$type][$name][$title]))
  374.         {
  375.             return parent::$_buffer[$type][$name][$title];
  376.         }
  377.  
  378.         $renderer $this->loadRenderer($type);
  379.         if ($this->_caching == true && $type == 'modules')
  380.         {
  381.             $cache JFactory::getCache('com_modules''');
  382.             $hash md5(serialize(array($name$attribsnull$renderer)));
  383.             $cbuffer $cache->get('cbuffer_' $type);
  384.  
  385.             if (isset($cbuffer[$hash]))
  386.             {
  387.                 return JCache::getWorkarounds($cbuffer[$hash]array('mergehead' => 1));
  388.             }
  389.             else
  390.             {
  391.                 $options array();
  392.                 $options['nopathway'1;
  393.                 $options['nomodules'1;
  394.                 $options['modulemode'1;
  395.  
  396.                 $this->setBuffer($renderer->render($name$attribsnull)$type$name);
  397.                 $data parent::$_buffer[$type][$name][$title];
  398.  
  399.                 $tmpdata JCache::setWorkarounds($data$options);
  400.  
  401.                 $cbuffer[$hash$tmpdata;
  402.  
  403.                 $cache->store($cbuffer'cbuffer_' $type);
  404.             }
  405.         }
  406.         else
  407.         {
  408.             $this->setBuffer($renderer->render($name$attribsnull)$type$name$title);
  409.         }
  410.  
  411.         return parent::$_buffer[$type][$name][$title];
  412.     }
  413.  
  414.     /**
  415.      * Set the contents a document includes
  416.      *
  417.      * @param   string  $content  The content to be set in the buffer.
  418.      * @param   array   $options  Array of optional elements.
  419.      *
  420.      * @return  JDocumentHTML instance of $this to allow chaining
  421.      *
  422.      * @since   11.1
  423.      */
  424.     public function setBuffer($content$options array())
  425.     {
  426.         // The following code is just for backward compatibility.
  427.         if (func_num_args(&& !is_array($options))
  428.         {
  429.             $args func_get_args();
  430.             $options array();
  431.             $options['type'$args[1];
  432.             $options['name'(isset($args[2])) $args[2null;
  433.             $options['title'(isset($args[3])) $args[3null;
  434.         }
  435.  
  436.         parent::$_buffer[$options['type']][$options['name']][$options['title']] $content;
  437.  
  438.         return $this;
  439.     }
  440.  
  441.     /**
  442.      * Parses the template and populates the buffer
  443.      *
  444.      * @param   array  $params  Parameters for fetching the template
  445.      *
  446.      * @return  JDocumentHTML instance of $this to allow chaining
  447.      *
  448.      * @since   11.1
  449.      */
  450.     public function parse($params array())
  451.     {
  452.         return $this->_fetchTemplate($params)->_parseTemplate();
  453.     }
  454.  
  455.     /**
  456.      * Outputs the template to the browser.
  457.      *
  458.      * @param   boolean  $caching  If true, cache the output
  459.      * @param   array    $params   Associative array of attributes
  460.      *
  461.      * @return  The rendered data
  462.      *
  463.      * @since   11.1
  464.      */
  465.     public function render($caching false$params array())
  466.     {
  467.         $this->_caching = $caching;
  468.  
  469.         if (!empty($this->_template))
  470.         {
  471.             $data $this->_renderTemplate();
  472.         }
  473.         else
  474.         {
  475.             $this->parse($params);
  476.             $data $this->_renderTemplate();
  477.         }
  478.  
  479.         parent::render();
  480.         return $data;
  481.     }
  482.  
  483.     /**
  484.      * Count the modules based on the given condition
  485.      *
  486.      * @param   string  $condition  The condition to use
  487.      *
  488.      * @return  integer  Number of modules found
  489.      *
  490.      * @since   11.1
  491.      */
  492.     public function countModules($condition)
  493.     {
  494.         $operators '(\+|\-|\*|\/|==|\!=|\<\>|\<|\>|\<=|\>=|and|or|xor)';
  495.         $words preg_split('# ' $operators ' #'$conditionnullPREG_SPLIT_DELIM_CAPTURE);
  496.         for ($i 0$n count($words)$i $n$i += 2)
  497.         {
  498.             // Odd parts (modules)
  499.             $name strtolower($words[$i]);
  500.             $words[$i((isset(parent::$_buffer['modules'][$name])) && (parent::$_buffer['modules'][$name=== false))
  501.                 ? 0
  502.                 : count(JModuleHelper::getModules($name));
  503.         }
  504.  
  505.         $str 'return ' implode(' '$words';';
  506.  
  507.         return eval($str);
  508.     }
  509.  
  510.     /**
  511.      * Count the number of child menu items
  512.      *
  513.      * @return  integer  Number of child menu items
  514.      *
  515.      * @since   11.1
  516.      */
  517.     public function countMenuChildren()
  518.     {
  519.         static $children;
  520.  
  521.         if (!isset($children))
  522.         {
  523.             $db JFactory::getDbo();
  524.             $app JFactory::getApplication();
  525.             $menu $app->getMenu();
  526.             $active $menu->getActive();
  527.             if ($active)
  528.             {
  529.                 $query $db->getQuery(true)
  530.                     ->select('COUNT(*)')
  531.                     ->from('#__menu')
  532.                     ->where('parent_id = ' $active->id)
  533.                     ->where('published = 1');
  534.                 $db->setQuery($query);
  535.                 $children $db->loadResult();
  536.             }
  537.             else
  538.             {
  539.                 $children 0;
  540.             }
  541.         }
  542.  
  543.         return $children;
  544.     }
  545.  
  546.     /**
  547.      * Load a template file
  548.      *
  549.      * @param   string  $directory  The name of the template
  550.      * @param   string  $filename   The actual filename
  551.      *
  552.      * @return  string  The contents of the template
  553.      *
  554.      * @since   11.1
  555.      */
  556.     protected function _loadTemplate($directory$filename)
  557.     {
  558.         // @todo remove code: $component    = JApplicationHelper::getComponentName();
  559.  
  560.         $contents '';
  561.  
  562.         // Check to see if we have a valid template file
  563.         if (file_exists($directory '/' $filename))
  564.         {
  565.             // Store the file path
  566.             $this->_file = $directory '/' $filename;
  567.  
  568.             // Get the file content
  569.             ob_start();
  570.             require $directory '/' $filename;
  571.             $contents ob_get_contents();
  572.             ob_end_clean();
  573.         }
  574.  
  575.         // Try to find a favicon by checking the template and root folder
  576.         $path $directory '/';
  577.         $dirs array($pathJPATH_BASE '/');
  578.         foreach ($dirs as $dir)
  579.         {
  580.             $icon $dir 'favicon.ico';
  581.             if (file_exists($icon))
  582.             {
  583.                 $path str_replace(JPATH_BASE '/'''$dir);
  584.                 $path str_replace('\\''/'$path);
  585.                 $this->addFavicon(JUri::base(true'/' $path 'favicon.ico');
  586.                 break;
  587.             }
  588.         }
  589.  
  590.         return $contents;
  591.     }
  592.  
  593.     /**
  594.      * Fetch the template, and initialise the params
  595.      *
  596.      * @param   array  $params  Parameters to determine the template
  597.      *
  598.      * @return  JDocumentHTML instance of $this to allow chaining
  599.      *
  600.      * @since   11.1
  601.      */
  602.     protected function _fetchTemplate($params array())
  603.     {
  604.         // Check
  605.         $directory = isset($params['directory']$params['directory''templates';
  606.         $filter JFilterInput::getInstance();
  607.         $template $filter->clean($params['template']'cmd');
  608.         $file $filter->clean($params['file']'cmd');
  609.  
  610.         if (!file_exists($directory '/' $template '/' $file))
  611.         {
  612.             $template 'system';
  613.         }
  614.  
  615.         // Load the language file for the template
  616.         $lang JFactory::getLanguage();
  617.  
  618.         // 1.5 or core then 1.6
  619.         $lang->load('tpl_' $templateJPATH_BASEnullfalsetrue)
  620.             || $lang->load('tpl_' $template$directory '/' $templatenullfalsetrue);
  621.  
  622.         // Assign the variables
  623.         $this->template = $template;
  624.         $this->baseurl = JUri::base(true);
  625.         $this->params = isset($params['params']$params['params'new JRegistry;
  626.  
  627.         // Load
  628.         $this->_template = $this->_loadTemplate($directory '/' $template$file);
  629.  
  630.         return $this;
  631.     }
  632.  
  633.     /**
  634.      * Parse a document template
  635.      *
  636.      * @return  JDocumentHTML  instance of $this to allow chaining
  637.      *
  638.      * @since   11.1
  639.      */
  640.     protected function _parseTemplate()
  641.     {
  642.         $matches array();
  643.  
  644.         if (preg_match_all('#<jdoc:include\ type="([^"]+)"(.*)\/>#iU'$this->_template$matches))
  645.         {
  646.             $template_tags_first array();
  647.             $template_tags_last array();
  648.  
  649.             // Step through the jdocs in reverse order.
  650.             for ($i count($matches[0]1$i >= 0$i--)
  651.             {
  652.                 $type $matches[1][$i];
  653.                 $attribs empty($matches[2][$i]array(JUtility::parseAttributes($matches[2][$i]);
  654.                 $name = isset($attribs['name']$attribs['name'null;
  655.  
  656.                 // Separate buffers to be executed first and last
  657.                 if ($type == 'module' || $type == 'modules')
  658.                 {
  659.                     $template_tags_first[$matches[0][$i]] array('type' => $type'name' => $name'attribs' => $attribs);
  660.                 }
  661.                 else
  662.                 {
  663.                     $template_tags_last[$matches[0][$i]] array('type' => $type'name' => $name'attribs' => $attribs);
  664.                 }
  665.             }
  666.             // Reverse the last array so the jdocs are in forward order.
  667.             $template_tags_last array_reverse($template_tags_last);
  668.  
  669.             $this->_template_tags = $template_tags_first $template_tags_last;
  670.         }
  671.  
  672.         return $this;
  673.     }
  674.  
  675.     /**
  676.      * Render pre-parsed template
  677.      *
  678.      * @return string rendered template
  679.      *
  680.      * @since   11.1
  681.      */
  682.     protected function _renderTemplate()
  683.     {
  684.         $replace array();
  685.         $with array();
  686.  
  687.         foreach ($this->_template_tags as $jdoc => $args)
  688.         {
  689.             $replace[$jdoc;
  690.             $with[$this->getBuffer($args['type']$args['name']$args['attribs']);
  691.         }
  692.  
  693.         return str_replace($replace$with$this->_template);
  694.     }
  695. }

Documentation generated on Tue, 19 Nov 2013 15:04:54 +0100 by phpDocumentor 1.4.3