Pressroom template verwijderd, website naar root van repo

This commit is contained in:
2020-03-22 15:30:52 +01:00
parent 2cb6a77425
commit f3d1c41e91
7620 changed files with 0 additions and 186900 deletions

View File

@@ -0,0 +1,21 @@
<?php
namespace Illuminate\Broadcasting;
use Illuminate\Http\Request;
use Illuminate\Routing\Controller;
use Illuminate\Support\Facades\Broadcast;
class BroadcastController extends Controller
{
/**
* Authenticate the request for channel access.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\Response
*/
public function authenticate(Request $request)
{
return Broadcast::auth($request);
}
}

View File

@@ -0,0 +1,101 @@
<?php
namespace Illuminate\Broadcasting;
use ReflectionClass;
use ReflectionProperty;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\Job;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Contracts\Support\Arrayable;
use Illuminate\Contracts\Broadcasting\Broadcaster;
class BroadcastEvent implements ShouldQueue
{
use Queueable;
/**
* The event instance.
*
* @var mixed
*/
public $event;
/**
* Create a new job handler instance.
*
* @param mixed $event
* @return void
*/
public function __construct($event)
{
$this->event = $event;
}
/**
* Handle the queued job.
*
* @param \Illuminate\Contracts\Broadcasting\Broadcaster $broadcaster
* @return void
*/
public function handle(Broadcaster $broadcaster)
{
$name = method_exists($this->event, 'broadcastAs')
? $this->event->broadcastAs() : get_class($this->event);
$broadcaster->broadcast(
array_wrap($this->event->broadcastOn()), $name,
$this->getPayloadFromEvent($this->event)
);
}
/**
* Get the payload for the given event.
*
* @param mixed $event
* @return array
*/
protected function getPayloadFromEvent($event)
{
if (method_exists($event, 'broadcastWith')) {
return array_merge(
$event->broadcastWith(), ['socket' => data_get($event, 'socket')]
);
}
$payload = [];
foreach ((new ReflectionClass($event))->getProperties(ReflectionProperty::IS_PUBLIC) as $property) {
$payload[$property->getName()] = $this->formatProperty($property->getValue($event));
}
unset($payload['broadcastQueue']);
return $payload;
}
/**
* Format the given value for a property.
*
* @param mixed $value
* @return mixed
*/
protected function formatProperty($value)
{
if ($value instanceof Arrayable) {
return $value->toArray();
}
return $value;
}
/**
* Get the display name for the queued job.
*
* @return string
*/
public function displayName()
{
return get_class($this->event);
}
}

View File

@@ -0,0 +1,10 @@
<?php
namespace Illuminate\Broadcasting;
use RuntimeException;
class BroadcastException extends RuntimeException
{
//
}

View File

