Skip to content

Commit 7a97d24

Browse files
authored
Merge pull request #1946 from liborm85/php80
Compatibility with PHP 7.4, PHP 8.0 and migrate to Laminas Escaper
2 parents ec1b3d3 + 36b63a1 commit 7a97d24

File tree

19 files changed

+102
-45
lines changed

19 files changed

+102
-45
lines changed

.scrutinizer.yml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,12 @@ build:
33
analysis:
44
tests:
55
override: [php-scrutinizer-run]
6+
environment:
7+
php:
8+
version: '7.4'
9+
pecl_extensions:
10+
- zip
11+
612
filter:
713
excluded_paths: [ 'vendor/*', 'tests/*', 'samples/*', 'src/PhpWord/Shared/PCLZip/*' ]
814

.travis.yml

Lines changed: 31 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,29 +11,30 @@ php:
1111
- 7.1
1212
- 7.2
1313
- 7.3
14-
- 7.4snapshot
14+
- 7.4
15+
- 8.0
1516

1617
matrix:
1718
include:
1819
- php: 5.3
1920
dist: precise
20-
env: COMPOSER_MEMORY_LIMIT=3G
2121
- php: 5.4
2222
dist: trusty
2323
- php: 5.5
2424
dist: trusty
2525
- php: 7.0
2626
env: COVERAGE=1
27-
- php: 7.3
27+
- php: 8.0
2828
env: DEPENDENCIES="--ignore-platform-reqs"
2929
exclude:
3030
- php: 5.3
31+
dist: xenial
3132
- php: 5.4
33+
dist: xenial
3234
- php: 5.5
33-
- php: 7.0
34-
- php: 7.3
35+
dist: xenial
3536
allow_failures:
36-
- php: 7.4snapshot
37+
- php: 8.0
3738

3839
cache:
3940
directories:
@@ -55,7 +56,31 @@ before_script:
5556
- if [ -z "$COVERAGE" ]; then phpenv config-rm xdebug.ini || echo "xdebug not available" ; fi
5657
## Composer
5758
- composer self-update
59+
## Composer in PHP versions 5.x requires 3 GB memory
60+
- if [ ${TRAVIS_PHP_VERSION:0:2} == "5." ]; then export COMPOSER_MEMORY_LIMIT=3G ; fi
61+
## PHP 8 require PHPUnit 8 (ugly hack for support PHPUnit 7 and 8 together)
62+
- |
63+
if [[ ${TRAVIS_PHP_VERSION:0:2} == "8." ]] || [[ $TRAVIS_PHP_VERSION == "nightly" ]]; then
64+
travis_wait composer remove phpunit/phpunit --dev --no-update --no-interaction
65+
travis_wait composer require phpunit/phpunit ^8.0 --dev --no-update
66+
fi
67+
## Install composer packages
5868
- travis_wait composer install --prefer-source $(if [ -n "$DEPENDENCIES" ]; then echo $DEPENDENCIES; fi)
69+
## PHP 8 require PHPUnit 8 (ugly hack for support PHPUnit 7 and 8 together)
70+
- |
71+
if [[ ${TRAVIS_PHP_VERSION:0:2} == "8." ]] || [[ $TRAVIS_PHP_VERSION == "nightly" ]]; then
72+
find ./tests/ -name "*.php" -type f -exec sed -i -e 's/function setUpBeforeClass()$/function setUpBeforeClass(): void/' {} \;
73+
find ./tests/ -name "*.php" -type f -exec sed -i -e 's/function tearDownAfterClass()$/function tearDownAfterClass(): void/' {} \;
74+
find ./tests/ -name "*.php" -type f -exec sed -i -e 's/function setUp()$/function setUp(): void/' {} \;
75+
find ./tests/ -name "*.php" -type f -exec sed -i -e 's/function tearDown()$/function tearDown(): void/' {} \;
76+
77+
find ./tests/ -name "*.php" -type f -exec sed -i -e 's/->assertContains(/->assertStringContainsString(/' {} \;
78+
find ./tests/ -name "*.php" -type f -exec sed -i -e 's/->assertNotContains(/->assertStringNotContainsString(/' {} \;
79+
find ./tests/ -name "*.php" -type f -exec sed -i -e "s/->assertInternalType('array', /->assertIsArray(/" {} \;
80+
81+
sed -i "s/\$this->addWarning('The @expectedException,/\/\/\$this->addWarning('The @expectedException,/" ./vendor/phpunit/phpunit/src/Framework/TestCase.php
82+
sed -i "s/self::createWarning('The optional \$delta/\/\/self::createWarning('The optional \$delta/" ./vendor/phpunit/phpunit/src/Framework/Assert.php
83+
fi
5984
## PHPDocumentor
6085
##- mkdir -p build/docs
6186
- mkdir -p build/coverage

