Completed
Branch EDTR/master (da70c7)
by
unknown
33:49 queued 25:01
created

AdvancedEditorData::getGraphQLDatetimes()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 43

Duplication

Lines 43
Ratio 100 %

Importance

Changes 0
Metric Value
cc 2
nc 2
nop 1
dl 43
loc 43
rs 9.232
c 0
b 0
f 0
1
<?php
2
3
namespace EventEspresso\core\domain\services\admin\events\editor;
4
5
use DomainException;
6
use EE_Admin_Config;
7
use EE_Error;
8
use EE_Event;
9
use EEM_Datetime;
10
use EEM_Price;
11
use EEM_Price_Type;
12
use EEM_Ticket;
13
use EEM_Venue;
14
use EventEspresso\core\domain\services\assets\EspressoEditorAssetManager;
15
use EventEspresso\core\exceptions\InvalidDataTypeException;
16
use EventEspresso\core\exceptions\InvalidInterfaceException;
17
use EventEspresso\core\exceptions\ModelConfigurationException;
18
use EventEspresso\core\exceptions\UnexpectedEntityException;
19
use InvalidArgumentException;
20
use ReflectionException;
21
use WP_Post;
22
use WPGraphQL\Router;
23
use GraphQLRelay\Relay;
24
25
/**
26
 * Class AdvancedEditorData
27
 * Description
28
 *
29
 * @package EventEspresso\core\domain\services\admin\events\editor
30
 * @author  Brent Christensen
31
 * @since   $VID:$
32
 */
33
class AdvancedEditorData
34
{
35
36
    /**
37
     * @var string $namespace The graphql namespace/prefix.
38
     */
39
    protected $namespace = 'Espresso';
40
41
    /**
42
     * @var EE_Event
43
     */
44
    protected $event;
45
46
    /**
47
     * @var EE_Admin_Config
48
     */
49
    protected $admin_config;
50
51
52
    /**
53
     * AdvancedEditorAdminForm constructor.
54
     *
55
     * @param EE_Event        $event
56
     * @param EE_Admin_Config $admin_config
57
     */
58
    public function __construct(
59
        EE_Event $event,
60
        EE_Admin_Config $admin_config
61
    ) {
62
        $this->event = $event;
63
        $this->admin_config = $admin_config;
64
        add_action('admin_enqueue_scripts', [$this, 'loadScriptsStyles']);
65
    }
66
67
68
    /**
69
     * @throws EE_Error
70
     * @throws InvalidArgumentException
71
     * @throws InvalidDataTypeException
72
     * @throws InvalidInterfaceException
73
     * @throws ModelConfigurationException
74
     * @throws ReflectionException
75
     * @throws UnexpectedEntityException
76
     * @throws DomainException
77
     * @since $VID:$
78
     */
79
    public function loadScriptsStyles()
80
    {
81
        if ($this->admin_config->useAdvancedEditor()) {
82
            $eventId = $this->event instanceof EE_Event ? $this->event->ID() : 0;
83
            if (! $eventId) {
84
                global $post;
85
                $eventId = isset($_REQUEST['post']) ? absint($_REQUEST['post']) : 0;
86
                $eventId = $eventId === 0 && $post instanceof WP_Post && $post->post_type === 'espresso_events'
0 ignored issues
show
Bug introduced by
The class WP_Post does not exist. Is this class maybe located in a folder that is not analyzed, or in a newer version of your dependencies than listed in your composer.lock/composer.json?
Loading history...
87
                    ? $post->ID
88
                    : $eventId;
89
            }
90
            if ($eventId) {
91
                $data = $this->getEditorData($eventId);
92
                $data = wp_json_encode($data);
93
                add_action(
94
                    'admin_footer',
95
                    static function () use ($data) {
96
                        wp_add_inline_script(
97
                            EspressoEditorAssetManager::JS_HANDLE_EDITOR,
98
                            "
99
var eeEditorData={$data};
100
",
101
                            'before'
102
                        );
103
                    }
104
                );
105
                add_action(
106
                    'admin_footer',
107
                    static function () use ($data) {
108
                        wp_add_inline_script(
109
                            EspressoEditorAssetManager::JS_HANDLE_EDITOR_PROTOTYPE,
110
                            "
111
var eeEditorData={$data};
112
",
113
                            'before'
114
                        );
115
                    }
116
                );
117
            }
118
        }
119
    }
120
121
122
    /**
123
     * @param int $eventId
124
     * @return array
125
     * @throws EE_Error
126
     * @throws InvalidDataTypeException
127
     * @throws InvalidInterfaceException
128
     * @throws ModelConfigurationException
129
     * @throws UnexpectedEntityException
130
     * @throws InvalidArgumentException
131
     * @throws ReflectionException
132
     * @throws DomainException
133
     * @since $VID:$
134
     */
135
    protected function getEditorData($eventId)
136
    {
137
        $event = $this->getEventGraphQLData($eventId);
138
        $event['dbId'] = $eventId;
139
140
        $graphqlEndpoint = class_exists('WPGraphQL') ? trailingslashit(site_url()) . Router::$route : '';
141
        $graphqlEndpoint = esc_url($graphqlEndpoint);
142
143
        $currentUser = $this->getGraphQLCurrentUser();
144
145
        $generalSettings = $this->getGraphQLGeneralSettings();
146
147
        return compact('event', 'graphqlEndpoint', 'currentUser', 'generalSettings');
148
    }
149
150
151
    /**
152
     * @param int $eventId
153
     * @return array
154
     * @since $VID:$
155
     */
156
    protected function getEventGraphQLData($eventId)
157
    {
158
        $datetimes = $this->getGraphQLDatetimes($eventId);
159
160
        if (! empty($datetimes['nodes'])) {
161
            $datetimeIn = wp_list_pluck($datetimes['nodes'], 'id');
162
163
            if (! empty($datetimeIn)) {
164
                $tickets = $this->getGraphQLTickets($datetimeIn);
165
            }
166
        }
167
168
        if (! empty($tickets['nodes'])) {
169
            $ticketIn = wp_list_pluck($tickets['nodes'], 'id');
170
171
            if (! empty($ticketIn)) {
172
                $prices = $this->getGraphQLPrices($ticketIn);
173
            }
174
        }
175
176
        $priceTypes = $this->getGraphQLPriceTypes();
177
178
        $relations = $this->getRelationalData($eventId);
179
180
        return compact('datetimes', 'tickets', 'prices', 'priceTypes', 'relations');
181
    }
182
183
184
    /**
185
     * @param int $eventId
186
     * @return array|null
187
     * @since $VID:$
188
     */
189 View Code Duplication
    protected function getGraphQLDatetimes($eventId)
190
    {
191
        $field_key = lcfirst($this->namespace) . 'Datetimes';
192
        $query = <<<QUERY
193
        query GET_DATETIMES(\$where: {$this->namespace}RootQueryDatetimesConnectionWhereArgs) {
194
            {$field_key}(where: \$where) {
195
                nodes {
196
                    id
197
                    dbId
198
                    name
199
                    description
200
                    startDate
201
                    endDate
202
                    capacity
203
                    isActive
204
                    isExpired
205
                    isPrimary
206
                    isSoldOut
207
                    isUpcoming
208
                    length
209
                    order
210
                    reserved
211
                    sold
212
                    __typename
213
                }
214
                __typename
215
            }
216
        }
217
QUERY;
218
            $data = [
219
                'operation_name' => 'GET_DATETIMES',
220
                'variables' => [
221
                    'first' => 50,
222
                    'where' => [
223
                        'eventId' => $eventId,
224
                    ],
225
                ],
226
                'query' => $query,
227
            ];
228
229
            $responseData = $this->makeGraphQLRequest($data);
230
            return !empty($responseData[ $field_key ]) ? $responseData[ $field_key ] : null;
231
    }
232
233
234
    /**
235
     * @param array $datetimeIn
236
     * @return array|null
237
     * @since $VID:$
238
     */
239 View Code Duplication
    protected function getGraphQLTickets(array $datetimeIn)
240
    {
241
        $field_key = lcfirst($this->namespace) . 'Tickets';
242
        $query = <<<QUERY
243
        query GET_TICKETS(\$where: {$this->namespace}RootQueryTicketsConnectionWhereArgs) {
244
            {$field_key}(where: \$where) {
245
                nodes {
246
                    id
247
                    dbId
248
                    description
249
                    endDate
250
                    isDefault
251
                    isFree
252
                    isRequired
253
                    isTaxable
254
                    max
255
                    min
256
                    name
257
                    order
258
                    price
259
                    quantity
260
                    reserved
261
                    reverseCalculate
262
                    sold
263
                    startDate
264
                    uses
265
                    __typename
266
                }
267
                __typename
268
            }
269
        }
270
QUERY;
271
            $data = [
272
                'operation_name' => 'GET_TICKETS',
273
                'variables' => [
274
                    'where' => [
275
                        'datetimeIn' => $datetimeIn,
276
                    ],
277
                ],
278
                'query' => $query,
279
            ];
280
281
            $responseData = $this->makeGraphQLRequest($data);
282
            return !empty($responseData[ $field_key ]) ? $responseData[ $field_key ] : null;
283
    }
284
285
286
    /**
287
     * @param array $ticketIn
288
     * @return array|null
289
     * @since $VID:$
290
     */
291 View Code Duplication
    protected function getGraphQLPrices(array $ticketIn)
292
    {
293
        $field_key = lcfirst($this->namespace) . 'Prices';
294
        $query = <<<QUERY
295
        query GET_PRICES(\$where: {$this->namespace}RootQueryPricesConnectionWhereArgs) {
296
            {$field_key}(where: \$where) {
297
                nodes {
298
                    id
299
                    dbId
300
                    amount
301
                    desc
302
                    isBasePrice
303
                    isDefault
304
                    isDeleted
305
                    isDiscount
306
                    isPercent
307
                    isTax
308
                    name
309
                    order
310
                    overrides
311
                    priceTypeOrder
312
                    __typename
313
                }
314
                __typename
315
            }
316
        }
317
QUERY;
318
            $data = [
319
                'operation_name' => 'GET_PRICES',
320
                'variables' => [
321
                    'where' => [
322
                        'ticketIn' => $ticketIn,
323
                    ],
324
                ],
325
                'query' => $query,
326
            ];
327
328
            $responseData = $this->makeGraphQLRequest($data);
329
            return !empty($responseData[ $field_key ]) ? $responseData[ $field_key ] : null;
330
    }
331
332
333
    /**
334
     * @return array|null
335
     * @since $VID:$
336
     */
337 View Code Duplication
    protected function getGraphQLPriceTypes()
338
    {
339
        $field_key = lcfirst($this->namespace) . 'PriceTypes';
340
        $query = <<<QUERY
341
        query GET_PRICES {
342
            {$field_key} {
343
                nodes {
344
                    id
345
                    dbId
346
                    baseType
347
                    isBasePrice
348
                    isDeleted
349
                    isDiscount
350
                    isPercent
351
                    isTax
352
                    name
353
                    order
354
                    __typename
355
                }
356
                __typename
357
            }
358
        }
359
QUERY;
360
            $data = [
361
                'operation_name' => 'GET_PRICES',
362
                'query' => $query,
363
            ];
364
365
            $responseData = $this->makeGraphQLRequest($data);
366
            return !empty($responseData[ $field_key ]) ? $responseData[ $field_key ] : null;
367
    }
368
369
370
    /**
371
     * @return array|null
372
     * @since $VID:$
373
     */
374 View Code Duplication
    protected function getGraphQLCurrentUser()
375
    {
376
        $field_key = 'viewer';
377
        $query = <<<QUERY
378
        query GET_CURRENT_USER {
379
            {$field_key} {
380
                description
381
                email
382
                firstName
383
                id
384
                name
385
                nicename
386
                nickname
387
                lastName
388
                locale
389
                userId
390
                username
391
                __typename
392
            }
393
        }
394
QUERY;
395
            $data = [
396
                'operation_name' => 'GET_CURRENT_USER',
397
                'query' => $query,
398
            ];
399
400
            $responseData = $this->makeGraphQLRequest($data);
401
            return !empty($responseData[ $field_key ]) ? $responseData[ $field_key ] : null;
402
    }
403
404
405
    /**
406
     * @return array|null
407
     * @since $VID:$
408
     */
409 View Code Duplication
    protected function getGraphQLGeneralSettings()
410
    {
411
        $field_key = 'generalSettings';
412
        $query = <<<QUERY
413
        query GET_GENERAL_SETTINGS {
414
            {$field_key} {
415
                dateFormat
416
                timeFormat
417
                timezone
418
                __typename
419
            }
420
        }
421
QUERY;
422
            $data = [
423
                'operation_name' => 'GET_CURRENT_USER',
424
                'query' => $query,
425
            ];
426
427
            $responseData = $this->makeGraphQLRequest($data);
428
            return !empty($responseData[ $field_key ]) ? $responseData[ $field_key ] : null;
429
    }
430
431
432
    /**
433
     * @param array $data
434
     * @return array
435
     * @since $VID:$
436
     */
437
    protected function makeGraphQLRequest($data)
438
    {
439
        try {
440
            $response = graphql($data);
441
            if (!empty($response['data'])) {
442
                return $response['data'];
443
            }
444
            return null;
445
        } catch (\Exception $e) {
446
            // do something with the errors thrown
447
            return null;
448
        }
449
    }
450
451
452
    /**
453
     * @param mixed       $source  The source that's passed down the GraphQL queries
0 ignored issues
show
Bug introduced by
There is no parameter named $source. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
454
     * @param array       $args    The inputArgs on the field
0 ignored issues
show
Bug introduced by
There is no parameter named $args. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
455
     * @param AppContext  $context The AppContext passed down the GraphQL tree
0 ignored issues
show
Bug introduced by
There is no parameter named $context. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
456
     * @param ResolveInfo $info    The ResolveInfo passed down the GraphQL tree
0 ignored issues
show
Bug introduced by
There is no parameter named $info. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
457
     * @return string
458
     * @throws EE_Error
459
     * @throws Exception
460
     * @throws InvalidArgumentException
461
     * @throws InvalidDataTypeException
462
     * @throws InvalidInterfaceException
463
     * @throws ReflectionException
464
     * @throws UserError
465
     * @throws UnexpectedEntityException
466
     * @since $VID:$
467
     */
468
    public static function getRelationalData($eventId)
469
    {
470
471
        $data = [
472
            'datetimes'  => [],
473
            'tickets'    => [],
474
            'prices'     => [],
475
        ];
476
477
        $eem_datetime   = EEM_Datetime::instance();
478
        $eem_ticket     = EEM_Ticket::instance();
479
        $eem_price      = EEM_Price::instance();
480
        $eem_price_type = EEM_Price_Type::instance();
481
482
        // PROCESS DATETIMES
483
        $related_models = [
484
            'tickets' => $eem_ticket,
485
        ];
486
        // Get the IDs of event datetimes.
487
        $datetimeIds = $eem_datetime->get_col([['EVT_ID' => $eventId]]);
488 View Code Duplication
        foreach ($datetimeIds as $datetimeId) {
489
            $GID = self::convertToGlobalId($eem_datetime->item_name(), $datetimeId);
490
            foreach ($related_models as $key => $model) {
491
                // Get the IDs of related entities for the datetime ID.
492
                $Ids = $model->get_col([['Datetime.DTT_ID' => $datetimeId]]);
493
                if (! empty($Ids)) {
494
                    $data['datetimes'][ $GID ][ $key ] = self::convertToGlobalId($model->item_name(), $Ids);
495
                }
496
            }
497
        }
498
499
        // PROCESS TICKETS
500
        $related_models = [
501
            'datetimes' => $eem_datetime,
502
            'prices'    => $eem_price,
503
        ];
504
        // Get the IDs of all datetime tickets.
505
        $ticketIds = $eem_ticket->get_col([['Datetime.DTT_ID' => ['in', $datetimeIds]]]);
506 View Code Duplication
        foreach ($ticketIds as $ticketId) {
507
            $GID = self::convertToGlobalId($eem_ticket->item_name(), $ticketId);
508
509
            foreach ($related_models as $key => $model) {
510
                // Get the IDs of related entities for the ticket ID.
511
                $Ids = $model->get_col([['Ticket.TKT_ID' => $ticketId]]);
512
                if (! empty($Ids)) {
513
                    $data['tickets'][ $GID ][ $key ] = self::convertToGlobalId($model->item_name(), $Ids);
514
                }
515
            }
516
        }
517
518
        // PROCESS PRICES
519
        $related_models = [
520
            'tickets'    => $eem_ticket,
521
            'priceTypes' => $eem_price_type,
522
        ];
523
        // Get the IDs of all ticket prices.
524
        $priceIds = $eem_price->get_col([['Ticket.TKT_ID' => ['in', $ticketIds]]]);
525 View Code Duplication
        foreach ($priceIds as $priceId) {
526
            $GID = self::convertToGlobalId($eem_price->item_name(), $priceId);
527
528
            foreach ($related_models as $key => $model) {
529
                // Get the IDs of related entities for the price ID.
530
                $Ids = $model->get_col([['Price.PRC_ID' => $priceId]]);
531
                if (! empty($Ids)) {
532
                    $data['prices'][ $GID ][ $key ] = self::convertToGlobalId($model->item_name(), $Ids);
533
                }
534
            }
535
        }
536
537
        return $data;
538
    }
539
540
    /**
541
     * Convert the DB ID into GID
542
     *
543
     * @param string    $type
544
     * @param int|int[] $ID
545
     * @return mixed
546
     */
547
    public static function convertToGlobalId($type, $ID)
548
    {
549
        if (is_array($ID)) {
550
            return array_map(function ($id) use ($type) {
551
                return self::convertToGlobalId($type, $id);
552
            }, $ID);
553
        }
554
        return Relay::toGlobalId($type, $ID);
555
    }
556
}
557