Browse Source

Merge branch '1.11.x' of github.com:chamilo/chamilo-lms into 1.11.x

Julio Montoya 6 years ago
parent
commit
c8980da9bd

+ 1 - 1
main/gradebook/lib/fe/evalform.class.php

@@ -20,7 +20,7 @@ class EvalForm extends FormValidator
     const TYPE_ALL_RESULTS_EDIT = 6;
     const TYPE_ADD_USERS_TO_EVAL = 7;
 
-    private $evaluation_object;
+    protected $evaluation_object;
     private $result_object;
     private $extra;
 

+ 71 - 0
plugin/ims_lti/Entity/ImsLtiTool.php

@@ -3,6 +3,8 @@
 
 namespace Chamilo\PluginBundle\Entity\ImsLti;
 
+use Chamilo\CoreBundle\Entity\Course;
+use Chamilo\CoreBundle\Entity\GradebookEvaluation;
 use Doctrine\ORM\Mapping as ORM;
 
 /**
@@ -70,12 +72,33 @@ class ImsLtiTool
      */
     private $activeDeepLinking = false;
 
+    /**
+     * @var Course|null
+     *
+     * @ORM\ManyToOne(targetEntity="Chamilo\CoreBundle\Entity\Course")
+     * @ORM\JoinColumn(name="c_id", referencedColumnName="id")
+     */
+    private $course = null;
+
+    /**
+     * @var GradebookEvaluation|null
+     *
+     * @ORM\ManyToOne(targetEntity="Chamilo\CoreBundle\Entity\GradebookEvaluation")
+     * @ORM\JoinColumn(name="gradebook_eval_id", referencedColumnName="id", onDelete="SET NULL")
+     */
+    private $gradebookEval = null;
+
+    /**
+     * ImsLtiTool constructor.
+     */
     public function __construct()
     {
         $this->description = null;
         $this->customParams = null;
         $this->isGlobal = false;
         $this->activeDeepLinking = false;
+        $this->course = null;
+        $this->gradebookEval =null;
     }
 
     /**
@@ -252,4 +275,52 @@ class ImsLtiTool
     {
         return $this->activeDeepLinking;
     }
+
+    /**
+     * Get course.
+     *
+     * @return Course|null
+     */
+    public function getCourse()
+    {
+        return $this->course;
+    }
+
+    /**
+     * Set course.
+     *
+     * @param Course|null $course
+     *
+     * @return ImsLtiTool
+     */
+    public function setCourse(Course $course = null)
+    {
+        $this->course = $course;
+
+        return $this;
+    }
+
+    /**
+     * Get gradebookEval.
+     *
+     * @return GradebookEvaluation|null
+     */
+    public function getGradebookEval()
+    {
+        return $this->gradebookEval;
+    }
+
+    /**
+     * Set gradebookEval.
+     *
+     * @param GradebookEvaluation|null $gradebookEval
+     *
+     * @return ImsLtiTool
+     */
+    public function setGradebookEval($gradebookEval)
+    {
+        $this->gradebookEval = $gradebookEval;
+
+        return $this;
+    }
 }

+ 47 - 4
plugin/ims_lti/ImsLtiPlugin.php

@@ -2,6 +2,7 @@
 /* For license terms, see /license.txt */
 
 use Chamilo\CoreBundle\Entity\CourseRelUser;
+use Chamilo\CoreBundle\Entity\GradebookEvaluation;
 use Chamilo\CoreBundle\Entity\Session;
 use Chamilo\CoreBundle\Entity\SessionRelCourseRelUser;
 use Chamilo\CourseBundle\Entity\CTool;
@@ -127,7 +128,25 @@ class ImsLtiPlugin extends Plugin
             $toolTable->addColumn('custom_params', Type::TEXT)->setNotnull(false);
             $toolTable->addColumn('is_global', Type::BOOLEAN);
             $toolTable->addColumn('active_deep_linking', Type::BOOLEAN)->setNotnull(false)->setDefault(false);
+            $toolTable->addColumn('c_id', Type::INTEGER);
+            $toolTable->addForeignKeyConstraint(
+                'course',
+                ['c_id'],
+                ['id'],
+                [],
+                'FK_C5E47F7C91D79BD3'
+            );
+            $toolTable->addColumn('gradebook_eval_id', Type::INTEGER, []);
+            $toolTable->addForeignKeyConstraint(
+                'gradebook_evaluation',
+                ['gradebook_eval_id'],
+                ['id'],
+                ['onDelete' => 'SET NULL'],
+                'FK_C5E47F7C82F80D8B'
+            );
             $toolTable->setPrimaryKey(['id']);
