diff --git a/main/newscorm/scorm.class.php b/main/newscorm/scorm.class.php index 6fa293a70d..7499ffa3d9 100755 --- a/main/newscorm/scorm.class.php +++ b/main/newscorm/scorm.class.php @@ -1,10 +1,12 @@ */ + /** * Includes */ @@ -12,6 +14,7 @@ require_once 'scormItem.class.php'; require_once 'scormMetadata.class.php'; require_once 'scormOrganization.class.php'; require_once 'scormResource.class.php'; + /** * Defines the "scorm" child of class "learnpath" * @package chamilo.learnpath @@ -23,415 +26,403 @@ class scorm extends learnpath { public $organizations = array(); public $organizations_att = array(); public $metadata = array(); - public $idrefs = array(); //will hold the references to resources for each item ID found - public $refurls = array(); //for each resource found, stores the file url/uri - public $subdir = ''; //path between the scorm/ directory and the imsmanifest.xml e.g. maritime_nav/maritime_nav. This is the path that will be used in the lp_path when importing a package + public $idrefs = array(); // Will hold the references to resources for each item ID found. + public $refurls = array(); // For each resource found, stores the file url/uri. + public $subdir = ''; // Path between the scorm/ directory and the imsmanifest.xml e.g. maritime_nav/maritime_nav. This is the path that will be used in the lp_path when importing a package. public $items = array(); - public $zipname = ''; //keeps the zipfile safe for the object's life so that we can use it if no title avail - public $lastzipnameindex = 0; //keeps an index of the number of uses of the zipname so far + public $zipname = ''; // Keeps the zipfile safe for the object's life so that we can use it if no title avail. + public $lastzipnameindex = 0; // Keeps an index of the number of uses of the zipname so far. public $manifest_encoding = 'UTF-8'; public $debug = 0; + /** * Class constructor. Based on the parent constructor. * @param string Course code * @param integer Learnpath ID in DB * @param integer User ID */ - function __construct($course_code=null,$resource_id=null,$user_id=null) { - if($this->debug>0){error_log('New LP - scorm::scorm('.$course_code.','.$resource_id.','.$user_id.') - In scorm constructor',0);} - if(!empty($course_code) and !empty($resource_id) and !empty($user_id)) - { - parent::__construct($course_code, $resource_id, $user_id); - }else{ - //do nothing but still build the scorm object - } - } - /** - * Opens a resource - * @param integer Database ID of the resource - */ - function open($id) - { - if($this->debug>0){error_log('New LP - scorm::open() - In scorm::open method',0);} - // redefine parent method - } - /** - * Possible SCO status: see CAM doc 2.3.2.5.1: passed, completed, browsed, failed, not attempted, incomplete - */ - /** - * Prerequisites: see CAM doc 2.3.2.5.1 for pseudo-code - */ - /** - * Parses an imsmanifest.xml file and puts everything into the $manifest array - * @param string Path to the imsmanifest.xml file on the system. If not defined, uses the base path of the course's scorm dir + function __construct($course_code = null, $resource_id = null, $user_id = null) { + if ($this->debug > 0) { error_log('New LP - scorm::scorm('.$course_code.','.$resource_id.','.$user_id.') - In scorm constructor', 0); } + if (!empty($course_code) && !empty($resource_id) && !empty($user_id)) { + parent::__construct($course_code, $resource_id, $user_id); + } else { + // Do nothing but still build the scorm object. + } + } + + /** + * Opens a resource + * @param integer Database ID of the resource + */ + function open($id) { + if ($this->debug > 0) { error_log('New LP - scorm::open() - In scorm::open method', 0); } + // redefine parent method + } + + /** + * Possible SCO status: see CAM doc 2.3.2.5.1: passed, completed, browsed, failed, not attempted, incomplete + */ + + /** + * Prerequisites: see CAM doc 2.3.2.5.1 for pseudo-code + */ + + /** + * Parses an imsmanifest.xml file and puts everything into the $manifest array + * @param string Path to the imsmanifest.xml file on the system. If not defined, uses the base path of the course's scorm dir * @return array Structured array representing the imsmanifest's contents - */ - function parse_manifest($file='') - { - if($this->debug>0){error_log('In scorm::parse_manifest('.$file.')',0);} - if(empty($file)){ - //get the path of the imsmanifest file - } - if(is_file($file) and is_readable($file)) - { - $v = substr(phpversion(),0,1); - if($v == 4){ - if($this->debug>0){error_log('In scorm::parse_manifest() - Parsing using PHP4 method',0);} - $var = file_get_contents($file); - //quick ugly hack to remove xml:id attributes from the file (break the system if xslt not installed) - $var = preg_replace('/xml:id=["\']id_\d{1,4}["\']/i','',$var); - $doc = xmldoc($var); - //error_reporting(E_ALL); - //$doc = xmldocfile($file); - if(!empty($doc->encoding)){ - $this->manifest_encoding = strtoupper($doc->encoding); - } - if($this->debug>1){error_log('New LP - Called xmldoc() (encoding:'.strtoupper($doc->encoding).' - saved: '.$this->manifest_encoding.')',0);} - if(!$doc) - { - if($this->debug>1){error_log('New LP - File '.$file.' is not an XML file',0);} - //$this->set_error_msg("File $file is not an XML file"); - return null; - }else{ - if($this->debug>1){error_log('New LP - File '.$file.' is XML',0);} - $root = $doc->root(); - $attributes = $root->attributes(); - for($a=0; $a element attributes - if($attributes[$a]->type == XML_ATTRIBUTE_NODE){ + */ + function parse_manifest($file = '') { + if ($this->debug > 0) { error_log('In scorm::parse_manifest('.$file.')', 0); } + if (empty($file)) { + // Get the path of the imsmanifest file. + } + if (is_file($file) and is_readable($file)) { + $v = substr(phpversion(), 0, 1); + if ($v == 4) { + if ($this->debug > 0) { error_log('In scorm::parse_manifest() - Parsing using PHP4 method', 0); } + $var = file_get_contents($file); + // Quick ugly hack to remove xml:id attributes from the file (break the system if xslt not installed). + $var = preg_replace('/xml:id=["\']id_\d{1,4}["\']/i', '', $var); + $doc = xmldoc($var); + //error_reporting(E_ALL); + //$doc = xmldocfile($file); + if (!empty($doc->encoding)) { + $this->manifest_encoding = strtoupper($doc->encoding); + } + if ($this->debug > 1) { error_log('New LP - Called xmldoc() (encoding:'.strtoupper($doc->encoding).' - saved: '.$this->manifest_encoding.')', 0); } + if (!$doc) { + if ($this->debug > 1) { error_log('New LP - File '.$file.' is not an XML file', 0); } + //$this->set_error_msg("File $file is not an XML file"); + return null; + } else { + if ($this->debug > 1) { error_log('New LP - File '.$file.' is XML', 0); } + $root = $doc->root(); + $attributes = $root->attributes(); + for ($a = 0; $a < sizeof($attributes); $a++) { + // element attributes + if ($attributes[$a]->type == XML_ATTRIBUTE_NODE) { $this->manifest[$attributes[$a]->name] = $attributes[$a]->value; - } - } - $this->manifest['name'] = $root->name; - $children = $root->children(); - for($b=0; $b element children (can be , or ) - if($children[$b]->type == XML_ELEMENT_NODE){ - switch($children[$b]->tagname){ - case 'metadata': - //parse items from inside the element - $this->metadata = new scormMetadata('manifest',$children[$b]); - break; - case 'organizations': - //contains the course structure - this element appears 1 and only 1 time in a package imsmanifest. It contains at least one 'organization' sub-element - $orgs_attribs = $children[$b]->attributes(); - for($c=0; $c element - if($orgs_attribs[$c]->type == XML_ATTRIBUTE_NODE){ - $this->manifest['organizations'][$orgs_attribs[$c]->name] = $orgs_attribs[$c]->value; - } - } - $orgs_nodes = $children[$b]->children(); - $i = 0; - $found_an_org = false; - foreach($orgs_nodes as $c => $dummy) - { - // elements - can contain , and - //Here we are at the 'organization' level. There might be several organization tags but - //there is generally only one. - //There are generally three children nodes we are looking for inside and organization: - //-title - //-item (may contain other item tags or may appear several times inside organization) - //-metadata (relative to the organization) - $found_an_org = false; - $orgnode =& $orgs_nodes[$c]; - switch($orgnode->type){ - case XML_TEXT_NODE: - //ignore here - break; - case XML_ATTRIBUTE_NODE: - //just in case ther would be interesting attributes inside the organization tag. There shouldn't - //as this is a node-level, not a data level - //$manifest['organizations'][$i][$orgnode->name] = $orgnode->value; - //$found_an_org = true; - break; - case XML_ELEMENT_NODE: - //<item>,<metadata> or <title> (or attributes) - $organizations_attributes = $orgnode->attributes(); - foreach($organizations_attributes as $d1 => $dummy) - { + } + } + $this->manifest['name'] = $root->name; + $children = $root->children(); + for($b = 0; $b < sizeof($children); $b++) { + // <manifest> element children (can be <metadata>, <organizations> or <resources> ) + if ($children[$b]->type == XML_ELEMENT_NODE) { + switch($children[$b]->tagname) { + case 'metadata': + // Parse items from inside the <metadata> element. + $this->metadata = new scormMetadata('manifest',$children[$b]); + break; + case 'organizations': + // Contains the course structure - this element appears 1 and only 1 time in a package imsmanifest. It contains at least one 'organization' sub-element. + $orgs_attribs = $children[$b]->attributes(); + for($c = 0; $c < sizeof($orgs_attribs); $c++) { + // Attributes of the <organizations> element. + if ($orgs_attribs[$c]->type == XML_ATTRIBUTE_NODE) { + $this->manifest['organizations'][$orgs_attribs[$c]->name] = $orgs_attribs[$c]->value; + } + } + $orgs_nodes = $children[$b]->children(); + $i = 0; + $found_an_org = false; + foreach ($orgs_nodes as $c => $dummy) { + // <organization> elements - can contain <item>, <metadata> and <title> + // Here we are at the 'organization' level. There might be several organization tags but + // there is generally only one. + // There are generally three children nodes we are looking for inside and organization: + // -title + // -item (may contain other item tags or may appear several times inside organization) + // -metadata (relative to the organization) + $found_an_org = false; + $orgnode =& $orgs_nodes[$c]; + switch ($orgnode->type) { + case XML_TEXT_NODE: + // Ignore here. + break; + case XML_ATTRIBUTE_NODE: + // just in case ther would be interesting attributes inside the organization tag. There shouldn't + // as this is a node-level, not a data level. + //$manifest['organizations'][$i][$orgnode->name] = $orgnode->value; + //$found_an_org = true; + break; + case XML_ELEMENT_NODE: + // <item>, <metadata> or <title> (or attributes) + $organizations_attributes = $orgnode->attributes(); + foreach($organizations_attributes as $d1 => $dummy) { //$manifest['organizations'][$i]['attributes'][$organizations_attributes[$d1]->name] = $organizations_attributes[$d1]->value; - //$found_an_org = true; - $this->organizations_att[$organizations_attributes[$d1]->name] = $organizations_attributes[$d1]->value; - } - $oOrganization = new scormOrganization('manifest',$orgnode,$this->manifest_encoding); - if($oOrganization->identifier != ''){ - $name = $oOrganization->get_name(); - if(empty($name)){ - //if the org title is empty, use zip file name - $myname = $this->zipname; - if($this->lastzipnameindex != 0){ - $myname = $myname + $this->lastzipnameindex; - $this->lastzipnameindex++; - } - $oOrganization->set_name($this->zipname); - } - $this->organizations[$oOrganization->identifier] = $oOrganization; - } - break; - } - } - break; - case 'resources': - $resources_attribs = $children[$b]->attributes(); - for($c=0; $c<sizeof($resources_attribs);$c++) - { - if($resources_attribs[$c]->type == XML_ATTRIBUTE_NODE){ - $this->manifest['resources'][$resources_attribs[$c]->name] = $resources_attribs[$c]->value; - } - } - $resources_nodes = $children[$b]->children(); - $i = 0; - foreach($resources_nodes as $c => $dummy) - { - /* - $my_res = scorm::parse_items($resources_nodes[$c]); - scorm::parse_items_get_refurls($resources_nodes[$c],$refurls); - if(count($my_res)>0) - { - $manifest['resources'][$i] = $my_res; - } - */ - $oResource = new scormResource('manifest',$resources_nodes[$c]); - if($oResource->identifier != ''){ + //$found_an_org = true; + $this->organizations_att[$organizations_attributes[$d1]->name] = $organizations_attributes[$d1]->value; + } + $oOrganization = new scormOrganization('manifest', $orgnode, $this->manifest_encoding); + if ($oOrganization->identifier != '') { + $name = $oOrganization->get_name(); + if (empty($name)) { + // If the org title is empty, use zip file name. + $myname = $this->zipname; + if ($this->lastzipnameindex != 0) { + $myname = $myname + $this->lastzipnameindex; + $this->lastzipnameindex++; + } + $oOrganization->set_name($this->zipname); + } + $this->organizations[$oOrganization->identifier] = $oOrganization; + } + break; + } + } + break; + case 'resources': + $resources_attribs = $children[$b]->attributes(); + for ($c = 0; $c < sizeof($resources_attribs); $c++) { + if ($resources_attribs[$c]->type == XML_ATTRIBUTE_NODE) { + $this->manifest['resources'][$resources_attribs[$c]->name] = $resources_attribs[$c]->value; + } + } + $resources_nodes = $children[$b]->children(); + $i = 0; + foreach ($resources_nodes as $c => $dummy) { + /* + $my_res = scorm::parse_items($resources_nodes[$c]); + scorm::parse_items_get_refurls($resources_nodes[$c], $refurls); + if (count($my_res) > 0) { + $manifest['resources'][$i] = $my_res; + } + */ + $oResource = new scormResource('manifest', $resources_nodes[$c]); + if ($oResource->identifier != '') { $this->resources[$oResource->identifier] = $oResource; - $i++; - } - } - //contains links to physical resources - break; - case 'manifest': - //only for sub-manifests - break; - } - } - } - } - unset($doc); - }elseif($v==5){ - if($this->debug>0){error_log('In scorm::parse_manifest() - Parsing using PHP5 method',0);} - $doc = new DOMDocument(); - $res = $doc->load($file); - if($res===false){ - if($this->debug>0){error_log('New LP - In scorm::parse_manifest() - Exception thrown when loading '.$file.' in DOMDocument',0);} - //throw exception? - return null; - } - - if(!empty($doc->xmlEncoding)){ - $this->manifest_encoding = strtoupper($doc->xmlEncoding); - } - if($this->debug>1){error_log('New LP - Called (encoding:'.$doc->xmlEncoding.' - saved: '.$this->manifest_encoding.')',0);} + $i++; + } + } + // Contains links to physical resources. + break; + case 'manifest': + // Only for sub-manifests. + break; + } + } + } + } + unset($doc); + } elseif ($v==5) { + if ($this->debug > 0) { error_log('In scorm::parse_manifest() - Parsing using PHP5 method', 0); } + $doc = new DOMDocument(); + $res = $doc->load($file); + if ($res === false) { + if ($this->debug > 0) { error_log('New LP - In scorm::parse_manifest() - Exception thrown when loading '.$file.' in DOMDocument', 0); } + // Throw exception? + return null; + } + + if (!empty($doc->xmlEncoding)) { + $this->manifest_encoding = strtoupper($doc->xmlEncoding); + } + if ($this->debug > 1) { error_log('New LP - Called (encoding:'.$doc->xmlEncoding.' - saved: '.$this->manifest_encoding.')', 0); } $root = $doc->documentElement; - if($root->hasAttributes()){ - $attributes = $root->attributes; - if($attributes->length !== 0){ - foreach($attributes as $attrib) - {//<manifest> element attributes + if ($root->hasAttributes()) { + $attributes = $root->attributes; + if ($attributes->length !== 0) { + foreach($attributes as $attrib) { + // <manifest> element attributes $this->manifest[$attrib->name] = $attrib->value; - } - } + } + } } - $this->manifest['name'] = $root->tagName; - if($root->hasChildNodes()){ - $children = $root->childNodes; - if($children->length !== 0){ - foreach($children as $child) - { - //<manifest> element children (can be <metadata>, <organizations> or <resources> ) - if($child->nodeType == XML_ELEMENT_NODE){ - switch($child->tagName){ - case 'metadata': - //parse items from inside the <metadata> element - $this->metadata = new scormMetadata('manifest',$child); - break; - case 'organizations': - //contains the course structure - this element appears 1 and only 1 time in a package imsmanifest. It contains at least one 'organization' sub-element - $orgs_attribs = $child->attributes; - foreach($orgs_attribs as $orgs_attrib) - {//attributes of the <organizations> element - if($orgs_attrib->nodeType == XML_ATTRIBUTE_NODE){ - $this->manifest['organizations'][$orgs_attrib->name] = $orgs_attrib->value; - } - } - $orgs_nodes = $child->childNodes; - $i = 0; - $found_an_org = false; - foreach($orgs_nodes as $orgnode) - { - //<organization> elements - can contain <item>, <metadata> and <title> - //Here we are at the 'organization' level. There might be several organization tags but - //there is generally only one. - //There are generally three children nodes we are looking for inside and organization: - //-title - //-item (may contain other item tags or may appear several times inside organization) - //-metadata (relative to the organization) - $found_an_org = false; - switch($orgnode->nodeType){ - case XML_TEXT_NODE: - //ignore here - break; - case XML_ATTRIBUTE_NODE: - //just in case there would be interesting attributes inside the organization tag. There shouldn't - //as this is a node-level, not a data level - //$manifest['organizations'][$i][$orgnode->name] = $orgnode->value; - //$found_an_org = true; - break; - case XML_ELEMENT_NODE: - //<item>,<metadata> or <title> (or attributes) - $organizations_attributes = $orgnode->attributes; - foreach($organizations_attributes as $orgs_attr) - { - $this->organizations_att[$orgs_attr->name] = $orgs_attr->value; - } - $oOrganization = new scormOrganization('manifest',$orgnode,$this->manifest_encoding); - if($oOrganization->identifier != ''){ - $name = $oOrganization->get_name(); - if(empty($name)){ - //if the org title is empty, use zip file name - $myname = $this->zipname; - if($this->lastzipnameindex != 0){ - $myname = $myname + $this->lastzipnameindex; - $this->lastzipnameindex++; - } - $oOrganization->set_name($this->zipname); - } - $this->organizations[$oOrganization->identifier] = $oOrganization; - } - break; - } - } - break; - case 'resources': - if($child->hasAttributes()){ - $resources_attribs = $child->attributes; - foreach($resources_attribs as $res_attr) - { - if($res_attr->type == XML_ATTRIBUTE_NODE){ - $this->manifest['resources'][$res_attr->name] = $res_attr->value; - } - } - } - if($child->hasChildNodes()){ - $resources_nodes = $child->childNodes; - $i = 0; - foreach($resources_nodes as $res_node) - { - $oResource = new scormResource('manifest',$res_node); - if($oResource->identifier != ''){ + $this->manifest['name'] = $root->tagName; + if ($root->hasChildNodes()) { + $children = $root->childNodes; + if ($children->length !== 0) { + foreach($children as $child) { + // <manifest> element children (can be <metadata>, <organizations> or <resources> ) + if ($child->nodeType == XML_ELEMENT_NODE) { + switch($child->tagName) { + case 'metadata': + // Parse items from inside the <metadata> element. + $this->metadata = new scormMetadata('manifest',$child); + break; + case 'organizations': + // Contains the course structure - this element appears 1 and only 1 time in a package imsmanifest. It contains at least one 'organization' sub-element. + $orgs_attribs = $child->attributes; + foreach($orgs_attribs as $orgs_attrib) { + // Attributes of the <organizations> element. + if ($orgs_attrib->nodeType == XML_ATTRIBUTE_NODE) { + $this->manifest['organizations'][$orgs_attrib->name] = $orgs_attrib->value; + } + } + $orgs_nodes = $child->childNodes; + $i = 0; + $found_an_org = false; + foreach ($orgs_nodes as $orgnode) { + // <organization> elements - can contain <item>, <metadata> and <title> + // Here we are at the 'organization' level. There might be several organization tags but + // there is generally only one. + // There are generally three children nodes we are looking for inside and organization: + // -title + // -item (may contain other item tags or may appear several times inside organization) + // -metadata (relative to the organization) + $found_an_org = false; + switch($orgnode->nodeType) { + case XML_TEXT_NODE: + // Ignore here. + break; + case XML_ATTRIBUTE_NODE: + // Just in case there would be interesting attributes inside the organization tag. There shouldn't + // as this is a node-level, not a data level. + //$manifest['organizations'][$i][$orgnode->name] = $orgnode->value; + //$found_an_org = true; + break; + case XML_ELEMENT_NODE: + // <item>, <metadata> or <title> (or attributes) + $organizations_attributes = $orgnode->attributes; + foreach ($organizations_attributes as $orgs_attr) { + $this->organizations_att[$orgs_attr->name] = $orgs_attr->value; + } + $oOrganization = new scormOrganization('manifest',$orgnode,$this->manifest_encoding); + if ($oOrganization->identifier != '') { + $name = $oOrganization->get_name(); + if (empty($name)) { + // If the org title is empty, use zip file name. + $myname = $this->zipname; + if ($this->lastzipnameindex != 0) { + $myname = $myname + $this->lastzipnameindex; + $this->lastzipnameindex++; + } + $oOrganization->set_name($this->zipname); + } + $this->organizations[$oOrganization->identifier] = $oOrganization; + } + break; + } + } + break; + case 'resources': + if ($child->hasAttributes()) { + $resources_attribs = $child->attributes; + foreach ($resources_attribs as $res_attr) { + if ($res_attr->type == XML_ATTRIBUTE_NODE) { + $this->manifest['resources'][$res_attr->name] = $res_attr->value; + } + } + } + if ($child->hasChildNodes()) { + $resources_nodes = $child->childNodes; + $i = 0; + foreach ($resources_nodes as $res_node) { + $oResource = new scormResource('manifest', $res_node); + if ($oResource->identifier != '') { $this->resources[$oResource->identifier] = $oResource; - $i++; - } - } - } - //contains links to physical resources - break; - case 'manifest': - //only for sub-manifests - break; - } - } - } - } + $i++; + } + } + } + // Contains links to physical resources. + break; + case 'manifest': + // Only for sub-manifests. + break; + } + } + } + } } - unset($doc); - }else{ - if($this->debug>0){error_log('In scorm::parse_manifest() - PHP version is not 4 nor 5, cannot parse',0);} - $this->set_error_msg("Parsing impossible because PHP version is not 4 nor 5"); - return null; + unset($doc); + } else { + if ($this->debug > 0) { error_log('In scorm::parse_manifest() - PHP version is not 4 nor 5, cannot parse', 0); } + $this->set_error_msg("Parsing impossible because PHP version is not 4 nor 5"); + return null; } - }else{ - if($this->debug>1){error_log('New LP - Could not open/read file '.$file,0);} - $this->set_error_msg("File $file could not be read"); - return null; - } - //TODO close the DOM handler - return $this->manifest; - } - /** - * Import the scorm object (as a result from the parse_manifest function) into the database structure - * @param string Unique course code - * @return bool Returns -1 on error - */ - function import_manifest($course_code){ - if($this->debug>0){error_log('New LP - Entered import_manifest('.$course_code.')',0);} + } else { + if ($this->debug > 1) { error_log('New LP - Could not open/read file '.$file, 0); } + $this->set_error_msg("File $file could not be read"); + return null; + } + // TODO: close the DOM handler + return $this->manifest; + } + + /** + * Import the scorm object (as a result from the parse_manifest function) into the database structure + * @param string Unique course code + * @return bool Returns -1 on error + */ + function import_manifest($course_code) { + if ($this->debug > 0) { error_log('New LP - Entered import_manifest('.$course_code.')', 0); } $sql = "SELECT * FROM ".Database::get_main_table(TABLE_MAIN_COURSE)." WHERE code='$course_code'"; - $res = Database::query($sql); - if(Database::num_rows($res)<1){ error_log('Database for '.$course_code.' not found '.__FILE__.' '.__LINE__,0);return -1;} - $row = Database::fetch_array($res); - $dbname = $row['db_name']; + $res = Database::query($sql); + if (Database::num_rows($res) < 1) { error_log('Database for '.$course_code.' not found '.__FILE__.' '.__LINE__,0); return -1; } + $row = Database::fetch_array($res); + $dbname = $row['db_name']; - //get table names + // Get table names. $new_lp = Database::get_course_table(TABLE_LP_MAIN, $dbname); $new_lp_item = Database::get_course_table(TABLE_LP_ITEM, $dbname); - foreach($this->organizations as $id => $dummy) - { - $is_session=api_get_session_id(); - $is_session!=0?$session_id=$is_session:$session_id=0; + foreach($this->organizations as $id => $dummy) { + $is_session = api_get_session_id(); + $is_session != 0 ? $session_id = $is_session : $session_id = 0; $oOrganization =& $this->organizations[$id]; - //prepare and execute insert queries - //-for learnpath - //-for items - //-for views? - $get_max = "SELECT MAX(display_order) FROM $new_lp"; - $res_max = Database::query($get_max); - $dsp = 1; - if(Database::num_rows($res_max)>0){ - $row = Database::fetch_array($res_max); - $dsp = $row[0]+1; - } - $myname = $oOrganization->get_name(); - //$this->manifest_encoding = 'UTF-8'; - global $charset; - if(!empty($charset) && !empty($this->manifest_encoding) && $this->manifest_encoding != $charset){ - $myname = api_convert_encoding($myname,$charset,$this->manifest_encoding); - } + // Prepare and execute insert queries: + // -for learnpath + // -for items + // -for views? + $get_max = "SELECT MAX(display_order) FROM $new_lp"; + $res_max = Database::query($get_max); + $dsp = 1; + if (Database::num_rows($res_max) > 0) { + $row = Database::fetch_array($res_max); + $dsp = $row[0] + 1; + } + $myname = $oOrganization->get_name(); + //$this->manifest_encoding = 'UTF-8'; + global $charset; + if (!empty($charset) && !empty($this->manifest_encoding) && $this->manifest_encoding != $charset) { + $myname = api_convert_encoding($myname, $charset, $this->manifest_encoding); + } $sql = "INSERT INTO $new_lp (lp_type, name, ref, description, path, force_commit, default_view_mod, default_encoding, js_lib,display_order, session_id)" . "VALUES (2,'".$myname."', '".$oOrganization->get_ref()."','','".$this->subdir."', 0, 'embedded', '".$this->manifest_encoding."','scorm_api.php',$dsp,$session_id)"; - if($this->debug>1){error_log('New LP - In import_manifest(), inserting path: '. $sql,0);} - + if ($this->debug > 1) { error_log('New LP - In import_manifest(), inserting path: '. $sql, 0); } $res = Database::query($sql); $lp_id = Database::insert_id(); $this->lp_id = $lp_id; - //insert into item_property + // Insert into item_property. api_item_property_update(api_get_course_info($course_code),TOOL_LEARNPATH,$this->lp_id,'LearnpathAdded',api_get_user_id()); api_item_property_update(api_get_course_info($course_code),TOOL_LEARNPATH,$this->lp_id,'visible',api_get_user_id()); - //now insert all elements from inside that learning path - //make sure we also get the href and sco/asset from the resources + // Now insert all elements from inside that learning path. + // Make sure we also get the href and sco/asset from the resources. $list = $oOrganization->get_flat_items_list(); $parents_stack = array(0); $parent = 0; $previous = 0; $level = 0; - foreach($list as $item){ - if($item['level'] > $level){ - //push something into the parents array - array_push($parents_stack,$previous); + foreach ($list as $item) { + if ($item['level'] > $level) { + // Push something into the parents array. + array_push($parents_stack, $previous); $parent = $previous; - }elseif($item['level'] < $level){ + } elseif ($item['level'] < $level) { $diff = $level - $item['level']; - //pop something out of the parents array - for($j=1;$j<=$diff;$j++){ + // Pop something out of the parents array. + for ($j = 1; $j <= $diff; $j++) { $outdated_parent = array_pop($parents_stack); } - $parent = array_pop($parents_stack); //just save that value, then add it back + $parent = array_pop($parents_stack); // Just save that value, then add it back. array_push($parents_stack,$parent); } $path = ''; $type = 'dir'; - if(isset($this->resources[$item['identifierref']])){ + if (isset($this->resources[$item['identifierref']])) { $oRes =& $this->resources[$item['identifierref']]; $path = @$oRes->get_path(); - if(!empty($path)){ + if (!empty($path)) { $temptype = $oRes->get_scorm_type(); - if(!empty($temptype)){ + if (!empty($temptype)) { $type = $temptype; } } @@ -439,29 +430,28 @@ class scorm extends learnpath { $level = $item['level']; $field_add = ''; $value_add = ''; - if(!empty($item['masteryscore'])){ + if (!empty($item['masteryscore'])) { $field_add .= 'mastery_score, '; $value_add .= $item['masteryscore'].','; } - if(!empty($item['maxtimeallowed'])) - { + if (!empty($item['maxtimeallowed'])) { $field_add .= 'max_time_allowed, '; $value_add .= "'".$item['maxtimeallowed']."',"; } $title = Database::escape_string($item['title']); $max_score = Database::escape_string($item['max_score']); - if ($max_score==0 || is_null($max_score) || $max_score=='') { - $max_score=100; + if ($max_score == 0 || is_null($max_score) || $max_score == '') { + $max_score = 100; + } + // DOM in PHP5 is always recovering data as UTF-8, somehow, no matter what + // the XML document encoding is. This means that we have to convert + // the data to the declared encoding when it is not UTF-8. + if ($this->manifest_encoding != 'UTF-8') { + $title = api_convert_encoding($title, $this->manifest_encoding, 'UTF-8'); } - //DOM in PHP5 is always recovering data as UTF-8, somehow, no matter what - //the XML document encoding is. This means that we have to convert - //the data to the declared encoding when it is not UTF-8 - if($this->manifest_encoding != 'UTF-8'){ - $title = api_convert_encoding($title,$this->manifest_encoding,'UTF-8'); - } - //if($this->manifest_encoding != $charset){ - // $title = api_convert_encoding($title,$charset,$this->manifest_encoding); - //} + //if ($this->manifest_encoding != $charset) { + // $title = api_convert_encoding($title, $charset, $this->manifest_encoding); + //} $identifier = Database::escape_string($item['identifier']); $prereq = Database::escape_string($item['prerequisites']); $sql_item = "INSERT INTO $new_lp_item " . @@ -478,25 +468,25 @@ class scorm extends learnpath { "'".$item['parameters']."'" . ")"; $res_item = Database::query($sql_item); - if($this->debug>1){error_log('New LP - In import_manifest(), inserting item : '.$sql_item.' : '.mysql_error(),0);} + if ($this->debug > 1) { error_log('New LP - In import_manifest(), inserting item : '.$sql_item.' : '.mysql_error(), 0); } $item_id = Database::insert_id(); - //now update previous item to change next_item_id + // Now update previous item to change next_item_id. $upd = "UPDATE $new_lp_item SET next_item_id = $item_id WHERE id = $previous"; $upd_res = Database::query($upd); - //update previous item id + // Update previous item id. $previous = $item_id; - // code for indexing, now only index specific fields like terms and the title + // Code for indexing, now only index specific fields like terms and the title. if (!empty($_POST['index_document'])) { require_once api_get_path(LIBRARY_PATH).'search/DokeosIndexer.class.php'; require_once api_get_path(LIBRARY_PATH).'search/IndexableChunk.class.php'; require_once api_get_path(LIBRARY_PATH).'specific_fields_manager.lib.php'; $di = new DokeosIndexer(); - isset($_POST['language'])? $lang=Database::escape_string($_POST['language']): $lang = 'english'; + isset($_POST['language']) ? $lang = Database::escape_string($_POST['language']) : $lang = 'english'; $di->connectDb(NULL, NULL, $lang); $ic_slide = new IndexableChunk(); - $ic_slide->addValue("title", $title); + $ic_slide->addValue('title', $title); $specific_fields = get_specific_field_list(); $all_specific_terms = ''; foreach ($specific_fields as $specific_field) { @@ -513,231 +503,212 @@ class scorm extends learnpath { } $body_to_index = $all_specific_terms .' '. $title; $ic_slide->addValue("content", $body_to_index); - //TODO: add a comment to say terms separated by commas + // TODO: Add a comment to say terms separated by commas. $courseid = api_get_course_id(); $ic_slide->addCourseId($courseid); $ic_slide->addToolId(TOOL_LEARNPATH); $xapian_data = array( SE_COURSE_ID => $courseid, SE_TOOL_ID => TOOL_LEARNPATH, - SE_DATA => array('lp_id' => $lp_id, 'lp_item'=> $previous, 'document_id' => ''), //TODO unify with other lp types + SE_DATA => array('lp_id' => $lp_id, 'lp_item'=> $previous, 'document_id' => ''), // TODO: Unify with other lp types. SE_USER => (int)api_get_user_id(), ); $ic_slide->xapian_data = serialize($xapian_data); $di->addChunk($ic_slide); - //index and return search engine document id + // Index and return search engine document id. $did = $di->index(); if ($did) { - // save it to db - $tbl_se_ref = Database::get_main_table(TABLE_MAIN_SEARCH_ENGINE_REF); - $sql = 'INSERT INTO %s (id, course_code, tool_id, ref_id_high_level, ref_id_second_level, search_did) - VALUES (NULL , \'%s\', \'%s\', %s, %s, %s)'; - $sql = sprintf($sql, $tbl_se_ref, api_get_course_id(), TOOL_LEARNPATH, $lp_id, $previous, $did); - Database::query($sql); + // Save it to db. + $tbl_se_ref = Database::get_main_table(TABLE_MAIN_SEARCH_ENGINE_REF); + $sql = 'INSERT INTO %s (id, course_code, tool_id, ref_id_high_level, ref_id_second_level, search_did) + VALUES (NULL , \'%s\', \'%s\', %s, %s, %s)'; + $sql = sprintf($sql, $tbl_se_ref, api_get_course_id(), TOOL_LEARNPATH, $lp_id, $previous, $did); + Database::query($sql); } } - } } - } - /** - * Intermediate to import_package only to allow import from local zip files - * @param string Path to the zip file, from the dokeos sys root - * @param string Current path (optional) - * @return string Absolute path to the imsmanifest.xml file or empty string on error - */ - function import_local_package($file_path,$current_dir='') - { - //todo prepare info as given by the $_FILES[''] vector - $file_info = array(); - $file_info['tmp_name'] = $file_path; - $file_info['name'] = basename($file_path); - //call the normal import_package function - return $this->import_package($file_info,$current_dir); - } - /** - * Imports a zip file into the Dokeos structure - * @param string Zip file info as given by $_FILES['userFile'] - * @return string Absolute path to the imsmanifest.xml file or empty string on error - */ - function import_package($zip_file_info,$current_dir = '') - { - if($this->debug>0){error_log('In scorm::import_package('.print_r($zip_file_info,true).',"'.$current_dir.'") method',0);} - require_once api_get_path(LIBRARY_PATH).'document.lib.php'; - $maxFilledSpace = DocumentManager :: get_course_quota(); - //$maxFilledSpace = 1000000000; - - $zip_file_path = $zip_file_info['tmp_name']; - $zip_file_name = $zip_file_info['name']; - if($this->debug>1){error_log('New LP - import_package() - zip file path = '.$zip_file_path.', zip file name = '.$zip_file_name,0);} - $course_rel_dir = api_get_course_path().'/scorm'; //scorm dir web path starting from /courses - $course_sys_dir = api_get_path(SYS_COURSE_PATH).$course_rel_dir; //absolute system path for this course - $current_dir = replace_dangerous_char(trim($current_dir),'strict'); //current dir we are in, inside scorm/ - if($this->debug>1){error_log('New LP - import_package() - current_dir = '.$current_dir,0);} + } + + /** + * Intermediate to import_package only to allow import from local zip files + * @param string Path to the zip file, from the dokeos sys root + * @param string Current path (optional) + * @return string Absolute path to the imsmanifest.xml file or empty string on error + */ + function import_local_package($file_path, $current_dir = '') { + // TODO: Prepare info as given by the $_FILES[''] vector. + $file_info = array(); + $file_info['tmp_name'] = $file_path; + $file_info['name'] = basename($file_path); + // Call the normal import_package function. + return $this->import_package($file_info, $current_dir); + } + + /** + * Imports a zip file into the Chamilo structure + * @param string Zip file info as given by $_FILES['userFile'] + * @return string Absolute path to the imsmanifest.xml file or empty string on error + */ + function import_package($zip_file_info, $current_dir = '') { + if ($this->debug > 0) { error_log('In scorm::import_package('.print_r($zip_file_info,true).',"'.$current_dir.'") method', 0); } + require_once api_get_path(LIBRARY_PATH).'document.lib.php'; + $maxFilledSpace = DocumentManager :: get_course_quota(); + //$maxFilledSpace = 1000000000; + + $zip_file_path = $zip_file_info['tmp_name']; + $zip_file_name = $zip_file_info['name']; + if ($this->debug > 1) { error_log('New LP - import_package() - zip file path = '.$zip_file_path.', zip file name = '.$zip_file_name, 0); } + $course_rel_dir = api_get_course_path().'/scorm'; // scorm dir web path starting from /courses + $course_sys_dir = api_get_path(SYS_COURSE_PATH).$course_rel_dir; // Sbsolute system path for this course. + $current_dir = replace_dangerous_char(trim($current_dir),'strict'); // Current dir we are in, inside scorm/ + if ($this->debug > 1) { error_log('New LP - import_package() - current_dir = '.$current_dir, 0); } //$uploaded_filename = $_FILES['userFile']['name']; - //get name of the zip file without the extension - if($this->debug>1){error_log('New LP - Received zip file name: '.$zip_file_path,0);} + // Get name of the zip file without the extension. + if ($this->debug > 1) { error_log('New LP - Received zip file name: '.$zip_file_path, 0); } $file_info = pathinfo($zip_file_name); $filename = $file_info['basename']; $extension = $file_info['extension']; - $file_base_name = str_replace('.'.$extension,'',$filename); //filename without its extension - $this->zipname = $file_base_name; //save for later in case we don't have a title + $file_base_name = str_replace('.'.$extension,'',$filename); // Filename without its extension. + $this->zipname = $file_base_name; // Save for later in case we don't have a title. - if($this->debug>1){error_log("New LP - base file name is : ".$file_base_name,0);} + if ($this->debug > 1) { error_log("New LP - base file name is : ".$file_base_name, 0); } $new_dir = replace_dangerous_char(trim($file_base_name),'strict'); $this->subdir = $new_dir; - if($this->debug>1){error_log("New LP - subdir is first set to : ".$this->subdir,0);} + if ($this->debug > 1) { error_log("New LP - subdir is first set to : ".$this->subdir, 0); } $zipFile = new pclZip($zip_file_path); - // Check the zip content (real size and file extension) + // Check the zip content (real size and file extension). $zipContentArray = $zipFile->listContent(); - $package_type=''; + $package_type = ''; $at_root = false; $manifest = ''; $manifest_list = array(); - //the following loop should be stopped as soon as we found the right imsmanifest.xml (how to recognize it?) - foreach($zipContentArray as $thisContent) - { - //error_log('Looking at '.$thisContent['filename'],0); - if ( preg_match('~.(php.*|phtml)$~i', $thisContent['filename']) ) - { - $this->set_error_msg("File $file contains a PHP script"); + // The following loop should be stopped as soon as we found the right imsmanifest.xml (how to recognize it?). + foreach($zipContentArray as $thisContent) { + //error_log('Looking at '.$thisContent['filename'], 0); + if (preg_match('~.(php.*|phtml)$~i', $thisContent['filename'])) { + $this->set_error_msg("File $file contains a PHP script"); //return api_failure::set_failure('php_file_in_zip_file'); - } - elseif(stristr($thisContent['filename'],'imsmanifest.xml')) - { - //error_log('Found imsmanifest at '.$thisContent['filename'],0); - if($thisContent['filename'] == basename($thisContent['filename'])){ + } elseif (stristr($thisContent['filename'], 'imsmanifest.xml')) { + //error_log('Found imsmanifest at '.$thisContent['filename'], 0); + if ($thisContent['filename'] == basename($thisContent['filename'])) { $at_root = true; - }else{ + } else { //$this->subdir .= '/'.dirname($thisContent['filename']); - if($this->debug>2){error_log("New LP - subdir is now ".$this->subdir,0);} + if ($this->debug > 2) { error_log("New LP - subdir is now ".$this->subdir, 0); } } $package_type = 'scorm'; $manifest_list[] = $thisContent['filename']; $manifest = $thisContent['filename']; //just the relative directory inside scorm/ - } - else - { - //do nothing, if it has not been set as scorm somewhere else, it stays as '' default + } else { + // Do nothing, if it has not been set as scorm somewhere else, it stays as '' default. } $realFileSize += $thisContent['size']; } - //now get the shortest path (basically, the imsmanifest that is the closest to the root) + // Now get the shortest path (basically, the imsmanifest that is the closest to the root). $shortest_path = $manifest_list[0]; - $slash_count = substr_count($shortest_path,'/'); - foreach($manifest_list as $manifest_path){ - $tmp_slash_count = substr_count($manifest_path,'/'); - if($tmp_slash_count<$slash_count){ + $slash_count = substr_count($shortest_path, '/'); + foreach ($manifest_list as $manifest_path) { + $tmp_slash_count = substr_count($manifest_path, '/'); + if ($tmp_slash_count<$slash_count) { $shortest_path = $manifest_path; $slash_count = $tmp_slash_count; } } - $this->subdir .= '/'.dirname($shortest_path); //do not concatenate because already done above + $this->subdir .= '/'.dirname($shortest_path); // Do not concatenate because already done above. $manifest = $shortest_path; - if($this->debug>1){error_log('New LP - Package type is now '.$package_type,0);} + if ($this->debug > 1) { error_log('New LP - Package type is now '.$package_type, 0); } - if($package_type== '') - // && defined('CHECK_FOR_SCORM') && CHECK_FOR_SCORM) + if ($package_type== '') + // && defined('CHECK_FOR_SCORM') && CHECK_FOR_SCORM) { - if($this->debug>1){error_log('New LP - Package type is empty',0);} + if ($this->debug > 1) { error_log('New LP - Package type is empty', 0); } return api_failure::set_failure('not_scorm_content'); } - if (! enough_size($realFileSize, $course_sys_dir, $maxFilledSpace) ) - { - if($this->debug>1){error_log('New LP - Not enough space to store package',0);} + if (!enough_size($realFileSize, $course_sys_dir, $maxFilledSpace)) { + if ($this->debug > 1) { error_log('New LP - Not enough space to store package', 0); } return api_failure::set_failure('not_enough_space'); } - // it happens on Linux that $new_dir sometimes doesn't start with '/' - if($new_dir[0] != '/') - { - $new_dir='/'.$new_dir; + // It happens on Linux that $new_dir sometimes doesn't start with '/' + if ($new_dir[0] != '/') { + $new_dir = '/'.$new_dir; } - if($new_dir[strlen($new_dir)-1] == '/') - { - $new_dir=substr($new_dir,0,-1); + if ($new_dir[strlen($new_dir)-1] == '/') { + $new_dir = substr($new_dir,0,-1); } - /* - -------------------------------------- - Uncompressing phase - -------------------------------------- - */ + /* Uncompressing phase */ + /* We need to process each individual file in the zip archive to - add it to the database - parse & change relative html links - make sure the filenames are secure (filter funny characters or php extensions) */ - if(is_dir($course_sys_dir.$new_dir) OR @mkdir($course_sys_dir.$new_dir, api_get_permissions_for_new_directories())) - { + if (is_dir($course_sys_dir.$new_dir) OR @mkdir($course_sys_dir.$new_dir, api_get_permissions_for_new_directories())) { // PHP method - slower... - if($this->debug>=1){error_log('New LP - Changing dir to '.$course_sys_dir.$new_dir,0);} + if ($this->debug >= 1) { error_log('New LP - Changing dir to '.$course_sys_dir.$new_dir, 0); } $saved_dir = getcwd(); chdir($course_sys_dir.$new_dir); $unzippingState = $zipFile->extract(); - for($j=0;$j<count($unzippingState);$j++) - { - $state=$unzippingState[$j]; + for($j = 0; $j < count($unzippingState); $j++) { + $state = $unzippingState[$j]; - //TODO fix relative links in html files (?) - $extension = strrchr($state["stored_filename"], "."); - if($this->debug>=1){error_log('New LP - found extension '.$extension.' in '.$state['stored_filename'],0);} + // TODO: Fix relative links in html files (?) + $extension = strrchr($state['stored_filename'], '.'); + if ($this->debug >= 1) { error_log('New LP - found extension '.$extension.' in '.$state['stored_filename'], 0); } } - if(!empty($new_dir)) - { + if (!empty($new_dir)) { $new_dir = $new_dir.'/'; } - //rename files, for example with \\ in it - if($dir=@opendir($course_sys_dir.$new_dir)) - { - if($this->debug==1){error_log('New LP - Opened dir '.$course_sys_dir.$new_dir,0);} - while($file=readdir($dir)) - { - if($file != '.' && $file != '..') - { - $filetype="file"; - - if(is_dir($course_sys_dir.$new_dir.$file)) $filetype="folder"; - - //TODO RENAMING FILES CAN BE VERY DANGEROUS SCORM-WISE, avoid that as much as possible! - //$safe_file=replace_dangerous_char($file,'strict'); - $find_str = array('\\','.php','.phtml'); - $repl_str = array('/', '.txt','.txt'); - $safe_file = str_replace($find_str,$repl_str,$file); - - if($safe_file != $file){ - //@rename($course_sys_dir.$new_dir,$course_sys_dir.'/'.$safe_file); + // Rename files, for example with \\ in it. + if ($dir = @opendir($course_sys_dir.$new_dir)) { + if ($this->debug == 1) { error_log('New LP - Opened dir '.$course_sys_dir.$new_dir, 0); } + while ($file=readdir($dir)) { + if ($file != '.' && $file != '..') { + $filetype = 'file'; + + if (is_dir($course_sys_dir.$new_dir.$file)) $filetype = 'folder'; + + // TODO: RENAMING FILES CAN BE VERY DANGEROUS SCORM-WISE, avoid that as much as possible! + //$safe_file = replace_dangerous_char($file, 'strict'); + $find_str = array('\\', '.php', '.phtml'); + $repl_str = array('/', '.txt', '.txt'); + $safe_file = str_replace($find_str, $repl_str,$file); + + if ($safe_file != $file) { + //@rename($course_sys_dir.$new_dir, $course_sys_dir.'/'.$safe_file); $mydir = dirname($course_sys_dir.$new_dir.$safe_file); - if(!is_dir($mydir)){ - $mysubdirs = split('/',$mydir); + if (!is_dir($mydir)) { + $mysubdirs = split('/', $mydir); $mybasedir = '/'; - foreach($mysubdirs as $mysubdir){ - if(!empty($mysubdir)){ + foreach ($mysubdirs as $mysubdir) { + if (!empty($mysubdir)) { $mybasedir = $mybasedir.$mysubdir.'/'; - if(!is_dir($mybasedir)){ + if (!is_dir($mybasedir)) { @mkdir($mybasedir, api_get_permissions_for_new_directories()); - if($this->debug==1){error_log('New LP - Dir '.$mybasedir.' doesnt exist. Creating.',0);} + if ($this->debug == 1) { error_log('New LP - Dir '.$mybasedir.' doesnt exist. Creating.', 0); } } } } } @rename($course_sys_dir.$new_dir.$file,$course_sys_dir.$new_dir.$safe_file); - if($this->debug==1){error_log('New LP - Renaming '.$course_sys_dir.$new_dir.$file.' to '.$course_sys_dir.$new_dir.$safe_file,0);} + if ($this->debug == 1) { error_log('New LP - Renaming '.$course_sys_dir.$new_dir.$file.' to '.$course_sys_dir.$new_dir.$safe_file, 0); } } - //set_default_settings($course_sys_dir,$safe_file,$filetype); + //set_default_settings($course_sys_dir, $safe_file, $filetype); } } @@ -745,7 +716,7 @@ class scorm extends learnpath { chdir($saved_dir); api_chmod_R($course_sys_dir.$new_dir, api_get_permissions_for_new_directories()); - if($this->debug>1){error_log('New LP - changed back to init dir',0);} + if ($this->debug > 1) { error_log('New LP - changed back to init dir', 0); } } } else { return ''; @@ -757,114 +728,108 @@ class scorm extends learnpath { * Sets the proximity setting in the database * @param string Proximity setting */ - function set_proximity($proxy=''){ - if($this->debug>0){error_log('In scorm::set_proximity('.$proxy.') method',0);} - $lp = $this->get_id(); - if($lp!=0){ - $tbl_lp = Database::get_course_table(TABLE_LP_MAIN); - $sql = "UPDATE $tbl_lp SET content_local = '$proxy' WHERE id = ".$lp; - $res = Database::query($sql); - return $res; - } else { - return false; - } - } - - /** + function set_proximity($proxy = '') { + if ($this->debug > 0) { error_log('In scorm::set_proximity('.$proxy.') method', 0); } + $lp = $this->get_id(); + if ($lp != 0) { + $tbl_lp = Database::get_course_table(TABLE_LP_MAIN); + $sql = "UPDATE $tbl_lp SET content_local = '$proxy' WHERE id = ".$lp; + $res = Database::query($sql); + return $res; + } else { + return false; + } + } + + /** * Sets the theme setting in the database * @param string theme setting */ - function set_theme($theme=''){ - if($this->debug>0){error_log('In scorm::set_theme('.$theme.') method',0);} - $lp = $this->get_id(); - if($lp!=0){ - $tbl_lp = Database::get_course_table(TABLE_LP_MAIN); - $sql = "UPDATE $tbl_lp SET theme = '$theme' WHERE id = ".$lp; - $res = Database::query($sql); - return $res; - }else{ - return false; - } - } - - /** - * Sets the image setting in the database - * @param string preview_image setting - */ - function set_preview_image($preview_image=''){ - if($this->debug>0){error_log('In scorm::set_theme('.$preview_image.') method',0);} - $lp = $this->get_id(); - if($lp!=0){ - $tbl_lp = Database::get_course_table(TABLE_LP_MAIN); - $sql = "UPDATE $tbl_lp SET preview_image = '$preview_image' WHERE id = ".$lp; - $res = Database::query($sql); - return $res; - }else{ - return false; - } - } - - - /** - * Sets the author setting in the database + function set_theme($theme = '') { + if ($this->debug > 0) { error_log('In scorm::set_theme('.$theme.') method', 0); } + $lp = $this->get_id(); + if ($lp != 0) { + $tbl_lp = Database::get_course_table(TABLE_LP_MAIN); + $sql = "UPDATE $tbl_lp SET theme = '$theme' WHERE id = ".$lp; + $res = Database::query($sql); + return $res; + } else { + return false; + } + } + + /** + * Sets the image setting in the database * @param string preview_image setting */ - function set_author($author=''){ - if($this->debug>0){error_log('In scorm::set_author('.$author.') method',0);} - $lp = $this->get_id(); - if($lp!=0){ - $tbl_lp = Database::get_course_table(TABLE_LP_MAIN); - $sql = "UPDATE $tbl_lp SET author = '$author' WHERE id = ".$lp; - $res = Database::query($sql); - return $res; - }else{ - return false; - } - } - - + function set_preview_image($preview_image = '') { + if ($this->debug > 0) { error_log('In scorm::set_theme('.$preview_image.') method', 0); } + $lp = $this->get_id(); + if ($lp != 0) { + $tbl_lp = Database::get_course_table(TABLE_LP_MAIN); + $sql = "UPDATE $tbl_lp SET preview_image = '$preview_image' WHERE id = ".$lp; + $res = Database::query($sql); + return $res; + } else { + return false; + } + } + /** + * Sets the author setting in the database + * @param string preview_image setting + */ + function set_author($author = '') { + if ($this->debug > 0) { error_log('In scorm::set_author('.$author.') method', 0); } + $lp = $this->get_id(); + if ($lp != 0) { + $tbl_lp = Database::get_course_table(TABLE_LP_MAIN); + $sql = "UPDATE $tbl_lp SET author = '$author' WHERE id = ".$lp; + $res = Database::query($sql); + return $res; + } else { + return false; + } + } /** * Sets the content maker setting in the database * @param string Proximity setting */ - function set_maker($maker=''){ - if($this->debug>0){error_log('In scorm::set_maker method('.$maker.')',0);} - $lp = $this->get_id(); - if($lp!=0){ - $tbl_lp = Database::get_course_table(TABLE_LP_MAIN); - $sql = "UPDATE $tbl_lp SET content_maker = '$maker' WHERE id = ".$lp; - $res = Database::query($sql); - return $res; - } else { - return false; - } - } - /** - * Exports the current SCORM object's files as a zip. Excerpts taken from learnpath_functions.inc.php::exportpath() - * @param integer Learnpath ID (optional, taken from object context if not defined) - */ - function export_zip($lp_id=null){ - if($this->debug>0){error_log('In scorm::export_zip method('.$lp_id.')',0);} - if(empty($lp_id)){ - if(!is_object($this)) - { + function set_maker($maker = '') { + if ($this->debug > 0) { error_log('In scorm::set_maker method('.$maker.')', 0); } + $lp = $this->get_id(); + if ($lp != 0) { + $tbl_lp = Database::get_course_table(TABLE_LP_MAIN); + $sql = "UPDATE $tbl_lp SET content_maker = '$maker' WHERE id = ".$lp; + $res = Database::query($sql); + return $res; + } else { + return false; + } + } + + /** + * Exports the current SCORM object's files as a zip. Excerpts taken from learnpath_functions.inc.php::exportpath() + * @param integer Learnpath ID (optional, taken from object context if not defined) + */ + function export_zip($lp_id = null) { + if ($this->debug > 0) { error_log('In scorm::export_zip method('.$lp_id.')', 0); } + if (empty($lp_id)) { + if (!is_object($this)) { return false; - } - else{ + } else { $id = $this->get_id(); - if(empty($id)){ + if (empty($id)) { return false; + } else { + $lp_id = $this->get_id(); } - else{ - $lp_id = $this->get_id(); - } } - } - //error_log('New LP - in export_zip()',0); - //zip everything that is in the corresponding scorm dir - //write the zip file somewhere (might be too big to return) + } + //error_log('New LP - in export_zip()',0); + //zip everything that is in the corresponding scorm dir + //write the zip file somewhere (might be too big to return) require_once api_get_path(LIBRARY_PATH).'fileUpload.lib.php'; require_once api_get_path(LIBRARY_PATH).'fileManage.lib.php'; require_once api_get_path(LIBRARY_PATH).'document.lib.php'; @@ -877,28 +842,28 @@ class scorm extends learnpath { $result = Database::query($sql); $row = Database::fetch_array($result); $LPname = $row['path']; - $list = split('/',$LPname); + $list = split('/', $LPname); $LPnamesafe = $list[0]; //$zipfoldername = '/tmp'; - //$zipfoldername = '../../courses/'.$_course['directory']."/temp/".$LPnamesafe; - $zipfoldername = api_get_path(SYS_COURSE_PATH).$_course['directory']."/temp/".$LPnamesafe; - $scormfoldername = api_get_path(SYS_COURSE_PATH).$_course['directory']."/scorm/".$LPnamesafe; - $zipfilename = $zipfoldername."/".$LPnamesafe.".zip"; + //$zipfoldername = '../../courses/'.$_course['directory'].'/temp/'.$LPnamesafe; + $zipfoldername = api_get_path(SYS_COURSE_PATH).$_course['directory'].'/temp/'.$LPnamesafe; + $scormfoldername = api_get_path(SYS_COURSE_PATH).$_course['directory'].'/scorm/'.$LPnamesafe; + $zipfilename = $zipfoldername.'/'.$LPnamesafe.'.zip'; - //Get a temporary dir for creating the zip file + // Get a temporary dir for creating the zip file. - //error_log('New LP - cleaning dir '.$zipfoldername,0); - deldir($zipfoldername); //make sure the temp dir is cleared + //error_log('New LP - cleaning dir '.$zipfoldername, 0); + deldir($zipfoldername); // Make sure the temp dir is cleared. $res = mkdir($zipfoldername, api_get_permissions_for_new_directories()); - //error_log('New LP - made dir '.$zipfoldername,0); + //error_log('New LP - made dir '.$zipfoldername, 0); - //create zipfile of given directory + // Create zipfile of given directory. $zip_folder = new PclZip($zipfilename); $zip_folder->create($scormfoldername.'/', PCLZIP_OPT_REMOVE_PATH, $scormfoldername.'/'); //$zipfilename = '/var/www/dokeos-comp/courses/TEST2/scorm/example_document.html'; - //this file sending implies removing the default mime-type from php.ini - //DocumentManager :: file_send_for_download($zipfilename, true, $LPnamesafe.".zip"); + //This file sending implies removing the default mime-type from php.ini + //DocumentManager :: file_send_for_download($zipfilename, true, $LPnamesafe.'.zip'); DocumentManager :: file_send_for_download($zipfilename, true); // Delete the temporary zip file and directory in fileManage.lib.php @@ -907,135 +872,134 @@ class scorm extends learnpath { return true; } + /** - * Gets a resource's path if available, otherwise return empty string - * @param string Resource ID as used in resource array - * @return string The resource's path as declared in imsmanifest.xml - */ - function get_res_path($id){ - if($this->debug>0){error_log('In scorm::get_res_path('.$id.') method',0);} - $path = ''; - if(isset($this->resources[$id])){ + * Gets a resource's path if available, otherwise return empty string + * @param string Resource ID as used in resource array + * @return string The resource's path as declared in imsmanifest.xml + */ + function get_res_path($id) { + if ($this->debug > 0) { error_log('In scorm::get_res_path('.$id.') method', 0); } + $path = ''; + if (isset($this->resources[$id])) { $oRes =& $this->resources[$id]; $path = @$oRes->get_path(); } return $path; - } - /** - * Gets a resource's type if available, otherwise return empty string - * @param string Resource ID as used in resource array - * @return string The resource's type as declared in imsmanifest.xml - */ - function get_res_type($id){ - if($this->debug>0){error_log('In scorm::get_res_type('.$id.') method',0);} - $type = ''; - if(isset($this->resources[$id])){ + } + + /** + * Gets a resource's type if available, otherwise return empty string + * @param string Resource ID as used in resource array + * @return string The resource's type as declared in imsmanifest.xml + */ + function get_res_type($id) { + if ($this->debug > 0) { error_log('In scorm::get_res_type('.$id.') method', 0); } + $type = ''; + if (isset($this->resources[$id])) { $oRes =& $this->resources[$id]; $temptype = $oRes->get_scorm_type(); - if(!empty($temptype)){ + if (!empty($temptype)) { $type = $temptype; } } return $type; - } - /** - * Gets the default organisation's title - * @return string The organization's title - */ - function get_title(){ - if($this->debug>0){error_log('In scorm::get_title() method',0);} - $title = ''; - if(isset($this->manifest['organizations']['default'])){ - $title = $this->organizations[$this->manifest['organizations']['default']]->get_name(); - }elseif(count($this->organizations)==1){ - //this will only get one title but so we don't need to know the index - foreach($this->organizations as $id => $value){ - $title = $this->organizations[$id]->get_name(); - break; - } - } - return $title; - } - /** - * //TODO @TODO implement this function to restore items data from an imsmanifest, - * updating the existing table... This will prove very useful in case initial data - * from imsmanifest were not imported well enough - * @param string course Code - * @param string LP ID (in database) - * @param string Manifest file path (optional if lp_id defined) - * @return integer New LP ID or false on failure - * TODO @TODO Implement imsmanifest_path parameter - */ - function reimport_manifest($course,$lp_id=null,$imsmanifest_path=''){ - if($this->debug>0){error_log('In scorm::reimport_manifest() method',0);} + } + + /** + * Gets the default organisation's title + * @return string The organization's title + */ + function get_title() { + if ($this->debug > 0) { error_log('In scorm::get_title() method', 0); } + $title = ''; + if (isset($this->manifest['organizations']['default'])) { + $title = $this->organizations[$this->manifest['organizations']['default']]->get_name(); + }elseif (count($this->organizations)==1) { + // This will only get one title but so we don't need to know the index. + foreach($this->organizations as $id => $value) { + $title = $this->organizations[$id]->get_name(); + break; + } + } + return $title; + } + + /** + * // TODO @TODO Implement this function to restore items data from an imsmanifest, + * updating the existing table... This will prove very useful in case initial data + * from imsmanifest were not imported well enough + * @param string course Code + * @param string LP ID (in database) + * @param string Manifest file path (optional if lp_id defined) + * @return integer New LP ID or false on failure + * TODO @TODO Implement imsmanifest_path parameter + */ + function reimport_manifest($course, $lp_id = null, $imsmanifest_path = '') { + if ($this->debug > 0) { error_log('In scorm::reimport_manifest() method', 0); } global $_course; - //RECOVERING PATH FROM DB + // RECOVERING PATH FROM DB $main_table = Database::get_main_table(TABLE_MAIN_COURSE); //$course = Database::escape_string($course); $course = $this->escape_string($course); $sql = "SELECT * FROM $main_table WHERE code = '$course'"; - if($this->debug>2){error_log('New LP - scorm::reimport_manifest() '.__LINE__.' - Querying course: '.$sql,0);} + if ($this->debug > 2) { error_log('New LP - scorm::reimport_manifest() '.__LINE__.' - Querying course: '.$sql, 0); } //$res = Database::query($sql); $res = Database::query($sql); - if(Database::num_rows($res)>0) - { + if (Database::num_rows($res) > 0) { $this->cc = $course; - } - else - { + } else { $this->error = 'Course code does not exist in database ('.$sql.')'; return false; } - //TODO make it flexible to use any course_code (still using env course code here) + // TODO: Make it flexible to use any course_code (still using env course code here) //$lp_table = Database::get_course_table(LEARNPATH_TABLE); - $lp_table = Database::get_course_table(TABLE_LP_MAIN); + $lp_table = Database::get_course_table(TABLE_LP_MAIN); //$id = Database::escape_integer($id); $lp_id = $this->escape_string($lp_id); $sql = "SELECT * FROM $lp_table WHERE id = '$lp_id'"; - if($this->debug>2){error_log('New LP - scorm::reimport_manifest() '.__LINE__.' - Querying lp: '.$sql,0);} + if ($this->debug > 2) { error_log('New LP - scorm::reimport_manifest() '.__LINE__.' - Querying lp: '.$sql, 0); } //$res = Database::query($sql); $res = Database::query($sql); - if(Database::num_rows($res)>0) - { - $this->lp_id = $lp_id; - $row = Database::fetch_array($res); - $this->type = $row['lp_type']; - $this->name = stripslashes($row['name']); - $this->encoding = $row['default_encoding']; - $this->proximity = $row['content_local']; - $this->maker = $row['content_maker']; - $this->prevent_reinit = $row['prevent_reinit']; - $this->license = $row['content_license']; - $this->scorm_debug = $row['debug']; - $this->js_lib = $row['js_lib']; - $this->path = $row['path']; - if($this->type == 2){ - if($row['force_commit'] == 1){ - $this->force_commit = true; - } - } - $this->mode = $row['default_view_mod']; + if (Database::num_rows($res) > 0) { + $this->lp_id = $lp_id; + $row = Database::fetch_array($res); + $this->type = $row['lp_type']; + $this->name = stripslashes($row['name']); + $this->encoding = $row['default_encoding']; + $this->proximity = $row['content_local']; + $this->maker = $row['content_maker']; + $this->prevent_reinit = $row['prevent_reinit']; + $this->license = $row['content_license']; + $this->scorm_debug = $row['debug']; + $this->js_lib = $row['js_lib']; + $this->path = $row['path']; + if ($this->type == 2) { + if ($row['force_commit'] == 1) { + $this->force_commit = true; + } + } + $this->mode = $row['default_view_mod']; $this->subdir = $row['path']; } - //parse the manifest (it is already in this lp's details) - $manifest_file = api_get_path(SYS_COURSE_PATH).$_course['directory'].'/scorm/'.$this->subdir.'/imsmanifest.xml'; - if($this->subdir == ''){ - $manifest_file = api_get_path(SYS_COURSE_PATH).$_course['directory'].'/scorm/imsmanifest.xml'; - } - echo $manifest_file; - if(is_file($manifest_file) && is_readable($manifest_file)){ - //re-parse the manifest file - if($this->debug>1){error_log('New LP - In scorm::reimport_manifest() - Parsing manifest '.$manifest_file,0);} + // Parse the manifest (it is already in this lp's details). + $manifest_file = api_get_path(SYS_COURSE_PATH).$_course['directory'].'/scorm/'.$this->subdir.'/imsmanifest.xml'; + if ($this->subdir == '') { + $manifest_file = api_get_path(SYS_COURSE_PATH).$_course['directory'].'/scorm/imsmanifest.xml'; + } + echo $manifest_file; + if (is_file($manifest_file) && is_readable($manifest_file)) { + // Re-parse the manifest file. + if ($this->debug > 1) { error_log('New LP - In scorm::reimport_manifest() - Parsing manifest '.$manifest_file, 0); } $manifest = $this->parse_manifest($manifest_file); - //import new LP in DB (ignore the current one) - if($this->debug>1){error_log('New LP - In scorm::reimport_manifest() - Importing manifest '.$manifest_file,0);} + // Import new LP in DB (ignore the current one). + if ($this->debug > 1) { error_log('New LP - In scorm::reimport_manifest() - Importing manifest '.$manifest_file, 0); } $this->import_manifest(api_get_course_id()); - }else{ - if($this->debug>0){error_log('New LP - In scorm::reimport_manifest() - Could not find manifest file at '.$manifest_file,0);} - } - return false; - } + } else { + if ($this->debug > 0) { error_log('New LP - In scorm::reimport_manifest() - Could not find manifest file at '.$manifest_file, 0); } + } + return false; + } } -?> diff --git a/main/newscorm/scorm.lib.php b/main/newscorm/scorm.lib.php index b7053e8815..e4371866d4 100755 --- a/main/newscorm/scorm.lib.php +++ b/main/newscorm/scorm.lib.php @@ -1,6 +1,8 @@ -<?php //$id:$ -//TODO migrate this into the scorm.class.php file +<?php /* For licensing terms, see /license.txt */ + +// TODO: Migrate this into the scorm.class.php file. + /** * This file is a container for functions related to SCORM and other * standard or common course content types. It might later become a class @@ -10,83 +12,73 @@ * @author Yannick Warnier <ywarnier@beeznest.org> * @author Based on work from Denes NAgy, Isthvan Mandak and Roan Embrechts */ + /** * Delete a scorm directory (check for imsmanifest and if found, deletes the related rows in scorm tables also) - * @param string Dir path - * @return boolean True on success, false otherwise + * @param string Dir path + * @return boolean True on success, false otherwise */ -function removescormDir($dir) -{ - global $_course; - if(!@$opendir = opendir($dir)) - { - return false; - } - while($readdir = readdir($opendir)) - { - if($readdir != '..' && $readdir != '.') - { - if(is_file($dir.'/'.$readdir)) - { - $pos=strpos('/'.$readdir, 'imsmanifest.xml'); - if ($pos) { //so we have the imsmanifest in this dir - //from d:/myworks/dokeos/dokeos_cvs/dokeos/dokeos/courses/CVSCODE4/scorm/LP2/LP2 - //we have to get /LP2/LP2 - $path=api_get_path(SYS_COURSE_PATH).$_course['official_code'].'/scorm'; - $pos=strpos($dir,$path); - if ($pos==0) { - $scormdir=substr($dir,strlen($path),strlen($dir)-strlen($path)); - $courseid=$_course['official_code']; - $sql="SELECT * FROM ".Database::get_scorm_table(TABLE_SCORM_MAIN)." where (contentTitle='$scormdir' and dokeosCourse='$courseid')"; - $result=Database::query($sql); - while ($row=Database::fetch_array($result)) - { - $c=$row['contentId']; - $sql2="DELETE FROM ".Database::get_scorm_table(TABLE_SCORM_SCO_DATA)." where contentId=$c"; - $result2=Database::query($sql2); - } - $sql="DELETE FROM ".Database::get_scorm_table(TABLE_SCORM_MAIN)." where (contentTitle='$scormdir' and dokeosCourse='$courseid')"; - $result=Database::query($sql); - } +function removescormDir($dir) { + global $_course; + if(!@$opendir = opendir($dir)) { + return false; } - if(!@unlink($dir.'/'.$readdir)) - { - return false; + while($readdir = readdir($opendir)) { + if($readdir != '..' && $readdir != '.') { + if(is_file($dir.'/'.$readdir)) { + $pos = strpos('/'.$readdir, 'imsmanifest.xml'); + if ($pos) { // So we have the imsmanifest in this dir + // from d:/myworks/dokeos/dokeos_cvs/dokeos/dokeos/courses/CVSCODE4/scorm/LP2/LP2 + // We have to get /LP2/LP2 + $path = api_get_path(SYS_COURSE_PATH).$_course['official_code'].'/scorm'; + $pos = strpos($dir, $path); + if ($pos == 0) { + $scormdir = substr($dir, strlen($path), strlen($dir) - strlen($path)); + $courseid = $_course['official_code']; + $sql = "SELECT * FROM ".Database::get_scorm_table(TABLE_SCORM_MAIN)." where (contentTitle='$scormdir' and dokeosCourse='$courseid')"; + $result = Database::query($sql); + while ($row = Database::fetch_array($result)) { + $c = $row['contentId']; + $sql2 = "DELETE FROM ".Database::get_scorm_table(TABLE_SCORM_SCO_DATA)." where contentId=$c"; + $result2 = Database::query($sql2); + } + $sql = "DELETE FROM ".Database::get_scorm_table(TABLE_SCORM_MAIN)." where (contentTitle='$scormdir' and dokeosCourse='$courseid')"; + $result = Database::query($sql); + } + } + if (!@unlink($dir.'/'.$readdir)) { + return false; + } + } elseif (is_dir($dir.'/'.$readdir)) { + if(!removescormDir($dir.'/'.$readdir)) { + return false; + } + } + } } - } elseif(is_dir($dir.'/'.$readdir)) { - if(!removescormDir($dir.'/'.$readdir)) - { - return false; + closedir($opendir); + if (!@rmdir($dir)) { + return false; } - } - } - } - closedir($opendir); - if(!@rmdir($dir)) { - return false; - } - return true; + return true; } + /** * This function removes a directory if it exists - * @param string Dir path - * @return boolean True on success, false otherwise - * @uses removescormDir() to actually remove the directory + * @param string Dir path + * @return boolean True on success, false otherwise + * @uses removescormDir() to actually remove the directory */ -function scorm_delete($file) -{ - if ( check_name_exist($file) ) - { - if ( is_dir($file) ) - { - return removescormDir($file); - } - } - else - { - return false; // no file or directory to delete - } +function scorm_delete($file) { + if (check_name_exist($file)) { + if (is_dir($file)) { + return removescormDir($file); + } + } else { + return false; // No file or directory to delete. + } } + /** * This function gets a list of scorm paths located in a given directory * @param string Base directory path @@ -95,60 +87,52 @@ function scorm_delete($file) * @return array Array(type=>array(),size=>array(),date=>array()) */ function get_scorm_paths_from_dir($basedir, $curdir, &$attribute){ - $scormcontent=false; + $scormcontent = false; $saved_dir = getcwd(); $res = @chdir (realpath($basedir.$curdir)); - if($res === false){ return(null);} - $handle = opendir("."); + if ($res === false) { return(null); } + $handle = opendir('.'); define('A_DIRECTORY', 1); define('A_FILE', 2); $fileList = array(); - // fill up $fileList for displaying the files list later on - while ($file = readdir($handle)) - { - if ($file == "." || $file == ".." || $file == '.htaccess') - { - continue; // Skip current and parent directories + // Fill up $fileList for displaying the files list later on. + while ($file = readdir($handle)) { + if ($file == '.' || $file == '..' || $file == '.htaccess') { + continue; // Skip current and parent directories } $fileList['name'][] = $file; //if ($file=='imsmanifest.xml') { $scormcontent=true; } - if(is_dir($file)) - { + if(is_dir($file)) { $fileList['type'][] = A_DIRECTORY; $fileList['size'][] = false; $fileList['date'][] = false; - } - elseif(is_file($file)) - { + } elseif (is_file($file)) { $fileList['type'][] = A_FILE; $fileList['size'][] = filesize($file); $fileList['date'][] = filectime($file); } + /* * Make the correspondance between * info given by the file system * and info given by the DB */ - if (is_array($attribute) && count($attribute['path'])>0) - { - $keyAttribute = array_search($curdir."/".$file, $attribute['path']); + if (is_array($attribute) && count($attribute['path']) > 0) { + $keyAttribute = array_search($curdir.'/'.$file, $attribute['path']); } - if ($keyAttribute !== false) - { + if ($keyAttribute !== false) { $fileList['comment' ][] = $attribute['comment' ][$keyAttribute]; $fileList['visibility'][] = $attribute['visibility'][$keyAttribute]; unset ($attribute['comment' ][$keyAttribute], - $attribute['visibility'][$keyAttribute], - $attribute['path' ][$keyAttribute]); - } - else - { + $attribute['visibility'][$keyAttribute], + $attribute['path' ][$keyAttribute]); + } else { $fileList['comment' ][] = false; $fileList['visibility'][] = false; } @@ -157,6 +141,7 @@ function get_scorm_paths_from_dir($basedir, $curdir, &$attribute){ chdir($saved_dir); return $fileList; } + /** * Detects the SCORM version from an imsmanifest.xml file * @param string Path to imsmanifest.xml @@ -166,4 +151,4 @@ function get_scorm_paths_from_dir($basedir, $curdir, &$attribute){ function get_scorm_version($path){ return '1.2'; } -?> + diff --git a/main/newscorm/scormItem.class.php b/main/newscorm/scormItem.class.php index 01d58cbaa0..835eced13b 100755 --- a/main/newscorm/scormItem.class.php +++ b/main/newscorm/scormItem.class.php @@ -1,15 +1,17 @@ -<?php +<?php /* For licensing terms, see /license.txt */ + /** * Container for the scormItem class that deals with <item> elements in an imsmanifest file * @package chamilo.learnpath.scorm * @author Yannick Warnier <ywarnier@beeznest.org> */ + /** * This class handles the <item> elements from an imsmanifest file. */ require_once 'learnpathItem.class.php'; -class scormItem extends learnpathItem{ +class scormItem extends learnpathItem { public $identifier = ''; public $identifierref = ''; public $isvisible = ''; @@ -27,250 +29,232 @@ class scormItem extends learnpathItem{ public $mastery_score = ''; public $scorm_contact; - /** - * Class constructor. Depending of the type of construction called ('db' or 'manifest'), will create a scormItem - * object from database records or from the DOM element given as parameter - * @param string Type of construction needed ('db' or 'manifest', default = 'manifest') - * @param mixed Depending on the type given, DB id for the lp_item or reference to the DOM element - */ - public function __construct($type='manifest',&$element) { - if(isset($element)) - { + /** + * Class constructor. Depending of the type of construction called ('db' or 'manifest'), will create a scormItem + * object from database records or from the DOM element given as parameter + * @param string Type of construction needed ('db' or 'manifest', default = 'manifest') + * @param mixed Depending on the type given, DB id for the lp_item or reference to the DOM element + */ + public function __construct($type='manifest',&$element) { + if (isset($element)) { - $v = substr(phpversion(),0,1); - if($v == 4){ - switch($type){ - case 'db': - parent::__construct($element,api_get_user_id()); - $this->scorm_contact = false; - //TODO implement this way of metadata object creation - return false; - case 'manifest': //do the same as the default - default: - //if($first_item->type == XML_ELEMENT_NODE) this is already check prior to the call to this function - $children = $element->children(); - foreach($children as $a => $dummy) - { - $child =& $children[$a]; - switch($child->type) - { - case XML_ELEMENT_NODE: - switch($child->tagname){ - case 'title': - $tmp_children = $child->children(); - if(count($tmp_children)==1 and $tmp_children[0]->content!='' ) - { - $this->title = $tmp_children[0]->content; - } - break; - case 'maxtimeallowed': - $tmp_children = $child->children(); - if(count($tmp_children)==1 and $tmp_children[0]->content!='' ) - { - $this->max_time_allowed = $tmp_children[0]->content; - } - break; + $v = substr(phpversion(), 0, 1); + if ($v == 4) { + switch ($type) { + case 'db': + parent::__construct($element,api_get_user_id()); + $this->scorm_contact = false; + // TODO: Implement this way of metadata object creation. + return false; + case 'manifest': // Do the same as the default. + default: + // if ($first_item->type == XML_ELEMENT_NODE) this is already check prior to the call to this function. + $children = $element->children(); + foreach($children as $a => $dummy) { + $child =& $children[$a]; + switch($child->type) { + case XML_ELEMENT_NODE: + switch($child->tagname) { + case 'title': + $tmp_children = $child->children(); + if (count($tmp_children) == 1 && $tmp_children[0]->content != '') { + $this->title = $tmp_children[0]->content; + } + break; + case 'maxtimeallowed': + $tmp_children = $child->children(); + if (count($tmp_children) == 1 && $tmp_children[0]->content != '') { + $this->max_time_allowed = $tmp_children[0]->content; + } + break; case 'prerequisites': - $tmp_children = $child->children(); - if(count($tmp_children)==1 and $tmp_children[0]->content!='' ) - { - $this->prereq_string = $tmp_children[0]->content; - } - break; + $tmp_children = $child->children(); + if (count($tmp_children) == 1 && $tmp_children[0]->content != '') { + $this->prereq_string = $tmp_children[0]->content; + } + break; case 'timelimitaction': - $tmp_children = $child->children(); - if(count($tmp_children)==1 and $tmp_children[0]->content!='' ) - { - $this->timelimitaction = $tmp_children[0]->content; - } - break; + $tmp_children = $child->children(); + if (count($tmp_children) == 1 && $tmp_children[0]->content != '') { + $this->timelimitaction = $tmp_children[0]->content; + } + break; case 'datafromlms': - $tmp_children = $child->children(); - if(count($tmp_children)==1 and $tmp_children[0]->content!='' ) - { - $this->datafromlms = $tmp_children[0]->content; - } - break; + $tmp_children = $child->children(); + if (count($tmp_children) == 1 && $tmp_children[0]->content != '') { + $this->datafromlms = $tmp_children[0]->content; + } + break; case 'masteryscore': - $tmp_children = $child->children(); - if(count($tmp_children)==1 and $tmp_children[0]->content!='' ) - { - $this->mastery_score = $tmp_children[0]->content; - } - break; - case 'item': - $oItem = new scormItem('manifest',$child); - if($oItem->identifier != ''){ - $this->sub_items[$oItem->identifier] = $oItem; - } + $tmp_children = $child->children(); + if (count($tmp_children) == 1 && $tmp_children[0]->content != '') { + $this->mastery_score = $tmp_children[0]->content; + } + break; + case 'item': + $oItem = new scormItem('manifest', $child); + if ($oItem->identifier != ''){ + $this->sub_items[$oItem->identifier] = $oItem; + } break; - case 'metadata': - $this->metadata = new scormMetadata('manifest',$child); - break; - } - break; - case XML_TEXT_NODE: - //this case is actually treated by looking into ELEMENT_NODEs above - break; - } - } - $attributes = $element->attributes(); - //$keep_href = ''; - foreach($attributes as $a1 => $dummy) - { - $attrib =& $attributes[$a1]; - switch($attrib->name){ - case 'identifier': - $this->identifier = $attrib->value; - break; - case 'identifierref': - $this->identifierref = $attrib->value; - break; - case 'isvisible': - $this->isvisible = $attrib->value; - break; - case 'parameters': - $this->parameters = $attrib->value; - break; - } - } + case 'metadata': + $this->metadata = new scormMetadata('manifest', $child); + break; + } + break; + case XML_TEXT_NODE: + // This case is actually treated by looking into ELEMENT_NODEs above. + break; + } + } + $attributes = $element->attributes(); + //$keep_href = ''; + foreach ($attributes as $a1 => $dummy) { + $attrib =& $attributes[$a1]; + switch($attrib->name){ + case 'identifier': + $this->identifier = $attrib->value; + break; + case 'identifierref': + $this->identifierref = $attrib->value; + break; + case 'isvisible': + $this->isvisible = $attrib->value; + break; + case 'parameters': + $this->parameters = $attrib->value; + break; + } + } return true; - } - }elseif($v == 5){ - //parsing using PHP5 DOMXML methods - switch($type){ - case 'db': - parent::__construct($element,api_get_user_id()); - $this->scorm_contact = false; - //TODO implement this way of metadata object creation - return false; - case 'manifest': //do the same as the default - default: - //if($first_item->type == XML_ELEMENT_NODE) this is already check prior to the call to this function - $children = $element->childNodes; - foreach($children as $child) - { - switch($child->nodeType) - { - case XML_ELEMENT_NODE: - switch($child->tagName){ - case 'title': - $tmp_children = $child->childNodes; - //if(count($tmp_children)==1 and $tmp_children[0]->textContent!='' ) - if($tmp_children->length==1 and $child->firstChild->nodeValue!='' ) - { - $this->title = $child->firstChild->nodeValue; - } - break; - case 'max_score': - if($tmp_children->length==1 and $child->firstChild->nodeValue!='' ) { - $this->max_score = $child->firstChild->nodeValue; - } - break; - case 'maxtimeallowed': - case 'adlcp:maxtimeallowed': - $tmp_children = $child->childNodes; - //if(count($tmp_children)==1 and $tmp_children[0]->textContent!='' ) - if($tmp_children->length==1 and $child->firstChild->nodeValue!='' ) - { - $this->max_time_allowed = $child->firstChild->nodeValue; - } - break; + } + } elseif ($v == 5) { + // Parsing using PHP5 DOMXML methods. + switch ($type) { + case 'db': + parent::__construct($element,api_get_user_id()); + $this->scorm_contact = false; + //TODO: Implement this way of metadata object creation. + return false; + case 'manifest': // Do the same as the default. + default: + //if ($first_item->type == XML_ELEMENT_NODE) this is already check prior to the call to this function. + $children = $element->childNodes; + foreach ($children as $child) { + switch ($child->nodeType) { + case XML_ELEMENT_NODE: + switch ($child->tagName) { + case 'title': + $tmp_children = $child->childNodes; + //if (count($tmp_children) == 1 && $tmp_children[0]->textContent != '') { + if ($tmp_children->length == 1 && $child->firstChild->nodeValue != '') { + $this->title = $child->firstChild->nodeValue; + } + break; + case 'max_score': + if ($tmp_children->length == 1 && $child->firstChild->nodeValue != '') { + $this->max_score = $child->firstChild->nodeValue; + } + break; + case 'maxtimeallowed': + case 'adlcp:maxtimeallowed': + $tmp_children = $child->childNodes; + //if (count($tmp_children) == 1 && $tmp_children[0]->textContent != '') { + if ($tmp_children->length == 1 && $child->firstChild->nodeValue != '') { + $this->max_time_allowed = $child->firstChild->nodeValue; + } + break; case 'prerequisites': case 'adlcp:prerequisites': - $tmp_children = $child->childNodes; - //if(count($tmp_children)==1 and $tmp_children[0]->textContent!='' ) - if($tmp_children->length==1 and $child->firstChild->nodeValue!='' ) - { - $this->prereq_string = $child->firstChild->nodeValue; - } - break; + $tmp_children = $child->childNodes; + //if (count($tmp_children) == 1 && $tmp_children[0]->textContent != '') { + if ($tmp_children->length == 1 && $child->firstChild->nodeValue != '') { + $this->prereq_string = $child->firstChild->nodeValue; + } + break; case 'timelimitaction': case 'adlcp:timelimitaction': - $tmp_children = $child->childNodes; - //if(count($tmp_children)==1 and $tmp_children[0]->textContent!='' ) - if($tmp_children->length==1 and $child->firstChild->nodeValue!='' ) - { - $this->timelimitaction = $child->firstChild->nodeValue; - } - break; + $tmp_children = $child->childNodes; + //if (count($tmp_children) == 1 && $tmp_children[0]->textContent != '') { + if ($tmp_children->length == 1 && $child->firstChild->nodeValue != '') { + $this->timelimitaction = $child->firstChild->nodeValue; + } + break; case 'datafromlms': case 'adlcp:datafromlms': case 'adlcp:launchdata': //in some cases (Wouters) - $tmp_children = $child->childNodes; - //if(count($tmp_children)==1 and $tmp_children[0]->textContent!='' ) - if($tmp_children->length==1 and $child->firstChild->nodeValue!='' ) - { - $this->datafromlms = $child->firstChild->nodeValue; - } - break; + $tmp_children = $child->childNodes; + //if (count($tmp_children) == 1 && $tmp_children[0]->textContent != '') { + if ($tmp_children->length == 1 && $child->firstChild->nodeValue != '') { + $this->datafromlms = $child->firstChild->nodeValue; + } + break; case 'masteryscore': case 'adlcp:masteryscore': - $tmp_children = $child->childNodes; - //if(count($tmp_children)==1 and $tmp_children[0]->textContent!='' ) - if($tmp_children->length==1 and $child->firstChild->nodeValue!='' ) - { - $this->mastery_score = $child->firstChild->nodeValue; - } - break; - case 'item': - $oItem = new scormItem('manifest',$child); - if($oItem->identifier != ''){ - $this->sub_items[$oItem->identifier] = $oItem; - } + $tmp_children = $child->childNodes; + //if (count($tmp_children) == 1 && $tmp_children[0]->textContent != '') { + if ($tmp_children->length == 1 && $child->firstChild->nodeValue != '') { + $this->mastery_score = $child->firstChild->nodeValue; + } + break; + case 'item': + $oItem = new scormItem('manifest',$child); + if ($oItem->identifier != '') { + $this->sub_items[$oItem->identifier] = $oItem; + } break; - case 'metadata': - $this->metadata = new scormMetadata('manifest',$child); - break; - } - break; - case XML_TEXT_NODE: - //this case is actually treated by looking into ELEMENT_NODEs above - break; - } - } - if($element->hasAttributes()){ - $attributes = $element->attributes; - //$keep_href = ''; - foreach($attributes as $attrib) - { - switch($attrib->name){ - case 'identifier': - $this->identifier = $attrib->value; - break; - case 'identifierref': - $this->identifierref = $attrib->value; - break; - case 'isvisible': - $this->isvisible = $attrib->value; - break; - case 'parameters': - $this->parameters = $attrib->value; - break; - } - } - } + case 'metadata': + $this->metadata = new scormMetadata('manifest', $child); + break; + } + break; + case XML_TEXT_NODE: + // This case is actually treated by looking into ELEMENT_NODEs above. + break; + } + } + if ($element->hasAttributes()) { + $attributes = $element->attributes; + //$keep_href = ''; + foreach ($attributes as $attrib) { + switch($attrib->name){ + case 'identifier': + $this->identifier = $attrib->value; + break; + case 'identifierref': + $this->identifierref = $attrib->value; + break; + case 'isvisible': + $this->isvisible = $attrib->value; + break; + case 'parameters': + $this->parameters = $attrib->value; + break; + } + } + } return true; - } - }else{ - //cannot parse because not PHP4 nor PHP5... We should not even be here anyway... + } + } else { + // Cannot parse because not PHP4 nor PHP5... We should not even be here anyway... return false; } - } - return false; - } - /** - * Builds a flat list with the current item and calls itself recursively on all children - * @param array Reference to the array to complete with the current item - * @param integer Optional absolute order (pointer) of the item in this learning path - * @param integer Optional relative order of the item at this level - * @param integer Optional level. If not given, assumes it's level 0 - */ - public function get_flat_list(&$list,&$abs_order,$rel_order=1,$level=0) { - $list[] = array( - 'abs_order' => $abs_order, + } + return false; + } + + /** + * Builds a flat list with the current item and calls itself recursively on all children + * @param array Reference to the array to complete with the current item + * @param integer Optional absolute order (pointer) of the item in this learning path + * @param integer Optional relative order of the item at this level + * @param integer Optional level. If not given, assumes it's level 0 + */ + public function get_flat_list(&$list, &$abs_order, $rel_order = 1, $level = 0) { + $list[] = array( + 'abs_order' => $abs_order, 'datafromlms' => $this->datafromlms, 'identifier' => $this->identifier, 'identifierref' => $this->identifierref, @@ -280,32 +264,31 @@ class scormItem extends learnpathItem{ 'maxtimeallowed' => $this->max_time_allowed, 'metadata' => $this->metadata, 'parameters' => $this->parameters, - 'prerequisites' => (!empty($this->prereq_string)?$this->prereq_string:''), + 'prerequisites' => (!empty($this->prereq_string) ? $this->prereq_string : ''), 'rel_order' => $rel_order, 'timelimitaction' => $this->timelimitaction, 'title' => $this->title, 'max_score' => $this->max_score - ); + ); $abs_order++; $i = 1; - foreach($this->sub_items as $id => $dummy) - { + foreach($this->sub_items as $id => $dummy) { $oSubitem =& $this->sub_items[$id]; - $oSubitem->get_flat_list($list,$abs_order,$i,$level+1); + $oSubitem->get_flat_list($list, $abs_order, $i, $level + 1); $i++; } - } - /** - * Save function. Uses the parent save function and adds a layer for SCORM. - * @param boolean Save from URL params (1) or from object attributes (0) - */ - public function save($from_outside=true,$prereqs_complete=false) { - parent::save($from_outside,$prereqs_complete); - //under certain conditions, the scorm_contact should not be set, because no scorm signal was sent - $this->scorm_contact = true; - if(!$this->scorm_contact){ - //error_log('New LP - was expecting SCORM message but none received',0); - } - } + } + + /** + * Save function. Uses the parent save function and adds a layer for SCORM. + * @param boolean Save from URL params (1) or from object attributes (0) + */ + public function save($from_outside = true, $prereqs_complete = false) { + parent::save($from_outside, $prereqs_complete); + // Under certain conditions, the scorm_contact should not be set, because no scorm signal was sent. + $this->scorm_contact = true; + if (!$this->scorm_contact){ + //error_log('New LP - was expecting SCORM message but none received', 0); + } + } } -?> \ No newline at end of file diff --git a/main/newscorm/scormMetadata.class.php b/main/newscorm/scormMetadata.class.php index e9a336b097..8081495574 100755 --- a/main/newscorm/scormMetadata.class.php +++ b/main/newscorm/scormMetadata.class.php @@ -1,9 +1,11 @@ <?php /* For licensing terms, see /license.txt */ + /** * Container for the scormMetadata class, setup to hold information about the <metadata> element in imsmanifest files * @package chamilo.learnpath.scorm */ + /** * scormMetadata class, handling each <metadata> element found in an imsmanifest file */ @@ -17,183 +19,170 @@ class scormMetadata { /** * Class constructor. Works in two different ways defined by the first element, being 'db' or 'manifest'. - * If 'db', then it is built using the information available in the Dokeos database. If 'manifest', then it + * If 'db', then it is built using the information available in the Chamilo database. If 'manifest', then it * is built using the element given as a parameter, expecting it to be a <metadata> element pointer from the * DOM parser. * @param string Type of creation required. Can be 'db' or 'manifest' (default) * @param mixed Depending on the type, can be the DB ID of the learnpath item or the pointer to the <metadata> element in the imsmanifest.xml file * @return boolean True on success, false on failure */ - public function __construct($type='manifest', &$element) { - if (isset($element)) { - $v = substr(phpversion(),0,1); + public function __construct($type = 'manifest', &$element) { + if (isset($element)) { + $v = substr(phpversion(), 0, 1); if ($v == 4) { - switch ($type) { - case 'db': - //TODO implement this way of metadata object creation - return false; - //break; - case 'manifest': //do the same as the default - //if($first_item->type == XML_ELEMENT_NODE) this is already check prior to the call to this function - $children = $element->children(); - foreach ($children as $a => $dummy) { - $child =& $children[$a]; - switch ($child->type) { - case XML_ELEMENT_NODE: - //could be 'lom','schema','schemaversion' or 'location' - switch ($child->tagname) { - case 'lom': - $childchildren = $child->children(); - foreach ($childchildren as $index => $dummy) - { - $my_elem = $childchildren[$index]; - //there is generally only one child here - //$this->lom[] = $my_elem->content; - $this->lom = $my_elem->content; - } - break; - case 'schema': - $childchildren = $child->children(); - foreach ($childchildren as $index => $dummy) - { - $my_elem = $childchildren[$index]; - //there is generally only one child here - //$this->schema[] = $my_elem->content; - $this->schema = $my_elem->content; - } - break; - case 'schemaversion': - $childchildren = $child->children(); - foreach ($childchildren as $index => $dummy) - { - $my_elem = $childchildren[$index]; - //there is generally only one child here - //$this->schemaversion[] = $my_elem->content; - $this->schemaversion = $my_elem->content; - } - break; - case 'location': - $childchildren = $child->children(); - foreach ($childchildren as $index => $dummy) - { - $my_elem = $childchildren[$index]; - //there is generally only one child here - //$this->location[] = $my_elem->content; - $this->location = $my_elem->content; - } - break; - } - break; - case XML_TEXT_NODE: - if(trim($child->content) != '') { - if (count($children == 1)) { - //if this is the only child at this level and it is a content... save differently - $this->text = $child->content; - } else { - $this->text[$element->tagname] = $child->content; - } - } - break; - } - } - $attributes = $element->attributes(); - //$keep_href = ''; - if (is_array($attributes)) { - foreach ($attributes as $a1 => $dummy) - { - $attrib =& $attributes[$a1]; - if(trim($attrib->value) != ''){ - $this->attribs[$attrib->name] = $attrib->value; - } - } - } + switch ($type) { + case 'db': + // TODO: Implement this way of metadata object creation + return false; + //break; + case 'manifest': // Do the same as the default. + //if ($first_item->type == XML_ELEMENT_NODE) this is already check prior to the call to this function. + $children = $element->children(); + foreach ($children as $a => $dummy) { + $child =& $children[$a]; + switch ($child->type) { + case XML_ELEMENT_NODE: + // Could be 'lom', 'schema', 'schemaversion' or 'location'. + switch ($child->tagname) { + case 'lom': + $childchildren = $child->children(); + foreach ($childchildren as $index => $dummy) { + $my_elem = $childchildren[$index]; + // There is generally only one child here. + //$this->lom[] = $my_elem->content; + $this->lom = $my_elem->content; + } + break; + case 'schema': + $childchildren = $child->children(); + foreach ($childchildren as $index => $dummy) { + $my_elem = $childchildren[$index]; + // There is generally only one child here. + //$this->schema[] = $my_elem->content; + $this->schema = $my_elem->content; + } + break; + case 'schemaversion': + $childchildren = $child->children(); + foreach ($childchildren as $index => $dummy) { + $my_elem = $childchildren[$index]; + // There is generally only one child here. + //$this->schemaversion[] = $my_elem->content; + $this->schemaversion = $my_elem->content; + } + break; + case 'location': + $childchildren = $child->children(); + foreach ($childchildren as $index => $dummy) { + $my_elem = $childchildren[$index]; + // There is generally only one child here. + //$this->location[] = $my_elem->content; + $this->location = $my_elem->content; + } + break; + } + break; + case XML_TEXT_NODE: + if (trim($child->content) != '') { + if (count($children == 1)) { + // If this is the only child at this level and it is a content... save differently. + $this->text = $child->content; + } else { + $this->text[$element->tagname] = $child->content; + } + } + break; + } + } + $attributes = $element->attributes(); + //$keep_href = ''; + if (is_array($attributes)) { + foreach ($attributes as $a1 => $dummy) { + $attrib =& $attributes[$a1]; + if (trim($attrib->value) != '') { + $this->attribs[$attrib->name] = $attrib->value; + } + } + } return true; - //break; - } - } elseif ($v == 5) { - //parsing using PHP5 DOMXML methods - switch ($type) { - case 'db': - //TODO implement this way of metadata object creation - return false; - //break; - case 'manifest': //do the same as the default - $children = $element->childNodes; - foreach ($children as $child) - { - switch ($child->nodeType) - { - case XML_ELEMENT_NODE: - //could be 'lom','schema','schemaversion' or 'location' - switch ($child->tagName) { - case 'lom': - $childchildren = $child->childNodes; - foreach ($childchildren as $childchild) - { - //$this->lom = $childchild->textContent; - $this->lom = $childchild->nodeValue; - } - break; - case 'schema': - $childchildren = $child->childNodes; - foreach ($childchildren as $childchild) - { - //there is generally only one child here - //$this->schema = $childchildren[$index]->textContent; - $this->schema = $childchild->nodeValue; - } - break; - case 'schemaversion': - $childchildren = $child->childNodes; - foreach ($childchildren as $childchild) - { - //there is generally only one child here - //$this->schemaversion = $childchildren[$index]->textContent; - $this->schemaversion = $childchild->nodeValue; - } - break; - case 'location': - $childchildren = $child->childNodes; - foreach ($childchildren as $childchild) - { - //there is generally only one child here - //$this->location = $childchildren[$index]->textContent; - $this->location = $childchild->nodeValue; - } - break; - } - break; - case XML_TEXT_NODE: - if (trim($child->textContent) != '') { - if (count($children == 1)){ - //if this is the only child at this level and it is a content... save differently - $this->text = $child->textContent; - } else { - $this->text[$element->tagName] = $child->textContent; - } - } - break; - } - } - $attributes = $element->attributes; - //$keep_href = ''; - if (is_array($attributes)) { - foreach($attributes as $attrib) - { - if(trim($attrib->value) != ''){ - $this->attribs[$attrib->name] = $attrib->value; - } - } - } + //break; + } + } elseif ($v == 5) { + // Parsing using PHP5 DOMXML methods. + switch ($type) { + case 'db': + // TODO: Implement this way of metadata object creation. + return false; + //break; + case 'manifest': // Do the same as the default. + $children = $element->childNodes; + foreach ($children as $child) { + switch ($child->nodeType) { + case XML_ELEMENT_NODE: + // Could be 'lom','schema','schemaversion' or 'location'. + switch ($child->tagName) { + case 'lom': + $childchildren = $child->childNodes; + foreach ($childchildren as $childchild) { + //$this->lom = $childchild->textContent; + $this->lom = $childchild->nodeValue; + } + break; + case 'schema': + $childchildren = $child->childNodes; + foreach ($childchildren as $childchild) { + // There is generally only one child here. + //$this->schema = $childchildren[$index]->textContent; + $this->schema = $childchild->nodeValue; + } + break; + case 'schemaversion': + $childchildren = $child->childNodes; + foreach ($childchildren as $childchild) { + // There is generally only one child here. + //$this->schemaversion = $childchildren[$index]->textContent; + $this->schemaversion = $childchild->nodeValue; + } + break; + case 'location': + $childchildren = $child->childNodes; + foreach ($childchildren as $childchild) { + // There is generally only one child here. + //$this->location = $childchildren[$index]->textContent; + $this->location = $childchild->nodeValue; + } + break; + } + break; + case XML_TEXT_NODE: + if (trim($child->textContent) != '') { + if (count($children == 1)) { + // If this is the only child at this level and it is a content... save differently. + $this->text = $child->textContent; + } else { + $this->text[$element->tagName] = $child->textContent; + } + } + break; + } + } + $attributes = $element->attributes; + //$keep_href = ''; + if (is_array($attributes)) { + foreach ($attributes as $attrib) { + if (trim($attrib->value) != ''){ + $this->attribs[$attrib->name] = $attrib->value; + } + } + } return true; - //break; - } + //break; + } } else { - //cannot parse because not PHP4 nor PHP5... We should not even be here anyway... + // Cannot parse because not PHP4 nor PHP5... We should not even be here anyway... return false; } - } - return false; - } + } + return false; + } } -?> \ No newline at end of file diff --git a/main/newscorm/scormOrganization.class.php b/main/newscorm/scormOrganization.class.php index 485a7cc899..73e8c25b9f 100755 --- a/main/newscorm/scormOrganization.class.php +++ b/main/newscorm/scormOrganization.class.php @@ -1,10 +1,12 @@ <?php /* For licensing terms, see /license.txt */ + /** * Container for the scormOrganization class * @package chamilo.learnpath.scorm * @author Yannick Warnier <ywarnier@beeznest.org> */ + /** * Class defining the <organization> tag in an imsmanifest.xml file */ @@ -14,125 +16,125 @@ class scormOrganization { public $title = ''; public $items = array(); public $metadata; - /** - * Class constructor. Depending of the type of construction called ('db' or 'manifest'), will create a scormOrganization - * object from database records or from the DOM element given as parameter - * @param string Type of construction needed ('db' or 'manifest', default = 'manifest') - * @param mixed Depending on the type given, DB id for the lp_item or reference to the DOM element - */ - public function __construct($type='manifest',&$element,$scorm_charset='UTF-8') { - if (isset($element)) { - $v = substr(phpversion(),0,1); + /** + * Class constructor. Depending of the type of construction called ('db' or 'manifest'), will create a scormOrganization + * object from database records or from the DOM element given as parameter + * @param string Type of construction needed ('db' or 'manifest', default = 'manifest') + * @param mixed Depending on the type given, DB id for the lp_item or reference to the DOM element + */ + public function __construct($type = 'manifest', &$element, $scorm_charset = 'UTF-8') { + if (isset($element)) { + $v = substr(phpversion(), 0, 1); if ($v == 4) { - switch ($type) { - case 'db': - //TODO implement this way of metadata object creation - return false; - case 'manifest': //do the same as the default - default: - //if($first_item->type == XML_ELEMENT_NODE) this is already check prior to the call to this function - $children = $element->children(); - foreach ($children as $a => $dummy) { - $child =& $children[$a]; - switch ($child->type) { - case XML_ELEMENT_NODE: + switch ($type) { + case 'db': + // TODO: Implement this way of metadata object creation + return false; + case 'manifest': // Do the same as the default. + default: + //if ($first_item->type == XML_ELEMENT_NODE) this is already check prior to the call to this function + $children = $element->children(); + foreach ($children as $a => $dummy) { + $child =& $children[$a]; + switch ($child->type) { + case XML_ELEMENT_NODE: switch ($child->tagname) { - case 'item': - $oItem = new scormItem('manifest',$child); - if ($oItem->identifier != '') { + case 'item': + $oItem = new scormItem('manifest', $child); + if ($oItem->identifier != '') { $this->items[$oItem->identifier] = $oItem; - } + } break; - case 'metadata': - $this->metadata = new scormMetadata('manifest',$child); - break; - case 'title': - $tmp_children = $child->children(); - if (count($tmp_children)==1 and $tmp_children[0]->content!='' ) { - $this->title = $tmp_children[0]->content; - } - break; - } - break; - case XML_TEXT_NODE: - break; - } - } - $attributes = $element->attributes(); - //$keep_href = ''; - foreach ($attributes as $a1 => $dummy) { - $attrib =& $attributes[$a1]; - switch ($attrib->name) { - case 'identifier': - $this->identifier = $attrib->value; - break; - case 'structure': - $this->structure = $attrib->value; - break; - } - } + case 'metadata': + $this->metadata = new scormMetadata('manifest', $child); + break; + case 'title': + $tmp_children = $child->children(); + if (count($tmp_children) == 1 && $tmp_children[0]->content != '') { + $this->title = $tmp_children[0]->content; + } + break; + } + break; + case XML_TEXT_NODE: + break; + } + } + $attributes = $element->attributes(); + //$keep_href = ''; + foreach ($attributes as $a1 => $dummy) { + $attrib =& $attributes[$a1]; + switch ($attrib->name) { + case 'identifier': + $this->identifier = $attrib->value; + break; + case 'structure': + $this->structure = $attrib->value; + break; + } + } return true; - } - } elseif ($v == 5) { - //parsing using PHP5 DOMXML methods - switch($type){ - case 'db': - //TODO implement this way of metadata object creation - return false; - case 'manifest': //do the same as the default - default: - //if($first_item->type == XML_ELEMENT_NODE) this is already check prior to the call to this function - $children = $element->childNodes; - foreach ($children as $child) { - switch ($child->nodeType) { - case XML_ELEMENT_NODE: + } + } elseif ($v == 5) { + // Parsing using PHP5 DOMXML methods. + switch ($type) { + case 'db': + // TODO: Implement this way of metadata object creation. + return false; + case 'manifest': // Do the same as the default. + default: + //if($first_item->type == XML_ELEMENT_NODE) this is already check prior to the call to this function. + $children = $element->childNodes; + foreach ($children as $child) { + switch ($child->nodeType) { + case XML_ELEMENT_NODE: switch ($child->tagName) { - case 'item': - $oItem = new scormItem('manifest',$child); - if($oItem->identifier != ''){ + case 'item': + $oItem = new scormItem('manifest', $child); + if ($oItem->identifier != '') { $this->items[$oItem->identifier] = $oItem; - } + } break; - case 'metadata': - $this->metadata = new scormMetadata('manifest',$child); - break; - case 'title': - $tmp_children = $child->childNodes; - if ($tmp_children->length==1 and $child->firstChild->nodeValue != '' ) { - $this->title = html_entity_decode(html_entity_decode($child->firstChild->nodeValue,ENT_QUOTES,$scorm_charset)); - } - break; - } - break; - case XML_TEXT_NODE: - break; - } - } + case 'metadata': + $this->metadata = new scormMetadata('manifest', $child); + break; + case 'title': + $tmp_children = $child->childNodes; + if ($tmp_children->length == 1 && $child->firstChild->nodeValue != '') { + $this->title = html_entity_decode(html_entity_decode($child->firstChild->nodeValue, ENT_QUOTES, $scorm_charset)); // TODO: This conversion from html-entities looks strange. + } + break; + } + break; + case XML_TEXT_NODE: + break; + } + } if ($element->hasAttributes()) { - $attributes = $element->attributes; - //$keep_href = ''; - foreach ($attributes as $attrib) { - switch ($attrib->name) { - case 'identifier': - $this->identifier = $attrib->value; - break; - case 'structure': - $this->structure = $attrib->value; - break; - } - } + $attributes = $element->attributes; + //$keep_href = ''; + foreach ($attributes as $attrib) { + switch ($attrib->name) { + case 'identifier': + $this->identifier = $attrib->value; + break; + case 'structure': + $this->structure = $attrib->value; + break; + } + } } return true; - - } + } } else { - //cannot parse because not PHP4 nor PHP5... We should not even be here anyway... + // Cannot parse because not PHP4 nor PHP5... We should not even be here anyway... return false; } - } - return false; - } + } + return false; + } + /** * Get a flat list of items in the organization * @return array Array containing an ordered list of all items with their level and all information related to each item @@ -140,43 +142,45 @@ class scormOrganization { public function get_flat_items_list() { $list = array(); $i = 1; - foreach ($this->items as $id=>$dummy) { + foreach ($this->items as $id => $dummy) { $abs_order = 0; - $this->items[$id]->get_flat_list($list,$abs_order,$i,0); //passes the array as a pointer so it is modified in $list directly + $this->items[$id]->get_flat_list($list,$abs_order, $i, 0); // Passes the array as a pointer so it is modified in $list directly. $i++; } return $list; } - /** - * Name getter - * @return string Name or empty string - */ - public function get_name() { - if (!empty($this->title)) { - return Database::escape_string($this->title); - } else { - return ''; - } - } - /** - * Reference identifier getter - * @return string Identifier or empty string - */ - public function get_ref() { - if (!empty($this->identifier)) { - return Database::escape_string($this->identifier); - } else { - return ''; - } - } - /** - * Sets the title element - * @param string New title to set - */ - public function set_name($title) { - if (!empty($title)) { - $this->title = Database::escape_string($title); - } - } + + /** + * Name getter + * @return string Name or empty string + */ + public function get_name() { + if (!empty($this->title)) { + return Database::escape_string($this->title); + } else { + return ''; + } + } + + /** + * Reference identifier getter + * @return string Identifier or empty string + */ + public function get_ref() { + if (!empty($this->identifier)) { + return Database::escape_string($this->identifier); + } else { + return ''; + } + } + + /** + * Sets the title element + * @param string New title to set + */ + public function set_name($title) { + if (!empty($title)) { + $this->title = Database::escape_string($title); + } + } } -?> \ No newline at end of file diff --git a/main/newscorm/scormResource.class.php b/main/newscorm/scormResource.class.php index bfcb6f4485..a963ecea5c 100755 --- a/main/newscorm/scormResource.class.php +++ b/main/newscorm/scormResource.class.php @@ -1,10 +1,12 @@ <?php /* For licensing terms, see /license.txt */ + /** * Container for the scormResource class * @package chamilo.learnpath.scorm * @author Yannick Warnier <ywarnier@beeznest.org> */ + /** * Class defining the <resource> tag in an imsmanifest.xml file * @@ -13,7 +15,7 @@ class scormResource { public $identifier = ''; public $type = 'webcontent'; //public $identifierref = ''; - public $scormtype = 'sco'; //fix problems with ENI content where asset is not defined + public $scormtype = 'sco'; // Fix problems with ENI content where asset is not defined. public $base = ''; public $href = ''; public $metadata; @@ -22,188 +24,181 @@ class scormResource { public $files = array(); public $dependencies = array(); - /** - * Class constructor. Depending of the type of construction called ('db' or 'manifest'), will create a scormResource - * object from database records or from the DOM element given as parameter - * @param string Type of construction needed ('db' or 'manifest', default = 'manifest') - * @param mixed Depending on the type given, DB id for the lp_item or reference to the DOM element - */ - public function __construct($type='manifest',&$element) { - /* - echo "<pre>Analysing resource:<br />\n"; - var_dump($element); - echo "</pre><br />\n"; - */ - if(isset($element)) - { - $v = substr(phpversion(),0,1); - if($v == 4){ - switch($type){ - case 'db': - //TODO implement this way of metadata object creation - return false; - case 'manifest': //do the same as the default - default: - //if($first_item->type == XML_ELEMENT_NODE) this is already check prior to the call to this function - $children = $element->children(); - foreach($children as $a => $dummy) - { - $child =& $children[$a]; - switch($child->type) - { - case XML_ELEMENT_NODE: - switch($child->tagname){ - case 'file': - //echo "Child is a file tag<br />\n"; - $this->files[] = $child->get_attribute('href'); - //var_dump($this->files); - //ignoring file metadata + /** + * Class constructor. Depending of the type of construction called ('db' or 'manifest'), will create a scormResource + * object from database records or from the DOM element given as parameter + * @param string Type of construction needed ('db' or 'manifest', default = 'manifest') + * @param mixed Depending on the type given, DB id for the lp_item or reference to the DOM element + */ + public function __construct($type = 'manifest', &$element) { + /* + echo "<pre>Analysing resource:<br />\n"; + var_dump($element); + echo "</pre><br />\n"; + */ + if (isset($element)) { + $v = substr(phpversion(), 0, 1); + if ($v == 4) { + switch ($type) { + case 'db': + // TODO: Implement this way of metadata object creation. + return false; + case 'manifest': //do the same as the default + default: + //if ($first_item->type == XML_ELEMENT_NODE) this is already check prior to the call to this function. + $children = $element->children(); + foreach ($children as $a => $dummy) { + $child =& $children[$a]; + switch ($child->type) { + case XML_ELEMENT_NODE: + switch ($child->tagname) { + case 'file': + //echo "Child is a file tag<br />\n"; + $this->files[] = $child->get_attribute('href'); + //var_dump($this->files); + //ignoring file metadata //files[] array contains all <file href='x'> tags one by one break; - case 'metadata': - //echo "Child is a metadata tag<br />\n"; - $this->metadata = new scormMetadata('manifest',$child); - break; - case 'dependency': - //echo "Child is a dependency tag<br />\n"; - //need to get identifierref attribute inside dependency node - //dependencies[] array represents all <dependency identifierref='x'> tags united - $this->dependencies[] = $child->get_attribute('identifierref'); - break; - } - break; - } - } - $attributes = $element->attributes(); - //$keep_href = ''; - if(count($attributes)>0){ //in some cases we get here with an empty attributes array - //TODO find when and why we get such a case (empty array) - foreach($attributes as $a1 => $dummy) - { - $attrib =& $attributes[$a1]; - switch($attrib->name){ - case 'identifier': - $this->identifier = $attrib->value; - break; - case 'type': - if(!empty($attrib->value)){ - $this->type = $attrib->value; - } - break; - case 'scormtype': - if(!empty($attrib->value)){ - $this->scormtype = $attrib->value; - } - break; - case 'base': - $this->base = $attrib->value; - break; - case 'href': - $this->href = $attrib->value; - break; - } - } - } + case 'metadata': + //echo "Child is a metadata tag<br />\n"; + $this->metadata = new scormMetadata('manifest', $child); + break; + case 'dependency': + //echo "Child is a dependency tag<br />\n"; + //need to get identifierref attribute inside dependency node + //dependencies[] array represents all <dependency identifierref='x'> tags united + $this->dependencies[] = $child->get_attribute('identifierref'); + break; + } + break; + } + } + $attributes = $element->attributes(); + //$keep_href = ''; + if (count($attributes) > 0) { // In some cases we get here with an empty attributes array. + //TODO find when and why we get such a case (empty array) + foreach ($attributes as $a1 => $dummy) { + $attrib =& $attributes[$a1]; + switch ($attrib->name) { + case 'identifier': + $this->identifier = $attrib->value; + break; + case 'type': + if (!empty($attrib->value)) { + $this->type = $attrib->value; + } + break; + case 'scormtype': + if (!empty($attrib->value)) { + $this->scormtype = $attrib->value; + } + break; + case 'base': + $this->base = $attrib->value; + break; + case 'href': + $this->href = $attrib->value; + break; + } + } + } return true; - } - }elseif($v == 5){ - //parsing using PHP5 DOMXML methods - switch($type){ - case 'db': - //TODO implement this way of metadata object creation - return false; - case 'manifest': //do the same as the default - default: - //if($first_item->type == XML_ELEMENT_NODE) this is already check prior to the call to this function - $children = $element->childNodes; - if(is_array($children)){ - foreach($children as $child) - { - switch($child->nodeType) - { - case XML_ELEMENT_NODE: - switch($child->tagName){ - case 'file': - //echo "Child is a file tag<br />\n"; - $this->files[] = $child->getAttribute('href'); + } + } elseif ($v == 5) { + // Parsing using PHP5 DOMXML methods. + switch($type){ + case 'db': + // TODO: Implement this way of metadata object creation. + return false; + case 'manifest': // Do the same as the default. + default: + //if ($first_item->type == XML_ELEMENT_NODE) this is already check prior to the call to this function. + $children = $element->childNodes; + if (is_array($children)) { + foreach ($children as $child) { + switch ($child->nodeType) { + case XML_ELEMENT_NODE: + switch ($child->tagName) { + case 'file': + //echo "Child is a file tag<br />\n"; + $this->files[] = $child->getAttribute('href'); + break; + case 'metadata': + //echo "Child is a metadata tag<br />\n"; + $this->metadata = new scormMetadata('manifest', $child); break; - case 'metadata': - //echo "Child is a metadata tag<br />\n"; - $this->metadata = new scormMetadata('manifest',$child); - break; - case 'dependency': - //need to get identifierref attribute inside dependency node - //dependencies[] array represents all <dependency identifierref='x'> tags united - $this->dependencies[] = $child->getAttribute('identifierref'); - break; - } - break; - } - } - } - //$keep_href = ''; - if($element->hasAttributes()){ //in some cases we get here with an empty attributes array - //TODO find when and why we get such a case (empty array) - $attributes = $element->attributes; - foreach($attributes as $attrib) - { - switch($attrib->name){ - case 'identifier': - $this->identifier = $attrib->value; - break; - case 'type': - if(!empty($attrib->value)){ - $this->type = $attrib->value; - } - break; - case 'scormtype': - if(!empty($attrib->value)){ - $this->scormtype = $attrib->value; - } - break; - case 'base': - $this->base = $attrib->value; - break; - case 'href': - $this->href = $attrib->value; - break; - } - } - } + case 'dependency': + // Need to get identifierref attribute inside dependency node. + // dependencies[] array represents all <dependency identifierref='x'> tags united. + $this->dependencies[] = $child->getAttribute('identifierref'); + break; + } + break; + } + } + } + //$keep_href = ''; + if ($element->hasAttributes()){ //in some cases we get here with an empty attributes array + // TODO: Find when and why we get such a case (empty array). + $attributes = $element->attributes; + foreach ($attributes as $attrib) { + switch ($attrib->name) { + case 'identifier': + $this->identifier = $attrib->value; + break; + case 'type': + if (!empty($attrib->value)) { + $this->type = $attrib->value; + } + break; + case 'scormtype': + if (!empty($attrib->value)) { + $this->scormtype = $attrib->value; + } + break; + case 'base': + $this->base = $attrib->value; + break; + case 'href': + $this->href = $attrib->value; + break; + } + } + } return true; - - } - }else{ - //cannot parse because not PHP4 nor PHP5... We should not even be here anyway... + } + } else { + // Cannot parse because not PHP4 nor PHP5... We should not even be here anyway... return false; } - } - return false; - } - /** - * Path getter - * @return string Path for this resource - */ - public function get_path() { - if(!empty($this->href)) - { - require_once 'learnpath.class.php'; - return learnpath::escape_string($this->href); - }else{ - return ''; - } - } - /** - * Scorm type getter - * @return string generally 'asset' or 'sco' as these are the only two values defined in SCORM 1.2 - */ - public function get_scorm_type() { - if(!empty($this->scormtype)){ - require_once 'learnpath.class.php'; - return learnpath::escape_string($this->scormtype); - }else{ - return ''; - } - } -} \ No newline at end of file + } + return false; + } + + /** + * Path getter + * @return string Path for this resource + */ + public function get_path() { + if (!empty($this->href)) { + require_once 'learnpath.class.php'; + return learnpath::escape_string($this->href); + } else { + return ''; + } + } + + /** + * Scorm type getter + * @return string generally 'asset' or 'sco' as these are the only two values defined in SCORM 1.2 + */ + public function get_scorm_type() { + if (!empty($this->scormtype)){ + require_once 'learnpath.class.php'; + return learnpath::escape_string($this->scormtype); + } else { + return ''; + } + } +} diff --git a/main/newscorm/scorm_admin.php b/main/newscorm/scorm_admin.php index 88229186a8..8a2ab3e41c 100755 --- a/main/newscorm/scorm_admin.php +++ b/main/newscorm/scorm_admin.php @@ -1,6 +1,7 @@ <?php /* For licensing terms, see /license.txt */ -//This file is probably deprecated - 2009-05-14 - ywarnier + +// This file is probably deprecated - 2009-05-14 - ywarnier /** * This script handles SCO administration features * @package chamilo.learnpath.scorm @@ -9,15 +10,14 @@ * @author Roan Embrechts, code improvements and refactoring * @author Yannick Warnier, complete refactoring <ywarnier@beeznest.org> */ -/** - * Script init - */ -//flag to allow for anonymous user - needs to be set before global.inc.php + +// Flag to allow for anonymous user - needs to be set before global.inc.php. $use_anonymous = true; -// name of the language file that needs to be included -$language_file = "scormdocument"; -$uncompress=1; //this variable shouldn't be found here (find its usage before removal) +// Name of the language file that needs to be included. +$language_file = 'scormdocument'; + +$uncompress = 1; // TODO: This variable shouldn't be found here (find its usage before removal). require_once 'back_compat.inc.php'; include 'learnpath_functions.inc.php'; @@ -25,39 +25,36 @@ include_once 'scorm.lib.php'; $is_allowedToEdit = api_is_allowed_to_edit(); -/** - * Variables - */ -//escapable integers -if ($_REQUEST['id'] != strval(intval($_REQUEST['id']))) {$id = $_REQUEST['id'];} else {$id=null;} +/* Variables */ -//imported strings -$path = (!empty($_REQUEST['path'])?$_REQUEST['path']:null); -$Submit = (!empty($_POST['Submit'])?$_POST['Submit']:null); -$submitImage = (!empty($_POST['submitImage'])?$_POST['submitImage']:null); -$cancelSubmitImage = (!empty($_POST['cancelSubmitImage'])?$_POST['cancelSubmitImage']:null); -$action = (!empty($_REQUEST['action'])?$_REQUEST['action']:null); -$delete = (!empty($_REQUEST['delete'])?$_REQUEST['delete']:null); -$createDir = (!empty($_REQUEST['createDir'])?$_REQUEST['createDir']:null); -$make_directory_visible = (!empty($_REQUEST['make_directory_visible'])?$_REQUEST['make_directory_visible']:''); -$make_directory_invisible = (!empty($_REQUEST['make_directory_invisible'])?$_REQUEST['make_directory_invisible']:''); +// Escapable integers. +if ($_REQUEST['id'] != strval(intval($_REQUEST['id']))) { $id = $_REQUEST['id']; } else { $id = null; } -//values from POST form to add directory -$newDirPath = (!empty($_POST['newDirPath'])?$_POST['newDirPath']:null); -$newDirName = (!empty($_POST['newDirName'])?$_POST['newDirName']:null); -//initialising internal variables +// Imported strings. +$path = (!empty($_REQUEST['path']) ? $_REQUEST['path'] : null); +$Submit = (!empty($_POST['Submit']) ? $_POST['Submit'] : null); +$submitImage = (!empty($_POST['submitImage']) ? $_POST['submitImage'] : null); +$cancelSubmitImage = (!empty($_POST['cancelSubmitImage']) ? $_POST['cancelSubmitImage'] : null); +$action = (!empty($_REQUEST['action']) ? $_REQUEST['action'] : null); +$delete = (!empty($_REQUEST['delete']) ? $_REQUEST['delete'] : null); +$createDir = (!empty($_REQUEST['createDir']) ? $_REQUEST['createDir'] : null); +$make_directory_visible = (!empty($_REQUEST['make_directory_visible']) ? $_REQUEST['make_directory_visible'] : ''); +$make_directory_invisible = (!empty($_REQUEST['make_directory_invisible']) ? $_REQUEST['make_directory_invisible'] : ''); + +// Values from POST form to add directory. +$newDirPath = (!empty($_POST['newDirPath']) ? $_POST['newDirPath'] : null); +$newDirName = (!empty($_POST['newDirName']) ? $_POST['newDirName'] : null); +// Initialising internal variables. $dialogbox = ''; if (! $is_allowed_in_course) api_not_allowed(); $is_allowedToUnzip = $is_courseAdmin; +/* Main code */ -/** - * Main code - */ switch ($action) { case 'exportpath': - if(!empty($id)){ + if (!empty($id)) { $export = exportpath($id); $dialogBox .= "This LP has been exported to the Document folder " ."of your course."; @@ -67,11 +64,11 @@ switch ($action) { exportSCORM($path); break; case 'deletepath': - /*================================================== + /* DELETE A DOKEOS LEARNPATH and all the items in it - ==================================================*/ - if(!empty($id)){ + */ + if (!empty($id)){ $l="learnpath/learnpath_handler.php?learnpath_id=$id"; $sql="DELETE FROM $tbl_tool where (link='$l' AND image='scormbuilder.gif')"; $result=Database::query($sql); @@ -90,303 +87,229 @@ switch ($action) { } break; case 'publishpath': - /*================================================================== - PUBLISHING (SHOWING) A DOKEOS LEARNPATH - ==================================================================*/ - if(!empty($id)){ - $sql="SELECT * FROM $tbl_learnpath_main where learnpath_id=$id"; - $result=Database::query($sql); - $row=Database::fetch_array($result); - $name=domesticate($row['learnpath_name']); + /* PUBLISHING (SHOWING) A DOKEOS LEARNPATH */ + if (!empty($id)){ + $sql = "SELECT * FROM $tbl_learnpath_main where learnpath_id=$id"; + $result = Database::query($sql); + $row = Database::fetch_array($result); + $name = domesticate($row['learnpath_name']); if ($set_visibility == 'i') { - $s=$name." ".get_lang('_no_published'); - $dialogBox=$s; - $v=0; + $s = $name.' '.get_lang('_no_published'); + $dialogBox = $s; + $v = 0; } if ($set_visibility == 'v') { - $s=$name." ".get_lang('_published'); - $dialogBox=$s; - $v=1; + $s=$name.' '.get_lang('_published'); + $dialogBox = $s; + $v = 1; } - $sql="SELECT * FROM $tbl_tool where (name='$name' and image='scormbuilder.gif')"; - $result=Database::query($sql); - $row2=Database::fetch_array($result); - $num=Database::num_rows($result); - if (($set_visibility == 'i') && ($num>0)) - { - //it is visible or hidden but once was published - if (($row2['visibility'])==1) - { - $sql ="DELETE FROM $tbl_tool WHERE (name='$name' and image='scormbuilder.gif')"; + $sql = "SELECT * FROM $tbl_tool where (name='$name' and image='scormbuilder.gif')"; + $result = Database::query($sql); + $row2 = Database::fetch_array($result); + $num = Database::num_rows($result); + if (($set_visibility == 'i') && ($num > 0)) { + // It is visible or hidden but once was published. + if (($row2['visibility']) == 1) { + $sql = "DELETE FROM $tbl_tool WHERE (name='$name' and image='scormbuilder.gif')"; + } else { + $sql = "UPDATE $tbl_tool set visibility=1 WHERE (name='$name' and image='scormbuilder.gif')"; } - else - { - $sql ="UPDATE $tbl_tool set visibility=1 WHERE (name='$name' and image='scormbuilder.gif')"; - } - } - elseif (($set_visibility == 'v') && ($num==0)) - { + } elseif (($set_visibility == 'v') && ($num == 0)) { $sql ="INSERT INTO $tbl_tool (id, name, link, image, visibility, admin, address, added_tool) VALUES ('$theid','$name','learnpath/learnpath_handler.php?learnpath_id=$id','scormbuilder.gif','$v','0','pastillegris.gif',0)"; + } else { + // Parameter and database incompatible, do nothing. } - else - { - //parameter and database incompatible, do nothing - } - $result=Database::query($sql); - + $result = Database::query($sql); } break; case 'editpath': - /*================================================================== - EDITING A DOKEOS NEW LEARNPATH - ==================================================================*/ - if(!empty($Submit)) - { - $l="learnpath/learnpath_handler.php?learnpath_id=$id"; - $sql="UPDATE $tbl_tool set name='".domesticate($learnpath_name)."' where (link='$l' and image='scormbuilder.gif')"; - $result=Database::query($sql); - $sql ="UPDATE $tbl_learnpath_main SET learnpath_name='".domesticate($learnpath_name)."', learnpath_description='".domesticate($learnpath_description)."' WHERE learnpath_id=$id"; - $result=Database::query($sql); - $dialogBox=get_lang('_learnpath_edited'); + /* EDITING A DOKEOS NEW LEARNPATH */ + if (!empty($Submit)) { + $l = "learnpath/learnpath_handler.php?learnpath_id=$id"; + $sql = "UPDATE $tbl_tool set name='".domesticate($learnpath_name)."' where (link='$l' and image='scormbuilder.gif')"; + $result = Database::query($sql); + $sql = "UPDATE $tbl_learnpath_main SET learnpath_name='".domesticate($learnpath_name)."', learnpath_description='".domesticate($learnpath_description)."' WHERE learnpath_id=$id"; + $result = Database::query($sql); + $dialogBox = get_lang('_learnpath_edited'); } break; case 'add': - /*================================================================== - ADDING A NEW LEARNPATH : treating the form - ==================================================================*/ - if (!empty($Submit)) - { - $sql ="INSERT INTO $tbl_learnpath_main (learnpath_name, learnpath_description) VALUES ('".domesticate($learnpath_name)."','".domesticate($learnpath_description)."')"; - Database::query($sql); - $my_lp_id = Database::insert_id(); - $sql ="INSERT INTO $tbl_tool (name, link, image, visibility, admin, address, added_tool) VALUES ('".domesticate($learnpath_name)."','learnpath/learnpath_handler.php?learnpath_id=$my_lp_id','scormbuilder.gif','1','0','pastillegris.gif',0)"; - Database::query($sql); - //instead of displaying this info text, get the user directly to the learnpath edit page - //$dialogBox=get_lang('_learnpath_added'); - header('location:../learnpath/learnpath_handler.php?'.api_get_cidreq().'&learnpath_id='.$my_lp_id); - exit(); + /* ADDING A NEW LEARNPATH : treating the form */ + if (!empty($Submit)) { + $sql = "INSERT INTO $tbl_learnpath_main (learnpath_name, learnpath_description) VALUES ('".domesticate($learnpath_name)."','".domesticate($learnpath_description)."')"; + Database::query($sql); + $my_lp_id = Database::insert_id(); + $sql = "INSERT INTO $tbl_tool (name, link, image, visibility, admin, address, added_tool) VALUES ('".domesticate($learnpath_name)."','learnpath/learnpath_handler.php?learnpath_id=$my_lp_id','scormbuilder.gif','1','0','pastillegris.gif',0)"; + Database::query($sql); + // Instead of displaying this info text, get the user directly to the learnpath edit page. + //$dialogBox = get_lang('_learnpath_added'); + header('location:../learnpath/learnpath_handler.php?'.api_get_cidreq().'&learnpath_id='.$my_lp_id); + exit(); } break; case 'editscorm': - /*================================================================== - EDITING A SCORM PACKAGE - ==================================================================*/ - if (!empty($Submit)) - { - $sql ="UPDATE $tbl_document SET comment='".domesticate($learnpath_description)."', name='".domesticate($learnpath_name)."' WHERE path='$path'"; - $result=Database::query($sql); - $dialogBox=get_lang('_learnpath_edited'); + /* EDITING A SCORM PACKAGE */ + if (!empty($Submit)) { + $sql = "UPDATE $tbl_document SET comment='".domesticate($learnpath_description)."', name='".domesticate($learnpath_name)."' WHERE path='$path'"; + $result = Database::query($sql); + $dialogBox = get_lang('_learnpath_edited'); } break; default: break; } -/*============================================================================*/ +if ($is_allowedToEdit) { // TEACHER ONLY -if($is_allowedToEdit) // TEACHER ONLY -{ - /*====================================== - UPLOAD SCORM - ======================================*/ - /* - * Check the request method instead of a variable from POST - * because if the file size exceeds the maximum file upload - * size set in php.ini, all variables from POST are cleared ! - */ + /* UPLOAD SCORM */ - if ($_SERVER['REQUEST_METHOD'] == 'POST' - && count($_FILES)>0 - && empty($submitImage) - && empty($cancelSubmitImage) - && empty($action)) - { - // A SCORM upload has been detected, now deal with the file... - //directory creation - $s=$_FILES['userFile']['name']; - $pathInfo = pathinfo($s); - //Check the filename has at least several letters in it :-) - //This is a very loose check as later on we might accept other formats of packages - //sent than just "zip" - if(preg_match('/[\w-_]+/',$pathInfo['basename'])){ - //get the basename without extension - $newDirName=substr( - $pathInfo['basename'], - 0, - strlen($pathInfo['basename'])-(strlen($pathInfo['extension'])+1)); - $newDirName = replace_dangerous_char(trim($newDirName),'strict'); - if( check_name_exist($baseWorkDir.$newDirPath.$openDir."/".$newDirName) ) - { - /** @todo change this output. Inaccurate at least in french. In this case, the - * file might not exist or the transfer might have been wrong (no $_FILES at all) - * but we still get the error message - */ - $dialogBox = get_lang('FileExists'); - $createDir = $newDirPath; unset($newDirPath);// return to step 1 - } - else - { - if(mkdir($baseWorkDir.$newDirPath.$openDir."/".$newDirName, api_get_permissions_for_new_directories())){ - FileManager::set_default_settings($newDirPath.$openDir, $newDirName, "folder", $tbl_document); - // RH: was: set_default_settings($newDirPath.$openDir,$newDirName,"folder"); - $dialogBox = get_lang('DirCr'); - }else{ - //Display msg "could not create dir..." - //exit(); - } - //directory creation end + /* + * Check the request method instead of a variable from POST + * because if the file size exceeds the maximum file upload + * size set in php.ini, all variables from POST are cleared ! + */ - $uploadPath=$openDir.'/'.$newDirName; - if(!$_FILES['userFile']['size']) - { - $dialogBox .= get_lang('FileError').'<br />'.get_lang('Notice').' : '.get_lang('MaxFileSize').' '.ini_get('upload_max_filesize'); - } - else //the file size is alright, we can assume the file is OK too - { - if($uncompress == 1 && $is_allowedToUnzip) - { - $unzip = 'unzip'; - } - else - { - $unzip = ''; - } - if (treat_uploaded_file($_FILES['userFile'], $baseWorkDir, - $uploadPath, $maxFilledSpace, $unzip)) - { - if ($uncompress == 1) - { - //$dialogBox .= get_lang('DownloadAndZipEnd'); - //modified by darkden : I omitted this part, so the user can see - //the scorm content message at once - } - else - { - $dialogBox = get_lang('DownloadEnd'); - } - // "WHAT'S NEW" notification: update table last_tooledit - //update_last_tooledit($_course, $nameTools, $id, get_lang('_new_document'), $_user['user_id']); - item_property_update($_course, TOOL_LEARNPATH, $id, "LearnpathAdded", $_user['user_id']); - } - else - { - if(api_failure::get_last_failure() == 'not_enough_space') - { - $dialogBox = get_lang('NoSpace'); - } - elseif (api_failure::get_last_failure() == 'php_file_in_zip_file') - { - $dialogBox = get_lang('ZipNoPhp'); - } - elseif(api_failure::get_last_failure() == 'not_scorm_content') - { - $dialogBox = get_lang('NotScormContent'); - } - } - } - $uploadPath=''; - if (api_failure::get_last_failure()) - { - rmdir($baseWorkDir.$newDirPath.$openDir."/".$newDirName); - } + if ($_SERVER['REQUEST_METHOD'] == 'POST' && count($_FILES) > 0 && empty($submitImage) && empty($cancelSubmitImage) && empty($action)) { - } - }// - else - {//the filename doesn't contain any alphanum chars (empty filename?) - //get a more detailed message? - $dialogBox .= get_lang('FileError').'<br />'; - } + // A SCORM upload has been detected, now deal with the file... + // Directory creation. + $s = $_FILES['userFile']['name']; + $pathInfo = pathinfo($s); + // Check the filename has at least several letters in it :-) + // This is a very loose check as later on we might accept other formats of packages. + // Sent than just "zip". + if (preg_match('/[\w-_]+/', $pathInfo['basename'])) { + // get the basename without extension. + $newDirName = substr($pathInfo['basename'], 0, strlen($pathInfo['basename']) - (strlen($pathInfo['extension']) + 1)); + $newDirName = replace_dangerous_char(trim($newDirName), 'strict'); + if (check_name_exist($baseWorkDir.$newDirPath.$openDir.'/'.$newDirName)) { + /** @todo change this output. Inaccurate at least in french. In this case, the + * file might not exist or the transfer might have been wrong (no $_FILES at all) + * but we still get the error message + */ + $dialogBox = get_lang('FileExists'); + $createDir = $newDirPath; unset($newDirPath); // Return to step 1. + } else { + if (mkdir($baseWorkDir.$newDirPath.$openDir.'/'.$newDirName, api_get_permissions_for_new_directories())) { + FileManager::set_default_settings($newDirPath.$openDir, $newDirName, 'folder', $tbl_document); + // RH: was: set_default_settings($newDirPath.$openDir, $newDirName, 'folder'); + $dialogBox = get_lang('DirCr'); + } else { + //Display msg "could not create dir..." + //exit(); + } + // Directory creation end. - /*====================================== - DELETE FILE OR DIRECTORY - ======================================*/ + $uploadPath = $openDir.'/'.$newDirName; + if (!$_FILES['userFile']['size']) { + $dialogBox .= get_lang('FileError').'<br />'.get_lang('Notice').' : '.get_lang('MaxFileSize').' '.ini_get('upload_max_filesize'); + } else { // The file size is alright, we can assume the file is OK too. + if ($uncompress == 1 && $is_allowedToUnzip) { + $unzip = 'unzip'; + } else { + $unzip = ''; + } + if (treat_uploaded_file($_FILES['userFile'], $baseWorkDir, $uploadPath, $maxFilledSpace, $unzip)) { + if ($uncompress == 1) { + //$dialogBox .= get_lang('DownloadAndZipEnd'); + // Modified by darkden : I omitted this part, so the user can see + // the scorm content message at once. + } else { + $dialogBox = get_lang('DownloadEnd'); + } + // "WHAT'S NEW" notification: update table last_tooledit. + //update_last_tooledit($_course, $nameTools, $id, get_lang('_new_document'), $_user['user_id']); + item_property_update($_course, TOOL_LEARNPATH, $id, "LearnpathAdded", $_user['user_id']); + } else { + if (api_failure::get_last_failure() == 'not_enough_space') { + $dialogBox = get_lang('NoSpace'); + } elseif (api_failure::get_last_failure() == 'php_file_in_zip_file') { + $dialogBox = get_lang('ZipNoPhp'); + } elseif (api_failure::get_last_failure() == 'not_scorm_content') { + $dialogBox = get_lang('NotScormContent'); + } + } + } + $uploadPath = ''; + if (api_failure::get_last_failure()) { + rmdir($baseWorkDir.$newDirPath.$openDir.'/'.$newDirName); + } + + } + } else { // The filename doesn't contain any alphanum chars (empty filename?) + // Get a more detailed message? + $dialogBox .= get_lang('FileError').'<br />'; + } + + /* DELETE FILE OR DIRECTORY */ + + if (isset($delete)) { + if ( scorm_delete($baseWorkDir.$delete)) { + //$tbl_document = substr($tbl_document, 1, strlen($tbl_document) - 2); // RH... + update_db_info('delete', $delete); + $dialogBox = get_lang('DocDeleted'); + } + } - if ( isset($delete) ) - { - if ( scorm_delete($baseWorkDir.$delete)) - { - //$tbl_document = substr($tbl_document, 1, strlen($tbl_document) - 2); // RH... - update_db_info("delete", $delete); - $dialogBox = get_lang('DocDeleted'); - } - } - /*====================================== - CREATE DIRECTORY - ======================================*/ - /* - * The code begin with STEP 2 so it allows to return to STEP 1 - * if STEP 2 unsucceds - */ + /* CREATE DIRECTORY */ - /*------------------------------------- - STEP 2 - --------------------------------------*/ - if (isset($newDirPath) && isset($newDirName)) - { - // echo $newDirPath . $newDirName; - $newDirName = replace_dangerous_char(trim(stripslashes($newDirName)),'strict'); - if( check_name_exist($baseWorkDir.$newDirPath."/".$newDirName) ) - { - $dialogBox = get_lang('FileExists'); - $createDir = $newDirPath; unset($newDirPath);// return to step 1 - } - else - { - if(mkdir($baseWorkDir.$newDirPath."/".$newDirName, api_get_permissions_for_new_directories())) - FileManager::set_default_settings($newDirPath, $newDirName, "folder", $tbl_document); - // RH: was: set_default_settings($newDirPath,$newDirName,"folder"); - $dialogBox = get_lang('DirCr'); - } - } + /* + * The code begin with STEP 2 so it allows to return to STEP 1 if STEP 2 unsucceds. + */ - /*------------------------------------- - STEP 1 - --------------------------------------*/ - if (isset($createDir)) - { - $dialogBox .= "<!-- create dir -->\n" - ."<form name='createdir' action='' method='POST'>\n" - ."<input type=\"hidden\" name=\"newDirPath\" value=\"$createDir\" />\n" - .get_lang('NameDir')." : \n" - ."<input type=\"text\" name=\"newDirName\" />\n" - ."<input type=\"submit\" value=\"".get_lang('Ok')."\" />\n" - ."</form>\n"; - } + /* STEP 2 */ - /*====================================== - VISIBILITY COMMANDS - ======================================*/ - if (!empty($make_directory_visible) || !empty($make_directory_invisible)) - { - $visibilityPath = $make_directory_visible.$make_directory_invisible; - // At least one of these variables are empty. So it's okay to proceed this way - /* Check if there is yet a record for this file in the DB */ - $result = Database::query ("SELECT * FROM $tbl_document WHERE path LIKE '".$visibilityPath."'"); - while($row = Database::fetch_array($result, 'ASSOC')) - { - $attribute['path' ] = $row['path' ]; - $attribute['visibility'] = $row['visibility']; - $attribute['comment' ] = $row['comment' ]; - } + if (isset($newDirPath) && isset($newDirName)) { + // echo $newDirPath . $newDirName; + $newDirName = replace_dangerous_char(trim(stripslashes($newDirName)), 'strict'); + if (check_name_exist($baseWorkDir.$newDirPath.'/'.$newDirName)) { + $dialogBox = get_lang('FileExists'); + $createDir = $newDirPath; unset($newDirPath);// return to step 1 + } else { + if (mkdir($baseWorkDir.$newDirPath.'/'.$newDirName, api_get_permissions_for_new_directories())) + FileManager::set_default_settings($newDirPath, $newDirName, 'folder', $tbl_document); + // RH: was: set_default_settings($newDirPath, $newDirName, 'folder'); + $dialogBox = get_lang('DirCr'); + } + } + + /* STEP 1 */ + + if (isset($createDir)) { + $dialogBox .= "<!-- create dir -->\n" + ."<form name='createdir' action='' method='POST'>\n" + ."<input type=\"hidden\" name=\"newDirPath\" value=\"$createDir\" />\n" + .get_lang('NameDir')." : \n" + ."<input type=\"text\" name=\"newDirName\" />\n" + ."<input type=\"submit\" value=\"".get_lang('Ok')."\" />\n" + ."</form>\n"; + } + + /* VISIBILITY COMMANDS */ - if ($make_directory_visible) - { - $newVisibilityStatus = "v"; - } - elseif ($make_directory_invisible) - { - $newVisibilityStatus = "i"; - } - $query = "UPDATE $tbl_document SET visibility='$newVisibilityStatus' WHERE path=\"".$visibilityPath."\""; //added by Toon - Database::query($query); - if (Database::affected_rows() == 0) // extra check added by Toon, normally not necessary anymore because all files are in the db - { - Database::query("INSERT INTO $tbl_document SET path=\"".$visibilityPath."\", visibility=\"".$newVisibilityStatus."\""); - } - unset($attribute); - $dialogBox = get_lang('ViMod'); - } - } // END is Allowed to Edit; + if (!empty($make_directory_visible) || !empty($make_directory_invisible)) { + $visibilityPath = $make_directory_visible.$make_directory_invisible; + // At least one of these variables are empty. So it's okay to proceed this way + /* Check if there is yet a record for this file in the DB */ + $result = Database::query ("SELECT * FROM $tbl_document WHERE path LIKE '".$visibilityPath."'"); + while($row = Database::fetch_array($result, 'ASSOC')) { + $attribute['path' ] = $row['path' ]; + $attribute['visibility'] = $row['visibility']; + $attribute['comment' ] = $row['comment' ]; + } + + if ($make_directory_visible) { + $newVisibilityStatus = 'v'; + } elseif ($make_directory_invisible) { + $newVisibilityStatus = 'i'; + } + $query = "UPDATE $tbl_document SET visibility='$newVisibilityStatus' WHERE path=\"".$visibilityPath."\""; // Added by Toon. + Database::query($query); + if (Database::affected_rows() == 0) { // Extra check added by Toon, normally not necessary anymore because all files are in the db. + Database::query("INSERT INTO $tbl_document SET path=\"".$visibilityPath."\", visibility=\"".$newVisibilityStatus."\""); + } + unset($attribute); + $dialogBox = get_lang('ViMod'); + } + } // END is Allowed to edit;. } -?> \ No newline at end of file