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
← All changes | libraries/vendor/PhpSpreadsheet/Worksheet/Worksheet.php +245 -12 3.3.3 → 3.4 View file →
@@ -31,8 +31,12 @@
31 31 use TablePress\PhpOffice\PhpSpreadsheet\Style\Conditional;
32 32 use TablePress\PhpOffice\PhpSpreadsheet\Style\NumberFormat;
33 33 use TablePress\PhpOffice\PhpSpreadsheet\Style\Protection as StyleProtection;
34 34 use TablePress\PhpOffice\PhpSpreadsheet\Style\Style;
35 +use TablePress\PhpOffice\PhpSpreadsheet\Worksheet\PivotTable\PivotTable;
36 +use TablePress\PhpOffice\PhpSpreadsheet\Worksheet\Sparkline\Sparkline;
37 +use TablePress\PhpOffice\PhpSpreadsheet\Worksheet\Sparkline\SparklineGroup;
38 +use TablePress\PhpOffice\PhpSpreadsheet\Worksheet\Sparkline\SparklineType;
35 39
36 40 class Worksheet
37 41 {
38 42 // Break types
@@ -129,8 +133,22 @@
129 133 */
130 134 private ArrayObject $tableCollection;
131 135
132 136 /**
137 + * Collection of SparklineGroup objects.
138 + *
139 + * @var ArrayObject<int, SparklineGroup>
140 + */
141 + private ArrayObject $sparklineGroupCollection;
142 +
143 + /**
144 + * Collection of PivotTable objects.
145 + *
146 + * @var ArrayObject<int, PivotTable>
147 + */
148 + private ArrayObject $pivotTableCollection;
149 +
150 + /**
133 151 * Worksheet title.
134 152 */
135 153 private string $title = '';
136 154
@@ -324,9 +342,11 @@
324 342 public function __construct(?Spreadsheet $parent = null, string $title = 'Worksheet')
325 343 {
326 344 // Set parent and title
327 345 $this->parent = $parent;
328 - $this->setTitle($title, false);
346 + // Chart collection must be set before title
347 + $this->chartCollection = new ArrayObject();
348 + $this->setTitle($title, false, true, false);
329 349 // setTitle can change $pTitle
330 350 $this->setCodeName($this->getTitle());
331 351 $this->setSheetState(self::SHEETSTATE_VISIBLE);
332 352
@@ -342,10 +362,8 @@
342 362 // Drawing collection
343 363 $this->drawingCollection = new ArrayObject();
344 364 // In Cell Drawing collection
345 365 $this->inCellDrawingCollection = new ArrayObject();
346 - // Chart collection
347 - $this->chartCollection = new ArrayObject();
348 366 // Protection
349 367 $this->protection = new Protection();
350 368 // Default row dimension
351 369 $this->defaultRowDimension = new RowDimension(null);
@@ -354,17 +372,24 @@
354 372 // AutoFilter
355 373 $this->autoFilter = new AutoFilter('', $this);
356 374 // Table collection
357 375 $this->tableCollection = new ArrayObject();
376 + // Sparkline group collection
377 + $this->sparklineGroupCollection = new ArrayObject();
378 +
379 + // Pivot table collection
380 + $this->pivotTableCollection = new ArrayObject();
358 381 }
359 382
360 383 /**
361 384 * Disconnect all cells from this Worksheet object,
362 385 * typically so that the worksheet object can be unset.
386 + * The worksheet will be in an unusable state after
387 + * this method has completed.
363 388 */
364 389 public function disconnectCells(): void
365 390 {
366 - if (isset($this->cellCollection)) { //* @phpstan-ignore-line
391 + if (isset($this->cellCollection)) { //* @phpstan-ignore isset.initializedProperty (may be null at destruct time)
367 392 $this->cellCollection->unsetWorksheetCells();
368 393 unset($this->cellCollection);
369 394 }
370 395 // detach ourself from the workbook, so that it can then delete this worksheet successfully
@@ -378,9 +403,9 @@
378 403 {
379 404 ($nullsafeVariable1 = Calculation::getInstanceOrNull($this->parent)) ? $nullsafeVariable1->clearCalculationCacheForWorksheet($this->title) : null;
380 405
381 406 $this->disconnectCells();
382 - unset($this->rowDimensions, $this->columnDimensions, $this->tableCollection, $this->drawingCollection, $this->inCellDrawingCollection, $this->chartCollection, $this->autoFilter);
407 + unset($this->rowDimensions, $this->columnDimensions, $this->tableCollection, $this->sparklineGroupCollection, $this->drawingCollection, $this->inCellDrawingCollection, $this->chartCollection, $this->autoFilter, $this->pivotTableCollection);
383 408 }
384 409
385 410 /**
386 411 * Return the cell collection.
@@ -460,9 +485,9 @@
460 485 * @return string[]
461 486 */
462 487 public function getCoordinates(bool $sorted = true): array
463 488 {
464 - if (!isset($this->cellCollection)) { //* @phpstan-ignore-line
489 + if (!isset($this->cellCollection)) { //* @phpstan-ignore isset.initializedProperty (may be null at destruct time)
465 490 return [];
466 491 }
467 492
468 493 if ($sorted) {
@@ -794,10 +819,11 @@
794 819 }
795 820 $this->activePane = $holdActivePane;
796 821 }
797 822 if ($activeSheet !== null && $activeSheet >= 0) {
798 - // Not sure what PhpStan doesn't like about next stmt
799 - ($nullsafeVariable3 = $this->getParent()) ? $nullsafeVariable3->setActiveSheetIndex($activeSheet) : null; // @phpstan-ignore-line
823 + // Okay, I get it now - if $activeSheet is not null,
824 + // then $this->getParent() must also be non-null.
825 + $this->getParent()->setActiveSheetIndex($activeSheet);
800 826 }
801 827 $this->setSelectedCells($selectedCells);
802 828
803 829 return $this;
@@ -873,9 +899,9 @@
873 899 * at parse time (by Readers), where titles can be assumed to be valid.
874 900 *
875 901 * @return $this
876 902 */
877 - public function setTitle(string $title, bool $updateFormulaCellReferences = true, bool $validate = true)
903 + public function setTitle(string $title, bool $updateFormulaCellReferences = true, bool $validate = true, bool $changeChartSheetNames = true)
878 904 {
879 905 // Is this a 'rename' or not?
880 906 if ($this->getTitle() == $title) {
881 907 return $this;
@@ -926,12 +952,63 @@
926 952 if ($updateFormulaCellReferences) {
927 953 ReferenceHelper::getInstance()->updateNamedFormulae($this->parent, $oldTitle, $newTitle);
928 954 }
929 955 }
956 + if ($changeChartSheetNames) {
957 + $this->changeChartSheetNames($oldTitle, $title);
958 + }
930 959
931 960 return $this;
932 961 }
933 962
963 + private function changeChartSheetNames(string $oldTitle, string $title): void
964 + {
965 + $worksheets = [$this];
966 + if ($this->parent !== null) {
967 + $sheets = $this->parent->getAllSheets();
968 + if (in_array($this, $sheets, true)) {
969 + $worksheets = $sheets;
970 + }
971 + }
972 + $titleq = "'$title'!";
973 + $oldTitleq1 = preg_quote("'$oldTitle'!");
974 + $oldTitleq2 = preg_quote("$oldTitle!");
975 + $preg1 = "/$oldTitleq1|\\b$oldTitleq2/";
976 + foreach ($worksheets as $sheet) {
977 + foreach ($sheet->getChartCollection() as $chart) {
978 + foreach (((($nullsafeVariable3 = $chart->getPlotArea()) ? $nullsafeVariable3->getPlotGroup() : null) ?? []) as $plotGroup) {
979 + foreach ($plotGroup->getPlotCategories() as $plotCategory) {
980 + $dataSource = (string) $plotCategory->getDataSource();
981 + $dataSource2 = Preg::replace($preg1, $titleq, $dataSource);
982 + if ($dataSource2 !== $dataSource) {
983 + $plotCategory->setDataSource(
984 + $dataSource2
985 + );
986 + }
987 + }
988 + foreach ($plotGroup->getPlotLabels() as $plotLabel) {
989 + $dataSource = (string) $plotLabel->getDataSource();
990 + $dataSource2 = Preg::replace($preg1, $titleq, $dataSource);
991 + if ($dataSource2 !== $dataSource) {
992 + $plotLabel->setDataSource(
993 + $dataSource2
994 + );
995 + }
996 + }
997 + foreach ($plotGroup->getPlotValues() as $plotValue) {
998 + $dataSource = (string) $plotValue->getDataSource();
999 + $dataSource2 = Preg::replace($preg1, $titleq, $dataSource);
1000 + if ($dataSource2 !== $dataSource) {
1001 + $plotValue->setDataSource(
1002 + $dataSource2
1003 + );
1004 + }
1005 + }
1006 + }
1007 + }
1008 + }
1009 + }
1010 +
934 1011 /**
935 1012 * Get sheet state.
936 1013 *
937 1014 * @return string Sheet state (visible, hidden, veryHidden)
@@ -1232,10 +1309,9 @@
1232 1309 if ($sheet === null) {
1233 1310 throw new Exception('Sheet not found for named range: ' . $namedRange->getName());
1234 1311 }
1235 1312
1236 - /** @phpstan-ignore-next-line */
1237 - $cellCoordinate = ltrim((string) substr($namedRange->getValue(), strrpos($namedRange->getValue(), '!')), '!');
1313 + $cellCoordinate = ltrim((string) substr($namedRange->getValue(), (int) strrpos($namedRange->getValue(), '!')), '!');
1238 1314 $finalCoordinate = str_replace('$', '', $cellCoordinate);
1239 1315 }
1240 1316 }
1241 1317
@@ -1677,9 +1753,9 @@
1677 1753 */
1678 1754 public function duplicateConditionalStyle(array $styles, string $range = '')
1679 1755 {
1680 1756 foreach ($styles as $cellStyle) {
1681 - if (!($cellStyle instanceof Conditional)) { // @phpstan-ignore-line
1757 + if (!($cellStyle instanceof Conditional)) {
1682 1758 throw new Exception('Style is not a conditional style');
1683 1759 }
1684 1760 }
1685 1761
@@ -2166,8 +2242,136 @@
2166 2242 return $this;
2167 2243 }
2168 2244
2169 2245 /**
2246 + * Get collection of SparklineGroups.
2247 + *
2248 + * @return ArrayObject<int, SparklineGroup>
2249 + */
2250 + public function getSparklineGroupCollection(): ArrayObject
2251 + {
2252 + return $this->sparklineGroupCollection;
2253 + }
2254 +
2255 + /**
2256 + * Add a SparklineGroup.
2257 + *
2258 + * @return $this
2259 + */
2260 + public function addSparklineGroup(SparklineGroup $sparklineGroup): self
2261 + {
2262 + $this->sparklineGroupCollection[] = $sparklineGroup;
2263 +
2264 + return $this;
2265 + }
2266 +
2267 + /**
2268 + * Add a single Sparkline, wrapping it in its own SparklineGroup.
2269 + *
2270 + * This is a convenience method for the common case of adding one sparkline
2271 + * with default formatting; the created group is returned so its formatting
2272 + * can be adjusted.
2273 + *
2274 + * @param mixed $type the type of sparkline (defaults to line)
2275 + * @param \TablePress\PhpOffice\PhpSpreadsheet\Worksheet\Sparkline\SparklineType::* $type
2276 + */
2277 + public function addSparkline(Sparkline $sparkline, $type = SparklineType::Line): SparklineGroup
2278 + {
2279 + $group = new SparklineGroup();
2280 + $group->setType($type);
2281 + $group->addSparkline($sparkline);
2282 + $this->addSparklineGroup($group);
2283 +
2284 + return $group;
2285 + }
2286 +
2287 + /**
2288 + * Remove all SparklineGroups.
2289 + *
2290 + * @return $this
2291 + */
2292 + public function removeSparklineGroupCollection(): self
2293 + {
2294 + $this->sparklineGroupCollection = new ArrayObject();
2295 +
2296 + return $this;
2297 + }
2298 +
2299 + /**
2300 + * Get collection of PivotTables.
2301 + *
2302 + * @return ArrayObject<int, PivotTable>
2303 + */
2304 + public function getPivotTableCollection(): ArrayObject
2305 + {
2306 + return $this->pivotTableCollection;
2307 + }
2308 +
2309 + /**
2310 + * Get collection of PivotTables (alias of getPivotTableCollection()).
2311 + *
2312 + * @return ArrayObject<int, PivotTable>
2313 + */
2314 + public function getPivotTables(): ArrayObject
2315 + {
2316 + return $this->pivotTableCollection;
2317 + }
2318 +
2319 + /**
2320 + * Add a PivotTable to this worksheet.
2321 + *
2322 + * @return $this
2323 + */
2324 + public function addPivotTable(PivotTable $pivotTable): self
2325 + {
2326 + $pivotTable->setWorksheet($this);
2327 + $this->pivotTableCollection[] = $pivotTable;
2328 +
2329 + return $this;
2330 + }
2331 +
2332 + /**
2333 + * @return string[] array of PivotTable names
2334 + */
2335 + public function getPivotTableNames(): array
2336 + {
2337 + $pivotTableNames = [];
2338 +
2339 + foreach ($this->pivotTableCollection as $pivotTable) {
2340 + $pivotTableNames[] = $pivotTable->getName();
2341 + }
2342 +
2343 + return $pivotTableNames;
2344 + }
2345 +
2346 + /**
2347 + * @param string $name the pivot table name to search
2348 + *
2349 + * @return null|PivotTable The pivot table from the collection, or null if not found
2350 + */
2351 + public function getPivotTableByName(string $name): ?PivotTable
2352 + {
2353 + $name = StringHelper::strToUpper($name);
2354 + foreach ($this->pivotTableCollection as $pivotTable) {
2355 + if (StringHelper::strToUpper($pivotTable->getName()) === $name) {
2356 + return $pivotTable;
2357 + }
2358 + }
2359 +
2360 + return null;
2361 + }
2362 +
2363 + /**
2364 + * Remove collection of PivotTables.
2365 + */
2366 + public function removePivotTableCollection(): self
2367 + {
2368 + $this->pivotTableCollection = new ArrayObject();
2369 +
2370 + return $this;
2371 + }
2372 +
2373 + /**
2170 2374 * Get Freeze Pane.
2171 2375 */
2172 2376 public function getFreezePane(): ?string
2173 2377 {
@@ -2437,8 +2641,20 @@
2437 2641 {
2438 2642 if ($row < 1) {
2439 2643 throw new Exception('Rows to be deleted should at least start from row 1.');
2440 2644 }
2645 + if ($numberOfRows === 0) {
2646 + return $this;
2647 + }
2648 + if ($numberOfRows < 0) {
2649 + $newRow = max(1, $row + $numberOfRows + 1);
2650 + $numberOfRows = $row - $newRow + 1;
2651 + $row = $newRow;
2652 + }
2653 + $newHighestRow = $this->cachedHighestRow;
2654 + if ($newHighestRow >= $row) {
2655 + $newHighestRow = max($row - 1, $this->cachedHighestRow - $numberOfRows);
2656 + }
2441 2657 $startRow = $row;
2442 2658 $endRow = $startRow + $numberOfRows - 1;
2443 2659 $removeKeys = [];
2444 2660 $addKeys = [];
@@ -2493,8 +2709,9 @@
2493 2709 --$highestRow;
2494 2710 }
2495 2711
2496 2712 $this->rowDimensions = $holdRowDimensions;
2713 + $this->cachedHighestRow = $newHighestRow;
2497 2714
2498 2715 return $this;
2499 2716 }
2500 2717
@@ -2531,8 +2748,21 @@
2531 2748 if (is_numeric($column)) {
2532 2749 throw new Exception('Column references should not be numeric.');
2533 2750 }
2534 2751 $startColumnInt = Coordinate::columnIndexFromString($column);
2752 + if ($numberOfColumns === 0) {
2753 + return $this;
2754 + }
2755 + if ($numberOfColumns < 0) {
2756 + $newStartColumnInt = max(1, $startColumnInt + $numberOfColumns + 1);
2757 + $numberOfColumns = $startColumnInt - $newStartColumnInt + 1;
2758 + $startColumnInt = $newStartColumnInt;
2759 + $column = Coordinate::stringFromColumnIndex($startColumnInt);
2760 + }
2761 + $newHighestColumn = $this->cachedHighestColumn;
2762 + if ($newHighestColumn >= $startColumnInt) {
2763 + $newHighestColumn = max($startColumnInt - 1, $this->cachedHighestColumn - $numberOfColumns);
2764 + }
2535 2765 $endColumnInt = $startColumnInt + $numberOfColumns - 1;
2536 2766 $removeKeys = [];
2537 2767 $addKeys = [];
2538 2768 foreach ($this->mergeCells as $key => $value) {
@@ -2581,8 +2811,10 @@
2581 2811
2582 2812 $this->columnDimensions = $holdColumnDimensions;
2583 2813
2584 2814 if ($pColumnIndex > $highestColumnIndex) {
2815 + $this->cachedHighestColumn = $newHighestColumn;
2816 +
2585 2817 return $this;
2586 2818 }
2587 2819
2588 2820 $maxPossibleColumnsToBeRemoved = $highestColumnIndex - $pColumnIndex + 1;
@@ -2590,8 +2822,9 @@
2590 2822 for ($c = 0, $n = min($maxPossibleColumnsToBeRemoved, $numberOfColumns); $c < $n; ++$c) {
2591 2823 $this->cellCollection->removeColumn($highestColumn);
2592 2824 $highestColumn = Coordinate::stringFromColumnIndex(Coordinate::columnIndexFromString($highestColumn) - 1);
2593 2825 }
2826 + $this->cachedHighestColumn = $newHighestColumn;
2594 2827
2595 2828 $this->garbageCollect();
2596 2829
2597 2830 return $this;