PluginProbe
LearnPress – WordPress LMS Plugin for Create and Sell Online Courses / 4.3.7
LearnPress – WordPress LMS Plugin for Create and Sell Online Courses v4.3.7
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 4.2.0 4.2.1 All 138 releases
learnpress / inc / Models / PostModel.php

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

631 lines 14.9 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 LP_Cache;
20 use LP_Post_Meta_DB;
21 use LP_Post_Meta_Filter;
22 use LP_Post_Type_Filter;
23
24 use stdClass;
25 use Throwable;
26 use WP_Error;
27 use WP_Post;
28 use WP_Term;
29
30 defined( 'ABSPATH' ) || exit();
31
32 class PostModel {
33 /**
34 * Auto increment, Primary key
35 *
36 * @var int
37 */
38 public $ID = 0;
39 public $post_author = 0;
40 public $post_date = null;
41 public $post_date_gmt = null;
42 public $post_modified = null;
43 public $post_modified_gmt = null;
44 public $post_content = '';
45 public $post_title = '';
46 public $post_excerpt = '';
47 public $post_status = '';
48 public $post_password = '';
49 public $post_name = '';
50 public $post_type = 'post';
51 public $post_parent = 0;
52 /**
53 * @var stdClass all meta data
54 */
55 public $meta_data = null;
56 /**
57 * @var stdClass all meta data
58 */
59 public $is_got_meta_data;
60 /**
61 * @var string only for set same property with class WP_Post
62 */
63 public $filter;
64
65 const STATUS_PUBLISH = 'publish';
66 const STATUS_TRASH = 'trash';
67 const STATUS_DRAFT = 'draft';
68 const STATUS_PRIVATE = 'private';
69 const STATUS_PENDING = 'pending';
70 const STATUS_FEATURE = 'future';
71 const STATUS_AUTO_DRAFT = 'auto-draft';
72 const VISIBILITY_PASSWORD = 'password';
73
74 /**
75 * If data get from database, map to object.
76 * Else create new object to save data to database.
77 *
78 * @param array|object|mixed $data
79 */
80 public function __construct( $data = null ) {
81 if ( $data ) {
82 $this->map_to_object( $data );
83 }
84
85 if ( is_null( $this->meta_data ) ) {
86 $this->meta_data = new stdClass();
87 }
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.0
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 $quizPostModel = $lp_cache->get_cache( $key_cache );
153 if ( $quizPostModel instanceof QuizPostModel ) {
154 return $quizPostModel;
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 error_log( __METHOD__ . ': ' . $e->getMessage() );
196 }
197
198 return $post_model;
199 }
200
201 /**
202 * Get all meta_data, all keys of a user it
203 *
204 * @return stdClass|null
205 * @throws Exception
206 * @version 1.0.1
207 * @since 4.2.6.9
208 */
209 public function get_all_metadata() {
210 if ( ! isset( $this->is_got_meta_data ) ) {
211 $lp_item_meta_db = LP_Post_Meta_DB::getInstance();
212 $filter = new LP_Post_Meta_Filter();
213 $filter->post_id = $this->get_id();
214 $filter->run_query_count = false;
215 $filter->limit = - 1;
216
217 $metadata_rs = $lp_item_meta_db->get_post_metas( $filter );
218 if ( ! $metadata_rs instanceof stdClass ) {
219 $this->meta_data = new stdClass();
220 foreach ( $metadata_rs as $value ) {
221 $this->meta_data->{$value->meta_key} = maybe_unserialize( $value->meta_value );
222 }
223 }
224
225 $this->is_got_meta_data = 1;
226 }
227
228 return $this->meta_data;
229 }
230
231 /**
232 * Check capabilities to create new post.
233 *
234 * @return bool
235 * @since 4.2.9.4
236 * @version 1.0.0
237 */
238 public function check_capabilities_create(): bool {
239 return true;
240 }
241
242 /**
243 * Check capabilities to update post.
244 *
245 * @return bool
246 * @since 4.2.9.4
247 * @version 1.0.0
248 */
249 public function check_capabilities_update(): bool {
250 return true;
251 }
252
253 /**
254 * Check capabilities of item's course.
255 * Check user current can edit it.
256 *
257 * @return void
258 * @throws Exception
259 * @version 1.0.0
260 * @since 4.2.9
261 */
262 public function check_capabilities_create_item_course() {
263 $course_item_types = CourseModel::item_types_support();
264 // Questions not type item of course, it is type item of quiz, but need check here.
265 $course_item_types[] = LP_QUESTION_CPT;
266 if ( ! in_array( $this->post_type, $course_item_types, true ) ) {
267 return;
268 }
269
270 $user = wp_get_current_user();
271 if ( ! user_can( $user, 'edit_' . LP_LESSON_CPT . 's' ) ) {
272 throw new Exception( __( 'You do not have permission to create item.', 'learnpress' ) );
273 }
274 }
275
276 /**
277 * Check capabilities of item's course.
278 * Check user current can edit it.
279 *
280 * @return void
281 * @throws Exception
282 * @version 1.0.0
283 * @since 4.2.9
284 */
285 public function check_capabilities_update_item_course() {
286 $course_item_types = CourseModel::item_types_support();
287 // Questions not type item of course, it is type item of quiz, but need check here.
288 $course_item_types[] = LP_QUESTION_CPT;
289 if ( ! in_array( $this->post_type, $course_item_types, true ) ) {
290 return;
291 }
292
293 $user = wp_get_current_user();
294 if ( ! user_can( $user, 'edit_' . LP_LESSON_CPT, $this->ID ) ) {
295 throw new Exception( __( 'You do not have permission to edit this item.', 'learnpress' ) );
296 }
297 }
298
299 /**
300 * Update data to database.
301 *
302 * If user_item_id is empty, insert new data, else update data.
303 *
304 * @throws Exception
305 * @since 4.2.5
306 * @version 1.0.4
307 */
308 public function save( bool $force_save = false ) {
309 $data = get_object_vars( $this );
310
311 if ( ! empty( $this->meta_data ) ) {
312 $data['meta_input'] = [];
313 foreach ( $this->meta_data as $key_meta => $value_meta ) {
314 $data['meta_input'][ $key_meta ] = $value_meta;
315 }
316 }
317
318 // Check if exists course id.
319 if ( empty( $this->ID ) ) { // Insert data.
320 // Check permission
321 if ( ! $force_save ) {
322 if ( ! $this->check_capabilities_create() ) {
323 throw new Exception( __( 'You do not have permission to create item.', 'learnpress' ) );
324 }
325
326 $this->check_capabilities_create_item_course();
327 }
328
329 unset( $data['ID'] );
330 $post_id = wp_insert_post( $data, true );
331 } else { // Update data.
332 // Check permission
333 if ( ! $force_save ) {
334 if ( ! $this->check_capabilities_update() ) {
335 throw new Exception( __( 'You do not have permission to edit this item.', 'learnpress' ) );
336 }
337
338 $this->check_capabilities_update_item_course();
339 }
340
341 $post_id = wp_update_post( $data, true );
342 }
343
344 if ( is_wp_error( $post_id ) ) {
345 throw new Exception( $post_id->get_error_message() );
346 } else {
347 $this->ID = $post_id;
348 }
349
350 $post = get_post( $this->ID );
351 foreach ( get_object_vars( $post ) as $property => $value ) {
352 // If property is not exists in PostModel, skip it.
353 if ( ! property_exists( $this, $property ) ) {
354 continue;
355 }
356 $this->{$property} = $value;
357 }
358
359 $this->clean_caches();
360 }
361
362 /**
363 * Delete row
364 *
365 * @throws Exception
366 * @since 4.3.6
367 * @version 1.0.0
368 */
369 public function delete() {
370 wp_delete_post( $this->get_id(), true );
371
372 // Clear cache
373 $this->clean_caches();
374 }
375
376 /**
377 * Clean caches.
378 *
379 * @return void
380 */
381 public function clean_caches() {
382 // Clear cache.
383 }
384
385 /**
386 * @return int
387 */
388 public function get_id(): int {
389 return (int) $this->ID;
390 }
391
392 /**
393 * Get image url of post.
394 *
395 * @param string|int[] $size
396 *
397 * @return string
398 * @since 4.2.6.9
399 * @version 1.0.3
400 */
401 public function get_image_url( $size = 'post-thumbnail' ): string {
402 $image_url = '';
403
404 if ( has_post_thumbnail( $this ) ) {
405 if ( is_string( $size ) ) {
406 $image_url = get_the_post_thumbnail_url( $this, $size );
407 } elseif ( is_array( $size ) && count( $size ) === 2 ) {
408 // Check file crop is existing.
409 $attachment_id = get_post_thumbnail_id( $this );
410 $file_path = get_attached_file( $attachment_id );
411 $file_url = wp_get_attachment_url( $attachment_id );
412 $upload_dir = wp_upload_dir();
413 $base_dir = $upload_dir['basedir'];
414
415 // Get file path with size.
416 $file_path_arr = explode( '.', $file_path );
417 $file_path_length = count( $file_path_arr );
418 $extension = end( $file_path_arr );
419 unset( $file_path_arr[ $file_path_length - 1 ] );
420 $file_path_join = implode( '.', $file_path_arr );
421 $file_path_with_size = $file_path_join . '-' . $size[0] . 'x' . $size[1] . '.' . $extension;
422 if ( file_exists( $file_path_with_size ) ) {
423 $file_url_arr = explode( '.', $file_url );
424 $file_url_length = count( $file_url_arr );
425 $url_extension = end( $file_url_arr );
426 unset( $file_url_arr[ $file_url_length - 1 ] );
427 $file_url_join = implode( '.', $file_url_arr );
428 $image_url = $file_url_join . '-' . $size[0] . 'x' . $size[1] . '.' . $url_extension;
429 } else {
430 // Custom crop size for image.
431 $resized_file = wp_get_image_editor( $file_path );
432
433 if ( ! is_wp_error( $resized_file ) ) {
434 $resized_file->resize( $size[0], $size[1], true );
435 $resized_image = $resized_file->save( $file_path_with_size );
436
437 if ( ! is_wp_error( $resized_image ) ) {
438 // Build the URL for the resized image
439 $imag_dir = $resized_image['path'];
440 $imag_dir = str_replace( $base_dir, '', $imag_dir );
441 $image_url = $upload_dir['baseurl'] . $imag_dir;
442 }
443 }
444 }
445 }
446 }
447
448 if ( empty( $image_url ) ) {
449 $image_url = LearnPress::instance()->image( 'no-image.png' );
450 }
451
452 return $image_url;
453 }
454
455 /**
456 * Get meta value by key.
457 *
458 * @param string $key
459 * @param mixed $default_value
460 * @param bool $single
461 *
462 * @return false|mixed
463 */
464 public function get_meta_value_by_key( string $key, $default_value = false, bool $single = true ) {
465 if ( $this->meta_data instanceof stdClass && isset( $this->meta_data->{$key} ) ) {
466 return maybe_unserialize( $this->meta_data->{$key} );
467 }
468
469 $value = get_post_meta( $this->ID, $key, $single );
470 if ( empty( $value ) ) {
471 $value = $default_value;
472 }
473
474 $value = maybe_unserialize( $value );
475 $this->meta_data->{$key} = $value;
476
477 return $value;
478 }
479
480 /**
481 * Get meta value by key.
482 *
483 * @param string $key
484 * @param mixed $value
485 * @param bool $fore_update
486 *
487 * @return void
488 * @throws Exception
489 * @since 4.2.6.9
490 * @version 1.0.3
491 */
492 public function save_meta_value_by_key( string $key, $value, bool $fore_update = false ) {
493 // Check permission
494 if ( ! $fore_update ) {
495 if ( ! $this->check_capabilities_update() ) {
496 throw new Exception( __( 'You do not have permission to edit this item.', 'learnpress' ) );
497 }
498 $this->check_capabilities_create_item_course();
499 }
500
501 $this->meta_data->{$key} = $value;
502 update_post_meta( $this->ID, $key, $value );
503 }
504
505 /**
506 * Get categories of course.
507 *
508 * @return array|WP_Term[]
509 * @version 1.0.1
510 * @since 4.2.3
511 */
512 public function get_categories(): array {
513 $wpPost = new WP_Post( $this );
514 $categories = get_the_terms( $wpPost, LP_COURSE_CATEGORY_TAX );
515 if ( ! $categories || $categories instanceof WP_Error ) {
516 $categories = array();
517 }
518
519 return $categories;
520 }
521
522 /**
523 * Get tags of course.
524 *
525 * @return array|WP_Term[]
526 * @version 1.0.1
527 * @since 4.2.7.2
528 */
529 public function get_tags(): array {
530 $wpPost = new WP_Post( $this );
531 $tags = get_the_terms( $wpPost, LP_COURSE_TAXONOMY_TAG );
532 if ( ! $tags || $tags instanceof WP_Error ) {
533 $tags = array();
534 }
535
536 return $tags;
537 }
538
539 /**
540 * Get permalink of post
541 *
542 * @return string
543 */
544 public function get_permalink(): string {
545 $permalink = get_permalink( $this );
546 if ( empty( $permalink ) ) {
547 $permalink = '';
548 }
549
550 return $permalink;
551 }
552
553 /**
554 * Get the content of WP
555 *
556 * @return string
557 */
558 public function get_the_content(): string {
559 $content = get_the_content( null, false, $this );
560 $content = apply_filters( 'the_content', $content );
561 $content = str_replace( ']]>', ']]&gt;', $content );
562
563 return $content;
564 }
565
566 /**
567 * Get excerpt of WP
568 *
569 * @return string
570 */
571 public function get_the_excerpt(): string {
572 $content = get_the_excerpt( $this );
573
574 return $content;
575 }
576
577 /**
578 * Get title of course
579 *
580 * @return string
581 */
582 public function get_the_title(): string {
583 return get_the_title( $this );
584 }
585
586 /**
587 * Get edit link of post
588 *
589 * @return string|null
590 * @since 4.2.7.4
591 * @version 1.0.1
592 */
593 public function get_edit_link() {
594 return admin_url( "post.php?post=$this->ID&action=edit" );
595 /**
596 * Not using get_edit_post_link() because it may not return the correct link in some cases
597 * get_post_type_object is null.
598 */
599 //return get_edit_post_link( $this->get_id() );
600 }
601
602 /**
603 * Get i18n status
604 *
605 * @return string
606 */
607 public function get_status_i18n(): string {
608 switch ( $this->post_status ) {
609 case self::STATUS_PUBLISH:
610 return __( 'Published', 'learnpress' );
611 case self::STATUS_FEATURE:
612 return __( 'Scheduled', 'learnpress' );
613 case self::STATUS_TRASH:
614 return __( 'Trash', 'learnpress' );
615 case self::STATUS_DRAFT:
616 return __( 'Draft', 'learnpress' );
617 case self::STATUS_PRIVATE:
618 return __( 'Private', 'learnpress' );
619 case self::STATUS_PENDING:
620 return __( 'Pending', 'learnpress' );
621 case self::STATUS_AUTO_DRAFT:
622 return __( 'Auto Draft', 'learnpress' );
623 case self::VISIBILITY_PASSWORD:
624 return __( 'Protected', 'learnpress' );
625
626 default:
627 return ucfirst( $this->post_status );
628 }
629 }
630 }
631