eZ Publish  [trunk]
ezmatrixtype.php
Go to the documentation of this file.
00001 <?php
00002 /**
00003  * File containing the eZMatrixType 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 eZMatrixType ezmatrixtype.php
00013   \ingroup eZDatatype
00014   \brief The class eZMatrixType does
00015 
00016 */
00017 
00018 class eZMatrixType extends eZDataType
00019 {
00020     const DEFAULT_NAME_VARIABLE = '_ezmatrix_default_name_';
00021 
00022     const NUM_COLUMNS_VARIABLE = '_ezmatrix_default_num_columns_';
00023     const NUM_ROWS_VARIABLE = '_ezmatrix_default_num_rows_';
00024     const CELL_VARIABLE = '_ezmatrix_cell_';
00025     const DATA_TYPE_STRING = 'ezmatrix';
00026 
00027     /*!
00028      Constructor
00029     */
00030     function eZMatrixType()
00031     {
00032         $this->eZDataType( self::DATA_TYPE_STRING, ezpI18n::tr( 'kernel/classes/datatypes', 'Matrix', 'Datatype name' ),
00033                            array( 'serialize_supported' => true ) );
00034     }
00035 
00036     /*!
00037      Validates the input and returns true if the input was
00038      valid for this datatype.
00039     */
00040     function validateObjectAttributeHTTPInput( $http, $base, $contentObjectAttribute )
00041     {
00042         $data = false;
00043         if ( $http->hasPostVariable( $base . '_ezmatrix_cell_' . $contentObjectAttribute->attribute( 'id' ) ) )
00044             $data = $http->PostVariable( $base . '_ezmatrix_cell_' . $contentObjectAttribute->attribute( 'id' ) );
00045         $count = 0;
00046         for ( $i = 0; $i < count( $data ); ++$i )
00047              if ( trim( $data[$i] ) <> '' )
00048              {
00049                  ++$count;
00050                  break;
00051              }
00052         if ( $contentObjectAttribute->validateIsRequired() and ( $count == 0 or $data === false ) )
00053         {
00054             $contentObjectAttribute->setValidationError( ezpI18n::tr( 'kernel/classes/datatypes',
00055                                                                  'Missing matrix input.' ) );
00056             return eZInputValidator::STATE_INVALID;
00057         }
00058         return eZInputValidator::STATE_ACCEPTED;
00059     }
00060 
00061     /*!
00062      Store content
00063     */
00064     function storeObjectAttribute( $contentObjectAttribute )
00065     {
00066         $matrix = $contentObjectAttribute->content();
00067         $contentObjectAttribute->setAttribute( 'data_text', $matrix->xmlString() );
00068         $matrix->decodeXML( $contentObjectAttribute->attribute( 'data_text' ) );
00069         $contentObjectAttribute->setContent( $matrix );
00070     }
00071 
00072     function storeClassAttribute( $contentClassAttribute, $version )
00073     {
00074         $matrixDefinition = $contentClassAttribute->content();
00075         $contentClassAttribute->setAttribute( 'data_text5', $matrixDefinition->xmlString() );
00076         $matrixDefinition->decodeClassAttribute( $contentClassAttribute->attribute( 'data_text5' ) );
00077         $contentClassAttribute->setContent(  $matrixDefinition );
00078     }
00079 
00080     /*!
00081      Returns the content.
00082     */
00083     function objectAttributeContent( $contentObjectAttribute )
00084     {
00085         $matrix = new eZMatrix( '' );
00086 
00087         $matrix->decodeXML( $contentObjectAttribute->attribute( 'data_text' ) );
00088 
00089         return $matrix;
00090     }
00091 
00092     function hasObjectAttributeContent( $contentObjectAttribute )
00093     {
00094         $matrix = $contentObjectAttribute->content();
00095         $columnsArray = $matrix->attribute( 'columns' );
00096         $columns = $columnsArray['sequential'];
00097         $count = 0;
00098         foreach ( $columns as $column )
00099         {
00100             $count += count( $column['rows'] );
00101         }
00102         return $count > 0;
00103     }
00104 
00105     /*!
00106      Returns the meta data used for storing search indeces.
00107     */
00108     function metaData( $contentObjectAttribute )
00109     {
00110         $matrix = $contentObjectAttribute->content();
00111         $columnsArray = $matrix->attribute( 'columns' );
00112         $columns = $columnsArray['sequential'];
00113         $metaDataArray = array();
00114         foreach ( $columns as $column )
00115         {
00116             $rows = $column['rows'];
00117             foreach ( $rows as $row )
00118             {
00119                 $metaDataArray[] = array( 'id' => $column['identifier'],
00120                                           'text' => $row );
00121             }
00122         }
00123         return $metaDataArray;
00124     }
00125 
00126     /*!
00127      Fetches the http post var matrix cells input and stores it in the data instance.
00128     */
00129     function fetchObjectAttributeHTTPInput( $http, $base, $contentObjectAttribute )
00130     {
00131         $cellsVarName = $base . self::CELL_VARIABLE . $contentObjectAttribute->attribute( 'id' );
00132         if ( $http->hasPostVariable( $cellsVarName ) )
00133         {
00134             $cells = array();
00135             foreach ( $http->postVariable( $cellsVarName ) as $cell )
00136             {
00137                 $cells[] = $cell;
00138             }
00139             $matrix = $contentObjectAttribute->attribute( 'content' );
00140             $matrix->Cells = $cells;
00141 
00142             $contentObjectAttribute->setAttribute( 'data_text', $matrix->xmlString() );
00143             $matrix->decodeXML( $contentObjectAttribute->attribute( 'data_text' ) );
00144             $contentObjectAttribute->setContent( $matrix );
00145         }
00146         return true;
00147     }
00148 
00149     function customObjectAttributeHTTPAction( $http, $action, $contentObjectAttribute, $parameters )
00150     {
00151         switch ( $action )
00152         {
00153             case 'new_row' :
00154             {
00155                 $matrix = $contentObjectAttribute->content( );
00156 
00157                 $postvarname = 'ContentObjectAttribute' . '_data_matrix_remove_' . $contentObjectAttribute->attribute( 'id' );
00158                 $addCountName = 'ContentObjectAttribute' . '_data_matrix_add_count_' . $contentObjectAttribute->attribute( 'id' );
00159 
00160                 $addCount = 1;
00161                 if ( $http->hasPostVariable( $addCountName ) )
00162                 {
00163                     $addCount = $http->postVariable( $addCountName );
00164                 }
00165 
00166                 if ( $http->hasPostVariable( $postvarname ) )
00167                 {
00168                     $selected = $http->postVariable( $postvarname );
00169                     $matrix->addRow( $selected[0], $addCount );
00170                 }
00171                 else
00172                 {
00173                     $matrix->addRow( false, $addCount );
00174                 }
00175 
00176                 $contentObjectAttribute->setAttribute( 'data_text', $matrix->xmlString() );
00177                 $matrix->decodeXML( $contentObjectAttribute->attribute( 'data_text' ) );
00178                 $contentObjectAttribute->setContent( $matrix );
00179                 $contentObjectAttribute->store();
00180             }break;
00181             case 'remove_selected' :
00182             {
00183                 $matrix = $contentObjectAttribute->content( );
00184                 $postvarname = 'ContentObjectAttribute' . '_data_matrix_remove_' . $contentObjectAttribute->attribute( 'id' );
00185                 $arrayRemove = $http->postVariable( $postvarname );
00186 
00187                 rsort( $arrayRemove );
00188                 foreach ( $arrayRemove as $rowNum)
00189                 {
00190                     $matrix->removeRow( $rowNum );
00191                 }
00192 
00193                 $contentObjectAttribute->setAttribute( 'data_text', $matrix->xmlString() );
00194                 $matrix->decodeXML( $contentObjectAttribute->attribute( 'data_text' ) );
00195                 $contentObjectAttribute->setContent( $matrix );
00196                 $contentObjectAttribute->store();
00197             }break;
00198             default :
00199             {
00200                 eZDebug::writeError( 'Unknown custom HTTP action: ' . $action, 'eZMatrixType' );
00201             }break;
00202         }
00203     }
00204 
00205     /*!
00206      Returns the integer value.
00207     */
00208     function title( $contentObjectAttribute, $name = 'name' )
00209     {
00210         $matrix = $contentObjectAttribute->content( );
00211 
00212         $value = $matrix->attribute( $name );
00213 
00214         return $value;
00215     }
00216 
00217     /*!
00218      Sets the default value.
00219     */
00220     function initializeObjectAttribute( $contentObjectAttribute, $currentVersion, $originalContentObjectAttribute )
00221     {
00222 
00223         if ( $currentVersion != false )
00224         {
00225             $matrix = $originalContentObjectAttribute->content();
00226             $contentClassAttribute = $contentObjectAttribute->contentClassAttribute();
00227             // make sure that $matrix contains right columns
00228             $matrix->adjustColumnsToDefinition( $contentClassAttribute->attribute( 'content' ) );
00229 
00230             $contentObjectAttribute->setAttribute( 'data_text', $matrix->xmlString() );
00231             $contentObjectAttribute->setContent( $matrix );
00232         }
00233         else
00234         {
00235             $contentClassAttribute = $contentObjectAttribute->contentClassAttribute();
00236             $numRows = $contentClassAttribute->attribute( 'data_int1' );
00237             $matrix = new eZMatrix( '', $numRows, $contentClassAttribute->attribute( 'content' ) );
00238             // 'default name' is never used => just a stub
00239             // $matrix->setName( $contentClassAttribute->attribute( 'data_text1' ) );
00240             $contentObjectAttribute->setAttribute( 'data_text', $matrix->xmlString() );
00241             $contentObjectAttribute->setContent( $matrix );
00242         }
00243 
00244     }
00245 
00246     function fetchClassAttributeHTTPInput( $http, $base, $classAttribute )
00247     {
00248         // 'default name' is never used => just a stub
00249         // $defaultValueName = $base . self::DEFAULT_NAME_VARIABLE . $classAttribute->attribute( 'id' );
00250         $defaultValueName = '';
00251         $defaultNumColumnsName = $base . self::NUM_COLUMNS_VARIABLE . $classAttribute->attribute( 'id' );
00252         $defaultNumRowsName = $base . self::NUM_ROWS_VARIABLE . $classAttribute->attribute( 'id' );
00253         $dataFetched = false;
00254         // 'default name' is never used => just a stub
00255         /*
00256         if ( $http->hasPostVariable( $defaultValueName ) )
00257         {
00258             $defaultValueValue = $http->postVariable( $defaultValueName );
00259 
00260             if ( $defaultValueValue == '' )
00261             {
00262                 $defaultValueValue = '';
00263             }
00264             $classAttribute->setAttribute( 'data_text1', $defaultValueValue );
00265             $dataFetched = true;
00266         }
00267         */
00268 
00269         if ( $http->hasPostVariable( $defaultNumRowsName ) )
00270         {
00271             $defaultNumRowsValue = $http->postVariable( $defaultNumRowsName );
00272 
00273             if ( $defaultNumRowsValue == '' )
00274             {
00275                 $defaultNumRowsValue = '1';
00276             }
00277             $classAttribute->setAttribute( 'data_int1', $defaultNumRowsValue );
00278             $dataFetched = true;
00279         }
00280 
00281         $columnNameVariable = $base . '_data_ezmatrix_column_name_' . $classAttribute->attribute( 'id' );
00282         $columnIDVariable = $base . '_data_ezmatrix_column_id_' . $classAttribute->attribute( 'id' );
00283 
00284 
00285         if ( $http->hasPostVariable( $columnNameVariable ) && $http->hasPostVariable( $columnIDVariable ) )
00286         {
00287             $columns = array();
00288             $i = 0;
00289             $columnNameList = $http->postVariable( $columnNameVariable );
00290             $columnIDList = $http->postVariable( $columnIDVariable );
00291 
00292             $matrixDefinition = $classAttribute->attribute( 'content' );
00293             $columnNames = $matrixDefinition->attribute( 'columns' );
00294             foreach ( $columnNames as $columnName )
00295             {
00296                 $columnID = '';
00297                 $name = '';
00298                 $index = $columnName['index'];
00299 
00300                 // after adding a new column $columnIDList and $columnNameList doesn't contain values for new column.
00301                 // if so just add column with empty 'name' and 'columnID'.
00302                 if ( isset( $columnIDList[$index] ) && isset( $columnNameList[$index] ) )
00303                 {
00304                     $columnID = $columnIDList[$index];
00305                     $name = $columnNameList[$index];
00306                     if ( strlen( $columnID ) == 0 )
00307                     {
00308                         $columnID = $name;
00309                         // Initialize transformation system
00310                         $trans = eZCharTransform::instance();
00311                         $columnID = $trans->transformByGroup( $columnID, 'identifier' );
00312                     }
00313                 }
00314 
00315                 $columns[] = array( 'name' => $name,
00316                                     'identifier' => $columnID,
00317                                     'index' => $i );
00318 
00319                 $i++;
00320             }
00321 
00322             $matrixDefinition->ColumnNames = $columns;
00323             $classAttribute->setContent( $matrixDefinition );
00324             $classAttribute->setAttribute( 'data_text5', $matrixDefinition->xmlString() );
00325 
00326             $dataFetched = true;
00327         }
00328         if ( $dataFetched )
00329         {
00330             return true;
00331         }
00332         return false;
00333 
00334     }
00335 
00336     function preStoreClassAttribute( $classAttribute, $version )
00337     {
00338         $matrixDefinition = $classAttribute->attribute( 'content' );
00339         $classAttribute->setAttribute( 'data_text5', $matrixDefinition->xmlString() );
00340     }
00341 
00342     /*!
00343      Returns the content.
00344     */
00345     function classAttributeContent( $contentClassAttribute )
00346     {
00347         $matrixDefinition = new eZMatrixDefinition();
00348         $matrixDefinition->decodeClassAttribute( $contentClassAttribute->attribute( 'data_text5' ) );
00349         return $matrixDefinition;
00350     }
00351 
00352     function customClassAttributeHTTPAction( $http, $action, $contentClassAttribute )
00353     {
00354         $id = $contentClassAttribute->attribute( 'id' );
00355         switch ( $action )
00356         {
00357             case 'new_ezmatrix_column' :
00358             {
00359                 $matrixDefinition = $contentClassAttribute->content( );
00360                 $matrixDefinition->addColumn( '' );
00361                 $contentClassAttribute->setContent( $matrixDefinition );
00362                 $contentClassAttribute->store();
00363             }break;
00364             case 'remove_selected' :
00365             {
00366                 $matrixDefinition = $contentClassAttribute->content( );
00367 
00368                 $postvarname = 'ContentClass' . '_data_ezmatrix_column_remove_' . $contentClassAttribute->attribute( 'id' );
00369                 $array_remove = $http->postVariable( $postvarname );
00370                 foreach( $array_remove as $columnIndex )
00371                 {
00372                     $matrixDefinition->removeColumn( $columnIndex );
00373                 }
00374                 $contentClassAttribute->setContent( $matrixDefinition );
00375             }break;
00376             default :
00377             {
00378                 eZDebug::writeError( 'Unknown custom HTTP action: ' . $action, 'eZEnumType' );
00379             }break;
00380         }
00381     }
00382 
00383     function isIndexable()
00384     {
00385         return true;
00386     }
00387 
00388     /*!
00389      \return string representation of an contentobjectattribute data for simplified export
00390 
00391     */
00392     function toString( $contentObjectAttribute )
00393     {
00394         $matrix = $contentObjectAttribute->attribute( 'content' );
00395         $matrixArray = array();
00396         $rows = $matrix->attribute( 'rows' );
00397 
00398         foreach( $rows['sequential'] as $row )
00399         {
00400             $matrixArray[] = eZStringUtils::implodeStr( $row['columns'], '|' );
00401         }
00402 
00403         return eZStringUtils::implodeStr( $matrixArray, '&' );
00404 
00405     }
00406 
00407     function fromString( $contentObjectAttribute, $string )
00408     {
00409         if ( $string != '' )
00410         {
00411             $matrix = $contentObjectAttribute->attribute( 'content' );
00412             $matrixRowsList = eZStringUtils::explodeStr( $string, "&" );
00413             $cells = array();
00414             $matrix->Matrix['rows']['sequential'] = array();
00415             $matrix->NumRows = 0;
00416 
00417             foreach( $matrixRowsList as $key => $value )
00418             {
00419                 $newCells = eZStringUtils::explodeStr( $value, '|' );
00420                 $matrixArray[] = $newCells;
00421                 $cells = array_merge( $cells, $newCells );
00422 
00423                 $newRow['columns'] = $newCells;
00424                 $newRow['identifier'] =  'row_' . ( $matrix->NumRows + 1 );
00425                 $newRow['name'] = 'Row_' . ( $matrix->NumRows + 1 );
00426                 $matrix->NumRows++;
00427 
00428 
00429                 $matrix->Matrix['rows']['sequential'][] = $newRow;
00430             }
00431             $matrix->Cells = $cells;
00432         }
00433         return true;
00434     }
00435 
00436     function serializeContentClassAttribute( $classAttribute, $attributeNode, $attributeParametersNode )
00437     {
00438         $content = $classAttribute->content();
00439         if ( $content )
00440         {
00441             $defaultName = $classAttribute->attribute( 'data_text1' );
00442             $defaultRowCount = $classAttribute->attribute( 'data_int1' );
00443             $columns = $content->attribute( 'columns' );
00444 
00445             $dom = $attributeParametersNode->ownerDocument;
00446             $defaultNameNode = $dom->createElement( 'default-name' );
00447             $defaultNameNode->appendChild( $dom->createTextNode( $defaultName ) );
00448             $attributeParametersNode->appendChild( $defaultNameNode );
00449             $defaultRowCountNode = $dom->createElement( 'default-row-count' );
00450             $defaultRowCountNode->appendChild( $dom->createTextNode( $defaultRowCount ) );
00451             $attributeParametersNode->appendChild( $defaultRowCountNode );
00452             $columnsNode = $dom->createElement( 'columns' );
00453             $attributeParametersNode->appendChild( $columnsNode );
00454             foreach ( $columns as $column )
00455             {
00456                 unset( $columnNode );
00457                 $columnNode = $dom->createElement( 'column' );
00458                 $columnNode->setAttribute( 'name', $column['name'] );
00459                 $columnNode->setAttribute( 'identifier', $column['identifier'] );
00460                 $columnNode->setAttribute( 'index', $column['index'] );
00461                 $columnsNode->appendChild( $columnNode );
00462             }
00463         }
00464     }
00465 
00466     function unserializeContentClassAttribute( $classAttribute, $attributeNode, $attributeParametersNode )
00467     {
00468         $defaultName = $attributeParametersNode->getElementsByTagName( 'default-name' )->item( 0 )->textContent;
00469         $defaultRowCount = $attributeParametersNode->getElementsByTagName( 'default-row-count' )->item( 0 )->textContent;
00470         $classAttribute->setAttribute( 'data_text1', $defaultName );
00471         $classAttribute->setAttribute( 'data_int1', $defaultRowCount );
00472 
00473         $matrixDefinition = new eZMatrixDefinition();
00474         $columnsNode = $attributeParametersNode->getElementsByTagName( 'columns' )->item( 0 );
00475         $columnsList = $columnsNode->getElementsByTagName( 'column' );
00476         foreach ( $columnsList  as $columnNode )
00477         {
00478             $columnName = $columnNode->getAttribute( 'name' );
00479             $columnIdentifier = $columnNode->getAttribute( 'identifier' );
00480             $matrixDefinition->addColumn( $columnName, $columnIdentifier );
00481         }
00482         $classAttribute->setContent( $matrixDefinition );
00483     }
00484 
00485     function serializeContentObjectAttribute( $package, $objectAttribute )
00486     {
00487         $node = $this->createContentObjectAttributeDOMNode( $objectAttribute );
00488 
00489         $dom = new DOMDocument( '1.0', 'utf-8' );
00490         $success = $dom->loadXML( $objectAttribute->attribute( 'data_text' ) );
00491 
00492         $importedRoot = $node->ownerDocument->importNode( $dom->documentElement, true );
00493         $node->appendChild( $importedRoot );
00494 
00495         return $node;
00496     }
00497 
00498     function unserializeContentObjectAttribute( $package, $objectAttribute, $attributeNode )
00499     {
00500         $rootNode = $attributeNode->getElementsByTagName( 'ezmatrix' )->item( 0 );
00501         $xmlString = $rootNode ? $rootNode->ownerDocument->saveXML( $rootNode ) : '';
00502         $objectAttribute->setAttribute( 'data_text', $xmlString );
00503     }
00504 
00505     function supportsBatchInitializeObjectAttribute()
00506     {
00507         return true;
00508     }
00509 
00510     function batchInitializeObjectAttributeData( $classAttribute )
00511     {
00512         $numRows = $classAttribute->attribute( 'data_int1' );
00513         $matrix = new eZMatrix( '', $numRows, $classAttribute->attribute( 'content' ) );
00514         $db = eZDB::instance();
00515         return array( 'data_text' => "'" . $db->escapeString( $matrix->xmlString() ) . "'" );
00516     }
00517 }
00518 
00519 eZDataType::register( eZMatrixType::DATA_TYPE_STRING, 'ezmatrixtype' );
00520 
00521 ?>