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