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