Completed
Branch EDTR/refactor-tkt-reg-count (88344e)
by
unknown
34:40 queued 26:27
created

AdvancedEditorEntityData::addDefaultEntities()   A

Complexity

Conditions 6
Paths 4

Size

Total Lines 19

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 6
nc 4
nop 2
dl 0
loc 19
rs 9.0111
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_Datetime;
8
use EE_Error;
9
use EE_Event;
10
use EEH_DTT_Helper;
11
use EEM_Datetime;
12
use EEM_Event;
13
use EEM_Price;
14
use EEM_Price_Type;
15
use EEM_Ticket;
16
use EE_Ticket;
17
use EEM_Venue;
18
use EventEspresso\core\domain\services\assets\EspressoEditorAssetManager;
19
use EventEspresso\core\domain\services\converters\RestApiSpoofer;
20
use EventEspresso\core\exceptions\InvalidDataTypeException;
21
use EventEspresso\core\exceptions\InvalidInterfaceException;
22
use EventEspresso\core\exceptions\ModelConfigurationException;
23
use EventEspresso\core\exceptions\RestPasswordIncorrectException;
24
use EventEspresso\core\exceptions\RestPasswordRequiredException;
25
use EventEspresso\core\exceptions\UnexpectedEntityException;
26
use EventEspresso\core\libraries\rest_api\RestException;
27
use InvalidArgumentException;
28
use ReflectionException;
29
use WP_Post;
30
31
/**
32
 * Class AdvancedEditorEntityData
33
 * Description
34
 *
35
 * @package EventEspresso\core\domain\services\admin\events\editor
36
 * @author  Brent Christensen
37
 * @since   $VID:$
38
 */
