Ejemplo n.º 1
0
function shGetNonSefURLFromCache($string, &$url)
{
    $sefConfig =& Sh404sefFactory::getConfig();
    if (!$sefConfig->shUseURLCache) {
        $url = null;
        return sh404SEF_URLTYPE_NONE;
    }
    shLoadURLCache();
    $diskCacheSize = count($GLOBALS['shURLDiskCache']);
    $memCacheSize = count($GLOBALS['shURLMemCache']);
    if (empty($diskCacheSize) && empty($memCacheSize)) {
        $url = null;
        return sh404SEF_URLTYPE_NONE;
    }
    for ($i = 0; $i < $diskCacheSize; $i++) {
        if (strpos($GLOBALS['shURLDiskCache'][$i], $string) !== false) {
            $tmp = explode('#', $GLOBALS['shURLDiskCache'][$i]);
            // cache format : non-sef#sef#type
            $nonSef = html_entity_decode($tmp[0], ENT_QUOTES);
            if ($string == $tmp[1]) {
                $url = $nonSef;
                _log('Retrieved Non SEF from disk cache : ' . $url . ' => ' . $tmp[1] . '(' . $tmp[2] . ')');
                return $tmp[2];
            }
        }
    }
    for ($i = 0; $i < $memCacheSize; $i++) {
        if (strpos($GLOBALS['shURLMemCache'][$i], $string) !== false) {
            $tmp = explode('#', $GLOBALS['shURLMemCache'][$i]);
            // cache format : non-sef#sef#type
            $nonSef = html_entity_decode($tmp[0], ENT_QUOTES);
            if ($string == $tmp[1]) {
                $url = $nonSef;
                _log('Retrieved Non SEF from mem cache : ' . $url . ' => ' . $tmp[1] . '(' . $tmp[2] . ')');
                return $tmp[2];
            }
        }
    }
    return sh404SEF_URLTYPE_NONE;
}
Ejemplo n.º 2
0
 /**
  * Save an url to the database, updating various elements
  * at the same time like ranking of duplicates
  *
  * @param integer $type force url type, used when saving a custom url
  */
 private function _saveUrl($type = sh404SEF_URLTYPE_AUTO)
 {
     // check for homepage handling
     if (!empty($this->_data['newurl']) && ($this->_data['newurl'] == '/' || $this->_data['newurl'] == sh404SEF_HOMEPAGE_CODE)) {
         $this->_saveHomeUrl();
         return sh404SEF_HOMEPAGE_CODE;
     }
     // check for importing urls : if importing, rank will already be set in
     // incoming data. If saving a url from the UI, rank is never set
     // as it is caculated upon saving the url
     $importing = isset($this->_data['rank']);
     // get required tools
     jimport('joomla.database.table');
     $row =& JTable::getInstance($this->_defaultTable, 'Sh404sefTable');
     // now bind incoming data to table row
     if (!$row->bind($this->_data)) {
         $this->setError($row->getError());
         return 0;
     }
     // pre-save checks
     if (!$row->check()) {
         $this->setError($row->getError());
         return 0;
     }
     // must load cache from disk, so that it can be written back later, with new url
     require_once JPATH_ROOT . '/components/com_sh404sef/shCache.php';
     shLoadURLCache();
     // find if we are adding a custom or automatic url
     $urlType = $row->dateadd == '0000-00-00' ? sh404SEF_URLTYPE_AUTO : sh404SEF_URLTYPE_CUSTOM;
     // override with user supplied
     if (!empty($type)) {
         $urlType = $type;
     }
     // adjust date added field if needed
     if ($urlType == sh404SEF_URLTYPE_CUSTOM) {
         $row->dateadd = date("Y-m-d");
     }
     // if custom url, and no language string, let's add default one
     if ($urlType == sh404SEF_URLTYPE_CUSTOM && !preg_match('/(&|\\?)lang=[a-zA-Z]{2,3}/iU', $row->newurl)) {
         $shTemp = explode('-', shGetDefaultLang());
         $shLangTemp = $shTemp[0] ? $shTemp[0] : 'en';
         $row->newurl .= '&lang=' . $shLangTemp;
     }
     // normalize the non-sef url representation, sorting query parts alphabetically
     $row->newurl = shSortUrl($row->newurl);
     // retrieve previous values of sef and non sef urls
     $previousSefUrl = JRequest::getVar('previousSefUrl', null, 'POST');
     $previousNonSefUrl = JRequest::getVar('previousNonSefUrl', null, 'POST');
     // if both were set, and nothing has changed, then nothing to do
     if (!empty($previousSefUrl) && !empty($previousNonSefUrl) && $previousNonSefUrl == $row->newurl && $previousSefUrl == $row->oldurl) {
         // nothing changed ! must be changing meta or aliases
         $this->_url = $row;
         return $row->id;
     }
     // search DB for urls pairs with same SEF url
     $query = 'SELECT * FROM #__redirection WHERE oldurl = ' . $this->_db->Quote($row->oldurl) . ' ORDER BY rank ASC';
     $this->_db->setQuery($query);
     $dbUrlList = $this->_db->loadObjectList();
     // do we have urls in the db with same SEF ?
     if (count($dbUrlList) > 0) {
         // yes we do
         // get config object
         $sefConfig = shRouter::shGetConfig();
         if (!$sefConfig->shRecordDuplicates) {
             // we don't allow duplicates : reject this URL
             $this->setError(COM_SH404SEF_DUPLICATE_NOT_ALLOWED);
         } else {
             // same SEF, but we allow duplicates
             $existingRecord = null;
             // importing meta data for instance
             foreach ($dbUrlList as $urlInDB) {
                 // same SEF, but is the incoming non-sef in this list of URl with same SEF ?
                 if ($urlInDB->newurl == $row->newurl) {
                     $existingRecord = $urlInDB;
                     $this->setError(COM_SH404SEF_URLEXIST);
                 }
             }
             if (empty($existingRecord)) {
                 // this new non-sef does not already exists
                 $shTemp = array('nonSefURL' => $row->newurl);
                 // which means we must update the record for the old non-sef url
                 Sh404sefHelperCache::removeURLFromCache($shTemp);
                 // remove the old url from cache
                 // then find new rank (as we are adding a duplicate, we add it at the end of the duplicate list)
                 // but only if not importing. When importing, rank is already set
                 if (!$importing) {
                     $row->rank = $dbUrlList[count($dbUrlList) - 1]->rank + 1;
                 }
                 // store will create a new record if id=0, or update existing if id non 0
                 $row->store();
                 // put custom URL in DB and cache
                 Sh404sefHelperCache::addSefUrlToCache($row->newurl, $row->oldurl, $urlType);
                 // we must add the previous SEF url to the alias list, only if
                 //   - not already there
                 //   - this sef url does not already exists in the DB; which will happen if the url
                 //     being saved was customized and also had duplicates
                 // TODO this code is duplicated just a few line below, need refactoring
                 if (!empty($previousSefUrl) && strpos($this->_data['shAliasList'], $previousSefUrl) === false) {
                     // check if not already a valid SEF url in the DB
                     $query = 'SELECT count(id) FROM #__redirection WHERE oldurl = ' . $this->_db->Quote($previousSefUrl);
                     $this->_db->setQuery($query);
                     $isThere = $this->_db->loadResult();
                     if (empty($isThere)) {
                         $this->_data['shAliasList'] .= $previousSefUrl . "\n";
                     }
                 }
             } else {
                 // there is already a record with both this sef and non sef.
                 // just do nothing but return success (ie: record id).
                 // Later, controller may store new aliases or metas
                 // This should never happen when saving regular data as we added
                 // a check for this case earlier
                 // May happen when importing though
                 $this->_url = $row;
                 return $row->id;
             }
             // additional step : if we are here, it may be because we have modified
             // an existing url, and specifically changed it sef value to something else
             // Now it may be that this record was the one with rank = 0 in a series
             // of duplicate urls. If so, the urls which was ranked above must now become
             // the main url, having rank = 0
             // note : when importing, we don't enter this test as previousSefUrl is empty
             // TODO this code is duplicated just a few line below, need refactoring
             if (!empty($previousSefUrl) && $previousSefUrl != $row->newurl) {
                 // search for the old #2 record in duplicate list
                 $query = 'SELECT id FROM #__redirection WHERE oldurl = ' . $this->_db->Quote($previousSefUrl) . ' ORDER BY rank ASC';
                 $this->_db->setQuery($query);
                 $previousRanked2 = $this->_db->loadObject();
                 // there was more than one duplicate in the same series, promote #2 to top spot
                 if (!empty($previousRanked2)) {
                     $query = 'UPDATE #__redirection SET rank="0" WHERE id = ' . $this->_db->Quote($previousRanked2->id);
                     $this->_db->setQuery($query);
                     $this->_db->query();
                 }
             }
         }
     } else {
         // there is no URL with same SEF URL, we are customizing an existing SEF url
         $shTemp = array('nonSefURL' => $row->newurl);
         Sh404sefHelperCache::removeURLFromCache($shTemp);
         // remove it from cache
         // simply store URL. If there is already one with same non-sef, this will raise an error in store()
         // as we don't allow creating a custom url for an already existing non-sef. User should
         // directly edit the existing non-sef/sef pair
         if (!$row->check()) {
             $this->setError($row->getError());
             return 0;
         }
         if (!$row->store()) {
             $this->setError($row->getError());
             return 0;
         }
         // add also to cache if saved to db
         Sh404sefHelperCache::addSefUrlToCache($row->newurl, $row->oldurl, $urlType);
         // we must add the previous SEF url to the alias list, only if
         //   - not already there
         //   - this sef url does not already exists in the DB; which will happen if the url
         //     begin saved was customized and also had duplicates
         // note : when importing, we don't enter this test as previousSefUrl is empty
         // TODO this code is duplicated just a few line above, need refactoring
         if (!empty($previousSefUrl) && strpos($this->_data['shAliasList'], $previousSefUrl) === false) {
             // check if not already a valid SEF url in the DB
             $query = 'SELECT count(id) FROM #__redirection WHERE oldurl = ' . $this->_db->Quote($previousSefUrl);
             $this->_db->setQuery($query);
             $isThere = $this->_db->loadResult();
             if (empty($isThere)) {
                 $this->_data['shAliasList'] .= $previousSefUrl . "\n";
             }
         }
         // finally, also check db for urls with same sef as previous SEF if any. We need
         // to search for the first duplicate of this old sef, and set it to be
         // the new main url
         // note : when importing, we don't enter this test as previousSefUrl is empty
         // TODO this code is duplicated just a few line above, need refactoring
         if (!empty($previousSefUrl) && $previousSefUrl != $row->newurl) {
             // search for the old #2 record in duplicate list
             $query = 'SELECT id FROM #__redirection WHERE oldurl = ' . $this->_db->Quote($previousSefUrl) . ' ORDER BY rank ASC';
             $this->_db->setQuery($query);
             $previousRanked2 = $this->_db->loadObject();
             // there was more than one duplicate in the same series, promote #2 to top spot
             if (!empty($previousRanked2)) {
                 $query = 'UPDATE #__redirection SET rank="0" WHERE id = ' . $this->_db->Quote($previousRanked2->id);
                 $this->_db->setQuery($query);
                 $this->_db->query();
             }
         }
     }
     // store saved url object
     $this->_url = $row;
     // return what should be a non-zero id
     return $this->_url->id;
 }