PluginProbe
LearnPress – WordPress LMS Plugin for Create and Sell Online Courses / 4.4.8
LearnPress – WordPress LMS Plugin for Create and Sell Online Courses v4.4.8
4.4.8 4.4.7 4.4.6 4.4.5 4.4.4 4.4.3 4.4.2 4.4.1 4.4.0 4.3.9.1 4.3.9 4.3.8 4.3.7 4.1.6.9 4.1.6.9.1 4.1.6.9.2 4.1.6.9.3 4.1.6.9.4 4.1.7 4.1.7.1 4.1.7.2 4.1.7.3 4.1.7.3.1 4.1.7.3.2 4.2.0 All 139 releases
← All changes | inc/background-process/abstract-lp-async-request.php +232 -232 4.3.84.4.8 View file →
@@ -1,232 +1,232 @@
1 -<?php
2 -
3 -/**
4 - * Abstract LP_Async_Request class.
5 - *
6 - * This class is used to create asynchronous requests in LearnPress.
7 - * It is recommended to use this class for tasks that can be processed in the background
8 - * Note: don't call too many times on a progress, it can cause server hang.
9 - * Should be considered when using
10 - *
11 - * @since 4.1.6.9.4
12 - * @version 1.0.2
13 - */
14 -abstract class LP_Async_Request {
15 - /**
16 - * Prefix
17 - * @var string
18 - */
19 - protected $prefix = 'lp';
20 -
21 - /**
22 - * Action
23 - * @var string
24 - */
25 - protected $action = 'async_request';
26 -
27 - /**
28 - * Identifier
29 - *
30 - * @var string
31 - */
32 - protected $identifier;
33 -
34 - /**
35 - * Constant identifier for a task that should be available to logged-in users
36 - */
37 - const LOGGED_IN = 1;
38 -
39 - /**
40 - * Constant identifier for a task that should be available to logged-out users
41 - */
42 - const LOGGED_OUT = 2;
43 -
44 - /**
45 - * Constant identifier for a task that should be available to all users regardless of auth status
46 - */
47 - const BOTH = 3;
48 -
49 - /**
50 - * Data
51 - *
52 - * (default value: array())
53 - *
54 - * @var array
55 - */
56 - protected $data = array();
57 -
58 - /**
59 - * Initiate new async request
60 - */
61 - public function __construct( $auth_level = self::BOTH ) {
62 - $this->identifier = $this->prefix . '_' . $this->action;
63 -
64 - //add_action( 'wp_ajax_' . $this->identifier, array( $this, 'maybe_handle' ) );
65 - //add_action( 'wp_ajax_nopriv_' . $this->identifier, array( $this, 'maybe_handle' ) );
66 -
67 - if ( $auth_level & self::LOGGED_IN ) {
68 - add_action( "admin_post_lp_async_$this->identifier", [ $this, 'maybe_handle' ] );
69 - }
70 - if ( $auth_level & self::LOGGED_OUT ) {
71 - add_action( "admin_post_nopriv_lp_async_$this->identifier", [ $this, 'maybe_handle' ] );
72 - }
73 - }
74 -
75 - /**
76 - * Set data used during the request
77 - *
78 - * @param array $data Data.
79 - *
80 - * @return $this
81 - */
82 - public function data( array $data ): LP_Async_Request {
83 - $this->data = $data;
84 -
85 - return $this;
86 - }
87 -
88 - /**
89 - * Dispatch the async request
90 - *
91 - * @return array|WP_Error
92 - */
93 - public function dispatch() {
94 - $url = esc_url_raw( $this->get_query_url() );
95 - $args = $this->get_post_args();
96 -
97 - return wp_remote_post( $url, $args );
98 - }
99 -
100 - /**
101 - * Get query URL
102 - *
103 - * @return string
104 - */
105 - protected function get_query_url(): string {
106 - if ( property_exists( $this, 'query_url' ) ) {
107 - return $this->query_url;
108 - }
109 -
110 - $url = admin_url( 'admin-post.php' );
111 - return apply_filters( $this->identifier . '/query_url', $url );
112 - }
113 -
114 - /**
115 - * Get post args
116 - *
117 - * @return array
118 - */
119 - protected function get_post_args(): array {
120 - $identifier = $this->identifier;
121 - $this->data['action'] = "lp_async_{$identifier}";
122 - $this->data['_nonce'] = $this->create_async_nonce();
123 -
124 - /**
125 - * Must set timeout to 0.01 to avoid blocking the request.
126 - * Don't change it, because it can make sever hang.
127 - */
128 - $args = array(
129 - 'timeout' => 0.01,
130 - 'blocking' => false,
131 - 'body' => $this->data,
132 - 'cookies' => $_COOKIE,
133 - 'sslverify' => is_ssl(),
134 - );
135 -
136 - /**
137 - * Filters the post arguments used during an async request.
138 - *
139 - * @param array $args
140 - */
141 - return apply_filters( $this->identifier . '_post_args', $args );
142 - }
143 -
144 - /**
145 - * Create nonce for async request
146 - *
147 - * @return false|string
148 - */
149 - protected function create_async_nonce() {
150 - $action = $this->get_nonce_action();
151 - $i = wp_nonce_tick();
152 -
153 - return substr( wp_hash( $i . $action . get_class( $this ), 'nonce' ), - 12, 10 );
154 - }
155 -
156 - /**
157 - * Verify that the correct nonce was used within the time limit.
158 - *
159 - * @param string $nonce
160 - *
161 - * @return bool
162 - */
163 - protected function verify_async_nonce( string $nonce ): bool {
164 - $action = $this->get_nonce_action();
165 - $i = wp_nonce_tick();
166 -
167 - // Nonce generated 0-12 hours ago
168 - if ( substr( wp_hash( $i . $action . get_class( $this ), 'nonce' ), - 12, 10 ) == $nonce ) {
169 - return 1;
170 - }
171 -
172 - // Nonce generated 12-24 hours ago
173 - if ( substr( wp_hash( ( $i - 1 ) . $action . get_class( $this ), 'nonce' ), - 12, 10 ) == $nonce ) {
174 - return 2;
175 - }
176 -
177 - // Invalid nonce
178 - return false;
179 - }
180 -
181 - /**
182 - * Get a nonce action based on the $action property of the class
183 - *
184 - * @return string The nonce action for the current instance
185 - */
186 - protected function get_nonce_action(): string {
187 - $action = $this->identifier;
188 - if ( substr( $action, 0, 7 ) === 'nopriv_' ) {
189 - $action = substr( $action, 7 );
190 - }
191 -
192 - return "lp_async_$action";
193 - }
194 -
195 - /**
196 - * Maybe handle
197 - *
198 - * Check for correct nonce and pass to handler.
199 - */
200 - public function maybe_handle() {
201 - // Don't lock up other requests while processing
202 - session_write_close();
203 -
204 - /**
205 - * set params $_POST['lp_no_check_referer'] = 1
206 - * for case: send request when user not login, but get request when user logged
207 - * @editor tungnx
208 - * @modify 4.1.4
209 - */
210 - /*if ( ! isset( $_POST['lp_no_check_referer'] ) ) {
211 - check_ajax_referer( $this->identifier, 'nonce' );
212 - }*/
213 -
214 - if ( isset( $_POST['_nonce'] ) && $this->verify_async_nonce( $_POST['_nonce'] ) ) {
215 - if ( ! is_user_logged_in() ) {
216 - $this->identifier = "nopriv_$this->identifier";
217 - }
218 -
219 - $this->handle();
220 - }
221 -
222 - wp_die();
223 - }
224 -
225 - /**
226 - * Handle
227 - *
228 - * Override this method to perform any actions required
229 - * during the async request.
230 - */
231 - abstract protected function handle();
232 -}
1 +<?php
2 +
3 +/**
4 + * Abstract LP_Async_Request class.
5 + *
6 + * This class is used to create asynchronous requests in LearnPress.
7 + * It is recommended to use this class for tasks that can be processed in the background
8 + * Note: don't call too many times on a progress, it can cause server hang.
9 + * Should be considered when using
10 + *
11 + * @since 4.1.6.9.4
12 + * @version 1.0.2
13 + */
14 +abstract class LP_Async_Request {
15 + /**
16 + * Prefix
17 + * @var string
18 + */
19 + protected $prefix = 'lp';
20 +
21 + /**
22 + * Action
23 + * @var string
24 + */
25 + protected $action = 'async_request';
26 +
27 + /**
28 + * Identifier
29 + *
30 + * @var string
31 + */
32 + protected $identifier;
33 +
34 + /**
35 + * Constant identifier for a task that should be available to logged-in users
36 + */
37 + const LOGGED_IN = 1;
38 +
39 + /**
40 + * Constant identifier for a task that should be available to logged-out users
41 + */
42 + const LOGGED_OUT = 2;
43 +
44 + /**
45 + * Constant identifier for a task that should be available to all users regardless of auth status
46 + */
47 + const BOTH = 3;
48 +
49 + /**
50 + * Data
51 + *
52 + * (default value: array())
53 + *
54 + * @var array
55 + */
56 + protected $data = array();
57 +
58 + /**
59 + * Initiate new async request
60 + */
61 + public function __construct( $auth_level = self::BOTH ) {
62 + $this->identifier = $this->prefix . '_' . $this->action;
63 +
64 + //add_action( 'wp_ajax_' . $this->identifier, array( $this, 'maybe_handle' ) );
65 + //add_action( 'wp_ajax_nopriv_' . $this->identifier, array( $this, 'maybe_handle' ) );
66 +
67 + if ( $auth_level & self::LOGGED_IN ) {
68 + add_action( "admin_post_lp_async_$this->identifier", [ $this, 'maybe_handle' ] );
69 + }
70 + if ( $auth_level & self::LOGGED_OUT ) {
71 + add_action( "admin_post_nopriv_lp_async_$this->identifier", [ $this, 'maybe_handle' ] );
72 + }
73 + }
74 +
75 + /**
76 + * Set data used during the request
77 + *
78 + * @param array $data Data.
79 + *
80 + * @return $this
81 + */
82 + public function data( array $data ): LP_Async_Request {
83 + $this->data = $data;
84 +
85 + return $this;
86 + }
87 +
88 + /**
89 + * Dispatch the async request
90 + *
91 + * @return array|WP_Error
92 + */
93 + public function dispatch() {
94 + $url = esc_url_raw( $this->get_query_url() );
95 + $args = $this->get_post_args();
96 +
97 + return wp_remote_post( $url, $args );
98 + }
99 +
100 + /**
101 + * Get query URL
102 + *
103 + * @return string
104 + */
105 + protected function get_query_url(): string {
106 + if ( property_exists( $this, 'query_url' ) ) {
107 + return $this->query_url;
108 + }
109 +
110 + $url = admin_url( 'admin-post.php' );
111 + return apply_filters( $this->identifier . '/query_url', $url );
112 + }
113 +
114 + /**
115 + * Get post args
116 + *
117 + * @return array
118 + */
119 + protected function get_post_args(): array {
120 + $identifier = $this->identifier;
121 + $this->data['action'] = "lp_async_{$identifier}";
122 + $this->data['_nonce'] = $this->create_async_nonce();
123 +
124 + /**
125 + * Must set timeout to 0.01 to avoid blocking the request.
126 + * Don't change it, because it can make sever hang.
127 + */
128 + $args = array(
129 + 'timeout' => 0.01,
130 + 'blocking' => false,
131 + 'body' => $this->data,
132 + 'cookies' => $_COOKIE,
133 + 'sslverify' => is_ssl(),
134 + );
135 +
136 + /**
137 + * Filters the post arguments used during an async request.
138 + *
139 + * @param array $args
140 + */
141 + return apply_filters( $this->identifier . '_post_args', $args );
142 + }
143 +
144 + /**
145 + * Create nonce for async request
146 + *
147 + * @return false|string
148 + */
149 + protected function create_async_nonce() {
150 + $action = $this->get_nonce_action();
151 + $i = wp_nonce_tick();
152 +
153 + return substr( wp_hash( $i . $action . get_class( $this ), 'nonce' ), - 12, 10 );
154 + }
155 +
156 + /**
157 + * Verify that the correct nonce was used within the time limit.
158 + *
159 + * @param string $nonce
160 + *
161 + * @return bool
162 + */
163 + protected function verify_async_nonce( string $nonce ): bool {
164 + $action = $this->get_nonce_action();
165 + $i = wp_nonce_tick();
166 +
167 + // Nonce generated 0-12 hours ago
168 + if ( substr( wp_hash( $i . $action . get_class( $this ), 'nonce' ), - 12, 10 ) == $nonce ) {
169 + return 1;
170 + }
171 +
172 + // Nonce generated 12-24 hours ago
173 + if ( substr( wp_hash( ( $i - 1 ) . $action . get_class( $this ), 'nonce' ), - 12, 10 ) == $nonce ) {
174 + return 2;
175 + }
176 +
177 + // Invalid nonce
178 + return false;
179 + }
180 +
181 + /**
182 + * Get a nonce action based on the $action property of the class
183 + *
184 + * @return string The nonce action for the current instance
185 + */
186 + protected function get_nonce_action(): string {
187 + $action = $this->identifier;
188 + if ( substr( $action, 0, 7 ) === 'nopriv_' ) {
189 + $action = substr( $action, 7 );
190 + }
191 +
192 + return "lp_async_$action";
193 + }
194 +
195 + /**
196 + * Maybe handle
197 + *
198 + * Check for correct nonce and pass to handler.
199 + */
200 + public function maybe_handle() {
201 + // Don't lock up other requests while processing
202 + session_write_close();
203 +
204 + /**
205 + * set params $_POST['lp_no_check_referer'] = 1
206 + * for case: send request when user not login, but get request when user logged
207 + * @editor tungnx
208 + * @modify 4.1.4
209 + */
210 + /*if ( ! isset( $_POST['lp_no_check_referer'] ) ) {
211 + check_ajax_referer( $this->identifier, 'nonce' );
212 + }*/
213 +
214 + if ( isset( $_POST['_nonce'] ) && $this->verify_async_nonce( $_POST['_nonce'] ) ) {
215 + if ( ! is_user_logged_in() ) {
216 + $this->identifier = "nopriv_$this->identifier";
217 + }
218 +
219 + $this->handle();
220 + }
221 +
222 + wp_die();
223 + }
224 +
225 + /**
226 + * Handle
227 + *
228 + * Override this method to perform any actions required
229 + * during the async request.
230 + */
231 + abstract protected function handle();
232 +}