39
class AdvancedEditorEntityData
40
{
41
42
    /**
43
     * @var EE_Event
44
     */
45
    protected $event;
46
47
    /**
48
     * @var RestApiSpoofer
49
     */
50
    protected $spoofer;
51
52
    /**
53
     * @var EE_Admin_Config
54
     */
55
    protected $admin_config;
56
57
    /**
58
     * @var EEM_Datetime $datetime_model
59
     */
60
    protected $datetime_model;
61
62
    /**
63
     * @var EEM_Event $event_model
64
     */
65
    protected $event_model;
66
67
    /**
68
     * @var EEM_Price $price_model
69
     */
70
    protected $price_model;
71
72
    /**
73
     * @var EEM_Price_Type $price_type_model
74
     */
75
    protected $price_type_model;
76
77
    /**
78
     * @var EEM_Ticket $ticket_model
79
     */
80
    protected $ticket_model;
81
    /**
82
     * @var EEM_Venue $venue_model
83
     */
84
    protected $venue_model;
85
86
87
    /**
88
     * AdvancedEditorAdminForm constructor.
89
     *
90
     * @param EE_Event        $event
91
     * @param RestApiSpoofer  $spoofer
92
     * @param EE_Admin_Config $admin_config
93
     * @param EEM_Datetime    $datetime_model
94
     * @param EEM_Event       $event_model
95
     * @param EEM_Price       $price_model
96
     * @param EEM_Price_Type  $price_type_model
97
     * @param EEM_Ticket      $ticket_model
98
     * @param EEM_Venue       $venue_model
99
     */
100
    public function __construct(
101
        EE_Event $event,
102
        RestApiSpoofer $spoofer,
103
        EE_Admin_Config $admin_config,
104
        EEM_Datetime $datetime_model,
105
        EEM_Event $event_model,
106
        EEM_Price $price_model,
107
        EEM_Price_Type $price_type_model,
108
        EEM_Ticket $ticket_model,
109
        EEM_Venue $venue_model
110
    ) {
111
        $this->event = $event;
112
        $this->admin_config = $admin_config;
113
        $this->spoofer = $spoofer;
114
        $this->datetime_model = $datetime_model;
115
        $this->event_model = $event_model;
116
        $this->price_model = $price_model;
117
        $this->price_type_model = $price_type_model;
118
        $this->ticket_model = $ticket_model;
119
        $this->venue_model = $venue_model;
120
        add_action('admin_enqueue_scripts', [$this, 'loadScriptsStyles']);
121
    }
122
123
124
    /**
125
     * @throws EE_Error
126
     * @throws InvalidArgumentException
127
     * @throws InvalidDataTypeException
128
     * @throws InvalidInterfaceException
129
     * @throws ModelConfigurationException
130
     * @throws ReflectionException
131
     * @throws RestException
132
     * @throws RestPasswordIncorrectException
133
     * @throws RestPasswordRequiredException
134
     * @throws UnexpectedEntityException
135
     * @throws DomainException
136
     * @since $VID:$
137
     */
138
    public function loadScriptsStyles()
139
    {
140
        if ($this->admin_config->useAdvancedEditor()) {
141
            $eventId = $this->event instanceof EE_Event ? $this->event->ID() : 0;
142
            if (! $eventId) {
143
                global $post;
144
                $eventId = isset($_REQUEST['post']) ? absint($_REQUEST['post']) : 0;
145
                $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...
146
                    ? $post->ID
147
                    : $eventId;
148
            }
149
            if ($eventId) {
150
                $data = $this->getAllEventData($eventId);
151
                $data = wp_json_encode($data);
152
                add_action(
153
                    'admin_footer',
154
                    static function () use ($data) {
155
                        wp_add_inline_script(
156
                            EspressoEditorAssetManager::JS_HANDLE_EDITOR,
157
                            "var eeEditorEventData={$data};",
158
                            'before'
159
                        );
160
                    }
161
                );
162
            }
163
        }
164
    }
165
166
167
    /**
168
     * @param int $eventId
169
     * @return array
170
     * @throws DomainException
171
     * @throws EE_Error
172
     * @throws InvalidArgumentException
173
     * @throws InvalidDataTypeException
174
     * @throws InvalidInterfaceException
175
     * @throws ModelConfigurationException
176
     * @throws ReflectionException
177
     * @throws RestException
178
     * @throws RestPasswordIncorrectException
179
     * @throws RestPasswordRequiredException
180
     * @throws UnexpectedEntityException
181
     * @since $VID:$
182
     */
183
    protected function getEventDates($eventId)
184
    {
185
        return $this->spoofer->getApiResults(
186
            $this->datetime_model,
187
            [
188
                [
189
                    'EVT_ID'      => $eventId,
190
                    'DTT_deleted' => ['IN', [true, false]]
191
                ]
192
            ]
193
        );
194
    }
195
196
197
    /**
198
     * @param int $eventId
199
     * @param array $eventDates
200
     * @throws DomainException
201
     * @throws EE_Error
202
     * @throws InvalidArgumentException
203
     * @throws InvalidDataTypeException
204
     * @throws InvalidInterfaceException
205
     * @throws ModelConfigurationException
206
     * @throws ReflectionException
207
     * @throws RestException
208
     * @throws RestPasswordIncorrectException
209
     * @throws RestPasswordRequiredException
210
     * @throws UnexpectedEntityException
211
     * @since $VID:$
212
     */
213
    protected function addDefaultEntities($eventId, array $eventDates = [])
214
    {
215
        $default_dates = $this->datetime_model->create_new_blank_datetime();
216
        if (is_array($default_dates) && isset($default_dates[0]) && $default_dates[0] instanceof EE_Datetime) {
217
            $default_date = $default_dates[0];
218
            $default_date->save();
219
            $default_date->_add_relation_to($eventId, 'Event');
220
            $default_tickets = $this->ticket_model->get_all_default_tickets();
221
            $default_prices = $this->price_model->get_all_default_prices();
222
            foreach ($default_tickets as $default_ticket) {
223
                $default_ticket->save();
224
                $default_ticket->_add_relation_to($default_date, 'Datetime');
225
                foreach ($default_prices as $default_price) {
0 ignored issues
show
Bug introduced by
The expression $default_prices of type integer|array<integer,object<EE_Base_Class>> is not guaranteed to be traversable. How about adding an additional type check?

There are different options of fixing this problem.

  1. If you want to be on the safe side, you can add an additional type-check:

    $collection = json_decode($data, true);
    if ( ! is_array($collection)) {
        throw new \RuntimeException('$collection must be an array.');
    }
    
    foreach ($collection as $item) { /** ... */ }
    
  2. If you are sure that the expression is traversable, you might want to add a doc comment cast to improve IDE auto-completion and static analysis:

    /** @var array $collection */
    $collection = json_decode($data, true);
    
    foreach ($collection as $item) { /** .. */ }
    
  3. Mark the issue as a false-positive: Just hover the remove button, in the top-right corner of this issue for more options.

Loading history...
226
                    $default_price->save();
227
                    $default_price->_add_relation_to($default_ticket, 'Ticket');
228
                }
229
            }
230
        }
231
    }
232
233
234
    /**
235
     * @param int $eventId
236
     * @return array
237
     * @throws EE_Error
238
     * @throws InvalidDataTypeException
239
     * @throws InvalidInterfaceException
240
     * @throws ModelConfigurationException
241
     * @throws RestPasswordIncorrectException
242
     * @throws RestPasswordRequiredException
243
     * @throws UnexpectedEntityException
244
     * @throws RestException
245
     * @throws InvalidArgumentException
246
     * @throws ReflectionException
247
     * @throws DomainException
248
     * @since $VID:$
249
     */
250
    protected function getAllEventData($eventId)
251
    {
252
        // these should ultimately be extracted out into their own classes (one per model)
253
        $event = $this->spoofer->getOneApiResult(
254
            $this->event_model,
255
            [['EVT_ID' => $eventId]]
256
        );
257
        if (! (is_array($event) && isset($event['EVT_ID']) && $event['EVT_ID'] === $eventId)) {
258
            return [];
259
        }
260
        $eventDates = $this->getEventDates($eventId);
261
        if ((! is_array($eventDates) || empty($eventDates))
262
            || (isset($_REQUEST['action']) && $_REQUEST['action'] === 'create_new')
263
        ) {
264
            $this->addDefaultEntities($eventId);
265
            $eventDates = $this->getEventDates($eventId);
266
        }
267
268
        $event = [$eventId => $event];
269
        $relations = [
270
            'event'    => [
271
                $eventId => [
272
                    'datetime' => []
273
                ]
274
            ],
275
            'datetime' => [],
276
            'ticket'   => [],
277
            'price'    => [],
278
        ];
279
280
        $datetimes = [];
281
        $eventDateTickets = [];
282
        if (is_array($eventDates)) {
283
            foreach ($eventDates as $eventDate) {
284
                if (isset($eventDate['DTT_ID']) && $eventDate['DTT_ID']) {
285
                    $DTT_ID = $eventDate['DTT_ID'];
286
                    $datetimes[ $DTT_ID ] = $eventDate;
287
                    $relations['event'][ $eventId ]['datetime'][] = $DTT_ID;
288
                    $eventDateTickets[ $DTT_ID ] = $this->spoofer->getApiResults(
289
                        $this->ticket_model,
290
                        [[
291
                            'Datetime.DTT_ID' => $DTT_ID,
292
                            'TKT_deleted' => ['IN', [true, false]]
293
                        ]]
294
                    );
295
                }
296
            }
297
        }
298
299
        $prices = [];
300
        $tickets = [];
301
        if (is_array($eventDateTickets)) {
302
            foreach ($eventDateTickets as $DTT_ID => $dateTickets) {
303
                if (is_array($dateTickets)) {
304
                    $relations['datetime'][ $DTT_ID ]['ticket'] = [];
305
                    foreach ($dateTickets as $ticket) {
306
                        if (isset($ticket['TKT_ID']) && $ticket['TKT_ID']) {
307
                            $TKT_ID = $ticket['TKT_ID'];
308
                            $tickets[ $TKT_ID ] = $ticket;
309
                            $relations['datetime'][ $DTT_ID ]['ticket'][] = $TKT_ID;
310
                            $ticketPrices[ $TKT_ID ] = $this->spoofer->getApiResults(
0 ignored issues
show
Coding Style Comprehensibility introduced by
$ticketPrices was never initialized. Although not strictly required by PHP, it is generally a good practice to add $ticketPrices = array(); before regardless.

Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code.

Let’s take a look at an example:

foreach ($collection as $item) {
    $myArray['foo'] = $item->getFoo();

    if ($item->hasBar()) {
        $myArray['bar'] = $item->getBar();
    }

    // do something with $myArray
}

As you can see in this example, the array $myArray is initialized the first time when the foreach loop is entered. You can also see that the value of the bar key is only written conditionally; thus, its value might result from a previous iteration.

This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop.

Loading history...
311
                                $this->price_model,
312
                                [['Ticket.TKT_ID' => $TKT_ID]]
313
                            );
314
                            if (is_array($ticketPrices[ $TKT_ID ])) {
315
                                $relations['ticket'][ $TKT_ID ]['price'] = [];
316
                                foreach ($ticketPrices[ $TKT_ID ] as $ticketPrice) {
317
                                    $PRC_ID = $ticketPrice['PRC_ID'];
318
                                    $prices[ $PRC_ID ] = $ticketPrice;
319
                                    $relations['ticket'][ $TKT_ID ]['price'][] = $PRC_ID;
320
                                }
321
                            }
322
                        }
323
                    }
324
                }
325
            }
326
        }
327
        $price_type_results = $this->spoofer->getApiResults(
328
            $this->price_type_model,
329
            [['PRT_deleted' => false]]
330
        );
331
        $price_types = [];
332
        foreach ($price_type_results as $price_type) {
333
            $price_types[ $price_type['PRT_ID'] ] = $price_type;
334
        }
335
        $venue = $this->spoofer->getOneApiResult(
336
            $this->venue_model,
337
            [['Event.EVT_ID' => $eventId]]
338
        );
339
        if (is_array($venue) && isset($venue['VNU_ID'])) {
340
            $relations['event'][ $eventId ]['venue'] = [ $venue['VNU_ID'] ];
341
            $venue = [$venue['VNU_ID'] => $venue];
342
        }
343
344
        $schemas = [
345
            'event'      => $this->spoofer->getModelSchema('events'),
346
            'datetime'   => $this->spoofer->getModelSchema('datetimes'),
347
            'ticket'     => $this->spoofer->getModelSchema('tickets'),
348
            'price'      => $this->spoofer->getModelSchema('prices'),
349
            'price_type' => $this->spoofer->getModelSchema('price_types'),
350
            'venue'      => $this->spoofer->getModelSchema('venues'),
351
        ];
352
353
        $tktRegCount = [];
354
        foreach ($tickets as $ticket) {
355
            $tkt_instance = $this->ticket_model->get_one_by_ID($ticket['TKT_ID']);
356
357
            $tktRegCount[$ticket['TKT_ID']] = $tkt_instance instanceof EE_Ticket ?
358
            $tkt_instance->count_registrations()
359
            : 0;
360
        }
361
362
        return [
363
            'eventId'     => $eventId,
364
            'event'       => $event,
365
            'datetime'    => $datetimes,
366
            'ticket'      => $tickets,
367
            'price'       => $prices,
368
            'price_type'  => $price_types,
369
            'venue'       => $venue,
370
            'schemas'     => $schemas,
371
            'relations'   => $relations,
372
            'tktRegCount' => $tktRegCount,
373
        ];
374
    }
375
}
376