[ Avaa Bypassed ]




Upload:

Command:

hmhc3928@3.144.232.156: ~ $
<?php
/**
 * Manage Instructor List
 *
 * @package Tutor
 * @author Themeum <support@themeum.com>
 * @link https://themeum.com
 * @since 1.0.0
 */

namespace TUTOR;

if ( ! defined( 'ABSPATH' ) ) {
	exit;
}

use TUTOR\Students_List;
use TUTOR\Backend_Page_Trait;
use Tutor\Cache\TutorCache;
use Tutor\Helpers\QueryHelper;

/**
 * Instructors_List class
 *
 * @since 1.0.0
 */
class Instructors_List {

	const INSTRUCTOR_LIST_PAGE       = 'tutor-instructors';
	const INSTRUCTOR_LIST_CACHE_KEY  = 'tutor-instructors-list';
	const INSTRUCTOR_COUNT_CACHE_KEY = 'tutor-instructors-count';

	/**
	 * Trait for utilities
	 *
	 * @var $page_title
	 */

	use Backend_Page_Trait;

	/**
	 * Page Title
	 *
	 * @var $page_title
	 */
	public $page_title;

	/**
	 * Bulk Action
	 *
	 * @var $bulk_action
	 */
	public $bulk_action = true;

	/**
	 * Constructor
	 *
	 * @since 1.0.0
	 * @return void
	 */
	public function __construct() {
		$this->page_title = __( 'Instructor', 'tutor' );

		/**
		 * Handle bulk action
		 *
		 * @since 2.0.0
		 */
		add_action( 'wp_ajax_tutor_instructor_bulk_action', array( $this, 'instructor_bulk_action' ) );
	}

	/**
	 * Available tabs that will visible on the right side of page navbar
	 *
	 * @since 2.0.0
	 *
	 * @param string $search instructor search | optional.
	 * @param string $course_id course id that belong to instructor | optional.
	 * @param string $date user registered date | optional.
	 *
	 * @return array
	 */
	public function tabs_key_value( $search = '', $course_id = '', $date = '' ): array {
		$url     = apply_filters( 'tutor_data_tab_base_url', get_pagenum_link() );
		$approve = self::count_total_instructors( array( 'approved' ), $search, $course_id, $date, 'approved' );
		$pending = self::count_total_instructors( array( 'pending' ), $search, $course_id, $date, 'pending' );
		$blocked = self::count_total_instructors( array( 'blocked' ), $search, $course_id, $date, 'blocked' );

		$tabs = array(
			array(
				'key'   => 'all',
				'title' => __( 'All', 'tutor' ),
				'value' => $approve + $pending + $blocked,
				'url'   => $url . '&data=all',
			),
			array(
				'key'   => 'approved',
				'title' => __( 'Approve', 'tutor' ),
				'value' => $approve,
				'url'   => $url . '&data=approved',
			),
			array(
				'key'   => 'pending',
				'title' => __( 'Pending', 'tutor' ),
				'value' => $pending,
				'url'   => $url . '&data=pending',
			),
			array(
				'key'   => 'blocked',
				'title' => __( 'Block', 'tutor' ),
				'value' => $blocked,
				'url'   => $url . '&data=blocked',
			),
		);
		return $tabs;
	}

	/**
	 * Prepare bulk actions that will show on dropdown options
	 *
	 * @since 2.0.0
	 * @return array
	 */
	public function prpare_bulk_actions(): array {
		$actions = array(
			$this->bulk_action_default(),
			$this->bulk_action_approved(),
			$this->bulk_action_pending(),
			$this->bulk_action_blocked(),
		);
		return $actions;
	}

	/**
	 * Handle bulk action for instructor delete
	 *
	 * @since 2.0.0
	 * @return string JSON response.
	 */
	public function instructor_bulk_action() {
		tutor_utils()->checking_nonce();

		// Check if user is privileged.
		if ( ! current_user_can( 'administrator' ) ) {
			wp_send_json_error( tutor_utils()->error_message() );
		}

		$action   = Input::post( 'bulk-action', '' );
		$bulk_ids = Input::post( 'bulk-ids', '' );

		Input::has( 'bulkIds' ) ? $bulk_ids = Input::post( 'bulkIds' ) : 0;

		if ( '' === $action || '' === $bulk_ids ) {
			return wp_send_json_error();
		}
		if ( 'delete' === $action ) {
			// Delete user from student_list class.
			do_action( 'tutor_before_instructor_delete', $bulk_ids );
			$response = Students_List::delete_students( $bulk_ids );
			do_action( 'tutor_after_instructor_delete', $bulk_ids );
		} else {
			do_action( 'tutor_before_instructor_update', $bulk_ids );
			$response = self::update_instructors( $action, $bulk_ids );
			do_action( 'tutor_after_instructor_delete', $bulk_ids );
		}

		$message = 'Instructor status updated';

		return true === $response ? wp_send_json_success( array( 'status' => $message ) ) : wp_send_json_error();
	}

