Location: PHPKode > projects > WebConference Plugin for Moodle > webconference/lib.php
<?php // $Id: lib.php,v 1.0 2009/11/19 06:23:12 mlazar Exp $

require_once($CFG->libdir.'/pagelib.php');
/* require_once('../../config.php'); */

if (!isset($CFG->webconference_supportemail)) {
    set_config("webconference_supportemail", $CFG->supportemail);
}
if (!isset($CFG->webconference_defaultcountry)) {
    set_config("webconference_defaultcountry", 'US:CA');
}
if (!isset($CFG->webconference_defaultstate)) {
    set_config("webconference_defaultstate", 'CA');
}
if (!isset($CFG->webconference_exposecountry)) {
    set_config("webconference_exposecountry", 'N');
}
if (!isset($CFG->webconference_timezone)) {
    set_config("webconference_timezone", '-8');
}
if (!isset($CFG->webconference_exposetimezone)) {
    set_config("webconference_exposetimezone", 'N');
}
if (!isset($CFG->webconference_newdaylightsavings)) {
    set_config("webconference_newdaylightsavings", '1');
}
if (!isset($CFG->webconference_allowpasschange)) {
    set_config("webconference_allowpasschange", '0');
}
if (!isset($CFG->webconference_serverhost)) {
    set_config("webconference_serverhost", "www.webconference.com");
}
if (!isset($CFG->webconference_serverip)) {
    set_config("webconference_serverip", '127.0.0.1');
}
if (!isset($CFG->webconference_serverport)) {
    set_config("webconference_serverport", '443');
}
if (!isset($CFG->webconference_masterusername)) {
    set_config("webconference_masterusername", 'yourid');
}
if (!isset($CFG->webconference_masterpassword)) {
    set_config("webconference_masterpassword", 'yourpassword');
}
if (!isset($CFG->webconference_accountid)) {
    set_config("webconference_accountid", 0);
}

/* define('WC_DL_CLIENT_OPTION_NO', 0);
define('WC_DL_CLIENT_OPTION_YES', 1);
define('WC_DL_CLIENT_VALUE_NO', 'N');
define('WC_DL_CLIENT_VALUE_YES', 'Y');

define('WC_FILEXCHANGE_OPTION_D', 0);
define('WC_FILEXCHANGE_OPTION_U', 1);
define('WC_FILEXCHANGE_OPTION_DU', 2);
define('WC_FILEXCHANGE_VALUE_D', 'D');
define('WC_FILEXCHANGE_VALUE_U', 'U');
define('WC_FILEXCHANGE_VALUE_DU', 'DU');

define('WC_USETC_OPTION_8', 0);
define('WC_USETC_OPTION_Y', 1);
define('WC_USETC_OPTION_N', 2);
define('WC_USETC_VALUE_8', 0);
define('WC_USETC_VALUE_Y', 1);
define('WC_USETC_VALUE_N', 2);
*/
// The HTML header
$webconference_HTMLHEAD = "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\" \"http://www.w3.org/TR/REC-html40/loose.dtd\"><html><head></head>\n<body bgcolor=\"#FFFFFF\">\n\n";

// The HTML header with a scroll feature
$webconference_HTMLHEAD_JS = "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\" \"http://www.w3.org/TR/REC-html40/loose.dtd\"><html><head><script language=\"JavaScript\">\n<!--\nfunction move()\n{\nif (scroll_active) window.scroll(1,400000);\nwindow.setTimeout(\"move()\",100);\n}\nscroll_active = true;\nmove();\n//-->\n</script>\n</head>\n<body bgcolor=\"#FFFFFF\" onBlur=\"scroll_active = true\" onFocus=\"scroll_active = false\">\n\n";

// The HTML code for standard empty pages (e.g. if a user was kicked out)
$webconference_HTMLHEAD_OUT = "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\" \"http://www.w3.org/TR/REC-html40/loose.dtd\"><html><head><title>You are out!</title></head><body bgcolor=\"#FFFFFF\"></body></html>";

// The HTML head for the message input page
$webconference_HTMLHEAD_MSGINPUT = "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\" \"http://www.w3.org/TR/REC-html40/loose.dtd\"><html><head><title>Type a Message</title></head><body bgcolor=\"#FFFFFF\">";

// The HTML code for the message input page, with JavaScript
$webconference_HTMLHEAD_MSGINPUT_JS = "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\" \"http://www.w3.org/TR/REC-html40/loose.dtd\"><html><head><title>Type a Message</title>\n<script language=\"Javascript\">\n<!--\nscroll_active = true;\nfunction empty_field_and_submit()\n{\ndocument.fdummy.arsc_message.value=document.f.arsc_message.value;\ndocument.fdummy.submit();\ndocument.f.arsc_message.focus();\ndocument.f.arsc_message.select();\nreturn false;\n}\n// -->\n</script>\n</head><body bgcolor=\"#FFFFFF\" OnLoad=\"document.f.arsc_message.focus();document.f.arsc_message.select();\">";

$gridwidth = array(
        'seqno' => '2'
       ,'category' => '17'
       ,'id' => '2'   
       ,'name' => '21'   
       ,'mbrs' => '5'   
       ,'copybtn' => '5'   
       ,'seats' => '8'   
       ,'username' => '14'   
       ,'usergen' => '5'   
       ,'password' => '14'   
       ,'passgen' => '5'   
       ,'country' => '0' // Hide unless exposecountry=Y   
       );
if ($CFG->webconference_exposecountry == 'Y') {
    $gridwidth['country'] = 8;
    $gridwidth['seats'] -= 1; // taking 2 from seats
    $gridwidth['name'] -= 1; // taking 2 from seats
    $gridwidth['username'] -= 3; // 11% or 8% for both 
    $gridwidth['password'] -= 3; // 11% or 8% for both
    if ($CFG->webconference_exposetimezone != 'Y') {
       // More space for country
       $gridwidth['country'] += 8;
       $gridwidth['username'] -= 3;
       $gridwidth['password'] -= 3;
       $gridwidth['name'] -= 1;
       $gridwidth['category'] -= 1;
    }
}
if ($CFG->webconference_exposetimezone == 'Y') {
    $gridwidth['timezone'] = "8";
    $gridwidth['seats'] -= 1; // taking 1 from cat
    $gridwidth['name'] -= 1; // 
    $gridwidth['username'] -= 3; // 11% or 8% for both
    $gridwidth['password'] -= 3; // 11% or 8% for both
    if ($CFG->webconference_exposecountry != 'Y') {
       // More space for country
       $gridwidth['timezone'] += 8;
       $gridwidth['username'] -= 3;
       $gridwidth['password'] -= 3;
       $gridwidth['name'] -= 1;
       $gridwidth['category'] -= 1;
    }
}
/* --> We are not using left at the moment.
 *     Currently the table percentage is doing ok by itself.       
$gridleft = array(
        'category' => '0px'
       ,'id' => '15%'   
       ,'name' => '20%'   
       ,'mbrs' => '40%'   
       ,'copybtn' => '45%'   
       ,'seats' => '50%'   
       ,'username' => '59%'   
       ,'password' => '79%'   
       );
*/
function webconference_process_options(&$config) {
    if ($config->exposecountry != 'Y') {
        $config->exposecountry = 'N';
    }
    if ($config->exposetimezone != 'Y') {
        $config->exposetimezone = 'N';
    }
    if ($config->newdaylightsavings != '1') {
        $config->newdaylightsavings = '0';
    }
    if ($config->allowpasschange != '1') {
        $config->allowpasschange = '0';
    }
    unset ($config->confirmpassword);
}
function webconference_scheme() {
                if (!empty($CFG->loginhttps)) {
                    //$wwwroot = str_replace('http','https', $wwwroot);
                    return "https://";
                }
                return "http://"; 
}

/**
 * webconference_get_meeting_repeats
 * Returns array dates (in seconds) of meeting start times
 * for repeating of a conference entry
 * 
 * @param int $courseid Course id of the course to get the last usable date 
 * @param string $type 'week' 'month' or 'course'
 * @param int $firstdate First datetime to use in calculations
 * @return array $dates
 */
