From c5221e0958f11d02fab02cc62547d38376b9959f Mon Sep 17 00:00:00 2001 From: Progi1984 Date: Mon, 11 Dec 2023 10:30:57 +0100 Subject: [PATCH] Added support for PHP 8.2 & 8.3 --- .github/workflows/php.yml | 4 +- composer.json | 7 ++- phpunit.xml.dist | 1 + src/Common/Adapter/Zip/PclZipAdapter.php | 6 +- src/Common/Adapter/Zip/ZipArchiveAdapter.php | 10 ++-- src/Common/Drawing.php | 4 +- src/Common/File.php | 7 +-- src/Common/Microsoft/PasswordEncoder.php | 2 +- src/Common/XMLReader.php | 56 +++++++++---------- src/Common/XMLWriter.php | 2 +- ...AdapterTest.php => AbstractZipAdapter.php} | 4 +- .../Tests/Adapter/Zip/PclZipAdapterTest.php | 4 +- .../Adapter/Zip/ZipArchiveAdapterTest.php | 4 +- tests/Common/Tests/DrawingTest.php | 2 +- .../Tests/Microsoft/PasswordEncoderTest.php | 24 ++++---- tests/Common/Tests/XMLReaderTest.php | 21 +++---- tests/Common/Tests/XMLWriterTest.php | 2 +- .../Common/Tests/_includes/TestHelperZip.php | 4 +- tests/Common/Tests/_includes/XmlDocument.php | 30 +++++----- 19 files changed, 91 insertions(+), 103 deletions(-) rename tests/Common/Tests/Adapter/Zip/{AbstractZipAdapterTest.php => AbstractZipAdapter.php} (93%) diff --git a/.github/workflows/php.yml b/.github/workflows/php.yml index 9342279..9902828 100644 --- a/.github/workflows/php.yml +++ b/.github/workflows/php.yml @@ -47,7 +47,7 @@ jobs: strategy: fail-fast: false matrix: - php: ['7.1', '7.2', '7.3', '7.4', '8.0', '8.1'] + php: ['7.1', '7.2', '7.3', '7.4', '8.0', '8.1', '8.2', '8.3'] steps: - name: Setup PHP uses: shivammathur/setup-php@v2 @@ -68,7 +68,7 @@ jobs: strategy: fail-fast: false matrix: - php: ['7.1', '7.2', '7.3', '7.4', '8.0', '8.1'] + php: ['7.1', '7.2', '7.3', '7.4', '8.0', '8.1', '8.2', '8.3'] steps: - name: Setup PHP uses: shivammathur/setup-php@v2 diff --git a/composer.json b/composer.json index b84cb46..5ecbcef 100644 --- a/composer.json +++ b/composer.json @@ -21,11 +21,16 @@ "require-dev": { "phpunit/phpunit": ">=7", "phpmd/phpmd": "2.*", - "phpstan/phpstan": "^0.12.88" + "phpstan/phpstan": "^0.12.88 || ^1.0.0" }, "autoload": { "psr-4": { "PhpOffice\\Common\\": "src/Common/" } + }, + "autoload-dev": { + "psr-4": { + "PhpOffice\\Common\\Tests\\": "tests/Common/Tests" + } } } diff --git a/phpunit.xml.dist b/phpunit.xml.dist index 05dc372..9a7e2fa 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -5,6 +5,7 @@ convertErrorsToExceptions="true" convertNoticesToExceptions="true" convertWarningsToExceptions="true" + convertDeprecationsToExceptions="true" processIsolation="false" stopOnFailure="false"> diff --git a/src/Common/Adapter/Zip/PclZipAdapter.php b/src/Common/Adapter/Zip/PclZipAdapter.php index 9d31f1a..2ccca4e 100644 --- a/src/Common/Adapter/Zip/PclZipAdapter.php +++ b/src/Common/Adapter/Zip/PclZipAdapter.php @@ -2,12 +2,10 @@ namespace PhpOffice\Common\Adapter\Zip; -use PclZip; - class PclZipAdapter implements ZipInterface { /** - * @var PclZip + * @var \PclZip */ protected $oPclZip; @@ -18,7 +16,7 @@ class PclZipAdapter implements ZipInterface public function open($filename) { - $this->oPclZip = new PclZip($filename); + $this->oPclZip = new \PclZip($filename); $this->tmpDir = sys_get_temp_dir(); return $this; diff --git a/src/Common/Adapter/Zip/ZipArchiveAdapter.php b/src/Common/Adapter/Zip/ZipArchiveAdapter.php index a8728eb..7636bf4 100644 --- a/src/Common/Adapter/Zip/ZipArchiveAdapter.php +++ b/src/Common/Adapter/Zip/ZipArchiveAdapter.php @@ -2,12 +2,10 @@ namespace PhpOffice\Common\Adapter\Zip; -use ZipArchive; - class ZipArchiveAdapter implements ZipInterface { /** - * @var ZipArchive + * @var \ZipArchive */ protected $oZipArchive; @@ -19,12 +17,12 @@ class ZipArchiveAdapter implements ZipInterface public function open($filename) { $this->filename = $filename; - $this->oZipArchive = new ZipArchive(); + $this->oZipArchive = new \ZipArchive(); - if ($this->oZipArchive->open($this->filename, ZipArchive::OVERWRITE) === true) { + if ($this->oZipArchive->open($this->filename, \ZipArchive::OVERWRITE) === true) { return $this; } - if ($this->oZipArchive->open($this->filename, ZipArchive::CREATE) === true) { + if ($this->oZipArchive->open($this->filename, \ZipArchive::CREATE) === true) { return $this; } throw new \Exception("Could not open $this->filename for writing."); diff --git a/src/Common/Drawing.php b/src/Common/Drawing.php index 2f71865..2b112e3 100644 --- a/src/Common/Drawing.php +++ b/src/Common/Drawing.php @@ -118,7 +118,7 @@ public static function pointsToPixels(float $pValue = 0): float */ public static function pixelsToCentimeters(int $pValue = 0): float { - //return $pValue * 0.028; + // return $pValue * 0.028; return ($pValue / self::DPI_96) * 2.54; } @@ -135,7 +135,7 @@ public static function centimetersToPixels(float $pValue = 0): int return 0; } - return (int) round((($pValue / 2.54) * self::DPI_96)); + return (int) round(($pValue / 2.54) * self::DPI_96); } /** diff --git a/src/Common/File.php b/src/Common/File.php index 8ab931d..7f35870 100644 --- a/src/Common/File.php +++ b/src/Common/File.php @@ -17,8 +17,6 @@ namespace PhpOffice\Common; -use ZipArchive; - class File { /** @@ -38,7 +36,7 @@ public static function fileExists(string $pFilename): bool $zipFile = substr($pFilename, 6, strpos($pFilename, '#') - 6); $archiveFile = substr($pFilename, strpos($pFilename, '#') + 1); - $zip = new ZipArchive(); + $zip = new \ZipArchive(); if ($zip->open($zipFile) === true) { $returnValue = ($zip->getFromName($archiveFile) !== false); $zip->close(); @@ -70,7 +68,7 @@ public static function fileGetContents(string $pFilename): ?string $zipFile = substr($pFilename, 6, strpos($pFilename, '#') - 6); $archiveFile = substr($pFilename, strpos($pFilename, '#') + 1); - $zip = new ZipArchive(); + $zip = new \ZipArchive(); if ($zip->open($zipFile) === true) { $returnValue = $zip->getFromName($archiveFile); $zip->close(); @@ -80,6 +78,7 @@ public static function fileGetContents(string $pFilename): ?string return null; } + // Regular file contents return file_get_contents($pFilename); } diff --git a/src/Common/Microsoft/PasswordEncoder.php b/src/Common/Microsoft/PasswordEncoder.php index 097060b..a32d5af 100644 --- a/src/Common/Microsoft/PasswordEncoder.php +++ b/src/Common/Microsoft/PasswordEncoder.php @@ -49,7 +49,7 @@ class PasswordEncoder self::ALGORITHM_MAC => [5, ''], // 'mac' -> not possible with hash() self::ALGORITHM_RIPEMD => [6, 'ripemd'], self::ALGORITHM_RIPEMD_160 => [7, 'ripemd160'], - self::ALGORITHM_HMAC => [9, ''], //'hmac' -> not possible with hash() + self::ALGORITHM_HMAC => [9, ''], // 'hmac' -> not possible with hash() self::ALGORITHM_SHA_256 => [12, 'sha256'], self::ALGORITHM_SHA_384 => [13, 'sha384'], self::ALGORITHM_SHA_512 => [14, 'sha512'], diff --git a/src/Common/XMLReader.php b/src/Common/XMLReader.php index 5d9fe81..601074e 100644 --- a/src/Common/XMLReader.php +++ b/src/Common/XMLReader.php @@ -18,8 +18,6 @@ namespace PhpOffice\Common; use DOMDocument; -use DOMElement; -use DOMNodeList; use DOMXpath; use ZipArchive; @@ -33,16 +31,16 @@ class XMLReader /** * DOMDocument object * - * @var DOMDocument + * @var \DOMDocument */ - private $dom = null; + private $dom; /** * DOMXpath object * - * @var DOMXpath + * @var \DOMXpath */ - private $xpath = null; + private $xpath; /** * Get DOMDocument from ZipArchive @@ -50,7 +48,7 @@ class XMLReader * @param string $zipFile * @param string $xmlFile * - * @return DOMDocument|false + * @return \DOMDocument|false * * @throws \Exception */ @@ -60,7 +58,7 @@ public function getDomFromZip(string $zipFile, string $xmlFile) throw new \Exception('Cannot find archive file.'); } - $zip = new ZipArchive(); + $zip = new \ZipArchive(); $zip->open($zipFile); $content = $zip->getFromName($xmlFile); $zip->close(); @@ -77,7 +75,7 @@ public function getDomFromZip(string $zipFile, string $xmlFile) * * @param string $content * - * @return DOMDocument + * @return \DOMDocument */ public function getDomFromString(string $content) { @@ -86,7 +84,7 @@ public function getDomFromString(string $content) $originalLibXMLEntityValue = libxml_disable_entity_loader(true); } - $this->dom = new DOMDocument(); + $this->dom = new \DOMDocument(); $this->dom->loadXML($content); if (\PHP_VERSION_ID < 80000) { @@ -100,17 +98,17 @@ public function getDomFromString(string $content) * Get elements * * @param string $path - * @param DOMElement $contextNode + * @param \DOMElement $contextNode * - * @return DOMNodeList + * @return \DOMNodeList<\DOMElement> */ - public function getElements(string $path, DOMElement $contextNode = null) + public function getElements(string $path, \DOMElement $contextNode = null) { if ($this->dom === null) { - return new DOMNodeList(); + return new \DOMNodeList(); } if ($this->xpath === null) { - $this->xpath = new DOMXpath($this->dom); + $this->xpath = new \DOMXpath($this->dom); } if (is_null($contextNode)) { @@ -136,7 +134,7 @@ public function registerNamespace($prefix, $namespaceURI) throw new \InvalidArgumentException('Dom needs to be loaded before registering a namespace'); } if ($this->xpath === null) { - $this->xpath = new DOMXpath($this->dom); + $this->xpath = new \DOMXpath($this->dom); } return $this->xpath->registerNamespace($prefix, $namespaceURI); @@ -146,15 +144,15 @@ public function registerNamespace($prefix, $namespaceURI) * Get element * * @param string $path - * @param DOMElement $contextNode + * @param \DOMElement $contextNode * - * @return DOMElement|null + * @return \DOMElement|null */ - public function getElement($path, DOMElement $contextNode = null): ?DOMElement + public function getElement($path, \DOMElement $contextNode = null): ?\DOMElement { $elements = $this->getElements($path, $contextNode); if ($elements->length > 0) { - return $elements->item(0) instanceof DOMElement ? $elements->item(0) : null; + return $elements->item(0) instanceof \DOMElement ? $elements->item(0) : null; } return null; @@ -164,18 +162,18 @@ public function getElement($path, DOMElement $contextNode = null): ?DOMElement * Get element attribute * * @param string $attribute - * @param DOMElement $contextNode + * @param \DOMElement $contextNode * @param string $path * * @return string|null */ - public function getAttribute($attribute, DOMElement $contextNode = null, $path = null) + public function getAttribute($attribute, \DOMElement $contextNode = null, $path = null) { $return = null; if ($path !== null) { $elements = $this->getElements($path, $contextNode); if ($elements->length > 0) { - /** @var DOMElement $node Type hint */ + /** @var \DOMElement $node Type hint */ $node = $elements->item(0); $return = $node->getAttribute($attribute); } @@ -192,11 +190,11 @@ public function getAttribute($attribute, DOMElement $contextNode = null, $path = * Get element value * * @param string $path - * @param DOMElement $contextNode + * @param \DOMElement $contextNode * * @return string|null */ - public function getValue($path, DOMElement $contextNode = null) + public function getValue($path, \DOMElement $contextNode = null) { $elements = $this->getElements($path, $contextNode); if ($elements->length > 0) { @@ -210,11 +208,11 @@ public function getValue($path, DOMElement $contextNode = null) * Count elements * * @param string $path - * @param DOMElement $contextNode + * @param \DOMElement $contextNode * * @return int */ - public function countElements($path, DOMElement $contextNode = null) + public function countElements($path, \DOMElement $contextNode = null) { $elements = $this->getElements($path, $contextNode); @@ -225,11 +223,11 @@ public function countElements($path, DOMElement $contextNode = null) * Element exists * * @param string $path - * @param DOMElement $contextNode + * @param \DOMElement $contextNode * * @return bool */ - public function elementExists($path, DOMElement $contextNode = null) + public function elementExists($path, \DOMElement $contextNode = null) { return $this->getElements($path, $contextNode)->length > 0; } diff --git a/src/Common/XMLWriter.php b/src/Common/XMLWriter.php index 4c886d6..511022a 100644 --- a/src/Common/XMLWriter.php +++ b/src/Common/XMLWriter.php @@ -143,7 +143,7 @@ public function writeElementBlock(string $element, $attributes, string $value = * * @return void */ - public function writeElementIf(bool $condition, string $element, ?string $attribute = null, $value = null) + public function writeElementIf(bool $condition, string $element, string $attribute = null, $value = null) { if ($condition) { if (is_null($attribute)) { diff --git a/tests/Common/Tests/Adapter/Zip/AbstractZipAdapterTest.php b/tests/Common/Tests/Adapter/Zip/AbstractZipAdapter.php similarity index 93% rename from tests/Common/Tests/Adapter/Zip/AbstractZipAdapterTest.php rename to tests/Common/Tests/Adapter/Zip/AbstractZipAdapter.php index 3387cf4..af34b8c 100644 --- a/tests/Common/Tests/Adapter/Zip/AbstractZipAdapterTest.php +++ b/tests/Common/Tests/Adapter/Zip/AbstractZipAdapter.php @@ -1,11 +1,11 @@ assertEquals(0, Drawing::centimetersToPoints()); $this->assertEquals(28.346456692913385, Drawing::centimetersToPoints(1)); - $this->assertEquals(31.181102362204726, Drawing::centimetersToPoints(1.1)); + $this->assertEquals(31.181102362204722, Drawing::centimetersToPoints(1.1)); } public function testTwips(): void diff --git a/tests/Common/Tests/Microsoft/PasswordEncoderTest.php b/tests/Common/Tests/Microsoft/PasswordEncoderTest.php index 538aa4e..fd3916f 100644 --- a/tests/Common/Tests/Microsoft/PasswordEncoderTest.php +++ b/tests/Common/Tests/Microsoft/PasswordEncoderTest.php @@ -31,13 +31,13 @@ class PasswordEncoderTest extends \PHPUnit\Framework\TestCase */ public function testEncodePassword(): void { - //given + // Given $password = 'test'; - //when + // When $hashPassword = PasswordEncoder::hashPassword($password); - //then + // Then $this->assertEquals('M795/MAlmGU8RIsY9Q9uDLHC7bk=', $hashPassword); } @@ -46,14 +46,14 @@ public function testEncodePassword(): void */ public function testEncodePasswordWithSalt(): void { - //given + // Given $password = 'test'; $salt = base64_decode('uq81pJRRGFIY5U+E9gt8tA=='); - //when + // When $hashPassword = PasswordEncoder::hashPassword($password, PasswordEncoder::ALGORITHM_SHA_1, $salt); - //then + // Then $this->assertEquals('QiDOcpia1YzSVJPiKPwWebl9p/0=', $hashPassword); } @@ -62,14 +62,14 @@ public function testEncodePasswordWithSalt(): void */ public function testDefaultsToSha1IfUnsupportedAlgorithm(): void { - //given + // Given $password = 'test'; $salt = base64_decode('uq81pJRRGFIY5U+E9gt8tA=='); - //when + // When $hashPassword = PasswordEncoder::hashPassword($password, PasswordEncoder::ALGORITHM_MAC, $salt); - //then + // Then $this->assertEquals('QiDOcpia1YzSVJPiKPwWebl9p/0=', $hashPassword); } @@ -78,14 +78,14 @@ public function testDefaultsToSha1IfUnsupportedAlgorithm(): void */ public function testEncodePasswordWithNullAsciiCodeInPassword(): void { - //given + // Given $password = 'test' . chr(0); $salt = base64_decode('uq81pJRRGFIY5U+E9gt8tA=='); - //when + // When $hashPassword = PasswordEncoder::hashPassword($password, PasswordEncoder::ALGORITHM_MAC, $salt, 1); - //then + // Then $this->assertEquals('rDV9sgdDsztoCQlvRCb1lF2wxNg=', $hashPassword); } } diff --git a/tests/Common/Tests/XMLReaderTest.php b/tests/Common/Tests/XMLReaderTest.php index 02603d5..9923d56 100644 --- a/tests/Common/Tests/XMLReaderTest.php +++ b/tests/Common/Tests/XMLReaderTest.php @@ -18,7 +18,6 @@ namespace PhpOffice\Common\Tests; use Exception; -use InvalidArgumentException; use PhpOffice\Common\XMLReader; use PHPUnit\Framework\TestCase; @@ -64,7 +63,7 @@ public function testDomFromZip(): void */ public function testThrowsExceptionOnNonExistingArchive(): void { - $this->expectException(Exception::class); + $this->expectException(\Exception::class); $this->expectExceptionMessage('Cannot find archive file.'); $pathResources = PHPOFFICE_COMMON_TESTS_BASE_DIR . DIRECTORY_SEPARATOR . 'resources' . DIRECTORY_SEPARATOR . 'files' . DIRECTORY_SEPARATOR; @@ -102,16 +101,12 @@ public function testReturnNullOnNonExistingNode(): void */ public function testShouldThrowExceptionIfNamespaceIsNotKnown(): void { - try { - $reader = new XMLReader(); - $reader->getDomFromString('AAA'); - - $this->assertTrue($reader->elementExists('/element/test:child')); - $this->assertEquals('AAA', $reader->getElement('/element/test:child')->textContent); - $this->fail(); - } catch (\Exception $e) { - $this->assertTrue(true); - } + $reader = new XMLReader(); + $reader->getDomFromString('AAA'); + $reader->registerNamespace('test', 'http://phpword.com/my/custom/namespace'); + + $this->assertTrue($reader->elementExists('/element/test:child')); + $this->assertEquals('AAA', $reader->getElement('/element/test:child')->textContent); } /** @@ -132,7 +127,7 @@ public function testShouldParseXmlWithCustomNamespace(): void */ public function testShouldThowExceptionIfTryingToRegisterNamespaceBeforeReadingDoc(): void { - $this->expectException(InvalidArgumentException::class); + $this->expectException(\InvalidArgumentException::class); $this->expectExceptionMessage('Dom needs to be loaded before registering a namespace'); $reader = new XMLReader(); diff --git a/tests/Common/Tests/XMLWriterTest.php b/tests/Common/Tests/XMLWriterTest.php index 53a237c..f1990b5 100644 --- a/tests/Common/Tests/XMLWriterTest.php +++ b/tests/Common/Tests/XMLWriterTest.php @@ -152,7 +152,7 @@ public function testWriteElementIf(bool $condition, ?string $attribute, ?string /** * @return array> */ - public function dataProviderWriteElementIf(): array + public static function dataProviderWriteElementIf(): array { return [ [ diff --git a/tests/Common/Tests/_includes/TestHelperZip.php b/tests/Common/Tests/_includes/TestHelperZip.php index df59087..dc78e81 100644 --- a/tests/Common/Tests/_includes/TestHelperZip.php +++ b/tests/Common/Tests/_includes/TestHelperZip.php @@ -2,13 +2,11 @@ namespace PhpOffice\Common\Tests; -use ZipArchive; - class TestHelperZip { public static function assertFileExists(string $fileZip, string $path): bool { - $oZip = new ZipArchive(); + $oZip = new \ZipArchive(); if ($oZip->open($fileZip) !== true) { return false; } diff --git a/tests/Common/Tests/_includes/XmlDocument.php b/tests/Common/Tests/_includes/XmlDocument.php index ff4ff8c..4faf6f3 100644 --- a/tests/Common/Tests/_includes/XmlDocument.php +++ b/tests/Common/Tests/_includes/XmlDocument.php @@ -18,10 +18,6 @@ namespace PhpOffice\PhpPowerpoint\Tests; -use DOMDocument; -use DOMElement; -use DOMNode; -use DOMNodeList; use DOMXpath; /** @@ -37,16 +33,16 @@ class XmlDocument private $path; /** - * DOMDocument object + * \DOMDocument object * - * @var DOMDocument + * @var \DOMDocument */ private $dom; /** * DOMXpath object * - * @var DOMXpath|null + * @var \DOMXpath|null */ private $xpath; @@ -72,9 +68,9 @@ public function __construct(string $path) * * @param string $file * - * @return DOMDocument + * @return \DOMDocument */ - public function getFileDom(string $file = 'word/document.xml'): DOMDocument + public function getFileDom(string $file = 'word/document.xml'): \DOMDocument { if (null !== $this->dom && $file === $this->file) { return $this->dom; @@ -84,7 +80,7 @@ public function getFileDom(string $file = 'word/document.xml'): DOMDocument $this->file = $file; $file = $this->path . '/' . $file; - $this->dom = new DOMDocument(); + $this->dom = new \DOMDocument(); $this->dom->load($file); return $this->dom; @@ -96,16 +92,16 @@ public function getFileDom(string $file = 'word/document.xml'): DOMDocument * @param string $path * @param string $file * - * @return DOMNodeList + * @return \DOMNodeList<\DOMElement> */ - public function getNodeList(string $path, string $file = 'word/document.xml'): DOMNodeList + public function getNodeList(string $path, string $file = 'word/document.xml'): \DOMNodeList { if ($this->dom === null || $file !== $this->file) { $this->getFileDom($file); } if (null === $this->xpath) { - $this->xpath = new DOMXpath($this->dom); + $this->xpath = new \DOMXpath($this->dom); } return $this->xpath->query($path); @@ -117,9 +113,9 @@ public function getNodeList(string $path, string $file = 'word/document.xml'): D * @param string $path * @param string $file * - * @return DOMNode + * @return \DOMNode */ - public function getElement(string $path, string $file = 'word/document.xml'): DOMNode + public function getElement(string $path, string $file = 'word/document.xml'): \DOMNode { $elements = $this->getNodeList($path, $file); @@ -159,7 +155,7 @@ public function getElementAttribute(string $path, string $attribute, string $fil { $element = $this->getElement($path, $file); - return $element instanceof DOMElement ? $element->getAttribute($attribute) : ''; + return $element instanceof \DOMElement ? $element->getAttribute($attribute) : ''; } /** @@ -175,7 +171,7 @@ public function attributeElementExists(string $path, string $attribute, string $ { $element = $this->getElement($path, $file); - return $element instanceof DOMElement ? $element->hasAttribute($attribute) : false; + return $element instanceof \DOMElement ? $element->hasAttribute($attribute) : false; } /**