<?php namespace Illuminate\Broadcasting\Broadcasters; use Illuminate\Support\Str; 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 = []; /** * 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($pattern, $channel)) { continue; } $parameters = $this->extractAuthParameters($pattern, $channel); 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 * @return array */ protected function extractAuthParameters($pattern, $channel) { if (! Str::contains($pattern, '*')) { return []; } $pattern = str_replace('\*', '([^\.]+)', preg_quote($pattern)); if (preg_match('/^'.$pattern.'/', $channel, $keys)) { array_shift($keys); return $keys; } return []; } /** * 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); } }