Procházet zdrojové kódy

Adding new question tool table with extra fields using jqgrid

Julio Montoya před 11 roky
rodič
revize
27d7a1003c

+ 2 - 1
main/exercice/exercice.php

@@ -414,7 +414,8 @@ if ($is_allowedToEdit && $origin != 'learnpath') {
         echo Display::return_icon('folder_global_category.png', get_lang('QuestionGlobalCategory'), array(), ICON_SIZE_MEDIUM);
         echo '</a>';
     }
-    echo '<a href="question_pool.php">';
+
+    echo '<a href="'.api_get_path(WEB_PUBLIC_PATH).'courses/'.api_get_course_path().'/'.api_get_session_id().'/exercise/question-pool">';
     echo Display::return_icon('database.png', get_lang('QuestionPool'), array('style' => 'width:32px'));
     echo '</a>';
 

+ 98 - 62
main/exercice/question.class.php

@@ -44,6 +44,7 @@ abstract class Question
     public $submitClass;
     public $submitText;
     public $setDefaultQuestionValues = false;
+    public $c_id = null;
 
     public static $questionTypes = array(
         UNIQUE_ANSWER                          => array('unique_answer.class.php', 'UniqueAnswer'),
@@ -154,7 +155,6 @@ abstract class Question
         $TBL_QUESTIONS         = Database::get_course_table(TABLE_QUIZ_QUESTION);
         $TBL_EXERCICE_QUESTION = Database::get_course_table(TABLE_QUIZ_TEST_QUESTION);
 
-        //$sql = "SELECT * FROM $TBL_QUESTIONS WHERE iid = $id AND c_id = $course_id";
         $sql = "SELECT * FROM $TBL_QUESTIONS WHERE iid = $id";
 
         $result = Database::query($sql);
@@ -178,8 +178,8 @@ abstract class Question
                 $objQuestion->parent_id     = $object->parent_id;
                 $objQuestion->category_list = Testcategory::getCategoryForQuestion($id);
                 $objQuestion->exercise      = $exercise;
+                $objQuestion->c_id          = $object->c_id;
 
-                //$sql = "SELECT exercice_id FROM $TBL_EXERCICE_QUESTION WHERE c_id = $course_id AND question_id = $id";
                 $sql = "SELECT exercice_id FROM $TBL_EXERCICE_QUESTION WHERE question_id = $id";
                 $result_exercise_list = Database::query($sql);
 
@@ -1680,10 +1680,13 @@ abstract class Question
             echo Display::return_icon('database_na.png', get_lang('GetExistingQuestion'));
         } else {
             if ($feedback_type == 1) {
-                echo $url = '<a href="question_pool.php?'.api_get_cidreq().'&type=1&fromExercise='.$exerciseId.'">';
+                //echo $url = '<a href="question_pool.php?'.api_get_cidreq().'&type=1&fromExercise='.$exerciseId.'">';
             } else {
-                echo $url = '<a href="question_pool.php?'.api_get_cidreq().'&fromExercise='.$exerciseId.'">';
+                //echo $url = '<a href="question_pool.php?'.api_get_cidreq().'&fromExercise='.$exerciseId.'">';
             }
+
+            echo $url = '<a href="'.api_get_path(WEB_PUBLIC_PATH).'courses/'.api_get_course_path().'/'.api_get_session_id().'/exercise/'.$exerciseId.'/question-pool">';
+
             echo Display::return_icon('database.png', get_lang('GetExistingQuestion'));
         }
         echo '</a>';
@@ -1991,9 +1994,10 @@ abstract class Question
 
     /**
      * Get question columns needed for the new question pool page
+     * @param int course code
      * @return array
      */
-    public static function getQuestionColumns()
+    public static function getQuestionColumns($courseCode = null)
     {
         // The order is important you need to check the the $column variable in the model.ajax.php file
         //$columns = array('id', get_lang('Name'), get_lang('Description'));
@@ -2022,23 +2026,23 @@ abstract class Question
             )*/
         );
 
+        // Extra field rules.
         $extraField = new \ExtraField('question');
-
         $rules = $extraField->getRules($columns, $columnModel);
 
-        // Exercise rules
-        self::getRules($rules, $columns, $columnModel);
+        // Exercise rules.
+        self::getRules($courseCode, $rules, $columns, $columnModel);
 
         $columns[] = get_lang('Actions');
 
