Completed
Pull Request — master (#446)
by
unknown
04:51 queued 02:50
created

Sheet::setIsVisible()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 6
ccs 3
cts 3
cp 1
rs 9.4285
cc 1
eloc 3
nc 1
nop 1
crap 1
1
<?php
2
3
namespace Box\Spout\Writer\Common;
4
5
use Box\Spout\Common\Helper\StringHelper;
6
use Box\Spout\Writer\Exception\InvalidSheetNameException;
7
8
/**
9
 * Class Sheet
10
 * External representation of a worksheet
11
 *
12
 * @package Box\Spout\Writer\Common
13
 */
14
class Sheet
15
{
16
    const DEFAULT_SHEET_NAME_PREFIX = 'Sheet';
17
18
    /** Sheet name should not exceed 31 characters */
19
    const MAX_LENGTH_SHEET_NAME = 31;
20
21
    /** @var array Invalid characters that cannot be contained in the sheet name */
22
    private static $INVALID_CHARACTERS_IN_SHEET_NAME = ['\\', '/', '?', '*', ':', '[', ']'];
23
24
    /** @var array Associative array [WORKBOOK_ID] => [[SHEET_INDEX] => [SHEET_NAME]] keeping track of sheets' name to enforce uniqueness per workbook */
25
    protected static $SHEETS_NAME_USED = [];
26
27
    /** @var int Index of the sheet, based on order in the workbook (zero-based) */
28
    protected $index;
29
30
    /** @var string ID of the sheet's associated workbook. Used to restrict sheet name uniqueness enforcement to a single workbook */
31
    protected $associatedWorkbookId;
32
33
    /** @var string Name of the sheet */
34
    protected $name;
35
36
     /** @var bool Visibility of the sheet */
37
    protected $isVisible;
38
39
    /** @var \Box\Spout\Common\Helper\StringHelper */
40
    protected $stringHelper;
41
42
    /**
43
     * @param int $sheetIndex Index of the sheet, based on order in the workbook (zero-based)
44
     * @param string $associatedWorkbookId ID of the sheet's associated workbook
45
     */
46 309
    public function __construct($sheetIndex, $associatedWorkbookId)
47
    {
48 309
        $this->index = $sheetIndex;
49 309
        $this->associatedWorkbookId = $associatedWorkbookId;
50 309
        if (!isset(self::$SHEETS_NAME_USED[$associatedWorkbookId])) {
51 261
            self::$SHEETS_NAME_USED[$associatedWorkbookId] = [];
52 261
        }
53
54 309
        $this->stringHelper = new StringHelper();
55 309
        $this->setName(self::DEFAULT_SHEET_NAME_PREFIX . ($sheetIndex + 1));
56 309
        $this->setIsVisible(true);
57 309
    }
58
59
    /**
60
     * @api
61
     * @return int Index of the sheet, based on order in the workbook (zero-based)
62
     */
63 225
    public function getIndex()
64
    {
65 225
        return $this->index;
66
    }
67
68
    /**
69
     * @api
70
     * @return string Name of the sheet
71
     */
72 234
    public function getName()
73
    {
74 234
        return $this->name;
75
    }
76
77
    /**
78
     * @api
79
     * @return bool isVisible visibility of the sheet
80
     */
81 105
    public function isVisible()
82
    {
83 105
        return $this->isVisible;
84
    }
85
86
    /**
87
     * @api
88
     * @param string $visibility Visibility of the sheet
0 ignored issues
show
Bug introduced by
There is no parameter named $visibility. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
89
     * @return Sheet
90
     */
91 309
    public function setIsVisible($isVisible = true)
92
    {
93 309
        $this->isVisible = $isVisible;
94
95 309
        return $this;
96
    }
97
98
99
    /**
100
     * Sets the name of the sheet. Note that Excel has some restrictions on the name:
101
     *  - it should not be blank
102
     *  - it should not exceed 31 characters
103
     *  - it should not contain these characters: \ / ? * : [ or ]
104
     *  - it should be unique
105
     *
106
     * @api
107
     * @param string $name Name of the sheet
108
     * @return Sheet
109
     * @throws \Box\Spout\Writer\Exception\InvalidSheetNameException If the sheet's name is invalid.
110
     */
111 309
    public function setName($name)
112
    {
113 309
        $this->throwIfNameIsInvalid($name);
114
115 309
        $this->name = $name;
116 309
        self::$SHEETS_NAME_USED[$this->associatedWorkbookId][$this->index] = $name;
117
118 309
        return $this;
119
    }
120
121
    /**
122
     * Throws an exception if the given sheet's name is not valid.
123
     * @see Sheet::setName for validity rules.
124
     *
125
     * @param string $name
126
     * @return void
127
     * @throws \Box\Spout\Writer\Exception\InvalidSheetNameException If the sheet's name is invalid.
128
     */
129 309
    protected function throwIfNameIsInvalid($name)
130
    {
131 309
        if (!is_string($name)) {
132 6
            $actualType = gettype($name);
133 6
            $errorMessage = "The sheet's name is invalid. It must be a string ($actualType given).";
134 6
            throw new InvalidSheetNameException($errorMessage);
135
        }
136
137 309
        $failedRequirements = [];
138 309
        $nameLength = $this->stringHelper->getStringLength($name);
139
140 309
        if (!$this->isNameUnique($name)) {
141 9
            $failedRequirements[] = 'It should be unique';
142 9
        } else {
143 309
            if ($nameLength === 0) {
144 3
                $failedRequirements[] = 'It should not be blank';
145 3
            } else {
146 309
                if ($nameLength > self::MAX_LENGTH_SHEET_NAME) {
147 3
                    $failedRequirements[] = 'It should not exceed 31 characters';
148 3
                }
149
150 309
                if ($this->doesContainInvalidCharacters($name)) {
151 21
                    $failedRequirements[] = 'It should not contain these characters: \\ / ? * : [ or ]';
152 21
                }
153
154 309
                if ($this->doesStartOrEndWithSingleQuote($name)) {
155 6
                    $failedRequirements[] = 'It should not start or end with a single quote';
156 6
                }
157
            }
158
        }
159
160 309
        if (count($failedRequirements) !== 0) {
161 42
            $errorMessage = "The sheet's name (\"$name\") is invalid. It did not respect these rules:\n - ";
162 42
            $errorMessage .= implode("\n - ", $failedRequirements);
163 42
            throw new InvalidSheetNameException($errorMessage);
164
        }
165 309
    }
166
167
    /**
168
     * Returns whether the given name contains at least one invalid character.
169
     * @see Sheet::$INVALID_CHARACTERS_IN_SHEET_NAME for the full list.
170
     *
171
     * @param string $name
172
     * @return bool TRUE if the name contains invalid characters, FALSE otherwise.
173
     */
174 309
    protected function doesContainInvalidCharacters($name)
175
    {
176 309
        return (str_replace(self::$INVALID_CHARACTERS_IN_SHEET_NAME, '', $name) !== $name);
177
    }
178
179
    /**
180
     * Returns whether the given name starts or ends with a single quote
181
     *
182
     * @param string $name
183
     * @return bool TRUE if the name starts or ends with a single quote, FALSE otherwise.
184
     */
185 309
    protected function doesStartOrEndWithSingleQuote($name)
186
    {
187 309
        $startsWithSingleQuote = ($this->stringHelper->getCharFirstOccurrencePosition('\'', $name) === 0);
188 309
        $endsWithSingleQuote = ($this->stringHelper->getCharLastOccurrencePosition('\'', $name) === ($this->stringHelper->getStringLength($name) - 1));
189
190 309
        return ($startsWithSingleQuote || $endsWithSingleQuote);
191
    }
192
193
    /**
194
     * Returns whether the given name is unique.
195
     *
196
     * @param string $name
197
     * @return bool TRUE if the name is unique, FALSE otherwise.
198
     */
199 309
    protected function isNameUnique($name)
200
    {
201 309
        foreach (self::$SHEETS_NAME_USED[$this->associatedWorkbookId] as $sheetIndex => $sheetName) {
202 111
            if ($sheetIndex !== $this->index && $sheetName === $name) {
203 9
                return false;
204
            }
205 309
        }
206
207 309
        return true;
208
    }
209
}
210