function webconference_get_meeting_repeats($courseid, $type, $firstdatesecs) {
    global $CFG;
    $stopday_wk = 6; // stop at sat midnight
    $dates = array($firstdatesecs);
    $nextdatesecs = $firstdatesecs;
    $fmt = '%w,%d,%y'; // %w=numeric day, 0-6  %d 2-digit day of month.
    
    $course = get_record('course', 'id', $courseid);
    if (!$course) {
        // Just return the one date. Could not get the course.
        return $dates;
    }
    // startdate and numsections are the important values
    $lastdatesecs = $course->startdate + ( 7 * 24 * 3600 * $course->numsections);
    $lastdaymon = strftime($fmt, $lastdatesecs);
    $lastdayarr = explode(',', $lastdaymon);
    while ($lastdayarr[0] < $stopday_wk) {
        $lastdatesecs += (24 * 3600);
        $lastdaymon = strftime($fmt, $lastdatesecs);
        $lastdayarr = explode(',', $lastdaymon);
    }
    $thisdaymon = strftime($fmt, $firstdatesecs);
    $thisdayarr = explode(',', $thisdaymon);
      
    $thisdayofweek = $thisdayarr[0];
    $thismonth = $thisdayarr[1];
    if ($type == 'week') {
        $nextdatesecs = $firstdatesecs + (24 * 3600);
        while ((++$thisdayofweek < $stopday_wk) && ($nextdatesecs < $lastdatesecs)) {             
            $dates[] = $nextdatesecs;
            $nextdatesecs += 24 * 3600;
        }
    }
    // go to the end of the month 
    // *or* end of course if course ends before then
    else if ($type == 'month') {
        $nextdatesecs = $firstdatesecs + (7 * 24 * 3600);
        $nextdaymon = strftime($fmt, $nextdatesecs);
        $nextdayarr = explode(',', $nextdaymon);
        
        while (($nextdatesecs <= $lastdatesecs) && ($nextdayarr[1] <= $thisdayarr[1])) {
            $dates[] = $nextdatesecs;
            $nextdatesecs += (7 * 24 * 3600);
            $nextdaymon = strftime($fmt, $nextdatesecs);
            $nextdayarr = explode(',', $nextdaymon);
        }
    }
    else if ($type == 'course') {
        $nextdatesecs = $firstdatesecs + (7 * 24 * 3600);
        $nextdaymon = strftime($fmt, $nextdatesecs);
        $nextdayarr = explode(',', $nextdaymon);
                
        while (($nextdatesecs <= $lastdatesecs)) {
            $dates[] = $nextdatesecs;
            $nextdatesecs += (7 * 24 * 3600);
            $nextdaymon = strftime($fmt, $nextdatesecs);
            $nextdayarr = explode(',', $nextdaymon);
        }     
    }

    return $dates;
}
function webconference_add_instance($conference) {
    /// Given an object containing all the necessary data,
    /// (defined by the form in mod.html) this function
    /// will create a new instance and return the id number
    /// of the new instance.

    $conference->timemodified = time();

    $conference->startdttm = make_timestamp($conference->mtgyear, $conference->mtgmonth, $conference->mtgday,
                                     $conference->mtghour, $conference->mtgminute);
/*                                     
    $dates = array();                  
    if ($conference->schedule == 1) {
       $dates = webconference_get_meeting_repeats($conference->course, 'week', $conference->startdttm);
    }
    else if ($conference->schedule == 2) {     
       $dates = webconference_get_meeting_repeats($conference->course, 'month', $conference->startdttm);
    }
    else if ($conference->schedule == 3) {     
       $dates = webconference_get_meeting_repeats($conference->course, 'course', $conference->startdttm);
    }
    $setcounter = 1;
    $conferencename = $conference->name;  // store for loop use
    foreach ($dates as $date) {
        $conference->name = $conferencename;
        if (count($dates) > 1) {
           if ($conference->repeatprintset == 1) {
                $conference->name .= " [Set #". $setcounter++ ."]"; 
           }
        }
        $conference->startdttm = $date;
*/
        if ($returnid = insert_record('webconference', $conference)) {

        	// If any of these values are null, the event will not be added.
            $event = NULL;
            $event->name        = $conference->name;
            $event->description = $conference->description;
            $event->courseid    = $conference->course;
            $event->groupid     = 0;
            $event->userid      = 0;
            $event->modulename  = 'webconference';
            $event->instance    = $returnid;
            $event->eventtype   = $conference->schedule;
            $event->timestart   = $conference->startdttm;
            $event->timeduration = $conference->durationmins; // 0;

            add_event($event);
        }
//    }
    return $returnid;
}

 
function webconference_update_instance($conference) {
    /// Input: Full object with all meeting information
    /// (defined by the form in mod.html) 
    /// update an existing instance with new data.

    $conference->timemodified = time();
    $conference->id = $conference->instance;

    $conference->startdttm = make_timestamp($conference->mtgyear
                                      ,$conference->mtgmonth
                                      ,$conference->mtgday
                                      ,$conference->mtghour
                                      ,$conference->mtgminute);

    if ($returnid = update_record('webconference', $conference)) {

        $event = NULL;

        if ($event->id = get_field('event', 'id', 'modulename', 'webconference', 'instance', $conference->id)) {

            $event->name        = $conference->name;
            $event->description = $conference->description;
            $event->timestart   = $conference->startdttm;

            update_event($event);
        }
    }

    return $returnid;
}


function webconference_delete_instance($id) {
    /// Given an ID of an instance of this module,
    /// this function will permanently delete the instance
    /// and any data that depends on it.

    if (! $conference = get_record('webconference', 'id', $id)) {
        return false;
    }

    $result = true;

    # Delete any dependent records here #

    if (! delete_records('webconference', 'id', $conference->id)) {
        $result = false;
    }
//  There are no messages
//    if (! delete_records('webconference_messages', 'webconferenceid', $conference->id)) {
//        $result = false;
//    }
//  There are no users
//    if (! delete_records('webconference_users', 'webconferenceid', $conference->id)) {
//        $result = false;
//    }

    $pagetypes = page_import_types('mod/webconference/');
    foreach($pagetypes as $pagetype) {
        if(!delete_records('block_instance', 'pageid', $webconference->id, 'pagetype', $pagetype)) {
            $result = false;
        }
    }

    if (! delete_records('event', 'modulename', 'webconference', 'instance', $conference->id)) {
        $result = false;
    }

    return $result;
}

function webconference_user_outline($course, $user, $mod, $conference) {
    /// Return a small object with summary information about what a
    /// user has done with a given particular instance of this module
    /// Used for user activity reports.
    /// $return->time = the time they did it
    /// $return->info = a short text description

    $return = NULL;
    return $return;
}

function webconference_user_complete($course, $user, $mod, $conference) {
    /// Print a detailed representation of what a  user has done with
    /// a given particular instance of this module, for user activity reports.

    return true;
}

function webconference_print_recent_activity($course, $isteacher, $timestart) {
    /// Parameters: a course, isteacher ,a date, prints a summary of all meetings
    /// This function is called from course/lib.php: print_recent_activity()

    global $CFG;

    return true;
}

function webconference_print_conference_pass_field () {
    global $CFG; 
    
    if ($CFG->webconference_allowpasschange) {
        $itype = 'text';
    }
    else {
        $itype = 'hidden';
     
    }
    echo "<input type='".$itype."' size=10 maxlength=40 name='conferencepass' value='sdfsdf'>\n";
}

function webconference_check_for_valid_user($courseid) {
    global $CFG;
    if (!webconference_get_users_in_courseids(array($courseid))) {
        $strpr = get_string('usernotconfigured','webconference');
        $stremailtxt = get_string('usernotconfiguredemailtxt','webconference');
        $stremaillink = "<a href='mailto:".$CFG->webconference_supportemail."'>"
                       .$stremailtxt ."</a>";
        $strall = preg_replace('/'.$stremailtxt.'/', $stremaillink, $strpr);
        echo "<center><h4>". $strall ."</h4></center>";
    }
}
function webconference_cron () {
    /// Function to be run periodically according to the moodle cron
    /// This function searches for things that need to be done, such
    /// as sending out mail, toggling flags etc ...

    global $CFG;

    webconference_update_wc_times();

    webconference_delete_old_users();

    /// Delete old messages
    if ($conferences = get_records('webconference')) {
        foreach ($conferences as $conference) {
            if ($conference->retention) {
                $timeold = time() - ($conference->retention * 24 * 3600);
                delete_records_select("webconference_messages", "webconferenceid = '$conference->id' AND timestamp < '$timeold'");
            }
        }
    }

    return true;
}

/**
 * This standard function will check and refresh events of the instances of this module
 * and make sure the events are up-to-date.
 * If courseid = 0, then every webconference event in the site is checked, 
 * else only the webconference events belonging to the course specified are checked.
 * This function is used by restore_refresh_events()
 * 
 * @param int $courseid
 * @return boolean
 */
