Completed
Branch models-cleanup/model-relations (bda124)
by
unknown
43:28 queued 33:48
created
core/db_models/relations/EE_Model_Relation_Base.php 3 patches
Doc Comments   +4 added lines, -4 removed lines patch added patch discarded remove patch
@@ -117,7 +117,7 @@  discard block
 block discarded – undo
117 117
      * Note: If the related model is extends EEM_Soft_Delete_Base, then the related
118 118
      * model objects will only be soft-deleted.
119 119
      *
120
-     * @param EE_Base_Class|int|string $model_object_or_id
120
+     * @param EE_Base_Class|null $model_object_or_id
121 121
      * @param array                    $query_params
122 122
      * @return int of how many related models got deleted
123 123
      * @throws EE_Error
@@ -293,7 +293,7 @@  discard block
 block discarded – undo
293 293
      * Note: If the related model is extends EEM_Soft_Delete_Base, then the related
294 294
      * model objects will only be soft-deleted.
295 295
      *
296
-     * @param EE_Base_Class|int|string $model_object_or_id
296
+     * @param EE_Base_Class|null $model_object_or_id
297 297
      * @param array                    $query_params
298 298
      * @return int of how many related models got deleted
299 299
      * @throws EE_Error
@@ -536,9 +536,9 @@  discard block
 block discarded – undo
536 536
 
