Completed
Push — master ( c434e9...dcf3b9 )
by Adrien
09:01
created

Protection::getPivotTables()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 1
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 1
c 0
b 0
f 0
nc 1
nop 0
dl 0
loc 3
rs 10
ccs 1
cts 1
cp 1
crap 1
1
<?php
2
3
namespace PhpOffice\PhpSpreadsheet\Worksheet;
4
5
use PhpOffice\PhpSpreadsheet\Shared\PasswordHasher;
6
7
class Protection
8
{
9
    const ALGORITHM_MD2 = 'MD2';
10
    const ALGORITHM_MD4 = 'MD4';
11
    const ALGORITHM_MD5 = 'MD5';
12
    const ALGORITHM_SHA_1 = 'SHA-1';
13
    const ALGORITHM_SHA_256 = 'SHA-256';
14
    const ALGORITHM_SHA_384 = 'SHA-384';
15
    const ALGORITHM_SHA_512 = 'SHA-512';
16
    const ALGORITHM_RIPEMD_128 = 'RIPEMD-128';
17
    const ALGORITHM_RIPEMD_160 = 'RIPEMD-160';
18
    const ALGORITHM_WHIRLPOOL = 'WHIRLPOOL';
19
20
    /**
21
     * Sheet.
22
     *
23
     * @var bool
24
     */
25
    private $sheet = false;
26
27
    /**
28
     * Objects.
29
     *
30
     * @var bool
31
     */
32
    private $objects = false;
33
34
    /**
35
     * Scenarios.
36
     *
37
     * @var bool
38
     */
39
    private $scenarios = false;
40
41
    /**
42
     * Format cells.
43
     *
44
     * @var bool
45
     */
46
    private $formatCells = false;
47
48
    /**
49
     * Format columns.
50
     *
51
     * @var bool
52
     */
53
    private $formatColumns = false;
54
55
    /**
56
     * Format rows.
57
     *
58
     * @var bool
59
     */
60
    private $formatRows = false;
61
62
    /**
63
     * Insert columns.
64
     *
65
     * @var bool
66
     */
67
    private $insertColumns = false;
68
69
    /**
70
     * Insert rows.
71
     *
72
     * @var bool
73
     */
74
    private $insertRows = false;
75
76
    /**
77
     * Insert hyperlinks.
78
     *
79
     * @var bool
80
     */
81
    private $insertHyperlinks = false;
82
83
    /**
84
     * Delete columns.
85
     *
86
     * @var bool
87
     */
88
    private $deleteColumns = false;
89
90
    /**
91
     * Delete rows.
92
     *
93
     * @var bool
94
     */
95
    private $deleteRows = false;
96
97
    /**
98
     * Select locked cells.
99
     *
100
     * @var bool
101
     */
102
    private $selectLockedCells = false;
103
104
    /**
105
     * Sort.
106
     *
107
     * @var bool
108
     */
109
    private $sort = false;
110
111
    /**
112
     * AutoFilter.
113
     *
114
     * @var bool
115
     */
116
    private $autoFilter = false;
117
118
    /**
119
     * Pivot tables.
120
     *
121
     * @var bool
122
     */
123
    private $pivotTables = false;
124
125
    /**
126
     * Select unlocked cells.
127
     *
128
     * @var bool
129
     */
130
    private $selectUnlockedCells = false;
131 359
132
    /**
133 359
     * Hashed password.
134
     *
135
     * @var string
136
     */
137
    private $password = '';
138
139
    /**
140 240
     * Algorithm name.
141
     *
142 240
     * @var string
143 240
     */
144 240
    private $algorithm = '';
145 240
146 240
    /**
147 240
     * Hash value.
148 240
     *
149 240
     * @var string
150 240
     */
151 240
    private $hash = '';
152 240
153 240
    /**
154 240
     * Salt value.
155 240
     *
156 240
     * @var string
157 240
     */
158
    private $salt = '';
159
160
    /**
161
     * Spin count.
162
     *
163
     * @var int
164
     */
165 120
    private $spinCount = 10000;
166
167 120
    /**
168
     * Create a new Protection.
169
     */
170
    public function __construct()
171
    {
172
    }
173
174
    /**
175
     * Is some sort of protection enabled?
176
     *
177 70
     * @return bool
178
     */
179 70
    public function isProtectionEnabled()
180
    {
181 70
        return $this->sheet ||
182
            $this->objects ||
183
            $this->scenarios ||
184
            $this->formatCells ||
185
            $this->formatColumns ||
186
            $this->formatRows ||
187
            $this->insertColumns ||
188
            $this->insertRows ||
189 120
            $this->insertHyperlinks ||
190
            $this->deleteColumns ||
191 120
            $this->deleteRows ||
192
            $this->selectLockedCells ||
193
            $this->sort ||
194
            $this->autoFilter ||
195
            $this->pivotTables ||
196
            $this->selectUnlockedCells;
197
    }
198
199
    /**
200
     * Get Sheet.
201 75
     *
202
     * @return bool
203 75
     */
204
    public function getSheet()
205 75
    {
206
        return $this->sheet;
207
    }
208
209
    /**
210
     * Set Sheet.
211
     *
212
     * @param bool $pValue
213 120
     *
214
     * @return $this
215 120
     */
216
    public function setSheet($pValue)
217
    {
218
        $this->sheet = $pValue;
219
220
        return $this;
221
    }
222
223
    /**
224
     * Get Objects.
225 75
     *
226
     * @return bool
227 75
     */
228
    public function getObjects()
229 75
    {
230
        return $this->objects;
231
    }
232
233
    /**
234
     * Set Objects.
235
     *
236
     * @param bool $pValue
237 120
     *
238
     * @return $this
239 120
     */
240
    public function setObjects($pValue)
241
    {
242
        $this->objects = $pValue;
243
244
        return $this;
245
    }
246
247
    /**
248
     * Get Scenarios.
249 76
     *
250
     * @return bool
251 76
     */
252
    public function getScenarios()
253 76
    {
254
        return $this->scenarios;
255
    }
256
257
    /**
258
     * Set Scenarios.
259
     *
260
     * @param bool $pValue
261 120
     *
262
     * @return $this
263 120
     */
264
    public function setScenarios($pValue)
265
    {
266
        $this->scenarios = $pValue;
267
268
        return $this;
269
    }
270
271
    /**
272
     * Get FormatCells.
273 75
     *
274
     * @return bool
275 75
     */
276
    public function getFormatCells()
277 75
    {
278
        return $this->formatCells;
279
    }
280
281
    /**
282
     * Set FormatCells.
283
     *
284
     * @param bool $pValue
285 120
     *
286
     * @return $this
287 120
     */
288
    public function setFormatCells($pValue)
289
    {
290
        $this->formatCells = $pValue;
291
292
        return $this;
293
    }
294
295
    /**
296
     * Get FormatColumns.
297 75
     *
298
     * @return bool
299 75
     */
300
    public function getFormatColumns()
301 75
    {
302
        return $this->formatColumns;
303
    }
304
305
    /**
306
     * Set FormatColumns.
307
     *
308
     * @param bool $pValue
309 120
     *
310
     * @return $this
311 120
     */
312
    public function setFormatColumns($pValue)
313
    {
314
        $this->formatColumns = $pValue;
315
316
        return $this;
317
    }
318
319
    /**
320
     * Get FormatRows.
321 75
     *
322
     * @return bool
323 75
     */
324
    public function getFormatRows()
325 75
    {
326
        return $this->formatRows;
327
    }
328
329
    /**
330
     * Set FormatRows.
331
     *
332
     * @param bool $pValue
333 120
     *
334
     * @return $this
335 120
     */
336
    public function setFormatRows($pValue)
337
    {
338
        $this->formatRows = $pValue;
339
340
        return $this;
341
    }
342
343
    /**
344
     * Get InsertColumns.
345 76
     *
346
     * @return bool
347 76
     */
348
    public function getInsertColumns()
349 76
    {
350
        return $this->insertColumns;
351
    }
352
353
    /**
354
     * Set InsertColumns.
355
     *
356
     * @param bool $pValue
357 120
     *
358
     * @return $this
359 120
     */
360
    public function setInsertColumns($pValue)
361
    {
362
        $this->insertColumns = $pValue;
363
364
        return $this;
365
    }
366
367
    /**
368
     * Get InsertRows.
369 75
     *
370
     * @return bool
371 75
     */
372
    public function getInsertRows()
373 75
    {
374
        return $this->insertRows;
375
    }
376
377
    /**
378
     * Set InsertRows.
379
     *
380
     * @param bool $pValue
381 120
     *
382
     * @return $this
383 120
     */
384
    public function setInsertRows($pValue)
385
    {
386
        $this->insertRows = $pValue;
387
388
        return $this;
389
    }
390
391
    /**
392
     * Get InsertHyperlinks.
393 75
     *
394
     * @return bool
395 75
     */
396
    public function getInsertHyperlinks()
397 75
    {
398
        return $this->insertHyperlinks;
399
    }
400
401
    /**
402
     * Set InsertHyperlinks.
403
     *
404
     * @param bool $pValue
405 120
     *
406
     * @return $this
407 120
     */
408
    public function setInsertHyperlinks($pValue)
409
    {
410
        $this->insertHyperlinks = $pValue;
411
412
        return $this;
413
    }
414
415
    /**
416
     * Get DeleteColumns.
417 75
     *
418
     * @return bool
419 75
     */
420
    public function getDeleteColumns()
421 75
    {
422
        return $this->deleteColumns;
423
    }
424
425
    /**
426
     * Set DeleteColumns.
427
     *
428
     * @param bool $pValue
429 120
     *
430
     * @return $this
431 120
     */
432
    public function setDeleteColumns($pValue)
433
    {
434
        $this->deleteColumns = $pValue;
435
436
        return $this;
437
    }
438
439
    /**
440
     * Get DeleteRows.
441 75
     *
442
     * @return bool
443 75
     */
444
    public function getDeleteRows()
445 75
    {
446
        return $this->deleteRows;
447
    }
448
449
    /**
450
     * Set DeleteRows.
451
     *
452
     * @param bool $pValue
453 120
     *
454
     * @return $this
455 120
     */
456
    public function setDeleteRows($pValue)
457
    {
458
        $this->deleteRows = $pValue;
459
460
        return $this;
461
    }
462
463
    /**
464
     * Get SelectLockedCells.
465 76
     *
466
     * @return bool
467 76
     */
468
    public function getSelectLockedCells()
469 76
    {
470
        return $this->selectLockedCells;
471
    }
472
473
    /**
474
     * Set SelectLockedCells.
475
     *
476
     * @param bool $pValue
477 120
     *
478
     * @return $this
479 120
     */
480
    public function setSelectLockedCells($pValue)
481
    {
482
        $this->selectLockedCells = $pValue;
483
484
        return $this;
485
    }
486
487
    /**
488
     * Get Sort.
489 75
     *
490
     * @return bool
491 75
     */
492
    public function getSort()
493 75
    {
494
        return $this->sort;
495
    }
496
497
    /**
498
     * Set Sort.
499
     *
500
     * @param bool $pValue
501 120
     *
502
     * @return $this
503 120
     */
504
    public function setSort($pValue)
505
    {
506
        $this->sort = $pValue;
507
508
        return $this;
509
    }
510
511
    /**
512
     * Get AutoFilter.
513 75
     *
514
     * @return bool
515 75
     */
516
    public function getAutoFilter()
517 75
    {
518
        return $this->autoFilter;
519
    }
520
521
    /**
522
     * Set AutoFilter.
523
     *
524
     * @param bool $pValue
525 120
     *
526
     * @return $this
527 120
     */
528
    public function setAutoFilter($pValue)
529
    {
530
        $this->autoFilter = $pValue;
531
532
        return $this;
533
    }
534
535
    /**
536
     * Get PivotTables.
537 75
     *
538
     * @return bool
539 75
     */
540
    public function getPivotTables()
541 75
    {
542
        return $this->pivotTables;
543
    }
544
545
    /**
546
     * Set PivotTables.
547
     *
548
     * @param bool $pValue
549 107
     *
550
     * @return $this
551 107
     */
552
    public function setPivotTables($pValue)
553
    {
554
        $this->pivotTables = $pValue;
555
556
        return $this;
557
    }
558
559
    /**
560
     * Get SelectUnlockedCells.
561
     *
562 59
     * @return bool
563
     */
564 59
    public function getSelectUnlockedCells()
565 1
    {
566
        return $this->selectUnlockedCells;
567 59
    }
568
569 59
    /**
570
     * Set SelectUnlockedCells.
571
     *
572
     * @param bool $pValue
573
     *
574
     * @return $this
575
     */
576
    public function setSelectUnlockedCells($pValue)
577
    {
578
        $this->selectUnlockedCells = $pValue;
579
580
        return $this;
581
    }
582
583
    /**
584
     * Get hashed password.
585
     *
586
     * @return string
587
     */
588
    public function getPassword()
589
    {
590
        return $this->password;
591
    }
592
593
    /**
594
     * Set Password.
595
     *
596
     * @param string $pValue
597
     * @param bool $pAlreadyHashed If the password has already been hashed, set this to true
598
     *
599
     * @return $this
600
     */
601
    public function setPassword($pValue, $pAlreadyHashed = false)
602
    {
603
        if (!$pAlreadyHashed) {
604
            $salt = $this->generateSalt();
605
            $this->setSalt($salt);
606
            $pValue = PasswordHasher::hashPassword($pValue, $this->getAlgorithm(), $this->getSalt(), $this->getSpinCount());
607
        }
608
609
        $this->password = $pValue;
610
611
        return $this;
612
    }
613
614
    /**
615
     * Create a pseudorandom string.
616
     */
617
    private function generateSalt(): string
618
    {
619
        return base64_encode(random_bytes(16));
620
    }
621
622
    /**
623
     * Get algorithm name.
624
     */
625
    public function getAlgorithm(): string
626
    {
627
        return $this->algorithm;
628
    }
629
630
    /**
631
     * Set algorithm name.
632
     */
633
    public function setAlgorithm(string $algorithm): void
634
    {
635
        $this->algorithm = $algorithm;
636
    }
637
638
    /**
639
     * Get salt value.
640
     */
641
    public function getSalt(): string
642
    {
643
        return $this->salt;
644
    }
645
646
    /**
647
     * Set salt value.
648
     */
649
    public function setSalt(string $salt): void
650
    {
651
        $this->salt = $salt;
652
    }
653
654
    /**
655
     * Get spin count.
656
     */
657
    public function getSpinCount(): int
658
    {
659
        return $this->spinCount;
660
    }
661
662
    /**
663
     * Set spin count.
664
     */
665
    public function setSpinCount(int $spinCount): void
666
    {
667
        $this->spinCount = $spinCount;
668
    }
669
670
    /**
671
     * Verify that the given non-hashed password can "unlock" the protection.
672
     */
673
    public function verify(string $password): bool
674
    {
675
        if (!$this->isProtectionEnabled()) {
676
            return true;
677
        }
678
679
        $hash = PasswordHasher::hashPassword($password, $this->getAlgorithm(), $this->getSalt(), $this->getSpinCount());
680
681
        return $this->getPassword() === $hash;
682
    }
683
684
    /**
685
     * Implement PHP __clone to create a deep clone, not just a shallow copy.
686
     */
687
    public function __clone()
688
    {
689
        $vars = get_object_vars($this);
690
        foreach ($vars as $key => $value) {
691
            if (is_object($value)) {
692
                $this->$key = clone $value;
693
            } else {
694
                $this->$key = $value;
695
            }
696
        }
697
    }
698
}
699