eZ Publish  [trunk]
ezcontentclasspackagehandler.php
Go to the documentation of this file.
00001 <?php
00002 /**
00003  * File containing the eZContentClassPackageHandler class.
00004  *
00005  * @copyright Copyright (C) 1999-2012 eZ Systems AS. All rights reserved.
00006  * @license http://www.gnu.org/licenses/gpl-2.0.txt GNU General Public License v2
00007  * @version //autogentag//
00008  * @package kernel
00009  */
00010 
00011 /*!
00012   \class eZContentClassPackageHandler ezcontentclasspackagehandler.php
00013   \brief Handles content classes in the package system
00014 
00015 */
00016 
00017 class eZContentClassPackageHandler extends eZPackageHandler
00018 {
00019     const ERROR_EXISTS = 1;
00020     const ERROR_HAS_OBJECTS = 101;
00021 
00022     const ACTION_REPLACE = 1;
00023     const ACTION_SKIP = 2;
00024     const ACTION_NEW = 3;
00025     const ACTION_DELETE = 4;
00026 
00027     /*!
00028      Constructor
00029     */
00030     function eZContentClassPackageHandler()
00031     {
00032         $this->eZPackageHandler( 'ezcontentclass',
00033                                  array( 'extract-install-content' => true ) );
00034     }
00035 
00036     /*!
00037      Returns an explanation for the content class install item.
00038      Use $requestedInfo to request portion of info.
00039     */
00040     function explainInstallItem( $package, $installItem, $requestedInfo = array( 'name', 'identifier', 'description', 'language_info' ) )
00041     {
00042         if ( $installItem['filename'] )
00043         {
00044             $explainClassName = in_array( 'name', $requestedInfo );
00045             $explainClassIdentitier = in_array( 'identifier', $requestedInfo );
00046             $explainDescription = in_array( 'description', $requestedInfo );
00047             $explainLanguageInfo = in_array( 'language_info', $requestedInfo );
00048 
00049             $filename = $installItem['filename'];
00050             $subdirectory = $installItem['sub-directory'];
00051             if ( $subdirectory )
00052                 $filepath = $subdirectory . '/' . $filename . '.xml';
00053             else
00054                 $filepath = $filename . '.xml';
00055 
00056             $filepath = $package->path() . '/' . $filepath;
00057 
00058             $dom = $package->fetchDOMFromFile( $filepath );
00059             if ( $dom )
00060             {
00061                 $languageInfo = array();
00062 
00063                 $content = $dom->documentElement;
00064                 $classIdentifier = $explainClassIdentitier ? $content->getElementsByTagName( 'identifier' )->item( 0 )->textContent : '';
00065 
00066                 $className = '';
00067                 if ( $explainClassName )
00068                 {
00069                     // BC ( <= 3.8 )
00070                     $classNameNode = $content->getElementsByTagName( 'name' )->item( 0 );
00071 
00072                     if( $classNameNode )
00073                     {
00074                         $className = $classNameNode->textContent;
00075                     }
00076                     else
00077                     {
00078                         // get info about translations.
00079                         $serializedNameListNode = $content->getElementsByTagName( 'serialized-name-list' )->item( 0 );
00080                         if( $serializedNameListNode )
00081                         {
00082                             $serializedNameList = $serializedNameListNode->textContent;
00083                             $nameList = new eZContentClassNameList( $serializedNameList );
00084                             $languageInfo = $explainLanguageInfo ? $nameList->languageLocaleList() : array();
00085                             $className = $nameList->name();
00086                         }
00087                     }
00088                 }
00089 
00090                 $description = $explainDescription ? ezpI18n::tr( 'kernel/package', "Content class '%classname' (%classidentifier)", false,
00091                                                              array( '%classname' => $className,
00092                                                                     '%classidentifier' => $classIdentifier ) ) : '';
00093                 $explainInfo = array( 'description' => $description,
00094                                       'language_info' => $languageInfo );
00095                 return $explainInfo;
00096             }
00097         }
00098     }
00099 
00100     /*!
00101      Uninstalls all previously installed content classes.
00102     */
00103     function uninstall( $package, $installType, $parameters,
00104                       $name, $os, $filename, $subdirectory,
00105                       $content, &$installParameters,
00106                       &$installData )
00107     {
00108         $classRemoteID = $content->getElementsByTagName( 'remote-id' )->item( 0 )->textContent;
00109 
00110         $class = eZContentClass::fetchByRemoteID( $classRemoteID );
00111 
00112         if ( $class == null )
00113         {
00114             eZDebug::writeNotice( "Class having remote id '$classRemoteID' not found.", __METHOD__ );
00115             return true;
00116         }
00117 
00118         if ( $class->isRemovable() )
00119         {
00120             $choosenAction = $this->errorChoosenAction( self::ERROR_HAS_OBJECTS,
00121                                                         $installParameters, false, $this->HandlerType );
00122             if ( $choosenAction == self::ACTION_SKIP )
00123             {
00124                 return true;
00125             }
00126             if ( $choosenAction != self::ACTION_DELETE )
00127             {
00128                 $objectsCount = eZContentObject::fetchSameClassListCount( $class->attribute( 'id' ) );
00129                 $name = $class->attribute( 'name' );
00130                 if ( $objectsCount )
00131                 {
00132                     $installParameters['error'] = array( 'error_code' => self::ERROR_HAS_OBJECTS,
00133                                                          'element_id' => $classRemoteID,
00134                                                          'description' => ezpI18n::tr( 'kernel/package',
00135                                                                                   "Removing class '%classname' will result in the removal of %objectscount object(s) of this class and all their sub-items. Are you sure you want to uninstall it?",
00136                                                                                   false,
00137                                                                                   array( '%classname' => $name,
00138                                                                                          '%objectscount' => $objectsCount ) ),
00139                                                          'actions' => array( self::ACTION_DELETE => "Uninstall class and object(s)",
00140                                                                              self::ACTION_SKIP => 'Skip' ) );
00141                     return false;
00142                 }
00143             }
00144 
00145             eZDebug::writeNotice( sprintf( "Removing class '%s' (%d)", $class->attribute( 'name' ), $class->attribute( 'id' ) ) );
00146 
00147             eZContentClassOperations::remove( $class->attribute( 'id' ) );
00148         }
00149 
00150         return true;
00151     }
00152 
00153     /*!
00154      Creates a new contentclass as defined in the xml structure.
00155     */
00156     function install( $package, $installType, $parameters,
00157                       $name, $os, $filename, $subdirectory,
00158                       $content, &$installParameters,
00159                       &$installData )
00160     {
00161         $serializedNameListNode = $content->getElementsByTagName( 'serialized-name-list' )->item( 0 );
00162         $serializedNameList = $serializedNameListNode ? $serializedNameListNode->textContent : false;
00163         $classNameList = new eZContentClassNameList( $serializedNameList );
00164         if ( $classNameList->isEmpty() )
00165         {
00166             $classNameList->initFromString( $content->getElementsByTagName( 'name' )->item( 0 )->textContent ); // for backward compatibility( <= 3.8 )
00167         }
00168         $classNameList->validate( );
00169 
00170         $serializedDescriptionListNode = $content->getElementsByTagName( 'serialized-description-list' )->item( 0 );
00171         $serializedDescriptionList = $serializedDescriptionListNode ? $serializedDescriptionListNode->textContent : false;
00172         $classDescriptionList = new eZSerializedObjectNameList( $serializedDescriptionList );
00173 
00174         $classIdentifier = $content->getElementsByTagName( 'identifier' )->item( 0 )->textContent;
00175         $classRemoteID = $content->getElementsByTagName( 'remote-id' )->item( 0 )->textContent;
00176         $classObjectNamePattern = $content->getElementsByTagName( 'object-name-pattern' )->item( 0 )->textContent;
00177         $classURLAliasPattern = is_object( $content->getElementsByTagName( 'url-alias-pattern' )->item( 0 ) ) ?
00178             $content->getElementsByTagName( 'url-alias-pattern' )->item( 0 )->textContent :
00179             null;
00180         $classIsContainer = $content->getAttribute( 'is-container' );
00181         if ( $classIsContainer !== false )
00182             $classIsContainer = $classIsContainer == 'true' ? 1 : 0;
00183 
00184         $classRemoteNode = $content->getElementsByTagName( 'remote' )->item( 0 );
00185         $classID = $classRemoteNode->getElementsByTagName( 'id' )->item( 0 )->textContent;
00186         $classGroupsNode = $classRemoteNode->getElementsByTagName( 'groups' )->item( 0 );
00187         $classCreated = $classRemoteNode->getElementsByTagName( 'created' )->item( 0 )->textContent;
00188         $classModified = $classRemoteNode->getElementsByTagName( 'modified' )->item( 0 )->textContent;
00189         $classCreatorNode = $classRemoteNode->getElementsByTagName( 'creator' )->item( 0 );
00190         $classModifierNode = $classRemoteNode->getElementsByTagName( 'modifier' )->item( 0 );
00191 
00192         $classAttributesNode = $content->getElementsByTagName( 'attributes' )->item( 0 );
00193 
00194         $dateTime = time();
00195         $classCreated = $dateTime;
00196         $classModified = $dateTime;
00197 
00198         $userID = false;
00199         if ( isset( $installParameters['user_id'] ) )
00200             $userID = $installParameters['user_id'];
00201 
00202         $class = eZContentClass::fetchByRemoteID( $classRemoteID );
00203 
00204         if ( $class )
00205         {
00206             $className = $class->name();
00207             $description = ezpI18n::tr( 'kernel/package', "Class '%classname' already exists.", false,
00208                                    array( '%classname' => $className ) );
00209 
00210             $choosenAction = $this->errorChoosenAction( self::ERROR_EXISTS,
00211                                                         $installParameters, $description, $this->HandlerType );
00212             switch( $choosenAction )
00213             {
00214             case eZPackage::NON_INTERACTIVE:
00215             case self::ACTION_REPLACE:
00216                 if ( eZContentClassOperations::remove( $class->attribute( 'id' ) ) == false )
00217                 {
00218                     eZDebug::writeWarning( "Unable to remove class '$className'." );
00219                     return true;
00220                 }
00221                 eZDebug::writeNotice( "Class '$className' will be replaced.", 'eZContentClassPackageHandler' );
00222                 break;
00223 
00224             case self::ACTION_SKIP:
00225                 return true;
00226 
00227             case self::ACTION_NEW:
00228                 $class->setAttribute( 'remote_id', eZRemoteIdUtility::generate( 'class' ) );
00229                 $class->store();
00230                 $classNameList->appendGroupName( " (imported)" );
00231                 break;
00232 
00233             default:
00234                 $installParameters['error'] = array( 'error_code' => self::ERROR_EXISTS,
00235                                                      'element_id' => $classRemoteID,
00236                                                      'description' => $description,
00237                                                      'actions' => array() );
00238                 if ( $class->isRemovable() )
00239                 {
00240                     $errorMsg = ezpI18n::tr( 'kernel/package', "Replace existing class" );
00241                     $objectsCount = eZContentObject::fetchSameClassListCount( $class->attribute( 'id' ) );
00242                     if ( $objectsCount )
00243                         $errorMsg .= ' ' . ezpI18n::tr( 'kernel/package', "(Warning! $objectsCount content object(s) and their sub-items will be removed)" );
00244                     $installParameters['error']['actions'][self::ACTION_REPLACE] = $errorMsg;
00245                 }
00246                 $installParameters['error']['actions'][self::ACTION_SKIP] = ezpI18n::tr( 'kernel/package', 'Skip installing this class' );
00247                 $installParameters['error']['actions'][self::ACTION_NEW] = ezpI18n::tr( 'kernel/package', 'Keep existing and create a new one' );
00248                 return false;
00249             }
00250         }
00251 
00252         unset( $class );
00253 
00254         // Try to create a unique class identifier
00255         $currentClassIdentifier = $classIdentifier;
00256         $unique = false;
00257 
00258         while( !$unique )
00259         {
00260             $classList = eZContentClass::fetchByIdentifier( $currentClassIdentifier );
00261             if ( $classList )
00262             {
00263                 // "increment" class identifier
00264                 if ( preg_match( '/^(.*)_(\d+)$/', $currentClassIdentifier, $matches ) )
00265                     $currentClassIdentifier = $matches[1] . '_' . ( $matches[2] + 1 );
00266                 else
00267                     $currentClassIdentifier = $currentClassIdentifier . '_1';
00268             }
00269             else
00270                 $unique = true;
00271 
00272             unset( $classList );
00273         }
00274 
00275         $classIdentifier = $currentClassIdentifier;
00276 
00277         $values = array( 'version' => 0,
00278                          'serialized_name_list' => $classNameList->serializeNames(),
00279                          'serialized_description_list' => $classDescriptionList->serializeNames(),
00280                          'create_lang_if_not_exist' => true,
00281                          'identifier' => $classIdentifier,
00282                          'remote_id' => $classRemoteID,
00283                          'contentobject_name' => $classObjectNamePattern,
00284                          'url_alias_name' => $classURLAliasPattern,
00285                          'is_container' => $classIsContainer,
00286                          'created' => $classCreated,
00287                          'modified' => $classModified );
00288 
00289         if ( $content->hasAttribute( 'sort-field' ) )
00290         {
00291             $values['sort_field'] = eZContentObjectTreeNode::sortFieldID( $content->getAttribute( 'sort-field' ) );
00292         }
00293         else
00294         {
00295             eZDebug::writeNotice( 'The sort field was not specified in the content class package. ' .
00296                                   'This property is exported and imported since eZ Publish 4.0.2', __METHOD__ );
00297         }
00298 
00299         if ( $content->hasAttribute( 'sort-order' ) )
00300         {
00301             $values['sort_order'] = $content->getAttribute( 'sort-order' );
00302         }
00303         else
00304         {
00305             eZDebug::writeNotice( 'The sort order was not specified in the content class package. ' .
00306                                   'This property is exported and imported since eZ Publish 4.0.2', __METHOD__ );
00307         }
00308 
00309         if ( $content->hasAttribute( 'always-available' ) )
00310         {
00311             $values['always_available'] = ( $content->getAttribute( 'always-available' ) === 'true' ? 1 : 0 );
00312         }
00313         else
00314         {
00315             eZDebug::writeNotice( 'The default object availability was not specified in the content class package. ' .
00316                                   'This property is exported and imported since eZ Publish 4.0.2', __METHOD__ );
00317         }
00318 
00319         // create class
00320         $class = eZContentClass::create( $userID,
00321                                          $values );
00322         $class->store();
00323 
00324         $classID = $class->attribute( 'id' );
00325 
00326         if ( !isset( $installData['classid_list'] ) )
00327             $installData['classid_list'] = array();
00328         if ( !isset( $installData['classid_map'] ) )
00329             $installData['classid_map'] = array();
00330         $installData['classid_list'][] = $class->attribute( 'id' );
00331         $installData['classid_map'][$classID] = $class->attribute( 'id' );
00332 
00333         // create class attributes
00334         $classAttributeList = $classAttributesNode->getElementsByTagName( 'attribute' );
00335         foreach ( $classAttributeList as $classAttributeNode )
00336         {
00337             $isNotSupported = strtolower( $classAttributeNode->getAttribute( 'unsupported' ) ) == 'true';
00338             if ( $isNotSupported )
00339                 continue;
00340 
00341             $attributeDatatype = $classAttributeNode->getAttribute( 'datatype' );
00342             $attributeIsRequired = strtolower( $classAttributeNode->getAttribute( 'required' ) ) == 'true';
00343             $attributeIsSearchable = strtolower( $classAttributeNode->getAttribute( 'searchable' ) ) == 'true';
00344             $attributeIsInformationCollector = strtolower( $classAttributeNode->getAttribute( 'information-collector' ) ) == 'true';
00345             $attributeIsTranslatable = strtolower( $classAttributeNode->getAttribute( 'translatable' ) ) == 'true';
00346             $attributeSerializedNameListNode = $classAttributeNode->getElementsByTagName( 'serialized-name-list' )->item( 0 );
00347             $attributeSerializedNameListContent = $attributeSerializedNameListNode ? $attributeSerializedNameListNode->textContent : false;
00348             $attributeSerializedNameList = new eZSerializedObjectNameList( $attributeSerializedNameListContent );
00349             if ( $attributeSerializedNameList->isEmpty() )
00350                 $attributeSerializedNameList->initFromString( $classAttributeNode->getElementsByTagName( 'name' )->item( 0 )->textContent ); // for backward compatibility( <= 3.8 )
00351             $attributeSerializedNameList->validate( );
00352 
00353             $attributeSerializedDescriptionListNode = $classAttributeNode->getElementsByTagName( 'serialized-description-list' )->item( 0 );
00354             $attributeSerializedDescriptionListContent = $attributeSerializedDescriptionListNode ? $attributeSerializedDescriptionListNode->textContent : false;
00355             $attributeSerializedDescriptionList = new eZSerializedObjectNameList( $attributeSerializedDescriptionListContent );
00356 
00357             $attributeCategoryNode = $classAttributeNode->getElementsByTagName( 'category' )->item( 0 );
00358             $attributeCategory = $attributeCategoryNode ? $attributeCategoryNode->textContent : '';
00359 
00360             $attributeSerializedDataTextNode = $classAttributeNode->getElementsByTagName( 'serialized-description-text' )->item( 0 );
00361             $attributeSerializedDataTextContent = $attributeSerializedDataTextNode ? $attributeSerializedDataTextNode->textContent : false;
00362             $attributeSerializedDataText = new eZSerializedObjectNameList( $attributeSerializedDataTextContent );
00363 
00364             $attributeIdentifier = $classAttributeNode->getElementsByTagName( 'identifier' )->item( 0 )->textContent;
00365             $attributePlacement = $classAttributeNode->getElementsByTagName( 'placement' )->item( 0 )->textContent;
00366             $attributeDatatypeParameterNode = $classAttributeNode->getElementsByTagName( 'datatype-parameters' )->item( 0 );
00367 
00368             $classAttribute = $class->fetchAttributeByIdentifier( $attributeIdentifier );
00369             if ( !$classAttribute )
00370             {
00371                 $classAttribute = eZContentClassAttribute::create( $class->attribute( 'id' ),
00372                                                                    $attributeDatatype,
00373                                                                    array( 'version' => 0,
00374                                                                           'identifier' => $attributeIdentifier,
00375                                                                           'serialized_name_list' => $attributeSerializedNameList->serializeNames(),
00376                                                                           'serialized_description_list' => $attributeSerializedDescriptionList->serializeNames(),
00377                                                                           'category' => $attributeCategory,
00378                                                                           'serialized_data_text' => $attributeSerializedDataText->serializeNames(),
00379                                                                           'is_required' => $attributeIsRequired,
00380                                                                           'is_searchable' => $attributeIsSearchable,
00381                                                                           'is_information_collector' => $attributeIsInformationCollector,
00382                                                                           'can_translate' => $attributeIsTranslatable,
00383                                                                           'placement' => $attributePlacement ) );
00384 
00385                 $dataType = $classAttribute->dataType();
00386                 $classAttribute->store();
00387                 $dataType->unserializeContentClassAttribute( $classAttribute, $classAttributeNode, $attributeDatatypeParameterNode );
00388                 $classAttribute->sync();
00389             }
00390         }
00391 
00392         // add class to a class group
00393         $classGroupsList = $classGroupsNode->getElementsByTagName( 'group' );
00394         foreach ( $classGroupsList as $classGroupNode )
00395         {
00396             $classGroupName = $classGroupNode->getAttribute( 'name' );
00397             $classGroup = eZContentClassGroup::fetchByName( $classGroupName );
00398             if ( !$classGroup )
00399             {
00400                 $classGroup = eZContentClassGroup::create();
00401                 $classGroup->setAttribute( 'name', $classGroupName );
00402                 $classGroup->store();
00403             }
00404             $classGroup->appendClass( $class );
00405         }
00406         return true;
00407     }
00408 
00409     function add( $packageType, $package, $cli, $parameters )
00410     {
00411         foreach ( $parameters['class-list'] as $classItem )
00412         {
00413             $classID = $classItem['id'];
00414             $classIdentifier = $classItem['identifier'];
00415             $classValue = $classItem['value'];
00416             $cli->notice( "Adding class $classValue to package" );
00417             $this->addClass( $package, $classID, $classIdentifier );
00418         }
00419     }
00420 
00421     /*!
00422      \static
00423      Adds the content class with ID \a $classID to the package.
00424      If \a $classIdentifier is \c false then it will be fetched from the class.
00425     */
00426     static function addClass( $package, $classID, $classIdentifier = false )
00427     {
00428         $class = false;
00429         if ( is_numeric( $classID ) )
00430             $class = eZContentClass::fetch( $classID );
00431         if ( !$class )
00432             return;
00433         $classNode = eZContentClassPackageHandler::classDOMTree( $class );
00434         if ( !$classNode )
00435             return;
00436         if ( !$classIdentifier )
00437             $classIdentifier = $class->attribute( 'identifier' );
00438         $package->appendInstall( 'ezcontentclass', false, false, true,
00439                                  'class-' . $classIdentifier, 'ezcontentclass',
00440                                  array( 'content' => $classNode ) );
00441         $package->appendProvides( 'ezcontentclass', 'contentclass', $class->attribute( 'identifier' ) );
00442         $package->appendInstall( 'ezcontentclass', false, false, false,
00443                                  'class-' . $classIdentifier, 'ezcontentclass',
00444                                  array( 'content' => false ) );
00445     }
00446 
00447     function handleAddParameters( $packageType, $package, $cli, $arguments )
00448     {
00449         return $this->handleParameters( $packageType, $package, $cli, 'add', $arguments );
00450     }
00451 
00452     /*!
00453      \private
00454     */
00455     function handleParameters( $packageType, $package, $cli, $type, $arguments )
00456     {
00457         $classList = false;
00458         foreach ( $arguments as $argument )
00459         {
00460             if ( $argument[0] == '-' )
00461             {
00462                 if ( strlen( $argument ) > 1 and
00463                      $argument[1] == '-' )
00464                 {
00465                 }
00466                 else
00467                 {
00468                 }
00469             }
00470             else
00471             {
00472                 if ( $classList === false )
00473                 {
00474                     $classList = array();
00475                     $classArray = explode( ',', $argument );
00476                     $error = false;
00477                     foreach ( $classArray as $classID )
00478                     {
00479                         if ( in_array( $classID, $classList ) )
00480                         {
00481                             $cli->notice( "Content class $classID already in list" );
00482                             continue;
00483                         }
00484                         if ( is_numeric( $classID ) )
00485                         {
00486                             if ( !eZContentClass::exists( $classID, 0, false, false ) )
00487                             {
00488                                 $cli->error( "Content class with ID $classID does not exist" );
00489                                 $error = true;
00490                             }
00491                             else
00492                             {
00493                                 unset( $class );
00494                                 $class = eZContentClass::fetch( $classID );
00495                                 $classList[] = array( 'id' => $classID,
00496                                                       'identifier' => $class->attribute( 'identifier' ),
00497                                                       'value' => $classID );
00498                             }
00499                         }
00500                         else
00501                         {
00502                             $realClassID = eZContentClass::exists( $classID, 0, false, true );
00503                             if ( !$realClassID )
00504                             {
00505                                 $cli->error( "Content class with identifier $classID does not exist" );
00506                                 $error = true;
00507                             }
00508                             else
00509                             {
00510                                 unset( $class );
00511                                 $class = eZContentClass::fetch( $realClassID );
00512                                 $classList[] = array( 'id' => $realClassID,
00513                                                       'identifier' => $class->attribute( 'identifier' ),
00514                                                       'value' => $classID );
00515                             }
00516                         }
00517                     }
00518                     if ( $error )
00519                         return false;
00520                 }
00521             }
00522         }
00523         if ( $classList === false )
00524         {
00525             $cli->error( "No class ids chosen" );
00526             return false;
00527         }
00528         return array( 'class-list' => $classList );
00529     }
00530 
00531     /*!
00532      \static
00533      Creates the DOM tree for the content class \a $class and returns the root node.
00534     */
00535     static function classDOMTree( $class )
00536     {
00537         if ( !$class )
00538         {
00539             $retValue = false;
00540             return $retValue;
00541         }
00542 
00543         $dom = new DOMDocument( '1.0', 'utf-8' );
00544         $classNode = $dom->createElement( 'content-class' );
00545         $dom->appendChild( $classNode );
00546 
00547         $serializedNameListNode = $dom->createElement( 'serialized-name-list' );
00548         $serializedNameListNode->appendChild( $dom->createTextNode( $class->attribute( 'serialized_name_list' ) ) );
00549         $classNode->appendChild( $serializedNameListNode );
00550 
00551         $identifierNode = $dom->createElement( 'identifier' );
00552         $identifierNode->appendChild( $dom->createTextNode( $class->attribute( 'identifier' ) ) );
00553         $classNode->appendChild( $identifierNode );
00554 
00555         $serializedDescriptionListNode = $dom->createElement( 'serialized-description-list' );
00556         $serializedDescriptionListNode->appendChild( $dom->createTextNode( $class->attribute( 'serialized_description_list' ) ) );
00557         $classNode->appendChild( $serializedDescriptionListNode );
00558 
00559         $remoteIDNode = $dom->createElement( 'remote-id' );
00560         $remoteIDNode->appendChild( $dom->createTextNode( $class->attribute( 'remote_id' ) ) );
00561         $classNode->appendChild( $remoteIDNode );
00562 
00563         $objectNamePatternNode = $dom->createElement( 'object-name-pattern' );
00564         $objectNamePatternNode->appendChild( $dom->createTextNode( $class->attribute( 'contentobject_name' ) ) );
00565         $classNode->appendChild( $objectNamePatternNode );
00566 
00567         $urlAliasPatternNode = $dom->createElement( 'url-alias-pattern' );
00568         $urlAliasPatternNode->appendChild( $dom->createTextNode( $class->attribute( 'url_alias_name' ) ) );
00569         $classNode->appendChild( $urlAliasPatternNode );
00570 
00571         $isContainer = $class->attribute( 'is_container' ) ? 'true' : 'false';
00572         $classNode->setAttribute( 'is-container', $isContainer );
00573         $classNode->setAttribute( 'always-available', $class->attribute( 'always_available' ) ? 'true' : 'false' );
00574         $classNode->setAttribute( 'sort-field', eZContentObjectTreeNode::sortFieldName( $class->attribute( 'sort_field' ) ) );
00575         $classNode->setAttribute( 'sort-order', $class->attribute( 'sort_order' ) );
00576 
00577         // Remote data start
00578         $remoteNode = $dom->createElement( 'remote' );
00579         $classNode->appendChild( $remoteNode );
00580 
00581         $ini = eZINI::instance();
00582         $siteName = $ini->variable( 'SiteSettings', 'SiteURL' );
00583 
00584         $classURL = 'http://' . $siteName . '/class/view/' . $class->attribute( 'id' );
00585         $siteURL = 'http://' . $siteName . '/';
00586 
00587         $siteUrlNode = $dom->createElement( 'site-url' );
00588         $siteUrlNode->appendChild( $dom->createTextNode( $siteURL ) );
00589         $remoteNode->appendChild( $siteUrlNode );
00590 
00591         $urlNode = $dom->createElement( 'url' );
00592         $urlNode->appendChild( $dom->createTextNode( $classURL ) );
00593         $remoteNode->appendChild( $urlNode );
00594 
00595         $classGroupsNode = $dom->createElement( 'groups' );
00596 
00597         $classGroupList = eZContentClassClassGroup::fetchGroupList( $class->attribute( 'id' ),
00598                                                                     $class->attribute( 'version' ) );
00599         foreach ( $classGroupList as $classGroupLink )
00600         {
00601             $classGroup = eZContentClassGroup::fetch( $classGroupLink->attribute( 'group_id' ) );
00602             if ( $classGroup )
00603             {
00604                 unset( $groupNode );
00605                 $groupNode = $dom->createElement( 'group' );
00606                 $groupNode->setAttribute( 'id', $classGroup->attribute( 'id' ) );
00607                 $groupNode->setAttribute( 'name', $classGroup->attribute( 'name' ) );
00608                 $classGroupsNode->appendChild( $groupNode );
00609             }
00610         }
00611         $remoteNode->appendChild( $classGroupsNode );
00612 
00613         $idNode = $dom->createElement( 'id' );
00614         $idNode->appendChild( $dom->createTextNode( $class->attribute( 'id' ) ) );
00615         $remoteNode->appendChild( $idNode );
00616         $createdNode = $dom->createElement( 'created' );
00617         $createdNode->appendChild( $dom->createTextNode( $class->attribute( 'created' ) ) );
00618         $remoteNode->appendChild( $createdNode );
00619         $modifiedNode = $dom->createElement( 'modified' );
00620         $modifiedNode->appendChild( $dom->createTextNode( $class->attribute( 'modified' ) ) );
00621         $remoteNode->appendChild( $modifiedNode );
00622 
00623         $creatorNode = $dom->createElement( 'creator' );
00624         $remoteNode->appendChild( $creatorNode );
00625         $creatorIDNode = $dom->createElement( 'user-id' );
00626         $creatorIDNode->appendChild( $dom->createTextNode( $class->attribute( 'creator_id' ) ) );
00627         $creatorNode->appendChild( $creatorIDNode );
00628         $creator = $class->attribute( 'creator' );
00629         if ( $creator )
00630         {
00631             $creatorLoginNode = $dom->createElement( 'user-login' );
00632             $creatorLoginNode->appendChild( $dom->createTextNode( $creator->attribute( 'login' ) ) );
00633             $creatorNode->appendChild( $creatorLoginNode );
00634         }
00635 
00636         $modifierNode = $dom->createElement( 'modifier' );
00637         $remoteNode->appendChild( $modifierNode );
00638         $modifierIDNode = $dom->createElement( 'user-id' );
00639         $modifierIDNode->appendChild( $dom->createTextNode( $class->attribute( 'modifier_id' ) ) );
00640         $modifierNode->appendChild( $modifierIDNode );
00641         $modifier = $class->attribute( 'modifier' );
00642         if ( $modifier )
00643         {
00644             $modifierLoginNode = $dom->createElement( 'user-login' );
00645             $modifierLoginNode->appendChild( $dom->createTextNode( $modifier->attribute( 'login' ) ) );
00646             $modifierNode->appendChild( $modifierLoginNode );
00647         }
00648         // Remote data end
00649 
00650         $attributesNode = $dom->createElementNS( 'http://ezpublish/contentclassattribute', 'ezcontentclass-attribute:attributes' );
00651         $classNode->appendChild( $attributesNode );
00652 
00653         $attributes = $class->fetchAttributes();
00654         foreach( $attributes as $attribute )
00655         {
00656             $attributeNode = $dom->createElement( 'attribute' );
00657             $attributeNode->setAttribute( 'datatype', $attribute->attribute( 'data_type_string' ) );
00658             $required = $attribute->attribute( 'is_required' ) ? 'true' : 'false';
00659             $attributeNode->setAttribute( 'required' , $required );
00660             $searchable = $attribute->attribute( 'is_searchable' ) ? 'true' : 'false';
00661             $attributeNode->setAttribute( 'searchable' , $searchable );
00662             $informationCollector = $attribute->attribute( 'is_information_collector' ) ? 'true' : 'false';
00663             $attributeNode->setAttribute( 'information-collector' , $informationCollector );
00664             $translatable = $attribute->attribute( 'can_translate' ) ? 'true' : 'false';
00665             $attributeNode->setAttribute( 'translatable' , $translatable );
00666 
00667             $attributeRemoteNode = $dom->createElement( 'remote' );
00668             $attributeNode->appendChild( $attributeRemoteNode );
00669 
00670             $attributeIDNode = $dom->createElement( 'id' );
00671             $attributeIDNode->appendChild( $dom->createTextNode( $attribute->attribute( 'id' ) ) );
00672             $attributeRemoteNode->appendChild( $attributeIDNode );
00673 
00674             $attributeSerializedNameListNode = $dom->createElement( 'serialized-name-list' );
00675             $attributeSerializedNameListNode->appendChild( $dom->createTextNode( $attribute->attribute( 'serialized_name_list' ) ) );
00676             $attributeNode->appendChild( $attributeSerializedNameListNode );
00677 
00678             $attributeIdentifierNode = $dom->createElement( 'identifier' );
00679             $attributeIdentifierNode->appendChild( $dom->createTextNode( $attribute->attribute( 'identifier' ) ) );
00680             $attributeNode->appendChild( $attributeIdentifierNode );
00681 
00682             $attributeSerializedDescriptionListNode = $dom->createElement( 'serialized-description-list' );
00683             $attributeSerializedDescriptionListNode->appendChild( $dom->createTextNode( $attribute->attribute( 'serialized_description_list' ) ) );
00684             $attributeNode->appendChild( $attributeSerializedDescriptionListNode );
00685 
00686             $attributeCategoryNode = $dom->createElement( 'category' );
00687             $attributeCategoryNode->appendChild( $dom->createTextNode( $attribute->attribute( 'category' ) ) );
00688             $attributeNode->appendChild( $attributeCategoryNode );
00689 
00690             $attributeSerializedDataTextNode = $dom->createElement( 'serialized-data-text' );
00691             $attributeSerializedDataTextNode->appendChild( $dom->createTextNode( $attribute->attribute( 'serialized_data_text' ) ) );
00692             $attributeNode->appendChild( $attributeSerializedDataTextNode );
00693 
00694             $attributePlacementNode = $dom->createElement( 'placement' );
00695             $attributePlacementNode->appendChild( $dom->createTextNode( $attribute->attribute( 'placement' ) ) );
00696             $attributeNode->appendChild( $attributePlacementNode );
00697 
00698             $attributeParametersNode = $dom->createElement( 'datatype-parameters' );
00699             $attributeNode->appendChild( $attributeParametersNode );
00700 
00701             $dataType = $attribute->dataType();
00702             if ( is_object( $dataType ) )
00703             {
00704                 $dataType->serializeContentClassAttribute( $attribute, $attributeNode, $attributeParametersNode );
00705             }
00706 
00707             $attributesNode->appendChild( $attributeNode );
00708         }
00709         eZDebug::writeDebug( $dom->saveXML(), 'content class package XML' );
00710         return $classNode;
00711     }
00712 
00713     function contentclassDirectory()
00714     {
00715         return 'ezcontentclass';
00716     }
00717 }
00718 
00719 ?>