class.llms.student.bulk.enroll.php 7.04 KB
Newer Older
cyrille's avatar
cyrille committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275
<?php
/**
 * Bulk Enrollment
 *
 * @package LifterLMS/Admin/Classes
 *
 * @since 3.20.0
 * @version 3.21.0
 */

defined( 'ABSPATH' ) || exit;

/**
 * Bulk Enrollment class
 *
 * @since 3.20.0
 * @since 3.30.3 Explicitly define class properties.
 */
class LLMS_Student_Bulk_Enroll {

	/**
	 * Admin notices
	 *
	 * @var string[]
	 * @since 3.19.4
	 */
	public $admin_notices = array();

	/**
	 * Product (Course/Membership) ID
	 *
	 * @var int
	 */
	public $product_id = 0;

	/**
	 * Product Post Title
	 *
	 * @var string
	 */
	public $product_title = '';

	/**
	 * User IDs
	 *
	 * @var int
	 */
	public $user_ids = array();

	/**
	 * Constructor
	 *
	 * @since   3.20.0
	 * @version 3.20.0
	 */
	public function __construct() {
		// Hook into extra ui on users table to display product selection.
		add_action( 'manage_users_extra_tablenav', array( $this, 'display_product_selection_for_bulk_users' ) );

		// Hook into users table screen to process bulk enrollment.
		add_action( 'admin_head-users.php', array( $this, 'maybe_enroll_users_in_product' ) );

		// Display enrollment results as notices.
		add_action( 'admin_notices', array( $this, 'display_notices' ) );
	}

	/**
	 * Displays ui for selecting product to bulk enroll users into
	 *
	 * @param   string $which
	 * @since   3.20.0
	 * @version 3.20.0
	 */
	public function display_product_selection_for_bulk_users( $which ) {

		// The attributes need to be different for top and bottom of the table.
		$id     = 'bottom' === $which ? 'llms_bulk_enroll_product2' : 'llms_bulk_enroll_product';
		$submit = 'bottom' === $which ? 'llms_bulk_enroll2' : 'llms_bulk_enroll';
		?>
		<div class="alignleft actions">
			<label class="screen-reader-text" for="_llms_bulk_enroll_product">
				<?php _e( 'Choose Course/Membership', 'lifterlms' ); ?>
			</label>
			<select id="<?php echo $id; ?>" class="llms-posts-select2 llms-bulk-enroll-product" data-post-type="llms_membership,course" name="<?php echo $id; ?>" style="min-width:200px;max-width:auto;">
			</select>
			<input type="submit" name="<?php echo $submit; ?>" id="<?php echo $submit; ?>" class="button" value="<?php esc_attr_e( 'Enroll', 'lifterlms' ); ?>">
		</div>
		<?php
	}

	/**
	 * Conditionally enrolls multiple users into a product
	 *
	 * @return  void
	 * @since   3.20.0
	 * @version 3.20.0
	 */
	public function maybe_enroll_users_in_product() {

		// Verify bulk enrollment request.
		$do_bulk_enroll = $this->_bottom_else_top( 'llms_bulk_enroll' );

		// Bail if this is not a bulk enrollment request.
		if ( empty( $do_bulk_enroll ) ) {
			return;
		}

		// Get the product (course/membership) to enroll users in.
		$this->product_id = $this->_bottom_else_top( 'llms_bulk_enroll_product', FILTER_VALIDATE_INT );

		if ( empty( $this->product_id ) ) {
			$message = __( 'Please select a Course or Membership to enroll users into!', 'lifterlms' );
			$this->generate_notice( 'error', $message );
			return;
		}

		// Get the product title for notices.
		$this->product_title = get_the_title( $this->product_id );

		// Get all the user ids to enroll.
		$this->user_ids = filter_input( INPUT_GET, 'users', FILTER_DEFAULT, FILTER_REQUIRE_ARRAY );

		if ( empty( $this->user_ids ) ) {
			$message = sprintf( __( 'Please select users to enroll into <em>%s</em>.', 'lifterlms' ), $this->product_title );
			$this->generate_notice( 'error', $message );
			return;
		}

		$this->enroll_users_in_product();

	}

