Completed
Branch BUG-10738-inconsistency-in-ses... (cda363)
by
unknown
13:38 queued 12s
created

EE_CPT_Base::wp_post()   C

Complexity

Conditions 8
Paths 5

Size

Total Lines 31
Code Lines 22

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 8
eloc 22
nc 5
nop 0
dl 0
loc 31
rs 5.3846
c 0
b 0
f 0
1
<?php if ( !defined( 'EVENT_ESPRESSO_VERSION' ) ) {
2
	exit( 'No direct script access allowed' );
3
}
4
/**
5
 * Event Espresso
6
 *
7
 * Event Registration and Management Plugin for WordPress
8
 *
9
 * @ package        Event Espresso
10
 * @ author        Event Espresso
11
 * @ copyright    (c) 2008-2011 Event Espresso  All Rights Reserved.
12
 * @ license        {@link http://eventespresso.com/support/terms-conditions/}   * see Plugin Licensing *
13
 * @ link                {@link http://www.eventespresso.com}
14
 * @ since            4.0
15
 *
16
 */
17
18
19
20
/**
21
 * Class EE_CPT_Base
22
 *
23
 * Base class for all models which are really custom post types, as there is much functionality they share
24
 *
25
 * @package               Event Espresso
26
 * @subpackage            core
27
 * @author                Michael Nelson
28
 * @since                 EE4
29
 *
30
 */
