Exemplo n.º 1
0
$token = external_generate_token_for_current_user($service);
// Log token access.
$DB->set_field('external_tokens', 'lastaccess', time(), array('id' => $token->id));
$params = array('objectid' => $token->id);
$event = \core\event\webservice_token_sent::create($params);
$event->add_record_snapshot('external_tokens', $token);
$event->trigger();
// Passport is generated in the mobile app, so the app opening can be validated using that variable.
// Passports are valid only one time, it's deleted in the app once used.
$siteid = md5($CFG->wwwroot . $passport);
$apptoken = base64_encode($siteid . ':::' . $token->token);
// Redirect using the custom URL scheme checking first if a URL scheme is forced in the site settings.
$forcedurlscheme = get_config('tool_mobile', 'forcedurlscheme');
if (!empty($forcedurlscheme)) {
    $urlscheme = $forcedurlscheme;
}
$location = "{$urlscheme}://token={$apptoken}";
// For iOS 10 onwards, we have to simulate a user click.
if (core_useragent::is_ios()) {
    $PAGE->set_context(null);
    $PAGE->set_url('/local/mobile/launch.php', array('service' => $serviceshortname, 'passport' => $passport, 'urlscheme' => $urlscheme));
    echo $OUTPUT->header();
    $notice = get_string('clickheretolaunchtheapp', 'tool_mobile');
    echo html_writer::link($location, $notice, array('id' => 'launchapp'));
    echo html_writer::script("window.onload = function() {\n            document.getElementById('launchapp').click();\n        };");
    echo $OUTPUT->footer();
} else {
    // For Android a http redirect will do fine.
    header('Location: ' . $location);
    die;
}
Exemplo n.º 2
0
 /**
  * @dataProvider user_agents_providers
  */
 public function test_useragent_ios($useragent, $tests)
 {
     // Setup the core_useragent instance.
     core_useragent::instance(true, $useragent);
     if (isset($tests['is_ios']) && $tests['is_ios']) {
         $this->assertTrue(core_useragent::is_ios(), "Browser was not identified as an iOS device browser");
         $this->assertTrue(core_useragent::check_safari_ios_version());
     } else {
         $this->assertFalse(core_useragent::is_ios(), "Browser was incorrectly identified as an iOS device browser");
         $this->assertFalse(core_useragent::check_safari_ios_version());
     }
 }
