[ Avaa Bypassed ]




Upload:

Command:

hmhc3928@18.221.175.172: ~ $
<?php
/**
 * Handle ecommerce hooks
 *
 * @package Tutor\Ecommerce
 * @author Themeum <support@themeum.com>
 * @link https://themeum.com
 * @since 3.0.0
 */

namespace Tutor\Ecommerce;

use TUTOR\Course;
use Tutor\Models\OrderActivitiesModel;
use TUTOR\Earnings;
use Tutor\Helpers\QueryHelper;
use TUTOR\Input;
use Tutor\Models\CartModel;
use Tutor\Models\OrderModel;
use TutorPro\CourseBundle\Models\BundleModel;

/**
 * Handle custom hooks
 */
class HooksHandler {

	/**
	 * OrderModel
	 *
	 * @since 3.0.0
	 *
	 * @var OrderModel
	 */
	private $order_model;

	/**
	 * OrderActivitiesModel
	 *
	 * @since 3.0.0
	 *
	 * @var OrderActivitiesModel
	 */
	private $order_activities_model;

	/**
	 * Register hooks & resolve props
	 *
	 * @since 3.0.0
	 */
	public function __construct() {
		$this->order_activities_model = new OrderActivitiesModel();
		$this->order_model            = new OrderModel();

		// Register hooks.
		add_filter( 'tutor_course_sell_by', array( $this, 'alter_course_sell_by' ) );
		add_filter( 'get_tutor_course_price', array( $this, 'alter_course_price' ), 10, 2 );

		// Order hooks.
		add_action( 'tutor_order_payment_updated', array( $this, 'handle_payment_updated_webhook' ) );

		add_action( 'tutor_order_payment_status_changed', array( $this, 'handle_payment_status_changed' ), 10, 3 );

		add_action( 'tutor_order_placement_success', array( $this, 'handle_order_placement_success' ) );

		/**
		 * Clear order menu badge count
		 *
		 * @since 3.0.0
		 */
		add_action( 'tutor_order_placed', array( $this, 'clear_order_badge_count' ) );
		add_action( 'tutor_order_payment_status_changed', array( $this, 'clear_order_badge_count' ) );
		add_action( 'tutor_before_order_bulk_action', array( $this, 'clear_order_badge_count' ) );
	}

	/**
	 * Clear order menu badge count
	 *
	 * @since 3.0.0
	 *
	 * @return void
	 */
	public function clear_order_badge_count() {
		delete_transient( OrderModel::TRANSIENT_ORDER_BADGE_COUNT );
	}

	/**
	 * Store order activity before bulk action.
	 *
	 * @since 3.0.0
	 *
	 * @param string $bulk_action The bulk action being performed.
	 * @param array  $bulk_ids The IDs of the orders being acted upon.
	 *
	 * @return void
	 */
	public function after_order_bulk_action( $bulk_action, $bulk_ids ) {
		$order_status = $this->order_model->get_order_status_by_payment_status( $bulk_action );

		$cancel_reason = Input::post( 'cancel_reason', '' );
		foreach ( $bulk_ids as $order_id ) {
			try {
				$this->manage_earnings_and_enrollments( $order_status, $order_id );
				$data = (object) array(
					'order_id'   => $order_id,
					'meta_key'   => $this->order_activities_model::META_KEY_HISTORY,
					'meta_value' => "Order mark as {$bulk_action} {$cancel_reason}",
				);
				$this->order_activities_model->add_order_meta( $data );
			} catch ( \Throwable $th ) {
				// Log message with line & file.
				error_log( $th->getMessage() . ' in ' . $th->getFile() . ' at line ' . $th->getLine() );
			}
		}
	}

	/**
	 * Alter course sell by value
	 *
	 * @since 3.0.0
	 *
	 * @param mixed $sell_by Default sell by.
	 *
	 * @return mixed
	 */
	public function alter_course_sell_by( $sell_by ) {
		if ( tutor_utils()->is_monetize_by_tutor() ) {
			$sell_by = Ecommerce::MONETIZE_BY;
		}

		return $sell_by;
	}

	/**
	 * Alter course price to show price on the course
	 * entry box
	 *
	 * @since 3.0.0
	 *
	 * @param mixed $price Course price.
	 * @param int   $course_id Course id.
	 *
	 * @return mixed
	 */
	public function alter_course_price( $price, $course_id ) {
		$price_type = tutor_utils()->price_type( $course_id );
		if ( tutor_utils()->is_monetize_by_tutor() && Course::PRICE_TYPE_PAID === $price_type ) {
			$price = tutor_get_course_formatted_price_html( $course_id, false );
		}

		return $price;
	}

