gocodebox/lifterlms

View on GitHub
includes/admin/class.llms.admin.setup.wizard.php

Summary

Maintainability
A
1 hr
Test Coverage
B
83%
<?php
/**
 * Display a Setup Wizard
 *
 * @package LifterLMS/Admin/Classes
 *
 * @since 3.0.0
 * @version 7.4.0
 */

defined( 'ABSPATH' ) || exit;

/**
 * Display a Setup Wizard class.
 *
 * @since 3.0.0
 * @since 3.30.3 Fixed spelling error.
 * @since 3.35.0 Sanitize input data.
 * @since 3.37.14 Ensure redirect to the imported course when a course is imported at setup completion.
 * @since 4.4.4 Method `LLMS_Admin_Setup_Wizard::scripts()` & `LLMS_Admin_Setup_Wizard::output_step_html()` are deprecated with no replacements.
 * @since 4.8.0 Removed private class property "generated_course_id".
 * @since 6.0.0 Removed deprecated items.
 *              - `LLMS_Admin_Setup_Wizard::generator_course_status()` method
 *              - `LLMS_Admin_Setup_Wizard::output_step_html()` method
 *              - `LLMS_Admin_Setup_Wizard::scripts()` method
 *              - `LLMS_Admin_Setup_Wizard::watch_course_generation()` method
 * @since 7.4.0 Abstracted: {@see LLMS_Abstract_Admin_Wizard}.
 */
class LLMS_Admin_Setup_Wizard extends LLMS_Abstract_Admin_Wizard {

    /**
     * Configure wizard.
     *
     * @since 3.0.0
     * @since 4.4.4 Remove output of inline scripts.
     * @since 7.4.0
     *
     * @return void
     */
    public function __construct() {
        $this->id        = 'setup';
        $this->views_dir = LLMS_PLUGIN_DIR . 'includes/admin/views/setup-wizard/';
        $this->title     = esc_html__( 'LifterLMS Setup Wizard', 'lifterlms' );
        $this->steps     = array(
            'intro'    => array(
                'title' => esc_html__( 'Welcome!', 'lifterlms' ),
                'save'  => esc_html__( 'Save & Continue', 'lifterlms' ),
                'skip'  => esc_html__( 'Skip this step', 'lifterlms' ),
            ),
            'pages'    => array(
                'title' => esc_html__( 'Page Setup', 'lifterlms' ),
                'save'  => esc_html__( 'Save & Continue', 'lifterlms' ),
                'skip'  => esc_html__( 'Skip this step', 'lifterlms' ),
            ),
            'payments' => array(
                'title' => esc_html__( 'Payments', 'lifterlms' ),
                'save'  => esc_html__( 'Save & Continue', 'lifterlms' ),
                'skip'  => esc_html__( 'Skip this step', 'lifterlms' ),
            ),
            'coupon'   => array(
                'title' => esc_html__( 'Coupon', 'lifterlms' ),
                'save'  => esc_html__( 'Allow', 'lifterlms' ),
                'skip'  => esc_html__( 'No thanks', 'lifterlms' ),
            ),
            'finish'   => array(
                'title' => esc_html__( 'Finish!', 'lifterlms' ),
                'save'  => esc_html__( 'Import Courses', 'lifterlms' ),
                'skip'  => esc_html__( 'Skip this step', 'lifterlms' ),
            ),
        );

        $this->add_hooks();

        // Add HTML around importable courses on last step.
        add_action( 'llms_before_importable_course', array( $this, 'output_before_importable_course' ) );
        add_action( 'llms_after_importable_course', array( $this, 'output_after_importable_course' ) );

        // Hide action buttons on importable courses during last step.
        add_filter( 'llms_importable_course_show_action', '__return_false' );

        // Enqueue importer styles.
        add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_importer' ) );
    }

    /**
     * Enqueue importer styles.
     *
     * @since 7.4.0
     *
     * @return bool
     */
    public function enqueue_importer(): bool {
        if ( 'finish' === $this->get_current_step() ) {
            return llms()->assets->enqueue_style( 'llms-admin-importer' );
        }

        return false;
    }

    /**
     * Output HTML prior to each importable course
     *
     * Adds an opening label wrapper and adds HTML data to turn the element into a toggleable form element.
     *
     * @since 4.8.0
     *
     * @param array $course Importable course data array.
     * @return void
     */
    public function output_before_importable_course( array $course ): void {

        $id = absint( $course['id'] ?? null );
        ?>
        <label>
        <div class="llms-switch">
            <input class="llms-toggle llms-toggle-round" id="llms-setup-import-course-<?php echo esc_attr( $id ); ?>" name="llms_setup_course_import_ids[]" value="<?php echo esc_attr( $id ); ?>" type="checkbox">
            <label for="llms-setup-import-course-<?php echo esc_attr( $id ); ?>"><span class="screen-reader-text"><?php esc_attr_e( 'Toggle to import course', 'lifterlms' ); ?>
            </label>
        </div>
        <?php

    }

