Completed
Branch EDTR/refactor-master (ea8df4)
by
unknown
26:23 queued 18:16
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 EEM_Venue;
17
use EventEspresso\core\domain\services\assets\EspressoEditorAssetManager;
18
use EventEspresso\core\domain\services\converters\RestApiSpoofer;
19
use EventEspresso\core\exceptions\InvalidDataTypeException;
20
use EventEspresso\core\exceptions\InvalidInterfaceException;
21
use EventEspresso\core\exceptions\ModelConfigurationException;
22
use EventEspresso\core\exceptions\RestPasswordIncorrectException;
23
use EventEspresso\core\exceptions\RestPasswordRequiredException;
24
use EventEspresso\core\exceptions\UnexpectedEntityException;
25
use EventEspresso\core\libraries\rest_api\RestException;
26
use InvalidArgumentException;
27
use ReflectionException;
28
use WP_Post;
29
30
/**
31
 * Class AdvancedEditorEntityData
32
 * Description
33
 *
34
 * @package EventEspresso\core\domain\services\admin\events\editor
35
 * @author  Brent Christensen
36
 * @since   $VID:$
37
 */
38
class AdvancedEditorEntityData
39
{
40
41
    /**
42
     * @var EE_Event
43
     */
44
    protected $event;
45
46
    /**
47
     * @var RestApiSpoofer
48
     */
49
    protected $spoofer;
50
51
    /**
52
     * @var EE_Admin_Config
53
     */
54
    protected $admin_config;
55
56
    /**
57
     * @var EEM_Datetime $datetime_model
58
     */
59
    protected $datetime_model;
60
61
    /**
62
     * @var EEM_Event $event_model
63
     */
64
    protected $event_model;
65
66
    /**
67
     * @var EEM_Price $price_model
68
     */
69
    protected $price_model;
70
71
    /**
72
     * @var EEM_Price_Type $price_type_model
73
     */
74
    protected $price_type_model;
75
76
    /**
77
     * @var EEM_Ticket $ticket_model
78
     */
79
    protected $ticket_model;
80
    /**
81
     * @var EEM_Venue $venue_model
82
     */
83
    protected $venue_model;
84
85
86
    /**
87
     * AdvancedEditorAdminForm constructor.
88
     *
89
     * @param EE_Event        $event
90
     * @param RestApiSpoofer  $spoofer
91
     * @param EE_Admin_Config $admin_config
92
     * @param EEM_Datetime    $datetime_model
93
     * @param EEM_Event       $event_model
94
     * @param EEM_Price       $price_model
95
     * @param EEM_Price_Type  $price_type_model
96
     * @param EEM_Ticket      $ticket_model
97
     * @param EEM_Venue       $venue_model
98
     */
99
    public function __construct(
100
        EE_Event $event,
101
        RestApiSpoofer $spoofer,
102
        EE_Admin_Config $admin_config,
103
        EEM_Datetime $datetime_model,
104
        EEM_Event $event_model,
105
        EEM_Price $price_model,
106
        EEM_Price_Type $price_type_model,
107
        EEM_Ticket $ticket_model,
108
        EEM_Venue $venue_model
109
    ) {
110
        $this->event = $event;
111
        $this->admin_config = $admin_config;
112
        $this->spoofer = $spoofer;
113
        $this->datetime_model = $datetime_model;
114
        $this->event_model = $event_model;
115
        $this->price_model = $price_model;
116
        $this->price_type_model = $price_type_model;
117
        $this->ticket_model = $ticket_model;
118
        $this->venue_model = $venue_model;
119
        add_action('admin_enqueue_scripts', [$this, 'loadScriptsStyles']);
120
    }
121
122
123
    /**
124
     * @throws EE_Error
125
     * @throws InvalidArgumentException
126
     * @throws InvalidDataTypeException
127
     * @throws InvalidInterfaceException
128
     * @throws ModelConfigurationException
129
     * @throws ReflectionException
130
     * @throws RestException
131
     * @throws RestPasswordIncorrectException
132
     * @throws RestPasswordRequiredException
133
     * @throws UnexpectedEntityException
134
     * @throws DomainException
135
     * @since $VID:$
136
     */
137
    public function loadScriptsStyles()
138
    {
139
        if ($this->admin_config->useAdvancedEditor()) {
140
            $eventId = $this->event instanceof EE_Event ? $this->event->ID() : 0;
141
            if (! $eventId) {
142
                global $post;
143
                $eventId = isset($_REQUEST['post']) ? absint($_REQUEST['post']) : 0;
144
                $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...
145
                    ? $post->ID
146
                    : $eventId;
147
            }
148
            if ($eventId) {
149
                $data = $this->getAllEventData($eventId);
150
                $data = wp_json_encode($data);
151
                add_action(
152
                    'admin_footer',
153
                    static function () use ($data) {
154
                        wp_add_inline_script(
155
                            EspressoEditorAssetManager::JS_HANDLE_EDITOR,
156
                            "var eeEditorEventData={$data};",
157
                            'before'
158
                        );
159
                    }
160
                );
161
            }
162
        }
163
    }
164
165
166
    /**
167
     * @param int $eventId
168
     * @return array
169
     * @throws DomainException
170
     * @throws EE_Error
171
     * @throws InvalidArgumentException
172
     * @throws InvalidDataTypeException
173
     * @throws InvalidInterfaceException
174
     * @throws ModelConfigurationException
175
     * @throws ReflectionException
176
     * @throws RestException
177
     * @throws RestPasswordIncorrectException
178
     * @throws RestPasswordRequiredException
179
     * @throws UnexpectedEntityException
180
     * @since $VID:$
181
     */
182
    protected function getEventDates($eventId)
183
    {
184
        return $this->spoofer->getApiResults(
185
            $this->datetime_model,
186
            [
187
                [
188
                    'EVT_ID'      => $eventId,
189
                    'DTT_deleted' => ['IN', [true, false]]
190
                ]
191
            ]
192
        );
193
    }
194
195
196
    /**
197
     * @param int $eventId
198
     * @param array $eventDates
199
     * @throws DomainException
200
     * @throws EE_Error
201
     * @throws InvalidArgumentException
202
     * @throws InvalidDataTypeException
203
     * @throws InvalidInterfaceException
204
     * @throws ModelConfigurationException
205
     * @throws ReflectionException
206
     * @throws RestException
207
     * @throws RestPasswordIncorrectException
208
     * @throws RestPasswordRequiredException
209
     * @throws UnexpectedEntityException
210
     * @since $VID:$
211
     */
212
    protected function addDefaultEntities($eventId, array $eventDates = [])
213
    {
214
        $default_dates = $this->datetime_model->create_new_blank_datetime();
215
        if (is_array($default_dates) && isset($default_dates[0]) && $default_dates[0] instanceof EE_Datetime) {
216
            $default_date = $default_dates[0];
217
            $default_date->save();
218
            $default_date->_add_relation_to($eventId, 'Event');
219
            $default_tickets = $this->ticket_model->get_all_default_tickets();
220
            $default_prices = $this->price_model->get_all_default_prices();
221
            foreach ($default_tickets as $default_ticket) {
222
                $default_ticket->save();
223
                $default_ticket->_add_relation_to($default_date, 'Datetime');
224
                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...
225
                    $default_price->save();
226
                    $default_price->_add_relation_to($default_ticket, 'Ticket');
227
                }
228
            }
229
        }
230
    }