+            $toolTable->addIndex(['c_id'], 'IDX_C5E47F7C91D79BD3');
+            $toolTable->addIndex(['gradebook_eval_id'], 'IDX_C5E47F7C82F80D8B');
 
             $queries = $pluginSchema->toSql($platform);
 
@@ -379,7 +398,8 @@ class ImsLtiPlugin extends Plugin
             )
             ->setDescription(
                 !empty($contentItem['text']) ? $contentItem['text'] : null
-            );
+            )
+            ->setCourse($course);
 
         $em->persist($newLtiTool);
         $em->flush();
@@ -441,13 +461,36 @@ class ImsLtiPlugin extends Plugin
 
     /**
      * @param SimpleXMLElement $resultRecord
+     *
+     * @throws \Doctrine\ORM\ORMException
+     * @throws \Doctrine\ORM\OptimisticLockException
+     * @throws \Doctrine\ORM\TransactionRequiredException
      */
     private function getReplaceRequest(SimpleXMLElement $resultRecord)
     {
-        $sourcedId = $resultRecord->sourcedGUID->sourcedId;
-        $resultScore = $resultRecord->result->resultScore->textString;
+        $sourcedId = (string) $resultRecord->sourcedGUID->sourcedId;
+        $resultScore = (float) $resultRecord->result->resultScore->textString;
+
+        list($evaluationId, $userId) = explode(':', $sourcedId);
 
-        error_log("ReplaceRequest sourcedId: $sourcedId - score: $resultScore");
+        $em = Database::getManager();
+        /** @var GradebookEvaluation $evaluation */
+        $evaluation = $em->find('ChamiloCoreBundle:GradebookEvaluation', $evaluationId);
+
+        if (empty($evaluation)) {
+            return;
+        }
+
+        $result = new Result();
+        $result->set_evaluation_id($evaluationId);
+        $result->set_user_id($userId);
+        $result->set_score($evaluation->getMax() * $resultScore);
+        $result->add();
+
+        error_log(
+            "ReplaceRequest sourcedId: $sourcedId - lti_score: $resultScore - score: "
+                .($evaluation->getMax() * $resultScore)
+        );
     }
 
     /**

+ 17 - 4
plugin/ims_lti/README.md

@@ -1,7 +1,7 @@
 IMS/LTI plugin
 ===
 
-Version 1.1 (beta)
+Version 1.2 (beta)
 
 This plugin is meant to be later integrated into Chamilo (in a major version
 release).
@@ -23,8 +23,8 @@ external tool.
 # Changelog
 
 **v1.1**
-
 * Support for Deep-Linking added.
+* Support for outcomes services.
 
 # Installation
 
@@ -34,12 +34,25 @@ external tool.
 
 # Upgrading
 
-**To v1.1**
-
 Run this changes on database:
+
+**To v1.1**
 ```sql
 ALTER TABLE plugin_ims_lti_tool
     ADD active_deep_linking TINYINT(1) DEFAULT '0' NOT NULL,
     CHANGE id id INT AUTO_INCREMENT NOT NULL,
     CHANGE launch_url launch_url VARCHAR(255) NOT NULL;
 ```
+
+**To v1.2**
+```sql
+ALTER TABLE plugin_ims_lti_tool ADD c_id INT DEFAULT NULL;
+ALTER TABLE plugin_ims_lti_tool ADD CONSTRAINT FK_C5E47F7C91D79BD3
+    FOREIGN KEY (c_id) REFERENCES course (id);
+CREATE INDEX IDX_C5E47F7C91D79BD3 ON plugin_ims_lti_tool (c_id);
+
+ALTER TABLE plugin_ims_lti_tool ADD gradebook_eval_id INT DEFAULT NULL;
+ALTER TABLE plugin_ims_lti_tool ADD CONSTRAINT FK_C5E47F7C82F80D8B
+    FOREIGN KEY (gradebook_eval_id) REFERENCES gradebook_evaluation (id) ON DELETE SET NULL;
+CREATE INDEX IDX_C5E47F7C82F80D8B ON plugin_ims_lti_tool (gradebook_eval_id);
+```

+ 2 - 1
plugin/ims_lti/add.php

@@ -84,7 +84,8 @@ if ($form->validate()) {
         ->setDescription(
             empty($formValues['description']) ? null : $formValues['description']
         )
-        ->setIsGlobal(false);
+        ->setIsGlobal(false)
+        ->setCourse($course);
     $em->persist($tool);
     $em->flush();
 

+ 11 - 9
plugin/ims_lti/form.php

@@ -54,15 +54,17 @@ if ($tool->isActiveDeepLinking()) {
     $params['resource_link_title'] = $tool->getName();
     $params['resource_link_description'] = $tool->getDescription();
 
-    $params['lis_result_sourcedid'] = $tool->getId().':'.$toolUserId;
-    $params['lis_outcome_service_url'] = api_get_path(WEB_PLUGIN_PATH).'ims_lti/outcome_service.php';
-    $params['lis_person_sourcedid'] = $platformDomain.':'.$toolUserId;
-    $params['lis_course_offering_sourcedid'] = "$platformDomain:";
-
-    if ($session) {
-        $params['lis_course_offering_sourcedid'] .= $session->getId().'-'.$course->getCode();
-    } else {
-        $params['lis_course_offering_sourcedid'] .= $course->getCode();
+    $toolEval = $tool->getGradebookEval();
+
+    if (!empty($toolEval)) {
+        $params['lis_result_sourcedid'] = $toolEval->getId().':'.$user->getId();
+        $params['lis_outcome_service_url'] = api_get_path(WEB_PLUGIN_PATH).'ims_lti/outcome_service.php';
+        $params['lis_person_sourcedid'] = "$platformDomain:$toolUserId";
+        $params['lis_course_offering_sourcedid'] = "$platformDomain:".$course->getId();
+
+        if ($session) {
+            $params['lis_course_offering_sourcedid'] .= ':'.$session->getId();
+        }
     }
 }
 

+ 193 - 0
plugin/ims_lti/gradebook/OutcomeForm.php

@@ -0,0 +1,193 @@
+<?php
+/* For licensing terms, see /license.txt */
+
+class OutcomeForm extends EvalForm
+{
+    /**
+     * Builds a form containing form items based on a given parameter.
+     *
+     * @param int        $form_type         1=add, 2=edit,3=move,4=result_add
+     * @param Evaluation $evaluation_object the category object
+     * @param obj        $result_object     the result object
+     * @param string     $form_name
+     * @param string     $method
+     * @param string     $action
+     */
+    public function __construct(
+        $evaluation_object,
+        $result_object,
+        $form_name,
+        $method = 'post',
+        $action = null,
+        $extra1 = null,
+        $extra2 = null
+    ) {
+        parent::__construct(
+            -1,
+            $evaluation_object,
+            $result_object,
+            $form_name,
+            $method,
+            $action,
+            $extra1,
+            $extra2
+        );
+
+        $this->build_add_form();
+        $this->setDefaults();
+    }
+
+    /**
+     * Builds a basic form that is used in add and edit.
+     *
+     * @param int $edit
+     *
+     * @throws Exception
+     */
+    private function build_basic_form($edit = 0)
+    {
+        $this->addElement('header', get_plugin_lang('NewOutcomeFormTitle'));
+        $this->addElement('hidden', 'hid_user_id');
+        $this->addElement('hidden', 'hid_course_code');
+
+        $this->addText(
+            'name',
+            get_lang('EvaluationName'),
+            true,
+            [
+                'maxlength' => '50',
+                'id' => 'evaluation_title',
+            ]
+        );
+
+        $cat_id = $this->evaluation_object->get_category_id();
+
+        $session_id = api_get_session_id();
+        $course_code = api_get_course_id();
+        $all_categories = Category:: load(null, null, $course_code, null, null, $session_id, false);
+
+        if (count($all_categories) == 1) {
+            $this->addElement('hidden', 'hid_category_id', $cat_id);
+        } else {
+            $select_gradebook = $this->addElement(
+                'select',
+                'hid_category_id',
+                get_lang('SelectGradebook'),
+                [],
+                ['id' => 'hid_category_id']
+            );
+            $this->addRule('hid_category_id', get_lang('ThisFieldIsRequired'), 'nonzero');
+            $default_weight = 0;
+            if (!empty($all_categories)) {
+                foreach ($all_categories as $my_cat) {
+                    if ($my_cat->get_course_code() == api_get_course_id()) {
+                        $grade_model_id = $my_cat->get_grade_model_id();
+                        if (empty($grade_model_id)) {
+                            if ($my_cat->get_parent_id() == 0) {
+                                $default_weight = $my_cat->get_weight();
+                                $select_gradebook->addoption(get_lang('Default'), $my_cat->get_id());
+                                $cats_added[] = $my_cat->get_id();
+                            } else {
+                                $select_gradebook->addoption($my_cat->get_name(), $my_cat->get_id());
+                                $cats_added[] = $my_cat->get_id();
+                            }
+                        } else {
+                            $select_gradebook->addoption(get_lang('Select'), 0);
+                        }
+                        if ($this->evaluation_object->get_category_id() == $my_cat->get_id()) {
+                            $default_weight = $my_cat->get_weight();
+                        }
+                    }
+                }
+            }
+        }
+
+        $this->addFloat(
+            'weight_mask',
+            [
+                get_lang('Weight'),
+                null,
+                ' [0 .. <span id="max_weight">'.$all_categories[0]->get_weight().'</span>] ',
+            ],
+            true,
+            [
+                'size' => '4',
+                'maxlength' => '5',
+            ]
+        );
+
+        if ($edit) {
+            if (!$this->evaluation_object->has_results()) {
+                $this->addText(
+                    'max',
+                    get_lang('QualificationNumeric'),
+                    true,
+                    [
+                        'maxlength' => '5',
+                    ]
+                );
+            } else {
+                $this->addText(
+                    'max',
+                    [get_lang('QualificationNumeric'), get_lang('CannotChangeTheMaxNote')],
+                    false,
+                    [
+                        'maxlength' => '5',
+                        'disabled' => 'disabled',
+                    ]
+                );
+            }
+        } else {
+            $this->addText(
+                'max',
+                get_lang('QualificationNumeric'),
+                true,
+                [
+                    'maxlength' => '5',
+                ]
+            );
+            $default_max = api_get_setting('gradebook_default_weight');
+            $defaults['max'] = isset($default_max) ? $default_max : 100;
+            $this->setDefaults($defaults);
+        }
+
+        $this->addElement('textarea', 'description', get_lang('Description'));
+        $this->addRule('hid_category_id', get_lang('ThisFieldIsRequired'), 'required');
+        $this->addElement('checkbox', 'visible', null, get_lang('Visible'));
+        $this->addRule('max', get_lang('OnlyNumbers'), 'numeric');
+        $this->addRule(
+            'max',
+            get_lang('NegativeValue'),
+            'compare',
+            '>=',
+            'server',
+            false,
+            false,
+            0
+        );
+        $setting = api_get_setting('tool_visible_by_default_at_creation');
+        $visibility_default = 1;
+        if (isset($setting['gradebook']) && $setting['gradebook'] == 'false') {
+            $visibility_default = 0;
+        }
+        $this->setDefaults(['visible' => $visibility_default]);
+    }
+
+    /**
+     *
+     */
+    protected function build_add_form()
+    {
+        $this->setDefaults(
+            [
+                'hid_user_id' => $this->evaluation_object->get_user_id(),
+                'hid_category_id' => $this->evaluation_object->get_category_id(),
+                'hid_course_code' => $this->evaluation_object->get_course_code(),
+                'created_at' => api_get_utc_datetime(),
+            ]
+        );
+        $this->build_basic_form();
+
+        $this->addButtonCreate(get_lang('AddAssessment'), 'submit');
+    }
+}

