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 Plugin For WordPress
   4:     Plugin URI: http://aurabright.aura-softare.com/
   5:     Description: Bright ... a state of the art integration framework for cloud based learning services.
   6:     Author: Aura Software
   7:     Version: 6.7.6
   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: $bright_plugin_root = dirname (__FILE__);
  16: global $bright_token;
  17: global $bright_embedder_templates;
  18: global $bright_js_for_footer;
  19: global $bright_curl_error;
  20: 
  21: // Disable textureize filter
  22: // This mangles quotations into unicode likenesses which cause unwanted
  23: // behavior in Bright templates, like not working at all.
  24: remove_filter('the_content', 'wptexturize');
  25: 
  26: require_once($bright_plugin_root.'/menus/settings.php');
  27: require_once($bright_plugin_root.'/menus/admin.php');
  28: require_once($bright_plugin_root.'/bright_helper_functions.php');
  29: require_once($bright_plugin_root.'/bright_php_api.php');
  30: require_once($bright_plugin_root.'/stub_functions.php');
  31: require_once($bright_plugin_root.'/user_management.php');
  32: 
  33: 
  34: global $bright_embedder_templates;
  35: if (empty($bright_embedder_templates)) {
  36:   $bright_embedder_templates = array();
  37: }
  38: 
  39: if(file_exists($bright_plugin_root.'/embedder_templates.php')) {
  40:   require_once($bright_plugin_root.'/embedder_templates.php');
  41: }
  42: 
  43: if(file_exists($bright_plugin_root.'/local_embedder_templates.php')) {
  44:   require_once($bright_plugin_root.'/local_embedder_templates.php');
  45: }
  46: 
  47: /*
  48: More capable than file_get_contents in that it supports SSL/TLS even on
  49: older systems, like Ubuntu 10.04.
  50: */
  51: 
  52: function bright_curl_error() {
  53:   global $bright_curl_error;
  54: 
  55:   if (empty($bright_curl_error))
  56:     return 'empty response returned from bright server.  Typically this means your Bright settings are incorrect; please check and try again.';
  57:   else
  58:     return $bright_curl_error;
  59: 
  60: }
  61: 
  62: function bright_curl($url, $method=null, $data=null) {
  63:   global $bright_curl_error;
  64:   bright_log("bright_curl calling {$url}; data to follow");
  65:   $ch = curl_init();
  66:   curl_setopt($ch, CURLOPT_URL, $url);
  67:   curl_setopt($ch, CURLOPT_SSLVERSION, 3);
  68:   curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
  69:   curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
  70:   if ($method == "POST") {
  71:     // Has a side effect of setting method to POST!
  72:     curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
  73:   }
  74:   bright_log($data);
  75:   $response = curl_exec($ch);
  76:   bright_log("bright_curl calling {$url}; response to follow");
  77:   bright_log($response);
  78:   if (!$response) 
  79:     $bright_curl_error = curl_error($ch);
  80: 
  81:   /* error_log('Bright cURL received: '.$response); */
  82:   curl_close($ch);
  83:   return $response;
  84: }
  85: 
  86: add_action('admin_menu', 'setup_bright_menu');
  87: 
  88: /* adds the bright menu to the WP dashboard */
  89: function setup_bright_menu() {
  90:   $bright_menu_slug = 'bright_options';
  91:   add_menu_page( 'Bright Overview', 'Bright' , 'manage_options', $bright_menu_slug, 'bright_menu_overview');
  92:   add_submenu_page( $bright_menu_slug, 'Bright Settings' , 'Settings', 'manage_options', $bright_menu_slug . "_settings" , 'bright_menu_settings');
  93:   add_submenu_page( $bright_menu_slug, 'Bright Admin' , 'Admin', 'manage_options', $bright_menu_slug . "_admin" , 'bright_menu_admin');
  94:   add_submenu_page( $bright_menu_slug, 'Sync User Data' , 'UserMeta Sync', 'manage_options', $bright_menu_slug . "_sync" , 'bright_menu_sync');
  95: }
  96: 
  97: function bright_menu_sync() {
  98:   echo <<<EOF
  99:   <form name="sync" method="post" action="">
 100:     
 101:     <br/>
 102:     <table>
 103:       <tr>
 104:         <td><label title="For large datasets, this can assist in working around timeout errors." for="SkipToday">Skip Records Already Updated Via Full Sync Today:</label></td>
 105:         <td><input type="checkbox" name="SkipToday"></td>
 106:         </tr>
 107:       <tr>
 108:         <td><label title="For large datasets, this can assist in working around timeout errors." for="MaxRecords">Max records to process:</label></td>
 109:         <td><input type="number" name="MaxRecords"></td>
 110:         </tr>
 111: 
 112:                <tr>
 113:    <td>
 114:     <br/>
 115:     <input type="submit" name="Submit" class="button-primary" value="Sync User Metadata">
 116:     </td>
 117:     </tr>
 118:     </table>
 119:   </form>
 120:   <br/>
 121: EOF;
 122:    if (! empty($_POST)) {
 123:     $args = array();
 124:     $args['skip-today'] = $_POST['SkipToday'];
 125:     $args['max-records'] = $_POST['MaxRecords'];
 126:     bright_update_all_users($args);
 127:    }
 128: }
 129: 
 130: function bright_menu_overview() {
 131:   global $bright_token;
 132:   echo '<h2>Bright!</h2>';
 133:   $links = bright_get_reportage_urls($bright_token);
 134:   echo '<ul>';
 135:   foreach ($links as $label => $url) {
 136:     echo '<li><a href="'.$url.'" target="_blank">'.$label.'</a></li>';
 137:   }
 138:   echo '</ul>';
 139: }
 140: 
 141: /* filter for expanding bright invitation embed codes in the post content */
 142: /* add_filter('the_content','bright_content_filter'); */
 143: 
 144: add_shortcode('bright', 'bright_shortcode_func');
 145: add_filter('widget_text', 'do_shortcode');
 146: 
 147: 
 148: function bright_shortcode_func($attr,$content) {
 149:   return bright_rewrite_embed_code($attr,$content);
 150: }
 151: 
 152: function bright_get_course_providers($api_key) {
 153:   $api_call = 'course_provider';
 154:   $api_root = get_option('bright_api_url');
 155:   $url = $api_root . '/' . $api_call . '?' . http_build_query(array(
 156:     'format' => 'json',
 157:     'api_key' => $api_key));
 158:   $json = file_get_contents($url);
 159:   $json_data = json_decode($json);
 160:   return $json_data;
 161: }
 162: 
 163: function bright_set_current_course_provider() {
 164:   $user = bright_get_user();
 165:   if (0 == $user->ID) 
 166:     return false;
 167:   else {
 168:     if (isset($_GET["clear_course_provider_id"])) 
 169:       delete_user_option($user->ID, 'bright_course_provider_id');
 170:     else 
 171:       if (isset($_GET["course_provider_id"])) {
 172:         $provider_id = (int) $_GET["course_provider_id"];
 173:         if ($provider_id)
 174:           update_user_option($user->ID, 'bright_course_provider_id', $provider_id);
 175:       }
 176:   }
 177: 
 178: }
 179: 
 180: /**
 181:  *
 182:  * Reset the global bright token to null
 183:  */
 184: 
 185: function bright_reset_token() {
 186:   global $bright_token;
 187:   $bright_token = NULL;
 188: }
 189: 
 190: /**
 191:  * Receive an authentication token from the bright server for client API
 192:  * operations.
 193:  *
 194:  * @param $user is a WP_User, like the one returned by wp_get_current_user();
 195:  *
 196:  * Returns a string containing the token or false in the case of failure.
 197:  */
 198: function bright_get_authentication_code_for_user($user) {
 199:   global $bright_token, $bright_curl_error;;
 200:   if (! empty($bright_token))
 201:     return $bright_token;
 202: 
 203:   if ( 0 == $user->ID )
 204:     return false;
 205:   else {
 206:     $api_root = get_option('bright_api_url');
 207:     $bright_realm_guid = get_option('bright_realm_guid');
 208:     $bright_secret_key = get_option('bright_secret_key');
 209:     $bright_scorm_cloud_app_id = get_option('bright_scorm_cloud_app_id');
 210:     $bright_scorm_cloud_secret_key = get_option('bright_scorm_cloud_secret_key');
 211:     $course_provider_id = get_user_option('bright_course_provider_id', $user->ID);
 212: 
 213:     $query_data = array(
 214:       'format' => 'json',
 215:       'realm_guid' => $bright_realm_guid,
 216:       'realm_secret_key' => $bright_secret_key,
 217:       'user_email' => $user->user_email);
 218: 
 219:     if ($course_provider_id)
 220:       $query_data['course_provider_id'] = $course_provider_id;
 221:     else
 222:       if (!empty($bright_scorm_cloud_app_id) && !empty($bright_scorm_cloud_secret_key)) {
 223:         $query_data['sc_app_id'] = $bright_scorm_cloud_app_id;
 224:         $query_data['sc_secret_key'] = $bright_scorm_cloud_secret_key;
 225:       }
 226: 
 227:     if (!empty($bright_realm_guid) && !empty($bright_secret_key)) {
 228:       $query_data['realm_guid'] = $bright_realm_guid;
 229:       $query_data['realm_secret_key'] = $bright_secret_key;
 230:     }
 231: 
 232:     $auth_url = $api_root.'/api_key';
 233: 
 234:     $json = bright_curl($auth_url, 'POST', $query_data);
 235:     if ($bright_curl_error) {
 236:       bright_log("bright_get_authentication_code_for_user: call to {$auth_url} failed: \"{$bright_curl_error}\"");
 237:       return null;
 238:     }
 239:     $json_data = json_decode($json);
 240:     $bright_token = $json_data->access_token;
 241:     return $bright_token;
 242:   }
 243: }
 244: 
 245: /*
 246:  * Call Bright API with a course ID.
 247:  */
 248: 
 249: function bright_call_api_for_course($api_call,$api_key,$course) {
 250:   $api_root = get_option('bright_api_url');
 251:   if (!empty($course)) {
 252:     $auth_url = $api_root . '/' . $api_call . '?' . http_build_query(array(
 253:       'format' => 'json',
 254:       'api_key' => $api_key,
 255:       'course_guid' => $course));
 256:   } else {
 257:     $auth_url = $api_root . '/' . $api_call . '?' . http_build_query(array(
 258:       'format' => 'json',
 259:       'api_key' => $api_key));
 260:   }
 261:   $results = bright_curl($auth_url);
 262:   return $results;
 263: }
 264: 
 265: function bright_get_user() {
 266:   return wp_get_current_user();
 267: }
 268: 
 269: function bright_run_stored_query($name,$params) {
 270:   $api_root = get_option('bright_api_url');
 271:   $controller = "stored_query";
 272:   $url = $api_root . '/' . $controller . '/run?' . http_build_query(array(
 273:     'format' => 'json',
 274:     'name' => $name,
 275:     'api_key' => bright_get_authentication_code_for_user(bright_get_user()))) . $params;
 276: 
 277:   $results = bright_curl($url);
 278:   return $results;
 279: }
 280: 
 281: function bright_get_course_list_with_registrations($api_key) {
 282: 
 283: 
 284:   $api_root = get_option('bright_api_url');
 285:   $controller = 'course';
 286:   if (strstr($api_root,"v1")) {
 287:     $controller = 'scorm_cloud_course';
 288:   }
 289: 
 290:   $auth_url = $api_root . '/' . $controller . '?' . http_build_query(array(
 291:     'format' => 'json',
 292:     'api_key' => $api_key,
 293:     'include_registrations' => 1,
 294:     'refresh_if_launched' => 1,
 295:   ));
 296: 
 297:   $results = bright_curl($auth_url);
 298:   return $results;
 299: }
 300: 
 301: function bright_get_registration_list($api_key) {
 302:   $api_root = get_option('bright_api_url');
 303:   $api_call = 'registration';
 304:   if (strstr($api_root,"v1")) {
 305:     $api_call = 'scorm_cloud_registration';
 306:   }
 307:   $auth_url = $api_root . '/' . $api_call . '?' . http_build_query(array(
 308:     'format' => 'json',
 309:     'api_key' => $api_key));
 310:   $results = bright_curl($auth_url);
 311:   return $results;
 312: }
 313: 
 314: 
 315: /**
 316:  * Get course data from bright server
 317:  */
 318: function bright_get_course_data($api_key, $course) {
 319:   $api_call = 'course';
 320:   $api_root = get_option('bright_api_url');
 321:   if (strstr($api_root,"v1")) {
 322:     $api_call = 'scorm_cloud_course';
 323:   }
 324: 
 325:   return bright_call_api_for_course($api_call,$api_key,$course);
 326: }
 327: 
 328: function bright_get_reportage_urls($api_key) {
 329:   $api_root = get_option('bright_api_url');
 330:   $api_call = 'util/reportage_urls';
 331:   $auth_url = $api_root . '/' . $api_call . '?' .
 332:     http_build_query(array('format' => 'json', 'api_key' => $api_key));
 333:   $json = bright_curl($auth_url);
 334:   $json_data = json_decode($json);
 335:   return $json_data;
 336: }
 337: 
 338: function bright_get_template_data($api_key, $template) {
 339:   $api_call = 'template';
 340:   $api_root = get_option('bright_api_url');
 341:   $auth_url = $api_root . '/' . $api_call . '?' . http_build_query(array(
 342:     'api_key' => $api_key,
 343:     'format' => 'json',
 344:     'name' => $template));
 345:   $json = bright_curl($auth_url);
 346:   $json_data = json_decode($json);
 347:   return $json_data[0]->body;
 348: }
 349: 
 350: /**
 351:  * Get registration data from bright server
 352:  */
 353: function bright_get_registration_data($api_key, $course) {
 354:   $api_call = 'registration';
 355:   $api_root = get_option('bright_api_url');
 356:   if (strstr($api_root,"v1"))
 357:     $api_call = 'scorm_cloud_registration';
 358: 
 359:   $auth_url = $api_root . '/' . $api_call . '?' . http_build_query(array(
 360:     'format' => 'json',
 361:     'api_key' => $api_key,
 362:     'refresh_if_launched' => 1,
 363:     // fetch only the last record; TODO; not sure if we should be doing this.  Bright.js will set 'registration' to the latest record.  As it stands now
 364:     // you couldn't write a standard template that showed more than one registration.  BUT a courselister can!
 365:     'last_only' => 1,
 366:     'course_guid' => $course));
 367:   return bright_curl($auth_url);
 368: }
 369: 
 370: /* DEPRECATED: use Bright::register_user_to_course() */
 371: function bright_register_user_to_course($api_key,$user_email,$course) {
 372:   $api_call = 'registration';
 373:   $api_root = get_option('bright_api_url');
 374:   if (strstr($api_root,"v1")) 
 375:     $api_call = 'scorm_cloud_registration';
 376: 
 377:   $query_params = array(
 378:     'api_key' => $api_key,
 379:     'dont_duplicate' => 1,
 380:     'format' => 'json',
 381:     'course_guid' => $course);
 382:   if (! empty($user_email)) {
 383:     $query_params['learner_id'] = $user_email;
 384:   }
 385:   $auth_url = $api_root . '/' . $api_call . '/gcreate?' . http_build_query($query_params);
 386:   return bright_curl($auth_url);
 387: }
 388: 
 389: /**
 390:  * Load JavaScript required for launch boxes
 391:  */
 392: 
 393: function bright_stop() {
 394:  if (in_the_loop()) {
 395:    $post_id = get_the_ID();
 396: 
 397:    if(!empty($post_id)) {
 398:      $bright_stop = get_post_meta($post_id,'bright-stop',true);
 399:      if (!empty($bright_stop))
 400:        return true;
 401:    }
 402:    return false;
 403:  }
 404:  return false;
 405: }
 406: 
 407: function bright_load_scripts() {
 408:   if (bright_stop())
 409:     return;
 410: 
 411:   wp_enqueue_script('jquery-i18n',
 412:     plugins_url('jquery.i18n.min.js', __FILE__),
 413:     array('jquery'));
 414:   wp_enqueue_script('handlebars',
 415:     plugins_url('handlebars-v3.0.1.js', __FILE__),
 416:     array('jquery'));
 417:   wp_enqueue_script('bright-lang',
 418:     plugins_url('bright.lang.js', __FILE__),
 419:     array('bright'));
 420:   wp_enqueue_script('underscore5',
 421:     plugins_url('underscore-min-1.5.1.js',__FILE__),
 422:     array('jquery'));
 423:   $bright_js = plugin_dir_path( __FILE__ ) . "/bright.js";
 424:   if(file_exists($bright_js)) {
 425:     wp_enqueue_script('bright',
 426:                       plugins_url('bright.js', __FILE__),
 427:                       array('jquery-i18n','handlebars','underscore5'));
 428:   } else {
 429:     wp_enqueue_script('bright',
 430:                       plugins_url('bright.min.js', __FILE__),
 431:                       array('jquery-i18n','handlebars','underscore5'));
 432:   }
 433: 
 434:   /* wp_register_style( 'jquery_ui_css', plugins_url('jquery-ui.min.js',__FILE__), false, '1.0.0' ); */
 435:   /* wp_enqueue_style( 'jquery_ui_css' ); */
 436: 
 437:   wp_register_style( 'bright_css', plugins_url('bright.css',__FILE__), false, '1.0.0' );
 438:   wp_enqueue_style( 'bright_css' );
 439: 
 440: }
 441: add_action('wp_enqueue_scripts', 'bright_load_scripts');
 442: 
 443: /**
 444:  * Add bright auth token to meta tag for Javascript access.
 445:  *
 446:  * Has the side-effect of setting $bright_token global.
 447:  */
 448: 
 449: function bright_check_compat() {
 450:   global $bright_usermeta_export;
 451: 
 452:   if (isset($bright_usermeta_export))
 453:     return('<div class="error">The support of $bright_usermeta_export was removed in Bright 6.0+.  Please remove this from your site and use the UserMeta Sync bright setting for this.</div>');
 454: }
 455: 
 456: 
 457: function bright_fetch_user_attributes($current_user) {
 458:   $bright_usermeta_export_raw = get_option("bright_usermeta_export");
 459:   // Set this to an empty array, just in case the option is empty. -TL
 460:   $usermeta_export = array();
 461:   // preg_split will produce a one element array in those cases, so
 462:   // let's make sure there is actually content. -TL
 463:   if (strlen($bright_usermeta_export_raw) > 0)
 464:     $usermeta_export = preg_split('/,/',$bright_usermeta_export_raw);
 465: 
 466:   $user_attributes = array();
 467: 
 468:   if (! empty($usermeta_export)) {
 469:     $usermeta = array();
 470:     foreach ($usermeta_export as $meta_key) {
 471:       // Interesting quirk to get_user_meta. If $meta_key was a zero-length
 472:       // string in the following statement, it would return ALL of the
 473:       // metadata! This is not desirable to us here. -TL
 474:       if (strlen($meta_key) > 0) {
 475:         $result = get_user_meta($current_user->ID, $meta_key,true);
 476:         $usermeta[$meta_key] = $result;
 477:       }
 478:     }
 479:     $user_attributes['meta'] = $usermeta;
 480:   }
 481: 
 482:   $user_attributes['site_roles'] = array();
 483: 
 484:   $user_attributes['email'] = bright_get_user()->user_email;
 485: 
 486:   if ($current_user->{'roles'}) {
 487:     foreach($current_user->{'roles'} as $role) {
 488:       $user_attributes['site_roles'][$role] = true;
 489:     }
 490:   }
 491: 
 492:   $user_attributes['avatar'] = bright_get_avatar_url(get_avatar( $current_user->ID));
 493: 
 494:   // If BuddyPress is installed and group functionality is on,
 495:   // we should include the user's BuddyPress groups.
 496:   if (function_exists('bp_has_groups') && bp_has_groups()) {
 497:     $groups = groups_get_groups(array(
 498:       'user_id' => $current_user->id,
 499:     ));
 500:     $user_attributes['groups'] = array_map(function ($group) {
 501:       return array(
 502:         'id' => $group->id,
 503:         'slug' => $group->slug,
 504:         'name' => $group->name,
 505:       );
 506:     }, $groups['groups']);
 507:   }
 508: 
 509:   return $user_attributes;
 510: }
 511: 
 512: function bright_add_token_tag() {
 513:   // TODO: Ticket #398.
 514:   global $bright_token;
 515: 
 516:   if ( ! is_user_logged_in() ) {
 517:     return;
 518:   }
 519: 
 520:   if (bright_stop())
 521:     return;
 522: 
 523:   bright_set_current_course_provider();
 524:   if (empty($bright_token)) {
 525:     $bright_token = bright_get_authentication_code_for_user(bright_get_user());
 526:   }
 527:   if (empty($bright_token))
 528:     return;
 529:   $providers = bright_get_course_providers($bright_token);
 530:   $api_url = get_option('bright_api_url');
 531: 
 532:   $current_user = bright_get_user();
 533:   $first_name = get_user_meta($current_user->ID, "first_name",true);
 534:   $last_name = get_user_meta($current_user->ID, "last_name",true);
 535:   $email = $current_user->user_email;
 536: 
 537:   $user_attributes = json_encode(bright_fetch_user_attributes(bright_get_user()));
 538: 
 539:   $as = "addslashes";
 540: 
 541:   global $bright_js_for_footer;
 542:   $usermetajs = <<<EOF
 543: var bright_user_attributes = "{$as($user_attributes)}";
 544: EOF;
 545: 
 546:   $footer_js =  <<<EOF
 547: // http://blog.errorception.com/2012/11/capture-custom-data-with-your-errors.html
 548: 
 549: if (typeof (_errs) === "undefined")
 550:   _errs = {};
 551: 
 552: _errs.meta = {
 553:   api_key: '{$bright_token}',
 554:   email: '{$email}',
 555:   api_url: '{$api_url}'
 556: };
 557: EOF;
 558: 
 559:   echo bright_return_as_javascript($usermetajs);
 560: 
 561:   echo "<meta name='bright-token' content='$bright_token'/>\n";
 562:   echo "<meta name='bright-api-url' content='$api_url'/>\n";
 563:   echo "<meta name='bright-first-name' content='$first_name'/>\n";
 564:   echo "<meta name='bright-last-name' content='$last_name'/>\n";
 565:   echo "<meta name='bright-email' content='$email'/>\n";
 566: 
 567:   $bright_js_for_footer .= bright_return_as_javascript($footer_js);
 568: }
 569: 
 570: add_action('wp_head', 'bright_add_token_tag');
 571: add_action('admin_head', 'bright_add_token_tag');
 572: 
 573: function bright_load_custom_wp_admin_style() {
 574:   global $wp_scripts;
 575:   $ui = $wp_scripts->query('jquery-ui-core');
 576:   wp_enqueue_script( 'jquery-ui-dialog');
 577:   if (!wp_style_is('jquery-ui')) {
 578:     wp_enqueue_style('jquery-ui', 'https://ajax.googleapis.com/ajax/libs/jqueryui/'.$ui->ver.'/themes/cupertino/jquery-ui.css');
 579:   }
 580:   // Only load the GWT stuff on the admin page.
 581:   if (get_current_screen()->id == 'bright_page_bright_options_admin') {
 582:     wp_register_style( 'bright_settings_css', plugins_url('BrightSettings.css',__FILE__), false, '1.0.0' );
 583:     wp_enqueue_style( 'bright_settings_css' );
 584:     wp_enqueue_script( 'bright_settings_js', plugins_url('/brightsettings/brightsettings.nocache.js', __FILE__) );
 585: 
 586:   }
 587: }
 588: add_action( 'admin_enqueue_scripts', 'bright_load_custom_wp_admin_style' );
 589: add_action( 'wp_footer', 'dump_bright_js_for_footer');
 590: 
 591: function dump_bright_js_for_footer() {
 592:   global $bright_js_for_footer;
 593: 
 594:   if (bright_stop())
 595:     return;
 596: 
 597:   echo $bright_js_for_footer;
 598: }
 599: 
 600: /* Filter: bright_templates */
 601: /* Function: Allows a plugin developer to modify the global $bright_embedder_templates on the fly */
 602: 
 603: function bright_fetch_template_text($template) {
 604:   global $bright_embedder_templates;
 605:   global $bright_token;
 606: 
 607:   $bright_embedder_templates = apply_filters('bright_templates',$bright_embedder_templates);
 608: 
 609:   if(!empty($bright_embedder_templates[$template]))
 610:     $text = $bright_embedder_templates[$template];
 611:   else {
 612:     $text = bright_get_template_data($bright_token, $template);
 613:     if (empty($text))
 614:       $text = '<div class="error">No embedder template named ' . $template . ' found.  Please check the spelling and/or validate that the container plugin is enabled on this site.</div>';
 615:   }
 616:   return $text;
 617: }
 618: 
 619: 
 620: function bright_get_avatar_url($get_avatar){
 621:   preg_match("/src='(.*?)'/i", $get_avatar, $matches);
 622:   if (count($matches) > 0)
 623:     return $matches[1];
 624:   else
 625:     return null;
 626: }
 627: 
 628: function bright_support() {
 629:   return '<a href="mailto:support@aura-software.com">Bright Support</a>';
 630: }
 631: 
 632: /**
 633:  * Process bright shortcode
 634:  */
 635: function bright_rewrite_embed_code($attr, $content) {
 636:   global $bright_token;
 637:   global $bright_curl_error;
 638: 
 639:   do_action('before_bright_rewrite_embed_code');
 640: 
 641:   if (bright_stop())
 642:     return;
 643: 
 644:   $support_text = apply_filters("bright_support_text", bright_support());
 645: 
 646:   if (empty($bright_token)) {
 647:     $login_url = apply_filters('login_url','/wp-login.php');
 648:     $redirect = get_permalink();
 649:     if ($bright_curl_error) {
 650:       $text = "<div class=\"bright_cannot_connect\">An error occurred connecting to the bright server: \"{$bright_curl_error}\".<br/>Please refresh the page to try again or contact us at $support_text if the problem persists.   <br/><strong>Please include the following information:</strong><br/><br/>";
 651:       $text .= "<strong>User Agent: </strong>" . $_SERVER["HTTP_USER_AGENT"] . "<br/>";
 652:       $text .= "<strong>User Host: </strong>" . $_SERVER["HTTP_HOST"] . "<br/>";
 653:       $text .= "<strong>Request URI: </strong>" . $_SERVER["REQUEST_URI"] . "<br/>";
 654:       $text .= "<strong>User: </strong>" . bright_get_user()->user_email . "<br/>";
 655:       $text .= "<br/><br/>THANKS</div>";
 656:     } else 
 657:       $text = '<div class="bright_not_logged_in">Please <a href="' . $login_url . '?redirect_to=' .  urlencode($redirect) . '">login or register</a> to view this content.</div>';
 658: 
 659:     return apply_filters('bright_please_login',$text);
 660:   }
 661: 
 662:   $bright_token= bright_get_authentication_code_for_user(bright_get_user());
 663: 
 664:   /* embedder attributes get put into the embed content so they are available from the templates */
 665:   $embedder_attributes = json_encode($attr);
 666: 
 667:   global $post;
 668: 
 669:   $page_attributes = array();
 670:   $user_attributes = bright_fetch_user_attributes(bright_get_user());
 671: 
 672:   if ($post->ID) {
 673:     $post_id = $post->ID;
 674:     $image = wp_get_attachment_image_src( get_post_thumbnail_id( $post->ID ));
 675:     $page_attributes['featured_image'] = $image[0];
 676:     $page_attributes['id'] = $post->ID;
 677: 
 678:     $cats = array();
 679:     $categories = get_the_category();
 680:     if($categories){
 681:       foreach($categories as $cat) {
 682:         $cats[$cat->slug] = $cat;
 683:       }
 684:     }
 685:     $page_attributes['categories'] = $cats;
 686: 
 687:     $tags = array();
 688: 
 689:     $posttags = get_the_tags();
 690:     if ($posttags) {
 691:       foreach($posttags as $tag) {
 692:         $tags[$tag->slug] = $tag;
 693:       }
 694:     }
 695:     $page_attributes['tags'] = $tags;
 696:   }
 697: 
 698:   global $bright_js_for_footer;
 699: 
 700:   $page_attributes = json_encode($page_attributes);
 701:   $user_attributes = json_encode($user_attributes);
 702: 
 703:   $course_locale = isset($attr['locale']) ? $attr['locale'] : '';
 704:   if (isset($attr['class']))
 705:     $embed_class = $attr['class'];
 706: 
 707:   $template = $attr['template'];
 708:   /* don't render this template */
 709:   /* the basic use of this is in writing documentation about the bright embedder */
 710:   /* usering ignore="true" means we can actually get the embed code out to the web page */
 711:   /* since we don't get any formatting, bold='' lets us geta little bit of styling inthere.
 712:      pretty rickety though */
 713: 
 714:   if (isset($attr['ignore'])) {
 715:     $ignore = $attr['ignore'];
 716:     $bold = $attr['bold'];
 717:     $ret_text = '[bright ';
 718:     foreach ($attr as $k => $v) {
 719:       if ($k == "ignore" || $k == "bold")
 720:         1;
 721:       else
 722:         if ($k == $bold)
 723:           $ret_text .= "<strong>{$k}=\"{$v}\"</strong> ";
 724:         else
 725:           $ret_text .= "{$k}=\"{$v}\" ";
 726:     }
 727:     $ret_text .="][/bright]";
 728:     return $ret_text;
 729:   }
 730:   /* add a CSS class to the bright <div> which includes the template name
 731:      set it to bright-template-inline if there's no template */
 732:   $template_class = "bright-template-";
 733:   if (empty($template))
 734:     $template_class .= 'inline';
 735:   else
 736:     $template_class .= $template;
 737: 
 738:   $type = isset($attr['type']) ? $attr['type'] : null;
 739:   // id allows us defined a unique ID for this launch box, as opposed to using the default.
 740:   if (isset($attr['id']))
 741:     $id = $attr['id'];
 742: 
 743:   if(!empty($template))
 744:     $content = bright_fetch_template_text($template);
 745: 
 746:   if(empty($type))
 747:     $type = "course";
 748: 
 749:   $new_content = '';
 750: 
 751:   if ($type == "course") {
 752:     /* the $template_class adds a CSS class to the encapsulating div so all templates of a type can be styled via one block of CSS */
 753:     if (empty($embed_class))
 754:       $embed_class = "bright-launchbox";
 755: 
 756:     $course_id = $attr['course'];
 757:     $course_id = apply_filters('bright_course_id',
 758:                                $course_id,
 759:                                array('attr' => $attr));
 760: 
 761:     if (empty($course_id)) {
 762:       $course_id = $_GET['bright_course_id'];
 763:       if (empty($course_id))
 764:         return '<div class="bright-error">Bright: No course ID set in your [bright] embed code.</div>';
 765:     }
 766: 
 767:     if (empty($id))
 768:       $id = $course_id;
 769: 
 770:     $container_id = md5(microtime());
 771:     $raw_course_data = bright_get_course_data($bright_token, $course_id);
 772: 
 773:     if (strlen($raw_course_data) < 3)
 774:       return '<div class="bright-error">Bright: No course with ID of ' . $course_id . ' was found.</div>';
 775: 
 776:     if (! empty($raw_course_data)) {
 777:       $bright_js_for_footer .= bright_return_as_javascript("if (typeof bright_courses === 'undefined') {bright_courses = {};}");
 778:       $bright_js_for_footer .= bright_return_as_javascript("bright_courses['" . $course_id . "'] = " . substr($raw_course_data,1,-1) . ";");
 779:     }
 780:     $raw_registration_data = bright_get_registration_data($bright_token, $course_id);
 781:     if (! empty($raw_registration_data)) {
 782:       $bright_js_for_footer .= bright_return_as_javascript("bright_courses['" . $course_id . "']['registrations'] = " . $raw_registration_data . ";");
 783:     }
 784: 
 785:     /* blowing up?  Before Bright 4.1, this call was wrong and had a bogus argument #, and arguments 3 and 4 were switched*/
 786:     $raw_course_data = apply_filters('bright_extend_on_course',$raw_course_data,$course_id,$raw_registration_data);
 787:     $course_data = json_decode($raw_course_data);
 788:     $customData = $course_data[0]->{'custom'};
 789:     $embed=rawurlencode($content);
 790: 
 791:     $as = "addslashes"; // Only way to get it to work inside the EOF
 792:     $template_js = <<<EOF
 793: Bright.launchBoxTemplates["{$as($container_id)}"] = {
 794:   courseId: "{$as($course_id)}",
 795:   embedLocale: "{$as($course_locale)}",
 796:   embedClass: "{$as($embed_class)}",
 797:   embedType: "{$as($type)}",
 798:   embedAttributes: "{$as($embedder_attributes)}",
 799:   pageAttributes: "{$as($page_attributes)}",
 800:   userAttributes: "{$as($user_attributes)}",
 801:   customData: "{$as($customData)}",
 802:   template: "{$as($embed)}",
 803:   isRendered: false
 804: };
 805: EOF;
 806: $bright_js_for_footer .= bright_return_as_javascript($template_js);
 807: 
 808:     $new_content = <<<EOF
 809: <div id="bright-launchbox-{$as($container_id)}" class="bright-embedder {$as($template_class)} {$as($embed_class)}"></div>
 810: EOF;
 811: 
 812:   } else if ($type === "courselist") {
 813:     if (empty($id)) {
 814:       $id = strval(rand());
 815:     }
 816:     $container_id = md5($id);
 817: 
 818:     if (empty($embed_class)) {
 819:       $embed_class = "bright-courselist";
 820:     }
 821: 
 822:     global $render_course_list;
 823:     global $bright_course_list;
 824:     if (empty($render_course_list)) {
 825:       // doing this once should be enough.
 826:       $bright_course_list = bright_get_course_list_with_registrations($bright_token,NULL);
 827:       if ($bright_course_list) {
 828:         $bright_js_for_footer .= bright_return_as_javascript("var bright_courselist = {$bright_course_list};");
 829:       }
 830:       else {
 831:         $bright_js_for_footer .= bright_return_as_javascript("var bright_courselist = [];");
 832:       }
 833:       $render_course_list = true;
 834:     }
 835: 
 836:     $customData = apply_filters('bright_extend_on_courselist',$bright_course_list,$attr);
 837: 
 838:     $embed=rawurlencode($content);
 839: 
 840:     $as = "addslashes"; // Only way to get it to work inside the EOF
 841: 
 842:     $template_js = <<<EOF
 843: Bright.courseListTemplates["{$as($container_id)}"] = {
 844:   embedLocale: "{$as($course_locale)}",
 845:   embedClass: "{$as($embed_class)}",
 846:   embedType: "{$as($type)}",
 847:   embedAttributes: "{$as($embedder_attributes)}",
 848:   pageAttributes: "{$as($page_attributes)}",
 849:   userAttributes: "{$as($user_attributes)}",
 850:   customData: "{$as($customData)}",
 851:   template: "{$as($embed)}",
 852:   isRendered: false
 853: };
 854: EOF;
 855: 
 856: $template_js = <<<EOF
 857: Bright.setCourseListTemplate("{$as($container_id)}", {
 858:   embedLocale: "{$as($course_locale)}",
 859:   embedClass: "{$as($embed_class)}",
 860:   embedType: "{$as($type)}",
 861:   embedAttributes: "{$as($embedder_attributes)}",
 862:   pageAttributes: "{$as($page_attributes)}",
 863:   userAttributes: "{$as($user_attributes)}",
 864:   customData: "{$as($customData)}",
 865:   template: "{$as($embed)}",
 866:   isRendered: false
 867: });
 868: EOF;
 869: 
 870: $bright_js_for_footer .= bright_return_as_javascript($template_js);
 871: 
 872:     $new_content = <<<EOF
 873: <div id="bright-courselist-{$as($container_id)}" class="{$as($template_class)} {$as($embed_class)}"></div>
 874: EOF;
 875: 
 876:   } else {
 877:     $new_content = '<div class="bright-error">Bright: No embedder of type ' . $type . ' found.</div>';
 878:   }
 879:   return $new_content;
 880: }
 881: 
 882: add_action('admin_print_footer_scripts', 'bright_add_quicktags');
 883: function bright_add_quicktags(){
 884:   global $bright_embedder_templates;
 885:   // Don't run if user doesn't have the rights
 886:   if (!current_user_can('edit_posts') && !current_user_can('edit_pages') ) {
 887:     return;
 888:   }
 889:   // Don't run if not a editor page
 890:   if(!(strstr($_SERVER['REQUEST_URI'], 'wp-admin/post-new.php') ||
 891:      strstr($_SERVER['REQUEST_URI'], 'wp-admin/post.php') ||
 892:      strstr($_SERVER['REQUEST_URI'], 'wp-admin/edit.php'))) {
 893:     return;
 894:   }
 895: 
 896:   $json_templates = json_encode($bright_embedder_templates);
 897:   $template_names = array_keys($bright_embedder_templates);
 898:   sort($template_names);
 899: ?>
 900: <div id="bright-embed-dialog">
 901:   <div>
 902:     <select class="course">
 903:       <option value="">Select a course</option>
 904:     </select>
 905:   </div>
 906:   <div>
 907:     <select class="template">
 908:       <option value="">Select a template</option>
 909:       <optgroup label="Local templates">
 910:         <?php
 911:           foreach($template_names as $name) {
 912:             echo "<option>".htmlspecialchars($name)."</option>";
 913:           }
 914:         ?>
 915:       </optgroup>
 916:     </select>
 917:     <input class="confirm insert" type="button" value="Embed Template"/>
 918:     <input class="confirm insert-all" type="button" value="Insert Template Contents"/>
 919:     <input class="cancel" type="button" value="Cancel"/>
 920:   </div>
 921: </div>
 922: 
 923: <script type="text/javascript" charset="utf-8">
 924: // <![CDATA[
 925:   jQuery.fn.insertAtCaret = function(text) {
 926:       return this.each(function() {
 927:           if (document.selection && this.tagName == 'TEXTAREA') {
 928:               //IE textarea support
 929:               this.focus();
 930:               sel = document.selection.createRange();
 931:               sel.text = text;
 932:               this.focus();
 933:           } else if (this.selectionStart || this.selectionStart == '0') {
 934:               //MOZILLA/NETSCAPE support
 935:               startPos = this.selectionStart;
 936:               endPos = this.selectionEnd;
 937:               scrollTop = this.scrollTop;
 938:               this.value = this.value.substring(0, startPos) + text + this.value.substring(endPos, this.value.length);
 939:               this.focus();
 940:               this.selectionStart = startPos + text.length;
 941:               this.selectionEnd = startPos + text.length;
 942:               this.scrollTop = scrollTop;
 943:           } else {
 944:               // IE input[type=text] and other browsers
 945:               this.value += text;
 946:               this.focus();
 947:               this.value = this.value;    // forces cursor to end
 948:           }
 949:       });
 950:   };
 951: 
 952:   (function(){
 953:     var url = jQuery('meta[name=bright-api-url]').attr('content');
 954:     var token = jQuery('meta[name=bright-token]').attr('content');
 955:     var BrightTemplates = <?php echo $json_templates; ?>;
 956: 
 957:     jQuery('#bright-embed-dialog').dialog({
 958:       autoOpen: false,
 959:       minWidth: 800
 960:     });
 961:     jQuery('#bright-embed-dialog select').change(function () {
 962:       var courseId = jQuery('#bright-embed-dialog select.course').val();
 963:       var templateName = jQuery('#bright-embed-dialog select.template').val();
 964:       if (courseId && templateName) {
 965:         jQuery('#bright-embed-dialog .confirm').button('option', 'disabled', false);
 966:       }
 967:       else {
 968:         jQuery('#bright-embed-dialog .confirm').button('option', 'disabled', true);
 969:       }
 970:     });
 971:     jQuery('#bright-embed-dialog input').button();
 972:     jQuery('#bright-embed-dialog .confirm').button('option', 'disabled', true);
 973:     jQuery('#bright-embed-dialog .insert').click(function () {
 974:       var courseId = jQuery('#bright-embed-dialog select.course').val();
 975:       var templateName = jQuery('#bright-embed-dialog select.template').val();
 976:       jQuery('#content').insertAtCaret(
 977:         '[bright course="' + courseId + '" template="' + templateName + '"/]'
 978:       );
 979:       jQuery('#bright-embed-dialog').dialog('close');
 980:     });
 981:     jQuery('#bright-embed-dialog .insert-all').click(function () {
 982:       var courseId = jQuery('#bright-embed-dialog select.course').val();
 983:       var templateName = jQuery('#bright-embed-dialog select.template').val();
 984:       jQuery('#content').insertAtCaret(
 985:         '[bright course="' + courseId + '"]' + "\n" +
 986:             BrightTemplates[templateName] +
 987:             "\n[/bright]"
 988:       );
 989:       jQuery('#bright-embed-dialog').dialog('close');
 990:     });
 991:     jQuery('#bright-embed-dialog .cancel').click(function () {
 992:       jQuery('#bright-embed-dialog').dialog('close');
 993:     });
 994: 
 995:     var controller = 'course';
 996:     if (url.match(/v1/)) {
 997:       controller = 'scorm_cloud_course';
 998:     }
 999: 
1000:     jQuery.ajax({
1001:       url:url + '/' + controller,
1002:       data:{
1003:         api_key:token,
1004:         format:'json'
1005:       },
1006:       dataType:'jsonp',
1007:       success:function (data) {
1008:         for (var i = 0; i < data.length; i++) {
1009:           jQuery('#bright-embed-dialog select.course').append(
1010:             '<option value="' + data[i].course_guid + '">' +
1011:                 data[i].title + '</option>'
1012:           );
1013:         }
1014:       }
1015:     });
1016: 
1017:     jQuery.ajax({
1018:       url:url + '/template',
1019:       data:{
1020:         api_key:token,
1021:         format:'json'
1022:       },
1023:       dataType:'jsonp',
1024:       success:function (data) {
1025:         optgroupCode = '<optgroup label="Templates from Bright">';
1026:         for (var i = 0; i < data.length; i++) {
1027:           optgroupCode += '<option value="' + data[i].name + '">' +
1028:               data[i].name + '</option>'
1029:           BrightTemplates[data[i].name] = data[i].body;
1030:         }
1031:         optgroupCode += '</optgroup>';
1032:         jQuery('#bright-embed-dialog select.template').append(
1033:           optgroupCode);
1034:       }
1035:     });
1036: 
1037:     if (QTags && QTags.addButton) { // Newer Wordpress, like 3.5.1
1038:       QTags.addButton('bright_embed', 'Bright Embed', function() {
1039:         jQuery('#bright-embed-dialog').dialog({autoOpen: true});
1040:       });
1041:     }
1042:     else { // Fallback to clumsy jQuery insert if older Wordpress
1043:       jQuery("#ed_toolbar").append('<input type="button" class="ed_button" onclick="jQuery(\'#bright-embed-dialog\').dialog({autoOpen: true});return false;" title="Insert a Bright Embed" value="Bright Embed"/>');
1044:     }
1045:   }());
1046: // ]]>
1047: </script>
1048: <?php
1049: }
1050: 
1051: 
API documentation generated by ApiGen