	/**
	 * Execute bulk action for enrollment list ex: complete | cancel
	 *
	 * @since 2.0.0
	 *
	 * @param string $status hold status for updating.
	 * @param string $user_ids comma seperated user ids.
	 *
	 * @return bool
	 */
	public static function update_instructors( $status, $user_ids ): bool {
		global $wpdb;
		$status           = sanitize_text_field( $status );
		$instructor_table = $wpdb->usermeta;

		$ids       = array_map( 'intval', explode( ',', $user_ids ) );
		$in_clause = QueryHelper::prepare_in_clause( $ids );

		//phpcs:disable WordPress.DB.PreparedSQL.InterpolatedNotPrepared
		$update = $wpdb->query(
			$wpdb->prepare(
				"UPDATE {$instructor_table} SET meta_value = %s 
				WHERE user_id IN ($in_clause) 
				AND meta_key = %s",
				$status,
				'_tutor_instructor_status'
			)
		);
		//phpcs:enable WordPress.DB.PreparedSQL.InterpolatedNotPrepared

		// Remove role.
		if ( 'pending' === $status || 'blocked' === $status ) {
			$arr = explode( ',', $user_ids );
			foreach ( $arr as $instructor_id ) {
				$instructor_id = (int) sanitize_text_field( $instructor_id );
				if ( 'pending' === $status ) {
					self::remove_instructor_role( $instructor_id, $status );
				} else {
					self::instructor_blockage( $instructor_id );
				}
			}
		}
		if ( 'reject' === $status ) {
			$arr = explode( ',', $user_ids );
			foreach ( $arr as $instructor_id ) {
				$instructor_id = (int) sanitize_text_field( $instructor_id );
				self::instructor_rejection( $instructor_id );
			}
		}

		if ( 'approved' === $status ) {
			$arr = explode( ',', $user_ids );
			foreach ( $arr as $instructor_id ) {
				$instructor_id = (int) sanitize_text_field( $instructor_id );
				self::add_instructor_role( $instructor_id, $status );
			}
		}
		return false === $update ? false : true;
	}

	/**
	 * Get total course.
	 *
	 * @since 1.0.0
	 *
	 * @param object $item item.
	 * @return void
	 */
	public function column_total_course( $item ) {
		global $wpdb;
		$course_post_type = tutor()->course_post_type;

		$total_course = (int) $wpdb->get_var(
			$wpdb->prepare(
				"SELECT count(ID) from {$wpdb->posts}
			WHERE post_author=%d AND post_type=%s ",
				$item->ID,
				$course_post_type
			)
		);

		echo esc_html( $total_course );
	}

	/**
	 * Initialize instructor_role to a user
	 *
	 * @since 1.0.0
	 *
	 * @param integer $instructor_id | user id that need to add role.
	 * @param string  $status | status that will added with role (approved).
	 *
	 * @return void
	 */
	protected static function add_instructor_role( int $instructor_id, string $status ) {
		$instructor_id = sanitize_text_field( $instructor_id );
		$status        = sanitize_text_field( $status );

		do_action( 'tutor_before_approved_instructor', $instructor_id );

		update_user_meta( $instructor_id, '_tutor_instructor_status', $status );
		update_user_meta( $instructor_id, '_tutor_instructor_approved', tutor_time() );

		$instructor = new \WP_User( $instructor_id );
		$instructor->add_role( tutor()->instructor_role );

		// TODO: send E-Mail to this user about instructor approval, should via hook.
		do_action( 'tutor_after_approved_instructor', $instructor_id );
	}

