| 1 |
<?php |
| 2 |
/** |
| 3 |
* This class works as a connection helper to connect with Moodle webservice API. |
| 4 |
* |
| 5 |
* @link https://edwiser.org |
| 6 |
* @since 1.0.0 |
| 7 |
* @package Edwiser Bridge. |
| 8 |
*/ |
| 9 |
|
| 10 |
namespace app\wisdmlabs\edwiserBridge; |
| 11 |
|
| 12 |
if ( ! defined( 'ABSPATH' ) ) { |
| 13 |
exit; // Exit if accessed directly. |
| 14 |
} |
| 15 |
|
| 16 |
/** |
| 17 |
* Esternal API. |
| 18 |
*/ |
| 19 |
class Eb_External_Api_Endpoint { |
| 20 |
|
| 21 |
/** |
| 22 |
* This method registers the webservice endpointr. |
| 23 |
*/ |
| 24 |
public function api_registration() { |
| 25 |
register_rest_route( |
| 26 |
'edwiser-bridge', |
| 27 |
'/wisdmlabs/', |
| 28 |
array( |
| 29 |
'methods' => \WP_REST_Server::EDITABLE, |
| 30 |
'callback' => array( $this, 'external_api_endpoint_def' ), |
| 31 |
'permission_callback' => '__return_true', |
| 32 |
) |
| 33 |
); |
| 34 |
} |
| 35 |
|
| 36 |
|
| 37 |
/** |
| 38 |
* Functionality to validate the secret key from Moodle with WP. |
| 39 |
* |
| 40 |
* @param text $request_data request Data. |
| 41 |
*/ |
| 42 |
public function eb_validate_api_key( $request_data ) { |
| 43 |
$wp_token = \app\wisdmlabs\edwiserBridge\wdm_edwiser_bridge_plugin_get_access_token(); |
| 44 |
$valid_key = false; |
| 45 |
if ( isset( $request_data['secret_key'] ) && ! empty( $request_data['secret_key'] ) && hash_equals( (string) $wp_token, (string) $request_data['secret_key'] ) ) { |
| 46 |
$valid_key = true; |
| 47 |
} |
| 48 |
return $valid_key; |
| 49 |
} |
| 50 |
|
| 51 |
|
| 52 |
|
| 53 |
/** |
| 54 |
* This function parse the request coming from |
| 55 |
* |
| 56 |
* @param text $request_data request Data. |
| 57 |
*/ |
| 58 |
public function external_api_endpoint_def( $request_data ) { |
| 59 |
$response_data = array(); |
| 60 |
|
| 61 |
// CHeck if key is valid. |
| 62 |
if ( isset( $request_data['action'] ) && ! empty( $request_data['action'] ) && $this->eb_validate_api_key( $request_data ) ) { |
| 63 |
$action = sanitize_text_field( wp_unslash( $request_data['action'] ) ); |
| 64 |
|
| 65 |
switch ( $action ) { |
| 66 |
case 'test_connection': |
| 67 |
$response_data = $this->eb_test_connection( $request_data ); |
| 68 |
break; |
| 69 |
|
| 70 |
case 'course_enrollment': |
| 71 |
$response_data = $this->eb_course_enrollment( $request_data, 0 ); |
| 72 |
break; |
| 73 |
|
| 74 |
case 'course_un_enrollment': |
| 75 |
$response_data = $this->eb_course_enrollment( $request_data, 1 ); |
| 76 |
break; |
| 77 |
|
| 78 |
case 'user_creation': |
| 79 |
$response_data = $this->eb_trigger_user_creation( $request_data ); |
| 80 |
break; |
| 81 |
|
| 82 |
case 'user_deletion': |
| 83 |
$response_data = $this->eb_trigger_user_delete( $request_data ); |
| 84 |
break; |
| 85 |
|
| 86 |
case 'user_updated': |
| 87 |
$response_data = $this->eb_trigger_user_update( $request_data ); |
| 88 |
break; |
| 89 |
|
| 90 |
case 'course_created': |
| 91 |
$response_data = $this->eb_trigger_course_creation( $request_data ); |
| 92 |
break; |
| 93 |
|
| 94 |
case 'course_deleted': |
| 95 |
$response_data = $this->eb_trigger_course_delete( $request_data ); |
| 96 |
break; |
| 97 |
|
| 98 |
default: |
| 99 |
// Apply filter here for more default options. |
| 100 |
break; |
| 101 |
} |
| 102 |
} elseif ( ! $this->eb_validate_api_key( $request_data ) ) { |
| 103 |
$response_data = array( |
| 104 |
'status' => 0, |
| 105 |
'msg' => 'Invalid token please check token', |
| 106 |
); |
| 107 |
} |
| 108 |
return $response_data; |
| 109 |
} |
| 110 |
|
| 111 |
|
| 112 |
/** |
| 113 |
* Function to test connection for the request from Moodle. |
| 114 |
* |
| 115 |
* @param data $data data. |
| 116 |
*/ |
| 117 |
protected function eb_test_connection( $data ) { |
| 118 |
$status = 0; |
| 119 |
|
| 120 |
if ( isset( $data['secret_key'] ) ) { |
| 121 |
$settings = maybe_unserialize( get_option( 'eb_connection' ) ); |
| 122 |
if ( ! isset( $settings['eb_access_token'] ) ) { |
| 123 |
$msg = 'Please save connection settings on Worpdress'; |
| 124 |
} elseif ( $settings['eb_access_token'] !== $data['secret_key'] ) { |
| 125 |
$msg = 'Invalid token please check token'; |
| 126 |
$status = 0; |
| 127 |
} else { |
| 128 |
$msg = 'Test connection successful'; |
| 129 |
$status = 1; |
| 130 |
} |
| 131 |
} |
| 132 |
return array( |
| 133 |
'status' => $status, |
| 134 |
'msg' => $msg, |
| 135 |
); |
| 136 |
} |
| 137 |
|
| 138 |
|
| 139 |
/** |
| 140 |
* Function to enroll or unenroll from the course for the request coming from Moodle |
| 141 |
* |
| 142 |
* @param [type] $data data. |
| 143 |
* @param [type] $un_enroll un_enroll. |
| 144 |
* @return [type] [description] |
| 145 |
*/ |
| 146 |
protected function eb_course_enrollment( $data, $un_enroll ) { |
| 147 |
if ( isset( $data['user_id'] ) && isset( $data['course_id'] ) ) { |
| 148 |
$mdl_course_id = $data['course_id']; |
| 149 |
$wp_course_id = \app\wisdmlabs\edwiserBridge\wdm_eb_get_wp_course_id_from_moodle_course_id( $data['course_id'] ); |
| 150 |
|
| 151 |
if ( $wp_course_id ) { |
| 152 |
$mdl_user_id = $data['user_id']; |
| 153 |
$wp_user_id = \app\wisdmlabs\edwiserBridge\wdm_eb_get_wp_user_id_from_moodle_id( $data['user_id'] ); |
| 154 |
if ( ! $wp_user_id && empty( $wp_user_id ) && 0 === $un_enroll ) { |
| 155 |
$role = \app\wisdmlabs\edwiserBridge\wdm_eb_default_registration_role(); |
| 156 |
|
| 157 |
// Check if user is available with same email address. |
| 158 |
$eb_user = get_user_by( 'email', $data['email'] ); |
| 159 |
|
| 160 |
if ( $eb_user && isset( $eb_user->ID ) ) { |
| 161 |
$wp_user_id = $eb_user->ID; |
| 162 |
} else { |
| 163 |
$wp_user_id = $this->create_only_wp_user( $data['user_name'], $data['email'], $data['first_name'], $data['last_name'], $role ); |
| 164 |
} |
| 165 |
update_user_meta( $wp_user_id, 'moodle_user_id', $mdl_user_id ); |
| 166 |
} |
| 167 |
|
| 168 |
if ( $wp_user_id ) { |
| 169 |
$user = get_user_by( 'ID', $wp_user_id ); |
| 170 |
|
| 171 |
$args = array( |
| 172 |
'user_id' => $wp_user_id, |
| 173 |
'role_id' => 5, |
| 174 |
'courses' => array( $wp_course_id ), |
| 175 |
'unenroll' => $un_enroll, |
| 176 |
'suspend' => 0, |
| 177 |
); |
| 178 |
|
| 179 |
// check if there any pending enrollments for the given course then don't enroll user. |
| 180 |
$user_enrollment_meta = get_user_meta( $wp_user_id, 'eb_pending_enrollment', 1 ); |
| 181 |
|
| 182 |
if ( is_array( $user_enrollment_meta ) && in_array( $wp_course_id, $user_enrollment_meta ) ) { // @codingStandardsIgnoreLine |
| 183 |
return; |
| 184 |
} |
| 185 |
|
| 186 |
$args['complete_unenroll'] = 0; |
| 187 |
if ( $un_enroll ) { |
| 188 |
$args['complete_unenroll'] = 1; |
| 189 |
} |
| 190 |
|
| 191 |
edwiser_bridge_instance()->enrollment_manager()->update_enrollment_record_wordpress( $args ); |
| 192 |
|
| 193 |
$args = array( |
| 194 |
'user_email' => $user->user_email, |
| 195 |
'username' => $user->user_login, |
| 196 |
'first_name' => $user->first_name, |
| 197 |
'last_name' => $user->last_name, |
| 198 |
'course_id' => $wp_course_id, |
| 199 |
); |
| 200 |
if ( $un_enroll ) { |
| 201 |
do_action( 'eb_mdl_un_enrollment_trigger', $args ); |
| 202 |
} else { |
| 203 |
|
| 204 |
do_action( 'eb_mdl_enrollment_trigger', $args ); |
| 205 |
} |
| 206 |
} |
| 207 |
} |
| 208 |
} |
| 209 |
} |
| 210 |
|
| 211 |
|
| 212 |
|
| 213 |
/** |
| 214 |
* Function to create user for the user creation request coming from Moodle. |
| 215 |
* |
| 216 |
* @param text $data data. |
| 217 |
*/ |
| 218 |
public function eb_trigger_user_creation( $data ) { |
| 219 |
if ( isset( $data['user_name'] ) && isset( $data['email'] ) ) { |
| 220 |
$role = \app\wisdmlabs\edwiserBridge\wdm_eb_default_registration_role(); |
| 221 |
$eb_access_token = \app\wisdmlabs\edwiserBridge\wdm_edwiser_bridge_plugin_get_access_token(); |
| 222 |
$user_p = ''; |
| 223 |
if ( isset( $data['password'] ) && ! empty( $data['password'] ) ) { |
| 224 |
|
| 225 |
$enc_method = 'AES-128-CTR'; |
| 226 |
$enc_iv = substr( hash( 'sha256', $eb_access_token ), 0, 16 ); |
| 227 |
$enc_key = openssl_digest( $eb_access_token, 'SHA256', true ); |
| 228 |
$user_p = openssl_decrypt( $data['password'], $enc_method, $enc_key, 0, $enc_iv ); |
| 229 |
} |
| 230 |
|
| 231 |
// When Moodle auto-generated the password and already sent its own notification email, |
| 232 |
// suppress the EB credential email to avoid sending a different (WordPress) password |
| 233 |
// that would not work for Moodle login, causing user confusion. |
| 234 |
$moodle_sent_notification = ! empty( $data['moodle_generated_password'] ); |
| 235 |
|
| 236 |
$wp_user_id = $this->create_only_wp_user( $data['user_name'], $data['email'], $data['first_name'], $data['last_name'], $role, $user_p, $moodle_sent_notification ); |
| 237 |
if ( $wp_user_id ) { |
| 238 |
update_user_meta( $wp_user_id, 'moodle_user_id', $data['user_id'] ); |
| 239 |
|
| 240 |
// user creation hook. |
| 241 |
do_action( 'eb_user_created_from_moodle', $wp_user_id, $data ); |
| 242 |
} |
| 243 |
} |
| 244 |
} |
| 245 |
|
| 246 |
|
| 247 |
/** |
| 248 |
* Function to delete user for the user deletion request coming from Moodle. |
| 249 |
* |
| 250 |
* @param text $data data. |
| 251 |
*/ |
| 252 |
public function eb_trigger_user_delete( $data ) { |
| 253 |
require_once ABSPATH . 'wp-admin/includes/user.php'; |
| 254 |
if ( isset( $data['user_id'] ) ) { |
| 255 |
$wp_user_id = \app\wisdmlabs\edwiserBridge\wdm_eb_get_wp_user_id_from_moodle_id( $data['user_id'] ); |
| 256 |
if ( $wp_user_id ) { |
| 257 |
$deleted = wp_delete_user( $wp_user_id ); |
| 258 |
} |
| 259 |
} |
| 260 |
} |
| 261 |
|
| 262 |
|
| 263 |
|
| 264 |
/** |
| 265 |
* Functinality to create only WordPress user. |
| 266 |
* |
| 267 |
* @param text $username username. |
| 268 |
* @param text $email email. |
| 269 |
* @param text $firstname firstname. |
| 270 |
* @param text $lastname lastname. |
| 271 |
* @param text $role role. |
| 272 |
* @param string $user_p password. |
| 273 |
*/ |
| 274 |
public function create_only_wp_user( $username, $email, $firstname, $lastname, $role = '', $user_p = '', $suppress_email = false ) { |
| 275 |
$uc_status = new \WP_Error( |
| 276 |
'registration-error', |
| 277 |
esc_html__( 'An account is already registered with your email address. Please login.', 'edwiser-bridge' ), |
| 278 |
'eb_email_exists' |
| 279 |
); |
| 280 |
if ( email_exists( $email ) ) { |
| 281 |
$uc_status = new \WP_Error( |
| 282 |
'registration-error', |
| 283 |
esc_html__( 'An account is already registered with your email address. Please login.', 'edwiser-bridge' ), |
| 284 |
'eb_email_exists' |
| 285 |
); |
| 286 |
} else { |
| 287 |
|
| 288 |
// Ensure username is unique. |
| 289 |
$append = 1; |
| 290 |
$o_username = $username; |
| 291 |
|
| 292 |
while ( username_exists( $username ) ) { |
| 293 |
$username = $o_username . $append; |
| 294 |
++$append; |
| 295 |
} |
| 296 |
|
| 297 |
if ( empty( $user_p ) ) { |
| 298 |
// Handle password creation. |
| 299 |
$user_p = wp_generate_password(); |
| 300 |
} |
| 301 |
|
| 302 |
// WP Validation. |
| 303 |
$validation_errors = new \WP_Error(); |
| 304 |
|
| 305 |
if ( $validation_errors->get_error_code() ) { |
| 306 |
$uc_status = $validation_errors; |
| 307 |
} else { |
| 308 |
|
| 309 |
// Added after 1.3.4. |
| 310 |
if ( '' === $role ) { |
| 311 |
$role = get_option( 'default_role' ); |
| 312 |
} |
| 313 |
|
| 314 |
$wp_user_data = apply_filters( |
| 315 |
'eb_new_user_data', |
| 316 |
array( |
| 317 |
'user_login' => $username, |
| 318 |
'user_pass' => $user_p, |
| 319 |
'user_email' => $email, |
| 320 |
'role' => $role, |
| 321 |
) |
| 322 |
); |
| 323 |
|
| 324 |
$user_id = wp_insert_user( $wp_user_data ); |
| 325 |
|
| 326 |
if ( is_wp_error( $user_id ) ) { |
| 327 |
$uc_status = new \WP_Error( |
| 328 |
'registration-error', |
| 329 |
'<strong>' . esc_html__( 'ERROR', 'edwiser-bridge' ) . '</strong>: ' . |
| 330 |
esc_html__( |
| 331 |
'Couldn’t register you… please contact us if you continue to have problems.', |
| 332 |
'edwiser-bridge' |
| 333 |
) |
| 334 |
); |
| 335 |
} else { |
| 336 |
|
| 337 |
// update firstname, lastname. |
| 338 |
update_user_meta( $user_id, 'first_name', $firstname ); |
| 339 |
update_user_meta( $user_id, 'last_name', $lastname ); |
| 340 |
|
| 341 |
$args = array( |
| 342 |
'user_email' => $email, |
| 343 |
'username' => $username, |
| 344 |
'first_name' => $firstname, |
| 345 |
'last_name' => $lastname, |
| 346 |
'password' => $user_p, |
| 347 |
); |
| 348 |
if ( ! $suppress_email ) { |
| 349 |
do_action( 'eb_created_user', $args ); |
| 350 |
} |
| 351 |
$uc_status = $user_id; |
| 352 |
} |
| 353 |
} |
| 354 |
} |
| 355 |
return $uc_status; |
| 356 |
} |
| 357 |
/** |
| 358 |
* Trigger course creation. |
| 359 |
* |
| 360 |
* @param text $data data. |
| 361 |
*/ |
| 362 |
public function eb_trigger_course_creation( $data ) { |
| 363 |
|
| 364 |
if ( isset( $data['course_id'] ) ) { |
| 365 |
// Create course data. |
| 366 |
$course_data = new \stdClass(); |
| 367 |
$course_data->id = $data['course_id']; |
| 368 |
$course_data->fullname = $data['fullname']; |
| 369 |
$course_data->summary = $data['summary']; |
| 370 |
$course_data->categoryid = $data['cat']; |
| 371 |
|
| 372 |
// Create WP course from Moodle course id info. |
| 373 |
edwiser_bridge_instance()->course_manager()->create_course_on_wordpress( |
| 374 |
$course_data, |
| 375 |
array( |
| 376 |
'eb_synchronize_draft' => '1', |
| 377 |
) |
| 378 |
); |
| 379 |
} |
| 380 |
} |
| 381 |
|
| 382 |
|
| 383 |
|
| 384 |
/** |
| 385 |
* Trigger Delete. |
| 386 |
* |
| 387 |
* @param text $data data. |
| 388 |
*/ |
| 389 |
public function eb_trigger_course_delete( $data ) { |
| 390 |
|
| 391 |
if ( isset( $data['course_id'] ) ) { |
| 392 |
global $wpdb; |
| 393 |
$wp_course_ids = $wpdb->get_col( $wpdb->prepare( "SELECT post_id FROM {$wpdb->prefix}postmeta WHERE meta_key='moodle_course_id' AND meta_value=%d", $data['course_id'] ) ); // @codingStandardsIgnoreLine |
| 394 |
|
| 395 |
foreach ( $wp_course_ids as $wp_course_id ) { |
| 396 |
$course_meta = get_post_meta( $wp_course_id, 'eb_course_options', 1 ); |
| 397 |
$course_meta['mdl_course_deleted'] = 1; |
| 398 |
|
| 399 |
wp_update_post( |
| 400 |
array( |
| 401 |
'ID' => $wp_course_id, |
| 402 |
'post_type' => 'eb_course', |
| 403 |
'post_status' => 'draft', |
| 404 |
) |
| 405 |
); |
| 406 |
|
| 407 |
update_post_meta( $wp_course_id, 'eb_course_options', $course_meta ); |
| 408 |
} |
| 409 |
} |
| 410 |
} |
| 411 |
|
| 412 |
|
| 413 |
/** |
| 414 |
* User update. |
| 415 |
* |
| 416 |
* @param text $data data. |
| 417 |
*/ |
| 418 |
public function eb_trigger_user_update( $data ) { |
| 419 |
// get WP User id if present then process. |
| 420 |
$wp_user_id = \app\wisdmlabs\edwiserBridge\wdm_eb_get_wp_user_id_from_moodle_id( $data['user_id'] ); |
| 421 |
$eb_access_token = \app\wisdmlabs\edwiserBridge\wdm_edwiser_bridge_plugin_get_access_token(); |
| 422 |
|
| 423 |
if ( ! empty( $wp_user_id ) ) { |
| 424 |
// get fields. |
| 425 |
$user_update_array = array( |
| 426 |
'ID' => $wp_user_id, |
| 427 |
); |
| 428 |
|
| 429 |
// CHecking this as when user updates password through preferences only password will be sent to the WordPress, so if anyone of the field is empty we need to only update password. |
| 430 |
if ( isset( $data['first_name'] ) && ! empty( $data['first_name'] ) ) { |
| 431 |
$user_update_array['first_name'] = $data['first_name']; |
| 432 |
$user_update_array['last_name'] = $data['last_name']; |
| 433 |
} |
| 434 |
|
| 435 |
// if password is present then decode with key. |
| 436 |
if ( isset( $data['password'] ) && ! empty( $data['password'] ) ) { |
| 437 |
$enc_method = 'AES-128-CTR'; |
| 438 |
$enc_iv = substr( hash( 'sha256', $eb_access_token ), 0, 16 ); |
| 439 |
|
| 440 |
$enc_key = openssl_digest( $eb_access_token, 'SHA256', true ); |
| 441 |
$user_p = openssl_decrypt( $data['password'], $enc_method, $enc_key, 0, $enc_iv ); |
| 442 |
$user_update_array['user_pass'] = $user_p; |
| 443 |
} |
| 444 |
|
| 445 |
$user_email = get_user_meta( $wp_user_id, 'user_email', true ); |
| 446 |
if ( isset( $data['email'] ) && ! empty( $data['email'] ) && $user_email !== $data['email'] ) { |
| 447 |
$user_update_array['user_email'] = $data['email']; |
| 448 |
} |
| 449 |
|
| 450 |
$user_update_array = apply_filters( 'eb_mdl_user_update_trigger_data', $user_update_array ); |
| 451 |
|
| 452 |
// Update password and fields. |
| 453 |
wp_update_user( $user_update_array ); |
| 454 |
|
| 455 |
do_action( 'eb_user_updated_from_moodle', $wp_user_id, $data ); |
| 456 |
} |
| 457 |
} |
| 458 |
} |
| 459 |
|