    /**
     * Output HTML after to each importable course
     *
     * Closes the label element opened in `output_before_importable_course()`.
     *
     * @since 4.8.0
     *
     * @param array $course Importable course data array.
     * @return void
     */
    public function output_after_importable_course( array $course ): void {
        echo '</label>';
    }

    /**
     * Retrieve the redirect URL to use after an import is complete at the conclusion of the wizard.
     *
     * If a single course is imported, redirects to that course's edit page, otherwise redirects
     * to the course post table list sorted by created date with the most recent courses first.
     *
     * @since 7.4.0
     *
     * @param int[] $course_ids WP_Post IDs of the course(s) generated during the import.
     * @return string
     */
    protected function get_completed_url( array $course_ids ): string {

        $count = count( $course_ids );

        if ( 1 === $count ) {
            return get_edit_post_link( $course_ids[0], 'not-display' ) ?? '';
        }

        return admin_url( 'edit.php?post_type=course&orderby=date&order=desc' );

    }

    /**
     * Save the "Coupon" step
     *
     * @since 4.8.0
     *
     * @return WP_Error|boolean Returns `true` on success otherwise returns a WP_Error.
     */
    protected function save_coupon() {

        update_option( 'llms_allow_tracking', 'yes' );

        $req = LLMS_Tracker::send_data( true );
        $ret = new WP_Error( 'llms-setup-coupon-save-unknown', esc_html__( 'There was an error saving your data, please try again.', 'lifterlms' ) );

        if ( is_wp_error( $req ) ) {
            $ret = $req;
        } elseif ( empty( $req['success'] ) && isset( $req['message'] ) ) {
            $ret = new WP_Error( 'llms-setup-coupon-save-tracking-api', $req['message'] );
        } elseif ( ! empty( $req['success'] ) && true === $req['success'] ) {
            $ret = true;
        }

        return $ret;

    }

    /**
     * Save the "Pages" creation step
     *
     * @since 4.8.0
     *
     * @return WP_Error|boolean Returns `true` on success otherwise returns a WP_Error.
     */
    protected function save_pages() {

        return LLMS_Install::create_pages() ? true : new WP_Error( 'llms-setup-pages-save', esc_html__( 'There was an error saving your data, please try again.', 'lifterlms' ) );

    }

    /**
     * Save the "Payments" step.
     *
     * @since 4.8.0
     * @since 5.9.0 Stop using deprecated `FILTER_SANITIZE_STRING`.
     *
     * @return bool Always returns true.
     */
    protected function save_payments(): bool {

        // phpcs:disable WordPress.Security.NonceVerification.Missing -- nonce is verified in `save()`.
        $country = isset( $_POST['country'] ) ? llms_filter_input_sanitize_string( INPUT_POST, 'country' ) : get_lifterlms_country();
        update_option( 'lifterlms_country', $country );

        $currency = isset( $_POST['currency'] ) ? llms_filter_input_sanitize_string( INPUT_POST, 'currency' ) : get_lifterlms_currency();
        update_option( 'lifterlms_currency', $currency );

        $manual = isset( $_POST['manual_payments'] ) ? llms_filter_input_sanitize_string( INPUT_POST, 'manual_payments' ) : 'no';
        update_option( 'llms_gateway_manual_enabled', $manual );
        // phpcs:enable WordPress.Security.NonceVerification.Missing

        return true;

    }

    /**
     * Save the "Finish" step.
     *
     * @since 4.8.0
     *
     * @return WP_Error|int[]|bool Returns an array of generated WP_Post IDs on success, `false` when no import IDs are posted, otherwise returns a WP_Error.
     */
    protected function save_finish() {

        $ids = (array) llms_filter_input( INPUT_POST, 'llms_setup_course_import_ids', FILTER_DEFAULT, FILTER_FORCE_ARRAY );
        $ids = array_filter( array_map( 'absint', $ids ) );
        if ( ! $ids ) {
            return false;
        }

        $res = LLMS_Export_API::get( $ids );
        if ( is_wp_error( $res ) ) {
            return $res;
        }

        $gen = new LLMS_Generator( $res );
        $gen->set_generator();
        $gen->generate();

        if ( $gen->is_error() ) {
            return $gen->get_results();
        }

        return $gen->get_generated_courses();

    }

}

return new LLMS_Admin_Setup_Wizard();