- Implemented enhancement #14133: Batch initialization of object attributes
[tinyz:tinyz.git] / kernel / classes / datatypes / ezinteger / ezintegertype.php
1 <?php
2 //
3 // Definition of eZIntegerType class
4 //
5 // ## BEGIN COPYRIGHT, LICENSE AND WARRANTY NOTICE ##
6 // SOFTWARE NAME: eZ Publish
7 // SOFTWARE RELEASE: 4.1.x
8 // COPYRIGHT NOTICE: Copyright (C) 1999-2008 eZ Systems AS
9 // SOFTWARE LICENSE: GNU General Public License v2.0
10 // NOTICE: >
11 //   This program is free software; you can redistribute it and/or
12 //   modify it under the terms of version 2.0  of the GNU General
13 //   Public License as published by the Free Software Foundation.
14 //
15 //   This program is distributed in the hope that it will be useful,
16 //   but WITHOUT ANY WARRANTY; without even the implied warranty of
17 //   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18 //   GNU General Public License for more details.
19 //
20 //   You should have received a copy of version 2.0 of the GNU General
21 //   Public License along with this program; if not, write to the Free
22 //   Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
23 //   MA 02110-1301, USA.
24 //
25 //
26 // ## END COPYRIGHT, LICENSE AND WARRANTY NOTICE ##
27 //
28
29 /*!
30   \class eZIntegerType ezintegertype.php
31   \ingroup eZDatatype
32   \brief A content datatype which handles integers
33
34   It provides the functionality to work as an integer and handles
35   class definition input, object definition input and object viewing.
36
37   It uses the spare field data_int in a content object attribute for storing
38   the attribute data.
39 */
40
41 class eZIntegerType extends eZDataType
42 {
43     const DATA_TYPE_STRING = "ezinteger";
44     const MIN_VALUE_FIELD = "data_int1";
45     const MIN_VALUE_VARIABLE = "_ezinteger_min_integer_value_";
46     const MAX_VALUE_FIELD = "data_int2";
47     const MAX_VALUE_VARIABLE = "_ezinteger_max_integer_value_";
48     const DEFAULT_VALUE_FIELD = "data_int3";
49     const DEFAULT_VALUE_VARIABLE = "_ezinteger_default_value_";
50     const INPUT_STATE_FIELD = "data_int4";
51     const NO_MIN_MAX_VALUE = 0;
52     const HAS_MIN_VALUE = 1;
53     const HAS_MAX_VALUE = 2;
54     const HAS_MIN_MAX_VALUE = 3;
55
56     function eZIntegerType()
57     {
58         $this->eZDataType( self::DATA_TYPE_STRING, ezi18n( 'kernel/classes/datatypes', "Integer", 'Datatype name' ),
59                            array( 'serialize_supported' => true,
60                                   'object_serialize_map' => array( 'data_int' => 'value' ) ) );
61         $this->IntegerValidator = new eZIntegerValidator();
62     }
63
64     /*!
65      Private method, only for using inside this class.
66     */
67     function validateIntegerHTTPInput( $data, $contentObjectAttribute, $classAttribute )
68     {
69         $min = $classAttribute->attribute( self::MIN_VALUE_FIELD );
70         $max = $classAttribute->attribute( self::MAX_VALUE_FIELD );
71         $input_state = $classAttribute->attribute( self::INPUT_STATE_FIELD );
72
73         switch( $input_state )
74         {
75             case self::NO_MIN_MAX_VALUE:
76             {
77                 $this->IntegerValidator->setRange( false, false );
78                 $state = $this->IntegerValidator->validate( $data );
79                 if( $state === eZInputValidator::STATE_INVALID || $state === eZInputValidator::STATE_INTERMEDIATE )
80                     $contentObjectAttribute->setValidationError( ezi18n( 'kernel/classes/datatypes',
81                                                                          'The input is not a valid integer.' ) );
82                 else
83                     return $state;
84             } break;
85             case self::HAS_MIN_VALUE:
86             {
87                 $this->IntegerValidator->setRange( $min, false );
88                 $state = $this->IntegerValidator->validate( $data );
89                 if( $state === eZInputValidator::STATE_ACCEPTED )
90                     return eZInputValidator::STATE_ACCEPTED;
91                 else
92                     $contentObjectAttribute->setValidationError( ezi18n( 'kernel/classes/datatypes',
93                                                                          'The number must be greater than %1' ),
94                                                                  $min );
95             } break;
96             case self::HAS_MAX_VALUE:
97             {
98                 $this->IntegerValidator->setRange( false, $max );
99                 $state = $this->IntegerValidator->validate( $data );
100                 if( $state===1 )
101                     return eZInputValidator::STATE_ACCEPTED;
102                 else
103                     $contentObjectAttribute->setValidationError( ezi18n( 'kernel/classes/datatypes',
104                                                                          'The number must be less than %1' ),
105                                                                  $max );
106             } break;
107             case self::HAS_MIN_MAX_VALUE:
108             {
109                 $this->IntegerValidator->setRange( $min, $max );
110                 $state = $this->IntegerValidator->validate( $data );
111                 if( $state===1 )
112                     return eZInputValidator::STATE_ACCEPTED;
113                 else
114                     $contentObjectAttribute->setValidationError( ezi18n( 'kernel/classes/datatypes',
115                                                                          'The number is not within the required range %1 - %2' ),
116                                                                  $min, $max );
117             } break;
118         }
119
120         return eZInputValidator::STATE_INVALID;
121
122     }
123
124     /*!
125      Validates the input and returns true if the input was
126      valid for this datatype.
127     */
128     function validateObjectAttributeHTTPInput( $http, $base, $contentObjectAttribute )
129     {
130         if ( $http->hasPostVariable( $base . "_data_integer_" . $contentObjectAttribute->attribute( "id" ) ) )
131         {
132             $data = $http->postVariable( $base . "_data_integer_" . $contentObjectAttribute->attribute( "id" ) );
133             $data = str_replace(" ", "", $data );
134             $classAttribute = $contentObjectAttribute->contentClassAttribute();
135
136             if ( $data == "" )
137             {
138                 if ( !$classAttribute->attribute( 'is_information_collector' ) and
139                      $contentObjectAttribute->validateIsRequired() )
140                 {
141                     $contentObjectAttribute->setValidationError( ezi18n( 'kernel/classes/datatypes',
142                                                                          'Input required.' ) );
143                     return eZInputValidator::STATE_INVALID;
144                 }
145                 else
146                     return eZInputValidator::STATE_ACCEPTED;
147             }
148             else
149             {
150                 return $this->validateIntegerHTTPInput( $data, $contentObjectAttribute, $classAttribute );
151             }
152         }
153         else
154             return eZInputValidator::STATE_ACCEPTED;
155     }
156
157     function fixupObjectAttributeHTTPInput( $http, $base, $contentObjectAttribute )
158     {
159     }
160
161     /*!
162      Sets the default value.
163     */
164     function initializeObjectAttribute( $contentObjectAttribute, $currentVersion, $originalContentObjectAttribute )
165     {
166         if ( $currentVersion != false )
167         {
168 //             $contentObjectAttributeID = $contentObjectAttribute->attribute( "id" );
169 //             $currentObjectAttribute = eZContentObjectAttribute::fetch( $contentObjectAttributeID,
170 //                                                                         $currentVersion );
171             $dataInt = $originalContentObjectAttribute->attribute( "data_int" );
172             $contentObjectAttribute->setAttribute( "data_int", $dataInt );
173         }
174         else
175         {
176             $contentClassAttribute = $contentObjectAttribute->contentClassAttribute();
177             $default = $contentClassAttribute->attribute( "data_int3" );
178             if ( $default !== 0 )
179             {
180                 $contentObjectAttribute->setAttribute( "data_int", $default );
181             }
182         }
183     }
184
185     /*!
186      Fetches the http post var integer input and stores it in the data instance.
187     */
188     function fetchObjectAttributeHTTPInput( $http, $base, $contentObjectAttribute )
189     {
190         if ( $http->hasPostVariable( $base . "_data_integer_" . $contentObjectAttribute->attribute( "id" ) ) )
191         {
192             $data = $http->postVariable( $base . "_data_integer_" . $contentObjectAttribute->attribute( "id" ) );
193             $data = trim( $data ) != '' ? $data : null;
194             $data = str_replace(" ", "", $data);
195             $contentObjectAttribute->setAttribute( "data_int", $data );
196             return true;
197         }
198         return false;
199     }
200
201     /*!
202      \reimp
203     */
204     function validateCollectionAttributeHTTPInput( $http, $base, $contentObjectAttribute )
205     {
206         if ( $http->hasPostVariable( $base . "_data_integer_" . $contentObjectAttribute->attribute( "id" ) ) )
207         {
208             $data = $http->postVariable( $base . "_data_integer_" . $contentObjectAttribute->attribute( "id" ) );
209             $data = str_replace(" ", "", $data );
210             $classAttribute = $contentObjectAttribute->contentClassAttribute();
211
212             if ( $data == "" )
213             {
214                 if ( $contentObjectAttribute->validateIsRequired() )
215                 {
216                     $contentObjectAttribute->setValidationError( ezi18n( 'kernel/classes/datatypes',
217                                                                          'Input required.' ) );
218                     return eZInputValidator::STATE_INVALID;
219                 }
220                 else
221                     return eZInputValidator::STATE_ACCEPTED;
222             }
223             else
224             {
225                 return $this->validateIntegerHTTPInput( $data, $contentObjectAttribute, $classAttribute );
226             }
227         }
228         else
229             return eZInputValidator::STATE_INVALID;
230     }
231
232     /*!
233      Fetches the http post variables for collected information
234     */
235     function fetchCollectionAttributeHTTPInput( $collection, $collectionAttribute, $http, $base, $contentObjectAttribute )
236     {
237         if ( $http->hasPostVariable( $base . "_data_integer_" . $contentObjectAttribute->attribute( "id" ) ) )
238         {
239             $data = $http->postVariable( $base . "_data_integer_" . $contentObjectAttribute->attribute( "id" ) );
240             $data = trim( $data ) != '' ? $data : null;
241             $data = str_replace(" ", "", $data);
242             $collectionAttribute->setAttribute( "data_int", $data );
243             return true;
244         }
245         return false;
246     }
247
248     /*!
249      Does nothing, the data is already present in the attribute.
250     */
251     function storeObjectAttribute( $object_attribute )
252     {
253     }
254
255     function storeClassAttribute( $attribute, $version )
256     {
257     }
258
259     /*!
260      \reimp
261     */
262     function validateClassAttributeHTTPInput( $http, $base, $classAttribute )
263     {
264         $minValueName = $base . self::MIN_VALUE_VARIABLE . $classAttribute->attribute( "id" );
265         $maxValueName = $base . self::MAX_VALUE_VARIABLE . $classAttribute->attribute( "id" );
266         $defaultValueName = $base . self::DEFAULT_VALUE_VARIABLE . $classAttribute->attribute( "id" );
267
268         if ( $http->hasPostVariable( $minValueName ) and
269              $http->hasPostVariable( $maxValueName ) and
270              $http->hasPostVariable( $defaultValueName ) )
271         {
272             $minValueValue = $http->postVariable( $minValueName );
273             $minValueValue = str_replace(" ", "", $minValueValue );
274             $maxValueValue = $http->postVariable( $maxValueName );
275             $maxValueValue = str_replace(" ", "", $maxValueValue );
276             $defaultValueValue = $http->postVariable( $defaultValueName );
277             $defaultValueValue = str_replace(" ", "", $defaultValueValue );
278
279             if ( ( $minValueValue == "" ) && ( $maxValueValue == "") ){
280                 return  eZInputValidator::STATE_ACCEPTED;
281             }
282             else if ( ( $minValueValue == "" ) && ( $maxValueValue !== "") )
283             {
284                 $max_state = $this->IntegerValidator->validate( $maxValueValue );
285                 return  $max_state;
286             }
287             else if ( ( $minValueValue !== "" ) && ( $maxValueValue == "") )
288             {
289                 $min_state = $this->IntegerValidator->validate( $minValueValue );
290                 return  $min_state;
291             }
292             else
293             {
294                 $min_state = $this->IntegerValidator->validate( $minValueValue );
295                 $max_state = $this->IntegerValidator->validate( $maxValueValue );
296                 if ( ( $min_state == eZInputValidator::STATE_ACCEPTED ) and
297                      ( $max_state == eZInputValidator::STATE_ACCEPTED ) )
298                 {
299                     if ($minValueValue <= $maxValueValue)
300                         return eZInputValidator::STATE_ACCEPTED;
301                     else
302                     {
303                         $state = eZInputValidator::STATE_INTERMEDIATE;
304                         eZDebug::writeNotice( "Integer minimum value great than maximum value." );
305                         return $state;
306                     }
307                 }
308             }
309
310             if ($defaultValueValue == ""){
311                 $default_state =  eZInputValidator::STATE_ACCEPTED;
312             }
313             else
314                 $default_state = $this->IntegerValidator->validate( $defaultValueValue );
315         }
316
317         return eZInputValidator::STATE_INVALID;
318     }
319
320     /*!
321      \reimp
322     */
323     function fixupClassAttributeHTTPInput( $http, $base, $classAttribute )
324     {
325         $minValueName = $base . self::MIN_VALUE_VARIABLE . $classAttribute->attribute( "id" );
326         $maxValueName = $base . self::MAX_VALUE_VARIABLE . $classAttribute->attribute( "id" );
327         if ( $http->hasPostVariable( $minValueName ) and $http->hasPostVariable( $maxValueName ) )
328         {
329             $minValueValue = $http->postVariable( $minValueName );
330             $minValueValue = $this->IntegerValidator->fixup( $minValueValue );
331             $http->setPostVariable( $minValueName, $minValueValue );
332
333             $maxValueValue = $http->postVariable( $maxValueName );
334             $maxValueValue = $this->IntegerValidator->fixup( $maxValueValue );
335             $http->setPostVariable( $maxValueName, $maxValueValue );
336
337             if ($minValueValue > $maxValueValue)
338             {
339                 $this->IntegerValidator->setRange( $minValueValue, false );
340                 $maxValueValue = $this->IntegerValidator->fixup( $maxValueValue );
341                 $http->setPostVariable( $maxValueName, $maxValueValue );
342             }
343         }
344     }
345
346     /*!
347      \reimp
348     */
349     function fetchClassAttributeHTTPInput( $http, $base, $classAttribute )
350     {
351         $minValueName = $base . self::MIN_VALUE_VARIABLE . $classAttribute->attribute( "id" );
352         $maxValueName = $base . self::MAX_VALUE_VARIABLE . $classAttribute->attribute( "id" );
353         $defaultValueName = $base . self::DEFAULT_VALUE_VARIABLE . $classAttribute->attribute( "id" );
354
355         if ( $http->hasPostVariable( $minValueName ) and
356              $http->hasPostVariable( $maxValueName ) and
357              $http->hasPostVariable( $defaultValueName ) )
358         {
359             $minValueValue = $http->postVariable( $minValueName );
360             $minValueValue = str_replace(" ", "", $minValueValue );
361             $maxValueValue = $http->postVariable( $maxValueName );
362             $maxValueValue = str_replace(" ", "", $maxValueValue );
363             $defaultValueValue = $http->postVariable( $defaultValueName );
364             $defaultValueValue = str_replace(" ", "", $defaultValueValue );
365
366             $classAttribute->setAttribute( self::MIN_VALUE_FIELD, $minValueValue );
367             $classAttribute->setAttribute( self::MAX_VALUE_FIELD, $maxValueValue );
368             $classAttribute->setAttribute( self::DEFAULT_VALUE_FIELD, $defaultValueValue );
369
370             if ( ( $minValueValue == "" ) && ( $maxValueValue == "") ){
371                 $input_state = self::NO_MIN_MAX_VALUE;
372                 $classAttribute->setAttribute( self::INPUT_STATE_FIELD, $input_state );
373             }
374             else if ( ( $minValueValue == "" ) && ( $maxValueValue !== "") )
375             {
376                 $input_state = self::HAS_MAX_VALUE;
377                 $classAttribute->setAttribute( self::INPUT_STATE_FIELD, $input_state );
378             }
379             else if ( ( $minValueValue !== "" ) && ( $maxValueValue == "") )
380             {
381                 $input_state = self::HAS_MIN_VALUE;
382                 $classAttribute->setAttribute( self::INPUT_STATE_FIELD, $input_state );
383             }
384             else
385             {
386                 $input_state = self::HAS_MIN_MAX_VALUE;
387                 $classAttribute->setAttribute( self::INPUT_STATE_FIELD, $input_state );
388             }
389             return true;
390         }
391         return false;
392     }
393
394     /*!
395      Returns the content.
396     */
397     function objectAttributeContent( $contentObjectAttribute )
398     {
399         return $contentObjectAttribute->attribute( "data_int" );
400     }
401
402
403     /*!
404      Returns the meta data used for storing search indeces.
405     */
406     function metaData( $contentObjectAttribute )
407     {
408         return $contentObjectAttribute->attribute( "data_int" );
409     }
410     /*!
411      \return string representation of an contentobjectattribute data for simplified export
412
413     */
414     function toString( $contentObjectAttribute )
415     {
416         return $contentObjectAttribute->attribute( 'data_int' );
417     }
418
419     function fromString( $contentObjectAttribute, $string )
420     {
421         return $contentObjectAttribute->setAttribute( 'data_int', $string );
422     }
423
424     /*!
425      Returns the integer value.
426     */
427     function title( $contentObjectAttribute, $name = null )
428     {
429         return $contentObjectAttribute->attribute( "data_int" );
430     }
431
432     function hasObjectAttributeContent( $contentObjectAttribute )
433     {
434         return true;
435     }
436
437     /*!
438      \reimp
439     */
440     function isInformationCollector()
441     {
442         return true;
443     }
444
445     /*!
446      \return true if the datatype can be indexed
447     */
448     function isIndexable()
449     {
450         return true;
451     }
452
453     /*!
454      \reimp
455     */
456     function sortKey( $contentObjectAttribute )
457     {
458         return $contentObjectAttribute->attribute( 'data_int' );
459     }
460
461     /*!
462      \reimp
463     */
464     function sortKeyType()
465     {
466         return 'int';
467     }
468
469     /*!
470      \reimp
471     */
472     function serializeContentClassAttribute( $classAttribute, $attributeNode, $attributeParametersNode )
473     {
474         $defaultValue = $classAttribute->attribute( self::DEFAULT_VALUE_FIELD );
475         $minValue = $classAttribute->attribute( self::MIN_VALUE_FIELD );
476         $maxValue = $classAttribute->attribute( self::MAX_VALUE_FIELD );
477         $minMaxState = $classAttribute->attribute( self::INPUT_STATE_FIELD );
478
479         $dom = $attributeParametersNode->ownerDocument;
480         $defaultValueNode = $dom->createElement( 'default-value', $defaultValue );
481         $attributeParametersNode->appendChild( $defaultValueNode );
482         if ( $minMaxState == self::HAS_MIN_VALUE or $minMaxState == self::HAS_MIN_MAX_VALUE )
483         {
484             $minValueNode = $dom->createElement( 'min-value', $minValue );
485             $attributeParametersNode->appendChild( $minValueNode );
486         }
487         if ( $minMaxState == self::HAS_MAX_VALUE or $minMaxState == self::HAS_MIN_MAX_VALUE )
488         {
489             $maxValueNode = $dom->createElement( 'max-value', $maxValue );
490             $attributeParametersNode->appendChild( $maxValueNode );
491         }
492     }
493
494     /*!
495      \reimp
496     */
497     function unserializeContentClassAttribute( $classAttribute, $attributeNode, $attributeParametersNode )
498     {
499         $defaultValue = $attributeParametersNode->getElementsByTagName( 'default-value' )->item( 0 )->textContent;
500         $minValue = $attributeParametersNode->getElementsByTagName( 'min-value' )->item( 0 )->textContent;
501         $maxValue = $attributeParametersNode->getElementsByTagName( 'max-value' )->item( 0 )->textContent;
502
503         if ( strlen( $minValue ) > 0 and strlen( $maxValue ) > 0 )
504             $minMaxState = self::HAS_MIN_MAX_VALUE;
505         else if ( strlen( $minValue ) > 0 )
506             $minMaxState = self::HAS_MIN_VALUE;
507         else if ( strlen( $maxValue ) > 0 )
508             $minMaxState = self::HAS_MAX_VALUE;
509         else
510             $minMaxState = self::NO_MIN_MAX_VALUE;
511
512         $classAttribute->setAttribute( self::DEFAULT_VALUE_FIELD, $defaultValue );
513         $classAttribute->setAttribute( self::MIN_VALUE_FIELD, $minValue );
514         $classAttribute->setAttribute( self::MAX_VALUE_FIELD, $maxValue );
515         $classAttribute->setAttribute( self::INPUT_STATE_FIELD, $minMaxState );
516     }
517
518     function batchInitializeObjectAttributeData( $classAttribute )
519     {
520         $default = $classAttribute->attribute( "data_int3" );
521         if ( $default === 0 )
522         {
523             return array();
524         }
525         else
526         {
527             return array( 'data_int'     => $default,
528                           'sort_key_int' => $default );
529         }
530     }
531
532     function supportsBatchInitializeObjectAttribute()
533     {
534         return true;
535     }
536
537     /// \privatesection
538     /// The integer value validator
539     public $IntegerValidator;
540 }
541
542 eZDataType::register( eZIntegerType::DATA_TYPE_STRING, "eZIntegerType" );
543
544 ?>