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

Source for file Style.php

Documentation is available at Style.php

  1. <?php
  2. /**
  3.  * PHPExcel
  4.  *
  5.  * Copyright (c) 2006 - 2011 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_Style
  23.  * @copyright  Copyright (c) 2006 - 2011 PHPExcel (http://www.codeplex.com/PHPExcel)
  24.  * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt    LGPL
  25.  * @version    1.7.6, 2011-02-27
  26.  */
  27.  
  28.  
  29. /**
  30.  * PHPExcel_Style
  31.  *
  32.  * @category   PHPExcel
  33.  * @package    PHPExcel_Style
  34.  * @copyright  Copyright (c) 2006 - 2011 PHPExcel (http://www.codeplex.com/PHPExcel)
  35.  */
  36. class PHPExcel_Style implements PHPExcel_IComparable
  37. {
  38.     /**
  39.      * Font
  40.      *
  41.      * @var PHPExcel_Style_Font 
  42.      */
  43.     private $_font;
  44.  
  45.     /**
  46.      * Fill
  47.      *
  48.      * @var PHPExcel_Style_Fill 
  49.      */
  50.     private $_fill;
  51.  
  52.     /**
  53.      * Borders
  54.      *
  55.      * @var PHPExcel_Style_Borders 
  56.      */
  57.     private $_borders;
  58.  
  59.     /**
  60.      * Alignment
  61.      *
  62.      * @var PHPExcel_Style_Alignment 
  63.      */
  64.     private $_alignment;
  65.  
  66.     /**
  67.      * Number Format
  68.      *
  69.      * @var PHPExcel_Style_NumberFormat 
  70.      */
  71.     private $_numberFormat;
  72.  
  73.     /**
  74.      * Conditional styles
  75.      *
  76.      * @var PHPExcel_Style_Conditional[] 
  77.      */
  78.     private $_conditionalStyles;
  79.  
  80.     /**
  81.      * Protection
  82.      *
  83.      * @var PHPExcel_Style_Protection 
  84.      */
  85.     private $_protection;
  86.  
  87.     /**
  88.      * Style supervisor?
  89.      *
  90.      * @var boolean 
  91.      */
  92.     private $_isSupervisor;
  93.  
  94.     /**
  95.      * Parent. Only used for style supervisor
  96.      *
  97.      * @var PHPExcel 
  98.      */
  99.     private $_parent;
  100.  
  101.     /**
  102.      * Index of style in collection. Only used for real style.
  103.      *
  104.      * @var int 
  105.      */
  106.     private $_index;
  107.  
  108.     /**
  109.      * Create a new PHPExcel_Style
  110.      *
  111.      * @param boolean $isSupervisor 
  112.      */
  113.     public function __construct($isSupervisor false)
  114.     {
  115.         // Supervisor?
  116.         $this->_isSupervisor $isSupervisor;
  117.  
  118.         // Initialise values
  119.         $this->_conditionalStyles     array();
  120.         $this->_font                new PHPExcel_Style_Font($isSupervisor);
  121.         $this->_fill                new PHPExcel_Style_Fill($isSupervisor);
  122.         $this->_borders                new PHPExcel_Style_Borders($isSupervisor);
  123.         $this->_alignment            new PHPExcel_Style_Alignment($isSupervisor);
  124.         $this->_numberFormat        new PHPExcel_Style_NumberFormat($isSupervisor);
  125.         $this->_protection            new PHPExcel_Style_Protection($isSupervisor);
  126.  
  127.         // bind parent if we are a supervisor
  128.         if ($isSupervisor{
  129.             $this->_font->bindParent($this);
  130.             $this->_fill->bindParent($this);
  131.             $this->_borders->bindParent($this);
  132.             $this->_alignment->bindParent($this);
  133.             $this->_numberFormat->bindParent($this);
  134.             $this->_protection->bindParent($this);
  135.         }
  136.     }
  137.  
  138.     /**
  139.      * Bind parent. Only used for supervisor
  140.      *
  141.      * @param PHPExcel $parent 
  142.      * @return PHPExcel_Style 
  143.      */
  144.     public function bindParent($parent)
  145.     {
  146.         $this->_parent $parent;
  147.         return $this;
  148.     }
  149.  
  150.     /**
  151.      * Is this a supervisor or a real style component?
  152.      *
  153.      * @return boolean 
  154.      */
  155.     public function getIsSupervisor()
  156.     {
  157.         return $this->_isSupervisor;
  158.     }
  159.  
  160.     /**
  161.      * Get the shared style component for the currently active cell in currently active sheet.
  162.      * Only used for style supervisor
  163.      *
  164.      * @return PHPExcel_Style 
  165.      */
  166.     public function getSharedComponent()
  167.     {
  168.         $activeSheet $this->getActiveSheet();
  169.         $selectedCell $this->getActiveCell()// e.g. 'A1'
  170.  
  171.         if ($activeSheet->cellExists($selectedCell)) {
  172.             $xfIndex $activeSheet->getCell($selectedCell)->getXfIndex();
  173.         else {
  174.             $xfIndex 0;
  175.         }
  176.  
  177.         return $this->_parent->getCellXfByIndex($xfIndex);
  178.     }
  179.  
  180.     /**
  181.      * Get the currently active sheet. Only used for supervisor
  182.      *
  183.      * @return PHPExcel_Worksheet 
  184.      */
  185.     public function getActiveSheet()
  186.     {
  187.         return $this->_parent->getActiveSheet();
  188.     }
  189.  
  190.     /**
  191.      * Get the currently active cell coordinate in currently active sheet.
  192.      * Only used for supervisor
  193.      *
  194.      * @return string E.g. 'A1'
  195.      */
  196.     public function getSelectedCells()
  197.     {
  198.         return $this->_parent->getActiveSheet()->getSelectedCells();
  199.     }
  200.  
  201.     /**
  202.      * Get the currently active cell coordinate in currently active sheet.
  203.      * Only used for supervisor
  204.      *
  205.      * @return string E.g. 'A1'
  206.      */
  207.     public function getActiveCell()
  208.     {
  209.         return $this->_parent->getActiveSheet()->getActiveCell();
  210.     }
  211.  
  212.     /**
  213.      * Get parent. Only used for style supervisor
  214.      *
  215.      * @return PHPExcel 
  216.      */
  217.     public function getParent()
  218.     {
  219.         return $this->_parent;
  220.     }
  221.  
  222.     /**
  223.      * Apply styles from array
  224.      *
  225.      * <code>
  226.      * $objPHPExcel->getActiveSheet()->getStyle('B2')->applyFromArray(
  227.      *         array(
  228.      *             'font'    => array(
  229.      *                 'name'      => 'Arial',
  230.      *                 'bold'      => true,
  231.      *                 'italic'    => false,
  232.      *                 'underline' => PHPExcel_Style_Font::UNDERLINE_DOUBLE,
  233.      *                 'strike'    => false,
  234.      *                 'color'     => array(
  235.      *                     'rgb' => '808080'
  236.      *                 )
  237.      *             ),
  238.      *             'borders' => array(
  239.      *                 'bottom'     => array(
  240.      *                     'style' => PHPExcel_Style_Border::BORDER_DASHDOT,
  241.      *                     'color' => array(
  242.      *                         'rgb' => '808080'
  243.      *                     )
  244.      *                 ),
  245.      *                 'top'     => array(
  246.      *                     'style' => PHPExcel_Style_Border::BORDER_DASHDOT,
  247.      *                     'color' => array(
  248.      *                         'rgb' => '808080'
  249.      *                     )
  250.      *                 )
  251.      *             )
  252.      *         )
  253.      * );
  254.      * </code>
  255.      *
  256.      * @param    array    $pStyles    Array containing style information
  257.      * @param     boolean        $pAdvanced    Advanced mode for setting borders.
  258.      * @throws    Exception
  259.      * @return PHPExcel_Style 
  260.      */
  261.     public function applyFromArray($pStyles null$pAdvanced true{
  262.         if (is_array($pStyles)) {
  263.             if ($this->_isSupervisor{
  264.  
  265.                 $pRange $this->getSelectedCells();
  266.  
  267.                 // Uppercase coordinate
  268.                 $pRange strtoupper($pRange);
  269.  
  270.                 // Is it a cell range or a single cell?
  271.                 if (strpos($pRange':'=== false{
  272.                     $rangeA $pRange;
  273.                     $rangeB $pRange;
  274.                 else {
  275.                     list($rangeA$rangeBexplode(':'$pRange);
  276.                 }
  277.  
  278.                 // Calculate range outer borders
  279.                 $rangeStart PHPExcel_Cell::coordinateFromString($rangeA);
  280.                 $rangeEnd     PHPExcel_Cell::coordinateFromString($rangeB);
  281.  
  282.                 // Translate column into index
  283.                 $rangeStart[0]    PHPExcel_Cell::columnIndexFromString($rangeStart[0]1;
  284.                 $rangeEnd[0]    PHPExcel_Cell::columnIndexFromString($rangeEnd[0]1;
  285.  
  286.                 // Make sure we can loop upwards on rows and columns
  287.                 if ($rangeStart[0$rangeEnd[0&& $rangeStart[1$rangeEnd[1]{
  288.                     $tmp $rangeStart;
  289.                     $rangeStart $rangeEnd;
  290.                     $rangeEnd $tmp;
  291.                 }
  292.  
  293.                 // ADVANCED MODE:
  294.  
  295.                 if ($pAdvanced && isset($pStyles['borders'])) {
  296.  
  297.                     // 'allborders' is a shorthand property for 'outline' and 'inside' and
  298.                     //        it applies to components that have not been set explicitly
  299.                     if (isset($pStyles['borders']['allborders'])) {
  300.                         foreach (array('outline''inside'as $component{
  301.                             if (!isset($pStyles['borders'][$component])) {
  302.                                 $pStyles['borders'][$component$pStyles['borders']['allborders'];
  303.                             }
  304.                         }
  305.                         unset($pStyles['borders']['allborders'])// not needed any more
  306.                     }
  307.  
  308.                     // 'outline' is a shorthand property for 'top', 'right', 'bottom', 'left'
  309.                     //        it applies to components that have not been set explicitly
  310.                     if (isset($pStyles['borders']['outline'])) {
  311.                         foreach (array('top''right''bottom''left'as $component{
  312.                             if (!isset($pStyles['borders'][$component])) {
  313.                                 $pStyles['borders'][$component$pStyles['borders']['outline'];
  314.                             }
  315.                         }
  316.                         unset($pStyles['borders']['outline'])// not needed any more
  317.                     }
  318.  
  319.                     // 'inside' is a shorthand property for 'vertical' and 'horizontal'
  320.                     //        it applies to components that have not been set explicitly
  321.                     if (isset($pStyles['borders']['inside'])) {
  322.                         foreach (array('vertical''horizontal'as $component{
  323.                             if (!isset($pStyles['borders'][$component])) {
  324.                                 $pStyles['borders'][$component$pStyles['borders']['inside'];
  325.                             }
  326.                         }
  327.                         unset($pStyles['borders']['inside'])// not needed any more
  328.                     }
  329.  
  330.                     // width and height characteristics of selection, 1, 2, or 3 (for 3 or more)
  331.                     $xMax min($rangeEnd[0$rangeStart[013);
  332.                     $yMax min($rangeEnd[1$rangeStart[113);
  333.  
  334.                     // loop through up to 3 x 3 = 9 regions
  335.                     for ($x 1$x <= $xMax++$x{
  336.                         // start column index for region
  337.                         $colStart ($x == 3?
  338.                             PHPExcel_Cell::stringFromColumnIndex($rangeEnd[0])
  339.                                 : PHPExcel_Cell::stringFromColumnIndex($rangeStart[0$x 1);
  340.  
  341.                         // end column index for region
  342.                         $colEnd ($x == 1?
  343.                             PHPExcel_Cell::stringFromColumnIndex($rangeStart[0])
  344.                                 : PHPExcel_Cell::stringFromColumnIndex($rangeEnd[0$xMax $x);
  345.  
  346.                         for ($y 1$y <= $yMax++$y{
  347.  
  348.                             // which edges are touching the region
  349.                             $edges array();
  350.  
  351.                             // are we at left edge
  352.                             if ($x == 1{
  353.                                 $edges['left';
  354.                             }
  355.  
  356.                             // are we at right edge
  357.                             if ($x == $xMax{
  358.                                 $edges['right';
  359.                             }
  360.  
  361.                             // are we at top edge?
  362.                             if ($y == 1{
  363.                                 $edges['top';
  364.                             }
  365.  
  366.                             // are we at bottom edge?
  367.                             if ($y == $yMax{
  368.                                 $edges['bottom';
  369.                             }
  370.  
  371.                             // start row index for region
  372.                             $rowStart ($y == 3?
  373.                                 $rangeEnd[1$rangeStart[1$y 1;
  374.  
  375.                             // end row index for region
  376.                             $rowEnd ($y == 1?
  377.                                 $rangeStart[1$rangeEnd[1$yMax $y;
  378.  
  379.                             // build range for region
  380.                             $range $colStart $rowStart ':' $colEnd $rowEnd;
  381.  
  382.                             // retrieve relevant style array for region
  383.                             $regionStyles $pStyles;
  384.                             unset($regionStyles['borders']['inside']);
  385.  
  386.                             // what are the inner edges of the region when looking at the selection
  387.                             $innerEdges array_diffarray('top''right''bottom''left')$edges );
  388.  
  389.                             // inner edges that are not touching the region should take the 'inside' border properties if they have been set
  390.                             foreach ($innerEdges as $innerEdge{
  391.                                 switch ($innerEdge{
  392.                                     case 'top':
  393.                                     case 'bottom':
  394.                                         // should pick up 'horizontal' border property if set
  395.                                         if (isset($pStyles['borders']['horizontal'])) {
  396.                                             $regionStyles['borders'][$innerEdge$pStyles['borders']['horizontal'];
  397.                                         else {
  398.                                             unset($regionStyles['borders'][$innerEdge]);
  399.                                         }
  400.                                         break;
  401.                                     case 'left':
  402.                                     case 'right':
  403.                                         // should pick up 'vertical' border property if set
  404.                                         if (isset($pStyles['borders']['vertical'])) {
  405.                                             $regionStyles['borders'][$innerEdge$pStyles['borders']['vertical'];
  406.                                         else {
  407.                                             unset($regionStyles['borders'][$innerEdge]);
  408.                                         }
  409.                                         break;
  410.                                 }
  411.                             }
  412.  
  413.                             // apply region style to region by calling applyFromArray() in simple mode
  414.                             $this->getActiveSheet()->getStyle($range)->applyFromArray($regionStylesfalse);
  415.                         }
  416.                     }
  417.                     return;
  418.                 }
  419.  
  420.                 // SIMPLE MODE:
  421.  
  422.                 // Selection type, inspect
  423.                 if (preg_match('/^[A-Z]+1:[A-Z]+1048576$/'$pRange)) {
  424.                     $selectionType 'COLUMN';
  425.                 else if (preg_match('/^A[0-9]+:XFD[0-9]+$/'$pRange)) {
  426.                     $selectionType 'ROW';
  427.                 else {
  428.                     $selectionType 'CELL';
  429.                 }
  430.  
  431.                 // First loop through columns, rows, or cells to find out which styles are affected by this operation
  432.                 switch ($selectionType{
  433.                     case 'COLUMN':
  434.                         $oldXfIndexes array();
  435.                         for ($col $rangeStart[0]$col <= $rangeEnd[0]++$col{
  436.                             $oldXfIndexes[$this->getActiveSheet()->getColumnDimensionByColumn($col)->getXfIndex()true;
  437.                         }
  438.                         break;
  439.  
  440.                     case 'ROW':
  441.                         $oldXfIndexes array();
  442.                         for ($row $rangeStart[1]$row <= $rangeEnd[1]++$row{
  443.                             if ($this->getActiveSheet()->getRowDimension($row)->getXfIndex(== null{
  444.                                 $oldXfIndexes[0true// row without explicit style should be formatted based on default style
  445.                             else {
  446.                                 $oldXfIndexes[$this->getActiveSheet()->getRowDimension($row)->getXfIndex()true;
  447.                             }
  448.                         }
  449.                         break;
  450.  
  451.                     case 'CELL':
  452.                         $oldXfIndexes array();
  453.                         for ($col $rangeStart[0]$col <= $rangeEnd[0]++$col{
  454.                             for ($row $rangeStart[1]$row <= $rangeEnd[1]++$row{
  455.                                 $oldXfIndexes[$this->getActiveSheet()->getCellByColumnAndRow($col$row)->getXfIndex()true;
  456.                             }
  457.                         }
  458.                         break;
  459.                 }
  460.  
  461.                 // clone each of the affected styles, apply the style arrray, and add the new styles to the workbook
  462.                 $workbook $this->getActiveSheet()->getParent();
  463.                 foreach ($oldXfIndexes as $oldXfIndex => $dummy{
  464.                     $style $workbook->getCellXfByIndex($oldXfIndex);
  465.                     $newStyle clone $style;
  466.                     $newStyle->applyFromArray($pStyles);
  467.  
  468.                     if ($existingStyle $workbook->getCellXfByHashCode($newStyle->getHashCode())) {
  469.                         // there is already such cell Xf in our collection
  470.                         $newXfIndexes[$oldXfIndex$existingStyle->getIndex();
  471.                     else {
  472.                         // we don't have such a cell Xf, need to add
  473.                         $workbook->addCellXf($newStyle);
  474.                         $newXfIndexes[$oldXfIndex$newStyle->getIndex();
  475.                     }
  476.                 }
  477.  
  478.                 // Loop through columns, rows, or cells again and update the XF index
  479.                 switch ($selectionType{
  480.                     case 'COLUMN':
  481.                         for ($col $rangeStart[0]$col <= $rangeEnd[0]++$col{
  482.                             $columnDimension $this->getActiveSheet()->getColumnDimensionByColumn($col);
  483.                             $oldXfIndex $columnDimension->getXfIndex();
  484.                             $columnDimension->setXfIndex($newXfIndexes[$oldXfIndex]);
  485.                         }
  486.                         break;
  487.  
  488.                     case 'ROW':
  489.                         for ($row $rangeStart[1]$row <= $rangeEnd[1]++$row{
  490.                             $rowDimension $this->getActiveSheet()->getRowDimension($row);
  491.                             $oldXfIndex $rowDimension->getXfIndex(=== null ?
  492.                                 $rowDimension->getXfIndex()// row without explicit style should be formatted based on default style
  493.                             $rowDimension->setXfIndex($newXfIndexes[$oldXfIndex]);
  494.                         }
  495.                         break;
  496.  
  497.                     case 'CELL':
  498.                         for ($col $rangeStart[0]$col <= $rangeEnd[0]++$col{
  499.                             for ($row $rangeStart[1]$row <= $rangeEnd[1]++$row{
  500.                                 $cell $this->getActiveSheet()->getCellByColumnAndRow($col$row);
  501.                                 $oldXfIndex $cell->getXfIndex();
  502.                                 $cell->setXfIndex($newXfIndexes[$oldXfIndex]);
  503.                             }
  504.                         }
  505.                         break;
  506.                 }
  507.  
  508.             else {
  509.                 // not a supervisor, just apply the style array directly on style object
  510.                 if (array_key_exists('fill'$pStyles)) {
  511.                     $this->getFill()->applyFromArray($pStyles['fill']);
  512.                 }
  513.                 if (array_key_exists('font'$pStyles)) {
  514.                     $this->getFont()->applyFromArray($pStyles['font']);
  515.                 }
  516.                 if (array_key_exists('borders'$pStyles)) {
  517.                     $this->getBorders()->applyFromArray($pStyles['borders']);
  518.                 }
  519.                 if (array_key_exists('alignment'$pStyles)) {
  520.                     $this->getAlignment()->applyFromArray($pStyles['alignment']);
  521.                 }
  522.                 if (array_key_exists('numberformat'$pStyles)) {
  523.                     $this->getNumberFormat()->applyFromArray($pStyles['numberformat']);
  524.                 }
  525.                 if (array_key_exists('protection'$pStyles)) {
  526.                     $this->getProtection()->applyFromArray($pStyles['protection']);
  527.                 }
  528.             }
  529.         else {
  530.             throw new Exception("Invalid style array passed.");
  531.         }
  532.         return $this;
  533.     }
  534.  
  535.     /**
  536.      * Get Fill
  537.      *
  538.      * @return PHPExcel_Style_Fill 
  539.      */
  540.     public function getFill({
  541.         return $this->_fill;
  542.     }
  543.  
  544.     /**
  545.      * Get Font
  546.      *
  547.      * @return PHPExcel_Style_Font 
  548.      */
  549.     public function getFont({
  550.         return $this->_font;
  551.     }
  552.  
  553.     /**
  554.      * Set font
  555.      *
  556.      * @param PHPExcel_Style_Font $font 
  557.      * @return PHPExcel_Style 
  558.      */
  559.     public function setFont(PHPExcel_Style_Font $font)
  560.     {
  561.         $this->_font $font;
  562.         return $this;
  563.     }
  564.  
  565.     /**
  566.      * Get Borders
  567.      *
  568.      * @return PHPExcel_Style_Borders 
  569.      */
  570.     public function getBorders({
  571.         return $this->_borders;
  572.     }
  573.  
  574.     /**
  575.      * Get Alignment
  576.      *
  577.      * @return PHPExcel_Style_Alignment 
  578.      */
  579.     public function getAlignment({
  580.         return $this->_alignment;
  581.     }
  582.  
  583.     /**
  584.      * Get Number Format
  585.      *
  586.      * @return PHPExcel_Style_NumberFormat 
  587.      */
  588.     public function getNumberFormat({
  589.         return $this->_numberFormat;
  590.     }
  591.  
  592.     /**
  593.      * Get Conditional Styles. Only used on supervisor.
  594.      *
  595.      * @return PHPExcel_Style_Conditional[] 
  596.      */
  597.     public function getConditionalStyles({
  598.         return $this->getActiveSheet()->getConditionalStyles($this->getActiveCell());
  599.     }
  600.  
  601.     /**
  602.      * Set Conditional Styles. Only used on supervisor.
  603.      *
  604.      * @param PHPExcel_Style_Conditional[]    $pValue    Array of condtional styles
  605.      * @return PHPExcel_Style 
  606.      */
  607.     public function setConditionalStyles($pValue null{
  608.         if (is_array($pValue)) {
  609.             $this->getActiveSheet()->setConditionalStyles($this->getSelectedCells()$pValue);
  610.         }
  611.         return $this;
  612.     }
  613.  
  614.     /**
  615.      * Get Protection
  616.      *
  617.      * @return PHPExcel_Style_Protection 
  618.      */
  619.     public function getProtection({
  620.         return $this->_protection;
  621.     }
  622.  
  623.     /**
  624.      * Get hash code
  625.      *
  626.      * @return string    Hash code
  627.      */
  628.     public function getHashCode({
  629.         $hashConditionals '';
  630.         foreach ($this->_conditionalStyles as $conditional{
  631.             $hashConditionals .= $conditional->getHashCode();
  632.         }
  633.  
  634.         return md5(
  635.               $this->_fill->getHashCode()
  636.             . $this->_font->getHashCode()
  637.             . $this->_borders->getHashCode()
  638.             . $this->_alignment->getHashCode()
  639.             . $this->_numberFormat->getHashCode()
  640.             . $hashConditionals
  641.             . $this->_protection->getHashCode()
  642.             . __CLASS__
  643.         );
  644.     }
  645.  
  646.     /**
  647.      * Get own index in style collection
  648.      *
  649.      * @return int 
  650.      */
  651.     public function getIndex()
  652.     {
  653.         return $this->_index;
  654.     }
  655.  
  656.     /**
  657.      * Set own index in style collection
  658.      *
  659.      * @param int $pValue 
  660.      */
  661.     public function setIndex($pValue)
  662.     {
  663.         $this->_index $pValue;
  664.     }
  665.  
  666.     /**
  667.      * Implement PHP __clone to create a deep clone, not just a shallow copy.
  668.      */
  669.     public function __clone({
  670.         $vars get_object_vars($this);
  671.         foreach ($vars as $key => $value{
  672.             if ((is_object($value)) && ($key != '_parent')) {
  673.                 $this->$key clone $value;
  674.             else {
  675.                 $this->$key $value;
  676.             }
  677.         }
  678.     }
  679. }

Documentation generated on Sun, 27 Feb 2011 16:34:19 -0800 by phpDocumentor 1.4.3