Beispiel #1
0
 /**
  * This function will add the attributes that are extracted from the qti xml
  * into the database.
  *
  * @param	array	attributes that are extracted from the QTI XML.
  * @return	int		the question ids.
  */
 function importQuestions($attributes)
 {
     global $supported_media_type, $msg;
     $qids = array();
     foreach ($attributes as $resource => $attrs) {
         if (preg_match('/imsqti\\_(.*)/', $attrs['type'])) {
             //Instantiate class obj
             $xml = new QTIParser($attrs['type']);
             $xml_content = @file_get_contents($this->import_path . $attrs['href']);
             $xml->setRelativePath($package_base_name);
             if (!$xml->parse($xml_content)) {
                 $msg->addError('QTI_WRONG_PACKAGE');
                 break;
             }
             //set test title
             $this->title = $xml->title;
             //if ($attrs[href] =='56B1BEDC-A820-7AA8-A21D-F32017189445/56B1BEDC-A820-7AA8-A21D-F32017189445.xml'){
             //	debug($xml, 'attributes');
             //}
             //import file, should we use file href? or jsut this href?
             //Aug 25, use both, so then it can check for respondus media as well.
             foreach ($attrs['file'] as $file_id => $file_name) {
                 $file_pathinfo = pathinfo($file_name);
                 if ($file_pathinfo['basename'] == $attrs['href']) {
                     //This file will be parsed later
                     continue;
                 }
                 if (in_array(strtolower($file_pathinfo['extension']), $supported_media_type)) {
                     //copy medias over.
                     $this->copyMedia(array($file_name), $xml->items);
                 }
             }
             for ($loopcounter = 0; $loopcounter < $xml->item_num; $loopcounter++) {
                 //Create POST values.
                 unset($test_obj);
                 //clear cache
                 $test_obj['required'] = 1;
                 $test_obj['preset_num'] = 0;
                 $test_obj['category_id'] = 0;
                 $test_obj['question'] = $xml->question[$loopcounter];
                 $test_obj['feedback'] = $xml->feedback[$loopcounter];
                 $test_obj['groups'] = $xml->groups[$loopcounter];
                 $test_obj['property'] = intval($xml->attributes[$loopcounter]['render_fib']['property']);
                 $test_obj['choice'] = array();
                 $test_obj['answers'] = array();
                 //assign choices
                 $i = 0;
                 //trim values
                 if (is_array($xml->answers[$loopcounter])) {
                     array_walk($xml->answers[$loopcounter], 'trim_value');
                 }
                 //TODO: The groups is 1-0+ choices.  So we should loop thru groups, not choices.
                 if (is_array($xml->choices[$loopcounter])) {
                     foreach ($xml->choices[$loopcounter] as $choiceNum => $choiceOpt) {
                         if (sizeof($test_obj['groups']) > 0) {
                             if (!empty($xml->answers[$loopcounter])) {
                                 foreach ($xml->answers[$loopcounter] as $ansNum => $ansOpt) {
                                     if ($choiceNum == $ansOpt) {
                                         //Not exactly efficient, worst case N^2
                                         $test_obj['answers'][$ansNum] = $i;
                                     }
                                 }
                             }
                         } else {
                             //save answer(s)
                             if (is_array($xml->answers[$loopcounter]) && in_array($choiceNum, $xml->answers[$loopcounter])) {
                                 $test_obj['answers'][] = $i;
                             }
                         }
                         $test_obj['choice'][] = $choiceOpt;
                         $i++;
                     }
                 }
                 //			unset($qti_import);
                 $this->constructParams($test_obj);
                 //debug($xml->getQuestionType($loopcounter), 'lp_'.$loopcounter);
                 //Create questions
                 $this->getQuestionType($xml->getQuestionType($loopcounter));
                 //save question id
                 $qids[] = $this->qid;
                 //Dependency handling
                 if (!empty($attrs['dependency'])) {
                     $xml_items = array_merge($xml_items, $xml->items);
                 }
             }
             //assign title
             if ($xml->title != '') {
                 $this->title = $xml->title;
             }
             //assign marks/weights
             $this->weights = $xml->weights;
             $xml->close();
         } elseif ($attrs['type'] == 'webcontent') {
             //webcontent, copy it over.
             $this->copyMedia($attrs['file'], $xml_items);
         }
     }
     //debug($qids, 'qids');
     return $qids;
 }
/**
 * Validate all the XML in the package, including checking XSDs, missing data.
 * @param string the path of the directory that contains all the package files
 * @return boolean true if every file exists in the manifest,
 * false if any is missing.
 */