231
232
233
    /**
234
     * @param int $eventId
235
     * @return array
236
     * @throws EE_Error
237
     * @throws InvalidDataTypeException
238
     * @throws InvalidInterfaceException
239
     * @throws ModelConfigurationException
240
     * @throws RestPasswordIncorrectException
241
     * @throws RestPasswordRequiredException
242
     * @throws UnexpectedEntityException
243
     * @throws RestException
244
     * @throws InvalidArgumentException
245
     * @throws ReflectionException
246
     * @throws DomainException
247
     * @since $VID:$
248
     */
249
    protected function getAllEventData($eventId)
250
    {
251
        // these should ultimately be extracted out into their own classes (one per model)
252
        $event = $this->spoofer->getOneApiResult(
253
            $this->event_model,
254
            [['EVT_ID' => $eventId]]
255
        );
256
        if (! (is_array($event) && isset($event['EVT_ID']) && $event['EVT_ID'] === $eventId)) {
257
            return [];
258
        }
259
        $eventDates = $this->getEventDates($eventId);
260
        if ((! is_array($eventDates) || empty($eventDates))
261
            || (isset($_REQUEST['action']) && $_REQUEST['action'] === 'create_new')
262
        ) {
263
            $this->addDefaultEntities($eventId);
264
            $eventDates = $this->getEventDates($eventId);
265
        }
266
267
        $event = [$eventId => $event];
268
        $relations = [
269
            'event'    => [
270
                $eventId => [
271
                    'datetime' => []
272
                ]
273
            ],
274
            'datetime' => [],
275
            'ticket'   => [],
276
            'price'    => [],
277
        ];
278
279
        $datetimes = [];
280
        $eventDateTickets = [];
281
        if (is_array($eventDates)) {
282
            foreach ($eventDates as $eventDate) {
283
                if (isset($eventDate['DTT_ID']) && $eventDate['DTT_ID']) {
284
                    $DTT_ID = $eventDate['DTT_ID'];
285
                    $datetimes[ $DTT_ID ] = $eventDate;
286
                    $relations['event'][ $eventId ]['datetime'][] = $DTT_ID;
287
                    $eventDateTickets[ $DTT_ID ] = $this->spoofer->getApiResults(
288
                        $this->ticket_model,
289
                        [[
290
                            'Datetime.DTT_ID' => $DTT_ID,
291
                            'TKT_deleted' => ['IN', [true, false]]
292
                        ]]
293
                    );
294
                }
295
            }
296
        }
297
298
        $prices = [];
299
        $tickets = [];
300
        if (is_array($eventDateTickets)) {
301
            foreach ($eventDateTickets as $DTT_ID => $dateTickets) {
302
                if (is_array($dateTickets)) {
303
                    $relations['datetime'][ $DTT_ID ]['ticket'] = [];
304
                    foreach ($dateTickets as $ticket) {
305
                        if (isset($ticket['TKT_ID']) && $ticket['TKT_ID']) {
306
                            $TKT_ID = $ticket['TKT_ID'];
307
                            $tickets[ $TKT_ID ] = $ticket;
308
                            $relations['datetime'][ $DTT_ID ]['ticket'][] = $TKT_ID;
309
                            $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...
310
                                $this->price_model,
311
                                [['Ticket.TKT_ID' => $TKT_ID]]
312
                            );
313
                            if (is_array($ticketPrices[ $TKT_ID ])) {
314
                                $relations['ticket'][ $TKT_ID ]['price'] = [];
315
                                foreach ($ticketPrices[ $TKT_ID ] as $ticketPrice) {
316
                                    $PRC_ID = $ticketPrice['PRC_ID'];
317
                                    $prices[ $PRC_ID ] = $ticketPrice;
318
                                    $relations['ticket'][ $TKT_ID ]['price'][] = $PRC_ID;
319
                                }
320
                            }
321
                        }
322
                    }
323
                }
324
            }
325
        }
