Proyectos de Subversion Moodle

Rev

| Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
1441 ariadna 1
<?php
2
 
3
namespace PhpOffice\PhpSpreadsheet\Worksheet\AutoFilter\Column;
4
 
5
use PhpOffice\PhpSpreadsheet\Exception as PhpSpreadsheetException;
6
use PhpOffice\PhpSpreadsheet\Worksheet\AutoFilter\Column;
7
 
8
class Rule
9
{
10
    const AUTOFILTER_RULETYPE_FILTER = 'filter';
11
    const AUTOFILTER_RULETYPE_DATEGROUP = 'dateGroupItem';
12
    const AUTOFILTER_RULETYPE_CUSTOMFILTER = 'customFilter';
13
    const AUTOFILTER_RULETYPE_DYNAMICFILTER = 'dynamicFilter';
14
    const AUTOFILTER_RULETYPE_TOPTENFILTER = 'top10Filter';
15
 
16
    private const RULE_TYPES = [
17
        //    Currently we're not handling
18
        //        colorFilter
19
        //        extLst
20
        //        iconFilter
21
        self::AUTOFILTER_RULETYPE_FILTER,
22
        self::AUTOFILTER_RULETYPE_DATEGROUP,
23
        self::AUTOFILTER_RULETYPE_CUSTOMFILTER,
24
        self::AUTOFILTER_RULETYPE_DYNAMICFILTER,
25
        self::AUTOFILTER_RULETYPE_TOPTENFILTER,
26
    ];
27
 
28
    const AUTOFILTER_RULETYPE_DATEGROUP_YEAR = 'year';
29
    const AUTOFILTER_RULETYPE_DATEGROUP_MONTH = 'month';
30
    const AUTOFILTER_RULETYPE_DATEGROUP_DAY = 'day';
31
    const AUTOFILTER_RULETYPE_DATEGROUP_HOUR = 'hour';
32
    const AUTOFILTER_RULETYPE_DATEGROUP_MINUTE = 'minute';
33
    const AUTOFILTER_RULETYPE_DATEGROUP_SECOND = 'second';
34
 
35
    private const DATE_TIME_GROUPS = [
36
        self::AUTOFILTER_RULETYPE_DATEGROUP_YEAR,
37
        self::AUTOFILTER_RULETYPE_DATEGROUP_MONTH,
38
        self::AUTOFILTER_RULETYPE_DATEGROUP_DAY,
39
        self::AUTOFILTER_RULETYPE_DATEGROUP_HOUR,
40
        self::AUTOFILTER_RULETYPE_DATEGROUP_MINUTE,
41
        self::AUTOFILTER_RULETYPE_DATEGROUP_SECOND,
42
    ];
43
 
44
    const AUTOFILTER_RULETYPE_DYNAMIC_YESTERDAY = 'yesterday';
45
    const AUTOFILTER_RULETYPE_DYNAMIC_TODAY = 'today';
46
    const AUTOFILTER_RULETYPE_DYNAMIC_TOMORROW = 'tomorrow';
47
    const AUTOFILTER_RULETYPE_DYNAMIC_YEARTODATE = 'yearToDate';
48
    const AUTOFILTER_RULETYPE_DYNAMIC_THISYEAR = 'thisYear';
49
    const AUTOFILTER_RULETYPE_DYNAMIC_THISQUARTER = 'thisQuarter';
50
    const AUTOFILTER_RULETYPE_DYNAMIC_THISMONTH = 'thisMonth';
51
    const AUTOFILTER_RULETYPE_DYNAMIC_THISWEEK = 'thisWeek';
52
    const AUTOFILTER_RULETYPE_DYNAMIC_LASTYEAR = 'lastYear';
53
    const AUTOFILTER_RULETYPE_DYNAMIC_LASTQUARTER = 'lastQuarter';
54
    const AUTOFILTER_RULETYPE_DYNAMIC_LASTMONTH = 'lastMonth';
55
    const AUTOFILTER_RULETYPE_DYNAMIC_LASTWEEK = 'lastWeek';
56
    const AUTOFILTER_RULETYPE_DYNAMIC_NEXTYEAR = 'nextYear';
57
    const AUTOFILTER_RULETYPE_DYNAMIC_NEXTQUARTER = 'nextQuarter';
58
    const AUTOFILTER_RULETYPE_DYNAMIC_NEXTMONTH = 'nextMonth';
59
    const AUTOFILTER_RULETYPE_DYNAMIC_NEXTWEEK = 'nextWeek';
60
    const AUTOFILTER_RULETYPE_DYNAMIC_MONTH_1 = 'M1';
61
    const AUTOFILTER_RULETYPE_DYNAMIC_JANUARY = self::AUTOFILTER_RULETYPE_DYNAMIC_MONTH_1;
62
    const AUTOFILTER_RULETYPE_DYNAMIC_MONTH_2 = 'M2';
63
    const AUTOFILTER_RULETYPE_DYNAMIC_FEBRUARY = self::AUTOFILTER_RULETYPE_DYNAMIC_MONTH_2;
64
    const AUTOFILTER_RULETYPE_DYNAMIC_MONTH_3 = 'M3';
65
    const AUTOFILTER_RULETYPE_DYNAMIC_MARCH = self::AUTOFILTER_RULETYPE_DYNAMIC_MONTH_3;
66
    const AUTOFILTER_RULETYPE_DYNAMIC_MONTH_4 = 'M4';
67
    const AUTOFILTER_RULETYPE_DYNAMIC_APRIL = self::AUTOFILTER_RULETYPE_DYNAMIC_MONTH_4;
68
    const AUTOFILTER_RULETYPE_DYNAMIC_MONTH_5 = 'M5';
69
    const AUTOFILTER_RULETYPE_DYNAMIC_MAY = self::AUTOFILTER_RULETYPE_DYNAMIC_MONTH_5;
70
    const AUTOFILTER_RULETYPE_DYNAMIC_MONTH_6 = 'M6';
71
    const AUTOFILTER_RULETYPE_DYNAMIC_JUNE = self::AUTOFILTER_RULETYPE_DYNAMIC_MONTH_6;
72
    const AUTOFILTER_RULETYPE_DYNAMIC_MONTH_7 = 'M7';
73
    const AUTOFILTER_RULETYPE_DYNAMIC_JULY = self::AUTOFILTER_RULETYPE_DYNAMIC_MONTH_7;
74
    const AUTOFILTER_RULETYPE_DYNAMIC_MONTH_8 = 'M8';
75
    const AUTOFILTER_RULETYPE_DYNAMIC_AUGUST = self::AUTOFILTER_RULETYPE_DYNAMIC_MONTH_8;
76
    const AUTOFILTER_RULETYPE_DYNAMIC_MONTH_9 = 'M9';
77
    const AUTOFILTER_RULETYPE_DYNAMIC_SEPTEMBER = self::AUTOFILTER_RULETYPE_DYNAMIC_MONTH_9;
78
    const AUTOFILTER_RULETYPE_DYNAMIC_MONTH_10 = 'M10';
79
    const AUTOFILTER_RULETYPE_DYNAMIC_OCTOBER = self::AUTOFILTER_RULETYPE_DYNAMIC_MONTH_10;
80
    const AUTOFILTER_RULETYPE_DYNAMIC_MONTH_11 = 'M11';
81
    const AUTOFILTER_RULETYPE_DYNAMIC_NOVEMBER = self::AUTOFILTER_RULETYPE_DYNAMIC_MONTH_11;
82
    const AUTOFILTER_RULETYPE_DYNAMIC_MONTH_12 = 'M12';
83
    const AUTOFILTER_RULETYPE_DYNAMIC_DECEMBER = self::AUTOFILTER_RULETYPE_DYNAMIC_MONTH_12;
84
    const AUTOFILTER_RULETYPE_DYNAMIC_QUARTER_1 = 'Q1';
85
    const AUTOFILTER_RULETYPE_DYNAMIC_QUARTER_2 = 'Q2';
86
    const AUTOFILTER_RULETYPE_DYNAMIC_QUARTER_3 = 'Q3';
87
    const AUTOFILTER_RULETYPE_DYNAMIC_QUARTER_4 = 'Q4';
88
    const AUTOFILTER_RULETYPE_DYNAMIC_ABOVEAVERAGE = 'aboveAverage';
89
    const AUTOFILTER_RULETYPE_DYNAMIC_BELOWAVERAGE = 'belowAverage';
90
 
91
    private const DYNAMIC_TYPES = [
92
        self::AUTOFILTER_RULETYPE_DYNAMIC_YESTERDAY,
93
        self::AUTOFILTER_RULETYPE_DYNAMIC_TODAY,
94
        self::AUTOFILTER_RULETYPE_DYNAMIC_TOMORROW,
95
        self::AUTOFILTER_RULETYPE_DYNAMIC_YEARTODATE,
96
        self::AUTOFILTER_RULETYPE_DYNAMIC_THISYEAR,
97
        self::AUTOFILTER_RULETYPE_DYNAMIC_THISQUARTER,
98
        self::AUTOFILTER_RULETYPE_DYNAMIC_THISMONTH,
99
        self::AUTOFILTER_RULETYPE_DYNAMIC_THISWEEK,
100
        self::AUTOFILTER_RULETYPE_DYNAMIC_LASTYEAR,
101
        self::AUTOFILTER_RULETYPE_DYNAMIC_LASTQUARTER,
102
        self::AUTOFILTER_RULETYPE_DYNAMIC_LASTMONTH,
103
        self::AUTOFILTER_RULETYPE_DYNAMIC_LASTWEEK,
104
        self::AUTOFILTER_RULETYPE_DYNAMIC_NEXTYEAR,
105
        self::AUTOFILTER_RULETYPE_DYNAMIC_NEXTQUARTER,
106
        self::AUTOFILTER_RULETYPE_DYNAMIC_NEXTMONTH,
107
        self::AUTOFILTER_RULETYPE_DYNAMIC_NEXTWEEK,
108
        self::AUTOFILTER_RULETYPE_DYNAMIC_MONTH_1,
109
        self::AUTOFILTER_RULETYPE_DYNAMIC_MONTH_2,
110
        self::AUTOFILTER_RULETYPE_DYNAMIC_MONTH_3,
111
        self::AUTOFILTER_RULETYPE_DYNAMIC_MONTH_4,
112
        self::AUTOFILTER_RULETYPE_DYNAMIC_MONTH_5,
113
        self::AUTOFILTER_RULETYPE_DYNAMIC_MONTH_6,
114
        self::AUTOFILTER_RULETYPE_DYNAMIC_MONTH_7,
115
        self::AUTOFILTER_RULETYPE_DYNAMIC_MONTH_8,
116
        self::AUTOFILTER_RULETYPE_DYNAMIC_MONTH_9,
117
        self::AUTOFILTER_RULETYPE_DYNAMIC_MONTH_10,
118
        self::AUTOFILTER_RULETYPE_DYNAMIC_MONTH_11,
119
        self::AUTOFILTER_RULETYPE_DYNAMIC_MONTH_12,
120
        self::AUTOFILTER_RULETYPE_DYNAMIC_QUARTER_1,
121
        self::AUTOFILTER_RULETYPE_DYNAMIC_QUARTER_2,
122
        self::AUTOFILTER_RULETYPE_DYNAMIC_QUARTER_3,
123
        self::AUTOFILTER_RULETYPE_DYNAMIC_QUARTER_4,
124
        self::AUTOFILTER_RULETYPE_DYNAMIC_ABOVEAVERAGE,
125
        self::AUTOFILTER_RULETYPE_DYNAMIC_BELOWAVERAGE,
126
    ];
127
 
128
    // Filter rule operators for filter and customFilter types.
129
    const AUTOFILTER_COLUMN_RULE_EQUAL = 'equal';
130
    const AUTOFILTER_COLUMN_RULE_NOTEQUAL = 'notEqual';
131
    const AUTOFILTER_COLUMN_RULE_GREATERTHAN = 'greaterThan';
132
    const AUTOFILTER_COLUMN_RULE_GREATERTHANOREQUAL = 'greaterThanOrEqual';
133
    const AUTOFILTER_COLUMN_RULE_LESSTHAN = 'lessThan';
134
    const AUTOFILTER_COLUMN_RULE_LESSTHANOREQUAL = 'lessThanOrEqual';
135
 
136
    private const OPERATORS = [
137
        self::AUTOFILTER_COLUMN_RULE_EQUAL,
138
        self::AUTOFILTER_COLUMN_RULE_NOTEQUAL,
139
        self::AUTOFILTER_COLUMN_RULE_GREATERTHAN,
140
        self::AUTOFILTER_COLUMN_RULE_GREATERTHANOREQUAL,
141
        self::AUTOFILTER_COLUMN_RULE_LESSTHAN,
142
        self::AUTOFILTER_COLUMN_RULE_LESSTHANOREQUAL,
143
    ];
144
 
145
    const AUTOFILTER_COLUMN_RULE_TOPTEN_BY_VALUE = 'byValue';
146
    const AUTOFILTER_COLUMN_RULE_TOPTEN_PERCENT = 'byPercent';
147
 
148
    private const TOP_TEN_VALUE = [
149
        self::AUTOFILTER_COLUMN_RULE_TOPTEN_BY_VALUE,
150
        self::AUTOFILTER_COLUMN_RULE_TOPTEN_PERCENT,
151
    ];
152
 
153
    const AUTOFILTER_COLUMN_RULE_TOPTEN_TOP = 'top';
154
    const AUTOFILTER_COLUMN_RULE_TOPTEN_BOTTOM = 'bottom';
155
 
156
    private const TOP_TEN_TYPE = [
157
        self::AUTOFILTER_COLUMN_RULE_TOPTEN_TOP,
158
        self::AUTOFILTER_COLUMN_RULE_TOPTEN_BOTTOM,
159
    ];
160
 
161
    //  Unimplented Rule Operators (Numeric, Boolean etc)
162
    //    const AUTOFILTER_COLUMN_RULE_BETWEEN = 'between';        //    greaterThanOrEqual 1 && lessThanOrEqual 2
163
    // Rule Operators (Numeric Special) which are translated to standard numeric operators with calculated values
164
    // Rule Operators (String) which are set as wild-carded values
165
    //    const AUTOFILTER_COLUMN_RULE_BEGINSWITH            = 'beginsWith';            // A*
166
    //    const AUTOFILTER_COLUMN_RULE_ENDSWITH            = 'endsWith';            // *Z
167
    //    const AUTOFILTER_COLUMN_RULE_CONTAINS            = 'contains';            // *B*
168
    //    const AUTOFILTER_COLUMN_RULE_DOESNTCONTAIN        = 'notEqual';            //    notEqual *B*
169
    // Rule Operators (Date Special) which are translated to standard numeric operators with calculated values
170
    //    const AUTOFILTER_COLUMN_RULE_BEFORE                = 'lessThan';
171
    //    const AUTOFILTER_COLUMN_RULE_AFTER                = 'greaterThan';
172
    /**
173
     * Autofilter Column.
174
     */
175
    private ?Column $parent;
176
 
177
    /**
178
     * Autofilter Rule Type.
179
     */
180
    private string $ruleType = self::AUTOFILTER_RULETYPE_FILTER;
181
 
182
    /**
183
     * Autofilter Rule Value.
184
     *
185
     * @var int|int[]|string|string[]
186
     */
187
    private $value = '';
188
 
189
    /**
190
     * Autofilter Rule Operator.
191
     */
192
    private string $operator = self::AUTOFILTER_COLUMN_RULE_EQUAL;
193
 
194
    /**
195
     * DateTimeGrouping Group Value.
196
     */
197
    private string $grouping = '';
198
 
199
    /**
200
     * Create a new Rule.
201
     */
202
    public function __construct(?Column $parent = null)
203
    {
204
        $this->parent = $parent;
205
    }
206
 
207
    private function setEvaluatedFalse(): void
208
    {
209
        if ($this->parent !== null) {
210
            $this->parent->setEvaluatedFalse();
211
        }
212
    }
213
 
214
    /**
215
     * Get AutoFilter Rule Type.
216
     */
217
    public function getRuleType(): string
218
    {
219
        return $this->ruleType;
220
    }
221
 
222
    /**
223
     * Set AutoFilter Rule Type.
224
     *
225
     * @param string $ruleType see self::AUTOFILTER_RULETYPE_*
226
     *
227
     * @return $this
228
     */
229
    public function setRuleType(string $ruleType): static
230
    {
231
        $this->setEvaluatedFalse();
232
        if (!in_array($ruleType, self::RULE_TYPES)) {
233
            throw new PhpSpreadsheetException('Invalid rule type for column AutoFilter Rule.');
234
        }
235
 
236
        $this->ruleType = $ruleType;
237
 
238
        return $this;
239
    }
240
 
241
    /**
242
     * Get AutoFilter Rule Value.
243
     *
244
     * @return int|int[]|string|string[]
245
     */
246
    public function getValue()
247
    {
248
        return $this->value;
249
    }
250
 
251
    /**
252
     * Set AutoFilter Rule Value.
253
     *
254
     * @param int|int[]|string|string[] $value
255
     *
256
     * @return $this
257
     */
258
    public function setValue($value): static
259
    {
260
        $this->setEvaluatedFalse();
261
        if (is_array($value)) {
262
            $grouping = -1;
263
            foreach ($value as $key => $v) {
264
                //    Validate array entries
265
                if (!in_array($key, self::DATE_TIME_GROUPS)) {
266
                    //    Remove any invalid entries from the value array
267
                    unset($value[$key]);
268
                } else {
269
                    //    Work out what the dateTime grouping will be
270
                    $grouping = max($grouping, array_search($key, self::DATE_TIME_GROUPS));
271
                }
272
            }
273
            if (count($value) == 0) {
274
                throw new PhpSpreadsheetException('Invalid rule value for column AutoFilter Rule.');
275
            }
276
            //    Set the dateTime grouping that we've anticipated
277
            $this->setGrouping(self::DATE_TIME_GROUPS[$grouping]);
278
        }
279
        $this->value = $value;
280
 
281
        return $this;
282
    }
283
 
284
    /**
285
     * Get AutoFilter Rule Operator.
286
     */
287
    public function getOperator(): string
288
    {
289
        return $this->operator;
290
    }
291
 
292
    /**
293
     * Set AutoFilter Rule Operator.
294
     *
295
     * @param string $operator see self::AUTOFILTER_COLUMN_RULE_*
296
     *
297
     * @return $this
298
     */
299
    public function setOperator(string $operator): static
300
    {
301
        $this->setEvaluatedFalse();
302
        if (empty($operator)) {
303
            $operator = self::AUTOFILTER_COLUMN_RULE_EQUAL;
304
        }
305
        if (
306
            (!in_array($operator, self::OPERATORS))
307
            && (!in_array($operator, self::TOP_TEN_VALUE))
308
        ) {
309
            throw new PhpSpreadsheetException('Invalid operator for column AutoFilter Rule.');
310
        }
311
        $this->operator = $operator;
312
 
313
        return $this;
314
    }
315
 
316
    /**
317
     * Get AutoFilter Rule Grouping.
318
     */
319
    public function getGrouping(): string
320
    {
321
        return $this->grouping;
322
    }
323
 
324
    /**
325
     * Set AutoFilter Rule Grouping.
326
     *
327
     * @return $this
328
     */
329
    public function setGrouping(string $grouping): static
330
    {
331
        $this->setEvaluatedFalse();
332
        if (
333
            (!in_array($grouping, self::DATE_TIME_GROUPS))
334
            && (!in_array($grouping, self::DYNAMIC_TYPES))
335
            && (!in_array($grouping, self::TOP_TEN_TYPE))
336
        ) {
337
            throw new PhpSpreadsheetException('Invalid grouping for column AutoFilter Rule.');
338
        }
339
        $this->grouping = $grouping;
340
 
341
        return $this;
342
    }
343
 
344
    /**
345
     * Set AutoFilter Rule.
346
     *
347
     * @param string $operator see self::AUTOFILTER_COLUMN_RULE_*
348
     * @param int|int[]|string|string[] $value
349
     *
350
     * @return $this
351
     */
352
    public function setRule(string $operator, $value, ?string $grouping = null): static
353
    {
354
        $this->setEvaluatedFalse();
355
        $this->setOperator($operator);
356
        $this->setValue($value);
357
        //  Only set grouping if it's been passed in as a user-supplied argument,
358
        //      otherwise we're calculating it when we setValue() and don't want to overwrite that
359
        //      If the user supplies an argumnet for grouping, then on their own head be it
360
        if ($grouping !== null) {
361
            $this->setGrouping($grouping);
362
        }
363
 
364
        return $this;
365
    }
366
 
367
    /**
368
     * Get this Rule's AutoFilter Column Parent.
369
     */
370
    public function getParent(): ?Column
371
    {
372
        return $this->parent;
373
    }
374
 
375
    /**
376
     * Set this Rule's AutoFilter Column Parent.
377
     *
378
     * @return $this
379
     */
380
    public function setParent(?Column $parent = null): static
381
    {
382
        $this->setEvaluatedFalse();
383
        $this->parent = $parent;
384
 
385
        return $this;
386
    }
387
 
388
    /**
389
     * Implement PHP __clone to create a deep clone, not just a shallow copy.
390
     */
391
    public function __clone()
392
    {
393
        $vars = get_object_vars($this);
394
        foreach ($vars as $key => $value) {
395
            if (is_object($value)) {
396
                if ($key == 'parent') { // this is only object
397
                    //    Detach from autofilter column parent
398
                    $this->$key = null;
399
                }
400
            } else {
401
                $this->$key = $value;
402
            }
403
        }
404
    }
405
}