PluginProbe
LearnPress – WordPress LMS Plugin for Create and Sell Online Courses / 4.4.4
LearnPress – WordPress LMS Plugin for Create and Sell Online Courses v4.4.4
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.4.4, at inc/Models/PostModel.php

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