PluginProbe ʕ •ᴥ•ʔ
SureCart – Ecommerce Made Easy For Selling Physical Products, Digital Downloads, Subscriptions, Donations, & Payments / 2.6.1
SureCart – Ecommerce Made Easy For Selling Physical Products, Digital Downloads, Subscriptions, Donations, & Payments v2.6.1
4.4.2 4.4.1 4.4.0 4.3.3 4.3.2 4.3.1 4.3.0 4.2.3 4.2.2 4.2.1 1.0.3 1.0.4 1.0.5 1.0.6 1.1.0 1.1.1 1.1.10 1.1.11 1.1.12 1.1.13 1.1.14 1.1.15 1.1.16 1.1.17 1.1.18 1.1.19 1.1.2 1.1.3 1.1.4 1.1.5 1.1.6 1.1.7 1.1.8 1.1.9 1.10.0 1.10.1 1.10.2 1.10.3 1.10.4 1.11.0 1.11.1 1.11.2 1.2.0 1.2.1 1.2.2 1.2.3 1.2.4 1.2.5 1.3.0 1.3.1 1.3.2 1.3.3 1.3.4 1.4.0 1.4.1 1.4.2 1.5.0 1.5.1 1.5.2 1.5.3 1.5.4 1.5.5 1.5.6 1.5.7 1.5.8 1.6.0 1.6.1 1.6.2 1.6.3 1.6.4 1.7.0 1.7.1 1.7.2 1.8.0 1.8.1 1.8.2 1.8.3 1.8.4 1.8.5 1.9.0 1.9.1 1.9.2 1.9.3 1.9.4 1.9.5 2.0.0 2.0.1 2.1.0 2.1.1 2.1.2 2.1.3 2.1.4 2.10.0 2.10.1 2.11.0 2.11.1 2.11.2 2.11.3 2.11.4 2.12.0 2.13.0 2.14.0 2.14.1 2.15.0 2.15.1 2.16.0 2.16.1 2.16.2 2.16.3 2.17.0 2.17.1 2.17.2 2.18.0 2.19.0 2.19.2 2.19.3 2.19.4 2.2.0 2.2.1 2.20.0 2.20.1 2.20.2 2.20.3 2.20.4 2.20.5 2.20.6 2.21.0 2.22.0 2.22.1 2.23.0 2.24.0 2.25.0 2.25.1 2.25.2 2.26.0 2.27.0 2.27.1 2.28.0 2.29.0 2.29.1 2.29.2 2.29.3 2.29.4 2.3.0 2.3.1 2.30.0 2.31.0 2.31.1 2.31.2 2.31.3 2.4.0 2.4.1 2.4.2 2.4.3 2.4.4 2.40.0 2.40.1 2.5.0 2.5.1 2.5.2 2.6.0 2.6.1 2.6.2 2.7.0 2.7.1 2.7.2 2.7.3 2.7.4 2.7.5 2.8.0 2.8.1 2.8.2 2.8.3 2.8.4 2.9.0 3.0.0 3.0.0-RC1 3.0.0-RC2 3.0.0-beta1 3.0.0-beta2 3.0.1 3.0.2 3.0.3 3.0.4 3.0.5 3.1.0 3.1.1 3.1.2 3.1.3 3.1.4 3.1.5 3.1.6 3.10.0 3.10.1 3.11.0 3.12.0 3.13.0 3.13.1 3.13.2 3.13.3 3.13.4 3.14.0 3.15.0 3.15.1 3.15.2 3.15.3 3.15.4 3.15.5 3.16.0 3.16.1 3.16.2 3.16.3 3.16.4 3.16.5 3.16.6 3.16.7 3.16.8 3.17.0 3.17.1 3.17.2 3.17.3 3.17.4 3.17.5 3.17.6 3.18.0 3.19.0 3.19.1 3.19.2 3.2.0 3.2.1 3.2.2 3.20.0 3.20.1 3.3.0 3.3.1 3.4.0 3.4.1 3.4.2 3.4.3 3.5.0 3.5.1 3.5.2 3.5.3 3.6.0 3.6.1 3.6.2 3.7.0 3.7.1 3.7.2 3.7.3 3.8.0 3.8.1 3.8.2 3.8.3 3.8.4 3.8.5 3.9.0 4.0.0 4.0.1 4.0.2 4.0.3 trunk 4.1.0 0.2.19.1 4.1.1 1.0.0 4.2.0 1.0.1 1.0.2
surecart / app / src / Integrations / TutorLMS / TutorLMSService.php
surecart / app / src / Integrations / TutorLMS Last commit date
TutorLMSService.php 3 years ago TutorLMSServiceProvider.php 3 years ago add-to-cart-surecart.php 3 years ago
TutorLMSService.php
401 lines
1 <?php
2
3 namespace SureCart\Integrations\TutorLMS;
4
5 use SureCart\Integrations\Contracts\IntegrationInterface;
6 use SureCart\Integrations\Contracts\PurchaseSyncInterface;
7 use SureCart\Integrations\IntegrationService;
8 use SureCart\Models\Integration;
9 use SureCart\Models\Price;
10 use SureCart\Models\Product;
11 use SureCart\Support\Currency;
12
13 /**
14 * Controls the LearnDash integration.
15 */
16 class TutorLMSService extends IntegrationService implements IntegrationInterface, PurchaseSyncInterface {
17
18 public function bootstrap() {
19 parent::bootstrap();
20
21 add_filter( 'tutor/course/single/entry-box/free', [ $this, 'purchaseButton' ], 10, 2 );
22 add_filter( 'tutor/course/single/entry-box/purchasable', [ $this, 'purchaseButton' ], 10, 2 );
23 add_filter( 'get_tutor_course_price', [ $this, 'coursePrice' ], 11, 2 );
24 add_filter( 'tutor_course_loop_price', [ $this, 'loopPurchaseButton' ], 10, 2 );
25
26 add_action( 'surecart/models/price/updated', [ $this, 'clearPriceCache' ], 10, 2 );
27 add_action( 'surecart/models/price/created', [ $this, 'clearPriceCache' ], 10, 2 );
28 }
29
30 /**
31 * Show our purchase button if we have an integration.
32 *
33 * @param string $output The button HTML.
34 *
35 * @return string
36 */
37 public function loopPurchaseButton( $output ) {
38 // check first to see if we have any integrations.
39 $integrations = Integration::where( 'integration_id', get_the_ID() )->andWhere( 'model_name', 'product' )->get();
40 if ( empty( $integrations ) ) {
41 return $output;
42 }
43
44 // Get the model ids from the integrations.
45 $product_ids = array_column( $integrations, 'model_id' );
46 if ( empty( $product_ids ) ) {
47 return $output;
48 }
49
50 // get purchasable prices from cache.
51 $prices = $this->getCachedProductsPrices( $product_ids );
52 if ( empty( $prices ) ) {
53 return $output;
54 }
55
56 // add our components.
57 \SureCart::assets()->enqueueComponents();
58
59 $is_logged_in = is_user_logged_in();
60 $enable_guest_course_cart = tutor_utils()->get_option( 'enable_guest_course_cart' );
61 $required_loggedin_class = '';
62 if ( ! $is_logged_in && ! $enable_guest_course_cart ) {
63 $required_loggedin_class = apply_filters( 'tutor_enroll_required_login_class', 'tutor-open-login-modal' );
64 }
65
66 // template.
67 ob_start(); ?>
68
69 <div class="tutor-course-list-btn"><?php echo apply_filters( 'tutor_course_restrict_new_entry', '<a href="' . get_the_permalink() . '" class="tutor-btn tutor-btn-outline-primary tutor-btn-md tutor-btn-block ' . $required_loggedin_class . '">' . __( 'Enroll Course', 'tutor' ) . '</a>' ); ?></div>
70
71 <?php
72 return ob_get_clean();
73 }
74
75 /**
76 * Clear the price cache.
77 *
78 * @param \SureCart\Models\Price $price The price model.
79 *
80 * @return void
81 */
82 public function clearPriceCache( $price ) {
83 if ( empty( $price->product ) ) {
84 return;
85 }
86
87 // get the product id.
88 $product_id = is_a( $price->product, Product::class ) ? $price->product->id : $price->product;
89
90 delete_transient( 'surecart_tutor_lms_product_' . $product_id );
91 }
92
93 /**
94 * Get cached product prices.
95 *
96 * @param array $product_ids The product ids.
97 *
98 * @return array
99 */
100 public function getCachedProductsPrices( $product_ids = [] ) {
101 $prices = [];
102 foreach ( $product_ids as $product_id ) {
103 $prices = array_merge( $prices, $this->getCachedProductPrices( $product_id ) );
104 }
105 return $prices;
106 }
107
108 /**
109 * Get the cached prices.
110 *
111 * @param string $product_id The product id.
112 *
113 * @return array
114 */
115 public function getCachedProductPrices( $product_id ) {
116 // cache key.
117 $cache_key = 'surecart_tutor_lms_product_' . $product_id;
118
119 // get the transient.
120 $prices = get_transient( $cache_key );
121
122 // if we do not have a transient.
123 if ( false === $prices ) {
124 // get purchasable prices for product.
125 $prices = Price::where(
126 [
127 'product_ids' => [ $product_id ],
128 'archived' => false,
129 ]
130 )->get();
131
132 // store in transient.
133 set_transient( $cache_key, $prices, apply_filters( 'surecart_tutor_lms_product_cache_time', DAY_IN_SECONDS, $this ) );
134 }
135
136 return $prices;
137 }
138
139 /**
140 * The course price.
141 *
142 * @param string $price The price string.
143 * @param integer $course_id The course id.
144 *
145 * @return string
146 */
147 public function coursePrice( $price, $course_id ) {
148 $integrations = Integration::where( 'integration_id', $course_id )->andWhere( 'model_name', 'product' )->get();
149
150 // we have no integrations.
151 if ( empty( $integrations ) ) {
152 return $price;
153 }
154
155 if ( empty( $integrations[0]->model_id ) ) {
156 return $price;
157 }
158
159 // get the first product.
160 $prices = $this->getCachedProductPrices( $integrations[0]->model_id );
161 if ( is_wp_error( $prices ) ) {
162 return $prices;
163 }
164
165 // there is no price.
166 if ( empty( $prices ) ) {
167 return esc_html__( 'No price', 'surecart' );
168 }
169
170 $price_array = [];
171 foreach ( $prices as $price ) {
172 if ( $price->ad_hoc ) {
173 $price_array[] = esc_html__( 'Custom amount', 'surecart' );
174 } else {
175 $price_array[] = Currency::format( $price->amount, $price->currency ?? 'usd' );
176 }
177 }
178
179 // no price.
180 return implode( ', ', $price_array );
181 }
182
183 /**
184 * Show our purchase button if we have an integration.
185 *
186 * @param string $output The button HTML.
187 * @param integer $id The course id.
188 *
189 * @return string
190 */
191 public function purchaseButton( $output, $id ) {
192 // check first to see if we have any integrations.
193 $integrations = Integration::where( 'integration_id', $id )->andWhere( 'model_name', 'product' )->get();
194 if ( empty( $integrations ) ) {
195 return $output;
196 }
197
198 // Get the model ids from the integrations.
199 $product_ids = array_column( $integrations, 'model_id' );
200 if ( empty( $product_ids ) ) {
201 return $output;
202 }
203
204 // get purchasable prices from cache.
205 $prices = $this->getCachedProductsPrices( $product_ids );
206 if ( empty( $prices ) ) {
207 return $output;
208 }
209
210 // add our components.
211 \SureCart::assets()->enqueueComponents();
212
213 // template.
214 ob_start();
215
216 include 'add-to-cart-surecart.php';
217
218 return ob_get_clean();
219 }
220
221 /**
222 * Get the slug for the integration.
223 *
224 * @return string
225 */
226 public function getName() {
227 return 'surecart/tutor-course';
228 }
229
230 /**
231 * Get the model for the integration.
232 *
233 * @return string
234 */
235 public function getModel() {
236 return 'product';
237 }
238
239 /**
240 * Get the slug for the integration.
241 *
242 * @return string
243 */
244 public function getLogo() {
245 return esc_url_raw( trailingslashit( plugin_dir_url( SURECART_PLUGIN_FILE ) ) . 'images/integrations/tutor.svg' );
246 }
247
248 /**
249 * Get the slug for the integration.
250 *
251 * @return string
252 */
253 public function getLabel() {
254 return __( 'TutorLMS Course', 'surecart' );
255 }
256
257 /**
258 * Get the slug for the integration.
259 *
260 * @return string
261 */
262 public function getItemLabel() {
263 return __( 'Course Access', 'surecart' );
264 }
265
266 /**
267 * Get the slug for the integration.
268 *
269 * @return string
270 */
271 public function getItemHelp() {
272 return __( 'Enable access to a TutorLMS course.', 'surecart' );
273 }
274
275 /**
276 * Is this enabled?
277 *
278 * @return boolean
279 */
280 public function enabled() {
281 return defined( 'TUTOR_VERSION' );
282 }
283
284 /**
285 * Get item listing for the integration.
286 *
287 * @param array $items The integration items.
288 * @param string $search The search term.
289 *
290 * @return array The items for the integration.
291 */
292 public function getItems( $items = [], $search = '' ) {
293 if ( ! function_exists( 'tutor' ) ) {
294 return $items;
295 }
296
297 wp_reset_query();
298 $course_query = new \WP_Query(
299 [
300 'post_type' => tutor()->course_post_type,
301 'post_status' => 'publish',
302 's' => $search,
303 'per_page' => 10,
304 ]
305 );
306
307 if ( ( isset( $course_query->posts ) ) && ( ! empty( $course_query->posts ) ) ) {
308 $items = array_map(
309 function( $post ) {
310 return (object) [
311 'id' => $post->ID,
312 'label' => $post->post_title,
313 ];
314 },
315 $course_query->posts
316 );
317 }
318
319 return $items;
320 }
321
322 /**
323 * Get the individual item.
324 *
325 * @param string $id Id for the record.
326 *
327 * @return object The item for the integration.
328 */
329 public function getItem( $id ) {
330 $course = get_post( $id );
331 if ( ! $course ) {
332 return [];
333 }
334 return (object) [
335 'id' => $id,
336 'provider_label' => __( 'TutorLMS Course', 'surecart' ),
337 'label' => $course->post_title,
338 ];
339 }
340
341 /**
342 * Enable Access to the course.
343 *
344 * @param \SureCart\Models\Integration $integration The integrations.
345 * @param \WP_User $wp_user The user.
346 *
347 * @return boolean|void Returns true if the user course access updation was successful otherwise false.
348 */
349 public function onPurchaseCreated( $integration, $wp_user ) {
350 $this->updateAccess( $integration->integration_id, $wp_user, true );
351 }
352
353 /**
354 * Enable access when purchase is invoked
355 *
356 * @param \SureCart\Models\Integration $integration The integrations.
357 * @param \WP_User $wp_user The user.
358 *
359 * @return boolean|void Returns true if the user course access updation was successful otherwise false.
360 */
361 public function onPurchaseInvoked( $integration, $wp_user ) {
362 $this->onPurchaseCreated( $integration, $wp_user );
363 }
364
365 /**
366 * Remove a user role.
367 *
368 * @param \SureCart\Models\Integration $integration The integrations.
369 * @param \WP_User $wp_user The user.
370 *
371 * @return boolean|void Returns true if the user course access updation was successful otherwise false.
372 */
373 public function onPurchaseRevoked( $integration, $wp_user ) {
374 $this->updateAccess( $integration->integration_id, $wp_user, false );
375 }
376
377 /**
378 * Update access to a course.
379 *
380 * @param integer $course_id The course id.
381 * @param \WP_User $wp_user The user.
382 * @param boolean $add True to add the user to the course, false to remove.
383 *
384 * @return boolean|void Returns true if the user course access updation was successful otherwise false.
385 */
386 public function updateAccess( $course_id, $wp_user, $add = true ) {
387 // we don't have learndash installed.
388 if ( ! function_exists( 'tutor_utils' ) ) {
389 return;
390 }
391
392 if ( ! $add ) {
393 tutor_utils()->cancel_course_enrol( $course_id, $wp_user->ID );
394 return;
395 }
396
397 tutor_utils()->do_enroll( $course_id, 0, $wp_user->ID );
398 tutor_utils()->complete_course_enroll( 0 );
399 }
400 }
401