function webconference_refresh_events($courseid = 0) {

    if ($courseid) {
        if (! $conferences = get_records('webconference', "course", $courseid)) {
            return true;
        }
    } else {
        if (! $conferences = get_records('webconference')) {
            return true;
        }
    }
    $moduleid = get_field('modules', 'id', 'name', 'webconference');

    foreach ($wcntgs as $conference) {
        $event = NULL;
        $event->name        = addslashes($conference->name);
        $event->description = addslashes($conference->intro);
        $event->timestart   = $conference->dimdimtime;

        if ($event->id = get_field('event', 'id', 'modulename', 'webconference', 'instance', $conference->id)) {
            update_event($event);

        } else {
            $event->courseid    = $conference->course;
            $event->groupid     = 0;
            $event->userid      = 0;
            $event->modulename  = 'webconference';
            $event->instance    = $conference->id;
            $event->eventtype   = $conference->schedule;
            $event->timeduration = 0;
            $event->visible     = get_field('course_modules', 'visible', 'module', $moduleid, 'instance', $conference->id);

            add_event($event);
        }
    }
    return true;
}

function webconference_force_language($lang) {
    /// This function forces moodle to operate in a given language
    /// usable when $nomoodlecookie = true;
    /// there must be no $course, $USER or $SESSION
    global $CFG;

    if(!empty($CFG->courselang)) {
        unset($CFG->courselang);
    }
    if(!empty($CFG->locale)) {
        unset($CFG->locale);
    }
    $CFG->lang = $lang;
    moodle_setlocale();
}
function webconference_get_states() {
    global $CFG;
        
    if (file_exists($CFG->dirroot .'/mod/webconference/countrystates.php')) {
        include($CFG->dirroot .'/mod/webconference/countrystates.php');
    }
    foreach ($string as $item) {
        if (!empty($item)) {
            uasort($item, 'strcoll');
        }
    }
    return $string;   
}

function webconference_print_countrystate_select($inputname='wc_country', $selected="US:CA") {
    static $countries;
    static $states;
    if (empty($countries)) {
        $countries = get_list_of_countries();
    }
    if (empty($states)) {
        $states = webconference_get_states();
    }
    $strselect = "<select class='wc_gridsel_country' id='id_".$inputname."' name='".$inputname."'>\n";
    foreach ($countries as $ccode => $country) {
        $strselected = "";
        if (!empty($states[$ccode])) {
            foreach ($states[$ccode] as $statecode => $statetext) {
                $strselected = "";
                if ($selected == $ccode.":".$statecode) {
                    $strselected = "selected";
                }
                $strselect .= " <option class='wc_seloption_state' value='".$ccode.":".$statecode."' ".$strselected." >".$country."->".$statetext."</option>\n";
            }
        }
        else {
            if (($selected == $ccode) && (empty($states[$ccode]))) {
                $strselected = "selected";
            }
            $strselect .= " <option class='wc_seloption_country' value='".$ccode."' ".$strselected." >".$country."</option>\n";         
        }
    }
    $strselect .= "</select>\n";
    echo $strselect;
}
/**
 * Converts timezone like PDT/EST to UTC equivalent
 *
 * @param string $intz
 */
function webconference_tz_to_utc($intz) {
    return $intz;
}
/**
 * Prints timezone select box.
 *
 * @param string $inputname name you want the select box to be id and named
 * @param string $selected option to be marked as selected.
 */
function webconference_print_timezone_select($inputname='wc_timezone', $selected) {
    $timezones = get_list_of_timezones();
    //$systz = date("T");  // TODO: default to system timezone
    //$sysutc = webconference_tz_to_utc($systz);
    $strselect = "<select class='wc_gridsel_tzone' id='id_".$inputname."' name='".$inputname."'>\n";
    foreach ($timezones as $tz => $timezone) {
        $strselected = "";
        if ($selected == $tz) {
            $strselected = "selected";
        }
        $strselect .= " <option class='wc_seloption_timezone' ".$strselected." value='".$tz."'>".$timezone."</option>\n";
    }
    $strselect .= "</select>\n";
    echo $strselect;
}

/**
 * Function will return all webconference_users providing a set of
 * course ids. Returns the seats/user/pass/ in an array of
 * returned rows (no key).
 * 
 * @param array $courseids
 * @return unknown
 */
