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