-         $columnModel[] = array(
-             'name'      => 'actions',
-             'index'     => 'actions',
-             'width'     => '30',
-             'align'     => 'left',
-             'formatter' => 'action_formatter',
-             'sortable'  => 'false'
-         );
+        $columnModel[] = array(
+            'name'      => 'actions',
+            'index'     => 'actions',
+            'width'     => '30',
+            'align'     => 'left',
+            'formatter' => 'action_formatter',
+            'sortable'  => 'false'
+        );
 
         foreach ($columnModel as $col_model) {
             $simple_column_name[] = $col_model['name'];
@@ -2059,7 +2063,7 @@ abstract class Question
      * @param array $options
      * @return array
      */
-    public static function getQuestions($categoryId, $options, $get_count = false)
+    public static function getQuestions($categoryId, $exerciseId, $courseId, $options, $get_count = false)
     {
         $questionTable = Database::get_course_table(TABLE_QUIZ_QUESTION);
 
@@ -2106,11 +2110,10 @@ abstract class Question
         $where = $options['where'];
 
         $newQuestionPoolField = array();
-        foreach ($options['question'] as $question) {
-            if (isset($questionPoolFields[$question['field']])) {
-                $newQuestionPoolField[$question['field']] = $questionPoolFields[$question['field']];
-                if ($question['data'] == -1) {
-
+        if (isset($options['question'])) {
+            foreach ($options['question'] as $question) {
+                if (isset($questionPoolFields[$question['field']])) {
+                    $newQuestionPoolField[$question['field']] = $questionPoolFields[$question['field']];
                 }
             }
         }
@@ -2127,7 +2130,6 @@ abstract class Question
                 $inject_question_fields .= $option['inject_fields'];
             }
         }
-        //var_dump($inject_question_fields);
 
         $options['where'] = $where;
 
@@ -2148,22 +2150,40 @@ abstract class Question
             $select = " SELECT s.*, $inject_extra_fields $inject_question_fields 1 ";
         }
 
-        $categoryCondition = null;
+        $extraCondition = null;
 
         if (!empty($categoryId)) {
             $categoryRelQuestionTable = Database::get_course_table(TABLE_QUIZ_QUESTION_REL_CATEGORY);
-            $categoryCondition = " INNER JOIN $categoryRelQuestionTable c ON (s.iid = c.question_id)";
+            $extraCondition = " INNER JOIN $categoryRelQuestionTable c ON (s.iid = c.question_id)";
             $categoryId = intval($categoryId);
             $where .= " AND category_id = $categoryId ";
         }
 
-        $query = " $select FROM $questionTable s $inject_joins $categoryCondition WHERE 1=1 $where $inject_where $order $limit";
+        if (!empty($exerciseId)) {
+            $exerciseRelQuestionTable = Database::get_course_table(TABLE_QUIZ_TEST_QUESTION);
+            $extraCondition .= " INNER JOIN $exerciseRelQuestionTable e ON (s.iid = e.question_id)";
+            $exerciseId = intval($exerciseId);
+            $where .= " AND exercice_id = $exerciseId ";
+        }
+
+        if (!empty($courseId)) {
+            $courseId = intval($courseId);
+            $where .= " AND s.c_id = $courseId ";
+        }
+
+        $query = " $select FROM $questionTable s $inject_joins $extraCondition WHERE 1=1 $where $inject_where $order $limit";
         //echo $query.'<br />';
 
         $result = Database::query($query);
         $questions = array();
         if (Database::num_rows($result)) {
             $questions = Database::store_result($result, 'ASSOC');
+            foreach ($questions as &$question) {
+                if (empty($question['c_id'])) {
+                    /*var_dump($question);
+                    $question['actions'] = 'ddd';*/
+                }
+            }
             if ($get_count) {
                 return $questions[0]['total_rows'];
             }
@@ -2176,7 +2196,14 @@ abstract class Question
         return Display::label($title, 'warning');
     }
 
-    public static function getRules(&$rules, &$columns, &$column_model)
+    /**
+     * @param $courseCode
+     * @param $rules
+     * @param $columns
+     * @param $column_model
+     * @return array
+     */
+    public static function getRules($courseCode, &$rules, &$columns, &$column_model)
     {
         // sessions
         // course
@@ -2185,43 +2212,47 @@ abstract class Question
         // difficult
         // type
 
-        // Session
-        $sessionList = SessionManager::get_sessions_by_general_coach(api_get_user_id());
-        $fields = array();
-        if (!empty($sessionList)) {
-            $new_options = array();
-            $new_options[] = "-1:".get_lang('All');
-            foreach ($sessionList as $session) {
-                $new_options[] = "{$session['id']}:{$session['name']}";
-            }
-            $string = implode(';', $new_options);
-            $fields[] = array(
-                'field_display_text' => get_lang('Session'),
-                'field_variable' => 'session_id',
-                'field_type' => ExtraField::FIELD_TYPE_SELECT,
-                'field_default_value' => null,
-                'field_options' => $string
-            );
-        }
+        if (empty($courseCode)) {
 
-        // Courses
+            // Session
+            $sessionList = SessionManager::get_sessions_by_general_coach(api_get_user_id());
+            $fields = array();
+            if (!empty($sessionList)) {
+                $new_options = array();
+                $new_options[] = "-1:".get_lang('All');
+                foreach ($sessionList as $session) {
+                    $new_options[] = "{$session['id']}:{$session['name']}";
+                }
+                $string = implode(';', $new_options);
+                $fields[] = array(
+                    'field_display_text' => get_lang('Session'),
+                    'field_variable' => 'session_id',
+                    'field_type' => ExtraField::FIELD_TYPE_SELECT,
+                    'field_default_value' => null,
+                    'field_options' => $string
+                );
+            }
 
-        $courseList = CourseManager::get_course_list_of_user_as_course_admin(api_get_user_id());
+            // Courses
+            $courseList = CourseManager::get_course_list_of_user_as_course_admin(api_get_user_id());
 
-        if (!empty($courseList)) {
-            $new_options = array();
-            $new_options[] = "-1:".get_lang('All');
-            foreach ($courseList as $course) {
-                $new_options[] = "{$course['id']}:{$course['title']}";
+            if (!empty($courseList)) {
+                $new_options = array();
+                $new_options[] = "-1:".get_lang('All');
+                foreach ($courseList as $course) {
+                    $new_options[] = "{$course['id']}:{$course['title']}";
+                }
+                $string = implode(';', $new_options);
+                $fields[] = array(
+                    'field_display_text' => get_lang('Course'),
+                    'field_variable' => 'c_id',
+                    'field_type' => ExtraField::FIELD_TYPE_SELECT,
+                    'field_default_value' => null,
+                    'field_options' => $string
+                );
             }
-            $string = implode(';', $new_options);
-            $fields[] = array(
-                'field_display_text' => get_lang('Course'),
-                'field_variable' => 'c_id',
-                'field_type' => ExtraField::FIELD_TYPE_SELECT,
-                'field_default_value' => null,
-                'field_options' => $string
-            );
+        } else {
+            $courseList = array(api_get_course_info());
         }
 
         // Categories
@@ -2275,6 +2306,7 @@ abstract class Question
         if (!empty($exerciseList)) {
             $new_options = array();
             $new_options[] = "-1:".get_lang('All');
+            $new_options[] = "0:".get_lang('Orphan');
             foreach ($exerciseList as $exercise) {
                 $new_options[] = "{$exercise['iid']}:{$exercise['title']}";
             }
@@ -2288,6 +2320,7 @@ abstract class Question
             );
         }
 
+
         // Question type
         $questionList = Question::get_question_type_list();
 
@@ -2333,6 +2366,7 @@ abstract class Question
                 if (in_array($field['field_type'], array(ExtraField::FIELD_TYPE_SELECT, ExtraField::FIELD_TYPE_DOUBLE_SELECT))) {
                     $type                   = 'select';
                     $search_options['sopt'] = array('eq', 'ne'); //equal not equal
+                    //$search_options['sopt'] = array('cn', 'nc'); //contains not contains
                 } else {
                     $search_options['sopt'] = array('cn', 'nc'); //contains not contains
                 }
@@ -2351,11 +2385,13 @@ abstract class Question
                     'searchoptions' => $search_options
                 );
                 $columns[] = $field['field_display_text'];
-                $rules[] = array('field' => 'question_'.$field['field_variable'], 'op' => 'cn');
+                $rules[] = array(
+                    'field' => 'question_'.$field['field_variable'],
+                    'op' => 'eq'
+                );
             }
         }
 
         return $rules;
     }
