diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index da9500c98394..af38873fe1ef 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -25,9 +25,9 @@ jobs: - 6379:6379 options: --entrypoint redis-server strategy: - fail-fast: true + fail-fast: false matrix: - php: [7.2, 7.3, 7.4] + php: [7.2, 7.3, 7.4, 8.0] stability: [prefer-lowest, prefer-stable] name: PHP ${{ matrix.php }} - ${{ matrix.stability }} @@ -47,8 +47,32 @@ jobs: - name: Setup Memcached uses: niden/actions-memcached@v7 - - name: Install dependencies - run: composer update --${{ matrix.stability }} --prefer-dist --no-interaction --no-progress + - name: Setup problem matchers + run: echo "::add-matcher::${{ runner.tool_cache }}/phpunit.json" + + - name: Install PHP 7 dependencies + uses: nick-invision/retry@v1 + with: + timeout_minutes: 5 + max_attempts: 5 + command: composer update --prefer-dist --no-interaction --no-progress + if: "matrix.php < 8" + + - name: Setup PHP 8 Dependencies + uses: nick-invision/retry@v1 + with: + timeout_minutes: 5 + max_attempts: 5 + command: composer require "phpunit/phpunit:^9.3.2" "doctrine/dbal:^3.0" --no-update --no-interaction + if: "matrix.php >= 8" + + - name: Install PHP 8 Dependencies + uses: nick-invision/retry@v1 + with: + timeout_minutes: 5 + max_attempts: 5 + command: composer update --${{ matrix.stability }} --prefer-dist --no-interaction --no-progress --ignore-platform-req=php + if: "matrix.php >= 8" - name: Execute tests run: vendor/bin/phpunit --verbose @@ -60,9 +84,9 @@ jobs: runs-on: windows-latest strategy: - fail-fast: true + fail-fast: false matrix: - php: [7.2, 7.3, 7.4] + php: [7.2, 7.3, 7.4, 8.0] include: - php: 7.2 stability: prefer-lowest @@ -70,6 +94,8 @@ jobs: stability: prefer-stable - php: 7.4 stability: prefer-stable + - php: 8.0 + stability: prefer-stable name: PHP ${{ matrix.php }} - ${{ matrix.stability }} - Windows @@ -89,10 +115,33 @@ jobs: extensions: dom, curl, libxml, mbstring, zip, pdo, sqlite, pdo_sqlite, gd, pdo_mysql, fileinfo, ftp tools: composer:v2 coverage: none - ini-values: memory_limit=512M - - name: Install dependencies - run: composer update --${{ matrix.stability }} --prefer-dist --no-interaction --no-progress + - name: Setup problem matchers + run: echo "::add-matcher::${{ runner.tool_cache }}/phpunit.json" + + - name: Install PHP 7 Dependencies + uses: nick-invision/retry@v1 + with: + timeout_minutes: 5 + max_attempts: 5 + command: composer update --prefer-dist --no-interaction --no-progress + if: "matrix.php < 8" + + - name: Setup PHP 8 Dependencies + uses: nick-invision/retry@v1 + with: + timeout_minutes: 5 + max_attempts: 5 + command: composer require "phpunit/phpunit:^9.3.2" "doctrine/dbal:^3.0" --no-update --no-interaction + if: "matrix.php >= 8" + + - name: Install PHP 8 Dependencies + uses: nick-invision/retry@v1 + with: + timeout_minutes: 5 + max_attempts: 5 + command: composer update --${{ matrix.stability }} --prefer-dist --no-interaction --no-progress --ignore-platform-req=php + if: "matrix.php >= 8" - name: Execute tests run: vendor/bin/phpunit --verbose diff --git a/composer.json b/composer.json index 5f09147f5675..c4f4b480e331 100644 --- a/composer.json +++ b/composer.json @@ -15,7 +15,7 @@ } ], "require": { - "php": "^7.2", + "php": "^7.2|^8.0", "ext-json": "*", "ext-mbstring": "*", "ext-openssl": "*", @@ -23,9 +23,9 @@ "dragonmantank/cron-expression": "^2.0", "egulias/email-validator": "^2.1.10", "league/commonmark": "^1.3", - "league/flysystem": "^1.0.34", + "league/flysystem": "^1.1", "monolog/monolog": "^1.12|^2.0", - "nesbot/carbon": "^2.0", + "nesbot/carbon": "^2.31", "opis/closure": "^3.1", "psr/container": "^1.0", "psr/simple-cache": "^1.0", @@ -78,15 +78,15 @@ }, "require-dev": { "aws/aws-sdk-php": "^3.0", - "doctrine/dbal": "^2.6", + "doctrine/dbal": "^2.6|^3.0", "filp/whoops": "^2.4", "guzzlehttp/guzzle": "^6.3|^7.0", "league/flysystem-cached-adapter": "^1.0", - "mockery/mockery": "^1.3.1", + "mockery/mockery": "~1.3.3|^1.4.2", "moontoast/math": "^1.1", "orchestra/testbench-core": "^4.0", "pda/pheanstalk": "^4.0", - "phpunit/phpunit": "^7.5.15|^8.4|^9.0", + "phpunit/phpunit": "^7.5.15|^8.4|^9.3", "predis/predis": "^1.1.1", "symfony/cache": "^4.3.4" }, @@ -120,7 +120,7 @@ "ext-posix": "Required to use all features of the queue worker.", "ext-redis": "Required to use the Redis cache and queue drivers (^4.0|^5.0).", "aws/aws-sdk-php": "Required to use the SQS queue driver, DynamoDb failed job storage and SES mail driver (^3.0).", - "doctrine/dbal": "Required to rename columns and drop SQLite columns (^2.6).", + "doctrine/dbal": "Required to rename columns and drop SQLite columns (^2.6|^3.0).", "filp/whoops": "Required for friendly error pages in development (^2.4).", "fzaninotto/faker": "Required to use the eloquent factory builder (^1.9.1).", "guzzlehttp/guzzle": "Required to use the Mailgun mail driver and the ping methods on schedules (^6.0|^7.0).", diff --git a/src/Illuminate/Auth/composer.json b/src/Illuminate/Auth/composer.json index 21ae73751ce9..cf15de456bed 100644 --- a/src/Illuminate/Auth/composer.json +++ b/src/Illuminate/Auth/composer.json @@ -14,7 +14,7 @@ } ], "require": { - "php": "^7.2", + "php": "^7.2|^8.0", "illuminate/contracts": "^6.0", "illuminate/http": "^6.0", "illuminate/queue": "^6.0", diff --git a/src/Illuminate/Broadcasting/composer.json b/src/Illuminate/Broadcasting/composer.json index cc050e135d73..8c82aa4e90de 100644 --- a/src/Illuminate/Broadcasting/composer.json +++ b/src/Illuminate/Broadcasting/composer.json @@ -14,7 +14,7 @@ } ], "require": { - "php": "^7.2", + "php": "^7.2|^8.0", "ext-json": "*", "psr/log": "^1.0", "illuminate/bus": "^6.0", diff --git a/src/Illuminate/Bus/composer.json b/src/Illuminate/Bus/composer.json index 63743abab856..2751d8923669 100644 --- a/src/Illuminate/Bus/composer.json +++ b/src/Illuminate/Bus/composer.json @@ -14,7 +14,7 @@ } ], "require": { - "php": "^7.2", + "php": "^7.2|^8.0", "illuminate/contracts": "^6.0", "illuminate/pipeline": "^6.0", "illuminate/support": "^6.0" diff --git a/src/Illuminate/Cache/RedisTaggedCache.php b/src/Illuminate/Cache/RedisTaggedCache.php index 208ae94661be..ad50ce9adb41 100644 --- a/src/Illuminate/Cache/RedisTaggedCache.php +++ b/src/Illuminate/Cache/RedisTaggedCache.php @@ -179,7 +179,7 @@ protected function deleteValues($referenceKey) if (count($values) > 0) { foreach (array_chunk($values, 1000) as $valuesChunk) { - call_user_func_array([$this->store->connection(), 'del'], $valuesChunk); + $this->store->connection()->del(...$valuesChunk); } } } diff --git a/src/Illuminate/Cache/composer.json b/src/Illuminate/Cache/composer.json index e69c406246ce..1599d78153f1 100755 --- a/src/Illuminate/Cache/composer.json +++ b/src/Illuminate/Cache/composer.json @@ -14,7 +14,7 @@ } ], "require": { - "php": "^7.2", + "php": "^7.2|^8.0", "illuminate/contracts": "^6.0", "illuminate/support": "^6.0" }, diff --git a/src/Illuminate/Config/composer.json b/src/Illuminate/Config/composer.json index 55e8a4035ad9..2356cbabb1b2 100755 --- a/src/Illuminate/Config/composer.json +++ b/src/Illuminate/Config/composer.json @@ -14,7 +14,7 @@ } ], "require": { - "php": "^7.2", + "php": "^7.2|^8.0", "illuminate/contracts": "^6.0", "illuminate/support": "^6.0" }, diff --git a/src/Illuminate/Console/Concerns/HasParameters.php b/src/Illuminate/Console/Concerns/HasParameters.php index 3f6f9c7642cf..e860ec2a2ec5 100644 --- a/src/Illuminate/Console/Concerns/HasParameters.php +++ b/src/Illuminate/Console/Concerns/HasParameters.php @@ -21,7 +21,7 @@ protected function specifyParameters() if ($arguments instanceof InputArgument) { $this->getDefinition()->addArgument($arguments); } else { - call_user_func_array([$this, 'addArgument'], $arguments); + $this->addArgument(...array_values($arguments)); } } @@ -29,7 +29,7 @@ protected function specifyParameters() if ($options instanceof InputOption) { $this->getDefinition()->addOption($options); } else { - call_user_func_array([$this, 'addOption'], $options); + $this->addOption(...array_values($options)); } } } diff --git a/src/Illuminate/Console/composer.json b/src/Illuminate/Console/composer.json index 55f104571a7f..51a5a71351b9 100755 --- a/src/Illuminate/Console/composer.json +++ b/src/Illuminate/Console/composer.json @@ -14,7 +14,7 @@ } ], "require": { - "php": "^7.2", + "php": "^7.2|^8.0", "illuminate/contracts": "^6.0", "illuminate/support": "^6.0", "symfony/console": "^4.3.4", diff --git a/src/Illuminate/Container/BoundMethod.php b/src/Illuminate/Container/BoundMethod.php index 8b53f71a331d..0afbd104c3c1 100644 --- a/src/Illuminate/Container/BoundMethod.php +++ b/src/Illuminate/Container/BoundMethod.php @@ -28,9 +28,7 @@ public static function call($container, $callback, array $parameters = [], $defa } return static::callBoundMethod($container, $callback, function () use ($container, $callback, $parameters) { - return call_user_func_array( - $callback, static::getMethodDependencies($container, $callback, $parameters) - ); + return $callback(...static::getMethodDependencies($container, $callback, $parameters)); }); } @@ -121,7 +119,7 @@ protected static function getMethodDependencies($container, $callback, array $pa static::addDependencyForCallParameter($container, $parameter, $parameters, $dependencies); } - return array_merge($dependencies, $parameters); + return array_merge($dependencies, array_values($parameters)); } /** diff --git a/src/Illuminate/Container/composer.json b/src/Illuminate/Container/composer.json index 76da2163481f..5e78e465fa18 100755 --- a/src/Illuminate/Container/composer.json +++ b/src/Illuminate/Container/composer.json @@ -14,7 +14,7 @@ } ], "require": { - "php": "^7.2", + "php": "^7.2|^8.0", "illuminate/contracts": "^6.0", "psr/container": "^1.0" }, diff --git a/src/Illuminate/Contracts/composer.json b/src/Illuminate/Contracts/composer.json index fee8ed4d078b..d7f41e433a70 100644 --- a/src/Illuminate/Contracts/composer.json +++ b/src/Illuminate/Contracts/composer.json @@ -14,7 +14,7 @@ } ], "require": { - "php": "^7.2", + "php": "^7.2|^8.0", "psr/container": "^1.0", "psr/simple-cache": "^1.0" }, diff --git a/src/Illuminate/Cookie/CookieJar.php b/src/Illuminate/Cookie/CookieJar.php index a880e898eb43..337435a74688 100755 --- a/src/Illuminate/Cookie/CookieJar.php +++ b/src/Illuminate/Cookie/CookieJar.php @@ -143,7 +143,7 @@ public function queue(...$parameters) if (head($parameters) instanceof Cookie) { $cookie = head($parameters); } else { - $cookie = call_user_func_array([$this, 'make'], $parameters); + $cookie = $this->make(...array_values($parameters)); } if (! isset($this->queued[$cookie->getName()])) { diff --git a/src/Illuminate/Cookie/composer.json b/src/Illuminate/Cookie/composer.json index 1517a2b1938a..bb0a6e247588 100755 --- a/src/Illuminate/Cookie/composer.json +++ b/src/Illuminate/Cookie/composer.json @@ -14,7 +14,7 @@ } ], "require": { - "php": "^7.2", + "php": "^7.2|^8.0", "illuminate/contracts": "^6.0", "illuminate/support": "^6.0", "symfony/http-foundation": "^4.3.4", diff --git a/src/Illuminate/Database/Connection.php b/src/Illuminate/Database/Connection.php index 7c688fdbe5a2..af5803354957 100755 --- a/src/Illuminate/Database/Connection.php +++ b/src/Illuminate/Database/Connection.php @@ -889,7 +889,14 @@ public function getDoctrineColumn($table, $column) */ public function getDoctrineSchemaManager() { - return $this->getDoctrineDriver()->getSchemaManager($this->getDoctrineConnection()); + $connection = $this->getDoctrineConnection(); + + // v2 expects only one param, and v3 two. We don't need to care about + // this, and can always pass them both. In v2, the 2nd is ignored. + return $this->getDoctrineDriver()->getSchemaManager( + $connection, + $connection->getDatabasePlatform() + ); } /** @@ -905,7 +912,7 @@ public function getDoctrineConnection() $this->doctrineConnection = new DoctrineConnection(array_filter([ 'pdo' => $this->getPdo(), 'dbname' => $this->getDatabaseName(), - 'driver' => $driver->getName(), + 'driver' => method_exists($driver, 'getName') ? $driver->getName() : null, 'serverVersion' => $this->getConfig('server_version'), ]), $driver); } diff --git a/src/Illuminate/Database/Eloquent/Builder.php b/src/Illuminate/Database/Eloquent/Builder.php index 00131c80054f..9c2288fac202 100755 --- a/src/Illuminate/Database/Eloquent/Builder.php +++ b/src/Illuminate/Database/Eloquent/Builder.php @@ -1351,14 +1351,16 @@ public function __call($method, $parameters) } if (static::hasGlobalMacro($method)) { - if (static::$macros[$method] instanceof Closure) { - return call_user_func_array(static::$macros[$method]->bindTo($this, static::class), $parameters); + $callable = static::$macros[$method]; + + if ($callable instanceof Closure) { + $callable = $callable->bindTo($this, static::class); } - return call_user_func_array(static::$macros[$method], $parameters); + return $callable(...$parameters); } - if (method_exists($this->model, $scope = 'scope'.ucfirst($method))) { + if ($this->model !== null && method_exists($this->model, $scope = 'scope'.ucfirst($method))) { return $this->callScope([$this->model, $scope], $parameters); } @@ -1396,11 +1398,13 @@ public static function __callStatic($method, $parameters) static::throwBadMethodCallException($method); } - if (static::$macros[$method] instanceof Closure) { - return call_user_func_array(Closure::bind(static::$macros[$method], null, static::class), $parameters); + $callable = static::$macros[$method]; + + if ($callable instanceof Closure) { + $callable = $callable->bindTo(null, static::class); } - return call_user_func_array(static::$macros[$method], $parameters); + return $callable(...$parameters); } /** diff --git a/src/Illuminate/Database/Eloquent/Collection.php b/src/Illuminate/Database/Eloquent/Collection.php index c4e8d9f1778c..6705232d9924 100755 --- a/src/Illuminate/Database/Eloquent/Collection.php +++ b/src/Illuminate/Database/Eloquent/Collection.php @@ -451,7 +451,7 @@ public function keys() */ public function zip($items) { - return call_user_func_array([$this->toBase(), 'zip'], func_get_args()); + return $this->toBase()->zip(...func_get_args()); } /** diff --git a/src/Illuminate/Database/Eloquent/Relations/Concerns/InteractsWithPivotTable.php b/src/Illuminate/Database/Eloquent/Relations/Concerns/InteractsWithPivotTable.php index 4894103d202a..c6812b75a150 100644 --- a/src/Illuminate/Database/Eloquent/Relations/Concerns/InteractsWithPivotTable.php +++ b/src/Illuminate/Database/Eloquent/Relations/Concerns/InteractsWithPivotTable.php @@ -537,11 +537,11 @@ public function newPivotQuery() $query = $this->newPivotStatement(); foreach ($this->pivotWheres as $arguments) { - call_user_func_array([$query, 'where'], $arguments); + $query->where(...$arguments); } foreach ($this->pivotWhereIns as $arguments) { - call_user_func_array([$query, 'whereIn'], $arguments); + $query->whereIn(...$arguments); } return $query->where($this->foreignPivotKey, $this->parent->{$this->parentKey}); diff --git a/src/Illuminate/Database/MigrationServiceProvider.php b/src/Illuminate/Database/MigrationServiceProvider.php index f9bded758358..efd5f836c866 100755 --- a/src/Illuminate/Database/MigrationServiceProvider.php +++ b/src/Illuminate/Database/MigrationServiceProvider.php @@ -102,7 +102,7 @@ protected function registerCreator() protected function registerCommands(array $commands) { foreach (array_keys($commands) as $command) { - call_user_func_array([$this, "register{$command}Command"], []); + $this->{"register{$command}Command"}(); } $this->commands(array_values($commands)); diff --git a/src/Illuminate/Database/MySqlConnection.php b/src/Illuminate/Database/MySqlConnection.php index 94b5b57d87e0..b53a9091ec0e 100755 --- a/src/Illuminate/Database/MySqlConnection.php +++ b/src/Illuminate/Database/MySqlConnection.php @@ -3,6 +3,8 @@ namespace Illuminate\Database; use Doctrine\DBAL\Driver\PDOMySql\Driver as DoctrineDriver; +use Doctrine\DBAL\Version; +use Illuminate\Database\PDO\MySqlDriver; use Illuminate\Database\Query\Grammars\MySqlGrammar as QueryGrammar; use Illuminate\Database\Query\Processors\MySqlProcessor; use Illuminate\Database\Schema\Grammars\MySqlGrammar as SchemaGrammar; @@ -57,10 +59,10 @@ protected function getDefaultPostProcessor() /** * Get the Doctrine DBAL driver. * - * @return \Doctrine\DBAL\Driver\PDOMySql\Driver + * @return \Doctrine\DBAL\Driver\PDOMySql\Driver|\Illuminate\Database\PDO\MySqlDriver */ protected function getDoctrineDriver() { - return new DoctrineDriver; + return class_exists(Version::class) ? new DoctrineDriver : new MySqlDriver; } } diff --git a/src/Illuminate/Database/PDO/Connection.php b/src/Illuminate/Database/PDO/Connection.php new file mode 100644 index 000000000000..c5e7e8fb32a6 --- /dev/null +++ b/src/Illuminate/Database/PDO/Connection.php @@ -0,0 +1,117 @@ +connection = $connection; + } + + public function exec(string $statement): int + { + try { + $result = $this->connection->exec($statement); + + \assert($result !== false); + + return $result; + } catch (PDOException $exception) { + throw Exception::new($exception); + } + } + + public function getServerVersion() + { + return $this->connection->getAttribute(PDO::ATTR_SERVER_VERSION); + } + + public function prepare(string $sql): StatementInterface + { + try { + return $this->createStatement( + $this->connection->prepare($sql) + ); + } catch (PDOException $exception) { + throw Exception::new($exception); + } + } + + public function query(string $sql): ResultInterface + { + try { + $stmt = $this->connection->query($sql); + \assert($stmt instanceof PDOStatement); + + return new Result($stmt); + } catch (PDOException $exception) { + throw Exception::new($exception); + } + } + + public function quote($input, $type = ParameterType::STRING) + { + return $this->connection->quote($input, $type); + } + + public function lastInsertId($name = null) + { + try { + if ($name === null) { + return $this->connection->lastInsertId(); + } + + return $this->connection->lastInsertId($name); + } catch (PDOException $exception) { + throw Exception::new($exception); + } + } + + protected function createStatement(PDOStatement $stmt): Statement + { + return new Statement($stmt); + } + + public function beginTransaction() + { + return $this->connection->beginTransaction(); + } + + public function commit() + { + return $this->connection->commit(); + } + + public function rollBack() + { + return $this->connection->rollBack(); + } + + public function getWrappedConnection(): PDO + { + return $this->connection; + } +} diff --git a/src/Illuminate/Database/PDO/MySqlDriver.php b/src/Illuminate/Database/PDO/MySqlDriver.php new file mode 100644 index 000000000000..e568ba2d2f41 --- /dev/null +++ b/src/Illuminate/Database/PDO/MySqlDriver.php @@ -0,0 +1,18 @@ +connection = $connection; + } + + public function prepare(string $sql): StatementInterface + { + return new Statement( + $this->connection->prepare($sql) + ); + } + + public function query(string $sql): Result + { + return $this->connection->query($sql); + } + + public function quote($value, $type = ParameterType::STRING) + { + $val = $this->connection->quote($value, $type); + + // Fix for a driver version terminating all values with null byte + if (\is_string($val) && \strpos($val, "\0") !== false) { + $val = \substr($val, 0, -1); + } + + return $val; + } + + public function exec(string $statement): int + { + return $this->connection->exec($statement); + } + + public function lastInsertId($name = null) + { + if ($name === null) { + return $this->connection->lastInsertId($name); + } + + return $this->prepare('SELECT CONVERT(VARCHAR(MAX), current_value) FROM sys.sequences WHERE name = ?') + ->execute([$name]) + ->fetchOne(); + } + + public function beginTransaction() + { + return $this->connection->beginTransaction(); + } + + public function commit() + { + return $this->connection->commit(); + } + + public function rollBack() + { + return $this->connection->rollBack(); + } + + public function getServerVersion() + { + return $this->connection->getServerVersion(); + } + + public function getWrappedConnection(): PDO + { + return $this->connection->getWrappedConnection(); + } +} diff --git a/src/Illuminate/Database/PDO/SqlServerDriver.php b/src/Illuminate/Database/PDO/SqlServerDriver.php new file mode 100644 index 000000000000..47bead97bb8d --- /dev/null +++ b/src/Illuminate/Database/PDO/SqlServerDriver.php @@ -0,0 +1,15 @@ +renamedColumns = [ - $command->from => new Column($command->to, $column->getType(), $column->toArray()), + $command->from => new Column($command->to, $column->getType(), self::getWritableColumnOptions($column)), ]; return $tableDiff; } + + /** + * Get the writable column options. + * + * @param \Doctrine\DBAL\Schema\Column $column + * @return array + */ + private static function getWritableColumnOptions(Column $column) + { + return array_filter($column->toArray(), function (string $name) use ($column) { + return method_exists($column, 'set'.$name); + }, ARRAY_FILTER_USE_KEY); + } } diff --git a/src/Illuminate/Database/SqlServerConnection.php b/src/Illuminate/Database/SqlServerConnection.php index 8a642572104f..6bb2f12818af 100755 --- a/src/Illuminate/Database/SqlServerConnection.php +++ b/src/Illuminate/Database/SqlServerConnection.php @@ -4,7 +4,9 @@ use Closure; use Doctrine\DBAL\Driver\PDOSqlsrv\Driver as DoctrineDriver; +use Doctrine\DBAL\Version; use Exception; +use Illuminate\Database\PDO\SqlServerDriver; use Illuminate\Database\Query\Grammars\SqlServerGrammar as QueryGrammar; use Illuminate\Database\Query\Processors\SqlServerProcessor; use Illuminate\Database\Schema\Grammars\SqlServerGrammar as SchemaGrammar; @@ -104,10 +106,10 @@ protected function getDefaultPostProcessor() /** * Get the Doctrine DBAL driver. * - * @return \Doctrine\DBAL\Driver\PDOSqlsrv\Driver + * @return \Doctrine\DBAL\Driver\PDOSqlsrv\Driver|\Illuminate\Database\PDO\SqlServerDriver */ protected function getDoctrineDriver() { - return new DoctrineDriver; + return class_exists(Version::class) ? new DoctrineDriver : new SqlServerDriver; } } diff --git a/src/Illuminate/Database/composer.json b/src/Illuminate/Database/composer.json index f407ca6c22d3..b6f5c0c7e090 100644 --- a/src/Illuminate/Database/composer.json +++ b/src/Illuminate/Database/composer.json @@ -15,7 +15,7 @@ } ], "require": { - "php": "^7.2", + "php": "^7.2|^8.0", "ext-json": "*", "illuminate/container": "^6.0", "illuminate/contracts": "^6.0", @@ -32,7 +32,7 @@ } }, "suggest": { - "doctrine/dbal": "Required to rename columns and drop SQLite columns (^2.6).", + "doctrine/dbal": "Required to rename columns and drop SQLite columns (^2.6|^3.0).", "fzaninotto/faker": "Required to use the eloquent factory builder (^1.9.1).", "illuminate/console": "Required to use the database commands (^6.0).", "illuminate/events": "Required to use the observers with Eloquent (^6.0).", diff --git a/src/Illuminate/Encryption/composer.json b/src/Illuminate/Encryption/composer.json index 5f535b4004b2..5a096a9c7a8e 100644 --- a/src/Illuminate/Encryption/composer.json +++ b/src/Illuminate/Encryption/composer.json @@ -14,7 +14,7 @@ } ], "require": { - "php": "^7.2", + "php": "^7.2|^8.0", "ext-json": "*", "ext-mbstring": "*", "ext-openssl": "*", diff --git a/src/Illuminate/Events/CallQueuedListener.php b/src/Illuminate/Events/CallQueuedListener.php index 5a88df56f8b4..c7fc821de584 100644 --- a/src/Illuminate/Events/CallQueuedListener.php +++ b/src/Illuminate/Events/CallQueuedListener.php @@ -89,17 +89,15 @@ public function handle(Container $container) $this->job, $container->make($this->class) ); - call_user_func_array( - [$handler, $this->method], $this->data - ); + $handler->{$this->method}(...array_values($this->data)); } /** * Set the job instance of the given class if necessary. * * @param \Illuminate\Contracts\Queue\Job $job - * @param mixed $instance - * @return mixed + * @param object $instance + * @return object */ protected function setJobInstanceIfNecessary(Job $job, $instance) { @@ -124,10 +122,10 @@ public function failed($e) $handler = Container::getInstance()->make($this->class); - $parameters = array_merge($this->data, [$e]); + $parameters = array_merge(array_values($this->data), [$e]); if (method_exists($handler, 'failed')) { - call_user_func_array([$handler, 'failed'], $parameters); + $handler->failed(...$parameters); } } diff --git a/src/Illuminate/Events/Dispatcher.php b/src/Illuminate/Events/Dispatcher.php index 21dc14ab9e88..0d0173e3cbb9 100755 --- a/src/Illuminate/Events/Dispatcher.php +++ b/src/Illuminate/Events/Dispatcher.php @@ -384,9 +384,9 @@ public function createClassListener($listener, $wildcard = false) return call_user_func($this->createClassCallable($listener), $event, $payload); } - return call_user_func_array( - $this->createClassCallable($listener), $payload - ); + $callable = $this->createClassCallable($listener); + + return $callable(...array_values($payload)); }; } diff --git a/src/Illuminate/Events/composer.json b/src/Illuminate/Events/composer.json index 639083026959..5b303a5fbff4 100755 --- a/src/Illuminate/Events/composer.json +++ b/src/Illuminate/Events/composer.json @@ -14,7 +14,7 @@ } ], "require": { - "php": "^7.2", + "php": "^7.2|^8.0", "illuminate/container": "^6.0", "illuminate/contracts": "^6.0", "illuminate/support": "^6.0" diff --git a/src/Illuminate/Filesystem/FilesystemAdapter.php b/src/Illuminate/Filesystem/FilesystemAdapter.php index d3d62194b251..e4b917c0d405 100644 --- a/src/Illuminate/Filesystem/FilesystemAdapter.php +++ b/src/Illuminate/Filesystem/FilesystemAdapter.php @@ -739,6 +739,6 @@ protected function parseVisibility($visibility) */ public function __call($method, array $parameters) { - return call_user_func_array([$this->driver, $method], $parameters); + return $this->driver->{$method}(...array_values($parameters)); } } diff --git a/src/Illuminate/Filesystem/composer.json b/src/Illuminate/Filesystem/composer.json index 010622d88b80..f018147e355f 100644 --- a/src/Illuminate/Filesystem/composer.json +++ b/src/Illuminate/Filesystem/composer.json @@ -14,7 +14,7 @@ } ], "require": { - "php": "^7.2", + "php": "^7.2|^8.0", "illuminate/contracts": "^6.0", "illuminate/support": "^6.0", "symfony/finder": "^4.3.4" @@ -31,7 +31,7 @@ }, "suggest": { "ext-ftp": "Required to use the Flysystem FTP driver.", - "league/flysystem": "Required to use the Flysystem local and FTP drivers (^1.0.34).", + "league/flysystem": "Required to use the Flysystem local and FTP drivers (^1.1).", "league/flysystem-aws-s3-v3": "Required to use the Flysystem S3 driver (^1.0).", "league/flysystem-cached-adapter": "Required to use the Flysystem cache (^1.0).", "league/flysystem-sftp": "Required to use the Flysystem SFTP driver (^1.0).", diff --git a/src/Illuminate/Foundation/Console/QueuedCommand.php b/src/Illuminate/Foundation/Console/QueuedCommand.php index 67749ee938dd..fb3d027b4b0a 100644 --- a/src/Illuminate/Foundation/Console/QueuedCommand.php +++ b/src/Illuminate/Foundation/Console/QueuedCommand.php @@ -37,6 +37,6 @@ public function __construct($data) */ public function handle(KernelContract $kernel) { - call_user_func_array([$kernel, 'call'], $this->data); + $kernel->call(...array_values($this->data)); } } diff --git a/src/Illuminate/Foundation/Providers/ArtisanServiceProvider.php b/src/Illuminate/Foundation/Providers/ArtisanServiceProvider.php index 66aeb5121141..7c33b8d5da91 100755 --- a/src/Illuminate/Foundation/Providers/ArtisanServiceProvider.php +++ b/src/Illuminate/Foundation/Providers/ArtisanServiceProvider.php @@ -168,7 +168,7 @@ public function register() protected function registerCommands(array $commands) { foreach (array_keys($commands) as $command) { - call_user_func_array([$this, "register{$command}Command"], []); + $this->{"register{$command}Command"}(); } $this->commands(array_values($commands)); diff --git a/src/Illuminate/Hashing/composer.json b/src/Illuminate/Hashing/composer.json index a728b6f7154b..e3bc6118a435 100755 --- a/src/Illuminate/Hashing/composer.json +++ b/src/Illuminate/Hashing/composer.json @@ -14,7 +14,7 @@ } ], "require": { - "php": "^7.2", + "php": "^7.2|^8.0", "illuminate/contracts": "^6.0", "illuminate/support": "^6.0" }, diff --git a/src/Illuminate/Http/ResponseTrait.php b/src/Illuminate/Http/ResponseTrait.php index 76744b487fb8..0858b40e2494 100644 --- a/src/Illuminate/Http/ResponseTrait.php +++ b/src/Illuminate/Http/ResponseTrait.php @@ -96,7 +96,7 @@ public function withHeaders($headers) */ public function cookie($cookie) { - return call_user_func_array([$this, 'withCookie'], func_get_args()); + return $this->withCookie(...func_get_args()); } /** @@ -108,7 +108,7 @@ public function cookie($cookie) public function withCookie($cookie) { if (is_string($cookie) && function_exists('cookie')) { - $cookie = call_user_func_array('cookie', func_get_args()); + $cookie = cookie(...func_get_args()); } $this->headers->setCookie($cookie); diff --git a/src/Illuminate/Http/composer.json b/src/Illuminate/Http/composer.json index 5c17211e9b95..949dd377060e 100755 --- a/src/Illuminate/Http/composer.json +++ b/src/Illuminate/Http/composer.json @@ -14,7 +14,7 @@ } ], "require": { - "php": "^7.2", + "php": "^7.2|^8.0", "ext-json": "*", "illuminate/session": "^6.0", "illuminate/support": "^6.0", diff --git a/src/Illuminate/Log/composer.json b/src/Illuminate/Log/composer.json index 5b2d0c3299f8..ee3c565a146e 100755 --- a/src/Illuminate/Log/composer.json +++ b/src/Illuminate/Log/composer.json @@ -14,7 +14,7 @@ } ], "require": { - "php": "^7.2", + "php": "^7.2|^8.0", "illuminate/contracts": "^6.0", "illuminate/support": "^6.0", "monolog/monolog": "^1.12|^2.0" diff --git a/src/Illuminate/Mail/composer.json b/src/Illuminate/Mail/composer.json index 3851f3907f6d..1b22c2bcf4d0 100755 --- a/src/Illuminate/Mail/composer.json +++ b/src/Illuminate/Mail/composer.json @@ -14,7 +14,7 @@ } ], "require": { - "php": "^7.2", + "php": "^7.2|^8.0", "ext-json": "*", "illuminate/container": "^6.0", "illuminate/contracts": "^6.0", diff --git a/src/Illuminate/Notifications/composer.json b/src/Illuminate/Notifications/composer.json index cbe02a736ba2..1250fd575eb2 100644 --- a/src/Illuminate/Notifications/composer.json +++ b/src/Illuminate/Notifications/composer.json @@ -14,7 +14,7 @@ } ], "require": { - "php": "^7.2", + "php": "^7.2|^8.0", "illuminate/broadcasting": "^6.0", "illuminate/bus": "^6.0", "illuminate/container": "^6.0", diff --git a/src/Illuminate/Pagination/composer.json b/src/Illuminate/Pagination/composer.json index d54b1d2b9d65..c0438de6f379 100755 --- a/src/Illuminate/Pagination/composer.json +++ b/src/Illuminate/Pagination/composer.json @@ -14,7 +14,7 @@ } ], "require": { - "php": "^7.2", + "php": "^7.2|^8.0", "ext-json": "*", "illuminate/contracts": "^6.0", "illuminate/support": "^6.0" diff --git a/src/Illuminate/Pipeline/composer.json b/src/Illuminate/Pipeline/composer.json index a5c9e57565f8..8b14414172d7 100644 --- a/src/Illuminate/Pipeline/composer.json +++ b/src/Illuminate/Pipeline/composer.json @@ -14,7 +14,7 @@ } ], "require": { - "php": "^7.2", + "php": "^7.2|^8.0", "illuminate/contracts": "^6.0", "illuminate/support": "^6.0", "symfony/debug": "^4.3" diff --git a/src/Illuminate/Queue/composer.json b/src/Illuminate/Queue/composer.json index a2bc8c461d20..eb10c77aad22 100644 --- a/src/Illuminate/Queue/composer.json +++ b/src/Illuminate/Queue/composer.json @@ -14,7 +14,7 @@ } ], "require": { - "php": "^7.2", + "php": "^7.2|^8.0", "ext-json": "*", "illuminate/console": "^6.0", "illuminate/container": "^6.0", diff --git a/src/Illuminate/Redis/Connections/PredisConnection.php b/src/Illuminate/Redis/Connections/PredisConnection.php index 67a9cc1163a3..bea9c6e47007 100644 --- a/src/Illuminate/Redis/Connections/PredisConnection.php +++ b/src/Illuminate/Redis/Connections/PredisConnection.php @@ -43,7 +43,7 @@ public function createSubscription($channels, Closure $callback, $method = 'subs { $loop = $this->pubSubLoop(); - call_user_func_array([$loop, $method], (array) $channels); + $loop->{$method}(...array_values((array) $channels)); foreach ($loop as $message) { if ($message->kind === 'message' || $message->kind === 'pmessage') { diff --git a/src/Illuminate/Redis/composer.json b/src/Illuminate/Redis/composer.json index 84dfa186bc9b..8261ad60c3df 100755 --- a/src/Illuminate/Redis/composer.json +++ b/src/Illuminate/Redis/composer.json @@ -14,7 +14,7 @@ } ], "require": { - "php": "^7.2", + "php": "^7.2|^8.0", "illuminate/contracts": "^6.0", "illuminate/support": "^6.0" }, diff --git a/src/Illuminate/Routing/Controller.php b/src/Illuminate/Routing/Controller.php index 50de9712294f..a26a5ee7effa 100644 --- a/src/Illuminate/Routing/Controller.php +++ b/src/Illuminate/Routing/Controller.php @@ -51,7 +51,7 @@ public function getMiddleware() */ public function callAction($method, $parameters) { - return call_user_func_array([$this, $method], $parameters); + return $this->{$method}(...array_values($parameters)); } /** diff --git a/src/Illuminate/Routing/Pipeline.php b/src/Illuminate/Routing/Pipeline.php index 63d59ad93a33..3d4a684cf39a 100644 --- a/src/Illuminate/Routing/Pipeline.php +++ b/src/Illuminate/Routing/Pipeline.php @@ -50,7 +50,7 @@ protected function handleException($passable, Exception $e) $response = $handler->render($passable, $e); - if (method_exists($response, 'withException')) { + if (is_object($response) && method_exists($response, 'withException')) { $response->withException($e); } diff --git a/src/Illuminate/Routing/Route.php b/src/Illuminate/Routing/Route.php index 2d854ef95964..9b31e619fea9 100755 --- a/src/Illuminate/Routing/Route.php +++ b/src/Illuminate/Routing/Route.php @@ -790,9 +790,9 @@ public function gatherMiddleware() $this->computedMiddleware = []; - return $this->computedMiddleware = array_unique(array_merge( + return $this->computedMiddleware = Router::uniqueMiddleware(array_merge( $this->middleware(), $this->controllerMiddleware() - ), SORT_REGULAR); + )); } /** diff --git a/src/Illuminate/Routing/Router.php b/src/Illuminate/Routing/Router.php index e7f0b58a4a43..8e762351ee8f 100644 --- a/src/Illuminate/Routing/Router.php +++ b/src/Illuminate/Routing/Router.php @@ -1273,6 +1273,29 @@ public function setRoutes(RouteCollection $routes) $this->container->instance('routes', $this->routes); } + /** + * Remove any duplicate middleware from the given array. + * + * @param array $middleware + * @return array + */ + public static function uniqueMiddleware(array $middleware) + { + $seen = []; + $result = []; + + foreach ($middleware as $value) { + $key = \is_object($value) ? \spl_object_id($value) : $value; + + if (! isset($seen[$key])) { + $seen[$key] = true; + $result[] = $value; + } + } + + return $result; + } + /** * Dynamically handle calls into the router instance. * diff --git a/src/Illuminate/Routing/SortedMiddleware.php b/src/Illuminate/Routing/SortedMiddleware.php index f384603387f8..57dbb0730a38 100644 --- a/src/Illuminate/Routing/SortedMiddleware.php +++ b/src/Illuminate/Routing/SortedMiddleware.php @@ -62,7 +62,7 @@ protected function sortMiddleware($priorityMap, $middlewares) } } - return array_values(array_unique($middlewares, SORT_REGULAR)); + return Router::uniqueMiddleware($middlewares); } /** diff --git a/src/Illuminate/Routing/composer.json b/src/Illuminate/Routing/composer.json index 9bc8e5f46f22..6362308f42df 100644 --- a/src/Illuminate/Routing/composer.json +++ b/src/Illuminate/Routing/composer.json @@ -14,7 +14,7 @@ } ], "require": { - "php": "^7.2", + "php": "^7.2|^8.0", "ext-json": "*", "illuminate/container": "^6.0", "illuminate/contracts": "^6.0", diff --git a/src/Illuminate/Session/composer.json b/src/Illuminate/Session/composer.json index 3c9962cde646..132304c2d30b 100755 --- a/src/Illuminate/Session/composer.json +++ b/src/Illuminate/Session/composer.json @@ -14,7 +14,7 @@ } ], "require": { - "php": "^7.2", + "php": "^7.2|^8.0", "ext-json": "*", "illuminate/contracts": "^6.0", "illuminate/filesystem": "^6.0", diff --git a/src/Illuminate/Support/Collection.php b/src/Illuminate/Support/Collection.php index 91102f6862d2..b9d4ebb7d82b 100644 --- a/src/Illuminate/Support/Collection.php +++ b/src/Illuminate/Support/Collection.php @@ -1210,7 +1210,7 @@ public function zip($items) return new static(func_get_args()); }, $this->items], $arrayableItems); - return new static(call_user_func_array('array_map', $params)); + return new static(array_map(...$params)); } /** diff --git a/src/Illuminate/Support/Str.php b/src/Illuminate/Support/Str.php index 8ff6d4cacfdd..3497e851caf0 100644 --- a/src/Illuminate/Support/Str.php +++ b/src/Illuminate/Support/Str.php @@ -455,6 +455,10 @@ public static function replaceFirst($search, $replace, $subject) */ public static function replaceLast($search, $replace, $subject) { + if ($search === '') { + return $subject; + } + $position = strrpos($subject, $search); if ($position !== false) { diff --git a/src/Illuminate/Support/Traits/EnumeratesValues.php b/src/Illuminate/Support/Traits/EnumeratesValues.php index a32b51803bc3..f7e9bfc60a63 100644 --- a/src/Illuminate/Support/Traits/EnumeratesValues.php +++ b/src/Illuminate/Support/Traits/EnumeratesValues.php @@ -143,7 +143,7 @@ public function containsStrict($key, $value = null) */ public function dd(...$args) { - call_user_func_array([$this, 'dump'], $args); + $this->dump(...$args); exit(1); } diff --git a/src/Illuminate/Support/Traits/Macroable.php b/src/Illuminate/Support/Traits/Macroable.php index 0c2112c7fba5..406f65edc79b 100644 --- a/src/Illuminate/Support/Traits/Macroable.php +++ b/src/Illuminate/Support/Traits/Macroable.php @@ -82,7 +82,7 @@ public static function __callStatic($method, $parameters) $macro = static::$macros[$method]; if ($macro instanceof Closure) { - return call_user_func_array(Closure::bind($macro, null, static::class), $parameters); + $macro = $macro->bindTo(null, static::class); } return $macro(...$parameters); @@ -108,7 +108,7 @@ public function __call($method, $parameters) $macro = static::$macros[$method]; if ($macro instanceof Closure) { - return call_user_func_array($macro->bindTo($this, static::class), $parameters); + $macro = $macro->bindTo($this, static::class); } return $macro(...$parameters); diff --git a/src/Illuminate/Support/composer.json b/src/Illuminate/Support/composer.json index 828c6e7f95b3..a9956f5f8272 100644 --- a/src/Illuminate/Support/composer.json +++ b/src/Illuminate/Support/composer.json @@ -14,12 +14,12 @@ } ], "require": { - "php": "^7.2", + "php": "^7.2|^8.0", "ext-json": "*", "ext-mbstring": "*", "doctrine/inflector": "^1.4|^2.0", "illuminate/contracts": "^6.0", - "nesbot/carbon": "^2.0" + "nesbot/carbon": "^2.31" }, "conflict": { "tightenco/collect": "<5.5.33" diff --git a/src/Illuminate/Support/helpers.php b/src/Illuminate/Support/helpers.php index d968dba5466d..17ec26b4ca89 100755 --- a/src/Illuminate/Support/helpers.php +++ b/src/Illuminate/Support/helpers.php @@ -385,7 +385,7 @@ function retry($times, callable $callback, $sleep = 0, $when = null) { $attempts = 0; - beginning: + beginning : $attempts++; $times--; diff --git a/src/Illuminate/Translation/composer.json b/src/Illuminate/Translation/composer.json index 25d2fd7fbd8a..a6ee58b3aacf 100755 --- a/src/Illuminate/Translation/composer.json +++ b/src/Illuminate/Translation/composer.json @@ -14,7 +14,7 @@ } ], "require": { - "php": "^7.2", + "php": "^7.2|^8.0", "ext-json": "*", "illuminate/contracts": "^6.0", "illuminate/filesystem": "^6.0", diff --git a/src/Illuminate/Validation/Concerns/FormatsMessages.php b/src/Illuminate/Validation/Concerns/FormatsMessages.php index 8ee3f0aee3bd..9d011892aaf7 100644 --- a/src/Illuminate/Validation/Concerns/FormatsMessages.php +++ b/src/Illuminate/Validation/Concerns/FormatsMessages.php @@ -374,7 +374,7 @@ protected function callReplacer($message, $attribute, $rule, $parameters, $valid $callback = $this->replacers[$rule]; if ($callback instanceof Closure) { - return call_user_func_array($callback, func_get_args()); + return $callback(...func_get_args()); } elseif (is_string($callback)) { return $this->callClassBasedReplacer($callback, $message, $attribute, $rule, $parameters, $validator); } @@ -395,6 +395,6 @@ protected function callClassBasedReplacer($callback, $message, $attribute, $rule { [$class, $method] = Str::parseCallback($callback, 'replace'); - return call_user_func_array([$this->container->make($class), $method], array_slice(func_get_args(), 1)); + return $this->container->make($class)->{$method}(...array_slice(func_get_args(), 1)); } } diff --git a/src/Illuminate/Validation/Validator.php b/src/Illuminate/Validation/Validator.php index df06c5077dbf..582075e7cba5 100755 --- a/src/Illuminate/Validation/Validator.php +++ b/src/Illuminate/Validation/Validator.php @@ -280,7 +280,7 @@ public function parseData(array $data) public function after($callback) { $this->after[] = function () use ($callback) { - return call_user_func_array($callback, [$this]); + return $callback($this); }; return $this; @@ -1268,7 +1268,7 @@ protected function callExtension($rule, $parameters) $callback = $this->extensions[$rule]; if (is_callable($callback)) { - return call_user_func_array($callback, $parameters); + return $callback(...array_values($parameters)); } elseif (is_string($callback)) { return $this->callClassBasedExtension($callback, $parameters); } @@ -1285,7 +1285,7 @@ protected function callClassBasedExtension($callback, $parameters) { [$class, $method] = Str::parseCallback($callback, 'validate'); - return call_user_func_array([$this->container->make($class), $method], $parameters); + return $this->container->make($class)->{$method}(...array_values($parameters)); } /** diff --git a/src/Illuminate/Validation/composer.json b/src/Illuminate/Validation/composer.json index e7475a2b5ea7..7b0f9827db70 100755 --- a/src/Illuminate/Validation/composer.json +++ b/src/Illuminate/Validation/composer.json @@ -14,7 +14,7 @@ } ], "require": { - "php": "^7.2", + "php": "^7.2|^8.0", "ext-json": "*", "egulias/email-validator": "^2.1.10", "illuminate/container": "^6.0", diff --git a/src/Illuminate/View/Concerns/ManagesEvents.php b/src/Illuminate/View/Concerns/ManagesEvents.php index 1889a6b6fdaa..39902905de09 100644 --- a/src/Illuminate/View/Concerns/ManagesEvents.php +++ b/src/Illuminate/View/Concerns/ManagesEvents.php @@ -121,9 +121,7 @@ protected function buildClassEventCallback($class, $prefix) // the instance out of the IoC container and call the method on it with the // given arguments that are passed to the Closure as the composer's data. return function () use ($class, $method) { - return call_user_func_array( - [$this->container->make($class), $method], func_get_args() - ); + return $this->container->make($class)->{$method}(...func_get_args()); }; } diff --git a/src/Illuminate/View/composer.json b/src/Illuminate/View/composer.json index e170e507d129..a08e34f11e05 100644 --- a/src/Illuminate/View/composer.json +++ b/src/Illuminate/View/composer.json @@ -14,7 +14,7 @@ } ], "require": { - "php": "^7.2", + "php": "^7.2|^8.0", "ext-json": "*", "illuminate/container": "^6.0", "illuminate/contracts": "^6.0", diff --git a/tests/Container/ContainerCallTest.php b/tests/Container/ContainerCallTest.php index fe8d6b96c1e8..bd5a4ca826dd 100644 --- a/tests/Container/ContainerCallTest.php +++ b/tests/Container/ContainerCallTest.php @@ -3,17 +3,17 @@ namespace Illuminate\Tests\Container; use Closure; +use Error; use Illuminate\Container\Container; use PHPUnit\Framework\TestCase; -use ReflectionException; use stdClass; class ContainerCallTest extends TestCase { public function testCallWithAtSignBasedClassReferencesWithoutMethodThrowsException() { - $this->expectException(ReflectionException::class); - $this->expectExceptionMessage('Function ContainerTestCallStub() does not exist'); + $this->expectException(Error::class); + $this->expectExceptionMessage('Call to undefined function ContainerTestCallStub()'); $container = new Container; $container->call('ContainerTestCallStub'); diff --git a/tests/Database/DatabaseConnectionTest.php b/tests/Database/DatabaseConnectionTest.php index ae9ab5007961..baf3b382ac54 100755 --- a/tests/Database/DatabaseConnectionTest.php +++ b/tests/Database/DatabaseConnectionTest.php @@ -178,6 +178,7 @@ public function testBeginTransactionMethodNeverRetriesIfWithinTransaction() $pdo->expects($this->once())->method('exec')->will($this->throwException(new Exception)); $connection = $this->getMockConnection(['reconnect'], $pdo); $queryGrammar = $this->createMock(Grammar::class); + $queryGrammar->expects($this->once())->method('compileSavepoint')->willReturn('trans1'); $queryGrammar->expects($this->once())->method('supportsSavepoints')->willReturn(true); $connection->setQueryGrammar($queryGrammar); $connection->expects($this->never())->method('reconnect'); diff --git a/tests/Database/DatabaseEloquentBelongsToTest.php b/tests/Database/DatabaseEloquentBelongsToTest.php index d362e4680307..06b2087ff395 100755 --- a/tests/Database/DatabaseEloquentBelongsToTest.php +++ b/tests/Database/DatabaseEloquentBelongsToTest.php @@ -77,10 +77,16 @@ public function testEagerConstraintsAreProperlyAdded() public function testIdsInEagerConstraintsCanBeZero() { + $keys = ['foreign.value', 0]; + + if (version_compare(PHP_VERSION, '8.0.0-dev', '>=')) { + sort($keys); + } + $relation = $this->getRelation(); $relation->getRelated()->shouldReceive('getKeyName')->andReturn('id'); $relation->getRelated()->shouldReceive('getKeyType')->andReturn('int'); - $relation->getQuery()->shouldReceive('whereIntegerInRaw')->once()->with('relation.id', ['foreign.value', 0]); + $relation->getQuery()->shouldReceive('whereIntegerInRaw')->once()->with('relation.id', $keys); $models = [new EloquentBelongsToModelStub, new EloquentBelongsToModelStubWithZeroId]; $relation->addEagerConstraints($models); } diff --git a/tests/Database/DatabaseEloquentBuilderTest.php b/tests/Database/DatabaseEloquentBuilderTest.php index 8276ea03e96b..29742f5bc60b 100755 --- a/tests/Database/DatabaseEloquentBuilderTest.php +++ b/tests/Database/DatabaseEloquentBuilderTest.php @@ -443,7 +443,9 @@ public function testGlobalMacrosAreCalledOnBuilder() return $bar; }); - Builder::macro('bam', [Builder::class, 'getQuery']); + Builder::macro('bam', function () { + return $this->getQuery(); + }); $builder = $this->getBuilder(); diff --git a/tests/Integration/Auth/ApiAuthenticationWithEloquentTest.php b/tests/Integration/Auth/ApiAuthenticationWithEloquentTest.php index 9966fbea6d5d..cf6c6cc5246f 100644 --- a/tests/Integration/Auth/ApiAuthenticationWithEloquentTest.php +++ b/tests/Integration/Auth/ApiAuthenticationWithEloquentTest.php @@ -8,6 +8,9 @@ use Illuminate\Support\Str; use Orchestra\Testbench\TestCase; +/** + * @requires extension pdo_mysql + */ class ApiAuthenticationWithEloquentTest extends TestCase { protected function getEnvironmentSetUp($app) diff --git a/tests/Integration/Database/DatabaseEmulatePreparesMySqlConnectionTest.php b/tests/Integration/Database/DatabaseEmulatePreparesMySqlConnectionTest.php index 65e71ebdb908..bd71a5865c29 100755 --- a/tests/Integration/Database/DatabaseEmulatePreparesMySqlConnectionTest.php +++ b/tests/Integration/Database/DatabaseEmulatePreparesMySqlConnectionTest.php @@ -4,6 +4,9 @@ use PDO; +/** + * @requires extension pdo_mysql + */ class DatabaseEmulatePreparesMySqlConnectionTest extends DatabaseMySqlConnectionTest { protected function getEnvironmentSetUp($app) diff --git a/tests/Integration/Database/DatabaseMySqlConnectionTest.php b/tests/Integration/Database/DatabaseMySqlConnectionTest.php index d0ce732573e1..0ca3d3f69a0f 100644 --- a/tests/Integration/Database/DatabaseMySqlConnectionTest.php +++ b/tests/Integration/Database/DatabaseMySqlConnectionTest.php @@ -7,6 +7,9 @@ use Illuminate\Support\Facades\Schema; use Orchestra\Testbench\TestCase; +/** + * @requires extension pdo_mysql + */ class DatabaseMySqlConnectionTest extends TestCase { const TABLE = 'player';