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
    • SIWECOS
    • SmartyWrapper
    • UrlShortener
    • UserForum
    • Workflow
  • PluginManager
  • Setup
    • Form
    • GUI
    • Helper
      • Environment
      • Filesystem
      • MySQL
      • PHP
    • UpgradeJob

Classes

  • cAjaxRequest
  • cAutoload
  • cBackend
  • cEffectiveSetting
  • cGuiScrollListAlltranslations
  • cHTMLValidator
  • cMailer
  • cModuleFileTranslation
  • cModuleHandler
  • cModuleSearch
  • cModuleSynchronizer
  • cModuleTemplateHandler
  • CodeMirror
  • cPasswordRequest
  • cPermission
  • cRegistry
  • cRights
  • cSystemPurge
  • cSystemtest
  • cTinymce4Configuration
  • cTinyMCE4Editor
  • cTinyMCEEditor
  • cWYSIWYGEditor
  • FrontendList
  • HtmlParser
  • TODOBackendList
  • TreeItem
  • UploadList
  • UploadSearchResultList

Functions

  • addArtspec
  • addSortImages
  • backToMainArea
  • buildArticleSelect
  • buildCategorySelect
  • buildCategorySelectRights
  • buildHeapTable
  • buildStackString
  • buildTree
  • buildUserOrGroupPermsFromRequest
  • callPluginStore
  • cApiCatGetLevelNode
  • cApiImageCheckCachedImageValidity
  • cApiImageCheckImageEditingPosibility
  • cApiImageCheckImageEditingPossibility
  • cApiImageGetCacheFileName
  • cApiImageGetTargetDimensions
  • cApiImageIsAnimGif
  • cApiImgScale
  • cApiImgScaleGetMD5CacheFile
  • cApiImgScaleHQ
  • cApiImgScaleImageMagick
  • cApiImgScaleLQ
  • cApiIsImageMagickAvailable
  • cApiStrCleanURLCharacters
  • cApiStrNormalizeLineEndings
  • cApiStrRecodeString
  • cApiStrReplaceDiacritics
  • cApiStrTrimAfterWord
  • cApiStrTrimHard
  • cApiStrTrimSentence
  • cDeprecated
  • cDie
  • cError
  • checkLangInClients
  • checkPathInformation
  • cInclude
  • compareUrlStrings
  • conChangeTemplateForCat
  • conCopyArticle
  • conCopyArtLang
  • conCopyContainerConf
  • conCopyContent
  • conCopyMetaTags
  • conCopyTemplateConfiguration
  • conCreateLocationString
  • conDeeperCategoriesArray
  • conDeleteart
  • conEditArt
  • conEditFirstTime
  • conFetchCategoryTree
  • conFlagOnOffline
  • conGenerateCode
  • conGenerateCodeForAllArts
  • conGenerateCodeForAllArtsInCategory
  • conGenerateCodeForAllartsUsingLayout
  • conGenerateCodeForAllartsUsingMod
  • conGenerateCodeForAllArtsUsingTemplate
  • conGenerateCodeForArtInAllCategories
  • conGenerateCodeForClient
  • conGenerateKeywords
  • conGetAvailableMetaTagTypes
  • conGetCategoryArticleId
  • conGetCategoryAssignments
  • conGetContainerConfiguration
  • conGetContentFromArticle
  • conGetHtmlTranslationTable
  • conGetMetaValue
  • conGetTemplateConfigurationIdForArticle
  • conGetTemplateConfigurationIdForCategory
  • conGetTopmostCat
  • conGetUniqueArticleUrlname
  • conGetUsedModules
  • conHtmlentities
  • conHtmlEntityDecode
  • conHtmlSpecialChars
  • conIsArticleUrlnameUnique
  • conIsLocked
  • conLock
  • conLockBulkEditing
  • conMakeArticleIndex
  • conMakeCatOnline
  • conMakeInlineScript
  • conMakeOnline
  • conMakeOnlineBulkEditing
  • conMakePublic
  • conMakeStart
  • conMoveArticles
  • conPhp54Check
  • conRemoveOldCategoryArticle
  • conSaveContentEntry
  • conSetCodeFlag
  • conSetCodeFlagBulkEditing
  • conSetMetaValue
  • conSetStartArticle
  • consoleLog
  • conSyncArticle
  • copyRightsForElement
  • createBulkEditingFunction
  • createRandomName
  • createRightsForElement
  • cWarning
  • dbGetColumns
  • dbGetIndexes
  • dbGetPrimaryKeyName
  • dbTableExists
  • dbUpgradeTable
  • defineIfNotDefined
  • deleteArtspec
  • deleteRightsForElement
  • deleteSystemProperty
  • displayDatetime
  • emptyLogFile
  • endAndLogTiming
  • extractNumber
  • generateDisplayFilePath
  • generateJs
  • getAllClientsAndLanguages
  • getArtLang
  • getArtspec
  • getAvailableContentTypes
  • getCanonicalDay
  • getCanonicalMonth
  • getDirectorySize
  • getEffectiveSetting
  • getEffectiveSettingsByType
  • getEncodingByLanguage
  • getFileInformation
  • getFileType
  • getGroupOrUserName
  • getIDForArea
  • getJsHelpContext
  • getLanguageNamesByClient
  • getLanguagesByClient
  • getmicrotime
  • getNamedFrame
  • getParentAreaId
  • getRightsList
  • getSearchResults
  • getStrExpandCollapseButton
  • getSystemProperties
  • getSystemPropertiesByType
  • getSystemProperty
  • getTemplateSelect
  • getUplExpandCollapseButton
  • htmldecode
  • htmlentities_iso88592
  • humanReadableSize
  • includePlugins
  • insertEmptyStrRow
  • ipMatch
  • isAlphanumeric
  • isArchive
  • isArtInMultipleUse
  • isFunctionDisabled
  • isGroup
  • isIPv4
  • isRunningFromWeb
  • isStartArticle
  • isUtf8
  • isValidMail
  • langActivateDeactivateLanguage
  • langDeleteLanguage
  • langEditLanguage
  • langGetTextDirection
  • langNewLanguage
  • langRenameLanguage
  • layDeleteLayout
  • layEditLayout
  • machineReadableSize
  • mailLogBulkEditingFunctions
  • mailLogDecodeAddresses
  • markSubMenuItem
  • mask
  • modDeleteModule
  • modEditModule
  • phpInfoToHtml
  • plugin_include
  • prCreateURLNameLocationString
  • prDeleteCacheFileContent
  • prGetCacheFileContent
  • prResolvePathViaCategoryNames
  • prResolvePathViaURLNames
  • prWriteCacheFileContent
  • recursiveCopy
  • removeFileInformation
  • renderBackendBreadcrumb
  • renderLabel
  • renderSelectProperty
  • renderTextProperty
  • saveGroupRights
  • saveRights
  • scanDirectory
  • scanPlugins
  • sendEncodingHeader
  • set_magic_quotes_gpc
  • setArtspecDefault
  • setArtspecOnline
  • setSystemProperty
  • showTree
  • startTiming
  • statCreateLocationString
  • statDisplayTopChooser
  • statDisplayYearlyTopChooser
  • statGetAvailableMonths
  • statGetAvailableYears
  • statResetStatistic
  • statsArchive
  • statsDisplayInfo
  • statsOverviewAll
  • statsOverviewTop
  • statsOverviewTopYear
  • statsOverviewYear
  • strAssignTemplate
  • strBuildSqlValues
  • strCheckAlias
  • strCheckTreeForErrors
  • strCopyCategory
  • strCopyTree
  • strDeeperCategoriesArray
  • strDeleteCategory
  • strHasArticles
  • strHasStartArticle
  • strMakePublic
  • strMakeVisible
  • strMoveCatTargetallowed
  • strMoveDownCategory
  • strMoveSubtree
  • strMoveUpCategory
  • strNewCategory
  • strNewTree
  • strNextBackwards
  • strNextDeeper
  • strNextDeeperAll
  • strNextPost
  • strOrderedPostTreeList
  • strRemakeTreeTable
  • strRenameCategory
  • strRenameCategoryAlias
  • strSortPrePost
  • strSyncCategory
  • systemHavePerm
  • tplAutoFillModules
  • tplBrowseLayoutForContainers
  • tplcfgDuplicate
  • tplDeleteTemplate
  • tplDuplicateTemplate
  • tplEditTemplate
  • tplGetContainerDefault
  • tplGetContainerMode
  • tplGetContainerName
  • tplGetContainerNumbersInLayout
  • tplGetContainerTypes
  • tplGetInUsedData
  • tplIsTemplateInUse
  • tplPreparseLayout
  • tplProcessSendContainerConfiguration
  • updateClientCache
  • updateFileInformation
  • uplCreateFriendlyName
  • uplDirectoryListRecursive
  • uplGetDirectoriesToExclude
  • uplGetFileExtension
  • uplGetFileIcon
  • uplGetFileTypeDescription
  • uplGetThumbnail
  • uplHasFiles
  • uplHasSubdirs
  • uplmkdir
  • uplRecursiveDBDirectoryList
  • uplRecursiveDirectoryList
  • uplRenameDirectory
  • uplSearch
  • uplSyncDirectory
  • uplSyncDirectoryDBFS
  • Overview
  • Package
  • Function
  • Tree
  • Deprecated
  • Todo
   1: <?php
   2: 
   3: /**
   4:  * This file contains the CONTENIDO structure/category functions.
   5:  *
   6:  * @package Core
   7:  * @subpackage Backend
   8:  * @author Olaf Niemann
   9:  * @author Murat Purc <murat@purc.de>
  10:  * @copyright four for business AG <www.4fb.de>
  11:  * @license http://www.contenido.org/license/LIZENZ.txt
  12:  * @link http://www.4fb.de
  13:  * @link http://www.contenido.org
  14:  */
  15: 
  16: defined('CON_FRAMEWORK') || die('Illegal call: Missing framework initialization - request aborted.');
  17: 
  18: cInclude('includes', 'functions.con.php');
  19: cInclude('includes', 'functions.database.php');
  20: 
  21: /**
  22:  * Creates a new category tree (root category item).
  23:  *
  24:  * @param string $catname
  25:  *         The category name
  26:  * @param string $catalias
  27:  *         Alias of category
  28:  * @param int    $visible
  29:  *         Flag about visible status
  30:  * @param int    $public
  31:  *         Flag about public status
  32:  * @param int    $iIdtplcfg
  33:  *         Id of template configuration
  34:  *
  35:  * @return int|NULL
  36:  *         of new generated category or nothing on failure
  37:  *
  38:  * @throws cDbException
  39:  * @throws cException
  40:  * @throws cInvalidArgumentException
  41:  */
  42: function strNewTree($catname, $catalias = '', $visible = 0, $public = 1, $iIdtplcfg = 0) {
  43:     global $client, $lang, $perm;
  44: 
  45:     // Flag to rebuild the category table
  46:     global $remakeCatTable, $remakeStrTable;
  47: 
  48:     if (trim($catname) == '') {
  49:         return;
  50:     }
  51: 
  52:     $catname = stripslashes($catname);
  53: 
  54:     $remakeCatTable = true;
  55:     $remakeStrTable = true;
  56: 
  57:     $catalias = trim($catalias);
  58:     if ($catalias == '') {
  59:         $catalias = trim($catname);
  60:     }
  61: 
  62:     $client = (int) $client;
  63:     $lang = (int) $lang;
  64: 
  65:     $visible = ($visible == 1) ? 1 : 0;
  66:     if (!$perm->have_perm_area_action('str', 'str_makevisible')) {
  67:         $visible = 0;
  68:     }
  69: 
  70:     $public = ($public == 1) ? 1 : 0;
  71:     if (!$perm->have_perm_area_action('str', 'str_makepublic')) {
  72:         $public = 1;
  73:     }
  74: 
  75:     // Get last category tree
  76:     $oCatColl = new cApiCategoryCollection();
  77:     $oLastCatTree = $oCatColl->fetchLastCategoryTree($client);
  78:     $lastCatTreeId = (is_object($oLastCatTree)) ? $oLastCatTree->get('idcat') : 0;
  79: 
  80:     // Insert new category tree
  81:     $oCatColl2 = new cApiCategoryCollection();
  82:     $oNewCat = $oCatColl2->create($client, 0, $lastCatTreeId, 0);
  83:     $newIdcat = $oNewCat->get('idcat');
  84:     $oldPostId = -1;
  85: 
  86:     // Update last category tree
  87:     if (is_object($oLastCatTree)) {
  88:         $oldPostId = $oLastCatTree->get('postid');
  89:         $oLastCatTree->set('postid', $newIdcat);
  90:         $oLastCatTree->store();
  91:     }
  92: 
  93:     $error = strCheckTreeForErrors();
  94:     if (!($error === false)) {
  95:         if ($oldPostId != -1) {
  96:             $oLastCatTree->set('postid', $oldPostId);
  97:             $oLastCatTree->store();
  98:         }
  99:         $oCatColl->delete($oNewCat->get('idcat'));
 100:         return;
 101:     }
 102: 
 103:     // Loop through languages
 104:     $aLanguages = array(
 105:         $lang
 106:     );
 107:     foreach ($aLanguages as $curLang) {
 108:         $name = $catname;
 109:         $urlname = conHtmlSpecialChars(cString::cleanURLCharacters($catalias), ENT_QUOTES);
 110: 
 111:         // Insert new category language entry
 112:         $oCatLangColl = new cApiCategoryLanguageCollection();
 113:         $oCatLangColl->create($newIdcat, $curLang, $name, $urlname, '', 0, $visible, $public, 0, '', 0);
 114: 
 115:         // Set correct rights for element
 116:         cRights::createRightsForElement('str', $newIdcat, $curLang);
 117:         cRights::createRightsForElement('con', $newIdcat, $curLang);
 118:     }
 119: 
 120:     // Assign template
 121:     strAssignTemplate($newIdcat, $client, $iIdtplcfg);
 122: 
 123:     return $newIdcat;
 124: }
 125: 
 126: /**
 127:  * Creates a new category.
 128:  *
 129:  * @param int    $parentid
 130:  *         Id of parent category
 131:  * @param string $catname
 132:  *         The category name
 133:  * @param bool   $remakeTree
 134:  *         Flag to rebuild category tree structure
 135:  * @param string $catalias
 136:  *         Alias of category
 137:  * @param int    $visible
 138:  *         Flag about visible status
 139:  * @param int    $public
 140:  *         Flag about public status
 141:  * @param int    $iIdtplcfg
 142:  *         Id of template configuration
 143:  *
 144:  * @return int|NULL
 145:  *         of new generated category or nothing on failure
 146:  *
 147:  * @throws cDbException
 148:  * @throws cException
 149:  * @throws cInvalidArgumentException
 150:  */
 151: function strNewCategory($parentid, $catname, $remakeTree = true, $catalias = '', $visible = 0, $public = 1, $iIdtplcfg = 0) {
 152:     global $client, $lang, $perm;
 153: 
 154:     // Flag to rebuild the category table
 155:     global $remakeCatTable, $remakeStrTable;
 156: 
 157:     $parentid = (int) $parentid;
 158: 
 159:     if (trim($catname) == '') {
 160:         return;
 161:     }
 162: 
 163:     $catname = stripslashes($catname);
 164: 
 165:     $remakeCatTable = true;
 166:     $remakeStrTable = true;
 167: 
 168:     $catalias = trim($catalias);
 169:     if ($catalias == '') {
 170:         $catalias = trim($catname);
 171:     }
 172: 
 173:     $client = (int) $client;
 174:     $lang = (int) $lang;
 175: 
 176:     $visible = ($visible == 1) ? 1 : 0;
 177:     if (!$perm->have_perm_area_action('str', 'str_makevisible')) {
 178:         $visible = 0;
 179:     }
 180: 
 181:     $public = ($public == 1) ? 1 : 0;
 182:     if (!$perm->have_perm_area_action('str', 'str_makepublic')) {
 183:         $public = 1;
 184:     }
 185: 
 186:     // Get previous category on same level, if exists
 187:     $oCatColl = new cApiCategoryCollection();
 188:     $oCatColl->select('parentid=' . $parentid . ' AND postid = 0 AND idclient = ' . $client);
 189:     $oPrevCat = $oCatColl->next();
 190:     $preIdcat = (is_object($oPrevCat)) ? $oPrevCat->get('idcat') : 0;
 191: 
 192:     // Insert new category tree
 193:     $oCatColl2 = new cApiCategoryCollection();
 194:     $oNewCat = $oCatColl2->create($client, $parentid, $preIdcat, 0);
 195:     $newIdcat = $oNewCat->get('idcat');
 196:     $oldPostId = -1;
 197: 
 198:     // Update previous category, if exists
 199:     if (is_object($oPrevCat)) {
 200:         $oldPostId = $oPrevCat->get('postid');
 201:         $oPrevCat->set('postid', $newIdcat);
 202:         $oPrevCat->set('lastmodified', date('Y-m-d H:i:s'));
 203:         $oPrevCat->store();
 204:     }
 205: 
 206:     $error = strCheckTreeForErrors();
 207: 
 208:     if (!($error === false)) {
 209:         if ($oldPostId != -1) {
 210:             $oPrevCat->set('postid', $oldPostId);
 211:             $oPrevCat->store();
 212:         }
 213:         $oCatColl2->delete($oNewCat->get('idcat'));
 214:         return;
 215:     }
 216: 
 217:     // Loop through languages
 218:     $aLanguages = [$lang];
 219: 
 220:     $catalias = conHtmlSpecialChars(cString::cleanURLCharacters($catalias), ENT_QUOTES);
 221: 
 222:     // Check alias name
 223:     $checkAlias = strCheckAlias($catalias);
 224:     if ($checkAlias === true) {
 225:         // $notification = new cGuiNotification();
 226:         // $notification->displayNotification(cGuiNotification::LEVEL_ERROR, i18n('This alias already exists in a other category. Please try with another alias name again.'));
 227:         // return;
 228:         $catalias = $catalias . $newIdcat;
 229:     }
 230: 
 231:     foreach ($aLanguages as $curLang) {
 232:         $name = $catname;
 233:         $urlname = $catalias;
 234: 
 235:         // Insert new category language entry
 236:         $oCatLangColl = new cApiCategoryLanguageCollection();
 237:         $oCatLangColl->create($newIdcat, $curLang, $name, $urlname, '', 0, $visible, $public, 0, '', 0);
 238: 
 239:         // Set correct rights for element
 240:         cRights::copyRightsForElement('str', $parentid, $newIdcat, $curLang);
 241:         cRights::copyRightsForElement('con', $parentid, $newIdcat, $curLang);
 242:     }
 243: 
 244:     if ($remakeTree == true) {
 245:         strRemakeTreeTable();
 246:     }
 247: 
 248:     // Assign template
 249:     strAssignTemplate($newIdcat, $client, $iIdtplcfg);
 250: 
 251:     return $newIdcat;
 252: }
 253: 
 254: /**
 255:  * This function check if the alias exists in this language in a other category
 256:  *
 257:  * @param string $catalias
 258:  *
 259:  * @return bool|void
 260:  *
 261:  * @throws cDbException
 262:  */
 263: function strCheckAlias($catalias) {
 264:     $lang = cRegistry::getLanguageId();
 265:     $catLangColl = new cApiCategoryLanguageCollection();
 266:     $result = $catLangColl->select("idlang = " . $lang . " AND urlname = '" . cSecurity::escapeString($catalias) . "'");
 267:     return $result;
 268: }
 269: 
 270: /**
 271:  * Builds ordered post string for a passed category
 272:  *
 273:  * @param int    $idcat
 274:  * @param string $poststring
 275:  *
 276:  * @return string
 277:  *
 278:  * @throws cDbException
 279:  * @throws cException
 280:  */
 281: function strOrderedPostTreeList($idcat, $poststring) {
 282:     $oCatColl = new cApiCategoryCollection();
 283:     $oCatColl->select('parentid = 0 AND preid = ' . (int) $idcat . ' AND idcat != 0');
 284:     if (($oCat = $oCatColl->next()) !== false) {
 285:         $postIdcat = $oCat->get('idcat');
 286:         $poststring = $poststring . ',' . $postIdcat;
 287:         $poststring = strOrderedPostTreeList($postIdcat, $poststring);
 288:     }
 289: 
 290:     return $poststring;
 291: }
 292: 
 293: /**
 294:  * Remakes the category tree structure in category tree table.
 295:  *
 296:  * It still uses manually build sql statements due to performance reasons.
 297:  *
 298:  * @throws cDbException
 299:  * @throws cException
 300:  */
 301: function strRemakeTreeTable() {
 302:     global $db, $client, $cfg;
 303: 
 304:     // Flag to rebuild the category table
 305:     global $remakeCatTable;
 306:     global $remakeStrTable;
 307: 
 308:     // Get all category ids
 309:     $oCatColl = new cApiCategoryCollection();
 310:     $idcats = $oCatColl->getCategoryIdsByClient($client);
 311:     if (0 === count($idcats)) {
 312:         // There are no categories to build the tree from!
 313:         return;
 314:     }
 315: 
 316:     $errors = strCheckTreeForErrors();
 317:     if (!($errors === false)) {
 318:         return;
 319:     }
 320: 
 321:     $remakeCatTable = true;
 322:     $remakeStrTable = true;
 323: 
 324:     // Empty category tree table having specific categories
 325:     $sql = 'DELETE FROM ' . $cfg['tab']['cat_tree'] . ' WHERE idcat IN (' . implode(', ', $idcats) . ')';
 326:     $db->query($sql);
 327: 
 328:     // Delete entries from category table having idcat = 0
 329:     // @todo: Check this, how it is possible to have an invalid entry with
 330:     // primary key = 0
 331:     $sql = 'DELETE FROM ' . $cfg['tab']['cat'] . ' WHERE idcat = 0';
 332:     $db->query($sql);
 333: 
 334:     // Delete entries from category language table having idcat = 0
 335:     // @todo: Check this, how it is possible to have an invalid entry with
 336:     // primary key = 0
 337:     $sql = 'DELETE FROM ' . $cfg['tab']['cat_lang'] . ' WHERE idcat = 0';
 338:     $db->query($sql);
 339: 
 340:     // Get all categories by client
 341:     $sql = "SELECT idcat, parentid, preid, postid FROM " . $cfg['tab']['cat'] . " WHERE idclient = " . (int) $client . " ORDER BY parentid ASC, preid ASC, postid ASC";
 342:     $aCategories = array();
 343:     $db->query($sql);
 344:     while ($db->nextRecord()) {
 345:         $rs = $db->toArray();
 346:         if (!isset($aCategories[$rs['parentid']])) {
 347:             $aCategories[$rs['parentid']] = array();
 348:         }
 349:         $aCategories[$rs['parentid']][$rs['idcat']] = $rs;
 350:     }
 351: 
 352:     // Build INSERT statement
 353:     $sInsertQuery = "INSERT INTO " . $cfg['tab']['cat_tree'] . " (idcat, level) VALUES ";
 354:     $sInsertQuery = strBuildSqlValues($aCategories[0], $sInsertQuery, $aCategories);
 355:     $sInsertQuery = rtrim($sInsertQuery, " ,");
 356: 
 357:     // Lock db table and execute INSERT query
 358:     $db->query($sInsertQuery);
 359: }
 360: 
 361: /**
 362:  * Sorts passed assoziative categories array.
 363:  *
 364:  * @todo Check logic, move sorting to db layer, if possible!
 365:  * @param array $arr
 366:  * @return array
 367:  */
 368: function strSortPrePost($arr) {
 369:     $firstElement = NULL;
 370:     foreach ($arr as $row) {
 371:         if ($row['preid'] == 0) {
 372:             $firstElement = $row['idcat'];
 373:         }
 374:     }
 375: 
 376:     $curId = $firstElement;
 377:     $array = array();
 378: 
 379:     // Test for a last element in the category list
 380:     $fine = false;
 381:     foreach ($arr as $row) {
 382:         if ($row['postid'] == 0) {
 383:             $fine = true;
 384:             break;
 385:         }
 386:     }
 387:     if (!$fine) {
 388:         die(); // we already displayed an error message through strCheckTree
 389:     }
 390: 
 391:     while ($curId != 0) {
 392:         $array[] = $arr[$curId];
 393:         $curId = $arr[$curId]['postid'];
 394:     }
 395: 
 396:     return $array;
 397: }
 398: 
 399: /**
 400:  * Builds values part of the SQL used to recreate the category tree table
 401:  *
 402:  * @param array $aCats
 403:  *         Assoziative categories array or something else, but what?
 404:  * @param string $sInsertQuery
 405:  *         The insert statement
 406:  * @param array $aAllCats
 407:  *         Assoziative categories array holding the complete category structure
 408:  * @param int $iLevel
 409:  *         Category level
 410:  * @return string
 411:  */
 412: function strBuildSqlValues($aCats, $sInsertQuery, &$aAllCats, $iLevel = 0) {
 413:     if (is_array($aCats)) {
 414:         $aCats = strSortPrePost($aCats);
 415:         foreach ($aCats as $aCat) {
 416:             $sInsertQuery .= '(' . (int) $aCat['idcat'] . ', ' . (int) $iLevel . '), ';
 417:             if (isset($aAllCats[$aCat['idcat']]) && is_array($aAllCats[$aCat['idcat']])) {
 418:                 $iSubLevel = $iLevel + 1;
 419:                 $sInsertQuery = strBuildSqlValues($aAllCats[$aCat['idcat']], $sInsertQuery, $aAllCats, $iSubLevel);
 420:             }
 421:         }
 422:     }
 423:     return $sInsertQuery;
 424: }
 425: 
 426: /**
 427:  * Returns id of next deeper category.
 428:  *
 429:  * @param int  $idcat
 430:  *         Category id to check next deeper item
 431:  * @param bool $ignoreLang
 432:  *         Flag to check for existing entry in category language table
 433:  *
 434:  * @return int
 435:  *
 436:  * @throws cDbException
 437:  */
 438: function strNextDeeper($idcat, $ignoreLang = false) {
 439:     $lang = cRegistry::getLanguageId();
 440: 
 441:     $languageId = (true == $ignoreLang) ? NULL : $lang;
 442:     $oCatColl = new cApiCategoryCollection();
 443:     return $oCatColl->getFirstChildCategoryId($idcat, $languageId);
 444: }
 445: 
 446: /**
 447:  * Checks, if passed category contains any articles
 448:  *
 449:  * @param int $idcat
 450:  *         ID of category
 451:  *
 452:  * @return bool
 453:  *
 454:  * @throws cDbException
 455:  */
 456: function strHasArticles($idcat) {
 457:     $lang = cRegistry::getLanguageId();
 458: 
 459:     $oCatArtColl = new cApiCategoryArticleCollection();
 460:     return $oCatArtColl->getHasArticles($idcat, $lang);
 461: }
 462: 
 463: /**
 464:  * Returns next post category id
 465:  *
 466:  * @param int $idcat
 467:  *         ID of category
 468:  *
 469:  * @return int
 470:  *
 471:  * @throws cDbException
 472:  */
 473: function strNextPost($idcat) {
 474:     $oCatColl = new cApiCategoryCollection();
 475:     return $oCatColl->getNextPostCategoryId($idcat);
 476: }
 477: 
 478: /**
 479:  * Returns next backwards category id
 480:  *
 481:  * @param int $idcat
 482:  *         ID of category
 483:  *
 484:  * @return int
 485:  *
 486:  * @throws cDbException
 487:  */
 488: function strNextBackwards($idcat) {
 489:     $oCatColl = new cApiCategoryCollection();
 490:     return $oCatColl->getParentsNextPostCategoryId($idcat);
 491: }
 492: 
 493: /**
 494:  * Returns list of child categories.
 495:  *
 496:  * @param int  $idcat
 497:  * @param bool $ignoreLang
 498:  *
 499:  * @return array
 500:  *
 501:  * @throws cDbException
 502:  *
 503:  * @global int $lang
 504:  */
 505: function strNextDeeperAll($idcat, $ignoreLang = false) {
 506:     global $lang;
 507: 
 508:     $languageId = (true == $ignoreLang) ? NULL : $lang;
 509:     $oCatColl = new cApiCategoryCollection();
 510:     return $oCatColl->getAllChildCategoryIds($idcat, $languageId);
 511: }
 512: 
 513: /**
 514:  * Renames a category
 515:  *
 516:  * @param int    $idcat
 517:  *         Category id
 518:  * @param int    $lang
 519:  *         Language id
 520:  * @param string $newCategoryName
 521:  *         New category name
 522:  * @param string $newCategoryAlias
 523:  *         New category alias
 524:  *
 525:  * @throws cDbException
 526:  * @throws cException
 527:  * @throws cInvalidArgumentException
 528:  */
 529: function strRenameCategory($idcat, $lang, $newCategoryName, $newCategoryAlias) {
 530:     if (trim($newCategoryName) == '') {
 531:         return;
 532:     }
 533: 
 534:     $oCatLang = new cApiCategoryLanguage();
 535:     if (!$oCatLang->loadByCategoryIdAndLanguageId($idcat, $lang)) {
 536:         // Couldn't load category language
 537:         return;
 538:     }
 539: 
 540:     $oldData = array(
 541:         'idcat' => $oCatLang->get('idcat'),
 542:         'name' => $oCatLang->get('name'),
 543:         'urlname' => $oCatLang->get('urlname')
 544:     );
 545: 
 546:     $name = stripslashes($newCategoryName);
 547:     $urlName = (trim($newCategoryAlias) != '') ? trim($newCategoryAlias) : $newCategoryName;
 548: 
 549:     if (trim($newCategoryAlias) != '') {
 550:         // overfluous assignment
 551:         // if ($oCatLang->get('urlname') != $newCategoryAlias) {
 552:         // $urlName = $newCategoryAlias;
 553:         // }
 554:         cInclude('includes', 'functions.pathresolver.php');
 555:         $client = cRegistry::getClientId();
 556:         prDeleteCacheFileContent($client, $lang);
 557:     }
 558: 
 559:     $oCatLang->set('name', $name);
 560:     $oCatLang->set('urlname', $urlName);
 561:     $oCatLang->set('lastmodified', date('Y-m-d H:i:s'));
 562:     $oCatLang->store();
 563: 
 564:     $newData = array(
 565:         'idcat' => $idcat,
 566:         'name' => $name,
 567:         'urlname' => $urlName
 568:     );
 569: 
 570:     cApiCecHook::execute('Contenido.Category.strRenameCategory', $newData, $oldData);
 571: }
 572: 
 573: /**
 574:  * Renames a category alias.
 575:  *
 576:  * @param int    $idcat
 577:  *         Category id
 578:  * @param int    $lang
 579:  *         Language id
 580:  * @param string $newcategoryalias
 581:  *         New category alias
 582:  *
 583:  * @throws cDbException
 584:  * @throws cException
 585:  * @throws cInvalidArgumentException
 586:  */
 587: function strRenameCategoryAlias($idcat, $lang, $newcategoryalias) {
 588:     $oCatLang = new cApiCategoryLanguage();
 589:     if (!$oCatLang->loadByCategoryIdAndLanguageId($idcat, $lang)) {
 590:         // Couldn't load category language
 591:         return;
 592:     }
 593: 
 594:     $oldData = array(
 595:         'idcat' => $oCatLang->get('idcat'),
 596:         'urlname' => $oCatLang->get('urlname')
 597:     );
 598: 
 599:     if (trim($newcategoryalias) == '') {
 600:         // Use categoryname as default -> get it escape it save it as urlname
 601:         $newcategoryalias = $oCatLang->get('name');
 602:     }
 603: 
 604:     $oCatLang->set('urlname', $newcategoryalias);
 605:     $oCatLang->set('lastmodified', date('Y-m-d H:i:s'));
 606:     $oCatLang->store();
 607: 
 608:     cInclude('includes', 'functions.pathresolver.php');
 609:     $client = cRegistry::getClientId();
 610:     prDeleteCacheFileContent($client, $lang);
 611: 
 612:     $newData = array(
 613:         'idcat' => $idcat,
 614:         'urlname' => $newcategoryalias
 615:     );
 616: 
 617:     cApiCecHook::execute('Contenido.Category.strRenameCategoryAlias', $newData, $oldData);
 618: }
 619: 
 620: /**
 621:  * Sets the visible status of the category and its childs
 622:  *
 623:  * @param int $idcat
 624:  *         Category id
 625:  * @param int $lang
 626:  *         Language id
 627:  * @param int $visible
 628:  *         Visible status
 629:  *
 630:  * @throws cDbException
 631:  * @throws cException
 632:  * @throws cInvalidArgumentException
 633:  */
 634: function strMakeVisible($idcat, $lang, $visible) {
 635:     $visible = (int) $visible;
 636:     $lang = (int) $lang;
 637: 
 638:     $categories = strDeeperCategoriesArray($idcat);
 639:     foreach ($categories as $value) {
 640:         $oCatLang = new cApiCategoryLanguage();
 641:         $oCatLang->loadByCategoryIdAndLanguageId($value, $lang);
 642:         $oCatLang->set('visible', $visible);
 643:         $oCatLang->set('lastmodified', date('Y-m-d H:i:s'));
 644:         $oCatLang->store();
 645:     }
 646: 
 647:     if (cRegistry::getConfigValue('pathresolve_heapcache') == true && $visible != 0) {
 648:         $oPathresolveCacheColl = new cApiPathresolveCacheCollection();
 649:         $oPathresolveCacheColl->deleteByCategoryAndLanguage($idcat, $lang);
 650:     }
 651: }
 652: 
 653: /**
 654:  * Sets the public status of the given category and its children
 655:  * for the given language.
 656:  *
 657:  * This is almost the same function as conMakePublic.
 658:  *
 659:  * @param int $idcat
 660:  *         category id
 661:  * @param int $lang
 662:  *         language id
 663:  * @param int $public
 664:  *         public status of the article to set
 665:  *
 666:  * @throws cDbException
 667:  * @throws cException
 668:  * @throws cInvalidArgumentException
 669:  */
 670: function strMakePublic($idcat, $lang, $public) {
 671: 
 672:     foreach (strDeeperCategoriesArray($idcat) as $tmpIdcat) {
 673:         $oCatLang = new cApiCategoryLanguage();
 674:         $oCatLang->loadByCategoryIdAndLanguageId($tmpIdcat, $lang);
 675:         $oCatLang->set('public', $public);
 676:         $oCatLang->set('lastmodified', date('Y-m-d H:i:s'));
 677:         $oCatLang->store();
 678:     }
 679: 
 680: }
 681: 
 682: /**
 683:  * Return a list of idcats of all scions of given category.
 684:  *
 685:  * @param int $idcat
 686:  *         category ID to start at
 687:  *
 688:  * @return array
 689:  *         idcats of all scions
 690:  *
 691:  * @throws cDbException
 692:  */
 693: function strDeeperCategoriesArray($idcat) {
 694:     global $client;
 695: 
 696:     $coll = new cApiCategoryCollection();
 697:     $idcats = $coll->getAllCategoryIdsRecursive($idcat, $client);
 698: 
 699:     return $idcats;
 700: }
 701: 
 702: /**
 703:  * Deletes the category and its template configurations.
 704:  *
 705:  * Only categories having no child categories and having no articles will be
 706:  * deleted!
 707:  *
 708:  * @param int $idcat
 709:  *         Id of category to delete
 710:  *
 711:  * @return void|string
 712:  *
 713:  * @throws cDbException
 714:  * @throws cException
 715:  * @throws cInvalidArgumentException
 716:  */
 717: function strDeleteCategory($idcat) {
 718:     $lang = cRegistry::getLanguageId();
 719: 
 720:     // Flag to rebuild the category table
 721:     global $remakeCatTable, $remakeStrTable;
 722: 
 723:     if (strNextDeeper($idcat)) {
 724:         // Category has subcategories
 725:         return '0201';
 726:     } elseif (strHasArticles($idcat)) {
 727:         // Category has articles
 728:         return '0202';
 729:     }
 730: 
 731:     $remakeCatTable = true;
 732:     $remakeStrTable = true;
 733: 
 734:     // Load category language
 735:     $oCatLang = new cApiCategoryLanguage();
 736:     $oCatLang->loadByCategoryIdAndLanguageId($idcat, $lang);
 737: 
 738:     if ($oCatLang->isLoaded()) {
 739:         // Delete template configuration (deletes also all container
 740:         // configurations)
 741:         $oTemplateConfigColl = new cApiTemplateConfigurationCollection();
 742:         $oTemplateConfigColl->delete($oCatLang->get('idtplcfg'));
 743: 
 744:         // Delete category language
 745:         $oCatLangColl = new cApiCategoryLanguageCollection();
 746:         $oCatLangColl->delete($oCatLang->get('idcatlang'));
 747:     }
 748: 
 749:     // Are there any additional entries for other languages?
 750:     $oCatLangColl = new cApiCategoryLanguageCollection();
 751:     $oCatLangColl->select('idcat = ' . (int) $idcat);
 752:     if (($oCatLang = $oCatLangColl->next()) !== false) {
 753:         // More languages found, delete rights for current category
 754:         cRights::deleteRightsForElement('str', $idcat, $lang);
 755:         cRights::deleteRightsForElement('con', $idcat, $lang);
 756:         return;
 757:     }
 758: 
 759:     // Load category
 760:     $oCat = new cApiCategory((int) $idcat);
 761:     $preid = (int) $oCat->get('preid');
 762:     $postid = (int) $oCat->get('postid');
 763: 
 764:     // Update pre cat, set it to new postid
 765:     if ($preid != 0) {
 766:         $oPreCat = new cApiCategory($preid);
 767:         $oPreCat->set('postid', $postid);
 768:         $oPreCat->store();
 769:     }
 770: 
 771:     // Update post cat, set it to new preid
 772:     if ($postid != 0) {
 773:         $oPostCat = new cApiCategory($postid);
 774:         $oPostCat->set('preid', $preid);
 775:         $oPostCat->store();
 776:     }
 777: 
 778:     $error = strCheckTreeForErrors(array(), array(
 779:         $idcat
 780:     ));
 781:     if (!($error === false)) {
 782:         if ($preid != 0) {
 783:             $oPreCat = new cApiCategory($preid);
 784:             $oPreCat->set('postid', $idcat);
 785:             $oPreCat->store();
 786:         }
 787:         if ($postid != 0) {
 788:             $oPostCat = new cApiCategory($postid);
 789:             $oPostCat->set('preid', $idcat);
 790:             $oPostCat->store();
 791:         }
 792:         return '0600';
 793:     }
 794: 
 795:     // Delete category
 796:     $oCatColl = new cApiCategoryCollection();
 797:     $oCatColl->deleteBy('idcat', (int) $idcat);
 798: 
 799:     $oCatLangColl = new cApiCategoryLanguageCollection();
 800:     $oCatLangColl->select('idcat = ' . (int) $idcat);
 801:     if (($oCatLang = $oCatLangColl->next()) !== false) {
 802:         // Delete template configuration (deletes also all container
 803:         // configurations)
 804:         $oTemplateConfigColl = new cApiTemplateConfigurationCollection();
 805:         $oTemplateConfigColl->delete($oCatLang->get('idtplcfg'));
 806:     }
 807: 
 808:     // Delete category language entry by category id
 809:     $oCatLangColl->resetQuery();
 810:     $oCatLangColl->deleteBy('idcat', (int) $idcat);
 811: 
 812:     // Delete category tree entry by category id
 813:     $oCatTreeColl = new cApiCategoryTreeCollection();
 814:     $oCatTreeColl->deleteBy('idcat', (int) $idcat);
 815: 
 816:     // Delete rights for element
 817:     cRights::deleteRightsForElement('str', $idcat);
 818:     cRights::deleteRightsForElement('con', $idcat);
 819: }
 820: 
 821: /**
 822:  * Moves a category upwards.
 823:  *
 824:  * @param int $idcat
 825:  *         Id of category to move upwards
 826:  *
 827:  * @throws cDbException
 828:  * @throws cException
 829:  */
 830: function strMoveUpCategory($idcat) {
 831:     // Flag to rebuild the category table and initializing notification variable
 832:     global $remakeCatTable, $remakeStrTable, $notification;
 833: 
 834:     // Load current category
 835:     $oCat = new cApiCategory();
 836:     $oCat->loadByPrimaryKey((int) $idcat);
 837:     $preid = $oCat->get('preid');
 838:     $postid = $oCat->get('postid');
 839: 
 840:     if (0 == $preid) {
 841:         // No preid, no way to move up
 842:         return;
 843:     }
 844: 
 845:     $remakeCatTable = true;
 846:     $remakeStrTable = true;
 847: 
 848:     // Load previous category
 849:     $oPreCat = new cApiCategory();
 850:     $oPreCat->loadByPrimaryKey((int) $preid);
 851:     $prePreid = $oPreCat->get('preid');
 852:     $preIdcat = $oPreCat->get('idcat');
 853: 
 854:     // Load category before previous category
 855:     $oPrePreCat = new cApiCategory();
 856:     if ((int) $prePreid > 0) {
 857:         $oPrePreCat->loadByPrimaryKey((int) $prePreid);
 858:     }
 859: 
 860:     // Load post category
 861:     $oPostCat = new cApiCategory();
 862:     if ((int) $postid > 0) {
 863:         $oPostCat->loadByPrimaryKey((int) $postid);
 864:     }
 865: 
 866:     $updateCats = array();
 867: 
 868:     // Update category before previous, if exists
 869:     if ($oPrePreCat->isLoaded()) {
 870:         $oPrePreCat->set('postid', $idcat);
 871:         $updateCats[$prePreid] = $oPrePreCat;
 872:     }
 873: 
 874:     // Update previous category
 875:     $oPreCat->set('preid', $idcat);
 876:     $oPreCat->set('postid', $postid);
 877:     $updateCats[$preid] = $oPreCat;
 878: 
 879:     // Update current category
 880:     $oCat->set('preid', $prePreid);
 881:     $oCat->set('postid', $preid);
 882:     $updateCats[$idcat] = $oCat;
 883: 
 884:     // Update post category, if exists!
 885:     $oPostCat->set('preid', $preIdcat);
 886:     $updateCats[$postid] = $oPostCat;
 887: 
 888:     $error = strCheckTreeForErrors($updateCats);
 889:     if ($error === false) {
 890:         foreach ($updateCats as $cat) {
 891:             $cat->store();
 892:         }
 893:     } else {
 894:         $string = '';
 895:         foreach ($error as $msg) {
 896:             $string .= $msg . '<br>';
 897:         }
 898:         $notification->displayNotification(cGuiNotification::LEVEL_WARNING, $msg . '<br><br>' . i18n('Something went wrong while trying to perform this operation. Please try again.'));
 899:         return;
 900:     }
 901: }
 902: 
 903: /**
 904:  * Moves a category downwards.
 905:  *
 906:  * @param int $idcat
 907:  *         Id of category to move downwards
 908:  *
 909:  * @throws cDbException
 910:  * @throws cException
 911:  */
 912: function strMoveDownCategory($idcat) {
 913:     // Flag to rebuild the category table and initializing notification variable
 914:     global $remakeCatTable, $remakeStrTable, $notification;
 915: 
 916:     // Load current category
 917:     $oCat = new cApiCategory();
 918:     $oCat->loadByPrimaryKey((int) $idcat);
 919:     $preid = $oCat->get('preid');
 920:     $postid = $oCat->get('postid');
 921: 
 922:     if (0 == $postid) {
 923:         // No post, no way to move down
 924:         return;
 925:     }
 926: 
 927:     $remakeCatTable = true;
 928:     $remakeStrTable = true;
 929: 
 930:     // Load previous category
 931:     $oPreCat = new cApiCategory();
 932:     if ((int) $preid > 0) {
 933:         $oPreCat->loadByPrimaryKey((int) $preid);
 934:         $preIdcat = (int) $oPreCat->get('idcat');
 935:     } else {
 936:         $preIdcat = 0;
 937:     }
 938: 
 939:     // Load post category
 940:     $oPostCat = new cApiCategory();
 941:     $oPostCat->loadByPrimaryKey((int) $postid);
 942:     $postIdcat = $oPostCat->get('idcat');
 943:     $postPostid = $oPostCat->get('postid');
 944: 
 945:     $updateCats = array();
 946: 
 947:     if ($preIdcat != 0) {
 948:         // Update previous category, if exists
 949:         $oPreCat->set('postid', (int) $postIdcat);
 950:         $updateCats[$preIdcat] = $oPreCat;
 951:     }
 952: 
 953:     // Update current category
 954:     $oCat->set('preid', $postid);
 955:     $oCat->set('postid', $postPostid);
 956:     $updateCats[$idcat] = $oCat;
 957: 
 958:     // Update post category
 959:     $oPostCat->set('preid', $preIdcat);
 960:     $oPostCat->set('postid', $idcat);
 961:     $updateCats[$postid] = $oPostCat;
 962: 
 963:     if ($postPostid != 0) {
 964:         // Update post post category, if exists
 965:         $oPostPostCat = new cApiCategory($postPostid);
 966:         $oPostPostCat->set('preid', $idcat);
 967:         $updateCats[$postPostid] = $oPostPostCat;
 968:     }
 969: 
 970:     $error = strCheckTreeForErrors($updateCats);
 971:     if ($error === false) {
 972:         foreach ($updateCats as $cat) {
 973:             $cat->store();
 974:         }
 975:     } else {
 976:         $string = '';
 977:         foreach ($error as $msg) {
 978:             $string .= $msg . '<br>';
 979:         }
 980:         $notification->displayNotification(cGuiNotification::LEVEL_WARNING, $msg . '<br><br>' . i18n('Something went wrong while trying to perform this operation. Please try again.'));
 981:         return;
 982:     }
 983: }
 984: 
 985: /**
 986:  * Moves a subtree to another destination.
 987:  *
 988:  * @param int $idcat
 989:  *         Id of category
 990:  * @param int $newParentId
 991:  *         Id of destination parent category
 992:  * @param int $newPreId
 993:  *         Id of new previous category
 994:  * @param int $newPostId
 995:  *         Id of new post category
 996:  *
 997:  * @return bool
 998:  *
 999:  * @throws cDbException
1000:  * @throws cException
1001:  */
1002: function strMoveSubtree($idcat, $newParentId, $newPreId = NULL, $newPostId = NULL) {
1003:     global $movesubtreeidcat, $notification;
1004: 
1005:     $idlang = cRegistry::getLanguageId();
1006:     $cat = new cApiCategoryCollection();
1007:     $children = $cat->getAllChildCategoryIds($idcat, $idlang);
1008: 
1009:     foreach ($children as $category) {
1010:         // avoids to move the main tree node in sub node of the same tree
1011:         if ($category == $newParentId) {
1012:             return false;
1013:         }
1014:     }
1015: 
1016:     if ($idcat == $newParentId) {
1017:         return false;
1018:     }
1019: 
1020:     if ($newParentId == 0 && $newPreId == 0) {
1021:         return false;
1022:     }
1023:     // if (!isset($newPostId)) {
1024:     //     return false;
1025:     // }
1026:     // flag to rebuild the category table
1027:     global $remakeCatTable, $remakeStrTable;
1028: 
1029:     $remakeCatTable = true;
1030:     $remakeStrTable = true;
1031: 
1032:     // check the post ID parameter
1033:     if (is_null($newPostId)) {
1034:         $newPostId = 0;
1035:     }
1036: 
1037:     if ($newParentId == -1) {
1038:         // stop moving the category without actually moving it
1039:         $movesubtreeidcat = 0;
1040:     } else if (is_null($newParentId)) {
1041:         // start moving the category withour moving it yet
1042:         $movesubtreeidcat = $idcat;
1043:     } else {
1044:         // move the category with the ID idcat to the category newParentId
1045:         $category = new cApiCategory($idcat);
1046:         $oldPreId = $category->get('preid');
1047:         $oldPostId = $category->get('postid');
1048:         $oldParentId = $category->get('parentid');
1049: 
1050:         $updateCats = array();
1051: 
1052:         // update old predecessor (pre) category
1053:         if ($oldPreId != 0) {
1054:             $oldPreCategory = new cApiCategory($oldPreId);
1055:             $oldPreCategory->set('postid', $oldPostId);
1056:             $updateCats[$oldPreId] = $oldPreCategory;
1057:         }
1058: 
1059:         // update old follower (post) category
1060:         if ($oldPostId != 0) {
1061:             if (isset($updateCats[$oldPostId])) {
1062:                 $updateCats[$oldPostId]->set('preid', $oldPreId);
1063:             } else {
1064:                 $oldPostCategory = new cApiCategory($oldPostId);
1065:                 $oldPostCategory->set('preid', $oldPreId);
1066:                 $updateCats[$oldPostId] = $oldPostCategory;
1067:             }
1068:         }
1069: 
1070:         // update new predecessor (pre) category
1071:         if (is_null($newPreId)) {
1072:             // if no new pre ID has been given, use the last category in the
1073:             // given parent category
1074:             $categoryCollection = new cApiCategoryCollection();
1075:             $categoryCollection->select("parentid = " . $newParentId . " AND postid = 0");
1076:             $newPreCategory = $categoryCollection->next();
1077:             if($newPreCategory != null) {
1078:                 $newPreId = $newPreCategory->get('idcat');
1079:                 $newPreCategory->set('postid', $idcat);
1080:                 $updateCats[$newPreId] = $newPreCategory;
1081:             }
1082:         } else {
1083:             if (isset($updateCats[$newPreId])) {
1084:                 $updateCats[$newPreId]->set('postid', $idcat);
1085:             } else {
1086:                 $newPreCategory = new cApiCategory($newPreId);
1087:                 $newPreCategory->set('postid', $idcat);
1088:                 $updateCats[$newPreId] = $newPreCategory;
1089:                 $newPreId = $newPreCategory->get('idcat');
1090:             }
1091:         }
1092: 
1093:         // update new follower (post) category
1094:         if ($newPostId != 0) {
1095:             if (isset($updateCats[$newPostId])) {
1096:                 $updateCats[$newPostId]->set('preid', $idcat);
1097:             } else {
1098:                 $newPostCategory = new cApiCategory($newPostId);
1099:                 $newPostCategory->set('preid', $idcat);
1100:                 $updateCats[$newPostId] = $newPostCategory;
1101:             }
1102:         }
1103: 
1104:         // Update current category
1105:         $category->set('parentid', $newParentId);
1106:         $category->set('preid', $newPreId);
1107:         $category->set('postid', $newPostId);
1108:         $updateCats[$idcat] = $category;
1109: 
1110:         $error = strCheckTreeForErrors($updateCats);
1111:         if ($error === false) {
1112:             foreach ($updateCats as $cat) {
1113:                 $cat->store();
1114:             }
1115:         } else {
1116:             $string = '';
1117:             foreach ($error as $msg) {
1118:                 $string .= $msg . '<br>';
1119:             }
1120:             $notification->displayNotification(cGuiNotification::LEVEL_WARNING, $msg . '<br><br>' . i18n('Something went wrong while trying to perform this operation. Please try again.'));
1121:             return false;
1122:         }
1123: 
1124:         $movesubtreeidcat = 0;
1125:     }
1126: 
1127:     $sess = cRegistry::getSession();
1128:     $sess->register('movesubtreeidcat');
1129:     $sess->freeze();
1130: }
1131: 
1132: /**
1133:  * Checks if category is movable.
1134:  *
1135:  * @param int $idcat
1136:  *         Id of category to move
1137:  * @param int $source
1138:  *         Id of source category
1139:  * @return bool
1140:  */
1141: function strMoveCatTargetallowed($idcat, $source) {
1142:     return ($idcat == $source) ? 0 : 1;
1143: }
1144: 
1145: /**
1146:  * Synchronizes a category from one language to another language.
1147:  *
1148:  * @param int  $idcatParam
1149:  *         Id of category to synchronize
1150:  * @param int  $sourcelang
1151:  *         Id of source language
1152:  * @param int  $targetlang
1153:  *         Id of target language
1154:  * @param bool $bMultiple
1155:  *         Flag to synchronize child languages
1156:  *
1157:  * @return bool
1158:  *
1159:  * @throws cDbException
1160:  * @throws cException
1161:  * @throws cInvalidArgumentException
1162:  */
1163: function strSyncCategory($idcatParam, $sourcelang, $targetlang, $bMultiple = false) {
1164:     $bMultiple = (bool) $bMultiple;
1165: 
1166:     $aCatArray = array();
1167:     if ($bMultiple == true) {
1168:         $aCatArray = strDeeperCategoriesArray($idcatParam);
1169:     } else {
1170:         $aCatArray[] = $idcatParam;
1171:     }
1172: 
1173:     foreach ($aCatArray as $idcat) {
1174:         // Check if category for target language already exists
1175:         $oCatLang = new cApiCategoryLanguage();
1176:         if ($oCatLang->loadByCategoryIdAndLanguageId($idcat, $targetlang)) {
1177:             return false;
1178:         }
1179: 
1180:         // Get source category language
1181:         $oCatLang = new cApiCategoryLanguage();
1182:         if ($oCatLang->loadByCategoryIdAndLanguageId($idcat, $sourcelang)) {
1183:             $aRs = $oCatLang->toArray();
1184: 
1185:             // Copy the template configuration, if exists
1186:             $newidtplcfg = ($aRs['idtplcfg'] != 0) ? tplcfgDuplicate($aRs['idtplcfg']) : 0;
1187: 
1188:             $visible = 0;
1189:             $startidartlang = 0;
1190:             $urlpath = '';
1191: 
1192:             $oCatLangColl = new cApiCategoryLanguageCollection();
1193:             $oNewCatLang = $oCatLangColl->create($aRs['idcat'], $targetlang, $aRs['name'], $aRs['urlname'], $urlpath, $newidtplcfg, $visible, $aRs['public'], $aRs['status'], $aRs['author'], $startidartlang, $aRs['created'], $aRs['lastmodified']);
1194: 
1195:             // Execute CEC hook
1196:             $param = $aRs;
1197:             $param['idlang'] = $targetlang;
1198:             $param['idtplcfg'] = (int) $newidtplcfg;
1199:             $param['visible'] = $visible;
1200:             cApiCecHook::execute('Contenido.Category.strSyncCategory_Loop', $param);
1201: 
1202:             // Set correct rights for element
1203:             cRights::createRightsForElement('str', $idcat, $targetlang);
1204:             cRights::createRightsForElement('con', $idcat, $targetlang);
1205:         }
1206:     }
1207: }
1208: 
1209: /**
1210:  * Checks if category has a start article
1211:  *
1212:  * @param int $idcat
1213:  *         Id of category
1214:  * @param int $idlang
1215:  *         The language id
1216:  *
1217:  * @return bool
1218:  *
1219:  * @throws cDbException
1220:  */
1221: function strHasStartArticle($idcat, $idlang) {
1222:     $oCatLangColl = new cApiCategoryLanguageCollection();
1223:     return ($oCatLangColl->getStartIdartlangByIdcatAndIdlang($idcat, $idlang) > 0);
1224: }
1225: 
1226: /**
1227:  * Copies the category and it's existing articles into another category.
1228:  *
1229:  * @param int  $idcat
1230:  *         Id of category to copy
1231:  * @param int  $destidcat
1232:  *         Id of destination category
1233:  * @param bool $remakeTree
1234:  *         Flag to rebuild category tree
1235:  * @param bool $bUseCopyLabel
1236:  *         Flag to add copy label to the new categories
1237:  *
1238:  * @return void|int
1239:  *
1240:  * @throws cDbException
1241:  * @throws cException
1242:  * @throws cInvalidArgumentException
1243:  */
1244: function strCopyCategory($idcat, $destidcat, $remakeTree = true, $bUseCopyLabel = true) {
1245:     global $cfg, $lang;
1246: 
1247:     $newidcat = (int) strNewCategory($destidcat, 'a', $remakeTree);
1248:     if ($newidcat == 0) {
1249:         return;
1250:     }
1251: 
1252:     // Load old and new category
1253:     $oOldCatLang = new cApiCategoryLanguage();
1254:     if (!$oOldCatLang->loadByCategoryIdAndLanguageId($idcat, $lang)) {
1255:         return;
1256:     }
1257: 
1258:     $oNewCatLang = new cApiCategoryLanguage();
1259:     if (!$oNewCatLang->loadByCategoryIdAndLanguageId($newidcat, $lang)) {
1260:         return;
1261:     }
1262: 
1263:     // Worker objects
1264:     $oNewCat = new cApiCategory((int) $newidcat);
1265:     $oOldCat = new cApiCategory((int) $idcat);
1266: 
1267:     // Copy properties
1268:     if ($bUseCopyLabel == true) {
1269:         $oNewCatLang->set('name', sprintf(i18n('%s (Copy)'), $oOldCatLang->get('name')));
1270:     } else {
1271:         $oNewCatLang->set('name', $oOldCatLang->get('name'));
1272:     }
1273: 
1274:     $oNewCatLang->set('public', $oOldCatLang->get('public'));
1275:     $oNewCatLang->set('visible', 0);
1276:     $oNewCatLang->store();
1277: 
1278:     // Execute cec hook
1279:     cApiCecHook::execute('Contenido.Category.strCopyCategory', array(
1280:         'oldcat' => $oOldCat,
1281:         'newcat' => $oNewCat,
1282:         'newcatlang' => $oNewCatLang
1283:     ));
1284: 
1285:     // Copy template configuration
1286:     if ($oOldCatLang->get('idtplcfg') != 0) {
1287:         // Create new template configuration
1288:         $oNewCatLang->assignTemplate($oOldCatLang->getTemplate());
1289: 
1290:         // Copy the container configuration
1291:         $oContainerConfColl = new cApiContainerConfigurationCollection();
1292:         $oContainerConfColl->select('idtplcfg = ' . (int) $oOldCatLang->get('idtplcfg'));
1293: 
1294:         $oNewContainerConfColl = new cApiContainerConfigurationCollection();
1295:         while (($oItem = $oContainerConfColl->next()) !== false) {
1296:             $oNewContainerConfColl->create($oNewCatLang->get('idtplcfg'), $oItem->get('number'), $oItem->get('container'));
1297:         }
1298:     }
1299: 
1300:     $db = cRegistry::getDb();
1301: 
1302:     $oCatArtColl = new cApiCategoryArticleCollection();
1303: 
1304:     // Copy all articles
1305:     $sql = "SELECT A.idart, B.idartlang FROM %s AS A, %s AS B WHERE A.idcat = %d AND B.idart = A.idart AND B.idlang = %s";
1306:     $db->query($sql, $cfg['tab']['cat_art'], $cfg['tab']['art_lang'], $idcat, $lang);
1307: 
1308:     while ($db->nextRecord()) {
1309:         $newidart = (int) conCopyArticle($db->f('idart'), $newidcat, '', $bUseCopyLabel);
1310:         if ($db->f('idartlang') == $oOldCatLang->get('startidartlang')) {
1311:             $oCatArtColl->resetQuery();
1312:             $idcatart = $oCatArtColl->getIdByCategoryIdAndArticleId($newidcat, $newidart);
1313:             if ($idcatart) {
1314:                 conMakeStart($idcatart, 1);
1315:             }
1316:         }
1317:     }
1318: 
1319:     return $newidcat;
1320: }
1321: 
1322: /**
1323:  * Copies the categorytree (category and its childs) to an another category.
1324:  *
1325:  * @param int  $idcat
1326:  *         Id of category to copy
1327:  * @param int  $destcat
1328:  *         Id of destination category
1329:  * @param bool $remakeTree
1330:  *         Flag to rebuild category tree
1331:  * @param bool $bUseCopyLabel
1332:  *         Flag to add copy label to the new categories
1333:  *
1334:  * @throws cDbException
1335:  * @throws cException
1336:  * @throws cInvalidArgumentException
1337:  */
1338: function strCopyTree($idcat, $destcat, $remakeTree = true, $bUseCopyLabel = true) {
1339:     $newidcat = strCopyCategory($idcat, $destcat, false, $bUseCopyLabel);
1340: 
1341:     $oCatColl = new cApiCategoryCollection();
1342:     $aIds = $oCatColl->getIdsByWhereClause('parentid = ' . (int) $idcat);
1343:     foreach ($aIds as $id) {
1344:         strCopyTree($id, $newidcat, false, $bUseCopyLabel);
1345:     }
1346: 
1347:     if ($remakeTree == true) {
1348:         strRemakeTreeTable();
1349:     }
1350: }
1351: 
1352: /**
1353:  * Assigns a template to passed category.
1354:  *
1355:  * @param int $idcat
1356:  * @param int $client
1357:  * @param int $idTplCfg
1358:  *
1359:  * @throws cDbException
1360:  * @throws cException
1361:  */
1362: function strAssignTemplate($idcat, $client, $idTplCfg) {
1363:     global $perm;
1364: 
1365:     // Template permission check
1366:     $iIdtplcfg = ($perm->have_perm_area_action('str_tplcfg', 'str_tplcfg')) ? (int) $idTplCfg : 0;
1367: 
1368:     $idtpl = NULL;
1369:     if ($iIdtplcfg == 0) {
1370:         // Get default template
1371:         $oTemplateColl = new cApiTemplateCollection('defaulttemplate = 1 AND idclient = ' . (int) $client);
1372:         if (($oTemplate = $oTemplateColl->next()) !== false) {
1373:             $idtpl = $oTemplate->get('idtpl');
1374:         }
1375:     } else {
1376:         // Use passed template
1377:         $idtpl = $idTplCfg;
1378:     }
1379: 
1380:     if ($idtpl) {
1381:         // Assign template
1382:         $oCatLangColl = new cApiCategoryLanguageCollection('idcat = ' . (int) $idcat);
1383:         while (($oCatLang = $oCatLangColl->next()) !== false) {
1384:             $oCatLang->assignTemplate($idtpl);
1385:         }
1386:     }
1387: }
1388: 
1389: /**
1390:  * Checks the category tree for errors
1391:  * Returns FALSE if there are NO errors.
1392:  * If there are errors, an array with error messages will be returned
1393:  *
1394:  * @param array $addCats
1395:  *         An array of cApiCategory objects which overwrite categories from the database
1396:  * @param array $ignoreCats
1397:  *         An array of idcat's which will be treated like they don't exist in the database
1398:  *
1399:  * @return array|bool
1400:  *         An array of error messages if something is wrong.
1401:  *         If nothing is wrong false will be returned.
1402:  *
1403:  * @throws cDbException
1404:  * @throws cException
1405:  */
1406: function strCheckTreeForErrors($addCats = array(), $ignoreCats = array()) {
1407:     $errorMessages = array();
1408: 
1409:     // Get all categories into memory
1410:     $cats = new cApiCategoryCollection();
1411:     $cats->select("idclient = '" . cSecurity::toInteger(cRegistry::getClientId()) . "'");
1412: 
1413:     $catArray = array();
1414:     // first add the ones from the parameters
1415:     foreach ($addCats as $addCat) {
1416:         if ($addCat->get('idcat') == 0) {
1417:             continue;
1418:         }
1419:         $catArray[$addCat->get('idcat')] = $addCat;
1420:     }
1421: 
1422:     // add every category from the database
1423:     while ($cat = $cats->next()) {
1424:         if (in_array($cat->get('idcat'), $ignoreCats)) {
1425:             continue;
1426:         }
1427:         if (isset($catArray[$cat->get('idcat')])) {
1428:             continue;
1429:         }
1430:         $catArray[$cat->get('idcat')] = $cat;
1431:     }
1432: 
1433:     ksort($catArray);
1434: 
1435:     // build an array with the parentids at the top level and every child
1436:     // category as member
1437:     // aka
1438:     // $parents[parentId][catIdOfChildToParentId] =
1439:     // cApiCategory(catIdOfChildToParent)
1440:     // check if every parent that is mentioned in the database actually exists
1441:     $fine = true;
1442:     $parents = array();
1443:     foreach ($catArray as $idcat => $cat) {
1444:         if (!array_key_exists($cat->get('parentid'), $catArray) && $cat->get('parentid') != 0) {
1445:             $fine = false;
1446:             $errorMessages[] = sprintf(i18n('Category %s has a parent id (%s) which does not exist!'), $idcat, $cat->get('parentid'));
1447:         }
1448:         $parents[$cat->get('parentid')][$idcat] = $cat;
1449:     }
1450: 
1451:     // check for consistency in every parent
1452:     foreach ($parents as $parentId => $parent) {
1453:         // first, check for multiple preids and postids
1454:         // the category tree will miss some categories if multiple categories
1455:         // share preids and/or postids
1456:         $preIds = array();
1457:         $postIds = array();
1458:         foreach ($parent as $idcat => $cat) {
1459:             $preId = $cat->get('preid');
1460:             $postId = $cat->get('postid');
1461:             if (in_array($preId, $preIds)) {
1462:                 $fine = false;
1463:                 $errorMessages[] = sprintf(i18n('There are multiple categories in %s that share the same pre-id (%s - second occurence at %s). Sorting will fail and not all categories will be shown.'), $parentId, $preId, $idcat);
1464:             }
1465:             if (in_array($postId, $postIds)) {
1466:                 $fine = false;
1467:                 $errorMessages[] = sprintf(i18n('There are multiple categories in %s that share the same post-id (%s - second occurence at %s). Sorting will fail and not all categories will be shown.'), $parentId, $postId, $idcat);
1468:             }
1469:             $preIds[] = $preId;
1470:             $postIds[] = $postId;
1471:         }
1472: 
1473:         // check the consistency of the postids
1474:         // find the start
1475:         $startCat = null;
1476:         foreach ($parent as $cat) {
1477:             if ($cat->get('preid') == 0) {
1478:                 $startCat = $cat;
1479:                 break;
1480:             }
1481:         }
1482:         // if not start was found then something is wrong
1483:         if ($startCat == null) {
1484:             $fine = false;
1485:             $errorMessages[] = sprintf(i18n('There is no defined start (a category with preid == 0) in %s. Sorting impossible.'), $parentId);
1486:             continue;
1487:         }
1488:         // loop through the categories using the postid
1489:         $actCat = $startCat;
1490:         $checkedCats = array();
1491:         $checkedCats[] = $startCat->get('idcat');
1492:         while ($actCat != null) {
1493:             $catId = $actCat->get('idcat');
1494:             $postId = $actCat->get('postid');
1495:             if ($postId == 0) {
1496:                 break;
1497:             }
1498:             // check if the postid is actually a child of the parent
1499:             if (!array_key_exists($postId, $parent)) {
1500:                 $fine = false;
1501:                 $errorMessages[] = sprintf(i18n('%s has an invalid post-id (%s). The category does not exist in this parent! Sorting impossible.'), $catId, $postId);
1502:                 break;
1503:             }
1504:             $actCat = $catArray[$postId];
1505:             // check if the postid was seen before. if yes that would mean
1506:             // there's a loop in the tree
1507:             if (in_array($actCat->get('idcat'), $checkedCats)) {
1508:                 $fine = false;
1509:                 $errorMessages[] = sprintf(i18n('The sorting in category %s creates an infinite loop (postid = %s). Sorting the category is impossible! (Cause of failure is near category %s)'), $parentId, $postId, $catId);
1510:                 break;
1511:             }
1512:             $checkedCats[] = $actCat->get('idcat');
1513: 
1514:             // check that all categories in this parent belong to the same
1515:             // client
1516:             if (isset($catArray[$parentId])) {
1517:                 $parentClientId = $catArray[$parentId]->get('idclient');
1518:                 if ($actCat->get('idclient') != $parentClientId) {
1519:                     $fine = false;
1520:                     $errorMessages[] = sprintf(i18n('The category %s has a sub category (%s) that belongs to another client!'), $parentId, $catId);
1521:                     break;
1522:                 }
1523:             }
1524:         }
1525: 
1526:         // check the consistency of the preids
1527:         // find the last element (which is the start of the preids)
1528:         $startCat = null;
1529:         foreach ($parent as $cat) {
1530:             if ($cat->get('postid') == 0) {
1531:                 $startCat = $cat;
1532:                 break;
1533:             }
1534:         }
1535:         // if no end was found => error (this most likely means there's some
1536:         // kind of loop too)
1537:         if ($startCat == null) {
1538:             $fine = false;
1539:             $errorMessages[] = sprintf(i18n('There is no defined end (a category with postid == 0) in %s. Sorting impossible.'), $parentId);
1540:             continue;
1541:         }
1542:         // loop through the categories using the preid
1543:         $actCat = $startCat;
1544:         $checkedCats = array();
1545:         $checkedCats[] = $startCat->get('idcat');
1546:         while ($actCat != null) {
1547:             $catId = $actCat->get('idcat');
1548:             $preId = $actCat->get('preid');
1549:             if ($preId == 0) {
1550:                 break;
1551:             }
1552:             // if the preid isn't a child of the parent => error
1553:             if (!array_key_exists($preId, $parent)) {
1554:                 $fine = false;
1555:                 $errorMessages[] = sprintf(i18n('%s has an invalid pre-id (%s). The category does not exist in this parent! Sorting impossible.'), $catId, $preId);
1556:                 break;
1557:             }
1558:             $actCat = $catArray[$preId];
1559:             // if we've seen this preid before, that means there is some kind of
1560:             // loop => error
1561:             if (in_array($actCat->get('idcat'), $checkedCats)) {
1562:                 $fine = false;
1563:                 $errorMessages[] = sprintf(i18n('The sorting in category %s creates an infinite loop (preid = %s). Sorting the category is impossible! (Cause of failure is near category %s)'), $parentId, $preId, $catId);
1564:                 break;
1565:             }
1566:             $checkedCats[] = $actCat->get('idcat');
1567:         }
1568:     }
1569:     // if everything is fine, return false
1570:     // otherwise return the collected error messages
1571:     if (!$fine) {
1572:         $messages = array();
1573:         foreach ($errorMessages as $errorMessage) {
1574:             if (in_array($errorMessage, $messages)) {
1575:                 continue;
1576:             }
1577:             $messages[] = $errorMessage;
1578:         }
1579:         return $messages;
1580:     } else {
1581:         return false;
1582:     }
1583: }
1584: 
CMS CONTENIDO 4.10.1 API documentation generated by ApiGen 2.8.0