芝麻web文件管理V1.00
编辑当前文件:/home2/sdektunc/www/libraries/src/Document/Document.php
* @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\CMS\Document; \defined('JPATH_PLATFORM') or die; use Joomla\Application\AbstractWebApplication; use Joomla\CMS\Date\Date; use Joomla\CMS\Factory as CmsFactory; use Joomla\CMS\WebAsset\WebAssetManager; use Symfony\Component\WebLink\HttpHeaderSerializer; /** * Document class, provides an easy interface to parse and display a document * * @since 1.7.0 */ class Document { /** * Document title * * @var string * @since 1.7.0 */ public $title = ''; /** * Document description * * @var string * @since 1.7.0 */ public $description = ''; /** * Document full URL * * @var string * @since 1.7.0 */ public $link = ''; /** * Document base URL * * @var string * @since 1.7.0 */ public $base = ''; /** * Contains the document language setting * * @var string * @since 1.7.0 */ public $language = 'en-gb'; /** * Contains the document direction setting * * @var string * @since 1.7.0 */ public $direction = 'ltr'; /** * Document generator * * @var string * @since 1.7.0 */ public $_generator = 'Joomla! - Open Source Content Management'; /** * Document modified date * * @var string|Date * @since 1.7.0 */ public $_mdate = ''; /** * Tab string * * @var string * @since 1.7.0 */ public $_tab = "\11"; /** * Contains the line end string * * @var string * @since 1.7.0 */ public $_lineEnd = "\12"; /** * Contains the character encoding string * * @var string * @since 1.7.0 */ public $_charset = 'utf-8'; /** * Document mime type * * @var string * @since 1.7.0 */ public $_mime = ''; /** * Document namespace * * @var string * @since 1.7.0 */ public $_namespace = ''; /** * Document profile * * @var string * @since 1.7.0 */ public $_profile = ''; /** * Array of linked scripts * * @var array * @since 1.7.0 * * @deprecated 5.0 Use WebAssetManager */ public $_scripts = array(); /** * Array of scripts placed in the header * * @var array * @since 1.7.0 * * @deprecated 5.0 Use WebAssetManager */ public $_script = array(); /** * Array of scripts options * * @var array */ protected $scriptOptions = array(); /** * Array of linked style sheets * * @var array * @since 1.7.0 * * @deprecated 5.0 Use WebAssetManager */ public $_styleSheets = array(); /** * Array of included style declarations * * @var array * @since 1.7.0 * * @deprecated 5.0 Use WebAssetManager */ public $_style = array(); /** * Array of meta tags * * @var array * @since 1.7.0 */ public $_metaTags = array(); /** * The rendering engine * * @var object * @since 1.7.0 */ public $_engine = null; /** * The document type * * @var string * @since 1.7.0 */ public $_type = null; /** * Array of buffered output * * @var mixed (depends on the renderer) * @since 1.7.0 */ public static $_buffer = null; /** * Document instances container. * * @var array * @since 1.7.3 */ protected static $instances = array(); /** * Media version added to assets * * @var string * @since 3.2 */ protected $mediaVersion = null; /** * Factory for creating JDocument API objects * * @var FactoryInterface * @since 4.0.0 */ protected $factory; /** * Preload manager * * @var PreloadManagerInterface * @since 4.0.0 */ protected $preloadManager = null; /** * The supported preload types * * @var array * @since 4.0.0 */ protected $preloadTypes = ['preload', 'dns-prefetch', 'preconnect', 'prefetch', 'prerender']; /** * Web Asset instance * * @var WebAssetManager * @since 4.0.0 */ protected $webAssetManager = null; /** * Class constructor. * * @param array $options Associative array of options * * @since 1.7.0 */ public function __construct($options = array()) { if (\array_key_exists('lineend', $options)) { $this->setLineEnd($options['lineend']); } if (\array_key_exists('charset', $options)) { $this->setCharset($options['charset']); } if (\array_key_exists('language', $options)) { $this->setLanguage($options['language']); } if (\array_key_exists('direction', $options)) { $this->setDirection($options['direction']); } if (\array_key_exists('tab', $options)) { $this->setTab($options['tab']); } if (\array_key_exists('link', $options)) { $this->setLink($options['link']); } if (\array_key_exists('base', $options)) { $this->setBase($options['base']); } if (\array_key_exists('mediaversion', $options)) { $this->setMediaVersion($options['mediaversion']); } if (\array_key_exists('factory', $options)) { $this->setFactory($options['factory']); } else { $this->setFactory(new Factory); } if (\array_key_exists('preloadManager', $options)) { $this->setPreloadManager($options['preloadManager']); } else { $this->setPreloadManager(new PreloadManager); } if (\array_key_exists('webAssetManager', $options)) { $this->setWebAssetManager($options['webAssetManager']); } else { $webAssetManager = new WebAssetManager(\Joomla\CMS\Factory::getContainer()->get('webassetregistry')); $this->setWebAssetManager($webAssetManager); } } /** * Returns the global Document object, only creating it * if it doesn't already exist. * * @param string $type The document type to instantiate * @param array $attributes Array of attributes * * @return static The document object. * * @since 1.7.0 * @deprecated 5.0 Use the \Joomla\CMS\Document\FactoryInterface instead */ public static function getInstance($type = 'html', $attributes = array()) { $signature = serialize(array($type, $attributes)); if (empty(self::$instances[$signature])) { self::$instances[$signature] = CmsFactory::getContainer()->get(FactoryInterface::class)->createDocument($type, $attributes); } return self::$instances[$signature]; } /** * Set the factory instance * * @param FactoryInterface $factory The factory instance * * @return Document * * @since 4.0.0 */ public function setFactory(FactoryInterface $factory): self { $this->factory = $factory; return $this; } /** * Set the document type * * @param string $type Type document is to set to * * @return Document instance of $this to allow chaining * * @since 1.7.0 */ public function setType($type) { $this->_type = $type; return $this; } /** * Returns the document type * * @return string * * @since 1.7.0 */ public function getType() { return $this->_type; } /** * Get the contents of the document buffer * * @return mixed * * @since 1.7.0 */ public function getBuffer() { return self::$_buffer; } /** * Set the contents of the document buffer * * @param string $content The content to be set in the buffer. * @param array $options Array of optional elements. * * @return Document instance of $this to allow chaining * * @since 1.7.0 */ public function setBuffer($content, $options = array()) { self::$_buffer = $content; return $this; } /** * Gets a meta tag. * * @param string $name Name of the meta HTML tag * @param string $attribute Attribute to use in the meta HTML tag * * @return string * * @since 1.7.0 */ public function getMetaData($name, $attribute = 'name') { // B/C old http_equiv parameter. if (!\is_string($attribute)) { $attribute = $attribute == true ? 'http-equiv' : 'name'; } if ($name === 'generator') { $result = $this->getGenerator(); } elseif ($name === 'description') { $result = $this->getDescription(); } else { $result = isset($this->_metaTags[$attribute]) && isset($this->_metaTags[$attribute][$name]) ? $this->_metaTags[$attribute][$name] : ''; } return $result; } /** * Sets or alters a meta tag. * * @param string $name Name of the meta HTML tag * @param mixed $content Value of the meta HTML tag as array or string * @param string $attribute Attribute to use in the meta HTML tag * * @return Document instance of $this to allow chaining * * @since 1.7.0 */ public function setMetaData($name, $content, $attribute = 'name') { // Pop the element off the end of array if target function expects a string or this http_equiv parameter. if (\is_array($content) && (\in_array($name, array('generator', 'description')) || !\is_string($attribute))) { $content = array_pop($content); } // B/C old http_equiv parameter. if (!\is_string($attribute)) { $attribute = $attribute == true ? 'http-equiv' : 'name'; } if ($name === 'generator') { $this->setGenerator($content); } elseif ($name === 'description') { $this->setDescription($content); } else { $this->_metaTags[$attribute][$name] = $content; } return $this; } /** * Adds a linked script to the page * * @param string $url URL to the linked script. * @param array $options Array of options. Example: array('version' => 'auto', 'conditional' => 'lt IE 9', 'preload' => array('preload')) * @param array $attribs Array of attributes. Example: array('id' => 'scriptid', 'async' => 'async', 'data-test' => 1) * * @return Document instance of $this to allow chaining * * @since 1.7.0 * * @deprecated 5.0 Use WebAssetManager */ public function addScript($url, $options = array(), $attribs = array()) { // Default value for type. if (!isset($attribs['type']) && !isset($attribs['mime'])) { $attribs['type'] = 'text/javascript'; } $this->_scripts[$url] = isset($this->_scripts[$url]) ? array_replace($this->_scripts[$url], $attribs) : $attribs; $this->_scripts[$url]['options'] = isset($this->_scripts[$url]['options']) ? array_replace($this->_scripts[$url]['options'], $options) : $options; return $this; } /** * Adds a script to the page * * @param string $content Script * @param string $type Scripting mime (defaults to 'text/javascript') * * @return Document instance of $this to allow chaining * * @since 1.7.0 * * @deprecated 5.0 Use WebAssetManager */ public function addScriptDeclaration($content, $type = 'text/javascript') { $type = strtolower($type); if (empty($this->_script[$type])) { $this->_script[$type] = array(); } $this->_script[$type][md5($content)] = $content; return $this; } /** * Add option for script * * @param string $key Name in Storage * @param mixed $options Scrip options as array or string * @param bool $merge Whether merge with existing (true) or replace (false) * * @return Document instance of $this to allow chaining * * @since 3.5 */ public function addScriptOptions($key, $options, $merge = true) { if (empty($this->scriptOptions[$key])) { $this->scriptOptions[$key] = array(); } if ($merge && \is_array($options)) { $this->scriptOptions[$key] = array_replace_recursive($this->scriptOptions[$key], $options); } else { $this->scriptOptions[$key] = $options; } return $this; } /** * Get script(s) options * * @param string $key Name in Storage * * @return array Options for given $key, or all script options * * @since 3.5 */ public function getScriptOptions($key = null) { if ($key) { return (empty($this->scriptOptions[$key])) ? array() : $this->scriptOptions[$key]; } else { return $this->scriptOptions; } } /** * Adds a linked stylesheet to the page * * @param string $url URL to the linked style sheet * @param array $options Array of options. Example: array('version' => 'auto', 'conditional' => 'lt IE 9', 'preload' => array('preload')) * @param array $attribs Array of attributes. Example: array('id' => 'stylesheet', 'data-test' => 1) * * @return Document instance of $this to allow chaining * * @since 1.7.0 * * @deprecated 5.0 Use WebAssetManager */ public function addStyleSheet($url, $options = array(), $attribs = array()) { // Default value for type. if (!isset($attribs['type']) && !isset($attribs['mime'])) { $attribs['type'] = 'text/css'; } $this->_styleSheets[$url] = isset($this->_styleSheets[$url]) ? array_replace($this->_styleSheets[$url], $attribs) : $attribs; if (isset($this->_styleSheets[$url]['options'])) { $this->_styleSheets[$url]['options'] = array_replace($this->_styleSheets[$url]['options'], $options); } else { $this->_styleSheets[$url]['options'] = $options; } return $this; } /** * Adds a stylesheet declaration to the page * * @param string $content Style declarations * @param string $type Type of stylesheet (defaults to 'text/css') * * @return Document instance of $this to allow chaining * * @since 1.7.0 * * @deprecated 5.0 Use WebAssetManager */ public function addStyleDeclaration($content, $type = 'text/css') { $type = strtolower($type); if (empty($this->_style[$type])) { $this->_style[$type] = array(); } $this->_style[$type][md5($content)] = $content; return $this; } /** * Sets the document charset * * @param string $type Charset encoding string * * @return Document instance of $this to allow chaining * * @since 1.7.0 */ public function setCharset($type = 'utf-8') { $this->_charset = $type; return $this; } /** * Returns the document charset encoding. * * @return string * * @since 1.7.0 */ public function getCharset() { return $this->_charset; } /** * Sets the global document language declaration. Default is English (en-gb). * * @param string $lang The language to be set * * @return Document instance of $this to allow chaining * * @since 1.7.0 */ public function setLanguage($lang = 'en-gb') { $this->language = strtolower($lang); return $this; } /** * Returns the document language. * * @return string * * @since 1.7.0 */ public function getLanguage() { return $this->language; } /** * Sets the global document direction declaration. Default is left-to-right (ltr). * * @param string $dir The language direction to be set * * @return Document instance of $this to allow chaining * * @since 1.7.0 */ public function setDirection($dir = 'ltr') { $this->direction = strtolower($dir); return $this; } /** * Returns the document direction declaration. * * @return string * * @since 1.7.0 */ public function getDirection() { return $this->direction; } /** * Sets the title of the document * * @param string $title The title to be set * * @return Document instance of $this to allow chaining * * @since 1.7.0 */ public function setTitle($title) { $this->title = $title; return $this; } /** * Return the title of the document. * * @return string * * @since 1.7.0 */ public function getTitle() { return $this->title; } /** * Set the assets version * * @param string $mediaVersion Media version to use * * @return Document instance of $this to allow chaining * * @since 3.2 */ public function setMediaVersion($mediaVersion) { $this->mediaVersion = strtolower($mediaVersion); return $this; } /** * Return the media version * * @return string * * @since 3.2 */ public function getMediaVersion() { return $this->mediaVersion; } /** * Set the preload manager * * @param PreloadManagerInterface $preloadManager The preload manager service * * @return Document instance of $this to allow chaining * * @since 4.0.0 */ public function setPreloadManager(PreloadManagerInterface $preloadManager): self { $this->preloadManager = $preloadManager; return $this; } /** * Return the preload manager * * @return PreloadManagerInterface * * @since 4.0.0 */ public function getPreloadManager(): PreloadManagerInterface { return $this->preloadManager; } /** * Set WebAsset manager * * @param WebAssetManager $webAsset The WebAsset instance * * @return Document * * @since 4.0.0 */ public function setWebAssetManager(WebAssetManager $webAsset): self { $this->webAssetManager = $webAsset; return $this; } /** * Return WebAsset manager * * @return WebAssetManager * * @since 4.0.0 */ public function getWebAssetManager(): WebAssetManager { return $this->webAssetManager; } /** * Sets the base URI of the document * * @param string $base The base URI to be set * * @return Document instance of $this to allow chaining * * @since 1.7.0 */ public function setBase($base) { $this->base = $base; return $this; } /** * Return the base URI of the document. * * @return string * * @since 1.7.0 */ public function getBase() { return $this->base; } /** * Sets the description of the document * * @param string $description The description to set * * @return Document instance of $this to allow chaining * * @since 1.7.0 */ public function setDescription($description) { $this->description = $description; return $this; } /** * Return the description of the document. * * @return string * * @since 1.7.0 */ public function getDescription() { return $this->description; } /** * Sets the document link * * @param string $url A url * * @return Document instance of $this to allow chaining * * @since 1.7.0 */ public function setLink($url) { $this->link = $url; return $this; } /** * Returns the document base url * * @return string * * @since 1.7.0 */ public function getLink() { return $this->link; } /** * Sets the document generator * * @param string $generator The generator to be set * * @return Document instance of $this to allow chaining * * @since 1.7.0 */ public function setGenerator($generator) { $this->_generator = $generator; return $this; } /** * Returns the document generator * * @return string * * @since 1.7.0 */ public function getGenerator() { return $this->_generator; } /** * Sets the document modified date * * @param string|Date $date The date to be set * * @return Document instance of $this to allow chaining * * @since 1.7.0 * @throws \InvalidArgumentException */ public function setModifiedDate($date) { if (!\is_string($date) && !($date instanceof Date)) { throw new \InvalidArgumentException( sprintf( 'The $date parameter of %1$s must be a string or a %2$s instance, a %3$s was given.', __METHOD__ . '()', 'Joomla\\CMS\\Date\\Date', \gettype($date) === 'object' ? (\get_class($date) . ' instance') : \gettype($date) ) ); } $this->_mdate = $date; return $this; } /** * Returns the document modified date * * @return string|Date * * @since 1.7.0 */ public function getModifiedDate() { return $this->_mdate; } /** * Sets the document MIME encoding that is sent to the browser. * * This usually will be text/html because most browsers cannot yet * accept the proper mime settings for XHTML: application/xhtml+xml * and to a lesser extent application/xml and text/xml. See the W3C note * ({@link https://www.w3.org/TR/xhtml-media-types/ * https://www.w3.org/TR/xhtml-media-types/}) for more details. * * @param string $type The document type to be sent * @param boolean $sync Should the type be synced with HTML? * * @return Document instance of $this to allow chaining * * @since 1.7.0 * * @link https://www.w3.org/TR/xhtml-media-types/ */ public function setMimeEncoding($type = 'text/html', $sync = true) { $this->_mime = strtolower($type); // Syncing with metadata if ($sync) { $this->setMetaData('content-type', $type . '; charset=' . $this->_charset, true); } return $this; } /** * Return the document MIME encoding that is sent to the browser. * * @return string * * @since 1.7.0 */ public function getMimeEncoding() { return $this->_mime; } /** * Sets the line end style to Windows, Mac, Unix or a custom string. * * @param string $style "win", "mac", "unix" or custom string. * * @return Document instance of $this to allow chaining * * @since 1.7.0 */ public function setLineEnd($style) { switch ($style) { case 'win': $this->_lineEnd = "\15\12"; break; case 'unix': $this->_lineEnd = "\12"; break; case 'mac': $this->_lineEnd = "\15"; break; default: $this->_lineEnd = $style; } return $this; } /** * Returns the lineEnd * * @return string * * @since 1.7.0 */ public function _getLineEnd() { return $this->_lineEnd; } /** * Sets the string used to indent HTML * * @param string $string String used to indent ("\11", "\t", ' ', etc.). * * @return Document instance of $this to allow chaining * * @since 1.7.0 */ public function setTab($string) { $this->_tab = $string; return $this; } /** * Returns a string containing the unit for indenting HTML * * @return string * * @since 1.7.0 */ public function _getTab() { return $this->_tab; } /** * Load a renderer * * @param string $type The renderer type * * @return RendererInterface * * @since 1.7.0 * @throws \RuntimeException */ public function loadRenderer($type) { return $this->factory->createRenderer($this, $type); } /** * Parses the document and prepares the buffers * * @param array $params The array of parameters * * @return Document instance of $this to allow chaining * * @since 1.7.0 */ public function parse($params = array()) { return $this; } /** * Outputs the document * * @param boolean $cache If true, cache the output * @param array $params Associative array of attributes * * @return string The rendered data * * @since 1.7.0 */ public function render($cache = false, $params = array()) { $app = CmsFactory::getApplication(); if ($mdate = $this->getModifiedDate()) { if (!($mdate instanceof Date)) { $mdate = new Date($mdate); } $app->modifiedDate = $mdate; } $app->mimeType = $this->_mime; $app->charSet = $this->_charset; // Handle preloading for configured assets in web applications if ($app instanceof AbstractWebApplication) { $this->preloadAssets(); } return ''; } /** * Generate the Link header for assets configured for preloading * * @return void * * @since 4.0.0 */ protected function preloadAssets() { // Process stylesheets first foreach ($this->_styleSheets as $link => $properties) { if (empty($properties['options']['preload'])) { continue; } foreach ($properties['options']['preload'] as $preloadMethod) { // Make sure the preload method is supported, special case for `dns-prefetch` to convert it to the right method name if ($preloadMethod === 'dns-prefetch') { $this->getPreloadManager()->dnsPrefetch($link); } elseif (\in_array($preloadMethod, $this->preloadTypes)) { $this->getPreloadManager()->$preloadMethod($link); } else { throw new \InvalidArgumentException(sprintf('The "%s" method is not supported for preloading.', $preloadMethod), 500); } } } // Now process scripts foreach ($this->_scripts as $link => $properties) { if (empty($properties['options']['preload'])) { continue; } foreach ($properties['options']['preload'] as $preloadMethod) { // Make sure the preload method is supported, special case for `dns-prefetch` to convert it to the right method name if ($preloadMethod === 'dns-prefetch') { $this->getPreloadManager()->dnsPrefetch($link); } elseif (\in_array($preloadMethod, $this->preloadTypes)) { $this->getPreloadManager()->$preloadMethod($link); } else { throw new \InvalidArgumentException(sprintf('The "%s" method is not supported for preloading.', $preloadMethod), 500); } } } // Check if the manager's provider has links, if so add the Link header if ($links = $this->getPreloadManager()->getLinkProvider()->getLinks()) { CmsFactory::getApplication()->setHeader('Link', (new HttpHeaderSerializer)->serialize($links)); } } }