|
eZ Publish
[4.0]
|
00001 <?php 00002 // 00003 // Definition of eZContentClass class 00004 // 00005 // Created on: <16-Apr-2002 11:08:14 amos> 00006 // 00007 // ## BEGIN COPYRIGHT, LICENSE AND WARRANTY NOTICE ## 00008 // SOFTWARE NAME: eZ Publish 00009 // SOFTWARE RELEASE: 4.0.x 00010 // COPYRIGHT NOTICE: Copyright (C) 1999-2008 eZ Systems AS 00011 // SOFTWARE LICENSE: GNU General Public License v2.0 00012 // NOTICE: > 00013 // This program is free software; you can redistribute it and/or 00014 // modify it under the terms of version 2.0 of the GNU General 00015 // Public License as published by the Free Software Foundation. 00016 // 00017 // This program is distributed in the hope that it will be useful, 00018 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00019 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00020 // GNU General Public License for more details. 00021 // 00022 // You should have received a copy of version 2.0 of the GNU General 00023 // Public License along with this program; if not, write to the Free 00024 // Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 00025 // MA 02110-1301, USA. 00026 // 00027 // 00028 // ## END COPYRIGHT, LICENSE AND WARRANTY NOTICE ## 00029 // 00030 00031 /*! 00032 \class eZContentClass ezcontentclass.php 00033 \ingroup eZKernel 00034 \brief Handles eZ Publish content classes 00035 00036 \sa eZContentObject 00037 */ 00038 00039 //include_once( "lib/ezdb/classes/ezdb.php" ); 00040 //include_once( "kernel/classes/ezpersistentobject.php" ); 00041 //include_once( "kernel/classes/ezcontentobject.php" ); 00042 //include_once( "kernel/classes/ezcontentclassattribute.php" ); 00043 //include_once( "kernel/classes/ezcontentclassclassgroup.php" ); 00044 //include_once( "kernel/classes/ezcontentclassnamelist.php" ); 00045 require_once( "kernel/common/i18n.php" ); 00046 00047 class eZContentClass extends eZPersistentObject 00048 { 00049 const VERSION_STATUS_DEFINED = 0; 00050 const VERSION_STATUS_TEMPORARY = 1; 00051 const VERSION_STATUS_MODIFIED = 2; 00052 00053 function eZContentClass( $row ) 00054 { 00055 if ( is_array( $row ) ) 00056 { 00057 $this->eZPersistentObject( $row ); 00058 $this->VersionCount = false; 00059 $this->InGroups = null; 00060 $this->AllGroups = null; 00061 if ( isset( $row["version_count"] ) ) 00062 $this->VersionCount = $row["version_count"]; 00063 00064 $this->NameList = new eZContentClassNameList(); 00065 if ( isset( $row['serialized_name_list'] ) ) 00066 $this->NameList->initFromSerializedList( $row['serialized_name_list'] ); 00067 else 00068 $this->NameList->initDefault(); 00069 } 00070 $this->DataMap = false; 00071 } 00072 00073 static function definition() 00074 { 00075 return array( "fields" => array( "id" => array( 'name' => 'ID', 00076 'datatype' => 'integer', 00077 'default' => 0, 00078 'required' => true ), 00079 "version" => array( 'name' => 'Version', 00080 'datatype' => 'integer', 00081 'default' => 0, 00082 'required' => true ), 00083 "serialized_name_list" => array( 'name' => 'SerializedNameList', 00084 'datatype' => 'string', 00085 'default' => '', 00086 'required' => true ), 00087 "identifier" => array( 'name' => "Identifier", 00088 'datatype' => 'string', 00089 'default' => '', 00090 'required' => true ), 00091 "contentobject_name" => array( 'name' => "ContentObjectName", 00092 'datatype' => 'string', 00093 'default' => '', 00094 'required' => true ), 00095 "url_alias_name" => array( 'name' => "URLAliasName", 00096 'datatype' => 'string', 00097 'default' => '', 00098 'required' => false ), 00099 "creator_id" => array( 'name' => "CreatorID", 00100 'datatype' => 'integer', 00101 'default' => 0, 00102 'required' => true, 00103 'foreign_class' => 'eZUser', 00104 'foreign_attribute' => 'contentobject_id', 00105 'multiplicity' => '1..*' ), 00106 "modifier_id" => array( 'name' => "ModifierID", 00107 'datatype' => 'integer', 00108 'default' => 0, 00109 'required' => true, 00110 'foreign_class' => 'eZUser', 00111 'foreign_attribute' => 'contentobject_id', 00112 'multiplicity' => '1..*' ), 00113 "created" => array( 'name' => "Created", 00114 'datatype' => 'integer', 00115 'default' => 0, 00116 'required' => true ), 00117 "remote_id" => array( 'name' => "RemoteID", 00118 'datatype' => 'string', 00119 'default' => '', 00120 'required' => true ), 00121 "modified" => array( 'name' => "Modified", 00122 'datatype' => 'integer', 00123 'default' => 0, 00124 'required' => true ), 00125 "is_container" => array( 'name' => "IsContainer", 00126 'datatype' => 'integer', 00127 'default' => 0, 00128 'required' => true ), 00129 'always_available' => array( 'name' => "AlwaysAvailable", 00130 'datatype' => 'integer', 00131 'default' => 0, 00132 'required' => true ), 00133 'language_mask' => array( 'name' => "LanguageMask", 00134 'datatype' => 'integer', 00135 'default' => 0, 00136 'required' => true ), 00137 'initial_language_id' => array( 'name' => "InitialLanguageID", 00138 'datatype' => 'integer', 00139 'default' => 0, 00140 'required' => true, 00141 'foreign_class' => 'eZContentLanguage', 00142 'foreign_attribute' => 'id', 00143 'multiplicity' => '1..*' ), 00144 'sort_field' => array( 'name' => 'SortField', 00145 'datatype' => 'integer', 00146 'default' => 1, 00147 'required' => true ), 00148 'sort_order' => array( 'name' => 'SortOrder', 00149 'datatype' => 'integer', 00150 'default' => 1, 00151 'required' => true ) ), 00152 "keys" => array( "id", "version" ), 00153 "function_attributes" => array( "data_map" => "dataMap", 00154 'object_count' => 'objectCount', 00155 'object_list' => 'objectList', 00156 'version_count' => 'versionCount', 00157 'version_status' => 'versionStatus', 00158 'remote_id' => 'remoteID', // Note: This overrides remote_id field 00159 'ingroup_list' => 'fetchGroupList', 00160 'ingroup_id_list' => 'fetchGroupIDList', 00161 'match_ingroup_id_list' => 'fetchMatchGroupIDList', 00162 'group_list' => 'fetchAllGroups', 00163 'creator' => 'creator', 00164 'modifier' => 'modifier', 00165 'can_instantiate_languages' => 'canInstantiateLanguages', 00166 'name' => 'name', 00167 'nameList' => 'nameList', 00168 'languages' => 'languages', 00169 'prioritized_languages' => 'prioritizedLanguages', 00170 'prioritized_languages_js_array' => 'prioritizedLanguagesJsArray', 00171 'can_create_languages' => 'canCreateLanguages', 00172 'top_priority_language_locale' => 'topPriorityLanguageLocale', 00173 'always_available_language' => 'alwaysAvailableLanguage' ), 00174 'set_functions' => array( 'name' => 'setName' ), 00175 "increment_key" => "id", 00176 "class_name" => "eZContentClass", 00177 "sort" => array( "id" => "asc" ), 00178 "name" => "ezcontentclass" ); 00179 } 00180 00181 function __clone() 00182 { 00183 unset( $this->Version ); 00184 unset( $this->InGroups ); 00185 unset( $this->AllGroups ); 00186 unset( $this->CanInstantiateLanguages ); 00187 unset( $this->VersionCount ); 00188 $this->ID = null; 00189 $this->RemoteID = md5( (string)mt_rand() . (string)time() ); 00190 } 00191 00192 /*! 00193 Creates an 'eZContentClass' object. 00194 00195 To specify contentclass name use either $optionalValues['serialized_name_list'] or 00196 combination of $optionalValues['name'] and/or $languageLocale. 00197 00198 In case of conflict(when both 'serialized_name_list' and 'name' with/without $languageLocale 00199 are specified) 'serialized_name_list' has top priority. This means that 'name' and 00200 $languageLocale will be ingnored because 'serialized_name_list' already has all needed info 00201 about names and languages. 00202 00203 If 'name' is specified then the contentclass will have a name in $languageLocale(if specified) or 00204 in default language. 00205 00206 If neither of 'serialized_name_list' or 'name' isn't specified then the contentclass will have an empty 00207 name in 'languageLocale'(if specified) or in default language. 00208 00209 'language_mask' and 'initial_language_id' attributes will be set according to specified(either 00210 in 'serialized_name_list' or by $languageLocale) languages. 00211 00212 \return 'eZContentClass' object. 00213 */ 00214 static function create( $userID = false, $optionalValues = array(), $languageLocale = false ) 00215 { 00216 $dateTime = time(); 00217 if ( !$userID ) 00218 $userID = eZUser::currentUserID(); 00219 00220 $nameList = new eZContentClassNameList(); 00221 if ( isset( $optionalValues['serialized_name_list'] ) ) 00222 $nameList->initFromSerializedList( $optionalValues['serialized_name_list'] ); 00223 else if ( isset( $optionalValues['name'] ) ) 00224 $nameList->initFromString( $optionalValues['name'], $languageLocale ); 00225 else 00226 $nameList->initFromString( '', $languageLocale ); 00227 00228 $languageMask = $nameList->languageMask(); 00229 $initialLanguageID = $nameList->alwaysAvailableLanguageID(); 00230 00231 $contentClassDefinition = eZContentClass::definition(); 00232 $row = array( 00233 "id" => null, 00234 "version" => 1, 00235 "serialized_name_list" => $nameList->serializeNames(), 00236 "identifier" => "", 00237 "contentobject_name" => "", 00238 "creator_id" => $userID, 00239 "modifier_id" => $userID, 00240 "created" => $dateTime, 00241 'remote_id' => md5( (string)mt_rand() . (string)time() ), 00242 "modified" => $dateTime, 00243 "is_container" => $contentClassDefinition[ 'fields' ][ 'is_container' ][ 'default' ], 00244 "always_available" => $contentClassDefinition[ 'fields' ][ 'always_available' ][ 'default' ], 00245 'language_mask' => $languageMask, 00246 'initial_language_id' => $initialLanguageID, 00247 "sort_field" => $contentClassDefinition[ 'fields' ][ 'sort_field' ][ 'default' ], 00248 "sort_order" => $contentClassDefinition[ 'fields' ][ 'sort_order' ][ 'default' ] ); 00249 00250 $row = array_merge( $row, $optionalValues ); 00251 00252 $contentClass = new eZContentClass( $row ); 00253 00254 // setting 'dirtyData' to make sure the 'NameList' will be stored into db. 00255 $contentClass->NameList->setHasDirtyData( true ); 00256 00257 return $contentClass; 00258 } 00259 00260 function instantiateIn( $lang, $userID = false, $sectionID = 0, $versionNumber = false, $versionStatus = eZContentObjectVersion::STATUS_INTERNAL_DRAFT ) 00261 { 00262 return eZContentClass::instantiate( $userID, $sectionID, $versionNumber, $lang, $versionStatus ); 00263 } 00264 00265 /*! 00266 Creates a new content object instance and stores it. 00267 00268 \param user ID (optional), current user if not set 00269 \param section ID (optional), 0 if not set 00270 \param version number, create initial version if not set 00271 \note Transaction unsafe. If you call several transaction unsafe methods you must enclose 00272 the calls within a db transaction; thus within db->begin and db->commit. 00273 */ 00274 function instantiate( $userID = false, $sectionID = 0, $versionNumber = false, $languageCode = false, $versionStatus = eZContentObjectVersion::STATUS_INTERNAL_DRAFT ) 00275 { 00276 $attributes = $this->fetchAttributes(); 00277 00278 $user = eZUser::currentUser(); 00279 if ( $userID === false ) 00280 { 00281 $userID = $user->attribute( 'contentobject_id' ); 00282 } 00283 00284 if ( $languageCode == false ) 00285 { 00286 $languageCode = eZContentObject::defaultLanguage(); 00287 } 00288 00289 $object = eZContentObject::create( ezi18n( "kernel/contentclass", "New %1", null, array( $this->name( $languageCode ) ) ), 00290 $this->attribute( "id" ), 00291 $userID, 00292 $sectionID, 00293 1, 00294 $languageCode ); 00295 00296 if ( $this->attribute( 'always_available' ) ) 00297 { 00298 $object->setAttribute( 'language_mask', (int)$object->attribute( 'language_mask') | 1 ); 00299 } 00300 00301 $db = eZDB::instance(); 00302 $db->begin(); 00303 00304 $object->store(); 00305 $object->setName( ezi18n( "kernel/contentclass", "New %1", null, array( $this->name( $languageCode ) ) ), false, $languageCode ); 00306 00307 if ( !$versionNumber ) 00308 { 00309 $version = $object->createInitialVersion( $userID, $languageCode ); 00310 } 00311 else 00312 { 00313 $version = eZContentObjectVersion::create( $object->attribute( "id" ), $userID, $versionNumber, $languageCode ); 00314 } 00315 if ( $versionStatus !== false ) 00316 { 00317 $version->setAttribute( 'status', $versionStatus ); 00318 } 00319 00320 $version->store(); 00321 00322 foreach ( $attributes as $attribute ) 00323 { 00324 $attribute->instantiate( $object->attribute( 'id' ), $languageCode ); 00325 } 00326 00327 if ( $user->isAnonymous() ) 00328 { 00329 //include_once( 'kernel/classes/ezpreferences.php' ); 00330 $createdObjectIDList = eZPreferences::value( 'ObjectCreationIDList' ); 00331 if ( !$createdObjectIDList ) 00332 { 00333 $createdObjectIDList = array( $object->attribute( 'id' ) ); 00334 } 00335 else 00336 { 00337 $createdObjectIDList = unserialize( $createdObjectIDList ); 00338 $createdObjectIDList[] = $object->attribute( 'id' ); 00339 } 00340 eZPreferences::setValue( 'ObjectCreationIDList', serialize( $createdObjectIDList ) ); 00341 } 00342 00343 $db->commit(); 00344 return $object; 00345 } 00346 00347 function canInstantiateClasses() 00348 { 00349 $ini = eZINI::instance(); 00350 $enableCaching = $ini->variable( 'RoleSettings', 'EnableCaching' ); 00351 00352 if ( $enableCaching == 'true' ) 00353 { 00354 $http = eZHTTPTool::instance(); 00355 00356 eZExpiryHandler::registerShutdownFunction(); 00357 $handler = eZExpiryHandler::instance(); 00358 $expiredTimeStamp = 0; 00359 if ( $handler->hasTimestamp( 'user-class-cache' ) ) 00360 $expiredTimeStamp = $handler->timestamp( 'user-class-cache' ); 00361 00362 $classesCachedForUser = $http->sessionVariable( 'CanInstantiateClassesCachedForUser' ); 00363 $classesCachedTimestamp = $http->sessionVariable( 'ClassesCachedTimestamp' ); 00364 $user = eZUser::currentUser(); 00365 $userID = $user->id(); 00366 00367 if ( ( $classesCachedTimestamp >= $expiredTimeStamp ) && $classesCachedForUser == $userID ) 00368 { 00369 if ( $http->hasSessionVariable( 'CanInstantiateClasses' ) ) 00370 { 00371 return $http->sessionVariable( 'CanInstantiateClasses' ); 00372 } 00373 } 00374 else 00375 { 00376 // store cache 00377 $http->setSessionVariable( 'CanInstantiateClassesCachedForUser', $userID ); 00378 } 00379 } 00380 $user = eZUser::currentUser(); 00381 $accessResult = $user->hasAccessTo( 'content' , 'create' ); 00382 $accessWord = $accessResult['accessWord']; 00383 $canInstantiateClasses = 1; 00384 if ( $accessWord == 'no' ) 00385 { 00386 $canInstantiateClasses = 0; 00387 } 00388 00389 if ( $enableCaching == 'true' ) 00390 { 00391 $http->setSessionVariable( 'CanInstantiateClasses', $canInstantiateClasses ); 00392 } 00393 return $canInstantiateClasses; 00394 } 00395 00396 // code-template::create-block: can-instantiate-class-list, group-filter, role-caching, class-policy-list, name-instantiate, object-creation, class-sql-creation, static-method 00397 // code-template::auto-generated:START can-instantiate-class-list 00398 // This code is automatically generated from templates/classcreatelist.ctpl 00399 // DO NOT EDIT THIS CODE DIRECTLY, CHANGE THE TEMPLATE FILE INSTEAD 00400 00401 /*! 00402 \static 00403 Finds all classes that the current user can create objects from and returns. 00404 It is also possible to filter the list event more with \a $includeFilter and \a $groupList. 00405 00406 \param $asObject If \c true then it return eZContentClass objects, if not it will 00407 be an associative array with \c name and \c id keys. 00408 \param $includeFilter If \c true then it will include only from class groups defined in 00409 \a $groupList, if not it will exclude those groups. 00410 \param $groupList An array with class group IDs that should be used in filtering, use 00411 \c false if you do not wish to filter at all. 00412 \param $id A unique name for the current fetch, this must be supplied when filtering is 00413 used if you want caching to work. 00414 */ 00415 static function canInstantiateClassList( $asObject = false, $includeFilter = true, $groupList = false, $fetchID = false ) 00416 { 00417 $ini = eZINI::instance(); 00418 $groupArray = array(); 00419 00420 $enableCaching = ( $ini->variable( 'RoleSettings', 'EnableCaching' ) == 'true' ); 00421 if ( is_array( $groupList ) ) 00422 { 00423 if ( $fetchID == false ) 00424 $enableCaching = false; 00425 } 00426 00427 if ( $enableCaching ) 00428 { 00429 $http = eZHTTPTool::instance(); 00430 eZExpiryHandler::registerShutdownFunction(); 00431 $handler = eZExpiryHandler::instance(); 00432 $expiredTimeStamp = 0; 00433 if ( $handler->hasTimestamp( 'user-class-cache' ) ) 00434 $expiredTimeStamp = $handler->timestamp( 'user-class-cache' ); 00435 00436 $classesCachedForUser = $http->sessionVariable( 'ClassesCachedForUser' ); 00437 $classesCachedTimestamp = $http->sessionVariable( 'ClassesCachedTimestamp' ); 00438 00439 $cacheVar = 'CanInstantiateClassList'; 00440 if ( is_array( $groupList ) and $fetchID !== false ) 00441 { 00442 $cacheVar = 'CanInstantiateClassListGroup'; 00443 } 00444 00445 $user = eZUser::currentUser(); 00446 $userID = $user->id(); 00447 if ( ( $classesCachedTimestamp >= $expiredTimeStamp ) && $classesCachedForUser == $userID ) 00448 { 00449 if ( $http->hasSessionVariable( $cacheVar ) ) 00450 { 00451 if ( $fetchID !== false ) 00452 { 00453 // Check if the group contains our ID, if not we need to fetch from DB 00454 $groupArray = $http->sessionVariable( $cacheVar ); 00455 if ( isset( $groupArray[$fetchID] ) ) 00456 { 00457 return $groupArray[$fetchID]; 00458 } 00459 } 00460 else 00461 { 00462 return $http->sessionVariable( $cacheVar ); 00463 } 00464 } 00465 } 00466 else 00467 { 00468 $http->setSessionVariable( 'ClassesCachedForUser' , $userID ); 00469 $http->setSessionVariable( 'ClassesCachedTimestamp', time() ); 00470 } 00471 } 00472 00473 $languageCodeList = eZContentLanguage::fetchLocaleList(); 00474 $allowedLanguages = array( '*' => array() ); 00475 00476 $user = eZUser::currentUser(); 00477 $accessResult = $user->hasAccessTo( 'content' , 'create' ); 00478 $accessWord = $accessResult['accessWord']; 00479 00480 $classIDArray = array(); 00481 $classList = array(); 00482 $fetchAll = false; 00483 if ( $accessWord == 'yes' ) 00484 { 00485 $fetchAll = true; 00486 $allowedLanguages['*'] = $languageCodeList; 00487 } 00488 else if ( $accessWord == 'no' ) 00489 { 00490 // Cannnot create any objects, return empty list. 00491 return $classList; 00492 } 00493 else 00494 { 00495 $policies = $accessResult['policies']; 00496 foreach ( $policies as $policyKey => $policy ) 00497 { 00498 $classIDArrayPart = '*'; 00499 if ( isset( $policy['Class'] ) ) 00500 { 00501 $classIDArrayPart = $policy['Class']; 00502 } 00503 $languageCodeArrayPart = $languageCodeList; 00504 if ( isset( $policy['Language'] ) ) 00505 { 00506 $languageCodeArrayPart = array_intersect( $policy['Language'], $languageCodeList ); 00507 } 00508 00509 if ( $classIDArrayPart == '*' ) 00510 { 00511 $fetchAll = true; 00512 $allowedLanguages['*'] = array_unique( array_merge( $allowedLanguages['*'], $languageCodeArrayPart ) ); 00513 } 00514 else 00515 { 00516 foreach( $classIDArrayPart as $class ) 00517 { 00518 if ( isset( $allowedLanguages[$class] ) ) 00519 { 00520 $allowedLanguages[$class] = array_unique( array_merge( $allowedLanguages[$class], $languageCodeArrayPart ) ); 00521 } 00522 else 00523 { 00524 $allowedLanguages[$class] = $languageCodeArrayPart; 00525 } 00526 } 00527 $classIDArray = array_merge( $classIDArray, array_diff( $classIDArrayPart, $classIDArray ) ); 00528 } 00529 } 00530 } 00531 00532 $db = eZDB::instance(); 00533 00534 $filterTableSQL = ''; 00535 $filterSQL = ''; 00536 // Create extra SQL statements for the class group filters. 00537 if ( is_array( $groupList ) ) 00538 { 00539 if ( count( $groupList ) == 0 ) 00540 { 00541 return $classList; 00542 } 00543 00544 $filterTableSQL = ', ezcontentclass_classgroup ccg'; 00545 $filterSQL = ( " AND\n" . 00546 " cc.id = ccg.contentclass_id AND\n" . 00547 " " ); 00548 $filterSQL .= $db->generateSQLINStatement( $groupList, 'ccg.group_id', !$includeFilter, true, 'int' ); 00549 } 00550 00551 $classNameFilter = eZContentClassName::sqlFilter( 'cc' ); 00552 $filterSQL .= " AND\n cc.id=" . $classNameFilter['from'] . ".contentclass_id"; 00553 00554 if ( $fetchAll ) 00555 { 00556 // If $asObject is true we fetch all fields in class 00557 $fields = $asObject ? "cc.*, $classNameFilter[nameField]" : "cc.id, $classNameFilter[nameField]"; 00558 $rows = $db->arrayQuery( "SELECT DISTINCT $fields\n" . 00559 "FROM ezcontentclass cc$filterTableSQL, $classNameFilter[from]\n" . 00560 "WHERE cc.version = " . eZContentClass::VERSION_STATUS_DEFINED . " $filterSQL\n" . 00561 "ORDER BY $classNameFilter[nameField] ASC" ); 00562 $classList = eZPersistentObject::handleRows( $rows, 'eZContentClass', $asObject ); 00563 } 00564 else 00565 { 00566 // If the constrained class list is empty we are not allowed to create any class 00567 if ( count( $classIDArray ) == 0 ) 00568 { 00569 return $classList; 00570 } 00571 00572 $classIDCondition = $db->generateSQLInStatement( $classIDArray, 'cc.id' ); 00573 // If $asObject is true we fetch all fields in class 00574 $fields = $asObject ? "cc.*, $classNameFilter[nameField]" : "cc.id, $classNameFilter[nameField]"; 00575 $rows = $db->arrayQuery( "SELECT DISTINCT $fields\n" . 00576 "FROM ezcontentclass cc$filterTableSQL, $classNameFilter[from]\n" . 00577 "WHERE $classIDCondition AND\n" . 00578 " cc.version = " . eZContentClass::VERSION_STATUS_DEFINED . " $filterSQL\n" . 00579 "ORDER BY $classNameFilter[nameField] ASC" ); 00580 $classList = eZPersistentObject::handleRows( $rows, 'eZContentClass', $asObject ); 00581 } 00582 00583 if ( $asObject ) 00584 { 00585 foreach ( $classList as $key => $class ) 00586 { 00587 $id = $class->attribute( 'id' ); 00588 if ( isset( $allowedLanguages[$id] ) ) 00589 { 00590 $languageCodes = array_unique( array_merge( $allowedLanguages['*'], $allowedLanguages[$id] ) ); 00591 } 00592 else 00593 { 00594 $languageCodes = $allowedLanguages['*']; 00595 } 00596 $classList[$key]->setCanInstantiateLanguages( $languageCodes ); 00597 } 00598 } 00599 00600 eZDebugSetting::writeDebug( 'kernel-content-class', $classList, "class list fetched from db" ); 00601 if ( $enableCaching ) 00602 { 00603 if ( $fetchID !== false ) 00604 { 00605 $groupArray[$fetchID] = $classList; 00606 $http->setSessionVariable( $cacheVar, $groupArray ); 00607 } 00608 else 00609 { 00610 $http->setSessionVariable( $cacheVar, $classList ); 00611 } 00612 } 00613 00614 return $classList; 00615 } 00616 00617 // This code is automatically generated from templates/classcreatelist.ctpl 00618 // code-template::auto-generated:END can-instantiate-class-list 00619 00620 /*! 00621 \return The creator of the class as an eZUser object by using the $CreatorID as user ID. 00622 \note The reference for the return value is required to workaround 00623 a bug with PHP references. 00624 */ 00625 function creator() 00626 { 00627 if ( isset( $this->CreatorID ) and $this->CreatorID ) 00628 { 00629 //include_once( "kernel/classes/datatypes/ezuser/ezuser.php" ); 00630 return eZUser::fetch( $this->CreatorID ); 00631 } 00632 return null; 00633 } 00634 00635 /*! 00636 \return The modifier of the class as an eZUser object by using the $ModifierID as user ID. 00637 \note The reference for the return value is required to workaround 00638 a bug with PHP references. 00639 */ 00640 function modifier() 00641 { 00642 if ( isset( $this->ModifierID ) and $this->ModifierID ) 00643 { 00644 //include_once( "kernel/classes/datatypes/ezuser/ezuser.php" ); 00645 return eZUser::fetch( $this->ModifierID ); 00646 } 00647 return null; 00648 } 00649 00650 /*! 00651 Find all groups the current class is placed in and returns a list of group objects. 00652 \return An array with eZContentClassGroup objects. 00653 \sa fetchGroupIDList() 00654 \note The reference for the return value is required to workaround 00655 a bug with PHP references. 00656 */ 00657 function fetchGroupList() 00658 { 00659 $this->InGroups = eZContentClassClassGroup::fetchGroupList( $this->attribute( "id" ), 00660 $this->attribute( "version" ), 00661 true ); 00662 return $this->InGroups; 00663 } 00664 00665 /*! 00666 Find all groups the current class is placed in and returns a list of group IDs. 00667 \return An array with integers (ids). 00668 \sa fetchGroupList() 00669 \note The reference for the return value is required to workaround 00670 a bug with PHP references. 00671 */ 00672 function fetchGroupIDList() 00673 { 00674 $list = eZContentClassClassGroup::fetchGroupList( $this->attribute( "id" ), 00675 $this->attribute( "version" ), 00676 false ); 00677 $this->InGroupIDs = array(); 00678 foreach ( $list as $item ) 00679 { 00680 $this->InGroupIDs[] = $item['group_id']; 00681 } 00682 return $this->InGroupIDs; 00683 } 00684 00685 /*! 00686 Returns the result from fetchGroupIDList() if class group overrides is 00687 enabled in content.ini. 00688 \return An array with eZContentClassGroup objects or \c false if disabled. 00689 \note \c EnableClassGroupOverride in group \c ContentOverrideSettings from INI file content.ini 00690 controls this behaviour. 00691 \note The reference for the return value is required to workaround 00692 a bug with PHP references. 00693 */ 00694 function fetchMatchGroupIDList() 00695 { 00696 //include_once( 'lib/ezutils/classes/ezini.php' ); 00697 $contentINI = eZINI::instance( 'content.ini' ); 00698 if( $contentINI->variable( 'ContentOverrideSettings', 'EnableClassGroupOverride' ) == 'true' ) 00699 { 00700 return $this->attribute( 'ingroup_id_list' ); 00701 } 00702 00703 return false; 00704 } 00705 00706 /*! 00707 Finds all Classes in the system and returns them. 00708 \return An array with eZContentClass objects. 00709 \note The reference for the return value is required to workaround 00710 a bug with PHP references. 00711 */ 00712 static function fetchAllClasses( $asObject = true, $includeFilter = true, $groupList = false ) 00713 { 00714 $filterTableSQL = ''; 00715 $filterSQL = ''; 00716 if ( is_array( $groupList ) ) 00717 { 00718 $filterTableSQL = ', ezcontentclass_classgroup ccg'; 00719 $filterSQL = ( " AND\n" . 00720 " cc.id = ccg.contentclass_id AND\n" . 00721 " ccg.group_id " ); 00722 $groupText = implode( ', ', $groupList ); 00723 if ( $includeFilter ) 00724 $filterSQL .= "IN ( $groupText )"; 00725 else 00726 $filterSQL .= "NOT IN ( $groupText )"; 00727 } 00728 00729 $classNameFilter = eZContentClassName::sqlFilter( 'cc' ); 00730 00731 $classList = array(); 00732 $db = eZDb::instance(); 00733 // If $asObject is true we fetch all fields in class 00734 $fields = $asObject ? "cc.*" : "cc.id, $classNameFilter[nameField]"; 00735 $rows = $db->arrayQuery( "SELECT DISTINCT $fields\n" . 00736 "FROM ezcontentclass cc$filterTableSQL, $classNameFilter[from]\n" . 00737 "WHERE cc.version = " . eZContentClass::VERSION_STATUS_DEFINED . "$filterSQL AND $classNameFilter[where]\n" . 00738 "ORDER BY $classNameFilter[nameField] ASC" ); 00739 00740 $classList = eZPersistentObject::handleRows( $rows, 'eZContentClass', $asObject ); 00741 return $classList; 00742 } 00743 00744 /*! 00745 Finds all Class groups in the system and returns them. 00746 \return An array with eZContentClassGroup objects. 00747 \sa fetchGroupList(), fetchGroupIDList() 00748 \note The reference for the return value is required to workaround 00749 a bug with PHP references. 00750 */ 00751 function fetchAllGroups() 00752 { 00753 $this->AllGroups = eZContentClassGroup::fetchList(); 00754 return $this->AllGroups; 00755 } 00756 00757 /*! 00758 \return true if the class is part of the group \a $groupID 00759 */ 00760 function inGroup( $groupID ) 00761 { 00762 return eZContentClassClassGroup::classInGroup( $this->attribute( 'id' ), 00763 $this->attribute( 'version' ), 00764 $groupID ); 00765 } 00766 00767 /*! 00768 \static 00769 Will remove all temporary classes from the database. 00770 */ 00771 static function removeTemporary() 00772 { 00773 $version = eZContentClass::VERSION_STATUS_TEMPORARY; 00774 $temporaryClasses = eZContentClass::fetchList( $version, true ); 00775 $db = eZDB::instance(); 00776 $db->begin(); 00777 foreach ( $temporaryClasses as $class ) 00778 { 00779 $class->remove( true, $version ); 00780 } 00781 eZPersistentObject::removeObject( eZContentClassAttribute::definition(), 00782 array( 'version' => $version ) ); 00783 00784 $db->commit(); 00785 } 00786 00787 /*! 00788 Get remote id of content node 00789 */ 00790 function remoteID() 00791 { 00792 $remoteID = eZPersistentObject::attribute( 'remote_id', true ); 00793 if ( !$remoteID && 00794 $this->Version == eZContentClass::VERSION_STATUS_DEFINED ) 00795 { 00796 $this->setAttribute( 'remote_id', md5( (string)mt_rand() . (string)time() ) ); 00797 $this->sync( array( 'remote_id' ) ); 00798 $remoteID = eZPersistentObject::attribute( 'remote_id', true ); 00799 } 00800 00801 return $remoteID; 00802 } 00803 00804 /*! 00805 \note If you want to remove a class with all data associated with it (objects/classMembers) 00806 you should use eZContentClassOperations::remove() 00807 */ 00808 function remove( $removeAttributes = false, $version = eZContentClass::VERSION_STATUS_DEFINED ) 00809 { 00810 // If we are not allowed to remove just return false 00811 if ( $this->Version != eZContentClass::VERSION_STATUS_TEMPORARY && !$this->isRemovable() ) 00812 return false; 00813 00814 if ( is_array( $removeAttributes ) or $removeAttributes ) 00815 $this->removeAttributes( $removeAttributes ); 00816 00817 $this->NameList->remove( $this ); 00818 eZPersistentObject::remove(); 00819 } 00820 00821 /*! 00822 Checks if the class can be removed and returns \c true if it can, \c false otherwise. 00823 \sa removableInformation() 00824 */ 00825 function isRemovable() 00826 { 00827 $info = $this->removableInformation( false ); 00828 return count( $info['list'] ) == 0; 00829 } 00830 00831 /*! 00832 Returns information on why the class cannot be removed, 00833 it does the same checks as in isRemovable() but generates 00834 some text in the return array. 00835 \return An array which contains: 00836 - text - Plain text description why this cannot be removed 00837 - list - An array with reasons why this failed, each entry contains: 00838 - text - Plain text description of the reason. 00839 - list - A sublist of reason (e.g from an attribute), is optional. 00840 \param $includeAll Controls whether the returned information will contain all 00841 sources for not being to remove or just the first that it finds. 00842 */ 00843 function removableInformation( $includeAll = true ) 00844 { 00845 $result = array( 'text' => ezi18n( 'kernel/contentclass', "Cannot remove class '%class_name':", 00846 null, array( '%class_name' => $this->attribute( 'name' ) ) ), 00847 'list' => array() ); 00848 $db = eZDB::instance(); 00849 00850 // Check top-level nodes 00851 $rows = $db->arrayQuery( "SELECT ezcot.node_id 00852 FROM ezcontentobject_tree ezcot, ezcontentobject ezco 00853 WHERE ezcot.depth = 1 AND 00854 ezco.contentclass_id = $this->ID AND 00855 ezco.id=ezcot.contentobject_id" ); 00856 if ( count( $rows ) > 0 ) 00857 { 00858 $result['list'][] = array( 'text' => ezi18n( 'kernel/contentclass', 'The class is used by a top-level node and cannot be removed. 00859 You will need to change the class of the node by using the swap functionality.' ) ); 00860 if ( !$includeAll ) 00861 return $result; 00862 } 00863 00864 // Check class attributes 00865 foreach ( $this->fetchAttributes() as $attribute ) 00866 { 00867 $dataType = $attribute->dataType(); 00868 if ( !$dataType->isClassAttributeRemovable( $attribute ) ) 00869 { 00870 $info = $dataType->classAttributeRemovableInformation( $attribute, $includeAll ); 00871 $result['list'][] = $info; 00872 if ( !$includeAll ) 00873 return $result; 00874 } 00875 } 00876 00877 return $result; 00878 } 00879 00880 /*! 00881 \note Removes class attributes 00882 00883 \param Array of attributes to remove 00884 \param Version to remove( optional ) 00885 */ 00886 function removeAttributes( $removeAttributes = false, $version = false ) 00887 { 00888 if ( is_array( $removeAttributes ) ) 00889 { 00890 $db = eZDB::instance(); 00891 $db->begin(); 00892 foreach( $removeAttributes as $attribute ) 00893 { 00894 $attribute->removeThis(); 00895 } 00896 $db->commit(); 00897 } 00898 else 00899 { 00900 $contentClassID = $this->ID; 00901 00902 if ( $version === false ) 00903 { 00904 $version = $this->Version; 00905 } 00906 $classAttributes = $this->fetchAttributes( ); 00907 00908 $db = eZDB::instance(); 00909 $db->begin(); 00910 foreach ( $classAttributes as $classAttribute ) 00911 { 00912 $dataType = $classAttribute->dataType(); 00913 $dataType->deleteStoredClassAttribute( $classAttribute, $version ); 00914 } 00915 eZPersistentObject::removeObject( eZContentClassAttribute::definition(), 00916 array( 'contentclass_id' => $contentClassID, 00917 'version' => $version ) ); 00918 $db->commit(); 00919 } 00920 } 00921 00922 function compareAttributes( $attr1, $attr2 ) 00923 { 00924 return ( $attr1->attribute( "placement" ) > $attr2->attribute( "placement" ) ) ? 1 : -1; 00925 } 00926 00927 function adjustAttributePlacements( $attributes ) 00928 { 00929 if ( !is_array( $attributes ) ) 00930 return; 00931 usort( $attributes, array( $this, "compareAttributes" ) ); 00932 $i = 0; 00933 foreach( $attributes as $attribute ) 00934 { 00935 $attribute->setAttribute( "placement", ++$i ); 00936 } 00937 } 00938 00939 /*! 00940 \reimp 00941 */ 00942 function store( $store_childs = false, $fieldFilters = null ) 00943 { 00944 00945 global $eZContentClassObjectCache; 00946 00947 if ( isset( $eZContentClassObjectCache[$this->ID] ) ) 00948 { 00949 unset( $eZContentClassObjectCache[$this->ID] ); 00950 } 00951 00952 $db = eZDB::instance(); 00953 $db->begin(); 00954 00955 if ( is_array( $store_childs ) || 00956 $store_childs ) 00957 { 00958 if ( is_array( $store_childs ) ) 00959 { 00960 $attributes = $store_childs; 00961 } 00962 else 00963 { 00964 $attributes = $this->fetchAttributes(); 00965 } 00966 00967 foreach( $attributes as $attribute ) 00968 { 00969 if ( is_object ( $attribute ) ) 00970 $attribute->store(); 00971 } 00972 } 00973 00974 eZExpiryHandler::registerShutdownFunction(); 00975 $handler = eZExpiryHandler::instance(); 00976 $handler->setTimestamp( 'user-class-cache', time() ); 00977 $handler->store(); 00978 00979 $this->setAttribute( 'serialized_name_list', $this->NameList->serializeNames() ); 00980 00981 eZPersistentObject::store( $fieldFilters ); 00982 00983 $this->NameList->store( $this ); 00984 00985 $db->commit(); 00986 } 00987 00988 /*! 00989 \reimp 00990 */ 00991 function sync( $fieldFilters = null ) 00992 { 00993 if ( $this->hasDirtyData() ) 00994 $this->store( false, $fieldFilters ); 00995 } 00996 00997 /*! 00998 Initializes this class as a copy of \a $originalClass by 00999 creating new a new name and identifier. 01000 It will check if there are other classes already with this name 01001 in which case it will append a unique number to the name and identifier. 01002 */ 01003 function initializeCopy( &$originalClass ) 01004 { 01005 $name = ezi18n( 'kernel/class', 'Copy of %class_name', null, 01006 array( '%class_name' => $originalClass->attribute( 'name' ) ) ); 01007 $identifier = 'copy_of_' . $originalClass->attribute( 'identifier' ); 01008 $db = eZDB::instance(); 01009 $sql = "SELECT count( ezcontentclass_name.name ) AS count FROM ezcontentclass, ezcontentclass_name WHERE ezcontentclass.id = ezcontentclass_name.contentclass_id AND ezcontentclass_name.name like '" . $db->escapeString( $name ) . "%'"; 01010 $rows = $db->arrayQuery( $sql ); 01011 $count = $rows[0]['count']; 01012 if ( $count > 0 ) 01013 { 01014 ++$count; 01015 $name .= $count; 01016 $identifier .= $count; 01017 } 01018 $this->setName( $name ); 01019 $this->setAttribute( 'identifier', $identifier ); 01020 $this->setAttribute( 'created', time() ); 01021 //include_once( "kernel/classes/datatypes/ezuser/ezuser.php" ); 01022 $user = eZUser::currentUser(); 01023 $userID = $user->attribute( "contentobject_id" ); 01024 $this->setAttribute( 'creator_id', $userID ); 01025 } 01026 01027 /*! 01028 Stores the current class as a defined version, updates the contentobject_name 01029 attribute and recreates the class group entries. 01030 \note It will remove any existing temporary or defined classes before storing. 01031 */ 01032 function storeDefined( $attributes ) 01033 { 01034 $db = eZDB::instance(); 01035 $db->begin(); 01036 01037 $this->removeAttributes( false, eZContentClass::VERSION_STATUS_DEFINED ); 01038 $this->removeAttributes( false, eZContentClass::VERSION_STATUS_TEMPORARY ); 01039 $this->remove( false ); 01040 $this->setVersion( eZContentClass::VERSION_STATUS_DEFINED, $attributes ); 01041 // include_once( "kernel/classes/datatypes/ezuser/ezuser.php" ); 01042 $user = eZUser::currentUser(); 01043 $user_id = $user->attribute( "contentobject_id" ); 01044 $this->setAttribute( "modifier_id", $user_id ); 01045 $this->setAttribute( "modified", time() ); 01046 $this->adjustAttributePlacements( $attributes ); 01047 foreach( $attributes as $attribute ) 01048 { 01049 $attribute->storeDefined(); 01050 } 01051 01052 // Set contentobject_name to something sensible if it is missing 01053 if ( count( $attributes ) > 0 ) 01054 { 01055 $identifier = $attributes[0]->attribute( 'identifier' ); 01056 $identifier = '<' . $identifier . '>'; 01057 if ( trim( $this->attribute( 'contentobject_name' ) ) == '' ) 01058 { 01059 $this->setAttribute( 'contentobject_name', $identifier ); 01060 } 01061 } 01062 01063 // Recreate class member entries 01064 eZContentClassClassGroup::removeClassMembers( $this->ID, eZContentClass::VERSION_STATUS_DEFINED ); 01065 $classgroups = eZContentClassClassGroup::fetchGroupList( $this->ID, eZContentClass::VERSION_STATUS_TEMPORARY ); 01066 foreach( $classgroups as $classgroup ) 01067 { 01068 $classgroup->setAttribute( 'contentclass_version', eZContentClass::VERSION_STATUS_DEFINED ); 01069 $classgroup->store(); 01070 } 01071 eZContentClassClassGroup::removeClassMembers( $this->ID, eZContentClass::VERSION_STATUS_TEMPORARY ); 01072 01073 eZExpiryHandler::registerShutdownFunction(); 01074 $handler = eZExpiryHandler::instance(); 01075 $time = time(); 01076 $handler->setTimestamp( 'user-class-cache', $time ); 01077 $handler->setTimestamp( 'class-identifier-cache', $time ); 01078 $handler->setTimestamp( 'sort-key-cache', $time ); 01079 $handler->store(); 01080 01081 //include_once( 'kernel/classes/ezcontentcachemanager.php' ); 01082 eZContentCacheManager::clearAllContentCache(); 01083 01084 $this->setAttribute( 'serialized_name_list', $this->NameList->serializeNames() ); 01085 eZPersistentObject::store(); 01086 $this->NameList->store( $this ); 01087 01088 $db->commit(); 01089 } 01090 01091 function setVersion( $version, $set_childs = false ) 01092 { 01093 if ( is_array( $set_childs ) or $set_childs ) 01094 { 01095 if ( is_array( $set_childs ) ) 01096 { 01097 $attributes = $set_childs; 01098 } 01099 else 01100 { 01101 $attributes = $this->fetchAttributes(); 01102 } 01103 foreach( $attributes as $attribute ) 01104 { 01105 $attribute->setAttribute( "version", $version ); 01106 } 01107 } 01108 01109 if ( $this->Version != $version ) 01110 $this->NameList->setHasDirtyData(); 01111 01112 $this->setAttribute( "version", $version ); 01113 } 01114 01115 static function exists( $id, $version = eZContentClass::VERSION_STATUS_DEFINED, $userID = false, $useIdentifier = false ) 01116 { 01117 $conds = array( "version" => $version ); 01118 if ( $useIdentifier ) 01119 $conds["identifier"] = $id; 01120 else 01121 $conds["id"] = $id; 01122 if ( $userID !== false and is_numeric( $userID ) ) 01123 $conds["creator_id"] = $userID; 01124 $version_sort = "desc"; 01125 if ( $version == eZContentClass::VERSION_STATUS_DEFINED ) 01126 $conds['version'] = $version; 01127 $rows = eZPersistentObject::fetchObjectList( eZContentClass::definition(), 01128 null, 01129 $conds, 01130 null, 01131 array( "offset" => 0, 01132 "length" => 1 ), 01133 false ); 01134 if ( count( $rows ) > 0 ) 01135 return $rows[0]['id']; 01136 return false; 01137 } 01138 01139 static function fetch( $id, $asObject = true, $version = eZContentClass::VERSION_STATUS_DEFINED, $user_id = false ,$parent_id = null ) 01140 { 01141 global $eZContentClassObjectCache; 01142 01143 // If the object given by its id is not cached or should be returned as array 01144 // then we fetch it from the DB (objects are always cached as arrays). 01145 if ( !isset( $eZContentClassObjectCache[$id] ) or $asObject === false or $version != eZContentClass::VERSION_STATUS_DEFINED ) 01146 { 01147 $conds = array( "id" => $id, 01148 "version" => $version ); 01149 01150 if ( $user_id !== false and is_numeric( $user_id ) ) 01151 $conds["creator_id"] = $user_id; 01152 01153 $version_sort = "desc"; 01154 if ( $version == eZContentClass::VERSION_STATUS_DEFINED ) 01155 $version_sort = "asc"; 01156 $rows = eZPersistentObject::fetchObjectList( eZContentClass::definition(), 01157 null, 01158 $conds, 01159 array( "version" => $version_sort ), 01160 array( "offset" => 0, 01161 "length" => 2 ), 01162 false ); 01163 01164 if ( count( $rows ) == 0 ) 01165 { 01166 $contentClass = null; 01167 return $contentClass; 01168 } 01169 01170 $row = $rows[0]; 01171 $row["version_count"] = count( $rows ); 01172 01173 if ( $asObject ) 01174 { 01175 $contentClass = new eZContentClass( $row ); 01176 if ( $version == eZContentClass::VERSION_STATUS_DEFINED ) 01177 { 01178 $eZContentClassObjectCache[$id] = $contentClass; 01179 } 01180 return $contentClass; 01181 } 01182 else 01183 $contentClass = $row; 01184 } 01185 else 01186 { 01187 $contentClass = $eZContentClassObjectCache[$id]; 01188 } 01189 01190 return $contentClass; 01191 } 01192 01193 static function fetchByRemoteID( $remoteID, $asObject = true, $version = eZContentClass::VERSION_STATUS_DEFINED, $user_id = false ,$parent_id = null ) 01194 { 01195 $conds = array( "remote_id" => $remoteID, 01196 "version" => $version ); 01197 if ( $user_id !== false and is_numeric( $user_id ) ) 01198 $conds["creator_id"] = $user_id; 01199 $version_sort = "desc"; 01200 if ( $version == eZContentClass::VERSION_STATUS_DEFINED ) 01201 $version_sort = "asc"; 01202 $rows = eZPersistentObject::fetchObjectList( eZContentClass::definition(), 01203 null, 01204 $conds, 01205 array( "version" => $version_sort ), 01206 array( "offset" => 0, 01207 "length" => 2 ), 01208 false ); 01209 if ( count( $rows ) == 0 ) 01210 { 01211 $contentClass = null; 01212 return $contentClass; 01213 } 01214 01215 $row = $rows[0]; 01216 $row["version_count"] = count( $rows ); 01217 01218 if ( $asObject ) 01219 { 01220 return new eZContentClass( $row ); 01221 } 01222 01223 return $row; 01224 } 01225 01226 static function fetchByIdentifier( $identifier, $asObject = true, $version = eZContentClass::VERSION_STATUS_DEFINED, $user_id = false ,$parent_id = null ) 01227 { 01228 $conds = array( "identifier" => $identifier, 01229 "version" => $version ); 01230 if ( $user_id !== false and is_numeric( $user_id ) ) 01231 $conds["creator_id"] = $user_id; 01232 $version_sort = "desc"; 01233 if ( $version == eZContentClass::VERSION_STATUS_DEFINED ) 01234 $version_sort = "asc"; 01235 $rows = eZPersistentObject::fetchObjectList( eZContentClass::definition(), 01236 null, 01237 $conds, 01238 array( "version" => $version_sort ), 01239 array( "offset" => 0, 01240 "length" => 2 ), 01241 false ); 01242 if ( count( $rows ) == 0 ) 01243 { 01244 $contentClass = null; 01245 return $contentClass; 01246 } 01247 01248 $row = $rows[0]; 01249 $row["version_count"] = count( $rows ); 01250 01251 if ( $asObject ) 01252 { 01253 return new eZContentClass( $row ); 01254 } 01255 return $row; 01256 } 01257 01258 /*! 01259 \static 01260 */ 01261 static function fetchList( $version = eZContentClass::VERSION_STATUS_DEFINED, $asObject = true, $user_id = false, 01262 $sorts = null, $fields = null, $classFilter = false, $limit = null ) 01263 { 01264 $conds = array(); 01265 $custom_fields = null; 01266 $custom_tables = null; 01267 $custom_conds = null; 01268 01269 if ( is_numeric( $version ) ) 01270 $conds["version"] = $version; 01271 if ( $user_id !== false and is_numeric( $user_id ) ) 01272 $conds["creator_id"] = $user_id; 01273 if ( $classFilter ) 01274 { 01275 $classIDCount = 0; 01276 $classIdentifierCount = 0; 01277 01278 $classIDFilter = array(); 01279 $classIdentifierFilter = array(); 01280 foreach ( $classFilter as $classType ) 01281 { 01282 if ( is_numeric( $classType ) ) 01283 { 01284 $classIDFilter[] = $classType; 01285 $classIDCount++; 01286 } 01287 else 01288 { 01289 $classIdentifierFilter[] = $classType; 01290 $classIdentifierCount++; 01291 } 01292 } 01293 01294 if ( $classIDCount > 1 ) 01295 $conds['id'] = array( $classIDFilter ); 01296 else if ( $classIDCount == 1 ) 01297 $conds['id'] = $classIDFilter[0]; 01298 if ( $classIdentifierCount > 1 ) 01299 $conds['identifier'] = array( $classIdentifierFilter ); 01300 else if ( $classIdentifierCount == 1 ) 01301 $conds['identifier'] = $classIdentifierFilter[0]; 01302 } 01303 01304 if ( $sorts && isset( $sorts['name'] ) ) 01305 { 01306 $nameFiler = eZContentClassName::sqlFilter( 'ezcontentclass' ); 01307 $custom_tables = array( $nameFiler['from'] ); 01308 $custom_conds = "AND " . $nameFiler['where']; 01309 $custom_fields = array( $nameFiler['nameField'] ); 01310 01311 $sorts[$nameFiler['orderBy']] = $sorts['name']; 01312 unset( $sorts['name'] ); 01313 } 01314 01315 return eZPersistentObject::fetchObjectList( eZContentClass::definition(), 01316 $fields, 01317 $conds, 01318 $sorts, 01319 $limit, 01320 $asObject, 01321 false, 01322 $custom_fields, 01323 $custom_tables, 01324 $custom_conds ); 01325 } 01326 01327 /*! 01328 Returns all attributes as an associative array with the key taken from the attribute identifier. 01329 */ 01330 function dataMap() 01331 { 01332 if ( !isset( $this->DataMap[$this->Version] ) ) 01333 { 01334 $attributes = $this->fetchAttributes( false, true, $this->Version ); 01335 foreach ( $attributes as $attribute ) 01336 { 01337 $this->DataMap[$this->Version][$attribute->attribute( 'identifier' )] = $attribute; 01338 } 01339 } 01340 return $this->DataMap[$this->Version]; 01341 } 01342 01343 function fetchAttributes( $id = false, $asObject = true, $version = eZContentClass::VERSION_STATUS_DEFINED ) 01344 { 01345 if ( $id === false ) 01346 { 01347 $id = $this->ID; 01348 $version = $this->Version; 01349 } 01350 01351 return eZContentClassAttribute::fetchFilteredList( array( "contentclass_id" => $id, 01352 "version" => $version ), 01353 $asObject ); 01354 } 01355 01356 /*! 01357 Fetch class attribute by identifier, return null if none exist. 01358 01359 \param attribute identifier. 01360 01361 \return Class Attribute, null if none matched 01362 */ 01363 function fetchAttributeByIdentifier( $identifier, $asObject = true ) 01364 { 01365 $attributeArray = eZContentClassAttribute::fetchFilteredList( array( 'contentclass_id' => $this->ID, 01366 'version' => $this->Version, 01367 'identifier' => $identifier ), $asObject ); 01368 if ( count( $attributeArray ) > 0 ) 01369 { 01370 return $attributeArray[0]; 01371 } 01372 return null; 01373 } 01374 01375 function fetchSearchableAttributes( $id = false, $asObject = true, $version = eZContentClass::VERSION_STATUS_DEFINED ) 01376 { 01377 if ( $id === false ) 01378 { 01379 $id = $this->ID; 01380 $version = $this->Version; 01381 } 01382 01383 return eZContentClassAttribute::fetchFilteredList( array( "contentclass_id" => $id, 01384 "is_searchable" => 1, 01385 "version" => $version ), $asObject ); 01386 } 01387 01388 /*! 01389 \note The reference for the return value is required to workaround 01390 a bug with PHP references. 01391 */ 01392 function versionStatus() 01393 { 01394 01395 if ( $this->VersionCount == 1 ) 01396 { 01397 if ( $this->Version == eZContentClass::VERSION_STATUS_TEMPORARY ) 01398 { 01399 return eZContentClass::VERSION_STATUS_TEMPORARY; 01400 } 01401 return eZContentClass::VERSION_STATUS_DEFINED; 01402 } 01403 return eZContentClass::VERSION_STATUS_MODIFIED; 01404 } 01405 01406 /*! 01407 \deprecated 01408 \return The version count for the class if has been determined. 01409 \note The reference for the return value is required to workaround 01410 a bug with PHP references. 01411 */ 01412 function versionCount() 01413 { 01414 return $this->VersionCount; 01415 } 01416 01417 /*! 01418 Will generate a name for the content object based on the class 01419 settings for content object. 01420 */ 01421 function contentObjectName( $contentObject, $version = false, $translation = false ) 01422 { 01423 $contentObjectNamePattern = $this->ContentObjectName; 01424 01425 $nameResolver = new eZNamePatternResolver( $contentObjectNamePattern, $contentObject, $version, $translation ); 01426 $contentObjectName = $nameResolver->resolveNamePattern(); 01427 01428 return $contentObjectName; 01429 } 01430 01431 /* 01432 Will generate a name for the url alias based on the class 01433 settings for content object. 01434 */ 01435 function urlAliasName( $contentObject, $version = false, $translation = false ) 01436 { 01437 if ( $this->URLAliasName ) 01438 { 01439 $urlAliasNamePattern = $this->URLAliasName; 01440 } 01441 else 01442 { 01443 $urlAliasNamePattern = $this->ContentObjectName; 01444 } 01445 01446 $nameResolver = new eZNamePatternResolver( $urlAliasNamePattern, $contentObject, $version, $translation ); 01447 $urlAliasName = $nameResolver->resolveNamePattern(); 01448 01449 return $urlAliasName; 01450 } 01451 01452 /*! 01453 Generates a name for the content object based on the content object name pattern 01454 and data map of an object. 01455 */ 01456 function buildContentObjectName( $contentObjectName, $dataMap, $tmpTags = false ) 01457 { 01458 preg_match_all( "|<[^>]+>|U", 01459 $contentObjectName, 01460 $tagMatchArray ); 01461 01462 foreach ( $tagMatchArray[0] as $tag ) 01463 { 01464 $tagName = str_replace( "<", "", $tag ); 01465 $tagName = str_replace( ">", "", $tagName ); 01466 01467 $tagParts = explode( '|', $tagName ); 01468 01469 $namePart = ""; 01470 foreach ( $tagParts as $name ) 01471 { 01472 // get the value of the attribute to use in name 01473 if ( isset( $dataMap[$name] ) ) 01474 { 01475 $namePart = $dataMap[$name]->title(); 01476 if ( $namePart != "" ) 01477 break; 01478 } 01479 elseif ( $tmpTags && isset( $tmpTags[$name] ) && $tmpTags[$name] != '' ) 01480 { 01481 $namePart = $tmpTags[$name]; 01482 break; 01483 } 01484 01485 } 01486 01487 // replace tag with object name part 01488 $contentObjectName = str_replace( $tag, $namePart, $contentObjectName ); 01489 } 01490 return $contentObjectName; 01491 } 01492 01493 /*! 01494 \return will return the number of objects published by this class. 01495 */ 01496 function objectCount() 01497 { 01498 $db = eZDB::instance(); 01499 01500 $countRow = $db->arrayQuery( 'SELECT count(*) AS count FROM ezcontentobject '. 01501 'WHERE contentclass_id='.$this->ID ." and status = " . eZContentObject::STATUS_PUBLISHED ); 01502 01503 return $countRow[0]['count']; 01504 } 01505 01506 /*! 01507 \return will return the list of objects published by this class. 01508 */ 01509 function objectList() 01510 { 01511 return eZContentObject::fetchSameClassList( $this->ID ); 01512 } 01513 01514 /*! 01515 \return Sets the languages which are allowed to be instantiated for the class. 01516 Used only for the content/ fetch function. 01517 */ 01518 function setCanInstantiateLanguages( $languageCodes ) 01519 { 01520 $this->CanInstantiateLanguages = $languageCodes; 01521 } 01522 01523 function canInstantiateLanguages() 01524 { 01525 if ( is_array( $this->CanInstantiateLanguages ) ) 01526 { 01527 return array_intersect( eZContentLanguage::prioritizedLanguageCodes(), $this->CanInstantiateLanguages ); 01528 } 01529 return array(); 01530 } 01531 01532 /*! 01533 \static 01534 Returns a contentclass name from serialized array \a $serializedNameList using 01535 top language from siteaccess language list or 'always available' name 01536 from \a $serializedNameList. 01537 01538 \return string with contentclass name. 01539 */ 01540 static function nameFromSerializedString( $serailizedNameList ) 01541 { 01542 return eZContentClassNameList::nameFromSerializedString( $serailizedNameList ); 01543 } 01544 01545 function hasNameInLanguage( $languageLocale ) 01546 { 01547 $hasName = $this->NameList->hasNameInLocale( $languageLocale ); 01548 return $hasName; 01549 } 01550 01551 /*! 01552 Returns a contentclass name in \a $languageLocale language. 01553 Uses siteaccess language list or 'always available' language if \a $languageLocale is 'false'. 01554 01555 \return string with contentclass name. 01556 */ 01557 function name( $languageLocale = false ) 01558 { 01559 return $this->NameList->name( $languageLocale ); 01560 } 01561 01562 function setName( $name, $languageLocale = false ) 01563 { 01564 if ( !$languageLocale ) 01565 $languageLocale = $this->topPriorityLanguageLocale(); 01566 $this->NameList->setNameByLanguageLocale( $name, $languageLocale ); 01567 01568 $languageID = eZContentLanguage::idByLocale( $languageLocale ); 01569 $languageMask = $this->attribute( 'language_mask' ); 01570 $this->setAttribute( 'language_mask', $languageMask | $languageID ); 01571 } 01572 01573 function setAlwaysAvailableLanguageID( $languageID, $updateChilds = true ) 01574 { 01575 $db = eZDB::instance(); 01576 $db->begin(); 01577 01578 $languageLocale = false; 01579 if ( $languageID ) 01580 { 01581 $language = eZContentLanguage::fetch( $languageID ); 01582 $languageLocale = $language->attribute( 'locale' ); 01583 } 01584 01585 if ( $languageID ) 01586 { 01587 $this->setAttribute( 'language_mask', (int)$this->attribute( 'language_mask' ) | 1 ); 01588 $this->NameList->setAlwaysAvailableLanguage( $languageLocale ); 01589 } 01590 else 01591 { 01592 $this->setAttribute( 'language_mask', (int)$this->attribute( 'language_mask' ) & ~1 ); 01593 $this->NameList->setAlwaysAvailableLanguage( false ); 01594 } 01595 $this->store(); 01596 01597 $classID = $this->attribute( 'id' ); 01598 $version = $this->attribute( 'version' ); 01599 01600 $attributes = $this->fetchAttributes(); 01601 foreach( $attributes as $attribute ) 01602 { 01603 $attribute->setAlwaysAvailableLanguage( $languageLocale ); 01604 $attribute->store(); 01605 } 01606 01607 // reset 'always available' flag 01608 $sql = "UPDATE ezcontentclass_name SET language_id="; 01609 if ( $db->databaseName() == 'oracle' ) 01610 { 01611 $sql .= "bitand( language_id, -2 )"; 01612 } 01613 else 01614 { 01615 $sql .= "language_id & ~1"; 01616 } 01617 $sql .= " WHERE contentclass_id = '$classID' AND contentclass_version = '$version'"; 01618 $db->query( $sql ); 01619 01620 if ( $languageID != false ) 01621 { 01622 $newLanguageID = $languageID | 1; 01623 01624 $sql = "UPDATE ezcontentclass_name 01625 SET language_id='$newLanguageID' 01626 WHERE language_id='$languageID' AND contentclass_id = '$classID' AND contentclass_version = '$version'"; 01627 $db->query( $sql ); 01628 } 01629 01630 $db->commit(); 01631 } 01632 01633 function clearAlwaysAvailableLanguageID() 01634 { 01635 $this->setAlwaysAvailableLanguageID( false ); 01636 } 01637 01638 /*! 01639 Wrapper for eZContentClassNameList::languages. 01640 */ 01641 function languages() 01642 { 01643 return $this->NameList->languages(); 01644 } 01645 01646 /*! 01647 Wrapper for eZContentClassNameList::prioritizedLanguages. 01648 */ 01649 function prioritizedLanguages() 01650 { 01651 return $this->NameList->prioritizedLanguages(); 01652 } 01653 01654 function prioritizedLanguagesJsArray() 01655 { 01656 return $this->NameList->prioritizedLanguagesJsArray(); 01657 } 01658 01659 /*! 01660 Wrapper for eZContentClassNameList::untranslatedLanguages. 01661 */ 01662 function canCreateLanguages() 01663 { 01664 return $this->NameList->untranslatedLanguages(); 01665 } 01666 01667 /*! 01668 Wrapper for eZContentClassNameList::topPriorityLanguageLocale. 01669 */ 01670 function topPriorityLanguageLocale() 01671 { 01672 return $this->NameList->topPriorityLanguageLocale(); 01673 } 01674 01675 /*! 01676 Wrapper for eZContentClassNameList::alwaysAvailableLanguage. 01677 01678 \return 'language' object. 01679 */ 01680 function alwaysAvailableLanguage() 01681 { 01682 return $this->NameList->alwaysAvailableLanguage(); 01683 } 01684 01685 /*! 01686 Wrapper for eZContentClassNameList::alwaysAvailableLanguageLocale. 01687 01688 \return 'language' object. 01689 */ 01690 function alwaysAvailableLanguageLocale() 01691 { 01692 $language = $this->NameList->alwaysAvailableLanguageLocale(); 01693 return $language; 01694 } 01695 01696 function nameList() 01697 { 01698 return $this->NameList->nameList(); 01699 } 01700 01701 /*! 01702 Removes translated name for specified by \a $languageID language. 01703 */ 01704 function removeTranslation( $languageID ) 01705 { 01706 $language = eZContentLanguage::fetch( $languageID ); 01707 01708 if ( !$language ) 01709 { 01710 return false; 01711 } 01712 01713 // check if it is not the initial language 01714 $classInitialLanguageID = $this->attribute( 'initial_language_id' ); 01715 if ( $classInitialLanguageID == $languageID ) 01716 { 01717 return false; 01718 } 01719 01720 $db = eZDB::instance(); 01721 $db->begin(); 01722 01723 $classID = $this->attribute( 'id' ); 01724 $languageID = $language->attribute( 'id' ); 01725 01726 // change language_mask of the object 01727 $languageMask = (int) $this->attribute( 'language_mask' ); 01728 $languageMask = (int) $languageMask & ~ (int) $languageID; 01729 $this->setAttribute( 'language_mask', $languageMask ); 01730 01731 // Remove all names in the language 01732 $db->query( "DELETE FROM ezcontentclass_name 01733 WHERE contentclass_id='$classID' 01734 AND language_id='$languageID'" ); 01735 01736 $languageLocale = $language->attribute( 'locale' ); 01737 $this->NameList->removeName( $languageLocale ); 01738 01739 $this->store(); 01740 01741 // Remove names for attributes in the language 01742 $attributes = $this->fetchAttributes(); 01743 foreach ( $attributes as $attribute ) 01744 { 01745 $attribute->removeTranslation( $languageLocale ); 01746 $attribute->store(); 01747 } 01748 01749 $db->commit(); 01750 01751 return true; 01752 } 01753 01754 /*! 01755 Returns an array of IDs of classes containing a specified datatype 01756 01757 \param $dataTypeString a datatype identification string 01758 */ 01759 static function fetchIDListContainingDatatype( $dataTypeString ) 01760 { 01761 $db = eZDB::instance(); 01762 01763 $version = self::VERSION_STATUS_DEFINED; 01764 $escapedDataTypeString = $db->escapeString( $dataTypeString ); 01765 01766 $sql = "SELECT DISTINCT contentclass_id 01767 FROM ezcontentclass_attribute 01768 WHERE version=$version 01769 AND data_type_string='$escapedDataTypeString'"; 01770 01771 $classIDArray = $db->arrayQuery( $sql, array( 'column' => 'contentclass_id' ) ); 01772 return $classIDArray; 01773 } 01774 01775 /// \privatesection 01776 public $ID; 01777 // serialized array of translated class names 01778 public $SerializedNameList; 01779 // unserialized class names 01780 public $NameList; 01781 public $Identifier; 01782 public $ContentObjectName; 01783 public $Version; 01784 public $VersionCount; 01785 public $CreatorID; 01786 public $ModifierID; 01787 public $Created; 01788 public $Modified; 01789 public $InGroups; 01790 public $AllGroups; 01791 public $IsContainer; 01792 public $CanInstantiateLanguages; 01793 public $LanguageMask; 01794 } 01795 01796 ?>