Merge branch 'master' into chartcaption
This commit is contained in:
commit
e8966183d3
|
|
@ -3490,11 +3490,6 @@ parameters:
|
|||
count: 1
|
||||
path: src/PhpSpreadsheet/Settings.php
|
||||
|
||||
-
|
||||
message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\CodePage\\:\\:\\$pageArray has no typehint specified\\.$#"
|
||||
count: 1
|
||||
path: src/PhpSpreadsheet/Shared/CodePage.php
|
||||
|
||||
-
|
||||
message: "#^Parameter \\#1 \\$dateValue of static method PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Date\\:\\:timestampToExcel\\(\\) expects int, float\\|int\\|string given\\.$#"
|
||||
count: 1
|
||||
|
|
@ -4025,11 +4020,6 @@ parameters:
|
|||
count: 1
|
||||
path: src/PhpSpreadsheet/Shared/OLERead.php
|
||||
|
||||
-
|
||||
message: "#^Argument of an invalid type array\\<int, string\\>\\|false supplied for foreach, only iterables are supported\\.$#"
|
||||
count: 1
|
||||
path: src/PhpSpreadsheet/Shared/PasswordHasher.php
|
||||
|
||||
-
|
||||
message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\StringHelper\\:\\:sanitizeUTF8\\(\\) should return string but returns string\\|false\\.$#"
|
||||
count: 1
|
||||
|
|
@ -6515,16 +6505,6 @@ parameters:
|
|||
count: 1
|
||||
path: tests/PhpSpreadsheetTests/Reader/Security/XmlScannerTest.php
|
||||
|
||||
-
|
||||
message: "#^Cannot call method getFormattedValue\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Cell\\\\Cell\\|null\\.$#"
|
||||
count: 1
|
||||
path: tests/PhpSpreadsheetTests/Reader/XlsTest.php
|
||||
|
||||
-
|
||||
message: "#^Cannot call method getCoordinate\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Cell\\\\Cell\\|null\\.$#"
|
||||
count: 1
|
||||
path: tests/PhpSpreadsheetTests/Reader/XlsTest.php
|
||||
|
||||
-
|
||||
message: "#^Method PhpOffice\\\\PhpSpreadsheetTests\\\\Reader\\\\Xlsx\\\\AutoFilterTest\\:\\:getWorksheetInstance\\(\\) has no return typehint specified\\.$#"
|
||||
count: 1
|
||||
|
|
@ -6640,11 +6620,6 @@ parameters:
|
|||
count: 1
|
||||
path: tests/PhpSpreadsheetTests/Worksheet/RowCellIterator2Test.php
|
||||
|
||||
-
|
||||
message: "#^Parameter \\#1 \\$options of static method PhpOffice\\\\PhpSpreadsheet\\\\Settings\\:\\:setLibXmlLoaderOptions\\(\\) expects int, null given\\.$#"
|
||||
count: 1
|
||||
path: tests/PhpSpreadsheetTests/Worksheet/WorksheetNamedRangesTest.php
|
||||
|
||||
-
|
||||
message: "#^Property PhpOffice\\\\PhpSpreadsheetTests\\\\Writer\\\\Csv\\\\CsvEnclosureTest\\:\\:\\$cellValues has no typehint specified\\.$#"
|
||||
count: 1
|
||||
|
|
@ -6685,11 +6660,6 @@ parameters:
|
|||
count: 3
|
||||
path: tests/PhpSpreadsheetTests/Writer/Html/HtmlCommentsTest.php
|
||||
|
||||
-
|
||||
message: "#^Parameter \\#1 \\$options of static method PhpOffice\\\\PhpSpreadsheet\\\\Settings\\:\\:setLibXmlLoaderOptions\\(\\) expects int, null given\\.$#"
|
||||
count: 1
|
||||
path: tests/PhpSpreadsheetTests/Writer/Xlsx/FloatsRetainedTest.php
|
||||
|
||||
-
|
||||
message: "#^Parameter \\#2 \\$locale of function setlocale expects string\\|null, string\\|false given\\.$#"
|
||||
count: 1
|
||||
|
|
@ -6700,16 +6670,6 @@ parameters:
|
|||
count: 1
|
||||
path: tests/PhpSpreadsheetTests/Writer/Xlsx/LocaleFloatsTest.php
|
||||
|
||||
-
|
||||
message: "#^Parameter \\#1 \\$options of static method PhpOffice\\\\PhpSpreadsheet\\\\Settings\\:\\:setLibXmlLoaderOptions\\(\\) expects int, null given\\.$#"
|
||||
count: 2
|
||||
path: tests/PhpSpreadsheetTests/Writer/Xlsx/StartsWithHashTest.php
|
||||
|
||||
-
|
||||
message: "#^Parameter \\#1 \\$options of static method PhpOffice\\\\PhpSpreadsheet\\\\Settings\\:\\:setLibXmlLoaderOptions\\(\\) expects int, null given\\.$#"
|
||||
count: 2
|
||||
path: tests/PhpSpreadsheetTests/Writer/Xlsx/UnparsedDataCloneTest.php
|
||||
|
||||
-
|
||||
message: "#^Cannot call method getDrawingCollection\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\Worksheet\\|null\\.$#"
|
||||
count: 4
|
||||
|
|
@ -6720,11 +6680,6 @@ parameters:
|
|||
count: 4
|
||||
path: tests/PhpSpreadsheetTests/Writer/Xlsx/UnparsedDataCloneTest.php
|
||||
|
||||
-
|
||||
message: "#^Parameter \\#1 \\$options of static method PhpOffice\\\\PhpSpreadsheet\\\\Settings\\:\\:setLibXmlLoaderOptions\\(\\) expects int, null given\\.$#"
|
||||
count: 1
|
||||
path: tests/PhpSpreadsheetTests/Writer/Xlsx/UnparsedDataTest.php
|
||||
|
||||
-
|
||||
message: "#^Parameter \\#1 \\$data of function simplexml_load_string expects string, string\\|false given\\.$#"
|
||||
count: 2
|
||||
|
|
|
|||
|
|
@ -336,6 +336,29 @@ class Xlsx extends BaseReader
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $fileName
|
||||
*/
|
||||
private function fileExistsInArchive(ZipArchive $archive, $fileName = ''): bool
|
||||
{
|
||||
// Root-relative paths
|
||||
if (strpos($fileName, '//') !== false) {
|
||||
$fileName = substr($fileName, strpos($fileName, '//') + 1);
|
||||
}
|
||||
$fileName = File::realpath($fileName);
|
||||
|
||||
// Sadly, some 3rd party xlsx generators don't use consistent case for filenaming
|
||||
// so we need to load case-insensitively from the zip file
|
||||
|
||||
// Apache POI fixes
|
||||
$contents = $archive->locateName($fileName, ZipArchive::FL_NOCASE);
|
||||
if ($contents === false) {
|
||||
$contents = $archive->locateName(substr($fileName, 1), ZipArchive::FL_NOCASE);
|
||||
}
|
||||
|
||||
return $contents !== false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $fileName
|
||||
*
|
||||
|
|
@ -821,8 +844,8 @@ class Xlsx extends BaseReader
|
|||
$this->readSheetProtection($docSheet, $xmlSheet);
|
||||
}
|
||||
|
||||
if ($xmlSheet && $xmlSheet->autoFilter && !$this->readDataOnly) {
|
||||
(new AutoFilter($docSheet, $xmlSheet))->load();
|
||||
if ($this->readDataOnly === false) {
|
||||
$this->readAutoFilterTables($xmlSheet, $docSheet, $dir, $fileWorksheet, $zip);
|
||||
}
|
||||
|
||||
if ($xmlSheet && $xmlSheet->mergeCells && $xmlSheet->mergeCells->mergeCell && !$this->readDataOnly) {
|
||||
|
|
@ -1977,4 +2000,52 @@ class Xlsx extends BaseReader
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function readAutoFilterTables(
|
||||
SimpleXMLElement $xmlSheet,
|
||||
Worksheet $docSheet,
|
||||
string $dir,
|
||||
string $fileWorksheet,
|
||||
ZipArchive $zip
|
||||
): void {
|
||||
if ($xmlSheet && $xmlSheet->autoFilter) {
|
||||
// In older files, autofilter structure is defined in the worksheet file
|
||||
(new AutoFilter($docSheet, $xmlSheet))->load();
|
||||
} elseif ($xmlSheet && $xmlSheet->tableParts && $xmlSheet->tableParts['count'] > 0) {
|
||||
// But for Office365, MS decided to make it all just a bit more complicated
|
||||
$this->readAutoFilterTablesInTablesFile($xmlSheet, $dir, $fileWorksheet, $zip, $docSheet);
|
||||
}
|
||||
}
|
||||
|
||||
private function readAutoFilterTablesInTablesFile(
|
||||
SimpleXMLElement $xmlSheet,
|
||||
string $dir,
|
||||
string $fileWorksheet,
|
||||
ZipArchive $zip,
|
||||
Worksheet $docSheet
|
||||
): void {
|
||||
foreach ($xmlSheet->tableParts->tablePart as $tablePart) {
|
||||
$relation = self::getAttributes($tablePart, Namespaces::SCHEMA_OFFICE_DOCUMENT);
|
||||
$tablePartRel = (string) $relation['id'];
|
||||
$relationsFileName = dirname("$dir/$fileWorksheet") . '/_rels/' . basename($fileWorksheet) . '.rels';
|
||||
|
||||
if ($zip->locateName($relationsFileName)) {
|
||||
$relsTableReferences = $this->loadZip($relationsFileName, Namespaces::RELATIONSHIPS);
|
||||
foreach ($relsTableReferences->Relationship as $relationship) {
|
||||
$relationshipAttributes = self::getAttributes($relationship, '');
|
||||
|
||||
if ((string) $relationshipAttributes['Id'] === $tablePartRel) {
|
||||
$relationshipFileName = (string) $relationshipAttributes['Target'];
|
||||
$relationshipFilePath = dirname("$dir/$fileWorksheet") . '/' . $relationshipFileName;
|
||||
$relationshipFilePath = File::realpath($relationshipFilePath);
|
||||
|
||||
if ($this->fileExistsInArchive($this->zip, $relationshipFilePath)) {
|
||||
$autoFilter = $this->loadZip($relationshipFilePath);
|
||||
(new AutoFilter($docSheet, $autoFilter))->load();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ class CodePage
|
|||
{
|
||||
public const DEFAULT_CODE_PAGE = 'CP1252';
|
||||
|
||||
/** @var array */
|
||||
private static $pageArray = [
|
||||
0 => 'CP1252', // CodePage is not always correctly set when the xls file was saved by Apple's Numbers program
|
||||
367 => 'ASCII', // ASCII
|
||||
|
|
@ -56,7 +57,7 @@ class CodePage
|
|||
10010 => 'MACROMANIA', // Macintosh Romania
|
||||
10017 => 'MACUKRAINE', // Macintosh Ukraine
|
||||
10021 => 'MACTHAI', // Macintosh Thai
|
||||
10029 => 'MACCENTRALEUROPE', // Macintosh Central Europe
|
||||
10029 => ['MACCENTRALEUROPE', 'MAC-CENTRALEUROPE'], // Macintosh Central Europe
|
||||
10079 => 'MACICELAND', // Macintosh Icelandic
|
||||
10081 => 'MACTURKISH', // Macintosh Turkish
|
||||
10082 => 'MACCROATIAN', // Macintosh Croatian
|
||||
|
|
@ -65,6 +66,7 @@ class CodePage
|
|||
//32769 => 'unsupported', // ANSI Latin I (BIFF2-BIFF3)
|
||||
65000 => 'UTF-7', // Unicode (UTF-7)
|
||||
65001 => 'UTF-8', // Unicode (UTF-8)
|
||||
99999 => ['unsupported'], // Unicode (UTF-8)
|
||||
];
|
||||
|
||||
public static function validate(string $codePage): bool
|
||||
|
|
@ -83,7 +85,20 @@ class CodePage
|
|||
public static function numberToName(int $codePage): string
|
||||
{
|
||||
if (array_key_exists($codePage, self::$pageArray)) {
|
||||
return self::$pageArray[$codePage];
|
||||
$value = self::$pageArray[$codePage];
|
||||
if (is_array($value)) {
|
||||
foreach ($value as $encoding) {
|
||||
if (@iconv('UTF-8', $encoding, ' ') !== false) {
|
||||
self::$pageArray[$codePage] = $encoding;
|
||||
|
||||
return $encoding;
|
||||
}
|
||||
}
|
||||
|
||||
throw new PhpSpreadsheetException("Code page $codePage not implemented on this system.");
|
||||
} else {
|
||||
return $value;
|
||||
}
|
||||
}
|
||||
if ($codePage == 720 || $codePage == 32769) {
|
||||
throw new PhpSpreadsheetException("Code page $codePage not supported."); // OEM Arabic
|
||||
|
|
|
|||
|
|
@ -2,11 +2,13 @@
|
|||
|
||||
namespace PhpOffice\PhpSpreadsheet\Shared;
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\Exception;
|
||||
use PhpOffice\PhpSpreadsheet\Exception as SpException;
|
||||
use PhpOffice\PhpSpreadsheet\Worksheet\Protection;
|
||||
|
||||
class PasswordHasher
|
||||
{
|
||||
const MAX_PASSWORD_LENGTH = 255;
|
||||
|
||||
/**
|
||||
* Get algorithm name for PHP.
|
||||
*/
|
||||
|
|
@ -34,36 +36,40 @@ class PasswordHasher
|
|||
return $mapping[$algorithmName];
|
||||
}
|
||||
|
||||
throw new Exception('Unsupported password algorithm: ' . $algorithmName);
|
||||
throw new SpException('Unsupported password algorithm: ' . $algorithmName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a password hash from a given string.
|
||||
*
|
||||
* This method is based on the algorithm provided by
|
||||
* This method is based on the spec at:
|
||||
* https://interoperability.blob.core.windows.net/files/MS-OFFCRYPTO/[MS-OFFCRYPTO].pdf
|
||||
* 2.3.7.1 Binary Document Password Verifier Derivation Method 1
|
||||
*
|
||||
* It replaces a method based on the algorithm provided by
|
||||
* Daniel Rentz of OpenOffice and the PEAR package
|
||||
* Spreadsheet_Excel_Writer by Xavier Noguer <xnoguer@rezebra.com>.
|
||||
*
|
||||
* Scrutinizer will squawk at the use of bitwise operations here,
|
||||
* but it should ultimately pass.
|
||||
*
|
||||
* @param string $pPassword Password to hash
|
||||
*/
|
||||
private static function defaultHashPassword(string $pPassword): string
|
||||
{
|
||||
$password = 0x0000;
|
||||
$charPos = 1; // char position
|
||||
|
||||
// split the plain text password in its component characters
|
||||
$chars = preg_split('//', $pPassword, -1, PREG_SPLIT_NO_EMPTY);
|
||||
foreach ($chars as $char) {
|
||||
$value = ord($char) << $charPos++; // shifted ASCII value
|
||||
$rotated_bits = $value >> 15; // rotated bits beyond bit 15
|
||||
$value &= 0x7fff; // first 15 bits
|
||||
$password ^= ($value | $rotated_bits);
|
||||
$verifier = 0;
|
||||
$pwlen = strlen($pPassword);
|
||||
$passwordArray = pack('c', $pwlen) . $pPassword;
|
||||
for ($i = $pwlen; $i >= 0; --$i) {
|
||||
$intermediate1 = (($verifier & 0x4000) === 0) ? 0 : 1;
|
||||
$intermediate2 = 2 * $verifier;
|
||||
$intermediate2 = $intermediate2 & 0x7fff;
|
||||
$intermediate3 = $intermediate1 | $intermediate2;
|
||||
$verifier = $intermediate3 ^ ord($passwordArray[$i]);
|
||||
}
|
||||
$verifier ^= 0xCE4B;
|
||||
|
||||
$password ^= strlen($pPassword);
|
||||
$password ^= 0xCE4B;
|
||||
|
||||
return strtoupper(dechex($password));
|
||||
return strtoupper(dechex($verifier));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -82,6 +88,9 @@ class PasswordHasher
|
|||
*/
|
||||
public static function hashPassword(string $password, string $algorithm = '', string $salt = '', int $spinCount = 10000): string
|
||||
{
|
||||
if (strlen($password) > self::MAX_PASSWORD_LENGTH) {
|
||||
throw new SpException('Password exceeds ' . self::MAX_PASSWORD_LENGTH . ' characters');
|
||||
}
|
||||
$phpAlgorithm = self::getAlgorithm($algorithm);
|
||||
if (!$phpAlgorithm) {
|
||||
return self::defaultHashPassword($password);
|
||||
|
|
|
|||
|
|
@ -267,6 +267,11 @@ class Column
|
|||
return null;
|
||||
}
|
||||
|
||||
public function ruleCount(): int
|
||||
{
|
||||
return count($this->ruleset);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all AutoFilter Column Rules.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -2138,7 +2138,7 @@ class Worksheet extends BIFFwriter
|
|||
private function writePassword(): void
|
||||
{
|
||||
// Exit unless sheet protection and password have been specified
|
||||
if (!$this->phpSheet->getProtection()->getSheet() || !$this->phpSheet->getProtection()->getPassword()) {
|
||||
if (!$this->phpSheet->getProtection()->getSheet() || !$this->phpSheet->getProtection()->getPassword() || $this->phpSheet->getProtection()->getAlgorithm() !== '') {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,74 @@
|
|||
<?php
|
||||
|
||||
namespace PhpOffice\PhpSpreadsheetTests\Features\AutoFilter\Xlsx;
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\Reader\Xlsx;
|
||||
use PhpOffice\PhpSpreadsheet\Worksheet\AutoFilter\Column\Rule;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class BasicLoadTest extends TestCase
|
||||
{
|
||||
public function testLoadAutoFilter(): void
|
||||
{
|
||||
$filename = 'tests/data/Features/AutoFilter/Xlsx/AutoFilter_Basic.xlsx';
|
||||
$reader = new Xlsx();
|
||||
$spreadsheet = $reader->load($filename);
|
||||
|
||||
$worksheet = $spreadsheet->getActiveSheet();
|
||||
self::assertSame('A1:D57', $worksheet->getAutoFilter()->getRange());
|
||||
self::assertSame(2, $worksheet->getAutoFilter()->getColumn('C')->ruleCount());
|
||||
self::assertSame(
|
||||
Rule::AUTOFILTER_COLUMN_RULE_EQUAL,
|
||||
$worksheet->getAutoFilter()->getColumn('C')->getRules()[0]->getOperator()
|
||||
);
|
||||
self::assertSame('UK', $worksheet->getAutoFilter()->getColumn('C')->getRules()[0]->getValue());
|
||||
self::assertSame(
|
||||
Rule::AUTOFILTER_COLUMN_RULE_EQUAL,
|
||||
$worksheet->getAutoFilter()->getColumn('C')->getRules()[1]->getOperator()
|
||||
);
|
||||
self::assertSame('United States', $worksheet->getAutoFilter()->getColumn('C')->getRules()[1]->getValue());
|
||||
self::assertSame(2, $worksheet->getAutoFilter()->getColumn('D')->ruleCount());
|
||||
self::assertSame(
|
||||
Rule::AUTOFILTER_COLUMN_RULE_GREATERTHAN,
|
||||
$worksheet->getAutoFilter()->getColumn('D')->getRules()[0]->getOperator()
|
||||
);
|
||||
self::assertSame('650', $worksheet->getAutoFilter()->getColumn('D')->getRules()[0]->getValue());
|
||||
self::assertSame(
|
||||
Rule::AUTOFILTER_COLUMN_RULE_LESSTHAN,
|
||||
$worksheet->getAutoFilter()->getColumn('D')->getRules()[1]->getOperator()
|
||||
);
|
||||
self::assertSame('800', $worksheet->getAutoFilter()->getColumn('D')->getRules()[1]->getValue());
|
||||
}
|
||||
|
||||
public function testLoadOffice365AutoFilter(): void
|
||||
{
|
||||
$filename = 'tests/data/Features/AutoFilter/Xlsx/AutoFilter_Basic_Office365.xlsx';
|
||||
$reader = new Xlsx();
|
||||
$spreadsheet = $reader->load($filename);
|
||||
|
||||
$worksheet = $spreadsheet->getActiveSheet();
|
||||
self::assertSame('A1:D57', $worksheet->getAutoFilter()->getRange());
|
||||
self::assertSame(2, $worksheet->getAutoFilter()->getColumn('C')->ruleCount());
|
||||
self::assertSame(
|
||||
Rule::AUTOFILTER_COLUMN_RULE_EQUAL,
|
||||
$worksheet->getAutoFilter()->getColumn('C')->getRules()[0]->getOperator()
|
||||
);
|
||||
self::assertSame('UK', $worksheet->getAutoFilter()->getColumn('C')->getRules()[0]->getValue());
|
||||
self::assertSame(
|
||||
Rule::AUTOFILTER_COLUMN_RULE_EQUAL,
|
||||
$worksheet->getAutoFilter()->getColumn('C')->getRules()[1]->getOperator()
|
||||
);
|
||||
self::assertSame('United States', $worksheet->getAutoFilter()->getColumn('C')->getRules()[1]->getValue());
|
||||
self::assertSame(2, $worksheet->getAutoFilter()->getColumn('D')->ruleCount());
|
||||
self::assertSame(
|
||||
Rule::AUTOFILTER_COLUMN_RULE_GREATERTHAN,
|
||||
$worksheet->getAutoFilter()->getColumn('D')->getRules()[0]->getOperator()
|
||||
);
|
||||
self::assertSame('650', $worksheet->getAutoFilter()->getColumn('D')->getRules()[0]->getValue());
|
||||
self::assertSame(
|
||||
Rule::AUTOFILTER_COLUMN_RULE_LESSTHAN,
|
||||
$worksheet->getAutoFilter()->getColumn('D')->getRules()[1]->getOperator()
|
||||
);
|
||||
self::assertSame('800', $worksheet->getAutoFilter()->getColumn('D')->getRules()[1]->getValue());
|
||||
}
|
||||
}
|
||||
|
|
@ -1,8 +1,10 @@
|
|||
<?php
|
||||
|
||||
namespace PhpOffice\PhpSpreadsheetTests\Reader;
|
||||
namespace PhpOffice\PhpSpreadsheetTests\Reader\Xls;
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\Cell\Cell;
|
||||
use PhpOffice\PhpSpreadsheet\Reader\Xls;
|
||||
use PhpOffice\PhpSpreadsheet\Shared\CodePage;
|
||||
use PhpOffice\PhpSpreadsheetTests\Functional\AbstractFunctional;
|
||||
|
||||
class XlsTest extends AbstractFunctional
|
||||
|
|
@ -16,6 +18,7 @@ class XlsTest extends AbstractFunctional
|
|||
$reader = new Xls();
|
||||
$spreadsheet = $reader->load($filename);
|
||||
self::assertEquals('Title', $spreadsheet->getSheet(0)->getCell('A1')->getValue());
|
||||
$spreadsheet->disconnectWorksheets();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -42,6 +45,8 @@ class XlsTest extends AbstractFunctional
|
|||
self::assertEquals($row, $newrow);
|
||||
self::assertEquals($sheet->getCell('A1')->getFormattedValue(), $newsheet->getCell('A1')->getFormattedValue());
|
||||
self::assertEquals($sheet->getCell("$col$row")->getFormattedValue(), $newsheet->getCell("$col$row")->getFormattedValue());
|
||||
$spreadsheet->disconnectWorksheets();
|
||||
$newspreadsheet->disconnectWorksheets();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -71,11 +76,49 @@ class XlsTest extends AbstractFunctional
|
|||
$rowIterator = $sheet->getRowIterator();
|
||||
|
||||
foreach ($rowIterator as $row) {
|
||||
foreach ($row->getCellIterator() as $cell) {
|
||||
foreach ($row->getCellIterator() as $cellx) {
|
||||
/** @var Cell */
|
||||
$cell = $cellx;
|
||||
$valOld = $cell->getFormattedValue();
|
||||
$valNew = $newsheet->getCell($cell->getCoordinate())->getFormattedValue();
|
||||
self::assertEquals($valOld, $valNew);
|
||||
}
|
||||
}
|
||||
$spreadsheet->disconnectWorksheets();
|
||||
$newspreadsheet->disconnectWorksheets();
|
||||
}
|
||||
|
||||
/**
|
||||
* Test load Xls file with MACCENTRALEUROPE encoding, which is implemented
|
||||
* as MAC-CENTRALEUROPE on some systems. Issue #549.
|
||||
*/
|
||||
public function testLoadMacCentralEurope(): void
|
||||
{
|
||||
$codePages = CodePage::getEncodings();
|
||||
self::assertIsArray($codePages[10029]);
|
||||
$filename = 'tests/data/Reader/XLS/maccentraleurope.xls';
|
||||
$reader = new Xls();
|
||||
// When no fix applied, spreadsheet fails to load on some systems
|
||||
$spreadsheet = $reader->load($filename);
|
||||
$sheet = $spreadsheet->getActiveSheet();
|
||||
self::assertSame('Ładowność', $sheet->getCell('I1')->getValue());
|
||||
$spreadsheet->disconnectWorksheets();
|
||||
}
|
||||
|
||||
/**
|
||||
* First test changes array entry in CodePage.
|
||||
* This test confirms new that new entry is okay.
|
||||
*/
|
||||
public function testLoadMacCentralEurope2(): void
|
||||
{
|
||||
$codePages = CodePage::getEncodings();
|
||||
self::assertIsString($codePages[10029]);
|
||||
$filename = 'tests/data/Reader/XLS/maccentraleurope.xls';
|
||||
$reader = new Xls();
|
||||
// When no fix applied, spreadsheet fails to load on some systems
|
||||
$spreadsheet = $reader->load($filename);
|
||||
$sheet = $spreadsheet->getActiveSheet();
|
||||
self::assertSame('Ładowność', $sheet->getCell('I1')->getValue());
|
||||
$spreadsheet->disconnectWorksheets();
|
||||
}
|
||||
}
|
||||
|
|
@ -41,6 +41,7 @@ class SettingsTest extends TestCase
|
|||
|
||||
public function testSetXMLSettings(): void
|
||||
{
|
||||
$original = Settings::getLibXmlLoaderOptions();
|
||||
Settings::setLibXmlLoaderOptions(LIBXML_DTDLOAD | LIBXML_DTDATTR | LIBXML_DTDVALID);
|
||||
$result = Settings::getLibXmlLoaderOptions();
|
||||
self::assertTrue((bool) ((LIBXML_DTDLOAD | LIBXML_DTDATTR | LIBXML_DTDVALID) & $result));
|
||||
|
|
@ -48,5 +49,6 @@ class SettingsTest extends TestCase
|
|||
if (\PHP_VERSION_ID < 80000) {
|
||||
self::assertFalse(libxml_disable_entity_loader());
|
||||
}
|
||||
Settings::setLibXmlLoaderOptions($original);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,8 +16,15 @@ class CodePageTest extends TestCase
|
|||
*/
|
||||
public function testCodePageNumberToName($expectedResult, $codePageIndex): void
|
||||
{
|
||||
if ($expectedResult === 'exception') {
|
||||
$this->expectException(Exception::class);
|
||||
}
|
||||
$result = CodePage::numberToName($codePageIndex);
|
||||
self::assertEquals($expectedResult, $result);
|
||||
if (is_array($expectedResult)) {
|
||||
self::assertContains($result, $expectedResult);
|
||||
} else {
|
||||
self::assertEquals($expectedResult, $result);
|
||||
}
|
||||
}
|
||||
|
||||
public function providerCodePage(): array
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
namespace PhpOffice\PhpSpreadsheetTests\Shared;
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\Exception as SpException;
|
||||
use PhpOffice\PhpSpreadsheet\Shared\PasswordHasher;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
|
|
@ -14,6 +15,9 @@ class PasswordHasherTest extends TestCase
|
|||
*/
|
||||
public function testHashPassword($expectedResult, ...$args): void
|
||||
{
|
||||
if ($expectedResult === 'exception') {
|
||||
$this->expectException(SpException::class);
|
||||
}
|
||||
$result = PasswordHasher::hashPassword(...$args);
|
||||
self::assertEquals($expectedResult, $result);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,51 @@
|
|||
<?php
|
||||
|
||||
namespace PhpOffice\PhpSpreadsheetTests\Shared;
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\Shared\PasswordHasher;
|
||||
use PhpOffice\PhpSpreadsheet\Spreadsheet;
|
||||
use PhpOffice\PhpSpreadsheetTests\Functional\AbstractFunctional;
|
||||
|
||||
class PasswordReloadTest extends AbstractFunctional
|
||||
{
|
||||
/**
|
||||
* @dataProvider providerPasswords
|
||||
*/
|
||||
public function testPasswordReload(string $format, string $algorithm, bool $supported = true): void
|
||||
{
|
||||
$password = 'hello';
|
||||
$spreadsheet = new Spreadsheet();
|
||||
$sheet = $spreadsheet->getActiveSheet();
|
||||
$sheet->getCell('A1')->setValue(1);
|
||||
$protection = $sheet->getProtection();
|
||||
$protection->setAlgorithm($algorithm);
|
||||
$protection->setPassword($password);
|
||||
$protection->setSheet(true);
|
||||
|
||||
$reloadedSpreadsheet = $this->writeAndReload($spreadsheet, $format);
|
||||
$resheet = $reloadedSpreadsheet->getActiveSheet();
|
||||
$reprot = $resheet->getProtection();
|
||||
$repassword = $reprot->getPassword();
|
||||
$hash = '';
|
||||
if ($supported) {
|
||||
$readAlgorithm = $reprot->getAlgorithm();
|
||||
self::assertSame($algorithm, $readAlgorithm);
|
||||
$salt = $reprot->getSalt();
|
||||
$spin = $reprot->getSpinCount();
|
||||
$hash = PasswordHasher::hashPassword($password, $readAlgorithm, $salt, $spin);
|
||||
}
|
||||
self::assertSame($repassword, $hash);
|
||||
$spreadsheet->disconnectWorksheets();
|
||||
$reloadedSpreadsheet->disconnectWorksheets();
|
||||
}
|
||||
|
||||
public function providerPasswords(): array
|
||||
{
|
||||
return [
|
||||
'Xls basic algorithm' => ['Xls', ''],
|
||||
'Xls cannot use SHA512' => ['Xls', 'SHA-512', false],
|
||||
'Xlsx basic algorithm' => ['Xlsx', ''],
|
||||
'Xlsx can use SHA512' => ['Xlsx', 'SHA-512'],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
@ -4,7 +4,6 @@ namespace PhpOffice\PhpSpreadsheetTests\Worksheet;
|
|||
|
||||
use PhpOffice\PhpSpreadsheet\Exception;
|
||||
use PhpOffice\PhpSpreadsheet\Reader\Xlsx;
|
||||
use PhpOffice\PhpSpreadsheet\Settings;
|
||||
use PhpOffice\PhpSpreadsheet\Spreadsheet;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
|
|
@ -17,8 +16,6 @@ class WorksheetNamedRangesTest extends TestCase
|
|||
|
||||
protected function setUp(): void
|
||||
{
|
||||
Settings::setLibXmlLoaderOptions(null); // reset to default options
|
||||
|
||||
$reader = new Xlsx();
|
||||
$this->spreadsheet = $reader->load('tests/data/Worksheet/namedRangeTest.xlsx');
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,7 +2,6 @@
|
|||
|
||||
namespace PhpOffice\PhpSpreadsheetTests\Writer\Xlsx;
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\Settings;
|
||||
use PhpOffice\PhpSpreadsheet\Spreadsheet;
|
||||
use PhpOffice\PhpSpreadsheet\Style\Conditional;
|
||||
use PhpOffice\PhpSpreadsheet\Style\Fill;
|
||||
|
|
@ -11,24 +10,6 @@ use PhpOffice\PhpSpreadsheetTests\Functional\AbstractFunctional;
|
|||
|
||||
class ConditionalTest extends AbstractFunctional
|
||||
{
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $prevValue;
|
||||
|
||||
protected function setUp(): void
|
||||
{
|
||||
$this->prevValue = Settings::getLibXmlLoaderOptions();
|
||||
|
||||
// Disable validating XML with the DTD
|
||||
Settings::setLibXmlLoaderOptions($this->prevValue & ~LIBXML_DTDVALID & ~LIBXML_DTDATTR & ~LIBXML_DTDLOAD);
|
||||
}
|
||||
|
||||
protected function tearDown(): void
|
||||
{
|
||||
Settings::setLibXmlLoaderOptions($this->prevValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test check if conditional style with type 'notContainsText' works on xlsx.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -4,30 +4,11 @@ namespace PhpOffice\PhpSpreadsheetTests\Writer\Xlsx;
|
|||
|
||||
use PhpOffice\PhpSpreadsheet\IOFactory;
|
||||
use PhpOffice\PhpSpreadsheet\Reader\Xlsx;
|
||||
use PhpOffice\PhpSpreadsheet\Settings;
|
||||
use PhpOffice\PhpSpreadsheet\Shared\File;
|
||||
use PhpOffice\PhpSpreadsheetTests\Functional\AbstractFunctional;
|
||||
|
||||
class DrawingsTest extends AbstractFunctional
|
||||
{
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $prevValue;
|
||||
|
||||
protected function setUp(): void
|
||||
{
|
||||
$this->prevValue = Settings::getLibXmlLoaderOptions();
|
||||
|
||||
// Disable validating XML with the DTD
|
||||
Settings::setLibXmlLoaderOptions($this->prevValue & ~LIBXML_DTDVALID & ~LIBXML_DTDATTR & ~LIBXML_DTDLOAD);
|
||||
}
|
||||
|
||||
protected function tearDown(): void
|
||||
{
|
||||
Settings::setLibXmlLoaderOptions($this->prevValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test save and load XLSX file with drawing on 2nd worksheet.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -3,7 +3,6 @@
|
|||
namespace PhpOffice\PhpSpreadsheetTests\Writer\Xlsx;
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\Reader\Xlsx as Reader;
|
||||
use PhpOffice\PhpSpreadsheet\Settings;
|
||||
use PhpOffice\PhpSpreadsheet\Shared\File;
|
||||
use PhpOffice\PhpSpreadsheet\Spreadsheet;
|
||||
use PhpOffice\PhpSpreadsheet\Writer\Xlsx as Writer;
|
||||
|
|
@ -19,7 +18,6 @@ class FloatsRetainedTest extends TestCase
|
|||
public function testIntyFloatsRetainedByWriter($value): void
|
||||
{
|
||||
$outputFilename = File::temporaryFilename();
|
||||
Settings::setLibXmlLoaderOptions(null);
|
||||
$sheet = new Spreadsheet();
|
||||
$sheet->getActiveSheet()->getCell('A1')->setValue($value);
|
||||
|
||||
|
|
|
|||
|
|
@ -4,7 +4,6 @@ namespace PhpOffice\PhpSpreadsheetTests\Writer\Xlsx;
|
|||
|
||||
use PhpOffice\PhpSpreadsheet\Cell\DataType;
|
||||
use PhpOffice\PhpSpreadsheet\Reader\Xlsx as Reader;
|
||||
use PhpOffice\PhpSpreadsheet\Settings;
|
||||
use PhpOffice\PhpSpreadsheet\Shared\File;
|
||||
use PhpOffice\PhpSpreadsheet\Spreadsheet;
|
||||
use PhpOffice\PhpSpreadsheet\Writer\Xlsx as Writer;
|
||||
|
|
@ -16,7 +15,6 @@ class StartsWithHashTest extends TestCase
|
|||
public function testStartWithHash(): void
|
||||
{
|
||||
$outputFilename = File::temporaryFilename();
|
||||
Settings::setLibXmlLoaderOptions(null);
|
||||
$spreadsheet = new Spreadsheet();
|
||||
$sheet = $spreadsheet->getActiveSheet();
|
||||
$sheet->setCellValueExplicit('A1', '#define M', DataType::TYPE_STRING);
|
||||
|
|
@ -41,7 +39,6 @@ class StartsWithHashTest extends TestCase
|
|||
{
|
||||
// Make sure raw data indicates A3 is an error, but A2 isn't.
|
||||
$outputFilename = File::temporaryFilename();
|
||||
Settings::setLibXmlLoaderOptions(null);
|
||||
$spreadsheet = new Spreadsheet();
|
||||
$sheet = $spreadsheet->getActiveSheet();
|
||||
$sheet->setCellValueExplicit('A1', '#define M', DataType::TYPE_STRING);
|
||||
|
|
|
|||
|
|
@ -2,7 +2,6 @@
|
|||
|
||||
namespace PhpOffice\PhpSpreadsheetTests\Writer\Xlsx;
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\Settings;
|
||||
use PhpOffice\PhpSpreadsheet\Shared\File;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use ZipArchive;
|
||||
|
|
@ -16,7 +15,6 @@ class UnparsedDataCloneTest extends TestCase
|
|||
{
|
||||
$sampleFilename = 'tests/data/Writer/XLSX/drawing_on_2nd_page.xlsx';
|
||||
$resultFilename = File::temporaryFilename();
|
||||
Settings::setLibXmlLoaderOptions(null); // reset to default options
|
||||
$reader = new \PhpOffice\PhpSpreadsheet\Reader\Xlsx();
|
||||
$spreadsheet = $reader->load($sampleFilename);
|
||||
$spreadsheet->setActiveSheetIndex(1);
|
||||
|
|
@ -63,7 +61,6 @@ class UnparsedDataCloneTest extends TestCase
|
|||
$resultFilename1 = File::temporaryFilename();
|
||||
$resultFilename2 = File::temporaryFilename();
|
||||
self::assertNotEquals($resultFilename1, $resultFilename2);
|
||||
Settings::setLibXmlLoaderOptions(null); // reset to default options
|
||||
$reader = new \PhpOffice\PhpSpreadsheet\Reader\Xlsx();
|
||||
$spreadsheet = $reader->load($sampleFilename);
|
||||
$sheet = $spreadsheet->setActiveSheetIndex(1);
|
||||
|
|
|
|||
|
|
@ -17,7 +17,6 @@ class UnparsedDataTest extends TestCase
|
|||
{
|
||||
$sampleFilename = 'tests/data/Writer/XLSX/form_pass_print.xlsm';
|
||||
$resultFilename = File::temporaryFilename();
|
||||
Settings::setLibXmlLoaderOptions(null); // reset to default options
|
||||
$reader = new \PhpOffice\PhpSpreadsheet\Reader\Xlsx();
|
||||
$excel = $reader->load($sampleFilename);
|
||||
|
||||
|
|
|
|||
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
|
@ -233,7 +233,7 @@ return [
|
|||
],
|
||||
// Macintosh Central Europe
|
||||
[
|
||||
'MACCENTRALEUROPE',
|
||||
['MACCENTRALEUROPE', 'MAC-CENTRALEUROPE'],
|
||||
10029,
|
||||
],
|
||||
// Macintosh Icelandic
|
||||
|
|
@ -271,4 +271,9 @@ return [
|
|||
'UTF-8',
|
||||
65001,
|
||||
],
|
||||
// invalid
|
||||
[
|
||||
'exception',
|
||||
99999,
|
||||
],
|
||||
];
|
||||
|
|
|
|||
|
|
@ -51,4 +51,9 @@ return [
|
|||
'Symbols_salt',
|
||||
100000,
|
||||
],
|
||||
// Additional tests suggested by Issue #1897
|
||||
['DCDF', 'ABCDEFGHIJKLMNOPQRSTUVW'],
|
||||
['ECD1', 'ABCDEFGHIJKLMNOPQRSTUVWX'],
|
||||
['88D2', 'ABCDEFGHIJKLMNOPQRSTUVWXY'],
|
||||
'password too long' => ['exception', str_repeat('x', 256)],
|
||||
];
|
||||
|
|
|
|||
Loading…
Reference in New Issue