bbb.module in BigBlueButton 6
Same filename and directory in other branches
Big Blue Button - Enables universities and colleges to deliver a high-quality learning experience.
@author Stefan Auditor <stefan.auditor@erdfisch.de>
TODO:
- Add 'start meeting' button
- Rework waiting page
- do a seperate page with a big throbber, that tells the status of the meeeting, so that it's clear you have to wait here.
- Incorporate a Flash Player check, explain it and use the waiting time to adjust the audio/video settings
File
bbb.moduleView source
<?php
/**
* @file
* Big Blue Button - Enables universities and colleges to deliver a high-quality
* learning experience.
*
* @author
* Stefan Auditor <stefan.auditor@erdfisch.de>
*
* TODO:
* - Add 'start meeting' button
* - Rework waiting page
* - do a seperate page with a big throbber, that tells the status of the
* meeeting, so that it's clear you have to wait here.
* - Incorporate a Flash Player check, explain it and use the waiting time
* to adjust the audio/video settings
*/
// API version
define('BBB_API_VERSION', variable_get('bbb_api_version', NULL));
// Security Salt
// see /var/lib/tomcat6/webapps/bigbluebutton/WEB-INF/classes/bigbluebutton.properties
define('BBB_API_SECURITY_SALT', variable_get('bbb_security_salt', '76b71974198f26ecc5a594eddddf49d1'));
// Define default settings
define('BBB_DISPLAY_MODE', variable_get('bbb_display_mode', 'inline'));
define('BBB_DISPLAY_HEIGHT', variable_get('bbb_display_height', '580px'));
define('BBB_DISPLAY_WIDTH', variable_get('bbb_display_width', '100%'));
if (BBB_API_VERSION) {
include_once drupal_get_path('modules', 'bbb') . 'includes/api-' . BBB_API_VERSION . '.bbb.inc';
}
/* Drupal Hooks */
/**
* Implementation of hook_views_api().
*/
function bbb_views_api() {
return array(
'api' => 2,
'path' => drupal_get_path('module', 'bbb') . '/includes',
);
}
/**
* Implement hook_views_handlers().
*/
function bbb_views_handlers() {
return array(
'info' => array(
'path' => drupal_get_path('module', 'bbb') . '/includes',
),
'handlers' => array(
'views_handler_field_bbb_join_attendee' => array(
'parent' => 'views_handler_field',
),
'views_handler_field_bbb_join_moderator' => array(
'parent' => 'views_handler_field',
),
),
);
}
/**
* Implement HOOK_perm().
*/
function bbb_perm() {
return array(
'administer big blue button',
//TODO:
// 'start meetings',
// 'start own meetings',
'moderate meetings',
'moderate own meetings',
'attend meetings',
);
}
/**
* Implement HOOK_menu().
*/
function bbb_menu() {
$items = array();
$show_local_tasks = variable_get('bbb_local_tasks', 1);
$items['node/%node/meeting/attend'] = array(
'title' => 'Attend Meeting',
'page callback' => 'bbb_meeting_attend',
'page arguments' => array(
1,
),
'access callback' => 'bbb_access_attendee',
'access arguments' => array(
1,
),
'type' => $show_local_tasks ? MENU_LOCAL_TASK : MENU_CALLBACK,
'weight' => 2,
);
$items['node/%node/meeting/moderate'] = array(
'title' => 'Moderate Meeting',
'page callback' => 'bbb_meeting_moderate',
'page arguments' => array(
1,
),
'access callback' => 'bbb_access_moderator',
'access arguments' => array(
1,
),
'type' => $show_local_tasks ? MENU_LOCAL_TASK : MENU_CALLBACK,
'weight' => 2,
);
$items['node/%node/meeting/end-confirm'] = array(
'title' => 'Terminate Meeting',
'page callback' => 'drupal_get_form',
'page arguments' => array(
'bbb_end_confirm_form',
1,
),
'access callback' => 'bbb_access_moderator',
'access arguments' => array(
1,
),
'type' => MENU_CALLBACK,
);
$items['node/%node/redirect/attend'] = array(
'page callback' => 'bbb_redirect',
'page arguments' => array(
1,
3,
),
'access callback' => 'bbb_access_attendee',
'access arguments' => array(
1,
),
'type' => MENU_CALLBACK,
);
$items['node/%node/redirect/moderate'] = array(
'page callback' => 'bbb_redirect',
'page arguments' => array(
1,
3,
),
'access callback' => 'bbb_access_moderator',
'access arguments' => array(
1,
),
'type' => MENU_CALLBACK,
);
$items['node/%node/meeting/status'] = array(
'page callback' => 'bbb_status',
'page arguments' => array(
1,
),
'access callback' => 'bbb_access_attendee',
'access arguments' => array(
1,
),
'type' => MENU_CALLBACK,
'file' => 'includes/api-' . BBB_API_VERSION . '.bbb.inc',
);
$items['admin/settings/bigbluebutton'] = array(
'title' => 'Big Blue Button meetings',
'description' => 'Default server and meeting settings.',
'page callback' => 'drupal_get_form',
'page arguments' => array(
'bbb_settings',
),
'access arguments' => array(
'administer big blue button',
),
'type' => MENU_NORMAL_ITEM,
'file' => 'includes/pages.bbb.inc',
);
return $items;
}
/**
* Check attendance access permissions; Menu access callback
*/
function bbb_access_attendee($node) {
global $user;
if (!bbb_is_meeting_type($node->type)) {
return FALSE;
}
// Check for node access and access to attend meetings
if (node_access('view', $node) && (user_access('attend meetings') || user_access('administer big blue button'))) {
return TRUE;
}
return FALSE;
}
/**
* Check moderation access permissions; Menu access callback
*/
function bbb_access_moderator($node) {
global $user;
if (!bbb_is_meeting_type($node->type)) {
return FALSE;
}
// Check for node access and access start meetings
if (node_access('view', $node) && (user_access('moderate meetings') || user_access('administer big blue button') || $user->uid == $node->uid && user_access('moderate own meetings'))) {
return TRUE;
}
return FALSE;
}
/**
* Implement HOOK_block().
*/
function bbb_block($op = 'list', $delta = 0, $edit = array()) {
if ($op == 'list') {
$blocks[0] = array(
'info' => t('Meeting details'),
'weight' => 0,
'status' => 1,
'region' => 'left',
);
return $blocks;
}
elseif ($op == 'configure' && $delta == 0) {
}
elseif ($op == 'save' && $delta == 0) {
}
elseif ($op == 'view') {
switch ($delta) {
case 0:
$block = array(
'subject' => t('Meeting details'),
'content' => bbb_block_meeting(),
);
break;
}
return $block;
}
}
/**
* Meeting details block
*/
function bbb_block_meeting() {
$output = '';
if (arg(0) == 'node' && is_numeric(arg(1))) {
$meeting = bbb_get_meeting(arg(1));
if ($meeting) {
$output = theme('bbb_block_meeting', $meeting);
}
}
return $output;
}
/**
* Implement HOOK_form_alter().
*/
function bbb_form_alter(&$form, &$form_state, $form_id) {
// Node type settings form
if ($form_id == 'node_type_form') {
$bbb_api_version = variable_get('bbb_api_version', NULL);
$form['bbb'] = array(
'#title' => t('Big Blue Button settings'),
'#type' => 'fieldset',
'#collapsible' => TRUE,
'#collapsed' => TRUE,
);
if (!is_numeric($bbb_api_version)) {
$form['bbb']['#value'] = '<p>' . t('Please go to the !page and setup your Big Blue button server.', array(
'!page' => l(t('administration page'), 'admin/settings/bigbluebutton'),
)) . '</p>';
}
else {
$form['bbb']['bbb_content_type'] = array(
'#type' => 'checkbox',
'#title' => t('Treat this node type as meeting'),
'#default_value' => variable_get('bbb_content_type_' . $form['#node_type']->type, FALSE),
);
$form['bbb']['bbb_content_type_show_links'] = array(
'#type' => 'checkbox',
'#title' => t('Show links to attend, moderate or terminate a meeting beneath the node'),
'#default_value' => variable_get('bbb_content_type_show_links_' . $form['#node_type']->type, FALSE),
);
$form['bbb']['bbb_content_type_show_status'] = array(
'#type' => 'checkbox',
'#title' => t('Display meeting status on node'),
'#default_value' => variable_get('bbb_content_type_show_status_' . $form['#node_type']->type, FALSE),
);
$form['bbb']['bbb_content_type_welcome'] = array(
'#title' => t('Welcome message'),
'#type' => 'textfield',
'#default_value' => variable_get('bbb_content_type_welcome_' . $form['#node_type']->type, ''),
'#maxlength' => 255,
'#description' => t('A welcome message that gets displayed on the chat window when the participant joins. You can include keywords (%%CONFNAME%%, %%DIALNUM%%, %%CONFNUM%%) which will be substituted automatically.'),
);
$form['bbb']['bbb_content_type_dialNumber'] = array(
'#title' => t('Dial number'),
'#type' => 'textfield',
'#default_value' => variable_get('bbb_content_type_dialNumber_' . $form['#node_type']->type, ''),
'#maxlength' => 32,
'#description' => t('The dial access number that participants can call in using regular phone.'),
);
$form['bbb']['bbb_content_type_moderatorPW'] = array(
'#title' => t('Moderator password'),
'#type' => 'textfield',
'#default_value' => variable_get('bbb_content_type_moderatorPW_' . $form['#node_type']->type, ''),
'#maxlength' => 32,
'#description' => t('The password that will be required for moderators to join the meeting or for certain administrative actions (i.e. ending a meeting).'),
);
$form['bbb']['bbb_content_type_attendeePW'] = array(
'#title' => t('Attendee password'),
'#type' => 'textfield',
'#default_value' => variable_get('bbb_content_type_attendeePW_' . $form['#node_type']->type, ''),
'#maxlength' => 32,
'#description' => t('The password that will be required for attendees to join the meeting.'),
);
$form['bbb']['bbb_content_type_logoutURL'] = array(
'#title' => t('Logout URL'),
'#type' => 'textfield',
'#default_value' => variable_get('bbb_content_type_logoutURL_' . $form['#node_type']->type, ''),
'#maxlength' => 255,
'#description' => t('The URL that the Big Blue Button client will go to after users click the OK button on the <em>You have been logged out message</em>.'),
);
}
}
// Node edit form
$node_type = $form['type']['#value'];
if (drupal_substr($form_id, drupal_strlen($form_id) - 10, 10) == '_node_form' && bbb_is_meeting_type($node_type) && user_access('administer big blue button')) {
if (is_numeric($form['nid']['#value'])) {
$meeting = bbb_get_meeting($form['nid']['#value']);
}
$form['bbb'] = array(
'#title' => t('Meeting settings'),
'#type' => 'fieldset',
'#description' => t("The following settings maybe changed until the meeting first starts."),
'#collapsible' => TRUE,
'#collapsed' => TRUE,
'#tree' => TRUE,
);
$form['bbb']['welcome'] = array(
'#title' => t('Welcome message'),
'#type' => 'textfield',
'#default_value' => variable_get('bbb_content_type_welcome_' . $node_type, ''),
'#maxlength' => 255,
'#description' => t('A welcome message that gets displayed on the chat window when the participant joins. You can include keywords (%%CONFNAME%%, %%DIALNUM%%, %%CONFNUM%%) which will be substituted automatically.'),
'#attributes' => $meeting->meetingID ? array(
'disabled' => 'disabled',
) : array(),
);
$form['bbb']['dialNumber'] = array(
'#title' => t('Dial number'),
'#type' => 'textfield',
'#default_value' => variable_get('bbb_content_type_dialNumber_' . $node_type, ''),
'#maxlength' => 32,
'#description' => t('The dial access number that participants can call in using regular phone.'),
'#attributes' => $meeting->meetingID ? array(
'disabled' => 'disabled',
) : array(),
);
$form['bbb']['moderatorPW'] = array(
'#title' => t('Moderator password'),
'#type' => 'textfield',
'#default_value' => variable_get('bbb_content_type_moderatorPW_' . $node_type, ''),
'#maxlength' => 32,
'#description' => t('The password that will be required for moderators to join the meeting or for certain administrative actions (i.e. ending a meeting).'),
'#attributes' => $meeting->meetingID ? array(
'disabled' => 'disabled',
) : array(),
);
$form['bbb']['attendeePW'] = array(
'#title' => t('Attendee password'),
'#type' => 'textfield',
'#default_value' => variable_get('bbb_content_type_attendeePW_' . $node_type, ''),
'#maxlength' => 32,
'#description' => t('The password that will be required for attendees to join the meeting.'),
'#attributes' => $meeting->meetingID ? array(
'disabled' => 'disabled',
) : array(),
);
$form['bbb']['logoutURL'] = array(
'#title' => t('Logout URL'),
'#type' => 'textfield',
'#default_value' => variable_get('bbb_content_type_logoutURL_' . $node_type, ''),
'#maxlength' => 255,
'#description' => t('The URL that the Big Blue Button client will go to after users click the OK button on the <em>You have been logged out message</em>.'),
'#attributes' => $meeting->meetingID ? array(
'disabled' => 'disabled',
) : array(),
);
}
}
/**
* Implement HOOK_nodeapi().
*/
function bbb_nodeapi(&$node, $op, $a3 = NULL, $a4 = NULL) {
global $user;
if (!bbb_is_meeting_type($node->type)) {
return;
}
switch ($op) {
case 'insert':
// local storage
bbb_store_meeting($node, (array) $node->bbb);
break;
case 'update':
// local update
bbb_update_meeting($node, $node->bbb);
break;
case 'view':
//$status = bbb_get_user_status($node->nid, $user->uid);
if (!variable_get('bbb_content_type_show_status_' . $node->type, FALSE)) {
return;
}
$meeting = bbb_get_meeting($node->nid);
$node->content['bbb_meeting_status'] = array(
'#value' => theme('bbb_meeting_status', $meeting),
'#weight' => 10,
);
$node->content['bbb_meeting_start'] = array(
'#value' => theme('bbb_meeting_start', $meeting),
'#weight' => 10,
);
break;
case 'load':
if (bbb_is_meeting_type($node->type)) {
$node->bbb = bbb_get_meeting($node->nid);
}
break;
case 'delete':
bbb_delete_meeting($node->nid);
break;
}
}
/**
* Implement HOOK_link().
*/
function bbb_link($type, $object, $teaser = FALSE) {
$links = array();
if ($type == 'node' && bbb_is_meeting_type($object->type)) {
$show = variable_get('bbb_content_type_show_links_' . $object->type, FALSE);
if (!$teaser && $show) {
$meeting = bbb_get_meeting($object->nid);
if (user_access('attend meetings') || user_access('administer big blue button')) {
$links['bbb_meeting_attend'] = array(
'title' => t('Attend meeting'),
'href' => "node/{$object->nid}/meeting/attend",
);
}
if (user_access('moderate meetings') || user_access('administer big blue button') || $user->uid == $node->uid && user_access('moderate own meetings')) {
$links['bbb_meeting_moderate'] = array(
'title' => t('Moderate meeting'),
'href' => "node/{$object->nid}/meeting/moderate",
);
}
if (user_access('moderate meetings') || user_access('administer big blue button') || $user->uid == $node->uid && user_access('moderate own meetings') && $meeting->running) {
$links['bbb_meeting_end'] = array(
'title' => t('Terminate meeting'),
'href' => "node/{$object->nid}/meeting/end-confirm",
);
}
}
}
return $links;
}
/**
* Implement HOOK_theme().
*/
function bbb_theme($existing, $type, $theme, $path) {
return array(
'bbb_meeting' => array(
'arguments' => array(
'meeting' => NULL,
'mode' => NULL,
'params' => array(),
),
),
'bbb_meeting_status' => array(
'arguments' => array(
'meeting' => NULL,
),
),
'bbb_meeting_join_moderator' => array(
'arguments' => array(
'meeting' => NULL,
),
),
'bbb_meeting_join_attendee' => array(
'arguments' => array(
'meeting' => NULL,
),
),
'bbb_block_meeting' => array(
'arguments' => array(
'meeting' => NULL,
),
),
);
}
/* Helper functions */
/**
* Check if user is meeting owner
*/
function bbb_is_meeting_owner($nid, $account = NULL) {
if (!$account) {
global $user;
$account = $user;
}
$sql = "SELECT COUNT(nid) FROM {bbb_meetings} bm\n INNER JOIN {node} n ON bm.nid = n.nid\n WHERE n.uid = %d\n AND nid = %d";
$owner = db_result(db_query($sql, $account->uid, $nid));
return $owner ? TRUE : FALSE;
}
/**
* Check if node type is meeting
*/
function bbb_is_meeting_type($type) {
return variable_get('bbb_content_type_' . $type, FALSE);
}
/**
* Return a meeting object
*/
function bbb_get_meeting($nid, $account = NULL, $cached = TRUE) {
// Simple static cache
static $meetings = array();
if (!$account) {
global $user;
$account = $user;
}
if (!isset($meetings[$nid]) || !$cached) {
$meeting = new stdClass();
$meeting = db_fetch_object(db_query("SELECT * FROM {bbb_meetings} WHERE nid = %d", $nid));
if ($meeting) {
$meeting->running = bbb_api_isMeetingRunning(array(
'meetingID' => $meeting->meetingID,
))->running ? TRUE : FALSE;
$meeting->url = array(
'attend' => bbb_api_join(array(
'fullName' => $account->name,
'meetingID' => $meeting->meetingID,
'password' => $meeting->attendeePW,
)),
'moderate' => bbb_api_join(array(
'fullName' => $account->name,
'meetingID' => $meeting->meetingID,
'password' => $meeting->moderatorPW,
)),
'end' => bbb_api_end(array(
'meetingID' => $meeting->meetingID,
'password' => $meeting->moderatorPW,
)),
);
// Allow alteration for e.g. access control
// Just implement hook_bbb_meeting_alter(&$data) {} in your module
drupal_alter('bbb_meeting', $meeting);
// Static cache
$meetings[$nid] = $meeting;
}
}
return isset($meetings[$nid]) ? $meetings[$nid] : FALSE;
}
/**
* Init meeting
*/
function bbb_init_meeting($node = NULL, $params = array()) {
$welcome = variable_get('bbb_content_type_welcome_' . $node->type, '');
$dialNumber = variable_get('bbb_content_type_dialNumber_' . $node->type, '');
$moderatorPW = variable_get('bbb_content_type_moderatorPW_' . $node->type, '');
$attendeePW = variable_get('bbb_content_type_attendeePW_' . $node->type, '');
$logoutURL = variable_get('bbb_content_type_logoutURL_' . $node->type, '');
$settings = array(
'nid' => $node->nid,
'name' => $node->title,
'meetingID' => bbb_create_meeting_id($node->nid),
'attendeePW' => !empty($attendeePW) ? $attendeePW : user_password(),
'moderatorPW' => !empty($moderatorPW) ? $moderatorPW : user_password(),
'welcome' => !empty($welcome) ? $welcome : t('Welcome to @title', array(
'@title' => $node->title,
)),
'dialNumber' => $dialNumber ? $dialNumber : NULL,
// TODO: This is limited to 90000 voice bridges and may
// collide sooner, as rand() may return x twice in a row
'voiceBridge' => rand(70000, 79999),
'logoutURL' => $logoutURL,
//TODO: make absolute, as soon as supported
'initialized' => 0,
'created' => time(),
);
$params = array_merge($params, $settings);
return $params;
}
/**
* Update meeting
*/
function bbb_update_meeting($node, $params = array()) {
$params += bbb_init_meeting($node, $params);
return drupal_write_record('bbb_meetings', $params, 'nid');
}
/**
* Create meeting
*/
function bbb_create_meeting($node, $params = array()) {
$params += bbb_init_meeting($node, $params);
if ($data = bbb_api_create($params)) {
return $data;
}
return FALSE;
}
/**
* Store meeting
*/
function bbb_store_meeting($node, $params = array()) {
$params += bbb_init_meeting($node, $params);
return drupal_write_record('bbb_meetings', $params);
}
/**
* Delete meeting
*/
function bbb_delete_meeting($nid) {
return db_query("DELETE FROM {bbb_meetings} WHERE nid = %d", $nid);
}
/* Menu Callbacks */
/**
* Return meeting status; Menu callback
*/
function bbb_status($node) {
$meeting = bbb_get_meeting($node->nid);
drupal_json(array(
'running' => $meeting->running,
));
die;
}
/**
* Redirect to big blue button instance; Menu callback
*
* @param OBJECT $node
* A Drupal node object
*/
function bbb_meeting_attend($node) {
global $user;
$url = array();
$mode = 'attend';
$meeting = bbb_get_meeting($node->nid);
$params = array(
'meetingID' => $meeting->meetingID,
'password' => $meeting->moderatorPW,
);
$status = bbb_api_getMeetingInfo($params);
if ($status->hasBeenForciblyEnded == 'true') {
drupal_set_message('The meeting has been terminated and is not available for attending.');
drupal_goto('node/' . $node->nid);
}
drupal_set_title($node->title);
if ($meeting->running) {
if (BBB_DISPLAY_MODE == 'blank') {
bbb_redirect($node, $mode);
}
}
else {
drupal_add_js('var bbb_check_status_url = ' . drupal_to_js(url('node/' . $node->nid . '/meeting/status')), 'inline');
drupal_add_js(drupal_get_path('module', 'bbb') . '/js/check_status.bbb.js');
drupal_set_message(t('You signed up for this meeting. Please stay on this page, you will be redirected immediately after the meeting has started.'));
return node_show($node, NULL);
}
return theme('bbb_meeting', $meeting, $mode, BBB_DISPLAY_HEIGHT, BBB_DISPLAY_WIDTH);
}
/**
* Redirect to big blue button instance; Menu callback
*
* @param OBJECT $node
* A Drupal node object
*/
function bbb_meeting_moderate($node) {
global $user;
$url = array();
$mode = 'moderate';
$meeting = bbb_get_meeting($node->nid);
$params = array(
'meetingID' => $meeting->meetingID,
'password' => $meeting->moderatorPW,
);
$status = bbb_api_getMeetingInfo($params);
if ($status->hasBeenForciblyEnded == 'true') {
drupal_set_message('The meeting has been terminated and is not available for reopening.');
drupal_goto('node/' . $node->nid);
}
drupal_set_title($node->title);
// Implicitly create meeting
if (empty($meeting->initialized)) {
if ($data = bbb_create_meeting($node, (array) $params)) {
// Update local data
bbb_update_meeting($node, array_merge((array) $meeting, (array) $data));
}
}
if (BBB_DISPLAY_MODE == 'blank') {
bbb_redirect($node, $mode);
}
return theme('bbb_meeting', $meeting, $mode, BBB_DISPLAY_HEIGHT, BBB_DISPLAY_WIDTH);
}
/**
* Terminate confirm form
*/
function bbb_end_confirm_form($form_state, $node) {
return confirm_form(array(
'nid' => array(
'#type' => 'value',
'#value' => $node->nid,
),
), t('Are you sure you want to terminate the meeting !name?', array(
'!name' => $node->title,
)), 'node/' . $node->nid, t('This action cannot be undone, all attendes will be removed from the meeting.'), t('Terminate'), t('Cancel'));
}
function bbb_end_confirm_form_submit($form, &$form_state) {
$node = node_load($form_state['values']['nid']);
bbb_meeting_end($node);
drupal_set_message(t('The meeting has been terminated.'));
drupal_goto('node/' . $node->nid);
}
/**
* Redirect to big blue button instance; Menu callback
*
* @param OBJECT $node
* A Drupal node object
*/
function bbb_meeting_end($node) {
$meeting = bbb_get_meeting($node->nid);
$params = array(
'meetingID' => $meeting->meetingID,
'password' => $meeting->moderatorPW,
);
$request = bbb_api_end($params);
bbb_api_execute_query($request);
}
/**
* Redirect to meeting
*/
function bbb_redirect($node, $mode = 'attend') {
$meeting = bbb_get_meeting($node->nid, NULL, FALSE);
switch ($mode) {
case 'attend':
// Get redirect URL
$url = parse_url($meeting->url[$mode]);
drupal_goto($url['scheme'] . '://' . $url['host'] . (isset($url['port']) ? ':' . $url['port'] : '') . $url['path'], $url['query']);
break;
case 'moderate':
// Get redirect URL
$url = parse_url($meeting->url[$mode]);
drupal_goto($url['scheme'] . '://' . $url['host'] . (isset($url['port']) ? ':' . $url['port'] : '') . $url['path'], $url['query']);
break;
}
}
function bbb_encode_int($string) {
$ords = array();
for ($i = 0; $i < strlen($string); $i++) {
$ords[] = ord(substr($string, $i, 1));
}
return implode($ords);
}
function bbb_create_meeting_id($salt = NULL) {
$private_key = drupal_get_private_key();
return bbb_encode_int($private_key) . $salt;
}
/* Themeables */
/**
* Theme inline meeting
*/
function theme_bbb_meeting($meeting, $mode = 'attend', $height = '580px', $width = '100%') {
$output .= '<iframe src="' . url('node/' . $meeting->nid . '/redirect/' . $mode, array(
'absolute' => TRUE,
)) . '" style="height:' . $height . ';width:' . $width . ';border:0;"></iframe>';
return $output;
}
/**
* Theme meeting status
*/
function theme_bbb_meeting_status($meeting) {
if ($meeting->running) {
$output = '<div class="bbb-status-is-running">' . t('Status: Meeting is progress.') . '</div>';
}
else {
$output = '<div class="bbb-status-is-not-running">' . t('Status: Meeting is not running') . '</div>';
}
return $output;
}
/**
* Theme meeting details block
*/
function theme_bbb_block_meeting($meeting) {
$output = '<div class="bbb-meeting-details">';
if ($meeting->welcome) {
$output .= '<div class="bbb-welcome">' . $meeting->welcome . '</div>';
}
$output .= theme('bbb_meeting_status', $meeting);
if ($meeting->dialNumber) {
$output .= '<div class="bbb-dial-number">' . t('Phone: @number', array(
'@number' => $meeting->dialNumber,
)) . '</div>';
}
if (user_access('attend meetings') || user_access('administer big blue button')) {
$output .= '<div class="bbb-meeting-attend">' . l('Attend meeting', 'node/' . $meeting->nid . '/meeting/attend') . '</div>';
}
if (user_access('moderate meetings') || user_access('administer big blue button')) {
$output .= '<div class="bbb-meeting-moderate">' . l(t('Moderate meeting'), 'node/' . $meeting->nid . '/meeting/moderate') . '</div>';
}
if (user_access('moderate meetings') || user_access('administer big blue button')) {
$output .= '<div class="bbb-meeting-end">' . l(t('Terminate meeting'), 'node/' . $meeting->nid . '/meeting/end-confirm') . '</div>';
}
$output .= '</div>';
return $output;
}
Functions
Name | Description |
---|---|
bbb_access_attendee | Check attendance access permissions; Menu access callback |
bbb_access_moderator | Check moderation access permissions; Menu access callback |
bbb_block | Implement HOOK_block(). |
bbb_block_meeting | Meeting details block |
bbb_create_meeting | Create meeting |
bbb_create_meeting_id | |
bbb_delete_meeting | Delete meeting |
bbb_encode_int | |
bbb_end_confirm_form | Terminate confirm form |
bbb_end_confirm_form_submit | |
bbb_form_alter | Implement HOOK_form_alter(). |
bbb_get_meeting | Return a meeting object |
bbb_init_meeting | Init meeting |
bbb_is_meeting_owner | Check if user is meeting owner |
bbb_is_meeting_type | Check if node type is meeting |
bbb_link | Implement HOOK_link(). |
bbb_meeting_attend | Redirect to big blue button instance; Menu callback |
bbb_meeting_end | Redirect to big blue button instance; Menu callback |
bbb_meeting_moderate | Redirect to big blue button instance; Menu callback |
bbb_menu | Implement HOOK_menu(). |
bbb_nodeapi | Implement HOOK_nodeapi(). |
bbb_perm | Implement HOOK_perm(). |
bbb_redirect | Redirect to meeting |
bbb_status | Return meeting status; Menu callback |
bbb_store_meeting | Store meeting |
bbb_theme | Implement HOOK_theme(). |
bbb_update_meeting | Update meeting |
bbb_views_api | Implementation of hook_views_api(). |
bbb_views_handlers | Implement hook_views_handlers(). |
theme_bbb_block_meeting | Theme meeting details block |
theme_bbb_meeting | Theme inline meeting |
theme_bbb_meeting_status | Theme meeting status |