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 ($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: