Merge branch 'MDL-45444-master' of git://github.com/andrewnicols/moodle
authorEloy Lafuente (stronk7) <stronk7@moodle.org>
Thu, 8 May 2014 10:40:27 +0000 (12:40 +0200)
committerEloy Lafuente (stronk7) <stronk7@moodle.org>
Thu, 8 May 2014 10:40:27 +0000 (12:40 +0200)
35 files changed:
admin/tool/availabilityconditions/index.php
admin/tool/availabilityconditions/settings.php
admin/tool/availabilityconditions/tests/behat/manage_conditions.feature [new file with mode: 0644]
backup/cc/cc_includes.php
backup/cc/cc_lib/cc_assesment_essay.php [new file with mode: 0644]
backup/cc/cc_lib/cc_assesment_sfib.php [new file with mode: 0644]
backup/cc/cc_lib/cc_assesment_truefalse.php [new file with mode: 0644]
backup/cc/cc_lib/cc_asssesment.php
backup/cc/cc_lib/cc_converter_folder.php [new file with mode: 0644]
backup/cc/cc_lib/cc_converter_quiz.php
backup/cc/cc_lib/cc_converter_resource.php
backup/cc/cc_lib/cc_converters.php
backup/cc/cc_lib/cc_manifest.php
backup/cc/cc_lib/cc_page.php
backup/cc/cc_lib/cc_resources.php
backup/cc/cc_lib/cc_utils.php
backup/cc/cc_lib/cc_version1.php
backup/cc/cc_lib/cc_version11.php
backup/cc/cc_lib/cc_version_base.php
backup/cc/cc_lib/gral_lib/ccdependencyparser.php
backup/cc/cc_lib/xmlbase.php
backup/cc/entities.class.php
backup/cc/entity.quiz.class.php
backup/cc/entity11.quiz.class.php
backup/cc/sheets/course_modules_mod_forum.xml
backup/converter/imscc1/lib.php
backup/converter/imscc11/lib.php
backup/converter/moodle1/lib.php
composer.json
mod/quiz/report/statistics/tests/fixtures/responsecounts01.csv
mod/quiz/report/statistics/tests/fixtures/responsecounts02.csv
mod/wiki/locallib.php
question/behaviour/behaviourbase.php
question/behaviour/interactivecountback/behaviour.php
repository/url/lib.php

index 4852c4e..485fc23 100644 (file)
@@ -43,7 +43,7 @@ foreach (core_component::get_plugin_list('availability') as $plugin => $plugindi
 core_collator::asort($plugins);
 
 // Do plugin actions.
-$pageurl = new moodle_url('/' . $CFG->admin . '/availabilityconditions.php');
+$pageurl = new moodle_url('/' . $CFG->admin . '/tool/availabilityconditions/');
 if (($plugin = optional_param('plugin', '', PARAM_PLUGIN))) {
     require_sesskey();
     if (!array_key_exists($plugin, $plugins)) {
@@ -103,8 +103,6 @@ foreach ($plugins as $plugin => $name) {
 
     // Make enable control. This is a POST request (using a form control rather
     // than just a link) because it makes a database change.
-    $targeturl = new moodle_url('availabilityconditions.php', array(
-            'plugin' => $plugin, 'action' => $enabledaction, 'sesskey' => sesskey()));
     $enablecontrol = html_writer::tag('form', html_writer::div(
             html_writer::empty_tag('input', array('type' => 'hidden',
                     'name' => 'sesskey', 'value' => sesskey())) .
@@ -116,7 +114,7 @@ foreach ($plugins as $plugin => $name) {
                     'src' => $OUTPUT->pix_url('t/' . $enabledaction), 'alt' => $enabledstr,
                     'title' => $enabledstr))
             ), array(
-            'method' => 'post', 'action' => 'availabilityconditions.php'));
+            'method' => 'post', 'action' => './'));
 
     $table->add_data(array($namespan, $version, $enablecontrol));
 }
index 95765ec..13c5c65 100644 (file)
@@ -24,7 +24,7 @@
 
 defined('MOODLE_INTERNAL') || die();
 
