Completed
Push — master ( 049abe...7733bc )
by Andrew
10s
created

ClassyPost::thumbnail()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 15
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 1
Metric Value
cc 3
eloc 6
c 2
b 0
f 1
nc 3
nop 0
dl 0
loc 15
rs 9.4285
1
<?php
2
3
class ClassyPost extends ClassyBasis {
0 ignored issues
show
Coding Style Compatibility introduced by
PSR1 recommends that each class must be in a namespace of at least one level to avoid collisions.

You can fix this by adding a namespace to your class:

namespace YourVendor;

class YourClass { }

When choosing a vendor namespace, try to pick something that is not too generic to avoid conflicts with other libraries.

Loading history...
4
5
	/**
6
	 * Current post id
7
	 * @var int
8
	 */
9
	public $ID;
10
11
	/**
12
	 * Stores current post object
13
	 * @var object
14
	 */
15
	protected $object;
16
17
	/**
18
	 * Post title
19
	 * @var string
20
	 */
21
	public $post_title;
22
23
	/**
24
	 * Post name
25
	 * @var string
26
	 */
27
	public $post_name;
28
29
	/**
30
	 * Post content (raw)
31
	 * @var string
32
	 */
33
	public $post_content;
34
35
	/**
36
	 * Post type
37
	 * @var string
38
	 */
39
	public $post_type;
40
41
	/**
42
	 * Post author id
43
	 * @var int
44
	 */
45
	public $post_author;
46
47
	/**
48
	 * Post date. String as stored in the WP database, ex: 2012-04-23 08:11:23
49
	 * @var string
50
	 */
51
	public $post_date;
52
53
	/**
54
	 * Post excerpt (raw)
55
	 * @var string
56
	 */
57
	public $post_excerpt;
58
59
	/**
60
	 * Post status. It can be draft, publish, pending, private, trash, etc.
61
	 * @var string
62
	 */
63
	public $post_status;
64
65
	/**
66
	 * Post permalink
67
	 * @var string
68
	 */
69
	public $permalink;
70
71
72
	/**
73
	 * Main constructor function. If ID won't be provided we will try to find it, based on your query
74
	 * @param object/int $post
0 ignored issues
show
Documentation introduced by
The doc-type object/int could not be parsed: Unknown type name "object/int" at position 0. (view supported doc-types)

This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.

Loading history...
75
	 */
76
	public function __construct( $post = null ) {
77
		if ( is_integer( $post ) ) {
78
			$this->ID = $post;
79
			$this->init();
80
		} elseif ( is_a( $post, 'WP_Post' ) ) {
81
			$this->import( $post );
82
		}
83
	}
84
85
	/**
86
	 * Initialises Instance based on provided post id
87
	 */
88
	protected function init() {
89
		$post = $this->get_object();
90
91
		if ( is_a( $post, 'WP_Post' ) ) {
92
			$this->import( $post );
93
		}
94
	}
95
96
	/**
97
	 * Returns post object
98
	 *
99
	 * @return object
100
	 */
101
102
	public function get_object() {
103
		$object = get_post( $this->ID );
104
105
		return $object;
106
	}
107
108
	/**
109
	 * Checks if current user can edit this post
110
	 *
111
	 * @return boolean
112
	 */
113
	public function can_edit() {
114
		if ( ! function_exists( 'current_user_can' ) ) {
115
			return false;
116
		}
117
		if ( current_user_can( 'edit_post', $this->ID ) ) {
118
			return true;
119
		}
120
		return false;
121
	}
122
123
	/**
124
	 * Returns post edit url
125
	 *
126
	 * @return string
127
	 */
128
	public function get_edit_url() {
129
		if ( $this->can_edit() ) {
130
			return get_edit_post_link( $this->ID );
131
		}
132
	}
133
134
	/**
135
	 * Returns array of attached image ids
136
	 *
137
	 * @return array of ids
138
	 */
139
	public function get_attached_images() {
140
141
		$attrs = array(
142
			'post_parent' => $this->ID,
143
			'post_status' => null,
144
			'post_type' => 'attachment',
145
			'post_mime_type' => 'image',
146
			'order' => 'ASC',
147
			'numberposts' => -1,
148
			'orderby' => 'menu_order',
149
			'fields' => 'ids',
150
		);
151
152
		$images = get_children( $attrs );
153
154
		if ( ! count( $images ) ) {
155
			return false;
0 ignored issues
show
Bug Best Practice introduced by
The return type of return false; (false) is incompatible with the return type documented by ClassyPost::get_attached_images of type array.

If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.

Let’s take a look at an example:

class Author {
    private $name;

    public function __construct($name) {
        $this->name = $name;
    }

    public function getName() {
        return $this->name;
    }
}

abstract class Post {
    public function getAuthor() {
        return 'Johannes';
    }
}

class BlogPost extends Post {
    public function getAuthor() {
        return new Author('Johannes');
    }
}

class ForumPost extends Post { /* ... */ }

function my_function(Post $post) {
    echo strtoupper($post->getAuthor());
}

Our function my_function expects a Post object, and outputs the author of the post. The base class Post returns a simple string and outputting a simple string will work just fine. However, the child class BlogPost which is a sub-type of Post instead decided to return an object, and is therefore violating the SOLID principles. If a BlogPost were passed to my_function, PHP would not complain, but ultimately fail when executing the strtoupper call in its body.

Loading history...
156
		}
157
158
		return $images;
159
160
	}
161
162
	/**
163
	 * Returns array of attached images as ClassyImage objects
164
	 *
165
	 * @return array of ClassyImage
166
	 */
167
	public function attached_images() {
168
169
		$_return = array();
170
171
		$images = $this->get_attached_images();
172
173
		if ( $images ) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $images of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
174
175
			foreach ( $images as $image_id ) {
176
177
				$_return[] = new ClassyImage( $image_id );
178
179
			}
180
		}
181
182
		return $_return;
183
	}
