PluginProbe
TablePress – Tables in WordPress made easy / 3.4
TablePress – Tables in WordPress made easy v3.4
3.4 3.3.4 3.3.3 3.3.2 3.3.1 trunk 1.12 1.14 1.9.2 2.0.4 2.1.7 2.1.8 2.2 2.2.1 2.2.2 2.2.3 2.2.4 2.2.5 2.3 2.3.1 2.3.2 2.4 2.4.1 2.4.2 2.4.3 All 45 releases
tablepress / libraries / vendor / PhpSpreadsheet / Calculation / Engine / BranchPruner.php

BranchPruner.php in TablePress – Tables in WordPress made easy 3.4, at libraries/vendor/PhpSpreadsheet/Calculation/Engine/BranchPruner.php

205 lines 5.2 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace TablePress\PhpOffice\PhpSpreadsheet\Calculation\Engine;
4
5 use TablePress\PhpOffice\PhpSpreadsheet\Calculation\Exception;
6
7 class BranchPruner
8 {
9 protected bool $branchPruningEnabled;
10
11 /**
12 * Used to generate unique store keys.
13 */
14 private int $branchStoreKeyCounter = 0;
15
16 /**
17 * currently pending storeKey (last item of the storeKeysStack.
18 */
19 protected ?string $pendingStoreKey = null;
20
21 /**
22 * @var string[]
23 */
24 protected array $storeKeysStack = [];
25
26 /**
27 * @var bool[]
28 */
29 protected array $conditionMap = [];
30
31 /**
32 * @var bool[]
33 */
34 protected array $thenMap = [];
35
36 /**
37 * @var bool[]
38 */
39 protected array $elseMap = [];
40
41 /**
42 * @var int[]
43 */
44 protected array $braceDepthMap = [];
45
46 protected ?string $currentCondition = null;
47
48 protected ?string $currentOnlyIf = null;
49
50 protected ?string $currentOnlyIfNot = null;
51
52 protected ?string $previousStoreKey = null;
53
54 public function __construct(bool $branchPruningEnabled)
55 {
56 $this->branchPruningEnabled = $branchPruningEnabled;
57 }
58
59 public function clearBranchStore(): void
60 {
61 $this->branchStoreKeyCounter = 0;
62 }
63
64 public function initialiseForLoop(): void
65 {
66 $this->currentCondition = null;
67 $this->currentOnlyIf = null;
68 $this->currentOnlyIfNot = null;
69 $this->previousStoreKey = null;
70 $this->pendingStoreKey = empty($this->storeKeysStack) ? null : end($this->storeKeysStack);
71
72 if ($this->branchPruningEnabled) {
73 $this->initialiseCondition();
74 $this->initialiseThen();
75 $this->initialiseElse();
76 }
77 }
78
79 private function initialiseCondition(): void
80 {
81 if (isset($this->pendingStoreKey, $this->conditionMap[$this->pendingStoreKey]) && $this->conditionMap[$this->pendingStoreKey]) {
82 $this->currentCondition = $this->pendingStoreKey;
83 $stackDepth = count($this->storeKeysStack);
84 if ($stackDepth > 1) {
85 // nested if
86 $this->previousStoreKey = $this->storeKeysStack[$stackDepth - 2];
87 }
88 }
89 }
90
91 private function initialiseThen(): void
92 {
93 if (isset($this->pendingStoreKey, $this->thenMap[$this->pendingStoreKey]) && $this->thenMap[$this->pendingStoreKey]) {
94 $this->currentOnlyIf = $this->pendingStoreKey;
95 } elseif (
96 isset($this->previousStoreKey, $this->thenMap[$this->previousStoreKey])
97 && $this->thenMap[$this->previousStoreKey]
98 ) {
99 $this->currentOnlyIf = $this->previousStoreKey;
100 }
101 }
102
103 private function initialiseElse(): void
104 {
105 if (isset($this->pendingStoreKey, $this->elseMap[$this->pendingStoreKey]) && $this->elseMap[$this->pendingStoreKey]) {
106 $this->currentOnlyIfNot = $this->pendingStoreKey;
107 } elseif (
108 isset($this->previousStoreKey, $this->elseMap[$this->previousStoreKey])
109 && $this->elseMap[$this->previousStoreKey]
110 ) {
111 $this->currentOnlyIfNot = $this->previousStoreKey;
112 }
113 }
114
115 public function decrementDepth(): void
116 {
117 if (!empty($this->pendingStoreKey)) {
118 --$this->braceDepthMap[$this->pendingStoreKey];
119 }
120 }
121
122 public function incrementDepth(): void
123 {
124 if (!empty($this->pendingStoreKey)) {
125 ++$this->braceDepthMap[$this->pendingStoreKey];
126 }
127 }
128
129 public function functionCall(string $functionName): void
130 {
131 if ($this->branchPruningEnabled && ($functionName === 'IF(')) {
132 // we handle a new if
133 $this->pendingStoreKey = $this->getUnusedBranchStoreKey();
134 $this->storeKeysStack[] = $this->pendingStoreKey;
135 $this->conditionMap[$this->pendingStoreKey] = true;
136 $this->braceDepthMap[$this->pendingStoreKey] = 0;
137 } elseif (!empty($this->pendingStoreKey) && array_key_exists($this->pendingStoreKey, $this->braceDepthMap)) {
138 // this is not an if but we go deeper
139 ++$this->braceDepthMap[$this->pendingStoreKey];
140 }
141 }
142
143 public function argumentSeparator(): void
144 {
145 if (!empty($this->pendingStoreKey) && $this->braceDepthMap[$this->pendingStoreKey] === 0) {
146 // We must go to the IF next argument
147 if ($this->conditionMap[$this->pendingStoreKey]) {
148 $this->conditionMap[$this->pendingStoreKey] = false;
149 $this->thenMap[$this->pendingStoreKey] = true;
150 } elseif ($this->thenMap[$this->pendingStoreKey]) {
151 $this->thenMap[$this->pendingStoreKey] = false;
152 $this->elseMap[$this->pendingStoreKey] = true;
153 } elseif ($this->elseMap[$this->pendingStoreKey]) {
154 throw new Exception('Reaching fourth argument of an IF');
155 }
156 }
157 }
158
159 /**
160 * @param mixed $value
161 */
162 public function closingBrace($value): void
163 {
164 if (!empty($this->pendingStoreKey) && $this->braceDepthMap[$this->pendingStoreKey] === -1) {
165 // we are closing an IF(
166 if ($value !== 'IF(') {
167 throw new Exception('Parser bug we should be in an "IF("');
168 }
169
170 if ($this->conditionMap[$this->pendingStoreKey]) {
171 throw new Exception('We should not be expecting a condition');
172 }
173
174 $this->thenMap[$this->pendingStoreKey] = false;
175 $this->elseMap[$this->pendingStoreKey] = false;
176 --$this->braceDepthMap[$this->pendingStoreKey];
177 array_pop($this->storeKeysStack);
178 $this->pendingStoreKey = null;
179 }
180 }
181
182 public function currentCondition(): ?string
183 {
184 return $this->currentCondition;
185 }
186
187 public function currentOnlyIf(): ?string
188 {
189 return $this->currentOnlyIf;
190 }
191
192 public function currentOnlyIfNot(): ?string
193 {
194 return $this->currentOnlyIfNot;
195 }
196
197 private function getUnusedBranchStoreKey(): string
198 {
199 $storeKeyValue = 'storeKey-' . $this->branchStoreKeyCounter;
200 ++$this->branchStoreKeyCounter;
201
202 return $storeKeyValue;
203 }
204 }
205