4 * http://opencaps.atrc.utoronto.ca
6 * Copyright 2009 Heidi Hazelton
7 * Adaptive Technology Resource Centre, University of Toronto
9 * Licensed under the Educational Community License (ECL), Version 2.0.
10 * You may not use this file except in compliance with this License.
11 * http://www.opensource.org/licenses/ecl2.php
22 public $media_loc; //url to media file
27 public $caption_loc; //url to caption json file
28 public $clip_collection; // holds everything: captions, descriptions, etc.
32 /* new project object belonging to member */
33 function __construct() {
34 $this->clip_collection = new clipCollection();
37 /* create a new project */
38 function createNew($name, $media, $captions) {
45 $this->id = $this_db->addProj($this);
47 if (isset($_SESSION['errors'])) {
48 header("Location:start.php");
52 $_SESSION['pid'] = $this->id;
55 if (!file_exists('projects/'.$this->id.'/')) {
56 @mkdir('projects/'.$this->id.'/');
57 @copy('projects/index.html', 'projects/'.$this->id.'/index.html');
61 if (is_array($media)) {
62 $this->media_loc = 'projects/'.$this->id.'/'.$media['name'];
64 if ( !move_uploaded_file($media['tmp_name'], 'projects/'.$this->id.'/'.basename($media['name'])) ) {
65 $_SESSION['errors'][] = "Problem uploading media file - can't copy file to server. The file may exceed file size limits. Try a smaller file or contact your server administrator.";
67 $this->delete($this->id);
73 $this->media_loc = $media;
76 //convert caption file to quicktime & save
77 if (!empty($captions['tmp_name'])) {
79 $this->importCaptions($captions);
83 $json = json_encode(get_object_vars($this));
84 $this->saveJson($json, $this->id);
85 $this_db->updateProj($this);
90 /* open user project */
93 $sql = "UPDATE projects SET last_accessed=NOW() WHERE project_id=$pid AND member_id=$_SESSION[mid]";
94 if (!$result = mysql_query($sql, $this_db->db)) {
95 echo 'Database error: '.mysql_error();
99 $_SESSION['pid'] = $pid;
103 /* save uploaded media - returns location of file */
104 function saveMedia($upload) {
106 if (!move_uploaded_file($file['tmp_name'], $dir.'/'.basename($file['name'])) ) {
107 //$err = "Problem uploading file - can't copy file to server. The file may exceed file size limits. Try a smaller file or contact your server administrator.";
111 /* list the current user's projects */
112 function printUserProjects($pageNum) {
113 global $this_db, $stripslashes, $addslashes;
115 if (!isset($pageNum))
120 //printing page numbers
121 $sql = "SELECT project_id FROM projects WHERE member_id=".intval($_SESSION['mid']);
122 $result = @mysql_query($sql, $this_db->db);
123 $numrows = @mysql_num_rows($result);
125 $maxPage = ceil($numrows/$projsPerPage);
128 for($page = 1; $page <= $maxPage; $page++) {
129 if ($page == $pageNum) {
132 $nav .= ' <a href="start.php?page='.$page.'">'.$page.'</a> ';
137 echo $nav."<br /><br />";
139 $offset = ($pageNum - 1) * $projsPerPage;
140 $sql = "SELECT * FROM projects WHERE member_id=".intval($_SESSION['mid'])." ORDER BY last_accessed DESC LIMIT $offset, $projsPerPage";
141 $result = @mysql_query($sql, $this_db->db);
145 echo "No projects yet.";
147 echo '<ul class="proj-list">';
148 while ($row = @mysql_fetch_assoc($result)) {
149 echo '<li><label><input type="radio" name="proj" value='.$row['project_id'].' /> '.$stripslashes($row['name']).'</label> (<a href="#" onClick="confirmDelete('.$row['project_id'].', \''.$addslashes($row['name']).'\');">Delete</a>)</li>';
152 echo "<div style='text-align:right;'><input type='submit' class='button' style='width:6em;margin-top:5px;' name='submit_new' value='Submit' /></div>";
157 function saveJson($json, $pid) {
158 global $stripslashes;
\r
160 $json_path = INCLUDE_PATH.'../projects/'.$pid.'/';
162 if (!file_exists($json_path))
166 ///////////////////////////////////////////
\r
167 if (get_magic_quotes_gpc())
\r
169 $json = stripslashes($json);
\r
172 // second test using regexp
\r
173 $validJsonRegExp = '/"clips":\[/'; // can be better tho
\r
174 if (!preg_match($validJsonRegExp, $validJsonRegExp))
\r
176 $json = str_replace('\"','"',$json);
\r
178 //end added by ANTO
\r
179 ///////////////////////////////////////////
\r
182 if (!@file_put_contents($json_path.'opencaps.json', $stripslashes($json))) {
183 echo 'Could not create project file.';
187 function importCaptions($capfile, $upload=true) {
188 global $page, $remote_systems;
191 if (OC_DEBUG_MODE_ON)
\r
193 $ocAtDebugMsg = '*************************';
\r
194 $ocAtDebugMsg .= '<br/>';
\r
195 $ocAtDebugMsg .= '<b>importCaptions() - class: project</b>';
\r
196 $ocAtDebugMsg .= '<br/>';
\r
197 $ocAtDebugMsg .= '<br/>Session ID: '.$_SESSION['pid'];
\r
198 $ocAtDebugMsg .= '<br/>$this->id: '.$this->id;
\r
199 $ocAtDebugMsg .= '<br/><br/>';
\r
200 $ocAtDebugMsg .= '*************************';
\r
201 ///echo $ocAtDebugMsg;
\r
202 $_SESSION['feedback'][] = $ocAtDebugMsg;
\r
205 $page = explode('/',$_SERVER["SCRIPT_NAME"]);
208 $page_len = strlen($page)+1;
210 $ccollection = new clipCollection() ;
214 if( !move_uploaded_file( $capfile['tmp_name'], INCLUDE_PATH.'../projects/'.$this->id.'/'.basename($capfile['name'])) ) {
215 $_SESSION['errors'][] = "Problem uploading caption file - can't copy file to server.";
216 $this->delete($this->id);
220 $base_url = substr('http://'.$_SERVER["SERVER_NAME"].$_SERVER["SCRIPT_NAME"], 0, -$page_len);
221 $caption_file = urlencode('../projects/'.$this->id.'/'.basename($capfile['name']));
224 /* system - matterhorn */
225 $page_len += strlen("include/");
226 $base_url = substr('http://'.$_SERVER["SERVER_NAME"].$_SERVER["SCRIPT_NAME"], 0, -$page_len);
228 $uri = substr($capfile, strlen($remote_systems[$_SESSION['rid']]['url']));
229 $caps = matterhornAuth($_SESSION['rid'], $uri);
230 $caption_file = INCLUDE_PATH.'../projects/'.$this->id.'/'.'captions.xml';
231 @file_put_contents($caption_file, $caps);
234 $convert_url = $base_url.'/conversion_service/?cc_url='.$caption_file.'&cc_result=0&cc_target=JSONcc&cc_name=noname.___';
235 $json_captions = json_decode(@file_get_contents($convert_url));
237 if (!empty($json_captions) && $json_captions != "The format of source Caption was not recognized.") {
239 foreach ($json_captions->captionCollection as $clip) {
240 $this_clip = new clip($clip->inTime, $clip->outTime, trim($clip->caption));
241 $ccollection->addClip($this_clip);
244 $_SESSION['feedback'][] = "Captions imported successfully.";
\r
245 $_SESSION['feedback'][] = "id: ".$this->id;
248 $_SESSION['errors'][] = "Problem uploading caption file - the format is incorrect, or unsupported.";
251 $this->clip_collection = $ccollection;
253 //save reference file
254 $json = json_encode(get_object_vars($this));
258 $this->saveJson($json, $_SESSION['pid']);
265 function exportCaption($format) {
267 if ($format == "all") {
270 } else if ($format == "json") {
271 $cappath = INCLUDE_PATH.'../projects/'.$this->id.'/'.'opencaps.json';
272 //make a copy of the json that has the proj name as prefix
276 $base_url = substr('http://'.$_SERVER["SERVER_NAME"].$_SERVER["SCRIPT_NAME"], 0, -10);
278 $convert_url = $base_url.'conversion_service/?cc_url='.urlencode('../projects/'.$this->id.'/opencaps.json').'&cc_result=0&cc_target='.$format.'&cc_name=noname.___';
279 $formatted_captions = @file_get_contents($convert_url);
280 if (!empty($formatted_captions)) {
281 $formatted_captions = trim($formatted_captions);
282 $cappath = INCLUDE_PATH.'../projects/'.$this->id.'/'.str_replace(' ', '_', $this->name).'_';
286 $cappath = $cappath.'captions.dfxp.xml';
290 $cappath = $cappath.'captions.stl';
294 $cappath = $cappath.'captions.sub';
298 $cappath = $cappath.'captions.MPsub';
302 $formatted_captions = $formatted_captions."\r\n".'['.$this->duration.']'; /* white cap background hack */
303 $cappath = $cappath.'captions.txt';
307 $cappath = $cappath.'captions.rt';
311 $cappath = $cappath.'capscribe.smi';
315 $cappath = $cappath.'captions.srt';
319 $cappath = $cappath.'captions.scc';
323 $cappath = $cappath.'captions.sub';
327 @file_put_contents($cappath, $formatted_captions);
330 export_file($cappath);
334 function delete($proj_id) {
337 if (deleteDir('../projects/'.$proj_id."/")) {
338 $sql = "DELETE from projects WHERE project_id=".$proj_id." AND member_id=".$_SESSION['mid'];
339 $result = mysql_query($sql, $this_db->db);
341 //echo "Project could not be deleted.";
345 function preview($layout) {
346 $this->layout = $layout;
348 //send this to the conversion service
349 $base_url = substr('http://'.$_SERVER["SERVER_NAME"].$_SERVER["SCRIPT_NAME"], 0, -20);
350 $json_url = urlencode($base_url.'projects/'.$this->id.'/opencaps.json');
351 $request = $base_url."conversion_service/?cc_url=".$json_url."&cc_result=0&cc_target=QTtext&cc_name=noname.___";
353 //create the qt-text file
354 $qt_text = @file_get_contents($request)."\r\n".'['.$this->duration.']';
355 @file_put_contents('../projects/'.$this->id.'/captions.txt', $qt_text);
357 //send the embed height back as a response
358 $eheight = $this->get_smil('save');
366 function get_smil($method="") {
367 $layout = $this->layout;
369 $contents = @file_get_contents(INCLUDE_PATH.'../projects/layouts/smil_'.$layout.'.mov');
370 $contents = str_replace("%rootwidth%", $this->media_width, $contents);
372 $vid_file_name = end(explode('/',$this->media_loc));
374 if ($this->media_loc == 'projects/'.$this->id.'/'.$vid_file_name)
375 $contents = str_replace("%video%", $vid_file_name, $contents);
377 $contents = str_replace("%video%", $this->media_loc, $contents);
379 $contents = str_replace("%duration%", $this->duration, $contents);
380 $contents = str_replace("%width%", $this->media_width, $contents);
381 $contents = str_replace("%height%", $this->media_height, $contents);
383 $contents = str_replace("%capwidth%", $this->media_width-10, $contents);
385 if ($layout == 0) { //cap below
386 $contents = str_replace("%rootheight%", $this->media_height+85, $contents);
387 $obj_height = $this->media_height+100;
388 $contents = str_replace("%captop%", $this->media_height+10, $contents);
389 $contents = str_replace("%capheight%", 135, $contents); //affects font size
391 } else if ($layout == 1) { //cap bottom
392 $contents = str_replace("%rootheight%", $this->media_height, $contents);
393 $obj_height = $this->media_height+30;
394 $contents = str_replace("%captop%", $this->media_height-75, $contents);
395 $contents = str_replace("%capheight%", 135, $contents);
397 } else { //caption only
398 $contents = str_replace("%rootheight%", 85, $contents);
400 $contents = str_replace("%captop%", 10, $contents);
401 $contents = str_replace("%capheight%", 135, $contents);
404 if ($method == "save") {
405 $proj_smil = INCLUDE_PATH.'../projects/'.$this->id.'/smil_'.$layout.'.mov';
406 @file_put_contents($proj_smil, $contents);
413 function export_pkg() {
415 $zip = new ZipArchive();
417 $proj_name = str_replace(' ', '', $this->name);
418 $proj_name = str_replace("'", '', $proj_name);
419 $zipfile = $proj_name.".zip";
420 if ($zip->open(INCLUDE_PATH.'../projects/'.$this->id.'/'.$zipfile, ZIPARCHIVE::CREATE)!==TRUE) {
421 exit("cannot open <$zipfile>\n");
424 $zip->addEmptyDir($proj_name);
427 $contents = $this->get_smil();
428 $zip->addFromString($proj_name.'/smil.mov', $contents);
430 //create player from template
431 $contents = file_get_contents(INCLUDE_PATH.'../projects/player_template.php');
432 $contents = str_replace("%width%", $this->media_width, $contents);
433 $contents = str_replace("%height%", $this->media_height+135, $contents);
436 $zip->addFromString($proj_name.'/player.html', $contents);
439 $zip->addFile(INCLUDE_PATH.'../projects/'.$this->id.'/captions.txt', $proj_name.'/captions.txt');
441 //add movie if not a URL
442 if (current(explode('/', $this->media_loc)) == "projects") {
443 $media_name = end(explode('/', $this->media_loc));
444 $zip->addFile($this->media_loc, $proj_name.'/'.$media_name);
448 //export_file(INCLUDE_PATH.'../projects/'.$this->id.'/'.$zipfile);
449 unlink(INCLUDE_PATH.'../projects/'.$this->id.'/'.$zipfile);
453 function editName($name) {
454 global $addslashes, $this_db;
456 $this->name = $addslashes($name);
458 //save reference file
459 $json = json_encode(get_object_vars($this));
460 $this->saveJson($json, $this->id);
461 $this_db->updateProj($this);
467 /* utility functions */
469 /* force download of a file in browser */
470 function export_file($exfile) {
471 if (file_exists($exfile)) {
472 header('Content-Description: File Transfer');
473 header('Content-Type: application/octet-stream');
474 header('Content-Disposition: attachment; filename='.basename($exfile));
475 header('Content-Transfer-Encoding: binary');
476 header('Expires: 0');
477 header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
478 header('Pragma: public');
479 header('Content-Length: '.filesize($exfile));
486 /* delete a directory and its contents */
487 function deleteDir($dir) {
488 $dh = @opendir($dir);
489 while ( $file = @readdir($dh) ) {
490 if ( $file != '.' || $file != '..') {
492 //if ( ! @unlink ( $dir . '/' . $obj ) ) deleteDir ( $dir . '/' . $obj, true )