function checkResources($import_path)
{
    global $items, $msg, $skip_ims_validation, $avail_dt;
    if (!is_dir($import_path)) {
        return;
    }
    //if the package has access for all content, skip validation for now.
    //todo: import the XSD into our validator
    if ($skip_ims_validation) {
        return true;
    }
    //generate a file tree
    $data = rscandir($import_path);
    //check if every file is presented in the manifest
    foreach ($data as $filepath) {
        $filepath = substr($filepath, strlen($import_path));
        //validate xml via its xsd/dtds
        if (preg_match('/(.*)\\.xml/', $filepath)) {
            libxml_use_internal_errors(true);
            $dom = new DOMDocument();
            $dom->load(realpath($import_path . $filepath));
            if (!@$dom->schemaValidate('main.xsd')) {
                $errors = libxml_get_errors();
                foreach ($errors as $error) {
                    //suppress warnings
                    if ($error->level == LIBXML_ERR_WARNING) {
                        continue;
                    }
                    $msg->addError(array('IMPORT_CARTRIDGE_FAILED', libxml_display_error($error)));
                }
                libxml_clear_errors();
            }
            //if this is the manifest file, we do not have
            //to check for its existance.
            //			if (preg_match('/(.*)imsmanifest\.xml/', $filepath)){
            //				continue;
            //			}
        }
    }
    //Create an array that mimics the structure of the data array,
    //based on the xml items
    $filearray = array();
    foreach ($items as $name => $fileinfo) {
        if (isset($fileinfo['file']) && is_array($fileinfo['file']) && !empty($fileinfo['file'])) {
            foreach ($fileinfo['file'] as $fn) {
                if (!in_array(realpath($import_path . $fn), $filearray)) {
                    //if url, skip
                    if (preg_match('/^http[s]?\\:/', $fn) == 0) {
                        $filearray[] = realpath($import_path . $fn);
                    }
                }
            }
        }
        //validate the xml by its schema
        if (preg_match('/imsqti\\_(.*)/', $fileinfo['type'])) {
            $qti = new QTIParser($fileinfo['type']);
            $xml_content = @file_get_contents($import_path . $fileinfo['href']);
            $qti->parse($xml_content);
            //will add error to $msg if failed
        }
        //add all dependent discussion tools to a list
        if (isset($fileinfo['dependency']) && !empty($fileinfo['dependency'])) {
            $avail_dt = array_merge($avail_dt, $fileinfo['dependency']);
        }
    }
    //check if all files in the xml is presented in the archieve
    $result = array_diff($filearray, $data);
    //using sizeof because array_diff only
    //returns an array containing all the entries from array1  that
    //are not present in any of the
    //other arrays.
    //Using sizeof make sure it's not a subset of array2.
    //-1 on data because it always contain the imsmanifest.xml file
    if (!$skip_ims_validation) {
        if (!empty($result) || sizeof($data) - 1 > sizeof($filearray)) {
            $msg->addError(array('IMPORT_CARTRIDGE_FAILED', _AT('ims_missing_references')));
        }
    }
    return true;
}
Beispiel #3
0
/**
 * Validate all the XML in the package, including checking XSDs, missing data.
 * @param	string		the path of the directory that contains all the package files
 * @return	boolean		true if every file exists in the manifest, false if any is missing.
 */
function checkResources($import_path)
{
    global $items, $msg, $skip_ims_validation;
    if (!is_dir($import_path)) {
        return;
    }
    //if the package has access for all content, skip validation for now.
    //todo: import the XSD into our validator
    if ($skip_ims_validation) {
        return true;
    }
    //generate a file tree
    $data = rscandir($import_path);
    //check if every file is presented in the manifest
    foreach ($data as $filepath) {
        $filepath = substr($filepath, strlen($import_path));
        //validate xml via its xsd/dtds
        if (preg_match('/(.*)\\.xml/', $filepath)) {
            $dom = new DOMDocument();
            $dom->load(realpath($import_path . $filepath));
            if (!@$dom->schemaValidate('main.xsd')) {
                $msg->addError('MANIFEST_FAILED_VALIDATION - ' . $filepath);
            }
            //if this is the manifest file, we do not have to check for its existance.
            if (preg_match('/(.*)imsmanifest\\.xml/', $filepath)) {
                continue;
            }
        }
        $flag = false;
        $file_exists_in_manifest = false;
        //check if every file in manifest indeed exists
        foreach ($items as $name => $fileinfo) {
            if (is_array($fileinfo['file'])) {
                if (in_array($filepath, $fileinfo['file'])) {
                    $file_exists_in_manifest = true;
                    //validate the xml by its schema
                    if (preg_match('/imsqti\\_(.*)/', $fileinfo['type'])) {
                        $qti = new QTIParser($fileinfo['type']);
                        $xml_content = @file_get_contents($import_path . $fileinfo['href']);
                        $qti->parse($xml_content);
                        if ($msg->containsErrors()) {
                            $flag = false;
                        } else {
                            $flag = true;
                        }
                    } else {
                        $flag = true;
                    }
                }
            }
        }
        //check if all the files exists in the manifest, if not, throw error.
        if (!$file_exists_in_manifest) {
            $msg->addError('MANIFEST_NOT_WELLFORM: MISSING REFERENCES');
            break;
        }
        if ($flag == false) {
            //add an error message if it doesn't have any.
            if (!$msg->containsErrors()) {
                $msg->addError('MANIFEST_NOT_WELLFORM: MISSING REFERENCES');
            }
            return false;
        }
    }
    return true;
}