Skip to content

Commit

Permalink
Merge pull request #4323 from oleibman/comppcre
Browse files Browse the repository at this point in the history
Use Composer/Pcre Part 1 of Many
  • Loading branch information
oleibman authored Jan 21, 2025
2 parents 8871095 + e7ae646 commit 3f15579
Show file tree
Hide file tree
Showing 20 changed files with 384 additions and 188 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ and this project adheres to [Semantic Versioning](https://semver.org).
- Ods Reader Sheet Names with Period. [Issue #4311](https://github.com/PHPOffice/PhpSpreadsheet/issues/4311) [PR #4313](https://github.com/PHPOffice/PhpSpreadsheet/pull/4313)
- Mpdf and Tcpdf Hidden Columns and Merged Cells. [Issue #4319](https://github.com/PHPOffice/PhpSpreadsheet/issues/4319) [PR #4320](https://github.com/PHPOffice/PhpSpreadsheet/pull/4320)
- Html Writer Allow mailto. [Issue #4316](https://github.com/PHPOffice/PhpSpreadsheet/issues/4316) [PR #4322](https://github.com/PHPOffice/PhpSpreadsheet/pull/4322)
- Use composer/pcre rather than preg_* in Writer. [PR #4323](https://github.com/PHPOffice/PhpSpreadsheet/pull/4323)

## 2025-01-11 - 3.8.0

Expand Down
1 change: 1 addition & 0 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@
"ext-xmlwriter": "*",
"ext-zip": "*",
"ext-zlib": "*",
"composer/pcre": "^3.3",
"maennchen/zipstream-php": "^2.1 || ^3.0",
"markbaker/complex": "^3.0",
"markbaker/matrix": "^3.0",
Expand Down
160 changes: 80 additions & 80 deletions composer.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions phpstan.neon.dist
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ includes:
- phpstan-baseline.neon
- vendor/phpstan/phpstan-phpunit/extension.neon
- vendor/phpstan/phpstan-phpunit/rules.neon
- vendor/composer/pcre/extension.neon

parameters:
level: 8
Expand Down
3 changes: 2 additions & 1 deletion samples/Pdf/21b_Pdf.php
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
<?php

use PhpOffice\PhpSpreadsheet\Exception as SpreadsheetException;
use PhpOffice\PhpSpreadsheet\IOFactory;
use PhpOffice\PhpSpreadsheet\Worksheet\PageSetup;
use PhpOffice\PhpSpreadsheet\Writer\Pdf\Dompdf;
Expand All @@ -21,7 +22,7 @@ function replaceBody(string $html): string
</body>
EOF;

return preg_replace($bodystring, $bodyrepl, $html) ?? '';
return preg_replace($bodystring, $bodyrepl, $html) ?? throw new SpreadsheetException('preg failed');
}

require __DIR__ . '/../Header.php';
Expand Down
5 changes: 3 additions & 2 deletions samples/Pdf/21c_Pdf.php
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
<?php

use PhpOffice\PhpSpreadsheet\Exception as SpreadsheetException;
use PhpOffice\PhpSpreadsheet\IOFactory;
use PhpOffice\PhpSpreadsheet\Spreadsheet;
use PhpOffice\PhpSpreadsheet\Writer\Pdf\Mpdf;
Expand All @@ -16,7 +17,7 @@ function addHeadersFootersMpdf2000(string $html): string
odd-footer-name: html_myFooter2;
EOF;
$html = preg_replace('/@page page0 {/', $pagerepl, $html) ?? '';
$html = preg_replace('/@page page0 {/', $pagerepl, $html) ?? throw new SpreadsheetException('preg 1 failed');
$bodystring = '/<body>/';
$simulatedBodyStart = Mpdf::SIMULATED_BODY_START;
$bodyrepl = <<<EOF
Expand All @@ -40,7 +41,7 @@ function addHeadersFootersMpdf2000(string $html): string
EOF;

return preg_replace($bodystring, $bodyrepl, $html) ?? '';
return preg_replace($bodystring, $bodyrepl, $html) ?? throw new SpreadsheetException('preg 2 failed');
}

$spreadsheet = new Spreadsheet();
Expand Down
5 changes: 5 additions & 0 deletions src/PhpSpreadsheet/Shared/StringHelper.php
Original file line number Diff line number Diff line change
Expand Up @@ -638,4 +638,9 @@ public static function testStringAsNumeric(string $textValue): float|string

return (is_numeric(substr($textValue, 0, strlen((string) $v)))) ? $v : $textValue;
}

public static function strlenAllowNull(?string $string): int
{
return strlen("$string");
}
}
15 changes: 8 additions & 7 deletions src/PhpSpreadsheet/Writer/Html.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

namespace PhpOffice\PhpSpreadsheet\Writer;

use Composer\Pcre\Preg;
use PhpOffice\PhpSpreadsheet\Calculation\Calculation;
use PhpOffice\PhpSpreadsheet\Cell\Cell;
use PhpOffice\PhpSpreadsheet\Cell\Coordinate;
Expand Down Expand Up @@ -646,13 +647,13 @@ private function writeImageInCell(string $coordinates): string
$filename = $drawing->getPath();

// Strip off eventual '.'
$filename = (string) preg_replace('/^[.]/', '', $filename);
$filename = Preg::replace('/^[.]/', '', $filename);

// Prepend images root
$filename = $this->getImagesRoot() . $filename;

// Strip off eventual '.' if followed by non-/
$filename = (string) preg_replace('@^[.]([^/])@', '$1', $filename);
$filename = Preg::replace('@^[.]([^/])@', '$1', $filename);

// Convert UTF8 data to PCDATA
$filename = htmlspecialchars($filename, Settings::htmlEntityFlags());
Expand Down Expand Up @@ -1411,7 +1412,7 @@ private function generateRowCellData(Worksheet $worksheet, null|Cell|string $cel

// Converts the cell content so that spaces occuring at beginning of each new line are replaced by &nbsp;
// Example: " Hello\n to the world" is converted to "&nbsp;&nbsp;Hello\n&nbsp;to the world"
$cellData = (string) preg_replace('/(?m)(?:^|\\G) /', '&nbsp;', $cellData);
$cellData = Preg::replace('/(?m)(?:^|\\G) /', '&nbsp;', $cellData);

// convert newline "\n" to '<br>'
$cellData = nl2br($cellData);
Expand Down Expand Up @@ -1599,9 +1600,9 @@ private function generateRow(Worksheet $worksheet, array $values, int $row, stri
if ($worksheet->hyperlinkExists($coordinate) && !$worksheet->getHyperlink($coordinate)->isInternal()) {
$url = $worksheet->getHyperlink($coordinate)->getUrl();
$urlDecode1 = html_entity_decode($url, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8');
$urlTrim = preg_replace('/^\\s+/u', '', $urlDecode1) ?? $urlDecode1;
$parseScheme = preg_match('/^([\\w\\s]+):/u', strtolower($urlTrim), $matches);
if ($parseScheme === 1 && !in_array($matches[1], ['http', 'https', 'file', 'ftp', 'mailto', 's3'], true)) {
$urlTrim = Preg::replace('/^\\s+/u', '', $urlDecode1);
$parseScheme = Preg::isMatch('/^([\\w\\s]+):/u', strtolower($urlTrim), $matches);
if ($parseScheme && !in_array($matches[1], ['http', 'https', 'file', 'ftp', 'mailto', 's3'], true)) {
$cellData = htmlspecialchars($url, Settings::htmlEntityFlags());
} else {
$tooltip = $worksheet->getHyperlink($coordinate)->getTooltip();
Expand Down Expand Up @@ -1755,7 +1756,7 @@ public static function formatColorStatic(string $value, string $format): string
$matches = [];

$color_regex = '/^\\[[a-zA-Z]+\\]/';
if (preg_match($color_regex, $format, $matches)) {
if (Preg::isMatch($color_regex, $format, $matches)) {
$color = str_replace(['[', ']'], '', $matches[0]);
$color = strtolower($color);
}
Expand Down
8 changes: 4 additions & 4 deletions src/PhpSpreadsheet/Writer/Ods/Content.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

namespace PhpOffice\PhpSpreadsheet\Writer\Ods;

use Composer\Pcre\Preg;
use PhpOffice\PhpSpreadsheet\Calculation\Calculation;
use PhpOffice\PhpSpreadsheet\Calculation\Exception as CalculationException;
use PhpOffice\PhpSpreadsheet\Cell\Cell;
Expand Down Expand Up @@ -227,16 +228,15 @@ private function writeCells(XMLWriter $objWriter, RowCellIterator $cells): void
}
}
if (isset($attributes['ref'])) {
if (preg_match('/^([A-Z]{1,3})([0-9]{1,7})(:([A-Z]{1,3})([0-9]{1,7}))?$/', (string) $attributes['ref'], $matches) == 1) {
if (Preg::isMatch('/^([A-Z]{1,3})([0-9]{1,7})(:([A-Z]{1,3})([0-9]{1,7}))?$/', (string) $attributes['ref'], $matches)) {
$matrixRowSpan = 1;
$matrixColSpan = 1;
if (isset($matches[3])) {
$minRow = (int) $matches[2];
// https://github.com/phpstan/phpstan/issues/11602
$maxRow = (int) $matches[5]; // @phpstan-ignore-line
$maxRow = (int) $matches[5];
$matrixRowSpan = $maxRow - $minRow + 1;
$minCol = Coordinate::columnIndexFromString($matches[1]);
$maxCol = Coordinate::columnIndexFromString($matches[4]); // @phpstan-ignore-line
$maxCol = Coordinate::columnIndexFromString($matches[4]);
$matrixColSpan = $maxCol - $minCol + 1;
}
$objWriter->writeAttribute('table:number-matrix-columns-spanned', "$matrixColSpan");
Expand Down
18 changes: 9 additions & 9 deletions src/PhpSpreadsheet/Writer/Ods/Formula.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@

namespace PhpOffice\PhpSpreadsheet\Writer\Ods;

use Composer\Pcre\Preg;
use PhpOffice\PhpSpreadsheet\Calculation\Calculation;
use PhpOffice\PhpSpreadsheet\DefinedName;
use PhpOffice\PhpSpreadsheet\Shared\StringHelper;

class Formula
{
Expand Down Expand Up @@ -33,14 +35,13 @@ public function convertFormula(string $formula, string $worksheetName = ''): str

private function convertDefinedNames(string $formula): string
{
$splitCount = preg_match_all(
$splitCount = Preg::matchAllWithOffsets(
'/' . Calculation::CALCULATION_REGEXP_DEFINEDNAME . '/mui',
$formula,
$splitRanges,
PREG_OFFSET_CAPTURE
$splitRanges
);

$lengths = array_map('strlen', array_column($splitRanges[0], 0));
$lengths = array_map([StringHelper::class, 'strlenAllowNull'], array_column($splitRanges[0], 0));
$offsets = array_column($splitRanges[0], 1);
$values = array_column($splitRanges[0], 0);

Expand All @@ -60,14 +61,13 @@ private function convertDefinedNames(string $formula): string

private function convertCellReferences(string $formula, string $worksheetName): string
{
$splitCount = preg_match_all(
$splitCount = Preg::matchAllWithOffsets(
'/' . Calculation::CALCULATION_REGEXP_CELLREF_RELATIVE . '/mui',
$formula,
$splitRanges,
PREG_OFFSET_CAPTURE
$splitRanges
);

$lengths = array_map('strlen', array_column($splitRanges[0], 0));
$lengths = array_map([StringHelper::class, 'strlenAllowNull'], array_column($splitRanges[0], 0));
$offsets = array_column($splitRanges[0], 1);

$worksheets = $splitRanges[2];
Expand All @@ -76,7 +76,7 @@ private function convertCellReferences(string $formula, string $worksheetName):

// Replace any commas in the formula with semi-colons for Ods
// If by chance there are commas in worksheet names, then they will be "fixed" again in the loop
// because we've already extracted worksheet names with our preg_match_all()
// because we've already extracted worksheet names with our Preg::matchAllWithOffsets()
$formula = str_replace(',', ';', $formula);
while ($splitCount > 0) {
--$splitCount;
Expand Down
Loading

0 comments on commit 3f15579

Please sign in to comment.