|
Moodle
2.2.1
http://www.collinsharper.com
|
00001 <?php 00002 00003 // This file is part of Moodle - http://moodle.org/ 00004 // 00005 // Moodle is free software: you can redistribute it and/or modify 00006 // it under the terms of the GNU General Public License as published by 00007 // the Free Software Foundation, either version 3 of the License, or 00008 // (at your option) any later version. 00009 // 00010 // Moodle is distributed in the hope that it will be useful, 00011 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00013 // GNU General Public License for more details. 00014 // 00015 // You should have received a copy of the GNU General Public License 00016 // along with Moodle. If not, see <http://www.gnu.org/licenses/>. 00017 00027 defined('MOODLE_INTERNAL') || die(); 00028 00029 require_once("$CFG->dirroot/mod/imscp/lib.php"); 00030 require_once("$CFG->libdir/filelib.php"); 00031 require_once("$CFG->libdir/resourcelib.php"); 00032 00033 function imscp_print_content($imscp, $cm, $course) { 00034 global $PAGE, $CFG; 00035 00036 $items = unserialize($imscp->structure); 00037 $first = reset($items); 00038 $context = get_context_instance(CONTEXT_MODULE, $cm->id); 00039 $urlbase = "$CFG->wwwroot/pluginfile.php"; 00040 $path = '/'.$context->id.'/mod_imscp/content/'.$imscp->revision.'/'.$first['href']; 00041 $firsturl = file_encode_url($urlbase, $path, false); 00042 00043 echo '<div id="imscp_layout">'; 00044 echo '<div id="imscp_toc">'; 00045 echo '<div id="imscp_tree"><ul>'; 00046 foreach ($items as $item) { 00047 echo imscp_htmllize_item($item, $imscp, $cm); 00048 } 00049 echo '</ul></div>'; 00050 echo '<div id="imscp_nav" style="display:none"><button id="nav_skipprev"><<</button><button id="nav_prev"><</button><button id="nav_up">^</button><button id="nav_next">></button><button id="nav_skipnext">>></button></div>'; 00051 echo '</div>'; 00052 echo '</div>'; 00053 00054 $PAGE->requires->js_init_call('M.mod_imscp.init'); 00055 return; 00056 } 00057 00061 function imscp_htmllize_item($item, $imscp, $cm) { 00062 global $CFG; 00063 00064 $context = get_context_instance(CONTEXT_MODULE, $cm->id); 00065 $urlbase = "$CFG->wwwroot/pluginfile.php"; 00066 $path = '/'.$context->id.'/mod_imscp/content/'.$imscp->revision.'/'.$item['href']; 00067 $url = file_encode_url($urlbase, $path, false); 00068 $result = "<li><a href=\"$url\">".$item['title'].'</a>'; 00069 if ($item['subitems']) { 00070 $result .= '<ul>'; 00071 foreach ($item['subitems'] as $subitem) { 00072 $result .= imscp_htmllize_item($subitem, $imscp, $cm); 00073 } 00074 $result .= '</ul>'; 00075 } 00076 $result .= '</li>'; 00077 00078 return $result; 00079 } 00080 00087 function imscp_parse_structure($imscp, $context) { 00088 $fs = get_file_storage(); 00089 00090 if (!$manifestfile = $fs->get_file($context->id, 'mod_imscp', 'content', $imscp->revision, '/', 'imsmanifest.xml')) { 00091 return null; 00092 } 00093 00094 return imscp_parse_manifestfile($manifestfile->get_content()); 00095 } 00096 00102 function imscp_parse_manifestfile($manifestfilecontents) { 00103 $doc = new DOMDocument(); 00104 if (!$doc->loadXML($manifestfilecontents, LIBXML_NONET)) { 00105 return null; 00106 } 00107 00108 // we put this fake URL as base in order to detect path changes caused by xml:base attributes 00109 $doc->documentURI = 'http://grrr/'; 00110 00111 $xmlorganizations = $doc->getElementsByTagName('organizations'); 00112 if (empty($xmlorganizations->length)) { 00113 return null; 00114 } 00115 $default = null; 00116 if ($xmlorganizations->item(0)->attributes->getNamedItem('default')) { 00117 $default = $xmlorganizations->item(0)->attributes->getNamedItem('default')->nodeValue; 00118 } 00119 $xmlorganization = $doc->getElementsByTagName('organization'); 00120 if (empty($xmlorganization->length)) { 00121 return null; 00122 } 00123 $organization = null; 00124 foreach ($xmlorganization as $org) { 00125 if (is_null($organization)) { 00126 // use first if default nor found 00127 $organization = $org; 00128 } 00129 if (!$org->attributes->getNamedItem('identifier')) { 00130 continue; 00131 } 00132 if ($default === $org->attributes->getNamedItem('identifier')->nodeValue) { 00133 // found default - use it 00134 $organization = $org; 00135 break; 00136 } 00137 } 00138 00139 // load all resources 00140 $resources = array(); 00141 00142 $xmlresources = $doc->getElementsByTagName('resource'); 00143 foreach ($xmlresources as $res) { 00144 if (!$identifier = $res->attributes->getNamedItem('identifier')) { 00145 continue; 00146 } 00147 $identifier = $identifier->nodeValue; 00148 if ($xmlbase = $res->baseURI) { 00149 // undo the fake URL, we are interested in relative links only 00150 $xmlbase = str_replace('http://grrr/', '/', $xmlbase); 00151 $xmlbase = rtrim($xmlbase, '/').'/'; 00152 } else { 00153 $xmlbase = ''; 00154 } 00155 if (!$href = $res->attributes->getNamedItem('href')) { 00156 // If href not found look for <file href="help.htm"/> 00157 $fileresources = $res->getElementsByTagName('file'); 00158 foreach ($fileresources as $file) { 00159 $href = $file->getAttribute('href'); 00160 } 00161 if (empty($href)) { 00162 continue; 00163 } 00164 } else { 00165 $href = $href->nodeValue; 00166 } 00167 if (strpos($href, 'http://') !== 0) { 00168 $href = $xmlbase.$href; 00169 } 00170 // href cleanup - Some packages are poorly done and use \ in urls 00171 $href = ltrim(strtr($href, "\\", '/'), '/'); 00172 $resources[$identifier] = $href; 00173 } 00174 00175 $items = array(); 00176 foreach ($organization->childNodes as $child) { 00177 if ($child->nodeName === 'item') { 00178 if (!$item = imscp_recursive_item($child, 0, $resources)) { 00179 continue; 00180 } 00181 $items[] = $item; 00182 } 00183 } 00184 00185 return $items; 00186 } 00187 00188 function imscp_recursive_item($xmlitem, $level, $resources) { 00189 $identifierref = ''; 00190 if ($identifierref = $xmlitem->attributes->getNamedItem('identifierref')) { 00191 $identifierref = $identifierref->nodeValue; 00192 } 00193 00194 $title = '?'; 00195 $subitems = array(); 00196 00197 foreach ($xmlitem->childNodes as $child) { 00198 if ($child->nodeName === 'title') { 00199 $title = $child->textContent; 00200 00201 } else if ($child->nodeName === 'item') { 00202 if ($subitem = imscp_recursive_item($child, $level+1, $resources)) { 00203 $subitems[] = $subitem; 00204 } 00205 } 00206 } 00207 00208 return array('href' => isset($resources[$identifierref]) ? $resources[$identifierref] : '', 00209 'title' => $title, 00210 'level' => $level, 00211 'subitems' => $subitems, 00212 ); 00213 } 00214 00218 class imscp_file_info extends file_info { 00219 protected $course; 00220 protected $cm; 00221 protected $areas; 00222 protected $filearea; 00223 00224 public function __construct($browser, $course, $cm, $context, $areas, $filearea) { 00225 parent::__construct($browser, $context); 00226 $this->course = $course; 00227 $this->cm = $cm; 00228 $this->areas = $areas; 00229 $this->filearea = $filearea; 00230 } 00231 00238 public function get_params() { 00239 return array('contextid'=>$this->context->id, 00240 'component'=>'mod_imscp', 00241 'filearea' =>$this->filearea, 00242 'itemid' =>null, 00243 'filepath' =>null, 00244 'filename' =>null); 00245 } 00246 00251 public function get_visible_name() { 00252 return $this->areas[$this->filearea]; 00253 } 00254 00259 public function is_writable() { 00260 return false; 00261 } 00262 00267 public function is_directory() { 00268 return true; 00269 } 00270 00275 public function get_children() { 00276 global $DB; 00277 00278 $children = array(); 00279 $itemids = $DB->get_records('files', array('contextid'=>$this->context->id, 'component'=>'mod_imscp', 'filearea'=>$this->filearea), 'itemid', "DISTINCT itemid"); 00280 foreach ($itemids as $itemid=>$unused) { 00281 if ($child = $this->browser->get_file_info($this->context, 'mod_imscp', $this->filearea, $itemid)) { 00282 $children[] = $child; 00283 } 00284 } 00285 return $children; 00286 } 00287 00292 public function get_parent() { 00293 return $this->browser->get_file_info($this->context); 00294 } 00295 }