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

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