README.md

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,8 +62,7 @@ PHPWord requires the following:
6262

6363
- PHP 5.3.3+
6464
- [XML Parser extension](http://www.php.net/manual/en/xml.installation.php)
65-
- [Zend\Escaper component](http://framework.zend.com/manual/current/en/modules/zend.escaper.introduction.html)
66-
- [Zend\Stdlib component](http://framework.zend.com/manual/current/en/modules/zend.stdlib.hydrator.html)
65+
- [Laminas Escaper component](https://docs.laminas.dev/laminas-escaper/intro/)
6766
- [Zip extension](http://php.net/manual/en/book.zip.php) (optional, used to write OOXML and ODF)
6867
- [GD extension](http://php.net/manual/en/book.image.php) (optional, used to add images)
6968
- [XMLWriter extension](http://php.net/manual/en/book.xmlwriter.php) (optional, used to write OOXML and ODF)

composer.json

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -58,24 +58,27 @@
5858
"fix": "Fixes issues found by PHP-CS"
5959
},
6060
"require": {
61-
"php": "^5.3.3 || ^7.0",
61+
"php": "^5.3.3 || ^7.0 || ^8.0",
6262
"ext-xml": "*",
63-
"zendframework/zend-escaper": "^2.2",
63+
"laminas/laminas-escaper": "^2.2",
6464
"phpoffice/common": "^0.2.9"
6565
},
6666
"require-dev": {
6767
"ext-zip": "*",
6868
"ext-gd": "*",
6969
"phpunit/phpunit": "^4.8.36 || ^7.0",
70-
"squizlabs/php_codesniffer": "^2.9",
70+
"squizlabs/php_codesniffer": "^2.9 || ^3.5",
7171
"friendsofphp/php-cs-fixer": "^2.2",
7272
"phpmd/phpmd": "2.*",
73-
"phploc/phploc": "2.* || 3.* || 4.*",
73+
"phploc/phploc": "2.* || 3.* || 4.* || 5.* || 6.* || 7.*",
7474
"dompdf/dompdf":"0.8.*",
7575
"tecnickcom/tcpdf": "6.*",
76-
"mpdf/mpdf": "5.7.4 || 6.* || 7.*",
76+
"mpdf/mpdf": "5.7.4 || 6.* || 7.* || 8.*",
7777
"php-coveralls/php-coveralls": "1.1.0 || ^2.0"
7878
},
79+
"replace": {
80+
"laminas/laminas-zendframework-bridge": "*"
81+
},
7982
"suggest": {
8083
"ext-zip": "Allows writing OOXML and ODF",
8184
"ext-gd2": "Allows adding images",

docs/installing.rst

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,7 @@ Mandatory:
1010

1111
- PHP 5.3.3+
1212
- `XML Parser <http://www.php.net/manual/en/xml.installation.php>`__ extension
13-
- `Zend\\Escaper <http://framework.zend.com/manual/current/en/modules/zend.escaper.introduction.html>`__ component
14-
- Zend\\Stdlib component
15-
- `Zend\\Validator <http://framework.zend.com/manual/current/en/modules/zend.validator.html>`__ component
13+
- `Laminas Escaper <https://docs.laminas.dev/laminas-escaper/intro/>`__ component
1614

1715
Optional:
1816

phpmd.xml.dist

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
xsi:schemaLocation="http://pmd.sf.net/ruleset/1.0.0 http://pmd.sf.net/ruleset_xml_schema.xsd"
66
xsi:noNamespaceSchemaLocation="http://pmd.sf.net/ruleset_xml_schema.xsd">
77
<rule ref="rulesets/naming.xml">
8+
<exclude name="ShortVariable" />
9+
<exclude name="ShortClassName" />
810
<exclude name="LongVariable" />
911
</rule>
1012
<rule ref="rulesets/naming.xml/LongVariable">

src/PhpWord/Element/AbstractContainer.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,7 @@ public function __call($function, $args)
109109
} else {
110110
// All other elements
111111
array_unshift($args, $element); // Prepend element name to the beginning of args array
112+
112113
return call_user_func_array(array($this, 'addElement'), $args);
113114
}
114115
}

src/PhpWord/Element/Image.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -454,7 +454,7 @@ private function setSourceType()
454454
} else {
455455
$this->sourceType = self::SOURCE_GD;
456456
}
457-
} elseif (@file_exists($this->source)) {
457+
} elseif ((strpos($this->source, chr(0)) === false) && @file_exists($this->source)) {
458458
$this->memoryImage = false;
459459
$this->sourceType = self::SOURCE_LOCAL;
460460
} else {

src/PhpWord/Reader/MsDoc.php

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1581,7 +1581,7 @@ private function readPrl($data, $pos, $cbNum)
15811581
// Variables
15821582
$sprmCPicLocation = null;
15831583
$sprmCFData = null;
1584-
$sprmCFSpec = null;
1584+
//$sprmCFSpec = null;
15851585

15861586
do {
15871587
// Variables
@@ -1830,7 +1830,7 @@ private function readPrl($data, $pos, $cbNum)
18301830
break;
18311831
// sprmCFSpec
18321832
case 0x55:
1833-
$sprmCFSpec = $operand;
1833+
//$sprmCFSpec = $operand;
18341834
break;
18351835
// sprmCFtcBi
18361836
case 0x5E:
@@ -2094,11 +2094,11 @@ private function readPrl($data, $pos, $cbNum)
20942094
$sprmCPicLocation += 1;
20952095

20962096
// stPicName
2097-
$stPicName = '';
2097+
//$stPicName = '';
20982098
for ($inc = 0; $inc <= $cchPicName; $inc++) {
2099-
$chr = self::getInt1d($this->dataData, $sprmCPicLocation);
2099+
//$chr = self::getInt1d($this->dataData, $sprmCPicLocation);
21002100
$sprmCPicLocation += 1;
2101-
$stPicName .= chr($chr);
2101+
//$stPicName .= chr($chr);
21022102
}
21032103
}
21042104

@@ -2143,11 +2143,11 @@ private function readPrl($data, $pos, $cbNum)
21432143
$sprmCPicLocation += 1;
21442144
// nameData
21452145
if ($cbName > 0) {
2146-
$nameData = '';
2146+
//$nameData = '';
21472147
for ($inc = 0; $inc <= ($cbName / 2); $inc++) {
2148-
$chr = self::getInt2d($this->dataData, $sprmCPicLocation);
2148+
//$chr = self::getInt2d($this->dataData, $sprmCPicLocation);
21492149
$sprmCPicLocation += 2;
2150-
$nameData .= chr($chr);
2150+
//$nameData .= chr($chr);
21512151
}
21522152
}
21532153
// embeddedBlip

src/PhpWord/Reader/Word2007/AbstractPart.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -573,11 +573,11 @@ private function readCellStyle(XMLReader $xmlReader, \DOMElement $domNode)
573573
* Returns the first child element found
574574
*
575575
* @param XMLReader $xmlReader
576-
* @param \DOMElement $parentNode
577-
* @param string|array $elements
576+
* @param \DOMElement|null $parentNode
577+
* @param string|array|null $elements
578578
* @return string|null
579579
*/
580-
private function findPossibleElement(XMLReader $xmlReader, \DOMElement $parentNode = null, $elements)
580+
private function findPossibleElement(XMLReader $xmlReader, \DOMElement $parentNode = null, $elements = null)
581581
{
582582
if (is_array($elements)) {
583583
//if element is an array, we take the first element that exists in the XML

src/PhpWord/Shared/Converter.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -338,9 +338,9 @@ public static function htmlToRgb($value)
338338
return false;
339339
}
340340

341-
$red = hexdec($red);
342-
$green = hexdec($green);
343-
$blue = hexdec($blue);
341+
$red = ctype_xdigit($red) ? hexdec($red) : 0;
342+
$green = ctype_xdigit($green) ? hexdec($green) : 0;
343+
$blue = ctype_xdigit($blue) ? hexdec($blue) : 0;
344344

345345
return array($red, $green, $blue);
346346
}

src/PhpWord/Shared/Html.php

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -72,15 +72,19 @@ public static function addHtml($element, $html, $fullHTML = false, $preserveWhit
7272
}
7373

7474
// Load DOM
75-
$orignalLibEntityLoader = libxml_disable_entity_loader(true);
75+
if (\PHP_VERSION_ID < 80000) {
76+
$orignalLibEntityLoader = libxml_disable_entity_loader(true);
77+
}
7678
$dom = new \DOMDocument();
7779
$dom->preserveWhiteSpace = $preserveWhiteSpace;
7880
$dom->loadXML($html);
7981
self::$xpath = new \DOMXPath($dom);
8082
$node = $dom->getElementsByTagName('body');
8183

8284
self::parseNode($node->item(0), $element);
83-
libxml_disable_entity_loader($orignalLibEntityLoader);
85+
if (\PHP_VERSION_ID < 80000) {
86+
libxml_disable_entity_loader($orignalLibEntityLoader);
87+
}
8488
}
8589

8690
/**
@@ -178,7 +182,7 @@ protected static function parseNode($node, $element, $styles = array(), $data =
178182
}
179183
}
180184
$method = "parse{$method}";
181-
$newElement = call_user_func_array(array('PhpOffice\PhpWord\Shared\Html', $method), $arguments);
185+
$newElement = call_user_func_array(array('PhpOffice\PhpWord\Shared\Html', $method), array_values($arguments));
182186

183187
// Retrieve back variables from arguments
184188
foreach ($keys as $key) {

src/PhpWord/TemplateProcessor.php

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,9 @@ protected function readPartWithRels($fileName)
170170
*/
171171
protected function transformSingleXml($xml, $xsltProcessor)
172172
{
173-
$orignalLibEntityLoader = libxml_disable_entity_loader(true);
173+
if (\PHP_VERSION_ID < 80000) {
174+
$orignalLibEntityLoader = libxml_disable_entity_loader(true);
175+
}
174176
$domDocument = new \DOMDocument();
175177
if (false === $domDocument->loadXML($xml)) {
176178
throw new Exception('Could not load the given XML document.');
@@ -180,7 +182,9 @@ protected function transformSingleXml($xml, $xsltProcessor)
180182
if (false === $transformedXml) {
181183
throw new Exception('Could not transform the given XML document.');
182184
}
183-
libxml_disable_entity_loader($orignalLibEntityLoader);
185+
if (\PHP_VERSION_ID < 80000) {
186+
libxml_disable_entity_loader($orignalLibEntityLoader);
187+
}
184188

185189
return $transformedXml;
186190
}

src/PhpWord/Writer/HTML/Element/AbstractElement.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,9 @@
1717

1818
namespace PhpOffice\PhpWord\Writer\HTML\Element;
1919

20+
use Laminas\Escaper\Escaper;
2021
use PhpOffice\PhpWord\Element\AbstractElement as Element;
2122
use PhpOffice\PhpWord\Writer\AbstractWriter;
22-
use Zend\Escaper\Escaper;
2323

2424
/**
2525
* Abstract HTML element writer
@@ -50,7 +50,7 @@ abstract class AbstractElement
5050
protected $withoutP = false;
5151

5252
/**
53-
* @var \Zend\Escaper\Escaper|\PhpOffice\PhpWord\Escaper\AbstractEscaper
53+
* @var \Laminas\Escaper\Escaper|\PhpOffice\PhpWord\Escaper\AbstractEscaper
5454
*/
5555
protected $escaper;
5656

src/PhpWord/Writer/HTML/Part/AbstractPart.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,9 @@
1717

1818
namespace PhpOffice\PhpWord\Writer\HTML\Part;
1919

20+
use Laminas\Escaper\Escaper;
2021
use PhpOffice\PhpWord\Exception\Exception;
2122
use PhpOffice\PhpWord\Writer\AbstractWriter;
22-
use Zend\Escaper\Escaper;
2323

2424
/**
2525
* @since 0.11.0
@@ -32,7 +32,7 @@ abstract class AbstractPart
3232
private $parentWriter;
3333

3434
/**
35-
* @var \Zend\Escaper\Escaper
35+
* @var \Laminas\Escaper\Escaper
3636
*/
3737
protected $escaper;
3838

tests/PhpWord/Element/TableTest.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -99,10 +99,10 @@ public function testCountColumns()
9999
{
100100
$oTable = new Table();
101101
$oTable->addRow();
102-
$element = $oTable->addCell();
102+
$oTable->addCell();
103103
$this->assertEquals($oTable->countColumns(), 1);
104-
$element = $oTable->addCell();
105-
$element = $oTable->addCell();
104+
$oTable->addCell();
105+
$oTable->addCell();
106106
$this->assertEquals($oTable->countColumns(), 3);
107107
}
108108
}

tests/PhpWord/TemplateProcessorTest.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,11 @@ final public function testXslStyleSheetCanBeApplied($actualDocumentFqfn)
140140
*/
141141
final public function testXslStyleSheetCanNotBeAppliedOnFailureOfSettingParameterValue()
142142
{
143+
// Test is not needed for PHP 8.0, because internally validation throws TypeError exception.
144+
if (\PHP_VERSION_ID >= 80000) {
145+
$this->markTestSkipped('not needed for PHP 8.0');
146+
}
147+
143148
$templateProcessor = new TemplateProcessor(__DIR__ . '/_files/templates/blank.docx');
144149

145150
$xslDomDocument = new \DOMDocument();

tests/PhpWord/Writer/PDF/TCPDFTest.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,12 @@ class TCPDFTest extends \PHPUnit\Framework\TestCase
3333
*/
3434
public function testConstruct()
3535
{
36+
// TCPDF version 6.3.5 doesn't support PHP 5.3, fixed via https://github.com/tecnickcom/TCPDF/pull/197,
37+
// pending new release.
38+
if (version_compare(PHP_VERSION, '5.4.0', '<')) {
39+
return;
40+
}
41+
3642
$file = __DIR__ . '/../../_files/tcpdf.pdf';
3743

3844
$phpWord = new PhpWord();

tests/PhpWord/_includes/XmlDocument.php

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -76,10 +76,14 @@ public function getFileDom($file = 'word/document.xml')
7676
$this->file = $file;
7777

7878
$file = $this->path . '/' . $file;
79-
$orignalLibEntityLoader = libxml_disable_entity_loader(false);
79+
if (\PHP_VERSION_ID < 80000) {
80+
$orignalLibEntityLoader = libxml_disable_entity_loader(false);
81+
}
8082
$this->dom = new \DOMDocument();
8183
$this->dom->load($file);
82-
libxml_disable_entity_loader($orignalLibEntityLoader);
84+
if (\PHP_VERSION_ID < 80000) {
85+
libxml_disable_entity_loader($orignalLibEntityLoader);
86+
}
8387

8488
return $this->dom;
8589
}

0 commit comments

Comments
 (0)