- Fixed bug in eZMatrix datatype when adding/removing/changing columns.
[tinyz:tinyz.git] / kernel / classes / datatypes / ezmatrix / ezmatrixtype.php
1 <?php
2 //
3 // Definition of eZMatrixType class
4 //
5 // Created on: <30-May-2003 14:18:35 sp>
6 //
7 // Copyright (C) 1999-2004 eZ systems as. All rights reserved.
8 //
9 // This source file is part of the eZ publish (tm) Open Source Content
10 // Management System.
11 //
12 // This file may be distributed and/or modified under the terms of the
13 // "GNU General Public License" version 2 as published by the Free
14 // Software Foundation and appearing in the file LICENSE included in
15 // the packaging of this file.
16 //
17 // Licencees holding a valid "eZ publish professional licence" version 2
18 // may use this file in accordance with the "eZ publish professional licence"
19 // version 2 Agreement provided with the Software.
20 //
21 // This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING
22 // THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23 // PURPOSE.
24 //
25 // The "eZ publish professional licence" version 2 is available at
26 // http://ez.no/ez_publish/licences/professional/ and in the file
27 // PROFESSIONAL_LICENCE included in the packaging of this file.
28 // For pricing of this licence please contact us via e-mail to licence@ez.no.
29 // Further contact information is available at http://ez.no/company/contact/.
30 //
31 // The "GNU General Public License" (GPL) is available at
32 // http://www.gnu.org/copyleft/gpl.html.
33 //
34 // Contact licence@ez.no if any conditions of this licencing isn't clear to
35 // you.
36 //
37
38 /*! \file ezmatrixtype.php
39 */
40
41 /*!
42   \class eZMatrixType ezmatrixtype.php
43   \brief The class eZMatrixType does
44
45 */
46
47 include_once( 'kernel/classes/ezdatatype.php' );
48 include_once( 'kernel/classes/datatypes/ezmatrix/ezmatrix.php' );
49 include_once( 'kernel/classes/datatypes/ezmatrix/ezmatrixdefinition.php' );
50
51 define( 'EZ_MATRIX_DEFAULT_NAME_VARIABLE', '_ezmatrix_default_name_' );
52
53 define( 'EZ_MATRIX_NUMCOLUMNS_VARIABLE', '_ezmatrix_default_num_columns_' );
54 define( 'EZ_MATRIX_NUMROWS_VARIABLE', '_ezmatrix_default_num_rows_' );
55 define( 'EZ_MATRIX_CELL_VARIABLE', '_ezmatrix_cell_' );
56 define( 'EZ_DATATYPESTRING_MATRIX', 'ezmatrix' );
57
58 class eZMatrixType extends eZDataType
59 {
60     /*!
61      Constructor
62     */
63     function eZMatrixType()
64     {
65         $this->eZDataType( EZ_DATATYPESTRING_MATRIX, ezi18n( 'kernel/classes/datatypes', 'Matrix', 'Datatype name' ),
66                            array( 'serialize_supported' => true ) );
67     }
68
69     /*!
70      Validates the input and returns true if the input was
71      valid for this datatype.
72     */
73     function validateObjectAttributeHTTPInput( &$http, $base, &$contentObjectAttribute )
74     {
75 /*        if ( $http->hasPostVariable( $base . '_data_option_id_' . $contentObjectAttribute->attribute( 'id' ) ) )
76         {
77                     return EZ_INPUT_VALIDATOR_STATE_INVALID;
78         }
79 */      return EZ_INPUT_VALIDATOR_STATE_ACCEPTED;
80     }
81
82     /*!
83      Store content
84     */
85     function storeObjectAttribute( &$contentObjectAttribute )
86     {
87         $matrix =& $contentObjectAttribute->content();
88         $contentObjectAttribute->setAttribute( 'data_text', $matrix->xmlString() );
89         $matrix->decodeXML( $contentObjectAttribute->attribute( 'data_text' ) );
90         $contentObjectAttribute->setContent( $matrix );
91     }
92
93     function storeClassAttribute( &$contentClassAttribute, $version )
94     {
95         $matrixDefinition =& $contentClassAttribute->content();
96         $contentClassAttribute->setAttribute( 'data_text5', $matrixDefinition->xmlString() );
97         $matrixDefinition->decodeClassAttribute( $contentClassAttribute->attribute( 'data_text5' ) );
98         $contentClassAttribute->setContent(  $matrixDefinition );
99     }
100
101     /*!
102      Returns the content.
103     */
104     function &objectAttributeContent( &$contentObjectAttribute )
105     {
106         $matrix = new eZMatrix( '' );
107
108         $matrix->decodeXML( $contentObjectAttribute->attribute( 'data_text' ) );
109
110         return $matrix;
111     }
112
113     function hasObjectAttributeContent( &$contentObjectAttribute )
114     {
115         $matrix =& $contentObjectAttribute->content();
116         $columnsArray =& $matrix->attribute( 'columns' );
117         $columns =& $columnsArray['sequential'];
118         $count = 0;
119         foreach ( $columns as $column )
120         {
121             $count += count( $column['rows'] );
122         }
123         return $count > 0;
124     }
125
126     /*!
127      Returns the meta data used for storing search indeces.
128     */
129     function metaData( $contentObjectAttribute )
130     {
131         $matrix =& $contentObjectAttribute->content();
132         $columnsArray =& $matrix->attribute( 'columns' );
133         $columns =& $columnsArray['sequential'];
134         $metaDataArray = array();
135         foreach ( $columns as $column )
136         {
137             $rows = $column['rows'];
138             foreach ( $rows as $row )
139             {
140                 $metaDataArray[] = array( 'id' => $column['identifier'],
141                                           'text' => $row );
142             }
143         }
144         return $metaDataArray;
145     }
146
147     /*!
148      Fetches the http post var matrix cells input and stores it in the data instance.
149     */
150     function fetchObjectAttributeHTTPInput( &$http, $base, &$contentObjectAttribute )
151     {
152         $cellsVarName = $base . EZ_MATRIX_CELL_VARIABLE . $contentObjectAttribute->attribute( 'id' );
153         if ( $http->hasPostVariable( $cellsVarName ) )
154         {
155             $cells = array();
156             foreach ( $http->postVariable( $cellsVarName ) as $cell )
157             {
158                 $cells[] = $cell;
159             }
160             $matrix =& $contentObjectAttribute->attribute( 'content' );
161             $matrix->Cells =& $cells;
162
163             $contentObjectAttribute->setAttribute( 'data_text', $matrix->xmlString() );
164             $matrix->decodeXML( $contentObjectAttribute->attribute( 'data_text' ) );
165             $contentObjectAttribute->setContent( $matrix );
166         }
167         return true;
168     }
169
170     /*!
171     */
172     function customObjectAttributeHTTPAction( $http, $action, &$contentObjectAttribute )
173     {
174         switch ( $action )
175         {
176             case 'new_row' :
177             {
178                 $matrix =& $contentObjectAttribute->content( );
179
180                 $postvarname = 'ContentObjectAttribute' . '_data_matrix_remove_' . $contentObjectAttribute->attribute( 'id' );
181                 $addCountName = 'ContentObjectAttribute' . '_data_matrix_add_count_' . $contentObjectAttribute->attribute( 'id' );
182
183                 $addCount = 1;
184                 if ( $http->hasPostVariable( $addCountName ) )
185                 {
186                     $addCount = $http->postVariable( $addCountName );
187                 }
188
189                 if ( $http->hasPostVariable( $postvarname ) )
190                 {
191                     $selected = $http->postVariable( $postvarname );
192                     $matrix->addRow( $selected[0], $addCount );
193                 }
194                 else
195                 {
196                     $matrix->addRow( false, $addCount );
197                 }
198
199                 $contentObjectAttribute->setAttribute( 'data_text', $matrix->xmlString() );
200                 $matrix->decodeXML( $contentObjectAttribute->attribute( 'data_text' ) );
201                 $contentObjectAttribute->setContent( $matrix );
202                 $contentObjectAttribute->store();
203             }break;
204             case 'remove_selected' :
205             {
206                 $matrix =& $contentObjectAttribute->content( );
207                 $postvarname = 'ContentObjectAttribute' . '_data_matrix_remove_' . $contentObjectAttribute->attribute( 'id' );
208                 $arrayRemove = $http->postVariable( $postvarname );
209
210                 rsort( $arrayRemove );
211                 foreach ( $arrayRemove as $rowNum)
212                 {
213                     $matrix->removeRow( $rowNum );
214                 }
215
216                 $contentObjectAttribute->setAttribute( 'data_text', $matrix->xmlString() );
217                 $matrix->decodeXML( $contentObjectAttribute->attribute( 'data_text' ) );
218                 $contentObjectAttribute->setContent( $matrix );
219                 $contentObjectAttribute->store();
220             }break;
221             default :
222             {
223                 eZDebug::writeError( 'Unknown custom HTTP action: ' . $action, 'eZMatrixType' );
224             }break;
225         }
226     }
227
228     /*!
229      Returns the integer value.
230     */
231     function title( &$contentObjectAttribute, $name = 'name' )
232     {
233         $matrix =& $contentObjectAttribute->content( );
234
235         $value = $matrix->attribute( $name );
236
237         return $value;
238     }
239
240     /*!
241      Sets the default value.
242     */
243     function initializeObjectAttribute( &$contentObjectAttribute, $currentVersion, &$originalContentObjectAttribute )
244     {
245
246         if ( $currentVersion != false )
247         {
248             $matrix =& $contentObjectAttribute->content();
249             $contentClassAttribute =& $contentObjectAttribute->contentClassAttribute();
250
251             // make sure that $matrix contains right columns
252             $matrix->adjustColumnsToDefinition( $contentClassAttribute->attribute( 'content' ) );
253
254             $matrix->setName( $contentClassAttribute->attribute( 'data_text1' ) );
255             $contentObjectAttribute->setAttribute( 'data_text', $matrix->xmlString() );
256             $contentObjectAttribute->setContent( $matrix );
257         }
258         else
259         {
260             $contentClassAttribute =& $contentObjectAttribute->contentClassAttribute();
261             $numRows = $contentClassAttribute->attribute( 'data_int1' );
262             $matrix = new eZMatrix( '', $numRows, $contentClassAttribute->attribute( 'content' ) );
263             $contentObjectAttribute->setAttribute( 'data_text', $matrix->xmlString() );
264             $contentObjectAttribute->setContent( $matrix );
265         }
266
267     }
268
269     /*!
270      \reimp
271     */
272     function fetchClassAttributeHTTPInput( &$http, $base, &$classAttribute )
273     {
274         $defaultValueName = $base . EZ_MATRIX_DEFAULT_NAME_VARIABLE . $classAttribute->attribute( 'id' );
275         $defaultNumColumnsName = $base . EZ_MATRIX_NUMCOLUMNS_VARIABLE . $classAttribute->attribute( 'id' );
276         $defaultNumRowsName = $base . EZ_MATRIX_NUMROWS_VARIABLE . $classAttribute->attribute( 'id' );
277         $dataFetched = false;
278         if ( $http->hasPostVariable( $defaultValueName ) )
279         {
280             $defaultValueValue = $http->postVariable( $defaultValueName );
281
282             if ( $defaultValueValue == '' )
283             {
284                 $defaultValueValue = '';
285             }
286             $classAttribute->setAttribute( 'data_text1', $defaultValueValue );
287             $dataFetched = true;
288         }
289
290         if ( $http->hasPostVariable( $defaultNumRowsName ) )
291         {
292             $defaultNumRowsValue = $http->postVariable( $defaultNumRowsName );
293
294             if ( $defaultNumRowsValue == '' )
295             {
296                 $defaultNumRowsValue = '1';
297             }
298             $classAttribute->setAttribute( 'data_int1', $defaultNumRowsValue );
299             $dataFetched = true;
300         }
301
302         $columnNameVariable = $base . '_data_ezmatrix_column_name_' . $classAttribute->attribute( 'id' );
303         $columnIDVariable = $base . '_data_ezmatrix_column_id_' . $classAttribute->attribute( 'id' );
304
305
306         if ( $http->hasPostVariable( $columnNameVariable ) && $http->hasPostVariable( $columnIDVariable ) )
307         {
308             $columns = array();
309             $i = 0;
310             $columnNameList = $http->postVariable( $columnNameVariable );
311             $columnIDList = $http->postVariable( $columnIDVariable );
312
313             $matrixDefinition =& $classAttribute->attribute( 'content' );
314             $columnNames =& $matrixDefinition->attribute( 'columns' );
315             foreach ( $columnNames as $columnName )
316             {
317                 $index = $columnName['index'];
318                 $columnID = $columnIDList[$index];
319                 $name = $columnNameList[$index];
320                 if ( strlen( $columnID ) == 0 )
321                 {
322                     $columnID = $name;
323                     $columnID = strtolower( $columnID );
324                     $columnID = preg_replace( array( '/[^a-z0-9_ ]/' ,
325                                        '/ /',
326                                        '/__+/' ),
327                                 array( '',
328                                        '_',
329                                        '_' ),
330                                 $columnID );
331                 }
332
333                 $columns[] = array( 'name' => $name,
334                                     'identifier' => $columnID,
335                                     'index' => $i );
336
337                 $i++;
338             }
339
340             $matrixDefinition->ColumnNames =& $columns;
341             $classAttribute->setContent( $matrixDefinition );
342             $classAttribute->setAttribute( 'data_text5', $matrixDefinition->xmlString() );
343
344             $dataFetched = true;
345         }
346         if ( $dataFetched )
347         {
348             return true;
349         }
350         return false;
351
352     }
353
354
355     /*!
356      Returns the content.
357     */
358     function &classAttributeContent( &$contentClassAttribute )
359     {
360         $matrixDefinition =& new eZMatrixDefinition();
361         $matrixDefinition->decodeClassAttribute( $contentClassAttribute->attribute( 'data_text5' ) );
362         return $matrixDefinition;
363     }
364
365     /*!
366     */
367     function customClassAttributeHTTPAction( &$http, $action, &$contentClassAttribute )
368     {
369         $id = $contentClassAttribute->attribute( 'id' );
370         switch ( $action )
371         {
372             case 'new_ezmatrix_column' :
373             {
374                 $matrixDefinition =& $contentClassAttribute->content( );
375                 $matrixDefinition->addColumn( '' );
376                 $contentClassAttribute->setContent( $matrixDefinition );
377                 $contentClassAttribute->store();
378             }break;
379             case 'remove_selected' :
380             {
381                 $matrixDefinition =& $contentClassAttribute->content( );
382
383                 $postvarname = 'ContentClass' . '_data_ezmatrix_column_remove_' . $contentClassAttribute->attribute( 'id' );
384                 $array_remove = $http->postVariable( $postvarname );
385                 foreach( $array_remove as $columnIndex )
386                 {
387                     $matrixDefinition->removeColumn( $columnIndex );
388                 }
389                 $contentClassAttribute->setContent( $matrixDefinition );
390             }break;
391             default :
392             {
393                 eZDebug::writeError( 'Unknown custom HTTP action: ' . $action, 'eZEnumType' );
394             }break;
395         }
396     }
397
398     /*!
399      \reimp
400     */
401     function isIndexable()
402     {
403         return true;
404     }
405
406     /*!
407      \reimp
408     */
409     function &serializeContentClassAttribute( &$classAttribute, &$attributeNode, &$attributeParametersNode )
410     {
411         $content =& $classAttribute->content();
412         if ( $content )
413         {
414             $defaultName = $classAttribute->attribute( 'data_text1' );
415             $defaultRowCount = $classAttribute->attribute( 'data_int1' );
416             $columns = $content->attribute( 'columns' );
417             $attributeParametersNode->appendChild( eZDOMDocument::createElementTextNode( 'default-name', $defaultName ) );
418             $attributeParametersNode->appendChild( eZDOMDocument::createElementTextNode( 'default-row-count', $defaultRowCount ) );
419             $columnsNode =& eZDOMDocument::createElementNode( 'columns' );
420             $attributeParametersNode->appendChild( $columnsNode );
421             foreach ( $columns as $column )
422             {
423                 $columnsNode->appendChild( eZDOMDocument::createElementNode( 'column',
424                                                                              array( 'name' => $column['name'],
425                                                                                     'identifier' => $column['identifier'],
426                                                                                     'index' => $column['index'] ) ) );
427             }
428         }
429     }
430
431     /*!
432      \reimp
433     */
434     function &unserializeContentClassAttribute( &$classAttribute, &$attributeNode, &$attributeParametersNode )
435     {
436         $defaultName = $attributeParametersNode->elementTextContentByName( 'default-name' );
437         $defaultRowCount = $attributeParametersNode->elementTextContentByName( 'default-row-count' );
438         $classAttribute->setAttribute( 'data_text1', $defaultName );
439         $classAttribute->setAttribute( 'data_int1', $defaultRowCount );
440
441         $matrixDefinition =& new eZMatrixDefinition();
442         $columnsNode =& $attributeParametersNode->elementByName( 'columns' );
443         $columnsList =& $columnsNode->children();
444         foreach ( array_keys( $columnsList ) as $columnKey )
445         {
446             $columnNode =& $columnsList[$columnKey];
447             $columnName = $columnNode->attributeValue( 'name' );
448             $columnIdentifier = $columnNode->attributeValue( 'identifier' );
449             $matrixDefinition->addColumn( $columnName, $columnIdentifier );
450         }
451         $classAttribute->setAttribute( 'data_text5', $matrixDefinition->xmlString() );
452     }
453 }
454
455 eZDataType::register( EZ_DATATYPESTRING_MATRIX, 'ezmatrixtype' );
456
457 ?>