eZ Publish  [trunk]
ezmatrix.php
Go to the documentation of this file.
00001 <?php
00002 /**
00003  * File containing the eZMatrix 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 eZMatrix ezmatrix.php
00013   \ingroup eZDatatype
00014   \brief The class eZMatrix does
00015 
00016 */
00017 
00018 class eZMatrix
00019 {
00020     /*!
00021      Constructor
00022     */
00023     function eZMatrix( $name, $numRows = false, $matrixColumnDefinition = false )
00024     {
00025         $this->Name = $name;
00026         $this->Matrix = array();
00027 
00028         if ( $numRows !== false &&  $matrixColumnDefinition !== false )
00029         {
00030             $columns = $matrixColumnDefinition->attribute( 'columns' );
00031             $numColumns = count( $columns );
00032             $this->NumColumns = $numColumns;
00033 
00034             $sequentialColumns = array();
00035             foreach ( $columns as $column )
00036             {
00037                 $sequentialColumns[] = array( 'identifier' => $column['identifier'],
00038                                               'index' => $column['index'],
00039                                               'name' => $column['name'] );
00040 
00041             }
00042             $this->Matrix['columns'] = array();
00043             $this->Matrix['columns']['sequential'] = $sequentialColumns;
00044 
00045             $this->NumRows = $numRows;
00046             $cells = array();
00047             for ( $i = 0; $i < $numColumns; ++$i )
00048             {
00049                 for ( $j = 0; $j < $numRows; ++$j )
00050                 {
00051                     $cells[] = '';
00052                 }
00053             }
00054             $this->Cells = $cells;
00055 
00056 
00057             $xmlString = $this->xmlString();
00058             $this->decodeXML( $xmlString );
00059         }
00060     }
00061 
00062     /*!
00063         Check if column index differs, and so, set new index.
00064 
00065         \param columnIndex internal column index
00066         \param newColumnIndex new column index
00067 
00068         \return true if index differs
00069     */
00070     function adjustColumnIndex( $columnIndex, $newColumnIndex )
00071     {
00072         $matrix = $this->attribute( 'matrix' );
00073         $columnDefinition = $matrix['columns']['sequential'][$columnIndex];
00074         if ( $columnDefinition['index'] != $newColumnIndex )
00075         {
00076             $this->setColumnIndex( $columnIndex, $newColumnIndex );
00077             return true;
00078         }
00079         return false;
00080     }
00081 
00082     /*!
00083         Sets column's index to \a $newColumnIndex.
00084     */
00085     function setColumnIndex( $columnIndex, $newColumnIndex )
00086     {
00087         $this->Matrix['columns']['sequential'][$columnIndex]['index'] = $newColumnIndex;
00088     }
00089 
00090     /*!
00091         Searches in matrix columns with identifiers that in \a $matrixColumnDefinition and
00092         a) if column exists then modification of column attributes is performed ( index, name, etc. );
00093         b) if column doesn't exist then new column will be created.
00094     */
00095     protected function updateColumns( $matrixColumnDefinition )
00096     {
00097         $matrixWasModified = false;
00098 
00099         if ( $matrixColumnDefinition && $matrixColumnDefinition !== false )
00100         {
00101             $columns = $matrixColumnDefinition->attribute( 'columns' );
00102             foreach ( $columns as $column )
00103             {
00104                 $columnIndex = $this->columnIndex( $column['identifier'] );
00105                 if ( $columnIndex !== false )
00106                 {
00107                     $matrixWasModified |= $this->adjustColumnName( $columnIndex, $column['name'] );
00108                     $matrixWasModified |= $this->adjustColumnIndex( $columnIndex, $column['index'] );
00109                 }
00110                 else
00111                 {
00112                     $matrixWasModified |= $this->addColumn( $column );
00113                 }
00114             }
00115         }
00116         return $matrixWasModified;
00117     }
00118 
00119     /*!
00120         Adds column \a $columnDefinition to eZMatrix object.
00121     */
00122     function addColumn( $columnDefinition )
00123     {
00124         $this->addColumnToMatrix( $columnDefinition );
00125         $this->addColumnToCells( $columnDefinition );
00126         return true;
00127     }
00128 
00129     /*!
00130         Adds column \a $columnDefinition to 'matrix' member of eZMatrix.
00131     */
00132     function addColumnToMatrix( $columnDefinition )
00133     {
00134         $newColumn  = array( 'identifier'   => $columnDefinition['identifier'],
00135                              'index'        => $columnDefinition['index'],
00136                              'name'         => $columnDefinition['name'] );
00137 
00138         array_splice( $this->Matrix['columns']['sequential'], $columnDefinition['index'], 0, array( $newColumn ) );
00139     }
00140 
00141     /*!
00142         Adds column \a $columnDefinition to 'cells' member of eZMatrix.
00143     */
00144     function addColumnToCells( $columnDefinition )
00145     {
00146         $cells = $this->attribute( 'cells' );
00147         $columnCount = $this->attribute( 'columnCount' );
00148         $rowCount = $this->attribute( 'rowCount' );
00149         $pos = $columnDefinition['index'];
00150 
00151         // walk through rows and add elements one by one.
00152         while ( $rowCount > 0 )
00153         {
00154             array_splice( $this->Cells, $pos, 0, '' );
00155             $pos += $columnCount;
00156             --$rowCount;
00157         }
00158     }
00159 
00160     /*!
00161         Check if new column name differs from existing column name, and sets new name.
00162 
00163         \param columnIndex internal column index
00164         \param newColumnName column name
00165 
00166         \return true if name differs
00167     */
00168     function adjustColumnName( $columnIndex, $newColumnName )
00169     {
00170         $matrix = $this->attribute( 'matrix' );
00171         $columnDefinition = $matrix['columns']['sequential'][$columnIndex];
00172         if ( $columnDefinition['name'] != $newColumnName )
00173         {
00174             $this->setColumnName( $columnIndex, $newColumnName );
00175             return true;
00176         }
00177         return false;
00178     }
00179 
00180     /*!
00181         Sets column's name to \a $newColumnName.
00182     */
00183     function setColumnName( $columnIndex, $newColumnName )
00184     {
00185         $this->Matrix['columns']['sequential'][$columnIndex]['name'] = $newColumnName;
00186     }
00187 
00188     /*!
00189         Checks current eZMatrix object against definition.
00190         If columns ids are wrong or
00191            there are additional/redundant columns in definition/eZMatrix object
00192         then current eZMatix object will be adjusted according to \a $matrixColumnDefinition.
00193         Note: if id of some column was changed form "old_id" to "new_id"
00194               then a column with "old_id" will be removed(all data of this column
00195               will be lost) and an empty column with "new_id" will be created.
00196         Returns \a true if adjustment(matrix modification) was performed. Otherwise - \a false.
00197     */
00198     function adjustColumnsToDefinition( $classColumnsDefinition )
00199     {
00200         $matrixWasModified = false;
00201 
00202         $matrixWasModified |= $this->removeUselessColumns( $classColumnsDefinition );
00203         $matrixWasModified |= $this->updateColumns( $classColumnsDefinition );
00204 
00205         if ( $matrixWasModified )
00206         {
00207             $this->reorderColumns();
00208 
00209             $columns          = $classColumnsDefinition->attribute( 'columns' );
00210             $numColumns       =  count( $columns );
00211             $this->NumColumns =  $numColumns;
00212 
00213             $xmlString        = $this->xmlString();
00214             $this->decodeXML( $xmlString );
00215         }
00216 
00217         return $matrixWasModified;
00218     }
00219 
00220     /*!
00221         Create reorder column reference array.
00222     */
00223     function buildReorderRuleForColumn( $columns, $pos )
00224     {
00225         $rule = array( $pos );
00226         $startPos = $pos;
00227 
00228         $column = $columns[$pos];
00229         while( $column['index'] != $startPos )
00230         {
00231             $pos = $column['index'];
00232             $rule[] = $pos;
00233             $column = $columns[$pos];
00234         }
00235 
00236         return $rule;
00237     }
00238 
00239     /*!
00240         Build column reorder rules.
00241     */
00242     function buildReorderRules()
00243     {
00244         $matrix     = $this->attribute( 'matrix' );
00245         $columns    = $matrix['columns']['sequential'];
00246         $rules      = array();
00247         $positions  = array_keys( $columns );
00248 
00249         foreach ( $columns as $pos => $column )
00250         {
00251             if ( $this->hasRuleForColumn( $rules, $pos ) )
00252             {
00253                 continue;
00254             }
00255 
00256             if ( $column['index'] != $pos )
00257             {
00258                 $rules[] = $this->buildReorderRuleForColumn( $columns, $pos );
00259             }
00260         }
00261         return $rules;
00262     }
00263 
00264     function reorderColumns()
00265     {
00266         $rules = $this->buildReorderRules();
00267 
00268         /*
00269             example rule: ( 0, 3, 2, 1 )
00270             reorder way:
00271             move( 1 -> buffer )
00272             move( 2 -> 1 )
00273             move( 3 -> 2 )
00274             move( 0 -> 3 )
00275             move( buffer -> 0 )
00276         */
00277         foreach( $rules as $rule )
00278         {
00279             // last column in rule
00280             $pos = count( $rule ) - 1;
00281 
00282             $column = $this->column( $rule[$pos] );
00283 
00284             while ( $pos != 0 )
00285             {
00286                 $this->copyDataBetweenColumns( $rule[$pos - 1], $rule[$pos]);
00287                 --$pos;
00288             }
00289 
00290             // first column in rule
00291             $this->setColumn( $rule[0], $column );
00292         }
00293     }
00294 
00295     /*!
00296         \a static
00297     */
00298     function hasRuleForColumn( $rules, $pos )
00299     {
00300         foreach ( $rules as $rule )
00301         {
00302             foreach ( $rule as $columnPos )
00303             {
00304                 if ( $columnPos == $pos )
00305                 {
00306                     return true;
00307                 }
00308             }
00309         }
00310         return false;
00311     }
00312 
00313     /*!
00314      Set column data and definition
00315 
00316      \param column index
00317      \param column data and definition
00318     */
00319     function setColumn( $colIdx, $column )
00320     {
00321         $this->setColumnDefinition( $colIdx, $column['columnDefinition'] );
00322         $this->setColumnCellData( $colIdx, $column['cellsData'] );
00323     }
00324 
00325     /*!
00326      Get column data and definition
00327 
00328      \param colIdx column index
00329 
00330      \return column data and definition
00331     */
00332     function column( $colIdx )
00333     {
00334         return array( 'columnDefinition' => $this->columnDefinition( $colIdx ),
00335                       'cellsData' => $this->columnCellsData ( $colIdx ) );
00336     }
00337 
00338     /*!
00339      Set column definition.
00340 
00341      \param colIdx column index
00342      \param columnDefinition column definition
00343     */
00344     protected function setColumnDefinition( $colIdx, $columnDefinition )
00345     {
00346         $this->Matrix['columns']['sequential'][$colIdx] = $columnDefinition;
00347     }
00348 
00349     /*!
00350      Get column definition.
00351 
00352      \param colIdx column index
00353 
00354      \return column definition
00355     */
00356     protected function columnDefinition( $colIdx )
00357     {
00358         $matrix = $this->attribute( 'matrix' );
00359         return $matrix['columns']['sequential'][$colIdx];
00360     }
00361 
00362     /*!
00363      Set column cell data
00364 
00365      \param colIdx column index
00366      \param cellData column definition
00367     */
00368     protected function setColumnCellData( $colIdx, $cellData )
00369     {
00370         $columnCount = $this->attribute( 'columnCount' );
00371         $dataCount = count( $cellData );
00372         $dataOffset = 0;
00373         $cellOffset = $colIdx;
00374 
00375         for( $dataOffset = 0 ; $dataOffset < $dataCount; $dataOffset++ )
00376         {
00377             $this->Cells[$cellOffset] = $cellData[$dataOffset];
00378             $cellOffset += $columnCount;
00379         }
00380     }
00381 
00382     /*!
00383      Get column data
00384 
00385      \param colIdx column index
00386 
00387      \return column data
00388     */
00389     protected function columnCellsData( $colIdx )
00390     {
00391         $retArray = array();
00392         $columnCount = $this->attribute( 'columnCount' );
00393         $rowCount = $this->attribute( 'rowCount' );
00394         $cells = $this->attribute( 'cells' );
00395         $pos = $colIdx;
00396 
00397         // walk through rows and add elements one by one.
00398         while ( $rowCount > 0 )
00399         {
00400             $retArray[] = $cells[$pos];
00401             $pos += $columnCount;
00402             --$rowCount;
00403         }
00404 
00405         return $retArray;
00406     }
00407 
00408     function copyDataBetweenColumns( $firstColIdx, $secondColIdx )
00409     {
00410         $this->copyDefinitionBetweenColumns( $firstColIdx, $secondColIdx );
00411         $this->copyCellsDataBetweenColumns ( $firstColIdx, $secondColIdx );
00412     }
00413 
00414     protected function copyDefinitionBetweenColumns( $col1, $col2 )
00415     {
00416         $this->Matrix['columns']['sequential'][$col2] = $this->Matrix['columns']['sequential'][$col1];
00417     }
00418 
00419     protected function copyCellsDataBetweenColumns ( $firstColIdx, $secondColIdx )
00420     {
00421         $columnCount = $this->attribute( 'columnCount' );
00422         $rowCount = $this->attribute( 'rowCount' );
00423         $firstColPos = $firstColIdx;
00424         $secondColIdx= $secondColIdx;
00425 
00426         // walk through rows and add elements one by one.
00427         while ( $rowCount > 0 )
00428         {
00429             $this->Cells[$secondColIdx] = $this->Cells[$firstColIdx];
00430             $firstColIdx  += $columnCount;
00431             $secondColIdx += $columnCount;
00432             --$rowCount;
00433         }
00434     }
00435 
00436     /*!
00437         Removes columns that are in matrix but not in \a $matrixColumnDefinition
00438 
00439       \return true if matrix was modified.
00440     */
00441     function removeUselessColumns( $matrixColumnDefinition )
00442     {
00443         $columnsToRemove = $this->getColumnsToRemove( $matrixColumnDefinition );
00444 
00445         if ( count( $columnsToRemove ) > 0 )
00446         {
00447             // remove begins from last column (reverse order )
00448             foreach ( array_reverse( $columnsToRemove ) as $column )
00449             {
00450                 $this->removeColumn( $column );
00451             }
00452             return true;
00453         }
00454 
00455         return false;
00456     }
00457 
00458     /*!
00459         Searches columns that are in matrix but not in \a $matrixColumnDefinition.
00460     */
00461     function getColumnsToRemove( $matrixColumnsDefinition )
00462     {
00463         $columnsToRemove = array();
00464         $matrix          = $this->attribute( 'matrix' );
00465         $columns         = $matrix['columns']['sequential'];
00466 
00467         foreach ( $columns as $column )
00468         {
00469             if ( !$this->columnExists( $column, $matrixColumnsDefinition ) )
00470             {
00471                 $columnsToRemove[] = $column;
00472             }
00473         }
00474 
00475         return $columnsToRemove;
00476     }
00477 
00478     /*!
00479      Get internal column index by column indentifier
00480 
00481      \param columnIdent column identifier
00482 
00483      \return column index.
00484     */
00485     protected function columnIndex( $columnIdent )
00486     {
00487         $matrix = $this->attribute( 'matrix' );
00488         $columns = $matrix['columns']['sequential'];
00489 
00490         foreach( $columns as $key => $column )
00491         {
00492             if ( $column['identifier'] == $columnIdent )
00493             {
00494                 return $key;
00495             }
00496         }
00497 
00498         return false;
00499     }
00500 
00501     /*!
00502         Searches column \a $columnToFind in \a $matrixColumnDefinition.
00503         Returns true if found, false - otherwise.
00504     */
00505     protected function columnExists( $columnToFind, $matrixColumnsDefinition )
00506     {
00507         $columns = $matrixColumnsDefinition->attribute( 'columns' );
00508 
00509         foreach ( $columns as $column )
00510         {
00511             if ( $column['identifier'] === $columnToFind['identifier'] )
00512                 return true;
00513         }
00514 
00515         return false;
00516     }
00517 
00518     /*!
00519         Removess column \a $columnDefinition from eZMatrix object.
00520     */
00521     function removeColumn( $columnDefinition )
00522     {
00523         $this->removeColumnFromCells( $columnDefinition );
00524         $this->removeColumnFromMatrix( $columnDefinition );
00525     }
00526 
00527     /*!
00528         Removess column \a $columnDefinition from 'cells' member of eZMatrix.
00529     */
00530     protected function removeColumnFromCells( $columnDefinition )
00531     {
00532         $cells          = $this->attribute( 'cells' );
00533         $rowCount       = $this->attribute( 'rowCount' );
00534         $columnCount    = $this->attribute( 'columnCount' );
00535 
00536         // last position(index) of element to remove in $cells.
00537         $pos =  ( $rowCount - 1 ) * $columnCount + $columnDefinition['index'];
00538 
00539         // walk through rows and remove elements one by one.
00540         while ( $rowCount > 0 )
00541         {
00542             array_splice( $this->Cells, $pos, 1 );
00543             $pos -= $columnCount;
00544             --$rowCount;
00545         }
00546     }
00547 
00548     /*!
00549         Removess column \a $columnDefinition from 'matrix' member of eZMatrix.
00550     */
00551     protected function removeColumnFromMatrix( $columnDefinition )
00552     {
00553         $matrix  = $this->attribute( 'matrix' );
00554         $columns = $matrix['columns']['sequential'];
00555         $pos     = 0;
00556 
00557         foreach ( $columns as $column )
00558         {
00559             if ( $column['identifier'] == $columnDefinition['identifier'] )
00560             {
00561                 array_splice( $this->Matrix['columns']['sequential'], $pos, 1 );
00562                 return true;
00563             }
00564             ++$pos;
00565         }
00566         return false;
00567     }
00568 
00569     /*!
00570      Sets the name of the matrix
00571     */
00572     function setName( $name )
00573     {
00574         $this->Name = $name;
00575     }
00576 
00577     /*!
00578      Returns the name of the matrix.
00579     */
00580     function name()
00581     {
00582         return $this->Name;
00583     }
00584 
00585     function attributes()
00586     {
00587         return array( 'name' ,
00588                       'rows',
00589                       'columns',
00590                       'matrix',
00591                       'cells',
00592                       'rowCount',
00593                       'columnCount' );
00594     }
00595 
00596     function hasAttribute( $name )
00597     {
00598         return in_array( $name, $this->attributes() );
00599     }
00600 
00601     function attribute( $name )
00602     {
00603         switch ( $name )
00604         {
00605             case "name" :
00606             {
00607                 return $this->Name;
00608             }break;
00609             case "matrix" :
00610             {
00611                 return $this->Matrix;
00612             }break;
00613             case "cells" :
00614             {
00615                 return $this->Cells;
00616             }break;
00617             case "rows" :
00618             {
00619                 return $this->Matrix['rows'];
00620             }break;
00621             case "columns" :
00622             {
00623                 return $this->Matrix['columns'];
00624             }break;
00625             case "rowCount" :
00626             {
00627                 return count( $this->Matrix['rows']['sequential'] );
00628             }break;
00629             case "columnCount" :
00630             {
00631                 return count( $this->Matrix['columns']['sequential'] );
00632             }break;
00633             default:
00634             {
00635                 eZDebug::writeError( "Attribute '$name' does not exist", __METHOD__ );
00636                 return null;
00637             }break;
00638         }
00639     }
00640 
00641     function addRow( $beforeIndex = false, $addCount = 1 )
00642     {
00643         $addCount = min( $addCount, 40 );
00644 
00645         for ( $r = $addCount; $r > 0; $r-- )
00646         {
00647             $newCells = array();
00648             $numColumns = $this->attribute( 'columnCount' );
00649             $numRows = $this->attribute( 'rowCount' );
00650             for ( $i = 0; $i < $numColumns; $i++ )
00651             {
00652                 $newCells[] = '';
00653             }
00654             $newRow = array();
00655             $newRow['columns'] = $newCells;
00656             $this->NumRows++;
00657             if ( $beforeIndex === false )
00658             {
00659                 $this->Cells = array_merge( $this->Cells, $newCells );
00660                 $newRow['identifier'] =  'row_' . ( $numRows + 1 );
00661                 $newRow['name'] = 'Row_' . ( $numRows + 1 );
00662                 $this->Matrix['rows']['sequential'][] = $newRow;
00663 
00664             }
00665             else
00666             {
00667                 $insertIndex  = ( $beforeIndex + 1 ) * $numColumns - $numColumns;
00668                 array_splice( $this->Cells, $insertIndex, 0, $newCells );
00669                 $newRow['identifier'] =  'row_' . $beforeIndex;
00670                 $newRow['name'] = 'Row_' . ( $numRows + 1 );
00671                 array_splice( $this->Matrix['rows']['sequential'], $beforeIndex, 0,  array( $newRow ) );
00672 
00673             }
00674         }
00675     }
00676 
00677     function removeRow( $rowNum )
00678     {
00679         $numColumns = $this->attribute( 'columnCount' );
00680         $numRows    = $this->attribute( 'rowCount' );
00681 
00682         array_splice( $this->Cells, $rowNum * $numColumns, $numColumns );
00683         array_splice( $this->Matrix['rows']['sequential'], $rowNum, 1 );
00684         $this->NumRows--;
00685     }
00686 
00687     /*!
00688      Will decode an xml string and initialize the eZ matrix object
00689     */
00690     function decodeXML( $xmlString )
00691     {
00692         $dom = new DOMDocument( '1.0', 'utf-8' );
00693         $success = $dom->loadXML( $xmlString );
00694         if ( $xmlString != "" )
00695         {
00696             // set the name of the node
00697             $nameArray = $dom->getElementsByTagName( "name" );
00698             $this->setName( $nameArray->item( 0 )->textContent );
00699 
00700             $columnsNode = $dom->getElementsByTagName( "columns" )->item( 0 );
00701             $numColumns = $columnsNode->getAttribute( 'number');
00702 
00703             $rowsNode = $dom->getElementsByTagName( "rows" )->item( 0 );
00704             $numRows = $rowsNode->getAttribute( 'number' );
00705 
00706             $namedColumns = $dom->getElementsByTagName( "column" );
00707             $namedColumnList = array();
00708             if ( $namedColumns->length > 0 )
00709             {
00710                 foreach ( $namedColumns as $namedColumn )
00711                 {
00712                     $columnName = $namedColumn->textContent;
00713                     $columnID = $namedColumn->getAttribute( 'id' );
00714                     $columnNumber = $namedColumn->getAttribute( 'num' );
00715                     $namedColumnList[$columnNumber] = array( 'name' => $columnName,
00716                                                              'column_number' => $columnNumber,
00717                                                              'column_id' => $columnID );
00718                 }
00719             }
00720             $cellNodes = $dom->getElementsByTagName( "c" );
00721             $cellList = array();
00722             foreach ( $cellNodes as $cellNode )
00723             {
00724                 $cellList[] = $cellNode->textContent;
00725             }
00726 
00727             $rows = array( 'sequential' => array() );
00728             $sequentialRows = array();
00729 
00730             for ( $i = 1; $i <= $numRows; $i++ )
00731             {
00732                 $row = array( 'identifier' => 'row_' . $i ,
00733                               'name' => 'Row_' . $i );
00734                 $rowColumns = array();
00735                 for ( $j = 1; $j <= $numColumns; $j++ )
00736                 {
00737                     $rowColumns[] = $cellList[ ($i-1) * $numColumns + $j-1];
00738                 }
00739                 $row['columns'] = $rowColumns;
00740                 $sequentialRows[] = $row;
00741             }
00742             $rows['sequential'] = $sequentialRows;
00743 
00744             $columns = array( 'sequential' => array(),
00745                               'id' => array() );
00746             $sequentialColumns = array();
00747             $idColumns = array();
00748 
00749             for ( $i = 0; $i < $numColumns; $i++ )
00750             {
00751                 if ( isset( $column ) )
00752                     unset( $column );
00753                 $column = array();
00754                 if ( isset( $namedColumnList[$i] ) && is_array( $namedColumnList[$i] ) )
00755                 {
00756                     $column = array( 'identifier' => $namedColumnList[$i]['column_id'],
00757                                      'index' => $i,
00758                                      'name' => $namedColumnList[$i]['name'] );
00759                 }
00760                 else
00761                 {
00762                     $column = array( 'identifier' => 'col_' . ($i + 1),
00763                                      'index' => $i,
00764                                      'name' => 'Col_' . ($i + 1) );
00765 
00766                 }
00767 
00768                 $columnRows = array();
00769                 for( $j = 0; $j < $numRows; $j++ )
00770                 {
00771                     $columnRows[] = $sequentialRows[$j]['columns'][$i];
00772                 }
00773                 $column['rows'] = $columnRows;
00774                 $sequentialColumns[] = $column;
00775                 $idColumns[$column['identifier']] = $column;
00776             }
00777             $columns['sequential'] = $sequentialColumns;
00778             $columns['id'] = $idColumns;
00779 
00780             $matrix = array( 'rows' => $rows,
00781                              'columns' => $columns,
00782                              'cells' => $cellList );
00783 
00784             $this->Matrix = $matrix;
00785             $this->NumRows = $numRows;
00786             $this->NumColumns = $numColumns;
00787             $this->Cells = $cellList;
00788         }
00789         else
00790         {
00791             $this->Cells = array();
00792             $this->Matrix = array();
00793         }
00794     }
00795     /*!
00796      \return the XML structure in \a $domDocument as text.
00797              It will take of care of the necessary charset conversions
00798              for content storage.
00799     */
00800     function domString( $domDocument )
00801     {
00802         $ini = eZINI::instance();
00803         $xmlCharset = $ini->variable( 'RegionalSettings', 'ContentXMLCharset' );
00804         if ( $xmlCharset == 'enabled' )
00805         {
00806             $charset = eZTextCodec::internalCharset();
00807         }
00808         else if ( $xmlCharset == 'disabled' )
00809             $charset = true;
00810         else
00811             $charset = $xmlCharset;
00812         if ( $charset !== true )
00813         {
00814             $charset = eZCharsetInfo::realCharsetCode( $charset );
00815         }
00816         $domString = $domDocument->saveXML();
00817         return $domString;
00818     }
00819 
00820     /*!
00821      Will return the XML string for this matrix.
00822     */
00823     function xmlString()
00824     {
00825         $doc = new DOMDocument( '1.0', 'utf-8' );
00826         $root = $doc->createElement( "ezmatrix" );
00827         $doc->appendChild( $root );
00828 
00829         $name = $doc->createElement( "name", $this->Name );
00830         $root->appendChild( $name );
00831 
00832         $columnsNode = $doc->createElement( "columns" );
00833 
00834         $sequentalColumns = $this->Matrix['columns']['sequential'];
00835         $columnAmount = $this->NumColumns;
00836         $columnsNode->setAttribute( 'number', $columnAmount );
00837         $root->appendChild( $columnsNode );
00838 
00839         if ( $sequentalColumns != null )
00840         {
00841             for( $i = 0; $i < $columnAmount; $i++ )
00842             {
00843                 $column = $sequentalColumns[$i];
00844                 if ( $column != null && $column['identifier'] != 'col_' . ($i+1) )
00845                 {
00846                     unset( $columnNode );
00847                     $columnNode = $doc->createElement( 'column' );
00848                     $columnNode->appendChild( $doc->createTextNode( $column['name'] ) );
00849                     $columnNode->setAttribute( 'num', $i );
00850                     $columnNode->setAttribute( 'id', $column['identifier'] );
00851 
00852                     $columnsNode->appendChild( $columnNode );
00853                 }
00854             }
00855 
00856         }
00857 
00858         $rowsNode =  $doc->createElement( "rows" );
00859         $rowAmount = $this->NumRows;
00860 
00861         $rowsNode->setAttribute( 'number', $rowAmount );
00862 
00863         $root->appendChild( $rowsNode );
00864 
00865         foreach ( $this->Cells as $cell )
00866         {
00867             unset( $cellNode );
00868             $cellNode = $doc->createElement( 'c' );
00869             $cellNode->appendChild( $doc->createTextNode( $cell ) );
00870 
00871             $root->appendChild( $cellNode );
00872         }
00873 
00874         return $this->domString( $doc );
00875     }
00876 
00877     /// Contains the Matrix name
00878     public $Name;
00879 
00880     /// Contains the Matrix array
00881     public $Matrix;
00882 
00883     /// Contains the number of columns
00884     public $NumColumns;
00885 
00886     /// Contains the number of rows
00887 
00888     public $NumRows;
00889     public $Cells;
00890 }
00891 
00892 ?>