aliroSEF.php

Go to the documentation of this file.
00001 <?php
00002 
00003 /*******************************************************************************
00004  * Aliro - the modern, accessible content management system
00005  *
00006  * Aliro is open source software, free to use, and licensed under GPL.
00007  * You can find the full licence at http://www.gnu.org/copyleft/gpl.html GNU/GPL
00008  *
00009  * The author freely draws attention to the fact that Aliro derives from Mambo,
00010  * software that is controlled by the Mambo Foundation.  However, this section
00011  * of code is totally new.  If it should contain any fragments that are similar
00012  * to Mambo, please bear in mind (1) there are only so many ways to do things
00013  * and (2) the author of Aliro is also the author and copyright owner for large
00014  * parts of Mambo 4.6.
00015  *
00016  * Tribute should be paid to all the developers who took Mambo to the stage
00017  * it had reached at the time Aliro was created.  It is a feature rich system
00018  * that contains a good deal of innovation.
00019  *
00020  * Your attention is also drawn to the fact that Aliro relies on other items of
00021  * open source software, which is very much in the spirit of open source.  Aliro
00022  * wishes to give credit to those items of code.  Please refer to
00023  * http://aliro.org/credits for details.  The credits are not included within
00024  * the Aliro package simply to avoid providing a marker that allows hackers to
00025  * identify the system.
00026  *
00027  * Copyright in this code is strictly reserved by its author, Martin Brampton.
00028  * If it seems appropriate, the copyright will be vested in the Aliro Organisation
00029  * at a suitable time.
00030  *
00031  * Copyright (c) 2007 Martin Brampton
00032  *
00033  * http://aliro.org
00034  *
00035  * counterpoint@aliro.org
00036  *
00037  * aliroSEF provides advanced SEF functions where sef_ext.php files are installed.
00038  * When SEF is turned off, aliroSEF still operates to achieve two things.  It will
00039  * redirect any SEF URLs that it recognises back to the non-SEF equivalents, with
00040  * a 301 redirect.  It also ensures that all URLs have ampersands correctly encoded.
00041  *
00042  * When SEF is turned on, but no sef_ext.php files are present, aliroSEF behaves
00043  * pretty much like the standard SEF functionality of Mambo 4.x or Joomla! 1.0.x.
00044  *
00045  * If components are activated through the admin interface and sef_ext.php files
00046  * are present, more advanced SEF processing takes place.  There are Aliro standard
00047  * sef_ext.php files for some common components, including the retro-content
00048  * component.
00049  *
00050  */
00051 
00052 class aliroUnAccent {
00053 
00054     // private vars
00055     private static $instance = null;
00056     private $tranmap = array();
00057 
00058     // private function
00059     private function aliroUnaccent () {
00060 
00061     $this->tranmap = array(
00062       "\xC3\x80" => "A",   "\xC3\x81" => "A",   "\xC3\x82" => "A",   "\xC3\x83" => "A",
00063       "\xC3\x84" => "A",   "\xC3\x85" => "A",   "\xC3\x86" => "AE",  "\xC3\x87" => "C",
00064       "\xC3\x88" => "E",   "\xC3\x89" => "E",   "\xC3\x8A" => "E",   "\xC3\x8B" => "E",
00065       "\xC3\x8C" => "I",   "\xC3\x8D" => "I",   "\xC3\x8E" => "I",   "\xC3\x8F" => "I",
00066       "\xC3\x90" => "D",   "\xC3\x91" => "N",   "\xC3\x92" => "O",   "\xC3\x93" => "O",
00067       "\xC3\x94" => "O",   "\xC3\x95" => "O",   "\xC3\x96" => "O",   "\xC3\x98" => "O",
00068       "\xC3\x99" => "U",   "\xC3\x9A" => "U",   "\xC3\x9B" => "U",   "\xC3\x9C" => "U",
00069       "\xC3\x9D" => "Y",   "\xC3\x9E" => "P",   "\xC3\x9F" => "ss",
00070       "\xC3\xA0" => "a",   "\xC3\xA1" => "a",   "\xC3\xA2" => "a",   "\xC3\xA3" => "a",
00071       "\xC3\xA4" => "a",   "\xC3\xA5" => "a",   "\xC3\xA6" => "ae",  "\xC3\xA7" => "c",
00072       "\xC3\xA8" => "e",   "\xC3\xA9" => "e",   "\xC3\xAA" => "e",   "\xC3\xAB" => "e",
00073       "\xC3\xAC" => "i",   "\xC3\xAD" => "i",   "\xC3\xAE" => "i",   "\xC3\xAF" => "i",
00074       "\xC3\xB0" => "o",   "\xC3\xB1" => "n",   "\xC3\xB2" => "o",   "\xC3\xB3" => "o",
00075       "\xC3\xB4" => "o",   "\xC3\xB5" => "o",   "\xC3\xB6" => "o",   "\xC3\xB8" => "o",
00076       "\xC3\xB9" => "u",   "\xC3\xBA" => "u",   "\xC3\xBB" => "u",   "\xC3\xBC" => "u",
00077       "\xC3\xBD" => "y",   "\xC3\xBE" => "p",   "\xC3\xBF" => "y",
00078       "\xC4\x80" => "A",   "\xC4\x81" => "a",   "\xC4\x82" => "A",   "\xC4\x83" => "a",
00079       "\xC4\x84" => "A",   "\xC4\x85" => "a",   "\xC4\x86" => "C",   "\xC4\x87" => "c",
00080       "\xC4\x88" => "C",   "\xC4\x89" => "c",   "\xC4\x8A" => "C",   "\xC4\x8B" => "c",
00081       "\xC4\x8C" => "C",   "\xC4\x8D" => "c",   "\xC4\x8E" => "D",   "\xC4\x8F" => "d",
00082       "\xC4\x90" => "D",   "\xC4\x91" => "d",   "\xC4\x92" => "E",   "\xC4\x93" => "e",
00083       "\xC4\x94" => "E",   "\xC4\x95" => "e",   "\xC4\x96" => "E",   "\xC4\x97" => "e",
00084       "\xC4\x98" => "E",   "\xC4\x99" => "e",   "\xC4\x9A" => "E",   "\xC4\x9B" => "e",
00085       "\xC4\x9C" => "G",   "\xC4\x9D" => "g",   "\xC4\x9E" => "G",   "\xC4\x9F" => "g",
00086       "\xC4\xA0" => "G",   "\xC4\xA1" => "g",   "\xC4\xA2" => "G",   "\xC4\xA3" => "g",
00087       "\xC4\xA4" => "H",   "\xC4\xA5" => "h",   "\xC4\xA6" => "H",   "\xC4\xA7" => "h",
00088       "\xC4\xA8" => "I",   "\xC4\xA9" => "i",   "\xC4\xAA" => "I",   "\xC4\xAB" => "i",
00089       "\xC4\xAC" => "I",   "\xC4\xAD" => "i",   "\xC4\xAE" => "I",   "\xC4\xAF" => "i",
00090       "\xC4\xB0" => "I",   "\xC4\xB1" => "i",   "\xC4\xB2" => "IJ",  "\xC4\xB3" => "ij",
00091       "\xC4\xB4" => "J",   "\xC4\xB5" => "j",   "\xC4\xB6" => "K",   "\xC4\xB7" => "k",
00092       "\xC4\xB8" => "k",   "\xC4\xB9" => "L",   "\xC4\xBA" => "l",   "\xC4\xBB" => "L",
00093       "\xC4\xBC" => "l",   "\xC4\xBD" => "L",   "\xC4\xBE" => "l",   "\xC4\xBF" => "L",
00094       "\xC5\x80" => "l",   "\xC5\x81" => "L",   "\xC5\x82" => "l",   "\xC5\x83" => "N",
00095       "\xC5\x84" => "n",   "\xC5\x85" => "N",   "\xC5\x86" => "n",   "\xC5\x87" => "N",
00096       "\xC5\x88" => "n",   "\xC5\x89" => "n",   "\xC5\x8A" => "N",   "\xC5\x8B" => "n",
00097       "\xC5\x8C" => "O",   "\xC5\x8D" => "o",   "\xC5\x8E" => "O",   "\xC5\x8F" => "o",
00098       "\xC5\x90" => "O",   "\xC5\x91" => "o",   "\xC5\x92" => "CE",  "\xC5\x93" => "ce",
00099       "\xC5\x94" => "R",   "\xC5\x95" => "r",   "\xC5\x96" => "R",   "\xC5\x97" => "r",
00100       "\xC5\x98" => "R",   "\xC5\x99" => "r",   "\xC5\x9A" => "S",   "\xC5\x9B" => "s",
00101       "\xC5\x9C" => "S",   "\xC5\x9D" => "s",   "\xC5\x9E" => "S",   "\xC5\x9F" => "s",
00102       "\xC5\xA0" => "S",   "\xC5\xA1" => "s",   "\xC5\xA2" => "T",   "\xC5\xA3" => "t",
00103       "\xC5\xA4" => "T",   "\xC5\xA5" => "t",   "\xC5\xA6" => "T",   "\xC5\xA7" => "t",
00104       "\xC5\xA8" => "U",   "\xC5\xA9" => "u",   "\xC5\xAA" => "U",   "\xC5\xAB" => "u",
00105       "\xC5\xAC" => "U",   "\xC5\xAD" => "u",   "\xC5\xAE" => "U",   "\xC5\xAF" => "u",
00106       "\xC5\xB0" => "U",   "\xC5\xB1" => "u",   "\xC5\xB2" => "U",   "\xC5\xB3" => "u",
00107       "\xC5\xB4" => "W",   "\xC5\xB5" => "w",   "\xC5\xB6" => "Y",   "\xC5\xB7" => "y",
00108       "\xC5\xB8" => "Y",   "\xC5\xB9" => "Z",   "\xC5\xBA" => "z",   "\xC5\xBB" => "Z",
00109       "\xC5\xBC" => "z",   "\xC5\xBD" => "Z",   "\xC5\xBE" => "z",   "\xC6\x8F" => "E",
00110       "\xC6\xA0" => "O",   "\xC6\xA1" => "o",   "\xC6\xAF" => "U",   "\xC6\xB0" => "u",
00111       "\xC7\x8D" => "A",   "\xC7\x8E" => "a",   "\xC7\x8F" => "I",
00112       "\xC7\x90" => "i",   "\xC7\x91" => "O",   "\xC7\x92" => "o",   "\xC7\x93" => "U",
00113       "\xC7\x94" => "u",   "\xC7\x95" => "U",   "\xC7\x96" => "u",   "\xC7\x97" => "U",
00114       "\xC7\x98" => "u",   "\xC7\x99" => "U",   "\xC7\x9A" => "u",   "\xC7\x9B" => "U",
00115       "\xC7\x9C" => "u",
00116       "\xC7\xBA" => "A",   "\xC7\xBB" => "a",   "\xC7\xBC" => "AE",  "\xC7\xBD" => "ae",
00117       "\xC7\xBE" => "O",   "\xC7\xBF" => "o",
00118       "\xC9\x99" => "e",
00119 
00120       "\xC2\x82" => ",",        // High code comma
00121       "\xC2\x84" => ",,",       // High code double comma
00122       "\xC2\x85" => "...",      // Tripple dot
00123       "\xC2\x88" => "^",        // High carat
00124       "\xC2\x91" => "\x27",     // Forward single quote
00125       "\xC2\x92" => "\x27",     // Reverse single quote
00126       "\xC2\x93" => "\x22",     // Forward double quote
00127       "\xC2\x94" => "\x22",     // Reverse double quote
00128       "\xC2\x96" => "-",        // High hyphen
00129       "\xC2\x97" => "--",       // Double hyphen
00130       "\xC2\xA6" => "|",        // Split vertical bar
00131       "\xC2\xAB" => "<<",       // Double less than
00132       "\xC2\xBB" => ">>",       // Double greater than
00133       "\xC2\xBC" => "1/4",      // one quarter
00134       "\xC2\xBD" => "1/2",      // one half
00135       "\xC2\xBE" => "3/4",      // three quarters
00136 
00137       "\xCA\xBF" => "\x27",     // c-single quote
00138       "\xCC\xA8" => "",         // modifier - under curve
00139       "\xCC\xB1" => ""          // modifier - under line
00140     );
00141 
00142     }
00143 
00144     public static function getInstance () {
00145         return self::$instance ? self::$instance : (self::$instance = new self());
00146     }
00147 
00148     public function unaccent ($utf8string) {
00149         return strtr($utf8string, $this->tranmap);
00150     }
00151 
00152 }
00153 
00154 class aliroSEF extends aliroFriendlyBase {
00155     protected static $instance = __CLASS__;
00156 
00157     // The following are private
00158     private $live_site = '';
00159     private $home_page = false;
00160     private $mainmenu = array();
00161     private $config = null;
00162     
00163 /* These should have been incorporate into $this->config    
00164     private $underscore = 0;
00165     private $enabled = 1;
00166     private $strip_chars = '';
00167     private $lower_case = '0';
00168     private $unique_id = '0';
00169     private $cache_time = '600';
00170     private $buffer_size = '500';
00171     private $home_title = 'Home';
00172     private $title_separator = '|';
00173     private $default_robots = 'index, follow';
00174     private $custom_code = array();
00175     private $custom_name = array();
00176     private $custom_PHP = array();
00177     private $custom_short = array();
00178     private $sef_content_task = array();
00179     private $sef_name_chars = array();
00180     private $sef_translate_chars = array();
00181     private $component_details = array();
00182     private $sef_substitutions_exact = array();
00183     private $sef_substitutions_in = array();
00184     private $sef_substitutions_out = array();
00185     private $legal_content_tasks = array();
00186 */
00187     
00188     private $sef_name_string = '';
00189     private $sef_translate_string = '';
00190     private $content_tasks = array (
00191         'findkey',
00192         'view',
00193         'section',
00194         'category',
00195         'blogsection',
00196         'blogcategorymulti',
00197         'blogcategory',
00198         'archivesection',
00199         'archivecategory',
00200         'save',
00201         'cancel',
00202         'emailform',
00203         'emailsend',
00204         'vote',
00205         'showblogsection'
00206         );
00207     private $content_menus = array();
00208     private $metadata = null;
00209 
00210     // The following are public
00211     public $content_data = null;
00212     public $content_items = array();
00213     public $content_sections = array();
00214     public $content_categories = array();
00215 
00216     // The following are private
00217     private $SEF_SPACE;
00218     private $cache = null;
00219     private $cached = array();
00220     private $cacheWritten = array();
00221     private $cacheObject = null;
00222     
00223     private $database = null;
00224 
00225     private function __construct () {
00226         $this->database = aliroDatabase::getInstance();
00227         $this->live_site = $this->getCfg('live_site');
00228 
00229         /*******************************************************************************
00230         **  The following are parameters for the ReMOSef Search Engine
00231         **  Optimisation component.  $this->SEF_SPACE should be set to the
00232         **  character that is to replace blanks in names that form the URL.
00233         **  You can privatey this, although the only sensible choices seem to be
00234         **  underscore or hyphen (_ or -).
00235         **
00236         **  The arrays $this->config->custom_code and $this->config->custom_name must be kept exactly
00237         **  in step with each other.  $this->custom_code is a list of the components
00238         **  that are to be handled by ReMOSef.
00239         **
00240         **  The array $this->config->custom_name is the alternative name that will be used
00241         **  in the optimised URL to identify the component and can be whatever
00242         **  you please so long as it is unique and legal for a URL.  Apart from
00243         **  using the custom name for the component, ReMOSef will do no further
00244         **  translation of the URL than is done by the standard Mambo SEF - UNLESS
00245         **  there is a sef_ext.php file installed for that component.  The
00246         **  exception to this is ReMOSitory - the optimisation code for Remository
00247         **  is integrated in ReMOSef.  For other components, if a sef_ext.php is
00248         **  present, it will be invoked by ReMOSef.
00249         **
00250         **  The array $remosef_content_task is capable of translating the tasks
00251         **  understood by the Mambo content component.  Please DO NOT CHANGE what
00252         **  is to the left of the equals sign.  When putting different values on
00253         **  the right hand side, remember that they must all be different, and must
00254         **  also be different from any of the custom names used for components.
00255         **  Without that, Remosef cannot figure out what a SEF URL means and will
00256         **  give unpredictable results.
00257         **
00258         **  Note that the names in custom_name must not be allowed to clash with
00259         **  the names used as tasks by the content component, in their
00260         **  translated form - see below.
00261         *******************************************************************************/
00262         // Use of underscore is NOT recommended, as search engines then do not see the words
00263         global $_SEF_SPACE;                                 // divide words with hyphens
00264         $this->SEF_SPACE = $_SEF_SPACE = "-";               // divide words with hyphens
00265         /*******************************************************************************
00266         **  The following are the parameters for the optional content specific
00267         **  URL optimisation.  They are not used within the standard SEF processing
00268         **  unless you add in a sef_ext.php that is integrated with the Mambo SEF.
00269         **
00270         **  The following two lines define the translations that SEF will perform on
00271         **  names of sections and categories when translating them for inclusion in a URL.
00272         **  Each item in $this->config->sef_name_chars is translated into the corresponding
00273         **  element of $this->config->sef_translate_chars.
00274         **
00275         **  NOTE it is important that space be the last translate character, since the
00276         **  characters are processed in the order in which they appear.  Since earlier
00277         **  translates may create new spaces, it is vital that the space translation is
00278         **  done last.
00279         **
00280         **  You can extend these arrays as you wish, although it is obviously important
00281         **  to make sure that the items of one match the items of the other exactly.
00282         *******************************************************************************/
00283         $this->sef_name_string = '"\'';
00284         $this->sef_translate_string = '--';
00285 
00286         $this->cache =new aliroCache('aliroSEF');
00287         $this->config = $this->cache->get('sefConfig');
00288         if (!$this->config) {
00289             $helper = new aliroSEFHelper();
00290             $this->config = $helper->getConfig($this->SEF_SPACE, $this->content_tasks);
00291             $this->cache->save($this->config);
00292         }
00293 
00294         $this->mainmenu = aliroMenuHandler::getInstance()->getByParentOrder('mainmenu');
00295         if ($this->mainmenu) foreach ($this->mainmenu as $menu) {
00296             $stage2 = parse_url($menu->link);
00297             if (isset($stage2['query'])) {
00298                 parse_str($stage2['query'], $parms);
00299                 if (isset($parms['option']) AND 'com_content' == $parms['option']) {
00300                     if (isset($parms['task'])) $this->content_menus[$parms['task']][$menu->id] = $parms;
00301                 }
00302             }
00303         }
00304 
00305         $this->cached = $this->cache->get('sefDataURI');
00306         if (!$this->cached) {
00307             $this->cached['SEF'] = $this->cached['Time'] = array();
00308             $results = $this->database->doSQLget("SELECT * FROM #__remosef_uri ORDER BY refreshed DESC LIMIT {$this->config->buffer_size}");
00309             foreach ($results as $result) {
00310                 $uri = $result->uri;
00311                 $this->cached['SEF'][$uri] = $result->sef;
00312                 $this->cached['Time'][$uri] = $result->refreshed;
00313             }
00314             unset($results);
00315             $this->cache->save($this->cached);
00316         }
00317     }
00318 
00319     public static function getInstance () {
00320         return is_object(self::$instance) ? self::$instance : (self::$instance = new self::$instance());
00321     }
00322     
00323     public function clearCache () {
00324         $this->cache->clean();
00325     }
00326 
00327     public function getContentMenuInfo () {
00328         return $this->content_menus;
00329     }
00330 
00331     public function nameForURL ($string) {
00332         $strips = explode ('|', $this->config->strip_chars);
00333         $string = str_replace($strips, '', (string) $string);
00334         $string = aliroUnaccent::getInstance()->unaccent($string);
00335         $string = str_replace($this->config->sef_name_chars, $this->config->sef_translate_chars, $string);
00336         $string = urlencode($string);
00337         return $string;
00338     }
00339 
00340     public function translateContentTask ($task) {
00341         return isset($this->config->sef_content_task[$task]) ? $this->config->sef_content_task[$task] : $task;
00342     }
00343 
00344     public function untranslateContentTask ($tr_task) {
00345         $task = array_search ($tr_task, $this->config->sef_content_task);
00346         if (!$task) $task = $tr_task;
00347         return in_array($task, $this->content_tasks) ? $task : null;
00348     }
00349 
00350     private function analyseStandardURI ($uri) {
00351         $_SERVER['REQUEST_URI'] = $uri;
00352         // Should think about using cache for this
00353         if (isset($this->cached['metadata'][$uri])) $this->metadata = $this->cached['metadata'][$uri];
00354         else {
00355             $this->database->setQuery("SELECT * FROM #__remosef_metadata WHERE uri = '$uri'");
00356             $this->database->loadObject($this->metadata);
00357             if (is_null($this->metadata)) $this->metadata =  new stdClass();
00358             $this->cached['metadata'][$uri] = $this->metadata;
00359             $this->cache->save($this->cached, 'sefDataURI');
00360         }
00361         $mainparts = explode('?', $uri);
00362         if (empty($mainparts[1])) return;
00363         $_SERVER['QUERY_STRING'] = $mainparts[1];
00364         $vars = explode('&', $mainparts[1]);
00365         foreach ($vars as $var) {
00366             $parts = explode('=', $var);
00367             if (!empty($parts[1])) {
00368                 $_REQUEST[$parts[0]] = $_GET[$parts[0]] = $parts[1];
00369             }
00370         }
00371     }
00372     
00373     private function redirect301 ($to) {
00374         header ('HTTP/1.1 301 Moved Permanently');
00375         header ('Location:'.$to);
00376         exit;
00377     }
00378 
00379     public function sefRetrieval() {
00380         $uri = $_SERVER['REQUEST_URI'];
00381         $sublength = strlen(dirname($_SERVER['PHP_SELF']));
00382         if (1 < $sublength) $uri = substr($uri,$sublength);
00383         $uri = str_replace(array('!', '%21', '&amp;'), array('','','&'), $uri);
00384         if (!$uri OR $uri == '/' or $uri == '/index.php') {
00385             $this->home_page = true;
00386             return 0;
00387         }
00388         if (preg_match('/(\b)GLOBALS|_REQUEST|_SERVER|_ENV|_COOKIE|_GET|_POST|_FILES|_SESSION(\b)/i', $uri) > 0) {
00389             die('Invalid Request');
00390         }
00391         $regex = '#[<>\(\)@"\']+|/\?#';
00392         if (preg_match($regex, $uri)) return 1;
00393         $saveuri = $uri;
00394         $uri = str_replace('//', '/', $uri);
00395         if ($this->config->underscore AND $this->SEF_SPACE == '-' AND strpos($uri,'_') !== false) $uri = str_replace('_', '-', $uri);
00396         $exactback = array_search($uri, $this->config->sef_substitutions_exact);
00397         if (false === $exactback AND '/' != substr($uri,-1)) {
00398             $exactback = array_search($uri.'/', $this->config->sef_substitutions_exact);
00399             if (false !== $exactback) $this->redirect301($this->live_site.$uri.'/');
00400         }
00401         if (false !== $exactback) {
00402             $this->analyseStandardURI($exactback);
00403             return 0;
00404         }
00405         $uri = @preg_replace(array_keys($this->config->sef_substitutions_in), array_values($this->config->sef_substitutions_in), $uri);
00406         if ($indexloc = strpos($uri, 'index.php?')) {
00407             if ($_SERVER['REQUEST_METHOD'] == 'GET') {
00408                 $sefagain = substr($this->sefRelToAbs(substr($uri,$indexloc), false),strlen($this->live_site));
00409                 if ($saveuri != $sefagain) $this->redirect301($sefagain);
00410             }
00411             return 0;
00412         }
00413         elseif (false !== strpos($uri,'index2.php') OR false !== strpos($uri,'index3.php')) return 0;
00414         $retrieved = $this->retrieveURI ($uri);
00415         if (!$retrieved AND '/' != substr($uri,-1)) {
00416             $retrieved = $this->retrieveURI($uri.'/');
00417             if ($retrieved) $this->redirect301($this->live_site.$uri.'/');
00418         }
00419         if (!$retrieved) {
00420             $helper = new aliroSEFHelper();
00421             $retrieved = $helper->basicRetrieve($uri, $this->config, $this, $this->live_site);
00422             if ($retrieved) trigger_error('Had to invoke SEF basicRetrieve: '.$uri.' : '.$retrieved);
00423         }
00424 
00425         if ($retrieved) {
00426             $retrieved = 'index.php?'.$retrieved;
00427             $sefagain = substr($this->sefRelToAbs($retrieved),strlen($this->live_site));
00428             if ($saveuri != $sefagain AND $_SERVER['REQUEST_METHOD'] == 'GET') $this->redirect301($sefagain);
00429             $this->analyseStandardURI($retrieved);
00430             $returncode = 0;
00431         }
00432         else $returncode = 1;
00433 
00434         return $returncode;
00435     }
00436     
00437     private function retrieveURI ($sef) {
00438         $retrieved = array_search($sef, $this->cached['SEF']);
00439         if ($retrieved) return $retrieved;
00440         $coded_sef = $this->database->getEscaped($sef);
00441         $this->database->setQuery("SELECT uri FROM #__remosef_uri WHERE sef='$coded_sef'");
00442         $this->database->loadObject($sefdata);
00443         if ($sefdata) return $sefdata->uri;
00444         else return false;
00445     }
00446 
00447     // Not intended for general use - public for use by helper class
00448     public function invoke_plugin ($i, $method, $parm1, $parm2=0) {
00449         error_reporting(E_ALL);
00450         require_once($this->config->custom_PHP[$i]);
00451         $classname = 'sef_'.$this->config->custom_short[$i];
00452         $compname = 'com_'.$this->config->custom_short[$i];
00453         $maptags = isset($this->config->component_details[$compname]) ? $this->config->component_details[$compname] : array();
00454         if (method_exists($classname, 'getInstance')) {
00455             $plugin = call_user_func(array($classname, 'getInstance'));
00456             if ('create' == $method) return $plugin->$method($parm1, $this->config->lower_case, $this->config->unique_id, $maptags);
00457             else return $plugin->revert($parm1, $parm2, $maptags);
00458         }
00459         else {
00460             $callplugin = array($classname, $method);
00461             if ('create' == $method) return call_user_func ($callplugin, $parm1, $this->config->lower_case, $this->config->unique_id, $maptags);
00462             else return call_user_func ($callplugin, $parm1, $parm2, $maptags);
00463         }
00464     }
00465 
00466     // Not intended for general use - public for use by helper class
00467     public function default_revert ($specialname) {
00468         $request = explode($specialname.'/', $_SERVER['REQUEST_URI']);
00469         if (isset($request[1])) $parmset = explode("/", $request[1]);
00470         else $parmset = array();
00471         $QUERY_STRING = '';
00472         foreach($parmset as $values) {
00473             $parts = explode(",", $values);
00474             if (count($parts) > 1) {
00475                 $_REQUEST[$parts[0]] = $_GET[$parts[0]] = $parts[1];
00476                 if ($parts[0] == 'option') $QUERY_STRING .= "option=$parts[1]";
00477                 else $QUERY_STRING .= "&$parts[0]=$parts[1]";
00478             }
00479         }
00480         return $QUERY_STRING;
00481     }
00482 
00483     private function parse ($string, &$parms) {
00484         $parms = array();
00485         $parts = explode('&', $string);
00486         foreach ($parts as $part) {
00487             $assigns = explode('=', $part);
00488             if (count($assigns) == 2) $parms[$assigns[0]] = $assigns[1];
00489         }
00490     }
00491 
00492     public function getHead($title, $metatags, $customtags) {
00493         $head = $found = array();
00494         $block['title'] = 1;
00495         $sitename = $this->getCfg('sitename');
00496         if ($this->home_page) $extratitle = $this->config->home_title;
00497         elseif (empty($this->metadata->htmltitle)) {
00498             if (strlen($title) > strlen($sitename)) $extratitle = substr($title, 0, -(strlen($sitename)+3));
00499             else $extratitle = '';
00500         }
00501         else $extratitle = htmlspecialchars($this->metadata->htmltitle, ENT_QUOTES, 'UTF-8');
00502         if ($extratitle) {
00503             if (strlen($extratitle) + strlen($sitename) < 60) $extratitle .= ' '.$this->config->title_separator.' '.$sitename;
00504         }
00505         else $extratitle = $sitename;
00506         $head[] = '<title>' . $extratitle . '</title>';
00507         
00508         if (!empty($this->metadata->description)) {
00509             $head[] = $this->makeMeta('description', htmlspecialchars($this->metadata->description, ENT_QUOTES, 'UTF-8'));
00510             $block['description'] = 1;
00511         }
00512         if (!empty($this->metadata->keywords)) {
00513             $head[] = $this->makeMeta('keywords', htmlspecialchars($this->metadata->keywords, ENT_QUOTES, 'UTF-8'));
00514             $block['keywords'] = 1;
00515         }
00516         if (!empty($this->metadata->robots)) {
00517             $head[] = $this->makeMeta('robots', htmlspecialchars($this->metadata->robots, ENT_QUOTES, 'UTF-8'));
00518             $block['robots'] = 1;
00519         }
00520 
00521         foreach ($metatags as $name=>$meta) {
00522             if (isset($block[$name]) OR empty($meta[0])) continue;
00523             $found[$name] = 1;
00524             if ($meta[1]) $head[] = $meta[1];
00525             $head[] = $this->makeMeta ($name, $meta[0]);
00526             if ($meta[2]) $head[] = $meta[2];
00527         }
00528 
00529         if (empty($block['description']) AND empty($found['description'])) $head[] = $this->makeMeta('description', htmlspecialchars($this->getCfg('MetaDesc'), ENT_QUOTES, 'UTF-8'));
00530         if (empty($block['keywords']) AND empty($found['keywords'])) $head[] = $this->makeMeta('keywords', htmlspecialchars($this->getCfg('MetaKeys'), ENT_QUOTES, 'UTF-8'));
00531         if (empty($block['robots']) AND empty($found['robots'])) $head[] = $this->makeMeta('robots', $this->config->default_robots);
00532 
00533         foreach ($customtags as $html) $head[] = $html;
00534         return implode( "\n", $head )."\n";
00535     }
00536 
00537     function makeMeta ($name, $value) {
00538         return <<<META_DATA
00539 <meta name="$name" content="$value" />
00540 META_DATA;
00541 
00542     }
00543     
00544     public function sefComponentName ($cname) {
00545         $i = array_search($cname,$this->config->custom_code);
00546         return ($i !== false AND $i !== null) ? $this->config->custom_name[$i] : $cname;
00547     }
00548 
00549     public function sefRelToAbs ($string, $specialamp=true) {
00550         if ($string == 'index.php') return $this->live_site.'/';
00551         if (strtolower(substr($string,0,9)) != 'index.php' OR eregi('^(([^:/?#]+):)',$string)) return $string;
00552         $string = str_replace('&amp;', '&', $string);
00553         $clean_string = preg_replace('/\&Itemid=[0-9]*/', '', $string);
00554         $homelink = $this->mainmenu[0]->link;
00555         if ($clean_string == $homelink) return $this->live_site.'/';
00556         if (!($this->getCfg('sef')) OR !$this->config->enabled) return $this->live_site.'/'.($specialamp ? str_replace( '&', '&amp;', $clean_string ) : $clean_string);
00557         $string = substr($clean_string,10);
00558         if (isset($this->config->sef_substitutions_exact['/'.$clean_string])) return $this->live_site.$this->config->sef_substitutions_exact['/'.$clean_string];
00559         if (isset($this->cached['SEF'][$clean_string]) AND (time() - $this->config->cachedTime[$clean_string]) < $this->config->cache_time) return $this->live_site.$this->cached['SEF'][$clean_string];
00560         $oktasks = true;
00561         $option = $task = '';
00562         $this->parse($string, $params);
00563         foreach ($params as $key=>$value) {
00564             $lowkey = strtolower($key);
00565             $lowvalue = strtolower($value);
00566             $unset = true;
00567             switch ($lowkey) {
00568                 case 'option':
00569                     $option = $lowvalue;
00570                     break;
00571                 case 'task':
00572                     $task = $value;
00573                     if ($lowvalue == 'new' OR $lowvalue == 'edit') $oktasks = false;
00574                     break;
00575                 default:
00576                     $check_params[$lowkey] = $key;
00577                     $unset = false;
00578             }
00579             if ($unset) unset($params[$key]);
00580         }
00581         // Process content items
00582         if (($option == 'com_content' OR $option == 'content') AND $oktasks) {
00583             /*
00584             Content
00585             index.php?option=com_content&task=$task&sectionid=$sectionid&id=$id&Itemid=$Itemid&limit=$limit&limitstart=$limitstart
00586             */
00587             $content_sef = _ALIRO_CLASS_BASE.'/components/com_content/sef_ext.php';
00588             if (file_exists($content_sef)) {
00589                 require_once($content_sef);
00590                 $result = sef_content::create($task, $params, $this->config->lower_case, $this->config->unique_id);
00591                 return $this->live_site.$this->outSubstitution($string, $result);
00592             }
00593             $keys = array('sectionid', 'id', 'itemid', 'limit', 'limitstart', 'year', 'month', 'module', 'lang');
00594             $result = '/content/'.$task.'/';
00595             foreach ($keys as $key) {
00596                 if (isset($check_params[$key])) {
00597                     $pkey = $check_params[$key];
00598                     $result .= $params[$pkey].'/';
00599                 }
00600             }
00601             return $this->live_site.$this->outSubstitution($string, $result);
00602         }
00603         // Process customised components
00604         $i = array_search($option,$this->config->custom_code);
00605         if ($i !== false AND $i !== null) {
00606             if ($this->config->custom_PHP[$i] AND file_exists($this->config->custom_PHP[$i])) {
00607                 $result = $this->invoke_plugin ($i, 'create', $clean_string);
00608             }
00609             else $result = $this->componentDetails($params,$task);
00610             $cname = $this->config->custom_name[$i];
00611             $result = '/'.($this->config->lower_case ? strtolower($cname) : $cname).'/'.$result;
00612             return $this->live_site.$this->outSubstitution($string, $result);
00613         }
00614         // Process ordinary components
00615         if (strpos($option,'com_')===0 AND $option != 'com_registration' AND $oktasks) {
00616             $result = "/component/option,$option/".$this->componentDetails($params,$task);
00617             return $this->live_site.$this->outSubstitution($string, $result);
00618         }
00619         // Anything else is returned as received, except it is guaranteed that & will be &amp;
00620         return $this->live_site.'/'.($specialamp ? str_replace( '&', '&amp;', $clean_string ) : $clean_string);
00621     }
00622 
00623     private function outSubstitution ($inuri, $outuri) {
00624         $now = time();
00625         // if ($this->config->underscore AND $this->SEF_SPACE == '-' AND strpos($outuri,'_') !== false) $outuri = str_replace('_', '-', $outuri);
00626         $finishedurl = @preg_replace(array_keys($this->config->sef_substitutions_out), array_values($this->config->sef_substitutions_out), $outuri);
00627         if (isset($this->cached['SEF'][$inuri]) AND $finishedurl == $this->cached['SEF'][$inuri] AND ($now - $this->cached['Time'][$inuri] < (int) $this->config->cache_time)) return $finishedurl;
00628         $this->cached['SEF'][$inuri] = $finishedurl;
00629         $this->cached['Time'][$inuri] = $now;
00630         $this->cache->save($this->cached, 'sefDataURI');
00631         $sef = $this->database->getEscaped($finishedurl);
00632         $uri = $this->database->getEscaped($inuri);
00633         $this->database->doSQL("UPDATE #__remosef_uri SET sef = '$sef', refreshed = $now, marker = 1 - marker WHERE uri = '$uri'");
00634         if (0 == $this->database->getAffectedRows()) {
00635             $this->database->doSQL("INSERT INTO #__remosef_uri (uri, sef, refreshed) VALUES ('$uri', '$sef', $now)");
00636         }
00637         if (50 == mt_rand(0,99)) {
00638             $weekago = $now - 7*24*60*60;
00639             $chkcode = 'option=com_remository&Itemid=65&func=download&id';
00640             $this->database->doSQL("DELETE FROM #__remosef_uri WHERE uri LIKE '$chkcode%' AND refreshed < $weekago");
00641         }
00642         return $finishedurl;
00643     }
00644 
00645     private function componentDetails (&$params, $task) {
00646         $string = ($task ? "task,$task/" : '');
00647         foreach ($params as $key=>$param) {
00648                     $param = urlencode($param);
00649                     $string .= "$key,$param/";
00650                 }
00651         return $string;
00652     }
00653 
00654 
00655 }

Generated on Wed May 14 13:01:56 2008 for ALIRO by  doxygen 1.5.5