1: <?php
  2:   3:   4:   5:   6:   7:   8:   9:  10:  11:  12: 
 13: 
 14: defined('CON_FRAMEWORK') || die('Illegal call: Missing framework initialization - request aborted.');
 15: 
 16:  17:  18:  19:  20:  21: 
 22: class cCategoryHelper {
 23: 
 24:      25:  26:  27:  28: 
 29:     private static $_instance = NULL;
 30: 
 31:      32:  33:  34:  35: 
 36:     protected $_languageId = 0;
 37: 
 38:      39:  40:  41:  42: 
 43:     protected $_clientId = 0;
 44: 
 45:      46:  47:  48:  49: 
 50:     protected $_levelCache = array();
 51: 
 52:      53:  54:  55:  56: 
 57:     protected $_auth = NULL;
 58: 
 59:      60:  61:  62:  63: 
 64:     protected $_feGroups = array();
 65: 
 66:      67:  68:  69:  70: 
 71:     protected $_fePermColl = NULL;
 72: 
 73:      74:  75:  76:  77: 
 78:     public static function getInstance() {
 79:         if (self::$_instance === NULL) {
 80:             self::$_instance = new self();
 81:         }
 82: 
 83:         return self::$_instance;
 84:     }
 85: 
 86:      87:  88: 
 89:     protected function __construct() {
 90:     }
 91: 
 92:      93:  94:  95:  96:  97: 
 98:     public function setAuth($auth) {
 99:         $this->_auth = $auth;
100: 
101:         $feUser = new cApiFrontendUser($auth->auth['uid']);
102:         if ($feUser->isLoaded() === true) {
103:             $this->_feGroups = $feUser->getGroupsForUser();
104:         }
105: 
106:         $this->_fePermColl = new cApiFrontendPermissionCollection();
107:     }
108: 
109:     110: 111: 112: 113: 114: 115: 116: 
117:     public function getClientId() {
118:         if ($this->_clientId == 0) {
119:             $clientId = cRegistry::getClientId();
120:             if ($clientId == 0) {
121:                 throw new cInvalidArgumentException('No active client ID specified or found.');
122:             }
123: 
124:             return $clientId;
125:         }
126: 
127:         return $this->_clientId;
128:     }
129: 
130:     131: 132: 133: 134: 135: 
136:     public function setClientId($clientId = 0) {
137:         $this->_clientId = (int) $clientId;
138:     }
139: 
140:     141: 142: 143: 144: 145: 146: 147: 
148:     public function getLanguageId() {
149:         if ($this->_languageId == 0) {
150:             $languageId = cRegistry::getLanguageId();
151:             if ($languageId == 0) {
152:                 throw new cInvalidArgumentException('No active language ID specified or found.');
153:             }
154: 
155:             return $languageId;
156:         }
157: 
158:         return $this->_languageId;
159:     }
160: 
161:     162: 163: 164: 165: 166: 
167:     public function setLanguageId($languageId = 0) {
168:         $this->_languageId = (int) $languageId;
169:     }
170: 
171:     172: 173: 174: 175: 176: 177: 178: 
179:     public function getTopMostCategoryId($categoryId) {
180:         $category = new cApiCategory($categoryId);
181: 
182:         if ($category->get('parentid') == 0) {
183:             $topMostCategoryId = $categoryId;
184:         } else {
185:             $topMostCategoryId = $this->getTopMostCategoryId($category->get('parentid'));
186:         }
187: 
188:         return $topMostCategoryId;
189:     }
190: 
191:     192: 193: 194: 195: 196: 197: 198: 199: 200: 201: 202: 203: 
204:     public function getCategoryPath($categoryId, $startingLevel = 1, $maxDepth = 20) {
205:         $clientId = $this->getClientId();
206:         $languageId = $this->getLanguageId();
207: 
208:         $categories = array();
209: 
210:         $categoryLanguage = new cApiCategoryLanguage();
211:         $categoryLanguage->loadByCategoryIdAndLanguageId($categoryId, $languageId);
212: 
213:         if ($this->hasCategoryAccess($categoryLanguage) === true) {
214:             $categories[] = $categoryLanguage;
215:         }
216: 
217:         $parentCategoryIds = $this->getParentCategoryIds($categoryId, $maxDepth);
218:         foreach ($parentCategoryIds as $parentCategoryId) {
219:             $categoryLanguage = new cApiCategoryLanguage();
220:             $categoryLanguage->loadByCategoryIdAndLanguageId($parentCategoryId, $languageId);
221: 
222:             if ($this->hasCategoryAccess($categoryLanguage) === true) {
223:                 $categories[] = $categoryLanguage;
224:             }
225:         }
226: 
227:         for ($removeCount = 2; $removeCount <= $startingLevel; $removeCount++) {
228:             array_pop($categories);
229:         }
230: 
231:         return array_reverse($categories);
232:     }
233: 
234:     235: 236: 237: 238: 239: 240: 241: 242: 243: 
244:     public function getParentCategoryIds($categoryId, $maxDepth = 20) {
245:         $categoryIds = array();
246: 
247:         $nextCategoryId = $categoryId;
248: 
249:         $categoryCount = 1;
250:         while ($nextCategoryId != 0 && $categoryCount < $maxDepth) {
251:             $category = new cApiCategory($nextCategoryId);
252: 
253:             $nextCategoryId = $category->get('parentid');
254:             if ($nextCategoryId != 0) {
255:                 $categoryIds[] = $nextCategoryId;
256:             }
257:             $categoryCount++;
258:         }
259: 
260:         return $categoryIds;
261:     }
262: 
263:     264: 265: 266: 267: 268: 269: 270: 
271:     public function getCategoryLevel($categoryId) {
272:         if (isset($this->_levelCache[$categoryId]) === false) {
273:             $categoryTree = new cApiCategoryTree();
274:             $categoryTree->loadBy("idcat", $categoryId);
275: 
276:             if ($categoryTree->isLoaded() === false) {
277:                 return -1;
278:             }
279: 
280:             $level = $categoryTree->get('level');
281: 
282:             $this->_levelCache[$categoryId] = $level;
283:         }
284: 
285:         return $this->_levelCache[$categoryId];
286:     }
287: 
288:     289: 290: 291: 292: 293: 294: 295: 296: 297: 298: 
299:     public function getSubCategories($categoryId, $depth) {
300:         if ((int) $categoryId <= 0 || (int) $depth < 0) {
301:             return array();
302:         }
303:         $depth = (int) $depth;
304: 
305:         $cfg = cRegistry::getConfig();
306: 
307:         $categories = array();
308: 
309:         $clientId = $this->getClientId();
310:         $languageId = $this->getLanguageId();
311: 
312:         $selectFields = "cat_tree.idcat, cat_tree.level";
313: 
314:         $useAuthorization = ($this->_auth !== NULL);
315: 
316:         if ($useAuthorization == true) {
317:             $selectFields .= ", cat_lang.public, cat_lang.idcatlang";
318:         }
319: 
320:         $sqlSnippetPublic = "cat_lang.public = 1 AND";
321:         if ($useAuthorization == true) {
322:             $sqlSnippetPublic = "";
323:         }
324: 
325:         $sql = 'SELECT
326:                     ' . $selectFields . '
327:                 FROM
328:                     ' . $cfg['tab']['cat_tree'] . ' AS cat_tree,
329:                     ' . $cfg['tab']['cat'] . ' AS cat,
330:                     ' . $cfg['tab']['cat_lang'] . ' AS cat_lang
331:                 WHERE
332:                     cat_tree.idcat    = cat.idcat AND
333:                     cat.idcat    = cat_lang.idcat AND
334:                     cat.idclient = ' . $clientId . ' AND
335:                     cat_lang.idlang   = ' . $languageId . ' AND
336:                     cat_lang.visible  = 1 AND ' . $sqlSnippetPublic . '
337:                     cat.parentid = ' . $categoryId . '
338:                 ORDER BY
339:                     cat_tree.idtree';
340: 
341:         $db = cRegistry::getDb();
342:         $db->query($sql);
343: 
344:         while ($db->nextRecord()) {
345:             $catId = (int) $db->f('idcat');
346:             $catLevel = (int) $db->f('level');
347: 
348:             if ($depth > 0 && ($depth > ($catLevel))) {
349:                 $subCategories = $this->getSubCategories($catId, $depth);
350:             } else {
351:                 $subCategories = array();
352:             }
353:             $categoryLanguage = new cApiCategoryLanguage();
354:             $categoryLanguage->loadByCategoryIdAndLanguageId($catId, $languageId);
355: 
356:             $category = array();
357:             $category['item'] = $categoryLanguage;
358:             $category['idcat'] = $catId;
359:             $category['level'] = $catLevel;
360:             $category['subcats'] = $subCategories;
361: 
362:             $this->_levelCache[$catId] = $catLevel;
363: 
364:             if ($this->hasCategoryAccess($categoryLanguage) === true) {
365:                 $categories[] = $category;
366:             }
367:         }
368: 
369:         return $categories;
370:     }
371: 
372:     373: 374: 375: 376: 377: 378: 379: 
380:     public function hasCategoryAccess(cApiCategoryLanguage $categoryLanguage) {
381:         $useAuthorization = ($this->_auth !== NULL && $this->_fePermColl !== NULL);
382: 
383:         if ($useAuthorization === false) {
384:             return true;
385:         }
386: 
387:         $perm = cRegistry::getPerm();
388: 
389:         if (intval($categoryLanguage->getField('public')) == 1) {
390:             return true;
391:         }
392: 
393:         $clientId = $this->getClientId();
394:         $languageId = $this->getLanguageId();
395: 
396:         if ($perm->have_perm_client_lang($clientId, $languageId) == true) {
397:             return true;
398:         }
399: 
400:         foreach ($this->_feGroups as $feGroup) {
401:             if ($this->_fePermColl->checkPerm($feGroup, 'category', 'access', $categoryLanguage->getField('idcatlang'), true)) {
402:                 return true;
403:             }
404:         }
405: 
406:         return false;
407:     }
408: }