+ 132 - 0
plugin/ims_lti/gradebook/add_eval.php

@@ -0,0 +1,132 @@
+<?php
+/* For licensing terms, see /license.txt */
+
+/**
+ * @package plugin.ims_lti
+ */
+
+use Chamilo\CoreBundle\Entity\GradebookEvaluation;
+use Chamilo\PluginBundle\Entity\ImsLti\ImsLtiTool;
+
+require_once __DIR__.'/../../../main/inc/global.inc.php';
+
+$current_course_tool = TOOL_GRADEBOOK;
+
+api_protect_course_script(true);
+api_block_anonymous_users();
+GradebookUtils::block_students();
+
+$select_cat = isset($_GET['selectcat']) ? (int) $_GET['selectcat'] : 0;
+$is_allowedToEdit = $is_courseAdmin;
+
+$em = Database::getManager();
+$course = $em->find('ChamiloCoreBundle:Course', api_get_course_int_id());
+$ltiToolRepo = $em->getRepository('ChamiloPluginBundle:ImsLti\ImsLtiTool');
+
+$evaladd = new Evaluation();
+$evaladd->set_user_id($_user['user_id']);
+
+if (!empty($select_cat)) {
+    $evaladd->set_category_id($_GET['selectcat']);
+    $cat = Category::load($_GET['selectcat']);
+    $evaladd->set_course_code($cat[0]->get_course_code());
+} else {
+    $evaladd->set_category_id(0);
+}
+
+$form = new EvalForm(
+    EvalForm::TYPE_ADD,
+    $evaladd,
+    null,
+    'add_eval_form',
+    null,
+    api_get_self().'?selectcat='.$select_cat.'&'.api_get_cidreq()
+);
+$form->removeElement('name');
+$form->removeElement('addresult');
+$slcLtiTools = $form->createElement('select', 'name', get_lang('Tool'));
+$form->insertElementBefore($slcLtiTools, 'hid_category_id');
+$form->addRule('name', get_lang('ThisFieldIsRequired'), 'required');
+
+$ltiTools = $ltiToolRepo->findByCourse($course);
+
+/** @var ImsLtiTool $ltiTool */
+foreach ($ltiTools as $ltiTool) {
+    $slcLtiTools->addOption($ltiTool->getName(), $ltiTool->getId());
+}
+
+if ($form->validate()) {
+    $values = $form->exportValues();
+
+    /** @var ImsLtiTool $ltiTool */
+    $ltiTool = $ltiToolRepo->find($values['name']);
+
+    if (!$ltiTool) {
+        api_not_allowed();
+    }
+
+    $eval = new Evaluation();
+    $eval->set_name($ltiTool->getName());
+    $eval->set_description($values['description']);
+    $eval->set_user_id($values['hid_user_id']);
+
+    if (!empty($values['hid_course_code'])) {
+        $eval->set_course_code($values['hid_course_code']);
+    }
+
+    //Always add the gradebook to the course
+    $eval->set_course_code(api_get_course_id());
+    $eval->set_category_id($values['hid_category_id']);
+
+    $parent_cat = Category::load($values['hid_category_id']);
+    $global_weight = $cat[0]->get_weight();
+    //$values['weight'] = $values['weight_mask']/$global_weight*$parent_cat[0]->get_weight();
+    $values['weight'] = $values['weight_mask'];
+
+    $eval->set_weight($values['weight']);
+    $eval->set_max($values['max']);
+    $eval->set_visible(empty($values['visible']) ? 0 : 1);
+    $eval->add();
+
+    /** @var GradebookEvaluation $gradebookEval */
+    $gradebookEval = $em->find('ChamiloCoreBundle:GradebookEvaluation', $eval->get_id());
+    $ltiTool->setGradebookEval($gradebookEval);
+
+    $em->persist($ltiTool);
+    $em->flush();
+
+    header('Location: '.Category::getUrl().'selectcat='.$eval->get_category_id());
+
+    exit;
+}
+
+$interbreadcrumb[] = [
+    'url' => Category::getUrl().'selectcat='.$select_cat,
+    'name' => get_lang('Gradebook'),
+];
+$this_section = SECTION_COURSES;
+
+$htmlHeadXtra[] = '<script>
+$(document).ready( function() {
+    $("#hid_category_id").change(function() {
+       $("#hid_category_id option:selected").each(function () {
+           var cat_id = $(this).val();
+            $.ajax({
+                url: "'.api_get_path(WEB_AJAX_PATH).'gradebook.ajax.php?a=get_gradebook_weight",
+                data: "cat_id="+cat_id,
+                success: function(return_value) {
+                    if (return_value != 0 ) {
+                        $("#max_weight").html(return_value);
+                    }
+                }
+            });
+       });
+    });
+});
+</script>';
+
+Display::display_header(get_lang('NewEvaluation'));
+
+$form->display();
+
+Display::display_footer();