Completed
Branch EDTR/master (0850e5)
by
unknown
43:54 queued 35:26
created

FieldResolver::resolveCacheId()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
nc 1
nop 1
dl 0
loc 9
rs 9.9666
c 0
b 0
f 0
1
<?php
2
3
namespace EventEspresso\core\domain\services\graphql\resolvers;
4
5
use EE_Attendee;
6
use EE_Base_Class;
7
use EE_Event;
8
use EE_Venue;
9
use EE_Datetime;
10
use EE_Ticket;
11
use EE_State;
12
use EEM_State;
13
use EE_Country;
14
use EEM_Country;
15
use EE_Error;
16
use EventEspresso\core\exceptions\InvalidDataTypeException;
17
use EventEspresso\core\exceptions\InvalidInterfaceException;
18
use EventEspresso\core\exceptions\UnexpectedEntityException;
19
use EventEspresso\core\services\graphql\resolvers\ResolverBase;
20
use EventEspresso\core\services\graphql\fields\GraphQLField;
21
use Exception;
22
use InvalidArgumentException;
23
use ReflectionException;
24
use WPGraphQL\Data\DataSource;
25
use GraphQL\Deferred;
26
use GraphQL\Error\UserError;
27
use GraphQL\Type\Definition\ResolveInfo;
28
use GraphQLRelay\Relay;
29
use WPGraphQL\AppContext;
30
31
/**
32
 * Class FieldResolver
33
 * Field resolver for a GraphQL type
34
 *
35
 * @package EventEspresso\core\domain\services\graphql\resolvers
36
 * @author  Manzoor Wani
37
 * @since   $VID:$
38
 */
