namespace, '/' . $this->base . '/get-quick-performance', [ [ 'methods' => WP_REST_Server::READABLE, 'callback' => [$this, 'get_quick_performance'], 'permission_callback' => [$this, 'check_permission'], ], ] ); register_rest_route( $this->namespace, '/' . $this->base . '/get-last-accessed-course', [ [ 'methods' => WP_REST_Server::READABLE, 'callback' => [$this, 'get_last_accessed_course'], 'permission_callback' => [$this, 'check_permission'], ], ] ); register_rest_route( $this->namespace, '/' . $this->base . '/get-course-categories', [ [ 'methods' => WP_REST_Server::READABLE, 'callback' => [$this, 'get_course_categories'], 'permission_callback' => [$this, 'check_permission'], ], ] ); register_rest_route( $this->namespace, '/' . $this->base . '/get-recently-joined-courses', [ [ 'methods' => WP_REST_Server::READABLE, 'callback' => [$this, 'get_recently_joined_courses'], 'permission_callback' => [$this, 'check_permission'], ], ] ); register_rest_route( $this->namespace, '/' . $this->base . '/get-popular-courses', [ [ 'methods' => WP_REST_Server::READABLE, 'callback' => [$this, 'get_popular_courses'], 'permission_callback' => [$this, 'check_permission'], ], ] ); register_rest_route( $this->namespace, '/' . $this->base . '/get-new-courses', [ [ 'methods' => WP_REST_Server::READABLE, 'callback' => [$this, 'get_new_courses'], 'permission_callback' => [$this, 'check_permission'], ], ] ); register_rest_route( $this->namespace, '/' . $this->base . '/get-subject-performance', [ [ 'methods' => WP_REST_Server::READABLE, 'callback' => [$this, 'get_subject_performance'], 'permission_callback' => [$this, 'check_permission'], ], ] ); register_rest_route( $this->namespace, '/' . $this->base . '/get-last-attempted-quizzes', [ [ 'methods' => WP_REST_Server::READABLE, 'callback' => [$this, 'get_last_attempted_quizzes'], 'permission_callback' => [$this, 'check_permission'], ], ] ); } public function get_quick_performance($request) { $params = apply_filters('acadlix_pre_get_quick_performance_params', $request->get_params(), $request); $userId = $params['user_id'] ?? $request->get_param('user_id') ?? 0; if (empty($userId)) { return new WP_Error('no_data_found', __('Required user_id', 'acadlix'), array('status' => 404)); } // 2) Payload/Data Filter: normalize values before core execution $payload = apply_filters('acadlix_get_quick_performance_payload', [ 'user_id' => intval($userId), ], $params); $get_query = function () use ($payload) { return acadlix()->model()->courseEnrollment()->getEnrolledCourseQuery($payload['user_id']); }; $enrolled_courses = $get_query()->count(); $completed_courses = $get_query()->where('progress_percent', 100)->count(); $in_progress_courses = $get_query()->where('progress_percent', '<', 100)->count(); $quizzes_attempted = acadlix()->model()->statisticRef() ->with('quiz') ->where('user_id', $payload['user_id']) ->count(); $res = [ 'enrolled_courses' => $enrolled_courses, 'completed_courses' => $completed_courses, 'in_progress_courses' => $in_progress_courses, 'quizzes_attempted' => $quizzes_attempted, ]; do_action('acadlix_get_quick_performance', $res, $payload, $params); $res = apply_filters('acadlix_get_quick_performance_response', $res, $payload, $params); return rest_ensure_response($res); } public function get_last_accessed_course($request) { $params = apply_filters('acadlix_pre_get_last_accessed_course_params', $request->get_params(), $request); $userId = $params['user_id'] ?? $request->get_param('user_id') ?? 0; if (empty($userId)) { return new WP_Error('no_data_found', __('Required user_id', 'acadlix'), array('status' => 404)); } // 2) Payload/Data Filter: normalize values before core execution $payload = apply_filters('acadlix_get_last_accessed_course_payload', [ 'user_id' => intval($userId), ], $params); $last_accessed_course_statistic = acadlix()->model()->courseStatistic() ->where('user_id', $payload['user_id']) ->orderByDesc('updated_at') ->first(); $last_accessed_course = null; $courseEnrollment = acadlix()->model()->courseEnrollment(); if ($last_accessed_course_statistic && $courseEnrollment->hasAccess($payload['user_id'], $last_accessed_course_statistic->course_id)) { $last_accessed_course = $courseEnrollment->getEnrolledCourseQuery($payload['user_id']) ->with('course') ->where('course_id', $last_accessed_course_statistic->course_id) ->first(); } else { $last_accessed_course = $courseEnrollment->getEnrolledCourseQuery($payload['user_id']) ->with('course') ->orderByDesc('updated_at') ->first(); } $res = [ 'last_accessed_course' => $last_accessed_course, ]; do_action('acadlix_get_last_accessed_course', $res, $payload, $params); $res = apply_filters('acadlix_get_last_accessed_course_response', $res, $payload, $params); return rest_ensure_response($res); } public function get_course_categories($request) { $params = apply_filters('acadlix_pre_get_course_categories_params', $request->get_params(), $request); $userId = $params['user_id'] ?? $request->get_param('user_id') ?? 0; if (empty($userId)) { return new WP_Error('no_data_found', __('Required user_id', 'acadlix'), array('status' => 404)); } // 2) Payload/Data Filter: normalize values before core execution $payload = apply_filters('acadlix_get_course_categories_payload', [ 'user_id' => intval($userId), ], $params); $categories = acadlix() ->model() ->wpTermTaxonomy() ->ofCourseCategory() ->with('term') ->where('count', '>', 0) ->limit(10) ->orderByDesc('count') ->get() ->each(function ($category) { $category->permalink = get_term_link($category->term_id); }); $res = [ 'categories' => $categories ?? [], ]; do_action('acadlix_get_course_categories', $res, $payload, $params); $res = apply_filters('acadlix_get_course_categories_response', $res, $payload, $params); return rest_ensure_response($res); } public function get_recently_joined_courses($request) { $params = apply_filters('acadlix_pre_get_recently_joined_courses_params', $request->get_params(), $request); $userId = $params['user_id'] ?? $request->get_param('user_id') ?? 0; if (empty($userId)) { return new WP_Error('no_data_found', __('Required user_id', 'acadlix'), array('status' => 404)); } // 2) Payload/Data Filter: normalize values before core execution $payload = apply_filters('acadlix_get_recently_joined_courses_payload', [ 'user_id' => intval($userId), ], $params); $recently_joined_courses = acadlix() ->model() ->courseEnrollment() ->getEnrolledCourses( $payload['user_id'], null, 0, 5, ['course'], ); $res = [ 'recently_joined_courses' => $recently_joined_courses['courses'] ?? [], ]; do_action('acadlix_get_recently_joined_courses', $res, $payload, $params); $res = apply_filters('acadlix_get_recently_joined_courses_response', $res, $payload, $params); return rest_ensure_response($res); } public function get_popular_courses($request) { $params = apply_filters('acadlix_pre_get_popular_courses_params', $request->get_params(), $request); $userId = $params['user_id'] ?? $request->get_param('user_id') ?? 0; if (empty($userId)) { return new WP_Error('no_data_found', __('Required user_id', 'acadlix'), array('status' => 404)); } // 2) Payload/Data Filter: normalize values before core execution $payload = apply_filters('acadlix_get_popular_courses_payload', [ 'user_id' => intval($userId) ], $params); $popular_courses = acadlix() ->model() ->courseEnrollment() ->getPopularCourses(5, ['course']) ->each(function ($enrolled) use ($payload) { $enrolled->course->wishlist = acadlix()->model()->userActivityMeta() ->ofCourse() ->ofWishlist() ->where("type_id", $enrolled->course->ID) ->where("user_id", $payload['user_id']) ->first(); $enrolled->course->average_rating = $enrolled->course->getAverageRating(); }); $res = [ 'popular_courses' => $popular_courses ?? [], ]; do_action('acadlix_get_popular_courses', $res, $payload, $params); $res = apply_filters('acadlix_get_popular_courses_response', $res, $payload, $params); return rest_ensure_response($res); } public function get_new_courses($request) { $params = apply_filters('acadlix_pre_get_new_courses_params', $request->get_params(), $request); $userId = $params['user_id'] ?? $request->get_param('user_id') ?? 0; if (empty($userId)) { return new WP_Error('no_data_found', __('Required user_id', 'acadlix'), array('status' => 404)); } // 2) Payload/Data Filter: normalize values before core execution $payload = apply_filters('acadlix_get_new_courses_payload', [ 'user_id' => $userId ], $params); $new_courses = acadlix() ->model() ->course() ->ofCourse() ->ofPublish() ->orderByDesc('post_date') ->limit(5) ->get() ->each(function ($course) use ($payload) { $course->wishlist = acadlix()->model()->userActivityMeta() ->ofCourse() ->ofWishlist() ->where("type_id", $course->ID) ->where("user_id", $payload['user_id']) ->first(); $course->average_rating = $course->getAverageRating(); }); $res = [ 'new_courses' => $new_courses ?? [], ]; do_action('acadlix_get_new_courses', $res, $payload, $params); $res = apply_filters('acadlix_get_new_courses_response', $res, $payload, $params); return rest_ensure_response($res); } public function get_subject_performance($request) { $params = apply_filters('acadlix_pre_get_subject_performance_params', $request->get_params(), $request); $userId = $params['user_id'] ?? $request->get_param('user_id') ?? 0; if (empty($userId)) { return new WP_Error('no_data_found', __('Required user_id', 'acadlix'), array('status' => 404)); } // 2) Payload/Data Filter: normalize values before core execution $payload = apply_filters('acadlix_get_subject_performance_payload', [ 'user_id' => intval($userId), 'page' => intval($params['page'] ?? 0), 'pageSize' => intval($params['pageSize'] ?? 10), 'search' => $params['search'] ?? null, ], $params); $subject_performance = acadlix() ->model() ->statistic() ->getSubjectPerformance( $payload['user_id'], $payload['page'], $payload['pageSize'], $payload['search'] ); $res = [ 'subject_performance' => $subject_performance['data'] ?? [], 'total' => $subject_performance['total'] ?? 0, ]; do_action('acadlix_get_subject_performance', $res, $payload, $params); $res = apply_filters('acadlix_get_subject_performance_response', $res, $payload, $params); return rest_ensure_response($res); } public function get_last_attempted_quizzes($request) { $params = apply_filters('acadlix_pre_get_last_attempted_quizzes_params', $request->get_params(), $request); $userId = $params['user_id'] ?? $request->get_param('user_id') ?? 0; if (empty($userId)) { return new WP_Error('no_data_found', __('Required user_id', 'acadlix'), array('status' => 404)); } // 2) Payload/Data Filter: normalize values before core execution $payload = apply_filters('acadlix_get_last_attempted_quizzes_payload', [ 'user_id' => intval($userId), ], $params); $last_attempted_quizzes = acadlix()->model()->statisticRef() ->with('quiz') ->where('user_id', $payload['user_id']) ->orderBy("id", "desc") ->limit(3) ->get(); $res = [ 'last_attempted_quizzes' => $last_attempted_quizzes ?? [], ]; do_action('acadlix_get_last_attempted_quizzes', $res, $payload, $params); $res = apply_filters('acadlix_get_last_attempted_quizzes_response', $res, $payload, $params); return rest_ensure_response($res); } public function check_permission($request) { if (!is_user_logged_in()) { return new WP_Error('not_logged_in', 'Login required', ['status' => 401]); } $user_id = absint($request->get_param('user_id') ?? 0); if ($user_id && get_current_user_id() !== $user_id) { return new WP_Error('forbidden', 'Access denied', ['status' => 403]); } return true; } }