scormItem.class.php 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311
  1. <?php
  2. /* For licensing terms, see /license.txt */
  3. /**
  4. * Container for the scormItem class that deals with <item> elements in an imsmanifest file
  5. * @package chamilo.learnpath.scorm
  6. * @author Yannick Warnier <ywarnier@beeznest.org>
  7. */
  8. /**
  9. * This class handles the <item> elements from an imsmanifest file.
  10. */
  11. require_once 'learnpathItem.class.php';
  12. class scormItem extends learnpathItem{
  13. public $identifier = '';
  14. public $identifierref = '';
  15. public $isvisible = '';
  16. public $parameters = '';
  17. public $title = '';
  18. public $sub_items = array();
  19. public $metadata;
  20. //public $prerequisites = ''; - defined in learnpathItem.class.php
  21. // Modified by Ivan Tcholakov, 06-FEB-2010.
  22. //public $max_time_allowed = ''; //should be something like HHHH:MM:SS.SS
  23. public $max_time_allowed = '00:00:00';
  24. //
  25. public $timelimitaction = '';
  26. public $datafromlms = '';
  27. public $mastery_score = '';
  28. public $scorm_contact;
  29. /**
  30. * Class constructor. Depending of the type of construction called ('db' or 'manifest'), will create a scormItem
  31. * object from database records or from the DOM element given as parameter
  32. * @param string Type of construction needed ('db' or 'manifest', default = 'manifest')
  33. * @param mixed Depending on the type given, DB id for the lp_item or reference to the DOM element
  34. */
  35. public function __construct($type='manifest',&$element) {
  36. if(isset($element))
  37. {
  38. $v = substr(phpversion(),0,1);
  39. if($v == 4){
  40. switch($type){
  41. case 'db':
  42. parent::__construct($element,api_get_user_id());
  43. $this->scorm_contact = false;
  44. //TODO implement this way of metadata object creation
  45. return false;
  46. case 'manifest': //do the same as the default
  47. default:
  48. //if($first_item->type == XML_ELEMENT_NODE) this is already check prior to the call to this function
  49. $children = $element->children();
  50. foreach($children as $a => $dummy)
  51. {
  52. $child =& $children[$a];
  53. switch($child->type)
  54. {
  55. case XML_ELEMENT_NODE:
  56. switch($child->tagname){
  57. case 'title':
  58. $tmp_children = $child->children();
  59. if(count($tmp_children)==1 and $tmp_children[0]->content!='' )
  60. {
  61. $this->title = $tmp_children[0]->content;
  62. }
  63. break;
  64. case 'maxtimeallowed':
  65. $tmp_children = $child->children();
  66. if(count($tmp_children)==1 and $tmp_children[0]->content!='' )
  67. {
  68. $this->max_time_allowed = $tmp_children[0]->content;
  69. }
  70. break;
  71. case 'prerequisites':
  72. $tmp_children = $child->children();
  73. if(count($tmp_children)==1 and $tmp_children[0]->content!='' )
  74. {
  75. $this->prereq_string = $tmp_children[0]->content;
  76. }
  77. break;
  78. case 'timelimitaction':
  79. $tmp_children = $child->children();
  80. if(count($tmp_children)==1 and $tmp_children[0]->content!='' )
  81. {
  82. $this->timelimitaction = $tmp_children[0]->content;
  83. }
  84. break;
  85. case 'datafromlms':
  86. $tmp_children = $child->children();
  87. if(count($tmp_children)==1 and $tmp_children[0]->content!='' )
  88. {
  89. $this->datafromlms = $tmp_children[0]->content;
  90. }
  91. break;
  92. case 'masteryscore':
  93. $tmp_children = $child->children();
  94. if(count($tmp_children)==1 and $tmp_children[0]->content!='' )
  95. {
  96. $this->mastery_score = $tmp_children[0]->content;
  97. }
  98. break;
  99. case 'item':
  100. $oItem = new scormItem('manifest',$child);
  101. if($oItem->identifier != ''){
  102. $this->sub_items[$oItem->identifier] = $oItem;
  103. }
  104. break;
  105. case 'metadata':
  106. $this->metadata = new scormMetadata('manifest',$child);
  107. break;
  108. }
  109. break;
  110. case XML_TEXT_NODE:
  111. //this case is actually treated by looking into ELEMENT_NODEs above
  112. break;
  113. }
  114. }
  115. $attributes = $element->attributes();
  116. //$keep_href = '';
  117. foreach($attributes as $a1 => $dummy)
  118. {
  119. $attrib =& $attributes[$a1];
  120. switch($attrib->name){
  121. case 'identifier':
  122. $this->identifier = $attrib->value;
  123. break;
  124. case 'identifierref':
  125. $this->identifierref = $attrib->value;
  126. break;
  127. case 'isvisible':
  128. $this->isvisible = $attrib->value;
  129. break;
  130. case 'parameters':
  131. $this->parameters = $attrib->value;
  132. break;
  133. }
  134. }
  135. return true;
  136. }
  137. }elseif($v == 5){
  138. //parsing using PHP5 DOMXML methods
  139. switch($type){
  140. case 'db':
  141. parent::__construct($element,api_get_user_id());
  142. $this->scorm_contact = false;
  143. //TODO implement this way of metadata object creation
  144. return false;
  145. case 'manifest': //do the same as the default
  146. default:
  147. //if($first_item->type == XML_ELEMENT_NODE) this is already check prior to the call to this function
  148. $children = $element->childNodes;
  149. foreach($children as $child)
  150. {
  151. switch($child->nodeType)
  152. {
  153. case XML_ELEMENT_NODE:
  154. switch($child->tagName){
  155. case 'title':
  156. $tmp_children = $child->childNodes;
  157. //if(count($tmp_children)==1 and $tmp_children[0]->textContent!='' )
  158. if($tmp_children->length==1 and $child->firstChild->nodeValue!='' )
  159. {
  160. $this->title = $child->firstChild->nodeValue;
  161. }
  162. break;
  163. case 'max_score':
  164. if($tmp_children->length==1 and $child->firstChild->nodeValue!='' ) {
  165. $this->max_score = $child->firstChild->nodeValue;
  166. }
  167. break;
  168. case 'maxtimeallowed':
  169. case 'adlcp:maxtimeallowed':
  170. $tmp_children = $child->childNodes;
  171. //if(count($tmp_children)==1 and $tmp_children[0]->textContent!='' )
  172. if($tmp_children->length==1 and $child->firstChild->nodeValue!='' )
  173. {
  174. $this->max_time_allowed = $child->firstChild->nodeValue;
  175. }
  176. break;
  177. case 'prerequisites':
  178. case 'adlcp:prerequisites':
  179. $tmp_children = $child->childNodes;
  180. //if(count($tmp_children)==1 and $tmp_children[0]->textContent!='' )
  181. if($tmp_children->length==1 and $child->firstChild->nodeValue!='' )
  182. {
  183. $this->prereq_string = $child->firstChild->nodeValue;
  184. }
  185. break;
  186. case 'timelimitaction':
  187. case 'adlcp:timelimitaction':
  188. $tmp_children = $child->childNodes;
  189. //if(count($tmp_children)==1 and $tmp_children[0]->textContent!='' )
  190. if($tmp_children->length==1 and $child->firstChild->nodeValue!='' )
  191. {
  192. $this->timelimitaction = $child->firstChild->nodeValue;
  193. }
  194. break;
  195. case 'datafromlms':
  196. case 'adlcp:datafromlms':
  197. case 'adlcp:launchdata': //in some cases (Wouters)
  198. $tmp_children = $child->childNodes;
  199. //if(count($tmp_children)==1 and $tmp_children[0]->textContent!='' )
  200. if($tmp_children->length==1 and $child->firstChild->nodeValue!='' )
  201. {
  202. $this->datafromlms = $child->firstChild->nodeValue;
  203. }
  204. break;
  205. case 'masteryscore':
  206. case 'adlcp:masteryscore':
  207. $tmp_children = $child->childNodes;
  208. //if(count($tmp_children)==1 and $tmp_children[0]->textContent!='' )
  209. if($tmp_children->length==1 and $child->firstChild->nodeValue!='' )
  210. {
  211. $this->mastery_score = $child->firstChild->nodeValue;
  212. }
  213. break;
  214. case 'item':
  215. $oItem = new scormItem('manifest',$child);
  216. if($oItem->identifier != ''){
  217. $this->sub_items[$oItem->identifier] = $oItem;
  218. }
  219. break;
  220. case 'metadata':
  221. $this->metadata = new scormMetadata('manifest',$child);
  222. break;
  223. }
  224. break;
  225. case XML_TEXT_NODE:
  226. //this case is actually treated by looking into ELEMENT_NODEs above
  227. break;
  228. }
  229. }
  230. if($element->hasAttributes()){
  231. $attributes = $element->attributes;
  232. //$keep_href = '';
  233. foreach($attributes as $attrib)
  234. {
  235. switch($attrib->name){
  236. case 'identifier':
  237. $this->identifier = $attrib->value;
  238. break;
  239. case 'identifierref':
  240. $this->identifierref = $attrib->value;
  241. break;
  242. case 'isvisible':
  243. $this->isvisible = $attrib->value;
  244. break;
  245. case 'parameters':
  246. $this->parameters = $attrib->value;
  247. break;
  248. }
  249. }
  250. }
  251. return true;
  252. }
  253. }else{
  254. //cannot parse because not PHP4 nor PHP5... We should not even be here anyway...
  255. return false;
  256. }
  257. }
  258. return false;
  259. }
  260. /**
  261. * Builds a flat list with the current item and calls itself recursively on all children
  262. * @param array Reference to the array to complete with the current item
  263. * @param integer Optional absolute order (pointer) of the item in this learning path
  264. * @param integer Optional relative order of the item at this level
  265. * @param integer Optional level. If not given, assumes it's level 0
  266. */
  267. public function get_flat_list(&$list,&$abs_order,$rel_order=1,$level=0) {
  268. $list[] = array(
  269. 'abs_order' => $abs_order,
  270. 'datafromlms' => $this->datafromlms,
  271. 'identifier' => $this->identifier,
  272. 'identifierref' => $this->identifierref,
  273. 'isvisible' => $this->isvisible,
  274. 'level' => $level,
  275. 'masteryscore' => $this->mastery_score,
  276. 'maxtimeallowed' => $this->max_time_allowed,
  277. 'metadata' => $this->metadata,
  278. 'parameters' => $this->parameters,
  279. 'prerequisites' => (!empty($this->prereq_string)?$this->prereq_string:''),
  280. 'rel_order' => $rel_order,
  281. 'timelimitaction' => $this->timelimitaction,
  282. 'title' => $this->title,
  283. 'max_score' => $this->max_score
  284. );
  285. $abs_order++;
  286. $i = 1;
  287. foreach($this->sub_items as $id => $dummy)
  288. {
  289. $oSubitem =& $this->sub_items[$id];
  290. $oSubitem->get_flat_list($list,$abs_order,$i,$level+1);
  291. $i++;
  292. }
  293. }
  294. /**
  295. * Save function. Uses the parent save function and adds a layer for SCORM.
  296. * @param boolean Save from URL params (1) or from object attributes (0)
  297. */
  298. public function save($from_outside=true,$prereqs_complete=false) {
  299. parent::save($from_outside,$prereqs_complete);
  300. //under certain conditions, the scorm_contact should not be set, because no scorm signal was sent
  301. $this->scorm_contact = true;
  302. if(!$this->scorm_contact){
  303. //error_log('New LP - was expecting SCORM message but none received',0);
  304. }
  305. }
  306. }
  307. ?>