| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641 | 
							- <?php
 
- namespace PhpOffice\PhpSpreadsheet\Style;
 
- use PhpOffice\PhpSpreadsheet\Cell\Coordinate;
 
- use PhpOffice\PhpSpreadsheet\Spreadsheet;
 
- class Style extends Supervisor
 
- {
 
-     /**
 
-      * Font.
 
-      *
 
-      * @var Font
 
-      */
 
-     protected $font;
 
-     /**
 
-      * Fill.
 
-      *
 
-      * @var Fill
 
-      */
 
-     protected $fill;
 
-     /**
 
-      * Borders.
 
-      *
 
-      * @var Borders
 
-      */
 
-     protected $borders;
 
-     /**
 
-      * Alignment.
 
-      *
 
-      * @var Alignment
 
-      */
 
-     protected $alignment;
 
-     /**
 
-      * Number Format.
 
-      *
 
-      * @var NumberFormat
 
-      */
 
-     protected $numberFormat;
 
-     /**
 
-      * Conditional styles.
 
-      *
 
-      * @var Conditional[]
 
-      */
 
-     protected $conditionalStyles;
 
-     /**
 
-      * Protection.
 
-      *
 
-      * @var Protection
 
-      */
 
-     protected $protection;
 
-     /**
 
-      * Index of style in collection. Only used for real style.
 
-      *
 
-      * @var int
 
-      */
 
-     protected $index;
 
-     /**
 
-      * Use Quote Prefix when displaying in cell editor. Only used for real style.
 
-      *
 
-      * @var bool
 
-      */
 
-     protected $quotePrefix = false;
 
-     /**
 
-      * Create a new Style.
 
-      *
 
-      * @param bool $isSupervisor Flag indicating if this is a supervisor or not
 
-      *         Leave this value at default unless you understand exactly what
 
-      *    its ramifications are
 
-      * @param bool $isConditional Flag indicating if this is a conditional style or not
 
-      *       Leave this value at default unless you understand exactly what
 
-      *    its ramifications are
 
-      */
 
-     public function __construct($isSupervisor = false, $isConditional = false)
 
-     {
 
-         parent::__construct($isSupervisor);
 
-         // Initialise values
 
-         $this->conditionalStyles = [];
 
-         $this->font = new Font($isSupervisor, $isConditional);
 
-         $this->fill = new Fill($isSupervisor, $isConditional);
 
-         $this->borders = new Borders($isSupervisor, $isConditional);
 
-         $this->alignment = new Alignment($isSupervisor, $isConditional);
 
-         $this->numberFormat = new NumberFormat($isSupervisor, $isConditional);
 
-         $this->protection = new Protection($isSupervisor, $isConditional);
 
-         // bind parent if we are a supervisor
 
-         if ($isSupervisor) {
 
-             $this->font->bindParent($this);
 
-             $this->fill->bindParent($this);
 
-             $this->borders->bindParent($this);
 
-             $this->alignment->bindParent($this);
 
-             $this->numberFormat->bindParent($this);
 
-             $this->protection->bindParent($this);
 
-         }
 
-     }
 
-     /**
 
-      * Get the shared style component for the currently active cell in currently active sheet.
 
-      * Only used for style supervisor.
 
-      *
 
-      * @return Style
 
-      */
 
-     public function getSharedComponent()
 
-     {
 
-         $activeSheet = $this->getActiveSheet();
 
-         $selectedCell = $this->getActiveCell(); // e.g. 'A1'
 
-         if ($activeSheet->cellExists($selectedCell)) {
 
-             $xfIndex = $activeSheet->getCell($selectedCell)->getXfIndex();
 
-         } else {
 
-             $xfIndex = 0;
 
-         }
 
-         return $this->parent->getCellXfByIndex($xfIndex);
 
-     }
 
-     /**
 
-      * Get parent. Only used for style supervisor.
 
-      *
 
-      * @return Spreadsheet
 
-      */
 
-     public function getParent()
 
-     {
 
-         return $this->parent;
 
-     }
 
-     /**
 
-      * Build style array from subcomponents.
 
-      *
 
-      * @param array $array
 
-      *
 
-      * @return array
 
-      */
 
-     public function getStyleArray($array)
 
-     {
 
-         return ['quotePrefix' => $array];
 
-     }
 
-     /**
 
-      * Apply styles from array.
 
-      *
 
-      * <code>
 
-      * $spreadsheet->getActiveSheet()->getStyle('B2')->applyFromArray(
 
-      *     [
 
-      *         'font' => [
 
-      *             'name' => 'Arial',
 
-      *             'bold' => true,
 
-      *             'italic' => false,
 
-      *             'underline' => Font::UNDERLINE_DOUBLE,
 
-      *             'strikethrough' => false,
 
-      *             'color' => [
 
-      *                 'rgb' => '808080'
 
-      *             ]
 
-      *         ],
 
-      *         'borders' => [
 
-      *             'bottom' => [
 
-      *                 'borderStyle' => Border::BORDER_DASHDOT,
 
-      *                 'color' => [
 
-      *                     'rgb' => '808080'
 
-      *                 ]
 
-      *             ],
 
-      *             'top' => [
 
-      *                 'borderStyle' => Border::BORDER_DASHDOT,
 
-      *                 'color' => [
 
-      *                     'rgb' => '808080'
 
-      *                 ]
 
-      *             ]
 
-      *         ],
 
-      *         'alignment' => [
 
-      *             'horizontal' => Alignment::HORIZONTAL_CENTER,
 
-      *             'vertical' => Alignment::VERTICAL_CENTER,
 
-      *             'wrapText' => true,
 
-      *         ],
 
-      *         'quotePrefix'    => true
 
-      *     ]
 
-      * );
 
-      * </code>
 
-      *
 
-      * @param array $pStyles Array containing style information
 
-      * @param bool $pAdvanced advanced mode for setting borders
 
-      *
 
-      * @return Style
 
-      */
 
-     public function applyFromArray(array $pStyles, $pAdvanced = true)
 
-     {
 
-         if ($this->isSupervisor) {
 
-             $pRange = $this->getSelectedCells();
 
-             // Uppercase coordinate
 
-             $pRange = strtoupper($pRange);
 
-             // Is it a cell range or a single cell?
 
-             if (strpos($pRange, ':') === false) {
 
-                 $rangeA = $pRange;
 
-                 $rangeB = $pRange;
 
-             } else {
 
-                 list($rangeA, $rangeB) = explode(':', $pRange);
 
-             }
 
-             // Calculate range outer borders
 
-             $rangeStart = Coordinate::coordinateFromString($rangeA);
 
-             $rangeEnd = Coordinate::coordinateFromString($rangeB);
 
-             // Translate column into index
 
-             $rangeStart[0] = Coordinate::columnIndexFromString($rangeStart[0]);
 
-             $rangeEnd[0] = Coordinate::columnIndexFromString($rangeEnd[0]);
 
-             // Make sure we can loop upwards on rows and columns
 
-             if ($rangeStart[0] > $rangeEnd[0] && $rangeStart[1] > $rangeEnd[1]) {
 
-                 $tmp = $rangeStart;
 
-                 $rangeStart = $rangeEnd;
 
-                 $rangeEnd = $tmp;
 
-             }
 
-             // ADVANCED MODE:
 
-             if ($pAdvanced && isset($pStyles['borders'])) {
 
-                 // 'allBorders' is a shorthand property for 'outline' and 'inside' and
 
-                 //        it applies to components that have not been set explicitly
 
-                 if (isset($pStyles['borders']['allBorders'])) {
 
-                     foreach (['outline', 'inside'] as $component) {
 
-                         if (!isset($pStyles['borders'][$component])) {
 
-                             $pStyles['borders'][$component] = $pStyles['borders']['allBorders'];
 
-                         }
 
-                     }
 
-                     unset($pStyles['borders']['allBorders']); // not needed any more
 
-                 }
 
-                 // 'outline' is a shorthand property for 'top', 'right', 'bottom', 'left'
 
-                 //        it applies to components that have not been set explicitly
 
-                 if (isset($pStyles['borders']['outline'])) {
 
-                     foreach (['top', 'right', 'bottom', 'left'] as $component) {
 
-                         if (!isset($pStyles['borders'][$component])) {
 
-                             $pStyles['borders'][$component] = $pStyles['borders']['outline'];
 
-                         }
 
-                     }
 
-                     unset($pStyles['borders']['outline']); // not needed any more
 
-                 }
 
-                 // 'inside' is a shorthand property for 'vertical' and 'horizontal'
 
-                 //        it applies to components that have not been set explicitly
 
-                 if (isset($pStyles['borders']['inside'])) {
 
-                     foreach (['vertical', 'horizontal'] as $component) {
 
-                         if (!isset($pStyles['borders'][$component])) {
 
-                             $pStyles['borders'][$component] = $pStyles['borders']['inside'];
 
-                         }
 
-                     }
 
-                     unset($pStyles['borders']['inside']); // not needed any more
 
-                 }
 
-                 // width and height characteristics of selection, 1, 2, or 3 (for 3 or more)
 
-                 $xMax = min($rangeEnd[0] - $rangeStart[0] + 1, 3);
 
-                 $yMax = min($rangeEnd[1] - $rangeStart[1] + 1, 3);
 
-                 // loop through up to 3 x 3 = 9 regions
 
-                 for ($x = 1; $x <= $xMax; ++$x) {
 
-                     // start column index for region
 
-                     $colStart = ($x == 3) ?
 
-                         Coordinate::stringFromColumnIndex($rangeEnd[0])
 
-                             : Coordinate::stringFromColumnIndex($rangeStart[0] + $x - 1);
 
-                     // end column index for region
 
-                     $colEnd = ($x == 1) ?
 
-                         Coordinate::stringFromColumnIndex($rangeStart[0])
 
-                             : Coordinate::stringFromColumnIndex($rangeEnd[0] - $xMax + $x);
 
-                     for ($y = 1; $y <= $yMax; ++$y) {
 
-                         // which edges are touching the region
 
-                         $edges = [];
 
-                         if ($x == 1) {
 
-                             // are we at left edge
 
-                             $edges[] = 'left';
 
-                         }
 
-                         if ($x == $xMax) {
 
-                             // are we at right edge
 
-                             $edges[] = 'right';
 
-                         }
 
-                         if ($y == 1) {
 
-                             // are we at top edge?
 
-                             $edges[] = 'top';
 
-                         }
 
-                         if ($y == $yMax) {
 
-                             // are we at bottom edge?
 
-                             $edges[] = 'bottom';
 
-                         }
 
-                         // start row index for region
 
-                         $rowStart = ($y == 3) ?
 
-                             $rangeEnd[1] : $rangeStart[1] + $y - 1;
 
-                         // end row index for region
 
-                         $rowEnd = ($y == 1) ?
 
-                             $rangeStart[1] : $rangeEnd[1] - $yMax + $y;
 
-                         // build range for region
 
-                         $range = $colStart . $rowStart . ':' . $colEnd . $rowEnd;
 
-                         // retrieve relevant style array for region
 
-                         $regionStyles = $pStyles;
 
-                         unset($regionStyles['borders']['inside']);
 
-                         // what are the inner edges of the region when looking at the selection
 
-                         $innerEdges = array_diff(['top', 'right', 'bottom', 'left'], $edges);
 
-                         // inner edges that are not touching the region should take the 'inside' border properties if they have been set
 
-                         foreach ($innerEdges as $innerEdge) {
 
-                             switch ($innerEdge) {
 
-                                 case 'top':
 
-                                 case 'bottom':
 
-                                     // should pick up 'horizontal' border property if set
 
-                                     if (isset($pStyles['borders']['horizontal'])) {
 
-                                         $regionStyles['borders'][$innerEdge] = $pStyles['borders']['horizontal'];
 
-                                     } else {
 
-                                         unset($regionStyles['borders'][$innerEdge]);
 
-                                     }
 
-                                     break;
 
-                                 case 'left':
 
-                                 case 'right':
 
-                                     // should pick up 'vertical' border property if set
 
-                                     if (isset($pStyles['borders']['vertical'])) {
 
-                                         $regionStyles['borders'][$innerEdge] = $pStyles['borders']['vertical'];
 
-                                     } else {
 
-                                         unset($regionStyles['borders'][$innerEdge]);
 
-                                     }
 
-                                     break;
 
-                             }
 
-                         }
 
-                         // apply region style to region by calling applyFromArray() in simple mode
 
-                         $this->getActiveSheet()->getStyle($range)->applyFromArray($regionStyles, false);
 
-                     }
 
-                 }
 
-                 // restore initial cell selection range
 
-                 $this->getActiveSheet()->getStyle($pRange);
 
-                 return $this;
 
-             }
 
-             // SIMPLE MODE:
 
-             // Selection type, inspect
 
-             if (preg_match('/^[A-Z]+1:[A-Z]+1048576$/', $pRange)) {
 
-                 $selectionType = 'COLUMN';
 
-             } elseif (preg_match('/^A\d+:XFD\d+$/', $pRange)) {
 
-                 $selectionType = 'ROW';
 
-             } else {
 
-                 $selectionType = 'CELL';
 
-             }
 
-             // First loop through columns, rows, or cells to find out which styles are affected by this operation
 
-             switch ($selectionType) {
 
-                 case 'COLUMN':
 
-                     $oldXfIndexes = [];
 
-                     for ($col = $rangeStart[0]; $col <= $rangeEnd[0]; ++$col) {
 
-                         $oldXfIndexes[$this->getActiveSheet()->getColumnDimensionByColumn($col)->getXfIndex()] = true;
 
-                     }
 
-                     break;
 
-                 case 'ROW':
 
-                     $oldXfIndexes = [];
 
-                     for ($row = $rangeStart[1]; $row <= $rangeEnd[1]; ++$row) {
 
-                         if ($this->getActiveSheet()->getRowDimension($row)->getXfIndex() == null) {
 
-                             $oldXfIndexes[0] = true; // row without explicit style should be formatted based on default style
 
-                         } else {
 
-                             $oldXfIndexes[$this->getActiveSheet()->getRowDimension($row)->getXfIndex()] = true;
 
-                         }
 
-                     }
 
-                     break;
 
-                 case 'CELL':
 
-                     $oldXfIndexes = [];
 
-                     for ($col = $rangeStart[0]; $col <= $rangeEnd[0]; ++$col) {
 
-                         for ($row = $rangeStart[1]; $row <= $rangeEnd[1]; ++$row) {
 
-                             $oldXfIndexes[$this->getActiveSheet()->getCellByColumnAndRow($col, $row)->getXfIndex()] = true;
 
-                         }
 
-                     }
 
-                     break;
 
-             }
 
-             // clone each of the affected styles, apply the style array, and add the new styles to the workbook
 
-             $workbook = $this->getActiveSheet()->getParent();
 
-             foreach ($oldXfIndexes as $oldXfIndex => $dummy) {
 
-                 $style = $workbook->getCellXfByIndex($oldXfIndex);
 
-                 $newStyle = clone $style;
 
-                 $newStyle->applyFromArray($pStyles);
 
-                 if ($existingStyle = $workbook->getCellXfByHashCode($newStyle->getHashCode())) {
 
-                     // there is already such cell Xf in our collection
 
-                     $newXfIndexes[$oldXfIndex] = $existingStyle->getIndex();
 
-                 } else {
 
-                     // we don't have such a cell Xf, need to add
 
-                     $workbook->addCellXf($newStyle);
 
-                     $newXfIndexes[$oldXfIndex] = $newStyle->getIndex();
 
-                 }
 
-             }
 
-             // Loop through columns, rows, or cells again and update the XF index
 
-             switch ($selectionType) {
 
-                 case 'COLUMN':
 
-                     for ($col = $rangeStart[0]; $col <= $rangeEnd[0]; ++$col) {
 
-                         $columnDimension = $this->getActiveSheet()->getColumnDimensionByColumn($col);
 
-                         $oldXfIndex = $columnDimension->getXfIndex();
 
-                         $columnDimension->setXfIndex($newXfIndexes[$oldXfIndex]);
 
-                     }
 
-                     break;
 
-                 case 'ROW':
 
-                     for ($row = $rangeStart[1]; $row <= $rangeEnd[1]; ++$row) {
 
-                         $rowDimension = $this->getActiveSheet()->getRowDimension($row);
 
-                         $oldXfIndex = $rowDimension->getXfIndex() === null ?
 
-                             0 : $rowDimension->getXfIndex(); // row without explicit style should be formatted based on default style
 
-                         $rowDimension->setXfIndex($newXfIndexes[$oldXfIndex]);
 
-                     }
 
-                     break;
 
-                 case 'CELL':
 
-                     for ($col = $rangeStart[0]; $col <= $rangeEnd[0]; ++$col) {
 
-                         for ($row = $rangeStart[1]; $row <= $rangeEnd[1]; ++$row) {
 
-                             $cell = $this->getActiveSheet()->getCellByColumnAndRow($col, $row);
 
-                             $oldXfIndex = $cell->getXfIndex();
 
-                             $cell->setXfIndex($newXfIndexes[$oldXfIndex]);
 
-                         }
 
-                     }
 
-                     break;
 
-             }
 
-         } else {
 
-             // not a supervisor, just apply the style array directly on style object
 
-             if (isset($pStyles['fill'])) {
 
-                 $this->getFill()->applyFromArray($pStyles['fill']);
 
-             }
 
-             if (isset($pStyles['font'])) {
 
-                 $this->getFont()->applyFromArray($pStyles['font']);
 
-             }
 
-             if (isset($pStyles['borders'])) {
 
-                 $this->getBorders()->applyFromArray($pStyles['borders']);
 
-             }
 
-             if (isset($pStyles['alignment'])) {
 
-                 $this->getAlignment()->applyFromArray($pStyles['alignment']);
 
-             }
 
-             if (isset($pStyles['numberFormat'])) {
 
-                 $this->getNumberFormat()->applyFromArray($pStyles['numberFormat']);
 
-             }
 
-             if (isset($pStyles['protection'])) {
 
-                 $this->getProtection()->applyFromArray($pStyles['protection']);
 
-             }
 
-             if (isset($pStyles['quotePrefix'])) {
 
-                 $this->quotePrefix = $pStyles['quotePrefix'];
 
-             }
 
-         }
 
-         return $this;
 
-     }
 
-     /**
 
-      * Get Fill.
 
-      *
 
-      * @return Fill
 
-      */
 
-     public function getFill()
 
-     {
 
-         return $this->fill;
 
-     }
 
-     /**
 
-      * Get Font.
 
-      *
 
-      * @return Font
 
-      */
 
-     public function getFont()
 
-     {
 
-         return $this->font;
 
-     }
 
-     /**
 
-      * Set font.
 
-      *
 
-      * @param Font $font
 
-      *
 
-      * @return Style
 
-      */
 
-     public function setFont(Font $font)
 
-     {
 
-         $this->font = $font;
 
-         return $this;
 
-     }
 
-     /**
 
-      * Get Borders.
 
-      *
 
-      * @return Borders
 
-      */
 
-     public function getBorders()
 
-     {
 
-         return $this->borders;
 
-     }
 
-     /**
 
-      * Get Alignment.
 
-      *
 
-      * @return Alignment
 
-      */
 
-     public function getAlignment()
 
-     {
 
-         return $this->alignment;
 
-     }
 
-     /**
 
-      * Get Number Format.
 
-      *
 
-      * @return NumberFormat
 
-      */
 
-     public function getNumberFormat()
 
-     {
 
-         return $this->numberFormat;
 
-     }
 
-     /**
 
-      * Get Conditional Styles. Only used on supervisor.
 
-      *
 
-      * @return Conditional[]
 
-      */
 
-     public function getConditionalStyles()
 
-     {
 
-         return $this->getActiveSheet()->getConditionalStyles($this->getActiveCell());
 
-     }
 
-     /**
 
-      * Set Conditional Styles. Only used on supervisor.
 
-      *
 
-      * @param Conditional[] $pValue Array of conditional styles
 
-      *
 
-      * @return Style
 
-      */
 
-     public function setConditionalStyles(array $pValue)
 
-     {
 
-         $this->getActiveSheet()->setConditionalStyles($this->getSelectedCells(), $pValue);
 
-         return $this;
 
-     }
 
-     /**
 
-      * Get Protection.
 
-      *
 
-      * @return Protection
 
-      */
 
-     public function getProtection()
 
-     {
 
-         return $this->protection;
 
-     }
 
-     /**
 
-      * Get quote prefix.
 
-      *
 
-      * @return bool
 
-      */
 
-     public function getQuotePrefix()
 
-     {
 
-         if ($this->isSupervisor) {
 
-             return $this->getSharedComponent()->getQuotePrefix();
 
-         }
 
-         return $this->quotePrefix;
 
-     }
 
-     /**
 
-      * Set quote prefix.
 
-      *
 
-      * @param bool $pValue
 
-      *
 
-      * @return Style
 
-      */
 
-     public function setQuotePrefix($pValue)
 
-     {
 
-         if ($pValue == '') {
 
-             $pValue = false;
 
-         }
 
-         if ($this->isSupervisor) {
 
-             $styleArray = ['quotePrefix' => $pValue];
 
-             $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray);
 
-         } else {
 
-             $this->quotePrefix = (bool) $pValue;
 
-         }
 
-         return $this;
 
-     }
 
-     /**
 
-      * Get hash code.
 
-      *
 
-      * @return string Hash code
 
-      */
 
-     public function getHashCode()
 
-     {
 
-         $hashConditionals = '';
 
-         foreach ($this->conditionalStyles as $conditional) {
 
-             $hashConditionals .= $conditional->getHashCode();
 
-         }
 
-         return md5(
 
-             $this->fill->getHashCode() .
 
-             $this->font->getHashCode() .
 
-             $this->borders->getHashCode() .
 
-             $this->alignment->getHashCode() .
 
-             $this->numberFormat->getHashCode() .
 
-             $hashConditionals .
 
-             $this->protection->getHashCode() .
 
-             ($this->quotePrefix ? 't' : 'f') .
 
-             __CLASS__
 
-         );
 
-     }
 
-     /**
 
-      * Get own index in style collection.
 
-      *
 
-      * @return int
 
-      */
 
-     public function getIndex()
 
-     {
 
-         return $this->index;
 
-     }
 
-     /**
 
-      * Set own index in style collection.
 
-      *
 
-      * @param int $pValue
 
-      */
 
-     public function setIndex($pValue)
 
-     {
 
-         $this->index = $pValue;
 
-     }
 
- }
 
 
  |