	/**
	 * Initialize instructor_role to a user
	 *
	 * @since 1.0.0
	 *
	 * @param int    $instructor_id | user id that need to add role.
	 * @param string $status | status that will added with role (approved).
	 *
	 * @return void
	 */
	protected static function remove_instructor_role( int $instructor_id, string $status ) {
		$instructor_id = sanitize_text_field( $instructor_id );
		$status        = sanitize_text_field( $status );
		update_user_meta( $instructor_id, '_tutor_instructor_status', $status );
		$instructor = new \WP_User( $instructor_id );
		$instructor->remove_role( tutor()->instructor_role );
	}
	/**
	 * Instructor blocking function
	 *
	 * @since 2.5.0
	 *
	 * @param int $instructor_id | user id that need to add role.
	 * @return void
	 */
	protected static function instructor_blockage( int $instructor_id ) {
		$instructor_id = sanitize_text_field( $instructor_id );
		do_action( 'tutor_before_blocked_instructor', $instructor_id );
		self::remove_instructor_role( $instructor_id, 'blocked' );
		do_action( 'tutor_after_blocked_instructor', $instructor_id );
	}
	/**
	 * Instructor rejection function
	 *
	 * @since 2.5.0
	 *
	 * @param int $instructor_id | user id that need to add role.
	 * @return void
	 */
	protected static function instructor_rejection( int $instructor_id ) {
		$instructor_id = sanitize_text_field( $instructor_id );
		do_action( 'tutor_before_rejected_instructor', $instructor_id );

		/**
		 * Removed tutor_instructor role and set `try_again` status
		 * for apply again as instructor with show message to applier in frontend.
		 */
		self::remove_instructor_role( $instructor_id, 'try_again' );
		delete_user_meta( $instructor_id, '_is_tutor_instructor' );

		do_action( 'tutor_after_rejected_instructor', $instructor_id );
	}

	/**
	 * Get instructors list
	 *
	 * @since 2.1.7
	 *
	 * @param array  $status instructor status: approved, pending, block.
	 * @param int    $offset offset for pagination.
	 * @param int    $per_page per page limit.
	 * @param string $search search keyword.
	 * @param string $course_id course id.
	 * @param string $date instructor registration date.
	 * @param string $order sorting order.
	 *
	 * @return wpdb::results
	 */
	public static function get_instructors( array $status, $offset, $per_page, $search = '', $course_id = '', $date = '', $order = 'DESC' ) {
		global $wpdb;

		$wild = '%';

		$search_clause = $wild . $wpdb->esc_like( $search ) . $wild;
		$course_clause = '';
		if ( '' !== $course_id ) {
			$course_id     = (int) $course_id;
			$course_clause = "AND umeta.meta_value = {$course_id}";
		}

		$order_clause = '';
		if ( '' !== $order ) {
			$is_valid_sql = sanitize_sql_orderby( $order );
			if ( $is_valid_sql ) {
				$order_clause = "ORDER BY user.ID {$order}";
			}
		}

		$date_clause   = '' !== $date ? "AND DATE(user.user_registered) = CAST('$date' AS DATE )" : '';
		$in_clause     = QueryHelper::prepare_in_clause( $status );

		$query  = "SELECT
					DISTINCT user.*,
					ins_status.meta_value AS status,
					(
						SELECT
							COUNT(*)
							FROM {$wpdb->posts}
							WHERE post_author = user.ID
								AND post_type = 'courses'
					) total_courses
					FROM {$wpdb->users} AS user
						
					INNER JOIN {$wpdb->usermeta} AS ins_status
						ON ( user.ID = ins_status.user_id )
						AND ins_status.meta_key = '_tutor_instructor_status'
					LEFT JOIN {$wpdb->usermeta} AS umeta
						ON umeta.user_id = user.ID
						AND umeta.meta_key = '_tutor_instructor_course_id'
					WHERE ins_status.meta_value IN ($in_clause)
						AND (user.user_email LIKE %s OR user.display_name LIKE %s)
						{$course_clause}
						{$date_clause}
					{$order_clause}
					LIMIT %d, %d;
				";
		$result = TutorCache::get( self::INSTRUCTOR_LIST_CACHE_KEY );
		if ( false === $result ) {
			TutorCache::set(
				self::INSTRUCTOR_LIST_CACHE_KEY,
				//phpcs:disable
				$result = $wpdb->get_results(
					$wpdb->prepare(
						$query,
						$search_clause,
						$search_clause,
						$offset,
						$per_page
					)
				)
				//phpcs:enable
			);
		}

		return $result;
	}

