function print_organizations($parent_id, &$_menu, $depth, $path = '', $children, &$string) { global $html_content_template, $default_html_style, $zipfile, $resources, $ims_template_xml, $parser, $my_files; global $used_glossary_terms, $course_id, $course_language_charset, $course_language_code; static $paths, $zipped_files; // global $glossary; global $test_list, $test_zipped_files, $test_files, $test_xml_items, $use_a4a; global $contentManager; /* added by bologna*/ //TODO***********BOLOGNA**************REMOVE ME*****************/ global $db, $forum_list; //forum_list contiene tutti i forum distinti associati ai contenuti. poich� la funzione in questione � ricorsiva deve essere globale in modo che in fase di creazione dell'archivio zip i file descrittori dei forum non vengano ripetuti require_once TR_INCLUDE_PATH . '../home/classes/ContentUtility.class.php'; require_once TR_INCLUDE_PATH . 'classes/DAO/ContentForumsAssocDAO.class.php'; $space = ' '; $prefix = ' '; if ($depth == 0) { $string .= '<ul>'; } $top_level = $_menu[$parent_id]; if (!is_array($paths)) { $paths = array(); } if (!is_array($zipped_files)) { $zipped_files = array(); } if (is_array($top_level)) { $counter = 1; $num_items = count($top_level); foreach ($top_level as $garbage => $content) { $link = ''; //XSL characters handling $content['title'] = str_replace('&', '&', $content['title']); if ($content['content_path'] && substr($content['content_path'], -1) != '/') { $content['content_path'] .= '/'; } /* * generate weblinks * Reason to put it here is cause we don't want the content to be overwrittened. */ if ($content['content_type'] == CONTENT_TYPE_WEBLINK) { $wl = new Weblinks($content['title'], $content['text']); $wlexport = new WeblinksExport($wl); $wl_xml = $wlexport->export(); $wl_filename = 'weblinks_' . $content['content_id'] . '.xml'; $zipfile->add_file($wl_xml, 'Weblinks/' . $wl_filename, $content['u_ts']); $resources .= str_replace(array('{PATH}', '{CONTENT_ID}'), array($wl_filename, $content['content_id']), $ims_template_xml['resource_weblink']); //Done. // continue; } if ($content['content_type'] == CONTENT_TYPE_FOLDER) { $link .= $prefix . '<item identifier="MANIFEST01_FOLDER' . $content['content_id'] . '">' . "\n"; $link .= $prefix . $space . '<title>' . $content['title'] . '</title>' . "\n"; } else { $link .= '<item identifier="MANIFEST01_ITEM' . $content['content_id'] . '" identifierref="MANIFEST01_RESOURCE' . $content['content_id'] . '">' . "\n"; $link .= $prefix . $space . '<title>' . $content['title'] . '</title>' . "\n{$prefix}{$space}"; } $html_link = '<a href="resources/' . $content['content_path'] . $content['content_id'] . '.html" target="body">' . $content['title'] . '</a>'; /* save the content as HTML files */ $content['text'] = str_replace('CONTENT_DIR/', '', $content['text']); /* Commented by Cindy Qi Li on Jan 12, 2010 * AContent does not support glossary // get all the glossary terms used $terms = find_terms($content['text']); if (is_array($terms)) { foreach ($terms[2] as $term) { $used_glossary_terms[] = $term; } } */ $f_count = count($forum_list); //count all distinct forum_id associated to a content page //la funzione è ricorsiva quindi lo devo ricavare attraverso la variabile globale forum_list $contentForumsAssocDAO = new ContentForumsAssocDAO(); $forums = $contentForumsAssocDAO->getByContent($content[content_id]); // $sql = "SELECT cf.forum_id, f.title, f.description FROM (SELECT * FROM ".TABLE_PREFIX."content_forums_assoc WHERE content_id=$content[content_id]) AS cf LEFT JOIN ".TABLE_PREFIX."forums f ON cf.forum_id=f.forum_id"; // $result_cf = mysql_query($sql,$db); $find = false; $forums_dependency = ''; //template for associate Discussion Topic to the current content into the manifest if (is_array($forums)) { foreach ($forums as $current_forum) { for ($j = 0; $j < $f_count; $j++) { if ($forum_list[$j]['id'] == $current_forum['forum_id']) { $find = true; } } if (!$find) { $forum_list[$f_count]['id'] = $current_forum['forum_id']; $forum_list[$f_count]['title'] = $current_forum['title']; $forum_list[$f_count]['description'] = $current_forum['description']; $find = false; $f_count++; } } $forums_dependency .= $prefix . $space . '<dependency identifierref="Forum' . $current_forum['forum_id'] . '_R" />'; } /** Test dependency **/ require_once TR_INCLUDE_PATH . 'classes/DAO/ContentTestsAssocDAO.class.php'; $contentTestsAssocDAO = new ContentTestsAssocDAO(); // $sql = 'SELECT * FROM '.TABLE_PREFIX.'content_tests_assoc WHERE content_id='.$content['content_id']; // $result = mysql_query($sql, $db); // while ($row = mysql_fetch_assoc($result)){ $rows = $contentTestsAssocDAO->getByContent($content['content_id']); if (is_array($rows)) { //add test dependency on top of forum dependency foreach ($rows as $row) { $forums_dependency .= $prefix . $space . '<dependency identifierref="MANIFEST01_RESOURCE_QTI' . $row['test_id'] . '" />'; } } /* calculate how deep this page is: */ $path = '../'; if ($content['content_path']) { $depth = substr_count($content['content_path'], '/'); $path .= str_repeat('../', $depth); } $content['text'] = ContentUtility::formatContent($content['text'], $content['formatting']); // add HTML header and footers to the files // use default style if <style> is not in imported html head $head = ''; if ($content['use_customized_head']) { if (strpos(strtolower($content['head']), '<style') > 0) { $head = $content['head']; } else { if (strlen($content['head']) > 0) { $head = $content['head'] . $default_html_style; } else { $head = $default_html_style; } } } $content['text'] = str_replace(array('{TITLE}', '{CONTENT}', '{KEYWORDS}', '{COURSE_PRIMARY_LANGUAGE_CHARSET}', '{COURSE_PRIMARY_LANGUAGE_CODE}', '{HEAD}'), array($content['title'], $content['text'], $content['keywords'], $course_language_charset, $course_language_code, $head), $html_content_template); /* duplicate the paths in the content_path field in the zip file */ if ($content['content_path']) { if (!in_array($content['content_path'], $paths)) { $zipfile->create_dir('resources/' . $content['content_path'], time()); $paths[] = $content['content_path']; } } //add the file iff it's a content file if ($content['content_type'] == CONTENT_TYPE_CONTENT) { $zipfile->add_file($content['text'], 'resources/' . $content['content_path'] . $content['content_id'] . '.html', $content['u_ts']); } $content['title'] = htmlspecialchars($content['title']); /* add the resource dependancies */ if ($my_files == null) { $my_files = array(); } $content_files = "\n"; $parser->parse($content['text']); /* generate the IMS QTI resource and files */ //check if test export is allowed. $content_test_rs = $contentManager->getContentTestsAssoc($content['content_id']); $test_ids = array(); //reset test ids //$my_files = array(); //reset myfiles. if (is_array($content_test_rs)) { foreach ($content_test_rs as $content_test_row) { //export $test_ids[] = $content_test_row['test_id']; //the 'added_files' is for adding into the manifest file in this zip $added_files = test_qti_export($content_test_row['test_id'], '', $zipfile); foreach ($added_files as $xml_file => $chunk) { foreach ($chunk as $xml_filename) { $added_files_xml .= str_replace('{FILE}', 'resources/' . $xml_filename, $ims_template_xml['xml']); } } //Save all the xml files in this array, and then print_organizations will add it to the manifest file. $resources .= str_replace(array('{TEST_ID}', '{PATH}', '{FILES}'), array($content_test_row['test_id'], 'tests_' . $content_test_row['test_id'] . '.xml', $added_files_xml), $ims_template_xml['resource_test']); /* Taken out since we are gonna use dependency instead $test_xml_items .= str_replace( array('{TEST_ID}'), array($content_test_row['test_id']), $ims_template_xml['test']); */ foreach ($test_files as $filename => $realfilepath) { $zipfile->add_file(@file_get_contents($realfilepath), 'resources/' . $filename, filemtime($realfilepath)); } } } /* generate the a4a files */ $a4a_xml_array = array(); //http://atutor.ca/atutor/mantis/view.php?id=4593 if ($content['formatting'] === 0) { $use_a4a = false; } if ($use_a4a == true) { $a4aExport = new A4aExport($content['content_id']); // $a4aExport->setRelativePath('resources/'.$content['content_path']); $secondary_files = $a4aExport->getAllSecondaryFiles(); $a4a_xml_array = $a4aExport->exportA4a(); $my_files = array_merge($my_files, $a4aExport->getAllSecondaryFiles()); } /* handle @import */ $import_files = get_import_files($content['text']); if (count($import_files) > 0) { $my_files = array_merge($my_files, $import_files); } foreach ($my_files as $file) { /* filter out full urls */ $url_parts = @parse_url($file); // if (isset($url_parts['scheme'])) { // continue; // } /* file should be relative to content. let's double check */ if (substr($file, 0, 1) == '/') { continue; } if (substr($file, 0, 7) != 'http://' && substr($file, 0, 8) != 'https://') { $file_path = realpath(TR_CONTENT_DIR . $course_id . '/' . $content['content_path'] . $file); /* check if the path contains TR_CONTENT_DIR in it, if not, skip it, it's trying to scan through * the file system */ if (strpos($file_path, TR_CONTENT_DIR) !== 0) { continue; //skip } /* check if this file exists in the content dir, if not don't include it */ if (file_exists($file_path) && is_file($file_path) && !in_array($file_path, $zipped_files)) { $zipped_files[] = $file_path; $dir = substr(dirname($file_path), strlen(TR_CONTENT_DIR . $course_id)); if (!in_array($dir, $paths) && $dir) { $dir = str_replace('\\', '/', substr($dir, 1)); $zipfile->create_dir('resources/' . $dir, time()); $paths[] = $dir; } $file_info = stat($file_path); //remove relative path in the content_path. $filepath_array = explode('/', 'resources/' . $content['content_path'] . $file); $new_filepath_array = array(); if (in_array('..', $filepath_array)) { while (!empty($filepath_array)) { $temp = array_shift($filepath_array); if ($temp == '..') { array_pop($new_filepath_array); } else { array_push($new_filepath_array, $temp); } } $zip_path = implode('/', $new_filepath_array); } else { $zip_path = 'resources/' . $content['content_path'] . $file; } $zipfile->add_file(@file_get_contents($file_path), $zip_path, $file_info['mtime']); } } //a4a secondary files have mapping, save the ones that we want in order to add the tag in $a4a_secondary_files = array(); foreach ($a4a_xml_array as $a4a_filename => $a4a_filearray) { if (preg_match('/(.*)\\sto\\s(.*)/', $a4a_filename, $matches)) { //save the actual file name $a4a_secondary_files[$matches[1]][] = $a4a_filename; //values are holders } } /** * 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 = ContentUtility::convertYoutubePlayURLToWatchURL($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 if (substr($file, 0, 7) == 'http://' || substr($file, 0, 8) == 'https://') { $name_in_file_meta = $file; } else { $name_in_file_meta = 'resources/' . $content['content_path'] . $file; } if (is_array($a4a_secondary_files[$file])) { $all_secondary_files_md = ''; //reinitialize string to null foreach ($a4a_secondary_files[$file] as $v) { foreach ($a4a_xml_array[$v] as $v2) { $all_secondary_files_md .= $v2; //all the meta data } } $content_files .= str_replace(array('{FILE}', '{FILE_META_DATA}'), array($name_in_file_meta, $all_secondary_files_md), $ims_template_xml['file_meta']); } else { $content_files .= str_replace(array('{FILE}', '{FILE_META_DATA}'), array($name_in_file_meta, $a4a_xml_array[$file]), $ims_template_xml['file_meta']); } } else { //if this file is in the test array, add an extra link to the direct file, if (!empty($test_zipped_files) && in_array($file_path, $test_zipped_files)) { $content_files .= str_replace('{FILE}', $file, $ims_template_xml['file']); } else { if (preg_match('/^http[s]?\\:/', $file) == 1) { $content_files .= str_replace('{FILE}', $file, $ims_template_xml['xml']); } elseif (file_exists($file_path) && is_file($file_path)) { //relative link that goes beyond get.php shouldn't be added //relative link that does not exist shouldn't be added. $filepath_array = explode('/', $content['content_path'] . $file); $new_filepath_array = array(); if (in_array('..', $filepath_array)) { while (!empty($filepath_array)) { $temp = array_shift($filepath_array); if ($temp == '..') { array_pop($new_filepath_array); } else { array_push($new_filepath_array, $temp); } } $file = implode('/', $new_filepath_array); } else { $file = $content['content_path'] . $file; } $content_files .= str_replace('{FILE}', $file, $ims_template_xml['file']); } } } /* check if this file is one of the test xml file, if so, we need to add the dependency * Note: The file has already been added to the archieve before this is called. */ if (preg_match('/tests\\_[0-9]+\\.xml$/', $file) && !in_array($file, $test_zipped_files)) { $content_files .= str_replace('{FILE}', 'QTI/' . $file, $ims_template_xml['xml']); $test_zipped_files[] = $file; } } /****************************** * http://www.atutor.ca/atutor/mantis/view.php?id=4383 */ $my_files = array(); /******************************/ //add it to the resources section if it hasn't been added. //Weblinks have been added. //Folders aren't resourecs, they shouldn't be added if ($content['content_type'] == CONTENT_TYPE_CONTENT) { $resources .= str_replace(array('{CONTENT_ID}', '{PATH}', '{FILES}', '{DEPENDENCY}'), array($content['content_id'], $content['content_path'], $content_files, $forums_dependency), $ims_template_xml['resource']); } for ($i = 0; $i < $depth; $i++) { $link .= $space; } if (is_array($_menu[$content['content_id']])) { /* has children */ $html_link = '<li>' . $html_link . '<ul>'; for ($i = 0; $i < $depth; $i++) { if ($children[$i] == 1) { echo $space; //$html_link = $space.$html_link; } else { echo $space; //$html_link = $space.$html_link; } } } else { /* doesn't have children */ $html_link = '<li>' . $html_link . '</li>'; if ($counter == $num_items) { for ($i = 0; $i < $depth; $i++) { if ($children[$i] == 1) { echo $space; //$html_link = $space.$html_link; } else { echo $space; //$html_link = $space.$html_link; } } } else { for ($i = 0; $i < $depth; $i++) { echo $space; //$html_link = $space.$html_link; } } $title = $space . $title; } echo $prefix . $link; // echo $title; echo "\n"; $string .= $html_link . "\n"; $depth++; print_organizations($content['content_id'], $_menu, $depth, $path . $counter . '.', $children, $string); $depth--; $counter++; for ($i = 0; $i < $depth; $i++) { echo $space; } // if (!empty($_menu[$content['content_id']])){ echo $prefix . '</item>'; // } echo "\n"; } $string .= '</ul>'; if ($depth > 0) { $string .= '</li>'; } } }
function populate_a4a($cid, $content, $formatting) { global $my_files, $content_base_href, $contentManager; // Defining alternatives is only available for content type "html". // But don't clean up the a4a tables at other content types in case the user needs them back at html. if ($formatting != 1) { return; } include_once TR_INCLUDE_PATH . 'classes/A4a/A4a.class.php'; include_once TR_INCLUDE_PATH . 'classes/XML/XML_HTMLSax/XML_HTMLSax.php'; /* for XML_HTMLSax */ include_once TR_INCLUDE_PATH . 'classes/ContentOutputParser.class.php'; /* for parser */ // initialize content_base_href; used in format_content if (!isset($content_base_href)) { $content_row = $contentManager->getContentPage($cid); // return if the cid is not found if (!is_array($content_row)) { return; } $content_base_href = $content_row["content_path"] . '/'; } $body = ContentUtility::formatContent($content, $formatting); $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 = ContentUtility::convertYoutubePlayURLToWatchURL($file); $resources[] = convertAmp($file); // converts & to & } $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 (count($resources) == 0 || !in_array($db_resource['resource'], $resources)) { $a4a->deletePrimaryResource($primary_rid); } } if (count($resources) == 0) { return; } // insert the new resources foreach ($resources as $primary_resource) { if (!$a4a->getPrimaryResourceByName($primary_resource)) { $a4a->setPrimaryResource($cid, $primary_resource, $_SESSION['lang']); } } }