Skip to content

Commit

Permalink
Fix #18317: Additional PHP 8 compatibility fixes
Browse files Browse the repository at this point in the history
Co-authored-by: Bizley <[email protected]>
  • Loading branch information
samdark and Bizley authored Oct 23, 2020
1 parent 7354329 commit ed1c087
Show file tree
Hide file tree
Showing 16 changed files with 149 additions and 47 deletions.
8 changes: 4 additions & 4 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -88,14 +88,14 @@ jobs:
- name: PHP Unit tests for PHP 7.1
run: vendor/bin/phpunit --verbose --coverage-clover=coverage.clover --exclude-group oci,wincache,xcache,zenddata,cubrid --colors=always
if: matrix.php == '7.1'
- name: PHP Unit tests for PHP 7.2 - 7.4
- name: PHP Unit tests for PHP >= 7.2
run: vendor/bin/phpunit --verbose --exclude-group $PHPUNIT_EXCLUDE_GROUP --colors=always
env:
PHPUNIT_EXCLUDE_GROUP: oci,wincache,xcache,zenddata,cubrid
if: matrix.php == '7.4' || matrix.php == '7.3' || matrix.php == '7.2'
- name: PHP Unit tests for PHP 5.4 - 7.0
if: matrix.php >= '7.2'
- name: PHP Unit tests for PHP <= 7.0
run: vendor/bin/phpunit --verbose --exclude-group $PHPUNIT_EXCLUDE_GROUP --colors=always
if: matrix.php == '7.0' || matrix.php == '5.6' || matrix.php == '5.5' || matrix.php == '5.4'
if: matrix.php <= '7.0'
- name: Code coverage
run: |
wget https://scrutinizer-ci.com/ocular.phar
Expand Down
5 changes: 3 additions & 2 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -115,10 +115,11 @@
"composer-exit-on-patch-failure": true,
"patches": {
"phpunit/phpunit-mock-objects": {
"Fix PHP 7 compatibility": "./tests/phpunit_mock_objects.patch"
"Fix PHP 7 and 8 compatibility": "./tests/phpunit_mock_objects.patch"
},
"phpunit/phpunit": {
"Fix PHP 7.2 compatibility": "./tests/phpunit_getopt.patch"
"Fix PHP 7 compatibility": "./tests/phpunit_php7.patch",
"Fix PHP 8 compatibility": "./tests/phpunit_php8.patch"
}
}
}
Expand Down
1 change: 1 addition & 0 deletions framework/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ Yii Framework 2 Change Log
- Bug #18287: Fix for OUTPUT INSERTED and computed columns. Added flag to computed values in table schema (darkdef)
- Bug #18308: Fixed `\yii\base\Model::getErrorSummary()` reverse order (DrDeath72)
- Bug #18313: Fix multipart form data parse with double quotes (wsaid)
- Bug #18317: Additional PHP 8 compatibility fixes (samdark, bizley)