@@ -0,0 +1,312 @@
<?php
namespace Illuminate\Broadcasting;
use Pusher;
use Closure;
use Illuminate\Support\Arr;
use Psr\Log\LoggerInterface;
use InvalidArgumentException;
use Illuminate\Broadcasting\Broadcasters\LogBroadcaster;
use Illuminate\Broadcasting\Broadcasters\NullBroadcaster;
use Illuminate\Contracts\Broadcasting\ShouldBroadcastNow;
use Illuminate\Broadcasting\Broadcasters\RedisBroadcaster;
use Illuminate\Broadcasting\Broadcasters\PusherBroadcaster;
use Illuminate\Contracts\Broadcasting\Factory as FactoryContract;
class BroadcastManager implements FactoryContract
{
/**
* The application instance.
*
* @var \Illuminate\Foundation\Application
*/
protected $app;
/**
* The array of resolved broadcast drivers.
*
* @var array
*/
protected $drivers = [];
/**
* The registered custom driver creators.
*
* @var array
*/
protected $customCreators = [];
/**
* Create a new manager instance.
*
* @param \Illuminate\Foundation\Application $app
* @return void
*/
public function __construct($app)
{
$this->app = $app;
}
/**
* Register the routes for handling broadcast authentication and sockets.
*
* @param array|null $attributes
* @return void
*/
public function routes(array $attributes = null)
{
if ($this->app->routesAreCached()) {
return;
}
$attributes = $attributes ?: ['middleware' => ['web']];
$this->app['router']->group($attributes, function ($router) {
$router->post('/broadcasting/auth', BroadcastController::class.'@authenticate');
});
}
/**
* Get the socket ID for the given request.
*
* @param \Illuminate\Http\Request|null $request
* @return string|null
*/
public function socket($request = null)
{
if (! $request && ! $this->app->bound('request')) {
return;
}
$request = $request ?: $this->app['request'];
if ($request->hasHeader('X-Socket-ID')) {
return $request->header('X-Socket-ID');
}
}
/**
* 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);
}
/**
* Queue the given event for broadcast.
*
* @param mixed $event
* @return void
*/
public function queue($event)
{
$connection = $event instanceof ShouldBroadcastNow ? 'sync' : null;
if (is_null($connection) && isset($event->connection)) {
$connection = $event->connection;
}
$queue = null;
if (method_exists($event, 'broadcastQueue')) {
$queue = $event->broadcastQueue();
} elseif (isset($event->broadcastQueue)) {
$queue = $event->broadcastQueue;
} elseif (isset($event->queue)) {
$queue = $event->queue;
}
$this->app->make('queue')->connection($connection)->pushOn(
$queue, new BroadcastEvent(clone $event)
);
}
/**
* Get a driver instance.
*
* @param string $driver
* @return mixed
*/
public function connection($driver = null)
{
return $this->driver($driver);
}
/**
* Get a driver instance.
*
* @param string $name
* @return mixed
*/
public function driver($name = null)
{
$name = $name ?: $this->getDefaultDriver();
return $this->drivers[$name] = $this->get($name);
}
/**
* Attempt to get the connection from the local cache.
*
* @param string $name
* @return \Illuminate\Contracts\Broadcasting\Broadcaster
*/
protected function get($name)
{
return isset($this->drivers[$name]) ? $this->drivers[$name] : $this->resolve($name);
}
/**
* Resolve the given store.
*
* @param string $name
* @return \Illuminate\Contracts\Broadcasting\Broadcaster
*
* @throws \InvalidArgumentException
*/
protected function resolve($name)
{
$config = $this->getConfig($name);
if (is_null($config)) {
throw new InvalidArgumentException("Broadcaster [{$name}] is not defined.");
}
if (isset($this->customCreators[$config['driver']])) {
return $this->callCustomCreator($config);
}
$driverMethod = 'create'.ucfirst($config['driver']).'Driver';
if (! method_exists($this, $driverMethod)) {
throw new InvalidArgumentException("Driver [{$config['driver']}] is not supported.");
}
return $this->{$driverMethod}($config);
}
/**
* Call a custom driver creator.
*
* @param array $config
* @return mixed
*/
protected function callCustomCreator(array $config)
{
return $this->customCreators[$config['driver']]($this->app, $config);
}
/**
* Create an instance of the driver.
*
* @param array $config
* @return \Illuminate\Contracts\Broadcasting\Broadcaster
*/
protected function createPusherDriver(array $config)
{
return new PusherBroadcaster(
new Pusher($config['key'], $config['secret'],
$config['app_id'], Arr::get($config, 'options', []))
);
}
/**
* Create an instance of the driver.
*
* @param array $config
* @return \Illuminate\Contracts\Broadcasting\Broadcaster
*/
protected function createRedisDriver(array $config)
{
return new RedisBroadcaster(
$this->app->make('redis'), Arr::get($config, 'connection')
);
}
/**
* Create an instance of the driver.
*
* @param array $config
* @return \Illuminate\Contracts\Broadcasting\Broadcaster
*/
protected function createLogDriver(array $config)
{
return new LogBroadcaster(
$this->app->make(LoggerInterface::class)
);
}
/**
* 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.
*
* @param string $name
* @return array
*/
protected function getConfig($name)
{
return $this->app['config']["broadcasting.connections.{$name}"];
}
/**
* Get the default driver name.
*
* @return string
*/
public function getDefaultDriver()
{
return $this->app['config']['broadcasting.default'];
}
/**
* Set the default driver name.
*
* @param string $name
* @return void
*/
public function setDefaultDriver($name)
{
$this->app['config']['broadcasting.default'] = $name;
}
/**
* Register a custom driver creator Closure.
*
* @param string $driver
* @param \Closure $callback
* @return $this
*/
public function extend($driver, Closure $callback)
{
$this->customCreators[$driver] = $callback;
return $this;
}
/**
* Dynamically call the default driver instance.
*
* @param string $method
* @param array $parameters
* @return mixed
*/
public function __call($method, $parameters)
{
return $this->driver()->$method(...$parameters);
}
}

View File

