]> git.mjollnir.org Git - moodle.git/commitdiff
Fixes for Bug 5749 and Bug 5750
authordanmarsden <danmarsden>
Sun, 23 Jul 2006 23:48:09 +0000 (23:48 +0000)
committerdanmarsden <danmarsden>
Sun, 23 Jul 2006 23:48:09 +0000 (23:48 +0000)
summary of bug 5749 and 5750
fixes for: function causes timeout when deleting temporary files for large scorm objects
scorm\validate.php calls function scorm_delete_files from scorm\lib.php - but lib.php not included in validate.php

Validation of Scorm objects broken - adds entry in modules database even when scorm object is not created.

mod/scorm/lib.php
mod/scorm/locallib.php
mod/scorm/validate.php

index f814162a85d1ec3907f686181e1adbe5fde2942f..514e58e96c530e2370a2727945f0a7d3e6d888cc 100755 (executable)
-<?php  // $Id$\r
-\r
-/// Library of functions and constants for module scorm\r
-\r
-define('GRADESCOES', '0');\r
-define('GRADEHIGHEST', '1');\r
-define('GRADEAVERAGE', '2');\r
-define('GRADESUM', '3');\r
-$SCORM_GRADE_METHOD = array (GRADESCOES => get_string('gradescoes', 'scorm'),\r
-                             GRADEHIGHEST => get_string('gradehighest', 'scorm'),\r
-                             GRADEAVERAGE => get_string('gradeaverage', 'scorm'),\r
-                             GRADESUM => get_string('gradesum', 'scorm'));\r
-\r
-define('VALUEHIGHEST', '0');\r
-define('VALUEAVERAGE', '1');\r
-define('VALUEFIRST', '2');\r
-define('VALUELAST', '3');\r
-$SCORM_WHAT_GRADE = array (VALUEHIGHEST => get_string('highestattempt', 'scorm'),\r
-                           VALUEAVERAGE => get_string('averageattempt', 'scorm'),\r
-                           VALUEFIRST => get_string('firstattempt', 'scorm'),\r
-                           VALUELAST => get_string('lastattempt', 'scorm'));\r
-\r
-$SCORM_POPUP_OPTIONS = array('resizable'=>1, \r
-                             'scrollbars'=>1, \r
-                             'directories'=>0, \r
-                             'location'=>0,\r
-                             'menubar'=>0, \r
-                             'toolbar'=>0, \r
-                             'status'=>0);\r
-$stdoptions = '';\r
-foreach ($SCORM_POPUP_OPTIONS as $popupopt => $value) {\r
-    $stdoptions .= $popupopt.'='.$value;\r
-    if ($popupopt != 'status') {\r
-        $stdoptions .= ',';\r
-    }\r
-}\r
-\r
-if (!isset($CFG->scorm_maxattempts)) {\r
-    set_config('scorm_maxattempts','6');\r
-}\r
-\r
-if (!isset($CFG->scorm_frameheight)) {\r
-    set_config('scorm_frameheight','500');\r
-}\r
-\r
-if (!isset($CFG->scorm_framewidth)) {\r
-    set_config('scorm_framewidth','100%');\r
-}\r
-\r
-/**\r
-* Given an object containing all the necessary data,\r
-* (defined by the form in mod.html) this function\r
-* will create a new instance and return the id number\r
-* of the new instance.\r
-*\r
-* @param mixed $scorm Form data\r
-* @return int\r
-*/\r
-function scorm_add_instance($scorm) {\r
-\r
-    global $CFG;\r
-    $scorm->timemodified = time();\r
-\r
-    $scorm = scorm_option2text($scorm);\r
-    $scorm->width = str_replace('%','',$scorm->width);\r
-    $scorm->height = str_replace('%','',$scorm->height);\r
-\r
-    //sanitize submitted values a bit\r
-    $scorm->width = clean_param($scorm->width, PARAM_INT);\r
-    $scorm->height = clean_param($scorm->height, PARAM_INT);\r
-\r
-    $id = insert_record('scorm', $scorm);\r
-\r
-    if (basename($scorm->reference) != 'imsmanifest.xml') {\r
-        // Rename temp scorm dir to scorm id\r
-        $scorm->dir = $CFG->dataroot.'/'.$scorm->course.'/moddata/scorm';\r
-        rename($scorm->dir.$scorm->datadir,$scorm->dir.'/'.$id);\r
-    }\r
-\r
-    // Parse scorm manifest\r
-    if ($scorm->launch == 0) {\r
-        require_once('locallib.php');\r
-        $scorm->id = $id;\r
-        $scorm->launch = scorm_parse($scorm);\r
-        set_field('scorm','launch',$scorm->launch,'id',$scorm->id);\r
-    }\r
-\r
-    return $id;\r
-}\r
-\r
-/**\r
-* Given an object containing all the necessary data,\r
-* (defined by the form in mod.html) this function\r
-* will update an existing instance with new data.\r
-*\r
-* @param mixed $scorm Form data\r
-* @return int\r
-*/\r
-function scorm_update_instance($scorm) {\r
-\r
-    global $CFG;\r
-\r
-    $scorm->timemodified = time();\r
-    $scorm->id = $scorm->instance;\r
-\r
-    $scorm = scorm_option2text($scorm);\r
-    $scorm->width = str_replace('%','',$scorm->width);\r
-    $scorm->height = str_replace('%','',$scorm->height);\r
-\r
-    // Check if scorm manifest needs to be reparsed\r
-    if ($scorm->launch == 0) {\r
-               //$f = "D:\\test.txt";\r
-               //@$ft = fopen($f,"a");\r
-               //fwrite($ft,"\n Xu ly trong update trong lib.php \n");\r
-               //fwrite($ft,"\n Lauch co gia tri \n".($scorm->launch));\r
-\r
-        // Delete old related records\r
-        delete_records('scorm_scoes','scorm',$scorm->id);\r
-        delete_records('scorm_scoes_track','scormid',$scorm->id);\r
-        delete_records('scorm_sequencing_controlmode','scormid',$scorm->id);\r
-        delete_records('scorm_sequencing_rolluprules','scormid',$scorm->id);\r
-        delete_records('scorm_sequencing_rolluprule','scormid',$scorm->id);\r
-        delete_records('scorm_sequencing_rollupruleconditions','scormid',$scorm->id);\r
-        delete_records('scorm_sequencing_rolluprulecondition','scormid',$scorm->id);                           \r
-        delete_records('scorm_sequencing_ruleconditions','scormid',$scorm->id);\r
-        delete_records('scorm_sequencing_rulecondition','scormid',$scorm->id);                         \r
-\r
-        \r
-        $scorm->dir = $CFG->dataroot.'/'.$scorm->course.'/moddata/scorm';\r
-        if (isset($scorm->datadir) && ($scorm->datadir != $scorm->id) && (basename($scorm->reference) != 'imsmanifest.xml')) {\r
-            scorm_delete_files($scorm->dir.'/'.$scorm->id);\r
-            rename($scorm->dir.$scorm->datadir,$scorm->dir.'/'.$scorm->id);\r
-        }\r
-        \r
-        require_once('locallib.php');\r
-        $scorm->launch = scorm_parse($scorm);\r
-    }\r
-\r
-    return update_record('scorm', $scorm);\r
-}\r
-\r
-/**\r
-* Given an ID of an instance of this module,\r
-* this function will permanently delete the instance\r
-* and any data that depends on it.\r
-*\r
-* @param int $id Scorm instance id\r
-* @return boolean\r
-*/\r
-function scorm_delete_instance($id) {\r
-\r
-    global $CFG;\r
-\r
-    if (! $scorm = get_record('scorm', 'id', $id)) {\r
-        return false;\r
-    }\r
-\r
-    $result = true;\r
-\r
-    // Delete any dependent files\r
-    scorm_delete_files($CFG->dataroot.'/'.$scorm->course.'/moddata/scorm/'.$scorm->id);\r
-\r
-    // Delete any dependent records\r
-    if (! delete_records('scorm_scoes_track', 'scormid', $scorm->id)) {\r
-        $result = false;\r
-    }\r
-    if (! delete_records('scorm_scoes', 'scorm', $scorm->id)) {\r
-        $result = false;\r
-    }\r
-    if (! delete_records('scorm', 'id', $scorm->id)) {\r
-        $result = false;\r
-    }\r
-    if (! delete_records('scorm_sequencing_controlmode', 'scormid', $scorm->id)) {\r
-        $result = false;\r
-    }\r
-    if (! delete_records('scorm_sequencing_rolluprules', 'scormid', $scorm->id)) {\r
-        $result = false;\r
-    }\r
-    if (! delete_records('scorm_sequencing_rolluprule', 'scormid', $scorm->id)) {\r
-        $result = false;\r
-    }\r
-    if (! delete_records('scorm_sequencing_rollupruleconditions', 'scormid', $scorm->id)) {\r
-        $result = false;\r
-    }\r
-    if (! delete_records('scorm_sequencing_rolluprulecondition', 'scormid', $scorm->id)) {\r
-        $result = false;\r
-    }\r
-    if (! delete_records('scorm_sequencing_rulecondition', 'scormid', $scorm->id)) {\r
-        $result = false;\r
-    }\r
-    if (! delete_records('scorm_sequencing_ruleconditions', 'scormid', $scorm->id)) {\r
-        $result = false;\r
-    }          \r
-    return $result;\r
-}\r
-\r
-/**\r
-* Return a small object with summary information about what a\r
-* user has done with a given particular instance of this module\r
-* Used for user activity reports.\r
-*\r
-* @param int $course Course id\r
-* @param int $user User id\r
-* @param int $mod  \r
-* @param int $scorm The scorm id\r
-* @return mixed\r
-*/\r
-function scorm_user_outline($course, $user, $mod, $scorm) { \r
-\r
-    $return = NULL;\r
-    $scores->values = 0;\r
-    $scores->sum = 0;\r
-    $scores->max = 0;\r
-    $scores->lastmodify = 0;\r
-    $scores->count = 0;\r
-    if ($scoes = get_records_select("scorm_scoes","scorm='$scorm->id' ORDER BY id")) {\r
-        require_once('locallib.php');\r
-        foreach ($scoes as $sco) {\r
-            if ($sco->launch!='') {\r
-               $scores->count++;\r
-               if ($userdata = scorm_get_tracks($sco->id, $user->id)) {\r
-                    if (!isset($scores->{$userdata->status})) {\r
-                        $scores->{$userdata->status} = 1;\r
-                    } else {    \r
-                        $scores->{$userdata->status}++;\r
-                    }\r
-                    if (!empty($userdata->score_raw)) {\r
-                        $scores->values++;\r
-                        $scores->sum += $userdata->score_raw;\r
-                        $scores->max = ($userdata->score_raw > $scores->max)?$userdata->score_raw:$scores->max;\r
-                    }\r
-                    if (isset($userdata->timemodified) && ($userdata->timemodified > $scores->lastmodify)) {\r
-                        $scores->lastmodify = $userdata->timemodified;\r
-                    }\r
-                }\r
-            }\r
-        }\r
-        switch ($scorm->grademethod) {\r
-            case GRADEHIGHEST:\r
-               if ($scores->values > 0) {\r
-                    $return->info = get_string('score','scorm').':&nbsp;'.$scores->max;\r
-                    $return->time = $scores->lastmodify;\r
-                }\r
-            break;\r
-            case GRADEAVERAGE:\r
-                if ($scores->values > 0) {\r
-                    $return->info = get_string('score','scorm').':&nbsp;'.$scores->sum/$scores->values;\r
-                    $return->time = $scores->lastmodify;\r
-                }\r
-            break;\r
-            case GRADESUM:\r
-                if ($scores->values > 0) {\r
-                    $return->info = get_string('score','scorm').':&nbsp;'.$scores->sum;\r
-                    $return->time = $scores->lastmodify;\r
-                }\r
-            break;\r
-            case GRADESCOES:\r
-                $return->info = '';\r
-                $scores->notattempted = $scores->count;\r
-                if (isset($scores->completed)) {\r
-                   $return->info .= get_string('completed','scorm').':&nbsp;'.$scores->completed.'<br />';\r
-                    $scores->notattempted -= $scores->completed;\r
-                }\r
-                if (isset($scores->passed)) {\r
-                   $return->info .= get_string('passed','scorm').':&nbsp;'.$scores->passed.'<br />';\r
-                    $scores->notattempted -= $scores->passed;\r
-                }\r
-                if (isset($scores->failed)) {\r
-                   $return->info .= get_string('failed','scorm').':&nbsp;'.$scores->failed.'<br />';\r
-                    $scores->notattempted -= $scores->failed;\r
-                }\r
-                if (isset($scores->incomplete)) {\r
-                   $return->info .= get_string('incomplete','scorm').':&nbsp;'.$scores->incomplete.'<br />';\r
-                    $scores->notattempted -= $scores->incomplete;\r
-                }\r
-                if (isset($scores->browsed)) {\r
-                   $return->info .= get_string('browsed','scorm').':&nbsp;'.$scores->browsed.'<br />';\r
-                    $scores->notattempted -= $scores->browsed;\r
-                }\r
-                $return->time = $scores->lastmodify;\r
-                if ($return->info == '') {\r
-                    $return = NULL;\r
-                } else {\r
-                   $return->info .= get_string('notattempted','scorm').':&nbsp;'.$scores->notattempted.'<br />';\r
-                }\r
-            break;\r
-        }\r
-    }\r
-    return $return;\r
-}\r
-\r
-/**\r
-* Print a detailed representation of what a user has done with\r
-* a given particular instance of this module, for user activity reports.\r
-*\r
-* @param int $course Course id\r
-* @param int $user User id\r
-* @param int $mod  \r
-* @param int $scorm The scorm id\r
-* @return boolean\r
-*/\r
-function scorm_user_complete($course, $user, $mod, $scorm) {\r
-    global $CFG;\r
-\r
-    $liststyle = 'structlist';\r
-    $scormpixdir = $CFG->modpixpath.'/scorm/pix';\r
-    $now = time();\r
-    $firstmodify = $now;\r
-    $lastmodify = 0;\r
-    $sometoreport = false;\r
-    $report = '';\r
-    \r
-    if ($orgs = get_records_select('scorm_scoes',"scorm='$scorm->id' AND organization='' AND launch=''",'id','id,identifier,title')) {\r
-        if (count($orgs) <= 1) {\r
-            unset($orgs);\r
-            $orgs[]->identifier = '';\r
-        }\r
-        $report .= '<div class="mod-scorm">'."\n";\r
-        foreach ($orgs as $org) {\r
-            $organizationsql = '';\r
-            $currentorg = '';\r
-            if (!empty($org->identifier)) {\r
-                $report .= '<div class="orgtitle">'.$org->title.'</div>';\r
-                $currentorg = $org->identifier;\r
-                $organizationsql = "AND organization='$currentorg'";\r
-            }\r
-            $report .= "<ul id='0' class='$liststyle'>";\r
-            if ($scoes = get_records_select('scorm_scoes',"scorm='$scorm->id' $organizationsql order by id ASC")){\r
-                $level=0;\r
-                $sublist=1;\r
-                $parents[$level]='/';\r
-                foreach ($scoes as $sco) {\r
-                    if ($parents[$level]!=$sco->parent) {\r
-                        if ($level>0 && $parents[$level-1]==$sco->parent) {\r
-                            $report .= "\t\t</ul></li>\n";\r
-                            $level--;\r
-                        } else {\r
-                            $i = $level;\r
-                            $closelist = '';\r
-                            while (($i > 0) && ($parents[$level] != $sco->parent)) {\r
-                                $closelist .= "\t\t</ul></li>\n";\r
-                                $i--;\r
-                            }\r
-                            if (($i == 0) && ($sco->parent != $currentorg)) {\r
-                                $report .= "\t\t<li><ul id='$sublist' class='$liststyle'>\n";\r
-                                $level++;\r
-                            } else {\r
-                                $report .= $closelist;\r
-                                $level = $i;\r
-                            }\r
-                            $parents[$level]=$sco->parent;\r
-                        }\r
-                    }\r
-                    $report .= "\t\t<li>";\r
-                    $nextsco = next($scoes);\r
-                    if (($nextsco !== false) && ($sco->parent != $nextsco->parent) && (($level==0) || (($level>0) && ($nextsco->parent == $sco->identifier)))) {\r
-                        $sublist++;\r
-                    } else {\r
-                        $report .= '<img src="'.$scormpixdir.'/spacer.gif" />';\r
-                    }\r
-\r
-                    if ($sco->launch) {\r
-                        require_once('locallib.php');\r
-                        $score = '';\r
-                        $totaltime = '';\r
-                        if ($usertrack=scorm_get_tracks($sco->id,$user->id)) {\r
-                            if ($usertrack->status == '') {\r
-                                $usertrack->status = 'notattempted';\r
-                            }\r
-                            $strstatus = get_string($usertrack->status,'scorm');\r
-                            $report .= "<img src='".$scormpixdir.'/'.$usertrack->status.".gif' alt='$strstatus' title='$strstatus' />";\r
-                            if ($usertrack->timemodified != 0) {\r
-                                if ($usertrack->timemodified > $lastmodify) {\r
-                                    $lastmodify = $usertrack->timemodified;\r
-                                }\r
-                                if ($usertrack->timemodified < $firstmodify) {\r
-                                    $firstmodify = $usertrack->timemodified;\r
-                                }\r
-                            }\r
-                        } else {\r
-                            if ($sco->scormtype == 'sco') {\r
-                                $report .= '<img src="'.$scormpixdir.'/'.'notattempted.gif" alt="'.get_string('notattempted','scorm').'" title="'.get_string('notattempted','scorm').'" />';\r
-                            } else {\r
-                                $report .= '<img src="'.$scormpixdir.'/'.'asset.gif" alt="'.get_string('asset','scorm').'" title="'.get_string('asset','scorm').'" />';\r
-                            }\r
-                        }\r
-                        $report .= "&nbsp;$sco->title $score$totaltime</li>\n";\r
-                        if ($usertrack !== false) {\r
-                            $sometoreport = true;\r
-                            $report .= "\t\t\t<li><ul class='$liststyle'>\n";\r
-                            foreach($usertrack as $element => $value) {\r
-                                if (substr($element,0,3) == 'cmi') {\r
-                                    $report .= '<li>'.$element.' => '.$value.'</li>';\r
-                                }\r
-                            }\r
-                            $report .= "\t\t\t</ul></li>\n";\r
-                        } \r
-                    } else {\r
-                        $report .= "&nbsp;$sco->title</li>\n";\r
-                    }\r
-                }\r
-                for ($i=0;$i<$level;$i++) {\r
-                    $report .= "\t\t</ul></li>\n";\r
-                }\r
-            }\r
-            $report .= "\t</ul><br />\n";\r
-        }\r
-        $report .= "</div>\n";\r
-    }\r
-    if ($sometoreport) {\r
-        if ($firstmodify < $now) {\r
-            $timeago = format_time($now - $firstmodify);\r
-            echo get_string('firstaccess','scorm').': '.userdate($firstmodify).' ('.$timeago.")<br />\n";\r
-        }\r
-        if ($lastmodify > 0) {\r
-            $timeago = format_time($now - $lastmodify);\r
-            echo get_string('lastaccess','scorm').': '.userdate($lastmodify).' ('.$timeago.")<br />\n";\r
-        }\r
-        echo get_string('report','scorm').":<br />\n";\r
-        echo $report;\r
-    } else {\r
-       print_string('noactivity','scorm');\r
-    }\r
-\r
-    return true;\r
-}\r
-\r
-/**\r
-* Given a list of logs, assumed to be those since the last login\r
-* this function prints a short list of changes related to this module\r
-* If isteacher is true then perhaps additional information is printed.\r
-* This function is called from course/lib.php: print_recent_activity()\r
-*\r
-* @param reference $logs Logs reference\r
-* @param boolean $isteacher\r
-* @return boolean\r
-*/\r
-function scorm_print_recent_activity(&$logs, $isteacher=false) {\r
-    return false;  // True if anything was printed, otherwise false\r
-}\r
-\r
-/**\r
-* Function to be run periodically according to the moodle cron\r
-* This function searches for things that need to be done, such\r
-* as sending out mail, toggling flags etc ...\r
-*\r
-* @return boolean\r
-*/\r
-function scorm_cron () {\r
-\r
-    global $CFG;\r
-\r
-    return true;\r
-}\r
-\r
-/**\r
-* Given a scorm id return all the grades of that activity\r
-*\r
-* @param int $scormid Scorm instance id\r
-* @return mixed\r
-*/\r
-function scorm_grades($scormid) {\r
-\r
-    global $CFG;\r
-\r
-    if (!$scorm = get_record('scorm', 'id', $scormid)) {\r
-        return NULL;\r
-    }\r
-    if (!$scoes = get_records('scorm_scoes','scorm',$scormid)) {\r
-        return NULL;\r
-    }\r
-\r
-    if ($scorm->grademethod == VALUESCOES) {\r
-        if (!$return->maxgrade = count_records_select('scorm_scoes',"scorm='$scormid' AND launch<>''")) {\r
-            return NULL;\r
-        }\r
-    } else {\r
-        $return->maxgrade = $scorm->maxgrade;\r
-    }\r
-\r
-    $return->grades = NULL;\r
-    if ($scousers=get_records_select('scorm_scoes_track', "scormid='$scormid' GROUP BY userid", "", "userid,null")) {\r
-        require_once('locallib.php');\r
-        foreach ($scousers as $scouser) {\r
-            $return->grades[$scouser->userid] = scorm_grade_user($scoes, $scouser->userid, $scorm->grademethod);\r
-        }\r
-    }\r
-    return $return;\r
-}\r
-\r
-function scorm_get_view_actions() {\r
-    return array('pre-view','view','view all','report');\r
-}\r
-\r
-function scorm_get_post_actions() {\r
-    return array();\r
-}\r
-\r
-/**\r
-* This function will permanently delete the given\r
-* directory and all files and subdirectories.\r
-*\r
-* @param string $directory The directory to remove\r
-* @return boolean\r
-*/\r
-function scorm_delete_files($directory) {\r
-    if (is_dir($directory)) {\r
-        $files=scorm_scandir($directory);\r
-        foreach($files as $file) {\r
-            if (($file != '.') && ($file != '..')) {\r
-                if (!is_dir($directory.'/'.$file)) {\r
-                    unlink($directory.'/'.$file);\r
-                } else {\r
-                    scorm_delete_files($directory.'/'.$file);\r
-                }\r
-            }\r
-        }\r
-        rmdir($directory);\r
-        return true;\r
-    }\r
-    return false;\r
-}\r
-\r
-/**\r
-* Given a diretory path returns the file list\r
-*\r
-* @param string $directory\r
-* @return array\r
-*/\r
-function scorm_scandir($directory) {\r
-    if (version_compare(phpversion(),'5.0.0','>=')) {\r
-        return scandir($directory);\r
-    } else {\r
-        $files = array();\r
-        if ($dh = opendir($directory)) {\r
-            while (($file = readdir($dh)) !== false) {\r
-               $files[] = $file;\r
-            }\r
-            closedir($dh);\r
-        }\r
-        return $files;\r
-    }\r
-}\r
-\r
-\r
-function scorm_option2text($scorm) {\r
-    global $SCORM_POPUP_OPTIONS;\r
-\r
-    if (isset($scorm->popup)) {\r
-        if ($scorm->popup) {\r
-            $optionlist = array();\r
-            foreach ($SCORM_POPUP_OPTIONS as $name => $option) {\r
-                if (isset($scorm->$name)) {\r
-                    $optionlist[] = $name.'='.$scorm->$name;\r
-                } else {\r
-                    $optionlist[] = $name.'=0';\r
-                }\r
-            }       \r
-            $scorm->options = implode(',', $optionlist);\r
-        } else {\r
-            $scorm->options = '';\r
-        } \r
-    } else {\r
-        $scorm->popup = 0;\r
-        $scorm->options = '';\r
-    }\r
-    return $scorm;\r
-}\r
-\r
+<?php  // $Id$
+
+/// Library of functions and constants for module scorm
+
+define('GRADESCOES', '0');
+define('GRADEHIGHEST', '1');
+define('GRADEAVERAGE', '2');
+define('GRADESUM', '3');
+$SCORM_GRADE_METHOD = array (GRADESCOES => get_string('gradescoes', 'scorm'),
+                             GRADEHIGHEST => get_string('gradehighest', 'scorm'),
+                             GRADEAVERAGE => get_string('gradeaverage', 'scorm'),
+                             GRADESUM => get_string('gradesum', 'scorm'));
+
+define('VALUEHIGHEST', '0');
+define('VALUEAVERAGE', '1');
+define('VALUEFIRST', '2');
+define('VALUELAST', '3');
+$SCORM_WHAT_GRADE = array (VALUEHIGHEST => get_string('highestattempt', 'scorm'),
+                           VALUEAVERAGE => get_string('averageattempt', 'scorm'),
+                           VALUEFIRST => get_string('firstattempt', 'scorm'),
+                           VALUELAST => get_string('lastattempt', 'scorm'));
+
+$SCORM_POPUP_OPTIONS = array('resizable'=>1, 
+                             'scrollbars'=>1, 
+                             'directories'=>0, 
+                             'location'=>0,
+                             'menubar'=>0, 
+                             'toolbar'=>0, 
+                             'status'=>0);
+$stdoptions = '';
+foreach ($SCORM_POPUP_OPTIONS as $popupopt => $value) {
+    $stdoptions .= $popupopt.'='.$value;
+    if ($popupopt != 'status') {
+        $stdoptions .= ',';
+    }
+}
+
+if (!isset($CFG->scorm_maxattempts)) {
+    set_config('scorm_maxattempts','6');
+}
+
+if (!isset($CFG->scorm_frameheight)) {
+    set_config('scorm_frameheight','500');
+}
+
+if (!isset($CFG->scorm_framewidth)) {
+    set_config('scorm_framewidth','100%');
+}
+
+/**
+* Given an object containing all the necessary data,
+* (defined by the form in mod.html) this function
+* will create a new instance and return the id number
+* of the new instance.
+*
+* @param mixed $scorm Form data
+* @return int
+*/
+function scorm_add_instance($scorm) {
+    if(empty($scorm->datadir)) { //check to make sure scorm object is valid BEFORE entering it in the database.
+        error(get_string('nomanifest', 'scorm'));
+    } else {
+        global $CFG;
+        $scorm->timemodified = time();
+
+        $scorm = scorm_option2text($scorm);
+        $scorm->width = str_replace('%','',$scorm->width);
+        $scorm->height = str_replace('%','',$scorm->height);
+
+        //sanitize submitted values a bit
+        $scorm->width = clean_param($scorm->width, PARAM_INT);
+        $scorm->height = clean_param($scorm->height, PARAM_INT);
+
+        $id = insert_record('scorm', $scorm);
+
+        if (basename($scorm->reference) != 'imsmanifest.xml') {
+            // Rename temp scorm dir to scorm id
+            $scorm->dir = $CFG->dataroot.'/'.$scorm->course.'/moddata/scorm';
+            rename($scorm->dir.$scorm->datadir,$scorm->dir.'/'.$id);
+        }
+
+        // Parse scorm manifest
+        if ($scorm->launch == 0) {
+            require_once('locallib.php');
+            $scorm->id = $id;
+            $scorm->launch = scorm_parse($scorm);
+            set_field('scorm','launch',$scorm->launch,'id',$scorm->id);
+        }
+
+        return $id;
+    }
+}
+
+/**
+* Given an object containing all the necessary data,
+* (defined by the form in mod.html) this function
+* will update an existing instance with new data.
+*
+* @param mixed $scorm Form data
+* @return int
+*/
+function scorm_update_instance($scorm) {
+
+    global $CFG;
+
+    $scorm->timemodified = time();
+    $scorm->id = $scorm->instance;
+
+    $scorm = scorm_option2text($scorm);
+    $scorm->width = str_replace('%','',$scorm->width);
+    $scorm->height = str_replace('%','',$scorm->height);
+
+    // Check if scorm manifest needs to be reparsed
+    if ($scorm->launch == 0) {
+               //$f = "D:\\test.txt";
+               //@$ft = fopen($f,"a");
+               //fwrite($ft,"\n Xu ly trong update trong lib.php \n");
+               //fwrite($ft,"\n Lauch co gia tri \n".($scorm->launch));
+
+        // Delete old related records
+        delete_records('scorm_scoes','scorm',$scorm->id);
+        delete_records('scorm_scoes_track','scormid',$scorm->id);
+        delete_records('scorm_sequencing_controlmode','scormid',$scorm->id);
+        delete_records('scorm_sequencing_rolluprules','scormid',$scorm->id);
+        delete_records('scorm_sequencing_rolluprule','scormid',$scorm->id);
+        delete_records('scorm_sequencing_rollupruleconditions','scormid',$scorm->id);
+        delete_records('scorm_sequencing_rolluprulecondition','scormid',$scorm->id);                           
+        delete_records('scorm_sequencing_ruleconditions','scormid',$scorm->id);
+        delete_records('scorm_sequencing_rulecondition','scormid',$scorm->id);                         
+
+        
+        $scorm->dir = $CFG->dataroot.'/'.$scorm->course.'/moddata/scorm';
+        if (isset($scorm->datadir) && ($scorm->datadir != $scorm->id) && (basename($scorm->reference) != 'imsmanifest.xml')) {
+            scorm_delete_files($scorm->dir.'/'.$scorm->id);
+            rename($scorm->dir.$scorm->datadir,$scorm->dir.'/'.$scorm->id);
+        }
+        
+        require_once('locallib.php');
+        $scorm->launch = scorm_parse($scorm);
+    }
+
+    return update_record('scorm', $scorm);
+}
+
+/**
+* Given an ID of an instance of this module,
+* this function will permanently delete the instance
+* and any data that depends on it.
+*
+* @param int $id Scorm instance id
+* @return boolean
+*/
+function scorm_delete_instance($id) {
+
+    global $CFG;
+
+    if (! $scorm = get_record('scorm', 'id', $id)) {
+        return false;
+    }
+
+    $result = true;
+
+    // Delete any dependent files
+    scorm_delete_files($CFG->dataroot.'/'.$scorm->course.'/moddata/scorm/'.$scorm->id);
+
+    // Delete any dependent records
+    if (! delete_records('scorm_scoes_track', 'scormid', $scorm->id)) {
+        $result = false;
+    }
+    if (! delete_records('scorm_scoes', 'scorm', $scorm->id)) {
+        $result = false;
+    }
+    if (! delete_records('scorm', 'id', $scorm->id)) {
+        $result = false;
+    }
+    if (! delete_records('scorm_sequencing_controlmode', 'scormid', $scorm->id)) {
+        $result = false;
+    }
+    if (! delete_records('scorm_sequencing_rolluprules', 'scormid', $scorm->id)) {
+        $result = false;
+    }
+    if (! delete_records('scorm_sequencing_rolluprule', 'scormid', $scorm->id)) {
+        $result = false;
+    }
+    if (! delete_records('scorm_sequencing_rollupruleconditions', 'scormid', $scorm->id)) {
+        $result = false;
+    }
+    if (! delete_records('scorm_sequencing_rolluprulecondition', 'scormid', $scorm->id)) {
+        $result = false;
+    }
+    if (! delete_records('scorm_sequencing_rulecondition', 'scormid', $scorm->id)) {
+        $result = false;
+    }
+    if (! delete_records('scorm_sequencing_ruleconditions', 'scormid', $scorm->id)) {
+        $result = false;
+    }          
+    return $result;
+}
+
+/**
+* Return a small object with summary information about what a
+* user has done with a given particular instance of this module
+* Used for user activity reports.
+*
+* @param int $course Course id
+* @param int $user User id
+* @param int $mod  
+* @param int $scorm The scorm id
+* @return mixed
+*/
+function scorm_user_outline($course, $user, $mod, $scorm) { 
+
+    $return = NULL;
+    $scores->values = 0;
+    $scores->sum = 0;
+    $scores->max = 0;
+    $scores->lastmodify = 0;
+    $scores->count = 0;
+    if ($scoes = get_records_select("scorm_scoes","scorm='$scorm->id' ORDER BY id")) {
+        require_once('locallib.php');
+        foreach ($scoes as $sco) {
+            if ($sco->launch!='') {
+               $scores->count++;
+               if ($userdata = scorm_get_tracks($sco->id, $user->id)) {
+                    if (!isset($scores->{$userdata->status})) {
+                        $scores->{$userdata->status} = 1;
+                    } else {    
+                        $scores->{$userdata->status}++;
+                    }
+                    if (!empty($userdata->score_raw)) {
+                        $scores->values++;
+                        $scores->sum += $userdata->score_raw;
+                        $scores->max = ($userdata->score_raw > $scores->max)?$userdata->score_raw:$scores->max;
+                    }
+                    if (isset($userdata->timemodified) && ($userdata->timemodified > $scores->lastmodify)) {
+                        $scores->lastmodify = $userdata->timemodified;
+                    }
+                }
+            }
+        }
+        switch ($scorm->grademethod) {
+            case GRADEHIGHEST:
+               if ($scores->values > 0) {
+                    $return->info = get_string('score','scorm').':&nbsp;'.$scores->max;
+                    $return->time = $scores->lastmodify;
+                }
+            break;
+            case GRADEAVERAGE:
+                if ($scores->values > 0) {
+                    $return->info = get_string('score','scorm').':&nbsp;'.$scores->sum/$scores->values;
+                    $return->time = $scores->lastmodify;
+                }
+            break;
+            case GRADESUM:
+                if ($scores->values > 0) {
+                    $return->info = get_string('score','scorm').':&nbsp;'.$scores->sum;
+                    $return->time = $scores->lastmodify;
+                }
+            break;
+            case GRADESCOES:
+                $return->info = '';
+                $scores->notattempted = $scores->count;
+                if (isset($scores->completed)) {
+                   $return->info .= get_string('completed','scorm').':&nbsp;'.$scores->completed.'<br />';
+                    $scores->notattempted -= $scores->completed;
+                }
+                if (isset($scores->passed)) {
+                   $return->info .= get_string('passed','scorm').':&nbsp;'.$scores->passed.'<br />';
+                    $scores->notattempted -= $scores->passed;
+                }
+                if (isset($scores->failed)) {
+                   $return->info .= get_string('failed','scorm').':&nbsp;'.$scores->failed.'<br />';
+                    $scores->notattempted -= $scores->failed;
+                }
+                if (isset($scores->incomplete)) {
+                   $return->info .= get_string('incomplete','scorm').':&nbsp;'.$scores->incomplete.'<br />';
+                    $scores->notattempted -= $scores->incomplete;
+                }
+                if (isset($scores->browsed)) {
+                   $return->info .= get_string('browsed','scorm').':&nbsp;'.$scores->browsed.'<br />';
+                    $scores->notattempted -= $scores->browsed;
+                }
+                $return->time = $scores->lastmodify;
+                if ($return->info == '') {
+                    $return = NULL;
+                } else {
+                   $return->info .= get_string('notattempted','scorm').':&nbsp;'.$scores->notattempted.'<br />';
+                }
+            break;
+        }
+    }
+    return $return;
+}
+
+/**
+* Print a detailed representation of what a user has done with
+* a given particular instance of this module, for user activity reports.
+*
+* @param int $course Course id
+* @param int $user User id
+* @param int $mod  
+* @param int $scorm The scorm id
+* @return boolean
+*/
+function scorm_user_complete($course, $user, $mod, $scorm) {
+    global $CFG;
+
+    $liststyle = 'structlist';
+    $scormpixdir = $CFG->modpixpath.'/scorm/pix';
+    $now = time();
+    $firstmodify = $now;
+    $lastmodify = 0;
+    $sometoreport = false;
+    $report = '';
+    
+    if ($orgs = get_records_select('scorm_scoes',"scorm='$scorm->id' AND organization='' AND launch=''",'id','id,identifier,title')) {
+        if (count($orgs) <= 1) {
+            unset($orgs);
+            $orgs[]->identifier = '';
+        }
+        $report .= '<div class="mod-scorm">'."\n";
+        foreach ($orgs as $org) {
+            $organizationsql = '';
+            $currentorg = '';
+            if (!empty($org->identifier)) {
+                $report .= '<div class="orgtitle">'.$org->title.'</div>';
+                $currentorg = $org->identifier;
+                $organizationsql = "AND organization='$currentorg'";
+            }
+            $report .= "<ul id='0' class='$liststyle'>";
+            if ($scoes = get_records_select('scorm_scoes',"scorm='$scorm->id' $organizationsql order by id ASC")){
+                $level=0;
+                $sublist=1;
+                $parents[$level]='/';
+                foreach ($scoes as $sco) {
+                    if ($parents[$level]!=$sco->parent) {
+                        if ($level>0 && $parents[$level-1]==$sco->parent) {
+                            $report .= "\t\t</ul></li>\n";
+                            $level--;
+                        } else {
+                            $i = $level;
+                            $closelist = '';
+                            while (($i > 0) && ($parents[$level] != $sco->parent)) {
+                                $closelist .= "\t\t</ul></li>\n";
+                                $i--;
+                            }
+                            if (($i == 0) && ($sco->parent != $currentorg)) {
+                                $report .= "\t\t<li><ul id='$sublist' class='$liststyle'>\n";
+                                $level++;
+                            } else {
+                                $report .= $closelist;
+                                $level = $i;
+                            }
+                            $parents[$level]=$sco->parent;
+                        }
+                    }
+                    $report .= "\t\t<li>";
+                    $nextsco = next($scoes);
+                    if (($nextsco !== false) && ($sco->parent != $nextsco->parent) && (($level==0) || (($level>0) && ($nextsco->parent == $sco->identifier)))) {
+                        $sublist++;
+                    } else {
+                        $report .= '<img src="'.$scormpixdir.'/spacer.gif" />';
+                    }
+
+                    if ($sco->launch) {
+                        require_once('locallib.php');
+                        $score = '';
+                        $totaltime = '';
+                        if ($usertrack=scorm_get_tracks($sco->id,$user->id)) {
+                            if ($usertrack->status == '') {
+                                $usertrack->status = 'notattempted';
+                            }
+                            $strstatus = get_string($usertrack->status,'scorm');
+                            $report .= "<img src='".$scormpixdir.'/'.$usertrack->status.".gif' alt='$strstatus' title='$strstatus' />";
+                            if ($usertrack->timemodified != 0) {
+                                if ($usertrack->timemodified > $lastmodify) {
+                                    $lastmodify = $usertrack->timemodified;
+                                }
+                                if ($usertrack->timemodified < $firstmodify) {
+                                    $firstmodify = $usertrack->timemodified;
+                                }
+                            }
+                        } else {
+                            if ($sco->scormtype == 'sco') {
+                                $report .= '<img src="'.$scormpixdir.'/'.'notattempted.gif" alt="'.get_string('notattempted','scorm').'" title="'.get_string('notattempted','scorm').'" />';
+                            } else {
+                                $report .= '<img src="'.$scormpixdir.'/'.'asset.gif" alt="'.get_string('asset','scorm').'" title="'.get_string('asset','scorm').'" />';
+                            }
+                        }
+                        $report .= "&nbsp;$sco->title $score$totaltime</li>\n";
+                        if ($usertrack !== false) {
+                            $sometoreport = true;
+                            $report .= "\t\t\t<li><ul class='$liststyle'>\n";
+                            foreach($usertrack as $element => $value) {
+                                if (substr($element,0,3) == 'cmi') {
+                                    $report .= '<li>'.$element.' => '.$value.'</li>';
+                                }
+                            }
+                            $report .= "\t\t\t</ul></li>\n";
+                        } 
+                    } else {
+                        $report .= "&nbsp;$sco->title</li>\n";
+                    }
+                }
+                for ($i=0;$i<$level;$i++) {
+                    $report .= "\t\t</ul></li>\n";
+                }
+            }
+            $report .= "\t</ul><br />\n";
+        }
+        $report .= "</div>\n";
+    }
+    if ($sometoreport) {
+        if ($firstmodify < $now) {
+            $timeago = format_time($now - $firstmodify);
+            echo get_string('firstaccess','scorm').': '.userdate($firstmodify).' ('.$timeago.")<br />\n";
+        }
+        if ($lastmodify > 0) {
+            $timeago = format_time($now - $lastmodify);
+            echo get_string('lastaccess','scorm').': '.userdate($lastmodify).' ('.$timeago.")<br />\n";
+        }
+        echo get_string('report','scorm').":<br />\n";
+        echo $report;
+    } else {
+       print_string('noactivity','scorm');
+    }
+
+    return true;
+}
+
+/**
+* Given a list of logs, assumed to be those since the last login
+* this function prints a short list of changes related to this module
+* If isteacher is true then perhaps additional information is printed.
+* This function is called from course/lib.php: print_recent_activity()
+*
+* @param reference $logs Logs reference
+* @param boolean $isteacher
+* @return boolean
+*/
+function scorm_print_recent_activity(&$logs, $isteacher=false) {
+    return false;  // True if anything was printed, otherwise false
+}
+
+/**
+* Function to be run periodically according to the moodle cron
+* This function searches for things that need to be done, such
+* as sending out mail, toggling flags etc ...
+*
+* @return boolean
+*/
+function scorm_cron () {
+
+    global $CFG;
+
+    return true;
+}
+
+/**
+* Given a scorm id return all the grades of that activity
+*
+* @param int $scormid Scorm instance id
+* @return mixed
+*/
+function scorm_grades($scormid) {
+
+    global $CFG;
+
+    if (!$scorm = get_record('scorm', 'id', $scormid)) {
+        return NULL;
+    }
+    if (!$scoes = get_records('scorm_scoes','scorm',$scormid)) {
+        return NULL;
+    }
+
+    if ($scorm->grademethod == VALUESCOES) {
+        if (!$return->maxgrade = count_records_select('scorm_scoes',"scorm='$scormid' AND launch<>''")) {
+            return NULL;
+        }
+    } else {
+        $return->maxgrade = $scorm->maxgrade;
+    }
+
+    $return->grades = NULL;
+    if ($scousers=get_records_select('scorm_scoes_track', "scormid='$scormid' GROUP BY userid", "", "userid,null")) {
+        require_once('locallib.php');
+        foreach ($scousers as $scouser) {
+            $return->grades[$scouser->userid] = scorm_grade_user($scoes, $scouser->userid, $scorm->grademethod);
+        }
+    }
+    return $return;
+}
+
+function scorm_get_view_actions() {
+    return array('pre-view','view','view all','report');
+}
+
+function scorm_get_post_actions() {
+    return array();
+}
+
+/**
+* This function will permanently delete the given
+* directory and all files and subdirectories.
+*
+* @param string $directory The directory to remove
+* @return boolean
+*/
+function scorm_delete_files($directory) {
+    if (is_dir($directory)) {
+        $files=scorm_scandir($directory);
+        foreach($files as $file) {
+            if (($file != '.') && ($file != '..')) {
+                if (!is_dir($directory.'/'.$file)) {
+                    unlink($directory.'/'.$file);
+                } else {
+                    scorm_delete_files($directory.'/'.$file);
+                }
+            }
+         set_time_limit(5);
+        }
+        rmdir($directory);
+        return true;
+    }
+    return false;
+}
+
+/**
+* Given a diretory path returns the file list
+*
+* @param string $directory
+* @return array
+*/
+function scorm_scandir($directory) {
+    if (version_compare(phpversion(),'5.0.0','>=')) {
+        return scandir($directory);
+    } else {
+        $files = array();
+        if ($dh = opendir($directory)) {
+            while (($file = readdir($dh)) !== false) {
+               $files[] = $file;
+            }
+            closedir($dh);
+        }
+        return $files;
+    }
+}
+
+
+function scorm_option2text($scorm) {
+    global $SCORM_POPUP_OPTIONS;
+
+    if (isset($scorm->popup)) {
+        if ($scorm->popup) {
+            $optionlist = array();
+            foreach ($SCORM_POPUP_OPTIONS as $name => $option) {
+                if (isset($scorm->$name)) {
+                    $optionlist[] = $name.'='.$scorm->$name;
+                } else {
+                    $optionlist[] = $name.'=0';
+                }
+            }       
+            $scorm->options = implode(',', $optionlist);
+        } else {
+            $scorm->options = '';
+        } 
+    } else {
+        $scorm->popup = 0;
+        $scorm->options = '';
+    }
+    return $scorm;
+}
+
 ?>
