Completed
Branch BUG/invalid-field-count (f53e3a)
by
unknown
08:39 queued 41s
created
core/db_models/EEM_CPT_Base.model.php 1 patch
Indentation   +557 added lines, -557 removed lines patch added patch discarded remove patch
@@ -16,561 +16,561 @@
 block discarded – undo
16 16
 abstract class EEM_CPT_Base extends EEM_Soft_Delete_Base
17 17
 {
18 18
 
19
-    const EVENT_CATEGORY_TAXONOMY = 'espresso_event_categories';
20
-
21
-    /**
22
-     * @var string post_status_publish - the wp post status for published cpts
23
-     */
24
-    const post_status_publish = 'publish';
25
-
26
-    /**
27
-     * @var string post_status_future - the wp post status for scheduled cpts
28
-     */
29
-    const post_status_future = 'future';
30
-
31
-    /**
32
-     * @var string post_status_draft - the wp post status for draft cpts
33
-     */
34
-    const post_status_draft = 'draft';
35
-
36
-    /**
37
-     * @var string post_status_pending - the wp post status for pending cpts
38
-     */
39
-    const post_status_pending = 'pending';
40
-
41
-    /**
42
-     * @var string post_status_private - the wp post status for private cpts
43
-     */
44
-    const post_status_private = 'private';
45
-
46
-    /**
47
-     * @var string post_status_trashed - the wp post status for trashed cpts
48
-     */
49
-    const post_status_trashed = 'trash';
50
-
51
-    /**
52
-     * This is an array of custom statuses for the given CPT model (modified by children)
53
-     * format:
54
-     * array(
55
-     *        'status_name' => array(
56
-     *            'label' => __('Status Name', 'event_espresso'),
57
-     *            'public' => TRUE //whether a public status or not.
58
-     *        )
59
-     * )
60
-     *
61
-     * @var array
62
-     */
63
-    protected $_custom_stati = array();
64
-
65
-
66
-    /**
67
-     * Adds a relationship to Term_Taxonomy for each CPT_Base
68
-     *
69
-     * @param string $timezone
70
-     * @throws \EE_Error
71
-     */
72
-    protected function __construct($timezone = null)
73
-    {
74
-        // adds a relationship to Term_Taxonomy for all these models. For this to work
75
-        // Term_Relationship must have a relation to each model subclassing EE_CPT_Base explicitly
76
-        // eg, in EEM_Term_Relationship, inside the _model_relations array, there must be an entry
77
-        // with key equalling the subclassing model's model name (eg 'Event' or 'Venue'), and the value
78
-        // must also be new EE_HABTM_Relation('Term_Relationship');
79
-        $this->_model_relations['Term_Taxonomy'] = new EE_HABTM_Relation('Term_Relationship');
80
-        $primary_table_name = null;
81
-        // add  the common _status field to all CPT primary tables.
82
-        foreach ($this->_tables as $alias => $table_obj) {
83
-            if ($table_obj instanceof EE_Primary_Table) {
84
-                $primary_table_name = $alias;
85
-            }
86
-        }
87
-        // set default wp post statuses if child has not already set.
88
-        if (! isset($this->_fields[ $primary_table_name ]['status'])) {
89
-            $this->_fields[ $primary_table_name ]['status'] = new EE_WP_Post_Status_Field(
90
-                'post_status',
91
-                __("Event Status", "event_espresso"),
92
-                false,
93
-                'draft'
94
-            );
95
-        }
96
-        if (! isset($this->_fields[ $primary_table_name ]['to_ping'])) {
97
-            $this->_fields[ $primary_table_name ]['to_ping'] = new EE_DB_Only_Text_Field(
98
-                'to_ping',
99
-                __('To Ping', 'event_espresso'),
100
-                false,
101
-                ''
102
-            );
103
-        }
104
-        if (! isset($this->_fields[ $primary_table_name ]['pinged'])) {
105
-            $this->_fields[ $primary_table_name ]['pinged'] = new EE_DB_Only_Text_Field(
106
-                'pinged',
107
-                __('Pinged', 'event_espresso'),
108
-                false,
109
-                ''
110
-            );
111
-        }
112
-        if (! isset($this->_fields[ $primary_table_name ]['comment_status'])) {
113
-            $this->_fields[ $primary_table_name ]['comment_status'] = new EE_Plain_Text_Field(
114
-                'comment_status',
115
-                __('Comment Status', 'event_espresso'),
116
-                false,
117
-                'open'
118
-            );
119
-        }
120
-        if (! isset($this->_fields[ $primary_table_name ]['ping_status'])) {
121
-            $this->_fields[ $primary_table_name ]['ping_status'] = new EE_Plain_Text_Field(
122
-                'ping_status',
123
-                __('Ping Status', 'event_espresso'),
124
-                false,
125
-                'open'
126
-            );
127
-        }
128
-        if (! isset($this->_fields[ $primary_table_name ]['post_content_filtered'])) {
129
-            $this->_fields[ $primary_table_name ]['post_content_filtered'] = new EE_DB_Only_Text_Field(
130
-                'post_content_filtered',
131
-                __('Post Content Filtered', 'event_espresso'),
132
-                false,
133
-                ''
134
-            );
135
-        }
136
-        if (! isset($this->_model_relations['Post_Meta'])) {
137
-            // don't block deletes though because we want to maintain the current behaviour
138
-            $this->_model_relations['Post_Meta'] = new EE_Has_Many_Relation(false);
139
-        }
140
-        if (! $this->_minimum_where_conditions_strategy instanceof EE_Default_Where_Conditions) {
141
-            // nothing was set during child constructor, so set default
142
-            $this->_minimum_where_conditions_strategy = new EE_CPT_Minimum_Where_Conditions($this->post_type());
143
-        }
144
-        if (! $this->_default_where_conditions_strategy instanceof EE_Default_Where_Conditions) {
145
-            // nothing was set during child constructor, so set default
146
-            // it's ok for child classes to specify this, but generally this is more DRY
147
-            $this->_default_where_conditions_strategy = new EE_CPT_Where_Conditions($this->post_type());
148
-        }
149
-        parent::__construct($timezone);
150
-    }
151
-
152
-
153
-    /**
154
-     * @return array
155
-     */
156
-    public function public_event_stati()
157
-    {
158
-        // @see wp-includes/post.php
159
-        return get_post_stati(array('public' => true));
160
-    }
161
-
162
-
163
-    /**
164
-     * Searches for field on this model of type 'deleted_flag'. if it is found,
165
-     * returns it's name. BUT That doesn't apply to CPTs. We should instead use post_status_field_name
166
-     *
167
-     * @return string
168
-     * @throws EE_Error
169
-     */
170
-    public function deleted_field_name()
171
-    {
172
-        throw new EE_Error(
173
-            sprintf(
174
-                __(
175
-                    "EEM_CPT_Base should nto call deleted_field_name! It should instead use post_status_field_name",
176
-                    "event_espresso"
177
-                )
178
-            )
179
-        );
180
-    }
181
-
182
-
183
-    /**
184
-     * Gets the field's name that sets the post status
185
-     *
186
-     * @return string
187
-     * @throws EE_Error
188
-     */
189
-    public function post_status_field_name()
190
-    {
191
-        $field = $this->get_a_field_of_type('EE_WP_Post_Status_Field');
192
-        if ($field) {
193
-            return $field->get_name();
194
-        } else {
195
-            throw new EE_Error(
196
-                sprintf(
197
-                    __(
198
-                        'We are trying to find the post status flag field on %s, but none was found. Are you sure there is a field of type EE_Trashed_Flag_Field in %s constructor?',
199
-                        'event_espresso'
200
-                    ),
201
-                    get_class($this),
202
-                    get_class($this)
203
-                )
204
-            );
205
-        }
206
-    }
207
-
208
-
209
-    /**
210
-     * Alters the query params so that only trashed/soft-deleted items are considered
211
-     *
212
-     * @param array $query_params like EEM_Base::get_all's $query_params
213
-     * @return array like EEM_Base::get_all's $query_params
214
-     */
215
-    protected function _alter_query_params_so_only_trashed_items_included($query_params)
216
-    {
217
-        $post_status_field_name = $this->post_status_field_name();
218
-        $query_params[0][ $post_status_field_name ] = self::post_status_trashed;
219
-        return $query_params;
220
-    }
221
-
222
-
223
-    /**
224
-     * Alters the query params so each item's deleted status is ignored.
225
-     *
226
-     * @param array $query_params
227
-     * @return array
228
-     */
229
-    protected function _alter_query_params_so_deleted_and_undeleted_items_included($query_params)
230
-    {
231
-        $query_params['default_where_conditions'] = 'minimum';
232
-        return $query_params;
233
-    }
234
-
235
-
236
-    /**
237
-     * Performs deletes or restores on items. Both soft-deleted and non-soft-deleted items considered.
238
-     *
239
-     * @param boolean $delete       true to indicate deletion, false to indicate restoration
240
-     * @param array   $query_params like EEM_Base::get_all
241
-     * @return boolean success
242
-     */
243
-    public function delete_or_restore($delete = true, $query_params = array())
244
-    {
245
-        $post_status_field_name = $this->post_status_field_name();
246
-        $query_params = $this->_alter_query_params_so_deleted_and_undeleted_items_included($query_params);
247
-        $new_status = $delete ? self::post_status_trashed : 'draft';
248
-        if ($this->update(array($post_status_field_name => $new_status), $query_params)) {
249
-            return true;
250
-        } else {
251
-            return false;
252
-        }
253
-    }
254
-
255
-
256
-    /**
257
-     * meta_table
258
-     * returns first EE_Secondary_Table table name
259
-     *
260
-     * @access public
261
-     * @return string
262
-     */
263
-    public function meta_table()
264
-    {
265
-        $meta_table = $this->_get_other_tables();
266
-        $meta_table = reset($meta_table);
267
-        return $meta_table instanceof EE_Secondary_Table ? $meta_table->get_table_name() : null;
268
-    }
269
-
270
-
271
-    /**
272
-     * This simply returns an array of the meta table fields (useful for when we just need to update those fields)
273
-     *
274
-     * @param  bool $all triggers whether we include DB_Only fields or JUST non DB_Only fields.  Defaults to false (no
275
-     *                   db only fields)
276
-     * @return array
277
-     */
278
-    public function get_meta_table_fields($all = false)
279
-    {
280
-        $all_fields = $fields_to_return = array();
281
-        foreach ($this->_tables as $alias => $table_obj) {
282
-            if ($table_obj instanceof EE_Secondary_Table) {
283
-                $all_fields = array_merge($this->_get_fields_for_table($alias), $all_fields);
284
-            }
285
-        }
286
-        if (! $all) {
287
-            foreach ($all_fields as $name => $obj) {
288
-                if ($obj instanceof EE_DB_Only_Field_Base) {
289
-                    continue;
290
-                }
291
-                $fields_to_return[] = $name;
292
-            }
293
-        } else {
294
-            $fields_to_return = array_keys($all_fields);
295
-        }
296
-        return $fields_to_return;
297
-    }
298
-
299
-
300
-    /**
301
-     * Adds an event category with the specified name and description to the specified
302
-     * $cpt_model_object. Intelligently adds a term if necessary, and adds a term_taxonomy if necessary,
303
-     * and adds an entry in the term_relationship if necessary.
304
-     *
305
-     * @param EE_CPT_Base $cpt_model_object
306
-     * @param string      $category_name (used to derive the term slug too)
307
-     * @param string      $category_description
308
-     * @param int         $parent_term_taxonomy_id
309
-     * @return EE_Term_Taxonomy
310
-     */
311
-    public function add_event_category(
312
-        EE_CPT_Base $cpt_model_object,
313
-        $category_name,
314
-        $category_description = '',
315
-        $parent_term_taxonomy_id = null
316
-    ) {
317
-        // create term
318
-        require_once(EE_MODELS . 'EEM_Term.model.php');
319
-        // first, check for a term by the same name or slug
320
-        $category_slug = sanitize_title($category_name);
321
-        $term = EEM_Term::instance()->get_one(
322
-            array(
323
-                array(
324
-                    'OR' => array(
325
-                        'name' => $category_name,
326
-                        'slug' => $category_slug,
327
-                    ),
328
-                ),
329
-            )
330
-        );
331
-        if (! $term) {
332
-            $term = EE_Term::new_instance(
333
-                array(
334
-                    'name' => $category_name,
335
-                    'slug' => $category_slug,
336
-                )
337
-            );
338
-            $term->save();
339
-        }
340
-        // make sure there's a term-taxonomy entry too
341
-        require_once(EE_MODELS . 'EEM_Term_Taxonomy.model.php');
342
-        $term_taxonomy = EEM_Term_Taxonomy::instance()->get_one(
343
-            array(
344
-                array(
345
-                    'term_id'  => $term->ID(),
346
-                    'taxonomy' => self::EVENT_CATEGORY_TAXONOMY,
347
-                ),
348
-            )
349
-        );
350
-        /** @var $term_taxonomy EE_Term_Taxonomy */
351
-        if (! $term_taxonomy) {
352
-            $term_taxonomy = EE_Term_Taxonomy::new_instance(
353
-                array(
354
-                    'term_id'     => $term->ID(),
355
-                    'taxonomy'    => self::EVENT_CATEGORY_TAXONOMY,
356
-                    'description' => $category_description,
357
-                    'term_count'       => 1,
358
-                    'parent'      => $parent_term_taxonomy_id,
359
-                )
360
-            );
361
-            $term_taxonomy->save();
362
-        } else {
363
-            $term_taxonomy->set_count($term_taxonomy->count() + 1);
364
-            $term_taxonomy->save();
365
-        }
366
-        return $this->add_relationship_to($cpt_model_object, $term_taxonomy, 'Term_Taxonomy');
367
-    }
368
-
369
-
370
-    /**
371
-     * Removed the category specified by name as having a relation to this event.
372
-     * Does not remove the term or term_taxonomy.
373
-     *
374
-     * @param EE_CPT_Base $cpt_model_object_event
375
-     * @param string      $category_name name of the event category (term)
376
-     * @return bool
377
-     */
378
-    public function remove_event_category(EE_CPT_Base $cpt_model_object_event, $category_name)
379
-    {
380
-        // find the term_taxonomy by that name
381
-        $term_taxonomy = $this->get_first_related(
382
-            $cpt_model_object_event,
383
-            'Term_Taxonomy',
384
-            array(array('Term.name' => $category_name, 'taxonomy' => self::EVENT_CATEGORY_TAXONOMY))
385
-        );
386
-        /** @var $term_taxonomy EE_Term_Taxonomy */
387
-        if ($term_taxonomy) {
388
-            $term_taxonomy->set_count($term_taxonomy->count() - 1);
389
-            $term_taxonomy->save();
390
-        }
391
-        return $this->remove_relationship_to($cpt_model_object_event, $term_taxonomy, 'Term_Taxonomy');
392
-    }
393
-
394
-
395
-    /**
396
-     * This is a wrapper for the WordPress get_the_post_thumbnail() function that returns the feature image for the
397
-     * given CPT ID.  It accepts the same params as what get_the_post_thumbnail() accepts.
398
-     *
399
-     * @link   http://codex.wordpress.org/Function_Reference/get_the_post_thumbnail
400
-     * @access public
401
-     * @param int          $id   the ID for the cpt we want the feature image for
402
-     * @param string|array $size (optional) Image size. Defaults to 'post-thumbnail' but can also be a 2-item array
403
-     *                           representing width and height in pixels (i.e. array(32,32) ).
404
-     * @param string|array $attr Optional. Query string or array of attributes.
405
-     * @return string HTML image element
406
-     */
407
-    public function get_feature_image($id, $size = 'thumbnail', $attr = '')
408
-    {
409
-        return get_the_post_thumbnail($id, $size, $attr);
410
-    }
411
-
412
-
413
-    /**
414
-     * Just a handy way to get the list of post statuses currently registered with WP.
415
-     *
416
-     * @global array $wp_post_statuses set in wp core for storing all the post stati
417
-     * @return array
418
-     */
419
-    public function get_post_statuses()
420
-    {
421
-        global $wp_post_statuses;
422
-        $statuses = array();
423
-        foreach ($wp_post_statuses as $post_status => $args_object) {
424
-            $statuses[ $post_status ] = $args_object->label;
425
-        }
426
-        return $statuses;
427
-    }
428
-
429
-
430
-    /**
431
-     * public method that can be used to retrieve the protected status array on the instantiated cpt model
432
-     *
433
-     * @return array array of statuses.
434
-     */
435
-    public function get_status_array()
436
-    {
437
-        $statuses = $this->get_post_statuses();
438
-        // first the global filter
439
-        $statuses = apply_filters('FHEE_EEM_CPT_Base__get_status_array', $statuses);
440
-        // now the class specific filter
441
-        $statuses = apply_filters('FHEE_EEM_' . get_class($this) . '__get_status_array', $statuses);
442
-        return $statuses;
443
-    }
444
-
445
-
446
-    /**
447
-     * this returns the post statuses that are NOT the default wordpress status
448
-     *
449
-     * @return array
450
-     */
451
-    public function get_custom_post_statuses()
452
-    {
453
-        $new_stati = array();
454
-        foreach ($this->_custom_stati as $status => $props) {
455
-            $new_stati[ $status ] = $props['label'];
456
-        }
457
-        return $new_stati;
458
-    }
459
-
460
-
461
-    /**
462
-     * Creates a child of EE_CPT_Base given a WP_Post or array of wpdb results which
463
-     * are a row from the posts table. If we're missing any fields required for the model,
464
-     * we just fetch the entire entry from the DB (ie, if you want to use this to save DB queries,
465
-     * make sure you are attaching all the model's fields onto the post)
466
-     *
467
-     * @param WP_Post|array $post
468
-     * @return EE_Base_Class|EE_Soft_Delete_Base_Class
469
-     */
470
-    public function instantiate_class_from_post_object_orig($post)
471
-    {
472
-        $post = (array) $post;
473
-        $has_all_necessary_fields_for_table = true;
474
-        // check if the post has fields on the meta table already
475
-        foreach ($this->_get_other_tables() as $table_obj) {
476
-            $fields_for_that_table = $this->_get_fields_for_table($table_obj->get_table_alias());
477
-            foreach ($fields_for_that_table as $field_obj) {
478
-                if (! isset($post[ $field_obj->get_table_column() ])
479
-                    && ! isset($post[ $field_obj->get_qualified_column() ])
480
-                ) {
481
-                    $has_all_necessary_fields_for_table = false;
482
-                }
483
-            }
484
-        }
485
-        // if we don't have all the fields we need, then just fetch the proper model from the DB
486
-        if (! $has_all_necessary_fields_for_table) {
487
-            return $this->get_one_by_ID($post['ID']);
488
-        } else {
489
-            return $this->instantiate_class_from_array_or_object($post);
490
-        }
491
-    }
492
-
493
-
494
-    /**
495
-     * @param null $post
496
-     * @return EE_Base_Class|EE_Soft_Delete_Base_Class
497
-     */
498
-    public function instantiate_class_from_post_object($post = null)
499
-    {
500
-        if (empty($post)) {
501
-            global $post;
502
-        }
503
-        $post = (array) $post;
504
-        $tables_needing_to_be_queried = array();
505
-        // check if the post has fields on the meta table already
506
-        foreach ($this->get_tables() as $table_obj) {
507
-            $fields_for_that_table = $this->_get_fields_for_table($table_obj->get_table_alias());
508
-            foreach ($fields_for_that_table as $field_obj) {
509
-                if (! isset($post[ $field_obj->get_table_column() ])
510
-                    && ! isset($post[ $field_obj->get_qualified_column() ])
511
-                ) {
512
-                    $tables_needing_to_be_queried[ $table_obj->get_table_alias() ] = $table_obj;
513
-                }
514
-            }
515
-        }
516
-        // if we don't have all the fields we need, then just fetch the proper model from the DB
517
-        if ($tables_needing_to_be_queried) {
518
-            if (count($tables_needing_to_be_queried) == 1
519
-                && reset($tables_needing_to_be_queried)
520
-                   instanceof
521
-                   EE_Secondary_Table
522
-            ) {
523
-                // so we're only missing data from a secondary table. Well that's not too hard to query for
524
-                $table_to_query = reset($tables_needing_to_be_queried);
525
-                $missing_data = $this->_do_wpdb_query(
526
-                    'get_row',
527
-                    array(
528
-                        'SELECT * FROM '
529
-                        . $table_to_query->get_table_name()
530
-                        . ' WHERE '
531
-                        . $table_to_query->get_fk_on_table()
532
-                        . ' = '
533
-                        . $post['ID'],
534
-                        ARRAY_A,
535
-                    )
536
-                );
537
-                if (! empty($missing_data)) {
538
-                    $post = array_merge($post, $missing_data);
539
-                }
540
-            } else {
541
-                return $this->get_one_by_ID($post['ID']);
542
-            }
543
-        }
544
-        return $this->instantiate_class_from_array_or_object($post);
545
-    }
546
-
547
-
548
-    /**
549
-     * Gets the post type associated with this
550
-     *
551
-     * @throws EE_Error
552
-     * @return string
553
-     */
554
-    public function post_type()
555
-    {
556
-        $post_type_field = null;
557
-        foreach ($this->field_settings(true) as $field_obj) {
558
-            if ($field_obj instanceof EE_WP_Post_Type_Field) {
559
-                $post_type_field = $field_obj;
560
-                break;
561
-            }
562
-        }
563
-        if ($post_type_field == null) {
564
-            throw new EE_Error(
565
-                sprintf(
566
-                    __(
567
-                        "CPT Model %s should have a field of type EE_WP_Post_Type, but doesnt",
568
-                        "event_espresso"
569
-                    ),
570
-                    get_class($this)
571
-                )
572
-            );
573
-        }
574
-        return $post_type_field->get_default_value();
575
-    }
19
+	const EVENT_CATEGORY_TAXONOMY = 'espresso_event_categories';
20
+
21
+	/**
22
+	 * @var string post_status_publish - the wp post status for published cpts
23
+	 */
24
+	const post_status_publish = 'publish';
25
+
26
+	/**
27
+	 * @var string post_status_future - the wp post status for scheduled cpts
28
+	 */
29
+	const post_status_future = 'future';
30
+
31
+	/**
32
+	 * @var string post_status_draft - the wp post status for draft cpts
33
+	 */
34
+	const post_status_draft = 'draft';
35
+
36
+	/**
37
+	 * @var string post_status_pending - the wp post status for pending cpts
38
+	 */
39
+	const post_status_pending = 'pending';
40
+
41
+	/**
42
+	 * @var string post_status_private - the wp post status for private cpts
43
+	 */
44
+	const post_status_private = 'private';
45
+
46
+	/**
47
+	 * @var string post_status_trashed - the wp post status for trashed cpts
48
+	 */
49
+	const post_status_trashed = 'trash';
50
+
51
+	/**
52
+	 * This is an array of custom statuses for the given CPT model (modified by children)
53
+	 * format:
54
+	 * array(
55
+	 *        'status_name' => array(
56
+	 *            'label' => __('Status Name', 'event_espresso'),
57
+	 *            'public' => TRUE //whether a public status or not.
58
+	 *        )
59
+	 * )
60
+	 *
61
+	 * @var array
62
+	 */
63
+	protected $_custom_stati = array();
64
+
65
+
66
+	/**
67
+	 * Adds a relationship to Term_Taxonomy for each CPT_Base
68
+	 *
69
+	 * @param string $timezone
70
+	 * @throws \EE_Error
71
+	 */
72
+	protected function __construct($timezone = null)
73
+	{
74
+		// adds a relationship to Term_Taxonomy for all these models. For this to work
75
+		// Term_Relationship must have a relation to each model subclassing EE_CPT_Base explicitly
76
+		// eg, in EEM_Term_Relationship, inside the _model_relations array, there must be an entry
77
+		// with key equalling the subclassing model's model name (eg 'Event' or 'Venue'), and the value
78
+		// must also be new EE_HABTM_Relation('Term_Relationship');
79
+		$this->_model_relations['Term_Taxonomy'] = new EE_HABTM_Relation('Term_Relationship');
80
+		$primary_table_name = null;
81
+		// add  the common _status field to all CPT primary tables.
82
+		foreach ($this->_tables as $alias => $table_obj) {
83
+			if ($table_obj instanceof EE_Primary_Table) {
84
+				$primary_table_name = $alias;
85
+			}
86
+		}
87
+		// set default wp post statuses if child has not already set.
88
+		if (! isset($this->_fields[ $primary_table_name ]['status'])) {
89
+			$this->_fields[ $primary_table_name ]['status'] = new EE_WP_Post_Status_Field(
90
+				'post_status',
91
+				__("Event Status", "event_espresso"),
92
+				false,
93
+				'draft'
94
+			);
95
+		}
96
+		if (! isset($this->_fields[ $primary_table_name ]['to_ping'])) {
97
+			$this->_fields[ $primary_table_name ]['to_ping'] = new EE_DB_Only_Text_Field(
98
+				'to_ping',
99
+				__('To Ping', 'event_espresso'),
100
+				false,
101
+				''
102
+			);
103
+		}
104
+		if (! isset($this->_fields[ $primary_table_name ]['pinged'])) {
105
+			$this->_fields[ $primary_table_name ]['pinged'] = new EE_DB_Only_Text_Field(
106
+				'pinged',
107
+				__('Pinged', 'event_espresso'),
108
+				false,
109
+				''
110
+			);
111
+		}
112
+		if (! isset($this->_fields[ $primary_table_name ]['comment_status'])) {
113
+			$this->_fields[ $primary_table_name ]['comment_status'] = new EE_Plain_Text_Field(
114
+				'comment_status',
115
+				__('Comment Status', 'event_espresso'),
116
+				false,
117
+				'open'
118
+			);
119
+		}
120
+		if (! isset($this->_fields[ $primary_table_name ]['ping_status'])) {
121
+			$this->_fields[ $primary_table_name ]['ping_status'] = new EE_Plain_Text_Field(
122
+				'ping_status',
123
+				__('Ping Status', 'event_espresso'),
124
+				false,
125
+				'open'
126
+			);
127
+		}
128
+		if (! isset($this->_fields[ $primary_table_name ]['post_content_filtered'])) {
129
+			$this->_fields[ $primary_table_name ]['post_content_filtered'] = new EE_DB_Only_Text_Field(
130
+				'post_content_filtered',
131
+				__('Post Content Filtered', 'event_espresso'),
132
+				false,
133
+				''
134
+			);
135
+		}
136
+		if (! isset($this->_model_relations['Post_Meta'])) {
137
+			// don't block deletes though because we want to maintain the current behaviour
138
+			$this->_model_relations['Post_Meta'] = new EE_Has_Many_Relation(false);
139
+		}
140
+		if (! $this->_minimum_where_conditions_strategy instanceof EE_Default_Where_Conditions) {
141
+			// nothing was set during child constructor, so set default
142
+			$this->_minimum_where_conditions_strategy = new EE_CPT_Minimum_Where_Conditions($this->post_type());
143
+		}
144
+		if (! $this->_default_where_conditions_strategy instanceof EE_Default_Where_Conditions) {
145
+			// nothing was set during child constructor, so set default
146
+			// it's ok for child classes to specify this, but generally this is more DRY
147
+			$this->_default_where_conditions_strategy = new EE_CPT_Where_Conditions($this->post_type());
148
+		}
149
+		parent::__construct($timezone);
150
+	}
151
+
152
+
153
+	/**
154
+	 * @return array
155
+	 */
156
+	public function public_event_stati()
157
+	{
158
+		// @see wp-includes/post.php
159
+		return get_post_stati(array('public' => true));
160
+	}
161
+
162
+
163
+	/**
164
+	 * Searches for field on this model of type 'deleted_flag'. if it is found,
165
+	 * returns it's name. BUT That doesn't apply to CPTs. We should instead use post_status_field_name
166
+	 *
167
+	 * @return string
168
+	 * @throws EE_Error
169
+	 */
170
+	public function deleted_field_name()
171
+	{
172
+		throw new EE_Error(
173
+			sprintf(
174
+				__(
175
+					"EEM_CPT_Base should nto call deleted_field_name! It should instead use post_status_field_name",
176
+					"event_espresso"
177
+				)
178
+			)
179
+		);
180
+	}
181
+
182
+
183
+	/**
184
+	 * Gets the field's name that sets the post status
185
+	 *
186
+	 * @return string
187
+	 * @throws EE_Error
188
+	 */
189
+	public function post_status_field_name()
190
+	{
191
+		$field = $this->get_a_field_of_type('EE_WP_Post_Status_Field');
192
+		if ($field) {
193
+			return $field->get_name();
194
+		} else {
195
+			throw new EE_Error(
196
+				sprintf(
197
+					__(
198
+						'We are trying to find the post status flag field on %s, but none was found. Are you sure there is a field of type EE_Trashed_Flag_Field in %s constructor?',
199
+						'event_espresso'
200
+					),
201
+					get_class($this),
202
+					get_class($this)
203
+				)
204
+			);
205
+		}
206
+	}
207
+
208
+
209
+	/**
210
+	 * Alters the query params so that only trashed/soft-deleted items are considered
211
+	 *
212
+	 * @param array $query_params like EEM_Base::get_all's $query_params
213
+	 * @return array like EEM_Base::get_all's $query_params
214
+	 */
215
+	protected function _alter_query_params_so_only_trashed_items_included($query_params)
216
+	{
217
+		$post_status_field_name = $this->post_status_field_name();
218
+		$query_params[0][ $post_status_field_name ] = self::post_status_trashed;
219
+		return $query_params;
220
+	}
221
+
222
+
223
+	/**
224
+	 * Alters the query params so each item's deleted status is ignored.
225
+	 *
226
+	 * @param array $query_params
227
+	 * @return array
228
+	 */
229
+	protected function _alter_query_params_so_deleted_and_undeleted_items_included($query_params)
230
+	{
231
+		$query_params['default_where_conditions'] = 'minimum';
232
+		return $query_params;
233
+	}
234
+
235
+
236
+	/**
237
+	 * Performs deletes or restores on items. Both soft-deleted and non-soft-deleted items considered.
238
+	 *
239
+	 * @param boolean $delete       true to indicate deletion, false to indicate restoration
240
+	 * @param array   $query_params like EEM_Base::get_all
241
+	 * @return boolean success
242
+	 */
243
+	public function delete_or_restore($delete = true, $query_params = array())
244
+	{
245
+		$post_status_field_name = $this->post_status_field_name();
246
+		$query_params = $this->_alter_query_params_so_deleted_and_undeleted_items_included($query_params);
247
+		$new_status = $delete ? self::post_status_trashed : 'draft';
248
+		if ($this->update(array($post_status_field_name => $new_status), $query_params)) {
249
+			return true;
250
+		} else {
251
+			return false;
252
+		}
253
+	}
254
+
255
+
256
+	/**
257
+	 * meta_table
258
+	 * returns first EE_Secondary_Table table name
259
+	 *
260
+	 * @access public
261
+	 * @return string
262
+	 */
263
+	public function meta_table()
264
+	{
265
+		$meta_table = $this->_get_other_tables();
266
+		$meta_table = reset($meta_table);
267
+		return $meta_table instanceof EE_Secondary_Table ? $meta_table->get_table_name() : null;
268
+	}
269
+
270
+
271
+	/**
272
+	 * This simply returns an array of the meta table fields (useful for when we just need to update those fields)
273
+	 *
274
+	 * @param  bool $all triggers whether we include DB_Only fields or JUST non DB_Only fields.  Defaults to false (no
275
+	 *                   db only fields)
276
+	 * @return array
277
+	 */
278
+	public function get_meta_table_fields($all = false)
279
+	{
280
+		$all_fields = $fields_to_return = array();
281
+		foreach ($this->_tables as $alias => $table_obj) {
282
+			if ($table_obj instanceof EE_Secondary_Table) {
283
+				$all_fields = array_merge($this->_get_fields_for_table($alias), $all_fields);
284
+			}
285
+		}
286
+		if (! $all) {
287
+			foreach ($all_fields as $name => $obj) {
288
+				if ($obj instanceof EE_DB_Only_Field_Base) {
289
+					continue;
290
+				}
291
+				$fields_to_return[] = $name;
292
+			}
293
+		} else {
294
+			$fields_to_return = array_keys($all_fields);
295
+		}
296
+		return $fields_to_return;
297
+	}
298
+
299
+
300
+	/**
301
+	 * Adds an event category with the specified name and description to the specified
302
+	 * $cpt_model_object. Intelligently adds a term if necessary, and adds a term_taxonomy if necessary,
303
+	 * and adds an entry in the term_relationship if necessary.
304
+	 *
305
+	 * @param EE_CPT_Base $cpt_model_object
306
+	 * @param string      $category_name (used to derive the term slug too)
307
+	 * @param string      $category_description
308
+	 * @param int         $parent_term_taxonomy_id
309
+	 * @return EE_Term_Taxonomy
310
+	 */
311
+	public function add_event_category(
312
+		EE_CPT_Base $cpt_model_object,
313
+		$category_name,
314
+		$category_description = '',
315
+		$parent_term_taxonomy_id = null
316
+	) {
317
+		// create term
318
+		require_once(EE_MODELS . 'EEM_Term.model.php');
319
+		// first, check for a term by the same name or slug
320
+		$category_slug = sanitize_title($category_name);
321
+		$term = EEM_Term::instance()->get_one(
322
+			array(
323
+				array(
324
+					'OR' => array(
325
+						'name' => $category_name,
326
+						'slug' => $category_slug,
327
+					),
328
+				),
329
+			)
330
+		);
331
+		if (! $term) {
332
+			$term = EE_Term::new_instance(
333
+				array(
334
+					'name' => $category_name,
335
+					'slug' => $category_slug,
336
+				)
337
+			);
338
+			$term->save();
339
+		}
340
+		// make sure there's a term-taxonomy entry too
341
+		require_once(EE_MODELS . 'EEM_Term_Taxonomy.model.php');
342
+		$term_taxonomy = EEM_Term_Taxonomy::instance()->get_one(
343
+			array(
344
+				array(
345
+					'term_id'  => $term->ID(),
346
+					'taxonomy' => self::EVENT_CATEGORY_TAXONOMY,
347
+				),
348
+			)
349
+		);
350
+		/** @var $term_taxonomy EE_Term_Taxonomy */
351
+		if (! $term_taxonomy) {
352
+			$term_taxonomy = EE_Term_Taxonomy::new_instance(
353
+				array(
354
+					'term_id'     => $term->ID(),
355
+					'taxonomy'    => self::EVENT_CATEGORY_TAXONOMY,
356
+					'description' => $category_description,
357
+					'term_count'       => 1,
358
+					'parent'      => $parent_term_taxonomy_id,
359
+				)
360
+			);
361
+			$term_taxonomy->save();
362
+		} else {
363
+			$term_taxonomy->set_count($term_taxonomy->count() + 1);
364
+			$term_taxonomy->save();
365
+		}
366
+		return $this->add_relationship_to($cpt_model_object, $term_taxonomy, 'Term_Taxonomy');
367
+	}
368
+
369
+
370
+	/**
371
+	 * Removed the category specified by name as having a relation to this event.
372
+	 * Does not remove the term or term_taxonomy.
373
+	 *
374
+	 * @param EE_CPT_Base $cpt_model_object_event
375
+	 * @param string      $category_name name of the event category (term)
376
+	 * @return bool
377
+	 */
378
+	public function remove_event_category(EE_CPT_Base $cpt_model_object_event, $category_name)
379
+	{
380
+		// find the term_taxonomy by that name
381
+		$term_taxonomy = $this->get_first_related(
382
+			$cpt_model_object_event,
383
+			'Term_Taxonomy',
384
+			array(array('Term.name' => $category_name, 'taxonomy' => self::EVENT_CATEGORY_TAXONOMY))
385
+		);
386
+		/** @var $term_taxonomy EE_Term_Taxonomy */
387
+		if ($term_taxonomy) {
388
+			$term_taxonomy->set_count($term_taxonomy->count() - 1);
389
+			$term_taxonomy->save();
390
+		}
391
+		return $this->remove_relationship_to($cpt_model_object_event, $term_taxonomy, 'Term_Taxonomy');
392
+	}
393
+
394
+
395
+	/**
396
+	 * This is a wrapper for the WordPress get_the_post_thumbnail() function that returns the feature image for the
397
+	 * given CPT ID.  It accepts the same params as what get_the_post_thumbnail() accepts.
398
+	 *
399
+	 * @link   http://codex.wordpress.org/Function_Reference/get_the_post_thumbnail
400
+	 * @access public
401
+	 * @param int          $id   the ID for the cpt we want the feature image for
402
+	 * @param string|array $size (optional) Image size. Defaults to 'post-thumbnail' but can also be a 2-item array
403
+	 *                           representing width and height in pixels (i.e. array(32,32) ).
404
+	 * @param string|array $attr Optional. Query string or array of attributes.
405
+	 * @return string HTML image element
406
+	 */
407
+	public function get_feature_image($id, $size = 'thumbnail', $attr = '')
408
+	{
409
+		return get_the_post_thumbnail($id, $size, $attr);
410
+	}
411
+
412
+
413
+	/**
414
+	 * Just a handy way to get the list of post statuses currently registered with WP.
415
+	 *
416
+	 * @global array $wp_post_statuses set in wp core for storing all the post stati
417
+	 * @return array
418
+	 */
419
+	public function get_post_statuses()
420
+	{
421
+		global $wp_post_statuses;
422
+		$statuses = array();
423
+		foreach ($wp_post_statuses as $post_status => $args_object) {
424
+			$statuses[ $post_status ] = $args_object->label;
425
+		}
426
+		return $statuses;
427
+	}
428
+
429
+
430
+	/**
431
+	 * public method that can be used to retrieve the protected status array on the instantiated cpt model
432
+	 *
433
+	 * @return array array of statuses.
434
+	 */
435
+	public function get_status_array()
436
+	{
437
+		$statuses = $this->get_post_statuses();
438
+		// first the global filter
439
+		$statuses = apply_filters('FHEE_EEM_CPT_Base__get_status_array', $statuses);
440
+		// now the class specific filter
441
+		$statuses = apply_filters('FHEE_EEM_' . get_class($this) . '__get_status_array', $statuses);
442
+		return $statuses;
443
+	}
444
+
445
+
446
+	/**
447
+	 * this returns the post statuses that are NOT the default wordpress status
448
+	 *
449
+	 * @return array
450
+	 */
451
+	public function get_custom_post_statuses()
452
+	{
453
+		$new_stati = array();
454
+		foreach ($this->_custom_stati as $status => $props) {
455
+			$new_stati[ $status ] = $props['label'];
456
+		}
457
+		return $new_stati;
458
+	}
459
+
460
+
461
+	/**
462
+	 * Creates a child of EE_CPT_Base given a WP_Post or array of wpdb results which
463
+	 * are a row from the posts table. If we're missing any fields required for the model,
464
+	 * we just fetch the entire entry from the DB (ie, if you want to use this to save DB queries,
465
+	 * make sure you are attaching all the model's fields onto the post)
466
+	 *
467
+	 * @param WP_Post|array $post
468
+	 * @return EE_Base_Class|EE_Soft_Delete_Base_Class
469
+	 */
470
+	public function instantiate_class_from_post_object_orig($post)
471
+	{
472
+		$post = (array) $post;
473
+		$has_all_necessary_fields_for_table = true;
474
+		// check if the post has fields on the meta table already
475
+		foreach ($this->_get_other_tables() as $table_obj) {
476
+			$fields_for_that_table = $this->_get_fields_for_table($table_obj->get_table_alias());
477
+			foreach ($fields_for_that_table as $field_obj) {
478
+				if (! isset($post[ $field_obj->get_table_column() ])
479
+					&& ! isset($post[ $field_obj->get_qualified_column() ])
480
+				) {
481
+					$has_all_necessary_fields_for_table = false;
482
+				}
483
+			}
484
+		}
485
+		// if we don't have all the fields we need, then just fetch the proper model from the DB
486
+		if (! $has_all_necessary_fields_for_table) {
487
+			return $this->get_one_by_ID($post['ID']);
488
+		} else {
489
+			return $this->instantiate_class_from_array_or_object($post);
490
+		}
491
+	}
492
+
493
+
494
+	/**
495
+	 * @param null $post
496
+	 * @return EE_Base_Class|EE_Soft_Delete_Base_Class
497
+	 */
498
+	public function instantiate_class_from_post_object($post = null)
499
+	{
500
+		if (empty($post)) {
501
+			global $post;
502
+		}
503
+		$post = (array) $post;
504
+		$tables_needing_to_be_queried = array();
505
+		// check if the post has fields on the meta table already
506
+		foreach ($this->get_tables() as $table_obj) {
507
+			$fields_for_that_table = $this->_get_fields_for_table($table_obj->get_table_alias());
508
+			foreach ($fields_for_that_table as $field_obj) {
509
+				if (! isset($post[ $field_obj->get_table_column() ])
510
+					&& ! isset($post[ $field_obj->get_qualified_column() ])
511
+				) {
512
+					$tables_needing_to_be_queried[ $table_obj->get_table_alias() ] = $table_obj;
513
+				}
514
+			}
515
+		}
516
+		// if we don't have all the fields we need, then just fetch the proper model from the DB
517
+		if ($tables_needing_to_be_queried) {
518
+			if (count($tables_needing_to_be_queried) == 1
519
+				&& reset($tables_needing_to_be_queried)
520
+				   instanceof
521
+				   EE_Secondary_Table
522
+			) {
523
+				// so we're only missing data from a secondary table. Well that's not too hard to query for
524
+				$table_to_query = reset($tables_needing_to_be_queried);
525
+				$missing_data = $this->_do_wpdb_query(
526
+					'get_row',
527
+					array(
528
+						'SELECT * FROM '
529
+						. $table_to_query->get_table_name()
530
+						. ' WHERE '
531
+						. $table_to_query->get_fk_on_table()
532
+						. ' = '
533
+						. $post['ID'],
534
+						ARRAY_A,
535
+					)
536
+				);
537
+				if (! empty($missing_data)) {
538
+					$post = array_merge($post, $missing_data);
539
+				}
540
+			} else {
541
+				return $this->get_one_by_ID($post['ID']);
542
+			}
543
+		}
544
+		return $this->instantiate_class_from_array_or_object($post);
545
+	}
546
+
547
+
548
+	/**
549
+	 * Gets the post type associated with this
550
+	 *
551
+	 * @throws EE_Error
552
+	 * @return string
553
+	 */
554
+	public function post_type()
555
+	{
556
+		$post_type_field = null;
557
+		foreach ($this->field_settings(true) as $field_obj) {
558
+			if ($field_obj instanceof EE_WP_Post_Type_Field) {
559
+				$post_type_field = $field_obj;
560
+				break;
561
+			}
562
+		}
563
+		if ($post_type_field == null) {
564
+			throw new EE_Error(
565
+				sprintf(
566
+					__(
567
+						"CPT Model %s should have a field of type EE_WP_Post_Type, but doesnt",
568
+						"event_espresso"
569
+					),
570
+					get_class($this)
571
+				)
572
+			);
573
+		}
574
+		return $post_type_field->get_default_value();
575
+	}
576 576
 }
Please login to merge, or discard this patch.