function webconference_get_users_in_courseids($courseids) {
    global $CFG;
    $inclause = '';
    foreach ($courseids as $cid) {
        $inclause .= $cid .",";
    }
    $inclause = rtrim($inclause, ',');
    
    return get_records_sql("SELECT c.*
                              FROM {$CFG->prefix}webconference_users c
                             WHERE c.course in ($inclause)");
}
function webconference_set_conference_account(&$conference) {
    global $CFG;
    if (!isset($conference->wc_acccountid)) {
        $conference->wc_accountid = $CFG->webconference_accountid;
    }
    if (!isset($conference->wc_username)) {
        $conference->wc_username = $CFG->webconference_username;
    }
    if (!isset($conference->wc_password)) {
        $conference->wc_password = $CFG->webconference_password;
    }
}
function webconference_conf_create($conference) {
    global $CFG;
    
    // wc_require_download: in moodle = 0 for no, 1 for yes.
    $wc_req_dl = "N";
    if ($conference->wc_require_download == 1) {
        $wc_req_dl = "Y";
    }
    /* wc_filexchange: 
    value="0">Download Only => D
    value="1">Upload Only => 
    value="2">Download and Upload => DU
    */
    $wc_fx = "D";
    switch ($conference->wc_filexchange) {
        case 1:
            $wc_fx = "U";
            break; 
        case 2:
            $wc_fx = "DU";
            break;
    }
    /*
     * wc_usetc:
     * value="0" Use 800 teleconferencing => 8
     * value="1" Use toll teleconferencing => Y
     * value="2" Do no use teleconferencing => N
     * 
     */
    $wc_usetc = "8"; // =0
    switch ($conference->wc_usetc) {
       case 1:
        $wc_usetc = "Y";
       case 2:
        $wc_usetc = "N";
    }   
    $s = array("wc_account" => $conference->wc_accountid
              ,"wc_cmd" => "conf_create"
              ,"wc_username" => $conference->wc_username 
              ,"wc_password" => $conference->wc_password
              ,"wc_topic" => urlencode($conference->name)
              ,"wc_require_download" => $wc_req_dl
              ,"wc_filexchange" => $wc_fx
              ,"wc_open" => "Y"
              ,"wc_confpassword" => $conference->conferencepass
              ,"wc_usetc" => $wc_usetc
              //,"wc_usetc_code" => $conference->wc_usetc_code
              // ,"wc_usetc_mod" => $conference->wc_usetc_mod
              ,"wc_backurl" => $CFG->wwwroot ."/mod/webconference/closer.html" // point to the blank page
              ,"wc_resellerid" => "" // urlencode($CFG->webconference_resellerid)
    );
    /*
    $s = "wc_account=". urlencode($CFG->webconference_accountid) 
         ."&"."wc_username=". urlencode($CFG->webconference_masterusername) 
         ."&"."wc_password=". urlencode($CFG->webconference_masterpassword)
         ."&"."wc_cmd=conf_create"
         ."&"."wc_topic=". urlencode($conference->name)
         ."&"."wc_require_download=". urlencode($conference->wc_require_download)
         ."&"."wc_filexchange=". urlencode($conference->wc_filexchange)
         ."&"."wc_open=Y"
         ."&"."wc_confpassword=". urlencode($conference->confkey)
         ."&"."wc_usetc=". urlencode($conference->wc_usetc)
         // ."&"."wc_usetc_code=". ""
         // ."&"."wc_usetc_mod=". ""
         ."&"."wc_backurl=". urlencode($courseurl)
         ."&"."wc_resellerid=". urlencode($CFG->webconference_resellerid)
    ;
    */
    $posturl = "https://".$CFG->webconference_serverhost.":".
                          $CFG->webconference_serverport."/webconferencepro/apis/api.php";
    if (!$result = wc_curl_post($posturl, $CFG->webconference_serverport, $s)) {
       error(get_string('errorconfcreate','webconference'));
    }
    return $result;
}

function webconference_conf_activate($conference) {
    global $CFG;
    $s = array (
        "wc_account" => $conference->wc_accountid 
       ,"wc_cmd" => "conf_activate"
       ,"wc_username" => $conference->wc_username 
       ,"wc_password" => $conference->wc_password
       ,"wc_conferenceid" => $conference->conferenceid
       ,"wc_force" => "Y"
       ,"wc_presenter_fname" => $conference->presenter_fname
       ,"wc_presenter_lname" => $conference->presenter_lname
       ,"wc_presenter_email" => $conference->presenter_email
       );   
    $posturl = "https://".$CFG->webconference_serverhost.":".
                         $CFG->webconference_serverport."/webconferencepro/apis/api.php";
    if (!$result = wc_curl_post($posturl, $CFG->webconference_serverport, $s)) {
       error(get_string('errorconfactivate','webconference'));
    }
    return $result; 
}

function webconference_conf_join($conference, $role, $USER) {
    global $CFG;    
    $s = array (
        "wc_account" => $conference->wc_accountid 
       ,"wc_cmd" => "conf_join"
       ,"wc_username" => $conference->wc_username 
       ,"wc_password" => $conference->wc_password
       ,"wc_conferenceid" => $conference->conferenceid
       ,"wc_role" => $role // "FirstPresenter" or "guest"
       ,"wc_guest_name" => $USER->firstname ." ". $USER->lastname
       ,"wc_guest_email" => $USER->email
       ,"wc_guest_backurl" => $CFG->wwwroot ."/mod/webconference/closer.html"
       ,"wc_error_url" => $CFG->wwwroot ."/mod/webconference/closer.html" // point to the blank page
       ,"B5" => "Submit"
       );   
    $posturl = "https://".$CFG->webconference_serverhost.":".
                         $CFG->webconference_serverport."/webconferencepro/apis/api.php";
    if (!$result = wc_curl_post($posturl, $CFG->webconference_serverport, $s)) {
       error(get_string('errorconfjoin','webconference'));
    }
    return $result; 
}

// Provide properly url encoded string
function wc_curl_post($url, $port, $s) {
    $ch = curl_init();
    $curlopts = array(CURLOPT_URL => $url // "https://www.google.com/" // $url
                     ,CURLOPT_HEADER => false                    
                     ,CURLOPT_AUTOREFERER => true
                     ,CURLOPT_RETURNTRANSFER => true
                     ,CURLOPT_FOLLOWLOCATION => true
                     ,CURLOPT_MAXREDIRS => 5
                     ,CURLOPT_POST => true
                     ,CURLOPT_SSL_VERIFYPEER => false //SET TO TRUE IN PROD ENV
                     ,CURLOPT_CONNECTTIMEOUT => 60 // seconds
                     ,CURLOPT_PORT => $port
                     //Upgrade to cURL 7.19.4 // ,CURLOPT_PROTOCOLS => CURLPROTO_HTTPS
                     ,CURLOPT_TIMEOUT => 60
                     ,CURLOPT_POSTFIELDS => $s
                     ,CURLOPT_VERBOSE => true
                     );
    curl_setopt_array($ch,$curlopts);
    $output = curl_exec($ch);                    
    curl_close($ch);
    if (preg_match("/404.*not found/i",$output)) {
        return false;
    }
    return $output;
}

/**
 * Add a webconference user. Users are tied to courses so multiple teachers could fire off a conference.
 * Input: webconfuser array with keys for the fields we intend to use
 * Required: seats, wc_username, wc_password, name, category, wc_country, wc_state, wc_timezone
 * 
 * @param array $webconfuser
 * @return array ['result'] => boolean, ['output'] => return output
 */
function webconference_add_conf_user($webconfuser) {
    global $USER;
    global $CFG;
    global $SITE;
    static $countries;
    $userwc = array(); // Make a copy to muck up
    foreach ($webconfuser as $ek => $ev) {
        $userwc[$ek] = $ev;
    }
    if (empty($countries)) {
           $countries = get_list_of_countries();
    }
    
    $defaultcountry = explode(':',$CFG->webconference_country);
    if (empty($userwc->wc_country)) {
         $userwc->wc_country = $defaultcountry[0];
         $userwc->wc_state = $defaultcountry[1];
    }
    $s = array (
        "wc_account"              => urlencode($CFG->webconference_accountid) 
       ,"wc_cmd"                  => "acct_purchase"
       ,"wc_username"             => $CFG->webconference_masterusername 
       ,"wc_password"             => $CFG->webconference_masterpassword
       ,"wc_new_seats"            => $userwc['seats']
       ,"wc_new_username"         => $userwc['wc_username']
       ,"wc_new_password"         => $userwc['wc_password']
       ,"wc_new_email"            => $CFG->webconference_supportemail
       ,"wc_new_firstname"        => $userwc['name'] // Course Name
       ,"wc_new_lastname"         => $userwc['category'] // Category
       ,"wc_new_company"          => $SITE->fullname // Institution
       ,"wc_new_country"          => $countries[$userwc['wc_country']] 
       ,"wc_new_state"            => $userwc['wc_state']
       ,"wc_new_timezone"         => $userwc['wc_timezone']
       ,"wc_new_daylight_savings" => $CFG->webconference_newdaylightsavings             // ??
    );   
    $posturl = "https://".$CFG->webconference_serverhost.":".
                         $CFG->webconference_serverport."/webconferencepro/apis/api.php";
    if (!$result = wc_curl_post($posturl, $CFG->webconference_serverport, $s)) {
       $rtnmsg['result'] = false;
       $rtnmsg['output'] = get_string('erroracctpurchase','webconference');
       return $rtnmsg;
    }
    // Result has new accountid or error.
    if (preg_match("/error/i", $result)) {
        $rtnmsg['result'] = false;
        $rtnmsg['output'] = $result;
        return $rtnmsg;
    }
    
    // Added successful. insert record into DB
    // get this account id for the seat assignment
    $userwc['wc_accountid'] = $result;
    
    // unset values we do not insert or it will fail.
    unset($userwc['action']);
    unset($userwc['name']);
    unset($userwc['category']);
    $userwc['updated_by'] = $USER->id;
    $userwc['timemodified'] = time();
    
    //return $result; 
    if (!insert_record('webconference_users', $userwc)) {
        $rtnmsg['result'] = false;
        $rtnmsg['output'] = get_string('errorinsertwcuser','webconference').": ". $webconfuser->name;
        return $rtnmsg;
    }
    $rtnmsg['result'] = true;
    $rtnmsg['output'] = "User added successfully";
    return $rtnmsg;    
}

function webconference_update_conf_user($webconfuser) {
    global $USER;
    global $CFG;

    $userwc = array();
    foreach ($webconfuser as $ek => $ev) {
        $userwc[$ek] = $ev;
    }
    
    $s = array (
        "wc_account" => $CFG->webconference_accountid
       ,"wc_cmd" => "acct_seats"
       ,"wc_username" => $CFG->webconference_masterusername
       ,"wc_password" => $CFG->webconference_masterpassword
       ,"wc_edit_account" => $userwc['wc_accountid']
       ,"wc_edit_seats" => $userwc['seats']
       ,"wc_edit_username" => $userwc['wc_username']
       ,"wc_edit_password" => $userwc['wc_password']
       ,"wc_edit_email" => $CFG->webconference_supportemail
    );   
    $posturl = "https://".$CFG->webconference_serverhost.":".
                         $CFG->webconference_serverport."/webconferencepro/apis/api.php";
    if (!$result = wc_curl_post($posturl, $CFG->webconference_serverport, $s)) {
       $rtnmsg['result'] = false;
       $rtnmsg['output'] = get_string('erroracctpurchase','webconference');
       return $rtnmsg;
    }
    // Result has new accountid or error.
    if (preg_match("/error/i", $result)) {
        $rtnmsg['result'] = false;
        $rtnmsg['output'] = $result;
        return $rtnmsg;
    }
    
    // Added successful. insert record into DB
    // get this account id for the seat assignment
    $userwc['seats'] = $result;
    
    // unset values we do not insert or it will fail.
    unset($userwc['action']);
    unset($userwc['name']);
    unset($userwc['category']);
    $userwc['updated_by'] = $USER->id;
    $userwc['timemodified'] = time();
    
	// Added successful. insert record into DB
    if (!update_record('webconference_users', $userwc)) {
        $rtnmsg['result'] = false;
        $rtnmsg['output'] = get_string('errorupdatewcuser','webconference').": ". $webconfuser->name;
        return $rtnmsg;
    }
    $rtnmsg['result'] = true;
    $rtnmsg['output'] = "User updated successfully";
    return $rtnmsg;    	
}

function webconference_delete_conf_user($webconfuser) {
    global $USER;
    global $CFG;

    $userwc = array();
    foreach ($webconfuser as $ek => $ev) {
        $userwc[$ek] = $ev;
    }
    
    $s = array (
        "wc_account" => $CFG->webconference_accountid
       ,"wc_cmd" => "acct_deactivate"
       ,"wc_username" => $CFG->webconference_masterusername
       ,"wc_password" => $CFG->webconference_masterpassword
       ,"wc_deactivate_account" => $userwc['wc_accountid']
    );   
    $posturl = "https://".$CFG->webconference_serverhost.":".
                         $CFG->webconference_serverport."/webconferencepro/apis/api.php";
    if (!$result = wc_curl_post($posturl, $CFG->webconference_serverport, $s)) {
       $rtnmsg['result'] = false;
       $rtnmsg['output'] = get_string('erroracctdeactivate','webconference');
       return $rtnmsg;
    }
    // Result has new accountid or error.
    if (preg_match("/error/i", $result)) {
        $rtnmsg['result'] = false;
        $rtnmsg['output'] = $result;
        return $rtnmsg;
    }
    
    // Added successful. insert record into DB
    // get this account id for the seat assignment
    $userwc['wc_accountid'] = $result;
    
    // unset values we do not insert or it will fail.
    unset($userwc['action']);
    unset($userwc['name']);
    unset($userwc['category']);
    $userwc['updated_by'] = $USER->id;
    $userwc['timemodified'] = time();
    
	// Added successful. insert record into DB
    if (!delete_records('webconference_users', 'id', $userwc['id'])) {
        $rtnmsg['result'] = false;
        $rtnmsg['output'] = get_string('errordeletewcuser','webconference').": ". $webconfuser->name;
        return $rtnmsg;
    }
    $rtnmsg['result'] = true;
    $rtnmsg['output'] = "User deleted successfully";
    return $rtnmsg;    	
}

/**
 * Print the form top html for the user and seat assignment admin form
 *
 */
function webconference_print_admin_seat_formtop() {
   echo "<form name='wc_seats_form' action='configusers.php' method='post'>\n";
}

/**
 * Prints the seat assignment footer, 
 * includes the update button and form closure
 *
 */
function webconference_print_admin_seat_footer($pagenumber=0) {
    // echo "<tbody><tr><td colspan=9><br />textpush<br />textpush<br />textpush<br />textpush<br />textpush<br />textpush<br />textpush<br />textpush<br />textpush<br />textpush<br />textpush<br />textpush<br />textpush<br />textpush<br />textpush<br />textpush<br />textpush<br />textpush<br />textpush<br />textpush<br />textpush<br />textpush<br />textpush<br />textpush<br />textpush<br />textpush</td></tr></tbody>\n";
    // Print "More" Banner
    echo "</div><div id='wc_update_seat_ctr' style='position:absolute; top:225px;'><input type=submit name='wc_seats_btn_sbmt' id='id_wc_seats_btn_sbmt' " 
        ." value='Update'></div>"
        ;
}

function webconference_print_error_bar($errorstring) {
    $styleinsert = "display:block;";
    echo "<div id='wc_seat_form_errorbar_c' style='".$styleinsert
        ."'><table cellspacing=0 cellpadding=0 border=0 bordercolor=#000000 "
        ." width=100% align=center class='wc_font_shrink'>\n"            
        ."<tbody><tr class='wc_grid_errorbar'><td width=100% align=center>"
        ."<div class='wc_grid_errorbar'>"
        .$errorstring
        ."</div></td></tr></tbody></table></div>\n"
        ;
}
function webconference_print_grid_nextbar($pagenumber, $recordsperpage=5, $categoryid, $searchstring, $styleinsert) {
    echo "<div id='wc_seat_form_nextbar_c' style='".$styleinsert
        ."'><table cellspacing=0 cellpadding=0 border=0 bordercolor=#000000 "
        ." width=100% align=center class='wc_font_shrink'>\n"            
        ."<tbody><tr class='wc_grid_morebar'><td width=100% align=center>"
        ."<div class='wc_grid_morebar'><a id='wc_course_nextlink' href='configusers.php?categoryid=".$categoryid
        ."&recordsperpage=".$recordsperpage."&pagenumber=".($pagenumber+1)
        ."&searchstring=".urlencode($searchstring)."'>Next"
        ."</a></div></td></tr></tbody></table></div>\n"
        ;
}

function webconference_print_grid_prevbar($pagenumber, $recordsperpage=5, $categoryid, $searchstring) {
    $styleinsert = "display:block;";
    if ($pagenumber < 1) {
        // $styleinsert = "display:none;";
        return;
    }
    echo "<div id='wc_seat_form_prevbar_c' style='".$styleinsert
        ."'><table cellspacing=0 cellpadding=0 border=0 bordercolor=#000000 "
        ." width=100% align=center class='wc_font_shrink'>\n"            
        ."<tbody><tr class='wc_grid_morebar'><td width=100% align=center>"
        ."<div class='wc_grid_morebar'><a id='wc_course_prevlink' href='configusers.php?categoryid=".$categoryid
        ."&recordsperpage=".$recordsperpage."&pagenumber=".($pagenumber-1)
        ."&searchstring=".urlencode($searchstring)."'>Prev"
        ."</a></div></td></tr></tbody></table></div>\n"
        ;
}
function webconference_print_no_records_row() {
    echo "<tbody><tr><td colspan=11 class='wc_grid_morebar'>"
        ."<div align=center class='wc_grid_morebar'>".get_string('nocoursesfound','webconference')."</div>"
        ."</td></tr></tbody>\n"
        ;
}
/**
 * Prints the admin seat header div and titlebar.
 *
 */
function webconference_print_admin_seat_header() {
    global $CFG;
    global $gridwidth;
    echo ""
    // Print the header
        ."<div id='wccoursebody_header' class='wc_grid_header' style='width: 97.5%; max-width:97.5%; "
        ."position:absolute; top: 0; left: 0; height:auto; max-height:auto;'>\n"
        /*
        ."<div id='wccoursebody_padleft' class='wcgridwrapper' style='width: auto;'>\n"
        ."<div id='course_hdr_category' class='wc_grid_header wc_font_shrink' "
        ."style='width:".$gridwidth['category']."; position:absolute; top: 0; left:".$gridleft['category'].";'>\n"
        ." <nobr>Category</nobr>\n</div>\n"
        ."<div id='course_hdr_id' class='wc_grid_header wc_font_shrink' "
        ."style='width:".$gridwidth['id']."; position:absolute; top: 0; left:".$gridleft['id'].";'>\n"
        ."<nobr>ID</nobr>\n</div>\n"
        ."<div id='course_hdr_name' class='wc_grid_header wc_font_shrink' "
        ."style='width:".$gridwidth['name']."; position:absolute; top: 0;left:".$gridleft['name'].";'>\n"
        ."<nobr>Course Name</nobr>\n</div>\n"
        ."<div id='course_hdr_mbrs' class='wc_grid_header wc_font_shrink' "
        ."style='width:".$gridwidth['mbrs']."; position:absolute; top: 0;left:".$gridleft['mbrs'].";'>\n"
        ."<nobr>Mbrs</nobr>\n</div>\n"
        ."<div id='course_hdr_copybtn' class='wc_grid_header wc_font_shrink' "
        ."style='width:".$gridwidth['copybtn']."; position:absolute; top: 0;left:".$gridleft['copybtn'].";'>\n"
        ."<nobr>>></nobr>\n</div>\n"
        ."<div id='course_hdr_seats' class='wc_grid_header wc_font_shrink' "
        ."style='width:".$gridwidth['seats']."; position:absolute; top: 0;left:".$gridleft['seats'].";'>\n"
        ."<nobr># Seats</nobr>\n</div>\n"
        ."<div id='course_hdr_username' class='wc_grid_header wc_font_shrink' "
        ."style='width:".$gridwidth['username']."; position:absolute; top: 0;left:".$gridleft['username'].";'>\n"
        ."<nobr>Username</nobr>\n</div>\n"
        ."<div id='course_hdr_password' class='wc_grid_header wc_font_shrink' "
        ."style='width:".$gridwidth['password']."; position:absolute; top: 0;left:".$gridleft['password'].";'>\n"
        ."<nobr>User Key</nobr>\n</div>\n"
        ."</div>"
        */
        
        ."<table cellspacing=0 cellpadding=0 border=0 bordercolor=#000000 "
        ." width=100% align=center class='wc_font_shrink'>\n"
        ."<tbody style='visibility:visible;'>\n"
        ."<tr>\n"
        ."    <td id='id_wcgridhdr_seqno' class='wc_grid_header' width='".$gridwidth['seqno']."%'>#</td>\n"
        ."    <td id='id_wcgridhdr_category' class='wc_grid_header' width='".$gridwidth['category']."%'><div id='id_inwcgridhdr_category' class='yui-skin-sam'>Category</div></td>\n"
        ."    <td id='id_wcgridhdr_id' class='wc_grid_header' width='".$gridwidth['id']."%'>ID</td>\n"
        ."    <td id='id_wcgridhdr_name' class='wc_grid_header' width='".$gridwidth['name']."%'><nobr>Course Name</nobr></td>\n"
        ."    <td id='id_wcgridhdr_mbrs' class='wc_grid_header' align='right' width='".$gridwidth['mbrs']."%'><nobr>Mbrs</nobr></td>\n"
        ."    <td id='id_wcgridhdr_copybtn'  align='center' class='wc_grid_header' width='".$gridwidth['copybtn']."%'><nobr>>></nobr></td>\n"
        ."    <td id='id_wcgridhdr_seats' align='left' class='wc_grid_header' width='".$gridwidth['seats']."%'><nobr>Seats</nobr></td>\n"
        ."    <td id='id_wcgridhdr_username' align='right' class='wc_grid_header' width='".$gridwidth['username']."%'><nobr>Username</nobr></td>\n"
        ."    <td id='id_wcgridhdr_usergen' align='center' class='wc_grid_header' width='".$gridwidth['usergen']."%'><nobr>Gen</nobr></td>\n"
        ."    <td id='id_wcgridhdr_password' align='right' class='wc_grid_header' width='".$gridwidth['password']."%'><nobr>Password</nobr></td>\n"
        ."    <td id='id_wcgridhdr_passgen' align='center' class='wc_grid_header' width='".$gridwidth['passgen']."%'><nobr>Gen</nobr></td>\n"
        ;
        if ($CFG->webconference_exposetimezone == 'Y') {
            echo "    <td id='id_wcgridhdr_timezone' align='left' class='wc_grid_header' width='".$gridwidth['timezone']."%'><nobr>Timezone</nobr></td>\n";
        }
        if ($CFG->webconference_exposecountry == 'Y') {
            echo "    <td id='id_wcgridhdr_country' align='left' class='wc_grid_header' width='".$gridwidth['country']."%'><nobr>Country</nobr></td>\n";
        }
        
        echo "</tr></tbody></table>\n"                
        // ."</div>\n" // padleft
        // ."<div id='wccoursebody_padright' class='wcgridwrapper' style='width: 20px;'>&nbsp;</div>\n"
        ."</div>\n"
        ."<div id='wccoursebody_hdrwrap' class='wc_grid_header'>"        
        ."&nbsp;</div>" // header        
        ."<div id='wccoursebody_grid' class='wc_grid_container'>\n" 
        /*
        ."<tbody style='visibility:hidden; display:none;'>\n"
        ."<tr>\n"
        ."    <td class='wc_grid_header' width='".$gridwidth['seqno']."%'>#</td>\n"
        ."    <td class='wc_grid_header' width='".$gridwidth['category']."%'>Category</td>\n"
        ."    <td class='wc_grid_header' width='".$gridwidth['id']."%'>ID</td>\n"
        ."    <td class='wc_grid_header' width='".$gridwidth['name']."%'><nobr>Course Name</nobr></td>\n"
        ."    <td class='wc_grid_header' width='".$gridwidth['mbrs']."%'><nobr>Mbrs</nobr></td>\n"
        ."    <td class='wc_grid_header' width='".$gridwidth['copybtn']."%'><nobr> >> </nobr></td>\n"
        ."    <td class='wc_grid_header' width='".$gridwidth['seats']."%'><nobr>Seats</nobr></td>\n"
        ."    <td class='wc_grid_header' align='right' style='text-align: right; width:".$gridwidth['username']."%' width='".$gridwidth['username']."%'><nobr>Username</nobr></td>\n"
        ."    <td class='wc_grid_header' width='".$gridwidth['usergen']."'><nobr>Gen</nobr></td>\n"
        ."    <td class='wc_grid_header' align='right' style='text-align: right; width:".$gridwidth['password']."%' width='".$gridwidth['password']."%'><nobr>Password</nobr></td>\n"
        ."    <td class='wc_grid_header' width='".$gridwidth['passgen']."%'><nobr>Gen</nobr></td>\n</tr>\n"
        ."</tbody>\n"
        */
        ;
 
}
/**
 * Print the admin's course to seat grid. 
 * This is the inner portion of the webconference seat assignment grid
 * Routine will print out a <div> table
 *
 * @param string $categoryid 'all' or a number
 * @param int $pagenumber
 * @param int $recordsperpage
 * @param string $searchstring
 * @param int &$totalcount
 */
function webconference_print_admin_seat_grid($categoryid='all',$pagenumber=0,$recordsperpage=5, $searchstring=NULL, &$totalcount) {
    global $CFG;
    global $gridwidth;
    // searchterms is an array of words to search for
    
    //get_courses_search($searchterms, $sort='fullname ASC', $page=0, $recordsperpage=50, &$totalcount) {
    //get_courses_page($categoryid="all", $sort="c.sortorder ASC", $fields="c.*",
    //                 &$totalcount, $limitfrom="", $limitnum="") {
    //$categoryid = 'all';
    //$pagenumber = 0;
    //$recordsperpage = 5;
    echo "<div id='wc_seat_form_page". $pagenumber ."'><table cellspacing=0 cellpadding=0 border=0 bordercolor=#000000 "
        ." width=100% align=center class='wc_font_shrink'>\n"
        ;
    // Currently the search is detached from the grid. 
    // This is because I wanted to try out formslib 
    // on the search, but felt it would make the grid 
    // design too complex and less flexible 
    // as I was developing.   
    // --> Push the categoryid and searchstring into the posted form. This will
    //     force the outgoing results to match what was on the screen before the update. 
    echo "<input type=hidden name='searchstring' value='".$searchstring."'>\n";    
    echo "<input type=hidden name='categoryid' value='".$categoryid."'>\n";    
    $limitfrom = $pagenumber * $recordsperpage;
    $ctxs = array();
    
    if ($searchstring) {
        $searchterms = explode(" ", $searchstring);    // Search for words independently
        foreach ($searchterms as $key => $searchterm) {
            if (strlen($searchterm) < 2) {
                unset($searchterms[$key]);
            }
        }
        $search = trim(implode(" ", $searchterms));
    
        if (!$courses = get_courses_search($searchterms, "fullname ASC", $pagenumber, $recordsperpage+1, &$totalcount )) {
           webconference_print_no_records_row();        }
    }
    else {
        // Get one more in case we match on site name
        // site omitted later.
        if (!($courses = get_courses_page($categoryid, "c.sortorder ASC", "c.*",
                                        &$totalcount, $limitfrom+1, $recordsperpage+1))) {
            //error("Unable to get courses no search");
            webconference_print_no_records_row();
            // use for debugging
            //foreach ($courses as $course) {
            // $thiscontext = get_context_instance(CONTEXT_COURSE, $course->id);
            //    $ctxs[$thiscontext->id] = 1;
            //    echo $course->id."<br />";
            //}
            //echo "";                                         
        }
    }
    $categories = get_categories();
    foreach ($categories as $cat) {
        $categorylookup[$cat->id] = $cat->name;    
    }
    $cssalt=0;
    
    echo "<tbody>\n";
    
    $seq = $limitfrom + 1 ; // limit starts from 0
    $rcount = 1;    
    $strcourseids=''; // This is for printing after form is done.
    $courseids = array(); // This is for functions that need an array.
    
    foreach ($courses as $course) {
         $strcourseids .= $course->id.",";         
         $courseids[] = $course->id;
    }
    $strcourseids = rtrim ($strcourseids, ',');
    
    $webconfusers = webconference_get_users_in_courseids($courseids);
    $wcusercourseidx = array();
    foreach ($webconfusers as $wckey => $wcuser) {
        $wcusercourseidx[$wcuser->course] = $wckey; 
    }
    foreach ($courses as $course) {
         if ($rcount > $recordsperpage) {
             break;
         }
         //$confuser = $webconfusers[$wcusercourseidx[$course->id]];
         $participants[$course->id] = webconference_get_participants_in_course($course->id);
         if ($participants[$course->id] == -1) { // site returns -1
              continue;
         }
         $cssname = 'wc_item_odd';
         if ($cssalt == 0) {
              $cssname = 'wc_item_odd';
              $cssalt = 1;
         }
         else {
              $cssname = 'wc_item_even';
              $cssalt = 0;          
         }
         $context = get_context_instance(CONTEXT_COURSE, $course->id);   
         $partlink = $CFG->wwwroot ."/user/index.php?contextid=".$context->id;
         $use_seats = "";
         $use_username = "";
         $use_password = "";
         $use_timezone = $CFG->webconference_timezone;
         $csarr = explode(':',$CFG->webconference_country);
         $use_country = $csarr[0];
         $use_state = $csarr[1];
         if (
             (!empty($wcusercourseidx[$course->id])) &&
             (!empty($webconfusers[$wcusercourseidx[$course->id]]))
            ) {
            $use_seats = $webconfusers[$wcusercourseidx[$course->id]]->seats;
            $use_username = $webconfusers[$wcusercourseidx[$course->id]]->wc_username;
            $use_password = $webconfusers[$wcusercourseidx[$course->id]]->wc_password;
            $use_timezone = $webconfusers[$wcusercourseidx[$course->id]]->wc_timezone;
            $use_country = $webconfusers[$wcusercourseidx[$course->id]]->wc_country;
            $use_state = $webconfusers[$wcusercourseidx[$course->id]]->wc_state;
            }
         echo "<input type=hidden name='wc_name_".$course->id."' value='".$course->fullname."'>\n"
             ."<input type=hidden name='wc_category_".$course->id."' value='".$categorylookup[$course->category]."'>\n"
             ."<tr class='wc_grid_item ".$cssname."'>\n"
             ." <td width='".$gridwidth['seqno']."%'>".$seq."</td>\n"
             ." <td width='".$gridwidth['category']."%'>".$categorylookup[$course->category]."</td>\n"
             ." <td width='".$gridwidth['id']."%'>".$course->id ."</td>\n"
             ." <td width='".$gridwidth['name']."%'>".$course->fullname."</td>\n"
             ." <td align='right' width='".$gridwidth['mbrs']."%'>"."<div id='id_wc_mbrs_".$course->id."' class='wc_grid_link wc_grid_padrt'><a class='wc_grid_mbr_lnk' id='id_wc_l_mbrs_".$course->id."' href='".$partlink."'>".$participants[$course->id]."</a></div></td>\n"
             ." <td width='".$gridwidth['copybtn']."%' align='center'>"."<input class='wc_gridform_font wc_copybtn' type=button id='id_wc_copybtn_".$course->id."' name='wc_copybtn_".$course->id."' value='>>'>"."</td>\n"
             ." <td width='".$gridwidth['seats']."%'>"."<input class='wc_gridform_font wc_grid_seats_fld' type=text size=4 id='id_wc_seats_".$course->id."' name='wc_seats_".$course->id."' value='".$use_seats."'></td>\n"
             ." <td align='right' style='font-size: 10px; text-align: right; width:".$gridwidth['username']."%' width='".$gridwidth['username']."%'>"."<input class='wc_gridform_font wc_grid_usr_fld' type=text size=10 id='id_wc_username_".$course->id."' name='wc_username_".$course->id."' value=\"".$use_username."\"></td>\n"
             ." <td width='".$gridwidth['usergen']."%'>"."<input class='wc_gridform_font wc_grid_usr_btn' type=button id='id_wc_btn_usergen_".$course->id."' name='wc_btn_usergen_".$course->id."' value='Gen'></td>\n"
             ." <td align='right' style='font-size: 10px; text-align: right; width:".$gridwidth['password']."' width='".$gridwidth['password']."%'>"."<input class='wc_gridform_font wc_grid_pwd_fld' type=text size=8 id='id_wc_password_".$course->id."' name='wc_password_".$course->id."' value=\"".$use_password."\"></td>\n"
             ." <td width='".$gridwidth['passgen']."%'>"."<input class='wc_gridform_font wc_grid_pwd_btn' type=button id='id_wc_btn_passgen_".$course->id."' name='wc_btn_passgen_".$course->id."' value='Gen'></td>\n"
             ;
         if ($CFG->webconference_exposetimezone == 'Y') {
             echo " <td width='".$gridwidth['timezone']."%'>";
             webconference_print_timezone_select('wc_timezone_'.$course->id,$use_timezone);
             echo "</td>\n";              
         }
         if ($CFG->webconference_exposecountry == 'Y') {
             echo " <td width='".$gridwidth['country']."%'>";
             webconference_print_countrystate_select('wc_countrystate_'.$course->id,$use_country.':'.$use_state);
             echo "</td>\n";              
         }
         echo "</tr>\n";
         $rcount++; $seq++;
    }             
    if ($rcount > $recordsperpage) {
       $rcount = $recordsperpage;
    }
    echo "</tbody></table></div>\n";
    echo "<input type=hidden name='wcseat_courseids' value='".$strcourseids."'>\n";
    return $rcount;
}

/**
 * Gets participants for 
 *
 * @param unknown_type $courseids
 * @return unknown
 */
function webconference_get_participants_in_course($courseid) {
    global $CFG;
    
    $context = get_context_instance(CONTEXT_COURSE, $courseid);       
    $frontpagectx = get_context_instance(CONTEXT_COURSE, SITEID);
    if ($context->id == $frontpagectx->id) {
       return -1;
    }
    $selectrole = "";
    $sitecontext = get_context_instance(CONTEXT_SYSTEM);
    $doanythingroles = get_roles_with_capability('moodle/site:doanything', CAP_ALLOW, $sitecontext);
    if ($roles = get_roles_used_in_context($context, true)) {
        // We should ONLY allow roles with moodle/course:view because otherwise we get little niggly issues
        // like MDL-8093
        // We should further exclude "admin" users (those with "doanything" at site level) because
        // Otherwise they appear in every participant list

        $canviewroles    = get_roles_with_capability('moodle/course:view', CAP_ALLOW, $context);
        $doanythingroles = get_roles_with_capability('moodle/site:doanything', CAP_ALLOW, $sitecontext);

        // we are looking for all users with this role assigned in this context or higher
        if ($usercontexts = get_parent_contexts($context)) {
            $listofcontexts = '('.implode(',', $usercontexts).')';
        } else {
            return -1;
            //$listofcontexts = '('.$sitecontext->id.')'; // must be site
        }
        /* --> We do not have a roleid
        if ($roleid > 0) {
           $selectrole = " AND r.roleid = $roleid ";
        } else {
           $selectrole = " ";
        }
        */
        
        // if you print the front page (SITE course) use this logic
        /*
        if ($context->id == $frontpagectx->id) {
            //we want admins listed on frontpage too
            foreach ($doanythingroles as $dar) {
                $canviewroles[$dar->id] = $dar;
            }
            $doanythingroles = array();
        }
        */
        
        foreach ($roles as $role) {
            if (!isset($canviewroles[$role->id])) {   // Avoid this role (eg course creator)
                $avoidroles[] = $role->id;
                unset($roles[$role->id]);
                continue;
            }
            if (isset($doanythingroles[$role->id])) {   // Avoid this role (ie admin)
                $avoidroles[] = $role->id;
                unset($roles[$role->id]);
                continue;
            }
            $rolenames[$role->id] = strip_tags(role_get_name($role, $context));   // Used in menus etc later on
        }
    }
    if ($avoidroles) {
        $adminroles = 'AND r.roleid NOT IN (';
        $adminroles .= implode(',', $avoidroles);
        $adminroles .= ')';
    } else {
        $adminroles = '';
    }
    
    $hiddensql = '';
    
    $select = 'SELECT u.id, u.username, u.firstname, u.lastname,
               u.email, u.city, u.country, u.picture,
               u.lang, u.timezone, u.emailstop, u.maildisplay, u.imagealt,
               u.lastaccess,
               ctx.id AS ctxid, ctx.path AS ctxpath,
               ctx.depth AS ctxdepth, ctx.contextlevel AS ctxlevel';
    $from = "FROM {$CFG->prefix}user u
              LEFT OUTER JOIN {$CFG->prefix}context ctx
              ON (u.id=ctx.instanceid AND ctx.contextlevel = ".CONTEXT_USER.") 
             JOIN {$CFG->prefix}role_assignments r
              ON u.id=r.userid
             LEFT OUTER JOIN {$CFG->prefix}user_lastaccess ul
              ON (r.userid=ul.userid and ul.courseid = $courseid ) "; 
    $where = "WHERE (r.contextid = $context->id OR r.contextid in $listofcontexts)
              AND u.deleted = 0 $selectrole 
              AND u.username != 'guest'
              $adminroles
              $hiddensql ";
    $where .= wc_get_course_lastaccess_sql('');
              
    //$matchcount = get_records_sql('SELECT COUNT(distinct u.id) '.$from.$where.$wheresearch);
    $totalcount = count_records_sql('SELECT COUNT(distinct u.id) '.$from.$where);   // Each user could have > 1 role
    return $totalcount; 
}

function wc_get_course_lastaccess_sql($accesssince='') {
    if (empty($accesssince)) {
        return '';
    }
    if ($accesssince == -1) { // never
        return ' AND ul.timeaccess = 0';
    } else {
        return ' AND ul.timeaccess != 0 AND ul.timeaccess < '.$accesssince;
    }
}

function webconference_update_wc_times($webconferenceid=0) {
    /// Updates records so that the next meeting time is correct

    $timenow = time();
    if ($webconferenceid) {
        if (!$conferences[] = get_record_select('webconference', "id = '$webconferenceid' AND startdttm <= '$timenow'")) {
            return;
        }
    } else {
        if (!$conferences = get_records_select('webconference', "startdttm <= '$timenow'")) {
            return;
        }
    }

    foreach ($conferences as $conference) {
        unset($conference->name);
        unset($conference->description);
        /*
        switch ($conference->repeattimes) {
            case 'S': // Single event - turn off schedule and disable
                    $conference->startdttm = 0;
                    $conference->schedule = 0;
                    break;
            case 'D': // Repeat daily
                    $conference->startdttm += 24 * 3600;
                    break;
            case 'W': // Repeat weekly
                    $conference->startdttm += 7 * 24 * 3600;
                    break;
        }
        */
        update_record('webconference', $conference);

        $event = NULL;           // Update calendar too
        if ($event->id = get_field('event', 'id', 'modulename', 'webconference', 'instance', $conference->id)) {
            $event->timestart   = $conference->startdttm;
            update_event($event);
        }
    }
}

function webconference_get_latest_message($webconferenceid, $groupid=0) {
    /// Efficient way to extract just the latest message
    /// Uses ADOdb directly instead of get_record_sql()
    /// because the LIMIT command causes problems with
    /// debugging

    global $db, $CFG;

    if ($groupid) {
        $groupselect = " AND (groupid='$groupid' OR groupid='0')";
    } else {
        $groupselect = "";
    }

    if (!$rs = $db->Execute("SELECT *
                               FROM {$CFG->prefix}webconference_messages
                              WHERE webconferenceid = '$webconferenceid' $groupselect
                           ORDER BY timestamp DESC LIMIT 1")) {
        return false;
    }
    if ($rs->RecordCount() == 1) {
        return (object)$rs->fields;
    } else {
        return false; // Nothing found
    }
}

function webconference_format_message_manually($message, $courseid, $sender, $currentuser, $conference_lastrow=NULL) {
    global $CFG, $USER;

    $output = New stdClass;
    $output->beep = false;       // by default
    $output->refreshusers = false; // by default

    // Use get_user_timezone() to find the correct timezone for displaying this message:
    // It's either the current user's timezone or else decided by some Moodle config setting
    // First, "reset" $USER->timezone (which could have been set by a previous call to here)
    // because otherwise the value for the previous $currentuser will take precedence over $CFG->timezone
    $USER->timezone = 99;
    $tz = get_user_timezone($currentuser->timezone);

    // Before formatting the message time string, set $USER->timezone to the above.
    // This will allow dst_offset_on (called by userdate) to work correctly, otherwise the
    // message times appear off because DST is not taken into account when it should be.
    $USER->timezone = $tz;
    $message->strtime = userdate($message->timestamp, get_string('strftimemessage', 'webconference'), $tz);

    $message->picture = print_user_picture($sender->id, 0, $sender->picture, false, true, false);
    if ($courseid) {
        $message->picture = "<a target=\"_new\" href=\"$CFG->wwwroot/user/view.php?id=$sender->id&amp;course=$courseid\">$message->picture</a>";
    }

    //Calculate the row class
    if ($webconference_lastrow !== NULL) {
        $rowclass = ' class="r'.$webconference_lastrow.'" ';
    } else {
        $rowclass = '';
    }

    // Start processing the message

    if(!empty($message->system)) {
        // System event
        $output->text = $message->strtime.': '.get_string('message'.$message->message, 'webconference', fullname($sender));
        $output->html  = '<table class="webconference-event"><tr'.$rowclass.'><td class="picture">'.$message->picture.'</td><td class="text">';
        $output->html .= '<span class="event">'.$output->text.'</span></td></tr></table>';

        if($message->message == 'exit' or $message->message == 'enter') {
            $output->refreshusers = true;
        }

        return $output;
    }

    // It's not a system event

    $text = $message->message;

    /// Parse the text to clean and filter it

    $options->para = false;
    $text = format_text($text, FORMAT_MOODLE, $options, $courseid);

    // And now check for special cases

    if (substr($text, 0, 5) == 'beep ') {
        /// It's a beep!
        $beepwho = trim(substr($text, 5));

        if ($beepwho == 'all') {   // everyone
            $outinfo = $message->strtime.': '.get_string('messagebeepseveryone', 'webconference', fullname($sender));
            $outmain = '';
            $output->beep = true;  
                                   

        } else if ($beepwho == $currentuser->id) {  
            $outinfo = $message->strtime.': '.get_string('messagebeepsyou', 'webconference', fullname($sender));
            $outmain = '';
            $output->beep = true;

        } else {
            return false;
        }
    } else if (substr($text, 0, 1) == ':') {              /// It's an MOO emote
        $outinfo = $message->strtime;
        $outmain = $sender->firstname.' '.substr($text, 1);

    } else if (substr($text, 0, 1) == '/') {     /// It's a user command

        if (substr($text, 0, 4) == "/me ") {
            $outinfo = $message->strtime;
            $outmain = $sender->firstname.' '.substr($text, 4);
        } else {
            $outinfo = $message->strtime;
            $outmain = $text;
        }

    } else {                                        /// normal message
        $outinfo = $message->strtime.' '.$sender->firstname;
        $outmain = $text;
    }

    /// Format the message as a small table

    $output->text  = strip_tags($outinfo.': '.$outmain);

    $output->html  = "<table class=\"webconference-message\"><tr$rowclass><td class=\"picture\">$message->picture</td><td class=\"text\">";
    $output->html .= "<span class=\"title\">$outinfo</span>";
    if ($outmain) {
        $output->html .= ": $outmain";
    }
    $output->html .= "</td></tr></table>";

    return $output;
}

function webconference_format_message($message, $courseid, $currentuser, $conference_lastrow=NULL) {
    ///  Formats a given message for output
    if (!$user = get_record("user", "id", $message->userid)) {
        return "Error finding user id = $message->userid";
    }

    return webconference_format_message_manually($message, $courseid, $user, $currentuser, $conference_lastrow);

}

function webconference_get_teachers_from_course_context($course, $context) {
    $canviewfullnames = has_capability('moodle/site:viewfullnames', $context);
        if (isset($course->managers)) {
            if (count($course->managers)) {
                $rusers = $course->managers;
                foreach ($rusers as $ra) {
                $fullname = fullname($ra->user, $canviewfullnames);
            }
        }
    }
    else {
        $managerroles = split(',', $CFG->coursemanager);
        $rusers = get_role_users($managerroles, $context,
                  true, '', 'r.sortorder ASC, u.lastname ASC', $canseehidden);
        if (is_array($rusers) && count($rusers)) {
            $canviewfullnames = has_capability('moodle/site:viewfullnames', $context);

            /// Rename some of the role names if needed
            if (isset($context)) {
                $aliasnames = get_records('role_names', 'contextid', $context->id,'','roleid,contextid,name');
            }

            foreach ($rusers as $teacher) {
                $fullname = fullname($teacher, $canviewfullnames);
                /// Apply role names
                if (isset($aliasnames[$teacher->roleid])) {
                    $teacher->rolename = $aliasnames[$teacher->roleid]->name;
                }

                $namesarray[] = format_string($teacher->rolename)
                                . ': <a href="'.$CFG->wwwroot.'/user/view.php?id='.$teacher->id.'&amp;course='.SITEID.'">'
                                . $fullname . '</a>';                    
            }
        }
    }    
    return $namesarray;
}

function webconference_context($conference) {
    //TODO: add some $cm caching if needed
    if (is_object($conference)) {
        $conference = $conference->id;
    }
    if (! $cm = get_coursemodule_from_instance('webconference', $conference)) {
        error(get_string('errornocoursemodule','webconference'));
    }

    return get_context_instance(CONTEXT_MODULE, $cm->id);
}

function webconference_is_teacher($conference, $userid=NULL) {
    return has_capability('mod/webconference:manage', webconference_context($conference), $userid);
}

if (!function_exists('ob_get_clean')) {
/// Compatibility function for PHP < 4.3.0
    function ob_get_clean() {
        $cont = ob_get_contents();
        if ($cont !== false) {
            ob_end_clean();
            return $cont;
        } else {
            return $cont;
        }
    }
}
?>
Return current item: WebConference Plugin for Moodle