Current File : /home/escuelai/public_html/wp-content/plugins/learnpress/inc/user-item/class-lp-user-item.php |
<?php
/**
* Class LP_User_Item
*
* @since 3.0.0
*/
class LP_User_Item extends LP_Abstract_Object_Data {
/**
* Auto increment
*
* @var int
*/
public $_user_item_id = 0;
/**
* User id
*
* @var string
*/
public $_user_id = 0;
/**
* Item id (course, lesson, quiz ...)
*
* @var string
*/
public $_item_id = 0;
/**
* @var string
*/
public $_start_time = '';
/**
* @var string
*/
public $_end_time = '';
/**
* Item type (course, lesson, quiz ...)
*
* @var string
*/
public $_item_type = '';
/**
* Status
*
* @var string
*/
public $_status = '';
/**
* Graduation
*
* @var string
*/
public $_graduation = '';
/**
* Ref id (Order, course ...)
*
* @var string
*/
public $_ref_id = '';
/**
* Ref type (Order, course ...)
*
* @var string
*/
public $_ref_type = '';
/**
* Parent id
*
* @var string
*/
public $_parent_id = '';
/**
* Key get data start time form DB.
*/
const KEY_DATA_START_TIME = 'start_time';
/**
* Key get data end time form DB.
*/
const KEY_DATA_END_TIME = 'end_time';
/**
* LP_User_Item constructor.
*
* @param array $item . A record fetched from table _learnpress_user_items
*/
public function __construct( $item ) {
if ( is_numeric( $item ) ) {
$item = array( 'item_id' => $item );
} else {
$item = (array) $item;
}
// $this->_data = self::get_empty_item();
parent::__construct( $item );
$this->set_default_data( $item );
}
/**
* Set data from passed args
*
* @param array $item
*/
protected function set_default_data( $item ) {
$this->_changes = array();
$item_id = 0;
if ( ! empty( $item['user_item_id'] ) ) {
$this->set_data( 'user_item_id', absint( $item['user_item_id'] ) );
}
if ( ! empty( $item['item_id'] ) ) {
$item['item_id'] = absint( $item['item_id'] );
$this->set_id( $item['item_id'] );
$this->set_data( 'item_id', $item['item_id'] );
$this->set_data( 'item_type', learn_press_get_post_type( $item['item_id'] ) );
$item_id = $item['item_id'];
}
$this->set_start_time( $item[ self::KEY_DATA_START_TIME ] ?? time() );
$this->set_end_time( $item[ self::KEY_DATA_END_TIME ] ?? '' );
$this->set_user_id( absint( $item['user_id'] ?? get_current_user_id() ) );
$this->set_status( $item['status'] ?? '' );
if ( ! empty( $item['ref_id'] ) ) {
$item['ref_id'] = absint( $item['ref_id'] );
$this->set_ref_id( $item['ref_id'] );
if ( empty( $item['ref_type'] ) ) {
$this->set_data( 'ref_type', learn_press_get_post_type( $item['ref_id'] ) );
}
}
if ( ! empty( $item['ref_type'] ) ) {
$this->set_data( 'ref_type', $item['ref_type'] );
}
if ( ! empty( $item['parent_id'] ) ) {
$item['parent_id'] = absint( $item['parent_id'] );
$this->set_parent_id( $item['parent_id'] );
}
if ( ! empty( $item['access_level'] ) ) {
$this->set_data( 'access_level', $item['access_level'] );
}
$this->set_data( 'graduation', $item['graduation'] ?? '' );
}
public function set_user_id( $user_id ) {
$this->set_data( 'user_id', $user_id );
}
public function get_user_id() {
return $this->get_data( 'user_id' );
}
public function set_ref_id( $ref_id ) {
$this->set_data( 'ref_id', $ref_id );
$this->set_data( 'ref_type', learn_press_get_post_type( $ref_id ) );
}
public function get_parent_id() {
return absint( $this->get_data( 'parent_id' ) );
}
public function set_parent_id( $parent_id ) {
$this->set_data( 'parent_id', $parent_id );
}
/**
* Get access level to a course.
*
* @return int
* @since 3.x.x
*/
public function get_access_level() {
return absint( $this->get_data( 'access_level' ) );
}
/**
* Get type of item. Consider is post-type.
*
* @return array|mixed
*/
public function get_type() {
return $this->get_data( 'item_type' );
}
/**
* Set start-time.
*
* @param mixed $time .
*
* @return $this
*/
public function set_start_time( $time = '' ): LP_User_Item {
$this->set_data_date( 'start_time', $time );
return $this;
}
/**
* Get start-time.
*
* @param string $format
* @param bool $local
*
* @return string|LP_Datetime|false
*/
public function get_start_time( string $format = '', $local = false ) {
$date = $this->get_data( self::KEY_DATA_START_TIME );
return $this->format_time( $date, $format, $local );
}
/**
* Set end-time for item.
*
* @param mixed $time
*
* @return $this
*/
public function set_end_time( $time = '' ): LP_User_Item {
$this->set_data_date( 'end_time', $time );
return $this;
}
/**
* Get end-time.
*
* @param string $format
*
* @return string|LP_Datetime
*/
public function get_end_time( string $format = '' ) {
$date = $this->get_data( self::KEY_DATA_END_TIME );
return $this->format_time( $date, $format );
}
/**
* @param string|int|LP_Datetime $date
* @param string $format
* @param bool $local
*
* @return bool|float|int|LP_Datetime|string
*/
public function format_time( $date, $format = '', $local = false ) {
if ( ! $date ) {
return false;
}
if ( ! $date instanceof LP_Datetime ) {
$date = new LP_Datetime( $date );
}
return $format ? $date->format( $format, $local ) : $date;
}
/**
* Get expiration time.
*
* @return string|LP_Datetime $time
* @since 3.3.0
* @version 3.3.2
*/
public function get_expiration_time() {
$duration = get_post_meta( $this->get_item_id(), '_lp_duration', true );
$start_time = $this->get_start_time()->getTimestamp();
if ( ! absint( $duration ) || ! $start_time ) {
$expire = null;
} else {
// Convert duration from string to seconds.
if ( ! is_numeric( $duration ) ) {
$duration = strtotime( $duration ) - time();
}
$expire_time = $start_time + $duration;
$expire = new LP_Datetime( $expire_time );
}
return apply_filters( 'learn-press/user-item/expiration-time', $expire, $duration, $this );
}
/**
* Set item-status.
*
* @param string $status .
*
* @return $this
*/
public function set_status( string $status ): LP_User_Item {
$this->_set_data( 'status', $status );
return $this;
}
/**
* Get item status.
*
* @param string $field
* @param bool $force_cache Reset first cache
*
* @version 1.0.1
* @return string
* @editor tungnx
* @modify 4.1.3
*/
public function get_status( string $field = 'status', bool $force_cache = false ): string {
$got_status = '';
try {
// User is Guest
if ( (int) $this->get_user_id() === 0 ) {
return $got_status;
}
if ( LP_COURSE_CPT === $this->get_type() ) {
return $this->get_data( $field );
}
/*error_log('status user item id: ' . $this->get_id());
error_log('status user item type: ' . $this->get_type());
error_log('status user course status: ' . $this->get_data( $field ));*/
$lp_user_item = LP_User_Items_DB::getInstance();
$filter = new LP_User_Items_Filter();
$filter->user_id = $this->get_user_id();
$filter->item_id = $this->get_item_id();
$filter->ref_id = $this->get_data( 'ref_id' );
$filter->parent_id = $this->get_parent_id();
$user_item = $lp_user_item->get_user_course_item( $filter, $force_cache );
if ( ! empty( $user_item ) && isset( $user_item->$field ) ) {
$got_status = $user_item->$field;
}
$this->set_data( $field, $got_status );
} catch ( Throwable $e ) {
LP_Debug::error_log( $e );
}
return $got_status;
}
public function is_exists() {
return ! ! $this->get_user_item_id();
}
/**
* @param string $return
*
* @return LP_User|int
*/
public function get_user( $return = '' ) {
return $this->get_data( 'user_id', 0 );
}
/**
* Get course.
*
* @param string $return
*
* @return bool|LP_Course|int|mixed
*/
public function get_course( string $return = '' ) {
$course_id = $this->get_data( 'ref_id', 0 );
if ( $return == '' ) {
return $course_id ? learn_press_get_course( $course_id ) : false;
}
return $course_id;
}
/**
* @return int
*/
public function get_user_item_id() {
return intval( $this->get_data( 'user_item_id' ) );
}
/**
* Change the primary key user_item_id of user-items.
* Only use zero value to force creating new item.
*
* @param int $user_item_id
*/
public function set_user_item_id( $user_item_id ) {
$this->_set_data( 'user_item_id', absint( $user_item_id ) );
}
public function get_item_id() {
return $this->get_data( 'item_id' );
}
public function get_parent() {
$user = learn_press_get_user( $this->get_user_id() );
$ref_id = $this->get_data( 'ref_id' );
if ( get_post_type( $ref_id ) === LP_COURSE_CPT ) {
return $user->get_course_data( $ref_id );
}
return false;
}
public function get_result( $prop = 'result' ) {
$result = array(
'result' => $this->is_completed() ? 100 : 0,
'grade' => $this->is_completed() ? 'passed' : 'failed',
);
return $prop && array_key_exists( $prop, $result ) ? $result[ $prop ] : $result;
}
public function read_meta() {
global $wpdb;
$query = $wpdb->prepare(
"
SELECT *
FROM {$wpdb->learnpress_user_itemmeta}
WHERE learnpress_user_item_id = %d
",
$this->get_user_item_id()
);
$results = $wpdb->get_results( $query );
if ( $results ) {
foreach ( $results as $result ) {
$result->meta_value = LP_Helper::maybe_unserialize( $result->meta_value );
$this->_meta_data[] = $result;
}
}
}
/**
* Get structure of an user item.
*
* @return array
* @since 3.1.0
*/
public static function get_empty_item() {
return array(
'user_item_id' => 0,
'user_id' => 0,
'item_id' => 0,
'start_time' => '',
'end_time' => '',
'item_type' => '',
'status' => '',
'graduation' => '',
'access_level' => 50,
'ref_id' => '',
'ref_type' => '',
'parent_id' => 0,
);
}
/**
* Get user-item meta data.
* Check if meta data does not exist then return FALSE.
*
* @updated 3.1.0
*
* @param string $key
* @param bool $single
*
* @return bool|mixed
*/
public function get_meta( $key, $single = true ) {
if ( ! metadata_exists( 'learnpress_user_item', $this->get_user_item_id(), $key ) ) {
return false;
}
return learn_press_get_user_item_meta( $this->get_user_item_id(), $key, $single );
}
/**
* Update meta data
*
* @updated 3.1.0
*
* @param string $key
* @param string $value
* @param string $prev_value
*
* @editor tungnx add bk method
*/
public function update_meta_bk( $key = '', $value = '', $prev_value = '' ) {
if ( func_num_args() === 0 ) {
if ( $this->_meta_data ) {
foreach ( $this->_meta_data as $meta_data ) {
if ( $meta_data->meta_value ) {
learn_press_update_user_item_meta(
$this->get_user_item_id(),
$meta_data->meta_key,
$meta_data->meta_value
);
} else {
learn_press_delete_user_item_meta( $this->get_user_item_id(), $meta_data->meta_key );
}
}
}
} else {
if ( is_array( $key ) ) {
foreach ( $key as $k => $v ) {
if ( $v === false ) {
learn_press_delete_user_item_meta( $this->get_user_item_id(), $k );
} else {
learn_press_update_user_item_meta( $this->get_user_item_id(), $k, $v );
}
}
} else {
if ( $value === false ) {
learn_press_delete_user_item_meta( $this->get_user_item_id(), $key );
} else {
learn_press_update_user_item_meta( $this->get_user_item_id(), $key, $value, $prev_value );
}
}
}
}
/**
* Update meta data
*
* @param string $key .
* @param string $value .
* @param string $prev_value .
*
* @return int|bool
* @editor tungnx
*/
public function update_meta( $key = '', $value = '', $prev_value = '' ) {
$result = false;
if ( is_array( $key ) ) {
$result = $this->update_meta_multiple_keys( $key );
} else {
if ( false === $value ) {
$result = learn_press_delete_user_item_meta( $this->get_user_item_id(), $key );
} else {
$result = learn_press_update_user_item_meta( $this->get_user_item_id(), $key, $value, $prev_value );
}
}
return $result;
}
/**
* Update metadata with array keys values
*
* @param array $meta_datas .
*
* @return bool|int
*/
public function update_meta_multiple_keys( $meta_datas = array() ) {
$result = false;
foreach ( $meta_datas as $k => $v ) {
if ( false === $v ) {
$result = learn_press_delete_user_item_meta( $this->get_user_item_id(), $k );
} else {
$result = learn_press_update_user_item_meta( $this->get_user_item_id(), $k, $v );
}
}
return $result;
}
public function get_mysql_data() {
/**
* @var LP_Datetime $v
*/
$columns = array();
foreach ( $this->get_data() as $k => $v ) {
$columns[ $k ] = $v;
}
return $columns;
}
/**
* @param $data
*
* @return LP_User_Item|bool
*/
public static function get_item_object( $data ) {
$item_id = 0;
if ( is_array( $data ) && isset( $data['item_id'] ) ) {
$item_id = $data['item_id'];
} elseif ( is_object( $data ) && isset( $data->item_id ) ) {
$item_id = $data->item_id;
} elseif ( is_numeric( $data ) ) {
$item_id = absint( $data );
} elseif ( $data instanceof LP_User_Item ) {
$item_id = $data->get_id();
}
$item = false;
$item_type = learn_press_get_post_type( $item_id );
switch ( $item_type ) {
case LP_LESSON_CPT:
$item = new LP_User_Item( $data );
break;
case LP_QUIZ_CPT:
$item = new LP_User_Item_Quiz( $data );
break;
default:
break;
}
return apply_filters( 'learn-press/user-item-object', $item, $data, $item_type );
}
/**
* Set graduation
*
* @param string $graduation .
*
* @return $this
*/
public function set_graduation( string $graduation ): LP_User_Item {
$this->_set_data( 'graduation', $graduation );
return $this;
}
/**
* Get graduation
*
* @param string $context
*
* @return string
*/
public function get_graduation( string $context = '' ): string {
$grade = $this->get_data( 'graduation', '' );
if ( ! $grade ) {
return '';
}
return $context == 'display' ? learn_press_course_grade_html( $grade, false ) : $grade;
}
/**
* Update data from memory to database.
*
* @updated 3.1.0
*
* @return bool|mixed
*/
public function update( $force = false, $wp_error = false ) {
$data = $this->get_mysql_data();
$data = apply_filters( 'learn-press/update-user-item-data', $data, $this->get_user_item_id() );
$where = array();
if ( $this->get_user_item_id() ) {
$where = array( 'user_item_id' => $this->get_user_item_id() );
}
$rs = learn_press_update_user_item_field( $data, $where );
// Clear cache first status
$this->get_status( 'status', true );
if ( $rs ) {
foreach ( (array) $rs as $k => $v ) {
$this->_set_data( $k, $v );
}
$this->_changes = array();
}
return $rs;
}
public function get_status_label( $status = '' ) {
$statuses = array(
LP_COURSE_ENROLLED => esc_html__( 'Enrolled', 'learnpress' ),
LP_COURSE_PURCHASED => esc_html__( 'Purchased', 'learnpress' ),
LP_ITEM_COMPLETED => esc_html__( 'Completed', 'learnpress' ),
LP_ITEM_STARTED => esc_html__( 'Started', 'learnpress' ),
LP_COURSE_FINISHED => esc_html__( 'Finished', 'learnpress' ),
);
if ( ! $status ) {
$status = $this->get_status();
}
return ! empty( $statuses[ $status ] ) ? $statuses[ $status ] : esc_html__( 'Not Enrolled', 'learnpress' );
}
/**
* Get time from user started to ended.
*
* @param string $context
*
* @return bool|int
*/
public function get_time_interval( $context = '' ) {
$start = $this->get_start_time();
$end = $this->get_end_time();
if ( ! $start instanceof LP_Datetime || ! $end instanceof LP_Datetime ) {
return false;
}
if ( $start->is_null() || $end->is_null() ) {
return false;
}
return $end->getTimestamp() - $start->getTimestamp();
}
/**
* Return true of item is completed/finished
*
* @param string $status
*
* @return bool
*/
public function is_completed( $status = 'completed' ) {
return $this->get_status() === $status;
}
/**
* Complete item
*
* @editor tungnx
* @modify 4.1.4.1 - should review to improve
* @version 4.0.1
*/
public function complete( $status = 'completed' ) {
try {
$this->set_end_time( time() );
$this->set_status( $status );
$this->update();
} catch ( Throwable $e ) {
error_log( __FUNCTION__ . ':' . $e->getMessage() );
return false;
}
return true;
}
/**
* Get post type of item.
*
* @return string
*/
public function get_post_type() {
return learn_press_get_post_type( $this->get_item_id() );
}
/**
* @return bool
*/
public function is_passed(): bool {
return LP_COURSE_GRADUATION_PASSED === $this->get_graduation();
}
/**
* @param int $decimal
*
* @return mixed|null
*/
public function get_percent_result( $decimal = 1 ) {
return apply_filters(
'learn-press/user/item-percent-result',
sprintf( '%s%', round( $this->get_result( 'result' ), $decimal ) ),
$this->get_user_id(),
$this->get_item_id()
);
}
public function offsetSet( $offset, $value ) {
_deprecated_function( __METHOD__, '4.2.3.5' );
// TODO: Implement offsetSet() method.
}
public function offsetGet( $offset ) {
_deprecated_function( __METHOD__, '4.2.3.5' );
if ( is_callable( array( $this, 'get_' . $offset ) ) ) {
return call_user_func( array( $this, 'get_' . $offset ) );
}
return false;
}
public function offsetUnset( $offset ) {
_deprecated_function( __METHOD__, '4.2.3.5' );
// TODO: Implement offsetUnset() method.
}
public function offsetExists( $offset ) {
_deprecated_function( __METHOD__, '4.2.3.5' );
// TODO: Implement offsetExists() method.
}
}