31
abstract class EE_CPT_Base extends EE_Soft_Delete_Base_Class {
32
33
	/**
34
	 * This is a property for holding cached feature images on CPT objects.  Cache's are set on the first "feature_image()" method call.  Each key in the array corresponds to the requested size.
35
	 * @var array
36
	 */
37
	protected $_feature_image = array();
38
39
    /**
40
     * @var WP_Post the WP_Post that corresponds with this CPT model object
41
     */
42
	protected $_wp_post;
43
44
45
	abstract public function wp_user();
46
47
48
49
    /**
50
     * Returns the WP post associated with this CPT model object. If this CPT is saved, fetches it
51
     * from the DB. Otherwise, create an unsaved WP_POst object. Caches the post internally.
52
     * @return WP_Post
53
     */
54
    public function wp_post(){
55
        global $wpdb;
56
        if (! $this->_wp_post instanceof WP_Post) {
57
            if ($this->ID()) {
58
                $this->_wp_post = get_post($this->ID());
59
            } else {
60
                $simulated_db_result = new stdClass();
61
                foreach($this->get_model()->field_settings(true) as $field_name => $field_obj){
62
                    if ($this->get_model()->get_table_obj_by_alias($field_obj->get_table_alias())->get_table_name() === $wpdb->posts){
63
                        $column = $field_obj->get_table_column();
64
65
                        if($field_obj instanceof EE_Datetime_Field){
66
                            $value_on_model_obj = $this->get_DateTime_object($field_name);
67
                        } elseif( $field_obj->is_db_only_field()){
68
                            $value_on_model_obj = $field_obj->get_default_value();
69
                        } else {
70
                            $value_on_model_obj = $this->get_raw($field_name);
71
                        }
72
                        $simulated_db_result->{$column} = $field_obj->prepare_for_use_in_db($value_on_model_obj);
73
                    }
74
                }
75
                $this->_wp_post = new WP_Post($simulated_db_result);
76
            }
77
            //and let's make retrieving the EE CPT object easy too
78
            $classname = get_class($this);
79
            if (! isset($this->_wp_post->{$classname})) {
80
                $this->_wp_post->{$classname} = $this;
81
            }
82
        }
83
        return $this->_wp_post;
84
    }
85
86
    /**
87
     * When fetching a new value for a post field that uses the global $post for rendering,
88
     * set the global $post temporarily to be this model object; and afterwards restore it
89
     * @param string $fieldname
90
     * @param bool $pretty
91
     * @param string $extra_cache_ref
92
     * @return mixed
93
     */
94
    protected function _get_fresh_property($fieldname, $pretty = false, $extra_cache_ref = null)
95
    {
96
        global $post;
97
98
        if ( $pretty
99
            && (
100
                ! (
101
                       $post instanceof WP_Post
102
                       && $post->ID
103
                   )
104
                || (int)$post->ID !== $this->ID()
105
             )
106
            && $this->get_model()->field_settings_for($fieldname) instanceof EE_Post_Content_Field ) {
107
            $old_post = $post;
108
            $post = $this->wp_post();
109
            $return_value = parent::_get_fresh_property($fieldname, $pretty, $extra_cache_ref);
110
            $post = $old_post;
111
        } else {
112
            $return_value = parent::_get_fresh_property($fieldname, $pretty, $extra_cache_ref);
113
        }
114
        return $return_value;
115
    }
116
117
    /**
118
	 * Adds to the specified event category. If it category doesn't exist, creates it.
119
	 * @param string $category_name
120
	 * @param string $category_description    optional
121
	 * @param int    $parent_term_taxonomy_id optional
122
	 * @return EE_Term_Taxonomy
123
	 */
124
	function add_event_category( $category_name, $category_description = NULL, $parent_term_taxonomy_id = NULL ) {
125
		return $this->get_model()->add_event_category( $this, $category_name, $category_description, $parent_term_taxonomy_id );
126
	}
127
128
129
130
	/**
131
	 * Removes the event category by specified name from being related ot this event
132
	 * @param string $category_name
133
	 * @return bool
134
	 */
135
	function remove_event_category( $category_name ) {
136
		return $this->get_model()->remove_event_category( $this, $category_name );
137
	}
138
139
140
141
	/**
142
	 * Removes the relation to the specified term taxonomy, and maintains the
143
	 * data integrity of the term taxonomy provided
144
	 * @param EE_Term_Taxonomy $term_taxonomy
145
	 * @return EE_Base_Class the relation was removed from
146
	 */
147
	function remove_relation_to_term_taxonomy( $term_taxonomy ) {
148 View Code Duplication
		if ( !$term_taxonomy ) {
149
			EE_Error::add_error( sprintf( __( "No Term_Taxonomy provided which to remove from model object of type %s and id %d", "event_espresso" ), get_class( $this ), $this->ID() ), __FILE__, __FUNCTION__, __LINE__ );
150
			return NULL;
151
		}
152
		$term_taxonomy->set_count( $term_taxonomy->count() - 1 );
153
		$term_taxonomy->save();
154
		return $this->_remove_relation_to( $term_taxonomy, 'Term_Taxonomy' );
155
	}
156
157
158
159
	/**
160
	 * The main purpose of this method is to return the post type for the model object
161
	 *
162
	 * @access public
163
	 * @return string
164
	 */
165
	public function post_type() {
166
		return $this->get_model()->post_type();
167
	}
168
169
170
171
	/**
172
	 * The main purpose of this method is to return the parent for the model object
173
	 *
174
	 * @access public
175
	 * @return int
176
	 */
177
	public function parent() {
178
		return $this->get( 'parent' );
179
	}
180
181
182
183
	/**
184
	 * return the _status property
185
	 * @return string
186
	 */
187
	public function status() {
188
		return $this->get( 'status' );
189
	}
190
191
192
193
	/**
194
	 * @param string $status
195
	 */
196
	public function set_status( $status ) {
197
		$this->set( 'status', $status );
198
	}
199
200
201
202
	/**
203
	 * This calls the equivalent model method for retrieving the feature image which in turn is a wrapper for WordPress' get_the_post_thumbnail() function.
204
	 *
205
	 * @link   http://codex.wordpress.org/Function_Reference/get_the_post_thumbnail
206
	 * @access protected
207
	 * @param string|array $size (optional) Image size. Defaults to 'post-thumbnail' but can also be a 2-item array representing width and height in pixels (i.e. array(32,32) ).
208
	 * @param string|array $attr Optional. Query string or array of attributes.
209
	 * @return string HTML image element
210
	 */
211
	protected function _get_feature_image( $size, $attr ) {
212
		//first let's see if we already have the _feature_image property set AND if it has a cached element on it FOR the given size
213
		$attr_key = is_array( $attr ) ? implode( '_', $attr ) : $attr;
214
		$cache_key = is_array( $size ) ? implode( '_', $size ) . $attr_key : $size . $attr_key;
215
		$this->_feature_image[ $cache_key ] = isset( $this->_feature_image[ $cache_key ] ) ? $this->_feature_image[ $cache_key ] : $this->get_model()->get_feature_image( $this->ID(), $size, $attr );
216
		return $this->_feature_image[ $cache_key ];
217
	}
218
219
220
221
	/**
222
	 * See _get_feature_image. Returns the HTML to display a featured image
223
	 * @param string       $size
224
	 * @param string|array $attr
225
	 * @return string of html
226
	 */
227
	public function feature_image( $size = 'thumbnail', $attr = '' ) {
228
		return $this->_get_feature_image( $size, $attr );
229
	}
230
231
232
233
	/**
234
	 * This uses the wp "wp_get_attachment_image_src()" function to return the feature image for the current class using the given size params.
235
	 * @param  string|array $size can either be a string: 'thumbnail', 'medium', 'large', 'full' OR 2-item array representing width and height in pixels eg. array(32,32).
236
	 * @return string|boolean          the url of the image or false if not found
237
	 */
238
	public function feature_image_url( $size = 'thumbnail' ) {
239
		$attachment = wp_get_attachment_image_src( get_post_thumbnail_id( $this->ID() ), $size );
240
		return !empty( $attachment ) ? $attachment[ 0 ] : FALSE;
241
	}
242
243
244
245
	/**
246
	 * This is a method for restoring this_obj using details from the given $revision_id
247
	 *
248
	 * @param int $revision_id 		ID of the revision we're getting data from
249
	 * @param array $related_obj_names if included this will be used to restore for related obj
250
	 *                                 if not included then we just do restore on the meta.
251
	 *                                 We will accept an array of related_obj_names for restoration here.
252
	 * @param array $where_query       You can optionally include an array of key=>value pairs
253
	 *                                 that allow you to further constrict the relation to being added.
254
	 *                                 However, keep in mind that the columns (keys) given
255
	 *                                 must match a column on the JOIN table and currently
256
	 *                                 only the HABTM models accept these additional conditions.
257
	 *                                 Also remember that if an exact match isn't found for these extra cols/val pairs,
258
	 *                                 then a NEW row is created in the join table.
259
	 *                                 This array is INDEXED by RELATED OBJ NAME (so it corresponds with the obj_names sent);
260
	 * @return void
261
	 */
262
	public function restore_revision( $revision_id, $related_obj_names = array(), $where_query = array() ) {
263
		//get revision object
264
		$revision_obj = $this->get_model()->get_one_by_ID( $revision_id );
265
		if ( $revision_obj instanceof EE_CPT_Base ) {
266
			//no related_obj_name so we assume we're saving a revision on this object.
267
			if ( empty( $related_obj_names ) ) {
268
				$fields = $this->get_model()->get_meta_table_fields();
269
				foreach ( $fields as $field ) {
270
					$this->set( $field, $revision_obj->get( $field ) );
271
				}
272
				$this->save();
273
			}
274
			$related_obj_names = (array)$related_obj_names;
275
			foreach ( $related_obj_names as $related_name ) {
276
				//related_obj_name so we're saving a revision on an object related to this object
277
				//do we have $where_query params for this related object?  If we do then we include that.
278
				$cols_n_values = isset( $where_query[ $related_name ] ) ? $where_query[ $related_name ] : array();
279
				$where_params = !empty( $cols_n_values ) ? array( $cols_n_values ) : array();
280
				$related_objs = $this->get_many_related( $related_name, $where_params );
281
				$revision_related_objs = $revision_obj->get_many_related( $related_name, $where_params );
282
				//load helper
283
				//remove related objs from this object that are not in revision
284
				//array_diff *should* work cause I think objects are indexed by ID?
285
				$related_to_remove = EEH_Array::object_array_diff( $related_objs, $revision_related_objs );
286
				foreach ( $related_to_remove as $rr ) {
287
					$this->_remove_relation_to( $rr, $related_name, $cols_n_values );
288
				}
289
				//add all related objs attached to revision to this object
290
				foreach ( $revision_related_objs as $r_obj ) {
291
					$this->_add_relation_to( $r_obj, $related_name, $cols_n_values );
292
				}
293
			}
294
		}
295
	}
296
297
298
299
	/**
300
	 * Wrapper for get_post_meta, http://codex.wordpress.org/Function_Reference/get_post_meta
301
	 * @param string  $meta_key
302
	 * @param boolean $single
303
	 * @return mixed <ul><li>If only $id is set it will return all meta values in an associative array.</li>
304
	 * <li>If $single is set to false, or left blank, the function returns an array containing all values of the specified key.</li>
305
	 * <li>If $single is set to true, the function returns the first value of the specified key (not in an array</li></ul>
306
	 */
307
	public function get_post_meta( $meta_key = NULL, $single = FALSE ) {
308
		return get_post_meta( $this->ID(), $meta_key, $single );
309
	}
310
311
312
313
	/**
314
	 * Wrapper for update_post_meta, http://codex.wordpress.org/Function_Reference/update_post_meta
315
	 * @param string $meta_key
316
	 * @param mixed  $meta_value
317
	 * @param mixed  $prev_value
318
	 * @return mixed Returns meta_id if the meta doesn't exist, otherwise returns true on success and false on failure. NOTE: If the meta_value passed to this function is the same as the value that is already in the database, this function returns false.
319
	 */
320
	public function update_post_meta( $meta_key, $meta_value, $prev_value = NULL ) {
321
		if ( ! $this->ID() ) {
322
			$this->save();
323
		}
324
		return update_post_meta( $this->ID(), $meta_key, $meta_value, $prev_value );
325
	}
326
327
328
329
	/**
330
	 * Wrapper for add_post_meta, http://codex.wordpress.org/Function_Reference/add_post_meta
331
	 * @param mixed $meta_key
332
	 * @param mixed $meta_value
333
	 * @param bool  $unique . If postmeta for this $meta_key already exists, whether to add an additional item or not
334
	 * @return boolean Boolean true, except if the $unique argument was set to true and a custom field with the given key already exists, in which case false is returned.
335
	 */
336
	public function add_post_meta( $meta_key, $meta_value, $unique = FALSE ) {
337
		if ( $this->ID() ) {
338
			$this->save();
339
		}
340
		return add_post_meta( $this->ID(), $meta_key, $meta_value, $unique );
341
	}
342
343
344
345
	/**
346
	 * Wrapper for delete_post_meta, http://codex.wordpress.org/Function_Reference/delete_post_meta
347
	 *
348
	 * @param mixed $meta_key
349
	 * @param mixed $meta_value
350
	 * @return boolean False for failure. True for success.
351
	 */
352
	public function delete_post_meta( $meta_key, $meta_value = '' ) {
353
		if ( ! $this->ID() ) {
354
			//there are obviously no postmetas for this if it's not saved
355
			//so let's just report this as a success
356
			return true;
357
		}
358
		return delete_post_meta( $this->ID(), $meta_key, $meta_value );
359
	}
360
361
362
363
	/**
364
	 * Gets the URL for viewing this event on the front-end
365
	 * @return string
366
	 */
367
	public function get_permalink() {
368
		return get_permalink( $this->ID() );
369
	}
370
371
372
373
	/**
374
	 * Gets all the term-taxonomies for this CPT
375
	 * @param array $query_params
376
	 * @return EE_Term_Taxonomy
377
	 */
378
	public function term_taxonomies( $query_params = array() ) {
379
		return $this->get_many_related( 'Term_Taxonomy', $query_params );
380
	}
381
382
383
384
	/**
385
	 * @return mixed
386
	 */
387
	public function get_custom_post_statuses() {
388
		return $this->get_model()->get_custom_post_statuses();
389
	}
390
391
392
393
	/**
394
	 * @return mixed
395
	 */
396
	public function get_all_post_statuses() {
397
		return $this->get_model()->get_status_array();
398
	}
399
400
401
402
    /**
403
     * Don't serialize the WP Post. That's just duplicate data and we want to avoid recursion
404
     * @return array
405
     */
406
    public function __sleep()
407
    {
408
        $properties_to_serialize = parent::__sleep();
409
        $properties_to_serialize = array_diff( $properties_to_serialize, array('_wp_post'));
410
        return $properties_to_serialize;
411
    }
412
}
413