537 537
     /**
538 538
      * @param        $other_table
539
-     * @param        $other_table_alias
539
+     * @param        string $other_table_alias
540 540
      * @param        $other_table_column
541
-     * @param        $this_table_alias
541
+     * @param        string $this_table_alias
542 542
      * @param        $this_table_join_column
543 543
      * @param string $extra_join_sql
544 544
      * @return string
Please login to merge, or discard this patch.
Indentation   +548 added lines, -548 removed lines patch added patch discarded remove patch
@@ -17,552 +17,552 @@
 block discarded – undo
17 17
 abstract class EE_Model_Relation_Base implements HasSchemaInterface
18 18
 {
19 19
 
20
-    /**
21
-     * @var bool
22
-     */
23
-    protected $_blocking_delete = false;
24
-
25
-    /**
26
-     * If you try to delete "this_model", and there are related "other_models",
27
-     * and this isn't null, then abandon the deletion and add this warning.
28
-     * This effectively makes it impossible to delete "this_model" while there are
29
-     * related "other_models" along this relation.
30
-     *
31
-     * @var string (internationalized)
32
-     */
33
-    protected $_blocking_delete_error_message;
34
-
35
-    /**
36
-     * The model name pointed to by this relation (ie, the model we want to establish a relationship to)
37
-     *
38
-     * @var string eg Event, Question_Group, Registration
39
-     */
40
-    private $_other_model_name;
41
-
42
-    /**
43
-     * The model name of which this relation is a component (ie, the model that called new EE_Model_Relation_Base)
44
-     *
45
-     * @var string eg Event, Question_Group, Registration
46
-     */
47
-    private $_this_model_name;
48
-
49
-    /**
50
-     * this is typically used when calling the relation models to make sure they inherit any set timezone from the
51
-     * initiating model.
52
-     *
53
-     * @var string
54
-     */
55
-    protected $_timezone;
56
-
57
-
58
-    /**
59
-     * Object representing the relationship between two models. This knows how to join the models,
60
-     * get related models across the relation, and add-and-remove the relationships.
61
-     *
62
-     * @param boolean $block_deletes                 if there are related models across this relation, block (prevent
63
-     *                                               and add an error) the deletion of this model
64
-     * @param string  $blocking_delete_error_message a customized error message on blocking deletes instead of the
65
-     *                                               default
66
-     */
67
-    public function __construct($block_deletes, $blocking_delete_error_message)
68
-    {
69
-        $this->_blocking_delete               = $block_deletes;
70
-        $this->_blocking_delete_error_message = $blocking_delete_error_message;
71
-    }
72
-
73
-
74
-    /**
75
-     * @param $this_model_name
76
-     * @param $other_model_name
77
-     * @throws EE_Error
78
-     */
79
-    public function _construct_finalize_set_models($this_model_name, $other_model_name)
80
-    {
81
-        $this->_this_model_name  = $this_model_name;
82
-        $this->_other_model_name = $other_model_name;
83
-        if (is_string($this->_blocking_delete)) {
84
-            throw new EE_Error(
85
-                sprintf(
86
-                    esc_html__(
87
-                        "When instantiating the relation of type %s from %s to %s, the \$block_deletes argument should be a boolean, not a string (%s)",
88
-                        "event_espresso"
89
-                    ),
90
-                    get_class($this),
91
-                    $this_model_name,
92
-                    $other_model_name,
93
-                    $this->_blocking_delete
94
-                )
95
-            );
96
-        }
97
-    }
98
-
99
-
100
-    /**
101
-     * entirely possible that relations may be called from a model and we need to make sure those relations have their
102
-     * timezone set correctly.
103
-     *
104
-     * @param string $timezone timezone to set.
105
-     */
106
-    public function set_timezone($timezone)
107
-    {
108
-        if (! empty($timezone)) {
109
-            $this->_timezone = $timezone;
110
-        }
111
-    }
112
-
113
-
114
-    /**
115
-     * Deletes the related model objects which meet the query parameters. If no
116
-     * parameters are specified, then all related model objects will be deleted.
117
-     * Note: If the related model is extends EEM_Soft_Delete_Base, then the related
118
-     * model objects will only be soft-deleted.
119
-     *
120
-     * @param EE_Base_Class|int|string $model_object_or_id
121
-     * @param array                    $query_params
122
-     * @return int of how many related models got deleted
123
-     * @throws EE_Error
124
-     * @throws ReflectionException
125
-     */
126
-    public function delete_all_related($model_object_or_id, $query_params = [])
127
-    {
128
-        // for each thing we would delete,
129
-        $related_model_objects = $this->get_all_related($model_object_or_id, $query_params);
130
-        // determine if it's blocked by anything else before it can be deleted
131
-        $deleted_count = 0;
132
-        foreach ($related_model_objects as $related_model_object) {
133
-            $delete_is_blocked = $this->get_other_model()->delete_is_blocked_by_related_models(
134
-                $related_model_object,
135
-                $model_object_or_id
136
-            );
137
-            /* @var $model_object_or_id EE_Base_Class */
138
-            if (! $delete_is_blocked) {
139
-                $this->remove_relation_to($model_object_or_id, $related_model_object);
140
-                $related_model_object->delete();
141
-                $deleted_count++;
142
-            }
143
-        }
144
-        return $deleted_count;
145
-    }
146
-
147
-
148
-    /**
149
-     * Gets all the model objects of type of other model related to $model_object,
150
-     * according to this relation. This is the same code for EE_HABTM_Relation and EE_Has_Many_Relation.
151
-     * For both of those child classes, $model_object must be saved so that it has an ID before querying,
152
-     * otherwise an error will be thrown. Note: by default we disable default_where_conditions
153
-     * EE_Belongs_To_Relation doesn't need to be saved before querying.
154
-     *
155
-     * @param EE_Base_Class|int $model_object_or_id                      or the primary key of this model
156
-     * @param array             $query_params                            @see
157
-     *                                                                   https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md
158
-     * @param boolean           $values_already_prepared_by_model_object @deprecated since 4.8.1
159
-     * @return EE_Base_Class[]
160
-     * @throws EE_Error
161
-     * @throws ReflectionException
162
-     */
163
-    public function get_all_related(
164
-        $model_object_or_id,
165
-        $query_params = [],
166
-        $values_already_prepared_by_model_object = false
167
-    ) {
168
-        if ($values_already_prepared_by_model_object !== false) {
169
-            EE_Error::doing_it_wrong(
170
-                'EE_Model_Relation_Base::get_all_related',
171
-                esc_html__('The argument $values_already_prepared_by_model_object is no longer used.', 'event_espresso'),
172
-                '4.8.1'
173
-            );
174
-        }
175
-        $query_params                                        =
176
-            $this->_disable_default_where_conditions_on_query_param($query_params);
177
-        $query_param_where_this_model_pk                     = $this->get_this_model()->get_this_model_name()
178
-                                                               .
179
-                                                               "."
180
-                                                               .
181
-                                                               $this->get_this_model()
182
-                                                                    ->get_primary_key_field()
183
-                                                                    ->get_name();
184
-        $model_object_id                                     = $this->_get_model_object_id($model_object_or_id);
185
-        $query_params[0][ $query_param_where_this_model_pk ] = $model_object_id;
186
-        return $this->get_other_model()->get_all($query_params);
187
-    }
188
-
189
-
190
-    /**
191
-     * Gets the model which this relation establishes the relation TO (ie,
192
-     * this relation object was defined on get_this_model(), get_other_model() is the other one)
193
-     *
194
-     * @return EEM_Base
195
-     * @throws EE_Error
196
-     * @throws ReflectionException
197
-     */
198
-    public function get_other_model()
199
-    {
200
-        return $this->_get_model($this->_other_model_name);
201
-    }
202
-
203
-
204
-    /**
205
-     * Similar to 'add_relation_to(...)', performs the opposite action of removing the relationship between the two
206
-     * model objects
207
-     *
208
-     * @param       $this_obj_or_id
209
-     * @param       $other_obj_or_id
210
-     * @param array $where_query
211
-     * @return bool
212
-     */
213
-    abstract public function remove_relation_to($this_obj_or_id, $other_obj_or_id, $where_query = []);
214
-
215
-
216
-    /**
217
-     * Alters the $query_params to disable default where conditions, unless otherwise specified
218
-     *
219
-     * @param array $query_params
220
-     * @return array
221
-     */
222
-    protected function _disable_default_where_conditions_on_query_param($query_params)
223
-    {
224
-        if (! isset($query_params['default_where_conditions'])) {
225
-            $query_params['default_where_conditions'] = 'none';
226
-        }
227
-        return $query_params;
228
-    }
229
-
230
-
231
-    /**
232
-     * Gets the model where this relation is defined.
233
-     *
234
-     * @return EEM_Base
235
-     * @throws EE_Error
236
-     * @throws ReflectionException
237
-     */
238
-    public function get_this_model()
239
-    {
240
-        return $this->_get_model($this->_this_model_name);
241
-    }
242
-
243
-
244
-    /**
245
-     * this just returns a model_object_id for incoming item that could be an object or id.
246
-     *
247
-     * @param EE_Base_Class|int $model_object_or_id model object or the primary key of this model
248
-     * @return int
249
-     * @throws EE_Error
250
-     * @throws ReflectionException
251
-     */
252
-    protected function _get_model_object_id($model_object_or_id)
253
-    {
254
-        $model_object_id = $model_object_or_id;
255
-        if ($model_object_or_id instanceof EE_Base_Class) {
256
-            $model_object_id = $model_object_or_id->ID();
257
-        }
258
-        if (! $model_object_id) {
259
-            throw new EE_Error(
260
-                sprintf(
261
-                    esc_html__(
262
-                        "Sorry, we cant get the related %s model objects to %s model object before it has an ID. You can solve that by just saving it before trying to get its related model objects",
263
-                        "event_espresso"
264
-                    ),
265
-                    $this->get_other_model()->get_this_model_name(),
266
-                    $this->get_this_model()->get_this_model_name()
267
-                )
268
-            );
269
-        }
270
-        return $model_object_id;
271
-    }
272
-
273
-
274
-    /**
275
-     * Internally used by get_this_model() and get_other_model()
276
-     *
277
-     * @param string $model_name like Event, Question_Group, etc. omit the EEM_
278
-     * @return EEM_Base
279
-     * @throws EE_Error
280
-     * @throws ReflectionException
281
-     */
282
-    protected function _get_model($model_name)
283
-    {
284
-        $modelInstance = EE_Registry::instance()->load_model($model_name);
285
-        $modelInstance->set_timezone($this->_timezone);
286
-        return $modelInstance;
287
-    }
288
-
289
-
290
-    /**
291
-     * Deletes the related model objects which meet the query parameters. If no
292
-     * parameters are specified, then all related model objects will be deleted.
293
-     * Note: If the related model is extends EEM_Soft_Delete_Base, then the related
294
-     * model objects will only be soft-deleted.
295
-     *
296
-     * @param EE_Base_Class|int|string $model_object_or_id
297
-     * @param array                    $query_params
298
-     * @return int of how many related models got deleted
299
-     * @throws EE_Error
300
-     * @throws ReflectionException
301
-     */
302
-    public function delete_related_permanently($model_object_or_id, $query_params = [])
303
-    {
304
-        // for each thing we would delete,
305
-        $related_model_objects = $this->get_all_related($model_object_or_id, $query_params);
306
-        // determine if it's blocked by anything else before it can be deleted
307
-        $deleted_count = 0;
308
-        foreach ($related_model_objects as $related_model_object) {
309
-            $delete_is_blocked = $this->get_other_model()->delete_is_blocked_by_related_models(
310
-                $related_model_object,
311
-                $model_object_or_id
312
-            );
313
-            /* @var $model_object_or_id EE_Base_Class */
314
-            if ($related_model_object instanceof EE_Soft_Delete_Base_Class) {
315
-                $this->remove_relation_to($model_object_or_id, $related_model_object);
316
-                $deleted_count++;
317
-                if (! $delete_is_blocked) {
318
-                    $related_model_object->delete_permanently();
319
-                } else {
320
-                    // delete is blocked
321
-                    // brent and darren, in this case, wanted to just soft delete it then
322
-                    $related_model_object->delete();
323
-                }
324
-            } else {
325
-                // its not a soft-deletable thing anyways. do the normal logic.
326
-                if (! $delete_is_blocked) {
327
-                    $this->remove_relation_to($model_object_or_id, $related_model_object);
328
-                    $related_model_object->delete();
329
-                    $deleted_count++;
330
-                }
331
-            }
332
-        }
333
-        return $deleted_count;
334
-    }
335
-
336
-
337
-    /**
338
-     * Gets the SQL string for performing the join between this model and the other model.
339
-     *
340
-     * @param string $model_relation_chain like 'Event.Event_Venue.Venue'
341
-     * @return string of SQL, eg "LEFT JOIN table_name AS table_alias ON this_model_primary_table.pk =
342
-     *                                     other_model_primary_table.fk" etc
343
-     */
344
-    abstract public function get_join_statement($model_relation_chain);
345
-
346
-
347
-    /**
348
-     * Adds a relationships between the two model objects provided. Each type of relationship handles this differently
349
-     * (EE_Belongs_To is a slight exception, it should more accurately be called set_relation_to(...), as this
350
-     * relationship only allows this model to be related to a single other model of this type)
351
-     *
352
-     * @param       $this_obj_or_id
353
-     * @param       $other_obj_or_id
354
-     * @param array $extra_join_model_fields_n_values
355
-     * @return EE_Base_Class the EE_Base_Class which was added as a relation. (Convenient if you only pass an ID for
356
-     *                        $other_obj_or_id)
357
-     */
358
-    abstract public function add_relation_to(
359
-        $this_obj_or_id,
360
-        $other_obj_or_id,
361
-        $extra_join_model_fields_n_values = []
362
-    );
363
-
364
-
365
-    /**
366
-     * Removes ALL relation instances for this relation obj
367
-     *
368
-     * @param EE_Base_Class|int $this_obj_or_id
369
-     * @param array             $where_query_param @see
370
-     *                                             https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md#0-where-conditions
371
-     * @return EE_Base_Class[]
372
-     * @throws EE_Error
373
-     * @throws ReflectionException
374
-     */
375
-    public function remove_relations($this_obj_or_id, $where_query_param = [])
376
-    {
377
-        $related_things = $this->get_all_related($this_obj_or_id, [$where_query_param]);
378
-        $objs_removed   = [];
379
-        foreach ($related_things as $related_thing) {
380
-            $objs_removed[] = $this->remove_relation_to($this_obj_or_id, $related_thing);
381
-        }
382
-        return $objs_removed;
383
-    }
384
-
385
-
386
-    /**
387
-     * If you aren't allowed to delete this model when there are related models across this
388
-     * relation object, return true. Otherwise, if you can delete this model even though
389
-     * related objects exist, returns false.
390
-     *
391
-     * @return boolean
392
-     */
393
-    public function block_delete_if_related_models_exist()
394
-    {
395
-        return $this->_blocking_delete;
396
-    }
397
-
398
-
399
-    /**
400
-     * Gets the error message to show
401
-     *
402
-     * @return string
403
-     * @throws EE_Error
404
-     * @throws ReflectionException
405
-     */
406
-    public function get_deletion_error_message()
407
-    {
408
-        if ($this->_blocking_delete_error_message) {
409
-            return $this->_blocking_delete_error_message;
410
-        }
411
-        return sprintf(
412
-            esc_html__(
413
-                'This %1$s is currently linked to one or more %2$s records. If this %1$s is incorrect, then please remove it from all %3$s before attempting to delete it.',
414
-                "event_espresso"
415
-            ),
416
-            $this->get_this_model()->item_name(),
417
-            $this->get_other_model()->item_name(),
418
-            $this->get_other_model()->item_name(2)
419
-        );
420
-    }
421
-
422
-
423
-    /**
424
-     * This returns elements used to represent this field in the json schema.
425
-     *
426
-     * @link http://json-schema.org/
427
-     * @return array
428
-     * @throws EE_Error
429
-     * @throws ReflectionException
430
-     */
431
-    public function getSchema()
432
-    {
433
-        $schema = [
434
-            'description'   => $this->getSchemaDescription(),
435
-            'type'          => $this->getSchemaType(),
436
-            'relation'      => true,
437
-            'relation_type' => get_class($this),
438
-            'readonly'      => $this->getSchemaReadonly(),
439
-        ];
440
-
441
-        if ($this instanceof EE_HABTM_Relation) {
442
-            $schema['joining_model_name'] = $this->get_join_model()->get_this_model_name();
443
-        }
444
-
445
-        if ($this->getSchemaType() === 'array') {
446
-            $schema['items'] = [
447
-                'type' => 'object',
448
-            ];
449
-        }
450
-
451
-        return $schema;
452
-    }
453
-
454
-
455
-    /**
456
-     * Returns whatever is set as the nice name for the object.
457
-     *
458
-     * @return string
459
-     * @throws EE_Error
460
-     * @throws ReflectionException
461
-     */
462
-    public function getSchemaDescription()
463
-    {
464
-        $description = $this instanceof EE_Belongs_To_Relation
465
-            ? esc_html__('The related %1$s entity to the %2$s.', 'event_espresso')
466
-            : esc_html__('The related %1$s entities to the %2$s.', 'event_espresso');
467
-        return sprintf(
468
-            $description,
469
-            $this->get_other_model()->get_this_model_name(),
470
-            $this->get_this_model()->get_this_model_name()
471
-        );
472
-    }
473
-
474
-
475
-    /**
476
-     * If a child class has enum values, they should override this method and provide a simple array
477
-     * of the enum values.
478
-     * The reason this is not a property on the class is because there may be filterable enum values that
479
-     * are set on the instantiated object that could be filtered after construct.
480
-     *
481
-     * @return array
482
-     */
483
-    public function getSchemaEnum()
484
-    {
485
-        return [];
486
-    }
487
-
488
-
489
-    /**
490
-     * This returns the value of the $_schema_format property on the object.
491
-     *
492
-     * @return array
493
-     */
494
-    public function getSchemaFormat()
495
-    {
496
-        return [];
497
-    }
498
-
499
-
500
-    /**
501
-     * This is usually present when the $_schema_type property is 'object'.  Any child classes will need to override
502
-     * this method and return the properties for the schema.
503
-     * The reason this is not a property on the class is because there may be filters set on the values for the property
504
-     * that won't be exposed on construct.  For example enum type schemas may have the enum values filtered.
505
-     *
506
-     * @return array
507
-     */
508
-    public function getSchemaProperties()
509
-    {
510
-        return [];
511
-    }
512
-
513
-
514
-    /**
515
-     * This returns the value of the $_schema_readonly property on the object.
516
-     *
517
-     * @return bool
518
-     */
519
-    public function getSchemaReadonly()
520
-    {
521
-        return true;
522
-    }
523
-
524
-
525
-    /**
526
-     * Returns whatever is set as the $_schema_type property for the object.
527
-     * Note: this will automatically add 'null' to the schema if the object is_nullable()
528
-     *
529
-     * @return string|array
530
-     */
531
-    public function getSchemaType()
532
-    {
533
-        return $this instanceof EE_Belongs_To_Relation ? 'object' : 'array';
534
-    }
535
-
536
-
537
-    /**
538
-     * @param        $other_table
539
-     * @param        $other_table_alias
540
-     * @param        $other_table_column
541
-     * @param        $this_table_alias
542
-     * @param        $this_table_join_column
543
-     * @param string $extra_join_sql
544
-     * @return string
545
-     */
546
-    protected function _left_join(
547
-        $other_table,
548
-        $other_table_alias,
549
-        $other_table_column,
550
-        $this_table_alias,
551
-        $this_table_join_column,
552
-        $extra_join_sql = ''
553
-    ) {
554
-        return " LEFT JOIN " .
555
-               $other_table .
556
-               " AS " .
557
-               $other_table_alias .
558
-               " ON " .
559
-               $other_table_alias .
560
-               "." .
561
-               $other_table_column .
562
-               "=" .
563
-               $this_table_alias .
564
-               "." .
565
-               $this_table_join_column .
566
-               ($extra_join_sql ? " AND $extra_join_sql" : '');
567
-    }
20
+	/**
21
+	 * @var bool
22
+	 */
23
+	protected $_blocking_delete = false;
24
+
25
+	/**
26
+	 * If you try to delete "this_model", and there are related "other_models",
27
+	 * and this isn't null, then abandon the deletion and add this warning.
28
+	 * This effectively makes it impossible to delete "this_model" while there are
29
+	 * related "other_models" along this relation.
30
+	 *
31
+	 * @var string (internationalized)
32
+	 */
33
+	protected $_blocking_delete_error_message;
34
+
35
+	/**
36
+	 * The model name pointed to by this relation (ie, the model we want to establish a relationship to)
37
+	 *
38
+	 * @var string eg Event, Question_Group, Registration
39
+	 */
40
+	private $_other_model_name;
41
+
42
+	/**
43
+	 * The model name of which this relation is a component (ie, the model that called new EE_Model_Relation_Base)
44
+	 *
45
+	 * @var string eg Event, Question_Group, Registration
46
+	 */
47
+	private $_this_model_name;
48
+
49
+	/**
50
+	 * this is typically used when calling the relation models to make sure they inherit any set timezone from the
51
+	 * initiating model.
52
+	 *
53
+	 * @var string
54
+	 */
55
+	protected $_timezone;
56
+
57
+
58
+	/**
59
+	 * Object representing the relationship between two models. This knows how to join the models,
60
+	 * get related models across the relation, and add-and-remove the relationships.
61
+	 *
62
+	 * @param boolean $block_deletes                 if there are related models across this relation, block (prevent
63
+	 *                                               and add an error) the deletion of this model
64
+	 * @param string  $blocking_delete_error_message a customized error message on blocking deletes instead of the
65
+	 *                                               default
66
+	 */
67
+	public function __construct($block_deletes, $blocking_delete_error_message)
68
+	{
69
+		$this->_blocking_delete               = $block_deletes;
70
+		$this->_blocking_delete_error_message = $blocking_delete_error_message;
71
+	}
72
+
73
+
74
+	/**
75
+	 * @param $this_model_name
76
+	 * @param $other_model_name
77
+	 * @throws EE_Error
78
+	 */
79
+	public function _construct_finalize_set_models($this_model_name, $other_model_name)
80
+	{
81
+		$this->_this_model_name  = $this_model_name;
82
+		$this->_other_model_name = $other_model_name;
83
+		if (is_string($this->_blocking_delete)) {
84
+			throw new EE_Error(
85
+				sprintf(
86
+					esc_html__(
87
+						"When instantiating the relation of type %s from %s to %s, the \$block_deletes argument should be a boolean, not a string (%s)",
88
+						"event_espresso"
89
+					),
90
+					get_class($this),
91
+					$this_model_name,
92
+					$other_model_name,
93
+					$this->_blocking_delete
94
+				)
95
+			);
96
+		}
97
+	}
98
+
99
+
100
+	/**
101
+	 * entirely possible that relations may be called from a model and we need to make sure those relations have their
102
+	 * timezone set correctly.
103
+	 *
104
+	 * @param string $timezone timezone to set.
105
+	 */
106
+	public function set_timezone($timezone)
107
+	{
108
+		if (! empty($timezone)) {
109
+			$this->_timezone = $timezone;
110
+		}
111
+	}
112
+
113
+
114
+	/**
115
+	 * Deletes the related model objects which meet the query parameters. If no
116
+	 * parameters are specified, then all related model objects will be deleted.
117
+	 * Note: If the related model is extends EEM_Soft_Delete_Base, then the related
118
+	 * model objects will only be soft-deleted.
119
+	 *
120
+	 * @param EE_Base_Class|int|string $model_object_or_id
121
+	 * @param array                    $query_params
122
+	 * @return int of how many related models got deleted
123
+	 * @throws EE_Error
124
+	 * @throws ReflectionException
125
+	 */
126
+	public function delete_all_related($model_object_or_id, $query_params = [])
127
+	{
128
+		// for each thing we would delete,
129
+		$related_model_objects = $this->get_all_related($model_object_or_id, $query_params);
130
+		// determine if it's blocked by anything else before it can be deleted
131
+		$deleted_count = 0;
132
+		foreach ($related_model_objects as $related_model_object) {
133
+			$delete_is_blocked = $this->get_other_model()->delete_is_blocked_by_related_models(
134
+				$related_model_object,
135
+				$model_object_or_id
136
+			);
137
+			/* @var $model_object_or_id EE_Base_Class */
138
+			if (! $delete_is_blocked) {
139
+				$this->remove_relation_to($model_object_or_id, $related_model_object);
140
+				$related_model_object->delete();
141
+				$deleted_count++;
142
+			}
143
+		}
144
+		return $deleted_count;
145
+	}
146
+
147
+
148
+	/**
149
+	 * Gets all the model objects of type of other model related to $model_object,
150
+	 * according to this relation. This is the same code for EE_HABTM_Relation and EE_Has_Many_Relation.
151
+	 * For both of those child classes, $model_object must be saved so that it has an ID before querying,
152
+	 * otherwise an error will be thrown. Note: by default we disable default_where_conditions
153
+	 * EE_Belongs_To_Relation doesn't need to be saved before querying.
154
+	 *
155
+	 * @param EE_Base_Class|int $model_object_or_id                      or the primary key of this model
156
+	 * @param array             $query_params                            @see
157
+	 *                                                                   https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md
158
+	 * @param boolean           $values_already_prepared_by_model_object @deprecated since 4.8.1
159
+	 * @return EE_Base_Class[]
160
+	 * @throws EE_Error
161
+	 * @throws ReflectionException
162
+	 */
163
+	public function get_all_related(
164
+		$model_object_or_id,
165
+		$query_params = [],
166
+		$values_already_prepared_by_model_object = false
167
+	) {
168
+		if ($values_already_prepared_by_model_object !== false) {
169
+			EE_Error::doing_it_wrong(
170
+				'EE_Model_Relation_Base::get_all_related',
171
+				esc_html__('The argument $values_already_prepared_by_model_object is no longer used.', 'event_espresso'),
172
+				'4.8.1'
173
+			);
174
+		}
175
+		$query_params                                        =
176
+			$this->_disable_default_where_conditions_on_query_param($query_params);
177
+		$query_param_where_this_model_pk                     = $this->get_this_model()->get_this_model_name()
178
+															   .
179
+															   "."
180
+															   .
181
+															   $this->get_this_model()
182
+																	->get_primary_key_field()
183
+																	->get_name();
184
+		$model_object_id                                     = $this->_get_model_object_id($model_object_or_id);
185
+		$query_params[0][ $query_param_where_this_model_pk ] = $model_object_id;
186
+		return $this->get_other_model()->get_all($query_params);
187
+	}
188
+
189
+
190
+	/**
191
+	 * Gets the model which this relation establishes the relation TO (ie,
192
+	 * this relation object was defined on get_this_model(), get_other_model() is the other one)
193
+	 *
194
+	 * @return EEM_Base
195
+	 * @throws EE_Error
196
+	 * @throws ReflectionException
197
+	 */
198
+	public function get_other_model()
199
+	{
200
+		return $this->_get_model($this->_other_model_name);
201
+	}
202
+
203
+
204
+	/**
205
+	 * Similar to 'add_relation_to(...)', performs the opposite action of removing the relationship between the two
206
+	 * model objects
207
+	 *
208
+	 * @param       $this_obj_or_id
209
+	 * @param       $other_obj_or_id
210
+	 * @param array $where_query
211
+	 * @return bool
212
+	 */
213
+	abstract public function remove_relation_to($this_obj_or_id, $other_obj_or_id, $where_query = []);
214
+
215
+
216
+	/**
217
+	 * Alters the $query_params to disable default where conditions, unless otherwise specified
218
+	 *
219
+	 * @param array $query_params
220
+	 * @return array
221
+	 */
222
+	protected function _disable_default_where_conditions_on_query_param($query_params)
223
+	{
224
+		if (! isset($query_params['default_where_conditions'])) {
225
+			$query_params['default_where_conditions'] = 'none';
226
+		}
227
+		return $query_params;
228
+	}
229
+
230
+
231
+	/**
232
+	 * Gets the model where this relation is defined.
233
+	 *
234
+	 * @return EEM_Base
235
+	 * @throws EE_Error
236
+	 * @throws ReflectionException
237
+	 */
238
+	public function get_this_model()
239
+	{
240
+		return $this->_get_model($this->_this_model_name);
241
+	}
242
+
243
+
244
+	/**
245
+	 * this just returns a model_object_id for incoming item that could be an object or id.
246
+	 *
247
+	 * @param EE_Base_Class|int $model_object_or_id model object or the primary key of this model
248
+	 * @return int
249
+	 * @throws EE_Error
250
+	 * @throws ReflectionException
251
+	 */
252
+	protected function _get_model_object_id($model_object_or_id)
253
+	{
254
+		$model_object_id = $model_object_or_id;
255
+		if ($model_object_or_id instanceof EE_Base_Class) {
256
+			$model_object_id = $model_object_or_id->ID();
257
+		}
258
+		if (! $model_object_id) {
259
+			throw new EE_Error(
260
+				sprintf(
261
+					esc_html__(
262
+						"Sorry, we cant get the related %s model objects to %s model object before it has an ID. You can solve that by just saving it before trying to get its related model objects",
263
+						"event_espresso"
264
+					),
265
+					$this->get_other_model()->get_this_model_name(),
266
+					$this->get_this_model()->get_this_model_name()
267
+				)
268
+			);
269
+		}
270
+		return $model_object_id;
271
+	}
272
+
273
+
274
+	/**
275
+	 * Internally used by get_this_model() and get_other_model()
276
+	 *
277
+	 * @param string $model_name like Event, Question_Group, etc. omit the EEM_
278
+	 * @return EEM_Base
279
+	 * @throws EE_Error
280
+	 * @throws ReflectionException
281
+	 */
282
+	protected function _get_model($model_name)
283
+	{
284
+		$modelInstance = EE_Registry::instance()->load_model($model_name);
285
+		$modelInstance->set_timezone($this->_timezone);
286
+		return $modelInstance;
287
+	}
288
+
289
+
290
+	/**
291
+	 * Deletes the related model objects which meet the query parameters. If no
292
+	 * parameters are specified, then all related model objects will be deleted.
293
+	 * Note: If the related model is extends EEM_Soft_Delete_Base, then the related
294
+	 * model objects will only be soft-deleted.
295
+	 *
296
+	 * @param EE_Base_Class|int|string $model_object_or_id
297
+	 * @param array                    $query_params
298
+	 * @return int of how many related models got deleted
299
+	 * @throws EE_Error
300
+	 * @throws ReflectionException
301
+	 */
302
+	public function delete_related_permanently($model_object_or_id, $query_params = [])
303
+	{
304
+		// for each thing we would delete,
305
+		$related_model_objects = $this->get_all_related($model_object_or_id, $query_params);
306
+		// determine if it's blocked by anything else before it can be deleted
307
+		$deleted_count = 0;
308
+		foreach ($related_model_objects as $related_model_object) {
309
+			$delete_is_blocked = $this->get_other_model()->delete_is_blocked_by_related_models(
310
+				$related_model_object,
311
+				$model_object_or_id
312
+			);
313
+			/* @var $model_object_or_id EE_Base_Class */
314
+			if ($related_model_object instanceof EE_Soft_Delete_Base_Class) {
315
+				$this->remove_relation_to($model_object_or_id, $related_model_object);
316
+				$deleted_count++;
317
+				if (! $delete_is_blocked) {
318
+					$related_model_object->delete_permanently();
319
+				} else {
320
+					// delete is blocked
321
+					// brent and darren, in this case, wanted to just soft delete it then
322
+					$related_model_object->delete();
323
+				}
324
+			} else {
325
+				// its not a soft-deletable thing anyways. do the normal logic.
326
+				if (! $delete_is_blocked) {
327
+					$this->remove_relation_to($model_object_or_id, $related_model_object);
328
+					$related_model_object->delete();
329
+					$deleted_count++;
330
+				}
331
+			}
332
+		}
333
+		return $deleted_count;
334
+	}
335
+
336
+
337
+	/**
338
+	 * Gets the SQL string for performing the join between this model and the other model.
339
+	 *
340
+	 * @param string $model_relation_chain like 'Event.Event_Venue.Venue'
341
+	 * @return string of SQL, eg "LEFT JOIN table_name AS table_alias ON this_model_primary_table.pk =
342
+	 *                                     other_model_primary_table.fk" etc
343
+	 */
344
+	abstract public function get_join_statement($model_relation_chain);
345
+
346
+
347
+	/**
348
+	 * Adds a relationships between the two model objects provided. Each type of relationship handles this differently
349
+	 * (EE_Belongs_To is a slight exception, it should more accurately be called set_relation_to(...), as this
350
+	 * relationship only allows this model to be related to a single other model of this type)
351
+	 *
352
+	 * @param       $this_obj_or_id
353
+	 * @param       $other_obj_or_id
354
+	 * @param array $extra_join_model_fields_n_values
355
+	 * @return EE_Base_Class the EE_Base_Class which was added as a relation. (Convenient if you only pass an ID for
356
+	 *                        $other_obj_or_id)
357
+	 */
358
+	abstract public function add_relation_to(
359
+		$this_obj_or_id,
360
+		$other_obj_or_id,
361
+		$extra_join_model_fields_n_values = []
362
+	);
363
+
364
+
365
+	/**
366
+	 * Removes ALL relation instances for this relation obj
367
+	 *
368
+	 * @param EE_Base_Class|int $this_obj_or_id
369
+	 * @param array             $where_query_param @see
370
+	 *                                             https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md#0-where-conditions
371
+	 * @return EE_Base_Class[]
372
+	 * @throws EE_Error
373
+	 * @throws ReflectionException
374
+	 */
375
+	public function remove_relations($this_obj_or_id, $where_query_param = [])
376
+	{
377
+		$related_things = $this->get_all_related($this_obj_or_id, [$where_query_param]);
378
+		$objs_removed   = [];
379
+		foreach ($related_things as $related_thing) {
380
+			$objs_removed[] = $this->remove_relation_to($this_obj_or_id, $related_thing);
381
+		}
382
+		return $objs_removed;
383
+	}
384
+
385
+
386
+	/**
387
+	 * If you aren't allowed to delete this model when there are related models across this
388
+	 * relation object, return true. Otherwise, if you can delete this model even though
389
+	 * related objects exist, returns false.
390
+	 *
391
+	 * @return boolean
392
+	 */
393
+	public function block_delete_if_related_models_exist()
394
+	{
395
+		return $this->_blocking_delete;
396
+	}
397
+
398
+
399
+	/**
400
+	 * Gets the error message to show
401
+	 *
402
+	 * @return string
403
+	 * @throws EE_Error
404
+	 * @throws ReflectionException
405
+	 */
406
+	public function get_deletion_error_message()
407
+	{
408
+		if ($this->_blocking_delete_error_message) {
409
+			return $this->_blocking_delete_error_message;
410
+		}
411
+		return sprintf(
412
+			esc_html__(
413
+				'This %1$s is currently linked to one or more %2$s records. If this %1$s is incorrect, then please remove it from all %3$s before attempting to delete it.',
414
+				"event_espresso"
415
+			),
416
+			$this->get_this_model()->item_name(),
417
+			$this->get_other_model()->item_name(),
418
+			$this->get_other_model()->item_name(2)
419
+		);
420
+	}
421
+
422
+
423
+	/**
424
+	 * This returns elements used to represent this field in the json schema.
425
+	 *
426
+	 * @link http://json-schema.org/
427
+	 * @return array
428
+	 * @throws EE_Error
429
+	 * @throws ReflectionException
430
+	 */
431
+	public function getSchema()
432
+	{
433
+		$schema = [
434
+			'description'   => $this->getSchemaDescription(),
435
+			'type'          => $this->getSchemaType(),
436
+			'relation'      => true,
437
+			'relation_type' => get_class($this),
438
+			'readonly'      => $this->getSchemaReadonly(),
439
+		];
440
+
441
+		if ($this instanceof EE_HABTM_Relation) {
442
+			$schema['joining_model_name'] = $this->get_join_model()->get_this_model_name();
443
+		}
444
+
445
+		if ($this->getSchemaType() === 'array') {
446
+			$schema['items'] = [
447
+				'type' => 'object',
448
+			];
449
+		}
450
+
451
+		return $schema;
452
+	}
453
+
454
+
455
+	/**
456
+	 * Returns whatever is set as the nice name for the object.
457
+	 *
458
+	 * @return string
459
+	 * @throws EE_Error
460
+	 * @throws ReflectionException
461
+	 */
462
+	public function getSchemaDescription()
463
+	{
464
+		$description = $this instanceof EE_Belongs_To_Relation
465
+			? esc_html__('The related %1$s entity to the %2$s.', 'event_espresso')
466
+			: esc_html__('The related %1$s entities to the %2$s.', 'event_espresso');
467
+		return sprintf(
468
+			$description,
469
+			$this->get_other_model()->get_this_model_name(),
470
+			$this->get_this_model()->get_this_model_name()
471
+		);
472
+	}
473
+
474
+
475
+	/**
476
+	 * If a child class has enum values, they should override this method and provide a simple array
477
+	 * of the enum values.
478
+	 * The reason this is not a property on the class is because there may be filterable enum values that
479
+	 * are set on the instantiated object that could be filtered after construct.
480
+	 *
481
+	 * @return array
482
+	 */
483
+	public function getSchemaEnum()
484
+	{
485
+		return [];
486
+	}
487
+
488
+
489
+	/**
490
+	 * This returns the value of the $_schema_format property on the object.
491
+	 *
492
+	 * @return array
493
+	 */
494
+	public function getSchemaFormat()
495
+	{
496
+		return [];
497
+	}
498
+
499
+
500
+	/**
501
+	 * This is usually present when the $_schema_type property is 'object'.  Any child classes will need to override
502
+	 * this method and return the properties for the schema.
503
+	 * The reason this is not a property on the class is because there may be filters set on the values for the property
504
+	 * that won't be exposed on construct.  For example enum type schemas may have the enum values filtered.
505
+	 *
506
+	 * @return array
507
+	 */
508
+	public function getSchemaProperties()
509
+	{
510
+		return [];
511
+	}
512
+
513
+
514
+	/**
515
+	 * This returns the value of the $_schema_readonly property on the object.
516
+	 *
517
+	 * @return bool
518
+	 */
519
+	public function getSchemaReadonly()
520
+	{
521
+		return true;
522
+	}
523
+
524
+
525
+	/**
526
+	 * Returns whatever is set as the $_schema_type property for the object.
527
+	 * Note: this will automatically add 'null' to the schema if the object is_nullable()
528
+	 *
529
+	 * @return string|array
530
+	 */
531
+	public function getSchemaType()
532
+	{
533
+		return $this instanceof EE_Belongs_To_Relation ? 'object' : 'array';
534
+	}
535
+
536
+
537
+	/**
538
+	 * @param        $other_table
539
+	 * @param        $other_table_alias
540
+	 * @param        $other_table_column
541
+	 * @param        $this_table_alias
542
+	 * @param        $this_table_join_column
543
+	 * @param string $extra_join_sql
544
+	 * @return string
545
+	 */
546
+	protected function _left_join(
547
+		$other_table,
548
+		$other_table_alias,
549
+		$other_table_column,
550
+		$this_table_alias,
551
+		$this_table_join_column,
552
+		$extra_join_sql = ''
553
+	) {
554
+		return " LEFT JOIN " .
555
+			   $other_table .
556
+			   " AS " .
557
+			   $other_table_alias .
558
+			   " ON " .
559
+			   $other_table_alias .
560
+			   "." .
561
+			   $other_table_column .
562
+			   "=" .
563
+			   $this_table_alias .
564
+			   "." .
565
+			   $this_table_join_column .
566
+			   ($extra_join_sql ? " AND $extra_join_sql" : '');
567
+	}
568 568
 }
