Source for file sef.php

Documentation is available at sef.php

  1. <?php
  2. /**
  3.  * @package     Joomla.Plugin
  4.  * @subpackage  System.sef
  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.txt
  8.  */
  9. defined('_JEXEC') or die;
  10.  
  11. /**
  12.  * Joomla! SEF Plugin
  13.  *
  14.  * @package     Joomla.Plugin
  15.  * @subpackage  System.sef
  16.  * @since       1.5
  17.  */
  18. class PlgSystemSef extends JPlugin
  19. {
  20.     /**
  21.      * Add the canonical uri to the head
  22.      *
  23.      * @return  void 
  24.      *
  25.      * @since   3.0
  26.      */
  27.     public function onAfterRoute()
  28.     {
  29.         $app = JFactory::getApplication();
  30.         $doc = JFactory::getDocument();
  31.  
  32.         if ($app->getName() != 'site' || $doc->getType() !== 'html')
  33.         {
  34.             return true;
  35.         }
  36.  
  37.         $router = $app->getRouter();
  38.  
  39.         $uri     = clone JUri::getInstance();
  40.         $domain  = $this->params->get('domain');
  41.  
  42.         if ($domain === null || $domain === '')
  43.         {
  44.             $domain = $uri->toString(array('scheme', 'host', 'port'));
  45.         }
  46.  
  47.         $parsed = $router->parse($uri);
  48.         $fakelink = 'index.php?' . http_build_query($parsed);
  49.         $link = $domain . JRoute::_($fakelink, false);
  50.  
  51.         if ($uri !== $link)
  52.         {
  53.             $doc->addHeadLink(htmlspecialchars($link), 'canonical');
  54.         }
  55.     }
  56.  
  57.     /**
  58.      * Converting the site URL to fit to the HTTP request
  59.      *
  60.      * @return  void 
  61.      */
  62.     public function onAfterRender()
  63.     {
  64.         $app = JFactory::getApplication();
  65.  
  66.         if ($app->getName() != 'site' || $app->getCfg('sef') == '0')
  67.         {
  68.             return true;
  69.         }
  70.  
  71.         // Replace src links
  72.         $base   = JUri::base(true).'/';
  73.         $buffer = $app->getBody();
  74.  
  75.         $regex  = '#href="index.php\?([^"]*)#m';
  76.         $buffer = preg_replace_callback($regex, array('PlgSystemSef', 'route'), $buffer);
  77.         $this->checkBuffer($buffer);
  78.  
  79.         $protocols = '[a-zA-Z0-9]+:'; //To check for all unknown protocals (a protocol must contain at least one alpahnumeric fillowed by :
  80.         $regex     = '#(src|href|poster)="(?!/|' . $protocols . '|\#|\')([^"]*)"#m';
  81.         $buffer    = preg_replace($regex, "$1=\"$base\$2\"", $buffer);
  82.         $this->checkBuffer($buffer);
  83.  
  84.         $regex  = '#(onclick="window.open\(\')(?!/|' . $protocols . '|\#)([^/]+[^\']*?\')#m';
  85.         $buffer = preg_replace($regex, '$1' . $base . '$2', $buffer);
  86.         $this->checkBuffer($buffer);
  87.  
  88.         // ONMOUSEOVER / ONMOUSEOUT
  89.         $regex  = '#(onmouseover|onmouseout)="this.src=([\']+)(?!/|' . $protocols . '|\#|\')([^"]+)"#m';
  90.         $buffer = preg_replace($regex, '$1="this.src=$2' . $base .'$3$4"', $buffer);
  91.         $this->checkBuffer($buffer);
  92.  
  93.         // Background image
  94.         $regex  = '#style\s*=\s*[\'\"](.*):\s*url\s*\([\'\"]?(?!/|' . $protocols . '|\#)([^\)\'\"]+)[\'\"]?\)#m';
  95.         $buffer = preg_replace($regex, 'style="$1: url(\'' . $base .'$2$3\')', $buffer);
  96.         $this->checkBuffer($buffer);
  97.  
  98.         // OBJECT <param name="xx", value="yy"> -- fix it only inside the <param> tag
  99.         $regex  = '#(<param\s+)name\s*=\s*"(movie|src|url)"[^>]\s*value\s*=\s*"(?!/|' . $protocols . '|\#|\')([^"]*)"#m';
  100.         $buffer = preg_replace($regex, '$1name="$2" value="' . $base . '$3"', $buffer);
  101.         $this->checkBuffer($buffer);
  102.  
  103.         // OBJECT <param value="xx", name="yy"> -- fix it only inside the <param> tag
  104.         $regex  = '#(<param\s+[^>]*)value\s*=\s*"(?!/|' . $protocols . '|\#|\')([^"]*)"\s*name\s*=\s*"(movie|src|url)"#m';
  105.         $buffer = preg_replace($regex, '<param value="' . $base .'$2" name="$3"', $buffer);
  106.         $this->checkBuffer($buffer);
  107.  
  108.         // OBJECT data="xx" attribute -- fix it only in the object tag
  109.         $regex  = '#(<object\s+[^>]*)data\s*=\s*"(?!/|' . $protocols . '|\#|\')([^"]*)"#m';
  110.         $buffer = preg_replace($regex, '$1data="' . $base . '$2"$3', $buffer);
  111.         $this->checkBuffer($buffer);
  112.  
  113.         $app->setBody($buffer);
  114.         return true;
  115.     }
  116.  
  117.     /**
  118.      * @param   string  $buffer 
  119.      *
  120.      * @return  void 
  121.      */
  122.     private function checkBuffer($buffer)
  123.     {
  124.         if ($buffer === null)
  125.         {
  126.             switch (preg_last_error())
  127.             {
  128.                 case PREG_BACKTRACK_LIMIT_ERROR:
  129.                     $message = "PHP regular expression limit reached (pcre.backtrack_limit)";
  130.                     break;
  131.                 case PREG_RECURSION_LIMIT_ERROR:
  132.                     $message = "PHP regular expression limit reached (pcre.recursion_limit)";
  133.                     break;
  134.                 case PREG_BAD_UTF8_ERROR:
  135.                     $message = "Bad UTF8 passed to PCRE function";
  136.                     break;
  137.                 default:
  138.                     $message = "Unknown PCRE error calling PCRE function";
  139.             }
  140.             throw new RuntimeException($message);
  141.         }
  142.     }
  143.  
  144.     /**
  145.      * Replaces the matched tags
  146.      *
  147.      * @param   array  &$matches  An array of matches (see preg_match_all)
  148.      *
  149.      * @return  string 
  150.      */
  151.     protected static function route(&$matches)
  152.     {
  153.         $url   = $matches[1];
  154.         $url   = str_replace('&amp;', '&', $url);
  155.         $route = JRoute::_('index.php?'.$url);
  156.  
  157.         return 'href="' . $route;
  158.     }
  159. }

Documentation generated on Tue, 19 Nov 2013 15:12:47 +0100 by phpDocumentor 1.4.3