--- a/learnpress-course-review/inc/CourseReviewCache.php
+++ b/learnpress-course-review/inc/CourseReviewCache.php
@@ -1,92 +1,92 @@
-<?php
-
-namespace LearnPressCourseReview;
-
-use Exception;
-use LearnPressModelsCourseModel;
-use LearnPressModelsCoursePostModel;
-use LP_Addon_Course_Review;
-use LP_Addon_Course_Review_Preload;
-use LP_Cache;
-
-defined( 'ABSPATH' ) || exit();
-
-/**
- * Class CourseReviewCache
- *
- * @author tungnx
- * @since 4.2.2
- * @version 1.0.2
- */
-class CourseReviewCache extends LP_Cache {
- /**
- * @var string Key group child(external)
- */
- protected $key_group_child = 'course-rating';
-
- public function __construct( $has_thim_cache = false ) {
- parent::__construct( $has_thim_cache );
- }
-
- /**
- * Set rating.
- *
- * @param $course_id
- * @param $rating
- *
- * @return void
- */
- public function set_rating( $course_id, $rating ) {
- $this->set_cache( $course_id, $rating );
-
- $key_cache_first = "{$this->key_group}/{$course_id}";
- LP_Cache::cache_load_first( 'set', $key_cache_first, $rating );
- }
-
- /**
- * Get rating.
- *
- * @param $course_id
- *
- * @return array|false|mixed|string
- */
- public function get_rating( $course_id ) {
- $key_cache_first = "{$this->key_group}/{$course_id}";
- $total = LP_Cache::cache_load_first( 'get', $key_cache_first );
- if ( false !== $total ) {
- return $total;
- }
-
- $total = $this->get_cache( $course_id );
- LP_Cache::cache_load_first( 'set', $key_cache_first, $total );
-
- return $total;
- }
-
- /**
- * Clean cache rating
- * And calculate average rating for course
- *
- * @param int $course_id
- * @param int $user_id
- *
- * @return void
- * @throws Exception
- */
- public function clean_rating( int $course_id, int $user_id = 0 ) {
- $this->clear( $course_id );
- $key_cache_first = "{$this->key_group}/{$course_id}";
- LP_Cache::cache_load_first( 'clean', $key_cache_first );
-
- // Set average rating for course
- $rating = LP_Addon_Course_Review_Preload::$addon->get_rating_of_course( $course_id );
- LP_Addon_Course_Review::set_course_rating_average( $course_id, $rating['rated'] );
- $courseModel = CourseModel::find( $course_id, true );
- if ( $courseModel instanceof CourseModel ) {
- $courseModel->meta_data->{LP_Addon_Course_Review::META_KEY_RATING_AVERAGE} = $rating['rated'];
- $courseModel->save( true );
- }
- $key_cache_review = "user/{$user_id}/course/{$course_id}/review";
- $this->clear( $key_cache_review );
- }
-}
+<?php
+
+namespace LearnPressCourseReview;
+
+use Exception;
+use LearnPressModelsCourseModel;
+use LearnPressModelsCoursePostModel;
+use LP_Addon_Course_Review;
+use LP_Addon_Course_Review_Preload;
+use LP_Cache;
+
+defined( 'ABSPATH' ) || exit();
+
+/**
+ * Class CourseReviewCache
+ *
+ * @author tungnx
+ * @since 4.2.2
+ * @version 1.0.2
+ */
+class CourseReviewCache extends LP_Cache {
+ /**
+ * @var string Key group child(external)
+ */
+ protected $key_group_child = 'course-rating';
+
+ public function __construct( $has_thim_cache = false ) {
+ parent::__construct( $has_thim_cache );
+ }
+
+ /**
+ * Set rating.
+ *
+ * @param $course_id
+ * @param $rating
+ *
+ * @return void
+ */
+ public function set_rating( $course_id, $rating ) {
+ $this->set_cache( $course_id, $rating );
+
+ $key_cache_first = "{$this->key_group}/{$course_id}";
+ LP_Cache::cache_load_first( 'set', $key_cache_first, $rating );
+ }
+
+ /**
+ * Get rating.
+ *
+ * @param $course_id
+ *
+ * @return array|false|mixed|string
+ */
+ public function get_rating( $course_id ) {
+ $key_cache_first = "{$this->key_group}/{$course_id}";
+ $total = LP_Cache::cache_load_first( 'get', $key_cache_first );
+ if ( false !== $total ) {
+ return $total;
+ }
+
+ $total = $this->get_cache( $course_id );
+ LP_Cache::cache_load_first( 'set', $key_cache_first, $total );
+
+ return $total;
+ }
+
+ /**
+ * Clean cache rating
+ * And calculate average rating for course
+ *
+ * @param int $course_id
+ * @param int $user_id
+ *
+ * @return void
+ * @throws Exception
+ */
+ public function clean_rating( int $course_id, int $user_id = 0 ) {
+ $this->clear( $course_id );
+ $key_cache_first = "{$this->key_group}/{$course_id}";
+ LP_Cache::cache_load_first( 'clean', $key_cache_first );
+
+ // Set average rating for course
+ $rating = LP_Addon_Course_Review_Preload::$addon->get_rating_of_course( $course_id );
+ LP_Addon_Course_Review::set_course_rating_average( $course_id, $rating['rated'] );
+ $courseModel = CourseModel::find( $course_id, true );
+ if ( $courseModel instanceof CourseModel ) {
+ $courseModel->meta_data->{LP_Addon_Course_Review::META_KEY_RATING_AVERAGE} = $rating['rated'];
+ $courseModel->save( true );
+ }
+ $key_cache_review = "user/{$user_id}/course/{$course_id}/review";
+ $this->clear( $key_cache_review );
+ }
+}
--- a/learnpress-course-review/inc/TemplateHooks/CourseRatingTemplate.php
+++ b/learnpress-course-review/inc/TemplateHooks/CourseRatingTemplate.php
@@ -1,655 +1,655 @@
-<?php
-/**
- * LearnPress Coming Soon Hook Template
- *
- * @since 4.1.4
- * @version 1.0.0
- */
-
-namespace LearnPressCourseReviewTemplateHooks;
-
-use LearnPressHelpersSingleton;
-use LearnPressHelpersTemplate;
-use LearnPressModelsCourseModel;
-use LearnPressModelsUserItemsUserCourseModel;
-use LearnPressModelsUserModel;
-use LearnPressTemplateHooksTemplateAJAX;
-use LP_Addon_Course_Review;
-use LP_Addon_Course_Review_Preload;
-use LP_Datetime;
-use LP_Debug;
-use stdClass;
-use Throwable;
-use WP_Error;
-
-class CourseRatingTemplate {
- use Singleton;
-
- public $addon;
-
- public function init() {
- $this->addon = LP_Addon_Course_Review_Preload::$addon;
- add_action( 'learn-press/course-review/rating-reviews', array( $this, 'layout_rating_reviews' ), 10, 2 );
- add_filter( 'lp/rest/ajax/allow_callback', [ $this, 'allow_callback' ] );
- }
-
- /**
- * @uses CourseRatingTemplate::render_rating_reviews()
- * @uses CourseRatingTemplate::submit_review()
- *
- * @param $callbacks
- *
- * @return mixed
- */
- public function allow_callback( $callbacks ) {
- $callbacks[] = CourseRatingTemplate::class . ':render_rating_reviews';
- $callbacks[] = CourseRatingTemplate::class . ':submit_review';
-
- return $callbacks;
- }
-
- /**
- * Layout rating reviews
- *
- * @param CourseModel $courseModel
- * @param UserModel|false $userModel
- *
- * return void
- */
- public function layout_rating_reviews( CourseModel $courseModel, $userModel ) {
- wp_enqueue_script( 'course-review' );
- wp_enqueue_style( 'course-review' );
-
- $html_wrapper = [
- '<div class="lp-courses-rating-reviews-ajax">' => '</div>',
- ];
-
- /**
- * @uses self::render_rating_reviews()
- */
- $callback = [
- 'class' => CourseRatingTemplate::class,
- 'method' => 'render_rating_reviews',
- ];
- $args = [
- 'id_url' => 'course-rating-reviews',
- 'course_id' => $courseModel->get_id(),
- 'paged' => 1,
- ];
-
- $content = TemplateAJAX::load_content_via_ajax( $args, $callback );
-
- echo Template::instance()->nest_elements( $html_wrapper, $content );
- }
-
- /**
- * Add course rating to course archive page
- *
- * @param float|string $rated
- *
- * @return string
- */
- public function html_rated_star( $rated ): string {
- $percent = min( 100, (float) $rated * 20 );
-
- $html_item = '';
- for ( $i = 1; $i <= 5; $i++ ) {
- $with_star = $i * 20; // Css set 20px
- $percent_width = max( $with_star <= $percent ? 100 : ( $percent - ( $i - 1 ) * 20 ) * 5, 0 );
- $section_item = [
- 'wrapper' => '<div class="review-star">',
- 'far' => sprintf(
- '<em class="far lp-review-svg-star">%s</em>',
- LP_Addon_Course_Review::get_svg_star()
- ),
- 'fas' => sprintf(
- '<em class="fas lp-review-svg-star" style="width:%s;">%s</em>',
- "{$percent_width}%",
- LP_Addon_Course_Review::get_svg_star()
- ),
- 'wrapper_end' => '</div>',
- ];
-
- $html_item .= Template::combine_components( $section_item );
- }
-
- $section = [
- 'wrapper' => '<div class="review-stars-rated">',
- 'item' => $html_item,
- 'wrapper_end' => '</div>',
- ];
-
- return Template::combine_components( $section );
- }
-
- /**
- * Add course rating to course archive page
- *
- * @param CourseModel $courseModel
- *
- * @return string
- * @since 4.1.6
- * @version 1.0.0
- */
- public function html_average_rating( CourseModel $courseModel ): string {
- // Get from meta key, check after
- //$average = LP_Addon_Course_Review_Preload::$addon->get_average_rated( $courseModel );
-
- $course_rate_res = LP_Addon_Course_Review_Preload::$addon->get_rating_of_course( $courseModel->ID );
-
- $section = [
- 'wrapper' => '<div class="course-rate__summary">',
- 'value' => sprintf(
- '<div class="course-rate__summary-value">%s</div>',
- esc_html( number_format( $course_rate_res['rated'] ?? 0, 1 ) )
- ),
- 'star' => sprintf(
- '<div class="course-rate__summary-stars">%s</div>',
- $this->html_rated_star( $course_rate_res['rated'] )
- ),
- 'text' => sprintf(
- '<div class="course-rate__summary-text">%s</div>',
- sprintf(
- _n(
- '<span>%d</span> rating',
- '<span>%d</span> ratings',
- $course_rate_res['total'],
- 'learnpress-course-review'
- ),
- $course_rate_res['total']
- )
- ),
- 'wrapper_end' => '</div>',
- ];
-
- return Template::combine_components( $section );
- }
-
- /**
- * Show rating detail
- * Number rating of each star (1-5)
- *
- * @param CourseModel $courseModel
- *
- * @return string
- * @since 4.1.6
- * @version 1.0.0
- */
- public function html_rating_detail( CourseModel $courseModel ): string {
- $course_rate_res = LP_Addon_Course_Review_Preload::$addon->get_rating_of_course( $courseModel->ID );
- $html_items = '';
-
- $items = $course_rate_res['items'] ?? [];
- foreach ( $items as $item ) {
- $section_item = [
- 'wrapper' => '<div class="course-rate__details-row">',
- 'star' => sprintf(
- '<span class="course-rate__details-row-star">%s</span>',
- esc_html( $item['rated'] )
- ),
- 'fas' => sprintf(
- '<em class="fas lp-review-svg-star">%s</em>',
- LP_Addon_Course_Review::get_svg_star()
- ),
- 'percent' => sprintf(
- '<div class="course-rate__details-row-value">
- <div class="rating-gray"></div>
- <div class="rating" style="width:%s;">
- </div>
- </div>',
- esc_attr( $item['percent'] . '%' )
- ),
- 'rating-count' => sprintf(
- '<span class="rating-count">%s</span>',
- esc_html( $item['total'] )
- ),
- 'wrapper_end' => '</div>',
- ];
-
- $html_items .= Template::combine_components( $section_item );
- }
-
- $section = [
- 'wrapper' => '<div class="course-rate__details">',
- 'items' => $html_items,
- 'wrapper_end' => '</div>',
- ];
-
- return Template::combine_components( $section );
- }
-
- /**
- * @param CourseModel $courseModel
- * @param UserModel|false $userModel
- *
- * @return string
- */
- public function html_btn_review( CourseModel $courseModel, $userModel ): string {
- $html = '';
-
- try {
- if ( ! $userModel instanceof UserModel ) {
- return $html;
- }
-
- if ( ! LP_Addon_Course_Review_Preload::$addon->check_user_can_review_course( $userModel, $courseModel ) ) {
- return $html;
- }
-
- $section = [
- 'button' => sprintf(
- '<button class="write-a-review lp-button">%s</button>',
- esc_html__( 'Write a review', 'learnpress-course-review' )
- ),
- 'wrapper' => '<div class="course-review-wrapper">',
- 'form' => self::instance()->html_form_review( $courseModel, $userModel ),
- 'wrapper_end' => '</div>',
- ];
-
- $html = Template::combine_components( $section );
- } catch ( Throwable $e ) {
- LP_Debug::error_log( $e );
- }
-
- return $html;
- }
-
- /**
- * @param CourseModel $courseModel
- * @param UserModel $userModel
- *
- * @return string
- */
- public function html_form_review( CourseModel $courseModel, UserModel $userModel ): string {
- $html = '';
-
- try {
- if ( ! LP_Addon_Course_Review_Preload::$addon->check_user_can_review_course( $userModel, $courseModel ) ) {
- return $html;
- }
-
- $html_stars = '';
- for ( $i = 1; $i <= 5; $i++ ) {
- $html_stars .= sprintf(
- '<li class="choose-star" data-star="%d">
- <span>%s</span>
- </li>',
- $i,
- LP_Addon_Course_Review::get_svg_star()
- );
- }
- $html_stars = sprintf(
- '<ul class="review-stars">%s</ul>',
- $html_stars
- );
-
- $section = [
- 'form' => '<form class="review-form">',
- 'h4' => sprintf(
- '<h4>%s<a href="" class="close"><i class="lp-icon-close"></i></a></h4>',
- esc_html__( 'Write a review', 'learnpress-course-review' )
- ),
- 'fields' => '<ul class="review-fields">',
- 'field_title' => sprintf(
- '<li>
- <label>%s <span class="required">*</span></label>
- <input type="text" name="review_title"/>
- </li>',
- esc_html__( 'Title', 'learnpress-course-review' )
- ),
- 'field_content' => sprintf(
- '<li>
- <label>%s<span class="required">*</span></label>
- <textarea name="review_content"></textarea>
- </li>',
- esc_html__( 'Content', 'learnpress-course-review' )
- ),
- 'field_rating' => sprintf(
- '<li>
- <label>%s<span class="required">*</span></label>
- %s',
- esc_html__( 'Rating (click to choice)', 'learnpress-course-review' ),
- $html_stars
- ),
- 'field_actions' => sprintf(
- '<li class="review-actions">
- <button type="button" class="lp-button submit-review" data-id="%d">%s</button>
- <button type="button" class="lp-button close">%s</button>
- <span class="error"></span>
- </li>',
- $courseModel->get_id(),
- esc_html__( 'Add review', 'learnpress-course-review' ),
- esc_html__( 'Cancel', 'learnpress-course-review' )
- ),
- 'fields_hidden' => '<input type="hidden" name="rating" value="0">',
- 'fields_end' => '</ul>',
- 'form_end' => '</form>',
- ];
-
- $args = [
- 'id_url' => 'lp-submit-review-form',
- 'course_id' => $courseModel->get_id(),
- 'html_no_load_ajax_first' => Template::combine_components( $section ),
- ];
- /**
- * @uses self::submit_review()
- */
- $callback = [
- 'class' => CourseRatingTemplate::class,
- 'method' => 'submit_review',
- ];
-
- // Set args for ajax to submit review
- $html = TemplateAJAX::load_content_via_ajax( $args, $callback );
- } catch ( Throwable $e ) {
- LP_Debug::error_log( $e );
- }
-
- return $html;
- }
-
- /**
- * HTML for list reviews
- *
- * @param CourseModel $courseModel
- * @param UserModel|false $userModel
- * @param $settings
- *
- * @return string
- * @since 4.1.6
- * @version 1.0.1
- */
- public function html_list_reviews( CourseModel $courseModel, $userModel, $settings ): string {
- $html = '';
-
- try {
- $reviews_rs = $settings['reviews_rs'] ?? [];
- $total_pages = $reviews_rs['pages'] ?? 0;
-
- $html_items = '';
- $reviews = $reviews_rs['reviews'] ?? [];
- if ( empty( $reviews ) ) {
- return $html;
- }
-
- foreach ( $reviews as $review ) {
- $date_time_review = new LP_DateTime( $review->comment_date_gmt );
-
- $section_info = apply_filters(
- 'learn-press/course-review/list-reviews/item-info/section',
- [
- 'wrapper' => '<div class="review-content-right">',
- 'wrapper-info' => '<div class="review-info">',
- 'wrapper-author-rated' => '<div class="author-rated">',
- 'rated' => self::instance()->html_rated_star( $review->rate ?? 0 ),
- 'user-name' => sprintf(
- '<h4 class="user-name">%s</h4>',
- $review->display_name ?? ''
- ),
- 'wrapper-author-rated_end' => '</div>',
- 'date' => sprintf(
- '<div class="review-date">%s</div>',
- $date_time_review->format( LP_DateTime::I18N_FORMAT )
- ),
- 'wrapper-info_end' => '</div>',
- 'title' => sprintf(
- '<h5 class="course-review-title">%s</h5>',
- $review->title ?? ''
- ),
- 'content' => sprintf(
- '<div class="review-content">%s</div>',
- $review->content ?? ''
- ),
- 'wrapper_end' => '</div>',
- ],
- $review,
- $courseModel,
- $userModel,
- $settings
- );
-
- $section_item = [
- 'li' => '<li>',
- 'avatar' => sprintf(
- '<div class="review-author">%s</div>',
- get_avatar( $review->user_email ?? '' )
- ),
- 'info' => Template::combine_components( $section_info ),
- 'li_end' => '</li>',
- ];
-
- $html_items .= apply_filters(
- 'learn-press/course-review/list-reviews/item/section',
- Template::combine_components( $section_item ),
- $review,
- $courseModel,
- $userModel,
- $settings
- );
- }
-
- $section = apply_filters(
- 'learn-press/course-review/list-reviews/section',
- array(
- 'wrapper' => '<div class="course-reviews">',
- 'ul' => '<ul class="course-reviews-list">',
- 'reviews' => $html_items,
- 'ul_end' => '</ul>',
- 'btn_load_more' => $total_pages > 1 ? sprintf(
- '<button class="lp-button course-review-load-more"
- id="course-review-load-more">%s
- </button>',
- esc_html__( 'Load more', 'learnpress-course-review' )
- ) : '',
- 'wrapper_end' => '</div>',
- ),
- $courseModel,
- $userModel,
- $settings
- );
-
- $html = Template::combine_components( $section );
- } catch ( Throwable $e ) {
- LP_Debug::error_log( $e );
- }
-
- return $html;
- }
-
- /**
- * HTML for show message if user has submitted review and it is awaiting approve
- *
- * @param CourseModel $courseModel
- * @param UserModel|false $userModel
- *
- * @return string
- * @since 4.1.6
- * @version 1.0.1
- */
- public function html_unapprove( CourseModel $courseModel, $userModel ): string {
- $html = '';
-
- try {
- if ( ! $userModel instanceof UserModel ) {
- return $html;
- }
-
- // Get comments of user for course with comment_approved = 0
- $args = array(
- 'user_id' => $userModel->get_id(),
- 'post_ID' => $courseModel->get_id(),
- 'type' => 'review',
- 'status' => 'hold',
- );
- $comments_count = get_comments( $args );
-
- if ( ! empty( $comments_count ) ) {
- $html = sprintf(
- '<div class="learn-press-message success">%s</div>',
- __( 'Your review has been submitted and is awaiting approve.', 'learnpress-course-review' )
- );
- }
- } catch ( Throwable $e ) {
- LP_Debug::error_log( $e );
- }
-
- return $html;
- }
-
- /**
- * Get html tiny rating info
- *
- * @param CourseModel $course
- *
- * @return string
- * @since 4.1.6
- * @version 1.0.0
- */
- public function html_tiny_rating_info( CourseModel $course ): string {
- $html = '';
-
- try {
- $rating_info = LP_Addon_Course_Review_Preload::$addon->get_rating_of_course( $course->get_id() );
-
- wp_enqueue_style( 'course-review' );
-
- $html_star = sprintf(
- '<em class="fas lp-review-svg-star">%s</em>',
- LP_Addon_Course_Review::get_svg_star()
- );
- $html = sprintf(
- '<div class="item-meta">
- <div class="star-info">
- <span class="ico-star">%s</span><span class="info-rating">%d/%d</span> %s
- </div>
- </div>',
- $html_star,
- $rating_info['rated'],
- $rating_info['total'],
- _n( 'Rating', 'Ratings', $rating_info['total'], 'learnpress-course-review' )
- );
- } catch ( Throwable $e ) {
- LP_Debug::error_log( $e );
- }
-
- return $html;
- }
-
- /**
- * Render rating reviews
- *
- * @param CourseModel $courseModel
- * @param UserModel|false $userModel
- *
- * @return string
- * @since 4.1.6
- * @version 1.0.0
- */
- public function html_rating_reviews( CourseModel $courseModel, $userModel ): string {
- $html = '';
-
- try {
- ob_start();
- LP_Addon_Course_Review_Preload::$addon->add_course_tab_reviews_callback();
- $html_rating_reviews_main = ob_get_clean();
-
- $section = [
- 'wrapper' => '<div class="lp-rating-reviews-wrapper">',
- 'header' => sprintf(
- '<h3 class="item-title">%s</h3>',
- esc_html__( 'Reviews', 'learnpress-course-review' )
- ),
- 'content' => $html_rating_reviews_main,
- 'wrapper_end' => '</div>',
- ];
-
- $html = Template::combine_components( $section );
- } catch ( Throwable $e ) {
- LP_Debug::error_log( $e );
- }
-
- return $html;
- }
-
- /**
- * Render rating reviews
- *
- * @param array $settings
- *
- * @return stdClass
- * @since 4.1.6
- * @version 1.0.0
- */
- public static function render_rating_reviews( array $settings = [] ): stdClass {
- $content = new stdClass();
- $content->content = '';
-
- try {
- $course_id = $settings['course_id'] ?? 0;
- $user_id = $settings['user_id'] ?? get_current_user_id();
- $userModel = UserModel::find( $user_id, true );
- $courseModel = CourseModel::find( $course_id, true );
- if ( ! $courseModel instanceof CourseModel ) {
- return $content;
- }
-
- $paged = $settings['paged'] ?? 1;
- $reviews_rs = learn_press_get_course_review( $courseModel->get_id(), $paged );
- $total_pages = $reviews_rs['pages'] ?? 0;
- $settings['reviews_rs'] = $reviews_rs;
-
- $section_course_rate = [
- 'wrapper' => '<div class="course-rate">',
- 'average' => self::instance()->html_average_rating( $courseModel ),
- 'detail' => self::instance()->html_rating_detail( $courseModel ),
- 'wrapper_end' => '</div>',
- ];
-
- $section = [
- 'wrapper' => '<div class="learnpress-course-review lp-rating-reviews-wrapper">',
- 'header' => sprintf(
- '<h3 class="item-title">%s</h3>',
- esc_html__( 'Reviews', 'learnpress-course-review' )
- ),
- 'rate' => Template::combine_components( $section_course_rate ),
- 'btn-review' => self::instance()->html_btn_review( $courseModel, $userModel ),
- 'unapprove' => self::instance()->html_unapprove( $courseModel, $userModel ),
- 'reviews' => self::instance()->html_list_reviews( $courseModel, $userModel, $settings ),
- 'wrapper_end' => '</div>',
- ];
-
- $content->content = Template::combine_components( $section );
- $content->paged = $paged;
- $content->total_pages = $total_pages;
- } catch ( Throwable $e ) {
- LP_Debug::error_log( $e );
- }
-
- return $content;
- }
-
- /**
- * Submit review
- *
- * @param array $settings
- *
- * @return stdClass
- * @since 4.1.6
- * @version 1.0.0
- */
- public static function submit_review( array $settings = [] ) {
- $content = new stdClass();
- $content->status = 'error';
- $content->content = '';
- $settings['user_id'] = get_current_user_id();
- $submit_rs = LP_Addon_Course_Review_Preload::$addon->submit_review( $settings );
- if ( $submit_rs instanceof WP_Error ) {
- $content->content = $submit_rs->get_error_message();
- } else {
- $content->status = 'success';
- $content->content = __( 'Your review has been submitted and is awaiting approve.', 'learnpress-course-review' );
- }
-
- return $content;
- }
-}
+<?php
+/**
+ * LearnPress Coming Soon Hook Template
+ *
+ * @since 4.1.4
+ * @version 1.0.0
+ */
+
+namespace LearnPressCourseReviewTemplateHooks;
+
+use LearnPressHelpersSingleton;
+use LearnPressHelpersTemplate;
+use LearnPressModelsCourseModel;
+use LearnPressModelsUserItemsUserCourseModel;
+use LearnPressModelsUserModel;
+use LearnPressTemplateHooksTemplateAJAX;
+use LP_Addon_Course_Review;
+use LP_Addon_Course_Review_Preload;
+use LP_Datetime;
+use LP_Debug;
+use stdClass;
+use Throwable;
+use WP_Error;
+
+class CourseRatingTemplate {
+ use Singleton;
+
+ public $addon;
+
+ public function init() {
+ $this->addon = LP_Addon_Course_Review_Preload::$addon;
+ add_action( 'learn-press/course-review/rating-reviews', array( $this, 'layout_rating_reviews' ), 10, 2 );
+ add_filter( 'lp/rest/ajax/allow_callback', [ $this, 'allow_callback' ] );
+ }
+
+ /**
+ * @uses CourseRatingTemplate::render_rating_reviews()
+ * @uses CourseRatingTemplate::submit_review()
+ *
+ * @param $callbacks
+ *
+ * @return mixed
+ */
+ public function allow_callback( $callbacks ) {
+ $callbacks[] = CourseRatingTemplate::class . ':render_rating_reviews';
+ $callbacks[] = CourseRatingTemplate::class . ':submit_review';
+
+ return $callbacks;
+ }
+
+ /**
+ * Layout rating reviews
+ *
+ * @param CourseModel $courseModel
+ * @param UserModel|false $userModel
+ *
+ * return void
+ */
+ public function layout_rating_reviews( CourseModel $courseModel, $userModel ) {
+ wp_enqueue_script( 'course-review' );
+ wp_enqueue_style( 'course-review' );
+
+ $html_wrapper = [
+ '<div class="lp-courses-rating-reviews-ajax">' => '</div>',
+ ];
+
+ /**
+ * @uses self::render_rating_reviews()
+ */
+ $callback = [
+ 'class' => CourseRatingTemplate::class,
+ 'method' => 'render_rating_reviews',
+ ];
+ $args = [
+ 'id_url' => 'course-rating-reviews',
+ 'course_id' => $courseModel->get_id(),
+ 'paged' => 1,
+ ];
+
+ $content = TemplateAJAX::load_content_via_ajax( $args, $callback );
+
+ echo Template::instance()->nest_elements( $html_wrapper, $content );
+ }
+
+ /**
+ * Add course rating to course archive page
+ *
+ * @param float|string $rated
+ *
+ * @return string
+ */
+ public function html_rated_star( $rated ): string {
+ $percent = min( 100, (float) $rated * 20 );
+
+ $html_item = '';
+ for ( $i = 1; $i <= 5; $i++ ) {
+ $with_star = $i * 20; // Css set 20px
+ $percent_width = max( $with_star <= $percent ? 100 : ( $percent - ( $i - 1 ) * 20 ) * 5, 0 );
+ $section_item = [
+ 'wrapper' => '<div class="review-star">',
+ 'far' => sprintf(
+ '<em class="far lp-review-svg-star">%s</em>',
+ LP_Addon_Course_Review::get_svg_star()
+ ),
+ 'fas' => sprintf(
+ '<em class="fas lp-review-svg-star" style="width:%s;">%s</em>',
+ "{$percent_width}%",
+ LP_Addon_Course_Review::get_svg_star()
+ ),
+ 'wrapper_end' => '</div>',
+ ];
+
+ $html_item .= Template::combine_components( $section_item );
+ }
+
+ $section = [
+ 'wrapper' => '<div class="review-stars-rated">',
+ 'item' => $html_item,
+ 'wrapper_end' => '</div>',
+ ];
+
+ return Template::combine_components( $section );
+ }
+
+ /**
+ * Add course rating to course archive page
+ *
+ * @param CourseModel $courseModel
+ *
+ * @return string
+ * @since 4.1.6
+ * @version 1.0.0
+ */
+ public function html_average_rating( CourseModel $courseModel ): string {
+ // Get from meta key, check after
+ //$average = LP_Addon_Course_Review_Preload::$addon->get_average_rated( $courseModel );
+
+ $course_rate_res = LP_Addon_Course_Review_Preload::$addon->get_rating_of_course( $courseModel->ID );
+
+ $section = [
+ 'wrapper' => '<div class="course-rate__summary">',
+ 'value' => sprintf(
+ '<div class="course-rate__summary-value">%s</div>',
+ esc_html( number_format( $course_rate_res['rated'] ?? 0, 1 ) )
+ ),
+ 'star' => sprintf(
+ '<div class="course-rate__summary-stars">%s</div>',
+ $this->html_rated_star( $course_rate_res['rated'] )
+ ),
+ 'text' => sprintf(
+ '<div class="course-rate__summary-text">%s</div>',
+ sprintf(
+ _n(
+ '<span>%d</span> rating',
+ '<span>%d</span> ratings',
+ $course_rate_res['total'],
+ 'learnpress-course-review'
+ ),
+ $course_rate_res['total']
+ )
+ ),
+ 'wrapper_end' => '</div>',
+ ];
+
+ return Template::combine_components( $section );
+ }
+
+ /**
+ * Show rating detail
+ * Number rating of each star (1-5)
+ *
+ * @param CourseModel $courseModel
+ *
+ * @return string
+ * @since 4.1.6
+ * @version 1.0.0
+ */
+ public function html_rating_detail( CourseModel $courseModel ): string {
+ $course_rate_res = LP_Addon_Course_Review_Preload::$addon->get_rating_of_course( $courseModel->ID );
+ $html_items = '';
+
+ $items = $course_rate_res['items'] ?? [];
+ foreach ( $items as $item ) {
+ $section_item = [
+ 'wrapper' => '<div class="course-rate__details-row">',
+ 'star' => sprintf(
+ '<span class="course-rate__details-row-star">%s</span>',
+ esc_html( $item['rated'] )
+ ),
+ 'fas' => sprintf(
+ '<em class="fas lp-review-svg-star">%s</em>',
+ LP_Addon_Course_Review::get_svg_star()
+ ),
+ 'percent' => sprintf(
+ '<div class="course-rate__details-row-value">
+ <div class="rating-gray"></div>
+ <div class="rating" style="width:%s;">
+ </div>
+ </div>',
+ esc_attr( $item['percent'] . '%' )
+ ),
+ 'rating-count' => sprintf(
+ '<span class="rating-count">%s</span>',
+ esc_html( $item['total'] )
+ ),
+ 'wrapper_end' => '</div>',
+ ];
+
+ $html_items .= Template::combine_components( $section_item );
+ }
+
+ $section = [
+ 'wrapper' => '<div class="course-rate__details">',
+ 'items' => $html_items,
+ 'wrapper_end' => '</div>',
+ ];
+
+ return Template::combine_components( $section );
+ }
+
+ /**
+ * @param CourseModel $courseModel
+ * @param UserModel|false $userModel
+ *
+ * @return string
+ */
+ public function html_btn_review( CourseModel $courseModel, $userModel ): string {
+ $html = '';
+
+ try {
+ if ( ! $userModel instanceof UserModel ) {
+ return $html;
+ }
+
+ if ( ! LP_Addon_Course_Review_Preload::$addon->check_user_can_review_course( $userModel, $courseModel ) ) {
+ return $html;
+ }
+
+ $section = [
+ 'button' => sprintf(
+ '<button class="write-a-review lp-button">%s</button>',
+ esc_html__( 'Write a review', 'learnpress-course-review' )
+ ),
+ 'wrapper' => '<div class="course-review-wrapper">',
+ 'form' => self::instance()->html_form_review( $courseModel, $userModel ),
+ 'wrapper_end' => '</div>',
+ ];
+
+ $html = Template::combine_components( $section );
+ } catch ( Throwable $e ) {
+ LP_Debug::error_log( $e );
+ }
+
+ return $html;
+ }
+
+ /**
+ * @param CourseModel $courseModel
+ * @param UserModel $userModel
+ *
+ * @return string
+ */
+ public function html_form_review( CourseModel $courseModel, UserModel $userModel ): string {
+ $html = '';
+
+ try {
+ if ( ! LP_Addon_Course_Review_Preload::$addon->check_user_can_review_course( $userModel, $courseModel ) ) {
+ return $html;
+ }
+
+ $html_stars = '';
+ for ( $i = 1; $i <= 5; $i++ ) {
+ $html_stars .= sprintf(
+ '<li class="choose-star" data-star="%d">
+ <span>%s</span>
+ </li>',
+ $i,
+ LP_Addon_Course_Review::get_svg_star()
+ );
+ }
+ $html_stars = sprintf(
+ '<ul class="review-stars">%s</ul>',
+ $html_stars
+ );
+
+ $section = [
+ 'form' => '<form class="review-form">',
+ 'h4' => sprintf(
+ '<h4>%s<a href="" class="close"><i class="lp-icon-close"></i></a></h4>',
+ esc_html__( 'Write a review', 'learnpress-course-review' )
+ ),
+ 'fields' => '<ul class="review-fields">',
+ 'field_title' => sprintf(
+ '<li>
+ <label>%s <span class="required">*</span></label>
+ <input type="text" name="review_title"/>
+ </li>',
+ esc_html__( 'Title', 'learnpress-course-review' )
+ ),
+ 'field_content' => sprintf(
+ '<li>
+ <label>%s<span class="required">*</span></label>
+ <textarea name="review_content"></textarea>
+ </li>',
+ esc_html__( 'Content', 'learnpress-course-review' )
+ ),
+ 'field_rating' => sprintf(
+ '<li>
+ <label>%s<span class="required">*</span></label>
+ %s',
+ esc_html__( 'Rating (click to choice)', 'learnpress-course-review' ),
+ $html_stars
+ ),
+ 'field_actions' => sprintf(
+ '<li class="review-actions">
+ <button type="button" class="lp-button submit-review" data-id="%d">%s</button>
+ <button type="button" class="lp-button close">%s</button>
+ <span class="error"></span>
+ </li>',
+ $courseModel->get_id(),
+ esc_html__( 'Add review', 'learnpress-course-review' ),
+ esc_html__( 'Cancel', 'learnpress-course-review' )
+ ),
+ 'fields_hidden' => '<input type="hidden" name="rating" value="0">',
+ 'fields_end' => '</ul>',
+ 'form_end' => '</form>',
+ ];
+
+ $args = [
+ 'id_url' => 'lp-submit-review-form',
+ 'course_id' => $courseModel->get_id(),
+ 'html_no_load_ajax_first' => Template::combine_components( $section ),
+ ];
+ /**
+ * @uses self::submit_review()
+ */
+ $callback = [
+ 'class' => CourseRatingTemplate::class,
+ 'method' => 'submit_review',
+ ];
+
+ // Set args for ajax to submit review
+ $html = TemplateAJAX::load_content_via_ajax( $args, $callback );
+ } catch ( Throwable $e ) {
+ LP_Debug::error_log( $e );
+ }
+
+ return $html;
+ }
+
+ /**
+ * HTML for list reviews
+ *
+ * @param CourseModel $courseModel
+ * @param UserModel|false $userModel
+ * @param $settings
+ *
+ * @return string
+ * @since 4.1.6
+ * @version 1.0.2
+ */
+ public function html_list_reviews( CourseModel $courseModel, $userModel, $settings ): string {
+ $html = '';
+
+ try {
+ $reviews_rs = $settings['reviews_rs'] ?? [];
+ $total_pages = $reviews_rs['pages'] ?? 0;
+
+ $html_items = '';
+ $reviews = $reviews_rs['reviews'] ?? [];
+ if ( empty( $reviews ) ) {
+ return $html;
+ }
+
+ foreach ( $reviews as $review ) {
+ $date_time_review = new LP_DateTime( $review->comment_date_gmt );
+
+ $section_info = apply_filters(
+ 'learn-press/course-review/list-reviews/item-info/section',
+ [
+ 'wrapper' => '<div class="review-content-right">',
+ 'wrapper-info' => '<div class="review-info">',
+ 'wrapper-author-rated' => '<div class="author-rated">',
+ 'rated' => self::instance()->html_rated_star( $review->rate ?? 0 ),
+ 'user-name' => sprintf(
+ '<h4 class="user-name">%s</h4>',
+ $review->display_name ?? ''
+ ),
+ 'wrapper-author-rated_end' => '</div>',
+ 'date' => sprintf(
+ '<div class="review-date">%s</div>',
+ $date_time_review->format( LP_DateTime::I18N_FORMAT )
+ ),
+ 'wrapper-info_end' => '</div>',
+ 'title' => sprintf(
+ '<h5 class="course-review-title">%s</h5>',
+ wp_kses_post( $review->title ?? '' )
+ ),
+ 'content' => sprintf(
+ '<div class="review-content">%s</div>',
+ wp_kses_post( $review->content ?? '' )
+ ),
+ 'wrapper_end' => '</div>',
+ ],
+ $review,
+ $courseModel,
+ $userModel,
+ $settings
+ );
+
+ $section_item = [
+ 'li' => '<li>',
+ 'avatar' => sprintf(
+ '<div class="review-author">%s</div>',
+ get_avatar( $review->user_email ?? '' )
+ ),
+ 'info' => Template::combine_components( $section_info ),
+ 'li_end' => '</li>',
+ ];
+
+ $html_items .= apply_filters(
+ 'learn-press/course-review/list-reviews/item/section',
+ Template::combine_components( $section_item ),
+ $review,
+ $courseModel,
+ $userModel,
+ $settings
+ );
+ }
+
+ $section = apply_filters(
+ 'learn-press/course-review/list-reviews/section',
+ array(
+ 'wrapper' => '<div class="course-reviews">',
+ 'ul' => '<ul class="course-reviews-list">',
+ 'reviews' => $html_items,
+ 'ul_end' => '</ul>',
+ 'btn_load_more' => $total_pages > 1 ? sprintf(
+ '<button class="lp-button course-review-load-more"
+ id="course-review-load-more">%s
+ </button>',
+ esc_html__( 'Load more', 'learnpress-course-review' )
+ ) : '',
+ 'wrapper_end' => '</div>',
+ ),
+ $courseModel,
+ $userModel,
+ $settings
+ );
+
+ $html = Template::combine_components( $section );
+ } catch ( Throwable $e ) {
+ LP_Debug::error_log( $e );
+ }
+
+ return $html;
+ }
+
+ /**
+ * HTML for show message if user has submitted review and it is awaiting approve
+ *
+ * @param CourseModel $courseModel
+ * @param UserModel|false $userModel
+ *
+ * @return string
+ * @since 4.1.6
+ * @version 1.0.1
+ */
+ public function html_unapprove( CourseModel $courseModel, $userModel ): string {
+ $html = '';
+
+ try {
+ if ( ! $userModel instanceof UserModel ) {
+ return $html;
+ }
+
+ // Get comments of user for course with comment_approved = 0
+ $args = array(
+ 'user_id' => $userModel->get_id(),
+ 'post_ID' => $courseModel->get_id(),
+ 'type' => 'review',
+ 'status' => 'hold',
+ );
+ $comments_count = get_comments( $args );
+
+ if ( ! empty( $comments_count ) ) {
+ $html = sprintf(
+ '<div class="learn-press-message success">%s</div>',
+ __( 'Your review has been submitted and is awaiting approve.', 'learnpress-course-review' )
+ );
+ }
+ } catch ( Throwable $e ) {
+ LP_Debug::error_log( $e );
+ }
+
+ return $html;
+ }
+
+ /**
+ * Get html tiny rating info
+ *
+ * @param CourseModel $course
+ *
+ * @return string
+ * @since 4.1.6
+ * @version 1.0.0
+ */
+ public function html_tiny_rating_info( CourseModel $course ): string {
+ $html = '';
+
+ try {
+ $rating_info = LP_Addon_Course_Review_Preload::$addon->get_rating_of_course( $course->get_id() );
+
+ wp_enqueue_style( 'course-review' );
+
+ $html_star = sprintf(
+ '<em class="fas lp-review-svg-star">%s</em>',
+ LP_Addon_Course_Review::get_svg_star()
+ );
+ $html = sprintf(
+ '<div class="item-meta">
+ <div class="star-info">
+ <span class="ico-star">%s</span><span class="info-rating">%d/%d</span> %s
+ </div>
+ </div>',
+ $html_star,
+ $rating_info['rated'],
+ $rating_info['total'],
+ _n( 'Rating', 'Ratings', $rating_info['total'], 'learnpress-course-review' )
+ );
+ } catch ( Throwable $e ) {
+ LP_Debug::error_log( $e );
+ }
+
+ return $html;
+ }
+
+ /**
+ * Render rating reviews
+ *
+ * @param CourseModel $courseModel
+ * @param UserModel|false $userModel
+ *
+ * @return string
+ * @since 4.1.6
+ * @version 1.0.0
+ */
+ public function html_rating_reviews( CourseModel $courseModel, $userModel ): string {
+ $html = '';
+
+ try {
+ ob_start();
+ LP_Addon_Course_Review_Preload::$addon->add_course_tab_reviews_callback();
+ $html_rating_reviews_main = ob_get_clean();
+
+ $section = [
+ 'wrapper' => '<div class="lp-rating-reviews-wrapper">',
+ 'header' => sprintf(
+ '<h3 class="item-title">%s</h3>',
+ esc_html__( 'Reviews', 'learnpress-course-review' )
+ ),
+ 'content' => $html_rating_reviews_main,
+ 'wrapper_end' => '</div>',
+ ];
+
+ $html = Template::combine_components( $section );
+ } catch ( Throwable $e ) {
+ LP_Debug::error_log( $e );
+ }
+
+ return $html;
+ }
+
+ /**
+ * Render rating reviews
+ *
+ * @param array $settings
+ *
+ * @return stdClass
+ * @since 4.1.6
+ * @version 1.0.0
+ */
+ public static function render_rating_reviews( array $settings = [] ): stdClass {
+ $content = new stdClass();
+ $content->content = '';
+
+ try {
+ $course_id = $settings['course_id'] ?? 0;
+ $user_id = $settings['user_id'] ?? get_current_user_id();
+ $userModel = UserModel::find( $user_id, true );
+ $courseModel = CourseModel::find( $course_id, true );
+ if ( ! $courseModel instanceof CourseModel ) {
+ return $content;
+ }
+
+ $paged = $settings['paged'] ?? 1;
+ $reviews_rs = learn_press_get_course_review( $courseModel->get_id(), $paged );
+ $total_pages = $reviews_rs['pages'] ?? 0;
+ $settings['reviews_rs'] = $reviews_rs;
+
+ $section_course_rate = [
+ 'wrapper' => '<div class="course-rate">',
+ 'average' => self::instance()->html_average_rating( $courseModel ),
+ 'detail' => self::instance()->html_rating_detail( $courseModel ),
+ 'wrapper_end' => '</div>',
+ ];
+
+ $section = [
+ 'wrapper' => '<div class="learnpress-course-review lp-rating-reviews-wrapper">',
+ 'header' => sprintf(
+ '<h3 class="item-title">%s</h3>',
+ esc_html__( 'Reviews', 'learnpress-course-review' )
+ ),
+ 'rate' => Template::combine_components( $section_course_rate ),
+ 'btn-review' => self::instance()->html_btn_review( $courseModel, $userModel ),
+ 'unapprove' => self::instance()->html_unapprove( $courseModel, $userModel ),
+ 'reviews' => self::instance()->html_list_reviews( $courseModel, $userModel, $settings ),
+ 'wrapper_end' => '</div>',
+ ];
+
+ $content->content = Template::combine_components( $section );
+ $content->paged = $paged;
+ $content->total_pages = $total_pages;
+ } catch ( Throwable $e ) {
+ LP_Debug::error_log( $e );
+ }
+
+ return $content;
+ }
+
+ /**
+ * Submit review
+ *
+ * @param array $settings
+ *
+ * @return stdClass
+ * @since 4.1.6
+ * @version 1.0.0
+ */
+ public static function submit_review( array $settings = [] ) {
+ $content = new stdClass();
+ $content->status = 'error';
+ $content->content = '';
+ $settings['user_id'] = get_current_user_id();
+ $submit_rs = LP_Addon_Course_Review_Preload::$addon->submit_review( $settings );
+ if ( $submit_rs instanceof WP_Error ) {
+ $content->content = $submit_rs->get_error_message();
+ } else {
+ $content->status = 'success';
+ $content->content = __( 'Your review has been submitted and is awaiting approve.', 'learnpress-course-review' );
+ }
+
+ return $content;
+ }
+}
--- a/learnpress-course-review/inc/load.php
+++ b/learnpress-course-review/inc/load.php
@@ -1,630 +1,630 @@
-<?php
-/**
- * Plugin load class.
- *
- * @author ThimPress
- * @package LearnPress/Course-Review/Classes
- * @version 3.0.2
- */
-
-// Prevent loading this file directly
-use LearnPressCourseReviewCourseReviewCache;
-use LearnPressCourseReviewCourseReviewWidget;
-use LearnPressCourseReviewDatabasesCourseReviewsDB;
-use LearnPressModelsCourseModel;
-use LearnPressModelsUserItemsUserCourseModel;
-use LearnPressModelsUserModel;
-
-defined( 'ABSPATH' ) || exit;
-
-if ( ! class_exists( 'LP_Addon_Course_Review' ) ) {
- /**
- * Class LP_Addon_Course_Review.
- */
- class LP_Addon_Course_Review extends LP_Addon {
- public $version = LP_ADDON_COURSE_REVIEW_VER;
- public $require_version = LP_ADDON_COURSE_REVIEW_REQUIRE_VER;
- public $plugin_file = LP_ADDON_COURSE_REVIEW_FILE;
- public $text_domain = 'learnpress-course-review';
-
- /**
- * @var string
- */
- private static $comment_type = 'review';
-
- const META_KEY_RATING_AVERAGE = 'lp_course_rating_average';
- const META_KEY_ENABLE = '_lp_course_review_enable';
-
- public static $instance = null;
-
- /**
- * Get instance class.
- *
- * @return LP_Addon_Course_Review|null
- */
- public static function instance() {
- if ( is_null( self::$instance ) ) {
- self::$instance = new self();
- }
-
- return self::$instance;
- }
-
- /**
- * LP_Addon_Course_Review constructor.
- */
- public function __construct() {
- parent::__construct();
- $this->hooks();
- }
-
- /**
- * Define Learnpress Course Review constants.
- *
- * @since 3.0.0
- */
- protected function _define_constants() {
- define( 'LP_ADDON_COURSE_REVIEW_PATH', dirname( LP_ADDON_COURSE_REVIEW_FILE ) );
- define( 'LP_ADDON_COURSE_REVIEW_PER_PAGE', apply_filters( 'learn-press/course-review/per-page', 5 ) );
- define( 'LP_ADDON_COURSE_REVIEW_TMPL', LP_ADDON_COURSE_REVIEW_PATH . '/templates/' );
- define( 'LP_ADDON_COURSE_REVIEW_URL', untrailingslashit( plugins_url( '/', __DIR__ ) ) );
- }
-
- /**
- * Include required core files used in admin and on the frontend.
- *
- * @since 3.0.0
- */
- protected function _includes() {
- require_once LP_ADDON_COURSE_REVIEW_PATH . '/inc/functions.php';
- // Rest API
- require_once LP_ADDON_COURSE_REVIEW_PATH . '/inc/rest-api/jwt/class-lp-rest-review-v1-controller.php';
- require_once LP_ADDON_COURSE_REVIEW_PATH . '/inc/rest-api/class-rest-api.php';
- // Background
- require_once LP_ADDON_COURSE_REVIEW_PATH . '/inc/background/class-lp-course-review-background.php';
- }
-
- /**
- * Init hooks.
- */
- protected function hooks() {
- // Enqueue assets.
- add_action( 'wp_enqueue_scripts', array( $this, 'frontend_assets' ) );
- add_action( 'learn-press/admin-default-styles', array( $this, 'admin_enqueue_assets' ) );
- add_filter( 'learn-press/course-tabs', array( $this, 'add_course_tab_reviews' ), 5 );
- // Clear cache when update comment. (Approve|Un-approve|Edit|Spam|Trash)
- add_action(
- 'wp_set_comment_status',
- function ( $comment_id ) {
- $comment = get_comment( $comment_id );
- if ( ! $comment ) {
- return;
- }
-
- $post_id = $comment->comment_post_ID;
- $user_id = $comment->user_id;
- if ( LP_COURSE_CPT !== get_post_type( $post_id ) ) {
- return;
- }
-
- $courseReviewCache = new CourseReviewCache( true );
- $courseReviewCache->clean_rating( $post_id, $user_id );
- }
- );
- add_filter(
- 'learnPress/prepare_struct_courses_response/courseObjPrepare',
- [
- $this,
- 'rest_api_courses',
- ],
- 10,
- 2
- );
- // Add setting field to course.
- add_filter(
- 'lp/course/meta-box/fields/general',
- function ( $fields, $post_id ) {
- $fields[ self::META_KEY_ENABLE ] = new LP_Meta_Box_Checkbox_Field(
- esc_html__( 'Enable reviews', 'learnpress-course-review' ),
- esc_html__( 'Show reviews for this course', 'learnpress-course-review' ),
- 'yes'
- );
-
- return $fields;
- },
- 10,
- 2
- );
-
- $this->init_comment_table();
- $this->calculate_rating_average_courses();
-
- // Add widget
- add_action(
- 'learn-press/widgets/register',
- function ( $widgets ) {
- $widgets[] = CourseReviewWidget::instance();
-
- return $widgets;
- }
- );
-
- /**
- * Frontend: exclude course review from comment default of WP.
- *
- * @param $wp_comment_query WP_Comment_Query
- */
- add_action(
- 'pre_get_comments',
- function ( &$wp_comment_query ) {
- if ( is_admin() ) {
- return;
- }
-
- $post_id = $wp_comment_query->query_vars['post_id'];
- if ( ! $post_id ) {
- return;
- }
-
- $courseModel = CourseModel::find( $post_id, true );
- if ( ! $courseModel instanceof CourseModel ) {
- return;
- }
-
- $wp_comment_query->query_vars['type__not_in'] = self::$comment_type;
- }
- );
- }
-
- /**
- * Admin assets.
- * @since 4.0.0
- * @version 1.0.1
- */
- public function admin_enqueue_assets( $styles ) {
- $is_rtl = is_rtl() ? '-rtl' : '';
- $min = '.min';
- $v = LP_ADDON_COURSE_REVIEW_VER;
- if ( LP_Debug::is_debug() ) {
- $v = rand();
- $min = '';
- }
-
- $styles['course-review'] = new LP_Asset_Key(
- $this->get_plugin_url( "assets/dist/css/admin{$is_rtl}{$min}.css" ),
- [],
- [ 'edit-comments', LP_COURSE_CPT ],
- 0
- );
-
- return $styles;
- }
-
- /**
- * Single course assets.
- *
- * @since 4.0.0
- * @version 1.0.2
- */
- public function frontend_assets() {
- $is_rtl = is_rtl() ? '-rtl' : '';
- $min = '.min';
- $v = LP_ADDON_COURSE_REVIEW_VER;
- if ( LP_Debug::is_debug() ) {
- $v = rand();
- $min = '';
- }
-
- wp_register_style(
- 'course-review',
- $this->get_plugin_url( "assets/dist/css/course-review{$is_rtl}{$min}.css" ),
- [],
- $v
- );
- wp_register_script(
- 'course-review',
- $this->get_plugin_url( "assets/dist/js/course-review{$min}.js" ),
- [],
- $v,
- [ 'strategy' => 'async' ]
- );
-
- // For case load AJAX on tab "Courses", "My Courses" of LearnPress.
- if ( LP_Page_Controller::is_page_profile() ) {
- wp_enqueue_style( 'course-review' );
- }
- }
-
- /**
- * Check if not register style, load style inline.
- *
- * @return void
- * @since 4.1.2
- * @version 1.0.0
- */
- public function check_load_file_style() {
- // Check if has action, this action add to LearnPress on v4.2.7.2
- if ( has_action( 'learn-press/widget/before' ) ) {
- return;
- }
-
- $is_rtl = is_rtl() ? '-rtl' : '';
- $min = '.min';
- if ( LP_Debug::is_debug() ) {
- $min = '';
- }
- $file_style = LP_Addon_Course_Review_Preload::$addon->get_plugin_url( "assets/css/course-review{$is_rtl}{$min}.css" );
- ?>
- <style id="lp-course-review-star-style">
- <?php echo wp_remote_fopen( $file_style ); ?>
- </style>
- <?php
- }
-
- public function init_comment_table() {
- //wp_enqueue_style( 'course-review', LP_ADDON_COURSE_REVIEW_URL . '/assets/css/course-review.css' );
-
- add_filter( 'admin_comment_types_dropdown', array( $this, 'add_comment_type_filter' ) );
-
- add_filter( 'comment_row_actions', array( $this, 'edit_comment_row_actions' ), 10, 2 );
- }
-
- public function edit_comment_row_actions( $actions, $comment ) {
- if ( ! $comment || $comment->comment_type != 'review' ) {
- return $actions;
- }
- unset( $actions['reply'] );
-
- return $actions;
- }
-
- public function add_comment_type_filter( $cmt_types ) {
- $cmt_types[ self::$comment_type ] = __( 'Course review', 'learnpress-course-review' );
-
- return $cmt_types;
- }
-
- public function add_course_tab_reviews( $tabs ) {
- $course = CourseModel::find( get_the_ID(), true );
- if ( ! $course ) {
- return $tabs;
- }
-
- if ( ! $this->is_enable( $course ) ) {
- return $tabs;
- }
-
- $tabs['reviews'] = array(
- 'title' => __( 'Reviews', 'learnpress-course-review' ),
- 'priority' => 60,
- 'callback' => array( $this, 'add_course_tab_reviews_callback' ),
- );
-
- return $tabs;
- }
-
- /**
- * Callback for course tab reviews.
- *
- * @return void
- * @since 4.0.0
- * @version 1.0.1
- */
- public function add_course_tab_reviews_callback() {
- $course_id = get_the_ID();
- $courseModel = CourseModel::find( $course_id, true );
- if ( empty( $courseModel ) ) {
- return;
- }
-
- $userModel = $courseModel::find( get_current_user_id(), true );
- do_action( 'learn-press/course-review/rating-reviews', $courseModel, $userModel );
- }
-
- /**
- * Get rating of course.
- *
- * @param int $course_id
- *
- * @return array
- * @since 4.0.6
- * @version 1.0.0
- */
- public function get_rating_of_course( int $course_id = 0 ): array {
- $courseReviewCache = new CourseReviewCache( true );
- $rating = [
- 'course_id' => $course_id,
- 'total' => 0,
- 'rated' => 0,
- 'items' => [
- 5 => [
- 'rated' => 5,
- 'total' => 0,
- 'percent' => 0,
- 'percent_float' => 0,
- ],
- 4 => [
- 'rated' => 4,
- 'total' => 0,
- 'percent' => 0,
- 'percent_float' => 0,
- ],
- 3 => [
- 'rated' => 3,
- 'total' => 0,
- 'percent' => 0,
- 'percent_float' => 0,
- ],
- 2 => [
- 'rated' => 2,
- 'total' => 0,
- 'percent' => 0,
- 'percent_float' => 0,
- ],
- 1 => [
- 'rated' => 1,
- 'total' => 0,
- 'percent' => 0,
- 'percent_float' => 0,
- ],
- ],
- ];
-
- try {
- $rating_cache = $courseReviewCache->get_rating( $course_id );
- if ( false !== $rating_cache ) {
- return json_decode( $rating_cache, true );
- }
-
- $courseReviewsDB = CourseReviewsDB::getInstance();
- $rating_rs = $courseReviewsDB->count_rating_of_course( $course_id );
- if ( ! $rating_rs ) {
- throw new Exception();
- }
-
- $rating['total'] = (int) $rating_rs->total;
- $total_rating = 0;
- for ( $star = 1; $star <= 5; $star ++ ) {
- $key = '';
- switch ( $star ) {
- case 1:
- $key = 'one';
- break;
- case 2:
- $key = 'two';
- break;
- case 3:
- $key = 'three';
- break;
- case 4:
- $key = 'four';
- break;
- case 5:
- $key = 'five';
- break;
- }
-
- // Calculate total rating by type.
- $rating['items'][ $star ]['rated'] = $star;
- $rating['items'][ $star ]['total'] = (int) $rating_rs->{$key};
- $rating['items'][ $star ]['percent'] = (int) ( $rating_rs->total ? $rating_rs->{$key} * 100 / $rating_rs->total : 0 );
-
- // Sum rating.
- $count_star = $rating_rs->{$key};
- $total_rating += $count_star * $star;
- }
-
- // Calculate average rating.
- $rating_average = $rating_rs->total ? $total_rating / $rating_rs->total : 0;
- if ( is_float( $rating_average ) ) {
- $rating_average = (float) number_format( $rating_average, 1 );
- }
- $rating['rated'] = $rating_average;
-
- // Set cache
- $courseReviewCache->set_rating( $course_id, json_encode( $rating ) );
- } catch ( Throwable $e ) {
- if ( ! empty( $e->getMessage() ) ) {
- LP_Debug::error_log( $e );
- }
- }
-
- return $rating;
- }
-
- /**
- * Calculate rating average all courses.
- * For case user upgrade plugin (not install First)
- * Apply new feature - filter course rating, need param from meta to compare.
- * For a long time will remove this function.
- *
- * @return void
- * @since 4.1.2
- */
- public function calculate_rating_average_courses() {
- if ( ! is_admin() ) {
- return;
- }
-
- $is_calculated = get_option( 'lp_calculated_rating_average_courses' );
- if ( ! empty( $is_calculated ) ) {
- return;
- }
-
- update_option( 'lp_calculated_rating_average_courses', 1 );
- $params = [ 'handle_name' => 'calculate_rating_average_courses' ];
- LPCourseReviewBackGround::instance()->data( $params )->dispatch();
- }
-
- /**
- * Set rating average for course
- *
- * @param int $course_id
- * @param float $average
- *
- * @return void
- * @since 4.1.2
- * @version 1.0.0
- */
- public static function set_course_rating_average( int $course_id, float $average ) {
- update_post_meta( $course_id, LP_Addon_Course_Review::META_KEY_RATING_AVERAGE, $average );
- }
-
- /**
- * Get SVG star.
- *
- * @return string
- * @since 4.1.2
- * @version 1.0.1
- */
- public static function get_svg_star() {
- $path_default = LP_ADDON_COURSE_REVIEW_PATH . '/assets/images/svg-star.svg';
- $path = realpath( apply_filters( 'learn-press/course-review/svg-star', $path_default ) );
- if ( ! $path ) {
- $path = $path_default;
- }
-
- return file_get_contents( $path );
- }
-
- /**
- * Hook get rating for API of APP.
- *
- * @param stdClass|mixed $courseObjPrepare
- * @param CourseModel $course form LP v4.2.6.9
- *
- * @return stdClass|mixed
- * @since 4.1.3
- * @version 1.0.0
- */
- public function rest_api_courses( $courseObjPrepare, CourseModel $course ) {
- $courseObjPrepare->rating = learn_press_get_course_rate( $course->get_id() );
-
- return $courseObjPrepare;
- }
-
- /**
- * Check course review is enable.
- *
- * @param CourseModel $course
- *
- * @return bool
- * @since 4.1.5
- * @version 1.0.0
- */
- public function is_enable( CourseModel $course ): bool {
- $enable = $course->get_meta_value_by_key( self::META_KEY_ENABLE, 'yes' );
-
- return 'yes' === $enable;
- }
-
- /**
- * Get average rating of course.
- *
- * @param CourseModel $course
- *
- * @return float
- * @since 4.1.5
- * @version 1.0.0
- */
- public function get_average_rated( CourseModel $course ): float {
- return (float) number_format( (float) $course->get_meta_value_by_key( LP_Addon_Course_Review::META_KEY_RATING_AVERAGE, 0 ), 1 );
- }
-
- /**
- * Check user can review course.
- *
- * @param UserModel $user
- * @param CourseModel $course
- *
- * @return bool
- * @since 4.1.5
- * @version 1.0.0
- */
- public function check_user_can_review_course( UserModel $user, CourseModel $course ): bool {
- $can_review = false;
-
- $userCourse = UserCourseModel::find( $user->get_id(), $course->get_id(), true );
- if ( $userCourse &&
- ( $userCourse->has_enrolled_or_finished() || ( $course->is_offline() && $userCourse->has_purchased() ) )
- && ! learn_press_get_user_rate( $course->get_id(), $user->get_id() ) ) {
- $can_review = true;
- }
-
- return $can_review;
- }
-
- /**
- * Submit review
- *
- * @param array $data
- * key courseModel
- * key userModel
- * key rating
- * key review_title
- * key review_content
- *
- * @return bool|WP_Error
- * @since 4.1.6
- * @version 1.0.0
- */
- public static function submit_review( array $data ) {
- $flag = false;
-
- try {
- $course_id = $data['course_id'] ?? false;
- $user_id = $data['user_id'] ?? false;
- $rating = $data['rating'] ?? 0;
- $title = $data['review_title'] ?? '';
- $content = $data['review_content'] ?? '';
-
- $courseModel = CourseModel::find( $course_id, true );
- if ( ! $courseModel instanceof CourseModel ) {
- throw new Exception( esc_html__( 'Course is invalid!', 'learnpress-course-review' ) );
- }
-
- $userModel = UserModel::find( $user_id, true );
- if ( ! $userModel instanceof UserModel ) {
- throw new Exception( esc_html__( 'User is invalid!', 'learnpress-course-review' ) );
- }
-
- if ( empty( $rating ) ) {
- throw new Exception( esc_html__( 'Rating is requirement!', 'learnpress-course-review' ) );
- }
-
- if ( empty( $title ) ) {
- throw new Exception( esc_html__( 'Title is not empty!', 'learnpress-course-review' ) );
- }
-
- if ( empty( $content ) ) {
- throw new Exception( esc_html__( 'Content is not empty!', 'learnpress-course-review' ) );
- }
-
- if ( ! LP_Addon_Course_Review_Preload::$addon->check_user_can_review_course( $userModel, $courseModel ) ) {
- throw new Exception( esc_html__( 'You can not submit review.', 'learnpress-course-review' ) );
- }
-
- $add_review = learn_press_add_course_review(
- array(
- 'user_id' => $userModel->get_id(),
- 'course_id' => $courseModel->get_id(),
- 'rate' => $rating,
- 'title' => $title,
- 'content' => $content,
- 'force' => true, // Not use cache.
- )
- );
-
- if ( ! $add_review instanceof WP_Error ) {
- $flag = true;
- } else {
- throw new Exception( $add_review->get_error_message() );
- }
- } catch ( Throwable $e ) {
- $flag = new WP_Error( 'lp_review_error', $e->getMessage() );
- }
-
- return $flag;
- }
- }
-}
+<?php
+/**
+ * Plugin load class.
+ *
+ * @author ThimPress
+ * @package LearnPress/Course-Review/Classes
+ * @version 3.0.2
+ */
+
+// Prevent loading this file directly
+use LearnPressCourseReviewCourseReviewCache;
+use LearnPressCourseReviewCourseReviewWidget;
+use LearnPressCourseReviewDatabasesCourseReviewsDB;
+use LearnPressModelsCourseModel;
+use LearnPressModelsUserItemsUserCourseModel;
+use LearnPressModelsUserModel;
+
+defined( 'ABSPATH' ) || exit;
+
+if ( ! class_exists( 'LP_Addon_Course_Review' ) ) {
+ /**
+ * Class LP_Addon_Course_Revi