PluginProbe
LearnPress – WordPress LMS Plugin for Create and Sell Online Courses / 4.4.9
LearnPress – WordPress LMS Plugin for Create and Sell Online Courses v4.4.9
4.4.9 4.4.8 4.4.7 4.4.6 4.4.5 4.4.4 4.4.3 4.4.2 4.4.1 4.4.0 4.3.9.1 4.3.9 4.3.8 4.3.7 4.1.6.9 4.1.6.9.1 4.1.6.9.2 4.1.6.9.3 4.1.6.9.4 4.1.7 4.1.7.1 4.1.7.2 4.1.7.3 4.1.7.3.1 4.1.7.3.2 All 140 releases
learnpress / inc / Models / PostModel.php

PostModel.php in LearnPress – WordPress LMS Plugin for Create and Sell Online Courses 4.4.9, at inc/Models/PostModel.php

660 lines 15.5 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 /**
4 * Class Course
5 * To replace class LP_User_Item
6 *
7 * @package LearnPress/Classes
8 * @version 1.0.8
9 * @since 4.2.6.9
10 */
11
12 namespace LearnPress\Models;
13
14 use Exception;
15 use LearnPress;
16 use LearnPress\Databases\PostDB;
17 use LearnPress\Filters\FilterBase;
18 use LearnPress\Filters\PostFilter;
19 use LearnPress\Services\CourseService;
20 use LP_Cache;
21 use LP_Debug;
22 use LP_Post_Meta_DB;
23 use LP_Post_Meta_Filter;
24 use LP_Post_Type_Filter;
25
26 use stdClass;
27 use Throwable;
28 use WP_Error;
29 use WP_Post;
30 use WP_Term;
31
32 defined( 'ABSPATH' ) || exit();
33
34 class PostModel {
35 /**
36 * Auto increment, Primary key
37 *
38 * @var int
39 */
40 public $ID = 0;
41 public $post_author = 0;
42 public $post_date = null;
43 public $post_date_gmt = null;
44 public $post_modified = null;
45 public $post_modified_gmt = null;
46 public $post_content = '';
47 public $post_title = '';
48 public $post_excerpt = '';
49 public $post_status = '';
50 public $post_password = '';
51 public $post_name = '';
52 public $post_type = 'post';
53 public $post_parent = 0;
54 /**
55 * @var stdClass all meta data
56 */
57 public $meta_data = null;
58 /**
59 * @var stdClass all meta data
60 */
61 public $is_got_meta_data;
62 /**
63 * @var string only for set same property with class WP_Post
64 */
65 public $filter;
66
67 const STATUS_PUBLISH = 'publish';
68 const STATUS_TRASH = 'trash';
69 const STATUS_DRAFT = 'draft';
70 const STATUS_PRIVATE = 'private';
71 const STATUS_PENDING = 'pending';
72 const STATUS_FEATURE = 'future';
73 const STATUS_AUTO_DRAFT = 'auto-draft';
74 const VISIBILITY_PASSWORD = 'password';
75
76 /**
77 * If data get from database, map to object.
78 * Else create new object to save data to database.
79 *
80 * @param array|object|mixed $data
81 */
82 public function __construct( $data = null ) {
83 if ( $data ) {
84 $this->map_to_object( $data );
85 }
86
87 $this->get_metadata();
88 }
89
90 /**
91 * Get user model
92 *
93 * @return false|UserModel
94 * @since 4.2.6.9
95 * @version 1.0.1
96 */
97 public function get_author_model() {
98 if ( ! empty( $this->post_author ) ) {
99 $author_id = $this->post_author;
100 } else {
101 $author_id = get_post_field( 'post_author', $this );
102 }
103
104 return UserModel::find( $author_id, true );
105 }
106
107 /**
108 * Map array, object data to PostModel.
109 * Use for data get from database.
110 *
111 * @param array|object|mixed $data
112 *
113 * @return PostModel|static
114 */
115 public function map_to_object( $data ): PostModel {
116 foreach ( $data as $key => $value ) {
117 if ( property_exists( $this, $key ) ) {
118 $this->{$key} = $value;
119 }
120 }
121
122 return $this;
123 }
124
125 /**
126 * Get post course by ID
127 *
128 * @param int $post_id
129 * @param bool $check_cache
130 *
131 * @return false|PostModel
132 * @version 1.0.1
133 * @since 4.3.2
134 */
135 public static function find_by_id( int $post_id, bool $check_cache = false ) {
136 $filter = new PostFilter();
137 $filter->ID = $post_id;
138 $filter->post_type = ( new static() )->post_type;
139
140 $type = ( new static() )->post_type;
141 $key_cache = "postModel/find/{$post_id}/" . $type;
142 $lp_cache = new LP_Cache();
143
144 // Check first load cache
145 $postModel = LP_Cache::cache_load_first( 'get', $key_cache );
146 if ( false !== $postModel ) {
147 return $postModel;
148 }
149
150 // Check cache
151 if ( $check_cache ) {
152 $postModel = $lp_cache->get_cache( $key_cache );
153 if ( $postModel instanceof PostModel ) {
154 return $postModel;
155 }
156 }
157
158 $postModel = self::get_item_model_from_db( $filter );
159 // Set cache
160 if ( $postModel instanceof PostModel ) {
161 $lp_cache->set_cache( $key_cache, $postModel );
162 }
163 LP_Cache::cache_load_first( 'set', $key_cache, $postModel );
164
165 return $postModel;
166 }
167
168 /**
169 * Get post from database.
170 * If not exists, return false.
171 * If exists, return PostModel.
172 *
173 * @param LP_Post_Type_Filter|FilterBase $filter
174 *
175 * @return PostModel|false|static
176 * @version 1.0.2
177 */
178 public static function get_item_model_from_db( $filter ) {
179 $lp_post_db = PostDB::getInstance();
180 $post_model = false;
181
182 try {
183 if ( empty( $filter->post_type ) ) {
184 $filter->post_type = ( new static() )->post_type;
185 }
186
187 $lp_post_db->get_query_single_row( $filter );
188 $query_single_row = $lp_post_db->get_posts( $filter );
189 $post_rs = $lp_post_db->wpdb->get_row( $query_single_row );
190
191 if ( $post_rs instanceof stdClass ) {
192 $post_model = new static( $post_rs );
193 }
194 } catch ( Throwable $e ) {
195 LP_Debug::error_log( $e );
196 }
197
198 return $post_model;
199 }
200
201 /**
202 * Return object metadata
203 *
204 * @return stdClass
205 * @since 4.4.8.1
206 * @version 1.0.0
207 */
208 public function get_metadata(): stdClass {
209 if ( is_null( $this->meta_data ) ) {
210 $this->meta_data = new stdClass();
211 }
212
213 return $this->meta_data;
214 }
215
216 /**
217 * Get all meta_data, all keys of a user it
218 *
219 * @return stdClass|null
220 * @throws Exception
221 * @version 1.0.1
222 * @since 4.2.6.9
223 */
224 public function get_all_metadata() {
225 if ( ! isset( $this->is_got_meta_data ) ) {
226 $lp_item_meta_db = LP_Post_Meta_DB::getInstance();
227 $filter = new LP_Post_Meta_Filter();
228 $filter->post_id = $this->get_id();
229 $filter->run_query_count = false;
230 $filter->limit = - 1;
231
232 $metadata_rs = $lp_item_meta_db->get_post_metas( $filter );
233 if ( ! $metadata_rs instanceof stdClass ) {
234 $this->meta_data = new stdClass();
235 foreach ( $metadata_rs as $value ) {
236 $this->meta_data->{$value->meta_key} = maybe_unserialize( $value->meta_value );
237 }
238 }
239
240 $this->is_got_meta_data = 1;
241 }
242
243 return $this->meta_data;
244 }
245
246 /**
247 * Check capabilities to create new post.
248 *
249 * @return bool
250 * @since 4.2.9.4
251 * @version 1.0.1
252 */
253 public function check_capabilities_create(): bool {
254 //return current_user_can( 'edit_' . $this->post_type . 's' );
255 return true;
256 }
257
258 /**
259 * Check capabilities to update post.
260 *
261 * @return bool
262 * @since 4.2.9.4
263 * @version 1.0.1
264 */
265 public function check_capabilities_update(): bool {
266 //return current_user_can( 'edit_' . $this->post_type, $this->ID );
267 return true;
268 }
269
270 /**
271 * Check capabilities of item's course.
272 * Check user current can edit it.
273 *
274 * @return void
275 * @throws Exception
276 * @version 1.0.1
277 * @since 4.2.9
278 */
279 public function check_capabilities_create_item_course() {
280 $user = wp_get_current_user();
281 if ( ! user_can( $user, 'edit_' . LP_LESSON_CPT . 's' ) ) {
282 throw new Exception( __( 'You do not have permission to create item.', 'learnpress' ) );
283 }
284 }
285
286 /**
287 * Check capabilities of item's course.
288 * Check user current can edit it.
289 *
290 * @return void
291 * @throws Exception
292 * @version 1.0.1
293 * @since 4.2.9
294 */
295 public function check_capabilities_update_item_course() {
296 $user = wp_get_current_user();
297 if ( ! user_can( $user, 'edit_' . LP_LESSON_CPT, $this->ID ) ) {
298 throw new Exception( __( 'You do not have permission to edit this item.', 'learnpress' ) );
299 }
300 }
301
302 /**
303 * Update data to database.
304 *
305 * If user_item_id is empty, insert new data, else update data.
306 *
307 * @throws Exception
308 * @since 4.2.5
309 * @version 1.0.6
310 */
311 public function save( bool $force_save = false ) {
312 $data = get_object_vars( $this );
313
314 $metadata = $this->get_metadata();
315 if ( ! empty( $metadata ) ) {
316 $data['meta_input'] = [];
317 foreach ( $metadata as $key_meta => $value_meta ) {
318 $data['meta_input'][ $key_meta ] = $value_meta;
319 }
320 }
321
322 // Check if exists course id.
323 if ( empty( $this->ID ) ) { // Insert data.
324 // Check permission
325 if ( ! $force_save ) {
326 if ( CourseService::check_is_item_type_of_course( $this->post_type )
327 || LP_QUESTION_CPT === $this->post_type ) {
328 $this->check_capabilities_create_item_course();
329 } elseif ( ! $this->check_capabilities_create() ) {
330 throw new Exception( __( 'You do not have permission to create item.', 'learnpress' ) );
331 }
332 }
333
334 unset( $data['ID'] );
335 $post_id = wp_insert_post( $data, true );
336 } else { // Update data.
337 // Check permission
338 if ( ! $force_save ) {
339 if ( courseservice::check_is_item_type_of_course( $this->post_type )
340 || LP_QUESTION_CPT === $this->post_type ) {
341 $this->check_capabilities_update_item_course();
342 } elseif ( ! $this->check_capabilities_update() ) {
343 throw new exception( __( 'you do not have permission to edit this item.', 'learnpress' ) );
344 }
345 }
346
347 $post_id = wp_update_post( $data, true );
348 }
349
350 if ( is_wp_error( $post_id ) ) {
351 throw new Exception( $post_id->get_error_message() );
352 } else {
353 $this->ID = $post_id;
354 }
355
356 $post = get_post( $this->ID );
357 foreach ( get_object_vars( $post ) as $property => $value ) {
358 // If property is not exists in PostModel, skip it.
359 if ( ! property_exists( $this, $property ) ) {
360 continue;
361 }
362 $this->{$property} = $value;
363 }
364
365 $this->clean_caches();
366 }
367
368 /**
369 * Delete row
370 *
371 * @throws Exception
372 * @since 4.3.6
373 * @version 1.0.0
374 */
375 public function delete() {
376 wp_delete_post( $this->get_id(), true );
377
378 // Clear cache
379 $this->clean_caches();
380 }
381
382 /**
383 * Clean caches.
384 *
385 * @return void
386 */
387 public function clean_caches() {
388 // Clear cache.
389 }
390
391 /**
392 * @return int
393 */
394 public function get_id(): int {
395 return (int) $this->ID;
396 }
397
398 /**
399 * Get image url of post.
400 *
401 * @param string|int[] $size
402 *
403 * @return string
404 * @since 4.2.6.9
405 * @version 1.0.3
406 */
407 public function get_image_url( $size = 'post-thumbnail' ): string {
408 $image_url = '';
409
410 if ( has_post_thumbnail( $this ) ) {
411 if ( is_string( $size ) ) {
412 $image_url = get_the_post_thumbnail_url( $this, $size );
413 } elseif ( is_array( $size ) && count( $size ) === 2 ) {
414 // Check file crop is existing.
415 $attachment_id = get_post_thumbnail_id( $this );
416 $file_path = get_attached_file( $attachment_id );
417 $file_url = wp_get_attachment_url( $attachment_id );
418 $upload_dir = wp_upload_dir();
419 $base_dir = $upload_dir['basedir'];
420
421 // Get file path with size.
422 $file_path_arr = explode( '.', $file_path );
423 $file_path_length = count( $file_path_arr );
424 $extension = end( $file_path_arr );
425 unset( $file_path_arr[ $file_path_length - 1 ] );
426 $file_path_join = implode( '.', $file_path_arr );
427 $file_path_with_size = $file_path_join . '-' . $size[0] . 'x' . $size[1] . '.' . $extension;
428 if ( file_exists( $file_path_with_size ) ) {
429 $file_url_arr = explode( '.', $file_url );
430 $file_url_length = count( $file_url_arr );
431 $url_extension = end( $file_url_arr );
432 unset( $file_url_arr[ $file_url_length - 1 ] );
433 $file_url_join = implode( '.', $file_url_arr );
434 $image_url = $file_url_join . '-' . $size[0] . 'x' . $size[1] . '.' . $url_extension;
435 } else {
436 // Custom crop size for image.
437 $resized_file = wp_get_image_editor( $file_path );
438
439 if ( ! is_wp_error( $resized_file ) ) {
440 $resized_file->resize( $size[0], $size[1], true );
441 $resized_image = $resized_file->save( $file_path_with_size );
442
443 if ( ! is_wp_error( $resized_image ) ) {
444 // Build the URL for the resized image
445 $imag_dir = $resized_image['path'];
446 $imag_dir = str_replace( $base_dir, '', $imag_dir );
447 $image_url = $upload_dir['baseurl'] . $imag_dir;
448 }
449 }
450 }
451 }
452 }
453
454 if ( empty( $image_url ) ) {
455 $image_url = LearnPress::instance()->image( 'no-image.png' );
456 }
457
458 return $image_url;
459 }
460
461 /**
462 * Get meta value by key.
463 *
464 * @param string $key
465 * @param mixed $default_value
466 * @param bool $single
467 *
468 * @return false|mixed
469 * @since 4.2.6.9
470 * @version 1.0.3
471 */
472 public function get_meta_value_by_key( string $key, $default_value = false, bool $single = true ) {
473 $metadata = $this->get_metadata();
474 if ( isset( $metadata->{$key} ) ) {
475 return maybe_unserialize( $metadata->{$key} );
476 }
477
478 $value = get_post_meta( $this->ID, $key, $single );
479 if ( empty( $value ) ) {
480 $value = $default_value;
481 }
482
483 $value = maybe_unserialize( $value );
484 $this->set_meta_value_by_key( $key, $value );
485
486 return $value;
487 }
488
489 /**
490 * Set meta value by key
491 *
492 * @param string $key
493 * @param mixed $value
494 *
495 * @since 4.4.8.1
496 * @version 1.0.0
497 * @return void
498 */
499 public function set_meta_value_by_key( string $key, $value ) {
500 $metadata = $this->get_metadata();
501 $metadata->{$key} = $value;
502
503 $this->meta_data = $metadata;
504 }
505
506 /**
507 * Get meta value by key.
508 *
509 * @param string $key
510 * @param mixed $value
511 * @param bool $fore_update
512 *
513 * @return void
514 * @throws Exception
515 * @since 4.2.6.9
516 * @version 1.0.4
517 */
518 public function save_meta_value_by_key( string $key, $value, bool $fore_update = false ) {
519 // Check permission
520 if ( ! $fore_update ) {
521 // Check permission if is item type of course
522 if ( CourseService::check_is_item_type_of_course( $this->post_type )
523 || LP_QUESTION_CPT === $this->post_type ) {
524 $this->check_capabilities_update_item_course();
525 } elseif ( ! $this->check_capabilities_update() ) {
526 throw new Exception( __( 'You do not have permission to edit this item.', 'learnpress' ) );
527 }
528 }
529
530 $this->set_meta_value_by_key( $key, $value );
531 update_post_meta( $this->ID, $key, $value );
532 }
533
534 /**
535 * Get categories of course.
536 *
537 * @return array|WP_Term[]
538 * @version 1.0.1
539 * @since 4.2.3
540 */
541 public function get_categories(): array {
542 $wpPost = new WP_Post( $this );
543 $categories = get_the_terms( $wpPost, LP_COURSE_CATEGORY_TAX );
544 if ( ! $categories || $categories instanceof WP_Error ) {
545 $categories = array();
546 }
547
548 return $categories;
549 }
550
551 /**
552 * Get tags of course.
553 *
554 * @return array|WP_Term[]
555 * @version 1.0.1
556 * @since 4.2.7.2
557 */
558 public function get_tags(): array {
559 $wpPost = new WP_Post( $this );
560 $tags = get_the_terms( $wpPost, LP_COURSE_TAXONOMY_TAG );
561 if ( ! $tags || $tags instanceof WP_Error ) {
562 $tags = array();
563 }
564
565 return $tags;
566 }
567
568 /**
569 * Get permalink of post
570 *
571 * @return string
572 */
573 public function get_permalink(): string {
574 $permalink = get_permalink( $this );
575 if ( empty( $permalink ) ) {
576 $permalink = '';
577 }
578
579 return $permalink;
580 }
581
582 /**
583 * Get the content of WP
584 *
585 * @return string
586 */
587 public function get_the_content(): string {
588 $content = get_the_content( null, false, $this );
589 $content = apply_filters( 'the_content', $content );
590 $content = str_replace( ']]>', ']]&gt;', $content );
591
592 return $content;
593 }
594
595 /**
596 * Get excerpt of WP
597 *
598 * @return string
599 */
600 public function get_the_excerpt(): string {
601 $content = get_the_excerpt( $this );
602
603 return $content;
604 }
605
606 /**
607 * Get title of course
608 *
609 * @return string
610 */
611 public function get_the_title(): string {
612 return get_the_title( $this );
613 }
614
615 /**
616 * Get edit link of post
617 *
618 * @return string|null
619 * @since 4.2.7.4
620 * @version 1.0.1
621 */
622 public function get_edit_link() {
623 return admin_url( "post.php?post=$this->ID&action=edit" );
624 /**
625 * Not using get_edit_post_link() because it may not return the correct link in some cases
626 * get_post_type_object is null.
627 */
628 //return get_edit_post_link( $this->get_id() );
629 }
630
631 /**
632 * Get i18n status
633 *
634 * @return string
635 */
636 public function get_status_i18n(): string {
637 switch ( $this->post_status ) {
638 case self::STATUS_PUBLISH:
639 return __( 'Published', 'learnpress' );
640 case self::STATUS_FEATURE:
641 return __( 'Scheduled', 'learnpress' );
642 case self::STATUS_TRASH:
643 return __( 'Trash', 'learnpress' );
644 case self::STATUS_DRAFT:
645 return __( 'Draft', 'learnpress' );
646 case self::STATUS_PRIVATE:
647 return __( 'Private', 'learnpress' );
648 case self::STATUS_PENDING:
649 return __( 'Pending', 'learnpress' );
650 case self::STATUS_AUTO_DRAFT:
651 return __( 'Auto Draft', 'learnpress' );
652 case self::VISIBILITY_PASSWORD:
653 return __( 'Protected', 'learnpress' );
654
655 default:
656 return ucfirst( $this->post_status );
657 }
658 }
659 }
660