	/**
	 * Count total instructors
	 *
	 * @since 2.1.7
	 *
	 * @param array  $status instructor status: approved, pending, block.
	 * @param string $search search keyword.
	 * @param string $course_id course id.
	 * @param string $date instructor registration date.
	 * @param string $unique_cache_key unique key will be append with
	 * self::INSTRUCTOR_COUNT_CACHE_KEY so that multiple count value could be
	 * stored as unique data.
	 *
	 * @return int count value of instructors
	 */
	public static function count_total_instructors( array $status, $search = '', $course_id = '', $date = '', $unique_cache_key = '' ) {
		global $wpdb;

		$wild = '%';

		$search_clause = $wild . $wpdb->esc_like( $search ) . $wild;
		$course_clause = '';
		if ( '' !== $course_id ) {
			$course_id     = (int) $course_id;
			$course_clause =  "AND umeta.meta_value = {$course_id}";
		}
		$date_clause   = '' !== $date ? "AND DATE(user.user_registered) = CAST('$date' AS DATE )" : '';
		$in_clause     = QueryHelper::prepare_in_clause( $status );

		$query  = "SELECT
					COUNT(DISTINCT user.ID)
					
					FROM {$wpdb->users} AS user
						
					INNER JOIN {$wpdb->usermeta} AS ins_status
						ON ( user.ID = ins_status.user_id )
						AND ins_status.meta_key = '_tutor_instructor_status'
					LEFT JOIN {$wpdb->usermeta} AS umeta
						ON umeta.user_id = user.ID
						AND umeta.meta_key = '_tutor_instructor_course_id'
					WHERE ins_status.meta_value IN ($in_clause)
						AND (user.user_email LIKE %s OR user.display_name LIKE %s)
						{$course_clause}
						{$date_clause}
				";
		$result = TutorCache::get( self::INSTRUCTOR_COUNT_CACHE_KEY . $unique_cache_key );
		if ( false === $result ) {
			TutorCache::set(
				self::INSTRUCTOR_COUNT_CACHE_KEY,
				//phpcs:disable
				$result = $wpdb->get_var(
					$wpdb->prepare(
						$query,
						$search_clause,
						$search_clause
					)
				)
				//phpcs:enable
			);
		}
		return $result;
	}
}

Filemanager

Name Type Size Permission Actions
Addons.php File 11.6 KB 0644
Admin.php File 21.3 KB 0644
Ajax.php File 16.82 KB 0644
Announcements.php File 2.67 KB 0644
Assets.php File 23.25 KB 0644
Backend_Page_Trait.php File 4.39 KB 0644
BaseController.php File 1.47 KB 0644
Course.php File 85.39 KB 0644
Course_Embed.php File 2.55 KB 0644
Course_Filter.php File 8.67 KB 0644
Course_List.php File 13.7 KB 0644
Course_Settings_Tabs.php File 1.16 KB 0644
Course_Widget.php File 8.19 KB 0644
Custom_Validation.php File 513 B 0644
Dashboard.php File 1.23 KB 0644
Earnings.php File 9.53 KB 0644
FormHandler.php File 7.16 KB 0644
Frontend.php File 2.94 KB 0644
Gutenberg.php File 4.62 KB 0644
Input.php File 9.08 KB 0644
Instructor.php File 12.99 KB 0644
Instructors_List.php File 12.97 KB 0644
Lesson.php File 17.08 KB 0644
Options_V2.php File 63.19 KB 0644
Permalink.php File 2 KB 0644
Post_types.php File 18.3 KB 0644
Private_Course_Access.php File 2.52 KB 0644
Q_And_A.php File 10.66 KB 0644
Question_Answers_List.php File 2.54 KB 0644
Quiz.php File 62.02 KB 0644
QuizBuilder.php File 11.5 KB 0644
Quiz_Attempts_List.php File 7.32 KB 0644
RestAPI.php File 7.97 KB 0644
Reviews.php File 2.71 KB 0644
Rewrite_Rules.php File 5.18 KB 0644
Shortcode.php File 14.22 KB 0644
Singleton.php File 1.08 KB 0644
Student.php File 10.18 KB 0644
Students_List.php File 2.37 KB 0644
Taxonomies.php File 8.2 KB 0644
Template.php File 14.18 KB 0644
Theme_Compatibility.php File 683 B 0644
Tools.php File 3.33 KB 0644
Tools_V2.php File 18.18 KB 0644
Tutor.php File 36.06 KB 0644
TutorEDD.php File 4.63 KB 0644
Tutor_Base.php File 1.48 KB 0644
Tutor_Setup.php File 33.25 KB 0644
Upgrader.php File 7.49 KB 0644
User.php File 14.66 KB 0644
Utils.php File 263.33 KB 0644
Video_Stream.php File 3.94 KB 0644
WhatsNew.php File 4.07 KB 0644
Withdraw.php File 9.49 KB 0644
Withdraw_Requests_List.php File 6.15 KB 0644
WooCommerce.php File 23.15 KB 0644