From 4c9cd53ef66870c2cb87ec5f230f69e1b5bd3c01 Mon Sep 17 00:00:00 2001 From: Harris Wong Date: Fri, 8 Oct 2010 17:17:51 +0000 Subject: [PATCH] http://atutor.ca/atutor/mantis/view.php?id=4574 --- docs/home/classes/ContentUtility.class.php | 185 ++++++++++++------ docs/home/course/content.php | 12 +- docs/home/editor/editor_tab_functions.inc.php | 70 +++++++ .../editor/editor_tabs/alternatives.inc.php | 66 ++----- docs/home/imscc/ims_export.php | 77 +------- docs/home/imscc/include/ims_template.inc.php | 24 ++- docs/include/classes/A4a/A4a.class.php | 24 ++- docs/include/classes/A4a/A4aExport.class.php | 4 + .../classes/DAO/PrimaryResourcesDAO.class.php | 42 +++- docs/include/lib/mime.inc.php | 1 + docs/include/lib/resources_parser.inc.php | 9 + docs/include/vitals.inc.php | 15 ++ 12 files changed, 326 insertions(+), 203 deletions(-) diff --git a/docs/home/classes/ContentUtility.class.php b/docs/home/classes/ContentUtility.class.php index 112b733..21e8e4d 100644 --- a/docs/home/classes/ContentUtility.class.php +++ b/docs/home/classes/ContentUtility.class.php @@ -204,6 +204,33 @@ class ContentUtility { return $text; } + /* + * This function converts the youtube playable url used in tag (for instance: http://www.youtube.com/v/a0ryB0m0MiM) + * to youtube url that is used to browse (for instance: http://www.youtube.com/watch?v=a0ryB0m0MiM) + * @param: youtube playable URL. For instance, http://www.youtube.com/v/a0ryB0m0MiM + * @return: if the param is a youtube playable url, return the according youtube URL used to browse. + * For instance: http://www.youtube.com/watch?v=a0ryB0m0MiM + * Otherwise, return the original send-in parameter. + */ + function convertYoutubePlayURLToWatchURL($youtube_playURL) { + return preg_replace("/(http:\/\/[a-z0-9\.]*)?youtube.com\/v\/(.*)/", + "\\1youtube.com/watch?v=\\2", $youtube_playURL); + } + + /* + * This function converts the youtube url that is used to browse (for instance: http://www.youtube.com/watch?v=a0ryB0m0MiM) + * to youtube playable url used in tag (for instance: http://www.youtube.com/v/a0ryB0m0MiM) + * @param: the youtube URL used to browse. + * For instance: http://www.youtube.com/watch?v=a0ryB0m0MiM + * @return: if the param is a youtube url used to browse, return the according youtube playable URL. + * For instance, http://www.youtube.com/v/a0ryB0m0MiM + * Otherwise, return the original send-in parameter. + */ + function convertYoutubeWatchURLToPlayURL($youtube_watchURL) { + return preg_replace("/(http:\/\/[a-z0-9\.]*)?youtube.com\/watch\?v=(.*)/", + "\\1youtube.com/v/\\2", $youtube_watchURL); + } + public static function embedMedia($text) { if (preg_match("/\[media(\|[0-9]+\|[0-9]+)?\]*/", $text)==0){ return $text; @@ -215,19 +242,14 @@ class ContentUtility { $media_matches = Array(); - /* - First, we search though the text for all different kinds of media defined by media tags and store the results in $media_matches. - - Then the different replacements for the different media tags are stored in $media_replace. - - Lastly, we loop through all $media_matches / $media_replaces. (We choose $media_replace as index because $media_matches is multi-dimensioned.) It is important that for each $media_matches there is a $media_replace with the same index. For each media match we check the width/height, or we use the default value of 425x350. We then replace the height/width/media1/media2 parameter placeholders in $media_replace with the correct ones, before running a str_replace on $text, replacing the given media with its correct replacement. - - */ + // First, we search though the text for all different kinds of media defined by media tags and store the results in $media_matches. + // Then the different replacements for the different media tags are stored in $media_replace. + // Lastly, we loop through all $media_matches / $media_replaces. (We choose $media_replace as index because $media_matches is multi-dimensioned.) It is important that for each $media_matches there is a $media_replace with the same index. For each media match we check the width/height, or we use the default value of 425x350. We then replace the height/width/media1/media2 parameter placeholders in $media_replace with the correct ones, before running a str_replace on $text, replacing the given media with its correct replacement. // youtube videos - preg_match_all("#\[media[0-9a-z\|]*\]http://([a-z0-9\.]*)?youtube.com/watch\?v=([a-z0-9_-]+)\[/media\]#i",$text,$media_matches[1],PREG_SET_ORDER); - $media_replace[1] = ''; - + preg_match_all("#\[media[0-9a-z\|]*\]http://([a-z0-9\.]*)?youtube.com/watch\?v=(.*)\[/media\]#iU",$text,$media_matches[1],PREG_SET_ORDER); + $media_replace[1] = ''; + // .mpg preg_match_all("#\[media[0-9a-z\|]*\]([.\w\d]+[^\s\"]+).mpg\[/media\]#i",$text,$media_matches[2],PREG_SET_ORDER); $media_replace[2] = "##MEDIA1##.mpg"; @@ -240,29 +262,25 @@ class ContentUtility { preg_match_all("#\[media[0-9a-z\|]*\]([.\w\d]+[^\s\"]+).wmv\[/media\]#i",$text,$media_matches[4],PREG_SET_ORDER); $media_replace[4] = "##MEDIA1##.wmv"; - // .mov - preg_match_all("#\[media[0-9a-z\|]*\]([.\w\d]+[^\s\"]+).mov\[/media\]#i",$text,$media_matches[5],PREG_SET_ORDER); - $media_replace[5] = "##MEDIA1##.mov"; - // .swf - preg_match_all("#\[media[0-9a-z\|]*\]([.\w\d]+[^\s\"]+).swf\[/media\]#i",$text,$media_matches[6],PREG_SET_ORDER); - $media_replace[6] = " ##MEDIA1##.swf"; - - // .mp3 - preg_match_all("#\[media[0-9a-z\|]*\](.+[^\s\"]+).mp3\[/media\]#i",$text,$media_matches[7],PREG_SET_ORDER); - $media_replace[7] = "##MEDIA1##.mp3"; + preg_match_all("#\[media[0-9a-z\|]*\]([.\w\d]+[^\s\"]+).swf\[/media\]#i",$text,$media_matches[5],PREG_SET_ORDER); + $media_replace[5] = " ##MEDIA1##.swf"; // .wav - preg_match_all("#\[media[0-9a-z\|]*\](.+[^\s\"]+).wav\[/media\]#i",$text,$media_matches[8],PREG_SET_ORDER); - $media_replace[8] ="##MEDIA1##.wav"; + preg_match_all("#\[media[0-9a-z\|]*\](.+[^\s\"]+).wav\[/media\]#i",$text,$media_matches[6],PREG_SET_ORDER); + $media_replace[6] ="##MEDIA1##.wav"; // .ogg - preg_match_all("#\[media[0-9a-z\|]*\](.+[^\s\"]+).ogg\[/media\]#i",$text,$media_matches[9],PREG_SET_ORDER); - $media_replace[9] ="##MEDIA1##.ogg"; + preg_match_all("#\[media[0-9a-z\|]*\](.+[^\s\"]+).ogg\[/media\]#i",$text,$media_matches[7],PREG_SET_ORDER); + $media_replace[7] ="##MEDIA1##.ogg"; + + // .ogm + preg_match_all("#\[media[0-9a-z\|]*\](.+[^\s\"]+).ogm\[/media\]#i",$text,$media_matches[8],PREG_SET_ORDER); + $media_replace[8] ="##MEDIA1##.ogm"; // .mid - preg_match_all("#\[media[0-9a-z\|]*\](.+[^\s\"]+).mid\[/media\]#i",$text,$media_matches[10],PREG_SET_ORDER); - $media_replace[10] ="##MEDIA1##.mid"; + preg_match_all("#\[media[0-9a-z\|]*\](.+[^\s\"]+).mid\[/media\]#i",$text,$media_matches[9],PREG_SET_ORDER); + $media_replace[9] ="##MEDIA1##.mid"; $text = preg_replace("#\[media[0-9a-z\|]*\](.+[^\s\"]+).mid\[/media\]#i", "\\1.mid", $text); @@ -535,8 +553,8 @@ class ContentUtility { $input); } else { $input = preg_replace - ("/(\[\?\])$term(\[\/\?\])/i", - '\\2?',$input); + ("/(\[\?\])$term(\[\/\?\])/i", + '\\2?',$input); } } } else if (!$user_glossary) { @@ -703,7 +721,19 @@ class ContentUtility { include_once(TR_INCLUDE_PATH.'classes/DAO/DAO.class.php'); $dao = new DAO(); - $video_exts = array("mpg", "avi", "wmv", "mov", "swf", "mp3", "wav", "ogg", "mid", "mp4", "flv"); + // All a4a resources have "&" converted to "&". To match content with resources, + // need the same conversion on content. + $content = convertAmp($content); + + // keep < (content saved in plain text format) as it is instead of &lt; + $content = str_replace('&lt;', '<', $content); + + $video_exts = array("mpg", "avi", "wmv", "mov", "swf", "mp4", "flv"); + + $audio_exts = array("mp3", "wav", "ogg", "mid"); + $audio_width = 425; + $audio_height = 27; + $txt_exts = array("txt", "html", "htm"); $image_exts = array("gif", "bmp", "png", "jpg", "jpeg", "png", "tif"); $only_on_secondary_type = intval($only_on_secondary_type); @@ -729,9 +759,16 @@ class ContentUtility { return array($has_text_alternative, $has_audio_alternative, $has_visual_alternative, $has_sign_lang_alternative); } } - // get all relations between primary resources and their alternatives - $sql = "SELECT c.content_path, pr.resource, prt.type_id primary_type, sr.secondary_resource, srt.type_id secondary_type + $sql = "SELECT DISTINCT c.content_path, pr.resource, "; + + // ignore primary resource type if the request is on particular secondary type. + // otherwise, if the primary resource is defined with multiple primary types, + // the primary resource would be replaced/appended multiple times. + if ($only_on_secondary_type == 0) { + $sql .= "prt.type_id primary_type, "; + } + $sql .= "sr.secondary_resource, srt.type_id secondary_type FROM ".TABLE_PREFIX."primary_resources pr, ". TABLE_PREFIX."primary_resources_types prt,". TABLE_PREFIX."secondary_resources sr,". @@ -758,7 +795,18 @@ class ContentUtility { } } - foreach ($rows as $row) + foreach ($rows as $row) { + $alternative_rows[] = $row; + + $youtube_playURL = ContentUtility::convertYoutubeWatchURLToPlayURL($row['resource']); + + if ($row['resource'] <> $youtube_playURL) { + $row['resource'] = $youtube_playURL; + $alternative_rows[] = $row; + } + } + + foreach ($alternative_rows as $row) { if ($info_only || $only_on_secondary_type || ($_SESSION['prefs']['PREF_USE_ALTERNATIVE_TO_TEXT']==1 && $row['primary_type']==3 && @@ -780,8 +828,18 @@ class ContentUtility { $ext = substr($row['secondary_resource'], strrpos($row['secondary_resource'], '.')+1); // alternative is video - if (in_array($ext, $video_exts)) - $target = '[media]'.$row['secondary_resource'].'[/media]'; + if (in_array($ext, $video_exts)|| in_array($ext, $audio_exts) || + preg_match("/http:\/\/.*youtube.com\/watch.*/", $row['secondary_resource'])) { + if (in_array($ext, $audio_exts)) { + // display audio medias in a smaller width/height (425 * 27) + // A hack for now to handle audio media player size + $target = '[media|'.$audio_width.'|'.$audio_height.']'.$row['secondary_resource'].'[/media]'; + } else { + // use default media size for video medias + $target = '[media]'.$row['secondary_resource'].'[/media]'; + } + $target = ContentUtility::embedFLV(ContentUtility::embedMedia($target)); + } // a text primary to be replaced by a visual alternative else if (in_array($ext, $txt_exts)) { @@ -822,19 +880,17 @@ class ContentUtility { if (($row['primary_type']==3 && $_SESSION['prefs']['PREF_ALT_TO_TEXT_APPEND_OR_REPLACE'] == 'replace') || ($row['primary_type']==1 && $_SESSION['prefs']['PREF_ALT_TO_AUDIO_APPEND_OR_REPLACE']=='replace') || ($row['primary_type']==4 && $_SESSION['prefs']['PREF_ALT_TO_VISUAL_APPEND_OR_REPLACE']=='replace')) - $pattern_replace_to = '${1}'.$target.'${3}'; - else - $pattern_replace_to = '${1}${2}'.$target.'${3}'; - - // *** Alternative replace/append starts from here *** - $img_processed = false; // The indicator to tell the source image is found (or not) - // and processed (or not) in an tag. If found and processed, - // SKIP the found/process for tag because the source is a image - // and is very likely the tag wrapping around + $pattern_replace_to = '${1}'."\n".$target."\n".'${3}'; + else + $pattern_replace_to = '${1}${2}'."

