280 Zeilen
Kein EOL
9,1 KiB
PHP
280 Zeilen
Kein EOL
9,1 KiB
PHP
<?php
|
|
/**
|
|
* File:
|
|
* class.modrewriteurlstack.php
|
|
*
|
|
* ModRewrite url stack class
|
|
*
|
|
* @category ConLite
|
|
* @package Plugin
|
|
* @subpackage ModRewrite
|
|
* @since 2.1.3
|
|
* @author Ortwin Pinke <o.pinke@conlite.org>
|
|
* @copyright (c) 2022, conlite.org
|
|
* @license http://www.gnu.de/documents/gpl.en.html GPL v3 (english version)
|
|
* @license http://www.gnu.de/documents/gpl.de.html GPL v3 (deutsche Version)
|
|
* @link http://www.conlite.org ConLite.org
|
|
*
|
|
* based on former AMR class by Murat Purc <murat@purc.de> for CONTENIDO 4.8.x
|
|
*/
|
|
if (!defined('CON_FRAMEWORK')) {
|
|
die('Illegal call');
|
|
}
|
|
|
|
class ModRewriteUrlStack {
|
|
|
|
/**
|
|
* Self instance
|
|
*
|
|
* @var ModRewriteUrlStack
|
|
*/
|
|
private static $_oInstance;
|
|
|
|
/**
|
|
* Database object
|
|
*
|
|
* @var DB_Contenido
|
|
*/
|
|
private $_oDb;
|
|
|
|
/**
|
|
* Array for urls
|
|
*
|
|
* @var array
|
|
*/
|
|
private $_aUrls = array();
|
|
|
|
/**
|
|
* Url stack array
|
|
*
|
|
* @var array
|
|
*/
|
|
private $_aStack = array();
|
|
|
|
/**
|
|
* CONTENIDO related parameter array
|
|
*
|
|
* @var array
|
|
*/
|
|
private $_aConParams = array(
|
|
'idcat' => 1, 'idart' => 1, 'lang' => 1, 'idcatlang' => 1, 'idcatart' => 1, 'idartlang' => 1
|
|
);
|
|
|
|
/**
|
|
* Database tables array
|
|
*
|
|
* @var array
|
|
*/
|
|
private $_aTab;
|
|
|
|
/**
|
|
* Language id
|
|
*
|
|
* @var int
|
|
*/
|
|
private $_idLang;
|
|
|
|
/**
|
|
* Constructor, sets some properties.
|
|
*/
|
|
private function __construct() {
|
|
$this->_oDb = cRegistry::getDb();
|
|
$this->_aTab = cRegistry::getConfigValue('tab');
|
|
$this->_idLang = cRegistry::getLanguageId();
|
|
}
|
|
|
|
/**
|
|
* Returns a instance of ModRewriteUrlStack (singleton implementation)
|
|
*
|
|
* @return ModRewriteUrlStack
|
|
*/
|
|
public static function getInstance() {
|
|
if (self::$_oInstance == null) {
|
|
self::$_oInstance = new ModRewriteUrlStack();
|
|
}
|
|
return self::$_oInstance;
|
|
}
|
|
|
|
/**
|
|
* Adds an url to the stack
|
|
*
|
|
* @param string Url, like front_content.php?idcat=123...
|
|
*/
|
|
public function add($url) {
|
|
$url = ModRewrite::urlPreClean($url);
|
|
if (isset($this->_aUrls[$url])) {
|
|
return;
|
|
}
|
|
|
|
$aUrl = $this->_extractUrl($url);
|
|
|
|
// cleanup parameter
|
|
foreach ($aUrl['params'] as $p => $v) {
|
|
if (!isset($this->_aConParams[$p])) {
|
|
unset($aUrl['params'][$p]);
|
|
} else {
|
|
$aUrl['params'][$p] = (int) $v;
|
|
}
|
|
}
|
|
|
|
// add language id, if not available
|
|
if ((int) mr_arrayValue($aUrl['params'], 'lang') == 0) {
|
|
$aUrl['params']['lang'] = $this->_idLang;
|
|
}
|
|
|
|
$sStackId = $this->_makeStackId($aUrl['params']);
|
|
$this->_aUrls[$url] = $sStackId;
|
|
$this->_aStack[$sStackId] = array('params' => $aUrl['params']);
|
|
}
|
|
|
|
/**
|
|
* Returns the pretty urlparts (only category path an article name) of the
|
|
* desired url.
|
|
*
|
|
* @param string Url, like front_content.php?idcat=123...
|
|
* @return array Assoziative array like
|
|
* <code>
|
|
* $arr['urlpath']
|
|
* $arr['urlname']
|
|
* </code>
|
|
*/
|
|
public function getPrettyUrlParts($url) {
|
|
$url = ModRewrite::urlPreClean($url);
|
|
if (!isset($this->_aUrls[$url])) {
|
|
$this->add($url);
|
|
}
|
|
|
|
$sStackId = $this->_aUrls[$url];
|
|
if (!isset($this->_aStack[$sStackId]['urlpath'])) {
|
|
$this->_chunkSetPrettyUrlParts($sStackId);
|
|
}
|
|
$aPretty = array(
|
|
'urlpath' => (empty($this->_aStack[$sStackId]['urlpath']))?'':$this->_aStack[$sStackId]['urlpath'],
|
|
'urlname' => (empty($this->_aStack[$sStackId]['urlname']))?'':$this->_aStack[$sStackId]['urlname']
|
|
);
|
|
return $aPretty;
|
|
}
|
|
|
|
/**
|
|
* Extracts passed url using parse_urla and adds also the 'params' array to it
|
|
*
|
|
* @param string Url, like front_content.php?idcat=123...
|
|
* @return array Components containing result of parse_url with additional
|
|
* 'params' array
|
|
*/
|
|
private function _extractUrl($url) {
|
|
$aUrl = @parse_url($url);
|
|
if (isset($aUrl['query'])) {
|
|
$aUrl['query'] = str_replace('&', '&', $aUrl['query']);
|
|
parse_str($aUrl['query'], $aUrl['params']);
|
|
}
|
|
if (empty($aUrl['params']) || !is_array($aUrl['params'])) {
|
|
$aUrl['params'] = array();
|
|
}
|
|
return $aUrl;
|
|
}
|
|
|
|
/**
|
|
* Extracts article or category related parameter from passed params array
|
|
* and generates an identifier.
|
|
*
|
|
* @param array $aParams Parameter array
|
|
* @return string Composed stack id
|
|
*/
|
|
private function _makeStackId(array $aParams) {
|
|
# idcatart
|
|
if ((int) mr_arrayValue($aParams, 'idart') > 0) {
|
|
$sStackId = 'idart_' . $aParams['idart'] . '_lang_' . $aParams['lang'];
|
|
} elseif ((int) mr_arrayValue($aParams, 'idartlang') > 0) {
|
|
$sStackId = 'idartlang_' . $aParams['idartlang'];
|
|
} elseif ((int) mr_arrayValue($aParams, 'idcatart') > 0) {
|
|
$sStackId = 'idcatart_' . $aParams['idcatart'] . '_lang_' . $aParams['lang'];
|
|
} elseif ((int) mr_arrayValue($aParams, 'idcat') > 0) {
|
|
$sStackId = 'idcat_' . $aParams['idcat'] . '_lang_' . $aParams['lang'];
|
|
} elseif ((int) mr_arrayValue($aParams, 'idcatlang') > 0) {
|
|
$sStackId = 'idcatlang_' . $aParams['idcatlang'];
|
|
} else {
|
|
$sStackId = 'lang_' . $aParams['lang'];
|
|
}
|
|
return $sStackId;
|
|
}
|
|
|
|
/**
|
|
* Main function to get the urlparts of urls.
|
|
*
|
|
* Composes the query by looping thru stored but non processed urls, executes
|
|
* the query and adds the (urlpath and urlname) result to the stack.
|
|
*
|
|
* @param type $sStackId
|
|
* @return type
|
|
*/
|
|
private function _chunkSetPrettyUrlParts($sStackId) {
|
|
if (!isset($this->_aStack[$sStackId]) || isset($this->_aStack[$sStackId]['urlpath'])) {
|
|
return;
|
|
}
|
|
|
|
$aStack = [];
|
|
$aStack[$sStackId] = $this->_aStack[$sStackId];
|
|
|
|
// now, it's time to compose the where clause of the query
|
|
$sWhere = '';
|
|
$aP = $this->_aStack[$sStackId]['params'];
|
|
if ((int) mr_arrayValue($aP, 'idart') > 0) {
|
|
$sWhere .= '(al.idart = ' . $aP['idart'] . ' AND al.idlang = ' . $aP['lang'] . ') OR ';
|
|
} elseif ((int) mr_arrayValue($aP, 'idartlang') > 0) {
|
|
$sWhere .= '(al.idartlang = ' . $aP['idartlang'] . ') OR ';
|
|
} elseif ((int) mr_arrayValue($aP, 'idcat') > 0) {
|
|
$sWhere .= '(cl.idcat = ' . $aP['idcat'] . ' AND cl.idlang = ' . $aP['lang'] . ' AND cl.startidartlang = al.idartlang) OR ';
|
|
} elseif ((int) mr_arrayValue($aP, 'idcatart') > 0) {
|
|
$sWhere .= '(ca.idcatart = ' . $aP['idcatart'] . ' AND ca.idart = al.idart AND al.idlang = ' . $aP['lang'] . ') OR ';
|
|
} elseif ((int) mr_arrayValue($aP, 'idcatlang') > 0) {
|
|
$sWhere .= '(cl.idcatlang = ' . $aP['idcatlang'] . ' AND cl.startidartlang = al.idartlang) OR ';
|
|
}
|
|
if ($sWhere == '') {
|
|
return;
|
|
}
|
|
$sWhere = cString::getPartOfString($sWhere, 0, -4);
|
|
$sWhere = str_replace(' OR ', " OR \n", $sWhere);
|
|
|
|
// compose query and execute it
|
|
$sql = <<<SQL
|
|
SELECT
|
|
al.idartlang, al.idart, al.idlang as lang, al.urlname, cl.idcatlang, cl.idcat,
|
|
cl.urlpath, ca.idcatart
|
|
FROM
|
|
{$this->_aTab['art_lang']} AS al, {$this->_aTab['cat_lang']} AS cl, {$this->_aTab['cat_art']} AS ca
|
|
WHERE
|
|
al.idart = ca.idart AND
|
|
ca.idcat = cl.idcat AND
|
|
al.idlang = cl.idlang AND
|
|
( $sWhere )
|
|
SQL;
|
|
ModRewriteDebugger::add($sql, 'ModRewriteUrlStack->_chunkSetPrettyUrlParts() $sql');
|
|
|
|
$aNewStack = [];
|
|
|
|
// create array of fields, which are to reduce step by step from record set below
|
|
$aFields = array('', 'idart', 'idartlang', 'idcatart', 'idcat');
|
|
|
|
$this->_oDb->query($sql);
|
|
while ($this->_oDb->next_record()) {
|
|
$aRS = $this->_oDb->Record;
|
|
|
|
// loop thru fields array
|
|
foreach ($aFields as $field) {
|
|
if (isset($aRS[$field])) {
|
|
// reduce existing field
|
|
unset($aRS[$field]);
|
|
}
|
|
|
|
// matching stack entry found, add urlpath and urlname to the new stack
|
|
$aNewStack[$sStackId]['urlpath'] = $aRS['urlpath'];
|
|
$aNewStack[$sStackId]['urlname'] = $aRS['urlname'];
|
|
}
|
|
}
|
|
ModRewriteDebugger::add($aNewStack, 'ModRewriteUrlStack->_chunkSetPrettyUrlParts() $aNewStack');
|
|
ModRewriteDebugger::add($this->_aStack, 'ModRewriteUrlStack->_chunkSetPrettyUrlParts() $this->_aStack');
|
|
|
|
$this->_aStack = array_merge($this->_aStack, $aNewStack);
|
|
}
|
|
} |