|
eZ Publish
[trunk]
|
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 ?>