	/**
	 * Handle payment updated webhook
	 *
	 * @since 3.0.0
	 *
	 * @param object $res Response data.
	 * {order_id, transaction_id, payment_status, payment_method, redirectUrl}.
	 *
	 * @return void
	 */
	public function handle_payment_updated_webhook( $res ) {
		$order_id           = $res->id;
		$new_payment_status = $res->payment_status;
		$transaction_id     = $res->transaction_id;

		$order_details = $this->order_model->get_order_by_id( $order_id );
		if ( $order_details ) {
			$prev_payment_status = $order_details->payment_status;

			$order_data = array(
				'order_status'     => $order_details->order_status,
				'payment_status'   => $new_payment_status,
				'payment_payloads' => $res->payment_payload,
				'transaction_id'   => $transaction_id,
				'earnings'         => $res->earnings,
				'fees'             => $res->fees,
				'updated_at_gmt'   => current_time( 'mysql', true ),
			);

			switch ( $new_payment_status ) {
				case $this->order_model::PAYMENT_PAID:
					$order_data['order_status'] = $this->order_model::ORDER_COMPLETED;
					break;
				case $this->order_model::PAYMENT_FAILED:
				case $this->order_model::PAYMENT_REFUNDED:
					$order_data['order_status'] = $this->order_model::ORDER_CANCELLED;
					break;
			}

			$update = $this->order_model->update_order( $order_id, $order_data );
			if ( $update ) {
				// Provide hook after update order.
				do_action( 'tutor_order_payment_status_changed', $order_id, $prev_payment_status, $new_payment_status );
			}
		}

	}

	/**
	 * Update enrollment & earnings based on payment status
	 *
	 * @since 3.0.0
	 *
	 * @param int    $order_id Order id.
	 * @param string $prev_payment_status previous payment status.
	 * @param string $new_payment_status new payment status.
	 *
	 * @return void
	 */
	public function handle_payment_status_changed( $order_id, $prev_payment_status, $new_payment_status ) {

		$order_status = $this->order_model->get_order_status_by_payment_status( $new_payment_status );

		$cancel_reason     = Input::post( 'cancel_reason' );
		$remove_enrollment = Input::post( 'is_remove_enrolment', false, Input::TYPE_BOOL );

		// Store activity.
		$data = (object) array(
			'order_id'   => $order_id,
			'meta_key'   => $this->order_activities_model::META_KEY_HISTORY,
			'meta_value' => 'Order marked as ' . $new_payment_status,
		);

		if ( $cancel_reason ) {
			$meta_value       = array(
				'message'       => 'Order marked as ' . $new_payment_status,
				'cancel_reason' => $cancel_reason,
			);
			$data->meta_value = json_encode( $meta_value );
		}

		$this->order_activities_model->add_order_meta( $data );

		if ( $remove_enrollment ) {
			$order_status = OrderModel::ORDER_CANCELLED;
		}

		$this->manage_earnings_and_enrollments( $order_status, $order_id );

		// Store coupon usage.
		( new CouponController( false ) )->store_coupon_usage( $order_id );
	}

	/**
	 * Handle new order placement
	 *
	 * Clear cart items, managing enrollment & earnings
	 *
	 * @since 3.0.0
	 *
	 * @param int $order_id Order id.
	 *
	 * @return void
	 */
	public function handle_order_placement_success( int $order_id ) {
		$order_data = $this->order_model->get_order_by_id( $order_id );
		if ( $order_data ) {
			$user_id = $order_data->student->id;

			( new CartModel() )->clear_user_cart( $user_id );

			// Manage enrollment & earnings.
			$order          = ( new OrderModel() )->get_order_by_id( $order_id );
			$payment_status = $order->payment_status;

			$order_status = $this->order_model->get_order_status_by_payment_status( $payment_status );

			$this->manage_earnings_and_enrollments( $order_status, $order_id );
		}
	}

	/**
	 * Check if order is bundle order
	 *
	 * @since 3.0.0
	 *
	 * @param object $order order object.
	 * @param int    $object_id object id.
	 *
	 * @return boolean
	 */
	private function is_bundle_order( $order, $object_id ) {
		return tutor_utils()->is_addon_enabled( 'course-bundle' )
		&& in_array( $order->order_type, array( $this->order_model::TYPE_SINGLE_ORDER, $this->order_model::TYPE_SUBSCRIPTION ), true )
		&& 'course-bundle' === get_post_type( $object_id );
	}

