eZ Publish  [trunk]
ezdatatype.php
Go to the documentation of this file.
00001 <?php
00002 /**
00003  * File containing the eZDataType 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 /*! \defgroup eZDataType Content datatypes */
00012 
00013 /*!
00014   \class eZDataType ezdatatype.php
00015   \ingroup eZKernel
00016   \brief Base class for content datatypes
00017 
00018   Defines both the interface for datatypes as well as functions
00019   for registering, quering and fetching datatypes.
00020 
00021   Each new datatype will inherit this class and define some functions
00022   as well as three templates. A datatype has three roles, it handles
00023   definition of content class attributes, editing of a content object
00024   attribute and viewing of a content object attribute. The content class
00025   attribute definition part is optional while object attribute edit and
00026   view must be implemented for the datatype to be usable.
00027 
00028   If the datatype handles class attribute definition it must define one
00029   or more of these functions: storeClassAttribute, validateClassAttributeHTTPInput,
00030   fixupClassAttributeHTTPInput, fetchClassAttributeHTTPInput. See each function
00031   for more details. The class attribute definition usually defines the
00032   default data and/or the validation rules for an object attribute.
00033 
00034   Object attribute editing must define these functions: storeObjectAttribute,
00035   validateObjectAttributeHTTPInput, fixupObjectAttributeHTTPInput,
00036   fetchObjectAttributeHTTPInput, initializeObjectAttribute. If the attribute
00037   wants to have a custom action it must implement the customObjectAttributeHTTPAction
00038   function. See each function for more details.
00039 
00040   Each datatype initializes itself with a datatype string id (ezstring, ezinteger)
00041   and a descriptive name. The datatype string id must be unique for the whole
00042   system and should have a prefix, for instance we in eZ Systems use ez as our prefix.
00043 */
00044 
00045 class eZDataType
00046 {
00047     /*!
00048      Initializes the datatype with the string id \a $dataTypeString and
00049      the name \a $name.
00050     */
00051     function eZDataType( $dataTypeString, $name, $properties = array() )
00052     {
00053         $this->DataTypeString = $dataTypeString;
00054         $this->Name = $name;
00055 
00056         $translationAllowed = true;
00057         $serializeSupported = false;
00058         $objectSerializeMap = false;
00059         if ( isset( $properties['translation_allowed'] ) )
00060             $translationAllowed = $properties['translation_allowed'];
00061         if ( isset( $properties['serialize_supported'] ) )
00062             $serializeSupported = $properties['serialize_supported'];
00063         if ( isset( $properties['object_serialize_map'] ) )
00064             $objectSerializeMap = $properties['object_serialize_map'];
00065 
00066         $this->Attributes = array();
00067         $this->Attributes["is_indexable"] = $this->isIndexable();
00068         $this->Attributes["is_information_collector"] = $this->isInformationCollector();
00069 
00070         $this->Attributes["information"] = array( "string" => $this->DataTypeString,
00071                                                   "name" => $this->Name );
00072         $this->Attributes["properties"] = array( "translation_allowed" => $translationAllowed,
00073                                                  'serialize_supported' => $serializeSupported,
00074                                                  'object_serialize_map' => $objectSerializeMap );
00075     }
00076 
00077     /*!
00078      \return the template name to use for viewing the attribute.
00079      \note Default is to return the datatype string which is OK
00080            for most datatypes, if you want dynamic templates
00081            reimplement this function and return a template name.
00082      \note The returned template name does not include the .tpl extension.
00083      \sa editTemplate, informationTemplate
00084     */
00085     function viewTemplate( $contentobjectAttribute )
00086     {
00087         return $this->DataTypeString;
00088     }
00089 
00090     /*!
00091      \return the template name to use for editing the attribute.
00092      \note Default is to return the datatype string which is OK
00093            for most datatypes, if you want dynamic templates
00094            reimplement this function and return a template name.
00095      \note The returned template name does not include the .tpl extension.
00096      \sa viewTemplate, informationTemplate
00097     */
00098     function editTemplate( $contentobjectAttribute )
00099     {
00100         return $this->DataTypeString;
00101     }
00102 
00103     /*!
00104      \return the template name to use for information collection for the attribute.
00105      \note Default is to return the datatype string which is OK
00106            for most datatypes, if you want dynamic templates
00107            reimplement this function and return a template name.
00108      \note The returned template name does not include the .tpl extension.
00109      \sa viewTemplate, editTemplate
00110     */
00111     function informationTemplate( $contentobjectAttribute )
00112     {
00113         return $this->DataTypeString;
00114     }
00115 
00116     /*!
00117      \return the template name to use for result view of an information collection attribute.
00118      \note Default is to return the datatype string which is OK
00119            for most datatypes, if you want dynamic templates
00120            reimplement this function and return a template name.
00121      \note The returned template name does not include the .tpl extension.
00122      \note \a $collectionAttribute can in some cases be a eZContentObjectAttribute, so any
00123            datatype that overrides this must be able to handle both types.
00124     */
00125     function resultTemplate( &$collectionAttribute )
00126     {
00127         return $this->DataTypeString;
00128     }
00129 
00130     /*!
00131      \static
00132      Crates a datatype instance of the datatype string id \a $dataTypeString.
00133      \note It only creates one instance for each datatype.
00134     */
00135     static function create( $dataTypeString )
00136     {
00137         $def = null;
00138         if ( !isset( $GLOBALS["eZDataTypes"][$dataTypeString] ) )
00139         {
00140             eZDataType::loadAndRegisterType( $dataTypeString );
00141         }
00142 
00143         if ( isset( $GLOBALS['eZDataTypes'][$dataTypeString] ) )
00144         {
00145             $className = $GLOBALS['eZDataTypes'][$dataTypeString];
00146 
00147             if ( !isset( $GLOBALS["eZDataTypeObjects"][$dataTypeString] ) ||
00148                  get_class( $GLOBALS["eZDataTypeObjects"][$dataTypeString] ) != $className )
00149             {
00150                 $GLOBALS["eZDataTypeObjects"][$dataTypeString] = new $className();
00151             }
00152             return $GLOBALS["eZDataTypeObjects"][$dataTypeString];
00153         }
00154 
00155         return null;
00156     }
00157 
00158     /*!
00159      \static
00160      \return a list of datatypes which has been registered.
00161      \note This will instantiate all datatypes.
00162     */
00163     static function registeredDataTypes()
00164     {
00165         $types = isset( $GLOBALS["eZDataTypes"] ) ? $GLOBALS["eZDataTypes"] : null;
00166         if ( isset( $types ) )
00167         {
00168             foreach ( $types as $dataTypeString => $className )
00169             {
00170                 if ( !isset( $GLOBALS["eZDataTypeObjects"][$dataTypeString] ) )
00171                 {
00172                     $GLOBALS["eZDataTypeObjects"][$dataTypeString] = new $className();
00173                 }
00174             }
00175             uasort( $GLOBALS["eZDataTypeObjects"],
00176                     create_function( '$a, $b',
00177                                      'return strcmp( $a->Name, $b->Name);' ) );
00178         return $GLOBALS["eZDataTypeObjects"];
00179         }
00180         return null;
00181     }
00182 
00183     /*!
00184      \static
00185      Registers the datatype with string id \a $dataTypeString and
00186      class name \a $className. The class name is used for instantiating
00187      the class and should be in lowercase letters.
00188     */
00189     static function register( $dataTypeString, $className )
00190     {
00191         $types =& $GLOBALS["eZDataTypes"];
00192         if ( !is_array( $types ) )
00193             $types = array();
00194         $types[$dataTypeString] = $className;
00195     }
00196 
00197     /*!
00198      \return the data type identification string.
00199     */
00200     function isA()
00201     {
00202         return $this->Attributes["information"]["string"];
00203     }
00204 
00205     /**
00206      * Indicates if datatype supports being translated
00207      *
00208      * @return bool
00209      */
00210     function isTranslatable()
00211     {
00212         return $this->Attributes['properties']['translation_allowed'];
00213     }
00214 
00215     /*!
00216      \return the attributes for this datatype.
00217     */
00218     function attributes()
00219     {
00220         return array_keys( $this->Attributes );
00221     }
00222 
00223     /*!
00224      \return true if the attribute \a $attr exists in this object.
00225     */
00226     function hasAttribute( $attr )
00227     {
00228         return isset( $this->Attributes[$attr] );
00229     }
00230 
00231     /*!
00232      \return the data for the attribute \a $attr or null if it does not exist.
00233     */
00234     function attribute( $attr )
00235     {
00236         if ( isset( $this->Attributes[$attr] ) )
00237         {
00238             return $this->Attributes[$attr];
00239         }
00240 
00241         eZDebug::writeError( "Attribute '$attr' does not exist", __METHOD__ );
00242         $attributeData = null;
00243         return $attributeData;
00244     }
00245 
00246     /*!
00247      \return \c true if the datatype support insertion of HTTP files or \c false (default) otherwise.
00248 
00249      \sa insertHTTPFile()
00250     */
00251     function isHTTPFileInsertionSupported()
00252     {
00253         return false;
00254     }
00255 
00256     /*!
00257      \return \c true if the datatype support insertion of files or \c false (default) otherwise.
00258 
00259      \sa insertRegularFile()
00260     */
00261     function isRegularFileInsertionSupported()
00262     {
00263         return false;
00264     }
00265 
00266     /*!
00267      \return \c true if the datatype support insertion of simple strings or \c false (default) otherwise.
00268 
00269      \sa insertSimpleString()
00270     */
00271     function isSimpleStringInsertionSupported()
00272     {
00273         return false;
00274     }
00275 
00276     /*!
00277      \virtual
00278      Inserts the HTTP file \a $httpFile to the content object attribute \a $objectAttribute.
00279 
00280      \param $object The contentobject in which the attribute is contained
00281      \param $objectVersion The current version of the object it is being worked on
00282      \param $objectLanguage The current language being worked on
00283      \param $objectAttribute The attribute which will get the file
00284      \param $httpFile Object of type eZHTTPFile which contains information on the uploaded file
00285      \param $mimeData MIME-Type information on the file, can be used to figure out a storage name
00286      \param[out] $result Array which will be filled with information on the process, it will contain:
00287                  - errors - Array with error elements, each element is an array with \c 'description' containing the text
00288                  - require_storage - \c true if the attribute must be stored after this call, or \c false if not required at all
00289 
00290      \return \c true if the file was stored correctly in the attribute or \c false if something failed.
00291      \note The datatype will return \c null (the default) if does not support HTTP files.
00292      \note \a $result will not be defined if the return value is \c null
00293      \note The \a $httpFile must not be stored prior to calling this, the datatype will handle this internally
00294 
00295      \sa isHTTPFileInsertionSupported()
00296     */
00297     function insertHTTPFile( $object, $objectVersion, $objectLanguage,
00298                              $objectAttribute, $httpFile, $mimeData,
00299                              &$result )
00300     {
00301         eZDebug::writeWarning( "The datatype " . get_class( $this ) . " for attribute ID " . $objectAttribute->attribute( 'id' ) . " does not support insertion of HTTP files", __METHOD__ );
00302         return null;
00303     }
00304 
00305     /*!
00306      \virtual
00307      Inserts the file named \a $filePath to the content object attribute \a $objectAttribute.
00308 
00309      \param $object The contentobject in which the attribute is contained
00310      \param $objectVersion The current version of the object it is being worked on
00311      \param $objectLanguage The current language being worked on
00312      \param $objectAttribute The attribute which will get the file
00313      \param $filePath Full path including the filename
00314      \param[out] $result Array which will be filled with information on the process, it will contain:
00315                  - errors - Array with error elements, each element is an array with \c 'description' containing the text
00316                  - require_storage - \c true if the attribute must be stored after this call, or \c false if not required at all
00317 
00318      \return \c true if the file was stored correctly in the attribute or \c false if something failed.
00319      \note The datatype will return \c null (the default) if does not support HTTP files.
00320      \note \a $result will not be defined if the return value is \c null
00321 
00322      \sa isRegularFileInsertionSupported()
00323     */
00324     function insertRegularFile( $object, $objectVersion, $objectLanguage,
00325                                 $objectAttribute, $filePath,
00326                                 &$result )
00327     {
00328         eZDebug::writeWarning( "The datatype " . get_class( $this ) . " for attribute ID " . $objectAttribute->attribute( 'id' ) . " does not support insertion of regular files", __METHOD__ );
00329         return null;
00330     }
00331 
00332     /*!
00333      \virtual
00334      Inserts the string \a $string to the content object attribute \a $objectAttribute.
00335 
00336      \param $object The contentobject in which the attribute is contained
00337      \param $objectVersion The current version of the object it is being worked on
00338      \param $objectLanguage The current language being worked on
00339      \param $objectAttribute The attribute which will get the file
00340      \param $filePath Full path including the filename
00341      \param[out] $result Array which will be filled with information on the process, it will contain:
00342                  - errors - Array with error elements, each element is an array with \c 'description' containing the text
00343                  - require_storage - \c true if the attribute must be stored after this call, or \c false if not required at all
00344 
00345      \return \c true if the file was stored correctly in the attribute or \c false if something failed.
00346      \note The datatype will return \c null (the default) if does not support HTTP files.
00347      \note \a $result will not be defined if the return value is \c null
00348 
00349      \sa isSimpleStringInsertionSupported()
00350     */
00351     function insertSimpleString( $object, $objectVersion, $objectLanguage,
00352                                  $objectAttribute, $string,
00353                                  &$result )
00354     {
00355         eZDebug::writeWarning( "The datatype " . get_class( $this ) . " for attribute ID " . $objectAttribute->attribute( 'id' ) . " does not support insertion of simple strings", __METHOD__ );
00356         return null;
00357     }
00358 
00359     /*!
00360      \virtual
00361      Checks if the datatype supports returning file information.
00362 
00363      \param $object The contentobject in which the attribute is contained
00364      \param $objectVersion The current version of the object it is being worked on
00365      \param $objectLanguage The current language being worked on
00366      \param $objectAttribute The attribute which stored the file
00367 
00368      \return \c true if file information is supported or \c false if it doesn't.
00369     */
00370     function hasStoredFileInformation( $object, $objectVersion, $objectLanguage,
00371                                        $objectAttribute )
00372     {
00373         return false;
00374     }
00375 
00376     /*!
00377      \virtual
00378      This function is called when someone tries to download the file.
00379 
00380      \param $object The contentobject in which the attribute is contained
00381      \param $objectVersion The current version of the object it is being worked on
00382      \param $objectLanguage The current language being worked on
00383      \param $objectAttribute The attribute which stored the file
00384 
00385      \return \c true if any action has been don or \c false if hasn't.
00386     */
00387     function handleDownload( $object, $objectVersion, $objectLanguage,
00388                              $objectAttribute )
00389     {
00390         return false;
00391     }
00392 
00393     /*!
00394      \virtual
00395      Returns file information for the filed stored by the attribute.
00396 
00397      \param $object The contentobject in which the attribute is contained
00398      \param $objectVersion The current version of the object it is being worked on
00399      \param $objectLanguage The current language being worked on
00400      \param $objectAttribute The attribute which stored the file
00401 
00402      \return An array structure with information or \c false (default) if no
00403              information could be found.
00404              The structure must contain:
00405              - filepath - The full path to the file
00406 
00407              The structure can contain:
00408              - filename - The name of the file, if not supplied it will
00409                            be figured out from the filepath
00410              - filesize - The size of the file, if not supplied it will
00411                            be figured out from the filepath
00412              - mime_type - The MIME type for the file, if not supplied it will
00413                            be figured out from the filepath
00414     */
00415     function storedFileInformation( $object, $objectVersion, $objectLanguage,
00416                                     $objectAttribute )
00417     {
00418         return false;
00419     }
00420 
00421     /*!
00422      Fetches the product option information for option with ID \a $optionID and returns this information.
00423      This will be called from the basket when a new product with an option is added, it is then up to the
00424      specific datatype to return proper data. It will also be used to recalcuate prices.
00425 
00426      \param $objectAttribute The attribute that the datatype controls.
00427      \param $optionID The ID of the option which information should be returned from.
00428      \param $productItem The product item object which contains the option, is available for reading only.
00429      \return An array structure which contains:
00430              - id - The unique ID of the selected option, this must be unique in the attribute and will later on
00431                     be used to recalculate prices.
00432              - name - The name of the option list
00433              - value - The display string of the selected option
00434              - additional_price - A value which is added to the total product price, set to 0 or \c false if no price is used.
00435              If the option could not be found it should return \c false, if not supported it should return \c null.
00436      \sa handleProductOption
00437     */
00438     function productOptionInformation( $objectAttribute, $optionID, $productItem )
00439     {
00440         eZDebug::writeWarning( "The datatype " . get_class( $this ) . " for attribute ID " . $objectAttribute->attribute( 'id' ) . " does not support product options", __METHOD__ );
00441         return null;
00442     }
00443 
00444     /*!
00445       \virtual
00446       Will return information on how the datatype should be represented in
00447       the various display modes when used by an object.
00448 
00449       If this method is reimplemented the implementor must call this method
00450       with the new info array as second parameter.
00451 
00452       \param $objectAttribute The content object attribute to return info for.
00453       \param $mergeInfo A structure that must match the returned array, or \c false to ignore.
00454                         Any entries here will override the default.
00455       \return An array structure which contains:
00456               - \c edit
00457                 - \c grouped_input - If \c true then the datatype has lots of input elements
00458                                      that should be grouped. (e.g. in a fieldset)
00459                                      EditSettings/GroupedInput in datatype.ini is used to
00460                                      automatically determine this field
00461                 .
00462               - \c view
00463               - \c collection
00464                 - \c grouped_input - If \c true then the datatype has lots of input elements
00465                                      that should be grouped. (e.g. in a fieldset)
00466                                      CollectionSettings/GroupedInput in datatype.ini is used to
00467                                      automatically determine this field and will override
00468                                      the default and datatype setting if used.
00469                 .
00470               - \c result
00471     */
00472     function objectDisplayInformation( $objectAttribute, $mergeInfo = false )
00473     {
00474         $datatype = $objectAttribute->attribute( 'data_type_string' );
00475         $ini = eZINI::instance( 'datatype.ini' );
00476         $editGrouped = in_array( $datatype, $ini->variable( 'EditSettings', 'GroupedInput' ) );
00477         $viewGrouped = in_array( $datatype, $ini->variable( 'ViewSettings', 'GroupedInput' ) );
00478         $resultGrouped = in_array( $datatype, $ini->variable( 'ResultSettings', 'GroupedInput' ) );
00479         $collectionGrouped = in_array( $datatype, $ini->variable( 'CollectionSettings', 'GroupedInput' ) );
00480 
00481         $info = array( 'edit' => array( 'grouped_input' => false ),
00482                        'view' => array( 'grouped_input' => false),
00483                        'collection' => array( 'grouped_input' => false ),
00484                        'result' => array( 'grouped_input' => false ) );
00485         $override = array();
00486         if ( $editGrouped )
00487             $override['edit']['grouped_input'] = true;
00488         if ( $collectionGrouped )
00489             $override['collection']['grouped_input'] = true;
00490         if ( $viewGrouped )
00491             $override['view']['grouped_input'] = true;
00492         if ( $resultGrouped )
00493             $override['result']['grouped_input'] = true;
00494 
00495         if ( $mergeInfo )
00496         {
00497             // All entries in $mergeInfo will override the defaults
00498             foreach ( array( 'edit', 'view', 'collection', 'result' ) as $view )
00499             {
00500                 if ( isset( $mergeInfo[$view] ) )
00501                     $info[$view] = array_merge( $info[$view], $mergeInfo[$view] );
00502                 if ( isset( $override[$view] ) )
00503                     $info[$view] = array_merge( $info[$view], $override[$view] );
00504             }
00505         }
00506         else
00507         {
00508             // All entries in $override will override the defaults
00509             foreach ( array( 'edit', 'view', 'collection', 'result' ) as $view )
00510             {
00511                 if ( isset( $override[$view] ) )
00512                     $info[$view] = array_merge( $info[$view], $override[$view] );
00513             }
00514         }
00515         return $info;
00516     }
00517 
00518     /*!
00519       \virtual
00520       Will return information on how the datatype should be represented in
00521       the various display modes when used by a class.
00522 
00523       If this method is reimplemented the implementor must call this method
00524       with the new info array as second parameter.
00525 
00526       \param $classAttribute The content class attribute to return info for.
00527       \param $mergeInfo A structure that must match the returned array, or \c false to ignore.
00528                         Any entries here will override the default.
00529       \return An array structure which contains:
00530               - \c edit
00531                 - \c grouped_input - If \c true then the datatype has lots of input elements
00532                                      that should be grouped. (e.g. in a fieldset)
00533                                      ClassEditSettings/GroupedInput in datatype.ini is used to
00534                                      automatically determine this field and will override
00535                                      the default and datatype setting if used.
00536                 .
00537               - \c view
00538     */
00539     function classDisplayInformation( $classAttribute, $mergeInfo = false )
00540     {
00541         $datatype = $classAttribute->attribute( 'data_type_string' );
00542         $ini = eZINI::instance( 'datatype.ini' );
00543         $editGrouped = in_array( $datatype, $ini->variable( 'ClassEditSettings', 'GroupedInput' ) );
00544 
00545         $info = array( 'edit' => array( 'grouped_input' => false ),
00546                        'view' => array() );
00547         $override = array();
00548         if ( $editGrouped )
00549             $override['edit']['grouped_input'] = true;
00550 
00551         if ( $mergeInfo )
00552         {
00553             // All entries in $mergeInfo will override the defaults
00554             foreach ( array( 'edit', 'view' ) as $view )
00555             {
00556                 if ( isset( $mergeInfo[$view] ) )
00557                     $info[$view] = array_merge( $info[$view], $mergeInfo[$view] );
00558                 if ( isset( $override[$view] ) )
00559                     $info[$view] = array_merge( $info[$view], $override[$view] );
00560             }
00561         }
00562         else
00563         {
00564             // All entries in $override will override the defaults
00565             foreach ( array( 'edit', 'view' ) as $view )
00566             {
00567                 if ( isset( $override[$view] ) )
00568                     $info[$view] = array_merge( $info[$view], $override[$view] );
00569             }
00570         }
00571         return $info;
00572     }
00573 
00574     /*!
00575      Returns the content data for the given content object attribute.
00576     */
00577     function objectAttributeContent( $objectAttribute )
00578     {
00579         $retValue = '';
00580         return $retValue;
00581     }
00582 
00583     /*!
00584      \return \c true if the datatype finds any content in the attribute \a $contentObjectAttribute.
00585     */
00586     function hasObjectAttributeContent( $contentObjectAttribute )
00587     {
00588         return false;
00589     }
00590 
00591     /*!
00592      Returns the content data for the given content class attribute.
00593     */
00594     function classAttributeContent( $classAttribute )
00595     {
00596         return '';
00597     }
00598 
00599     /*!
00600      Stores the datatype data to the database which is related to the
00601      object attribute.
00602      \return True if the value was stored correctly.
00603      \note The method is entirely up to the datatype, for instance
00604            it could reuse the available types in the the attribute or
00605            store in a separate object.
00606      \sa fetchObjectAttributeHTTPInput
00607     */
00608     function storeObjectAttribute( $objectAttribute )
00609     {
00610     }
00611 
00612     /*!
00613      Performs necessary actions with attribute data after object is published,
00614      it means that you have access to published nodes.
00615      \return True if the value was stored correctly.
00616      \note The method is entirely up to the datatype, for instance
00617            it could reuse the available types in the the attribute or
00618            store in a separate object.
00619 
00620      \note Might be transaction unsafe.
00621     */
00622     function onPublish( $contentObjectAttribute, $contentObject, $publishedNodes )
00623     {
00624     }
00625 
00626     /*!
00627      Similar to the storeClassAttribute but is called before the
00628      attribute itself is stored and can be used to set values in the
00629      class attribute.
00630      \return True if the value was stored correctly.
00631      \sa fetchClassAttributeHTTPInput
00632     */
00633     function preStoreClassAttribute( $classAttribute, $version )
00634     {
00635     }
00636 
00637     /*!
00638      Stores the datatype data to the database which is related to the
00639      class attribute. The \a $version parameter determines which version
00640      is currently being stored, 0 is the real version while 1 is the
00641      temporary version.
00642      \return True if the value was stored correctly.
00643      \note The method is entirely up to the datatype, for instance
00644            it could reuse the available types in the the attribute or
00645            store in a separate object.
00646      \note This function is called after the attribute data has been stored.
00647            If you need to alter attribute data use preStoreClassAttribute instead.
00648      \sa fetchClassAttributeHTTPInput
00649     */
00650     function storeClassAttribute( $classAttribute, $version )
00651     {
00652     }
00653 
00654 
00655     /**
00656      * @note Transaction unsafe. If you call several transaction unsafe methods you must enclose
00657      *       the calls within a db transaction; thus within db->begin and db->commit.
00658      *
00659      * @param eZContentClassAttribute $classAttribute Content class attribute of the datatype
00660      */
00661     function storeDefinedClassAttribute( $classAttribute )
00662     {
00663     }
00664 
00665     /**
00666      * @note Transaction unsafe. If you call several transaction unsafe methods you must enclose
00667      *       the calls within a db transaction; thus within db->begin and db->commit.
00668      * @param eZContentClassAttribute $classAttribute Content class attribute of the datatype
00669      */
00670     function storeModifiedClassAttribute( $classAttribute )
00671     {
00672     }
00673 
00674     /**
00675      * @note Transaction unsafe. If you call several transaction unsafe methods you must enclose
00676      *       the calls within a db transaction; thus within db->begin and db->commit.
00677      * @param eZContentClassAttribute $classAttribute Content class attribute of the datatype
00678      * @param int $version Version of the attribute to be stored
00679      */
00680     function storeVersionedClassAttribute( $classAttribute, $version )
00681     {
00682         switch ( $version )
00683         {
00684             case eZContentClass::VERSION_STATUS_DEFINED:
00685                 $this->storeDefinedClassAttribute( $classAttribute );
00686                 break;
00687 
00688             case eZContentClass::VERSION_STATUS_MODIFIED:
00689                 $this->storeModifiedClassAttribute( $classAttribute );
00690                 break;
00691         }
00692     }
00693 
00694     /**
00695      * @param eZContentClassAttribute $classAttribute Content class attribute of the datatype
00696      */
00697     function preStoreDefinedClassAttribute( $classAttribute )
00698     {
00699         $this->preStoreClassAttribute( $classAttribute, $classAttribute->attribute( 'version' ) );
00700     }
00701 
00702     /**
00703      * @param eZContentClassAttribute $classAttribute Content class attribute of the datatype
00704      */
00705     function preStoreModifiedClassAttribute( $classAttribute )
00706     {
00707         $this->preStoreClassAttribute( $classAttribute, $classAttribute->attribute( 'version' ) );
00708     }
00709 
00710     /**
00711      * Hook function which is called before an content class attribute is stored
00712      *
00713      * @see eZContentClassAttribute::storeVersioned()
00714      * @param eZContentClassAttribute $classAttribute Content class attribute of the datatype
00715      * @param int $version Version of the attribute to be stored
00716      */
00717     function preStoreVersionedClassAttribute( $classAttribute, $version )
00718     {
00719         switch ( $version )
00720         {
00721             case eZContentClass::VERSION_STATUS_DEFINED:
00722                 $this->preStoreDefinedClassAttribute( $classAttribute );
00723                 break;
00724 
00725             case eZContentClass::VERSION_STATUS_MODIFIED:
00726                 $this->preStoreModifiedClassAttribute( $classAttribute );
00727                 break;
00728         }
00729     }
00730 
00731     /*!
00732      Validates the input for a class attribute and returns a validation
00733      state as defined in eZInputValidator.
00734      \note Default implementation does nothing and returns accepted.
00735     */
00736     function validateClassAttributeHTTPInput( $http, $base, $classAttribute )
00737     {
00738         return eZInputValidator::STATE_ACCEPTED;
00739     }
00740 
00741     /*!
00742      Tries to do a fixup on the input text so that it's acceptable as
00743      class attribute input.
00744      \note Default implementation does nothing and returns accepted.
00745     */
00746     function fixupClassAttributeHTTPInput( $http, $base, $classAttribute )
00747     {
00748         return eZInputValidator::STATE_ACCEPTED;
00749     }
00750 
00751     /*!
00752      Fetches the HTTP input for the content class attribute.
00753      \note Default implementation does nothing.
00754     */
00755     function fetchClassAttributeHTTPInput( $http, $base, $classAttribute )
00756     {
00757     }
00758 
00759     /*!
00760      Executes a custom action for a class attribute which was defined on the web page.
00761      \note Default implementation does nothing.
00762     */
00763     function customClassAttributeHTTPAction( $http, $action, $classAttribute )
00764     {
00765     }
00766 
00767     /*!
00768      Matches the action against the action name \a $actionName
00769      and extracts the value from the action puts it into \a $value.
00770      \return \c true if the action matched and a value was found,
00771              \c false otherwise.
00772      \node If no match is made or no value found the \a $value parameter is not modified.
00773     */
00774     function fetchActionValue( $action, $actionName, &$value )
00775     {
00776         if ( preg_match( "#^" . $actionName . "_(.+)$#", $action, $matches ) )
00777         {
00778             $value = $matches[1];
00779             return true;
00780         }
00781         return false;
00782     }
00783 
00784     /*!
00785      Validates the input for an object attribute and returns a validation
00786      state as defined in eZInputValidator.
00787      \note Default implementation does nothing and returns accepted.
00788     */
00789     function validateObjectAttributeHTTPInput( $http, $base, $objectAttribute )
00790     {
00791         return eZInputValidator::STATE_ACCEPTED;
00792     }
00793 
00794     /*!
00795      Tries to do a fixup on the input text so that it's acceptable as
00796      object attribute input.
00797      \note Default implementation does nothing.
00798     */
00799     function fixupObjectAttributeHTTPInput( $http, $base, $objectAttribute )
00800     {
00801     }
00802 
00803     /*!
00804      Fetches the HTTP input for the content object attribute.
00805      \note Default implementation does nothing.
00806     */
00807     function fetchObjectAttributeHTTPInput( $http, $base, $objectAttribute )
00808     {
00809     }
00810 
00811     /*!
00812      Validates the input for an object attribute and returns a validation
00813      state as defined in eZInputValidator.
00814      \note Default implementation does nothing and returns accepted.
00815     */
00816     function validateCollectionAttributeHTTPInput( $http, $base, $objectAttribute )
00817     {
00818         return eZInputValidator::STATE_ACCEPTED;
00819     }
00820 
00821     /*!
00822      Tries to do a fixup on the input text so that it's acceptable as
00823      object attribute input.
00824      \note Default implementation does nothing.
00825     */
00826     function fixupCollectionAttributeHTTPInput( $http, $base, $objectAttribute )
00827     {
00828     }
00829 
00830     /*!
00831      Fetches the HTTP collected information for the content object attribute.
00832      \note Default implementation does nothing.
00833 
00834      \return true if variable was successfully fetched.
00835     */
00836     function fetchCollectionAttributeHTTPInput( $collection, $collectionAttribute, $http, $base, $objectAttribute )
00837     {
00838     }
00839 
00840     /*!
00841      Executes a custom action for an object attribute which was defined on the web page.
00842      \note Default implementation does nothing.
00843     */
00844     function customObjectAttributeHTTPAction( $http, $action, $objectAttribute, $parameters )
00845     {
00846     }
00847 
00848     /*!
00849      Takes care of custom action handling, this means checking if a custom action request
00850      must be sent to a contentobject attribute. This function is only useful for
00851      datatypes that must do custom action handling for sub objects and attributes.
00852      \note Default implementation does nothing.
00853     */
00854     function handleCustomObjectHTTPActions( $http, $attributeDataBaseName,
00855                                             $customActionAttributeArray, $customActionParameters )
00856     {
00857     }
00858 
00859     /*!
00860      Initializes the class attribute with some data.
00861      \note Default implementation does nothing.
00862     */
00863     function initializeClassAttribute( $classAttribute )
00864     {
00865     }
00866 
00867     /*!
00868      Clones the date from the old class attribute to the new one.
00869      \note Default implementation does nothing which is good enough for datatypes which does not use external tables.
00870     */
00871     function cloneClassAttribute( $oldClassAttribute, $newClassAttribute )
00872     {
00873     }
00874 
00875     /*!
00876      Initializes the object attribute with some data.
00877      \note Default implementation does nothing.
00878     */
00879     function initializeObjectAttribute( $objectAttribute, $currentVersion, $originalContentObjectAttribute )
00880     {
00881     }
00882 
00883     /*!
00884      Tries to do a repair on the content object attribute \a $contentObjectAttribute and returns \c true if it succeeds.
00885      \return \c false if it fails or \c null if it is not supported to do a repair.
00886     */
00887     function repairContentObjectAttribute( $contentObjectAttribute )
00888     {
00889         return null;
00890     }
00891 
00892     /*!
00893      Initializes the object attribute with some data after object attribute is already stored. It means that for initial version you allready have an attribute_id and you can store data somewhere using this id.
00894      \note Default implementation does nothing.
00895     */
00896     function postInitializeObjectAttribute( $objectAttribute, $currentVersion, $originalContentObjectAttribute )
00897     {
00898     }
00899 
00900     /*
00901      Makes some post-store operations. Called by framework after store of eZContentObjectAttribute object.
00902     */
00903     function postStore( $objectAttribute )
00904     {
00905     }
00906 
00907     /*!
00908      Do any necessary changes to stored object attribute when moving an object to trash.
00909      \note Default implementation does nothing.
00910     */
00911     function trashStoredObjectAttribute( $objectAttribute, $version = null )
00912     {
00913     }
00914 
00915     /**
00916      * Restores the content object attribute $objectAttribute from trash
00917      * Default implementation does nothing
00918      * @param eZContentObjectAttribute $objectAttribute
00919      */
00920     public function restoreTrashedObjectAttribute( $objectAttribute )
00921     {
00922     }
00923 
00924     /*!
00925      Clean up stored object attribute
00926      \note Default implementation does nothing.
00927     */
00928     function deleteStoredObjectAttribute( $objectAttribute, $version = null )
00929     {
00930     }
00931 
00932     /*!
00933      Clean up stored class attribute
00934      \note Default implementation does nothing.
00935     */
00936     function deleteStoredClassAttribute( $classAttribute, $version = null )
00937     {
00938     }
00939 
00940     /**
00941      * Return content action(s) which can be performed on object containing
00942      * the current datatype. Return format is array of arrays with key 'name'
00943      * and 'action'. 'action' can be mapped to url in datatype.ini
00944      *
00945      * @param eZContentClassAttribute $classAttribute
00946      * @return array
00947     */
00948     function contentActionList( $classAttribute )
00949     {
00950         $actionList = array();
00951         if ( $classAttribute instanceof eZContentClassAttribute )
00952         {
00953             if ( $classAttribute->attribute( 'is_information_collector' ) == true )
00954             {
00955                 $actionList[] = array( 'name' => ezpI18n::tr( 'kernel/classes/datatypes', 'Send', 'Datatype information collector action' ),
00956                                        'action' => 'ActionCollectInformation' );
00957             }
00958         }
00959         else
00960         {
00961             eZDebug::writeError( '$classAttribute isn\'t an object.', __METHOD__ );
00962         }
00963         return $actionList;
00964     }
00965 
00966     /*!
00967      \return true if the data type can do information collection
00968     */
00969     function hasInformationCollection()
00970     {
00971         return false;
00972     }
00973 
00974     /*!
00975      Returns the title of the current type, this is to form
00976      the title of the object.
00977     */
00978     function title( $objectAttribute, $name = null )
00979     {
00980         return "";
00981     }
00982 
00983     /*!
00984      \return true if the datatype can be indexed
00985     */
00986     function isIndexable()
00987     {
00988         return false;
00989     }
00990 
00991     /*!
00992      \return true if the datatype requires validation during add to basket procedure
00993     */
00994     function isAddToBasketValidationRequired()
00995     {
00996         return false;
00997     }
00998     /*!
00999      Validates the input for an object attribute during add to basket process
01000      and returns a validation state as defined in eZInputValidator.
01001      \note Default implementation does nothing and returns accepted.
01002     */
01003     function validateAddToBasket( $objectAttribute, $data, &$errors )
01004     {
01005         return eZInputValidator::STATE_ACCEPTED;
01006     }
01007 
01008     /*!
01009      Queries the datatype if the attribute containing this datatype can be
01010      removed from the class. This can be used by datatypes to ensure
01011      that very important datatypes that could cause system malfunction is
01012      not removed.
01013      The datatype will only need to reimplemented this if it wants to
01014      do some checking, the default returns \c true.
01015 
01016      \return \c true if the class attribute can be removed or \c false.
01017      \sa classAttributeRemovableInformation()
01018      \note The default code will call classAttributeRemovableInformation with
01019           $includeAll set to \c false, if it returns false or an empty \c 'list'
01020           it will return \c true.
01021     */
01022     function isClassAttributeRemovable( $classAttribute )
01023     {
01024         $info = $this->classAttributeRemovableInformation( $classAttribute, false );
01025         return ( $info === false or count( $info['list'] ) == 0 );
01026     }
01027 
01028     /*!
01029      If the call to isClassAttributeRemovable() returns \c false then this
01030      can be called to figure out why it cannot be removed, e.g to give
01031      information to the user.
01032      \return An array structure with information, or \c false if no info is available
01033              - text - Plain text explaining why it can't be removed
01034              - list - A list of reasons with details on why it can be removed
01035                       - identifier - The identifier of the reason (optional)
01036                       - text - Plain text explaning the reason
01037      \param $includeAll Controls whether the returned information will contain all
01038                         sources for not being to remove or just the first that it finds.
01039     */
01040     function classAttributeRemovableInformation( $classAttribute, $includeAll = true )
01041     {
01042         return false;
01043     }
01044 
01045     /*!
01046      \return true if the datatype can be used as an information collector
01047     */
01048     function isInformationCollector()
01049     {
01050         return false;
01051     }
01052 
01053     /*!
01054      \return the sort key for the datatype. This is used for sorting on attribute level.
01055     */
01056     function sortKey( $objectAttribute )
01057     {
01058         return "";
01059     }
01060 
01061     /*!
01062      \returns the type of the sort key int|string
01063       False is returned if sorting is not supported
01064     */
01065     function sortKeyType()
01066     {
01067         return false;
01068     }
01069 
01070     function customSorting()
01071     {
01072         return false;
01073     }
01074 
01075     function customSortingSQL( $params )
01076     {
01077         return false;
01078     }
01079 
01080     /*!
01081      \return the text which should be indexed in the search engine. An associative array can
01082       be returned to enable searching in specific parts of the data. E.g. array( 'first_column' => "foo",
01083      'second_column' => "bar" );
01084     */
01085     function metaData( $contentObjectAttribute )
01086     {
01087         return '';
01088     }
01089     /*!
01090      \return string representation of an contentobjectattribute data for simplified export
01091      */
01092     function toString( $objectAttribute )
01093     {
01094         return '';
01095     }
01096     function fromString( $objectAttribute, $string )
01097     {
01098     }
01099 
01100     /*!
01101      Can be called to figure out if a datatype has certain special templates that it relies on.
01102      This can for instance be used to figure out which override templates to include in a package.
01103      \return An array with template files that this datatype relies on.
01104              Each element can be one of the following types:
01105              - string - The filepath of the template
01106              - array - Advanced matching criteria, element 0 determines the type:
01107                - 'regexp' - A regular expression, element 1 is the regexp string (PREG)
01108              If \c false is returned it means there are no relations to any templates.
01109      \note All matching is done relative from templates directory in the given design.
01110      \note The templates that are found in content/datatype/* should not be included.
01111     */
01112     function templateList()
01113     {
01114         return false;
01115     }
01116 
01117     /*!
01118      Adds the necessary dom structure to the attribute parameters.
01119      \note The default is to add unsupported='true' to the attribute node,
01120            meaning that the datatype does not support serializing.
01121     */
01122     function serializeContentClassAttribute( $classAttribute, $attributeNode, $attributeParametersNode )
01123     {
01124         if ( !$this->Attributes['properties']['serialize_supported'] )
01125             $attributeNode->setAttribute( 'unsupported', 'true' );
01126     }
01127 
01128     /*!
01129      Extracts values from the attribute parameters and sets it in the class attribute.
01130      \note This function is called after the attribute has been stored and a second store is
01131            called after this function is done.
01132     */
01133     function unserializeContentClassAttribute( $classAttribute, $attributeNode, $attributeParametersNode )
01134     {
01135     }
01136 
01137     /*!
01138      \param package
01139      \param objectAttribute content attribute
01140 
01141      \return a DOM representation of the content object attribute
01142     */
01143     function serializeContentObjectAttribute( $package, $objectAttribute )
01144     {
01145         $dom = new DOMDocument( '1.0', 'utf-8' );
01146 
01147         $node = $dom->createElementNS( 'http://ez.no/object/', 'ezobject:attribute' );
01148 
01149         $node->setAttributeNS( 'http://ez.no/ezobject', 'ezremote:id', $objectAttribute->attribute( 'id' ) );
01150         $node->setAttributeNS( 'http://ez.no/ezobject', 'ezremote:identifier', $objectAttribute->contentClassAttributeIdentifier() );
01151         $node->setAttribute( 'name', $objectAttribute->contentClassAttributeName() );
01152         $node->setAttribute( 'type', $this->isA() );
01153 
01154         if ( $this->Attributes["properties"]['object_serialize_map'] )
01155         {
01156             $map = $this->Attributes["properties"]['object_serialize_map'];
01157             foreach ( $map as $attributeName => $xmlName )
01158             {
01159                 if ( $objectAttribute->hasAttribute( $attributeName ) )
01160                 {
01161                     $value = $objectAttribute->attribute( $attributeName );
01162                     unset( $attributeNode );
01163                     $attributeNode = $dom->createElement( $xmlName );
01164                     $attributeNode->appendChild( $dom->createTextNode( (string)$value ) );
01165                     $node->appendChild( $attributeNode );
01166                 }
01167                 else
01168                 {
01169                     eZDebug::writeError( "The attribute '$attributeName' does not exist for contentobject attribute " . $objectAttribute->attribute( 'id' ), __METHOD__ );
01170                 }
01171             }
01172         }
01173         else
01174         {
01175             $dataIntNode = $dom->createElement( 'data-int' );
01176             $dataIntNode->appendChild( $dom->createTextNode( (string)$objectAttribute->attribute( 'data_int' ) ) );
01177             $node->appendChild( $dataIntNode );
01178             $dataFloatNode = $dom->createElement( 'data-float' );
01179             $dataFloatNode->appendChild( $dom->createTextNode( (string)$objectAttribute->attribute( 'data_float' ) ) );
01180             $node->appendChild( $dataFloatNode );
01181             $dataTextNode = $dom->createElement( 'data-text' );
01182             $dataTextNode->appendChild( $dom->createTextNode( $objectAttribute->attribute( 'data_text' ) ) );
01183             $node->appendChild( $dataTextNode );
01184         }
01185         return $node;
01186     }
01187 
01188     /*!
01189      Unserialize contentobject attribute
01190 
01191      \param package
01192      \param objectAttribute contentobject attribute object
01193      \param attributeNode ezdomnode object
01194     */
01195     function unserializeContentObjectAttribute( $package, $objectAttribute, $attributeNode )
01196     {
01197         if ( $this->Attributes["properties"]['object_serialize_map'] )
01198         {
01199             $map = $this->Attributes["properties"]['object_serialize_map'];
01200             foreach ( $map as $attributeName => $xmlName )
01201             {
01202                 if ( $objectAttribute->hasAttribute( $attributeName ) )
01203                 {
01204                     $elements = $attributeNode->getElementsByTagName( $xmlName );
01205                     if ( $elements->length !== 0 )
01206                     {
01207                         $value = $elements->item( 0 )->textContent;
01208                         $objectAttribute->setAttribute( $attributeName, $value );
01209                     }
01210                     else
01211                     {
01212                         eZDebug::writeError( "The xml element '$xmlName' does not exist for contentobject attribute " . $objectAttribute->attribute( 'id' ), __METHOD__ );
01213                     }
01214                 }
01215                 else
01216                 {
01217                     eZDebug::writeError( "The attribute '$attributeName' does not exist for contentobject attribute " . $objectAttribute->attribute( 'id' ), __METHOD__ );
01218                 }
01219             }
01220         }
01221         else
01222         {
01223             $objectAttribute->setAttribute( 'data_int', (int)$attributeNode->getElementsByTagName( 'data-int' )->item( 0 )->textContent );
01224             $objectAttribute->setAttribute( 'data_float', (float)$attributeNode->getElementsByTagName( 'data-float' )->item( 0 )->textContent );
01225             $objectAttribute->setAttribute( 'data_text', $attributeNode->getElementsByTagName( 'data-text' )->item( 0 )->textContent );
01226         }
01227     }
01228 
01229     /*
01230         Post unserialize. Called after all related objects are created.
01231         \return true means that attribute has been modified and should be stored
01232     */
01233     function postUnserializeContentObjectAttribute( $package, $objectAttribute )
01234     {
01235         return false;
01236     }
01237 
01238     static function allowedTypes()
01239     {
01240         $allowedTypes =& $GLOBALS["eZDataTypeAllowedTypes"];
01241         if ( !is_array( $allowedTypes ) )
01242         {
01243             $contentINI = eZINI::instance( 'content.ini' );
01244             $dataTypes = $contentINI->variable( 'DataTypeSettings', 'AvailableDataTypes' );
01245             $allowedTypes = array_unique( $dataTypes );
01246         }
01247         return $allowedTypes;
01248     }
01249 
01250     static function loadAndRegisterAllTypes()
01251     {
01252         $allowedTypes = eZDataType::allowedTypes();
01253         foreach( $allowedTypes as $type )
01254         {
01255             eZDataType::loadAndRegisterType( $type );
01256         }
01257     }
01258 
01259     static function loadAndRegisterType( $type )
01260     {
01261         $types =& $GLOBALS["eZDataTypes"];
01262         if ( isset( $types[$type] ) )
01263         {
01264             return false;
01265         }
01266 
01267         $baseDirectory = eZExtension::baseDirectory();
01268         $contentINI = eZINI::instance( 'content.ini' );
01269 
01270         $extensionDirectories = $contentINI->variable( 'DataTypeSettings', 'ExtensionDirectories' );
01271         $extensionDirectories = array_unique( $extensionDirectories );
01272         $repositoryDirectories = $contentINI->variable( 'DataTypeSettings', 'RepositoryDirectories' );
01273         $triedDirectories = $repositoryDirectories;
01274 
01275         foreach ( $extensionDirectories as $extensionDirectory )
01276         {
01277             $extensionPath = $baseDirectory . '/' . $extensionDirectory . '/datatypes';
01278             $triedDirectories[] = $extensionPath;
01279             if ( file_exists( $extensionPath ) )
01280             {
01281                 $repositoryDirectories[] = $extensionPath;
01282             }
01283             else
01284             {
01285                 eZDebug::writeWarning( "Extension '$extensionDirectory' does not have the subdirectory 'datatypes'\n" .
01286                                        "Looked for directory '" . $extensionPath . "'\n" .
01287                                        "Cannot look for datatype '$type' in this extension." );
01288             }
01289         }
01290         $foundEventType = false;
01291         $repositoryDirectories = array_unique( $repositoryDirectories );
01292         foreach ( $repositoryDirectories as $repositoryDirectory )
01293         {
01294             $includeFile = "$repositoryDirectory/$type/" . $type . "type.php";
01295             if ( file_exists( $includeFile ) )
01296             {
01297                 $foundEventType = true;
01298                 break;
01299             }
01300         }
01301         if ( !$foundEventType )
01302         {
01303             eZDebug::writeError( "Datatype not found: '$type', searched in these directories: " . implode( ', ', $triedDirectories ), __METHOD__ );
01304             return false;
01305         }
01306         include_once( $includeFile );
01307         return true;
01308     }
01309 
01310     /*!
01311      Removes objects with given ID from the relations list
01312      \note Default implementation does nothing.
01313     */
01314     function removeRelatedObjectItem( $contentObjectAttribute, $objectID )
01315     {
01316     }
01317 
01318     /*!
01319     Fixes objects with given ID in the relations list according to what is done with object
01320      \note Default implementation does nothing.
01321     */
01322     function fixRelatedObjectItem( $contentObjectAttribute, $objectID, $mode )
01323     {
01324     }
01325     /**
01326      * Create empty content object attribute DOM node.
01327      *
01328      * The result is intended to be used in a datatype's
01329      * serializeContentObjectAttribute() method.
01330      *
01331      * \return "Empty" DOM node
01332      */
01333     function createContentObjectAttributeDOMNode( $objectAttribute )
01334     {
01335         $dom = new DOMDocument( '1.0', 'utf-8' );
01336 
01337         $node = $dom->createElementNS( 'http://ez.no/object/', 'ezobject:attribute' );
01338 
01339         $node->setAttributeNS( 'http://ez.no/ezobject', 'ezremote:id', $objectAttribute->attribute( 'id' ) );
01340         $node->setAttributeNS( 'http://ez.no/ezobject', 'ezremote:identifier', $objectAttribute->contentClassAttributeIdentifier() );
01341         $node->setAttribute( 'name', $objectAttribute->contentClassAttributeName() );
01342         $node->setAttribute( 'type', $this->isA() );
01343 
01344         return $node;
01345     }
01346 
01347     /*!
01348       Method used by content diff system to retrieve changes in attributes.
01349       This method implements the default behaviour, which is to show old and
01350       new version values of the object.
01351     */
01352     function diff( $old, $new, $options = false )
01353     {
01354         $diff = new eZDiff();
01355         $diff->setDiffEngineType( $diff->engineType( 'container' ) );
01356         $diff->initDiffEngine();
01357         $diffObject = $diff->diff( $old, $new );
01358         return $diffObject;
01359     }
01360 
01361     /*!
01362       Returns dba-data file name of the specific datatype.
01363       This one is the default dba-data file name for all datatypes
01364     */
01365     function getDBAFileName()
01366     {
01367         return 'share/db_data.dba';
01368     }
01369 
01370     /*!
01371       Returns dba-data file path (relative to the system root folder) for the specific datatype.
01372     */
01373     function getDBAFilePath( $checkExtensions = true )
01374     {
01375          $fileName = 'kernel/classes/datatypes/' . $this->DataTypeString . '/' . $this->getDBAFileName();
01376          if ( $checkExtensions === true && !file_exists( $fileName ) )
01377          {
01378              $fileName = $this->getDBAExtensionFilePath();
01379          }
01380          return $fileName;
01381     }
01382 
01383     /*!
01384       Returns dba-data file extension path (relative to the system root folder) for the specific datatype.
01385       \return the first path that is found for the datatype. If not found, it will return false.
01386     */
01387     function getDBAExtensionFilePath()
01388     {
01389         $activeExtensions = eZExtension::activeExtensions();
01390         $dataTypeString = $this->DataTypeString;
01391         $dbaFileName = $this->getDBAFileName();
01392         $fileName = false;
01393         foreach ( $activeExtensions as $activeExtension )
01394         {
01395             $extesionFileName = eZExtension::baseDirectory() . '/' . $activeExtension .
01396                                 '/datatypes/' . $dataTypeString . '/' . $dbaFileName;
01397             if ( file_exists( $extesionFileName ) )
01398             {
01399                 $fileName = $extesionFileName;
01400                 break;
01401             }
01402         }
01403         return $fileName;
01404     }
01405 
01406     /*!
01407       Used by setup-wizard to update database data using per datatype dba file
01408       which is usually placed in share subfolder of the datatype and (share/db_data.dba)
01409       Any reimplementation of this method must return true if import is succesfully done,
01410       otherwise false.
01411     */
01412     function importDBDataFromDBAFile( $dbaFilePath = false )
01413     {
01414         // If no file path is passed then get the common dba-data file name for the datatype
01415         if ( $dbaFilePath === false )
01416             $dbaFilePath = $this->getDBAFilePath();
01417 
01418         $fileExist = true;
01419         if ( !file_exists( $dbaFilePath ) )
01420         {
01421             $fileExist = false;
01422         }
01423         $result = true;
01424         if ( $fileExist === true )
01425         {
01426             $dataArray = eZDbSchema::read( $dbaFilePath, true );
01427             if ( is_array( $dataArray ) and count( $dataArray ) > 0 )
01428             {
01429                 $db = eZDB::instance();
01430                 $dataArray['type'] = strtolower( $db->databaseName() );
01431                 $dataArray['instance'] =& $db;
01432                 $dbSchema = eZDbSchema::instance( $dataArray );
01433 
01434                 $result = false;
01435                 if ( $dbSchema )
01436                 {
01437                     // Before adding the schema, make sure that the tables are empty.
01438                     if ( $this->cleanDBDataBeforeImport() )
01439                     {
01440                         // This will insert the data and
01441                         // run any sequence value correction SQL if required
01442                         $result = $dbSchema->insertSchema( array( 'schema' => false,
01443                                                                   'data' => true ) );
01444                     }
01445                 }
01446             }
01447         }
01448         else
01449         {
01450             $result = false;
01451         }
01452         return $result;
01453     }
01454 
01455     /*!
01456       \private
01457       Used by updateDBDataByDBAFile() method
01458       Must return true if successfull, or false otherwise.
01459     */
01460     function cleanDBDataBeforeImport()
01461     {
01462         return true;
01463     }
01464 
01465     function batchInitializeObjectAttributeData( $classAttribute )
01466     {
01467         return array();
01468     }
01469 
01470     function supportsBatchInitializeObjectAttribute()
01471     {
01472         return false;
01473     }
01474 
01475     /// \privatesection
01476     /// The datatype string ID, used for uniquely identifying a datatype
01477     public $DataTypeString;
01478     /// The descriptive name of the datatype, usually used for displaying to the user
01479     public $Name;
01480 }
01481 
01482 ?>