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