Skip to content

Commit

Permalink
Merge branch '8.x'
Browse files Browse the repository at this point in the history
# Conflicts:
#	CHANGELOG-8.x.md
#	src/Illuminate/Collections/Collection.php
#	src/Illuminate/Foundation/Application.php
#	src/Illuminate/Testing/TestResponse.php
  • Loading branch information
driesvints committed Sep 2, 2021
2 parents 932e601 + e7f075f commit d69e2e0
Show file tree
Hide file tree
Showing 38 changed files with 842 additions and 74 deletions.
10 changes: 1 addition & 9 deletions .github/SECURITY.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,7 @@

## Supported Versions

Version | Security Fixes Until
--- | ---
8 | September 8th, 2021
7 | March 3rd, 2021
6 (LTS) | September 3rd, 2022
5.8 | February 26th, 2020
5.7 | September 4th, 2019
5.6 | February 7th, 2019
5.5 (LTS) | August 30th, 2020
Please see [our support policy](https://laravel.com/docs/releases#support-policy) for information on supported versions for security releases.

## Reporting a Vulnerability

Expand Down
8 changes: 4 additions & 4 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -91,10 +91,10 @@ jobs:
matrix:
php: ['8.0']
stability: [prefer-lowest, prefer-stable]
include:
- php: '8.1'
flags: "--ignore-platform-req=php"
stability: prefer-stable
# include:
# - php: '8.1'
# flags: "--ignore-platform-req=php"
# stability: prefer-stable

name: PHP ${{ matrix.php }} - ${{ matrix.stability }} - Windows

Expand Down
21 changes: 16 additions & 5 deletions src/Illuminate/Auth/Notifications/ResetPassword.php
Original file line number Diff line number Diff line change
Expand Up @@ -59,20 +59,31 @@ public function via($notifiable)
*/
public function toMail($notifiable)
{
$url = $this->resetUrl($notifiable);

if (static::$toMailCallback) {
return call_user_func(static::$toMailCallback, $notifiable, $this->token);
return call_user_func(static::$toMailCallback, $notifiable, $this->token, $url);
}

return $this->buildMailMessage($url);
}

/**
* Get the password reset URL for the given notifiable.
*
* @param mixed $notifiable
* @return string
*/
protected function resetUrl($notifiable)
{
if (static::$createUrlCallback) {
$url = call_user_func(static::$createUrlCallback, $notifiable, $this->token);
return call_user_func(static::$createUrlCallback, $notifiable, $this->token);
} else {
$url = url(route('password.reset', [
return url(route('password.reset', [
'token' => $this->token,
'email' => $notifiable->getEmailForPasswordReset(),
], false));
}

return $this->buildMailMessage($url);
}

/**
Expand Down
5 changes: 4 additions & 1 deletion src/Illuminate/Broadcasting/BroadcastManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,10 @@ public function event($event = null)
*/
public function queue($event)
{
if ($event instanceof ShouldBroadcastNow) {
if ($event instanceof ShouldBroadcastNow ||
(is_object($event) &&
method_exists($event, 'shouldBroadcastNow') &&
$event->shouldBroadcastNow())) {
return $this->app->make(BusDispatcherContract::class)->dispatchNow(new BroadcastEvent(clone $event));
}

Expand Down
8 changes: 5 additions & 3 deletions src/Illuminate/Collections/Collection.php
Original file line number Diff line number Diff line change
Expand Up @@ -1177,13 +1177,15 @@ public function firstOrFail($key = null, $operator = null, $value = null)
? $this->operatorForWhere(...func_get_args())
: $key;

$items = $this->unless($filter == null)->filter($filter);
$placeholder = new stdClass();

if ($items->isEmpty()) {
$item = $this->first($filter, $placeholder);

if ($item === $placeholder) {
throw new ItemNotFoundException;
}

return $items->first();
return $item;
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ public function needs($abstract);
/**
* Define the implementation for the contextual binding.
*
* @param \Closure|string $implementation
* @param \Closure|string|array $implementation
* @return void
*/
public function give($implementation);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,17 @@ public function onChannels(array $channels)
return $this;
}

/**
* Determine if the event should be broadcast synchronously.
*
* @return bool
*/
public function shouldBroadcastNow()
{
return $this->event === 'deleted' &&
! method_exists($this->model, 'bootSoftDeletes');
}

/**
* Get the event name.
*
Expand Down
4 changes: 4 additions & 0 deletions src/Illuminate/Database/Eloquent/BroadcastsEvents.php
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,10 @@ public function broadcastDeleted($channels = null)
*/
protected function broadcastIfBroadcastChannelsExistForEvent($instance, $event, $channels = null)
{
if (! static::$isBroadcasting) {
return;
}

if (! empty($this->broadcastOn($event)) || ! empty($channels)) {
return broadcast($instance->onChannels(Arr::wrap($channels)));
}
Expand Down
66 changes: 66 additions & 0 deletions src/Illuminate/Database/Eloquent/Concerns/QueriesRelationships.php
Original file line number Diff line number Diff line change
Expand Up @@ -348,6 +348,72 @@ public function orWhereDoesntHaveMorph($relation, $types, Closure $callback = nu
return $this->doesntHaveMorph($relation, $types, 'or', $callback);
}

/**
* Add a basic where clause to a relationship query.
*
* @param string $relation
* @param \Closure|string|array|\Illuminate\Database\Query\Expression $column
* @param mixed $operator
* @param mixed $value
* @return \Illuminate\Database\Eloquent\Builder|static
*/
public function whereRelation($relation, $column, $operator = null, $value = null)
{
return $this->whereHas($relation, function ($query) use ($column, $operator, $value) {
$query->where($column, $operator, $value);
});
}

/**
* Add an "or where" clause to a relationship query.
*
* @param string $relation
* @param \Closure|string|array|\Illuminate\Database\Query\Expression $column
* @param mixed $operator
* @param mixed $value
* @return \Illuminate\Database\Eloquent\Builder|static
*/
public function orWhereRelation($relation, $column, $operator = null, $value = null)
{
return $this->orWhereHas($relation, function ($query) use ($column, $operator, $value) {
$query->where($column, $operator, $value);
});
}

/**
* Add a polymorphic relationship condition to the query with a where clause.
*
* @param \Illuminate\Database\Eloquent\Relations\MorphTo|string $relation
* @param string|array $types
* @param \Closure|string|array|\Illuminate\Database\Query\Expression $column
* @param mixed $operator
* @param mixed $value
* @return \Illuminate\Database\Eloquent\Builder|static
*/
public function whereMorphRelation($relation, $types, $column, $operator = null, $value = null)
{
return $this->whereHasMorph($relation, $types, function ($query) use ($column, $operator, $value) {
$query->where($column, $operator, $value);
});
}

/**
* Add a polymorphic relationship condition to the query with an "or where" clause.
*
* @param \Illuminate\Database\Eloquent\Relations\MorphTo|string $relation
* @param string|array $types
* @param \Closure|string|array|\Illuminate\Database\Query\Expression $column
* @param mixed $operator
* @param mixed $value
* @return \Illuminate\Database\Eloquent\Builder|static
*/
public function orWhereMorphRelation($relation, $types, $column, $operator = null, $value = null)
{
return $this->orWhereHasMorph($relation, $types, function ($query) use ($column, $operator, $value) {
$query->where($column, $operator, $value);
});
}

/**
* Add subselect queries to include an aggregate value for a relationship.
*
Expand Down
38 changes: 38 additions & 0 deletions src/Illuminate/Database/Eloquent/Factories/Factory.php
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,17 @@ public function createOne($attributes = [])
return $this->count(null)->create($attributes);
}

/**
* Create a single model and persist it to the database.
*
* @param array $attributes
* @return \Illuminate\Database\Eloquent\Model
*/
public function createOneQuietly($attributes = [])
{
return $this->count(null)->createQuietly($attributes);
}

/**
* Create a collection of models and persist them to the database.
*
Expand All @@ -217,6 +228,19 @@ public function createMany(iterable $records)
);
}

/**
* Create a collection of models and persist them to the database.
*
* @param iterable $records
* @return \Illuminate\Database\Eloquent\Collection
*/
public function createManyQuietly(iterable $records)
{
return Model::withoutEvents(function () use ($records) {
return $this->createMany($records);
});
}

/**
* Create a collection of models and persist them to the database.
*
Expand Down Expand Up @@ -245,6 +269,20 @@ public function create($attributes = [], ?Model $parent = null)
return $results;
}

/**
* Create a collection of models and persist them to the database.
*
* @param array $attributes
* @param \Illuminate\Database\Eloquent\Model|null $parent
* @return \Illuminate\Database\Eloquent\Collection|\Illuminate\Database\Eloquent\Model
*/
public function createQuietly($attributes = [], ?Model $parent = null)
{
return Model::withoutEvents(function () use ($attributes, $parent) {
return $this->create($attributes, $parent);
});
}

/**
* Create a callback that persists a model in the database when invoked.
*
Expand Down
46 changes: 45 additions & 1 deletion src/Illuminate/Database/Eloquent/Model.php
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,13 @@ abstract class Model implements Arrayable, ArrayAccess, HasBroadcastChannel, Jso
*/
protected static $lazyLoadingViolationCallback;

/**
* Indicates if broadcasting is currently enabled.
*
* @var bool
*/
protected static $isBroadcasting = true;

/**
* The name of the "created at" column.
*
Expand Down Expand Up @@ -377,6 +384,25 @@ public static function handleLazyLoadingViolationUsing(callable $callback)
static::$lazyLoadingViolationCallback = $callback;
}

/**
* Execute a callback without broadcasting any model events for all model types.
*
* @param callable $callback
* @return mixed
*/
public static function withoutBroadcasting(callable $callback)
{
$isBroadcasting = static::$isBroadcasting;

static::$isBroadcasting = false;

try {
return $callback();
} finally {
static::$isBroadcasting = $isBroadcasting;
}
}

/**
* Fill the model with an array of attributes.
*
Expand Down Expand Up @@ -851,6 +877,24 @@ public function update(array $attributes = [], array $options = [])
return $this->fill($attributes)->save($options);
}

/**
* Update the model in the database within a transaction.
*
* @param array $attributes
* @param array $options
* @return bool
*
* @throws \Throwable
*/
public function updateOrFail(array $attributes = [], array $options = [])
{
if (! $this->exists) {
return false;
}

return $this->fill($attributes)->saveOrFail($options);
}

/**
* Update the model in the database without raising any events.
*
Expand Down Expand Up @@ -958,7 +1002,7 @@ public function save(array $options = [])
}

/**
* Save the model to the database using transaction.
* Save the model to the database within a transaction.
*
* @param array $options
* @return bool
Expand Down

1 comment on commit d69e2e0

@Krisell
Copy link
Contributor

@Krisell Krisell commented on d69e2e0 Sep 2, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The failing test is my fault – there is a 1/64 chance that the cipher tag modification doesn't actually change the tag, which breaks the test, I'll update the test in 8.x.

Please sign in to comment.