PageRenderTime 147ms CodeModel.GetById 51ms app.highlight 35ms RepoModel.GetById 55ms app.codeStats 0ms

/libraries/joomla/document/html/html.php

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