diff --git a/classes/Dependency.php b/classes/Dependency.php index c6217d4..8fc327b 100644 --- a/classes/Dependency.php +++ b/classes/Dependency.php @@ -46,7 +46,7 @@ public function show_admin_notice() { ?>

- +

@@ -66,13 +66,18 @@ public function show_admin_notice() { * @since v2.0.0 */ public function is_tutor_core_has_req_verion(): bool { - $file_path = WP_PLUGIN_DIR . '/tutor/tutor.php'; - $plugin_data = get_file_data( + $file_path = WP_PLUGIN_DIR . '/tutor/tutor.php'; + if ( ! file_exists( $file_path ) ) { + return false; + } + + $plugin_data = get_file_data( $file_path, array( 'Version' => 'Version', ) ); + $tutor_version = $plugin_data['Version']; $tutor_core_req_version = TLMT_TUTOR_CORE_REQ_VERSION; $is_compatible = version_compare( $tutor_version, $tutor_core_req_version, '>=' ); diff --git a/classes/LDtoTutorMigration.php b/classes/LDtoTutorMigration.php index a9c5810..66dd2a2 100644 --- a/classes/LDtoTutorMigration.php +++ b/classes/LDtoTutorMigration.php @@ -1,666 +1,673 @@ + * @link https://themeum.com + * @since 2.3.0 + */ + defined( 'ABSPATH' ) || exit; - if (! class_exists('LDtoTutorMigration')) { - class LDtoTutorMigration - { - public function __construct() - { - add_filter('tutor_tool_pages', array($this, 'ld_tool_pages')); - add_action('wp_ajax_insert_tutor_migration_data', array($this, 'insert_tutor_migration_data')); - add_action('wp_ajax_ld_migrate_all_data_to_tutor', array($this, 'ld_migrate_all_data_to_tutor')); - add_action('wp_ajax_ld_reset_migrated_items_count', array($this, 'ld_reset_migrated_items_count')); - add_action('wp_ajax__get_ld_live_progress_course_migrating_info', array($this, '_get_ld_live_progress_course_migrating_info')); - add_action('tutor_action_ld_order_migrate', array($this, 'ld_order_migrate')); - } - - public function insert_tutor_migration_data(){ - global $wpdb; - - tutor_utils()->checking_nonce(); - - Utils::check_course_access(); - - $tutor_migration_table_data = [ - 'migration_type' => $_POST['migration_type'], - 'migration_vendor' => $_POST['migration_vendor'], - 'created_by' => get_current_user_id(), - 'created_at' => current_time('mysql'), - ]; - - $wpdb->insert( - $wpdb->prefix . 'tutor_migration', - $tutor_migration_table_data - ); - } - - - public function ld_tool_pages($pages) - { - // if (defined('LEARNDASH_VERSION') && !defined('LEARNPRESS_VERSION') ) { - if (defined('LEARNDASH_VERSION') ) { - // $pages['migration_ld'] = array('title' => __('LearnDash Migration', 'tutor-lms-migration-tool'), 'view_path' => TLMT_PATH.'views/migration_ld.php'); - $pages['migration_ld'] = array( - 'label' => __( 'LearnDash Migration', 'tutor' ), - 'slug' => 'migration_ld', - 'desc' => __( 'LearnDash Migration', 'tutor' ), - 'template' => 'migration_ld', - 'view_path' => TLMT_PATH . 'views/', - 'icon' => 'tutor-icon-brand-learndash', - 'blocks' => array( - 'block' => array(), - ), - ); - } - return $pages; - } - - - public function ld_reset_migrated_items_count() - { - - tutor_utils()->checking_nonce(); - - Utils::check_course_access(); - - - delete_option('_tutor_migrated_items_count'); - } - - - public function ld_migrate_all_data_to_tutor() - { - tutor_utils()->checking_nonce(); - - Utils::check_course_access(); - - - if (isset($_POST['migrate_type'])) { - $migrate_type = sanitize_text_field($_POST['migrate_type']); - - switch ($migrate_type) { - case 'courses': - $this->ld_migrate_course_to_tutor(); - break; - - case 'orders': - $this->ld_order_migrate(); - break; - } - - wp_send_json_success(); - } - wp_send_json_error(); - } - - /* - * Course Migration - */ - public function ld_migrate_course_to_tutor($return_type = false) - { - global $wpdb; - $ld_courses = $wpdb->get_results("SELECT ID, post_author, post_date, post_content, post_title, post_excerpt, post_status FROM {$wpdb->posts} WHERE post_type = 'sfwd-courses' AND (post_status = 'publish' OR post_status = 'draft');"); - - $course_type = tutor()->course_post_type; - - if (tutils()->count($ld_courses)) { - $course_i = (int) get_option('_tutor_migrated_items_count'); - $i = 0; - foreach ($ld_courses as $ld_course) { - $course_i++; - $course_id = $this->update_post($ld_course->ID, $course_type, 0, ''); - if ($course_id) { - $this->migrate_course($ld_course->ID, $course_id); - - update_option('_tutor_migrated_items_count', $course_i); - - // Attached Product - $this->attached_product($course_id, $ld_course->post_title); - - // Attached Prerequisite - $this->attached_prerequisite($course_id); - - // Add Enrollments - $this->insert_enrollment($course_id); - - // Attached thumbnail - $this->insert_thumbnail($ld_course->ID, $course_id); - } - } - - } - wp_send_json_success(); - - } - - public function attached_prerequisite($course_id){ - $course_data = get_post_meta($course_id, '_sfwd-courses', true); - if( $course_data['sfwd-courses_course_prerequisite'] ) { - update_post_meta($course_id, '_tutor_course_prerequisites_ids', $course_data['sfwd-courses_course_prerequisite']); - } - } - - /** - * Insert thumbnail ID - */ - public function insert_thumbnail($new_thumbnail_id, $thumbnail_id) - { - $thumbnail = get_post_meta($thumbnail_id, '_thumbnail_id', true); - if ($thumbnail) { - set_post_thumbnail($new_thumbnail_id, $thumbnail); - } - } - - - /** - * Insert Enbrolement LD to Tutor - */ - public function insert_enrollment($course_id) - { - global $wpdb; - $ld_course_complete_datas = $wpdb->get_results("SELECT * from {$wpdb->prefix}learndash_user_activity WHERE activity_type = 'course' AND activity_status = 1"); - - foreach ($ld_course_complete_datas as $ld_course_complete_data){ - $user_id = $ld_course_complete_data->user_id; - $complete_course_id = $ld_course_complete_data->course_id; - - if ( ! tutils()->is_enrolled($course_id, $user_id)) { - - $date = date( 'Y-m-d H:i:s', tutor_time() ); - - do { - $hash = substr( md5( wp_generate_password( 32 ) . $date . $complete_course_id . $user_id ), 0, 16 ); - $hasHash = (int) $wpdb->get_var( - $wpdb->prepare( - "SELECT COUNT(comment_ID) from {$wpdb->comments} +if ( ! class_exists( 'LDtoTutorMigration' ) ) { + class LDtoTutorMigration { + + public function __construct() { + add_filter( 'tutor_tool_pages', array( $this, 'ld_tool_pages' ) ); + add_action( 'wp_ajax_insert_tutor_migration_data', array( $this, 'insert_tutor_migration_data' ) ); + add_action( 'wp_ajax_ld_migrate_all_data_to_tutor', array( $this, 'ld_migrate_all_data_to_tutor' ) ); + add_action( 'wp_ajax_ld_reset_migrated_items_count', array( $this, 'ld_reset_migrated_items_count' ) ); + add_action( 'wp_ajax__get_ld_live_progress_course_migrating_info', array( $this, '_get_ld_live_progress_course_migrating_info' ) ); + add_action( 'tutor_action_ld_order_migrate', array( $this, 'ld_order_migrate' ) ); + } + + public function insert_tutor_migration_data() { + global $wpdb; + + tutor_utils()->checking_nonce(); + + Utils::check_course_access(); + + $tutor_migration_table_data = array( + 'migration_type' => $_POST['migration_type'], + 'migration_vendor' => $_POST['migration_vendor'], + 'created_by' => get_current_user_id(), + 'created_at' => current_time( 'mysql' ), + ); + + $wpdb->insert( + $wpdb->prefix . 'tutor_migration', + $tutor_migration_table_data + ); + } + + + public function ld_tool_pages( $pages ) { + // if (defined('LEARNDASH_VERSION') && !defined('LEARNPRESS_VERSION') ) { + if ( defined( 'LEARNDASH_VERSION' ) ) { + // $pages['migration_ld'] = array('title' => __('LearnDash Migration', 'tutor-lms-migration-tool'), 'view_path' => TLMT_PATH.'views/migration_ld.php'); + $pages['migration_ld'] = array( + 'label' => __( 'LearnDash Migration', 'tutor' ), + 'slug' => 'migration_ld', + 'desc' => __( 'LearnDash Migration', 'tutor' ), + 'template' => 'migration_ld', + 'view_path' => TLMT_PATH . 'views/', + 'icon' => 'tutor-icon-brand-learndash', + 'blocks' => array( + 'block' => array(), + ), + ); + } + return $pages; + } + + + public function ld_reset_migrated_items_count() { + + tutor_utils()->checking_nonce(); + + Utils::check_course_access(); + + delete_option( '_tutor_migrated_items_count' ); + } + + + public function ld_migrate_all_data_to_tutor() { + tutor_utils()->checking_nonce(); + + Utils::check_course_access(); + + if ( isset( $_POST['migrate_type'] ) ) { + $migrate_type = sanitize_text_field( $_POST['migrate_type'] ); + + switch ( $migrate_type ) { + case 'courses': + $this->ld_migrate_course_to_tutor(); + break; + + case 'orders': + $this->ld_order_migrate(); + break; + } + + wp_send_json_success(); + } + wp_send_json_error(); + } + + /* + * Course Migration + */ + public function ld_migrate_course_to_tutor( $return_type = false ) { + global $wpdb; + $ld_courses = $wpdb->get_results( "SELECT ID, post_author, post_date, post_content, post_title, post_excerpt, post_status FROM {$wpdb->posts} WHERE post_type = 'sfwd-courses' AND (post_status = 'publish' OR post_status = 'draft');" ); + + $course_type = tutor()->course_post_type; + + if ( tutils()->count( $ld_courses ) ) { + $course_i = (int) get_option( '_tutor_migrated_items_count' ); + $i = 0; + foreach ( $ld_courses as $ld_course ) { + $course_i++; + $course_id = $this->update_post( $ld_course->ID, $course_type, 0, '' ); + if ( $course_id ) { + $this->migrate_course( $ld_course->ID, $course_id ); + + update_option( '_tutor_migrated_items_count', $course_i ); + + // Attached Product + $this->attached_product( $course_id, $ld_course->post_title ); + + // Attached Prerequisite + $this->attached_prerequisite( $course_id ); + + // Add Enrollments + $this->insert_enrollment( $course_id ); + + // Attached thumbnail + $this->insert_thumbnail( $ld_course->ID, $course_id ); + } + } + } + wp_send_json_success(); + + } + + public function attached_prerequisite( $course_id ) { + $course_data = get_post_meta( $course_id, '_sfwd-courses', true ); + if ( $course_data['sfwd-courses_course_prerequisite'] ) { + update_post_meta( $course_id, '_tutor_course_prerequisites_ids', $course_data['sfwd-courses_course_prerequisite'] ); + } + } + + /** + * Insert thumbnail ID + */ + public function insert_thumbnail( $new_thumbnail_id, $thumbnail_id ) { + $thumbnail = get_post_meta( $thumbnail_id, '_thumbnail_id', true ); + if ( $thumbnail ) { + set_post_thumbnail( $new_thumbnail_id, $thumbnail ); + } + } + + + /** + * Insert Enbrolement LD to Tutor + */ + public function insert_enrollment( $course_id ) { + global $wpdb; + $ld_course_complete_datas = $wpdb->get_results( "SELECT * from {$wpdb->prefix}learndash_user_activity WHERE activity_type = 'course' AND activity_status = 1" ); + + foreach ( $ld_course_complete_datas as $ld_course_complete_data ) { + $user_id = $ld_course_complete_data->user_id; + $complete_course_id = $ld_course_complete_data->course_id; + + if ( ! tutils()->is_enrolled( $course_id, $user_id ) ) { + + $date = date( 'Y-m-d H:i:s', tutor_time() ); + + do { + $hash = substr( md5( wp_generate_password( 32 ) . $date . $complete_course_id . $user_id ), 0, 16 ); + $hasHash = (int) $wpdb->get_var( + $wpdb->prepare( + "SELECT COUNT(comment_ID) from {$wpdb->comments} WHERE comment_agent = 'TutorLMSPlugin' AND comment_type = 'course_completed' AND comment_content = %s ", - $hash - ) - ); - - } while ( $hasHash > 0 ); - - $tutor_course_complete_data = array( - 'comment_type' => 'course_completed', - 'comment_agent' => 'TutorLMSPlugin', - 'comment_approved' => 'approved', - 'comment_content' => $hash, - 'user_id' => $user_id, - 'comment_author' => $user_id, - 'comment_post_ID' => $complete_course_id, - ); - - $isEnrolled = wp_insert_comment( $tutor_course_complete_data ); - - } - } - - $ld_enrollments = $wpdb->get_results( $wpdb->prepare( "SELECT * from {$wpdb->prefix}learndash_user_activity WHERE course_id = %d AND activity_type = 'access' AND activity_status = 0", $course_id ) ); - - foreach ($ld_enrollments as $ld_enrollment) { - $user_id = $ld_enrollment->user_id; - - if (! tutils()->is_enrolled($course_id, $user_id)) { - - $title = __('Course Enrolled', 'tutor'); - $tutor_enrollment_data = array( - 'post_type' => 'tutor_enrolled', - 'post_title' => $title, - 'post_status' => 'completed', - 'post_author' => $user_id, - 'post_parent' => $course_id, - ); - - $isEnrolled = wp_insert_post($tutor_enrollment_data); - - if ($isEnrolled) { - //Mark Current User as Students with user meta data - update_user_meta($user_id, '_is_tutor_student', $order_time); - } - } - } - } - - /** - * Create WC & EDD Product and linked with the course - */ - public function attached_product($course_id, $course_title) { - - update_post_meta($course_id, '_tutor_course_price_type', 'free'); - $tutor_monetize_by = tutils()->get_option('monetize_by'); - - /** - * Create WC Product and linked with the course - */ - if (tutils()->has_wc() && $tutor_monetize_by == 'wc' || $tutor_monetize_by == '-1' || $tutor_monetize_by == 'free') { - - update_post_meta($course_id, '_tutor_course_price_type', 'free'); - $monetize_by = tutils()->get_option('monetize_by'); - - if (tutils()->has_wc() && $monetize_by == 'wc') { - - $_ld_price = get_post_meta($course_id, '_sfwd-courses', true); - - if ($_ld_price['sfwd-courses_course_price']) { - - update_post_meta($course_id, '_tutor_course_price_type', 'paid'); - - $product_id = wp_insert_post(array( - 'post_title' => $course_title.' Product', - 'post_content' => '', - 'post_status' => 'publish', - 'post_type' => "product", - )); - - if ($product_id) { - $product_metas = array( - '_stock_status' => 'instock', - 'total_sales' => '0', - '_regular_price' => '', - '_sale_price' => $_ld_price['sfwd-courses_course_price'], - '_price' => $_ld_price['sfwd-courses_course_price'], - '_sold_individually' => 'no', - '_manage_stock' => 'no', - '_backorders' => 'no', - '_stock' => '', - '_virtual' => 'yes', - '_tutor_product' => 'yes', - ); - - foreach ($product_metas as $key => $value) { - update_post_meta($product_id, $key, $value); - } - - // Attaching product to course - update_post_meta($course_id, '_tutor_course_product_id', $product_id); - - $coursePostThumbnail = get_post_meta($course_id, '_thumbnail_id', true); - - if ($coursePostThumbnail) { - set_post_thumbnail($product_id, $coursePostThumbnail); - } - - } - - } else { - update_post_meta($course_id, '_tutor_course_price_type', 'free'); - } - } - - } - - /** - * Create EDD Product and linked with the course - */ - if (tutils()->has_edd() && $tutor_monetize_by == 'edd') { - $_ld_price = get_post_meta($course_id, '_sfwd-courses', true); - if ($_ld_price['sfwd-courses_course_price']) { - update_post_meta($course_id, '_tutor_course_price_type', 'paid'); - $product_id = wp_insert_post(array( - 'post_title' => $course_title.' Product', - 'post_content' => '', - 'post_status' => 'publish', - 'post_type' => "download", - )); - $product_metas = array( - 'edd_price' => $_ld_price['sfwd-courses_course_price'], - 'edd_variable_prices' => array(), - 'edd_download_files' => array(), - '_edd_bundled_products' => array('0'), - '_edd_bundled_products_conditions' => array('all'), - ); - foreach ($product_metas as $key => $value) { - update_post_meta($product_id, $key, $value); - } - update_post_meta($course_id, '_tutor_course_product_id', $product_id); - $coursePostThumbnail = get_post_meta($course_id, '_thumbnail_id', true); - if ($coursePostThumbnail) { - set_post_thumbnail($product_id, $coursePostThumbnail); - } - } else { - update_post_meta($course_id, '_tutor_course_price_type', 'free'); - } - } - } - - /* - * Learndash eCommerce orders migration to WC & EDD - */ - public function ld_order_migrate(){ - global $wpdb; - - tutor_utils()->checking_nonce(); - - Utils::check_course_access(); - - - $tutor_monetize_by = tutils()->get_option('monetize_by'); - - $ld_orders = $wpdb->get_results("SELECT ID, post_author, post_date, post_content, post_title, post_status FROM {$wpdb->posts} WHERE post_type = 'sfwd-transactions' AND post_status = 'publish';"); - $item_i = (int) get_option('_tutor_migrated_items_count'); - - if (tutils()->has_wc() && $tutor_monetize_by == 'wc' || $tutor_monetize_by == '-1' || $tutor_monetize_by == 'free') { - - foreach ($ld_orders as $order) { - $item_i++; - update_option('_tutor_migrated_items_count', $item_i); - - $migrate_order_data = array( - 'ID' => $order->ID, - 'post_status' => 'wc-completed', - 'post_type' => 'shop_order', - ); - wp_update_post($migrate_order_data); - - // Order Item - $course_id = get_post_meta($order->ID, 'course_id', true); - $item_data = array( - 'order_item_name' => get_the_title($course_id), - 'order_item_type' => 'line_item', - 'order_id' => $course_id, - ); - $wpdb->insert($wpdb->prefix.'woocommerce_order_items', $item_data); - $order_item_id = (int) $wpdb->insert_id; - - // Order Item Meta - $_ld_price = get_post_meta( $order->ID, '_sfwd-courses', true ); - $wc_item_metas = array( - '_product_id' => $order->ID, - '_variation_id' => 0, - '_qty' => 1, - '_tax_class' => '', - '_line_subtotal' => $_ld_price['sfwd-courses_course_price'] ? $_ld_price['sfwd-courses_course_price'] : 0, - '_line_subtotal_tax' => 0, - '_line_total' => $_ld_price['sfwd-courses_course_price'] ? $_ld_price['sfwd-courses_course_price'] : 0, - '_line_tax' => 0, - '_order_total' => $_ld_price['sfwd-courses_course_price'] ? $_ld_price['sfwd-courses_course_price'] : 0, - '_line_tax_data' => maybe_serialize( array( 'total' => array(), 'subtotal' => array() ) ), - ); - - foreach ($wc_item_metas as $wc_item_meta_key => $wc_item_meta_value ){ - $wc_item_metas = array( - 'order_item_id' => $order_item_id, - 'meta_key' => $wc_item_meta_key, - 'meta_value' => $wc_item_meta_value, - ); - $wpdb->insert($wpdb->prefix.'woocommerce_order_itemmeta', $wc_item_metas); - } - - update_post_meta($order->ID, '_customer_user', $order->post_author); - $user_email = $wpdb->get_var( $wpdb->prepare( "SELECT user_email from {$wpdb->users} WHERE ID = %d", $order->post_author ) ); - update_post_meta($order->ID, '_billing_address_index', $user_email ); - update_post_meta($order->ID, '_billing_email', $user_email ); - - } - } - - if ( tutils()->has_edd() && $tutor_monetize_by == 'edd' ) { - - foreach ($ld_orders as $order) { - $item_i++; - update_option('_tutor_migrated_items_count', $item_i); - - $migrate_order_data = array( - 'ID' => $order->ID, - 'post_status' => 'publish', - 'post_type' => 'edd_payment', - ); - wp_update_post($migrate_order_data); - - $_ld_price = get_post_meta( $order->ID, '_sfwd-courses', true ); - $user_email = $wpdb->get_var( $wpdb->prepare( "SELECT user_email from {$wpdb->users} WHERE ID = %d ", $order->post_author ) ); - $meta_data = array( - '_edd_payment_meta' => array(), - '_edd_payment_gateway' => '', - '_edd_payment_user_id' => $order->post_author, - '_edd_payment_user_email' => $user_email, - '_edd_payment_user_ip' => '', - '_edd_payment_purchase_key' => '', - '_edd_payment_mode' => 'migration', - '_edd_payment_tax_rate' => 0, - '_edd_payment_customer_id' => $order->post_author, - '_edd_payment_total' => $_ld_price['sfwd-courses_course_price'] ? $_ld_price['sfwd-courses_course_price'] : 0, - '_edd_payment_tax' => 0, - '_edd_completed_date' => $order->post_date, - ); - - foreach ($meta_data as $key => $value) { - update_post_meta($order->ID, $key, $value); - } - - $display_name = $wpdb->get_var( $wpdb->prepare( "SELECT display_name from {$wpdb->users} WHERE ID = %d ", $order->post_author )); - $edd_item_metas = array( - 'user_id' => $order->post_author, - 'email' => $user_email, - 'name' => $display_name, - 'purchase_value' => $_ld_price['sfwd-courses_course_price'] ? $_ld_price['sfwd-courses_course_price'] : 0, - 'purchase_count' => 1, - 'notes' => '', - 'date_created' => $order->post_date, - ); - - $wpdb->insert($wpdb->prefix.'edd_customers', $edd_item_metas); - - } - } - } - - /* - * Progress Migration - */ - public function _get_ld_live_progress_course_migrating_info() - { - $migrated_count = (int) get_option('_tutor_migrated_items_count'); - wp_send_json_success(array('migrated_count' => $migrated_count )); - } - - public function insert_post($post_title, $post_content, $author_id, $post_type = 'topics', $menu_order = 0, $post_parent = '') - { - $post_arg = array( - 'post_type' => $post_type, - 'post_title' => $post_title, - 'post_content' => $post_content, - 'post_status' => 'publish', - 'post_author' => $author_id, - 'post_parent' => $post_parent, - 'menu_order' => $menu_order, - ); - return wp_insert_post($post_arg); - } - - public function update_post($post_id, $post_type = 'topics', $menu_order = 0, $post_parent = '') - { - global $wpdb; - $post_arg = array( - 'ID' => $post_id, - 'post_type' => $post_type, - 'post_parent' => $post_parent, - 'menu_order' => $menu_order, - ); - $wpdb->query($wpdb->prepare("UPDATE {$wpdb->prefix}posts SET post_type=%s, post_parent=%s, menu_order=%s WHERE ID=%s", $post_type, $post_parent, $menu_order, $post_id)); - return $post_id; - } - - public function migrate_quiz($old_quiz_id) - { - global $wpdb; - $xml = ''; - $question_ids = get_post_meta($old_quiz_id, 'ld_quiz_questions', true); - $is_table = $wpdb->get_var( $wpdb->prepare( "SHOW TABLES LIKE %s", "{$wpdb->prefix}learndash_pro_quiz_question" ) ); - - if (!empty($question_ids)) { - $question_ids = array_keys($question_ids); - foreach ($question_ids as $question_single) { - $question_id = get_post_meta($question_single, 'question_pro_id', true); - - $result = array(); - if ($is_table) { - $result = $wpdb->get_row( - $wpdb->prepare( "SELECT id, title, question, points, answer_type, answer_data FROM {$wpdb->prefix}learndash_pro_quiz_question where id = %d", $question_id ), - ARRAY_A); - } else { - $result = $wpdb->get_row( - $wpdb->prepare( "SELECT id, title, question, points, answer_type, answer_data FROM {$wpdb->prefix}wp_pro_quiz_question where id = %d", $question_id ), ARRAY_A); - } - - $question = array(); - $question['quiz_id'] = $old_quiz_id; - $question['question_title'] = $result['title']; - $question['question_description'] = (string) $result['question']; - $question['question_mark'] = $result['points']; - switch ($result['answer_type']) { - case 'single': - $question['question_type'] = 'single_choice'; - break; - - case 'multiple': - $question['question_type'] = 'multiple_choice'; - break; - - case 'sort_answer': - $question['question_type'] = 'ordering'; - break; - - case 'essay': - $question['question_type'] = 'open_ended'; - break; - - case 'cloze_answer': - $question['question_type'] = 'fill_in_the_blank'; - break; - - default: - # code... - break; - } - - $question['question_settings'] = maybe_serialize(array( - 'question_type' => $result['answer_type'], - 'question_mark' => $result['points'] - )); - - $wpdb->insert($wpdb->prefix.'tutor_quiz_questions', $question); - - // Will Return $questions - $question_id = $wpdb->insert_id; - if ($question_id) { - foreach ((array)maybe_unserialize($result['answer_data']) as $key => $value) { - $i = 0; - $answer = array(); - foreach ((array)$value as $k => $val) { - if ($i == 0) { - $answer['answer_title'] = $val; - if ($result['answer_type'] == 'cloze_answer') { - $final_question = wp_strip_all_tags($val); - preg_match_all('/{.*?\}/', $final_question, $matches); - if (isset($matches[0])) { - foreach ($matches[0] as $key => $v) { - $v = explode(']', $v); - if (isset($v[0])) { - $answer_str[] = str_replace(array('{[','{','}'), '', $v[0]); - } - } - $final_question = str_replace($matches[0], '{dash}', $final_question); - } - $answer['answer_two_gap_match'] = implode('|', $answer_str); - $answer['answer_title'] = $final_question; - } - } elseif ($i == 2) { - $answer['is_correct'] = $val ? 0 : 1; - } elseif ($i == 3) { - $answer['belongs_question_id'] = $question_id; - $answer['belongs_question_type'] = $question['question_type']; - $answer['answer_view_format'] = 'text'; - $answer['answer_order'] = $i; - $answer['image_id'] = 0; - } - $i++; - } - $wpdb->insert( $wpdb->prefix.'tutor_quiz_question_answers', $answer ); - } - } - - if ($is_table) { - $wpdb->delete( $wpdb->prefix.'learndash_pro_quiz_question', array( 'id' => $result->id ) ); - } else { - $wpdb->delete( $wpdb->prefix.'wp_pro_quiz_question', array( 'id' => $result->id ) ); - } - - } - } - } - - public function migrate_course($course_id, $new_course_id) - { - global $wpdb; - $section_heading = get_post_meta($course_id, 'course_sections', true); - $section_heading = $section_heading ? json_decode($section_heading, true) : array(array('order' => 0, 'post_title' => 'Tutor Topics')); - - $total_data = LDLMS_Factory_Post::course_steps($course_id); - $total_data = $total_data->get_steps(); - - if (empty($total_data)) { - return; - } - - $lesson_post_type = tutor()->lesson_post_type; - - $i = 0; - $section_count = 0; - $topic_id = 0; - foreach ($total_data['sfwd-lessons'] as $lesson_key => $lesson_data) { - $author_id = get_post_field('post_author', $course_id); - - // Topic Section - $check = $i == 0 ? 0 : $i+1; - if (isset($section_heading[$section_count]['order'])) { - if ($section_heading[$section_count]['order'] == $check) { - // Insert Topics - $topic_id = $this->insert_post($section_heading[$section_count]['post_title'], '', $author_id, 'topics', $i, $new_course_id); - $section_count++; - } - } - - - if ($topic_id) { - $lesson_id = $this->update_post($lesson_key, $lesson_post_type, $i, $topic_id); - - update_post_meta($lesson_id, '_tutor_course_id_for_lesson', $course_id); - - foreach ($lesson_data['sfwd-topic'] as $lesson_inner_key => $lesson_inner) { - - $lesson_id = $this->update_post($lesson_inner_key, $lesson_post_type, $i, $topic_id); // Insert Lesson - - update_post_meta($lesson_id, '_tutor_course_id_for_lesson', $course_id); - - foreach ($lesson_inner['sfwd-quiz'] as $quiz_key => $quiz_data) { - $quiz_id = $this->update_post( $quiz_key, 'tutor_quiz', $i, $topic_id ); - - if ($quiz_id) { - $this->migrate_quiz($quiz_id); - } - } - } - - foreach ($lesson_data['sfwd-quiz'] as $quiz_key => $quiz_data) { - $quiz_id = $this->update_post($quiz_key, 'tutor_quiz', $i, $topic_id); - if ($quiz_id) { - $this->migrate_quiz($quiz_id); - } - } - } - $i++; - } - - if (!empty($total_data['sfwd-quiz'])) { - foreach ($total_data['sfwd-quiz'] as $quiz_key => $quiz_data) { - $quiz_id = $this->update_post($quiz_key, 'tutor_quiz', $i, $topic_id); - if ($quiz_id) { - $this->migrate_quiz($quiz_id); - } - } - } - - } - } - } \ No newline at end of file + $hash + ) + ); + + } while ( $hasHash > 0 ); + + $tutor_course_complete_data = array( + 'comment_type' => 'course_completed', + 'comment_agent' => 'TutorLMSPlugin', + 'comment_approved' => 'approved', + 'comment_content' => $hash, + 'user_id' => $user_id, + 'comment_author' => $user_id, + 'comment_post_ID' => $complete_course_id, + ); + + $isEnrolled = wp_insert_comment( $tutor_course_complete_data ); + + } + } + + $ld_enrollments = $wpdb->get_results( $wpdb->prepare( "SELECT * from {$wpdb->prefix}learndash_user_activity WHERE course_id = %d AND activity_type = 'access' AND activity_status = 0", $course_id ) ); + + foreach ( $ld_enrollments as $ld_enrollment ) { + $user_id = $ld_enrollment->user_id; + + if ( ! tutils()->is_enrolled( $course_id, $user_id ) ) { + + $title = __( 'Course Enrolled', 'tutor' ); + $tutor_enrollment_data = array( + 'post_type' => 'tutor_enrolled', + 'post_title' => $title, + 'post_status' => 'completed', + 'post_author' => $user_id, + 'post_parent' => $course_id, + ); + + $isEnrolled = wp_insert_post( $tutor_enrollment_data ); + + if ( $isEnrolled ) { + // Mark Current User as Students with user meta data + update_user_meta( $user_id, '_is_tutor_student', $order_time ); + } + } + } + } + + /** + * Create WC & EDD Product and linked with the course + */ + public function attached_product( $course_id, $course_title ) { + + update_post_meta( $course_id, '_tutor_course_price_type', 'free' ); + $tutor_monetize_by = tutils()->get_option( 'monetize_by' ); + + /** + * Create WC Product and linked with the course + */ + if ( tutils()->has_wc() && $tutor_monetize_by == 'wc' || $tutor_monetize_by == '-1' || $tutor_monetize_by == 'free' ) { + + update_post_meta( $course_id, '_tutor_course_price_type', 'free' ); + $monetize_by = tutils()->get_option( 'monetize_by' ); + + if ( tutils()->has_wc() && $monetize_by == 'wc' ) { + + $_ld_price = get_post_meta( $course_id, '_sfwd-courses', true ); + + if ( $_ld_price['sfwd-courses_course_price'] ) { + + update_post_meta( $course_id, '_tutor_course_price_type', 'paid' ); + + $product_id = wp_insert_post( + array( + 'post_title' => $course_title . ' Product', + 'post_content' => '', + 'post_status' => 'publish', + 'post_type' => 'product', + ) + ); + + if ( $product_id ) { + $product_metas = array( + '_stock_status' => 'instock', + 'total_sales' => '0', + '_regular_price' => '', + '_sale_price' => $_ld_price['sfwd-courses_course_price'], + '_price' => $_ld_price['sfwd-courses_course_price'], + '_sold_individually' => 'no', + '_manage_stock' => 'no', + '_backorders' => 'no', + '_stock' => '', + '_virtual' => 'yes', + '_tutor_product' => 'yes', + ); + + foreach ( $product_metas as $key => $value ) { + update_post_meta( $product_id, $key, $value ); + } + + // Attaching product to course + update_post_meta( $course_id, '_tutor_course_product_id', $product_id ); + + $coursePostThumbnail = get_post_meta( $course_id, '_thumbnail_id', true ); + + if ( $coursePostThumbnail ) { + set_post_thumbnail( $product_id, $coursePostThumbnail ); + } + } + } else { + update_post_meta( $course_id, '_tutor_course_price_type', 'free' ); + } + } + } + + /** + * Create EDD Product and linked with the course + */ + if ( tutils()->has_edd() && $tutor_monetize_by == 'edd' ) { + $_ld_price = get_post_meta( $course_id, '_sfwd-courses', true ); + if ( $_ld_price['sfwd-courses_course_price'] ) { + update_post_meta( $course_id, '_tutor_course_price_type', 'paid' ); + $product_id = wp_insert_post( + array( + 'post_title' => $course_title . ' Product', + 'post_content' => '', + 'post_status' => 'publish', + 'post_type' => 'download', + ) + ); + $product_metas = array( + 'edd_price' => $_ld_price['sfwd-courses_course_price'], + 'edd_variable_prices' => array(), + 'edd_download_files' => array(), + '_edd_bundled_products' => array( '0' ), + '_edd_bundled_products_conditions' => array( 'all' ), + ); + foreach ( $product_metas as $key => $value ) { + update_post_meta( $product_id, $key, $value ); + } + update_post_meta( $course_id, '_tutor_course_product_id', $product_id ); + $coursePostThumbnail = get_post_meta( $course_id, '_thumbnail_id', true ); + if ( $coursePostThumbnail ) { + set_post_thumbnail( $product_id, $coursePostThumbnail ); + } + } else { + update_post_meta( $course_id, '_tutor_course_price_type', 'free' ); + } + } + } + + /* + * Learndash eCommerce orders migration to WC & EDD + */ + public function ld_order_migrate() { + global $wpdb; + + tutor_utils()->checking_nonce(); + + Utils::check_course_access(); + + $tutor_monetize_by = tutils()->get_option( 'monetize_by' ); + + $ld_orders = $wpdb->get_results( "SELECT ID, post_author, post_date, post_content, post_title, post_status FROM {$wpdb->posts} WHERE post_type = 'sfwd-transactions' AND post_status = 'publish';" ); + $item_i = (int) get_option( '_tutor_migrated_items_count' ); + + if ( tutils()->has_wc() && $tutor_monetize_by == 'wc' || $tutor_monetize_by == '-1' || $tutor_monetize_by == 'free' ) { + + foreach ( $ld_orders as $order ) { + $item_i++; + update_option( '_tutor_migrated_items_count', $item_i ); + + $migrate_order_data = array( + 'ID' => $order->ID, + 'post_status' => 'wc-completed', + 'post_type' => 'shop_order', + ); + wp_update_post( $migrate_order_data ); + + // Order Item + $course_id = get_post_meta( $order->ID, 'course_id', true ); + $item_data = array( + 'order_item_name' => get_the_title( $course_id ), + 'order_item_type' => 'line_item', + 'order_id' => $course_id, + ); + $wpdb->insert( $wpdb->prefix . 'woocommerce_order_items', $item_data ); + $order_item_id = (int) $wpdb->insert_id; + + // Order Item Meta + $_ld_price = get_post_meta( $order->ID, '_sfwd-courses', true ); + $wc_item_metas = array( + '_product_id' => $order->ID, + '_variation_id' => 0, + '_qty' => 1, + '_tax_class' => '', + '_line_subtotal' => $_ld_price['sfwd-courses_course_price'] ? $_ld_price['sfwd-courses_course_price'] : 0, + '_line_subtotal_tax' => 0, + '_line_total' => $_ld_price['sfwd-courses_course_price'] ? $_ld_price['sfwd-courses_course_price'] : 0, + '_line_tax' => 0, + '_order_total' => $_ld_price['sfwd-courses_course_price'] ? $_ld_price['sfwd-courses_course_price'] : 0, + '_line_tax_data' => maybe_serialize( + array( + 'total' => array(), + 'subtotal' => array(), + ) + ), + ); + + foreach ( $wc_item_metas as $wc_item_meta_key => $wc_item_meta_value ) { + $wc_item_metas = array( + 'order_item_id' => $order_item_id, + 'meta_key' => $wc_item_meta_key, + 'meta_value' => $wc_item_meta_value, + ); + $wpdb->insert( $wpdb->prefix . 'woocommerce_order_itemmeta', $wc_item_metas ); + } + + update_post_meta( $order->ID, '_customer_user', $order->post_author ); + $user_email = $wpdb->get_var( $wpdb->prepare( "SELECT user_email from {$wpdb->users} WHERE ID = %d", $order->post_author ) ); + update_post_meta( $order->ID, '_billing_address_index', $user_email ); + update_post_meta( $order->ID, '_billing_email', $user_email ); + + } + } + + if ( tutils()->has_edd() && $tutor_monetize_by == 'edd' ) { + + foreach ( $ld_orders as $order ) { + $item_i++; + update_option( '_tutor_migrated_items_count', $item_i ); + + $migrate_order_data = array( + 'ID' => $order->ID, + 'post_status' => 'publish', + 'post_type' => 'edd_payment', + ); + wp_update_post( $migrate_order_data ); + + $_ld_price = get_post_meta( $order->ID, '_sfwd-courses', true ); + $user_email = $wpdb->get_var( $wpdb->prepare( "SELECT user_email from {$wpdb->users} WHERE ID = %d ", $order->post_author ) ); + $meta_data = array( + '_edd_payment_meta' => array(), + '_edd_payment_gateway' => '', + '_edd_payment_user_id' => $order->post_author, + '_edd_payment_user_email' => $user_email, + '_edd_payment_user_ip' => '', + '_edd_payment_purchase_key' => '', + '_edd_payment_mode' => 'migration', + '_edd_payment_tax_rate' => 0, + '_edd_payment_customer_id' => $order->post_author, + '_edd_payment_total' => $_ld_price['sfwd-courses_course_price'] ? $_ld_price['sfwd-courses_course_price'] : 0, + '_edd_payment_tax' => 0, + '_edd_completed_date' => $order->post_date, + ); + + foreach ( $meta_data as $key => $value ) { + update_post_meta( $order->ID, $key, $value ); + } + + $display_name = $wpdb->get_var( $wpdb->prepare( "SELECT display_name from {$wpdb->users} WHERE ID = %d ", $order->post_author ) ); + $edd_item_metas = array( + 'user_id' => $order->post_author, + 'email' => $user_email, + 'name' => $display_name, + 'purchase_value' => $_ld_price['sfwd-courses_course_price'] ? $_ld_price['sfwd-courses_course_price'] : 0, + 'purchase_count' => 1, + 'notes' => '', + 'date_created' => $order->post_date, + ); + + $wpdb->insert( $wpdb->prefix . 'edd_customers', $edd_item_metas ); + + } + } + } + + /* + * Progress Migration + */ + public function _get_ld_live_progress_course_migrating_info() { + $migrated_count = (int) get_option( '_tutor_migrated_items_count' ); + wp_send_json_success( array( 'migrated_count' => $migrated_count ) ); + } + + public function insert_post( $post_title, $post_content, $author_id, $post_type = 'topics', $menu_order = 0, $post_parent = '' ) { + $post_arg = array( + 'post_type' => $post_type, + 'post_title' => $post_title, + 'post_content' => $post_content, + 'post_status' => 'publish', + 'post_author' => $author_id, + 'post_parent' => $post_parent, + 'menu_order' => $menu_order, + ); + return wp_insert_post( $post_arg ); + } + + public function update_post( $post_id, $post_type = 'topics', $menu_order = 0, $post_parent = '' ) { + global $wpdb; + $post_arg = array( + 'ID' => $post_id, + 'post_type' => $post_type, + 'post_parent' => $post_parent, + 'menu_order' => $menu_order, + ); + $wpdb->query( $wpdb->prepare( "UPDATE {$wpdb->prefix}posts SET post_type=%s, post_parent=%s, menu_order=%s WHERE ID=%s", $post_type, $post_parent, $menu_order, $post_id ) ); + return $post_id; + } + + public function migrate_quiz( $old_quiz_id ) { + global $wpdb; + $xml = ''; + $question_ids = get_post_meta( $old_quiz_id, 'ld_quiz_questions', true ); + $is_table = $wpdb->get_var( $wpdb->prepare( 'SHOW TABLES LIKE %s', "{$wpdb->prefix}learndash_pro_quiz_question" ) ); + + if ( ! empty( $question_ids ) ) { + $question_ids = array_keys( $question_ids ); + foreach ( $question_ids as $question_single ) { + $question_id = get_post_meta( $question_single, 'question_pro_id', true ); + + $result = array(); + if ( $is_table ) { + $result = $wpdb->get_row( + $wpdb->prepare( "SELECT id, title, question, points, answer_type, answer_data FROM {$wpdb->prefix}learndash_pro_quiz_question where id = %d", $question_id ), + ARRAY_A + ); + } else { + $result = $wpdb->get_row( + $wpdb->prepare( "SELECT id, title, question, points, answer_type, answer_data FROM {$wpdb->prefix}wp_pro_quiz_question where id = %d", $question_id ), + ARRAY_A + ); + } + + $question = array(); + $question['quiz_id'] = $old_quiz_id; + $question['question_title'] = $result['title']; + $question['question_description'] = (string) $result['question']; + $question['question_mark'] = $result['points']; + switch ( $result['answer_type'] ) { + case 'single': + $question['question_type'] = 'single_choice'; + break; + + case 'multiple': + $question['question_type'] = 'multiple_choice'; + break; + + case 'sort_answer': + $question['question_type'] = 'ordering'; + break; + + case 'essay': + $question['question_type'] = 'open_ended'; + break; + + case 'cloze_answer': + $question['question_type'] = 'fill_in_the_blank'; + break; + + default: + // code... + break; + } + + $question['question_settings'] = maybe_serialize( + array( + 'question_type' => $result['answer_type'], + 'question_mark' => $result['points'], + ) + ); + + $wpdb->insert( $wpdb->prefix . 'tutor_quiz_questions', $question ); + + // Will Return $questions + $question_id = $wpdb->insert_id; + if ( $question_id ) { + foreach ( (array) maybe_unserialize( $result['answer_data'] ) as $key => $value ) { + $i = 0; + $answer = array(); + foreach ( (array) $value as $k => $val ) { + if ( $i == 0 ) { + $answer['answer_title'] = $val; + if ( $result['answer_type'] == 'cloze_answer' ) { + $final_question = wp_strip_all_tags( $val ); + preg_match_all( '/{.*?\}/', $final_question, $matches ); + if ( isset( $matches[0] ) ) { + foreach ( $matches[0] as $key => $v ) { + $v = explode( ']', $v ); + if ( isset( $v[0] ) ) { + $answer_str[] = str_replace( array( '{[', '{', '}' ), '', $v[0] ); + } + } + $final_question = str_replace( $matches[0], '{dash}', $final_question ); + } + $answer['answer_two_gap_match'] = implode( '|', $answer_str ); + $answer['answer_title'] = $final_question; + } + } elseif ( $i == 2 ) { + $answer['is_correct'] = $val ? 0 : 1; + } elseif ( $i == 3 ) { + $answer['belongs_question_id'] = $question_id; + $answer['belongs_question_type'] = $question['question_type']; + $answer['answer_view_format'] = 'text'; + $answer['answer_order'] = $i; + $answer['image_id'] = 0; + } + $i++; + } + $wpdb->insert( $wpdb->prefix . 'tutor_quiz_question_answers', $answer ); + } + } + + if ( $is_table ) { + $wpdb->delete( $wpdb->prefix . 'learndash_pro_quiz_question', array( 'id' => $result->id ) ); + } else { + $wpdb->delete( $wpdb->prefix . 'wp_pro_quiz_question', array( 'id' => $result->id ) ); + } + } + } + } + + public function migrate_course( $course_id, $new_course_id ) { + global $wpdb; + $section_heading = get_post_meta( $course_id, 'course_sections', true ); + $section_heading = $section_heading ? json_decode( $section_heading, true ) : array( + array( + 'order' => 0, + 'post_title' => 'Tutor Topics', + ), + ); + + $total_data = LDLMS_Factory_Post::course_steps( $course_id ); + $total_data = $total_data->get_steps(); + + if ( empty( $total_data ) ) { + return; + } + + $lesson_post_type = tutor()->lesson_post_type; + + $i = 0; + $section_count = 0; + $topic_id = 0; + foreach ( $total_data['sfwd-lessons'] as $lesson_key => $lesson_data ) { + $author_id = get_post_field( 'post_author', $course_id ); + + // Topic Section + $check = $i == 0 ? 0 : $i + 1; + if ( isset( $section_heading[ $section_count ]['order'] ) ) { + if ( $section_heading[ $section_count ]['order'] == $check ) { + // Insert Topics + $topic_id = $this->insert_post( $section_heading[ $section_count ]['post_title'], '', $author_id, 'topics', $i, $new_course_id ); + $section_count++; + } + } + + if ( $topic_id ) { + $lesson_id = $this->update_post( $lesson_key, $lesson_post_type, $i, $topic_id ); + + update_post_meta( $lesson_id, '_tutor_course_id_for_lesson', $course_id ); + + foreach ( $lesson_data['sfwd-topic'] as $lesson_inner_key => $lesson_inner ) { + + $lesson_id = $this->update_post( $lesson_inner_key, $lesson_post_type, $i, $topic_id ); // Insert Lesson + + update_post_meta( $lesson_id, '_tutor_course_id_for_lesson', $course_id ); + + foreach ( $lesson_inner['sfwd-quiz'] as $quiz_key => $quiz_data ) { + $quiz_id = $this->update_post( $quiz_key, 'tutor_quiz', $i, $topic_id ); + + if ( $quiz_id ) { + $this->migrate_quiz( $quiz_id ); + } + } + } + + foreach ( $lesson_data['sfwd-quiz'] as $quiz_key => $quiz_data ) { + $quiz_id = $this->update_post( $quiz_key, 'tutor_quiz', $i, $topic_id ); + if ( $quiz_id ) { + $this->migrate_quiz( $quiz_id ); + } + } + } + $i++; + } + + if ( ! empty( $total_data['sfwd-quiz'] ) ) { + foreach ( $total_data['sfwd-quiz'] as $quiz_key => $quiz_data ) { + $quiz_id = $this->update_post( $quiz_key, 'tutor_quiz', $i, $topic_id ); + if ( $quiz_id ) { + $this->migrate_quiz( $quiz_id ); + } + } + } + + } + } +} diff --git a/classes/TutorLMSMigrationTool.php b/classes/TutorLMSMigrationTool.php index f2e3373..6fab065 100644 --- a/classes/TutorLMSMigrationTool.php +++ b/classes/TutorLMSMigrationTool.php @@ -54,7 +54,6 @@ public function __construct() { add_filter( 'plugin_action_links_' . plugin_basename( TLMT_FILE ), array( $this, 'plugin_action_links' ) ); if ( $this->check_installed() ) { - $this->includes(); $this->used_classes(); $this->classes_initialize(); } else { @@ -213,21 +212,6 @@ public function install_tutor_plugin() { die(); } - /** - * Includes. - * - * @return void - */ - public function includes() { - include TLMT_PATH . 'classes/LPtoTutorMigration.php'; - include TLMT_PATH . 'classes/LDtoTutorMigration.php'; - if ( is_plugin_active( 'lifterlms/lifterlms.php' ) ) { - include TLMT_PATH . 'classes/LIFtoTutorMigration.php'; - } - include TLMT_PATH . 'classes/LDtoTutorExport.php'; - include TLMT_PATH . 'classes/Utils.php'; - } - /** * Used classed. * @@ -239,7 +223,6 @@ public function used_classes() { if ( is_plugin_active( 'lifterlms/lifterlms.php' ) ) { $this->classes[] = 'LIFtoTutorMigration'; } - } /** diff --git a/composer.json b/composer.json new file mode 100644 index 0000000..25d8105 --- /dev/null +++ b/composer.json @@ -0,0 +1,21 @@ +{ + "name": "themeum/tutor-lms-migration-tool", + "autoload": { + "classmap": [ + "classes/" + ], + "psr-4": { + "Themeum\\TutorLMSMigrationTool\\": "inc/" + }, + "files": [ + "inc/Functions.php" + ] + }, + "authors": [ + { + "name": "themeum", + "email": "support@themeum.com" + } + ], + "require": {} +} diff --git a/inc/ContentTypes.php b/inc/ContentTypes.php new file mode 100644 index 0000000..e2ad28c --- /dev/null +++ b/inc/ContentTypes.php @@ -0,0 +1,37 @@ + + * @link https://themeum.com + * @since 2.3.0 + */ + +namespace Themeum\TutorLMSMigrationTool; + +/** + * Contains constant for the available migration types. + * + * @since 2.3.0 + */ +abstract class ContentTypes { + + const COURSE = 'course'; + const COURSE_META = 'course_meta'; + const COURSE_REVIEWS = 'course_reviews'; + const COURSE_PROGRESS = 'course_progress'; + + const SALES = 'sales'; + const ORDERS = 'orders'; + const WC_PRODUCTS = 'wc_products'; + + const LESSON = 'lesson_meta'; + const LESSON_META = 'lesson'; + + const ASSIGNMENT = 'assignment'; + const ASSIGNMENT_META = 'assignment_meta'; + + const QUIZ = 'quiz'; + const QUIZ_META = 'quiz_meta'; +} diff --git a/inc/Factories/PostMetaFactory.php b/inc/Factories/PostMetaFactory.php new file mode 100644 index 0000000..48e8200 --- /dev/null +++ b/inc/Factories/PostMetaFactory.php @@ -0,0 +1,52 @@ + + * @link https://themeum.com + * @since 2.3.0 + */ + +namespace Themeum\TutorLMSMigrationTool\Factories; + +use InvalidArgumentException; +use Themeum\TutorLMSMigrationTool\ContentTypes; +use Themeum\TutorLMSMigrationTool\Interfaces\PostMeta; +use Themeum\TutorLMSMigrationTool\LDMigration\PostMeta\CourseMeta; +use Themeum\TutorLMSMigrationTool\MigrationTypes; + +/** + * Create the post meta objects based on migration type and meta type + */ +abstract class PostMetaFactory { + + /** + * Creates post meta objects based on migration and meta type + * + * @since 2.3.0 + * + * @param string $meta_type Type of meta (course, lesson, quiz, assignment). + * @param string $migration_type Type of migration (LD to Tutor etc). + * + * @throws InvalidArgumentException If invalid meta or migration type provided. + * + * @return PostMeta Post meta object for the specified type + */ + public static function create( $meta_type, $migration_type ): PostMeta { + switch ( $migration_type ) { + case MigrationTypes::LD_TO_TUTOR: + switch ( $meta_type ) { + case ContentTypes::COURSE_META: + return new CourseMeta(); + default: + break; + } + break; + default: + break; + } + + throw new InvalidArgumentException( __( 'Invalid argument passed', 'tutor-lms-migration-tool' ) ); + } +} diff --git a/inc/Functions.php b/inc/Functions.php new file mode 100644 index 0000000..9eafe07 --- /dev/null +++ b/inc/Functions.php @@ -0,0 +1,53 @@ + + * @link https://themeum.com + * @since 2.3.0 + */ + +use Themeum\TutorLMSMigrationTool\Factories\PostMetaFactory; + +if ( ! function_exists( 'tlmt_has_tutor_pro' ) ) { + /** + * Check whether tutor pro is installed or not + * + * @since 2.3.0 + * + * @return bool + */ + function tlmt_has_tutor_pro() { + return function_exists( 'tutor_pro' ); + } +} + +if ( ! function_exists( 'get_meta_obj' ) ) { + /** + * Check whether tutor pro is installed or not + * + * @since 2.3.0 + * + * @param string $meta_type Meta type like: course, lesson, etc. + * @param string $migration_type Migration type like: ld_to_tutor. + * + * @see MigrationTypes & ContentTypes class + * + * @throws \Throwable If the migration type is not supported. + * + * @return PostMeta object + */ + function get_meta_obj( $meta_type, $migration_type ) { + try { + $obj = PostMetaFactory::create( $meta_type, $migration_type ); + return $obj; + } catch ( \Throwable $th ) { + throw $th; + } + } +} + + diff --git a/inc/Interfaces/PostMeta.php b/inc/Interfaces/PostMeta.php new file mode 100644 index 0000000..c3474f2 --- /dev/null +++ b/inc/Interfaces/PostMeta.php @@ -0,0 +1,26 @@ + + * @link https://themeum.com + * @since 2.3.0 + */ + +namespace Themeum\TutorLMSMigrationTool\Interfaces; + +interface PostMeta { + + /** + * Migrate post meta + * + * @since 2.3.0 + * + * @param int $post_id Post id. + * + * @return void + */ + public function migrate( int $post_id ); + +} diff --git a/inc/LDMigration/PostMeta/CourseMeta.php b/inc/LDMigration/PostMeta/CourseMeta.php new file mode 100644 index 0000000..f8afec6 --- /dev/null +++ b/inc/LDMigration/PostMeta/CourseMeta.php @@ -0,0 +1,181 @@ + + * @link https://themeum.com + * @since 2.3.0 + */ + +namespace Themeum\TutorLMSMigrationTool\LDMigration\PostMeta; + +use Themeum\TutorLMSMigrationTool\Interfaces\PostMeta; +use Tutor\Helpers\QueryHelper; + +/** + * Handle course meta migration + */ +class CourseMeta implements PostMeta { + + /** + * Current post id + * + * @since 2.3.0 + * + * @var int + */ + private $post_id; + + /** + * Migrate course meta + * + * Migrate meta that are associated with the give post id. + * + * @since 2.3.0 + * + * @param integer $post_id Post id. + * + * @throws \Throwable If Database error occur. + * + * @return void + */ + public function migrate( int $post_id ) { + global $wpdb; + + $this->post_id = $post_id; + + $migrate_able_meta = $this->get_migrate_able_meta(); + + if ( ! empty( $migrate_able_meta ) ) { + // Prepare meta. + $meta = $this->ld_to_tutor_meta_map( $migrate_able_meta ); + if ( is_array( $meta ) && count( $meta ) ) { + try { + QueryHelper::insert_multiple_rows( $wpdb->postmeta, $meta, true, false ); + } catch ( \Throwable $th ) { + throw $th; + } + } + } + } + + /** + * Get all the migrate-able meta from the given post id + * + * @since 2.3.0 + * + * @return array + */ + private function get_migrate_able_meta(): array { + $all_meta = get_post_meta( $this->post_id, '_sfwd-courses', true ); + if ( ! empty( $all_meta ) ) { + $migrate_able_meta = $this->migrate_able_meta(); + + return array_intersect_key( $all_meta, array_flip( $migrate_able_meta ) ); + } + + return array(); + } + + /** + * Get all the meta that is migrate-able + * + * @since 2.3.0 + * + * @return array + */ + private function migrate_able_meta() { + return array( + 'sfwd-courses_course_seats_limit', + 'sfwd-courses_expire_access_days', + 'sfwd-courses_course_materials', + 'sfwd-courses_course_price', + 'sfwd-courses_course_price_type', + ); + } + + /** + * Map all ld meta to tutor meta for migration + * + * @since 2.3.0 + * + * @param array $meta Mapped meta, ready to migrate. + * + * @return array Multi-dimension array with meta key and value. + */ + private function ld_to_tutor_meta_map( array $meta ): array { + $ld_tutor_meta_map = array( + '_tutor_course_price_type' => 'sfwd-courses_course_price_type', + '_tutor_course_material_includes' => 'sfwd-courses_course_materials', + 'tutor_course_regular_price' => 'sfwd-courses_course_price', + ); + + $course_settings = array(); + $has_tutor_pro = function_exists( 'tutor_pro' ); + + if ( $has_tutor_pro ) { + $course_settings = array( + 'maximum_students' => 0, + 'enrollment_expiry' => 0, + 'enable_content_drip' => 0, + 'content_drip_type' => '', + 'enrollment_starts_at' => '', + 'enrollment_ends_at' => '', + 'pause_enrollment' => '', + ); + } + + $tutor_meta_map = array(); + + $ld_keys = array_keys( $meta ); + foreach ( $ld_tutor_meta_map as $key => $value ) { + if ( in_array( $value, $ld_keys ) ) { + $tutor_meta_map[ $key ] = $meta[ $value ]; + } + } + + // Price type. + $price_type = $tutor_meta_map['_tutor_course_price_type']; + if ( 'open' === $price_type ) { + $tutor_meta_map['_tutor_course_price_type'] = 'free'; + // Set visibility public. + $tutor_meta_map['_tutor_is_public_course'] = 'yes'; + } elseif ( 'paynow' === $price_type ) { + $tutor_meta_map['_tutor_course_price_type'] = 'paid'; + } elseif ( 'closed' === $price_type && $has_tutor_pro ) { + $course_settings['pause_enrollment'] = 'yes'; + } else { + $tutor_meta_map['_tutor_course_price_type'] = 'free'; + } + + if ( $has_tutor_pro ) { + // Max students. + if ( ! empty( $meta['sfwd-courses_course_seats_limit'] ) ) { + $course_settings['maximum_students'] = (int) $meta['sfwd-courses_course_seats_limit']; + } + + // Enrollment expiry. + if ( ! empty( $meta['sfwd-courses_expire_access'] && 'on' === $meta[ $meta['sfwd-courses_expire_access'] ] ) ) { + $course_settings['enrollment_expiry'] = (int) $meta['sfwd-courses_expire_access_days']; + } + } + + // Add course settings in meta. + $tutor_meta_map['_tutor_course_settings'] = maybe_serialize( $course_settings ); + + // Prepare to post meta to make it insert-able. + $prepared_meta = array(); + foreach ( $tutor_meta_map as $key => $value ) { + $new_meta = array( + 'post_id' => $this->post_id, + 'meta_key' => $key, + 'meta_value' => $value, + ); + + $prepared_meta[] = $new_meta; + } + + return $prepared_meta; + } +} diff --git a/inc/MigrationTypes.php b/inc/MigrationTypes.php new file mode 100644 index 0000000..ec77554 --- /dev/null +++ b/inc/MigrationTypes.php @@ -0,0 +1,23 @@ + + * @link https://themeum.com + * @since 2.3.0 + */ + +namespace Themeum\TutorLMSMigrationTool; + +/** + * Contains constant for the available migration types. + * + * @since 2.3.0 + */ +abstract class MigrationTypes { + + const LD_TO_TUTOR = 'learndash_to_tutor'; + const LP_TO_TUTOR = 'learnpress_to_tutor'; + const LIF_TO_TUTOR = 'lifter_to_tutor'; +} diff --git a/tutor-lms-migration-tool.php b/tutor-lms-migration-tool.php index 664a317..99e6ba9 100644 --- a/tutor-lms-migration-tool.php +++ b/tutor-lms-migration-tool.php @@ -19,7 +19,7 @@ exit; } -require 'classes/Dependency.php'; +require_once __DIR__ . '/vendor/autoload.php'; use TutorLMSMigrationTool\TLMT\Dependency; @@ -80,17 +80,18 @@ function tutor_migration_tool_deleted() { register_uninstall_hook( __FILE__, 'tutor_migration_tool_deleted' ); -if ( ! class_exists( 'TutorLMSMigrationTool' ) ) { +TutorLMSMigrationTool::instance(); - $dependency = new Dependency(); - if ( ! $dependency->is_tutor_core_has_req_verion() ) { - add_action( 'admin_notices', array( $dependency, 'show_admin_notice' ) ); - return; +add_action( + 'plugins_loaded', + function() { + $dependency = new Dependency(); + if ( ! $dependency->is_tutor_core_has_req_verion() ) { + add_action( 'admin_notices', array( $dependency, 'show_admin_notice' ) ); + return; + } } - - include_once 'classes/TutorLMSMigrationTool.php'; - TutorLMSMigrationTool::instance(); -} +); if ( is_plugin_active( 'tutor/tutor.php' ) ) { diff --git a/views/migration_ld.php b/views/migration_ld.php index 73bf0cc..8ae1fb2 100644 --- a/views/migration_ld.php +++ b/views/migration_ld.php @@ -1,266 +1,276 @@ + * @link https://themeum.com + * @since 2.3.0 + */ -if ( ! defined( 'ABSPATH' ) ) +if ( ! defined( 'ABSPATH' ) ) { exit; +} ?>
- fetch_history('ld'); + $tutor_migration_history = $utils->fetch_history( 'ld' ); - $courses_count = $utils->ld_course_count(); - - $orders_count = $utils->ld_orders_count(); + $courses_count = $utils->ld_course_count(); - $items_count = $courses_count + $orders_count; - ?> - -
-
-
-
-
- -
-
- -
-
-
- import -
-
+ $orders_count = $utils->ld_orders_count(); -
- -
+ $items_count = $courses_count + $orders_count; + ?> + +
+
+
+
+
+ +
+
+ +
+
+
+ import +
+
+ +
+ +
-
-
-
-
- -
-
- -
-
- -
-
- -
-
-
-
-
-
-
-
- -
- - - - -
-
-
- - -
-
-
-
-
-
-
-
- -
-
- - - - - -
-
-
- -
-
-
- -
- - - - -
-
-
- -
-
-
-
-
- -
+
+
+
+
+ +
+
+ +
+
+ +
+
+ +
+
+
+
+
+
+
+
+ +
+ + + + +
+
+
+ + +
+
+
+
+
+
+
+
+ +
+
+ + + + + +
+
+
+ +
+
+
+ +
+ + + + +
+
+
+ +
+
+
+
+
+ +
- - -
-
- -
-
- - - - - - - - - - - - - - - -
- - -
-
- created_at ) ); - echo ', ' . date('h:i A', strtotime($tutor_history->created_at)); - ?> -
-
- migration_type == 'Imported') { - $migration_type_class = 'success'; - } else if ($tutor_history->migration_type == 'Exported') { - $migration_type_class = 'warning'; - } - ?> -
- - migration_type; ?> - -
-
-
-
- - -
+ + +
+
+ +
+
+ + + + + + + + + + + + + + + +
+ + +
+
+ created_at ) ); + echo ', ' . date( 'h:i A', strtotime( $tutor_history->created_at ) ); + ?> + +
+
+ migration_type == 'Imported' ) { + $migration_type_class = 'success'; + } elseif ( $tutor_history->migration_type == 'Exported' ) { + $migration_type_class = 'warning'; + } + ?> +
+ + migration_type ); ?> + +
+
+
+
+ + +
- export + export
- -
- + +
+ +
+ -
- -
+ +
- -
- - + +
+ +
@@ -300,20 +310,20 @@
- error-midal-alert-icon -
- -
+ +
- +
- \ No newline at end of file +