2.0.38 September 14, 2020
-------------------------
Expand Down
14 changes: 7 additions & 7 deletions framework/base/ErrorException.php
Original file line number Diff line number Diff line change
Expand Up @@ -33,14 +33,14 @@ class ErrorException extends \ErrorException
/**
* Constructs the exception.
* @link https://secure.php.net/manual/en/errorexception.construct.php
* @param $message [optional]
* @param $code [optional]
* @param $severity [optional]
* @param $filename [optional]
* @param $lineno [optional]
* @param $previous [optional]
* @param string $message [optional]
* @param int $code [optional]
* @param int $severity [optional]
* @param string $filename [optional]
* @param int $lineno [optional]
* @param \Throwable|\Exception $previous [optional]
*/
public function __construct($message = '', $code = 0, $severity = 1, $filename = __FILE__, $lineno = __LINE__, \Exception $previous = null)
public function __construct($message = '', $code = 0, $severity = 1, $filename = __FILE__, $lineno = __LINE__, $previous = null)
{
parent::__construct($message, $code, $severity, $filename, $lineno, $previous);

Expand Down
4 changes: 2 additions & 2 deletions framework/base/ExitException.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,9 @@ class ExitException extends \Exception
* @param int $status the exit status code
* @param string $message error message
* @param int $code error code
* @param \Exception $previous The previous exception used for the exception chaining.
* @param \Throwable|\Exception $previous The previous exception used for the exception chaining.
*/
public function __construct($status = 0, $message = null, $code = 0, \Exception $previous = null)
public function __construct($status = 0, $message = null, $code = 0, $previous = null)
{
$this->statusCode = $status;
parent::__construct($message, $code, $previous);
Expand Down
8 changes: 7 additions & 1 deletion framework/console/Controller.php
Original file line number Diff line number Diff line change
Expand Up @@ -555,7 +555,13 @@ public function getActionArgsHelp($action)

/** @var \ReflectionParameter $reflection */
foreach ($method->getParameters() as $i => $reflection) {
if ($reflection->getClass() !== null) {
if (PHP_VERSION_ID >= 80000) {
$class = $reflection->getType();
} else {
$class = $reflection->getClass();
}

if ($class !== null) {
continue;
}
$name = $reflection->getName();
Expand Down
6 changes: 6 additions & 0 deletions framework/db/Command.php
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,9 @@ public function prepare($forRead = null)
}

$sql = $this->getSql();
if ($sql === '') {
return;
}

if ($this->db->getTransaction()) {
// master is in a transaction. use the same connection.
Expand All @@ -264,6 +267,9 @@ public function prepare($forRead = null)
$message = $e->getMessage() . "\nFailed to prepare SQL: $sql";
$errorInfo = $e instanceof \PDOException ? $e->errorInfo : null;
throw new Exception($message, $errorInfo, (int) $e->getCode(), $e);
} catch (\Throwable $e) {
$message = $e->getMessage() . "\nFailed to prepare SQL: $sql";
throw new Exception($message, null, (int) $e->getCode(), $e);
}
}

Expand Down
4 changes: 2 additions & 2 deletions framework/db/Exception.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,9 @@ class Exception extends \yii\base\Exception
* @param string $message PDO error message
* @param array $errorInfo PDO error info
* @param string $code PDO error code
* @param \Exception $previous The previous exception used for the exception chaining.
* @param \Throwable|\Exception $previous The previous exception used for the exception chaining.
*/
public function __construct($message, $errorInfo = [], $code = '', \Exception $previous = null)
public function __construct($message, $errorInfo = [], $code = '', $previous = null)
{
parent::__construct($message, 0, $previous);
$this->errorInfo = $errorInfo;
Expand Down
27 changes: 21 additions & 6 deletions framework/di/Container.php
Original file line number Diff line number Diff line change
Expand Up @@ -458,17 +458,21 @@ protected function getDependencies($class)
$constructor = $reflection->getConstructor();
if ($constructor !== null) {
foreach ($constructor->getParameters() as $param) {
if (version_compare(PHP_VERSION, '5.6.0', '>=') && $param->isVariadic()) {
if (PHP_VERSION_ID >= 50600 && $param->isVariadic()) {
break;
} elseif ($param->isDefaultValueAvailable()) {
}

if ($param->isDefaultValueAvailable()) {
$dependencies[] = $param->getDefaultValue();
} else {
if (PHP_VERSION_ID >= 80000) {
$c = $param->getType();
$isClass = $c !== null && !$param->getType()->isBuiltin();
} else {
$c = $param->getClass();
$isClass = $c !== null;
}
$dependencies[] = Instance::of($c === null ? null : $c->getName());
$dependencies[] = Instance::of($isClass ? $c->getName() : null);
}
}
}
Expand Down Expand Up @@ -565,12 +569,23 @@ public function resolveCallableDependencies(callable $callback, $params = [])

foreach ($reflection->getParameters() as $param) {
$name = $param->getName();
if (($class = $param->getClass()) !== null) {

if (PHP_VERSION_ID >= 80000) {
$class = $param->getType();
$isClass = $class !== null && !$param->getType()->isBuiltin();
} else {
$class = $param->getClass();
$isClass = $class !== null;
}

if ($isClass) {
$className = $class->getName();
if (version_compare(PHP_VERSION, '5.6.0', '>=') && $param->isVariadic()) {
if (PHP_VERSION_ID >= 50600 && $param->isVariadic()) {
$args = array_merge($args, array_values($params));
break;
} elseif ($associative && isset($params[$name]) && $params[$name] instanceof $className) {
}

if ($associative && isset($params[$name]) && $params[$name] instanceof $className) {
$args[] = $params[$name];
unset($params[$name]);
} elseif (!$associative && isset($params[0]) && $params[0] instanceof $className) {
Expand Down
4 changes: 2 additions & 2 deletions tests/data/validators/models/FakedValidationModel.php
Original file line number Diff line number Diff line change
Expand Up @@ -44,14 +44,14 @@ public function rules()
];
}

public function inlineVal($attribute, $params = [], $validator, $current)
public function inlineVal($attribute, $params, $validator, $current)
{
$this->inlineValArgs = \func_get_args();

return true;
}

public function clientInlineVal($attribute, $params = [], $validator, $current)
public function clientInlineVal($attribute, $params, $validator, $current)
{
return \func_get_args();
}
Expand Down
12 changes: 6 additions & 6 deletions tests/framework/db/ActiveRecordTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -1893,24 +1893,24 @@ public function testLegalValuesForFindByCondition($modelClassName, $validFilter)
public function illegalValuesForFindByCondition()
{
return [
[Customer::className(), ['id' => ['`id`=`id` and 1' => 1]]],
[Customer::className(), ['id' => [
[Customer::className(), [['`id`=`id` and 1' => 1]]],
[Customer::className(), [[
'legal' => 1,
'`id`=`id` and 1' => 1,
]]],
[Customer::className(), ['id' => [
[Customer::className(), [[
'nested_illegal' => [
'false or 1=' => 1
]
]]],
[Customer::className(), [['true--' => 1]]],

[CustomerWithAlias::className(), ['csr.id' => ['`csr`.`id`=`csr`.`id` and 1' => 1]]],
[CustomerWithAlias::className(), ['csr.id' => [
[CustomerWithAlias::className(), [['`csr`.`id`=`csr`.`id` and 1' => 1]]],
[CustomerWithAlias::className(), [[
'legal' => 1,
'`csr`.`id`=`csr`.`id` and 1' => 1,
]]],
[CustomerWithAlias::className(), ['csr.id' => [
[CustomerWithAlias::className(), [[
'nested_illegal' => [
'false or 1=' => 1
]
Expand Down
15 changes: 3 additions & 12 deletions tests/framework/filters/RateLimiterTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,12 @@

namespace yiiunit\framework\filters;

use Prophecy\Argument;
use Yii;
use yii\filters\RateLimiter;
use yii\log\Logger;
use yii\web\Request;
use yii\web\Response;
use yii\web\User;
use yiiunit\framework\filters\stubs\ExposedLogger;
use yiiunit\framework\filters\stubs\RateLimit;
use yiiunit\framework\filters\stubs\UserIdentity;
use yiiunit\TestCase;
Expand All @@ -27,15 +26,7 @@ protected function setUp()
{
parent::setUp();

/* @var $logger Logger|\Prophecy\ObjectProphecy */
$logger = $this->prophesize(Logger::className());
$logger
->log(Argument::any(), Argument::any(), Argument::any())
->will(function ($parameters, $logger) {
$logger->messages = $parameters;
});

Yii::setLogger($logger->reveal());
Yii::setLogger(new ExposedLogger());

$this->mockWebApplication();
}
Expand Down Expand Up @@ -170,7 +161,7 @@ public function testUserWithClosureFunction()
};
$rateLimiter->beforeAction('test');

// testing the evaluation of user closure, which in this case returns not the expect object and therefore
// testing the evaluation of user closure, which in this case returns not the expect object and therefore
// the log message "does not implement RateLimitInterface" is expected.
$this->assertInstanceOf(User::className(), $rateLimiter->user);
$this->assertContains('Rate limit skipped: "user" does not implement RateLimitInterface.', Yii::getLogger()->messages);
Expand Down
19 changes: 19 additions & 0 deletions tests/framework/filters/stubs/ExposedLogger.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<?php
/**
* @link http://www.yiiframework.com/
* @copyright Copyright (c) 2008 Yii Software LLC
* @license http://www.yiiframework.com/license/
*/

namespace yiiunit\framework\filters\stubs;


use yii\log\Logger;

class ExposedLogger extends Logger
{
public function log($message, $level, $category = 'application')
{
$this->messages[] = $message;
}
}
30 changes: 27 additions & 3 deletions tests/phpunit_mock_objects.patch
Original file line number Diff line number Diff line change
@@ -1,14 +1,38 @@
diff --git a/src/Framework/MockObject/Generator.php b/src/Framework/MockObject/Generator.php
index 3df3abb..8407182 100644
index 3df3abb..fc76d5d 100644
--- a/src/Framework/MockObject/Generator.php
+++ b/src/Framework/MockObject/Generator.php
@@ -1032,7 +1032,8 @@ protected function getMethodParameters(ReflectionMethod $method, $forCall = fals
@@ -1031,16 +1031,29 @@ protected function getMethodParameters(ReflectionMethod $method, $forCall = fals
$typeDeclaration = '';

if (!$forCall) {
+ if (PHP_VERSION_ID >= 80000) {
+ $isArray = $parameter->getType() && $parameter->getType()->getName() === 'array';
+ $isCallable = $parameter->getType() && $parameter->getType()->getName() === 'callable';
+ } else {
+ $isArray = $parameter->isArray();
+ $isCallable = version_compare(PHP_VERSION, '5.4.0', '>=') ? $parameter->isCallable() : false;
+ }
+
if ($this->hasType($parameter)) {
- $typeDeclaration = (string) $parameter->getType() . ' ';
- } elseif ($parameter->isArray()) {
+ $type = $parameter->getType();
+ $typeDeclaration = (PHP_VERSION_ID >= 70100 ? $type->getName() : (string) $type) . ' ';
} elseif ($parameter->isArray()) {
+ } elseif ($isArray) {
$typeDeclaration = 'array ';
} elseif ((defined('HHVM_VERSION') || version_compare(PHP_VERSION, '5.4.0', '>='))
- && $parameter->isCallable()) {
+ && $isCallable) {
$typeDeclaration = 'callable ';
} else {
try {
- $class = $parameter->getClass();
+ if (PHP_VERSION_ID >= 80000) {
+ $class = $parameter->getType();
+ } else {
+ $class = $parameter->getClass();
+ }
} catch (ReflectionException $e) {
throw new PHPUnit_Framework_MockObject_RuntimeException(
sprintf(
File renamed without changes.
39 changes: 39 additions & 0 deletions tests/phpunit_php8.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
diff --git a/src/Framework/TestCase.php b/src/Framework/TestCase.php
index 638f42513..b4c7d3a5e 100644
--- a/src/Framework/TestCase.php
+++ b/src/Framework/TestCase.php
@@ -905,7 +905,7 @@ protected function runTest()
try {
$testResult = $method->invokeArgs(
$this,
- array_merge($this->data, $this->dependencyInput)
+ array_values(array_merge($this->data, $this->dependencyInput))
);
} catch (Throwable $_e) {
$e = $_e;
diff --git a/src/Util/Configuration.php b/src/Util/Configuration.php
index 5c1041608..b2f7a7bd0 100644
--- a/src/Util/Configuration.php
+++ b/src/Util/Configuration.php
@@ -162,7 +162,7 @@ protected function __construct($filename)
/**
* @since Method available since Release 3.4.0
*/
- final private function __clone()
+ private function __clone()
{
}

diff --git a/src/Util/PHP/Template/TestCaseMethod.tpl.dist b/src/Util/PHP/Template/TestCaseMethod.tpl.dist
index b48f354cd..d59cdeea7 100644
--- a/src/Util/PHP/Template/TestCaseMethod.tpl.dist
+++ b/src/Util/PHP/Template/TestCaseMethod.tpl.dist
@@ -78,7 +78,7 @@ if ('' !== $configurationFilePath) {
unset($configuration);
}

-function __phpunit_error_handler($errno, $errstr, $errfile, $errline, $errcontext)
+function __phpunit_error_handler($errno, $errstr, $errfile, $errline, $errcontext = null)
{
return true;
}

0 comments on commit ed1c087

Please sign in to comment.