Exemplo n.º 3
0
// Passports are valid only one time, it's deleted in the app once used.
$siteid = md5($CFG->wwwroot . $passport);
$apptoken = $siteid . ':::' . $token->token;
if ($privatetoken and is_https() and !$siteadmin) {
    $apptoken .= ':::' . $privatetoken;
}
$apptoken = base64_encode($apptoken);
// Redirect using the custom URL scheme checking first if a URL scheme is forced in the site settings.
$forcedurlscheme = get_config('tool_mobile', 'forcedurlscheme');
if (!empty($forcedurlscheme)) {
    $urlscheme = $forcedurlscheme;
}
$location = "{$urlscheme}://token={$apptoken}";
// For iOS 10 onwards, we have to simulate a user click.
// If we come from the confirmation page, we should display a nicer page.
$isios = core_useragent::is_ios();
if ($confirmed or $isios) {
    $PAGE->set_context(context_system::instance());
    $PAGE->set_heading($COURSE->fullname);
    $params = array('service' => $serviceshortname, 'passport' => $passport, 'urlscheme' => $urlscheme, 'confirmed' => $confirmed);
    $PAGE->set_url("/{$CFG->admin}/tool/mobile/launch.php", $params);
    echo $OUTPUT->header();
    if ($confirmed) {
        $confirmedstr = get_string('confirmed');
        $PAGE->navbar->add($confirmedstr);
        $PAGE->set_title($confirmedstr);
        echo $OUTPUT->notification($confirmedstr, \core\output\notification::NOTIFY_SUCCESS);
        echo $OUTPUT->box_start('generalbox centerpara boxwidthnormal boxaligncenter');
        echo $OUTPUT->single_button(new moodle_url('/course/'), get_string('courses'));
        echo $OUTPUT->box_end();
    }
Exemplo n.º 4
0
 /**
  * Generates code required to embed the player.
  *
  * @param moodle_url[] $urls
  * @param string $name
  * @param int $width
  * @param int $height
  * @param array $options
  * @return string
  */
 public function embed($urls, $name, $width, $height, $options)
 {
     global $CFG;
     require_once $CFG->libdir . '/filelib.php';
     $sources = array();
     $mediamanager = core_media_manager::instance();
     $datasetup = [];
     $text = null;
     $isaudio = null;
     $hastracks = false;
     $hasposter = false;
     if (array_key_exists(core_media_manager::OPTION_ORIGINAL_TEXT, $options) && preg_match('/^<(video|audio)\\b/i', $options[core_media_manager::OPTION_ORIGINAL_TEXT], $matches)) {
         // Original text already had media tag - get some data from it.
         $text = $options[core_media_manager::OPTION_ORIGINAL_TEXT];
         $isaudio = strtolower($matches[1]) === 'audio';
         $hastracks = preg_match('/<track\\b/i', $text);
         $hasposter = self::get_attribute($text, 'poster') !== null;
     }
     // Currently Flash in VideoJS does not support responsive layout. If Flash is enabled try to guess
     // if HTML5 player will be engaged for the user and then set it to responsive.
     $responsive = get_config('media_videojs', 'useflash') && !$this->youtube ? null : true;
     // Build list of source tags.
     foreach ($urls as $url) {
         $extension = $mediamanager->get_extension($url);
         $mimetype = $mediamanager->get_mimetype($url);
         if ($mimetype === 'video/quicktime' && (core_useragent::is_chrome() || core_useragent::is_edge())) {
             // Fix for VideoJS/Chrome bug https://github.com/videojs/video.js/issues/423 .
             $mimetype = 'video/mp4';
         }
         $source = html_writer::empty_tag('source', array('src' => $url, 'type' => $mimetype));
         $sources[] = $source;
         if ($isaudio === null) {
             $isaudio = in_array('.' . $extension, file_get_typegroup('extension', 'audio'));
         }
         if ($responsive === null) {
             $responsive = core_useragent::supports_html5($extension);
         }
     }
     $sources = implode("\n", $sources);
     // Find the title, prevent double escaping.
     $title = $this->get_name($name, $urls);
     $title = preg_replace(['/&amp;/', '/&gt;/', '/&lt;/'], ['&', '>', '<'], $title);
     if ($this->youtube) {
         $datasetup[] = '"techOrder": ["youtube"]';
         $datasetup[] = '"sources": [{"type": "video/youtube", "src":"' . $urls[0] . '"}]';
         $sources = '';
         // Do not specify <source> tags - it may confuse browser.
         $isaudio = false;
         // Just in case.
     }
     // Add a language.
     if ($this->language) {
         $datasetup[] = '"language": "' . $this->language . '"';
     }
     // Set responsive option.
     if ($responsive) {
         $datasetup[] = '"fluid": true';
     }
     if ($isaudio && !$hastracks) {
         // We don't need a full screen toggle for the audios (except when tracks are present).
         $datasetup[] = '"controlBar": {"fullscreenToggle": false}';
     }
     if ($isaudio && !$height && !$hastracks && !$hasposter) {
         // Hide poster area for audios without tracks or poster.
         // See discussion on https://github.com/videojs/video.js/issues/2777 .
         // Maybe TODO: if there are only chapter tracks we still don't need poster area.
         $datasetup[] = '"aspectRatio": "1:0"';
     }
     // Attributes for the video/audio tag.
     $attributes = ['data-setup' => '{' . join(', ', $datasetup) . '}', 'id' => 'id_videojs_' . uniqid(), 'class' => get_config('media_videojs', $isaudio ? 'audiocssclass' : 'videocssclass')];
     if (!$responsive) {
         // Note we ignore limitsize setting if not responsive.
         parent::pick_video_size($width, $height);
         $attributes += ['width' => $width] + ($height ? ['height' => $height] : []);
     }
     if (core_useragent::is_ios(10)) {
         // Hides native controls and plays videos inline instead of fullscreen,
         // see https://github.com/videojs/video.js/issues/3761 and
         // https://github.com/videojs/video.js/issues/3762 .
         // iPhone with iOS 9 still displays double controls and plays fullscreen.
         // iPhone with iOS before 9 display only native controls.
         $attributes += ['playsinline' => 'true'];
     }
     if ($text !== null) {
         // Original text already had media tag - add necessary attributes and replace sources
         // with the supported URLs only.
         if (($class = self::get_attribute($text, 'class')) !== null) {
             $attributes['class'] .= ' ' . $class;
         }
         $text = self::remove_attributes($text, ['id', 'width', 'height', 'class']);
         if (self::get_attribute($text, 'title') === null) {
             $attributes['title'] = $title;
         }
         $text = self::add_attributes($text, $attributes);
         $text = self::replace_sources($text, $sources);
     } else {
         // Create <video> or <audio> tag with necessary attributes and all sources.
         // We don't want fallback to another player because list_supported_urls() is already smart.
         // Otherwise we could end up with nested <audio> or <video> tags. Fallback to link only.
         $attributes += ['preload' => 'auto', 'controls' => 'true', 'title' => $title];
         $text = html_writer::tag($isaudio ? 'audio' : 'video', $sources . self::LINKPLACEHOLDER, $attributes);
     }
     // Limit the width of the video if width is specified.
     // We do not do it in the width attributes of the video because it does not work well
     // together with responsive behavior.
     if ($responsive) {
         self::pick_video_size($width, $height);
         if ($width) {
             $text = html_writer::div($text, null, ['style' => 'max-width:' . $width . 'px;']);
         }
     }
     return html_writer::div($text, 'mediaplugin mediaplugin_videojs');
 }