-
 }

+ 1 - 1
main/exercice/question_list_admin.inc.php

@@ -208,7 +208,7 @@ if (!$inATest) {
                         echo '<br />';
                         //echo get_lang('Level').': '.$objQuestionTmp->selectLevel();
                         echo '<br />';
-                        ExerciseLib::showQuestion($objQuestionTmp, false, null, null, false, true, false, true, $objExercise->feedback_type, true);
+                        echo ExerciseLib::showQuestion($objQuestionTmp, false, null, null, false, true, false, true, $objExercise->feedback_type, true);
                         echo '</p>';
                     echo '</div>';
                 echo '</div>';

+ 6 - 3
main/inc/ajax/exercise.ajax.php

@@ -65,9 +65,12 @@ switch ($action) {
         if (!in_array($sord, array('asc','desc'))) {
             $sord = 'desc';
         }
+
         // get index row - i.e. user click to sort $sord = $_GET['sord'];
         // get the direction
-        if (!$sidx) $sidx = 1;
+        if (!$sidx) {
+            $sidx = 1;
+        }
 
         $track_exercise        = Database::get_statistic_table(TABLE_STATISTIC_TRACK_E_EXERCICES);
         $user_table            = Database::get_main_table(TABLE_MAIN_USER);
@@ -127,7 +130,7 @@ switch ($action) {
 
         $result = Database::query($sql);
         $results = array();
-        while ($row = Database::fetch_array($result,'ASSOC')){
+        while ($row = Database::fetch_array($result, 'ASSOC')) {
             $results[] = $row;
         }
 
@@ -456,4 +459,4 @@ switch ($action) {
     default:
         echo '';
 }
-exit;
+exit;

+ 15 - 18
main/inc/ajax/model.ajax.php

@@ -156,7 +156,6 @@ if ($_REQUEST['_search'] == 'true') {
             $where_condition .= implode($filters->groupOp, $condition_array);
             $where_condition .= ' ) ';
         }
-
     }
 }
 
@@ -172,14 +171,13 @@ if (!$sidx) {
 switch ($action) {
     case 'get_questions':
         $categoryId = isset($_REQUEST['categoryId']) ? $_REQUEST['categoryId'] : null;
+        $exerciseId = isset($_REQUEST['exerciseId']) ? $_REQUEST['exerciseId'] : null;
+        $courseId = isset($_REQUEST['courseId']) ? $_REQUEST['courseId'] : null;
         /** @var \Doctrine\ORM\EntityManager $em */
         /*$em = $app['orm.em'];
         $repo = $em->getRepository('Entity\CQuizQuestionRelCategory');
         $count = $repo->getCountQuestionByCategory($categoryId);*/
-        if (isset($_REQUEST['categoryId'])) {
-            $categoryId = intval($_REQUEST['categoryId']);
-        }
-        $count = Question::getQuestions($categoryId, array('where'=> $where_condition, 'extra' => $extra_fields, 'question' => $questionFields), true);
+        $count = Question::getQuestions($categoryId, $exerciseId, $courseId, array('where'=> $where_condition, 'extra' => $extra_fields, 'question' => $questionFields), true);
         break;
     case 'get_user_list_plugin_widescale':
         $count = UserManager::get_user_data(null, null, null, null, true);
@@ -344,7 +342,7 @@ switch ($action) {
         $columns = Question::getQuestionColumns();
         $columns = $columns['simple_column_name'];
         //var_dump($columns);
-        $result = Question::getQuestions($categoryId, array('where'=> $where_condition, 'order'=>"$sidx $sord", 'extra' => $extra_fields, 'question' => $questionFields, 'limit'=> "$start , $limit"));
+        $result = Question::getQuestions($categoryId, $exerciseId, $courseId, array('where'=> $where_condition, 'order'=>"$sidx $sord", 'extra' => $extra_fields, 'question' => $questionFields, 'limit'=> "$start , $limit"));
 
         break;
     case 'get_user_list_plugin_widescale':
@@ -641,19 +639,19 @@ switch ($action) {
             $result = $new_result;
         }*/
         break;
-      case 'get_usergroups_teacher':
+    case 'get_usergroups_teacher':
         $columns = array('name', 'users', 'actions');
         $options = array('order'=>"name $sord", 'LIMIT'=> "$start , $limit");
         $options['course_id'] = $course_id;
         switch ($type) {
-            case 'not_registered':
-                $options['where'] = array(" (course_id IS NULL OR course_id != ?) " => $course_id);
-                $result = $obj->get_usergroup_not_in_course($options);
-                break;
-            case 'registered':
-                $options['where'] = array(" usergroup.course_id = ? " =>  $course_id);
-                $result = $obj->get_usergroup_in_course($options);
-                break;
+        case 'not_registered':
+            $options['where'] = array(" (course_id IS NULL OR course_id != ?) " => $course_id);
+            $result = $obj->get_usergroup_not_in_course($options);
+            break;
+        case 'registered':
+            $options['where'] = array(" usergroup.course_id = ? " =>  $course_id);
+            $result = $obj->get_usergroup_in_course($options);
+            break;
         }
         $new_result = array();
 
@@ -674,13 +672,12 @@ switch ($action) {
             }
             $result = $new_result;
         }
-        if(!in_array($sidx, $columns)) {
+        if (!in_array($sidx, $columns)) {
             $sidx = 'name';
         }
         //Multidimensional sort
-          ArrayClass::msort($result, $sidx);
+        ArrayClass::msort($result, $sidx);
         break;
-
     default:
         exit;
 }

+ 27 - 32
main/inc/lib/exercise.lib.php

@@ -25,7 +25,8 @@ class ExerciseLib
      * @param int   current item from the list of questions
      * @param int   number of total questions
      * */
-    public static function showQuestion($objQuestionTmp, $only_questions = false, $origin = false, $current_item = '', $show_title = true, $freeze = false, $user_choice = array(), $show_comment = false, $exercise_feedback = null, $show_answers = false) {
+    public static function showQuestion($objQuestionTmp, $only_questions = false, $origin = false, $current_item = '', $show_title = true, $freeze = false, $user_choice = array(), $show_comment = false, $exercise_feedback = null, $show_answers = false)
+    {
         // Text direction for the current language
         //$is_ltr_text_direction = api_get_text_direction() != 'rtl';
         // Change false to true in the following line to enable answer hinting
@@ -36,6 +37,8 @@ class ExerciseLib
             return false;
         }
 
+        $html = null;
+
         $questionId = $objQuestionTmp->id;
 
         if ($exercise_feedback != EXERCISE_FEEDBACK_TYPE_END) {
@@ -53,19 +56,19 @@ class ExerciseLib
             if (!$only_questions) {
                 $questionDescription = $objQuestionTmp->selectDescription();
                 if ($show_title) {
-                    echo Testcategory::getCategoryNamesForQuestion($objQuestionTmp->id);
-                    echo Display::div($current_item.'. '.$objQuestionTmp->selectTitle(), array('class' => 'question_title'));
+                    $html .= Testcategory::getCategoryNamesForQuestion($objQuestionTmp->id);
+                    $html .= Display::div($current_item.'. '.$objQuestionTmp->selectTitle(), array('class' => 'question_title'));
                 }
                 if (!empty($questionDescription)) {
-                    echo Display::div($questionDescription, array('class' => 'question_description'));
+                    $html .= Display::div($questionDescription, array('class' => 'question_description'));
                 }
             }
 
             if (in_array($answerType, array(FREE_ANSWER, ORAL_EXPRESSION)) && $freeze) {
-                return '';
+                return null;
             }
 
-            echo '<div class="question_options">';
+            $html .= '<div class="question_options">';
             // construction of the Answer object (also gets all answers details)
             $objAnswerTmp = new Answer($questionId);
 
@@ -126,9 +129,7 @@ class ExerciseLib
                 $num_suggestions = ($nbrAnswers - $j) + 1;
             } elseif ($answerType == FREE_ANSWER) {
                 $fck_content = isset($user_choice[0]) && !empty($user_choice[0]['answer']) ? $user_choice[0]['answer'] : null;
-
                 $oFCKeditor = new FCKeditor("choice[".$questionId."]");
-
                 $oFCKeditor->ToolbarSet = 'TestFreeAnswer';
                 $oFCKeditor->Width = '100%';
                 $oFCKeditor->Height = '200';
@@ -156,7 +157,7 @@ class ExerciseLib
                     }
 
                     $nano = new Nanogong($params);
-                    echo $nano->show_button();
+                    $s .= $nano->show_button();
                 }
 
                 $oFCKeditor = new FCKeditor("choice[".$questionId."]");
@@ -181,7 +182,7 @@ class ExerciseLib
                     $header .= Display::tag('th', get_lang('Feedback'));
                 }
                 $s .= '<table class="data_table">';
-                $s.= Display::tag('tr', $header, array('style' => 'text-align:left;'));
+                $s .= Display::tag('tr', $header, array('style' => 'text-align:left;'));
             }
 
             if ($show_comment) {
@@ -455,7 +456,7 @@ class ExerciseLib
                     // TODO: replace $answerId by $numAnswer
 
                     if ($lines_count == 1) {
-                        echo $objAnswerTmp->getJs();
+                        $s .= $objAnswerTmp->getJs();
                     }
                     if ($answerCorrect != 0) {
                         // only show elements to be answered (not the contents of
@@ -634,7 +635,6 @@ class ExerciseLib
 
                 $counterAnswer = 1;
                 foreach ($objAnswerTmp->answer as $answerId => $answer_item) {
-                //for ($answerId = 1; $answerId <= $nbrAnswers; $answerId++) {
                     $answerCorrect = $objAnswerTmp->isCorrect($answerId);
                     $windowId = $questionId.'_'.$counterAnswer;
                     if ($answerCorrect == 0) {
@@ -656,11 +656,8 @@ class ExerciseLib
             // destruction of the Question object
             unset($objQuestionTmp);
 
-            if ($origin != 'export') {
-                echo $s;
-            } else {
-                return $s;
-            }
+            $html .= $s;
+            return $html;
         } elseif ($answerType == HOT_SPOT || $answerType == HOT_SPOT_DELINEATION) {
             // Question is a HOT_SPOT
             //checking document/images visibility
@@ -679,17 +676,16 @@ class ExerciseLib
             $questionDescription = $objQuestionTmp->selectDescription();
 
             if ($freeze) {
-                echo Display::img($objQuestionTmp->selectPicturePath());
-                return;
+                $s .= Display::img($objQuestionTmp->selectPicturePath());
+                $html .= $s;
+                return $html;
             }
 
             // Get the answers, make a list
             $objAnswerTmp = new Answer($questionId);
-            $nbrAnswers = $objAnswerTmp->selectNbrAnswers();
 
             // get answers of hotpost
             $answers_hotspot = array();
-            //for ($answerId = 1; $answerId <= $nbrAnswers; $answerId++) {
             foreach ($objAnswerTmp->answer as $answerId => $answer_item) {
                 //$answers = $objAnswerTmp->selectAnswerByAutoId($objAnswerTmp->selectAutoId($answerId));
                 $answers_hotspot[$answerId] = $objAnswerTmp->selectAnswer($answerId);
@@ -716,16 +712,16 @@ class ExerciseLib
 
             if (!$only_questions) {
                 if ($show_title) {
-                    echo Testcategory::getCategoryNamesForQuestion($objQuestionTmp->id);
-                    echo '<div class="question_title">'.$current_item.'. '.$questionName.'</div>';
+                    $html .=  Testcategory::getCategoryNamesForQuestion($objQuestionTmp->id);
+                    $html .=  '<div class="question_title">'.$current_item.'. '.$questionName.'</div>';
                 }
                 //@todo I need to the get the feedback type
-                echo '<input type="hidden" name="hidden_hotspot_id" value="'.$questionId.'" />';
-                echo '<table class="exercise_questions" >
+                $html .=  '<input type="hidden" name="hidden_hotspot_id" value="'.$questionId.'" />';
+                $html .=  '<table class="exercise_questions" >
                       <tr>
                         <td valign="top" colspan="2">';
-                echo $questionDescription;
-                echo '</td></tr>';
+                $html .=  $questionDescription;
+                $html .=  '</td></tr>';
             }
             $canClick = isset($_GET['editQuestion']) ? '0' : (isset($_GET['modifyAnswers']) ? '0' : '1');
 
@@ -841,7 +837,6 @@ class ExerciseLib
                             </script>';
             $s .= '<tr><td valign="top" colspan="2" width="520"><table><tr><td width="520">
                         <script>
-                            <!--
                             // Version check based upon the values entered above in "Globals"
                             var hasReqestedVersion = DetectFlashVer(requiredMajorVersion, requiredMinorVersion, requiredRevision);
 
@@ -858,14 +853,14 @@ class ExerciseLib
                                     + "<a href=\"http://www.macromedia.com/go/getflash/\">Get Flash<\/a>";
                                 document.write(alternateContent);  // insert non-flash content
                             }
-                            // -->
                         </script>
                         </td>
                         <td valign="top" align="left">'.$answer_list.'</td></tr>
                         </table>
             </td></tr>';
-            echo $s;
-            echo '</table>';
+            $html .= $s;
+            $html .= '</table>';
+            return $html;
         }
         return $nbrAnswers;
     }
@@ -2673,7 +2668,7 @@ class ExerciseLib
         echo '<div id="question_div_'.$questionId.'" class="main_question '.$remind_highlight.'" >';
 
         // Shows the question + possible answers
-        ExerciseLib::showQuestion($question_obj, false, $origin, $i, true, false, $user_choice, false);
+        echo ExerciseLib::showQuestion($question_obj, false, $origin, $i, true, false, $user_choice, false);
 
         // Button save and continue
         switch ($objExercise->type) {

+ 11 - 6
main/inc/lib/extra_field.lib.php

@@ -1304,16 +1304,17 @@ EOF;
         $condition_array = array();
 
         foreach ($filters->rules as $rule) {
+
             if (strpos($rule->field, $stringToSearch) === false) {
                 //normal fields
                 $field = $rule->field;
-                if (!empty($rule->data) && $rule->data != -1) {
+
+                if (isset($rule->data) && $rule->data != -1) {
                     $condition_array[] = get_where_clause($field, $rule->op, $rule->data);
                 }
             } else {
-                //Extra fields
+                // Extra fields
 
-                //normal
                 if (strpos($rule->field, '_second') === false) {
                     //No _second
                     $original_field = str_replace($stringToSearch, '', $rule->field);
@@ -1329,12 +1330,13 @@ EOF;
                             $data = explode('#', $rule->data);
                             $rule->data = $data[1];
                         }
-                        if (!empty($rule->data)) {
+
+                        if (!isset($rule->data)) {
                             $condition_array[] = ' ('.get_where_clause($rule->field, $rule->op, $rule->data).') ';
                             $extra_fields[] = array('field' => $rule->field, 'id' => $field_option['id']);
                         }
                     } else {
-                        if (!empty($rule->data)) {
+                        if (isset($rule->data)) {
                             if ($rule->data == -1) {
                                 continue;
                             }
@@ -1350,7 +1352,10 @@ EOF;
                     $my_field = str_replace('_second', '', $rule->field);
                     $original_field = str_replace($stringToSearch, '', $my_field);
                     $field_option = $this->get_handler_field_info_by_field_variable($original_field);
-                    $extra_fields[] = array('field' => $rule->field, 'id' => $field_option['id']);
+                    $extra_fields[] = array(
+                        'field' => $rule->field,
+                        'id' => $field_option['id']
+                    );
                 }
             }
         }

+ 2 - 0
main/inc/lib/template.lib.php

@@ -270,6 +270,8 @@ class Template
     {
         //Setting course id
         $this->course_id = api_get_course_int_id();
+        $this->app['course_code'] = api_get_course_id();
+        $this->app['session_id'] = api_get_session_id();
     }
 
     /**

+ 2 - 1
main/template/default/admin/questionmanager/edit_question.tpl

@@ -1,4 +1,5 @@
 {% extends app.template_style ~ "/layout/layout_1_col.tpl" %}
 {% block content %}
+    <h3> {{ question.question }} </h3>
     {{ form }}
-{% endblock %}
+{% endblock %}

+ 4 - 0
main/template/default/exercise/question/edit_question.tpl

@@ -0,0 +1,4 @@
+{% extends app.template_style ~ "/layout/layout_1_col.tpl" %}
+{% block content %}
+    {{ form }}
+{% endblock %}

+ 15 - 0
main/template/default/exercise/question/show_question.tpl

@@ -0,0 +1,15 @@
+{% extends app.template_style ~ "/layout/layout_1_col.tpl" %}
+{% block content %}
+    {% if (app.request.get('exerciseId')) %}
+        <a href="{{ app.url_generator.generate('exercise_dashboard', {cidReq : app.course_code, id_session:app.session_id, exerciseId: app.request.get('exerciseId') }) }}">
+            <img src="{{ "back.png"|icon(22) }}">
+        </a>
+    {% endif  %}
+    <h3>{{ question.question }}
+        <a href="{{ app.url_generator.generate('exercise_question_edit', {cidReq : app.course_code, id_session:app.session_id, id: question.id }) }}">
+            <img src="{{ "edit.png"|icon(22) }}">
+        </a>
+    </h3>
+
+    {{ question_preview }}
+{% endblock %}

+ 11 - 11
src/ChamiloLMS/Controller/Admin/QuestionManager/QuestionManagerController.php

@@ -25,7 +25,7 @@ class QuestionManagerController
     }
 
     /**
-     * Edits a question
+     * Edits a question for the question manager
      *
      * @param Application $app
      * @param int $id
@@ -59,21 +59,21 @@ class QuestionManagerController
 
         // Creating a new form
         $form = new \FormValidator('edit_question', 'post', $url);
-        $question->createForm($form);
-        $form->freeze();
-        $question->createAnswersForm($form);
 
-        $submitQuestion = $app['request']->get('submitQuestion');
+        $extraFields = new \ExtraField('question');
+        $extraFields->add_elements($form, $id);
 
-        // If form was submitted.
-        if ($form->validate() && isset($submitQuestion)) {
-            // Save question.
-            $question->processCreation($form, $exercise);
+        $form->addElement('button', 'submit', get_lang('Update'));
 
-            // Save answers.
-            $question->processAnswersCreation($form);
+        // If form was submitted.
+        if ($form->validate()) {
+            $field_value = new \ExtraFieldValue('question');
+            $params = $form->exportValues();
+            $params['question_id'] = $id;
+            $field_value->save_field_values($params);
         }
 
+        $app['template']->assign('question', $question);
         $app['template']->assign('form', $form->toHtml());
         $response = $app['template']->render_template('admin/questionmanager/edit_question.tpl');
 

+ 142 - 13
src/ChamiloLMS/Controller/ExerciseController.php

@@ -14,13 +14,48 @@ use Symfony\Component\HttpKernel\HttpKernelInterface;
  */
 class ExerciseController
 {
+
+    public function dashboardAction(Application $app, $exerciseId)
+    {
+        $url = api_get_path(WEB_CODE_PATH).'exercice/admin.php?exerciseId='.$exerciseId.'&'.api_get_cidreq();
+        return $app->redirect($url);
+    }
+
     /**
      * @param Application $app
-     * @return Response
+     * @param $exerciseId
+     * @param $questionId
      */
-    public function questionPoolAction(Application $app)
+    public function copyQuestionAction(Application $app, $exerciseId, $questionId)
     {
+        $question = \Question::read($questionId);
+
+        if ($question) {
+            $question->updateTitle($question->selectTitle().' - '.get_lang('Copy'));
+            //Duplicating the source question, in the current course
+            $courseInfo = api_get_course_int_id();
+            $newId = $question->duplicate($courseInfo);
+            // Reading new question
+            $newQuestion = \Question::read($newId);
+            $newQuestion->addToList($exerciseId);
 
+            // Reading Answers obj of the current course
+            $newAnswer = new \Answer($questionId);
+            $newAnswer->read();
+            //Duplicating the Answers in the current course
+            $newAnswer->duplicate($newId);
+            $params = array('cidReq' => api_get_course_id(), 'id_session' => api_get_session_id(), 'id' => $newId, 'exerciseId' => $exerciseId);
+            $url = $app['url_generator']->generate('exercise_question_show', $params);
+            return $app->redirect($url);
+        }
+    }
+
+    /**
+     * @param Application $app
+     * @return Response
+     */
+    public function questionPoolAction(Application $app, $cidReq = null, $exerciseId = null)
+    {
         $extraJS = array();
         //@todo improve this JS includes should be added using twig
         $extraJS[]      = api_get_jqgrid_js();
@@ -34,7 +69,7 @@ class ExerciseController
             $rules[] = ;
         }*/
 
-        $questionColumns = \Question::getQuestionColumns();
+        $questionColumns = \Question::getQuestionColumns($cidReq);
         $columnModel     = $questionColumns['column_model'];
         $columns         = $questionColumns['columns'];
         $rules           = $questionColumns['rules'];
@@ -42,7 +77,12 @@ class ExerciseController
         $grid = \Display::grid_html('questions');
 
         //jqgrid will use this URL to do the selects
-        $url = api_get_path(WEB_AJAX_PATH).'model.ajax.php?a=get_questions';
+        $extraConditions = null;
+        if (!empty($cidReq)) {
+            $extraConditions = "courseId=".api_get_course_int_id();
+        }
+
+        $url = api_get_path(WEB_AJAX_PATH).'model.ajax.php?a=get_questions&'.$extraConditions;
 
         $extraParams['postData'] = array(
             'filters' => array(
@@ -53,19 +93,26 @@ class ExerciseController
 
         // Autowidth.
         $extraParams['autowidth'] = 'true';
+
         // Height auto.
         $extraParams['height'] = 'auto';
         $token                 = null;
-        $editUrl               = $app['url_generator']->generate('admin_questions');
 
-        $actionLinks = 'function action_formatter(cellvalue, options, rowObject) {
-            return \'<a href="'.$editUrl.'/\'+rowObject[0]+\'/edit">'.\Display::return_icon(
-            'edit.png',
-            get_lang('Edit'),
-            '',
-            ICON_SIZE_SMALL
-        ).'</a>'.'\';
-        }';
+        $courseURL = $app['url_generator']->generate('course', array('cidReq' => api_get_course_id(), 'id_session' => api_get_session_id()));
+
+        $exerciseId = intval($exerciseId);
+        if (empty($exerciseId)) {
+            $actionLinks = 'function action_formatter(cellvalue, options, rowObject) {
+                return \' <a target="_blank" href="'.$courseURL.'exercise/question/\'+rowObject[0]+\'">'.\Display::return_icon('preview.gif',get_lang('View'),'', ICON_SIZE_SMALL).'</a>'.
+                         ' <a href="'.$courseURL.'exercise/question/\'+rowObject[0]+\'/edit">'.\Display::return_icon('edit.png',get_lang('Edit'),'', ICON_SIZE_SMALL).'</a>'.'\';
+            }';
+        } else {
+            $actionLinks = 'function action_formatter(cellvalue, options, rowObject) {
+                return \' <a target="_blank" href="'.$courseURL.'exercise/'.$exerciseId.'/question/\'+rowObject[0]+\'">'.\Display::return_icon('preview.gif',get_lang('View'),'', ICON_SIZE_SMALL).'</a>'.
+                         ' <a href=\"'.$courseURL.'exercise/'.$exerciseId.'/copy-question/\'+rowObject[0]+\'">'.\Display::return_icon('copy.png',get_lang('Copy'),'', ICON_SIZE_SMALL).'</a>'.
+                         ' <a href="'.$courseURL.'exercise/question/\'+rowObject[0]+\'/edit">'.\Display::return_icon('edit.png',get_lang('Edit'),'', ICON_SIZE_SMALL).'</a>'.'\';
+            }';
+        }
 
         $js = \Display::grid_js(
             'questions',
@@ -84,4 +131,86 @@ class ExerciseController
 
         return new Response($response, 200, array());
     }
+
+    /**
+     * @param Application $app
+     */
+    public function getQuestionAction(Application $app, $id, $exerciseId = null)
+    {
+        // Setting exercise obj.
+        if (!empty($exerciseId)) {
+            $exercise = new \Exercise();
+            $exercise->read($exerciseId);
+            $questionList = $exercise->questionList;
+            if (!in_array($id, $questionList)) {
+                return $app->abort(401);
+            }
+        } else {
+            $exercise = new \Exercise();
+            $exercise->edit_exercise_in_lp = true;
+        }
+
+        $question = \Question::read($id, null, $exercise);
+
+        $questionHTML = \ExerciseLib::showQuestion($question, false, null, null, false, true, false, true, $exercise->feedback_type, true);
+        $app['template']->assign('question_preview', $questionHTML);
+        $app['template']->assign('question', $question);
+        $response = $app['template']->render_template('exercise/question/show_question.tpl');
+
+        return new Response($response, 200, array());
+    }
+
+     /**
+     * Edits a question
+     *
+     * @param Application $app
+     * @param int $id
+     * @return Response
+     */
+    public function editQuestionAction(Application $app, $id)
+    {
+        $extraJS = array();
+        //@todo improve this JS includes should be added using twig
+        $extraJS[]      = '<link href="'.api_get_path(WEB_LIBRARY_PATH).'javascript/tag/style.css" rel="stylesheet" type="text/css" />';
+        $extraJS[]      = '<script src="'.api_get_path(WEB_LIBRARY_PATH).'javascript/tag/jquery.fcbkcomplete.js" type="text/javascript" language="javascript"></script>';
+        $app['extraJS'] = $extraJS;
+
+        // Setting exercise obj.
+        $exercise                      = new \Exercise();
+        $exercise->edit_exercise_in_lp = true;
+
+        // Setting question obj.
+        /** @var  \Question $question */
+        $question                   = \Question::read($id, null, $exercise);
+        $question->submitClass      = "btn save";
+        $question->submitText       = get_lang('ModifyQuestion');
+        $question->setDefaultValues = true;
+
+        // Generating edit URL.
+        $url = $app['url_generator']->generate('exercise_question_edit', array('cidReq' => api_get_course_id(), 'id_session' => api_get_session_id(), 'id' => $id));
+
+        // Creating a new form
+        $form = new \FormValidator('edit_question', 'post', $url);
+        $question->createForm($form);
+        $question->createAnswersForm($form);
+
+        $submitQuestion = $app['request']->get('submitQuestion');
+
+        // If form was submitted.
+        if ($form->validate() && isset($submitQuestion)) {
+            // Save question.
+            $question->processCreation($form, $exercise);
+
+            // Save answers.
+            $question->processAnswersCreation($form);
+
+            $url = $app['url_generator']->generate('exercise_question_show', array('cidReq' => api_get_course_id(), 'id_session' => api_get_session_id(), 'id' => $id));
+            return $app->redirect($url);
+        }
+
+        $app['template']->assign('form', $form->toHtml());
+        $response = $app['template']->render_template('admin/questionmanager/edit_question.tpl');
+
+        return new Response($response, 200, array());
+    }
 }