diff --git a/.travis.yml b/.travis.yml index 7d48e602f13e..742efffd57de 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,9 +7,6 @@ env: matrix: fast_finish: true include: - - php: 7.0.21 - - php: 7.0.21 - env: setup=lowest - php: 7.1 - php: 7.1 env: setup=lowest diff --git a/CHANGELOG-5.6.md b/CHANGELOG-5.6.md new file mode 100644 index 000000000000..39034332ab42 --- /dev/null +++ b/CHANGELOG-5.6.md @@ -0,0 +1,32 @@ +# Release Notes for 5.6.x + +## [Unreleased] + +### General +- ⚠️ Added `runningUnitTests()` to `Application` contract ([#21034](https://github.com/laravel/framework/pull/21034)) +- ⚠️ Upgraded `cron-expression` to `2.x` ([#21637](https://github.com/laravel/framework/pull/21637)) + +### Arrays +- ⚠️ Arr::wrap(null) will now return an empty array instead of wrapping the null value ([#21745](https://github.com/laravel/framework/pull/21745)) + +### Artisan Console +- ⚠️ Removed deprecated `optimize` command ([#20851](https://github.com/laravel/framework/pull/20851)) +- Show job id in `queue:work` output ([#21204](https://github.com/laravel/framework/pull/21204)) +- Show batch number in `migrate:status` output ([#21391](https://github.com/laravel/framework/pull/21391)) + +### Database +- ⚠️ Swap the index order of morph type and id ([#21693](https://github.com/laravel/framework/pull/21693)) + +### Eloquent +- Serialize relationships ([#21229](https://github.com/laravel/framework/pull/21229)) +- Allow setting custom owner key on polymorphic relationships ([#21310](https://github.com/laravel/framework/pull/21310)) + +### Queues +- ⚠️ Added `payload()` and `getJobId()` to `Job` contract ([#21303](https://github.com/laravel/framework/pull/21303)) + +### Responses +- Added missing `$raw` and `$sameSite` parameters to `Cookie\Factory` methods ([#21553](https://github.com/laravel/framework/pull/21553)) +- ⚠️ Return `201` status of Model was recently created ([#21625](https://github.com/laravel/framework/pull/21625)) + +### Validation +- ⚠️ Ignore SVGs in `validateDimensions()` ([#21390](https://github.com/laravel/framework/pull/21390)) diff --git a/composer.json b/composer.json index 8fd0008ec104..c24913e4e011 100644 --- a/composer.json +++ b/composer.json @@ -15,14 +15,14 @@ } ], "require": { - "php": ">=7.0", + "php": "^7.1.3", "ext-mbstring": "*", "ext-openssl": "*", "doctrine/inflector": "~1.1", "erusev/parsedown": "~1.6", "league/flysystem": "~1.0", "monolog/monolog": "~1.12", - "mtdowling/cron-expression": "~1.0", + "dragonmantank/cron-expression": "~2.0", "nesbot/carbon": "~1.20", "psr/container": "~1.0", "psr/simple-cache": "^1.0", @@ -75,7 +75,7 @@ "doctrine/dbal": "~2.5", "filp/whoops": "^2.1.4", "mockery/mockery": "~1.0", - "orchestra/testbench-core": "3.5.*", + "orchestra/testbench-core": "3.6.*", "pda/pheanstalk": "~3.0", "phpunit/phpunit": "~6.0", "predis/predis": "^1.1.1", @@ -101,7 +101,7 @@ }, "extra": { "branch-alias": { - "dev-master": "5.5-dev" + "dev-master": "5.6-dev" } }, "suggest": { diff --git a/src/Illuminate/Auth/composer.json b/src/Illuminate/Auth/composer.json index f3a41d953587..896c871a3919 100644 --- a/src/Illuminate/Auth/composer.json +++ b/src/Illuminate/Auth/composer.json @@ -14,11 +14,11 @@ } ], "require": { - "php": ">=7.0", - "illuminate/contracts": "5.5.*", - "illuminate/http": "5.5.*", - "illuminate/queue": "5.5.*", - "illuminate/support": "5.5.*" + "php": "^7.1.3", + "illuminate/contracts": "5.6.*", + "illuminate/http": "5.6.*", + "illuminate/queue": "5.6.*", + "illuminate/support": "5.6.*" }, "autoload": { "psr-4": { @@ -27,13 +27,13 @@ }, "extra": { "branch-alias": { - "dev-master": "5.5-dev" + "dev-master": "5.6-dev" } }, "suggest": { - "illuminate/console": "Required to use the auth:clear-resets command (5.5.*).", - "illuminate/queue": "Required to fire login / logout events (5.5.*).", - "illuminate/session": "Required to use the session based guard (5.5.*)." + "illuminate/console": "Required to use the auth:clear-resets command (5.6.*).", + "illuminate/queue": "Required to fire login / logout events (5.6.*).", + "illuminate/session": "Required to use the session based guard (5.6.*)." }, "config": { "sort-packages": true diff --git a/src/Illuminate/Broadcasting/composer.json b/src/Illuminate/Broadcasting/composer.json index 2f4b18ef8195..02069ac250fd 100644 --- a/src/Illuminate/Broadcasting/composer.json +++ b/src/Illuminate/Broadcasting/composer.json @@ -14,12 +14,12 @@ } ], "require": { - "php": ">=7.0", + "php": "^7.1.3", "psr/log": "~1.0", - "illuminate/bus": "5.5.*", - "illuminate/contracts": "5.5.*", - "illuminate/queue": "5.5.*", - "illuminate/support": "5.5.*" + "illuminate/bus": "5.6.*", + "illuminate/contracts": "5.6.*", + "illuminate/queue": "5.6.*", + "illuminate/support": "5.6.*" }, "autoload": { "psr-4": { @@ -28,7 +28,7 @@ }, "extra": { "branch-alias": { - "dev-master": "5.5-dev" + "dev-master": "5.6-dev" } }, "suggest": { diff --git a/src/Illuminate/Bus/composer.json b/src/Illuminate/Bus/composer.json index 3836cee9b7e7..4939a99d921b 100644 --- a/src/Illuminate/Bus/composer.json +++ b/src/Illuminate/Bus/composer.json @@ -14,10 +14,10 @@ } ], "require": { - "php": ">=7.0", - "illuminate/contracts": "5.5.*", - "illuminate/pipeline": "5.5.*", - "illuminate/support": "5.5.*" + "php": "^7.1.3", + "illuminate/contracts": "5.6.*", + "illuminate/pipeline": "5.6.*", + "illuminate/support": "5.6.*" }, "autoload": { "psr-4": { @@ -26,7 +26,7 @@ }, "extra": { "branch-alias": { - "dev-master": "5.5-dev" + "dev-master": "5.6-dev" } }, "config": { diff --git a/src/Illuminate/Cache/composer.json b/src/Illuminate/Cache/composer.json index f81a218c707e..48b7e1bb7a73 100755 --- a/src/Illuminate/Cache/composer.json +++ b/src/Illuminate/Cache/composer.json @@ -14,9 +14,9 @@ } ], "require": { - "php": ">=7.0", - "illuminate/contracts": "5.5.*", - "illuminate/support": "5.5.*" + "php": "^7.1.3", + "illuminate/contracts": "5.6.*", + "illuminate/support": "5.6.*" }, "autoload": { "psr-4": { @@ -25,13 +25,13 @@ }, "extra": { "branch-alias": { - "dev-master": "5.5-dev" + "dev-master": "5.6-dev" } }, "suggest": { - "illuminate/database": "Required to use the database cache driver (5.5.*).", - "illuminate/filesystem": "Required to use the file cache driver (5.5.*).", - "illuminate/redis": "Required to use the redis cache driver (5.5.*)." + "illuminate/database": "Required to use the database cache driver (5.6.*).", + "illuminate/filesystem": "Required to use the file cache driver (5.6.*).", + "illuminate/redis": "Required to use the redis cache driver (5.6.*)." }, "config": { "sort-packages": true diff --git a/src/Illuminate/Config/composer.json b/src/Illuminate/Config/composer.json index 55d6f0a0e0f0..f79f6f5665bb 100755 --- a/src/Illuminate/Config/composer.json +++ b/src/Illuminate/Config/composer.json @@ -14,9 +14,9 @@ } ], "require": { - "php": ">=7.0", - "illuminate/contracts": "5.5.*", - "illuminate/support": "5.5.*" + "php": "^7.1.3", + "illuminate/contracts": "5.6.*", + "illuminate/support": "5.6.*" }, "autoload": { "psr-4": { @@ -25,7 +25,7 @@ }, "extra": { "branch-alias": { - "dev-master": "5.5-dev" + "dev-master": "5.6-dev" } }, "config": { diff --git a/src/Illuminate/Console/Scheduling/Event.php b/src/Illuminate/Console/Scheduling/Event.php index 4d67c4789501..ba5ff56eb36c 100644 --- a/src/Illuminate/Console/Scheduling/Event.php +++ b/src/Illuminate/Console/Scheduling/Event.php @@ -27,7 +27,7 @@ class Event * * @var string */ - public $expression = '* * * * * *'; + public $expression = '* * * * *'; /** * The timezone the date should be evaluated on. diff --git a/src/Illuminate/Console/composer.json b/src/Illuminate/Console/composer.json index 6e432e03e59f..2fcdc11cf506 100755 --- a/src/Illuminate/Console/composer.json +++ b/src/Illuminate/Console/composer.json @@ -14,9 +14,9 @@ } ], "require": { - "php": ">=7.0", - "illuminate/contracts": "5.5.*", - "illuminate/support": "5.5.*", + "php": "^7.1.3", + "illuminate/contracts": "5.6.*", + "illuminate/support": "5.6.*", "symfony/console": "~3.3" }, "autoload": { @@ -26,7 +26,7 @@ }, "extra": { "branch-alias": { - "dev-master": "5.5-dev" + "dev-master": "5.6-dev" } }, "suggest": { diff --git a/src/Illuminate/Container/Container.php b/src/Illuminate/Container/Container.php index 54d10354876a..a4b479aea1d7 100755 --- a/src/Illuminate/Container/Container.php +++ b/src/Illuminate/Container/Container.php @@ -271,13 +271,28 @@ public function hasMethodBinding($method) /** * Bind a callback to resolve with Container::call. * - * @param string $method + * @param array|string $method * @param \Closure $callback * @return void */ public function bindMethod($method, $callback) { - $this->methodBindings[$method] = $callback; + $this->methodBindings[$this->parseBindMethod($method)] = $callback; + } + + /** + * Get the method to be bound in class@method format. + * + * @param array|string $method + * @return string + */ + protected function parseBindMethod($method) + { + if (is_array($method)) { + return $method[0].'@'.$method[1]; + } + + return $method; } /** diff --git a/src/Illuminate/Container/composer.json b/src/Illuminate/Container/composer.json index 7347da14a73f..b8c4aafc738a 100755 --- a/src/Illuminate/Container/composer.json +++ b/src/Illuminate/Container/composer.json @@ -14,8 +14,8 @@ } ], "require": { - "php": ">=7.0", - "illuminate/contracts": "5.5.*", + "php": "^7.1.3", + "illuminate/contracts": "5.6.*", "psr/container": "~1.0" }, "autoload": { @@ -25,7 +25,7 @@ }, "extra": { "branch-alias": { - "dev-master": "5.5-dev" + "dev-master": "5.6-dev" } }, "config": { diff --git a/src/Illuminate/Contracts/Cookie/Factory.php b/src/Illuminate/Contracts/Cookie/Factory.php index 6124397658ea..0cf83ea7f08a 100644 --- a/src/Illuminate/Contracts/Cookie/Factory.php +++ b/src/Illuminate/Contracts/Cookie/Factory.php @@ -14,9 +14,11 @@ interface Factory * @param string $domain * @param bool $secure * @param bool $httpOnly + * @param bool $raw + * @param string|null $sameSite * @return \Symfony\Component\HttpFoundation\Cookie */ - public function make($name, $value, $minutes = 0, $path = null, $domain = null, $secure = false, $httpOnly = true); + public function make($name, $value, $minutes = 0, $path = null, $domain = null, $secure = false, $httpOnly = true, $raw = false, $sameSite = null); /** * Create a cookie that lasts "forever" (five years). @@ -27,9 +29,11 @@ public function make($name, $value, $minutes = 0, $path = null, $domain = null, * @param string $domain * @param bool $secure * @param bool $httpOnly + * @param bool $raw + * @param string|null $sameSite * @return \Symfony\Component\HttpFoundation\Cookie */ - public function forever($name, $value, $path = null, $domain = null, $secure = false, $httpOnly = true); + public function forever($name, $value, $path = null, $domain = null, $secure = false, $httpOnly = true, $raw = false, $sameSite = null); /** * Expire the given cookie. diff --git a/src/Illuminate/Contracts/Database/ModelIdentifier.php b/src/Illuminate/Contracts/Database/ModelIdentifier.php index 587044a8dab3..9893d280ef69 100644 --- a/src/Illuminate/Contracts/Database/ModelIdentifier.php +++ b/src/Illuminate/Contracts/Database/ModelIdentifier.php @@ -20,6 +20,13 @@ class ModelIdentifier */ public $id; + /** + * The relationships loaded on the model. + * + * @var array + */ + public $relations; + /** * The connection name of the model. * @@ -32,13 +39,15 @@ class ModelIdentifier * * @param string $class * @param mixed $id + * @param array $relations * @param mixed $connection * @return void */ - public function __construct($class, $id, $connection) + public function __construct($class, $id, array $relations, $connection) { $this->id = $id; $this->class = $class; + $this->relations = $relations; $this->connection = $connection; } } diff --git a/src/Illuminate/Contracts/Foundation/Application.php b/src/Illuminate/Contracts/Foundation/Application.php index a7d643b15ace..810f929b4e64 100644 --- a/src/Illuminate/Contracts/Foundation/Application.php +++ b/src/Illuminate/Contracts/Foundation/Application.php @@ -28,12 +28,19 @@ public function basePath(); public function environment(); /** - * Determine if we are running in the console. + * Determine if the application is running in the console. * * @return bool */ public function runningInConsole(); + /** + * Determine if the application is running unit tests. + * + * @return bool + */ + public function runningUnitTests(); + /** * Determine if the application is currently down for maintenance. * diff --git a/src/Illuminate/Contracts/Queue/Job.php b/src/Illuminate/Contracts/Queue/Job.php index 8a907987a35c..98ecf6356673 100644 --- a/src/Illuminate/Contracts/Queue/Job.php +++ b/src/Illuminate/Contracts/Queue/Job.php @@ -4,6 +4,20 @@ interface Job { + /** + * Get the job identifier. + * + * @return string + */ + public function getJobId(); + + /** + * Get the decoded body of the job. + * + * @return array + */ + public function payload(); + /** * Fire the job. * diff --git a/src/Illuminate/Contracts/Queue/QueueableCollection.php b/src/Illuminate/Contracts/Queue/QueueableCollection.php index 0331b814f04b..7f1ea19c5436 100644 --- a/src/Illuminate/Contracts/Queue/QueueableCollection.php +++ b/src/Illuminate/Contracts/Queue/QueueableCollection.php @@ -18,6 +18,13 @@ public function getQueueableClass(); */ public function getQueueableIds(); + /** + * Get the relationships of the entities being queued. + * + * @return array + */ + public function getQueueableRelations(); + /** * Get the connection of the entities being queued. * diff --git a/src/Illuminate/Contracts/Queue/QueueableEntity.php b/src/Illuminate/Contracts/Queue/QueueableEntity.php index 00e28f8a070f..366f0c84fab6 100644 --- a/src/Illuminate/Contracts/Queue/QueueableEntity.php +++ b/src/Illuminate/Contracts/Queue/QueueableEntity.php @@ -11,6 +11,13 @@ interface QueueableEntity */ public function getQueueableId(); + /** + * Get the relationships for the entity. + * + * @return array + */ + public function getQueueableRelations(); + /** * Get the connection of the entity. * diff --git a/src/Illuminate/Contracts/composer.json b/src/Illuminate/Contracts/composer.json index c97fc256a5ca..bd00fd61626e 100644 --- a/src/Illuminate/Contracts/composer.json +++ b/src/Illuminate/Contracts/composer.json @@ -14,7 +14,7 @@ } ], "require": { - "php": ">=7.0", + "php": "^7.1.3", "psr/container": "~1.0", "psr/simple-cache": "~1.0" }, @@ -25,7 +25,7 @@ }, "extra": { "branch-alias": { - "dev-master": "5.5-dev" + "dev-master": "5.6-dev" } }, "config": { diff --git a/src/Illuminate/Cookie/composer.json b/src/Illuminate/Cookie/composer.json index e9a85cd64a34..11e27be2e2f3 100755 --- a/src/Illuminate/Cookie/composer.json +++ b/src/Illuminate/Cookie/composer.json @@ -14,9 +14,9 @@ } ], "require": { - "php": ">=7.0", - "illuminate/contracts": "5.5.*", - "illuminate/support": "5.5.*", + "php": "^7.1.3", + "illuminate/contracts": "5.6.*", + "illuminate/support": "5.6.*", "symfony/http-foundation": "~3.3", "symfony/http-kernel": "~3.3" }, @@ -27,7 +27,7 @@ }, "extra": { "branch-alias": { - "dev-master": "5.5-dev" + "dev-master": "5.6-dev" } }, "config": { diff --git a/src/Illuminate/Database/Console/Migrations/StatusCommand.php b/src/Illuminate/Database/Console/Migrations/StatusCommand.php index 6cdea01faa75..4cec4dd61f1c 100644 --- a/src/Illuminate/Database/Console/Migrations/StatusCommand.php +++ b/src/Illuminate/Database/Console/Migrations/StatusCommand.php @@ -57,8 +57,10 @@ public function handle() $ran = $this->migrator->getRepository()->getRan(); - if (count($migrations = $this->getStatusFor($ran)) > 0) { - $this->table(['Ran?', 'Migration'], $migrations); + $batches = $this->migrator->getRepository()->getMigrationBatches(); + + if (count($migrations = $this->getStatusFor($ran, $batches)) > 0) { + $this->table(['Ran?', 'Migration', 'Batch'], $migrations); } else { $this->error('No migrations found'); } @@ -68,16 +70,17 @@ public function handle() * Get the status for the given ran migrations. * * @param array $ran + * @param array $batches * @return \Illuminate\Support\Collection */ - protected function getStatusFor(array $ran) + protected function getStatusFor(array $ran, array $batches) { return Collection::make($this->getAllMigrationFiles()) - ->map(function ($migration) use ($ran) { + ->map(function ($migration) use ($ran, $batches) { $migrationName = $this->migrator->getMigrationName($migration); return in_array($migrationName, $ran) - ? ['Y', $migrationName] + ? ['Y', $migrationName, $batches[$migrationName]] : ['N', $migrationName]; }); } diff --git a/src/Illuminate/Database/Eloquent/Collection.php b/src/Illuminate/Database/Eloquent/Collection.php index b87315ebc167..044fa5cce2ab 100755 --- a/src/Illuminate/Database/Eloquent/Collection.php +++ b/src/Illuminate/Database/Eloquent/Collection.php @@ -410,6 +410,16 @@ public function getQueueableIds() return $this->modelKeys(); } + /** + * Get the relationships of the entities being queued. + * + * @return array + */ + public function getQueueableRelations() + { + return $this->isNotEmpty() ? $this->first()->getRelations() : []; + } + /** * Get the connection of the entities being queued. * diff --git a/src/Illuminate/Database/Eloquent/Concerns/HasRelationships.php b/src/Illuminate/Database/Eloquent/Concerns/HasRelationships.php index d5599da4378c..a6d6f7ede8db 100644 --- a/src/Illuminate/Database/Eloquent/Concerns/HasRelationships.php +++ b/src/Illuminate/Database/Eloquent/Concerns/HasRelationships.php @@ -128,9 +128,10 @@ public function belongsTo($related, $foreignKey = null, $ownerKey = null, $relat * @param string $name * @param string $type * @param string $id + * @param string $ownerKey * @return \Illuminate\Database\Eloquent\Relations\MorphTo */ - public function morphTo($name = null, $type = null, $id = null) + public function morphTo($name = null, $type = null, $id = null, $ownerKey = null) { // If no name is provided, we will use the backtrace to get the function name // since that is most likely the name of the polymorphic interface. We can @@ -145,8 +146,8 @@ public function morphTo($name = null, $type = null, $id = null) // the relationship. In this case we'll just pass in a dummy query where we // need to remove any eager loads that may already be defined on a model. return empty($class = $this->{$type}) - ? $this->morphEagerTo($name, $type, $id) - : $this->morphInstanceTo($class, $name, $type, $id); + ? $this->morphEagerTo($name, $type, $id, $ownerKey) + : $this->morphInstanceTo($class, $name, $type, $id, $ownerKey); } /** @@ -155,12 +156,13 @@ public function morphTo($name = null, $type = null, $id = null) * @param string $name * @param string $type * @param string $id + * @param string $ownerKey * @return \Illuminate\Database\Eloquent\Relations\MorphTo */ - protected function morphEagerTo($name, $type, $id) + protected function morphEagerTo($name, $type, $id, $ownerKey) { return new MorphTo( - $this->newQuery()->setEagerLoads([]), $this, $id, null, $type, $name + $this->newQuery()->setEagerLoads([]), $this, $id, $ownerKey, $type, $name ); } @@ -171,16 +173,17 @@ protected function morphEagerTo($name, $type, $id) * @param string $name * @param string $type * @param string $id + * @param string $ownerKey * @return \Illuminate\Database\Eloquent\Relations\MorphTo */ - protected function morphInstanceTo($target, $name, $type, $id) + protected function morphInstanceTo($target, $name, $type, $id, $ownerKey) { $instance = $this->newRelatedInstance( static::getActualClassNameForMorph($target) ); return new MorphTo( - $instance->newQuery(), $this, $id, $instance->getKeyName(), $type, $name + $instance->newQuery(), $this, $id, $ownerKey ?? $instance->getKeyName(), $type, $name ); } diff --git a/src/Illuminate/Database/Eloquent/Model.php b/src/Illuminate/Database/Eloquent/Model.php index 65a314a1454f..cdd1f25afbf5 100644 --- a/src/Illuminate/Database/Eloquent/Model.php +++ b/src/Illuminate/Database/Eloquent/Model.php @@ -12,6 +12,7 @@ use Illuminate\Contracts\Routing\UrlRoutable; use Illuminate\Contracts\Queue\QueueableEntity; use Illuminate\Database\Eloquent\Relations\Pivot; +use Illuminate\Contracts\Queue\QueueableCollection; use Illuminate\Database\Query\Builder as QueryBuilder; use Illuminate\Database\ConnectionResolverInterface as Resolver; @@ -1004,6 +1005,8 @@ public function refresh() $this->load(collect($this->relations)->except('pivot')->keys()->toArray()); + $this->syncOriginal(); + return $this; } @@ -1258,6 +1261,34 @@ public function getQueueableId() return $this->getKey(); } + /** + * Get the queueable relationships for the entity. + * + * @return array + */ + public function getQueueableRelations() + { + $relations = []; + + foreach ($this->getRelations() as $key => $relation) { + $relations[] = $key; + + if ($relation instanceof QueueableCollection) { + foreach ($relation->getQueueableRelations() as $collectionKey => $collectionValue) { + $relations[] = $key.'.'.$collectionKey; + } + } + + if ($relation instanceof QueueableEntity) { + foreach ($relation->getQueueableRelations() as $entityKey => $entityValue) { + $relations[] = $key.'.'.$entityValue; + } + } + } + + return array_unique($relations); + } + /** * Get the queueable connection for the entity. * diff --git a/src/Illuminate/Database/Eloquent/Relations/MorphTo.php b/src/Illuminate/Database/Eloquent/Relations/MorphTo.php index 0b5375b3229e..c027f94e818f 100644 --- a/src/Illuminate/Database/Eloquent/Relations/MorphTo.php +++ b/src/Illuminate/Database/Eloquent/Relations/MorphTo.php @@ -120,12 +120,14 @@ protected function getResultsByType($type) { $instance = $this->createModelByType($type); + $ownerKey = $this->ownerKey ?? $instance->getKeyName(); + $query = $this->replayMacros($instance->newQuery()) ->mergeConstraintsFrom($this->getQuery()) ->with($this->getQuery()->getEagerLoads()); return $query->whereIn( - $instance->getTable().'.'.$instance->getKeyName(), $this->gatherKeysByType($type) + $instance->getTable().'.'.$ownerKey, $this->gatherKeysByType($type) )->get(); } @@ -178,8 +180,10 @@ public function match(array $models, Collection $results, $relation) protected function matchToMorphParents($type, Collection $results) { foreach ($results as $result) { - if (isset($this->dictionary[$type][$result->getKey()])) { - foreach ($this->dictionary[$type][$result->getKey()] as $model) { + $ownerKey = ! is_null($this->ownerKey) ? $result->{$this->ownerKey} : $result->getKey(); + + if (isset($this->dictionary[$type][$ownerKey])) { + foreach ($this->dictionary[$type][$ownerKey] as $model) { $model->setRelation($this->relation, $result); } } diff --git a/src/Illuminate/Database/Migrations/DatabaseMigrationRepository.php b/src/Illuminate/Database/Migrations/DatabaseMigrationRepository.php index b1685ffa3524..1ace1a6ff7e3 100755 --- a/src/Illuminate/Database/Migrations/DatabaseMigrationRepository.php +++ b/src/Illuminate/Database/Migrations/DatabaseMigrationRepository.php @@ -41,7 +41,7 @@ public function __construct(Resolver $resolver, $table) } /** - * Get the ran migrations. + * Get the completed migrations. * * @return array */ @@ -80,11 +80,24 @@ public function getLast() return $query->orderBy('migration', 'desc')->get()->all(); } + /** + * Get the completed migrations with their batch numbers. + * + * @return array + */ + public function getMigrationBatches() + { + return $this->table() + ->orderBy('batch', 'asc') + ->orderBy('migration', 'asc') + ->pluck('batch', 'migration')->all(); + } + /** * Log that a migration was run. * * @param string $file - * @param int $batch + * @param int $batch * @return void */ public function log($file, $batch) diff --git a/src/Illuminate/Database/Migrations/MigrationRepositoryInterface.php b/src/Illuminate/Database/Migrations/MigrationRepositoryInterface.php index 60bc921f8931..410326a9bd68 100755 --- a/src/Illuminate/Database/Migrations/MigrationRepositoryInterface.php +++ b/src/Illuminate/Database/Migrations/MigrationRepositoryInterface.php @@ -5,7 +5,7 @@ interface MigrationRepositoryInterface { /** - * Get the ran migrations for a given package. + * Get the completed migrations. * * @return array */ @@ -26,11 +26,18 @@ public function getMigrations($steps); */ public function getLast(); + /** + * Get the completed migrations with their batch numbers. + * + * @return array + */ + public function getMigrationBatches(); + /** * Log that a migration was run. * * @param string $file - * @param int $batch + * @param int $batch * @return void */ public function log($file, $batch); diff --git a/src/Illuminate/Database/Schema/Blueprint.php b/src/Illuminate/Database/Schema/Blueprint.php index 2b0251a78320..e27a2f103dfc 100755 --- a/src/Illuminate/Database/Schema/Blueprint.php +++ b/src/Illuminate/Database/Schema/Blueprint.php @@ -96,7 +96,7 @@ public function build(Connection $connection, Grammar $grammar) */ public function toSql(Connection $connection, Grammar $grammar) { - $this->addImpliedCommands(); + $this->addImpliedCommands($grammar); $statements = []; @@ -119,9 +119,10 @@ public function toSql(Connection $connection, Grammar $grammar) /** * Add the commands that are implied by the blueprint's state. * + * @param \Illuminate\Database\Grammar $grammer * @return void */ - protected function addImpliedCommands() + protected function addImpliedCommands(Grammar $grammar) { if (count($this->getAddedColumns()) > 0 && ! $this->creating()) { array_unshift($this->commands, $this->createCommand('add')); @@ -132,6 +133,8 @@ protected function addImpliedCommands() } $this->addFluentIndexes(); + + $this->addFluentCommands($grammar); } /** @@ -164,6 +167,31 @@ protected function addFluentIndexes() } } + /** + * Add the fluent commands specified on any columns. + * + * @param \Illuminate\Database\Grammar $grammer + * @param + */ + public function addFluentCommands(Grammar $grammar) + { + foreach ($this->columns as $column) { + foreach ($grammar->getFluentCommands() as $commandName) { + $attributeName = lcfirst($commandName); + + if (! isset($column->{$attributeName})) { + continue; + } + + $value = $column->{$attributeName}; + + $this->addCommand( + $commandName, compact('value', 'column') + ); + } + } + } + /** * Determine if the blueprint has a create command. * @@ -1046,11 +1074,11 @@ public function multiPolygon($column) */ public function morphs($name, $indexName = null) { - $this->unsignedInteger("{$name}_id"); - $this->string("{$name}_type"); - $this->index(["{$name}_id", "{$name}_type"], $indexName); + $this->unsignedInteger("{$name}_id"); + + $this->index(["{$name}_type", "{$name}_id"], $indexName); } /** @@ -1062,11 +1090,11 @@ public function morphs($name, $indexName = null) */ public function nullableMorphs($name, $indexName = null) { - $this->unsignedInteger("{$name}_id")->nullable(); - $this->string("{$name}_type")->nullable(); - $this->index(["{$name}_id", "{$name}_type"], $indexName); + $this->unsignedInteger("{$name}_id")->nullable(); + + $this->index(["{$name}_type", "{$name}_id"], $indexName); } /** diff --git a/src/Illuminate/Database/Schema/Grammars/Grammar.php b/src/Illuminate/Database/Schema/Grammars/Grammar.php index ddd38385710d..1ea4dabc8977 100755 --- a/src/Illuminate/Database/Schema/Grammars/Grammar.php +++ b/src/Illuminate/Database/Schema/Grammars/Grammar.php @@ -19,6 +19,13 @@ abstract class Grammar extends BaseGrammar */ protected $transactions = false; + /** + * The commands to be executed outside of create or alter command. + * + * @var array + */ + protected $fluentCommands = []; + /** * Compile a rename column command. * @@ -243,6 +250,16 @@ public function getDoctrineTableDiff(Blueprint $blueprint, SchemaManager $schema }); } + /** + * Get the fluent commands for the grammar. + * + * @return array + */ + public function getFluentCommands() + { + return $this->fluentCommands; + } + /** * Check if this Grammar supports schema changes wrapped in a transaction. * diff --git a/src/Illuminate/Database/Schema/Grammars/PostgresGrammar.php b/src/Illuminate/Database/Schema/Grammars/PostgresGrammar.php index 6dc12456831d..321da18f80e7 100755 --- a/src/Illuminate/Database/Schema/Grammars/PostgresGrammar.php +++ b/src/Illuminate/Database/Schema/Grammars/PostgresGrammar.php @@ -30,6 +30,13 @@ class PostgresGrammar extends Grammar */ protected $serials = ['bigInteger', 'integer', 'mediumInteger', 'smallInteger', 'tinyInteger']; + /** + * The commands to be executed outside of create or alter command. + * + * @var array + */ + protected $fluentCommands = ['Comment']; + /** * Compile the query to determine if a table exists. * @@ -324,6 +331,22 @@ public function compileDisableForeignKeyConstraints() return 'SET CONSTRAINTS ALL DEFERRED;'; } + /** + * Compile a comment command. + * + * @param \Illuminate\Database\Schema\Blueprint $blueprint + * @param \Illuminate\Support\Fluent $command + * @return string + */ + public function compileComment(Blueprint $blueprint, Fluent $command) + { + return sprintf('comment on column %s.%s is %s', + $this->wrapTable($blueprint), + $this->wrap($command->column->name), + "'".addslashes($command->value)."'" + ); + } + /** * Create the column definition for a char type. * diff --git a/src/Illuminate/Database/composer.json b/src/Illuminate/Database/composer.json index 153abad646f2..769327fa17fd 100644 --- a/src/Illuminate/Database/composer.json +++ b/src/Illuminate/Database/composer.json @@ -15,10 +15,10 @@ } ], "require": { - "php": ">=7.0", - "illuminate/container": "5.5.*", - "illuminate/contracts": "5.5.*", - "illuminate/support": "5.5.*" + "php": "^7.1.3", + "illuminate/container": "5.6.*", + "illuminate/contracts": "5.6.*", + "illuminate/support": "5.6.*" }, "autoload": { "psr-4": { @@ -27,16 +27,16 @@ }, "extra": { "branch-alias": { - "dev-master": "5.5-dev" + "dev-master": "5.6-dev" } }, "suggest": { "doctrine/dbal": "Required to rename columns and drop SQLite columns (~2.5).", "fzaninotto/faker": "Required to use the eloquent factory builder (~1.4).", - "illuminate/console": "Required to use the database commands (5.5.*).", - "illuminate/events": "Required to use the observers with Eloquent (5.5.*).", - "illuminate/filesystem": "Required to use the migrations (5.5.*).", - "illuminate/pagination": "Required to paginate the result set (5.5.*)." + "illuminate/console": "Required to use the database commands (5.6.*).", + "illuminate/events": "Required to use the observers with Eloquent (5.6.*).", + "illuminate/filesystem": "Required to use the migrations (5.6.*).", + "illuminate/pagination": "Required to paginate the result set (5.6.*)." }, "config": { "sort-packages": true diff --git a/src/Illuminate/Encryption/composer.json b/src/Illuminate/Encryption/composer.json index 0887e6fa152d..73486ababaf9 100644 --- a/src/Illuminate/Encryption/composer.json +++ b/src/Illuminate/Encryption/composer.json @@ -14,11 +14,11 @@ } ], "require": { - "php": ">=7.0", + "php": "^7.1.3", "ext-mbstring": "*", "ext-openssl": "*", - "illuminate/contracts": "5.5.*", - "illuminate/support": "5.5.*" + "illuminate/contracts": "5.6.*", + "illuminate/support": "5.6.*" }, "autoload": { "psr-4": { @@ -27,7 +27,7 @@ }, "extra": { "branch-alias": { - "dev-master": "5.5-dev" + "dev-master": "5.6-dev" } }, "config": { diff --git a/src/Illuminate/Events/composer.json b/src/Illuminate/Events/composer.json index 772cab000010..ceca48505b3f 100755 --- a/src/Illuminate/Events/composer.json +++ b/src/Illuminate/Events/composer.json @@ -14,10 +14,10 @@ } ], "require": { - "php": ">=7.0", - "illuminate/container": "5.5.*", - "illuminate/contracts": "5.5.*", - "illuminate/support": "5.5.*" + "php": "^7.1.3", + "illuminate/container": "5.6.*", + "illuminate/contracts": "5.6.*", + "illuminate/support": "5.6.*" }, "autoload": { "psr-4": { @@ -26,7 +26,7 @@ }, "extra": { "branch-alias": { - "dev-master": "5.5-dev" + "dev-master": "5.6-dev" } }, "config": { diff --git a/src/Illuminate/Filesystem/composer.json b/src/Illuminate/Filesystem/composer.json index 3f09194272eb..1a9cfe3f2eb9 100644 --- a/src/Illuminate/Filesystem/composer.json +++ b/src/Illuminate/Filesystem/composer.json @@ -14,9 +14,9 @@ } ], "require": { - "php": ">=7.0", - "illuminate/contracts": "5.5.*", - "illuminate/support": "5.5.*", + "php": "^7.1.3", + "illuminate/contracts": "5.6.*", + "illuminate/support": "5.6.*", "symfony/finder": "~3.3" }, "autoload": { @@ -26,7 +26,7 @@ }, "extra": { "branch-alias": { - "dev-master": "5.5-dev" + "dev-master": "5.6-dev" } }, "suggest": { diff --git a/src/Illuminate/Foundation/Application.php b/src/Illuminate/Foundation/Application.php index 7c7c8af5006b..14fc68965f03 100755 --- a/src/Illuminate/Foundation/Application.php +++ b/src/Illuminate/Foundation/Application.php @@ -29,7 +29,7 @@ class Application extends Container implements ApplicationContract, HttpKernelIn * * @var string */ - const VERSION = '5.5.20'; + const VERSION = '5.6-dev'; /** * The base path for the Laravel installation. @@ -524,7 +524,7 @@ public function detectEnvironment(Closure $callback) } /** - * Determine if we are running in the console. + * Determine if the application is running in the console. * * @return bool */ @@ -534,7 +534,7 @@ public function runningInConsole() } /** - * Determine if we are running unit tests. + * Determine if the application is running unit tests. * * @return bool */ @@ -1111,7 +1111,7 @@ public function registerCoreContainerAliases() 'filesystem' => [\Illuminate\Filesystem\FilesystemManager::class, \Illuminate\Contracts\Filesystem\Factory::class], 'filesystem.disk' => [\Illuminate\Contracts\Filesystem\Filesystem::class], 'filesystem.cloud' => [\Illuminate\Contracts\Filesystem\Cloud::class], - 'hash' => [\Illuminate\Contracts\Hashing\Hasher::class], + 'hash' => [\Illuminate\Hashing\HashManager::class], 'translator' => [\Illuminate\Translation\Translator::class, \Illuminate\Contracts\Translation\Translator::class], 'log' => [\Illuminate\Log\Writer::class, \Illuminate\Contracts\Logging\Log::class, \Psr\Log\LoggerInterface::class], 'mailer' => [\Illuminate\Mail\Mailer::class, \Illuminate\Contracts\Mail\Mailer::class, \Illuminate\Contracts\Mail\MailQueue::class], diff --git a/src/Illuminate/Foundation/Console/OptimizeCommand.php b/src/Illuminate/Foundation/Console/OptimizeCommand.php deleted file mode 100644 index 1694d5833db4..000000000000 --- a/src/Illuminate/Foundation/Console/OptimizeCommand.php +++ /dev/null @@ -1,47 +0,0 @@ - 'command.migrate.reset', 'MigrateRollback' => 'command.migrate.rollback', 'MigrateStatus' => 'command.migrate.status', - 'Optimize' => 'command.optimize', 'PackageDiscover' => 'command.package.discover', 'Preset' => 'command.preset', 'QueueFailed' => 'command.queue.failed', @@ -575,18 +573,6 @@ protected function registerNotificationMakeCommand() }); } - /** - * Register the command. - * - * @return void - */ - protected function registerOptimizeCommand() - { - $this->app->singleton('command.optimize', function ($app) { - return new OptimizeCommand($app['composer']); - }); - } - /** * Register the command. * diff --git a/src/Illuminate/Foundation/helpers.php b/src/Illuminate/Foundation/helpers.php index f3cbd85364df..864584a69450 100644 --- a/src/Illuminate/Foundation/helpers.php +++ b/src/Illuminate/Foundation/helpers.php @@ -185,15 +185,15 @@ function base_path($path = '') if (! function_exists('bcrypt')) { /** - * Hash the given value. + * Hash the given value against the bcrypt algorithm. * * @param string $value - * @param array $options + * @param array $options * @return string */ function bcrypt($value, $options = []) { - return app('hash')->make($value, $options); + return app('hash')->driver('bcrypt')->make($value, $options); } } diff --git a/src/Illuminate/Hashing/ArgonHasher.php b/src/Illuminate/Hashing/ArgonHasher.php new file mode 100644 index 000000000000..f6a4718c8f6a --- /dev/null +++ b/src/Illuminate/Hashing/ArgonHasher.php @@ -0,0 +1,160 @@ + $this->memory($options), + 'time_cost' => $this->time($options), + 'threads' => $this->processors($options), + ]); + + if ($hash === false) { + throw new RuntimeException('Argon2 hashing not supported.'); + } + + return $hash; + } + + /** + * Check the given plain value against a hash. + * + * @param string $value + * @param string $hashedValue + * @param array $options + * @return bool + */ + public function check($value, $hashedValue, array $options = []) + { + if (strlen($hashedValue) === 0) { + return false; + } + + return password_verify($value, $hashedValue); + } + + /** + * Check if the given hash has been hashed using the given options. + * + * @param string $hashedValue + * @param array $options + * @return bool + */ + public function needsRehash($hashedValue, array $options = []) + { + return password_needs_rehash($hashedValue, PASSWORD_ARGON2I, [ + 'memory_cost' => $this->memory($options), + 'time_cost' => $this->time($options), + 'threads' => $this->processors($options), + ]); + } + + /** + * Set the default password threads factor. + * + * @param int $threads + * + * @return $this; + */ + public function setProcessors(int $threads) + { + $this->threads = $threads; + + return $this; + } + + /** + * Set the default password memory factor. + * + * @param int $memory + * + * @return $this + */ + public function setMemory(int $memory) + { + $this->memory = $memory; + + return $this; + } + + /** + * Set the default password timing factor. + * + * @param int $time + * + * @return $this + */ + public function setTime(int $time) + { + $this->time = $time; + + return $this; + } + + /** + * Extract the memory cost value from the options array. + * + * @param $options + * @return int + */ + protected function memory($options) + { + return $options['memory'] ?? $this->memory; + } + + /** + * Extract the time cost value from the options array. + * + * @param $options + * @return int + */ + protected function time($options) + { + return $options['time'] ?? $this->time; + } + + /** + * Extract the threads value from the options array. + * + * @param $options + * @return int + */ + protected function processors($options) + { + return $options['processors'] ?? $this->processors; + } +} diff --git a/src/Illuminate/Hashing/HashManager.php b/src/Illuminate/Hashing/HashManager.php new file mode 100644 index 000000000000..3f51c184e730 --- /dev/null +++ b/src/Illuminate/Hashing/HashManager.php @@ -0,0 +1,76 @@ +driver()->make($value, $options); + } + + /** + * Check the given plain value against a hash. + * + * @param string $value + * @param string $hashedValue + * @param array $options + * @return bool + */ + public function check($value, $hashedValue, array $options = []) + { + return $this->driver()->check($value, $hashedValue, $options); + } + + /** + * Check if the given hash has been hashed using the given options. + * + * @param string $hashedValue + * @param array $options + * @return bool + */ + public function needsRehash($hashedValue, array $options = []) + { + return $this->driver()->needsRehash($hashedValue, $options); + } + + /** + * Get the default driver name. + * + * @return string + */ + public function getDefaultDriver() + { + return $this->app['config']['hashing.driver']; + } +} diff --git a/src/Illuminate/Hashing/HashServiceProvider.php b/src/Illuminate/Hashing/HashServiceProvider.php index 85581f40cf65..5b8d525463d9 100755 --- a/src/Illuminate/Hashing/HashServiceProvider.php +++ b/src/Illuminate/Hashing/HashServiceProvider.php @@ -20,8 +20,8 @@ class HashServiceProvider extends ServiceProvider */ public function register() { - $this->app->singleton('hash', function () { - return new BcryptHasher; + $this->app->singleton('hash', function ($app) { + return new HashManager($app); }); } diff --git a/src/Illuminate/Hashing/composer.json b/src/Illuminate/Hashing/composer.json index d727f86c9592..f7dae2f4408a 100755 --- a/src/Illuminate/Hashing/composer.json +++ b/src/Illuminate/Hashing/composer.json @@ -14,9 +14,9 @@ } ], "require": { - "php": ">=7.0", - "illuminate/contracts": "5.5.*", - "illuminate/support": "5.5.*" + "php": "^7.1.3", + "illuminate/contracts": "5.6.*", + "illuminate/support": "5.6.*" }, "autoload": { "psr-4": { @@ -25,7 +25,7 @@ }, "extra": { "branch-alias": { - "dev-master": "5.5-dev" + "dev-master": "5.6-dev" } }, "config": { diff --git a/src/Illuminate/Http/composer.json b/src/Illuminate/Http/composer.json index a634cd284c6d..2e9e91f130ae 100755 --- a/src/Illuminate/Http/composer.json +++ b/src/Illuminate/Http/composer.json @@ -14,9 +14,9 @@ } ], "require": { - "php": ">=7.0", - "illuminate/session": "5.5.*", - "illuminate/support": "5.5.*", + "php": "^7.1.3", + "illuminate/session": "5.6.*", + "illuminate/support": "5.6.*", "symfony/http-foundation": "~3.3", "symfony/http-kernel": "~3.3" }, @@ -27,7 +27,7 @@ }, "extra": { "branch-alias": { - "dev-master": "5.5-dev" + "dev-master": "5.6-dev" } }, "config": { diff --git a/src/Illuminate/Log/composer.json b/src/Illuminate/Log/composer.json index 5fe136438433..15f56f0182a3 100755 --- a/src/Illuminate/Log/composer.json +++ b/src/Illuminate/Log/composer.json @@ -14,9 +14,9 @@ } ], "require": { - "php": ">=7.0", - "illuminate/contracts": "5.5.*", - "illuminate/support": "5.5.*", + "php": "^7.1.3", + "illuminate/contracts": "5.6.*", + "illuminate/support": "5.6.*", "monolog/monolog": "~1.11" }, "autoload": { @@ -26,7 +26,7 @@ }, "extra": { "branch-alias": { - "dev-master": "5.5-dev" + "dev-master": "5.6-dev" } }, "config": { diff --git a/src/Illuminate/Mail/Events/MessageSending.php b/src/Illuminate/Mail/Events/MessageSending.php index 17bc25731dba..cff45213b2ae 100644 --- a/src/Illuminate/Mail/Events/MessageSending.php +++ b/src/Illuminate/Mail/Events/MessageSending.php @@ -11,14 +11,23 @@ class MessageSending */ public $message; + /** + * The message data. + * + * @var array + */ + public $data; + /** * Create a new event instance. * - * @param \Swift_Message $message + * @param \Swift_Message $message + * @param array $data * @return void */ - public function __construct($message) + public function __construct($message, $data = []) { + $this->data = $data; $this->message = $message; } } diff --git a/src/Illuminate/Mail/Events/MessageSent.php b/src/Illuminate/Mail/Events/MessageSent.php index 8af4a0e93388..9dee09c2f73c 100644 --- a/src/Illuminate/Mail/Events/MessageSent.php +++ b/src/Illuminate/Mail/Events/MessageSent.php @@ -11,14 +11,23 @@ class MessageSent */ public $message; + /** + * The message data. + * + * @var array + */ + public $data; + /** * Create a new event instance. * * @param \Swift_Message $message + * @param array $data * @return void */ - public function __construct($message) + public function __construct($message, $data = []) { + $this->data = $data; $this->message = $message; } } diff --git a/src/Illuminate/Mail/Mailer.php b/src/Illuminate/Mail/Mailer.php index f6508bc8744b..660834a14f27 100755 --- a/src/Illuminate/Mail/Mailer.php +++ b/src/Illuminate/Mail/Mailer.php @@ -231,10 +231,10 @@ public function send($view, array $data = [], $callback = null) // its recipients. We will then fire the sent event for the sent message. $swiftMessage = $message->getSwiftMessage(); - if ($this->shouldSendMessage($swiftMessage)) { + if ($this->shouldSendMessage($swiftMessage, $data)) { $this->sendSwiftMessage($swiftMessage); - $this->dispatchSentEvent($message); + $this->dispatchSentEvent($message, $data); } } @@ -458,16 +458,17 @@ protected function sendSwiftMessage($message) * Determines if the message can be sent. * * @param \Swift_Message $message + * @param array $data * @return bool */ - protected function shouldSendMessage($message) + protected function shouldSendMessage($message, $data = []) { if (! $this->events) { return true; } return $this->events->until( - new Events\MessageSending($message) + new Events\MessageSending($message, $data) ) !== false; } @@ -475,13 +476,14 @@ protected function shouldSendMessage($message) * Dispatch the message sent event. * * @param \Illuminate\Mail\Message $message + * @param array $data * @return void */ - protected function dispatchSentEvent($message) + protected function dispatchSentEvent($message, $data = []) { if ($this->events) { $this->events->dispatch( - new Events\MessageSent($message->getSwiftMessage()) + new Events\MessageSent($message->getSwiftMessage(), $data) ); } } diff --git a/src/Illuminate/Mail/composer.json b/src/Illuminate/Mail/composer.json index 6343a9234c73..c84186a563ca 100755 --- a/src/Illuminate/Mail/composer.json +++ b/src/Illuminate/Mail/composer.json @@ -14,11 +14,11 @@ } ], "require": { - "php": ">=7.0", + "php": "^7.1.3", "erusev/parsedown": "~1.6", - "illuminate/container": "5.5.*", - "illuminate/contracts": "5.5.*", - "illuminate/support": "5.5.*", + "illuminate/container": "5.6.*", + "illuminate/contracts": "5.6.*", + "illuminate/support": "5.6.*", "psr/log": "~1.0", "swiftmailer/swiftmailer": "~6.0", "tijsverkoyen/css-to-inline-styles": "~2.2" @@ -30,7 +30,7 @@ }, "extra": { "branch-alias": { - "dev-master": "5.5-dev" + "dev-master": "5.6-dev" } }, "suggest": { diff --git a/src/Illuminate/Notifications/composer.json b/src/Illuminate/Notifications/composer.json index 3e7264f9aa09..c1715cb2027e 100644 --- a/src/Illuminate/Notifications/composer.json +++ b/src/Illuminate/Notifications/composer.json @@ -14,15 +14,15 @@ } ], "require": { - "php": ">=7.0", - "illuminate/broadcasting": "5.5.*", - "illuminate/bus": "5.5.*", - "illuminate/container": "5.5.*", - "illuminate/contracts": "5.5.*", - "illuminate/filesystem": "5.5.*", - "illuminate/mail": "5.5.*", - "illuminate/queue": "5.5.*", - "illuminate/support": "5.5.*", + "php": "^7.1.3", + "illuminate/broadcasting": "5.6.*", + "illuminate/bus": "5.6.*", + "illuminate/container": "5.6.*", + "illuminate/contracts": "5.6.*", + "illuminate/filesystem": "5.6.*", + "illuminate/mail": "5.6.*", + "illuminate/queue": "5.6.*", + "illuminate/support": "5.6.*", "ramsey/uuid": "~3.0" }, "autoload": { @@ -32,12 +32,12 @@ }, "extra": { "branch-alias": { - "dev-master": "5.5-dev" + "dev-master": "5.6-dev" } }, "suggest": { "guzzlehttp/guzzle": "Required to use the Slack transport (~6.0)", - "illuminate/database": "Required to use the database transport (5.5.*).", + "illuminate/database": "Required to use the database transport (5.6.*).", "nexmo/client": "Required to use the Nexmo transport (~1.0)." }, "config": { diff --git a/src/Illuminate/Pagination/composer.json b/src/Illuminate/Pagination/composer.json index 48bcc06214af..433829cb730f 100755 --- a/src/Illuminate/Pagination/composer.json +++ b/src/Illuminate/Pagination/composer.json @@ -14,9 +14,9 @@ } ], "require": { - "php": ">=7.0", - "illuminate/contracts": "5.5.*", - "illuminate/support": "5.5.*" + "php": "^7.1.3", + "illuminate/contracts": "5.6.*", + "illuminate/support": "5.6.*" }, "autoload": { "psr-4": { @@ -25,7 +25,7 @@ }, "extra": { "branch-alias": { - "dev-master": "5.5-dev" + "dev-master": "5.6-dev" } }, "config": { diff --git a/src/Illuminate/Pipeline/composer.json b/src/Illuminate/Pipeline/composer.json index 3b85f815cb06..7e08e581ae2d 100644 --- a/src/Illuminate/Pipeline/composer.json +++ b/src/Illuminate/Pipeline/composer.json @@ -14,9 +14,9 @@ } ], "require": { - "php": ">=7.0", - "illuminate/contracts": "5.5.*", - "illuminate/support": "5.5.*" + "php": "^7.1.3", + "illuminate/contracts": "5.6.*", + "illuminate/support": "5.6.*" }, "autoload": { "psr-4": { @@ -25,7 +25,7 @@ }, "extra": { "branch-alias": { - "dev-master": "5.5-dev" + "dev-master": "5.6-dev" } }, "config": { diff --git a/src/Illuminate/Queue/Console/WorkCommand.php b/src/Illuminate/Queue/Console/WorkCommand.php index 750d13398be1..8d759c7d0983 100644 --- a/src/Illuminate/Queue/Console/WorkCommand.php +++ b/src/Illuminate/Queue/Console/WorkCommand.php @@ -168,8 +168,9 @@ protected function writeOutput(Job $job, $status) protected function writeStatus(Job $job, $status, $type) { $this->output->writeln(sprintf( - "<{$type}>[%s] %s %s", + "<{$type}>[%s][%s] %s %s", Carbon::now()->format('Y-m-d H:i:s'), + $job->getJobId(), str_pad("{$status}:", 11), $job->resolveName() )); } diff --git a/src/Illuminate/Queue/Jobs/Job.php b/src/Illuminate/Queue/Jobs/Job.php index 20b48222a485..93a020f53193 100755 --- a/src/Illuminate/Queue/Jobs/Job.php +++ b/src/Illuminate/Queue/Jobs/Job.php @@ -55,6 +55,13 @@ abstract class Job */ protected $queue; + /** + * Get the job identifier. + * + * @return string + */ + abstract public function getJobId(); + /** * Get the raw body of the job. * diff --git a/src/Illuminate/Queue/SerializesAndRestoresModelIdentifiers.php b/src/Illuminate/Queue/SerializesAndRestoresModelIdentifiers.php index 6bb677aee8ac..9dff64495c99 100644 --- a/src/Illuminate/Queue/SerializesAndRestoresModelIdentifiers.php +++ b/src/Illuminate/Queue/SerializesAndRestoresModelIdentifiers.php @@ -21,6 +21,7 @@ protected function getSerializedPropertyValue($value) return new ModelIdentifier( $value->getQueueableClass(), $value->getQueueableIds(), + $value->getQueueableRelations(), $value->getQueueableConnection() ); } @@ -29,6 +30,7 @@ protected function getSerializedPropertyValue($value) return new ModelIdentifier( get_class($value), $value->getQueueableId(), + $value->getQueueableRelations(), $value->getQueueableConnection() ); } @@ -50,8 +52,7 @@ protected function getRestoredPropertyValue($value) return is_array($value->id) ? $this->restoreCollection($value) - : $this->getQueryForModelRestoration((new $value->class)->setConnection($value->connection)) - ->useWritePdo()->findOrFail($value->id); + : $this->restoreModel($value); } /** @@ -72,6 +73,19 @@ protected function restoreCollection($value) ->whereIn($model->getQualifiedKeyName(), $value->id)->get(); } + /** + * @param \Illuminate\Contracts\Database\ModelIdentifier $value + * @return \Illuminate\Database\Eloquent\Model + */ + public function restoreModel($value) + { + $model = $this->getQueryForModelRestoration((new $value->class) + ->setConnection($value->connection)) + ->useWritePdo()->findOrFail($value->id); + + return $model->load($value->relations); + } + /** * Get the query for restoration. * diff --git a/src/Illuminate/Queue/Worker.php b/src/Illuminate/Queue/Worker.php index 8e568d957abd..e699a1ac292e 100644 --- a/src/Illuminate/Queue/Worker.php +++ b/src/Illuminate/Queue/Worker.php @@ -84,7 +84,9 @@ public function __construct(QueueManager $manager, */ public function daemon($connectionName, $queue, WorkerOptions $options) { - $this->listenForSignals(); + if ($this->supportsAsyncSignals()) { + $this->listenForSignals(); + } $lastRestart = $this->getTimestampOfLastQueueRestart(); @@ -105,7 +107,9 @@ public function daemon($connectionName, $queue, WorkerOptions $options) $this->manager->connection($connectionName), $queue ); - $this->registerTimeoutHandler($job, $options); + if ($this->supportsAsyncSignals()) { + $this->registerTimeoutHandler($job, $options); + } // If the daemon should run (not in maintenance mode, etc.), then we can run // fire off this job for processing. Otherwise, we will need to sleep the @@ -124,7 +128,7 @@ public function daemon($connectionName, $queue, WorkerOptions $options) } /** - * Register the worker timeout handler (PHP 7.1+). + * Register the worker timeout handler. * * @param \Illuminate\Contracts\Queue\Job|null $job * @param \Illuminate\Queue\WorkerOptions $options @@ -132,18 +136,16 @@ public function daemon($connectionName, $queue, WorkerOptions $options) */ protected function registerTimeoutHandler($job, WorkerOptions $options) { - if ($this->supportsAsyncSignals()) { - // We will register a signal handler for the alarm signal so that we can kill this - // process if it is running too long because it has frozen. This uses the async - // signals supported in recent versions of PHP to accomplish it conveniently. - pcntl_signal(SIGALRM, function () { - $this->kill(1); - }); - - pcntl_alarm( - max($this->timeoutForJob($job, $options), 0) - ); - } + // We will register a signal handler for the alarm signal so that we can kill this + // process if it is running too long because it has frozen. This uses the async + // signals supported in recent versions of PHP to accomplish it conveniently. + pcntl_signal(SIGALRM, function () { + $this->kill(1); + }); + + pcntl_alarm( + max($this->timeoutForJob($job, $options), 0) + ); } /** @@ -476,21 +478,6 @@ protected function raiseExceptionOccurredJobEvent($connectionName, $job, $e) )); } - /** - * Raise the failed queue job event. - * - * @param string $connectionName - * @param \Illuminate\Contracts\Queue\Job $job - * @param \Exception $e - * @return void - */ - protected function raiseFailedJobEvent($connectionName, $job, $e) - { - $this->events->dispatch(new Events\JobFailed( - $connectionName, $job, $e - )); - } - /** * Determine if the queue worker should restart. * @@ -521,21 +508,19 @@ protected function getTimestampOfLastQueueRestart() */ protected function listenForSignals() { - if ($this->supportsAsyncSignals()) { - pcntl_async_signals(true); + pcntl_async_signals(true); - pcntl_signal(SIGTERM, function () { - $this->shouldQuit = true; - }); + pcntl_signal(SIGTERM, function () { + $this->shouldQuit = true; + }); - pcntl_signal(SIGUSR2, function () { - $this->paused = true; - }); + pcntl_signal(SIGUSR2, function () { + $this->paused = true; + }); - pcntl_signal(SIGCONT, function () { - $this->paused = false; - }); - } + pcntl_signal(SIGCONT, function () { + $this->paused = false; + }); } /** @@ -545,8 +530,7 @@ protected function listenForSignals() */ protected function supportsAsyncSignals() { - return version_compare(PHP_VERSION, '7.1.0') >= 0 && - extension_loaded('pcntl'); + return extension_loaded('pcntl'); } /** diff --git a/src/Illuminate/Queue/composer.json b/src/Illuminate/Queue/composer.json index 8d1edc88888e..d1a5b7739eb6 100644 --- a/src/Illuminate/Queue/composer.json +++ b/src/Illuminate/Queue/composer.json @@ -14,13 +14,13 @@ } ], "require": { - "php": ">=7.0", - "illuminate/console": "5.5.*", - "illuminate/container": "5.5.*", - "illuminate/contracts": "5.5.*", - "illuminate/database": "5.5.*", - "illuminate/filesystem": "5.5.*", - "illuminate/support": "5.5.*", + "php": "^7.1.3", + "illuminate/console": "5.6.*", + "illuminate/container": "5.6.*", + "illuminate/contracts": "5.6.*", + "illuminate/database": "5.6.*", + "illuminate/filesystem": "5.6.*", + "illuminate/support": "5.6.*", "symfony/debug": "~3.3", "symfony/process": "~3.3" }, @@ -31,14 +31,14 @@ }, "extra": { "branch-alias": { - "dev-master": "5.5-dev" + "dev-master": "5.6-dev" } }, "suggest": { "ext-pcntl": "Required to use all features of the queue worker.", "ext-posix": "Required to use all features of the queue worker.", "aws/aws-sdk-php": "Required to use the SQS queue driver (~3.0).", - "illuminate/redis": "Required to use the Redis queue driver (5.5.*).", + "illuminate/redis": "Required to use the Redis queue driver (5.6.*).", "pda/pheanstalk": "Required to use the Beanstalk queue driver (~3.0)." }, "config": { diff --git a/src/Illuminate/Redis/composer.json b/src/Illuminate/Redis/composer.json index 741a13ed4fd1..ee8bae7d5d23 100755 --- a/src/Illuminate/Redis/composer.json +++ b/src/Illuminate/Redis/composer.json @@ -14,9 +14,9 @@ } ], "require": { - "php": ">=7.0", - "illuminate/contracts": "5.5.*", - "illuminate/support": "5.5.*", + "php": "^7.1.3", + "illuminate/contracts": "5.6.*", + "illuminate/support": "5.6.*", "predis/predis": "~1.0" }, "autoload": { @@ -26,7 +26,7 @@ }, "extra": { "branch-alias": { - "dev-master": "5.5-dev" + "dev-master": "5.6-dev" } }, "config": { diff --git a/src/Illuminate/Routing/Router.php b/src/Illuminate/Routing/Router.php index 0096935bf5a5..3972ef5ddb76 100644 --- a/src/Illuminate/Routing/Router.php +++ b/src/Illuminate/Routing/Router.php @@ -11,6 +11,7 @@ use Illuminate\Http\JsonResponse; use Illuminate\Support\Collection; use Illuminate\Container\Container; +use Illuminate\Database\Eloquent\Model; use Illuminate\Support\Traits\Macroable; use Illuminate\Contracts\Support\Jsonable; use Illuminate\Contracts\Events\Dispatcher; @@ -713,6 +714,8 @@ public static function toResponse($request, $response) if ($response instanceof PsrResponseInterface) { $response = (new HttpFoundationFactory)->createResponse($response); + } elseif ($response instanceof Model && $response->wasRecentlyCreated) { + $response = new JsonResponse($response, 201); } elseif (! $response instanceof SymfonyResponse && ($response instanceof Arrayable || $response instanceof Jsonable || diff --git a/src/Illuminate/Routing/composer.json b/src/Illuminate/Routing/composer.json index 7b12355cd7c8..6f97d34a2ca4 100644 --- a/src/Illuminate/Routing/composer.json +++ b/src/Illuminate/Routing/composer.json @@ -14,13 +14,13 @@ } ], "require": { - "php": ">=7.0", - "illuminate/container": "5.5.*", - "illuminate/contracts": "5.5.*", - "illuminate/http": "5.5.*", - "illuminate/pipeline": "5.5.*", - "illuminate/session": "5.5.*", - "illuminate/support": "5.5.*", + "php": "^7.1.3", + "illuminate/container": "5.6.*", + "illuminate/contracts": "5.6.*", + "illuminate/http": "5.6.*", + "illuminate/pipeline": "5.6.*", + "illuminate/session": "5.6.*", + "illuminate/support": "5.6.*", "symfony/debug": "~3.3", "symfony/http-foundation": "~3.3", "symfony/http-kernel": "~3.3", @@ -33,11 +33,11 @@ }, "extra": { "branch-alias": { - "dev-master": "5.5-dev" + "dev-master": "5.6-dev" } }, "suggest": { - "illuminate/console": "Required to use the make commands (5.5.*).", + "illuminate/console": "Required to use the make commands (5.6.*).", "symfony/psr-http-message-bridge": "Required to psr7 bridging features (~1.0)." }, "config": { diff --git a/src/Illuminate/Session/composer.json b/src/Illuminate/Session/composer.json index a854c506b2b4..47aadbe567fb 100755 --- a/src/Illuminate/Session/composer.json +++ b/src/Illuminate/Session/composer.json @@ -14,10 +14,10 @@ } ], "require": { - "php": ">=7.0", - "illuminate/contracts": "5.5.*", - "illuminate/filesystem": "5.5.*", - "illuminate/support": "5.5.*", + "php": "^7.1.3", + "illuminate/contracts": "5.6.*", + "illuminate/filesystem": "5.6.*", + "illuminate/support": "5.6.*", "symfony/finder": "~3.3", "symfony/http-foundation": "~3.3" }, @@ -28,11 +28,11 @@ }, "extra": { "branch-alias": { - "dev-master": "5.5-dev" + "dev-master": "5.6-dev" } }, "suggest": { - "illuminate/console": "Required to use the session:table command (5.5.*)." + "illuminate/console": "Required to use the session:table command (5.6.*)." }, "config": { "sort-packages": true diff --git a/src/Illuminate/Support/Arr.php b/src/Illuminate/Support/Arr.php index a9e09ce81287..df9f8a142eee 100755 --- a/src/Illuminate/Support/Arr.php +++ b/src/Illuminate/Support/Arr.php @@ -594,13 +594,17 @@ public static function where($array, callable $callback) } /** - * If the given value is not an array, wrap it in one. + * If the given value is not an array and not null, wrap it in one. * * @param mixed $value * @return array */ public static function wrap($value) { + if (is_null($value)) { + return []; + } + return ! is_array($value) ? [$value] : $value; } } diff --git a/src/Illuminate/Support/Collection.php b/src/Illuminate/Support/Collection.php index 13898792cbbd..22a0f3cdadb9 100644 --- a/src/Illuminate/Support/Collection.php +++ b/src/Illuminate/Support/Collection.php @@ -1482,10 +1482,6 @@ public function transform(callable $callback) */ public function unique($key = null, $strict = false) { - if (is_null($key)) { - return new static(array_unique($this->items, SORT_REGULAR)); - } - $callback = $this->valueRetriever($key); $exists = []; diff --git a/src/Illuminate/Support/composer.json b/src/Illuminate/Support/composer.json index 172303dc4c19..36a4821b3b75 100644 --- a/src/Illuminate/Support/composer.json +++ b/src/Illuminate/Support/composer.json @@ -14,10 +14,10 @@ } ], "require": { - "php": ">=7.0", + "php": "^7.1.3", "ext-mbstring": "*", "doctrine/inflector": "~1.1", - "illuminate/contracts": "5.5.*", + "illuminate/contracts": "5.6.*", "nesbot/carbon": "^1.20" }, "replace": { @@ -33,7 +33,7 @@ }, "extra": { "branch-alias": { - "dev-master": "5.5-dev" + "dev-master": "5.6-dev" } }, "suggest": { diff --git a/src/Illuminate/Translation/composer.json b/src/Illuminate/Translation/composer.json index b84b17fde1d1..4b01b280a826 100755 --- a/src/Illuminate/Translation/composer.json +++ b/src/Illuminate/Translation/composer.json @@ -14,10 +14,10 @@ } ], "require": { - "php": ">=7.0", - "illuminate/contracts": "5.5.*", - "illuminate/filesystem": "5.5.*", - "illuminate/support": "5.5.*" + "php": "^7.1.3", + "illuminate/contracts": "5.6.*", + "illuminate/filesystem": "5.6.*", + "illuminate/support": "5.6.*" }, "autoload": { "psr-4": { @@ -26,7 +26,7 @@ }, "extra": { "branch-alias": { - "dev-master": "5.5-dev" + "dev-master": "5.6-dev" } }, "config": { diff --git a/src/Illuminate/Validation/Concerns/ValidatesAttributes.php b/src/Illuminate/Validation/Concerns/ValidatesAttributes.php index f75736247181..166d5e624241 100644 --- a/src/Illuminate/Validation/Concerns/ValidatesAttributes.php +++ b/src/Illuminate/Validation/Concerns/ValidatesAttributes.php @@ -447,6 +447,10 @@ public function validateDigitsBetween($attribute, $value, $parameters) */ public function validateDimensions($attribute, $value, $parameters) { + if ($this->isValidFileInstance($value) && $value->getClientMimeType() == 'image/svg+xml') { + return true; + } + if (! $this->isValidFileInstance($value) || ! $sizeDetails = @getimagesize($value->getRealPath())) { return false; } diff --git a/src/Illuminate/Validation/composer.json b/src/Illuminate/Validation/composer.json index a026981bb818..d51ddffc84e0 100755 --- a/src/Illuminate/Validation/composer.json +++ b/src/Illuminate/Validation/composer.json @@ -14,11 +14,11 @@ } ], "require": { - "php": ">=7.0", - "illuminate/container": "5.5.*", - "illuminate/contracts": "5.5.*", - "illuminate/support": "5.5.*", - "illuminate/translation": "5.5.*", + "php": "^7.1.3", + "illuminate/container": "5.6.*", + "illuminate/contracts": "5.6.*", + "illuminate/support": "5.6.*", + "illuminate/translation": "5.6.*", "symfony/http-foundation": "~3.3" }, "autoload": { @@ -28,11 +28,11 @@ }, "extra": { "branch-alias": { - "dev-master": "5.5-dev" + "dev-master": "5.6-dev" } }, "suggest": { - "illuminate/database": "Required to use the database presence verifier (5.5.*)." + "illuminate/database": "Required to use the database presence verifier (5.6.*)." }, "config": { "sort-packages": true diff --git a/src/Illuminate/View/composer.json b/src/Illuminate/View/composer.json index 142c75593ae0..fe4c57e0719b 100644 --- a/src/Illuminate/View/composer.json +++ b/src/Illuminate/View/composer.json @@ -14,12 +14,12 @@ } ], "require": { - "php": ">=7.0", - "illuminate/container": "5.5.*", - "illuminate/contracts": "5.5.*", - "illuminate/events": "5.5.*", - "illuminate/filesystem": "5.5.*", - "illuminate/support": "5.5.*", + "php": "^7.1.3", + "illuminate/container": "5.6.*", + "illuminate/contracts": "5.6.*", + "illuminate/events": "5.6.*", + "illuminate/filesystem": "5.6.*", + "illuminate/support": "5.6.*", "symfony/debug": "~3.3" }, "autoload": { @@ -29,7 +29,7 @@ }, "extra": { "branch-alias": { - "dev-master": "5.5-dev" + "dev-master": "5.6-dev" } }, "config": { diff --git a/tests/Console/ConsoleApplicationTest.php b/tests/Console/ConsoleApplicationTest.php index a5924311c642..76b658339267 100755 --- a/tests/Console/ConsoleApplicationTest.php +++ b/tests/Console/ConsoleApplicationTest.php @@ -47,7 +47,7 @@ public function testResolveAddsCommandViaApplicationResolution() protected function getMockConsole(array $methods) { - $app = m::mock('Illuminate\Contracts\Foundation\Application', ['version' => '5.5']); + $app = m::mock('Illuminate\Contracts\Foundation\Application', ['version' => '5.6']); $events = m::mock('Illuminate\Contracts\Events\Dispatcher', ['dispatch' => null]); $console = $this->getMockBuilder('Illuminate\Console\Application')->setMethods($methods)->setConstructorArgs([ diff --git a/tests/Console/ConsoleScheduledEventTest.php b/tests/Console/ConsoleScheduledEventTest.php index 7fe250ce4dc4..ddd3b9b95170 100644 --- a/tests/Console/ConsoleScheduledEventTest.php +++ b/tests/Console/ConsoleScheduledEventTest.php @@ -36,7 +36,7 @@ public function testBasicCronCompilation() $app->shouldReceive('environment')->andReturn('production'); $event = new Event(m::mock('Illuminate\Console\Scheduling\Mutex'), 'php foo'); - $this->assertEquals('* * * * * *', $event->getExpression()); + $this->assertEquals('* * * * *', $event->getExpression()); $this->assertTrue($event->isDue($app)); $this->assertTrue($event->skip(function () { return true; @@ -46,17 +46,17 @@ public function testBasicCronCompilation() })->filtersPass($app)); $event = new Event(m::mock('Illuminate\Console\Scheduling\Mutex'), 'php foo'); - $this->assertEquals('* * * * * *', $event->getExpression()); + $this->assertEquals('* * * * *', $event->getExpression()); $this->assertFalse($event->environments('local')->isDue($app)); $event = new Event(m::mock('Illuminate\Console\Scheduling\Mutex'), 'php foo'); - $this->assertEquals('* * * * * *', $event->getExpression()); + $this->assertEquals('* * * * *', $event->getExpression()); $this->assertFalse($event->when(function () { return false; })->filtersPass($app)); $event = new Event(m::mock('Illuminate\Console\Scheduling\Mutex'), 'php foo'); - $this->assertEquals('* * * * * *', $event->getExpression()); + $this->assertEquals('* * * * *', $event->getExpression()); $this->assertFalse($event->when(false)->filtersPass($app)); // chained rules should be commutative @@ -81,11 +81,11 @@ public function testEventIsDueCheck() Carbon::setTestNow(Carbon::create(2015, 1, 1, 0, 0, 0)); $event = new Event(m::mock('Illuminate\Console\Scheduling\Mutex'), 'php foo'); - $this->assertEquals('* * * * 4 *', $event->thursdays()->getExpression()); + $this->assertEquals('* * * * 4', $event->thursdays()->getExpression()); $this->assertTrue($event->isDue($app)); $event = new Event(m::mock('Illuminate\Console\Scheduling\Mutex'), 'php foo'); - $this->assertEquals('0 19 * * 3 *', $event->wednesdays()->at('19:00')->timezone('EST')->getExpression()); + $this->assertEquals('0 19 * * 3', $event->wednesdays()->at('19:00')->timezone('EST')->getExpression()); $this->assertTrue($event->isDue($app)); } diff --git a/tests/Console/Scheduling/EventTest.php b/tests/Console/Scheduling/EventTest.php index af9b0d382ecf..bc3e9df29509 100644 --- a/tests/Console/Scheduling/EventTest.php +++ b/tests/Console/Scheduling/EventTest.php @@ -28,7 +28,7 @@ public function testBuildCommand() $event->runInBackground(); $defaultOutput = (DIRECTORY_SEPARATOR == '\\') ? 'NUL' : '/dev/null'; - $this->assertSame("(php -i > {$quote}{$defaultOutput}{$quote} 2>&1 ; '".PHP_BINARY."' artisan schedule:finish \"framework/schedule-c65b1c374c37056e0c57fccb0c08d724ce6f5043\") > {$quote}{$defaultOutput}{$quote} 2>&1 &", $event->buildCommand()); + $this->assertSame("(php -i > {$quote}{$defaultOutput}{$quote} 2>&1 ; '".PHP_BINARY."' artisan schedule:finish \"framework/schedule-eeb46c93d45e928d62aaf684d727e213b7094822\") > {$quote}{$defaultOutput}{$quote} 2>&1 &", $event->buildCommand()); } public function testBuildCommandSendOutputTo() diff --git a/tests/Console/Scheduling/FrequencyTest.php b/tests/Console/Scheduling/FrequencyTest.php index 8a12a7940263..e9738115c337 100644 --- a/tests/Console/Scheduling/FrequencyTest.php +++ b/tests/Console/Scheduling/FrequencyTest.php @@ -23,99 +23,99 @@ public function setUp() public function testEveryMinute() { - $this->assertEquals('* * * * * *', $this->event->getExpression()); - $this->assertEquals('* * * * * *', $this->event->everyMinute()->getExpression()); + $this->assertEquals('* * * * *', $this->event->getExpression()); + $this->assertEquals('* * * * *', $this->event->everyMinute()->getExpression()); } public function testEveryFiveMinutes() { - $this->assertEquals('*/5 * * * * *', $this->event->everyFiveMinutes()->getExpression()); + $this->assertEquals('*/5 * * * *', $this->event->everyFiveMinutes()->getExpression()); } public function testDaily() { - $this->assertEquals('0 0 * * * *', $this->event->daily()->getExpression()); + $this->assertEquals('0 0 * * *', $this->event->daily()->getExpression()); } public function testTwiceDaily() { - $this->assertEquals('0 3,15 * * * *', $this->event->twiceDaily(3, 15)->getExpression()); + $this->assertEquals('0 3,15 * * *', $this->event->twiceDaily(3, 15)->getExpression()); } public function testOverrideWithHourly() { - $this->assertEquals('0 * * * * *', $this->event->everyFiveMinutes()->hourly()->getExpression()); - $this->assertEquals('37 * * * * *', $this->event->hourlyAt(37)->getExpression()); + $this->assertEquals('0 * * * *', $this->event->everyFiveMinutes()->hourly()->getExpression()); + $this->assertEquals('37 * * * *', $this->event->hourlyAt(37)->getExpression()); } public function testMonthlyOn() { - $this->assertEquals('0 15 4 * * *', $this->event->monthlyOn(4, '15:00')->getExpression()); + $this->assertEquals('0 15 4 * *', $this->event->monthlyOn(4, '15:00')->getExpression()); } public function testTwiceMonthly() { - $this->assertEquals('0 0 1,16 * * *', $this->event->twiceMonthly(1, 16)->getExpression()); + $this->assertEquals('0 0 1,16 * *', $this->event->twiceMonthly(1, 16)->getExpression()); } public function testMonthlyOnWithMinutes() { - $this->assertEquals('15 15 4 * * *', $this->event->monthlyOn(4, '15:15')->getExpression()); + $this->assertEquals('15 15 4 * *', $this->event->monthlyOn(4, '15:15')->getExpression()); } public function testWeekdaysDaily() { - $this->assertEquals('0 0 * * 1-5 *', $this->event->weekdays()->daily()->getExpression()); + $this->assertEquals('0 0 * * 1-5', $this->event->weekdays()->daily()->getExpression()); } public function testWeekdaysHourly() { - $this->assertEquals('0 * * * 1-5 *', $this->event->weekdays()->hourly()->getExpression()); + $this->assertEquals('0 * * * 1-5', $this->event->weekdays()->hourly()->getExpression()); } public function testWeekdays() { - $this->assertEquals('* * * * 1-5 *', $this->event->weekdays()->getExpression()); + $this->assertEquals('* * * * 1-5', $this->event->weekdays()->getExpression()); } public function testSundays() { - $this->assertEquals('* * * * 0 *', $this->event->sundays()->getExpression()); + $this->assertEquals('* * * * 0', $this->event->sundays()->getExpression()); } public function testMondays() { - $this->assertEquals('* * * * 1 *', $this->event->mondays()->getExpression()); + $this->assertEquals('* * * * 1', $this->event->mondays()->getExpression()); } public function testTuesdays() { - $this->assertEquals('* * * * 2 *', $this->event->tuesdays()->getExpression()); + $this->assertEquals('* * * * 2', $this->event->tuesdays()->getExpression()); } public function testWednesdays() { - $this->assertEquals('* * * * 3 *', $this->event->wednesdays()->getExpression()); + $this->assertEquals('* * * * 3', $this->event->wednesdays()->getExpression()); } public function testThursdays() { - $this->assertEquals('* * * * 4 *', $this->event->thursdays()->getExpression()); + $this->assertEquals('* * * * 4', $this->event->thursdays()->getExpression()); } public function testFridays() { - $this->assertEquals('* * * * 5 *', $this->event->fridays()->getExpression()); + $this->assertEquals('* * * * 5', $this->event->fridays()->getExpression()); } public function testSaturdays() { - $this->assertEquals('* * * * 6 *', $this->event->saturdays()->getExpression()); + $this->assertEquals('* * * * 6', $this->event->saturdays()->getExpression()); } public function testQuarterly() { - $this->assertEquals('0 0 1 1-12/3 * *', $this->event->quarterly()->getExpression()); + $this->assertEquals('0 0 1 1-12/3 *', $this->event->quarterly()->getExpression()); } public function testFrequencyMacro() @@ -124,6 +124,6 @@ public function testFrequencyMacro() return $this->spliceIntoPosition(1, "*/{$x}"); }); - $this->assertEquals('*/6 * * * * *', $this->event->everyXMinutes(6)->getExpression()); + $this->assertEquals('*/6 * * * *', $this->event->everyXMinutes(6)->getExpression()); } } diff --git a/tests/Container/ContainerTest.php b/tests/Container/ContainerTest.php index 23159e32a7a6..c8bb3896d7fd 100755 --- a/tests/Container/ContainerTest.php +++ b/tests/Container/ContainerTest.php @@ -563,6 +563,23 @@ public function testCallWithBoundMethod() $this->assertEquals(['foo', 'bar'], $result); } + public function testBindMethodAcceptsAnArray() + { + $container = new Container; + $container->bindMethod([\Illuminate\Tests\Container\ContainerTestCallStub::class, 'unresolvable'], function ($stub) { + return $stub->unresolvable('foo', 'bar'); + }); + $result = $container->call('Illuminate\Tests\Container\ContainerTestCallStub@unresolvable'); + $this->assertEquals(['foo', 'bar'], $result); + + $container = new Container; + $container->bindMethod([\Illuminate\Tests\Container\ContainerTestCallStub::class, 'unresolvable'], function ($stub) { + return $stub->unresolvable('foo', 'bar'); + }); + $result = $container->call([new ContainerTestCallStub, 'unresolvable']); + $this->assertEquals(['foo', 'bar'], $result); + } + public function testContainerCanInjectDifferentImplementationsDependingOnContext() { $container = new Container; diff --git a/tests/Database/DatabasePostgresSchemaGrammarTest.php b/tests/Database/DatabasePostgresSchemaGrammarTest.php index 194287a31153..4518b6c11e32 100755 --- a/tests/Database/DatabasePostgresSchemaGrammarTest.php +++ b/tests/Database/DatabasePostgresSchemaGrammarTest.php @@ -33,6 +33,19 @@ public function testBasicCreateTable() $this->assertEquals('alter table "users" add column "id" serial primary key not null, add column "email" varchar(255) not null', $statements[0]); } + public function testCreateTableAndCommentColumn() + { + $blueprint = new Blueprint('users'); + $blueprint->create(); + $blueprint->increments('id'); + $blueprint->string('email')->comment('my first comment'); + $statements = $blueprint->toSql($this->getConnection(), $this->getGrammar()); + + $this->assertCount(2, $statements); + $this->assertEquals('create table "users" ("id" serial primary key not null, "email" varchar(255) not null)', $statements[0]); + $this->assertEquals('comment on column "users"."email" is \'my first comment\'', $statements[1]); + } + public function testDropTable() { $blueprint = new Blueprint('users'); diff --git a/tests/Hashing/BcryptHasherTest.php b/tests/Hashing/BcryptHasherTest.php deleted file mode 100755 index e223b71dc4a7..000000000000 --- a/tests/Hashing/BcryptHasherTest.php +++ /dev/null @@ -1,18 +0,0 @@ -make('password'); - $this->assertNotSame('password', $value); - $this->assertTrue($hasher->check('password', $value)); - $this->assertFalse($hasher->needsRehash($value)); - $this->assertTrue($hasher->needsRehash($value, ['rounds' => 1])); - } -} diff --git a/tests/Hashing/HasherTest.php b/tests/Hashing/HasherTest.php new file mode 100755 index 000000000000..1ac9d34089d6 --- /dev/null +++ b/tests/Hashing/HasherTest.php @@ -0,0 +1,32 @@ +make('password'); + $this->assertNotSame('password', $value); + $this->assertTrue($hasher->check('password', $value)); + $this->assertFalse($hasher->needsRehash($value)); + $this->assertTrue($hasher->needsRehash($value, ['rounds' => 1])); + } + + public function testBasicArgonHashing() + { + if (! defined('PASSWORD_ARGON2I')) { + $this->markTestSkipped('PHP not compiled with argon2 hashing support support.'); + } + + $hasher = new \Illuminate\Hashing\ArgonHasher; + $value = $hasher->make('password'); + $this->assertNotSame('password', $value); + $this->assertTrue($hasher->check('password', $value)); + $this->assertFalse($hasher->needsRehash($value)); + $this->assertTrue($hasher->needsRehash($value, ['processors' => 1])); + } +} diff --git a/tests/Integration/Auth/AuthenticationTest.php b/tests/Integration/Auth/AuthenticationTest.php index 7faea9f38a84..475a8c5bb84e 100644 --- a/tests/Integration/Auth/AuthenticationTest.php +++ b/tests/Integration/Auth/AuthenticationTest.php @@ -24,6 +24,8 @@ protected function getEnvironmentSetUp($app) 'database' => ':memory:', 'prefix' => '', ]); + + $app['config']->set('hashing', ['driver' => 'bcrypt']); } public function setUp() diff --git a/tests/Integration/Database/EloquentModelRefreshTest.php b/tests/Integration/Database/EloquentModelRefreshTest.php index 9687f5d32805..aa4b9828c7f1 100644 --- a/tests/Integration/Database/EloquentModelRefreshTest.php +++ b/tests/Integration/Database/EloquentModelRefreshTest.php @@ -63,6 +63,22 @@ public function it_refreshes_a_soft_deleted_model() $this->assertTrue($post->trashed()); } + + /** + * @test + */ + public function it_syncs_original_on_refresh() + { + $post = Post::create(['title' => 'pat']); + + Post::find($post->id)->update(['title' => 'patrick']); + + $post->refresh(); + + $this->assertEmpty($post->getDirty()); + + $this->assertEquals('patrick', $post->getOriginal('title')); + } } class Post extends Model diff --git a/tests/Integration/Http/ThrottleRequestsTest.php b/tests/Integration/Http/ThrottleRequestsTest.php index 824427842e34..45c5b7e9c420 100644 --- a/tests/Integration/Http/ThrottleRequestsTest.php +++ b/tests/Integration/Http/ThrottleRequestsTest.php @@ -19,6 +19,11 @@ public function tearDown() Carbon::setTestNow(null); } + public function getEnvironmentSetUp($app) + { + $app['config']->set('hashing', ['driver' => 'bcrypt']); + } + public function test_lock_opens_immediately_after_decay() { Carbon::setTestNow(null); diff --git a/tests/Integration/Http/ThrottleRequestsWithRedisTest.php b/tests/Integration/Http/ThrottleRequestsWithRedisTest.php index 56da516882a6..ba99a9a4b444 100644 --- a/tests/Integration/Http/ThrottleRequestsWithRedisTest.php +++ b/tests/Integration/Http/ThrottleRequestsWithRedisTest.php @@ -22,6 +22,11 @@ public function tearDown() Carbon::setTestNow(null); } + public function getEnvironmentSetUp($app) + { + $app['config']->set('hashing', ['driver' => 'bcrypt']); + } + public function test_lock_opens_immediately_after_decay() { $this->ifRedisAvailable(function () { diff --git a/tests/Integration/Queue/ModelSerializationTest.php b/tests/Integration/Queue/ModelSerializationTest.php index 0949b683f78c..fd72abe87809 100644 --- a/tests/Integration/Queue/ModelSerializationTest.php +++ b/tests/Integration/Queue/ModelSerializationTest.php @@ -43,6 +43,20 @@ public function setUp() $table->increments('id'); $table->string('email'); }); + + Schema::create('orders', function ($table) { + $table->increments('id'); + }); + + Schema::create('lines', function ($table) { + $table->increments('id'); + $table->unsignedInteger('order_id'); + $table->unsignedInteger('product_id'); + }); + + Schema::create('products', function ($table) { + $table->increments('id'); + }); } /** @@ -126,6 +140,48 @@ public function it_fails_if_models_on_multi_connections() unserialize($serialized); } + + /** + * @test + */ + public function it_reloads_relationships() + { + $order = Order::create(); + + $product1 = Product::create(); + $product2 = Product::create(); + + Line::create(['order_id' => $order->id, 'product_id' => $product1->id]); + Line::create(['order_id' => $order->id, 'product_id' => $product2->id]); + + $order->load('line', 'lines'); + + $serialized = serialize(new ModelRelationSerializationTestClass($order)); + $unSerialized = unserialize($serialized); + + $this->assertEquals($unSerialized->order->getRelations(), $order->getRelations()); + } + + /** + * @test + */ + public function it_reloads_nested_relationships() + { + $order = Order::create(); + + $product1 = Product::create(); + $product2 = Product::create(); + + Line::create(['order_id' => $order->id, 'product_id' => $product1->id]); + Line::create(['order_id' => $order->id, 'product_id' => $product2->id]); + + $order->load('line.product', 'lines', 'lines.product'); + + $nestedSerialized = serialize(new ModelRelationSerializationTestClass($order)); + $nestedUnSerialized = unserialize($nestedSerialized); + + $this->assertEquals($nestedUnSerialized->order->getRelations(), $order->getRelations()); + } } class ModelSerializationTestUser extends Model @@ -135,6 +191,39 @@ class ModelSerializationTestUser extends Model public $timestamps = false; } +class Order extends Model +{ + public $guarded = ['id']; + public $timestamps = false; + + public function line() + { + return $this->hasOne(Line::class); + } + + public function lines() + { + return $this->hasMany(Line::class); + } +} + +class Line extends Model +{ + public $guarded = ['id']; + public $timestamps = false; + + public function product() + { + return $this->belongsTo(Product::class); + } +} + +class Product extends Model +{ + public $guarded = ['id']; + public $timestamps = false; +} + class ModelSerializationTestClass { use \Illuminate\Queue\SerializesModels; @@ -146,3 +235,15 @@ public function __construct($user) $this->user = $user; } } + +class ModelRelationSerializationTestClass +{ + use \Illuminate\Queue\SerializesModels; + + public $order; + + public function __construct($order) + { + $this->order = $order; + } +} diff --git a/tests/Queue/QueueSyncQueueTest.php b/tests/Queue/QueueSyncQueueTest.php index 8d533c8b197f..cbbac59c9c4a 100755 --- a/tests/Queue/QueueSyncQueueTest.php +++ b/tests/Queue/QueueSyncQueueTest.php @@ -61,6 +61,11 @@ public function getQueueableConnection() { // } + + public function getQueueableRelations() + { + // + } } class SyncQueueTestHandler diff --git a/tests/Support/SupportArrTest.php b/tests/Support/SupportArrTest.php index 94b5ec59207c..fb334044a11e 100644 --- a/tests/Support/SupportArrTest.php +++ b/tests/Support/SupportArrTest.php @@ -662,5 +662,6 @@ public function testWrap() $this->assertEquals(['a'], Arr::wrap($string)); $this->assertEquals($array, Arr::wrap($array)); $this->assertEquals([$object], Arr::wrap($object)); + $this->assertEquals([], Arr::wrap(null)); } } diff --git a/tests/Support/SupportTestingMailFakeTest.php b/tests/Support/SupportTestingMailFakeTest.php index 1bb4a39cb3e6..8a2a7ead675c 100644 --- a/tests/Support/SupportTestingMailFakeTest.php +++ b/tests/Support/SupportTestingMailFakeTest.php @@ -111,7 +111,7 @@ class MailableStub extends Mailable { public $framework = 'Laravel'; - protected $version = '5.5'; + protected $version = '5.6'; /** * Build the message. @@ -129,7 +129,7 @@ class QueueableMailableStub extends Mailable implements ShouldQueue { public $framework = 'Laravel'; - protected $version = '5.5'; + protected $version = '5.6'; /** * Build the message. diff --git a/tests/Validation/ValidationValidatorTest.php b/tests/Validation/ValidationValidatorTest.php index 7c74d753672c..fd95834f6680 100755 --- a/tests/Validation/ValidationValidatorTest.php +++ b/tests/Validation/ValidationValidatorTest.php @@ -2114,6 +2114,13 @@ public function testValidateImageDimensions() // Ensure validation doesn't erroneously fail when ratio has no fractional part $v = new Validator($trans, ['x' => $uploadedFile], ['x' => 'dimensions:ratio=2/3']); $this->assertTrue($v->passes()); + + // Ensure svg images always pass as size is irreleveant + $uploadedFile = new \Symfony\Component\HttpFoundation\File\UploadedFile(__DIR__.'/fixtures/image.svg', '', 'image/svg+xml', null, null, true); + $trans = $this->getIlluminateArrayTranslator(); + + $v = new Validator($trans, ['x' => $uploadedFile], ['x' => 'dimensions:max_width=1,max_height=1']); + $this->assertTrue($v->passes()); } /** diff --git a/tests/Validation/fixtures/image.svg b/tests/Validation/fixtures/image.svg new file mode 100644 index 000000000000..9a55b678ffb5 --- /dev/null +++ b/tests/Validation/fixtures/image.svg @@ -0,0 +1,2 @@ + +