184
185
186
	/**
187
	 * Returns first attached image id
188
	 *
189
	 * @return int/boolean
0 ignored issues
show
Documentation introduced by
The doc-type int/boolean could not be parsed: Unknown type name "int/boolean" at position 0. (view supported doc-types)

This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.

Loading history...
190
	 */
191
	public function get_first_attached_image_id() {
192
193
		$attrs = array(
194
			'post_parent' => $this->ID,
195
			'post_status' => null,
196
			'post_type' => 'attachment',
197
			'post_mime_type' => 'image',
198
			'order' => 'ASC',
199
			'numberposts' => 1,
200
			'orderby' => 'menu_order',
201
			'fields' => 'ids',
202
		);
203
204
		$images = get_children( $attrs );
205
206
		if ( ! count( $images ) ) {
207
			return false;
208
		}
209
210
		$images = array_values( $images );
211
212
		return $images[0];
213
214
	}
215
216
217
	/**
218
	 * Returns first attached image
219
	 *
220
	 * @return ClassyImage
221
	 */
222
	public function first_attached_image( $size = 'thumbnail' ) {
0 ignored issues
show
Unused Code introduced by
The parameter $size is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
223
224
		$image_id = $this->get_first_attached_image_id();
225
226
		if ( $image_id ) {
227
			return new ClassyImage( $image_id );
228
		}
229
230
		return new ClassyImage();
231
	}
232
233
234
	/**
235
	 * Returns post thumbnail
236
	 *
237
	 * @return ClassyImage
238
	 */
239
	public function thumbnail() {
240
		
241
		if ( function_exists( 'get_post_thumbnail_id' ) ) {
242
			$image_id = get_post_thumbnail_id( $this->ID );
243
244
			if ( $image_id ) {
245
246
				return new ClassyImage( $image_id );
247
248
			}
249
		}
250
251
		return new ClassyImage();
252
253
	}
254
255
256
	/**
257
	 * Returns post title with filters applied
258
	 *
259
	 * @return string
260
	 */
261
	public function get_title() {
262
		return apply_filters( 'the_title', $this->post_title, $this->ID );
263
	}
264
265
	/**
266
	 * Alias for get_title
267
	 *
268
	 * @return string
269
	 */
270
	public function title() {
271
		return $this->get_title();
272
	}
273
274
275
	/**
276
	 * Returns the post content with filters applied.
277
	 *
278
	 * @param  integer $page Page number, in case our post has <!--nextpage--> tags
279
	 * @return string        Post content
280
	 */
281
	public function get_content( $page = 0 ) {
282
		if ( 0 == $page && $this->post_content ) {
283
			return $this->post_content;
284
		}
285
286
		$content = $this->post_content;
287
288
		if ( $page ) {
289
			$contents = explode( '<!--nextpage-->', $content );
290
291
			$page--;
292
293
			if ( count( $contents ) > $page ) {
294
				$content = $contents[ $page ];
295
			}
296
		}
297
298
		$content = apply_filters( 'the_content', ($content) );
299
300
		return $content;
301
	}
302
303
304
	/**
305
	 * Alias for get_content
306
	 *
307
	 * @return string
308
	 */
309
	public function content() {
310
		return $this->get_content();
311
	}
312
313
	/**
314
	 * Returns post type object for current post
315
	 *
316
	 * @return object
317
	 */