	/**
	 * Manage earnings after order bulk action
	 *
	 * @since 3.0.0
	 *
	 * @param string $order_status Order status.
	 * @param int    $order_id Order ID.
	 *
	 * @return void
	 */
	public function manage_earnings_and_enrollments( string $order_status, int $order_id ) {
		$earnings   = Earnings::get_instance();
		$order      = $this->order_model->get_order_by_id( $order_id );
		$student_id = $order->student->id;

		$enrollment_status = ( OrderModel::ORDER_COMPLETED === $order_status ? 'completed' : ( OrderModel::ORDER_INCOMPLETE === $order->order_status ? 'pending' : 'cancel' ) );

		foreach ( $order->items as $item ) {
			$object_id = $item->id; // It could be course/bundle/plan id.
			if ( $this->order_model::TYPE_SINGLE_ORDER !== $order->order_type ) {
				$object_id = apply_filters( 'tutor_subscription_course_by_plan', $item->id, $order );

				/**
				 * Do not process enrollment for membership plan.
				 *
				 * @since 3.2.0
				 */
				$plan_info = apply_filters( 'tutor_get_plan_info', new \stdClass(), $object_id );
				if ( $plan_info && isset( $plan_info->is_membership_plan ) && $plan_info->is_membership_plan ) {
					continue;
				}
			}

			$has_enrollment = tutor_utils()->is_enrolled( $object_id, $student_id, false );
			if ( $has_enrollment ) {
				// Update enrollment status based on order status.
				$update = tutor_utils()->update_enrollments( $enrollment_status, array( $has_enrollment->ID ) );
				if ( $update ) {
					if ( $this->is_bundle_order( $order, $object_id ) && $this->order_model->is_single_order( $order ) ) {
						if ( 'completed' === $enrollment_status ) {
							BundleModel::enroll_to_bundle_courses( $object_id, $student_id );
						} else {
							BundleModel::disenroll_from_bundle_courses( $object_id, $student_id );
						}
					}

					/**
					 * For subscription, renewal no need to update order id.
					 */
					if ( $this->order_model->is_single_order( $order ) ) {
						update_post_meta( $has_enrollment->ID, '_tutor_enrolled_by_order_id', $order_id );

						/**
						 * Update enrollment expiry date if it is set in a course.
						 */
						if ( tutor()->course_post_type === get_post_type( $object_id ) ) {
							$is_set_enrollment_expiry  = (int) get_tutor_course_settings( $object_id, 'enrollment_expiry' );
							$enrollment_expiry_enabled = (bool) get_tutor_option( 'enrollment_expiry_enabled' );
							if ( $enrollment_expiry_enabled && $is_set_enrollment_expiry ) {
								global $wpdb;
								QueryHelper::update(
									$wpdb->posts,
									array(
										'post_date'     => current_time( 'mysql' ),
										'post_date_gmt' => current_time( 'mysql', true ),
									),
									array(
										'ID'        => $has_enrollment->ID,
										'post_type' => tutor()->enrollment_post_type,
									)
								);
							}
						}

						if ( OrderModel::ORDER_COMPLETED === $order_status ) {
							do_action( 'tutor_after_enrolled', $object_id, $student_id, $has_enrollment->ID );
						}
					}

					if ( 'completed' === $enrollment_status ) {
						do_action( 'tutor_order_enrolled', $order, $has_enrollment->ID );
					}
				}
			} else {
				if ( $order->order_status === $this->order_model::ORDER_COMPLETED ) {
					// Insert enrollment.
					add_filter( 'tutor_enroll_data', fn( $enroll_data) => array_merge( $enroll_data, array( 'post_status' => 'completed' ) ) );

					$enrollment_id = tutor_utils()->do_enroll( $object_id, $order_id, $student_id );
					if ( $enrollment_id ) {
						if ( $this->is_bundle_order( $order, $object_id ) && $this->order_model->is_single_order( $order ) ) {
							BundleModel::enroll_to_bundle_courses( $object_id, $student_id );
						}
						update_post_meta( $enrollment_id, '_tutor_enrolled_by_order_id', $order_id );

						do_action( 'tutor_order_enrolled', $order, $enrollment_id );
					} else {
						// Log error message with student id and course id.
						error_log( "Error updating enrollment for student {$student_id} and course {$object_id}" );
					}
				}
			}
		}

		// Update earnings.
		$earnings->prepare_order_earnings( $order_id );
		$earnings->remove_before_store_earnings();
	}
}


Filemanager

Name Type Size Permission Actions
PaymentGateways Folder 0755
AdminMenu.php File 2.34 KB 0644
BillingController.php File 5.57 KB 0644
CartController.php File 5.46 KB 0644
CheckoutController.php File 26.97 KB 0644
CouponController.php File 21.48 KB 0644
Ecommerce.php File 5.12 KB 0644
EmailController.php File 24.96 KB 0644
HooksHandler.php File 11.75 KB 0644
OptionKeys.php File 1.77 KB 0644
OrderActivitiesController.php File 4.57 KB 0644
OrderController.php File 33.34 KB 0644
PaymentHandler.php File 4.25 KB 0644
Settings.php File 12.7 KB 0644
Tax.php File 6.35 KB 0644
currency.php File 27.51 KB 0644