Completed
Pull Request — develop_3.0 (#427)
by Adrien
02:28
created

StyleHelperAbstract::getStyleFromSerializedStyle()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

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