eZ Publish  [4.0]
ezidentifiertype.php
Go to the documentation of this file.
00001 <?php
00002 //
00003 // Definition of eZIdentifierType class
00004 //
00005 // Created on: <28-Aug-2003 11:43:09 br>
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 ezidentifiertype.php
00032 */
00033 
00034 /*!
00035   \class eZIdentifierType ezidentifiertype.php
00036   \ingroup eZDatatype
00037   \brief The class eZIdentifierType does
00038 
00039 */
00040 
00041 //include_once( "kernel/classes/ezdatatype.php" );
00042 //include_once( "lib/ezutils/classes/ezintegervalidator.php" );
00043 
00044 class eZIdentifierType extends eZDataType
00045 {
00046     const PRETEXT_FIELD = "data_text1";
00047     const PRETEXT_VARIABLE = "_ezidentifier_pretext_value_";
00048 
00049     const POSTTEXT_FIELD = "data_text2";
00050     const POSTTEXT_VARIABLE = "_ezidentifier_posttext_value_";
00051 
00052     const START_VALUE_FIELD = "data_int1";
00053     const START_VALUE_VARIABLE = "_ezidentifier_start_integer_value_";
00054 
00055     const DIGITS_FIELD = "data_int2";
00056     const DIGITS_VARIABLE = "_ezidentifier_digits_integer_value_";
00057 
00058     const IDENTIFIER_FIELD = "data_int3";
00059     const IDENTIFIER_VARIABLE = "_ezidentifier_identifier_value_";
00060 
00061     const DATA_TYPE_STRING = "ezidentifier";
00062 
00063     /*!
00064      Constructor
00065     */
00066     function eZIdentifierType()
00067     {
00068         $this->eZDataType( self::DATA_TYPE_STRING,
00069                            ezi18n( 'kernel/classes/datatypes', "Identifier", 'Datatype name' ),
00070                            array( 'serialize_supported' => true,
00071                                   'object_serialize_map' => array( 'data_text' => 'identifier',
00072                                                                    'data_int' => 'number' ) ) );
00073         $this->IntegerValidator = new eZIntegerValidator( 1 );
00074     }
00075 
00076     /*!
00077      Validates the input and returns true if the input was
00078      valid for this datatype.
00079     */
00080     function validateObjectAttributeHTTPInput( $http, $base, $contentObjectAttribute )
00081     {
00082     }
00083 
00084     function fetchObjectAttributeHTTPInput( $http, $base, $contentObjectAttribute )
00085     {
00086     }
00087 
00088     /*!
00089      Store the content. Since the content has been stored in function fetchObjectAttributeHTTPInput(),
00090      this function is with empty code.
00091     */
00092     function storeObjectAttribute( $contentObjectattribute )
00093     {
00094     }
00095 
00096     /*!
00097      Returns the content.
00098     */
00099     function objectAttributeContent( $contentObjectAttribute )
00100     {
00101         $content = $contentObjectAttribute->attribute( "data_text" );
00102         if ( trim( $content ) == '' )
00103         {
00104             $contentClassAttribute = $contentObjectAttribute->contentClassAttribute();
00105             $content = eZIdentifierType::generateIdentifierString( $contentClassAttribute, false );
00106         }
00107         return $content;
00108     }
00109 
00110     function toString( $contentObjectAttribute )
00111     {
00112         return $contentObjectAttribute->attribute( 'data_text' );
00113     }
00114 
00115 
00116     function fromString( $contentObjectAttribute, $string )
00117     {
00118         if ( $string == '' )
00119             return true;
00120         $contentObjectAttribute->setAttribute( 'data_text', $string );
00121         return true;
00122     }
00123     function hasObjectAttributeContent( $contentObjectAttribute )
00124     {
00125         $content = $contentObjectAttribute->attribute( "data_text" );
00126         return ( trim( $content ) != '' );
00127     }
00128 
00129     function initializeClassAttribute( $classAttribute )
00130     {
00131         if ( $classAttribute->attribute( self::START_VALUE_FIELD ) == null
00132           && $classAttribute->attribute( self::DIGITS_FIELD ) == null
00133           && $classAttribute->attribute( self::IDENTIFIER_FIELD ) == null )
00134         {
00135             $classAttribute->setAttribute( self::START_VALUE_FIELD, 1 );
00136             $classAttribute->setAttribute( self::IDENTIFIER_FIELD, 1 );
00137             $classAttribute->setAttribute( self::DIGITS_FIELD, 1 );
00138         }
00139     }
00140 
00141     /*!
00142       Validates the input and returns true if the input was
00143       valid for this datatype.
00144     */
00145     function validateClassAttributeHTTPInput( $http, $base, $classAttribute )
00146     {
00147         $startValueName = $base . self::START_VALUE_VARIABLE . $classAttribute->attribute( "id" );
00148         $digitsName = $base . self::DIGITS_VARIABLE . $classAttribute->attribute( "id" );
00149 
00150         if ( $http->hasPostVariable( $startValueName ) and
00151              $http->hasPostVariable( $digitsName ) )
00152         {
00153             $startValueValue = str_replace( " ", "", $http->postVariable( $startValueName ) );
00154             $digitsValue = str_replace( " ", "", $http->postVariable( $digitsName ) );
00155 
00156             $startValueValueState = $this->IntegerValidator->validate( $startValueValue );
00157             $digitsValueState = $this->IntegerValidator->validate( $digitsValue );
00158 
00159             if ( ( $startValueValueState == eZInputValidator::STATE_ACCEPTED ) and
00160                  ( $digitsValueState == eZInputValidator::STATE_ACCEPTED ) )
00161             {
00162                 return eZInputValidator::STATE_ACCEPTED;
00163             }
00164             return eZInputValidator::STATE_INTERMEDIATE;
00165         }
00166         return eZInputValidator::STATE_INVALID;
00167     }
00168 
00169     /*!
00170      \reimp
00171     */
00172     function fetchClassAttributeHTTPInput( $http, $base, $classAttribute )
00173     {
00174         $startValueName = $base . self::START_VALUE_VARIABLE . $classAttribute->attribute( "id" );
00175         $digitsName = $base . self::DIGITS_VARIABLE . $classAttribute->attribute( "id" );
00176         $preTextName = $base . self::PRETEXT_VARIABLE . $classAttribute->attribute( "id" );
00177         $postTextName = $base . self::POSTTEXT_VARIABLE . $classAttribute->attribute( "id" );
00178 
00179         if ( $http->hasPostVariable( $startValueName ) and
00180              $http->hasPostVariable( $digitsName ) and
00181              $http->hasPostVariable( $preTextName ) and
00182              $http->hasPostVariable( $postTextName ) )
00183         {
00184             $startValueValue = str_replace( " ", "", $http->postVariable( $startValueName ) );
00185             $startValueValue = ( int ) $startValueValue;
00186             if ( $startValueValue < 1 )
00187             {
00188                 $startValueValue = 1;
00189             }
00190             $digitsValue = str_replace( " ", "", $http->postVariable( $digitsName ) );
00191             $digitsValue = ( int ) $digitsValue;
00192             if ( $digitsValue < 1 )
00193             {
00194                 $digitsValue = 1;
00195             }
00196 
00197             $preTextValue =  $http->postVariable( $preTextName );
00198             $postTextValue = $http->postVariable( $postTextName );
00199 
00200             $classAttribute->setAttribute( self::DIGITS_FIELD, $digitsValue );
00201             $classAttribute->setAttribute( self::PRETEXT_FIELD, $preTextValue );
00202             $classAttribute->setAttribute( self::POSTTEXT_FIELD, $postTextValue );
00203 
00204             $classAttribute->setAttribute( self::START_VALUE_FIELD, $startValueValue );
00205             $classAttribute->setAttribute( self::IDENTIFIER_FIELD,
00206                                            $classAttribute->attribute( self::START_VALUE_FIELD ) );
00207 
00208             $originalClassAttribute = eZContentClassAttribute::fetch( $classAttribute->attribute( 'id' ), true, 0 );
00209             if ( $originalClassAttribute )
00210             {
00211                 if ( $originalClassAttribute->attribute( self::DIGITS_FIELD ) == $digitsValue
00212                   && $originalClassAttribute->attribute( self::PRETEXT_FIELD ) == $preTextValue
00213                   && $originalClassAttribute->attribute( self::POSTTEXT_FIELD ) == $postTextValue
00214                   && $originalClassAttribute->attribute( self::IDENTIFIER_FIELD ) >= $startValueValue )
00215                 {
00216                     $classAttribute->setAttribute( self::START_VALUE_FIELD, $originalClassAttribute->attribute( self::START_VALUE_FIELD ) );
00217                     $classAttribute->setAttribute( self::IDENTIFIER_FIELD, $originalClassAttribute->attribute( self::IDENTIFIER_FIELD ) );
00218                 }
00219             }
00220         }
00221         return true;
00222     }
00223 
00224     /*!
00225      Returns the meta data used for storing search indices.
00226     */
00227     function metaData( $contentObjectAttribute )
00228     {
00229         return $contentObjectAttribute->attribute( "data_text" );
00230     }
00231 
00232     /*!
00233      Returns the text.
00234     */
00235     function title( $contentObjectAttribute, $name = null )
00236     {
00237         return  $contentObjectAttribute->attribute( "data_text" );
00238     }
00239 
00240     /*!
00241      \reimp
00242     */
00243     function isIndexable()
00244     {
00245         return true;
00246     }
00247 
00248 
00249     /*!
00250      \reimp
00251     */
00252     function initializeObjectAttribute( $contentObjectAttribute, $currentVersion, $originalContentObjectAttribute )
00253     {
00254         $contentObjectAttributeID = $originalContentObjectAttribute->attribute( "id" );
00255         $version = $contentObjectAttribute->attribute( "version" );
00256         if ( $currentVersion == false )
00257         {
00258             // If this is not a copy we need to see if a unique ID must be
00259             // assigned. This is handled in assignValue().
00260             $contentClassAttribute = $contentObjectAttribute->attribute( 'contentclass_attribute' );
00261             $ret = eZIdentifierType::assignValue( $contentClassAttribute, $contentObjectAttribute );
00262         }
00263     }
00264 
00265     /*!
00266       When published it will check if it needs to aquire a new unique identifier, if so
00267       it updates all existing versions with this new identifier.
00268     */
00269     function onPublish( $contentObjectAttribute, $contentObject, $publishedNodes )
00270     {
00271         $contentClassAttribute = $contentObjectAttribute->attribute( 'contentclass_attribute' );
00272         $ret = eZIdentifierType::assignValue( $contentClassAttribute, $contentObjectAttribute );
00273 
00274         return $ret;
00275     }
00276 
00277     /*!
00278       \private
00279       Assigns the identifiervalue for the first version of the current attribute.
00280     */
00281     function assignValue( $contentClassAttribute, $contentObjectAttribute )
00282     {
00283 
00284         $retValue = false;
00285         $ret = array();
00286         $version = $contentObjectAttribute->attribute( 'version' );
00287         $contentClassAttributeID = $contentClassAttribute->attribute( 'id' );
00288         $objectID = (int)$contentObjectAttribute->attribute( 'contentobject_id' );
00289         $classAttributeID = (int)$contentObjectAttribute->attribute( 'contentclassattribute_id' );
00290 
00291         $db = eZDB::instance();
00292 
00293         $existingIDs = $db->arrayQuery( "SELECT data_int\n" .
00294                                         "FROM   ezcontentobject_attribute\n" .
00295                                         "WHERE  contentobject_id = $objectID AND\n" .
00296                                         "       contentclassattribute_id = $classAttributeID AND\n" .
00297                                         "       data_type_string = 'ezidentifier' AND\n" .
00298                                         "       data_int != 0" );
00299         if ( count( $existingIDs ) > 0 )
00300         {
00301             $identifierValue = $existingIDs[0]['data_int'];
00302             $ret[] = eZIdentifierType::storeIdentifierValue( $contentClassAttribute, $contentObjectAttribute, $identifierValue );
00303         }
00304         else
00305         {
00306             $db->begin();
00307 
00308             // Ensure that we don't get another identifier with the same id, so lock ezcontentclass_attribute
00309             $db->lock( array( array( 'table' => 'ezcontentclass_attribute' ) ) );
00310 
00311             $selectQuery = "SELECT data_int3 FROM ezcontentclass_attribute WHERE " .
00312                  "id=$contentClassAttributeID AND version=0";
00313             $result = $db->arrayQuery( $selectQuery );
00314             $identifierValue = $result[0]['data_int3'];
00315 
00316             // should only increment when we don't have the first version
00317             $updateQuery = "UPDATE ezcontentclass_attribute SET data_int3=data_int3 + 1 WHERE " .
00318                   "id=$contentClassAttributeID AND version=0";
00319 
00320             $ret[] = $db->query( $updateQuery );
00321             
00322             $db->unlock();
00323             // unlock before we start to update the ezcontentobject_attribute table
00324             
00325             $ret[] = eZIdentifierType::storeIdentifierValue( $contentClassAttribute, $contentObjectAttribute, $identifierValue );
00326 
00327             if ( !in_array( false, $ret ) )
00328             {
00329                 // Now make sure all existing versions (if any) gets the same identifier
00330                 $dataText = $db->escapeString( $contentObjectAttribute->attribute( 'data_text' ) );
00331                 $dataInt = (int)$contentObjectAttribute->attribute( 'data_int' );
00332 
00333                 //include_once( 'lib/ezi18n/classes/ezchartransform.php' );
00334                 $trans = eZCharTransform::instance();
00335                 $sortText = $db->escapeString( $trans->transformByGroup( $contentObjectAttribute->attribute( 'data_text' ),
00336                                                                          'lowercase' ) );
00337 
00338                 $db->query( "UPDATE ezcontentobject_attribute\n" .
00339                             "SET    data_text = '$dataText', data_int = $dataInt, sort_key_string = '$sortText'\n" .
00340                             "WHERE  contentobject_id = $objectID AND\n" .
00341                             "       contentclassattribute_id = $classAttributeID AND\n" .
00342                             "       data_type_string = 'ezidentifier'" );
00343             }
00344 
00345             if ( !in_array( false, $ret ) )
00346                 $db->commit();
00347             else
00348                 $db->rollback();
00349         }
00350 
00351         if ( !in_array( false, $ret ) )
00352             $retValue = true;
00353 
00354         return $retValue;
00355     }
00356 
00357     /*!
00358      \reimp
00359     */
00360     function sortKey( $contentObjectAttribute )
00361     {
00362         //include_once( 'lib/ezi18n/classes/ezchartransform.php' );
00363         $trans = eZCharTransform::instance();
00364         return $trans->transformByGroup( $contentObjectAttribute->attribute( 'data_text' ), 'lowercase' );
00365     }
00366 
00367     /*!
00368     \reimp
00369     */
00370     function sortKeyType()
00371     {
00372         return 'string';
00373     }
00374 
00375     /*!
00376       \private
00377       Store the new value to the attribute.
00378     */
00379     function storeIdentifierValue( $contentClassAttribute, $contentObjectAttribute, $identifierValue )
00380     {
00381         $value = eZIdentifierType::generateIdentifierString( $contentClassAttribute, $identifierValue );
00382         $contentObjectAttribute->setAttribute( 'data_text', $value );
00383         $contentObjectAttribute->setAttribute( 'data_int', $identifierValue );
00384         return true;
00385     }
00386 
00387     function generateIdentifierString( $contentClassAttribute, $identifierValue = false )
00388     {
00389         $preText = $contentClassAttribute->attribute( self::PRETEXT_FIELD );
00390         $postText = $contentClassAttribute->attribute( self::POSTTEXT_FIELD );
00391         $digits = $contentClassAttribute->attribute( self::DIGITS_FIELD );
00392 
00393         if ( $identifierValue !== false )
00394             $midText = str_pad( $identifierValue, $digits, '0', STR_PAD_LEFT );
00395         else
00396             $midText = str_repeat( 'x', $digits );
00397 
00398         $value = $preText . $midText . $postText;
00399         return $value;
00400     }
00401 
00402     function customClassAttributeHTTPAction( $http, $action, $contentClassAttribute )
00403     {
00404     }
00405 
00406     function preStoreClassAttribute( $classAttribute, $version )
00407     {
00408     }
00409 
00410     function preStoreDefinedClassAttribute( $classAttribute )
00411     {
00412     }
00413 
00414     /*!
00415      \reimp
00416     */
00417     function serializeContentClassAttribute( $classAttribute, $attributeNode, $attributeParametersNode )
00418     {
00419         $digits     = $classAttribute->attribute( self::DIGITS_FIELD );
00420         $preText    = $classAttribute->attribute( self::PRETEXT_FIELD );
00421         $postText   = $classAttribute->attribute( self::POSTTEXT_FIELD );
00422         $startValue = $classAttribute->attribute( self::START_VALUE_FIELD );
00423         $identifier = $classAttribute->attribute( self::IDENTIFIER_FIELD );
00424 
00425         $dom = $attributeParametersNode->ownerDocument;
00426 
00427         $digitsNode = $dom->createElement( 'digits' );
00428         $digitsNode->appendChild( $dom->createTextNode( $digits ) );
00429         $attributeParametersNode->appendChild( $digitsNode );
00430         $preTextNode = $dom->createElement( 'pre-text' );
00431         $preTextNode->appendChild( $dom->createTextNode( $preText ) );
00432         $attributeParametersNode->appendChild( $preTextNode );
00433         $postTextNode = $dom->createElement( 'post-text' );
00434         $postTextNode->appendChild( $dom->createTextNode( $postText ) );
00435         $attributeParametersNode->appendChild( $postTextNode );
00436         $startValueNode = $dom->createElement( 'start-value' );
00437         $startValueNode->appendChild( $dom->createTextNode( $startValue ) );
00438         $attributeParametersNode->appendChild( $startValueNode );
00439         $identifierNode = $dom->createElement( 'identifier' );
00440         $identifierNode->appendChild( $dom->createTextNode( $identifier ) );
00441         $attributeParametersNode->appendChild( $identifierNode );
00442     }
00443 
00444     /*!
00445      \reimp
00446     */
00447     function unserializeContentClassAttribute( $classAttribute, $attributeNode, $attributeParametersNode )
00448     {
00449         $digits     = $attributeParametersNode->getElementsByTagName( 'digits' )->item( 0 )->textContent;
00450         $preText    = $attributeParametersNode->getElementsByTagName( 'pre-text' )->item( 0 )->textContent;
00451         $postText   = $attributeParametersNode->getElementsByTagName( 'post-text' )->item( 0 )->textContent;
00452         $startValue = $attributeParametersNode->getElementsByTagName( 'start-value' )->item( 0 )->textContent;
00453         $identifier = $attributeParametersNode->getElementsByTagName( 'identifier' )->item( 0 )->textContent;
00454 
00455         if ( $digits !== false )
00456             $classAttribute->setAttribute( self::DIGITS_FIELD,      $digits );
00457 
00458         if ( $preText !== false )
00459             $classAttribute->setAttribute( self::PRETEXT_FIELD,     $preText );
00460 
00461         if ( $postText !== false )
00462             $classAttribute->setAttribute( self::POSTTEXT_FIELD,    $postText );
00463 
00464         if ( $startValue !== false )
00465             $classAttribute->setAttribute( self::START_VALUE_FIELD, $startValue );
00466 
00467         if ( $identifier !== false )
00468             $classAttribute->setAttribute( self::IDENTIFIER_FIELD,  $identifier );
00469     }
00470 
00471     public $IntegerValidator;
00472 }
00473 
00474 eZDataType::register( eZIdentifierType::DATA_TYPE_STRING, "ezidentifiertype" );
00475 
00476 ?>