-if ($hassiteconfig) {
+if ($hassiteconfig && !empty($CFG->enableavailability)) {
     $ADMIN->add('modules', new admin_category('availabilitysettings',
             new lang_string('type_availability_plural', 'plugin')));
     $ADMIN->add('availabilitysettings', new admin_externalpage('manageavailability',
diff --git a/admin/tool/availabilityconditions/tests/behat/manage_conditions.feature b/admin/tool/availabilityconditions/tests/behat/manage_conditions.feature
new file mode 100644 (file)
index 0000000..3df48ed
--- /dev/null
@@ -0,0 +1,58 @@
+@tool @tool_availabilityconditions
+Feature: Manage availability conditions
+  In order to control availability restrictions
+  As an administrator
+  I need to see the list of restrictions and hide or show them
+
+  @javascript
+  Scenario: Display list of availability conditions
+    # Check the report doesn't show when not enabled.
+    Given I log in as "admin"
+    And I expand "Site administration" node
+    When I expand "Plugins" node
+    Then I should not see "Availability restrictions"
+
+    # Enable it and check I can now see and click on it.
+    And I set the following administration settings values:
+      | Enable conditional access | 1 |
+    And I am on homepage
+    And I navigate to "Manage restrictions" node in "Site administration > Plugins > Availability restrictions"
+
+    # Having clicked on it, I should also see the list of plugins.
+    And I should see "Restriction by date"
+    And I should see "Restriction by grades"
+
+  @javascript
+  Scenario: Hide and show conditions
+    # Get to the right page
+    Given the following "courses" exist:
+      | fullname | shortname | format |
+      | Course 1 | C1        | topics |
+    And I log in as "admin"
+    And I set the following administration settings values:
+      | Enable conditional access | 1 |
+    And I am on homepage
+    When I navigate to "Manage restrictions" node in "Site administration > Plugins > Availability restrictions"
+
+    # Check the icon is there (it should be a Hide icon, meaning is currently visible).
+    Then "input[title=Hide]" "css_element" should exist in the "Restriction by date" "table_row"
+
+    # Click the icon. It should toggle to hidden (title=Show).
+    And I click on "input[title=Hide]" "css_element" in the "Restriction by date" "table_row"
+    And "input[title=Show]" "css_element" should exist in the "Restriction by date" "table_row"
+
+    # Toggle it back to visible (title=Hide).
+    And I click on "input[title=Show]" "css_element" in the "Restriction by date" "table_row"
+    And "input[title=Hide]" "css_element" should exist in the "Restriction by date" "table_row"
+
+    # OK, toggling works. Set the grade one to Hide and we'll go see if it actually worked.
+    And I click on "input[title=Hide]" "css_element" in the "Restriction by grade" "table_row"
+    And I am on homepage
+    And I follow "Course 1"
+    And I turn editing mode on
+    And I add a "Page" to section "1"
+    And I expand all fieldsets
+    And I click on "Add restriction..." "button"
+    And "Add restriction..." "dialogue" should be visible
+    And "Date" "button" should exist in the "Add restriction..." "dialogue"
+    And "Grade" "button" should not exist in the "Add restriction..." "dialogue"
index 9b1a9bd..0c920e1 100644 (file)
 //
 // You should have received a copy of the GNU General Public License
 // along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
+
 /**
-* Main include for IMS Common Cartridge export classes
-*
-* @package    backup-convert
-* @copyright  2011 Darko Miletic <dmiletic@moodlerooms.com>
-* @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
-*/
+ * Main include for IMS Common Cartridge export classes
+ *
+ * @package    backup-convert
+ * @copyright  2011 Darko Miletic <dmiletic@moodlerooms.com>
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
 
 require_once($CFG->dirroot .'/backup/cc/cc_lib/xmlbase.php');
 require_once($CFG->dirroot .'/backup/cc/cc_lib/cc_resources.php');
@@ -40,4 +41,5 @@ require_once($CFG->dirroot .'/backup/cc/cc_lib/cc_converter_resource.php');
 require_once($CFG->dirroot .'/backup/cc/cc_lib/cc_converter_quiz.php');
 require_once($CFG->dirroot .'/backup/cc/cc_lib/cc_converter_page.php');
 require_once($CFG->dirroot .'/backup/cc/cc_lib/cc_converter_label.php');
+require_once($CFG->dirroot .'/backup/cc/cc_lib/cc_converter_folder.php');
 require_once($CFG->dirroot .'/backup/cc/cc_lib/cc_convert_moodle2.php');
diff --git a/backup/cc/cc_lib/cc_assesment_essay.php b/backup/cc/cc_lib/cc_assesment_essay.php
new file mode 100644 (file)
index 0000000..cd8c318
--- /dev/null
@@ -0,0 +1,69 @@
+<?php
+// This file is part of Moodle - http://moodle.org/
+//
+// Moodle is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Moodle is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
+/**
+ * @package    backup-convert
+ * @copyright  2012 Darko Miletic <dmiletic@moodlerooms.com>
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+defined('MOODLE_INTERNAL') or die('Direct access to this script is forbidden.');
+
+class cc_assesment_question_essay extends cc_assesment_question_proc_base {
+    public function __construct($quiz, $questions, $manifest, $section, $question_node, $rootpath, $contextid, $outdir) {
+        parent::__construct($quiz, $questions, $manifest, $section, $question_node, $rootpath, $contextid, $outdir);
+        $this->qtype = cc_qti_profiletype::essay;
+        $maximum_quiz_grade = (int)$this->quiz->nodeValue('/activity/quiz/grade');
+        $this->total_grade_value = ($maximum_quiz_grade + 1).'.0000000';
+    }
+
+    public function on_generate_metadata() {
+        parent::on_generate_metadata();
+        // Mark essay for manual grading.
+        $this->qmetadata->enable_scoringpermitted();
+        $this->qmetadata->enable_computerscored(false);
+    }
+
+    public function on_generate_presentation() {
+        parent::on_generate_presentation();
+        $response_str = new cc_assesment_response_strtype();
+        $response_fib = new cc_assesment_render_fibtype();
+        $row_value = (int)$this->questions->nodeValue('plugin_qtype_essay_question//responsefieldlines', $this->question_node);
+        $response_fib->set_rows($row_value);
+        $response_str->set_render_fib($response_fib);
+        $this->qpresentation->set_response_str($response_str);
+    }
+
+    public function on_generate_response_processing() {
+        parent::on_generate_response_processing();
+
+        // Response conditions.
+        if (!empty($this->general_feedback)) {
+            $qrespcondition = new cc_assesment_respconditiontype();
+            $qrespcondition->set_title('General feedback');
+            $this->qresprocessing->add_respcondition($qrespcondition);
+            // Define the condition for success.
+            $qconditionvar = new cc_assignment_conditionvar();
+            $qrespcondition->set_conditionvar($qconditionvar);
+            $qother = new cc_assignment_conditionvar_othertype();
+            $qconditionvar->set_other($qother);
+            $qdisplayfeedback = new cc_assignment_displayfeedbacktype();
+            $qrespcondition->add_displayfeedback($qdisplayfeedback);
+            $qdisplayfeedback->set_feedbacktype(cc_qti_values::Response);
+            $qdisplayfeedback->set_linkrefid('general_fb');
+        }
+    }
+}
+
diff --git a/backup/cc/cc_lib/cc_assesment_sfib.php b/backup/cc/cc_lib/cc_assesment_sfib.php
new file mode 100644 (file)
index 0000000..6a83ccc
--- /dev/null
@@ -0,0 +1,183 @@
+<?php
+// This file is part of Moodle - http://moodle.org/
+//
+// Moodle is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Moodle is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
+/**
+ * @package    backup-convert
+ * @copyright  2012 Darko Miletic <dmiletic@moodlerooms.com>
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+defined('MOODLE_INTERNAL') or die('Direct access to this script is forbidden.');
+
+require_once('cc_asssesment.php');
+
+class cc_assesment_question_sfib extends cc_assesment_question_proc_base {
+    public function __construct($quiz, $questions, $manifest, $section, $question_node, $rootpath, $contextid, $outdir) {
+        parent::__construct($quiz, $questions, $manifest, $section, $question_node, $rootpath, $contextid, $outdir);
+        $this->qtype = cc_qti_profiletype::field_entry;
+        $this->correct_answer_node_id = $this->questions->nodeValue(
+            'plugin_qtype_truefalse_question/truefalse/trueanswer',
+            $this->question_node
+        );
+        $maximum_quiz_grade = (int)$this->quiz->nodeValue('/activity/quiz/grade');
+        $this->total_grade_value = ($maximum_quiz_grade + 1).'.0000000';
+    }
+
+    public function on_generate_metadata() {
+        parent::on_generate_metadata();
+
+        $category = $this->questions->nodeValue('../../name', $this->question_node);
+        if (!empty($category)) {
+            $this->qmetadata->set_category($category);
+        }
+    }
+
+    public function on_generate_presentation() {
+        parent::on_generate_presentation();
+        $response_str = new cc_assesment_response_strtype();
+        $response_fib = new cc_assesment_render_fibtype();
+
+         // The standard requires that only rows attribute must be set,
+         // the rest may or may not be configured. For the sake of brevity we leave it empty.
+        $response_fib->set_rows(1);
+        $response_str->set_render_fib($response_fib);
+        $this->qpresentation->set_response_str($response_str);
+    }
+
+    public function on_generate_feedbacks() {
+        parent::on_generate_feedbacks();
+        // Question combined feedback.
+        $responsenodes = $this->questions->nodeList('plugin_qtype_shortanswer_question//answer', $this->question_node);
+        $count = 0;
+        foreach ($responsenodes as $respnode) {
+            $content = $this->questions->nodeValue('feedback', $respnode);
+            if (empty($content)) {
+                continue;
+            }
+
+            $correct = (int)$this->questions->nodeValue('fraction', $respnode) == 1;
+            $answerid = (int)$this->questions->nodeValue('@id', $respnode);
+
+            $result = cc_helpers::process_linked_files( $content,
+                                                        $this->manifest,
+                                                        $this->rootpath,
+                                                        $this->contextid,
+                                                        $this->outdir);
+            $ident = $correct ? 'correct' : 'incorrect';
+            $ident .= '_'.$count.'_fb';
+            cc_assesment_helper::add_feedback( $this->qitem,
+                                                $result[0],
+                                                cc_qti_values::htmltype,
+                                                $ident);
+
+            pkg_resource_dependencies::instance()->add($result[1]);
+
+            if ($correct) {
+                $this->correct_feedbacks[$answerid] = $ident;
+            } else {
+                $this->incorrect_feedbacks[$answerid] = $ident;
+            }
+
+            ++$count;
+        }
+    }
+
+    public function on_generate_response_processing() {
+        parent::on_generate_response_processing();
+
+        // General unconditional feedback must be added as a first respcondition
+        // without any condition and just displayfeedback (if exists).
+        if (!empty($this->general_feedback)) {
+            $qrespcondition = new cc_assesment_respconditiontype();
+            $qrespcondition->set_title('General feedback');
+            $this->qresprocessing->add_respcondition($qrespcondition);
+            $qrespcondition->enable_continue();
+            // Define the condition for success.
+            $qconditionvar = new cc_assignment_conditionvar();
+            $qrespcondition->set_conditionvar($qconditionvar);
+            $qother = new cc_assignment_conditionvar_othertype();
+            $qconditionvar->set_other($qother);
+            $qdisplayfeedback = new cc_assignment_displayfeedbacktype();
+            $qrespcondition->add_displayfeedback($qdisplayfeedback);
+            $qdisplayfeedback->set_feedbacktype(cc_qti_values::Response);
+            $qdisplayfeedback->set_linkrefid('general_fb');
+        }
+
+        // Answer separate conditions.
+        $correct_responses = $this->questions->nodeList(
+            'plugin_qtype_shortanswer_question//answer[fraction=1]', $this->question_node);
+        $incorrect_responses = $this->questions->nodeList(
+            'plugin_qtype_shortanswer_question//answer[fraction<1]', $this->question_node);
+        $items = array(
+            array($correct_responses, $this->correct_feedbacks),
+            array($incorrect_responses, $this->incorrect_feedbacks)
+        );
+        foreach ($items as $respfeed) {
+            foreach ($respfeed[0] as $coresponse) {
+                $qrespcondition = new cc_assesment_respconditiontype();
+                $qrespcondition->enable_continue();
+                $this->qresprocessing->add_respcondition($qrespcondition);
+                $qconditionvar = new cc_assignment_conditionvar();
+                $qrespcondition->set_conditionvar($qconditionvar);
+                $respc = $this->questions->nodeValue('answertext', $coresponse);
+                $resid = $this->questions->nodeValue('@id', $coresponse);
+                $qvarequal = new cc_assignment_conditionvar_varequaltype($respc);
+                $qconditionvar->set_varequal($qvarequal);
+                $qvarequal->set_respident('response');
+                $qvarequal->enable_case(false);
+                if (!empty($respfeed[1][$resid])) {
+                    $qdisplayfeedback = new cc_assignment_displayfeedbacktype();
+                    $qrespcondition->add_displayfeedback($qdisplayfeedback);
+                    $qdisplayfeedback->set_feedbacktype(cc_qti_values::Response);
+                    $qdisplayfeedback->set_linkrefid($respfeed[1][$resid]);
+                }
+            }
+        }
+        // Success condition.
+        // For all question types outside of the Essay question, scoring is done in a
+        // single <respcondition> with a continue flag set to No. The outcome is always
+        // a variable named SCORE which value must be set to 100 in case of correct answer.
+        // Partial scores (not 0 or 100) are not supported.
+        $qrespcondition = new cc_assesment_respconditiontype();
+        $qrespcondition->set_title('Correct');
+        $this->qresprocessing->add_respcondition($qrespcondition);
+        $qrespcondition->enable_continue(false);
+        $qsetvar = new cc_assignment_setvartype(100);
+        $qrespcondition->add_setvar($qsetvar);
+        // Define the condition for success.
+        $qconditionvar = new cc_assignment_conditionvar();
+        $qrespcondition->set_conditionvar($qconditionvar);
+
+        foreach ($correct_responses as $coresponse) {
+            $respc = $this->questions->nodeValue('answertext', $coresponse);
+            $qvarequal = new cc_assignment_conditionvar_varequaltype($respc);
+            $qconditionvar->set_varequal($qvarequal);
+            $qvarequal->set_respident('response');
+            $qvarequal->enable_case(false);
+        }
+
+        // Add incorrect handling.
+        $qrespcondition = new cc_assesment_respconditiontype();
+        $this->qresprocessing->add_respcondition($qrespcondition);
+        $qrespcondition->enable_continue(false);
+        // Define the condition for failure.
+        $qconditionvar = new cc_assignment_conditionvar();
+        $qrespcondition->set_conditionvar($qconditionvar);
+        $qother = new cc_assignment_conditionvar_othertype();
+        $qconditionvar->set_other($qother);
+        $qsetvar = new cc_assignment_setvartype(0);
+        $qrespcondition->add_setvar($qsetvar);
+    }
+}
diff --git a/backup/cc/cc_lib/cc_assesment_truefalse.php b/backup/cc/cc_lib/cc_assesment_truefalse.php
new file mode 100644 (file)
index 0000000..64d0e79
--- /dev/null
@@ -0,0 +1,173 @@
+<?php
+// This file is part of Moodle - http://moodle.org/
+//
+// Moodle is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Moodle is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
+/**
+ * @package    backup-convert
+ * @copyright  2012 Darko Miletic <dmiletic@moodlerooms.com>
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+defined('MOODLE_INTERNAL') or die('Direct access to this script is forbidden.');
+
+require_once('cc_asssesment.php');
+
+class cc_assesment_question_truefalse extends cc_assesment_question_proc_base {
+    public function __construct($quiz, $questions, $manifest, $section, $question_node, $rootpath, $contextid, $outdir) {
+        parent::__construct($quiz, $questions, $manifest, $section, $question_node, $rootpath, $contextid, $outdir);
+        $this->qtype = cc_qti_profiletype::true_false;
+        $this->correct_answer_node_id = $this->questions->nodeValue(
+            'plugin_qtype_truefalse_question/truefalse/trueanswer', $this->question_node);
+        $maximum_quiz_grade = (int)$this->quiz->nodeValue('/activity/quiz/grade');
+        $this->total_grade_value = ($maximum_quiz_grade + 1).'.0000000';
+    }
+
+    public function on_generate_answers() {
+        // Add responses holder.
+        $qresponse_lid = new cc_response_lidtype();
+        $this->qresponse_lid = $qresponse_lid;
+        $this->qpresentation->set_response_lid($qresponse_lid);
+        $qresponse_choice = new cc_assesment_render_choicetype();
+        $qresponse_lid->set_render_choice($qresponse_choice);
+        // Mark that question has only one correct answer -
+        // which applies for multiple choice and yes/no questions.
+        $qresponse_lid->set_rcardinality(cc_qti_values::Single);
+        // Are we to shuffle the responses?
+        $shuffle_answers = (int)$this->quiz->nodeValue('/activity/quiz/shuffleanswers') > 0;
+        $qresponse_choice->enable_shuffle($shuffle_answers);
+        $answerlist = array();
+        $qa_responses = $this->questions->nodeList('plugin_qtype_truefalse_question/answers/answer', $this->question_node);
+        foreach ($qa_responses as $node) {
+            $answer_content = $this->questions->nodeValue('answertext', $node);
+            $id = ((int)$this->questions->nodeValue('@id', $node) == $this->correct_answer_node_id);
+            $qresponse_label = cc_assesment_helper::add_answer( $qresponse_choice,
+                                                                $answer_content,
+                                                                cc_qti_values::htmltype);
+            $answer_ident = strtolower(trim($answer_content));
+            $qresponse_label->set_ident($answer_ident);
+            $feedback_ident = ($id) ? 'correct_fb' : 'incorrect_fb';
+            if (empty($this->correct_answer_ident) && $id) {
+                $this->correct_answer_ident = $answer_ident;
+            }
+            // Add answer specific feedback if not empty.
+            $content = $this->questions->nodeValue('feedback', $node);
+            if (!empty($content)) {
+                $result = cc_helpers::process_linked_files( $content,
+                                                            $this->manifest,
+                                                            $this->rootpath,
+                                                            $this->contextid,
+                                                            $this->outdir);
+
+
+                cc_assesment_helper::add_feedback( $this->qitem,
+                                                    $result[0],
+                                                    cc_qti_values::htmltype,
+                                                    $feedback_ident);
+
+                pkg_resource_dependencies::instance()->add($result[1]);
+
+                $answerlist[$answer_ident] = $feedback_ident;
+            }
+        }
+
+        $this->answerlist = $answerlist;
+
+    }
+
+    public function on_generate_response_processing() {
+        parent::on_generate_response_processing();
+
+        // Response conditions.
+        // General unconditional feedback must be added as a first respcondition
+        // without any condition and just displayfeedback (if exists).
+        if (!empty($this->general_feedback)) {
+            $qrespcondition = new cc_assesment_respconditiontype();
+            $qrespcondition->set_title('General feedback');
+            $this->qresprocessing->add_respcondition($qrespcondition);
+            $qrespcondition->enable_continue();
+            // Define the condition for success.
+            $qconditionvar = new cc_assignment_conditionvar();
+            $qrespcondition->set_conditionvar($qconditionvar);
+            $qother = new cc_assignment_conditionvar_othertype();
+            $qconditionvar->set_other($qother);
+            $qdisplayfeedback = new cc_assignment_displayfeedbacktype();
+            $qrespcondition->add_displayfeedback($qdisplayfeedback);
+            $qdisplayfeedback->set_feedbacktype(cc_qti_values::Response);
+            $qdisplayfeedback->set_linkrefid('general_fb');
+        }
+
+        // Success condition.
+        // For all question types outside of the Essay question, scoring is done in a
+        // single <respcondition> with a continue flag set to No. The outcome is always
+        // a variable named SCORE which value must be set to 100 in case of correct answer.
+        // Partial scores (not 0 or 100) are not supported.
+        $qrespcondition = new cc_assesment_respconditiontype();
+        $qrespcondition->set_title('Correct');
+        $this->qresprocessing->add_respcondition($qrespcondition);
+        $qrespcondition->enable_continue(false);
+        $qsetvar = new cc_assignment_setvartype(100);
+        $qrespcondition->add_setvar($qsetvar);
+        // Define the condition for success.
+        $qconditionvar = new cc_assignment_conditionvar();
+        $qrespcondition->set_conditionvar($qconditionvar);
+        // TODO: recheck this.
+        $qvarequal = new cc_assignment_conditionvar_varequaltype($this->correct_answer_ident);
+        $qconditionvar->set_varequal($qvarequal);
+        $qvarequal->set_respident($this->qresponse_lid->get_ident());
+
+        if (array_key_exists($this->correct_answer_ident, $this->answerlist)) {
+            $qdisplayfeedback = new cc_assignment_displayfeedbacktype();
+            $qrespcondition->add_displayfeedback($qdisplayfeedback);
+            $qdisplayfeedback->set_feedbacktype(cc_qti_values::Response);
+            $qdisplayfeedback->set_linkrefid($this->answerlist[$this->correct_answer_ident]);
+        }
+
+        foreach ($this->correct_feedbacks as $ident) {
+            $qdisplayfeedback = new cc_assignment_displayfeedbacktype();
+            $qrespcondition->add_displayfeedback($qdisplayfeedback);
+            $qdisplayfeedback->set_feedbacktype(cc_qti_values::Response);
+            $qdisplayfeedback->set_linkrefid($ident);
+        }
+
+        // Rest of the conditions.
+        foreach ($this->answerlist as $ident => $refid) {
+            if ($ident == $this->correct_answer_ident) {
+                continue;
+            }
+
+            $qrespcondition = new cc_assesment_respconditiontype();
+            $this->qresprocessing->add_respcondition($qrespcondition);
+            $qsetvar = new cc_assignment_setvartype(0);
+            $qrespcondition->add_setvar($qsetvar);
+            // Define the condition for fail.
+            $qconditionvar = new cc_assignment_conditionvar();
+            $qrespcondition->set_conditionvar($qconditionvar);
+            $qvarequal = new cc_assignment_conditionvar_varequaltype($ident);
+            $qconditionvar->set_varequal($qvarequal);
+            $qvarequal->set_respident($this->qresponse_lid->get_ident());
+
+            $qdisplayfeedback = new cc_assignment_displayfeedbacktype();
+            $qrespcondition->add_displayfeedback($qdisplayfeedback);
+            $qdisplayfeedback->set_feedbacktype(cc_qti_values::Response);
+            $qdisplayfeedback->set_linkrefid($refid);
+
+            foreach ($this->incorrect_feedbacks as $ident) {
+                $qdisplayfeedback = new cc_assignment_displayfeedbacktype();
+                $qrespcondition->add_displayfeedback($qdisplayfeedback);
+                $qdisplayfeedback->set_feedbacktype(cc_qti_values::Response);
+                $qdisplayfeedback->set_linkrefid($ident);
+            }
+        }
+    }
+}
index 3e3af90..bbc5650 100644 (file)
 
 defined('MOODLE_INTERNAL') or die('Direct access to this script is forbidden.');
 
-require_once 'cc_utils.php';
-require_once 'cc_general.php';
+require_once('cc_utils.php');
+require_once('cc_general.php');
 
 abstract class cc_xml_namespace {
     const xml = 'http://www.w3.org/XML/1998/namespace';
 }
 
 abstract class cc_qti_metadata {
-    //assesment
+    // Assessment.
     const qmd_assessmenttype       = 'qmd_assessmenttype';
     const qmd_scoretype            = 'qmd_scoretype';
     const qmd_feedbackpermitted    = 'qmd_feedbackpermitted';
@@ -40,7 +40,7 @@ abstract class cc_qti_metadata {
     const cc_maxattempts           = 'cc_maxattempts';
     const cc_profile               = 'cc_profile';
 
-    //item
+    // Items.
     const cc_weighting         = 'cc_weighting';
     const qmd_scoringpermitted = 'qmd_scoringpermitted';
     const qmd_computerscored   = 'qmd_computerscored';
@@ -698,26 +698,30 @@ class cc_assignment_conditionvar_varsubstringtype extends cc_assignment_conditio
 
 
 class cc_assignment_conditionvar_andtype extends cc_question_metadata_base {
-    protected $not = null;
-    protected $varequal = null;
+    protected $nots = array();
+    protected $varequals = array();
 
     public function set_not(cc_assignment_conditionvar_varequaltype $object) {
-        $this->not = $object;
+        $this->nots[] = $object;
     }
 
     public function set_varequal(cc_assignment_conditionvar_varequaltype $object) {
-        $this->varequal = $object;
+        $this->varequals[] = $object;
     }
 
     public function generate(XMLGenericDocument &$doc, DOMNode &$item, $namespace) {
         $node = $doc->append_new_element_ns($item, $namespace, cc_qti_tags::and_);
-        if (!empty($this->not)) {
-            $not = $doc->append_new_element_ns($node, $namespace, cc_qti_tags::not_);
-            $this->not->generate($doc, $not, $namespace);
+        if (!empty($this->nots)) {
+            foreach ($this->nots as $notv) {
+                $not = $doc->append_new_element_ns($node, $namespace, cc_qti_tags::not_);
+                $notv->generate($doc, $not, $namespace);
+            }
         }
 
-        if (!empty($this->varequal)) {
-            $this->varequal->generate($doc, $node, $namespace);
+        if (!empty($this->varequals)) {
+            foreach ($this->varequals as $varequal) {
+                $varequal->generate($doc, $node, $namespace);
+            }
         }
     }
 }
@@ -733,9 +737,9 @@ class cc_assignment_conditionvar extends cc_question_metadata_base {
      */
     protected $other = null;
     /**
-     * @var cc_assignment_conditionvar_varequaltype
+     * @var array
      */
-    protected $varequal = null;
+    protected $varequal = array();
     /**
      * @var cc_assignment_conditionvar_varsubstringtype
      */
@@ -750,7 +754,7 @@ class cc_assignment_conditionvar extends cc_question_metadata_base {
     }
 
     public function set_varequal(cc_assignment_conditionvar_varequaltype $object) {
-        $this->varequal = $object;
+        $this->varequal[] = $object;
     }
 
     public function set_varsubstring(cc_assignment_conditionvar_varsubstringtype $object) {
@@ -769,7 +773,9 @@ class cc_assignment_conditionvar extends cc_question_metadata_base {
         }
 
         if (!empty($this->varequal)) {
-            $this->varequal->generate($doc, $node, $namespace);
+            foreach ($this->varequal as $varequal) {
+                $varequal->generate($doc, $node, $namespace);
+            }
         }
 
         if (!empty($this->varsubstring)) {
@@ -1895,8 +1901,20 @@ abstract class cc_assesment_helper {
         return $qresponse_label;
     }
 
-    public static function add_response_condition() {
-
+    public static function add_response_condition($node, $title, $ident, $feedback_refid, $respident) {
+        $qrespcondition = new cc_assesment_respconditiontype();
+        $node->add_respcondition($qrespcondition);
+        //define rest of the conditions
+        $qconditionvar = new cc_assignment_conditionvar();
+        $qrespcondition->set_conditionvar($qconditionvar);
+        $qvarequal = new cc_assignment_conditionvar_varequaltype($ident);
+        $qvarequal->enable_case();
+        $qconditionvar->set_varequal($qvarequal);
+        $qvarequal->set_respident($respident);
+        $qdisplayfeedback = new cc_assignment_displayfeedbacktype();
+        $qrespcondition->add_displayfeedback($qdisplayfeedback);
+        $qdisplayfeedback->set_feedbacktype(cc_qti_values::Response);
+        $qdisplayfeedback->set_linkrefid($feedback_refid);
     }
 
     public static function add_assesment_description($rt, $content, $contenttype) {
@@ -1913,10 +1931,31 @@ abstract class cc_assesment_helper {
         $rt->set_rubric($activity_rubric);
     }
 
+    public static function add_respcondition($node, $title, $feedback_refid, $grade_value = null, $continue = false ) {
+        $qrespcondition = new cc_assesment_respconditiontype();
+        $qrespcondition->set_title($title);
+        $node->add_respcondition($qrespcondition);
+        $qrespcondition->enable_continue($continue);
+        //Add setvar if grade present
+        if ($grade_value !== null) {
+            $qsetvar = new cc_assignment_setvartype($grade_value);
+            $qrespcondition->add_setvar($qsetvar);
+        }
+        //define the condition for success
+        $qconditionvar = new cc_assignment_conditionvar();
+        $qrespcondition->set_conditionvar($qconditionvar);
+        $qother = new cc_assignment_conditionvar_othertype();
+        $qconditionvar->set_other($qother);
+        $qdisplayfeedback = new cc_assignment_displayfeedbacktype();
+        $qrespcondition->add_displayfeedback($qdisplayfeedback);
+        $qdisplayfeedback->set_feedbacktype(cc_qti_values::Response);
+        $qdisplayfeedback->set_linkrefid($feedback_refid);
+    }
+
     /**
      *
      * Enter description here ...
-     * @param unknown_type $qdoc
+     * @param XMLGenericDocument $qdoc
      * @param unknown_type $manifest
      * @param cc_assesment_section $section
      * @param unknown_type $rootpath
@@ -1932,9 +1971,12 @@ abstract class cc_assesment_helper {
         }
 
         pkg_resource_dependencies::instance()->reset();
-
-        $qids = explode(',', $qdoc->nodeValue('/activity/quiz/questions'));
-        foreach ($qids as $value) {
+        $questioncount = 0;
+        $questionforexport = 0;
+        $qids = $qdoc->nodeList('//question_instances//questionid');
+        foreach ($qids as $qid) {
+            /** @var DOMNode $qid */
+            $value = $qid->nodeValue;
             if (intval($value) == 0) {
                 continue;
             }
@@ -1942,6 +1984,7 @@ abstract class cc_assesment_helper {
             if (empty($question_node)) {
                 continue;
             }
+            ++$questionforexport;
             //process question
             //question type
             $qtype = $questions->nodeValue('qtype', $question_node);
@@ -1949,15 +1992,43 @@ abstract class cc_assesment_helper {
             switch ($qtype) {
                 case 'multichoice':
                     $single_correct_answer = (int)$questions->nodeValue('plugin_qtype_multichoice_question/multichoice/single', $question_node) > 0;
+                    //TODO: Add checking for the nunmber of valid responses
+                    //If question is marked as multi response but contains only one valid answer it
+                    //should be handle as single response - classic multichoice
                     if ($single_correct_answer) {
                         $question_processor = new cc_assesment_question_multichoice($qdoc, $questions, $manifest, $section, $question_node, $rootpath, $contextid, $outdir);
-                        $question_processor->generate();
                     } else {
-                        //TODO: implement
+                        $question_processor = new cc_assesment_question_multichoice_multiresponse($qdoc, $questions, $manifest, $section, $question_node, $rootpath, $contextid, $outdir);
+                    }
+                    $question_processor->generate();
+                    ++$questioncount;
+                break;
+                case 'truefalse':
+                    $question_processor = new cc_assesment_question_truefalse($qdoc, $questions, $manifest, $section, $question_node, $rootpath, $contextid, $outdir);
+                    $question_processor->generate();
+                    ++$questioncount;
+                break;
+                case 'essay':
+                    $question_processor = new cc_assesment_question_essay($qdoc, $questions, $manifest, $section, $question_node, $rootpath, $contextid, $outdir);
+                    $question_processor->generate();
+                    ++$questioncount;
+                break;
+                case 'shortanswer':
+                    //This is rather ambiguos since shortanswer supports partial pattern match
+                    //In order to detect pattern match we need to scan for all the responses
+                    //if at least one of the responses uses wildcards it should be treated as
+                    //pattern match, otherwise it should be simple fill in the blank
+                    if (self::has_matching_element($questions, $question_node)) {
+                        //$question_processor = new cc_assesment_question_patternmatch($qdoc, $questions, $manifest, $section, $question_node, $rootpath, $contextid, $outdir);
+                        $questionforexport--;
+                    } else {
+                        $question_processor = new cc_assesment_question_sfib($qdoc, $questions, $manifest, $section, $question_node, $rootpath, $contextid, $outdir);
+                    }
+                    if (!empty($question_processor)) {
+                        $question_processor->generate();
+                        ++$questioncount;
                     }
-                ;
                 break;
-
                 default:
                     ;
                 break;
@@ -1966,7 +2037,28 @@ abstract class cc_assesment_helper {
         }
 
         //return dependencies
-        return pkg_resource_dependencies::instance()->get_deps();
+        return ($questioncount == 0) || ($questioncount != $questionforexport)?
+               false: pkg_resource_dependencies::instance()->get_deps();
+    }
+
+    /**
+     *
+     * Checks if question has matching element
+     * @param XMLGenericDocument $questions
+     * @param object $question_node
+     * @return bool
+     */
+    public static function has_matching_element(XMLGenericDocument $questions, $question_node) {
+        $answers = $questions->nodeList('plugin_qtype_shortanswer_question//answertext', $question_node);
+        $result = false;
+        foreach ($answers as $answer) {
+            $prepare = str_replace('\*', '\#', $answer->nodeValue);
+            $result = (strpos($prepare, '*') !== false);
+            if ($result) {
+                break;
+            }
+        }
+        return $result;
     }
 
 }
@@ -2085,6 +2177,11 @@ class cc_assesment_question_proc_base {
             if ($weighting_value > 1) {
                 $this->qmetadata->set_weighting($weighting_value);
             }
+            //Get category
+            $question_category = $this->questions->nodeValue('../../name', $this->question_node);
+            if (!empty($question_category)) {
+                $this->qmetadata->set_category($question_category);
+            }
             $rts = new cc_assesment_itemmetadata();
             $rts->add_metadata($this->qmetadata);
             $this->qitem->set_itemmetadata($rts);
@@ -2169,14 +2266,14 @@ class cc_assesment_question_multichoice extends cc_assesment_question_proc_base
         $this->qtype = cc_qti_profiletype::multiple_choice;
 
         /**
-        *
-        * What is needed is a maximum grade value taken from the answer fraction
-        * It is supposed to always be between 1 and 0 in decimal representation,
-        * however that is not always the case so a change in test was needed
-        * but since we support here one correct answer type
-        * correct answer would always have to be 1
-        */
-        $correct_answer_node = $this->questions->node("plugin_qtype_multichoice_question/answers/answer[fraction!=0.0000000]", $this->question_node);
+         *
+         * What is needed is a maximum grade value taken from the answer fraction
+         * It is supposed to always be between 1 and 0 in decimal representation,
+         * however that is not always the case so a change in test was needed
+         * but since we support here one correct answer type
+         * correct answer would always have to be 1
+         */
+        $correct_answer_node = $this->questions->node("plugin_qtype_multichoice_question/answers/answer[fraction > 0]", $this->question_node);
         if (empty($correct_answer_node)) {
             throw new RuntimeException('No correct answer!');
         }
@@ -2362,3 +2459,193 @@ class cc_assesment_question_multichoice extends cc_assesment_question_proc_base
         }
     }
 }
+
+class cc_assesment_question_multichoice_multiresponse extends cc_assesment_question_proc_base {
+    /**
+     * @var DOMNodeList
+     */
+    protected $correct_answers = null;
+
+    public function __construct($quiz, $questions, $manifest, $section, $question_node, $rootpath, $contextid, $outdir) {
+        parent::__construct($quiz, $questions, $manifest, $section, $question_node, $rootpath, $contextid, $outdir);
+        $this->qtype = cc_qti_profiletype::multiple_response;
+
+        $correct_answer_nodes = $this->questions->nodeList("plugin_qtype_multichoice_question/answers/answer[fraction > 0]", $this->question_node);
+        if ($correct_answer_nodes->length == 0) {
+            throw new RuntimeException('No correct answer!');
+        }
+        $this->correct_answers = $correct_answer_nodes;
+        //$this->correct_answer_node_id = $this->questions->nodeValue('@id', $correct_answer_node);
+        $maximum_quiz_grade = (int)$this->quiz->nodeValue('/activity/quiz/grade');
+        $this->total_grade_value = ($maximum_quiz_grade + 1).'.0000000';
+    }
+
+    public function on_generate_answers() {
+        //add responses holder
+        $qresponse_lid = new cc_response_lidtype();
+        $this->qresponse_lid = $qresponse_lid;
+        $this->qpresentation->set_response_lid($qresponse_lid);
+        $qresponse_choice = new cc_assesment_render_choicetype();
+        $qresponse_lid->set_render_choice($qresponse_choice);
+        //Mark that question has more than one correct answer
+        $qresponse_lid->set_rcardinality(cc_qti_values::Multiple);
+        //are we to shuffle the responses?
+        $shuffle_answers = (int)$this->quiz->nodeValue('/activity/quiz/shuffleanswers') > 0;
+        $qresponse_choice->enable_shuffle($shuffle_answers);
+        $answerlist = array();
+        $qa_responses = $this->questions->nodeList('plugin_qtype_multichoice_question/answers/answer', $this->question_node);
+        foreach ($qa_responses as $node) {
+            $answer_content = $this->questions->nodeValue('answertext', $node);
+            $answer_grade_fraction = (float)$this->questions->nodeValue('fraction', $node);
+            $result = cc_helpers::process_linked_files( $answer_content,
+                                                        $this->manifest,
+                                                        $this->rootpath,
+                                                        $this->contextid,
+                                                        $this->outdir);
+            $qresponse_label = cc_assesment_helper::add_answer( $qresponse_choice,
+                                                                $result[0],
+                                                                cc_qti_values::htmltype);
+            pkg_resource_dependencies::instance()->add($result[1]);
+            $answer_ident = $qresponse_label->get_ident();
+            $feedback_ident = $answer_ident.'_fb';
+            //add answer specific feedbacks if not empty
+            $content = $this->questions->nodeValue('feedback', $node);
+            if (!empty($content)) {
+                $result = cc_helpers::process_linked_files( $content,
+                                                            $this->manifest,
+                                                            $this->rootpath,
+                                                            $this->contextid,
+                                                            $this->outdir);
+
+
+                cc_assesment_helper::add_feedback( $this->qitem,
+                                                    $result[0],
+                                                    cc_qti_values::htmltype,
+                                                    $feedback_ident);
+
+                pkg_resource_dependencies::instance()->add($result[1]);
+
+            }
+            $answerlist[$answer_ident] = array($feedback_ident, ($answer_grade_fraction > 0));
+        }
+
+        $this->answerlist = $answerlist;
+
+    }
+
+    public function on_generate_feedbacks() {
+        parent::on_generate_feedbacks();
+        //Question combined feedbacks
+        $correct_question_fb = $this->questions->nodeValue('plugin_qtype_multichoice_question/multichoice/correctfeedback', $this->question_node);
+        $incorrect_question_fb = $this->questions->nodeValue('plugin_qtype_multichoice_question/multichoice/incorrectfeedback', $this->question_node);
+        if (empty($correct_question_fb)) {
+            //Hardcode some text for now
+            $correct_question_fb = 'Well done!';
+        }
+        if (empty($incorrect_question_fb)) {
+            //Hardcode some text for now
+            $incorrect_question_fb = 'Better luck next time!';
+        }
+
+        $proc = array('correct_fb' => $correct_question_fb, 'incorrect_fb' => $incorrect_question_fb);
+        foreach ($proc as $ident => $content) {
+            if (empty($content)) {
+                continue;
+            }
+            $result = cc_helpers::process_linked_files( $content,
+                                                        $this->manifest,
+                                                        $this->rootpath,
+                                                        $this->contextid,
+                                                        $this->outdir);
+
+            cc_assesment_helper::add_feedback( $this->qitem,
+                                                $result[0],
+                                                cc_qti_values::htmltype,
+                                                $ident);
+
+            pkg_resource_dependencies::instance()->add($result[1]);
+            if ($ident == 'correct_fb') {
+                $this->correct_feedbacks[$ident] = $ident;
+            } else {
+                $this->incorrect_feedbacks[$ident] = $ident;
+            }
+        }
+
+    }
+
+    public function on_generate_response_processing() {
+        parent::on_generate_response_processing();
+
+        //respconditions
+        /**
+        * General unconditional feedback must be added as a first respcondition
+        * without any condition and just displayfeedback (if exists)
+        */
+        cc_assesment_helper::add_respcondition( $this->qresprocessing,
+                                                'General feedback',
+                                                $this->general_feedback,
+                                                null,
+                                                true
+                                               );
+
+        //success condition
+        /**
+        * For all question types outside of the Essay question, scoring is done in a
+        * single <respcondition> with a continue flag set to No. The outcome is always
+        * a variable named SCORE which value must be set to 100 in case of correct answer.
+        * Partial scores (not 0 or 100) are not supported.
+        */
+        $qrespcondition = new cc_assesment_respconditiontype();
+        $qrespcondition->set_title('Correct');
+        $this->qresprocessing->add_respcondition($qrespcondition);
+        $qrespcondition->enable_continue(false);
+        $qsetvar = new cc_assignment_setvartype(100);
+        $qrespcondition->add_setvar($qsetvar);
+        //define the condition for success
+        $qconditionvar = new cc_assignment_conditionvar();
+        $qrespcondition->set_conditionvar($qconditionvar);
+        //create root and condition
+        $qandcondition = new cc_assignment_conditionvar_andtype();
+        $qconditionvar->set_and($qandcondition);
+        foreach ($this->answerlist as $ident => $refid) {
+            $qvarequal = new cc_assignment_conditionvar_varequaltype($ident);
+            $qvarequal->enable_case();
+            if ($refid[1]) {
+                $qandcondition->set_varequal($qvarequal);
+            } else {
+                $qandcondition->set_not($qvarequal);
+            }
+            $qvarequal->set_respident($this->qresponse_lid->get_ident());
+        }
+
+        $qdisplayfeedback = new cc_assignment_displayfeedbacktype();
+        $qrespcondition->add_displayfeedback($qdisplayfeedback);
+        $qdisplayfeedback->set_feedbacktype(cc_qti_values::Response);
+        //TODO: this needs to be fixed
+        reset($this->correct_feedbacks);
+        $ident = key($this->correct_feedbacks);
+        $qdisplayfeedback->set_linkrefid($ident);
+
+
+        //rest of the conditions
+        foreach ($this->answerlist as $ident => $refid) {
+            cc_assesment_helper::add_response_condition( $this->qresprocessing,
+                                                         'Incorrect feedback',
+                                                         $refid[0],
+                                                         $this->general_feedback,
+                                                         $this->qresponse_lid->get_ident()
+                                                       );
+        }
+
+        //Final element for incorrect feedback
+        reset($this->incorrect_feedbacks);
+        $ident = key($this->incorrect_feedbacks);
+        cc_assesment_helper::add_respcondition( $this->qresprocessing,
+                                                'Incorrect feedback',
+                                                $ident,
+                                                0
+                                              );
+
+    }
+
+}
diff --git a/backup/cc/cc_lib/cc_converter_folder.php b/backup/cc/cc_lib/cc_converter_folder.php
new file mode 100644 (file)
index 0000000..bbdeeb1
--- /dev/null
@@ -0,0 +1,48 @@
+<?php
+// This file is part of Moodle - http://moodle.org/
+//
+// Moodle is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Moodle is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
+/**
+ * @package    backup-convert
+ * @subpackage cc-library
+ * @copyright  2012 Darko Miletic <dmiletic@moodlerooms.com>
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+require_once('cc_converters.php');
+require_once('cc_general.php');
+
+class cc_converter_folder extends cc_converter {
+
+    public function __construct(cc_i_item &$item, cc_i_manifest &$manifest, $rootpath, $path) {
+        $this->defaultfile = 'folder.xml';
+        parent::__construct($item, $manifest, $rootpath, $path);
+    }
+
+    public function convert($outdir) {
+        $resitem = new cc_item();
+        $resitem->title = $this->doc->nodeValue('/activity/folder/name');
+        $this->item->add_child_item($resitem);
+
+        $contextid = $this->doc->nodeValue('/activity/@contextid');
+        cc_helpers::handle_static_content($this->manifest,
+                                          $this->rootpath,
+                                          $contextid,
+                                          $outdir);
+
+        return true;
+    }
+
+}
+
index 343f3a4..daf32bb 100644 (file)
@@ -1,12 +1,36 @@
 <?php
+// This file is part of Moodle - http://moodle.org/
+//
+// Moodle is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Moodle is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
 
-require_once 'cc_converters.php';
-require_once 'cc_general.php';
-require_once 'cc_asssesment.php';
+/**
+ * @package    backup-convert
+ * @subpackage cc-library
+ * @copyright  2012 Darko Miletic <dmiletic@moodlerooms.com>
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+require_once('cc_converters.php');
+require_once('cc_general.php');
+require_once('cc_asssesment.php');
+require_once('cc_assesment_truefalse.php');
+require_once('cc_assesment_essay.php');
+require_once('cc_assesment_sfib.php');
 
 class cc_converter_quiz extends cc_converter {
 
-    public function __construct(cc_i_item &$item, cc_i_manifest &$manifest, $rootpath, $path){
+    public function __construct(cc_i_item &$item, cc_i_manifest &$manifest, $rootpath, $path) {
         $this->cc_type     = cc_version11::assessment;
         $this->defaultfile = 'quiz.xml';
         $this->defaultname = assesment11_resurce_file::deafultname;
@@ -18,23 +42,23 @@ class cc_converter_quiz extends cc_converter {
         $title = $this->doc->nodeValue('/activity/quiz/name');
         $rt->set_title($title);
 
-        //metadata
+        // Metadata.
         $metadata = new cc_assesment_metadata();
         $rt->set_metadata($metadata);
         $metadata->enable_feedback();
         $metadata->enable_hints();
         $metadata->enable_solutions();
-        //attempts
+        // Attempts.
         $max_attempts = (int)$this->doc->nodeValue('/activity/quiz/attempts_number');
         if ($max_attempts > 0) {
-            //qti does not support number of specific attempts bigger than 5 (??)
+            // Qti does not support number of specific attempts bigger than 5 (??)
             if ($max_attempts > 5) {
                 $max_attempts = cc_qti_values::unlimited;
             }
             $metadata->set_maxattempts($max_attempts);
         }
-        //timelimit must be converted into minutes
-        $timelimit = (int)floor((int)$this->doc->nodeValue('/activity/quiz/timelimit')/60);
+        // Time limit must be converted into minutes.
+        $timelimit = (int)floor((int)$this->doc->nodeValue('/activity/quiz/timelimit') / 60);
         if ($timelimit > 0) {
             $metadata->set_timelimit($timelimit);
             $metadata->enable_latesubmissions(false);
@@ -48,21 +72,26 @@ class cc_converter_quiz extends cc_converter {
                                                     $outdir);
         cc_assesment_helper::add_assesment_description($rt, $result[0], cc_qti_values::htmltype);
 
-        //section
+        // Section.
         $section = new cc_assesment_section();
         $rt->set_section($section);
 
-        //Process the actual questions
+        // Process the actual questions.
         $ndeps = cc_assesment_helper::process_questions($this->doc,
                                                         $this->manifest,
                                                         $section,
                                                         $this->rootpath,
                                                         $contextid,
                                                         $outdir);
-        //store any additional dependencies
+        if ($ndeps === false) {
+            // No exportable questions in quiz or quiz has no questions
+            // so just skip it.
+            return true;
+        }
+        // Store any additional dependencies.
         $deps = array_merge($result[1], $ndeps);
 
-        //store everything
+        // Store everything.
         $this->store($rt, $outdir, $title, $deps);
         return true;
     }
index 6293c95..cbbc706 100644 (file)
 // You should have received a copy of the GNU General Public License
 // along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
 /**
-* @package    backup-convert
-* @subpackage cc-library
-* @copyright  2011 Darko Miletic <dmiletic@moodlerooms.com>
-* @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
-*/
+ * @package    backup-convert
+ * @subpackage cc-library
+ * @copyright  2011 Darko Miletic <dmiletic@moodlerooms.com>
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
 
-require_once 'cc_converters.php';
-require_once 'cc_general.php';
+require_once('cc_converters.php');
+require_once('cc_general.php');
 
 class cc_converter_resource extends cc_converter {
 
-    public function __construct(cc_i_item &$item, cc_i_manifest &$manifest, $rootpath, $path){
+    public function __construct(cc_i_item &$item, cc_i_manifest &$manifest, $rootpath, $path) {
         $this->cc_type     = cc_version11::webcontent;
         $this->defaultfile = 'resource.xml';
         parent::__construct($item, $manifest, $rootpath, $path);
@@ -40,7 +40,7 @@ class cc_converter_resource extends cc_converter {
                                                    $outdir);
         $deps = null;
         $resvalue = null;
-        foreach ($files as $vfile => $values) {
+        foreach ($files as $values) {
             if ($values[2]) {
                 $resvalue = $values[0];
                 break;
@@ -52,6 +52,9 @@ class cc_converter_resource extends cc_converter {
         $resitem->title = $title;
         $this->item->add_child_item($resitem);
 
+        // Checking the visibility.
+        $this->manifest->update_instructoronly($resvalue, !$this->is_visible());
+
         return true;
     }
 
index 26e6d37..2584bbb 100644 (file)
 // You should have received a copy of the GNU General Public License
 // along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
 /**
-* @package    backup-convert
-* @subpackage cc-library
-* @copyright  2011 Darko Miletic <dmiletic@moodlerooms.com>
-* @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
-*/
+ * @package    backup-convert
+ * @subpackage cc-library
+ * @copyright  2011 Darko Miletic <dmiletic@moodlerooms.com>
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
 
-require_once 'cc_interfaces.php';
+require_once('cc_interfaces.php');
 
 abstract class cc_converter {
     /**
@@ -81,7 +81,7 @@ abstract class cc_converter {
      * @param  string $path
      * @throws InvalidArgumentException
      */
-    public function __construct(cc_i_item &$item, cc_i_manifest &$manifest, $rootpath, $path){
+    public function __construct(cc_i_item &$item, cc_i_manifest &$manifest, $rootpath, $path) {
         $rpath = realpath($rootpath);
         if (empty($rpath)) {
             throw new InvalidArgumentException('Invalid path!');
@@ -110,6 +110,21 @@ abstract class cc_converter {
      */
     abstract public function convert($outdir);
 
+    /**
+     *
+     * Is the element visible in the course?
+     * @throws RuntimeException
+     * @return bool
+     */
+    protected function is_visible() {
+        $tdoc = new XMLGenericDocument();
+        if (!$tdoc->load($this->path . DIRECTORY_SEPARATOR . 'module.xml')) {
+            throw new RuntimeException('File does not exist!');
+        }
+        $visible = (int)$tdoc->nodeValue('/module/visible');
+        return ($visible > 0);
+    }
+
     /**
      *
      * Stores any files that need to be stored
@@ -120,6 +135,7 @@ abstract class cc_converter {
         if ( $doc->saveTo($rtp) ) {
             $resource = new cc_resource($rdir->rootdir(), $this->defaultname, $rdir->dirname(true));
             $resource->dependency = empty($deps) ? array() : $deps;
+            $resource->instructoronly = !$this->is_visible();
             $res = $this->manifest->add_resource($resource, null, $this->cc_type);
             $resitem = new cc_item();
             $resitem->attach_resource($res[0]);
index 01dbb1f..ba426ee 100644 (file)
 // You should have received a copy of the GNU General Public License
 // along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
 /**
-* Manifest management
-*
-* @package    backup-convert
-* @subpackage cc-library
-* @copyright  2011 Darko Miletic <dmiletic@moodlerooms.com>
-* @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
-*/
-
-
-require_once 'cc_utils.php';
-require_once 'xmlbase.php';
-require_once 'cc_resources.php';
-require_once 'cc_version_base.php';
-require_once 'gral_lib/pathutils.php';
+ * Manifest management
+ *
+ * @package    backup-convert
+ * @subpackage cc-library
+ * @copyright  2011 Darko Miletic <dmiletic@moodlerooms.com>
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
 
+require_once('cc_utils.php');
+require_once('xmlbase.php');
+require_once('cc_resources.php');
+require_once('cc_version_base.php');
+require_once('gral_lib/pathutils.php');
 
 /**
  * Manifest Class
@@ -44,16 +42,15 @@ class cc_manifest extends XMLGenericDocument implements cc_i_manifest {
     private $ares                   = array();
     private $mainidentifier         = null;
 
-    public function __construct($ccver = cc_version::v1,$activemanifest=null,
-                        $parentmanifest=null,$parentparentmanifest=null) {
+    public function __construct($ccver = cc_version::v1, $activemanifest=null,
+                        $parentmanifest=null, $parentparentmanifest=null) {
 
-        if (is_int($ccver)){
+        if (is_int($ccver)) {
             $this->ccversion=$ccver;
             $classname = "cc_version{$ccver}";
             $this->ccobj = new $classname;
-            parent::__construct('UTF-8',true);
-        } else
-        if (is_object($ccver) && (get_class($ccver)=='cc_manifest')){
+            parent::__construct('UTF-8', true);
+        } else if (is_object($ccver) && (get_class($ccver)=='cc_manifest')) {
             $this->doc = $ccver->doc;
             $this->rootmanifest = $ccver->rootmanifest;
             $this->activemanifest = $activemanifest;
@@ -65,19 +62,14 @@ class cc_manifest extends XMLGenericDocument implements cc_i_manifest {
         }
     }
 
-    public function __destruct() {
-        parent::__destruct();
-    }
-
-
     /**
      * Register Namespace for use XPATH
      *
      */
-    public function register_namespaces_for_xpath(){
+    public function register_namespaces_for_xpath() {
         $scnam = $this->activemanifest->get_cc_namespaces();
-        foreach ($scnam as $key => $value){
-            $this->registerNS($key,$value);
+        foreach ($scnam as $key => $value) {
+            $this->registerNS($key, $value);
         }
     }
 
@@ -94,11 +86,11 @@ class cc_manifest extends XMLGenericDocument implements cc_i_manifest {
      *
      * @param cc_i_metadata_manifest $met
      */
-    public function add_metadata_manifest (cc_i_metadata_manifest $met){
+    public function add_metadata_manifest(cc_i_metadata_manifest $met) {
         $metanode = $this->node("//imscc:manifest[@identifier='".
                                 $this->activemanifest->manifestID().
                                 "']/imscc:metadata");
-        $nmeta = $this->activemanifest->create_metadata_node($met,$this->doc,$metanode);
+        $nmeta = $this->activemanifest->create_metadata_node($met, $this->doc, $metanode);
         $metanode->appendChild($nmeta);
     }
 
@@ -109,20 +101,18 @@ class cc_manifest extends XMLGenericDocument implements cc_i_manifest {
      * @param cc_i_metadata_resource $met
      * @param string $identifier
      */
-    public function add_metadata_resource (cc_i_metadata_resource $met,$identifier){
-       $metanode = $this->node("//imscc:resource".
-                     "[@identifier='".
-                     $identifier.
-                     "']");
-       $metanode2 = $this->node("//imscc:resource".
-                     "[@identifier='".
-                     $identifier.
-                     "']/imscc:file");
-       $dnode  = $this->doc->createElementNS($this->ccnamespaces['imscc'], "metadata");
-
-       $metanode->insertBefore($dnode,$metanode2);
-
-       $this->activemanifest->create_metadata_resource_node($met,$this->doc,$dnode);
+    public function add_metadata_resource(cc_i_metadata_resource $met, $identifier) {
+        $metanode  = $this->node("//imscc:resource".
+            "[@identifier='".
+            $identifier.
+            "']");
+        $metanode2 = $this->node("//imscc:resource".
+            "[@identifier='".
+            $identifier.
+            "']/imscc:file");
+        $nspaces   = $this->activemanifest->get_cc_namespaces();
+        $dnode     = $this->append_new_element_ns($metanode2, $nspaces['imscc'], 'metadata');
+        $this->activemanifest->create_metadata_resource_node($met, $this->doc, $dnode);
     }
 
 
@@ -133,45 +123,56 @@ class cc_manifest extends XMLGenericDocument implements cc_i_manifest {
      * @param string $identifier
      * @param string $filename
      */
-    public function add_metadata_file (cc_i_metadata_file $met,$identifier,$filename){
+    public function add_metadata_file(cc_i_metadata_file $met, $identifier, $filename) {
 
-        if (empty($met) || empty($identifier) || empty($filename)){
+        if (empty($met) || empty($identifier) || empty($filename)) {
             throw new Exception('Try to add a metadata file with nulls values given!');
         }
 
         $metanode = $this->node("//imscc:resource".
-                     "[@identifier='".
-                     $identifier.
-                     "']/imscc:file".
-                     "[@href='".
-                     $filename.
-                     "']");
+            "[@identifier='".
+            $identifier.
+            "']/imscc:file".
+            "[@href='".
+            $filename.
+            "']");
 
-       $dnode  = $this->doc->createElementNS($this->ccnamespaces['imscc'], "metadata");
+        $nspaces = $this->activemanifest->get_cc_namespaces();
+        $dnode   = $this->doc->createElementNS($nspaces['imscc'], "metadata");
 
-       $metanode->appendChild($dnode);
+        $metanode->appendChild($dnode);
 
-       $this->activemanifest->create_metadata_file_node($met,$this->doc,$dnode);
+        $this->activemanifest->create_metadata_file_node($met, $this->doc, $dnode);
     }
 
 
-    public function on_create (){
+    public function on_create() {
         $this->activemanifest = cc_builder_creator::factory($this->ccversion);
         $this->rootmanifest = $this->activemanifest;
         $result = $this->activemanifest->create_manifest($this->doc);
         $this->register_namespaces_for_xpath();
         return $result;
+    }
 
+    public function get_relative_base_path() {
+        return $this->activemanifest->base();
     }
 
+    public function parent_manifest() {
+        return new cc_manifest($this, $this->parentmanifest, $this->parentparentmanifest);
+    }
 
-    public function get_relative_base_path() {return $this->activemanifest->base();}
-    public function parent_manifest () {return new cc_manifest($this,$this->parentmanifest,$this->parentparentmanifest);}
-    public function root_manifest   () {return new cc_manifest($this,$this->rootmanifest);}
-    public function manifestID     () {return $this->activemanifest->manifestID();}
-    public function get_manifest_namespaces() {return $this->rootmanifest->get_cc_namespaces(); }
+    public function root_manifest() {
+        return new cc_manifest($this, $this->rootmanifest);
+    }
 
+    public function manifestID() {
+        return $this->activemanifest->manifestID();
+    }
 
+    public function get_manifest_namespaces() {
+        return $this->rootmanifest->get_cc_namespaces();
+    }
 
     /**
      * Add a new organization
@@ -179,28 +180,24 @@ class cc_manifest extends XMLGenericDocument implements cc_i_manifest {
      * @param cc_i_organization $org
      */
     public function add_new_organization(cc_i_organization &$org) {
-        $norg = $this->activemanifest->create_organization_node($org,$this->doc);
+        $norg    = $this->activemanifest->create_organization_node($org, $this->doc);
         $orgnode = $this->node("//imscc:manifest[@identifier='".
-                                $this->activemanifest->manifestID().
-                                "']/imscc:organizations");
+            $this->activemanifest->manifestID().
+            "']/imscc:organizations");
         $orgnode->appendChild($norg);
     }
 
-
-
     public function get_resources($searchspecific='') {
         $reslist = $this->get_resource_list($searchspecific);
         $resourcelist = array();
         foreach ($reslist as $resourceitem) {
-            $resourcelist[]=new cc_resource($this, $resourceitem);
+            $resourcelist[] = new cc_resource($this, $resourceitem);
         }
         return $resourcelist;
     }
 
-
-
     public function get_cc_namespace_path($nsname) {
-        if (is_string($nsname) && (!empty($nsname))){
+        if (is_string($nsname) && (!empty($nsname))) {
             $scnam = $this->activemanifest->get_cc_namespaces();
             return $scnam[$nsname];
         }
@@ -208,24 +205,22 @@ class cc_manifest extends XMLGenericDocument implements cc_i_manifest {
     }
 
 
-    public function get_resource_list($searchspecific=''){
+    public function get_resource_list($searchspecific = '') {
         return $this->nodeList("//imscc:manifest[@identifier='".
                             $this->activemanifest->manifestID().
                             "']/imscc:resources/imscc:resource".$searchspecific);
     }
 
-
-    public function on_load (){
+    public function on_load() {
         $this->register_namespaces_for_xpath();
         $this->fill_manifest();
         return true;
     }
 
-    public function on_save (){
+    public function on_save() {
         return true;
     }
 
-
     /**
      * Add a resource to the manifest
      *
@@ -234,30 +229,21 @@ class cc_manifest extends XMLGenericDocument implements cc_i_manifest {
      * @param string $type
      * @return array
      */
-    public function add_resource (cc_i_resource $res, $identifier=null, $type='webcontent'){
+    public function add_resource(cc_i_resource $res, $identifier = null, $type = 'webcontent') {
 
-        if (!$this->ccobj->valid($type)){
-             throw new Exception("Type invalid...");
+        if (!$this->ccobj->valid($type)) {
+            throw new Exception("Type invalid...");
         }
 
-        if (is_null($res)){
+        if ($res == null) {
             throw new Exception('Invalid Resource or dont give it');
         }
-        $rst = null;
-
-        if (is_string($res)){
-            $rst = new cc_resource($this->filePath(), $res);
-            if (is_string($identifier)){
-                $rst->identifier = $identifier;
-            }
-        } else {
-            $rst = $res;
-        }
+        $rst = $res;
 
-        //TODO: This has to be reviewed since it does not handle properly mutiple file
-        //      dependencies
+        // TODO: This has to be reviewed since it does not handle multiple files properly.
+        // Dependencies.
         if (is_object($identifier)) {
-            $this->activemanifest->create_resource_node($rst,$this->doc,$identifier);
+            $this->activemanifest->create_resource_node($rst, $this->doc, $identifier);
         } else {
             $nresnode   = null;
 
@@ -265,112 +251,105 @@ class cc_manifest extends XMLGenericDocument implements cc_i_manifest {
             if (!cc_helpers::is_html($rst->filename)) {
                 $rst->href = null;
             }
-            $this->activemanifest->create_resource_node($rst,$this->doc,$nresnode);
-
-
-            for ($i = 1 ; $i < count ($rst->files); $i++){
-                $ident = $this->get_identifier_by_filename($rst->files[$i]);
-                if(empty($ident)){
-                    $newres = new cc_resource($rst->manifestroot,$rst->files[$i],false);
-                    if (!empty($newres)) {
-                        if (!cc_helpers::is_html($rst->files[$i])) {
-                             $newres->href = null;
-                        }
-                        $newres->type = 'webcontent';
-                        $this->activemanifest->create_resource_node($newres,$this->doc,$nresnode);
-                    }
-                }
 
-            }
-            foreach ($this->activemanifest->resources as $k => $v){
-                ($k);
-                $depen = $this->check_if_exist_in_other($v->files[0]);
-                if (!empty($depen)){
-                    $this->replace_file_x_dependency($depen,$v->files[0]);
-                    // coloca aca como type = webcontent porque son archivos dependientes
-                    // quizas aqui habria q ver de que type es el que vino y segun eso, ponerlo
-                    // en associatedcontent o en webcontent
-                    $v->type = 'webcontent';
+            $this->activemanifest->create_resource_node($rst, $this->doc, $nresnode);
+            foreach ($rst->files as $file) {
+                $ident = $this->get_identifier_by_filename($file);
+                if ($ident == null) {
+                    $newres = new cc_resource($rst->manifestroot, $file);
+                    if (!cc_helpers::is_html($file)) {
+                         $newres->href = null;
+                    }
+                    $newres->type = 'webcontent';
+                    $this->activemanifest->create_resource_node($newres, $this->doc, $nresnode);
                 }
             }
         }
 
-        $tmparray = array($rst->identifier,$rst->files[0]);
+        $tmparray = array($rst->identifier, $rst->files[0]);
         return $tmparray;
     }
 
-
-
-    private function check_if_exist_in_other($name){
+    private function check_if_exist_in_other($name, $identifier) {
         $status = array();
-        foreach ($this->activemanifest->resources as $key => $value){
-            ($key);
-            for ($i=1; $i< count($value->files); $i++){
-                if ($name == $value->files[$i]){
-                    array_push($status,$value->identifier);
-                }
+        foreach ($this->activemanifest->resources as $value) {
+            if (($value->identifier != $identifier) && isset($value->files[$name])) {
+                $status[] = $value->identifier;
             }
         }
         return $status;
     }
 
-
-    private function replace_file_x_dependency($depen,$name){
-        foreach ($depen as $key => $value){
+    private function replace_file_x_dependency($depen, $name) {
+        foreach ($depen as $key => $value) {
             ($key);
-            $ident = $this->get_identifier_by_filename($name);
+            $ident                                          = $this->get_identifier_by_filename($name);
             $this->activemanifest->resources[$value]->files =
-                $this->array_remove_by_value($this->activemanifest->resources[$value]->files,$name);
-            if (!in_array($ident,$this->activemanifest->resources[$value]->dependency)){
-                array_push($this->activemanifest->resources[$value]->dependency,$ident);
+                $this->array_remove_by_value($this->activemanifest->resources[$value]->files, $name);
+            if (!in_array($ident, $this->activemanifest->resources[$value]->dependency)) {
+                array_push($this->activemanifest->resources[$value]->dependency, $ident);
             }
 
         }
         return true;
     }
 
-
-    private function get_identifier_by_filename($name){
+    private function get_identifier_by_filename($name) {
         $result = null;
-        foreach ($this->activemanifest->resources as $key => $value) {
-                if ($name == $value->files[0]){
-                    $result = $key;
-                    break;
-                }
+        if (isset($this->activemanifest->resources_ind[$name])) {
+            $result = $this->activemanifest->resources_ind[$name];
         }
         return $result;
     }
 
-
-
-    private function array_remove_by_value($arr,$value) {
-        return array_values(array_diff($arr,array($value)));
-
+    private function array_remove_by_value($arr, $value) {
+        return array_values(array_diff($arr, array($value)));
     }
 
-    private function array_remove_by_key($arr,$key) {
-        return array_values(array_diff_key($arr,array($key)));
-
+    private function array_remove_by_key($arr, $key) {
+        return array_values(array_diff_key($arr, array($key)));
     }
 
+    public function update_instructoronly($identifier, $value = false) {
+        if (isset($this->activemanifest->resources[$identifier])) {
+            $resource = $this->activemanifest->resources[$identifier];
+            $resource->instructoronly = $value;
+        }
+    }
 
     /**
      * Append the resources nodes in the Manifest
      *
      * @return DOMNode
      */
-    public function put_nodes (){
+    public function put_nodes() {
 
         $resnodestr = "//imscc:manifest[@identifier='".$this->activemanifest->manifestID().
-                          "']/imscc:resources";
+            "']/imscc:resources";
         $resnode    = $this->node($resnodestr);
 
-        foreach ($this->activemanifest->resources as $key => $node) {
-            ($key);
-            $resnode->appendChild($this->activemanifest->create_resource_node($node,$this->doc,null));
+        foreach ($this->activemanifest->resources as $k => $v) {
+            ($k);
+            $depen = $this->check_if_exist_in_other($v->files[0], $v->identifier);
+            if (!empty($depen)) {
+                $this->replace_file_x_dependency($depen, $v->files[0]);
+                $v->type = 'webcontent';
+            }
         }
-        return $resnode;
 
+        foreach ($this->activemanifest->resources as $node) {
+            $rnode = $this->activemanifest->create_resource_node($node, $this->doc, null);
+            $resnode->appendChild($rnode);
+            if ($node->instructoronly) {
+                $metafileceduc = new cc_metadata_resouce_educational();
+                $metafileceduc->set_value(intended_user_role::INSTRUCTOR);
+                $metafile = new cc_metadata_resouce();
+                $metafile->add_metadata_resource_educational($metafileceduc);
+                $this->activemanifest->create_metadata_educational($metafile, $this->doc, $rnode);
+            }
+        }
+
+        return $resnode;
     }
 }
 
index af9fd98..5764342 100644 (file)
@@ -19,7 +19,7 @@
  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  */
 
-require_once 'cc_general.php';
+require_once('cc_general.php');
 
 class page11_resurce_file extends general_cc_file {
     protected $rootns = 'xmlns';
@@ -31,6 +31,7 @@ class page11_resurce_file extends general_cc_file {
     protected $intro = null;
 
     public function set_content($value) {
+        // We are not cleaning up this one on purpose.
         $this->content = $value;
     }
 
@@ -57,38 +58,38 @@ class page11_resurce_file extends general_cc_file {
     public function on_save() {
 
         $rns = $this->ccnamespaces[$this->rootns];
-        //Add the basic tags
+        // Add the basic tags.
         $head = $this->append_new_element_ns($this->root, $rns, 'head');
         $this->append_new_attribute_ns($head, $rns, 'profile', 'http://dublincore.org/documents/dc-html/');
 
-        //Linking Dublin Core Metadata 1.1
+        // Linking Dublin Core Metadata 1.1.
         $link_dc = $this->append_new_element_ns($head, $rns, 'link');
         $this->append_new_attribute_ns($link_dc, $rns, 'rel', 'schema.DC');
         $this->append_new_attribute_ns($link_dc, $rns, 'href', 'http://purl.org/dc/elements/1.1/');
         $link_dcterms = $this->append_new_element_ns($head, $rns, 'link');
         $this->append_new_attribute_ns($link_dcterms, $rns, 'rel', 'schema.DCTERMS');
         $this->append_new_attribute_ns($link_dcterms, $rns, 'href', 'http://purl.org/dc/terms/');
-        //Content type
+        // Content type.
         $meta_type = $this->append_new_element_ns($head, $rns, 'meta');
-        $this->append_new_attribute_ns($meta_type, $rns, 'name'   , 'DC.type'         );
-        $this->append_new_attribute_ns($meta_type, $rns, 'scheme' , 'DCTERMS.DCMIType');
-        $this->append_new_attribute_ns($meta_type, $rns, 'content', 'Text'            );
+        $this->append_new_attribute_ns($meta_type, $rns, 'name', 'DC.type');
+        $this->append_new_attribute_ns($meta_type, $rns, 'scheme', 'DCTERMS.DCMIType');
+        $this->append_new_attribute_ns($meta_type, $rns, 'content', 'Text');
 
-        //Content description
+        // Content description.
         if (!empty($this->intro)) {
-            $meta_description = $this->append_new_element_ns($head, $rns     , 'meta'          );
-            $this->append_new_attribute_ns($meta_description, $rns, 'name'   , 'DC.description');
-            $this->append_new_attribute_ns($meta_description, $rns, 'content', $this->intro    );
+            $meta_description = $this->append_new_element_ns($head, $rns, 'meta');
+            $this->append_new_attribute_ns($meta_description, $rns, 'name', 'DC.description');
+            $this->append_new_attribute_ns($meta_description, $rns, 'content', $this->intro);
         }
 
         $meta = $this->append_new_element_ns($head, $rns, 'meta');
         $this->append_new_attribute_ns($meta, $rns, 'http-equiv', 'Content-type');
         $this->append_new_attribute_ns($meta, $rns, 'content', 'text/html; charset=UTF-8');
-        //set the title
+        // Set the title.
         $title = $this->append_new_element_ns($head, $rns, 'title', $this->title);
         $body = $this->append_new_element_ns($this->root, $rns, 'body');
-        //We are unable to use DOM for embedding HTML due to numerous content errors
-        //Therefore we place a dummy tag that will be later replaced with the real content
+        // We are unable to use DOM for embedding HTML due to numerous content errors.
+        // Therefore we place a dummy tag that will be later replaced with the real content.
         $this->append_new_element_ns($body, $rns, 'div', '##REPLACE##');
 
         return true;
index eb34779..d03ba25 100644 (file)
 // along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
 
 /**
-* @package    backup-convert
-* @subpackage cc-library
-* @copyright  2011 Darko Miletic <dmiletic@moodlerooms.com>
-* @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
-*/
-
-require_once 'cc_interfaces.php';
-require_once 'xmlbase.php';
-require_once 'gral_lib/pathutils.php';
-require_once 'gral_lib/ccdependencyparser.php';
-require_once 'cc_version_base.php';
-require_once 'cc_version1.php';
-require_once 'cc_manifest.php';
+ * @package    backup-convert
+ * @subpackage cc-library
+ * @copyright  2011 Darko Miletic <dmiletic@moodlerooms.com>
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+require_once('cc_interfaces.php');
+require_once('xmlbase.php');
+require_once('gral_lib/pathutils.php');
+require_once('gral_lib/ccdependencyparser.php');
+require_once('cc_version_base.php');
+require_once('cc_version1.php');
+require_once('cc_manifest.php');
 
 /**
  * Common Cartridge Version
@@ -82,18 +82,20 @@ class cc11_resource_type {
  */
 class cc_resource implements cc_i_resource {
 
-    public  $identifier     = null;
-    public  $type           = null;
-    public  $dependency     = array();
-    public  $identifierref  = null;
-    public  $href           = null;
-    public  $base           = null;
-    public  $persiststate   = null;
-    public  $filename       = null;
-    public  $files          = array();
-    public  $isempty        = null;
-    public  $manifestroot   = null;
-    public  $folder         = null;
+    public $identifier     = null;
+    public $type           = null;
+    public $dependency     = array();
+    public $identifierref  = null;
+    public $href           = null;
+    public $base           = null;
+    public $persiststate   = null;
+    public $metadata       = array();
+    public $filename       = null;
+    public $files          = array();
+    public $isempty        = null;
+    public $manifestroot   = null;
+    public $folder         = null;
+    public $instructoronly = false;
 
     private $throwonerror   = true;
 
@@ -101,10 +103,10 @@ class cc_resource implements cc_i_resource {
         $this->throwonerror = $throwonerror;
         if (is_string($manifest)) {
             $this->folder = $folder;
-            $this->process_resource($manifest, $file,$folder);
+            $this->process_resource($manifest, $file, $folder);
             $this->manifestroot = $manifest;
         } else if (is_object($manifest)) {
-            $this->import_resource($file,$manifest.$folder);
+            $this->import_resource($file, $manifest);
         }
     }
 
@@ -114,12 +116,10 @@ class cc_resource implements cc_i_resource {
      * @param string $fname
      * @param string $location
      */
-    public function add_resource ($fname, $location =''){
-        $this->process_resource($fname,$location);
-
+    public function add_resource ($fname, $location ='') {
+        $this->process_resource($fname, $location, null);
     }
 
-
     /**
      * Import a resource
      *
@@ -130,10 +130,10 @@ class cc_resource implements cc_i_resource {
 
         $searchstr = "//imscc:manifest[@identifier='".$doc->manifestID().
                      "']/imscc:resources/imscc:resource";
-        $this->identifier   = $this->get_attr_value($node,"identifier");
-        $this->type         = $this->get_attr_value($node,"type");
-        $this->href         = $this->get_attr_value($node,"href");
-        $this->base         = $this->get_attr_value($node,"base");
+        $this->identifier   = $this->get_attr_value($node, "identifier");
+        $this->type         = $this->get_attr_value($node, "type");
+        $this->href         = $this->get_attr_value($node, "href");
+        $this->base         = $this->get_attr_value($node, "base");
         $this->persiststate = null;
         $nodo               = $doc->nodeList($searchstr."[@identifier='".
                               $this->identifier."']/metadata/@href");
@@ -154,7 +154,6 @@ class cc_resource implements cc_i_resource {
         $this->isempty      = false;
     }
 
-
     /**
      * Get a attribute value
      *
@@ -164,12 +163,12 @@ class cc_resource implements cc_i_resource {
      * @return string
      */
     public function get_attr_value(&$nod, $name, $ns=null) {
-      return is_null($ns) ?
-             ($nod->hasAttribute($name) ? $nod->getAttribute($name) : null) :
-             ($nod->hasAttributeNS($ns, $name) ? $nod->getAttributeNS($ns, $name) : null);
+        if (is_null($ns)) {
+            return ($nod->hasAttribute($name) ? $nod->getAttribute($name) : null);
+        }
+        return ($nod->hasAttributeNS($ns, $name) ? $nod->getAttributeNS($ns, $name) : null);
     }
 
-
     /**
      * Process a resource
      *
@@ -179,12 +178,12 @@ class cc_resource implements cc_i_resource {
      */
     public function process_resource($manifestroot, &$fname, $folder) {
         $file = empty($folder) ? $manifestroot.'/'.$fname : $manifestroot.'/'.$folder.'/'.$fname;
-        if (!file_exists($file) && $this->throwonerror){
+        if (!file_exists($file) && $this->throwonerror) {
             throw new Exception('The file doesnt exist!');
         }
 
         GetDepFiles($manifestroot, $fname, $this->folder, $this->files);
-        array_unshift($this->files,$folder.$fname);
+        array_unshift($this->files, $folder.$fname);
         $this->init_empty_new();
         $this->href             = $folder.$fname;
         $this->identifierref    = $folder.$fname;
@@ -196,43 +195,41 @@ class cc_resource implements cc_i_resource {
     public function adjust_path($mroot, $fname) {
         $result = null;
         if (file_exists($fname->filename)) {
-            $result = pathDiff($fname->filename,$mroot);
+            $result = pathDiff($fname->filename, $mroot);
 
         } else if (file_exists($mroot.$fname->filename) || file_exists($mroot.DIRECTORY_SEPARATOR.$fname->filename)) {
-            $result = trim(toUrlPath($fname->filename),"/");
+            $result = $fname->filename;
+            toUrlPath($result);
+            $result = trim($result, "/");
         }
         return $result;
     }
 
-
-
     public function init_clean() {
-        $this->identifier       =   null;
-        $this->type             =   null;
-        $this->href             =   null;
-        $this->base             =   null;
-        $this->metadata         =   array();
-        $this->dependency       =   array();
-        $this->identifierref    =   null;
-        $this->persiststate     =   null;
-        $this->filename         =   '';
-        $this->files            =   array();
-        $this->isempty          =   true;
+        $this->identifier    = null;
+        $this->type          = null;
+        $this->href          = null;
+        $this->base          = null;
+        $this->metadata      = array();
+        $this->dependency    = array();
+        $this->identifierref = null;
+        $this->persiststate  = null;
+        $this->filename      = '';
+        $this->files         = array();
+        $this->isempty       = true;
     }
 
-
     public function init_empty_new() {
-        $this->identifier       =   cc_helpers::uuidgen('I_', '_R');
-        $this->type             =   null;
-        $this->href             =   null;
-        $this->persiststate     =   null;
-        $this->filename         =   null;
-        $this->isempty          =   false;
-        $this->identifierref    =   null;
+        $this->identifier    = cc_helpers::uuidgen('I_', '_R');
+        $this->type          = null;
+        $this->href          = null;
+        $this->persiststate  = null;
+        $this->filename      = null;
+        $this->isempty       = false;
+        $this->identifierref = null;
     }
 
-    public function get_manifestroot(){
+    public function get_manifestroot() {
         return $this->manifestroot;
     }
-
 }
\ No newline at end of file
index 39e7062..4ca4f37 100644 (file)
 // along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
 
 /**
-* @package    backup-convert
-* @subpackage cc-library
-* @copyright  2011 Darko Miletic <dmiletic@moodlerooms.com>
-* @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
-*/
+ * @package    backup-convert
+ * @subpackage cc-library
+ * @copyright  2011 Darko Miletic <dmiletic@moodlerooms.com>
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
 
-require_once 'xmlbase.php';
+require_once('xmlbase.php');
 
 /**
  *
@@ -32,8 +32,8 @@ require_once 'xmlbase.php';
 abstract class cc_helpers {
 
     /**
-     *
      * Checks extension of the supplied filename
+     *
      * @param string $filename
      */
     public static function is_html($filename) {
@@ -42,7 +42,6 @@ abstract class cc_helpers {
     }
 
     /**
-     *
      * Generates unique identifier
      * @param string $prefix
      * @param string $suffix
@@ -50,17 +49,16 @@ abstract class cc_helpers {
      */
     public static function uuidgen($prefix = '', $suffix = '', $uppercase = true) {
         $uuid = trim(sprintf('%s%04x%04x%s', $prefix, mt_rand(0, 65535), mt_rand(0, 65535), $suffix));
-        $result = $uppercase ? strtoupper($uuid) : strtolower($uuid) ;
+        $result = $uppercase ? strtoupper($uuid) : strtolower($uuid);
         return $result;
     }
 
     /**
-     *
      * Creates new folder with random name
      * @param string $where
      * @param string $prefix
      * @param string $suffix
-     * @return mixed - directory short name or false in case of faliure
+     * @return mixed - directory short name or false in case of failure
      */
     public static function randomdir($where, $prefix = '', $suffix = '') {
         global $CFG;
@@ -145,12 +143,12 @@ abstract class cc_helpers {
             $type       = $mfile->nodeValue('mimetype', $node);
             $depfiles[$filepath.$filename] = array( $location,
                                                     ($mainfile == 1),
-                                                    strtolower(str_replace(' ', '_',$filename)),
+                                                    strtolower(str_replace(' ', '_', $filename)),
                                                     $type,
                                                     $source,
                                                     $author,
                                                     $license,
-                                                    strtolower(str_replace(' ', '_',$filepath)));
+                                                    strtolower(str_replace(' ', '_', $filepath)));
         }
 
         return $depfiles;
@@ -210,23 +208,21 @@ abstract class cc_helpers {
      * @param boolean $allinone
      * @throws RuntimeException
      */
-    public static function handle_static_content(cc_i_manifest &$manifest, $packageroot, $contextid, $outdir, $allinone = true){
-        cc_helpers::add_files($manifest, $packageroot, $outdir, $allinone);
+    public static function handle_static_content(cc_i_manifest &$manifest, $packageroot, $contextid, $outdir, $allinone = true) {
+        self::add_files($manifest, $packageroot, $outdir, $allinone);
         return pkg_static_resources::instance()->get_values();
     }
 
-    public static function handle_resource_content(cc_i_manifest &$manifest, $packageroot, $contextid, $outdir, $allinone = true){
+    public static function handle_resource_content(cc_i_manifest &$manifest, $packageroot, $contextid, $outdir, $allinone = true) {
         $result = array();
-        cc_helpers::add_files($manifest, $packageroot, $outdir, $allinone);
-        $files = cc_helpers::embedded_mapping($packageroot, $contextid);
-        //$rdir = $allinone ? new cc_resource_location($outdir) : null;
+        self::add_files($manifest, $packageroot, $outdir, $allinone);
+        $files = self::embedded_mapping($packageroot, $contextid);
         $rootnode = null;
         $rootvals = null;
         $depfiles = array();
         $depres = array();
         $flocation = null;
         foreach ($files as $virtual => $values) {
-            $clean_filename = $values[2];
             $vals = pkg_static_resources::instance()->get_identifier($virtual);
             $resource = $vals[3];
             $identifier = $resource->identifier;
@@ -250,17 +246,16 @@ abstract class cc_helpers {
         return $result;
     }
 
-    public static function process_linked_files($content, cc_i_manifest &$manifest, $packageroot, $contextid, $outdir, $webcontent = false) {
-        /**
-        - detect all embedded files
-        - locate their physical counterparts in moodle 2 backup
-        - copy all files in the cc package stripping any spaces and using inly lowercase letters
-        - add those files as resources of the type webcontent to the manifest
-        - replace the links to the resourcse using $IMS-CC-FILEBASE$ and their new locations
-        - cc_resource has array of files and array of dependencies
-        - most likely we would need to add all files as independent resources and than
-        attach them all as dependencies to the forum tag
-        */
+    public static function process_linked_files($content, cc_i_manifest &$manifest, $packageroot,
+                                                $contextid, $outdir, $webcontent = false) {
+        // Detect all embedded files
+        // locate their physical counterparts in moodle 2 backup
+        // copy all files in the cc package stripping any spaces and using only lowercase letters
+        // add those files as resources of the type webcontent to the manifest
+        // replace the links to the resource using $IMS-CC-FILEBASE$ and their new locations
+        // cc_resource has array of files and array of dependencies
+        // most likely we would need to add all files as independent resources and than
+        // attach them all as dependencies to the forum tag.
         $lfiles = self::embedded_files($content);
         $text = $content;
         $deps = array();
@@ -271,13 +266,13 @@ abstract class cc_helpers {
                                                  $outdir);
             $replaceprefix = $webcontent ? '' : '$IMS-CC-FILEBASE$';
             foreach ($lfiles as $lfile) {
-                if (array_key_exists($lfile, $files)) {
-                    $filename = str_replace('%2F', '/',rawurlencode($lfile));
+                if (isset($files[$lfile])) {
+                    $filename = str_replace('%2F', '/', rawurlencode($lfile));
                     $content = str_replace('@@PLUGINFILE@@'.$filename,
                                            $replaceprefix.'../'.$files[$lfile][1],
                                            $content);
-                    //for the legacy stuff
-                    $content = str_replace('$@FILEPHP@$'.str_replace('/','$@SLASH@$',$filename),
+                    // For the legacy stuff.
+                    $content = str_replace('$@FILEPHP@$'.str_replace('/', '$@SLASH@$', $filename),
                                            $replaceprefix.'../'.$files[$lfile][1],
                                            $content);
                     $deps[] = $files[$lfile][0];
@@ -380,8 +375,11 @@ class pkg_static_resources {
      */
     private static $instance = null;
 
-    private function __clone() {}
-    private function __construct() {}
+    private function __clone() {
+    }
+
+    private function __construct() {
+    }
 
     /**
      * @return pkg_static_resources
@@ -413,24 +411,20 @@ class pkg_static_resources {
     }
 
     public function get_identifier($location) {
-        $result = false;
-        if (array_key_exists($location, $this->values)) {
-            $result = $this->values[$location];
-        }
-        return $result;
+        return isset($this->values[$location]) ? $this->values[$location] : false;
     }
 
     public function reset() {
         $this->values   = array();
-        $this->finished = false  ;
+        $this->finished = false;
     }
 }
 
 
 class pkg_resource_dependencies {
     /**
-    * @var array
-    */
+     * @var array
+     */
     private $values = array();
 
     /**
index 30f382a..f68cb58 100644 (file)
 // along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
 
 /**
-* @package    backup-convert
-* @subpackage cc-library
-* @copyright  2011 Darko Miletic <dmiletic@moodlerooms.com>
-* @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
-*/
-
-require_once 'cc_utils.php';
-require_once 'cc_version_base.php';
-require_once 'cc_organization.php';
+ * @package    backup-convert
+ * @subpackage cc-library
+ * @copyright  2011 Darko Miletic <dmiletic@moodlerooms.com>
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
 
+require_once('cc_utils.php');
+require_once('cc_version_base.php');
+require_once('cc_organization.php');
 
 /**
  * Version 1 class of Common Cartridge
@@ -63,80 +62,78 @@ class cc_version1 extends cc_version_base {
                                         'xsi'      => 'http://www.w3.org/2001/XMLSchema-instance'
                                         );
 
-        $this->ccnsnames        = array('imscc'    => 'http://www.imsglobal.org/profile/cc/ccv1p0/derived_schema/imscp_v1p2_localised.xsd' ,
-                                        'lom'      => 'http://www.imsglobal.org/profile/cc/ccv1p0/derived_schema/domainProfile_2/lomLoose_localised.xsd' ,
-                                        'lomimscc' => 'http://www.imsglobal.org/profile/cc/ccv1p0/derived_schema/domainProfile_1/lomLoose_localised.xsd',
-                                        'voc'      => 'http://www.imsglobal.org/profile/cc/ccv1p0/derived_schema/domainProfile_2/vocab/loose.xsd'
-                                        );
+        $this->ccnsnames = array(
+            'imscc'    => 'http://www.imsglobal.org/profile/cc/ccv1p0/derived_schema/imscp_v1p2_localised.xsd',
+            'lom'      => 'http://www.imsglobal.org/profile/cc/ccv1p0/derived_schema/domainProfile_2/lomLoose_localised.xsd',
+            'lomimscc' => 'http://www.imsglobal.org/profile/cc/ccv1p0/derived_schema/domainProfile_1/lomLoose_localised.xsd',
+            'voc'      => 'http://www.imsglobal.org/profile/cc/ccv1p0/derived_schema/domainProfile_2/vocab/loose.xsd'
+        );
 
         $this->ccversion        = '1.0.0';
         $this->camversion       = '1.0.0';
         $this->_generator       = 'Moodle 2 Common Cartridge generator';
     }
 
-    protected function on_create(DOMDocument &$doc, $rootmanifestnode=null,$nmanifestID=null) {
-      $doc->formatOutput        = true;
-      $doc->preserveWhiteSpace  = true;
+    protected function on_create(DOMDocument &$doc, $rootmanifestnode = null, $nmanifestID = null) {
+        $doc->formatOutput       = true;
+        $doc->preserveWhiteSpace = true;
+
 
+        $this->manifestID = is_null($nmanifestID) ? cc_helpers::uuidgen('M_') : $nmanifestID;
+        $mUUID            = $doc->createAttribute('identifier');
+        $mUUID->nodeValue = $this->manifestID;
 
-      $this->manifestID = is_null($nmanifestID) ? cc_helpers::uuidgen('M_') : $nmanifestID;
-      $mUUID = $doc->createAttribute('identifier');
-      $mUUID->nodeValue = $this->manifestID;
 
+        if (is_null($rootmanifestnode)) {
+            if (!empty($this->_generator)) {
+                $comment = $doc->createComment($this->_generator);
+                $doc->appendChild($comment);
+            }
 
-      if (is_null($rootmanifestnode)) {
-          if (!empty($this->_generator)) {
-              $comment = $doc->createComment($this->_generator);
-              $doc->appendChild($comment);
-          }
+            $rootel = $doc->createElementNS($this->ccnamespaces['imscc'], 'manifest');
+            $rootel->appendChild($mUUID);
+            $doc->appendChild($rootel);
 
-          $rootel = $doc->createElementNS($this->ccnamespaces['imscc'],'manifest');
-          $rootel->appendChild($mUUID);
-          $doc->appendChild($rootel);
+            // Add all namespaces.
+            foreach ($this->ccnamespaces as $key => $value) {
+                $dummy_attr = $key.":dummy";
+                $doc->createAttributeNS($value, $dummy_attr);
+            }
 
-          //add all namespaces
-          foreach ($this->ccnamespaces as $key => $value) {
-                if ($key != 'lom' ){
-                    $dummy_attr = $key.":dummy";
-                    $doc->createAttributeNS($value,$dummy_attr);
-                }
-          }
-
-          // add location of schemas
-          $schemaLocation='';
-          foreach ($this->ccnsnames as $key => $value) {
-              $vt = empty($schemaLocation) ? '' : ' ';
-              $schemaLocation .= $vt.$this->ccnamespaces[$key].' '.$value;
-          }
-          $aSchemaLoc = $doc->createAttributeNS($this->ccnamespaces['xsi'],'xsi:schemaLocation');
-          $aSchemaLoc->nodeValue=$schemaLocation;
-          $rootel->appendChild($aSchemaLoc);
-
-      } else {
-          $rootel = $doc->createElementNS($this->ccnamespaces['imscc'],'imscc:manifest');
-          $rootel->appendChild($mUUID);
-      }
-
-      $metadata = $doc->createElementNS($this->ccnamespaces['imscc'],'metadata');
-      $schema = $doc->createElementNS($this->ccnamespaces['imscc'],'schema','IMS Common Cartridge');
-      $schemaversion = $doc->createElementNS($this->ccnamespaces['imscc'],'schemaversion',$this->ccversion);
-
-      $metadata->appendChild($schema);
-      $metadata->appendChild($schemaversion);
-      $rootel->appendChild($metadata);
-
-      if (!is_null($rootmanifestnode)) {
-          $rootmanifestnode->appendChild($rootel);
-      }
-
-      $organizations = $doc->createElementNS($this->ccnamespaces['imscc'],'organizations');
-      $rootel->appendChild($organizations);
-      $resources = $doc->createElementNS($this->ccnamespaces['imscc'],'resources');
-      $rootel->appendChild($resources);
-
-      return true;
-    }
+            // Add location of schemas.
+            $schemaLocation = '';
+            foreach ($this->ccnsnames as $key => $value) {
+                $vt = empty($schemaLocation) ? '' : ' ';
+                $schemaLocation .= $vt.$this->ccnamespaces[$key].' '.$value;
+            }
+            $aSchemaLoc            = $doc->createAttributeNS($this->ccnamespaces['xsi'], 'xsi:schemaLocation');
+            $aSchemaLoc->nodeValue = $schemaLocation;
+            $rootel->appendChild($aSchemaLoc);
+
+        } else {
+            $rootel = $doc->createElementNS($this->ccnamespaces['imscc'], 'imscc:manifest');
+            $rootel->appendChild($mUUID);
+        }
+
+        $metadata      = $doc->createElementNS($this->ccnamespaces['imscc'], 'metadata');
+        $schema        = $doc->createElementNS($this->ccnamespaces['imscc'], 'schema', 'IMS Common Cartridge');
+        $schemaversion = $doc->createElementNS($this->ccnamespaces['imscc'], 'schemaversion', $this->ccversion);
+
+        $metadata->appendChild($schema);
+        $metadata->appendChild($schemaversion);
+        $rootel->appendChild($metadata);
+
+        if (!is_null($rootmanifestnode)) {
+            $rootmanifestnode->appendChild($rootel);
+        }
+
+        $organizations = $doc->createElementNS($this->ccnamespaces['imscc'], 'organizations');
+        $rootel->appendChild($organizations);
+        $resources = $doc->createElementNS($this->ccnamespaces['imscc'], 'resources');
+        $rootel->appendChild($resources);
 
+        return true;
+    }
 
     protected function update_attribute(DOMDocument &$doc, $attrname, $attrvalue, DOMElement &$node) {
         $busenew = (is_object($node) && $node->hasAttribute($attrname));
@@ -153,14 +150,14 @@ class cc_version1 extends cc_version_base {
         return $nResult;
     }
 
-
     protected function update_attribute_ns(DOMDocument &$doc, $attrname, $attrnamespace,$attrvalue, DOMElement &$node) {
         $busenew = (is_object($node) && $node->hasAttributeNS($attrnamespace, $attrname));
         $nResult = null;
         if (!$busenew && is_null($attrvalue)) {
             $node->removeAttributeNS($attrnamespace, $attrname);
         } else {
-            $nResult = $busenew ? $node->getAttributeNodeNS($attrnamespace, $attrname) : $doc->createAttributeNS($attrnamespace, $attrname);
+            $nResult = $busenew ? $node->getAttributeNodeNS($attrnamespace, $attrname) :
+                $doc->createAttributeNS($attrnamespace, $attrname);
             $nResult->nodeValue = $attrvalue;
             if (!$busenew) {
                 $node->appendChild($nResult);
@@ -169,21 +166,19 @@ class cc_version1 extends cc_version_base {
         return $nResult;
     }
 
-
     protected function get_child_node(DOMDocument &$doc, $itemname, DOMElement &$node) {
         $nlist = $node->getElementsByTagName($itemname);
         $item = is_object($nlist) && ($nlist->length > 0) ? $nlist->item(0) : null;
         return $item;
     }
 
-
     protected function update_child_item(DOMDocument &$doc, $itemname, $itemvalue, DOMElement &$node, $attrtostore=null) {
-        $tnode = $this->get_child_node($doc,'title',$node);
+        $tnode = $this->get_child_node($doc, 'title', $node);
         $usenew = is_null($tnode);
         $tnode = $usenew ? $doc->createElementNS($this->ccnamespaces['imscc'], $itemname) : $tnode;
         if (!is_null($attrtostore)) {
             foreach ($attrtostore as $key => $value) {
-                $this->update_attribute($doc,$key,$value,$tnode);
+                $this->update_attribute($doc, $key, $value, $tnode);
             }
         }
         $tnode->nodeValue = $itemvalue;
@@ -192,7 +187,6 @@ class cc_version1 extends cc_version_base {
         }
     }
 
-
     protected function update_items($items, DOMDocument &$doc, DOMElement &$xmlnode) {
         foreach ($items as $key => $item) {
             $itemnode = $doc->createElementNS($this->ccnamespaces['imscc'], 'item');
@@ -212,7 +206,6 @@ class cc_version1 extends cc_version_base {
         }
     }
 
-
     /**
      * Create a Resource (How to)
      *
@@ -224,22 +217,23 @@ class cc_version1 extends cc_version_base {
     protected function create_resource(cc_i_resource &$res, DOMDocument &$doc, $xmlnode=null) {
         $usenew = is_object($xmlnode);
         $dnode  = $usenew ? $xmlnode : $doc->createElementNS($this->ccnamespaces['imscc'], "resource");
-        $this->update_attribute($doc,'identifier',$res->identifier,$dnode);
-        $this->update_attribute($doc,'type'      ,$res->type      ,$dnode);
-        !is_null($res->href) ? $this->update_attribute($doc,'href',$res->href,$dnode): null;
-        $this->update_attribute($doc,'base'      ,$res->base      ,$dnode);
+        $this->update_attribute($doc, 'identifier', $res->identifier, $dnode);
+        $this->update_attribute($doc, 'type', $res->type, $dnode);
+        !is_null($res->href) ? $this->update_attribute($doc, 'href', $res->href, $dnode) : null;
+        $this->update_attribute($doc, 'base', $res->base, $dnode);
 
         foreach ($res->files as $file) {
-            $nd = $doc->createElementNS($this->ccnamespaces['imscc'],'file');
+            $nd = $doc->createElementNS($this->ccnamespaces['imscc'], 'file');
             $ndatt = $doc->createAttribute('href');
             $ndatt->nodeValue = $file;
             $nd->appendChild($ndatt);
             $dnode->appendChild($nd);
         }
-        $this->resources[$res->identifier]  = $res;
+        $this->resources[$res->identifier]   = $res;
+        $this->resources_ind[$res->files[0]] = $res->identifier;
 
-        foreach ($res->dependency as $dependency){
-            $nd = $doc->createElementNS($this->ccnamespaces['imscc'],'dependency');
+        foreach ($res->dependency as $dependency) {
+            $nd = $doc->createElementNS($this->ccnamespaces['imscc'], 'dependency');
             $ndatt = $doc->createAttribute('identifierref');
             $ndatt->nodeValue = $dependency;
             $nd->appendChild($ndatt);
@@ -249,8 +243,6 @@ class cc_version1 extends cc_version_base {
         return $dnode;
     }
 
-
-
     /**
      * Create an Item Folder (How To)
      *
@@ -258,25 +250,22 @@ class cc_version1 extends cc_version_base {
      * @param DOMDocument $doc
      * @param DOMElement $xmlnode
      */
-    protected function create_item_folder (cc_i_organization &$org, DOMDocument &$doc, DOMElement &$xmlnode=null){
+    protected function create_item_folder(cc_i_organization &$org, DOMDocument &$doc, DOMElement &$xmlnode = null) {
 
-            $itemfoldernode = $doc->createElementNS($this->ccnamespaces['imscc'],'item');
-            $this->update_attribute($doc,'identifier', "root", $itemfoldernode);
+        $itemfoldernode = $doc->createElementNS($this->ccnamespaces['imscc'], 'item');
+        $this->update_attribute($doc, 'identifier', "root", $itemfoldernode);
 
-            if ($org->has_items()) {
-                $this->update_items($org->itemlist, $doc, $itemfoldernode);
-            }
-            if (is_null($this->organizations)) {
-                $this->organizations = array();
-            }
-            $this->organizations[$org->identifier]  = $org;
+        if ($org->has_items()) {
+            $this->update_items($org->itemlist, $doc, $itemfoldernode);
+        }
+        if (is_null($this->organizations)) {
+            $this->organizations = array();
+        }
+        $this->organizations[$org->identifier] = $org;
 
-            $xmlnode->appendChild($itemfoldernode);
+        $xmlnode->appendChild($itemfoldernode);
     }
 
-
-
-
     /**
      * Create an Organization (How To)
      *
@@ -285,21 +274,18 @@ class cc_version1 extends cc_version_base {
      * @param object $xmlnode
      * @return DOMNode
      */
-    protected function create_organization (cc_i_organization &$org, DOMDocument &$doc, $xmlnode=null){
+    protected function create_organization(cc_i_organization &$org, DOMDocument &$doc, $xmlnode = null) {
 
         $usenew = is_object($xmlnode);
         $dnode  = $usenew ? $xmlnode : $doc->createElementNS($this->ccnamespaces['imscc'], "organization");
-        $this->update_attribute($doc,'identifier' ,$org->identifier,$dnode);
-        $this->update_attribute($doc,'structure'  ,$org->structure ,$dnode);
+        $this->update_attribute($doc, 'identifier', $org->identifier, $dnode);
+        $this->update_attribute($doc, 'structure', $org->structure, $dnode);
 
-        $this->create_item_folder($org,$doc,$dnode);
+        $this->create_item_folder($org, $doc, $dnode);
 
         return $dnode;
     }
 
-
-
-
     /**
      * Create Metadata For Manifest (How To)
      *
@@ -308,28 +294,26 @@ class cc_version1 extends cc_version_base {
      * @param object $xmlnode
      * @return DOMNode
      */
-    protected function create_metadata_manifest (cc_i_metadata_manifest $met,DOMDocument &$doc,$xmlnode=null) {
+    protected function create_metadata_manifest(cc_i_metadata_manifest $met, DOMDocument &$doc, $xmlnode = null) {
 
-        $dnode  =  $doc->createElementNS($this->ccnamespaces['lomimscc'], "lom");
+        $dnode = $doc->createElementNS($this->ccnamespaces['lomimscc'], "lom");
         if (!empty($xmlnode)) {
             $xmlnode->appendChild($dnode);
         }
-        $dnodegeneral   = empty($met->arraygeneral  ) ? null : $this->create_metadata_general  ($met, $doc, $xmlnode);
-        $dnodetechnical = empty($met->arraytech     ) ? null : $this->create_metadata_technical($met, $doc, $xmlnode);
-        $dnoderights    = empty($met->arrayrights   ) ? null : $this->create_metadata_rights   ($met, $doc, $xmlnode);
+        $dnodegeneral   = empty($met->arraygeneral) ? null : $this->create_metadata_general($met, $doc, $xmlnode);
+        $dnodetechnical = empty($met->arraytech) ? null : $this->create_metadata_technical($met, $doc, $xmlnode);
+        $dnoderights    = empty($met->arrayrights) ? null : $this->create_metadata_rights($met, $doc, $xmlnode);
         $dnodelifecycle = empty($met->arraylifecycle) ? null : $this->create_metadata_lifecycle($met, $doc, $xmlnode);
 
-        !is_null($dnodegeneral)?$dnode->appendChild($dnodegeneral):null;
-        !is_null($dnodetechnical)?$dnode->appendChild($dnodetechnical):null;
-        !is_null($dnoderights)?$dnode->appendChild($dnoderights):null;
-        !is_null($dnodelifecycle)?$dnode->appendChild($dnodelifecycle):null;
+        !is_null($dnodegeneral) ? $dnode->appendChild($dnodegeneral) : null;
+        !is_null($dnodetechnical) ? $dnode->appendChild($dnodetechnical) : null;
+        !is_null($dnoderights) ? $dnode->appendChild($dnoderights) : null;
+        !is_null($dnodelifecycle) ? $dnode->appendChild($dnodelifecycle) : null;
 
         return $dnode;
 
     }
 
-
-
     /**
      * Create Metadata For Resource (How To)
      *
@@ -338,19 +322,16 @@ class cc_version1 extends cc_version_base {
      * @param object $xmlnode
      * @return DOMNode
      */
-    protected function create_metadata_resource (cc_i_metadata_resource $met,DOMDocument &$doc,$xmlnode=null) {
+    protected function create_metadata_resource(cc_i_metadata_resource $met, DOMDocument &$doc, $xmlnode = null) {
 
         $dnode = $doc->createElementNS($this->ccnamespaces['lom'], "lom");
 
-        !empty($xmlnode)? $xmlnode->appendChild($dnode):null;
-        !empty($met->arrayeducational) ? $this->create_metadata_educational($met,$doc,$dnode):null;
+        !empty($xmlnode) ? $xmlnode->appendChild($dnode) : null;
+        !empty($met->arrayeducational) ? $this->create_metadata_educational($met, $doc, $dnode) : null;
 
         return $dnode;
     }
 
-
-
-
     /**
      * Create Metadata For File (How To)
      *
@@ -359,19 +340,16 @@ class cc_version1 extends cc_version_base {
      * @param Object $xmlnode
      * @return DOMNode
      */
-    protected function create_metadata_file (cc_i_metadata_file $met,DOMDocument &$doc,$xmlnode=null) {
+    protected function create_metadata_file(cc_i_metadata_file $met, DOMDocument &$doc, $xmlnode = null) {
 
         $dnode = $doc->createElementNS($this->ccnamespaces['lom'], "lom");
 
-        !empty($xmlnode)? $xmlnode->appendChild($dnode):null;
-        !empty($met->arrayeducational) ? $this->create_metadata_educational($met,$doc,$dnode):null;
+        !empty($xmlnode) ? $xmlnode->appendChild($dnode) : null;
+        !empty($met->arrayeducational) ? $this->create_metadata_educational($met, $doc, $dnode) : null;
 
         return $dnode;
     }
 
-
-
-
     /**
      * Create General Metadata (How To)
      *
@@ -380,48 +358,43 @@ class cc_version1 extends cc_version_base {
      * @param object $xmlnode
      * @return DOMNode
      */
-    protected function create_metadata_general($met,DOMDocument &$doc,$xmlnode){
-        ($xmlnode);
-        $nd = $doc->createElementNS($this->ccnamespaces['lomimscc'],'general');
+    protected function create_metadata_general($met, DOMDocument &$doc, $xmlnode) {
+        $nd = $doc->createElementNS($this->ccnamespaces['lomimscc'], 'general');
 
         foreach ($met->arraygeneral as $name => $value) {
-            !is_array($value)?$value =array($value):null;
-            foreach ($value as $k => $v){
-                ($k);
-                if ($name != 'language' && $name != 'catalog' && $name != 'entry'){
-                    $nd2 = $doc->createElementNS($this->ccnamespaces['lomimscc'],$name);
-                    $nd3 = $doc->createElementNS($this->ccnamespaces['lomimscc'],'string',$v[1]);
+            !is_array($value) ? $value = array($value) : null;
+            foreach ($value as $v) {
+                if ($name != 'language' && $name != 'catalog' && $name != 'entry') {
+                    $nd2 = $doc->createElementNS($this->ccnamespaces['lomimscc'], $name);
+                    $nd3 = $doc->createElementNS($this->ccnamespaces['lomimscc'], 'string', $v[1]);
                     $ndatt = $doc->createAttribute('language');
                     $ndatt->nodeValue = $v[0];
                     $nd3->appendChild($ndatt);
                     $nd2->appendChild($nd3);
                     $nd->appendChild($nd2);
-                }else{
-                    if ($name == 'language'){
-                        $nd2 = $doc->createElementNS($this->ccnamespaces['lomimscc'],$name,$v[0]);
+                } else {
+                    if ($name == 'language') {
+                        $nd2 = $doc->createElementNS($this->ccnamespaces['lomimscc'], $name, $v[0]);
                         $nd->appendChild($nd2);
                     }
                 }
             }
         }
-        if (!empty($met->arraygeneral['catalog']) || !empty($met->arraygeneral['entry'])){
-            $nd2 = $doc->createElementNS($this->ccnamespaces['lomimscc'],'identifier');
+        if (!empty($met->arraygeneral['catalog']) || !empty($met->arraygeneral['entry'])) {
+            $nd2 = $doc->createElementNS($this->ccnamespaces['lomimscc'], 'identifier');
             $nd->appendChild($nd2);
-            if (!empty($met->arraygeneral['catalog'])){
-                $nd3 = $doc->createElementNS($this->ccnamespaces['lomimscc'],'catalog',$met->arraygeneral['catalog'][0][0]);
+            if (!empty($met->arraygeneral['catalog'])) {
+                $nd3 = $doc->createElementNS($this->ccnamespaces['lomimscc'], 'catalog', $met->arraygeneral['catalog'][0][0]);
                 $nd2->appendChild($nd3);
             }
-            if (!empty($met->arraygeneral['entry'])){
-                $nd4 = $doc->createElementNS($this->ccnamespaces['lomimscc'],'entry',$met->arraygeneral['entry'][0][0]);
+            if (!empty($met->arraygeneral['entry'])) {
+                $nd4 = $doc->createElementNS($this->ccnamespaces['lomimscc'], 'entry', $met->arraygeneral['entry'][0][0]);
                 $nd2->appendChild($nd4);
             }
         }
         return $nd;
     }
 
-
-
-
     /**
      * Create Technical Metadata (How To)
      *
@@ -430,26 +403,21 @@ class cc_version1 extends cc_version_base {
      * @param object $xmlnode
      * @return DOMNode
      */
-    protected function create_metadata_technical($met,DOMDocument &$doc,$xmlnode){
-        ($xmlnode);
-        $nd = $doc->createElementNS($this->ccnamespaces['lomimscc'],'technical');
+    protected function create_metadata_technical($met, DOMDocument &$doc, $xmlnode) {
+        $nd = $doc->createElementNS($this->ccnamespaces['lomimscc'], 'technical');
         $xmlnode->appendChild($nd);
 
         foreach ($met->arraytech as $name => $value) {
-            ($name);
-            !is_array($value)?$value =array($value):null;
-            foreach ($value as $k => $v){
-                ($k);
-                    $nd2 = $doc->createElementNS($this->ccnamespaces['lomimscc'],$name,$v[0]);
-                    $nd->appendChild($nd2);
+            !is_array($value) ? $value = array($value) : null;
+            foreach ($value as $v) {
+                $nd2 = $doc->createElementNS($this->ccnamespaces['lomimscc'], $name, $v[0]);
+                $nd->appendChild($nd2);
             }
         }
         return $nd;
     }
 
 
-
-
     /**
      * Create Rights Metadata (How To)
      *
@@ -458,26 +426,24 @@ class cc_version1 extends cc_version_base {
      * @param object $xmlnode
      * @return DOMNode
      */
-    protected function create_metadata_rights($met,DOMDocument &$doc,$xmlnode){
-        ($xmlnode);
+    protected function create_metadata_rights($met, DOMDocument &$doc, $xmlnode) {
 
-        $nd = $doc->createElementNS($this->ccnamespaces['lomimscc'],'rights');
+        $nd = $doc->createElementNS($this->ccnamespaces['lomimscc'], 'rights');
 
         foreach ($met->arrayrights as $name => $value) {
-            !is_array($value)?$value =array($value):null;
-            foreach ($value as $k => $v){
-                ($k);
-                if ($name == 'description'){
-                    $nd2 = $doc->createElementNS($this->ccnamespaces['lomimscc'],$name);
-                    $nd3 = $doc->createElementNS($this->ccnamespaces['lomimscc'],'string',$v[1]);
+            !is_array($value) ? $value = array($value) : null;
+            foreach ($value as $v) {
+                if ($name == 'description') {
+                    $nd2 = $doc->createElementNS($this->ccnamespaces['lomimscc'], $name);
+                    $nd3 = $doc->createElementNS($this->ccnamespaces['lomimscc'], 'string', $v[1]);
                     $ndatt = $doc->createAttribute('language');
                     $ndatt->nodeValue = $v[0];
                     $nd3->appendChild($ndatt);
                     $nd2->appendChild($nd3);
                     $nd->appendChild($nd2);
-                }elseif ($name == 'copyrightAndOtherRestrictions' || $name == 'cost'){
-                    $nd2 = $doc->createElementNS($this->ccnamespaces['lomimscc'],$name);
-                    $nd3 = $doc->createElementNS($this->ccnamespaces['lomimscc'],'value',$v[0]);
+                } else if ($name == 'copyrightAndOtherRestrictions' || $name == 'cost') {
+                    $nd2 = $doc->createElementNS($this->ccnamespaces['lomimscc'], $name);
+                    $nd3 = $doc->createElementNS($this->ccnamespaces['lomimscc'], 'value', $v[0]);
                     $nd2->appendChild($nd3);
                     $nd->appendChild($nd2);
                 }
@@ -486,44 +452,38 @@ class cc_version1 extends cc_version_base {
         return $nd;
     }
 
-
-
-
     /**
-     * Create LifeCyle Metadata (How To)
+     * Create Lifecycle Metadata (How To)
      *
      * @param object $met
      * @param DOMDocument $doc
      * @param object $xmlnode
      * @return DOMNode
      */
-    protected function create_metadata_lifecycle($met,DOMDocument &$doc,$xmlnode){
-        ($xmlnode);
+    protected function create_metadata_lifecycle($met, DOMDocument &$doc, $xmlnode) {
 
-        $nd = $doc->createElementNS($this->ccnamespaces['lomimscc'],'lifeCycle');
-        $nd2= $doc->createElementNS($this->ccnamespaces['lomimscc'],'contribute');
+        $nd  = $doc->createElementNS($this->ccnamespaces['lomimscc'], 'lifeCycle');
+        $nd2 = $doc->createElementNS($this->ccnamespaces['lomimscc'], 'contribute');
 
-
-        $nd->appendChild ($nd2);
-        $xmlnode->appendChild ($nd);
+        $nd->appendChild($nd2);
+        $xmlnode->appendChild($nd);
 
         foreach ($met->arraylifecycle as $name => $value) {
-            !is_array($value)?$value =array($value):null;
-            foreach ($value as $k => $v){
-                ($k);
-                if ($name == 'role'){
-                    $nd3 = $doc->createElementNS($this->ccnamespaces['lomimscc'],$name);
+            !is_array($value) ? $value = array($value) : null;
+            foreach ($value as $v) {
+                if ($name == 'role') {
+                    $nd3 = $doc->createElementNS($this->ccnamespaces['lomimscc'], $name);
                     $nd2->appendChild($nd3);
-                    $nd4 = $doc->createElementNS($this->ccnamespaces['lomimscc'],'value',$v[0]);
+                    $nd4 = $doc->createElementNS($this->ccnamespaces['lomimscc'], 'value', $v[0]);
                     $nd3->appendChild($nd4);
-                }else{
-                    if ($name == 'date'){
-                        $nd3 = $doc->createElementNS($this->ccnamespaces['lomimscc'],$name);
+                } else {
+                    if ($name == 'date') {
+                        $nd3 = $doc->createElementNS($this->ccnamespaces['lomimscc'], $name);
                         $nd2->appendChild($nd3);
-                        $nd4 = $doc->createElementNS($this->ccnamespaces['lomimscc'],'dateTime',$v[0]);
+                        $nd4 = $doc->createElementNS($this->ccnamespaces['lomimscc'], 'dateTime', $v[0]);
                         $nd3->appendChild($nd4);
-                    }else{
-                        $nd3 = $doc->createElementNS($this->ccnamespaces['lomimscc'],$name,$v[0]);
+                    } else {
+                        $nd3 = $doc->createElementNS($this->ccnamespaces['lomimscc'], $name, $v[0]);
                         $nd2->appendChild($nd3);
                     }
                 }
@@ -532,9 +492,6 @@ class cc_version1 extends cc_version_base {
         return $nd;
     }
 
-
-
-
     /**
      * Create Education Metadata (How To)
      *
@@ -543,24 +500,22 @@ class cc_version1 extends cc_version_base {
      * @param object $xmlnode
      * @return DOMNode
      */
-    protected function create_metadata_educational ($met,DOMDocument  &$doc, $xmlnode){
-        $nd = $doc->createElementNS($this->ccnamespaces['lom'],'educational');
-        $nd2 = $doc->createElementNS($this->ccnamespaces['lom'],'intendedEndUserRole');
-        $nd3 = $doc->createElementNS($this->ccnamespaces['voc'],'vocabulary');
+    public function create_metadata_educational($met, DOMDocument  &$doc, $xmlnode) {
+        $nd  = $doc->createElementNS($this->ccnamespaces['lom'], 'educational');
+        $nd2 = $doc->createElementNS($this->ccnamespaces['lom'], 'intendedEndUserRole');
+        $nd3 = $doc->createElementNS($this->ccnamespaces['voc'], 'vocabulary');
 
         $xmlnode->appendChild($nd);
         $nd->appendChild($nd2);
         $nd2->appendChild($nd3);
 
         foreach ($met->arrayeducational as $name => $value) {
-            !is_array($value)?$value =array($value):null;
-            foreach ($value as $k => $v){
-                ($k);
-                $nd4 = $doc->createElementNS($this->ccnamespaces['voc'],$name,$v[0]);
+            !is_array($value) ? $value = array($value) : null;
+            foreach ($value as $v) {
+                $nd4 = $doc->createElementNS($this->ccnamespaces['voc'], $name, $v[0]);
                 $nd3->appendChild($nd4);
             }
         }
         return $nd;
     }
-
 }
\ No newline at end of file
index 6df8ab7..c65431b 100644 (file)
 // along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
 
 /**
-* @package    backup-convert
-* @subpackage cc-library
-* @copyright  2011 Darko Miletic <dmiletic@moodlerooms.com>
-* @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
-*/
-
-require_once 'cc_version1.php';
+ * @package    backup-convert
+ * @subpackage cc-library
+ * @copyright  2011 Darko Miletic <dmiletic@moodlerooms.com>
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
 
+require_once('cc_version1.php');
 
 /**
  * Version 1.1 class of Common Cartridge
@@ -46,11 +45,11 @@ class cc_version11 extends cc_version1 {
                                    self::basiclti);
 
     /**
-    * Validate if the type are valid or not
-    *
-    * @param string $type
-    * @return bool
-    */
+     * Validate if the type are valid or not
+     *
+     * @param string $type
+     * @return bool
+     */
     public function valid($type) {
         return in_array($type, self::$checker);
     }
@@ -78,9 +77,8 @@ class cc_version11 extends cc_version1 {
             $this->update_attribute($doc, 'identifier'   , $key                , $itemnode);
             $this->update_attribute($doc, 'identifierref', $item->identifierref, $itemnode);
             if (!is_null($item->title)) {
-                $titlenode = $doc->createElementNS($this->ccnamespaces['imscc'],
-                                                       'title',
-                $item->title);
+                $titlenode = $doc->createElementNS($this->ccnamespaces['imscc'], 'title');
+                $titlenode->appendChild(new DOMText($item->title));
                 $itemnode->appendChild($titlenode);
             }
             if ($item->has_child_items()) {
@@ -90,4 +88,33 @@ class cc_version11 extends cc_version1 {
         }
     }
 
+    /**
+     * Create Education Metadata (How To)
+     *
+     * @param object $met
+     * @param DOMDocument $doc
+     * @param object $xmlnode
+     * @return DOMNode
+     */
+    public function create_metadata_educational($met, DOMDocument  &$doc, $xmlnode) {
+        $metadata = $doc->createElementNS($this->ccnamespaces['imscc'], 'metadata');
+        $xmlnode->insertBefore($metadata, $xmlnode->firstChild);
+        $lom = $doc->createElementNS($this->ccnamespaces['lom'], 'lom');
+        $metadata->appendChild($lom);
+        $educational = $doc->createElementNS($this->ccnamespaces['lom'], 'educational');
+        $lom->appendChild($educational);
+
+        foreach ($met->arrayeducational as $value) {
+            !is_array($value) ? $value = array($value) : null;
+            foreach ($value as $v) {
+                $userrole = $doc->createElementNS($this->ccnamespaces['lom'], 'intendedEndUserRole');
+                $educational->appendChild($userrole);
+                $nd4 = $doc->createElementNS($this->ccnamespaces['lom'], 'source', 'IMSGLC_CC_Rolesv1p1');
+                $nd5 = $doc->createElementNS($this->ccnamespaces['lom'], 'value', $v[0]);
+                $userrole->appendChild($nd4);
+                $userrole->appendChild($nd5);
+            }
+        }
+        return $metadata;
+    }
 }
index 9fc230e..5db380c 100644 (file)
@@ -29,85 +29,86 @@ require_once 'cc_organization.php';
  *
  */
 abstract class cc_version_base {
-    protected $_generator           = null;
-    protected $ccnamespaces         = array();
-    protected $isrootmanifest       = false;
-    protected $manifestID           = null;
-    protected $organizationid       = null;
-    public    $resources            = null;
-    protected $metadata             = null;
-    public    $organizations        = null;
-    protected $base                 = null;
-    public    $ccversion            = null;
-    public    $camversion           = null;
+    protected $_generator = null;
+    protected $ccnamespaces = array();
+    protected $isrootmanifest = false;
+    protected $manifestID = null;
+    protected $organizationid = null;
+    public $resources = null;
+    public $resources_ind = null;
+    protected $metadata = null;
+    public $organizations = null;
+    protected $base = null;
+    public $ccversion = null;
+    public $camversion = null;
 
 
-    abstract protected function on_create(DOMDocument &$doc,$rootmanifestnode=null,$nmanifestID=null);
+    abstract protected function on_create(DOMDocument &$doc, $rootmanifestnode = null, $nmanifestID = null);
 
-    abstract protected function create_metadata_manifest (cc_i_metadata_manifest $met,DOMDocument &$doc,$xmlnode=null);
+    abstract protected function create_metadata_manifest(cc_i_metadata_manifest $met, DOMDocument &$doc, $xmlnode = null);
 
-    abstract protected function create_metadata_resource (cc_i_metadata_resource $met,DOMDocument &$doc,$xmlnode=null);
+    abstract protected function create_metadata_resource(cc_i_metadata_resource $met, DOMDocument &$doc, $xmlnode = null);
 
-    abstract protected function create_metadata_file (cc_i_metadata_file $met,DOMDocument &$doc,$xmlnode=null);
+    abstract protected function create_metadata_file(cc_i_metadata_file $met, DOMDocument &$doc, $xmlnode = null);
 
     abstract protected function create_resource(cc_i_resource &$res, DOMDocument &$doc, $xmlnode=null);
 
     abstract protected function create_organization(cc_i_organization &$org, DOMDocument &$doc, $xmlnode=null);
 
-    public function get_cc_namespaces(){
+    public function get_cc_namespaces() {
         return $this->ccnamespaces;
     }
 
-    public function create_manifest(DOMDocument &$doc,$rootmanifestnode=null){
-        return $this->on_create($doc,$rootmanifestnode);
+    public function create_manifest(DOMDocument &$doc, $rootmanifestnode = null) {
+        return $this->on_create($doc, $rootmanifestnode);
     }
 
     public function create_resource_node(cc_i_resource &$res, DOMDocument &$doc, $xmlnode = null) {
-        return $this->create_resource($res,$doc,$xmlnode);
+        return $this->create_resource($res, $doc, $xmlnode);
     }
 
 
-    public function create_metadata_node (&$met, DOMDocument &$doc, $xmlnode = null){
-        return $this->create_metadata_manifest($met,$doc,$xmlnode);
+    public function create_metadata_node(&$met, DOMDocument &$doc, $xmlnode = null) {
+        return $this->create_metadata_manifest($met, $doc, $xmlnode);
     }
 
-    public function create_metadata_resource_node (&$met, DOMDocument &$doc, $xmlnode = null){
-        return $this->create_metadata_resource($met,$doc,$xmlnode);
+    public function create_metadata_resource_node(&$met, DOMDocument &$doc, $xmlnode = null) {
+        return $this->create_metadata_resource($met, $doc, $xmlnode);
     }
 
-    public function create_metadata_file_node (&$met, DOMDocument &$doc, $xmlnode = null){
-        return $this->create_metadata_file($met,$doc,$xmlnode);
+    public function create_metadata_file_node(&$met, DOMDocument &$doc, $xmlnode = null) {
+        return $this->create_metadata_file($met, $doc, $xmlnode);
     }
 
     public function create_organization_node(cc_i_organization &$org, DOMDocument &$doc, $xmlnode = null) {
-        return $this->create_organization($org,$doc,$xmlnode);
+        return $this->create_organization($org, $doc, $xmlnode);
     }
 
-    public function manifestID(){
+    public function manifestID() {
         return $this->manifestID;
     }
 
-    public function set_manifestID($id){
+    public function set_manifestID($id) {
         $this->manifestID = $id;
     }
 
-    public function get_base(){
+    public function get_base() {
         return $this->base;
     }
 
-    public function set_base($baseval){
+    public function set_base($baseval) {
         $this->base = $baseval;
     }
 
     public function import_resources(DOMElement &$node, cc_i_manifest &$doc) {
-        if (is_null($this->resources)){
+        if (is_null($this->resources)) {
             $this->resources = array();
         }
-        $nlist = $node->getElementsByTagNameNS($this->ccnamespaces['imscc'],'resource');
+        $nlist = $node->getElementsByTagNameNS($this->ccnamespaces['imscc'], 'resource');
         if (is_object($nlist)) {
             foreach ($nlist as $nd) {
-                $sc = new cc_resource($doc,$nd);
-                $this->resources[$sc->identifier]=$sc;
+                $sc = new cc_resource($doc, $nd);
+                $this->resources[$sc->identifier] = $sc;
             }
         }
     }
@@ -116,11 +117,11 @@ abstract class cc_version_base {
         if (is_null($this->organizations)) {
             $this->organizations = array();
         }
-        $nlist = $node->getElementsByTagNameNS($this->ccnamespaces['imscc'],'organization');
+        $nlist = $node->getElementsByTagNameNS($this->ccnamespaces['imscc'], 'organization');
         if (is_object($nlist)) {
             foreach ($nlist as $nd) {
-                $sc = new cc_organization($nd,$doc);
-                $this->organizations[$sc->identifier]=$sc;
+                $sc = new cc_organization($nd, $doc);
+                $this->organizations[$sc->identifier] = $sc;
             }
         }
     }
index e01557c..66fc55c 100644 (file)
 // You should have received a copy of the GNU General Public License
 // along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
 
-require_once dirname(__FILE__) .'/../xmlbase.php';
-require_once 'cssparser.php';
-require_once 'pathutils.php';
-
-
+require_once(dirname(__FILE__) .'/../xmlbase.php');
+require_once('cssparser.php');
+require_once('pathutils.php');
 
 /**
  *
  * Older version better suited for PHP < 5.2
  * @deprecated
- * @param unknown_type $url
+ * @param mixed $url
  * @return boolean
  */
 function is_url_deprecated($url) {
@@ -51,118 +49,83 @@ function is_url($url) {
     return $result;
 }
 
-function GetDepFiles($manifestroot, $fname,$folder,&$filenames) {
-    $extension      = pathinfo($fname, PATHINFO_EXTENSION);
-    $filenames      = array();
-    $dcx            = new XMLGenericDocument();
-    $result         = true;
-
-    switch ($extension){
-        case 'xml':
-                 $result = @$dcx->loadXMLFile($manifestroot.$folder.$fname);
-                 if (!$result) {
-                    $result = @$dcx->loadXMLFile($manifestroot.DIRECTORY_SEPARATOR.$folder.DIRECTORY_SEPARATOR.$fname);
-                 }
-                 GetDepFilesXML($manifestroot, $fname,$filenames,$dcx, $folder);
-            break;
-        case 'html':
-        case 'htm':
-                 $result = @$dcx->loadHTMLFile($manifestroot.$folder.$fname);
-                 if (!$result) {
-                    $result = @$dcx->loadHTMLFile($manifestroot.DIRECTORY_SEPARATOR.$folder.DIRECTORY_SEPARATOR.$fname);
-                 }
-                 GetDepFilesHTML($manifestroot, $fname,$filenames,$dcx, $folder);
-            break;
-    }
-    return $result;
-}
-
-
-
-function GetDepFilesXML ($manifestroot, $fname,&$filenames,&$dcx, $folder){
-        $nlist = $dcx->nodeList("//img/@src | //attachments/attachment/@href  | //link/@href | //script/@src");
-        $css_obj_array = array();
-        foreach ($nlist as $nl) {
-            $item = $folder.$nl->nodeValue;
-            $path_parts = pathinfo($item);
-            $fname = $path_parts['basename'];
-            $ext   = array_key_exists('extension',$path_parts) ? $path_parts['extension'] : '';
-            if (!is_url($nl->nodeValue)) {
-              //$file =   $folder.$nl->nodeValue; // DEPENDERA SI SE QUIERE Q SEA RELATIVO O ABSOLUTO
-              $file =   $nl->nodeValue;
-              toNativePath($file);
-              $filenames[]=$file;
-            }
+function GetDepFiles($manifestroot, $fname, $folder, &$filenames) {
+    static $types = array('xhtml' => true, 'html' => true, 'htm' => true);
+    $extension = strtolower(trim(pathinfo($fname, PATHINFO_EXTENSION)));
+    $filenames = array();
+    if (isset($types[$extension])) {
+        $dcx = new XMLGenericDocument();
+        $filename = $manifestroot.$folder.$fname;
+        if (!file_exists($filename)) {
+            $filename = $manifestroot.DIRECTORY_SEPARATOR.$folder.DIRECTORY_SEPARATOR.$fname;
         }
-        $dcx->registerNS('qti','http://www.imsglobal.org/xsd/imscc/ims_qtiasiv1p2.xsd');
-        $dcx->resetXpath();
-        $nlist = $dcx->nodeList("//qti:mattext | //text");
-        $dcx2 = new XMLGenericDocument();
-        foreach ($nlist as $nl) {
-            if ($dcx2->loadString($nl->nodeValue)){
-                GetDepFilesHTML($manifestroot,$fname,$filenames,$dcx2,$folder);
+        if (file_exists($filename)) {
+            $res = $dcx->loadHTMLFile($filename);
+            if ($res) {
+                GetDepFilesHTML($manifestroot, $fname, $filenames, $dcx, $folder);
             }
         }
+    }
 }
 
-
-
-function GetDepFilesHTML ($manifestroot, $fname, &$filenames, &$dcx, $folder){
-        $dcx->resetXpath();
-        $nlist = $dcx->nodeList("//img/@src | //link/@href | //script/@src | //a[not(starts-with(@href,'#'))]/@href");
-        $css_obj_array=array();
-        foreach ($nlist as $nl) {
-            $item = $folder.$nl->nodeValue;
-            $path_parts = pathinfo($item);
-            $fname = $path_parts['basename'];
-            $ext   = array_key_exists('extension',$path_parts) ? $path_parts['extension'] : '';
-            if (!is_url($folder.$nl->nodeValue) && !is_url($nl->nodeValue)) {
-              $path = $folder.$nl->nodeValue;
-              $file = fullPath($path,"/");
-              toNativePath($file);
-              if (file_exists($manifestroot.DIRECTORY_SEPARATOR.$file)) {
-                  $filenames[]= $file;
-              }
+function GetDepFilesHTML($manifestroot, $fname, &$filenames, &$dcx, $folder) {
+    $dcx->resetXpath();
+    $nlist         = $dcx->nodeList("//img/@src | //link/@href | //script/@src | //a[not(starts-with(@href,'#'))]/@href");
+    $css_obj_array = array();
+    foreach ($nlist as $nl) {
+        $item       = $folder.$nl->nodeValue;
+        $path_parts = pathinfo($item);
+        $fname      = $path_parts['basename'];
+        $ext        = array_key_exists('extension', $path_parts) ? $path_parts['extension'] : '';
+        if (!is_url($folder.$nl->nodeValue) && !is_url($nl->nodeValue)) {
+            $path = $folder.$nl->nodeValue;
+            $file = fullPath($path, "/");
+            toNativePath($file);
+            if (file_exists($manifestroot.DIRECTORY_SEPARATOR.$file)) {
+                $filenames[$file] = $file;
             }
-            if ($ext == 'css') {
-                $css = new cssparser();
-                $css->Parse($dcx->filePath().$nl->nodeValue);
-                $css_obj_array[$item]=$css;
+        }
+        if ($ext == 'css') {
+            $css = new cssparser();
+            $css->Parse($dcx->filePath().$nl->nodeValue);
+            $css_obj_array[$item] = $css;
+        }
+    }
+    $nlist = $dcx->nodeList("//*/@class");
+    foreach ($nlist as $nl) {
+        $item = $folder.$nl->nodeValue;
+        foreach ($css_obj_array as $csskey => $cssobj) {
+            $bimg  = $cssobj->Get($item, "background-image");
+            $limg  = $cssobj->Get($item, "list-style-image");
+            $npath = pathinfo($csskey);
+            if ((!empty($bimg)) && ($bimg != 'none')) {
+                $value             = stripUrl($bimg, $npath['dirname'].'/');
+                $filenames[$value] = $value;
+            } else if ((!empty($limg)) && ($limg != 'none')) {
+                $value             = stripUrl($limg, $npath['dirname'].'/');
+                $filenames[$value] = $value;
             }
         }
-        $nlist = $dcx->nodeList("//*/@class");
-        foreach ($nlist as $nl) {
-            $item = $folder.$nl->nodeValue;
+    }
+    $elems_to_check = array("body", "p", "ul", "h4", "a", "th");
+    $do_we_have_it  = array();
+    foreach ($elems_to_check as $elem) {
+        $do_we_have_it[$elem] = ($dcx->nodeList("//".$elem)->length > 0);
+    }
+    foreach ($elems_to_check as $elem) {
+        if ($do_we_have_it[$elem]) {
             foreach ($css_obj_array as $csskey => $cssobj) {
-                $bimg = $cssobj->Get($item,"background-image");
-                $limg = $cssobj->Get($item,"list-style-image");
+                $sb    = $cssobj->Get($elem, "background-image");
+                $sbl   = $cssobj->Get($elem, "list-style-image");
                 $npath = pathinfo($csskey);
-                if ((!empty($bimg))&& ($bimg != 'none')) {
-                    $filenames[] = stripUrl($bimg,$npath['dirname'].'/');
-                } else
-                if ((!empty($limg))&& ($limg != 'none')) {
-                    $filenames[] = stripUrl($limg,$npath['dirname'].'/');
-                }
-            }
-        }
-        $elems_to_check = array("body","p","ul","h4","a","th");
-        $do_we_have_it = array();
-        foreach ($elems_to_check as $elem) {
-            $do_we_have_it[$elem]=($dcx->nodeList("//".$elem)->length > 0);
-        }
-        foreach ($elems_to_check as $elem) {
-            if ($do_we_have_it[$elem]) {
-                foreach ($css_obj_array as $csskey => $cssobj) {
-                    $sb = $cssobj->Get($elem, "background-image");
-                    $sbl = $cssobj->Get($elem,"list-style-image");
-                    $npath = pathinfo($csskey);
-                    if ((!empty($sb)) && ($sb != 'none')) {
-                        $filenames[] = stripUrl($sb,$npath['dirname'].'/');
-                    } else
-                    if ((!empty($sbl)) && ($sbl != 'none')) {
-                        $filenames[] = stripUrl($sbl,$npath['dirname'].'/');
-                    }
+                if ((!empty($sb)) && ($sb != 'none')) {
+                    $value             = stripUrl($sb, $npath['dirname'].'/');
+                    $filenames[$value] = $value;
+                } else if ((!empty($sbl)) && ($sbl != 'none')) {
+                    $value             = stripUrl($sbl, $npath['dirname'].'/');
+                    $filenames[$value] = $value;
                 }
             }
         }
+    }
 }
\ No newline at end of file
index c85cbe9..0bc406d 100644 (file)
  *
  */
 
-require_once 'gral_lib/cssparser.php';
+require_once('gral_lib/cssparser.php');
 
 /**
  * Base XML class
  *
  */
 class XMLGenericDocument {
-
-
-    private   $charset;
+    private $charset;
     /**
-     *
      * Document
      * @var DOMDocument
      */
-    public    $doc = null;
+    public $doc = null;
     /**
      *
      * Xpath
      * @var DOMXPath
      */
     protected $dxpath = null;
-    protected   $filename;
-    private   $filepath;
-    private   $isloaded         = false;
-    private   $arrayPrefixNS    = array();
-    private   $is_html          = false;
-
+    protected $filename;
+    private $filepath;
+    private $isloaded = false;
+    private $arrayPrefixNS = array();
+    private $is_html = false;
 
     /**
-    * @param string $value
-    * @return string
-    */
+     * @param string $value
+     * @return string
+     */
     public static function safexml($value) {
         $result = htmlspecialchars(html_entity_decode($value, ENT_QUOTES, 'UTF-8'),
                                    ENT_NOQUOTES,
@@ -53,51 +49,51 @@ class XMLGenericDocument {
         return $result;
     }
 
-    function __construct($ch = 'UTF-8',$validatenow=true){
+    function __construct($ch = 'UTF-8', $validatenow = true) {
         $this->charset = $ch;
         $this->documentInit();
         $this->doc->validateOnParse = $validatenow;
     }
 
-    function __destruct(){
+    function __destruct() {
         $this->dxpath = null;
-        $this->doc = null;
+        $this->doc    = null;
     }
 
-    private function documentInit($withonCreate=true) {
+    private function documentInit($withonCreate = true) {
         $hg = false;
-        if ($this->isloaded){
+        if ($this->isloaded) {
             $guardstate = $this->doc->validateOnParse;
             $hg = true;
             unset($this->dxpath);
             unset($this->doc);
             $this->isloaded = false;
           }
-        $this->doc = new DOMDocument("1.0",$this->charset);
+        $this->doc = new DOMDocument("1.0", $this->charset);
         $this->doc->strictErrorChecking = true;
         if ($hg) {
             $this->doc->validateOnParse = $guardstate;
         }
         $this->doc->formatOutput = true;
         $this->doc->preserveWhiteSpace = true;
-        if($withonCreate) {
+        if ($withonCreate) {
             $this->on_create();
         }
     }
 
-    public function viewXML (){
+    public function viewXML() {
         return $this->doc->saveXML();
     }
 
     public function registerNS($prefix, $nsuri) {
-        $this->arrayPrefixNS[$prefix]=$nsuri;
+        $this->arrayPrefixNS[$prefix] = $nsuri;
     }
 
     public function load($fname) {
-    // Sine xml will remain loaded should the repeated load fail we should recreate document to be empty.
+        // Sine xml will remain loaded should the repeated load fail we should recreate document to be empty.
         $this->documentInit(false);
         $this->isloaded = $this->doc->load($fname);
-        if ($this->isloaded){
+        if ($this->isloaded) {
             $this->filename = $fname;
             $this->processPath();
             $this->is_html = false;
@@ -105,7 +101,7 @@ class XMLGenericDocument {
         return $this->on_load();
     }
 
-    public function loadUrl($url){
+    public function loadUrl($url) {
         $this->documentInit();
         $this->isloaded = true;
         $this->doc->loadXML( file_get_contents($url) );
@@ -113,7 +109,7 @@ class XMLGenericDocument {
         return $this->on_load();
     }
 
-    public function loadHTML ($content){
+    public function loadHTML($content) {
         $this->documentInit();
         $this->doc->validateOnParse = false;
         $this->isloaded = true;
@@ -122,7 +118,7 @@ class XMLGenericDocument {
         return $this->on_load();
     }
 
-    public function loadXML ($content){
+    public function loadXML($content) {
         $this->documentInit();
         $this->doc->validateOnParse = false;
         $this->isloaded = true;
@@ -131,9 +127,9 @@ class XMLGenericDocument {
         return $this->on_load();
     }
 
-    public function loadHTMLFile($fname){
-      //Sine xml will remain loaded should the repeated load fail
-      //we shoudl recreate document to be empty
+    public function loadHTMLFile($fname) {
+        // Sine xml will remain loaded should the repeated load fail
+        // we should recreate document to be empty.
         $this->documentInit();
         $this->doc->validateOnParse = false;
         $this->isloaded = $this->doc->loadHTMLFile($fname);
@@ -145,29 +141,28 @@ class XMLGenericDocument {
         return $this->on_load();
     }
 
-    public function loadXMLFile($fname){
-    //Sine xml will remain loaded should the repeated load fail
-    //we shoudl recreate document to be empty
+    public function loadXMLFile($fname) {
+        // Sine xml will remain loaded should the repeated load fail
+        // we should recreate document to be empty.
         $this->documentInit();
         $this->doc->validateOnParse = false;
         $this->isloaded = $this->doc->load($fname);
         if ($this->isloaded) {
             $this->filename = $fname;
             $this->processPath();
-            $this->is_html=true;
+            $this->is_html = true;
         }
         return $this->on_load();
     }
 
 
-    public function loadString($content){
+    public function loadString($content) {
 
-        $this->doc = new DOMDocument("1.0",$this->charset);
+        $this->doc = new DOMDocument("1.0", $this->charset);
         $content = '<virtualtag>'.$content.'</virtualtag>';
         $this->doc->loadXML($content);
 
         return true;
-
     }
 
     public function save() {
@@ -193,18 +188,16 @@ class XMLGenericDocument {
         return $this->doc->validate();
     }
 
-    public function attributeValue($path,$attrname,$node=null) {
+    public function attributeValue($path, $attrname, $node = null) {
         $this->chkxpath();
         $result = null;
         $resultlist = null;
         if (is_null($node)) {
             $resultlist = $this->dxpath->query($path);
         } else {
-            $resultlist = $this->dxpath->query($path,$node);
+            $resultlist = $this->dxpath->query($path, $node);
         }
-        if ( is_object($resultlist) &&
-        ($resultlist->length > 0) &&
-        $resultlist->item(0)->hasAttribute($attrname)){
+        if (is_object($resultlist) && ($resultlist->length > 0) && $resultlist->item(0)->hasAttribute($attrname)) {
             $result = $resultlist->item(0)->getAttribute($attrname);
         }
         return $result;
@@ -218,7 +211,7 @@ class XMLGenericDocument {
      * @param int $count
      * @return string
      */
-    public function nodeValue($path, $node = null, $count = 1){
+    public function nodeValue($path, $node = null, $count = 1) {
         $nd = $this->node($path, $node, $count);
         return $this->nodeTextValue($nd);
     }
@@ -229,17 +222,17 @@ class XMLGenericDocument {
      * @param DOMNode $node
      * @return string
      */
-    public function nodeTextValue($node){
+    public function nodeTextValue($node) {
         $result = '';
         if (is_object($node)) {
             if ($node->hasChildNodes()) {
                 $chnodesList = $node->childNodes;
                 $types = array(XML_TEXT_NODE, XML_CDATA_SECTION_NODE);
                 foreach ($chnodesList as $chnode) {
-                    if (in_array($chnode->nodeType, $types)){
-                           $result .= $chnode->wholeText;
-                      }
-                  }
+                    if (in_array($chnode->nodeType, $types)) {
+                        $result .= $chnode->wholeText;
+                    }
+                }
             }
         }
         return $result;
@@ -256,9 +249,8 @@ class XMLGenericDocument {
     public function node($path, $nd = null, $count = 1) {
         $result = null;
         $resultlist = $this->nodeList($path,$nd);
-        if ( is_object($resultlist) &&
-        ($resultlist->length > 0) ){
-            $result = $resultlist->item($count -1);
+        if (is_object($resultlist) && ($resultlist->length > 0)) {
+            $result = $resultlist->item($count - 1);
         }
         return $result;
     }
@@ -270,7 +262,7 @@ class XMLGenericDocument {
      * @param DOMNode $node
      * @return DOMNodeList
      */
-    public function nodeList($path,$node=null){
+    public function nodeList($path, $node = null) {
 
         $this->chkxpath();
 
@@ -278,7 +270,7 @@ class XMLGenericDocument {
         if (is_null($node)) {
             $resultlist = $this->dxpath->query($path);
         } else {
-            $resultlist = $this->dxpath->query($path,$node);
+            $resultlist = $this->dxpath->query($path, $node);
         }
         return $resultlist;
     }
@@ -393,12 +385,25 @@ class XMLGenericDocument {
         return $node->appendChild($this->create_attribute_ns($namespace, $name, $value));
     }
 
-    public function fileName() {return $this->filename;}
-    public function filePath() {return $this->filepath;}
+    public function fileName() {
+        return $this->filename;
+    }
+
+    public function filePath() {
+        return $this->filepath;
+    }
+
+    protected function on_load() {
+        return $this->isloaded;
+    }
 
-    protected function on_load() {return $this->isloaded;}
-    protected function on_save() {return true;}
-    protected function on_create() {return true;}
+    protected function on_save() {
+        return true;
+    }
+
+    protected function on_create() {
+        return true;
+    }
 
     public function resetXpath() {
         $this->dxpath = null;
@@ -406,16 +411,16 @@ class XMLGenericDocument {
     }
 
     private function chkxpath() {
-        if (!isset($this->dxpath) || is_null($this->dxpath)){
+        if (!isset($this->dxpath) || is_null($this->dxpath)) {
             $this->dxpath = new DOMXPath($this->doc);
             foreach ($this->arrayPrefixNS as $nskey => $nsuri) {
-                $this->dxpath->registerNamespace($nskey,$nsuri);
+                $this->dxpath->registerNamespace($nskey, $nsuri);
             }
         }
     }
 
-    protected function processPath(){
-        $path_parts = pathinfo($this->filename);
-        $this->filepath = array_key_exists('dirname',$path_parts) ? $path_parts['dirname']."/" : '';
+    protected function processPath() {
+        $path_parts     = pathinfo($this->filename);
+        $this->filepath = array_key_exists('dirname', $path_parts) ? $path_parts['dirname']."/" : '';
     }
 }
index 4f441ba..dfff6b2 100644 (file)
@@ -25,9 +25,10 @@ defined('MOODLE_INTERNAL') or die('Direct access to this script is forbidden.');
 
 class entities {
     /**
-     *
      * Prepares convert for inclusion into XML
+     *
      * @param string $value
+     * @return string
      */
     public static function safexml($value) {
         $result = htmlspecialchars(html_entity_decode($value, ENT_QUOTES, 'UTF-8'),
@@ -57,7 +58,7 @@ class entities {
             $result = mb_convert_encoding($content, 'UTF-8', $encoding);
         }
 
-        // See if we can strip off body tag and anything outside of it
+        // See if we can strip off body tag and anything outside of it.
         foreach (array('body', 'html') as $tagname) {
             $regex = str_replace('##', $tagname, "/<##[^>]*>(.+)<\/##>/is");
             if (preg_match($regex, $result, $matches)) {
@@ -68,11 +69,11 @@ class entities {
         return $result;
     }
 
-    public function load_xml_resource ($path_to_file) {
+    public function load_xml_resource($path_to_file) {
 
         $resource = new DOMDocument();
 
-        cc2moodle::log_action('Load the XML resource file: ' . $path_to_file);
+        cc2moodle::log_action('Load the XML resource file: '.$path_to_file);
 
         if (!$resource->load($path_to_file)) {
             cc2moodle::log_action('Cannot load the XML resource file: ' . $path_to_file, true);
@@ -81,11 +82,9 @@ class entities {
         return $resource;
     }
 
-    public function update_sources ($html, $root_path = '') {
-
-        $document = new DOMDocument();
+    public function update_sources($html, $root_path = '') {
 
-        @$document->loadHTML($html);
+        $document = $this->load_html($html);
 
         $tags = array('img' => 'src' , 'a' => 'href');
 
@@ -108,18 +107,17 @@ class entities {
             }
         }
 
-        $html = $this->clear_doctype($document->saveHTML());
+        $html = $this->html_insidebody($document);
 
         return $html;
     }
 
-    public function full_path ($path, $dir_sep = DIRECTORY_SEPARATOR) {
+    public function full_path($path, $dir_sep = DIRECTORY_SEPARATOR) {
 
         $token = '$IMS-CC-FILEBASE$';
         $path = str_replace($token, '', $path);
 
         if (is_string($path) && ($path != '')) {
-            $dir_sep;
             $dot_dir = '.';
             $up_dir = '..';
             $length = strlen($path);
@@ -154,13 +152,11 @@ class entities {
         }
 
         return $result;
-
     }
 
     public function include_titles ($html) {
 
-        $document = new DOMDocument();
-        @$document->loadHTML($html);
+        $document = $this->load_html($html);
 
         $images = $document->getElementsByTagName('img');
 
@@ -180,18 +176,17 @@ class entities {
             $image->setAttribute('title', $title);
         }
 
-        $html = $this->clear_doctype($document->saveHTML());
+        $html = $this->html_insidebody($document);
 
         return $html;
     }
 
     public function get_external_xml ($identifier) {
 
-        $response = '';
-
         $xpath = cc2moodle::newx_path(cc2moodle::$manifest, cc2moodle::$namespaces);
 
-        $files = $xpath->query('/imscc:manifest/imscc:resources/imscc:resource[@identifier="' . $identifier . '"]/imscc:file/@href');
+        $files = $xpath->query('/imscc:manifest/imscc:resources/imscc:resource[@identifier="'.
+            $identifier.'"]/imscc:file/@href');
 
         if (empty($files)) {
             $response = '';
@@ -202,7 +197,7 @@ class entities {
         return $response;
     }
 
-    public function move_files ($files, $destination_folder) {
+    public function move_files($files, $destination_folder) {
         global $CFG;
 
         if (!empty($files)) {
@@ -245,7 +240,7 @@ class entities {
 
             if (!empty($files) && ($files->length > 0)) {
                 foreach ($files as $file) {
-                    //omit html files
+                    // Omit html files.
                     $ext = strtolower(pathinfo($file->nodeValue, PATHINFO_EXTENSION));
                     if (in_array($ext, array('html', 'htm', 'xhtml'))) {
                         continue;
@@ -256,7 +251,7 @@ class entities {
             unset($files);
         }
 
-        //are there any labels?
+        // Are there any labels?
         $xquery = "//imscc:item/imscc:item/imscc:item[imscc:title][not(@identifierref)]";
         $labels = $xpath->query($xquery);
         if (!empty($labels) && ($labels->length > 0)) {
@@ -268,7 +263,7 @@ class entities {
             if (!file_exists($dpath)) {
                 mkdir($dpath, $CFG->directorypermissions, true);
             }
-            //copy the folder.gif file
+            // Copy the folder.gif file.
             $folder_gif = "{$CFG->dirroot}/pix/i/files.gif";
             copy($folder_gif, $fpath);
             $all_files[] = $rfpath;
@@ -289,13 +284,36 @@ class entities {
 
     }
 
-    private function clear_doctype ($html) {
+    /**
+     * @param string $html
+     * @return DOMDocument
+     */
+    private function load_html($html) {
+        // Need to make sure that the html passed has charset meta tag.
+        $metatag = '<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />';
+        if (strpos($html, $metatag) === false) {
+            $html = '<html><head>'.$metatag.'</head><body>'.$html.'</body></html>';
+        }
+
+        $document = new DOMDocument();
+        @$document->loadHTML($html);
+
+        return $document;
+    }
 
-        return preg_replace('/^<!DOCTYPE.+?>/',
-                            '',
-                            str_replace(array('<html>' , '</html>' , '<body>' , '</body>'),
-                                        array('' , '' , '' , ''),
-                                        $html));
+    /**
+     * @param DOMDocument $domdocument
+     * @return string
+     */
+    private function html_insidebody($domdocument) {
+        $html = '';
+        $bodyitems = $domdocument->getElementsByTagName('body');
+        if ($bodyitems->length > 0) {
+            $body = $bodyitems->item(0);
+            $html = str_ireplace(array('<body>', '</body>'), '', $body->C14N());
+        }
+
+        return $html;
     }
 
     public function generate_random_string ($length = 6) {
@@ -317,7 +335,7 @@ class entities {
         return $response;
     }
 
-    public function truncate_text ($text, $max, $remove_html) {
+    public function truncate_text($text, $max, $remove_html) {
 
         if ($max > 10) {
             $text = substr($text, 0, ($max - 6)) . ' [...]';
index 4bb8c32..56c42de 100644 (file)
@@ -88,13 +88,17 @@ class cc_quiz extends entities {
 
                     if (!empty($assessment_file)) {
 
-                        $assessment = $this->load_xml_resource(cc2moodle::$path_to_manifest_folder . DIRECTORY_SEPARATOR . $assessment_file);
+                        $assessment = $this->load_xml_resource(
+                            cc2moodle::$path_to_manifest_folder . DIRECTORY_SEPARATOR . $assessment_file
+                        );
 
                         if (!empty($assessment)) {
 
                             $replace_values = array('unlimited' => 0);
 
-                            $questions = $this->get_questions($assessment, $last_question_id, $last_answer_id, dirname($assessment_file), $is_question_bank);
+                            $questions = $this->get_questions(
+                                $assessment, $last_question_id, $last_answer_id, dirname($assessment_file), $is_question_bank
+                            );
                             $question_count = count($questions);
 
                             if (!empty($question_count)) {
@@ -105,8 +109,10 @@ class cc_quiz extends entities {
                                 $instances[$instance['resource_indentifier']]['id'] = $last_instance_id;
                                 $instances[$instance['resource_indentifier']]['title'] = $instance['title'];
                                 $instances[$instance['resource_indentifier']]['is_question_bank'] = $is_question_bank;
-                                $instances[$instance['resource_indentifier']]['options']['timelimit'] = $this->get_global_config($assessment, 'qmd_timelimit', 0);
-                                $instances[$instance['resource_indentifier']]['options']['max_attempts'] = $this->get_global_config($assessment, 'cc_maxattempts', 0, $replace_values);
+                                $instances[$instance['resource_indentifier']]['options']['timelimit'] =
+                                    $this->get_global_config($assessment, 'qmd_timelimit', 0);
+                                $instances[$instance['resource_indentifier']]['options']['max_attempts'] =
+                                    $this->get_global_config($assessment, 'cc_maxattempts', 0, $replace_values);
                             }
                         }
                     }
@@ -148,7 +154,7 @@ class cc_quiz extends entities {
                                 $instance['options']['max_attempts'],
                                 $instance['options']['timelimit'],
                                 $node_course_modules_quiz_question_instances,
-                                $node_course_modules_quiz_feedback); //this one has tags
+                                $node_course_modules_quiz_feedback); // This one has tags.
 
         $node_question_mod = str_replace($find_tags, $replace_values, $sheet_question_mod);
 
@@ -194,10 +200,14 @@ class cc_quiz extends entities {
 
             foreach ($instance['questions'] as $question) {
                 $replace_values = array($question['id'] , $question['id']);
-                $node_course_module_mod_quiz_questions_instances .= str_replace($find_tags, $replace_values, $sheet_question_mod_instance);
+                $node_course_module_mod_quiz_questions_instances .= str_replace(
+                    $find_tags, $replace_values, $sheet_question_mod_instance
+                );
             }
 
-            $node_course_module_mod_quiz_questions_instances = str_replace($find_tags, $replace_values, $node_course_module_mod_quiz_questions_instances);
+            $node_course_module_mod_quiz_questions_instances = str_replace(
+                $find_tags, $replace_values, $node_course_module_mod_quiz_questions_instances
+            );
         }
 
         return $node_course_module_mod_quiz_questions_instances;
@@ -218,7 +228,7 @@ class cc_quiz extends entities {
         return $questions_string;
     }
 
-    private function create_node_course_question_categories ($instances) {
+    private function create_node_course_question_categories($instances) {
 
         $sheet_question_categories = cc2moodle::loadsheet(SHEET_COURSE_QUESTION_CATEGORIES);
 
@@ -227,7 +237,8 @@ class cc_quiz extends entities {
             $node_course_question_categories_question_category = '';
 
             foreach ($instances as $instance) {
-                $node_course_question_categories_question_category .= $this->create_node_course_question_categories_question_category($instance);
+                $node_course_question_categories_question_category .=
+                    $this->create_node_course_question_categories_question_category($instance);
             }
 
             $find_tags = array('[#node_course_question_categories_question_category#]');
@@ -250,8 +261,10 @@ class cc_quiz extends entities {
                            '[#quiz_stamp#]',
                            '[#node_course_question_categories_question_category_questions#]');
 
-        $node_course_question_categories_questions = $this->create_node_course_question_categories_question_category_question($instance);
-        $node_course_question_categories_questions = empty($node_course_question_categories_questions) ? '' : $node_course_question_categories_questions;
+        $node_course_question_categories_questions =
+            $this->create_node_course_question_categories_question_category_question($instance);
+        $node_course_question_categories_questions =
+            empty($node_course_question_categories_questions) ? '' : $node_course_question_categories_questions;
 
         $quiz_stamp = 'localhost+' . time() . '+' . $this->generate_random_string(6);
 
@@ -653,8 +666,9 @@ class cc_quiz extends entities {
 
         $question_cc_type = $this->get_question_type($identifier, $assessment);
         $question_cc_type = $question_cc_type['cc'];
+        $is_multiresponse = ($question_cc_type == CC_QUIZ_MULTIPLE_RESPONSE);
 
-        if ($question_cc_type == CC_QUIZ_MULTIPLE_CHOICE || $question_cc_type == CC_QUIZ_MULTIPLE_RESPONSE || $question_cc_type == CC_QUIZ_TRUE_FALSE) {
+        if ($question_cc_type == CC_QUIZ_MULTIPLE_CHOICE || $is_multiresponse || $question_cc_type == CC_QUIZ_TRUE_FALSE) {
 
             $query_answers = '//xmlns:item[@ident="' . $identifier . '"]/xmlns:presentation/xmlns:response_lid/xmlns:render_choice/xmlns:response_label';
             $query_answers_with_flow = '//xmlns:item[@ident="' . $identifier . '"]/xmlns:presentation/xmlns:flow/xmlns:response_lid/xmlns:render_choice/xmlns:response_label';
@@ -704,7 +718,19 @@ class cc_quiz extends entities {
             }
 
             if (!empty($response_items)) {
-
+                if ($is_multiresponse) {
+                    $correct_answer_score = 0;
+                    //get the correct answers count
+                    $canswers_query = "//xmlns:item[@ident='{$identifier}']//xmlns:setvar[@varname='SCORE'][.=100]/../xmlns:conditionvar//xmlns:varequal[@case='Yes'][not(parent::xmlns:not)]";
+                    $canswers = $xpath->query($canswers_query);
+                    if ($canswers->length > 0) {
+                        $correct_answer_score = round(1.0 / (float)$canswers->length, 7); //weird
+                        $correct_answers_ident = array();
+                        foreach ($canswers as $cnode) {
+                            $correct_answers_ident[$cnode->nodeValue] = true;
+                        }
+                    }
+                }
                 foreach ($response_items as $response_item) {
 
                     $last_answer_id++;
@@ -719,6 +745,10 @@ class cc_quiz extends entities {
 
                     $answer_score = $this->get_score($assessment, $answer_identifier, $identifier);
 
+                    if ($is_multiresponse && isset($correct_answers_ident[$answer_identifier])) {
+                        $answer_score = $correct_answer_score;
+                    }
+
                     $answers[] = array('id' => $last_answer_id,
                                        'title' => $answer_title,
                                        'score' => $answer_score,
@@ -757,7 +787,7 @@ class cc_quiz extends entities {
             }
         }
 
-        $score = empty($score) ? 0 : $score;
+        $score = empty($score) ? 0 : sprintf("%.7F", $score);
 
         return $score;
     }
index 9472607..5410caa 100644 (file)
@@ -304,8 +304,9 @@ class cc11_quiz extends entities11 {
                 $question_type_node = ($question_moodle_type == MOODLE_QUIZ_ESSAY) ? $this->create_node_course_question_categories_question_category_question_eesay($question) : $question_type_node;
                 $question_type_node = ($question_moodle_type == MOODLE_QUIZ_SHORTANSWER) ? $this->create_node_course_question_categories_question_category_question_shortanswer($question) : $question_type_node;
 
+                $questionname = !empty($question['name']) ? self::safexml($question['name']) : self::safexml($this->truncate_text($question['title'], 255, true));
                 $replace_values = array($question['id'],
-                                        self::safexml($this->truncate_text($question['title'], 255, true)),
+                                        $questionname,
                                         self::safexml($question['title']),
                                         $question_moodle_type,
                                         self::safexml($question['feedback']),
@@ -365,7 +366,12 @@ class cc11_quiz extends entities11 {
                     $question_title = $this->update_sources($question_title, $root_path);
                     $question_title = !empty($question_title) ? str_replace("%24", "\$", $this->include_titles($question_title)) : '';
 
+                    // This attribute is not IMSCC spec, but it is included in Moodle 2.x export of IMS1.1
+                    $questionname = $xpath->query('@title', $question_item);
+                    $questionname = !empty($questionname->item(0)->nodeValue) ? $questionname->item(0)->nodeValue : '';
+
                     $questions[$question_identifier]['title'] = $question_title;
+                    $questions[$question_identifier]['name'] = $questionname;
                     $questions[$question_identifier]['identifier'] = $question_identifier;
                     $questions[$question_identifier]['moodle_type'] = $question_type['moodle'];
                     $questions[$question_identifier]['cc_type'] = $question_type['cc'];
@@ -507,63 +513,90 @@ class cc11_quiz extends entities11 {
 
         $xpath = cc112moodle::newx_path($assessment, cc112moodle::getquizns());
 
-        $answers_fib = array();
+        $correctanswersfib = array();
+        $incorrectanswersfib = array();
 
         $response_items = $xpath->query('//xmlns:item[@ident="' . $question_identifier . '"]/xmlns:resprocessing/xmlns:respcondition');
 
-        foreach ($response_items as $response_item) {
+        $correctrespcond = $xpath->query('//xmlns:item[@ident="' . $question_identifier . '"]/xmlns:resprocessing/xmlns:respcondition/xmlns:setvar[text()="100"]/..');
+        $correctanswers = $xpath->query('xmlns:conditionvar/xmlns:varequal', $correctrespcond->item(0));
 
-            $setvar = $xpath->query('xmlns:setvar', $response_item);
-            $setvar = is_object($setvar->item(0)) ? $setvar->item(0)->nodeValue : '';
+        // Correct answers.
+        foreach ($correctanswers as $correctans) {
+            $answertitle = !empty($correctans->nodeValue) ? $correctans->nodeValue : '';
+            if (empty($answertitle)) {
+                continue;
+            }
 
-            if ($setvar != '') {
+            $last_answer_id++;
 
-                $last_answer_id++;
+            $correctanswersfib[$answertitle] = array(
+                'id' => $last_answer_id,
+                'title' => $answertitle,
+                'score' => 1,
+                'feedback' => '',
+                'case' => 0);
+        }
 
-                $answer_title = $xpath->query('xmlns:conditionvar/xmlns:varequal[@respident="' . $identifier . '"]', $response_item);
-                $answer_title = !empty($answer_title->item(0)->nodeValue) ? $answer_title->item(0)->nodeValue : '';
+        // Handle incorrect answers and feedback for all items.
+        foreach ($response_items as $response_item) {
 
-            $case = $xpath->query('xmlns:conditionvar/xmlns:varequal/@case', $response_item);
-            $case = is_object($case->item(0)) ? $case->item(0)->nodeValue : 'no'
-                                    ;
-            $case = strtolower($case) == 'yes' ? 1 :
-                            0;
+            $setvar = $xpath->query('xmlns:setvar', $response_item);
+            if (!empty($setvar->length) && $setvar->item(0)->nodeValue == '100') {
+                // Skip the correct answer responsecondition.
+                continue;
+            }
 
-                $display_feedback = $xpath->query('xmlns:displayfeedback', $response_item);
+            $varequal = $xpath->query('xmlns:conditionvar/xmlns:varequal', $response_item);
+            if (empty($varequal->length)) {
+                // Skip respcondition elements that don't have varequal containing an answer
+                continue;
+            }
+            $answer_title = !empty($varequal->item(0)->nodeValue) ? $varequal->item(0)->nodeValue : '';
 
-                unset($feedbacks_identifiers);
+            $display_feedback = $xpath->query('xmlns:displayfeedback', $response_item);
 
-                if (!empty($display_feedback)) {
+            unset($feedbacks_identifiers);
 
-                    foreach ($display_feedback as $feedback) {
+            if (!empty($display_feedback)) {
 
-                        $feedback_identifier = $feedback->getAttributeNode('linkrefid');
-                        $feedback_identifier = !empty($feedback_identifier->nodeValue) ? $feedback_identifier->nodeValue : '';
+                foreach ($display_feedback as $feedback) {
 
-                        if (!empty($feedback_identifier)) {
-                            $feedbacks_identifiers[] = $feedback_identifier;
-                        }
+                    $feedback_identifier = $feedback->getAttributeNode('linkrefid');
+                    $feedback_identifier = !empty($feedback_identifier->nodeValue) ? $feedback_identifier->nodeValue : '';
+
+                    if (!empty($feedback_identifier)) {
+                        $feedbacks_identifiers[] = $feedback_identifier;
                     }
                 }
+            }
 
-                $feedback = '';
-                $feedbacks_identifiers = empty($feedbacks_identifiers) ? '' : $feedbacks_identifiers;
+            $feedback = '';
+            $feedbacks_identifiers = empty($feedbacks_identifiers) ? '' : $feedbacks_identifiers;
 
-                if (!empty($feedbacks_identifiers)) {
-                    foreach ($feedbacks_identifiers as $feedback_identifier) {
-                        $feedbacks = $xpath->query('//xmlns:item[@ident="' . $question_identifier . '"]/xmlns:itemfeedback[@ident="' . $feedback_identifier . '"]/xmlns:flow_mat/xmlns:material/xmlns:mattext');
-                        $feedback .= !empty($feedbacks->item(0)->nodeValue) ? $feedbacks->item(0)->nodeValue . ' ' : '';
-                    }
+            if (!empty($feedbacks_identifiers)) {
+                foreach ($feedbacks_identifiers as $feedback_identifier) {
+                    $feedbacks = $xpath->query('//xmlns:item[@ident="' . $question_identifier . '"]/xmlns:itemfeedback[@ident="' . $feedback_identifier . '"]/xmlns:flow_mat/xmlns:material/xmlns:mattext');
+                    $feedback .= !empty($feedbacks->item(0)->nodeValue) ? $feedbacks->item(0)->nodeValue . ' ' : '';
                 }
+            }
 
-                $answers_fib[] = array('id' => $last_answer_id,
-                                       'title' => $answer_title,
-                                       'score' => $setvar,
-                                       'feedback' => $feedback,
-                                       'case' => $case);
+            if (array_key_exists($answer_title, $correctanswersfib)) {
+                // Already a correct answer, just need the feedback for the correct answer.
+                $correctanswerfib[$answer_title]['feedback'] = $feedback;
+            } else {
+                // Need to add an incorrect answer.
+                $last_answer_id++;
+                $incorrectanswersfib[] = array(
+                    'id' => $last_answer_id,
+                    'title' => $answer_title,
+                    'score' => 0,
+                    'feedback' => $feedback,
+                    'case' => 0);
             }
         }
 
+        $answers_fib = array_merge($correctanswersfib, $incorrectanswersfib);
         $answers_fib = empty($answers_fib) ? '' : $answers_fib;
 
         return $answers_fib;
@@ -653,8 +686,9 @@ class cc11_quiz extends entities11 {
 
         $question_cc_type = $this->get_question_type($identifier, $assessment);
         $question_cc_type = $question_cc_type['cc'];
+        $is_multiresponse = ($question_cc_type == CC_QUIZ_MULTIPLE_RESPONSE);
 
-        if ($question_cc_type == CC_QUIZ_MULTIPLE_CHOICE || $question_cc_type == CC_QUIZ_MULTIPLE_RESPONSE || $question_cc_type == CC_QUIZ_TRUE_FALSE) {
+        if ($question_cc_type == CC_QUIZ_MULTIPLE_CHOICE || $is_multiresponse || $question_cc_type == CC_QUIZ_TRUE_FALSE) {
 
             $query_answers = '//xmlns:item[@ident="' . $identifier . '"]/xmlns:presentation/xmlns:response_lid/xmlns:render_choice/xmlns:response_label';
             $query_answers_with_flow = '//xmlns:item[@ident="' . $identifier . '"]/xmlns:presentation/xmlns:flow/xmlns:response_lid/xmlns:render_choice/xmlns:response_label';
@@ -705,6 +739,20 @@ class cc11_quiz extends entities11 {
 
             if (!empty($response_items)) {
 
+                if ($is_multiresponse) {
+                    $correct_answer_score = 0;
+                    //get the correct answers count
+                    $canswers_query = "//xmlns:item[@ident='{$identifier}']//xmlns:setvar[@varname='SCORE'][.=100]/../xmlns:conditionvar//xmlns:varequal[@case='Yes'][not(parent::xmlns:not)]";
+                    $canswers = $xpath->query($canswers_query);
+                    if ($canswers->length > 0) {
+                        $correct_answer_score = round(1.0 / (float)$canswers->length, 7); //weird
+                        $correct_answers_ident = array();
+                        foreach ($canswers as $cnode) {
+                            $correct_answers_ident[$cnode->nodeValue] = true;
+                        }
+                    }
+                }
+
                 foreach ($response_items as $response_item) {
 
                     $last_answer_id++;
@@ -719,6 +767,10 @@ class cc11_quiz extends entities11 {
 
                     $answer_score = $this->get_score($assessment, $answer_identifier, $identifier);
 
+                    if ($is_multiresponse && isset($correct_answers_ident[$answer_identifier])) {
+                        $answer_score = $correct_answer_score;
+                    }
+
                     $answers[] = array('id' => $last_answer_id,
                                        'title' => $answer_title,
                                        'score' => $answer_score,
@@ -757,7 +809,8 @@ class cc11_quiz extends entities11 {
             }
         }
 
-        $score = empty($score) ? 0 : $score;
+        // This method (get_score) is only used by T/F & M/C questions in CC, therefore it's either 0 or 1 in Moodle.
+        $score = empty($score) ? "0.0000000" : '1.0000000';
 
         return $score;
     }
index 78b21b1..4d8e372 100644 (file)
@@ -1,7 +1,7 @@
       <MOD>
         <ID>[#mod_instance#]</ID>
         <MODTYPE>forum</MODTYPE>
-        <TYPE>news</TYPE>
+        <TYPE>general</TYPE>
         <NAME>[#mod_forum_title#]</NAME>
         <INTRO>[#mod_forum_intro#]</INTRO>
         <ASSESSED>0</ASSESSED>
index 5cfae39..10476d0 100644 (file)
@@ -1,31 +1,31 @@
 <?php
 
 /**
-* Provides Common Cartridge v1 converter class
-*
-* @package    core
-* @subpackage backup-convert
-* @copyright  2011 Darko Miletic <dmiletic@moodlerooms.com>
-* @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
-*/
-
-require_once($CFG->dirroot . '/backup/converter/convertlib.php');
-require_once($CFG->dirroot . '/backup/cc/includes/constants.php');
-require_once($CFG->dirroot . '/backup/cc/cc2moodle.php');
-require_once($CFG->dirroot . '/backup/cc/validator.php');
+ * Provides Common Cartridge v1 converter class
+ *
+ * @package    core
+ * @subpackage backup-convert
+ * @copyright  2011 Darko Miletic <dmiletic@moodlerooms.com>
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+require_once($CFG->dirroot.'/backup/converter/convertlib.php');
+require_once($CFG->dirroot.'/backup/cc/includes/constants.php');
+require_once($CFG->dirroot.'/backup/cc/cc2moodle.php');
+require_once($CFG->dirroot.'/backup/cc/validator.php');
 
 class imscc1_converter extends base_converter {
 
     /**
-    * Log a message
-    *
-    * @see parent::log()
-    * @param string $message message text
-    * @param int $level message level {@example backup::LOG_WARNING}
-    * @param null|mixed $a additional information
-    * @param null|int $depth the message depth
-    * @param bool $display whether the message should be sent to the output, too
-    */
+     * Log a message
+     *
+     * @see parent::log()
+     * @param string $message message text
+     * @param int $level message level {@example backup::LOG_WARNING}
+     * @param null|mixed $a additional information
+     * @param null|int $depth the message depth
+     * @param bool $display whether the message should be sent to the output, too
+     */
     public function log($message, $level, $a = null, $depth = null, $display = false) {
         parent::log('(imscc1) '.$message, $level, $a, $depth, $display);
     }
@@ -42,12 +42,12 @@ class imscc1_converter extends base_converter {
         $filepath = $CFG->dataroot . '/temp/backup/' . $tempdir;
         $manifest = cc2moodle::get_manifest($filepath);
         if (!empty($manifest)) {
-            // looks promising, lets load some information
+            // Looks promising, lets load some information.
             $handle = fopen($manifest, 'r');
-            $xml_snippet = fread($handle, 500);
+            $xml_snippet = fread($handle, 1024);
             fclose($handle);
 
-            // check if it has the required strings
+            // Check if it has the required strings.
 
             $xml_snippet = strtolower($xml_snippet);
             $xml_snippet = preg_replace('/\s*/m', '', $xml_snippet);
@@ -65,13 +65,13 @@ class imscc1_converter extends base_converter {
 
 
     /**
-    * Returns the basic information about the converter
-    *
-    * The returned array must contain the following keys:
-    * 'from' - the supported source format, eg. backup::FORMAT_MOODLE1
-    * 'to'   - the supported target format, eg. backup::FORMAT_MOODLE
-    * 'cost' - the cost of the conversion, non-negative non-zero integer
-    */
+     * Returns the basic information about the converter
+     *
+     * The returned array must contain the following keys:
+     * 'from' - the supported source format, eg. backup::FORMAT_MOODLE1
+     * 'to'   - the supported target format, eg. backup::FORMAT_MOODLE
+     * 'cost' - the cost of the conversion, non-negative non-zero integer
+     */
     public static function description() {
 
         return array(
@@ -102,7 +102,7 @@ class imscc1_converter extends base_converter {
             throw new imscc1_convert_exception('protected_cc_not_supported');
         }
         $status = $cc2moodle->generate_moodle_xml();
-        //Final cleanup
+        // Final cleanup.
         $xml_error = new libxml_errors_mgr(true);
         $mdoc = new DOMDocument();
         $mdoc->preserveWhiteSpace = false;
@@ -116,7 +116,7 @@ class imscc1_converter extends base_converter {
             $this->log('validation error(s): '.PHP_EOL.error_messages::instance(), backup::LOG_DEBUG, null, 2);
             throw new imscc1_convert_exception(error_messages::instance()->to_string(true));
         }
-        //Move the files to the workdir
+        // Move the files to the workdir.
         rename($manifestdir.'/course_files', $this->get_workdir_path().'/course_files');
     }
 
@@ -124,7 +124,7 @@ class imscc1_converter extends base_converter {
 }
 
 /**
-* Exception thrown by this converter
-*/
+ * Exception thrown by this converter
+ */
 class imscc1_convert_exception extends convert_exception {
 }
index 7e885f0..0c1c6d6 100644 (file)
@@ -1,32 +1,32 @@
 <?php
 
 /**
-* Provides Common Cartridge v1.1 converter class
-*
-* @package    core
-* @subpackage backup-convert
-* @copyright  2011 Darko Miletic <dmiletic@moodlerooms.com>
-* @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
-*/
+ * Provides Common Cartridge v1.1 converter class
+ *
+ * @package    core
+ * @subpackage backup-convert
+ * @copyright  2011 Darko Miletic <dmiletic@moodlerooms.com>
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
 
-require_once($CFG->dirroot . '/backup/converter/convertlib.php');
-require_once($CFG->dirroot . '/backup/cc/includes/constants.php');
-require_once($CFG->dirroot . '/backup/cc/cc112moodle.php');
-require_once($CFG->dirroot . '/backup/cc/validator.php');
+require_once($CFG->dirroot.'/backup/converter/convertlib.php');
+require_once($CFG->dirroot.'/backup/cc/includes/constants.php');
+require_once($CFG->dirroot.'/backup/cc/cc112moodle.php');
+require_once($CFG->dirroot.'/backup/cc/validator.php');
 
 
 class imscc11_converter extends base_converter {
 
     /**
-    * Log a message
-    *
-    * @see parent::log()
-    * @param string $message message text
-    * @param int $level message level {@example backup::LOG_WARNING}
-    * @param null|mixed $a additional information
-    * @param null|int $depth the message depth
-    * @param bool $display whether the message should be sent to the output, too
-    */
+     * Log a message
+     *
+     * @see parent::log()
+     * @param string $message message text
+     * @param int $level message level {@example backup::LOG_WARNING}
+     * @param null|mixed $a additional information
+     * @param null|int $depth the message depth
+     * @param bool $display whether the message should be sent to the output, too
+     */
     public function log($message, $level, $a = null, $depth = null, $display = false) {
         parent::log('(imscc1) '.$message, $level, $a, $depth, $display);
     }
@@ -43,12 +43,12 @@ class imscc11_converter extends base_converter {
         $filepath = $CFG->dataroot . '/temp/backup/' . $tempdir;
         $manifest = cc112moodle::get_manifest($filepath);
         if (file_exists($manifest)) {
-            // looks promising, lets load some information
+            // Looks promising, lets load some information.
             $handle = fopen($manifest, 'r');
-            $xml_snippet = fread($handle, 500);
+            $xml_snippet = fread($handle, 1024);
             fclose($handle);
 
-            // check if it has the required strings
+            // Check if it has the required strings.
 
             $xml_snippet = strtolower($xml_snippet);
             $xml_snippet = preg_replace('/\s*/m', '', $xml_snippet);
@@ -66,13 +66,13 @@ class imscc11_converter extends base_converter {
 
 
     /**
-    * Returns the basic information about the converter
-    *
-    * The returned array must contain the following keys:
-    * 'from' - the supported source format, eg. backup::FORMAT_MOODLE1
-    * 'to'   - the supported target format, eg. backup::FORMAT_MOODLE
-    * 'cost' - the cost of the conversion, non-negative non-zero integer
-    */
+     * Returns the basic information about the converter
+     *
+     * The returned array must contain the following keys:
+     * 'from' - the supported source format, eg. backup::FORMAT_MOODLE1
+     * 'to'   - the supported target format, eg. backup::FORMAT_MOODLE
+     * 'cost' - the cost of the conversion, non-negative non-zero integer
+     */
     public static function description() {
 
         return array(
@@ -102,7 +102,7 @@ class imscc11_converter extends base_converter {
             throw new imscc11_convert_exception('protected_cc_not_supported');
         }
         $status = $cc112moodle->generate_moodle_xml();
-        //Final cleanup
+        // Final cleanup.
         $xml_error = new libxml_errors_mgr(true);
         $mdoc = new DOMDocument();
         $mdoc->preserveWhiteSpace = false;
@@ -116,7 +116,7 @@ class imscc11_converter extends base_converter {
             $this->log('validation error(s): '.PHP_EOL.error_messages::instance(), backup::LOG_DEBUG, null, 2);
             throw new imscc11_convert_exception(error_messages::instance()->to_string(true));
         }
-        //Move the files to the workdir
+        // Move the files to the workdir.
         rename($manifestdir.'/course_files', $this->get_workdir_path().'/course_files');
     }
 
@@ -124,7 +124,7 @@ class imscc11_converter extends base_converter {
 }
 
 /**
-* Exception thrown by this converter
-*/
+ * Exception thrown by this converter
+ */
 class imscc11_convert_exception extends convert_exception {
 }
index 5b0ae4c..2f8232a 100644 (file)
@@ -466,6 +466,9 @@ class moodle1_converter extends base_converter {
         if (empty($record)) {
             throw new moodle1_convert_empty_storage_exception('required_not_stashed_data', array($stashname, $itemid));
         } else {
+            if (empty($record->info)) {
+                return array();
+            }
             return $record->info;
         }
     }
index 93ea27f..469225d 100644 (file)
@@ -8,6 +8,6 @@
     "require-dev": {
         "phpunit/phpunit": "3.7.*",
         "phpunit/dbUnit": "1.2.*",
-        "moodlehq/behat-extension": "1.27.6"
+        "moodlehq/behat-extension": "1.27.9"
     }
 }
index de81954..71c6a32 100644 (file)
@@ -1,18 +1,18 @@
 slot,randq,variant,subpart,modelresponse,actualresponse,count1,count2,count3,count4,count5,totalcount
 1,shortanswer,1,1,frog,,0,0,0,0,0,0
-1,shortanswer,1,1,toad,toad,1,0,1,0,0,2
+1,shortanswer,1,1,toad,toad,2,1,1,0,0,4
 1,shortanswer,1,1,*,butterfly,1,0,0,0,0,1
 1,shortanswer,1,1,*,dog,1,1,0,0,0,2
 1,shortanswer,1,1,*,chicken,0,0,1,0,0,1
 1,shortanswer,1,1,*,Tod,1,0,0,0,0,1
 1,shortanswer,1,1,*,Tony,0,1,0,0,0,1
 1,shortanswer,1,1,*,Sharon,0,0,1,0,0,1
-1,shortanswer,1,1,*,snake,0,1,0,0,0,1
+1,shortanswer,1,1,*,snake,1,1,0,0,0,2
 1,shortanswer,1,1,*,snakes,0,0,1,0,0,1
 1,shortanswer,1,1,*,Snakes,0,0,0,1,0,1
 1,shortanswer,1,1,*,SnakeS,0,0,0,0,1,1
 1,shortanswer,1,1,*,goat,1,0,0,0,0,1
-1,shortanswer,1,1,*,"Mexican burrowing caecilian",0,0,1,0,0,1
+1,shortanswer,1,1,*,"Mexican burrowing caecilian",0,1,1,0,0,2
 1,shortanswer,1,1,*,newt,0,0,0,1,0,1
 1,shortanswer,1,1,*,human,0,0,0,0,1,1
 1,shortanswer,1,1,*,eggs,1,0,0,0,0,1
@@ -32,9 +32,9 @@ slot,randq,variant,subpart,modelresponse,actualresponse,count1,count2,count3,cou
 2,,1,1,[Did not match any answer],9,0,0,0,1,0,1
 2,,1,1,[No response],,0,0,0,0,0,0
 2,,2,1,{a} + {b} (±0.01 Relative),8.5,1,0,0,0,1,2
-2,,2,1,"[Did not match any answer]",19.4,0,1,0,0,0,1
+2,,2,1,"[Did not match any answer]",19.4,1,1,0,0,0,2
 2,,2,1,[Did not match any answer],4.5,1,0,0,0,0,1
-2,,2,1,"[Did not match any answer]",8,0,0,0,1,0,1
+2,,2,1,"[Did not match any answer]",8,1,1,1,1,0,4
 2,,2,1,[No response],,0,0,0,0,0,0
 2,,3,1,{a} + {b} (±0.01 Relative),3.3,0,1,0,0,0,1
 2,,3,1,[Did not match any answer],19.4,1,0,0,0,0,1
@@ -56,16 +56,16 @@ slot,randq,variant,subpart,modelresponse,actualresponse,count1,count2,count3,cou
 2,,10,1,"[Did not match any answer]",11,0,0,0,1,0,1
 2,,10,1,"[Did not match any answer]",12,0,0,0,0,1,1
 2,,10,1,"[No response]",,0,0,0,0,0,0
-3,,1,1,"frog: amphibian",amphibian,8,0,1,0,0,9
+3,,1,1,"frog: amphibian",amphibian,8,2,3,3,0,16
 3,,1,1,frog: mammal,mammal,0,0,0,1,1,2
-3,,1,1,frog: insect,insect,4,3,0,0,0,7
+3,,1,1,"frog: insect",insect,4,4,2,1,0,11
 3,,1,1,[No response],,0,0,0,0,0,0
-3,,1,2,"cat: amphibian",amphibian,8,0,1,1,0,10
+3,,1,2,"cat: amphibian",amphibian,8,1,2,1,1,13
 3,,1,2,cat: mammal,mammal,0,1,1,2,0,4
-3,,1,2,"cat: insect",insect,4,1,1,1,0,7
+3,,1,2,"cat: insect",insect,4,4,2,2,0,12
 3,,1,2,[No response],,0,0,0,0,0,0
-3,,1,3,"newt: amphibian",amphibian,6,2,1,0,0,9
-3,,1,3,"newt: mammal",mammal,3,0,0,1,0,5
+3,,1,3,"newt: amphibian",amphibian,6,4,4,3,1,18
+3,,1,3,"newt: mammal",mammal,3,0,1,2,0,6
 3,,1,3,newt: insect,insect,3,2,0,0,0,5
 3,,1,3,[No response],,0,0,0,0,0,0
 4,,1,1,False,,3,0,0,0,0,3
index f0c4fe9..6c9714c 100644 (file)
@@ -1,9 +1,9 @@
 slot,subpart,modelresponse,actualresponse,totalcount,count1,count2,count3,count4,count5
-1,1,frog: insect,insect,3,3,0,0,0,0
-1,1,"frog: mammal",mammal,1,0,0,1,0,0
+1,1,"frog: insect",insect,12,3,3,2,2,2
+1,1,"frog: mammal",mammal,4,0,0,1,1,2
 1,1,"frog: amphibian",amphibian,1,0,0,0,0,1
-1,2,"cat: insect",insect,3,2,1,0,0,0
+1,2,"cat: insect",insect,13,2,3,3,3,2
 1,2,cat: amphibian,amphibian,1,1,0,0,0,0
-1,2,cat: mammal,mammal,2,0,0,0,0,2
-1,3,newt: insect,insect,3,3,0,0,0,0
+1,2,cat: mammal,mammal,3,0,0,0,0,3
+1,3,newt: insect,insect,15,3,3,3,3,3
 1,3,newt: amphibian,amphibian,2,0,0,0,0,2
index 213d712..9a085a4 100644 (file)
@@ -1515,7 +1515,8 @@ function wiki_build_tree($page, $node, &$keys) {
     $content = array();
     static $icon = null;
     if ($icon === null) {
-        $icon = new pix_icon('f/text-24', '');
+        // Substitute the default navigation icon with empty image.
+        $icon = new pix_icon('spacer', '');
     }
     $pages = wiki_get_linked_pages($page->id);
     foreach ($pages as $p) {
index d690bdd..3cd2511 100644 (file)
@@ -304,49 +304,11 @@ abstract class question_behaviour {
                 foreach ($stepswithsubmit as $submittedresponseno => $step) {
                     $classifiedresponses[$submittedresponseno] = $this->question->classify_response($step->get_qt_data());
                 }
-                return $this->remove_repeated_submitted_responses($classifiedresponses);
+                return $classifiedresponses;
             }
         }
     }
 
-    /**
-     * Filter classified responses for multiple tries to remove identical responses that are not significant.
-     *
-     * In base class we compare last response to preceding responses and remove all identical responses until a different one is
-     * found then for that different response compare to preceding and remove all identical until ...
-     *
-     * @param array[] $classifiedresponses first index is submitted response no and second is sub-part id. Value is of type
-     *                                     question_classified_response. Return value from self::classify_response for ALL_TRIES.
-     * @return array[] return non repeated responses.
-     */
-    protected function remove_repeated_submitted_responses($classifiedresponses) {
-        $submittedresponsenos = array_keys($classifiedresponses);
-        $submittedresponsenos = array_reverse($submittedresponsenos);
-        $lastsubmittedresponseno = array_shift($submittedresponsenos);
-        $nooflastnewresponse = $lastsubmittedresponseno;
-        while (count($submittedresponsenos)) {
-            $precedingresponseno = array_shift($submittedresponsenos);
-            $responsesrepeated = true;
-            if (count($classifiedresponses[$precedingresponseno]) !== count($classifiedresponses[$nooflastnewresponse])) {
-                $responsesrepeated = false;
-            } else {
-                foreach (array_keys($classifiedresponses[$precedingresponseno]) as $subpartid) {
-                    if ($classifiedresponses[$precedingresponseno][$subpartid] !=
-                                        $classifiedresponses[$nooflastnewresponse][$subpartid]) {
-                        $responsesrepeated = false;
-                        break;
-                    }
-                }
-            }
-            if ($responsesrepeated) {
-                unset($classifiedresponses[$precedingresponseno]);
-            } else {
-                $nooflastnewresponse = $precedingresponseno;
-            }
-        }
-        return $classifiedresponses;
-    }
-
     /**
      * Generate a brief textual description of the current state of the question,
      * normally displayed under the question number.
index 81088c6..20c650b 100644 (file)
@@ -90,31 +90,4 @@ class qbehaviour_interactivecountback extends qbehaviour_interactive {
 
         return $this->question->compute_final_grade($responses, $totaltries);
     }
-
-    /**
-     * Filter classified responses for multiple tries to remove identical responses that are not significant.
-     *
-     * For this behaviour the significant repeated response part are the first of any repeated responses, for any part of the
-     * question. These are the responses that are graded.
-     *
-     * @param array[] $classifiedresponses first index is submitted response no and second is sub-part id. Value is of type
-     *                                     question_classified_response. Return value from self::classify_response for ALL_TRIES.
-     * @return array[] return non repeated responses.
-     */
-    protected function remove_repeated_submitted_responses($classifiedresponses) {
-        $subpartids = array_keys($classifiedresponses[1]);
-        foreach ($subpartids as $subpartid) {
-            $lastdifferentresponsepart = 1;
-            $tryno = 2;
-            while (isset($classifiedresponses[$tryno])) {
-                if ($classifiedresponses[$tryno][$subpartid] != $classifiedresponses[$lastdifferentresponsepart][$subpartid]) {
-                    $lastdifferentresponsepart = $tryno;
-                } else {
-                    unset($classifiedresponses[$tryno][$subpartid]);
-                }
-                $tryno++;
-            }
-        }
-        return $classifiedresponses;
-    }
 }
index daf057b..1fae252 100644 (file)
@@ -46,7 +46,7 @@ class repository_url extends repository {
     public function __construct($repositoryid, $context = SYSCONTEXTID, $options = array()){
         global $CFG;
         parent::__construct($repositoryid, $context, $options);
-        $this->file_url = optional_param('file', '', PARAM_RAW);
+        $this->file_url = optional_param('file', '', PARAM_URL);
     }
 
     public function check_login() {