1: <?php
2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13:
14:
15: defined('CON_FRAMEWORK') || die('Illegal call: Missing framework initialization - request aborted.');
16:
17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48:
49: class ModRewriteUrlStack {
50:
51: 52: 53: 54: 55:
56: private static $_instance;
57:
58: 59: 60: 61: 62:
63: private $_oDb;
64:
65: 66: 67: 68: 69:
70: private $_aUrls = array();
71:
72: 73: 74: 75: 76:
77: private $_aStack = array();
78:
79: 80: 81: 82: 83:
84: private $_aConParams = array(
85: 'idcat' => 1, 'idart' => 1, 'lang' => 1, 'idcatlang' => 1, 'idcatart' => 1, 'idartlang' => 1
86: );
87:
88: 89: 90: 91: 92:
93: private $_aTab;
94:
95: 96: 97: 98: 99:
100: private $_idLang;
101:
102: 103: 104:
105: private function __construct() {
106: global $cfg, $lang;
107: $this->_oDb = cRegistry::getDb();
108: $this->_aTab = $cfg['tab'];
109: $this->_idLang = $lang;
110: }
111:
112: 113: 114: 115: 116:
117: public static function getInstance() {
118: if (self::$_instance == NULL) {
119: self::$_instance = new ModRewriteUrlStack();
120: }
121: return self::$_instance;
122: }
123:
124: 125: 126: 127: 128:
129: public function add($url) {
130: $url = ModRewrite::urlPreClean($url);
131: if (isset($this->_aUrls[$url])) {
132: return;
133: }
134:
135: $aUrl = $this->_extractUrl($url);
136:
137:
138: foreach ($aUrl['params'] as $p => $v) {
139: if (!isset($this->_aConParams[$p])) {
140: unset($aUrl['params'][$p]);
141: } else {
142: $aUrl['params'][$p] = (int) $v;
143: }
144: }
145:
146:
147: if ((int) mr_arrayValue($aUrl['params'], 'lang') == 0) {
148: $aUrl['params']['lang'] = $this->_idLang;
149: }
150:
151: $sStackId = $this->_makeStackId($aUrl['params']);
152: $this->_aUrls[$url] = $sStackId;
153: $this->_aStack[$sStackId] = array('params' => $aUrl['params']);
154: }
155:
156: 157: 158: 159: 160: 161: 162: 163: 164: 165: 166:
167: public function getPrettyUrlParts($url) {
168: $url = ModRewrite::urlPreClean($url);
169: if (!isset($this->_aUrls[$url])) {
170: $this->add($url);
171: }
172:
173: $sStackId = $this->_aUrls[$url];
174: if (!isset($this->_aStack[$sStackId]['urlpath'])) {
175: $this->_chunkSetPrettyUrlParts();
176: }
177: $aPretty = array(
178: 'urlpath' => $this->_aStack[$sStackId]['urlpath'],
179: 'urlname' => $this->_aStack[$sStackId]['urlname']
180: );
181: return $aPretty;
182: }
183:
184: 185: 186: 187: 188: 189: 190:
191: private function ($url) {
192: $aUrl = @parse_url($url);
193: if (isset($aUrl['query'])) {
194: $aUrl['query'] = str_replace('&', '&', $aUrl['query']);
195: parse_str($aUrl['query'], $aUrl['params']);
196: }
197: if (!isset($aUrl['params']) && !is_array($aUrl['params'])) {
198: $aUrl['params'] = array();
199: }
200: return $aUrl;
201: }
202:
203: 204: 205: 206: 207: 208: 209:
210: private function _makeStackId(array $aParams) {
211:
212: if ((int) mr_arrayValue($aParams, 'idart') > 0) {
213: $sStackId = 'idart_' . $aParams['idart'] . '_lang_' . $aParams['lang'];
214: } elseif ((int) mr_arrayValue($aParams, 'idartlang') > 0) {
215: $sStackId = 'idartlang_' . $aParams['idartlang'];
216: } elseif ((int) mr_arrayValue($aParams, 'idcatart') > 0) {
217: $sStackId = 'idcatart_' . $aParams['idcatart'] . '_lang_' . $aParams['lang'];
218: } elseif ((int) mr_arrayValue($aParams, 'idcat') > 0) {
219: $sStackId = 'idcat_' . $aParams['idcat'] . '_lang_' . $aParams['lang'];
220: } elseif ((int) mr_arrayValue($aParams, 'idcatlang') > 0) {
221: $sStackId = 'idcatlang_' . $aParams['idcatlang'];
222: } else {
223: $sStackId = 'lang_' . $aParams['lang'];
224: }
225: return $sStackId;
226: }
227:
228: 229: 230: 231: 232: 233:
234: private function _chunkSetPrettyUrlParts() {
235:
236: $aStack = array();
237: foreach ($this->_aStack as $stackId => $item) {
238: if (!isset($item['urlpath'])) {
239:
240: $aStack[$stackId] = $item;
241: }
242: }
243:
244:
245: $sWhere = '';
246: foreach ($aStack as $stackId => $item) {
247: $aP = $item['params'];
248: if ((int) mr_arrayValue($aP, 'idart') > 0) {
249: $sWhere .= '(al.idart = ' . $aP['idart'] . ' AND al.idlang = ' . $aP['lang'] . ') OR ';
250: } elseif ((int) mr_arrayValue($aP, 'idartlang') > 0) {
251: $sWhere .= '(al.idartlang = ' . $aP['idartlang'] . ') OR ';
252: } elseif ((int) mr_arrayValue($aP, 'idcat') > 0) {
253: $sWhere .= '(cl.idcat = ' . $aP['idcat'] . ' AND cl.idlang = ' . $aP['lang'] . ' AND cl.startidartlang = al.idartlang) OR ';
254: } elseif ((int) mr_arrayValue($aP, 'idcatart') > 0) {
255: $sWhere .= '(ca.idcatart = ' . $aP['idcatart'] . ' AND ca.idart = al.idart AND al.idlang = ' . $aP['lang'] . ') OR ';
256: } elseif ((int) mr_arrayValue($aP, 'idcatlang') > 0) {
257: $sWhere .= '(cl.idcatlang = ' . $aP['idcatlang'] . ' AND cl.startidartlang = al.idartlang) OR ';
258: }
259: }
260: if ($sWhere == '') {
261: return;
262: }
263: $sWhere = substr($sWhere, 0, -4);
264: $sWhere = str_replace(' OR ', " OR \n", $sWhere);
265:
266:
267: $sql = <<<SQL
268: SELECT
269: al.idartlang, al.idart, al.idlang as lang, al.urlname, cl.idcatlang, cl.idcat,
270: cl.urlpath, ca.idcatart
271: FROM
272: {$this->_aTab['art_lang']} AS al, {$this->_aTab['cat_lang']} AS cl, {$this->_aTab['cat_art']} AS ca
273: WHERE
274: al.idart = ca.idart AND
275: ca.idcat = cl.idcat AND
276: al.idlang = cl.idlang AND
277: ($sWhere)
278: SQL;
279: ModRewriteDebugger::add($sql, 'ModRewriteUrlStack->_chunkSetPrettyUrlParts() $sql');
280:
281: $aNewStack = array();
282:
283:
284: $aFields = array('', 'idart', 'idartlang', 'idcatart', 'idcat');
285:
286: $this->_oDb->query($sql);
287: while ($this->_oDb->nextRecord()) {
288: $aRS = $this->_oDb->getRecord();
289:
290:
291: foreach ($aFields as $field) {
292: if (isset($aRS[$field])) {
293:
294: unset($aRS[$field]);
295: }
296: $rsStackID = $this->_makeStackId($aRS);
297: if (isset($aStack[$rsStackID])) {
298:
299: $aNewStack[$rsStackID]['urlpath'] = $aRS['urlpath'];
300: $aNewStack[$rsStackID]['urlname'] = $aRS['urlname'];
301: break;
302: }
303: }
304: }
305: ModRewriteDebugger::add($aNewStack, 'ModRewriteUrlStack->_chunkSetPrettyUrlParts() $aNewStack');
306:
307:
308: $this->_aStack = array_merge($this->_aStack, $aNewStack);
309: }
310:
311: }
312: