Failed Conditions
Push — perf-tests ( 50942d...2fc93e )
by Adrien
14:53
created

AbstractStyleHelper   A

Complexity

Total Complexity 13

Size/Duplication

Total Lines 128
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 1

Importance

Changes 2
Bugs 0 Features 0
Metric Value
wmc 13
c 2
b 0
f 0
lcom 1
cbo 1
dl 0
loc 128
rs 10

8 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 5 1
A registerStyle() 0 14 2
A hasStyleAlreadyBeenRegistered() 0 7 1
A getStyleFromSerializedStyle() 0 5 1
A getRegisteredStyles() 0 4 1
A getDefaultStyle() 0 5 1
A applyExtraStylesIfNeeded() 0 5 1
B applyWrapTextIfCellContainsNewLine() 0 16 5
1
<?php
2
3
namespace Box\Spout\Writer\Common\Helper;
4
5
/**
6
 * Class AbstractStyleHelper
7
 * This class provides helper functions to manage styles
8
 *
9
 * @package Box\Spout\Writer\Common\Helper
10
 */
11
abstract class AbstractStyleHelper
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
    public function __construct($defaultStyle)
23
    {
24
        // This ensures that the default style is the first one to be registered
25
        $this->registerStyle($defaultStyle);
26
    }
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
    public function registerStyle($style)
36
    {
37
        $serializedStyle = $style->serialize();
38
39
        if (!$this->hasStyleAlreadyBeenRegistered($style)) {
40
            $nextStyleId = count($this->serializedStyleToStyleIdMappingTable);
41
            $style->setId($nextStyleId);
42
43
            $this->serializedStyleToStyleIdMappingTable[$serializedStyle] = $nextStyleId;
44
            $this->styleIdToStyleMappingTable[$nextStyleId] = $style;
45
        }
46
47
        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
    protected function hasStyleAlreadyBeenRegistered($style)
57
    {
58
        $serializedStyle = $style->serialize();
59
60
        // Using isset here because it is way faster than array_key_exists...
61
        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
    protected function getStyleFromSerializedStyle($serializedStyle)
71
    {
72
        $styleId = $this->serializedStyleToStyleIdMappingTable[$serializedStyle];
73
        return $this->styleIdToStyleMappingTable[$styleId];
74
    }
75
76
    /**
77
     * @return \Box\Spout\Writer\Style\Style[] List of registered styles
78
     */
79
    protected function getRegisteredStyles()
80
    {
81
        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
    protected function getDefaultStyle()
90
    {
91
        // By construction, the default style has ID 0
92
        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
    public function applyExtraStylesIfNeeded($style, $dataRow)
104
    {
105
        $updatedStyle = $this->applyWrapTextIfCellContainsNewLine($style, $dataRow);
106
        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
    protected function applyWrapTextIfCellContainsNewLine($style, $dataRow)
123
    {
124
        // if the "wrap text" option is already set, no-op
125
        if ($style->shouldWrapText()) {
126
            return $style;
127
        }
128
129
        foreach ($dataRow as $cell) {
130
            if (is_string($cell) && strpos($cell, "\n") !== false) {
131
                $style->setShouldWrapText();
132
                break;
133
            }
134
        }
135
136
        return $style;
137
    }
138
}
139