Kaynağa Gözat

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

Alex 11 yıl önce
ebeveyn
işleme
55fbdb8190
100 değiştirilmiş dosya ile 3426 ekleme ve 2572 silme
  1. 2 1
      composer.json
  2. 21 0
      documentation/optimization.html
  3. 0 88
      main/admin/calendar.lib.php
  4. 2 1
      main/admin/configure_homepage.php
  5. 5 5
      main/admin/configure_plugin.php
  6. 5 4
      main/admin/settings.lib.php
  7. 28 0
      main/admin/update_last_login.php
  8. 0 1
      main/admin/user_list.php
  9. 11 4
      main/announcements/announcements.inc.php
  10. 28 0
      main/auth/inscription.php
  11. 98 899
      main/calendar/agenda.inc.php
  12. 553 170
      main/calendar/agenda.lib.php
  13. 219 231
      main/calendar/agenda.php
  14. 61 53
      main/calendar/agenda_js.php
  15. 16 6
      main/calendar/agenda_list.php
  16. 13 9
      main/course_info/delete_course.php
  17. 52 34
      main/course_info/infocours.php
  18. 129 65
      main/coursecopy/classes/CourseRecycler.class.php
  19. 11 5
      main/coursecopy/classes/CourseRestorer.class.php
  20. 29 8
      main/coursecopy/classes/CourseSelectForm.class.php
  21. 10 4
      main/coursecopy/copy_course.php
  22. 16 12
      main/coursecopy/create_backup.php
  23. 19 9
      main/coursecopy/import_backup.php
  24. 14 10
      main/coursecopy/recycle_course.php
  25. 5 0
      main/css/academica/dataTable.css
  26. 5 0
      main/css/baby_orange/dataTable.css
  27. 31 2
      main/css/base.css
  28. 5 0
      main/css/blue_lagoon/dataTable.css
  29. 5 0
      main/css/chamilo/dataTable.css
  30. 32 31
      main/css/chamilo/default.css
  31. 5 0
      main/css/chamilo_electric_blue/dataTable.css
  32. 5 0
      main/css/chamilo_green/dataTable.css
  33. 5 0
      main/css/chamilo_orange/dataTable.css
  34. 5 0
      main/css/chamilo_red/dataTable.css
  35. 5 0
      main/css/chamilo_sport_red/dataTable.css
  36. 5 0
      main/css/cool_blue/dataTable.css
  37. 5 0
      main/css/corporate/dataTable.css
  38. 5 0
      main/css/cosmic_campus/dataTable.css
  39. 5 0
      main/css/delicious_bordeaux/dataTable.css
  40. 5 0
      main/css/dokeos_blue/dataTable.css
  41. 5 0
      main/css/dokeos_classic/dataTable.css
  42. 5 0
      main/css/dokeos_classic_2D/dataTable.css
  43. 5 0
      main/css/empire_green/dataTable.css
  44. 5 0
      main/css/fruity_orange/dataTable.css
  45. 5 0
      main/css/kiddy/dataTable.css
  46. 5 0
      main/css/medical/dataTable.css
  47. 5 0
      main/css/public_admin/dataTable.css
  48. 5 0
      main/css/royal_purple/dataTable.css
  49. 5 0
      main/css/silver_line/dataTable.css
  50. 5 0
      main/css/sober_brown/dataTable.css
  51. 5 0
      main/css/steel_grey/dataTable.css
  52. 5 0
      main/css/tasty_olive/dataTable.css
  53. 3 2
      main/document/create_document.php
  54. 16 11
      main/document/document.inc.php
  55. 411 173
      main/document/document.php
  56. 3 4
      main/document/upload.php
  57. 3 3
      main/exercice/admin.php
  58. 45 21
      main/exercice/exercise.class.php
  59. 2 0
      main/exercice/exercise.lib.php
  60. 1 0
      main/exercice/exercise_result.php
  61. 38 31
      main/exercice/export/exercise_import.inc.php
  62. 12 14
      main/exercice/matching.class.php
  63. 11 14
      main/exercice/multiple_answer.class.php
  64. 25 27
      main/exercice/multiple_answer_combination.class.php
  65. 5 6
      main/exercice/multiple_answer_combination_true_false.class.php
  66. 83 85
      main/exercice/multiple_answer_true_false.class.php
  67. 4 6
      main/exercice/oral_expression.class.php
  68. 28 11
      main/exercice/qti2.php
  69. 91 79
      main/exercice/unique_answer.class.php
  70. 76 81
      main/exercice/unique_answer_no_option.class.php
  71. 115 64
      main/exercice/upload_exercise.php
  72. 12 2
      main/forum/forumfunction.inc.php
  73. 5 1
      main/gradebook/gradebook_add_link.php
  74. 6 1
      main/gradebook/gradebook_edit_link.php
  75. 32 16
      main/gradebook/index.php
  76. 17 7
      main/gradebook/lib/be/category.class.php
  77. 2 2
      main/group/example.csv
  78. 15 14
      main/group/group.php
  79. 32 18
      main/group/group_category.php
  80. 10 4
      main/group/group_creation.php
  81. 2 2
      main/group/group_edit.php
  82. 26 8
      main/group/group_space.php
  83. 22 3
      main/group/import.php
  84. 22 5
      main/group/settings.php
  85. BIN
      main/img/icons/32/week.png
  86. 33 10
      main/inc/ajax/agenda.ajax.php
  87. 1 1
      main/inc/ajax/document.ajax.php
  88. 68 15
      main/inc/ajax/model.ajax.php
  89. 52 30
      main/inc/ajax/myspace.ajax.php
  90. 8 0
      main/inc/global.inc.php
  91. 4 4
      main/inc/lib/banner.lib.php
  92. 152 42
      main/inc/lib/course.lib.php
  93. 30 6
      main/inc/lib/course_category.lib.php
  94. 1 1
      main/inc/lib/course_home.lib.php
  95. 6 4
      main/inc/lib/database.lib.php
  96. 147 80
      main/inc/lib/document.lib.php
  97. 2 1
      main/inc/lib/events.lib.inc.php
  98. 30 11
      main/inc/lib/fileUpload.lib.php
  99. 61 0
      main/inc/lib/formvalidator/Element/DatePicker.php
  100. 121 0
      main/inc/lib/formvalidator/Element/DateRangePicker.php

+ 2 - 1
composer.json

@@ -1,5 +1,6 @@
 {
     "require": {
-        "php-ffmpeg/php-ffmpeg": "0.3.x-dev@dev"
+        "php-ffmpeg/php-ffmpeg": "0.3.x-dev@dev",
+        "sabre/vobject" : "~3.1"
     }
 }

+ 21 - 0
documentation/optimization.html

@@ -174,6 +174,27 @@ If you prefer using <a href="http://php.net/manual/en/book.apc.php">APC</a>, you
      ...
 </pre>
 <p>It is also worth noting that the Université de Genève, Switzerland, observed that the calculation of the total size used by course documents is one of the heaviest queries in Chamilo, so you might want to cache the results of this one as well, using the same technique.</p>
+<p>Finally, if your portal is highly public *and* you are showing the popular courses on the homepage, you might want to also reduce the amount of queries this generates, using the same technique as above, but for the main/inc/lib/auth.lib.php library, looking for the "Tracking::get_course_connections_count()" call:</p>
+<pre>
+        while ($row = Database::fetch_array($result)) {
+            $row['registration_code'] = !empty($row['registration_code']);
+            $count_users = CourseManager::get_users_count_in_course($row['code']);
+            $xc = function_exists('apc_exists');
+            if ($xc) {
+                $apc = apc_cache_info(null, true);
+                $apx_end = $apc['start_time']+$apx['ttl'];
+                if (apc_exists('my_campus_course_visits_'.$row['code']) AND (time() < $apc_end) AND apc_fetch('my_campus_course_visits_'.$row['code']) > 0) {
+                    $count_connections_last_month = apc_fetch('my_campus_course_visits_'.$row['code']);
+                } else {
+                    $count_connections_last_month = Tracking::get_course_connections_count($row['code'], 0, api_get_utc_datetime(time() - (30 * 86400)));
+                    apc_store('my_campus_course_visits_'.$row['code'], $count_connections_last_month, $apc['ttl']);
+                }
+            } else {
+                $count_connections_last_month = Tracking::get_course_connections_count($row['code'], 0, api_get_utc_datetime(time() - (30 * 86400)));
+            }
+            ...
+        }
+</pre>
 <hr />
 <h2><a name="2.Slow-queries"></a>2. Slow queries</h2>
 Enable slow_queries in /etc/mysqld/my.cnf, restart MySQL then follow using sudo tail -f /var/log/mysql/mysql-slow.log

+ 0 - 88
main/admin/calendar.lib.php

@@ -1108,7 +1108,6 @@ function show_user_filter_form()
 
 /** @todo this select missing to implement */
 
-//$user_list=get_course_users();
 echo "<select name=\"select\" onchange=\"MM_jumpMenu('parent',this,0)\">";
 echo "<option value=\"agenda.php?user=none\">show all users</option>";
 /*foreach($user_list as $this_user)
@@ -1141,7 +1140,6 @@ function show_user_group_filter_form()
 
 	// Users
 	echo "<optgroup label=\"".get_lang("Users")."\">";
-	//$user_list=get_course_users();
 /*	foreach($user_list as $this_user)
 		{
 		// echo "<option value=\"agenda.php?isStudentView=true&amp;user=".$this_user['uid']."\">".$this_user['lastName']." ".$this_user['firstName']."</option>";
@@ -1546,92 +1544,6 @@ function show_add_form($id = '') {
 <?php
 }
 
-function get_agendaitems($month, $year)
-{
-	global $_user;
-	global $_configuration;
-	$month=Database::escape_string($month);
-	$year=Database::escape_string($year);
-
-	$items = array ();
-
-	//databases of the courses
-	$TABLEAGENDA = Database :: get_main_table(TABLE_MAIN_SYSTEM_CALENDAR);
-	//$TABLE_ITEMPROPERTY = Database :: get_course_table(TABLE_ITEM_PROPERTY);
-
-	//$group_memberships = GroupManager :: get_group_ids(Database::get_current_course_database(), $_user['user_id']);
-	// if the user is administrator of that course we show all the agenda items
-	//if (api_is_allowed_to_edit())
-	//{
-		//echo "course admin";
-	$sqlquery = "SELECT
-						DISTINCT *
-						FROM ".$TABLEAGENDA."
-						WHERE
-						MONTH(start_date)='".$month."'
-						AND YEAR(start_date)='".$year."'
-						GROUP BY id
-						ORDER BY start_date ";
-	//}
-	// if the user is not an administrator of that course
-/*	else
-	{
-		//echo "GEEN course admin";
-		if (is_array($group_memberships) && count($group_memberships)>0)
-		{
-			$sqlquery = "SELECT
-							agenda.*
-							FROM ".$TABLEAGENDA."
-							WHERE
-							MONTH(agenda.start_date)='".$month."'
-							AND YEAR(agenda.start_date)='".$year."'
-							ORDER BY start_date ";
-		}
-		else
-		{
-			$sqlquery = "SELECT
-							agenda.*, item_property.*
-							FROM ".$TABLEAGENDA."
-							WHERE
-							MONTH(agenda.start_date)='".$month."'
-							AND YEAR(agenda.start_date)='".$year."'
-							ORDER BY start_date ";
-		}
-	}*/
-
-	//$mycourse = api_get_course_info();
-	$portal_url = $_configuration['root_web'];
-	if ($_configuration['multiple_access_urls']) {
-		$access_url_id = api_get_current_access_url_id();
-		if ($access_url_id != -1 ){
-			$url = api_get_access_url($access_url_id);
-			$portal_url = $url['url'];
-		}
-	}
-
-    $result = Database::query($sqlquery);
-	while ($item = Database::fetch_array($result))
-	{
-		$agendaday_string = api_convert_and_format_date($item['start_date'], "%d", date_default_timezone_get());
-		$agendaday = intval($agendaday_string);
-		$time = api_convert_and_format_date($item['start_date'], TIME_NO_SEC_FORMAT, date_default_timezone_get());
-		$URL = $portal_url.'main/admin/agenda.php?day='.$agendaday."&amp;month=".$month."&amp;year=".$year; // RH  //Patrick Cool: to highlight the relevant agenda item
-		$items[$agendaday][$item['start_time']] .= '<i>'.$time.'</i> <a href="'.$URL.'" title="'.$item['title'].'<br />';
-	}
-
-	// sorting by hour for every day
-	$agendaitems = array ();
-	while (list ($agendaday, $tmpitems) = each($items))
-	{
-		sort($tmpitems);
-		while (list ($key, $val) = each($tmpitems))
-		{
-			$agendaitems[$agendaday] .= $val;
-		}
-	}
-	return $agendaitems;
-}
-
 function display_upcoming_events() {
 	echo '<br /><b>'.get_lang('UpcomingEvent').'</b><br />';
 	$number_of_items_to_show = (int)api_get_setting('number_of_upcoming_events');

+ 2 - 1
main/admin/configure_homepage.php

@@ -796,7 +796,8 @@ switch ($action) {
 		  <td><textarea name="notice_text" cols="30" rows="5" wrap="virtual" style="width: 350px;"><?php echo $notice_text; ?></textarea></td>
 		</tr>
         <tr>
-          <td><input type="checkbox" value="<?php echo get_lang('ApplyAllLanguages'); ?>"/></td>
+          <td><label><?php echo get_lang('ApplyAllLanguages'); ?></label>
+          <td><input type="checkbox" name="all_langs" value="<?php echo get_lang('ApplyAllLanguages'); ?>"/></td>
         </tr>
 		<tr>
 		  <td>&nbsp;</td>

+ 5 - 5
main/admin/configure_plugin.php

@@ -16,7 +16,7 @@ api_protect_admin_script();
 $plugin_name = $_GET['name'];
 
 $plugin_obj = new AppPlugin();
-$plugin_info = $plugin_obj->get_plugin_info($plugin_name, true);
+$plugin_info = $plugin_obj->getPluginInfo($plugin_name, true);
 
 if (empty($plugin_info)) {
     api_not_allowed();
@@ -33,7 +33,7 @@ global $_configuration;
 $content = null;
 
 if (isset($plugin_info['settings_form'])) {
-    $form = $plugin_info['settings_form'];    
+    $form = $plugin_info['settings_form'];
     if (isset($form)) {
         //We override the form attributes
         $attributes = array('action'=>api_get_self().'?name='.$plugin_name, 'method'=>'POST');
@@ -48,7 +48,7 @@ if (isset($plugin_info['settings_form'])) {
 if (isset($form)) {
     if ($form->validate()) {
         $values = $form->exportValues();
-        
+
         //api_delete_category_settings_by_subkey($plugin_name);
         $access_url_id = api_get_current_access_url_id();
         api_delete_settings_params(array('category = ? AND access_url = ? AND subkey = ? AND type = ? and variable <> ?' =>
@@ -56,7 +56,7 @@ if (isset($form)) {
         foreach ($values as $key => $value) {
             $key = Database::escape_string($plugin_name.'_'.$key);
             api_add_setting($value, $key, $plugin_name, 'setting', 'Plugins', $plugin_name, null, null, null, $_configuration['access_url'], 1);
-            
+
         }
         $message = Display::return_message(get_lang('Updated'), 'success');
     }
@@ -65,4 +65,4 @@ $tpl = new Template($tool_name, true, true, false, true, false);
 $tpl->assign('actions', $actions);
 $tpl->assign('message', $message);
 $tpl->assign('content', $content);
-$tpl->display_one_col_template();
+$tpl->display_one_col_template();

+ 5 - 4
main/admin/settings.lib.php

@@ -497,16 +497,16 @@ function store_regions()
 */
 function store_plugins()
 {
-    $plugin_obj = new AppPlugin();
+    $appPlugin = new AppPlugin();
 
     // Get a list of all current 'Plugins' settings
-    $plugin_list = $plugin_obj->read_plugins_from_path();
+    $plugin_list = $appPlugin->read_plugins_from_path();
 
     $installed_plugins = array();
 
     foreach ($plugin_list as $plugin) {
         if (isset($_POST['plugin_'.$plugin])) {
-            $plugin_obj->install($plugin);
+            $appPlugin->install($plugin);
             $installed_plugins[] = $plugin;
         }
     }
@@ -516,8 +516,9 @@ function store_plugins()
     } else {
         $remove_plugins = $plugin_list;
     }
+
     foreach ($remove_plugins as $plugin) {
-        $plugin_obj->uninstall($plugin);
+        $appPlugin->uninstall($plugin);
     }
 }
 

+ 28 - 0
main/admin/update_last_login.php

@@ -0,0 +1,28 @@
+<?php
+/* For licensing terms, see /license.txt */
+
+require_once '../inc/global.inc.php';
+api_protect_admin_script();
+
+if (isset($_configuration['save_user_last_login']) &&
+    $_configuration['save_user_last_login']
+) {
+    $tableUser = Database::get_main_table(TABLE_MAIN_USER);
+    $userInfo = api_get_user_info(api_get_user_id());
+    if (isset($userInfo['last_login'])) {
+        $sql = "SELECT login_user_id, MAX(login_date) login_date from track_e_login group by login_user_id";
+        echo "Executing: <br />$sql<br /> Updating <br />";
+        $result = Database::query($sql);
+        while ($row = Database::fetch_array($result)) {
+            $date = $row['login_date'];
+            $userId = $row['login_user_id'];
+            $sql = "UPDATE $tableUser SET last_login ='$date' WHERE user_id = $userId";
+            echo "<br />Updating: <br />$sql";
+            Database::query($sql);
+        }
+    } else {
+        $sql = "ALTER TABLE $tableUser ADD COLUMN last_login DATETIME";
+        Database::query($sql);
+        echo "last_login does not exits creating with: <br/> $sql";
+    }
+}

+ 0 - 1
main/admin/user_list.php

@@ -237,7 +237,6 @@ function prepare_user_sql_query($is_count) {
         $query_admin_table = '';
         $keyword_admin = '';
 
-        error_log("kw_status: $keyword_status");
         if ($keyword_status == SESSIONADMIN) {
            $keyword_status = '%';
            $query_admin_table = " , $admin_table a ";

+ 11 - 4
main/announcements/announcements.inc.php

@@ -294,8 +294,14 @@ class AnnouncementManager
      * @param string    Comment describing the attachment
      * @return int      false on failure, ID of the announcement on success
      */
-    public static function add_announcement($emailTitle, $newContent, $sent_to, $file = array(), $file_comment = null, $end_date = null)
-    {
+    public static function add_announcement(
+        $emailTitle,
+        $newContent,
+        $sentTo,
+        $file = array(),
+        $file_comment = null,
+        $end_date = null
+    ) {
         $_course = api_get_course_info();
         $tbl_announcement = Database::get_course_table(TABLE_ANNOUNCEMENT);
 
@@ -333,11 +339,12 @@ class AnnouncementManager
             }
 
             // store in item_property (first the groups, then the users
-            if (empty($sent_to) || !empty($sent_to) && isset($sent_to[0]) && $sent_to[0] == 'everyone') {
+
+            if (empty($sentTo) || !empty($sentTo) && isset($sentTo[0]) && $sentTo[0] == 'everyone') {
                 // The message is sent to EVERYONE, so we set the group to 0
                 api_item_property_update($_course, TOOL_ANNOUNCEMENT, $last_id, "AnnouncementAdded", api_get_user_id(), '0');
             } else {
-                $send_to = self::separate_users_groups($sent_to);
+                $send_to = self::separate_users_groups($sentTo);
 
                 // Storing the selected groups
                 if (is_array($send_to['groups'])) {

+ 28 - 0
main/auth/inscription.php

@@ -137,6 +137,34 @@ if ($user_already_registered_show_terms == false) {
         $form->addElement('radio', 'status', null, get_lang('RegAdmin'), COURSEMANAGER);
     }
 
+    $allowCaptcha = isset($_configuration['allow_captcha']) ? $_configuration['allow_captcha'] : false;
+
+    if ($allowCaptcha) {
+
+        $ajax = api_get_path(WEB_AJAX_PATH).'form.ajax.php?a=get_captcha';
+
+        $options = array(
+                'width'        => 220,
+                'height'       => 90,
+                'callback'     => $ajax.'&var='.basename(__FILE__, '.php'),
+                'sessionVar'   => basename(__FILE__, '.php'),
+                'imageOptions' => array(
+                    'font_size' => 20,
+                    'font_path' => api_get_path(LIBRARY_PATH).'pchart/fonts/',
+                    'font_file' => 'tahoma.ttf',
+                        //'output' => 'gif'
+                )
+        );
+
+        $captcha_question =  $form->addElement('CAPTCHA_Image', 'captcha_question', '', $options);
+        $form->addElement('static', null, null, get_lang('ClickOnTheImageForANewOne'));
+
+        $form->addElement('text', 'captcha', get_lang('EnterTheLettersYouSee'), array('size' => 40));
+        $form->addRule('captcha', get_lang('EnterTheCharactersYouReadInTheImage'), 'required', null, 'client');
+
+        $form->addRule('captcha', get_lang('TheTextYouEnteredDoesNotMatchThePicture'), 'CAPTCHA', $captcha_question);
+    }
+
     //	EXTENDED FIELDS
     if (api_get_setting('extended_profile') == 'true' && api_get_setting('extendedprofile_registration', 'mycomptetences') == 'true') {
         $form->add_html_editor('competences', get_lang('MyCompetences'), false, false, array('ToolbarSet' => 'register', 'Width' => '100%', 'Height' => '130'));

Dosya farkı çok büyük olduğundan ihmal edildi
+ 98 - 899
main/calendar/agenda.inc.php


Dosya farkı çok büyük olduğundan ihmal edildi
+ 553 - 170
main/calendar/agenda.lib.php


+ 219 - 231
main/calendar/agenda.php

@@ -16,25 +16,23 @@ $language_file = array('agenda', 'group');
 $use_anonymous = true;
 require_once '../inc/global.inc.php';
 $current_course_tool = TOOL_CALENDAR_EVENT;
-
 $course_info = api_get_course_info();
 
 if (!empty($course_info)) {
     api_protect_course_script(true);
 }
 
-//session
-if (isset($_GET['id_session'])) {
-    $_SESSION['id_session'] = intval($_GET['id_session']);
-}
-
 $action = isset($_GET['action']) ? $_GET['action'] : null;
 $origin = isset($_GET['origin']) ? $_GET['origin'] : null;
 
 $this_section = SECTION_COURSES;
 
 if (empty($action)) {
-    $url = api_get_path(WEB_CODE_PATH).'calendar/agenda_js.php?type=course';
+    if (!empty($course_info)) {
+        $url = api_get_path(WEB_CODE_PATH).'calendar/agenda_js.php?type=course'.'&'.api_get_cidreq();
+    } else {
+        $url = api_get_path(WEB_CODE_PATH).'calendar/agenda_js.php?';
+    }
     header("Location: $url");
     exit;
 }
@@ -43,185 +41,58 @@ if (empty($action)) {
 $_SESSION['source_type'] = 'Agenda';
 require_once '../resourcelinker/resourcelinker.inc.php';
 require_once api_get_path(LIBRARY_PATH).'fileUpload.lib.php';
-
-if (!empty($addresources)) {
-    // When the "Add Resource" button is clicked we store all the form data into a session
-    $form_elements = array(
-        'day' => Security::remove_XSS($_POST['fday']),
-        'month' => Security::remove_XSS($_POST['fmonth']),
-        'year' => Security::remove_XSS($_POST['fyear']),
-        'hour' => Security::remove_XSS($_POST['fhour']),
-        'minutes' => Security::remove_XSS($_POST['fminute']),
-        'end_day' => Security::remove_XSS($_POST['end_fday']),
-        'end_month' => Security::remove_XSS($_POST['end_fmonth']),
-        'end_year' => Security::remove_XSS($_POST['end_fyear']),
-        'end_hours' => Security::remove_XSS($_POST['end_fhour']),
-        'end_minutes' => Security::remove_XSS($_POST['end_fminute']),
-        'title' => Security::remove_XSS(stripslashes($_POST['title'])),
-        'content' => Security::remove_XSS(stripslashes($_POST['content'])),
-        'id' => Security::remove_XSS($_POST['id']),
-        'action' => Security::remove_XSS($_POST['action']),
-        'add_announcement' => Security::remove_XSS($_POST['add_announcement']),
-        'to' => Security::remove_XSS($_POST['selectedform'])
-    );
-    $_SESSION['formelements'] = $form_elements;
-    // this is to correctly handle edits
-    if ($id) {
-        $action = "edit";
-    }
-    //print_r($form_elements);
-    header('Location: '.api_get_path(WEB_CODE_PATH)."resourcelinker/resourcelinker.php?source_id=1&action=$action&id=$id&originalresource=no");
-    exit;
-}
-
-if (!empty($_GET['view'])) {
-    $_SESSION['view'] = Security::remove_XSS($_GET['view']);
-}
-
-// Functions for the agenda tool
-require_once 'agenda.inc.php';
-/*
-  TREATING THE PARAMETERS
-  1. viewing month only or everything
-  2. sort ascending or descending
-  3. showing or hiding the send-to-specific-groups-or-users form
-  4. filter user or group
- */
-
-
-// 3. showing or hiding the send-to-specific-groups-or-users form
-$setting_allow_individual_calendar = true;
-if (empty($_POST['To']) and empty($_SESSION['allow_individual_calendar'])) {
-    $_SESSION['allow_individual_calendar'] = "hide";
-}
-$allow_individual_calendar_status = $_SESSION['allow_individual_calendar'];
-if (!empty($_POST['To']) and ($allow_individual_calendar_status == "hide")) {
-    $_SESSION['allow_individual_calendar'] = "show";
-}
-if (!empty($_GET['sort']) and ($allow_individual_calendar_status == "show")) {
-    $_SESSION['allow_individual_calendar'] = "hide";
-}
-
-// 4. filter user or group
-if (!empty($_GET['user']) or !empty($_GET['group'])) {
-    $_SESSION['user'] = (int) $_GET['user'];
-    $_SESSION['group'] = (int) $_GET['group'];
-}
-if ((!empty($_GET['user']) and $_GET['user'] == "none") or (!empty($_GET['group']) and $_GET['group'] == "none")) {
-    Session::erase("user");
-    Session::erase("group");
-}
-
 $group_id = api_get_group_id();
+$eventId = isset($_REQUEST['id']) ? $_REQUEST['id'] : null;
+$type = $event_type = isset($_GET['type']) ? $_GET['type'] : null;
 
-//It comes from the group tools. If it's define it overwrites $_SESSION['group']
-
-$htmlHeadXtra[] = to_javascript();
-$htmlHeadXtra[] = user_group_filter_javascript();
+$htmlHeadXtra[] = "<script>
 
-// this loads the javascript that is needed for the date popup selection
-$htmlHeadXtra[] = "<script src=\"tbl_change.js\" type=\"text/javascript\" language=\"javascript\"></script>";
+function plus_repeated_event() {
+    if (document.getElementById('options2').style.display == 'none') {
+        document.getElementById('options2').style.display = 'block';
+    } else {
+        document.getElementById('options2').style.display = 'none';
+    }
+}
+    $(function() {
+        var checked = $('input[name=repeat]').attr('checked');
+        if (checked) {
+            $('#options2').show();
+        }
+    });
+</script>
+";
 
 // setting the name of the tool
-$nameTools = get_lang('Agenda'); // language variable in trad4all.inc.php
-// showing the header if we are not in the learning path, if we are in
-// the learning path, we do not include the banner so we have to explicitly
-// include the stylesheet, which is normally done in the header
-if (!empty($group_id)) {
-    $group_properties = GroupManager :: get_group_properties($group_id);
-    $interbreadcrumb[] = array("url" => "../group/group.php", "name" => get_lang('Groups'));
-    $interbreadcrumb[] = array("url" => "../group/group_space.php?gidReq=".$group_id, "name" => get_lang('GroupSpace').' '.$group_properties['name']);
-    Display::display_header($nameTools, 'Agenda');
-} elseif (empty($origin) or $origin != 'learnpath') {
-    Display::display_header($nameTools, 'Agenda');
-} else {
-    echo "<link rel=\"stylesheet\" type=\"text/css\" href=\"".api_get_path(WEB_CODE_PATH)."css/default.css\"/>";
-}
+$nameTools = get_lang('Agenda');
 
-/*
-  TRACKING
- */
 event_access_tool(TOOL_CALENDAR_EVENT);
 
-/*   			SETTING SOME VARIABLES
- */
-// Variable definitions
-// Defining the shorts for the days. We use camelcase because these are arrays of language variables
-$DaysShort = api_get_week_days_short();
-// Defining the days of the week to allow translation of the days. We use camelcase because these are arrays of language variables
-$DaysLong = api_get_week_days_long();
-// Defining the months of the year to allow translation of the months. We use camelcase because these are arrays of language variables
-$MonthsLong = api_get_months_long();
-
-// Database table definitions
-$TABLEAGENDA = Database::get_course_table(TABLE_AGENDA);
-$TABLE_ITEM_PROPERTY = Database::get_course_table(TABLE_ITEM_PROPERTY);
-$tbl_user = Database::get_main_table(TABLE_MAIN_USER);
-$tbl_courseUser = Database::get_main_table(TABLE_MAIN_COURSE_USER);
-$tbl_group = Database::get_course_table(TABLE_GROUP);
-$tbl_groupUser = Database::get_course_table(TABLE_GROUP_USER);
-$tbl_session_course_user = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
-
-/*   			ACCESS RIGHTS */
 // permission stuff - also used by loading from global in agenda.inc.php
 $is_allowed_to_edit = api_is_allowed_to_edit(false, true) OR (api_get_course_setting('allow_user_edit_agenda') && !api_is_anonymous());
-
-// Tool introduction
-Display::display_introduction_section(TOOL_CALENDAR_EVENT);
-
-/* 		MAIN SECTION	 */
-
-//setting the default year and month
-$select_year = '';
-$select_month = '';
-$select_day = '';
-
-if (!empty($_GET['year'])) {
-    $select_year = (int) $_GET['year'];
-}
-if (!empty($_GET['month'])) {
-    $select_month = (int) $_GET['month'];
-}
-if (!empty($_GET['day'])) {
-    $select_day = (int) $_GET['day'];
-}
-
-$today = getdate();
-
-if (empty($select_year)) {
-    $select_year = $today['year'];
-}
-if (empty($select_month)) {
-    $select_month = $today['mon'];
-}
-
-echo '<div class="actions">';
-
-if (api_is_allowed_to_edit(false, true) OR
-    (api_get_course_setting('allow_user_edit_agenda') && !api_is_anonymous()) && api_is_allowed_to_session_edit(false, true) OR
-    GroupManager::user_has_access(api_get_user_id(), $group_id,  GroupManager::GROUP_TOOL_CALENDAR) && GroupManager::is_tutor_of_group(api_get_user_id(), $group_id)
-) {
-    echo display_courseadmin_links();
-}
-
-echo '</div>';
-
-$event_id = isset($_REQUEST['id']) ? $_REQUEST['id'] : null;
-$type = $event_type = isset($_GET['type']) ? $_GET['type'] : null;
+$agenda = new Agenda();
+$agenda->type = $type;
+$actions = $agenda->displayActions('calendar');
 
 if ($type == 'fromjs') {
-    $id_list = explode('_', $event_id);
-    $event_id = $id_list[1];
+    $id_list = explode('_', $eventId);
+    $eventId = $id_list[1];
     $event_type = $id_list[0];
 }
 
 if (!api_is_allowed_to_edit(null, true) && $event_type == 'course') {
-    api_not_allowed();
+    api_not_allowed(true);
+}
+if ($event_type == 'course') {
+    $agendaUrl = api_get_path(WEB_CODE_PATH).'calendar/agenda_js.php?'.api_get_cidreq().'&type=course';
+} else {
+    $agendaUrl = api_get_path(WEB_CODE_PATH).'calendar/agenda_js.php?&type='.$event_type;
 }
-
 $course_info = api_get_course_info();
-$agenda = new Agenda();
+$agenda->type = $event_type;
 
+$message = null;
+$content = null;
 if (api_is_allowed_to_edit(false, true) OR
     (api_get_course_setting('allow_user_edit_agenda') &&
     !api_is_anonymous() &&
@@ -231,107 +102,224 @@ if (api_is_allowed_to_edit(false, true) OR
 ) {
     switch ($action) {
         case 'add':
-            if (isset($_POST['submit_event']) && $_POST['submit_event']) {
-                $event_start = (int) $_POST['fyear'].'-'.(int) $_POST['fmonth'].'-'.(int) $_POST['fday'].' '.(int) $_POST['fhour'].':'.(int) $_POST['fminute'].':00';
-                $event_stop = (int) $_POST['end_fyear'].'-'.(int) $_POST['end_fmonth'].'-'.(int) $_POST['end_fday'].' '.(int) $_POST['end_fhour'].':'.(int) $_POST['end_fminute'].':00';
-                $safe_title = Security::remove_XSS($_POST['title']);
-                $safe_file_comment = isset($_POST['file_comment']) ? Security::remove_XSS($_POST['file_comment']) : null;
-
-                if (isset($_POST['empty_end_date']) && $_POST['empty_end_date'] == 'on') {
-                    $event_stop = '0000-00-00 00:00:00';
+            $form = $agenda->getForm(array('action' => 'add'));
+
+            if ($form->validate()) {
+                $values = $form->getSubmitValues();
+
+                $sendEmail = isset($values['add_announcement']) ? true : false;
+                $allDay = isset($values['all_day']) ? 'true' : 'false';
+
+                $sendAttachment = isset($_FILES['user_upload']) ? true : false;
+                $attachment = $sendAttachment ? $_FILES['user_upload'] : null;
+                $attachmentComment = isset($values['file_comment']) ? $values['file_comment'] : null;
+
+                $startDate = $values['date_range_start'];
+                $endDate = $values['date_range_end'];
+
+                $eventId = $agenda->add_event(
+                    $startDate,
+                    $endDate,
+                    $allDay,
+                    $values['title'],
+                    $values['content'],
+                    $values['users_to_send'],
+                    $sendEmail,
+                    null,
+                    $attachment,
+                    $attachmentComment
+                );
+
+                if (!empty($values['repeat']) && !empty($eventId)) {
+                    // End date is always set as 23:59:59
+                    $endDate = substr($values['repeat_end_day'], 0, 10).' 23:59:59';
+                    $agenda->addRepeatedItem(
+                        $eventId,
+                        $values['repeat_type'],
+                        $endDate,
+                        $values['users_to_send']
+                    );
                 }
-                $agenda->type = 'course';
-                $sendEmail = isset($_POST['add_announcement']) ? true : false;
-                $eventId = $agenda->add_event($event_start, $event_stop, false, null, $safe_title, $_POST['content'], $_POST['selected_form'], $sendEmail);
-
-                if (!empty($_POST['repeat']) && !empty($eventId)) {
-                    $end_y = intval($_POST['repeat_end_year']);
-                    $end_m = intval($_POST['repeat_end_month']);
-                    $end_d = intval($_POST['repeat_end_day']);
-                    $end = mktime(23, 59, 59, $end_m, $end_d, $end_y);
-                    $agenda->addRepeatedItem($eventId, $_POST['repeat_type'], $end, $_POST['selected_form']);
-                }
-                Display::display_confirmation_message(get_lang('AddSuccess'));
+                $message = Display::return_message(get_lang('AddSuccess'), 'confirmation');
                 if ($sendEmail) {
-                    Display::display_confirmation_message(get_lang('AdditionalMailWasSentToSelectedUsers'));
+                    $message .= Display::return_message(get_lang('AdditionalMailWasSentToSelectedUsers'), 'confirmation');
+                }
+                Session::write('message', $message);
+                header("Location: $agendaUrl");
+                exit;
+            } else {
+                $content = $form->return_form();
+            }
+            break;
+        case 'edit':
+            $event = $agenda->get_event($eventId);
+            if (empty($event)) {
+                api_not_allowed(true);
+            }
+
+            $event['action'] = 'edit';
+            $event['id'] = $eventId;
+
+            $form = $agenda->getForm($event);
+
+            if ($form->validate()) {
+                $values = $form->getSubmitValues();
+
+                $allDay = isset($values['all_day']) ? 'true' : 'false';
+                $startDate = $values['date_range_start'];
+                $endDate = $values['date_range_end'];
+                //$repeatType = isset($values['edit_repeat_type']) ? $values['edit_repeat_type'] : null;
+                $sendAttachment = isset($_FILES['user_upload']) ? true : false;
+                $attachment = $sendAttachment ? $_FILES['user_upload'] : null;
+                $attachmentComment = isset($values['file_comment']) ? $values['file_comment'] : null;
+
+                // This is a sub event. Delete the current and create another BT#7803
+
+                if (!empty($event['parent_event_id'])) {
+                    $agenda->delete_event($eventId);
+
+                    $eventId = $agenda->add_event(
+                        $startDate,
+                        $endDate,
+                        $allDay,
+                        $values['title'],
+                        $values['content'],
+                        $values['users_to_send'],
+                        false,
+                        null,
+                        $attachment,
+                        $attachmentComment
+                    );
+
+                    $message = Display::return_message(get_lang('Updated'), 'confirmation');
+                    Session::write('message', $message);
+                    header("Location: $agendaUrl");
+                    exit;
+                }
+
+                // Editing normal event.
+
+                $agenda->edit_event(
+                    $eventId,
+                    $startDate,
+                    $endDate,
+                    $allDay,
+                    $values['title'],
+                    $values['content'],
+                    $values['users_to_send'],
+                    $attachment,
+                    $attachmentComment
+                );
+
+                if (!empty($values['repeat']) && !empty($eventId)) {
+                    // End date is always set as 23:59:59
+                    $endDate = substr($values['repeat_end_day'], 0, 10).' 23:59:59';
+                    $agenda->addRepeatedItem(
+                        $eventId,
+                        $values['repeat_type'],
+                        $endDate,
+                        $values['users_to_send']
+                    );
+                }
+
+                $deleteAttachment = isset($values['delete_attachment']) ? true : false;
+
+                if ($deleteAttachment && isset($event['attachment']) && !empty($event['attachment'])) {
+                    $agenda->deleteAttachmentFile(
+                        $event['attachment']['id'],
+                        $agenda->course
+                    );
                 }
+
+                $message = Display::return_message(get_lang('Updated'), 'confirmation');
+                Session::write('message', $message);
+                header("Location: $agendaUrl");
+                exit;
             } else {
-                show_add_form();
+                $content = $form->return_form();
+
             }
             break;
         case "announce":
             //copying the agenda item into an announcement
-            if (!(api_is_course_coach() && !api_is_element_in_the_session(TOOL_AGENDA, $event_id))) {
+            /*if (!(api_is_course_coach() && !api_is_element_in_the_session(TOOL_AGENDA, $eventId))) {
                 // a coach can only delete an element belonging to his session
-                $ann_id = store_agenda_item_as_announcement($event_id);
+                $ann_id = store_agenda_item_as_announcement($eventId);
                 $tool_group_link = (isset($_SESSION['toolgroup']) ? '&toolgroup='.$_SESSION['toolgroup'] : '');
-                Display::display_normal_message(get_lang('CopiedAsAnnouncement').'&nbsp;<a href="../announcements/announcements.php?id='.$ann_id.$tool_group_link.'">'.get_lang('NewAnnouncement').'</a>', false);
-            }
+                $message = Display::return_message(
+                    get_lang('CopiedAsAnnouncement').'&nbsp;<a href='.api_get_path(WEB_CODE_PATH).'announcements/announcements.php?id='.$ann_id.$tool_group_link.'">'.
+                    get_lang('NewAnnouncement').'</a>',
+                    'normal',
+                    false
+                );
+                Session::write('message', $message);
+            }*/
             break;
         case 'importical':
-            if (isset($_POST['ical_submit'])) {
+            $form = $agenda->getImportCalendarForm();
+            $content = $form->return_form();
+
+            if ($form->validate()) {
                 $ical_name = $_FILES['ical_import']['name'];
                 $ical_type = $_FILES['ical_import']['type'];
-
                 $ext = substr($ical_name, (strrpos($ical_name, ".") + 1));
 
-                //$ical_type === 'text/calendar'
                 if ($ext === 'ics' || $ext === 'ical' || $ext === 'icalendar' || $ext === 'ifb') {
-                    $agenda_result = agenda_import_ical($course_info, $_FILES['ical_import']);
+                    $result = $agenda->importEventFile($course_info, $_FILES['ical_import']);
                     $is_ical = true;
                 } else {
                     $is_ical = false;
                 }
 
                 if (!$is_ical) {
-                    Display::display_error_message(get_lang('IsNotiCalFormatFile'));
-                    display_ical_import_form();
+                    $message = Display::return_message(get_lang('IsNotiCalFormatFile'), 'error');
+                    $form = $agenda->getImportCalendarForm();
+                    $content = $form->return_form();
                     break;
                 } else {
-                    Display::display_confirmation_message(get_lang('AddSuccess'));
-                    echo $agenda_result;
+                    $message = Display::return_message(get_lang('AddSuccess'), 'error');
+                    $content = $result;
                 }
-            } else {
-                display_ical_import_form();
-            }
-            break;
-        case 'edit':
-            // a coach can only delete an element belonging to his session
-            if ($_POST['submit_event']) {
-                store_edited_agenda_item($event_id, $_REQUEST['id_attach'], $_REQUEST['file_comment']);
-                $action = 'view';
-            } else {
-                show_add_form($event_id, $event_type);
+                Session::write('message', $message);
             }
             break;
         case "delete":
-            if (!(api_is_course_coach() && !api_is_element_in_the_session(TOOL_AGENDA, $event_id) )) {
+            if (!(api_is_course_coach() && !api_is_element_in_the_session(TOOL_AGENDA, $eventId) )) {
                 // a coach can only delete an element belonging to his session
-                delete_agenda_item($event_id);
-                $action = 'view';
+                $content = $agenda->delete_event($eventId);
             }
             break;
         case "showhide":
-            if (!(api_is_course_coach() && !api_is_element_in_the_session(TOOL_AGENDA, $event_id))) {
+            /*if (!(api_is_course_coach() && !api_is_element_in_the_session(TOOL_AGENDA, $eventId))) {
                 // a coach can only delete an element belonging to his session
-                showhide_agenda_item($event_id);
-                $action = 'view';
-            }
-            if (!empty($_GET['agenda_id'])) {
-                display_one_agenda_item($_GET['agenda_id']);
-            }
-            break;
-        case "delete_attach":  //delete attachment file
-            $id_attach = $_GET['id_attach'];
-            if (!empty($id_attach)) {
-                delete_attachment_file($id_attach);
+                $content = showhide_agenda_item($eventId);
                 $action = 'view';
-            }
+            }*/
             break;
     }
 }
 
-// The footer is displayed only if we are not in the learnpath
-if ($origin != 'learnpath') {
-    Display::display_footer();
+if (!empty($group_id)) {
+    $group_properties = GroupManager :: get_group_properties($group_id);
+    $interbreadcrumb[] = array(
+        "url" => api_get_path(WEB_CODE_PATH)."group/group.php",
+        "name" => get_lang('Groups')
+    );
+    $interbreadcrumb[] = array(
+        "url" => api_get_path(WEB_CODE_PATH)."group/group_space.php?gidReq=".$group_id,
+        "name" => get_lang('GroupSpace').' '.$group_properties['name']
+    );
 }
+
+// Tool introduction
+$introduction = Display::return_introduction_section(TOOL_CALENDAR_EVENT);
+
+$message = Session::read('message');
+Session::erase('message');
+
+$tpl = new Template(get_lang('Agenda'));
+$tpl->assign('content', $content);
+$tpl->assign('actions', $actions);
+
+// Loading main Chamilo 1 col template
+$tpl->display_one_col_template();

+ 61 - 53
main/calendar/agenda_js.php

@@ -6,6 +6,8 @@
 /**
  * INIT SECTION
  */
+use \ChamiloSession as Session;
+
 // name of the language file that needs to be included
 $language_file = array('agenda', 'group', 'announcements');
 
@@ -13,7 +15,8 @@ $language_file = array('agenda', 'group', 'announcements');
 $use_anonymous = true;
 
 // Calendar type
-$type = isset($_REQUEST['type']) && in_array($_REQUEST['type'], array('personal', 'course', 'admin')) ? $_REQUEST['type'] : 'personal';
+$type = isset($_REQUEST['type']) && in_array($_REQUEST['type'], array('personal', 'course', 'admin', 'platform')) ? $_REQUEST['type'] : 'personal';
+$userId = isset($_REQUEST['user_id']) ? $_REQUEST['user_id'] : null;
 
 if ($type == 'personal') {
     $cidReset = true; // fixes #5162
@@ -24,7 +27,6 @@ require_once 'agenda.lib.php';
 require_once 'agenda.inc.php';
 
 $current_course_tool = TOOL_CALENDAR_EVENT;
-
 $this_section = SECTION_MYAGENDA;
 
 $htmlHeadXtra[] = api_get_jquery_libraries_js(array('jquery-ui', 'jquery-ui-i18n'));
@@ -34,7 +36,7 @@ $htmlHeadXtra[] = api_get_js('fullcalendar/gcal.js');
 $htmlHeadXtra[] = api_get_css(api_get_path(WEB_LIBRARY_PATH).'javascript/fullcalendar/fullcalendar.css');
 $htmlHeadXtra[] = api_get_css(api_get_path(WEB_LIBRARY_PATH).'javascript/qtip2/jquery.qtip.min.css');
 
-if (api_is_platform_admin() && $type == 'admin') {
+if (api_is_platform_admin() && ($type == 'admin' || $type == 'platform')) {
     $type = 'admin';
 }
 
@@ -42,19 +44,27 @@ if (isset($_REQUEST['cidReq']) && !empty($_REQUEST['cidReq'])) {
     $type = 'course';
 }
 
+$agenda = new Agenda();
+$agenda->type = $type;
+
 $is_group_tutor = false;
 $session_id = api_get_session_id();
 $group_id = api_get_group_id();
 
 if (!empty($group_id)) {
     $is_group_tutor = GroupManager::is_tutor_of_group(api_get_user_id(), $group_id);
-    $group_properties = GroupManager :: get_group_properties($group_id);
-    $interbreadcrumb[] = array("url" => "../group/group.php", "name" => get_lang('Groups'));
-    $interbreadcrumb[] = array("url" => "../group/group_space.php?gidReq=".$group_id, "name" => get_lang('GroupSpace').' '.$group_properties['name']);
+    $group_properties = GroupManager::get_group_properties($group_id);
+    $interbreadcrumb[] = array(
+        "url" => api_get_path(WEB_CODE_PATH)."group/group.php?".api_get_cidreq(),
+        "name" => get_lang('Groups')
+    );
+    $interbreadcrumb[] = array(
+        "url" => api_get_path(WEB_CODE_PATH)."group/group_space.php?".api_get_cidreq(),
+        "name" => get_lang('GroupSpace').' '.$group_properties['name']
+    );
 }
 
 $tpl = new Template(get_lang('Agenda'));
-
 $tpl->assign('use_google_calendar', 0);
 
 $can_add_events = 0;
@@ -68,7 +78,7 @@ switch ($type) {
         }
         break;
     case 'course':
-        api_protect_course_script();
+        api_protect_course_script(true);
         $this_section = SECTION_COURSES;
         if (api_is_allowed_to_edit()) {
             $can_add_events = 1;
@@ -126,31 +136,16 @@ if ($region_value == 'en') {
 }
 $tpl->assign('region_value', $region_value);
 
-$export_icon = '../img/export.png';
-$export_icon_low = '../img/export_low_fade.png';
-$export_icon_high = '../img/export_high_fade.png';
+$export_icon = api_get_path(WEB_IMG_PATH).'img/export.png';
+$export_icon_low = api_get_path(WEB_IMG_PATH).'img/export_low_fade.png';
+$export_icon_high = api_get_path(WEB_IMG_PATH).'img/export_high_fade.png';
 
-$tpl->assign('export_ical_confidential_icon', Display::return_icon($export_icon_high, get_lang('ExportiCalConfidential')));
-
-$actions = null;
-$filter = null;
+$tpl->assign(
+    'export_ical_confidential_icon',
+    Display::return_icon($export_icon_high, get_lang('ExportiCalConfidential'))
+);
 
-if (api_is_allowed_to_edit(false, true) OR
-    (api_get_course_setting('allow_user_edit_agenda') && !api_is_anonymous()) &&
-    api_is_allowed_to_session_edit(false, true) OR
-    $is_group_tutor
-) {
-    if ($type == 'course') {
-        if (isset($_GET['user_id'])) {
-            $filter = $_GET['user_id'];
-        }
-        $actions = display_courseadmin_links($filter);
-    }
-} else {
-    if ($type == 'course') {
-        $actions = "<a href='agenda_list.php?type=course&".api_get_cidreq()."'>".Display::return_icon('week.png', get_lang('Agenda'), '', ICON_SIZE_MEDIUM)."</a>";
-    }
-}
+$actions = $agenda->displayActions('calendar', $userId);
 
 $tpl->assign('actions', $actions);
 
@@ -170,7 +165,7 @@ if (empty($defaultView)) {
     $defaultView = 'month';
 }
 
-/* month, basicWeek,agendaWeek,agendaDay */
+/* month, basicWeek, agendaWeek, agendaDay */
 
 $tpl->assign('default_view', $defaultView);
 
@@ -182,42 +177,55 @@ if ($type == 'course' && !empty($session_id)) {
 $tpl->assign('type_label', $type_label);
 $tpl->assign('type_event_class', $type_event_class);
 
-//Current user can add event?
+// Current user can add event?
 $tpl->assign('can_add_events', $can_add_events);
 
-//Setting AJAX caller
-if (isset($_GET['user_id'])) {
-    $user_id = $_GET['user_id'];
-    $agenda_ajax_url = api_get_path(WEB_AJAX_PATH).'agenda.ajax.php?user_id='.$user_id.'&type='.$type;
+// Setting AJAX caller
+if (!empty($userId)) {
+    $agenda_ajax_url = api_get_path(WEB_AJAX_PATH).'agenda.ajax.php?user_id='.$userId.'&type='.$type;
 } else {
     $agenda_ajax_url = api_get_path(WEB_AJAX_PATH).'agenda.ajax.php?type='.$type;
 }
 $tpl->assign('web_agenda_ajax_url', $agenda_ajax_url);
 $course_code = api_get_course_id();
 
-if ((api_is_allowed_to_edit() || $is_group_tutor) && $course_code != '-1' && $type == 'course') {
-    $order = 'lastname';
-    if (api_is_western_name_order()) {
-        $order = 'firstname';
+//if ((api_is_allowed_to_edit() || $is_group_tutor) && $course_code != '-1' && $type == 'course') {
+
+    $form = new FormValidator('form', 'get', null, null, array('id' => 'add_event_form'));
+    $form->addElement('html', '<div id="visible_to_input">');
+    $sendTo = $agenda->parseAgendaFilter($userId);
+    $showAll = false;
+    if ($sendTo == 'everyone') {
+        $showAll = true;
     }
 
-    if (!empty($group_id)) {
-        $group_list = array($group_id => $group_properties);
-        $user_list = GroupManager::get_subscribed_users($group_id);
-    } else {
-        $user_list = CourseManager::get_user_list_from_course_code(api_get_course_id(), api_get_session_id(), null, $order);
-        $group_list = CourseManager::get_group_list_of_course(api_get_course_id(), api_get_session_id());
+    $agenda->showToForm($form, $sendTo, array(), $showAll);
+    $form->addElement('html', '</div>');
+
+    $form->addElement('html', '<div id="visible_to_read_only" style="display: none">');
+    $form->addElement('label', get_lang('To'), '<div id="visible_to_read_only_users"></div>');
+    $form->addElement('html', '</div>');
+
+    $form->addElement('label', get_lang('Agenda'), '<div id ="color_calendar"></div>');
+    $form->addElement('label', get_lang('Date'), '<span id="start_date"></span><span id="end_date"></span>');
+    $form->addElement('text', 'title', get_lang('Title'), array('id' => 'title'));
+    $form->addElement('textarea', 'content', get_lang('Description'), array('id' => 'content'));
+    if ($agenda->type == 'course') {
+        $form->addElement('html', '<div id="add_as_announcement_div" style="display: none">');
+        $form->addElement('checkbox', 'add_as_annonuncement', null, get_lang('AddAsAnnouncement'));
+        $form->addElement('html', '</div>');
     }
 
-    $agenda = new Agenda();
-    //This will fill the select called #users_to_send_id
-    $select = $agenda->construct_not_selected_select_form($group_list, $user_list, array());
-    $tpl->assign('visible_to', $select);
-}
+    $tpl->assign('form_add', $form->return_form());
+//}
 
-// Loading Agenda template
+// Loading Agenda template.
 $content = $tpl->fetch('default/agenda/month.tpl');
 
+$message = Session::read('message');
+$tpl->assign('message', $message);
+Session::erase('message');
+
 $tpl->assign('content', $content);
 
 // Loading main Chamilo 1 col template

+ 16 - 6
main/calendar/agenda_list.php

@@ -13,19 +13,29 @@ require_once '../inc/global.inc.php';
 require_once 'agenda.lib.php';
 require_once 'agenda.inc.php';
 
-$interbreadcrumb[] = array("url" => api_get_path(WEB_CODE_PATH)."calendar/agenda_js.php?".api_get_cidreq(), "name" => get_lang('Agenda'));
+$interbreadcrumb[] = array(
+    'url' => api_get_path(WEB_CODE_PATH)."calendar/agenda_js.php?".api_get_cidreq(),
+    'name' => get_lang('Agenda')
+);
 
 $tpl = new Template(get_lang('Events'));
 
 $agenda = new Agenda();
-$agenda->type = 'course'; //course,admin or personal
-
-$events = $agenda->get_events(null, null, api_get_course_int_id(), api_get_group_id(), null, 'array');
+$type = isset($_REQUEST['type']) ? $_REQUEST['type'] : null;
+$agenda->type = $type;
+$events = $agenda->get_events(
+    null,
+    null,
+    api_get_course_int_id(),
+    api_get_group_id(),
+    null,
+    'array'
+);
 $url = api_get_path(WEB_CODE_PATH).'calendar/agenda_list.php?'.api_get_cidreq();
 $tpl->assign('url', $url);
 $tpl->assign('agenda_events', $events);
-$actions = '<a href="'.api_get_path(WEB_CODE_PATH).'calendar/agenda_js.php?type=course&'.api_get_cidreq().'">'.
-            Display::return_icon('calendar.png', get_lang('Agenda'), '', ICON_SIZE_MEDIUM)."</a>";
+
+$actions = $agenda->displayActions('list');
 $tpl->assign('actions', $actions);
 $tpl->assign('is_allowed_to_edit', api_is_allowed_to_edit());
 

+ 13 - 9
main/course_info/delete_course.php

@@ -10,6 +10,7 @@
 /**
  * Code
  */
+use \ChamiloSession as Session;
 
 // Language files that need to be included
 $language_file = array('admin', 'course_info');
@@ -18,39 +19,42 @@ require_once '../inc/global.inc.php';
 require_once '../gradebook/lib/be/gradebookitem.class.php';
 require_once '../gradebook/lib/be/category.class.php';
 $this_section = SECTION_COURSES;
-$current_course_tool  = TOOL_COURSE_MAINTENANCE;
+$current_course_tool = TOOL_COURSE_MAINTENANCE;
 api_protect_course_script(true);
 
+$_course = api_get_course_info();
+
 $current_course_code = $_course['official_code'];
 $current_course_name = $_course['name'];
 
 if (!api_is_allowed_to_edit()) {
 	api_not_allowed(true);
 }
+
 $tool_name = get_lang('DelCourse');
 
 if (isset($_GET['delete']) && $_GET['delete'] == 'yes') {
-	CourseManager :: delete_course($_course['sysCode']);
+	CourseManager::delete_course($_course['sysCode']);
 	$obj_cat = new Category();
 	$obj_cat->update_category_delete($_course['sysCode']);
 
 	// DELETE CONFIRMATION MESSAGE
-	unset($_course);
-	unset($_cid);
+    Session::erase('_cid');
+    Session::erase('_real_cid');
 	$noPHP_SELF = true;
 	$message = '<h2>'.get_lang('Course').' : '.$current_course_name.' ('.$current_course_code.') </h2>';
     $message .=get_lang('HasDel');
 	$message .= '<br /><br /><a href="../../index.php">'.get_lang('BackHome').' '.api_get_setting('siteName').'</a>';
 
-} else {	
+} else {
     $message = '<h3>'.get_lang('Course').' : '.$current_course_name.' ('.$current_course_code.') </h3>';
-    $message .= '<p>'.get_lang('ByDel').'</p><p><a class="btn btn-primary" href="maintenance.php">'.get_lang('No').'</a>&nbsp;<a class="btn" href="'.api_get_self().'?delete=yes">'.get_lang('Yes').'</a></p>';
+    $message .= '<p>'.get_lang('ByDel').'</p>';
+    $message .= '<p><a class="btn btn-primary" href="'.api_get_path(WEB_CODE_PATH).'course_info/maintenance.php?'.api_get_cidreq().'">'.
+        get_lang('No').'</a>&nbsp;<a class="btn" href="'.api_get_self().'?delete=yes&'.api_get_cidreq().'">'.
+        get_lang('Yes').'</a></p>';
 	$interbreadcrumb[] = array('url' => 'maintenance.php', 'name' => get_lang('Maintenance'));
 }
 Display :: display_header($tool_name, 'Settings');
 echo Display::page_header($tool_name);
 Display::display_warning_message($message, false);
-
-/*	FOOTER */
-
 Display :: display_footer();

+ 52 - 34
main/course_info/infocours.php

@@ -128,7 +128,6 @@ if (file_exists($course_path.'/course-pic85x85.png')) {
 }
 $form->addElement('html', $image_html);
 
-
 $form->add_textfield('title', get_lang('Title'), true, array('class' => 'span6'));
 $form->applyFilter('title', 'html_filter');
 $form->applyFilter('title', 'trim');
@@ -344,7 +343,6 @@ $form->addGroup($group, '', array(get_lang("ShowSystemFolders")), '');
 $form->addElement('style_submit_button', null, get_lang('SaveSettings'), 'class="save"');
 $form->addElement('html', '</div></div>');
 
-
 // Certificate settings
 if (api_get_setting('allow_public_certificates')=='true') {
     $form->addElement('html', '<div><h3>'.Display::return_icon('certificate.png', Security::remove_XSS(get_lang('Certificates')),'',ICON_SIZE_SMALL).' '.Security::remove_XSS(get_lang('Certificates')).'</h3><div>');
@@ -359,11 +357,11 @@ if (api_get_setting('allow_public_certificates')=='true') {
 
 // Plugin course settings
 
-$app_plugin = new AppPlugin();
-$app_plugin->add_course_settings_form($form);
+$appPlugin = new AppPlugin();
+$appPlugin->add_course_settings_form($form);
 
 // Get all the course information
-$all_course_information =  CourseManager::get_course_information($_course['sysCode']);
+$all_course_information = CourseManager::get_course_information($_course['sysCode']);
 
 // Set the default values of the form
 $values = array();
@@ -382,58 +380,78 @@ $values['course_registration_password'] = $all_course_information['registration_
 $values['legal']                        = $all_course_information['legal'];
 $values['activate_legal']               = $all_course_information['activate_legal'];
 
-$courseSettings = CourseManager::getCourseSettingVariables();
+$courseSettings = CourseManager::getCourseSettingVariables($appPlugin);
 foreach ($courseSettings as $setting) {
-    $values[$setting] = api_get_course_setting($setting);
+    $result = api_get_course_setting($setting);
+    if ($result != '-1') {
+        $values[$setting] = $result;
+    }
 }
 
-$app_plugin->set_course_settings_defaults($values);
-
 $form->setDefaults($values);
 
 // Validate form
 if ($form->validate() && is_settings_editable()) {
-    $update_values = $form->exportValues();
+    $updateValues = $form->exportValues();
 
-    $pdf_export_watermark_path = $_FILES['pdf_export_watermark_path'];
+    $pdf_export_watermark_path = isset($_FILES['pdf_export_watermark_path']) ? $_FILES['pdf_export_watermark_path'] : null;
 
     if (!empty($pdf_export_watermark_path['name'])) {
-        $pdf_export_watermark_path_result = PDF::upload_watermark($pdf_export_watermark_path['name'], $pdf_export_watermark_path['tmp_name'], $course_code);
-        unset($update_values['pdf_export_watermark_path']);
+        $pdf_export_watermark_path_result = PDF::upload_watermark(
+            $pdf_export_watermark_path['name'],
+            $pdf_export_watermark_path['tmp_name'],
+            $course_code
+        );
+        unset($updateValues['pdf_export_watermark_path']);
     }
 
     //Variables that will be saved in the TABLE_MAIN_COURSE table
-    $update_in_course_table = array('title', 'course_language','category_code','department_name', 'department_url','visibility',
-    								'subscribe', 'unsubscribe','tutor_name','course_registration_password', 'legal', 'activate_legal');
-
-    foreach ($update_values as $index =>$value) {
-        $update_values[$index] = Database::escape_string($value);
+    $update_in_course_table = array(
+        'title',
+        'course_language',
+        'category_code',
+        'department_name',
+        'department_url',
+        'visibility',
+        'subscribe',
+        'unsubscribe',
+        'tutor_name',
+        'course_registration_password',
+        'legal',
+        'activate_legal'
+    );
+    foreach ($updateValues as $index =>$value) {
+        $updateValues[$index] = Database::escape_string($value);
     }
-    unset($value);
+
     $table_course = Database :: get_main_table(TABLE_MAIN_COURSE);
     $sql = "UPDATE $table_course SET
-        title 				    = '".$update_values['title']."',
-        course_language 	    = '".$update_values['course_language']."',
-        category_code 		    = '".$update_values['category_code']."',
-        department_name  	    = '".$update_values['department_name']."',
-        department_url  	    = '".$update_values['department_url']."',
-        visibility  		    = '".$update_values['visibility']."',
-        subscribe  			    = '".$update_values['subscribe']."',
-        unsubscribe  		    = '".$update_values['unsubscribe']."',
-        legal                   = '".$update_values['legal']."',
-        activate_legal          = '".$update_values['activate_legal']."',
-        registration_code 	    = '".$update_values['course_registration_password']."'
+        title 				    = '".$updateValues['title']."',
+        course_language 	    = '".$updateValues['course_language']."',
+        category_code 		    = '".$updateValues['category_code']."',
+        department_name  	    = '".$updateValues['department_name']."',
+        department_url  	    = '".$updateValues['department_url']."',
+        visibility  		    = '".$updateValues['visibility']."',
+        subscribe  			    = '".$updateValues['subscribe']."',
+        unsubscribe  		    = '".$updateValues['unsubscribe']."',
+        legal                   = '".$updateValues['legal']."',
+        activate_legal          = '".$updateValues['activate_legal']."',
+        registration_code 	    = '".$updateValues['course_registration_password']."'
         WHERE code = '".$course_code."'";
     Database::query($sql);
 
     // Insert/Updates course_settings table
     foreach ($courseSettings as $setting) {
-        if (isset($update_values[$setting])) {
-            CourseManager::saveCourseConfigurationSetting($setting, $update_values[$setting], api_get_course_int_id());
-        }
+        $value = isset($updateValues[$setting]) ? $updateValues[$setting] : null;
+        CourseManager::saveCourseConfigurationSetting(
+            $appPlugin,
+            $setting,
+            $value,
+            api_get_course_int_id()
+        );
     }
 
-    $app_plugin->save_course_settings($update_values);
+    $appPlugin->saveCourseSettingsHook($update_values);
     $cidReset = true;
     $cidReq = $course_code;
     require '../inc/local.inc.php';

+ 129 - 65
main/coursecopy/classes/CourseRecycler.class.php

@@ -21,11 +21,13 @@ class CourseRecycler
      * @param course $course The course-object which contains the items to
      * delete
      */
-    function CourseRecycler($course) {
+    function CourseRecycler($course)
+    {
         $this->course = $course;
         $this->course_info = api_get_course_info($this->course->code);
         $this->course_id = $this->course_info['real_id'];
     }
+
     /**
      * Delete all items from the course.
      * This deletes all items in the course-object from the current Chamilo-
@@ -33,8 +35,11 @@ class CourseRecycler
      * @param string The type of recycling we want (full_backup or select_items)
      * @assert (null) === false
      */
-    function recycle($type) {
-        if (empty($type)) { return false; }
+    function recycle($type)
+    {
+        if (empty($type)) {
+            return false;
+        }
         $this->type = $type;
 
         $table_tool_intro 		= Database::get_course_table(TABLE_TOOL_INTRO);
@@ -61,23 +66,30 @@ class CourseRecycler
 
         foreach ($this->course->resources as $type => $resources) {
             foreach ($resources as $id => $resource) {
-                $sql = "DELETE FROM ".$table_linked_resources." WHERE c_id = ".$this->course_id." AND  (source_type = '".$type."' AND source_id = '".$id."') OR (resource_type = '".$type."' AND resource_id = '".$id."')  ";
+                $sql = "DELETE FROM ".$table_linked_resources."
+                        WHERE
+                            c_id = ".$this->course_id." AND
+                            (source_type = '".$type."' AND source_id = '".$id."') OR
+                            (resource_type = '".$type."' AND resource_id = '".$id."') ";
                 Database::query($sql);
                 if (is_numeric($id)) {
-                    $sql = "DELETE FROM ".$table_item_properties." WHERE c_id = ".$this->course_id." AND tool ='".$resource->get_tool()."' AND ref=".$id;
+                    $sql = "DELETE FROM ".$table_item_properties."
+                            WHERE c_id = ".$this->course_id." AND tool ='".$resource->get_tool()."' AND ref=".$id;
                     Database::query($sql);
                 } elseif ($type == RESOURCE_TOOL_INTRO) {
-                    $sql = "DELETE FROM $table_tool_intro WHERE c_id = ".$this->course_id." AND  id='$id'";
+                    $sql = "DELETE FROM $table_tool_intro
+                            WHERE c_id = ".$this->course_id." AND id='$id'";
                     Database::query($sql);
                 }
             }
         }
-
     }
+
     /**
      * Delete documents
      */
-    function recycle_documents() {
+    function recycle_documents()
+    {
         if ($this->course->has_resources(RESOURCE_DOCUMENT)) {
             $table = Database :: get_course_table(TABLE_DOCUMENT);
             foreach ($this->course->resources[RESOURCE_DOCUMENT] as $id => $document) {
@@ -92,13 +104,11 @@ class CourseRecycler
     /**
      * Delete wiki
      */
-    function recycle_wiki() {
+    function recycle_wiki()
+    {
         if ($this->course->has_resources(RESOURCE_WIKI)) {
             $table_wiki 		= Database::get_course_table(TABLE_WIKI);
             $table_wiki_conf 	= Database::get_course_table(TABLE_WIKI_CONF);
-            //$table_wiki_discuss = Database::get_course_table(TABLE_WIKI_DISCUSS);
-            //$table_wiki_mailcue = Database::get_course_table(TABLE_WIKI_MAILCUE);
-
             $pages = array();
             foreach ($this->course->resources[RESOURCE_WIKI] as $resource) {
                 $pages[] = $resource->page_id;
@@ -116,7 +126,8 @@ class CourseRecycler
     /**
      * Delete glossary
      */
-    function recycle_glossary() {
+    function recycle_glossary()
+    {
         if ($this->course->has_resources(RESOURCE_GLOSSARY)) {
             $table_glossary	= Database::get_course_table(TABLE_GLOSSARY);
             $ids = implode(',', (array_keys($this->course->resources[RESOURCE_GLOSSARY])));
@@ -128,7 +139,8 @@ class CourseRecycler
     /**
      * Delete links
      */
-    function recycle_links() {
+    function recycle_links()
+    {
         if ($this->course->has_resources(RESOURCE_LINK)) {
             $table = Database :: get_course_table(TABLE_LINK);
             $ids = implode(',', (array_keys($this->course->resources[RESOURCE_LINK])));
@@ -140,7 +152,8 @@ class CourseRecycler
     /**
      * Delete forums
      */
-    function recycle_forums() {
+    function recycle_forums()
+    {
 
         $table_category = Database :: get_course_table(TABLE_FORUM_CATEGORY);
         $table_forum = Database :: get_course_table(TABLE_FORUM);
@@ -171,10 +184,8 @@ class CourseRecycler
             Database::query($sql);
             $sql = "DELETE FROM ".$table_thread_qualify_log." WHERE c_id = ".$this->course_id;
             Database::query($sql);
-
             $sql = "DELETE FROM ".$table_thread_qualify_log." WHERE c_id = ".$this->course_id;
             Database::query($sql);
-
         }
 
         if ($this->course->has_resources(RESOURCE_FORUMCATEGORY)) {
@@ -195,40 +206,56 @@ class CourseRecycler
                 " AND ".$table_post.".forum_id IN(".$forum_ids.");";
             Database::query($sql);
 
-            $sql = "DELETE FROM ".$table_mail_queue." USING ".$table_mail_queue." INNER JOIN ".$table_post.
-                " WHERE  ".$table_post.".c_id = ".$this->course_id." AND ".$table_mail_queue.".c_id = ".$this->course_id." AND  ".$table_mail_queue.".post_id = ".$table_post.".post_id".
-                " AND ".$table_post.".forum_id IN(".$forum_ids.");";
+            $sql = "DELETE FROM ".$table_mail_queue." USING ".$table_mail_queue." INNER JOIN $table_post
+                    WHERE
+                        ".$table_post.".c_id = ".$this->course_id." AND
+                        ".$table_mail_queue.".c_id = ".$this->course_id." AND
+                        ".$table_mail_queue.".post_id = ".$table_post.".post_id AND
+                        ".$table_post.".forum_id IN(".$forum_ids.");";
             Database::query($sql);
 
             // Just in case, deleting in the same table using thread_id as record-linker.
-            $sql = "DELETE FROM ".$table_mail_queue.
-                " USING ".$table_mail_queue." INNER JOIN ".$table_thread.
-                " WHERE $table_mail_queue.c_id = ".$this->course_id." AND $table_thread.c_id = ".$this->course_id." AND ".$table_mail_queue.".thread_id = ".$table_thread.".thread_id".
-                " AND ".$table_thread.".forum_id IN(".$forum_ids.");";
+            $sql = "DELETE FROM $table_mail_queue
+                    USING ".$table_mail_queue." INNER JOIN $table_thread
+                    WHERE
+                        $table_mail_queue.c_id = ".$this->course_id." AND
+                        $table_thread.c_id = ".$this->course_id." AND
+                        $table_mail_queue.thread_id = ".$table_thread.".thread_id AND
+                        $table_thread.forum_id IN(".$forum_ids.");";
             Database::query($sql);
 
-            $sql = "DELETE FROM ".$table_thread_qualify.
-                " USING ".$table_thread_qualify." INNER JOIN ".$table_thread.
-                " WHERE $table_thread_qualify.c_id = ".$this->course_id." AND  $table_thread.c_id = ".$this->course_id." AND ".$table_thread_qualify.".thread_id = ".$table_thread.".thread_id".
-                " AND ".$table_thread.".forum_id IN(".$forum_ids.");";
+            $sql = "DELETE FROM $table_thread_qualify
+                    USING $table_thread_qualify INNER JOIN $table_thread
+                    WHERE
+                        $table_thread_qualify.c_id = ".$this->course_id." AND
+                        $table_thread.c_id = ".$this->course_id." AND
+                        $table_thread_qualify.thread_id = $table_thread.thread_id AND
+                        $table_thread.forum_id IN(".$forum_ids.");";
             Database::query($sql);
 
             $sql = "DELETE FROM ".$table_thread_qualify_log.
                 " USING ".$table_thread_qualify_log." INNER JOIN ".$table_thread.
-                " WHERE  $table_thread_qualify_log.c_id = ".$this->course_id." AND $table_thread.c_id = ".$this->course_id." AND ".$table_thread_qualify_log.".thread_id = ".$table_thread.".thread_id".
-                " AND ".$table_thread.".forum_id IN(".$forum_ids.");";
+                " WHERE
+                    $table_thread_qualify_log.c_id = ".$this->course_id." AND
+                    $table_thread.c_id = ".$this->course_id." AND
+                    ".$table_thread_qualify_log.".thread_id = ".$table_thread.".thread_id AND
+                    ".$table_thread.".forum_id IN(".$forum_ids.");";
             Database::query($sql);
 
-            $sql = "DELETE FROM ".$table_notification." WHERE c_id = ".$this->course_id." AND forum_id IN(".$forum_ids.")";
+            $sql = "DELETE FROM ".$table_notification."
+                    WHERE c_id = ".$this->course_id." AND forum_id IN(".$forum_ids.")";
             Database::query($sql);
 
-            $sql = "DELETE FROM ".$table_post." WHERE c_id = ".$this->course_id." AND forum_id IN(".$forum_ids.")";
+            $sql = "DELETE FROM ".$table_post."
+                    WHERE c_id = ".$this->course_id." AND forum_id IN(".$forum_ids.")";
             Database::query($sql);
 
-            $sql = "DELETE FROM ".$table_thread." WHERE c_id = ".$this->course_id." AND forum_id IN(".$forum_ids.")";
+            $sql = "DELETE FROM ".$table_thread."
+                    WHERE c_id = ".$this->course_id." AND forum_id IN(".$forum_ids.")";
             Database::query($sql);
 
-            $sql = "DELETE FROM ".$table_forum." WHERE c_id = ".$this->course_id." AND forum_id IN(".$forum_ids.")";
+            $sql = "DELETE FROM ".$table_forum."
+                    WHERE c_id = ".$this->course_id." AND forum_id IN(".$forum_ids.")";
             Database::query($sql);
         }
 
@@ -238,15 +265,21 @@ class CourseRecycler
      * Delete forum-categories
      * Deletes all forum-categories from current course without forums
      */
-    function recycle_forum_categories() {
+    function recycle_forum_categories()
+    {
         $table_forum = Database :: get_course_table(TABLE_FORUM);
         $table_forumcat = Database :: get_course_table(TABLE_FORUM_CATEGORY);
         $sql = "SELECT fc.cat_id FROM ".$table_forumcat." fc
-                        LEFT JOIN ".$table_forum." f ON fc.cat_id=f.forum_category AND fc.c_id = ".$this->course_id." AND f.c_id = ".$this->course_id."
+                LEFT JOIN ".$table_forum." f
+                ON
+                    fc.cat_id=f.forum_category AND
+                    fc.c_id = ".$this->course_id." AND
+                    f.c_id = ".$this->course_id."
         		WHERE f.forum_id IS NULL";
         $res = Database::query($sql);
         while ($obj = Database::fetch_object($res)) {
-            $sql = "DELETE FROM ".$table_forumcat." WHERE c_id = ".$this->course_id." AND cat_id = ".$obj->cat_id;
+            $sql = "DELETE FROM ".$table_forumcat."
+                    WHERE c_id = ".$this->course_id." AND cat_id = ".$obj->cat_id;
             Database::query($sql);
         }
     }
@@ -255,16 +288,21 @@ class CourseRecycler
      * Delete link-categories
      * Deletes all empty link-categories (=without links) from current course
      */
-    function recycle_link_categories() {
+    function recycle_link_categories()
+    {
         $link_cat_table = Database :: get_course_table(TABLE_LINK_CATEGORY);
         $link_table = Database :: get_course_table(TABLE_LINK);
         $sql = "SELECT lc.id FROM ".$link_cat_table." lc
                 LEFT JOIN ".$link_table." l
-                    ON lc.id=l.category_id AND lc.c_id = ".$this->course_id." AND l.c_id = ".$this->course_id."
+                ON
+                    lc.id=l.category_id AND
+                    lc.c_id = ".$this->course_id." AND
+                    l.c_id = ".$this->course_id."
         		WHERE l.id IS NULL";
         $res = Database::query($sql);
         while ($obj = Database::fetch_object($res)) {
-            $sql = "DELETE FROM ".$link_cat_table." WHERE c_id = ".$this->course_id." AND id = ".$obj->id;
+            $sql = "DELETE FROM ".$link_cat_table."
+                    WHERE c_id = ".$this->course_id." AND id = ".$obj->id;
             Database::query($sql);
         }
     }
@@ -278,26 +316,31 @@ class CourseRecycler
             $table_attachment = Database :: get_course_table(TABLE_AGENDA_ATTACHMENT);
 
             $ids = implode(',', (array_keys($this->course->resources[RESOURCE_EVENT])));
-            $sql = "DELETE FROM ".$table." WHERE c_id = ".$this->course_id." AND id IN(".$ids.")";
+            $sql = "DELETE FROM ".$table."
+                    WHERE c_id = ".$this->course_id." AND id IN(".$ids.")";
             Database::query($sql);
 
-            $sql = "DELETE FROM ".$table_attachment." WHERE c_id = ".$this->course_id." AND agenda_id IN(".$ids.")";
+            $sql = "DELETE FROM ".$table_attachment."
+                    WHERE c_id = ".$this->course_id." AND agenda_id IN(".$ids.")";
             Database::query($sql);
         }
     }
     /**
      * Delete announcements
      */
-    function recycle_announcements() {
+    function recycle_announcements()
+    {
         if ($this->course->has_resources(RESOURCE_ANNOUNCEMENT)) {
             $table = Database :: get_course_table(TABLE_ANNOUNCEMENT);
             $table_attachment = Database :: get_course_table(TABLE_ANNOUNCEMENT_ATTACHMENT);
 
             $ids = implode(',', (array_keys($this->course->resources[RESOURCE_ANNOUNCEMENT])));
-            $sql = "DELETE FROM ".$table." WHERE c_id = ".$this->course_id." AND id IN(".$ids.")";
+            $sql = "DELETE FROM ".$table."
+                    WHERE c_id = ".$this->course_id." AND id IN(".$ids.")";
             Database::query($sql);
 
-            $sql = "DELETE FROM ".$table_attachment." WHERE c_id = ".$this->course_id." AND announcement_id IN(".$ids.")";
+            $sql = "DELETE FROM ".$table_attachment."
+                    WHERE c_id = ".$this->course_id." AND announcement_id IN(".$ids.")";
             Database::query($sql);
         }
     }
@@ -400,7 +443,8 @@ class CourseRecycler
     /**
      * Recycle surveys - removes everything
      */
-    function recycle_surveys() {
+    function recycle_surveys()
+    {
         if ($this->course->has_resources(RESOURCE_SURVEY)) {
             $table_survey = Database :: get_course_table(TABLE_SURVEY);
             $table_survey_q = Database :: get_course_table(TABLE_SURVEY_QUESTION);
@@ -420,10 +464,12 @@ class CourseRecycler
             Database::query($sql);
         }
     }
+
     /**
      * Recycle learnpaths
      */
-    function recycle_learnpaths() {
+    function recycle_learnpaths()
+    {
         if ($this->course->has_resources(RESOURCE_LEARNPATH)) {
             $table_main = Database :: get_course_table(TABLE_LP_MAIN);
             $table_item = Database :: get_course_table(TABLE_LP_ITEM);
@@ -436,9 +482,9 @@ class CourseRecycler
                 // See task #875.
                 if ($learnpath->lp_type == 2) {
                     // This is a learning path of SCORM type.
-                    if (trim($learnpath->path) != '')   // A sanity check for avoiding removal of the parent folder scorm/
-                                                        // when $learnpath->path value is incorrect for some reason.
-                    {
+                    // A sanity check for avoiding removal of the parent folder scorm/
+                    if (trim($learnpath->path) != '') {
+                        // when $learnpath->path value is incorrect for some reason.
                         // The directory trat contains files of the SCORM package is to be deleted.
                         $scorm_package_dir = realpath($this->course->path . 'scorm/' . $learnpath->path);
                         rmdirr($scorm_package_dir);
@@ -446,40 +492,47 @@ class CourseRecycler
                 }
 
                 //remove links from course homepage
-                $sql = "DELETE FROM $table_tool WHERE c_id = ".$this->course_id."  AND link LIKE '%lp_controller.php%lp_id=$id%' AND image='scormbuilder.gif'";
+                $sql = "DELETE FROM $table_tool
+                        WHERE c_id = ".$this->course_id." AND link LIKE '%lp_controller.php%lp_id=$id%' AND image='scormbuilder.gif'";
                 Database::query($sql);
                 //remove elements from lp_* tables (from bottom-up) by removing interactions, then item_view, then views and items, then paths
-                $sql_items = "SELECT id FROM $table_item WHERE  c_id = ".$this->course_id."  AND lp_id=$id";
+                $sql_items = "SELECT id FROM $table_item
+                              WHERE c_id = ".$this->course_id."  AND lp_id=$id";
                 $res_items = Database::query($sql_items);
                 while ($row_item = Database::fetch_array($res_items)) {
                     //get item views
-                    $sql_iv = "SELECT id FROM $table_iv WHERE  c_id = ".$this->course_id."  AND lp_item_id=".$row_item['id'];
+                    $sql_iv = "SELECT id FROM $table_iv
+                               WHERE  c_id = ".$this->course_id."  AND lp_item_id=".$row_item['id'];
                     $res_iv = Database::query($sql_iv);
                     while ($row_iv = Database::fetch_array($res_iv)) {
                         //delete interactions
-                        $sql_iv_int_del = "DELETE FROM $table_iv_int WHERE  c_id = ".$this->course_id."  AND lp_iv_id = ".$row_iv['id'];
-                        $res_iv_int_del = Database::query($sql_iv_int_del);
+                        $sql_iv_int_del = "DELETE FROM $table_iv_int
+                                           WHERE c_id = ".$this->course_id."  AND lp_iv_id = ".$row_iv['id'];
+                        Database::query($sql_iv_int_del);
                     }
                     //delete item views
-                    $sql_iv_del = "DELETE FROM $table_iv WHERE c_id = ".$this->course_id."  AND lp_item_id=".$row_item['id'];
-                    $res_iv_del = Database::query($sql_iv_del);
+                    $sql_iv_del = "DELETE FROM $table_iv
+                                   WHERE c_id = ".$this->course_id."  AND lp_item_id=".$row_item['id'];
+                    Database::query($sql_iv_del);
                 }
                 //delete items
                 $sql_items_del = "DELETE FROM $table_item WHERE c_id = ".$this->course_id."  AND lp_id=$id";
-                $res_items_del = Database::query($sql_items_del);
+                Database::query($sql_items_del);
                 //delete views
                 $sql_views_del = "DELETE FROM $table_view WHERE c_id = ".$this->course_id."  AND lp_id=$id";
-                $res_views_del = Database::query($sql_views_del);
+                Database::query($sql_views_del);
                 //delete lps
                 $sql_del = "DELETE FROM $table_main WHERE c_id = ".$this->course_id."  AND id = $id";
-                $res_del = Database::query($sql_del);
+                Database::query($sql_del);
             }
         }
     }
+
     /**
      * Delete course description
      */
-    function recycle_cours_description() {
+    function recycle_cours_description()
+    {
         if ($this->course->has_resources(RESOURCE_COURSEDESCRIPTION)) {
             $table = Database :: get_course_table(TABLE_COURSE_DESCRIPTION);
             $ids = implode(',', (array_keys($this->course->resources[RESOURCE_COURSEDESCRIPTION])));
@@ -487,10 +540,12 @@ class CourseRecycler
             Database::query($sql);
         }
     }
+
     /**
     * Recycle Thematics
     */
-    function recycle_thematic($session_id = 0) {
+    function recycle_thematic($session_id = 0)
+    {
         if ($this->course->has_resources(RESOURCE_THEMATIC)) {
             $table_thematic         = Database :: get_course_table(TABLE_THEMATIC);
             $table_thematic_advance = Database :: get_course_table(TABLE_THEMATIC_ADVANCE);
@@ -522,7 +577,8 @@ class CourseRecycler
     /**
     * Recycle Attendances
     */
-    function recycle_attendance($session_id = 0) {
+    function recycle_attendance($session_id = 0)
+    {
         if ($this->course->has_resources(RESOURCE_ATTENDANCE)) {
             $table_attendance          = Database :: get_course_table(TABLE_ATTENDANCE);
             $table_attendance_calendar = Database :: get_course_table(TABLE_ATTENDANCE_CALENDAR);
@@ -541,10 +597,12 @@ class CourseRecycler
             }
         }
     }
+
     /**
      * Recycle Works
      */
-    function recycle_work($session_id = 0) {
+    function recycle_work($session_id = 0)
+    {
         if ($this->course->has_resources(RESOURCE_WORK)) {
             $table_work          = Database :: get_course_table(TABLE_STUDENT_PUBLICATION);
             $table_work_assignment = Database :: get_course_table(TABLE_STUDENT_PUBLICATION_ASSIGNMENT);
@@ -560,7 +618,13 @@ class CourseRecycler
                     // Finally, delete the main task registry
                     $cond = array('id = ? AND c_id = ?'=>array($last_id, $this->course_id));
                     Database::delete($table_work, $cond);
-                    api_item_property_update($this->course_info, TOOL_STUDENTPUBLICATION, $last_id,'StudentPublicationDeleted', api_get_user_id());
+                    api_item_property_update(
+                        $this->course_info,
+                        TOOL_STUDENTPUBLICATION,
+                        $last_id,
+                        'StudentPublicationDeleted',
+                        api_get_user_id()
+                    );
                 }
             }
         }

+ 11 - 5
main/coursecopy/classes/CourseRestorer.class.php

@@ -1368,11 +1368,17 @@ class CourseRestorer
         // question source_id => category source_id
         if ($this->course->has_resources(RESOURCE_QUIZQUESTION)) {
             // check the category number of each question restored
-            foreach ($resources[RESOURCE_QUIZQUESTION] as $id => $CourseCopyQuestion) {
-                $new_quiz_question_id = $resources[RESOURCE_QUIZQUESTION][$id]->destination_id;
-                $question_category = $CourseCopyQuestion->question_category;
-                if ($question_category > 0) {
-                    Testcategory::add_category_for_question_id($tab_test_category_id_old_new[$question_category], $new_quiz_question_id, $course_id);
+            if (!empty($resources[RESOURCE_QUIZQUESTION])) {
+                foreach ($resources[RESOURCE_QUIZQUESTION] as $id => $CourseCopyQuestion) {
+                    $new_quiz_question_id = $resources[RESOURCE_QUIZQUESTION][$id]->destination_id;
+                    $question_category = $CourseCopyQuestion->question_category;
+                    if ($question_category > 0) {
+                        Testcategory::add_category_for_question_id(
+                            $tab_test_category_id_old_new[$question_category],
+                            $new_quiz_question_id,
+                            $course_id
+                        );
+                    }
                 }
             }
         }

+ 29 - 8
main/coursecopy/classes/CourseSelectForm.class.php

@@ -146,7 +146,11 @@ class CourseSelectForm
 		echo '<form method="post" id="upload_form" name="course_select_form" onsubmit="javascript: myUpload.start(\'dynamic_div\',\''.api_get_path(WEB_CODE_PATH).'img/progress_bar.gif\',\''.get_lang('PleaseStandBy', '').'\',\'upload_form\')">';
 		echo '<input type="hidden" name="action" value="course_select_form"/>';
 
-		if (!empty($hidden_fields['destination_course']) && !empty($hidden_fields['origin_course']) && !empty($hidden_fields['destination_session']) && !empty($hidden_fields['origin_session']) ) {
+		if (!empty($hidden_fields['destination_course']) &&
+            !empty($hidden_fields['origin_course']) &&
+            !empty($hidden_fields['destination_session']) &&
+            !empty($hidden_fields['origin_session'])
+        ) {
 			echo '<input type="hidden" name="destination_course" 	value="'.$hidden_fields['destination_course'].'"/>';
 			echo '<input type="hidden" name="origin_course" 		value="'.$hidden_fields['origin_course'].'"/>';
 			echo '<input type="hidden" name="destination_session" 	value="'.$hidden_fields['destination_session'].'"/>';
@@ -298,13 +302,22 @@ class CourseSelectForm
 			}
 		}
 
+        $recycleOption = isset($_POST['recycle_option']) ? true : false;
+
 		if (empty($element_count)) {
 		    Display::display_warning_message(get_lang('NoDataAvailable'));
 		} else {
     		if (!empty($hidden_fields['destination_session'])) {
-    			echo '<br /><button class="save" type="submit" onclick="javascript:if(!confirm('."'".addslashes(api_htmlentities(get_lang("ConfirmYourChoice"),ENT_QUOTES, $charset))."'".')) return false;" >'.get_lang('Ok').'</button>';
+    			echo '<br /><button class="save" type="submit" onclick="javascript:if(!confirm('."'".addslashes(api_htmlentities(get_lang("ConfirmYourChoice"),ENT_QUOTES, $charset))."'".')) return false;" >'.
+                    get_lang('Ok').'</button>';
     		} else {
-    			echo '<br /><button class="save" type="submit" onclick="checkLearnPath(\''.addslashes(get_lang('DocumentsWillBeAddedToo')).'\')">'.get_lang('Ok').'</button>';
+                if ($recycleOption) {
+                    echo '<br /><button class="save" type="submit">'.
+                        get_lang('Ok').'</button>';
+                } else {
+    			    echo '<br /><button class="save" type="submit" onclick="checkLearnPath(\''.addslashes(get_lang('DocumentsWillBeAddedToo')).'\')">'.
+                    get_lang('Ok').'</button>';
+                }
     		}
 		}
 
@@ -314,8 +327,11 @@ class CourseSelectForm
 		echo '<div id="dynamic_div" style="display:block;margin-left:40%;margin-top:10px;height:50px;"></div>';
 	}
 
-
-    static function display_hidden_quiz_questions($course) {
+    /**
+     * @param $course
+     */
+    static function display_hidden_quiz_questions($course)
+    {
 		if(is_array($course->resources)){
 			foreach ($course->resources as $type => $resources) {
 				if (count($resources) > 0) {
@@ -331,7 +347,11 @@ class CourseSelectForm
 		}
 	}
 
-	static function display_hidden_scorm_directories($course) {
+    /**
+     * @param $course
+     */
+    static function display_hidden_scorm_directories($course)
+    {
         if (is_array($course->resources)){
 			foreach ($course->resources as $type => $resources) {
 				if (count($resources) > 0) {
@@ -521,7 +541,8 @@ class CourseSelectForm
 	 * @param array $hidden_fiels Hidden fields to add to the form.
 	 * @param boolean the document array will be serialize. This is used in the course_copy.php file
 	 */
-	 function display_form_session_export($list_course, $hidden_fields = null, $avoid_serialize=false) {
+	 function display_form_session_export($list_course, $hidden_fields = null, $avoid_serialize=false)
+     {
 ?>
 		<script>
 			function exp(item) {
@@ -620,4 +641,4 @@ class CourseSelectForm
 		echo '</form>';
 		echo '<div id="dynamic_div" style="display:block;margin-left:40%;margin-top:10px;height:50px;"></div>';
 	}
-}
+}

+ 10 - 4
main/coursecopy/copy_course.php

@@ -68,11 +68,17 @@ if ((isset($_POST['action']) && $_POST['action'] == 'course_select_form') || (is
     $table_cu = Database :: get_main_table(TABLE_MAIN_COURSE_USER);
     $user_info = api_get_user_info();
     $course_info = api_get_course_info();
-    $sql = 'SELECT * FROM '.$table_c.' c, '.$table_cu.' cu WHERE cu.course_code = c.code';
+    $sql = 'SELECT *
+            FROM '.$table_c.' c, '.$table_cu.' cu
+            WHERE cu.course_code = c.code';
     if (!api_is_platform_admin()) {
         $sql .= ' AND cu.status=1 ';
     }
-    $sql .= ' AND target_course_code IS NULL AND cu.user_id = '.$user_info['user_id'].' AND c.code != '."'".$course_info['sysCode']."'".' ORDER BY title ASC';
+    $sql .= ' AND
+        target_course_code IS NULL AND
+        cu.user_id = '.$user_info['user_id'].' AND
+        c.code != '."'".$course_info['sysCode']."'".'
+    ORDER BY title ASC';
     $res = Database::query($sql);
     if (Database::num_rows($res) == 0) {
         Display::display_normal_message(get_lang('NoDestinationCoursesAvailable'));
@@ -83,7 +89,6 @@ if ((isset($_POST['action']) && $_POST['action'] == 'course_select_form') || (is
         }
 
         $form = new FormValidator('copy_course', 'post', 'copy_course.php?'.api_get_cidreq());
-        $form->addElement('header', '');
         $form->addElement('select', 'destination_course', get_lang('SelectDestinationCourse'), $options);
 
         $group = array();
@@ -96,10 +101,11 @@ if ((isset($_POST['action']) && $_POST['action'] == 'course_select_form') || (is
         $group[] = $form->createElement('radio', 'same_file_name_option', null, get_lang('SameFilenameRename'), FILE_RENAME);
         $group[] = $form->createElement('radio', 'same_file_name_option', null, get_lang('SameFilenameOverwrite'), FILE_OVERWRITE);
         $form->addGroup($group, '', get_lang('SameFilename'));
+        $form->add_progress_bar();
         $form->addElement('style_submit_button', 'submit', get_lang('CopyCourse'), 'class="save"');
         $form->setDefaults(array('copy_option' =>'select_items','same_file_name_option' => FILE_OVERWRITE));
         $form->display();
 	}
 }
 
-Display::display_footer();
+Display::display_footer();

+ 16 - 12
main/coursecopy/create_backup.php

@@ -53,14 +53,18 @@ echo Display::page_header($nameTools);
 
 /*	MAIN CODE */
 
-if ((isset($_POST['action']) && $_POST['action'] == 'course_select_form') || (isset($_POST['backup_option']) && $_POST['backup_option'] == 'full_backup')) {
+if ((isset($_POST['action']) &&
+    $_POST['action'] == 'course_select_form') ||
+    (isset($_POST['backup_option']) &&
+    $_POST['backup_option'] == 'full_backup')
+) {
 	if (isset ($_POST['action']) && $_POST['action'] == 'course_select_form') {
-		$course = CourseSelectForm::get_posted_course();        
+		$course = CourseSelectForm::get_posted_course();
 	} else {
 		$cb = new CourseBuilder();
 		$course = $cb->build();
 	}
-	$zip_file = CourseArchiver::write_course($course); 
+	$zip_file = CourseArchiver::write_course($course);
 	Display::display_confirmation_message(get_lang('BackupCreated'));
 	echo '<br /><a class="btn btn-primary btn-large" href="../course_info/download.php?archive='.$zip_file.'">'.get_lang('Download').'</a>';
 
@@ -73,25 +77,25 @@ if ((isset($_POST['action']) && $_POST['action'] == 'course_select_form') || (is
 	$course = $cb->build();
 	if (!$course->has_resources()) {
 		echo get_lang('NoResourcesToBackup');
-	} else {		
-		
-		$form = new FormValidator('create_backup_form', 'post');
+	} else {
+		$form = new FormValidator('create_backup_form', 'post', api_get_self().'?'.api_get_cidreq());
 		$form->addElement('header',get_lang('SelectOptionForBackup'));
-		
 		$form->addElement('radio', 'backup_option', '', get_lang('CreateFullBackup'), 'full_backup');
 		$form->addElement('radio', 'backup_option', '',  get_lang('LetMeSelectItems'), 'select_items');
-		
 		$form->addElement('style_submit_button', null, get_lang('CreateBackup'), 'class="save"');
-
 		$form->add_progress_bar();
 		// When progress bar appears we have to hide the title "Please select a backup-option".
-		$form->updateAttributes(array('onsubmit' => str_replace('javascript: ', 'javascript: page_title = getElementById(\'page_title\'); if (page_title) { setTimeout(\'page_title.style.display = \\\'none\\\';\', 2000); } ', $form->getAttribute('onsubmit'))));
-
+		$form->updateAttributes(
+            array('onsubmit' => str_replace(
+                'javascript: ',
+                'javascript: page_title = getElementById(\'page_title\'); if (page_title) { setTimeout(\'page_title.style.display = \\\'none\\\';\', 2000); } ',
+                $form->getAttribute('onsubmit')
+            ))
+        );
 		$values['backup_option'] = 'full_backup';
 		$form->setDefaults($values);
 		$form->display();
 	}
 }
 
-/*	FOOTER */
 Display::display_footer();

+ 19 - 9
main/coursecopy/import_backup.php

@@ -52,12 +52,16 @@ echo Display::page_header($nameTools);
 
 /*	MAIN CODE */
 
-if ((isset($_POST['action']) && $_POST['action'] == 'course_select_form' ) || (isset($_POST['import_option']) && $_POST['import_option'] == 'full_backup' )) {
+if ((isset($_POST['action']) &&
+    $_POST['action'] == 'course_select_form') ||
+    (isset($_POST['import_option']) &&
+    $_POST['import_option'] == 'full_backup')
+) {
 	$error = false;
 	if (isset($_POST['action']) && $_POST['action'] == 'course_select_form') {
 		// Partial backup here we recover the documents posted
 		$course = CourseSelectForm::get_posted_course();
-        
+
 	} else {
 		if ($_POST['backup_type'] == 'server') {
 			$filename = $_POST['backup_server'];
@@ -74,7 +78,7 @@ if ((isset($_POST['action']) && $_POST['action'] == 'course_select_form' ) || (i
 				$error = true;
 			}
 		}
-    
+
         if (!$error) {
 		  // Full backup
 		  $course = CourseArchiver::read_course($filename, $delete_file);
@@ -96,7 +100,7 @@ if ((isset($_POST['action']) && $_POST['action'] == 'course_select_form' ) || (i
             echo '<a class="btn" href="import_backup.php?'.api_get_cidreq().'">'.get_lang('TryAgain').'</a>';
         } else {
             if ($filename == '') {
-               Display::display_error_message(get_lang('SelectBackupFile')); 
+               Display::display_error_message(get_lang('SelectBackupFile'));
                echo '<a class="btn" href="import_backup.php?'.api_get_cidreq().'">'.get_lang('TryAgain').'</a>';
             } else {
     			Display::display_error_message(get_lang('UploadError'));
@@ -105,6 +109,7 @@ if ((isset($_POST['action']) && $_POST['action'] == 'course_select_form' ) || (i
 		}
 	}
 	CourseArchiver::clean_backup_dir();
+
 } elseif (isset($_POST['import_option']) && $_POST['import_option'] == 'select_items') {
 	if ($_POST['backup_type'] == 'server') {
 		$filename = $_POST['backup_server'];
@@ -114,7 +119,7 @@ if ((isset($_POST['action']) && $_POST['action'] == 'course_select_form' ) || (i
 		$delete_file = true;
 	}
 	$course = CourseArchiver::read_course($filename, $delete_file);
-  
+
 	if ($course->has_resources() && ($filename !== false)) {
 		CourseSelectForm::display_form($course, array('same_file_name_option' => $_POST['same_file_name_option']));
 	} elseif ($filename === false) {
@@ -129,7 +134,7 @@ if ((isset($_POST['action']) && $_POST['action'] == 'course_select_form' ) || (i
 	$backups = CourseArchiver::get_available_backups($is_platformAdmin ?null:$user['user_id']);
 	$backups_available = count($backups) > 0;
 
-	$form = new FormValidator('import_backup_form', 'post', 'import_backup.php', '', 'multipart/form-data');
+	$form = new FormValidator('import_backup_form', 'post', api_get_path(WEB_CODE_PATH).'coursecopy/import_backup.php?'.api_get_cidreq(), '', 'multipart/form-data');
     $form->addElement('header', get_lang('SelectBackupFile'));
 	$renderer = $form->defaultRenderer();
 	$renderer->setElementTemplate('<div>{element}</div> ');
@@ -175,10 +180,15 @@ if ((isset($_POST['action']) && $_POST['action'] == 'course_select_form' ) || (i
 
 	$form->add_progress_bar();
 	// When progress bar appears we have to hide the title "Select backup file".
-	$form->updateAttributes(array('onsubmit' => str_replace('javascript: ', 'javascript: page_title = getElementById(\'page_title\'); if (page_title) { setTimeout(\'page_title.style.display = \\\'none\\\';\', 2000); } ', $form->getAttribute('onsubmit'))));
+	$form->updateAttributes(array(
+        'onsubmit' => str_replace(
+            'javascript: ',
+            'javascript: page_title = getElementById(\'page_title\'); if (page_title) { setTimeout(\'page_title.style.display = \\\'none\\\';\', 2000); } ',
+            $form->getAttribute('onsubmit')
+        )
+    ));
 
 	$form->display();
 }
 
-/*	FOOTER */
-Display::display_footer();
+Display::display_footer();

+ 14 - 10
main/coursecopy/recycle_course.php

@@ -26,7 +26,10 @@ if (!api_is_allowed_to_edit()) {
 $this_section = SECTION_COURSES;
 
 // Breadcrumbs
-$interbreadcrumb[] = array('url' => '../course_info/maintenance.php', 'name' => get_lang('Maintenance'));
+$interbreadcrumb[] = array(
+    'url' => api_get_path(WEB_CODE_PATH).'course_info/maintenance.php',
+    'name' => get_lang('Maintenance')
+);
 
 // Displaying the header
 $nameTools = get_lang('RecycleCourse');
@@ -43,27 +46,30 @@ echo Display::page_header($nameTools);
 
 /*		MAIN CODE	*/
 
-if ((isset($_POST['action']) && $_POST['action'] == 'course_select_form') || (isset($_POST['recycle_option']) && $_POST['recycle_option'] == 'full_backup')) {
+if ((isset($_POST['action']) &&
+    $_POST['action'] == 'course_select_form') ||
+    (isset($_POST['recycle_option']) &&
+    $_POST['recycle_option'] == 'full_backup')
+) {
 	if (isset($_POST['action']) && $_POST['action'] == 'course_select_form') {
 		$course = CourseSelectForm::get_posted_course();
 	} else {
 		$cb = new CourseBuilder();
 		$course = $cb->build();
-	}    
+	}
 	$recycle_type = "";
 	if (isset($_POST['recycle_option']) && $_POST['recycle_option'] == 'full_backup') {
 	    $recycle_type = 'full_backup';
-	}
-	else if (isset($_POST['action']) && $_POST['action'] == 'course_select_form') {
+	} else if (isset($_POST['action']) && $_POST['action'] == 'course_select_form') {
 	    $recycle_type = 'select_items';
 	}
 	$cr = new CourseRecycler($course);
 	$cr->recycle($recycle_type);
-	
+
 	Display::display_confirmation_message(get_lang('RecycleFinished'));
 } elseif (isset($_POST['recycle_option']) && $_POST['recycle_option'] == 'select_items') {
 	$cb = new CourseBuilder();
-	$course = $cb->build();    
+	$course = $cb->build();
 	CourseSelectForm::display_form($course);
 } else {
 	$cb = new CourseBuilder();
@@ -72,12 +78,10 @@ if ((isset($_POST['action']) && $_POST['action'] == 'course_select_form') || (is
 		echo get_lang('NoResourcesToRecycle');
 	} else {
 		Display::display_warning_message(get_lang('RecycleWarning'), false);
-        $form = new FormValidator('recycle_course', 'post', 'recycle_course.php?'.api_get_cidreq());
+        $form = new FormValidator('recycle_course', 'post', api_get_self().'?'.api_get_cidreq());
 		$form->addElement('header', get_lang('SelectOptionForBackup'));
-		
 		$form->addElement('radio', 'recycle_option', null, get_lang('FullRecycle'), 'full_backup');
         $form->addElement('radio', 'recycle_option', null, get_lang('LetMeSelectItems'), 'select_items');
-        
         $form->addElement('style_submit_button', 'submit', get_lang('RecycleCourse'), 'class="save"');
         $form->setDefaults(array('recycle_option' => 'select_items'));
         $form->display();

+ 5 - 0
main/css/academica/dataTable.css

@@ -9,6 +9,11 @@
  *  Project:      DataTables
  *
  *  Copyright 2009 Allan Jardine. All Rights Reserved.
+ *  Note: dataTable.css was later released as part of the jquery.dataTables
+ *  plugin, released itself as GPLv2. As such, we believe this copyright is no
+ *  longer an issue and will try to upgrade to a later version of dataTables
+ *  in the near future. -- Yannick Warnier, Chamilo project leader, 2014-04
+ *  See https://support.chamilo.org/issues/7043
  *
  * ***************************************************************************
  * DESCRIPTION

+ 5 - 0
main/css/baby_orange/dataTable.css

@@ -9,6 +9,11 @@
  *  Project:      DataTables
  *
  *  Copyright 2009 Allan Jardine. All Rights Reserved.
+ *  Note: dataTable.css was later released as part of the jquery.dataTables
+ *  plugin, released itself as GPLv2. As such, we believe this copyright is no
+ *  longer an issue and will try to upgrade to a later version of dataTables
+ *  in the near future. -- Yannick Warnier, Chamilo project leader, 2014-04
+ *  See https://support.chamilo.org/issues/7043
  *
  * ***************************************************************************
  * DESCRIPTION

+ 31 - 2
main/css/base.css

@@ -2257,7 +2257,7 @@ div.admin_section h4 {
 }
 
 .actions span {
-    margin-right:0px;
+    /* margin-right:0px; */
 }
 
 #courseintro_empty {
@@ -2411,7 +2411,7 @@ div.admin_section h4 {
 
 /* chosen javascript checkbox select width fix */
 .chzn-select {
-    min-width: 173px;
+    /*min-width: 173px; */
 }
 
 .lp_tree {
@@ -4746,3 +4746,32 @@ i.size-32.icon-new-work{
 .jqgrid_whitespace {
     white-space: normal !important;
 }
+
+.text-h1 {
+    font-size: 24px;
+}
+
+.text-h2 {
+    font-size: 21px;
+}
+
+.text-h3 {
+    font-size: 18px;
+}
+
+.text-h4 {
+    font-size: 15px;
+}
+
+.text-h5 {
+    font-size: 12px;
+    font-weight: normal;
+}
+
+.chosen-container {
+    min-width: 250px;
+}
+
+.chzn-container-single .chzn-search {
+    z-index: 1010;
+}

+ 5 - 0
main/css/blue_lagoon/dataTable.css

@@ -9,6 +9,11 @@
  *  Project:      DataTables
  *
  *  Copyright 2009 Allan Jardine. All Rights Reserved.
+ *  Note: dataTable.css was later released as part of the jquery.dataTables
+ *  plugin, released itself as GPLv2. As such, we believe this copyright is no
+ *  longer an issue and will try to upgrade to a later version of dataTables
+ *  in the near future. -- Yannick Warnier, Chamilo project leader, 2014-04
+ *  See https://support.chamilo.org/issues/7043
  *
  * ***************************************************************************
  * DESCRIPTION

+ 5 - 0
main/css/chamilo/dataTable.css

@@ -9,6 +9,11 @@
  *  Project:      DataTables
  *
  *  Copyright 2009 Allan Jardine. All Rights Reserved.
+ *  Note: dataTable.css was later released as part of the jquery.dataTables
+ *  plugin, released itself as GPLv2. As such, we believe this copyright is no
+ *  longer an issue and will try to upgrade to a later version of dataTables
+ *  in the near future. -- Yannick Warnier, Chamilo project leader, 2014-04
+ *  See https://support.chamilo.org/issues/7043
  *
  * ***************************************************************************
  * DESCRIPTION

+ 32 - 31
main/css/chamilo/default.css

@@ -11,7 +11,7 @@ a {
     color :#6E6E6E;
 }
 a:visited {
-    text-decoration: none;    
+    text-decoration: none;
 }
 a:hover {
     text-decoration: none;
@@ -46,10 +46,10 @@ a:active {
 
 
 .subnav .nav > #current > a,
-.subnav .nav > #current > a:hover {  
+.subnav .nav > #current > a:hover {
     color: #fff;
     background-color: #0f466a;
-    border-right-color: #0f466a;  
+    border-right-color: #0f466a;
 }
 
 .subnav li a {
@@ -108,7 +108,7 @@ a.thumbnail:hover{
 }
 
 .breadcrumb li{
-    
+
     text-shadow: none;
 }
 .breadcrumb a.btn-mini{
@@ -368,8 +368,8 @@ a.thumbnail:hover{
     margin-top: 10px;
     color: #0191C7;
     font-weight: normal;
-    
-    
+
+
 }
 .page-header {
   border-bottom-color: #0191C7;
@@ -455,13 +455,13 @@ a.thumbnail:hover{
   box-shadow: none;
 }
 .breadcrumb a{
-  
+
   line-height: 30px;
   text-transform: none;
 }
 
 .breadcrumb li{
-    
+
     text-shadow: none;
 }
 
@@ -639,8 +639,8 @@ a.thumbnail:hover{
     margin-top: 10px;
     color: #0191C7;
     font-weight: normal;
-    
-    
+
+
 }
 .page-header {
   border:none;
@@ -667,6 +667,9 @@ a.thumbnail:hover{
 .categories-course-description h3{
     color: #0F466A;
 }
+.categories-course-description .text-h3{
+    color: #0F466A;
+}
 #course_tools .content a {
   font-size: 12px;
   font-weight: normal;
@@ -687,12 +690,12 @@ a.thumbnail:hover{
  *  FOOTER STYLES                                    *
  *****************************************************/
 footer {
-    height: 10em;    
+    height: 10em;
     background-color: #0191C7;
     background-image: none;
-    background-repeat:repeat-x;    
+    background-repeat:repeat-x;
     color:#ffffff;
-    border-top: none;   
+    border-top: none;
 }
 footer .container .row {
   padding-top: 5px;
@@ -720,8 +723,8 @@ footer a:link, footer a:visited {
   color: #ffffff;
   border-right:1px solid #222;
   border-left:1px solid #222;
-  
-  background-color: #222; 
+
+  background-color: #222;
   background-repeat: repeat-x;
   background-image: -khtml-gradient(linear, left top, left bottom, from(#333333), to(#222222));
   background-image: -moz-linear-gradient(top, #333333, #222222);
@@ -734,7 +737,7 @@ footer a:link, footer a:visited {
   -webkit-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.25), inset 0 -1px 0 rgba(0, 0, 0, 0.1);
   -moz-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.25), inset 0 -1px 0 rgba(0, 0, 0, 0.1);
   box-shadow: 0 1px 3px rgba(0, 0, 0, 0.25), inset 0 -1px 0 rgba(0, 0, 0, 0.1);
-    
+
 }
 #chatboxtitlemain {
     cursor: pointer;
@@ -749,12 +752,10 @@ footer a:link, footer a:visited {
 .normal-message {
     color: #00407F;
     border: 1px solid #CDE6F5;
-    background: url("images/background_message.png") repeat-x scroll 0 0 #EAF8FE;
 }
 .warning-message {
     border: 1px solid #FFB30F;
     color: #000;
-	background: url("images/background_message.png") repeat-x scroll 0 0 #FFEFA7;
 }
 .confirmation-message {
 	border: 1px solid #1F8323;
@@ -779,7 +780,7 @@ footer a:link, footer a:visited {
 #social-content-online {
     background-color:#00AAE3;
 }
-		
+
 .admin_section li {
     background-image:url(images/bullet.gif);
 }
@@ -795,7 +796,7 @@ footer a:link, footer a:visited {
     background:transparent url('images/logob4.gif') no-repeat;
 }
 
-#bottomhellomindfactory {    
+#bottomhellomindfactory {
     background:transparent url('images/textologo.jpg') no-repeat;
 }
 
@@ -874,10 +875,10 @@ button.upload {
 }
 
 button.arrowr, input.arrowr {
-	background-image:url(images/2rightarrow.gif);	
+	background-image:url(images/2rightarrow.gif);
 }
 button.arrowl, input.arrowl {
-    background-image:url(images/2leftarrow.gif);	
+    background-image:url(images/2leftarrow.gif);
 }
 .refresh {
     background-image:url(images/refresh.png);
@@ -888,7 +889,7 @@ button.arrowl, input.arrowl {
 }
 
 /*+++++++++++++++++++++++++++++++++++++++++++
- + CHAMILO INSTALL 
+ + CHAMILO INSTALL
  ++++++++++++++++++++++++++++++++++++++++++++*/
 .install-mascot{
   background: url(images/install.png) no-repeat center 0;
@@ -1118,43 +1119,43 @@ RESPONSIVE CSS
         padding-left: 30px;
         background-size: 25px auto;
     }
-    
+
     .new-message-social{
         background: url("images/icon-chamilo.png") no-repeat 0 -307px;
         padding-left: 30px;
         background-size: 25px auto;
     }
-    
+
     .invitations-social{
         background: url("images/icon-chamilo.png") no-repeat 0 -378px;
         padding-left: 30px;
         background-size: 25px auto;
     }
-    
+
     .profile-social{
         background: url("images/icon-chamilo.png") no-repeat 0 -414px;
         padding-left: 30px;
         background-size: 25px auto;
     }
-    
+
     .add-course{
         background: url("images/icon-chamilo.png") no-repeat 0 -274px;
         padding-left: 30px;
         background-size: 25px auto;
     }
-   
+
     .order-course{
         background: url("images/icon-chamilo.png") no-repeat 0 -447px;
         padding-left: 30px;
         background-size: 25px auto;
     }
-    
+
     .history-course{
         background: url("images/icon-chamilo.png") no-repeat 0 -481px;
         padding-left: 30px;
         background-size: 25px auto;
     }
-    
+
     .list-course{
         background: url("images/icon-chamilo.png") no-repeat 0 -517px;
         padding-left: 30px;
@@ -1164,7 +1165,7 @@ RESPONSIVE CSS
       background: url("images/icon-chamilo.png") no-repeat scroll 0 -552px / 25px auto rgba(0, 0, 0, 0);
       padding-left: 30px;
 }
-    
+
 }
 @media (min-width: 321px) and (max-width: 480px){
 footer {

+ 5 - 0
main/css/chamilo_electric_blue/dataTable.css

@@ -9,6 +9,11 @@
  *  Project:      DataTables
  *
  *  Copyright 2009 Allan Jardine. All Rights Reserved.
+ *  Note: dataTable.css was later released as part of the jquery.dataTables
+ *  plugin, released itself as GPLv2. As such, we believe this copyright is no
+ *  longer an issue and will try to upgrade to a later version of dataTables
+ *  in the near future. -- Yannick Warnier, Chamilo project leader, 2014-04
+ *  See https://support.chamilo.org/issues/7043
  *
  * ***************************************************************************
  * DESCRIPTION

+ 5 - 0
main/css/chamilo_green/dataTable.css

@@ -9,6 +9,11 @@
  *  Project:      DataTables
  *
  *  Copyright 2009 Allan Jardine. All Rights Reserved.
+ *  Note: dataTable.css was later released as part of the jquery.dataTables
+ *  plugin, released itself as GPLv2. As such, we believe this copyright is no
+ *  longer an issue and will try to upgrade to a later version of dataTables
+ *  in the near future. -- Yannick Warnier, Chamilo project leader, 2014-04
+ *  See https://support.chamilo.org/issues/7043
  *
  * ***************************************************************************
  * DESCRIPTION

+ 5 - 0
main/css/chamilo_orange/dataTable.css

@@ -9,6 +9,11 @@
  *  Project:      DataTables
  *
  *  Copyright 2009 Allan Jardine. All Rights Reserved.
+ *  Note: dataTable.css was later released as part of the jquery.dataTables
+ *  plugin, released itself as GPLv2. As such, we believe this copyright is no
+ *  longer an issue and will try to upgrade to a later version of dataTables
+ *  in the near future. -- Yannick Warnier, Chamilo project leader, 2014-04
+ *  See https://support.chamilo.org/issues/7043
  *
  * ***************************************************************************
  * DESCRIPTION

+ 5 - 0
main/css/chamilo_red/dataTable.css

@@ -9,6 +9,11 @@
  *  Project:      DataTables
  *
  *  Copyright 2009 Allan Jardine. All Rights Reserved.
+ *  Note: dataTable.css was later released as part of the jquery.dataTables
+ *  plugin, released itself as GPLv2. As such, we believe this copyright is no
+ *  longer an issue and will try to upgrade to a later version of dataTables
+ *  in the near future. -- Yannick Warnier, Chamilo project leader, 2014-04
+ *  See https://support.chamilo.org/issues/7043
  *
  * ***************************************************************************
  * DESCRIPTION

+ 5 - 0
main/css/chamilo_sport_red/dataTable.css

@@ -9,6 +9,11 @@
  *  Project:      DataTables
  *
  *  Copyright 2009 Allan Jardine. All Rights Reserved.
+ *  Note: dataTable.css was later released as part of the jquery.dataTables
+ *  plugin, released itself as GPLv2. As such, we believe this copyright is no
+ *  longer an issue and will try to upgrade to a later version of dataTables
+ *  in the near future. -- Yannick Warnier, Chamilo project leader, 2014-04
+ *  See https://support.chamilo.org/issues/7043
  *
  * ***************************************************************************
  * DESCRIPTION

+ 5 - 0
main/css/cool_blue/dataTable.css

@@ -9,6 +9,11 @@
  *  Project:      DataTables
  *
  *  Copyright 2009 Allan Jardine. All Rights Reserved.
+ *  Note: dataTable.css was later released as part of the jquery.dataTables
+ *  plugin, released itself as GPLv2. As such, we believe this copyright is no
+ *  longer an issue and will try to upgrade to a later version of dataTables
+ *  in the near future. -- Yannick Warnier, Chamilo project leader, 2014-04
+ *  See https://support.chamilo.org/issues/7043
  *
  * ***************************************************************************
  * DESCRIPTION

+ 5 - 0
main/css/corporate/dataTable.css

@@ -9,6 +9,11 @@
  *  Project:      DataTables
  *
  *  Copyright 2009 Allan Jardine. All Rights Reserved.
+ *  Note: dataTable.css was later released as part of the jquery.dataTables
+ *  plugin, released itself as GPLv2. As such, we believe this copyright is no
+ *  longer an issue and will try to upgrade to a later version of dataTables
+ *  in the near future. -- Yannick Warnier, Chamilo project leader, 2014-04
+ *  See https://support.chamilo.org/issues/7043
  *
  * ***************************************************************************
  * DESCRIPTION

+ 5 - 0
main/css/cosmic_campus/dataTable.css

@@ -9,6 +9,11 @@
  *  Project:      DataTables
  *
  *  Copyright 2009 Allan Jardine. All Rights Reserved.
+ *  Note: dataTable.css was later released as part of the jquery.dataTables
+ *  plugin, released itself as GPLv2. As such, we believe this copyright is no
+ *  longer an issue and will try to upgrade to a later version of dataTables
+ *  in the near future. -- Yannick Warnier, Chamilo project leader, 2014-04
+ *  See https://support.chamilo.org/issues/7043
  *
  * ***************************************************************************
  * DESCRIPTION

+ 5 - 0
main/css/delicious_bordeaux/dataTable.css

@@ -9,6 +9,11 @@
  *  Project:      DataTables
  *
  *  Copyright 2009 Allan Jardine. All Rights Reserved.
+ *  Note: dataTable.css was later released as part of the jquery.dataTables
+ *  plugin, released itself as GPLv2. As such, we believe this copyright is no
+ *  longer an issue and will try to upgrade to a later version of dataTables
+ *  in the near future. -- Yannick Warnier, Chamilo project leader, 2014-04
+ *  See https://support.chamilo.org/issues/7043
  *
  * ***************************************************************************
  * DESCRIPTION

+ 5 - 0
main/css/dokeos_blue/dataTable.css

@@ -9,6 +9,11 @@
  *  Project:      DataTables
  *
  *  Copyright 2009 Allan Jardine. All Rights Reserved.
+ *  Note: dataTable.css was later released as part of the jquery.dataTables
+ *  plugin, released itself as GPLv2. As such, we believe this copyright is no
+ *  longer an issue and will try to upgrade to a later version of dataTables
+ *  in the near future. -- Yannick Warnier, Chamilo project leader, 2014-04
+ *  See https://support.chamilo.org/issues/7043
  *
  * ***************************************************************************
  * DESCRIPTION

+ 5 - 0
main/css/dokeos_classic/dataTable.css

@@ -9,6 +9,11 @@
  *  Project:      DataTables
  *
  *  Copyright 2009 Allan Jardine. All Rights Reserved.
+ *  Note: dataTable.css was later released as part of the jquery.dataTables
+ *  plugin, released itself as GPLv2. As such, we believe this copyright is no
+ *  longer an issue and will try to upgrade to a later version of dataTables
+ *  in the near future. -- Yannick Warnier, Chamilo project leader, 2014-04
+ *  See https://support.chamilo.org/issues/7043
  *
  * ***************************************************************************
  * DESCRIPTION

+ 5 - 0
main/css/dokeos_classic_2D/dataTable.css

@@ -9,6 +9,11 @@
  *  Project:      DataTables
  *
  *  Copyright 2009 Allan Jardine. All Rights Reserved.
+ *  Note: dataTable.css was later released as part of the jquery.dataTables
+ *  plugin, released itself as GPLv2. As such, we believe this copyright is no
+ *  longer an issue and will try to upgrade to a later version of dataTables
+ *  in the near future. -- Yannick Warnier, Chamilo project leader, 2014-04
+ *  See https://support.chamilo.org/issues/7043
  *
  * ***************************************************************************
  * DESCRIPTION

+ 5 - 0
main/css/empire_green/dataTable.css

@@ -9,6 +9,11 @@
  *  Project:      DataTables
  *
  *  Copyright 2009 Allan Jardine. All Rights Reserved.
+ *  Note: dataTable.css was later released as part of the jquery.dataTables
+ *  plugin, released itself as GPLv2. As such, we believe this copyright is no
+ *  longer an issue and will try to upgrade to a later version of dataTables
+ *  in the near future. -- Yannick Warnier, Chamilo project leader, 2014-04
+ *  See https://support.chamilo.org/issues/7043
  *
  * ***************************************************************************
  * DESCRIPTION

+ 5 - 0
main/css/fruity_orange/dataTable.css

@@ -9,6 +9,11 @@
  *  Project:      DataTables
  *
  *  Copyright 2009 Allan Jardine. All Rights Reserved.
+ *  Note: dataTable.css was later released as part of the jquery.dataTables
+ *  plugin, released itself as GPLv2. As such, we believe this copyright is no
+ *  longer an issue and will try to upgrade to a later version of dataTables
+ *  in the near future. -- Yannick Warnier, Chamilo project leader, 2014-04
+ *  See https://support.chamilo.org/issues/7043
  *
  * ***************************************************************************
  * DESCRIPTION

+ 5 - 0
main/css/kiddy/dataTable.css

@@ -9,6 +9,11 @@
  *  Project:      DataTables
  *
  *  Copyright 2009 Allan Jardine. All Rights Reserved.
+ *  Note: dataTable.css was later released as part of the jquery.dataTables
+ *  plugin, released itself as GPLv2. As such, we believe this copyright is no
+ *  longer an issue and will try to upgrade to a later version of dataTables
+ *  in the near future. -- Yannick Warnier, Chamilo project leader, 2014-04
+ *  See https://support.chamilo.org/issues/7043
  *
  * ***************************************************************************
  * DESCRIPTION

+ 5 - 0
main/css/medical/dataTable.css

@@ -9,6 +9,11 @@
  *  Project:      DataTables
  *
  *  Copyright 2009 Allan Jardine. All Rights Reserved.
+ *  Note: dataTable.css was later released as part of the jquery.dataTables
+ *  plugin, released itself as GPLv2. As such, we believe this copyright is no
+ *  longer an issue and will try to upgrade to a later version of dataTables
+ *  in the near future. -- Yannick Warnier, Chamilo project leader, 2014-04
+ *  See https://support.chamilo.org/issues/7043
  *
  * ***************************************************************************
  * DESCRIPTION

+ 5 - 0
main/css/public_admin/dataTable.css

@@ -9,6 +9,11 @@
  *  Project:      DataTables
  *
  *  Copyright 2009 Allan Jardine. All Rights Reserved.
+ *  Note: dataTable.css was later released as part of the jquery.dataTables
+ *  plugin, released itself as GPLv2. As such, we believe this copyright is no
+ *  longer an issue and will try to upgrade to a later version of dataTables
+ *  in the near future. -- Yannick Warnier, Chamilo project leader, 2014-04
+ *  See https://support.chamilo.org/issues/7043
  *
  * ***************************************************************************
  * DESCRIPTION

+ 5 - 0
main/css/royal_purple/dataTable.css

@@ -9,6 +9,11 @@
  *  Project:      DataTables
  *
  *  Copyright 2009 Allan Jardine. All Rights Reserved.
+ *  Note: dataTable.css was later released as part of the jquery.dataTables
+ *  plugin, released itself as GPLv2. As such, we believe this copyright is no
+ *  longer an issue and will try to upgrade to a later version of dataTables
+ *  in the near future. -- Yannick Warnier, Chamilo project leader, 2014-04
+ *  See https://support.chamilo.org/issues/7043
  *
  * ***************************************************************************
  * DESCRIPTION

+ 5 - 0
main/css/silver_line/dataTable.css

@@ -9,6 +9,11 @@
  *  Project:      DataTables
  *
  *  Copyright 2009 Allan Jardine. All Rights Reserved.
+ *  Note: dataTable.css was later released as part of the jquery.dataTables
+ *  plugin, released itself as GPLv2. As such, we believe this copyright is no
+ *  longer an issue and will try to upgrade to a later version of dataTables
+ *  in the near future. -- Yannick Warnier, Chamilo project leader, 2014-04
+ *  See https://support.chamilo.org/issues/7043
  *
  * ***************************************************************************
  * DESCRIPTION

+ 5 - 0
main/css/sober_brown/dataTable.css

@@ -9,6 +9,11 @@
  *  Project:      DataTables
  *
  *  Copyright 2009 Allan Jardine. All Rights Reserved.
+ *  Note: dataTable.css was later released as part of the jquery.dataTables
+ *  plugin, released itself as GPLv2. As such, we believe this copyright is no
+ *  longer an issue and will try to upgrade to a later version of dataTables
+ *  in the near future. -- Yannick Warnier, Chamilo project leader, 2014-04
+ *  See https://support.chamilo.org/issues/7043
  *
  * ***************************************************************************
  * DESCRIPTION

+ 5 - 0
main/css/steel_grey/dataTable.css

@@ -9,6 +9,11 @@
  *  Project:      DataTables
  *
  *  Copyright 2009 Allan Jardine. All Rights Reserved.
+ *  Note: dataTable.css was later released as part of the jquery.dataTables
+ *  plugin, released itself as GPLv2. As such, we believe this copyright is no
+ *  longer an issue and will try to upgrade to a later version of dataTables
+ *  in the near future. -- Yannick Warnier, Chamilo project leader, 2014-04
+ *  See https://support.chamilo.org/issues/7043
  *
  * ***************************************************************************
  * DESCRIPTION

+ 5 - 0
main/css/tasty_olive/dataTable.css

@@ -9,6 +9,11 @@
  *  Project:      DataTables
  *
  *  Copyright 2009 Allan Jardine. All Rights Reserved.
+ *  Note: dataTable.css was later released as part of the jquery.dataTables
+ *  plugin, released itself as GPLv2. As such, we believe this copyright is no
+ *  longer an issue and will try to upgrade to a later version of dataTables
+ *  in the near future. -- Yannick Warnier, Chamilo project leader, 2014-04
+ *  See https://support.chamilo.org/issues/7043
  *
  * ***************************************************************************
  * DESCRIPTION

+ 3 - 2
main/document/create_document.php

@@ -301,7 +301,7 @@ if (isset($group_properties)) {
 }
 
 $select_cat = isset($_GET['selectcat']) ? intval($_GET['selectcat']) : null;
-
+$curDirPath = isset($_GET['curdirpath']) ? Security::remove_XSS($_GET['curdirpath']) : null;
 // Create a new form
 $form = new FormValidator(
     'create_document',
@@ -569,8 +569,9 @@ if ($form->validate()) {
                 if (!isset($df)) {
                     DocumentManager::attach_gradebook_certificate ($_course['code'],$document_id);
 				}
-				$certificate_condition = '&certificate=true';
+				$certificate_condition = '&certificate=true&curdirpath=/certificates';
 			}
+
 			header('Location: document.php?'.api_get_cidreq().'&id='.$folder_id.$selectcat.$certificate_condition);
 			exit();
 		} else {

+ 16 - 11
main/document/document.inc.php

@@ -476,9 +476,7 @@ function build_edit_icons($document_data, $id, $is_template, $is_read_only = 0,
         $req_gid = '';
     }
     $document_id = $document_data['id'];
-
     $type = $document_data['filetype'];
-
     $is_read_only = $document_data['readonly'];
     $path = $document_data['path'];
     $parent_id = DocumentManager::get_document_id(api_get_course_info(), dirname($path));
@@ -582,7 +580,8 @@ function build_edit_icons($document_data, $id, $is_template, $is_read_only = 0,
                 } else {
                     $tip_visibility = get_lang('Hide');
                 }
-                $modify_icons .= '&nbsp;<a href="' . api_get_self() . '?' . api_get_cidreq() . '&amp;id=' . $parent_id . '&amp;' . $visibility_command . '=' . $id . $req_gid . '&amp;' . $sort_params . '">' . Display::return_icon($visibility_icon . '.png', $tip_visibility, '', ICON_SIZE_SMALL) . '</a>';
+                $modify_icons .= '&nbsp;<a href="' . api_get_self() . '?' . api_get_cidreq() . '&amp;id=' . $parent_id . '&amp;' . $visibility_command . '=' . $id . $req_gid . '&amp;' . $sort_params . '">' .
+                    Display::return_icon($visibility_icon . '.png', $tip_visibility, '', ICON_SIZE_SMALL) . '</a>';
             }
         }
 
@@ -591,19 +590,23 @@ function build_edit_icons($document_data, $id, $is_template, $is_read_only = 0,
             $modify_icons .= '&nbsp;' . Display::return_icon('delete_na.png', get_lang('ThisFolderCannotBeDeleted'), array(), ICON_SIZE_SMALL);
         } else {
             if (isset($_GET['curdirpath']) && $_GET['curdirpath'] == '/certificates' && DocumentManager::get_default_certificate_id(api_get_course_id()) == $id) {
-                $modify_icons .= '&nbsp;<a href="' . api_get_self() . '?' . api_get_cidreq() . '&amp;curdirpath=' . $curdirpath . '&amp;deleteid=' . $document_id . $req_gid . '&amp;' . $sort_params . 'delete_certificate_id=' . $id . '" onclick="return confirmation(\'' . basename($path) . '\');">' . Display::return_icon('delete.png', get_lang('Delete'), array(), ICON_SIZE_SMALL) . '</a>';
+                $modify_icons .= '&nbsp;<a href="' . api_get_self() . '?' . api_get_cidreq() . '&amp;curdirpath=' . $curdirpath . '&action=delete_item&id='.$parent_id.'&deleteid='.$document_id.$req_gid.'&amp;' . $sort_params . 'delete_certificate_id=' . $id . '" onclick="return confirmation(\'' . basename($path) . '\');">' .
+                    Display::return_icon('delete.png', get_lang('Delete'), array(), ICON_SIZE_SMALL) . '</a>';
             } else {
                 if ($is_certificate_mode) {
-                    $modify_icons .= '&nbsp;<a href="' . api_get_self() . '?' . api_get_cidreq() . '&amp;curdirpath=' . $curdirpath . '&amp;deleteid=' . $document_id . $req_gid . '&amp;' . $sort_params . '" onclick="return confirmation(\'' . basename($path) . '\');">' . Display::return_icon('delete.png', get_lang('Delete'), array(), ICON_SIZE_SMALL) . '</a>';
+                    $modify_icons .= '&nbsp;<a href="' . api_get_self() . '?' . api_get_cidreq() . '&amp;curdirpath=' . $curdirpath . '&action=delete_item&id='.$parent_id.'&deleteid=' . $document_id . $req_gid . '&amp;' . $sort_params . '" onclick="return confirmation(\'' . basename($path) . '\');">' .
+                        Display::return_icon('delete.png', get_lang('Delete'), array(), ICON_SIZE_SMALL) . '</a>';
                 } else {
                     if (api_get_session_id()) {
                         if ($document_data['session_id'] == api_get_session_id()) {
-                            $modify_icons .= '&nbsp;<a href="' . api_get_self() . '?' . api_get_cidreq() . '&amp;curdirpath=' . $curdirpath . '&amp;deleteid=' . $document_id . $req_gid . '&amp;' . $sort_params . '" onclick="return confirmation(\'' . basename($path) . '\');">' . Display::return_icon('delete.png', get_lang('Delete'), array(), ICON_SIZE_SMALL) . '</a>';
+                            $modify_icons .= '&nbsp;<a href="' . api_get_self() . '?' . api_get_cidreq() . '&amp;curdirpath=' . $curdirpath . '&action=delete_item&id='.$parent_id.'&deleteid='.$document_id . $req_gid . '&amp;' . $sort_params . '" onclick="return confirmation(\'' . basename($path) . '\');">'.
+                                Display::return_icon('delete.png', get_lang('Delete'), array(), ICON_SIZE_SMALL) . '</a>';
                         } else {
                             $modify_icons .= '&nbsp;' . Display::return_icon('delete_na.png', get_lang('ThisFolderCannotBeDeleted'), array(), ICON_SIZE_SMALL);
                         }
                     } else {
-                        $modify_icons .= '&nbsp;<a href="' . api_get_self() . '?' . api_get_cidreq() . '&amp;curdirpath=' . $curdirpath . '&amp;deleteid=' . $document_id . $req_gid . '&amp;' . $sort_params . '" onclick="return confirmation(\'' . basename($path) . '\');">' . Display::return_icon('delete.png', get_lang('Delete'), array(), ICON_SIZE_SMALL) . '</a>';
+                        $modify_icons .= '&nbsp;<a href="' . api_get_self() . '?' . api_get_cidreq() . '&amp;curdirpath=' . $curdirpath . '&action=delete_item&id='.$parent_id.'&deleteid='.$document_id . $req_gid . '&amp;' . $sort_params . '" onclick="return confirmation(\'' . basename($path) . '\');">' .
+                            Display::return_icon('delete.png', get_lang('Delete'), array(), ICON_SIZE_SMALL) . '</a>';
                     }
                 }
             }
@@ -613,7 +616,8 @@ function build_edit_icons($document_data, $id, $is_template, $is_read_only = 0,
     if ($type == 'file' && ($extension == 'html' || $extension == 'htm')) {
         if ($is_template == 0) {
             if ((isset($_GET['curdirpath']) && $_GET['curdirpath'] != '/certificates') || !isset($_GET['curdirpath'])) {
-                $modify_icons .= '&nbsp;<a href="' . api_get_self() . '?' . api_get_cidreq() . '&amp;curdirpath=' . $curdirpath . '&amp;add_as_template=' . $id . $req_gid . '&amp;' . $sort_params . '">' . Display::return_icon('wizard.png', get_lang('AddAsTemplate'), array(), ICON_SIZE_SMALL) . '</a>';
+                $modify_icons .= '&nbsp;<a href="' . api_get_self() . '?' . api_get_cidreq() . '&amp;curdirpath=' . $curdirpath . '&amp;add_as_template=' . $id . $req_gid . '&amp;' . $sort_params . '">' .
+                    Display::return_icon('wizard.png', get_lang('AddAsTemplate'), array(), ICON_SIZE_SMALL) . '</a>';
             }
             if (isset($_GET['curdirpath']) && $_GET['curdirpath'] == '/certificates') {//allow attach certificate to course
                 $visibility_icon_certificate = 'nocertificate';
@@ -627,7 +631,8 @@ function build_edit_icons($document_data, $id, $is_template, $is_read_only = 0,
                     $certificate = get_lang('NoDefaultCertificate');
                 }
                 if (isset($_GET['selectcat'])) {
-                    $modify_icons .= '&nbsp;<a href="' . api_get_self() . '?' . api_get_cidreq() . '&amp;curdirpath=' . $curdirpath . '&amp;selectcat=' . Security::remove_XSS($_GET['selectcat']) . '&amp;set_certificate=' . $id . $req_gid . '&amp;' . $sort_params . '"><img src="../img/' . $visibility_icon_certificate . '.png" border="0" title="' . $certificate . '" alt="" /></a>';
+                    $modify_icons .= '&nbsp;<a href="' . api_get_self() . '?' . api_get_cidreq() . '&amp;curdirpath=' . $curdirpath . '&amp;selectcat=' . Security::remove_XSS($_GET['selectcat']) . '&amp;set_certificate=' . $id . $req_gid . '&amp;' . $sort_params . '">
+                    <img src="../img/' . $visibility_icon_certificate . '.png" border="0" title="' . $certificate . '" alt="" /></a>';
                     if ($is_preview) {
                         $modify_icons .= '&nbsp;<a target="_blank"  href="' . api_get_self() . '?' . api_get_cidreq() . '&amp;curdirpath=' . $curdirpath . '&amp;set_preview=' . $id . $req_gid . '&amp;' . $sort_params . '" >' .
                                 Display::return_icon('preview_view.png', $preview, '', ICON_SIZE_SMALL) . '</a>';
@@ -638,7 +643,8 @@ function build_edit_icons($document_data, $id, $is_template, $is_read_only = 0,
             $modify_icons .= '&nbsp;<a href="' . api_get_self() . '?' . api_get_cidreq() . '&curdirpath=' . $curdirpath . '&amp;remove_as_template=' . $id . $req_gid . '&amp;' . $sort_params . '">' .
                     Display::return_icon('wizard_na.png', get_lang('RemoveAsTemplate'), '', ICON_SIZE_SMALL) . '</a>';
         }
-        $modify_icons .= '&nbsp;<a href="' . api_get_self() . '?' . api_get_cidreq() . '&action=export_to_pdf&id=' . $id . '">' . Display::return_icon('pdf.png', get_lang('Export2PDF'), array(), ICON_SIZE_SMALL) . '</a>';
+        $modify_icons .= '&nbsp;<a href="' . api_get_self() . '?' . api_get_cidreq() . '&action=export_to_pdf&id=' . $id . '">' .
+            Display::return_icon('pdf.png', get_lang('Export2PDF'), array(), ICON_SIZE_SMALL) . '</a>';
     }
     return $modify_icons;
 }
@@ -771,7 +777,6 @@ function display_user_link_document($user_id, $name) {
  */
 function create_dir_form($current_dir_id) {
     global $document_id;
-
     $form = new FormValidator('create_dir_form', 'post', api_get_self().'?'.api_get_cidreq(), '', null, false);
     $form->addElement('hidden', 'create_dir', 1);
     $form->addElement('hidden', 'dir_id', intval($document_id));

Dosya farkı çok büyük olduğundan ihmal edildi
+ 411 - 173
main/document/document.php


+ 3 - 4
main/document/upload.php

@@ -202,10 +202,10 @@ if (!empty($_FILES)) {
 echo '<div class="actions">';
 // Link back to the documents overview
 if ($is_certificate_mode) {
-    echo '<a href="document.php?id='.$document_id.'&selectcat=' . $selectcat.'">'.
+    echo '<a href="document.php?id='.$document_id.'&selectcat=' . $selectcat.'&'.api_get_cidreq().'">'.
             Display::return_icon('back.png',get_lang('BackTo').' '.get_lang('CertificateOverview'),'',ICON_SIZE_MEDIUM).'</a>';
 } else {
-    echo '<a href="document.php?id='.$document_id.'">'.
+    echo '<a href="document.php?id='.$document_id.'&'.api_get_cidreq().'">'.
             Display::return_icon('back.png',get_lang('BackTo').' '.get_lang('DocumentsOverview'),'',ICON_SIZE_MEDIUM).'</a>';
 }
 
@@ -258,8 +258,7 @@ if (api_get_setting('search_enabled') == 'true') {
 
 $form->addElement('radio', 'if_exists', get_lang('UplWhatIfFileExists'), get_lang('UplDoNothing'), 'nothing');
 $form->addElement('radio', 'if_exists', '', get_lang('UplOverwriteLong'), 'overwrite');
-$form->addElement('radio', 'if_exists', '', get_lang('UplRenameLong'), 'rename');
-
+$form->addElement('radio', 'if_exists', '', get_lang('UplRenameLong'), 'rename', array('checked="checked"'));
 // Close the java script and avoid the footer up
 $form->addElement('html', '</div>');
 

+ 3 - 3
main/exercice/admin.php

@@ -451,7 +451,7 @@ $inATest = isset($exerciseId) && $exerciseId > 0;
 if ($inATest) {
     echo '<div class="actions">';
     if (isset($_GET['hotspotadmin']) || isset($_GET['newQuestion']) || isset($_GET['myid']))
-        echo '<a href="admin.php?exerciseId='.$exerciseId.'">'.Display::return_icon('back.png', get_lang('GoBackToQuestionList'),'',ICON_SIZE_MEDIUM).'</a>';
+        echo '<a href="admin.php?exerciseId='.$exerciseId.'&'.api_get_cidReq().'">'.Display::return_icon('back.png', get_lang('GoBackToQuestionList'),'',ICON_SIZE_MEDIUM).'</a>';
 
     if (!isset($_GET['hotspotadmin']) && !isset($_GET['newQuestion']) && !isset($_GET['myid']) &&  !isset($_GET['editQuestion'])) {
         echo '<a href="exercice.php?'.api_get_cidReq().'">'.Display::return_icon('back.png', get_lang('BackToExercisesList'),'',ICON_SIZE_MEDIUM).'</a>';
@@ -499,11 +499,11 @@ if ($newQuestion || $editQuestion) {
 	// statement management
 	$type = Security::remove_XSS($_REQUEST['answerType']);
 	echo '<input type="hidden" name="Type" value="'.$type.'" />';
-        
+
         if ($newQuestion == 'yes') {
             $objExercise->edit_exercise_in_lp = true;
         }
-        
+
 	require 'question_admin.inc.php';
 }
 

+ 45 - 21
main/exercice/exercise.class.php

@@ -3387,12 +3387,12 @@ class Exercise {
                         </tr>
                     </table>';
         $open_question_list = null;
-        
-        $msg    = str_replace("#email#",       $user_info['email'],$msg);       
+
+        $msg    = str_replace("#email#",       $user_info['email'],$msg);
         $msg1   = str_replace("#exercise#",    $this->exercise, $msg);
         $msg    = str_replace("#firstName#",   $user_info['firstname'],$msg1);
         $msg1   = str_replace("#lastName#",    $user_info['lastname'],$msg);
-        
+
         $msg    = str_replace("#course#",      $courseInfo['name'],$msg1);
 
         if ($origin != 'learnpath') {
@@ -3402,20 +3402,20 @@ class Exercise {
         $msg1 = str_replace("#url#", $url_email, $msg);
         $mail_content = $msg1;
         $subject = get_lang('ExerciseAttempted');
-         
+
         $teachers = array();
         if (api_get_session_id()) {
             $teachers = CourseManager::get_coach_list_from_course_code($coursecode, api_get_session_id());
         } else {
             $teachers = CourseManager::get_teacher_list_from_course_code($coursecode);
         }
-         
+
         if (!empty($teachers)) {
             foreach ($teachers as $user_id => $teacher_data) {
                 MessageManager::send_message_simple($user_id, $subject, $mail_content);
             }
         }
-        
+
     }
 
     /**
@@ -3628,22 +3628,35 @@ class Exercise {
      * @todo this was function was added due the import exercise via CSV
      * @return    int New exercise ID
      */
-    function create_quiz ($title, $expired_time = 0, $type = 2, $random = 0, $active = 1, $results_disabled = 0, $max_attempt = 0, $feedback = 3) {
+    public function createExercise(
+        $title,
+        $expired_time = 0,
+        $type = 2,
+        $random = 0,
+        $active = 1,
+        $results_disabled = 0,
+        $max_attempt = 0,
+        $feedback = 3,
+        $propagateNegative = 0
+    ) {
         $tbl_quiz = Database::get_course_table(TABLE_QUIZ_TEST);
-        $expired_time = filter_var($expired_time,FILTER_SANITIZE_NUMBER_INT);
-        $type = filter_var($type,FILTER_SANITIZE_NUMBER_INT);
-        $random = filter_var($random,FILTER_SANITIZE_NUMBER_INT);
-        $active = filter_var($active,FILTER_SANITIZE_NUMBER_INT);
-        $results_disabled = filter_var($results_disabled,FILTER_SANITIZE_NUMBER_INT);
-        $max_attempt = filter_var($max_attempt,FILTER_SANITIZE_NUMBER_INT);
-        $feedback = filter_var($feedback,FILTER_SANITIZE_NUMBER_INT);
-        $sid = api_get_session_id();
+        $type = intval($type);
+        $random = intval($random);
+        $active = intval($active);
+        $results_disabled = intval($results_disabled);
+        $max_attempt = intval($max_attempt);
+        $feedback = intval($feedback);
+        $expired_time = intval($expired_time);
+        $title = Database::escape_string($title);
+        $propagateNegative = intval($propagateNegative);
+        $sessionId = api_get_session_id();
         $course_id = api_get_course_int_id();
         // Save a new quiz
-        $sql = "INSERT INTO $tbl_quiz (c_id, title,type,random,active,results_disabled, max_attempt,start_time,end_time,feedback_type,expired_time, session_id) ".
-            " VALUES('$course_id', '".Database::escape_string($title)."',$type,$random,$active, $results_disabled,$max_attempt,'','',$feedback,$expired_time,$sid)";
-        $rs = Database::query($sql);
-        $quiz_id = Database::get_last_insert_id();
+        $sql = "INSERT INTO $tbl_quiz (c_id, title, type, random, active, results_disabled, max_attempt, start_time,end_time,feedback_type,expired_time, session_id, propagate_neg) ".
+            " VALUES('$course_id', '".$title."', $type, $random, $active, $results_disabled, $max_attempt,'','', $feedback, $expired_time, $sessionId, $propagateNegative)";
+        Database::query($sql);
+        $quiz_id = Database::insert_id();
+
         return $quiz_id;
     }
 
@@ -3660,15 +3673,26 @@ class Exercise {
     public function get_exercise_result($exe_id) {
         $result = array();
         $track_exercise_info = get_exercise_track_exercise_info($exe_id);
+
         if (!empty($track_exercise_info)) {
+            $totalScore = 0;
             $objExercise = new Exercise();
             $objExercise->read($track_exercise_info['exe_exo_id']);
             if (!empty($track_exercise_info['data_tracking'])) {
                 $question_list = explode(',', $track_exercise_info['data_tracking']);
             }
             foreach ($question_list as $questionId) {
-                $question_result = $objExercise->manage_answer($exe_id, $questionId, '','exercise_show', array(), false, true, false, $objExercise->selectPropagateNeg());
-                $questionScore   = $question_result['score'];
+                $question_result = $objExercise->manage_answer(
+                    $exe_id,
+                    $questionId,
+                    '',
+                    'exercise_show',
+                    array(),
+                    false,
+                    true,
+                    false,
+                    $objExercise->selectPropagateNeg()
+                );
                 $totalScore      += $question_result['score'];
             }
 

+ 2 - 0
main/exercice/exercise.lib.php

@@ -2383,6 +2383,8 @@ function display_question_list_by_attempt($objExercise, $exe_id, $save_user_resu
     if ($show_all_but_expected_answer) {
         $exercise_content .= "<div class='normal-message'>".get_lang("ExerciseWithFeedbackWithoutCorrectionComment")."</div>";
     }
+    // Remove audio autoplay from questions on results page - refs BT#7939
+    $exercise_content = preg_replace('/autoplay[\=\".+\"]+/','',$exercise_content);
 
     echo $total_score_text;
     echo $exercise_content;

+ 1 - 0
main/exercice/exercise_result.php

@@ -179,6 +179,7 @@ if ($origin != 'learnpath') {
         Session::erase('objExercise');
         Session::erase('exe_id');
     }
+
 	//record the results in the learning path, using the SCORM interface (API)
 	echo "<script>window.parent.API.void_save_asset('$total_score', '$total_weight', 0, 'completed');</script>";
     echo '<script type="text/javascript">'.$href.'</script>';

+ 38 - 31
main/exercice/export/exercise_import.inc.php

@@ -31,35 +31,39 @@ function tempdir($dir, $prefix = 'tmp', $mode = 0777) {
 }
 
 /**
- * @return the path of the temporary directory where the exercise was uploaded and unzipped
+ * the path of the temporary directory where the exercise was uploaded and unzipped
+ * @param string
+ * @param string
+ * @return bool
  */
 
-function get_and_unzip_uploaded_exercise($baseWorkDir, $uploadPath) {
-	global $_course, $_user;
+function get_and_unzip_uploaded_exercise($baseWorkDir, $uploadPath)
+{
+    $_course = api_get_course_info();
+    $_user = api_get_user_info();
+
 	//Check if the file is valid (not to big and exists)
-	if (!isset ($_FILES['userFile']) || !is_uploaded_file($_FILES['userFile']['tmp_name'])) {
+	if (!isset($_FILES['userFile']) || !is_uploaded_file($_FILES['userFile']['tmp_name'])) {
 		// upload failed
 		return false;
-	}	
-	if (preg_match('/.zip$/i', $_FILES['userFile']['name']) && handle_uploaded_document($_course, $_FILES['userFile'], $baseWorkDir, $uploadPath, $_user['user_id'], 0, null, 1)) {
-		if (!function_exists('gzopen')) {			
-			//claro_delete_file($uploadPath);
-			return false;
-		}
-		// upload successfull
+	}
+
+	if (preg_match('/.zip$/i', $_FILES['userFile']['name']) &&
+        handle_uploaded_document($_course, $_FILES['userFile'], $baseWorkDir, $uploadPath, $_user['user_id'], 0, null, 1)
+    ) {
 		return true;
-	} else {
-		//claro_delete_file($uploadPath);
-		return false;
 	}
+    return false;
 }
+
 /**
  * main function to import an exercise,
- *
+ * @param array $file
  * @return an array as a backlog of what was really imported, and error or debug messages to display
  */
 
-function import_exercise($file) {
+function import_exercise($file)
+{
 	global $exercise_info;
 	global $element_pile;
 	global $non_HTML_tag_to_avoid;
@@ -99,15 +103,17 @@ function import_exercise($file) {
 	}
 
 	// find the different manifests for each question and parse them.
+
 	$exerciseHandle = opendir($baseWorkDir);
 	//$question_number = 0;
 	$file_found = false;
 	$operation = false;
     $result = false;
+
 	// parse every subdirectory to search xml question files
 	while (false !== ($file = readdir($exerciseHandle))) {
 		if (is_dir($baseWorkDir . '/' . $file) && $file != "." && $file != "..") {
-			//find each manifest for each question repository found
+			// Find each manifest for each question repository found
 			$questionHandle = opendir($baseWorkDir . '/' . $file);
 			while (false !== ($questionFile = readdir($questionHandle))) {
 				if (preg_match('/.xml$/i', $questionFile)) {
@@ -120,11 +126,12 @@ function import_exercise($file) {
 			$file_found = true;
 		} // else ignore file
 	}
+
 	if (!$file_found) {
-		Display :: display_error_message(get_lang('No XML file found in the zip'));        
+		Display :: display_error_message(get_lang('No XML file found in the zip'));
 		return false;
 	}
-    if ($result == false ) {        
+    if ($result == false ) {
         return false;
     }
 
@@ -133,7 +140,7 @@ function import_exercise($file) {
 	//1.create exercise
 	$exercise = new Exercise();
 	$exercise->exercise = $exercise_info['name'];
-    
+
 	$exercise->save();
 	$last_exercise_id = $exercise->selectId();
 	if (!empty($last_exercise_id)) {
@@ -170,11 +177,12 @@ function import_exercise($file) {
 		// delete the temp dir where the exercise was unzipped
 		my_delete($baseWorkDir . $uploadPath);
 		$operation = true;
-	}    
+	}
 	return $operation;
 }
 
-function parse_file($exercisePath, $file, $questionFile) {
+function parse_file($exercisePath, $file, $questionFile)
+{
 	global $exercise_info;
 	global $element_pile;
 	global $non_HTML_tag_to_avoid;
@@ -183,8 +191,7 @@ function parse_file($exercisePath, $file, $questionFile) {
 
 	$questionTempDir = $exercisePath . '/' . $file . '/';
 	$questionFilePath = $questionTempDir . $questionFile;
-
-	if (!($fp = @ fopen($questionFilePath, 'r'))) {
+	if (!($fp = fopen($questionFilePath, 'r'))) {
 		Display :: display_error_message(get_lang('Error opening question\'s XML file'));
 		return false;
 	} else {
@@ -193,7 +200,7 @@ function parse_file($exercisePath, $file, $questionFile) {
 
 	//parse XML question file
 	$data = str_replace(array('<p>', '</p>','<front>','</front>'), '', $data);
-	
+
 	//used global variable start values declaration :
 
 	$record_item_body = false;
@@ -412,12 +419,12 @@ function startElement($parser, $name, $attributes) {
 			//retrieve answers id for MCUA and MCMA questions
 
 		case 'SIMPLECHOICE' :
-			
+
             $current_answer_id = $attributes['IDENTIFIER'];
             if (!isset($exercise_info['question'][$current_question_ident]['answer'][$current_answer_id])) {
                 $exercise_info['question'][$current_question_ident]['answer'][$current_answer_id] = array ();
             }
-			
+
 			break;
 
 		case 'MAPENTRY' :
@@ -524,15 +531,15 @@ function elementData($parser, $data) {
 	if ($record_item_body && (!in_array($current_element, $non_HTML_tag_to_avoid))) {
 		$current_question_item_body .= $data;
 	}
-    
+
 	switch ($current_element) {
 		case 'SIMPLECHOICE' :
-			
+
 				if (!isset ($exercise_info['question'][$current_question_ident]['answer'][$current_answer_id]['value'])) {
 					$exercise_info['question'][$current_question_ident]['answer'][$current_answer_id]['value'] = trim($data);
 				} else {
 					$exercise_info['question'][$current_question_ident]['answer'][$current_answer_id]['value'] .= ''.trim($data);
-				}    		
+				}
 			break;
 
 		case 'FEEDBACKINLINE' :
@@ -590,4 +597,4 @@ function elementData($parser, $data) {
 			}
 			break;
 	}
-}
+}

+ 12 - 14
main/exercice/matching.class.php

@@ -12,7 +12,6 @@
 /**
  * Code
  */
-if(!class_exists('Matching')):
 /**
  * Matching questions type class
  * @package chamilo.exercise
@@ -101,9 +100,9 @@ class Matching extends Question {
 							'.get_lang('Weighting').'
 						</th>
 					</tr>';
-        
+
 		$form -> addElement ('label', get_lang('MakeCorrespond').'<br /> <img src="../img/fill_field.png">', $html);
-		
+
 		if ($nb_matches < 1) {
 			$nb_matches = 1;
 			Display::display_normal_message(get_lang('YouHaveToCreateAtLeastOneAnswer'));
@@ -125,13 +124,13 @@ class Matching extends Question {
 
 		$form -> addElement ('html', '</table></div></div>');
 		$group = array();
-		
+
 		if ($navigator_info['name']=='Internet Explorer' &&  $navigator_info['version']=='6') {
 			$group[] = $form->createElement('submit', 'lessMatches', get_lang('DelElem'),'class="btn minus"');
 			$group[] = $form->createElement('submit', 'moreMatches', get_lang('AddElem'),'class="btn plus"');
 		} else {
             $group[] = $form->createElement('style_submit_button', 'moreMatches', get_lang('AddElem'),'class="btn plus"');
-			$group[] = $form->createElement('style_submit_button', 'lessMatches', get_lang('DelElem'),'class="btn minus"');			
+			$group[] = $form->createElement('style_submit_button', 'lessMatches', get_lang('DelElem'),'class="btn minus"');
 		}
 
 		$form -> addGroup($group);
@@ -171,18 +170,18 @@ class Matching extends Question {
 
 		if ($navigator_info['name']=='Internet Explorer' &&  $navigator_info['version']=='6') {
             // setting the save button here and not in the question class.php
-            $group[] = $form->createElement('submit','submitQuestion',$text, 'class="'.$class.'"');            
+            $group[] = $form->createElement('submit','submitQuestion',$text, 'class="'.$class.'"');
             $group[] = $form->createElement('submit', 'lessOptions', get_lang('DelElem'),'class="minus"');
-            $group[] = $form->createElement('submit', 'moreOptions',get_lang('AddElem'),'class="plus"');			
+            $group[] = $form->createElement('submit', 'moreOptions',get_lang('AddElem'),'class="plus"');
 		} else {
-            // setting the save button here and not in the question class.php            
+            // setting the save button here and not in the question class.php
             $group[] = $form->createElement('style_submit_button', 'lessOptions', get_lang('DelElem'),'class="minus"');
             $group[] = $form->createElement('style_submit_button', 'moreOptions',get_lang('AddElem'),' class="plus"');
             $group[] = $form->createElement('style_submit_button','submitQuestion',$text, 'class="'.$class.'"');
 		}
-		
+
 		$form -> addGroup($group);
-		
+
 		if (!empty($this -> id)) {
 			$form -> setDefaults($defaults);
 		} else {
@@ -190,7 +189,7 @@ class Matching extends Question {
 				$form -> setDefaults($defaults);
 			}
 		}
-		
+
 		$form->setConstants(array('nb_matches' => $nb_matches,'nb_options' => $nb_options));
 	}
 
@@ -227,10 +226,10 @@ class Matching extends Question {
 		$objAnswer->save();
 		$this->save();
 	}
-	
+
 	function return_header($feedback_type = null, $counter = null, $score = null) {
 	    $header = parent::return_header($feedback_type, $counter, $score);
-        $header .= '<table class="'.$this->question_table_class .'">';            
+        $header .= '<table class="'.$this->question_table_class .'">';
         $header .= '<tr>
                 <th>'.get_lang('ElementList').'</th>
                 <th>'.get_lang('CorrespondsTo').'</th>
@@ -238,4 +237,3 @@ class Matching extends Question {
         return $header;
 	}
 }
-endif;

+ 11 - 14
main/exercice/multiple_answer.class.php

@@ -8,8 +8,6 @@
 /**
  * Code
  */
-if(!class_exists('MultipleAnswer')):
-
 /**
 	CLASS MultipleAnswer
  *
@@ -103,12 +101,12 @@ class MultipleAnswer extends Question {
 				$defaults['weighting[2]'] = -5;
 			}
 			$renderer = & $form->defaultRenderer();
-			            
-            $renderer->setElementTemplate('<td><!-- BEGIN error --><span class="form_error">{error}</span><!-- END error --><br/>{element}</td>', 'correct['.$i.']');  
-            $renderer->setElementTemplate('<td><!-- BEGIN error --><span class="form_error">{error}</span><!-- END error --><br/>{element}</td>', 'counter['.$i.']');  
-            $renderer->setElementTemplate('<td><!-- BEGIN error --><span class="form_error">{error}</span><!-- END error --><br/>{element}</td>', 'answer['.$i.']');  
-            $renderer->setElementTemplate('<td><!-- BEGIN error --><span class="form_error">{error}</span><!-- END error --><br/>{element}</td>', 'comment['.$i.']');  
-            $renderer->setElementTemplate('<td><!-- BEGIN error --><span class="form_error">{error}</span><!-- END error --><br/>{element}</td>', 'weighting['.$i.']');        
+
+            $renderer->setElementTemplate('<td><!-- BEGIN error --><span class="form_error">{error}</span><!-- END error --><br/>{element}</td>', 'correct['.$i.']');
+            $renderer->setElementTemplate('<td><!-- BEGIN error --><span class="form_error">{error}</span><!-- END error --><br/>{element}</td>', 'counter['.$i.']');
+            $renderer->setElementTemplate('<td><!-- BEGIN error --><span class="form_error">{error}</span><!-- END error --><br/>{element}</td>', 'answer['.$i.']');
+            $renderer->setElementTemplate('<td><!-- BEGIN error --><span class="form_error">{error}</span><!-- END error --><br/>{element}</td>', 'comment['.$i.']');
+            $renderer->setElementTemplate('<td><!-- BEGIN error --><span class="form_error">{error}</span><!-- END error --><br/>{element}</td>', 'weighting['.$i.']');
 
 			$answer_number=$form->addElement('text', 'counter['.$i.']', null, 'value="'.$i.'"');
 			$answer_number->freeze();
@@ -137,13 +135,13 @@ class MultipleAnswer extends Question {
 			//ie6 fix
 			if ($navigator_info['name']=='Internet Explorer' &&  $navigator_info['version']=='6') {
                 $form->addElement('submit', 'lessAnswers', get_lang('LessAnswer'),'class="btn minus"');
-                $form->addElement('submit', 'moreAnswers', get_lang('PlusAnswer'),'class="btn plus"');				
+                $form->addElement('submit', 'moreAnswers', get_lang('PlusAnswer'),'class="btn plus"');
                 $form->addElement('submit','submitQuestion',$text, 'class="'.$class.'"');
 			} else {
-                // setting the save button here and not in the question class.php                
+                // setting the save button here and not in the question class.php
                 $form->addElement('style_submit_button', 'lessAnswers', get_lang('LessAnswer'),'class="btn minus"');
                 $form->addElement('style_submit_button', 'moreAnswers', get_lang('PlusAnswer'),'class="btn plus"');
-                $form->addElement('style_submit_button','submitQuestion',$text, 'class="'.$class.'"');				
+                $form->addElement('style_submit_button','submitQuestion',$text, 'class="'.$class.'"');
 			}
 		}
 		$renderer->setElementTemplate('{element}&nbsp;','lessAnswers');
@@ -200,10 +198,10 @@ class MultipleAnswer extends Question {
         $this->updateWeighting($questionWeighting);
         $this->save();
 	}
-	
+
 	function return_header($feedback_type = null, $counter = null, $score = null) {
 	    $header = parent::return_header($feedback_type, $counter, $score);
-	    $header .= '<table class="'.$this->question_table_class .'">			
+	    $header .= '<table class="'.$this->question_table_class .'">
 			<tr>
 				<th>'.get_lang("Choice").'</th>
 				<th>'. get_lang("ExpectedChoice").'</th>
@@ -213,4 +211,3 @@ class MultipleAnswer extends Question {
         return $header;
 	}
 }
-endif;

+ 25 - 27
main/exercice/multiple_answer_combination.class.php

@@ -9,8 +9,6 @@
 /**
  * Code
  */
-if(class_exists('MultipleAnswerCombination')) { return true; }
-
 /**
 	CLASS MultipleAnswer
  *
@@ -54,8 +52,8 @@ class MultipleAnswerCombination extends Question {
 						</th>
 						<th width="50%">
 							'.get_lang('Answer').'
-						</th>';				
-						// show column comment when feedback is enable						
+						</th>';
+						// show column comment when feedback is enable
                         $html .='<th>'.get_lang('Comment').'</th>';
 						$html .= '</tr>';
         $form -> addElement ('label', get_lang('Answers').'<br /> <img src="../img/fill_field.png">', $html);
@@ -72,11 +70,11 @@ class MultipleAnswerCombination extends Question {
 
 		$form -> addElement('hidden', 'nb_answers');
 		$boxes_names = array();
-		
+
 		if ($nb_answers < 1) {
 			$nb_answers = 1;
 			Display::display_normal_message(get_lang('YouHaveToCreateAtLeastOneAnswer'));
-		}		
+		}
 
 		for($i = 1 ; $i <= $nb_answers ; ++$i) {
 			if(is_object($answer)) {
@@ -92,15 +90,15 @@ class MultipleAnswerCombination extends Question {
 
 				$defaults['answer[2]']  = get_lang('DefaultMultipleAnswer1');
 				$defaults['comment[2]'] = get_lang('DefaultMultipleComment1');
-				$defaults['correct[2]'] = false;				
+				$defaults['correct[2]'] = false;
 			}
 			$renderer = & $form->defaultRenderer();
-			
-            $renderer->setElementTemplate('<td><!-- BEGIN error --><span class="form_error">{error}</span><!-- END error --><br/>{element}</td>', 'correct['.$i.']');  
-            $renderer->setElementTemplate('<td><!-- BEGIN error --><span class="form_error">{error}</span><!-- END error --><br/>{element}</td>', 'counter['.$i.']');  
-            $renderer->setElementTemplate('<td><!-- BEGIN error --><span class="form_error">{error}</span><!-- END error --><br/>{element}</td>', 'answer['.$i.']');  
-            $renderer->setElementTemplate('<td><!-- BEGIN error --><span class="form_error">{error}</span><!-- END error --><br/>{element}</td>', 'comment['.$i.']');  
-                    
+
+            $renderer->setElementTemplate('<td><!-- BEGIN error --><span class="form_error">{error}</span><!-- END error --><br/>{element}</td>', 'correct['.$i.']');
+            $renderer->setElementTemplate('<td><!-- BEGIN error --><span class="form_error">{error}</span><!-- END error --><br/>{element}</td>', 'counter['.$i.']');
+            $renderer->setElementTemplate('<td><!-- BEGIN error --><span class="form_error">{error}</span><!-- END error --><br/>{element}</td>', 'answer['.$i.']');
+            $renderer->setElementTemplate('<td><!-- BEGIN error --><span class="form_error">{error}</span><!-- END error --><br/>{element}</td>', 'comment['.$i.']');
+
 
 			$answer_number=$form->addElement('text', 'counter['.$i.']', null,'value="'.$i.'"');
 			$answer_number->freeze();
@@ -110,38 +108,38 @@ class MultipleAnswerCombination extends Question {
 
 			$form->addElement('html_editor', 'answer['.$i.']',null, 'style="vertical-align:middle"', array('ToolbarSet' => 'TestProposedAnswer', 'Width' => '100%', 'Height' => '100'));
 			$form->addRule('answer['.$i.']', get_lang('ThisFieldIsRequired'), 'required');
-			
+
             $form->addElement('html_editor', 'comment['.$i.']',null, 'style="vertical-align:middle"', array('ToolbarSet' => 'TestProposedAnswer', 'Width' => '100%', 'Height' => '100'));
 			//only 1 answer the all deal ...
 			//$form->addElement('text', 'weighting['.$i.']',null, 'style="vertical-align:middle;margin-left: 0em;" size="5" value="10"');
-				
+
 			$form -> addElement ('html', '</tr>');
 		}
 		$form -> addElement ('html', '</table>');
 		$form -> addElement ('html', '<br />');
 
-		$form -> add_multiple_required_rule ($boxes_names , get_lang('ChooseAtLeastOneCheckbox') , 'multiple_required');		
-						
+		$form -> add_multiple_required_rule ($boxes_names , get_lang('ChooseAtLeastOneCheckbox') , 'multiple_required');
+
 		//only 1 answer the all deal ...
 		$form->addElement('text', 'weighting[1]', get_lang('Score'), array('class' => "span1", 'value' => '10'));
-				
+
 		$navigator_info = api_get_navigator();
 		global $text, $class;
 		//ie6 fix
 		if ($obj_ex->edit_exercise_in_lp == true) {
 			if ($navigator_info['name']=='Internet Explorer' &&  $navigator_info['version']=='6') {
-                
+
                 $form->addElement('submit', 'lessAnswers', get_lang('LessAnswer'),'class="btn minus"');
                 $form->addElement('submit', 'moreAnswers', get_lang('PlusAnswer'),'class="btn plus"');
-                $form->addElement('submit', 'submitQuestion', $text, 'class="'.$class.'"');				
+                $form->addElement('submit', 'submitQuestion', $text, 'class="'.$class.'"');
 			} else {
-                
+
                 $form->addElement('style_submit_button', 'lessAnswers', get_lang('LessAnswer'),'class="btn minus"');
                 $form->addElement('style_submit_button', 'moreAnswers', get_lang('PlusAnswer'),'class="btn plus"');
                 $form->addElement('style_submit_button', 'submitQuestion',$text, 'class="'.$class.'"');
-				
+
 				// setting the save button here and not in the question class.php
-				
+
 			}
 		}
 		$renderer->setElementTemplate('{element}&nbsp;','lessAnswers');
@@ -172,7 +170,7 @@ class MultipleAnswerCombination extends Question {
 		$objAnswer = new Answer($this->id);
 
 		$nb_answers = $form -> getSubmitValue('nb_answers');
-		
+
 		for($i=1 ; $i <= $nb_answers ; $i++)
         {
         	$answer = trim($form -> getSubmitValue('answer['.$i.']'));
@@ -204,16 +202,16 @@ class MultipleAnswerCombination extends Question {
         $this -> updateWeighting($questionWeighting);
         $this -> save();
 	}
-	
+
 	function return_header($feedback_type = null, $counter = null, $score = null) {
 	    $header = parent::return_header($feedback_type, $counter, $score);
-	    $header .= '<table class="'.$this->question_table_class .'">			
+	    $header .= '<table class="'.$this->question_table_class .'">
 			<tr>
 				<th>'.get_lang("Choice").'</th>
 				<th>'. get_lang("ExpectedChoice").'</th>
 				<th>'. get_lang("Answer").'</i></th>';
         $header .= '<th>'.get_lang("Comment").'</th>';
         $header .= '</tr>';
-        return $header;	  
+        return $header;
 	}
 }

+ 5 - 6
main/exercice/multiple_answer_combination_true_false.class.php

@@ -9,8 +9,6 @@
 /**
  * Code
  */
-if(class_exists('MultipleAnswerCombinationTrueFalse')) { return true; }
-require_once 'multiple_answer_combination.class.php';
 /**
 	CLASS MultipleAnswer
  *
@@ -20,16 +18,17 @@ require_once 'multiple_answer_combination.class.php';
  *	@author Eric Marguin
  *	@package chamilo.exercise
  **/
-class MultipleAnswerCombinationTrueFalse extends MultipleAnswerCombination {
-
+class MultipleAnswerCombinationTrueFalse extends MultipleAnswerCombination
+{
 	static $typePicture = 'mcmaco.gif';
 	static $explanationLangVar = 'MultipleAnswerCombinationTrueFalse';
-    var    $options; 
+    var    $options;
 
 	/**
 	 * Constructor
 	 */
-	function MultipleAnswerCombinationTrueFalse(){
+	function MultipleAnswerCombinationTrueFalse()
+    {
 		parent::question();
 		$this -> type = MULTIPLE_ANSWER_COMBINATION_TRUE_FALSE;
 		$this -> isContent = $this-> getIsContent();

+ 83 - 85
main/exercice/multiple_answer_true_false.class.php

@@ -11,7 +11,6 @@
 /**
  * Code
  */
-if(!class_exists('MultipleAnswerTrueFalse')):
 /**
  * Class
  * @package chamilo.exercise
@@ -40,15 +39,15 @@ class MultipleAnswerTrueFalse extends Question {
 
 		$nb_answers  = isset($_POST['nb_answers']) ? $_POST['nb_answers'] : 4;  // The previous default value was 2. See task #1759.
 		$nb_answers += (isset($_POST['lessAnswers']) ? -1 : (isset($_POST['moreAnswers']) ? 1 : 0));
-        
+
         $course_id = api_get_course_int_id();
 
 		$obj_ex = $_SESSION['objExercise'];
-                
+
         $renderer = & $form->defaultRenderer();
-               
+
         $defaults = array();
-               
+
 		$html = '<table class="data_table">
 					<tr style="text-align: center;">
 						<th>
@@ -59,7 +58,7 @@ class MultipleAnswerTrueFalse extends Question {
 						</th>
                         <th>
                             '.get_lang('False').'
-                        </th>     
+                        </th>
 						<th>
 							'.get_lang('Answer').'
 						</th>';
@@ -69,16 +68,16 @@ class MultipleAnswerTrueFalse extends Question {
         }
         $html .= '</tr>';
         $form -> addElement ('label', get_lang('Answers').'<br /> <img src="../img/fill_field.png">', $html);
-		
+
 		$correct = 0;
 		if (!empty($this -> id)) {
 			$answer = new Answer($this -> id);
-			$answer->read();			
+			$answer->read();
 			if (count($answer->nbrAnswers) > 0 && !$form->isSubmitted()) {
 				$nb_answers = $answer->nbrAnswers;
 			}
 		}
-		
+
 		$form -> addElement('hidden', 'nb_answers');
 		$boxes_names = array();
 
@@ -86,51 +85,51 @@ class MultipleAnswerTrueFalse extends Question {
 			$nb_answers = 1;
 			Display::display_normal_message(get_lang('YouHaveToCreateAtLeastOneAnswer'));
 		}
-		
-        // Can be more options        
+
+        // Can be more options
         $option_data = Question::readQuestionOption($this->id, $course_id);
-          
+
 		for ($i = 1 ; $i <= $nb_answers ; ++$i) {
-            
-            $renderer->setElementTemplate('<td><!-- BEGIN error --><span class="form_error">{error}</span><!-- END error --><br/>{element}</td>', 'correct['.$i.']');  
-            $renderer->setElementTemplate('<td><!-- BEGIN error --><span class="form_error">{error}</span><!-- END error --><br/>{element}</td>', 'counter['.$i.']');  
-            $renderer->setElementTemplate('<td><!-- BEGIN error --><span class="form_error">{error}</span><!-- END error --><br/>{element}</td>', 'answer['.$i.']');  
-            $renderer->setElementTemplate('<td><!-- BEGIN error --><span class="form_error">{error}</span><!-- END error --><br/>{element}</td>', 'comment['.$i.']'); 
-            
+
+            $renderer->setElementTemplate('<td><!-- BEGIN error --><span class="form_error">{error}</span><!-- END error --><br/>{element}</td>', 'correct['.$i.']');
+            $renderer->setElementTemplate('<td><!-- BEGIN error --><span class="form_error">{error}</span><!-- END error --><br/>{element}</td>', 'counter['.$i.']');
+            $renderer->setElementTemplate('<td><!-- BEGIN error --><span class="form_error">{error}</span><!-- END error --><br/>{element}</td>', 'answer['.$i.']');
+            $renderer->setElementTemplate('<td><!-- BEGIN error --><span class="form_error">{error}</span><!-- END error --><br/>{element}</td>', 'comment['.$i.']');
+
             $answer_number=$form->addElement('text', 'counter['.$i.']',null,'value="'.$i.'"');
-            $answer_number->freeze();            
-            
-			if (is_object($answer)) {               
+            $answer_number->freeze();
+
+			if (is_object($answer)) {
 				$defaults['answer['.$i.']']     = $answer -> answer[$i];
 				$defaults['comment['.$i.']']    = $answer -> comment[$i];
 				//$defaults['weighting['.$i.']']  = float_format($answer -> weighting[$i], 1);
-      
+
                 $correct = $answer->correct[$i];
-                                
-                $defaults['correct['.$i.']']    = $correct;          
-			
-                $j = 1;             
+
+                $defaults['correct['.$i.']']    = $correct;
+
+                $j = 1;
                 if (!empty($option_data)) {
-                    foreach ($option_data as $id=>$data) {                 
+                    foreach ($option_data as $id=>$data) {
                         $form->addElement('radio', 'correct['.$i.']', null, null, $id);
                         $j++;
                         if ($j == 3) {
                         	break;
                         }
-                       
-                    }            
+
+                    }
                 }
-			} else {                
-                $form->addElement('radio', 'correct['.$i.']', null, null, 1);            
+			} else {
+                $form->addElement('radio', 'correct['.$i.']', null, null, 1);
                 $form->addElement('radio', 'correct['.$i.']', null, null, 2);
-            
+
                 $defaults['answer['.$i.']']     = '';
                 $defaults['comment['.$i.']']    = '';
-                $defaults['correct['.$i.']']    = '';                
-			}          
-            
+                $defaults['correct['.$i.']']    = '';
+			}
+
             //$form->addElement('select', 'correct['.$i.']',null, $this->options, array('id'=>$i,'onchange'=>'multiple_answer_true_false_onchange(this)'));
-            
+
 			$boxes_names[] = 'correct['.$i.']';
 
 			$form->addElement('html_editor', 'answer['.$i.']',null, 'style="vertical-align:middle"', array('ToolbarSet' => 'TestProposedAnswer', 'Width' => '100%', 'Height' => '100'));
@@ -142,38 +141,38 @@ class MultipleAnswerTrueFalse extends Question {
 			}
 			$form->addElement ('html', '</tr>');
 		}
-        
+
 		$form->addElement('html', '</table>');
-		$form->addElement('html', '<br />');  
-        
+		$form->addElement('html', '<br />');
+
         $form->addElement('html', '<table><tr><td></td><td>'.get_lang('Correct').'</td><td>'.get_lang('Wrong').'</td><td>'.get_lang('DoubtScore').'</td></tr>');
-               
+
         $renderer->setElementTemplate('<tr><td><span class="form_required">*</span>'.get_lang('Score').'&nbsp;&nbsp;&nbsp;&nbsp;</td><td>{element} &nbsp;&nbsp; <br /><!-- BEGIN error --><span class="form_error">{error}</span><!-- END error --></td>', 'option[1]');
         $renderer->setElementTemplate('<td>{element} &nbsp;&nbsp;<br /><!-- BEGIN error --><span class="form_error">{error}</span><!-- END error --></td>', 'option[2]');
         $renderer->setElementTemplate('<td>{element} &nbsp;&nbsp;<br /><!-- BEGIN error --><span class="form_error">{error}</span><!-- END error --></td>', 'option[3]');
 
         // 3 scores
         $form->addElement('text', 'option[1]', get_lang('Correct'),   array('class'=>'span1','value'=>'1'));
-        $form->addElement('text', 'option[2]', get_lang('Wrong'),     array('class'=>'span1','value'=>'-0.5'));        
+        $form->addElement('text', 'option[2]', get_lang('Wrong'),     array('class'=>'span1','value'=>'-0.5'));
         $form->addElement('text', 'option[3]', get_lang('DoubtScore'),array('class'=>'span1','value'=>'0'));
-        
+
         $form->addRule('option[1]', get_lang('ThisFieldIsRequired'), 'required');
         $form->addRule('option[2]', get_lang('ThisFieldIsRequired'), 'required');
-        $form->addRule('option[3]', get_lang('ThisFieldIsRequired'), 'required');                
-        
+        $form->addRule('option[3]', get_lang('ThisFieldIsRequired'), 'required');
+
         $form -> addElement ('html', '</tr><table>');
-        $form -> addElement('hidden', 'options_count', 3);                    
-        $form -> addElement ('html', '</table><br /><br />');        
-        
+        $form -> addElement('hidden', 'options_count', 3);
+        $form -> addElement ('html', '</table><br /><br />');
+
         //Extra values True, false,  Dont known
         if (!empty($this->extra)) {
-            $scores = explode(':',$this->extra);        
+            $scores = explode(':',$this->extra);
             if (!empty($scores)) {
                 for ($i = 1; $i <=3; $i++) {
-                    $defaults['option['.$i.']']	= $scores[$i-1];                
-                }        
-            }        
-        }        
+                    $defaults['option['.$i.']']	= $scores[$i-1];
+                }
+            }
+        }
 
 		//$form -> add_multiple_required_rule ($boxes_names , get_lang('ChooseAtLeastOneCheckbox') , 'multiple_required');
 
@@ -183,16 +182,16 @@ class MultipleAnswerTrueFalse extends Question {
 		if ($obj_ex->edit_exercise_in_lp == true) {
 			//ie6 fix
 			if ($navigator_info['name']=='Internet Explorer' &&  $navigator_info['version']=='6') {
-                
+
                 $form->addElement('submit', 'lessAnswers', get_lang('LessAnswer'),'class="btn minus"');
-                $form->addElement('submit', 'moreAnswers', get_lang('PlusAnswer'),'class="btn plus"');				
+                $form->addElement('submit', 'moreAnswers', get_lang('PlusAnswer'),'class="btn plus"');
                 $form->addElement('submit', 'submitQuestion',$text, 'class="'.$class.'"');
 			} else {
                 // setting the save button here and not in the question class.php
-                
+
                 $form->addElement('style_submit_button', 'lessAnswers', get_lang('LessAnswer'),'class="btn minus"');
                 $form->addElement('style_submit_button', 'moreAnswers', get_lang('PlusAnswer'),'class="btn plus"');
-                $form->addElement('style_submit_button', 'submitQuestion',$text, 'class="'.$class.'"');	
+                $form->addElement('style_submit_button', 'submitQuestion',$text, 'class="'.$class.'"');
 			}
 		}
 		$renderer->setElementTemplate('{element}&nbsp;','lessAnswers');
@@ -223,75 +222,74 @@ class MultipleAnswerTrueFalse extends Question {
 		$nb_answers       = $form->getSubmitValue('nb_answers');
         $options_count    = $form->getSubmitValue('options_count');
         $course_id        = api_get_course_int_id();
-       
+
         $correct = array();
         $options = Question::readQuestionOption($this->id, $course_id);
-        	
-        
+
+
         if (!empty($options)) {
             foreach ($options as $option_data) {
                 $id = $option_data['id'];
                 unset($option_data['id']);
                 Question::updateQuestionOption($id, $option_data, $course_id);
             }
-        } else {            
-            for ($i=1 ; $i <= 3 ; $i++) {                
+        } else {
+            for ($i=1 ; $i <= 3 ; $i++) {
         	   $last_id = Question::saveQuestionOption($this->id, $this->options[$i], $course_id, $i);
                $correct[$i] = $last_id;
-            }            
+            }
         }
-  
+
         //Getting quiz_question_options (true, false, doubt) because it's possible that there are more options in the future
         $new_options = Question::readQuestionOption($this->id, $course_id);
-        
+
         $sorted_by_position = array();
         foreach($new_options as $item) {
         	$sorted_by_position[$item['position']] = $item;
-        }        
-        
-        //Saving quiz_question.extra values that has the correct scores of the true, false, doubt options registered in this format XX:YY:ZZZ where XX is a float score value 
+        }
+
+        //Saving quiz_question.extra values that has the correct scores of the true, false, doubt options registered in this format XX:YY:ZZZ where XX is a float score value
         $extra_values = array();
         for ($i=1 ; $i <= 3 ; $i++) {
             $score = trim($form -> getSubmitValue('option['.$i.']'));
             $extra_values[]= $score;
-        }        
-        $this->setExtra(implode(':',$extra_values));       
-          
+        }
+        $this->setExtra(implode(':',$extra_values));
+
 		for ($i=1 ; $i <= $nb_answers ; $i++) {
         	$answer     = trim($form -> getSubmitValue('answer['.$i.']'));
             $comment    = trim($form -> getSubmitValue('comment['.$i.']'));
-            $goodAnswer = trim($form -> getSubmitValue('correct['.$i.']'));  
+            $goodAnswer = trim($form -> getSubmitValue('correct['.$i.']'));
             if (empty($options)) {
-                //If this is the first time that the question is created when change the default values from the form 1 and 2 by the correct "option id" registered 
+                //If this is the first time that the question is created when change the default values from the form 1 and 2 by the correct "option id" registered
                 $goodAnswer = $sorted_by_position[$goodAnswer]['id'];
-            }         
+            }
     	    $questionWeighting += $extra_values[0]; //By default 0 has the correct answers
-        	$objAnswer->createAnswer($answer, $goodAnswer, $comment,'',$i);            
-        }        
-    
+        	$objAnswer->createAnswer($answer, $goodAnswer, $comment,'',$i);
+        }
+
 
     	// saves the answers into the data base
         $objAnswer -> save();
-    
+
         // sets the total weighting of the question
         $this -> updateWeighting($questionWeighting);
         $this -> save();
 	}
-	
-	function return_header($feedback_type = null, $counter = null, $score = null) {	    	    
-        $header = parent::return_header($feedback_type, $counter, $score);        
-  	    $header .= '<table class="'.$this->question_table_class .'">		
+
+	function return_header($feedback_type = null, $counter = null, $score = null) {
+        $header = parent::return_header($feedback_type, $counter, $score);
+  	    $header .= '<table class="'.$this->question_table_class .'">
 		<tr>
 			<th>'.get_lang("Choice").'</th>
 			<th>'. get_lang("ExpectedChoice").'</th>
 			<th>'. get_lang("Answer").'</th>';
-			if ($feedback_type != EXERCISE_FEEDBACK_TYPE_EXAM) { 
+			if ($feedback_type != EXERCISE_FEEDBACK_TYPE_EXAM) {
 				$header .= '<th>'.get_lang("Comment").'</th>';
-			} else { 
+			} else {
 				$header .= '<th>&nbsp;</th>';
 			}
         $header .= '</tr>';
-        return $header;	  
+        return $header;
 	}
 }
-endif;

+ 4 - 6
main/exercice/oral_expression.class.php

@@ -11,7 +11,6 @@
 /**
  * Code
  */
-if(!class_exists('OralExpression')):
 /**
  * @package chamilo.exercise
  */
@@ -55,7 +54,7 @@ class OralExpression extends Question {
 		$this->weighting = $form -> getSubmitValue('weighting');
 		$this->save();
 	}
-	
+
 	function return_header($feedback_type = null, $counter = null, $score = null) {
 	    $header = parent::return_header($feedback_type, $counter, $score);
 	    $header .= '<table class="'.$this->question_table_class.'">
@@ -67,8 +66,7 @@ class OralExpression extends Question {
 			</tr>
 			<tr>
                 <th>&nbsp;</th>
-			</tr>';				
-        return $header;	  
-	}	
+			</tr>';
+        return $header;
+	}
 }
-endif;

+ 28 - 11
main/exercice/qti2.php

@@ -30,22 +30,33 @@ if (!api_is_allowed_to_edit(null, true)) {
 }
 
 // the breadcrumbs
-$interbreadcrumb[]= array ("url"=>"exercice.php", "name"=> get_lang('Exercices'));
+$interbreadcrumb[]= array (
+    "url" => api_get_path(WEB_CODE_PATH)."exercice/exercice.php?".api_get_cidreq(),
+    "name" => get_lang('Exercices')
+);
 $is_allowedToEdit = api_is_allowed_to_edit(null, true);
 
 /**
  * This function displays the form for import of the zip file with qti2
  */
-function ch_qti2_display_form() {
+function ch_qti2_display_form()
+{
 	$name_tools = get_lang('ImportQtiQuiz');
 	$form  = '<div class="actions">';
-	$form .= '<a href="exercice.php?show=test">' . Display :: return_icon('back.png', get_lang('BackToExercisesList'),'',ICON_SIZE_MEDIUM).'</a>';
+	$form .= '<a href="'.api_get_path(WEB_CODE_PATH).'exercice/exercice.php?show=test&'.api_get_cidreq().'">'.
+            Display :: return_icon('back.png', get_lang('BackToExercisesList'),'',ICON_SIZE_MEDIUM).'</a>';
 	$form .= '</div>';
-    $form_validator  = new FormValidator('qti_upload', 'post',api_get_self()."?".api_get_cidreq(), null, array('enctype' => 'multipart/form-data') );
-    $form_validator->addElement('header', $name_tools);    
-    $form_validator->addElement('file', 'userFile', get_lang('DownloadFile'));    
-    $form_validator->addElement('style_submit_button', 'submit', get_lang('Send'), 'class="upload"');    
-    $form .= $form_validator->return_form();	
+    $formValidator = new FormValidator(
+        'qti_upload',
+        'post',
+        api_get_self()."?".api_get_cidreq(),
+        null,
+        array('enctype' => 'multipart/form-data')
+    );
+    $formValidator->addElement('header', $name_tools);
+    $formValidator->addElement('file', 'userFile', get_lang('DownloadFile'));
+    $formValidator->addElement('style_submit_button', 'submit', get_lang('Send'), 'class="upload"');
+    $form .= $formValidator->return_form();
 
 	echo $form;
 }
@@ -54,7 +65,8 @@ function ch_qti2_display_form() {
  * This function will import the zip file with the respective qti2
  * @param array $uploaded_file ($_FILES)
  */
-function ch_qti2_import_file($array_file) {
+function ch_qti2_import_file($array_file)
+{
 	$unzip = 0;
 	$lib_path = api_get_path(LIBRARY_PATH);
 	require_once $lib_path.'fileUpload.lib.php';
@@ -64,15 +76,20 @@ function ch_qti2_import_file($array_file) {
 		// if it's a zip, allow zip upload
 		$unzip = 1;
 	}
+
 	if ($process && $unzip == 1) {
 		$main_path = api_get_path(SYS_CODE_PATH);
 		require_once $main_path.'exercice/export/exercise_import.inc.php';
         require_once $main_path.'exercice/export/qti2/qti2_classes.php';
+
         $imported = import_exercise($array_file['name']);
+
         if ($imported) {
-        	header('Location: exercice.php?'.api_get_cidreq());
+        	header('Location: '.api_get_path(WEB_CODE_PATH).'exercice/exercice.php?'.api_get_cidreq());
+            exit;
         } else {
             Display::display_error_message(get_lang('UplNoFileUploaded'));
+
             return false;
         }
 	}
@@ -92,4 +109,4 @@ if ((api_is_allowed_to_edit(null, true))) {
 ch_qti2_display_form();
 
 // display the footer
-Display::display_footer();
+Display::display_footer();

+ 91 - 79
main/exercice/unique_answer.class.php

@@ -10,8 +10,6 @@
  * Code
  */
 
-if(!class_exists('UniqueAnswer')):
-
 /**
 	CLASS UNIQUE_ANSWER
  *
@@ -23,15 +21,16 @@ if(!class_exists('UniqueAnswer')):
  *	@package chamilo.exercise
  **/
 
-class UniqueAnswer extends Question {
-
+class UniqueAnswer extends Question
+{
 	static $typePicture = 'mcua.gif';
 	static $explanationLangVar = 'UniqueSelect';
 
 	/**
 	 * Constructor
 	 */
-	function UniqueAnswer() {
+	function UniqueAnswer()
+    {
 		//this is highly important
 		parent::question();
 		$this -> type = UNIQUE_ANSWER;
@@ -39,11 +38,12 @@ class UniqueAnswer extends Question {
 	}
 
 	/**
-	 * function which redifines Question::createAnswersForm
+	 * function which redefines Question::createAnswersForm
 	 * @param the formvalidator instance
 	 * @param the answers number to display
 	 */
-	function createAnswersForm ($form) {
+	function createAnswersForm ($form)
+    {
 		// Getting the exercise list
 		$obj_ex = $_SESSION['objExercise'];
 
@@ -89,11 +89,11 @@ class UniqueAnswer extends Question {
                         '.$feedback_title.'
                     <th width="50px">
                         '.get_lang('Weighting').'
-                    </th>        
+                    </th>
                 </tr>';
 
         $form -> addElement ('label', get_lang('Answers').'<br /> <img src="../img/fill_field.png">', $html);
-		
+
 		$defaults = array();
 		$correct = 0;
 		if(!empty($this -> id)) {
@@ -110,7 +110,7 @@ class UniqueAnswer extends Question {
 		$select_question=array();
 		$select_question[0] = get_lang('SelectTargetQuestion');
 
-		require_once '../newscorm/learnpathList.class.php';        
+		require_once '../newscorm/learnpathList.class.php';
 		if (is_array($question_list)) {
 			foreach ($question_list as $key=>$questionid) {
 				//To avoid warning messages
@@ -133,14 +133,14 @@ class UniqueAnswer extends Question {
 		}
 
 		$temp_scenario = array();
-        
+
         if ($nb_answers < 1) {
             $nb_answers = 1;
             Display::display_normal_message(get_lang('YouHaveToCreateAtLeastOneAnswer'));
-        }                        
+        }
 
         for ($i = 1 ; $i <= $nb_answers ; ++$i) {
-            $form -> addElement ('html', '<tr>');                
+            $form -> addElement ('html', '<tr>');
             if (isset($answer) && is_object($answer)) {
                 if ($answer -> correct[$i]) {
                     $correct = $i;
@@ -183,67 +183,67 @@ class UniqueAnswer extends Question {
             $defaults['scenario'] = $temp_scenario;
 
             $renderer = $form->defaultRenderer();
-            
-            $renderer->setElementTemplate('<td><!-- BEGIN error --><span class="form_error">{error}</span><!-- END error --><br/>{element}</td>', 'correct');  
-            $renderer->setElementTemplate('<td><!-- BEGIN error --><span class="form_error">{error}</span><!-- END error --><br/>{element}</td>', 'counter['.$i.']');  
-            $renderer->setElementTemplate('<td><!-- BEGIN error --><span class="form_error">{error}</span><!-- END error --><br/>{element}</td>', 'answer['.$i.']');  
+
+            $renderer->setElementTemplate('<td><!-- BEGIN error --><span class="form_error">{error}</span><!-- END error --><br/>{element}</td>', 'correct');
+            $renderer->setElementTemplate('<td><!-- BEGIN error --><span class="form_error">{error}</span><!-- END error --><br/>{element}</td>', 'counter['.$i.']');
+            $renderer->setElementTemplate('<td><!-- BEGIN error --><span class="form_error">{error}</span><!-- END error --><br/>{element}</td>', 'answer['.$i.']');
             $renderer->setElementTemplate('<td><!-- BEGIN error --><span class="form_error">{error}</span><!-- END error --><br/>{element}</td>', 'comment['.$i.']');
-            $renderer->setElementTemplate('<td><!-- BEGIN error --><span class="form_error">{error}</span><!-- END error --><br/>{element}</td>', 'weighting['.$i.']');        
-            
+            $renderer->setElementTemplate('<td><!-- BEGIN error --><span class="form_error">{error}</span><!-- END error --><br/>{element}</td>', 'weighting['.$i.']');
+
             $answer_number = $form->addElement('text', 'counter['.$i.']',null,' value = "'.$i.'"');
             $answer_number->freeze();
 
             $form->addElement('radio', 'correct', null, null, $i, 'class="checkbox" style="margin-left: 0em;"');
             $form->addElement('html_editor', 'answer['.$i.']', null, 'style="vertical-align:middle"', $editor_config);
-            
+
             $form->addRule('answer['.$i.']', get_lang('ThisFieldIsRequired'), 'required');
 
             if ($obj_ex->selectFeedbackType() == EXERCISE_FEEDBACK_TYPE_DIRECT) {
                 $form->addElement('html_editor', 'comment['.$i.']', null, 'style="vertical-align:middle"', $editor_config);
                 // Direct feedback
-          
+
                 //Adding extra feedback fields
                 $group = array();
                 $group['try'.$i] = $form->createElement('checkbox', 'try'.$i, null , get_lang('TryAgain'));
                 $group['lp'.$i]  = $form->createElement('select', 'lp'.$i, get_lang('SeeTheory').': ', $select_lp_id);
                 $group['destination'.$i]= $form->createElement('select', 'destination'.$i, get_lang('GoToQuestion').': ' , $select_question);
                 $group['url'.$i] = $form->createElement('text', 'url'.$i, get_lang('Other').': ', array('class'=>'span2', 'placeholder' => get_lang('Other')));
-                $form->addGroup($group, 'scenario');                
-                
-                $renderer->setElementTemplate('<td><!-- BEGIN error --><span class="form_error">{error}</span><!-- END error --><br/>{element}', 'scenario');            
-                
+                $form->addGroup($group, 'scenario');
+
+                $renderer->setElementTemplate('<td><!-- BEGIN error --><span class="form_error">{error}</span><!-- END error --><br/>{element}', 'scenario');
+
             }
             else {
                 $form->addElement('html_editor', 'comment['.$i.']', null, 'style="vertical-align:middle"', $editor_config);
             }
-            $form->addElement('text', 'weighting['.$i.']', null, array('class' => "span1", 'value' => '0'));                    
-            $form->addElement ('html', '</tr>');                
+            $form->addElement('text', 'weighting['.$i.']', null, array('class' => "span1", 'value' => '0'));
+            $form->addElement ('html', '</tr>');
         }
 
 		$form -> addElement ('html', '</table>');
-		$form -> addElement ('html', '<br />');        
-        
+		$form -> addElement ('html', '<br />');
+
 		$navigator_info = api_get_navigator();
 
 		global $text, $class;
-        
+
 		//ie6 fix
 		if ($obj_ex->edit_exercise_in_lp == true) {
-			if ($navigator_info['name']=='Internet Explorer' &&  $navigator_info['version']=='6') {                
+			if ($navigator_info['name']=='Internet Explorer' &&  $navigator_info['version']=='6') {
                 $form->addElement('submit', 'lessAnswers', get_lang('LessAnswer'),'class="btn minus"');
-                $form->addElement('submit', 'moreAnswers', get_lang('PlusAnswer'),'class="btn plus"'); 
+                $form->addElement('submit', 'moreAnswers', get_lang('PlusAnswer'),'class="btn plus"');
                 $form->addElement('submit','submitQuestion',$text, 'class="'.$class.'"');
 			} else {
-                //setting the save button here and not in the question class.php                
+                //setting the save button here and not in the question class.php
                 $form->addElement('style_submit_button', 'lessAnswers', get_lang('LessAnswer'),'class="btn minus"');
-                $form->addElement('style_submit_button', 'moreAnswers', get_lang('PlusAnswer'),'class="btn plus"');                
-                $form->addElement('style_submit_button', 'submitQuestion',$text, 'class="'.$class.'"');				
+                $form->addElement('style_submit_button', 'moreAnswers', get_lang('PlusAnswer'),'class="btn plus"');
+                $form->addElement('style_submit_button', 'submitQuestion',$text, 'class="'.$class.'"');
 			}
 		}
 		$renderer->setElementTemplate('{element}&nbsp;','submitQuestion');
 		$renderer->setElementTemplate('{element}&nbsp;','lessAnswers');
 		$renderer->setElementTemplate('{element}&nbsp;','moreAnswers');
-        
+
         $form->addElement('html', '</div></div>');
 
 		//We check the first radio button to be sure a radio button will be check
@@ -265,13 +265,13 @@ class UniqueAnswer extends Question {
 
 	/**
 	 * abstract function which creates the form to create / edit the answers of the question
-	 * @param the formvalidator instance
+	 * @param FormValidator $form
 	 * @param the answers number to display
 	 */
-	function processAnswersCreation($form) {
-
+	function processAnswersCreation($form)
+    {
 		$questionWeighting = $nbrGoodAnswers = 0;
-		$correct = $form -> getSubmitValue('correct');
+		$correct = $form->getSubmitValue('correct');
 		$objAnswer = new Answer($this->id);
 		$nb_answers = $form->getSubmitValue('nb_answers');
 
@@ -281,11 +281,11 @@ class UniqueAnswer extends Question {
             $weighting = trim($form -> getSubmitValue('weighting['.$i.']'));
 
             $scenario = $form -> getSubmitValue('scenario');
-            
+
            	//$list_destination = $form -> getSubmitValue('destination'.$i);
            	//$destination_str = $form -> getSubmitValue('destination'.$i);
 
- 		    $try = $scenario['try'.$i];            
+ 		    $try = $scenario['try'.$i];
             $lp = $scenario['lp'.$i];
  			$destination = $scenario['destination'.$i];
  			$url = trim($scenario['url'.$i]);
@@ -302,7 +302,7 @@ class UniqueAnswer extends Question {
 			lp_id = id of a learning path (0 if dont select)
 			selected_questions= ids of questions
 			url= an url
-	
+
  			$destination_str='';
  			foreach ($list_destination as $destination_id)
  			{
@@ -330,16 +330,16 @@ class UniqueAnswer extends Question {
  			if (empty($destination)) {
  				$destination=0;
  			}
-            
+
  			if ($url=='') {
  				$url=0;
  			}
 
  			//1@@1;2;@@2;4;4;@@http://www.chamilo.org
-			$dest = $try.'@@'.$lp.'@@'.$destination.'@@'.$url;            
+			$dest = $try.'@@'.$lp.'@@'.$destination.'@@'.$url;
         	$objAnswer->createAnswer($answer, $goodAnswer, $comment, $weighting, $i, null, null, $dest);
         }
-        
+
     	// saves the answers into the data base
         $objAnswer->save();
 
@@ -347,45 +347,57 @@ class UniqueAnswer extends Question {
         $this->updateWeighting($questionWeighting);
         $this->save();
 	}
-	
-	function return_header($feedback_type = null, $counter = null, $score = null) {
+
+	function return_header($feedback_type = null, $counter = null, $score = null)
+    {
 	    $header = parent::return_header($feedback_type, $counter, $score);
-	    $header .= '<table class="'.$this->question_table_class .'">			
+	    $header .= '<table class="'.$this->question_table_class .'">
 			<tr>
 				<th>'.get_lang("Choice").'</th>
 				<th>'. get_lang("ExpectedChoice").'</th>
-				<th>'. get_lang("Answer").'</th>';        
+				<th>'. get_lang("Answer").'</th>';
         $header .= '<th>'.get_lang("Comment").'</th>';
         $header .= '</tr>';
-        return $header;	
+
+        return $header;
     }
-    
-  function create_answer($id, $question_id, $answer_title, $comment, $score = 0, $correct = 0) {
-    $tbl_quiz_answer = Database::get_course_table(TABLE_QUIZ_ANSWER);
-    $tbl_quiz_question = Database::get_course_table(TABLE_QUIZ_QUESTION);
-    $course_id = api_get_course_int_id();
-    $position = 1;
-    $question_id = filter_var($question_id,FILTER_SANITIZE_NUMBER_INT);
-    $score = filter_var($score,FILTER_SANITIZE_NUMBER_FLOAT);
-    $correct = filter_var($correct,FILTER_SANITIZE_NUMBER_INT);
-    // Get the max position
-    $sql = "SELECT max(position) as max_position FROM $tbl_quiz_answer "
-          ." WHERE c_id = $course_id AND question_id = $question_id";
-    $rs_max  = Database::query($sql);
-    $row_max = Database::fetch_object($rs_max);
-    $position = $row_max->max_position + 1;
-    // Insert a new answer
-    $sql = "INSERT INTO $tbl_quiz_answer "
-    ."(c_id, id, question_id,answer,correct,comment,ponderation,position,destination)"
-    ."VALUES ($course_id, $id,$question_id,'".Database::escape_string($answer_title)."',"
-    ."$correct,'".Database::escape_string($comment)."',$score,$position, "
-    ." '0@@0@@0@@0')";
-    $rs = Database::query($sql);
-    if ($correct) {
-        $sql = "UPDATE $tbl_quiz_question "
-        ." SET ponderation = (ponderation + $score) WHERE c_id = $course_id AND id = ".$question_id;
-        $rs = Database::query($sql);
+
+    /**
+     * @param int $id
+     * @param int $question_id
+     * @param string $title
+     * @param string $comment
+     * @param float $score
+     * @param int $correct
+     */
+    function addAnswer($id, $question_id, $title, $comment, $score = 0, $correct = 0)
+    {
+        $tbl_quiz_answer = Database::get_course_table(TABLE_QUIZ_ANSWER);
+        $tbl_quiz_question = Database::get_course_table(TABLE_QUIZ_QUESTION);
+        $course_id = api_get_course_int_id();
+        $question_id = intval($question_id);
+        $score = floatval($score);
+        $correct = intval($correct);
+        $title = Database::escape_string($title);
+        $comment = Database::escape_string($comment);
+        // Get the max position.
+        $sql = "SELECT max(position) as max_position
+                FROM $tbl_quiz_answer
+                WHERE
+                  c_id = $course_id AND
+                  question_id = $question_id";
+        $rs_max  = Database::query($sql);
+        $row_max = Database::fetch_object($rs_max);
+        $position = $row_max->max_position + 1;
+        // Insert a new answer
+        $sql = "INSERT INTO $tbl_quiz_answer (c_id, id, question_id,answer,correct,comment,ponderation,position,destination)
+                VALUES ($course_id, $id, $question_id, '".$title."', $correct, '".$comment."', '$score', $position, '0@@0@@0@@0')";
+        Database::query($sql);
+        if ($correct) {
+            $sql = "UPDATE $tbl_quiz_question
+                    SET ponderation = (ponderation + $score)
+                    WHERE c_id = $course_id AND id = ".$question_id;
+            Database::query($sql);
+        }
     }
-  }
 }
-endif;

+ 76 - 81
main/exercice/unique_answer_no_option.class.php

@@ -11,8 +11,6 @@
  * Code
  */
 
-if(!class_exists('UniqueAnswerNoOption')):
-
 /**
 	CLASS UNIQUE_ANSWER
  *
@@ -24,8 +22,8 @@ if(!class_exists('UniqueAnswerNoOption')):
  *	@package chamilo.exercise
  **/
 
-class UniqueAnswerNoOption extends Question {
-
+class UniqueAnswerNoOption extends Question
+{
 	static $typePicture = 'mcuao.gif';
 	static $explanationLangVar = 'UniqueAnswerNoOption';
 
@@ -52,7 +50,7 @@ class UniqueAnswerNoOption extends Question {
 
 		//this line define how many question by default appear when creating a choice question
 		$nb_answers  = isset($_POST['nb_answers']) ? (int) $_POST['nb_answers'] : 3;  // The previous default value was 2. See task #1759.
-		$nb_answers += (isset($_POST['lessAnswers']) ? -1 : (isset($_POST['moreAnswers']) ? 1 : 0)); 
+		$nb_answers += (isset($_POST['lessAnswers']) ? -1 : (isset($_POST['moreAnswers']) ? 1 : 0));
 
 		/*
 	 		Types of Feedback
@@ -89,32 +87,32 @@ class UniqueAnswerNoOption extends Question {
 							'.$feedback_title.'
 						<th width="60px">
 							'.get_lang('Weighting').'
-						</th>        
+						</th>
 					</tr>';
         $form -> addElement ('label', get_lang('Answers').'<br /> <img src="../img/fill_field.png">', $html);
 
 		$defaults = array();
 		$correct = 0;
-		
+
 		if (!empty($this -> id)) {
 			$answer = new Answer($this -> id);
 			$answer -> read();
 			if (count($answer->nbrAnswers)>0 && !$form->isSubmitted()) {
-				$nb_answers = $answer->nbrAnswers;				
+				$nb_answers = $answer->nbrAnswers;
 			}
 		}
 
 		$temp_scenario = array();
-	    	    
+
 		if ($nb_answers < 1) {
 			$nb_answers = 1;
 			Display::display_normal_message(get_lang('YouHaveToCreateAtLeastOneAnswer'));
-		}				
+		}
         if ($_GET['editQuestion']) {
-            
+
             //fixing $nb_answers
             $new_list = array();
-            $count = 1;            
+            $count = 1;
             if (isset($_POST['lessAnswers'])) {
                 if (!isset($_SESSION['less_answer'])) {
                     $_SESSION['less_answer'] = $this -> id;
@@ -122,106 +120,106 @@ class UniqueAnswerNoOption extends Question {
                 }
             }
             for ($k = 1 ; $k <= $nb_answers; ++$k) {
-                if ($answer->position[$k] != '666') {                    
+                if ($answer->position[$k] != '666') {
                     $new_list[$count] = $count;
                     $count++;
                 }
-            }          
+            }
         } else {
-            for ($k = 1 ; $k <= $nb_answers; ++$k) {                                
-                $new_list[$k] = $k;                
-            }            
+            for ($k = 1 ; $k <= $nb_answers; ++$k) {
+                $new_list[$k] = $k;
+            }
         }
-        
+
         $i = 1;
-		//for ($k = 1 ; $k <= $real_nb_answers; $k++) {            
+		//for ($k = 1 ; $k <= $real_nb_answers; $k++) {
         foreach ($new_list as $key) {
-            $i = $key;	    
-			$form -> addElement ('html', '<tr>'); 
-		             
+            $i = $key;
+			$form -> addElement ('html', '<tr>');
+
 			if (is_object($answer)) {
 			    if($answer->position[$i] == 666) {
-			        //we set nothing			        
-			    } else {			    
+			        //we set nothing
+			    } else {
     				if ($answer->correct[$i]) {
     					$correct = $i;
     				}
-                    $answer_result = $answer->answer[$i];                
+                    $answer_result = $answer->answer[$i];
                     $weight_result = float_format($answer->weighting[$i], 1);
                     if ($nb_answers == $i) {
                         $weight_result = '0';
                     }
-                    
+
     				$defaults['answer['.$i.']']    = $answer_result;
     				$defaults['comment['.$i.']']   = $answer->comment[$i];
     				$defaults['weighting['.$i.']'] = $weight_result;
-    
+
     				$item_list=explode('@@',$answer -> destination[$i]);
-    
+
     				$try       = $item_list[0];
     				$lp        = $item_list[1];
     				$list_dest = $item_list[2];
     				$url       = $item_list[3];
-    
+
     				if ($try==0)
     					$try_result=0;
     				else
     					$try_result=1;
-    
+
     				if ($url==0)
     					$url_result='';
     				else
     					$url_result=$url;
-    
+
     				$temp_scenario['url'.$i]        = $url_result;
     				$temp_scenario['try'.$i]        = $try_result;
     				$temp_scenario['lp'.$i]         = $lp;
     				$temp_scenario['destination'.$i]= $list_dest;
 			    }
 			}
-			
+
 			$defaults['scenario']=$temp_scenario;
 			$renderer = & $form->defaultRenderer();
-            
-			$renderer->setElementTemplate('<td><!-- BEGIN error --><span class="form_error">{error}</span><!-- END error --><br/>{element}</td>', 'correct');  
-            $renderer->setElementTemplate('<td><!-- BEGIN error --><span class="form_error">{error}</span><!-- END error --><br/>{element}</td>', 'counter['.$i.']');  
-            $renderer->setElementTemplate('<td><!-- BEGIN error --><span class="form_error">{error}</span><!-- END error --><br/>{element}</td>', 'answer['.$i.']');  
-            $renderer->setElementTemplate('<td><!-- BEGIN error --><span class="form_error">{error}</span><!-- END error --><br/>{element}</td>', 'comment['.$i.']');  
-            $renderer->setElementTemplate('<td><!-- BEGIN error --><span class="form_error">{error}</span><!-- END error --><br/>{element}</td>', 'weighting['.$i.']');        
-          
-            
+
+			$renderer->setElementTemplate('<td><!-- BEGIN error --><span class="form_error">{error}</span><!-- END error --><br/>{element}</td>', 'correct');
+            $renderer->setElementTemplate('<td><!-- BEGIN error --><span class="form_error">{error}</span><!-- END error --><br/>{element}</td>', 'counter['.$i.']');
+            $renderer->setElementTemplate('<td><!-- BEGIN error --><span class="form_error">{error}</span><!-- END error --><br/>{element}</td>', 'answer['.$i.']');
+            $renderer->setElementTemplate('<td><!-- BEGIN error --><span class="form_error">{error}</span><!-- END error --><br/>{element}</td>', 'comment['.$i.']');
+            $renderer->setElementTemplate('<td><!-- BEGIN error --><span class="form_error">{error}</span><!-- END error --><br/>{element}</td>', 'weighting['.$i.']');
+
+
 			$answer_number=$form->addElement('text', 'counter['.$i.']', null,'value="'.$i.'"');
 			$answer_number->freeze();
-		
-        
+
+
 			$form->addElement('radio', 'correct', null, null, $i, 'class="checkbox" style="margin-left: 0em;"');
 			$form->addElement('html_editor', 'answer['.$i.']', null, 'style="vertical-align:middle"', $editor_config);
-			
+
             $form->addElement('html_editor', 'comment['.$i.']', null, 'style="vertical-align:middle"', $editor_config);
 			$form->addElement('text', 'weighting['.$i.']', null, array('class' => "span1", 'value' => '0'));
 			$form->addElement('html', '</tr>');
-            $i++;				
-		}	
-		
+            $i++;
+		}
+
 		if (empty($this -> id)) {
 		    $form->addElement('hidden', 'new_question', 1);
 		}
-        
+
         //Adding the "I don't know" question answer
         //if (empty($this -> id)) {
-        $i = 666;        
-        $form -> addElement ('html', '<tr>'); 
+        $i = 666;
+        $form -> addElement ('html', '<tr>');
 
         $defaults['answer['.$i.']']     = get_lang('DontKnow');
         $defaults['weighting['.$i.']']  = 0;
         $defaults['scenario']=$temp_scenario;
         $renderer = & $form->defaultRenderer();
 
-        $renderer->setElementTemplate('<td><!-- BEGIN error --><span class="form_error">{error}</span><!-- END error --><br/>{element}</td>', 'correct');  
-        $renderer->setElementTemplate('<td><!-- BEGIN error --><span class="form_error">{error}</span><!-- END error --><br/>{element}</td>', 'counter['.$i.']');  
-        $renderer->setElementTemplate('<td><!-- BEGIN error --><span class="form_error">{error}</span><!-- END error --><br/>{element}</td>', 'answer['.$i.']');  
-        $renderer->setElementTemplate('<td><!-- BEGIN error --><span class="form_error">{error}</span><!-- END error --><br/>{element}</td>', 'comment['.$i.']');  
-        $renderer->setElementTemplate('<td><!-- BEGIN error --><span class="form_error">{error}</span><!-- END error --><br/>{element}</td>', 'weighting['.$i.']'); 
+        $renderer->setElementTemplate('<td><!-- BEGIN error --><span class="form_error">{error}</span><!-- END error --><br/>{element}</td>', 'correct');
+        $renderer->setElementTemplate('<td><!-- BEGIN error --><span class="form_error">{error}</span><!-- END error --><br/>{element}</td>', 'counter['.$i.']');
+        $renderer->setElementTemplate('<td><!-- BEGIN error --><span class="form_error">{error}</span><!-- END error --><br/>{element}</td>', 'answer['.$i.']');
+        $renderer->setElementTemplate('<td><!-- BEGIN error --><span class="form_error">{error}</span><!-- END error --><br/>{element}</td>', 'comment['.$i.']');
+        $renderer->setElementTemplate('<td><!-- BEGIN error --><span class="form_error">{error}</span><!-- END error --><br/>{element}</td>', 'weighting['.$i.']');
 
         $answer_number=$form->addElement('text', 'counter['.$i.']',null,'value="-"');
         $answer_number->freeze();
@@ -241,9 +239,7 @@ class UniqueAnswerNoOption extends Question {
         $form->addElement('text', 'weighting['.$i.']', null, array('class' => "span1", 'value' => '0', 'readonly' =>'readonly'));
         $form->addElement ('html', '</tr>');
 
-     //}
-    
-       
+
 		$form -> addElement ('html', '</table>');
 		$form -> addElement ('html', '<br />');
 		$navigator_info = api_get_navigator();
@@ -251,15 +247,15 @@ class UniqueAnswerNoOption extends Question {
 		global $text, $class;
 		//ie6 fix
 		if ($obj_ex->edit_exercise_in_lp == true) {
-			if ($navigator_info['name']=='Internet Explorer' &&  $navigator_info['version']=='6') {                
-                $form->addElement('submit', 'moreAnswers', get_lang('PlusAnswer'),'class="btn plus"');                
+			if ($navigator_info['name']=='Internet Explorer' &&  $navigator_info['version']=='6') {
+                $form->addElement('submit', 'moreAnswers', get_lang('PlusAnswer'),'class="btn plus"');
 				$form->addElement('submit', 'lessAnswers', get_lang('LessAnswer'),'class="btn minus"');
                 $form->addElement('submit','submitQuestion',$text, 'class="'.$class.'"');
 			} else {
-                //setting the save button here and not in the question class.php                
+                //setting the save button here and not in the question class.php
                 $form->addElement('style_submit_button', 'lessAnswers', get_lang('LessAnswer'),'class="btn minus"');
                 $form->addElement('style_submit_button', 'moreAnswers', get_lang('PlusAnswer'),'class="btn plus"');
-                $form->addElement('style_submit_button','submitQuestion',$text, 'class="'.$class.'"');				
+                $form->addElement('style_submit_button','submitQuestion',$text, 'class="'.$class.'"');
 			}
 		}
 		$renderer->setElementTemplate('{element}&nbsp;','submitQuestion');
@@ -278,13 +274,13 @@ class UniqueAnswerNoOption extends Question {
 			$form -> setDefaults($defaults);
 		} else {
             $form -> setDefaults($defaults);
-		}		
-		
+		}
+
 		$form->addElement('hidden', 'nb_answers');
-		
-	
+
+
 	    $form->setConstants(array('nb_answers' => $nb_answers));
-		
+
 	}
 
 
@@ -301,19 +297,19 @@ class UniqueAnswerNoOption extends Question {
 		$nb_answers = $form -> getSubmitValue('nb_answers');
 		$minus = 1;
 		if ($form -> getSubmitValue('new_question')) {
-		    $minus = 0;    
-		}	
-            
+		    $minus = 0;
+		}
+
 		for ($i=1 ; $i <= $nb_answers - $minus; $i++) {
 		    $position   = trim($form -> getSubmitValue('position['.$i.']'));
         	$answer     = trim($form -> getSubmitValue('answer['.$i.']'));
             $comment    = trim($form -> getSubmitValue('comment['.$i.']'));
             $weighting  = trim($form -> getSubmitValue('weighting['.$i.']'));
             $scenario   = $form -> getSubmitValue('scenario');
-            
-            
+
+
 //
-            
+
            	//$list_destination = $form -> getSubmitValue('destination'.$i);
            	//$destination_str = $form -> getSubmitValue('destination'.$i);
 
@@ -362,7 +358,7 @@ class UniqueAnswerNoOption extends Question {
  			if (empty($destination)) {
  				$destination=0;
  			}
-            
+
  			if ($url=='') {
  				$url=0;
  			}
@@ -371,17 +367,17 @@ class UniqueAnswerNoOption extends Question {
 			$dest= $try.'@@'.$lp.'@@'.$destination.'@@'.$url;
         	$objAnswer -> createAnswer($answer,$goodAnswer,$comment,$weighting,$i,NULL,NULL,$dest);
         }
-        
+
         //Create 666 answer
         $i = 666;
         $answer     = trim($form -> getSubmitValue('answer['.$i.']'));
         $comment    = trim($form -> getSubmitValue('comment['.$i.']'));
         $weighting  = trim($form -> getSubmitValue('weighting['.$i.']'));
         $goodAnswer= ($correct == $i) ? true : false;
-        $dest       = ''; 
-            
+        $dest       = '';
+
         $objAnswer -> createAnswer($answer,$goodAnswer,$comment,$weighting,$i,NULL,NULL,$dest);
-        
+
     	// saves the answers into the data base
         $objAnswer -> save();
 
@@ -389,17 +385,16 @@ class UniqueAnswerNoOption extends Question {
         $this -> updateWeighting($questionWeighting);
         $this -> save();
 	}
-	
+
 	function return_header($feedback_type = null, $counter = null, $score = null) {
 	    $header = parent::return_header($feedback_type, $counter, $score);
-	    $header .= '<table class="'.$this->question_table_class .'">			
+	    $header .= '<table class="'.$this->question_table_class .'">
 			<tr>
 				<th>'.get_lang("Choice").'</th>
 				<th>'. get_lang("ExpectedChoice").'</th>
 				<th>'. get_lang("Answer").'</th>';
         $header .= '<th>'.get_lang("Comment").'</th>';
         $header .= '</tr>';
-        return $header;	
+        return $header;
 	}
 }
-endif;

+ 115 - 64
main/exercice/upload_exercise.php

@@ -32,13 +32,13 @@ $is_allowed_to_edit = api_is_allowed_to_edit(null, true);
 if (!$is_allowed_to_edit) {
     api_not_allowed(true);
 }
-
 // setting the tabs
 $this_section = SECTION_COURSES;
-$htmlHeadXtra[] = "<script type='text/javascript'>
-  $(document).ready( function(){
-  $(\"div.formw\").attr(\"style\",\"width: 73%;\");
-  $(\"#img_plus_and_minus\").hide();
+$htmlHeadXtra[] = "<script>
+$(document).ready( function(){
+    $('#user_custom_score').click(function() {
+        $('#options').toggle();
+    });
 });
 </script>";
 
@@ -48,41 +48,34 @@ lp_upload_quiz_action_handling();
 $interbreadcrumb[]= array ("url"=>"exercice.php", "name"=> get_lang('Exercices'));
 
 // Display the header
-if ($origin != 'learnpath') {
-    //so we are not in learnpath tool
-    Display :: display_header(get_lang('ImportExcelQuiz'), 'Exercises');
-    if (isset ($_GET['message'])) {
-        if (in_array($_GET['message'], array ('ExerciseEdited'))) {
-            Display :: display_confirmation_message(get_lang($_GET['message']));
-        }
+
+Display :: display_header(get_lang('ImportExcelQuiz'), 'Exercises');
+
+if (isset($_GET['message'])) {
+    if (in_array($_GET['message'], array('ExerciseEdited'))) {
+        Display :: display_confirmation_message(get_lang($_GET['message']));
     }
-} else {
-    echo '<link rel="stylesheet" type="text/css" href="' . api_get_path(WEB_CODE_PATH) . 'css/default.css"/>';
 }
+
 // display the actions
 echo '<div class="actions">';
 echo lp_upload_quiz_actions();
 echo '</div>';
 
-// start the content div
-echo '<div id="content_with_secondary_actions" class="gradient">';
 // the main content
 lp_upload_quiz_main();
 
-// close the content div
-echo '</div>';
-
 function lp_upload_quiz_actions() {
-    $lp_id = Security::remove_XSS($_GET['lp_id']);
-    $return = "";
-    $return .= '<a href="exercice.php?'.api_get_cidReq().'">'.Display::return_icon('back.png', get_lang('BackToExercisesList'),'',ICON_SIZE_MEDIUM).'</a>';
+    $return = '<a href="exercice.php?'.api_get_cidReq().'">'.
+        Display::return_icon('back.png', get_lang('BackToExercisesList'),'',ICON_SIZE_MEDIUM).'</a>';
     return $return;
 }
 
 function lp_upload_quiz_secondary_actions() {
     $lp_id = Security::remove_XSS($_GET['lp_id']);
     $return = '';
-    $return.='<a href="exercise_report.php?' . api_get_cidreq() . '">' . Display :: return_icon('reporting32.png', get_lang('Tracking')) . get_lang('Tracking') . '</a>';
+    $return .= '<a href="exercise_report.php?' . api_get_cidreq() . '">' .
+                Display :: return_icon('reporting32.png', get_lang('Tracking')) . get_lang('Tracking') . '</a>';
     return $return;
 }
 
@@ -91,15 +84,24 @@ function lp_upload_quiz_main() {
     // variable initialisation
     $lp_id = Security::remove_XSS($_GET['lp_id']);
 
-    $form = new FormValidator('upload', 'POST', api_get_self() . '?' . api_get_cidreq() . '&lp_id=' . $lp_id, '', array('enctype' => 'multipart/form-data'));
+    $form = new FormValidator('upload', 'POST', api_get_self() . '?' . api_get_cidreq() . '&lp_id='.$lp_id, '', array('enctype' => 'multipart/form-data'));
     $form->addElement('header', get_lang('ImportExcelQuiz'));
     $form->addElement('file', 'user_upload_quiz', get_lang('FileUpload'));
 
-    $link = '<a href="../exercice/quiz_template.xls">'.Display::return_icon('export_excel.png', get_lang('DownloadExcelTemplate'),null,16).get_lang('DownloadExcelTemplate');
-
+    $link = '<a href="../exercice/quiz_template.xls">'.
+             Display::return_icon('export_excel.png', get_lang('DownloadExcelTemplate')).get_lang('DownloadExcelTemplate').'</a>';
     $form->addElement('advanced_settings', $link);
 
-    //button send document
+    $form->addElement('checkbox', 'user_custom_score', null, get_lang('UseCustomScoreForAllQuestions'), array('id'=> 'user_custom_score'));
+
+    $form->addElement('html', '<div id="options" style="display:none">');
+    $form->addElement('text', 'correct_score', get_lang('CorrectScore'));
+    $form->addElement('text', 'incorrect_score', get_lang('IncorrectScore'));
+    $form->addElement('html', '</div>');
+
+    $form->addRule('user_upload_quiz', get_lang('ThisFieldIsRequired'), 'required');
+
+    $form->add_progress_bar();
     $form->addElement('style_submit_button', 'submit_upload_quiz', get_lang('Send'), 'class="upload"');
 
     // Display the upload field
@@ -110,16 +112,21 @@ function lp_upload_quiz_main() {
  * Handles a given Excel spreadsheets as in the template provided
  */
 function lp_upload_quiz_action_handling() {
-    global $_course, $debug;
+    global $debug;
+    $_course = api_get_course_info();
+
     if (!isset($_POST['submit_upload_quiz'])) {
         return;
     }
+
     // Get the extension of the document.
     $path_info = pathinfo($_FILES['user_upload_quiz']['name']);
+
     // Check if the document is an Excel document
     if ($path_info['extension'] != 'xls') {
         return;
     }
+
     // Read the Excel document
     $data = new Spreadsheet_Excel_Reader();
     // Set output Encoding.
@@ -127,6 +134,17 @@ function lp_upload_quiz_action_handling() {
     // Reading the xls document.
     $data->read($_FILES['user_upload_quiz']['tmp_name']);
 
+    $correctScore = isset($_POST['correct_score']) ? $_POST['correct_score'] : null;
+    $incorrectScore = isset($_POST['incorrect_score']) ? $_POST['incorrect_score'] : null;
+    $useCustomScore = isset($_POST['user_custom_score']) ? true : false;
+
+    $propagateNegative = 0;
+    if ($useCustomScore && !empty($incorrectScore)) {
+        if ($incorrectScore < 0) {
+            $propagateNegative = 1;
+        }
+    }
+
     // Variables
     $quiz_index = 0;
     $question_title_index = array();
@@ -137,7 +155,7 @@ function lp_upload_quiz_action_handling() {
     $feedback_false_index = array();
     $number_questions = 0;
     $question_description_index = array();
-    // Reading all the first column items sequencially to create breakpoints
+    // Reading all the first column items sequentially to create breakpoints
     for ($i = 1; $i <= $data->sheets[0]['numRows']; $i++) {
         if ($data->sheets[0]['cells'][$i][1] == 'Quiz' && $i == 1) {
             $quiz_index = $i; // Quiz title position, only occurs once
@@ -155,18 +173,18 @@ function lp_upload_quiz_action_handling() {
         } elseif ($data->sheets[0]['cells'][$i][1] == 'EnrichQuestion') {
             $question_description_index[] = $i;
         }
-
     }
+
     // Variables
     $quiz = array();
     $question = array();
-    $answer = array();
     $new_answer = array();
     $score_list = array();
     $feedback_true_list = array();
     $feedback_false_list = array();
     $question_description = array();
-    // Get questions
+
+    // Getting questions.
     $k = $z = $q = $l = $m = 0;
     for ($i = 1; $i <= $data->sheets[0]['numRows']; $i++) {
         if (is_array($data->sheets[0]['cells'][$i])) {
@@ -183,22 +201,28 @@ function lp_upload_quiz_action_handling() {
             $column_data = '';
         }
         // Fill quiz data
-        if ($quiz_index == $i) { // The title always in the first position
+        if ($quiz_index == $i) {
+            // The title always in the first position
             $quiz = $column_data;
         } elseif (in_array($i, $question_title_index)) {
-            $question[$k] = $column_data; //a complete line where 1st column is 'Question'
+            //a complete line where 1st column is 'Question'
+            $question[$k] = $column_data;
             $k++;
         } elseif (in_array($i, $score_index)) {
-            $score_list[$z] = $column_data; //a complete line where 1st column is 'Score'
+            //a complete line where 1st column is 'Score'
+            $score_list[$z] = $column_data;
             $z++;
         } elseif (in_array($i, $feedback_true_index)) {
-            $feedback_true_list[$q] = $column_data;//a complete line where 1st column is 'FeedbackTrue'
+            //a complete line where 1st column is 'FeedbackTrue'
+            $feedback_true_list[$q] = $column_data;
             $q++;
         } elseif (in_array($i, $feedback_false_index)) {
-            $feedback_false_list[$l] = $column_data;//a complete line where 1st column is 'FeedbackFalse' for wrong answers
+            //a complete line where 1st column is 'FeedbackFalse' for wrong answers
+            $feedback_false_list[$l] = $column_data;
             $l++;
         } elseif (in_array($i, $question_description_index)) {
-            $question_description[$m] = $column_data; //a complete line where 1st column is 'EnrichQuestion'
+            //a complete line where 1st column is 'EnrichQuestion'
+            $question_description[$m] = $column_data;
             $m++;
         }
     }
@@ -223,49 +247,67 @@ function lp_upload_quiz_action_handling() {
         }
     }
 
-    $quiz_title = $quiz[2]; // Quiz title
+    // Quiz title.
+    $quiz_title = $quiz[2];
 
     if ($quiz_title != '') {
         // Variables
         $type = 2;
         $random = $active = $results = $max_attempt = $expired_time = 0;
-        //make sure feedback is enabled (3 to disable), otherwise the fields
+        // Make sure feedback is enabled (3 to disable), otherwise the fields
         // added to the XLS are not shown, which is confusing
         $feedback = 0;
+
         // Quiz object
-        $quiz_object = new Exercise();
-        $quiz_id = $quiz_object->create_quiz($quiz_title, $expired_time, $type, $random, $active, $results, $max_attempt, $feedback);
+        $exercise = new Exercise();
+        //
+        $quiz_id = $exercise->createExercise(
+            $quiz_title,
+            $expired_time,
+            $type,
+            $random,
+            $active,
+            $results,
+            $max_attempt,
+            $feedback,
+            $propagateNegative
+        );
 
         if ($quiz_id) {
 
             // insert into the item_property table
             api_item_property_update($_course, TOOL_QUIZ, $quiz_id, 'QuizAdded', api_get_user_id());
 
-            // Import questions
+            // Import questions.
             for ($i = 0; $i < $number_questions; $i++) {
-                // Create questions
-
-
-                $question_title = $question[$i][2]; // Question name
+                // Question name
+                $question_title = $question[$i][2];
                 $question_description_text = "<p></p>";
                 if (isset($question_description[$i][2])) {
-                    $question_description_text =  "<p>".$question_description[$i][2]."</p>"; // Question description, if any
+                    // Question description.
+                    $question_description_text =  "<p>".$question_description[$i][2]."</p>";
                 }
 
                 // Unique answers are the only question types available for now
                 // through xls-format import
-                $unique_answer = new UniqueAnswer();
+                $uniqueAnswer = new UniqueAnswer();
                 if ($question_title != '') {
-                    $question_id = $unique_answer->create_question($quiz_id, $question_title, $question_description_text);
+                    $question_id = $uniqueAnswer->create_question(
+                        $quiz_id,
+                        $question_title,
+                        $question_description_text
+                    );
                 }
+
                 if (is_array($new_answer[$i])) {
                     $id = 1;
                     $answers_data = $new_answer[$i];
+
                     foreach ($answers_data as $answer_data) {
                         $answer = $answer_data[2];
                         $correct = 0;
                         $score = 0;
-                        $comment = '';
+
                         if (strtolower($answer_data[3]) == 'x') {
                             $correct = 1;
                             $score = $score_list[$i][3];
@@ -273,15 +315,25 @@ function lp_upload_quiz_action_handling() {
                         } else {
                             $comment = $feedback_false_list[$i][2];
                         }
-                        /*
-                        if ($id == 1) {
-                            $comment = $feedback_true_list[$i][2];
-                        } elseif ($id == 2) {
-                            $comment = $feedback_false_list[$i][2];
+
+                        if ($useCustomScore) {
+                            if ($correct) {
+                                $score = $correctScore;
+                            } else {
+                                $score = $incorrectScore;
+                            }
                         }
-                        */
-                        // Create answer
-                        $unique_answer->create_answer($id, $question_id, $answer, $comment, $score, $correct);
+
+                        // Add answer.
+                        $uniqueAnswer->addAnswer(
+                            $id,
+                            $question_id,
+                            $answer,
+                            $comment,
+                            $score,
+                            $correct
+                        );
+
                         $id++;
                     }
                 }
@@ -306,22 +358,21 @@ function lp_upload_quiz_action_handling() {
                     Session::erase('lpobject');
                 } else {
                     $_SESSION['oLP'] = $oLP;
-                    $lp_found = true;
                 }
             }
         }
-        if (isset($_SESSION['oLP']) && isset($_GET['lp_id'])) {
 
+        if (isset($_SESSION['oLP']) && isset($_GET['lp_id'])) {
             $previous = $_SESSION['oLP']->select_previous_item_id();
             $parent = 0;
             // Add a Quiz as Lp Item
-            $_SESSION['oLP']->add_item($parent, $previous, TOOL_QUIZ, $quiz_id, ($quiz_title), '');
+            $_SESSION['oLP']->add_item($parent, $previous, TOOL_QUIZ, $quiz_id, $quiz_title, '');
             // Redirect to home page for add more content
-            header('location: ../newscorm/lp_controller.php?' . api_get_cidreq() . '&action=add_item&type=step&lp_id=' . Security::remove_XSS($_GET['lp_id']).'&session_id='.api_get_session_id());
+            header('location: ../newscorm/lp_controller.php?'.api_get_cidreq().'&action=add_item&type=step&lp_id='.Security::remove_XSS($_GET['lp_id']));
             exit;
         } else {
             //  header('location: exercice.php?' . api_get_cidreq());
-            echo '<script>window.location.href = "admin.php?'.api_get_cidReq().'&exerciseId='.$quiz_id.'&session_id='.api_get_session_id().'"</script>';
+            echo '<script>window.location.href = "'.api_get_path(WEB_CODE_PATH).'exercice/admin.php?'.api_get_cidReq().'&exerciseId='.$quiz_id.'&session_id='.api_get_session_id().'"</script>';
         }
     }
 }

+ 12 - 2
main/forum/forumfunction.inc.php

@@ -3598,6 +3598,8 @@ function display_forum_search_results($search_term)
     $table_forums = Database :: get_course_table(TABLE_FORUM);
     $table_threads = Database :: get_course_table(TABLE_FORUM_THREAD);
     $table_posts = Database :: get_course_table(TABLE_FORUM_POST);
+    $table_item_property = Database :: get_course_table(TABLE_ITEM_PROPERTY);
+    $session_id = api_get_session_id();
 
     $gradebook = Security::remove_XSS($_GET['gradebook']);
 
@@ -3616,8 +3618,16 @@ function display_forum_search_results($search_term)
                                     OR posts.post_text LIKE '%".Database::escape_string(trim($value))."%')";
     }
 
-    $sql = "SELECT * FROM $table_posts posts
-                WHERE c_id = $course_id AND ".implode(' AND ', $search_restriction)."
+    $sql = "SELECT posts.* FROM $table_posts posts, $table_threads threads, $table_item_property item_property
+                WHERE posts.c_id = $course_id
+                AND item_property.c_id = $course_id
+                AND posts.thread_id = threads.thread_id
+                AND item_property.ref = threads.thread_id
+                AND item_property.visibility = 1
+                AND item_property.id_session = $session_id
+                AND posts.visible = 1
+                AND item_property.tool = '".TOOL_FORUM_THREAD."'
+                AND ".implode(' AND ', $search_restriction)."
                 GROUP BY posts.post_id";
 
     // Getting all the information of the forum categories.

+ 5 - 1
main/gradebook/gradebook_add_link.php

@@ -29,8 +29,12 @@ $tbl_link = Database::get_main_table(TABLE_MAIN_GRADEBOOK_LINK);
 
 $session_id = api_get_session_id();
 $typeSelected = isset($_GET['typeselected']) ? intval($_GET['typeselected']) : null;
-$all_categories = Category :: load(null, null, api_get_course_id(), null, null, $session_id);
 
+if ($session_id == 0) {
+    $all_categories = Category :: load(null, null, api_get_course_id(), null, null, $session_id);
+} else {
+    $all_categories = Category :: load_session_categories(null, $session_id);
+}
 $category = Category :: load($_GET['selectcat']);
 $url = api_get_self().'?selectcat='.Security::remove_XSS($_GET['selectcat']).'&newtypeselected='.$typeSelected.'&course_code='.api_get_course_id();
 $typeform = new LinkForm(LinkForm :: TYPE_CREATE, $category[0], null, 'create_link', null, $url, $typeSelected);

+ 6 - 1
main/gradebook/gradebook_edit_link.php

@@ -33,7 +33,12 @@ if ($link->is_locked() && !api_is_platform_admin()) {
 $linkcat  = isset($_GET['selectcat']) ? Security::remove_XSS($_GET['selectcat']):'';
 $linkedit = isset($_GET['editlink']) ? Security::remove_XSS($_GET['editlink']):'';
 
-$cats = Category :: load(null, null, $course_code, null, null, $session_id, false); //already init
+$session_id = api_get_session_id();
+if ($session_id == 0) {
+    $cats = Category :: load(null, null, $course_code, null, null, $session_id, false); //already init
+} else {
+    $cats = Category :: load_session_categories(null, $session_id);
+}
 
 $form = new LinkAddEditForm(LinkAddEditForm :: TYPE_EDIT, $cats, null, $link, 'edit_link_form', api_get_self() . '?selectcat=' . $linkcat. '&editlink=' . $linkedit);
 if ($form->validate()) {

+ 32 - 16
main/gradebook/index.php

@@ -119,11 +119,19 @@ $filter_confirm_msg = true;
 $filter_warning_msg = true;
 
 ///direct access to one evaluation
-$cats = Category :: load(null, null, $course_code, null, null, $session_id, false); //already init
+$catsResult = array();
+if (api_get_session_id() != 0) {
+    $session_id = api_get_session_id();
+    $cats = Category :: load_session_categories(null, $session_id); //already init
+    $catsResult = $cats;
+} else {
+    $cats = Category :: load(null, null, $course_code, null, null, null, false);
+}
 $first_time = null;
+
 if (empty($cats)) {
-	$cats = Category :: load(0, null, $course_code, null, null, $session_id, false);//first time
-	$first_time=1;
+    $cats = Category :: load(0, null, $course_code, null, null, $session_id, false);//first time
+    $first_time = 1;
 }
 $_GET['selectcat'] = $cats[0]->get_id();
 
@@ -133,7 +141,7 @@ if (isset($_GET['isStudentView'])) {
 	}
 }
 
-if ( (isset($_GET['selectcat']) && $_GET['selectcat']>0) && (isset($_SESSION['studentview']) && $_SESSION['studentview']=='studentview') ) {
+if ((isset($_GET['selectcat']) && $_GET['selectcat']>0) && (isset($_SESSION['studentview']) && $_SESSION['studentview']=='studentview')) {
 	Display :: display_header();
 
 	//Introduction tool: student view
@@ -819,20 +827,28 @@ if (isset($first_time) && $first_time==1 && api_is_allowed_to_edit(null,true)) {
             }
         }
 
-		$i = 0;
-        /** @var Category $cat **/
+        $i = 0;
+        $allcat = array();
         foreach ($cats as $cat) {
-			$allcat  = $cat->get_subcategories($stud_id, $course_code, $session_id);
-			$alleval = $cat->get_evaluations($stud_id);
-			$alllink = $cat->get_links($stud_id);
-
-			if ($cat->get_parent_id() != 0) {
-				$i++;
-			} else {
-
-				// This is the father
-				// Create gradebook/add gradebook links.
+            if ($session_id != 0) {
+                $allcatSession = $catsResult;
+                foreach ($allcatSession as $catSession) {
+                    if ($catSession->get_parent_id() == 0) {
+                        continue;    
+                    }
+                    $allcat[] = $catSession;
+                }
+            } else {
+                $allcat  = $cat->get_subcategories($stud_id, $course_code, $session_id);
+            }
+            $alleval = $cat->get_evaluations($stud_id);
+            $alllink = $cat->get_links($stud_id,true);
 
+            if ($cat->get_parent_id() != 0) {
+                $i++;
+            } else {
+                // This is the father
+                // Create gradebook/add gradebook links.
                 DisplayGradebook::display_header_gradebook(
                     $cat,
                     0,

+ 17 - 7
main/gradebook/lib/be/category.class.php

@@ -169,18 +169,28 @@ class Category implements GradebookItem
             $cats[] = Category::create_root_category();
             return $cats;
         }
-        $cat = array();
+        $courseCode = api_get_course_info(api_get_course_id());
+        $courseCode = $courseCode['code'];
+        
         $cats = array();
         if (!empty ($session_id)) {
              $tbl_grade_categories = Database :: get_main_table(TABLE_MAIN_GRADEBOOK_CATEGORY);
-             $sql_session = 'SELECT id FROM '.$tbl_grade_categories. ' WHERE session_id = '.$session_id;
+             $sql_session = 'SELECT id, course_code FROM '.$tbl_grade_categories. ' WHERE session_id = '.(int) $session_id;
              $result_session = Database::query($sql_session);
              if (Database::num_rows($result_session) > 0) {
-                 $data_session = Database::fetch_array($result_session);
-                 $parent_id = $data_session['id'];
-                 $cat = Category::load($parent_id);
-                 $cats = Category::load(null, null, null, $parent_id, null, null, $order);
-                 return array_merge($cat,$cats);
+                $cat = array();                  
+                while ($data_session = Database::fetch_array($result_session)) {
+                    
+                    $parent_id = $data_session['id'];
+                    if ($data_session['course_code'] == $courseCode) {             
+                        $cat = Category::load($parent_id);
+                        $cats = Category::load(null,null,null,$parent_id,null,null,null);
+                        //$cat = array_merge($cat,$cats);
+                    }
+                }  
+               
+               
+                return array_merge($cat,$cats);
              }
          }
      }

+ 2 - 2
main/group/example.csv

@@ -1,5 +1,5 @@
 "category";"group";"description";"announcements_state";"calendar_state";"chat_state";"doc_state";"forum_state";"work_state";"wiki_state";"max_student";"self_reg_allowed";"self_unreg_allowed";"groups_per_user";
 "Category 1";"";"This is a category";"2";"2";"2";"2";"2";"2";"2";"0";"0";"0";"0";
-"";"This is a group with no category";"";"2";"2";"2";"2";"2";"2";"2";"0";"0";"0"
-"Category 1";"This is a group in a Category 1";"";"2";"2";"2";"2";"2";"2";"2";"0";"0";"0"
+"";"Group 1";"This is a group with no category";"2";"2";"2";"2";"2";"2";"2";"0";"0";"0"
+"Category 1";"Group 2";"This is a group in a category 1";"2";"2";"2";"2";"2";"2";"2";"0";"0";"0"
 

+ 15 - 14
main/group/group.php

@@ -20,7 +20,8 @@ $language_file = 'group';
 
 require_once '../inc/global.inc.php';
 
-$is_allowed_in_course = api_is_allowed_to_edit(false, true);
+$is_allowed_in_course = api_is_allowed_in_course();
+$userId = api_get_user_id();
 
 $this_section = SECTION_COURSES;
 $current_course_tool  = TOOL_GROUP;
@@ -64,34 +65,34 @@ Display::display_introduction_section(TOOL_GROUP);
  * Self-registration and un-registration
  */
 $my_group_id = isset($_GET['group_id']) ? intval($_GET['group_id']) : null;
-$my_msg	  = isset($_GET['msg']) ? Security::remove_XSS($_GET['msg']) : null;
-$my_group    = isset($_REQUEST['group']) ? Security::remove_XSS($_REQUEST['group']) : null;
-$my_get_id1  = isset($_GET['id1']) ? Security::remove_XSS($_GET['id1']) : null;
-$my_get_id2  = isset($_GET['id2']) ? Security::remove_XSS($_GET['id2']) : null;
-$my_get_id   = isset($_GET['id']) ? Security::remove_XSS($_GET['id']) : null;
+$my_msg	= isset($_GET['msg']) ? Security::remove_XSS($_GET['msg']) : null;
+$my_group = isset($_REQUEST['group']) ? Security::remove_XSS($_REQUEST['group']) : null;
+$my_get_id1 = isset($_GET['id1']) ? Security::remove_XSS($_GET['id1']) : null;
+$my_get_id2 = isset($_GET['id2']) ? Security::remove_XSS($_GET['id2']) : null;
+$my_get_id  = isset($_GET['id']) ? Security::remove_XSS($_GET['id']) : null;
 
 if (isset($_GET['action']) && $is_allowed_in_course) {
     switch ($_GET['action']) {
         case 'self_reg':
-            if (GroupManager :: is_self_registration_allowed($_SESSION['_user']['user_id'], $my_group_id)) {
-                GroupManager :: subscribe_users($_SESSION['_user']['user_id'], $my_group_id);
+            if (GroupManager::is_self_registration_allowed($userId, $my_group_id)) {
+                GroupManager::subscribe_users($userId, $my_group_id);
                 Display :: display_confirmation_message(get_lang('GroupNowMember'));
             }
             break;
         case 'self_unreg':
-            if (GroupManager :: is_self_unregistration_allowed($_SESSION['_user']['user_id'], $my_group_id)) {
-                GroupManager :: unsubscribe_users($_SESSION['_user']['user_id'], $my_group_id);
+            if (GroupManager::is_self_unregistration_allowed($userId, $my_group_id)) {
+                GroupManager::unsubscribe_users($userId, $my_group_id);
                 Display :: display_confirmation_message(get_lang('StudentDeletesHimself'));
             }
             break;
         case 'show_msg':
-            Display :: display_confirmation_message($my_msg);
+            Display::display_confirmation_message($my_msg);
             break;
         case 'warning_message':
-            Display :: display_warning_message($my_msg);
+            Display::display_warning_message($my_msg);
             break;
         case 'success_message':
-            Display :: display_confirmation_message($my_msg);
+            Display::display_confirmation_message($my_msg);
             break;
     }
 }
@@ -107,7 +108,7 @@ if (api_is_allowed_to_edit(false, true)) {
         switch ($_POST['action']) {
             case 'delete_selected':
                 if (is_array($_POST['group'])) {
-                    GroupManager :: delete_groups($my_group);
+                    GroupManager::delete_groups($my_group);
                     Display :: display_confirmation_message(get_lang('SelectedGroupsDeleted'));
                 }
                 break;

+ 32 - 18
main/group/group_category.php

@@ -15,7 +15,12 @@ $current_course_tool  = TOOL_GROUP;
 // Notice for unauthorized people.
 api_protect_course_script(true);
 
-if (!api_is_allowed_to_edit(false,true) || !(isset ($_GET['id']) || isset ($_POST['id']) || isset ($_GET['action']) || isset ($_POST['action']))) {
+if (!api_is_allowed_to_edit(false,true) ||
+    !(isset ($_GET['id']) ||
+    isset ($_POST['id']) ||
+    isset ($_GET['action']) ||
+    isset ($_POST['action']))
+) {
 	api_not_allowed();
 }
 
@@ -141,20 +146,17 @@ if (api_get_setting('allow_group_categories') == 'true') {
 }
 
 $form->addElement('header', get_lang('DefaultSettingsForNewGroups'));
-// Action
 $form->addElement('hidden', 'action');
-
-
 $form->addElement('html', '<div class="span6">');
 
 // Self registration
 $group = array(
-    $form->createElement('checkbox', 'self_registration_allowed', get_lang('GroupSelfRegistration'), get_lang('GroupAllowStudentRegistration'), 1),
-    $form->createElement('checkbox', 'self_unregistration_allowed', null, get_lang('GroupAllowStudentUnregistration'), 1)
+    $form->createElement('checkbox', 'self_reg_allowed', get_lang('GroupSelfRegistration'), get_lang('GroupAllowStudentRegistration'), 1),
+    $form->createElement('checkbox', 'self_unreg_allowed', null, get_lang('GroupAllowStudentUnregistration'), 1)
 );
 $form->addGroup($group, '', Display::return_icon('user.png', get_lang('GroupSelfRegistration'), array(), ICON_SIZE_SMALL).' '.get_lang('GroupSelfRegistration'), '', false);
 
-// Documents settings
+// Documents settings.
 $group = array(
     $form->createElement('radio', 'doc_state', get_lang('GroupDocument'), get_lang('NotAvailable'), GroupManager::TOOL_NOT_AVAILABLE),
     $form->createElement('radio', 'doc_state', null, get_lang('Public'), GroupManager::TOOL_PUBLIC),
@@ -162,7 +164,7 @@ $group = array(
 );
 $form->addGroup($group, '', Display::return_icon('folder.png', get_lang('GroupDocument'), array(), ICON_SIZE_SMALL).' '.get_lang('GroupDocument'), '', false);
 
-// Work settings
+// Work settings.
 $group = array(
     $form->createElement('radio', 'work_state', get_lang('GroupWork'), get_lang('NotAvailable'), GroupManager::TOOL_NOT_AVAILABLE),
     $form->createElement('radio', 'work_state', null, get_lang('Public'), GroupManager::TOOL_PUBLIC),
@@ -170,8 +172,7 @@ $group = array(
 );
 $form->addGroup($group, '', Display::return_icon('work.png', get_lang('GroupWork'), array(), ICON_SIZE_SMALL).' '.get_lang('GroupWork'), '', false);
 
-
-// Calendar settings
+// Calendar settings.
 $group = array(
     $form->createElement('radio', 'calendar_state', get_lang('GroupCalendar'), get_lang('NotAvailable'), GroupManager::TOOL_NOT_AVAILABLE),
     $form->createElement('radio', 'calendar_state', null, get_lang('Public'), GroupManager::TOOL_PUBLIC),
@@ -179,11 +180,10 @@ $group = array(
 );
 $form->addGroup($group, '', Display::return_icon('agenda.png', get_lang('GroupCalendar'), array(), ICON_SIZE_SMALL).' '.get_lang('GroupCalendar'), '', false);
 
-
 $form->addElement('html', '</div>');
 $form->addElement('html', '<div class="span6">');
 
-// Announcements settings
+// Announcements settings.
 $group = array(
     $form->createElement('radio', 'announcements_state', get_lang('GroupAnnouncements'), get_lang('NotAvailable'), GroupManager::TOOL_NOT_AVAILABLE),
     $form->createElement('radio', 'announcements_state', null, get_lang('Public'), GroupManager::TOOL_PUBLIC),
@@ -191,7 +191,7 @@ $group = array(
 );
 $form->addGroup($group, '', Display::return_icon('announce.png', get_lang('GroupAnnouncements'), array(), ICON_SIZE_SMALL).' '.get_lang('GroupAnnouncements'), '', false);
 
-// Forum settings
+// Forum settings.
 $group = array(
     $form->createElement('radio', 'forum_state', get_lang('GroupForum'), get_lang('NotAvailable'), GroupManager::TOOL_NOT_AVAILABLE),
     $form->createElement('radio', 'forum_state', null, get_lang('Public'), GroupManager::TOOL_PUBLIC),
@@ -199,7 +199,7 @@ $group = array(
 );
 $form->addGroup($group, '', Display::return_icon('forum.png', get_lang('GroupForum'), array(), ICON_SIZE_SMALL).' '.get_lang('GroupForum'), '', false);
 
-// Wiki settings
+// Wiki settings.
 $group = array(
     $form->createElement('radio', 'wiki_state', get_lang('GroupWiki'), get_lang('NotAvailable'), GroupManager::TOOL_NOT_AVAILABLE),
     $form->createElement('radio', 'wiki_state', null, get_lang('Public'), GroupManager::TOOL_PUBLIC),
@@ -207,7 +207,7 @@ $group = array(
 );
 $form->addGroup($group, '', Display::return_icon('wiki.png', get_lang('GroupWiki'), array(), ICON_SIZE_SMALL).' '.get_lang('GroupWiki'), '', false);
 
-// Chat settings
+// Chat settings.
 $group = array(
     $form->createElement('radio', 'chat_state', get_lang('Chat'), get_lang('NotAvailable'), GroupManager::TOOL_NOT_AVAILABLE),
     $form->createElement('radio', 'chat_state', null, get_lang('Public'), GroupManager::TOOL_PUBLIC),
@@ -215,9 +215,7 @@ $group = array(
 );
 $form->addGroup($group, '', Display::return_icon('chat.png', get_lang('Chat'), array(), ICON_SIZE_SMALL).' '.get_lang('Chat'), '', false);
 
-
 $form->addElement('html', '</div>');
-
 $form->addElement('html', '<div class="span12">');
 
 // Submit
@@ -231,8 +229,10 @@ if ($form->validate()) {
 	} else {
 		$max_member = $values['max_member'];
 	}
+
 	$self_reg_allowed = isset($values['self_reg_allowed']) ? $values['self_reg_allowed'] : 0;
 	$self_unreg_allowed = isset($values['self_unreg_allowed']) ? $values['self_unreg_allowed'] : 0;
+
 	switch ($values['action']) {
 		case 'update_settings':
 			GroupManager::update_category(
@@ -255,7 +255,21 @@ if ($form->validate()) {
 			header('Location: group.php?action=show_msg&msg='.$msg.'&category='.$values['id']);
 			break;
 		case 'add_category':
-			GroupManager :: create_category($values['title'], $values['description'], $values['doc_state'], $values['work_state'], $values['calendar_state'], $values['announcements_state'], $values['forum_state'], $values['wiki_state'], $values['chat_state'], $self_reg_allowed, $self_unreg_allowed, $max_member, $values['groups_per_user']);
+			GroupManager :: create_category(
+                $values['title'],
+                $values['description'],
+                $values['doc_state'],
+                $values['work_state'],
+                $values['calendar_state'],
+                $values['announcements_state'],
+                $values['forum_state'],
+                $values['wiki_state'],
+                $values['chat_state'],
+                $self_reg_allowed,
+                $self_unreg_allowed,
+                $max_member,
+                $values['groups_per_user']
+            );
 			$msg = urlencode(get_lang('CategoryCreated'));
 			header('Location: group.php?action=show_msg&msg='.$msg);
 			break;

+ 10 - 4
main/group/group_creation.php

@@ -17,10 +17,9 @@ $current_course_tool  = TOOL_GROUP;
 // Notice for unauthorized people.
 api_protect_course_script(true);
 
-
 /*	Create the groups */
 
-if (isset ($_POST['action'])) {
+if (isset($_POST['action'])) {
     switch ($_POST['action']) {
         case 'create_groups':
             $groups = array();
@@ -45,7 +44,13 @@ if (isset ($_POST['action'])) {
                 } elseif ($_POST['same_category']) {
                     $group['category'] = $_POST['group_0_category'];
                 }
-                GroupManager :: create_group($group['name'], $group['category'], $group['tutor'], $group['places']);
+
+                GroupManager::create_group(
+                    $group['name'],
+                    $group['category'],
+                    $group['tutor'],
+                    $group['places']
+                );
             }
             $msg = urlencode(count($groups).' '.get_lang('GroupsAdded'));
             header('Location: group.php?action=show_msg&msg='.$msg);
@@ -126,7 +131,7 @@ elseif (isset($_POST['number_of_groups'])) {
     </script>
     <?php
 		}
-		$group_categories = GroupManager :: get_categories();
+		$group_categories = GroupManager::get_categories();
 		$group_id = GroupManager :: get_number_of_groups() + 1;
 		foreach ($group_categories as $index => $category) {
 			// Don't allow new groups in the virtual course category!
@@ -226,6 +231,7 @@ EOT;
 	} else {
 		echo get_lang('NoCategoriesDefined');
 	}
+
 	/*
 	 * Show form to generate subgroups
 	 */

+ 2 - 2
main/group/group_edit.php

@@ -286,8 +286,8 @@ if ($form->validate()) {
 
     GroupManager::set_group_properties(
         $current_group['id'],
-        strip_tags($values['name']),
-        strip_tags($values['description']),
+        $values['name'],
+        $values['description'],
         $max_member,
         $values['doc_state'],
         $values['work_state'],

+ 26 - 8
main/group/group_space.php

@@ -60,7 +60,8 @@ if ($current_group['doc_state'] != 1 &&
     $current_group['chat_state'] != 1 &&
     $forum_state_public != 1
 ) {
-	if (!api_is_allowed_to_edit(null,true) && !GroupManager::is_user_in_group($user_id, $group_id)) {
+	if (!api_is_allowed_to_edit(null,true) &&
+        !GroupManager::is_user_in_group($user_id, $group_id)) {
 		api_not_allowed($print_headers);
 	}
 }
@@ -90,6 +91,7 @@ if (!empty($_GET['selfUnReg']) && GroupManager :: is_self_unregistration_allowed
     GroupManager :: unsubscribe_users($user_id, $current_group['id']);
     Display::display_normal_message(get_lang('StudentDeletesHimself'));
 }
+
 echo '<div class="actions">';
 echo '<a href="group.php">'.Display::return_icon('back.png',get_lang('BackToGroupList'),'',ICON_SIZE_MEDIUM).'</a>';
 
@@ -98,7 +100,8 @@ echo '<a href="group.php">'.Display::return_icon('back.png',get_lang('BackToGrou
  */
 $subscribe_group = '';
 if (GroupManager :: is_self_registration_allowed($user_id, $current_group['id'])) {
-	$subscribe_group = '<a class="btn" href="'.api_get_self().'?selfReg=1&amp;group_id='.$current_group['id'].'" onclick="javascript: if(!confirm('."'".addslashes(api_htmlentities(get_lang("ConfirmYourChoice"), ENT_QUOTES))."'".')) return false;">'.get_lang("RegIntoGroup").'</a>';
+	$subscribe_group = '<a class="btn" href="'.api_get_self().'?selfReg=1&amp;group_id='.$current_group['id'].'" onclick="javascript: if(!confirm('."'".addslashes(api_htmlentities(get_lang("ConfirmYourChoice"), ENT_QUOTES))."'".')) return false;">'.
+        get_lang("RegIntoGroup").'</a>';
 }
 
 /*
@@ -106,7 +109,8 @@ if (GroupManager :: is_self_registration_allowed($user_id, $current_group['id'])
  */
 $unsubscribe_group = '';
 if (GroupManager :: is_self_unregistration_allowed($user_id, $current_group['id'])) {
-	$unsubscribe_group = '<a class="btn" href="'.api_get_self().'?selfUnReg=1" onclick="javascript: if(!confirm('."'".addslashes(api_htmlentities(get_lang("ConfirmYourChoice"),ENT_QUOTES))."'".')) return false;">'.get_lang("StudentUnsubscribe").'</a>';
+	$unsubscribe_group = '<a class="btn" href="'.api_get_self().'?selfUnReg=1" onclick="javascript: if(!confirm('."'".addslashes(api_htmlentities(get_lang("ConfirmYourChoice"),ENT_QUOTES))."'".')) return false;">'.
+        get_lang("StudentUnsubscribe").'</a>';
 }
 echo '&nbsp;</div>';
 
@@ -121,12 +125,17 @@ if (isset($_GET['action'])) {
 /*	Main Display Area */
 
 $course_code = api_get_course_id();
-$is_course_member = CourseManager :: is_user_subscribed_in_real_or_linked_course(api_get_user_id(), $course_code);
+$is_course_member = CourseManager::is_user_subscribed_in_real_or_linked_course(
+    api_get_user_id(),
+    $course_code
+);
 
 // Edit the group.
 
 $edit_url = '';
-if (api_is_allowed_to_edit(false, true) or GroupManager :: is_tutor_of_group(api_get_user_id(), api_get_group_id())) {
+if (api_is_allowed_to_edit(false, true) or
+    GroupManager::is_tutor_of_group(api_get_user_id(), api_get_group_id())
+) {
     $my_origin = isset($origin) ? $origin : '';
     $edit_url =  '<a href="'.api_get_path(WEB_CODE_PATH).'group/settings.php?cidReq='.api_get_course_id().'&origin='.$my_origin.'&gidReq='.api_get_group_id().'">'.
         Display::return_icon('edit.png', get_lang('EditGroup'),'',ICON_SIZE_SMALL).'</a>';
@@ -144,7 +153,9 @@ if (!empty($current_group['description'])) {
  * Group Tools
  */
 // If the user is subscribed to the group or the user is a tutor of the group then
-if (api_is_allowed_to_edit(false, true) OR GroupManager :: is_user_in_group(api_get_user_id(), $current_group['id'])) {
+if (api_is_allowed_to_edit(false, true) OR
+    GroupManager::is_user_in_group(api_get_user_id(), $current_group['id'])
+) {
     $actions_array = array();
     // Link to the forum of this group
     $forums_of_groups = get_forums_of_group($current_group['id']);
@@ -152,7 +163,12 @@ if (api_is_allowed_to_edit(false, true) OR GroupManager :: is_user_in_group(api_
 	if (is_array($forums_of_groups)) {
 		if ($current_group['forum_state'] != GroupManager::TOOL_NOT_AVAILABLE ) {
 			foreach ($forums_of_groups as $key => $value) {
-				if ($value['forum_group_public_private'] == 'public' || (/*!empty($user_subscribe_to_current_group) && */ $value['forum_group_public_private'] == 'private') || !empty($user_is_tutor) || api_is_allowed_to_edit(false, true)) {
+                //*!empty($user_subscribe_to_current_group) && */
+				if ($value['forum_group_public_private'] == 'public' ||
+                    ($value['forum_group_public_private'] == 'private') ||
+                    !empty($user_is_tutor) ||
+                    api_is_allowed_to_edit(false, true)
+                ) {
                     $actions_array[] = array(
                         'url' => '../forum/viewforum.php?forum='.$value['forum_id'].'&gidReq='.Security::remove_XSS($current_group['id']).'&amp;origin=group',
                         'content' => Display::return_icon('forum.png', get_lang('Forum').': '.$value['forum_title'] , array(), 32)
@@ -161,7 +177,7 @@ if (api_is_allowed_to_edit(false, true) OR GroupManager :: is_user_in_group(api_
 			}
 		}
 	}
-	if ($current_group['doc_state'] != GroupManager::TOOL_NOT_AVAILABLE ) {
+	if ($current_group['doc_state'] != GroupManager::TOOL_NOT_AVAILABLE) {
 		// Link to the documents area of this group
         $actions_array[] = array(
             'url' => '../document/document.php?'.api_get_cidreq(),
@@ -222,6 +238,7 @@ if (api_is_allowed_to_edit(false, true) OR GroupManager :: is_user_in_group(api_
 
 	// Link to the forum of this group
 	$forums_of_groups = get_forums_of_group($current_group['id']);
+
 	if (is_array($forums_of_groups)) {
 		if ( $current_group['forum_state'] == GroupManager::TOOL_PUBLIC ) {
 			foreach ($forums_of_groups as $key => $value) {
@@ -234,6 +251,7 @@ if (api_is_allowed_to_edit(false, true) OR GroupManager :: is_user_in_group(api_
 			}
 		}
 	}
+
 	if ($current_group['doc_state'] == GroupManager::TOOL_PUBLIC) {
 		// Link to the documents area of this group
         $actions_array[] = array(

+ 22 - 3
main/group/import.php

@@ -39,15 +39,23 @@ if ($form->validate()) {
         $groupData = Import::csv_reader($_FILES['file']['tmp_name']);
         $deleteNotInArray = $form->getSubmitValue('delete_not_in_file') == 1 ? true : false;
 
-        $result = GroupManager::importCategoriesAndGroupsFromArray($groupData, $deleteNotInArray);
+        $result = GroupManager::importCategoriesAndGroupsFromArray(
+            $groupData,
+            $deleteNotInArray
+        );
+
         if (!empty($result)) {
             $html = null;
+
             foreach ($result as $status => $data) {
-                if (empty($data['category']) && empty($data['group'])) {
-                    continue;
+                if ($status != 'error') {
+                    if (empty($data['category']) && empty($data['group'])) {
+                        continue;
+                    }
                 }
 
                 $html .= " <h3>".get_lang(ucfirst($status)).' </h3>';
+
                 if (!empty($data['category'])) {
                     $html .= "<h4> ".get_lang('Categories').':</h4>';
                     foreach ($data['category'] as $category) {
@@ -61,7 +69,18 @@ if ($form->validate()) {
                         $html .= "<div>".$group['group']."</div>";
                     }
                 }
+
+                if ($status == 'error') {
+                    if (!empty($data)) {
+                        foreach ($data as $message) {
+                            if (!empty($message)) {
+                                $html .= "<div>".$message."</div>";
+                            }
+                        }
+                    }
+                }
             }
+
             echo $html;
         }
     }

+ 22 - 5
main/group/settings.php

@@ -24,12 +24,12 @@ $current_course_tool  = TOOL_GROUP;
 api_protect_course_script(true);
 
 $group_id = api_get_group_id();
-$current_group = GroupManager :: get_group_properties($group_id);
+$current_group = GroupManager::get_group_properties($group_id);
 
 $nameTools = get_lang('EditGroup');
 $interbreadcrumb[] = array('url' => 'group.php', 'name' => get_lang('Groups'));
 $interbreadcrumb[] = array('url' => 'group_space.php?'.api_get_cidReq(), 'name' => $current_group['name']);
-$is_group_member = GroupManager :: is_tutor_of_group(api_get_user_id(), $group_id);
+$is_group_member = GroupManager::is_tutor_of_group(api_get_user_id(), $group_id);
 
 if (!api_is_allowed_to_edit(false, true) && !$is_group_member) {
     api_not_allowed(true);
@@ -46,6 +46,16 @@ $form->addElement('html', '<div class="span6">');
 // Group name
 $form->addElement('text', 'name', get_lang('GroupName'));
 
+if (api_get_setting('allow_group_categories') == 'true') {
+    $groupCategories = GroupManager::get_categories();
+    $categoryList = array();
+    //$categoryList[] = null;
+    foreach ($groupCategories as $category) {
+        $categoryList[$category['id']] = $category['title'];
+    }
+    $form->addElement('select', 'category_id', get_lang('Category'), $categoryList);
+}
+
 // Members per group
 $group = array(
     $form->createElement('radio', 'max_member_no_limit', get_lang('GroupLimit'), get_lang('NoLimit'), GroupManager::MEMBER_PER_GROUP_NO_LIMIT),
@@ -150,11 +160,12 @@ if ($form->validate()) {
     }
     $self_registration_allowed   = isset($values['self_registration_allowed']) ? 1 : 0;
     $self_unregistration_allowed = isset($values['self_unregistration_allowed']) ? 1 : 0;
+    $categoryId = isset($values['category_id']) ? $values['category_id'] : null;
 
     GroupManager::set_group_properties(
         $current_group['id'],
-        strip_tags($values['name']),
-        strip_tags($values['description']),
+        $values['name'],
+        $values['description'],
         $max_member,
         $values['doc_state'],
         $values['work_state'],
@@ -164,7 +175,8 @@ if ($form->validate()) {
         $values['wiki_state'],
         $values['chat_state'],
         $self_registration_allowed,
-        $self_unregistration_allowed
+        $self_unregistration_allowed,
+        $categoryId
     );
     if (isset($_POST['group_members']) && count($_POST['group_members']) > $max_member && $max_member != GroupManager::MEMBER_PER_GROUP_NO_LIMIT) {
         header('Location: group.php?'.api_get_cidreq(true, false).'&action=warning_message&msg='.get_lang('GroupTooMuchMembers'));
@@ -175,6 +187,11 @@ if ($form->validate()) {
 }
 
 $defaults = $current_group;
+$category = GroupManager::get_category_from_group($group_id);
+if (!empty($category)) {
+    $defaults['category_id'] = $category['id'];
+}
+
 $action = isset($_GET['action']) ? $_GET['action'] : '';
 $defaults['action'] = $action;
 if ($defaults['maximum_number_of_students'] == GroupManager::MEMBER_PER_GROUP_NO_LIMIT) {

BIN
main/img/icons/32/week.png


+ 33 - 10
main/inc/ajax/agenda.ajax.php

@@ -3,6 +3,7 @@
 /**
  * Responses to AJAX calls
  */
+
 $type = isset($_REQUEST['type']) && in_array($_REQUEST['type'], array('personal', 'course', 'admin')) ? $_REQUEST['type'] : 'personal';
 
 if ($type == 'personal') {
@@ -27,7 +28,7 @@ $group_id = api_get_group_id();
 $is_group_tutor = GroupManager::is_tutor_of_group(api_get_user_id(), $group_id);
 
 $agenda = new Agenda();
-$agenda->type = $type; //course,admin or personal
+$agenda->type = $type;
 
 switch ($action) {
     case 'add_event':
@@ -35,7 +36,15 @@ switch ($action) {
             break;
         }
         $add_as_announcement = isset($_REQUEST['add_as_annonuncement']) ? $_REQUEST['add_as_annonuncement'] : null;
-        echo $agenda->add_event($_REQUEST['start'], $_REQUEST['end'], $_REQUEST['all_day'], $_REQUEST['view'], $_REQUEST['title'], $_REQUEST['content'], $_REQUEST['users_to_send'], $add_as_announcement);
+        echo $agenda->add_event(
+            $_REQUEST['start'],
+            $_REQUEST['end'],
+            $_REQUEST['all_day'],
+            $_REQUEST['title'],
+            $_REQUEST['content'],
+            $_REQUEST['users_to_send'],
+            $add_as_announcement
+        );
         break;
     case 'edit_event':
         if (!api_is_allowed_to_edit(null, true) && $type == 'course') {
@@ -43,7 +52,14 @@ switch ($action) {
         }
         $id_list = explode('_', $_REQUEST['id']);
         $id = $id_list[1];
-        $agenda->edit_event($id, $_REQUEST['start'], $_REQUEST['end'], $_REQUEST['all_day'], $_REQUEST['view'], $_REQUEST['title'], $_REQUEST['content']);
+        $agenda->edit_event(
+            $id,
+            $_REQUEST['start'],
+            $_REQUEST['end'],
+            $_REQUEST['all_day'],
+            $_REQUEST['title'],
+            $_REQUEST['content']
+        );
         break;
     case 'delete_event':
         if (!api_is_allowed_to_edit(null, true) && $type == 'course') {
@@ -51,7 +67,8 @@ switch ($action) {
         }
         $id_list = explode('_', $_REQUEST['id']);
         $id = $id_list[1];
-        $agenda->delete_event($id);
+        $deleteAllEventsFromSerie = isset($_REQUEST['delete_all_events']) ? true : false;
+        $agenda->delete_event($id, $deleteAllEventsFromSerie);
         break;
     case 'resize_event':
         if (!api_is_allowed_to_edit(null, true) && $type == 'course') {
@@ -74,15 +91,21 @@ switch ($action) {
         $agenda->move_event($id, $day_delta, $minute_delta);
         break;
     case 'get_events':
-        $user_id = isset($_REQUEST['user_id']) ? $_REQUEST['user_id'] : null;
-        if (substr($user_id, 0, 1) == 'G') {
-            $length = strlen($user_id);
-            $group_id = substr($user_id, 2, $length-1);
-        }
+        $filter = isset($_REQUEST['user_id']) ? $_REQUEST['user_id'] : null;
+        $result = $agenda->parseAgendaFilter($filter);
+        $groupId = current($result['groups']);
+        $userId = current($result['users']);
+
         $start = isset($_REQUEST['start']) ? $_REQUEST['start'] : null;
         $end = isset($_REQUEST['end']) ? $_REQUEST['end'] : null;
 
-        $events = $agenda->get_events($start, $end, api_get_course_int_id(), $group_id, $user_id);
+        $events = $agenda->get_events(
+            $start,
+            $end,
+            api_get_course_int_id(),
+            $groupId,
+            $userId
+        );
         echo $events;
         break;
     case 'get_user_agenda':

+ 1 - 1
main/inc/ajax/document.ajax.php

@@ -33,7 +33,7 @@ switch($action) {
                 $file['name'],
                 null,
                 0,
-                'overwrite',
+                $_POST['if_exists'],
                 false,
                 false
             );

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

@@ -142,20 +142,42 @@ if (!$sidx) {
 switch ($action) {
     case 'get_user_course_report':
     case 'get_user_course_report_resumed':
-
         if (!(api_is_platform_admin(false, true))) {
-            exit;
+            //exit;
         }
         $courseCodeList = array();
         $userIdList  = array();
         if (api_is_drh()) {
-            $userList = UserManager::get_users_followed_by_drh(api_get_user_id());
-            if (!empty($userList)) {
-                $userIdList = array_keys($userList);
-            }
-            $courseList = CourseManager::get_courses_followed_by_drh(api_get_user_id());
-            if (!empty($courseList)) {
-                $courseCodeList = array_keys($courseList);
+            if (api_drh_can_access_all_session_content()) {
+                $userList = SessionManager::getAllUsersFromCoursesFromAllSessionFromStatus(
+                    'drh_all',
+                    api_get_user_id()
+                );
+
+                if (!empty($userList)) {
+                    foreach ($userList as $user) {
+                        $userIdList[] = $user['user_id'];
+                    }
+                }
+
+                $courseList = SessionManager::getAllCoursesFollowedByUser(
+                    api_get_user_id(),
+                    null
+                );
+                if (!empty($courseList)) {
+                    foreach ($courseList as $course) {
+                        $courseCodeList[] = $course['code'];
+                    }
+                }
+            } else {
+                $userList = UserManager::get_users_followed_by_drh(api_get_user_id());
+                if (!empty($userList)) {
+                    $userIdList = array_keys($userList);
+                }
+                $courseList = CourseManager::get_courses_followed_by_drh(api_get_user_id());
+                if (!empty($courseList)) {
+                    $courseCodeList = array_keys($courseList);
+                }
             }
 
             if (empty($userIdList) || empty($courseCodeList)) {
@@ -265,11 +287,27 @@ switch ($action) {
         $count = get_count_exam_hotpotatoes_results($hotpot_path);
         break;
     case 'get_sessions_tracking':
+        $keyword = isset($_REQUEST['keyword']) ? $_REQUEST['keyword'] : null;
         if (api_is_drh()) {
-            $count = SessionManager::get_sessions_followed_by_drh(api_get_user_id(), null, null, true);
+            $count = SessionManager::get_sessions_followed_by_drh(
+                api_get_user_id(),
+                null,
+                null,
+                true,
+                false,
+                false,
+                null,
+                $keyword
+            );
         } else {
             // Sessions for the coach
-            $count = Tracking::get_sessions_coached_by_user(api_get_user_id(), null, null, true);
+            $count = Tracking::get_sessions_coached_by_user(
+                api_get_user_id(),
+                null,
+                null,
+                true,
+                $keyword
+            );
         }
         break;
     case 'get_sessions':
@@ -571,9 +609,9 @@ switch ($action) {
         $course = api_get_course_info();
         $documentPath = api_get_path(SYS_COURSE_PATH) . $course['path'] . "/document";
         if (api_is_allowed_to_edit()) {
-            $columns = array('firstname', 'lastname', 'username', 'group_name', 'exe_date',  'score', 'actions');    
+            $columns = array('firstname', 'lastname', 'username', 'group_name', 'exe_date',  'score', 'actions');
         } else {
-            $columns = array('exe_date',  'score', 'actions');    
+            $columns = array('exe_date',  'score', 'actions');
         }
         $result = get_exam_results_hotpotatoes_data($start, $limit, $sidx, $sord, $hotpot_path, $where_condition); //get_exam_results_data($start, $limit, $sidx, $sord, $exercise_id, $where_condition);
         break;
@@ -609,10 +647,25 @@ switch ($action) {
         break;
     case 'get_sessions_tracking':
         if (api_is_drh()) {
-            $sessions = SessionManager::get_sessions_followed_by_drh(api_get_user_id(), $start, $limit);
+            $sessions = SessionManager::get_sessions_followed_by_drh(
+                api_get_user_id(),
+                $start,
+                $limit,
+                false,
+                false,
+                false,
+                null,
+                $keyword
+            );
         } else {
             // Sessions for the coach
-            $sessions = Tracking::get_sessions_coached_by_user(api_get_user_id(), $start, $limit);
+            $sessions = Tracking::get_sessions_coached_by_user(
+                api_get_user_id(),
+                $start,
+                $limit,
+                false,
+                $keyword
+            );
         }
 
         $columns =  array(

+ 52 - 30
main/inc/ajax/myspace.ajax.php

@@ -4,27 +4,35 @@
  * Responses to AJAX calls
  */
 
-$language_file = array ('tracking');
+$language_file = array('tracking');
 
 require_once '../global.inc.php';
 $action = $_GET['a'];
 
 //if (!api_is_platform_admin() && !api_is_xml_http_request()) { exit; }
-require_once api_get_path(SYS_CODE_PATH).'mySpace/myspace.lib.php';
+require_once api_get_path(SYS_CODE_PATH) . 'mySpace/myspace.lib.php';
 
 switch ($action) {
     case 'access_detail':
-        $user_id        = intval($_REQUEST['student']);
-        $course_code    = Security::remove_XSS($_REQUEST['course']);
-        $type           = Security::remove_XSS($_REQUEST['type']);
-        $range          = Security::remove_XSS($_REQUEST['range']);
+        $user_id = intval($_REQUEST['student']);
+        $course_code = Security::remove_XSS($_REQUEST['course']);
+        $type = Security::remove_XSS($_REQUEST['type']);
+        $range = Security::remove_XSS($_REQUEST['range']);
 
         if ($range == 1) {
-            $start_date     = Security::remove_XSS($_REQUEST['sd']);
-            $end_date       = Security::remove_XSS($_REQUEST['ed']);
-            $sql_result     = get_connections_to_course_by_date($user_id, $course_code, $start_date, $end_date);
+            $start_date = Security::remove_XSS($_REQUEST['sd']);
+            $end_date = Security::remove_XSS($_REQUEST['ed']);
+            $sql_result = get_connections_to_course_by_date(
+                $user_id,
+                $course_code,
+                $start_date,
+                $end_date
+            );
         } else {
-            $sql_result     = MySpace::get_connections_to_course($user_id, $course_code);
+            $sql_result = MySpace::get_connections_to_course(
+                $user_id,
+                $course_code
+            );
         }
         $foo_print = grapher($sql_result, $start_date, $end_date, $type);
         echo $foo_print;
@@ -32,31 +40,45 @@ switch ($action) {
         break;
 
     case 'access_detail_by_date':
+        $db = array('is_empty' => true);
+        $start_date = isset($_REQUEST['startDate']) ? $_REQUEST['startDate'] : "";
+        $end_date = isset($_REQUEST['endDate']) ? $_REQUEST['endDate'] : "";
+        $user_id = isset($_REQUEST['student']) ? $_REQUEST['student'] : "";
+        $course_code = isset($_REQUEST['course']) ? $_REQUEST['course'] : "";
+        $type = isset($_REQUEST['type']) ? $_REQUEST['type'] : "";
 
-        $db = array('is_empty'=>true);
-        $start_date     = isset($_REQUEST['startDate'])?$_REQUEST['startDate']:"";
-        $end_date       = isset($_REQUEST['endDate'])?$_REQUEST['endDate']:"";
-        $user_id        = isset($_REQUEST['student'])?$_REQUEST['student']:"";
-        $course_code    = isset($_REQUEST['course'])?$_REQUEST['course']:"";
-
-        $sql_result = get_connections_to_course_by_date($user_id, $course_code, $start_date, $end_date);
+        $sql_result = get_connections_to_course_by_date(
+            $user_id,
+            $course_code,
+            $start_date,
+            $end_date
+        );
 
         if (is_array($sql_result) && count($sql_result) > 0) {
-            $db['is_empty']     = false;
-            $db['result']       = convert_to_string($sql_result);
-            $rst                = get_stats($user_id, $course_code, $start_date, $end_date);
-            $foo_stats           = '<strong>'.get_lang('Total').': </strong>'.$rst['total'].'<br />';
-            $foo_stats          .= '<strong>'.get_lang('Average').': </strong>'.$rst['avg'].'<br />';
-            $foo_stats          .= '<strong>'.get_lang('Quantity').' : </strong>'.$rst['times'].'<br />';
-            $db['stats']        = $foo_stats;
-            $db['graph_result'] = grapher($sql_result, $start_date, $end_date);
+            $db['is_empty'] = false;
+            $db['result'] = convert_to_string($sql_result);
+            $rst = get_stats($user_id, $course_code, $start_date, $end_date);
+            $foo_stats = '<strong>' . get_lang('Total') . ': </strong>' . $rst['total'] . '<br />';
+            $foo_stats .= '<strong>' . get_lang('Average') . ': </strong>' . $rst['avg'] . '<br />';
+            $foo_stats .= '<strong>' . get_lang('Quantity') . ' : </strong>' . $rst['times'] . '<br />';
+            $db['stats'] = $foo_stats;
+            $db['graph_result'] = grapher($sql_result, $start_date, $end_date, $type);
         } else {
-            $db['result']       = Display::return_message(get_lang('NoDataAvailable'), 'warning');
-            $db['graph_result'] = Display::return_message(get_lang('NoDataAvailable'), 'warning');
-            $db['stats']        = Display::return_message(get_lang('NoDataAvailable'), 'warning');
+            $db['result'] = Display::return_message(
+                get_lang('NoDataAvailable'),
+                'warning'
+            );
+            $db['graph_result'] = Display::return_message(
+                get_lang('NoDataAvailable'),
+                'warning'
+            );
+            $db['stats'] = Display::return_message(
+                get_lang('NoDataAvailable'),
+                'warning'
+            );
         }
         header('Cache-Control: no-cache');
-        echo json_encode($db); // requires: PHP >= 5.2.0, PECL json >= 1.2.0
+        echo json_encode($db);
         break;
 }
-exit;
+exit;

+ 8 - 0
main/inc/global.inc.php

@@ -588,6 +588,14 @@ if (!isset($_SESSION['login_as']) && isset($_user)) {
         $now = api_get_utc_datetime(time());
         $s_sql_update_logout_date = "UPDATE $tbl_track_login SET logout_date='$now' WHERE login_id='$i_id_last_connection'";
         Database::query($s_sql_update_logout_date);
+        // Saves the last login in the user table see BT#7297
+        if (isset($_configuration['save_user_last_login']) &&
+            $_configuration['save_user_last_login']
+        ) {
+            $tableUser = Database::get_main_table(TABLE_MAIN_USER);
+            $sql = "UPDATE $tableUser SET last_login ='$now' WHERE user_id = ".$_user["user_id"];
+            Database::query($sql);
+        }
     }
 }
 // Add language_measure_frequency to your main/inc/conf/configuration.php in

+ 4 - 4
main/inc/lib/banner.lib.php

@@ -36,7 +36,7 @@ function get_tabs() {
     }
     $navigation['mycourses']['title'] = get_lang('MyCourses');
     $navigation['mycourses']['key'] = 'my-course';
-	
+
     // My Profile
 	$navigation['myprofile']['url'] = api_get_path(WEB_CODE_PATH).'auth/profile.php'.(!empty($_course['path']) ? '?coursePath='.$_course['path'].'&amp;courseCode='.$_course['official_code'] : '' );
 	$navigation['myprofile']['title'] = get_lang('ModifyProfile');
@@ -115,7 +115,7 @@ function get_tabs() {
 			$navigation['custom_tab_'.$i]['url'] = api_get_setting('custom_tab_'.$i.'_url');
 			$navigation['custom_tab_'.$i]['title'] = api_get_setting('custom_tab_'.$i.'_name');
             $navigation['custom_tab_'.$i]['key'] = 'custom_tab_'.$i;
-           
+
 		}
 
 	// Platform administration
@@ -301,10 +301,10 @@ function return_navigation_array() {
         // Dashboard
         if (api_get_setting('show_tabs', 'dashboard') == 'true') {
             if (api_is_platform_admin() || api_is_drh() || api_is_session_admin()) {
-                $navigation['dashboard'] = $possible_tabs['dashboard'];
+                $navigation['dashboard'] = isset($possible_tabs['dashboard']) ? $possible_tabs['dashboard'] : null;
             }
         } else{
-            $menu_navigation['dashboard'] = $possible_tabs['dashboard'];
+            $menu_navigation['dashboard'] = isset($possible_tabs['dashboard']) ? $possible_tabs['dashboard'] : null;
         }
 
         // Administration

+ 152 - 42
main/inc/lib/course.lib.php

@@ -339,9 +339,11 @@ class CourseManager
         $course_id = $course_info['real_id'];
 
         // Unsubscribe user from all groups in the course.
-        $sql = "DELETE FROM ".Database::get_course_table(TABLE_GROUP_USER)."  WHERE c_id = $course_id AND user_id IN (".$user_ids.")";
+        $sql = "DELETE FROM ".Database::get_course_table(TABLE_GROUP_USER)."
+                WHERE c_id = $course_id AND user_id IN (".$user_ids.")";
         Database::query($sql);
-        $sql = "DELETE FROM ".Database::get_course_table(TABLE_GROUP_TUTOR)." WHERE c_id = $course_id AND user_id IN (".$user_ids.")";
+        $sql = "DELETE FROM ".Database::get_course_table(TABLE_GROUP_TUTOR)."
+                WHERE c_id = $course_id AND user_id IN (".$user_ids.")";
         Database::query($sql);
 
         // Erase user student publications (works) in the course - by André Boivin
@@ -1825,9 +1827,19 @@ class CourseManager
      * @param   boolean get empty groups (optional)
      * @return  array   List of groups info
      */
-    public static function get_group_list_of_course($course_code, $session_id = 0, $in_get_empty_group = 0) {
-        $course_info = Database::get_course_info($course_code);
+    public static function get_group_list_of_course($course_code, $session_id = 0, $in_get_empty_group = 0)
+    {
+        $course_info = api_get_course_info($course_code);
+
+        if (empty($course_info)) {
+            return array();
+        }
         $course_id = $course_info['real_id'];
+
+        if (empty($course_id)) {
+            return array();
+        }
+
         $group_list = array();
         $session_id != 0 ? $session_condition = ' WHERE g.session_id IN(1,'.intval($session_id).')' : $session_condition = ' WHERE g.session_id = 0';
 
@@ -2970,50 +2982,120 @@ class CourseManager
                 }
             }
         }
-        return $affected_rows;
 
+        return $affected_rows;
     }
 
     /**
      * get courses followed by human resources manager
-     * @param int         human resources manager id
+     * @param int $user_id
+     * @param int $from
+     * @param int $limit
+     * @param string $column
+     * @param string $direction
      * @return array    courses
      */
-    public static function get_courses_followed_by_drh($user_id)
-    {
+    public static function get_courses_followed_by_drh(
+        $user_id,
+        $from = null,
+        $limit = null,
+        $column = null,
+        $direction = null,
+        $getCount = false
+    ) {
+        return self::getCoursesFollowedByUser(
+            $user_id,
+            $from,
+            $limit,
+            $column,
+            $direction,
+            $getCount
+        );
+    }
+
+    /**
+     * get courses followed by user
+     * @param int $user_id
+     * @param int $from
+     * @param int $limit
+     * @param string $column
+     * @param string $direction
+     * @return array    courses
+     */
+    public static function getCoursesFollowedByUser(
+        $user_id,
+        $status = null,
+        $from = null,
+        $limit = null,
+        $column = null,
+        $direction = null,
+        $getCount = false,
+        $keyword = null
+    ) {
         // Database Table Definitions
-        $tbl_course             =     Database::get_main_table(TABLE_MAIN_COURSE);
-        $tbl_course_rel_user     =     Database::get_main_table(TABLE_MAIN_COURSE_USER);
-        $tbl_course_rel_access_url =   Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_COURSE);
+        $tbl_course = Database::get_main_table(TABLE_MAIN_COURSE);
+        $tbl_course_rel_user = Database::get_main_table(TABLE_MAIN_COURSE_USER);
+        $tbl_course_rel_access_url = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_COURSE);
 
         $user_id = intval($user_id);
-        $assigned_courses_to_hrm = array();
+        $select  = "SELECT DISTINCT *, id as real_id ";
+
+        if ($getCount) {
+            $select = "SELECT COUNT(DISTINCT id) as count";
+        }
+
+        $whereConditions = null;
+        switch ($status) {
+            case COURSEMANAGER:
+                $whereConditions .= " AND
+                    cru.user_id = '$user_id' AND
+                    status = ".COURSEMANAGER."
+                ";
+                break;
+            case DRH:
+                $whereConditions .= " AND
+                    cru.user_id = '$user_id' AND
+                    status = ".DRH." AND
+                    relation_type = '".COURSE_RELATION_TYPE_RRHH."'
+                ";
+                break;
+        }
+
+        $keywordCondition = null;
+        if (!empty($keyword)) {
+            $keyword = Database::escape_string($keyword);
+            $keywordCondition = " AND (c.code LIKE '%$keyword%' OR c.title LIKE '%$keyword%' ) ";
+        }
+
+        $whereConditions .= $keywordCondition;
+        $sql = "$select
+                FROM $tbl_course c
+                    INNER JOIN $tbl_course_rel_user cru ON (cru.course_code = c.code)
+                    INNER JOIN $tbl_course_rel_access_url a ON (a.course_code = c.code)
+                WHERE
+                    access_url_id = ".api_get_current_access_url_id()."
+                    $whereConditions
+                ";
+        if (isset($from) && isset($limit)) {
+            $from = intval($from);
+            $limit = intval($limit);
+            $sql .= " LIMIT $from, $limit";
+        }
 
-        if (api_get_multiple_access_url()) {
-           $sql = "SELECT *, id as real_id FROM $tbl_course c
-                        INNER JOIN $tbl_course_rel_user cru ON (cru.course_code = c.code)
-                        LEFT JOIN $tbl_course_rel_access_url a ON (a.course_code = c.code)
-                    WHERE
-                        cru.user_id = '$user_id' AND
-                        status = ".DRH." AND
-                        relation_type = '".COURSE_RELATION_TYPE_RRHH."' AND
-                        access_url_id = ".api_get_current_access_url_id()."";
-        } else {
-            $sql = "SELECT *, id as real_id FROM $tbl_course c
-                    INNER JOIN $tbl_course_rel_user cru
-                    ON
-                        cru.course_code = c.code AND
-                        cru.user_id = '$user_id' AND
-                        status = ".DRH." AND
-                        relation_type = '".COURSE_RELATION_TYPE_RRHH."' ";
-        }
-        $rs_assigned_courses = Database::query($sql);
-        if (Database::num_rows($rs_assigned_courses) > 0) {
-            while ($row_assigned_courses = Database::fetch_array($rs_assigned_courses))    {
-                $assigned_courses_to_hrm[$row_assigned_courses['code']] = $row_assigned_courses;
+        $result = Database::query($sql);
+
+        if ($getCount) {
+            $row = Database::fetch_array($result);
+            return $row['count'];
+        }
+
+        $courses = array();
+        if (Database::num_rows($result) > 0) {
+            while ($row = Database::fetch_array($result))    {
+                $courses[$row['code']] = $row;
             }
         }
-        return $assigned_courses_to_hrm;
+        return $courses;
     }
 
     /**
@@ -4102,12 +4184,12 @@ class CourseManager
         //WHERE login_course_date <= '$today' AND login_course_date >= '$today_diff'
 
         //$table_course_access table uses the now() and interval ...
-
+       $now = api_get_utc_datetime(time());
        $sql = "SELECT COUNT(course_access_id) course_count, a.course_code, visibility ".
               "FROM $table_course c INNER JOIN $table_course_access a ".
               "  ON (c.code = a.course_code) INNER JOIN $table_course_url u ON u.course_code = a.course_code ".
               "  WHERE   u.access_url_id = ".$_configuration['access_url']." AND".
-              "          login_course_date <= now() AND ".
+              "          login_course_date <= '$now' AND ".
               "          login_course_date > DATE_SUB(now(), INTERVAL $days DAY) AND".
               "          visibility <> '".COURSE_VISIBILITY_CLOSED."' AND visibility <> '".COURSE_VISIBILITY_HIDDEN."'".
               "  GROUP BY course_code".
@@ -4130,6 +4212,8 @@ class CourseManager
 
         foreach ($courses as &$my_course) {
             $course_info = api_get_course_info($my_course['course_code']);
+            $courseCode = $my_course['course_code'];
+            $categoryCode = $my_course['categoryCode'];
             $my_course['extra_info'] = $course_info;
             $my_course['extra_info']['go_to_course_button'] = '';
             $my_course['extra_info']['register_button'] = '';
@@ -4144,6 +4228,10 @@ class CourseManager
                 $my_course['extra_info']['go_to_course_button'] = Display::url(get_lang('GoToCourse'), api_get_path(WEB_COURSE_PATH).$course_info['path'].'/index.php', array('class' => 'btn btn-primary'));
             }
 
+            if ($access_link && in_array('unsubscribe', $access_link)) {
+                $my_course['extra_info']['unsubscribe_button'] = Display::url(get_lang('Unsubscribe'), api_get_path(WEB_CODE_PATH).'auth/courses.php?action=unsubscribe&amp;unsubscribe='.$courseCode.'&amp;sec_token='.$stok.'&amp;category_code='.$categoryCode, array('class' => 'btn btn-primary'));
+            }
+
             //Description
             $my_course['extra_info']['description_button'] = '';
             if ($course_info['visibility'] == COURSE_VISIBILITY_OPEN_WORLD || in_array($course_info['real_id'], $my_course_code_list) ) {
@@ -4244,7 +4332,6 @@ class CourseManager
         $options = array();
         // Register button
         if (!api_is_anonymous($uid) &&
-            !$is_admin &&
             (
                 ($course['visibility'] == COURSE_VISIBILITY_OPEN_WORLD || $course['visibility'] == COURSE_VISIBILITY_OPEN_PLATFORM)
                 //$course['visibility'] == COURSE_VISIBILITY_REGISTERED && $course['subscribe'] == SUBSCRIBE_ALLOWED
@@ -4264,6 +4351,18 @@ class CourseManager
             $options[]=  'enter';
         }
 
+        if ($is_admin ||
+            $course['visibility'] == COURSE_VISIBILITY_OPEN_WORLD && empty($course['registration_code']) ||
+            (api_user_is_login($uid) && $course['visibility'] == COURSE_VISIBILITY_OPEN_PLATFORM && empty($course['registration_code']) ) ||
+            (in_array($course['real_id'], $user_courses) && $course['visibility'] != COURSE_VISIBILITY_CLOSED)
+        ) {
+            $options[]=  'enter';
+        }
+
+         if ($course['visibility'] != HIDDEN && empty($course['registration_code']) && $course['unsubscribe'] == UNSUBSCRIBE_ALLOWED && api_user_is_login($uid) && (in_array($course['real_id'], $user_courses))) {
+            $options[]=  'unsubscribe';
+        }
+
         return $options;
     }
 
@@ -4361,11 +4460,13 @@ class CourseManager
 
     /**
      * Course available settings variables see c_course_setting table
+     * @param AppPlugin $appPlugin
      * @return array
      */
-    public static function getCourseSettingVariables()
+    public static function getCourseSettingVariables(AppPlugin $appPlugin)
     {
-        return array(
+        $pluginCourseSettings = $appPlugin->getAllPluginCourseSettings();
+        $courseSettings = array(
             // Get allow_learning_path_theme from table
             'allow_learning_path_theme',
             // Get allow_open_chat_window from table
@@ -4397,17 +4498,26 @@ class CourseManager
             'pdf_export_watermark_text',
             'show_system_folders'
         );
+        if (!empty($pluginCourseSettings)) {
+            $courseSettings = array_merge(
+                $courseSettings,
+                $pluginCourseSettings
+            );
+        }
+        return $courseSettings;
     }
 
     /**
+     * @param AppPlugin $appPlugin
      * @param string $variable
      * @param string $value
      * @param int $courseId
      * @return bool
      */
-    public static function saveCourseConfigurationSetting($variable, $value, $courseId)
+    public static function saveCourseConfigurationSetting(AppPlugin $appPlugin, $variable, $value, $courseId)
     {
-        $settingList = self::getCourseSettingVariables();
+        $settingList = self::getCourseSettingVariables($appPlugin);
+
         if (!in_array($variable, $settingList)) {
             return false;
         }

+ 30 - 6
main/inc/lib/course_category.lib.php

@@ -437,7 +437,21 @@ function browseCourseCategories()
             $whereCondition
             ORDER BY tree_pos ASC";
     $result = Database::query($sql);
+    $url_access_id = 1;
+    if (api_is_multiple_url_enabled()) {
+        $url_access_id = api_get_current_access_url_id();
+    }
+    $countCourses = CourseManager :: count_courses($url_access_id);
     $categories = array();
+    $categories[0][0] = array(
+        'id' => 0,
+        'name' => get_lang('DisplayAll'),
+        'code' => 'ALL',
+        'parent_id' => null,
+        'tree_pos' => 0,
+        'count_courses' => $countCourses
+
+    );
     while ($row = Database::fetch_array($result)) {
         $count_courses = countCoursesInCategory($row['code']);
         $row['count_courses'] = $count_courses;
@@ -447,7 +461,9 @@ function browseCourseCategories()
             $categories[$row['parent_id']][$row['tree_pos']] = $row;
         }
     }
+    
     $count_courses = countCoursesInCategory();
+
     $categories[0][count($categories[0])+1] = array(
         'id' =>0,
         'name' => get_lang('None'),
@@ -459,6 +475,7 @@ function browseCourseCategories()
         'auth_cat_child' => true,
         'count_courses' => $count_courses
     );
+    
     return $categories;
 }
 
@@ -466,7 +483,7 @@ function browseCourseCategories()
  * @param string $category_code
  * @return int
  */
-function countCoursesInCategory($category_code='')
+function countCoursesInCategory($category_code="")
 {
     $tbl_course = Database::get_main_table(TABLE_MAIN_COURSE);
     $TABLE_COURSE_FIELD = Database :: get_main_table(TABLE_MAIN_COURSE_FIELD);
@@ -502,8 +519,7 @@ function countCoursesInCategory($category_code='')
             $sql = "SELECT * FROM $tbl_course as course
                     INNER JOIN $tbl_url_rel_course as url_rel_course
                     ON (url_rel_course.course_code=course.code)
-                    WHERE
-                        access_url_id = $url_access_id AND category_code" . "='" . $category_code . "'" . $without_special_courses;
+                    WHERE access_url_id = $url_access_id AND category_code" . "='" . $category_code . "'" . $without_special_courses;
         }
     }
     return Database::num_rows(Database::query($sql));
@@ -581,7 +597,7 @@ function browseCoursesInCategory($category_code, $random_value = null)
         $sql = "SELECT * FROM $tbl_course WHERE id IN($id_in)";
     } else {
         $category_code = Database::escape_string($category_code);
-        if (empty($category_code)) {
+        if (empty($category_code) || $category_code == "ALL") {
             $sql = "SELECT * FROM $tbl_course WHERE 1=1 $without_special_courses ORDER BY title ";
         } else {
             if ($category_code == 'NONE') {
@@ -594,10 +610,18 @@ function browseCoursesInCategory($category_code, $random_value = null)
         if (api_is_multiple_url_enabled()) {
             $url_access_id = api_get_current_access_url_id();
             $tbl_url_rel_course = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_COURSE);
-            $sql = "SELECT * FROM $tbl_course as course INNER JOIN $tbl_url_rel_course as url_rel_course
+            if ($category_code != "ALL") {
+                $sql = "SELECT * FROM $tbl_course as course INNER JOIN $tbl_url_rel_course as url_rel_course
                     ON (url_rel_course.course_code=course.code)
                     WHERE access_url_id = $url_access_id AND category_code='$category_code' $without_special_courses
+                    ORDER BY title";    
+            } else{
+                $sql = "SELECT * FROM $tbl_course as course INNER JOIN $tbl_url_rel_course as url_rel_course
+                    ON (url_rel_course.course_code=course.code)
+                    WHERE access_url_id = $url_access_id $without_special_courses
                     ORDER BY title";
+            }
+            
         }
     }
 
@@ -748,4 +772,4 @@ function searchCategoryById($list)
 
 /**
  CREATE TABLE IF NOT EXISTS access_url_rel_course_category (access_url_id int unsigned NOT NULL, course_category_id int unsigned NOT NULL, PRIMARY KEY (access_url_id, course_category_id));
- */
+ */

+ 1 - 1
main/inc/lib/course_home.lib.php

@@ -741,7 +741,7 @@ class CourseHome
                 // Creating title and the link
 
                 if (isset($tool['category']) && $tool['category'] == 'plugin') {
-                    $plugin_info = $app_plugin->get_plugin_info($tool['name']);
+                    $plugin_info = $app_plugin->getPluginInfo($tool['name']);
                     if (isset($plugin_info) && isset($plugin_info['title'])) {
                         $tool_name = $plugin_info['title'];
                     }

+ 6 - 4
main/inc/lib/database.lib.php

@@ -1129,7 +1129,8 @@ class Database {
      * Experimental useful database insert
      * @todo lot of stuff to do here
      */
-    public static function insert($table_name, $attributes, $show_query = false) {
+    public static function insert($table_name, $attributes, $show_query = false)
+    {
         if (empty($attributes) || empty($table_name)) {
             return false;
         }
@@ -1137,15 +1138,16 @@ class Database {
         foreach($attributes as $key => $value) {
             $filtred_attributes[$key] = "'".self::escape_string($value)."'";
         }
-        $params = array_keys($filtred_attributes); //@todo check if the field exists in the table we should use a describe of that table
+        //@todo check if the field exists in the table we should use a describe of that table
+        $params = array_keys($filtred_attributes);
         $values = array_values($filtred_attributes);
         if (!empty($params) && !empty($values)) {
             $sql    = 'INSERT INTO '.$table_name.' ('.implode(',',$params).') VALUES ('.implode(',',$values).')';
-            $result = self::query($sql);
+            self::query($sql);
             if ($show_query) {
             	var_dump($sql);
             }
-            return  self::get_last_insert_id();
+            return self::insert_id();
         }
         return false;
     }

+ 147 - 80
main/inc/lib/document.lib.php

@@ -548,7 +548,6 @@ class DocumentManager
 
         if ($result !== false && Database::num_rows($result) != 0) {
             while ($row = Database::fetch_array($result, 'ASSOC')) {
-
                 if (api_is_coach()) {
                     // Looking for course items that are invisible to hide it in the session
                     if (in_array($row['id'], array_keys($doc_list))) {
@@ -644,6 +643,7 @@ class DocumentManager
             } else {
                 $final_document_data = $document_data;
             }
+
             return $final_document_data;
         } else {
             return false;
@@ -658,8 +658,11 @@ class DocumentManager
      * @param boolean $can_see_invisible
      * @return array with paths
      */
-    public static function get_all_document_folders($_course, $to_group_id = '0', $can_see_invisible = false)
-    {
+    public static function get_all_document_folders(
+        $_course,
+        $to_group_id = '0',
+        $can_see_invisible = false
+    ) {
         $TABLE_ITEMPROPERTY = Database::get_course_table(TABLE_ITEM_PROPERTY);
         $TABLE_DOCUMENT = Database::get_course_table(TABLE_DOCUMENT);
 
@@ -800,7 +803,7 @@ class DocumentManager
      *
      * @param array  $_course
      * @param int    $user_id id of the current user
-     * @param string $file path stored in the database
+     * @param string $file path stored in the database (if not defined, $documentId must be used)
      * @param int    $document_id in case you dont have the file path ,insert the id of the file here and leave $file in blank ''
      * @param bool $to_delete
      * @param int $sessionId
@@ -809,10 +812,11 @@ class DocumentManager
     public static function check_readonly(
         $_course,
         $user_id,
-        $file,
+        $file = null,
         $document_id = '',
         $to_delete = false,
-        $sessionId = null
+        $sessionId = null,
+        $documentId = null
     ) {
 
         if (empty($sessionId)) {
@@ -906,7 +910,7 @@ class DocumentManager
      * @param int $session_id
      * @param bool $remove_content_from_db
      */
-    public static function delete_document_from_db(
+    public static function deleteDocumentFromDb(
         $document_id,
         $course_info = array(),
         $session_id = 0,
@@ -946,12 +950,15 @@ class DocumentManager
         //Hard DB delete
         if ($remove_content_from_db) {
             $sql = "DELETE FROM $TABLE_ITEMPROPERTY
-                    WHERE c_id = {$course_info['real_id']} AND ref = ".$document_id." AND tool='".TOOL_DOCUMENT."'";
+                    WHERE
+                        c_id = {$course_info['real_id']} AND
+                        ref = ".$document_id." AND
+                        tool='".TOOL_DOCUMENT."'";
             Database::query($sql);
 
-            $sql = "DELETE FROM $TABLE_DOCUMENT WHERE c_id = {$course_info['real_id']} AND id = ".$document_id;
+            $sql = "DELETE FROM $TABLE_DOCUMENT
+                    WHERE c_id = {$course_info['real_id']} AND id = ".$document_id;
             Database::query($sql);
-
             self::delete_document_metadata($document_id);
         }
     }
@@ -978,26 +985,32 @@ class DocumentManager
      *
      * @param array $_course
      * @param string $path, path stored in the database
-     * @param string $base_work_dir, path to the documents folder
+     * @param string $base_work_dir, path to the documents folder (if not defined, $documentId must be used)
      * @param int   $sessionId The ID of the session, if any
      * @param int   $documentId The document id, if available
      * @return boolean true/false
      * @todo now only files/folders in a folder get visibility 2, we should rename them too.
+     * @todo We should be able to get rid of this later when using only documentId (check further usage)
      */
-    public static function delete_document($_course, $path = null, $base_work_dir, $sessionId = null, $documentId = null)
-    {
-        $TABLE_DOCUMENT = Database :: get_course_table(TABLE_DOCUMENT);
-        // @todo We should be able to get rid of this later when using only documentId (check further usage)
-        if (empty ($documentId)) {
-            if (empty($path) || empty($base_work_dir)) {
-                return false;
-            }
+    public static function delete_document(
+        $_course,
+        $path = null,
+        $base_work_dir,
+        $sessionId = null,
+        $documentId = null,
+        $groupId = null
+    ) {
+        $TABLE_DOCUMENT = Database::get_course_table(TABLE_DOCUMENT);
+        if (empty($groupId)) {
+            $groupId = api_get_group_id();
         } else {
-            if (empty($base_work_dir)) {
-                return false;
-            }
-            $docInfo = self::get_document_data_by_id($documentId, $_course['code'], false, $sessionId);
-            $path = $docInfo['path'];
+            $groupId = intval($groupId);
+        }
+
+        if (empty($sessionId)) {
+            $sessionId = api_get_session_id();
+        } else {
+            $sessionId = intval($sessionId);
         }
 
         $course_id = $_course['real_id'];
@@ -1006,96 +1019,145 @@ class DocumentManager
             return false;
         }
 
-        if (empty($sessionId)) {
-            $sessionId = api_get_session_id();
-        } else {
-            $sessionId = intval($sessionId);
+        if (empty($base_work_dir)) {
+            return false;
         }
 
-        // First, delete the actual document.
         if (empty($documentId)) {
-            $document_id = self::get_document_id($_course, $path, $sessionId);
+            $documentId = self::get_document_id($_course, $path, $sessionId);
+            $docInfo = self::get_document_data_by_id(
+                $documentId,
+                $_course['code'],
+                false,
+                $sessionId
+            );
+            $path = $docInfo['path'];
         } else {
-            $document_id = intval($documentId);
+            $docInfo = self::get_document_data_by_id(
+                $documentId,
+                $_course['code'],
+                false,
+                $sessionId
+            );
+            if (empty($docInfo)) {
+                return false;
+            }
+            $path = $docInfo['path'];
         }
 
-        if (empty($document_id)) {
+        $documentId = intval($documentId);
+
+        if (empty($path) || empty($docInfo) || empty($documentId)) {
             return false;
         }
 
-        $document_exists_in_disk = file_exists($base_work_dir.$path);
+        $itemInfo = api_get_item_property_info($_course['real_id'], TOOL_DOCUMENT, $documentId, 0);
+
+        if (empty($itemInfo)) {
+            return false;
+        }
+
+        // File was already deleted.
+        if ($itemInfo['lastedit_type'] == 'DocumentDeleted' ||
+            $itemInfo['lastedit_type'] == 'delete' ||
+            $itemInfo['visibility'] == 2
+        ) {
+            return false;
+        }
+
+        // Filtering by group.
+        if ($itemInfo['to_group_id'] != $groupId) {
+            return false;
+        }
 
-        $new_path = $path.'_DELETED_'.$document_id;
+        $document_exists_in_disk = file_exists($base_work_dir.$path);
+        $new_path = $path.'_DELETED_'.$documentId;
 
         $file_deleted_from_db = false;
         $file_deleted_from_disk = false;
         $file_renamed_from_disk = false;
 
-        if ($document_id) {
-            self::delete_document_from_db($document_id, $_course, $sessionId);
+        if ($documentId) {
+            // Deleting doc from the DB.
+            self::deleteDocumentFromDb($documentId, $_course, $sessionId);
             // Checking
-            // $file_exists_in_db = self::get_document_data_by_id($document_id, $_course['code']);
+            // $file_exists_in_db = self::get_document_data_by_id($documentId, $_course['code']);
             $file_deleted_from_db = true;
         }
 
-        if ($document_exists_in_disk) {
-            if (api_get_setting('permanently_remove_deleted_files') == 'true') {
+        // Looking for children.
+        if ($docInfo['filetype'] == 'folder') {
+            $cleanPath = Database::escape_string($path);
 
-                // Deleted files are *really* deleted.
-                $sql = "SELECT id FROM $TABLE_DOCUMENT
-                        WHERE
-                            c_id = $course_id AND
-                            session_id = $sessionId AND
-                            (path = '".$path."' OR path LIKE BINARY '".$path."/%') ";
-                // Get all id's of documents that are deleted.
-                $result = Database::query($sql);
-
-                if ($result && Database::num_rows($result) != 0) {
-                    // Delete all item_property entries
-                    while ($row = Database::fetch_array($result)) {
-                        // Query to delete from item_property table (hard way)
-                        self::delete_document_from_db($row['id'], $_course, $sessionId, true);
-                    }
+            // Deleted files inside this folder.
+            $sql = "SELECT id FROM $TABLE_DOCUMENT
+                    WHERE
+                        c_id = $course_id AND
+                        session_id = $sessionId AND
+                        path LIKE BINARY '".$cleanPath."/%'";
+
+            // Get all id's of documents that are deleted.
+            $result = Database::query($sql);
+
+            if ($result && Database::num_rows($result) != 0) {
+                // Recursive delete.
+                while ($row = Database::fetch_array($result)) {
+                    self::delete_document(
+                        $_course,
+                        null,
+                        $base_work_dir,
+                        $sessionId,
+                        $row['id']
+                    );
                 }
+            }
+        }
 
+        if ($document_exists_in_disk) {
+            if (api_get_setting('permanently_remove_deleted_files') == 'true') {
                 // Delete documents, do it like this so metadata gets deleted too
                 my_delete($base_work_dir.$path);
+                // Hard delete.
+                self::deleteDocumentFromDb($documentId, $_course, $sessionId, true);
                 $file_deleted_from_disk = true;
-
             } else {
                 // Set visibility to 2 and rename file/folder to xxx_DELETED_#id (soft delete)
 
                 if (is_file($base_work_dir.$path) || is_dir($base_work_dir.$path)) {
                     if (rename($base_work_dir.$path, $base_work_dir.$new_path)) {
+                        $new_path = Database::escape_string($new_path);
 
-                        $sql = "UPDATE $TABLE_DOCUMENT SET path='".$new_path."'
-                                WHERE c_id = $course_id AND session_id = $sessionId AND id = '".$document_id."'";
+                        $sql = "UPDATE $TABLE_DOCUMENT
+                                SET path = '".$new_path."'
+                                WHERE
+                                    c_id = $course_id AND
+                                    session_id = $sessionId AND
+                                    id = ".$documentId;
                         Database::query($sql);
 
-                        $sql = "SELECT id, path FROM $TABLE_DOCUMENT
+                        // Soft delete.
+                        self::deleteDocumentFromDb($documentId, $_course, $sessionId);
+
+                        // Change path of sub folders and documents in database.
+                        $old_item_path = $docInfo['path'];
+                        $new_item_path = $new_path.substr($old_item_path, strlen($path));
+                        $new_item_path = Database::escape_string($new_item_path);
+
+                        $sql = "UPDATE $TABLE_DOCUMENT
+                                SET path = '".$new_item_path."'
                                 WHERE
                                     c_id = $course_id AND
                                     session_id = $sessionId AND
-                                    (path = '".$path."' OR path LIKE BINARY '".$path."/%') ";
-                        $result = Database::query($sql);
-                        if ($result && Database::num_rows($result) > 0) {
-                            while ($deleted_items = Database::fetch_array($result, 'ASSOC')) {
-                                self::delete_document_from_db($deleted_items['id'], $_course, $sessionId);
-
-                                // Change path of sub folders and documents in database.
-                                $old_item_path = $deleted_items['path'];
-                                $new_item_path = $new_path.substr($old_item_path, strlen($path));
-
-                                $sql = "UPDATE $TABLE_DOCUMENT
-                                        SET path = '".$new_item_path."'
-                                        WHERE c_id = $course_id AND session_id = $sessionId AND id = ".$deleted_items['id'];
-                                Database::query($sql);
-                            }
-                        }
+                                    id = ".$documentId;
+                        Database::query($sql);
+
                         $file_renamed_from_disk = true;
                     } else {
                         // Couldn't rename - file permissions problem?
-                        error_log(__FILE__ . ' ' . __LINE__ . ': Error renaming '.$base_work_dir.$path.' to '.$base_work_dir.$new_path.'. This is probably due to file permissions', 0);
+                        error_log(
+                            __FILE__.' '.__LINE__.': Error renaming '.$base_work_dir.$path.' to '.$base_work_dir.$new_path.'. This is probably due to file permissions',
+                            0
+                        );
                     }
                 }
             }
@@ -1113,7 +1175,10 @@ class DocumentManager
             // This means it has been removed externally. To prevent a
             // blocking error from happening, we drop the related items from the
             // item_property and the document table.
-            error_log(__FILE__.' '.__LINE__.': System inconsistency detected. The file or directory '.$base_work_dir.$path.' seems to have been removed from the filesystem independently from the web platform. To restore consistency, the elements using the same path will be removed from the database', 0);
+            error_log(
+                __FILE__.' '.__LINE__.': System inconsistency detected. The file or directory '.$base_work_dir.$path.' seems to have been removed from the filesystem independently from the web platform. To restore consistency, the elements using the same path will be removed from the database',
+                0
+            );
             return false;
         }
     }
@@ -1227,7 +1292,7 @@ class DocumentManager
             $row['absolute_path_from_document'] = '/document' . $row['path'];
 
             $pathinfo = pathinfo($row['path']);
-            $row['absolute_parent_path'] = api_get_path(SYS_COURSE_PATH) . $course_info['path'] . '/document' . $pathinfo['dirname'] . '/';
+            $row['absolute_parent_path'] = api_get_path(SYS_COURSE_PATH).$course_info['path'].'/document'.$pathinfo['dirname'] . '/';
             $row['direct_url'] = $www . $path;
 
             if (dirname($row['path']) == '.') {
@@ -1660,7 +1725,7 @@ class DocumentManager
 
     /**
      * Remove default certificate
-     * @param string The course id
+     * @param string The course code
      * @param int The document id of the default certificate
      * @return void()
      */
@@ -1683,14 +1748,16 @@ class DocumentManager
             }
 
             $sql = 'UPDATE ' . $tbl_category . ' SET document_id=null
-                  WHERE course_code="' . Database::escape_string($course_id) . '" AND document_id="' . $default_certificate_id . '" ' . $sql_session;
+                    WHERE
+                        course_code = "' . Database::escape_string($course_id) . '" AND
+                        document_id="' . $default_certificate_id . '" ' . $sql_session;
             Database::query($sql);
         }
     }
 
     /**
      * Create directory certificate
-     * @param string The course id
+     * @param string The course code
      * @return void()
      */
     public static function create_directory_certificate_in_course($course_id)

+ 2 - 1
main/inc/lib/events.lib.inc.php

@@ -171,8 +171,9 @@ function event_access_tool($tool, $id_session = 0)
     // only if user comes from the course $_cid
     //if( eregi($_configuration['root_web'].$_cid,$_SERVER['HTTP_REFERER'] ) )
     //$pos = strpos($_SERVER['HTTP_REFERER'],$_configuration['root_web'].$_cid);
+    $coursePath = isset($_course['path']) ? $_course['path'] : null;
 
-    $pos = isset($_SERVER['HTTP_REFERER']) ? strpos(strtolower($_SERVER['HTTP_REFERER']), strtolower(api_get_path(WEB_COURSE_PATH).$_course['path'])) : false;
+    $pos = isset($_SERVER['HTTP_REFERER']) ? strpos(strtolower($_SERVER['HTTP_REFERER']), strtolower(api_get_path(WEB_COURSE_PATH).$coursePath)) : false;
     // added for "what's new" notification
     $pos2 = isset($_SERVER['HTTP_REFERER']) ? strpos(strtolower($_SERVER['HTTP_REFERER']), strtolower($_configuration['root_web']."index")) : false;
     // end "what's new" notification

+ 30 - 11
main/inc/lib/fileUpload.lib.php

@@ -211,7 +211,14 @@ function handle_uploaded_document(
 
 	// If the want to unzip, check if the file has a .zip (or ZIP,Zip,ZiP,...) extension
 	if ($unzip == 1 && preg_match('/.zip$/', strtolower($uploaded_file['name']))) {
-		return unzip_uploaded_document($uploaded_file, $upload_path, $base_work_dir, $max_filled_space, $output, $to_group_id);
+		return unzip_uploaded_document(
+            $uploaded_file,
+            $upload_path,
+            $base_work_dir,
+            $max_filled_space,
+            $output,
+            $to_group_id
+        );
 		//display_message('Unzipping file');
 	} elseif ($unzip == 1 && !preg_match('/.zip$/', strtolower($uploaded_file['name']))) { // We can only unzip ZIP files (no gz, tar,...)
 	    if ($output) {
@@ -257,17 +264,18 @@ function handle_uploaded_document(
 			$file_size = $uploaded_file['size'];
 
 			$files_perm = api_get_permissions_for_new_files();
-
-			// What to do if the target file exists
+                       $doc_path = '/'.$clean_name;
+                       $docId = DocumentManager :: get_document_id($_course, $doc_path, $current_session_id);
+      		        // What to do if the target file exists
 			switch ($what_if_file_exists) {
 				// Overwrite the file if it exists
 				case 'overwrite':
-					// Check if the target file exists, so we can give another message
+                                       // Check if the target file exists, so we can give another message
 					$file_exists = file_exists($store_path);
 					if (moveUploadedFile($uploaded_file, $store_path)) {
 						chmod($store_path, $files_perm);
 
-						if ($file_exists) {
+						if ($file_exists && $docId) {
 							// UPDATE DATABASE
 							$document_id = DocumentManager::get_document_id($_course, $file_path);
 
@@ -327,7 +335,11 @@ function handle_uploaded_document(
 
 				// Rename the file if it exists
 				case 'rename':
+                                  if ($docId) {
 					$new_name = unique_name($where_to_save, $clean_name);
+                                  } else {
+                                      $new_name = $clean_name;
+                                  }
 					$store_path = $where_to_save.$new_name;
 					$new_file_path = $upload_path.$new_name;
 
@@ -361,13 +373,13 @@ function handle_uploaded_document(
 					break;
 				default:
                     // Only save the file if it doesn't exist or warn user if it does exist
-					if (file_exists($store_path)) {
+					if (file_exists($store_path) && $docId) {
 					    if ($output) {
 						  Display::display_error_message($clean_name.' '.get_lang('UplAlreadyExists'));
 						}
 					} else {
 						if (moveUploadedFile($uploaded_file, $store_path)) {
-							chmod($store_path, $files_perm);
+						    chmod($store_path, $files_perm);
 
 							// Put the document data in the database
 							$document_id = add_document($_course, $file_path, 'file', $file_size, $document_name, null, 0, true);
@@ -746,7 +758,14 @@ function unzip_uploaded_file($uploaded_file, $upload_path, $base_work_dir, $max_
  *
  * @return boolean true if it succeeds false otherwise
  */
-function unzip_uploaded_document($uploaded_file, $upload_path, $base_work_dir, $max_filled_space, $output = true, $to_group_id = 0) {
+function unzip_uploaded_document(
+    $uploaded_file,
+    $upload_path,
+    $base_work_dir,
+    $max_filled_space,
+    $output = true,
+    $to_group_id = 0
+) {
 	global $_course;
 	global $_user;
 	global $to_user_id;
@@ -755,11 +774,10 @@ function unzip_uploaded_document($uploaded_file, $upload_path, $base_work_dir, $
 	$zip_file = new PclZip($uploaded_file['tmp_name']);
 
 	// Check the zip content (real size and file extension)
-
 	$zip_content_array = (array)$zip_file->listContent();
 
     $real_filesize = 0;
-	foreach($zip_content_array as & $this_content) {
+	foreach ($zip_content_array as & $this_content) {
 		$real_filesize += $this_content['size'];
 	}
 
@@ -777,12 +795,13 @@ function unzip_uploaded_document($uploaded_file, $upload_path, $base_work_dir, $
 
 	// Get into the right directory
 	$save_dir = getcwd();
+
 	chdir($base_work_dir.$upload_path);
 	// We extract using a callback function that "cleans" the path
 	$unzipping_state = $zip_file->extract(PCLZIP_CB_PRE_EXTRACT, 'clean_up_files_in_zip', PCLZIP_OPT_REPLACE_NEWER);
 	// Add all documents in the unzipped folder to the database
 	add_all_documents_in_folder_to_database($_course, $_user['user_id'], $base_work_dir ,$upload_path == '/' ? '' : $upload_path, $to_group_id);
-	//Display::display_normal_message(get_lang('UplZipExtractSuccess'));
+
 	return true;
 }
 

+ 61 - 0
main/inc/lib/formvalidator/Element/DatePicker.php

@@ -0,0 +1,61 @@
+<?php
+/* For licensing terms, see /license.txt */
+require_once 'HTML/QuickForm/date.php';
+
+/**
+ * Form element to select a date and hour (with popup datepicker)
+ */
+class DatePicker extends HTML_QuickForm_text
+{
+	/**
+	 * Constructor
+	 */
+	public function DatePicker($elementName = null, $elementLabel = null, $attributes = null)
+	{
+        if (!isset($attributes['id'])) {
+            $attributes['id'] = $elementName;
+        }
+
+		HTML_QuickForm_element::HTML_QuickForm_element($elementName, $elementLabel, $attributes);
+		$this->_appendName = true;
+		$this->_type = 'date_picker';
+	}
+
+	/**
+	 * HTML code to display this datepicker
+	 */
+	public function toHtml()
+	{
+		$js = $this->getElementJS();
+		return $js.parent::toHtml();
+	}
+
+    function setValue($value)
+    {
+        $value = substr($value, 0, 16);
+        $this->updateAttributes(
+            array(
+                'value' => $value
+            )
+        );
+    }
+
+	/**
+	 * Get the necessary javascript for this datepicker
+	 */
+	private function getElementJS()
+	{
+        $js = null;
+        $id = $this->getAttribute('id');
+
+        $js .= "<script>
+            $(function() {
+                $('#$id').datepicker({
+                    dateFormat: 'yy-mm-dd'
+                });
+            });
+        </script>";
+
+		return $js;
+	}
+}

+ 121 - 0
main/inc/lib/formvalidator/Element/DateRangePicker.php

@@ -0,0 +1,121 @@
+<?php
+/* For licensing terms, see /license.txt */
+require_once 'HTML/QuickForm/date.php';
+
+/**
+ * Form element to select a date and hour (with popup datepicker)
+ */
+class DateRangePicker extends HTML_QuickForm_text
+{
+	/**
+	 * Constructor
+	 */
+	public function DateRangePicker($elementName = null, $elementLabel = null, $attributes = null)
+	{
+        if (!isset($attributes['id'])) {
+            $attributes['id'] = $elementName;
+        }
+        $attributes['class'] = 'span3';
+		HTML_QuickForm_element::HTML_QuickForm_element($elementName, $elementLabel, $attributes);
+		$this->_appendName = true;
+		$this->_type = 'date_range_picker';
+	}
+
+	/**
+	 * HTML code to display this datepicker
+	 */
+	public function toHtml()
+	{
+		$js = $this->getElementJS();
+		return $js.parent::toHtml();
+	}
+
+    function setValue($value)
+    {
+        $this->updateAttributes(
+            array(
+                'value' => $value
+            )
+        );
+    }
+
+	/**
+	 * Get the necessary javascript for this datepicker
+	 */
+	private function getElementJS()
+	{
+        $js = null;
+
+        $id = $this->getAttribute('id');
+        //timeFormat: 'hh:mm'
+        $js .= "<script>
+            $(function() {
+                $('#$id').daterangepicker({
+                    format: 'YYYY-MM-DD HH:mm',
+                    timePicker: true,
+                    timePickerIncrement: 30,
+                    timePicker12Hour: false,
+                    ranges: {
+                         '".addslashes(get_lang('Today'))."': [moment(), moment()],
+                         '".addslashes(get_lang('ThisWeek'))."': [moment().weekday(1), moment().weekday(5)],
+                         '".addslashes(get_lang('NextWeek'))."': [moment().weekday(8), moment().weekday(12)]
+                    },
+                    //showDropdowns : true,
+                    separator: ' / ',
+                    locale: {
+                        applyLabel: '".addslashes(get_lang('Ok'))."',
+                        cancelLabel: '".addslashes(get_lang('Cancel'))."',
+                        fromLabel: '".addslashes(get_lang('From'))."',
+                        toLabel: '".addslashes(get_lang('Until'))."',
+                        customRangeLabel: '".addslashes(get_lang('CustomRange'))."',
+                    }
+                });
+            });
+        </script>";
+
+		return $js;
+	}
+
+    /**
+     * @param array $dateRange
+
+     * @return array
+     */
+    function parseDateRange($dateRange)
+    {
+        $dates = explode('/', $dateRange);
+        $dates = array_map('trim', $dates);
+
+        return array(
+            'start' => $dates[0],
+            'end' => $dates[1]
+        );
+    }
+
+    /**
+     * @param array $dates result of parseDateRange()
+     * @return bool
+     */
+    function validateDates($dates)
+    {
+
+        if (empty($dates['start']) || empty($dates['end'])) {
+            return false;
+        }
+        $format = 'Y-m-d H:i';
+        $d = DateTime::createFromFormat($format, $dates['start']);
+        $resultStart = $d && $d->format($format) == $dates['start'];
+
+        $d = DateTime::createFromFormat($format, $dates['end']);
+        $resultEnd = $d && $d->format($format) == $dates['end'];
+
+        if (!($resultStart) || !$resultEnd) {
+            return false;
+        }
+
+        return true;
+    }
+
+
+
+}

Bu fark içinde çok fazla dosya değişikliği olduğu için bazı dosyalar gösterilmiyor