Subversion-Projekte lars-tiefland.laravel_shop

Revision

Details | Letzte Änderung | Log anzeigen | RSS feed

Revision Autor Zeilennr. Zeile
148 lars 1
<?php
2
 
3
namespace Illuminate\Broadcasting\Broadcasters;
4
 
5
use Illuminate\Broadcasting\BroadcastException;
6
use Illuminate\Support\Arr;
7
use Illuminate\Support\Collection;
8
use Pusher\ApiErrorException;
9
use Pusher\Pusher;
10
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
11
 
12
class PusherBroadcaster extends Broadcaster
13
{
14
    use UsePusherChannelConventions;
15
 
16
    /**
17
     * The Pusher SDK instance.
18
     *
19
     * @var \Pusher\Pusher
20
     */
21
    protected $pusher;
22
 
23
    /**
24
     * Create a new broadcaster instance.
25
     *
26
     * @param  \Pusher\Pusher  $pusher
27
     * @return void
28
     */
29
    public function __construct(Pusher $pusher)
30
    {
31
        $this->pusher = $pusher;
32
    }
33
 
34
    /**
35
     * Resolve the authenticated user payload for an incoming connection request.
36
     *
37
     * See: https://pusher.com/docs/channels/library_auth_reference/auth-signatures/#user-authentication
38
     * See: https://pusher.com/docs/channels/server_api/authenticating-users/#response
39
     *
40
     * @param  \Illuminate\Http\Request  $request
41
     * @return array|null
42
     */
43
    public function resolveAuthenticatedUser($request)
44
    {
45
        if (! $user = parent::resolveAuthenticatedUser($request)) {
46
            return;
47
        }
48
 
49
        if (method_exists($this->pusher, 'authenticateUser')) {
50
            return $this->pusher->authenticateUser($request->socket_id, $user);
51
        }
52
 
53
        $settings = $this->pusher->getSettings();
54
        $encodedUser = json_encode($user);
55
        $decodedString = "{$request->socket_id}::user::{$encodedUser}";
56
 
57
        $auth = $settings['auth_key'].':'.hash_hmac(
58
            'sha256', $decodedString, $settings['secret']
59
        );
60
 
61
        return [
62
            'auth' => $auth,
63
            'user_data' => $encodedUser,
64
        ];
65
    }
66
 
67
    /**
68
     * Authenticate the incoming request for a given channel.
69
     *
70
     * @param  \Illuminate\Http\Request  $request
71
     * @return mixed
72
     *
73
     * @throws \Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException
74
     */
75
    public function auth($request)
76
    {
77
        $channelName = $this->normalizeChannelName($request->channel_name);
78
 
79
        if (empty($request->channel_name) ||
80
            ($this->isGuardedChannel($request->channel_name) &&
81
            ! $this->retrieveUser($request, $channelName))) {
82
            throw new AccessDeniedHttpException;
83
        }
84
 
85
        return parent::verifyUserCanAccessChannel(
86
            $request, $channelName
87
        );
88
    }
89
 
90
    /**
91
     * Return the valid authentication response.
92
     *
93
     * @param  \Illuminate\Http\Request  $request
94
     * @param  mixed  $result
95
     * @return mixed
96
     */
97
    public function validAuthenticationResponse($request, $result)
98
    {
99
        if (str_starts_with($request->channel_name, 'private')) {
100
            return $this->decodePusherResponse(
101
                $request,
102
                method_exists($this->pusher, 'authorizeChannel')
103
                    ? $this->pusher->authorizeChannel($request->channel_name, $request->socket_id)
104
                    : $this->pusher->socket_auth($request->channel_name, $request->socket_id)
105
            );
106
        }
107
 
108
        $channelName = $this->normalizeChannelName($request->channel_name);
109
 
110
        $user = $this->retrieveUser($request, $channelName);
111
 
112
        $broadcastIdentifier = method_exists($user, 'getAuthIdentifierForBroadcasting')
113
                        ? $user->getAuthIdentifierForBroadcasting()
114
                        : $user->getAuthIdentifier();
115
 
116
        return $this->decodePusherResponse(
117
            $request,
118
            method_exists($this->pusher, 'authorizePresenceChannel')
119
                ? $this->pusher->authorizePresenceChannel($request->channel_name, $request->socket_id, $broadcastIdentifier, $result)
120
                : $this->pusher->presence_auth($request->channel_name, $request->socket_id, $broadcastIdentifier, $result)
121
        );
122
    }
123
 
124
    /**
125
     * Decode the given Pusher response.
126
     *
127
     * @param  \Illuminate\Http\Request  $request
128
     * @param  mixed  $response
129
     * @return array
130
     */
131
    protected function decodePusherResponse($request, $response)
132
    {
133
        if (! $request->input('callback', false)) {
134
            return json_decode($response, true);
135
        }
136
 
137
        return response()->json(json_decode($response, true))
138
                    ->withCallback($request->callback);
139
    }
140
 
141
    /**
142
     * Broadcast the given event.
143
     *
144
     * @param  array  $channels
145
     * @param  string  $event
146
     * @param  array  $payload
147
     * @return void
148
     *
149
     * @throws \Illuminate\Broadcasting\BroadcastException
150
     */
151
    public function broadcast(array $channels, $event, array $payload = [])
152
    {
153
        $socket = Arr::pull($payload, 'socket');
154
 
155
        $parameters = $socket !== null ? ['socket_id' => $socket] : [];
156
 
157
        $channels = Collection::make($this->formatChannels($channels));
158
 
159
        try {
160
            $channels->chunk(100)->each(function ($channels) use ($event, $payload, $parameters) {
161
                $this->pusher->trigger($channels->toArray(), $event, $payload, $parameters);
162
            });
163
        } catch (ApiErrorException $e) {
164
            throw new BroadcastException(
165
                sprintf('Pusher error: %s.', $e->getMessage())
166
            );
167
        }
168
    }
169
 
170
    /**
171
     * Get the Pusher SDK instance.
172
     *
173
     * @return \Pusher\Pusher
174
     */
175
    public function getPusher()
176
    {
177
        return $this->pusher;
178
    }
179
 
180
    /**
181
     * Set the Pusher SDK instance.
182
     *
183
     * @param  \Pusher\Pusher  $pusher
184
     * @return void
185
     */
186
    public function setPusher($pusher)
187
    {
188
        $this->pusher = $pusher;
189
    }
190
}