@@ -0,0 +1,51 @@
<?php
namespace Illuminate\Broadcasting;
use Illuminate\Support\ServiceProvider;
use Illuminate\Contracts\Broadcasting\Factory as BroadcastingFactory;
use Illuminate\Contracts\Broadcasting\Broadcaster as BroadcasterContract;
class BroadcastServiceProvider extends ServiceProvider
{
/**
* Indicates if loading of the provider is deferred.
*
* @var bool
*/
protected $defer = true;
/**
* Register the service provider.
*
* @return void
*/
public function register()
{
$this->app->singleton(BroadcastManager::class, function ($app) {
return new BroadcastManager($app);
});
$this->app->singleton(BroadcasterContract::class, function ($app) {
return $app->make(BroadcastManager::class)->connection();
});
$this->app->alias(
BroadcastManager::class, BroadcastingFactory::class
);
}
/**
* Get the services provided by the provider.
*
* @return array
*/
public function provides()
{
return [
BroadcastManager::class,
BroadcastingFactory::class,
BroadcasterContract::class,
];
}
}

View File

@@ -0,0 +1,201 @@
<?php
namespace Illuminate\Broadcasting\Broadcasters;
use ReflectionFunction;
use ReflectionParameter;
use Illuminate\Support\Str;
use Illuminate\Container\Container;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Contracts\Routing\BindingRegistrar;
use Symfony\Component\HttpKernel\Exception\HttpException;
use Illuminate\Contracts\Broadcasting\Broadcaster as BroadcasterContract;
abstract class Broadcaster implements BroadcasterContract
{
/**
* The registered channel authenticators.
*
* @var array
*/
protected $channels = [];
/**
* The binding registrar instance.
*
* @var BindingRegistrar
*/
protected $bindingRegistrar;
/**
* Register a channel authenticator.
*
* @param string $channel
* @param callable $callback
* @return $this
*/
public function channel($channel, callable $callback)
{
$this->channels[$channel] = $callback;
return $this;
}
/**
* Authenticate the incoming request for a given channel.
*
* @param \Illuminate\Http\Request $request
* @param string $channel
* @return mixed
*/
protected function verifyUserCanAccessChannel($request, $channel)
{
foreach ($this->channels as $pattern => $callback) {
if (! Str::is(preg_replace('/\{(.*?)\}/', '*', $pattern), $channel)) {
continue;
}
$parameters = $this->extractAuthParameters($pattern, $channel, $callback);
if ($result = $callback($request->user(), ...$parameters)) {
return $this->validAuthenticationResponse($request, $result);
}
}
throw new HttpException(403);
}
/**
* Extract the parameters from the given pattern and channel.
*
* @param string $pattern
* @param string $channel
* @param callable $callback
* @return array
*/
protected function extractAuthParameters($pattern, $channel, $callback)
{
$callbackParameters = (new ReflectionFunction($callback))->getParameters();
return collect($this->extractChannelKeys($pattern, $channel))->reject(function ($value, $key) {
return is_numeric($key);
})->map(function ($value, $key) use ($callbackParameters) {
return $this->resolveBinding($key, $value, $callbackParameters);
})->values()->all();
}
/**
* Extract the channel keys from the incoming channel name.
*
* @param string $pattern
* @param string $channel
* @return array
*/
protected function extractChannelKeys($pattern, $channel)
{
preg_match('/^'.preg_replace('/\{(.*?)\}/', '(?<$1>[^\.]+)', $pattern).'/', $channel, $keys);
return $keys;
}
/**
* Resolve the given parameter binding.
*
* @param string $key
* @param string $value
* @param array $callbackParameters
* @return mixed
*/
protected function resolveBinding($key, $value, $callbackParameters)
{
$newValue = $this->resolveExplicitBindingIfPossible($key, $value);
return $newValue === $value ? $this->resolveImplicitBindingIfPossible(
$key, $value, $callbackParameters
) : $newValue;
}
/**
* Resolve an explicit parameter binding if applicable.
*
* @param string $key
* @param mixed $value
* @return mixed
*/
protected function resolveExplicitBindingIfPossible($key, $value)
{
$binder = $this->binder();
if ($binder && $binder->getBindingCallback($key)) {
return call_user_func($binder->getBindingCallback($key), $value);
}
return $value;
}
/**
* Resolve an implicit parameter binding if applicable.
*
* @param string $key
* @param mixed $value
* @param array $callbackParameters
* @return mixed
*/
protected function resolveImplicitBindingIfPossible($key, $value, $callbackParameters)
{
foreach ($callbackParameters as $parameter) {
if (! $this->isImplicitlyBindable($key, $parameter)) {
continue;
}
$model = $parameter->getClass()->newInstance();
return $model->where($model->getRouteKeyName(), $value)->firstOr(function () {
throw new HttpException(403);
});
}
return $value;
}
/**
* Determine if a given key and parameter is implicitly bindable.
*
* @param string $key
* @param ReflectionParameter $parameter
* @return bool
*/
protected function isImplicitlyBindable($key, $parameter)
{
return $parameter->name === $key && $parameter->getClass() &&
$parameter->getClass()->isSubclassOf(Model::class);
}
/**
* Format the channel array into an array of strings.
*
* @param array $channels
* @return array
*/
protected function formatChannels(array $channels)
{
return array_map(function ($channel) {
return (string) $channel;
}, $channels);
}
/**
* Get the model binding registrar instance.
*
* @return BindingRegistrar
*/
protected function binder()
{
if (! $this->bindingRegistrar) {
$this->bindingRegistrar = Container::getInstance()->bound(BindingRegistrar::class)
? Container::getInstance()->make(BindingRegistrar::class) : null;
}
return $this->bindingRegistrar;
}
}

