Overview

Classes

  • Bright
  • BrightWoocommerceConstants
  • BrightWoocommerceIntegration
  • WoocommerceExtensions

Functions

  • bright_add_quicktags
  • bright_add_token_tag
  • bright_call_api_for_course
  • bright_check_compat
  • bright_curl
  • bright_curl_error
  • bright_echo_message
  • bright_extract_embed_code
  • bright_fetch_template_text
  • bright_fetch_user_attributes
  • bright_get_authentication_code_for_user
  • bright_get_avatar_url
  • bright_get_course_data
  • bright_get_course_list_with_registrations
  • bright_get_course_providers
  • bright_get_registration_data
  • bright_get_registration_list
  • bright_get_reportage_urls
  • bright_get_template_data
  • bright_get_user
  • bright_learning_paths_load_bright_customization_scripts
  • bright_load_custom_wp_admin_style
  • bright_load_scripts
  • bright_log
  • bright_manage_woocommerce_order
  • bright_menu_admin
  • bright_menu_overview
  • bright_menu_settings
  • bright_menu_sync
  • bright_message
  • bright_register_user_to_course
  • bright_render_as_javascript
  • bright_reset_token
  • bright_results_matrix
  • bright_return_as_javascript
  • bright_rewrite_embed_code
  • bright_run_stored_query
  • bright_set_current_course_provider
  • bright_shortcode_func
  • bright_stop
  • bright_stub
  • bright_support
  • bright_template_pack_load_bright_customization_scripts
  • bright_template_pack_load_bright_customization_styles
  • bright_update_all_users
  • bright_update_realmuser_meta
  • bright_update_user_licenses
  • bright_update_user_meta
  • btp_create_header_text
  • dump_bright_js_for_footer
  • setup_bright_menu
  • Overview
  • Class
  1: <?php
  2:     /*
  3:     Plugin Name: Bright Woocommerce Integration
  4:     Plugin URI: http://aurabright.aura-softare.com/
  5:     Description: Bright Woocommerce Integration Plugin For WordPress
  6:     Author: Aura Software
  7:     Version: 3.5.1
  8:     Author URI: http://www.aura-software.com/
  9: 
 10:     Source code created by Aura Software, LLC is licensed under a 
 11:     Attribution-NoDerivs 3.0 Unported United States License
 12:     http://creativecommons.org/licenses/by-nd/3.0/
 13:     */
 14: 
 15: /* add_action( 'profile_update', 'update_user_licenses', 10, 2 ); */
 16: 
 17: /* add_filter( 'update_user_metadata', 'myplugin_update_foo', 10, 5 ); */
 18: 
 19: class BrightWoocommerceConstants {
 20:   const LICENSE_ORDER = 'bright_license';
 21:   const LICENSE_META = 'bright_licenses';
 22:   const LICENSE_ORDER_ID = 'bright_license_id';
 23:   const BRIGHT_COURSE_ID = 'bright_course_id';
 24:   const BRIGHT_METADATA = 'bright_metadata'; 
 25: }
 26: 
 27: add_filter( 'update_user_metadata', 'bright_update_user_licenses', 10, 5 );
 28: 
 29: /**
 30:  * A Filter on update_user_metadata.   Looks for 'bright_licenses' user meta data and updates the user licenses accordingly.
 31:  * Argument 1 is ignored.
 32:  *
 33:  * See https://codex.wordpress.org/Plugin_API/Filter_Reference/update_(meta_type)_metadata
 34:  * https://core.trac.wordpress.org/browser/tags/3.7.1/src/wp-includes/meta.php#L122
 35:  *
 36:  * @return void
 37:  * @access public
 38:  *
 39:  */
 40: 
 41: function bright_update_user_licenses( $null, $object_id, $meta_key, $meta_value, $prev_value ) {
 42:   if ($meta_key == BrightWoocommerceConstants::LICENSE_META)
 43:     BrightWoocommerceIntegration::update_user_licenses($object_id,$meta_value); /* $object_id is the $user_id */
 44: }
 45: 
 46: class WoocommerceExtensions {
 47:   /**
 48:    * Returns the associated WC_Product record for an WC_Item
 49:    * @access public
 50:    * @return WC_Product
 51:    * @param WC_Item $item
 52:    */
 53:   static public function item_product($item) {
 54:     $product_id = $item['product_id'];
 55:     $product = new WC_Product ($product_id);
 56:     return $product;
 57:    }
 58: }
 59: 
 60: 
 61: class BrightWoocommerceIntegration {
 62:   /**
 63:    * Returns true if product has associated linked Bright product ids.
 64:    * @access public
 65:    * @return Boolean
 66:    * @param WC_Product $product
 67:    */
 68:   static public function is_bright_product($product) {
 69:     $bright_course_ids = BrightWoocommerceIntegration::get_bright_course_ids($product); 
 70:     if (count($bright_course_ids) > 0) 
 71:       return true;
 72:     return false;
 73:   }
 74: 
 75:   /**
 76:    * Returns true if product is a bright product, and one of the following is true:
 77:    *     1. the item quantity is greater than 1.
 78:    *     2. the bright metadata defines a quantity_multiplier.
 79:    *     3. the bright metadata indicates that the product should always be in the form of a license purchase.
 80:    *
 81:    * No arguments is taken, access to the cart is via the global $woocommerce variable.
 82:    *
 83:    * @access public
 84:    * @return Boolean
 85:    */
 86:   static public function is_cart_a_probable_license_purchase() {
 87:     global $woocommerce;
 88: 
 89:     $cart = $woocommerce->cart;
 90:     $cart_contents = $cart->cart_contents;
 91: 
 92:     $ret = false;
 93: 
 94:     foreach ($cart_contents as $key => $product_a) {
 95:       $product = $product_a['data'];
 96:       
 97:       if (BrightWoocommerceIntegration::is_bright_product($product)) {
 98: 
 99:         $bright_metadata= BrightWoocommerceIntegration::get_bright_product_metadata($product);
100:         $bright_course_ids = BrightWoocommerceIntegration::get_bright_course_ids($product);
101:         foreach($bright_course_ids as &$bright_course_id) {
102:           $quantity = BrightWoocommerceIntegration::determine_quantity($product_a['quantity'],
103:                                                                        $bright_course_id,
104:                                                                        $bright_metadata);
105:           bright_log("quantity for {$bright_course_id} is {$quantity}");
106:           if ($quantity > 1)
107:             $ret = true;
108:         }
109:       }
110:     }
111:     return $ret;
112:   }
113:   
114:   /* update a user's licenses; whether they need it or not */
115:   static public function update_user_licenses($user_id , $licenses=null) {
116:     $user = get_user_by( 'id', $user_id);
117:     if (empty($licenses))
118:       $licenses = get_user_meta($user_id, BrightWoocommerceConstants::LICENSE_META, true);  
119:     $a_l = explode(",",$licenses);
120:     /* TODO: strip whitespace */
121:     foreach ($a_l as &$license) 
122:       Bright::add_learner_to_invitation($user->user_email,$license,true); /* arg3 says synchronous registration */
123:   }
124: 
125:   /* will return a valid non null non empty value if the data for this order has been sent to the bright server 
126:      and a valid ID was returned */
127:   static function get_bright_license_id($wc_order) {
128:     if ($wc_order instanceof WC_Order) {
129:       $order_id = $wc_order->id;
130:       return get_post_meta($order_id, BrightWoocommerceConstants::LICENSE_ORDER_ID,true);
131:     }
132:     return null;
133:   }
134: 
135: 
136:   static function set_bright_license_id($wc_order,$license_id) {
137:     if ($wc_order instanceof WC_Order) {
138:       $order_id = $wc_order->id;
139:       return add_post_meta($order_id, BrightWoocommerceConstants::LICENSE_ORDER_ID,$license_id,true) || update_post_meta($order_id, BrightWoocommerceConstants::LICENSE_ORDER_ID,$license_id);
140:     }
141:     return null;
142:   }
143: 
144:   static function is_license_order($wc_order) {
145:     $ret = get_post_meta($wc_order->id,BrightWoocommerceConstants::LICENSE_ORDER,false);
146:     return $ret;
147:   }
148: 
149:   static function get_bright_product_metadata($product) {
150:     if ($product instanceof WC_Product) {
151:       $single =  get_post_meta($product->id,BrightWoocommerceConstants::BRIGHT_METADATA,true);
152:       if (!empty($single)) {
153:         bright_log("got order metadata of {$single}");
154:         $decode = json_decode($single);
155:         if (empty($decode)) {
156:           bright_log("Could not process Bright Order Metadata of {$single}",true);
157: 
158:           switch (json_last_error()) {
159:           case JSON_ERROR_NONE:
160:             bright_log( ' - No errors', true);
161:             break;
162:           case JSON_ERROR_DEPTH:
163:             bright_log( ' - Maximum stack depth exceeded', true);
164:             break;
165:           case JSON_ERROR_STATE_MISMATCH:
166:             bright_log( ' - Underflow or the modes mismatch', true);
167:             break;
168:           case JSON_ERROR_CTRL_CHAR:
169:             bright_log( ' - Unexpected control character found', true);
170:             break;
171:           case JSON_ERROR_SYNTAX:
172:             bright_log( ' - Syntax error, malformed JSON', true);
173:             break;
174:           case JSON_ERROR_UTF8:
175:             bright_log( ' - Malformed UTF-8 characters, possibly incorrectly encoded', true);
176:             break;
177:           default:
178:             bright_log( ' - Unknown error', true);
179:             break;
180:           }
181:           bright_log("This is a misconfiguration please contact your system administrator for repair.",true);
182:         }
183: 
184:         bright_log("decoded metadata to follow");
185:         bright_log($decode);
186:         return $decode;
187:       }
188:     }
189:     return null;
190:   }
191: 
192:   static function get_bright_course_ids($product) {
193:     if ($product instanceof WC_Product) {
194:       $multiple = get_post_meta($product->id,BrightWoocommerceConstants::BRIGHT_COURSE_ID,false);
195:       return $multiple;
196:     } else 
197:       bright_log('Argument must be of type WC_Product',true);
198: 
199:     return null;
200:   }
201: 
202:   static public function debug_order($wc_order) {
203:     $order_id = $wc_order->id;
204:     $items = $wc_order->get_items();
205:     $course_guids = array();
206:     $license_data = array();
207:     foreach($items as &$item) {
208:       $quantity = $item['qty'];
209:       $product =  WoocommerceExtensions::item_product($item);
210:       /* hmmm next line seems to be bogus .... no such function */
211:       $bright_course_id = BrightWoocommerceIntegration::get_bright_course_id($product);
212:       array_push($course_guids,$bright_course_id);
213:       $license_data[$bright_course_id] = array();
214:       $license_data[$bright_course_id]['seats_available'] = $quantity;
215:     }
216:   }
217: 
218:   /**
219:    * Returns an integer representing the quantity of the bright course to be purchased.
220:    * This can be a function of the item quantity and/or bright metadata
221:    * See also http://help.aura-software.com/defining-bright-metadata-for-a-product/
222:    * @return integer
223:    * @access public
224:    * @param integer $item_quantity
225:    * @param string $bright_course_id
226:    * @param Arrray $bright_metadata
227:    */
228:   static public function determine_quantity($item_quantity,$bright_course_id,$bright_metadata) {
229:     bright_log($item_quantity);
230:     bright_log($bright_course_id);
231:     bright_log($bright_metadata);
232:     if(!empty($bright_metadata)) {
233:       if(!empty($bright_course_id)) {
234:         bright_log("bright_course_id is {$bright_course_id}");
235:         $bright_courses = $bright_metadata->{'bright-courses'};
236:         if (!empty($bright_courses)) 
237:           foreach($bright_courses as &$course) 
238:             if ($course->{'course-id'} == $bright_course_id) {
239:               if(property_exists($course, "quantity-multiplier"))
240:                 $quantity_multipier = $course->{'quantity-multiplier'};
241:               if(property_exists($course, "quantity_multiplier"))
242:                 $quantity_multipier = $course->{'quantity_multiplier'};
243:               if (!empty($quantity_multipier)) {
244:                 bright_log("for course id {$bright_course_id} a quantity_multiplier of {$quantity_multipier} was found");
245:                 $quan = $item_quantity * $quantity_multipier;
246:                 bright_log("for course id {$bright_course_id} returning a quantity of {$quan}");
247:                 return $quan;
248:               }
249:             }
250:       }
251:     }
252:     return $item_quantity; /* fallthrough */
253:   }
254: 
255:   static function manage_license_order($wc_order) {
256:     $log_base = "manage_license_order({$wc_order->id}): ";
257:     $do_manage = ($wc_order->get_status() == "processing");
258:     $debug_manage = false;
259:     
260:     if (strstr ($_SERVER['REQUEST_URI'],'debug_manage_order')) {
261:       $do_manage = true;
262:       $debug_manage = true;
263:     }
264: 
265:     if ($do_manage) {
266:       $license_id = BrightWoocommerceIntegration::get_bright_license_id($wc_order);
267:       bright_log("{$log_base}license_id is {$license_id}");
268:       if (empty($license_id) || $debug_manage) {
269:         $order_id = $wc_order->id;
270:         $items = $wc_order->get_items();
271:         $course_guids = array();
272:         $license_data = array();
273:         foreach($items as &$item) {
274:           $quantity = $item['qty'];
275:           $product =  WoocommerceExtensions::item_product($item);
276:           $bright_course_ids = BrightWoocommerceIntegration::get_bright_course_ids($product);
277:           $bright_metadata= BrightWoocommerceIntegration::get_bright_product_metadata($product);
278:               
279:           foreach($bright_course_ids as &$bright_course_id) {
280:             if (! in_array($bright_course_id,$course_guids) )
281:               array_push($course_guids,$bright_course_id);
282: 
283:             if (! array_key_exists($bright_course_id, $license_data)) {
284:               $license_data[$bright_course_id] = array();
285:               $license_data[$bright_course_id]['seats_available'] = 0;
286:             }
287:             $license_data[$bright_course_id]['seats_available'] += BrightWoocommerceIntegration::determine_quantity($quantity,
288:                                                                                                                     $bright_course_id,
289:                                                                                                                     $bright_metadata);
290:           }
291:         }
292: 
293:         $custom = array();
294:         $custom['license'] = true;
295:         $custom['order_id'] = $order_id;
296:         $custom['course_guids'] = $course_guids;
297:         $custom['license_data'] = $license_data;
298: 
299:         $url = get_site_url();
300:         $find = array( 'http://', 'https://' );
301:         $replace = '';
302:         $without_protocol = str_replace( $find, $replace, $url );
303: 
304:         $custom['initiating_site'] = $without_protocol;
305:         $custom['initiating_user'] = bright_get_user()->user_email;
306:         
307:         $bright_license = Bright::create_invitation(array(
308:                                                           'license' => true,
309:                                                           'course_guids' => $course_guids,
310:                                                           'license_data' => $license_data,
311:                                                           'custom' =>  json_encode($custom) // "{\"license\": 1, \"order_id\": {$order_id}}",
312:                                                           ));
313: 
314:         global $bright_curl_error;
315: 
316:         $error_func = function($log_base,$errortext,$wc_order,$object=null) {
317:           $error = "{$log_base}: {$errortext}";
318:           $wc_order->add_order_note($error);
319:           bright_log("{$error}",true);
320:           if ($object)
321:             bright_log($object);
322:           bright_log("Please try to refresh the page or contact support if problems continue",true);
323:           return null;
324:         };
325:         
326: 
327:         if (!empty($bright_curl_error)) 
328:           return $error_func($log_base, "Error Contacting The Bright Server: {$bright_curl_error}.",$wc_order);
329: 
330:         if (property_exists($bright_license,'error'))
331:           return $error_func($log_base, "An error was received from the Bright Server: \"{$bright_license->error} ({$bright_license->details})\".",$wc_order);
332:         
333:         if (!property_exists($bright_license,'name')) 
334:           return $error_func($log_base, "An illegal response was received from the Bright server [no license name returned].",$wc_order,$bright_license);
335:         $invitation_id = $bright_license->name;
336:         if (! empty($invitation_id)) {
337:             BrightWoocommerceIntegration::set_bright_license_id($wc_order,$invitation_id);
338:             // TODO: I can see scenarios where we WOULDN't want to do this.
339:             $wc_order->add_order_note("{$log_base} bright license key set to {$invitation_id}");
340:             return $wc_order->update_status('completed');
341:         } else
342:           return $error_func($log_base, "An illegal response was received from the Bright server [blank license key returned].",$wc_order,$bright_license);
343:       } 
344:     }
345:   }
346: }
347: 
348: function bright_manage_woocommerce_order($order_id) {
349:   global $woocommerce,  $wpdb, $bright_token;
350:   bright_log("bright_manage_woocommerce_order({$order_id})");
351: 
352:   $wc_order = new WC_ORDER($order_id);
353:   if (BrightWoocommerceIntegration::is_license_order($wc_order))  /* don't process registrations for license orders */
354:     return BrightWoocommerceIntegration::manage_license_order($wc_order);
355: 
356:   $current_user = wp_get_current_user();
357:   $email = $current_user->user_email;
358:   $blog_id = get_current_blog_id();
359: 
360:   $prefix="{$wpdb->prefix}";
361:   $query = <<<EOF
362: select 
363:   products.id product_id,
364:   orders.id order_id,
365:   product_meta.meta_value as bright_course_id,
366:   customer.meta_value as customer,
367:   {$prefix}woocommerce_order_itemmeta.*
368: from 
369:   {$prefix}posts products,
370:   {$prefix}postmeta product_meta,
371:   {$prefix}posts orders,
372:   {$prefix}postmeta order_meta,
373:   {$prefix}postmeta customer,
374:   {$prefix}woocommerce_order_items,
375:   {$prefix}woocommerce_order_itemmeta
376: where 
377:   orders.id = order_meta.post_id
378: and
379:   order_meta.meta_key = '_paid_date'
380: and
381:   order_meta.meta_value is not null
382: and
383:   orders.id = {$prefix}woocommerce_order_items.order_id
384: and
385:   orders.id = customer.post_id
386: and
387:   customer.meta_key = '_customer_user'
388: and
389:   {$prefix}woocommerce_order_itemmeta.order_item_id = {$prefix}woocommerce_order_items.order_item_id
390: and
391:   {$prefix}woocommerce_order_itemmeta.meta_key = '_product_id'
392: and
393:   products.id = {$prefix}woocommerce_order_itemmeta.meta_value
394: and
395:   product_meta.meta_key = 'bright_course_id'
396: and
397:   customer.meta_value = {$current_user->ID}
398: and 
399:   products.id = product_meta.post_id
400: and
401:   orders.id = {$order_id}
402: EOF;
403: 
404:   $products = $wpdb->get_results($query, ARRAY_A); 
405: 
406:   if (strstr ($_SERVER['REQUEST_URI'],'brightwoodumpquery')) {
407:     echo var_dump($products);
408:     echo "<pre>{$query}</pre>";
409:     echo var_dump($products);
410:   }
411: 
412:   $bright_products = array();
413:   foreach ($products as &$product) {
414:     $product_id = $product['product_id'];
415:     $order_id = $product['order_id'];
416:     $bright_course_id = $product['bright_course_id'];
417:     $customer = $product['customer'];
418:     $meta_id = $product['meta_id'];
419:     $order_item_id = $product['order_item_id'];
420:     $meta_key = $product['meta_key'];
421:     $meta_value = $product['meta_value'];
422: 
423:     bright_register_user_to_course($bright_token,$email,$bright_course_id); 
424:     $bright_products[$product_id] = true;
425:   }
426: 
427:   /* all items are satisfied; so this order is now complete! */
428:   if (count($wc_order->get_items()) === count($bright_products))
429:     $wc_order->update_status( 'completed' );
430: }
431: 
432: add_action( 'woocommerce_thankyou', function ($order_id) {
433:     bright_manage_woocommerce_order($order_id);
434:   }, 8);
435: 
436: add_action( 'woocommerce_view_order', function ($order_id) {
437:     bright_manage_woocommerce_order($order_id);
438:   }, 8);
439: 
440: global $bright_embedder_templates;
441: 
442: if (empty($bright_embedder_templates))  /* you have to do this in case the variable isn't loaded yet */
443:   $bright_embedder_templates = array();
444: 
445: $bright_embedder_templates['classic_paywall'] = <<<EOF
446: {$header_text}
447: {{#if registration}}
448: {$stats_table}
449: {$clear}
450: {$launchbutton}
451: {{else}}
452: This course will become available after purchase and the successful processing of your payment.
453: {{/if}}
454: EOF;
455: 
456: ?>
457: 
API documentation generated by ApiGen