|
Moodle
2.2.1
http://www.collinsharper.com
|
00001 <?php 00002 // This file is part of Moodle - http://moodle.org/ 00003 // 00004 // Moodle is free software: you can redistribute it and/or modify 00005 // it under the terms of the GNU General Public License as published by 00006 // the Free Software Foundation, either version 3 of the License, or 00007 // (at your option) any later version. 00008 // 00009 // Moodle is distributed in the hope that it will be useful, 00010 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00012 // GNU General Public License for more details. 00013 // 00014 // You should have received a copy of the GNU General Public License 00015 // along with Moodle. If not, see <http://www.gnu.org/licenses/>. 00016 00017 function scorm_add_time($a, $b) { 00018 $aes = explode(':', $a); 00019 $bes = explode(':', $b); 00020 $aseconds = explode('.', $aes[2]); 00021 $bseconds = explode('.', $bes[2]); 00022 $change = 0; 00023 00024 $acents = 0; //Cents 00025 if (count($aseconds) > 1) { 00026 $acents = $aseconds[1]; 00027 } 00028 $bcents = 0; 00029 if (count($bseconds) > 1) { 00030 $bcents = $bseconds[1]; 00031 } 00032 $cents = $acents + $bcents; 00033 $change = floor($cents / 100); 00034 $cents = $cents - ($change * 100); 00035 if (floor($cents) < 10) { 00036 $cents = '0'. $cents; 00037 } 00038 00039 $secs = $aseconds[0] + $bseconds[0] + $change; //Seconds 00040 $change = floor($secs / 60); 00041 $secs = $secs - ($change * 60); 00042 if (floor($secs) < 10) { 00043 $secs = '0'. $secs; 00044 } 00045 00046 $mins = $aes[1] + $bes[1] + $change; //Minutes 00047 $change = floor($mins / 60); 00048 $mins = $mins - ($change * 60); 00049 if ($mins < 10) { 00050 $mins = '0' . $mins; 00051 } 00052 00053 $hours = $aes[0] + $bes[0] + $change; //Hours 00054 if ($hours < 10) { 00055 $hours = '0' . $hours; 00056 } 00057 00058 if ($cents != '0') { 00059 return $hours . ":" . $mins . ":" . $secs . '.' . $cents; 00060 } else { 00061 return $hours . ":" . $mins . ":" . $secs; 00062 } 00063 } 00064 00074 function scorm_get_aicc_columns($row, $mastername='system_id') { 00075 $tok = strtok(strtolower($row), "\",\n\r"); 00076 $result = new stdClass(); 00077 $result->columns = array(); 00078 $i=0; 00079 while ($tok) { 00080 if ($tok !='') { 00081 $result->columns[] = $tok; 00082 if ($tok == $mastername) { 00083 $result->mastercol = $i; 00084 } 00085 $i++; 00086 } 00087 $tok = strtok("\",\n\r"); 00088 } 00089 return $result; 00090 } 00091 00100 function scorm_forge_cols_regexp($columns, $remodule='(".*")?,') { 00101 $regexp = '/^'; 00102 foreach ($columns as $column) { 00103 $regexp .= $remodule; 00104 } 00105 $regexp = substr($regexp, 0, -1) . '/'; 00106 return $regexp; 00107 } 00108 00109 00110 function scorm_parse_aicc($scorm) { 00111 global $DB; 00112 00113 if ($scorm->scormtype == SCORM_TYPE_AICCURL) { 00114 return scorm_aicc_generate_simple_sco($scorm); 00115 } 00116 if (!isset($scorm->cmid)) { 00117 $cm = get_coursemodule_from_instance('scorm', $scorm->id); 00118 $scorm->cmid = $cm->id; 00119 } 00120 $context = get_context_instance(CONTEXT_MODULE, $scorm->cmid); 00121 00122 $fs = get_file_storage(); 00123 00124 $files = $fs->get_area_files($context->id, 'mod_scorm', 'content', 0, '', false); 00125 00126 $version = 'AICC'; 00127 $ids = array(); 00128 $courses = array(); 00129 $extaiccfiles = array('crs', 'des', 'au', 'cst', 'ort', 'pre', 'cmp'); 00130 00131 foreach ($files as $file) { 00132 $filename = $file->get_filename(); 00133 $ext = substr($filename, strrpos($filename, '.')); 00134 $extension = strtolower(substr($ext, 1)); 00135 if (in_array($extension, $extaiccfiles)) { 00136 $id = strtolower(basename($filename, $ext)); 00137 $ids[$id]->$extension = $file; 00138 } 00139 } 00140 00141 foreach ($ids as $courseid => $id) { 00142 if (isset($id->crs)) { 00143 $contents = $id->crs->get_content(); 00144 $rows = explode("\r\n", $contents); 00145 if (is_array($rows)) { 00146 foreach ($rows as $row) { 00147 if (preg_match("/^(.+)=(.+)$/", $row, $matches)) { 00148 switch (strtolower(trim($matches[1]))) { 00149 case 'course_id': 00150 $courses[$courseid]->id = trim($matches[2]); 00151 break; 00152 case 'course_title': 00153 $courses[$courseid]->title = trim($matches[2]); 00154 break; 00155 case 'version': 00156 $courses[$courseid]->version = 'AICC_'.trim($matches[2]); 00157 break; 00158 } 00159 } 00160 } 00161 } 00162 } 00163 if (isset($id->des)) { 00164 $contents = $id->des->get_content(); 00165 $rows = explode("\r\n", $contents); 00166 $columns = scorm_get_aicc_columns($rows[0]); 00167 $regexp = scorm_forge_cols_regexp($columns->columns); 00168 for ($i=1; $i<count($rows); $i++) { 00169 if (preg_match($regexp, $rows[$i], $matches)) { 00170 for ($j=0; $j<count($columns->columns); $j++) { 00171 $column = $columns->columns[$j]; 00172 $courses[$courseid]->elements[substr(trim($matches[$columns->mastercol+1]), 1 , -1)]->$column = substr(trim($matches[$j+1]), 1, -1); 00173 } 00174 } 00175 } 00176 } 00177 if (isset($id->au)) { 00178 $contents = $id->au->get_content(); 00179 $rows = explode("\r\n", $contents); 00180 $columns = scorm_get_aicc_columns($rows[0]); 00181 $regexp = scorm_forge_cols_regexp($columns->columns); 00182 for ($i=1; $i<count($rows); $i++) { 00183 if (preg_match($regexp, $rows[$i], $matches)) { 00184 for ($j=0; $j<count($columns->columns); $j++) { 00185 $column = $columns->columns[$j]; 00186 $courses[$courseid]->elements[substr(trim($matches[$columns->mastercol+1]), 1, -1)]->$column = substr(trim($matches[$j+1]), 1, -1); 00187 } 00188 } 00189 } 00190 } 00191 if (isset($id->cst)) { 00192 $contents = $id->cst->get_content(); 00193 $rows = explode("\r\n", $contents); 00194 $columns = scorm_get_aicc_columns($rows[0], 'block'); 00195 $regexp = scorm_forge_cols_regexp($columns->columns, '(.+)?,'); 00196 for ($i=1; $i<count($rows); $i++) { 00197 if (preg_match($regexp, $rows[$i], $matches)) { 00198 for ($j=0; $j<count($columns->columns); $j++) { 00199 if ($j != $columns->mastercol) { 00200 $courses[$courseid]->elements[substr(trim($matches[$j+1]), 1 , -1)]->parent = substr(trim($matches[$columns->mastercol+1]), 1, -1); 00201 } 00202 } 00203 } 00204 } 00205 } 00206 if (isset($id->ort)) { 00207 $contents = $id->ort->get_content(); 00208 $rows = explode("\r\n", $contents); 00209 $columns = scorm_get_aicc_columns($rows[0], 'course_element'); 00210 $regexp = scorm_forge_cols_regexp($columns->columns, '(.+)?,'); 00211 for ($i=1; $i<count($rows); $i++) { 00212 if (preg_match($regexp, $rows[$i], $matches)) { 00213 for ($j=0; $j<count($matches)-1; $j++) { 00214 if ($j != $columns->mastercol) { 00215 $courses[$courseid]->elements[substr(trim($matches[$j+1]), 1, -1)]->parent = substr(trim($matches[$columns->mastercol+1]), 1, -1); 00216 } 00217 } 00218 } 00219 } 00220 } 00221 if (isset($id->pre)) { 00222 $contents = $id->pre->get_content(); 00223 $rows = explode("\r\n", $contents); 00224 $columns = scorm_get_aicc_columns($rows[0], 'structure_element'); 00225 $regexp = scorm_forge_cols_regexp($columns->columns, '(.+),'); 00226 for ($i=1; $i<count($rows); $i++) { 00227 if (preg_match($regexp, $rows[$i], $matches)) { 00228 $courses[$courseid]->elements[$columns->mastercol+1]->prerequisites = substr(trim($matches[1-$columns->mastercol+1]), 1, -1); 00229 } 00230 } 00231 } 00232 if (isset($id->cmp)) { 00233 $contents = $id->cmp->get_content(); 00234 $rows = explode("\r\n", $contents); 00235 } 00236 } 00237 00238 $oldscoes = $DB->get_records('scorm_scoes', array('scorm'=>$scorm->id)); 00239 00240 $launch = 0; 00241 if (isset($courses)) { 00242 foreach ($courses as $course) { 00243 $sco = new stdClass(); 00244 $sco->identifier = $course->id; 00245 $sco->scorm = $scorm->id; 00246 $sco->organization = ''; 00247 $sco->title = $course->title; 00248 $sco->parent = '/'; 00249 $sco->launch = ''; 00250 $sco->scormtype = ''; 00251 00252 if ($ss = $DB->get_record('scorm_scoes', array('scorm'=>$scorm->id, 00253 'identifier'=>$sco->identifier))) { 00254 $id = $ss->id; 00255 $sco->id = $id; 00256 $DB->update_record('scorm_scoes',$sco); 00257 unset($oldscoes[$id]); 00258 } else { 00259 $id = $DB->insert_record('scorm_scoes', $sco); 00260 } 00261 00262 if ($launch == 0) { 00263 $launch = $id; 00264 } 00265 if (isset($course->elements)) { 00266 foreach ($course->elements as $element) { 00267 unset($sco); 00268 $sco->identifier = $element->system_id; 00269 $sco->scorm = $scorm->id; 00270 $sco->organization = $course->id; 00271 $sco->title = $element->title; 00272 00273 if (!isset($element->parent) || strtolower($element->parent) == 'root') { 00274 $sco->parent = '/'; 00275 } else { 00276 $sco->parent = $element->parent; 00277 } 00278 if (isset($element->file_name)) { 00279 $sco->launch = $element->file_name; 00280 $sco->scormtype = 'sco'; 00281 $sco->previous = 0; 00282 $sco->next = 0; 00283 $id = null; 00284 if ($oldscoid = scorm_array_search('identifier', $sco->identifier, $oldscoes)) { 00285 $sco->id = $oldscoid; 00286 $DB->update_record('scorm_scoes', $sco); 00287 $id = $oldscoid; 00288 $DB->delete_records('scorm_scoes_data', array('scoid'=>$oldscoid)); 00289 unset($oldscoes[$oldscoid]); 00290 } else { 00291 $id = $DB->insert_record('scorm_scoes', $sco); 00292 } 00293 if (!empty($id)) { 00294 $scodata = new stdClass(); 00295 $scodata->scoid = $id; 00296 if (isset($element->web_launch)) { 00297 $scodata->name = 'parameters'; 00298 $scodata->value = $element->web_launch; 00299 $dataid = $DB->insert_record('scorm_scoes_data', $scodata); 00300 } 00301 if (isset($element->prerequisites)) { 00302 $scodata->name = 'prerequisites'; 00303 $scodata->value = $element->prerequisites; 00304 $dataid = $DB->insert_record('scorm_scoes_data', $scodata); 00305 } 00306 if (isset($element->max_time_allowed)) { 00307 $scodata->name = 'max_time_allowed'; 00308 $scodata->value = $element->max_time_allowed; 00309 $dataid = $DB->insert_record('scorm_scoes_data', $scodata); 00310 } 00311 if (isset($element->time_limit_action)) { 00312 $scodata->name = 'time_limit_action'; 00313 $scodata->value = $element->time_limit_action; 00314 $dataid = $DB->insert_record('scorm_scoes_data', $scodata); 00315 } 00316 if (isset($element->mastery_score)) { 00317 $scodata->name = 'mastery_score'; 00318 $scodata->value = $element->mastery_score; 00319 $dataid = $DB->insert_record('scorm_scoes_data', $scodata); 00320 } 00321 if (isset($element->core_vendor)) { 00322 $scodata->name = 'datafromlms'; 00323 $scodata->value = preg_replace('/<cr>/i', "\r\n", $element->core_vendor); 00324 $dataid = $DB->insert_record('scorm_scoes_data', $scodata); 00325 } 00326 } 00327 if ($launch==0) { 00328 $launch = $id; 00329 } 00330 } 00331 } 00332 } 00333 } 00334 } 00335 if (!empty($oldscoes)) { 00336 foreach ($oldscoes as $oldsco) { 00337 $DB->delete_records('scorm_scoes', array('id'=>$oldsco->id)); 00338 $DB->delete_records('scorm_scoes_track', array('scoid'=>$oldsco->id)); 00339 } 00340 } 00341 00342 $scorm->version = 'AICC'; 00343 00344 $scorm->launch = $launch; 00345 00346 return true; 00347 } 00348 00355 function scorm_aicc_get_hacp_session($scormid) { 00356 global $USER, $DB, $SESSION; 00357 $cfg_scorm = get_config('scorm'); 00358 if (empty($cfg_scorm->allowaicchacp)) { 00359 return false; 00360 } 00361 $now = time(); 00362 00363 $hacpsession = $SESSION->scorm; 00364 $hacpsession->scormid = $scormid; 00365 $hacpsession->hacpsession = random_string(20); 00366 $hacpsession->userid = $USER->id; 00367 $hacpsession->timecreated = $now; 00368 $hacpsession->timemodified = $now; 00369 $DB->insert_record('scorm_aicc_session', $hacpsession); 00370 00371 return $hacpsession->hacpsession; 00372 } 00373 00381 function scorm_aicc_confirm_hacp_session($hacpsession) { 00382 global $DB; 00383 $cfg_scorm = get_config('scorm'); 00384 if (empty($cfg_scorm->allowaicchacp)) { 00385 return false; 00386 } 00387 $time = time()-($cfg_scorm->aicchacptimeout * 60); 00388 $sql = "hacpsession = ? AND timemodified > ?"; 00389 $hacpsession = $DB->get_record_select('scorm_aicc_session', $sql, array($hacpsession, $time)); 00390 if (!empty($hacpsession)) { //update timemodified as this is still an active session - resets the timeout. 00391 $hacpsession->timemodified = time(); 00392 $DB->update_record('scorm_aicc_session', $hacpsession); 00393 } 00394 return $hacpsession; 00395 } 00396 00404 function scorm_aicc_generate_simple_sco($scorm) { 00405 global $DB; 00406 // find the old one 00407 $scos = $DB->get_records('scorm_scoes', array('scorm'=>$scorm->id)); 00408 if (!empty($scos)) { 00409 $sco = array_shift($scos); 00410 } else { 00411 $sco = new object(); 00412 } 00413 // get rid of old ones 00414 foreach($scos as $oldsco) { 00415 $DB->delete_records('scorm_scoes', array('id'=>$oldsco->id)); 00416 $DB->delete_records('scorm_scoes_track', array('scoid'=>$oldsco->id)); 00417 } 00418 00419 $sco->identifier = 'A1'; 00420 $sco->scorm = $scorm->id; 00421 $sco->organization = ''; 00422 $sco->title = $scorm->name; 00423 $sco->parent = '/'; 00424 // add the HACP signal to the activity launcher 00425 if (preg_match('/\?/', $scorm->reference)) { 00426 $sco->launch = $scorm->reference.'&CMI=HACP'; 00427 } 00428 else { 00429 $sco->launch = $scorm->reference.'?CMI=HACP'; 00430 } 00431 $sco->scormtype = 'sco'; 00432 if (isset($sco->id)) { 00433 $DB->update_record('scorm_scoes', $sco); 00434 $id = $sco->id; 00435 } else { 00436 $id = $DB->insert_record('scorm_scoes', $sco); 00437 } 00438 return $id; 00439 }