1
<?php
2

3
namespace Nuwave\Lighthouse\Subscriptions;
4

5
use GraphQL\Language\AST\DocumentNode;
6
use GraphQL\Language\AST\NodeList;
7
use GraphQL\Type\Definition\ResolveInfo;
8
use GraphQL\Utils\AST;
9
use Illuminate\Support\Str;
10
use Nuwave\Lighthouse\Subscriptions\Contracts\ContextSerializer;
11
use Nuwave\Lighthouse\Support\Contracts\GraphQLContext;
12
use Serializable;
13

14
class Subscriber implements Serializable
15
{
16
    /**
17
     * A unique key for the subscriber's channel.
18
     *
19
     * This has to be unique for each subscriber, because each of them can send a different
20
     * query and must receive a response that is specifically tailored towards that.
21
     *
22
     * @var string
23
     */
24
    public $channel;
25

26
    /**
27
     * The topic subscribed to.
28
     *
29
     * @var string
30
     */
31
    public $topic;
32

33
    /**
34
     * The contents of the query.
35
     *
36
     * @var \GraphQL\Language\AST\DocumentNode
37
     */
38
    public $query;
39

40
    /**
41
     * The name of the queried field.
42
     *
43
     * Guaranteed be be unique because of
44
     * @see \GraphQL\Validator\Rules\SingleFieldSubscription
45
     *
46
     * @var string
47
     */
48
    public $fieldName;
49

50
    /**
51
     * The root element of the query.
52
     *
53
     * @var mixed Can be anything.
54
     */
55
    public $root;
56

57
    /**
58
     * The args passed to the subscription query.
59
     *
60
     * @var array<string, mixed>
61
     */
62
    public $args;
63

64
    /**
65
     * The variables passed to the subscription query.
66
     *
67
     * @var array<string, mixed>
68
     */
69
    public $variables;
70

71
    /**
72
     * The context passed to the query.
73
     *
74
     * @var \Nuwave\Lighthouse\Support\Contracts\GraphQLContext
75
     */
76
    public $context;
77

78
    /**
79
     * @param  array<string, mixed>  $args
80
     */
81 1
    public function __construct(
82
        array $args,
83
        GraphQLContext $context,
84
        ResolveInfo $resolveInfo
85
    ) {
86 1
        $this->fieldName = $resolveInfo->fieldName;
87 1
        $this->channel = self::uniqueChannelName();
88 1
        $this->args = $args;
89 1
        $this->variables = $resolveInfo->variableValues;
90 1
        $this->context = $context;
91

92
        /**
93
         * Must be here, since webonyx/graphql-php validated the subscription.
94
         *
95
         * @var \GraphQL\Language\AST\OperationDefinitionNode $operation
96
         */
97 1
        $operation = $resolveInfo->operation;
98

99 1
        $this->query = new DocumentNode([
100 1
            'definitions' => new NodeList(array_merge(
101 1
                $resolveInfo->fragments,
102 1
                [$operation]
103
            )),
104
        ]);
105
    }
106

107
    /**
108
     * Unserialize subscription from a JSON string.
109
     *
110
     * @param  string  $subscription
111
     */
112 1
    public function unserialize($subscription): void
113
    {
114 1
        $data = \Safe\json_decode($subscription, true);
115

116 1
        $this->channel = $data['channel'];
117 1
        $this->topic = $data['topic'];
118

119
        /**
120
         * We know the type since it is set during construction and serialized.
121
         *
122
         * @var \GraphQL\Language\AST\DocumentNode $documentNode
123
         */
124 1
        $documentNode = AST::fromArray(
125 1
            unserialize($data['query'])
126
        );
127 1
        $this->query = $documentNode;
128 1
        $this->fieldName = $data['field_name'];
129 1
        $this->args = $data['args'];
130 1
        $this->variables = $data['variables'];
131 1
        $this->context = $this->contextSerializer()->unserialize(
132 1
            $data['context']
133
        );
134
    }
135

136
    /**
137
     * Convert this into a JSON string.
138
     */
139 1
    public function serialize(): string
140
    {
141 1
        return \Safe\json_encode([
142 1
            'channel' => $this->channel,
143 1
            'topic' => $this->topic,
144 1
            'query' => serialize(
145 1
                AST::toArray($this->query)
146
            ),
147 1
            'field_name' => $this->fieldName,
148 1
            'args' => $this->args,
149 1
            'variables' => $this->variables,
150 1
            'context' => $this->contextSerializer()->serialize($this->context),
151
        ]);
152
    }
153

154
    /**
155
     * Set root data.
156
     *
157
     * @return $this
158
     * @deprecated set the attribute directly
159
     */
160 0
    public function setRoot($root): self
161
    {
162 0
        $this->root = $root;
163

164 0
        return $this;
165
    }
166

167
    /**
168
     * Generate a unique private channel name.
169
     */
170 1
    public static function uniqueChannelName(): string
171
    {
172 1
        return 'private-lighthouse-'.Str::random(32).'-'.time();
173
    }
174

175 1
    protected function contextSerializer(): ContextSerializer
176
    {
177 1
        return app(ContextSerializer::class);
178
    }
179
}

Read our documentation on viewing source code .

Loading