/** * Writes timestamped data into log file * * @param string $data data to be written */ static function write($data) { global $CFG; if (!mod_opencast_series::getValueForKey('logging_enabled')) { return; } $logdir = $CFG->dataroot . '/mod/opencast'; if (!file_exists($logdir)) { mkdir($logdir, 0755, true); } $logfile = $logdir . '/opencast_api.log'; if (!is_writable($logdir)) { print_error('nologfilewrite', 'opencast', null, $logfile); } $date = date("Y-m-d H:i:s (T)"); $logged = error_log($date . "\n" . $data . "\n\n", 3, $logfile); if (!$logged) { print_error('nologfilewrite', 'opencast', null, $logfile); } }
/** * Updates event metadata at SWITCHCast server * * @return bool true if succesful */ public function update() { // TODO WAIT FOR SWITCH : can not send empty strings (to remove e.g. description), see my e-mail to switch-api on 20150703 // first, update clip metadata $event_metadata = ['metadata' => json_encode([['id' => 'title', 'value' => $this->getTitle()], ['id' => 'isPartOf', 'value' => $this->series->getExtId()], ['id' => 'description', 'value' => $this->getSubtitle()], ['id' => 'location', 'value' => $this->getLocation()], ['id' => 'creator', 'value' => explode(',', $this->getPresenter())]], JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE)]; mod_opencast_apicall::sendRequest('/events/' . $this->getExtId() . '/metadata?type=dublincore/episode', 'PUT', $event_metadata); // second, update ACLs with (possibly) new owner : // 1.- get current ACLs $event_acls = mod_opencast_apicall::sendRequest('/events/' . $this->getExtId() . '/acl', 'GET', null, false, true, null, false, true); // 2.- delete any ACL that is not the system_user $new_acls = []; while ($acl = array_pop($event_acls)) { if (preg_match('/^ROLE\\_AAI\\_USER\\_([^\\_]+)$/', $acl->role, $matches) && $matches[1] != mod_opencast_series::getValueForKey('default_sysaccount')) { // drop ACL (i.e. do nothing) } else { // user is either OpenCast internal, or system_user -> keep ACL $new_acls[] = $acl; } } // 3.- add specified owner $new_acls[] = ['action' => 'write', 'allow' => true, 'role' => 'ROLE_AAI_USER_' . $this->getOwner()]; if ($this->series->getIvt()) { $new_acls[] = ['action' => 'write', 'allow' => true, 'role' => 'ROLE_USER_IVT_AAI_' . $this->getOwner()]; } $data = ['acl' => json_encode($new_acls, JSON_UNESCAPED_SLASHES)]; mod_opencast_apicall::sendRequest('/events/' . $this->getExtId() . '/acl', 'PUT', $data); return true; }
$mod_opencast_clip->owner_name = ''; } else { $mod_opencast_clip->owner_name = 'SOME_NAME'; } $allclips[$clip['identifier']] = $mod_opencast_clip; } else { $mod_opencast_clip = $allclips[$clip['identifier']]; } $all_clip_objs[] = $mod_opencast_clip; } } usort($clip_objs, 'opencast_clip_sort'); if ($sortdir == 'desc') { $clip_objs = array_reverse($clip_objs); } $visible_clips = array_slice($clip_objs, $offset, $length); $json = ['count' => count($clip_objs), 'clips' => $visible_clips]; if (mod_opencast_series::getValueForKey('display_select_columns')) { $json['allclips'] = $all_clip_objs; } echo json_encode($json); function opencast_clip_sort($a, $b) { global $sortkey; if ($a->{$sortkey} > $b->{$sortkey}) { return 1; } else { return -1; } return 0; }
/** * @param string $url * * @return mixed */ static function hashfilename($url = '') { $f = str_replace(mod_opencast_series::getValueForKey('switch_api_host'), '', $url); $f = str_replace(mod_opencast_series::getValueForKey('default_sysaccount'), '', $f); $f = preg_replace('/[^a-zA-Z0-9]/', '_', $f); $f = preg_replace('/^(_)+/', '', $f); // return sha1($f); return $f; }
/** * * @param type $enforceglobalmax * * @return array */ public static function getMaxfilesizes($enforceglobalmax = false) { $sizemb = get_string('sizemb'); $sizes = [5 * 1024 * 1024 => '5 ' . $sizemb, 10 * 1024 * 1024 => '10 ' . $sizemb, 20 * 1024 * 1024 => '20 ' . $sizemb, 50 * 1024 * 1024 => '50 ' . $sizemb, 100 * 1024 * 1024 => '100 ' . $sizemb, 250 * 1024 * 1024 => '250 ' . $sizemb, 500 * 1024 * 1024 => '500 ' . $sizemb]; if ($enforceglobalmax) { // enforme global maximum $globalmax = mod_opencast_series::getValueForKey('userupload_maxfilesize'); foreach ($sizes as $size => $label) { if ($size > $globalmax) { unset($sizes[$size]); } } } return $sizes; }
if (!$DB->insert_record('opencast_uploadedclip', $uploaded_clip)) { print_error('error'); } $eventparams = ['context' => $context, 'objectid' => $opencast->id]; $event = \mod_opencast\event\clip_uploaded::create($eventparams); $event->add_record_snapshot('course_modules', $cm); $event->add_record_snapshot('course', $course); $event->add_record_snapshot('opencast', $opencast); $event->trigger(); redirect($return_channel); } else { // no data submitted yet; display recap & form echo $OUTPUT->header(); $renderer = $PAGE->get_renderer('mod_opencast'); echo html_writer::tag('h2', get_string('upload_clip', 'opencast')); $upl_help = $OUTPUT->help_icon('upload_clip_misc', 'opencast', ''); $upl_a = mod_opencast_series::getValueForKey('uploadfile_extensions'); echo html_writer::tag('p', get_string('upload_clip_info', 'opencast', $upl_a) . $upl_help); $renderer->display_user_pending_clips(true, true, false, false, false); // The following two set_context()'s are a dirty hack, but we have to do this, // otherwise the couse/site maxbytes limit is enforced. // (see MoodleQuickForm_filemanager class constructor) $PAGE->set_context($usercontext); if ($formdata = unserialize(optional_param('formdata', '', PARAM_RAW_TRIMMED))) { $mform->set_data($formdata); } $mform->display(); $PAGE->set_context($context); echo html_writer::link($return_channel, get_string('back_to_channel', 'opencast')); echo $OUTPUT->footer(); }
print_error('invalidcoursemodule', null, $return_course); } if (!($context = context_module::instance($cm->id))) { print_error('badcontext', null, $return_course); } require_login($course); require_capability('mod/opencast:use', $context); $url = base64_decode($url_b64); $salt = base64_decode($salt_b64); $token = base64_decode($token_b64); if ($token == sha1(mod_opencast_series::getValueForKey('default_sysaccount') . $salt . $opencast->id . $url)) { $eventparams = ['context' => $context, 'objectid' => $opencast->id]; $event = \mod_opencast\event\clip_viewed::create($eventparams); $event->add_record_snapshot('course_modules', $cm); $event->add_record_snapshot('course', $course); $event->add_record_snapshot('opencast', $opencast); $event->trigger(); // 1.- request signing of the URL $time = time(); $validity_time_seconds = 60; $valid_until = $time + $validity_time_seconds; $signing_request_params = ['url' => $url, 'valid-until' => date('Y-m-d', $valid_until) . 'T' . gmdate('H:i:s', $valid_until) . 'Z']; if (mod_opencast_series::getValueForKey('use_ipaddr_restriction')) { $signing_request_params['valid-source'] = getremoteaddr(); } $signed_url = mod_opencast_apicall::sendRequest('/security/sign', 'POST', $signing_request_params); // 2.- redirect to signed URL header("Location: " . $signed_url->url); exit; } print_error('redirfailed', 'opencast');
/** * Returns a Moodle user ID if one is found with the provided SWITCHaai unique ID * * @param string $ext_id SWITCHaai unique ID * * @return int Moodle user ID */ public static function getMoodleUserIdFromExtId($ext_id = '') { global $DB; $moodleid = false; if ($ext_id === '') { return false; } $uid_field = mod_opencast_series::getValueForKey('uid_field'); if (strpos($uid_field, '::') !== false) { $params = explode('::', $uid_field); $table = $params[0]; $fieldid = $params[1]; $u = $DB->get_record_select($table, $DB->sql_compare_text('data') . ' = \'' . (string) $ext_id . '\' AND fieldid = ' . (int) $fieldid, [], '*', IGNORE_MULTIPLE); if ($u) { $moodleid = $u->userid; } } else { $u = $DB->get_record('user', [$uid_field => (string) $ext_id]); if ($u) { $moodleid = $u->id; } } return (int) $moodleid; }
function definition() { global $CFG, $PAGE; $mform =& $this->_form; // some checks, before going any further $scuser = new mod_opencast_user(); if (empty($this->_instance) && $scuser->getExternalAccount() == '') { // $USER has no SWITCHaai account and is attempting to create a new activity instance: // he cannot create a channel nor link to an existing channel (because he doesn't own // any, as he doesn't exist in SwitchCast). Therefore, we prevent him from going any further. print_error('user_notaai', 'opencast', new moodle_url('/course/view.php', ['id' => (int) $this->current->course])); } else { if (empty($this->_instance) && !in_array(mod_opencast_series::getOrganizationByEmail($scuser->getExternalAccount()), mod_opencast_series::getEnabledOrgnanizations())) { // $USER has a SWITCHaai account, but we don't have a sys_account for his HomeOrganization. // Therefore, we prevent him from going any further. // TODO remove as we're now only using local org (i.e. unil.ch for us) // print_error('user_homeorgnotenabled', 'opencast', // new moodle_url('/course/view.php', ['id' => (int)$this->current->course]), // mod_opencast_series::getOrganizationByEmail($scuser->getExternalAccount())); } } if (!empty($this->_instance) && !in_array($this->current->organization_domain, mod_opencast_series::getEnabledOrgnanizations())) { // TODO remove as we're now only using local org (i.e. unil.ch for us) // print_error('badorganization', 'opencast', // new moodle_url('/course/view.php', ['id' => (int)$this->current->course])); } if ($scuser->getExternalAccount() != '') { // $USER has a SWITCHaai account, so register him at SwitchCast to make sure it exists there // mod_opencast_obj::registerUser($scuser); } // have we got a sys_account for the channel? $sysaccount = false; if (!empty($this->_instance) && in_array($this->current->organization_domain, mod_opencast_series::getEnabledOrgnanizations())) { // TODO remove as we're now only using local org (i.e. unil.ch for us) // $sysaccount_extid = mod_opencast_series::getSysAccountByOrganization($this->current->organization_domain); // $sysaccount = new mod_opencast_user($sysaccount_extid); } $PAGE->requires->jquery(); $PAGE->requires->js('/mod/opencast/js/existing_series.js'); // General settings : $mform->addElement('header', 'general', get_string('general', 'form')); $mform->addElement('text', 'name', get_string('opencastname', 'opencast'), ['size' => '64']); if (!empty($CFG->formatstringstriptags)) { $mform->setType('name', PARAM_TEXT); } else { $mform->setType('name', PARAM_CLEANHTML); } $mform->addRule('name', null, 'required', null, 'client'); $this->standard_intro_elements(); // Miscellaneous settings : $mform->addElement('header', 'miscellaneoussettingshdr', get_string('miscellaneoussettings', 'form')); if (mod_opencast_series::getValueForKey('moreinfo_url')) { $mform->addElement('static', 'moreinfo_url', get_string('miscellaneoussettings_help', 'opencast'), html_writer::link(mod_opencast_series::getValueForKey('moreinfo_url'), mod_opencast_series::getValueForKey('moreinfo_url'))); } $mform->addElement('select', 'channelnew', get_string('channel', 'opencast'), [OPENCAST_CHANNEL_NEW => get_string('channelnew', 'opencast'), OPENCAST_CHANNEL_EXISTING => get_string('channelexisting', 'opencast')]); if (empty($this->_instance)) { $mform->setDefault('channelnew', OPENCAST_CHANNEL_NEW); } else { $mform->setDefault('channelnew', OPENCAST_CHANNEL_EXISTING); } $userchannels = $scuser->getChannels(); $channels = []; if (!empty($this->_instance) && $scuser->getExternalAccount() == '') { // Instance exists but $USER is not SWITCHaai => get channels list // from $sysaccount, which MUST exist because we already checked. // We freeze the channel selector further anyway because $USER's // HomeOrg isn't the same as the channel's. $userchannels = $sysaccount->getChannels(); } foreach ($userchannels as $userchannel) { $channels[(string) $userchannel->identifier] = (string) $userchannel->title; } $mform->addElement('select', 'ext_id', get_string('channelchoose', 'opencast'), $channels); $mform->disabledIf('ext_id', 'channelnew', 'eq', OPENCAST_CHANNEL_NEW); $mform->addElement('text', 'newchannelname', get_string('newchannelname', 'opencast')); $mform->disabledIf('newchannelname', 'channelnew', 'eq', OPENCAST_CHANNEL_EXISTING); $mform->setType('newchannelname', PARAM_TEXT); if (!empty($this->_instance)) { $mform->freeze('channelnew'); $mform->removeElement('newchannelname'); } $scast = new mod_opencast_series(); // $scast_licenses = $scast->getAllLicenses(); // $mform->addElement('select', 'license', get_string('license', 'opencast'), $scast_licenses); // $mform->setDefault('license', ''); $annotations = [OPENCAST_NO_ANNOTATIONS => get_string('annotationsno', 'opencast'), OPENCAST_ANNOTATIONS => get_string('annotationsyes', 'opencast')]; $mform->addElement('select', 'allow_annotations', get_string('annotations', 'opencast'), $annotations); $mform->setDefault('allow_annotations', OPENCAST_NO_ANNOTATIONS); // $mod_opencast_templates = mod_opencast_series::getAllTemplates(); // $templates_admin = mod_opencast_series::getEnabledTemplates(); // TODO NOW : remove all about templates // $templates = []; // foreach ($templates_admin as $template_id => $template_name) { // if (array_key_exists($template_id, $mod_opencast_templates)) { // $templates[$template_id] = $template_name; // } // } // $mform->addElement('select', 'template_id', get_string('template_id', 'opencast'), $templates); // $mform->disabledIf('template_id', 'channelnew', 'eq', OPENCAST_CHANNEL_EXISTING); // $mform->addHelpButton('template_id', 'template_id', 'opencast'); $yesno = [0 => get_string('no'), 1 => get_string('yes')]; $mform->addElement('select', 'is_ivt', get_string('is_ivt', 'opencast'), $yesno); $mform->addElement('select', 'inviting', get_string('inviting', 'opencast'), $yesno); $mform->disabledIf('inviting', 'is_ivt', 'eq', 0); if (mod_opencast_series::getValueForKey('allow_userupload') && mod_opencast_series::getValueForKey('userupload_maxfilesize')) { $mform->addElement('select', 'userupload', get_string('allow_userupload', 'opencast'), $yesno); $mform->addElement('select', 'userupload_maxfilesize', get_string('userupload_maxfilesize', 'opencast'), mod_opencast_series::getMaxfilesizes(true)); } if (!empty($this->_instance) && mod_opencast_series::getOrganizationByEmail($scuser->getExternalAccount()) !== $this->current->organization_domain) { // teacher has no SwitchAAI account OR is from a different HomeOrg than the Channel Producer(s), // so check whether we have sys_account for him to see if we can manipulate the channel if ($sysaccount) { // sys_account available -> only freeze channel selection $mform->disabledIf('ext_id', 'channelnew', 'eq', OPENCAST_CHANNEL_EXISTING); } else { // sys_account unavailable -> remove all channel manipulation options and display a notice $mform->removeElement('inviting'); $mform->removeElement('is_ivt'); // $mform->removeElement('template_id'); $mform->removeElement('allow_annotations'); // $mform->removeElement('license'); $mform->removeElement('ext_id'); $mform->removeElement('channelnew'); $mform->removeElement('userupload'); $mform->removeElement('userupload_maxfilesize'); $mform->addElement('html', get_string('channeldoesnotbelong', 'opencast', $this->current->organization_domain)); } } // What if the channel does not exist any more? -> remove all channel manipulation options and display a notice if (!empty($this->_instance) && mod_opencast_series::getOrganizationByEmail($scuser->getExternalAccount()) == $this->current->organization_domain && !isset($channels[$this->current->ext_id])) { $mform->removeElement('inviting'); $mform->removeElement('is_ivt'); // $mform->removeElement('template_id'); $mform->removeElement('allow_annotations'); // $mform->removeElement('license'); $mform->removeElement('ext_id'); $mform->removeElement('channelnew'); $mform->removeElement('userupload'); $mform->removeElement('userupload_maxfilesize'); $mform->addElement('html', html_writer::tag('p', get_string('channel_not_found', 'opencast'), ['class' => 'notify'])); } $this->standard_coursemodule_elements(); $this->add_action_buttons(); }