\n".$target."\n".'${3}'; - // append/replace target alternative to [media]source[/media] - if (preg_match("/".preg_quote("[media").".*".preg_quote("]".$row['resource']."[/media]", "/")."/sU", $content)) - { + // *** Alternative replace/append starts from here *** + $processed = false; // one primary resource is only processed once + + // append/replace target alternative to [media]source[/media] + if (!$processed && preg_match("/".preg_quote("[media").".*".preg_quote("]".$row['resource']."[/media]", "/")."/sU", $content)) + { + $processed = true; if (!$info_only) { $content = preg_replace("/(.*)(".preg_quote("[media").".*".preg_quote("]".$row['resource']."[/media]", "/").")(.*)/sU", $pattern_replace_to, $content); @@ -847,9 +903,9 @@ class ContentUtility { } // append/replace target alternative to
- if (preg_match("/\/sU", $content)) - { - $img_processed = true; + if (!$processed && preg_match("/\/sU", $content)) + { + $processed = true; if (!$info_only) { $content = preg_replace("/(.*)(\)(.*)/sU", $pattern_replace_to, $content); @@ -861,12 +917,12 @@ class ContentUtility { } } - // append/replace target alternative to ...source... or ... - // skip this "if" when the source object has been processed in aboved tag - if (!$img_processed && preg_match("/\/sU", $content)) - { - if (!$info_only) { - $content = preg_replace("/(.*)(\)(.*)/sU", + // append/replace target alternative to + if (!$processed && preg_match("/\/sU", $content)) + { + $processed = true; + if (!$info_only) { + $content = preg_replace("/(.*)(\)(.*)/sU", $pattern_replace_to, $content); } else { if ($row['secondary_type'] == 1) $has_audio_alternative = true; @@ -876,11 +932,13 @@ class ContentUtility { } } - // append/replace target alternative to - if (preg_match("/\/sU", $content)) - { - if (!$info_only) { - $content = preg_replace("/(.*)(\)(.*)/sU", + // append/replace target alternative to ...source... or ... + // skip this "if" when the source object has been processed in aboved tag + if (!$processed && preg_match("/\/sU", $content)) + { + $processed = true; + if (!$info_only) { + $content = preg_replace("/(.*)(\)(.*)/sU", $pattern_replace_to, $content); } else { if ($row['secondary_type'] == 1) $has_audio_alternative = true; @@ -891,8 +949,9 @@ class ContentUtility { } // append/replace target alternative to - if (preg_match("/\/sU", $content)) - { + if (!$processed && preg_match("/\/sU", $content)) + { + $processed = true; if (!$info_only) { $content = preg_replace("/(.*)(\)(.*)/sU", $pattern_replace_to, $content); diff --git a/docs/home/course/content.php b/docs/home/course/content.php index 06edcda..fb09578 100644 --- a/docs/home/course/content.php +++ b/docs/home/course/content.php @@ -256,18 +256,18 @@ if ($content_row['text'] == '' && empty($content_test_ids)){ $msg->addInfo('NO_PAGE_CONTENT'); $savant->assign('body', ''); } else { - // find whether the body has alternatives defined + $content = ContentUtility::formatContent($content_row['text'], $content_row['formatting']); + + // find whether the body has alternatives defined list($has_text_alternative, $has_audio_alternative, $has_visual_alternative, $has_sign_lang_alternative) - = ContentUtility::applyAlternatives($cid, $content_row['text'], true); + = ContentUtility::applyAlternatives($cid, $content, true); // apply alternatives if (intval($_GET['alternative']) > 0) { - $content = ContentUtility::applyAlternatives($cid, $content_row['text'], false, intval($_GET['alternative'])); + $content = ContentUtility::applyAlternatives($cid, $content, false, intval($_GET['alternative'])); } else { - $content = ContentUtility::applyAlternatives($cid, $content_row['text']); + $content = ContentUtility::applyAlternatives($cid, $content); } - - $content = ContentUtility::formatContent($content, $content_row['formatting']); $content_array = ContentUtility::getContentTable($content); diff --git a/docs/home/editor/editor_tab_functions.inc.php b/docs/home/editor/editor_tab_functions.inc.php index 4347b00..58e8c62 100644 --- a/docs/home/editor/editor_tab_functions.inc.php +++ b/docs/home/editor/editor_tab_functions.inc.php @@ -83,6 +83,73 @@ function isValidURL($url) { return false; } +/* + * Parse the primary resources out of the content and save into db. + * Clean up the removed primary resources from db. + * @param: $cid: content id + * @param: $content + * @return: none + */ +function populate_a4a($cid, $content, $formatting){ + global $db, $my_files; + + include_once(AT_INCLUDE_PATH.'classes/A4a/A4a.class.php'); + include_once(AT_INCLUDE_PATH.'classes/XML/XML_HTMLSax/XML_HTMLSax.php'); /* for XML_HTMLSax */ + include_once(AT_INCLUDE_PATH.'classes/ContentOutputParser.class.php'); /* for parser */ + + $body = format_content($content, $formatting,array()); + + $handler = new ContentOutputParser(); + $parser = new XML_HTMLSax(); + $parser->set_object($handler); + $parser->set_element_handler('openHandler','closeHandler'); + + $my_files = array(); + $parser->parse($body); + $my_files = array_unique($my_files); + + foreach ($my_files as $file) { + /* filter out full urls */ + $url_parts = @parse_url($file); + + // file should be relative to content + if ((substr($file, 0, 1) == '/')) { + continue; + } + + // The URL of the movie from youtube.com has been converted above in embed_media(). + // For example: http://www.youtube.com/watch?v=a0ryB0m0MiM is converted to + // http://www.youtube.com/v/a0ryB0m0MiM to make it playable. This creates the problem + // that the parsed-out url (http://www.youtube.com/v/a0ryB0m0MiM) does not match with + // the URL saved in content table (http://www.youtube.com/watch?v=a0ryB0m0MiM). + // The code below is to convert the URL back to original. + $file = convertYoutubePlayURLToWatchURL($file); + + $resources[] = convertAmp($file); // converts & to & + } + + if (count($resources) == 0) return; + + $a4a = new A4a($cid); + $db_primary_resources = $a4a->getPrimaryResources(); + + // clean up the removed resources + foreach ($db_primary_resources as $primary_rid=>$db_resource){ + //if this file from our table is not found in the $resource, then it's not used. + if(in_array($db_resource['resource'], $resources)===false){ + $a4a->deletePrimaryResource($primary_rid); + } + } + + // insert the new resources + foreach($resources as $primary_resource) + { + if (!$a4a->getPrimaryResourceByName($primary_resource)){ + $a4a->setPrimaryResource($cid, $primary_resource, $_SESSION['lang']); + } + } +} + // save all changes to the DB function save_changes($redir, $current_tab) { global $contentManager, $addslashes, $msg, $_course_id, $_content_id; @@ -124,6 +191,7 @@ function save_changes($redir, $current_tab) { // } // if (!$msg->containsErrors()) { + $orig_body_text = $_POST['body_text']; // used to populate a4a tables // $_POST['title'] = $addslashes($_POST['title']); // $_POST['body_text'] = $addslashes($_POST['body_text']); // $_POST['head'] = $addslashes($_POST['head']); @@ -155,6 +223,8 @@ function save_changes($redir, $current_tab) { $_POST['_cid'] = $cid; $_REQUEST['_cid'] = $cid; } + // re-populate a4a tables based on the new content + populate_a4a($cid, $orig_body_text, $_POST['formatting']); if ($cid == 0) return; // } diff --git a/docs/home/editor/editor_tabs/alternatives.inc.php b/docs/home/editor/editor_tabs/alternatives.inc.php index 76fc8df..ebf1231 100644 --- a/docs/home/editor/editor_tabs/alternatives.inc.php +++ b/docs/home/editor/editor_tabs/alternatives.inc.php @@ -29,27 +29,6 @@ if ($cid == 0) { require_once(TR_INCLUDE_PATH.'footer.inc.php'); exit; } -/** - * This function returns the preview link of the given file - * @param $file the file location in "file manager" - * @return the relative URL to preview the file - */ -function get_preview_link($file) -{ - global $content_row, $_course_id; - - if (substr($file, 0 , 7) == 'http://' || substr($file, 0 , 8) == 'https://') { - return $file; - } else { - if (defined('TR_FORCE_GET_FILE') && TR_FORCE_GET_FILE) { - $get_file = 'get.php/'; - } else { - $get_file = 'content/' . $_course_id . '/'; - } - } - - return $get_file.$content_row['content_path'].'/'.$file; -} /** * When the file name is a remote URL, this function reduces the full URL @@ -92,7 +71,7 @@ function display_alternative_cell($secondary_resources, $alternative_type, $cont if ($secondary_resource['type_id'] == $alternative_type) { echo '
'."\n"; - echo ' '.get_display_filename($secondary_resource['secondary_resource']).'
'."\n"; + echo ' '.get_display_filename($secondary_resource['secondary_resource']).'
'."\n"; echo ' '."\n"; echo ' '._AT('alter').''."\n"; echo ' '."\n"; @@ -115,9 +94,15 @@ function display_alternative_cell($secondary_resources, $alternative_type, $cont } // Main program -require(TR_INCLUDE_PATH.'lib/resources_parser.inc.php'); +global $db, $content_row; +populate_a4a($cid, $_POST['body_text'], $_POST['formatting']); + +include_once(AT_INCLUDE_PATH.'classes/A4a/A4a.class.php'); -if (count($resources)==0) +$a4a = new A4a($cid); +$primary_resources = $a4a->getPrimaryResources(); + +if (count($primary_resources)==0) { echo '

'. _AT('No_resources'). '

'; } @@ -145,32 +130,9 @@ else echo ' '."\n"; echo ' '; - foreach($resources as $primary_resource) + foreach($primary_resources as $primary_resource_id => $primary_resource_row) { - // check whether the primary resource is in the table - $sql = "SELECT * FROM ".TABLE_PREFIX."primary_resources - WHERE content_id = ".$cid." - AND language_code = '".$_SESSION['lang']."' - AND resource='".$primary_resource."'"; -// $primary_result = mysql_query($sql, $db); - $existing_primary_resource = $dao->execute($sql); - - // insert primary resource if it's not in db - if (!is_array($existing_primary_resource)) -// if (mysql_num_rows($primary_result) == 0) - { - $sql = "INSERT INTO ".TABLE_PREFIX."primary_resources (content_id, resource, language_code) - VALUES (".$cid.", '".$primary_resource."', '".$_SESSION['lang']."')"; -// $result = mysql_query($sql, $db); - $dao->execute($sql); - $primary_resource_id = mysql_insert_id(); - } - else - { - // get primary resource id -// $primary_resource_row = mysql_fetch_assoc($primary_result); - $primary_resource_id = $existing_primary_resource[0]['primary_resource_id']; - } + $primary_resource = $primary_resource_row['resource']; $sql = "SELECT prt.type_id, rt.type FROM ".TABLE_PREFIX."primary_resources pr, ". @@ -178,7 +140,7 @@ else TABLE_PREFIX."resource_types rt WHERE pr.content_id = ".$cid." AND pr.language_code = '".$_SESSION['lang']."' - AND pr.resource='".$primary_resource."' + AND pr.primary_resource_id='".$primary_resource_id."' AND pr.primary_resource_id = prt.primary_resource_id AND prt.type_id = rt.type_id"; // $primary_type_result = mysql_query($sql, $db); @@ -197,7 +159,7 @@ else TABLE_PREFIX."secondary_resources_types srt WHERE pr.content_id = ".$cid." AND pr.language_code = '".$_SESSION['lang']."' - AND pr.resource='".$primary_resource."' + AND pr.primary_resource_id='".$primary_resource_id."' AND pr.primary_resource_id = sr.primary_resource_id AND sr.secondary_resource_id = srt.secondary_resource_id"; // $secondary_result = mysql_query($sql, $db); @@ -207,7 +169,7 @@ else // table cell "original resource" echo ' '."\n"; - echo ' '.get_display_filename($primary_resource).''."\n"; + echo ' '.get_display_filename($primary_resource).''."\n"; echo ' '."\n"; // table cell "original resource type" diff --git a/docs/home/imscc/ims_export.php b/docs/home/imscc/ims_export.php index 68443ca..bb57c49 100644 --- a/docs/home/imscc/ims_export.php +++ b/docs/home/imscc/ims_export.php @@ -100,6 +100,7 @@ $course_language_code = $courseLanguage->getCode(); require_once(TR_INCLUDE_PATH.'classes/zipfile.class.php'); /* for zipfile */ require_once(TR_INCLUDE_PATH.'classes/vcard.php'); /* for vcard */ require_once(TR_INCLUDE_PATH.'classes/XML/XML_HTMLSax/XML_HTMLSax.php'); /* for XML_HTMLSax */ +require_once(TR_INCLUDE_PATH.'classes/ContentOutputParser.class.php'); /* to retrieve content resources/medias from at_content[text] */ require_once(TR_INCLUDE_PATH.'../home/imscc/include/ims_template.inc.php'); /* for ims templates + print_organizations() */ if (isset($_POST['cancel'])) { @@ -111,86 +112,12 @@ if (isset($_POST['cancel'])) { $zipfile = new zipfile(); $zipfile->create_dir('resources/'); -/* - the following resources are to be identified: - even if some of these can't be images, they can still be files in the content dir. - theoretically the only urls we wouldn't deal with would be for a - - img => src - a => href // ignore if href doesn't exist (ie. ) - object => data | classid // probably only want data - applet => classid | archive // whatever these two are should double check to see if it's a valid file (not a dir) - link => href - script => src - form => action - input => src - iframe => src - -*/ -class MyHandler { - function MyHandler(){} - function openHandler(& $parser,$name,$attrs) { - global $my_files; - - $name = strtolower($name); - $attrs = array_change_key_case($attrs, CASE_LOWER); - - $elements = array( 'img' => 'src', - 'a' => 'href', - 'object' => array('data', 'classid'), - 'applet' => array('classid', 'archive'), - 'link' => 'href', - 'script' => 'src', - 'form' => 'action', - 'input' => 'src', - 'iframe' => 'src', - 'embed' => 'src', - 'param' => 'value'); - - /* check if this attribute specifies the files in different ways: (ie. java) */ - if (is_array($elements[$name])) { - $items = $elements[$name]; - - foreach ($items as $item) { - if ($attrs[$item] != '') { - - /* some attributes allow a listing of files to include seperated by commas (ie. applet->archive). */ - if (strpos($attrs[$item], ',') !== false) { - $files = explode(',', $attrs[$item]); - foreach ($files as $file) { - $my_files[] = trim($file); - } - } else { - $my_files[] = $attrs[$item]; - } - } - } - } else if (isset($elements[$name]) && ($attrs[$elements[$name]] != '')) { - //hack, if param[name]=src or none tag, extract. Skip all other attributes. - if ($name!='param' || $attrs['name']=='src'){ - //skip glossary.html, tweak to accomodate atutor imscp; also skip repeated entries. - //skip javascript: links, void();, #, mailto: - if (strpos($attrs[$elements[$name]], 'glossary.html')===false - && !in_array($attrs[$elements[$name]], $my_files) - && $attrs[$elements[$name]]!='#' - && strpos($attrs[$elements[$name]], 'javascript:')===false - && strpos($attrs[$elements[$name]], 'mailto:')===false - && strpos($attrs[$elements[$name]], 'void(')===false - ){ - $my_files[] = $attrs[$elements[$name]]; - } - } - } - } - function closeHandler(& $parser,$name) { } -} - /* get all the content */ $content = array(); $paths = array(); $top_content_parent_id = 0; -$handler=new MyHandler(); +$handler=new ContentOutputParser(); $parser = new XML_HTMLSax(); $parser->set_object($handler); $parser->set_element_handler('openHandler','closeHandler'); diff --git a/docs/home/imscc/include/ims_template.inc.php b/docs/home/imscc/include/ims_template.inc.php index 3384bd3..c096590 100644 --- a/docs/home/imscc/include/ims_template.inc.php +++ b/docs/home/imscc/include/ims_template.inc.php @@ -328,6 +328,18 @@ function print_organizations($parent_id, } } + /** + * A hack to fix youtube links. one uses youtube.com?watch=xxx, the other uses youtube.com/v/xxx, + * in which both points to the same file, but needed different links to play. + * in A4a, these youtube links are always stored as "?watch=xxx", however, output.inc.php converted + * these to /v/xxx for rendering purposes. Convert it back if youtube exists in url. + * http://atutor.ca/atutor/mantis/view.php?id=4548 + * @harris 9/30/2010 + */ + if (strpos($file, 'youtube.com')!==false){ + //apply the conversion before linking the alternatives. Otherwise it will not be added. + $file = convert_youtube_playURL_to_watchURL($file); + } // If this file has a4a alternatives, link it. if (isset($a4a_xml_array[$file]) || isset($a4a_secondary_files[$file])){ //if this is an array, meaning that it has more than 1 alternatives, print all @@ -532,10 +544,14 @@ function print_resources_forum() { $ims_template_xml['header'] = ' - - - - + + + IMS Common Cartridge 1.0.0 diff --git a/docs/include/classes/A4a/A4a.class.php b/docs/include/classes/A4a/A4a.class.php index 9b7c069..be62e0b 100644 --- a/docs/include/classes/A4a/A4a.class.php +++ b/docs/include/classes/A4a/A4a.class.php @@ -72,6 +72,18 @@ class A4a { return $pri_resources; } + //get primary resource by resource name + function getPrimaryResourceByName($resource_name){ + if ($resource_name==''){ + return array(); + } + + include_once(TR_INCLUDE_PATH.'classes/DAO/PrimaryResourcesDAO.class.php'); + $primaryResourcesDAO = new PrimaryResourcesDAO(); + $pri_resources = $primaryResourcesDAO->getByResourceName($this->cid, $_SESSION['lang'], $resource_name); + return $pri_resources; + } + // Get primary resources types function getPrimaryResourcesTypes($pri_resource_id=0){ @@ -192,12 +204,22 @@ class A4a { } + /** + * Delete this primary resource and all its associated secondary resources + * @param int primary resournce id + */ + function deletePrimaryResource($primary_rid){ + include_once(TR_INCLUDE_PATH.'classes/DAO/PrimaryResourcesDAO.class.php'); + $primaryResourcesDAO = new PrimaryResourcesDAO(); + $primaryResourcesDAO->DeleteByResourceID($primary_rid); + } + // Delete all materials associated with this content function deleteA4a(){ include_once(TR_INCLUDE_PATH.'classes/DAO/PrimaryResourcesDAO.class.php'); $primaryResourcesDAO = new PrimaryResourcesDAO(); $rows = $primaryResourcesDAO->Delete($this->cid); - } + } } ?> \ No newline at end of file diff --git a/docs/include/classes/A4a/A4aExport.class.php b/docs/include/classes/A4a/A4aExport.class.php index 1599fe2..83274fb 100644 --- a/docs/include/classes/A4a/A4aExport.class.php +++ b/docs/include/classes/A4a/A4aExport.class.php @@ -34,6 +34,10 @@ class A4aExport extends A4a { foreach($resources as $rid => $prop){ $resources_types = parent::getPrimaryResourcesTypes($rid); + if (empty($resources_types)){ + //if there are no resource types, then don't use it. + continue; + } $temp = array(); $secondary_array = array(); foreach($resources_types as $rtid){ diff --git a/docs/include/classes/DAO/PrimaryResourcesDAO.class.php b/docs/include/classes/DAO/PrimaryResourcesDAO.class.php index bfadd5f..2e35ece 100644 --- a/docs/include/classes/DAO/PrimaryResourcesDAO.class.php +++ b/docs/include/classes/DAO/PrimaryResourcesDAO.class.php @@ -35,7 +35,7 @@ class PrimaryResourcesDAO extends DAO { global $addslashes; $content_id = intval($content_id); - $file_name = $addslashes($file_name); + $file_name = $addslashes(convertAmp($file_name)); $lang = $addslashes($lang); $sql = "INSERT INTO ".TABLE_PREFIX."primary_resources @@ -99,6 +99,26 @@ class PrimaryResourcesDAO extends DAO { return $this->execute($sql); } + /** + * Delete rows by using resource id + * @access public + * @param $resourceID: primary resource ID + * @return true or false + * @author Harris Wong + * @date Oct 6, 2010 + */ + function DeleteByResourceID($resourceID){ + // Delete all secondary a4a + $sql = 'DELETE c, d FROM '.TABLE_PREFIX.'secondary_resources c LEFT JOIN '.TABLE_PREFIX."secondary_resources_types d ON c.secondary_resource_id=d.secondary_resource_id WHERE primary_resource_id=$resourceID"; + $result = $this->execute($sql); + + // If successful, remove all primary resources + if ($result){ + $sql = 'DELETE a, b FROM '.TABLE_PREFIX.'primary_resources a LEFT JOIN '.TABLE_PREFIX."primary_resources_types b ON a.primary_resource_id=b.primary_resource_id WHERE a.primary_resource_id=$resourceID"; + return $this->execute($sql); + } + } + /** * Return rows by content_id * @access public @@ -108,8 +128,26 @@ class PrimaryResourcesDAO extends DAO { */ public function getByContent($cid) { - $sql = 'SELECT * FROM '.TABLE_PREFIX.'primary_resources WHERE content_id='.$cid; + $sql = 'SELECT * FROM '.TABLE_PREFIX.'primary_resources WHERE content_id='.$cid.' ORDER BY primary_resource_id';; return $this->execute($sql); } + + /** + * Return rows by primary resource name + * @access public + * @param $cid: the content id + * @param $lang: the language code. + * @param $resourceName: primary resource name + * @return table rows + * @author Harris Wong + * @date Oct 6, 2010 + */ + public function getByResourceName($cid, $lang, $resource_name){ + $sql = "SELECT * FROM ".TABLE_PREFIX."primary_resources + WHERE content_id=".$cid." + AND language_code = '".$lang."' + AND resource='".$resource_name."'"; + return $this->execute($sql); + } } ?> \ No newline at end of file diff --git a/docs/include/lib/mime.inc.php b/docs/include/lib/mime.inc.php index 4cf37bd..4761083 100644 --- a/docs/include/lib/mime.inc.php +++ b/docs/include/lib/mime.inc.php @@ -149,6 +149,7 @@ $mime['xml'] = array('text/xml', 'xml'); $mime['mpeg'] = array('video/mpeg', 'video'); $mime['mpg'] = array('video/mpeg', 'video'); $mime['mpe'] = array('video/mpeg', 'video'); +$mime['mp4'] = array('video/mp4', 'video'); $mime['qt'] = array('video/quicktime', 'qt'); $mime['mov'] = array('video/quicktime', 'qt'); $mime['wmv'] = array('video/x-ms-wmv', 'video'); diff --git a/docs/include/lib/resources_parser.inc.php b/docs/include/lib/resources_parser.inc.php index 2daf5f6..4c676fc 100644 --- a/docs/include/lib/resources_parser.inc.php +++ b/docs/include/lib/resources_parser.inc.php @@ -136,6 +136,15 @@ foreach ($my_files as $file) { continue; } + // The URL of the movie from youtube.com has been converted above in embed_media(). + // For example: http://www.youtube.com/watch?v=a0ryB0m0MiM is converted to + // http://www.youtube.com/v/a0ryB0m0MiM to make it playable. This creates the problem + // that the parsed-out url (http://www.youtube.com/v/a0ryB0m0MiM) does not match with + // the URL saved in content table (http://www.youtube.com/watch?v=a0ryB0m0MiM). + // The code below is to convert the URL back to original. + $file = preg_replace("/(http:\/\/[a-z0-9\.]*)?youtube.com\/v\/(.*)/", + "\\1youtube.com/watch?v=\\2", $file); + $resources[$i] = $file; $i++; } diff --git a/docs/include/vitals.inc.php b/docs/include/vitals.inc.php index 83db8a2..2b422d2 100644 --- a/docs/include/vitals.inc.php +++ b/docs/include/vitals.inc.php @@ -107,6 +107,9 @@ if (is_array($rows)) } } +//set the timezone, php 5.3+ problem. http://atutor.ca/atutor/mantis/view.php?id=4409 +date_default_timezone_set('UTC'); + // define as constants. more constants are defined in include/constants.inc.php define('EMAIL', $_config['contact_email']); define('SITE_NAME', $_config['site_name']); @@ -397,4 +400,16 @@ function get_default_theme() { return $rows[0]['dir_name']; } +/** + * Convert all '&' to '&' from the input + * @param string any string input, mainly URLs. + * @return input with & replaced to '&' + * @author Harris Wong + * @date Oct 7, 2010 + */ +function convertAmp($input){ + $input = str_replace('&', '&', $input); //convert everything to '&' first + return str_replace('&', '&', $input); +} + ?> -- 2.17.1