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