diff --git a/.gitattributes b/.gitattributes
index 927c475f58cd..a49ae3b7ca61 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -5,9 +5,8 @@
.editorconfig export-ignore
.gitattributes export-ignore
.gitignore export-ignore
-.nitpick.json export-ignore
.php_cs export-ignore
.travis.yml export-ignore
-phpunit.xml export-ignore
+phpunit.xml.dist export-ignore
CHANGELOG.md export-ignore
CONTRIBUTING.md export-ignore
diff --git a/.gitignore b/.gitignore
index 54406f02a976..2de844b899a3 100644
--- a/.gitignore
+++ b/.gitignore
@@ -4,3 +4,4 @@ composer.lock
.php_cs.cache
.DS_Store
Thumbs.db
+/phpunit.xml
\ No newline at end of file
diff --git a/.nitpick.json b/.nitpick.json
deleted file mode 100644
index 3881d8dc2f2e..000000000000
--- a/.nitpick.json
+++ /dev/null
@@ -1,5 +0,0 @@
-{
- "ignore": [
- "tests/*"
- ]
-}
diff --git a/.travis.yml b/.travis.yml
index 20d73d042e04..37a59740861d 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -3,7 +3,6 @@ language: php
php:
- 5.6
- 7.0
- - hhvm
env:
global:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 7a80d6ff302b..96c3abc935ea 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,40 @@
# Release Notes
+## v5.2.43 (2016-08-10)
+
+### Changed
+- Throw exception if `$amount` is not numeric in `increment()` and `decrement()` ([915cb84](https://github.com/laravel/framework/commit/915cb843981ad434b10709425d968bf2db37cb1a))
+
+
+## v5.2.42 (2016-08-08)
+
+### Added
+- Allow `BelongsToMany::detach()` to accept a collection ([#14412](https://github.com/laravel/framework/pull/14412))
+- Added `whereTime()` and `orWhereTime()` to query builder ([#14528](https://github.com/laravel/framework/pull/14528))
+- Added PHP 7.1 support ([#14549](https://github.com/laravel/framework/pull/14549))
+- Allow collections to be created from objects that implement `Traversable` ([#14628](https://github.com/laravel/framework/pull/14628))
+- Support dot notation in `Request::exists()` ([#14660](https://github.com/laravel/framework/pull/14660))
+- Added missing `Model::makeHidden()` method ([#14641](https://github.com/laravel/framework/pull/14641))
+
+### Changed
+- Return `true` when `$key` is empty in `MessageBag::has()` ([#14409](https://github.com/laravel/framework/pull/14409))
+- Optimized `Filesystem::moveDirectory` ([#14362](https://github.com/laravel/framework/pull/14362))
+- Convert `$count` to integer in `Str::plural()` ([#14502](https://github.com/laravel/framework/pull/14502))
+- Handle arrays in `validateIn()` method ([#14607](https://github.com/laravel/framework/pull/14607))
+
+### Fixed
+- Fixed an issue with `wherePivotIn()` ([#14397](https://github.com/laravel/framework/issues/14397))
+- Fixed PDO connection on HHVM ([#14429](https://github.com/laravel/framework/pull/14429))
+- Prevent `make:migration` from creating duplicate classes ([#14432](https://github.com/laravel/framework/pull/14432))
+- Fixed lazy eager loading issue in `LengthAwarePaginator` collection ([#14476](https://github.com/laravel/framework/pull/14476))
+- Fixed plural form of Pokémon ([#14525](https://github.com/laravel/framework/pull/14525))
+- Fixed authentication bug in `TokenGuard::validate()` ([#14568](https://github.com/laravel/framework/pull/14568))
+- Fix missing middleware parameters when using `authorizeResource()` ([#14592](https://github.com/laravel/framework/pull/14592))
+
+### Removed
+- Removed duplicate interface implementation in `Dispatcher` ([#14515](https://github.com/laravel/framework/pull/14515))
+
+
## v5.2.41 (2016-07-20)
### Changed
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 2cbf8251054c..500ac3f96bec 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -1,3 +1,3 @@
# Laravel Contribution Guide
-Thank you for considering contributing to the Laravel framework! The contribution guide can be found in the [Laravel documentation](http://laravel.com/docs/contributions). Please review the entire guide before sending a pull request.
+Thank you for considering contributing to the Laravel framework! The contribution guide can be found in the [Laravel documentation](https://laravel.com/docs/contributions). Please review the entire guide before sending a pull request.
diff --git a/composer.json b/composer.json
index bcbbd3e8bb49..471df21da6c9 100644
--- a/composer.json
+++ b/composer.json
@@ -3,7 +3,7 @@
"description": "The Laravel Framework.",
"keywords": ["framework", "laravel"],
"license": "MIT",
- "homepage": "http://laravel.com",
+ "homepage": "https://laravel.com",
"support": {
"issues": "https://github.com/laravel/framework/issues",
"source": "https://github.com/laravel/framework"
@@ -11,7 +11,7 @@
"authors": [
{
"name": "Taylor Otwell",
- "email": "taylorotwell@gmail.com"
+ "email": "taylor@laravel.com"
}
],
"require": {
@@ -27,6 +27,7 @@
"nesbot/carbon": "~1.20",
"paragonie/random_compat": "~1.4|~2.0",
"psy/psysh": "0.7.*",
+ "ramsey/uuid": "~3.0",
"swiftmailer/swiftmailer": "~5.1",
"symfony/console": "3.1.*",
"symfony/debug": "3.1.*",
diff --git a/phpunit.xml b/phpunit.xml.dist
similarity index 87%
rename from phpunit.xml
rename to phpunit.xml.dist
index db640da487f2..baa2d1e86eb3 100644
--- a/phpunit.xml
+++ b/phpunit.xml.dist
@@ -26,4 +26,10 @@
+
+
+
diff --git a/readme.md b/readme.md
index 76d266ffaf3c..c7d5e0f27848 100644
--- a/readme.md
+++ b/readme.md
@@ -17,11 +17,11 @@ Laravel is accessible, yet powerful, providing powerful tools needed for large,
## Official Documentation
-Documentation for the framework can be found on the [Laravel website](http://laravel.com/docs).
+Documentation for the framework can be found on the [Laravel website](https://laravel.com/docs).
## Contributing
-Thank you for considering contributing to the Laravel framework! The contribution guide can be found in the [Laravel documentation](http://laravel.com/docs/contributions).
+Thank you for considering contributing to the Laravel framework! The contribution guide can be found in the [Laravel documentation](https://laravel.com/docs/contributions).
## Security Vulnerabilities
diff --git a/src/Illuminate/Auth/Access/Gate.php b/src/Illuminate/Auth/Access/Gate.php
index a16966e75e6d..85882567e95d 100644
--- a/src/Illuminate/Auth/Access/Gate.php
+++ b/src/Illuminate/Auth/Access/Gate.php
@@ -369,11 +369,9 @@ protected function resolvePolicyCallback($user, $ability, array $arguments)
}
// If the first argument is a string, that means they are passing a class name
- // to the policy. We'll append "Any" to this ability name so that users may
- // call the policy method with either a class or model name consistently.
+ // to the policy. We will remove the first argument from this argument list
+ // because the policy already knows what type of models it can authorize.
if (isset($arguments[0]) && is_string($arguments[0])) {
- $ability = $ability.'Any';
-
array_shift($arguments);
}
diff --git a/src/Illuminate/Auth/Console/stubs/make/controllers/HomeController.stub b/src/Illuminate/Auth/Console/stubs/make/controllers/HomeController.stub
index 669e2ea9ca39..8e0007adcab8 100644
--- a/src/Illuminate/Auth/Console/stubs/make/controllers/HomeController.stub
+++ b/src/Illuminate/Auth/Console/stubs/make/controllers/HomeController.stub
@@ -2,7 +2,6 @@
namespace {{namespace}}Http\Controllers;
-use {{namespace}}Http\Requests;
use Illuminate\Http\Request;
class HomeController extends Controller
diff --git a/src/Illuminate/Auth/Console/stubs/make/views/auth/passwords/reset.stub b/src/Illuminate/Auth/Console/stubs/make/views/auth/passwords/reset.stub
index bb4775a99093..3ac82d8c38fd 100644
--- a/src/Illuminate/Auth/Console/stubs/make/views/auth/passwords/reset.stub
+++ b/src/Illuminate/Auth/Console/stubs/make/views/auth/passwords/reset.stub
@@ -17,7 +17,7 @@
E-Mail Address
-
+
@if ($errors->has('email'))
diff --git a/src/Illuminate/Auth/Console/stubs/make/views/layouts/app.stub b/src/Illuminate/Auth/Console/stubs/make/views/layouts/app.stub
index 71d548a30b11..3222a70f9cd8 100644
--- a/src/Illuminate/Auth/Console/stubs/make/views/layouts/app.stub
+++ b/src/Illuminate/Auth/Console/stubs/make/views/layouts/app.stub
@@ -5,10 +5,20 @@
+
+
+
Laravel
+
+
+
diff --git a/src/Illuminate/Auth/Middleware/Authorize.php b/src/Illuminate/Auth/Middleware/Authorize.php
index 0d1af41b03b3..6752f9cb30a1 100644
--- a/src/Illuminate/Auth/Middleware/Authorize.php
+++ b/src/Illuminate/Auth/Middleware/Authorize.php
@@ -41,17 +41,17 @@ public function __construct(Auth $auth, Gate $gate)
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @param string $ability
- * @param string|null $model
+ * @param array|null $models
* @return mixed
*
* @throws \Illuminate\Auth\Access\AuthenticationException
* @throws \Illuminate\Auth\Access\AuthorizationException
*/
- public function handle($request, Closure $next, $ability, $model = null)
+ public function handle($request, Closure $next, $ability, ...$models)
{
$this->auth->authenticate();
- $this->gate->authorize($ability, $this->getGateArguments($request, $model));
+ $this->gate->authorize($ability, $this->getGateArguments($request, $models));
return $next($request);
}
@@ -60,12 +60,18 @@ public function handle($request, Closure $next, $ability, $model = null)
* Get the arguments parameter for the gate.
*
* @param \Illuminate\Http\Request $request
- * @param string|null $model
+ * @param array|null $models
* @return array|string|\Illuminate\Database\Eloquent\Model
*/
- protected function getGateArguments($request, $model)
+ protected function getGateArguments($request, $models)
{
- return is_null($model) ? [] : $this->getModel($request, $model);
+ if (is_null($models)) {
+ return [];
+ }
+
+ return collect($models)->map(function ($model) use ($request) {
+ return $this->getModel($request, $model);
+ })->all();
}
/**
diff --git a/src/Illuminate/Auth/Notifications/ResetPassword.php b/src/Illuminate/Auth/Notifications/ResetPassword.php
index 488d4e1d0e6b..c5fa1d819ec2 100644
--- a/src/Illuminate/Auth/Notifications/ResetPassword.php
+++ b/src/Illuminate/Auth/Notifications/ResetPassword.php
@@ -3,6 +3,7 @@
namespace Illuminate\Auth\Notifications;
use Illuminate\Notifications\Notification;
+use Illuminate\Notifications\Messages\MailMessage;
class ResetPassword extends Notification
{
@@ -36,15 +37,18 @@ public function via($notifiable)
}
/**
- * Get the notification message.
+ * Build the mail representation of the notification.
*
- * @param mixed $notifiable
- * @return \Illuminate\Notifications\MessageBuilder
+ * @return \Illuminate\Notifications\Messages\MailMessage
*/
- public function message($notifiable)
+ public function toMail()
{
- return $this->line('You are receiving this email because we received a password reset request for your account. Click the button below to reset your password:')
- ->action('Reset Password', url('password/reset', $this->token).'?email='.urlencode($notifiable->email))
- ->line('If you did not request a password reset, no further action is required.');
+ return (new MailMessage)
+ ->line([
+ 'You are receiving this email because we received a password reset request for your account.',
+ 'Click the button below to reset your password:',
+ ])
+ ->action('Reset Password', url('password/reset', $this->token))
+ ->line('If you did not request a password reset, no further action is required.');
}
}
diff --git a/src/Illuminate/Auth/RequestGuard.php b/src/Illuminate/Auth/RequestGuard.php
index 0d73bd6aef69..e6b9a7e7f73e 100644
--- a/src/Illuminate/Auth/RequestGuard.php
+++ b/src/Illuminate/Auth/RequestGuard.php
@@ -27,11 +27,10 @@ class RequestGuard implements Guard
* Create a new authentication guard.
*
* @param callable $callback
- * @param \Symfony\Component\HttpFoundation\Request $request
+ * @param \Illuminate\Http\Request $request
* @return void
*/
- public function __construct(callable $callback,
- Request $request)
+ public function __construct(callable $callback, Request $request)
{
$this->request = $request;
$this->callback = $callback;
diff --git a/src/Illuminate/Auth/TokenGuard.php b/src/Illuminate/Auth/TokenGuard.php
index e9d3602fca57..2a33ab0e61f4 100644
--- a/src/Illuminate/Auth/TokenGuard.php
+++ b/src/Illuminate/Auth/TokenGuard.php
@@ -101,6 +101,10 @@ protected function getTokenForRequest()
*/
public function validate(array $credentials = [])
{
+ if (empty($credentials[$this->inputKey])) {
+ return false;
+ }
+
$credentials = [$this->storageKey => $credentials[$this->inputKey]];
if ($this->provider->retrieveByCredentials($credentials)) {
diff --git a/src/Illuminate/Auth/composer.json b/src/Illuminate/Auth/composer.json
index 9e3fba321fcb..08582ba6727d 100644
--- a/src/Illuminate/Auth/composer.json
+++ b/src/Illuminate/Auth/composer.json
@@ -2,7 +2,7 @@
"name": "illuminate/auth",
"description": "The Illuminate Auth package.",
"license": "MIT",
- "homepage": "http://laravel.com",
+ "homepage": "https://laravel.com",
"support": {
"issues": "https://github.com/laravel/framework/issues",
"source": "https://github.com/laravel/framework"
@@ -10,7 +10,7 @@
"authors": [
{
"name": "Taylor Otwell",
- "email": "taylorotwell@gmail.com"
+ "email": "taylor@laravel.com"
}
],
"require": {
diff --git a/src/Illuminate/Broadcasting/BroadcastController.php b/src/Illuminate/Broadcasting/BroadcastController.php
index e4b704f5436f..f71c9237711d 100644
--- a/src/Illuminate/Broadcasting/BroadcastController.php
+++ b/src/Illuminate/Broadcasting/BroadcastController.php
@@ -2,7 +2,6 @@
namespace Illuminate\Broadcasting;
-use Illuminate\Support\Str;
use Illuminate\Http\Request;
use Illuminate\Routing\Controller;
use Illuminate\Support\Facades\Broadcast;
@@ -13,25 +12,10 @@ class BroadcastController extends Controller
* Authenticate the request for channel access.
*
* @param \Illuminate\Http\Request $request
- * @return void
+ * @return \Illuminate\Http\Response
*/
public function authenticate(Request $request)
{
- if (Str::startsWith($request->channel_name, 'presence-') && ! $request->user()) {
- abort(403);
- }
-
- return Broadcast::check($request);
- }
-
- /**
- * Store the socket ID for the current user.
- *
- * @param \Illuminate\Http\Request $request
- * @return void
- */
- public function rememberSocket(Request $request)
- {
- return Broadcast::rememberSocket($request);
+ return Broadcast::auth($request);
}
}
diff --git a/src/Illuminate/Broadcasting/BroadcastEvent.php b/src/Illuminate/Broadcasting/BroadcastEvent.php
index 1b6bad9f2e12..6b852bd03e87 100644
--- a/src/Illuminate/Broadcasting/BroadcastEvent.php
+++ b/src/Illuminate/Broadcasting/BroadcastEvent.php
@@ -42,8 +42,14 @@ public function fire(Job $job, array $data)
$name = method_exists($event, 'broadcastAs')
? $event->broadcastAs() : get_class($event);
+ $channels = $event->broadcastOn();
+
+ if (! is_array($channels)) {
+ $channels = [$channels];
+ }
+
$this->broadcaster->broadcast(
- $event->broadcastOn(), $name, $this->getPayloadFromEvent($event)
+ $channels, $name, $this->getPayloadFromEvent($event)
);
$job->delete();
diff --git a/src/Illuminate/Broadcasting/BroadcastManager.php b/src/Illuminate/Broadcasting/BroadcastManager.php
index 8693c7ccb88f..697585b7b2c3 100644
--- a/src/Illuminate/Broadcasting/BroadcastManager.php
+++ b/src/Illuminate/Broadcasting/BroadcastManager.php
@@ -7,6 +7,8 @@
use Illuminate\Support\Arr;
use InvalidArgumentException;
use Illuminate\Broadcasting\Broadcasters\LogBroadcaster;
+use Illuminate\Contracts\Broadcasting\ShouldBroadcastNow;
+use Illuminate\Broadcasting\Broadcasters\NullBroadcaster;
use Illuminate\Broadcasting\Broadcasters\RedisBroadcaster;
use Illuminate\Broadcasting\Broadcasters\PusherBroadcaster;
use Illuminate\Contracts\Broadcasting\Factory as FactoryContract;
@@ -48,18 +50,19 @@ public function __construct($app)
/**
* Register the routes for handling broadcast authentication and sockets.
*
- * @param array $attributes
+ * @param array|null $attributes
* @return void
*/
- public function route(array $attributes = [])
+ public function routes(array $attributes = null)
{
if ($this->app->routesAreCached()) {
return;
}
- $this->app['router']->group($attributes, function () {
- $this->app['router']->post('/broadcasting/auth', BroadcastController::class.'@authenticate');
- $this->app['router']->post('/broadcasting/socket', BroadcastController::class.'@rememberSocket');
+ $attributes = $attributes ?: ['middleware' => ['web']];
+
+ $this->app['router']->group($attributes, function ($router) {
+ $router->post('/broadcasting/auth', BroadcastController::class.'@authenticate');
});
}
@@ -77,35 +80,46 @@ public function socket($request = null)
$request = $request ?: $this->app['request'];
- if ($request->hasHeader('X-Socket-Id')) {
- return $request->header('X-Socket-Id');
- }
-
- if (! $request->hasSession()) {
- return;
+ if ($request->hasHeader('X-Socket-ID')) {
+ return $request->header('X-Socket-ID');
}
+ }
- return $this->app['cache']->get(
- 'broadcast:socket:'.$request->session()->getId()
- );
+ /**
+ * Begin broadcasting an event.
+ *
+ * @param mixed|null $event
+ * @return \Illuminate\Broadcasting\PendingBroadcast|void
+ */
+ public function event($event = null)
+ {
+ return new PendingBroadcast($this->app->make('events'), $event);
}
/**
- * Remember the socket for the given request.
+ * Queue the given event for broadcast.
*
- * @param \Illuminate\Http\Request|null $request
+ * @param mixed $event
* @return void
*/
- public function rememberSocket($request = null)
+ public function queue($event)
{
- if (! $request && ! $this->app->bound('request')) {
- return;
+ $connection = $event instanceof ShouldBroadcastNow ? 'sync' : null;
+
+ if (is_null($connection) && isset($event->connection)) {
+ $connection = $event->connection;
}
- $request = $request ?: $this->app['request'];
+ $queue = null;
+
+ if (isset($event->broadcastQueue)) {
+ $queue = $event->broadcastQueue;
+ } elseif (isset($event->queue)) {
+ $queue = $event->queue;
+ }
- $this->app['cache']->forever(
- 'broadcast:socket:'.$request->session()->getId(), $request->socket_id
+ $this->app->make('queue')->connection($connection)->pushOn(
+ $queue, BroadcastEvent::class, ['event' => serialize(clone $event)]
);
}
@@ -223,6 +237,17 @@ protected function createLogDriver(array $config)
);
}
+ /**
+ * Create an instance of the driver.
+ *
+ * @param array $config
+ * @return \Illuminate\Contracts\Broadcasting\Broadcaster
+ */
+ protected function createNullDriver(array $config)
+ {
+ return new NullBroadcaster;
+ }
+
/**
* Get the connection configuration.
*
@@ -278,6 +303,6 @@ public function extend($driver, Closure $callback)
*/
public function __call($method, $parameters)
{
- return call_user_func_array([$this->driver(), $method], $parameters);
+ return $this->driver()->$method(...$parameters);
}
}
diff --git a/src/Illuminate/Broadcasting/Broadcasters/Broadcaster.php b/src/Illuminate/Broadcasting/Broadcasters/Broadcaster.php
index 9607c08e15b1..d41ed40fadfc 100644
--- a/src/Illuminate/Broadcasting/Broadcasters/Broadcaster.php
+++ b/src/Illuminate/Broadcasting/Broadcasters/Broadcaster.php
@@ -15,11 +15,6 @@ abstract class Broadcaster implements BroadcasterContract
*/
protected $channels = [];
- /**
- * {@inheritdoc}
- */
- abstract public function broadcast(array $channels, $event, array $payload = []);
-
/**
* Register a channel authenticator.
*
@@ -27,7 +22,7 @@ abstract public function broadcast(array $channels, $event, array $payload = [])
* @param callable $callback
* @return $this
*/
- public function auth($channel, callable $callback)
+ public function channel($channel, callable $callback)
{
$this->channels[$channel] = $callback;
@@ -38,12 +33,11 @@ public function auth($channel, callable $callback)
* Authenticate the incoming request for a given channel.
*
* @param \Illuminate\Http\Request $request
+ * @param string $channel
* @return mixed
*/
- public function check($request)
+ protected function verifyUserCanAccessChannel($request, $channel)
{
- $channel = str_replace(['private-', 'presence-'], '', $request->channel_name);
-
foreach ($this->channels as $pattern => $callback) {
if (! Str::is($pattern, $channel)) {
continue;
@@ -84,21 +78,15 @@ protected function extractAuthParameters($pattern, $channel)
}
/**
- * Return the valid Pusher authentication response.
+ * Format the channel array into an array of strings.
*
- * @param \Illuminate\Http\Request $request
- * @param mixed $result
- * @return mixed
+ * @param array $channels
+ * @return array
*/
- protected function validAuthenticationResponse($request, $result)
+ protected function formatChannels(array $channels)
{
- if (is_bool($result)) {
- return json_encode($result);
- }
-
- return json_encode(['channel_data' => [
- 'user_id' => $request->user()->getKey(),
- 'user_info' => $result,
- ]]);
+ return array_map(function ($channel) {
+ return (string) $channel;
+ }, $channels);
}
}
diff --git a/src/Illuminate/Broadcasting/Broadcasters/LogBroadcaster.php b/src/Illuminate/Broadcasting/Broadcasters/LogBroadcaster.php
index 3407c9cd78c6..50877dc976fe 100644
--- a/src/Illuminate/Broadcasting/Broadcasters/LogBroadcaster.php
+++ b/src/Illuminate/Broadcasting/Broadcasters/LogBroadcaster.php
@@ -24,12 +24,28 @@ public function __construct(LoggerInterface $logger)
$this->logger = $logger;
}
+ /**
+ * {@inheritdoc}
+ */
+ public function auth($request)
+ {
+ //
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function validAuthenticationResponse($request, $result)
+ {
+ //
+ }
+
/**
* {@inheritdoc}
*/
public function broadcast(array $channels, $event, array $payload = [])
{
- $channels = implode(', ', $channels);
+ $channels = implode(', ', $this->formatChannels($channels));
$payload = json_encode($payload, JSON_PRETTY_PRINT);
diff --git a/src/Illuminate/Broadcasting/Broadcasters/NullBroadcaster.php b/src/Illuminate/Broadcasting/Broadcasters/NullBroadcaster.php
new file mode 100644
index 000000000000..6205c90c12da
--- /dev/null
+++ b/src/Illuminate/Broadcasting/Broadcasters/NullBroadcaster.php
@@ -0,0 +1,30 @@
+channel_name, ['private-', 'presence-']) &&
+ ! $request->user()) {
+ throw new HttpException(403);
+ }
+
+ return parent::verifyUserCanAccessChannel(
+ $request, str_replace(['private-', 'presence-'], '', $request->channel_name)
+ );
+ }
+
+ /**
+ * Return the valid authentication response.
*
* @param \Illuminate\Http\Request $request
* @param mixed $result
* @return mixed
*/
- protected function validAuthenticationResponse($request, $result)
+ public function validAuthenticationResponse($request, $result)
{
if (Str::startsWith($request->channel_name, 'private')) {
return $this->pusher->socket_auth($request->channel_name, $request->socket_id);
@@ -45,13 +64,18 @@ protected function validAuthenticationResponse($request, $result)
}
/**
- * {@inheritdoc}
+ * Broadcast the given event.
+ *
+ * @param array $channels
+ * @param string $event
+ * @param array $payload
+ * @return void
*/
public function broadcast(array $channels, $event, array $payload = [])
{
$socket = Arr::pull($payload, 'socket');
- $this->pusher->trigger($channels, $event, $payload, $socket);
+ $this->pusher->trigger($this->formatChannels($channels), $event, $payload, $socket);
}
/**
diff --git a/src/Illuminate/Broadcasting/Broadcasters/RedisBroadcaster.php b/src/Illuminate/Broadcasting/Broadcasters/RedisBroadcaster.php
index fd588aa5bc0c..6b7e5be66c92 100644
--- a/src/Illuminate/Broadcasting/Broadcasters/RedisBroadcaster.php
+++ b/src/Illuminate/Broadcasting/Broadcasters/RedisBroadcaster.php
@@ -3,7 +3,9 @@
namespace Illuminate\Broadcasting\Broadcasters;
use Illuminate\Support\Arr;
+use Illuminate\Support\Str;
use Illuminate\Contracts\Redis\Database as RedisDatabase;
+use Symfony\Component\HttpKernel\Exception\HttpException;
class RedisBroadcaster extends Broadcaster
{
@@ -35,7 +37,49 @@ public function __construct(RedisDatabase $redis, $connection = null)
}
/**
- * {@inheritdoc}
+ * Authenticate the incoming request for a given channel.
+ *
+ * @param \Illuminate\Http\Request $request
+ * @return mixed
+ */
+ public function auth($request)
+ {
+ if (Str::startsWith($request->channel_name, ['private-', 'presence-']) &&
+ ! $request->user()) {
+ throw new HttpException(403);
+ }
+
+ return parent::verifyUserCanAccessChannel(
+ $request, str_replace(['private-', 'presence-'], '', $request->channel_name)
+ );
+ }
+
+ /**
+ * Return the valid authentication response.
+ *
+ * @param \Illuminate\Http\Request $request
+ * @param mixed $result
+ * @return mixed
+ */
+ public function validAuthenticationResponse($request, $result)
+ {
+ if (is_bool($result)) {
+ return json_encode($result);
+ }
+
+ return json_encode(['channel_data' => [
+ 'user_id' => $request->user()->getKey(),
+ 'user_info' => $result,
+ ]]);
+ }
+
+ /**
+ * Broadcast the given event.
+ *
+ * @param array $channels
+ * @param string $event
+ * @param array $payload
+ * @return void
*/
public function broadcast(array $channels, $event, array $payload = [])
{
@@ -47,7 +91,7 @@ public function broadcast(array $channels, $event, array $payload = [])
'event' => $event, 'data' => $payload, 'socket' => $socket,
]);
- foreach ($channels as $channel) {
+ foreach ($this->formatChannels($channels) as $channel) {
$connection->publish($channel, $payload);
}
}
diff --git a/src/Illuminate/Broadcasting/Channel.php b/src/Illuminate/Broadcasting/Channel.php
new file mode 100644
index 000000000000..798d6026a5f9
--- /dev/null
+++ b/src/Illuminate/Broadcasting/Channel.php
@@ -0,0 +1,34 @@
+name = $name;
+ }
+
+ /**
+ * Convert the channel instance to a string.
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ return $this->name;
+ }
+}
diff --git a/src/Illuminate/Broadcasting/PendingBroadcast.php b/src/Illuminate/Broadcasting/PendingBroadcast.php
new file mode 100644
index 000000000000..c972520b1ef6
--- /dev/null
+++ b/src/Illuminate/Broadcasting/PendingBroadcast.php
@@ -0,0 +1,59 @@
+event = $event;
+ $this->events = $events;
+ }
+
+ /**
+ * Handle the object's destruction.
+ *
+ * @return void
+ */
+ public function __destruct()
+ {
+ $this->events->fire($this->event);
+ }
+
+ /**
+ * Broadcast the event to everyone except the current user.
+ *
+ * @return $this
+ */
+ public function toOthers()
+ {
+ if (method_exists($this->event, 'dontBroadcastToCurrentUser')) {
+ $this->event->dontBroadcastToCurrentUser();
+ }
+
+ return $this;
+ }
+}
diff --git a/src/Illuminate/Broadcasting/PresenceChannel.php b/src/Illuminate/Broadcasting/PresenceChannel.php
new file mode 100644
index 000000000000..22de12d37f16
--- /dev/null
+++ b/src/Illuminate/Broadcasting/PresenceChannel.php
@@ -0,0 +1,17 @@
+storage[$key] = $this->storage[$key] + $value;
+ $this->storage[$key] = ((int) $this->storage[$key]) + $value;
return $this->storage[$key];
}
diff --git a/src/Illuminate/Cache/CacheManager.php b/src/Illuminate/Cache/CacheManager.php
index 69f7111ab2dd..bc1318e504ff 100755
--- a/src/Illuminate/Cache/CacheManager.php
+++ b/src/Illuminate/Cache/CacheManager.php
@@ -298,6 +298,6 @@ public function extend($driver, Closure $callback)
*/
public function __call($method, $parameters)
{
- return call_user_func_array([$this->store(), $method], $parameters);
+ return $this->store()->$method(...$parameters);
}
}
diff --git a/src/Illuminate/Cache/Console/CacheTableCommand.php b/src/Illuminate/Cache/Console/CacheTableCommand.php
index 2feedfd27d9a..7c3f4b62d519 100644
--- a/src/Illuminate/Cache/Console/CacheTableCommand.php
+++ b/src/Illuminate/Cache/Console/CacheTableCommand.php
@@ -35,7 +35,7 @@ class CacheTableCommand extends Command
protected $composer;
/**
- * Create a new session table command instance.
+ * Create a new cache table command instance.
*
* @param \Illuminate\Filesystem\Filesystem $files
* @param \Illuminate\Support\Composer $composer
diff --git a/src/Illuminate/Cache/Console/stubs/cache.stub b/src/Illuminate/Cache/Console/stubs/cache.stub
index c972a4fba790..cbcdfa970456 100644
--- a/src/Illuminate/Cache/Console/stubs/cache.stub
+++ b/src/Illuminate/Cache/Console/stubs/cache.stub
@@ -1,5 +1,6 @@
encrypter->decrypt($cache->value);
- $new = $callback($current, $value);
+ $new = $callback((int) $current, $value);
if (! is_numeric($current)) {
return false;
diff --git a/src/Illuminate/Cache/RedisStore.php b/src/Illuminate/Cache/RedisStore.php
index fa81c0ac48c6..ea80432e4b86 100755
--- a/src/Illuminate/Cache/RedisStore.php
+++ b/src/Illuminate/Cache/RedisStore.php
@@ -3,14 +3,14 @@
namespace Illuminate\Cache;
use Illuminate\Contracts\Cache\Store;
-use Illuminate\Redis\Database as Redis;
+use Illuminate\Contracts\Redis\Database;
class RedisStore extends TaggableStore implements Store
{
/**
* The Redis database connection.
*
- * @var \Illuminate\Redis\Database
+ * @var \Illuminate\Contracts\Redis\Database
*/
protected $redis;
@@ -31,12 +31,12 @@ class RedisStore extends TaggableStore implements Store
/**
* Create a new Redis store.
*
- * @param \Illuminate\Redis\Database $redis
+ * @param \Illuminate\Contracts\Redis\Database $redis
* @param string $prefix
* @param string $connection
* @return void
*/
- public function __construct(Redis $redis, $prefix = '', $connection = 'default')
+ public function __construct(Database $redis, $prefix = '', $connection = 'default')
{
$this->redis = $redis;
$this->setPrefix($prefix);
@@ -51,7 +51,9 @@ public function __construct(Redis $redis, $prefix = '', $connection = 'default')
*/
public function get($key)
{
- if (! is_null($value = $this->connection()->get($this->prefix.$key))) {
+ $value = $this->connection()->get($this->prefix.$key);
+
+ if (! is_null($value) && $value !== false) {
return is_numeric($value) ? $value : unserialize($value);
}
}
@@ -208,7 +210,7 @@ public function setConnection($connection)
/**
* Get the Redis database instance.
*
- * @return \Illuminate\Redis\Database
+ * @return \Illuminate\Contracts\Redis\Database
*/
public function getRedis()
{
diff --git a/src/Illuminate/Cache/Repository.php b/src/Illuminate/Cache/Repository.php
index 3c7eb9eece7d..a1983d793dc1 100755
--- a/src/Illuminate/Cache/Repository.php
+++ b/src/Illuminate/Cache/Repository.php
@@ -110,7 +110,9 @@ protected function fireCacheEvent($event, $payload)
*/
public function has($key)
{
- return ! is_null($this->get($key));
+ $value = $this->get($key);
+
+ return ! is_null($value) && $value !== false;
}
/**
@@ -128,7 +130,7 @@ public function get($key, $default = null)
$value = $this->store->get($this->itemKey($key));
- if (is_null($value)) {
+ if (is_null($value) || $value === false) {
$this->fireCacheEvent('missed', [$key]);
$value = value($default);
@@ -158,7 +160,7 @@ public function many(array $keys)
$values = $this->store->many($normalizedKeys);
foreach ($values as $key => &$value) {
- if (is_null($value)) {
+ if (is_null($value) || $value === false) {
$this->fireCacheEvent('missed', [$key]);
$value = isset($keys[$key]) ? value($keys[$key]) : null;
@@ -249,7 +251,9 @@ public function add($key, $value, $minutes)
return $this->store->add($this->itemKey($key), $value, $minutes);
}
- if (is_null($this->get($key))) {
+ $exists = $this->get($key);
+
+ if (is_null($exists) || $exists === false) {
$this->put($key, $value, $minutes);
return true;
@@ -306,10 +310,12 @@ public function forever($key, $value)
*/
public function remember($key, $minutes, Closure $callback)
{
+ $value = $this->get($key);
+
// If the item exists in the cache we will just return this immediately
// otherwise we will execute the given Closure and cache the result
// of that execution for the given number of minutes in storage.
- if (! is_null($value = $this->get($key))) {
+ if (! is_null($value) && $value !== false) {
return $value;
}
@@ -339,10 +345,12 @@ public function sear($key, Closure $callback)
*/
public function rememberForever($key, Closure $callback)
{
+ $value = $this->get($key);
+
// If the item exists in the cache we will just return this immediately
// otherwise we will execute the given Closure and cache the result
// of that execution for the given number of minutes. It's easy.
- if (! is_null($value = $this->get($key))) {
+ if (! is_null($value) && $value !== false) {
return $value;
}
@@ -506,7 +514,7 @@ public function __call($method, $parameters)
return $this->macroCall($method, $parameters);
}
- return call_user_func_array([$this->store, $method], $parameters);
+ return $this->store->$method(...$parameters);
}
/**
diff --git a/src/Illuminate/Cache/composer.json b/src/Illuminate/Cache/composer.json
index 1eaa26b83b2f..568ffb0e8764 100755
--- a/src/Illuminate/Cache/composer.json
+++ b/src/Illuminate/Cache/composer.json
@@ -2,7 +2,7 @@
"name": "illuminate/cache",
"description": "The Illuminate Cache package.",
"license": "MIT",
- "homepage": "http://laravel.com",
+ "homepage": "https://laravel.com",
"support": {
"issues": "https://github.com/laravel/framework/issues",
"source": "https://github.com/laravel/framework"
@@ -10,7 +10,7 @@
"authors": [
{
"name": "Taylor Otwell",
- "email": "taylorotwell@gmail.com"
+ "email": "taylor@laravel.com"
}
],
"require": {
diff --git a/src/Illuminate/Config/composer.json b/src/Illuminate/Config/composer.json
index d61855ad86a3..4e44ea7bb79a 100755
--- a/src/Illuminate/Config/composer.json
+++ b/src/Illuminate/Config/composer.json
@@ -2,7 +2,7 @@
"name": "illuminate/config",
"description": "The Illuminate Config package.",
"license": "MIT",
- "homepage": "http://laravel.com",
+ "homepage": "https://laravel.com",
"support": {
"issues": "https://github.com/laravel/framework/issues",
"source": "https://github.com/laravel/framework"
@@ -10,7 +10,7 @@
"authors": [
{
"name": "Taylor Otwell",
- "email": "taylorotwell@gmail.com"
+ "email": "taylor@laravel.com"
}
],
"require": {
diff --git a/src/Illuminate/Console/Scheduling/Event.php b/src/Illuminate/Console/Scheduling/Event.php
index ae10b0aa3311..1971d2a40ab3 100644
--- a/src/Illuminate/Console/Scheduling/Event.php
+++ b/src/Illuminate/Console/Scheduling/Event.php
@@ -341,7 +341,7 @@ public function cron($expression)
*/
public function hourly()
{
- return $this->cron('0 * * * * *');
+ return $this->spliceIntoPosition(1, 0);
}
/**
@@ -351,7 +351,8 @@ public function hourly()
*/
public function daily()
{
- return $this->cron('0 0 * * * *');
+ return $this->spliceIntoPosition(1, 0)
+ ->spliceIntoPosition(2, 0);
}
/**
@@ -481,7 +482,9 @@ public function sundays()
*/
public function weekly()
{
- return $this->cron('0 0 * * 0 *');
+ return $this->spliceIntoPosition(1, 0)
+ ->spliceIntoPosition(2, 0)
+ ->spliceIntoPosition(5, 0);
}
/**
@@ -505,7 +508,9 @@ public function weeklyOn($day, $time = '0:0')
*/
public function monthly()
{
- return $this->cron('0 0 1 * * *');
+ return $this->spliceIntoPosition(1, 0)
+ ->spliceIntoPosition(2, 0)
+ ->spliceIntoPosition(3, 1);
}
/**
@@ -529,7 +534,10 @@ public function monthlyOn($day = 1, $time = '0:0')
*/
public function quarterly()
{
- return $this->cron('0 0 1 */3 *');
+ return $this->spliceIntoPosition(1, 0)
+ ->spliceIntoPosition(2, 0)
+ ->spliceIntoPosition(3, 1)
+ ->spliceIntoPosition(4, '*/3');
}
/**
@@ -539,7 +547,10 @@ public function quarterly()
*/
public function yearly()
{
- return $this->cron('0 0 1 1 * *');
+ return $this->spliceIntoPosition(1, 0)
+ ->spliceIntoPosition(2, 0)
+ ->spliceIntoPosition(3, 1)
+ ->spliceIntoPosition(4, 1);
}
/**
@@ -549,7 +560,7 @@ public function yearly()
*/
public function everyMinute()
{
- return $this->cron('* * * * * *');
+ return $this->spliceIntoPosition(1, '*');
}
/**
@@ -559,7 +570,7 @@ public function everyMinute()
*/
public function everyFiveMinutes()
{
- return $this->cron('*/5 * * * * *');
+ return $this->spliceIntoPosition(1, '*/5');
}
/**
@@ -569,7 +580,7 @@ public function everyFiveMinutes()
*/
public function everyTenMinutes()
{
- return $this->cron('*/10 * * * * *');
+ return $this->spliceIntoPosition(1, '*/10');
}
/**
@@ -579,7 +590,7 @@ public function everyTenMinutes()
*/
public function everyThirtyMinutes()
{
- return $this->cron('0,30 * * * * *');
+ return $this->spliceIntoPosition(1, '0,30');
}
/**
diff --git a/src/Illuminate/Console/Scheduling/Schedule.php b/src/Illuminate/Console/Scheduling/Schedule.php
index b9bd265912ed..f5ee9cf813bc 100644
--- a/src/Illuminate/Console/Scheduling/Schedule.php
+++ b/src/Illuminate/Console/Scheduling/Schedule.php
@@ -39,15 +39,7 @@ public function command($command, array $parameters = [])
{
$binary = ProcessUtils::escapeArgument((new PhpExecutableFinder)->find(false));
- if (defined('HHVM_VERSION')) {
- $binary .= ' --php';
- }
-
- if (defined('ARTISAN_BINARY')) {
- $artisan = ProcessUtils::escapeArgument(ARTISAN_BINARY);
- } else {
- $artisan = 'artisan';
- }
+ $artisan = defined('ARTISAN_BINARY') ? ProcessUtils::escapeArgument(ARTISAN_BINARY) : 'artisan';
return $this->exec("{$binary} {$artisan} {$command}", $parameters);
}
diff --git a/src/Illuminate/Console/composer.json b/src/Illuminate/Console/composer.json
index 6c3464d7e6aa..f0b4bc02f014 100755
--- a/src/Illuminate/Console/composer.json
+++ b/src/Illuminate/Console/composer.json
@@ -2,7 +2,7 @@
"name": "illuminate/console",
"description": "The Illuminate Console package.",
"license": "MIT",
- "homepage": "http://laravel.com",
+ "homepage": "https://laravel.com",
"support": {
"issues": "https://github.com/laravel/framework/issues",
"source": "https://github.com/laravel/framework"
@@ -10,7 +10,7 @@
"authors": [
{
"name": "Taylor Otwell",
- "email": "taylorotwell@gmail.com"
+ "email": "taylor@laravel.com"
}
],
"require": {
diff --git a/src/Illuminate/Container/composer.json b/src/Illuminate/Container/composer.json
index c4ea9ad0b34a..aa98b334530e 100755
--- a/src/Illuminate/Container/composer.json
+++ b/src/Illuminate/Container/composer.json
@@ -2,7 +2,7 @@
"name": "illuminate/container",
"description": "The Illuminate Container package.",
"license": "MIT",
- "homepage": "http://laravel.com",
+ "homepage": "https://laravel.com",
"support": {
"issues": "https://github.com/laravel/framework/issues",
"source": "https://github.com/laravel/framework"
@@ -10,7 +10,7 @@
"authors": [
{
"name": "Taylor Otwell",
- "email": "taylorotwell@gmail.com"
+ "email": "taylor@laravel.com"
}
],
"require": {
diff --git a/src/Illuminate/Contracts/Auth/Access/Gate.php b/src/Illuminate/Contracts/Auth/Access/Gate.php
index 04f3e5e41968..9d8389089515 100644
--- a/src/Illuminate/Contracts/Auth/Access/Gate.php
+++ b/src/Illuminate/Contracts/Auth/Access/Gate.php
@@ -38,6 +38,14 @@ public function policy($class, $policy);
*/
public function before(callable $callback);
+ /**
+ * Register a callback to run after all Gate checks.
+ *
+ * @param callable $callback
+ * @return $this
+ */
+ public function after(callable $callback);
+
/**
* Determine if the given ability should be granted for the current user.
*
@@ -65,6 +73,27 @@ public function denies($ability, $arguments = []);
*/
public function check($ability, $arguments = []);
+ /**
+ * Determine if the given ability should be granted for the current user.
+ *
+ * @param string $ability
+ * @param array|mixed $arguments
+ * @return \Illuminate\Auth\Access\Response
+ *
+ * @throws \Illuminate\Auth\Access\AuthorizationException
+ */
+ public function authorize($ability, $arguments = []);
+
+ /**
+ * Get a policy instance for a given class.
+ *
+ * @param object|string $class
+ * @return mixed
+ *
+ * @throws \InvalidArgumentException
+ */
+ public function getPolicyFor($class);
+
/**
* Get a guard instance for the given user.
*
diff --git a/src/Illuminate/Contracts/Broadcasting/Broadcaster.php b/src/Illuminate/Contracts/Broadcasting/Broadcaster.php
index 73643669c2b4..1034e4406823 100644
--- a/src/Illuminate/Contracts/Broadcasting/Broadcaster.php
+++ b/src/Illuminate/Contracts/Broadcasting/Broadcaster.php
@@ -4,6 +4,23 @@
interface Broadcaster
{
+ /**
+ * Authenticate the incoming request for a given channel.
+ *
+ * @param \Illuminate\Http\Request $request
+ * @return mixed
+ */
+ public function auth($request);
+
+ /**
+ * Return the valid authentication response.
+ *
+ * @param \Illuminate\Http\Request $request
+ * @param mixed $result
+ * @return mixed
+ */
+ public function validAuthenticationResponse($request, $result);
+
/**
* Broadcast the given event.
*
diff --git a/src/Illuminate/Contracts/Notifications/Dispatcher.php b/src/Illuminate/Contracts/Notifications/Dispatcher.php
index 17b8d3e9e2cb..696376620cd6 100644
--- a/src/Illuminate/Contracts/Notifications/Dispatcher.php
+++ b/src/Illuminate/Contracts/Notifications/Dispatcher.php
@@ -4,13 +4,13 @@
interface Dispatcher
{
- /**
- * Dispatch the given notification instance to the given notifiable.
- *
- * @param mixed $notifiable
- * @param mixed $instance
- * @param array $channels
- * @return void
- */
- public function dispatch($notifiable, $instance, array $channels = []);
+ // *
+ // * Dispatch the given notification instance to the given notifiable.
+ // *
+ // * @param mixed $notifiable
+ // * @param mixed $instance
+ // * @param array $channels
+ // * @return void
+
+ // public function dispatch($notifiable, $instance, array $channels = []);
}
diff --git a/src/Illuminate/Contracts/Queue/Job.php b/src/Illuminate/Contracts/Queue/Job.php
index 50d849dd2740..577b75e0c8f9 100644
--- a/src/Illuminate/Contracts/Queue/Job.php
+++ b/src/Illuminate/Contracts/Queue/Job.php
@@ -54,6 +54,13 @@ public function attempts();
*/
public function getName();
+ /**
+ * Get the resolved name of the queued job class.
+ *
+ * @return string
+ */
+ public function resolveName();
+
/**
* Call the failed method on the job instance.
*
diff --git a/src/Illuminate/Contracts/Queue/Queue.php b/src/Illuminate/Contracts/Queue/Queue.php
index 3f9e38304720..b5b5c9427c14 100644
--- a/src/Illuminate/Contracts/Queue/Queue.php
+++ b/src/Illuminate/Contracts/Queue/Queue.php
@@ -4,6 +4,14 @@
interface Queue
{
+ /**
+ * Get the size of the queue.
+ *
+ * @param string $queue
+ * @return int
+ */
+ public function size($queue = null);
+
/**
* Push a new job onto the queue.
*
diff --git a/src/Illuminate/Contracts/composer.json b/src/Illuminate/Contracts/composer.json
index 18e4c9f7d683..e836001ddcaf 100644
--- a/src/Illuminate/Contracts/composer.json
+++ b/src/Illuminate/Contracts/composer.json
@@ -2,7 +2,7 @@
"name": "illuminate/contracts",
"description": "The Illuminate Contracts package.",
"license": "MIT",
- "homepage": "http://laravel.com",
+ "homepage": "https://laravel.com",
"support": {
"issues": "https://github.com/laravel/framework/issues",
"source": "https://github.com/laravel/framework"
@@ -10,7 +10,7 @@
"authors": [
{
"name": "Taylor Otwell",
- "email": "taylorotwell@gmail.com"
+ "email": "taylor@laravel.com"
}
],
"require": {
diff --git a/src/Illuminate/Cookie/composer.json b/src/Illuminate/Cookie/composer.json
index aeccfa7ddbe2..176cd71fdf06 100755
--- a/src/Illuminate/Cookie/composer.json
+++ b/src/Illuminate/Cookie/composer.json
@@ -2,7 +2,7 @@
"name": "illuminate/cookie",
"description": "The Illuminate Cookie package.",
"license": "MIT",
- "homepage": "http://laravel.com",
+ "homepage": "https://laravel.com",
"support": {
"issues": "https://github.com/laravel/framework/issues",
"source": "https://github.com/laravel/framework"
@@ -10,7 +10,7 @@
"authors": [
{
"name": "Taylor Otwell",
- "email": "taylorotwell@gmail.com"
+ "email": "taylor@laravel.com"
}
],
"require": {
diff --git a/src/Illuminate/Database/Capsule/Manager.php b/src/Illuminate/Database/Capsule/Manager.php
index 5800df0603d3..b82a792ce7d2 100755
--- a/src/Illuminate/Database/Capsule/Manager.php
+++ b/src/Illuminate/Database/Capsule/Manager.php
@@ -196,6 +196,6 @@ public function setEventDispatcher(Dispatcher $dispatcher)
*/
public static function __callStatic($method, $parameters)
{
- return call_user_func_array([static::connection(), $method], $parameters);
+ return static::connection()->$method(...$parameters);
}
}
diff --git a/src/Illuminate/Database/Connection.php b/src/Illuminate/Database/Connection.php
index b593559da384..9efaabedac1e 100755
--- a/src/Illuminate/Database/Connection.php
+++ b/src/Illuminate/Database/Connection.php
@@ -407,7 +407,7 @@ public function bindValues($statement, $bindings)
foreach ($bindings as $key => $value) {
$statement->bindValue(
is_string($key) ? $key : $key + 1, $value,
- filter_var($value, FILTER_VALIDATE_FLOAT) !== false ? PDO::PARAM_INT : PDO::PARAM_STR
+ ! is_string($value) && is_numeric($value) ? PDO::PARAM_INT : PDO::PARAM_STR
);
}
}
diff --git a/src/Illuminate/Database/DatabaseManager.php b/src/Illuminate/Database/DatabaseManager.php
index 17f8bf676fa1..1021507c1416 100755
--- a/src/Illuminate/Database/DatabaseManager.php
+++ b/src/Illuminate/Database/DatabaseManager.php
@@ -314,6 +314,6 @@ public function getConnections()
*/
public function __call($method, $parameters)
{
- return call_user_func_array([$this->connection(), $method], $parameters);
+ return $this->connection()->$method(...$parameters);
}
}
diff --git a/src/Illuminate/Database/Eloquent/Builder.php b/src/Illuminate/Database/Eloquent/Builder.php
index 6b3194416e01..40ef104174e7 100755
--- a/src/Illuminate/Database/Eloquent/Builder.php
+++ b/src/Illuminate/Database/Eloquent/Builder.php
@@ -3,6 +3,7 @@
namespace Illuminate\Database\Eloquent;
use Closure;
+use BadMethodCallException;
use Illuminate\Support\Arr;
use Illuminate\Support\Str;
use Illuminate\Pagination\Paginator;
@@ -233,7 +234,9 @@ public function findOrNew($id, $columns = ['*'])
*/
public function firstOrNew(array $attributes)
{
- if (! is_null($instance = $this->where($attributes)->first())) {
+ $mutatedAttributes = $this->model->newInstance($attributes)->getAttributes();
+
+ if (! is_null($instance = $this->where($mutatedAttributes)->first())) {
return $instance;
}
@@ -249,7 +252,9 @@ public function firstOrNew(array $attributes)
*/
public function firstOrCreate(array $attributes, array $values = [])
{
- if (! is_null($instance = $this->where($attributes)->first())) {
+ $mutatedAttributes = $this->model->newInstance($attributes)->getAttributes();
+
+ if (! is_null($instance = $this->where($mutatedAttributes)->first())) {
return $instance;
}
@@ -677,7 +682,11 @@ public function getRelation($name)
// not have to remove these where clauses manually which gets really hacky
// and is error prone while we remove the developer's own where clauses.
$relation = Relation::noConstraints(function () use ($name) {
- return $this->getModel()->$name();
+ try {
+ return $this->getModel()->$name();
+ } catch (BadMethodCallException $e) {
+ throw RelationNotFoundException::make($this->getModel(), $name);
+ }
});
$nested = $this->nestedRelations($name);
@@ -1287,7 +1296,7 @@ protected function nestWhereSlice($whereSlice, $boolean = 'and')
/**
* Get the underlying query builder instance.
*
- * @return \Illuminate\Database\Query\Builder|static
+ * @return \Illuminate\Database\Query\Builder
*/
public function getQuery()
{
diff --git a/src/Illuminate/Database/Eloquent/Collection.php b/src/Illuminate/Database/Eloquent/Collection.php
index d52c4d8c5992..59a48f6ca454 100755
--- a/src/Illuminate/Database/Eloquent/Collection.php
+++ b/src/Illuminate/Database/Eloquent/Collection.php
@@ -114,6 +114,21 @@ public function merge($items)
return new static(array_values($dictionary));
}
+ /**
+ * Run a map over each of the items.
+ *
+ * @param callable $callback
+ * @return static
+ */
+ public function map(callable $callback)
+ {
+ $result = parent::map($callback);
+
+ return $result->contains(function ($item) {
+ return ! $item instanceof Model;
+ }) ? $result->toBase() : $result;
+ }
+
/**
* Diff the collection with the given items.
*
@@ -160,12 +175,13 @@ public function intersect($items)
* Return only unique items from the collection.
*
* @param string|callable|null $key
+ * @param bool $strict
* @return static
*/
- public function unique($key = null)
+ public function unique($key = null, $strict = false)
{
if (! is_null($key)) {
- return parent::unique($key);
+ return parent::unique($key, $strict);
}
return new static(array_values($this->getDictionary()));
@@ -341,14 +357,4 @@ public function getQueueableIds()
{
return $this->modelKeys();
}
-
- /**
- * Get a base Support collection instance from this collection.
- *
- * @return \Illuminate\Support\Collection
- */
- public function toBase()
- {
- return new BaseCollection($this->items);
- }
}
diff --git a/src/Illuminate/Database/Eloquent/FactoryBuilder.php b/src/Illuminate/Database/Eloquent/FactoryBuilder.php
index 3fdb4b0b2e9a..8107dc788760 100644
--- a/src/Illuminate/Database/Eloquent/FactoryBuilder.php
+++ b/src/Illuminate/Database/Eloquent/FactoryBuilder.php
@@ -104,15 +104,11 @@ public function make(array $attributes = [])
{
if ($this->amount === 1) {
return $this->makeInstance($attributes);
- } else {
- $results = [];
-
- for ($i = 0; $i < $this->amount; $i++) {
- $results[] = $this->makeInstance($attributes);
- }
-
- return new Collection($results);
}
+
+ return new Collection(array_map(function () use ($attributes) {
+ return $this->makeInstance($attributes);
+ }, range(1, $this->amount)));
}
/**
diff --git a/src/Illuminate/Database/Eloquent/Model.php b/src/Illuminate/Database/Eloquent/Model.php
index e946d4b81ef9..cddc22555d8b 100644
--- a/src/Illuminate/Database/Eloquent/Model.php
+++ b/src/Illuminate/Database/Eloquent/Model.php
@@ -182,13 +182,6 @@ abstract class Model implements ArrayAccess, Arrayable, Jsonable, JsonSerializab
*/
protected $with = [];
- /**
- * The class name to be used in polymorphic relations.
- *
- * @var string
- */
- protected $morphClass;
-
/**
* Indicates if the model exists.
*
@@ -2036,7 +2029,7 @@ public function getMorphClass()
return array_search($class, $morphMap, true);
}
- return $this->morphClass ?: $class;
+ return $class;
}
/**
@@ -2108,6 +2101,21 @@ public function addHidden($attributes = null)
$this->hidden = array_merge($this->hidden, $attributes);
}
+ /**
+ * Make the given, typically visible, attributes hidden.
+ *
+ * @param array|string $attributes
+ * @return $this
+ */
+ public function makeHidden($attributes)
+ {
+ $this->visible = array_diff($this->visible, (array) $attributes);
+
+ $this->hidden = array_unique(array_merge($this->hidden, $attributes));
+
+ return $this;
+ }
+
/**
* Make the given, typically hidden, attributes visible.
*
@@ -2567,10 +2575,14 @@ protected function getArrayableRelations()
protected function getArrayableItems(array $values)
{
if (count($this->getVisible()) > 0) {
- return array_intersect_key($values, array_flip($this->getVisible()));
+ $values = array_intersect_key($values, array_flip($this->getVisible()));
}
- return array_diff_key($values, array_flip($this->getHidden()));
+ if (count($this->getHidden()) > 0) {
+ $values = array_diff_key($values, array_flip($this->getHidden()));
+ }
+
+ return $values;
}
/**
@@ -3139,6 +3151,17 @@ public function isDirty($attributes = null)
return false;
}
+ /**
+ * Determine if the model or given attribute(s) have remained the same.
+ *
+ * @param array|string|null $attributes
+ * @return bool
+ */
+ public function isClean($attributes = null)
+ {
+ return ! $this->isDirty(...func_get_args());
+ }
+
/**
* Get the attributes that have been changed since last sync.
*
diff --git a/src/Illuminate/Database/Eloquent/RelationNotFoundException.php b/src/Illuminate/Database/Eloquent/RelationNotFoundException.php
new file mode 100755
index 000000000000..5026ac9c8910
--- /dev/null
+++ b/src/Illuminate/Database/Eloquent/RelationNotFoundException.php
@@ -0,0 +1,22 @@
+ [], 'detached' => [],
+ ];
+
+ if ($ids instanceof Model) {
+ $ids = $ids->getKey();
+ }
+
+ if ($ids instanceof Collection) {
+ $ids = $ids->modelKeys();
+ }
+
+ // First we will execute a query to get all of the current attached IDs for
+ // the relationship, which will allow us to determine which of them will
+ // be attached and which of them will be detached from the join table.
+ $current = $this->newPivotQuery()
+ ->pluck($this->otherKey)->all();
+
+ $records = $this->formatRecordsList((array) $ids);
+
+ // Next, we will determine which IDs should get removed from the join table
+ // by checking which of the given ID / records is in the list of current
+ // records. We will then remove all those rows from the joining table.
+ $detach = array_values(array_intersect(
+ $current, array_keys($records)
+ ));
+
+ if (count($detach) > 0) {
+ $this->detach($detach, false);
+
+ $changes['detached'] = $this->castKeys($detach);
+ }
+
+ // Finally, for all of the records that were not detached, we'll attach the
+ // records into the intermediate table. Then we'll add those attaches to
+ // the change list and be ready to return these results to the caller.
+ $attach = array_diff_key($records, array_flip($detach));
+
+ if (count($attach) > 0) {
+ $this->attach($attach, [], false);
+
+ $changes['attached'] = array_keys($attach);
+ }
+
+ if (count($changes['attached']) || count($changes['detached'])) {
+ $this->touchIfTouching();
+ }
+
+ return $changes;
+ }
+
+ /**
+ * Sync the intermediate tables with a list of IDs without detaching.
+ *
+ * @param \Illuminate\Database\Eloquent\Collection|array $ids
+ * @return array
+ */
+ public function syncWithoutDetaching($ids)
+ {
+ return $this->sync($ids, false);
+ }
+
/**
* Sync the intermediate tables with a list of IDs or collection of models.
*
@@ -817,7 +889,7 @@ public function sync($ids, $detaching = true)
// if they exist in the array of current ones, and if not we will insert.
$current = $this->newPivotQuery()->pluck($this->otherKey)->all();
- $records = $this->formatSyncList($ids);
+ $records = $this->formatRecordsList($ids);
$detach = array_diff($current, array_keys($records));
@@ -827,9 +899,7 @@ public function sync($ids, $detaching = true)
if ($detaching && count($detach) > 0) {
$this->detach($detach);
- $changes['detached'] = (array) array_map(function ($v) {
- return is_numeric($v) ? (int) $v : (string) $v;
- }, $detach);
+ $changes['detached'] = $this->castKeys($detach);
}
// Now we are finally ready to attach the new records. Note that we'll disable
@@ -847,12 +917,12 @@ public function sync($ids, $detaching = true)
}
/**
- * Format the sync list so that it is keyed by ID.
+ * Format the sync/toggle list so that it is keyed by ID.
*
* @param array $records
* @return array
*/
- protected function formatSyncList(array $records)
+ protected function formatRecordsList(array $records)
{
$results = [];
@@ -901,6 +971,19 @@ protected function attachNew(array $records, array $current, $touch = true)
return $changes;
}
+ /**
+ * Cast the given keys to integers if they are numeric and string otherwise.
+ *
+ * @param arary $keys
+ * @return array
+ */
+ protected function castKeys(array $keys)
+ {
+ return (array) array_map(function ($v) {
+ return is_numeric($v) ? (int) $v : (string) $v;
+ }, $keys);
+ }
+
/**
* Update an existing pivot record on the table.
*
diff --git a/src/Illuminate/Database/Eloquent/SoftDeletingScope.php b/src/Illuminate/Database/Eloquent/SoftDeletingScope.php
index dee43bb4d523..86770d78dfde 100644
--- a/src/Illuminate/Database/Eloquent/SoftDeletingScope.php
+++ b/src/Illuminate/Database/Eloquent/SoftDeletingScope.php
@@ -9,7 +9,7 @@ class SoftDeletingScope implements Scope
*
* @var array
*/
- protected $extensions = ['ForceDelete', 'Restore', 'WithTrashed', 'OnlyTrashed'];
+ protected $extensions = ['ForceDelete', 'Restore', 'WithTrashed', 'WithoutTrashed', 'OnlyTrashed'];
/**
* Apply the scope to a given Eloquent query builder.
@@ -100,6 +100,25 @@ protected function addWithTrashed(Builder $builder)
});
}
+ /**
+ * Add the without-trashed extension to the builder.
+ *
+ * @param \Illuminate\Database\Eloquent\Builder $builder
+ * @return void
+ */
+ protected function addWithoutTrashed(Builder $builder)
+ {
+ $builder->macro('withoutTrashed', function (Builder $builder) {
+ $model = $builder->getModel();
+
+ $builder->withoutGlobalScope($this)->whereNull(
+ $model->getQualifiedDeletedAtColumn()
+ );
+
+ return $builder;
+ });
+ }
+
/**
* Add the only-trashed extension to the builder.
*
diff --git a/src/Illuminate/Database/Query/Builder.php b/src/Illuminate/Database/Query/Builder.php
index 42e7c810d6c2..6da0772d4f08 100755
--- a/src/Illuminate/Database/Query/Builder.php
+++ b/src/Illuminate/Database/Query/Builder.php
@@ -1078,6 +1078,33 @@ public function orWhereDate($column, $operator, $value)
return $this->whereDate($column, $operator, $value, 'or');
}
+ /**
+ * Add a "where time" statement to the query.
+ *
+ * @param string $column
+ * @param string $operator
+ * @param int $value
+ * @param string $boolean
+ * @return \Illuminate\Database\Query\Builder|static
+ */
+ public function whereTime($column, $operator, $value, $boolean = 'and')
+ {
+ return $this->addDateBasedWhere('Time', $column, $operator, $value, $boolean);
+ }
+
+ /**
+ * Add an "or where time" statement to the query.
+ *
+ * @param string $column
+ * @param string $operator
+ * @param int $value
+ * @return \Illuminate\Database\Query\Builder|static
+ */
+ public function orWhereTime($column, $operator, $value)
+ {
+ return $this->whereTime($column, $operator, $value, 'or');
+ }
+
/**
* Add a "where day" statement to the query.
*
@@ -1133,7 +1160,7 @@ public function whereYear($column, $operator, $value = null, $boolean = 'and')
}
/**
- * Add a date based (year, month, day) statement to the query.
+ * Add a date based (year, month, day, time) statement to the query.
*
* @param string $type
* @param string $column
@@ -1682,7 +1709,17 @@ public function getCountForPagination($columns = ['*'])
return count($results);
}
- return isset($results[0]) ? (int) array_change_key_case((array) $results[0])['aggregate'] : 0;
+ if (! isset($results[0])) {
+ return 0;
+ }
+
+ $item = $results[0];
+
+ if (is_object($item)) {
+ return (int) $item->aggregate;
+ }
+
+ return (int) array_change_key_case((array) $item)['aggregate'];
}
/**
@@ -2001,8 +2038,18 @@ public function aggregate($function, $columns = ['*'])
if (! $results->isEmpty()) {
$result = array_change_key_case((array) $results[0]);
- return $result['aggregate'];
+ if (is_int($result['aggregate']) || is_float($result['aggregate'])) {
+ return $result['aggregate'];
+ }
+
+ if (strpos((string) $result['aggregate'], '.') !== false) {
+ return (int) $result['aggregate'];
+ }
+
+ return (float) $result['aggregate'];
}
+
+ return 0;
}
/**
@@ -2114,6 +2161,10 @@ public function updateOrInsert(array $attributes, array $values = [])
*/
public function increment($column, $amount = 1, array $extra = [])
{
+ if (! is_numeric($amount)) {
+ throw new InvalidArgumentException('Non-numeric value passed to increment method.');
+ }
+
$wrapped = $this->grammar->wrap($column);
$columns = array_merge([$column => $this->raw("$wrapped + $amount")], $extra);
@@ -2131,6 +2182,10 @@ public function increment($column, $amount = 1, array $extra = [])
*/
public function decrement($column, $amount = 1, array $extra = [])
{
+ if (! is_numeric($amount)) {
+ throw new InvalidArgumentException('Non-numeric value passed to decrement method.');
+ }
+
$wrapped = $this->grammar->wrap($column);
$columns = array_merge([$column => $this->raw("$wrapped - $amount")], $extra);
diff --git a/src/Illuminate/Database/Query/Grammars/Grammar.php b/src/Illuminate/Database/Query/Grammars/Grammar.php
index e51e6ec4047a..47beabc26398 100755
--- a/src/Illuminate/Database/Query/Grammars/Grammar.php
+++ b/src/Illuminate/Database/Query/Grammars/Grammar.php
@@ -389,6 +389,18 @@ protected function whereDate(Builder $query, $where)
return $this->dateBasedWhere('date', $query, $where);
}
+ /**
+ * Compile a "where time" clause.
+ *
+ * @param \Illuminate\Database\Query\Builder $query
+ * @param array $where
+ * @return string
+ */
+ protected function whereTime(Builder $query, $where)
+ {
+ return $this->dateBasedWhere('time', $query, $where);
+ }
+
/**
* Compile a "where day" clause.
*
diff --git a/src/Illuminate/Database/README.md b/src/Illuminate/Database/README.md
index 1675a9325de9..e7cdeed2c8b4 100755
--- a/src/Illuminate/Database/README.md
+++ b/src/Illuminate/Database/README.md
@@ -67,4 +67,4 @@ class User extends Illuminate\Database\Eloquent\Model {}
$users = User::where('votes', '>', 1)->get();
```
-For further documentation on using the various database facilities this library provides, consult the [Laravel framework documentation](http://laravel.com/docs).
+For further documentation on using the various database facilities this library provides, consult the [Laravel framework documentation](https://laravel.com/docs).
diff --git a/src/Illuminate/Database/composer.json b/src/Illuminate/Database/composer.json
index 4f7e03144db7..7aa0525adcf7 100644
--- a/src/Illuminate/Database/composer.json
+++ b/src/Illuminate/Database/composer.json
@@ -2,7 +2,7 @@
"name": "illuminate/database",
"description": "The Illuminate Database package.",
"license": "MIT",
- "homepage": "http://laravel.com",
+ "homepage": "https://laravel.com",
"support": {
"issues": "https://github.com/laravel/framework/issues",
"source": "https://github.com/laravel/framework"
@@ -11,7 +11,7 @@
"authors": [
{
"name": "Taylor Otwell",
- "email": "taylorotwell@gmail.com"
+ "email": "taylor@laravel.com"
}
],
"require": {
diff --git a/src/Illuminate/Encryption/composer.json b/src/Illuminate/Encryption/composer.json
index 0c79358ca1aa..481391089a7d 100644
--- a/src/Illuminate/Encryption/composer.json
+++ b/src/Illuminate/Encryption/composer.json
@@ -2,7 +2,7 @@
"name": "illuminate/encryption",
"description": "The Illuminate Encryption package.",
"license": "MIT",
- "homepage": "http://laravel.com",
+ "homepage": "https://laravel.com",
"support": {
"issues": "https://github.com/laravel/framework/issues",
"source": "https://github.com/laravel/framework"
@@ -10,7 +10,7 @@
"authors": [
{
"name": "Taylor Otwell",
- "email": "taylorotwell@gmail.com"
+ "email": "taylor@laravel.com"
}
],
"require": {
diff --git a/src/Illuminate/Events/Dispatcher.php b/src/Illuminate/Events/Dispatcher.php
index 63dc8996f034..ede7ebe64017 100755
--- a/src/Illuminate/Events/Dispatcher.php
+++ b/src/Illuminate/Events/Dispatcher.php
@@ -7,8 +7,8 @@
use Illuminate\Support\Str;
use Illuminate\Container\Container;
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
-use Illuminate\Contracts\Broadcasting\ShouldBroadcastNow;
use Illuminate\Contracts\Events\Dispatcher as DispatcherContract;
+use Illuminate\Contracts\Broadcasting\Factory as BroadcastFactory;
use Illuminate\Contracts\Container\Container as ContainerContract;
class Dispatcher implements DispatcherContract
@@ -252,15 +252,7 @@ public function fire($event, $payload = [], $halt = false)
*/
protected function broadcastEvent($event)
{
- if ($this->queueResolver) {
- $connection = $event instanceof ShouldBroadcastNow ? 'sync' : null;
-
- $queue = method_exists($event, 'onQueue') ? $event->onQueue() : null;
-
- $this->resolveQueue()->connection($connection)->pushOn($queue, 'Illuminate\Broadcasting\BroadcastEvent', [
- 'event' => serialize(clone $event),
- ]);
- }
+ $this->container->make(BroadcastFactory::class)->queue($event);
}
/**
@@ -303,21 +295,30 @@ protected function getWildcardListeners($eventName)
* Sort the listeners for a given event by priority.
*
* @param string $eventName
- * @return array
+ * @return void
*/
protected function sortListeners($eventName)
{
- $this->sorted[$eventName] = [];
-
// If listeners exist for the given event, we will sort them by the priority
// so that we can call them in the correct order. We will cache off these
// sorted event listeners so we do not have to re-sort on every events.
- if (isset($this->listeners[$eventName])) {
- krsort($this->listeners[$eventName]);
+ $listeners = isset($this->listeners[$eventName])
+ ? $this->listeners[$eventName] : [];
+
+ if (class_exists($eventName, false)) {
+ foreach (class_implements($eventName) as $interface) {
+ if (isset($this->listeners[$interface])) {
+ $listeners = array_merge_recursive($listeners, $this->listeners[$interface]);
+ }
+ }
+ }
- $this->sorted[$eventName] = call_user_func_array(
- 'array_merge', $this->listeners[$eventName]
- );
+ if ($listeners) {
+ krsort($listeners);
+
+ $this->sorted[$eventName] = call_user_func_array('array_merge', $listeners);
+ } else {
+ $this->sorted[$eventName] = [];
}
}
diff --git a/src/Illuminate/Events/composer.json b/src/Illuminate/Events/composer.json
index ca5c9c7deea6..0605612ddc58 100755
--- a/src/Illuminate/Events/composer.json
+++ b/src/Illuminate/Events/composer.json
@@ -2,7 +2,7 @@
"name": "illuminate/events",
"description": "The Illuminate Events package.",
"license": "MIT",
- "homepage": "http://laravel.com",
+ "homepage": "https://laravel.com",
"support": {
"issues": "https://github.com/laravel/framework/issues",
"source": "https://github.com/laravel/framework"
@@ -10,7 +10,7 @@
"authors": [
{
"name": "Taylor Otwell",
- "email": "taylorotwell@gmail.com"
+ "email": "taylor@laravel.com"
}
],
"require": {
diff --git a/src/Illuminate/Filesystem/FilesystemManager.php b/src/Illuminate/Filesystem/FilesystemManager.php
index adb4092bc650..8ca82309dff1 100644
--- a/src/Illuminate/Filesystem/FilesystemManager.php
+++ b/src/Illuminate/Filesystem/FilesystemManager.php
@@ -325,6 +325,6 @@ public function extend($driver, Closure $callback)
*/
public function __call($method, $parameters)
{
- return call_user_func_array([$this->disk(), $method], $parameters);
+ return $this->disk()->$method(...$parameters);
}
}
diff --git a/src/Illuminate/Filesystem/composer.json b/src/Illuminate/Filesystem/composer.json
index 0242fac70fdf..492799d795e6 100644
--- a/src/Illuminate/Filesystem/composer.json
+++ b/src/Illuminate/Filesystem/composer.json
@@ -2,7 +2,7 @@
"name": "illuminate/filesystem",
"description": "The Illuminate Filesystem package.",
"license": "MIT",
- "homepage": "http://laravel.com",
+ "homepage": "https://laravel.com",
"support": {
"issues": "https://github.com/laravel/framework/issues",
"source": "https://github.com/laravel/framework"
@@ -10,7 +10,7 @@
"authors": [
{
"name": "Taylor Otwell",
- "email": "taylorotwell@gmail.com"
+ "email": "taylor@laravel.com"
}
],
"require": {
diff --git a/src/Illuminate/Foundation/Auth/Access/AuthorizesRequests.php b/src/Illuminate/Foundation/Auth/Access/AuthorizesRequests.php
index 92ffcbb7ebc2..c678c6e0eeb3 100644
--- a/src/Illuminate/Foundation/Auth/Access/AuthorizesRequests.php
+++ b/src/Illuminate/Foundation/Auth/Access/AuthorizesRequests.php
@@ -98,7 +98,6 @@ public function authorizeResource($model, $parameter = null, array $options = []
protected function resourceAbilityMap()
{
return [
- 'index' => 'view',
'show' => 'view',
'create' => 'create',
'store' => 'create',
diff --git a/src/Illuminate/Foundation/Auth/ResetsPasswords.php b/src/Illuminate/Foundation/Auth/ResetsPasswords.php
index 7f4105474547..cf79ace0bc45 100644
--- a/src/Illuminate/Foundation/Auth/ResetsPasswords.php
+++ b/src/Illuminate/Foundation/Auth/ResetsPasswords.php
@@ -54,7 +54,7 @@ public function reset(Request $request)
// redirect them back to where they came from with their error message.
return $response == Password::PASSWORD_RESET
? $this->sendResetResponse($response)
- : $this->sendResetFailedResponse($response);
+ : $this->sendResetFailedResponse($request, $response);
}
/**
@@ -102,10 +102,11 @@ protected function sendResetResponse($response)
/**
* Get the response for a failed password reset.
*
+ * @param \Illuminate\Http\Request
* @param string $response
* @return \Illuminate\Http\Response
*/
- protected function sendResetFailedResponse($response)
+ protected function sendResetFailedResponse(Request $request, $response)
{
return redirect()->back()
->withInput($request->only('email'))
diff --git a/src/Illuminate/Foundation/Console/Kernel.php b/src/Illuminate/Foundation/Console/Kernel.php
index 0c67528bfd31..ec46c44dbd46 100644
--- a/src/Illuminate/Foundation/Console/Kernel.php
+++ b/src/Illuminate/Foundation/Console/Kernel.php
@@ -8,6 +8,7 @@
use Illuminate\Contracts\Events\Dispatcher;
use Illuminate\Console\Scheduling\Schedule;
use Illuminate\Console\Application as Artisan;
+use Illuminate\Console\Events\ArtisanStarting;
use Illuminate\Contracts\Foundation\Application;
use Illuminate\Contracts\Console\Kernel as KernelContract;
use Symfony\Component\Debug\Exception\FatalThrowableError;
@@ -167,7 +168,11 @@ protected function commands()
*/
public function command($signature, Closure $callback)
{
- $this->registerCommand($command = new ClosureCommand($signature, $callback));
+ $command = new ClosureCommand($signature, $callback);
+
+ $this->app['events']->listen(ArtisanStarting::class, function ($event) use ($command) {
+ $event->artisan->add($command);
+ });
return $command;
}
diff --git a/src/Illuminate/Foundation/Console/RouteListCommand.php b/src/Illuminate/Foundation/Console/RouteListCommand.php
index 1abd6cae669e..dbb8531c82b9 100644
--- a/src/Illuminate/Foundation/Console/RouteListCommand.php
+++ b/src/Illuminate/Foundation/Console/RouteListCommand.php
@@ -159,7 +159,8 @@ protected function getControllerMiddleware($actionName)
$segments = explode('@', $actionName);
return $this->getControllerMiddlewareFromInstance(
- $this->laravel->make($segments[0]), $segments[1]
+ $this->laravel->make($segments[0]),
+ isset($segments[1]) ? $segments[1] : null
);
}
@@ -167,17 +168,21 @@ protected function getControllerMiddleware($actionName)
* Get the middlewares for the given controller instance and method.
*
* @param \Illuminate\Routing\Controller $controller
- * @param string $method
+ * @param string|null $method
* @return array
*/
protected function getControllerMiddlewareFromInstance($controller, $method)
{
+ if (! method_exists($controller, 'getMiddleware')) {
+ return [];
+ }
+
$middleware = $this->router->getMiddleware();
$results = [];
foreach ($controller->getMiddleware() as $name => $options) {
- if (! $this->methodExcludedByOptions($method, $options)) {
+ if (! $method || ! $this->methodExcludedByOptions($method, $options)) {
$results[] = Arr::get($middleware, $name, $name);
}
}
diff --git a/src/Illuminate/Foundation/Console/ServeCommand.php b/src/Illuminate/Foundation/Console/ServeCommand.php
index 90e596e9788e..9c3478cca3f9 100644
--- a/src/Illuminate/Foundation/Console/ServeCommand.php
+++ b/src/Illuminate/Foundation/Console/ServeCommand.php
@@ -2,7 +2,6 @@
namespace Illuminate\Foundation\Console;
-use Exception;
use Illuminate\Console\Command;
use Symfony\Component\Process\ProcessUtils;
use Symfony\Component\Console\Input\InputOption;
@@ -45,15 +44,7 @@ public function fire()
$this->info("Laravel development server started on http://{$host}:{$port}/");
- if (defined('HHVM_VERSION')) {
- if (version_compare(HHVM_VERSION, '3.8.0') >= 0) {
- passthru("{$binary} -m server -v Server.Type=proxygen -v Server.SourceRoot={$base}/ -v Server.IP={$host} -v Server.Port={$port} -v Server.DefaultDocument=server.php -v Server.ErrorDocument404=server.php");
- } else {
- throw new Exception("HHVM's built-in server requires HHVM >= 3.8.0.");
- }
- } else {
- passthru("{$binary} -S {$host}:{$port} {$base}/server.php");
- }
+ passthru("{$binary} -S {$host}:{$port} {$base}/server.php");
}
/**
diff --git a/src/Illuminate/Foundation/Console/ViewClearCommand.php b/src/Illuminate/Foundation/Console/ViewClearCommand.php
index 74b919ebe347..c7e443e7d67a 100644
--- a/src/Illuminate/Foundation/Console/ViewClearCommand.php
+++ b/src/Illuminate/Foundation/Console/ViewClearCommand.php
@@ -2,6 +2,7 @@
namespace Illuminate\Foundation\Console;
+use RuntimeException;
use Illuminate\Console\Command;
use Illuminate\Filesystem\Filesystem;
@@ -48,9 +49,13 @@ public function __construct(Filesystem $files)
*/
public function fire()
{
- $views = $this->files->glob($this->laravel['config']['view.compiled'].'/*');
+ $path = $this->laravel['config']['view.compiled'];
- foreach ($views as $view) {
+ if (! $path) {
+ throw new RuntimeException('View path not found.');
+ }
+
+ foreach ($this->files->glob("{$path}/*") as $view) {
$this->files->delete($view);
}
diff --git a/src/Illuminate/Foundation/Console/stubs/event.stub b/src/Illuminate/Foundation/Console/stubs/event.stub
index db435cfd5a14..9e61b6359b08 100644
--- a/src/Illuminate/Foundation/Console/stubs/event.stub
+++ b/src/Illuminate/Foundation/Console/stubs/event.stub
@@ -2,7 +2,10 @@
namespace DummyNamespace;
+use Illuminate\Broadcasting\Channel;
use Illuminate\Queue\SerializesModels;
+use Illuminate\Broadcasting\PrivateChannel;
+use Illuminate\Broadcasting\PresenceChannel;
use Illuminate\Broadcasting\InteractsWithSockets;
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
@@ -21,12 +24,12 @@ class DummyClass
}
/**
- * Get the channels the event should be broadcast on.
+ * Get the channels the event should broadcast on.
*
- * @return array
+ * @return Channel|array
*/
public function broadcastOn()
{
- return [];
+ return new PrivateChannel('channel-name');
}
}
diff --git a/src/Illuminate/Foundation/Console/stubs/mail.stub b/src/Illuminate/Foundation/Console/stubs/mail.stub
index f517c152680a..402313448769 100644
--- a/src/Illuminate/Foundation/Console/stubs/mail.stub
+++ b/src/Illuminate/Foundation/Console/stubs/mail.stub
@@ -5,6 +5,7 @@ namespace DummyNamespace;
use Illuminate\Bus\Queueable;
use Illuminate\Mail\Mailable;
use Illuminate\Queue\SerializesModels;
+use Illuminate\Contracts\Queue\ShouldQueue;
class DummyClass extends Mailable
{
diff --git a/src/Illuminate/Foundation/Console/stubs/notification.stub b/src/Illuminate/Foundation/Console/stubs/notification.stub
index dce1e296a1c0..cc537f517aff 100644
--- a/src/Illuminate/Foundation/Console/stubs/notification.stub
+++ b/src/Illuminate/Foundation/Console/stubs/notification.stub
@@ -5,6 +5,7 @@ namespace DummyNamespace;
use Illuminate\Bus\Queueable;
use Illuminate\Notifications\Notification;
use Illuminate\Contracts\Queue\ShouldQueue;
+use Illuminate\Notifications\Messages\MailMessage;
class DummyClass extends Notification
{
@@ -21,9 +22,10 @@ class DummyClass extends Notification
}
/**
- * Get the notification channels.
+ * Get the notification's delivery channels.
*
- * @return array|string
+ * @param mixed $notifiable
+ * @return array
*/
public function via($notifiable)
{
@@ -31,14 +33,29 @@ class DummyClass extends Notification
}
/**
- * Get the notification message.
+ * Get the mail representation of the notification.
*
- * @return \Illuminate\Notifications\MessageBuilder
+ * @param mixed $notifiable
+ * @return \Illuminate\Notifications\Messages\MailMessage
*/
- public function message()
+ public function toMail($notifiable)
{
- return $this->line('The introduction to the notification.')
+ return (new MailMessage)
+ ->line('The introduction to the notification.')
->action('Notification Action', 'https://laravel.com')
->line('Thank you for using our application!');
}
+
+ /**
+ * Get the array representation of the notification.
+ *
+ * @param mixed $notifiable
+ * @return array
+ */
+ public function toArray($notifiable)
+ {
+ return [
+ //
+ ];
+ }
}
diff --git a/src/Illuminate/Foundation/Console/stubs/policy.stub b/src/Illuminate/Foundation/Console/stubs/policy.stub
index 04f73e216413..59dcf5925839 100644
--- a/src/Illuminate/Foundation/Console/stubs/policy.stub
+++ b/src/Illuminate/Foundation/Console/stubs/policy.stub
@@ -10,17 +10,6 @@ class DummyClass
{
use HandlesAuthorization;
- /**
- * Determine whether the user can view dummyPluralModelName.
- *
- * @param DummyRootNamespaceUser $user
- * @return mixed
- */
- public function viewAny(User $user)
- {
- //
- }
-
/**
* Determine whether the user can view the dummyModelName.
*
@@ -39,18 +28,7 @@ class DummyClass
* @param DummyRootNamespaceUser $user
* @return mixed
*/
- public function createAny(User $user)
- {
- //
- }
-
- /**
- * Determine whether the user can update dummyPluralModelName.
- *
- * @param DummyRootNamespaceUser $user
- * @return mixed
- */
- public function updateAny(User $user)
+ public function create(User $user)
{
//
}
diff --git a/src/Illuminate/Foundation/Console/stubs/request.stub b/src/Illuminate/Foundation/Console/stubs/request.stub
index 06294e3f8d09..6653f57a91a0 100644
--- a/src/Illuminate/Foundation/Console/stubs/request.stub
+++ b/src/Illuminate/Foundation/Console/stubs/request.stub
@@ -2,9 +2,9 @@
namespace DummyNamespace;
-use DummyRootNamespaceHttp\Requests\Request;
+use Illuminate\Foundation\Http\FormRequest;
-class DummyClass extends Request
+class DummyClass extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
diff --git a/src/Illuminate/Foundation/Providers/ArtisanServiceProvider.php b/src/Illuminate/Foundation/Providers/ArtisanServiceProvider.php
index 83f1ec090081..08a1c440ff17 100755
--- a/src/Illuminate/Foundation/Providers/ArtisanServiceProvider.php
+++ b/src/Illuminate/Foundation/Providers/ArtisanServiceProvider.php
@@ -41,6 +41,7 @@
use Illuminate\Foundation\Console\VendorPublishCommand;
use Illuminate\Database\Console\Seeds\SeederMakeCommand;
use Illuminate\Foundation\Console\NotificationMakeCommand;
+use Illuminate\Notifications\Console\NotificationTableCommand;
class ArtisanServiceProvider extends ServiceProvider
{
@@ -93,6 +94,7 @@ class ArtisanServiceProvider extends ServiceProvider
'MiddlewareMake' => 'command.middleware.make',
'ModelMake' => 'command.model.make',
'NotificationMake' => 'command.notification.make',
+ 'NotificationTable' => 'command.notification.table',
'PolicyMake' => 'command.policy.make',
'ProviderMake' => 'command.provider.make',
'QueueFailedTable' => 'command.queue.failed-table',
@@ -590,6 +592,18 @@ protected function registerPolicyMakeCommand()
});
}
+ /**
+ * Register the command.
+ *
+ * @return void
+ */
+ protected function registerNotificationTableCommand()
+ {
+ $this->app->singleton('command.notification.table', function ($app) {
+ return new NotificationTableCommand($app['files'], $app['composer']);
+ });
+ }
+
/**
* Get the services provided by the provider.
*
diff --git a/src/Illuminate/Foundation/Support/Providers/RouteServiceProvider.php b/src/Illuminate/Foundation/Support/Providers/RouteServiceProvider.php
index c14313c3e9a8..ad0435851b1b 100644
--- a/src/Illuminate/Foundation/Support/Providers/RouteServiceProvider.php
+++ b/src/Illuminate/Foundation/Support/Providers/RouteServiceProvider.php
@@ -2,6 +2,7 @@
namespace Illuminate\Foundation\Support\Providers;
+use Illuminate\Routing\Router;
use Illuminate\Support\Facades\Route;
use Illuminate\Support\ServiceProvider;
use Illuminate\Contracts\Routing\UrlGenerator;
diff --git a/src/Illuminate/Foundation/Testing/Concerns/InteractsWithPages.php b/src/Illuminate/Foundation/Testing/Concerns/InteractsWithPages.php
index 28db9d42a06b..e81aa361aa41 100644
--- a/src/Illuminate/Foundation/Testing/Concerns/InteractsWithPages.php
+++ b/src/Illuminate/Foundation/Testing/Concerns/InteractsWithPages.php
@@ -61,6 +61,18 @@ public function visit($uri)
return $this->makeRequest('GET', $uri);
}
+ /**
+ * Visit the given named route with a GET request.
+ *
+ * @param string $route
+ * @param array $parameters
+ * @return $this
+ */
+ public function visitRoute($route, $parameters = [])
+ {
+ return $this->makeRequest('GET', route($route, $parameters));
+ }
+
/**
* Make a request to the application and create a Crawler instance.
*
@@ -172,6 +184,18 @@ protected function seePageIs($uri)
return $this;
}
+ /**
+ * Assert that the current page matches a given named route.
+ *
+ * @param string $route
+ * @param array $parameters
+ * @return $this
+ */
+ protected function seeRouteIs($route, $parameters = [])
+ {
+ return $this->seePageIs(route($route, $parameters));
+ }
+
/**
* Assert that a given page successfully loaded.
*
diff --git a/src/Illuminate/Foundation/Testing/Concerns/MakesHttpRequests.php b/src/Illuminate/Foundation/Testing/Concerns/MakesHttpRequests.php
index 64153d844089..074519c7da0c 100644
--- a/src/Illuminate/Foundation/Testing/Concerns/MakesHttpRequests.php
+++ b/src/Illuminate/Foundation/Testing/Concerns/MakesHttpRequests.php
@@ -321,14 +321,14 @@ protected function seeJsonContains(array $data, $negate = false)
$actual = json_encode(Arr::sortRecursive(
(array) $this->decodeResponseJson()
- ));
+ ), JSON_PRETTY_PRINT);
foreach (Arr::sortRecursive($data) as $key => $value) {
$expected = $this->formatToExpectedJson($key, $value);
$this->{$method}(
Str::contains($actual, $expected),
- ($negate ? 'Found unexpected' : 'Unable to find')." JSON fragment [{$expected}] within [{$actual}]."
+ ($negate ? 'Found unexpected' : 'Unable to find').' JSON fragment'.PHP_EOL."[{$expected}]".PHP_EOL.'within'.PHP_EOL."[{$actual}]."
);
}
@@ -373,7 +373,7 @@ protected function decodeResponseJson()
*/
protected function formatToExpectedJson($key, $value)
{
- $expected = json_encode([$key => $value]);
+ $expected = json_encode([$key => $value], JSON_PRETTY_PRINT);
if (Str::startsWith($expected, '{')) {
$expected = substr($expected, 1);
diff --git a/src/Illuminate/Foundation/Testing/TestCase.php b/src/Illuminate/Foundation/Testing/TestCase.php
index 42c4e1da4500..979c2f38d542 100755
--- a/src/Illuminate/Foundation/Testing/TestCase.php
+++ b/src/Illuminate/Foundation/Testing/TestCase.php
@@ -100,14 +100,14 @@ protected function setUpTraits()
{
$uses = array_flip(class_uses_recursive(static::class));
- if (isset($uses[DatabaseTransactions::class])) {
- $this->beginDatabaseTransaction();
- }
-
if (isset($uses[DatabaseMigrations::class])) {
$this->runDatabaseMigrations();
}
+ if (isset($uses[DatabaseTransactions::class])) {
+ $this->beginDatabaseTransaction();
+ }
+
if (isset($uses[WithoutMiddleware::class])) {
$this->disableMiddlewareForAllTests();
}
diff --git a/src/Illuminate/Foundation/helpers.php b/src/Illuminate/Foundation/helpers.php
index 0f798a6fea12..d52ae3084f13 100644
--- a/src/Illuminate/Foundation/helpers.php
+++ b/src/Illuminate/Foundation/helpers.php
@@ -12,6 +12,7 @@
use Illuminate\Contracts\Cookie\Factory as CookieFactory;
use Illuminate\Database\Eloquent\Factory as EloquentFactory;
use Illuminate\Contracts\Validation\Factory as ValidationFactory;
+use Illuminate\Contracts\Broadcasting\Factory as BroadcastFactory;
if (! function_exists('abort')) {
/**
@@ -191,6 +192,19 @@ function bcrypt($value, $options = [])
}
}
+if (! function_exists('broadcast')) {
+ /**
+ * Begin broadcasting an event.
+ *
+ * @param mixed|null $event
+ * @return \Illuminate\Broadcasting\PendingBroadcast|void
+ */
+ function broadcast($event = null)
+ {
+ return app(BroadcastFactory::class)->event($event);
+ }
+}
+
if (! function_exists('cache')) {
/**
* Get / set the specified cache value.
@@ -589,7 +603,7 @@ function redirect($to = null, $status = 302, $headers = [], $secure = null)
/**
* Get an instance of the current request or an input item from the request.
*
- * @param string $key
+ * @param array|string $key
* @param mixed $default
* @return \Illuminate\Http\Request|string|array
*/
@@ -599,10 +613,28 @@ function request($key = null, $default = null)
return app('request');
}
+ if (is_array($key)) {
+ return app('request')->only($key);
+ }
+
return app('request')->input($key, $default);
}
}
+if (! function_exists('resolve')) {
+ /**
+ * Resolve a service from the container.
+ *
+ * @param string $name
+ * @param array $parameters
+ * @return mixed
+ */
+ function resolve($name, $parameters = [])
+ {
+ return app($name, $parameters);
+ }
+}
+
if (! function_exists('resource_path')) {
/**
* Get the path to the resources folder.
diff --git a/src/Illuminate/Hashing/composer.json b/src/Illuminate/Hashing/composer.json
index 09548cf731f3..8442f35685b1 100755
--- a/src/Illuminate/Hashing/composer.json
+++ b/src/Illuminate/Hashing/composer.json
@@ -2,7 +2,7 @@
"name": "illuminate/hashing",
"description": "The Illuminate Hashing package.",
"license": "MIT",
- "homepage": "http://laravel.com",
+ "homepage": "https://laravel.com",
"support": {
"issues": "https://github.com/laravel/framework/issues",
"source": "https://github.com/laravel/framework"
@@ -10,7 +10,7 @@
"authors": [
{
"name": "Taylor Otwell",
- "email": "taylorotwell@gmail.com"
+ "email": "taylor@laravel.com"
}
],
"require": {
diff --git a/src/Illuminate/Http/Request.php b/src/Illuminate/Http/Request.php
index 2ef5cadfc187..bf5b51757abe 100644
--- a/src/Illuminate/Http/Request.php
+++ b/src/Illuminate/Http/Request.php
@@ -273,7 +273,7 @@ public function exists($key)
$input = $this->all();
foreach ($keys as $value) {
- if (! array_key_exists($value, $input)) {
+ if (! Arr::has($input, $value)) {
return false;
}
}
@@ -340,7 +340,7 @@ public function input($key = null, $default = null)
}
/**
- * Get a subset of the items from the input data.
+ * Get a subset containing the provided keys with values from the input data.
*
* @param array|mixed $keys
* @return array
@@ -461,7 +461,7 @@ protected function convertUploadedFiles(array $files)
*
* @param string $key
* @param mixed $default
- * @return \Symfony\Component\HttpFoundation\File\UploadedFile|array|null
+ * @return \Illuminate\Http\UploadedFile|array|null
*/
public function file($key = null, $default = null)
{
@@ -923,16 +923,13 @@ public function route($param = null)
*/
public function fingerprint()
{
- if (! $this->route()) {
+ if (! $route = $this->route()) {
throw new RuntimeException('Unable to generate fingerprint. Route unavailable.');
}
- return sha1(
- implode('|', $this->route()->methods()).
- '|'.$this->route()->domain().
- '|'.$this->route()->uri().
- '|'.$this->ip()
- );
+ return sha1(implode('|', array_merge(
+ $route->methods(), [$route->domain(), $route->uri(), $this->ip()]
+ )));
}
/**
@@ -1026,7 +1023,7 @@ public function offsetGet($offset)
*/
public function offsetSet($offset, $value)
{
- return $this->getInputSource()->set($offset, $value);
+ $this->getInputSource()->set($offset, $value);
}
/**
@@ -1037,7 +1034,7 @@ public function offsetSet($offset, $value)
*/
public function offsetUnset($offset)
{
- return $this->getInputSource()->remove($offset);
+ $this->getInputSource()->remove($offset);
}
/**
@@ -1059,12 +1056,10 @@ public function __isset($key)
*/
public function __get($key)
{
- $all = $this->all();
-
- if (array_key_exists($key, $all)) {
- return $all[$key];
- } else {
- return $this->route($key);
+ if ($this->offsetExists($key)) {
+ return $this->offsetGet($key);
}
+
+ return $this->route($key);
}
}
diff --git a/src/Illuminate/Http/composer.json b/src/Illuminate/Http/composer.json
index 52ef78494686..409554dbe3bf 100755
--- a/src/Illuminate/Http/composer.json
+++ b/src/Illuminate/Http/composer.json
@@ -2,7 +2,7 @@
"name": "illuminate/http",
"description": "The Illuminate Http package.",
"license": "MIT",
- "homepage": "http://laravel.com",
+ "homepage": "https://laravel.com",
"support": {
"issues": "https://github.com/laravel/framework/issues",
"source": "https://github.com/laravel/framework"
@@ -10,7 +10,7 @@
"authors": [
{
"name": "Taylor Otwell",
- "email": "taylorotwell@gmail.com"
+ "email": "taylor@laravel.com"
}
],
"require": {
diff --git a/src/Illuminate/Log/composer.json b/src/Illuminate/Log/composer.json
index 7e406a863de6..0d157d5fe5c9 100755
--- a/src/Illuminate/Log/composer.json
+++ b/src/Illuminate/Log/composer.json
@@ -2,7 +2,7 @@
"name": "illuminate/log",
"description": "The Illuminate Log package.",
"license": "MIT",
- "homepage": "http://laravel.com",
+ "homepage": "https://laravel.com",
"support": {
"issues": "https://github.com/laravel/framework/issues",
"source": "https://github.com/laravel/framework"
@@ -10,7 +10,7 @@
"authors": [
{
"name": "Taylor Otwell",
- "email": "taylorotwell@gmail.com"
+ "email": "taylor@laravel.com"
}
],
"require": {
diff --git a/src/Illuminate/Mail/Jobs/HandleQueuedMessage.php b/src/Illuminate/Mail/Jobs/HandleQueuedMessage.php
new file mode 100644
index 000000000000..848c59ae6a81
--- /dev/null
+++ b/src/Illuminate/Mail/Jobs/HandleQueuedMessage.php
@@ -0,0 +1,96 @@
+view = $view;
+ $this->data = $data;
+ $this->callback = $callback;
+ }
+
+ /**
+ * Handle the queued job.
+ *
+ * @param \Illuminate\Contracts\Mail\Mailer $mailer
+ * @return void
+ */
+ public function handle(Mailer $mailer)
+ {
+ $mailer->send($this->view, $this->data, $this->callback);
+ }
+
+ /**
+ * Prepare the instance for serialization.
+ *
+ * @return array
+ */
+ public function __sleep()
+ {
+ foreach ($this->data as $key => $value) {
+ $this->data[$key] = $this->getSerializedPropertyValue($value);
+ }
+
+ if ($this->callback instanceof Closure) {
+ $this->callback = (new Serializer)->serialize($this->callback);
+ }
+
+ return array_keys(get_object_vars($this));
+ }
+
+ /**
+ * Restore the model after serialization.
+ *
+ * @return void
+ */
+ public function __wakeup()
+ {
+ foreach ($this->data as $key => $value) {
+ $this->data[$key] = $this->getRestoredPropertyValue($value);
+ }
+
+ if (Str::contains($this->callback, 'SerializableClosure')) {
+ $this->callback = (new Serializer)->unserialize($this->callback);
+ }
+ }
+}
diff --git a/src/Illuminate/Mail/Mailable.php b/src/Illuminate/Mail/Mailable.php
index 85091e4c887d..f56b2b75349e 100644
--- a/src/Illuminate/Mail/Mailable.php
+++ b/src/Illuminate/Mail/Mailable.php
@@ -7,8 +7,8 @@
use Illuminate\Support\Str;
use Illuminate\Support\Collection;
use Illuminate\Container\Container;
-use Illuminate\Contracts\Mail\Mailer;
use Illuminate\Contracts\Queue\Factory as Queue;
+use Illuminate\Contracts\Mail\Mailer as MailerContract;
use Illuminate\Contracts\Mail\Mailable as MailableContract;
class Mailable implements MailableContract
@@ -100,10 +100,10 @@ class Mailable implements MailableContract
/**
* Send the message using the given mailer.
*
- * @param Mailer $mailer
+ * @param \Illuminate\Contracts\Mail\Mailer $mailer
* @return void
*/
- public function send(Mailer $mailer)
+ public function send(MailerContract $mailer)
{
Container::getInstance()->call([$this, 'build']);
@@ -119,7 +119,7 @@ public function send(Mailer $mailer)
/**
* Queue the message for sending.
*
- * @param Queue $queue
+ * @param \Illuminate\Contracts\Queue\Factory $queue
* @return mixed
*/
public function queue(Queue $queue)
@@ -289,7 +289,7 @@ protected function runCallbacks($message)
*/
public function from($address, $name = null)
{
- $this->setAddress($address, $name, 'from');
+ return $this->setAddress($address, $name, 'from');
}
/**
@@ -345,6 +345,7 @@ public function replyTo($address, $name = null)
*
* @param object|array|string $address
* @param string|null $name
+ * @param string $property
* @return $this
*/
protected function setAddress($address, $name = null, $property = 'to')
@@ -395,7 +396,7 @@ public function view($view, array $data = [])
/**
* Set the plain text view for the message.
*
- * @param string $view
+ * @param string $textView
* @param array $data
* @return $this
*/
@@ -410,12 +411,17 @@ public function text($textView, array $data = [])
/**
* Set the view data for the message.
*
- * @param array $data
+ * @param string|array $key
+ * @param mixed $value
* @return $this
*/
- public function with(array $data)
+ public function with($key, $value = null)
{
- $this->viewData = $data;
+ if (is_array($key)) {
+ $this->viewData = array_merge($this->viewData, $key);
+ } else {
+ $this->viewData[$key] = $value;
+ }
return $this;
}
diff --git a/src/Illuminate/Mail/MailableMailer.php b/src/Illuminate/Mail/MailableMailer.php
index befc9dae778b..bc967b45cd70 100644
--- a/src/Illuminate/Mail/MailableMailer.php
+++ b/src/Illuminate/Mail/MailableMailer.php
@@ -2,6 +2,8 @@
namespace Illuminate\Mail;
+use Illuminate\Contracts\Queue\ShouldQueue;
+
class MailableMailer
{
/**
@@ -90,41 +92,49 @@ public function bcc($users)
*/
public function send(Mailable $mailable)
{
- $mailable = $mailable->to($this->to)
- ->cc($this->cc)
- ->bcc($this->bcc);
+ if ($mailable instanceof ShouldQueue) {
+ return $this->queue($this->fill($mailable));
+ }
- return $this->mailer->send($mailable);
+ return $this->mailer->send($this->fill($mailable));
}
/**
- * Queue a mailable message for sending.
+ * Send a mailable message immediately.
*
* @param Mailable $mailable
* @return mixed
*/
- public function queue(Mailable $mailable)
+ public function sendNow(Mailable $mailable)
{
- $mailable = $mailable->to($this->to)
- ->cc($this->cc)
- ->bcc($this->bcc);
+ return $this->mailer->send($this->fill($mailable));
+ }
- return $this->mailer->queue($mailable);
+ /**
+ * Populate the mailable with the addresses.
+ *
+ * @param Mailable $mailable
+ * @return Mailable
+ */
+ protected function fill(Mailable $mailable)
+ {
+ return $mailable->to($this->to)
+ ->cc($this->cc)
+ ->bcc($this->bcc);
}
/**
- * Deliver the queued message after the given delay.
+ * Push the given mailable onto the queue.
*
- * @param \DateTime|int $delay
* @param Mailable $mailable
* @return mixed
*/
- public function later($delay, Mailable $mailable)
+ protected function queue(Mailable $mailable)
{
- $mailable = $mailable->to($this->to)
- ->cc($this->cc)
- ->bcc($this->bcc);
+ if (isset($mailable->delay)) {
+ return $this->mailer->later($mailable->delay, $mailable);
+ }
- return $this->mailer->later($delay, $mailable);
+ return $this->mailer->queue($mailable);
}
}
diff --git a/src/Illuminate/Mail/Mailer.php b/src/Illuminate/Mail/Mailer.php
index 9561440ea3e9..54a76aa1335b 100755
--- a/src/Illuminate/Mail/Mailer.php
+++ b/src/Illuminate/Mail/Mailer.php
@@ -6,8 +6,6 @@
use Swift_Mailer;
use Swift_Message;
use Illuminate\Support\Arr;
-use Illuminate\Support\Str;
-use SuperClosure\Serializer;
use InvalidArgumentException;
use Illuminate\Contracts\View\Factory;
use Illuminate\Contracts\Events\Dispatcher;
@@ -213,10 +211,8 @@ public function queue($view, array $data = [], $callback = null, $queue = null)
return $view->queue($this->queue);
}
- $callback = $this->buildQueueCallable($callback);
-
- return $this->queue->push(
- 'mailer@handleQueuedMessage', compact('view', 'data', 'callback'), $queue
+ return $this->queue->pushOn(
+ $queue, new Jobs\HandleQueuedMessage($view, $data, $callback)
);
}
@@ -266,11 +262,8 @@ public function later($delay, $view, array $data = [], $callback = null, $queue
return $view->later($delay, $this->queue);
}
- $callback = $this->buildQueueCallable($callback);
-
- return $this->queue->later(
- $delay, 'mailer@handleQueuedMessage',
- compact('view', 'data', 'callback'), $queue
+ return $this->queue->laterOn(
+ $queue, $delay, new Jobs\HandleQueuedMessage($view, $data, $callback)
);
}
@@ -289,50 +282,6 @@ public function laterOn($queue, $delay, $view, array $data, $callback)
return $this->later($delay, $view, $data, $callback, $queue);
}
- /**
- * Build the callable for a queued e-mail job.
- *
- * @param \Closure|string $callback
- * @return string
- */
- protected function buildQueueCallable($callback)
- {
- if (! $callback instanceof Closure) {
- return $callback;
- }
-
- return (new Serializer)->serialize($callback);
- }
-
- /**
- * Handle a queued e-mail message job.
- *
- * @param \Illuminate\Contracts\Queue\Job $job
- * @param array $data
- * @return void
- */
- public function handleQueuedMessage($job, $data)
- {
- $this->send($data['view'], $data['data'], $this->getQueuedCallable($data));
-
- $job->delete();
- }
-
- /**
- * Get the true callable for a queued e-mail message.
- *
- * @param array $data
- * @return \Closure|string
- */
- protected function getQueuedCallable(array $data)
- {
- if (Str::contains($data['callback'], 'SerializableClosure')) {
- return (new Serializer)->unserialize($data['callback']);
- }
-
- return $data['callback'];
- }
-
/**
* Force the transport to re-connect.
*
diff --git a/src/Illuminate/Mail/SendQueuedMailable.php b/src/Illuminate/Mail/SendQueuedMailable.php
index 1d5bd36601e5..995b5a88d536 100644
--- a/src/Illuminate/Mail/SendQueuedMailable.php
+++ b/src/Illuminate/Mail/SendQueuedMailable.php
@@ -2,7 +2,7 @@
namespace Illuminate\Mail;
-use Illuminate\Contracts\Mail\Mailer;
+use Illuminate\Contracts\Mail\Mailer as MailerContract;
use Illuminate\Contracts\Mail\Mailable as MailableContract;
class SendQueuedMailable
@@ -28,10 +28,10 @@ public function __construct(MailableContract $mailable)
/**
* Handle the queued job.
*
- * @param Mailer $mailer
+ * @param MailerContract $mailer
* @return void
*/
- public function handle(Mailer $mailer)
+ public function handle(MailerContract $mailer)
{
$mailer->send($this->mailable);
}
diff --git a/src/Illuminate/Mail/Transport/MailgunTransport.php b/src/Illuminate/Mail/Transport/MailgunTransport.php
index 21bffea0e5a4..f8378322868d 100644
--- a/src/Illuminate/Mail/Transport/MailgunTransport.php
+++ b/src/Illuminate/Mail/Transport/MailgunTransport.php
@@ -46,8 +46,8 @@ class MailgunTransport extends Transport
*/
public function __construct(ClientInterface $client, $key, $domain)
{
- $this->client = $client;
$this->key = $key;
+ $this->client = $client;
$this->setDomain($domain);
}
diff --git a/src/Illuminate/Mail/composer.json b/src/Illuminate/Mail/composer.json
index 0986a9d8e803..ad96ea5a6bb8 100755
--- a/src/Illuminate/Mail/composer.json
+++ b/src/Illuminate/Mail/composer.json
@@ -2,7 +2,7 @@
"name": "illuminate/mail",
"description": "The Illuminate Mail package.",
"license": "MIT",
- "homepage": "http://laravel.com",
+ "homepage": "https://laravel.com",
"support": {
"issues": "https://github.com/laravel/framework/issues",
"source": "https://github.com/laravel/framework"
@@ -10,7 +10,7 @@
"authors": [
{
"name": "Taylor Otwell",
- "email": "taylorotwell@gmail.com"
+ "email": "taylor@laravel.com"
}
],
"require": {
diff --git a/src/Illuminate/Notifications/Action.php b/src/Illuminate/Notifications/Action.php
index f59f86836d1a..071db2d9efdc 100644
--- a/src/Illuminate/Notifications/Action.php
+++ b/src/Illuminate/Notifications/Action.php
@@ -23,6 +23,7 @@ class Action
*
* @param string $text
* @param string $url
+ * @return void
*/
public function __construct($text, $url)
{
diff --git a/src/Illuminate/Notifications/ChannelManager.php b/src/Illuminate/Notifications/ChannelManager.php
index 20e77c214bb8..0ffdd783b408 100644
--- a/src/Illuminate/Notifications/ChannelManager.php
+++ b/src/Illuminate/Notifications/ChannelManager.php
@@ -2,6 +2,7 @@
namespace Illuminate\Notifications;
+use Ramsey\Uuid\Uuid;
use InvalidArgumentException;
use Illuminate\Support\Manager;
use Nexmo\Client as NexmoClient;
@@ -22,83 +23,84 @@ class ChannelManager extends Manager implements DispatcherContract, FactoryContr
protected $defaultChannels = ['mail', 'database'];
/**
- * Create a new notification for the given notifiable entities.
+ * Send the given notification to the given notifiable entities.
*
- * @param array $notifiables
- * @return \Illuminate\Notifications\Channels\Notification
+ * @param \Illuminate\Support\Collection|array $notifiables
+ * @param mixed $notification
+ * @return void
*/
- public function to($notifiables)
+ public function send($notifiables, $notification)
{
- return new Channels\Notification($notifiables);
+ if ($notification instanceof ShouldQueue) {
+ return $this->queueNotification($notifiables, $notification);
+ }
+
+ return $this->sendNow($notifiables, $notification);
}
/**
- * Dispatch the given notification instance to the given notifiable.
+ * Send the given notification immediately.
*
- * @param mixed $notifiable
- * @param mixed $instance
- * @param array $channels
+ * @param \Illuminate\Support\Collection|array $notifiables
+ * @param mixed $notification
* @return void
*/
- public function dispatch($notifiable, $instance, array $channels = [])
+ public function sendNow($notifiables, $notification)
{
- $notifications = $this->notificationsFromInstance(
- $notifiable, $instance
- );
+ foreach ($notifiables as $notifiable) {
+ $notification = clone $notification;
+
+ $notification->id = (string) Uuid::uuid4();
- if (count($channels) > 0) {
- foreach ($notifications as $notification) {
- $notification->via((array) $channels);
+ $channels = $notification->via($notifiable);
+
+ if (empty($channels)) {
+ continue;
}
- }
- if ($instance instanceof ShouldQueue) {
- return $this->queueNotifications($instance, $notifications);
- }
+ foreach ($channels as $channel) {
+ if (! $this->shouldSendNotification($notifiable, $notification, $channel)) {
+ continue;
+ }
+
+ $this->driver($channel)->send($notifiable, $notification);
- foreach ($notifications as $notification) {
- $this->send($notification);
+ $this->app->make('events')->fire(
+ new Events\NotificationSent($notifiable, $notification, $channel)
+ );
+ }
}
}
/**
- * Queue the given notification instances.
+ * Determines if the notification can be sent.
*
- * @param mixed $instance
- * @param array[\Illuminate\Notifcations\Channels\Notification]
- * @return void
+ * @param mixed $notifiable
+ * @param mixed $notification
+ * @param string $channel
+ * @return bool
*/
- protected function queueNotifications($instance, array $notifications)
+ protected function shouldSendNotification($notifiable, $notification, $channel)
{
- $this->app->make(Bus::class)->dispatch(
- (new SendQueuedNotifications($notifications))
- ->onConnection($instance->connection)
- ->onQueue($instance->queue)
- ->delay($instance->delay)
- );
+ return $this->app->make('events')->until(
+ new Events\NotificationSending($notifiable, $notification, $channel)
+ ) !== false;
}
/**
- * Send the given notification.
+ * Queue the given notification instances.
*
- * @param \Illuminate\Notifications\Channels\Notification $notification
+ * @param mixed $notifiables
+ * @param array[\Illuminate\Notifcations\Channels\Notification] $notification
* @return void
*/
- public function send(Channels\Notification $notification)
+ protected function queueNotification($notifiables, $notification)
{
- if (! $notification->application) {
- $notification->application(
- $this->app['config']['app.name'],
- $this->app['config']['app.logo']
- );
- }
-
- foreach ($notification->via ?: $this->deliversVia() as $channel) {
- $this->driver($channel)->send($notification);
- }
-
- $this->app->make('events')->fire(
- new Events\NotificationSent($notification)
+ $this->app->make(Bus::class)->dispatch(
+ (new SendQueuedNotifications($notifiables, $notification))
+ ->onConnection($notification->connection)
+ ->onQueue($notification->queue)
+ ->delay($notification->delay)
);
}
@@ -123,6 +125,16 @@ protected function createDatabaseDriver()
return $this->app->make(Channels\DatabaseChannel::class);
}
+ /**
+ * Create an instance of the broadcast driver.
+ *
+ * @return \Illuminate\Notifications\Channels\BroadcastChannel
+ */
+ protected function createBroadcastDriver()
+ {
+ return $this->app->make(Channels\BroadcastChannel::class);
+ }
+
/**
* Create an instance of the mail driver.
*
@@ -210,17 +222,4 @@ public function deliverVia($channels)
{
$this->defaultChannels = (array) $channels;
}
-
- /**
- * Build a new channel notification from the given object.
- *
- * @param mixed $notifiable
- * @param mixed $notification
- * @param array|null $channels
- * @return array
- */
- public function notificationsFromInstance($notifiable, $notification, $channels = null)
- {
- return Channels\Notification::notificationsFromInstance($notifiable, $notification, $channels);
- }
}
diff --git a/src/Illuminate/Notifications/Channels/BroadcastChannel.php b/src/Illuminate/Notifications/Channels/BroadcastChannel.php
new file mode 100644
index 000000000000..20a46c70f0ac
--- /dev/null
+++ b/src/Illuminate/Notifications/Channels/BroadcastChannel.php
@@ -0,0 +1,63 @@
+events = $events;
+ }
+
+ /**
+ * Send the given notification.
+ *
+ * @param mixed $notifiable
+ * @param \Illuminate\Notifications\Notification $notification
+ * @return void
+ */
+ public function send($notifiable, Notification $notification)
+ {
+ $this->events->fire(new BroadcastNotificationCreated(
+ $notifiable, $notification, $this->getData($notifiable, $notification)
+ ));
+ }
+
+ /**
+ * Get the data for the notification.
+ *
+ * @param mixed $notifiable
+ * @param \Illuminate\Notifications\Notification $notification
+ * @return array
+ *
+ * @throws \RuntimeException
+ */
+ protected function getData($notifiable, Notification $notification)
+ {
+ if (method_exists($notification, 'toArray')) {
+ return $notification->toArray($notifiable);
+ }
+
+ throw new RuntimeException(
+ 'Notification is missing toArray method.'
+ );
+ }
+}
diff --git a/src/Illuminate/Notifications/Channels/DatabaseChannel.php b/src/Illuminate/Notifications/Channels/DatabaseChannel.php
index 696a5bdbbf88..e5d7aeee2f48 100644
--- a/src/Illuminate/Notifications/Channels/DatabaseChannel.php
+++ b/src/Illuminate/Notifications/Channels/DatabaseChannel.php
@@ -2,25 +2,49 @@
namespace Illuminate\Notifications\Channels;
+use RuntimeException;
+use Illuminate\Notifications\Notification;
+
class DatabaseChannel
{
/**
* Send the given notification.
*
- * @param \Illuminate\Notifications\Channels\Notification $notification
+ * @param mixed $notifiable
+ * @param \Illuminate\Notifications\Notification $notification
* @return void
*/
- public function send(Notification $notification)
+ public function send($notifiable, Notification $notification)
+ {
+ $notifiable->routeNotificationFor('database')->create([
+ 'id' => $notification->id,
+ 'type' => get_class($notification),
+ 'data' => $this->getData($notifiable, $notification),
+ 'read_at' => null,
+ ]);
+ }
+
+ /**
+ * Get the data for the notification.
+ *
+ * @param mixed $notifiable
+ * @param \Illuminate\Notifications\Notification $notification
+ * @return array
+ *
+ * @throws \RuntimeException
+ */
+ protected function getData($notifiable, Notification $notification)
{
- foreach ($notification->notifiables as $notifiable) {
- $notifiable->routeNotificationFor('database')->create([
- 'level' => $notification->level,
- 'intro' => $notification->introLines,
- 'outro' => $notification->outroLines,
- 'action_text' => $notification->actionText,
- 'action_url' => $notification->actionUrl,
- 'read' => false,
- ]);
+ if (method_exists($notification, 'toDatabase')) {
+ $data = $notification->toDatabase($notifiable);
+
+ return is_array($data) ? $data : $data->data;
+ } elseif (method_exists($notification, 'toArray')) {
+ return $notification->toArray($notifiable);
}
+
+ throw new RuntimeException(
+ 'Notification is missing toDatabase / toArray method.'
+ );
}
}
diff --git a/src/Illuminate/Notifications/Channels/MailChannel.php b/src/Illuminate/Notifications/Channels/MailChannel.php
index 8e54bd7c211b..5a91079f0b05 100644
--- a/src/Illuminate/Notifications/Channels/MailChannel.php
+++ b/src/Illuminate/Notifications/Channels/MailChannel.php
@@ -2,8 +2,9 @@
namespace Illuminate\Notifications\Channels;
-use Illuminate\Support\Arr;
+use Illuminate\Support\Str;
use Illuminate\Contracts\Mail\Mailer;
+use Illuminate\Notifications\Notification;
class MailChannel
{
@@ -28,59 +29,24 @@ public function __construct(Mailer $mailer)
/**
* Send the given notification.
*
- * @param \Illuminate\Notifications\Channels\Notification $notification
+ * @param mixed $notifiable
+ * @param \Illuminate\Notifications\Notification $notification
* @return void
*/
- public function send(Notification $notification)
+ public function send($notifiable, Notification $notification)
{
- $data = $this->prepareNotificationData($notification);
-
- $emails = $notification->notifiables->map(function ($n) {
- return $n->routeNotificationFor('mail');
- })->filter()->all();
-
- if (empty($emails)) {
+ if (! $notifiable->routeNotificationFor('mail')) {
return;
}
- $view = data_get($notification, 'options.view', 'notifications::email');
+ $message = $notification->toMail($notifiable);
- $this->mailer->send($view, $data, function ($m) use ($notification, $emails) {
- count($notification->notifiables) === 1
- ? $m->to($emails) : $m->bcc($emails);
+ $this->mailer->send($message->view, $message->toArray(), function ($m) use ($notifiable, $notification, $message) {
+ $m->to($notifiable->routeNotificationFor('mail'));
- $m->subject($notification->subject);
+ $m->subject($message->subject ?: Str::title(
+ Str::snake(class_basename($notification), ' ')
+ ));
});
}
-
- /**
- * Prepare the data from the given notification.
- *
- * @param \Illuminate\Notifications\Channels\Notification $notification
- * @return array
- */
- protected function prepareNotificationData($notification)
- {
- $data = $notification->toArray();
-
- return Arr::set($data, 'actionColor', $this->actionColorForLevel($data['level']));
- }
-
- /**
- * Get the action color for the given notification "level".
- *
- * @param string $level
- * @return string
- */
- protected function actionColorForLevel($level)
- {
- switch ($level) {
- case 'success':
- return 'green';
- case 'error':
- return 'red';
- default:
- return 'blue';
- }
- }
}
diff --git a/src/Illuminate/Notifications/Channels/NexmoSmsChannel.php b/src/Illuminate/Notifications/Channels/NexmoSmsChannel.php
index b3a7ecc92281..bc0cb21908cc 100644
--- a/src/Illuminate/Notifications/Channels/NexmoSmsChannel.php
+++ b/src/Illuminate/Notifications/Channels/NexmoSmsChannel.php
@@ -2,8 +2,9 @@
namespace Illuminate\Notifications\Channels;
-use Illuminate\Support\Arr;
use Nexmo\Client as NexmoClient;
+use Illuminate\Notifications\Notification;
+use Illuminate\Notifications\Messages\NexmoMessage;
class NexmoSmsChannel
{
@@ -25,6 +26,7 @@ class NexmoSmsChannel
* Create a new Nexmo channel instance.
*
* @param \Nexmo\Client $nexmo
+ * @param string $from
* @return void
*/
public function __construct(NexmoClient $nexmo, $from)
@@ -36,54 +38,26 @@ public function __construct(NexmoClient $nexmo, $from)
/**
* Send the given notification.
*
- * @param \Illuminate\Notifications\Channels\Notification $notification
+ * @param mixed $notifiable
+ * @param \Illuminate\Notifications\Notification $notification
* @return void
*/
- public function send(Notification $notification)
+ public function send($notifiable, Notification $notification)
{
- foreach ($notification->notifiables as $notifiable) {
- if (! $to = $notifiable->routeNotificationFor('nexmo')) {
- continue;
- }
-
- $this->nexmo->message()->send([
- 'from' => $this->from,
- 'to' => $to,
- 'text' => $this->formatNotification($notification),
- ]);
+ if (! $to = $notifiable->routeNotificationFor('nexmo')) {
+ return;
}
- }
- /**
- * Format the given notification to a single string.
- *
- * @param \Illuminate\Notifications\Channels\Notification $notification
- * @return string
- */
- protected function formatNotification(Notification $notification)
- {
- $data = $notification->toArray();
+ $message = $notification->toNexmo($notifiable);
- $actionText = $notification->actionText
- ? $notification->actionText.': ' : '';
-
- return trim(implode(PHP_EOL.PHP_EOL, array_filter([
- implode(' ', Arr::get($data, 'introLines', [])),
- $actionText.Arr::get($data, 'actionUrl'),
- implode(' ', Arr::get($data, 'outroLines', [])),
- ])));
- }
-
- /**
- * Set the phone number that should be used to send notification.
- *
- * @param string $from
- * @return $this
- */
- public function sendNotificationsFrom($from)
- {
- $this->from = $from;
+ if (is_string($message)) {
+ $message = new NexmoMessage($message);
+ }
- return $this;
+ $this->nexmo->message()->send([
+ 'from' => $message->from ?: $this->from,
+ 'to' => $to,
+ 'text' => trim($message->content),
+ ]);
}
}
diff --git a/src/Illuminate/Notifications/Channels/Notification.php b/src/Illuminate/Notifications/Channels/Notification.php
deleted file mode 100644
index 600e1d66f907..000000000000
--- a/src/Illuminate/Notifications/Channels/Notification.php
+++ /dev/null
@@ -1,352 +0,0 @@
-notifiables = Collection::make($notifiables);
- }
-
- /**
- * Specify the name of the application sending the notification.
- *
- * @param string $application
- * @param string $logoUrl
- * @return $this
- */
- public function application($application, $logoUrl = null)
- {
- $this->application = $application;
- $this->logoUrl = $logoUrl;
-
- return $this;
- }
-
- /**
- * Indicate that the notification gives information about a successful operation.
- *
- * @return $this
- */
- public function success()
- {
- $this->level = 'success';
-
- return $this;
- }
-
- /**
- * Indicate that the notification gives information about an error.
- *
- * @return $this
- */
- public function error()
- {
- $this->level = 'error';
-
- return $this;
- }
-
- /**
- * Set the "level" of the notification (success, error, etc.).
- *
- * @param string $level
- * @return $this
- */
- public function level($level)
- {
- $this->level = $level;
-
- return $this;
- }
-
- /**
- * Set the subject of the notification.
- *
- * @param string $subject
- * @return $this
- */
- public function subject($subject)
- {
- $this->subject = $subject;
-
- return $this;
- }
-
- /**
- * Add a line of text to the notification.
- *
- * @param \Illuminate\Notifications\Action|string $line
- * @return $this
- */
- public function line($line)
- {
- return $this->with($line);
- }
-
- /**
- * Add a line of text to the notification.
- *
- * @param \Illuminate\Notifications\Action|string $line
- * @return $this
- */
- public function with($line)
- {
- if ($line instanceof Action) {
- $this->action($line->text, $line->url);
- } elseif (! $this->actionText) {
- $this->introLines[] = trim($line);
- } else {
- $this->outroLines[] = trim($line);
- }
-
- return $this;
- }
-
- /**
- * Set the notification's options.
- *
- * @param array $options
- * @return $this
- */
- public function options(array $options)
- {
- $this->options = $options;
-
- return $this;
- }
-
- /**
- * Configure the "call to action" button.
- *
- * @param string $text
- * @param string $url
- * @return $this
- */
- public function action($text, $url)
- {
- $this->actionText = $text;
- $this->actionUrl = $url;
-
- return $this;
- }
-
- /**
- * Set the channels that should be used to deliver the notification.
- *
- * @param array|string $channels
- * @return $this
- */
- public function via($channels)
- {
- $this->via = is_string($channels) ? func_get_args() : (array) $channels;
-
- return $this;
- }
-
- /**
- * Send the notification.
- *
- * @return void
- */
- public function send()
- {
- return Container::getInstance()->make(ChannelManager::class)->send($this);
- }
-
- /**
- * Build new channel notifications from the given object.
- *
- * @param mixed $notifiable
- * @param mixed $instance
- * @param array|null $channels
- * @return array[static]
- */
- public static function notificationsFromInstance($notifiable, $instance, $channels = null)
- {
- $notifications = [];
-
- $channels = $channels ?: $instance->via($notifiable);
-
- $channels = $channels ?: app(ChannelManager::class)->deliversVia();
-
- foreach ($channels as $channel) {
- $notifications[] = static::buildNotification($notifiable, $instance, $channel);
- }
-
- return $notifications;
- }
-
- /**
- * Build a new channel notification.
- *
- * @param mixed $notifiable
- * @param mixed $instance
- * @param string $channel
- * @return static
- */
- protected static function buildNotification($notifiable, $instance, $channel)
- {
- $notification = new static([$notifiable]);
-
- $notification->via($channel)
- ->subject($instance->subject())
- ->level($instance->level());
-
- $method = static::messageMethod($instance, $channel);
-
- foreach ($instance->{$method}($notifiable)->elements as $element) {
- $notification->with($element);
- }
-
- $method = static::optionsMethod($instance, $channel);
-
- $notification->options($instance->{$method}($notifiable));
-
- return $notification;
- }
-
- /**
- * Get the proper message method for the given instance and channel.
- *
- * @param mixed $instance
- * @param string $channel
- * @return string
- */
- protected static function messageMethod($instance, $channel)
- {
- return method_exists(
- $instance, $channelMethod = Str::camel($channel).'Message'
- ) ? $channelMethod : 'message';
- }
-
- /**
- * Get the proper data method for the given instance and channel.
- *
- * @param mixed $instance
- * @param string $channel
- * @return string
- */
- protected static function optionsMethod($instance, $channel)
- {
- return method_exists(
- $instance, $channelMethod = Str::camel($channel).'Options'
- ) ? $channelMethod : 'options';
- }
-
- /**
- * Get the instance as an array.
- *
- * @return array
- */
- public function toArray()
- {
- return [
- 'notifiables' => $this->notifiables,
- 'application' => $this->application,
- 'logoUrl' => $this->logoUrl,
- 'level' => $this->level,
- 'subject' => $this->subject,
- 'introLines' => $this->introLines,
- 'outroLines' => $this->outroLines,
- 'actionText' => $this->actionText,
- 'actionUrl' => $this->actionUrl,
- ];
- }
-}
diff --git a/src/Illuminate/Notifications/Channels/SlackWebhookChannel.php b/src/Illuminate/Notifications/Channels/SlackWebhookChannel.php
index 4e68e904842f..b75821bb63a9 100644
--- a/src/Illuminate/Notifications/Channels/SlackWebhookChannel.php
+++ b/src/Illuminate/Notifications/Channels/SlackWebhookChannel.php
@@ -3,6 +3,9 @@
namespace Illuminate\Notifications\Channels;
use GuzzleHttp\Client as HttpClient;
+use Illuminate\Notifications\Notification;
+use Illuminate\Notifications\Messages\SlackMessage;
+use Illuminate\Notifications\Messages\SlackAttachment;
class SlackWebhookChannel
{
@@ -27,63 +30,55 @@ public function __construct(HttpClient $http)
/**
* Send the given notification.
*
- * @param \Illuminate\Notifications\Channels\Notification $notification
+ * @param mixed $notifiable
+ * @param \Illuminate\Notifications\Notification $notification
* @return void
*/
- public function send(Notification $notification)
+ public function send($notifiable, Notification $notification)
{
- foreach ($notification->notifiables as $notifiable) {
- if (! $url = $notifiable->routeNotificationFor('slack')) {
- continue;
- }
-
- $this->http->post($url, [
- 'json' => [
- 'attachments' => [
- array_filter([
- 'color' => $this->color($notification),
- 'title' => $notification->subject,
- 'title_link' => $notification->actionUrl ?: null,
- 'text' => $this->format($notification),
- ]),
- ],
- ],
- ]);
+ if (! $url = $notifiable->routeNotificationFor('slack')) {
+ return;
}
+
+ $message = $notification->toSlack($notifiable);
+
+ $this->http->post($url, [
+ 'json' => [
+ 'text' => $message->content,
+ 'attachments' => $this->attachments($message),
+ ],
+ ]);
}
/**
- * Format the given notification.
+ * Format the message's attachments.
*
- * @param \Illuminate\Notifications\Channels\Notification $notification
- * @return string
+ * @param \Illuminate\Notifications\Messages\SlackMessage $message
+ * @return array
*/
- protected function format(Notification $notification)
+ protected function attachments(SlackMessage $message)
{
- $message = trim(implode(PHP_EOL.PHP_EOL, $notification->introLines));
-
- if ($notification->actionText) {
- $message .= PHP_EOL.PHP_EOL.'<'.$notification->actionUrl.'|'.$notification->actionText.'>';
- }
-
- $message .= PHP_EOL.PHP_EOL.trim(implode(PHP_EOL.PHP_EOL, $notification->outroLines));
-
- return trim($message);
+ return collect($message->attachments)->map(function ($attachment) use ($message) {
+ return array_filter([
+ 'color' => $message->color(),
+ 'title' => $attachment->title,
+ 'text' => $attachment->content,
+ 'title_link' => $attachment->url,
+ 'fields' => $this->fields($attachment),
+ ]);
+ })->all();
}
/**
- * Get the color that should be applied to the notification.
+ * Format the attachment's fields.
*
- * @param \Illuminate\Notifications\Channels\Notification $notification
- * @return string|null
+ * @param \Illuminate\Notifications\Messages\SlackAttachment $attachment
+ * @return array
*/
- protected function color(Notification $notification)
+ protected function fields(SlackAttachment $attachment)
{
- switch ($notification->level) {
- case 'success':
- return 'good';
- case 'error':
- return 'danger';
- }
+ return collect($attachment->fields)->map(function ($value, $key) {
+ return ['title' => $key, 'value' => $value, 'short' => true];
+ })->values()->all();
}
}
diff --git a/src/Illuminate/Notifications/Console/NotificationTableCommand.php b/src/Illuminate/Notifications/Console/NotificationTableCommand.php
new file mode 100644
index 000000000000..09b0e3eb5415
--- /dev/null
+++ b/src/Illuminate/Notifications/Console/NotificationTableCommand.php
@@ -0,0 +1,81 @@
+files = $files;
+ $this->composer = $composer;
+ }
+
+ /**
+ * Execute the console command.
+ *
+ * @return void
+ */
+ public function fire()
+ {
+ $fullPath = $this->createBaseMigration();
+
+ $this->files->put($fullPath, $this->files->get(__DIR__.'/stubs/notifications.stub'));
+
+ $this->info('Migration created successfully!');
+
+ $this->composer->dumpAutoloads();
+ }
+
+ /**
+ * Create a base migration file for the notifications.
+ *
+ * @return string
+ */
+ protected function createBaseMigration()
+ {
+ $name = 'create_notifications_table';
+
+ $path = $this->laravel->databasePath().'/migrations';
+
+ return $this->laravel['migration.creator']->create($name, $path);
+ }
+}
diff --git a/src/Illuminate/Notifications/Console/stubs/notifications.stub b/src/Illuminate/Notifications/Console/stubs/notifications.stub
new file mode 100644
index 000000000000..160a1c42f498
--- /dev/null
+++ b/src/Illuminate/Notifications/Console/stubs/notifications.stub
@@ -0,0 +1,34 @@
+string('id')->primary();
+ $table->string('type');
+ $table->morphs('notifiable');
+ $table->text('data');
+ $table->timestamp('read_at')->nullable();
+ $table->timestamps();
+ });
+ }
+
+ /**
+ * Reverse the migrations.
+ *
+ * @return void
+ */
+ public function down()
+ {
+ Schema::drop('notifications');
+ }
+}
diff --git a/src/Illuminate/Notifications/DatabaseNotification.php b/src/Illuminate/Notifications/DatabaseNotification.php
index 69497c1cfe9c..a8e6ec12beb2 100644
--- a/src/Illuminate/Notifications/DatabaseNotification.php
+++ b/src/Illuminate/Notifications/DatabaseNotification.php
@@ -6,6 +6,13 @@
class DatabaseNotification extends Model
{
+ /**
+ * Indicates if the IDs are auto-incrementing.
+ *
+ * @var bool
+ */
+ public $incrementing = false;
+
/**
* The table associated with the model.
*
@@ -26,9 +33,8 @@ class DatabaseNotification extends Model
* @var array
*/
protected $casts = [
- 'intro' => 'array',
- 'outro' => 'array',
- 'read' => 'boolean',
+ 'data' => 'array',
+ 'read_at' => 'datetime',
];
/**
@@ -46,6 +52,19 @@ public function notifiable()
*/
public function markAsRead()
{
- $this->forceFill(['read' => true])->save();
+ if (is_null($this->read_at)) {
+ $this->forceFill(['read_at' => $this->freshTimestamp()])->save();
+ }
+ }
+
+ /**
+ * Create a new database notification collection instance.
+ *
+ * @param array $models
+ * @return \Illuminate\Notifications\DatabaseNotificationCollection
+ */
+ public function newCollection(array $models = [])
+ {
+ return new DatabaseNotificationCollection($models);
}
}
diff --git a/src/Illuminate/Notifications/DatabaseNotificationCollection.php b/src/Illuminate/Notifications/DatabaseNotificationCollection.php
new file mode 100644
index 000000000000..5ef3f27e11ff
--- /dev/null
+++ b/src/Illuminate/Notifications/DatabaseNotificationCollection.php
@@ -0,0 +1,20 @@
+each(function ($notification) {
+ $notification->markAsRead();
+ });
+ }
+}
diff --git a/src/Illuminate/Notifications/Events/BroadcastNotificationCreated.php b/src/Illuminate/Notifications/Events/BroadcastNotificationCreated.php
new file mode 100644
index 000000000000..a24cc8b362cd
--- /dev/null
+++ b/src/Illuminate/Notifications/Events/BroadcastNotificationCreated.php
@@ -0,0 +1,84 @@
+data = $data;
+ $this->notifiable = $notifiable;
+ $this->notification = $notification;
+ }
+
+ /**
+ * Get the channels the event should broadcast on.
+ *
+ * @return array
+ */
+ public function broadcastOn()
+ {
+ return [new PrivateChannel($this->channelName())];
+ }
+
+ /**
+ * Get the data that should be sent with the broadcasted event.
+ *
+ * @return array
+ */
+ public function broadcastWith()
+ {
+ return array_merge($this->data, [
+ 'id' => $this->notification->id,
+ 'type' => get_class($this->notification),
+ ]);
+ }
+
+ /**
+ * Get the broadcast channel name for the event.
+ *
+ * @return string
+ */
+ protected function channelName()
+ {
+ $class = str_replace('\\', '.', get_class($this->notifiable));
+
+ return $class.'.'.$this->notifiable->getKey();
+ }
+}
diff --git a/src/Illuminate/Notifications/Events/NotificationSending.php b/src/Illuminate/Notifications/Events/NotificationSending.php
new file mode 100644
index 000000000000..81a218ece563
--- /dev/null
+++ b/src/Illuminate/Notifications/Events/NotificationSending.php
@@ -0,0 +1,42 @@
+channel = $channel;
+ $this->notifiable = $notifiable;
+ $this->notification = $notification;
+ }
+}
diff --git a/src/Illuminate/Notifications/Events/NotificationSent.php b/src/Illuminate/Notifications/Events/NotificationSent.php
index 1361f1ad6764..5685f231b136 100644
--- a/src/Illuminate/Notifications/Events/NotificationSent.php
+++ b/src/Illuminate/Notifications/Events/NotificationSent.php
@@ -2,25 +2,41 @@
namespace Illuminate\Notifications\Events;
-use Illuminate\Notifications\Channels\Notification;
-
class NotificationSent
{
+ /**
+ * The notifiable entity who received the notification.
+ *
+ * @var mixed
+ */
+ public $notifiable;
+
/**
* The notification instance.
*
- * @var \Illuminate\Notifications\Channels\Notification
+ * @var \Illuminate\Notifications\Notification
*/
public $notification;
+ /**
+ * The channel name.
+ *
+ * @var string
+ */
+ public $channel;
+
/**
* Create a new event instance.
*
- * @param \Illuminate\Notifications\Channels\Notification $notification
+ * @param mixed $notifiable
+ * @param \Illuminate\Notifications\Notification $notification
+ * @param string $channel
* @return void
*/
- public function __construct(Notification $notification)
+ public function __construct($notifiable, $notification, $channel)
{
+ $this->channel = $channel;
+ $this->notifiable = $notifiable;
$this->notification = $notification;
}
}
diff --git a/src/Illuminate/Notifications/HasDatabaseNotifications.php b/src/Illuminate/Notifications/HasDatabaseNotifications.php
index d9b8fde4726b..807ebadc5005 100644
--- a/src/Illuminate/Notifications/HasDatabaseNotifications.php
+++ b/src/Illuminate/Notifications/HasDatabaseNotifications.php
@@ -9,6 +9,17 @@ trait HasDatabaseNotifications
*/
public function notifications()
{
- return $this->morphMany(DatabaseNotification::class, 'notifiable');
+ return $this->morphMany(DatabaseNotification::class, 'notifiable')
+ ->orderBy('created_at', 'desc');
+ }
+
+ /**
+ * Get the entity's unread notifications.
+ */
+ public function unreadNotifications()
+ {
+ return $this->morphMany(DatabaseNotification::class, 'notifiable')
+ ->whereNull('read_at')
+ ->orderBy('created_at', 'desc');
}
}
diff --git a/src/Illuminate/Notifications/MessageBuilder.php b/src/Illuminate/Notifications/MessageBuilder.php
deleted file mode 100644
index c548a6dcbeae..000000000000
--- a/src/Illuminate/Notifications/MessageBuilder.php
+++ /dev/null
@@ -1,55 +0,0 @@
-elements[] = $line;
- }
-
- /**
- * Add a line to the message.
- *
- * @param string $line
- * @return $this
- */
- public function line($line)
- {
- $this->elements[] = $line;
-
- return $this;
- }
-
- /**
- * Add an action to the message.
- *
- * @param string $text
- * @param string $url
- * @return $this
- */
- public function action($text, $url)
- {
- $this->elements[] = new Action($text, $url);
-
- return $this;
- }
-}
diff --git a/src/Illuminate/Notifications/Messages/DatabaseMessage.php b/src/Illuminate/Notifications/Messages/DatabaseMessage.php
new file mode 100644
index 000000000000..55707a7c065f
--- /dev/null
+++ b/src/Illuminate/Notifications/Messages/DatabaseMessage.php
@@ -0,0 +1,24 @@
+data = $data;
+ }
+}
diff --git a/src/Illuminate/Notifications/Messages/MailMessage.php b/src/Illuminate/Notifications/Messages/MailMessage.php
new file mode 100644
index 000000000000..ee6a8b2b870a
--- /dev/null
+++ b/src/Illuminate/Notifications/Messages/MailMessage.php
@@ -0,0 +1,26 @@
+view = $view;
+
+ return $this;
+ }
+}
diff --git a/src/Illuminate/Notifications/Messages/NexmoMessage.php b/src/Illuminate/Notifications/Messages/NexmoMessage.php
new file mode 100644
index 000000000000..23ebbe622f79
--- /dev/null
+++ b/src/Illuminate/Notifications/Messages/NexmoMessage.php
@@ -0,0 +1,57 @@
+content = $content;
+ }
+
+ /**
+ * Set the message content.
+ *
+ * @param string $content
+ * @return $this
+ */
+ public function content($content)
+ {
+ $this->content = $content;
+
+ return $this;
+ }
+
+ /**
+ * Set the phone number the message should be sent from.
+ *
+ * @param string $number
+ * @return $this
+ */
+ public function from($from)
+ {
+ $this->from = $from;
+
+ return $this;
+ }
+}
diff --git a/src/Illuminate/Notifications/Messages/SimpleMessage.php b/src/Illuminate/Notifications/Messages/SimpleMessage.php
new file mode 100644
index 000000000000..25187ecc1d39
--- /dev/null
+++ b/src/Illuminate/Notifications/Messages/SimpleMessage.php
@@ -0,0 +1,177 @@
+level = 'success';
+
+ return $this;
+ }
+
+ /**
+ * Indicate that the notification gives information about an error.
+ *
+ * @return $this
+ */
+ public function error()
+ {
+ $this->level = 'error';
+
+ return $this;
+ }
+
+ /**
+ * Set the "level" of the notification (success, error, etc.).
+ *
+ * @param string $level
+ * @return $this
+ */
+ public function level($level)
+ {
+ $this->level = $level;
+
+ return $this;
+ }
+
+ /**
+ * Set the subject of the notification.
+ *
+ * @param string $subject
+ * @return $this
+ */
+ public function subject($subject)
+ {
+ $this->subject = $subject;
+
+ return $this;
+ }
+
+ /**
+ * Add a line of text to the notification.
+ *
+ * @param \Illuminate\Notifications\Action|string $line
+ * @return $this
+ */
+ public function line($line)
+ {
+ return $this->with($line);
+ }
+
+ /**
+ * Add a line of text to the notification.
+ *
+ * @param \Illuminate\Notifications\Action|string|array $line
+ * @return $this
+ */
+ public function with($line)
+ {
+ if ($line instanceof Action) {
+ $this->action($line->text, $line->url);
+ } elseif (! $this->actionText) {
+ $this->introLines[] = $this->formatLine($line);
+ } else {
+ $this->outroLines[] = $this->formatLine($line);
+ }
+
+ return $this;
+ }
+
+ /**
+ * Format the given line of text.
+ *
+ * @param string|array $line
+ * @return string
+ */
+ protected function formatLine($line)
+ {
+ if (is_array($line)) {
+ return implode(' ', array_map('trim', $line));
+ }
+
+ return trim(implode(' ', array_map('trim', explode(PHP_EOL, $line))));
+ }
+
+ /**
+ * Configure the "call to action" button.
+ *
+ * @param string $text
+ * @param string $url
+ * @return $this
+ */
+ public function action($text, $url)
+ {
+ $this->actionText = $text;
+ $this->actionUrl = $url;
+
+ return $this;
+ }
+
+ /**
+ * Get an array representation of the message.
+ *
+ * @return array
+ */
+ public function toArray()
+ {
+ return [
+ 'level' => $this->level,
+ 'subject' => $this->subject,
+ 'introLines' => $this->introLines,
+ 'outroLines' => $this->outroLines,
+ 'actionText' => $this->actionText,
+ 'actionUrl' => $this->actionUrl,
+ ];
+ }
+}
diff --git a/src/Illuminate/Notifications/Messages/SlackAttachment.php b/src/Illuminate/Notifications/Messages/SlackAttachment.php
new file mode 100644
index 000000000000..11b8a7ac0ef9
--- /dev/null
+++ b/src/Illuminate/Notifications/Messages/SlackAttachment.php
@@ -0,0 +1,75 @@
+title = $title;
+ $this->url = $url;
+
+ return $this;
+ }
+
+ /**
+ * Set the content (text) of the attachment.
+ *
+ * @param string $content
+ * @return $this
+ */
+ public function content($content)
+ {
+ $this->content = $content;
+
+ return $this;
+ }
+
+ /**
+ * Set the fields of the attachment.
+ *
+ * @param array $fields
+ * @return $this
+ */
+ public function fields(array $fields)
+ {
+ $this->fields = $fields;
+
+ return $this;
+ }
+}
diff --git a/src/Illuminate/Notifications/Messages/SlackMessage.php b/src/Illuminate/Notifications/Messages/SlackMessage.php
new file mode 100644
index 000000000000..c20508f8fcf1
--- /dev/null
+++ b/src/Illuminate/Notifications/Messages/SlackMessage.php
@@ -0,0 +1,96 @@
+level = 'success';
+
+ return $this;
+ }
+
+ /**
+ * Indicate that the notification gives information about an error.
+ *
+ * @return $this
+ */
+ public function error()
+ {
+ $this->level = 'error';
+
+ return $this;
+ }
+
+ /**
+ * Set the content of the Slack message.
+ *
+ * @param string $content
+ * @return $this
+ */
+ public function content($content)
+ {
+ $this->content = $content;
+
+ return $this;
+ }
+
+ /**
+ * Define an attachment for the message.
+ *
+ * @param \Closure $callback
+ * @return $this
+ */
+ public function attachment(Closure $callback)
+ {
+ $this->attachments[] = $attachment = new SlackAttachment;
+
+ $callback($attachment);
+
+ return $this;
+ }
+
+ /**
+ * Get the color for the message.
+ *
+ * @return string
+ */
+ public function color()
+ {
+ switch ($this->level) {
+ case 'success':
+ return '#7CD197';
+ case 'error':
+ return '#F35A00';
+ }
+ }
+}
diff --git a/src/Illuminate/Notifications/Notification.php b/src/Illuminate/Notifications/Notification.php
index 96595fcd9d0a..9b258b7dc1f6 100644
--- a/src/Illuminate/Notifications/Notification.php
+++ b/src/Illuminate/Notifications/Notification.php
@@ -2,50 +2,26 @@
namespace Illuminate\Notifications;
-use Illuminate\Support\Str;
+use Illuminate\Queue\SerializesModels;
class Notification
{
- /**
- * Get the "level" of the notification.
- *
- * @return string
- */
- public function level()
- {
- return property_exists($this, 'level') ? $this->level : 'info';
- }
+ use SerializesModels;
/**
- * Get the subject of the notification.
+ * The unique identifier for the notification.
*
- * @return string
+ * @var string
*/
- public function subject()
- {
- return property_exists($this, 'subject')
- ? $this->subject
- : Str::title(Str::snake(class_basename($this), ' '));
- }
-
- /**
- * Create a new message builder instance.
- *
- * @param string $line
- * @return \Illuminate\Notifications\MessageBuilder
- */
- public function line($line)
- {
- return new MessageBuilder($line);
- }
+ public $id;
/**
- * Get the notification's options.
+ * Get the channels the event should broadcast on.
*
* @return array
*/
- public function options()
+ public function broadcastOn()
{
- return property_exists($this, 'options') ? $this->options : [];
+ return [];
}
}
diff --git a/src/Illuminate/Notifications/NotificationServiceProvider.php b/src/Illuminate/Notifications/NotificationServiceProvider.php
index bba721ccc8ab..ba1fb2c3ad4c 100644
--- a/src/Illuminate/Notifications/NotificationServiceProvider.php
+++ b/src/Illuminate/Notifications/NotificationServiceProvider.php
@@ -8,13 +8,6 @@
class NotificationServiceProvider extends ServiceProvider
{
- /**
- * Indicates if loading of the provider is deferred.
- *
- * @var bool
- */
- protected $defer = true;
-
/**
* Boot the application services.
*
@@ -50,16 +43,4 @@ public function register()
ChannelManager::class, FactoryContract::class
);
}
-
- /**
- * Get the services provided by the provider.
- *
- * @return array
- */
- public function provides()
- {
- return [
- ChannelManager::class, DispatcherContract::class, FactoryContract::class,
- ];
- }
}
diff --git a/src/Illuminate/Notifications/RoutesNotifications.php b/src/Illuminate/Notifications/RoutesNotifications.php
index 9619ad3d7eb5..f73cdffc1571 100644
--- a/src/Illuminate/Notifications/RoutesNotifications.php
+++ b/src/Illuminate/Notifications/RoutesNotifications.php
@@ -15,19 +15,7 @@ trait RoutesNotifications
*/
public function notify($instance)
{
- app(Dispatcher::class)->dispatch($this, $instance);
- }
-
- /**
- * Send the given notification via the given channels.
- *
- * @param array|string $channels
- * @param mixed $instance
- * @return void
- */
- public function notifyVia($channels, $instance)
- {
- app(Dispatcher::class)->dispatch($this, $instance, $channels);
+ app(Dispatcher::class)->send([$this], $instance);
}
/**
diff --git a/src/Illuminate/Notifications/SendQueuedNotifications.php b/src/Illuminate/Notifications/SendQueuedNotifications.php
index deab7c803128..c829bec7f487 100644
--- a/src/Illuminate/Notifications/SendQueuedNotifications.php
+++ b/src/Illuminate/Notifications/SendQueuedNotifications.php
@@ -3,28 +3,38 @@
namespace Illuminate\Notifications;
use Illuminate\Bus\Queueable;
+use Illuminate\Queue\SerializesModels;
use Illuminate\Contracts\Queue\ShouldQueue;
class SendQueuedNotifications implements ShouldQueue
{
- use Queueable;
+ use Queueable, SerializesModels;
/**
- * The notifications to be sent.
+ * The notifiable entities that should receive the notification.
*
- * @var array
+ * @var \Illuminate\Support\Collection
*/
- protected $notifications;
+ protected $notifiables;
+
+ /**
+ * The notification to be sent.
+ *
+ * @var \Illuminate\Notifications\Notification
+ */
+ protected $notification;
/**
* Create a new job instance.
*
- * @param array[\Illuminate\Notifications\Channels\Notification] $notifications
+ * @param \Illuminate\Support\Collection $notifiables
+ * @param \Illuminate\Notifications\Notification $notification
* @return void
*/
- public function __construct(array $notifications)
+ public function __construct($notifiables, $notification)
{
- $this->notifications = $notifications;
+ $this->notifiables = $notifiables;
+ $this->notification = $notification;
}
/**
@@ -35,8 +45,6 @@ public function __construct(array $notifications)
*/
public function handle(ChannelManager $manager)
{
- foreach ($this->notifications as $notification) {
- $manager->send($notification);
- }
+ $manager->sendNow($this->notifiables, $this->notification);
}
}
diff --git a/src/Illuminate/Notifications/composer.json b/src/Illuminate/Notifications/composer.json
index 6a9e29c66df2..c0dc101e9259 100644
--- a/src/Illuminate/Notifications/composer.json
+++ b/src/Illuminate/Notifications/composer.json
@@ -2,7 +2,7 @@
"name": "illuminate/notifications",
"description": "The Illuminate Notifications package.",
"license": "MIT",
- "homepage": "http://laravel.com",
+ "homepage": "https://laravel.com",
"support": {
"issues": "https://github.com/laravel/framework/issues",
"source": "https://github.com/laravel/framework"
@@ -15,9 +15,11 @@
],
"require": {
"php": ">=5.6.4",
+ "illuminate/broadcasting": "5.3.*",
"illuminate/bus": "5.3.*",
"illuminate/contracts": "5.3.*",
- "illuminate/support": "5.3.*"
+ "illuminate/support": "5.3.*",
+ "ramsey/uuid": "~3.0"
},
"autoload": {
"psr-4": {
diff --git a/src/Illuminate/Notifications/resources/views/email.blade.php b/src/Illuminate/Notifications/resources/views/email.blade.php
index 5467e73fc557..65397fbbe650 100644
--- a/src/Illuminate/Notifications/resources/views/email.blade.php
+++ b/src/Illuminate/Notifications/resources/views/email.blade.php
@@ -1,240 +1,89 @@
-
-
+
+
+
- /* Layout ------------------------------ */
+ 'margin: 0; padding: 0; width: 100%; background-color: #F2F4F6;',
+ 'email-wrapper' => 'width: 100%; margin: 0; padding: 0; background-color: #F2F4F6;',
- .email-masthead {
- padding: 25px 0;
- text-align: center;
- }
- .email-masthead_logo {
- max-width: 400px;
- border: 0;
- }
- .email-masthead_name {
- font-size: 16px;
- font-weight: bold;
- color: #2F3133;
- text-decoration: none;
- text-shadow: 0 1px 0 white;
- }
- .email-logo {
- max-height: 50px;
- }
+ /* Masthead ----------------------- */
- /* Body ------------------------------ */
+ 'email-masthead' => 'padding: 25px 0; text-align: center;',
+ 'email-masthead_name' => 'font-size: 16px; font-weight: bold; color: #2F3133; text-decoration: none; text-shadow: 0 1px 0 white;',
- .email-body {
- width: 100%;
- margin: 0;
- padding: 0;
- border-top: 1px solid #EDEFF2;
- border-bottom: 1px solid #EDEFF2;
- background-color: #FFF;
- }
- .email-body_inner {
- width: 570px;
- margin: 0 auto;
- padding: 0;
- }
- .email-footer {
- width: 570px;
- margin: 0 auto;
- padding: 0;
- text-align: center;
- }
- .email-footer p {
- color: #AEAEAE;
- }
- .body-action {
- width: 100%;
- margin: 30px auto;
- padding: 0;
- text-align: center;
- }
- .body-sub {
- margin-top: 25px;
- padding-top: 25px;
- border-top: 1px solid #EDEFF2;
- }
- .content-cell {
- padding: 35px;
- }
- .align-right {
- text-align: right;
- }
+ 'email-body' => 'width: 100%; margin: 0; padding: 0; border-top: 1px solid #EDEFF2; border-bottom: 1px solid #EDEFF2; background-color: #FFF;',
+ 'email-body_inner' => 'width: auto; max-width: 570px; margin: 0 auto; padding: 0;',
+ 'email-body_cell' => 'padding: 35px;',
- /* Type ------------------------------ */
+ 'email-footer' => 'width: auto; max-width: 570px; margin: 0 auto; padding: 0; text-align: center;',
+ 'email-footer_cell' => 'color: #AEAEAE; padding: 35px; text-align: center;',
- h1 {
- margin-top: 0;
- color: #2F3133;
- font-size: 19px;
- font-weight: bold;
- text-align: left;
- }
- h2 {
- margin-top: 0;
- color: #2F3133;
- font-size: 16px;
- font-weight: bold;
- text-align: left;
- }
- h3 {
- margin-top: 0;
- color: #2F3133;
- font-size: 14px;
- font-weight: bold;
- text-align: left;
- }
- p {
- margin-top: 0;
- color: #74787E;
- font-size: 16px;
- line-height: 1.5em;
- }
- p.sub {
- font-size: 12px;
- }
- p.center {
- text-align: center;
- }
+ /* Body ------------------------------ */
- /* Data table ------------------------------ */
+ 'body_action' => 'width: 100%; margin: 30px auto; padding: 0; text-align: center;',
+ 'body_sub' => 'margin-top: 25px; padding-top: 25px; border-top: 1px solid #EDEFF2;',
- .data-wrapper {
- width: 100%;
- margin: 0;
- padding: 35px 0;
- }
- .data-table {
- width: 100%;
- margin: 0;
- }
- .data-table th {
- text-align: left;
- padding: 0px 5px;
- padding-bottom: 8px;
- border-bottom: 1px solid #EDEFF2;
- }
- .data-table th p {
- margin: 0;
- color: #9BA2AB;
- font-size: 12px;
- }
- .data-table td {
- padding: 10px 5px;
- color: #74787E;
- font-size: 15px;
- line-height: 18px;
- }
+ /* Type ------------------------------ */
- /* Buttons ------------------------------ */
+ 'anchor' => 'color: #3869D4;',
+ 'header-1' => 'margin-top: 0; color: #2F3133; font-size: 19px; font-weight: bold; text-align: left;',
+ 'paragraph' => 'margin-top: 0; color: #74787E; font-size: 16px; line-height: 1.5em;',
+ 'paragraph-sub' => 'margin-top: 0; color: #74787E; font-size: 12px; line-height: 1.5em;',
+ 'paragraph-center' => 'text-align: center;',
- .button {
- display: inline-block;
- width: 200px;
- background-color: #3869D4;
- border-radius: 3px;
- color: #ffffff;
- font-size: 15px;
- line-height: 45px;
- text-align: center;
- text-decoration: none;
- -webkit-text-size-adjust: none;
- mso-hide: all;
- }
- .button--green {
- background-color: #22BC66;
- }
- .button--red {
- background-color: #dc4d2f;
- }
- .button--blue {
- background-color: #3869D4;
- }
+ /* Buttons ------------------------------ */
- /*Media Queries ------------------------------ */
+ 'button' => 'display: block; display: inline-block; width: 200px; min-height: 20px; padding: 10px;
+ background-color: #3869D4; border-radius: 3px; color: #ffffff; font-size: 15px; line-height: 25px;
+ text-align: center; text-decoration: none; -webkit-text-size-adjust: none;',
- @media only screen and (max-width: 600px) {
- .email-body_inner,
- .email-footer {
- width: 100% !important;
- }
- }
- @media only screen and (max-width: 500px) {
- .button {
- width: 100% !important;
- }
- }
-
-
+ 'button--green' => 'background-color: #22BC66;',
+ 'button--red' => 'background-color: #dc4d2f;',
+ 'button--blue' => 'background-color: #3869D4;',
+];
+?>
+
+
-
-