318
	public function get_post_type() {
319
		return get_post_type_object( $this->post_type );
320
	}
321
322
	/**
323
	 * Returns post permalink
324
	 *
325
	 * @return string
326
	 */
327
	public function get_permalink() {
328
		if ( isset( $this->permalink ) ) {
329
			return $this->permalink;
330
		}
331
332
		$this->permalink = get_permalink( $this->ID );
333
334
		return $this->permalink;
335
	}
336
337
338
	/**
339
	 * Alias for get_permalink
340
	 *
341
	 * @return string
342
	 */
343
	public function permalink() {
344
		return $this->get_permalink();
345
	}
346
347
	/**
348
	 * Returns post preview of requested length.
349
	 * It will look for post_excerpt and will return it.
350
	 * If post contains <!-- more --> tag it will return content until it
351
	 *
352
	 * @param  integer $len      Number of words
353
	 * @param  boolean $force    If is set to true it will cut your post_excerpt to desired $len length
354
	 * @param  string  $readmore The text for 'readmore' link
355
	 * @param  boolean $strip    Should we strip tags?
356
	 * @return string            Post preview
357
	 */
358
	public function get_preview( $len = 50, $force = false, $readmore = 'Read More', $strip = true ) {
359
		$text = '';
360
		$trimmed = false;
361
362
		if ( isset( $this->post_excerpt ) && strlen( $this->post_excerpt ) ) {
363
364
			if ( $force ) {
365
				$text = ClassyHelper::trim_words( $this->post_excerpt, $len, false );
366
				$trimmed = true;
367
			} else {
368
				$text = $this->post_excerpt;
369
			}
370
		}
371
372
		if ( ! strlen( $text ) && preg_match( '/<!--\s?more(.*?)?-->/', $this->post_content, $readmore_matches ) ) {
373
374
			$pieces = explode( $readmore_matches[0], $this->post_content );
375
			$text = $pieces[0];
376
377
			if ( $force ) {
378
				$text = ClassyHelper::trim_words( $text, $len, false );
379
				$trimmed = true;
380
			}
381
382
			$text = do_shortcode( $text );
383
384
		}
385
386
		if ( ! strlen( $text ) ) {
387
388
			$text = ClassyHelper::trim_words( $this->get_content(), $len, false );
389
			$trimmed = true;
390
391
		}
392
393
		if ( ! strlen( trim( $text ) ) ) {
394
395
			return trim( $text );
396
397
		}
398
399
		if ( $strip ) {
400
401
			$text = trim( strip_tags( $text ) );
402
403
		}
404
405
		if ( strlen( $text ) ) {
406
407
			$text = trim( $text );
408
			$last = $text[ strlen( $text ) - 1 ];
409
410
			if ( '.' != $last && $trimmed ) {
411
				$text .= ' &hellip; ';
412
			}
413
414
			if ( ! $strip ) {
415
				$last_p_tag = strrpos( $text, '</p>' );
416
				if ( false !== $last_p_tag ) {
417
					$text = substr( $text, 0, $last_p_tag );
418
				}
419
				if ( '.' != $last && $trimmed ) {
420
					$text .= ' &hellip; ';
421
				}
422
			}
423
424
			if ( $readmore && isset( $readmore_matches ) && ! empty( $readmore_matches[1] ) ) {
425
				$text .= ' <a href="' . $this->get_permalink() . '" class="read-more">' . trim( $readmore_matches[1] ) . '</a>';
426
			} elseif ( $readmore ) {
427
				$text .= ' <a href="' . $this->get_permalink() . '" class="read-more">' . trim( $readmore ) . '</a>';
428
			}
429
430
			if ( ! $strip ) {
431
				$text .= '</p>';
432
			}
433
		}
434
435
		return trim( $text );
436
	}
437
438
	/**
439
	 * Returns comments array
440
	 * @return array
441
	 */
442
	public function get_comments( $status = 'approve', $order = 'DESC' ) {
443
444
		$_return = array();
445
446
		$args = array(
447
			'post_id' => $this->ID,
448
			'status' => $status,
449
			'order' => $order,
450
		);
451
452
		$comments = get_comments( $args );
453
454
		foreach ( $comments as $comment ) {
455
456
			$_return[ $comment->comment_ID ] = new ClassyComment( $comment );
457
458
		}
459
460
		foreach ( $_return as $key => $comment ) {
461
462
			if ( $comment->has_parent() ) {
463
464
				$_return[ $comment->comment_parent ]->add_child( $comment );
465
466
				unset( $_return[ $key ] );
467
468
			}
469
		}
470
471
		return array_values( $_return );
472
473
	}
474
}
475