Diff: STRATO-apps/wordpress_03/app/wp-content/plugins/tutor-pro/gift-course/GiftCourse.php
Keine Baseline-Datei – Diff nur gegen leer.
1
-
1
+
<?php
2
+
/**
3
+
* Handle Gift Course
4
+
*
5
+
* @package TutorPro\GiftCourse
6
+
* @author Themeum <support@themeum.com>
7
+
* @link https://themeum.com
8
+
* @since 3.8.0
9
+
*/
10
+
11
+
namespace TutorPro\GiftCourse;
12
+
13
+
use TUTOR\Course;
14
+
use Tutor\Helpers\DateTimeHelper;
15
+
use Tutor\Helpers\HttpHelper;
16
+
use TUTOR\Icon;
17
+
use TUTOR\Input;
18
+
use Tutor\Models\CourseModel;
19
+
use Tutor\Traits\JsonResponse;
20
+
use TUTOR_ENROLLMENTS\Enrollments;
21
+
22
+
if ( ! defined( 'ABSPATH' ) ) {
23
+
exit;
24
+
}
25
+
26
+
/**
27
+
* Class Course Coming Soon
28
+
*/
29
+
class GiftCourse {
30
+
31
+
use JsonResponse;
32
+
33
+
/**
34
+
* Store gift course details in this meta key.
35
+
*
36
+
* @since 3.8.0
37
+
*/
38
+
const GIFT_FLAG_META = 'tutor_gift';
39
+
const GIFT_DATA_META = 'tutor_gift_payload';
40
+
const GIFT_STATUS_META = 'tutor_gift_status';
41
+
42
+
/**
43
+
* Gift status
44
+
*
45
+
* @since 3.8.0
46
+
*/
47
+
const GIFT_STATUS_PROCESSING = 'processing';
48
+
const GIFT_STATUS_SCHEDULED = 'scheduled';
49
+
const GIFT_STATUS_SENT = 'sent';
50
+
const GIFT_STATUS_RECEIVED = 'received';
51
+
52
+
const GIFT_SENT_AT_META = 'tutor_gift_sent_at';
53
+
const GIFT_RECEIVED_AT_META = 'tutor_gift_received_at';
54
+
55
+
/**
56
+
* Register hooks.
57
+
*
58
+
* @since 3.3.0
59
+
*/
60
+
public function __construct() {
61
+
add_action( 'tutor_course/single/entry/after', array( $this, 'add_gift_this_course_button' ) );
62
+
add_action( 'tutor_before_dashboard_content', array( $this, 'gift_course_banner_template' ) );
63
+
add_action( 'tutor_cart_item_badge', array( $this, 'add_cart_item_gift_badge' ) );
64
+
add_action( 'wp_ajax_tutor_pro_gift_proceed_to_checkout', array( $this, 'ajax_gift_proceed_to_checkout' ) );
65
+
add_filter( 'tutor_enrollment_buttons', array( $this, 'filter_enrollment_buttons' ), 10, 3 );
66
+
}
67
+
68
+
/**
69
+
* Add gift this course button to the single course entry box.
70
+
*
71
+
* @since 3.8.0
72
+
*
73
+
* @param int $course_id the course id.
74
+
*
75
+
* @return void
76
+
*/
77
+
public function add_gift_this_course_button( $course_id ) {
78
+
if ( ! $this->can_gift_course( $course_id ) ) {
79
+
return;
80
+
}
81
+
82
+
?>
83
+
<button class="tutor-btn tutor-btn-primary tutor-btn-gift tutor-btn-lg tutor-btn-block tutor-my-12 <?php echo is_user_logged_in() ? '' : 'tutor-open-login-modal'; ?>" <?php echo is_user_logged_in() ? 'data-tutor-modal-target="tutor-gift-this-course-modal"' : ''; ?>>
84
+
<?php tutor_utils()->render_svg_icon( Icon::GIFT, 24, 24 ); ?>
85
+
<?php esc_html_e( 'Gift this Course', 'tutor-pro' ); ?>
86
+
</button>
87
+
<?php
88
+
89
+
if ( is_user_logged_in() ) {
90
+
tutor_load_template(
91
+
'single.course.gift-this-course-modal',
92
+
array( 'course_id' => $course_id ),
93
+
true
94
+
);
95
+
}
96
+
}
97
+
98
+
/**
99
+
* Add gift this course banner to the dashboard.
100
+
*
101
+
* @since 3.8.0
102
+
*
103
+
* @return void
104
+
*/
105
+
public function gift_course_banner_template() {
106
+
$user_id = get_current_user_id();
107
+
$gifts = $this->get_gift_courses( $user_id );
108
+
109
+
if ( tutor_utils()->count( $gifts ) ) {
110
+
foreach ( $gifts as $gift ) {
111
+
$reference_id = $gift->reference_id;
112
+
$payload = json_decode( $gift->payload );
113
+
$course_id = $payload->course_id;
114
+
if ( $this::can_open_gift( $gift ) ) {
115
+
tutor_load_template(
116
+
'dashboard.gift-course',
117
+
compact( 'reference_id', 'course_id' ),
118
+
true
119
+
);
120
+
}
121
+
}
122
+
}
123
+
}
124
+
125
+
/**
126
+
* Add gift badge to checkout course item
127
+
*
128
+
* @since 3.8.0
129
+
*
130
+
* @param object $course the course.
131
+
*
132
+
* @return void
133
+
*/
134
+
public function add_cart_item_gift_badge( $course ) {
135
+
if ( ! $this->is_gift_course_in_cart( $course->ID ) ) {
136
+
return;
137
+
}
138
+
139
+
?>
140
+
<span class="tutor-checkout-gift-course-badge">
141
+
<?php tutor_utils()->render_svg_icon( Icon::GIFT, 16, 16 ); ?>
142
+
<?php esc_html_e( 'Gift', 'tutor-pro' ); ?>
143
+
</span>
144
+
<?php
145
+
}
146
+
147
+
/**
148
+
* Process gift course form to proceed to checkout
149
+
*
150
+
* @since 3.8.0
151
+
*
152
+
* @return void send wp_json response
153
+
*/
154
+
public function ajax_gift_proceed_to_checkout() {
155
+
tutor_utils()->checking_nonce();
156
+
157
+
//phpcs:ignore
158
+
$gift_form_data = Input::sanitize_array( $_POST, array( 'message' => 'esc_textarea' ) );
159
+
$course_id = (int) $gift_form_data['course_id'];
160
+
161
+
if ( tutor_is_item_in_cart( $course_id ) ) {
162
+
$this->response_bad_request(
163
+
__( 'This course is already in your cart and cannot be gifted.', 'tutor-pro' )
164
+
);
165
+
}
166
+
167
+
$user = get_user_by( 'email', $gift_form_data['recipient_email'] );
168
+
if ( $user && tutor_utils()->is_enrolled( $course_id, $user->ID ) ) {
169
+
$this->response_bad_request(
170
+
__( 'The recipient is already enrolled in this course.', 'tutor-pro' )
171
+
);
172
+
}
173
+
174
+
$gift_data = (object) array(
175
+
'reference_id' => 'gift_' . bin2hex( random_bytes( 8 ) ),
176
+
'recipient_name' => $gift_form_data['recipient_name'],
177
+
'recipient_email' => $gift_form_data['recipient_email'],
178
+
'course_id' => $course_id,
179
+
'purchaser_id' => get_current_user_id(),
180
+
'course_title' => get_the_title( $course_id ),
181
+
'scheduled_at_gmt' => $gift_form_data['datetime'],
182
+
'message' => $gift_form_data['message'],
183
+
'notify_me' => (int) $gift_form_data['notify_me'],
184
+
);
185
+
186
+
$monetization = tutor_utils()->get_option( 'monetize_by' );
187
+
try {
188
+
$proceeder = GiftProceedFactory::get_proceeder( $monetization );
189
+
$checkout_url = $proceeder->proceed_to_checkout( $gift_data );
190
+
191
+
$this->json_response(
192
+
__( 'Success', 'tutor-pro' ),
193
+
array( 'url' => $checkout_url )
194
+
);
195
+
} catch ( \Throwable $th ) {
196
+
$this->json_response(
197
+
$th->getMessage(),
198
+
null,
199
+
HttpHelper::STATUS_BAD_REQUEST
200
+
);
201
+
}
202
+
}
203
+
204
+
/**
205
+
* Check whether this course is gift-able
206
+
*
207
+
* @since 3.8.0
208
+
*
209
+
* @param integer $course_id Course to check against a course.
210
+
*
211
+
* @return boolean
212
+
*/
213
+
public static function can_gift_course( int $course_id ): bool {
214
+
$course = get_post( $course_id );
215
+
216
+
// Show gift course button only for published courses.
217
+
if ( CourseModel::STATUS_PUBLISH !== $course->post_status ) {
218
+
return false;
219
+
}
220
+
221
+
// Handle free courses.
222
+
if ( ! tutor_utils()->is_course_purchasable( $course_id ) ) {
223
+
return false;
224
+
}
225
+
226
+
// Handle enrollment periods settings.
227
+
if ( tutor_utils()->is_addon_enabled( 'enrollments' ) ) {
228
+
$enrollment = new Enrollments();
229
+
list( $pause_enrollment, $course_enrollment_period, $enrollment_starts_at, $enrollment_ends_at ) = array_values( $enrollment->get_course_enrollment_settings( $course_id ) );
230
+
231
+
if ( 'yes' === $pause_enrollment ) {
232
+
return false;
233
+
}
234
+
235
+
if ( 'yes' === $course_enrollment_period ) {
236
+
if ( $enrollment_starts_at && time() < strtotime( $enrollment_starts_at ) ) {
237
+
return false;
238
+
}
239
+
240
+
if ( $enrollment_ends_at && time() > strtotime( $enrollment_ends_at ) ) {
241
+
return false;
242
+
}
243
+
}
244
+
}
245
+
246
+
// Handle enrollment booked coursed.
247
+
if ( tutor_utils()->is_course_fully_booked( $course_id ) ) {
248
+
return false;
249
+
}
250
+
251
+
// Handle course selling options.
252
+
$course_selling_option = Course::get_selling_option( $course_id );
253
+
if ( in_array( $course_selling_option, array( Course::SELLING_OPTION_SUBSCRIPTION, Course::SELLING_OPTION_MEMBERSHIP ), true ) ) {
254
+
return false;
255
+
}
256
+
257
+
return apply_filters( 'tutor_can_gift_course', true, $course_id );
258
+
}
259
+
260
+
/**
261
+
* Check if the items is for gift
262
+
*
263
+
* @since 3.8.0
264
+
*
265
+
* @param object|integer $item_id Order Item id or item object.
266
+
*
267
+
* @return object|boolean Item object if exist or false
268
+
*/
269
+
public static function is_gift_item( $item_id ) {
270
+
try {
271
+
$proceeder = self::get_gift_proceeder();
272
+
return $proceeder->is_gift_item( $item_id );
273
+
} catch ( \Throwable $th ) {
274
+
return false;
275
+
}
276
+
}
277
+
278
+
/**
279
+
* Get gift data by course id
280
+
*
281
+
* @since 3.8.0
282
+
*
283
+
* @param mixed $reference_id Gift reference id.
284
+
* @param bool $details Whether to return gift details or not.
285
+
*
286
+
* @return mixed false|object
287
+
*/
288
+
public static function get_gift_data_by_reference_id( $reference_id, $details = false ) {
289
+
$where = array(
290
+
'reference_id' => $reference_id,
291
+
);
292
+
293
+
$gift_data = ( new GiftScheduler() )->get( $where );
294
+
if ( ! $gift_data ) {
295
+
return false;
296
+
}
297
+
298
+
return $details ? $gift_data : json_decode( $gift_data->payload );
299
+
}
300
+
301
+
/**
302
+
* Get gift proceeder
303
+
*
304
+
* @since 3.8.0
305
+
*
306
+
* @throws \Throwable If failed to get proceeder.
307
+
*
308
+
* @return GiftProceeder
309
+
*/
310
+
public static function get_gift_proceeder() {
311
+
$monetization = tutor_utils()->get_option( 'monetize_by' );
312
+
try {
313
+
return GiftProceedFactory::get_proceeder( $monetization );
314
+
} catch ( \Throwable $th ) {
315
+
throw $th;
316
+
}
317
+
}
318
+
319
+
/**
320
+
* Can user open a gift
321
+
*
322
+
* @since 3.8.0
323
+
*
324
+
* @param object|int $gift_details Gift details or gift reference id.
325
+
*
326
+
* @return bool
327
+
*/
328
+
public static function can_open_gift( object $gift_details ): bool {
329
+
if ( is_int( $gift_details ) ) {
330
+
$gift_details = self::get_gift_data_by_reference_id( $gift_details, true );
331
+
}
332
+
333
+
if ( ! $gift_details ) {
334
+
return false;
335
+
}
336
+
337
+
$gift_data = json_decode( $gift_details->payload );
338
+
if ( ! $gift_data ) {
339
+
$error = json_last_error();
340
+
return false;
341
+
}
342
+
343
+
$user = wp_get_current_user();
344
+
if ( $gift_data->recipient_email !== $user->user_email ) {
345
+
return false;
346
+
}
347
+
348
+
$course_id = $gift_data->course_id;
349
+
$course = get_post( $course_id );
350
+
if ( ! $course || CourseModel::STATUS_PUBLISH !== $course->post_status ) {
351
+
return false;
352
+
}
353
+
354
+
if ( GiftScheduler::STATUS_PROCESSED !== $gift_details->status ) {
355
+
return false;
356
+
}
357
+
358
+
return true;
359
+
}
360
+
361
+
/**
362
+
* Get all gift courses of a user that is ready to claim
363
+
*
364
+
* @since 3.8.0
365
+
*
366
+
* @param integer $user_id User id to get gift courses.
367
+
*
368
+
* @return mixed
369
+
*/
370
+
public static function get_gift_courses( int $user_id ) {
371
+
return ( new GiftScheduler() )->get_all( array( 'scheduled_for' => $user_id ) );
372
+
}
373
+
374
+
/**
375
+
* Check if the course in cart is for gift
376
+
*
377
+
* This method will work only if the monetization is by tutor native
378
+
*
379
+
* @since 3.8.0
380
+
*
381
+
* @param integer $course_id The course id.
382
+
*
383
+
* @return bool true|false
384
+
*/
385
+
public static function is_gift_course_in_cart( int $course_id ) {
386
+
if ( ! tutor_utils()->is_monetize_by_tutor() ) {
387
+
return false;
388
+
}
389
+
390
+
return ( new NativeGiftProceeder() )->is_gift_course_in_cart( $course_id );
391
+
}
392
+
393
+
/**
394
+
* Filter enrollment buttons to add gift course button
395
+
*
396
+
* @since 3.9.3
397
+
*
398
+
* @param object $buttons buttons.
399
+
* @param int $course_id course id.
400
+
* @param int $user_id user id.
401
+
*
402
+
* @return object
403
+
*/
404
+
public function filter_enrollment_buttons( $buttons, $course_id, $user_id ) {
405
+
$buttons->show_gift_course_btn = false;
406
+
407
+
if ( self::can_gift_course( $course_id ) ) {
408
+
$buttons->show_gift_course_btn = true;
409
+
}
410
+
411
+
return $buttons;
412
+
}
413
+
}
414
+