Overview

Packages

  • CONTENIDO
  • Core
    • Authentication
    • Backend
    • Cache
    • CEC
    • Chain
    • ContentType
    • Database
    • Debug
    • Exception
    • Frontend
      • Search
      • URI
      • Util
    • GenericDB
      • Model
    • GUI
      • HTML
    • I18N
    • LayoutHandler
    • Log
    • Security
    • Session
    • Util
    • Validation
    • Versioning
    • XML
  • Module
    • ContentSitemapHtml
    • ContentSitemapXml
    • ContentUserForum
    • NavigationTop
    • ScriptCookieDirective
  • mpAutoloaderClassMap
  • None
  • PHP
  • Plugin
    • ContentAllocation
    • CronjobOverview
    • FormAssistant
    • FrontendLogic
    • FrontendUsers
    • Linkchecker
    • ModRewrite
    • Newsletter
    • Repository
      • FrontendNavigation
      • KeywordDensity
    • SmartyWrapper
    • UrlShortener
    • UserForum
    • Workflow
  • PluginManager
  • Setup
    • Form
    • GUI
    • Helper
      • Environment
      • Filesystem
      • MySQL
      • PHP
    • UpgradeJob

Classes

  • cCategoryHelper
  • cFrontendHelper
  • Overview
  • Package
  • Class
  • Tree
  • Deprecated
  • Todo
  1: <?php
  2: /**
  3:  * This file contains the category helper class.
  4:  *
  5:  * @package Core
  6:  * @subpackage Frontend_Util
  7:  * @author Dominik Ziegler
  8:  * @copyright four for business AG <www.4fb.de>
  9:  * @license http://www.contenido.org/license/LIZENZ.txt
 10:  * @link http://www.4fb.de
 11:  * @link http://www.contenido.org
 12:  */
 13: 
 14: defined('CON_FRAMEWORK') || die('Illegal call: Missing framework initialization - request aborted.');
 15: 
 16: /**
 17:  * This class contains functions for the category helper class in CONTENIDO.
 18:  *
 19:  * @package Core
 20:  * @subpackage Frontend_Util
 21:  */
 22: class cCategoryHelper {
 23: 
 24:     /**
 25:      * Instance of the helper class.
 26:      *
 27:      * @var cCategoryHelper
 28:      */
 29:     private static $_instance = NULL;
 30: 
 31:     /**
 32:      * Local stored language ID
 33:      *
 34:      * @var int language ID
 35:      */
 36:     protected $_languageId = 0;
 37: 
 38:     /**
 39:      * Local stored client ID
 40:      *
 41:      * @var int client ID
 42:      */
 43:     protected $_clientId = 0;
 44: 
 45:     /**
 46:      * Local cache of category levels.
 47:      *
 48:      * @var array
 49:      */
 50:     protected $_levelCache = array();
 51: 
 52:     /**
 53:      * Auth object to use.
 54:      *
 55:      * @var cAuth
 56:      */
 57:     protected $_auth = NULL;
 58: 
 59:     /**
 60:      * Array with current frontend user groups.
 61:      *
 62:      * @var array
 63:      */
 64:     protected $_feGroups = array();
 65: 
 66:     /**
 67:      * Object for frontend permission collection.
 68:      *
 69:      * @var cApiFrontendPermissionCollection
 70:      */
 71:     protected $_fePermColl = NULL;
 72: 
 73:     /**
 74:      * Returns the instance of this class.
 75:      *
 76:      * @return cCategoryHelper
 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:      * Constructor to create an instance of this class.
 88:      */
 89:     protected function __construct() {
 90:     }
 91: 
 92:     /**
 93:      * Sets an auth object to use on category access check.
 94:      *
 95:      * @param cAuth $auth
 96:      *         auth object
 97:      *
 98:      * @throws cException
 99:      */
100:     public function setAuth($auth) {
101:         $this->_auth = $auth;
102: 
103:         $feUser = new cApiFrontendUser($auth->auth['uid']);
104:         if ($feUser->isLoaded() === true) {
105:             $this->_feGroups = $feUser->getGroupsForUser();
106:         }
107: 
108:         $this->_fePermColl = new cApiFrontendPermissionCollection();
109:     }
110: 
111:     /**
112:      * Returns the local stored client ID
113:      *
114:      * @return int
115:      *         client ID
116:      *
117:      * @throws cInvalidArgumentException if no active client ID specified or found
118:      */
119:     public function getClientId() {
120:         if ($this->_clientId == 0) {
121:             $clientId = cRegistry::getClientId();
122:             if ($clientId == 0) {
123:                 throw new cInvalidArgumentException('No active client ID specified or found.');
124:             }
125: 
126:             return $clientId;
127:         }
128: 
129:         return $this->_clientId;
130:     }
131: 
132:     /**
133:      * Sets the client ID to store it locally in the class.
134:      *
135:      * @param int $clientId [optional]
136:      *         client ID
137:      */
138:     public function setClientId($clientId = 0) {
139:         $this->_clientId = (int) $clientId;
140:     }
141: 
142:     /**
143:      * Returns the local stored language ID
144:      *
145:      * @return int
146:      *         language ID
147:      *
148:      * @throws cInvalidArgumentException
149:      *         if no active language ID specified or found
150:      */
151:     public function getLanguageId() {
152:         if ($this->_languageId == 0) {
153:             $languageId = cRegistry::getLanguageId();
154:             if ($languageId == 0) {
155:                 throw new cInvalidArgumentException('No active language ID specified or found.');
156:             }
157: 
158:             return $languageId;
159:         }
160: 
161:         return $this->_languageId;
162:     }
163: 
164:     /**
165:      * Sets the language ID to store it locally in the class.
166:      *
167:      * @param int $languageId [optional]
168:      *         language ID
169:      */
170:     public function setLanguageId($languageId = 0) {
171:         $this->_languageId = (int) $languageId;
172:     }
173: 
174:     /**
175:      * Return the ID of the top most category based on a given category ID.
176:      *
177:      * @param int $categoryId
178:      *         Base category ID to search on
179:      * @return int
180:      *         Top most category ID
181:      */
182:     public function getTopMostCategoryId($categoryId) {
183:         $category = new cApiCategory($categoryId);
184: 
185:         if ($category->get('parentid') == 0) {
186:             $topMostCategoryId = $categoryId;
187:         } else {
188:             $topMostCategoryId = $this->getTopMostCategoryId($category->get('parentid'));
189:         }
190: 
191:         return $topMostCategoryId;
192:     }
193: 
194:     /**
195:      * Returns an array with ordered cApiCategoryLanguage objects e.g.
196:      * for a breadcrumb.
197:      *
198:      * @param int $categoryId
199:      *                           Last category ID in list.
200:      * @param int $startingLevel [optional, default: 1]
201:      *                           Define here, at which level the list should start.
202:      * @param int $maxDepth      [optional, default: 20]
203:      *                           Amount of the max depth of categories.
204:      *
205:      * @return array
206:      *         Array with cApiCategoryLanguage objects
207:      *
208:      * @throws cException
209:      * @throws cInvalidArgumentException
210:      */
211:     public function getCategoryPath($categoryId, $startingLevel = 1, $maxDepth = 20) {
212:         $languageId = $this->getLanguageId();
213: 
214:         $categories = array();
215: 
216:         $categoryLanguage = new cApiCategoryLanguage();
217:         $categoryLanguage->loadByCategoryIdAndLanguageId($categoryId, $languageId);
218: 
219:         if ($this->hasCategoryAccess($categoryLanguage) === true) {
220:             $categories[] = $categoryLanguage;
221:         }
222: 
223:         $parentCategoryIds = $this->getParentCategoryIds($categoryId, $maxDepth);
224:         foreach ($parentCategoryIds as $parentCategoryId) {
225:             $categoryLanguage = new cApiCategoryLanguage();
226:             $categoryLanguage->loadByCategoryIdAndLanguageId($parentCategoryId, $languageId);
227: 
228:             if ($this->hasCategoryAccess($categoryLanguage) === true) {
229:                 $categories[] = $categoryLanguage;
230:             }
231:         }
232: 
233:         for ($removeCount = 2; $removeCount <= $startingLevel; $removeCount++) {
234:             array_pop($categories);
235:         }
236: 
237:         return array_reverse($categories);
238:     }
239: 
240:     /**
241:      * Fetch all parent category IDs of a given category.
242:      *
243:      * @param int $categoryId
244:      *         Base category to search on.
245:      * @param int $maxDepth [optional, default: 20]
246:      *         Amount of the max depth of categories.
247:      * @return array
248:      *         Array with parent category IDs.
249:      */
250:     public function getParentCategoryIds($categoryId, $maxDepth = 20) {
251:         $categoryIds = array();
252: 
253:         $nextCategoryId = $categoryId;
254: 
255:         $categoryCount = 1;
256:         while ($nextCategoryId != 0 && $categoryCount < $maxDepth) {
257:             $category = new cApiCategory($nextCategoryId);
258: 
259:             $nextCategoryId = $category->get('parentid');
260:             if ($nextCategoryId != 0) {
261:                 $categoryIds[] = $nextCategoryId;
262:             }
263:             $categoryCount++;
264:         }
265: 
266:         return $categoryIds;
267:     }
268: 
269:     /**
270:      * Fetchs the level of a category by a given category ID.
271:      *
272:      * @param int $categoryId
273:      *         Category ID to fetch the level of.
274:      * @return int
275:      *         category level
276:      *
277:      * @throws cDbException
278:      * @throws cException
279:      */
280:     public function getCategoryLevel($categoryId) {
281:         if (isset($this->_levelCache[$categoryId]) === false) {
282:             $categoryTree = new cApiCategoryTree();
283:             $categoryTree->loadBy("idcat", $categoryId);
284: 
285:             if ($categoryTree->isLoaded() === false) {
286:                 return -1;
287:             }
288: 
289:             $level = $categoryTree->get('level');
290: 
291:             $this->_levelCache[$categoryId] = $level;
292:         }
293: 
294:         return $this->_levelCache[$categoryId];
295:     }
296: 
297:     /**
298:      * Return the subcategories of the given category ID.
299:      * TODO: Use Generic DB instead of SQL queries
300:      *
301:      * @param int $categoryId
302:      *         ID of the category to load
303:      * @param int $depth
304:      *         the maximum depth
305:      * @return array
306:      *         array with subcategories
307:      *
308:      * @throws cDbException
309:      * @throws cException
310:      * @throws cInvalidArgumentException
311:      */
312:     public function getSubCategories($categoryId, $depth) {
313:         if ((int) $categoryId <= 0 || (int) $depth < 0) {
314:             return array();
315:         }
316:         $depth = (int) $depth;
317: 
318:         $cfg = cRegistry::getConfig();
319: 
320:         $categories = array();
321: 
322:         $clientId = $this->getClientId();
323:         $languageId = $this->getLanguageId();
324: 
325:         $selectFields = "cat_tree.idcat, cat_tree.level";
326: 
327:         $useAuthorization = ($this->_auth !== NULL);
328: 
329:         if ($useAuthorization == true) {
330:             $selectFields .= ", cat_lang.public, cat_lang.idcatlang";
331:         }
332: 
333:         $sqlSnippetPublic = "cat_lang.public = 1 AND";
334:         if ($useAuthorization == true) {
335:             $sqlSnippetPublic = "";
336:         }
337: 
338:         $sql = 'SELECT
339:                     ' . $selectFields . '
340:                 FROM
341:                     ' . $cfg['tab']['cat_tree'] . ' AS cat_tree,
342:                     ' . $cfg['tab']['cat'] . ' AS cat,
343:                     ' . $cfg['tab']['cat_lang'] . ' AS cat_lang
344:                 WHERE
345:                     cat_tree.idcat    = cat.idcat AND
346:                     cat.idcat    = cat_lang.idcat AND
347:                     cat.idclient = ' . $clientId . ' AND
348:                     cat_lang.idlang   = ' . $languageId . ' AND
349:                     cat_lang.visible  = 1 AND ' . $sqlSnippetPublic . '
350:                     cat.parentid = ' . $categoryId . '
351:                 ORDER BY
352:                     cat_tree.idtree';
353: 
354:         $db = cRegistry::getDb();
355:         $db->query($sql);
356: 
357:         while ($db->nextRecord()) {
358:             $catId = (int) $db->f('idcat');
359:             $catLevel = (int) $db->f('level');
360: 
361:             if ($depth > 0 && ($depth > ($catLevel))) {
362:                 $subCategories = $this->getSubCategories($catId, $depth);
363:             } else {
364:                 $subCategories = array();
365:             }
366:             $categoryLanguage = new cApiCategoryLanguage();
367:             $categoryLanguage->loadByCategoryIdAndLanguageId($catId, $languageId);
368: 
369:             $category = array();
370:             $category['item'] = $categoryLanguage;
371:             $category['idcat'] = $catId;
372:             $category['level'] = $catLevel;
373:             $category['subcats'] = $subCategories;
374: 
375:             $this->_levelCache[$catId] = $catLevel;
376: 
377:             if ($this->hasCategoryAccess($categoryLanguage) === true) {
378:                 $categories[] = $category;
379:             }
380:         }
381: 
382:         return $categories;
383:     }
384: 
385:     /**
386:      * Checks if set auth object has access to the specific category.
387:      *
388:      * @param cApiCategoryLanguage $categoryLanguage
389:      *         category language object
390:      *
391:      * @return bool
392:      *         result of access check
393:      *
394:      * @throws cDbException
395:      * @throws cException
396:      * @throws cInvalidArgumentException
397:      */
398:     public function hasCategoryAccess(cApiCategoryLanguage $categoryLanguage) {
399:         $useAuthorization = ($this->_auth !== NULL && $this->_fePermColl !== NULL);
400: 
401:         if ($useAuthorization === false) {
402:             return true;
403:         }
404: 
405:         $perm = cRegistry::getPerm();
406: 
407:         if (intval($categoryLanguage->getField('public')) == 1) {
408:             return true;
409:         }
410: 
411:         $clientId = $this->getClientId();
412:         $languageId = $this->getLanguageId();
413: 
414:         if ($perm->have_perm_client_lang($clientId, $languageId) == true) {
415:             return true;
416:         }
417: 
418:         foreach ($this->_feGroups as $feGroup) {
419:             if ($this->_fePermColl->checkPerm($feGroup, 'category', 'access', $categoryLanguage->getField('idcatlang'), true)) {
420:                 return true;
421:             }
422:         }
423: 
424:         return false;
425:     }
426: }
CMS CONTENIDO 4.10.0 API documentation generated by ApiGen 2.8.0