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:  * Defines the 'con' related functions in CONTENIDO
   5:  *
   6:  * @package Core
   7:  * @subpackage Backend
   8:  * @author Olaf Niemann
   9:  * @author Jan Lengowski
  10:  * @author Murat Purc <murat@purc.de>
  11:  * @copyright four for business AG <www.4fb.de>
  12:  * @license http://www.contenido.org/license/LIZENZ.txt
  13:  * @link http://www.4fb.de
  14:  * @link http://www.contenido.org
  15:  */
  16: 
  17: defined('CON_FRAMEWORK') || die('Illegal call: Missing framework initialization - request aborted.');
  18: 
  19: // Compatibility: Include new functions.con2.php
  20: cInclude('includes', 'functions.con2.php');
  21: 
  22: /**
  23:  * Create a new article; create article version, if versioning state
  24:  * is simple or advanced
  25:  *
  26:  * @param int $idcat
  27:  * @param int $idcatnew
  28:  * @param int $idart
  29:  * @param int $isstart
  30:  * @param int $idtpl
  31:  * @param int $idartlang
  32:  * @param int $idlang
  33:  * @param string $title
  34:  * @param string $summary
  35:  * @param int $artspec
  36:  * @param string $created
  37:  * @param string $lastmodified
  38:  * @param string $author
  39:  * @param int $online
  40:  * @param string $datestart
  41:  * @param string $dateend
  42:  * @param int $artsort
  43:  * @param int $keyart
  44:  * @param int $searchable
  45:  * @param float $sitemapprio
  46:  * @param string $changefreq
  47:  * @return int
  48:  *         Id of the new article
  49:  */
  50: function conEditFirstTime(
  51:     $idcat, $idcatnew, $idart, $isstart, $idtpl, $idartlang, $idlang, $title,
  52:     $summary, $artspec, $created, $lastmodified, $author, $online, $datestart,
  53:     $dateend, $artsort, $keyart = 0, $searchable = 1, $sitemapprio = 0.5,
  54:     $changefreq = ''
  55: ) {
  56: 
  57:     global $client, $lang, $auth, $urlname, $page_title;
  58:     // Some stuff for the redirect
  59:     global $redirect, $redirect_url, $external_redirect;
  60:     global $time_move_cat; // Used to indicate "move to cat"
  61:     global $time_target_cat; // Used to indicate the target category
  62:     global $time_online_move; // Used to indicate if the moved article should be
  63:                               // online
  64:     global $timemgmt;
  65: 
  66:     $page_title = addslashes($page_title);
  67:     $title = stripslashes($title);
  68:     $redirect_url = stripslashes($redirect_url);
  69:     $urlname = (trim($urlname) == '')? trim($title) : trim($urlname);
  70: 
  71:     if ($isstart == 1) {
  72:         $timemgmt = 0;
  73:     }
  74: 
  75:     if (!is_array($idcatnew)) {
  76:         $idcatnew[0] = 0;
  77:     }
  78: 
  79:     $versioning = new cContentVersioning();
  80:     // Create article entry
  81:     $oArtColl = new cApiArticleCollection();
  82:     $oArt = $oArtColl->create($client);
  83:     $idart = $oArt->get('idart');
  84: 
  85:     $status = 0;
  86: 
  87:     // Create an category article entry
  88:     $oCatArtColl = new cApiCategoryArticleCollection();
  89:     $oCatArt = $oCatArtColl->create($idcat, $idart, $status);
  90:     $idcatart = $oCatArt->get('idcatart');
  91: 
  92:     $aLanguages = array(
  93:         $lang
  94:     );
  95: 
  96:     // Table 'con_art_lang', one entry for every language
  97:     foreach ($aLanguages as $curLang) {
  98:         $lastmodified = ($lang == $curLang)? $lastmodified : '';
  99:         $modifiedby = '';
 100: 
 101:         if ($online == 1) {
 102:             $published_value = date('Y-m-d H:i:s');
 103:             $publishedby_value = $auth->auth['uname'];
 104:         } else {
 105:             $published_value = '';
 106:             $publishedby_value = '';
 107:         }
 108: 
 109:         // Create an stat entry
 110:         $oStatColl = new cApiStatCollection();
 111:         $oStat = $oStatColl->create($idcatart, $curLang, $client, 0);
 112: 
 113:         // Create an article language entry
 114:         $oArtLangColl = new cApiArticleLanguageCollection();
 115:         $oArtLang = $oArtLangColl->create($idart, $curLang, $title, $urlname, $page_title, $summary, $artspec, $created, $auth->auth['uname'], $lastmodified, $modifiedby, $published_value, $publishedby_value, $online, $redirect, $redirect_url, $external_redirect, $artsort, $timemgmt, $datestart, $dateend, $status, $time_move_cat, $time_target_cat, $time_online_move, 0, '', '', '', $searchable, $sitemapprio, $changefreq);
 116:         $lastId = $oArtLang->get('idartlang');
 117:         $availableTags = conGetAvailableMetaTagTypes();
 118:         foreach ($availableTags as $key => $value) {
 119:             conSetMetaValue($lastId, $key, $_POST['META' . $value['name']], $child);
 120:         }
 121:     }
 122: 
 123:     // Get all idcats that contain art
 124:     $oCatArtColl = new cApiCategoryArticleCollection();
 125:     $aCatsForArt = $oCatArtColl->getCategoryIdsByArticleId($idart);
 126:     if (count($aCatsForArt) == 0) {
 127:         $aCatsForArt[0] = 0;
 128:     }
 129: 
 130:     $aLanguages = getLanguagesByClient($client);
 131: 
 132:     foreach ($idcatnew as $value) {
 133:         if (!in_array($value, $aCatsForArt)) {
 134:             // New category article entry
 135:             $oCatArtColl = new cApiCategoryArticleCollection();
 136:             $oCatArt = $oCatArtColl->create($value, $idart);
 137:             $curIdcatart = $oCatArt->get('idcatart');
 138: 
 139:             // New statistics entry for each language
 140:             foreach ($aLanguages as $curLang) {
 141:                 $oStatColl = new cApiStatCollection();
 142:                 $oStatColl->create($curIdcatart, $curLang, $client, 0);
 143:             }
 144:         }
 145:     }
 146: 
 147:     foreach ($aCatsForArt as $value) {
 148:         if (!in_array($value, $idcatnew)) {
 149:             // Delete category article and other related entries that will no
 150:             // longer exist
 151:             conRemoveOldCategoryArticle($value, $idart, $idartlang, $client, $lang);
 152:         }
 153:     }
 154: 
 155:     if (!$title) {
 156:         $title = '--- ' . i18n("Default title") . ' ---';
 157:     }
 158: 
 159:     // Update article language for all languages
 160:     foreach ($aLanguages as $curLang) {
 161:         $curOnline = ($lang == $curLang)? $online : 0;
 162:         $curLastmodified = ($lang == $curLang)? $lastmodified : '';
 163: 
 164:         $oArtLang = new cApiArticleLanguage();
 165:         $oArtLang->loadByArticleAndLanguageId($idart, $curLang);
 166:         if (!$oArtLang->isLoaded()) {
 167:             continue;
 168:         }
 169: 
 170:         $oArtLang->set('title', $title);
 171:         $oArtLang->set('urlname', $urlname);
 172:         $oArtLang->set('pagetitle', $page_title);
 173:         $oArtLang->set('summary', $summary);
 174:         $oArtLang->set('artspec', $artspec);
 175:         $oArtLang->set('created', $created);
 176:         $oArtLang->set('lastmodified', $curLastmodified);
 177:         $oArtLang->set('modifiedby', $author);
 178:         $oArtLang->set('online', $curOnline);
 179:         $oArtLang->set('searchable', $searchable);
 180:         $oArtLang->set('sitemapprio', $sitemapprio);
 181:         $oArtLang->set('changefreq', $changefreq);
 182:         $oArtLang->set('redirect', $redirect);
 183:         $oArtLang->set('redirect_url', $redirect_url);
 184:         $oArtLang->set('external_redirect', $external_redirect);
 185:         $oArtLang->set('artsort', $artsort);
 186:         $oArtLang->set('datestart', $datestart);
 187:         $oArtLang->set('dateend', $dateend);
 188:         $oArtLang->store();
 189:     }
 190: 
 191:     $versioningState = $versioning->getState();
 192: 
 193:     switch ($versioningState) {
 194:         case 'simple':
 195:         case 'advanced':
 196:             // Create new Article Language Version Entry
 197:             $parameters = array(
 198:                 'published' => $published_value,
 199:                 'idcat' => $idcat,
 200:                 'idcatnew' => $idcatnew,
 201:                 'idart' => $idart,
 202:                 'isstart' => $isstart,
 203:                 'idtpl' => $idtpl,
 204:                 'idartlang' => $lastId,
 205:                 'idlang' => $idlang,
 206:                 'title' => $title,
 207:                 'summary' => $summary,
 208:                 'artspec' => $artspec,
 209:                 'created' => $created,
 210:                 'iscurrentversion' => 1,
 211:                 'lastmodified' => $lastmodified,
 212:                 'author' => $author,
 213:                 'online' => $online,
 214:                 'artsort' => $artsort,
 215:                 'datestart' => $datestart,
 216:                 'dateend' => $dateend,
 217:                 'keyart' => $keyart,
 218:                 'searchable' => $searchable,
 219:                 'sitemapprio' => $sitemapprio,
 220:                 'changefreq' => $changefreq
 221:             );
 222: 
 223:             $versioning->createArticleLanguageVersion($parameters);
 224:             break;
 225:         case 'disabled':
 226:         default:
 227:             break;
 228:     }
 229: 
 230:     return $idart;
 231: }
 232: 
 233: /**
 234:  * Edit an existing article.
 235:  * Create a version if versioning state is simple or advanced.
 236:  *
 237:  * @param int $idcat
 238:  * @param int $idcatnew
 239:  * @param int $idart
 240:  * @param int $isstart
 241:  * @param int $idtpl
 242:  * @param int $idartlang
 243:  * @param int $idlang
 244:  * @param string $title
 245:  * @param string $summary
 246:  * @param int $artspec
 247:  * @param unknown_type $created
 248:  * @param unknown_type $lastmodified
 249:  * @param unknown_type $author
 250:  * @param unknown_type $online
 251:  * @param unknown_type $datestart
 252:  * @param unknown_type $dateend
 253:  * @param unknown_type $published
 254:  * @param unknown_type $artsort
 255:  * @param int $keyart
 256:  * @param unknown_type $searchable
 257:  * @param unknown_type $sitemapprio
 258:  * @param unknown_type $changefreq
 259:  * @return int|void
 260:  */
 261: function conEditArt($idcat, $idcatnew, $idart, $isstart, $idtpl, $idartlang, $idlang, $title, $summary, $artspec, $created, $lastmodified, $author, $online, $datestart, $dateend, $published, $artsort, $keyart = 0, $searchable = 1, $sitemapprio = -1, $changefreq = 'nothing') {
 262:     global $client, $lang, $redirect, $redirect_url, $external_redirect, $perm;
 263:     global $urlname, $page_title;
 264:     global $time_move_cat, $time_target_cat;
 265:     // Used to indicate if the moved article should be online
 266:     global $time_online_move;
 267:     global $timemgmt;
 268:     // CON-2134 check admin permission
 269:     $aAuthPerms = explode(',', $auth->auth['perm']);
 270: 
 271:     $admin = false;
 272:     if (count(preg_grep("/admin.*/", $aAuthPerms)) > 0) {
 273:         $admin = true;
 274:     }
 275:     $oArtLang = new cApiArticleLanguage($idartlang);
 276:     $locked = (int) $oArtLang->get('locked');
 277: 
 278:     // abort editing if article is locked and user user no admin
 279:     if (1 === $locked
 280:         && false === $admin) {
 281:             return $idart;
 282:     }
 283: 
 284:     // Add slashes because single quotes will crash the db
 285:     $page_title = addslashes($page_title);
 286:     $title = stripslashes($title);
 287:     $redirect_url = stripslashes($redirect_url);
 288: 
 289:     $urlname = (trim($urlname) == '')? trim($title) : trim($urlname);
 290:     $usetimemgmt = ((int) $timemgmt == 1)? 1 : 0;
 291:     if ($timemgmt == '1' && (($datestart == '' && $dateend == '') || ($datestart == '0000-00-00 00:00:00' && $dateend == '0000-00-00 00:00:00'))) {
 292:         $usetimemgmt = 0;
 293:     }
 294: 
 295:     if ($isstart == 1) {
 296:         $usetimemgmt = 0;
 297:     }
 298: 
 299:     if (!is_array($idcatnew)) {
 300:         $idcatnew[0] = 0;
 301:     }
 302: 
 303:     $artLang = new cApiArticleLanguage((int) $idartlang);
 304:     if (!$artLang->isLoaded()) {
 305:         return;
 306:     }
 307: 
 308:     // Get idtplcfg
 309:     $idTplCfg = $artLang->get('idtplcfg');
 310: 
 311:     // Get all idcats that contain art
 312:     $oCatArtColl = new cApiCategoryArticleCollection();
 313:     $aCatsForArt = $oCatArtColl->getCategoryIdsByArticleId($idart);
 314:     if (count($aCatsForArt) == 0) {
 315:         $aCatsForArt[0] = 0;
 316:     }
 317: 
 318:     foreach ($idcatnew as $value) {
 319:         if (!in_array($value, $aCatsForArt)) {
 320:             // New category article entry
 321:             $oCatArtColl = new cApiCategoryArticleCollection();
 322:             $oCatArt = $oCatArtColl->create($value, $idart);
 323:             $curIdcatart = $oCatArt->get('idcatart');
 324: 
 325:             // Copy template configuration
 326:             if ($idTplCfg != 0) {
 327:                 $newIdTplCfg = conCopyTemplateConfiguration($idTplCfg);
 328:                 conCopyContainerConf($idTplCfg, $newIdTplCfg);
 329:             }
 330: 
 331:             $aLanguages = getLanguagesByClient($client);
 332: 
 333:             // New statistics entry for each language
 334:             foreach ($aLanguages as $curLang) {
 335:                 $oStatColl = new cApiStatCollection();
 336:                 $oStatColl->create($curIdcatart, $curLang, $client, 0);
 337:             }
 338:         }
 339:     }
 340: 
 341:     foreach ($aCatsForArt as $value) {
 342:         if (!in_array($value, $idcatnew)) {
 343:             // Delete category article and other related entries that will no
 344:             // longer exist
 345:             conRemoveOldCategoryArticle($value, $idart, $idartlang, $client, $lang);
 346:         }
 347:     }
 348: 
 349:     if ($title == '') {
 350:         $title = '--- ' . i18n('Default title') . ' ---';
 351:     }
 352: 
 353:     $versioning = new cContentVersioning();
 354:     $versioningState = $versioning->getState();
 355: 
 356:     switch ($versioningState) {
 357:         case 'simple':
 358:             // update current article
 359:             $artLang->set('title', $title);
 360:             $artLang->set('urlname', $urlname);
 361:             $artLang->set('summary', $summary);
 362:             $artLang->set('artspec', $artspec);
 363:             $artLang->set('created', $created);
 364:             $artLang->set('lastmodified', $lastmodified);
 365:             $artLang->set('modifiedby', $author);
 366:             $artLang->set('timemgmt', $usetimemgmt);
 367:             $artLang->set('redirect', $redirect);
 368:             $artLang->set('external_redirect', $external_redirect);
 369:             $artLang->set('redirect_url', $redirect_url);
 370:             $artLang->set('artsort', $artsort);
 371:             $artLang->set('searchable', $searchable);
 372:             if ($sitemapprio != -1) {
 373:                 $artLang->set('sitemapprio', $sitemapprio);
 374:             }
 375:             if ($changefreq != "nothing") {
 376:                 $artLang->set('changefreq', $changefreq);
 377:             }
 378:             $artLang->set('published', date("Y-m-d H:i:s", strtotime($published)));
 379: 
 380:             // If the user has right for makeonline, update some properties.
 381:             if ($perm->have_perm_area_action('con', 'con_makeonline') || $perm->have_perm_area_action_item('con', 'con_makeonline', $idcat)) {
 382:                 $oldOnline = $artLang->get('online');
 383:                 if (isset($online)) {
 384:                     $artLang->set('online', $online);
 385:                 }
 386: 
 387:                 // Check if old online value was 0, update published data if value
 388:                 // changed from 0 to 1
 389:                 if ((int) $online == 1 && $oldOnline == 0) {
 390:                     $artLang->set('published', date('Y-m-d H:i:s'));
 391:                     $artLang->set('publishedby', $author);
 392:                 }
 393: 
 394:                 $artLang->set('datestart', $datestart);
 395:                 $artLang->set('dateend', $dateend);
 396:                 $artLang->set('time_move_cat', $time_move_cat);
 397:                 $artLang->set('time_target_cat', $time_target_cat);
 398:                 $artLang->set('time_online_move', $time_online_move);
 399:             }
 400: 
 401:             // Update idtplcfg
 402:             if (!empty($newIdTplCfg) && $idTplCfg != $newIdTplCfg) {
 403:                 $artLang->set('idtplcfg', $newIdTplCfg);
 404:             }
 405: 
 406:             $artLang->store();
 407:         case 'advanced':
 408:             $oldOnline = $artLang->get('online');
 409:             // Create new Article Language Version Entry
 410:             if ((int) $online == 1 && $oldOnline == 0) {
 411:                     $published = date('Y-m-d H:i:s');
 412:                     $publishedby = $author;
 413:             }
 414:             $parameters = array(
 415:                 'idcat' => $idcat,
 416:                 'idcatnew' => $idcatnew,
 417:                 'idart' => $idart,
 418:                 'isstart' => $isstart,
 419:                 'idtpl' => $idtpl,
 420:                 'idartlang' => $idartlang,
 421:                 'idlang' => $idlang,
 422:                 'title' => $title,
 423:                 'summary' => $summary,
 424:                 'artspec' => $artspec,
 425:                 'created' => $created,
 426:                 'iscurrentversion' => 1,
 427:                 'lastmodified' => $lastmodified,
 428:                 'published' => $published,
 429:                 'publishedby' => $publishedby,
 430:                 'author' => $author,
 431:                 'artsort' => $artsort,
 432:                 'datestart' => $datestart,
 433:                 'dateend' => $dateend,
 434:                 'keyart' => $keyart,
 435:                 'searchable' => $searchable,
 436:                 'sitemapprio' => $sitemapprio,
 437:                 'changefreq' => $changefreq
 438:             );
 439: 
 440:             if (isset($online)) {
 441:                 $parameters['online'] = $online;
 442:             } else {
 443:                 $parameters['online'] = $oldOnline;
 444:             }
 445: 
 446:             $versioning->createArticleLanguageVersion($parameters);
 447: 
 448:             break;
 449:         case 'disabled':
 450:             $artLang->set('title', $title);
 451:             $artLang->set('urlname', $urlname);
 452:             $artLang->set('summary', $summary);
 453:             $artLang->set('artspec', $artspec);
 454:             $artLang->set('created', $created);
 455:             $artLang->set('lastmodified', $lastmodified);
 456:             $artLang->set('modifiedby', $author);
 457:             $artLang->set('timemgmt', $usetimemgmt);
 458:             $artLang->set('redirect', $redirect);
 459:             $artLang->set('external_redirect', $external_redirect);
 460:             $artLang->set('redirect_url', $redirect_url);
 461:             $artLang->set('artsort', $artsort);
 462:             $artLang->set('searchable', $searchable);
 463:             if ($sitemapprio != -1) {
 464:                 $artLang->set('sitemapprio', $sitemapprio);
 465:             }
 466:             if ($changefreq != "nothing") {
 467:                 $artLang->set('changefreq', $changefreq);
 468:             }
 469:             $artLang->set('published', date("Y-m-d H:i:s", strtotime($published)));
 470: 
 471:             // If the user has right for makeonline, update some properties.
 472:             if ($perm->have_perm_area_action('con', 'con_makeonline') || $perm->have_perm_area_action_item('con', 'con_makeonline', $idcat)) {
 473:                 $oldOnline = $artLang->get('online');
 474:                 if (isset($online)) {
 475:                     $artLang->set('online', $online);
 476:                 }
 477: 
 478:                 // Check if old online value was 0, update published data if value
 479:                 // changed from 0 to 1
 480:                 if ((int) $online == 1 && $oldOnline == 0) {
 481:                     $artLang->set('published', date('Y-m-d H:i:s'));
 482:                     $artLang->set('publishedby', $author);
 483:                 }
 484: 
 485:                 $artLang->set('datestart', $datestart);
 486:                 $artLang->set('dateend', $dateend);
 487:                 $artLang->set('time_move_cat', $time_move_cat);
 488:                 $artLang->set('time_target_cat', $time_target_cat);
 489:                 $artLang->set('time_online_move', $time_online_move);
 490:             }
 491: 
 492:             // Update idtplcfg
 493:             if (!empty($newIdTplCfg) && $idTplCfg != $newIdTplCfg) {
 494:                 $artLang->set('idtplcfg', $newIdTplCfg);
 495:             }
 496: 
 497:             $artLang->store();
 498:         default:
 499:             break;
 500:     }
 501: 
 502:     // article has been saved, so clear the article cache
 503:     $purge = new cSystemPurge();
 504:     $purge->clearArticleCache($idartlang);
 505: }
 506: 
 507: /**
 508:  * Save a content element and generate index; create content version if
 509:  * versioning state is simple or advanced
 510:  *
 511:  * @param int $idartlang
 512:  *         idartlang of the article
 513:  * @param string $type
 514:  *         Type of content element
 515:  * @param int $typeid
 516:  *         Serial number of the content element
 517:  * @param string $value
 518:  *         Content
 519:  * @param bool $bForce
 520:  *         Not used: Was a flag to use existing db instance in global scope
 521:  */
 522: function conSaveContentEntry($idartlang, $type, $typeid, $value, $bForce = false) {
 523:     global $auth, $cfgClient, $client, $_cecRegistry, $lang;
 524: 
 525:     $oType = new cApiType();
 526:     if (!$oType->loadByType($type)) {
 527:         // Couldn't load type...
 528:         return;
 529:     }
 530: 
 531:     $value = str_replace(cRegistry::getFrontendUrl(), '', $value);
 532:     $value = stripslashes($value);
 533: 
 534:     $iterator = $_cecRegistry->getIterator('Contenido.Content.SaveContentEntry');
 535:     while (($chainEntry = $iterator->next()) !== false) {
 536:         $value = $chainEntry->execute($idartlang, $type, $typeid, $value);
 537:     }
 538: 
 539:     $idtype = $oType->get('idtype');
 540: 
 541:     // instantiate content
 542:     $content = new cApiContent();
 543:     $content->loadByArticleLanguageIdTypeAndTypeId($idartlang, $idtype, $typeid);
 544: 
 545:     if (! $content->isLoaded()) {
 546:         $contentColl = new cApiContentCollection();
 547:         $content = $contentColl->create($idartlang, $idtype, $typeid, NULL, NULL);
 548:     }
 549: 
 550:     // save content and versions
 551:     $versioning = new cContentVersioning();
 552:     $versioning->prepareContentForSaving($idartlang, $content, $value);
 553: 
 554:     // content entry has been saved, so clear the article cache
 555:     $purge = new cSystemPurge();
 556:     $purge->clearArticleCache($idartlang);
 557: }
 558: 
 559: /**
 560:  * Generate index of article content.
 561:  *
 562:  * This is done by calling the hook 'Contenido.Content.AfterStore'.
 563:  *
 564:  * @param int $idartlang
 565:  *         of article to index
 566:  * @param int $idart
 567:  *         of article to index
 568:  */
 569: function conMakeArticleIndex($idartlang, $idart) {
 570: 
 571:     // get IDs of given article langauge
 572:     if (cRegistry::getArticleLanguageId() == $idartlang) {
 573:         // quite easy if given article is current article
 574:         $idclient = cRegistry::getClientId();
 575:         $idlang = cRegistry::getLanguageId();
 576:         $idcat = cRegistry::getCategoryId();
 577:         $idart = cRegistry::getArticleId();
 578:         $idcatlang = cRegistry::getCategoryLanguageId();
 579:         $idartlang = cRegistry::getArticleLanguageId();
 580:     } else {
 581:         // == for other articles these infos have to be read from DB
 582:         // get idclient by idart
 583:         $article = new cApiArticle($idart);
 584:         if ($article->isLoaded()) {
 585:             $idclient = $article->get('idclient');
 586:         }
 587:         // get idlang by idartlang
 588:         $articleLanguage = new cApiArticleLanguage($idartlang);
 589:         if ($articleLanguage->isLoaded()) {
 590:             $idlang = $articleLanguage->get('idlang');
 591:         }
 592:         // get first idcat by idart
 593:         $coll = new cApiCategoryArticleCollection();
 594:         $idcat = array_shift($coll->getCategoryIdsByArticleId($idart));
 595:         // get idcatlang by idcat & idlang
 596:         $categoryLanguage = new cApiCategoryLanguage();
 597:         $categoryLanguage->loadByCategoryIdAndLanguageId($idcat, $idlang);
 598:         if ($categoryLanguage->isLoaded()) {
 599:             $idcatlang = $articleLanguage->get('idlang');
 600:         }
 601:     }
 602: 
 603:     // build data structure expected by handlers of Contenido.Content.AfterStore
 604:     $articleIds = array(
 605:         'idclient' => $idclient,
 606:         'idlang' => $idlang,
 607:         'idcat' => $idcat,
 608:         'idcatlang' => $idcatlang,
 609:         'idart' => $idart,
 610:         'idartlang' => $idartlang
 611:     );
 612: 
 613:     // iterate chain Contenido.Content.AfterStore
 614:     $iterator = cRegistry::getCecRegistry()->getIterator('Contenido.Content.AfterStore');
 615:     while (false !== $chainEntry = $iterator->next()) {
 616:         $chainEntry->execute($articleIds);
 617:     }
 618: 
 619: }
 620: 
 621: /**
 622:  * Toggle the online status of an article
 623:  *
 624:  * @param int $idart
 625:  *         Article Id
 626:  * @param int $lang
 627:  *         Language Id
 628:  * @param int $online [optional]
 629:  *         if 0 the article will be offline, if 1 article will be online
 630:  */
 631: function conMakeOnline($idart, $lang, $online = -1) {
 632:     $auth = cRegistry::getAuth();
 633: 
 634:     $artLang = new cApiArticleLanguage();
 635:     if (!$artLang->loadByArticleAndLanguageId($idart, $lang)) {
 636:         return;
 637:     }
 638: 
 639:     // Reverse current value
 640:     if($online === -1) {
 641:         $online = ($artLang->get('online') == 0)? 1 : 0;
 642:     }
 643: 
 644:     $artLang->set('online', $online);
 645: 
 646:     if ($online == 1) {
 647:         // Update published date and publisher
 648:         $artLang->set('published', date('Y-m-d H:i:s'));
 649:         $artLang->set('publishedby', $auth->auth['uname']);
 650:     }
 651: 
 652:     $artLang->store();
 653: 
 654:     // Execute cec hook
 655:     cApiCecHook::execute('Contenido.Article.ConMakeOnline', array(
 656:     'idart' => $idart,
 657:     'idlang' => $lang,
 658:     'state' => $online
 659:     ));
 660: }
 661: 
 662: /**
 663:  * Set the status from articles to online or offline.
 664:  *
 665:  * @param array $idarts
 666:  *         All articles
 667:  * @param int $idlang
 668:  * @param bool $online
 669:  */
 670: function conMakeOnlineBulkEditing($idarts, $idlang, $online) {
 671:     $auth = cRegistry::getAuth();
 672: 
 673:     // get all articles with the given idart and idlang
 674:     $idartString = implode("','", $idarts);
 675:     $artLangCollection = new cApiArticleLanguageCollection();
 676:     $artLangCollection->select("`idart` IN ('" . $idartString . "') AND `idlang`='" . cSecurity::toInteger($idlang) . "'");
 677: 
 678:     // iterate over articles and set online flag
 679:     while (($artLang = $artLangCollection->next()) !== false) {
 680:         $artLang->set('online', $online);
 681:         if ($online == 1) {
 682:             // update published date and publisher
 683:             $artLang->set('published', date('Y-m-d H:i:s'));
 684:             $artLang->set('publishedby', $auth->auth['uname']);
 685:         }
 686:         $artLang->store();
 687:     }
 688: }
 689: 
 690: /**
 691:  * Toggle the lock status of an article
 692:  *
 693:  * @param int $idart
 694:  *         Article Id
 695:  * @param int $lang
 696:  *         Language Id
 697:  */
 698: function conLock($idart, $lang) {
 699:     $artLang = new cApiArticleLanguage();
 700:     if (!$artLang->loadByArticleAndLanguageId($idart, $lang)) {
 701:         return;
 702:     }
 703: 
 704:     $locked = ($artLang->get('locked') == 0)? 1 : 0;
 705: 
 706:     $artLang->set('locked', $locked);
 707:     $artLang->store();
 708: }
 709: 
 710: /**
 711:  * Freeze/Lock more articles.
 712:  *
 713:  * @param array $idarts
 714:  *         All articles
 715:  * @param int $idlang
 716:  * @param bool $lock
 717:  */
 718: function conLockBulkEditing($idarts, $idlang, $lock) {
 719:     // get all articles with the given idart and idlang
 720:     $idartString = implode("','", $idarts);
 721:     $artLangCollection = new cApiArticleLanguageCollection();
 722:     $artLangCollection->select("`idart` IN ('" . $idartString . "') AND `idlang`='" . cSecurity::toInteger($idlang) . "'");
 723: 
 724:     // iterate over articles and set online flag
 725:     while (($artLang = $artLangCollection->next()) !== false) {
 726:         $artLang->set('locked', $lock);
 727:         $artLang->store();
 728:     }
 729: }
 730: 
 731: /**
 732:  * Checks if a article is locked or not
 733:  *
 734:  * @param int $idart
 735:  *         Article Id
 736:  * @param int $lang
 737:  *         Language Id
 738:  * @return bool
 739:  */
 740: function conIsLocked($idart, $lang) {
 741:     $artLang = new cApiArticleLanguage();
 742:     if (!$artLang->loadByArticleAndLanguageId($idart, $lang)) {
 743:         return false;
 744:     }
 745:     return (1 == $artLang->get('locked'));
 746: }
 747: 
 748: /**
 749:  * Toggle the online status of a category
 750:  *
 751:  * @param int $idcat
 752:  *         Id of the category
 753:  * @param int $lang
 754:  *         Id of the language
 755:  * @param int $status
 756:  *         Status of the category
 757:  */
 758: function conMakeCatOnline($idcat, $lang, $status) {
 759:     global $cfg;
 760: 
 761:     $catLang = new cApiCategoryLanguage();
 762:     if (!$catLang->loadByCategoryIdAndLanguageId($idcat, $lang)) {
 763:         return;
 764:     }
 765: 
 766:     $status = (1 == $status)? 1 : 0;
 767: 
 768:     $catLang->set('visible', $status);
 769:     $catLang->set('lastmodified', date('Y-m-d H:i:s'));
 770:     $catLang->store();
 771: 
 772:     if ($cfg['pathresolve_heapcache'] == true && !$status = 0) {
 773:         $oPathresolveCacheColl = new cApiPathresolveCacheCollection();
 774:         $oPathresolveCacheColl->deleteByCategoryAndLanguage($idcat, $lang);
 775:     }
 776: 
 777:     // Execute cec hook
 778:     cApiCecHook::execute('Contenido.Article.ConMakeCatOnline', array(
 779:     'idcat' => $idcat,
 780:     'idlang' => $lang,
 781:     ));
 782: }
 783: 
 784: /**
 785:  * Sets the public status of the given category and its children
 786:  * for the given language.
 787:  *
 788:  * This is almost the same function as strMakePublic.
 789:  *
 790:  * @param int $idcat
 791:  *         category id
 792:  * @param int $lang
 793:  *         language id
 794:  * @param bool $public
 795:  *         public status of the article to set
 796:  */
 797: function conMakePublic($idcat, $lang, $public) {
 798: 
 799:     foreach (conDeeperCategoriesArray($idcat) as $tmpIdcat) {
 800:         $oCatLang = new cApiCategoryLanguage();
 801:         $oCatLang->loadByCategoryIdAndLanguageId($tmpIdcat, $lang);
 802:         $oCatLang->set('public', $public);
 803:         $oCatLang->set('lastmodified', date('Y-m-d H:i:s'));
 804:         $oCatLang->store();
 805:     }
 806: 
 807: }
 808: 
 809: /**
 810:  * Delete an Article and all other related entries
 811:  *
 812:  * @param int $idart
 813:  *         Article Id
 814:  */
 815: function conDeleteart($idart) {
 816:     global $_cecRegistry, $cfgClient, $client;
 817:     $lang = cRegistry::getLanguageId();
 818: 
 819:     // Get article language
 820:     $artLang = new cApiArticleLanguage();
 821:     if (!$artLang->loadByArticleAndLanguageId($idart, $lang)) {
 822:         return;
 823:     }
 824: 
 825:     $idartlang = $artLang->get('idartlang');
 826:     $idtplcfg = $artLang->get('idtplcfg');
 827: 
 828:     $catArtColl = new cApiCategoryArticleCollection();
 829:     $cats = $catArtColl->getIdsByWhereClause("idart = " . (int) $idart);
 830: 
 831:     // Fetch idcat
 832:     foreach ($cats as $idcat) {
 833:         // Reset startidartlang
 834:         if (isStartArticle($idartlang, $idcat, $lang)) {
 835:             $catLang = new cApiCategoryLanguage();
 836:             $catLang->loadByCategoryIdAndLanguageId($idcat, $lang);
 837:             $catLang->set('startidartlang', 0);
 838:             $catLang->store();
 839:         }
 840:     }
 841: 
 842:     $contentColl = new cApiContentCollection();
 843:     $contentColl->deleteBy('idartlang', (int) $idartlang);
 844: 
 845:     // delete article in language itself
 846:     $artLangColl = new cApiArticleLanguageCollection();
 847:     $artLangColl->delete((int) $idartlang);
 848: 
 849:     // delete all versioning information for article in language
 850:     $oArtLangVersColl = new cApiArticleLanguageVersionCollection();
 851:     $oArtLangVersColl->deleteBy('idartlang', (int) $idartlang);
 852: 
 853:     if ($idtplcfg != 0) {
 854:         $containerConfColl = new cApiContainerConfigurationCollection();
 855:         $containerConfColl->deleteBy('idtplcfg', (int) $idtplcfg);
 856: 
 857:         $tplConfColl = new cApiTemplateConfigurationCollection();
 858:         $tplConfColl->delete($idtplcfg);
 859:     }
 860: 
 861:     // Check if there are remaining languages
 862:     $artLangColl->resetQuery();
 863:     $artLangColl->select('idart = ' . (int) $idart);
 864:     if ($artLangColl->next()) {
 865:         return;
 866:     }
 867: 
 868:     $catArtColl = new cApiCategoryArticleCollection();
 869:     $catArtColl->select('idart = ' . (int) $idart);
 870:     while (($oCatArtItem = $catArtColl->next()) !== false) {
 871:         // Delete from code cache
 872:         if (cFileHandler::exists($cfgClient[$client]['code']['path'])) {
 873:             /* @var $file SplFileInfo */
 874:             foreach (new DirectoryIterator($cfgClient[$client]['code']['path']) as $file) {
 875:                 if ($file->isFile() === false) {
 876:                     continue;
 877:                 }
 878: 
 879:                 $extension = substr($file, strrpos($file->getBasename(), '.') + 1);
 880:                 if ($extension != 'php') {
 881:                     continue;
 882:                 }
 883: 
 884:                 if (preg_match('/[0-9*].[0-9*].' . $oCatArtItem->get('idcatart') . '/s', $file->getBasename())) {
 885:                     cFileHandler::remove($cfgClient[$client]['code']['path'] . '/' . $file->getFilename());
 886:                 }
 887:             }
 888:         }
 889: 
 890:         // Delete from 'stat'-table
 891:         $statColl = new cApiStatCollection();
 892:         $statColl->deleteBy('idcatart', (int) $oCatArtItem->get('idcatart'));
 893:     }
 894: 
 895:     // delete values from con_cat_art only in the correct language
 896:     $catLangColl = new cApiCategoryLanguageCollection();
 897:     $catLangColl->select('`idlang`=' . cSecurity::toInteger($lang));
 898:     $idcats = $catLangColl->getAllIds();
 899:     $idcatsString = "('" . implode('\',\'', $idcats) . "')";
 900:     $catArtColl->resetQuery();
 901:     $catArtColl->deleteByWhereClause('`idart`=' . $idart . ' AND `idcat` IN ' . $idcatsString);
 902: 
 903:     // delete entry from con_art
 904:     $oArtColl = new cApiArticleCollection();
 905:     $oArtColl->delete((int) $idart);
 906: 
 907:     // this will delete all keywords associated with the article
 908:     $search = new cSearchIndex();
 909:     $search->start($idart, array());
 910: 
 911:     // delete articles meta tags
 912:     $metaTagColl = new cApiMetaTagCollection();
 913:     $metaTagColl->deleteBy('idartlang', (int) $idartlang);
 914: 
 915:     // Contenido Extension Chain
 916:     // @see docs/techref/plugins/Contenido Extension Chainer.pdf
 917:     $iterator = $_cecRegistry->getIterator("Contenido.Content.DeleteArticle");
 918:     while (($chainEntry = $iterator->next()) !== false) {
 919:         $chainEntry->execute($idart);
 920:     }
 921: 
 922:     // delete meta tags
 923:     $metaTagColl = new cApiMetaTagCollection();
 924:     $metaTagColl->deleteBy('idartlang', (int) $idartlang);
 925: 
 926:     // delete article, content and meta tag versions
 927:     $contentVersionColl = new cApiContentVersionCollection();
 928:     $contentVersionColl->deleteBy('idartlang', (int) $idartlang);
 929:     $artLangVersionColl = new cApiArticleLanguageVersionCollection();
 930:     $artLangVersionColl->deleteBy('idartlang', (int) $idartlang);
 931:     $metaTagVersionColl = new cApiMetaTagVersionCollection();
 932:     $metaTagVersionColl->deleteBy('idartlang', (int) $idartlang);
 933: }
 934: 
 935: /**
 936:  * Extract a number from a string
 937:  *
 938:  * @deprecated [2015-05-21]
 939:  *         use cString::extractNumber() instead
 940:  * @param string $string
 941:  *         String var by reference
 942:  * @return string
 943:  */
 944: function extractNumber(&$string) {
 945:     return cString::extractNumber($string);
 946: }
 947: 
 948: /**
 949:  * Change the template of a category
 950:  *
 951:  * @param int $idcat
 952:  *         Category Id
 953:  * @param int $idtpl
 954:  *         Template Id
 955:  */
 956: function conChangeTemplateForCat($idcat, $idtpl) {
 957:     global $lang;
 958: 
 959:     $oCatLang = new cApiCategoryLanguage();
 960:     if (!$oCatLang->loadByCategoryIdAndLanguageId($idcat, $lang)) {
 961:         return;
 962:     }
 963: 
 964:     if ($oCatLang->get('idtplcfg')) {
 965:         // Delete old container configuration
 966:         $oContainerConfColl = new cApiContainerConfigurationCollection();
 967:         $oContainerConfColl->deleteBy('idtplcfg', (int) $oCatLang->get('idtplcfg'));
 968: 
 969:         // Delete old template configuration
 970:         $oTplConfColl = new cApiTemplateConfigurationCollection();
 971:         $oTplConfColl->delete((int) $oCatLang->get('idtplcfg'));
 972:     }
 973: 
 974:     // Parameter $idtpl is 0, reset the template
 975:     if (0 == $idtpl) {
 976:         $oCatLang->set('idtplcfg', 0);
 977:         $oCatLang->store();
 978:     } else {
 979:         // Check if a pre-configuration is assigned
 980:         $oTpl = new cApiTemplate();
 981:         $oTpl->loadBy('idtpl', (int) $idtpl);
 982: 
 983:         if (0 != $oTpl->get('idtplcfg')) {
 984:             // Template is pre-configured, create new configuration
 985:             $oTplConfColl = new cApiTemplateConfigurationCollection();
 986:             $oTplConf = $oTplConfColl->create($idtpl);
 987: 
 988:             // If there is a preconfiguration of template, copy its settings
 989:             // into templateconfiguration
 990:             $oTplConfColl->copyTemplatePreconfiguration($idtpl, $oTplConf->get('idtplcfg'));
 991: 
 992:             // Update category language
 993:             $oCatLang->set('idtplcfg', $oTplConf->get('idtplcfg'));
 994:             $oCatLang->store();
 995:         } else {
 996:             // Template is not pre-configured, create a new configuration.
 997:             $oTplConfColl = new cApiTemplateConfigurationCollection();
 998:             $oTplConf = $oTplConfColl->create($idtpl);
 999: 
1000:             // Update category language
1001:             $oCatLang->set('idtplcfg', $oTplConf->get('idtplcfg'));
1002:             $oCatLang->store();
1003:         }
1004:     }
1005: 
1006:     conGenerateCodeForAllArtsInCategory($idcat);
1007: }
1008: 
1009: /**
1010:  * Returns category tree structure.
1011:  *
1012:  * @param int $client
1013:  *         Uses global set client if not set
1014:  * @param int $lang
1015:  *         Uses global set language if not set
1016:  * @return array
1017:  */
1018: function conFetchCategoryTree($client = false, $lang = false) {
1019:     if ($client === false) {
1020:         $client = $GLOBALS['client'];
1021:     }
1022:     if ($lang === false) {
1023:         $lang = $GLOBALS['lang'];
1024:     }
1025: 
1026:     $oCatTreeColl = new cApiCategoryTreeCollection();
1027:     $aCatTree = $oCatTreeColl->getCategoryTreeStructureByClientIdAndLanguageId($client, $lang);
1028: 
1029:     return $aCatTree;
1030: }
1031: 
1032: /**
1033:  * Return a list of idcats of all scions of given category.
1034:  *
1035:  * @param int $idcat
1036:  *         category ID to start at
1037:  * @return array
1038:  *         idcats of all scions
1039:  */
1040: function conDeeperCategoriesArray($idcat) {
1041:     global $client;
1042: 
1043:     $coll = new cApiCategoryCollection();
1044:     $idcats = $coll->getAllCategoryIdsRecursive($idcat, $client);
1045: 
1046:     return $idcats;
1047: }
1048: 
1049: /**
1050:  * Recursive function to create an location string
1051:  *
1052:  * @param int $idcat
1053:  *         ID of the starting category
1054:  * @param string $seperator
1055:  *         Seperation string
1056:  * @param string $catStr
1057:  *         Category location string (by reference)
1058:  * @param bool $makeLink
1059:  *         Create location string with links
1060:  * @param string $linkClass
1061:  *         Stylesheet class for the links
1062:  * @param int $firstTreeElementToUse
1063:  *         First navigation Level location string should be printed out
1064:  *         (first level = 0!!)
1065:  * @param int $uselang
1066:  *         Id of language
1067:  * @param bool $final
1068:  * @param bool $usecache
1069:  * @return string
1070:  *         Location string
1071:  */
1072: function conCreateLocationString($idcat, $seperator, &$catStr, $makeLink = false, $linkClass = '', $firstTreeElementToUse = 0, $uselang = 0, $final = true, $usecache = false) {
1073:     global $cfg, $client, $cfgClient, $lang, $sess;
1074: 
1075:     if ($idcat == 0) {
1076:         $catStr = i18n("Lost and found");
1077:         return;
1078:     }
1079: 
1080:     if ($uselang == 0) {
1081:         $uselang = $lang;
1082:     }
1083: 
1084:     $locationStringCache = cRegistry::getAppVar('locationStringCache');
1085:     $locationStringCacheFile = $cfgClient[$client]['cache']['path'] . "locationstring-cache-$uselang.txt";
1086: 
1087:     if ($final == true && $usecache == true) {
1088:         if (!is_array($locationStringCache)) {
1089:             if (cFileHandler::exists($locationStringCacheFile)) {
1090:                 $locationStringCache = unserialize(cFileHandler::read($locationStringCacheFile));
1091:             } else {
1092:                 $locationStringCache = array();
1093:             }
1094:             cRegistry::setAppVar('locationStringCache', $locationStringCache);
1095:         }
1096: 
1097:         if (array_key_exists($idcat, $locationStringCache)) {
1098:             if ($locationStringCache[$idcat]['expires'] > time()) {
1099:                 $catStr = $locationStringCache[$idcat]['name'];
1100:                 return;
1101:             }
1102:         }
1103:     }
1104: 
1105:     $db = cRegistry::getDb();
1106: 
1107:     $sql = "SELECT a.name AS name, a.idcat AS idcat, b.parentid AS parentid, c.level as level " . "FROM `:cat_lang` AS a, `:cat` AS b, `:cat_tree` AS c " . "WHERE a.idlang = :idlang AND b.idclient = :idclient AND b.idcat = :idcat AND a.idcat = b.idcat AND c.idcat = b.idcat";
1108: 
1109:     $sql = $db->prepare($sql, array(
1110:         'cat_lang' => $cfg['tab']['cat_lang'],
1111:         'cat' => $cfg['tab']['cat'],
1112:         'cat_tree' => $cfg['tab']['cat_tree'],
1113:         'idlang' => (int) $uselang,
1114:         'idclient' => (int) $client,
1115:         'idcat' => (int) $idcat
1116:     ));
1117:     $db->query($sql);
1118:     $db->nextRecord();
1119: 
1120:     if ($db->f('level') >= $firstTreeElementToUse) {
1121:         $name = $db->f('name');
1122:         $parentid = $db->f('parentid');
1123: 
1124:         // create link
1125:         if ($makeLink == true) {
1126:             $linkUrl = $sess->url("front_content.php?idcat=$idcat");
1127:             $name = '<a href="' . $linkUrl . '" class="' . $linkClass . '">' . $name . '</a>';
1128:         }
1129: 
1130:         $tmp_cat_str = $name . $seperator . $catStr;
1131:         $catStr = $tmp_cat_str;
1132:     }
1133: 
1134:     if ($parentid != 0) {
1135:         conCreateLocationString($parentid, $seperator, $catStr, $makeLink, $linkClass, $firstTreeElementToUse, $uselang, false);
1136:     } else {
1137:         $sep_length = strlen($seperator);
1138:         $str_length = strlen($catStr);
1139:         $tmp_length = $str_length - $sep_length;
1140:         $catStr = substr($catStr, 0, $tmp_length);
1141:     }
1142: 
1143:     if ($final == true && $usecache == true) {
1144:         $locationStringCache[$idcat]['name'] = $catStr;
1145:         $locationStringCache[$idcat]['expires'] = time() + 3600;
1146: 
1147:         if (is_writable($cfgClient[$client]['cache']['path'])) {
1148:             cFileHandler::write($locationStringCacheFile, serialize($locationStringCache));
1149:         }
1150:         cRegistry::setAppVar('locationStringCache', $locationStringCache);
1151:     }
1152: }
1153: 
1154: /**
1155:  * Set a start-article @fixme Do we still need the isstart.
1156:  * The old start
1157:  * compatibility has already been removed...
1158:  *
1159:  * @param int $idcatart
1160:  *         Idcatart of the article
1161:  * @param bool $isstart
1162:  *         Start article flag
1163:  */
1164: function conMakeStart($idcatart, $isstart) {
1165:     global $lang;
1166: 
1167:     // Load category article
1168:     $oCatArt = new cApiCategoryArticle((int) $idcatart);
1169:     if (!$oCatArt->isLoaded()) {
1170:         return;
1171:     }
1172:     $idart = $oCatArt->get('idart');
1173:     $idcat = $oCatArt->get('idcat');
1174: 
1175:     // Load article language
1176:     $oArtLang = new cApiArticleLanguage();
1177:     if (!$oArtLang->loadByArticleAndLanguageId($idart, $lang)) {
1178:         return;
1179:     }
1180:     $idartlang = $oArtLang->get('idartlang');
1181: 
1182:     // Update startidartlang for category language
1183:     $oCatLang = new cApiCategoryLanguage();
1184:     if ($oCatLang->loadByCategoryIdAndLanguageId($idcat, $lang)) {
1185:         if ($isstart == 1) {
1186:             $oCatLang->set('startidartlang', $idartlang);
1187:         } else {
1188:             $oCatLang->set('startidartlang', 0);
1189:         }
1190:         $oCatLang->store();
1191:     }
1192: 
1193:     if ($isstart == 1) {
1194:         // Deactivate time management if article is a start article
1195:         $oArtLang->set('timemgmt', 0);
1196:         $oArtLang->store();
1197:     }
1198: 
1199:     // Execute cec hook
1200:     cApiCecHook::execute('Contenido.Article.ConMakeStart', array(
1201:     'idart' => $oCatArt->get("idart"),
1202:     'idlang' => $lang,
1203:     ));
1204: }
1205: 
1206: /**
1207:  * Create code for one article in all categories
1208:  *
1209:  * @param int $idart
1210:  *         Article ID
1211:  */
1212: function conGenerateCodeForArtInAllCategories($idart) {
1213:     $oCatArtColl = new cApiCategoryArticleCollection();
1214:     $ids = $oCatArtColl->getIdsByWhereClause('idart = ' . (int) $idart);
1215:     conSetCodeFlagBulkEditing($ids);
1216: }
1217: 
1218: /**
1219:  * Generate code for all articles in a category
1220:  *
1221:  * @param int $idcat
1222:  *         Category ID
1223:  */
1224: function conGenerateCodeForAllArtsInCategory($idcat) {
1225:     $oCatArtColl = new cApiCategoryArticleCollection();
1226:     $ids = $oCatArtColl->getIdsByWhereClause('idcat = ' . (int) $idcat);
1227:     conSetCodeFlagBulkEditing($ids);
1228: }
1229: 
1230: /**
1231:  * Generate code for the active client
1232:  */
1233: function conGenerateCodeForClient() {
1234:     global $client;
1235:     $oCatArtColl = new cApiCategoryArticleCollection();
1236:     $ids = $oCatArtColl->getAllIdsByClientId($client);
1237:     conSetCodeFlagBulkEditing($ids);
1238: }
1239: 
1240: /**
1241:  * Create code for all arts using the same layout
1242:  *
1243:  * @param int $idlay
1244:  *         Layout Id
1245:  */
1246: function conGenerateCodeForAllartsUsingLayout($idlay) {
1247:     global $cfg;
1248: 
1249:     $db = cRegistry::getDb();
1250: 
1251:     $sql = "SELECT idtpl FROM " . $cfg["tab"]["tpl"] . " WHERE idlay='" . cSecurity::toInteger($idlay) . "'";
1252:     $db->query($sql);
1253:     while ($db->nextRecord()) {
1254:         conGenerateCodeForAllArtsUsingTemplate($db->f("idtpl"));
1255:     }
1256: }
1257: 
1258: /**
1259:  * Create code for all articles using the same module
1260:  *
1261:  * @param int $idmod
1262:  *         Module Id
1263:  */
1264: function conGenerateCodeForAllartsUsingMod($idmod) {
1265:     $oContainerColl = new cApiContainerCollection();
1266:     $rsList = $oContainerColl->getFieldsByWhereClause(array(
1267:         'idtpl'
1268:     ), 'idmod = ' . (int) $idmod);
1269:     foreach ($rsList as $rs) {
1270:         conGenerateCodeForAllArtsUsingTemplate($rs['idtpl']);
1271:     }
1272: }
1273: 
1274: /**
1275:  * Generate code for all articles using one template
1276:  *
1277:  * @param int $idtpl
1278:  *         Template Id
1279:  */
1280: function conGenerateCodeForAllArtsUsingTemplate($idtpl) {
1281:     global $cfg, $client;
1282: 
1283:     $db = cRegistry::getDb();
1284: 
1285:     $oCatArtColl = new cApiCategoryArticleCollection();
1286: 
1287:     // Search all categories
1288:     $sql = "SELECT
1289:                 b.idcat
1290:             FROM
1291:                 " . $cfg['tab']['tpl_conf'] . " AS a,
1292:                 " . $cfg['tab']['cat_lang'] . " AS b,
1293:                 " . $cfg['tab']['cat'] . " AS c
1294:             WHERE
1295:                 a.idtpl     = " . cSecurity::toInteger($idtpl) . " AND
1296:                 b.idtplcfg  = a.idtplcfg AND
1297:                 c.idclient  = " . cSecurity::toInteger($client) . " AND
1298:                 b.idcat     = c.idcat";
1299: 
1300:     $db->query($sql);
1301: 
1302:     while ($db->nextRecord()) {
1303:         $oCatArtColl->resetQuery();
1304:         $ids = $oCatArtColl->getIdsByWhereClause('idcat = ' . cSecurity::toInteger($db->f('idcat')));
1305:         foreach ($ids as $id) {
1306:             conSetCodeFlag($id);
1307:         }
1308:     }
1309: 
1310:     // Search all articles
1311:     $sql = "SELECT
1312:                 b.idart
1313:             FROM
1314:                 " . $cfg['tab']['tpl_conf'] . " AS a,
1315:                 " . $cfg['tab']['art_lang'] . " AS b,
1316:                 " . $cfg['tab']['art'] . " AS c
1317:             WHERE
1318:                 a.idtpl     = " . cSecurity::toInteger($idtpl) . " AND
1319:                 b.idtplcfg  = a.idtplcfg AND
1320:                 c.idclient  = " . cSecurity::toInteger($client) . " AND
1321:                 b.idart     = c.idart";
1322: 
1323:     $db->query($sql);
1324: 
1325:     while ($db->nextRecord()) {
1326:         $oCatArtColl->resetQuery();
1327:         $ids = $oCatArtColl->getIdsByWhereClause('idart = ' . (int) $db->f('idart'));
1328:         foreach ($ids as $id) {
1329:             conSetCodeFlag($id);
1330:         }
1331:     }
1332: }
1333: 
1334: /**
1335:  * Create code for all articles
1336:  */
1337: function conGenerateCodeForAllArts() {
1338:     global $cfg;
1339: 
1340:     $db = cRegistry::getDb();
1341: 
1342:     $sql = "SELECT idcatart FROM " . $cfg['tab']['cat_art'];
1343:     $db->query($sql);
1344:     while ($db->nextRecord()) {
1345:         conSetCodeFlag($db->f("idcatart"));
1346:     }
1347: }
1348: 
1349: /**
1350:  * Set code creation flag for one category article id to true
1351:  *
1352:  * @param int $idcatart
1353:  *         category article ID
1354:  */
1355: function conSetCodeFlag($idcatart) {
1356:     global $client, $cfgClient;
1357: 
1358:     // Set 'createcode' flag
1359:     $coll = new cApiCategoryArticleCollection();
1360:     $coll->setCreateCodeFlag($idcatart);
1361: 
1362:     // Delete also generated code files from file system
1363:     if (cFileHandler::exists($cfgClient[$client]['code']['path'])) {
1364:         /* @var $file SplFileInfo */
1365:         foreach (new DirectoryIterator($cfgClient[$client]['code']['path']) as $file) {
1366:             if ($file->isFile() === false) {
1367:                 continue;
1368:             }
1369: 
1370:             $extension = substr($file, strrpos($file->getBasename(), '.') + 1);
1371:             if ($extension != 'php') {
1372:                 continue;
1373:             }
1374: 
1375:             if (preg_match('/[0-9*].[0-9*].' . $idcatart . '/s', $file->getBasename())) {
1376:                 cFileHandler::remove($cfgClient[$client]['code']['path'] . '/' . $file->getFilename());
1377:             }
1378:         }
1379:     }
1380: }
1381: 
1382: /**
1383:  * Set code creation flag for several category article ids to true
1384:  *
1385:  * @param array $idcatarts
1386:  *         List of category article ids
1387:  */
1388: function conSetCodeFlagBulkEditing(array $idcatarts) {
1389:     global $client, $cfgClient;
1390: 
1391:     if (count($idcatarts) == 0) {
1392:         return;
1393:     }
1394: 
1395:     // Set 'createcode' flag
1396:     $oCatArtColl = new cApiCategoryArticleCollection();
1397:     $oCatArtColl->setCreateCodeFlag($idcatarts);
1398: 
1399:     if (cFileHandler::exists($cfgClient[$client]['code']['path']) === false) {
1400:         return;
1401:     }
1402: 
1403:     // Delete also generated code files from file system
1404:     foreach ($idcatarts as $id) {
1405:         /* @var $file SplFileInfo */
1406:         foreach (new DirectoryIterator($cfgClient[$client]['code']['path']) as $file) {
1407:             if ($file->isFile() === false) {
1408:                 continue;
1409:             }
1410: 
1411:             $extension = substr($file, strrpos($file->getBasename(), '.') + 1);
1412:             if ($extension != 'php') {
1413:                 continue;
1414:             }
1415: 
1416:             if (preg_match('/[0-9*].[0-9*].' . $id . '/s', $file->getBasename())) {
1417:                 cFileHandler::remove($cfgClient[$client]['code']['path'] . '/' . $file->getFilename());
1418:             }
1419:         }
1420:     }
1421: }
1422: 
1423: /**
1424:  * Set articles on/offline for the time management function
1425:  */
1426: function conFlagOnOffline() {
1427:     global $cfg;
1428: 
1429:     $db = cRegistry::getDb();
1430: 
1431:     $oArtLangColl = new cApiArticleLanguageCollection();
1432: 
1433:     // Set all articles which are before our starttime to offline
1434:     $where = "NOW() < datestart AND datestart != '0000-00-00 00:00:00' AND datestart IS NOT NULL AND timemgmt = 1";
1435:     $ids = $oArtLangColl->getIdsByWhereClause($where);
1436:     foreach ($ids as $id) {
1437:         $sql = "UPDATE " . $cfg['tab']['art_lang'] . " SET online = 0 WHERE idartlang = " . (int) $id;
1438:         $db->query($sql);
1439:     }
1440:     if(count($ids) > 0) {
1441:         // Execute cec hook
1442:         cApiCecHook::execute('Contenido.Article.conFlagOnOffline', $ids);
1443:     }
1444: 
1445:     // Set all articles which are in between of our start/endtime to online
1446:     $where = "NOW() > datestart AND (NOW() < dateend OR dateend = '0000-00-00 00:00:00') AND " . "online = 0 AND timemgmt = 1";
1447:     $oArtLangColl->resetQuery();
1448:     $ids = $oArtLangColl->getIdsByWhereClause($where);
1449:     foreach ($ids as $id) {
1450:         $sql = "UPDATE " . $cfg['tab']['art_lang'] . " SET online = 1, published = datestart WHERE idartlang = " . (int) $id;
1451:         $db->query($sql);
1452:     }
1453:     if(count($ids) > 0) {
1454:         // Execute cec hook
1455:         cApiCecHook::execute('Contenido.Article.conFlagOnOffline', $ids);
1456:     }
1457: 
1458:     // Set all articles after our endtime to offline
1459:     $where = "NOW() > dateend AND dateend != '0000-00-00 00:00:00' AND timemgmt = 1 AND online = 1";
1460:     $oArtLangColl->resetQuery();
1461:     $ids = $oArtLangColl->getIdsByWhereClause($where);
1462:     foreach ($ids as $id) {
1463:         $sql = "UPDATE " . $cfg['tab']['art_lang'] . " SET online = 0 WHERE idartlang = " . (int) $id;
1464:         $db->query($sql);
1465:     }
1466:     if(count($ids) > 0) {
1467:         // Execute cec hook
1468:         cApiCecHook::execute('Contenido.Article.conFlagOnOffline', $ids);
1469:     }
1470: }
1471: 
1472: /**
1473:  * Move articles for the time management function
1474:  */
1475: function conMoveArticles() {
1476:     global $cfg;
1477: 
1478:     $db = cRegistry::getDb();
1479: 
1480:     // Perform after-end updates
1481:     $fields = array(
1482:         'idartlang',
1483:         'idart',
1484:         'time_move_cat',
1485:         'time_target_cat',
1486:         'time_online_move'
1487:     );
1488:     $where = "NOW() > dateend AND dateend != '0000-00-00 00:00:00' AND timemgmt = 1 AND time_move_cat = 1";
1489:     $oArtLangColl = new cApiArticleLanguageCollection();
1490:     $rsList = $oArtLangColl->getFieldsByWhereClause($fields, $where);
1491: 
1492:     foreach ($rsList as $rs) {
1493:         $online = ($rs['time_online_move'] == '1')? 1 : 0;
1494:         $sql = array();
1495:         $sql[] = 'UPDATE ' . $cfg['tab']['art_lang'] . ' SET timemgmt = 0, online = 0 WHERE idartlang = ' . (int) $rs['idartlang'] . ';';
1496:         $sql[] = 'UPDATE ' . $cfg['tab']['cat_art'] . ' SET idcat = ' . (int) $rs['time_target_cat'] . ', createcode = 1 WHERE idart = ' . (int) $rs['idart'] . ';';
1497:         $sql[] = 'UPDATE ' . $cfg['tab']['art_lang'] . ' SET online = ' . (int) $online . ' WHERE idart = ' . (int) $rs['idart'] . ';';
1498: 
1499:         // $sql = implode("\n", $sql);
1500:         // cDebug::out($sql);
1501:         $db->query($sql[0]);
1502:         $db->query($sql[1]);
1503:         $db->query($sql[2]);
1504: 
1505:         // Execute CEC hook
1506:         cApiCecHook::execute('Contenido.Article.conMoveArticles_Loop', $rs);
1507:     }
1508: }
1509: 
1510: /**
1511:  * Copies template configuration entry from source template configuration.
1512:  *
1513:  * @param int $srcidtplcfg
1514:  * @return int|NULL
1515:  */
1516: function conCopyTemplateConfiguration($srcidtplcfg) {
1517:     $oTemplateConf = new cApiTemplateConfiguration((int) $srcidtplcfg);
1518:     if (!$oTemplateConf->isLoaded()) {
1519:         return NULL;
1520:     }
1521: 
1522:     $oTemplateConfColl = new cApiTemplateConfigurationCollection();
1523:     $oNewTemplateConf = $oTemplateConfColl->create($oTemplateConf->get('idtpl'));
1524:     return (is_object($oNewTemplateConf))? $oNewTemplateConf->get('idtplcfg') : NULL;
1525: }
1526: 
1527: /**
1528:  * Copies container configuration entries from source container configuration
1529:  * to destination container configuration.
1530:  *
1531:  * @param int $srcidtplcfg
1532:  * @param int $dstidtplcfg
1533:  * @return boolean
1534:  */
1535: function conCopyContainerConf($srcidtplcfg, $dstidtplcfg) {
1536:     $counter = 0;
1537:     $oContainerConfColl = new cApiContainerConfigurationCollection();
1538:     $oContainerConfColl->select('idtplcfg = ' . cSecurity::toInteger($srcidtplcfg));
1539:     while (($oContainerConf = $oContainerConfColl->next()) !== false) {
1540:         $oNewContainerConfColl = new cApiContainerConfigurationCollection();
1541:         $oNewContainerConfColl->copyItem($oContainerConf, array(
1542:             'idtplcfg' => cSecurity::toInteger($dstidtplcfg)
1543:         ));
1544:         $counter++;
1545:     }
1546:     return ($counter > 0)? true : false;
1547: }
1548: 
1549: /**
1550:  * Copies content entries from source article language to destination article
1551:  * language.
1552:  *
1553:  * @param int $srcidartlang
1554:  * @param int $dstidartlang
1555:  */
1556: function conCopyContent($srcidartlang, $dstidartlang) {
1557:     $oContentColl = new cApiContentCollection();
1558:     $oContentColl->select('idartlang = ' . cSecurity::toInteger($srcidartlang));
1559:     while (($oContent = $oContentColl->next()) !== false) {
1560:         $oNewContentColl = new cApiContentCollection();
1561:         $oNewContentColl->copyItem($oContent, array(
1562:             'idartlang' => cSecurity::toInteger($dstidartlang)
1563:         ));
1564:     }
1565: }
1566: 
1567: /**
1568:  * Copies meta tag entries from source article language to destination article
1569:  * language.
1570:  *
1571:  * @param int $srcidartlang
1572:  * @param int $dstidartlang
1573:  */
1574: function conCopyMetaTags($srcidartlang, $dstidartlang) {
1575:     $oMetaTagColl = new cApiMetaTagCollection();
1576:     $oMetaTagColl->select('idartlang = ' . cSecurity::toInteger($srcidartlang));
1577:     while (($oMetaTag = $oMetaTagColl->next()) !== false) {
1578:         $oNewMetaTagColl = new cApiMetaTagCollection();
1579:         $oNewMetaTagColl->copyItem($oMetaTag, array(
1580:             'idartlang' => cSecurity::toInteger($dstidartlang)
1581:         ));
1582:     }
1583: }
1584: 
1585: /**
1586:  * Copy article language entry.
1587:  *
1588:  * @global array $cfg
1589:  * @global int $lang
1590:  * @param int $srcidart
1591:  * @param int $dstidart
1592:  * @param int $newtitle
1593:  * @param int $useCopyLabel
1594:  */
1595: function conCopyArtLang($srcidart, $dstidart, $newtitle, $useCopyLabel = true) {
1596:     global $auth, $lang;
1597: 
1598:     $oSrcArtLang = new cApiArticleLanguage();
1599:     if (!$oSrcArtLang->loadByArticleAndLanguageId($srcidart, $lang)) {
1600:         return;
1601:     }
1602: 
1603:     // Copy the template configuration
1604:     if ($oSrcArtLang->get('idtplcfg') != 0) {
1605:         $newidtplcfg = conCopyTemplateConfiguration($oSrcArtLang->get('idtplcfg'));
1606:         conCopyContainerConf($oSrcArtLang->get('idtplcfg'), $newidtplcfg);
1607:     }
1608: 
1609:     $idart = $dstidart;
1610:     $idlang = $oSrcArtLang->get('idlang');
1611:     $idtplcfg = $newidtplcfg;
1612: 
1613:     if ($newtitle != '') {
1614:         $title = sprintf($newtitle, $oSrcArtLang->get('title'));
1615:     } else if ($useCopyLabel == true) {
1616:         $title = sprintf(i18n('%s (Copy)'), $oSrcArtLang->get('title'));
1617:     } else {
1618:         $title = $oSrcArtLang->get('title');
1619:     }
1620: 
1621:     // Create an article language entry
1622:     $oArtLangColl = new cApiArticleLanguageCollection();
1623:     $fieldsToOverwrite = array(
1624:         'idart' => $idart,
1625:         'idlang' => $idlang,
1626:         'idtplcfg' => cSecurity::toInteger($idtplcfg),
1627:         'online' => 0,
1628:         'title' => $title,
1629:         'created' => date('Y-m-d H:i:s'),
1630:         'lastmodified' => date('Y-m-d H:i:s'),
1631:         'modifiedby' => $auth->auth['uname'],
1632:         'published' => '',
1633:         'publishedby' => ''
1634:     );
1635:     $oNewArtLang = $oArtLangColl->copyItem($oSrcArtLang, $fieldsToOverwrite);
1636: 
1637:     if (!is_object($oNewArtLang)) {
1638:         return;
1639:     }
1640: 
1641:     // Copy content
1642:     conCopyContent($oSrcArtLang->get('idartlang'), $oNewArtLang->get('idartlang'));
1643: 
1644:     // Copy meta tags
1645:     conCopyMetaTags($oSrcArtLang->get('idartlang'), $oNewArtLang->get('idartlang'));
1646: 
1647:     // Execute CEC hook
1648:     cApiCecHook::execute('Contenido.Article.conCopyArtLang_AfterInsert', array(
1649:         'idartlang' => cSecurity::toInteger($oNewArtLang->get('idartlang')),
1650:         'idart' => cSecurity::toInteger($idart),
1651:         'idlang' => cSecurity::toInteger($idlang),
1652:         'idtplcfg' => cSecurity::toInteger($idtplcfg),
1653:         'title' => $title
1654:     ));
1655: 
1656:     // Update keyword list for new article
1657:     $versioning = new cContentVersioning();
1658:     if ($versioning->getState() != 'advanced') {
1659:         conMakeArticleIndex($oNewArtLang->get('idartlang'), $idart);
1660:     }
1661: }
1662: 
1663: /**
1664:  * Copy article entry.
1665:  *
1666:  * @global object $auth
1667:  * @param int $srcidart
1668:  * @param int $targetcat
1669:  * @param string $newtitle
1670:  * @param bool $useCopyLabel
1671:  * @return bool
1672:  */
1673: function conCopyArticle($srcidart, $targetcat = 0, $newtitle = '', $useCopyLabel = true) {
1674:     // Get source article
1675:     $oSrcArt = new cApiArticle((int) $srcidart);
1676:     if (!$oSrcArt->isLoaded()) {
1677:         return false;
1678:     }
1679:     $idclient = $oSrcArt->get('idclient');
1680: 
1681:     // Create destination article
1682:     $oArtCollection = new cApiArticleCollection();
1683:     $oNewArt = $oArtCollection->create($idclient);
1684:     if (!is_object($oNewArt)) {
1685:         return false;
1686:     }
1687:     $dstidart = $oNewArt->get('idart');
1688: 
1689:     conCopyArtLang($srcidart, $dstidart, $newtitle, $useCopyLabel);
1690: 
1691:     // Get source category article entries
1692:     $oCatArtColl = new cApiCategoryArticleCollection();
1693:     $oCatArtColl->select('idart = ' . (int) $srcidart);
1694:     while (($oCatArt = $oCatArtColl->next()) !== false) {
1695:         // Insert destination category article entry
1696:         $oCatArtColl2 = new cApiCategoryArticleCollection();
1697:         $fieldsToOverwrite = array(
1698:             'idcat' => ($targetcat != 0)? $targetcat : $oCatArt->get('idcat'),
1699:             'idart' => $dstidart,
1700:             'status' => ($oCatArt->get('status') !== '')? $oCatArt->get('status') : 0,
1701:             'createcode' => 1,
1702:             'is_start' => 0
1703:         );
1704:         $oCatArtColl2->copyItem($oCatArt, $fieldsToOverwrite);
1705: 
1706:         // If true, exit while routine, only one category entry is needed
1707:         if ($targetcat != 0) {
1708:             break;
1709:         }
1710:     }
1711: 
1712:     // Contenido Extension Chain
1713:     // @see docs/techref/plugins/Contenido Extension Chainer.pdf
1714:     $_cecRegistry = cApiCecRegistry::getInstance();
1715:     $iterator = $_cecRegistry->getIterator('Contenido.Content.CopyArticle');
1716:     while (($chainEntry = $iterator->next()) !== false) {
1717:         $chainEntry->execute($srcidart, $dstidart);
1718:     }
1719: 
1720:     return $dstidart;
1721: }
1722: 
1723: /**
1724:  *
1725:  * @todo Returns something....
1726:  * @global array $cfg
1727:  * @global int $client
1728:  * @global int $lang
1729:  * @param int $idcat
1730:  * @param int $minLevel
1731:  * @return int
1732:  */
1733: function conGetTopmostCat($idcat, $minLevel = 0) {
1734:     global $cfg, $client, $lang;
1735: 
1736:     $db = cRegistry::getDb();
1737: 
1738:     $sql = "SELECT a.name AS name, a.idcat AS idcat, b.parentid AS parentid, c.level AS level
1739:             FROM `:cat_lang` AS a, `:cat` AS b, `:cat_tree` AS c
1740:             WHERE a.idlang = :idlang AND b.idclient = :idclient AND b.idcat = :idcat
1741:             AND c.idcat = b.idcat AND a.idcat = b.idcat";
1742: 
1743:     $sql = $db->prepare($sql, array(
1744:         'cat_lang' => $cfg['tab']['cat_lang'],
1745:         'cat' => $cfg['tab']['cat'],
1746:         'cat_tree' => $cfg['tab']['cat_tree'],
1747:         'idlang' => (int) $lang,
1748:         'idclient' => (int) $client,
1749:         'idcat' => (int) $idcat
1750:     ));
1751:     $db->query($sql);
1752:     $db->nextRecord();
1753: 
1754:     $name = $db->f('name');
1755:     $parentid = $db->f('parentid');
1756:     $thislevel = $db->f('level');
1757: 
1758:     if ($parentid != 0 && $thislevel >= $minLevel) {
1759:         return conGetTopmostCat($parentid, $minLevel);
1760:     } else {
1761:         return $idcat;
1762:     }
1763: }
1764: 
1765: /**
1766:  * Synchronizes an article from source language to destination language.
1767:  *
1768:  * @param int $idart
1769:  *         Article id
1770:  * @param int $srclang
1771:  *         Source language id
1772:  * @param int $dstlang
1773:  *         Destination language id
1774:  */
1775: function conSyncArticle($idart, $srclang, $dstlang) {
1776:     $auth = cRegistry::getAuth();
1777: 
1778:     // Check if article has already been synced to target language
1779:     $dstArtLang = new cApiArticleLanguage();
1780:     $dstArtLang->loadByArticleAndLanguageId($idart, $dstlang);
1781:     if ($dstArtLang->isLoaded()) {
1782:         // Article already exists in detination language
1783:         return;
1784:     }
1785: 
1786:     $srcArtLang = new cApiArticleLanguage();
1787:     $srcArtLang->loadByArticleAndLanguageId($idart, $srclang);
1788:     if (!$srcArtLang->isLoaded()) {
1789:         // Couldn't load article in source language
1790:         return;
1791:     }
1792:     $srcidartlang = $srcArtLang->get('idartlang');
1793: 
1794:     if ($srcArtLang->get('idtplcfg') != 0) {
1795:         $newidtplcfg = tplcfgDuplicate($srcArtLang->get('idtplcfg'));
1796:     } else {
1797:         $newidtplcfg = 0;
1798:     }
1799: 
1800:     // Create an article language entry for destination language
1801:     $artLangColl = new cApiArticleLanguageCollection();
1802:     $fieldsToOverwrite = array(
1803:         'idart' => $idart,
1804:         'idlang' => $dstlang,
1805:         'artspec' => 0,
1806:         'online' => 0,
1807:         'created' => date('Y-m-d H:i:s'),
1808:         'lastmodified' => date('Y-m-d H:i:s'),
1809:         'modifiedby' => $auth->auth['uname'],
1810:         'published' => '',
1811:         'publishedby' => '',
1812:         'timemgmt' => 0,
1813:         'datestart' => '',
1814:         'dateend' => '',
1815:         'status' => 0,
1816:         'time_move_cat' => 0,
1817:         'time_target_cat' => 0,
1818:         'time_online_move' => 0,
1819:         'free_use_01' => '',
1820:         'free_use_02' => '',
1821:         'free_use_03' => ''
1822:     );
1823:     $artLang = $artLangColl->copyItem($srcArtLang, $fieldsToOverwrite);
1824:     if (!is_object($artLang)) {
1825:         return;
1826:     }
1827: 
1828:     $newidartlang = $artLang->get('idartlang');
1829: 
1830:     // Execute CEC hook
1831:     $param = array();
1832:     $param['src_art_lang'] = $srcArtLang->toArray();
1833:     $param['dest_art_lang'] = $dstArtLang->toArray();
1834:     $param['dest_art_lang']['idartlang'] = cSecurity::toInteger($newidartlang);
1835:     $param['dest_art_lang']['idlang'] = cSecurity::toInteger($dstlang);
1836:     $param['dest_art_lang']['idtplcfg'] = cSecurity::toInteger($newidtplcfg);
1837:     cApiCecHook::execute('Contenido.Article.conSyncArticle_AfterInsert', $param);
1838: 
1839:     // Copy content
1840:     conCopyContent($srcidartlang, $newidartlang);
1841: 
1842:     // Copy meta tags
1843:     conCopyMetaTags($srcidartlang, $newidartlang);
1844: }
1845: 
1846: /**
1847:  * Checks if an article is a start article of a category.
1848:  *
1849:  * @param int $idartlang
1850:  * @param int $idcat
1851:  * @param int $idlang
1852:  * @param cDb $db [optional]
1853:  *         If specified, uses the given db object (NOT used)
1854:  * @return bool
1855:  */
1856: function isStartArticle($idartlang, $idcat, $idlang, $db = NULL) {
1857:     $oCatLangColl = new cApiCategoryLanguageCollection();
1858:     return $oCatLangColl->isStartArticle($idartlang, $idcat, $idlang);
1859: }
1860: 
1861: /**
1862:  * Returns all categories in which the given article is in.
1863:  *
1864:  * @param int $idart
1865:  *         Article ID
1866:  * @param cDb $db [optional]
1867:  *         If specified, uses the given db object (NOT used)
1868:  * @return array
1869:  *         Flat array which contains all category id's
1870:  */
1871: function conGetCategoryAssignments($idart, $db = NULL) {
1872: 
1873:     // Return empty array if idart is null (or empty)
1874:     if (empty($idart)) {
1875:         return array();
1876:     }
1877: 
1878:     $categories = array();
1879:     $oCatArtColl = new cApiCategoryArticleCollection();
1880:     $entries = $oCatArtColl->getFieldsByWhereClause(array(
1881:         'idcat'
1882:     ), 'idart = ' . (int) $idart);
1883:     foreach ($entries as $entry) {
1884:         $categories[] = $entry['idcat'];
1885:     }
1886:     return $categories;
1887: }
1888: 
1889: /**
1890:  * Deletes old category article entries and other related entries from other
1891:  * tables.
1892:  *
1893:  * @global array $cfgClient
1894:  * @param int $idcat
1895:  * @param int $idart
1896:  * @param int $idartlang
1897:  * @param int $client
1898:  * @param int $lang
1899:  */
1900: function conRemoveOldCategoryArticle($idcat, $idart, $idartlang, $client, $lang) {
1901:     global $cfgClient;
1902: 
1903:     // Get category article that will no longer exist
1904:     $oCatArtColl = new cApiCategoryArticleCollection();
1905:     $oCatArt = $oCatArtColl->fetchByCategoryIdAndArticleId($idcat, $idart);
1906:     if (!is_object($oCatArt)) {
1907:         return;
1908:     }
1909: 
1910:     $idcatart = $oCatArt->get('idcatart');
1911: 
1912:     // Delete from code cache and delete corresponding code
1913:     /* @var $file SplFileInfo */
1914:     foreach (new DirectoryIterator($cfgClient[$client]['code']['path']) as $file) {
1915:         if ($file->isFile() === false) {
1916:             continue;
1917:         }
1918: 
1919:         $extension = substr($file, strrpos($file->getBasename(), '.') + 1);
1920:         if ($extension != 'php') {
1921:             continue;
1922:         }
1923: 
1924:         if (preg_match('/[0-9*].[0-9*].' . $idcatart . '/s', $file->getBasename())) {
1925:             cFileHandler::remove($cfgClient[$client]['code']['path'] . '/' . $file->getFilename());
1926:         }
1927:     }
1928: 
1929:     // Delete statistics
1930:     $oStatColl = new cApiStatCollection();
1931:     $oStatColl->deleteByCategoryArticleAndLanguage($idcatart, $lang);
1932: 
1933:     // Delete category article
1934:     $oCatArtColl->delete($idcatart);
1935: 
1936:     // Remove startidartlang
1937:     if (isStartArticle($idartlang, $idcat, $lang)) {
1938:         $oCatLang = new cApiCategoryLanguage();
1939:         $oCatLang->loadByCategoryIdAndLanguageId($idcat, $lang);
1940:         if ($oCatLang->isLoaded()) {
1941:             $oCatLang->set('startidartlang', 0);
1942:             $oCatLang->store();
1943:         }
1944:     }
1945: 
1946:     // Delete template configuration
1947:     $oArtLang = new cApiArticleLanguage();
1948:     $oArtLang->loadByArticleAndLanguageId($idart, $lang);
1949:     if ($oArtLang->isLoaded() && $oArtLang->get('idtplcfg') > 0) {
1950:         $oTplCfgColl = new cApiTemplateConfigurationCollection();
1951:         $oTplCfgColl->delete($oArtLang->get('idtplcfg'));
1952:     }
1953: }
1954: 
CMS CONTENIDO 4.9.11 API documentation generated by ApiGen 2.8.0