/** * @package Joomla.Plugin * @subpackage System.sef * * @copyright Copyright (C) 2005 - 2014 Open Source Matters, Inc. All rights reserved. * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') or die; /** * Joomla! SEF Plugin. * * @package Joomla.Plugin * @subpackage System.sef * @since 1.5 */ class PlgSystemSef extends JPlugin { /** * Add the canonical uri to the head. * * @return void * * @since 3.0 */ public function onAfterRoute() { $app = JFactory::getApplication(); $doc = JFactory::getDocument(); if ($app->getName() != 'site' || $doc->getType() !== 'html') { return true; } $router = $app->getRouter(); $uri = clone JUri::getInstance(); $domain = $this->params->get('domain'); if ($domain === null || $domain === '') { $domain = $uri->toString(array('scheme', 'host', 'port')); } $parsed = $router->parse($uri); $fakelink = 'index.php?' . http_build_query($parsed); $link = $domain . JRoute::_($fakelink, false); if ($uri !== $link) { $doc->addHeadLink(htmlspecialchars($link), 'canonical'); } } /** * Convert the site URL to fit to the HTTP request. * * @return void */ public function onAfterRender() { $app = JFactory::getApplication(); if ($app->getName() != 'site' || $app->getCfg('sef') == '0') { return true; } // Replace src links. $base = JUri::base(true) . '/'; $buffer = $app->getBody(); $regex = '#href="index.php\?([^"]*)#m'; $buffer = preg_replace_callback($regex, array('PlgSystemSef', 'route'), $buffer); $this->checkBuffer($buffer); // Check for all unknown protocals (a protocol must contain at least one alpahnumeric character followed by a ":"). $protocols = '[a-zA-Z0-9]+:'; $regex = '#(src|href|poster)="(?!/|' . $protocols . '|\#|\')([^"]*)"#m'; $buffer = preg_replace($regex, "$1=\"$base\$2\"", $buffer); $this->checkBuffer($buffer); $regex = '#(onclick="window.open\(\')(?!/|' . $protocols . '|\#)([^/]+[^\']*?\')#m'; $buffer = preg_replace($regex, '$1' . $base . '$2', $buffer); $this->checkBuffer($buffer); // ONMOUSEOVER / ONMOUSEOUT $regex = '#(onmouseover|onmouseout)="this.src=([\']+)(?!/|' . $protocols . '|\#|\')([^"]+)"#m'; $buffer = preg_replace($regex, '$1="this.src=$2' . $base . '$3$4"', $buffer); $this->checkBuffer($buffer); // Background image. $regex = '#style\s*=\s*[\'\"](.*):\s*url\s*\([\'\"]?(?!/|' . $protocols . '|\#)([^\)\'\"]+)[\'\"]?\)#m'; $buffer = preg_replace($regex, 'style="$1: url(\'' . $base . '$2$3\')', $buffer); $this->checkBuffer($buffer); // OBJECT -- fix it only inside the tag. $regex = '#(]\s*value\s*=\s*"(?!/|' . $protocols . '|\#|\')([^"]*)"#m'; $buffer = preg_replace($regex, '$1name="$2" value="' . $base . '$3"', $buffer); $this->checkBuffer($buffer); // OBJECT -- fix it only inside the tag. $regex = '#(]*)value\s*=\s*"(?!/|' . $protocols . '|\#|\')([^"]*)"\s*name\s*=\s*"(movie|src|url)"#m'; $buffer = preg_replace($regex, 'checkBuffer($buffer); // OBJECT data="xx" attribute -- fix it only in the object tag. $regex = '#(]*)data\s*=\s*"(?!/|' . $protocols . '|\#|\')([^"]*)"#m'; $buffer = preg_replace($regex, '$1data="' . $base . '$2"$3', $buffer); $this->checkBuffer($buffer); $app->setBody($buffer); return true; } /** * Check the buffer. * * @param string $buffer Buffer to be checked. * * @return void */ private function checkBuffer($buffer) { if ($buffer === null) { switch (preg_last_error()) { case PREG_BACKTRACK_LIMIT_ERROR: $message = "PHP regular expression limit reached (pcre.backtrack_limit)"; break; case PREG_RECURSION_LIMIT_ERROR: $message = "PHP regular expression limit reached (pcre.recursion_limit)"; break; case PREG_BAD_UTF8_ERROR: $message = "Bad UTF8 passed to PCRE function"; break; default: $message = "Unknown PCRE error calling PCRE function"; } throw new RuntimeException($message); } } /** * Replace the matched tags. * * @param array &$matches An array of matches (see preg_match_all). * * @return string */ protected static function route(&$matches) { $url = $matches[1]; $url = str_replace('&', '&', $url); $route = JRoute::_('index.php?' . $url); return 'href="' . $route; } } /** * @package Joomla.Legacy * @subpackage Response * * @copyright Copyright (C) 2005 - 2014 Open Source Matters, Inc. All rights reserved. * @license GNU General Public License version 2 or later; see LICENSE */ defined('JPATH_PLATFORM') or die; JLog::add('JResponse is deprecated.', JLog::WARNING, 'deprecated'); /** * JResponse Class. * * This class serves to provide the Joomla Platform with a common interface to access * response variables. This includes header and body. * * @package Joomla.Legacy * @subpackage Response * @since 11.1 * @deprecated 4.0 Use JApplicationWeb instead */ class JResponse { /** * @var array Body * @since 11.1 * @deprecated 4.0 */ protected static $body = array(); /** * @var boolean Cachable * @since 11.1 * @deprecated 4.0 */ protected static $cachable = false; /** * @var array Headers * @since 11.1 * @deprecated 4.0 */ protected static $headers = array(); /** * Set/get cachable state for the response. * * If $allow is set, sets the cachable state of the response. Always returns current state. * * @param boolean $allow True to allow browser caching. * * @return boolean True if browser caching should be allowed * * @since 11.1 * @deprecated 4.0 Use JApplicationWeb::allowCache() instead */ public static function allowCache($allow = null) { return JFactory::getApplication()->allowCache($allow); } /** * Set a header. * * If $replace is true, replaces any headers already defined with that $name. * * @param string $name The name of the header to set. * @param string $value The value of the header to set. * @param boolean $replace True to replace any existing headers by name. * * @return void * * @since 11.1 * @deprecated 4.0 Use JApplicationWeb::setHeader() instead */ public static function setHeader($name, $value, $replace = false) { JFactory::getApplication()->setHeader($name, $value, $replace); } /** * Return array of headers. * * @return array * * @since 11.1 * @deprecated 4.0 Use JApplicationWeb::getHeaders() instead */ public static function getHeaders() { return JFactory::getApplication()->getHeaders(); } /** * Clear headers. * * @return void * * @since 11.1 * @deprecated 4.0 Use JApplicationWeb::clearHeaders() instead */ public static function clearHeaders() { JFactory::getApplication()->clearHeaders(); } /** * Send all headers. * * @return void * * @since 11.1 * @deprecated 4.0 Use JApplicationWeb::sendHeaders() instead */ public static function sendHeaders() { JFactory::getApplication()->sendHeaders(); } /** * Set body content. * * If body content already defined, this will replace it. * * @param string $content The content to set to the response body. * * @return void * * @since 11.1 * @deprecated 4.0 Use JApplicationWeb::setBody() instead */ public static function setBody($content) { JFactory::getApplication()->setBody($content); } /** * Prepend content to the body content * * @param string $content The content to prepend to the response body. * * @return void * * @since 11.1 * @deprecated 4.0 Use JApplicationWeb::prependBody() instead */ public static function prependBody($content) { JFactory::getApplication()->prependBody($content); } /** * Append content to the body content * * @param string $content The content to append to the response body. * * @return void * * @since 11.1 * @deprecated 4.0 Use JApplicationWeb::appendBody() instead */ public static function appendBody($content) { JFactory::getApplication()->appendBody($content); } /** * Return the body content * * @param boolean $toArray Whether or not to return the body content as an array of strings or as a single string; defaults to false. * * @return string array * * @since 11.1 * @deprecated 4.0 Use JApplicationWeb::getBody() instead */ public static function getBody($toArray = false) { return JFactory::getApplication()->getBody($toArray); } /** * Sends all headers prior to returning the string * * @param boolean $compress If true, compress the data * * @return string * * @since 11.1 * @deprecated 4.0 Use JApplicationCms::toString() instead */ public static function toString($compress = false) { return JFactory::getApplication()->toString($compress); } /** * Compress the data * * Checks the accept encoding of the browser and compresses the data before * sending it to the client. * * @param string $data Content to compress for output. * * @return string compressed data * * @note Replaces _compress method in 11.1 * @since 11.1 * @deprecated 4.0 Use JApplicationWeb::compress() instead */ protected static function compress($data) { $encoding = self::clientEncoding(); if (!$encoding) { return $data; } if (!extension_loaded('zlib') || ini_get('zlib.output_compression')) { return $data; } if (headers_sent()) { return $data; } if (connection_status() !== 0) { return $data; } // Ideal level $level = 4; /* $size = strlen($data); $crc = crc32($data); $gzdata = "\x1f\x8b\x08\x00\x00\x00\x00\x00"; $gzdata .= gzcompress($data, $level); $gzdata = substr($gzdata, 0, strlen($gzdata) - 4); $gzdata .= pack("V",$crc) . pack("V", $size); */ $gzdata = gzencode($data, $level); self::setHeader('Content-Encoding', $encoding); // Header will be removed at 4.0 if (JFactory::getConfig()->get('MetaVersion', 0) && defined('JVERSION')) { self::setHeader('X-Content-Encoded-By', 'Joomla! ' . JVERSION); } return $gzdata; } /** * Check, whether client supports compressed data * * @return boolean * * @since 11.1 * @note Replaces _clientEncoding method from 11.1 * @deprecated 4.0 Use JApplicationWebClient instead */ protected static function clientEncoding() { if (!isset($_SERVER['HTTP_ACCEPT_ENCODING'])) { return false; } $encoding = false; if (false !== strpos($_SERVER['HTTP_ACCEPT_ENCODING'], 'gzip')) { $encoding = 'gzip'; } if (false !== strpos($_SERVER['HTTP_ACCEPT_ENCODING'], 'x-gzip')) { $encoding = 'x-gzip'; } return $encoding; } }