View File

@@ -0,0 +1,54 @@
<?php
namespace Illuminate\Broadcasting\Broadcasters;
use Psr\Log\LoggerInterface;
class LogBroadcaster extends Broadcaster
{
/**
* The logger implementation.
*
* @var \Psr\Log\LoggerInterface
*/
protected $logger;
/**
* Create a new broadcaster instance.
*
* @param \Psr\Log\LoggerInterface $logger
* @return void
*/
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(', ', $this->formatChannels($channels));
$payload = json_encode($payload, JSON_PRETTY_PRINT);
$this->logger->info('Broadcasting ['.$event.'] on channels ['.$channels.'] with payload:'.PHP_EOL.$payload);
}
}

View File

@@ -0,0 +1,30 @@
<?php
namespace Illuminate\Broadcasting\Broadcasters;
class NullBroadcaster extends Broadcaster
{
/**
* {@inheritdoc}
*/
public function auth($request)
{
//
}
/**
* {@inheritdoc}
*/
public function validAuthenticationResponse($request, $result)
{
//
}
/**
* {@inheritdoc}
*/
public function broadcast(array $channels, $event, array $payload = [])
{
//
}
}

View File

@@ -0,0 +1,120 @@
<?php
namespace Illuminate\Broadcasting\Broadcasters;
use Pusher;
use Illuminate\Support\Arr;
use Illuminate\Support\Str;
use Illuminate\Broadcasting\BroadcastException;
use Symfony\Component\HttpKernel\Exception\HttpException;
class PusherBroadcaster extends Broadcaster
{
/**
* The Pusher SDK instance.
*
* @var \Pusher
*/
protected $pusher;
/**
* Create a new broadcaster instance.
*
* @param \Pusher $pusher
* @return void
*/
public function __construct(Pusher $pusher)
{
$this->pusher = $pusher;
}
/**
* 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);
}
$channelName = Str::startsWith($request->channel_name, 'private-')
? Str::replaceFirst('private-', '', $request->channel_name)
: Str::replaceFirst('presence-', '', $request->channel_name);
return parent::verifyUserCanAccessChannel(
$request, $channelName
);
}
/**
* Return the valid authentication response.
*
* @param \Illuminate\Http\Request $request
* @param mixed $result
* @return mixed
*/
public function validAuthenticationResponse($request, $result)
{
if (Str::startsWith($request->channel_name, 'private')) {
return $this->decodePusherResponse(
$this->pusher->socket_auth($request->channel_name, $request->socket_id)
);
}
return $this->decodePusherResponse(
$this->pusher->presence_auth(
$request->channel_name, $request->socket_id, $request->user()->getAuthIdentifier(), $result)
);
}
/**
* Decode the given Pusher response.
*
* @param mixed $response
* @return array
*/
protected function decodePusherResponse($response)
{
return json_decode($response, true);
}
/**
* 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');
$response = $this->pusher->trigger(
$this->formatChannels($channels), $event, $payload, $socket, true
);
if ((is_array($response) && $response['status'] >= 200 && $response['status'] <= 299)
|| $response === true) {
return;
}
throw new BroadcastException(
is_bool($response) ? 'Failed to connect to Pusher.' : $response['body']
);
}
/**
* Get the Pusher SDK instance.
*
* @return \Pusher
*/
public function getPusher()
{
return $this->pusher;
}
}

View File

