1<?php 2/* Copyright (c) 1998-2009 ILIAS open source, Extended GPL, see docs/LICENSE */ 3 4include_once "./Services/Xml/classes/class.ilXmlWriter.php"; 5include_once "./Modules/Exercise/classes/class.ilExAssignment.php"; 6 7/** 8 * XML writer class 9 * 10 * Class to simplify manual writing of xml documents. 11 * It only supports writing xml sequentially, because the xml document 12 * is saved in a string with no additional structure information. 13 * The author is responsible for well-formedness and validity 14 * of the xml document. 15 * 16 * @author Roland Küstermann <Roland@kuestermann.com> 17 * @version $Id: class.ilExerciseXMLWriter.php,v 1.3 2005/11/04 12:50:24 smeyer Exp $ 18 * 19 * @ingroup ModulesExercise 20 */ 21class ilExerciseXMLWriter extends ilXmlWriter 22{ 23 public static $CONTENT_ATTACH_NO = 0; 24 public static $CONTENT_ATTACH_ENCODED = 1; 25 public static $CONTENT_ATTACH_ZLIB_ENCODED = 2; 26 public static $CONTENT_ATTACH_GZIP_ENCODED = 3; 27 28 public static $STATUS_NOT_GRADED = "NOT_GRADED"; 29 public static $STATUS_PASSED = "PASSED"; 30 public static $STATUS_FAILED = "FAILED"; 31 /** 32 * if true, file contents will be attached as base64 33 * 34 * @var boolean 35 */ 36 public $attachFileContents; 37 38 /** 39 * if true, members will be attach to xml 40 * 41 * @var boolean 42 */ 43 public $attachMembers; 44 45 /** 46 * Exercise Object 47 * 48 * @var ilObjExercise 49 */ 50 public $exercise; 51 52 /** 53 * constructor 54 * @param string xml version 55 * @param string output encoding 56 * @param string input encoding 57 * @access public 58 */ 59 public function __construct() 60 { 61 // @todo: needs to be revised for multiple assignments per exercise 62 //die ("Needs revision for ILIAS 4.1"); 63 parent::__construct(); 64 $this->attachFileContents = ilExerciseXMLWriter::$CONTENT_ATTACH_NO; 65 } 66 67 /** 68 * 69 * set exercise object 70 * @param ilObjExercise $exercise 71 */ 72 73 public function setExercise($exercise) 74 { 75 $this->exercise = $exercise; 76 } 77 78 /** 79 * set attachment content mode 80 * 81 * @param int $attachFileContents 82 * @throws ilExerciseException if mode is not supported 83 */ 84 public function setAttachFileContents($attachFileContents) 85 { 86 if ($attachFileContents == ilExerciseXMLWriter::$CONTENT_ATTACH_GZIP_ENCODED && !function_exists("gzencode")) { 87 throw new ilExerciseException("Inflating with gzip is not supported", ilExerciseException::$ID_DEFLATE_METHOD_MISMATCH); 88 } 89 if ($attachFileContents == ilExerciseXMLWriter::$CONTENT_ATTACH_ZLIB_ENCODED && !function_exists("gzcompress")) { 90 throw new ilExerciseException("Inflating with zlib (compress/uncompress) is not supported", ilExerciseException::$ID_DEFLATE_METHOD_MISMATCH); 91 } 92 93 $this->attachFileContents = $attachFileContents; 94 } 95 96 public function start() 97 { 98 $this->__buildHeader(); 99 100 $attribs = array("obj_id" => "il_" . IL_INST_ID . "_exc_" . $this->exercise->getId() ); 101 102 if ($this->exercise->getOwner()) { 103 $attribs ["owner"] = "il_" . IL_INST_ID . "_usr_" . $this->exercise->getOwner(); 104 } 105 106 $this->xmlStartTag("Exercise", $attribs); 107 108 //todo: create new dtd for new assignment structure 109 $this->xmlElement("Title", null, $this->exercise->getTitle()); 110 $this->xmlElement("Description", null, $this->exercise->getDescription()); 111 //$this->xmlElement("Instruction", null,$this->exercise->getInstruction()); 112 //$this->xmlElement("DueDate", null,$this->exercise->getTimestamp()); 113 114 115 //todo: as a workaround use first assignment for compatibility with old exercise dtd 116 $assignments = ilExAssignment::getAssignmentDataOfExercise($this->exercise->getId()); 117 118 if (count($assignments) > 0) { 119 foreach ($assignments as $assignment) { 120 $this->xmlStartTag("Assignment"); 121 $this->xmlElement("Instruction", null, $assignment ["instruction"]); 122 $this->xmlElement("DueDate", null, $assignment ["deadline"]); 123 124 $this->handleAssignmentFiles($this->exercise->getId(), $assignment ["id"]); 125 if ($this->attachMembers) { 126 $this->handleAssignmentMembers($this->exercise->getId(), $assignment ["id"]); 127 } 128 $this->xmlEndTag("Assignment"); 129 } 130 } 131 132 133 $this->xmlEndTag("Exercise"); 134 $this->__buildFooter(); 135 136 return true; 137 } 138 139 public function getXML() 140 { 141 return $this->xmlDumpMem(false); 142 } 143 144 public function __buildHeader() 145 { 146 $this->xmlSetDtdDef("<!DOCTYPE Exercise PUBLIC \"-//ILIAS//DTD ExerciseAdministration//EN\" \"" . ILIAS_HTTP_PATH . "/xml/ilias_exercise_4_4.dtd\">"); 147 $this->xmlSetGenCmt("Exercise Object"); 148 $this->xmlHeader(); 149 150 return true; 151 } 152 153 public function __buildFooter() 154 { 155 } 156 157 /** 158 * write access to property attchMarkings 159 * 160 * @param boolean $value 161 */ 162 public function setAttachMembers($value) 163 { 164 $this->attachMembers = $value ? true : false; 165 } 166 167 /** 168 * attach marking tag to member for given assignment 169 * 170 * @param int $user_id 171 * @param int $assignment_id 172 */ 173 private function attachMarking($user_id, $assignment_id) 174 { 175 $ass = new ilExAssignment($assignment_id); 176 177 $amark = $ass->getMemberStatus($user_id)->getMark(); 178 $astatus = $ass->getMemberStatus($user_id)->getStatus(); 179 $acomment = $ass->getMemberStatus($user_id)->getComment(); 180 $anotice = $ass->getMemberStatus($user_id)->getNotice(); 181 182 183 if ($astatus == "notgraded") { 184 $status = ilExerciseXMLWriter::$STATUS_NOT_GRADED; 185 } elseif ($astatus == "failed") { 186 $status = ilExerciseXMLWriter::$STATUS_FAILED; 187 } else { 188 $status = ilExerciseXMLWriter::$STATUS_PASSED; 189 } 190 191 $this->xmlStartTag("Marking", array("status" => $status )); 192 $this->xmlElement("Mark", null, $amark); 193 $this->xmlElement("Notice", null, $anotice); 194 $this->xmlElement("Comment", null, $acomment); 195 $this->xmlEndTag("Marking"); 196 } 197 198 private function handleAssignmentFiles($ex_id, $as_id) 199 { 200 $this->xmlStartTag("Files"); 201 include_once("./Modules/Exercise/classes/class.ilFSStorageExercise.php"); 202 $storage = new ilFSStorageExercise($ex_id, $as_id); 203 $files = $storage->getFiles(); 204 205 if (count($files)) { 206 foreach ($files as $file) { 207 $this->xmlStartTag("File", array("size" => $file ["size"] )); 208 $this->xmlElement("Filename", null, $file ["name"]); 209 if ($this->attachFileContents) { 210 $filename = $file ["fullpath"]; 211 if (@is_file($filename)) { 212 $content = @file_get_contents($filename); 213 $attribs = array("mode" => "PLAIN" ); 214 if ($this->attachFileContents == ilExerciseXMLWriter::$CONTENT_ATTACH_ZLIB_ENCODED) { 215 $attribs = array("mode" => "ZLIB" ); 216 $content = gzcompress($content, 9); 217 } elseif ($this->attachFileContents == ilExerciseXMLWriter::$CONTENT_ATTACH_GZIP_ENCODED) { 218 $attribs = array("mode" => "GZIP" ); 219 $content = gzencode($content, 9); 220 } 221 $content = base64_encode($content); 222 $this->xmlElement("Content", $attribs, $content); 223 } 224 } 225 $this->xmlEndTag("File"); 226 } 227 } 228 $this->xmlEndTag("Files"); 229 } 230 231 /** 232 * create xml for files per assignment 233 * 234 * @param integer $ex_id exercise id 235 * @param array $assignments assignment id 236 */ 237 private function handleAssignmentMembers($ex_id, $assignment_id) 238 { 239 $this->xmlStartTag("Members"); 240 include_once("./Modules/Exercise/classes/class.ilExerciseMembers.php"); 241 $members = ilExerciseMembers::_getMembers($ex_id); 242 if (count($members)) { 243 foreach ($members as $member_id) { 244 $this->xmlStartTag("Member", array("usr_id" => "il_" . IL_INST_ID . "_usr_" . $member_id )); 245 246 $name = ilObjUser::_lookupName($member_id); 247 248 $this->xmlElement("Firstname", array(), $name['firstname']); 249 $this->xmlElement("Lastname", array(), $name['lastname']); 250 $this->xmlElement("Login", array(), $name['login']); 251 $this->attachMarking($member_id, $assignment_id); 252 $this->xmlEndTag("Member"); 253 } 254 } 255 $this->xmlEndTag("Members"); 256 } 257} 258