	/**
	 * Retrieves submitted inputs
	 *
	 * @param   string $param The input key
	 * @param   mixed  $validation Validation filter constant
	 * @return  mixed The submitted input value
	 * @since   3.20.0
	 * @version 3.20.0
	 */
	private function _bottom_else_top( $param, $validation = FILTER_DEFAULT ) {

		$return_val = false;

		// Get the value of the input displayed at the bottom of users table.
		$bottom_value = filter_input( INPUT_GET, $param . '2', $validation );

		// Get the value of input displayed at the top of users table.
		$top_value = filter_input( INPUT_GET, $param, $validation );

		// Prefer top over bottom, just like WordPress does.
		if ( ! empty( $bottom_value ) ) {
			$return_val = $bottom_value;
		}
		if ( ! empty( $top_value ) ) {
			$return_val = $top_value;
		}

		return $return_val;
	}

	/**
	 * Enrolls multiple users into a product
	 *
	 * @since   3.20.0
	 * @version 3.20.0
	 */
	private function enroll_users_in_product() {

		// Get user information from user ids.
		$users = $this->get_users( $this->user_ids );

		// Bail if for some reason, no users are found (because they were deleted in the bg?).
		if ( empty( $users ) ) {
			$message = sprintf( __( 'No such users found. Cannot enroll into <em>%s</em>.', 'lifterlms' ), $this->product_title );
			$this->generate_notice( 'error', $message );
			return;
		}

		// Create manual enrollment trigger.
		$trigger = 'admin_' . get_current_user_id();

		foreach ( $users as $user ) {

			$this->enroll( $user, $trigger );
		}
	}

	/**
	 * Get user details from user IDs

	 * @param   array $user_ids WP user IDs
	 * @return  array User details
	 * @since   3.20.0
	 * @version 3.21.0
	 */
	private function get_users( $user_ids ) {

		// Prepare query arguments.
		$user_query_args = array(
			'include' => $user_ids,
			// We need display names for notices.
			'fields'  => array( 'ID', 'display_name' ),
		);

		$user_query = new WP_User_Query( $user_query_args );

		$results = $user_query->get_results();

		return empty( $results ) ? false : $results;
	}

	/**
	 * Enrolls a user into the selected product
	 *
	 * @param   WP_User $user User object
	 * @param   string  $trigger Enrollment trigger string
	 * @since   3.20.0
	 * @version 3.20.0
	 */
	private function enroll( $user, $trigger ) {

		// Enroll into LifterLMS product.
		$enrolled = llms_enroll_student( $user->ID, $this->product_id, $trigger );

		// Figure out notice type based on enrollment success.
		$type = ( ! $enrolled ) ? 'error' : 'success';

		// Figure out notice message string based on notice type.
		$success_fail_string = ( ! $enrolled ) ? __( 'Failed to enroll <em>%1$1s</em> into <em>%2$2s</em>.', 'lifterlms' ) : __( 'Successfully enrolled <em>%1$1s</em> into <em>%2$2s</em>.', 'lifterlms' );

		// Get formatted message with username and product title.
		$message = sprintf( $success_fail_string, $user->display_name, $this->product_title );

		// Generate a notice for display.
		$this->generate_notice( $type, $message );
	}

	/**
	 * Generates admin notice markup
	 *
	 * @param   string $type Type of notice 'error' or 'success'
	 * @param   string $message Notice message
	 * @since   3.20.0
	 * @version 3.20.0
	 */
	public function generate_notice( $type, $message ) {
		ob_start();
		?>
		<div class="notice notice-<?php echo $type; ?> is-dismissible">
			<p><?php echo $message; ?></p>
		</div>
		<?php
		$notice                = ob_get_clean();
		$this->admin_notices[] = $notice;
	}

	/**
	 * Displays all generated notices
	 *
	 * @return  void
	 * @since   3.20.0
	 * @version 3.20.0
	 */
	public function display_notices() {
		if ( empty( $this->admin_notices ) ) {
			return;
		}
		echo implode( "\n", $this->admin_notices );
	}

}

return new LLMS_Student_Bulk_Enroll();