@@ -0,0 +1,102 @@
<?php
namespace Illuminate\Broadcasting\Broadcasters;
use Illuminate\Support\Arr;
use Illuminate\Support\Str;
use Illuminate\Contracts\Redis\Factory as Redis;
use Symfony\Component\HttpKernel\Exception\HttpException;
class RedisBroadcaster extends Broadcaster
{
/**
* The Redis instance.
*
* @var \Illuminate\Contracts\Redis\Factory
*/
protected $redis;
/**
* The Redis connection to use for broadcasting.
*
* @var string
*/
protected $connection;
/**
* Create a new broadcaster instance.
*
* @param \Illuminate\Contracts\Redis\Factory $redis
* @param string $connection
* @return void
*/
public function __construct(Redis $redis, $connection = null)
{
$this->redis = $redis;
$this->connection = $connection;
}
/**
* 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);
}
$channelName = Str::startsWith($request->channel_name, 'private-')
? Str::replaceFirst('private-', '', $request->channel_name)
: Str::replaceFirst('presence-', '', $request->channel_name);
return parent::verifyUserCanAccessChannel(
$request, $channelName
);
}
/**
* 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()->getAuthIdentifier(),
'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 = [])
{
$connection = $this->redis->connection($this->connection);
$payload = json_encode([
'event' => $event,
'data' => $payload,
'socket' => Arr::pull($payload, 'socket'),
]);
foreach ($this->formatChannels($channels) as $channel) {
$connection->publish($channel, $payload);
}
}
}

View File

@@ -0,0 +1,34 @@
<?php
namespace Illuminate\Broadcasting;
class Channel
{
/**
* The channel's name.
*
* @var string
*/
public $name;
/**
* Create a new channel instance.
*
* @param string $name
* @return void
*/
public function __construct($name)
{
$this->name = $name;
}
/**
* Convert the channel instance to a string.
*
* @return string
*/
public function __toString()
{
return $this->name;
}
}

View File

@@ -0,0 +1,39 @@
<?php
namespace Illuminate\Broadcasting;
use Illuminate\Support\Facades\Broadcast;
trait InteractsWithSockets
{
/**
* The socket ID for the user that raised the event.
*
* @var string|null
*/
public $socket;
/**
* Exclude the current user from receiving the broadcast.
*
* @return $this
*/
public function dontBroadcastToCurrentUser()
{
$this->socket = Broadcast::socket();
return $this;
}
/**
* Broadcast the event to everyone.
*
* @return $this
*/
public function broadcastToEveryone()
{
$this->socket = null;
return $this;
}
}

View File

@@ -0,0 +1,59 @@
<?php
namespace Illuminate\Broadcasting;
use Illuminate\Contracts\Events\Dispatcher;
class PendingBroadcast
{
/**
* The event dispatcher implementation.
*
* @var \Illuminate\Contracts\Events\Dispatcher
*/
protected $events;
/**
* The event instance.
*
* @var mixed
*/
protected $event;
/**
* Create a new pending broadcast instance.
*
* @param \Illuminate\Contracts\Events\Dispatcher $events
* @param mixed $event
* @return void
*/
public function __construct(Dispatcher $events, $event)
{
$this->event = $event;
$this->events = $events;
}
/**
* 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;
}
/**
* Handle the object's destruction.
*
* @return void
*/
public function __destruct()
{
$this->events->dispatch($this->event);
}
}

View File

@@ -0,0 +1,17 @@
<?php
namespace Illuminate\Broadcasting;
class PresenceChannel extends Channel
{
/**
* Create a new channel instance.
*
* @param string $name
* @return void
*/
public function __construct($name)
{
parent::__construct('presence-'.$name);
}
}

View File

@@ -0,0 +1,17 @@
<?php
namespace Illuminate\Broadcasting;
class PrivateChannel extends Channel
{
/**
* Create a new channel instance.
*
* @param string $name
* @return void
*/
public function __construct($name)
{
parent::__construct('private-'.$name);
}
}

View File

@@ -0,0 +1,40 @@
{
"name": "illuminate/broadcasting",
"description": "The Illuminate Broadcasting package.",
"license": "MIT",
"homepage": "https://laravel.com",
"support": {
"issues": "https://github.com/laravel/framework/issues",
"source": "https://github.com/laravel/framework"
},
"authors": [
{
"name": "Taylor Otwell",
"email": "taylor@laravel.com"
}
],
"require": {
"php": ">=5.6.4",
"illuminate/bus": "5.4.*",
"illuminate/contracts": "5.4.*",
"illuminate/queue": "5.4.*",
"illuminate/support": "5.4.*"
},
"autoload": {
"psr-4": {
"Illuminate\\Broadcasting\\": ""
}
},
"extra": {
"branch-alias": {
"dev-master": "5.4-dev"
}
},
"suggest": {
"pusher/pusher-php-server": "Required to use the Pusher broadcast driver (~2.0)."
},
"config": {
"sort-packages": true
},
"minimum-stability": "dev"
}