Overview

Packages

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

Classes

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

Functions

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