Please login to merge, or discard this patch.
Spacing   +19 added lines, -19 removed lines patch added patch discarded remove patch
@@ -105,7 +105,7 @@  discard block
 block discarded – undo
105 105
      */
106 106
     public function set_timezone($timezone)
107 107
     {
108
-        if (! empty($timezone)) {
108
+        if ( ! empty($timezone)) {
109 109
             $this->_timezone = $timezone;
110 110
         }
111 111
     }
@@ -135,7 +135,7 @@  discard block
 block discarded – undo
135 135
                 $model_object_or_id
136 136
             );
137 137
             /* @var $model_object_or_id EE_Base_Class */
138
-            if (! $delete_is_blocked) {
138
+            if ( ! $delete_is_blocked) {
139 139
                 $this->remove_relation_to($model_object_or_id, $related_model_object);
140 140
                 $related_model_object->delete();
141 141
                 $deleted_count++;
@@ -182,7 +182,7 @@  discard block
 block discarded – undo
182 182
                                                                     ->get_primary_key_field()
183 183
                                                                     ->get_name();
184 184
         $model_object_id                                     = $this->_get_model_object_id($model_object_or_id);
185
-        $query_params[0][ $query_param_where_this_model_pk ] = $model_object_id;
185
+        $query_params[0][$query_param_where_this_model_pk] = $model_object_id;
186 186
         return $this->get_other_model()->get_all($query_params);
187 187
     }
188 188
 
@@ -221,7 +221,7 @@  discard block
 block discarded – undo
221 221
      */
222 222
     protected function _disable_default_where_conditions_on_query_param($query_params)
223 223
     {
224
-        if (! isset($query_params['default_where_conditions'])) {
224
+        if ( ! isset($query_params['default_where_conditions'])) {
225 225
             $query_params['default_where_conditions'] = 'none';
226 226
         }
227 227
         return $query_params;
@@ -255,7 +255,7 @@  discard block
 block discarded – undo
255 255
         if ($model_object_or_id instanceof EE_Base_Class) {
256 256
             $model_object_id = $model_object_or_id->ID();
257 257
         }
258
-        if (! $model_object_id) {
258
+        if ( ! $model_object_id) {
259 259
             throw new EE_Error(
260 260
                 sprintf(
261 261
                     esc_html__(
@@ -314,7 +314,7 @@  discard block
 block discarded – undo
314 314
             if ($related_model_object instanceof EE_Soft_Delete_Base_Class) {
315 315
                 $this->remove_relation_to($model_object_or_id, $related_model_object);
316 316
                 $deleted_count++;
317
-                if (! $delete_is_blocked) {
317
+                if ( ! $delete_is_blocked) {
318 318
                     $related_model_object->delete_permanently();
319 319
                 } else {
320 320
                     // delete is blocked
@@ -323,7 +323,7 @@  discard block
 block discarded – undo
323 323
                 }
324 324
             } else {
325 325
                 // its not a soft-deletable thing anyways. do the normal logic.
326
-                if (! $delete_is_blocked) {
326
+                if ( ! $delete_is_blocked) {
327 327
                     $this->remove_relation_to($model_object_or_id, $related_model_object);
328 328
                     $related_model_object->delete();
329 329
                     $deleted_count++;
@@ -551,18 +551,18 @@  discard block
 block discarded – undo
551 551
         $this_table_join_column,
552 552
         $extra_join_sql = ''
553 553
     ) {
554
-        return " LEFT JOIN " .
555
-               $other_table .
556
-               " AS " .
557
-               $other_table_alias .
558
-               " ON " .
559
-               $other_table_alias .
560
-               "." .
561
-               $other_table_column .
562
-               "=" .
563
-               $this_table_alias .
564
-               "." .
565
-               $this_table_join_column .
554
+        return " LEFT JOIN ".
555
+               $other_table.
556
+               " AS ".
557
+               $other_table_alias.
558
+               " ON ".
559
+               $other_table_alias.
560
+               ".".
561
+               $other_table_column.
562
+               "=".
563
+               $this_table_alias.
564
+               ".".
565
+               $this_table_join_column.
566 566
                ($extra_join_sql ? " AND $extra_join_sql" : '');
567 567
     }
568 568
 }
Please login to merge, or discard this patch.