\ No newline at end of file
index 0f9617ace92830a46aa6b595e37f48ee779e93ed..980ca004689cb2a0eef24a72b1089780465f23ec 100755 (executable)
-\r
-<?php  // $Id$\r
-define("VALUESCOES",0);\r
-define("VALUEHIGHEST",1);\r
-define("VALUEAVERAGE",2);\r
-define("VALUESUM",3);\r
-\r
-/// Local Library of functions and constants for module scorm\r
-\r
-/**\r
-* Create a new temporary subdirectory with a random name in the given path\r
-*\r
-* @param string $strpath The scorm data directory\r
-* @return string/boolean\r
-*/\r
-function scorm_datadir($strPath)\r
-{\r
-    global $CFG;\r
-\r
-    if (is_dir($strPath)) {\r
-        do {\r
-            // Create a random string of 8 chars\r
-            $randstring = NULL;\r
-            $lchar = '';\r
-            $len = 8;\r
-            for ($i=0; $i<$len; $i++) {\r
-                $char = chr(rand(48,122));\r
-                while (!ereg('[a-zA-Z0-9]', $char)){\r
-                    if ($char == $lchar) continue;\r
-                        $char = chr(rand(48,90));\r
-                    }\r
-                    $randstring .= $char;\r
-                    $lchar = $char;\r
-            } \r
-            $datadir='/'.$randstring;\r
-        } while (file_exists($strPath.$datadir));\r
-        mkdir($strPath.$datadir, $CFG->directorypermissions);\r
-        @chmod($strPath.$datadir, $CFG->directorypermissions);  // Just in case mkdir didn't do it\r
-        return $strPath.$datadir;\r
-    } else {\r
-        return false;\r
-    }\r
-}\r
-\r
-/**\r
-* Given a package directory, this function will check if the package is valid\r
-*\r
-* @param string $packagedir The package directory\r
-* @return mixed\r
-*/\r
-function scorm_validate($packagedir) {\r
-\r
-    ////$f = "D:\\test.txt";\r
-    ////@$ft = fopen($f,"a");\r
-    ////fwrite($ft,"\n Xu ly trong ham scorm_validate \n");    \r
-\r
-\r
-    $validation = new stdClass();\r
-    if (is_file($packagedir.'/imsmanifest.xml')) {\r
-        $validation->result = 'found';\r
-        $validation->pkgtype = 'SCORM';\r
-    } else {\r
-        if ($handle = opendir($packagedir)) {\r
-            while (($file = readdir($handle)) !== false) {\r
-                $ext = substr($file,strrpos($file,'.'));\r
-                if (strtolower($ext) == '.cst') {\r
-                    $validation->result = 'found';\r
-                    $validation->pkgtype = 'AICC';\r
-                    break;\r
-                }\r
-            }\r
-            closedir($handle);\r
-        }\r
-        if (!isset($validation)) {\r
-            $validation->result = 'nomanifest';\r
-            $validation->pkgtype = 'SCORM';\r
-        }\r
-    }\r
-    return $validation;\r
-}\r
-\r
-function scorm_get_user_data($userid) {\r
-/// Gets user info required to display the table of scorm results\r
-/// for report.php\r
-\r
-    return get_record('user','id',$userid,'','','','','firstname, lastname, picture');\r
-}\r
-\r
-function scorm_string_wrap($stringa, $len=15) {\r
-// Crop the given string into max $len characters lines\r
-    $textlib = textlib_get_instance();\r
-    if ($textlib->strlen($stringa, current_charset()) > $len) {\r
-        $words = explode(' ', $stringa);\r
-        $newstring = '';\r
-        $substring = '';\r
-        foreach ($words as $word) {\r
-           if (($textlib->strlen($substring, current_charset())+$textlib->strlen($word, current_charset())+1) < $len) {\r
-               $substring .= ' '.$word;\r
-           } else {\r
-               $newstring .= ' '.$substring.'<br />';\r
-               $substring = $word;\r
-           }\r
-        }\r
-        if (!empty($substring)) {\r
-            $newstring .= ' '.$substring;\r
-        }\r
-        return $newstring;\r
-    } else {\r
-        return $stringa;\r
-    }\r
-}\r
-\r
-function scorm_eval_prerequisites($prerequisites,$usertracks) {\r
-\r
-    //$f = "D:\\test.txt";\r
-    //@$ft = fopen($f,"a");\r
-    ////fwrite($ft,"\n Xu ly trong ham scorm_eval_prerequisites \n");    \r
-\r
-\r
-    $element = '';\r
-    $stack = array();\r
-    $statuses = array(\r
-                'passed' => 'passed',\r
-                'completed' => 'completed',\r
-                'failed' => 'failed',\r
-                'incomplete' => 'incomplete',\r
-                'browsed' => 'browsed',\r
-                'not attempted' => 'notattempted',\r
-                'p' => 'passed',\r
-                'c' => 'completed',\r
-                'f' => 'failed',\r
-                'i' => 'incomplete',\r
-                'b' => 'browsed',\r
-                'n' => 'notattempted'\r
-                );\r
-    $i=0;  \r
-    while ($i<strlen($prerequisites)) {\r
-        $symbol = $prerequisites[$i];\r
-        switch ($symbol) {\r
-            case '&':\r
-            case '|':\r
-                $symbol .= $symbol;\r
-            case '~':\r
-            case '(':\r
-            case ')':\r
-            case '*':\r
-            //case '{':\r
-            //case '}':\r
-            //case ',':\r
-                $element = trim($element);\r
-                \r
-                if (!empty($element)) {\r
-                    $element = trim($element);\r
-                    if (isset($usertracks[$element])) {\r
-                        $element = '((\''.$usertracks[$element]->status.'\' == \'completed\') || '.\r
-                                  '(\''.$usertracks[$element]->status.'\' == \'passed\'))'; \r
-                    } else if (($operator = strpos($element,'=')) !== false) {\r
-                        $item = trim(substr($element,0,$operator));\r
-                        if (!isset($usertracks[$item])) {\r
-                            return false;\r
-                        }\r
-                        \r
-                        $value = trim(trim(substr($element,$operator+1)),'"');\r
-                        if (isset($statuses[$value])) {\r
-                            $status = $statuses[$value];\r
-                        } else {\r
-                            return false;\r
-                        }\r
-                                              \r
-                        $element = '(\''.$usertracks[$item]->status.'\' == \''.$status.'\')';\r
-                    } else if (($operator = strpos($element,'<>')) !== false) {\r
-                        $item = trim(substr($element,0,$operator));\r
-                        if (!isset($usertracks[$item])) {\r
-                            return false;\r
-                        }\r
-                        \r
-                        $value = trim(trim(substr($element,$operator+2)),'"');\r
-                        if (isset($statuses[$value])) {\r
-                            $status = $statuses[$value];\r
-                        } else {\r
-                            return false;\r
-                        }\r
-                        \r
-                        $element = '(\''.$usertracks[$item]->status.'\' != \''.$status.'\')';\r
-                    } else if (is_numeric($element)) {\r
-                        if ($symbol == '*') {\r
-                            $symbol = '';\r
-                            $open = strpos($prerequisites,'{',$i);\r
-                            $opened = 1;\r
-                            $closed = 0;\r
-                            for ($close=$open+1; (($opened > $closed) && ($close<strlen($prerequisites))); $close++) { \r
-                                 if ($prerequisites[$close] == '}') {\r
-                                     $closed++;\r
-                                 } else if ($prerequisites[$close] == '{') {\r
-                                     $opened++;\r
-                                 }\r
-                            } \r
-                            $i = $close;\r
-                            \r
-                            $setelements = explode(',', substr($prerequisites, $open+1, $close-($open+1)-1));\r
-                            $settrue = 0;\r
-                            foreach ($setelements as $setelement) {\r
-                                if (scorm_eval_prerequisites($setelement,$usertracks)) {\r
-                                    $settrue++;\r
-                                }\r
-                            }\r
-                            \r
-                            if ($settrue >= $element) {\r
-                                $element = 'true'; \r
-                            } else {\r
-                                $element = 'false';\r
-                            }\r
-                        }\r
-                    } else {\r
-                        return false;\r
-                    }\r
-                    \r
-                    array_push($stack,$element);\r
-                    $element = '';\r
-                }\r
-                if ($symbol == '~') {\r
-                    $symbol = '!';\r
-                }\r
-                if (!empty($symbol)) {\r
-                    array_push($stack,$symbol);\r
-                }\r
-            break;\r
-            default:\r
-                $element .= $symbol;\r
-            break;\r
-        }\r
-        $i++;\r
-    }\r
-    if (!empty($element)) {\r
-        $element = trim($element);\r
-        if (isset($usertracks[$element])) {\r
-            $element = '((\''.$usertracks[$element]->status.'\' == \'completed\') || '.\r
-                       '(\''.$usertracks[$element]->status.'\' == \'passed\'))'; \r
-        } else if (($operator = strpos($element,'=')) !== false) {\r
-            $item = trim(substr($element,0,$operator));\r
-            if (!isset($usertracks[$item])) {\r
-                return false;\r
-            }\r
-            \r
-            $value = trim(trim(substr($element,$operator+1)),'"');\r
-            if (isset($statuses[$value])) {\r
-                $status = $statuses[$value];\r
-            } else {\r
-                return false;\r
-            }\r
-            \r
-            $element = '(\''.$usertracks[$item]->status.'\' == \''.$status.'\')';\r
-        } else if (($operator = strpos($element,'<>')) !== false) {\r
-            $item = trim(substr($element,0,$operator));\r
-            if (!isset($usertracks[$item])) {\r
-                return false;\r
-            }\r
-            \r
-            $value = trim(trim(substr($element,$operator+1)),'"');\r
-            if (isset($statuses[$value])) {\r
-                $status = $statuses[$value];\r
-            } else {\r
-                return false;\r
-            }\r
-            \r
-            $element = '(\''.$usertracks[$item]->status.'\' != \''.trim($status).'\')';\r
-        } else {\r
-            return false;\r
-        }\r
-        \r
-        array_push($stack,$element);\r
-    }\r
-    return eval('return '.implode($stack).';');\r
-}\r
-\r
-function scorm_insert_statistic($statisticInput){\r
-\r
-    $id = null;\r
-    if ($statistic = get_record_select('scorm_statistic',"userid='$statisticInput->userid' AND scormid='$statisticInput->scormid'")) {\r
-\r
-        $statistic->durationtime = $statisticInput->duration;\r
-        $statistic->accesstime = $statisticInput->accesstime;        \r
-        $statistic->status = $statisticInput->status;        \r
-        $statistic->attemptnumber = $statisticInput->attemptnumber;        \r
-        $id = update_record('scorm_statistic',$statistic);\r
-    } else {\r
-        ////fwrite($ft,"Insert trong ham scorm_insert_track \n");    \r
-        $id = insert_record('scorm_statistic',$statisticInput);\r
-    }\r
-    return $id;\r
-\r
-}\r
-function scorm_insert_track($userid,$scormid,$scoid,$attempt,$element,$value) {\r
-\r
-//    //$f = "D:\\test.txt";\r
-//    //@$ft = fopen($f,"a");\r
-    ////fwrite($ft,"\n Xu ly trong ham scorm_insert_track \n");    \r
-\r
-    $id = null;\r
-    if ($track = get_record_select('scorm_scoes_track',"userid='$userid' AND scormid='$scormid' AND scoid='$scoid' AND attempt='$attempt' AND element='$element'")) {\r
-        $track->value = $value;\r
-        $track->timemodified = time();\r
-        ////fwrite($ft,$userid."Update trong ham scorm_insert_track voi cac gia tri userid = ");    \r
-        $id = update_record('scorm_scoes_track',$track);\r
-    } else {\r
-        $track->userid = $userid;\r
-        $track->scormid = $scormid;\r
-        $track->scoid = $scoid;\r
-        $track->attempt = $attempt;\r
-        $track->element = $element;\r
-        $track->value = addslashes($value);\r
-        $track->timemodified = time();\r
-        ////fwrite($ft,"Insert trong ham scorm_insert_track \n");    \r
-        $id = insert_record('scorm_scoes_track',$track);\r
-    }\r
-    return $id;\r
-}\r
-\r
-function scorm_insert_trackmodel($userid,$scormid,$scoid,$attempt) {\r
-\r
-//    //$f = "D:\\test.txt";\r
-//    //@$ft = fopen($f,"a");\r
-\r
-    $id = null;\r
-    if ($suspendtrack = get_record_select('scorm_suspendtrack',"userid='$userid' AND scormid='$scormid'")) {\r
-        $suspendtrack->suspendscoid = $scoid;\r
-        $suspendtrack->attempt = $attempt;\r
-\r
-        $id = update_record('scorm_suspendtrack',$suspendtrack);\r
-    } else {\r
-        $suspendtrack->scormid = $scormid;\r
-        $suspendtrack->suspendscoid = $scoid;\r
-        $suspendtrack->userid = $userid;\r
-        $suspendtrack->attempt = $attempt;\r
-        $id = insert_record('scorm_suspendtrack',$suspendtrack);\r
-    }\r
-    return $id;\r
-}\r
-\r
-function scorm_get_suspendscoid($scormid,$userid) {\r
-    if ($sco = get_record("scorm_suspendtrack","scormid",$scormid,"userid",$userid)) {\r
-        $suspendscoid = $sco->suspendscoid;\r
-        return $suspendscoid;\r
-    } else {\r
-        return 0;\r
-    }\r
-}\r
-\r
-function scorm_add_time($a, $b) {\r
-    $aes = explode(':',$a);\r
-    $bes = explode(':',$b);\r
-    $aseconds = explode('.',$aes[2]);\r
-    $bseconds = explode('.',$bes[2]);\r
-    $change = 0;\r
-\r
-    $acents = 0;  //Cents\r
-    if (count($aseconds) > 1) {\r
-        $acents = $aseconds[1];\r
-    }\r
-    $bcents = 0;\r
-    if (count($bseconds) > 1) {\r
-        $bcents = $bseconds[1];\r
-    }\r
-    $cents = $acents + $bcents;\r
-    $change = floor($cents / 100);\r
-    $cents = $cents - ($change * 100);\r
-    if (floor($cents) < 10) {\r
-        $cents = '0'. $cents;\r
-    }\r
-\r
-    $secs = $aseconds[0] + $bseconds[0] + $change;  //Seconds\r
-    $change = floor($secs / 60);\r
-    $secs = $secs - ($change * 60);\r
-    if (floor($secs) < 10) {\r
-        $secs = '0'. $secs;\r
-    }\r
-\r
-    $mins = $aes[1] + $bes[1] + $change;   //Minutes\r
-    $change = floor($mins / 60);\r
-    $mins = $mins - ($change * 60);\r
-    if ($mins < 10) {\r
-        $mins = '0' .  $mins;\r
-    }\r
-\r
-    $hours = $aes[0] + $bes[0] + $change;  //Hours\r
-    if ($hours < 10) {\r
-        $hours = '0' . $hours;\r
-    }\r
-\r
-    if ($cents != '0') {\r
-        return $hours . ":" . $mins . ":" . $secs . '.' . $cents;\r
-    } else {\r
-        return $hours . ":" . $mins . ":" . $secs;\r
-    }\r
-}\r
-\r
-function scorm_external_link($link) {\r
-// check if a link is external\r
-    $result = false;\r
-    $link = strtolower($link);\r
-    if (substr($link,0,7) == 'http://') {\r
-        $result = true;\r
-    } else if (substr($link,0,8) == 'https://') {\r
-        $result = true;\r
-    } else if (substr($link,0,4) == 'www.') {\r
-        $result = true;\r
-    }\r
-    return $result;\r
-}\r
-\r
-function scorm_grade_user($scoes, $userid, $grademethod=VALUESCOES) {\r
-\r
-    //$f = "D:\\test.txt";\r
-    //@$ft = fopen($f,"a");\r
-    //fwrite($ft,"\n Xu ly trong ham scorm_grade_user \n");    \r
-\r
-    $scores = NULL; \r
-    $scores->scoes = 0;\r
-    $scores->values = 0;\r
-    $scores->max = 0;\r
-    $scores->sum = 0;\r
-\r
-    if (!$scoes) {\r
-        return '';\r
-    }\r
-\r
-    $current = current($scoes);\r
-    $attempt = scorm_get_last_attempt($current->scorm, $userid);\r
-    foreach ($scoes as $sco) { \r
-        if ($userdata=scorm_get_tracks($sco->id, $userid,$attempt)) {\r
-            if (($userdata->status == 'completed') || ($userdata->status == 'passed')) {\r
-                $scores->scoes++;\r
-            }       \r
-            if (!empty($userdata->score_raw)) {\r
-                $scores->values++;\r
-                $scores->sum += $userdata->score_raw;\r
-                $scores->max = ($userdata->score_raw > $scores->max)?$userdata->score_raw:$scores->max;\r
-            }       \r
-        }       \r
-    }\r
-    switch ($grademethod) {\r
-        case VALUEHIGHEST:\r
-            return $scores->max;\r
-        break;  \r
-        case VALUEAVERAGE:\r
-            if ($scores->values > 0) {\r
-                return $scores->sum/$scores->values;\r
-            } else {\r
-                return 0;\r
-            }       \r
-        break;  \r
-        case VALUESUM:\r
-            return $scores->sum;\r
-        break;  \r
-        case VALUESCOES:\r
-            return $scores->scoes;\r
-        break;  \r
-    }\r
-}\r
-\r
-//Lay diem theo Sco cha.. Thuc chat la theo bai kiem tra\r
-function scorm_get_score_from_parent($sco,$userid,$grademethod=VALUESCOES)\r
-{\r
-    \r
-    $scores = NULL; \r
-    $scores->scoes = 0;\r
-    $scores->values = 0;\r
-    $scores->scaled = 0;\r
-    $scores->max = 0;\r
-    $scores->sum = 0;\r
-\r
-    $scoes_total = 0;\r
-    $scoes_count = 0;\r
-    $attempt = scorm_get_last_attempt($sco->scorm, $userid);\r
-    $scoes = get_records('scorm_scoes', 'parent', $sco->identifier);\r
-    foreach ($scoes as $sco)\r
-    {\r
-           $scoes_total++;\r
-           if ($userdata=scorm_get_tracks($sco->id, $userid,$attempt)) {\r
-               if (($userdata->status == 'completed') || ($userdata->success_status == 'passed')) {\r
-                    $scoes_count++;\r
-               }\r
-\r
-\r
-            $scoreraw = $userdata->score_raw; \r
-\r
-            if (!empty($userdata->score_raw)) {\r
-                $scores->values++;\r
-                $scores->sum += $userdata->score_raw;\r
-                $scores->max = ($userdata->score_raw > $scores->max)?$userdata->score_raw:$scores->max;\r
-            }   \r
-            if (!empty($userdata->score_scaled)) {\r
-                $scores->scaled = $scores->scaled + $userdata->score_scaled;\r
-            }       \r
-            \r
-        }       \r
-    }\r
-    if ($scoes_count > 0)\r
-    {\r
-        $scores->scaled = ($scores->scaled)/($scoes_count);\r
-    }\r
-    switch ($grademethod) {\r
-        case VALUEHIGHEST:\r
-            return $scores->max;\r
-        break;  \r
-        case VALUEAVERAGE:\r
-            if ($scores->values > 0) {\r
-                return $scores->sum/$scores->values;\r
-            } else {\r
-                return 0;\r
-            }       \r
-        break;  \r
-        case VALUESUM:\r
-            return $scores->sum;\r
-        break;  \r
-        case VALUESCOES:\r
-            return $scores->scaled;\r
-        break;  \r
-    }\r
-\r
-}\r
-\r
-// Lay ra so luong cac scoes duoc user thuc hien xong\r
-function scorm_get_user_sco_count($scormid, $userid)\r
-{\r
-    $scoes_count = 0;\r
-    $attempt = scorm_get_last_attempt($current->scorm, $userid);\r
-    $scoes = get_records('scorm_scoes', 'scorm', $scormid);\r
-\r
-\r
-\r
-    foreach ($scoes as $sco)\r
-    {\r
-           if ($userdata=scorm_get_tracks($sco->id, $userid,$attempt)) {\r
-\r
-               if (($userdata->status == 'completed') || ($userdata->success_status == 'passed')) {\r
-                    $scoes_count++;\r
-               }\r
-           }\r
-\r
-    }\r
-    return $scoes_count;\r
-    \r
-}\r
-\r
-function scorm_grade_user_new($scoes, $userid, $grademethod=VALUESCOES) {\r
-\r
-    //$f = "D:\\test.txt";\r
-    //@$ft = fopen($f,"a");\r
-    //fwrite($ft,"\n Xu ly trong ham scorm_grade_user \n");    \r
-\r
-    $scores = NULL; \r
-    $scores->scoes = 0;\r
-    $scores->values = 0;\r
-    $scores->scaled = 0;\r
-    $scores->max = 0;\r
-    $scores->sum = 0;\r
-\r
-    if (!$scoes) {\r
-        //fwrite($ft,"\n Khong xuat hien mot SCO duoc tinh diem \n");    \r
-        return '';\r
-    }\r
-\r
-    $current = current($scoes);\r
-    $attempt = scorm_get_last_attempt($current->scorm, $userid);\r
-    //fwrite($ft,"\n ---------------------------------------\n");    \r
-    foreach ($scoes as $sco) { \r
-        if ($userdata=scorm_get_tracks($sco->id, $userid,$attempt)) {\r
-            if (($userdata->status == 'completed') || ($userdata->success_status == 'passed')) {\r
-                $scores->scoes++;\r
-                //fwrite($ft,"\n Them mot khoa hoan thanh co id la ".$sco->id." co gia tri scaled la ".$userdata->score_scaled." \n");    \r
-        \r
-            }  \r
-            $scaled = $userdata->score_scaled;\r
-            $scoreraw = $userdata->score_raw; \r
-            if ($scaled ==0){\r
-                $scores->scaled = $scores->scaled / $scores->scoes;\r
-                //fwrite($ft,"\n Ti le chinh xac ".($scores->scaled*100)." phan tram");    \r
-\r
-            }\r
-\r
-            if (!empty($userdata->score_raw)) {\r
-                $scores->values++;\r
-                $scores->sum += $userdata->score_raw;\r
-                $scores->max = ($userdata->score_raw > $scores->max)?$userdata->score_raw:$scores->max;\r
-            }  \r
-                        \r
-            if (!empty($scaled)) {\r
-                //fwrite($ft,"\n go ---->>> \n");    \r
-                $scores->scaled = (($scores->scaled) * ($scores->scoes-1) + $scaled)/($scores->scoes);\r
-                //fwrite($ft,"\n Ti le chinh xac ".($scores->scaled*100)." phan tram");    \r
-\r
-            }       \r
-            \r
-        }       \r
-    }\r
-    //fwrite($ft,"\n ----+++++++++++------\n");    \r
-    //fwrite($ft,"\n Kieu gia tri tra ve la  ".$grademethod);    \r
-    switch ($grademethod) {\r
-        case VALUEHIGHEST:\r
-            //fwrite($ft,"\n Gia tri tra ve thouoc loai cao nhat");    \r
-            return $scores->max;\r
-        break;  \r
-        case VALUEAVERAGE:\r
-            //fwrite($ft,"\n Gia tri tra ve thouoc loai trung binh");    \r
-            if ($scores->values > 0) {\r
-                return $scores->sum/$scores->values;\r
-            } else {\r
-                return 0;\r
-            }       \r
-        break;  \r
-        case VALUESUM:\r
-            //fwrite($ft,"\n Gia tri tra ve thouoc loai tong cong");    \r
-            return $scores->sum;\r
-        break;  \r
-        case VALUESCOES:\r
-            //fwrite($ft,"\n Gia tri tra ve thouoc loai scoes co gia tri".$scores->scaled);    \r
-            return $scores->scaled;\r
-        break;  \r
-    }\r
-}\r
-\r
-function scorm_count_launchable($scormid,$organization) {\r
-    return count_records_select('scorm_scoes',"scorm=$scormid AND organization='$organization' AND launch<>''");\r
-}\r
-\r
-function scorm_get_toc($user,$scorm,$liststyle,$currentorg='',$scoid='',$mode='normal',$attempt='',$play=false) {\r
-    global $CFG;\r
-\r
-    //$f = "D:\\test.txt";\r
-    //@$ft = fopen($f,"a");\r
-    //fwrite($ft,"\n Xu ly trong ham scorm_get_toc \n");    \r
-\r
-    //\r
-    $suspendscoid = scorm_get_suspendscoid($scorm->id,$user->id);\r
-    //\r
-\r
-    $strexpand = get_string('expcoll','scorm');\r
-    $modestr = '';\r
-    if ($mode == 'browse') {\r
-        $modestr = '&amp;mode='.$mode;\r
-    } \r
-    $scormpixdir = $CFG->modpixpath.'/scorm/pix';\r
-    \r
-    $result = new stdClass();\r
-    $result->toc = "<ul id='0' class='$liststyle'>\n";\r
-    $tocmenus = array();\r
-    $result->prerequisites = true;\r
-    $incomplete = false;\r
-    \r
-    //\r
-    // Get the current organization infos\r
-    //\r
-    $organizationsql = '';\r
-    if (!empty($currentorg)) {\r
-        if (($organizationtitle = get_field('scorm_scoes','title','scorm',$scorm->id,'identifier',$currentorg)) != '') {\r
-            $result->toc .= "\t<li>$organizationtitle</li>\n";\r
-            $tocmenus[] = $organizationtitle;\r
-        }\r
-        $organizationsql = "AND organization='$currentorg'";\r
-    }\r
-    //\r
-    // If not specified retrieve the last attempt number\r
-    //\r
-    if (empty($attempt)) {\r
-        $attempt = scorm_get_last_attempt($scorm->id, $user->id);\r
-    }\r
-    $result->attemptleft = $scorm->maxattempt - $attempt;\r
-\r
-    //fwrite($ft,"\n So lan attempt con lai la \n".$result->attemptleft);    \r
-    \r
-    if ($scoes = get_records_select('scorm_scoes',"scorm='$scorm->id' $organizationsql order by id ASC")){\r
-        //\r
-        // Lay du lieu da duoc tracking cho moi doi tuong hoc tap\r
-        // \r
-        $usertracks = array();\r
-        foreach ($scoes as $sco) {\r
-            //Kiem tra xem $sco co phai la phan muc khong. Neu la trang Asset hoac SCO thi xu ly tiep\r
-            if (!empty($sco->launch)) {\r
-                if ($usertrack=scorm_get_tracks($sco->id,$user->id,$attempt)) {\r
-                    if ($usertrack->status == '') {\r
-                        $usertrack->status = 'notattempted';\r
-                    }\r
-                    // Ghi lai thong tin $usertracks theo tung doi tuong sco\r
-                    $usertracks[$sco->identifier] = $usertrack;\r
-                }\r
-            }\r
-        }\r
-\r
-        $level=0;\r
-        $sublist=1;\r
-        $previd = 0;\r
-        $nextid = 0;\r
-        $findnext = false;\r
-        $parents[$level]='/';\r
-        \r
-        foreach ($scoes as $sco) {\r
-            if ($parents[$level]!=$sco->parent) {\r
-                if ($newlevel = array_search($sco->parent,$parents)) {\r
-                    for ($i=0; $i<($level-$newlevel); $i++) {\r
-                        $result->toc .= "\t\t</ul></li>\n";\r
-                    }\r
-                    $level = $newlevel;\r
-                } else {\r
-                    $i = $level;\r
-                    $closelist = '';\r
-                    while (($i > 0) && ($parents[$level] != $sco->parent)) {\r
-                        $closelist .= "\t\t</ul></li>\n";\r
-                        $i--;\r
-                    }\r
-                    if (($i == 0) && ($sco->parent != $currentorg)) {\r
-                        $style = '';\r
-                        if (isset($_COOKIE['hide:SCORMitem'.$sco->id])) {\r
-                            $style = ' style="display: none;"';\r
-                        }\r
-                        $result->toc .= "\t\t<li><ul id='$sublist' class='$liststyle'$style>\n";\r
-                        $level++;\r
-                    } else {\r
-                        $result->toc .= $closelist;\r
-                        $level = $i;\r
-                    }\r
-                    $parents[$level]=$sco->parent;\r
-                }\r
-            }\r
-            $result->toc .= "\t\t<li>";\r
-            $nextsco = next($scoes);\r
-            if (($nextsco !== false) && ($sco->parent != $nextsco->parent) && (($level==0) || (($level>0) && ($nextsco->parent == $sco->identifier)))) {\r
-                $sublist++;\r
-                $icon = 'minus';\r
-                if (isset($_COOKIE['hide:SCORMitem'.$nextsco->id])) {\r
-                    $icon = 'plus';\r
-                }\r
-                $result->toc .= '<a href="javascript:expandCollide(img'.$sublist.','.$sublist.','.$nextsco->id.');"><img id="img'.$sublist.'" src="'.$scormpixdir.'/'.$icon.'.gif" alt="'.$strexpand.'" title="'.$strexpand.'"/></a>';\r
-            } else {\r
-                $result->toc .= '<img src="'.$scormpixdir.'/spacer.gif" />';\r
-            }\r
-            if (empty($sco->title)) {\r
-                $sco->title = $sco->identifier;\r
-            }\r
-            if (!empty($sco->launch)) {\r
-                $startbold = '';\r
-                $endbold = '';\r
-                $score = '';\r
-                if (empty($scoid) && ($mode != 'normal')) {\r
-                    $scoid = $sco->id;\r
-                }\r
-                //Neu la sco suspend thi hien thi anh khac\r
-                if ($suspendscoid == $sco->id){\r
-                    $result->toc .= '<img src="'.$scormpixdir.'/suspend.gif" alt="Dang tam dung o day" title="Dang dung o day" />';                \r
-                } else {\r
-                //-----------------------\r
-                    if (isset($usertracks[$sco->identifier])) {\r
-                        $usertrack = $usertracks[$sco->identifier];\r
-                        $strstatus = get_string($usertrack->status,'scorm');\r
-                        $result->toc .= '<img src="'.$scormpixdir.'/'.$usertrack->status.'.gif" alt="'.$strstatus.'" title="'.$strstatus.'" />';\r
-                        \r
-                        if (($usertrack->status == 'notattempted') || ($usertrack->status == 'incomplete') || ($usertrack->status == 'browsed')) {\r
-                            //Neu khoa hoc chua duoc attempted hoac chua hoan thanh hoac la chi browsed\r
-                            $incomplete = true;\r
-                            if ($play && empty($scoid)) {\r
-                                $scoid = $sco->id;\r
-                            }\r
-                        }\r
-                        if ($usertrack->score_raw != '') {\r
-                            $score = '('.get_string('score','scorm').':&nbsp;'.$usertrack->score_raw.')';\r
-                        }\r
-                    } else {\r
-                        if ($play && empty($scoid)) {\r
-                            $scoid = $sco->id;\r
-                        }\r
-                        if ($sco->scormtype == 'sco') {\r
-                            $result->toc .= '<img src="'.$scormpixdir.'/notattempted.gif" alt="'.get_string('notattempted','scorm').'" title="'.get_string('notattempted','scorm').'" />';\r
-                            $incomplete = true;\r
-                        } else {\r
-                            $result->toc .= '<img src="'.$scormpixdir.'/asset.gif" alt="'.get_string('asset','scorm').'" title="'.get_string('asset','scorm').'" />';\r
-                        }\r
-                    }\r
-                }\r
-                if ($sco->id == $scoid) {\r
-                    $startbold = '<b>';\r
-                    $endbold = '</b>';\r
-                    $findnext = true;\r
-                    $shownext = $sco->next;\r
-                    $showprev = $sco->previous;\r
-                }\r
-                \r
-                if (($nextid == 0) && (scorm_count_launchable($scorm->id,$currentorg) > 1) && ($nextsco!==false) && (!$findnext)) {\r
-                    if (!empty($sco->launch)) {\r
-                        $previd = $sco->id;\r
-                    }\r
-                }\r
-                if (empty($sco->prerequisites) || scorm_eval_prerequisites($sco->prerequisites,$usertracks)) {\r
-                    if ($sco->id == $scoid) {\r
-                        $result->prerequisites = true;\r
-                    }\r
-                    if (scorm_isChoice($scorm->id,$sco->id) == 1)\r
-                    {\r
-                    $url = $CFG->wwwroot.'/mod/scorm/player.php?a='.$scorm->id.'&amp;currentorg='.$currentorg.$modestr.'&amp;scoid='.$sco->id;\r
-                    $result->toc .= '&nbsp;'.$startbold.'<a href="'.$url.'">'.format_string($sco->title).'</a>'.$score.$endbold."</li>\n";\r
-                    $tocmenus[$sco->id] = scorm_repeater('&minus;',$level) . '&gt;' . format_string($sco->title);\r
-                    }\r
-                    else\r
-                    {\r
-                    $result->toc .= '&nbsp;'.$startbold.format_string($sco->title).$score.$endbold."</li>\n";\r
-                    $tocmenus[$sco->id] = scorm_repeater('&minus;',$level) . '&gt;' . format_string($sco->title);                    \r
-                    }\r
-                } else {\r
-                    if ($sco->id == $scoid) {\r
-                        $result->prerequisites = false;\r
-                    }\r
-                    $result->toc .= '&nbsp;'.$sco->title."</li>\n";\r
-                }\r
-            } else {\r
-                $result->toc .= '&nbsp;'.$sco->title."</li>\n";\r
-            }\r
-            if (($nextsco !== false) && ($nextid == 0) && ($findnext)) {\r
-                if (!empty($nextsco->launch)) {\r
-                    $nextid = $nextsco->id;\r
-                }\r
-            }\r
-        }\r
-        for ($i=0;$i<$level;$i++) {\r
-            $result->toc .= "\t\t</ul></li>\n";\r
-        }\r
-        \r
-        if ($play) {\r
-            $sco = get_record('scorm_scoes','id',$scoid);\r
-            $sco->previd = $previd;\r
-            $sco->nextid = $nextid;\r
-            $result->sco = $sco;\r
-            $result->incomplete = $incomplete;\r
-        } else {\r
-            $result->incomplete = $incomplete;\r
-        }\r
-    }\r
-    $result->toc .= "\t</ul>\n";\r
-    if ($scorm->hidetoc == 0) {\r
-        $result->toc .= '\r
-          <script language="javascript" type="text/javascript">\r
-          <!--\r
-              function expandCollide(which,list,item) {\r
-                  var nn=document.ids?true:false\r
-                  var w3c=document.getElementById?true:false\r
-                  var beg=nn?"document.ids.":w3c?"document.getElementById(":"document.all.";\r
-                  var mid=w3c?").style":".style";\r
-\r
-                  if (eval(beg+list+mid+".display") != "none") {\r
-                      which.src = "'.$scormpixdir.'/plus.gif";\r
-                      eval(beg+list+mid+".display=\'none\';");\r
-                      new cookie("hide:SCORMitem" + item, 1, 356, "/").set();\r
-                  } else {\r
-                      which.src = "'.$scormpixdir.'/minus.gif";\r
-                      eval(beg+list+mid+".display=\'block\';");\r
-                      new cookie("hide:SCORMitem" + item, 1, -1, "/").set();\r
-                  }\r
-              }\r
-          -->\r
-          </script>'."\n";\r
-    }\r
-    \r
-    $url = $CFG->wwwroot.'/mod/scorm/player.php?a='.$scorm->id.'&amp;currentorg='.$currentorg.$modestr.'&amp;scoid=';\r
-    $result->tocmenu = popup_form($url,$tocmenus, "tocmenu", $sco->id, '', '', '', true);\r
-\r
-    return $result;\r
-}\r
-\r
-function scorm_get_last_attempt($scormid, $userid) {\r
-\r
-    //$f = "D:\\test.txt";\r
-    //@$ft = fopen($f,"a");\r
-    ////fwrite($ft,"\n Xu ly trong ham scorm_get_last_attempt \n");    \r
-\r
-/// Find the last attempt number for the given user id and scorm id\r
-    if ($lastattempt = get_record('scorm_scoes_track', 'userid', $userid, 'scormid', $scormid, '', '', 'max(attempt) as a')) {\r
-        if (empty($lastattempt->a)) {\r
-            return '1';\r
-        } else {\r
-            return $lastattempt->a;\r
-        }\r
-    }\r
-}\r
-\r
-// Khi mot nguoi truy nhap vao mot SCO thi se thiet lap\r
-// nguoi do da no luc thuc hien no\r
-function scorm_set_attempt($scoid,$userid)\r
-{\r
-    //Lay gia tri last attempt\r
-    if ($scormid = get_field('scorm_scoes','scorm','id',$scoid)) {\r
-        $attempt = scorm_get_last_attempt($scormid,$userid);\r
-    } else {\r
-        $attempt = 1;\r
-    }\r
-    //Chi set attempt cho cac SCO\r
-    $scormtype = get_field('scorm_scoes','scormtype','id',$scoid) ;\r
-    if ($scormtype == 'sco'){\r
-        $element = 'cmi.attempt_status';\r
-        $value = 'attempted';\r
-        scorm_insert_track($userid,$scormid,$scoid,$attempt,$element,$value);\r
-    }\r
-}\r
-function scorm_get_tracks($scoid,$userid,$attempt='') {\r
-\r
-    //$f = "D:\\test.txt";\r
-    //@$ft = fopen($f,"a");\r
-    ////fwrite($ft,"\n Xu ly trong ham scorm_get_tracks \n");    \r
-\r
-/// Gets all tracks of specified sco and user\r
-    global $CFG;\r
-\r
-    if (empty($attempt)) {\r
-        if ($scormid = get_field('scorm_scoes','scorm','id',$scoid)) {\r
-            $attempt = scorm_get_last_attempt($scormid,$userid);\r
-        } else {\r
-            $attempt = 1;\r
-        }\r
-    }\r
-    $attemptsql = ' AND attempt=' . $attempt;\r
-    if ($tracks = get_records_select('scorm_scoes_track',"userid=$userid AND scoid=$scoid".$attemptsql,'element ASC')) {\r
-        $usertrack->userid = $userid;\r
-        $usertrack->scoid = $scoid; \r
-        $usertrack->score_raw = '';\r
-        $usertrack->score_scaled = '';\r
-        $usertrack->status = '';\r
-        $usertrack->success_status = '';\r
-        $usertrack->attempt_status = '';\r
-        $usertrack->satisfied_status = '';\r
-        $usertrack->total_time = '00:00:00';\r
-        $usertrack->session_time = '00:00:00';\r
-        $usertrack->timemodified = 0;\r
-        foreach ($tracks as $track) {\r
-            $element = $track->element;\r
-            $usertrack->{$element} = $track->value;\r
-            switch ($element) {\r
-                case 'cmi.core.lesson_status':\r
-                case 'cmi.attempt_status':\r
-                    $usertrack->status = $track->value;\r
-                    $usertrack->attempt_status = $track->value;                    \r
-                break;                \r
-                case 'cmi.completion_status':\r
-                    if ($track->value == 'not attempted') {\r
-                        $track->value = 'notattempted';\r
-                        $usertrack->attempt_status = $track->value;\r
-                    }       \r
-                    $usertrack->status = $track->value;\r
-                break;  \r
-                case 'cmi.success_status':\r
-                    $usertrack->success_status = $track->value;\r
-                    if ($track->value=='passed'){\r
-                        $usertrack->satisfied_status = 'satisfied';                    \r
-                    }\r
-                    if ($track->value=='failed'){\r
-                        $usertrack->satisfied_status = 'notSatisfied';                    \r
-                    }                    \r
-                break;\r
-                case 'cmi.core.score.raw':\r
-                case 'cmi.score.raw':\r
-                    $usertrack->score_raw = $track->value;\r
-                break;  \r
-                case 'cmi.score.scaled':\r
-                    $usertrack->score_scaled = $track->value;\r
-                break;  \r
-                case 'cmi.core.session_time':\r
-                case 'cmi.session_time':\r
-                    $usertrack->session_time = $track->value;\r
-                break;  \r
-                case 'cmi.core.total_time':\r
-                case 'cmi.total_time':\r
-                    $usertrack->total_time = $track->value;\r
-                break;  \r
-            }       \r
-            if (isset($track->timemodified) && ($track->timemodified > $usertrack->timemodified)) {\r
-                $usertrack->timemodified = $track->timemodified;\r
-            }       \r
-        }       \r
-        return $usertrack;\r
-    } else {\r
-        return false;\r
-    }\r
-}\r
-\r
-\r
-function scorm_get_AbsoluteTimeLimit($scoid){\r
-    $sco = get_record("scorm_scoes","id",$scoid);\r
-    if (!empty($sco)){\r
-        return $sco->attemptAbsoluteDurationLimit;\r
-    }\r
-    return 0;\r
-}\r
-//-----------------------------------------------------\r
-/// Library of functions and constants for parsing packages\r
-\r
-function scorm_parse($scorm) {\r
-    global $CFG;\r
-\r
-    //$f = "D:\\test.txt";\r
-    //@$ft = fopen($f,"a");\r
-    ////fwrite($ft,"\n Xu ly doc thong tin trong ham scorm_parse \n");\r
-\r
-    // Parse scorm manifest\r
-    if ($scorm->pkgtype == 'AICC') {\r
-        $scorm->launch = scorm_parse_aicc($scorm->dir.'/'.$scorm->id,$scorm->id);\r
-    } else {\r
-        if (basename($scorm->reference) != 'imsmanifest.xml') {\r
-            $scorm->launch = scorm_parse_scorm($scorm->dir.'/'.$scorm->id,$scorm->id);\r
-        } else {\r
-            $scorm->launch = scorm_parse_scorm($CFG->dataroot.'/'.$scorm->course.'/'.dirname($scorm->reference),$scorm->id);\r
-        }\r
-    }\r
-\r
-    return $scorm->launch;\r
-}\r
-\r
-/**\r
-* Take the header row of an AICC definition file\r
-* and returns sequence of columns and a pointer to\r
-* the sco identifier column.\r
-*\r
-* @param string $row AICC header row\r
-* @param string $mastername AICC sco identifier column\r
-* @return mixed\r
-*/\r
-function scorm_get_aicc_columns($row,$mastername='system_id') {\r
-    $tok = strtok(strtolower($row),"\",\n\r");\r
-    $result->columns = array();\r
-    $i=0;\r
-    while ($tok) {\r
-        if ($tok !='') {\r
-            $result->columns[] = $tok;\r
-            if ($tok == $mastername) {\r
-                $result->mastercol = $i;\r
-            }\r
-            $i++;\r
-        }\r
-        $tok = strtok("\",\n\r");\r
-    }\r
-    return $result;\r
-}\r
-\r
-/**\r
-* Given a colums array return a string containing the regular\r
-* expression to match the columns in a text row.\r
-*\r
-* @param array $column The header columns\r
-* @param string $remodule The regular expression module for a single column\r
-* @return string\r
-*/\r
-function scorm_forge_cols_regexp($columns,$remodule='(".*")?,') {\r
-    $regexp = '/^';\r
-    foreach ($columns as $column) {\r
-        $regexp .= $remodule;\r
-    }\r
-    $regexp = substr($regexp,0,-1) . '/';\r
-    return $regexp;\r
-}\r
-\r
-function scorm_parse_aicc($pkgdir,$scormid){\r
-    \r
-    //$f = "D:\\test.txt";\r
-    //@$ft = fopen($f,"a");\r
-    ////fwrite($ft,"\n Xu ly doc thong tin trong ham scorm_parse_aicc \n");    \r
-    \r
-    $version = 'AICC';\r
-    $ids = array();\r
-    $courses = array();\r
-    if ($handle = opendir($pkgdir)) {\r
-        while (($file = readdir($handle)) !== false) {\r
-            $ext = substr($file,strrpos($file,'.'));\r
-            $extension = strtolower(substr($ext,1));\r
-            $id = strtolower(basename($file,$ext));\r
-            $ids[$id]->$extension = $file;\r
-        }\r
-        closedir($handle);\r
-    }\r
-    foreach ($ids as $courseid => $id) {\r
-        if (isset($id->crs)) {\r
-            if (is_file($pkgdir.'/'.$id->crs)) {\r
-                $rows = file($pkgdir.'/'.$id->crs);\r
-                foreach ($rows as $row) {\r
-                    if (preg_match("/^(.+)=(.+)$/",$row,$matches)) {\r
-                        switch (strtolower(trim($matches[1]))) {\r
-                            case 'course_id':\r
-                                $courses[$courseid]->id = trim($matches[2]);\r
-                            break;\r
-                            case 'course_title':\r
-                                $courses[$courseid]->title = trim($matches[2]);\r
-                            break;\r
-                            case 'version':\r
-                                $courses[$courseid]->version = 'AICC_'.trim($matches[2]);\r
-                            break;\r
-                        }\r
-                    }\r
-                }\r
-            }\r
-        }\r
-        if (isset($id->des)) {\r
-            $rows = file($pkgdir.'/'.$id->des);\r
-            $columns = scorm_get_aicc_columns($rows[0]);\r
-            $regexp = scorm_forge_cols_regexp($columns->columns);\r
-            for ($i=1;$i<count($rows);$i++) {\r
-                if (preg_match($regexp,$rows[$i],$matches)) {\r
-                    for ($j=0;$j<count($columns->columns);$j++) {\r
-                        $column = $columns->columns[$j];\r
-                        $courses[$courseid]->elements[substr(trim($matches[$columns->mastercol+1]),1,-1)]->$column = substr(trim($matches[$j+1]),1,-1);\r
-                    }\r
-                }\r
-            }\r
-        }\r
-        if (isset($id->au)) {\r
-            $rows = file($pkgdir.'/'.$id->au);\r
-            $columns = scorm_get_aicc_columns($rows[0]);\r
-            $regexp = scorm_forge_cols_regexp($columns->columns);\r
-            for ($i=1;$i<count($rows);$i++) {\r
-                if (preg_match($regexp,$rows[$i],$matches)) {\r
-                    for ($j=0;$j<count($columns->columns);$j++) {\r
-                        $column = $columns->columns[$j];\r
-                        $courses[$courseid]->elements[substr(trim($matches[$columns->mastercol+1]),1,-1)]->$column = substr(trim($matches[$j+1]),1,-1);\r
-                    }\r
-                }\r
-            }\r
-        }\r
-        if (isset($id->cst)) {\r
-            $rows = file($pkgdir.'/'.$id->cst);\r
-            $columns = scorm_get_aicc_columns($rows[0],'block');\r
-            $regexp = scorm_forge_cols_regexp($columns->columns,'(.+)?,');\r
-            for ($i=1;$i<count($rows);$i++) {\r
-                if (preg_match($regexp,$rows[$i],$matches)) {\r
-                    for ($j=0;$j<count($columns->columns);$j++) {\r
-                        if ($j != $columns->mastercol) {\r
-                            $courses[$courseid]->elements[substr(trim($matches[$j+1]),1,-1)]->parent = substr(trim($matches[$columns->mastercol+1]),1,-1);\r
-                        }\r
-                    }\r
-                }\r
-            }\r
-        }\r
-        if (isset($id->ort)) {\r
-            $rows = file($pkgdir.'/'.$id->ort);\r
-        }\r
-        if (isset($id->pre)) {\r
-            $rows = file($pkgdir.'/'.$id->pre);\r
-            $columns = scorm_get_aicc_columns($rows[0],'structure_element');\r
-            $regexp = scorm_forge_cols_regexp($columns->columns,'(.+),');\r
-            for ($i=1;$i<count($rows);$i++) {\r
-                if (preg_match($regexp,$rows[$i],$matches)) {\r
-                    $courses[$courseid]->elements[$columns->mastercol+1]->prerequisites = substr(trim($matches[1-$columns->mastercol+1]),1,-1);\r
-                }\r
-            }\r
-        }\r
-        if (isset($id->cmp)) {\r
-            $rows = file($pkgdir.'/'.$id->cmp);\r
-        }\r
-    }\r
-    //print_r($courses);\r
-    $launch = 0;\r
-    if (isset($courses)) {\r
-        foreach ($courses as $course) {\r
-            unset($sco);\r
-            $sco->identifier = $course->id;\r
-            $sco->scorm = $scormid;\r
-            $sco->organization = '';\r
-            $sco->title = $course->title;\r
-            $sco->parent = '/';\r
-            $sco->launch = '';\r
-            $sco->scormtype = '';\r
-            //print_r($sco);\r
-            $id = insert_record('scorm_scoes',$sco);\r
-            if ($launch == 0) {\r
-                $launch = $id;\r
-            }\r
-            if (isset($course->elements)) {\r
-                foreach($course->elements as $element) {\r
-                    unset($sco);\r
-                    $sco->identifier = $element->system_id;\r
-                    $sco->scorm = $scormid;\r
-                    $sco->organization = $course->id;\r
-                    $sco->title = $element->title;\r
-                    if (strtolower($element->parent) == 'root') {\r
-                        $sco->parent = '/';\r
-                    } else {\r
-                        $sco->parent = $element->parent;\r
-                    }\r
-                    if (isset($element->file_name)) {\r
-                        $sco->launch = $element->file_name;\r
-                        $sco->scormtype = 'sco';\r
-                    } else {\r
-                        $element->file_name = '';\r
-                        $sco->scormtype = '';\r
-                    }\r
-                    if (!isset($element->prerequisites)) {\r
-                        $element->prerequisites = '';\r
-                    }\r
-                    $sco->prerequisites = $element->prerequisites;\r
-                    if (!isset($element->max_time_allowed)) {\r
-                        $element->max_time_allowed = '';\r
-                    }\r
-                    $sco->maxtimeallowed = $element->max_time_allowed;\r
-                    if (!isset($element->time_limit_action)) {\r
-                        $element->time_limit_action = '';\r
-                    }\r
-                    $sco->timelimitaction = $element->time_limit_action;\r
-                    if (!isset($element->mastery_score)) {\r
-                        $element->mastery_score = '';\r
-                    }\r
-                    $sco->masteryscore = $element->mastery_score;\r
-                    $sco->previous = 0;\r
-                    $sco->next = 0;\r
-                    $id = insert_record('scorm_scoes',$sco);\r
-                    if ($launch==0) {\r
-                        $launch = $id;\r
-                    }\r
-                }\r
-            }\r
-        }\r
-    }\r
-    set_field('scorm','version','AICC','id',$scormid);\r
-    return $launch;\r
-}\r
-\r
-function scorm_get_resources($blocks) {\r
-\r
-    //$f = "D:\\test.txt";\r
-    //@$ft = fopen($f,"a");\r
-    ////fwrite($ft,"\n Xu ly trong ham scorm_get_resources \n");    \r
-\r
-    foreach ($blocks as $block) {\r
-        if ($block['name'] == 'RESOURCES') {\r
-            foreach ($block['children'] as $resource) {\r
-                if ($resource['name'] == 'RESOURCE') {\r
-                    $resources[addslashes($resource['attrs']['IDENTIFIER'])] = $resource['attrs'];\r
-                }\r
-            }\r
-        }\r
-    }\r
-    return $resources;\r
-}\r
-\r
-function scorm_get_manifest($blocks,$scoes) {\r
-\r
-    //$f = "D:\\test.txt";\r
-    //@$ft = fopen($f,"a");\r
-    ////fwrite($ft,"\n Xu ly doc thong tin trong ham scorm_get_manifest.  \n");    \r
-    ////////fwrite($ft,$blocks." la  gia tri block la  \n");    \r
-\r
-    static $parents = array();\r
-    static $resources;\r
-\r
-    static $manifest;\r
-    static $organization;\r
-\r
-    if (count($blocks) > 0) {\r
-        foreach ($blocks as $block) {\r
-            switch ($block['name']) {\r
-                case 'METADATA':\r
-                    if (isset($block['children'])) {\r
-                        foreach ($block['children'] as $metadata) {\r
-                            if ($metadata['name'] == 'SCHEMAVERSION') {\r
-                                if (empty($scoes->version)) {\r
-                                    if (isset($metadata['tagData']) && (preg_match("/^(1\.2)$|^(CAM )?(1\.3)$/",$metadata['tagData'],$matches))) {\r
-                                        $scoes->version = 'SCORM_'.$matches[count($matches)-1];\r
-                                    } else {\r
-                                        $scoes->version = 'SCORM_1.2';\r
-                                    }\r
-                                }\r
-                            }\r
-                        }\r
-                    }\r
-                break;\r
-                case 'MANIFEST':\r
-                    $manifest = addslashes($block['attrs']['IDENTIFIER']); //Lay thuoc tinh IDENTFIER cua MANIFEST\r
-                    $organization = '';\r
-                    $resources = array();\r
-                    $resources = scorm_get_resources($block['children']);\r
-                    $scoes = scorm_get_manifest($block['children'],$scoes);\r
-                    if (count($scoes->elements) <= 0) {\r
-                        foreach ($resources as $item => $resource) {\r
-                            if (!empty($resource['HREF'])) {\r
-                                $sco = new stdClass();\r
-                                $sco->identifier = $item;\r
-                                $sco->title = $item;\r
-                                $sco->parent = '/';\r
-                                $sco->launch = addslashes($resource['HREF']);\r
-                                $sco->scormtype = addslashes($resource['ADLCP:SCORMTYPE']);\r
-                                $scoes->elements[$manifest][$organization][$item] = $sco;\r
-                            }\r
-                        }\r
-                    }\r
-                break;\r
-                case 'ORGANIZATIONS':\r
-                    if (!isset($scoes->defaultorg)) {\r
-                        $scoes->defaultorg = addslashes($block['attrs']['DEFAULT']);\r
-                    }\r
-                    $scoes = scorm_get_manifest($block['children'],$scoes);\r
-                break;\r
-                case 'ORGANIZATION':\r
-                    $identifier = addslashes($block['attrs']['IDENTIFIER']);\r
-                    $organization = '';\r
-                    $scoes->elements[$manifest][$organization][$identifier]->identifier = $identifier;\r
-                    $scoes->elements[$manifest][$organization][$identifier]->parent = '/';\r
-                    $scoes->elements[$manifest][$organization][$identifier]->launch = '';\r
-                    $scoes->elements[$manifest][$organization][$identifier]->scormtype = '';\r
-\r
-                    $parents = array();\r
-                    $parent = new stdClass();\r
-                    $parent->identifier = $identifier;\r
-                    $parent->organization = $organization;\r
-                    array_push($parents, $parent);\r
-                    $organization = $identifier;\r
-\r
-                    $scoes = scorm_get_manifest($block['children'],$scoes);\r
-                    \r
-                    array_pop($parents);\r
-                break;\r
-                case 'ITEM':\r
-                    $parent = array_pop($parents);\r
-                    array_push($parents, $parent);\r
-\r
-                    $identifier = addslashes($block['attrs']['IDENTIFIER']);\r
-                    $scoes->elements[$manifest][$organization][$identifier]->identifier = $identifier;\r
-                    $scoes->elements[$manifest][$organization][$identifier]->parent = $parent->identifier;\r
-                    if (!isset($block['attrs']['ISVISIBLE'])) {\r
-                        $block['attrs']['ISVISIBLE'] = 'true';\r
-                    }\r
-                    $scoes->elements[$manifest][$organization][$identifier]->isvisible = addslashes($block['attrs']['ISVISIBLE']);\r
-                    if (!isset($block['attrs']['PARAMETERS'])) {\r
-                        $block['attrs']['PARAMETERS'] = '';\r
-                    }\r
-                    $scoes->elements[$manifest][$organization][$identifier]->parameters = addslashes($block['attrs']['PARAMETERS']);\r
-                    if (!isset($block['attrs']['IDENTIFIERREF'])) {\r
-                        $scoes->elements[$manifest][$organization][$identifier]->launch = '';\r
-                        $scoes->elements[$manifest][$organization][$identifier]->scormtype = 'asset';\r
-                    } else {\r
-                        $idref = addslashes($block['attrs']['IDENTIFIERREF']);\r
-                        $base = '';\r
-                        if (isset($resources[$idref]['XML:BASE'])) {\r
-                            $base = $resources[$idref]['XML:BASE'];\r
-                        }\r
-                        $scoes->elements[$manifest][$organization][$identifier]->launch = addslashes($base.$resources[$idref]['HREF']);\r
-                        if (empty($resources[$idref]['ADLCP:SCORMTYPE'])) {\r
-                            $resources[$idref]['ADLCP:SCORMTYPE'] = 'asset';\r
-                        }\r
-                        $scoes->elements[$manifest][$organization][$identifier]->scormtype = addslashes($resources[$idref]['ADLCP:SCORMTYPE']);\r
-                    }\r
-                    \r
-                    //////fwrite($ft,"---Dang lam viec voi ITEM co Identifier = ".$identifier);\r
-                    $parent = new stdClass();\r
-                    $parent->identifier = $identifier;\r
-                    $parent->organization = $organization;\r
-                    array_push($parents, $parent);\r
-\r
-                    $scoes = scorm_get_manifest($block['children'],$scoes);\r
-                    \r
-                    array_pop($parents);\r
-                break;\r
-                case 'TITLE':\r
-                    $parent = array_pop($parents);\r
-                    array_push($parents, $parent);\r
-                    $scoes->elements[$manifest][$parent->organization][$parent->identifier]->title = addslashes($block['tagData']);\r
-                break;\r
-                case 'ADLCP:PREREQUISITES':\r
-                    if ($block['attrs']['TYPE'] == 'aicc_script') {\r
-                        $parent = array_pop($parents);\r
-                        array_push($parents, $parent);\r
-                        $scoes->elements[$manifest][$parent->organization][$parent->identifier]->prerequisites = addslashes($block['tagData']);\r
-                    }\r
-                break;\r
-                case 'ADLCP:MAXTIMEALLOWED':\r
-                    $parent = array_pop($parents);\r
-                    array_push($parents, $parent);\r
-                    $scoes->elements[$manifest][$parent->organization][$parent->identifier]->maxtimeallowed = addslashes($block['tagData']);\r
-                break;\r
-                case 'ADLCP:TIMELIMITACTION':\r
-                    $parent = array_pop($parents);\r
-                    array_push($parents, $parent);\r
-                    $scoes->elements[$manifest][$parent->organization][$parent->identifier]->timelimitaction = addslashes($block['tagData']);\r
-                break;\r
-                case 'ADLCP:DATAFROMLMS':\r
-                    $parent = array_pop($parents);\r
-                    array_push($parents, $parent);\r
-                    $scoes->elements[$manifest][$parent->organization][$parent->identifier]->datafromlms = addslashes($block['tagData']);\r
-                break;\r
-                case 'ADLCP:MASTERYSCORE':\r
-                    $parent = array_pop($parents);\r
-                    array_push($parents, $parent);\r
-                    $scoes->elements[$manifest][$parent->organization][$parent->identifier]->masteryscore = addslashes($block['tagData']);\r
-                break;\r
-                case 'ADLNAV:PRESENTATION':\r
-                    $parent = array_pop($parents);\r
-                    array_push($parents, $parent);\r
-                    foreach ($block['children'] as $adlnav) {\r
-                        if ($adlnav['name'] == 'ADLNAV:NAVIGATIONINTERFACE') {                                    //////fwrite($ft,$scoes->elements[$manifest][$parent->organization][$parent->identifier]->title."  Xuat hien dieu khien NAV \n");\r
-                            foreach ($adlnav['children'] as $adlnavInterface){\r
-                                if ($adlnavInterface['name'] == 'ADLNAV:HIDELMSUI'){\r
-                                //////fwrite($ft,$scoes->elements[$manifest][$parent->organization][$parent->identifier]->title."  Xuat hien dieu khien NAV HIDELMSUI\n");\r
-                                //////fwrite($ft," Gia tri thuoc tinh an la ".$adlnavInterface['tagData']);\r
-                                    if ($adlnavInterface['tagData'] == 'continue')    {\r
-                                    $scoes->elements[$manifest][$parent->organization][$parent->identifier]->next = 1; \r
-//                                    //////fwrite($ft," Thiet lap thuoc tinh an OK ");\r
-                                    }\r
-                                    if ($adlnavInterface['tagData'] == 'previous')    {\r
-                                    $scoes->elements[$manifest][$parent->organization][$parent->identifier]->previous = 1; \r
-//                                    //////fwrite($ft," Thiet lap thuoc tinh an OK ");\r
-                                    }\r
-                                }\r
-\r
-                            }\r
-\r
-                        }\r
-                    }\r
-                break;\r
-\r
-                case 'IMSSS:SEQUENCING':\r
-                    $parent = array_pop($parents);\r
-                    array_push($parents, $parent);\r
-                    foreach ($block['children'] as $sequencing) {\r
-                        //////fwrite($ft,"\n Xuat hien IMSSS:SEQUENCING cua ".$parent->identifier);\r
-                        if ($sequencing['name']=='IMSSS:CONTROLMODE'){\r
-                            //Xu ly cac Control Mode voi mot Item trong SCO\r
-                            if ($sequencing['attrs']['CHOICE'] == 'false'){\r
-                            $scoes->elements[$manifest][$parent->organization][$parent->identifier]->choice = 0;\r
-                            //////fwrite($ft,"\n Xuat hien lua chon choice  \n");\r
-                            }\r
-                            if ($sequencing['attrs']['CHOICEEXIT'] == 'false'){\r
-                            $scoes->elements[$manifest][$parent->organization][$parent->identifier]->choiceexit = 0;\r
-                            }\r
-                            if ($sequencing['attrs']['FLOW'] == 'true'){\r
-                            $scoes->elements[$manifest][$parent->organization][$parent->identifier]->flow = 1;\r
-                            }\r
-                            if ($sequencing['attrs']['FORWARDONLY'] == 'true'){\r
-                            $scoes->elements[$manifest][$parent->organization][$parent->identifier]->forwardonly = 1;\r
-                            }\r
-                            if ($sequencing['attrs']['USECURRENTATTEMPTOBJECTINFO'] == 'true'){\r
-                            $scoes->elements[$manifest][$parent->organization][$parent->identifier]->usecurrentattemptobjectinfo = 1;\r
-                            }\r
-                            if ($sequencing['attrs']['USECURRENTATTEMPTPROGRESSINFO'] == 'true'){\r
-                            $scoes->elements[$manifest][$parent->organization][$parent->identifier]->usecurrentattemptprogressinfo = 1;\r
-                            }\r
-                        }\r
-                        if ($sequencing['name']=='ADLSEQ:CONSTRAINEDCHOICECONSIDERATIONS'){\r
-                            //Xu ly cac dieu kien rang buoc thu tu \r
-                            if ($sequencing['attrs']['CONSTRAINCHOICE'] == 'true'){\r
-                            $scoes->elements[$manifest][$parent->organization][$parent->identifier]->constrainChoice = 1;\r
-                            }\r
-                            if ($sequencing['attrs']['PREVENTACTIVATION'] == 'true'){\r
-                            $scoes->elements[$manifest][$parent->organization][$parent->identifier]->preventactivation = 1;\r
-                            }\r
-\r
-                        }\r
-                        if ($sequencing['name']=='IMSSS:OBJECTIVES'){\r
-                            //Xu ly cac cac gia tri muc tieu\r
-                            foreach ($sequencing['children'] as $objective){\r
-                                if($objective['name']=='IMSSS:PRIMARYOBJECTIVE'){\r
-                                    //Xac dinh primary objective de lay thong so\r
-                                    foreach ($objective['children'] as $primaryobjective){\r
-                                        if($primaryobjective['name']=='IMSSS:MINNORMALIZEDMEASURE'){    $scoes->elements[$manifest][$parent->organization][$parent->identifier]->minnormalizedmeasure = $primaryobjective['tagData'];\r
-                                        }\r
-                                    }\r
-                                }\r
-                            }\r
-                        }\r
-                        if ($sequencing['name']=='IMSSS:LIMITCONDITIONS'){\r
-                            //Xu ly cac cac gia tri cac dieu kien gioi han\r
-                            if (!empty($sequencing['attrs']['ATTEMPTLIMIT'])){\r
-                                    $scoes->elements[$manifest][$parent->organization][$parent->identifier]->attemptLimit = $sequencing['attrs']['ATTEMPTLIMIT'];                                \r
-                            }\r
-                            if (!empty($sequencing['attrs']['ATTEMPTABSOLUTEDURATIONLIMIT'])){\r
-                                    $scoes->elements[$manifest][$parent->organization][$parent->identifier]->attemptAbsoluteDurationLimit = $sequencing['attrs']['ATTEMPTABSOLUTEDURATIONLIMIT'];                                \r
-                            }                            \r
-                        }                        \r
-                        if ($sequencing['name']=='IMSSS:ROLLUPRULES'){\r
-                            $rolluprules = array();\r
-                            //Phan danh cho RollupRule\r
-                            if (!empty($sequencing['attrs']['ROLLUPOBJECTIVESATISFIED'])){\r
-                                if ($sequencing['attrs']['ROLLUPOBJECTIVESATISFIED']== 'false'){\r
-                                    $scoes->elements[$manifest][$parent->organization][$parent->identifier]->rollupobjectivesatisfied = 0;                                \r
-                                }\r
-                            }\r
-                            if (!empty($sequencing['attrs']['ROLLUPPROGRESSCOMPLETION'])){\r
-                                if ($sequencing['attrs']['ROLLUPPROGRESSCOMPLETION']== 'false'){\r
-                                    $scoes->elements[$manifest][$parent->organization][$parent->identifier]->rollupprogresscompletion = 0;                                \r
-                                }\r
-                            }\r
-                            if (!empty($sequencing['attrs']['OBJECTIVEMEASUREWEIGHT'])){\r
-                                $scoes->elements[$manifest][$parent->organization][$parent->identifier]->objectivemeasureweight = $sequencing['attrs']['OBJECTIVEMEASUREWEIGHT'];                    \r
-                            }\r
-\r
-                            if (!empty($sequencing['children'])){\r
-                                foreach ($sequencing['children'] as $sequencingrolluprule){\r
-                                    if ($sequencingrolluprule['name']=='IMSSS:ROLLUPRULE' ){\r
-                                        $rolluprule = new stdClass();\r
-                                        if ($sequencingrolluprule['attrs']['CHILDACTIVITYSET'] !=' '){\r
-                                            $rolluprule->childactivityset = $sequencingrolluprule['attrs']['CHILDACTIVITYSET'];\r
-                                            ////fwrite($ft,"\n Thiet lap them 1 childActivitySet la ".$rolluprule->childactivityset);\r
-\r
-                                            //Phan xu ly danh sach condition\r
-                                            if (!empty($sequencingrolluprule['children'])){\r
-                                                foreach ($sequencingrolluprule['children'] as $rolluproleconditions)\r
-                                                {\r
-                                                    if ($rolluproleconditions['name']=='IMSSS:ROLLUPCONDITIONS'){\r
-                                                        $conditions = array();\r
-                                                        if (!empty($rolluproleconditions['attrs']['conditionCombination'])){\r
-                                                        $rolluprule->conditionCombination = $rolluproleconditions['attrs']['conditionCombination'];\r
-                                                        }\r
-                                                        foreach ($rolluproleconditions['children'] as $rolluprulecondition){\r
-                                                            if ($rolluprulecondition['name']=='IMSSS:ROLLUPCONDITION'){\r
-                                                                $condition = new stdClass();\r
-                                                                if (!empty($rolluprulecondition['attrs']['OPERATOR'])){\r
-                                                                    $condition->operator = $rolluprulecondition['attrs']['OPERATOR'];\r
-                                                                }\r
-                                                                if (!empty($rolluprulecondition['attrs']['CONDITION'])){\r
-                                                                    $condition->condition = $rolluprulecondition['attrs']['CONDITION'];\r
-                                                                }\r
-                                                            array_push($conditions,$condition);    \r
-                                                            ////fwrite($ft,"Da them mot rolluprulecondition");\r
-                                                            }\r
-\r
-                                                        }\r
-                                                    $rolluprule->conditions = $conditions;\r
-                                                    }\r
-                                                    if ($rolluproleconditions['name']=='IMSSS:ROLLUPACTION'){\r
-                                                    $rolluprule->rollupruleaction = $rolluproleconditions['attrs']['ACTION'];\r
-                                                    }\r
-                                                }\r
-                                            }\r
-                                            //Ket thuc xu ly danh sach condition\r
-\r
-                                        }\r
-                                        ////fwrite($ft,"\n Dua them 1 rule vao \n");\r
-                                        array_push($rolluprules, $rolluprule);\r
-                                        ////fwrite($ft,"\n Dua them 1 rule vao mang \n");\r
-                                    }\r
-\r
-                                }\r
-                            }\r
-                            $scoes->elements[$manifest][$parent->organization][$parent->identifier]->rolluprules = $rolluprules;\r
-\r
-//                            ////fwrite($ft,"\n >>>>NOW TEST ");\r
-//                            foreach ($scoes->elements[$manifest][$parent->organization][$parent->identifier]->rolluprules as $rolluptest){\r
-//                            ////fwrite($ft,"\n >>>> Gia tri Test thu duoc la:".$rolluptest->childactivityset);\r
-    \r
-                        }\r
-\r
-\r
-                        \r
-                        if ($sequencing['name']=='IMSSS:SEQUENCINGRULES'){\r
-                            //Xu ly cac dieu kien Rules cua Sequencing\r
-                            //////fwrite($ft,"\n Xuat hien SEQUENCINGRULES >>>>>>>>>>");                            \r
-                            $sequencingrules = array();\r
-                            foreach ($sequencing['children'] as $conditionrules){\r
-                                if($conditionrules['name']=='IMSSS:EXITCONDITIONRULE'){\r
-                                        $sequencingrule = new stdClass();\r
-                                        //Phan xu ly danh sach condition\r
-                                        //////fwrite($ft,"\n Xuat hien exitrule >>>>>>>>>>");\r
-                                        if (!empty($conditionrules['children'])){\r
-                                            foreach ($conditionrules['children'] as $conditionrule)\r
-                                            {\r
-                                                if ($conditionrule['name']=='IMSSS:RULECONDITIONS'){\r
-                                                    $ruleconditions = array();\r
-                                                    if (!empty($conditionrule['attrs']['conditionCombination'])){\r
-                                                    $sequencingrule->conditionCombination = $conditionrule['attrs']['conditionCombination'];\r
-                                                    }\r
-                                                    foreach ($conditionrule['children'] as $rulecondition){\r
-                                                        if ($rulecondition['name']=='IMSSS:RULECONDITION'){\r
-                                                            $condition = new stdClass();\r
-                                                            if (!empty($rulecondition['attrs']['OPERATOR'])){\r
-                                                                $condition->operator = $rulecondition['attrs']['OPERATOR'];\r
-                                                            }\r
-                                                            if (!empty($rulecondition['attrs']['CONDITION'])){\r
-                                                                $condition->condition = $rulecondition['attrs']['CONDITION'];\r
-                                                            }\r
-                                                            if (!empty($rulecondition['attrs']['MEASURETHRESHOLD'])){\r
-                                                                $condition->measurethreshold = $rulecondition['attrs']['MEASURETHRESHOLD'];\r
-                                                            }\r
-                                                            if (!empty($rulecondition['attrs']['REFERENCEDOBJECTIVE'])){\r
-                                                                $condition->referencedobjective = $rulecondition['attrs']['REFERENCEDOBJECTIVE'];\r
-                                                            }                                                                                                                        \r
-                                                        array_push($ruleconditions,$condition);    \r
-                                                        ////fwrite($ft,"\n Da them mot rulecondition trong exitrule");\r
-                                                        }\r
-\r
-                                                    }\r
-                                                $sequencingrule->ruleconditions = $ruleconditions;\r
-                                                }\r
-                                                if ($conditionrule['name']=='IMSSS:RULEACTION'){\r
-                                                $sequencingrule->exitconditionruleaction = $conditionrule['attrs']['ACTION'];\r
-                                                }\r
-                                            }\r
-                                        }\r
-                                        //Ket thuc xu ly danh sach condition\r
-                                array_push($sequencingrules,$sequencingrule);                                        \r
-                                }\r
-                                if ($conditionrules['name']=='IMSSS:PRECONDITIONRULE'){\r
-                                    $sequencingrule = new stdClass();\r
-                                    //Phan xu ly danh sach condition\r
-                                    if (!empty($conditionrules['children'])){\r
-                                        foreach ($conditionrules['children'] as $conditionrule)\r
-                                        {\r
-                                            if ($conditionrule['name']=='IMSSS:RULECONDITIONS'){\r
-                                                $ruleconditions = array();\r
-                                                if (!empty($conditionrule['attrs']['conditionCombination'])){\r
-                                                    $sequencingrule->conditionCombination = $conditionrule['attrs']['conditionCombination'];\r
-                                                }\r
-                                                foreach ($conditionrule['children'] as $rulecondition){\r
-                                                    if ($rulecondition['name']=='IMSSS:RULECONDITION'){\r
-                                                        $condition = new stdClass();\r
-                                                        if (!empty($rulecondition['attrs']['OPERATOR'])){\r
-                                                            $condition->operator = $rulecondition['attrs']['OPERATOR'];\r
-                                                        }\r
-                                                        if (!empty($rulecondition['attrs']['CONDITION'])){\r
-                                                            $condition->condition = $rulecondition['attrs']['CONDITION'];\r
-                                                        }\r
-                                                        if (!empty($rulecondition['attrs']['MEASURETHRESHOLD'])){\r
-                                                            $condition->measurethreshold = $rulecondition['attrs']['MEASURETHRESHOLD'];\r
-                                                        }\r
-                                                        if (!empty($rulecondition['attrs']['REFERENCEDOBJECTIVE'])){\r
-                                                            $condition->referencedobjective = $rulecondition['attrs']['REFERENCEDOBJECTIVE'];\r
-                                                        }                                                                                                                        \r
-                                                    array_push($ruleconditions,$condition);    \r
-                                                    ////fwrite($ft,"\n Da them mot rulecondition trong prerule");\r
-                                                    }\r
-\r
-                                                }\r
-                                            $sequencingrule->ruleconditions = $ruleconditions;\r
-                                            }\r
-                                            if ($conditionrule['name']=='IMSSS:RULEACTION'){\r
-                                            $sequencingrule->preconditionruleaction = $conditionrule['attrs']['ACTION'];\r
-                                            }\r
-                                        }\r
-                                    }\r
-                                    //Ket thuc xu ly danh sach condition\r
-                                array_push($sequencingrules,$sequencingrule);                                \r
-                                }\r
-                                if($conditionrules['name']=='IMSSS:POSTCONDITIONRULE'){\r
-                                        $sequencingrule = new stdClass();\r
-                                        //Phan xu ly danh sach condition\r
-                                        if (!empty($conditionrules['children'])){\r
-                                            foreach ($conditionrules['children'] as $conditionrule)\r
-                                            {\r
-                                                if ($conditionrule['name']=='IMSSS:RULECONDITIONS'){\r
-                                                    $ruleconditions = array();\r
-                                                    if (!empty($conditionrule['attrs']['conditionCombination'])){\r
-                                                    $sequencingrule->conditionCombination = $conditionrule['attrs']['conditionCombination'];\r
-                                                    }\r
-                                                    foreach ($conditionrule['children'] as $rulecondition){\r
-                                                        if ($rulecondition['name']=='IMSSS:RULECONDITION'){\r
-                                                            $condition = new stdClass();\r
-                                                            if (!empty($rulecondition['attrs']['OPERATOR'])){\r
-                                                                $condition->operator = $rulecondition['attrs']['OPERATOR'];\r
-                                                            }\r
-                                                            if (!empty($rulecondition['attrs']['CONDITION'])){\r
-                                                                $condition->condition = $rulecondition['attrs']['CONDITION'];\r
-                                                            }\r
-                                                            if (!empty($rulecondition['attrs']['MEASURETHRESHOLD'])){\r
-                                                                $condition->measurethreshold = $rulecondition['attrs']['MEASURETHRESHOLD'];\r
-                                                            }\r
-                                                            if (!empty($rulecondition['attrs']['REFERENCEDOBJECTIVE'])){\r
-                                                                $condition->referencedobjective = $rulecondition['attrs']['REFERENCEDOBJECTIVE'];\r
-                                                            }                                                                                                                        \r
-                                                        array_push($ruleconditions,$condition);    \r
-                                                        ////fwrite($ft,"\n Da them mot rulecondition trong postrule");\r
-                                                        }\r
-\r
-                                                    }\r
-                                                $sequencingrule->ruleconditions = $ruleconditions;\r
-                                                }\r
-                                                if ($conditionrule['name']=='IMSSS:RULEACTION'){\r
-                                                $sequencingrule->postconditionruleaction = $conditionrule['attrs']['ACTION'];\r
-                                                }\r
-                                            }\r
-                                        }\r
-                                        //Ket thuc xu ly danh sach condition\r
-                                array_push($sequencingrules,$sequencingrule);                                \r
-                                }\r
-                                $scoes->elements[$manifest][$parent->organization][$parent->identifier]->sequencingrules = $sequencingrules;                                \r
-                            }\r
-                        }\r
-                    }\r
-\r
-                break;\r
-\r
-            }\r
-        }\r
-    }\r
-\r
-    return $scoes;\r
-}\r
-\r
-function scorm_parse_scorm($pkgdir,$scormid) {\r
-    global $CFG;\r
-\r
-    //$f = "D:\\test.txt";\r
-    //@$ft = fopen($f,"a");\r
-    //////fwrite($ft,"\n Xu ly doc thong tin trong ham scorm_parse_scorm \n");\r
-    \r
-    $launch = 0;\r
-    $manifestfile = $pkgdir.'/imsmanifest.xml';\r
-\r
-    if (is_file($manifestfile)) {\r
-    \r
-        $xmlstring = file_get_contents($manifestfile);\r
-        $objXML = new xml2Array();\r
-        $manifests = $objXML->parse($xmlstring);\r
-            \r
-        $scoes = new stdClass();\r
-        $scoes->version = '';\r
-        $scoes = scorm_get_manifest($manifests,$scoes);\r
-\r
-        if (count($scoes->elements) > 0) {\r
-            foreach ($scoes->elements as $manifest => $organizations) {\r
-                foreach ($organizations as $organization => $items) {\r
-                    foreach ($items as $identifier => $item) {\r
-                        $item->scorm = $scormid;\r
-                        $item->manifest = $manifest;\r
-                        $item->organization = $organization;\r
-                        //////fwrite($ft,"\n ---- Item chuan bi dua vao la ".$item->identifier);\r
-                        $id = insert_record('scorm_scoes',$item);\r
-                        //////fwrite($ft,"\n Lay duoc ScoID la ".$id);\r
-                        $item->scormid = $scormid;\r
-                        $item->scoid = $id;\r
-                        $idControlMode = insert_record('scorm_sequencing_controlmode',$item);\r
-\r
-                        if (!empty($item->sequencingrules)){\r
-                            ////fwrite($ft,"\n ++++++++Them SequencingRules cho SCO: ".$item->scoid) ;\r
-                            foreach($item->sequencingrules as $sequencingrule){\r
-                                ////fwrite($ft,"\n ----Chuan bi them 1 sequencingrule vao CSDL: ");\r
-                                $sequencingrule->scormid = $scormid;\r
-                                $sequencingrule->scoid = $item->scoid;\r
-                                ////fwrite($ft,"\n ----Thong tin Scormid: ".$sequencingrule->scormid);                                                                                            \r
-                                ////fwrite($ft,"\n ----Thong tin Scoid: ".$sequencingrule->scoid);                                                                                                                            \r
-                                $idruleconditions = insert_record('scorm_sequencing_ruleconditions',$sequencingrule);\r
-                                foreach($sequencingrule->ruleconditions as $rulecondition){\r
-                                    $rulecondition->scormid = $sequencingrule->scormid;\r
-                                    $rulecondition->scoid = $sequencingrule->scoid;\r
-                                    $rulecondition->ruleconditionsid = $idruleconditions;\r
-                                    $idrulecondition = insert_record('scorm_sequencing_rulecondition',$rulecondition);\r
-                                    ////fwrite($ft,"\n ----Da them 1 sequencingrulecondition vao CSDL: ");                                    \r
-                                }\r
-                            \r
-                            }                        \r
-                        }\r
-                        \r
-                        if (!empty($item->rolluprules)){\r
-                            ////fwrite($ft,"\n ++++++++Them RollupRules cho SCO: ".$item->scoid) ;\r
-                            $idControlMode = insert_record('scorm_sequencing_rolluprules',$item);\r
-                            ////fwrite($ft,"\n ----Gia tri idRollupRules \n");\r
-                            foreach($item->rolluprules as $rollup)\r
-                            {\r
-                                ////fwrite($ft,"\n ----Chuan bi them 1 rule vao CSDL ");\r
-                                $rollup->rolluprulesid =$idControlMode;\r
-                                $rollup->scormid = $scormid;\r
-                                $rollup->scoid =  $item->scoid;\r
-\r
-                                ////fwrite($ft,"\n ----Cac thong tin cua Rule: \n ");\r
-                                ////fwrite($ft,"\n ----rolluprulesid:  ".$rollup->rolluprulesid);\r
-                                ////fwrite($ft,"\n ----scormid:  ".$rollup->scormid );\r
-                                ////fwrite($ft,"\n ----scoid:  ".$rollup->scoid);\r
-                                ////fwrite($ft,"\n ----activichild:  ".$rollup->childactivityset);\r
-                                ////fwrite($ft,"\n ----rollupaction:  ".$rollup->rollupruleaction);\r
-                                $idRollupRule = insert_record('scorm_sequencing_rolluprule',$rollup);\r
-                                ////fwrite($ft,"\n ----Dua them 1 rule vao CSDL -- Chuan bi them condition vao rule".$idRollupRule);\r
-                                $rollup->rollupruleid = $idRollupRule;\r
-                                $idconditions = insert_record('scorm_sequencing_rollupruleconditions',$rollup);\r
-                                ////fwrite($ft,"\n --Dua cac condition con vao CSDL");\r
-                                foreach($rollup->conditions as $condition){\r
-                                    $condition->ruleconditionsid = $idconditions;\r
-                                    $condition->scormid = $rollup->scormid;\r
-                                    $condition->scoid = $rollup->scoid;\r
-                                    $idcondition = insert_record('scorm_sequencing_rolluprulecondition',$condition);\r
-                                    ////fwrite($ft,"\n --Da dua them 1 condition vao CSDL");\r
-                                }\r
-                                                                \r
-                                \r
-                            }\r
-                        }\r
-                        if (($launch == 0) && ((empty($scoes->defaultorg)) || ($scoes->defaultorg == $identifier))) {\r
-                            $launch = $id;\r
-                        }\r
-                    }\r
-                }\r
-            }\r
-            set_field('scorm','version',$scoes->version,'id',$scormid);\r
-        }\r
-    } \r
-    \r
-    return $launch;\r
-}\r
-\r
-function scorm_course_format_display($user,$course) {\r
-    global $CFG;\r
-\r
-    $strupdate = get_string('update');\r
-    $strmodule = get_string('modulename','scorm');\r
-\r
-    echo '<div class="mod-scorm">';\r
-    if ($scorms = get_all_instances_in_course('scorm', $course)) {\r
-        // The module SCORM activity with the least id is the course  \r
-        $scorm = current($scorms);\r
-        if (! $cm = get_coursemodule_from_instance('scorm', $scorm->id, $course->id)) {\r
-            error("Course Module ID was incorrect");\r
-        }\r
-        $colspan = '';\r
-        $headertext = '<table width="100%"><tr><td class="title">'.get_string('name').': <b>'.format_string($scorm->name).'</b>';\r
-        if (isteacher($course->id, $user->id, true)) {\r
-            if (isediting($course->id)) {\r
-                // Display update icon\r
-                $path = $CFG->wwwroot.'/course';\r
-                $headertext .= '<span class="commands">'.\r
-                        '<a title="'.$strupdate.'" href="'.$path.'/mod.php?update='.$cm->id.'&amp;sesskey='.sesskey().'">'.\r
-                        '<img src="'.$CFG->pixpath.'/t/edit.gif" hspace="2" height="11" width="11" border="0" alt="'.$strupdate.'" /></a></span>';\r
-            }\r
-            $headertext .= '</td>';\r
-            // Display report link\r
-            $trackedusers = get_record('scorm_scoes_track', 'scormid', $scorm->id, '', '', '', '', 'count(distinct(userid)) as c');\r
-            if ($trackedusers->c > 0) {\r
-                $headertext .= '<td class="reportlink">'.\r
-                              '<a target="'.$CFG->framename.'" href="'.$CFG->wwwroot.'/mod/scorm/report.php?id='.$cm->id.'">'.\r
-                               get_string('viewallreports','scorm',$trackedusers->c).'</a>';\r
-            } else {\r
-                $headertext .= '<td class="reportlink">'.get_string('noreports','scorm');\r
-            }\r
-            $colspan = ' colspan="2"';\r
-        } \r
-        $headertext .= '</td></tr><tr><td'.$colspan.'>'.format_text(get_string('summary').':<br />'.$scorm->summary).'</td></tr></table>';\r
-        print_simple_box($headertext,'','100%');\r
-        scorm_view_display($user, $scorm, 'view.php?id='.$course->id, $cm, '100%');\r
-    } else {\r
-        if (isteacheredit($course->id, $user->id)) {\r
-            // Create a new activity\r
-            redirect('mod.php?id='.$course->id.'&amp;section=0&sesskey='.sesskey().'&amp;add=scorm');\r
-        } else {\r
-            notify('Could not find a scorm course here');\r
-        }\r
-    }\r
-    echo '</div>';\r
-}\r
-\r
-function scorm_view_display ($user, $scorm, $action, $cm, $blockwidth='') {\r
-    global $CFG;\r
-    $organization = optional_param('organization', '', PARAM_INT);\r
-\r
-    print_simple_box_start('center',$blockwidth);\r
-?>\r
-        <div class="structurehead"><?php print_string('coursestruct','scorm') ?></div>\r
-<?php\r
-    if (empty($organization)) {\r
-        $organization = $scorm->launch;\r
-    }\r
-    if ($orgs = get_records_select_menu('scorm_scoes',"scorm='$scorm->id' AND organization='' AND launch=''",'id','id,title')) {\r
-        if (count($orgs) > 1) {\r
- ?>\r
-            <div class='center'>\r
-                <?php print_string('organizations','scorm') ?>\r
-                <form name='changeorg' method='post' action='<?php echo $action ?>'>\r
-                    <?php choose_from_menu($orgs, 'organization', "$organization", '','submit()') ?>\r
-                </form>\r
-            </div>\r
-<?php\r
-        }\r
-    }\r
-    $orgidentifier = '';\r
-    if ($org = get_record('scorm_scoes','id',$organization)) {\r
-        if (($org->organization == '') && ($org->launch == '')) {\r
-            $orgidentifier = $org->identifier;\r
-        } else {\r
-            $orgidentifier = $org->organization;\r
-        }\r
-    }\r
-    $result = scorm_get_toc($user,$scorm,'structlist',$orgidentifier);\r
-    $incomplete = $result->incomplete;\r
-//    echo ("Toc ---");\r
-    echo $result->toc;\r
-//    echo ("Ket thuc");\r
-    print_simple_box_end();\r
-?>\r
-            <div class="center">\r
-                <form name="theform" method="post" action="<?php echo $CFG->wwwroot ?>/mod/scorm/player.php?id=<?php echo $cm->id ?>"<?php echo $scorm->popup == 1?' target="newwin"':'' ?>>\r
-              <?php\r
-\r
-// Thiet lap suspend\r
-            $suspend = get_record("scorm_suspendtrack","scormid",$scorm->id,"userid",$user->id);\r
-\r
-//------------------\r
-                  if ($scorm->hidebrowse == 0) {\r
-                      print_string("mode","scorm");\r
-                      echo ': <input type="radio" id="b" name="mode" value="browse" /><label for="b">'.get_string('browse','scorm').'</label>'."\n";\r
-                      if ($incomplete === true) {\r
-                          echo '<input type="radio" id="n" name="mode" value="normal" checked="checked" /><label for="n">'.get_string('normal','scorm')."</label>\n";\r
-                            \r
-                            //Neu co luu tru thi co the chon continue de tiep tu\r
-                          if (!empty($suspend))\r
-                          {\r
-                              echo '<input type="radio" id="n" name="mode" value="continue" checked="checked" /><label for="n">'.get_string('continue','scorm')."</label>\n";\r
-                          }\r
-\r
-                      } else {\r
-                          echo '<input type="radio" id="r" name="mode" value="review" checked="checked" /><label for="r">'.get_string('review','scorm')."</label>\n";\r
-                      }\r
-                  } else {\r
-                      if ($incomplete === true) {\r
-                          echo '<input type="hidden" name="mode" value="normal" />'."\n";\r
-                      } else {\r
-                          echo '<input type="hidden" name="mode" value="review" />'."\n";\r
-                      }\r
-                  }\r
-                  if (($incomplete === false) && (($result->attemptleft > 0)||($scorm->maxattempt == 0))) {\r
-?>\r
-                  <br />\r
-                  <input type="checkbox" id="a" name="newattempt" />\r
-                  <label for="a"><?php print_string('newattempt','scorm') ?></label>\r
-<?php\r
-                  }\r
-              ?>\r
-              <br />\r
-              <input type="hidden" name="scoid" />\r
-              <input type="hidden" name="currentorg" value="<?php echo $orgidentifier ?>" />\r
-              <input type="submit" value="<?php print_string('entercourse','scorm') ?>" />\r
-              </form>\r
-          </div>\r
-<?php\r
-}\r
-\r
-function scorm_update_status($scormid,$scoid)\r
-{\r
-    \r
-}\r
-\r
-\r
-function scorm_repeater($what, $times) {\r
-    if ($times <= 0) {\r
-        return null;\r
-    }\r
-    $return = '';\r
-    for ($i=0; $i<$times;$i++) {\r
-        $return .= $what;\r
-    }\r
-    return $return;\r
-}\r
-\r
-//chuyen toi SCO duoc thuc hien tiep theo\r
-function scorm_get_nextsco($scormid,$scoid)\r
-{\r
-\r
-\r
-\r
-}\r
-//Chuyen toi SCO duoc thuc hien truoc\r
-function scorm_get_presco($scormid,$scoid)\r
-{\r
-\r
-\r
-\r
-}\r
-//Xac dinh xem doi tuong do co cho phep lua chon khong\r
-function scorm_isChoice($scormid,$scoid)\r
-{\r
-//    //$f = "D:\\test.txt";\r
-//    //@$ft = fopen($f,"a");\r
-    $sco = get_record("scorm_sequencing_controlmode","scormid",$scormid,"scoid",$scoid);\r
-//    ////fwrite($ft,"\n Xu ly doc thong tin trong ham scorm_isChoice scormid la ".$scormid." scoid la: ".$scoid);\r
-    $scoparent = get_record("scorm_sequencing_controlmode","scormid",$scormid,"identifier",$sco->parent);\r
-//    ////fwrite($ft,"\n Xu ly doc thong tin trong ham scorm_isChoice scoparent scormid la ".$scormid." scoid la: ".$scoparent->scoid);\r
-\r
-\r
-//    ////fwrite($ft,"\n Xu ly doc thong tin trong ham scorm_isChoice gia tri la: ".$scoparent->choice);\r
-    return $scoparent->choice;\r
-}\r
-\r
-//Xac dinh xem doi tuong do co cho phep lua chon thoat khong\r
-function scorm_isChoiceexit($scormid,$scoid)\r
-{\r
-    $sco = get_record("scorm_sequencing_controlmode","scormid",$scormid,"scoid",$scoid);\r
-    $scoparent = get_record("scorm_sequencing_controlmode","scormid",$scormid,"identifier",$sco->parent);\r
-\r
-    return $scoparent->choiceexit;\r
-}\r
-/* Usage\r
- Grab some XML data, either from a file, URL, etc. however you want. Assume storage in $strYourXML;\r
-\r
- $objXML = new xml2Array();\r
- $arrOutput = $objXML->parse($strYourXML);\r
- print_r($arrOutput); //print it out, or do whatever!\r
-  \r
-*/\r
-class xml2Array {\r
-   \r
-   var $arrOutput = array();\r
-   var $resParser;\r
-   var $strXmlData;\r
-   \r
-   /**\r
-   * Convert a utf-8 string to html entities\r
-   *\r
-   * @param string $str The UTF-8 string\r
-   * @return string\r
-   */\r
-   function utf8_to_entities($str) {\r
-       $entities = '';\r
-       $values = array();\r
-       $lookingfor = 1;\r
-\r
-       for ($i = 0; $i < strlen($str); $i++) {\r
-           $thisvalue = ord($str[$i]);\r
-           if ($thisvalue < 128) {\r
-               $entities .= $str[$i]; // Leave ASCII chars unchanged \r
-           } else {\r
-               if (count($values) == 0) {\r
-                   $lookingfor = ($thisvalue < 224) ? 2 : 3;\r
-               }\r
-               $values[] = $thisvalue;\r
-               if (count($values) == $lookingfor) {\r
-                   $number = ($lookingfor == 3) ?\r
-                       (($values[0] % 16) * 4096) + (($values[1] % 64) * 64) + ($values[2] % 64):\r
-                       (($values[0] % 32) * 64) + ($values[1] % 64);\r
-                   $entities .= '&#' . $number . ';';\r
-                   $values = array();\r
-                   $lookingfor = 1;\r
-               }\r
-           }\r
-       }\r
-       return $entities;\r
-   }\r
-\r
-   /**\r
-   * Parse an XML text string and create an array tree that rapresent the XML structure\r
-   *\r
-   * @param string $strInputXML The XML string\r
-   * @return array\r
-   */\r
-   function parse($strInputXML) {\r
-           $this->resParser = xml_parser_create ('UTF-8');\r
-           xml_set_object($this->resParser,$this);\r
-           xml_set_element_handler($this->resParser, "tagOpen", "tagClosed");\r
-           \r
-           xml_set_character_data_handler($this->resParser, "tagData");\r
-       \r
-           $this->strXmlData = xml_parse($this->resParser,$strInputXML );\r
-           if(!$this->strXmlData) {\r
-               die(sprintf("XML error: %s at line %d",\r
-                           xml_error_string(xml_get_error_code($this->resParser)),\r
-                           xml_get_current_line_number($this->resParser)));\r
-           }\r
-                           \r
-           xml_parser_free($this->resParser);\r
-           \r
-           return $this->arrOutput;\r
-   }\r
-   \r
-   function tagOpen($parser, $name, $attrs) {\r
-       $tag=array("name"=>$name,"attrs"=>$attrs); \r
-       array_push($this->arrOutput,$tag);\r
-   }\r
-   \r
-   function tagData($parser, $tagData) {\r
-       if(trim($tagData)) {\r
-           if(isset($this->arrOutput[count($this->arrOutput)-1]['tagData'])) {\r
-               $this->arrOutput[count($this->arrOutput)-1]['tagData'] .= $this->utf8_to_entities($tagData);\r
-           } else {\r
-               $this->arrOutput[count($this->arrOutput)-1]['tagData'] = $this->utf8_to_entities($tagData);\r
-           }\r
-       }\r
-   }\r
-   \r
-   function tagClosed($parser, $name) {\r
-       $this->arrOutput[count($this->arrOutput)-2]['children'][] = $this->arrOutput[count($this->arrOutput)-1];\r
-       array_pop($this->arrOutput);\r
-   }\r
-\r
-}\r
-?>\r
+
+<?php  // $Id$
+define("VALUESCOES",0);
+define("VALUEHIGHEST",1);
+define("VALUEAVERAGE",2);
+define("VALUESUM",3);
+
+/// Local Library of functions and constants for module scorm
+
+/**
+* Create a new temporary subdirectory with a random name in the given path
+*
+* @param string $strpath The scorm data directory
+* @return string/boolean
+*/
+function scorm_datadir($strPath)
+{
+    global $CFG;
+
+    if (is_dir($strPath)) {
+        do {
+            // Create a random string of 8 chars
+            $randstring = NULL;
+            $lchar = '';
+            $len = 8;
+            for ($i=0; $i<$len; $i++) {
+                $char = chr(rand(48,122));
+                while (!ereg('[a-zA-Z0-9]', $char)){
+                    if ($char == $lchar) continue;
+                        $char = chr(rand(48,90));
+                    }
+                    $randstring .= $char;
+                    $lchar = $char;
+            } 
+            $datadir='/'.$randstring;
+        } while (file_exists($strPath.$datadir));
+        mkdir($strPath.$datadir, $CFG->directorypermissions);
+        @chmod($strPath.$datadir, $CFG->directorypermissions);  // Just in case mkdir didn't do it
+        return $strPath.$datadir;
+    } else {
+        return false;
+    }
+}
+
+/**
+* Given a package directory, this function will check if the package is valid
+*
+* @param string $packagedir The package directory
+* @return mixed
+*/
+function scorm_validate($packagedir) {
+
+    ////$f = "D:\\test.txt";
+    ////@$ft = fopen($f,"a");
+    ////fwrite($ft,"\n Xu ly trong ham scorm_validate \n");    
+
+
+    $validation = new stdClass();
+    if (is_file($packagedir.'/imsmanifest.xml')) {
+        $validation->result = 'found';
+        $validation->pkgtype = 'SCORM';
+    } else {
+        if ($handle = opendir($packagedir)) {
+            while (($file = readdir($handle)) !== false) {
+                $ext = substr($file,strrpos($file,'.'));
+                if (strtolower($ext) == '.cst') {
+                    $validation->result = 'found';
+                    $validation->pkgtype = 'AICC';
+                    break;
+                }
+            }
+            closedir($handle);
+        }
+        if (!isset($validation->result)) {
+            $validation->result = 'nomanifest';
+            $validation->pkgtype = 'SCORM';
+        }
+    }
+    return $validation;
+}
+
+function scorm_get_user_data($userid) {
+/// Gets user info required to display the table of scorm results
+/// for report.php
+
+    return get_record('user','id',$userid,'','','','','firstname, lastname, picture');
+}
+
+function scorm_string_wrap($stringa, $len=15) {
+// Crop the given string into max $len characters lines
+    $textlib = textlib_get_instance();
+    if ($textlib->strlen($stringa, current_charset()) > $len) {
+        $words = explode(' ', $stringa);
+        $newstring = '';
+        $substring = '';
+        foreach ($words as $word) {
+           if (($textlib->strlen($substring, current_charset())+$textlib->strlen($word, current_charset())+1) < $len) {
+               $substring .= ' '.$word;
+           } else {
+               $newstring .= ' '.$substring.'<br />';
+               $substring = $word;
+           }
+        }
+        if (!empty($substring)) {
+            $newstring .= ' '.$substring;
+        }
+        return $newstring;
+    } else {
+        return $stringa;
+    }
+}
+
+function scorm_eval_prerequisites($prerequisites,$usertracks) {
+
+    //$f = "D:\\test.txt";
+    //@$ft = fopen($f,"a");
+    ////fwrite($ft,"\n Xu ly trong ham scorm_eval_prerequisites \n");    
+
+
+    $element = '';
+    $stack = array();
+    $statuses = array(
+                'passed' => 'passed',
+                'completed' => 'completed',
+                'failed' => 'failed',
+                'incomplete' => 'incomplete',
+                'browsed' => 'browsed',
+                'not attempted' => 'notattempted',
+                'p' => 'passed',
+                'c' => 'completed',
+                'f' => 'failed',
+                'i' => 'incomplete',
+                'b' => 'browsed',
+                'n' => 'notattempted'
+                );
+    $i=0;  
+    while ($i<strlen($prerequisites)) {
+        $symbol = $prerequisites[$i];
+        switch ($symbol) {
+            case '&':
+            case '|':
+                $symbol .= $symbol;
+            case '~':
+            case '(':
+            case ')':
+            case '*':
+            //case '{':
+            //case '}':
+            //case ',':
+                $element = trim($element);
+                
+                if (!empty($element)) {
+                    $element = trim($element);
+                    if (isset($usertracks[$element])) {
+                        $element = '((\''.$usertracks[$element]->status.'\' == \'completed\') || '.
+                                  '(\''.$usertracks[$element]->status.'\' == \'passed\'))'; 
+                    } else if (($operator = strpos($element,'=')) !== false) {
+                        $item = trim(substr($element,0,$operator));
+                        if (!isset($usertracks[$item])) {
+                            return false;
+                        }
+                        
+                        $value = trim(trim(substr($element,$operator+1)),'"');
+                        if (isset($statuses[$value])) {
+                            $status = $statuses[$value];
+                        } else {
+                            return false;
+                        }
+                                              
+                        $element = '(\''.$usertracks[$item]->status.'\' == \''.$status.'\')';
+                    } else if (($operator = strpos($element,'<>')) !== false) {
+                        $item = trim(substr($element,0,$operator));
+                        if (!isset($usertracks[$item])) {
+                            return false;
+                        }
+                        
+                        $value = trim(trim(substr($element,$operator+2)),'"');
+                        if (isset($statuses[$value])) {
+                            $status = $statuses[$value];
+                        } else {
+                            return false;
+                        }
+                        
+                        $element = '(\''.$usertracks[$item]->status.'\' != \''.$status.'\')';
+                    } else if (is_numeric($element)) {
+                        if ($symbol == '*') {
+                            $symbol = '';
+                            $open = strpos($prerequisites,'{',$i);
+                            $opened = 1;
+                            $closed = 0;
+                            for ($close=$open+1; (($opened > $closed) && ($close<strlen($prerequisites))); $close++) { 
+                                 if ($prerequisites[$close] == '}') {
+                                     $closed++;
+                                 } else if ($prerequisites[$close] == '{') {
+                                     $opened++;
+                                 }
+                            } 
+                            $i = $close;
+                            
+                            $setelements = explode(',', substr($prerequisites, $open+1, $close-($open+1)-1));
+                            $settrue = 0;
+                            foreach ($setelements as $setelement) {
+                                if (scorm_eval_prerequisites($setelement,$usertracks)) {
+                                    $settrue++;
+                                }
+                            }
+                            
+                            if ($settrue >= $element) {
+                                $element = 'true'; 
+                            } else {
+                                $element = 'false';
+                            }
+                        }
+                    } else {
+                        return false;
+                    }
+                    
+                    array_push($stack,$element);
+                    $element = '';
+                }
+                if ($symbol == '~') {
+                    $symbol = '!';
+                }
+                if (!empty($symbol)) {
+                    array_push($stack,$symbol);
+                }
+            break;
+            default:
+                $element .= $symbol;
+            break;
+        }
+        $i++;
+    }
+    if (!empty($element)) {
+        $element = trim($element);
+        if (isset($usertracks[$element])) {
+            $element = '((\''.$usertracks[$element]->status.'\' == \'completed\') || '.
+                       '(\''.$usertracks[$element]->status.'\' == \'passed\'))'; 
+        } else if (($operator = strpos($element,'=')) !== false) {
+            $item = trim(substr($element,0,$operator));
+            if (!isset($usertracks[$item])) {
+                return false;
+            }
+            
+            $value = trim(trim(substr($element,$operator+1)),'"');
+            if (isset($statuses[$value])) {
+                $status = $statuses[$value];
+            } else {
+                return false;
+            }
+            
+            $element = '(\''.$usertracks[$item]->status.'\' == \''.$status.'\')';
+        } else if (($operator = strpos($element,'<>')) !== false) {
+            $item = trim(substr($element,0,$operator));
+            if (!isset($usertracks[$item])) {
+                return false;
+            }
+            
+            $value = trim(trim(substr($element,$operator+1)),'"');
+            if (isset($statuses[$value])) {
+                $status = $statuses[$value];
+            } else {
+                return false;
+            }
+            
+            $element = '(\''.$usertracks[$item]->status.'\' != \''.trim($status).'\')';
+        } else {
+            return false;
+        }
+        
+        array_push($stack,$element);
+    }
+    return eval('return '.implode($stack).';');
+}
+
+function scorm_insert_statistic($statisticInput){
+
+    $id = null;
+    if ($statistic = get_record_select('scorm_statistic',"userid='$statisticInput->userid' AND scormid='$statisticInput->scormid'")) {
+
+        $statistic->durationtime = $statisticInput->duration;
+        $statistic->accesstime = $statisticInput->accesstime;        
+        $statistic->status = $statisticInput->status;        
+        $statistic->attemptnumber = $statisticInput->attemptnumber;        
+        $id = update_record('scorm_statistic',$statistic);
+    } else {
+        ////fwrite($ft,"Insert trong ham scorm_insert_track \n");    
+        $id = insert_record('scorm_statistic',$statisticInput);
+    }
+    return $id;
+
+}
+function scorm_insert_track($userid,$scormid,$scoid,$attempt,$element,$value) {
+
+//    //$f = "D:\\test.txt";
+//    //@$ft = fopen($f,"a");
+    ////fwrite($ft,"\n Xu ly trong ham scorm_insert_track \n");    
+
+    $id = null;
+    if ($track = get_record_select('scorm_scoes_track',"userid='$userid' AND scormid='$scormid' AND scoid='$scoid' AND attempt='$attempt' AND element='$element'")) {
+        $track->value = $value;
+        $track->timemodified = time();
+        ////fwrite($ft,$userid."Update trong ham scorm_insert_track voi cac gia tri userid = ");    
+        $id = update_record('scorm_scoes_track',$track);
+    } else {
+        $track->userid = $userid;
+        $track->scormid = $scormid;
+        $track->scoid = $scoid;
+        $track->attempt = $attempt;
+        $track->element = $element;
+        $track->value = addslashes($value);
+        $track->timemodified = time();
+        ////fwrite($ft,"Insert trong ham scorm_insert_track \n");    
+        $id = insert_record('scorm_scoes_track',$track);
+    }
+    return $id;
+}
+
+function scorm_insert_trackmodel($userid,$scormid,$scoid,$attempt) {
+
+//    //$f = "D:\\test.txt";
+//    //@$ft = fopen($f,"a");
+
+    $id = null;
+    if ($suspendtrack = get_record_select('scorm_suspendtrack',"userid='$userid' AND scormid='$scormid'")) {
+        $suspendtrack->suspendscoid = $scoid;
+        $suspendtrack->attempt = $attempt;
+
+        $id = update_record('scorm_suspendtrack',$suspendtrack);
+    } else {
+        $suspendtrack->scormid = $scormid;
+        $suspendtrack->suspendscoid = $scoid;
+        $suspendtrack->userid = $userid;
+        $suspendtrack->attempt = $attempt;
+        $id = insert_record('scorm_suspendtrack',$suspendtrack);
+    }
+    return $id;
+}
+
+function scorm_get_suspendscoid($scormid,$userid) {
+    if ($sco = get_record("scorm_suspendtrack","scormid",$scormid,"userid",$userid)) {
+        $suspendscoid = $sco->suspendscoid;
+        return $suspendscoid;
+    } else {
+        return 0;
+    }
+}
+
+function scorm_add_time($a, $b) {
+    $aes = explode(':',$a);
+    $bes = explode(':',$b);
+    $aseconds = explode('.',$aes[2]);
+    $bseconds = explode('.',$bes[2]);
+    $change = 0;
+
+    $acents = 0;  //Cents
+    if (count($aseconds) > 1) {
+        $acents = $aseconds[1];
+    }
+    $bcents = 0;
+    if (count($bseconds) > 1) {
+        $bcents = $bseconds[1];
+    }
+    $cents = $acents + $bcents;
+    $change = floor($cents / 100);
+    $cents = $cents - ($change * 100);
+    if (floor($cents) < 10) {
+        $cents = '0'. $cents;
+    }
+
+    $secs = $aseconds[0] + $bseconds[0] + $change;  //Seconds
+    $change = floor($secs / 60);
+    $secs = $secs - ($change * 60);
+    if (floor($secs) < 10) {
+        $secs = '0'. $secs;
+    }
+
+    $mins = $aes[1] + $bes[1] + $change;   //Minutes
+    $change = floor($mins / 60);
+    $mins = $mins - ($change * 60);
+    if ($mins < 10) {
+        $mins = '0' .  $mins;
+    }
+
+    $hours = $aes[0] + $bes[0] + $change;  //Hours
+    if ($hours < 10) {
+        $hours = '0' . $hours;
+    }
+
+    if ($cents != '0') {
+        return $hours . ":" . $mins . ":" . $secs . '.' . $cents;
+    } else {
+        return $hours . ":" . $mins . ":" . $secs;
+    }
+}
+
+function scorm_external_link($link) {
+// check if a link is external
+    $result = false;
+    $link = strtolower($link);
+    if (substr($link,0,7) == 'http://') {
+        $result = true;
+    } else if (substr($link,0,8) == 'https://') {
+        $result = true;
+    } else if (substr($link,0,4) == 'www.') {
+        $result = true;
+    }
+    return $result;
+}
+
+function scorm_grade_user($scoes, $userid, $grademethod=VALUESCOES) {
+
+    //$f = "D:\\test.txt";
+    //@$ft = fopen($f,"a");
+    //fwrite($ft,"\n Xu ly trong ham scorm_grade_user \n");    
+
+    $scores = NULL; 
+    $scores->scoes = 0;
+    $scores->values = 0;
+    $scores->max = 0;
+    $scores->sum = 0;
+
+    if (!$scoes) {
+        return '';
+    }
+
+    $current = current($scoes);
+    $attempt = scorm_get_last_attempt($current->scorm, $userid);
+    foreach ($scoes as $sco) { 
+        if ($userdata=scorm_get_tracks($sco->id, $userid,$attempt)) {
+            if (($userdata->status == 'completed') || ($userdata->status == 'passed')) {
+                $scores->scoes++;
+            }       
+            if (!empty($userdata->score_raw)) {
+                $scores->values++;
+                $scores->sum += $userdata->score_raw;
+                $scores->max = ($userdata->score_raw > $scores->max)?$userdata->score_raw:$scores->max;
+            }       
+        }       
+    }
+    switch ($grademethod) {
+        case VALUEHIGHEST:
+            return $scores->max;
+        break;  
+        case VALUEAVERAGE:
+            if ($scores->values > 0) {
+                return $scores->sum/$scores->values;
+            } else {
+                return 0;
+            }       
+        break;  
+        case VALUESUM:
+            return $scores->sum;
+        break;  
+        case VALUESCOES:
+            return $scores->scoes;
+        break;  
+    }
+}
+
+//Lay diem theo Sco cha.. Thuc chat la theo bai kiem tra
+function scorm_get_score_from_parent($sco,$userid,$grademethod=VALUESCOES)
+{
+    
+    $scores = NULL; 
+    $scores->scoes = 0;
+    $scores->values = 0;
+    $scores->scaled = 0;
+    $scores->max = 0;
+    $scores->sum = 0;
+
+    $scoes_total = 0;
+    $scoes_count = 0;
+    $attempt = scorm_get_last_attempt($sco->scorm, $userid);
+    $scoes = get_records('scorm_scoes', 'parent', $sco->identifier);
+    foreach ($scoes as $sco)
+    {
+           $scoes_total++;
+           if ($userdata=scorm_get_tracks($sco->id, $userid,$attempt)) {
+               if (($userdata->status == 'completed') || ($userdata->success_status == 'passed')) {
+                    $scoes_count++;
+               }
+
+
+            $scoreraw = $userdata->score_raw; 
+
+            if (!empty($userdata->score_raw)) {
+                $scores->values++;
+                $scores->sum += $userdata->score_raw;
+                $scores->max = ($userdata->score_raw > $scores->max)?$userdata->score_raw:$scores->max;
+            }   
+            if (!empty($userdata->score_scaled)) {
+                $scores->scaled = $scores->scaled + $userdata->score_scaled;
+            }       
+            
+        }       
+    }
+    if ($scoes_count > 0)
+    {
+        $scores->scaled = ($scores->scaled)/($scoes_count);
+    }
+    switch ($grademethod) {
+        case VALUEHIGHEST:
+            return $scores->max;
+        break;  
+        case VALUEAVERAGE:
+            if ($scores->values > 0) {
+                return $scores->sum/$scores->values;
+            } else {
+                return 0;
+            }       
+        break;  
+        case VALUESUM:
+            return $scores->sum;
+        break;  
+        case VALUESCOES:
+            return $scores->scaled;
+        break;  
+    }
+
+}
+
+// Lay ra so luong cac scoes duoc user thuc hien xong
+function scorm_get_user_sco_count($scormid, $userid)
+{
+    $scoes_count = 0;
+    $attempt = scorm_get_last_attempt($current->scorm, $userid);
+    $scoes = get_records('scorm_scoes', 'scorm', $scormid);
+
+
+
+    foreach ($scoes as $sco)
+    {
+           if ($userdata=scorm_get_tracks($sco->id, $userid,$attempt)) {
+
+               if (($userdata->status == 'completed') || ($userdata->success_status == 'passed')) {
+                    $scoes_count++;
+               }
+           }
+
+    }
+    return $scoes_count;
+    
+}
+
+function scorm_grade_user_new($scoes, $userid, $grademethod=VALUESCOES) {
+
+    //$f = "D:\\test.txt";
+    //@$ft = fopen($f,"a");
+    //fwrite($ft,"\n Xu ly trong ham scorm_grade_user \n");    
+
+    $scores = NULL; 
+    $scores->scoes = 0;
+    $scores->values = 0;
+    $scores->scaled = 0;
+    $scores->max = 0;
+    $scores->sum = 0;
+
+    if (!$scoes) {
+        //fwrite($ft,"\n Khong xuat hien mot SCO duoc tinh diem \n");    
+        return '';
+    }
+
+    $current = current($scoes);
+    $attempt = scorm_get_last_attempt($current->scorm, $userid);
+    //fwrite($ft,"\n ---------------------------------------\n");    
+    foreach ($scoes as $sco) { 
+        if ($userdata=scorm_get_tracks($sco->id, $userid,$attempt)) {
+            if (($userdata->status == 'completed') || ($userdata->success_status == 'passed')) {
+                $scores->scoes++;
+                //fwrite($ft,"\n Them mot khoa hoan thanh co id la ".$sco->id." co gia tri scaled la ".$userdata->score_scaled." \n");    
+        
+            }  
+            $scaled = $userdata->score_scaled;
+            $scoreraw = $userdata->score_raw; 
+            if ($scaled ==0){
+                $scores->scaled = $scores->scaled / $scores->scoes;
+                //fwrite($ft,"\n Ti le chinh xac ".($scores->scaled*100)." phan tram");    
+
+            }
+
+            if (!empty($userdata->score_raw)) {
+                $scores->values++;
+                $scores->sum += $userdata->score_raw;
+                $scores->max = ($userdata->score_raw > $scores->max)?$userdata->score_raw:$scores->max;
+            }  
+                        
+            if (!empty($scaled)) {
+                //fwrite($ft,"\n go ---->>> \n");    
+                $scores->scaled = (($scores->scaled) * ($scores->scoes-1) + $scaled)/($scores->scoes);
+                //fwrite($ft,"\n Ti le chinh xac ".($scores->scaled*100)." phan tram");    
+
+            }       
+            
+        }       
+    }
+    //fwrite($ft,"\n ----+++++++++++------\n");    
+    //fwrite($ft,"\n Kieu gia tri tra ve la  ".$grademethod);    
+    switch ($grademethod) {
+        case VALUEHIGHEST:
+            //fwrite($ft,"\n Gia tri tra ve thouoc loai cao nhat");    
+            return $scores->max;
+        break;  
+        case VALUEAVERAGE:
+            //fwrite($ft,"\n Gia tri tra ve thouoc loai trung binh");    
+            if ($scores->values > 0) {
+                return $scores->sum/$scores->values;
+            } else {
+                return 0;
+            }       
+        break;  
+        case VALUESUM:
+            //fwrite($ft,"\n Gia tri tra ve thouoc loai tong cong");    
+            return $scores->sum;
+        break;  
+        case VALUESCOES:
+            //fwrite($ft,"\n Gia tri tra ve thouoc loai scoes co gia tri".$scores->scaled);    
+            return $scores->scaled;
+        break;  
+    }
+}
+
+function scorm_count_launchable($scormid,$organization) {
+    return count_records_select('scorm_scoes',"scorm=$scormid AND organization='$organization' AND launch<>''");
+}
+
+function scorm_get_toc($user,$scorm,$liststyle,$currentorg='',$scoid='',$mode='normal',$attempt='',$play=false) {
+    global $CFG;
+
+    //$f = "D:\\test.txt";
+    //@$ft = fopen($f,"a");
+    //fwrite($ft,"\n Xu ly trong ham scorm_get_toc \n");    
+
+    //
+    $suspendscoid = scorm_get_suspendscoid($scorm->id,$user->id);
+    //
+
+    $strexpand = get_string('expcoll','scorm');
+    $modestr = '';
+    if ($mode == 'browse') {
+        $modestr = '&amp;mode='.$mode;
+    } 
+    $scormpixdir = $CFG->modpixpath.'/scorm/pix';
+    
+    $result = new stdClass();
+    $result->toc = "<ul id='0' class='$liststyle'>\n";
+    $tocmenus = array();
+    $result->prerequisites = true;
+    $incomplete = false;
+    
+    //
+    // Get the current organization infos
+    //
+    $organizationsql = '';
+    if (!empty($currentorg)) {
+        if (($organizationtitle = get_field('scorm_scoes','title','scorm',$scorm->id,'identifier',$currentorg)) != '') {
+            $result->toc .= "\t<li>$organizationtitle</li>\n";
+            $tocmenus[] = $organizationtitle;
+        }
+        $organizationsql = "AND organization='$currentorg'";
+    }
+    //
+    // If not specified retrieve the last attempt number
+    //
+    if (empty($attempt)) {
+        $attempt = scorm_get_last_attempt($scorm->id, $user->id);
+    }
+    $result->attemptleft = $scorm->maxattempt - $attempt;
+
+    //fwrite($ft,"\n So lan attempt con lai la \n".$result->attemptleft);    
+    
+    if ($scoes = get_records_select('scorm_scoes',"scorm='$scorm->id' $organizationsql order by id ASC")){
+        //
+        // Lay du lieu da duoc tracking cho moi doi tuong hoc tap
+        // 
+        $usertracks = array();
+        foreach ($scoes as $sco) {
+            //Kiem tra xem $sco co phai la phan muc khong. Neu la trang Asset hoac SCO thi xu ly tiep
+            if (!empty($sco->launch)) {
+                if ($usertrack=scorm_get_tracks($sco->id,$user->id,$attempt)) {
+                    if ($usertrack->status == '') {
+                        $usertrack->status = 'notattempted';
+                    }
+                    // Ghi lai thong tin $usertracks theo tung doi tuong sco
+                    $usertracks[$sco->identifier] = $usertrack;
+                }
+            }
+        }
+
+        $level=0;
+        $sublist=1;
+        $previd = 0;
+        $nextid = 0;
+        $findnext = false;
+        $parents[$level]='/';
+        
+        foreach ($scoes as $sco) {
+            if ($parents[$level]!=$sco->parent) {
+                if ($newlevel = array_search($sco->parent,$parents)) {
+                    for ($i=0; $i<($level-$newlevel); $i++) {
+                        $result->toc .= "\t\t</ul></li>\n";
+                    }
+                    $level = $newlevel;
+                } else {
+                    $i = $level;
+                    $closelist = '';
+                    while (($i > 0) && ($parents[$level] != $sco->parent)) {
+                        $closelist .= "\t\t</ul></li>\n";
+                        $i--;
+                    }
+                    if (($i == 0) && ($sco->parent != $currentorg)) {
+                        $style = '';
+                        if (isset($_COOKIE['hide:SCORMitem'.$sco->id])) {
+                            $style = ' style="display: none;"';
+                        }
+                        $result->toc .= "\t\t<li><ul id='$sublist' class='$liststyle'$style>\n";
+                        $level++;
+                    } else {
+                        $result->toc .= $closelist;
+                        $level = $i;
+                    }
+                    $parents[$level]=$sco->parent;
+                }
+            }
+            $result->toc .= "\t\t<li>";
+            $nextsco = next($scoes);
+            if (($nextsco !== false) && ($sco->parent != $nextsco->parent) && (($level==0) || (($level>0) && ($nextsco->parent == $sco->identifier)))) {
+                $sublist++;
+                $icon = 'minus';
+                if (isset($_COOKIE['hide:SCORMitem'.$nextsco->id])) {
+                    $icon = 'plus';
+                }
+                $result->toc .= '<a href="javascript:expandCollide(img'.$sublist.','.$sublist.','.$nextsco->id.');"><img id="img'.$sublist.'" src="'.$scormpixdir.'/'.$icon.'.gif" alt="'.$strexpand.'" title="'.$strexpand.'"/></a>';
+            } else {
+                $result->toc .= '<img src="'.$scormpixdir.'/spacer.gif" />';
+            }
+            if (empty($sco->title)) {
+                $sco->title = $sco->identifier;
+            }
+            if (!empty($sco->launch)) {
+                $startbold = '';
+                $endbold = '';
+                $score = '';
+                if (empty($scoid) && ($mode != 'normal')) {
+                    $scoid = $sco->id;
+                }
+                //Neu la sco suspend thi hien thi anh khac
+                if ($suspendscoid == $sco->id){
+                    $result->toc .= '<img src="'.$scormpixdir.'/suspend.gif" alt="Dang tam dung o day" title="Dang dung o day" />';                
+                } else {
+                //-----------------------
+                    if (isset($usertracks[$sco->identifier])) {
+                        $usertrack = $usertracks[$sco->identifier];
+                        $strstatus = get_string($usertrack->status,'scorm');
+                        $result->toc .= '<img src="'.$scormpixdir.'/'.$usertrack->status.'.gif" alt="'.$strstatus.'" title="'.$strstatus.'" />';
+                        
+                        if (($usertrack->status == 'notattempted') || ($usertrack->status == 'incomplete') || ($usertrack->status == 'browsed')) {
+                            //Neu khoa hoc chua duoc attempted hoac chua hoan thanh hoac la chi browsed
+                            $incomplete = true;
+                            if ($play && empty($scoid)) {
+                                $scoid = $sco->id;
+                            }
+                        }
+                        if ($usertrack->score_raw != '') {
+                            $score = '('.get_string('score','scorm').':&nbsp;'.$usertrack->score_raw.')';
+                        }
+                    } else {
+                        if ($play && empty($scoid)) {
+                            $scoid = $sco->id;
+                        }
+                        if ($sco->scormtype == 'sco') {
+                            $result->toc .= '<img src="'.$scormpixdir.'/notattempted.gif" alt="'.get_string('notattempted','scorm').'" title="'.get_string('notattempted','scorm').'" />';
+                            $incomplete = true;
+                        } else {
+                            $result->toc .= '<img src="'.$scormpixdir.'/asset.gif" alt="'.get_string('asset','scorm').'" title="'.get_string('asset','scorm').'" />';
+                        }
+                    }
+                }
+                if ($sco->id == $scoid) {
+                    $startbold = '<b>';
+                    $endbold = '</b>';
+                    $findnext = true;
+                    $shownext = $sco->next;
+                    $showprev = $sco->previous;
+                }
+                
+                if (($nextid == 0) && (scorm_count_launchable($scorm->id,$currentorg) > 1) && ($nextsco!==false) && (!$findnext)) {
+                    if (!empty($sco->launch)) {
+                        $previd = $sco->id;
+                    }
+                }
+                if (empty($sco->prerequisites) || scorm_eval_prerequisites($sco->prerequisites,$usertracks)) {
+                    if ($sco->id == $scoid) {
+                        $result->prerequisites = true;
+                    }
+                    if (scorm_isChoice($scorm->id,$sco->id) == 1)
+                    {
+                    $url = $CFG->wwwroot.'/mod/scorm/player.php?a='.$scorm->id.'&amp;currentorg='.$currentorg.$modestr.'&amp;scoid='.$sco->id;
+                    $result->toc .= '&nbsp;'.$startbold.'<a href="'.$url.'">'.format_string($sco->title).'</a>'.$score.$endbold."</li>\n";
+                    $tocmenus[$sco->id] = scorm_repeater('&minus;',$level) . '&gt;' . format_string($sco->title);
+                    }
+                    else
+                    {
+                    $result->toc .= '&nbsp;'.$startbold.format_string($sco->title).$score.$endbold."</li>\n";
+                    $tocmenus[$sco->id] = scorm_repeater('&minus;',$level) . '&gt;' . format_string($sco->title);                    
+                    }
+                } else {
+                    if ($sco->id == $scoid) {
+                        $result->prerequisites = false;
+                    }
+                    $result->toc .= '&nbsp;'.$sco->title."</li>\n";
+                }
+            } else {
+                $result->toc .= '&nbsp;'.$sco->title."</li>\n";
+            }
+            if (($nextsco !== false) && ($nextid == 0) && ($findnext)) {
+                if (!empty($nextsco->launch)) {
+                    $nextid = $nextsco->id;
+                }
+            }
+        }
+        for ($i=0;$i<$level;$i++) {
+            $result->toc .= "\t\t</ul></li>\n";
+        }
+        
+        if ($play) {
+            $sco = get_record('scorm_scoes','id',$scoid);
+            $sco->previd = $previd;
+            $sco->nextid = $nextid;
+            $result->sco = $sco;
+            $result->incomplete = $incomplete;
+        } else {
+            $result->incomplete = $incomplete;
+        }
+    }
+    $result->toc .= "\t</ul>\n";
+    if ($scorm->hidetoc == 0) {
+        $result->toc .= '
+          <script language="javascript" type="text/javascript">
+          <!--
+              function expandCollide(which,list,item) {
+                  var nn=document.ids?true:false
+                  var w3c=document.getElementById?true:false
+                  var beg=nn?"document.ids.":w3c?"document.getElementById(":"document.all.";
+                  var mid=w3c?").style":".style";
+
+                  if (eval(beg+list+mid+".display") != "none") {
+                      which.src = "'.$scormpixdir.'/plus.gif";
+                      eval(beg+list+mid+".display=\'none\';");
+                      new cookie("hide:SCORMitem" + item, 1, 356, "/").set();
+                  } else {
+                      which.src = "'.$scormpixdir.'/minus.gif";
+                      eval(beg+list+mid+".display=\'block\';");
+                      new cookie("hide:SCORMitem" + item, 1, -1, "/").set();
+                  }
+              }
+          -->
+          </script>'."\n";
+    }
+    
+    $url = $CFG->wwwroot.'/mod/scorm/player.php?a='.$scorm->id.'&amp;currentorg='.$currentorg.$modestr.'&amp;scoid=';
+    $result->tocmenu = popup_form($url,$tocmenus, "tocmenu", $sco->id, '', '', '', true);
+
+    return $result;
+}
+
+function scorm_get_last_attempt($scormid, $userid) {
+
+    //$f = "D:\\test.txt";
+    //@$ft = fopen($f,"a");
+    ////fwrite($ft,"\n Xu ly trong ham scorm_get_last_attempt \n");    
+
+/// Find the last attempt number for the given user id and scorm id
+    if ($lastattempt = get_record('scorm_scoes_track', 'userid', $userid, 'scormid', $scormid, '', '', 'max(attempt) as a')) {
+        if (empty($lastattempt->a)) {
+            return '1';
+        } else {
+            return $lastattempt->a;
+        }
+    }
+}
+
+// Khi mot nguoi truy nhap vao mot SCO thi se thiet lap
+// nguoi do da no luc thuc hien no
+function scorm_set_attempt($scoid,$userid)
+{
+    //Lay gia tri last attempt
+    if ($scormid = get_field('scorm_scoes','scorm','id',$scoid)) {
+        $attempt = scorm_get_last_attempt($scormid,$userid);
+    } else {
+        $attempt = 1;
+    }
+    //Chi set attempt cho cac SCO
+    $scormtype = get_field('scorm_scoes','scormtype','id',$scoid) ;
+    if ($scormtype == 'sco'){
+        $element = 'cmi.attempt_status';
+        $value = 'attempted';
+        scorm_insert_track($userid,$scormid,$scoid,$attempt,$element,$value);
+    }
+}
+function scorm_get_tracks($scoid,$userid,$attempt='') {
+
+    //$f = "D:\\test.txt";
+    //@$ft = fopen($f,"a");
+    ////fwrite($ft,"\n Xu ly trong ham scorm_get_tracks \n");    
+
+/// Gets all tracks of specified sco and user
+    global $CFG;
+
+    if (empty($attempt)) {
+        if ($scormid = get_field('scorm_scoes','scorm','id',$scoid)) {
+            $attempt = scorm_get_last_attempt($scormid,$userid);
+        } else {
+            $attempt = 1;
+        }
+    }
+    $attemptsql = ' AND attempt=' . $attempt;
+    if ($tracks = get_records_select('scorm_scoes_track',"userid=$userid AND scoid=$scoid".$attemptsql,'element ASC')) {
+        $usertrack->userid = $userid;
+        $usertrack->scoid = $scoid; 
+        $usertrack->score_raw = '';
+        $usertrack->score_scaled = '';
+        $usertrack->status = '';
+        $usertrack->success_status = '';
+        $usertrack->attempt_status = '';
+        $usertrack->satisfied_status = '';
+        $usertrack->total_time = '00:00:00';
+        $usertrack->session_time = '00:00:00';
+        $usertrack->timemodified = 0;
+        foreach ($tracks as $track) {
+            $element = $track->element;
+            $usertrack->{$element} = $track->value;
+            switch ($element) {
+                case 'cmi.core.lesson_status':
+                case 'cmi.attempt_status':
+                    $usertrack->status = $track->value;
+                    $usertrack->attempt_status = $track->value;                    
+                break;                
+                case 'cmi.completion_status':
+                    if ($track->value == 'not attempted') {
+                        $track->value = 'notattempted';
+                        $usertrack->attempt_status = $track->value;
+                    }       
+                    $usertrack->status = $track->value;
+                break;  
+                case 'cmi.success_status':
+                    $usertrack->success_status = $track->value;
+                    if ($track->value=='passed'){
+                        $usertrack->satisfied_status = 'satisfied';                    
+                    }
+                    if ($track->value=='failed'){
+                        $usertrack->satisfied_status = 'notSatisfied';                    
+                    }                    
+                break;
+                case 'cmi.core.score.raw':
+                case 'cmi.score.raw':
+                    $usertrack->score_raw = $track->value;
+                break;  
+                case 'cmi.score.scaled':
+                    $usertrack->score_scaled = $track->value;
+                break;  
+                case 'cmi.core.session_time':
+                case 'cmi.session_time':
+                    $usertrack->session_time = $track->value;
+                break;  
+                case 'cmi.core.total_time':
+                case 'cmi.total_time':
+                    $usertrack->total_time = $track->value;
+                break;  
+            }       
+            if (isset($track->timemodified) && ($track->timemodified > $usertrack->timemodified)) {
+                $usertrack->timemodified = $track->timemodified;
+            }       
+        }       
+        return $usertrack;
+    } else {
+        return false;
+    }
+}
+
+
+function scorm_get_AbsoluteTimeLimit($scoid){
+    $sco = get_record("scorm_scoes","id",$scoid);
+    if (!empty($sco)){
+        return $sco->attemptAbsoluteDurationLimit;
+    }
+    return 0;
+}
+//-----------------------------------------------------
+/// Library of functions and constants for parsing packages
+
+function scorm_parse($scorm) {
+    global $CFG;
+
+    //$f = "D:\\test.txt";
+    //@$ft = fopen($f,"a");
+    ////fwrite($ft,"\n Xu ly doc thong tin trong ham scorm_parse \n");
+
+    // Parse scorm manifest
+    if ($scorm->pkgtype == 'AICC') {
+        $scorm->launch = scorm_parse_aicc($scorm->dir.'/'.$scorm->id,$scorm->id);
+    } else {
+        if (basename($scorm->reference) != 'imsmanifest.xml') {
+            $scorm->launch = scorm_parse_scorm($scorm->dir.'/'.$scorm->id,$scorm->id);
+        } else {
+            $scorm->launch = scorm_parse_scorm($CFG->dataroot.'/'.$scorm->course.'/'.dirname($scorm->reference),$scorm->id);
+        }
+    }
+
+    return $scorm->launch;
+}
+
+/**
+* Take the header row of an AICC definition file
+* and returns sequence of columns and a pointer to
+* the sco identifier column.
+*
+* @param string $row AICC header row
+* @param string $mastername AICC sco identifier column
+* @return mixed
+*/
+function scorm_get_aicc_columns($row,$mastername='system_id') {
+    $tok = strtok(strtolower($row),"\",\n\r");
+    $result->columns = array();
+    $i=0;
+    while ($tok) {
+        if ($tok !='') {
+            $result->columns[] = $tok;
+            if ($tok == $mastername) {
+                $result->mastercol = $i;
+            }
+            $i++;
+        }
+        $tok = strtok("\",\n\r");
+    }
+    return $result;
+}
+
+/**
+* Given a colums array return a string containing the regular
+* expression to match the columns in a text row.
+*
+* @param array $column The header columns
+* @param string $remodule The regular expression module for a single column
+* @return string
+*/
+function scorm_forge_cols_regexp($columns,$remodule='(".*")?,') {
+    $regexp = '/^';
+    foreach ($columns as $column) {
+        $regexp .= $remodule;
+    }
+    $regexp = substr($regexp,0,-1) . '/';
+    return $regexp;
+}
+
+function scorm_parse_aicc($pkgdir,$scormid){
+    
+    //$f = "D:\\test.txt";
+    //@$ft = fopen($f,"a");
+    ////fwrite($ft,"\n Xu ly doc thong tin trong ham scorm_parse_aicc \n");    
+    
+    $version = 'AICC';
+    $ids = array();
+    $courses = array();
+    if ($handle = opendir($pkgdir)) {
+        while (($file = readdir($handle)) !== false) {
+            $ext = substr($file,strrpos($file,'.'));
+            $extension = strtolower(substr($ext,1));
+            $id = strtolower(basename($file,$ext));
+            $ids[$id]->$extension = $file;
+        }
+        closedir($handle);
+    }
+    foreach ($ids as $courseid => $id) {
+        if (isset($id->crs)) {
+            if (is_file($pkgdir.'/'.$id->crs)) {
+                $rows = file($pkgdir.'/'.$id->crs);
+                foreach ($rows as $row) {
+                    if (preg_match("/^(.+)=(.+)$/",$row,$matches)) {
+                        switch (strtolower(trim($matches[1]))) {
+                            case 'course_id':
+                                $courses[$courseid]->id = trim($matches[2]);
+                            break;
+                            case 'course_title':
+                                $courses[$courseid]->title = trim($matches[2]);
+                            break;
+                            case 'version':
+                                $courses[$courseid]->version = 'AICC_'.trim($matches[2]);
+                            break;
+                        }
+                    }
+                }
+            }
+        }
+        if (isset($id->des)) {
+            $rows = file($pkgdir.'/'.$id->des);
+            $columns = scorm_get_aicc_columns($rows[0]);
+            $regexp = scorm_forge_cols_regexp($columns->columns);
+            for ($i=1;$i<count($rows);$i++) {
+                if (preg_match($regexp,$rows[$i],$matches)) {
+                    for ($j=0;$j<count($columns->columns);$j++) {
+                        $column = $columns->columns[$j];
+                        $courses[$courseid]->elements[substr(trim($matches[$columns->mastercol+1]),1,-1)]->$column = substr(trim($matches[$j+1]),1,-1);
+                    }
+                }
+            }
+        }
+        if (isset($id->au)) {
+            $rows = file($pkgdir.'/'.$id->au);
+            $columns = scorm_get_aicc_columns($rows[0]);
+            $regexp = scorm_forge_cols_regexp($columns->columns);
+            for ($i=1;$i<count($rows);$i++) {
+                if (preg_match($regexp,$rows[$i],$matches)) {
+                    for ($j=0;$j<count($columns->columns);$j++) {
+                        $column = $columns->columns[$j];
+                        $courses[$courseid]->elements[substr(trim($matches[$columns->mastercol+1]),1,-1)]->$column = substr(trim($matches[$j+1]),1,-1);
+                    }
+                }
+            }
+        }
+        if (isset($id->cst)) {
+            $rows = file($pkgdir.'/'.$id->cst);
+            $columns = scorm_get_aicc_columns($rows[0],'block');
+            $regexp = scorm_forge_cols_regexp($columns->columns,'(.+)?,');
+            for ($i=1;$i<count($rows);$i++) {
+                if (preg_match($regexp,$rows[$i],$matches)) {
+                    for ($j=0;$j<count($columns->columns);$j++) {
+                        if ($j != $columns->mastercol) {
+                            $courses[$courseid]->elements[substr(trim($matches[$j+1]),1,-1)]->parent = substr(trim($matches[$columns->mastercol+1]),1,-1);
+                        }
+                    }
+                }
+            }
+        }
+        if (isset($id->ort)) {
+            $rows = file($pkgdir.'/'.$id->ort);
+        }
+        if (isset($id->pre)) {
+            $rows = file($pkgdir.'/'.$id->pre);
+            $columns = scorm_get_aicc_columns($rows[0],'structure_element');
+            $regexp = scorm_forge_cols_regexp($columns->columns,'(.+),');
+            for ($i=1;$i<count($rows);$i++) {
+                if (preg_match($regexp,$rows[$i],$matches)) {
+                    $courses[$courseid]->elements[$columns->mastercol+1]->prerequisites = substr(trim($matches[1-$columns->mastercol+1]),1,-1);
+                }
+            }
+        }
+        if (isset($id->cmp)) {
+            $rows = file($pkgdir.'/'.$id->cmp);
+        }
+    }
+    //print_r($courses);
+    $launch = 0;
+    if (isset($courses)) {
+        foreach ($courses as $course) {
+            unset($sco);
+            $sco->identifier = $course->id;
+            $sco->scorm = $scormid;
+            $sco->organization = '';
+            $sco->title = $course->title;
+            $sco->parent = '/';
+            $sco->launch = '';
+            $sco->scormtype = '';
+            //print_r($sco);
+            $id = insert_record('scorm_scoes',$sco);
+            if ($launch == 0) {
+                $launch = $id;
+            }
+            if (isset($course->elements)) {
+                foreach($course->elements as $element) {
+                    unset($sco);
+                    $sco->identifier = $element->system_id;
+                    $sco->scorm = $scormid;
+                    $sco->organization = $course->id;
+                    $sco->title = $element->title;
+                    if (strtolower($element->parent) == 'root') {
+                        $sco->parent = '/';
+                    } else {
+                        $sco->parent = $element->parent;
+                    }
+                    if (isset($element->file_name)) {
+                        $sco->launch = $element->file_name;
+                        $sco->scormtype = 'sco';
+                    } else {
+                        $element->file_name = '';
+                        $sco->scormtype = '';
+                    }
+                    if (!isset($element->prerequisites)) {
+                        $element->prerequisites = '';
+                    }
+                    $sco->prerequisites = $element->prerequisites;
+                    if (!isset($element->max_time_allowed)) {
+                        $element->max_time_allowed = '';
+                    }
+                    $sco->maxtimeallowed = $element->max_time_allowed;
+                    if (!isset($element->time_limit_action)) {
+                        $element->time_limit_action = '';
+                    }
+                    $sco->timelimitaction = $element->time_limit_action;
+                    if (!isset($element->mastery_score)) {
+                        $element->mastery_score = '';
+                    }
+                    $sco->masteryscore = $element->mastery_score;
+                    $sco->previous = 0;
+                    $sco->next = 0;
+                    $id = insert_record('scorm_scoes',$sco);
+                    if ($launch==0) {
+                        $launch = $id;
+                    }
+                }
+            }
+        }
+    }
+    set_field('scorm','version','AICC','id',$scormid);
+    return $launch;
+}
+
+function scorm_get_resources($blocks) {
+
+    //$f = "D:\\test.txt";
+    //@$ft = fopen($f,"a");
+    ////fwrite($ft,"\n Xu ly trong ham scorm_get_resources \n");    
+
+    foreach ($blocks as $block) {
+        if ($block['name'] == 'RESOURCES') {
+            foreach ($block['children'] as $resource) {
+                if ($resource['name'] == 'RESOURCE') {
+                    $resources[addslashes($resource['attrs']['IDENTIFIER'])] = $resource['attrs'];
+                }
+            }
+        }
+    }
+    return $resources;
+}
+
+function scorm_get_manifest($blocks,$scoes) {
+
+    //$f = "D:\\test.txt";
+    //@$ft = fopen($f,"a");
+    ////fwrite($ft,"\n Xu ly doc thong tin trong ham scorm_get_manifest.  \n");    
+    ////////fwrite($ft,$blocks." la  gia tri block la  \n");    
+
+    static $parents = array();
+    static $resources;
+
+    static $manifest;
+    static $organization;
+
+    if (count($blocks) > 0) {
+        foreach ($blocks as $block) {
+            switch ($block['name']) {
+                case 'METADATA':
+                    if (isset($block['children'])) {
+                        foreach ($block['children'] as $metadata) {
+                            if ($metadata['name'] == 'SCHEMAVERSION') {
+                                if (empty($scoes->version)) {
+                                    if (isset($metadata['tagData']) && (preg_match("/^(1\.2)$|^(CAM )?(1\.3)$/",$metadata['tagData'],$matches))) {
+                                        $scoes->version = 'SCORM_'.$matches[count($matches)-1];
+                                    } else {
+                                        $scoes->version = 'SCORM_1.2';
+                                    }
+                                }
+                            }
+                        }
+                    }
+                break;
+                case 'MANIFEST':
+                    $manifest = addslashes($block['attrs']['IDENTIFIER']); //Lay thuoc tinh IDENTFIER cua MANIFEST
+                    $organization = '';
+                    $resources = array();
+                    $resources = scorm_get_resources($block['children']);
+                    $scoes = scorm_get_manifest($block['children'],$scoes);
+                    if (count($scoes->elements) <= 0) {
+                        foreach ($resources as $item => $resource) {
+                            if (!empty($resource['HREF'])) {
+                                $sco = new stdClass();
+                                $sco->identifier = $item;
+                                $sco->title = $item;
+                                $sco->parent = '/';
+                                $sco->launch = addslashes($resource['HREF']);
+                                $sco->scormtype = addslashes($resource['ADLCP:SCORMTYPE']);
+                                $scoes->elements[$manifest][$organization][$item] = $sco;
+                            }
+                        }
+                    }
+                break;
+                case 'ORGANIZATIONS':
+                    if (!isset($scoes->defaultorg)) {
+                        $scoes->defaultorg = addslashes($block['attrs']['DEFAULT']);
+                    }
+                    $scoes = scorm_get_manifest($block['children'],$scoes);
+                break;
+                case 'ORGANIZATION':
+                    $identifier = addslashes($block['attrs']['IDENTIFIER']);
+                    $organization = '';
+                    $scoes->elements[$manifest][$organization][$identifier]->identifier = $identifier;
+                    $scoes->elements[$manifest][$organization][$identifier]->parent = '/';
+                    $scoes->elements[$manifest][$organization][$identifier]->launch = '';
+                    $scoes->elements[$manifest][$organization][$identifier]->scormtype = '';
+
+                    $parents = array();
+                    $parent = new stdClass();
+                    $parent->identifier = $identifier;
+                    $parent->organization = $organization;
+                    array_push($parents, $parent);
+                    $organization = $identifier;
+
+                    $scoes = scorm_get_manifest($block['children'],$scoes);
+                    
+                    array_pop($parents);
+                break;
+                case 'ITEM':
+                    $parent = array_pop($parents);
+                    array_push($parents, $parent);
+
+                    $identifier = addslashes($block['attrs']['IDENTIFIER']);
+                    $scoes->elements[$manifest][$organization][$identifier]->identifier = $identifier;
+                    $scoes->elements[$manifest][$organization][$identifier]->parent = $parent->identifier;
+                    if (!isset($block['attrs']['ISVISIBLE'])) {
+                        $block['attrs']['ISVISIBLE'] = 'true';
+                    }
+                    $scoes->elements[$manifest][$organization][$identifier]->isvisible = addslashes($block['attrs']['ISVISIBLE']);
+                    if (!isset($block['attrs']['PARAMETERS'])) {
+                        $block['attrs']['PARAMETERS'] = '';
+                    }
+                    $scoes->elements[$manifest][$organization][$identifier]->parameters = addslashes($block['attrs']['PARAMETERS']);
+                    if (!isset($block['attrs']['IDENTIFIERREF'])) {
+                        $scoes->elements[$manifest][$organization][$identifier]->launch = '';
+                        $scoes->elements[$manifest][$organization][$identifier]->scormtype = 'asset';
+                    } else {
+                        $idref = addslashes($block['attrs']['IDENTIFIERREF']);
+                        $base = '';
+                        if (isset($resources[$idref]['XML:BASE'])) {
+                            $base = $resources[$idref]['XML:BASE'];
+                        }
+                        $scoes->elements[$manifest][$organization][$identifier]->launch = addslashes($base.$resources[$idref]['HREF']);
+                        if (empty($resources[$idref]['ADLCP:SCORMTYPE'])) {
+                            $resources[$idref]['ADLCP:SCORMTYPE'] = 'asset';
+                        }
+                        $scoes->elements[$manifest][$organization][$identifier]->scormtype = addslashes($resources[$idref]['ADLCP:SCORMTYPE']);
+                    }
+                    
+                    //////fwrite($ft,"---Dang lam viec voi ITEM co Identifier = ".$identifier);
+                    $parent = new stdClass();
+                    $parent->identifier = $identifier;
+                    $parent->organization = $organization;
+                    array_push($parents, $parent);
+
+                    $scoes = scorm_get_manifest($block['children'],$scoes);
+                    
+                    array_pop($parents);
+                break;
+                case 'TITLE':
+                    $parent = array_pop($parents);
+                    array_push($parents, $parent);
+                    $scoes->elements[$manifest][$parent->organization][$parent->identifier]->title = addslashes($block['tagData']);
+                break;
+                case 'ADLCP:PREREQUISITES':
+                    if ($block['attrs']['TYPE'] == 'aicc_script') {
+                        $parent = array_pop($parents);
+                        array_push($parents, $parent);
+                        $scoes->elements[$manifest][$parent->organization][$parent->identifier]->prerequisites = addslashes($block['tagData']);
+                    }
+                break;
+                case 'ADLCP:MAXTIMEALLOWED':
+                    $parent = array_pop($parents);
+                    array_push($parents, $parent);
+                    $scoes->elements[$manifest][$parent->organization][$parent->identifier]->maxtimeallowed = addslashes($block['tagData']);
+                break;
+                case 'ADLCP:TIMELIMITACTION':
+                    $parent = array_pop($parents);
+                    array_push($parents, $parent);
+                    $scoes->elements[$manifest][$parent->organization][$parent->identifier]->timelimitaction = addslashes($block['tagData']);
+                break;
+                case 'ADLCP:DATAFROMLMS':
+                    $parent = array_pop($parents);
+                    array_push($parents, $parent);
+                    $scoes->elements[$manifest][$parent->organization][$parent->identifier]->datafromlms = addslashes($block['tagData']);
+                break;
+                case 'ADLCP:MASTERYSCORE':
+                    $parent = array_pop($parents);
+                    array_push($parents, $parent);
+                    $scoes->elements[$manifest][$parent->organization][$parent->identifier]->masteryscore = addslashes($block['tagData']);
+                break;
+                case 'ADLNAV:PRESENTATION':
+                    $parent = array_pop($parents);
+                    array_push($parents, $parent);
+                    foreach ($block['children'] as $adlnav) {
+                        if ($adlnav['name'] == 'ADLNAV:NAVIGATIONINTERFACE') {                                    //////fwrite($ft,$scoes->elements[$manifest][$parent->organization][$parent->identifier]->title."  Xuat hien dieu khien NAV \n");
+                            foreach ($adlnav['children'] as $adlnavInterface){
+                                if ($adlnavInterface['name'] == 'ADLNAV:HIDELMSUI'){
+                                //////fwrite($ft,$scoes->elements[$manifest][$parent->organization][$parent->identifier]->title."  Xuat hien dieu khien NAV HIDELMSUI\n");
+                                //////fwrite($ft," Gia tri thuoc tinh an la ".$adlnavInterface['tagData']);
+                                    if ($adlnavInterface['tagData'] == 'continue')    {
+                                    $scoes->elements[$manifest][$parent->organization][$parent->identifier]->next = 1; 
+//                                    //////fwrite($ft," Thiet lap thuoc tinh an OK ");
+                                    }
+                                    if ($adlnavInterface['tagData'] == 'previous')    {
+                                    $scoes->elements[$manifest][$parent->organization][$parent->identifier]->previous = 1; 
+//                                    //////fwrite($ft," Thiet lap thuoc tinh an OK ");
+                                    }
+                                }
+
+                            }
+
+                        }
+                    }
+                break;
+
+                case 'IMSSS:SEQUENCING':
+                    $parent = array_pop($parents);
+                    array_push($parents, $parent);
+                    foreach ($block['children'] as $sequencing) {
+                        //////fwrite($ft,"\n Xuat hien IMSSS:SEQUENCING cua ".$parent->identifier);
+                        if ($sequencing['name']=='IMSSS:CONTROLMODE'){
+                            //Xu ly cac Control Mode voi mot Item trong SCO
+                            if ($sequencing['attrs']['CHOICE'] == 'false'){
+                            $scoes->elements[$manifest][$parent->organization][$parent->identifier]->choice = 0;
+                            //////fwrite($ft,"\n Xuat hien lua chon choice  \n");
+                            }
+                            if ($sequencing['attrs']['CHOICEEXIT'] == 'false'){
+                            $scoes->elements[$manifest][$parent->organization][$parent->identifier]->choiceexit = 0;
+                            }
+                            if ($sequencing['attrs']['FLOW'] == 'true'){
+                            $scoes->elements[$manifest][$parent->organization][$parent->identifier]->flow = 1;
+                            }
+                            if ($sequencing['attrs']['FORWARDONLY'] == 'true'){
+                            $scoes->elements[$manifest][$parent->organization][$parent->identifier]->forwardonly = 1;
+                            }
+                            if ($sequencing['attrs']['USECURRENTATTEMPTOBJECTINFO'] == 'true'){
+                            $scoes->elements[$manifest][$parent->organization][$parent->identifier]->usecurrentattemptobjectinfo = 1;
+                            }
+                            if ($sequencing['attrs']['USECURRENTATTEMPTPROGRESSINFO'] == 'true'){
+                            $scoes->elements[$manifest][$parent->organization][$parent->identifier]->usecurrentattemptprogressinfo = 1;
+                            }
+                        }
+                        if ($sequencing['name']=='ADLSEQ:CONSTRAINEDCHOICECONSIDERATIONS'){
+                            //Xu ly cac dieu kien rang buoc thu tu 
+                            if ($sequencing['attrs']['CONSTRAINCHOICE'] == 'true'){
+                            $scoes->elements[$manifest][$parent->organization][$parent->identifier]->constrainChoice = 1;
+                            }
+                            if ($sequencing['attrs']['PREVENTACTIVATION'] == 'true'){
+                            $scoes->elements[$manifest][$parent->organization][$parent->identifier]->preventactivation = 1;
+                            }
+
+                        }
+                        if ($sequencing['name']=='IMSSS:OBJECTIVES'){
+                            //Xu ly cac cac gia tri muc tieu
+                            foreach ($sequencing['children'] as $objective){
+                                if($objective['name']=='IMSSS:PRIMARYOBJECTIVE'){
+                                    //Xac dinh primary objective de lay thong so
+                                    foreach ($objective['children'] as $primaryobjective){
+                                        if($primaryobjective['name']=='IMSSS:MINNORMALIZEDMEASURE'){    $scoes->elements[$manifest][$parent->organization][$parent->identifier]->minnormalizedmeasure = $primaryobjective['tagData'];
+                                        }
+                                    }
+                                }
+                            }
+                        }
+                        if ($sequencing['name']=='IMSSS:LIMITCONDITIONS'){
+                            //Xu ly cac cac gia tri cac dieu kien gioi han
+                            if (!empty($sequencing['attrs']['ATTEMPTLIMIT'])){
+                                    $scoes->elements[$manifest][$parent->organization][$parent->identifier]->attemptLimit = $sequencing['attrs']['ATTEMPTLIMIT'];                                
+                            }
+                            if (!empty($sequencing['attrs']['ATTEMPTABSOLUTEDURATIONLIMIT'])){
+                                    $scoes->elements[$manifest][$parent->organization][$parent->identifier]->attemptAbsoluteDurationLimit = $sequencing['attrs']['ATTEMPTABSOLUTEDURATIONLIMIT'];                                
+                            }                            
+                        }                        
+                        if ($sequencing['name']=='IMSSS:ROLLUPRULES'){
+                            $rolluprules = array();
+                            //Phan danh cho RollupRule
+                            if (!empty($sequencing['attrs']['ROLLUPOBJECTIVESATISFIED'])){
+                                if ($sequencing['attrs']['ROLLUPOBJECTIVESATISFIED']== 'false'){
+                                    $scoes->elements[$manifest][$parent->organization][$parent->identifier]->rollupobjectivesatisfied = 0;                                
+                                }
+                            }
+                            if (!empty($sequencing['attrs']['ROLLUPPROGRESSCOMPLETION'])){
+                                if ($sequencing['attrs']['ROLLUPPROGRESSCOMPLETION']== 'false'){
+                                    $scoes->elements[$manifest][$parent->organization][$parent->identifier]->rollupprogresscompletion = 0;                                
+                                }
+                            }
+                            if (!empty($sequencing['attrs']['OBJECTIVEMEASUREWEIGHT'])){
+                                $scoes->elements[$manifest][$parent->organization][$parent->identifier]->objectivemeasureweight = $sequencing['attrs']['OBJECTIVEMEASUREWEIGHT'];                    
+                            }
+
+                            if (!empty($sequencing['children'])){
+                                foreach ($sequencing['children'] as $sequencingrolluprule){
+                                    if ($sequencingrolluprule['name']=='IMSSS:ROLLUPRULE' ){
+                                        $rolluprule = new stdClass();
+                                        if ($sequencingrolluprule['attrs']['CHILDACTIVITYSET'] !=' '){
+                                            $rolluprule->childactivityset = $sequencingrolluprule['attrs']['CHILDACTIVITYSET'];
+                                            ////fwrite($ft,"\n Thiet lap them 1 childActivitySet la ".$rolluprule->childactivityset);
+
+                                            //Phan xu ly danh sach condition
+                                            if (!empty($sequencingrolluprule['children'])){
+                                                foreach ($sequencingrolluprule['children'] as $rolluproleconditions)
+                                                {
+                                                    if ($rolluproleconditions['name']=='IMSSS:ROLLUPCONDITIONS'){
+                                                        $conditions = array();
+                                                        if (!empty($rolluproleconditions['attrs']['conditionCombination'])){
+                                                        $rolluprule->conditionCombination = $rolluproleconditions['attrs']['conditionCombination'];
+                                                        }
+                                                        foreach ($rolluproleconditions['children'] as $rolluprulecondition){
+                                                            if ($rolluprulecondition['name']=='IMSSS:ROLLUPCONDITION'){
+                                                                $condition = new stdClass();
+                                                                if (!empty($rolluprulecondition['attrs']['OPERATOR'])){
+                                                                    $condition->operator = $rolluprulecondition['attrs']['OPERATOR'];
+                                                                }
+                                                                if (!empty($rolluprulecondition['attrs']['CONDITION'])){
+                                                                    $condition->condition = $rolluprulecondition['attrs']['CONDITION'];
+                                                                }
+                                                            array_push($conditions,$condition);    
+                                                            ////fwrite($ft,"Da them mot rolluprulecondition");
+                                                            }
+
+                                                        }
+                                                    $rolluprule->conditions = $conditions;
+                                                    }
+                                                    if ($rolluproleconditions['name']=='IMSSS:ROLLUPACTION'){
+                                                    $rolluprule->rollupruleaction = $rolluproleconditions['attrs']['ACTION'];
+                                                    }
+                                                }
+                                            }
+                                            //Ket thuc xu ly danh sach condition
+
+                                        }
+                                        ////fwrite($ft,"\n Dua them 1 rule vao \n");
+                                        array_push($rolluprules, $rolluprule);
+                                        ////fwrite($ft,"\n Dua them 1 rule vao mang \n");
+                                    }
+
+                                }
+                            }
+                            $scoes->elements[$manifest][$parent->organization][$parent->identifier]->rolluprules = $rolluprules;
+
+//                            ////fwrite($ft,"\n >>>>NOW TEST ");
+//                            foreach ($scoes->elements[$manifest][$parent->organization][$parent->identifier]->rolluprules as $rolluptest){
+//                            ////fwrite($ft,"\n >>>> Gia tri Test thu duoc la:".$rolluptest->childactivityset);
+    
+                        }
+
+
+                        
+                        if ($sequencing['name']=='IMSSS:SEQUENCINGRULES'){
+                            //Xu ly cac dieu kien Rules cua Sequencing
+                            //////fwrite($ft,"\n Xuat hien SEQUENCINGRULES >>>>>>>>>>");                            
+                            $sequencingrules = array();
+                            foreach ($sequencing['children'] as $conditionrules){
+                                if($conditionrules['name']=='IMSSS:EXITCONDITIONRULE'){
+                                        $sequencingrule = new stdClass();
+                                        //Phan xu ly danh sach condition
+                                        //////fwrite($ft,"\n Xuat hien exitrule >>>>>>>>>>");
+                                        if (!empty($conditionrules['children'])){
+                                            foreach ($conditionrules['children'] as $conditionrule)
+                                            {
+                                                if ($conditionrule['name']=='IMSSS:RULECONDITIONS'){
+                                                    $ruleconditions = array();
+                                                    if (!empty($conditionrule['attrs']['conditionCombination'])){
+                                                    $sequencingrule->conditionCombination = $conditionrule['attrs']['conditionCombination'];
+                                                    }
+                                                    foreach ($conditionrule['children'] as $rulecondition){
+                                                        if ($rulecondition['name']=='IMSSS:RULECONDITION'){
+                                                            $condition = new stdClass();
+                                                            if (!empty($rulecondition['attrs']['OPERATOR'])){
+                                                                $condition->operator = $rulecondition['attrs']['OPERATOR'];
+                                                            }
+                                                            if (!empty($rulecondition['attrs']['CONDITION'])){
+                                                                $condition->condition = $rulecondition['attrs']['CONDITION'];
+                                                            }
+                                                            if (!empty($rulecondition['attrs']['MEASURETHRESHOLD'])){
+                                                                $condition->measurethreshold = $rulecondition['attrs']['MEASURETHRESHOLD'];
+                                                            }
+                                                            if (!empty($rulecondition['attrs']['REFERENCEDOBJECTIVE'])){
+                                                                $condition->referencedobjective = $rulecondition['attrs']['REFERENCEDOBJECTIVE'];
+                                                            }                                                                                                                        
+                                                        array_push($ruleconditions,$condition);    
+                                                        ////fwrite($ft,"\n Da them mot rulecondition trong exitrule");
+                                                        }
+
+                                                    }
+                                                $sequencingrule->ruleconditions = $ruleconditions;
+                                                }
+                                                if ($conditionrule['name']=='IMSSS:RULEACTION'){
+                                                $sequencingrule->exitconditionruleaction = $conditionrule['attrs']['ACTION'];
+                                                }
+                                            }
+                                        }
+                                        //Ket thuc xu ly danh sach condition
+                                array_push($sequencingrules,$sequencingrule);                                        
+                                }
+                                if ($conditionrules['name']=='IMSSS:PRECONDITIONRULE'){
+                                    $sequencingrule = new stdClass();
+                                    //Phan xu ly danh sach condition
+                                    if (!empty($conditionrules['children'])){
+                                        foreach ($conditionrules['children'] as $conditionrule)
+                                        {
+                                            if ($conditionrule['name']=='IMSSS:RULECONDITIONS'){
+                                                $ruleconditions = array();
+                                                if (!empty($conditionrule['attrs']['conditionCombination'])){
+                                                    $sequencingrule->conditionCombination = $conditionrule['attrs']['conditionCombination'];
+                                                }
+                                                foreach ($conditionrule['children'] as $rulecondition){
+                                                    if ($rulecondition['name']=='IMSSS:RULECONDITION'){
+                                                        $condition = new stdClass();
+                                                        if (!empty($rulecondition['attrs']['OPERATOR'])){
+                                                            $condition->operator = $rulecondition['attrs']['OPERATOR'];
+                                                        }
+                                                        if (!empty($rulecondition['attrs']['CONDITION'])){
+                                                            $condition->condition = $rulecondition['attrs']['CONDITION'];
+                                                        }
+                                                        if (!empty($rulecondition['attrs']['MEASURETHRESHOLD'])){
+                                                            $condition->measurethreshold = $rulecondition['attrs']['MEASURETHRESHOLD'];
+                                                        }
+                                                        if (!empty($rulecondition['attrs']['REFERENCEDOBJECTIVE'])){
+                                                            $condition->referencedobjective = $rulecondition['attrs']['REFERENCEDOBJECTIVE'];
+                                                        }                                                                                                                        
+                                                    array_push($ruleconditions,$condition);    
+                                                    ////fwrite($ft,"\n Da them mot rulecondition trong prerule");
+                                                    }
+
+                                                }
+                                            $sequencingrule->ruleconditions = $ruleconditions;
+                                            }
+                                            if ($conditionrule['name']=='IMSSS:RULEACTION'){
+                                            $sequencingrule->preconditionruleaction = $conditionrule['attrs']['ACTION'];
+                                            }
+                                        }
+                                    }
+                                    //Ket thuc xu ly danh sach condition
+                                array_push($sequencingrules,$sequencingrule);                                
+                                }
+                                if($conditionrules['name']=='IMSSS:POSTCONDITIONRULE'){
+                                        $sequencingrule = new stdClass();
+                                        //Phan xu ly danh sach condition
+                                        if (!empty($conditionrules['children'])){
+                                            foreach ($conditionrules['children'] as $conditionrule)
+                                            {
+                                                if ($conditionrule['name']=='IMSSS:RULECONDITIONS'){
+                                                    $ruleconditions = array();
+                                                    if (!empty($conditionrule['attrs']['conditionCombination'])){
+                                                    $sequencingrule->conditionCombination = $conditionrule['attrs']['conditionCombination'];
+                                                    }
+                                                    foreach ($conditionrule['children'] as $rulecondition){
+                                                        if ($rulecondition['name']=='IMSSS:RULECONDITION'){
+                                                            $condition = new stdClass();
+                                                            if (!empty($rulecondition['attrs']['OPERATOR'])){
+                                                                $condition->operator = $rulecondition['attrs']['OPERATOR'];
+                                                            }
+                                                            if (!empty($rulecondition['attrs']['CONDITION'])){
+                                                                $condition->condition = $rulecondition['attrs']['CONDITION'];
+                                                            }
+                                                            if (!empty($rulecondition['attrs']['MEASURETHRESHOLD'])){
+                                                                $condition->measurethreshold = $rulecondition['attrs']['MEASURETHRESHOLD'];
+                                                            }
+                                                            if (!empty($rulecondition['attrs']['REFERENCEDOBJECTIVE'])){
+                                                                $condition->referencedobjective = $rulecondition['attrs']['REFERENCEDOBJECTIVE'];
+                                                            }                                                                                                                        
+                                                        array_push($ruleconditions,$condition);    
+                                                        ////fwrite($ft,"\n Da them mot rulecondition trong postrule");
+                                                        }
+
+                                                    }
+                                                $sequencingrule->ruleconditions = $ruleconditions;
+                                                }
+                                                if ($conditionrule['name']=='IMSSS:RULEACTION'){
+                                                $sequencingrule->postconditionruleaction = $conditionrule['attrs']['ACTION'];
+                                                }
+                                            }
+                                        }
+                                        //Ket thuc xu ly danh sach condition
+                                array_push($sequencingrules,$sequencingrule);                                
+                                }
+                                $scoes->elements[$manifest][$parent->organization][$parent->identifier]->sequencingrules = $sequencingrules;                                
+                            }
+                        }
+                    }
+
+                break;
+
+            }
+        }
+    }
+
+    return $scoes;
+}
+
+function scorm_parse_scorm($pkgdir,$scormid) {
+    global $CFG;
+
+    //$f = "D:\\test.txt";
+    //@$ft = fopen($f,"a");
+    //////fwrite($ft,"\n Xu ly doc thong tin trong ham scorm_parse_scorm \n");
+    
+    $launch = 0;
+    $manifestfile = $pkgdir.'/imsmanifest.xml';
+
+    if (is_file($manifestfile)) {
+    
+        $xmlstring = file_get_contents($manifestfile);
+        $objXML = new xml2Array();
+        $manifests = $objXML->parse($xmlstring);
+            
+        $scoes = new stdClass();
+        $scoes->version = '';
+        $scoes = scorm_get_manifest($manifests,$scoes);
+
+        if (count($scoes->elements) > 0) {
+            foreach ($scoes->elements as $manifest => $organizations) {
+                foreach ($organizations as $organization => $items) {
+                    foreach ($items as $identifier => $item) {
+                        $item->scorm = $scormid;
+                        $item->manifest = $manifest;
+                        $item->organization = $organization;
+                        //////fwrite($ft,"\n ---- Item chuan bi dua vao la ".$item->identifier);
+                        $id = insert_record('scorm_scoes',$item);
+                        //////fwrite($ft,"\n Lay duoc ScoID la ".$id);
+                        $item->scormid = $scormid;
+                        $item->scoid = $id;
+                        $idControlMode = insert_record('scorm_sequencing_controlmode',$item);
+
+                        if (!empty($item->sequencingrules)){
+                            ////fwrite($ft,"\n ++++++++Them SequencingRules cho SCO: ".$item->scoid) ;
+                            foreach($item->sequencingrules as $sequencingrule){
+                                ////fwrite($ft,"\n ----Chuan bi them 1 sequencingrule vao CSDL: ");
+                                $sequencingrule->scormid = $scormid;
+                                $sequencingrule->scoid = $item->scoid;
+                                ////fwrite($ft,"\n ----Thong tin Scormid: ".$sequencingrule->scormid);                                                                                            
+                                ////fwrite($ft,"\n ----Thong tin Scoid: ".$sequencingrule->scoid);                                                                                                                            
+                                $idruleconditions = insert_record('scorm_sequencing_ruleconditions',$sequencingrule);
+                                foreach($sequencingrule->ruleconditions as $rulecondition){
+                                    $rulecondition->scormid = $sequencingrule->scormid;
+                                    $rulecondition->scoid = $sequencingrule->scoid;
+                                    $rulecondition->ruleconditionsid = $idruleconditions;
+                                    $idrulecondition = insert_record('scorm_sequencing_rulecondition',$rulecondition);
+                                    ////fwrite($ft,"\n ----Da them 1 sequencingrulecondition vao CSDL: ");                                    
+                                }
+                            
+                            }                        
+                        }
+                        
+                        if (!empty($item->rolluprules)){
+                            ////fwrite($ft,"\n ++++++++Them RollupRules cho SCO: ".$item->scoid) ;
+                            $idControlMode = insert_record('scorm_sequencing_rolluprules',$item);
+                            ////fwrite($ft,"\n ----Gia tri idRollupRules \n");
+                            foreach($item->rolluprules as $rollup)
+                            {
+                                ////fwrite($ft,"\n ----Chuan bi them 1 rule vao CSDL ");
+                                $rollup->rolluprulesid =$idControlMode;
+                                $rollup->scormid = $scormid;
+                                $rollup->scoid =  $item->scoid;
+
+                                ////fwrite($ft,"\n ----Cac thong tin cua Rule: \n ");
+                                ////fwrite($ft,"\n ----rolluprulesid:  ".$rollup->rolluprulesid);
+                                ////fwrite($ft,"\n ----scormid:  ".$rollup->scormid );
+                                ////fwrite($ft,"\n ----scoid:  ".$rollup->scoid);
+                                ////fwrite($ft,"\n ----activichild:  ".$rollup->childactivityset);
+                                ////fwrite($ft,"\n ----rollupaction:  ".$rollup->rollupruleaction);
+                                $idRollupRule = insert_record('scorm_sequencing_rolluprule',$rollup);
+                                ////fwrite($ft,"\n ----Dua them 1 rule vao CSDL -- Chuan bi them condition vao rule".$idRollupRule);
+                                $rollup->rollupruleid = $idRollupRule;
+                                $idconditions = insert_record('scorm_sequencing_rollupruleconditions',$rollup);
+                                ////fwrite($ft,"\n --Dua cac condition con vao CSDL");
+                                foreach($rollup->conditions as $condition){
+                                    $condition->ruleconditionsid = $idconditions;
+                                    $condition->scormid = $rollup->scormid;
+                                    $condition->scoid = $rollup->scoid;
+                                    $idcondition = insert_record('scorm_sequencing_rolluprulecondition',$condition);
+                                    ////fwrite($ft,"\n --Da dua them 1 condition vao CSDL");
+                                }
+                                                                
+                                
+                            }
+                        }
+                        if (($launch == 0) && ((empty($scoes->defaultorg)) || ($scoes->defaultorg == $identifier))) {
+                            $launch = $id;
+                        }
+                    }
+                }
+            }
+            set_field('scorm','version',$scoes->version,'id',$scormid);
+        }
+    } 
+    
+    return $launch;
+}
+
+function scorm_course_format_display($user,$course) {
+    global $CFG;
+
+    $strupdate = get_string('update');
+    $strmodule = get_string('modulename','scorm');
+
+    echo '<div class="mod-scorm">';
+    if ($scorms = get_all_instances_in_course('scorm', $course)) {
+        // The module SCORM activity with the least id is the course  
+        $scorm = current($scorms);
+        if (! $cm = get_coursemodule_from_instance('scorm', $scorm->id, $course->id)) {
+            error("Course Module ID was incorrect");
+        }
+        $colspan = '';
+        $headertext = '<table width="100%"><tr><td class="title">'.get_string('name').': <b>'.format_string($scorm->name).'</b>';
+        if (isteacher($course->id, $user->id, true)) {
+            if (isediting($course->id)) {
+                // Display update icon
+                $path = $CFG->wwwroot.'/course';
+                $headertext .= '<span class="commands">'.
+                        '<a title="'.$strupdate.'" href="'.$path.'/mod.php?update='.$cm->id.'&amp;sesskey='.sesskey().'">'.
+                        '<img src="'.$CFG->pixpath.'/t/edit.gif" hspace="2" height="11" width="11" border="0" alt="'.$strupdate.'" /></a></span>';
+            }
+            $headertext .= '</td>';
+            // Display report link
+            $trackedusers = get_record('scorm_scoes_track', 'scormid', $scorm->id, '', '', '', '', 'count(distinct(userid)) as c');
+            if ($trackedusers->c > 0) {
+                $headertext .= '<td class="reportlink">'.
+                              '<a target="'.$CFG->framename.'" href="'.$CFG->wwwroot.'/mod/scorm/report.php?id='.$cm->id.'">'.
+                               get_string('viewallreports','scorm',$trackedusers->c).'</a>';
+            } else {
+                $headertext .= '<td class="reportlink">'.get_string('noreports','scorm');
+            }
+            $colspan = ' colspan="2"';
+        } 
+        $headertext .= '</td></tr><tr><td'.$colspan.'>'.format_text(get_string('summary').':<br />'.$scorm->summary).'</td></tr></table>';
+        print_simple_box($headertext,'','100%');
+        scorm_view_display($user, $scorm, 'view.php?id='.$course->id, $cm, '100%');
+    } else {
+        if (isteacheredit($course->id, $user->id)) {
+            // Create a new activity
+            redirect('mod.php?id='.$course->id.'&amp;section=0&sesskey='.sesskey().'&amp;add=scorm');
+        } else {
+            notify('Could not find a scorm course here');
+        }
+    }
+    echo '</div>';
+}
+
+function scorm_view_display ($user, $scorm, $action, $cm, $blockwidth='') {
+    global $CFG;
+    $organization = optional_param('organization', '', PARAM_INT);
+
+    print_simple_box_start('center',$blockwidth);
+?>
+        <div class="structurehead"><?php print_string('coursestruct','scorm') ?></div>
+<?php
+    if (empty($organization)) {
+        $organization = $scorm->launch;
+    }
+    if ($orgs = get_records_select_menu('scorm_scoes',"scorm='$scorm->id' AND organization='' AND launch=''",'id','id,title')) {
+        if (count($orgs) > 1) {
+ ?>
+            <div class='center'>
+                <?php print_string('organizations','scorm') ?>
+                <form name='changeorg' method='post' action='<?php echo $action ?>'>
+                    <?php choose_from_menu($orgs, 'organization', "$organization", '','submit()') ?>
+                </form>
+            </div>
+<?php
+        }
+    }
+    $orgidentifier = '';
+    if ($org = get_record('scorm_scoes','id',$organization)) {
+        if (($org->organization == '') && ($org->launch == '')) {
+            $orgidentifier = $org->identifier;
+        } else {
+            $orgidentifier = $org->organization;
+        }
+    }
+    $result = scorm_get_toc($user,$scorm,'structlist',$orgidentifier);
+    $incomplete = $result->incomplete;
+//    echo ("Toc ---");
+    echo $result->toc;
+//    echo ("Ket thuc");
+    print_simple_box_end();
+?>
+            <div class="center">
+                <form name="theform" method="post" action="<?php echo $CFG->wwwroot ?>/mod/scorm/player.php?id=<?php echo $cm->id ?>"<?php echo $scorm->popup == 1?' target="newwin"':'' ?>>
+              <?php
+
+// Thiet lap suspend
+            $suspend = get_record("scorm_suspendtrack","scormid",$scorm->id,"userid",$user->id);
+
+//------------------
+                  if ($scorm->hidebrowse == 0) {
+                      print_string("mode","scorm");
+                      echo ': <input type="radio" id="b" name="mode" value="browse" /><label for="b">'.get_string('browse','scorm').'</label>'."\n";
+                      if ($incomplete === true) {
+                          echo '<input type="radio" id="n" name="mode" value="normal" checked="checked" /><label for="n">'.get_string('normal','scorm')."</label>\n";
+                            
+                            //Neu co luu tru thi co the chon continue de tiep tu
+                          if (!empty($suspend))
+                          {
+                              echo '<input type="radio" id="n" name="mode" value="continue" checked="checked" /><label for="n">'.get_string('continue','scorm')."</label>\n";
+                          }
+
+                      } else {
+                          echo '<input type="radio" id="r" name="mode" value="review" checked="checked" /><label for="r">'.get_string('review','scorm')."</label>\n";
+                      }
+                  } else {
+                      if ($incomplete === true) {
+                          echo '<input type="hidden" name="mode" value="normal" />'."\n";
+                      } else {
+                          echo '<input type="hidden" name="mode" value="review" />'."\n";
+                      }
+                  }
+                  if (($incomplete === false) && (($result->attemptleft > 0)||($scorm->maxattempt == 0))) {
+?>
+                  <br />
+                  <input type="checkbox" id="a" name="newattempt" />
+                  <label for="a"><?php print_string('newattempt','scorm') ?></label>
+<?php
+                  }
+              ?>
+              <br />
+              <input type="hidden" name="scoid" />
+              <input type="hidden" name="currentorg" value="<?php echo $orgidentifier ?>" />
+              <input type="submit" value="<?php print_string('entercourse','scorm') ?>" />
+              </form>
+          </div>
+<?php
+}
+
+function scorm_update_status($scormid,$scoid)
+{
+    
+}
+
+
+function scorm_repeater($what, $times) {
+    if ($times <= 0) {
+        return null;
+    }
+    $return = '';
+    for ($i=0; $i<$times;$i++) {
+        $return .= $what;
+    }
+    return $return;
+}
+
+//chuyen toi SCO duoc thuc hien tiep theo
+function scorm_get_nextsco($scormid,$scoid)
+{
+
+
+
+}
+//Chuyen toi SCO duoc thuc hien truoc
+function scorm_get_presco($scormid,$scoid)
+{
+
+
+
+}
+//Xac dinh xem doi tuong do co cho phep lua chon khong
+function scorm_isChoice($scormid,$scoid)
+{
+//    //$f = "D:\\test.txt";
+//    //@$ft = fopen($f,"a");
+    $sco = get_record("scorm_sequencing_controlmode","scormid",$scormid,"scoid",$scoid);
+//    ////fwrite($ft,"\n Xu ly doc thong tin trong ham scorm_isChoice scormid la ".$scormid." scoid la: ".$scoid);
+    $scoparent = get_record("scorm_sequencing_controlmode","scormid",$scormid,"identifier",$sco->parent);
+//    ////fwrite($ft,"\n Xu ly doc thong tin trong ham scorm_isChoice scoparent scormid la ".$scormid." scoid la: ".$scoparent->scoid);
+
+
+//    ////fwrite($ft,"\n Xu ly doc thong tin trong ham scorm_isChoice gia tri la: ".$scoparent->choice);
+    return $scoparent->choice;
+}
+
+//Xac dinh xem doi tuong do co cho phep lua chon thoat khong
+function scorm_isChoiceexit($scormid,$scoid)
+{
+    $sco = get_record("scorm_sequencing_controlmode","scormid",$scormid,"scoid",$scoid);
+    $scoparent = get_record("scorm_sequencing_controlmode","scormid",$scormid,"identifier",$sco->parent);
+
+    return $scoparent->choiceexit;
+}
+/* Usage
+ Grab some XML data, either from a file, URL, etc. however you want. Assume storage in $strYourXML;
+
+ $objXML = new xml2Array();
+ $arrOutput = $objXML->parse($strYourXML);
+ print_r($arrOutput); //print it out, or do whatever!
+  
+*/
+class xml2Array {
+   
+   var $arrOutput = array();
+   var $resParser;
+   var $strXmlData;
+   
+   /**
+   * Convert a utf-8 string to html entities
+   *
+   * @param string $str The UTF-8 string
+   * @return string
+   */
+   function utf8_to_entities($str) {
+       $entities = '';
+       $values = array();
+       $lookingfor = 1;
+
+       for ($i = 0; $i < strlen($str); $i++) {
+           $thisvalue = ord($str[$i]);
+           if ($thisvalue < 128) {
+               $entities .= $str[$i]; // Leave ASCII chars unchanged 
+           } else {
+               if (count($values) == 0) {
+                   $lookingfor = ($thisvalue < 224) ? 2 : 3;
+               }
+               $values[] = $thisvalue;
+               if (count($values) == $lookingfor) {
+                   $number = ($lookingfor == 3) ?
+                       (($values[0] % 16) * 4096) + (($values[1] % 64) * 64) + ($values[2] % 64):
+                       (($values[0] % 32) * 64) + ($values[1] % 64);
+                   $entities .= '&#' . $number . ';';
+                   $values = array();
+                   $lookingfor = 1;
+               }
+           }
+       }
+       return $entities;
+   }
+
+   /**
+   * Parse an XML text string and create an array tree that rapresent the XML structure
+   *
+   * @param string $strInputXML The XML string
+   * @return array
+   */
+   function parse($strInputXML) {
+           $this->resParser = xml_parser_create ('UTF-8');
+           xml_set_object($this->resParser,$this);
+           xml_set_element_handler($this->resParser, "tagOpen", "tagClosed");
+           
+           xml_set_character_data_handler($this->resParser, "tagData");
+       
+           $this->strXmlData = xml_parse($this->resParser,$strInputXML );
+           if(!$this->strXmlData) {
+               die(sprintf("XML error: %s at line %d",
+                           xml_error_string(xml_get_error_code($this->resParser)),
+                           xml_get_current_line_number($this->resParser)));
+           }
+                           
+           xml_parser_free($this->resParser);
+           
+           return $this->arrOutput;
+   }
+   
+   function tagOpen($parser, $name, $attrs) {
+       $tag=array("name"=>$name,"attrs"=>$attrs); 
+       array_push($this->arrOutput,$tag);
+   }
+   
+   function tagData($parser, $tagData) {
+       if(trim($tagData)) {
+           if(isset($this->arrOutput[count($this->arrOutput)-1]['tagData'])) {
+               $this->arrOutput[count($this->arrOutput)-1]['tagData'] .= $this->utf8_to_entities($tagData);
+           } else {
+               $this->arrOutput[count($this->arrOutput)-1]['tagData'] = $this->utf8_to_entities($tagData);
+           }
+       }
+   }
+   
+   function tagClosed($parser, $name) {
+       $this->arrOutput[count($this->arrOutput)-2]['children'][] = $this->arrOutput[count($this->arrOutput)-1];
+       array_pop($this->arrOutput);
+   }
+
+}
+?>
index dfd3bf0162da823acb00ba481587b8be98255690..f2ee7b3d9ce1e00246d36b2099f053267bf1c529 100755 (executable)
-<?php // $Id$\r
-\r
-    require_once("../../config.php");\r
-    require_once('locallib.php');\r
-       \r
-    $courseid = required_param('id', PARAM_INT);             // Course Module ID, or\r
-    $reference = required_param('reference', PARAM_PATH);    // Package path\r
-    $scormid = optional_param('instance', '', PARAM_INT);       // scorm ID\r
-\r
-    require_login($courseid, false);\r
-\r
-if (confirm_sesskey() && !empty($courseid)) {\r
-    $launch = 0;\r
-    $validation = new stdClass();\r
-    if (empty($reference)) {\r
-        $launch = -1;\r
-        $validation->result = "packagefile";\r
-    }\r
-    if (!empty($scormid)) {  \r
-        //\r
-        // SCORM Update\r
-        //\r
-        if (is_file($CFG->dataroot.'/'.$courseid.'/'.$reference)) {\r
-            $fp = fopen($CFG->dataroot.'/'.$courseid.'/'.$reference,"r");\r
-            $fstat = fstat($fp);\r
-            fclose($fp);\r
-            if ($scorm = get_record("scorm","id",$scormid)) {\r
-                $launch = $scorm->launch;\r
-                if ((($scorm->timemodified < $fstat["mtime"]) && ($scorm->reference == $reference)) || ($scorm->reference != $reference)) {\r
-                    // This is a new package\r
-                    $launch = 0;\r
-                } else {\r
-                    // Old package already validated\r
-                    $validation->result = 'found';\r
-                    if (strpos($scorm->version,'AICC') !== false) {\r
-                        $validation->pkgtype = 'AICC';\r
-                    } else {\r
-                        $validation->pkgtype = 'SCORM';\r
-                    }\r
-                }\r
-            } else {\r
-                $validation->result = 'badinstance';\r
-                $launch = -1;\r
-            }\r
-        } else {\r
-            $validation->result = 'badreference';\r
-            $launch = -1;\r
-        }\r
-    }\r
-    //$launch = 0;\r
-    if ($launch == 0) {\r
-        //\r
-        // Package must be validated\r
-        //\r
-\r
-        $ext = strtolower(substr(basename($reference),strrpos(basename($reference),'.')));\r
-        switch ($ext) {\r
-            case '.pif':\r
-            case '.zip':\r
-                // Create a temporary directory to unzip package and validate package\r
-                $tempdir = '';\r
-                $scormdir = '';\r
-                if ($scormdir = make_upload_directory("$courseid/$CFG->moddata/scorm")) {\r
-                    if ($tempdir = scorm_datadir($scormdir)) {\r
-                        copy ("$CFG->dataroot/$courseid/$reference", $tempdir."/".basename($reference));\r
-                        unzip_file($tempdir."/".basename($reference), $tempdir, false);\r
-                        unlink ($tempdir."/".basename($reference));\r
-                        $validation = scorm_validate($tempdir);\r
-                    } else {\r
-                        $validation->result = "packagedir";\r
-                    }\r
-                } else {\r
-                    $validation->result = "datadir";\r
-                }\r
-            break;\r
-            case '.xml':\r
-                if (basename($reference) == 'imsmanifest.xml') {\r
-                    $validation = scorm_validate("$CFG->dataroot/$courseid/".dirname($reference));\r
-                } else {\r
-                    $validation->result = "manifestfile";\r
-                }\r
-            break;\r
-            default: \r
-                $validation->result = "packagefile";\r
-            break;\r
-        }\r
-        if (($validation->result != "regular") && ($validation->result != "found")) {\r
-            $validation->result = get_string($validation->result,'scorm');\r
-            if (is_dir($tempdir)) {\r
-                // Delete files and temporary directory\r
-                scorm_delete_files($tempdir);\r
-            }\r
-        } else {\r
-            if ($ext == '.xml') {\r
-                $datadir = dirname($reference);\r
-            } else {\r
-                $datadir = substr($tempdir,strlen($scormdir));\r
-            }\r
-        }\r
-    }\r
-    //\r
-    // Print validation result\r
-    //\r
-    echo 'result=' . $validation->result . "\n";\r
-    echo 'launch=' . $launch . "\n";\r
-    if (isset($validation->pkgtype)) {\r
-        echo 'pkgtype=' . $validation->pkgtype . "\n";\r
-    }\r
-    if (isset($datadir)) {\r
-        echo 'datadir=' . $datadir . "\n";\r
-    }\r
-    if (isset($validation->errors[1])) {\r
-        echo 'errorlogs='."\n";\r
-        foreach($validation->errors as $error) {\r
-            echo get_string($error->type,"scorm",$error->data) . "\n";\r
-        }\r
-    }\r
-} else {\r
-    echo 'result=' . get_string('badrequest','scorm') . "\n";\r
-}\r
-?>\r
+<?php // $Id$
+
+    require_once("../../config.php");
+    require_once('locallib.php');
+    require_once('lib.php');
+
+    $courseid = required_param('id', PARAM_INT);             // Course Module ID, or
+    $reference = required_param('reference', PARAM_PATH);    // Package path
+    $scormid = optional_param('instance', '', PARAM_INT);       // scorm ID
+
+    require_login($courseid, false);
+
+if (confirm_sesskey() && !empty($courseid)) {
+    $launch = 0;
+    $validation = new stdClass();
+    if (empty($reference)) {
+        $launch = -1;
+        $validation->result = "packagefile";
+    }
+    if (!empty($scormid)) {  
+        //
+        // SCORM Update
+        //
+        if (is_file($CFG->dataroot.'/'.$courseid.'/'.$reference)) {
+            $fp = fopen($CFG->dataroot.'/'.$courseid.'/'.$reference,"r");
+            $fstat = fstat($fp);
+            fclose($fp);
+            if ($scorm = get_record("scorm","id",$scormid)) {
+                $launch = $scorm->launch;
+                if ((($scorm->timemodified < $fstat["mtime"]) && ($scorm->reference == $reference)) || ($scorm->reference != $reference)) {
+                    // This is a new package
+                    $launch = 0;
+                } else {
+                    // Old package already validated
+                    $validation->result = 'found';
+                    if (strpos($scorm->version,'AICC') !== false) {
+                        $validation->pkgtype = 'AICC';
+                    } else {
+                        $validation->pkgtype = 'SCORM';
+                    }
+                }
+            } else {
+                $validation->result = 'badinstance';
+                $launch = -1;
+            }
+        } else {
+            $validation->result = 'badreference';
+            $launch = -1;
+        }
+    }
+    //$launch = 0;
+    if ($launch == 0) {
+        //
+        // Package must be validated
+        //
+
+        $ext = strtolower(substr(basename($reference),strrpos(basename($reference),'.')));
+        switch ($ext) {
+            case '.pif':
+            case '.zip':
+                // Create a temporary directory to unzip package and validate package
+                $tempdir = '';
+                $scormdir = '';
+                if ($scormdir = make_upload_directory("$courseid/$CFG->moddata/scorm")) {
+                    if ($tempdir = scorm_datadir($scormdir)) {
+                        copy ("$CFG->dataroot/$courseid/$reference", $tempdir."/".basename($reference));
+                        unzip_file($tempdir."/".basename($reference), $tempdir, false);
+                        unlink ($tempdir."/".basename($reference));
+                        $validation = scorm_validate($tempdir);
+                    } else {
+                        $validation->result = "packagedir";
+                    }
+                } else {
+                    $validation->result = "datadir";
+                }
+            break;
+            case '.xml':
+                if (basename($reference) == 'imsmanifest.xml') {
+                    $validation = scorm_validate("$CFG->dataroot/$courseid/".dirname($reference));
+                } else {
+                    $validation->result = "manifestfile";
+                }
+            break;
+            default: 
+                $validation->result = "packagefile";
+            break;
+        }
+        if (($validation->result != "regular") && ($validation->result != "found")) {
+            $validation->result = get_string($validation->result,'scorm');
+            if (is_dir($tempdir)) {
+                // Delete files and temporary directory
+                scorm_delete_files($tempdir);
+            }
+        } else {
+            if ($ext == '.xml') {
+                $datadir = dirname($reference);
+            } else {
+                $datadir = substr($tempdir,strlen($scormdir));
+            }
+        }
+    }
+    //
+    // Print validation result
+    //
+    echo 'result=' . $validation->result . "\n";
+    echo 'launch=' . $launch . "\n";
+    if (isset($validation->pkgtype)) {
+        echo 'pkgtype=' . $validation->pkgtype . "\n";
+    }
+    if (isset($datadir)) {
+        echo 'datadir=' . $datadir . "\n";
+    }
+    if (isset($validation->errors[1])) {
+        echo 'errorlogs='."\n";
+        foreach($validation->errors as $error) {
+            echo get_string($error->type,"scorm",$error->data) . "\n";
+        }
+    }
+} else {
+    echo 'result=' . get_string('badrequest','scorm') . "\n";
+}
+?>