39
class FieldResolver extends ResolverBase
40
{
41
42
    /**
43
     * @var mixed $model
44
     */
45
    protected $model;
46
47
    /**
48
     * @var array $fields .
49
     */
50
    protected $fields;
51
52
53
    /**
54
     * FieldResolver constructor.
55
     *
56
     * @param mixed $model  The model instance.
57
     * @param array $fields The fields registered for the type.
58
     */
59
    public function __construct($model, array $fields)
60
    {
61
        $this->model = $model;
62
        $this->fields = $fields;
63
    }
64
65
66
    /**
67
     * @param mixed       $source  The source that's passed down the GraphQL queries
68
     * @param array       $args    The inputArgs on the field
69
     * @param AppContext  $context The AppContext passed down the GraphQL tree
70
     * @param ResolveInfo $info    The ResolveInfo passed down the GraphQL tree
71
     * @return string
72
     * @throws EE_Error
73
     * @throws Exception
74
     * @throws InvalidArgumentException
75
     * @throws InvalidDataTypeException
76
     * @throws InvalidInterfaceException
77
     * @throws ReflectionException
78
     * @throws UserError
79
     * @throws UnexpectedEntityException
80
     * @since $VID:$
81
     */
82
    public function resolve($source, array $args, AppContext $context, ResolveInfo $info)
83
    {
84
        $fieldName = $info->fieldName;
85
        $field = isset($this->fields[ $fieldName ]) ? $this->fields[ $fieldName ] : null;
86
        // Field should exist in teh registered fields
87
        if ($field instanceof GraphQLField) {
88
            // check if the field should be resolved.
89
            if (! $field->shouldResolve()) {
90
                return null;
91
            }
92
            // Give priority to the internal resolver.
93
            if ($field->hasInternalResolver()) {
94
                return $field->resolve($source, $args, $context, $info);
95
            }
96
            if (! ($source instanceof EE_Base_Class)) {
97
                return null;
98
            }
99
            // Check if the field has a key mapped to model.
100
            if (! empty($field->key())) {
101
                $value = $source->{$field->key()}();
102
                return $field->mayBeFormatValue($value, $source);
103
            }
104
            switch ($fieldName) {
105
                case 'id': // the global ID
106
                    return $this->resolveId($source);
107
                case 'cacheId':
108
                    return $this->resolveCacheId($source);
109
                case 'parent':
110
                    return $this->resolveParent($source);
111
                case 'event':
112
                    return $this->resolveEvent($source, $args, $context);
113
                case 'wpUser':
114
                    return $this->resolveWpUser($source, $args, $context);
115
                case 'state': // Venue
116
                    return $this->resolveState($source);
117
                case 'country': // State, Venue
118
                    return $this->resolveCountry($source);
119
            }
120
        }
121
        return null;
122
    }
123
124
125
    /**
126
     * Resolve the global ID
127
     *
128
     * @param mixed     $source
129
     * @return string|null
130
     * @throws Exception
131
     * @since $VID:$
132
     */
133
    public function resolveId($source)
134
    {
135
        $ID = $source instanceof EE_Base_Class ? $source->ID() : 0;
136
137
        return $ID ? Relay::toGlobalId($this->model->item_name(), $ID) : null;
138
    }
139
140
141
    /**
142
     * Resolve the cache ID
143
     *
144
     * @param mixed     $source
145
     * @return string
146
     * @since $VID:$
147
     */
148
    public function resolveCacheId($source)
149
    {
150
        $model_name = $this->model->item_name();
151
        $ID         = $source->ID();
152
        // Since cacheId does not need to be globally unique
153
        // $uniqid is sufficient, still adding the model name and ID
154
        // may be we need/use them in future.
155
        return uniqid("{$model_name}:{$ID}:", true);
156
    }
157
158
159
    /**
160
     * @param mixed     $source
161
     * @param           $args
162
     * @param           $context
163
     * @return Deferred|null
164
     * @throws Exception
165
     * @since $VID:$
166
     */
167
    public function resolveWpUser($source, $args, $context)
168
    {
169
        $user_id = $source->wp_user();
170
        return $user_id
171
            ? DataSource::resolve_user($user_id, $context)
172
            : null;
173
    }
174
175
176
    /**
177
     * @param mixed $source
178
     * @return EE_Base_Class|null
179
     * @throws EE_Error
180
     * @throws InvalidArgumentException
181
     * @throws InvalidDataTypeException
182
     * @throws InvalidInterfaceException
183
     * @throws ReflectionException
184
     * @since $VID:$
185
     */
186
    public function resolveParent($source)
187
    {
188
        return $this->model->get_one_by_ID($source->parent());
189
    }
190
191
192
    /**
193
     * @param mixed       $source
194
     * @param             $args
195
     * @param             $context
196
     * @return Deferred|null
197
     * @throws EE_Error
198
     * @throws InvalidArgumentException
199
     * @throws InvalidDataTypeException
200
     * @throws InvalidInterfaceException
201
     * @throws ReflectionException
202
     * @throws UserError
203
     * @throws UnexpectedEntityException
204
     * @since $VID:$
205
     */
206
    public function resolveEvent($source, $args, $context)
207
    {
208
        switch (true) {
209
            case $source instanceof EE_Datetime:
210
                $event = $source->event();
211
                break;
212
            case $source instanceof EE_Venue:
213
            case $source instanceof EE_Ticket:
214
                $event = $source->get_related_event();
0 ignored issues
show
Bug introduced by
The method get_related_event does only exist in EE_Ticket, but not in EE_Venue.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
215
                break;
216
            default:
217
                $event = null;
218
                break;
219
        }
220
        return $event instanceof EE_Event
221
            ? DataSource::resolve_post_object($event->ID(), $context)
222
            : null;
223
    }
224
225
226
    /**
227
     * @param mixed $source The source instance.
228
     * @return EE_Base_Class|null
229
     * @throws EE_Error
230
     * @throws InvalidArgumentException
231
     * @throws InvalidDataTypeException
232
     * @throws InvalidInterfaceException
233
     * @since $VID:$
234
     */
235 View Code Duplication
    public function resolveState($source)
236
    {
237
        switch (true) {
238
            case $source instanceof EE_Attendee:
239
            case $source instanceof EE_Venue:
240
                $state_id = $source->state_ID();
241
                break;
242
            default:
243
                $state_id = null;
244
                break;
245
        }
246
        return $state_id
247
            ? EEM_State::instance()->get_one_by_ID($state_id)
248
            : null;
249
    }
250
251
252
    /**
253
     * @param mixed $source The source instance.
254
     * @return EE_Base_Class|null
255
     * @throws EE_Error
256
     * @throws InvalidArgumentException
257
     * @throws InvalidDataTypeException
258
     * @throws InvalidInterfaceException
259
     * @since $VID:$
260
     */
261 View Code Duplication
    public function resolveCountry($source)
262
    {
263
        switch (true) {
264
            case $source instanceof EE_State:
265
                $country_iso = $source->country_iso();
266
                break;
267
            case $source instanceof EE_Venue:
268
                $country_iso = $source->country_ID();
269
                break;
270
            default:
271
                $country_iso = null;
272
                break;
273
        }
274
275
        return $country_iso
276
            ? EEM_Country::instance()->get_one_by_ID($country_iso)
277
            : null;
278
    }
279
}
280