PHPExcel
[ class tree: PHPExcel ] [ index: PHPExcel ] [ all elements ]

Source for file ReferenceHelper.php

Documentation is available at ReferenceHelper.php

  1. <?php
  2. /**
  3.  * PHPExcel
  4.  *
  5.  * Copyright (c) 2006 - 2010 PHPExcel
  6.  *
  7.  * This library is free software; you can redistribute it and/or
  8.  * modify it under the terms of the GNU Lesser General Public
  9.  * License as published by the Free Software Foundation; either
  10.  * version 2.1 of the License, or (at your option) any later version.
  11.  *
  12.  * This library is distributed in the hope that it will be useful,
  13.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  15.  * Lesser General Public License for more details.
  16.  *
  17.  * You should have received a copy of the GNU Lesser General Public
  18.  * License along with this library; if not, write to the Free Software
  19.  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
  20.  *
  21.  * @category   PHPExcel
  22.  * @package    PHPExcel
  23.  * @copyright  Copyright (c) 2006 - 2010 PHPExcel (http://www.codeplex.com/PHPExcel)
  24.  * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt    LGPL
  25.  * @version    1.7.3c, 2010-06-01
  26.  */
  27.  
  28.  
  29. /**
  30.  * PHPExcel_ReferenceHelper (Singleton)
  31.  *
  32.  * @category   PHPExcel
  33.  * @package    PHPExcel
  34.  * @copyright  Copyright (c) 2006 - 2010 PHPExcel (http://www.codeplex.com/PHPExcel)
  35.  */
  36. {
  37.     /**
  38.      * Instance of this class
  39.      *
  40.      * @var PHPExcel_ReferenceHelper 
  41.      */
  42.     private static $_instance;
  43.  
  44.     /**
  45.      * Get an instance of this class
  46.      *
  47.      * @return PHPExcel_ReferenceHelper 
  48.      */
  49.     public static function getInstance({
  50.         if (!isset(self::$_instance|| is_null(self::$_instance)) {
  51.             self::$_instance new PHPExcel_ReferenceHelper();
  52.         }
  53.  
  54.         return self::$_instance;
  55.     }
  56.  
  57.     /**
  58.      * Create a new PHPExcel_ReferenceHelper
  59.      */
  60.     protected function __construct({
  61.     }
  62.  
  63.     /**
  64.      * Insert a new column, updating all possible related data
  65.      *
  66.      * @param    int    $pBefore    Insert before this one
  67.      * @param    int    $pNumCols    Number of columns to insert
  68.      * @param    int    $pNumRows    Number of rows to insert
  69.      * @throws    Exception
  70.      */
  71.     public function insertNewBefore($pBefore 'A1'$pNumCols 0$pNumRows 0PHPExcel_Worksheet $pSheet null{
  72.         $aCellCollection $pSheet->getCellCollection();
  73.  
  74.         // Get coordinates of $pBefore
  75.         $beforeColumn    'A';
  76.         $beforeRow        1;
  77.         list($beforeColumn$beforeRowPHPExcel_Cell::coordinateFromString$pBefore );
  78.  
  79.  
  80.         // Clear cells if we are removing columns or rows
  81.         $highestColumn    $pSheet->getHighestColumn();
  82.         $highestRow    $pSheet->getHighestRow();
  83.  
  84.         // 1. Clear column strips if we are removing columns
  85.         if ($pNumCols && PHPExcel_Cell::columnIndexFromString($beforeColumn$pNumCols 0{
  86.             for ($i 1$i <= $highestRow 1++$i{
  87.                 for ($j PHPExcel_Cell::columnIndexFromString($beforeColumn$pNumCols$j <= PHPExcel_Cell::columnIndexFromString($beforeColumn2++$j{
  88.                     $coordinate PHPExcel_Cell::stringFromColumnIndex($j$i;
  89.                     $pSheet->removeConditionalStyles($coordinate);
  90.                     if ($pSheet->cellExists($coordinate)) {
  91.                         $pSheet->getCell($coordinate)->setValueExplicit(''PHPExcel_Cell_DataType::TYPE_NULL);
  92.                         $pSheet->getCell($coordinate)->setXfIndex(0);
  93.                     }
  94.                 }
  95.             }
  96.         }
  97.  
  98.         // 2. Clear row strips if we are removing rows
  99.         if ($pNumRows && $beforeRow $pNumRows 0{
  100.             for ($i PHPExcel_Cell::columnIndexFromString($beforeColumn1$i <= PHPExcel_Cell::columnIndexFromString($highestColumn1++$i{
  101.                 for ($j $beforeRow $pNumRows$j <= $beforeRow 1++$j{
  102.                     $coordinate PHPExcel_Cell::stringFromColumnIndex($i$j;
  103.                     $pSheet->removeConditionalStyles($coordinate);
  104.                     if ($pSheet->cellExists($coordinate)) {
  105.                         $pSheet->getCell($coordinate)->setValueExplicit(''PHPExcel_Cell_DataType::TYPE_NULL);
  106.                         $pSheet->getCell($coordinate)->setXfIndex(0);
  107.                     }
  108.                 }
  109.             }
  110.         }
  111.  
  112.  
  113.         // Loop through cells, bottom-up, and change cell coordinates
  114.         while (($cellID ($pNumCols || $pNumRows 0array_shift($aCellCollectionarray_pop($aCellCollection))) {
  115.             $cell $pSheet->getCell($cellID);
  116.  
  117.             // New coordinates
  118.             $newCoordinates PHPExcel_Cell::stringFromColumnIndexPHPExcel_Cell::columnIndexFromString($cell->getColumn()) $pNumCols ($cell->getRow($pNumRows);
  119.  
  120.             // Should the cell be updated? Move value and cellXf index from one cell to another.
  121.             if (
  122.                     (PHPExcel_Cell::columnIndexFromString$cell->getColumn() ) >= PHPExcel_Cell::columnIndexFromString($beforeColumn)) &&
  123.                     ($cell->getRow(>= $beforeRow)
  124.                  {
  125.  
  126.                 // Update cell styles
  127.                 $pSheet->getCell($newCoordinates)->setXfIndex($cell->getXfIndex());
  128.                 $cell->setXfIndex(0);
  129.  
  130.                 // Insert this cell at its new location
  131.                 if ($cell->getDataType(== PHPExcel_Cell_DataType::TYPE_FORMULA{
  132.                     // Formula should be adjusted
  133.                     $pSheet->getCell($newCoordinates)
  134.                         ->setValue($this->updateFormulaReferences($cell->getValue()$pBefore$pNumCols$pNumRows));
  135.                 else {
  136.                     // Formula should not be adjusted
  137.                     $pSheet->getCell($newCoordinates)->setValue($cell->getValue());
  138.                 }
  139.  
  140.                 // Clear the original cell
  141.                 $pSheet->getCell($cell->getCoordinate())->setValue('');
  142.             }
  143.         }
  144.  
  145.  
  146.         // Duplicate styles for the newly inserted cells
  147.         $highestColumn    $pSheet->getHighestColumn();
  148.         $highestRow    $pSheet->getHighestRow();
  149.  
  150.         if ($pNumCols && PHPExcel_Cell::columnIndexFromString($beforeColumn0{
  151.             for ($i $beforeRow$i <= $highestRow 1++$i{
  152.  
  153.                 // Style
  154.                 $coordinate PHPExcel_Cell::stringFromColumnIndexPHPExcel_Cell::columnIndexFromString($beforeColumn$i;
  155.                 if ($pSheet->cellExists($coordinate)) {
  156.                     $xfIndex $pSheet->getCell($coordinate)->getXfIndex();
  157.                     $conditionalStyles $pSheet->conditionalStylesExists($coordinate?
  158.                         $pSheet->getConditionalStyles($coordinatefalse;
  159.                     for ($j PHPExcel_Cell::columnIndexFromString($beforeColumn1$j <= PHPExcel_Cell::columnIndexFromString($beforeColumn$pNumCols++$j{
  160.                         $pSheet->getCellByColumnAndRow($j$i)->setXfIndex($xfIndex);
  161.                         if ($conditionalStyles{
  162.                             $cloned array();
  163.                             foreach ($conditionalStyles as $conditionalStyle{
  164.                                 $cloned[clone $conditionalStyle;
  165.                             }
  166.                             $pSheet->setConditionalStyles(PHPExcel_Cell::stringFromColumnIndex($j$i$cloned);
  167.                         }
  168.                     }
  169.                 }
  170.  
  171.             }
  172.         }
  173.  
  174.         if ($pNumRows && $beforeRow 0{
  175.             for ($i PHPExcel_Cell::columnIndexFromString($beforeColumn1$i <= PHPExcel_Cell::columnIndexFromString($highestColumn1++$i{
  176.  
  177.                 // Style
  178.                 $coordinate PHPExcel_Cell::stringFromColumnIndex($i($beforeRow 1);
  179.                 if ($pSheet->cellExists($coordinate)) {
  180.                     $xfIndex $pSheet->getCell($coordinate)->getXfIndex();
  181.                     $conditionalStyles $pSheet->conditionalStylesExists($coordinate?
  182.                         $pSheet->getConditionalStyles($coordinatefalse;
  183.                     for ($j $beforeRow$j <= $beforeRow $pNumRows++$j{
  184.                         $pSheet->getCell(PHPExcel_Cell::stringFromColumnIndex($i$j)->setXfIndex($xfIndex);
  185.                         if ($conditionalStyles{
  186.                             $cloned array();
  187.                             foreach ($conditionalStyles as $conditionalStyle{
  188.                                 $cloned[clone $conditionalStyle;
  189.                             }
  190.                             $pSheet->setConditionalStyles(PHPExcel_Cell::stringFromColumnIndex($i$j$cloned);
  191.                         }
  192.                     }
  193.                 }
  194.             }
  195.         }
  196.  
  197.  
  198.         // Update worksheet: column dimensions
  199.         $aColumnDimensions array_reverse($pSheet->getColumnDimensions()true);
  200.         if (count($aColumnDimensions0{
  201.             foreach ($aColumnDimensions as $objColumnDimension{
  202.                 $newReference $this->updateCellReference($objColumnDimension->getColumnIndex('1'$pBefore$pNumCols$pNumRows);
  203.                 list($newReferencePHPExcel_Cell::coordinateFromString($newReference);
  204.                 if ($objColumnDimension->getColumnIndex(!= $newReference{
  205.                     $objColumnDimension->setColumnIndex($newReference);
  206.                 }
  207.             }
  208.             $pSheet->refreshColumnDimensions();
  209.         }
  210.  
  211.  
  212.         // Update worksheet: row dimensions
  213.         $aRowDimensions array_reverse($pSheet->getRowDimensions()true);
  214.         if (count($aRowDimensions0{
  215.             foreach ($aRowDimensions as $objRowDimension{
  216.                 $newReference $this->updateCellReference('A' $objRowDimension->getRowIndex()$pBefore$pNumCols$pNumRows);
  217.                 list($newReferencePHPExcel_Cell::coordinateFromString($newReference);
  218.                 if ($objRowDimension->getRowIndex(!= $newReference{
  219.                     $objRowDimension->setRowIndex($newReference);
  220.                 }
  221.             }
  222.             $pSheet->refreshRowDimensions();
  223.  
  224.             $copyDimension $pSheet->getRowDimension($beforeRow 1);
  225.             for ($i $beforeRow$i <= $beforeRow $pNumRows++$i{
  226.                 $newDimension $pSheet->getRowDimension($i);
  227.                 $newDimension->setRowHeight($copyDimension->getRowHeight());
  228.                 $newDimension->setVisible($copyDimension->getVisible());
  229.                 $newDimension->setOutlineLevel($copyDimension->getOutlineLevel());
  230.                 $newDimension->setCollapsed($copyDimension->getCollapsed());
  231.             }
  232.         }
  233.  
  234.  
  235.         // Update worksheet: breaks
  236.         $aBreaks array_reverse($pSheet->getBreaks()true);
  237.         foreach ($aBreaks as $key => $value{
  238.             $newReference $this->updateCellReference($key$pBefore$pNumCols$pNumRows);
  239.             if ($key != $newReference{
  240.                 $pSheet->setBreak$newReference$value );
  241.                 $pSheet->setBreak$keyPHPExcel_Worksheet::BREAK_NONE );
  242.             }
  243.         }
  244.  
  245.  
  246.         // Update worksheet: hyperlinks
  247.         $aHyperlinkCollection array_reverse($pSheet->getHyperlinkCollection()true);
  248.         foreach ($aHyperlinkCollection as $key => $value{
  249.             $newReference $this->updateCellReference($key$pBefore$pNumCols$pNumRows);
  250.             if ($key != $newReference{
  251.                 $pSheet->setHyperlink$newReference$value );
  252.                 $pSheet->setHyperlink$keynull );
  253.             }
  254.         }
  255.  
  256.  
  257.         // Update worksheet: data validations
  258.         $aDataValidationCollection array_reverse($pSheet->getDataValidationCollection()true);
  259.         foreach ($aDataValidationCollection as $key => $value{
  260.             $newReference $this->updateCellReference($key$pBefore$pNumCols$pNumRows);
  261.             if ($key != $newReference{
  262.                 $pSheet->setDataValidation$newReference$value );
  263.                 $pSheet->setDataValidation$keynull );
  264.             }
  265.         }
  266.  
  267.  
  268.         // Update worksheet: merge cells
  269.         $aMergeCells $pSheet->getMergeCells();
  270.         $aNewMergeCells array()// the new array of all merge cells
  271.         foreach ($aMergeCells as $key => &$value{
  272.             $newReference $this->updateCellReference($key$pBefore$pNumCols$pNumRows);
  273.             $aNewMergeCells[$newReference$newReference;
  274.         }
  275.         $pSheet->setMergeCells($aNewMergeCells)// replace the merge cells array
  276.  
  277.  
  278.         // Update worksheet: protected cells
  279.         $aProtectedCells array_reverse($pSheet->getProtectedCells()true);
  280.         foreach ($aProtectedCells as $key => $value{
  281.             $newReference $this->updateCellReference($key$pBefore$pNumCols$pNumRows);
  282.             if ($key != $newReference{
  283.                 $pSheet->protectCells$newReference$valuetrue );
  284.                 $pSheet->unprotectCells$key );
  285.             }
  286.         }
  287.  
  288.  
  289.         // Update worksheet: autofilter
  290.         if ($pSheet->getAutoFilter(!= ''{
  291.             $pSheet->setAutoFilter$this->updateCellReference($pSheet->getAutoFilter()$pBefore$pNumCols$pNumRows) );
  292.         }
  293.  
  294.  
  295.         // Update worksheet: freeze pane
  296.         if ($pSheet->getFreezePane(!= ''{
  297.             $pSheet->freezePane$this->updateCellReference($pSheet->getFreezePane()$pBefore$pNumCols$pNumRows) );
  298.         }
  299.  
  300.  
  301.         // Page setup
  302.         if ($pSheet->getPageSetup()->isPrintAreaSet()) {
  303.             $pSheet->getPageSetup()->setPrintArea$this->updateCellReference($pSheet->getPageSetup()->getPrintArea()$pBefore$pNumCols$pNumRows) );
  304.         }
  305.  
  306.  
  307.         // Update worksheet: drawings
  308.         $aDrawings $pSheet->getDrawingCollection();
  309.         foreach ($aDrawings as $objDrawing{
  310.             $newReference $this->updateCellReference($objDrawing->getCoordinates()$pBefore$pNumCols$pNumRows);
  311.             if ($objDrawing->getCoordinates(!= $newReference{
  312.                 $objDrawing->setCoordinates($newReference);
  313.             }
  314.         }
  315.  
  316.  
  317.         // Update workbook: named ranges
  318.         if (count($pSheet->getParent()->getNamedRanges()) 0{
  319.             foreach ($pSheet->getParent()->getNamedRanges(as $namedRange{
  320.                 if ($namedRange->getWorksheet()->getHashCode(== $pSheet->getHashCode()) {
  321.                     $namedRange->setRange(
  322.                         $this->updateCellReference($namedRange->getRange()$pBefore$pNumCols$pNumRows)
  323.                     );
  324.                 }
  325.             }
  326.         }
  327.  
  328.         // Garbage collect
  329.         $pSheet->garbageCollect();
  330.     }
  331.  
  332.     /**
  333.      * Update references within formulas
  334.      *
  335.      * @param    string    $pFormula    Formula to update
  336.      * @param    int        $pBefore    Insert before this one
  337.      * @param    int        $pNumCols    Number of columns to insert
  338.      * @param    int        $pNumRows    Number of rows to insert
  339.      * @return    string    Updated formula
  340.      * @throws    Exception
  341.      */
  342.     public function updateFormulaReferences($pFormula ''$pBefore 'A1'$pNumCols 0$pNumRows 0{
  343.         // Parse formula into a tree of tokens
  344.         $tokenisedFormula PHPExcel_Calculation::getInstance()->parseFormula($pFormula);
  345.  
  346.         $newCellTokens $cellTokens array();
  347.         $adjustCount 0;
  348.         //    Build the translation table of cell tokens
  349.         foreach($tokenisedFormula as $token{
  350.             $token $token['value'];
  351.             if (preg_match('/^'.PHPExcel_Calculation::CALCULATION_REGEXP_CELLREF.'$/i'$token$matches)) {
  352.                 list($column,$rowPHPExcel_Cell::coordinateFromString($token);
  353.                 //    Max worksheet size is 1,048,576 rows by 16,384 columns in Excel 2007, so our adjustments need to be at least one digit more
  354.                 $column PHPExcel_Cell::columnIndexFromString($column100000;
  355.                 $row += 10000000;
  356.                 $cellIndex $column.$row;
  357.                 if (!isset($cellTokens[$cellIndex])) {
  358.                     $newReference $this->updateCellReference($token$pBefore$pNumCols$pNumRows);
  359.                     if ($newReference !== $token{
  360.                         $newCellTokens[$cellIndexpreg_quote($newReference);
  361.                         $cellTokens[$cellIndex'/(?<![A-Z])'.preg_quote($token).'(?!\d)/i';
  362.                         ++$adjustCount;
  363.                     }
  364.                 }
  365.             }
  366.         }
  367.         if ($adjustCount == 0{
  368.             return $pFormula;
  369.         }
  370.         krsort($cellTokens);
  371.         krsort($newCellTokens);
  372.  
  373.         //    Update cell references in the formula
  374.         $formulaBlocks explode('"',$pFormula);
  375.         foreach($formulaBlocks as $i => &$formulaBlock{
  376.             //    Only count/replace in alternate array entries
  377.             if (($i 2== 0{
  378.                 $formulaBlock preg_replace($cellTokens,$newCellTokens,$formulaBlock);
  379.             }
  380.         }
  381.         unset($formulaBlock);
  382.  
  383.         //    Then rebuild the formula string
  384.         return implode('"',$formulaBlocks);
  385.     }
  386.  
  387.     /**
  388.      * Update cell reference
  389.      *
  390.      * @param    string    $pCellRange            Cell range
  391.      * @param    int        $pBefore            Insert before this one
  392.      * @param    int        $pNumCols            Number of columns to increment
  393.      * @param    int        $pNumRows            Number of rows to increment
  394.      * @return    string    Updated cell range
  395.      * @throws    Exception
  396.      */
  397.     public function updateCellReference($pCellRange 'A1'$pBefore 'A1'$pNumCols 0$pNumRows 0{
  398.         // Is it in another worksheet? Will not have to update anything.
  399.         if (strpos($pCellRange"!"!== false{
  400.             return $pCellRange;
  401.         // Is it a range or a single cell?
  402.         elseif (strpos($pCellRange':'=== false && strpos($pCellRange','=== false{
  403.             // Single cell
  404.             return $this->_updateSingleCellReference($pCellRange$pBefore$pNumCols$pNumRows);
  405.         elseif (strpos($pCellRange':'!== false || strpos($pCellRange','!== false{
  406.             // Range
  407.             return $this->_updateCellRange($pCellRange$pBefore$pNumCols$pNumRows);
  408.         else {
  409.             // Return original
  410.             return $pCellRange;
  411.         }
  412.     }
  413.  
  414.     /**
  415.      * Update named formulas (i.e. containing worksheet references / named ranges)
  416.      *
  417.      * @param PHPExcel $pPhpExcel    Object to update
  418.      * @param string $oldName        Old name (name to replace)
  419.      * @param string $newName        New name
  420.      */
  421.     public function updateNamedFormulas(PHPExcel $pPhpExcel$oldName ''$newName ''{
  422.         if ($oldName == ''{
  423.             return;
  424.         }
  425.  
  426.         foreach ($pPhpExcel->getWorksheetIterator(as $sheet{
  427.             foreach ($sheet->getCellCollection(falseas $cellID{
  428.                 $cell $sheet->getCell($cellID);
  429.                 if (!is_null($cell&& $cell->getDataType(== PHPExcel_Cell_DataType::TYPE_FORMULA{
  430.                     $formula $cell->getValue();
  431.                     if (strpos($formula$oldName!== false{
  432.                         $formula str_replace("'" $oldName "'!""'" $newName "'!"$formula);
  433.                         $formula str_replace($oldName "!"$newName "!"$formula);
  434.                         $cell->setValueExplicit($formulaPHPExcel_Cell_DataType::TYPE_FORMULA);
  435.                     }
  436.                 }
  437.             }
  438.         }
  439.     }
  440.  
  441.     /**
  442.      * Update cell range
  443.      *
  444.      * @param    string    $pCellRange            Cell range
  445.      * @param    int        $pBefore            Insert before this one
  446.      * @param    int        $pNumCols            Number of columns to increment
  447.      * @param    int        $pNumRows            Number of rows to increment
  448.      * @return    string    Updated cell range
  449.      * @throws    Exception
  450.      */
  451.     private function _updateCellRange($pCellRange 'A1:A1'$pBefore 'A1'$pNumCols 0$pNumRows 0{
  452.         if (strpos($pCellRange,':'!== false || strpos($pCellRange','!== false{
  453.             // Update range
  454.             $range PHPExcel_Cell::splitRange($pCellRange);
  455.             for ($i 0$i count($range)++$i{
  456.                 for ($j 0$j count($range[$i])++$j{
  457.                     $range[$i][$j$this->_updateSingleCellReference($range[$i][$j]$pBefore$pNumCols$pNumRows);
  458.                 }
  459.             }
  460.  
  461.             // Recreate range string
  462.             return PHPExcel_Cell::buildRange($range);
  463.         else {
  464.             throw new Exception("Only cell ranges may be passed to this method.");
  465.         }
  466.     }
  467.  
  468.     /**
  469.      * Update single cell reference
  470.      *
  471.      * @param    string    $pCellReference        Single cell reference
  472.      * @param    int        $pBefore            Insert before this one
  473.      * @param    int        $pNumCols            Number of columns to increment
  474.      * @param    int        $pNumRows            Number of rows to increment
  475.      * @return    string    Updated cell reference
  476.      * @throws    Exception
  477.      */
  478.     private function _updateSingleCellReference($pCellReference 'A1'$pBefore 'A1'$pNumCols 0$pNumRows 0{
  479.         if (strpos($pCellReference':'=== false && strpos($pCellReference','=== false{
  480.             // Get coordinates of $pBefore
  481.             $beforeColumn    'A';
  482.             $beforeRow        1;
  483.             list($beforeColumn$beforeRowPHPExcel_Cell::coordinateFromString$pBefore );
  484.  
  485.             // Get coordinates
  486.             $newColumn    'A';
  487.             $newRow    1;
  488.             list($newColumn$newRowPHPExcel_Cell::coordinateFromString$pCellReference );
  489.  
  490.             // Make sure the reference can be used
  491.             if ($newColumn == '' && $newRow == '')
  492.             {
  493.                 return $pCellReference;
  494.             }
  495.  
  496.             // Verify which parts should be updated
  497.             $updateColumn (PHPExcel_Cell::columnIndexFromString($newColumn>= PHPExcel_Cell::columnIndexFromString($beforeColumn))
  498.                             && (strpos($newColumn'$'=== false)
  499.                             && (strpos($beforeColumn'$'=== false);
  500.  
  501.             $updateRow ($newRow >= $beforeRow)
  502.                             && (strpos($newRow'$'=== false)
  503.                             && (strpos($beforeRow'$'=== false);
  504.  
  505.             // Create new column reference
  506.             if ($updateColumn{
  507.                 $newColumn    PHPExcel_Cell::stringFromColumnIndexPHPExcel_Cell::columnIndexFromString($newColumn$pNumCols );
  508.             }
  509.  
  510.             // Create new row reference
  511.             if ($updateRow{
  512.                 $newRow    $newRow $pNumRows;
  513.             }
  514.  
  515.             // Return new reference
  516.             return $newColumn $newRow;
  517.         else {
  518.             throw new Exception("Only single cell references may be passed to this method.");
  519.         }
  520.     }
  521.  
  522.     /**
  523.      * __clone implementation. Cloning should not be allowed in a Singleton!
  524.      *
  525.      * @throws    Exception
  526.      */
  527.     public final function __clone({
  528.         throw new Exception("Cloning a Singleton is not allowed!");
  529.     }
  530. }

Documentation generated on Tue, 01 Jun 2010 17:05:50 +0200 by phpDocumentor 1.4.3