Last active
October 1, 2018 05:35
-
-
Save wpmudev-sls/c1d9579172faabf64fef4f77a4912d08 to your computer and use it in GitHub Desktop.
CoursePress] - Clone Unit Modules
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* Plugin Name: [CoursePress] - Clone Unit Modules | |
* Plugin URI: https://premium.wpmudev.org/ | |
* Description: Clones all Modules from a CoursePress Unit | |
* Author: Panos Lyrakis @ WPMUDEV | |
* Author URI: https://premium.wpmudev.org/ | |
* License: GPLv2 or later | |
*/ | |
if ( ! defined( 'ABSPATH' ) ) { | |
exit; | |
} | |
if ( ! class_exists( 'wpmudev_cp_clone_unit_modules_Modules' ) ) { | |
class wpmudev_cp_clone_unit_modules_Modules { | |
private static $_instance = null; | |
public static $slug = 'coursepress_clone_unit_module'; | |
private static $title = ''; | |
private static $menu_title = ''; | |
private static $post_type; | |
private static $unit_type; | |
private $courses; | |
private $parent_slug; | |
public static function get_instance() { | |
if( is_null( self::$_instance ) ){ | |
self::$_instance = new wpmudev_cp_clone_unit_modules_Modules(); | |
} | |
return self::$_instance; | |
} | |
private function __construct() { | |
if ( ! class_exists( 'CoursePress_Admin_Controller_Menu' ) ) { | |
return; | |
} | |
self::$title = self::$menu_title = 'Copy Unit Modules'; | |
self::$post_type = CoursePress_Data_Course::get_post_type_name(); | |
self::$unit_type = CoursePress_Data_Unit::get_post_type_name(); | |
$this->parent_slug = 'edit.php?post_type=' . self::$post_type; | |
add_action( 'admin_menu', array( $this, 'menu' ), 99 ); | |
add_action( 'admin_footer', array( $this, 'js' ) ); | |
add_action( 'wp_ajax_wpmudev_cp_clone_unit_modules', array( $this, 'clone_unit_ajax' ) ); | |
} | |
public function menu() { | |
add_submenu_page( | |
$this->parent_slug, | |
self::$title, | |
self::$menu_title, | |
apply_filters( 'coursepress_capabilities', 'manage_options' ), | |
'coursepress-clone-unit-modules-page', | |
array( $this, 'admin_page' ) | |
); | |
} | |
public static function clone_post( $post_id, $post_parent = null ) { | |
global $wpdb; | |
$post = get_post( $post_id ); | |
$target_post = self::post_to_array( $post, $post_parent ); | |
$new_post_id = wp_insert_post( $target_post ); | |
/* | |
* Clone terms | |
*/ | |
$taxonomies = get_object_taxonomies( $post->post_type ); // returns array of taxonomy names for post type, ex array("category", "post_tag"); | |
foreach ($taxonomies as $taxonomy) { | |
$post_terms = wp_get_object_terms( $post_id, $taxonomy, array( 'fields' => 'slugs' ) ); | |
wp_set_object_terms( $new_post_id, $post_terms, $taxonomy, false ); | |
} | |
/* | |
* Clone meta | |
*/ | |
$post_meta_infos = $wpdb->get_results( "SELECT meta_key, meta_value FROM {$wpdb->postmeta} WHERE post_id ={$post_id}" ); | |
// Fix any double meta entries which may cause issues | |
$meta_keys = array(); | |
foreach ( $post_meta_infos as $key => $meta ) { | |
$meta_key = trim( $meta->meta_key ); | |
if ( ! in_array( $meta_key, $meta_keys ) ) { | |
$meta_keys[] = $meta_key; | |
} | |
else { | |
unset( $post_meta_infos[ $key ] ); | |
} | |
} | |
if ( ! empty( $post_meta_infos ) ) { | |
$sql_query = "INSERT INTO $wpdb->postmeta (post_id, meta_key, meta_value) "; | |
foreach ( $post_meta_infos as $meta_info ) { | |
$meta_key = $meta_info->meta_key; | |
if ( | |
'_wp_old_slug' == $meta_key || | |
( 'module_type' == $meta_key && ! in_array( $meta_info->meta_value, array_keys( CoursePress_Helper_UI_Module::get_types() ) ) ) | |
) | |
{ | |
continue; | |
} | |
$meta_value = addslashes( $meta_info->meta_value ); | |
$sql_query_sel[] = "SELECT $new_post_id, '$meta_key', '$meta_value'"; | |
} | |
$sql_query.= implode( " UNION ALL ", $sql_query_sel ); | |
$wpdb->query( $sql_query ); | |
} | |
return $new_post_id; | |
} | |
public static function post_to_array( $post, $parent = null ) { | |
$post = (array) $post; | |
unset( $post['ID'] ); | |
unset( $post['post_date'] ); | |
unset( $post['post_date_gmt'] ); | |
unset( $post['post_modified'] ); | |
unset( $post['post_modified_gmt'] ); | |
unset( $post['guid'] ); | |
if ( ! is_null( $parent ) ) { | |
$post['post_parent'] = (int) $parent; | |
} | |
return $post; | |
} | |
public function clone_unit_ajax() { | |
check_ajax_referer( 'wpmudev_cp_clone_unit_modules', 'security' ); | |
$source_unit_id = (int) $_POST['source_unit']; | |
$target_unit_id = (int) $_POST['target_unit']; | |
$mapped_modules = array(); | |
$mapped_modules = array(); | |
$source_unit = get_post( $source_unit_id ); | |
$target_unit = get_post( $target_unit_id ); | |
if ( | |
! $source_unit instanceof WP_Post || self::$unit_type != $source_unit->post_type || | |
! $target_unit instanceof WP_Post || self::$unit_type != $target_unit->post_type | |
){ | |
$out = "One of the ids provided does not correspond to a unit"; | |
$return = array( | |
'success' => false, | |
'content' => $out | |
); | |
wp_send_json($return); | |
} | |
$source_course = $source_unit->post_parent; | |
$target_course = $target_unit->post_parent; | |
$clone_students = apply_filters( '_cp_cloner/clone_students', ! ( $source_course == $target_course ) ); | |
// 1. Fetch modules | |
$source_modules_ids = CoursePress_Data_Course::get_unit_modules( $source_unit_id, 'any' ,true ); | |
foreach ( $source_modules_ids as $source_module_id ) { | |
$target_module_id = self::clone_post( $source_module_id, $target_unit_id ); | |
$mapped_modules[ $source_module_id ] = $target_module_id; | |
} | |
// 2. Clone students and progress | |
// 2.1 Check if allowed to clone students | |
if ( $clone_students ) { | |
//.2 We need the students that exist in both courses | |
$source_students = CoursePress_Data_Course::get_student_ids( $source_course ); | |
$target_students = CoursePress_Data_Course::get_student_ids( $target_course ); | |
$student_ids = array_intersect( $source_students, $target_students ); | |
foreach ( $student_ids as $student_id ) { | |
$progress_meta = get_user_meta( $student_id, "course_{$source_course}_progress", true ); | |
$completion = $progress_meta['completion'][$source_unit_id]; | |
// 3.3 Re-map progress completion | |
// There are 2 completion_items of the unit that contain modules: modules_seen and answered | |
foreach ( $completion as $item_key => $items ) { | |
if ( 'modules_seen' != $item_key && 'answered' != $item_key ) { | |
$progress_meta['completion'][$target_unit_id][$item_key] = $items; | |
continue; | |
} | |
foreach ( $items as $module_id => $value ) { | |
if ( isset( $mapped_modules[$module_id] ) ) { | |
$progress_meta['completion'][$target_unit_id][$item_key][ $mapped_modules[$module_id] ] = $value; | |
} | |
} | |
if ( $source_course != $target_course ) { | |
unset( $progress_meta['completion'][$source_unit_id] ); | |
} | |
} | |
// 3.4 Re-map progress responses | |
// 3.4.1 Replace unit ids | |
$progress_meta['units'][$target_unit_id] = $progress_meta['units'][$source_unit_id]; | |
// Maybe unset $source_unit_id | |
if ( $source_course != $target_course ) { | |
unset( $progress_meta['units'][$source_unit_id] ); | |
} | |
// 3.4.2 Remap module in "responses" | |
if ( ! empty( $progress_meta['units'][$target_unit_id]['responses'] ) ) { | |
$responses = $progress_meta['units'][$target_unit_id]['responses']; | |
foreach ( $responses as $module_id => $value ) { | |
if ( isset( $mapped_modules[$module_id] ) ) { | |
$progress_meta['units'][$target_unit_id]['responses'][ $mapped_modules[$module_id] ] = $value; | |
unset( $progress_meta['units'][$target_unit_id]['responses'][ $module_id ] ); | |
} | |
} | |
} | |
if ( $source_course != $target_course ) { | |
unset( $progress_meta['units'][$source_unit_id] ); | |
} | |
if ( $source_course != $target_course ) { | |
unset( $progress_meta['units'][$source_unit_id]['responses'] ); | |
} | |
update_user_meta( $student_id, "course_{$target_course}_progress", $progress_meta ); | |
} | |
} | |
$out = 'Unit was cloned to selected course'; | |
$return = array( | |
'success' => true, | |
'content' => $out | |
); | |
wp_send_json($return); | |
} | |
public function admin_page(){ | |
?> | |
<div id="_cp_cloner"> | |
<h2>Copy Unit Modules</h2> | |
<h4>Insert Source Module</h4> | |
<input type="text" id="cp_source_unit_id" /> | |
<h4>Insert Target Module</h4> | |
<input type="text" id="cp_target_unit_id" /> | |
<div style="margin-top: 30px;"> | |
<a class="button" id="cp_clone_btn">Clone</a> | |
</div> | |
<div id="results_output"></div> | |
</div> | |
<?php | |
} | |
public function js() { | |
if ( ! function_exists( 'get_current_screen' ) || 'course_page_coursepress-clone-unit-modules-page' != get_current_screen()->id ) { | |
return; | |
} | |
?> | |
<script type="text/javascript"> | |
(function($){ | |
const cp_cloner = { | |
cloner_wrap : $( '#_cp_cloner' ), | |
source_unit: $( '#_cp_cloner #cp_source_unit_id' ), | |
target_unit: $( '#_cp_cloner #cp_target_unit_id' ), | |
clone_btn: $( '#_cp_cloner #cp_clone_btn' ), | |
nonce: '<?php echo wp_create_nonce( "wpmudev_cp_clone_unit_modules" ); ?>', | |
results_output: $( '#results_output' ), | |
clone: function( source_unit, target_unit ) { | |
cp_cloner.results_output.html( 'Please wait while cloning modules' ); | |
let data = { | |
action: 'wpmudev_cp_clone_unit_modules', | |
security: this.nonce, | |
source_unit: source_unit, | |
target_unit: target_unit | |
}; | |
$.post( ajaxurl, data, function( response ) { | |
if( response.success ){ | |
cp_cloner.results_output.html( response.content ); | |
} | |
else{ | |
cp_cloner.results_output.html( response.content ); | |
} | |
}); | |
} | |
} | |
$(document).ready(function(){ | |
$(cp_cloner.clone_btn).on('click',function(e){ | |
e.preventDefault(); | |
if ( '' == cp_cloner.source_unit.val() || '' == cp_cloner.target_unit.val() ) { | |
alert( 'You need to insert the id of the source unit and the id ofthe terget unit' ); | |
} | |
cp_cloner.clone( cp_cloner.source_unit.val(), cp_cloner.target_unit.val() ); | |
}); | |
}); | |
})(jQuery); | |
</script> | |
<?php | |
} | |
} | |
if ( ! function_exists( 'wpmudev_cp_clone_unit_modules' ) ) { | |
function wpmudev_cp_clone_unit_modules() { | |
return wpmudev_cp_clone_unit_modules_Modules::get_instance(); | |
}; | |
add_action( 'plugins_loaded', 'wpmudev_cp_clone_unit_modules', 10 ); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment