/** * Perform minimal validation on the settings form * * @param array $data Data to be validated * @param array $files Files to be validated * * @return array */ public function validation($data, $files) { $errors = parent::validation($data, $files); // If no errors have been detecting on subtitle if (!isset($errors['subtitle'])) { global $USER; $fs = get_file_storage(); $context = context_user::instance($USER->id); $files = $fs->get_area_files($context->id, 'user', 'draft', $data['subtitle'], 'id DESC', false); $noerror = false; // Loop on all files (normally only one) foreach ($files as $file) { // Save the file to a temporary path try { $filepath = $file->copy_content_to_temp(); } catch (\Exception $e) { $errors['subtitle'] = get_string('subtitleunabletosave', 'elang'); break; } // Try to detect encoding $config = get_config('elang'); if (isset($config->encodings)) { $encodings = $config->encodings; } else { $encodings = null; } $contents = Elang\transcodeSubtitle(file_get_contents($filepath), 'UTF-8', $encodings); if (false === $contents) { // Automatic detection does not succeed $errors['subtitle'] = get_string('subtitleunknownencoding', 'elang'); break; } else { // Encoding succeeds, put back encoded contents in file file_put_contents($filepath, $contents); // Detect vtt format try { $caption = new \Captioning\Format\WebvttFile($filepath); $caption->setUseIconv(function_exists('mb_convert_encoding')); $noerror = true; break; } catch (\Exception $e) { } // Detect subrip format try { $caption = new \Captioning\Format\SubripFile($filepath); $caption->setUseIconv(function_exists('mb_convert_encoding')); $noerror = true; break; } catch (\Exception $e) { } } } if ($noerror) { // $noerror means automatic detection of encoding has been successfull and the file is in vtt or subrip format $this->vtt = new \Captioning\Format\WebvttFile(); // Construct the cues in vtt format $cues = $caption->getCues(); if ($cues) { foreach ($cues as $cue) { $this->vtt->addCue($cue->getText(), \Captioning\Format\WebvttCue::ms2tc($cue->getStartMS()), \Captioning\Format\WebvttCue::ms2tc($cue->getStopMS())); } } } elseif (!isset($errors['subtitle'])) { // File is not in vtt or subrip format $errors['subtitle'] = get_string('subtitleinvalidformat', 'elang'); } } $jaro = str_replace(",", ".", $data['jaroDistance']); if (!is_numeric($jaro) || $jaro <= 0 || $jaro > 1) { $errors['jaroDistance'] = get_string('jaroDistance_error', 'elang'); } return $errors; }
/** * @param string $start * @param string $stop * @param string $text * @param string $settings * @param string $id * @param string $note * @return WebvttCue */ private function createCue($start, $stop, $text, $settings, $id, $note) { $cue = new WebvttCue($start, $stop, $text); $tmp = explode(' ', trim($settings)); foreach ($tmp as $setting) { $tmp2 = explode(':', $setting); if (count($tmp2) !== 2) { continue; } $cue->setSetting($tmp2[0], $tmp2[1]); } if ($id !== null) { $cue->setIdentifier($id); } if (!empty($note)) { $cue->setNote($note); } return $cue; }
/** * Serves the files from the elang file areas * * @param stdClass $course the course object * @param stdClass $cm the course module object * @param stdClass $context the elang's context * @param string $filearea the name of the file area * @param array $args extra arguments (itemid, path) * @param boolean $forcedownload whether or not force download * @param array $options additional options affecting the file serving * * @return void * * @category files * * @since 0.0.1 */ function elang_pluginfile($course, $cm, $context, $filearea, array $args, $forcedownload, array $options = array()) { global $DB, $CFG, $USER; require_once dirname(__FILE__) . '/locallib.php'; if ($context->contextlevel != CONTEXT_MODULE) { send_file_not_found(); } require_login($course, true, $cm); if (!has_capability('mod/elang:view', $context)) { send_file_not_found(); } if ($filearea == 'subtitle') { $vtt = new \Captioning\Format\WebvttFile(); $idlang = $cm->instance; $records = $DB->get_records('elang_cues', array('id_elang' => $idlang), 'begin ASC'); $elang = $DB->get_record('elang', array('id' => $idlang)); $options = json_decode($elang->options, true); $repeatedunderscore = isset($options['repeatedunderscore']) ? $options['repeatedunderscore'] : 10; $i = 0; $users = $DB->get_records('elang_users', array('id_elang' => $idlang, 'id_user' => $USER->id), '', 'id_cue,json'); foreach ($records as $id => $record) { if (isset($users[$id])) { $data = json_decode($users[$id]->json, true); } else { $data = array(); } $cue = new \Captioning\Format\WebvttCue(\Captioning\Format\WebvttCue::ms2tc($record->begin), \Captioning\Format\WebvttCue::ms2tc($record->end), Elang\generateCueText(json_decode($record->json, true), $data, '-', $repeatedunderscore)); $i++; $cue->setIdentifier($i); $vtt->addCue($cue); } send_file($vtt->build()->getFileContent(), end($args), 0, 0, true, false, 'text/vtt'); } elseif ($filearea == 'pdf') { $idlang = $cm->instance; $records = $DB->get_records('elang_cues', array('id_elang' => $idlang), 'begin ASC'); $elang = $DB->get_record('elang', array('id' => $idlang)); $options = json_decode($elang->options, true); $repeatedunderscore = isset($options['repeatedunderscore']) ? $options['repeatedunderscore'] : 10; require_once $CFG->libdir . '/pdflib.php'; $doc = new pdf(); $doc->SetMargins(isset($options['left']) ? $options['left'] : 20, isset($options['top']) ? $options['top'] : 20); $doc->SetFont('', '', isset($options['size']) ? $options['size'] : 16); $doc->setPrintHeader(false); $doc->setPrintFooter(false); $doc->AddPage(); $doc->WriteHtml('<h1>' . sprintf(get_string('pdftitle', 'elang'), $course->fullname) . '</h1>'); $doc->WriteHtml('<h2>' . sprintf(get_string('pdfsubtitle', 'elang'), Elang\generateTitle($elang, $options), userdate($elang->timecreated, get_string('strftimedaydate'))) . '</h2>'); $doc->WriteHtml($elang->intro); $i = 1; foreach ($records as $id => $record) { $doc->Write(5, '', '', false, '', true); $doc->WriteHtml('<h3>' . sprintf(get_string('pdfcue', 'elang'), $i++, \Captioning\Format\WebvttCue::ms2tc($record->begin), \Captioning\Format\WebvttCue::ms2tc($record->end)) . '</h3>'); $doc->Write(5, Elang\generateCueText(json_decode($record->json, true), array(), '_', $repeatedunderscore), '', false, '', true); } send_file($doc->Output('', 'S'), end($args), 0, 0, true, false, 'application/pdf'); } else { $fs = get_file_storage(); $relativepath = implode('/', $args); $fullpath = rtrim('/' . $context->id . '/mod_elang/' . $filearea . '/0/' . $relativepath, '/'); $file = $fs->get_file_by_hash(sha1($fullpath)); if (!$file) { send_file_not_found(); } send_stored_file($file, 86400, 0, $forcedownload, $options); } }
public function parse() { $handle = fopen($this->filename, "r"); $parsing_errors = array(); if ($handle) { $case = 'header'; $i = 1; while (($line = fgets($handle)) !== false) { // checking header if ($case === 'header' && trim($line) != 'WEBVTT') { $parsing_errors[] = 'Missing "WEBVTT" at the beginning of the file'; } elseif ($case === 'header') { $case = 'region'; continue; } if ($case !== 'header') { // parsing regions if ($case === 'region' && substr($line, 0, 7) == 'Region:') { $this->addRegion(WebvttRegion::parseFromString($line)); continue; } if ($case === 'region' && trim($line) === '') { $case = 'body'; continue; } if ($case === 'body') { // parsing notes if (substr($line, 0, 4) === 'NOTE') { if (trim($line) === 'NOTE') { $note = $this->lineEnding; } else { $note = trim(ltrim($line, 'NOTE ')) . $this->lineEnding; } // note continues until there is a blank line while (trim($line = fgets($handle)) !== '') { $note .= trim($line) . $this->lineEnding; $i++; } continue; } // parsing cues $id_match = !strstr($line, '-->') && trim($line) != ''; $matches = array(); $timecode_match = preg_match(self::TIMECODE_PATTERN, $line, $matches); if ($id_match || $timecode_match) { $id = null; $start = null; $stop = null; $settings = null; $text = ''; if ($id_match) { $id = $line; $line = fgets($handle); $matches = array(); $timecode_match = preg_match(self::TIMECODE_PATTERN, $line, $matches); } if (!$timecode_match) { $parsing_errors[] = 'Malformed cue detected at line ' . $i; } else { $start = $matches[1]; $stop = $matches[2]; $settings = trim($matches[3]); } // cue continues until there is a blank line while (trim($line = fgets($handle)) !== '') { $text .= trim($line) . $this->lineEnding; } // make the cue object and add it to the file $cue = new WebvttCue($start, $stop, $text); $tmp = explode(' ', trim($settings)); foreach ($tmp as $setting) { $tmp2 = explode(':', $setting); if (count($tmp2) !== 2) { continue; } $cue->setSetting($tmp2[0], $tmp2[1]); } if ($id !== null) { $cue->setIdentifier($id); } if (!empty($note)) { $cue->setNote($note); unset($note); } $this->addCue($cue); unset($cue); continue; } } } $i++; } } else { throw new \Exception('Could not read the file "' . $this->filename . '".'); } fclose($handle); if (count($parsing_errors) > 0) { throw new \Exception('The following errors were found while parsing the file:' . "\n" . print_r($parsing_errors, true)); } return $this; }