326
        $price_type_results = $this->spoofer->getApiResults(
327
            $this->price_type_model,
328
            [['PRT_deleted' => false]]
329
        );
330
        $price_types = [];
331
        foreach ($price_type_results as $price_type) {
332
            $price_types[ $price_type['PRT_ID'] ] = $price_type;
333
        }
334
        $venue = $this->spoofer->getOneApiResult(
335
            $this->venue_model,
336
            [['Event.EVT_ID' => $eventId]]
337
        );
338
        if (is_array($venue) && isset($venue['VNU_ID'])) {
339
            $relations['event'][ $eventId ]['venue'] = [ $venue['VNU_ID'] ];
340
            $venue = [$venue['VNU_ID'] => $venue];
341
        }
342
343
        $schemas = [
344
            'event'      => $this->spoofer->getModelSchema('events'),
345
            'datetime'   => $this->spoofer->getModelSchema('datetimes'),
346
            'ticket'     => $this->spoofer->getModelSchema('tickets'),
347
            'price'      => $this->spoofer->getModelSchema('prices'),
348
            'price_type' => $this->spoofer->getModelSchema('price_types'),
349
            'venue'      => $this->spoofer->getModelSchema('venues'),
350
        ];
351
352
        return [
353
            'eventId'    => $eventId,
354
            'event'      => $event,
355
            'datetime'   => $datetimes,
356
            'ticket'     => $tickets,
357
            'price'      => $prices,
358
            'price_type' => $price_types,
359
            'venue'      => $venue,
360
            'schemas'    => $schemas,
361
            'relations'  => $relations,
362
        ];
363
    }
364
}
365