Version Description
= 4.0.0 = In this version, we have to change the database structure, so that if you have installed LP3 on your site before, please backup your site and follow these steps to upgrade.
= 0.9.19 = In this version, we have changed a little bit about LearnPress Plugin directory structure and moved all add-ons to become independent plugins. If you face any problems related to add-ons, please completely remove old version and re-install LearnPress. It does not affect your current data. Thank you.
Download this release
Release Info
Developer | ThimPress |
Plugin | LearnPress – WordPress LMS Plugin |
Version | 4.0.7-beta-1 |
Comparing to | |
See all releases |
Code changes from version 4.0.6 to 4.0.7-beta-1
- inc/background-process/class-lp-background-clear-temp-users.php +0 -62
- inc/background-process/class-lp-background-emailer.php +2 -4
- inc/background-process/class-lp-background-global.php +0 -75
- inc/background-process/class-lp-background-installer.php +12 -77
- inc/background-process/class-lp-background-query-items.php +2 -0
- inc/background-process/class-lp-background-schedule-items.php +0 -257
- inc/background-process/class-lp-background-sync-data.php +0 -68
- inc/class-lp-emails.php +9 -5
- inc/class-lp-repair-database.php +10 -6
- inc/curds/class-lp-course-curd.php +0 -16
- inc/databases/class-lp-user-items-db.php +43 -30
- inc/libraries/wp-async-request.php +30 -7
- inc/libraries/wp-background-process.php +39 -34
- inc/user-item/class-lp-user-item-course.php +14 -7
- inc/user-item/class-lp-user-item.php +0 -3
- inc/user/abstract-lp-user.php +0 -14
- inc/user/class-lp-user-factory.php +0 -20
- inc/user/lp-user-functions.php +60 -43
- learnpress.php +3 -95
- readme.txt +2 -2
- templates/content-quiz/js.php +10 -6
inc/background-process/class-lp-background-clear-temp-users.php
DELETED
@@ -1,62 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
defined( 'ABSPATH' ) || exit;
|
3 |
-
|
4 |
-
if ( ! class_exists( 'LP_Background_Clear_Temp_Users' ) ) {
|
5 |
-
/**
|
6 |
-
* Class LP_Background_Clear_Temp_Users
|
7 |
-
*
|
8 |
-
* @since 3.0.0
|
9 |
-
*/
|
10 |
-
class LP_Background_Clear_Temp_Users extends LP_Abstract_Background_Process {
|
11 |
-
|
12 |
-
/**
|
13 |
-
* @var int
|
14 |
-
*/
|
15 |
-
protected $queue_lock_time = 60;
|
16 |
-
|
17 |
-
/**
|
18 |
-
* @var string
|
19 |
-
*/
|
20 |
-
protected $action = 'lp_clear_temp_users';
|
21 |
-
|
22 |
-
/**
|
23 |
-
* @var string
|
24 |
-
*/
|
25 |
-
protected $transient_key = 'lp_schedule_clear_temp_users';
|
26 |
-
|
27 |
-
|
28 |
-
/**
|
29 |
-
* LP_Background_Clear_Temp_Users constructor.
|
30 |
-
*/
|
31 |
-
public function __construct() {
|
32 |
-
parent::__construct();
|
33 |
-
}
|
34 |
-
|
35 |
-
/**
|
36 |
-
* @param mixed $data
|
37 |
-
*
|
38 |
-
* @return bool
|
39 |
-
*/
|
40 |
-
protected function task( $data ) {
|
41 |
-
global $wpdb;
|
42 |
-
|
43 |
-
parent::task( $data );
|
44 |
-
|
45 |
-
if ( ! empty( $data['action'] ) && 'clear_temp_users' == $data['action'] ) {
|
46 |
-
$query = $wpdb->prepare(
|
47 |
-
"
|
48 |
-
DELETE a.*, b.*
|
49 |
-
FROM {$wpdb->prefix}learnpress_user_items a
|
50 |
-
INNER JOIN {$wpdb->prefix}learnpress_user_itemmeta b
|
51 |
-
WHERE a.user_item_id = b.learnpress_user_item_id
|
52 |
-
AND a.user_id = %d
|
53 |
-
",
|
54 |
-
$data['users']
|
55 |
-
);
|
56 |
-
$wpdb->query( $query );
|
57 |
-
}
|
58 |
-
|
59 |
-
return false;
|
60 |
-
}
|
61 |
-
}
|
62 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
inc/background-process/class-lp-background-emailer.php
CHANGED
@@ -4,13 +4,13 @@
|
|
4 |
*/
|
5 |
defined( 'ABSPATH' ) || exit;
|
6 |
|
7 |
-
if ( ! class_exists( '
|
8 |
/**
|
9 |
* Class LP_Background_Emailer
|
10 |
*
|
11 |
* @since 3.0.0
|
12 |
*/
|
13 |
-
class
|
14 |
|
15 |
/**
|
16 |
* @var string
|
@@ -49,5 +49,3 @@ if ( ! class_exists( 'LP_Background_Emailer' ) ) {
|
|
49 |
}
|
50 |
}
|
51 |
}
|
52 |
-
|
53 |
-
return LP_Background_Emailer::instance();
|
4 |
*/
|
5 |
defined( 'ABSPATH' ) || exit;
|
6 |
|
7 |
+
if ( ! class_exists( 'LP_Background_Email' ) ) {
|
8 |
/**
|
9 |
* Class LP_Background_Emailer
|
10 |
*
|
11 |
* @since 3.0.0
|
12 |
*/
|
13 |
+
class LP_Background_Email extends LP_Abstract_Background_Process {
|
14 |
|
15 |
/**
|
16 |
* @var string
|
49 |
}
|
50 |
}
|
51 |
}
|
|
|
|
inc/background-process/class-lp-background-global.php
DELETED
@@ -1,75 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
/**
|
3 |
-
* Send emails in background
|
4 |
-
*/
|
5 |
-
defined( 'ABSPATH' ) || exit;
|
6 |
-
|
7 |
-
if ( ! class_exists( 'LP_Background_Global' ) ) {
|
8 |
-
/**
|
9 |
-
* Class LP_Background_Global
|
10 |
-
*
|
11 |
-
* @since 3.0.0
|
12 |
-
*/
|
13 |
-
class LP_Background_Global extends LP_Abstract_Background_Process {
|
14 |
-
|
15 |
-
/**
|
16 |
-
* @var string
|
17 |
-
*/
|
18 |
-
protected $action = 'lp_background';
|
19 |
-
|
20 |
-
/**
|
21 |
-
* @var int
|
22 |
-
*/
|
23 |
-
protected $queue_lock_time = 60;
|
24 |
-
|
25 |
-
/**
|
26 |
-
* LP_Background_Global constructor.
|
27 |
-
*/
|
28 |
-
public function __construct() {
|
29 |
-
parent::__construct();
|
30 |
-
}
|
31 |
-
|
32 |
-
/**
|
33 |
-
* @param string $action
|
34 |
-
* @param array $args
|
35 |
-
* @param string $callback
|
36 |
-
*/
|
37 |
-
public static function add( $action, $args = array(), $callback = '' ) {
|
38 |
-
$item = array(
|
39 |
-
'action' => $action,
|
40 |
-
'callback' => $callback,
|
41 |
-
'args' => $args,
|
42 |
-
);
|
43 |
-
|
44 |
-
$instance = self::instance();
|
45 |
-
$instance->push_to_queue( $item );
|
46 |
-
}
|
47 |
-
|
48 |
-
/**
|
49 |
-
* @param mixed $callback
|
50 |
-
*
|
51 |
-
* @return bool
|
52 |
-
*/
|
53 |
-
protected function task( $callback ) {
|
54 |
-
parent::task( $callback );
|
55 |
-
|
56 |
-
if ( isset( $callback['action'] ) ) {
|
57 |
-
$args = isset( $callback['args'] ) ? $callback['args'] : array();
|
58 |
-
try {
|
59 |
-
|
60 |
-
if ( is_callable( $callback['callback'] ) ) {
|
61 |
-
call_user_func( $callback['callback'], $callback );
|
62 |
-
}
|
63 |
-
|
64 |
-
do_action( 'learn-press/background/' . $callback['action'], $callback );
|
65 |
-
} catch ( Exception $e ) {
|
66 |
-
|
67 |
-
}
|
68 |
-
}
|
69 |
-
|
70 |
-
return false;
|
71 |
-
}
|
72 |
-
}
|
73 |
-
}
|
74 |
-
|
75 |
-
return LP_Background_Global::instance();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
inc/background-process/class-lp-background-installer.php
CHANGED
@@ -1,4 +1,10 @@
|
|
1 |
<?php
|
|
|
|
|
|
|
|
|
|
|
|
|
2 |
defined( 'ABSPATH' ) || exit;
|
3 |
|
4 |
if ( ! class_exists( 'LP_Background_Installer' ) ) {
|
@@ -7,55 +13,12 @@ if ( ! class_exists( 'LP_Background_Installer' ) ) {
|
|
7 |
*
|
8 |
* @since 3.0.0
|
9 |
*/
|
10 |
-
class LP_Background_Installer
|
11 |
-
|
12 |
-
/**
|
13 |
-
* @var int
|
14 |
-
*/
|
15 |
-
|
16 |
-
/**
|
17 |
-
* @var string
|
18 |
-
*/
|
19 |
-
protected $action = 'lp_installer';
|
20 |
|
21 |
/**
|
22 |
* LP_Background_Installer constructor.
|
23 |
*/
|
24 |
public function __construct() {
|
25 |
-
parent::__construct();
|
26 |
-
|
27 |
-
if ( 'yes' !== get_option( 'learn_press_check_tables' ) ) {
|
28 |
-
add_action( 'wp_loaded', array( $this, 'check' ), 100 );
|
29 |
-
}
|
30 |
-
}
|
31 |
-
|
32 |
-
public function check() {
|
33 |
-
$this->push_to_queue(
|
34 |
-
array(
|
35 |
-
'check_tables' => 'yes',
|
36 |
-
)
|
37 |
-
)->save()->dispatch();
|
38 |
-
}
|
39 |
-
|
40 |
-
/**
|
41 |
-
* @param mixed $data
|
42 |
-
*
|
43 |
-
* @return bool
|
44 |
-
*/
|
45 |
-
protected function task( $data ) {
|
46 |
-
parent::task( $data );
|
47 |
-
|
48 |
-
if ( ! isset( $data['check_tables'] ) ) {
|
49 |
-
return false;
|
50 |
-
}
|
51 |
-
|
52 |
-
LP_Install::create_tables();
|
53 |
-
|
54 |
-
if ( ! $this->get_missing_tables() ) {
|
55 |
-
update_option( 'learn_press_check_tables', 'yes', 'yes' );
|
56 |
-
}
|
57 |
-
|
58 |
-
return false;
|
59 |
}
|
60 |
|
61 |
/**
|
@@ -63,45 +26,17 @@ if ( ! class_exists( 'LP_Background_Installer' ) ) {
|
|
63 |
*
|
64 |
* @return array
|
65 |
*/
|
66 |
-
protected function
|
67 |
-
global $wpdb;
|
68 |
-
$query = $wpdb->prepare(
|
69 |
-
'
|
70 |
-
SHOW TABLES LIKE %s
|
71 |
-
',
|
72 |
-
'%' . $wpdb->esc_like( 'learnpress' ) . '%'
|
73 |
-
);
|
74 |
-
|
75 |
-
$tables = $wpdb->get_col( $query );
|
76 |
-
|
77 |
-
$required_tables = get_object_vars( $wpdb );
|
78 |
-
$required_tables = array_filter( $required_tables, array( $this, '_filter_tables' ) );
|
79 |
-
|
80 |
-
return array_diff( $required_tables, $tables );
|
81 |
}
|
82 |
|
83 |
/**
|
84 |
-
*
|
85 |
*
|
86 |
-
* @
|
87 |
-
*
|
88 |
-
* @param string $prop
|
89 |
-
*
|
90 |
-
* @return bool
|
91 |
*/
|
92 |
-
protected function
|
93 |
-
global $wpdb;
|
94 |
|
95 |
-
return is_string( $prop ) && strpos( $prop, $wpdb->prefix . 'learnpress' ) === 0;
|
96 |
-
}
|
97 |
-
|
98 |
-
/**
|
99 |
-
* @return LP_Background_Installer
|
100 |
-
*/
|
101 |
-
public static function instance() {
|
102 |
-
return parent::instance();
|
103 |
}
|
104 |
}
|
105 |
}
|
106 |
-
|
107 |
-
return LP_Background_Installer::instance();
|
1 |
<?php
|
2 |
+
/**
|
3 |
+
* class LP_Background_Installer
|
4 |
+
*
|
5 |
+
* @since 4.0.7
|
6 |
+
* @author tungnx
|
7 |
+
*/
|
8 |
defined( 'ABSPATH' ) || exit;
|
9 |
|
10 |
if ( ! class_exists( 'LP_Background_Installer' ) ) {
|
13 |
*
|
14 |
* @since 3.0.0
|
15 |
*/
|
16 |
+
class LP_Background_Installer {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
17 |
|
18 |
/**
|
19 |
* LP_Background_Installer constructor.
|
20 |
*/
|
21 |
public function __construct() {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
22 |
}
|
23 |
|
24 |
/**
|
26 |
*
|
27 |
* @return array
|
28 |
*/
|
29 |
+
protected function get_tables_missing() {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
30 |
}
|
31 |
|
32 |
/**
|
33 |
+
* Get tables must have on this version of LP
|
34 |
*
|
35 |
+
* @since 4.0.7
|
36 |
+
* @author tungnx
|
|
|
|
|
|
|
37 |
*/
|
38 |
+
protected function get_tables_require() {
|
|
|
39 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
40 |
}
|
41 |
}
|
42 |
}
|
|
|
|
inc/background-process/class-lp-background-query-items.php
CHANGED
@@ -19,6 +19,8 @@ if ( ! class_exists( 'LP_Background_Query_Items' ) ) {
|
|
19 |
*/
|
20 |
protected $queue_lock_time = 3600;
|
21 |
|
|
|
|
|
22 |
/**
|
23 |
* @var float|int
|
24 |
*/
|
19 |
*/
|
20 |
protected $queue_lock_time = 3600;
|
21 |
|
22 |
+
protected $cron_interval = 60 * 24; // minutes
|
23 |
+
|
24 |
/**
|
25 |
* @var float|int
|
26 |
*/
|
inc/background-process/class-lp-background-schedule-items.php
DELETED
@@ -1,257 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
defined( 'ABSPATH' ) || exit;
|
3 |
-
|
4 |
-
if ( ! class_exists( 'LP_Background_Schedule_Items' ) ) {
|
5 |
-
/**
|
6 |
-
* Class LP_Background_Schedule_Items
|
7 |
-
*
|
8 |
-
* @since 3.0.0
|
9 |
-
*/
|
10 |
-
class LP_Background_Schedule_Items extends LP_Abstract_Background_Process {
|
11 |
-
|
12 |
-
/**
|
13 |
-
* @var int
|
14 |
-
*/
|
15 |
-
protected $queue_lock_time = 60;
|
16 |
-
|
17 |
-
/**
|
18 |
-
* @var string
|
19 |
-
*/
|
20 |
-
protected $action = 'schedule_items';
|
21 |
-
|
22 |
-
/**
|
23 |
-
* @var string
|
24 |
-
*/
|
25 |
-
protected $transient_key = 'lp_schedule_complete_items';
|
26 |
-
|
27 |
-
|
28 |
-
/**
|
29 |
-
* LP_Background_Schedule_Items constructor.
|
30 |
-
*/
|
31 |
-
public function __construct() {
|
32 |
-
parent::__construct();
|
33 |
-
|
34 |
-
add_action( 'learn_press_schedule_items', array( $this, 'xxx' ) );
|
35 |
-
|
36 |
-
}
|
37 |
-
|
38 |
-
public function xxx() {
|
39 |
-
$this->run();
|
40 |
-
|
41 |
-
$t = date( 'H.i.s' );
|
42 |
-
sleep( 15 );
|
43 |
-
}
|
44 |
-
|
45 |
-
public function cron_schedules( $schedules ) {
|
46 |
-
$schedules['lp_cron_schedule'] = array(
|
47 |
-
'interval' => 15,
|
48 |
-
'display' => __( 'Every 3 Minutes', 'learnpress' ),
|
49 |
-
);
|
50 |
-
|
51 |
-
return $schedules;
|
52 |
-
}
|
53 |
-
|
54 |
-
/**
|
55 |
-
* Run
|
56 |
-
*/
|
57 |
-
public function run() {
|
58 |
-
if ( ! $this->has_queued() ) {
|
59 |
-
$this->push_to_queue(
|
60 |
-
array( 'x' => 100 )
|
61 |
-
)->save()->dispatch();
|
62 |
-
} else {
|
63 |
-
$this->dispatch();
|
64 |
-
}
|
65 |
-
}
|
66 |
-
|
67 |
-
/**
|
68 |
-
* Update user-item status.
|
69 |
-
* This function called in background by schedule event.
|
70 |
-
*
|
71 |
-
* @param mixed $data
|
72 |
-
*
|
73 |
-
* @editor tungnx
|
74 |
-
* @reason not use
|
75 |
-
*
|
76 |
-
* @return bool
|
77 |
-
* @since 3.3.0
|
78 |
-
*
|
79 |
-
*/
|
80 |
-
/*protected function task( $data ) {
|
81 |
-
|
82 |
-
$settings = LP_Settings::instance();
|
83 |
-
|
84 |
-
// If option auto finish course is turn off.
|
85 |
-
if ( 'yes' !== $settings->get( 'auto_finish_course', 'yes' ) ) {
|
86 |
-
die();
|
87 |
-
}
|
88 |
-
|
89 |
-
$curd = new LP_User_CURD();
|
90 |
-
|
91 |
-
// Get all courses in user-items are in-progress but has expired
|
92 |
-
$course_items = $curd->get_courses(
|
93 |
-
array(
|
94 |
-
'status' => 'in-progress',
|
95 |
-
'expired' => true,
|
96 |
-
'paginate' => false,
|
97 |
-
'no_join_users' => true,
|
98 |
-
'limit' => 100,
|
99 |
-
)
|
100 |
-
);
|
101 |
-
|
102 |
-
if ( ! $course_items ) {
|
103 |
-
die();
|
104 |
-
}
|
105 |
-
|
106 |
-
// Force auto completing course items if turn on.
|
107 |
-
$complete_items = 'yes' === $settings->get( 'force_complete_course_items', 'yes' );
|
108 |
-
|
109 |
-
// Cron-job auto finish course when expiration time (nhamdv).
|
110 |
-
foreach ( $course_items as $course_item ) {
|
111 |
-
$user = learn_press_get_user( $course_item->user_id );
|
112 |
-
$course_data = $user->get_course_data( $course_item->course_id );
|
113 |
-
|
114 |
-
$finished = $course_data->finish( $complete_items );
|
115 |
-
|
116 |
-
learn_press_update_user_item_meta( $finished, 'finishing_type', 'exceeded' );
|
117 |
-
}
|
118 |
-
|
119 |
-
return false;
|
120 |
-
}*/
|
121 |
-
|
122 |
-
/**
|
123 |
-
* Get the items.
|
124 |
-
*
|
125 |
-
* @return array|bool
|
126 |
-
*/
|
127 |
-
protected function _get_items() {
|
128 |
-
global $wpdb;
|
129 |
-
$queued_items = get_transient( $this->transient_key );
|
130 |
-
$queued_course_ids = $queued_items ? array_keys( $queued_items ) : false;
|
131 |
-
$queued_course_ids = array_unique( $queued_course_ids );
|
132 |
-
$exclude_items = $queued_course_ids ? 'AND user_item_id NOT IN(' . join( ',',
|
133 |
-
$queued_course_ids ) . ')' : '';
|
134 |
-
|
135 |
-
$null_time = '0000-00-00 00:00:00';
|
136 |
-
$query = $wpdb->prepare(
|
137 |
-
"
|
138 |
-
SELECT user_item_id, user_id
|
139 |
-
FROM {$wpdb->learnpress_user_items}
|
140 |
-
WHERE item_type = %s
|
141 |
-
AND ( end_time IS NULL OR end_time = %s OR status <> %s )
|
142 |
-
{$exclude_items}
|
143 |
-
LIMIT 0, 1
|
144 |
-
",
|
145 |
-
LP_COURSE_CPT,
|
146 |
-
$null_time,
|
147 |
-
'finished'
|
148 |
-
);
|
149 |
-
|
150 |
-
$item_courses = $wpdb->get_results( $query );
|
151 |
-
|
152 |
-
if ( ! $item_courses ) {
|
153 |
-
return false;
|
154 |
-
}
|
155 |
-
|
156 |
-
if ( ! $queued_items ) {
|
157 |
-
$queued_items = array();
|
158 |
-
}
|
159 |
-
|
160 |
-
$course_item_types = learn_press_get_course_item_types();
|
161 |
-
$format = array_fill( 0, sizeof( $course_item_types ), '%s' );
|
162 |
-
$args = $course_item_types;
|
163 |
-
$new_items = array();
|
164 |
-
|
165 |
-
die();
|
166 |
-
|
167 |
-
foreach ( $item_courses as $item_course ) {
|
168 |
-
$new_items[ $item_course->user_item_id ] = array();
|
169 |
-
|
170 |
-
$args['end_time'] = $null_time;
|
171 |
-
$args['status'] = 'completed';
|
172 |
-
$args['parent'] = $item_course->user_item_id;
|
173 |
-
$query = $wpdb->prepare(
|
174 |
-
"
|
175 |
-
SELECT user_item_id
|
176 |
-
FROM {$wpdb->learnpress_user_items}
|
177 |
-
WHERE item_type IN(" . join( ',', $format ) . ')
|
178 |
-
AND ( end_time IS NULL OR end_time = %s OR status <> %s )
|
179 |
-
AND parent_id = %d
|
180 |
-
',
|
181 |
-
$args
|
182 |
-
);
|
183 |
-
|
184 |
-
$item_course_items = $wpdb->get_col( $query );
|
185 |
-
if ( $item_course_items ) {
|
186 |
-
$new_items[ $item_course->user_item_id ] = $item_course_items;
|
187 |
-
}
|
188 |
-
}
|
189 |
-
|
190 |
-
foreach ( $new_items as $user_item_id => $items ) {
|
191 |
-
if ( array_key_exists( $user_item_id, $queued_items ) ) {
|
192 |
-
$queued_items[ $user_item_id ] = array_merge( $queued_items[ $user_item_id ], $items );
|
193 |
-
} else {
|
194 |
-
$queued_items[ $user_item_id ] = $items;
|
195 |
-
}
|
196 |
-
}
|
197 |
-
|
198 |
-
set_transient( $this->transient_key, $queued_items );
|
199 |
-
|
200 |
-
return $new_items;
|
201 |
-
}
|
202 |
-
|
203 |
-
/**
|
204 |
-
* @param array $item
|
205 |
-
*/
|
206 |
-
protected function finish_course( $item ) {
|
207 |
-
|
208 |
-
$item_course = new LP_User_Item_Course( $item );
|
209 |
-
if ( ! $item_course ) {
|
210 |
-
return;
|
211 |
-
}
|
212 |
-
|
213 |
-
$user = $item_course->get_user();
|
214 |
-
if ( ! $user ) {
|
215 |
-
return;
|
216 |
-
}
|
217 |
-
|
218 |
-
}
|
219 |
-
|
220 |
-
/**
|
221 |
-
* @param array $item
|
222 |
-
*/
|
223 |
-
protected function complete_lesson( $item ) {
|
224 |
-
$item_course = new LP_User_Item_Course( $item );
|
225 |
-
|
226 |
-
if ( ! $item_course ) {
|
227 |
-
return;
|
228 |
-
}
|
229 |
-
|
230 |
-
$user = $item_course->get_user();
|
231 |
-
|
232 |
-
if ( $user ) {
|
233 |
-
return;
|
234 |
-
}
|
235 |
-
|
236 |
-
$user->finish_course( $item_course->get_item_id() );
|
237 |
-
}
|
238 |
-
|
239 |
-
/**
|
240 |
-
* Schedule fallback event.
|
241 |
-
*/
|
242 |
-
protected function schedule_event() {
|
243 |
-
if ( ! wp_next_scheduled( $this->cron_hook_identifier ) ) {
|
244 |
-
wp_schedule_event( time() + 10, $this->cron_interval_identifier, $this->cron_hook_identifier );
|
245 |
-
}
|
246 |
-
}
|
247 |
-
|
248 |
-
/**
|
249 |
-
* @return LP_Background_Schedule_Items
|
250 |
-
*/
|
251 |
-
public static function instance() {
|
252 |
-
return parent::instance();
|
253 |
-
}
|
254 |
-
}
|
255 |
-
}
|
256 |
-
|
257 |
-
return LP_Background_Schedule_Items::instance();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
inc/background-process/class-lp-background-sync-data.php
DELETED
@@ -1,68 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
if ( ! defined( 'ABSPATH' ) ) {
|
3 |
-
exit;
|
4 |
-
}
|
5 |
-
|
6 |
-
if ( ! class_exists( 'LP_Background_Sync_Data' ) ) {
|
7 |
-
/**
|
8 |
-
* Class LP_Background_Sync_Data
|
9 |
-
*
|
10 |
-
* @since 3.0.0
|
11 |
-
*/
|
12 |
-
class LP_Background_Sync_Data extends LP_Abstract_Background_Process {
|
13 |
-
|
14 |
-
/**
|
15 |
-
* @var int
|
16 |
-
*/
|
17 |
-
protected $queue_lock_time = 60;
|
18 |
-
|
19 |
-
/**
|
20 |
-
* @var string
|
21 |
-
*/
|
22 |
-
protected $action = 'lp_sync_data';
|
23 |
-
|
24 |
-
/**
|
25 |
-
* @var string
|
26 |
-
*/
|
27 |
-
protected $transient_key = 'lp_schedule_complete_items';
|
28 |
-
|
29 |
-
|
30 |
-
/**
|
31 |
-
* LP_Background_Sync_Data constructor.
|
32 |
-
*/
|
33 |
-
public function __construct() {
|
34 |
-
parent::__construct();
|
35 |
-
}
|
36 |
-
|
37 |
-
public function test() {
|
38 |
-
$this->task( 0 );
|
39 |
-
}
|
40 |
-
|
41 |
-
/**
|
42 |
-
* @param mixed $data
|
43 |
-
*
|
44 |
-
* @return bool
|
45 |
-
*/
|
46 |
-
protected function task( $data ) {
|
47 |
-
$queue_user_ids = get_option( $data['option_key'] );
|
48 |
-
|
49 |
-
if ( ! $queue_user_ids ) {
|
50 |
-
delete_option( $data['option_key'] );
|
51 |
-
delete_option( 'doing-sync-user-course-results' );
|
52 |
-
|
53 |
-
return false;
|
54 |
-
} else {
|
55 |
-
update_option( $data['option_key'], $queue_user_ids, 'no' );
|
56 |
-
}
|
57 |
-
|
58 |
-
return $data;
|
59 |
-
}
|
60 |
-
|
61 |
-
public function is_running() {
|
62 |
-
return false === $this->is_queue_empty();
|
63 |
-
}
|
64 |
-
|
65 |
-
}
|
66 |
-
}
|
67 |
-
|
68 |
-
return LP_Background_Sync_Data::instance();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
inc/class-lp-emails.php
CHANGED
@@ -182,18 +182,22 @@ if ( ! class_exists( 'LP_Emails' ) ) {
|
|
182 |
)
|
183 |
);
|
184 |
|
185 |
-
|
|
|
186 |
|
187 |
// self::$_background_emailer = new LP_Background_Emailer();
|
188 |
|
189 |
foreach ( $actions as $action ) {
|
190 |
-
add_action( $action, array( __CLASS__, 'queue_email' ), 10, 10 );
|
191 |
}
|
192 |
} else {
|
193 |
-
|
194 |
foreach ( $actions as $action ) {
|
195 |
add_action( $action, array( __CLASS__, 'send_email' ), 10, 10 );
|
196 |
}
|
|
|
|
|
|
|
|
|
197 |
}
|
198 |
|
199 |
self::instance();
|
@@ -204,13 +208,13 @@ if ( ! class_exists( 'LP_Emails' ) ) {
|
|
204 |
*
|
205 |
* @since 3.0.0
|
206 |
*/
|
207 |
-
public static function queue_email() {
|
208 |
$data_queue = array(
|
209 |
'filter' => current_filter(),
|
210 |
'args' => func_get_args(),
|
211 |
);
|
212 |
LP()->background( 'emailer' )->push_to_queue( $data_queue );
|
213 |
-
}
|
214 |
|
215 |
/**
|
216 |
* Send email notification.
|
182 |
)
|
183 |
);
|
184 |
|
185 |
+
//TODO: tungnx - rewrite background progess
|
186 |
+
/*if ( 'yes' === LP()->settings()->get( 'emails_general.send_email_background' ) ) {
|
187 |
|
188 |
// self::$_background_emailer = new LP_Background_Emailer();
|
189 |
|
190 |
foreach ( $actions as $action ) {
|
191 |
+
//add_action( $action, array( __CLASS__, 'queue_email' ), 10, 10 );
|
192 |
}
|
193 |
} else {
|
|
|
194 |
foreach ( $actions as $action ) {
|
195 |
add_action( $action, array( __CLASS__, 'send_email' ), 10, 10 );
|
196 |
}
|
197 |
+
}*/
|
198 |
+
|
199 |
+
foreach ( $actions as $action ) {
|
200 |
+
add_action( $action, array( __CLASS__, 'send_email' ), 10, 10 );
|
201 |
}
|
202 |
|
203 |
self::instance();
|
208 |
*
|
209 |
* @since 3.0.0
|
210 |
*/
|
211 |
+
/*public static function queue_email() {
|
212 |
$data_queue = array(
|
213 |
'filter' => current_filter(),
|
214 |
'args' => func_get_args(),
|
215 |
);
|
216 |
LP()->background( 'emailer' )->push_to_queue( $data_queue );
|
217 |
+
}*/
|
218 |
|
219 |
/**
|
220 |
* Send email notification.
|
inc/class-lp-repair-database.php
CHANGED
@@ -607,10 +607,11 @@ class LP_Repair_Database {
|
|
607 |
* Sync course data when saving post.
|
608 |
*
|
609 |
* @param int $course_id
|
610 |
-
*
|
|
|
611 |
* @since 3.1.0
|
612 |
*/
|
613 |
-
public function sync_course_data( $course_id ) {
|
614 |
$user_curd = new LP_User_CURD();
|
615 |
$course_curd = new LP_Course_CURD();
|
616 |
|
@@ -621,8 +622,6 @@ class LP_Repair_Database {
|
|
621 |
}
|
622 |
|
623 |
update_post_meta( $course_id, 'count_items', $count_items );
|
624 |
-
$this->queue_sync_user_course_results( $course_id );
|
625 |
-
|
626 |
}
|
627 |
|
628 |
/**
|
@@ -648,7 +647,12 @@ class LP_Repair_Database {
|
|
648 |
call_user_func( array( $this, $func ) );
|
649 |
}
|
650 |
|
651 |
-
|
|
|
|
|
|
|
|
|
|
|
652 |
global $wpdb;
|
653 |
$query = $wpdb->prepare(
|
654 |
"
|
@@ -693,7 +697,7 @@ class LP_Repair_Database {
|
|
693 |
update_option( 'doing-sync-user-course-results', 'yes' );
|
694 |
}
|
695 |
}
|
696 |
-
}
|
697 |
|
698 |
/**
|
699 |
* Sync orders for each course
|
607 |
* Sync course data when saving post.
|
608 |
*
|
609 |
* @param int $course_id
|
610 |
+
* @editor tungnx
|
611 |
+
* @version 3.1.1
|
612 |
* @since 3.1.0
|
613 |
*/
|
614 |
+
public function sync_course_data( int $course_id ) {
|
615 |
$user_curd = new LP_User_CURD();
|
616 |
$course_curd = new LP_Course_CURD();
|
617 |
|
622 |
}
|
623 |
|
624 |
update_post_meta( $course_id, 'count_items', $count_items );
|
|
|
|
|
625 |
}
|
626 |
|
627 |
/**
|
647 |
call_user_func( array( $this, $func ) );
|
648 |
}
|
649 |
|
650 |
+
/***
|
651 |
+
* @editor tungnx
|
652 |
+
* @deprecated 4.0.7
|
653 |
+
* @reason not use on LP4, make CPU run high.
|
654 |
+
*/
|
655 |
+
/*public function queue_sync_user_course_results( $course_id ) {
|
656 |
global $wpdb;
|
657 |
$query = $wpdb->prepare(
|
658 |
"
|
697 |
update_option( 'doing-sync-user-course-results', 'yes' );
|
698 |
}
|
699 |
}
|
700 |
+
}*/
|
701 |
|
702 |
/**
|
703 |
* Sync orders for each course
|
inc/curds/class-lp-course-curd.php
CHANGED
@@ -308,22 +308,6 @@ if ( ! class_exists( 'LP_Course_CURD' ) ) {
|
|
308 |
return $wpdb->get_col( $query );
|
309 |
}
|
310 |
|
311 |
-
/**
|
312 |
-
* @param int $course_id
|
313 |
-
*/
|
314 |
-
public function bg_update_items_format( $course_id ) {
|
315 |
-
if ( ! get_option( 'update_items_format_' . $course_id ) ) {
|
316 |
-
LP_Background_Global::add(
|
317 |
-
'update_items_format_' . $course_id,
|
318 |
-
array(
|
319 |
-
'course_id' => $course_id,
|
320 |
-
),
|
321 |
-
__CLASS__ . '::bg_update_items_format'
|
322 |
-
);
|
323 |
-
update_option( 'update_items_format_' . $course_id, 'yes' );
|
324 |
-
}
|
325 |
-
}
|
326 |
-
|
327 |
public static function update_items_format( $item ) {
|
328 |
|
329 |
if ( empty( $item['args']['course_id'] ) ) {
|
308 |
return $wpdb->get_col( $query );
|
309 |
}
|
310 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
311 |
public static function update_items_format( $item ) {
|
312 |
|
313 |
if ( empty( $item['args']['course_id'] ) ) {
|
inc/databases/class-lp-user-items-db.php
CHANGED
@@ -35,48 +35,61 @@ class LP_User_Items_DB extends LP_Database {
|
|
35 |
* @param int $user_id
|
36 |
*
|
37 |
* @return object
|
|
|
38 |
*/
|
39 |
public function get_course_items_by_user_item_id( $user_item_id_by_course_id = 0, $user_id = 0 ) {
|
40 |
if ( empty( $user_item_id_by_course_id ) || empty( $user_id ) ) {
|
41 |
return null;
|
42 |
}
|
43 |
|
44 |
-
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
|
|
|
|
52 |
);
|
53 |
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
SELECT * FROM {$this->tb_lp_user_items}
|
58 |
-
WHERE parent_id = %d
|
59 |
-
AND ref_type = %s
|
60 |
-
AND user_id = %d
|
61 |
-
",
|
62 |
-
$user_item_id_by_course_id,
|
63 |
-
LP_COURSE_CPT,
|
64 |
-
$user_id
|
65 |
-
);
|
66 |
-
|
67 |
-
$course_items = $this->wpdb->get_results( $query );
|
68 |
-
|
69 |
-
// Set cache .
|
70 |
-
wp_cache_set(
|
71 |
-
'lp-course-items-' . $user_id . '-' . $user_item_id_by_course_id,
|
72 |
-
$course_items,
|
73 |
-
'lp-user-course-items'
|
74 |
-
);
|
75 |
-
}
|
76 |
|
77 |
return $course_items;
|
78 |
}
|
79 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
80 |
/**
|
81 |
* Remove items' of course and user learned
|
82 |
*
|
35 |
* @param int $user_id
|
36 |
*
|
37 |
* @return object
|
38 |
+
* @throws Exception
|
39 |
*/
|
40 |
public function get_course_items_by_user_item_id( $user_item_id_by_course_id = 0, $user_id = 0 ) {
|
41 |
if ( empty( $user_item_id_by_course_id ) || empty( $user_id ) ) {
|
42 |
return null;
|
43 |
}
|
44 |
|
45 |
+
$query = $this->wpdb->prepare(
|
46 |
+
"
|
47 |
+
SELECT * FROM {$this->tb_lp_user_items}
|
48 |
+
WHERE parent_id = %d
|
49 |
+
AND ref_type = %s
|
50 |
+
AND user_id = %d
|
51 |
+
",
|
52 |
+
$user_item_id_by_course_id,
|
53 |
+
LP_COURSE_CPT,
|
54 |
+
$user_id
|
55 |
);
|
56 |
|
57 |
+
$course_items = $this->wpdb->get_results( $query );
|
58 |
+
|
59 |
+
$this->check_execute_has_error();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
60 |
|
61 |
return $course_items;
|
62 |
}
|
63 |
|
64 |
+
/**
|
65 |
+
* Get data user_items by course_id, quiz_id, user_id
|
66 |
+
*
|
67 |
+
* @param [type] $course_id
|
68 |
+
* @param [type] $item_id
|
69 |
+
* @param [type] $user_id
|
70 |
+
* @return array
|
71 |
+
*/
|
72 |
+
public function get_result_by_item_id( $course_id, $item_id, $user_id ) {
|
73 |
+
if ( empty( $course_id ) || empty( $item_id ) ) {
|
74 |
+
return false;
|
75 |
+
}
|
76 |
+
|
77 |
+
$query = $this->wpdb->prepare(
|
78 |
+
"SELECT * FROM {$this->tb_lp_user_items}
|
79 |
+
WHERE ref_id = %d
|
80 |
+
AND item_id = %d
|
81 |
+
AND user_id=%d
|
82 |
+
ORDER BY user_item_id DESC",
|
83 |
+
$course_id,
|
84 |
+
$item_id,
|
85 |
+
$user_id
|
86 |
+
);
|
87 |
+
|
88 |
+
$results = $this->wpdb->get_row( $query, ARRAY_A );
|
89 |
+
|
90 |
+
return $results;
|
91 |
+
}
|
92 |
+
|
93 |
/**
|
94 |
* Remove items' of course and user learned
|
95 |
*
|
inc/libraries/wp-async-request.php
CHANGED
@@ -1,12 +1,13 @@
|
|
1 |
<?php
|
2 |
-
|
3 |
-
|
4 |
-
|
|
|
|
|
5 |
|
6 |
/**
|
7 |
* Abstract WP_Async_Request class.
|
8 |
*
|
9 |
-
* @package WP-Background-Processing
|
10 |
* @abstract
|
11 |
*/
|
12 |
abstract class WP_Async_Request {
|
@@ -94,10 +95,17 @@ abstract class WP_Async_Request {
|
|
94 |
return $this->query_args;
|
95 |
}
|
96 |
|
97 |
-
|
98 |
'action' => $this->identifier,
|
99 |
'nonce' => wp_create_nonce( $this->identifier ),
|
100 |
);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
101 |
}
|
102 |
|
103 |
/**
|
@@ -110,7 +118,14 @@ abstract class WP_Async_Request {
|
|
110 |
return $this->query_url;
|
111 |
}
|
112 |
|
113 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
114 |
}
|
115 |
|
116 |
/**
|
@@ -123,13 +138,20 @@ abstract class WP_Async_Request {
|
|
123 |
return $this->post_args;
|
124 |
}
|
125 |
|
126 |
-
|
127 |
'timeout' => 0.01,
|
128 |
'blocking' => false,
|
129 |
'body' => $this->data,
|
130 |
'cookies' => $_COOKIE,
|
131 |
'sslverify' => apply_filters( 'https_local_ssl_verify', false ),
|
132 |
);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
133 |
}
|
134 |
|
135 |
/**
|
@@ -155,4 +177,5 @@ abstract class WP_Async_Request {
|
|
155 |
* during the async request.
|
156 |
*/
|
157 |
abstract protected function handle();
|
|
|
158 |
}
|
1 |
<?php
|
2 |
+
/**
|
3 |
+
* WP Async Request
|
4 |
+
*
|
5 |
+
* @package WP-Background-Processing
|
6 |
+
*/
|
7 |
|
8 |
/**
|
9 |
* Abstract WP_Async_Request class.
|
10 |
*
|
|
|
11 |
* @abstract
|
12 |
*/
|
13 |
abstract class WP_Async_Request {
|
95 |
return $this->query_args;
|
96 |
}
|
97 |
|
98 |
+
$args = array(
|
99 |
'action' => $this->identifier,
|
100 |
'nonce' => wp_create_nonce( $this->identifier ),
|
101 |
);
|
102 |
+
|
103 |
+
/**
|
104 |
+
* Filters the post arguments used during an async request.
|
105 |
+
*
|
106 |
+
* @param array $url
|
107 |
+
*/
|
108 |
+
return apply_filters( $this->identifier . '_query_args', $args );
|
109 |
}
|
110 |
|
111 |
/**
|
118 |
return $this->query_url;
|
119 |
}
|
120 |
|
121 |
+
$url = admin_url( 'admin-ajax.php' );
|
122 |
+
|
123 |
+
/**
|
124 |
+
* Filters the post arguments used during an async request.
|
125 |
+
*
|
126 |
+
* @param string $url
|
127 |
+
*/
|
128 |
+
return apply_filters( $this->identifier . '_query_url', $url );
|
129 |
}
|
130 |
|
131 |
/**
|
138 |
return $this->post_args;
|
139 |
}
|
140 |
|
141 |
+
$args = array(
|
142 |
'timeout' => 0.01,
|
143 |
'blocking' => false,
|
144 |
'body' => $this->data,
|
145 |
'cookies' => $_COOKIE,
|
146 |
'sslverify' => apply_filters( 'https_local_ssl_verify', false ),
|
147 |
);
|
148 |
+
|
149 |
+
/**
|
150 |
+
* Filters the post arguments used during an async request.
|
151 |
+
*
|
152 |
+
* @param array $args
|
153 |
+
*/
|
154 |
+
return apply_filters( $this->identifier . '_post_args', $args );
|
155 |
}
|
156 |
|
157 |
/**
|
177 |
* during the async request.
|
178 |
*/
|
179 |
abstract protected function handle();
|
180 |
+
|
181 |
}
|
inc/libraries/wp-background-process.php
CHANGED
@@ -1,13 +1,15 @@
|
|
1 |
<?php
|
2 |
-
|
3 |
-
|
4 |
-
|
|
|
|
|
|
|
5 |
|
6 |
/**
|
7 |
* Abstract WP_Background_Process class.
|
8 |
*
|
9 |
* @abstract
|
10 |
-
* @package WP-Background-Processing
|
11 |
* @extends WP_Async_Request
|
12 |
*/
|
13 |
abstract class WP_Background_Process extends WP_Async_Request {
|
@@ -106,7 +108,7 @@ abstract class WP_Background_Process extends WP_Async_Request {
|
|
106 |
/**
|
107 |
* Update queue
|
108 |
*
|
109 |
-
* @param string $key
|
110 |
* @param array $data Data.
|
111 |
*
|
112 |
* @return $this
|
@@ -270,18 +272,17 @@ abstract class WP_Background_Process extends WP_Async_Request {
|
|
270 |
$key = $wpdb->esc_like( $this->identifier . '_batch_' ) . '%';
|
271 |
|
272 |
$query = $wpdb->get_row( $wpdb->prepare( "
|
273 |
-
|
274 |
-
|
275 |
-
|
276 |
-
|
277 |
-
|
278 |
", $key ) );
|
279 |
-
|
280 |
-
|
281 |
-
|
282 |
-
|
283 |
-
|
284 |
-
}
|
285 |
return $batch;
|
286 |
}
|
287 |
|
@@ -296,20 +297,20 @@ abstract class WP_Background_Process extends WP_Async_Request {
|
|
296 |
|
297 |
do {
|
298 |
$batch = $this->get_batch();
|
299 |
-
|
300 |
-
|
301 |
-
|
302 |
-
|
303 |
-
|
304 |
-
|
305 |
-
|
306 |
-
|
307 |
-
|
308 |
-
|
309 |
-
|
310 |
-
|
311 |
-
|
312 |
-
|
313 |
}
|
314 |
|
315 |
// Update or delete current batch.
|
@@ -328,6 +329,8 @@ abstract class WP_Background_Process extends WP_Async_Request {
|
|
328 |
} else {
|
329 |
$this->complete();
|
330 |
}
|
|
|
|
|
331 |
}
|
332 |
|
333 |
/**
|
@@ -363,12 +366,12 @@ abstract class WP_Background_Process extends WP_Async_Request {
|
|
363 |
$memory_limit = '128M';
|
364 |
}
|
365 |
|
366 |
-
if ( ! $memory_limit || -1 === intval( $memory_limit ) ) {
|
367 |
// Unlimited, set to 32GB.
|
368 |
$memory_limit = '32000M';
|
369 |
}
|
370 |
|
371 |
-
return
|
372 |
}
|
373 |
|
374 |
/**
|
@@ -405,20 +408,22 @@ abstract class WP_Background_Process extends WP_Async_Request {
|
|
405 |
* Schedule cron healthcheck
|
406 |
*
|
407 |
* @access public
|
|
|
408 |
* @param mixed $schedules Schedules.
|
|
|
409 |
* @return mixed
|
410 |
*/
|
411 |
public function schedule_cron_healthcheck( $schedules ) {
|
412 |
$interval = apply_filters( $this->identifier . '_cron_interval', 5 );
|
413 |
|
414 |
if ( property_exists( $this, 'cron_interval' ) ) {
|
415 |
-
$interval = apply_filters( $this->identifier . '_cron_interval', $this->
|
416 |
}
|
417 |
|
418 |
// Adds every 5 minutes to the existing schedules.
|
419 |
$schedules[ $this->identifier . '_cron_interval' ] = array(
|
420 |
'interval' => MINUTE_IN_SECONDS * $interval,
|
421 |
-
'display' => sprintf( __( 'Every %d
|
422 |
);
|
423 |
|
424 |
return $schedules;
|
1 |
<?php
|
2 |
+
/**
|
3 |
+
* WP Background Process
|
4 |
+
*
|
5 |
+
* @package WP-Background-Processing
|
6 |
+
* @source https://github.com/deliciousbrains/wp-background-processing
|
7 |
+
*/
|
8 |
|
9 |
/**
|
10 |
* Abstract WP_Background_Process class.
|
11 |
*
|
12 |
* @abstract
|
|
|
13 |
* @extends WP_Async_Request
|
14 |
*/
|
15 |
abstract class WP_Background_Process extends WP_Async_Request {
|
108 |
/**
|
109 |
* Update queue
|
110 |
*
|
111 |
+
* @param string $key Key.
|
112 |
* @param array $data Data.
|
113 |
*
|
114 |
* @return $this
|
272 |
$key = $wpdb->esc_like( $this->identifier . '_batch_' ) . '%';
|
273 |
|
274 |
$query = $wpdb->get_row( $wpdb->prepare( "
|
275 |
+
SELECT *
|
276 |
+
FROM {$table}
|
277 |
+
WHERE {$column} LIKE %s
|
278 |
+
ORDER BY {$key_column} ASC
|
279 |
+
LIMIT 1
|
280 |
", $key ) );
|
281 |
+
|
282 |
+
$batch = new stdClass();
|
283 |
+
$batch->key = $query->$column;
|
284 |
+
$batch->data = maybe_unserialize( $query->$value_column );
|
285 |
+
|
|
|
286 |
return $batch;
|
287 |
}
|
288 |
|
297 |
|
298 |
do {
|
299 |
$batch = $this->get_batch();
|
300 |
+
|
301 |
+
foreach ( $batch->data as $key => $value ) {
|
302 |
+
$task = $this->task( $value );
|
303 |
+
|
304 |
+
if ( false !== $task ) {
|
305 |
+
$batch->data[ $key ] = $task;
|
306 |
+
} else {
|
307 |
+
unset( $batch->data[ $key ] );
|
308 |
+
}
|
309 |
+
|
310 |
+
if ( $this->time_exceeded() || $this->memory_exceeded() ) {
|
311 |
+
// Batch limits reached.
|
312 |
+
break;
|
313 |
+
}
|
314 |
}
|
315 |
|
316 |
// Update or delete current batch.
|
329 |
} else {
|
330 |
$this->complete();
|
331 |
}
|
332 |
+
|
333 |
+
wp_die();
|
334 |
}
|
335 |
|
336 |
/**
|
366 |
$memory_limit = '128M';
|
367 |
}
|
368 |
|
369 |
+
if ( ! $memory_limit || - 1 === intval( $memory_limit ) ) {
|
370 |
// Unlimited, set to 32GB.
|
371 |
$memory_limit = '32000M';
|
372 |
}
|
373 |
|
374 |
+
return wp_convert_hr_to_bytes( $memory_limit );
|
375 |
}
|
376 |
|
377 |
/**
|
408 |
* Schedule cron healthcheck
|
409 |
*
|
410 |
* @access public
|
411 |
+
*
|
412 |
* @param mixed $schedules Schedules.
|
413 |
+
*
|
414 |
* @return mixed
|
415 |
*/
|
416 |
public function schedule_cron_healthcheck( $schedules ) {
|
417 |
$interval = apply_filters( $this->identifier . '_cron_interval', 5 );
|
418 |
|
419 |
if ( property_exists( $this, 'cron_interval' ) ) {
|
420 |
+
$interval = apply_filters( $this->identifier . '_cron_interval', $this->cron_interval );
|
421 |
}
|
422 |
|
423 |
// Adds every 5 minutes to the existing schedules.
|
424 |
$schedules[ $this->identifier . '_cron_interval' ] = array(
|
425 |
'interval' => MINUTE_IN_SECONDS * $interval,
|
426 |
+
'display' => sprintf( __( 'Every %d Minutes' ), $interval ),
|
427 |
);
|
428 |
|
429 |
return $schedules;
|
inc/user-item/class-lp-user-item-course.php
CHANGED
@@ -123,12 +123,18 @@ class LP_User_Item_Course extends LP_User_Item implements ArrayAccess {
|
|
123 |
);
|
124 |
}
|
125 |
|
126 |
-
$
|
127 |
-
|
128 |
-
|
129 |
-
|
130 |
-
|
131 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
132 |
|
133 |
if ( $course_item ) {
|
134 |
$this->_items[ $item_id ] = $item_id;
|
@@ -138,6 +144,7 @@ class LP_User_Item_Course extends LP_User_Item implements ArrayAccess {
|
|
138 |
$items[ $item_id ] = $course_item;
|
139 |
}
|
140 |
}
|
|
|
141 |
LP_Object_Cache::set(
|
142 |
$this->get_user_id() . '-' . $this->get_id(),
|
143 |
$items,
|
@@ -181,7 +188,7 @@ class LP_User_Item_Course extends LP_User_Item implements ArrayAccess {
|
|
181 |
}
|
182 |
|
183 |
public function offsetGet( $offset ) {
|
184 |
-
$items = $this->read_items();
|
185 |
|
186 |
return $items && array_key_exists( $offset, $items ) ? $items[ $offset ] : false;
|
187 |
}
|
123 |
);
|
124 |
}
|
125 |
|
126 |
+
$item_type = learn_press_get_post_type( $item_id );
|
127 |
+
|
128 |
+
switch ( $item_type ) {
|
129 |
+
case LP_QUIZ_CPT:
|
130 |
+
$course_item = new LP_User_Item_Quiz( $user_course_item );
|
131 |
+
break;
|
132 |
+
case LP_LESSON_CPT:
|
133 |
+
$course_item = new LP_User_Item( $user_course_item );
|
134 |
+
break;
|
135 |
+
}
|
136 |
+
|
137 |
+
$course_item = apply_filters( 'learn-press/user-course-item', $course_item, $user_course_item, $this );
|
138 |
|
139 |
if ( $course_item ) {
|
140 |
$this->_items[ $item_id ] = $item_id;
|
144 |
$items[ $item_id ] = $course_item;
|
145 |
}
|
146 |
}
|
147 |
+
|
148 |
LP_Object_Cache::set(
|
149 |
$this->get_user_id() . '-' . $this->get_id(),
|
150 |
$items,
|
188 |
}
|
189 |
|
190 |
public function offsetGet( $offset ) {
|
191 |
+
$items = $this->read_items( true );
|
192 |
|
193 |
return $items && array_key_exists( $offset, $items ) ? $items[ $offset ] : false;
|
194 |
}
|
inc/user-item/class-lp-user-item.php
CHANGED
@@ -654,9 +654,6 @@ class LP_User_Item extends LP_Abstract_Object_Data implements ArrayAccess {
|
|
654 |
case LP_LESSON_CPT:
|
655 |
$item = new LP_User_Item( $data );
|
656 |
break;
|
657 |
-
case LP_QUIZ_CPT:
|
658 |
-
$item = new LP_User_Item_Quiz( $data );
|
659 |
-
break;
|
660 |
}
|
661 |
|
662 |
return apply_filters( 'learn-press/user-item-object', $item, $data, $item_type );
|
654 |
case LP_LESSON_CPT:
|
655 |
$item = new LP_User_Item( $data );
|
656 |
break;
|
|
|
|
|
|
|
657 |
}
|
658 |
|
659 |
return apply_filters( 'learn-press/user-item-object', $item, $data, $item_type );
|
inc/user/abstract-lp-user.php
CHANGED
@@ -663,20 +663,6 @@ if ( ! class_exists( 'LP_Abstract_User' ) ) {
|
|
663 |
}
|
664 |
|
665 |
return false;
|
666 |
-
$item = false;
|
667 |
-
if ( false !== ( $items = LP_Object_Cache::get(
|
668 |
-
'course-item-' . $this->get_id() . '-' . $course_id . '-' . $item_id,
|
669 |
-
'learn-press/user-course-items'
|
670 |
-
) ) ) {
|
671 |
-
// Only get status of a newest record.
|
672 |
-
if ( $last ) {
|
673 |
-
$item = reset( $items );
|
674 |
-
} else {
|
675 |
-
$item = $items;
|
676 |
-
}
|
677 |
-
}
|
678 |
-
|
679 |
-
return $item;
|
680 |
}
|
681 |
|
682 |
/**
|
663 |
}
|
664 |
|
665 |
return false;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
666 |
}
|
667 |
|
668 |
/**
|
inc/user/class-lp-user-factory.php
CHANGED
@@ -18,11 +18,6 @@ class LP_User_Factory {
|
|
18 |
|
19 |
public static $_deleted_users = array();
|
20 |
|
21 |
-
/**
|
22 |
-
* @var LP_Background_Clear_Temp_Users
|
23 |
-
*/
|
24 |
-
// protected static $_background_clear_users = null;
|
25 |
-
|
26 |
/**
|
27 |
*
|
28 |
*/
|
@@ -43,21 +38,6 @@ class LP_User_Factory {
|
|
43 |
add_action( 'learn-press/order/status-changed', array( __CLASS__, 'update_user_items' ), 10, 3 );
|
44 |
}
|
45 |
|
46 |
-
public static function clear_temp_users() {
|
47 |
-
global $wpdb;
|
48 |
-
|
49 |
-
$users = learn_press_get_temp_users();
|
50 |
-
|
51 |
-
if ( $users ) {
|
52 |
-
LP()->background( 'clear-temp-users' )->push_to_queue(
|
53 |
-
array(
|
54 |
-
'action' => 'clear_temp_users',
|
55 |
-
'users' => $users,
|
56 |
-
)
|
57 |
-
);
|
58 |
-
}
|
59 |
-
}
|
60 |
-
|
61 |
public static function update_user_items( $the_id, $old_status, $new_status ) {
|
62 |
$order = learn_press_get_order( $the_id );
|
63 |
|
18 |
|
19 |
public static $_deleted_users = array();
|
20 |
|
|
|
|
|
|
|
|
|
|
|
21 |
/**
|
22 |
*
|
23 |
*/
|
38 |
add_action( 'learn-press/order/status-changed', array( __CLASS__, 'update_user_items' ), 10, 3 );
|
39 |
}
|
40 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
41 |
public static function update_user_items( $the_id, $old_status, $new_status ) {
|
42 |
$order = learn_press_get_order( $the_id );
|
43 |
|
inc/user/lp-user-functions.php
CHANGED
@@ -442,12 +442,7 @@ add_action( 'register_form', 'learn_press_user_become_teacher_registration_form'
|
|
442 |
*
|
443 |
* @return mixed
|
444 |
*/
|
445 |
-
function learn_press_update_user_item_field(
|
446 |
-
$fields,
|
447 |
-
$where = false,
|
448 |
-
$update_cache = true,
|
449 |
-
$update_extra_fields_as_meta = false
|
450 |
-
) {
|
451 |
global $wpdb;
|
452 |
|
453 |
// Table fields
|
@@ -667,6 +662,7 @@ function learn_press_get_user_item( $where, $single = true ) {
|
|
667 |
SELECT *
|
668 |
FROM {$wpdb->prefix}learnpress_user_items
|
669 |
WHERE " . join( ' AND ', $where_str ) . '
|
|
|
670 |
',
|
671 |
$where
|
672 |
);
|
@@ -833,9 +829,9 @@ function _learn_press_update_updated_time_user_item_meta( $meta_id, $object_id,
|
|
833 |
|
834 |
/**
|
835 |
* @param $status
|
836 |
-
* @param int
|
837 |
-
* @param int
|
838 |
-
* @param int
|
839 |
*
|
840 |
* @return bool|mixed
|
841 |
*/
|
@@ -1051,7 +1047,7 @@ function learn_press_update_user_option( $name, $value, $id = 0 ) {
|
|
1051 |
|
1052 |
/**
|
1053 |
* @param $name
|
1054 |
-
* @param int
|
1055 |
*
|
1056 |
* @return bool
|
1057 |
*/
|
@@ -1073,7 +1069,7 @@ function learn_press_delete_user_option( $name, $id = 0 ) {
|
|
1073 |
|
1074 |
/**
|
1075 |
* @param $name
|
1076 |
-
* @param int
|
1077 |
*
|
1078 |
* @return bool
|
1079 |
*/
|
@@ -1531,12 +1527,12 @@ function learn_press_get_user_role( $user_id ) {
|
|
1531 |
function learn_press_create_user_item( $args = array(), $wp_error = false ) {
|
1532 |
global $wpdb;
|
1533 |
|
1534 |
-
$
|
1535 |
-
$defaults = array(
|
1536 |
'user_id' => get_current_user_id(),
|
1537 |
'item_id' => '',
|
1538 |
-
'start_time' =>
|
1539 |
'end_time' => '',
|
|
|
1540 |
'item_type' => '',
|
1541 |
'status' => '',
|
1542 |
'ref_id' => 0,
|
@@ -1545,10 +1541,10 @@ function learn_press_create_user_item( $args = array(), $wp_error = false ) {
|
|
1545 |
'create_meta' => array(),
|
1546 |
);
|
1547 |
|
1548 |
-
$
|
1549 |
|
1550 |
// Validate item_id and post type
|
1551 |
-
if ( empty( $
|
1552 |
if ( $wp_error ) {
|
1553 |
return new WP_Error( 'invalid_item_id', __( 'Invalid item id.', 'learnpress' ) );
|
1554 |
}
|
@@ -1556,32 +1552,32 @@ function learn_press_create_user_item( $args = array(), $wp_error = false ) {
|
|
1556 |
return 0;
|
1557 |
}
|
1558 |
|
1559 |
-
if ( empty( $
|
1560 |
-
$
|
1561 |
}
|
1562 |
|
1563 |
// Get id and type of ref if they are null
|
1564 |
-
if ( ! empty( $
|
1565 |
$parent = $wpdb->get_row(
|
1566 |
$wpdb->prepare(
|
1567 |
"SELECT * FROM {$wpdb->learnpress_user_items} WHERE %d",
|
1568 |
-
$
|
1569 |
)
|
1570 |
);
|
1571 |
|
1572 |
if ( $parent ) {
|
1573 |
-
if ( empty( $
|
1574 |
-
$
|
1575 |
}
|
1576 |
|
1577 |
-
if ( empty( $
|
1578 |
-
$
|
1579 |
}
|
1580 |
}
|
1581 |
}
|
1582 |
|
1583 |
// Filter
|
1584 |
-
if ( ! $
|
1585 |
if ( $wp_error ) {
|
1586 |
return new WP_Error( 'invalid_item_data', __( 'Invalid item data.', 'learnpress' ) );
|
1587 |
}
|
@@ -1589,17 +1585,17 @@ function learn_press_create_user_item( $args = array(), $wp_error = false ) {
|
|
1589 |
return 0;
|
1590 |
}
|
1591 |
|
1592 |
-
do_action( 'learn-press/before-create-user-item', $
|
1593 |
|
1594 |
-
$
|
1595 |
|
1596 |
-
if ( $
|
1597 |
-
unset( $
|
1598 |
}
|
1599 |
|
1600 |
-
$
|
1601 |
|
1602 |
-
$result = $
|
1603 |
|
1604 |
if ( ! $result || is_wp_error( $result ) ) {
|
1605 |
|
@@ -1610,22 +1606,22 @@ function learn_press_create_user_item( $args = array(), $wp_error = false ) {
|
|
1610 |
return 0;
|
1611 |
}
|
1612 |
|
1613 |
-
do_action( 'learn-press/created-user-item', $
|
1614 |
|
1615 |
-
$
|
1616 |
-
if ( ! $
|
1617 |
-
return $
|
1618 |
}
|
1619 |
|
1620 |
-
do_action( 'learn-press/before-create-user-item-meta', $
|
1621 |
|
1622 |
-
foreach ( $
|
1623 |
-
learn_press_update_user_item_meta( $
|
1624 |
}
|
1625 |
|
1626 |
-
do_action( 'learn-press/created-user-item-meta', $
|
1627 |
|
1628 |
-
return $
|
1629 |
}
|
1630 |
|
1631 |
/**
|
@@ -1640,9 +1636,10 @@ function learn_press_create_user_item_for_quiz( $args = array(), $wp_error = fal
|
|
1640 |
$item_data = wp_parse_args(
|
1641 |
$args,
|
1642 |
array(
|
1643 |
-
'item_type'
|
1644 |
-
'status'
|
1645 |
-
'
|
|
|
1646 |
)
|
1647 |
);
|
1648 |
|
@@ -1656,6 +1653,26 @@ function learn_press_create_user_item_for_quiz( $args = array(), $wp_error = fal
|
|
1656 |
return $user_item;
|
1657 |
}
|
1658 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1659 |
/**
|
1660 |
* Create new user item prepare for user starts a quiz
|
1661 |
* Update error retry course not work - Nhamdv.
|
442 |
*
|
443 |
* @return mixed
|
444 |
*/
|
445 |
+
function learn_press_update_user_item_field( $fields, $where = false, $update_cache = true, $update_extra_fields_as_meta = false ) {
|
|
|
|
|
|
|
|
|
|
|
446 |
global $wpdb;
|
447 |
|
448 |
// Table fields
|
662 |
SELECT *
|
663 |
FROM {$wpdb->prefix}learnpress_user_items
|
664 |
WHERE " . join( ' AND ', $where_str ) . '
|
665 |
+
ORDER BY user_item_id DESC
|
666 |
',
|
667 |
$where
|
668 |
);
|
829 |
|
830 |
/**
|
831 |
* @param $status
|
832 |
+
* @param int $quiz_id
|
833 |
+
* @param int $user_id
|
834 |
+
* @param int $course_id
|
835 |
*
|
836 |
* @return bool|mixed
|
837 |
*/
|
1047 |
|
1048 |
/**
|
1049 |
* @param $name
|
1050 |
+
* @param int $id
|
1051 |
*
|
1052 |
* @return bool
|
1053 |
*/
|
1069 |
|
1070 |
/**
|
1071 |
* @param $name
|
1072 |
+
* @param int $id
|
1073 |
*
|
1074 |
* @return bool
|
1075 |
*/
|
1527 |
function learn_press_create_user_item( $args = array(), $wp_error = false ) {
|
1528 |
global $wpdb;
|
1529 |
|
1530 |
+
$defaults = array(
|
|
|
1531 |
'user_id' => get_current_user_id(),
|
1532 |
'item_id' => '',
|
1533 |
+
'start_time' => current_time( 'mysql', true ),
|
1534 |
'end_time' => '',
|
1535 |
+
'graduation' => '',
|
1536 |
'item_type' => '',
|
1537 |
'status' => '',
|
1538 |
'ref_id' => 0,
|
1541 |
'create_meta' => array(),
|
1542 |
);
|
1543 |
|
1544 |
+
$item_data = wp_parse_args( $args, $defaults );
|
1545 |
|
1546 |
// Validate item_id and post type
|
1547 |
+
if ( empty( $item_data['item_id'] ) ) {
|
1548 |
if ( $wp_error ) {
|
1549 |
return new WP_Error( 'invalid_item_id', __( 'Invalid item id.', 'learnpress' ) );
|
1550 |
}
|
1552 |
return 0;
|
1553 |
}
|
1554 |
|
1555 |
+
if ( empty( $item_data['item_type'] ) && $post_type = learn_press_get_post_type( $item_data['item_id'] ) ) {
|
1556 |
+
$item_data['item_type'] = $post_type;
|
1557 |
}
|
1558 |
|
1559 |
// Get id and type of ref if they are null
|
1560 |
+
if ( ! empty( $item_data['parent_id'] ) && ( empty( $item_data['ref_id'] ) || ( empty( $item_data['ref_type'] ) ) ) ) {
|
1561 |
$parent = $wpdb->get_row(
|
1562 |
$wpdb->prepare(
|
1563 |
"SELECT * FROM {$wpdb->learnpress_user_items} WHERE %d",
|
1564 |
+
$item_data['parent_id']
|
1565 |
)
|
1566 |
);
|
1567 |
|
1568 |
if ( $parent ) {
|
1569 |
+
if ( empty( $item_data['ref_id'] ) ) {
|
1570 |
+
$item_data['ref_id'] = $parent->item_id;
|
1571 |
}
|
1572 |
|
1573 |
+
if ( empty( $item_data['ref_type'] ) ) {
|
1574 |
+
$item_data['ref_type'] = $parent->item_type;
|
1575 |
}
|
1576 |
}
|
1577 |
}
|
1578 |
|
1579 |
// Filter
|
1580 |
+
if ( ! $item_data = apply_filters( 'learn-press/create-user-item-data', $item_data ) ) {
|
1581 |
if ( $wp_error ) {
|
1582 |
return new WP_Error( 'invalid_item_data', __( 'Invalid item data.', 'learnpress' ) );
|
1583 |
}
|
1585 |
return 0;
|
1586 |
}
|
1587 |
|
1588 |
+
do_action( 'learn-press/before-create-user-item', $item_data );
|
1589 |
|
1590 |
+
$create_meta = ! empty( $item_data['create_meta'] ) ? $item_data['create_meta'] : false;
|
1591 |
|
1592 |
+
if ( $create_meta ) {
|
1593 |
+
unset( $item_data['create_meta'] );
|
1594 |
}
|
1595 |
|
1596 |
+
$user_item = new LP_User_Item( $item_data );
|
1597 |
|
1598 |
+
$result = $user_item->update( true, false );
|
1599 |
|
1600 |
if ( ! $result || is_wp_error( $result ) ) {
|
1601 |
|
1606 |
return 0;
|
1607 |
}
|
1608 |
|
1609 |
+
do_action( 'learn-press/created-user-item', $user_item, $item_data );
|
1610 |
|
1611 |
+
$create_meta = apply_filters( 'learn-press/create-user-item-meta', $create_meta, $item_data );
|
1612 |
+
if ( ! $create_meta ) {
|
1613 |
+
return $user_item;
|
1614 |
}
|
1615 |
|
1616 |
+
do_action( 'learn-press/before-create-user-item-meta', $create_meta );
|
1617 |
|
1618 |
+
foreach ( $create_meta as $key => $value ) {
|
1619 |
+
learn_press_update_user_item_meta( $user_item->get_user_item_id(), $key, $value );
|
1620 |
}
|
1621 |
|
1622 |
+
do_action( 'learn-press/created-user-item-meta', $user_item, $create_meta );
|
1623 |
|
1624 |
+
return $user_item;
|
1625 |
}
|
1626 |
|
1627 |
/**
|
1636 |
$item_data = wp_parse_args(
|
1637 |
$args,
|
1638 |
array(
|
1639 |
+
'item_type' => LP_QUIZ_CPT,
|
1640 |
+
'status' => 'started',
|
1641 |
+
'graduation' => 'in-progress',
|
1642 |
+
'user_id' => get_current_user_id(),
|
1643 |
)
|
1644 |
);
|
1645 |
|
1653 |
return $user_item;
|
1654 |
}
|
1655 |
|
1656 |
+
/**
|
1657 |
+
* Get list user_item_id for Quiz in table learnpress_user_items
|
1658 |
+
*
|
1659 |
+
* @param int $quiz_id
|
1660 |
+
* @param int $course_id
|
1661 |
+
* @return array || false
|
1662 |
+
*/
|
1663 |
+
function learn_press_isset_user_item_for_quiz( $quiz_id, $course_id ) {
|
1664 |
+
global $wpdb;
|
1665 |
+
|
1666 |
+
$query = $wpdb->prepare( "SELECT user_item_id FROM $wpdb->learnpress_user_items WHERE ref_id=%d AND item_id=%d", $course_id, $quiz_id );
|
1667 |
+
$col = $wpdb->get_col( $query );
|
1668 |
+
|
1669 |
+
if ( ! empty( $col ) ) {
|
1670 |
+
return $col;
|
1671 |
+
} else {
|
1672 |
+
return false;
|
1673 |
+
}
|
1674 |
+
}
|
1675 |
+
|
1676 |
/**
|
1677 |
* Create new user item prepare for user starts a quiz
|
1678 |
* Update error retry course not work - Nhamdv.
|
learnpress.php
CHANGED
@@ -4,7 +4,7 @@
|
|
4 |
* Plugin URI: http://thimpress.com/learnpress
|
5 |
* Description: LearnPress is a WordPress complete solution for creating a Learning Management System (LMS). It can help you to create courses, lessons and quizzes.
|
6 |
* Author: ThimPress
|
7 |
-
* Version: 4.0.
|
8 |
* Author URI: http://thimpress.com
|
9 |
* Requires at least: 3.8
|
10 |
* Tested up to: 5.7
|
@@ -172,75 +172,6 @@ if ( ! class_exists( 'LearnPress' ) ) {
|
|
172 |
}
|
173 |
}
|
174 |
|
175 |
-
public function init_background_processes() {
|
176 |
-
$supports = apply_filters(
|
177 |
-
'learn-press/background-processes',
|
178 |
-
array(
|
179 |
-
'emailer' => 'emailer',
|
180 |
-
'installer' => 'installer',
|
181 |
-
'query-items' => 'query-items',
|
182 |
-
'schedule-items' => 'schedule-items',
|
183 |
-
'global' => 'global',
|
184 |
-
'clear-temp-users' => 'clear-temp-users',
|
185 |
-
'sync-data' => 'sync-data',
|
186 |
-
)
|
187 |
-
);
|
188 |
-
|
189 |
-
foreach ( $supports as $name => $file ) {
|
190 |
-
if ( ! is_file( $file ) || ! file_exists( $file ) || preg_match( '~.php$~', $file ) ) {
|
191 |
-
$file = LP_PLUGIN_PATH . "/inc/background-process/class-lp-background-{$file}.php";
|
192 |
-
}
|
193 |
-
|
194 |
-
if ( file_exists( $file ) && is_readable( $file ) ) {
|
195 |
-
$this->backgrounds[ $name ] = include_once $file;
|
196 |
-
}
|
197 |
-
}
|
198 |
-
}
|
199 |
-
|
200 |
-
/**
|
201 |
-
* Add new task to a background process.
|
202 |
-
*
|
203 |
-
* @param mixed $data .
|
204 |
-
* @param string $background .
|
205 |
-
*
|
206 |
-
* @return LP_Abstract_Background_Process|bool
|
207 |
-
* @since 3.0.8
|
208 |
-
* @editor tungnx | comment this function
|
209 |
-
*/
|
210 |
-
/*public function add_background_task( $data, $background = 'global' ) {
|
211 |
-
if ( isset( $this->backgrounds[ $background ] ) ) {
|
212 |
-
$this->backgrounds[ $background ]->push_to_queue( $data );
|
213 |
-
|
214 |
-
return $this->backgrounds[ $background ];
|
215 |
-
}
|
216 |
-
|
217 |
-
return false;
|
218 |
-
}*/
|
219 |
-
|
220 |
-
/**
|
221 |
-
* Return a background instance.
|
222 |
-
*
|
223 |
-
* @param string $name
|
224 |
-
*
|
225 |
-
* @return LP_Abstract_Background_Process|bool
|
226 |
-
* @since 3.0.8
|
227 |
-
*/
|
228 |
-
public function background( $name ) {
|
229 |
-
if ( ! did_action( 'plugins_loaded' ) ) {
|
230 |
-
_doing_it_wrong(
|
231 |
-
__CLASS__ . '::' . __FUNCTION__,
|
232 |
-
'should call after \'plugins_loaded\' action',
|
233 |
-
'3.0.8'
|
234 |
-
);
|
235 |
-
}
|
236 |
-
|
237 |
-
if ( isset( $this->backgrounds[ $name ] ) ) {
|
238 |
-
return $this->backgrounds[ $name ];
|
239 |
-
}
|
240 |
-
|
241 |
-
return false;
|
242 |
-
}
|
243 |
-
|
244 |
/**
|
245 |
* Defines database table names.
|
246 |
*/
|
@@ -551,30 +482,8 @@ if ( ! class_exists( 'LearnPress' ) ) {
|
|
551 |
*/
|
552 |
public function on_deactivate() {
|
553 |
do_action( 'learn-press/deactivate', $this );
|
554 |
-
//$this->remove_cron();
|
555 |
}
|
556 |
|
557 |
-
/*protected function add_cron() {
|
558 |
-
add_filter( 'cron_schedules', array( $this, 'cron_schedules' ) );
|
559 |
-
|
560 |
-
if ( ! wp_next_scheduled( 'learn_press_schedule_items' ) ) {
|
561 |
-
wp_schedule_event( time(), 'lp_cron_schedule_items', 'learn_press_schedule_items' );
|
562 |
-
}
|
563 |
-
}*/
|
564 |
-
|
565 |
-
/*protected function remove_cron() {
|
566 |
-
wp_clear_scheduled_hook( 'learn_press_schedule_items' );
|
567 |
-
}*/
|
568 |
-
|
569 |
-
/*public function cron_schedules( $schedules ) {
|
570 |
-
$schedules['lp_cron_schedule_items'] = array(
|
571 |
-
'interval' => 15,
|
572 |
-
'display' => esc_html__( 'Every 3 Minutes', 'learnpress' ),
|
573 |
-
);
|
574 |
-
|
575 |
-
return $schedules;
|
576 |
-
}*/
|
577 |
-
|
578 |
/**
|
579 |
* Trigger WP loaded actions.
|
580 |
*
|
@@ -618,11 +527,10 @@ if ( ! class_exists( 'LearnPress' ) ) {
|
|
618 |
* @editor tungnx
|
619 |
*/
|
620 |
public function plugin_loaded() {
|
621 |
-
//$this->add_cron();
|
622 |
$this->init();
|
623 |
|
624 |
-
//
|
625 |
-
|
626 |
|
627 |
require_once 'inc/lp-template-hooks.php';
|
628 |
|
4 |
* Plugin URI: http://thimpress.com/learnpress
|
5 |
* Description: LearnPress is a WordPress complete solution for creating a Learning Management System (LMS). It can help you to create courses, lessons and quizzes.
|
6 |
* Author: ThimPress
|
7 |
+
* Version: 4.0.7-beta-1
|
8 |
* Author URI: http://thimpress.com
|
9 |
* Requires at least: 3.8
|
10 |
* Tested up to: 5.7
|
172 |
}
|
173 |
}
|
174 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
175 |
/**
|
176 |
* Defines database table names.
|
177 |
*/
|
482 |
*/
|
483 |
public function on_deactivate() {
|
484 |
do_action( 'learn-press/deactivate', $this );
|
|
|
485 |
}
|
486 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
487 |
/**
|
488 |
* Trigger WP loaded actions.
|
489 |
*
|
527 |
* @editor tungnx
|
528 |
*/
|
529 |
public function plugin_loaded() {
|
|
|
530 |
$this->init();
|
531 |
|
532 |
+
//Todo: tungnx - remove this code after handle ajax on page learn-press-addons
|
533 |
+
require_once 'inc/background-process/class-lp-background-query-items.php';
|
534 |
|
535 |
require_once 'inc/lp-template-hooks.php';
|
536 |
|
readme.txt
CHANGED
@@ -5,7 +5,7 @@ Tags: elearning, education, course, lms, learning management system
|
|
5 |
Requires at least: 5.6
|
6 |
Tested up to: 5.7
|
7 |
Requires PHP: 7.0
|
8 |
-
Stable tag: 4.0.
|
9 |
License: GPLv2 or later
|
10 |
License URI: https://www.gnu.org/licenses/gpl-2.0.html
|
11 |
|
@@ -204,7 +204,7 @@ https://www.transifex.com/projects/p/learnpress/
|
|
204 |
~ Fixed: show html title question
|
205 |
~ Fixed: Order change status from "completed" to "pending" => user can't learn courses in this order
|
206 |
~ Added: Option "Logout Redirect"
|
207 |
-
~ Fixed: Set default sidebar
|
208 |
~ Modify: Remove course on Overview tab when enable "Publish Profile"
|
209 |
~ Fixed: Elementor pro make archive course show wrong
|
210 |
|
5 |
Requires at least: 5.6
|
6 |
Tested up to: 5.7
|
7 |
Requires PHP: 7.0
|
8 |
+
Stable tag: 4.0.7-beta-1
|
9 |
License: GPLv2 or later
|
10 |
License URI: https://www.gnu.org/licenses/gpl-2.0.html
|
11 |
|
204 |
~ Fixed: show html title question
|
205 |
~ Fixed: Order change status from "completed" to "pending" => user can't learn courses in this order
|
206 |
~ Added: Option "Logout Redirect"
|
207 |
+
~ Fixed: Set default sidebar curriculum will be hide on mobile
|
208 |
~ Modify: Remove course on Overview tab when enable "Publish Profile"
|
209 |
~ Fixed: Elementor pro make archive course show wrong
|
210 |
|
templates/content-quiz/js.php
CHANGED
@@ -117,12 +117,16 @@ if ( $total_question ) :
|
|
117 |
<div id="learn-press-quiz-app"></div>
|
118 |
|
119 |
<script>
|
120 |
-
|
121 |
-
|
122 |
-
|
123 |
-
|
124 |
-
|
125 |
-
|
|
|
|
|
|
|
|
|
126 |
</script>
|
127 |
|
128 |
<?php
|
117 |
<div id="learn-press-quiz-app"></div>
|
118 |
|
119 |
<script>
|
120 |
+
document.addEventListener( 'DOMContentLoaded', () => {
|
121 |
+
if ( typeof LP !== 'undefined' ) {
|
122 |
+
LP.Hook.addAction('course-ready', () => {
|
123 |
+
LP.quiz.init(
|
124 |
+
'#learn-press-quiz-app',
|
125 |
+
<?php echo json_encode( $js ); ?>
|
126 |
+
)
|
127 |
+
});
|
128 |
+
}
|
129 |
+
});
|
130 |
</script>
|
131 |
|
132 |
<?php
|