Completed
Pull Request — develop_3.0 (#434)
by Hura
04:17
created

StyleHelperAbstract::getDefaultStyle()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 5
ccs 2
cts 2
cp 1
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 2
nc 1
nop 0
crap 1
1
<?php
2
3
namespace Box\Spout\Writer\Common\Helper;
4
5
use Box\Spout\Writer\Common\Entity\Cell;
6
use Box\Spout\Writer\Common\Entity\Style\Style;
7
use Box\Spout\Writer\Common\Manager\StyleManager;
8
9
/**
10
 * Class StyleHelperAbstract
11
 * This class provides helper functions to manage styles
12
 *
13
 * @package Box\Spout\Writer\Common\Helper
14
 */
15
abstract class StyleHelperAbstract implements StyleHelperInterface
16
{
17
    /** @var StyleManager Style manager */
18
    private $styleManager;
19
20
    /** @var array [SERIALIZED_STYLE] => [STYLE_ID] mapping table, keeping track of the registered styles */
21
    protected $serializedStyleToStyleIdMappingTable = [];
22
23
    /** @var array [STYLE_ID] => [STYLE] mapping table, keeping track of the registered styles */
24
    protected $styleIdToStyleMappingTable = [];
25
26
    /**
27
     * @param Style $defaultStyle
28
     * @param StyleManager $styleManager
29
     */
30 98
    public function __construct(Style $defaultStyle, StyleManager $styleManager)
31
    {
32 98
        $this->styleManager = $styleManager;
33
34
        // This ensures that the default style is the first one to be registered
35 98
        $this->registerStyle($defaultStyle);
36 98
    }
37
38
    /**
39
     * Registers the given style as a used style.
40
     * Duplicate styles won't be registered more than once.
41
     *
42
     * @param Style $style The style to be registered
43
     * @return Style The registered style, updated with an internal ID.
44
     */
45 98
    public function registerStyle($style)
46
    {
47 98
        $serializedStyle = $this->styleManager->serialize($style);
48
49 98
        if (!$this->hasStyleAlreadyBeenRegistered($style)) {
50 98
            $nextStyleId = count($this->serializedStyleToStyleIdMappingTable);
51 98
            $style->setId($nextStyleId);
52
53 98
            $this->serializedStyleToStyleIdMappingTable[$serializedStyle] = $nextStyleId;
54 98
            $this->styleIdToStyleMappingTable[$nextStyleId] = $style;
55
        }
56
57 98
        return $this->getStyleFromSerializedStyle($serializedStyle);
58
    }
59
60
    /**
61
     * Returns whether the given style has already been registered.
62
     *
63
     * @param Style $style
64
     * @return bool
65
     */
66 98
    protected function hasStyleAlreadyBeenRegistered($style)
67
    {
68 98
        $serializedStyle = $this->styleManager->serialize($style);
69
70
        // Using isset here because it is way faster than array_key_exists...
71 98
        return isset($this->serializedStyleToStyleIdMappingTable[$serializedStyle]);
72
    }
73
74
    /**
75
     * Returns the registered style associated to the given serialization.
76
     *
77
     * @param string $serializedStyle The serialized style from which the actual style should be fetched from
78
     * @return Style
79
     */
80 98
    protected function getStyleFromSerializedStyle($serializedStyle)
81
    {
82 98
        $styleId = $this->serializedStyleToStyleIdMappingTable[$serializedStyle];
83 98
        return $this->styleIdToStyleMappingTable[$styleId];
84
    }
85
86
    /**
87
     * @return Style[] List of registered styles
88
     */
89 70
    protected function getRegisteredStyles()
90
    {
91 70
        return array_values($this->styleIdToStyleMappingTable);
92
    }
93
94
    /**
95
     * Returns the default style
96
     *
97
     * @return Style Default style
98
     */
99 34
    protected function getDefaultStyle()
100
    {
101
        // By construction, the default style has ID 0
102 34
        return $this->styleIdToStyleMappingTable[0];
103
    }
104
105
    /**
106
     * Apply additional styles if the given row needs it.
107
     * Typically, set "wrap text" if a cell contains a new line.
108
     *
109
     * @param Cell $cell
110
     * @return Style
111
     */
112 68
    public function applyExtraStylesIfNeeded(Cell $cell)
113
    {
114 68
        $updatedStyle = $this->applyWrapTextIfCellContainsNewLine($cell);
115 68
        return $updatedStyle;
116
    }
117
118
    /**
119
     * Set the "wrap text" option if a cell of the given row contains a new line.
120
     *
121
     * @NOTE: There is a bug on the Mac version of Excel (2011 and below) where new lines
122
     *        are ignored even when the "wrap text" option is set. This only occurs with
123
     *        inline strings (shared strings do work fine).
124
     *        A workaround would be to encode "\n" as "_x000D_" but it does not work
125
     *        on the Windows version of Excel...
126
     *
127
     * @param Cell $cell The cell the style should be applied to
128
     * @return \Box\Spout\Writer\Common\Entity\Style\Style The eventually updated style
129
     */
130 68
    protected function applyWrapTextIfCellContainsNewLine(Cell $cell)
131
    {
132
        // if the "wrap text" option is already set, no-op
133 68
        if ($cell->getStyle()->hasSetWrapText()) {
134 4
            return $cell->getStyle();
135
        }
136
137 64
        if ($cell->isString() && strpos($cell->getValue(), "\n") !== false) {
138 5
            $cell->getStyle()->setShouldWrapText();
139
        }
140
141 64
        return $cell->getStyle();
142
    }
143
}
144