Below is a differential between the unpatched vulnerable code and the patched update, for reference.
--- a/tablepress/blocks/blocks-manifest.php
+++ b/tablepress/blocks/blocks-manifest.php
@@ -5,7 +5,7 @@
'$schema' => 'https://schemas.wp.org/trunk/block.json',
'apiVersion' => 3,
'name' => 'tablepress/table',
- 'version' => '3.0.2',
+ 'version' => '3.0.3',
'title' => 'TablePress table',
'category' => 'media',
'icon' => 'list-view',
--- a/tablepress/blocks/table/build/index.asset.php
+++ b/tablepress/blocks/table/build/index.asset.php
@@ -1 +1 @@
-<?php return array('dependencies' => array('react-jsx-runtime', 'wp-block-editor', 'wp-blocks', 'wp-components', 'wp-element', 'wp-i18n', 'wp-primitives', 'wp-server-side-render', 'wp-shortcode'), 'version' => 'cdcf4828488d034d7127');
+<?php return array('dependencies' => array('react-jsx-runtime', 'wp-block-editor', 'wp-blocks', 'wp-components', 'wp-element', 'wp-i18n', 'wp-primitives', 'wp-server-side-render', 'wp-shortcode'), 'version' => '1e19f120a27788ffcd8d');
--- a/tablepress/classes/class-tablepress.php
+++ b/tablepress/classes/class-tablepress.php
@@ -27,7 +27,7 @@
* @since 1.0.0
* @const string
*/
- public const version = '3.0.2'; // phpcs:ignore Generic.NamingConventions.UpperCaseConstantName.ClassConstantNotUpperCase
+ public const version = '3.0.3'; // phpcs:ignore Generic.NamingConventions.UpperCaseConstantName.ClassConstantNotUpperCase
/**
* TablePress internal plugin version ("options scheme" version).
@@ -37,7 +37,7 @@
* @since 1.0.0
* @const int
*/
- public const db_version = 98; // phpcs:ignore Generic.NamingConventions.UpperCaseConstantName.ClassConstantNotUpperCase
+ public const db_version = 99; // phpcs:ignore Generic.NamingConventions.UpperCaseConstantName.ClassConstantNotUpperCase
/**
* TablePress "table scheme" (data format structure) version.
--- a/tablepress/libraries/freemius/includes/class-freemius.php
+++ b/tablepress/libraries/freemius/includes/class-freemius.php
@@ -24000,13 +24000,15 @@
// Start trial button.
$button = ' ' . sprintf(
- '<a style="margin-left: 10px; vertical-align: super;" href="%s"><button class="button button-primary">%s ➜</button></a>',
+ '<div><a class="button button-primary" href="%s">%s ➜</a></div>',
$trial_url,
$this->get_text_x_inline( 'Start free trial', 'call to action', 'start-free-trial' )
);
+ $message_text = $this->apply_filters( 'trial_promotion_message', "{$message} {$cc_string}" );
+
$this->_admin_notices->add_sticky(
- $this->apply_filters( 'trial_promotion_message', "{$message} {$cc_string} {$button}" ),
+ "<div class="fs-trial-message-container"><div>{$message_text}</div> {$button}</div>",
'trial_promotion',
'',
'promotion'
@@ -25476,7 +25478,7 @@
$img_dir = WP_FS__DIR_IMG;
// Locate the main assets folder.
- if ( 1 < count( $fs_active_plugins->plugins ) ) {
+ if ( ! empty( $fs_active_plugins->plugins ) ) {
$plugin_or_theme_img_dir = ( $this->is_plugin() ? WP_PLUGIN_DIR : get_theme_root( get_stylesheet() ) );
foreach ( $fs_active_plugins->plugins as $sdk_path => &$data ) {
--- a/tablepress/libraries/freemius/includes/class-fs-plugin-updater.php
+++ b/tablepress/libraries/freemius/includes/class-fs-plugin-updater.php
@@ -542,24 +542,8 @@
global $wp_current_filter;
- $current_plugin_version = $this->_fs->get_plugin_version();
-
- if ( ! empty( $wp_current_filter ) && 'upgrader_process_complete' === $wp_current_filter[0] ) {
- if (
- is_null( $this->_update_details ) ||
- ( is_object( $this->_update_details ) && $this->_update_details->new_version !== $current_plugin_version )
- ) {
- /**
- * After an update, clear the stored update details and reparse the plugin's main file in order to get
- * the updated version's information and prevent the previous update information from showing up on the
- * updates page.
- *
- * @author Leo Fajardo (@leorw)
- * @since 2.3.1
- */
- $this->_update_details = null;
- $current_plugin_version = $this->_fs->get_plugin_version( true );
- }
+ if ( ! empty( $wp_current_filter ) && in_array( 'upgrader_process_complete', $wp_current_filter ) ) {
+ return $transient_data;
}
if ( ! isset( $this->_update_details ) ) {
@@ -568,7 +552,7 @@
false,
fs_request_get_bool( 'force-check' ),
FS_Plugin_Updater::UPDATES_CHECK_CACHE_EXPIRATION,
- $current_plugin_version
+ $this->_fs->get_plugin_version()
);
$this->_update_details = false;
--- a/tablepress/libraries/freemius/includes/entities/class-fs-plugin-plan.php
+++ b/tablepress/libraries/freemius/includes/entities/class-fs-plugin-plan.php
@@ -13,7 +13,6 @@
/**
* Class FS_Plugin_Plan
*
- * @property FS_Pricing[] $pricing
*/
class FS_Plugin_Plan extends FS_Entity {
--- a/tablepress/libraries/freemius/includes/entities/class-fs-site.php
+++ b/tablepress/libraries/freemius/includes/entities/class-fs-site.php
@@ -10,16 +10,16 @@
exit;
}
- /**
- * @property int $blog_id
- */
- #[AllowDynamicProperties]
class FS_Site extends FS_Scope_Entity {
/**
* @var number
*/
public $site_id;
/**
+ * @var int
+ */
+ public $blog_id;
+ /**
* @var number
*/
public $plugin_id;
--- a/tablepress/libraries/freemius/includes/entities/class-fs-user.php
+++ b/tablepress/libraries/freemius/includes/entities/class-fs-user.php
@@ -48,6 +48,19 @@
parent::__construct( $user );
}
+ /**
+ * This method removes the deprecated 'is_beta' property from the serialized data.
+ * Should clean up the serialized data to avoid PHP 8.2 warning on next execution.
+ *
+ * @return void
+ */
+ function __wakeup() {
+ if ( property_exists( $this, 'is_beta' ) ) {
+ // If we enter here, and we are running PHP 8.2, we already had the warning. But we sanitize data for next execution.
+ unset( $this->is_beta );
+ }
+ }
+
function get_name() {
return trim( ucfirst( trim( is_string( $this->first ) ? $this->first : '' ) ) . ' ' . ucfirst( trim( is_string( $this->last ) ? $this->last : '' ) ) );
}
--- a/tablepress/libraries/freemius/includes/managers/class-fs-admin-menu-manager.php
+++ b/tablepress/libraries/freemius/includes/managers/class-fs-admin-menu-manager.php
@@ -699,15 +699,35 @@
$menu = $this->find_main_submenu();
}
+ $menu_slug = $menu['menu'][2];
$parent_slug = isset( $menu['parent_slug'] ) ?
$menu['parent_slug'] :
'admin.php';
+ if ( fs_apply_filter( $this->_module_unique_affix, 'enable_cpt_advanced_menu_logic', false ) ) {
+ $parent_slug = 'admin.php';
+
+ /**
+ * This line and the `if` block below it are based on the `menu_page_url()` function of WordPress.
+ *
+ * @author Leo Fajardo (@leorw)
+ * @since 2.10.2
+ */
+ global $_parent_pages;
+
+ if ( ! empty( $_parent_pages[ $menu_slug ] ) ) {
+ $_parent_slug = $_parent_pages[ $menu_slug ];
+ $parent_slug = isset( $_parent_pages[ $_parent_slug ] ) ?
+ $parent_slug :
+ $menu['parent_slug'];
+ }
+ }
+
return admin_url(
$parent_slug .
( false === strpos( $parent_slug, '?' ) ? '?' : '&' ) .
'page=' .
- $menu['menu'][2]
+ $menu_slug
);
}
--- a/tablepress/libraries/freemius/includes/managers/class-fs-admin-notice-manager.php
+++ b/tablepress/libraries/freemius/includes/managers/class-fs-admin-notice-manager.php
@@ -194,8 +194,14 @@
* @since 1.0.7
*/
static function _add_sticky_dismiss_javascript() {
+ $sticky_admin_notice_js_template_name = 'sticky-admin-notice-js.php';
+
+ if ( ! file_exists( fs_get_template_path( $sticky_admin_notice_js_template_name ) ) ) {
+ return;
+ }
+
$params = array();
- fs_require_once_template( 'sticky-admin-notice-js.php', $params );
+ fs_require_once_template( $sticky_admin_notice_js_template_name, $params );
}
private static $_added_sticky_javascript = false;
--- a/tablepress/libraries/freemius/start.php
+++ b/tablepress/libraries/freemius/start.php
@@ -15,7 +15,7 @@
*
* @var string
*/
- $this_sdk_version = '2.10.1';
+ $this_sdk_version = '2.11.0';
#region SDK Selection Logic --------------------------------------------------------------------
--- a/tablepress/libraries/vendor/PhpSpreadsheet/Calculation/Calculation.php
+++ b/tablepress/libraries/vendor/PhpSpreadsheet/Calculation/Calculation.php
@@ -553,13 +553,13 @@
'argumentCount' => '2+',
],
'CHOOSECOLS' => [
- 'category' => Category::CATEGORY_MATH_AND_TRIG,
- 'functionCall' => [Functions::class, 'DUMMY'],
+ 'category' => Category::CATEGORY_LOOKUP_AND_REFERENCE,
+ 'functionCall' => [LookupRefChooseRowsEtc::class, 'chooseCols'],
'argumentCount' => '2+',
],
'CHOOSEROWS' => [
- 'category' => Category::CATEGORY_MATH_AND_TRIG,
- 'functionCall' => [Functions::class, 'DUMMY'],
+ 'category' => Category::CATEGORY_LOOKUP_AND_REFERENCE,
+ 'functionCall' => [LookupRefChooseRowsEtc::class, 'chooseRows'],
'argumentCount' => '2+',
],
'CLEAN' => [
@@ -925,8 +925,8 @@
'argumentCount' => '3',
],
'DROP' => [
- 'category' => Category::CATEGORY_MATH_AND_TRIG,
- 'functionCall' => [Functions::class, 'DUMMY'],
+ 'category' => Category::CATEGORY_LOOKUP_AND_REFERENCE,
+ 'functionCall' => [LookupRefChooseRowsEtc::class, 'drop'],
'argumentCount' => '2-3',
],
'DSTDEV' => [
@@ -1025,8 +1025,8 @@
'argumentCount' => '1',
],
'EXPAND' => [
- 'category' => Category::CATEGORY_MATH_AND_TRIG,
- 'functionCall' => [Functions::class, 'DUMMY'],
+ 'category' => Category::CATEGORY_LOOKUP_AND_REFERENCE,
+ 'functionCall' => [LookupRefChooseRowsEtc::class, 'expand'],
'argumentCount' => '2-4',
],
'EXPONDIST' => [
@@ -1256,6 +1256,11 @@
'functionCall' => [Functions::class, 'DUMMY'],
'argumentCount' => '2+',
],
+ 'GROUPBY' => [
+ 'category' => Category::CATEGORY_LOOKUP_AND_REFERENCE,
+ 'functionCall' => [Functions::class, 'DUMMY'],
+ 'argumentCount' => '3-7',
+ ],
'GROWTH' => [
'category' => Category::CATEGORY_STATISTICAL,
'functionCall' => [StatisticalTrends::class, 'GROWTH'],
@@ -2485,8 +2490,8 @@
'argumentCount' => '1',
],
'TAKE' => [
- 'category' => Category::CATEGORY_MATH_AND_TRIG,
- 'functionCall' => [Functions::class, 'DUMMY'],
+ 'category' => Category::CATEGORY_LOOKUP_AND_REFERENCE,
+ 'functionCall' => [LookupRefChooseRowsEtc::class, 'take'],
'argumentCount' => '2-3',
],
'TAN' => [
@@ -4668,7 +4673,7 @@
private static int $matchIndex10 = 10;
/**
- * @return array<int, mixed>|false
+ * @return array<int, mixed>|false|string
* @param mixed $tokens
*/
private function processTokenStack($tokens, ?string $cellID = null, ?Cell $cell = null)
@@ -5250,6 +5255,9 @@
} elseif (preg_match('/^' . self::CALCULATION_REGEXP_DEFINEDNAME . '$/miu', $token, $matches)) {
// if the token is a named range or formula, evaluate it and push the result onto the stack
$definedName = $matches[6];
+ if (str_starts_with($definedName, '_xleta')) {
+ return Functions::NOT_YET_IMPLEMENTED;
+ }
if ($cell === null || $pCellWorksheet === null) {
return $this->raiseFormulaError("undefined name '$token'");
}
@@ -5282,6 +5290,7 @@
}
$result = $this->evaluateDefinedName($cell, $namedRange, $pCellWorksheet, $stack, $specifiedWorksheet !== '');
+
if (isset($storeKey)) {
$branchStore[$storeKey] = $result;
}
--- a/tablepress/libraries/vendor/PhpSpreadsheet/Calculation/Engine/ArrayArgumentHelper.php
+++ b/tablepress/libraries/vendor/PhpSpreadsheet/Calculation/Engine/ArrayArgumentHelper.php
@@ -145,11 +145,9 @@
private function columns(array $arguments): array
{
return array_map(
- function ($argument): int {
- return is_array($argument) && is_array($argument[array_keys($argument)[0]])
+ fn ($argument): int => is_array($argument) && is_array($argument[array_keys($argument)[0]])
? count($argument[array_keys($argument)[0]])
- : 1;
- },
+ : 1,
$arguments
);
}
--- a/tablepress/libraries/vendor/PhpSpreadsheet/Calculation/Functions.php
+++ b/tablepress/libraries/vendor/PhpSpreadsheet/Calculation/Functions.php
@@ -247,6 +247,32 @@
}
/**
+ * Convert a multi-dimensional array to a simple 1-dimensional array.
+ * Same as above but argument is specified in ... format.
+ *
+ * @param mixed $array Array to be flattened
+ *
+ * @return array Flattened array
+ */
+ public static function flattenArray2(...$array): array
+ {
+ $flattened = [];
+ $stack = array_values($array);
+
+ while (!empty($stack)) {
+ $value = array_shift($stack);
+
+ if (is_array($value)) {
+ array_unshift($stack, ...array_values($value));
+ } else {
+ $flattened[] = $value;
+ }
+ }
+
+ return $flattened;
+ }
+
+ /**
* @param mixed $value
* @return mixed
*/
--- a/tablepress/libraries/vendor/PhpSpreadsheet/Calculation/LookupRef/ChooseRowsEtc.php
+++ b/tablepress/libraries/vendor/PhpSpreadsheet/Calculation/LookupRef/ChooseRowsEtc.php
@@ -0,0 +1,259 @@
+<?php
+
+namespace TablePressPhpOfficePhpSpreadsheetCalculationLookupRef;
+
+use TablePressPhpOfficePhpSpreadsheetCalculationFunctions;
+use TablePressPhpOfficePhpSpreadsheetCalculationInformationExcelError;
+
+class ChooseRowsEtc
+{
+ /**
+ * Transpose 2-dimensional array.
+ * See https://stackoverflow.com/questions/797251/transposing-multidimensional-arrays-in-php
+ * especially the comment from user17994717.
+ *
+ * @param mixed[] $array
+ *
+ * @return mixed[]
+ */
+ public static function transpose(array $array): array
+ {
+ return empty($array) ? [] : (array_map((count($array) === 1) ? (fn ($x) => [$x]) : null, ...$array)); // @phpstan-ignore-line
+ }
+
+ /** @return mixed[]
+ * @param mixed $array */
+ private static function arrayValues($array): array
+ {
+ return is_array($array) ? array_values($array) : [$array];
+ }
+
+ /**
+ * CHOOSECOLS.
+ *
+ * @param mixed $input expecting two-dimensional array
+ *
+ * @return mixed[]|string
+ * @param mixed ...$args
+ */
+ public static function chooseCols($input, ...$args)
+ {
+ if (!is_array($input)) {
+ $input = [[$input]];
+ }
+ $retval = self::chooseRows(self::transpose($input), ...$args);
+
+ return is_array($retval) ? self::transpose($retval) : $retval;
+ }
+
+ /**
+ * CHOOSEROWS.
+ *
+ * @param mixed $input expecting two-dimensional array
+ *
+ * @return mixed[]|string
+ * @param mixed ...$args
+ */
+ public static function chooseRows($input, ...$args)
+ {
+ if (!is_array($input)) {
+ $input = [[$input]];
+ }
+ $inputArray = [[]]; // no row 0
+ $numRows = 0;
+ foreach ($input as $inputRow) {
+ $inputArray[] = self::arrayValues($inputRow);
+ ++$numRows;
+ }
+ $outputArray = [];
+ foreach (Functions::flattenArray2(...$args) as $arg) {
+ if (!is_numeric($arg)) {
+ return ExcelError::VALUE();
+ }
+ $index = (int) $arg;
+ if ($index < 0) {
+ $index += $numRows + 1;
+ }
+ if ($index <= 0 || $index > $numRows) {
+ return ExcelError::VALUE();
+ }
+ $outputArray[] = $inputArray[$index];
+ }
+
+ return $outputArray;
+ }
+
+ /**
+ * @return mixed[]|string
+ * @param mixed $offset
+ */
+ private static function dropRows(array $array, $offset)
+ {
+ if ($offset === null) {
+ return $array;
+ }
+ if (!is_numeric($offset)) {
+ return ExcelError::VALUE();
+ }
+ $offset = (int) $offset;
+ $count = count($array);
+ if (abs($offset) >= $count) {
+ // In theory, this should be #CALC!, but Excel treats
+ // #CALC! as corrupt, and it's not worth figuring out why
+ return ExcelError::VALUE();
+ }
+ if ($offset === 0) {
+ return $array;
+ }
+ if ($offset > 0) {
+ return array_slice($array, $offset);
+ }
+
+ return array_slice($array, 0, $count + $offset);
+ }
+
+ /**
+ * DROP.
+ *
+ * @param mixed $input expect two-dimensional array
+ *
+ * @return mixed[]|string
+ * @param mixed $rows
+ * @param mixed $columns
+ */
+ public static function drop($input, $rows = null, $columns = null)
+ {
+ if (!is_array($input)) {
+ $input = [[$input]];
+ }
+ $inputArray = []; // no row 0
+ foreach ($input as $inputRow) {
+ $inputArray[] = self::arrayValues($inputRow);
+ }
+ $outputArray1 = self::dropRows($inputArray, $rows);
+ if (is_string($outputArray1)) {
+ return $outputArray1;
+ }
+ $outputArray2 = self::transpose($outputArray1);
+ $outputArray3 = self::dropRows($outputArray2, $columns);
+ if (is_string($outputArray3)) {
+ return $outputArray3;
+ }
+
+ return self::transpose($outputArray3);
+ }
+
+ /**
+ * @return mixed[]|string
+ * @param mixed $offset
+ */
+ private static function takeRows(array $array, $offset)
+ {
+ if ($offset === null) {
+ return $array;
+ }
+ if (!is_numeric($offset)) {
+ return ExcelError::VALUE();
+ }
+ $offset = (int) $offset;
+ if ($offset === 0) {
+ // should be #CALC! - see above
+ return ExcelError::VALUE();
+ }
+ $count = count($array);
+ if (abs($offset) >= $count) {
+ return $array;
+ }
+ if ($offset > 0) {
+ return array_slice($array, 0, $offset);
+ }
+
+ return array_slice($array, $count + $offset);
+ }
+
+ /**
+ * TAKE.
+ *
+ * @param mixed $input expecting two-dimensional array
+ *
+ * @return mixed[]|string
+ * @param mixed $rows
+ * @param mixed $columns
+ */
+ public static function take($input, $rows, $columns = null)
+ {
+ if (!is_array($input)) {
+ $input = [[$input]];
+ }
+ if ($rows === null && $columns === null) {
+ return $input;
+ }
+ $inputArray = [];
+ foreach ($input as $inputRow) {
+ $inputArray[] = self::arrayValues($inputRow);
+ }
+ $outputArray1 = self::takeRows($inputArray, $rows);
+ if (is_string($outputArray1)) {
+ return $outputArray1;
+ }
+ $outputArray2 = self::transpose($outputArray1);
+ $outputArray3 = self::takeRows($outputArray2, $columns);
+ if (is_string($outputArray3)) {
+ return $outputArray3;
+ }
+
+ return self::transpose($outputArray3);
+ }
+
+ /**
+ * EXPAND.
+ *
+ * @param mixed $input expecting two-dimensional array
+ *
+ * @return mixed[]|string
+ * @param mixed $rows
+ * @param mixed $columns
+ * @param mixed $pad
+ */
+ public static function expand($input, $rows, $columns = null, $pad = '#N/A')
+ {
+ if (!is_array($input)) {
+ $input = [[$input]];
+ }
+ if ($rows === null && $columns === null) {
+ return $input;
+ }
+ $numRows = count($input);
+ $rows ??= $numRows;
+ if (!is_numeric($rows)) {
+ return ExcelError::VALUE();
+ }
+ $rows = (int) $rows;
+ if ($rows < count($input)) {
+ return ExcelError::VALUE();
+ }
+ $numCols = 0;
+ foreach ($input as $inputRow) {
+ $numCols = max($numCols, is_array($inputRow) ? count($inputRow) : 1);
+ }
+ $columns ??= $numCols;
+ if (!is_numeric($columns)) {
+ return ExcelError::VALUE();
+ }
+ $columns = (int) $columns;
+ if ($columns < $numCols) {
+ return ExcelError::VALUE();
+ }
+ $inputArray = [];
+ foreach ($input as $inputRow) {
+ $inputArray[] = array_pad(self::arrayValues($inputRow), $columns, $pad);
+ }
+ $outputArray = [];
+ $padRow = array_pad([], $columns, $pad);
+ for ($count = 0; $count < $rows; ++$count) {
+ $outputArray[] = ($count >= $numRows) ? $padRow : $inputArray[$count];
+ }
+
+ return $outputArray;
+ }
+}
--- a/tablepress/libraries/vendor/PhpSpreadsheet/Calculation/MathTrig/Random.php
+++ b/tablepress/libraries/vendor/PhpSpreadsheet/Calculation/MathTrig/Random.php
@@ -86,11 +86,9 @@
return array_chunk(
array_map(
- function () use ($min, $max, $wholeNumber) {
- return $wholeNumber
+ fn () => $wholeNumber
? mt_rand((int) $min, (int) $max)
- : (mt_rand() / mt_getrandmax()) * ($max - $min) + $min;
- },
+ : (mt_rand() / mt_getrandmax()) * ($max - $min) + $min,
array_fill(0, $rows * $columns, $min)
),
max($columns, 1)
--- a/tablepress/libraries/vendor/PhpSpreadsheet/Calculation/Statistical/Distributions/ChiSquared.php
+++ b/tablepress/libraries/vendor/PhpSpreadsheet/Calculation/Statistical/Distributions/ChiSquared.php
@@ -133,10 +133,8 @@
return ExcelError::NAN();
}
- $callback = function ($value) use ($degrees): float {
- return 1 - (Gamma::incompleteGamma($degrees / 2, $value / 2)
+ $callback = fn ($value): float => 1 - (Gamma::incompleteGamma($degrees / 2, $value / 2)
/ Gamma::gammaValue($degrees / 2));
- };
$newtonRaphson = new NewtonRaphson($callback);
--- a/tablepress/libraries/vendor/PhpSpreadsheet/Calculation/TextData/Text.php
+++ b/tablepress/libraries/vendor/PhpSpreadsheet/Calculation/TextData/Text.php
@@ -174,11 +174,9 @@
);
return array_map(
- function (array $row) use ($columnCount, $padding): array {
- return (count($row) < $columnCount)
+ fn (array $row): array => (count($row) < $columnCount)
? array_merge($row, array_fill(0, $columnCount - count($row), $padding))
- : $row;
- },
+ : $row,
$rows
);
}
--- a/tablepress/libraries/vendor/PhpSpreadsheet/Collection/Memory/SimpleCache1.php
+++ b/tablepress/libraries/vendor/PhpSpreadsheet/Collection/Memory/SimpleCache1.php
@@ -46,9 +46,9 @@
}
/**
- * @return mixed
- */
- public function get($key, $default = null)
+ * @return mixed
+ */
+ public function get($key, $default = null)
{
if ($this->has($key)) {
return $this->cache[$key];
--- a/tablepress/libraries/vendor/PhpSpreadsheet/Reader/Ods/FormulaTranslator.php
+++ b/tablepress/libraries/vendor/PhpSpreadsheet/Reader/Ods/FormulaTranslator.php
@@ -6,10 +6,24 @@
class FormulaTranslator
{
- public static function convertToExcelAddressValue(string $openOfficeAddress): string
+ private static function replaceQuotedPeriod(string $value): string
{
- $excelAddress = $openOfficeAddress;
+ $value2 = '';
+ $quoted = false;
+ foreach (mb_str_split($value, 1, 'UTF-8') as $char) {
+ if ($char === "'") {
+ $quoted = !$quoted;
+ } elseif ($char === '.' && $quoted) {
+ $char = "u{fffe}";
+ }
+ $value2 .= $char;
+ }
+
+ return $value2;
+ }
+ public static function convertToExcelAddressValue(string $openOfficeAddress): string
+ {
// Cell range 3-d reference
// As we don't support 3-d ranges, we're just going to take a quick and dirty approach
// and assume that the second worksheet reference is the same as the first
@@ -20,6 +34,7 @@
'/$?([^.]+).([^.]+)/miu', // Cell reference in another sheet
'/.([^.]+):.([^.]+)/miu', // Cell range reference
'/.([^.]+)/miu', // Simple cell reference
+ '/\x{FFFE}/miu', // restore quoted periods
],
[
'$1!$2:$4',
@@ -27,8 +42,9 @@
'$1!$2',
'$1:$2',
'$1',
+ '.',
],
- $excelAddress
+ self::replaceQuotedPeriod($openOfficeAddress)
);
return $excelAddress;
@@ -52,14 +68,16 @@
'/[$?([^.]+).([^.]+)]/miu', // Cell reference in another sheet
'/[.([^.]+):.([^.]+)]/miu', // Cell range reference
'/[.([^.]+)]/miu', // Simple cell reference
+ '/\x{FFFE}/miu', // restore quoted periods
],
[
'$1!$2:$3',
'$1!$2',
'$1:$2',
'$1',
+ '.',
],
- $value
+ self::replaceQuotedPeriod($value)
);
// Convert references to defined names/formulae
$value = str_replace('$$', '', $value);
--- a/tablepress/libraries/vendor/PhpSpreadsheet/Reader/Xls/ConditionalFormatting.php
+++ b/tablepress/libraries/vendor/PhpSpreadsheet/Reader/Xls/ConditionalFormatting.php
@@ -288,12 +288,12 @@
}
/*private function getCFProtectionStyle(string $options, Style $style, Xls $xls): void
- {
- }*/
- /**
- * @return float|int|string|null
- */
- private function readCFFormula(string $recordData, int $offset, int $size, Xls $xls)
+ {
+ }*/
+ /**
+ * @return float|int|string|null
+ */
+ private function readCFFormula(string $recordData, int $offset, int $size, Xls $xls)
{
try {
$formula = substr($recordData, $offset, $size);
@@ -311,10 +311,10 @@
}
/**
- * @param null|float|int|string $formula1
- * @param null|float|int|string $formula2
- */
- private function setCFRules(array $cellRanges, string $type, string $operator, $formula1, $formula2, Style $style, bool $noFormatSet, Xls $xls): void
+ * @param null|float|int|string $formula1
+ * @param null|float|int|string $formula2
+ */
+ private function setCFRules(array $cellRanges, string $type, string $operator, $formula1, $formula2, Style $style, bool $noFormatSet, Xls $xls): void
{
foreach ($cellRanges as $cellRange) {
$conditional = new Conditional();
--- a/tablepress/libraries/vendor/PhpSpreadsheet/Reader/Xls/ListFunctions.php
+++ b/tablepress/libraries/vendor/PhpSpreadsheet/Reader/Xls/ListFunctions.php
@@ -31,22 +31,22 @@
$code = self::getUInt2d($xls->data, $xls->pos);
switch ($code) {
- case self::XLS_TYPE_BOF:
- $xls->readBof();
- break;
- case self::XLS_TYPE_SHEET:
- $xls->readSheet();
- break;
- case self::XLS_TYPE_EOF:
- $xls->readDefault();
- break;
- case self::XLS_TYPE_CODEPAGE:
- $xls->readCodepage();
- break;
- default:
- $xls->readDefault();
- break;
- }
+ case self::XLS_TYPE_BOF:
+ $xls->readBof();
+ break;
+ case self::XLS_TYPE_SHEET:
+ $xls->readSheet();
+ break;
+ case self::XLS_TYPE_EOF:
+ $xls->readDefault();
+ break;
+ case self::XLS_TYPE_CODEPAGE:
+ $xls->readCodepage();
+ break;
+ default:
+ $xls->readDefault();
+ break;
+ }
if ($code === self::XLS_TYPE_EOF) {
break;
@@ -87,22 +87,22 @@
$code = self::getUInt2d($xls->data, $xls->pos);
switch ($code) {
- case self::XLS_TYPE_BOF:
- $xls->readBof();
- break;
- case self::XLS_TYPE_SHEET:
- $xls->readSheet();
- break;
- case self::XLS_TYPE_EOF:
- $xls->readDefault();
- break;
- case self::XLS_TYPE_CODEPAGE:
- $xls->readCodepage();
- break;
- default:
- $xls->readDefault();
- break;
- }
+ case self::XLS_TYPE_BOF:
+ $xls->readBof();
+ break;
+ case self::XLS_TYPE_SHEET:
+ $xls->readSheet();
+ break;
+ case self::XLS_TYPE_EOF:
+ $xls->readDefault();
+ break;
+ case self::XLS_TYPE_CODEPAGE:
+ $xls->readCodepage();
+ break;
+ default:
+ $xls->readDefault();
+ break;
+ }
if ($code === self::XLS_TYPE_EOF) {
break;
--- a/tablepress/libraries/vendor/PhpSpreadsheet/Reader/Xlsx.php
+++ b/tablepress/libraries/vendor/PhpSpreadsheet/Reader/Xlsx.php
@@ -864,6 +864,8 @@
}
// Read cell!
+ $useFormula = isset($c->f)
+ && ((string) $c->f !== '' || (isset($c->f->attributes()['t']) && strtolower((string) $c->f->attributes()['t']) === 'shared'));
switch ($cellDataType) {
case DataType::TYPE_STRING:
if ((string) $c->v != '') {
@@ -878,7 +880,7 @@
break;
case DataType::TYPE_BOOL:
- if (!isset($c->f) || ((string) $c->f) === '') {
+ if (!$useFormula) {
if (isset($c->v)) {
$value = self::castToBoolean($c);
} else {
@@ -893,16 +895,16 @@
break;
case DataType::TYPE_STRING2:
- if (isset($c->f)) {
+ if ($useFormula) {
$this->castToFormula($c, $r, $cellDataType, $value, $calculatedValue, 'castToString');
self::storeFormulaAttributes($c->f, $docSheet, $r);
} else {
- $value = self::castToString($c);
+ $value = self::castToString($c);
}
break;
case DataType::TYPE_INLINE:
- if (isset($c->f)) {
+ if ($useFormula) {
$this->castToFormula($c, $r, $cellDataType, $value, $calculatedValue, 'castToError');
self::storeFormulaAttributes($c->f, $docSheet, $r);
} else {
@@ -911,7 +913,7 @@
break;
case DataType::TYPE_ERROR:
- if (!isset($c->f)) {
+ if (!$useFormula) {
$value = self::castToError($c);
} else {
// Formula
@@ -926,7 +928,7 @@
break;
default:
- if (!isset($c->f)) {
+ if (!$useFormula) {
$value = self::castToString($c);
if (is_numeric($value)) {
$value += 0;
--- a/tablepress/libraries/vendor/PhpSpreadsheet/Shared/StringHelper.php
+++ b/tablepress/libraries/vendor/PhpSpreadsheet/Shared/StringHelper.php
@@ -326,11 +326,11 @@
}
/**
- * Formats a numeric value as a string for output in various output writers forcing
- * point as decimal separator in case locale is other than English.
- * @param float|int|string|null $numericValue
- */
- public static function formatNumber($numericValue): string
+ * Formats a numeric value as a string for output in various output writers forcing
+ * point as decimal separator in case locale is other than English.
+ * @param float|int|string|null $numericValue
+ */
+ public static function formatNumber($numericValue): string
{
if (is_float($numericValue)) {
return str_replace(',', '.', (string) $numericValue);
@@ -639,4 +639,9 @@
return (is_numeric(substr($textValue, 0, strlen((string) $v)))) ? $v : $textValue;
}
+
+ public static function strlenAllowNull(?string $string): int
+ {
+ return strlen("$string");
+ }
}
--- a/tablepress/libraries/vendor/PhpSpreadsheet/Spreadsheet.php
+++ b/tablepress/libraries/vendor/PhpSpreadsheet/Spreadsheet.php
@@ -519,7 +519,7 @@
public function createSheet(?int $sheetIndex = null): Worksheet
{
$newSheet = new Worksheet($this);
- $this->addSheet($newSheet, $sheetIndex);
+ $this->addSheet($newSheet, $sheetIndex, true);
return $newSheet;
}
@@ -534,14 +534,35 @@
return $this->getSheetByName($worksheetName) !== null;
}
+ public function duplicateWorksheetByTitle(string $title): Worksheet
+ {
+ $original = $this->getSheetByNameOrThrow($title);
+ $index = $this->getIndex($original) + 1;
+ $clone = clone $original;
+
+ return $this->addSheet($clone, $index, true);
+ }
+
/**
* Add sheet.
*
* @param Worksheet $worksheet The worksheet to add
* @param null|int $sheetIndex Index where sheet should go (0,1,..., or null for last)
*/
- public function addSheet(Worksheet $worksheet, ?int $sheetIndex = null): Worksheet
+ public function addSheet(Worksheet $worksheet, ?int $sheetIndex = null, bool $retitleIfNeeded = false): Worksheet
{
+ if ($retitleIfNeeded) {
+ $title = $worksheet->getTitle();
+ if ($this->sheetNameExists($title)) {
+ $i = 1;
+ $newTitle = "$title $i";
+ while ($this->sheetNameExists($newTitle)) {
+ ++$i;
+ $newTitle = "$title $i";
+ }
+ $worksheet->setTitle($newTitle);
+ }
+ }
if ($this->sheetNameExists($worksheet->getTitle())) {
throw new Exception(
"Workbook already contains a worksheet named '{$worksheet->getTitle()}'. Rename this worksheet first."
@@ -1085,6 +1106,11 @@
return $this->cellXfCollection[$cellStyleIndex];
}
+ public function getCellXfByIndexOrNull(?int $cellStyleIndex): ?Style
+ {
+ return ($cellStyleIndex === null) ? null : ($this->cellXfCollection[$cellStyleIndex] ?? null);
+ }
+
/**
* Get cellXf by hash code.
*
--- a/tablepress/libraries/vendor/PhpSpreadsheet/Style/NumberFormat/Formatter.php
+++ b/tablepress/libraries/vendor/PhpSpreadsheet/Style/NumberFormat/Formatter.php
@@ -22,11 +22,11 @@
private const SECTION_SPLIT = '/;(?=(?:[^"]*"[^"]*")*[^"]*Z)/miu';
/**
- * @param mixed $value
- * @param mixed $comparisonValue
- * @param mixed $defaultComparisonValue
- */
- private static function splitFormatComparison(
+ * @param mixed $value
+ * @param mixed $comparisonValue
+ * @param mixed $defaultComparisonValue
+ */
+ private static function splitFormatComparison(
$value,
?string $condition,
$comparisonValue,
@@ -39,23 +39,23 @@
}
switch ($condition) {
- case '>':
- return $value > $comparisonValue;
- case '<':
- return $value < $comparisonValue;
- case '<=':
- return $value <= $comparisonValue;
- case '<>':
- return $value != $comparisonValue;
- case '=':
- return $value == $comparisonValue;
- default:
- return $value >= $comparisonValue;
- }
+ case '>':
+ return $value > $comparisonValue;
+ case '<':
+ return $value < $comparisonValue;
+ case '<=':
+ return $value <= $comparisonValue;
+ case '<>':
+ return $value != $comparisonValue;
+ case '=':
+ return $value == $comparisonValue;
+ default:
+ return $value >= $comparisonValue;
+ }
}
/** @param mixed $value value to be formatted */
- private static function splitFormatForSectionSelection(array $sections, $value): array
+ private static function splitFormatForSectionSelection(array $sections, $value): array
{
// Extract the relevant section depending on whether number is positive, negative, or zero?
// Text not supported yet.
--- a/tablepress/libraries/vendor/PhpSpreadsheet/Worksheet/AutoFilter.php
+++ b/tablepress/libraries/vendor/PhpSpreadsheet/Worksheet/AutoFilter.php
@@ -44,7 +44,7 @@
/**
* Create a new AutoFilter.
*
- * @param AddressRange<CellAddress>|array{0: int, 1: int, 2: int, 3: int}|array{0: int, 1: int}|string $range
+ * @param AddressRange<CellAddress>|AddressRange<int>|AddressRange<string>|array{0: int, 1: int, 2: int, 3: int}|array{0: int, 1: int}|string $range
* A simple string containing a Cell range like 'A1:E10' is permitted
* or passing in an array of [$fromColumnIndex, $fromRow, $toColumnIndex, $toRow] (e.g. [3, 5, 6, 8]),
* or an AddressRange object.
--- a/tablepress/libraries/vendor/PhpSpreadsheet/Worksheet/Drawing.php
+++ b/tablepress/libraries/vendor/PhpSpreadsheet/Worksheet/Drawing.php
@@ -103,7 +103,7 @@
$this->path = '';
// Check if a URL has been passed. https://stackoverflow.com/a/2058596/1252979
- if (filter_var($path, FILTER_VALIDATE_URL)) {
+ if (filter_var($path, FILTER_VALIDATE_URL) || (preg_match('/^([\w\s\x00-\x1f]+):/u', $path) && !preg_match('/^([\w]+):/u', $path))) {
if (!preg_match('/^(http|https|file|ftp|s3):/', $path)) {
throw new PhpSpreadsheetException('Invalid protocol for linked drawing');
}
--- a/tablepress/libraries/vendor/PhpSpreadsheet/Worksheet/Table.php
+++ b/tablepress/libraries/vendor/PhpSpreadsheet/Worksheet/Table.php
@@ -55,7 +55,7 @@
/**
* Create a new Table.
*
- * @param AddressRange<CellAddress>|array{0: int, 1: int, 2: int, 3: int}|array{0: int, 1: int}|string $range
+ * @param AddressRange<CellAddress>|AddressRange<int>|AddressRange<string>|array{0: int, 1: int, 2: int, 3: int}|array{0: int, 1: int}|string $range
* A simple string containing a Cell range like 'A1:E10' is permitted
* or passing in an array of [$fromColumnIndex, $fromRow, $toColumnIndex, $toRow] (e.g. [3, 5, 6, 8]),
* or an AddressRange object.
@@ -244,7 +244,7 @@
/**
* Set Table Cell Range.
*
- * @param AddressRange<CellAddress>|array{0: int, 1: int, 2: int, 3: int}|array{0: int, 1: int}|string $range
+ * @param AddressRange<CellAddress>|AddressRange<int>|AddressRange<string>|array{0: int, 1: int, 2: int, 3: int}|array{0: int, 1: int}|string $range
* A simple string containing a Cell range like 'A1:E10' is permitted
* or passing in an array of [$fromColumnIndex, $fromRow, $toColumnIndex, $toRow] (e.g. [3, 5, 6, 8]),
* or an AddressRange object.
--- a/tablepress/libraries/vendor/PhpSpreadsheet/Worksheet/Validations.php
+++ b/tablepress/libraries/vendor/PhpSpreadsheet/Worksheet/Validations.php
@@ -36,7 +36,7 @@
/**
* Validate a cell address or cell range.
*
- * @param AddressRange<CellAddress>|array{0: int, 1: int, 2: int, 3: int}|array{0: int, 1: int}|CellAddress|int|string $cellRange Coordinate of the cells as a string, eg: 'C5:F12';
+ * @param AddressRange<CellAddress>|AddressRange<int>|AddressRange<string>|array{0: int, 1: int, 2: int, 3: int}|array{0: int, 1: int}|CellAddress|int|string $cellRange Coordinate of the cells as a string, eg: 'C5:F12';
* or as an array of [$fromColumnIndex, $fromRow, $toColumnIndex, $toRow] (e.g. [3, 5, 6, 12]),
* or as a CellAddress or AddressRange object.
*/
@@ -59,7 +59,7 @@
/**
* Validate a cell range.
*
- * @param AddressRange<CellAddress>|array{0: int, 1: int, 2: int, 3: int}|array{0: int, 1: int}|string $cellRange Coordinate of the cells as a string, eg: 'C5:F12';
+ * @param AddressRange<CellAddress>|AddressRange<int>|AddressRange<string>|array{0: int, 1: int, 2: int, 3: int}|array{0: int, 1: int}|string $cellRange Coordinate of the cells as a string, eg: 'C5:F12';
* or as an array of [$fromColumnIndex, $fromRow, $toColumnIndex, $toRow] (e.g. [3, 5, 6, 12]),
* or as an AddressRange object.
*/
--- a/tablepress/libraries/vendor/PhpSpreadsheet/Worksheet/Worksheet.php
+++ b/tablepress/libraries/vendor/PhpSpreadsheet/Worksheet/Worksheet.php
@@ -49,6 +49,8 @@
public const MERGE_CELL_CONTENT_HIDE = 'hide';
public const MERGE_CELL_CONTENT_MERGE = 'merge';
+ public const FUNCTION_LIKE_GROUPBY = '/\b(groupby|_xleta)\b/i'; // weird new syntax
+
protected const SHEET_NAME_REQUIRES_NO_QUOTES = '/^[_p{L}][_p{L}p{N}]*$/mui';
/**
@@ -321,6 +323,7 @@
{
// Set parent and title
$this->parent = $parent;
+ $this->hash = spl_object_id($this);
$this->setTitle($title, false);
// setTitle can change $pTitle
$this->setCodeName($this->getTitle());
@@ -349,7 +352,6 @@
$this->autoFilter = new AutoFilter('', $this);
// Table collection
$this->tableCollection = new ArrayObject();
- $this->hash = spl_object_id($this);
}
/**
@@ -869,7 +871,7 @@
// Syntax check
self::checkSheetTitle($title);
- if ($this->parent) {
+ if ($this->parent && $this->parent->getIndex($this, true) >= 0) {
// Is there already such sheet name?
if ($this->parent->sheetNameExists($title)) {
// Use name, but append with lowest possible integer
@@ -899,7 +901,7 @@
// Set title
$this->title = $title;
- if ($this->parent && $this->parent->getCalculationEngine()) {
+ if ($this->parent && $this->parent->getIndex($this, true) >= 0 && $this->parent->getCalculationEngine()) {
// New title
$newTitle = $this->getTitle();
$this->parent->getCalculationEngine()
@@ -1333,6 +1335,11 @@
return $this->rowDimensions[$row];
}
+ public function getRowStyle(int $row): ?Style
+ {
+ return ($nullsafeVariable3 = $this->parent) ? $nullsafeVariable3->getCellXfByIndexOrNull(($nullsafeVariable4 = $this->rowDimensions[$row] ?? null) ? $nullsafeVariable4->getXfIndex() : null) : null;
+ }
+
public function rowDimensionExists(int $row): bool
{
return isset($this->rowDimensions[$row]);
@@ -1376,6 +1383,11 @@
return $this->getColumnDimension(Coordinate::stringFromColumnIndex($columnIndex));
}
+ public function getColumnStyle(string $column): ?Style
+ {
+ return ($nullsafeVariable5 = $this->parent) ? $nullsafeVariable5->getCellXfByIndexOrNull(($nullsafeVariable6 = $this->columnDimensions[$column] ?? null) ? $nullsafeVariable6->getXfIndex() : null) : null;
+ }
+
/**
* Get styles.
*
@@ -1389,7 +1401,7 @@
/**
* Get style for cell.
*
- * @param AddressRange<CellAddress>|array{0: int, 1: int, 2: int, 3: int}|array{0: int, 1: int}|CellAddress|int|string $cellCoordinate
+ * @param AddressRange<CellAddress>|AddressRange<int>|AddressRange<string>|array{0: int, 1: int, 2: int, 3: int}|array{0: int, 1: int}|CellAddress|int|string $cellCoordinate
* A simple string containing a cell address like 'A1' or a cell range like 'A1:E10'
* or passing in an array of [$fromColumnIndex, $fromRow, $toColumnIndex, $toRow] (e.g. [3, 5, 6, 8]),
* or a CellAddress or AddressRange object.
@@ -1693,7 +1705,7 @@
/**
* Set merge on a cell range.
*
- * @param AddressRange<CellAddress>|array{0: int, 1: int, 2: int, 3: int}|array{0: int, 1: int}|string $range A simple string containing a Cell range like 'A1:E10'
+ * @param AddressRange<CellAddress>|AddressRange<int>|AddressRange<string>|array{0: int, 1: int, 2: int, 3: int}|array{0: int, 1: int}|string $range A simple string containing a Cell range like 'A1:E10'
* or passing in an array of [$fromColumnIndex, $fromRow, $toColumnIndex, $toRow] (e.g. [3, 5, 6, 8]),
* or an AddressRange.
* @param string $behaviour How the merged cells should behave.
@@ -1818,7 +1830,7 @@
/**
* Remove merge on a cell range.
*
- * @param AddressRange<CellAddress>|array{0: int, 1: int, 2: int, 3: int}|array{0: int, 1: int}|string $range A simple string containing a Cell range like 'A1:E10'
+ * @param AddressRange<CellAddress>|AddressRange<int>|AddressRange<string>|array{0: int, 1: int, 2: int, 3: int}|array{0: int, 1: int}|string $range A simple string containing a Cell range like 'A1:E10'
* or passing in an array of [$fromColumnIndex, $fromRow, $toColumnIndex, $toRow] (e.g. [3, 5, 6, 8]),
* or an AddressRange.
*
@@ -1869,7 +1881,7 @@
/**
* Set protection on a cell or cell range.
*
- * @param AddressRange<CellAddress>|array{0: int, 1: int, 2: int, 3: int}|array{0: int, 1: int}|CellAddress|int|string $range A simple string containing a Cell range like 'A1:E10'
+ * @param AddressRange<CellAddress>|AddressRange<int>|AddressRange<string>|array{0: int, 1: int, 2: int, 3: int}|array{0: int, 1: int}|CellAddress|int|string $range A simple string containing a Cell range like 'A1:E10'
* or passing in an array of [$fromColumnIndex, $fromRow, $toColumnIndex, $toRow] (e.g. [3, 5, 6, 8]),
* or a CellAddress or AddressRange object.
* @param string $password Password to unlock the protection
@@ -1892,7 +1904,7 @@
/**
* Remove protection on a cell or cell range.
*
- * @param AddressRange<CellAddress>|array{0: int, 1: int, 2: int, 3: int}|array{0: int, 1: int}|CellAddress|int|string $range A simple string containing a Cell range like 'A1:E10'
+ * @param AddressRange<CellAddress>|AddressRange<int>|AddressRange<string>|array{0: int, 1: int, 2: int, 3: int}|array{0: int, 1: int}|CellAddress|int|string $range A simple string containing a Cell range like 'A1:E10'
* or passing in an array of [$fromColumnIndex, $fromRow, $toColumnIndex, $toRow] (e.g. [3, 5, 6, 8]),
* or a CellAddress or AddressRange object.
*
@@ -1950,7 +1962,7 @@
/**
* Set AutoFilter.
*
- * @param AddressRange<CellAddress>|array{0: int, 1: int, 2: int, 3: int}|array{0: int, 1: int}|AutoFilter|string $autoFilterOrRange
+ * @param AddressRange<CellAddress>|AddressRange<int>|AddressRange<string>|array{0: int, 1: int, 2: int, 3: int}|array{0: int, 1: int}|AutoFilter|string $autoFilterOrRange
* A simple string containing a Cell range like 'A1:E10' is permitted for backward compatibility
* or passing in an array of [$fromColumnIndex, $fromRow, $toColumnIndex, $toRow] (e.g. [3, 5, 6, 8]),
* or an AddressRange.
@@ -2696,7 +2708,7 @@
/**
* Select a range of cells.
*
- * @param AddressRange<CellAddress>|array{0: int, 1: int, 2: int, 3: int}|array{0: int, 1: int}|CellAddress|int|string $coordinate A simple string containing a Cell range like 'A1:E10'
+ * @param AddressRange<CellAddress>|AddressRange<int>|AddressRange<string>|array{0: int, 1: int, 2: int, 3: int}|array{0: int, 1: int}|CellAddress|int|string $coordinate A simple string containing a Cell range like 'A1:E10'
* or passing in an array of [$fromColumnIndex, $fromRow, $toColumnIndex, $toRow] (e.g. [3, 5, 6, 8]),
* or a CellAddress or AddressRange object.
*
@@ -3703,7 +3715,9 @@
$keys = $this->cellCollection->getCoordinates();
foreach ($keys as $key) {
if ($this->getCell($key)->getDataType() === DataType::TYPE_FORMULA) {
- $this->getCell($key)->getCalculatedValue();
+ if (preg_match(self::FUNCTION_LIKE_GROUPBY, $this->getCell($key)->getValue()) !== 1) {
+ $this->getCell($key)->getCalculatedValue();
+ }
}
}
}
--- a/tablepress/libraries/vendor/autoload-classmap.php
+++ b/tablepress/libraries/vendor/autoload-classmap.php
@@ -280,6 +280,7 @@
'TablePressPhpOfficePhpSpreadsheetCalculationLookupRefIndirect' => $strauss_src . '/PhpSpreadsheet/Calculation/LookupRef/Indirect.php',
'TablePressPhpOfficePhpSpreadsheetCalculationLookupRefHelpers' => $strauss_src . '/PhpSpreadsheet/Calculation/LookupRef/Helpers.php',
'TablePressPhpOfficePhpSpreadsheetCalculationLookupRefRowColumnInformation' => $strauss_src . '/PhpSpreadsheet/Calculation/LookupRef/RowColumnInformation.php',
+ 'TablePressPhpOfficePhpSpreadsheetCalculationLookupRefChooseRowsEtc' => $strauss_src . '/PhpSpreadsheet/Calculation/LookupRef/ChooseRowsEtc.php',
'TablePressPhpOfficePhpSpreadsheetCalculationBinaryComparison' => $strauss_src . '/PhpSpreadsheet/Calculation/BinaryComparison.php',
'TablePressPhpOfficePhpSpreadsheetCalculationFinancialTreasuryBill' => $strauss_src . '/PhpSpreadsheet/Calculation/Financial/TreasuryBill.php',
'TablePressPhpOfficePhpSpreadsheetCalculationFinancialSecuritiesYields' => $strauss_src . '/PhpSpreadsheet/Calculation/Financial/Securities/Yields.php',
--- a/tablepress/tablepress.php
+++ b/tablepress/tablepress.php
@@ -4,13 +4,13 @@
*
* @package TablePress
* @author Tobias Bäthge
- * @version 3.0.2
+ * @version 3.0.3
*
*
* Plugin Name: TablePress
* Plugin URI: https://tablepress.org/
* Description: Embed beautiful and interactive tables into your WordPress website’s posts and pages, without having to write code!
- * Version: 3.0.2
+ * Version: 3.0.3
* Requires at least: 6.2
* Requires PHP: 7.4
* Author: Tobias Bäthge