Browse Source

Solve merge conflicts

Francis Gonzales 11 years ago
parent
commit
f81e05722f
100 changed files with 4875 additions and 6160 deletions
  1. 21 10
      documentation/installation_guide.html
  2. 1 1
      home/home_menu.html
  3. 6 6
      main/auth/cas/lib/CAS/client.php
  4. 10 2
      main/auth/inscription.php
  5. 1 0
      main/calendar/agenda.inc.php
  6. 167 78
      main/calendar/agenda.lib.php
  7. 13 35
      main/calendar/agenda.php
  8. 30 42
      main/calendar/agenda_js.php
  9. 30 29
      main/coursecopy/classes/CourseCopyLearnpath.class.php
  10. 130 125
      main/coursecopy/classes/CourseRestorer.class.php
  11. 7 5
      main/coursecopy/classes/CourseSelectForm.class.php
  12. 19 12
      main/coursecopy/classes/Resource.class.php
  13. 0 1
      main/css/academica/default.css
  14. 1 1
      main/css/academica/scorm.css
  15. 0 1
      main/css/baby_orange/default.css
  16. 1 1
      main/css/baby_orange/scorm.css
  17. 11 3
      main/css/base.css
  18. 0 1
      main/css/blue_lagoon/default.css
  19. 1 1
      main/css/blue_lagoon/scorm.css
  20. 1 1
      main/css/bootstrap.css
  21. 0 6
      main/css/chamilo/default.css
  22. 1 1
      main/css/chamilo/scorm.css
  23. 0 1
      main/css/chamilo_electric_blue/default.css
  24. 1 1
      main/css/chamilo_electric_blue/scorm.css
  25. 0 1
      main/css/chamilo_green/default.css
  26. 1 1
      main/css/chamilo_green/scorm.css
  27. 0 1
      main/css/chamilo_orange/default.css
  28. 1 1
      main/css/chamilo_orange/scorm.css
  29. 0 1
      main/css/chamilo_red/default.css
  30. 1 1
      main/css/chamilo_red/scorm.css
  31. 0 1
      main/css/chamilo_sport_red/default.css
  32. 1 1
      main/css/chamilo_sport_red/scorm.css
  33. 0 1
      main/css/cool_blue/default.css
  34. 1 1
      main/css/cool_blue/scorm.css
  35. 0 1
      main/css/corporate/default.css
  36. 1 1
      main/css/corporate/scorm.css
  37. 0 1
      main/css/cosmic_campus/default.css
  38. 1 1
      main/css/cosmic_campus/scorm.css
  39. 1021 3
      main/css/journal/default.css
  40. 1 4
      main/css/kiddy/default.css
  41. 1 1
      main/css/kiddy/scorm.css
  42. 1 1
      main/document/document_slideshow.inc.php
  43. 2 4
      main/document/show_content.php
  44. 1 0
      main/document/upload.php
  45. 10 10
      main/exercice/admin.php
  46. 29 27
      main/exercice/answer.class.php
  47. 28 17
      main/exercice/exercice.php
  48. 160 121
      main/exercice/exercise.class.php
  49. 51 22
      main/exercice/exercise.lib.php
  50. 4 8
      main/exercice/exercise_report.php
  51. 175 219
      main/exercice/export/exercise_import.inc.php
  52. 84 168
      main/exercice/export/qti2/qti2_classes.php
  53. 87 78
      main/exercice/export/qti2/qti2_export.php
  54. 8 4
      main/exercice/fill_blanks.class.php
  55. 1 0
      main/exercice/multiple_answer_true_false.class.php
  56. 1 1
      main/exercice/overview.php
  57. 29 13
      main/exercice/qti2.php
  58. 132 117
      main/exercice/question.class.php
  59. 2 2
      main/exercice/testcategory.class.php
  60. 13 3
      main/forum/forumfunction.inc.php
  61. 5 4
      main/forum/index.php
  62. 1 1
      main/forum/viewthread_threaded.inc.php
  63. 1 0
      main/gradebook/lib/fe/flatviewtable.class.php
  64. 220 188
      main/gradebook/lib/gradebook_data_generator.class.php
  65. 0 0
      main/img/btn_previous.png
  66. BIN
      main/img/icons/32/week.png
  67. 7 7
      main/inc/ajax/agenda.ajax.php
  68. 3 1
      main/inc/ajax/document.ajax.php
  69. 83 28
      main/inc/ajax/exercise.ajax.php
  70. 2 2
      main/inc/ajax/model.ajax.php
  71. 6 5
      main/inc/ajax/work.ajax.php
  72. 1 1
      main/inc/global.inc.php
  73. 1 1
      main/inc/lib/banner.lib.php
  74. 1224 1055
      main/inc/lib/browser/Browser.php
  75. 45 34
      main/inc/lib/course_home.lib.php
  76. 6 1
      main/inc/lib/display.lib.php
  77. 4 3
      main/inc/lib/document.lib.php
  78. 64 30
      main/inc/lib/events.lib.inc.php
  79. 11 11
      main/inc/lib/fckeditor/editor/plugins/ajaxfilemanager/inc/class.pagination.php
  80. 10 14
      main/inc/lib/fckeditor/fckeditor.php
  81. 30 15
      main/inc/lib/fileUpload.lib.php
  82. 0 1
      main/inc/lib/formvalidator/Element/DatePicker.php
  83. 8 25
      main/inc/lib/formvalidator/Element/DateRangePicker.php
  84. 4 20
      main/inc/lib/formvalidator/Element/DateTimePicker.php
  85. 41 4
      main/inc/lib/formvalidator/FormValidator.class.php
  86. 10 13
      main/inc/lib/internationalization.lib.php
  87. BIN
      main/inc/lib/javascript/chosen/chosen-sprite@2x.png
  88. 300 278
      main/inc/lib/javascript/chosen/chosen.css
  89. 487 274
      main/inc/lib/javascript/chosen/chosen.jquery.js
  90. 1 1089
      main/inc/lib/javascript/chosen/chosen.jquery.min.js
  91. 0 1646
      main/inc/lib/javascript/jquery-ui/ui/i18n/jquery-ui-i18n.js
  92. 0 23
      main/inc/lib/javascript/jquery-ui/ui/i18n/jquery.ui.datepicker-af.js
  93. 0 23
      main/inc/lib/javascript/jquery-ui/ui/i18n/jquery.ui.datepicker-ar-DZ.js
  94. 0 23
      main/inc/lib/javascript/jquery-ui/ui/i18n/jquery.ui.datepicker-ar.js
  95. 0 23
      main/inc/lib/javascript/jquery-ui/ui/i18n/jquery.ui.datepicker-az.js
  96. 0 24
      main/inc/lib/javascript/jquery-ui/ui/i18n/jquery.ui.datepicker-bg.js
  97. 0 23
      main/inc/lib/javascript/jquery-ui/ui/i18n/jquery.ui.datepicker-bs.js
  98. 0 23
      main/inc/lib/javascript/jquery-ui/ui/i18n/jquery.ui.datepicker-ca.js
  99. 0 23
      main/inc/lib/javascript/jquery-ui/ui/i18n/jquery.ui.datepicker-cs.js
  100. 0 23
      main/inc/lib/javascript/jquery-ui/ui/i18n/jquery.ui.datepicker-cy-GB.js

+ 21 - 10
documentation/installation_guide.html

@@ -74,7 +74,7 @@ optimal flexibility, remote control and scalability. <br />
 
 <br />
 
-Chamilo is mainly a LMS running <span style="font-weight: bold;">Apache (1.3, 2.0 or 2.2)</span>, <span style="font-weight: bold;">MySQL 5.1 (or MariaDB)</span> and <span style="font-weight: bold;">PHP 5.3 (or 5.4)</span> (the so called <span style="font-weight: bold;">AMP</span> trilogy). <br />
+Chamilo is mainly a LMS running <span style="font-weight: bold;">Apache (1.3, 2.0 or 2.2)</span>, <span style="font-weight: bold;">MySQL 5.1 or 5.5 (or MariaDB)</span> and <span style="font-weight: bold;">PHP 5.3, 5.4 or 5.5 (5.5 recommended for greater efficiency)</span> (the so called <span style="font-weight: bold;">AMP</span> trilogy). <br />
 
 
 <br />
@@ -104,10 +104,14 @@ For instance, on a Ubuntu server,&nbsp;use Shell or Synaptic following the
 <h3><span style="font-weight: bold;">MySQL or MariaDB database server</span></h3>
 
 You will need a login and password allowing to manage and create
-a database. Usually, the default configuration on local computers is to allow you to connect as root with an empty password. It is highly recommended to change the password and define a user with access to only a specific database. Please refer to the MySQL or MariaDB documentation in order to do this.<br />
-<span class="muted">Note that this has been greatly simplified since version 1.9, as it
-previously required to choose between multiple databases and a deprecated
-single-database mode.</span><br />
+a database. Usually, the default configuration on local computers is
+to allow you to connect as root with an empty password. It is HIGHLY
+RECOMMENDED to change the password and define a user with access to
+only a specific database. Please refer to the MySQL or MariaDB documentation
+in order to do this.<br />
+<span class="muted">Note that this has been greatly simplified since
+version 1.9, as it previously required to choose between multiple databases
+and a deprecated single-database mode.</span><br />
 
 <hr style="width: 100%; height: 2px;" />
 <h2><a name="2._Installation_of_Chamilo_LMS"></a><span style="font-weight: bold;">2. Installation of Chamilo LMS</span></h2>
@@ -126,6 +130,12 @@ single-database mode.</span><br />
 values. Consider changing the admin password to remember it.&nbsp;</li>
 </ol>
 <br />
+<span class="muted">Note: if installing Chamilo locally using localhost or
+the IP address of your computer during the installation, you might get issues
+while accessing from another computer. To avoid this, you can
+<a href="http://beeznest.wordpress.com/2013/01/15/answering-to-different-addresses-with-chamilo/">apply a little
+change to your configuration file</a>.</span>
+<br />
 The following directories need to be readable, writeable and executable by your web server.
 <span class="muted">This usually requires no specific action on Windows servers, but will require a "chmod" under Linux and Mac. See instructions below.</span><br />Replace [chamilo] with the directory where your Chamilo installation is located):
 <ul>
@@ -217,7 +227,8 @@ it might be a bit more expensive now, but you'll be happy not to have to loose
 all of your data to a hacker who attacked your site.</li>
 
   <li><strong>Configure your Chamilo installation: </strong>
-in the administration section of Chamilo, you can use the Chamilo Configuration Settings to adjust the behavior of your installation.</li>
+in the administration section of Chamilo, you can use the Chamilo Configuration
+Settings to adjust the behavior of your installation.</li>
 
   <li><strong>Configure Chamilo mail: </strong>
 most of Chamilo uses the mail settings from the php.ini file. However,
@@ -246,9 +257,9 @@ To get the best out of Chamilo, you need to finetune your PHP settings. Consider
 </ul>
 
 <div class="code">
-      max_execution_time = 300; Maximum execution time of each script, in seconds<br />
-      max_input_time = 600; Maximum amount of time each script may spend parsing request data<br />
-      memory_limit = 256M; Maximum amount of memory a script may consume (128MB)<br />
+      max_execution_time = 300 ;Maximum execution time of each script, in seconds<br />
+      max_input_time = 600 ;Maximum amount of time each script may spend parsing request data<br />
+      memory_limit = 256M ;Maximum amount of memory a script may consume (128MB)<br />
       post_max_size = 100M<br />
       upload_max_filesize = 100M<br />
 </div>
@@ -323,7 +334,7 @@ a full backup of your system before you upgrade.</em>
 <div class="muted"> NOTE: This version of Chamilo can only be used to upgrade from
 smaller versions of Chamilo or Dok€os. For example, you cannot use the normal
 upgrade scripts from Chamilo 1.9 to upgrade from Dok€os 2.0. If you need this,
-please contact one of the Chamilo Association's official providers <providers@chamilo.org>)</div>
+please contact one of the Chamilo Association's official providers &lt;providers@chamilo.org&gt;)</div>
 
 <p></p>
 

+ 1 - 1
home/home_menu.html

@@ -1 +1 @@
-<li class="forum-btn"><a href="http://www.chamilo.org/forum" target="_self">Forum</a></li>
+<li class="forum-btn"><a href="http://www.chamilo.org/forum" target="_self">Forum</a></li>

+ 6 - 6
main/auth/cas/lib/CAS/client.php

@@ -883,16 +883,16 @@ class CASClient
 	function checkAuthentication()
 		{
 		phpCAS::traceBegin();
-		
 		if ( $this->isAuthenticated() ) {
-			phpCAS::trace('user is authenticated');
+            phpCAS::trace('user is authenticated');
 			$res = TRUE;
 		} else if (isset($_SESSION['phpCAS']['auth_checked'])) {
-			// the previous request has redirected the client to the CAS server with gateway=true
-			unset($_SESSION['phpCAS']['auth_checked']);
-			$res = FALSE;
+            // the previous request has redirected the client to the CAS server with gateway=true
+            // comment line bellow to
+//			unset($_SESSION['phpCAS']['auth_checked']);
+            $res = FALSE;
 		} else {
-			//        $_SESSION['phpCAS']['auth_checked'] = true;
+//        $_SESSION['phpCAS']['auth_checked'] = true;
 			//	    $this->redirectToCas(TRUE/* gateway */);	
 			//	    // never reached
 			//	    $res = FALSE;

+ 10 - 2
main/auth/inscription.php

@@ -471,6 +471,7 @@ if ($form->validate()) {
     $_user['language'] 	= $values['language'];
     $_user['user_id']	= $user_id;
     $is_allowedCreateCourse = $values['status'] == 1;
+    $usersCanCreateCourse = (api_get_setting('allow_users_to_create_courses') == 'true');
 
     Session::write('_user', $_user);
     Session::write('is_allowedCreateCourse', $is_allowedCreateCourse);
@@ -498,13 +499,16 @@ if ($form->validate()) {
         }
 
         if ($is_allowedCreateCourse) {
-            $form_data['message'] = '<p>'. get_lang('NowGoCreateYourCourse',null,$_user['language']). "</p>";
+            if ($usersCanCreateCourse) {
+                $form_data['message'] = '<p>'. get_lang('NowGoCreateYourCourse',null,$_user['language']). "</p>";
+            }
             $form_data['action']  = '../create_course/add_course.php';
 
             if (api_get_setting('course_validation') == 'true') {
                 $form_data['button'] = Display::button('next', get_lang('CreateCourseRequest', null, $_user['language']), array('class' => 'btn btn-primary btn-large'));
             } else {
                 $form_data['button'] = Display::button('next', get_lang('CourseCreate', null, $_user['language']), array('class' => 'btn btn-primary btn-large'));
+                $form_data['go_button'] = '&nbsp;&nbsp;<a href="'.api_get_path(WEB_PATH).'index.php'.'">'.Display::span(get_lang('Next', null, $_user['language']), array('class' => 'btn btn-primary btn-large')).'</a>';
             }
         } else {
             if (api_get_setting('allow_students_to_browse_courses') == 'true') {
@@ -560,7 +564,11 @@ if ($form->validate()) {
     if (!empty($form_data['message'])) {
         $form_register->addElement('html', $form_data['message'].'<br /><br />');
     }
-    $form_register->addElement('html', $form_data['button']);
+    if ($usersCanCreateCourse) {
+        $form_register->addElement('html', $form_data['button']);
+    } else {
+        $form_register->addElement('html', $form_data['go_button']);
+    }
     $text_after_registration .= $form_register->return_form();
 
     //Just in case

+ 1 - 0
main/calendar/agenda.inc.php

@@ -1969,6 +1969,7 @@ function get_attachment($agenda_id, $course_id = null)
  * @author Patrick Cool <patrick.cool@UGent.be>, Ghent University
  * @param integer id, the id of the agenda item we are editing. By default this is empty which means that we are adding an
  * 		 agenda item.
+ * @deprecated
  */
 function show_add_form($id = '', $type = null)
 {

+ 167 - 78
main/calendar/agenda.lib.php

@@ -273,7 +273,7 @@ class Agenda
     /**
     * @param int $eventId
     * @param string $type
-    * @param string $end date time
+    * @param string $end in local time
     * @param array $sentTo
     *
     * @return bool
@@ -282,10 +282,15 @@ class Agenda
     {
         $t_agenda = Database::get_course_table(TABLE_AGENDA);
         $t_agenda_r = Database::get_course_table(TABLE_AGENDA_REPEAT);
+
+        if (empty($this->course)) {
+            return false;
+        }
+
         $course_id = $this->course['real_id'];
         $eventId = intval($eventId);
 
-        $sql = "SELECT title, content, start_date as sd, end_date as ed, all_day
+        $sql = "SELECT title, content, start_date, end_date, all_day
                 FROM $t_agenda
                 WHERE c_id = $course_id AND id = $eventId";
         $res = Database::query($sql);
@@ -295,13 +300,14 @@ class Agenda
         }
 
         $row = Database::fetch_array($res);
-        $orig_start = api_strtotime($row['sd']);
-        $orig_end = api_strtotime($row['ed']);
+        $origStartDate = api_strtotime($row['start_date'], 'UTC');
+        $origEndDate = api_strtotime($row['end_date'], 'UTC');
+        $diff = $origEndDate - $origStartDate;
 
-        $diff = $orig_end - $orig_start;
         $title = $row['title'];
         $content = $row['content'];
         $allDay = $row['all_day'];
+
         $now = time();
         $type = Database::escape_string($type);
         $end = api_strtotime($end);
@@ -311,13 +317,13 @@ class Agenda
             //and that he wants us to calculate the end date with that (particularly in case of imports from ical)
             switch ($type) {
                 case 'daily':
-                    $end = $orig_start + (86400 * $end);
+                    $end = $origStartDate + (86400 * $end);
                     break;
                 case 'weekly':
-                    $end = $this->addWeek($orig_start, $end);
+                    $end = $this->addWeek($origStartDate, $end);
                     break;
                 case 'monthlyByDate':
-                    $end = $this->addMonth($orig_start, $end);
+                    $end = $this->addMonth($origStartDate, $end);
                     break;
                 case 'monthlyByDay':
                     //TODO
@@ -326,7 +332,7 @@ class Agenda
                     //TODO
                     break;
                 case 'yearly':
-                    $end = $this->addYear($orig_start, $end);
+                    $end = $this->addYear($origStartDate, $end);
                     break;
             }
         }
@@ -341,7 +347,7 @@ class Agenda
             switch ($type) {
                 // @todo improve loop.
                 case 'daily':
-                    for ($i = $orig_start + 86400; $i <= $end; $i += 86400) {
+                    for ($i = $origStartDate + 86400; $i <= $end; $i += 86400) {
                         $start = date('Y-m-d H:i:s', $i);
                         $repeatEnd = date('Y-m-d H:i:s', $i + $diff);
                         $this->add_event(
@@ -357,7 +363,7 @@ class Agenda
                     }
                     break;
                 case 'weekly':
-                    for ($i = $orig_start + 604800; $i <= $end; $i += 604800) {
+                    for ($i = $origStartDate + 604800; $i <= $end; $i += 604800) {
                         $start = date('Y-m-d H:i:s', $i);
                         $repeatEnd = date('Y-m-d H:i:s', $i + $diff);
                         $this->add_event(
@@ -373,7 +379,7 @@ class Agenda
                     }
                     break;
                 case 'monthlyByDate':
-                    $next_start = $this->addMonth($orig_start);
+                    $next_start = $this->addMonth($origStartDate);
                     while ($next_start <= $end) {
                         $start = date('Y-m-d H:i:s', $next_start);
                         $repeatEnd = date('Y-m-d H:i:s', $next_start + $diff);
@@ -397,7 +403,7 @@ class Agenda
                     //not yet implemented
                     break;
                 case 'yearly':
-                    $next_start = $this->addYear($orig_start);
+                    $next_start = $this->addYear($origStartDate);
                     while ($next_start <= $end) {
                         $start = date('Y-m-d H:i:s', $next_start);
                         $repeatEnd = date('Y-m-d H:i:s', $next_start + $diff);
@@ -416,6 +422,7 @@ class Agenda
                     break;
             }
         }
+
         return true;
     }
 
@@ -461,12 +468,12 @@ class Agenda
     /**
      * Edits an event
      *
-     * @param int       $id id
-     * @param string    $start datetime format: 2012-06-14 09:00:00
-     * @param string    $end datetime format: 2012-06-14 09:00:00
-     * @param int       $allDay is all day 'true' or 'false'
-     * @param string    $title
-     * @param string    $content
+     * @param int $id
+     * @param string $start datetime format: 2012-06-14 09:00:00
+     * @param string $end datetime format: 2012-06-14 09:00:00
+     * @param int $allDay is all day 'true' or 'false'
+     * @param string $title
+     * @param string $content
      * @param array $usersToSend
      * @param int $editRepeatType
      * @param array $attachmentArray
@@ -482,11 +489,11 @@ class Agenda
         $title,
         $content,
         $usersToSend = array(),
-        $editRepeatType = 1,
         $attachmentArray = array(),
         $attachmentComment = null
     ) {
         $start = api_get_utc_datetime($start);
+        $end = api_get_utc_datetime($end);
         $allDay = isset($allDay) && $allDay == 'true' ? 1 : 0;
 
         switch ($this->type) {
@@ -681,9 +688,6 @@ class Agenda
                         $this->store_agenda_item_as_announcement($id);
                     }*/
 
-                    // Repeat
-                    //$editRepeatType = null;
-
                     // Add attachment.
                     if (isset($attachmentArray) && !empty($attachmentArray)) {
                         $this->updateAttachment(
@@ -1144,6 +1148,9 @@ class Agenda
         $start = isset($start) && !empty($start) ? api_get_utc_datetime(intval($start)) : null;
         $end = isset($end) && !empty($end) ? api_get_utc_datetime(intval($end)) : null;
 
+        if (empty($courseInfo)) {
+            return array();
+        }
         $course_id = $courseInfo['real_id'];
         if (empty($course_id)) {
             return array();
@@ -1466,13 +1473,17 @@ class Agenda
      * @param FormValidator $form
      * @param array $groupList
      * @param array $userList
-     * @param array $sendTo array('users' => [1, 2], 'groups' => [3, 4]
+     * @param array $sendTo array('users' => [1, 2], 'groups' => [3, 4])
+     * @param array $attributes
+     * @param bool $addOnlyItemsInSendTo
      */
-    public static function construct_not_selected_select_form_validator(
+    public function setSendToSelect(
         $form,
         $groupList = null,
         $userList = null,
-        $sendTo = array()
+        $sendTo = array(),
+        $attributes = array(),
+        $addOnlyItemsInSendTo = false
     ) {
         $params = array(
             'id' => 'users_to_send_id',
@@ -1482,14 +1493,23 @@ class Agenda
             'class' => 'chzn-select'
         );
 
+        if (!empty($attributes)) {
+            $params = array_merge($params, $attributes);
+            if (empty($params['multiple'])) {
+                unset($params['multiple']);
+            }
+        }
+
         $sendToGroups = isset($sendTo['groups']) ? $sendTo['groups'] : array();
         $sendToUsers = isset($sendTo['users']) ? $sendTo['users'] : array();
+
         /** @var HTML_QuickForm_select $select */
         $select = $form->addElement('select', 'users_to_send', get_lang('To'), null, $params);
 
         $selectedEveryoneOptions = array();
         if (isset($sendTo['everyone']) && $sendTo['everyone']) {
             $selectedEveryoneOptions = array('selected');
+            $sendToUsers = array();
         }
 
         $select->addOption(get_lang('Everyone'), 'everyone', $selectedEveryoneOptions);
@@ -1507,11 +1527,19 @@ class Agenda
                 if ($selected) {
                     $option['selected'] = 'selected';
                 }
-                $options[] = $option;
+
+                if ($addOnlyItemsInSendTo) {
+                    if ($selected) {
+                        $options[] = $option;
+                    }
+                } else {
+                    $options[] = $option;
+                }
             }
             $select->addOptGroup($options, get_lang('Groups'));
         }
 
+
         // adding the individual users to the select form
         if (is_array($userList)) {
             $options = array();
@@ -1520,12 +1548,22 @@ class Agenda
                     'text' => api_get_person_name($user['firstname'], $user['lastname']).' ('.$user['username'].')',
                     'value' => "USER:".$user['user_id']
                 );
+
                 $selected = in_array($user['user_id'], $sendToUsers) ? true : false;
+
                 if ($selected) {
                     $option['selected'] = 'selected';
                 }
-                $options[] = $option;
+
+                if ($addOnlyItemsInSendTo) {
+                    if ($selected) {
+                        $options[] = $option;
+                    }
+                } else {
+                    $options[] = $option;
+                }
             }
+
             $select->addOptGroup($options, get_lang('Users'));
         }
     }
@@ -1582,6 +1620,7 @@ class Agenda
         } else {
             $url = api_get_self().'?action='.$action.'&id='.$id.'&type='.$this->type;
         }
+
         $form = new FormValidator(
             'add_event',
             'post',
@@ -1605,6 +1644,32 @@ class Agenda
         $form->addElement('hidden', 'id', $id);
         $form->addElement('hidden', 'action', $action);
         $form->addElement('hidden', 'id_attach', $idAttach);
+
+        $isSubEventEdition = false;
+        $isParentFromSerie = false;
+        $showAttachmentForm = true;
+
+        if ($this->type == 'course') {
+            // Edition mode.
+            if (!empty($id)) {
+                $showAttachmentForm = false;
+                if (isset($params['parent_event_id']) && !empty($params['parent_event_id'])) {
+                    $isSubEventEdition = true;
+                }
+                if (!empty($params['repeat_info'])) {
+                    $isParentFromSerie = true;
+                }
+            }
+        }
+
+        if ($isSubEventEdition) {
+            $form->addElement(
+                'label',
+                null,
+                Display::return_message(get_lang('EditingThisEventWillRemoveItFromTheSerie'), 'warning')
+            );
+        }
+
         $form->addElement('text', 'title', get_lang('ItemTitle'));
 
         if (isset($groupId) && !empty($groupId)) {
@@ -1613,45 +1678,33 @@ class Agenda
         } else {
             $sendTo = isset($params['send_to']) ? $params['send_to'] : null;
             if ($this->type == 'course') {
-                self::show_to_form($form, $sendTo);
+                $this->showToForm($form, $sendTo);
             }
         }
 
-        //$form->addElement('date_time_picker', 'start_date', get_lang('StartDate'), array('id' => 'start_date_form'));
-        //$form->addElement('date_time_picker', 'end_date', get_lang('EndDate'), array('id' => 'end_date_form'));
-
         $form->addDateRangePicker('date_range', get_lang('StartDate'), false, array('id' => 'date_range'));
         $form->addElement('checkbox', 'all_day', null, get_lang('AllDay'));
 
-        $showRepeatWarning = false;
-        $showAttachmentForm = true;
-
         if ($this->type == 'course') {
             $repeat = $form->addElement('checkbox', 'repeat', null, get_lang('RepeatEvent'), array('onclick' => 'return plus_repeated_event();'));
             $form->addElement('html', '<div id="options2" style="display:none">');
             $form->addElement('select', 'repeat_type', get_lang('RepeatType'), self::getRepeatTypes());
             $form->addElement('date_picker', 'repeat_end_day', get_lang('RepeatEnd'), array('id' => 'repeat_end_date_form'));
 
-            if (!empty($id)) {
-                if (isset($params['parent_event_id']) && !empty($params['parent_event_id'])) {
+            if ($isSubEventEdition || $isParentFromSerie) {
+                if ($isSubEventEdition) {
                     $parentEvent = $params['parent_info'];
                     $repeatInfo = $parentEvent['repeat_info'];
-                    $params['repeat'] = 1;
-                    $params['repeat_type'] = $repeatInfo['cal_type'];
-                    $params['repeat_end_day'] = substr(api_get_local_time($repeatInfo['cal_end']), 0, 10);
-                    /*$group = array(
-                        $form->createElement('radio', 'edit_repeat_type', null, get_lang('EditThisEvent'), 1),
-                        $form->createElement('radio', 'edit_repeat_type', null, get_lang('RemoveThisEventAndCreateANewOne'), 2),
-                    );
-                    $params['edit_repeat_type'] = 1;
-                    $form->addGroup($group);*/
-                    $form->freeze(array('repeat_type', 'repeat_end_day'));
-                    $repeat->_attributes['disabled'] = 'disabled';
-                    $showRepeatWarning = true;
-                    $showAttachmentForm = false;
+                } else {
+                    $repeatInfo = $params['repeat_info'];
                 }
-            }
+                $params['repeat'] = 1;
+                $params['repeat_type'] = $repeatInfo['cal_type'];
+                $params['repeat_end_day'] = substr(api_get_local_time($repeatInfo['cal_end']), 0, 10);
 
+                $form->freeze(array('repeat_type', 'repeat_end_day'));
+                $repeat->_attributes['disabled'] = 'disabled';
+            }
             $form->addElement('html', '</div>');
         }
 
@@ -1709,13 +1762,6 @@ class Agenda
             );
         }
 
-        if ($showRepeatWarning) {
-            $form->addElement(
-                'label',
-                null,
-                Display::return_message(get_lang('EditingThisEventWillRemoveItFromTheSerie'))
-            );
-        }
         $form->addElement('button', 'submit', $button);
         $form->setDefaults($params);
 
@@ -1727,10 +1773,21 @@ class Agenda
 
     /**
      * @param FormValidator $form
-     * @param array $sendTo
+     * @param array $sendTo array('everyone' => false, 'users' => [1, 2], 'groups' => [3, 4])
+     * @param array $attributes
+     * @param bool $addOnlyItemsInSendTo
+     * @return bool
      */
-    static function show_to_form($form, $sendTo = array())
-    {
+    public function showToForm(
+        $form,
+        $sendTo = array(),
+        $attributes = array(),
+        $addOnlyItemsInSendTo = false
+    ) {
+        if ($this->type != 'course') {
+            return false;
+        }
+
         $order = 'lastname';
         if (api_is_western_name_order()) {
             $order = 'firstname';
@@ -1747,12 +1804,16 @@ class Agenda
             api_get_session_id()
         );
 
-        self::construct_not_selected_select_form_validator(
+        $this->setSendToSelect(
             $form,
             $groupList,
             $userList,
-            $sendTo
+            $sendTo,
+            $attributes,
+            $addOnlyItemsInSendTo
         );
+        return true;
+
     }
 
     /**
@@ -2031,31 +2092,30 @@ class Agenda
      */
     public function displayActions($view, $filter = 0)
     {
-        if ($view == 'calendar') {
-            $actions = "<a href='".api_get_path(WEB_CODE_PATH)."calendar/agenda_list.php?type={$this->type}&".api_get_cidreq()."'>".
-                Display::return_icon('week.png', get_lang('AgendaList'), '', ICON_SIZE_MEDIUM)."</a>";
-        } else {
-            $actions = "<a href='".api_get_path(WEB_CODE_PATH)."calendar/agenda_js.php?type={$this->type}'>".
-                Display::return_icon('calendar.png', get_lang('Calendar'), '', ICON_SIZE_MEDIUM)."</a>";
-        }
+        $actions = "<a href='".api_get_path(WEB_CODE_PATH)."calendar/agenda_js.php?type={$this->type}'>".
+            Display::return_icon('calendar.png', get_lang('Calendar'), '', ICON_SIZE_MEDIUM)."</a>";
+
+        $actions .= "<a href='".api_get_path(WEB_CODE_PATH)."calendar/agenda_list.php?type={$this->type}&".api_get_cidreq()."'>".
+            Display::return_icon('week.png', get_lang('AgendaList'), '', ICON_SIZE_MEDIUM)."</a>";
 
         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(), api_get_group_id(), GroupManager::GROUP_TOOL_CALENDAR) &&
             GroupManager::is_tutor_of_group(api_get_user_id(), api_get_group_id())
         ) {
-
             if ($this->type == 'course') {
                 $form = null;
                 if (!isset($_GET['action'])) {
-                    $form = show_to($filter, 'select_form_id_search');
-                    /*$actions .= "<a href='".api_get_path(WEB_CODE_PATH)."calendar/agenda_js.php?type=course&".api_get_cidreq()."'>".
-                        Display::return_icon('calendar_na.png', get_lang('Agenda'), '', ICON_SIZE_MEDIUM)."</a>";*/
-                } else {
-                 /*   $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>";*/
-                }
+                    $form = new FormValidator('form-search');
+                    $attributes = array(
+                        'multiple' => false,
+                        'id' => 'select_form_id_search'
+                    );
+                    $selectedValues = $this->parseAgendaFilter($filter);
+                    $this->showToForm($form, $selectedValues, $attributes);
+                    $form = $form->return_form();
 
+                }
                 $actions .= "<a href='".api_get_path(WEB_CODE_PATH)."calendar/agenda.php?".api_get_cidreq()."&action=add&type=course'>".
                     Display::return_icon('new_event.png', get_lang('AgendaAdd'), '', ICON_SIZE_MEDIUM)."</a>";
                 $actions .= "<a href='".api_get_path(WEB_CODE_PATH)."calendar/agenda.php?".api_get_cidreq()."&action=importical&type=course'>".
@@ -2195,5 +2255,34 @@ class Agenda
         return $messages;
     }
 
+    /**
+     * Parse filter turns USER:12 to ['users' => [12])] or G:1 ['groups' => [1]]
+     * @param $filter
+     * @return array
+     */
+    public function parseAgendaFilter($filter)
+    {
+        $everyone = false;
+        $groupId = null;
+        $userId = null;
 
+        if ($filter == 'everyone') {
+            $everyone = true;
+        } else {
+            if (substr($filter, 0, 1) == 'G') {
+                $groupId = str_replace('GROUP:', '', $filter);
+            } else {
+                $userId = str_replace('USER:', '', $filter);
+            }
+        }
+        if (empty($userId) && empty($groupId)) {
+            $everyone = true;
+        }
+
+        return array(
+            'everyone' => $everyone,
+            'users' => array($userId),
+            'groups' => array($groupId)
+        );
+    }
 }

+ 13 - 35
main/calendar/agenda.php

@@ -26,7 +26,7 @@ $action = isset($_GET['action']) ? $_GET['action'] : null;
 $origin = isset($_GET['origin']) ? $_GET['origin'] : null;
 
 $this_section = SECTION_COURSES;
-
+$url = null;
 if (empty($action)) {
     if (!empty($course_info)) {
         $url = api_get_path(WEB_CODE_PATH).'calendar/agenda_js.php?type=course'.'&'.api_get_cidreq();
@@ -93,6 +93,7 @@ $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() &&
@@ -102,6 +103,7 @@ if (api_is_allowed_to_edit(false, true) OR
 ) {
     switch ($action) {
         case 'add':
+            $actionName = get_lang('Add');
             $form = $agenda->getForm(array('action' => 'add'));
 
             if ($form->validate()) {
@@ -152,7 +154,9 @@ if (api_is_allowed_to_edit(false, true) OR
             }
             break;
         case 'edit':
+            $actionName = get_lang('Edit');
             $event = $agenda->get_event($eventId);
+
             if (empty($event)) {
                 api_not_allowed(true);
             }
@@ -168,7 +172,7 @@ if (api_is_allowed_to_edit(false, true) OR
                 $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;
@@ -207,7 +211,6 @@ if (api_is_allowed_to_edit(false, true) OR
                     $values['title'],
                     $values['content'],
                     $values['users_to_send'],
-                    $repeatType,
                     $attachment,
                     $attachmentComment
                 );
@@ -232,15 +235,6 @@ if (api_is_allowed_to_edit(false, true) OR
                     );
                 }
 
-                if (!empty($values['repeat']) && !empty($eventId)) {
-                    $agenda->addRepeatedItem(
-                        $eventId,
-                        $values['repeat_type'],
-                        $values['repeat_end_day'],
-                        $values['users_to_send']
-                    );
-                }
-
                 $message = Display::return_message(get_lang('Updated'), 'confirmation');
                 Session::write('message', $message);
                 header("Location: $agendaUrl");
@@ -250,21 +244,6 @@ if (api_is_allowed_to_edit(false, true) OR
 
             }
             break;
-        case "announce":
-            //copying the agenda item into an announcement
-            /*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($eventId);
-                $tool_group_link = (isset($_SESSION['toolgroup']) ? '&toolgroup='.$_SESSION['toolgroup'] : '');
-                $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':
             $form = $agenda->getImportCalendarForm();
             $content = $form->return_form();
@@ -299,13 +278,6 @@ if (api_is_allowed_to_edit(false, true) OR
                 $content = $agenda->delete_event($eventId);
             }
             break;
-        case "showhide":
-            /*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
-                $content = showhide_agenda_item($eventId);
-                $action = 'view';
-            }*/
-            break;
     }
 }
 
@@ -320,6 +292,12 @@ if (!empty($group_id)) {
         "name" => get_lang('GroupSpace').' '.$group_properties['name']
     );
 }
+if (!empty($actionName)) {
+    $interbreadcrumb[] = array(
+        "url" => $url,
+        "name" => get_lang('Agenda')
+    );
+}
 
 // Tool introduction
 $introduction = Display::return_introduction_section(TOOL_CALENDAR_EVENT);
@@ -327,7 +305,7 @@ $introduction = Display::return_introduction_section(TOOL_CALENDAR_EVENT);
 $message = Session::read('message');
 Session::erase('message');
 
-$tpl = new Template(get_lang('Agenda'));
+$tpl = new Template($actionName);
 $tpl->assign('content', $content);
 $tpl->assign('actions', $actions);
 

+ 30 - 42
main/calendar/agenda_js.php

@@ -16,6 +16,7 @@ $use_anonymous = true;
 
 // Calendar type
 $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
@@ -144,8 +145,7 @@ $tpl->assign(
     Display::return_icon($export_icon_high, get_lang('ExportiCalConfidential'))
 );
 
-$filter = null;
-$actions = $agenda->displayActions('calendar', $filter);
+$actions = $agenda->displayActions('calendar', $userId);
 
 $tpl->assign('actions', $actions);
 
@@ -180,58 +180,46 @@ $tpl->assign('type_event_class', $type_event_class);
 // 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') {
 
-    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());
-    }
+    $form = new FormValidator('form', 'get', null, null, array('id' => 'add_event_form'));
+    $form->addElement('html', '<div id="visible_to_input">');
 
-    // This will fill the select called #users_to_send_id.
+    $sendTo = $agenda->parseAgendaFilter($userId);
+    $addOnlyItemsInSendTo = true;
 
-    if (isset($_REQUEST['user_id'])) {
-        if (in_array($_REQUEST['user_id'], array_keys($user_list))) {
-            $userInfo = api_get_user_info($_REQUEST['user_id']);
-            if (!empty($userInfo)) {
-                $user_list = array($userInfo['user_id'] => $userInfo);
-                $group_list = array();
-            }
-        }
+    if ($sendTo['everyone']) {
+        $addOnlyItemsInSendTo = false;
+    }
 
-        $param = explode(':', $_REQUEST['user_id']);
-        if (isset($param[1]) && in_array($param[1], array_keys($group_list))) {
-            $groupInfo = GroupManager::get_group_properties($param[1]);
-            if ($groupInfo) {
-                $group_list = array($groupInfo['id'] => $groupInfo);
-                $user_list = array();
-            }
-        }
+    $agenda->showToForm($form, $sendTo, array(), $addOnlyItemsInSendTo);
+    $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>');
     }
 
-    $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.
 $content = $tpl->fetch('default/agenda/month.tpl');

+ 30 - 29
main/coursecopy/classes/CourseCopyLearnpath.class.php

@@ -9,82 +9,81 @@ class CourseCopyLearnpath extends Resource {
 	/**
 	 * Type of learnpath (can be dokeos (1), scorm (2), aicc (3))
 	 */
-	var $lp_type;
+	public $lp_type;
 	/**
 	 * The name
 	 */
-	var $name;
+	public $name;
 	/**
 	 * The reference
 	 */
-	var $ref;
+	public $ref;
 	/**
 	 * The description
 	 */
-	var $description;
+	public $description;
 	/**
 	 * Path to the learning path files
 	 */
-	var $path;
+	public $path;
 	/**
 	 * Whether additional commits should be forced or not
 	 */
-	var $force_commit;
+	public $force_commit;
 	/**
 	 * View mode by default ('embedded' or 'fullscreen')
 	 */
-	var $default_view_mod;
+	public $default_view_mod;
 	/**
 	 * Default character encoding
 	 */
-	var $default_encoding;
+	public $default_encoding;
 	/**
 	 * Display order
 	 */
-	var $display_order;
+	public $display_order;
 	/**
 	 * Content editor/publisher
 	 */
-	var $content_maker;
+	public $content_maker;
 	/**
 	 * Location of the content (local or remote)
 	 */
-	var $content_local;
+	public $content_local;
 	/**
 	 * License of the content
 	 */
-	var $content_license;
+	public $content_license;
 	/**
 	 * Whether to prevent reinitialisation or not
 	 */
-	var $prevent_reinit;
+	public $prevent_reinit;
 	/**
 	 * JavaScript library used
 	 */
-	var $js_lib;
+	public $js_lib;
 	/**
 	 * Debug level for this lp
 	 */
-	var $debug;
+	public $debug;
 	/**
 	 * The items
 	 */
-	var $items;
+	public $items;
 	/**
 	 * The learnpath visibility on the homepage
 	 */
-	var $visibility;
-	
+	public $visibility;
+
 	/**
 	 * Author info
 	 */
-	var $author;
-	
+	public $author;
+
 	/**
 	 * Author's image
 	 */
-	var $preview_image;
-								
+	public $preview_image;
 
 	/**
 	 * Create a new learnpath
@@ -127,18 +126,18 @@ class CourseCopyLearnpath extends Resource {
 		$this->content_license = $content_license;
 		$this->debug = $debug;
 		$this->visibility=$visibility;
-		
+
 		$this->use_max_score=$use_max_score;
 		$this->autolunch=$autolunch;
 		$this->created_on=$created_on;
 		$this->modified_on=$modified_on;
 		$this->publicated_on=$publicated_on;
 		$this->expired_on=$expired_on;
-		$this->session_id=$session_id;	
-		
+		$this->session_id=$session_id;
+
 		$this->author= $author;
 		$this->preview_image= $preview_image;
-		
+
 		$this->items = $items;
 	}
 	/**
@@ -153,8 +152,10 @@ class CourseCopyLearnpath extends Resource {
 	 */
 	function has_item($resource)
 	{
-		foreach($this->items as $index => $item) {
-			if( $item['id'] == $resource->get_id() && $item['type'] == $resource->get_type()) {
+		foreach ($this->items as $item) {
+			if ($item['id'] == $resource->get_id() &&
+                isset($item['type']) && $item['type'] == $resource->get_type()
+            ) {
 				return true;
 			}
 		}
@@ -167,4 +168,4 @@ class CourseCopyLearnpath extends Resource {
 		parent::show();
 		echo $this->name;
 	}
-}
+}

+ 130 - 125
main/coursecopy/classes/CourseRestorer.class.php

@@ -113,11 +113,17 @@ class CourseRestorer
 		$this->file_option = $option;
 	}
 
+    /**
+     * @param string $status
+     */
     function set_add_text_in_items($status)
     {
         $this->add_text_in_items = $status;
     }
 
+    /**
+     * @param array $array
+     */
     function set_tool_copy_settings($array)
     {
         $this->tool_copy_settings = $array;
@@ -125,10 +131,10 @@ class CourseRestorer
 
 	/**
 	 * Restore a course.
-	 * @param 	string 	The code of the Chamilo-course in
-	 * @param	int		The session id
-	 * @param	bool	Course settings are going to be restore?
-
+	 * @param string 	The code of the Chamilo-course in
+	 * @param int		The session id
+	 * @param bool	Course settings are going to be restore?
+     * @param bool
 	 */
     public function restore(
         $destination_course_code = '',
@@ -1829,37 +1835,53 @@ class CourseRestorer
 
 		}
 	}
+
 	/**
-	 * restore works
+	 * Restore works
+     * @deprecated use restore_works
+     *
 	 */
-	function restore_student_publication() {
+	public function restore_student_publication()
+    {
 		$work_assignment_table  = Database :: get_course_table(TABLE_STUDENT_PUBLICATION_ASSIGNMENT);
 		$work_table    			= Database :: get_course_table(TABLE_STUDENT_PUBLICATION);
 		$item_property_table  	= Database :: get_course_table(TABLE_ITEM_PROPERTY);
 
-		//query in student publication
-		$sql = 'SELECT c_id, id, url, title,description,author,active,accepted,post_group_id, sent_date,filetype,has_properties,view_properties,qualification,date_of_qualification,qualificator_id,session_id
-		      FROM '.$work_table.'
-		      WHERE c_id = '.$this->course_origin_id.' AND filetype="folder" AND active IN (0, 1) ';
+		// Query in student publication
+		$sql = 'SELECT * FROM '.$work_table.'
+		        WHERE c_id = '.$this->course_origin_id.' AND filetype = "folder" AND active IN (0, 1) ';
 
 		$result = Database::query($sql);
 		$folders = Database::store_result($result, 'ASSOC');
 
 		foreach ($folders  as $folder) {
 		    $old_id = $folder['id'];
-
             unset($folder['id']);
 			$folder['c_id'] = $this->destination_course_id;
             $folder['parent_id'] = 0;
 			$new_id = Database::insert($work_table, $folder);
 
             if ($new_id) {
-                 //query in item property
-                $sql = 'SELECT tool,insert_user_id,insert_date,lastedit_date,ref,lastedit_type, lastedit_user_id,to_group_id,to_user_id,visibility,start_visible, end_visible
-                           FROM '.$item_property_table.' ip INNER JOIN '.$work_table.' sp ON ip.ref=sp.id
-                           WHERE  sp.c_id = '.$this->course_origin_id.' AND
-                                  ip.c_id = '.$this->course_origin_id.' AND
-                                  tool="work" AND sp.id = '.$old_id.'';
+                //query in item property
+                $sql = 'SELECT
+                        tool,
+                        insert_user_id,
+                        insert_date,
+                        lastedit_date,
+                        ref,
+                        lastedit_type,
+                        lastedit_user_id,
+                        to_group_id,
+                        to_user_id,
+                        visibility,
+                        start_visible,
+                        end_visible
+                        FROM '.$item_property_table.' ip
+                        INNER JOIN '.$work_table.' sp ON ip.ref=sp.id
+                        WHERE
+                            sp.c_id = '.$this->course_origin_id.' AND
+                            ip.c_id = '.$this->course_origin_id.' AND
+                            tool="work" AND sp.id = '.$old_id.'';
 
                 $result = Database::query($sql);
                 $sub_folders = Database::store_result($result, 'ASSOC');
@@ -1870,14 +1892,15 @@ class CourseRestorer
                 }
 
                 $sql = 'SELECT sa.id, sa.expires_on,sa.ends_on,sa.add_to_calendar, sa.enable_qualification, sa.publication_id
-                          FROM '.$work_assignment_table.' sa INNER JOIN '.$work_table.' sp ON sa.publication_id=sp.id
-                          WHERE   sp.c_id = '.$this->course_origin_id.' AND
-                                  sa.c_id = '.$this->course_origin_id.' AND
-                                  filetype="folder" AND sp.id = '.$old_id.'';
+                        FROM '.$work_assignment_table.' sa INNER JOIN '.$work_table.' sp ON sa.publication_id=sp.id
+                        WHERE
+                            sp.c_id = '.$this->course_origin_id.' AND
+                            sa.c_id = '.$this->course_origin_id.' AND
+                            filetype="folder" AND sp.id = '.$old_id.'';
 
                 $result = Database::query($sql);
                 $assing_list = Database::store_result($result, 'ASSOC');
-                foreach($assing_list  as $assign) {
+                foreach ($assing_list  as $assign) {
                     $assign['c_id'] = $this->destination_course_id;
                     $assign['id'] = $new_id;
                     Database::insert($work_assignment_table, $assign);
@@ -1885,41 +1908,43 @@ class CourseRestorer
             }
 		}
 
-		$destination='../../courses/'.$this->course->destination_path.'/work/';
-		$origin='../../courses/'.$this->course->info['path'].'/work/';
+		$destination = '../../courses/'.$this->course->destination_path.'/work/';
+		$origin = '../../courses/'.$this->course->info['path'].'/work/';
 		self::allow_create_all_directory($origin,$destination,false);
 	}
 
-/**
- * copy all directory and sub directory
- * @param string The path origin
- * @param string The path destination
- * @param boolean Option Overwrite
- * @return void()
- */
-	function allow_create_all_directory($source, $dest, $overwrite = false) {
-   		if(!is_dir($dest)) {
-   			mkdir($dest, api_get_permissions_for_new_directories());
-   		}
-	    if ($handle = opendir($source)) {        // if the folder exploration is sucsessful, continue
-	        while (false !== ($file = readdir($handle))) { // as long as storing the next file to $file is successful, continue
-	            if ($file != '.' && $file != '..') {
-	                $path = $source . '/' . $file;
-	                if (is_file($path)) {
-	                   /* if (!is_file($dest . '/' . $file) || $overwrite)
-	                    if (!@copy($path, $dest . '/' . $file)) {
-	                        echo '<font color="red">File ('.$path.') '.get_lang('NotHavePermission').'</font>';
-	                    }*/
-	                } elseif(is_dir($path)) {
-	                    if (!is_dir($dest . '/' . $file))
-	                    mkdir($dest . '/' . $file);
-	                   self:: allow_create_all_directory($path, $dest . '/' . $file, $overwrite);
-	                }
-	            }
-	        }
-	        closedir($handle);
-	    }
-	}
+    /**
+    * copy all directory and sub directory
+    * @param string The path origin
+    * @param string The path destination
+    * @param boolean Option Overwrite
+    * @return void()
+    * @deprecated
+    */
+    function allow_create_all_directory($source, $dest, $overwrite = false)
+    {
+        if (!is_dir($dest)) {
+            mkdir($dest, api_get_permissions_for_new_directories());
+        }
+        if ($handle = opendir($source)) {        // if the folder exploration is sucsessful, continue
+            while (false !== ($file = readdir($handle))) { // as long as storing the next file to $file is successful, continue
+                if ($file != '.' && $file != '..') {
+                    $path = $source . '/' . $file;
+                    if (is_file($path)) {
+                       /* if (!is_file($dest . '/' . $file) || $overwrite)
+                        if (!@copy($path, $dest . '/' . $file)) {
+                            echo '<font color="red">File ('.$path.') '.get_lang('NotHavePermission').'</font>';
+                        }*/
+                    } elseif(is_dir($path)) {
+                        if (!is_dir($dest . '/' . $file))
+                        mkdir($dest . '/' . $file);
+                       self:: allow_create_all_directory($path, $dest . '/' . $file, $overwrite);
+                    }
+                }
+            }
+            closedir($handle);
+        }
+    }
 
 	/**
 	 * Gets the new ID of one specific tool item from the tool name and the old ID
@@ -2100,20 +2125,27 @@ class CourseRestorer
 	}
 
     /**
-     * Restore Work
+     * Restore Works
+     * @param int $sessionId
      */
-    function restore_works($session_id = 0)
+    function restore_works($sessionId = 0)
     {
-        $perm = api_get_permissions_for_new_directories();
+        require_once api_get_path(SYS_CODE_PATH).'work/work.lib.php';
         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);
 
             $resources = $this->course->resources;
-            foreach ($resources[RESOURCE_WORK] as $id => $obj) {
+            foreach ($resources[RESOURCE_WORK] as $obj) {
 
                 // check resources inside html from fckeditor tool and copy correct urls into recipient course
-                $obj->params['description'] = DocumentManager::replace_urls_inside_content_html_from_copy_course($obj->params['description'], $this->course->code, $this->course->destination_path, $this->course->backup_path, $this->course->info['path']);
+                $obj->params['description'] = DocumentManager::replace_urls_inside_content_html_from_copy_course(
+                    $obj->params['description'],
+                    $this->course->code,
+                    $this->course->destination_path,
+                    $this->course->backup_path,
+                    $this->course->info['path']
+                );
+
                 $id_work = $obj->params['id'];
                 $obj->params['id'] = null;
                 $obj->params['c_id'] = $this->destination_course_id;
@@ -2122,80 +2154,53 @@ class CourseRestorer
                 // @todo check security against injection of dir in crafted course backup here!
                 $path = $obj->params['url'];
                 $path = '/'.str_replace('/','',substr($path,1));
-                $destination_path = api_get_path(SYS_COURSE_PATH).$this->course->destination_path.'/work'.$path;
-                if (!file_exists($destination_path) && is_dir($destination_path)) {
-                    $r = @mkdir($destination_path, $perm);
-                    if ($r === false) {
-                        error_log('Failed creating directory '.$destination_path.' in course restore for work tool');
-                    }
 
-                    $last_id = Database::insert($table_work, $obj->params);
-                    if (is_numeric($last_id)) {
-                        $sql = 'SELECT *
-                                FROM '.$table_work_assignment.'
-                                WHERE  c_id = '.$this->course_origin_id.' AND
-                                       publication_id = '.$id_work;
+                $workData = array();
+                switch ($this->file_option) {
+                    case FILE_SKIP:
+                        $workData = get_work_data_by_path($path, $this->destination_course_info['real_id']);
+                        if (!empty($workData)) {
+                            continue;
+                        }
+                    case FILE_OVERWRITE:
+                        // Creating folder.
+                        $workData = get_work_data_by_path($path, $this->destination_course_info['real_id']);
+                    case FILE_RENAME:
+                        $obj->params['new_dir'] = $obj->params['title'];
+                        $sql = 'SELECT * FROM '.$table_work_assignment.'
+                                WHERE
+                                    c_id = '.$this->course_origin_id.' AND
+                                    publication_id = '.$id_work;
 
                         $result = Database::query($sql);
                         $cant = Database::num_rows($result);
                         if ($cant > 0) {
                             $row = Database::fetch_assoc($result);
-                            $expires_date = $row['expires_on'];
-                            $end_date = $row['ends_on'];
-                            $add_to_calendar = $row['add_to_calendar'];
-                            $enable_calification = $row['enable_calification'];
-                            $sql_add_homework = "INSERT INTO $table_work_assignment SET
-                                                        c_id                 = $this->destination_course_id ,
-                                                        expires_on       		= '$expires_date',
-                                                        ends_on        	 	 = '$end_date',
-                                                        add_to_calendar  		= '$add_to_calendar',
-                                                        enable_qualification = '$enable_calification',
-                                                        publication_id 			= '$last_id'";
-                            Database::query($sql_add_homework);
                         }
-                        api_item_property_update($this->destination_course_info, 'work', $last_id,"DirectoryCreated", api_get_user_id());
-                    }
-                } elseif ($this->file_option == FILE_RENAME) {
-                    $i = 1;
-                    $new_path = $destination_path.'_'.$i;
-                    $folder_exists = file_exists($new_path);
-                    while ($folder_exists) {
-                        $i ++;
-                        $new_path = $destination_path.'_'.$i;
-                        $folder_exists = file_exists($path.$new_path);
-                    }
-                    $r = @mkdir($new_path, $perm);
-                    if ($r === false) {
-                        error_log('Failed creating directory '.$new_path.' in course restore for work tool');
-                    }
-                    $obj->params['url'] .= '_'.$i;
-                    $obj->params['title'] .= '_'.$i;
-                    $last_id = Database::insert($table_work, $obj->params);
-                    if (is_numeric($last_id)) {
-                        $sql = 'SELECT *
-                            FROM '.$table_work_assignment.'
-                            WHERE  c_id = '.$this->course_origin_id.' AND
-                                   publication_id = '.$id_work;
 
-                        $result = Database::query($sql);
-                        $cant = Database::num_rows($result);
-                        if ($cant > 0) {
-                            $row = Database::fetch_assoc($result);
-                            $expires_date = $row['expires_on'];
-                            $end_date = $row['ends_on'];
-                            $add_to_calendar = $row['add_to_calendar'];
-                            $enable_calification = $row['enable_calification'];
-                            $sql_add_homework = "INSERT INTO $table_work_assignment SET
-                                                    c_id                 = $this->destination_course_id ,
-                                                    expires_on       		= '$expires_date',
-                                                    ends_on        	 	 = '$end_date',
-                                                    add_to_calendar  		= '$add_to_calendar',
-                                                    enable_qualification = '$enable_calification',
-                                                    publication_id 			= '$last_id'";
-                            Database::query($sql_add_homework);
+                        //$obj->params['qualification'] = empty($row['enable_qualification']) ? true : false;
+                        $obj->params['enableExpiryDate'] = $row['expires_on'] == '0000-00-00 00:00:00' ? false : true;
+                        $obj->params['enableEndDate'] = $row['ends_on'] == '0000-00-00 00:00:00' ? false : true;
+
+                        $obj->params['expires_on'] = $row['expires_on'];
+                        $obj->params['ends_on'] = $row['ends_on'];
+                        $obj->params['enable_qualification'] = $row['enable_qualification'];
+                        $obj->params['add_to_calendar'] = !empty($row['add_to_calendar']) ? 1 : 0;
+
+                        if (empty($workData)) {
+                            addDir(
+                                $obj->params,
+                                api_get_user_id(),
+                                $this->destination_course_info,
+                                0,
+                                0
+                            );
+                        } else {
+                            $workId = $workData['id'];
+                            updateWork($workId, $obj->params, $this->destination_course_info);
+                            updatePublicationAssignment($workId, $obj->params, $this->destination_course_info, 0);
                         }
-                        api_item_property_update($this->destination_course_info, 'work', $last_id,"DirectoryCreated", api_get_user_id());
-                    }
+                        break;
                 }
             }
         }

+ 7 - 5
main/coursecopy/classes/CourseSelectForm.class.php

@@ -1,6 +1,5 @@
 <?php
 /* For licensing terms, see /license.txt */
-
 require_once 'Course.class.php';
 
 /**
@@ -475,7 +474,7 @@ class CourseSelectForm
                         }
                         break;
                     case RESOURCE_LEARNPATH:
-                        $lps = $_POST['resource'][RESOURCE_LEARNPATH];
+                        $lps = isset($_POST['resource'][RESOURCE_LEARNPATH]) ? $_POST['resource'][RESOURCE_LEARNPATH] : null;
                         if (!empty($lps)) {
                             foreach ($lps as $id => $obj) {
                                 $lp_resource = $course->resources[RESOURCE_LEARNPATH][$id];
@@ -499,9 +498,12 @@ class CourseSelectForm
 						// but in which a document was selected.
 						$documents = isset($_POST['resource'][RESOURCE_DOCUMENT]) ? $_POST['resource'][RESOURCE_DOCUMENT] : null;
 						if (!empty($resources) && is_array($resources))
-							foreach($resources as $id => $obj) {
-								if ($obj->file_type == 'folder' && ! isset($_POST['resource'][RESOURCE_DOCUMENT][$id]) && is_array($documents)) {
-									foreach($documents as $id_to_check => $post_value) {
+							foreach ($resources as $id => $obj) {
+								if (isset($obj->file_type) && $obj->file_type == 'folder' &&
+                                    !isset($_POST['resource'][RESOURCE_DOCUMENT][$id]) &&
+                                    is_array($documents)
+                                ) {
+									foreach ($documents as $id_to_check => $post_value) {
 										$obj_to_check = $resources[$id_to_check];
 										$shared_path_part = substr($obj_to_check->path,0,strlen($obj->path));
 										if ($id_to_check != $id && $obj->path == $shared_path_part) {

+ 19 - 12
main/coursecopy/classes/Resource.class.php

@@ -42,41 +42,42 @@ define('RESOURCE_WORK', 'work');
  * @todo Use the gloabaly defined constants voor tools and remove the RESOURCE_*
  * constants
  */
-class Resource {
-
+class Resource
+{
     /**
      * The id from this resource in the source course
      */
-    var $source_id;
+    public $source_id;
 
     /**
      * The id from this resource in the destination course
      */
-    var $destination_id;
+    public $destination_id;
 
     /**
      * The type of this resource
      */
-    var $type;
+    public $type;
 
     /**
      * Linked resources
      */
-    var $linked_resources;
+    public $linked_resources;
 
     /**
      * The properties of this resource
      */
-    var $item_properties;
+    public $item_properties;
 
-    var $obj = null;
+    public $obj = null;
 
     /**
      * Create a new Resource
      * @param int $id The id of this resource in the source course.
      * @param constant $type The type of this resource.
      */
-    function Resource($id, $type) {
+    function Resource($id, $type)
+    {
         $this->source_id = $id;
         $this->type = $type;
         $this->destination_id = -1;
@@ -102,8 +103,14 @@ class Resource {
      * Checks if this resource links to a given resource
      */
     function links_to(& $resource) {
-        if (is_array($this->linked_resources[$resource->get_type()])) {
-            return in_array($resource->get_id(), $this->linked_resources[$resource->get_type()]);
+        $type = $resource->get_type();
+        if (isset($this->linked_resources[$type]) &&
+            is_array($this->linked_resources[$type])
+        ) {
+            return in_array(
+                $resource->get_id(),
+                $this->linked_resources[$type]
+            );
         }
         return false;
     }
@@ -212,4 +219,4 @@ class Resource {
     function show() {
         //echo 'RESOURCE: '.$this->get_id().' '.$type[$this->get_type()].' ';
     }
-}
+}

+ 0 - 1
main/css/academica/default.css

@@ -574,7 +574,6 @@ input.span3, textarea.span3, .uneditable-input.span3 {
     font-weight: bold;
     font-size: 18px;
     padding-left: 10px;
-    width: 250px;
 }
 #course_tools .course-title-tools h3 {
     margin-top: 10px;

+ 1 - 1
main/css/academica/scorm.css

@@ -432,7 +432,7 @@ opacity: 0.7;
 }
 
 /*STYLES PROCESS LESSION*/
-.inner_lp_toc .scrom_completed {
+.inner_lp_toc .scorm_completed {
     
     background-image: url("images/blue_arrow.png") !important;
     background-position: 250px center !important;

+ 0 - 1
main/css/baby_orange/default.css

@@ -508,7 +508,6 @@ input.span3, textarea.span3, .uneditable-input.span3 {
     font-weight: bold;
     font-size: 18px;
     padding-left: 10px;
-    width: 250px;
 }
 #course_tools .course-title-tools h3 {
     margin-top: 10px;

+ 1 - 1
main/css/baby_orange/scorm.css

@@ -432,7 +432,7 @@ opacity: 0.7;
 }
 
 /*STYLES PROCESS LESSION*/
-.inner_lp_toc .scrom_completed {
+.inner_lp_toc .scorm_completed {
     
     background-image: url("images/blue_arrow.png") !important;
     background-position: 250px center !important;

+ 11 - 3
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 {
@@ -4766,4 +4766,12 @@ i.size-32.icon-new-work{
 .text-h5 {
     font-size: 12px;
     font-weight: normal;
-}
+}
+
+.chosen-container {
+    min-width: 180px;
+}
+
+.chzn-container-single .chzn-search {
+    z-index: 1010;
+}

+ 0 - 1
main/css/blue_lagoon/default.css

@@ -460,7 +460,6 @@ filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#f4f5f6', end
     font-weight: normal;
     font-size: 20px;
     padding-left: 10px;
-    width: 250px;
 }
 #course_tools .course-title-tools h3 {
     margin-top: 10px;

+ 1 - 1
main/css/blue_lagoon/scorm.css

@@ -432,7 +432,7 @@ opacity: 0.7;
 }
 
 /*STYLES PROCESS LESSION*/
-.inner_lp_toc .scrom_completed {
+.inner_lp_toc .scorm_completed {
     
     background-image: url("images/blue_arrow.png") !important;
     background-position: 250px center !important;

+ 1 - 1
main/css/bootstrap.css

@@ -2390,7 +2390,7 @@ table .span24 {
 
 .dropdown-menu {
   position: absolute;
-  top: 100%;
+  top: 33px;
   left: 0;
   z-index: 1000;
   display: none;

+ 0 - 6
main/css/chamilo/default.css

@@ -465,9 +465,6 @@ a.thumbnail:hover{
     text-shadow: none;
 }
 
-.form-search .btn{
-    margin-left: 5px;
-}
 /* styles for the star rater */
 .star-rating{
     list-style:none;
@@ -633,14 +630,11 @@ a.thumbnail:hover{
     font-weight: bold;
     font-size: 20px;
     padding-left: 10px;
-    width: 250px;
 }
 #course_tools .course-title-tools h3 {
     margin-top: 10px;
     color: #0191C7;
     font-weight: normal;
-
-
 }
 .page-header {
   border:none;

+ 1 - 1
main/css/chamilo/scorm.css

@@ -432,7 +432,7 @@ opacity: 0.7;
 }
 
 /*STYLES PROCESS LESSION*/
-.inner_lp_toc .scrom_completed {
+.inner_lp_toc .scorm_completed {
     
     background-image: url("images/blue_arrow.png") !important;
     background-position: 250px center !important;

+ 0 - 1
main/css/chamilo_electric_blue/default.css

@@ -421,7 +421,6 @@ a:active {
     font-weight: bold;
     font-size: 20px;
     padding-left: 10px;
-    width: 250px;
 }
 #course_tools .course-title-tools h3 {
     margin-top: 10px;

+ 1 - 1
main/css/chamilo_electric_blue/scorm.css

@@ -432,7 +432,7 @@ opacity: 0.7;
 }
 
 /*STYLES PROCESS LESSION*/
-.inner_lp_toc .scrom_completed {
+.inner_lp_toc .scorm_completed {
     
     background-image: url("images/blue_arrow.png") !important;
     background-position: 250px center !important;

+ 0 - 1
main/css/chamilo_green/default.css

@@ -422,7 +422,6 @@ a:active {
     font-weight: bold;
     font-size: 20px;
     padding-left: 10px;
-    width: 250px;
 }
 #course_tools .course-title-tools h3 {
     margin-top: 10px;

+ 1 - 1
main/css/chamilo_green/scorm.css

@@ -432,7 +432,7 @@ opacity: 0.7;
 }
 
 /*STYLES PROCESS LESSION*/
-.inner_lp_toc .scrom_completed {
+.inner_lp_toc .scorm_completed {
     
     background-image: url("images/blue_arrow.png") !important;
     background-position: 250px center !important;

+ 0 - 1
main/css/chamilo_orange/default.css

@@ -422,7 +422,6 @@ a:active {
     font-weight: bold;
     font-size: 20px;
     padding-left: 10px;
-    width: 250px;
 }
 #course_tools .course-title-tools h3 {
     margin-top: 10px;

+ 1 - 1
main/css/chamilo_orange/scorm.css

@@ -432,7 +432,7 @@ opacity: 0.7;
 }
 
 /*STYLES PROCESS LESSION*/
-.inner_lp_toc .scrom_completed {
+.inner_lp_toc .scorm_completed {
     
     background-image: url("images/blue_arrow.png") !important;
     background-position: 250px center !important;

+ 0 - 1
main/css/chamilo_red/default.css

@@ -422,7 +422,6 @@ a:active {
     font-weight: bold;
     font-size: 20px;
     padding-left: 10px;
-    width: 250px;
 }
 #course_tools .course-title-tools h3 {
     margin-top: 10px;

+ 1 - 1
main/css/chamilo_red/scorm.css

@@ -432,7 +432,7 @@ opacity: 0.7;
 }
 
 /*STYLES PROCESS LESSION*/
-.inner_lp_toc .scrom_completed {
+.inner_lp_toc .scorm_completed {
     
     background-image: url("images/blue_arrow.png") !important;
     background-position: 250px center !important;

+ 0 - 1
main/css/chamilo_sport_red/default.css

@@ -464,7 +464,6 @@ filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#ffffff', end
     font-weight: bold;
     font-size: 20px;
     padding-left: 10px;
-    width: 250px;
 }
 #course_tools .course-title-tools h3 {
     margin-top: 10px;

+ 1 - 1
main/css/chamilo_sport_red/scorm.css

@@ -432,7 +432,7 @@ opacity: 0.7;
 }
 
 /*STYLES PROCESS LESSION*/
-.inner_lp_toc .scrom_completed {
+.inner_lp_toc .scorm_completed {
     
     background-image: url("images/blue_arrow.png") !important;
     background-position: 250px center !important;

+ 0 - 1
main/css/cool_blue/default.css

@@ -490,7 +490,6 @@ a.thumbnail:hover{
     font-weight: normal;
     font-size: 20px;
     padding-left: 10px;
-    width: 250px;
 }
 #course_tools .course-title-tools h3 {
     margin-top: 10px;

+ 1 - 1
main/css/cool_blue/scorm.css

@@ -432,7 +432,7 @@ opacity: 0.7;
 }
 
 /*STYLES PROCESS LESSION*/
-.inner_lp_toc .scrom_completed {
+.inner_lp_toc .scorm_completed {
     
     background-image: url("images/blue_arrow.png") !important;
     background-position: 250px center !important;

+ 0 - 1
main/css/corporate/default.css

@@ -449,7 +449,6 @@ a:active {
     font-weight: normal;
     font-size: 20px;
     padding-left: 10px;
-    width: 250px;
 }
 #course_tools .course-title-tools h3 {
     margin-top: 10px;

+ 1 - 1
main/css/corporate/scorm.css

@@ -432,7 +432,7 @@ opacity: 0.7;
 }
 
 /*STYLES PROCESS LESSION*/
-.inner_lp_toc .scrom_completed {
+.inner_lp_toc .scorm_completed {
     
     background-image: url("images/blue_arrow.png") !important;
     background-position: 250px center !important;

+ 0 - 1
main/css/cosmic_campus/default.css

@@ -505,7 +505,6 @@ input.span3, textarea.span3, .uneditable-input.span3 {
     font-weight: bold;
     font-size: 18px;
     padding-left: 10px;
-    width: 250px;
 }
 #course_tools .course-title-tools h3 {
     margin-top: 10px;

+ 1 - 1
main/css/cosmic_campus/scorm.css

@@ -432,7 +432,7 @@ opacity: 0.7;
 }
 
 /*STYLES PROCESS LESSION*/
-.inner_lp_toc .scrom_completed {
+.inner_lp_toc .scorm_completed {
     
     background-image: url("images/blue_arrow.png") !important;
     background-position: 250px center !important;

+ 1021 - 3
main/css/journal/default.css

@@ -1,8 +1,1026 @@
-@import url('bootstrap.css');
+/*****************************************************
+ *  MAIN  - CHAMILO CSS
+ *****************************************************/
 
 /* Adding default style for the chamilo_X themes */
 @import url('../base_chamilo.css');
+/* the following for regular <a> elements */
+a {
+    text-decoration: none;
+    color :#6E6E6E;
+}
+a:visited {
+    text-decoration: none;    
+}
+a:hover {
+    text-decoration: none;
+    color: #FE9A2E;
+}
+a:active {
+    text-decoration: none;
+}
+.navbar .nav > li > a {
+    float: none;
+    line-height: 24px;
+    padding-bottom: 13px;
+    padding-right: 10px;
+    padding-top: 13px;
+    color: #FFFFFF;
+}
+.subnav .navbar-inner {
+    background: #505f6b; /* Old browsers */
+    background: -moz-linear-gradient(top, #505f6b 0%, #3e4f5c 100%); /* FF3.6+ */
+    background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#505f6b), color-stop(100%,#3e4f5c)); /* Chrome,Safari4+ */
+    background: -webkit-linear-gradient(top, #505f6b 0%,#3e4f5c 100%); /* Chrome10+,Safari5.1+ */
+    background: -o-linear-gradient(top, #505f6b 0%,#3e4f5c 100%); /* Opera 11.10+ */
+    background: -ms-linear-gradient(top, #505f6b 0%,#3e4f5c 100%); /* IE10+ */
+    background: linear-gradient(to bottom, #505f6b 0%,#3e4f5c 100%); /* W3C */
+    filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#505f6b', endColorstr='#3e4f5c',GradientType=0 ); /* IE6-9 */
+    border: none;
+}
 
+.subnav .nav > li > a {
+    border-left: none;
+    border-right: none;
+    color: white;
+    font-weight: normal;
+    font-size: 13px;
+}
+
+
+.subnav .nav > #current > a,
+.subnav .nav > #current > a:hover {  
+    color: #fff;
+    background-color: #3A4751;
+    -webkit-border-radius: 6px;
+    -moz-border-radius: 6px;
+    border-radius: 6px;
+    border: 1px solid rgba(255, 255, 255, 0.2);
+    box-shadow:0 1px 1px rgba(0, 0, 0, 0.15) inset;
+    line-height: 13px;
+    margin-top: 5px;
+}
+
+.subnav li a {
+    color:#fff;
+}
+#main .nav .dropdown .dropdown-toggle{
+    background: #f68a7a; /* Old browsers */
+    background: -moz-linear-gradient(top, #f68a7a 0%, #f26954 100%); /* FF3.6+ */
+    background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#f68a7a), color-stop(100%,#f26954)); /* Chrome,Safari4+ */
+    background: -webkit-linear-gradient(top, #f68a7a 0%,#f26954 100%); /* Chrome10+,Safari5.1+ */
+    background: -o-linear-gradient(top, #f68a7a 0%,#f26954 100%); /* Opera 11.10+ */
+    background: -ms-linear-gradient(top, #f68a7a 0%,#f26954 100%); /* IE10+ */
+    background: linear-gradient(to bottom, #f68a7a 0%,#f26954 100%); /* W3C */
+    filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#f68a7a', endColorstr='#f26954',GradientType=0 ); /* IE6-9 */
+    line-height: 23px;
+}
+#main .nav .dropdown .dropdown-toggle:hover{
+    background: #f68a7a; /* Old browsers */
+    background: -moz-linear-gradient(top, #f68a7a 0%, #f26954 100%); /* FF3.6+ */
+    background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#f68a7a), color-stop(100%,#f26954)); /* Chrome,Safari4+ */
+    background: -webkit-linear-gradient(top, #f68a7a 0%,#f26954 100%); /* Chrome10+,Safari5.1+ */
+    background: -o-linear-gradient(top, #f68a7a 0%,#f26954 100%); /* Opera 11.10+ */
+    background: -ms-linear-gradient(top, #f68a7a 0%,#f26954 100%); /* IE10+ */
+    background: linear-gradient(to bottom, #f68a7a 0%,#f26954 100%); /* W3C */
+    filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#f68a7a', endColorstr='#f26954',GradientType=0 ); /* IE6-9 */
+    line-height: 23px;
+    margin-top: 0;
+}
+
+/* Green hover */
+.subnav .navbar-inner li a:hover {
+    color: #fff;
+    background-color: #3A4751;
+    -webkit-border-radius: 6px;
+    -moz-border-radius: 6px;
+    border-radius: 6px;
+    border: none;
+    box-shadow:0 1px 1px rgba(0, 0, 0, 0.15) inset;
+    line-height: 15px;
+    margin-top: 5px;
+}
+.well .nav-list > li > a:hover {
+  text-decoration: none;
+  background: none;
+}
+.sidebar-nav h4{
+    color: #037FB2;
+    padding-bottom: 3px;
+    padding-left: 15px;
+    padding-right: 15px;
+    padding-top: 3px;
+}
+.dropdown .dropdown-menu li a:hover {
+    -webkit-border-radius: 0;
+    -moz-border-radius: 0;
+    border-radius: 0;
+}
+#logout_button{
+  margin-top: 4px;
+}
+#logout_button:hover{
+  margin-top: 6px;
+  background: none;
+  box-shadow: none;
+}
+/*****************************************************
+ *  STYLE THEME CHAMILO                              *
+ *****************************************************/
+ .page-section{
+    background:url(images/bg-header.jpg) repeat-x;
+    margin-top: -5px;
+ }
+.navbar-inner{
+  background: #f68a7a; /* Old browsers */
+background: -moz-linear-gradient(top, #f68a7a 0%, #f26954 100%); /* FF3.6+ */
+background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#f68a7a), color-stop(100%,#f26954)); /* Chrome,Safari4+ */
+background: -webkit-linear-gradient(top, #f68a7a 0%,#f26954 100%); /* Chrome10+,Safari5.1+ */
+background: -o-linear-gradient(top, #f68a7a 0%,#f26954 100%); /* Opera 11.10+ */
+background: -ms-linear-gradient(top, #f68a7a 0%,#f26954 100%); /* IE10+ */
+background: linear-gradient(to bottom, #f68a7a 0%,#f26954 100%); /* W3C */
+filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#f68a7a', endColorstr='#f26954',GradientType=0 ); /* IE6-9 */
+}
+.dropdown-menu li > a:hover, .dropdown-menu .active > a, .dropdown-menu .active > a:hover {
+  background-color: #3A4751;
+  color: #FFFFFF;
+}
+.navbar-search {
+  margin-bottom: 0;
+  margin-top: 11px;
+  position: relative;
+}
+.navbar-search .search-query {
+  background:#FFFFFF;
+  color: #666;
+  border: 1px solid #ffffff;
+}
+.navbar .nav .active > a, .navbar .nav .active > a:hover {
+  background:none;
+  color: #FFFFFF;
+}
+.welcome-mascot{
+  background: url(images/chamilo-welcome.png) no-repeat right 0;
+  padding-right: 200px;
+  padding-bottom: 2em;
+  padding-top: 2em;
+}
+
+.nav-list > li > a {
+    font-size: 14px;
+    padding-bottom: 6px;
+   /* padding-left: 15px;
+    padding-right: 15px;*/
+    padding-top: 6px;
+}
+.controls .btn{
+    background: #f68a7a; /* Old browsers */
+    background: -moz-linear-gradient(top, #f68a7a 0%, #f26954 100%); /* FF3.6+ */
+    background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#f68a7a), color-stop(100%,#f26954)); /* Chrome,Safari4+ */
+    background: -webkit-linear-gradient(top, #f68a7a 0%,#f26954 100%); /* Chrome10+,Safari5.1+ */
+    background: -o-linear-gradient(top, #f68a7a 0%,#f26954 100%); /* Opera 11.10+ */
+    background: -ms-linear-gradient(top, #f68a7a 0%,#f26954 100%); /* IE10+ */
+    background: linear-gradient(to bottom, #f68a7a 0%,#f26954 100%); /* W3C */
+    filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#f68a7a', endColorstr='#f26954',GradientType=0 ); /* IE6-9 */
+    color: #FFFFFF;
+    border:1px solid rgba(0, 0, 0, 0.15);
+    padding: 5px 25px;
+    text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.17);
+}
+.controls .btn:hover{
+    background: #f68a7a; /* Old browsers */
+background: -moz-linear-gradient(top, #f68a7a 0%, #ef7f70 100%); /* FF3.6+ */
+background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#f68a7a), color-stop(100%,#ef7f70)); /* Chrome,Safari4+ */
+background: -webkit-linear-gradient(top, #f68a7a 0%,#ef7f70 100%); /* Chrome10+,Safari5.1+ */
+background: -o-linear-gradient(top, #f68a7a 0%,#ef7f70 100%); /* Opera 11.10+ */
+background: -ms-linear-gradient(top, #f68a7a 0%,#ef7f70 100%); /* IE10+ */
+background: linear-gradient(to bottom, #f68a7a 0%,#ef7f70 100%); /* W3C */
+filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#f68a7a', endColorstr='#ef7f70',GradientType=0 ); /* IE6-9 */
+    color: #FFFFFF;
+    border:1px solid rgba(0, 0, 0, 0.15);
+    padding: 5px 25px;
+    text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.17);
+
+}
+.form-actions {
+  background:transparent;
+}
+.breadcrumb {
+  margin-bottom: 0;
+  background-color: #E1E1E0;
+  background-image: none;
+  padding-top: 5px;
+  padding-bottom: 5px;
+  border: 1px solid #E1E1E0;
+  box-shadow: none;
+  font-size: 12px;
+}
+.breadcrumb a{
+  color: #333;
+  f
+  line-height: 30px;
+  text-transform: none;
+}
+
+.breadcrumb li{
+    
+    text-shadow: none;
+}
+.breadcrumb a.btn-mini{
+    font-size: 12px;
+    line-height: 17px;
+    text-transform: none;
+    color: #FFFFFF;
+}
+.breadcrumb a.btn-success {
+  background: #f68a7a; /* Old browsers */
+background: -moz-linear-gradient(top, #f68a7a 0%, #f26954 100%); /* FF3.6+ */
+background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#f68a7a), color-stop(100%,#f26954)); /* Chrome,Safari4+ */
+background: -webkit-linear-gradient(top, #f68a7a 0%,#f26954 100%); /* Chrome10+,Safari5.1+ */
+background: -o-linear-gradient(top, #f68a7a 0%,#f26954 100%); /* Opera 11.10+ */
+background: -ms-linear-gradient(top, #f68a7a 0%,#f26954 100%); /* IE10+ */
+background: linear-gradient(to bottom, #f68a7a 0%,#f26954 100%); /* W3C */
+filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#f68a7a', endColorstr='#f26954',GradientType=0 ); /* IE6-9 */
+  border: 1px solid #FD6600;
+  color: #FFFFFF;
+  text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.17);
+}
+.breadcrumb a.btn-success:hover{
+  background: #f68a7a; /* Old browsers */
+background: -moz-linear-gradient(top, #f68a7a 0%, #ef7f70 100%); /* FF3.6+ */
+background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#f68a7a), color-stop(100%,#ef7f70)); /* Chrome,Safari4+ */
+background: -webkit-linear-gradient(top, #f68a7a 0%,#ef7f70 100%); /* Chrome10+,Safari5.1+ */
+background: -o-linear-gradient(top, #f68a7a 0%,#ef7f70 100%); /* Opera 11.10+ */
+background: -ms-linear-gradient(top, #f68a7a 0%,#ef7f70 100%); /* IE10+ */
+background: linear-gradient(to bottom, #f68a7a 0%,#ef7f70 100%); /* W3C */
+filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#f68a7a', endColorstr='#ef7f70',GradientType=0 ); /* IE6-9 */
+text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.17);
+}
+.btn{
+  display: inline-block;
+  padding: 3px 25px;
+  margin-bottom: 0;
+  font-size: 14px;
+  font-weight: normal;
+  line-height: 1.428571429;
+  text-align: center;
+  text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.17);
+  cursor: pointer;
+  color: #FFFFFF;
+  background: #606e78; /* Old browsers */
+  background: -moz-linear-gradient(top, #606e78 0%, #495864 100%); /* FF3.6+ */
+  background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#606e78), color-stop(100%,#495864)); /* Chrome,Safari4+ */
+  background: -webkit-linear-gradient(top, #606e78 0%,#495864 100%); /* Chrome10+,Safari5.1+ */
+  background: -o-linear-gradient(top, #606e78 0%,#495864 100%); /* Opera 11.10+ */
+  background: -ms-linear-gradient(top, #606e78 0%,#495864 100%); /* IE10+ */
+  background: linear-gradient(to bottom, #606e78 0%,#495864 100%); /* W3C */
+  filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#606e78', endColorstr='#495864',GradientType=0 ); /* IE6-9 */
+  border:1px solid rgba(0, 0, 0, 0.15);
+}
+.btn:hover{
+  background: #6f8091; /* Old browsers */
+  background: -moz-linear-gradient(top, #6f8091 0%, #4d5963 100%); /* FF3.6+ */
+  background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#6f8091), color-stop(100%,#4d5963)); /* Chrome,Safari4+ */
+  background: -webkit-linear-gradient(top, #6f8091 0%,#4d5963 100%); /* Chrome10+,Safari5.1+ */
+  background: -o-linear-gradient(top, #6f8091 0%,#4d5963 100%); /* Opera 11.10+ */
+  background: -ms-linear-gradient(top, #6f8091 0%,#4d5963 100%); /* IE10+ */
+  background: linear-gradient(to bottom, #6f8091 0%,#4d5963 100%); /* W3C */
+  filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#6f8091', endColorstr='#4d5963',GradientType=0 ); /* IE6-9 */
+  color: #ffffff;
+  text-decoration: none;
+}
+.btn-primary{
+  background: #f68a7a; /* Old browsers */
+  background: -moz-linear-gradient(top, #f68a7a 0%, #f26954 100%); /* FF3.6+ */
+  background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#f68a7a), color-stop(100%,#f26954)); /* Chrome,Safari4+ */
+  background: -webkit-linear-gradient(top, #f68a7a 0%,#f26954 100%); /* Chrome10+,Safari5.1+ */
+  background: -o-linear-gradient(top, #f68a7a 0%,#f26954 100%); /* Opera 11.10+ */
+  background: -ms-linear-gradient(top, #f68a7a 0%,#f26954 100%); /* IE10+ */
+  background: linear-gradient(to bottom, #f68a7a 0%,#f26954 100%); /* W3C */
+  filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#f68a7a', endColorstr='#f26954',GradientType=0 ); /* IE6-9 */
+  color: #FFFFFF;
+    border:1px solid rgba(0, 0, 0, 0.15);
+    padding: 3px 25px;
+    text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.17);
+}
+.btn-primary:hover{
+    background: #f68a7a; /* Old browsers */
+background: -moz-linear-gradient(top, #f68a7a 0%, #ef7f70 100%); /* FF3.6+ */
+background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#f68a7a), color-stop(100%,#ef7f70)); /* Chrome,Safari4+ */
+background: -webkit-linear-gradient(top, #f68a7a 0%,#ef7f70 100%); /* Chrome10+,Safari5.1+ */
+background: -o-linear-gradient(top, #f68a7a 0%,#ef7f70 100%); /* Opera 11.10+ */
+background: -ms-linear-gradient(top, #f68a7a 0%,#ef7f70 100%); /* IE10+ */
+background: linear-gradient(to bottom, #f68a7a 0%,#ef7f70 100%); /* W3C */
+filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#f68a7a', endColorstr='#ef7f70',GradientType=0 ); /* IE6-9 */
+    color: #FFFFFF;
+    border:1px solid rgba(0, 0, 0, 0.15);
+    
+    text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.17);
+}
+
+/* styles for the star rater */
+.star-rating{
+    list-style:none;
+    margin: 0px;
+    padding:0px;
+    width: 125px;
+    height: 25px;
+    position: relative;
+    overflow:hidden;
+    background: url(images/start-level.png) top left repeat-x;
+}
+.star-rating li{
+    padding:0px;
+    margin:0px;
+    width:25px;
+    height:25px;
+    float: left;
+}
+.star-rating li a{
+    display:block;
+    width:25px;
+    height: 25px;
+    line-height:25px;
+    text-decoration: none;
+    text-indent: -9000px;
+    z-index: 20;
+    position: absolute;
+    padding: 0px;
+    overflow:hidden;
+}
+.star-rating li a:hover{
+    background: url(images/start-level.png) left bottom;
+    z-index: 2;
+    left: 0px;
+    border:none;
+}
+.star-rating a.one-star{
+    left: 0px;
+}
+.star-rating a.one-star:hover{
+    width:25px;
+}
+.star-rating a.two-stars{
+    left:25px;
+}
+.star-rating a.two-stars:hover{
+    width: 50px;
+}
+.star-rating a.three-stars{
+    left: 50px;
+}
+.star-rating a.three-stars:hover{
+    width: 75px;
+}
+.star-rating a.four-stars{
+    left: 75px;
+}
+.star-rating a.four-stars:hover{
+    width: 100px;
+}
+.star-rating a.five-stars{
+    left: 100px;
+}
+.star-rating a.five-stars:hover{
+    width: 125px;
+}
+.star-rating li.current-rating{
+    background: url(images/start-level.png) left center;
+    position: absolute;
+    height: 25px;
+    display: block;
+    text-indent: -9000px;
+    z-index: 1;
+}
+/*ICON INBOX*/
+.home-icon{
+  background:url(images/icon-chamilo.png) no-repeat 0 0;
+  background-size: 24px auto;
+  padding-left: 30px;
+}
+.home-icon:hover,.messages-icon:hover, .invitations-icon:hover,.shared-profile-icon:hover,.friends-icon:hover,
+.browse-groups-icon:hover ,.search-icon:hover ,.myfiles-icon:hover {
+  opacity: 0.8;
+}
+.messages-icon{
+  background:url(images/icon-chamilo.png) no-repeat 0 -29px;
+  background-size: 24px auto;
+  padding-left: 30px;
+}
+.invitations-icon{
+  background:url(images/icon-chamilo.png) no-repeat 0 -61px;
+  background-size: 24px auto;
+  padding-left: 30px;
+}
+.shared-profile-icon{
+  background:url(images/icon-chamilo.png) no-repeat 0 -96px;
+  background-size: 24px auto;
+  padding-left: 30px;
+}
+.friends-icon{
+  background:url(images/icon-chamilo.png) no-repeat 0 -130px;
+  background-size: 24px auto;
+  padding-left: 30px;
+}
+
+.browse-groups-icon{
+  background:url(images/icon-chamilo.png) no-repeat 0 -163px;
+  background-size: 24px auto;
+  padding-left: 30px;
+}
+
+.search-icon {
+  background:url(images/icon-chamilo.png) no-repeat 0 -198px;
+  background-size: 24px auto;
+  padding-left: 30px;
+}
+
+.myfiles-icon {
+  background:url(images/icon-chamilo.png) no-repeat 0 -229px;
+  background-size: 24px auto;
+  padding-left: 30px;
+}
+
+/* END ICON INBOX */
+.nav-list > .active > a, .nav-list > .active > a:hover {
+  color: #333333;
+  background: none;
+  text-shadow:none;
+}
+.social-menu .well .thumbnail{
+  border: none;
+  border-radius: none;
+  box-shadow: none;
+}
+.invitation_confirm .thumbnail{
+    border: 1px solid rgba(96, 165, 209, 0.1);
+    -webkit-border-radius: 10px;
+    -moz-border-radius: 10px;
+    border-radius: 10px;
+    box-shadow: 0 1px 1px rgba(0, 0, 0, 0.05);
+    display: block;
+    line-height: 1;
+    padding: 4px;
+    background-color: #EEF5FA;
+}
+.invitation_confirm a.thumbnail:hover{
+    border-color: rgba(96, 165, 209, 0.1);
+    box-shadow: 0 1px 1px rgba(0, 0, 0, 0.05);
+    background-color: #FFFFFF;
+}
+.social-menu .well .thumbnail img{
+  -webkit-border-radius: 10px;
+  -moz-border-radius: 10px;
+  border-radius: 10px;
+  border: 2px solid #FFFFFF;
+}
+
+/*CSS SLIDER ANUNCIOS*/
+
+.pagerslide h2{
+    font-size: 18px;
+    font-weight: normal;
+    background:  #E6E6E6;
+    color: #666;
+    padding-left: 15px;
+}
+
+#top_main_content #announcements .page-header{
+  display: none;
+  line-height: 1;
+}
+#top_main_content #announcements .span6 {
+  width: 800px;
+}
+
+/*CSS PARA CONTENIDO DE CURSO INTRODUCCION*/
+
+.page-course-intro{
+    padding: 2em;
+    border: 1px solid #DDDDDD;
+    -webkit-border-radius: 10px;
+    -moz-border-radius: 10px;
+    border-radius: 10px;
+    margin-bottom: 2em;
+    background: #FFFFFF;
+}
+
+.page-course-intro ul{
+    list-style-image:url(images/vineta.png);
+    padding-top: 10px;
+}
+.page-course-intro a{
+    color: #FD6600;
+}
+.page-course-intro a:hover{
+    color: #FD6600;
+    text-decoration: underline;
+}
+
+
+/*FIN DE INTRODUCCION DEL CURSO*/
+.fc-header-title h2{
+    color: #666;
+}
+.fc-first .fc-widget-header{
+    font-size: 14px;
+    font-weight: normal;
+    padding-top: 5px;
+    padding-bottom: 5px;
+}
+
+.well {
+  background: #f2f2f2; /* Old browsers */
+background: -moz-linear-gradient(top, #f2f2f2 0%, #fcfcfc 100%); /* FF3.6+ */
+background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#f2f2f2), color-stop(100%,#fcfcfc)); /* Chrome,Safari4+ */
+background: -webkit-linear-gradient(top, #f2f2f2 0%,#fcfcfc 100%); /* Chrome10+,Safari5.1+ */
+background: -o-linear-gradient(top, #f2f2f2 0%,#fcfcfc 100%); /* Opera 11.10+ */
+background: -ms-linear-gradient(top, #f2f2f2 0%,#fcfcfc 100%); /* IE10+ */
+background: linear-gradient(to bottom, #f2f2f2 0%,#fcfcfc 100%); /* W3C */
+filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#f2f2f2', endColorstr='#fcfcfc',GradientType=0 ); /* IE6-9 */
+  border: 1px solid rgba(243,226,169, 0.1);
+  border-radius: 8px;
+  box-shadow: 0 1px 1px rgba(0, 0, 0, 0.05) inset;
+  margin-bottom: 20px;
+  min-height: 20px;
+  padding: 20px 10px;
+}
+input.span3, textarea.span3, .uneditable-input.span3 {
+  margin-right: 10px;
+  width: 260px;
+}
+.sidebar-nav img{
+    -webkit-border-radius: 10px;
+    -moz-border-radius: 10px;
+    border-radius: 10px;
+}
+#homepage .row .span9 h2{
+    font-size: 26px;
+    font-weight: bold;
+    color: #666;
+    padding-bottom: 8px;
+}
+#homepage .row .span9 p,#homepage .row .span9 ol {
+    color: #6E6E6E;
+}
+#homepage .row .span9 a{
+    /*color: #DE3A01;*/
+}
+#homepage .row .span9 a:hover{
+    /*color: #DE3A01;*/
+}
+.page-header h2{
+    color: #666;
+    font-weight: bold;
+    font-size: 18px;
+    padding-left: 10px;
+    width: 250px;
+}
+#course_tools .course-title-tools h3 {
+    margin-top: 10px;
+    color: #666;
+    font-weight: bold;
+    
+    
+}
+.page-header {
+  border-bottom-color: #CCCCCC;
+  border-bottom-style: solid;
+  border-bottom-width: 1px;
+  box-shadow: none;
+  padding-bottom: 0px;
+}
+.well_border{
+  background: #f2f2f2; /* Old browsers */
+  background: -moz-linear-gradient(top, #f2f2f2 0%, #fcfcfc 100%); /* FF3.6+ */
+  background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#f2f2f2), color-stop(100%,#fcfcfc)); /* Chrome,Safari4+ */
+  background: -webkit-linear-gradient(top, #f2f2f2 0%,#fcfcfc 100%); /* Chrome10+,Safari5.1+ */
+  background: -o-linear-gradient(top, #f2f2f2 0%,#fcfcfc 100%); /* Opera 11.10+ */
+  background: -ms-linear-gradient(top, #f2f2f2 0%,#fcfcfc 100%); /* IE10+ */
+  background: linear-gradient(to bottom, #f2f2f2 0%,#fcfcfc 100%); /* W3C */
+  filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#f2f2f2', endColorstr='#fcfcfc',GradientType=0 ); /* IE6-9 */
+  border: 1px solid rgba(243,226,169, 0.1);
+  border-radius: 8px;
+  box-shadow: 0 1px 1px rgba(0, 0, 0, 0.05) inset;
+  margin-bottom: 20px;
+  min-height: 20px;
+  padding: 19px;
+}
+.well_border .row .span2 {
+  width: 98px;
+}
+.well_border .row .span2 .thumbnail {
+  background-color: #FFFFFF;
+  background-image: none;
+}
+#hot_courses .row .span9 .well_border .row .span6{
+    width: auto;
+}
+.categories-course-description h3{
+    color: #666;
+}
+#course_tools .content a {
+  font-size: 12px;
+  font-weight: normal;
+}
+#main_content .course-box .row .span7{
+  width: 730px;
+}
+#main_content .course-box .row .span7 .row .span6 {
+    width: 615px;
+}
+#main_content .course-box .row .span7 .row .span6 h3{
+  font-size: 20px;
+}
+#course_category li, #hot_courses h5, .course_item h5, .categories-course-description h5, .course-box h5 {
+  font-weight: normal;
+}
+/*****************************************************
+ *  FOOTER STYLES                                    *
+ *****************************************************/
+footer {
+    height: 10em;    
+    background: #505f6b; /* Old browsers */
+    background: -moz-linear-gradient(top, #505f6b 0%, #3e4f5c 100%); /* FF3.6+ */
+    background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#505f6b), color-stop(100%,#3e4f5c)); /* Chrome,Safari4+ */
+    background: -webkit-linear-gradient(top, #505f6b 0%,#3e4f5c 100%); /* Chrome10+,Safari5.1+ */
+    background: -o-linear-gradient(top, #505f6b 0%,#3e4f5c 100%); /* Opera 11.10+ */
+    background: -ms-linear-gradient(top, #505f6b 0%,#3e4f5c 100%); /* IE10+ */
+    background: linear-gradient(to bottom, #505f6b 0%,#3e4f5c 100%); /* W3C */
+    filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#505f6b', endColorstr='#3e4f5c',GradientType=0 ); /* IE6-9 */    
+    color:#ffffff;
+    border-top: 5px solid #B0BEBC; 
+}
+footer .container .row {
+  padding-top: 5px;
+}
 footer a:link, footer a:visited {
-    color:black;
-}
+  color: #F1D40D;
+}
+/*****************************************************
+ *  DISPLAY MESSAGES	                             *
+ *****************************************************/
+/*****************************************************
+ *  CSS CHAT                               *
+ *****************************************************/
+.chatboxmain {
+    bottom: 0;
+    display: block;
+    position: fixed;
+    right: 20px;
+    width: 225px;
+    z-index: 9000;
+}
+
+.chatboxheadmain {
+  padding:7px 7px 7px 0px;
+  color: #ffffff;
+  border-right:1px solid #222;
+  border-left:1px solid #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);
+  background-image: -ms-linear-gradient(top, #333333, #222222);
+  background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #333333), color-stop(100%, #222222));
+  background-image: -webkit-linear-gradient(top, #333333, #222222);
+  background-image: -o-linear-gradient(top, #333333, #222222);
+  background-image: linear-gradient(top, #333333, #222222);
+  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#333333', endColorstr='#222222', GradientType=0);
+  -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;
+    float: left;
+    font-size: 12px;
+    font-weight: normal;
+    width: 160px;
+}
+/*****************************************************
+ *  CSS CHAT END                             *
+ *****************************************************/
+.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;
+    color:#1F8323;
+	background: url("images/background_message.png") repeat-x scroll 0 0 #CAF0C7;
+}
+.error-message {
+    border: 1px solid #FF0000;
+    color: #440000;
+	background: url("images/background_message.png") repeat-x scroll 0 0 #FFD1D1;
+}
+
+.social-menu-title {
+	background-color:#00AAE3;
+}
+
+#social-content-online {
+    background-color:#00AAE3;
+}
+		
+.admin_section li {
+    background-image:url(images/bullet.gif);
+}
+
+.system_announcements {
+    background: transparent url('images/systemenouvelles.jpg') no-repeat top  left;
+}
+
+.topa {
+    background:transparent url('images/logoa4.gif') no-repeat;
+}
+.topb {
+    background:transparent url('images/logob4.gif') no-repeat;
+}
+
+#bottomhellomindfactory {    
+    background:transparent url('images/textologo.jpg') no-repeat;
+}
+
+/*including "login" image*/
+button.login {
+    background-image:url(images/bg-button.gif);
+}
+
+button.login:hover {
+}
+
+/*including "save" image
+button.save {
+    background-image:url(images/button_accept.gif);
+}
+/*including "add" image
+button.add {
+    background-image:url(images/button_add.gif);
+
+}
+/*including "cancel" image
+button.cancel {
+    background-image:url(images/button_delete.gif);
+}
+/*including "search" image
+button.search {
+    background-image:url(images/bg-button.gif);
+
+}
+/*including "plus" image
+button.plus {
+    background-image:url(images/button_plus.gif);
+}
+/*including "minus" image
+button.minus {
+    background-image:url(images/button_minus.gif);
+}
+/*including "next" image
+button.next {
+    background-image:url(images/button_next.gif) !important;
+}
+/*including "back" image
+button.back {
+    background-image:url(images/button_back.gif);
+}
+/*including "refresh" image
+button.refresh {
+    background-image:url(images/button_refresh.gif);
+}
+/*including "upload" image
+button.upload {
+    background-image:url(images/button_upload.gif);
+}
+*/
+button.add, button.save, button.cancel, button.refresh, button.upload, button.search, button.login, button.plus, button.minus, button.next, button.back {
+  display: inline-block;
+  padding: 3px 25px;
+  margin-bottom: 0;
+  font-size: 14px;
+  font-weight: normal;
+  line-height: 1.428571429;
+  text-align: center;
+  text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.17);
+  cursor: pointer;
+  color: #FFFFFF;
+  background: #606e78; /* Old browsers */
+  background: -moz-linear-gradient(top, #606e78 0%, #495864 100%); /* FF3.6+ */
+  background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#606e78), color-stop(100%,#495864)); /* Chrome,Safari4+ */
+  background: -webkit-linear-gradient(top, #606e78 0%,#495864 100%); /* Chrome10+,Safari5.1+ */
+  background: -o-linear-gradient(top, #606e78 0%,#495864 100%); /* Opera 11.10+ */
+  background: -ms-linear-gradient(top, #606e78 0%,#495864 100%); /* IE10+ */
+  background: linear-gradient(to bottom, #606e78 0%,#495864 100%); /* W3C */
+  filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#606e78', endColorstr='#495864',GradientType=0 ); /* IE6-9 */
+  border:1px solid rgba(0, 0, 0, 0.15);
+}
+.bottom_actions_fixed{
+  background: #f2f2f2; /* Old browsers */
+background: -moz-linear-gradient(top, #f2f2f2 0%, #fcfcfc 100%); /* FF3.6+ */
+background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#f2f2f2), color-stop(100%,#fcfcfc)); /* Chrome,Safari4+ */
+background: -webkit-linear-gradient(top, #f2f2f2 0%,#fcfcfc 100%); /* Chrome10+,Safari5.1+ */
+background: -o-linear-gradient(top, #f2f2f2 0%,#fcfcfc 100%); /* Opera 11.10+ */
+background: -ms-linear-gradient(top, #f2f2f2 0%,#fcfcfc 100%); /* IE10+ */
+background: linear-gradient(to bottom, #f2f2f2 0%,#fcfcfc 100%); /* W3C */
+filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#f2f2f2', endColorstr='#fcfcfc',GradientType=0 ); /* IE6-9 */
+  border: 1px solid #E1E1E0;
+}
+.new_actions-fixed {
+  top: 50px;
+}
+
+button.arrowr, input.arrowr {
+	background-image:url(images/2rightarrow.gif);	
+}
+button.arrowl, input.arrowl {
+    background-image:url(images/2leftarrow.gif);	
+}
+.refresh {
+    background-image:url(images/refresh.png);
+}
+
+.portal {
+    background-image:url(images/portal.png);
+}
+
+/*CSS ICON BLOCK USER*/
+   .inbox-social{
+        background: url("images/icon-chamilo.png") no-repeat 0 -415px;
+        padding-left: 40px;
+    }
+    .inbox-social:hover,.new-message-social:hover,.invitations-social:hover,.profile-social:hover,.add-course:hover,
+    .order-course:hover,.history-course:hover, .list-course:hover{
+        opacity: 0.8;
+    }
+    .new-message-social{
+        background: url("images/icon-chamilo.png") no-repeat 0 -370px;
+        padding-left: 40px;
+    }
+    .invitations-social{
+        background: url("images/icon-chamilo.png") no-repeat 0 -455px;
+        padding-left: 40px;
+    }
+    .profile-social{
+        background: url("images/icon-chamilo.png") no-repeat 0 -496px;
+        padding-left: 40px;
+    }
+    .add-course{
+        background: url("images/icon-chamilo.png") no-repeat 0 -327px;
+        padding-left: 40px;
+    }
+    .order-course{
+        background: url("images/icon-chamilo.png") no-repeat 0 -536px;
+        padding-left: 40px;
+    }
+    .history-course{
+        background: url("images/icon-chamilo.png") no-repeat 0 -576px;
+        padding-left: 40px;
+    }
+    .list-course{
+        background: url("images/icon-chamilo.png") no-repeat 0 -618px;
+        padding-left: 40px;
+    }
+    .forum-btn{
+        background: url("images/icon-chamilo.png") no-repeat 0 -666px;
+        padding-left: 40px;
+    }
+
+/*+++++++++++++++++++++++++++++++++
+RESPONSIVE CSS
++++++++++++++++++++++++++++++++++*/
+
+.navbar .brand {
+  float: left;
+  font-size: 16px;
+  font-weight: 200;
+  line-height: 20px;
+  padding-bottom: 12px;
+  padding-top: 15px;
+  color: #FFFFFF;
+}
+
+@media (min-width: 481px) and (max-width: 800px) {
+
+    .sidebar-nav h4 {
+        color: #037FB2;
+        font-size: 18px;
+        padding-bottom: 10px;
+        padding-left: 15px;
+        padding-right: 15px;
+        padding-top: 10px;
+    }
+    #profile_block .nav-list li, #course_block .nav-list li{
+        padding-bottom: 5px;
+        padding-top: 5px;
+    }
+    #top_main_content .menu-column #user_image_block{
+      box-shadow: none;
+    }
+
+}
+@media (max-width: 600px) {
+#main_content .course-box .row .span7 .row .span6 {
+  float: left;
+  /*width: 615px;*/
+  padding-left: 10px;
+}
+#main_content .course-box .row .span7 .row .span6 h3 {
+        font-size: 16px;
+        /*width: 500px;*/
+    }
+}
+
+@media (min-width: 801px){
+  .nav-list > li > a {
+  font-size: 13px;
+  padding-bottom: 8px;
+  padding-top: 8px;
+}
+
+/*CSS ICON BLOCK USER*/
+   .inbox-social{
+        background: url("images/icon-chamilo.png") no-repeat 0 -345px;
+        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;
+        background-size: 25px auto;
+    }
+    .forum-btn {
+      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 {
+    height: 5em;
+  }
+  .welcome-mascot{
+      background: none;
+      padding-right: 0px;
+      padding-bottom: 2em;
+      padding-top: 2em;
+    }
+  #homepage .row .span9 h2 {
+  color: #666;
+  font-size: 22px;
+  font-weight: bold;
+  padding-bottom: 8px;
+  line-height: 25px;
+}
+#announcements{
+  display: none;
+}
+}
+/*+++++++++++++++++++++++++++++++++
+END RESPONSIVE CSS
++++++++++++++++++++++++++++++++++*/

+ 1 - 4
main/css/kiddy/default.css

@@ -467,7 +467,6 @@ a.thumbnail:hover{
     font-weight: normal;
     font-size: 20px;
     padding-left: 10px;
-    width: 250px;
 }
 #course_tools .course-title-tools h3 {
     margin-top: 10px;
@@ -570,9 +569,7 @@ filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#efeab3', end
     text-shadow: none;
 }
 
-.form-search .btn{
-    margin-left: 5px;
-}
+
 /* styles for the star rater */
 .star-rating{
     list-style:none;

+ 1 - 1
main/css/kiddy/scorm.css

@@ -432,7 +432,7 @@ opacity: 0.7;
 }
 
 /*STYLES PROCESS LESSION*/
-.inner_lp_toc .scrom_completed {
+.inner_lp_toc .scorm_completed {
     
     background-image: url("images/blue_arrow.png") !important;
     background-position: 250px center !important;

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

@@ -36,7 +36,7 @@ if (isset($_GET['action']) && $_GET['action'] == 'exit_slideshow') {
 // We check if there are images in this folder by searching the extensions for .jpg, .gif, .png
 // grabbing the list of all the documents of this folder
 //$all_files = $fileList['name'];
-$array_to_search = is_array($docs_and_folders) ? $docs_and_folders : array();
+$array_to_search = !empty($docs_and_folders) && is_array($docs_and_folders) ? $docs_and_folders : array();
 
 if (count($array_to_search) > 0) {
 	while (list($key) = each($array_to_search)) {

+ 2 - 4
main/document/show_content.php

@@ -17,7 +17,7 @@ require_once '../inc/global.inc.php';
 api_protect_course_script();
 
 $noPHP_SELF = true;
-$header_file = Security::remove_XSS($_GET['file']);
+$header_file = isset($_GET['file']) ? Security::remove_XSS($_GET['file']) : null;
 $document_id = intval($_GET['id']);
 
 $course_info = api_get_course_info();
@@ -28,7 +28,7 @@ if (empty($course_info)) {
     api_not_allowed(true);
 }
 
-//Generate path
+// Generate path
 if (!$document_id) {
     $document_id = DocumentManager::get_document_id($course_info, $header_file);
 }
@@ -92,9 +92,7 @@ header('Last-Modified: Wed, 01 Jan 2100 00:00:00 GMT');
 header('Cache-Control: no-cache, must-revalidate');
 header('Pragma: no-cache');
 $browser_display_title = 'Documents - '.Security::remove_XSS($_GET['cidReq']).' - '.$file;
-
 $file_url_web = api_get_path(WEB_COURSE_PATH).$_course['path'].'/document'.$header_file.'?'.api_get_cidreq();
-
 $pathinfo = pathinfo($header_file);
 
 if ($pathinfo['extension']=='wav' && preg_match('/_chnano_.wav/i', $file_url_web) && api_get_setting('enable_nanogong') == 'true'){

+ 1 - 0
main/document/upload.php

@@ -161,6 +161,7 @@ if ($is_certificate_array[0] == 'certificates') {
 }
 
 // Title of the tool
+$add_group_to_title = null;
 if ($to_group_id != 0) { // Add group name after for group documents
     $add_group_to_title = ' ('.$group_properties['name'].')';
 }

+ 10 - 10
main/exercice/admin.php

@@ -125,9 +125,9 @@ $cancelQuestion = isset($cancelQuestion) ? $cancelQuestion : null;
 delete_all_incomplete_attempts(api_get_user_id(), $exerciseId, api_get_course_id(), api_get_session_id());
 
 // get from session
-$objExercise = $_SESSION['objExercise'];
-$objQuestion = $_SESSION['objQuestion'];
-$objAnswer   = $_SESSION['objAnswer'];
+$objExercise = isset($_SESSION['objExercise']) ? $_SESSION['objExercise'] : null;
+$objQuestion = isset($_SESSION['objQuestion']) ? $_SESSION['objQuestion'] : null;
+$objAnswer   = isset($_SESSION['objAnswer']) ? $_SESSION['objAnswer'] : null;
 
 // document path
 $documentPath = api_get_path(SYS_COURSE_PATH).$_course['path'].'/document';
@@ -264,9 +264,9 @@ if ($cancelAnswers) {
 	$editQuestion=$modifyAnswers;
 	unset($modifyAnswers);
 }
-
+$nameTools = null;
 // modifies the query string that is used in the link of tool name
-if($editQuestion || $modifyQuestion || $newQuestion || $modifyAnswers) {
+if ($editQuestion || $modifyQuestion || $newQuestion || $modifyAnswers) {
 	$nameTools = get_lang('QuestionManagement');
 }
 
@@ -497,12 +497,12 @@ if (isset($_GET['message'])) {
 
 if ($newQuestion || $editQuestion) {
 	// statement management
-	$type = Security::remove_XSS($_REQUEST['answerType']);
+	$type = isset($_REQUEST['answerType']) ? Security::remove_XSS($_REQUEST['answerType']) : null;
 	echo '<input type="hidden" name="Type" value="'.$type.'" />';
 
-        if ($newQuestion == 'yes') {
-            $objExercise->edit_exercise_in_lp = true;
-        }
+    if ($newQuestion == 'yes') {
+        $objExercise->edit_exercise_in_lp = true;
+    }
 
 	require 'question_admin.inc.php';
 }
@@ -523,7 +523,7 @@ if (!$newQuestion && !$modifyQuestion && !$editQuestion && !isset($_GET['hotspot
 }
 
 // if we are in question authoring, display warning to user is feedback not shown at the end of the test -ref #6619
-// this test to displau only message in the question authoring page and not in the question list page too
+// this test to display only message in the question authoring page and not in the question list page too
 // if (is_object($objQuestion) && $objExercise->selectFeedbackType() == EXERCISE_FEEDBACK_TYPE_EXAM && ($newQuestion || $modifyQuestion || $editQuestion)) {
 if ($objExercise->selectFeedbackType() == EXERCISE_FEEDBACK_TYPE_EXAM) {
     Display::display_normal_message(get_lang("TestFeedbackNotShown"));

+ 29 - 27
main/exercice/answer.class.php

@@ -73,7 +73,8 @@ class Answer
 
         // fills arrays
         $objExercise = new Exercise($this->course_id);
-        $objExercise->read($_REQUEST['exerciseId']);
+        $exerciseId = isset($_REQUEST['exerciseId']) ? $_REQUEST['exerciseId'] : null;
+        $objExercise->read($exerciseId);
         if ($objExercise->random_answers == '1') {
             $this->readOrderedBy('rand()', '');// randomize answers
         } else {
@@ -84,7 +85,7 @@ class Answer
     /**
      * Clears $new_* arrays
      *
-     * @author - Olivier Brouckaert
+     * @author Olivier Brouckaert
      */
     function cancel() {
         $this->new_answer				= array();
@@ -101,7 +102,7 @@ class Answer
     /**
      * Reads answer information from the database
      *
-     * @author - Olivier Brouckaert
+     * @author Olivier Brouckaert
      */
     public function read()
     {
@@ -137,8 +138,8 @@ class Answer
      /**
      * returns all answer ids from this question Id
      *
-     * @author - Yoselyn Castillo
-     * @return - array - $id (answer ids)
+     * @author Yoselyn Castillo
+     * @return array - $id (answer ids)
      */
     public function selectAnswerId()
     {
@@ -223,8 +224,8 @@ class Answer
 	/**
 	 * returns the autoincrement id identificator
 	 *
-	 * @author - Juan Carlos Ra�a
-	 * @return - integer - answer num
+	 * @author Juan Carlos Ra�a
+	 * @return integer - answer num
 	 */
 	function selectAutoId($id)
     {
@@ -234,8 +235,8 @@ class Answer
 	/**
 	 * returns the number of answers in this question
 	 *
-	 * @author - Olivier Brouckaert
-	 * @return - integer - number of answers
+	 * @author Olivier Brouckaert
+	 * @return integer - number of answers
 	 */
 	function selectNbrAnswers()
     {
@@ -245,8 +246,8 @@ class Answer
 	/**
 	 * returns the question ID which the answers belong to
 	 *
-	 * @author - Olivier Brouckaert
-	 * @return - integer - the question ID
+	 * @author Olivier Brouckaert
+	 * @return integer - the question ID
 	 */
 	function selectQuestionId()
     {
@@ -256,8 +257,8 @@ class Answer
 	/**
 	 * returns the question ID of the destination question
 	 *
-	 * @author - Julio Montoya
-	 * @return - integer - the question ID
+	 * @author Julio Montoya
+	 * @return integer - the question ID
 	 */
 	function selectDestination($id)
     {
@@ -267,9 +268,9 @@ class Answer
     /**
 	 * returns the answer title
 	 *
-	 * @author - Olivier Brouckaert
+	 * @author Olivier Brouckaert
 	 * @param - integer $id - answer ID
-	 * @return - string - answer title
+	 * @return string - answer title
 	 */
 	function selectAnswer($id)
     {
@@ -296,9 +297,9 @@ class Answer
     /**
      * returns the answer title from an answer's position
      *
-     * @author - Yannick Warnier
+     * @author Yannick Warnier
      * @param - integer $id - answer ID
-     * @return - bool - answer title
+     * @return bool - answer title
      */
 	function selectAnswerIdByPosition($pos) {
 		foreach ($this->position as $k => $v) {
@@ -374,9 +375,9 @@ class Answer
 	/**
 	 * tells if answer is correct or not
 	 *
-	 * @author - Olivier Brouckaert
+	 * @author Olivier Brouckaert
 	 * @param - integer $id - answer ID
-	 * @return - integer - 0 if bad answer, not 0 if good answer
+	 * @return integer - 0 if bad answer, not 0 if good answer
 	 */
 	function isCorrect($id)
 	{
@@ -386,9 +387,9 @@ class Answer
 	/**
 	 * returns answer comment
 	 *
-	 * @author - Olivier Brouckaert
+	 * @author Olivier Brouckaert
 	 * @param - integer $id - answer ID
-	 * @return - string - answer comment
+	 * @return string - answer comment
 	 */
 	function selectComment($id)
 	{
@@ -398,9 +399,9 @@ class Answer
 	/**
 	 * returns answer weighting
 	 *
-	 * @author - Olivier Brouckaert
+	 * @author Olivier Brouckaert
 	 * @param - integer $id - answer ID
-	 * @return - integer - answer weighting
+	 * @return integer - answer weighting
 	 */
 	function selectWeighting($id)
 	{
@@ -410,9 +411,9 @@ class Answer
 	/**
 	 * returns answer position
 	 *
-	 * @author - Olivier Brouckaert
+	 * @author Olivier Brouckaert
 	 * @param - integer $id - answer ID
-	 * @return - integer - answer position
+	 * @return integer - answer position
 	 */
 	function selectPosition($id)
 	{
@@ -506,7 +507,7 @@ class Answer
 	/**
 	 * Records answers into the data base
 	 *
-	 * @author - Olivier Brouckaert
+	 * @author Olivier Brouckaert
 	 */
 	function save()
     {
@@ -533,7 +534,8 @@ class Answer
 			    $sql.="($c_id, '$i','$questionId','$answer','$correct','$comment','$weighting','$position','$hotspot_coordinates','$hotspot_type','$destination'),";
             } else {
                 // https://support.chamilo.org/issues/6558
-                // function updateAnswers already escape_string, error if we do it twice. Feed function updateAnswers with none escaped strings
+                // function updateAnswers already escape_string, error if we do it twice.
+                // Feed function updateAnswers with none escaped strings
                 $this->updateAnswers(
                     $this->new_answer[$i],
                     $this->new_comment[$i],

+ 28 - 17
main/exercice/exercice.php

@@ -1,5 +1,4 @@
 <?php
-
 /* For licensing terms, see /license.txt */
 /**
  * 	Exercise list: This script shows the list of exercises for administrators and students.
@@ -122,30 +121,40 @@ if (!empty($gradebook) && $gradebook == 'view') {
 }
 
 $nameTools = get_lang('Exercices');
-
+$errorXmlExport = null;
 if ($is_allowedToEdit && !empty($choice) && $choice == 'exportqti2') {
     require_once 'export/qti2/qti2_export.php';
+
     $export = export_exercise($exerciseId, true);
 
     require_once api_get_path(LIBRARY_PATH).'pclzip/pclzip.lib.php';
     $archive_path = api_get_path(SYS_ARCHIVE_PATH);
     $temp_dir_short = api_get_unique_id();
-    $temp_zip_dir = $archive_path."/".$temp_dir_short;
-    if (!is_dir($temp_zip_dir))
+    $temp_zip_dir = $archive_path.$temp_dir_short;
+    if (!is_dir($temp_zip_dir)) {
         mkdir($temp_zip_dir, api_get_permissions_for_new_directories());
+    }
     $temp_zip_file = $temp_zip_dir."/".api_get_unique_id().".zip";
     $temp_xml_file = $temp_zip_dir."/qti2export_".$exerciseId.'.xml';
     file_put_contents($temp_xml_file, $export);
-    $zip_folder = new PclZip($temp_zip_file);
-    $zip_folder->add($temp_xml_file, PCLZIP_OPT_REMOVE_ALL_PATH);
-    $name = 'qti2_export_'.$exerciseId.'.zip';
-
-    //DocumentManager::string_send_for_download($export,true,'qti2export_'.$exerciseId.'.xml');
-    DocumentManager :: file_send_for_download($temp_zip_file, true, $name);
-    unlink($temp_zip_file);
-    unlink($temp_xml_file);
-    rmdir($temp_zip_dir);
-    exit; //otherwise following clicks may become buggy
+
+    $xmlReader = new XMLReader();
+    $xmlReader->open($temp_xml_file);
+    $xmlReader->setParserProperty(XMLReader::VALIDATE, true);
+    $isValid = $xmlReader->isValid();
+
+    if ($isValid) {
+        $zip_folder = new PclZip($temp_zip_file);
+        $zip_folder->add($temp_xml_file, PCLZIP_OPT_REMOVE_ALL_PATH);
+        $name = 'qti2_export_'.$exerciseId.'.zip';
+        DocumentManager::file_send_for_download($temp_zip_file, true, $name);
+        unlink($temp_zip_file);
+        unlink($temp_xml_file);
+        rmdir($temp_zip_dir);
+        exit; //otherwise following clicks may become buggy
+    } else {
+        $errorXmlExport = Display :: return_message(get_lang('ErrorWritingXMLFile'), 'error');
+    }
 }
 
 $htmlHeadXtra[] = '<script>
@@ -195,14 +204,16 @@ event_access_tool(TOOL_QUIZ);
 // Tool introduction
 Display :: display_introduction_section(TOOL_QUIZ);
 
+if (!empty($errorXmlExport)) {
+    echo $errorXmlExport;
+}
+
 HotPotGCt($documentPath, 1, api_get_user_id());
 
 // only for administrator
 
 if ($is_allowedToEdit) {
-
     if (!empty($choice)) {
-
         // All test choice, clean all test's results
         if ($choice == 'clean_all_test') {
             $check = Security::check_token('get');
@@ -649,7 +660,7 @@ if (!empty($exercise_list)) {
                             }
                         }
                         // Export qti ...
-                        $actions .= Display::url(Display::return_icon('export_qti2.png', 'IMS/QTI', '', ICON_SIZE_SMALL), 'exercice.php?choice=exportqti2&exerciseId='.$row['id']);
+                        $actions .= Display::url(Display::return_icon('export_qti2.png', 'IMS/QTI', '', ICON_SIZE_SMALL), 'exercice.php?choice=exportqti2&exerciseId='.$row['id'].'&'.api_get_cidreq());
                     } else {
                         // not session
                         $actions = Display::return_icon('edit_na.png', get_lang('ExerciseEditionNotAvailableInSession'));

+ 160 - 121
main/exercice/exercise.class.php

@@ -66,7 +66,8 @@ class Exercise {
      *
      * @author - Olivier Brouckaert
      */
-    function Exercise($course_id = null) {
+    public function Exercise($course_id = null)
+    {
         $this->id				= 0;
         $this->exercise			= '';
         $this->description		= '';
@@ -98,13 +99,14 @@ class Exercise {
     }
 
     /**
-     * reads exercise informations from the data base
+     * Reads exercise information from the data base
      *
-     * @author - Olivier Brouckaert
-     * @param - integer $id - exercise ID
-     * @return - boolean - true if exercise exists, otherwise false
+     * @author Olivier Brouckaert
+     * @param integer $id - exercise ID
+     * @return boolean - true if exercise exists, otherwise false
      */
-    function read($id) {
+    public function read($id)
+    {
         global $_configuration;
         $TBL_EXERCICES = Database::get_course_table(TABLE_QUIZ_TEST);
         $table_lp_item = Database::get_course_table(TABLE_LP_ITEM);
@@ -192,7 +194,8 @@ class Exercise {
         return false;
     }
 
-    function getCutTitle() {
+    function getCutTitle()
+    {
         return cut($this->exercise, EXERCISE_MAX_NAME_SIZE);
     }
 
@@ -209,8 +212,8 @@ class Exercise {
     /**
      * returns the exercise title
      *
-     * @author - Olivier Brouckaert
-     * @return - string - exercise title
+     * @author Olivier Brouckaert
+     * @return string - exercise title
      */
     function selectTitle() {
         return $this->exercise;
@@ -219,7 +222,7 @@ class Exercise {
     /**
      * returns the number of attempts setted
      *
-     * @return - numeric - exercise attempts
+     * @return numeric - exercise attempts
      */
     function selectAttempts() {
         return $this->attempts;
@@ -227,7 +230,7 @@ class Exercise {
 
     /** returns the number of FeedbackType  *
      *  0=>Feedback , 1=>DirectFeedback, 2=>NoFeedback
-     * @return - numeric - exercise attempts
+     * @return numeric - exercise attempts
      */
     function selectFeedbackType() {
         return $this->feedback_type;
@@ -243,8 +246,8 @@ class Exercise {
     /**
      * returns the exercise description
      *
-     * @author - Olivier Brouckaert
-     * @return - string - exercise description
+     * @author Olivier Brouckaert
+     * @return string - exercise description
      */
     function selectDescription() {
         return $this->description;
@@ -253,8 +256,8 @@ class Exercise {
     /**
      * returns the exercise sound file
      *
-     * @author - Olivier Brouckaert
-     * @return - string - exercise description
+     * @author Olivier Brouckaert
+     * @return string - exercise description
      */
     function selectSound() {
         return $this->sound;
@@ -263,16 +266,16 @@ class Exercise {
     /**
      * returns the exercise type
      *
-     * @author - Olivier Brouckaert
-     * @return - integer - exercise type
+     * @author Olivier Brouckaert
+     * @return integer - exercise type
      */
     function selectType() {
         return $this->type;
     }
 
     /**
-     * @author - hubert borderiou 30-11-11
-     * @return - integer : do we display the question category name for students
+     * @author hubert borderiou 30-11-11
+     * @return integer : do we display the question category name for students
      */
     function selectDisplayCategoryName() {
         return $this->display_category_name;
@@ -283,8 +286,8 @@ class Exercise {
     }
 
     /**
-     * @author - hubert borderiou 30-11-11
-     * @return - : modify object to update the switch display_category_name
+     * @author hubert borderiou 30-11-11
+     * @return : modify object to update the switch display_category_name
      * $in_txt is an integer 0 or 1
      */
     function updateDisplayCategoryName($in_txt) {
@@ -292,16 +295,16 @@ class Exercise {
     }
 
     /**
-     * @author - hubert borderiou 28-11-11
-     * @return - html text : the text to display ay the end of the test.
+     * @author hubert borderiou 28-11-11
+     * @return html text : the text to display ay the end of the test.
      */
     function selectTextWhenFinished() {
         return $this->text_when_finished;
     }
 
     /**
-     * @author - hubert borderiou 28-11-11
-     * @return - html text : update the text to display ay the end of the test.
+     * @author hubert borderiou 28-11-11
+     * @return html text : update the text to display ay the end of the test.
      */
     function updateTextWhenFinished($in_txt) {
         $this->text_when_finished = $in_txt;
@@ -309,8 +312,8 @@ class Exercise {
 
     /**
      * return 1 or 2 if randomByCat
-     * @author - hubert borderiou
-     * @return - integer - quiz random by category
+     * @author hubert borderiou
+     * @return integer - quiz random by category
      */
     function selectRandomByCat() {
         return $this->randomByCat;
@@ -320,8 +323,8 @@ class Exercise {
      * return 0 if no random by cat
      * return 1 if random by cat, categories shuffled
      * return 2 if random by cat, categories sorted by alphabetic order
-     * @author - hubert borderiou
-     * @return - integer - quiz random by category
+     * @author hubert borderiou
+     * @return integer - quiz random by category
      */
     function isRandomByCat() {
         $res = 0;
@@ -336,7 +339,7 @@ class Exercise {
     /**
      * return nothing
      * update randomByCat value for object
-     * @author - hubert borderiou
+     * @author hubert borderiou
      */
     function updateRandomByCat($in_randombycat) {
         if ($in_randombycat == 1) {
@@ -352,8 +355,8 @@ class Exercise {
     /**
      * tells if questions are selected randomly, and if so returns the draws
      *
-     * @author - Carlos Vargas
-     * @return - integer - results disabled exercise
+     * @author Carlos Vargas
+     * @return integer - results disabled exercise
      */
     function selectResultsDisabled() {
         return $this->results_disabled;
@@ -362,8 +365,8 @@ class Exercise {
     /**
      * tells if questions are selected randomly, and if so returns the draws
      *
-     * @author - Olivier Brouckaert
-     * @return - integer - 0 if not random, otherwise the draws
+     * @author Olivier Brouckaert
+     * @return integer - 0 if not random, otherwise the draws
      */
     function isRandom() {
         if($this->random > 0 || $this->random == -1) {
@@ -376,7 +379,7 @@ class Exercise {
     /**
      * returns random answers status.
      *
-     * @author - Juan Carlos Rana
+     * @author Juan Carlos Rana
      */
     function selectRandomAnswers() {
         return $this->random_answers;
@@ -392,8 +395,8 @@ class Exercise {
     /**
      * returns the exercise status (1 = enabled ; 0 = disabled)
      *
-     * @author - Olivier Brouckaert
-     * @return - boolean - true if enabled, otherwise false
+     * @author Olivier Brouckaert
+     * @return boolean - true if enabled, otherwise false
      */
     function selectStatus() {
         return $this->active;
@@ -402,8 +405,8 @@ class Exercise {
     /**
      * returns the array with the question ID list
      *
-     * @author - Olivier Brouckaert
-     * @return - array - question ID list
+     * @author Olivier Brouckaert
+     * @return array - question ID list
      */
     function selectQuestionList($from_db = false) {
         if ($from_db && !empty($this->id)) {
@@ -450,8 +453,8 @@ class Exercise {
     /**
      * returns the number of questions in this exercise
      *
-     * @author - Olivier Brouckaert
-     * @return - integer - number of questions
+     * @author Olivier Brouckaert
+     * @return integer - number of questions
      */
     function selectNbrQuestions() {
         return sizeof($this->questionList);
@@ -464,8 +467,8 @@ class Exercise {
     /**
      * Selects questions randomly in the question list
      *
-     * @author - Olivier Brouckaert
-     * @return - array - if the exercise is not set to take questions randomly, returns the question list
+     * @author Olivier Brouckaert
+     * @return array - if the exercise is not set to take questions randomly, returns the question list
      *					 without randomizing, otherwise, returns the list with questions selected randomly
      * Modified by Hubert Borderiou 15 nov 2011
      */
@@ -502,9 +505,9 @@ class Exercise {
     /**
      * returns 'true' if the question ID is in the question list
      *
-     * @author - Olivier Brouckaert
-     * @param - integer $questionId - question ID
-     * @return - boolean - true if in the list, otherwise false
+     * @author Olivier Brouckaert
+     * @param integer $questionId - question ID
+     * @return boolean - true if in the list, otherwise false
      */
     function isInList($questionId) {
         if (is_array($this->questionList))
@@ -516,8 +519,8 @@ class Exercise {
     /**
      * changes the exercise title
      *
-     * @author - Olivier Brouckaert
-     * @param - string $title - exercise title
+     * @author Olivier Brouckaert
+     * @param string $title - exercise title
      */
     function updateTitle($title) {
         $this->exercise=$title;
@@ -526,7 +529,7 @@ class Exercise {
     /**
      * changes the exercise max attempts
      *
-     * @param - numeric $attempts - exercise max attempts
+     * @param numeric $attempts - exercise max attempts
      */
     function updateAttempts($attempts) {
         $this->attempts=$attempts;
@@ -536,7 +539,7 @@ class Exercise {
     /**
      * changes the exercise feedback type
      *
-     * @param - numeric $attempts - exercise max attempts
+     * @param numeric $attempts - exercise max attempts
      */
     function updateFeedbackType($feedback_type) {
         $this->feedback_type=$feedback_type;
@@ -545,8 +548,8 @@ class Exercise {
     /**
      * changes the exercise description
      *
-     * @author - Olivier Brouckaert
-     * @param - string $description - exercise description
+     * @author Olivier Brouckaert
+     * @param string $description - exercise description
      */
     function updateDescription($description) {
         $this->description=$description;
@@ -555,8 +558,8 @@ class Exercise {
     /**
      * changes the exercise expired_time
      *
-     * @author - Isaac flores
-     * @param - int The expired time of the quiz
+     * @author Isaac flores
+     * @param int The expired time of the quiz
      */
     function updateExpiredTime($expired_time) {
         $this->expired_time = $expired_time;
@@ -577,9 +580,9 @@ class Exercise {
     /**
      * changes the exercise sound file
      *
-     * @author - Olivier Brouckaert
-     * @param - string $sound - exercise sound file
-     * @param - string $delete - ask to delete the file
+     * @author Olivier Brouckaert
+     * @param string $sound - exercise sound file
+     * @param string $delete - ask to delete the file
      */
     function updateSound($sound,$delete) {
         global $audioPath, $documentPath;
@@ -609,8 +612,8 @@ class Exercise {
     /**
      * changes the exercise type
      *
-     * @author - Olivier Brouckaert
-     * @param - integer $type - exercise type
+     * @author Olivier Brouckaert
+     * @param integer $type - exercise type
      */
     function updateType($type) {
         $this->type=$type;
@@ -620,8 +623,8 @@ class Exercise {
      * sets to 0 if questions are not selected randomly
      * if questions are selected randomly, sets the draws
      *
-     * @author - Olivier Brouckaert
-     * @param - integer $random - 0 if not random, otherwise the draws
+     * @author Olivier Brouckaert
+     * @param integer $random - 0 if not random, otherwise the draws
      */
     function setRandom($random) {
         /*if ($random == 'all') {
@@ -634,8 +637,8 @@ class Exercise {
     /**
      * sets to 0 if answers are not selected randomly
      * if answers are selected randomly
-     * @author - Juan Carlos Rana
-     * @param - integer $random_answers - random answers
+     * @author Juan Carlos Rana
+     * @param integer $random_answers - random answers
      */
     function updateRandomAnswers($random_answers) {
         $this->random_answers = $random_answers;
@@ -644,7 +647,7 @@ class Exercise {
     /**
      * enables the exercise
      *
-     * @author - Olivier Brouckaert
+     * @author Olivier Brouckaert
      */
     function enable() {
         $this->active=1;
@@ -653,7 +656,7 @@ class Exercise {
     /**
      * disables the exercise
      *
-     * @author - Olivier Brouckaert
+     * @author Olivier Brouckaert
      */
     function disable() {
         $this->active=0;
@@ -675,7 +678,7 @@ class Exercise {
     /**
      * updates the exercise in the data base
      *
-     * @author - Olivier Brouckaert
+     * @author Olivier Brouckaert
      */
     function save($type_e = '')
     {
@@ -832,9 +835,9 @@ class Exercise {
     /**
      * Adds a question into the question list
      *
-     * @author - Olivier Brouckaert
-     * @param - integer $questionId - question ID
-     * @return - boolean - true if the question has been added, otherwise false
+     * @author Olivier Brouckaert
+     * @param integer $questionId - question ID
+     * @return boolean - true if the question has been added, otherwise false
      */
     function addToList($questionId) {
         // checks if the question ID is not in the list
@@ -855,9 +858,9 @@ class Exercise {
     /**
      * removes a question from the question list
      *
-     * @author - Olivier Brouckaert
-     * @param - integer $questionId - question ID
-     * @return - boolean - true if the question has been removed, otherwise false
+     * @author Olivier Brouckaert
+     * @param integer $questionId - question ID
+     * @return boolean - true if the question has been removed, otherwise false
      */
     function removeFromList($questionId) {
         // searches the position of the question ID in the list
@@ -885,7 +888,7 @@ class Exercise {
      * deletes the exercise from the database
      * Notice : leaves the question in the data base
      *
-     * @author - Olivier Brouckaert
+     * @author Olivier Brouckaert
      */
     function delete() {
         $TBL_EXERCICES = Database::get_course_table(TABLE_QUIZ_TEST);
@@ -900,7 +903,7 @@ class Exercise {
 
     /**
      * Creates the form to create / edit an exercise
-     * @param FormValidator $form the formvalidator instance (by reference)
+     * @param FormValidator $form
      */
     function createForm ($form, $type='full') {
         global $id;
@@ -1472,23 +1475,27 @@ class Exercise {
             Database::query($sql);
 
             // remove terms from db
-            require_once(api_get_path(LIBRARY_PATH) .'specific_fields_manager.lib.php');
+            require_once api_get_path(LIBRARY_PATH) .'specific_fields_manager.lib.php';
             delete_all_values_for_item($course_id, TOOL_QUIZ, $this->id);
         }
     }
-    function selectExpiredTime() {
+
+    function selectExpiredTime()
+    {
         return $this->expired_time;
     }
 
     /**
      * Cleans the student's results only for the Exercise tool (Not from the LP)
-     * The LP results are NOT deleted by default, otherwise put $clean_lp_tests = true
+     * The LP results are NOT deleted by default, otherwise put $cleanLpTests = true
      * Works with exercises in sessions
-     * @param bool $clean_lp_tests
-     * @param int $clean_result_before_date
+     * @param bool $cleanLpTests
+     * @param string $cleanResultBeforeDate
+     *
      * @return int quantity of user's exercises deleted
      */
-    function clean_results($clean_lp_tests = false, $clean_result_before_date = '0') {
+    public function clean_results($cleanLpTests = false, $cleanResultBeforeDate = null)
+    {
         $table_track_e_exercises = Database::get_statistic_table(TABLE_STATISTIC_TRACK_E_EXERCICES);
         $table_track_e_attempt   = Database::get_statistic_table(TABLE_STATISTIC_TRACK_E_ATTEMPT);
 
@@ -1497,44 +1504,62 @@ class Exercise {
                         orig_lp_item_id = 0';
 
         // if we want to delete results from LP too
-        if ($clean_lp_tests) {
+        if ($cleanLpTests) {
             $sql_where = "";
         }
 
-        // if we want to delete attempts before date $clean_result_before_date
-        // $clean_result_before_date must be a valid UTC-0 date yyyy-mm-dd
-        if ($clean_result_before_date != '0') {
-            $sql_where .= "  AND exe_date <= '$clean_result_before_date' ";
+        // if we want to delete attempts before date $cleanResultBeforeDate
+        // $cleanResultBeforeDate must be a valid UTC-0 date yyyy-mm-dd
+        if (!empty($cleanResultBeforeDate)) {
+            $cleanResultBeforeDate = Database::escape_string($cleanResultBeforeDate);
+            if (api_is_valid_date($cleanResultBeforeDate)) {
+                $sql_where .= "  AND exe_date <= '$cleanResultBeforeDate' ";
+            } else {
+                return 0;
+            }
         }
 
-        $sql_select = "SELECT exe_id FROM $table_track_e_exercises
-					   WHERE 	exe_cours_id = '".api_get_course_id()."' AND
-								exe_exo_id = ".$this->id." AND
-								session_id = ".api_get_session_id()." ".
-                                $sql_where;
+        $sql = "SELECT exe_id
+                FROM $table_track_e_exercises
+                WHERE
+                    exe_cours_id = '".api_get_course_id()."' AND
+                    exe_exo_id = ".$this->id." AND
+                    session_id = ".api_get_session_id()." ".
+                    $sql_where;
 
-        $result   = Database::query($sql_select);
+        $result   = Database::query($sql);
         $exe_list = Database::store_result($result);
 
         // deleting TRACK_E_ATTEMPT table
         // check if exe in learning path or not
         $i = 0;
         if (is_array($exe_list) && count($exe_list) > 0) {
-            foreach($exe_list as $item) {
+            foreach ($exe_list as $item) {
                 $sql = "DELETE FROM $table_track_e_attempt WHERE exe_id = '".$item['exe_id']."'";
                 Database::query($sql);
                 $i++;
             }
         }
 
+        $session_id = api_get_session_id();
         // delete TRACK_E_EXERCICES table
         $sql = "DELETE FROM $table_track_e_exercises
                 WHERE exe_cours_id = '".api_get_course_id()."'
                 AND exe_exo_id = ".$this->id."
                 $sql_where
-                AND session_id = ".api_get_session_id()."";
+                AND session_id = ".$session_id."";
         Database::query($sql);
 
+        event_system(
+            LOG_EXERCISE_RESULT_DELETE,
+            LOG_EXERCISE_ID,
+            $this->id,
+            null,
+            null,
+            api_get_course_id(),
+            $session_id
+        );
+
         return $i;
     }
 
@@ -1580,7 +1605,7 @@ class Exercise {
     /**
      * Changes the exercise id
      *
-     * @param - in $id - exercise id
+     * @param int $id - exercise id
      */
     private function updateId($id) {
         $this->id = $id;
@@ -1589,7 +1614,7 @@ class Exercise {
     /**
      * Changes the exercise status
      *
-     * @param - string $status - exercise status
+     * @param string $status - exercise status
      */
     function updateStatus($status) {
         $this->active = $status;
@@ -2119,13 +2144,15 @@ class Exercise {
 
             switch ($answerType) {
                 // for unique answer
-                case UNIQUE_ANSWER :
-                case UNIQUE_ANSWER_NO_OPTION :
+                case UNIQUE_ANSWER:
+                case UNIQUE_ANSWER_NO_OPTION:
                     if ($from_database) {
-                        $queryans = "SELECT answer FROM ".$TBL_TRACK_ATTEMPT."
-                        WHERE exe_id = '".$exeId."' and question_id= '".$questionId."'";
-                        $resultans = Database::query($queryans);
-                        $choice = Database::result($resultans,0,"answer");
+                        $sql = "SELECT answer FROM $TBL_TRACK_ATTEMPT
+                                WHERE
+                                    exe_id = '".$exeId."' AND
+                                    question_id= '".$questionId."'";
+                        $result = Database::query($sql);
+                        $choice = Database::result($result,0,"answer");
 
                         $studentChoice = ($choice == $numAnswer)?1:0;
                         if ($studentChoice) {
@@ -2144,24 +2171,26 @@ class Exercise {
                 case MULTIPLE_ANSWER_TRUE_FALSE:
                     if ($from_database) {
                         $choice = array();
-                        $sql = "SELECT answer FROM ".$TBL_TRACK_ATTEMPT."
+                        $sql = "SELECT answer FROM $TBL_TRACK_ATTEMPT
                                 WHERE
-                                    exe_id = ".$exeId." AND
+                                    exe_id = $exeId AND
                                     question_id = ".$questionId;
-                        $resultans = Database::query($sql);
-                        while ($row = Database::fetch_array($resultans)) {
+
+                        $result = Database::query($sql);
+                        while ($row = Database::fetch_array($result)) {
                             $ind = $row['answer'];
-                            $result = explode(':', $ind);
-                            $my_answer_id = $result[0];
-                            $option = $result[1];
+                            $values = explode(':', $ind);
+                            $my_answer_id = $values[0];
+                            $option = $values[1];
                             $choice[$my_answer_id] = $option;
                         }
                     }
+
                     $studentChoice = isset($choice[$numAnswer]) ? $choice[$numAnswer] : null;
 
                     if (!empty($studentChoice)) {
                         if ($studentChoice == $answerCorrect) {
-                            $questionScore  += $true_score;
+                            $questionScore += $true_score;
                         } else {
                             if ($quiz_question_options[$studentChoice]['name'] != "Don't know") {
                                 $questionScore += $false_score;
@@ -2568,18 +2597,21 @@ class Exercise {
                     }
                 case HOT_SPOT :
                     if ($from_database) {
-                        if ($show_result) {
-                            $TBL_TRACK_HOTSPOT = Database::get_statistic_table(TABLE_STATISTIC_TRACK_E_HOTSPOT);
-                            $query = "SELECT hotspot_correct FROM ".$TBL_TRACK_HOTSPOT." WHERE hotspot_exe_id = '".$exeId."' and hotspot_question_id= '".$questionId."' AND hotspot_answer_id='".Database::escape_string($answerId)."'";
-                            $resq = Database::query($query);
-                            $studentChoice = Database::result($resq,0,"hotspot_correct");
+                        $TBL_TRACK_HOTSPOT = Database::get_statistic_table(TABLE_STATISTIC_TRACK_E_HOTSPOT);
+                        $sql = "SELECT hotspot_correct
+                                FROM $TBL_TRACK_HOTSPOT
+                                WHERE
+                                    hotspot_exe_id = '".$exeId."' AND
+                                    hotspot_question_id= '".$questionId."' AND
+                                    hotspot_answer_id = '".Database::escape_string($answerId)."'";
+                        $result = Database::query($sql);
+                        $studentChoice = Database::result($result, 0, "hotspot_correct");
 
-                            if ($studentChoice) {
-                                $questionScore  += $answerWeighting;
-                                $totalScore     += $answerWeighting;
-                            }
+                        if ($studentChoice) {
+                            $questionScore  += $answerWeighting;
+                            $totalScore     += $answerWeighting;
                         }
-                    }  else {
+                    } else {
                         $studentChoice = $choice[$answerId];
                         if ($studentChoice) {
                             $questionScore  += $answerWeighting;
@@ -2604,7 +2636,13 @@ class Exercise {
                     if ($from_database) {
                         // getting the user answer
                         $TBL_TRACK_HOTSPOT = Database::get_statistic_table(TABLE_STATISTIC_TRACK_E_HOTSPOT);
-                        $query   = "SELECT hotspot_correct, hotspot_coordinate from ".$TBL_TRACK_HOTSPOT." where hotspot_exe_id = '".$exeId."' and hotspot_question_id= '".$questionId."' AND hotspot_answer_id='1'"; //by default we take 1 because it's a delineation
+                        $query   = "SELECT hotspot_correct, hotspot_coordinate
+                                    FROM $TBL_TRACK_HOTSPOT
+                                    WHERE
+                                        hotspot_exe_id = '".$exeId."' AND
+                                        hotspot_question_id= '".$questionId."' AND
+                                        hotspot_answer_id='1'";
+                        //by default we take 1 because it's a delineation
                         $resq    = Database::query($query);
                         $row     = Database::fetch_array($resq,'ASSOC');
 
@@ -4131,7 +4169,8 @@ class Exercise {
      * @param $in_title
      * @return string
      */
-    public static function get_formated_title_variable($in_title) {
+    public static function get_formated_title_variable($in_title)
+    {
         return api_html_entity_decode($in_title);
     }
 

+ 51 - 22
main/exercice/exercise.lib.php

@@ -45,6 +45,7 @@ function showQuestion($questionId, $only_questions = false, $origin = false, $cu
 
     $answerType    = $objQuestionTmp->selectType();
     $pictureName   = $objQuestionTmp->selectPicture();
+    $s = '';
 
     if ($answerType != HOT_SPOT && $answerType != HOT_SPOT_DELINEATION) {
     	// Question is not a hotspot
@@ -65,9 +66,6 @@ function showQuestion($questionId, $only_questions = false, $origin = false, $cu
         }
 
         echo '<div class="question_options">';
-
-    	$s = '';
-
     	// construction of the Answer object (also gets all answers details)
     	$objAnswerTmp = new Answer($questionId);
 
@@ -195,7 +193,7 @@ function showQuestion($questionId, $only_questions = false, $origin = false, $cu
                     $header .= Display::tag('th', get_lang('Feedback'));
                 }
                 $s .= '<table class="data_table">';
-                $s.= Display::tag('tr',$header, array('style'=>'text-align:left;'));
+                $s .= Display::tag('tr',$header, array('style'=>'text-align:left;'));
             }
         }
 
@@ -353,16 +351,16 @@ function showQuestion($questionId, $only_questions = false, $origin = false, $cu
                 $answer_input .= '</label>';
 
                 if ($show_comment) {
-                    $s.= '<tr>';
+                    $s .= '<tr>';
                     $s .= '<td>';
-                    $s.= $answer_input;
+                    $s .= $answer_input;
                     $s .= '</td>';
                     $s .= '<td>';
                     $s .= $comment;
                     $s .= '</td>';
-                    $s.= '</tr>';
+                    $s .= '</tr>';
                 } else {
-                    $s.= $answer_input;
+                    $s .= $answer_input;
                 }
 
             } elseif ($answerType == MULTIPLE_ANSWER_COMBINATION_TRUE_FALSE) {
@@ -400,7 +398,7 @@ function showQuestion($questionId, $only_questions = false, $origin = false, $cu
                     $s .= $comment;
                     $s .= '</td>';
                 }
-            	$s.='</tr>';
+            	$s .='</tr>';
 
     		} elseif ($answerType == FILL_IN_BLANKS) {
                 /*
@@ -529,7 +527,7 @@ function showQuestion($questionId, $only_questions = false, $origin = false, $cu
     				}  // end foreach()
 
     				$s .= '</select></td>';
-    				$s.='<td width="45%" valign="top" >';
+    				$s .='<td width="45%" valign="top" >';
     				if (isset($select_items[$lines_count])) {
     					$s.='<span style="float:left; width:5%;"><b>'.$select_items[$lines_count]['letter'].'.</b></span>'.
     						 '<span style="float:left; width:95%;">'.$select_items[$lines_count]['answer'].'</span>';
@@ -547,8 +545,8 @@ function showQuestion($questionId, $only_questions = false, $origin = false, $cu
     						$s .= '<tr>
     							  <td colspan="2"></td>
     							  <td valign="top">';
-    						$s.='<b>'.$select_items[$lines_count]['letter'].'.</b> '.$select_items[$lines_count]['answer'];
-    						$s.="</td>
+    						$s .='<b>'.$select_items[$lines_count]['letter'].'.</b> '.$select_items[$lines_count]['answer'];
+    						$s .="</td>
     						</tr>";
     						$lines_count++;
     					}	// end while()
@@ -567,8 +565,6 @@ function showQuestion($questionId, $only_questions = false, $origin = false, $cu
             }
         }
 
-
-
     	$s .= '</div>';
 
     	// destruction of the Answer object
@@ -648,6 +644,7 @@ function showQuestion($questionId, $only_questions = false, $origin = false, $cu
     		echo $questionDescription;
     		echo '</td></tr>';
     	}
+
     	$canClick = isset($_GET['editQuestion']) ? '0' : (isset($_GET['modifyAnswers']) ? '0' : '1');
 
     	$s .= '<script type="text/javascript" src="../plugin/hotspot/JavaScriptFlashGateway.js"></script>
@@ -788,6 +785,7 @@ function showQuestion($questionId, $only_questions = false, $origin = false, $cu
     	echo $s;
         echo '</table>';
     }
+
     return $nbrAnswers;
 }
 
@@ -2277,14 +2275,25 @@ function display_question_list_by_attempt($objExercise, $exe_id, $save_user_resu
             ob_start();
 
             // We're inside *one* question. Go through each possible answer for this question
-            $result = $objExercise->manage_answer($exercise_stat_info['exe_id'], $questionId, null, 'exercise_result', array(), $save_user_result, true, $show_results, $objExercise->selectPropagateNeg(), $hotspot_delineation_result);
+            $result = $objExercise->manage_answer(
+                $exercise_stat_info['exe_id'],
+                $questionId,
+                null,
+                'exercise_result',
+                array(),
+                $save_user_result,
+                true,
+                $show_results,
+                $objExercise->selectPropagateNeg(),
+                array()
+            );
 
             if (empty($result)) {
                 continue;
             }
 
-            $total_score     += $result['score'];
-            $total_weight    += $result['weight'];
+            $total_score += $result['score'];
+            $total_weight += $result['weight'];
 
             $question_list_answers[] = array(
                 'question' => $result['open_question'],
@@ -2295,8 +2304,7 @@ function display_question_list_by_attempt($objExercise, $exe_id, $save_user_resu
             $my_total_score  = $result['score'];
             $my_total_weight = $result['weight'];
 
-
-            //Category report
+            // Category report
             $category_was_added_for_this_test = false;
 
             if (isset($objQuestionTmp->category) && !empty($objQuestionTmp->category)) {
@@ -2313,8 +2321,15 @@ function display_question_list_by_attempt($objExercise, $exe_id, $save_user_resu
                 }
             }
 
-            //No category for this question!
+            // No category for this question!
             if ($category_was_added_for_this_test == false) {
+                if (!isset($category_list['none']['score'])) {
+                    $category_list['none']['score'] = 0;
+                }
+                if (!isset($category_list['none']['total'])) {
+                    $category_list['none']['total'] = 0;
+                }
+
                 $category_list['none']['score'] += $my_total_score;
                 $category_list['none']['total'] += $my_total_weight;
             }
@@ -2383,6 +2398,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;
@@ -2390,7 +2407,6 @@ function display_question_list_by_attempt($objExercise, $exe_id, $save_user_resu
         echo $total_score_text;
     }
 
-
     if ($save_user_result) {
 
         // Tracking of results
@@ -2399,7 +2415,20 @@ function display_question_list_by_attempt($objExercise, $exe_id, $save_user_resu
         $learnpath_item_view_id = $exercise_stat_info['orig_lp_item_view_id'];
 
         if (api_is_allowed_to_session_edit()) {
-            update_event_exercice($exercise_stat_info['exe_id'], $objExercise->selectId(), $total_score, $total_weight, api_get_session_id(), $learnpath_id, $learnpath_item_id, $learnpath_item_view_id, $exercise_stat_info['exe_duration'], $question_list, '', array(), $end_date);
+            update_event_exercice(
+                $exercise_stat_info['exe_id'],
+                $objExercise->selectId(),
+                $total_score,
+                $total_weight,
+                api_get_session_id(),
+                $learnpath_id,
+                $learnpath_item_id,
+                $learnpath_item_view_id,
+                $exercise_stat_info['exe_duration'],
+                $question_list,
+                '',
+                array()
+            );
         }
 
         // Send notification ..

+ 4 - 8
main/exercice/exercise_report.php

@@ -283,14 +283,10 @@ if (($is_allowedToEdit || $is_tutor || api_is_coach()) && isset($_GET['delete_be
     // ask for the date
     $check = Security::check_token('get');
     if ($check) {
-        // delete attempts before date $_GET['delete_before_date']
-        $dateUTC = api_get_utc_datetime($_GET['delete_before_date']);
-        if (api_is_valid_date($_GET['delete_before_date'])) {
-            $objExerciseTmp = new Exercise();
-            if ($objExerciseTmp->read($exercise_id)) {
-                $nb_del = $objExerciseTmp->clean_results(true, $_GET['delete_before_date']);
-                Display :: display_confirmation_message(sprintf(get_lang('XResultsCleaned'), $nb_del));
-            }
+        $objExerciseTmp = new Exercise();
+        if ($objExerciseTmp->read($exercise_id)) {
+            $count = $objExerciseTmp->clean_results(true, $_GET['delete_before_date'].' 23:59:59');
+            Display::display_confirmation_message(sprintf(get_lang('XResultsCleaned'), $count));
         }
     }
 }

+ 175 - 219
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,82 +103,111 @@ 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;
+    $filePath = null;
 	// 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)) {
 					$result = parse_file($baseWorkDir, $file, $questionFile);
+                    $filePath = $baseWorkDir.$file;
 					$file_found = true;
 				}
 			}
 		} elseif (preg_match('/.xml$/i', $file)) {
+            // Else ignore file
 			$result = parse_file($baseWorkDir, '', $file);
+            $filePath = $baseWorkDir.'/'.$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;
     }
 
-	//add exercise in tool
 
-	//1.create exercise
+    $doc = new DOMDocument();
+    $doc->load($filePath);
+    $encoding = $doc->encoding;
+
+	// 1. Create exercise.
 	$exercise = new Exercise();
 	$exercise->exercise = $exercise_info['name'];
-    
+
 	$exercise->save();
 	$last_exercise_id = $exercise->selectId();
 	if (!empty($last_exercise_id)) {
-		//For each question found...
-		foreach ($exercise_info['question'] as $key => $question_array) {
-			//2.create question
+		// For each question found...
+		foreach ($exercise_info['question'] as $question_array) {
+			//2. Create question
 			$question = new Ims2Question();
 			$question->type = $question_array['type'];
 			$question->setAnswer();
-			$question->updateTitle($question_array['title']); // question ...
+			$question->updateTitle(formatText($question_array['title']));
+            //$question->updateDescription($question_array['title']);
 			$type = $question->selectType();
-			$question->type = constant($type); // type ...
-			$question->save($last_exercise_id); // save computed grade
+			$question->type = constant($type);
+			$question->save($last_exercise_id);
 			$last_question_id = $question->selectId();
-			//3.create answer
+			//3. Create answer
 			$answer = new Answer($last_question_id);
 			$answer->new_nbrAnswers = count($question_array['answer']);
+            $totalCorrectWeight = 0;
 			foreach ($question_array['answer'] as $key => $answers) {
 				$split = explode('_', $key);
 				$i = $split[1];
-				$answer->new_answer[$i] = $answers['value']; // answer ...
-				$answer->new_comment[$i] = $answers['feedback']; // comment ...
-				$answer->new_position[$i] = $i; // position ...
-				// correct answers ...
+                // Answer
+				$answer->new_answer[$i] = formatText($answers['value']);
+                // Comment
+				$answer->new_comment[$i] = isset($answers['feedback']) ? formatText($answers['feedback']) : null;
+                // Position
+				$answer->new_position[$i] = $i;
+				// Correct answers
 				if (in_array($key, $question_array['correct_answers'])) {
 					$answer->new_correct[$i] = 1;
 				} else {
 					$answer->new_correct[$i] = 0;
 				}
 				$answer->new_weighting[$i] = $question_array['weighting'][$key];
+                if ($answer->new_correct[$i]) {
+                    $totalCorrectWeight = $answer->new_weighting[$i];
+                }
 			}
+            $question->updateWeighting($totalCorrectWeight);
+            $question->save($last_exercise_id);
 			$answer->save();
 		}
+
 		// delete the temp dir where the exercise was unzipped
 		my_delete($baseWorkDir . $uploadPath);
 		$operation = true;
-	}    
+	}
 	return $operation;
 }
+/**
+ * We assume the file charset is UTF8
+ **/
+function formatText($text)
+{
+    return api_html_entity_decode($text);
+}
 
-function parse_file($exercisePath, $file, $questionFile) {
+function parse_file($exercisePath, $file, $questionFile)
+{
 	global $exercise_info;
 	global $element_pile;
 	global $non_HTML_tag_to_avoid;
@@ -184,7 +217,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 +226,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;
@@ -230,15 +263,15 @@ function parse_file($exercisePath, $file, $questionFile) {
 		"RESPONSECONDITION",
 		"RESPONSEIF"
 	);
-	$question_format_supported = true;
+
+    $question_format_supported = true;
 
 	$xml_parser = xml_parser_create();
 	xml_parser_set_option($xml_parser, XML_OPTION_SKIP_WHITE, false);
 	xml_set_element_handler($xml_parser, 'startElement', 'endElement');
 	xml_set_character_data_handler($xml_parser, 'elementData');
-
 	if (!xml_parse($xml_parser, $data, feof($fp))) {
-		// if reading of the xml file in not successfull :
+		// if reading of the xml file in not successful :
 		// set errorFound, set error msg, break while statement
 		Display :: display_error_message(get_lang('Error reading XML file'));
 		return false;
@@ -314,143 +347,89 @@ function startElement($parser, $name, $attributes) {
 				$current_question_item_body .= "<BR/>";
 			}
 		}
-
 	}
-
 	switch ($current_element) {
 		case 'ASSESSMENTITEM' :
-			{
-				//retrieve current question
-
-				$current_question_ident = $attributes['IDENTIFIER'];
-				$exercise_info['question'][$current_question_ident] = array ();
-				$exercise_info['question'][$current_question_ident]['answer'] = array ();
-				$exercise_info['question'][$current_question_ident]['correct_answers'] = array ();
-				$exercise_info['question'][$current_question_ident]['title'] = $attributes['TITLE'];
-				$exercise_info['question'][$current_question_ident]['tempdir'] = $questionTempDir;
-			}
-			break;
-
-		case 'SECTION' :
-			{
-				//retrieve exercise name
-
-				$exercise_info['name'] = $attributes['TITLE'];
-
-			}
+            //retrieve current question
+            $current_question_ident = $attributes['IDENTIFIER'];
+            $exercise_info['question'][$current_question_ident] = array ();
+            $exercise_info['question'][$current_question_ident]['answer'] = array ();
+            $exercise_info['question'][$current_question_ident]['correct_answers'] = array ();
+            $exercise_info['question'][$current_question_ident]['title'] = $attributes['TITLE'];
+            $exercise_info['question'][$current_question_ident]['tempdir'] = $questionTempDir;
+            break;
+		case 'SECTION':
+            //retrieve exercise name
+            $exercise_info['name'] = $attributes['TITLE'];
 			break;
-
-		case 'RESPONSEDECLARATION' :
-			{
-				//retrieve question type
-
-				if ("multiple" == $attributes['CARDINALITY']) {
-					$exercise_info['question'][$current_question_ident]['type'] = 'MCMA';
-					$cardinality = 'multiple';
-				}
-				if ("single" == $attributes['CARDINALITY']) {
-					$exercise_info['question'][$current_question_ident]['type'] = 'MCUA';
-					$cardinality = 'single';
-				}
-
-				//needed for FIB
-
-				$current_answer_id = $attributes['IDENTIFIER'];
-
-			}
+		case 'RESPONSEDECLARATION':
+            // Retrieve question type
+            if ("multiple" == $attributes['CARDINALITY']) {
+                $exercise_info['question'][$current_question_ident]['type'] = 'MCMA';
+                $cardinality = 'multiple';
+            }
+            if ("single" == $attributes['CARDINALITY']) {
+                $exercise_info['question'][$current_question_ident]['type'] = 'MCUA';
+                $cardinality = 'single';
+            }
+            //needed for FIB
+            $current_answer_id = $attributes['IDENTIFIER'];
 			break;
-
 		case 'INLINECHOICEINTERACTION' :
-			{
-				$exercise_info['question'][$current_question_ident]['type'] = 'FIB';
-				$exercise_info['question'][$current_question_ident]['subtype'] = 'LISTBOX_FILL';
-				$current_answer_id = $attributes['RESPONSEIDENTIFIER'];
-
-			}
+            $exercise_info['question'][$current_question_ident]['type'] = 'FIB';
+			$exercise_info['question'][$current_question_ident]['subtype'] = 'LISTBOX_FILL';
+			$current_answer_id = $attributes['RESPONSEIDENTIFIER'];
 			break;
-
 		case 'INLINECHOICE' :
-			{
-				$current_inlinechoice_id = $attributes['IDENTIFIER'];
-			}
+            $current_inlinechoice_id = $attributes['IDENTIFIER'];
 			break;
-
-		case 'TEXTENTRYINTERACTION' :
-			{
-				$exercise_info['question'][$current_question_ident]['type'] = 'FIB';
-				$exercise_info['question'][$current_question_ident]['subtype'] = 'TEXTFIELD_FILL';
-				$exercise_info['question'][$current_question_ident]['response_text'] = $current_question_item_body;
-
-				//replace claroline tags
-
-			}
+		case 'TEXTENTRYINTERACTION':
+            $exercise_info['question'][$current_question_ident]['type'] = 'FIB';
+            $exercise_info['question'][$current_question_ident]['subtype'] = 'TEXTFIELD_FILL';
+            $exercise_info['question'][$current_question_ident]['response_text'] = $current_question_item_body;
+            //replace claroline tags
 			break;
-
-		case 'MATCHINTERACTION' :
-			{
-				$exercise_info['question'][$current_question_ident]['type'] = 'MATCHING';
-			}
+		case 'MATCHINTERACTION':
+			$exercise_info['question'][$current_question_ident]['type'] = 'MATCHING';
 			break;
-
 		case 'SIMPLEMATCHSET' :
-			{
-				if (!isset ($current_match_set)) {
-					$current_match_set = 1;
-				} else {
-					$current_match_set++;
-				}
-				$exercise_info['question'][$current_question_ident]['answer'][$current_match_set] = array ();
-			}
+            if (!isset ($current_match_set)) {
+                $current_match_set = 1;
+            } else {
+                $current_match_set++;
+            }
+            $exercise_info['question'][$current_question_ident]['answer'][$current_match_set] = array ();
 			break;
-
-		case 'SIMPLEASSOCIABLECHOICE' :
-			{
-				$currentAssociableChoice = $attributes['IDENTIFIER'];
-			}
+		case 'SIMPLEASSOCIABLECHOICE':
+            $currentAssociableChoice = $attributes['IDENTIFIER'];
 			break;
-
 			//retrieve answers id for MCUA and MCMA questions
-
-		case 'SIMPLECHOICE' :
-			
+		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' :
-			{
-				if ($parent_element == "MAPPING") {
-					$answer_id = $attributes['MAPKEY'];
-
-					if (!isset ($exercise_info['question'][$current_question_ident]['weighting'])) {
-						$exercise_info['question'][$current_question_ident]['weighting'] = array ();
-					}
-					$exercise_info['question'][$current_question_ident]['weighting'][$answer_id] = $attributes['MAPPEDVALUE'];
-				}
-			}
+		case 'MAPENTRY':
+            if ($parent_element == "MAPPING") {
+                $answer_id = $attributes['MAPKEY'];
+
+                if (!isset ($exercise_info['question'][$current_question_ident]['weighting'])) {
+                    $exercise_info['question'][$current_question_ident]['weighting'] = array ();
+                }
+                $exercise_info['question'][$current_question_ident]['weighting'][$answer_id] = $attributes['MAPPEDVALUE'];
+            }
 			break;
-
-		case 'MAPPING' :
-			{
-				if (isset ($attributes['DEFAULTVALUE'])) {
-					$exercise_info['question'][$current_question_ident]['default_weighting'] = $attributes['DEFAULTVALUE'];
-				}
-			}
-
-		case 'ITEMBODY' :
-			{
-				$record_item_body = true;
-				$current_question_item_body = '';
-			}
+		case 'MAPPING':
+            if (isset ($attributes['DEFAULTVALUE'])) {
+                $exercise_info['question'][$current_question_ident]['default_weighting'] = $attributes['DEFAULTVALUE'];
+            }
+		case 'ITEMBODY':
+            $record_item_body = true;
+            $current_question_item_body = '';
 			break;
-
-		case 'IMG' :
-			{
-				$exercise_info['question'][$current_question_ident]['attached_file_url'] = $attributes['SRC'];
-			}
+		case 'IMG':
+            $exercise_info['question'][$current_question_ident]['attached_file_url'] = $attributes['SRC'];
 			break;
 	}
 }
@@ -480,15 +459,13 @@ function endElement($parser, $name) {
 	}
 
 	switch ($name) {
-		case 'ITEMBODY' :
-			{
-				$record_item_body = false;
-				if ($exercise_info['question'][$current_question_ident]['type'] == 'FIB') {
-					$exercise_info['question'][$current_question_ident]['response_text'] = $current_question_item_body;
-				} else {
-					$exercise_info['question'][$current_question_ident]['statement'] = $current_question_item_body;
-				}
-			}
+		case 'ITEMBODY':
+            $record_item_body = false;
+            if ($exercise_info['question'][$current_question_ident]['type'] == 'FIB') {
+                $exercise_info['question'][$current_question_ident]['response_text'] = $current_question_item_body;
+            } else {
+                $exercise_info['question'][$current_question_ident]['statement'] = $current_question_item_body;
+            }
 			break;
 	}
 	array_pop($element_pile);
@@ -524,70 +501,49 @@ 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);
-				}    		
+		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' :
-			{
-				if (!isset ($exercise_info['question'][$current_question_ident]['answer'][$current_answer_id]['feedback'])) {
-					$exercise_info['question'][$current_question_ident]['answer'][$current_answer_id]['feedback'] = trim($data);
-				} else {
-					$exercise_info['question'][$current_question_ident]['answer'][$current_answer_id]['feedback'] .= ' ' . trim($data);
-				}
-			}
+            if (!isset ($exercise_info['question'][$current_question_ident]['answer'][$current_answer_id]['feedback'])) {
+                $exercise_info['question'][$current_question_ident]['answer'][$current_answer_id]['feedback'] = trim($data);
+            } else {
+                $exercise_info['question'][$current_question_ident]['answer'][$current_answer_id]['feedback'] .= ' ' . trim($data);
+            }
 			break;
-
-		case 'SIMPLEASSOCIABLECHOICE' :
-			{
-				$exercise_info['question'][$current_question_ident]['answer'][$current_match_set][$currentAssociableChoice] = trim($data);
-			}
+		case 'SIMPLEASSOCIABLECHOICE':
+			$exercise_info['question'][$current_question_ident]['answer'][$current_match_set][$currentAssociableChoice] = trim($data);
 			break;
-
 		case 'VALUE' :
-			{
-				if ($parent_element == "CORRECTRESPONSE") {
-					if ($cardinality == "single") {
-						$exercise_info['question'][$current_question_ident]['correct_answers'][$current_answer_id] = $data;
-					} else {
-						$exercise_info['question'][$current_question_ident]['correct_answers'][] = $data;
-					}
-				}
-			}
+            if ($parent_element == "CORRECTRESPONSE") {
+                if ($cardinality == "single") {
+                    $exercise_info['question'][$current_question_ident]['correct_answers'][$current_answer_id] = $data;
+                } else {
+                    $exercise_info['question'][$current_question_ident]['correct_answers'][] = $data;
+                }
+            }
 			break;
 
 		case 'ITEMBODY' :
-			{
-				$current_question_item_body .= $data;
-
-			}
+            $current_question_item_body .= $data;
 			break;
-
 		case 'INLINECHOICE' :
-			{
-
-				// if this is the right answer, then we must replace the claroline tags in the FIB text bye the answer between "[" and "]" :
-
-				$answer_identifier = $exercise_info['question'][$current_question_ident]['correct_answers'][$current_answer_id];
-
-				if ($current_inlinechoice_id == $answer_identifier) {
-
-					$current_question_item_body = str_replace("**claroline_start**" . $current_answer_id . "**claroline_end**", "[" . $data . "]", $current_question_item_body);
-				} else // save wrong answers in an array
-					{
-					if (!isset ($exercise_info['question'][$current_question_ident]['wrong_answers'])) {
-						$exercise_info['question'][$current_question_ident]['wrong_answers'] = array ();
-					}
-					$exercise_info['question'][$current_question_ident]['wrong_answers'][] = $data;
-				}
-			}
+            // if this is the right answer, then we must replace the claroline tags in the FIB text bye the answer between "[" and "]" :
+            $answer_identifier = $exercise_info['question'][$current_question_ident]['correct_answers'][$current_answer_id];
+            if ($current_inlinechoice_id == $answer_identifier) {
+                $current_question_item_body = str_replace("**claroline_start**" . $current_answer_id . "**claroline_end**", "[" . $data . "]", $current_question_item_body);
+            } else {
+                if (!isset ($exercise_info['question'][$current_question_ident]['wrong_answers'])) {
+                    $exercise_info['question'][$current_question_ident]['wrong_answers'] = array ();
+                }
+                $exercise_info['question'][$current_question_ident]['wrong_answers'][] = $data;
+            }
 			break;
 	}
-}
+}

+ 84 - 168
main/exercice/export/qti2/qti2_classes.php

@@ -1,4 +1,4 @@
-<?php // $Id: $
+<?php
 /* For licensing terms, see /license.txt */
 /**
  * @author Claro Team <cvs@claroline.net>
@@ -8,14 +8,6 @@
 /**
  * Code
  */
-if ( count( get_included_files() ) == 1 ) die( '---' );
-
-if (!function_exists('mime_content_type')) {
-	require_once api_get_path(LIBRARY_PATH).'document.lib.php';
-	function mime_content_type($filename) {
-		return DocumentManager::file_get_mime_type((string)$filename);
-	}
-}
 
 require_once(api_get_path(SYS_CODE_PATH).'/exercice/answer.class.php');
 require_once(api_get_path(SYS_CODE_PATH).'/exercice/exercise.class.php');
@@ -39,42 +31,52 @@ class Ims2Question extends Question
 {
     /**
      * Include the correct answer class and create answer
+     * @return Answer
      */
-    function setAnswer()
+    public function setAnswer()
     {
-        switch($this->type)
-        {
-            case MCUA :
+        switch($this->type) {
+            case MCUA:
                 $answer = new ImsAnswerMultipleChoice($this->id);
-            	return $answer;
-            case MCMA :
+
+                return $answer;
+            case MCMA:
                 $answer = new ImsAnswerMultipleChoice($this->id);
-            	return $answer;
+
+                return $answer;
             case TF :
                 $answer = new ImsAnswerMultipleChoice($this->id);
-            	return $answer;
-            case FIB :
+
+                return $answer;
+            case FIB:
                 $answer = new ImsAnswerFillInBlanks($this->id);
-            	return $answer;
-            case MATCHING :
+
+                return $answer;
+            case MATCHING:
                 $answer = new ImsAnswerMatching($this->id);
-            	return $answer;
-            case FREE_ANSWER :
-            	$answer = new ImsAnswerFree($this->id);
-            	return $answer;
-            case HOT_SPOT :
-            	$answer = new ImsAnswerHotspot($this->id);
-            	return $answer;
-            default :
+
+                return $answer;
+            case FREE_ANSWER:
+                $answer = new ImsAnswerFree($this->id);
+
+                return $answer;
+            case HOT_SPOT:
+                $answer = new ImsAnswerHotspot($this->id);
+
+                return $answer;
+            default:
                 $answer = null;
                 break;
         }
+
         return $answer;
     }
+
     function createAnswersForm($form)
     {
     	return true;
     }
+
     function processAnswersCreation($form)
     {
     	return true;
@@ -90,24 +92,26 @@ class ImsAnswerMultipleChoice extends Answer
      * Return the XML flow for the possible answers.
      *
      */
-    function imsExportResponses($questionIdent, $questionStatment)
+    public function imsExportResponses($questionIdent, $questionStatment)
     {
+        // @todo getAnswersList() converts the answers using api_html_entity_decode()
 		$this->answerList = $this->getAnswersList(true);
         $out  = '    <choiceInteraction responseIdentifier="' . $questionIdent . '" >' . "\n";
-        $out .= '      <prompt> ' . $questionStatment . ' </prompt>'. "\n";
+        $out .= '      <prompt><![CDATA['.formatExerciseQtiTitle($questionStatment) . ']]></prompt>'. "\n";
 		if (is_array($this->answerList)) {
 	        foreach ($this->answerList as $current_answer) {
-	        	
-	        	
-	            $out .= '      <simpleChoice identifier="answer_' . $current_answer['id'] . '" fixed="false">' . $current_answer['answer'];
-	            if (isset($current_answer['comment']) && $current_answer['comment'] != '')
-	            {
-	                $out .= '<feedbackInline identifier="answer_' . $current_answer['id'] . '">' . $current_answer['comment'] . '</feedbackInline>';
+	            $out .= '<simpleChoice identifier="answer_' . $current_answer['id'] . '" fixed="false">
+                         <![CDATA['.formatExerciseQtiTitle($current_answer['answer']).']]>';
+	            if (isset($current_answer['comment']) && $current_answer['comment'] != '') {
+	                $out .= '<feedbackInline identifier="answer_' . $current_answer['id'] . '">
+	                         <![CDATA['.formatExerciseQtiTitle($current_answer['comment']).']]>
+	                         </feedbackInline>';
 	            }
 	            $out .= '</simpleChoice>'. "\n";
 	        }
 		}
         $out .= '    </choiceInteraction>'. "\n";
+
         return $out;
     }
 
@@ -115,7 +119,7 @@ class ImsAnswerMultipleChoice extends Answer
      * Return the XML flow of answer ResponsesDeclaration
      *
      */
-    function imsExportResponsesDeclaration($questionIdent)
+    public function imsExportResponsesDeclaration($questionIdent)
     {
 		$this->answerList = $this->getAnswersList(true);
 		$type = $this->getQuestionType();
@@ -123,13 +127,12 @@ class ImsAnswerMultipleChoice extends Answer
 
         $out = '  <responseDeclaration identifier="' . $questionIdent . '" cardinality="' . $cardinality . '" baseType="identifier">' . "\n";
 
-        //Match the correct answers
+        // Match the correct answers.
 
         $out .= '    <correctResponse>'. "\n";
 		if (is_array($this->answerList)) {
 	        foreach($this->answerList as $current_answer) {
-	            if ($current_answer['correct'])
-	            {
+	            if ($current_answer['correct']) {
 	                $out .= '      <value>answer_'. $current_answer['id'] .'</value>'. "\n";
 	            }
 	        }
@@ -140,16 +143,13 @@ class ImsAnswerMultipleChoice extends Answer
 
         $out .= '    <mapping>'. "\n";
 		if (is_array($this->answerList)) {
-	        foreach($this->answerList as $current_answer)
-	        {
-	            if (isset($current_answer['grade']))
-	            {
-	                $out .= '      <mapEntry mapKey="answer_'. $current_answer['id'] .'" mappedValue="'.$current_answer['grade'].'" />'. "\n";
+	        foreach($this->answerList as $current_answer) {
+	            if (isset($current_answer['grade'])) {
+	                $out .= ' <mapEntry mapKey="answer_'. $current_answer['id'] .'" mappedValue="'.$current_answer['grade'].'" />'. "\n";
 	            }
 	        }
 		}
         $out .= '    </mapping>'. "\n";
-
         $out .= '  </responseDeclaration>'. "\n";
 
         return $out;
@@ -167,114 +167,41 @@ class ImsAnswerFillInBlanks extends Answer
      *
      *
      */
-    function imsExportResponses($questionIdent, $questionStatment)
+    public function imsExportResponses($questionIdent, $questionStatment)
     {
-        global $charset;
 		$this->answerList = $this->getAnswersList(true);
-
-        //switch ($this->type)
-        //{
-        //    case TEXTFIELD_FILL :
-        //    {
-        		$text = '';
-                $text .= $this->answerText;
-				if (is_array($this->answerList)) {
-	                foreach ($this->answerList as $key=>$answer) {
-	                	$key = $answer['id'];
-	                	$answer = $answer['answer'];
-	                	$len = api_strlen($answer);
-	                    $text = str_replace('['.$answer.']','<textEntryInteraction responseIdentifier="fill_'.$key.'" expectedLength="'.api_strlen($answer).'"/>', $text);
-	                }
-				}
-                $out = $text;
-        //    }
-        //    break;
-
-            /*
-            case LISTBOX_FILL :
-            {
-                $text = $this->answerText;
-
-                foreach ($this->answerList as $answerKey=>$answer)
-                {
-
-                    //build inlinechoice list
-
-                    $inlineChoiceList = '';
-
-                    //1-start interaction tag
-
-                    $inlineChoiceList .= '<inlineChoiceInteraction responseIdentifier="fill_'.$answerKey.'" >'. "\n";
-
-                    //2- add wrong answer array
-
-                    foreach ($this->wrongAnswerList as $choiceKey=>$wrongAnswer)
-                    {
-                        $inlineChoiceList .= '  <inlineChoice identifier="choice_w_'.$answerKey.'_'.$choiceKey.'">'.$wrongAnswer.'</inlineChoice>'. "\n";
-                    }
-
-                    //3- add correct answers array
-                    foreach ($this->answerList as $choiceKey=>$correctAnswer)
-                    {
-                        $inlineChoiceList .= '  <inlineChoice identifier="choice_c_'.$answerKey.'_'.$choiceKey.'">'.$correctAnswer.'</inlineChoice>'. "\n";
-                    }
-
-                    //4- finish interaction tag
-
-                    $inlineChoiceList .= '</inlineChoiceInteraction>';
-
-                    $text = str_replace('['.$answer.']',$inlineChoiceList, $text);
-                }
-                $out = $text;
-
+        $text = '';
+        $text .= $this->answerText;
+        if (is_array($this->answerList)) {
+            foreach ($this->answerList as $key=>$answer) {
+                $key = $answer['id'];
+                $answer = $answer['answer'];
+                $len = api_strlen($answer);
+                $text = str_replace('['.$answer.']','<textEntryInteraction responseIdentifier="fill_'.$key.'" expectedLength="'.api_strlen($answer).'"/>', $text);
             }
-            break;
-            */
-        //}
+        }
+        $out = $text;
 
         return $out;
-
     }
 
     /**
      *
      */
-    function imsExportResponsesDeclaration($questionIdent)
+    public function imsExportResponsesDeclaration($questionIdent)
     {
-
 		$this->answerList = $this->getAnswersList(true);
 		$this->gradeList = $this->getGradesList();
         $out = '';
 		if (is_array($this->answerList)) {
-	        foreach ($this->answerList as $answerKey=>$answer) {
-	        	
+	        foreach ($this->answerList as $answer) {
 	        	$answerKey = $answer['id'];
 	        	$answer = $answer['answer'];
 	            $out .= '  <responseDeclaration identifier="fill_' . $answerKey . '" cardinality="single" baseType="identifier">' . "\n";
 	            $out .= '    <correctResponse>'. "\n";
-
-	            //if ($this->type==TEXTFIELD_FILL)
-	            //{
-	                $out .= '      <value>'.$answer.'</value>'. "\n";
-	            //}
-	            /*
-	            else
-	            {
-	                //find correct answer key to apply in manifest and output it
-
-	                foreach ($this->answerList as $choiceKey=>$correctAnswer)
-	                {
-	                    if ($correctAnswer==$answer)
-	                    {
-	                        $out .= '      <value>choice_c_'.$answerKey.'_'.$choiceKey.'</value>'. "\n";
-	                    }
-	                }
-	            }
-	            */
+                $out .= '      <value><![CDATA['.formatExerciseQtiTitle($answer).']]></value>'. "\n";
 	            $out .= '    </correctResponse>'. "\n";
-
-	            if (isset($this->gradeList[$answerKey]))
-	            {
+	            if (isset($this->gradeList[$answerKey])) {
 	                $out .= '    <mapping>'. "\n";
 	                $out .= '      <mapEntry mapKey="'.$answer.'" mappedValue="'.$this->gradeList[$answerKey].'"/>'. "\n";
 	                $out .= '    </mapping>'. "\n";
@@ -297,7 +224,7 @@ class ImsAnswerMatching extends Answer
     /**
      * Export the question part as a matrix-choice, with only one possible answer per line.
      */
-    function imsExportResponses($questionIdent, $questionStatment)
+    public function imsExportResponses($questionIdent, $questionStatment)
     {
 		$this->answerList = $this->getAnswersList(true);
 		$maxAssociation = max(count($this->leftList), count($this->rightList));
@@ -311,9 +238,11 @@ class ImsAnswerMatching extends Answer
 
         $out .= '  <simpleMatchSet>'. "\n";
 		if (is_array($this->leftList)) {
-	        foreach ($this->leftList as $leftKey=>$leftElement)
-	        {
-	            $out .= '    <simpleAssociableChoice identifier="left_'.$leftKey.'" >'. $leftElement['answer'] .'</simpleAssociableChoice>'. "\n";
+	        foreach ($this->leftList as $leftKey=>$leftElement) {
+	            $out .= '
+	            <simpleAssociableChoice identifier="left_'.$leftKey.'" >
+	                <![CDATA['.formatExerciseQtiTitle($leftElement['answer']).']]>
+	            </simpleAssociableChoice>'. "\n";
 	        }
     	}
 
@@ -326,14 +255,14 @@ class ImsAnswerMatching extends Answer
         $i = 0;
 
 		if (is_array($this->rightList)) {
-	        foreach($this->rightList as $rightKey=>$rightElement)
-	        {
-	            $out .= '    <simpleAssociableChoice identifier="right_'.$i.'" >'. $rightElement['answer'] .'</simpleAssociableChoice>'. "\n";
+	        foreach($this->rightList as $rightKey=>$rightElement) {
+	            $out .= '<simpleAssociableChoice identifier="right_'.$i.'" >
+	                    <![CDATA['.formatExerciseQtiTitle($rightElement['answer']).']]>
+	                    </simpleAssociableChoice>'. "\n";
 	            $i++;
 	        }
 		}
         $out .= '  </simpleMatchSet>'. "\n";
-
         $out .= '</matchInteraction>'. "\n";
 
         return $out;
@@ -342,7 +271,7 @@ class ImsAnswerMatching extends Answer
     /**
      *
      */
-    function imsExportResponsesDeclaration($questionIdent)
+    public function imsExportResponsesDeclaration($questionIdent)
     {
 		$this->answerList = $this->getAnswersList(true);
         $out =  '  <responseDeclaration identifier="' . $questionIdent . '" cardinality="single" baseType="identifier">' . "\n";
@@ -350,13 +279,10 @@ class ImsAnswerMatching extends Answer
 
         $gradeArray = array();
 		if (is_array($this->leftList)) {
-	        foreach ($this->leftList as $leftKey=>$leftElement)
-	        {
+	        foreach ($this->leftList as $leftKey=>$leftElement) {
 	            $i=0;
-	            foreach ($this->rightList as $rightKey=>$rightElement)
-	            {
-	                if( ($leftElement['match'] == $rightElement['code']))
-	                {
+	            foreach ($this->rightList as $rightKey=>$rightElement) {
+	                if (($leftElement['match'] == $rightElement['code'])) {
 	                    $out .= '      <value>left_' . $leftKey . ' right_'.$i.'</value>'. "\n";
 
 	                    $gradeArray['left_' . $leftKey . ' right_'.$i] = $leftElement['grade'];
@@ -368,8 +294,7 @@ class ImsAnswerMatching extends Answer
         $out .= '    </correctResponse>'. "\n";
         $out .= '    <mapping>' . "\n";
         if (is_array($gradeArray)) {
-	        foreach ($gradeArray as $gradeKey=>$grade)
-	        {
+	        foreach ($gradeArray as $gradeKey=>$grade) {
 	            $out .= '          <mapEntry mapKey="'.$gradeKey.'" mappedValue="'.$grade.'"/>' . "\n";
 	        }
         }
@@ -378,7 +303,6 @@ class ImsAnswerMatching extends Answer
 
         return $out;
     }
-
 }
 
 /**
@@ -388,12 +312,11 @@ class ImsAnswerMatching extends Answer
 class ImsAnswerHotspot extends Answer
 {
     /**
-     * TODO update this to match hotspots instead of copying matching
+     * TODO update this to match hot spots instead of copying matching
      * Export the question part as a matrix-choice, with only one possible answer per line.
      */
-   	function imsExportResponses($questionIdent, $questionStatment, $questionDesc='', $questionMedia='')
+    public function imsExportResponses($questionIdent, $questionStatment, $questionDesc='', $questionMedia='')
     {
-        global $charset;
 		$this->answerList = $this->getAnswersList(true);
 		$questionMedia = api_get_path(WEB_COURSE_PATH).api_get_course_path().'/document/images/'.$questionMedia;
 		$mimetype = mime_content_type($questionMedia);
@@ -406,8 +329,7 @@ class ImsAnswerHotspot extends Answer
 		$text .= '        <prompt>'.$questionDesc.'</prompt>'."\n";
 		$text .= '        <object type="'.$mimetype.'" width="250" height="230" data="'.$questionMedia.'">-</object>'."\n";
         if (is_array($this->answerList)) {
-	        foreach ($this->answerList as $key=>$answer)
-	        {
+	        foreach ($this->answerList as $key=>$answer) {
 	        	$key = $answer['id'];
 	        	$answerTxt = $answer['answer'];
 	        	$len = api_strlen($answerTxt);
@@ -442,17 +364,14 @@ class ImsAnswerHotspot extends Answer
         $text .= '      </graphicOrderInteraction>'."\n";
         $out = $text;
 
-
         return $out;
-
     }
 
     /**
      *
      */
-    function imsExportResponsesDeclaration($questionIdent)
+    public function imsExportResponsesDeclaration($questionIdent)
     {
-
 		$this->answerList = $this->getAnswersList(true);
 		$this->gradeList = $this->getGradesList();
         $out = '';
@@ -460,12 +379,10 @@ class ImsAnswerHotspot extends Answer
         $out .= '    <correctResponse>'. "\n";
 
 		if (is_array($this->answerList)) {
-	        foreach ($this->answerList as $answerKey=>$answer)
-	        {
+	        foreach ($this->answerList as $answerKey=>$answer)  {
 	        	$answerKey = $answer['id'];
 	        	$answer = $answer['answer'];
-	            $out .= '      <value>'.$answerKey.'</value>'. "\n";
-
+	            $out .= '<value><![CDATA['.formatExerciseQtiTitle($answerKey).']]></value>';
 	        }
 		}
         $out .= '    </correctResponse>'. "\n";
@@ -485,16 +402,15 @@ class ImsAnswerFree extends Answer
      * TODO implement
      * Export the question part as a matrix-choice, with only one possible answer per line.
      */
-   	function imsExportResponses($questionIdent, $questionStatment, $questionDesc='', $questionMedia='')
+    public function imsExportResponses($questionIdent, $questionStatment, $questionDesc='', $questionMedia='')
 	{
 		return '';
 	}
     /**
      *
      */
-    function imsExportResponsesDeclaration($questionIdent)
+    public function imsExportResponsesDeclaration($questionIdent)
     {
     	return '';
     }
 }
-?>

+ 87 - 78
main/exercice/export/qti2/qti2_export.php

@@ -1,4 +1,4 @@
-<?php // $Id: $
+<?php
 /* For licensing terms, see /license.txt */
 /**
  * @author Claro Team <cvs@claroline.net>
@@ -8,7 +8,6 @@
 /**
  * Code
  */
-if ( count( get_included_files() ) == 1 ) die( '---' );
 require dirname(__FILE__) . '/qti2_classes.php';
 /**
  * Classes
@@ -26,19 +25,18 @@ require dirname(__FILE__) . '/qti2_classes.php';
  */
 class ImsAssessmentItem
 {
-    var $question;
-    var $question_ident;
-    var $answer;
+    public $question;
+    public $question_ident;
+    public $answer;
 
     /**
      * Constructor.
      *
-     * @param $question The Question object we want to export.
+     * @param $question Ims2Question object we want to export.
      */
      function ImsAssessmentItem($question)
      {
         $this->question = $question;
-        //$this->answer = new Answer($question->id);
         $this->answer = $this->question->setAnswer();
         $this->questionIdent = "QST_" . $question->id ;
      }
@@ -51,20 +49,13 @@ class ImsAssessmentItem
       */
       function start_item()
       {
-        /*
-        return '<assessmentItem xmlns="http://www.imsglobal.org/xsd/imsqti_v2p0"
-                    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-                    xsi:schemaLocation="http://www.imsglobal.org/xsd/imsqti_v2p0 imsqti_v2p0.xsd"
-                    identifier="'.$this->questionIdent.'"
-                    title="'.htmlspecialchars($this->question->selectTitle()).'">'."\n";
-         */
         $string = '<assessmentItem xmlns="http://www.imsglobal.org/xsd/imsqti_v2p1"
                     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                     xsi:schemaLocation="http://www.imsglobal.org/xsd/imsqti_v2p1 imsqti_v2p1.xsd"
                     identifier="'.$this->questionIdent.'"
-                    title="'.htmlspecialchars($this->question->selectTitle()).'">'."\n";
-        return $string;
+                    title="'.htmlspecialchars(formatExerciseQtiTitle($this->question->selectTitle())).'">'."\n";
 
+        return $string;
       }
 
       /**
@@ -101,11 +92,9 @@ class ImsAssessmentItem
 
       function add_response_processing()
       {
-          //return '  <responseProcessing template="http://www.imsglobal.org/question/qti_v2p0/rptemplates/map_response"/>' . "\n";
           return '  <responseProcessing template="http://www.imsglobal.org/question/qti_v2p1/rptemplates/map_correct"/>' . "\n";
       }
 
-
      /**
       * Export the question as an IMS/QTI Item.
       *
@@ -116,24 +105,31 @@ class ImsAssessmentItem
       */
      function export($standalone = false)
      {
-        global $charset;
         $head = $foot = "";
 
-        if( $standalone )
-        {
-            $head = '<?xml version="1.0" encoding="'.$charset.'" standalone="no"?>' . "\n";
+        if ($standalone) {
+            $head = '<?xml version="1.0" encoding="UTF-8" standalone="no"?>' . "\n";
         }
-	//TODO understand why answer might be a non-object sometimes
-	if (!is_object($this->answer)) { return $head; }
+        //TODO understand why answer might be a non-object sometimes
+        if (!is_object($this->answer)) {
+            return $head;
+        }
+
         $res = $head
-               . $this->start_item()
-                 .$this->answer->imsExportResponsesDeclaration($this->questionIdent)
-                 . $this->start_item_body()
-                 . $this->answer->imsExportResponses($this->questionIdent, $this->question->question, $this->question->description, $this->question->picture)
-                 . $this->end_item_body()
-               . $this->add_response_processing()
-               . $this->end_item()
-             . $foot;
+            .$this->start_item()
+            .$this->answer->imsExportResponsesDeclaration($this->questionIdent)
+            .$this->start_item_body()
+            .$this->answer->imsExportResponses(
+                $this->questionIdent,
+                $this->question->question,
+                $this->question->description,
+                $this->question->picture
+            )
+            .$this->end_item_body()
+            .$this->add_response_processing()
+            .$this->end_item()
+            .$foot;
+
         return $res;
      }
 }
@@ -168,7 +164,7 @@ class ImsSection
 
     function start_section()
     {
-        $out = '<section ident="EXO_' . $this->exercise->selectId() . '" title="' . $this->exercise->selectTitle() . '">' . "\n";
+        $out = '<section ident="EXO_' . $this->exercise->selectId() . '" title="' .cleanAttribute(formatExerciseQtiDescription($this->exercise->selectTitle())) . '">' . "\n";
         return $out;
     }
 
@@ -185,9 +181,7 @@ class ImsSection
             $minutes = floor($max_time / 60);
             $seconds = $max_time % 60;
             return '<duration>PT' . $minutes . 'M' . $seconds . "S</duration>\n";
-        }
-        else
-        {
+        } else {
             return '';
         }
     }
@@ -199,7 +193,7 @@ class ImsSection
     function export_presentation()
     {
         $out = "<presentation_material><flow_mat><material>\n"
-             . "  <mattext><![CDATA[" . $this->exercise->selectDescription() . "]]></mattext>\n"
+             . "  <mattext><![CDATA[" . formatExerciseQtiDescription($this->exercise->selectDescription()) . "]]></mattext>\n"
              . "</material></flow_mat></presentation_material>\n";
         return $out;
     }
@@ -211,6 +205,7 @@ class ImsSection
      */
     function export_ordering()
     {
+
         $out = '';
         if ($n = $this->exercise->getShuffle()) {
             $out.= "<selection_ordering>"
@@ -219,9 +214,7 @@ class ImsSection
                  . "  </selection>\n"
                  . '  <order order_type="Random" />'
                  . "\n</selection_ordering>\n";
-        }
-        else
-        {
+        } else {
             $out.= '<selection_ordering sequence_type="Normal">' . "\n"
                  . "  <selection />\n"
                  . "</selection_ordering>\n";
@@ -237,8 +230,7 @@ class ImsSection
     function export_questions()
     {
         $out = "";
-        foreach ($this->exercise->selectQuestionList() as $q)
-        {
+        foreach ($this->exercise->selectQuestionList() as $q) {
         	$out .= export_question($q, false);
         }
         return $out;
@@ -253,11 +245,9 @@ class ImsSection
      */
     function export($standalone)
     {
-        global $charset;
-
         $head = $foot = "";
         if ($standalone) {
-            $head = '<?xml version = "1.0" encoding = "' . $charset . '" standalone = "no"?>' . "\n"
+            $head = '<?xml version = "1.0" encoding = "UTF-8" standalone = "no"?>' . "\n"
                   . '<!DOCTYPE questestinterop SYSTEM "ims_qtiasiv2p1.dtd">' . "\n"
                   . "<questestinterop>\n";
             $foot = "</questestinterop>\n";
@@ -289,6 +279,8 @@ class ImsSection
     Feedback identifier :: <Question identifier> + "_F_" + <Response Id from the DB>
 */
 /**
+ * Class ImsItem
+ *
  * An IMS/QTI item. It corresponds to a single question.
  * This class allows export from Claroline to IMS/QTI XML format.
  * It is not usable as-is, but must be subclassed, to support different kinds of questions.
@@ -297,13 +289,15 @@ class ImsSection
  *
  * warning: Attached files are NOT exported.
  * @author Amand Tihon <amand@alrj.org>
+ *
  * @package chamilo.exercise
  */
+
 class ImsItem
 {
-    var $question;
-    var $question_ident;
-    var $answer;
+    public $question;
+    public $question_ident;
+    public $answer;
 
     /**
      * Constructor.
@@ -327,7 +321,7 @@ class ImsItem
       */
       function start_item()
       {
-        return '<item title="' . htmlspecialchars($this->question->selectTitle()) . '" ident="' . $this->questionIdent . '">' . "\n";
+        return '<item title="' . cleanAttribute(formatExerciseQtiDescription($this->question->selectTitle())) . '" ident="' . $this->questionIdent . '">' . "\n";
       }
 
       /**
@@ -344,14 +338,14 @@ class ImsItem
       * Create the opening, with the question itself.
       *
       * This means it opens the <presentation> but doesn't close it, as this is the role of end_presentation().
-      * Inbetween, the export_responses from the subclass should have been called.
+      * In between, the export_responses from the subclass should have been called.
       *
       * @author Amand Tihon <amand@alrj.org>
       */
      function start_presentation()
      {
         return '<presentation label="' . $this->questionIdent . '"><flow>' . "\n"
-             . '<material><mattext><![CDATA[' . $this->question->selectDescription() . "]]></mattext></material>\n";
+             . '<material><mattext>' . formatExerciseQtiDescription($this->question->selectDescription()) . "</mattext></material>\n";
      }
 
      /**
@@ -384,7 +378,6 @@ class ImsItem
         return "</resprocessing>\n";
      }
 
-
      /**
       * Export the question as an IMS/QTI Item.
       *
@@ -399,8 +392,7 @@ class ImsItem
         global $charset;
         $head = $foot = "";
 
-        if( $standalone )
-        {
+        if ($standalone) {
             $head = '<?xml version = "1.0" encoding = "'.$charset.'" standalone = "no"?>' . "\n"
                   . '<!DOCTYPE questestinterop SYSTEM "ims_qtiasiv2p1.dtd">' . "\n"
                   . "<questestinterop>\n";
@@ -408,36 +400,30 @@ class ImsItem
         }
 
         return $head
-               . $this->start_item()
-                . $this->start_presentation()
-                    . $this->answer->imsExportResponses($this->questionIdent)
-                . $this->end_presentation()
-                . $this->start_processing()
-                    . $this->answer->imsExportProcessing($this->questionIdent)
-                . $this->end_processing()
-                . $this->answer->imsExportFeedback($this->questionIdent)
-               . $this->end_item()
-              . $foot;
+            . $this->start_item()
+            . $this->start_presentation()
+            . $this->answer->imsExportResponses($this->questionIdent)
+            . $this->end_presentation()
+            . $this->start_processing()
+            . $this->answer->imsExportProcessing($this->questionIdent)
+            . $this->end_processing()
+            . $this->answer->imsExportFeedback($this->questionIdent)
+            . $this->end_item()
+            . $foot;
      }
 }
 
-
-/*--------------------------------------------------------
-      Functions
-  --------------------------------------------------------*/
-
 /**
  * Send a complete exercise in IMS/QTI format, from its ID
  *
- * @param int $exerciseId The exercise to exporte
+ * @param int $exerciseId The exercise to export
  * @param boolean $standalone Wether it should include XML tag and DTD line.
  * @return The XML as a string, or an empty string if there's no exercise with given ID.
  */
-function export_exercise($exerciseId, $standalone=true)
+function export_exercise($exerciseId, $standalone = true)
 {
     $exercise = new Exercise();
-    if (! $exercise->read($exerciseId))
-    {
+    if (!$exercise->read($exerciseId)) {
         return '';
     }
     $ims = new ImsSection($exercise);
@@ -448,15 +434,14 @@ function export_exercise($exerciseId, $standalone=true)
 /**
  * Returns the XML flow corresponding to one question
  *
- * @param int The question ID
- * @param bool standalone (ie including XML tag, DTD declaration, etc)
+ * @param int $questionId
+ * @param bool $standalone (ie including XML tag, DTD declaration, etc)
  */
-function export_question($questionId, $standalone=true)
+function export_question($questionId, $standalone = true)
 {
     $question = new Ims2Question();
     $qst = $question->read($questionId);
-    if( !$qst or $qst->type == FREE_ANSWER)
-    {
+    if (!$qst or $qst->type == FREE_ANSWER) {
         return '';
     }
     $question->id = $qst->id;
@@ -470,3 +455,27 @@ function export_question($questionId, $standalone=true)
 
     return $ims->export($standalone);
 }
+
+/**
+ * Clean text like a description
+ **/
+function formatExerciseQtiDescription($text)
+{
+    $entities = api_html_entity_decode($text);
+    return htmlspecialchars($entities);
+}
+
+/**
+ * Clean titles
+ * @param $text
+ * @return string
+ */
+function formatExerciseQtiTitle($text)
+{
+    return htmlspecialchars($text);
+}
+
+function cleanAttribute($text)
+{
+    return $text;
+}

+ 8 - 4
main/exercice/fill_blanks.class.php

@@ -101,6 +101,7 @@ class FillBlanks extends Question
                 if (firstTime) {
                     field = document.getElementById("answer");
                     var answer = field.value;
+                    
                 } else {
                     var oEditor = FCKeditorAPI.GetInstance("answer");
                     //var answer =  oEditor.GetXHTML(true);
@@ -109,15 +110,13 @@ class FillBlanks extends Question
 
                 var blanks = answer.match(/\[[^\]]*\]/g);
                 var fields = "<div class=\"control-group\"><label class=\"control-label\">'.get_lang('Weighting').'</label><div class=\"controls\"><table>";
-
                 if (blanks!=null) {
                     for (i=0 ; i<blanks.length ; i++){
                         if (document.getElementById("weighting["+i+"]"))
                             value = document.getElementById("weighting["+i+"]").value;
                         else
                             value = "10";
-                        fields += "<tr><td>"+blanks[i]+"</td><td><input style=\"margin-left: 0em;\" size=\"5\" value=\""+value+"\" type=\"text\" id=\"weighting["+i+"]\" name=\"weighting["+i+"]\" /></td></tr>";
-
+                        fields += "<tr><td><label>"+blanks[i]+"</label></td><td><input style=\"margin-left: 0em;\" size=\"5\" value=\""+value+"\" type=\"text\" id=\"weighting["+i+"]\" name=\"weighting["+i+"]\" /></td></tr>";
                     }
                 }
                 document.getElementById("blanks_weighting").innerHTML = fields + "</table></div></div>";
@@ -176,8 +175,13 @@ class FillBlanks extends Question
 		}
 
 		if ($nb>0) {
-			$answer .= '::';
+		  	$answer .= '::';
 			for($i=0 ; $i<$nb ; ++$i) {
+			        $blankItem = $blanks[0][$i];
+                               $replace = array("[", "]");
+                               $newBlankItem = str_replace($replace, "", $blankItem);
+                               $newBlankItem = "[".trim($newBlankItem)."]";
+                               $answer = str_replace($blankItem, $newBlankItem, $answer);
 				$answer .= $form->getSubmitValue('weighting['.$i.']').',';
 				$this -> weighting += $form->getSubmitValue('weighting['.$i.']');
 			}

+ 1 - 0
main/exercice/multiple_answer_true_false.class.php

@@ -70,6 +70,7 @@ class MultipleAnswerTrueFalse extends Question {
         $form -> addElement ('label', get_lang('Answers').'<br /> <img src="../img/fill_field.png">', $html);
 
 		$correct = 0;
+        $answer = null;
 		if (!empty($this -> id)) {
 			$answer = new Answer($this -> id);
 			$answer->read();

+ 1 - 1
main/exercice/overview.php

@@ -98,7 +98,7 @@ if (isset($exercise_stat_info['exe_id'])) {
 }
 
 //1. Check if this is a new attempt or a previous
-$countNotFinished = $exercise_stat_info['num_exe'];
+$countNotFinished = isset($exercise_stat_info['num_exe']) ? $exercise_stat_info['num_exe'] : null;
 $label = get_lang('StartTest');
 if ($time_control && !empty($clock_expired_time) || !empty($attempt_list)) {
 	$label = get_lang('ContinueTest');

+ 29 - 13
main/exercice/qti2.php

@@ -30,23 +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 +64,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,21 +75,26 @@ 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;
         }
 	}
 }
 
-// display header
+// Display header
 Display::display_header(get_lang('ImportQtiQuiz'), 'Exercises');
 
 // import file
@@ -92,4 +108,4 @@ if ((api_is_allowed_to_edit(null, true))) {
 ch_qti2_display_form();
 
 // display the footer
-Display::display_footer();
+Display::display_footer();

+ 132 - 117
main/exercice/question.class.php

@@ -45,47 +45,47 @@ define('FIB',				3);
  */
 abstract class Question
 {
-	public $id;
-	public $question;
-	public $description;
-	public $weighting;
-	public $position;
-	public $type;
-	public $level;
-	public $picture;
-	public $exerciseList;  // array with the list of exercises which this question is in
+    public $id;
+    public $question;
+    public $description;
+    public $weighting;
+    public $position;
+    public $type;
+    public $level;
+    public $picture;
+    public $exerciseList;  // array with the list of exercises which this question is in
     public $category_list;
     public $parent_id;
-	public $category;
-	public $isContent;
+    public $category;
+    public $isContent;
     public $course;
-	public static $typePicture = 'new_question.png';
-	public static $explanationLangVar = '';
+    public static $typePicture = 'new_question.png';
+    public static $explanationLangVar = '';
     public $question_table_class = 'table table-striped';
-	public static $questionTypes =
-        array(
-            UNIQUE_ANSWER => 				array('unique_answer.class.php' , 	'UniqueAnswer'),
-            MULTIPLE_ANSWER => 				array('multiple_answer.class.php' , 'MultipleAnswer'),
-            FILL_IN_BLANKS => 				array('fill_blanks.class.php' , 	'FillBlanks'),
-            MATCHING => 					array('matching.class.php' , 		'Matching'),
-            FREE_ANSWER => 					array('freeanswer.class.php' , 		'FreeAnswer'),
-            ORAL_EXPRESSION => 				array('oral_expression.class.php' , 'OralExpression'),
-            HOT_SPOT => 					array('hotspot.class.php' , 		'HotSpot'),
-            HOT_SPOT_DELINEATION =>         array('hotspot.class.php' , 'HotspotDelineation'),
-            MULTIPLE_ANSWER_COMBINATION =>	array('multiple_answer_combination.class.php', 'MultipleAnswerCombination'),
-            UNIQUE_ANSWER_NO_OPTION =>      array('unique_answer_no_option.class.php',   'UniqueAnswerNoOption'),
-            MULTIPLE_ANSWER_TRUE_FALSE =>   array('multiple_answer_true_false.class.php', 'MultipleAnswerTrueFalse'),
-            MULTIPLE_ANSWER_COMBINATION_TRUE_FALSE =>   array('multiple_answer_combination_true_false.class.php', 'MultipleAnswerCombinationTrueFalse'),
-            GLOBAL_MULTIPLE_ANSWER =>		array('global_multiple_answer.class.php' , 'GlobalMultipleAnswer'),
-            //MEDIA_QUESTION =>               array('media_question.class.php' , 'MediaQuestion')
-        );
+    public static $questionTypes = array(
+        UNIQUE_ANSWER => 				array('unique_answer.class.php' , 	'UniqueAnswer'),
+        MULTIPLE_ANSWER => 				array('multiple_answer.class.php' , 'MultipleAnswer'),
+        FILL_IN_BLANKS => 				array('fill_blanks.class.php' , 	'FillBlanks'),
+        MATCHING => 					array('matching.class.php' , 		'Matching'),
+        FREE_ANSWER => 					array('freeanswer.class.php' , 		'FreeAnswer'),
+        ORAL_EXPRESSION => 				array('oral_expression.class.php' , 'OralExpression'),
+        HOT_SPOT => 					array('hotspot.class.php' , 		'HotSpot'),
+        HOT_SPOT_DELINEATION =>         array('hotspot.class.php' , 'HotspotDelineation'),
+        MULTIPLE_ANSWER_COMBINATION =>	array('multiple_answer_combination.class.php', 'MultipleAnswerCombination'),
+        UNIQUE_ANSWER_NO_OPTION =>      array('unique_answer_no_option.class.php',   'UniqueAnswerNoOption'),
+        MULTIPLE_ANSWER_TRUE_FALSE =>   array('multiple_answer_true_false.class.php', 'MultipleAnswerTrueFalse'),
+        MULTIPLE_ANSWER_COMBINATION_TRUE_FALSE =>   array('multiple_answer_combination_true_false.class.php', 'MultipleAnswerCombinationTrueFalse'),
+        GLOBAL_MULTIPLE_ANSWER =>		array('global_multiple_answer.class.php' , 'GlobalMultipleAnswer'),
+        //MEDIA_QUESTION =>               array('media_question.class.php' , 'MediaQuestion')
+    );
 
 	/**
 	 * constructor of the class
 	 *
-	 * @author - Olivier Brouckaert
+	 * @author Olivier Brouckaert
 	 */
-	public function Question() {
+	public function Question()
+    {
 		$this->id=0;
 		$this->question='';
 		$this->description='';
@@ -110,11 +110,12 @@ abstract class Question
 	}
 
 	/**
-	 * Reads question informations from the data base
+	 * Reads question information from the data base
 	 *
-	 * @author - Olivier Brouckaert
-	 * @param - integer $id - question ID
-	 * @return - boolean - true if question exists, otherwise false
+	 * @author Olivier Brouckaert
+	 * @param integer $id - question ID
+     *
+	 * @return Question
 	 */
 	static function read($id, $course_id = null) {
         $id = intval($id);
@@ -176,7 +177,7 @@ abstract class Question
 	/**
 	 * returns the question ID
 	 *
-	 * @author - Olivier Brouckaert
+	 * @author Olivier Brouckaert
 	 * @return - integer - question ID
 	 */
 	function selectId() {
@@ -186,8 +187,8 @@ abstract class Question
 	/**
 	 * returns the question title
 	 *
-	 * @author - Olivier Brouckaert
-	 * @return - string - question title
+	 * @author Olivier Brouckaert
+	 * @return string - question title
 	 */
 	function selectTitle() {
 		return $this->question;
@@ -196,8 +197,8 @@ abstract class Question
 	/**
 	 * returns the question description
 	 *
-	 * @author - Olivier Brouckaert
-	 * @return - string - question description
+	 * @author Olivier Brouckaert
+	 * @return string - question description
 	 */
 	function selectDescription() {
 		$this->description=text_filter($this->description);
@@ -207,8 +208,8 @@ abstract class Question
 	/**
 	 * returns the question weighting
 	 *
-	 * @author - Olivier Brouckaert
-	 * @return - integer - question weighting
+	 * @author Olivier Brouckaert
+	 * @return integer - question weighting
 	 */
 	function selectWeighting()
 	{
@@ -218,8 +219,8 @@ abstract class Question
 	/**
 	 * returns the question position
 	 *
-	 * @author - Olivier Brouckaert
-	 * @return - integer - question position
+	 * @author Olivier Brouckaert
+	 * @return integer - question position
 	 */
 	function selectPosition() {
 		return $this->position;
@@ -228,8 +229,8 @@ abstract class Question
 	/**
 	 * returns the answer type
 	 *
-	 * @author - Olivier Brouckaert
-	 * @return - integer - answer type
+	 * @author Olivier Brouckaert
+	 * @return integer - answer type
 	 */
 	function selectType() {
 		return $this->type;
@@ -238,8 +239,8 @@ abstract class Question
 	/**
 	 * returns the level of the question
 	 *
-	 * @author - Nicolas Raynaud
-	 * @return - integer - level of the question, 0 by default.
+	 * @author Nicolas Raynaud
+	 * @return integer - level of the question, 0 by default.
 	 */
 	function selectLevel() {
 		return $this->level;
@@ -248,8 +249,8 @@ abstract class Question
 	/**
 	 * returns the picture name
 	 *
-	 * @author - Olivier Brouckaert
-	 * @return - string - picture name
+	 * @author Olivier Brouckaert
+	 * @return string - picture name
 	 */
 	function selectPicture() {
 		return $this->picture;
@@ -265,8 +266,8 @@ abstract class Question
 	/**
 	 * returns the array with the exercise ID list
 	 *
-	 * @author - Olivier Brouckaert
-	 * @return - array - list of exercise ID which the question is in
+	 * @author Olivier Brouckaert
+	 * @return array - list of exercise ID which the question is in
 	 */
 	function selectExerciseList() {
 		return $this->exerciseList;
@@ -275,8 +276,8 @@ abstract class Question
 	/**
 	 * returns the number of exercises which this question is in
 	 *
-	 * @author - Olivier Brouckaert
-	 * @return - integer - number of exercises
+	 * @author Olivier Brouckaert
+	 * @return integer - number of exercises
 	 */
 	function selectNbrExercises() {
 		return sizeof($this->exerciseList);
@@ -285,8 +286,8 @@ abstract class Question
 	/**
 	 * changes the question title
 	 *
-	 * @author - Olivier Brouckaert
-	 * @param - string $title - question title
+	 * @author Olivier Brouckaert
+	 * @param string $title - question title
 	 */
 	function updateTitle($title) {
 		$this->question=$title;
@@ -299,8 +300,8 @@ abstract class Question
 	/**
 	 * changes the question description
 	 *
-	 * @author - Olivier Brouckaert
-	 * @param - string $description - question description
+	 * @author Olivier Brouckaert
+	 * @param string $description - question description
 	 */
 	function updateDescription($description) {
 		$this->description=$description;
@@ -309,32 +310,32 @@ abstract class Question
 	/**
 	 * changes the question weighting
 	 *
-	 * @author - Olivier Brouckaert
-	 * @param - integer $weighting - question weighting
+	 * @author Olivier Brouckaert
+	 * @param integer $weighting - question weighting
 	 */
 	function updateWeighting($weighting) {
 		$this->weighting=$weighting;
 	}
 
 	/**
-	 * @author - Hubert Borderiou 12-10-2011
-	 * @param - array of category $in_category
+	 * @author Hubert Borderiou 12-10-2011
+	 * @param array of category $in_category
 	 */
 	function updateCategory($in_category) {
 		$this->category=$in_category;
 	}
 
 	/**
-	 * @author - Hubert Borderiou 12-10-2011
-	 * @param - interger $in_positive
+	 * @author Hubert Borderiou 12-10-2011
+	 * @param int $in_positive
 	 */
 	function updateScoreAlwaysPositive($in_positive) {
 		$this->scoreAlwaysPositive=$in_positive;
 	}
 
 	/**
-	 * @author - Hubert Borderiou 12-10-2011
-	 * @param - interger $in_positive
+	 * @author Hubert Borderiou 12-10-2011
+	 * @param int $in_positive
 	 */
 	function updateUncheckedMayScore($in_positive) {
 		$this->uncheckedMayScore=$in_positive;
@@ -347,7 +348,7 @@ abstract class Question
 	 * if category is empty, then question has no category then delete the category entry
      *
      * @param  - int $in_positive
-     * @author - Julio Montoya - Adding multiple cat support
+     * @author Julio Montoya - Adding multiple cat support
 	 */
 	function saveCategories($category_list) {
 
@@ -375,8 +376,8 @@ abstract class Question
 	}
 
 	/**
-	 * @author - Hubert Borderiou 12-10-2011
-	 * @param - interger $in_positive
+	 * @author Hubert Borderiou 12-10-2011
+	 * @param int $in_positive
 	 * in this version, a question can only have 1 category
 	 * if category is 0, then question has no category then delete the category entry
 	 */
@@ -418,8 +419,8 @@ abstract class Question
 	/**
 	 * changes the question position
 	 *
-	 * @author - Olivier Brouckaert
-	 * @param - integer $position - question position
+	 * @author Olivier Brouckaert
+	 * @param integer $position - question position
 	 */
 	function updatePosition($position) {
 		$this->position=$position;
@@ -428,8 +429,8 @@ abstract class Question
 	/**
 	 * changes the question level
 	 *
-	 * @author - Nicolas Raynaud
-	 * @param - integer $level - question level
+	 * @author Nicolas Raynaud
+	 * @param integer $level - question level
 	 */
 	function updateLevel($level) {
 		$this->level=$level;
@@ -439,8 +440,8 @@ abstract class Question
 	 * changes the answer type. If the user changes the type from "unique answer" to "multiple answers"
 	 * (or conversely) answers are not deleted, otherwise yes
 	 *
-	 * @author - Olivier Brouckaert
-	 * @param - integer $type - answer type
+	 * @author Olivier Brouckaert
+	 * @param integer $type - answer type
 	 */
 	function updateType($type) {
 		$TBL_REPONSES           = Database::get_course_table(TABLE_QUIZ_ANSWER);
@@ -465,10 +466,10 @@ abstract class Question
 	/**
 	 * adds a picture to the question
 	 *
-	 * @author - Olivier Brouckaert
-	 * @param - string $Picture - temporary path of the picture to upload
-	 * @param - string $PictureName - Name of the picture
-	 * @return - boolean - true if uploaded, otherwise false
+	 * @author Olivier Brouckaert
+	 * @param string $Picture - temporary path of the picture to upload
+	 * @param string $PictureName - Name of the picture
+	 * @return boolean - true if uploaded, otherwise false
 	 */
 	function uploadPicture($Picture, $PictureName, $picturePath = null) {
         if (empty($picturePath)) {
@@ -503,10 +504,10 @@ abstract class Question
 	/**
 	 * Resizes a picture || Warning!: can only be called after uploadPicture, or if picture is already available in object.
 	 *
-	 * @author - Toon Keppens
-	 * @param - string $Dimension - Resizing happens proportional according to given dimension: height|width|any
-	 * @param - integer $Max - Maximum size
-	 * @return - boolean - true if success, false if failed
+	 * @author Toon Keppens
+	 * @param string $Dimension - Resizing happens proportional according to given dimension: height|width|any
+	 * @param integer $Max - Maximum size
+	 * @return boolean - true if success, false if failed
 	 */
 	function resizePicture($Dimension, $Max) {
 		global $picturePath;
@@ -571,8 +572,8 @@ abstract class Question
 	/**
 	 * deletes the picture
 	 *
-	 * @author - Olivier Brouckaert
-	 * @return - boolean - true if removed, otherwise false
+	 * @author Olivier Brouckaert
+	 * @return boolean - true if removed, otherwise false
 	 */
 	function removePicture() {
 		global $picturePath;
@@ -591,9 +592,9 @@ abstract class Question
 	/**
 	 * Exports a picture to another question
 	 *
-	 * @author - Olivier Brouckaert
-	 * @param - integer $questionId - ID of the target question
-	 * @return - boolean - true if copied, otherwise false
+	 * @author Olivier Brouckaert
+	 * @param integer $questionId - ID of the target question
+	 * @return boolean - true if copied, otherwise false
 	 */
 	function exportPicture($questionId, $course_info) {
 		$course_id          = $course_info['real_id'];
@@ -628,9 +629,9 @@ abstract class Question
 	 * Temporary pictures are used when we don't want to save a picture right after a form submission.
 	 * For example, if we first show a confirmation box.
 	 *
-	 * @author - Olivier Brouckaert
-	 * @param - string $Picture - temporary path of the picture to move
-	 * @param - string $PictureName - Name of the picture
+	 * @author Olivier Brouckaert
+	 * @param string $Picture - temporary path of the picture to move
+	 * @param string $PictureName - Name of the picture
 	 */
 	function setTmpPicture($Picture,$PictureName) {
 		global $picturePath;
@@ -660,8 +661,8 @@ abstract class Question
 	 * Temporary pictures are used when we don't want to save a picture right after a form submission.
 	 * For example, if we first show a confirmation box.
 	 *
-	 * @author - Olivier Brouckaert
-	 * @return - boolean - true if moved, otherwise false
+	 * @author Olivier Brouckaert
+	 * @return boolean - true if moved, otherwise false
 	 */
 	function getTmpPicture() {
 		global $picturePath;
@@ -685,8 +686,8 @@ abstract class Question
 	 * updates the question in the data base
 	 * if an exercise ID is provided, we add that exercise ID into the exercise list
 	 *
-	 * @author - Olivier Brouckaert
-	 * @param - integer $exerciseId - exercise ID if saving in an exercise
+	 * @author Olivier Brouckaert
+	 * @param integer $exerciseId - exercise ID if saving in an exercise
 	 */
 	function save($exerciseId=0) {
 		$TBL_EXERCICE_QUESTION	= Database::get_course_table(TABLE_QUIZ_TEST_QUESTION);
@@ -910,9 +911,9 @@ abstract class Question
 	/**
 	 * adds an exercise into the exercise list
 	 *
-	 * @author - Olivier Brouckaert
-     * @param - integer $exerciseId - exercise ID
-     * @param - boolean $fromSave - comming from $this->save() or not
+	 * @author Olivier Brouckaert
+     * @param integer $exerciseId - exercise ID
+     * @param boolean $fromSave - comming from $this->save() or not
 	 */
 	function addToList($exerciseId, $fromSave = false) {
 		$TBL_EXERCICE_QUESTION = Database::get_course_table(TABLE_QUIZ_TEST_QUESTION);
@@ -938,9 +939,9 @@ abstract class Question
 	/**
 	 * removes an exercise from the exercise list
 	 *
-	 * @author - Olivier Brouckaert
-	 * @param - integer $exerciseId - exercise ID
-	 * @return - boolean - true if removed, otherwise false
+	 * @author Olivier Brouckaert
+	 * @param integer $exerciseId - exercise ID
+	 * @return boolean - true if removed, otherwise false
 	 */
 	function removeFromList($exerciseId) {
         $TBL_EXERCICE_QUESTION = Database::get_course_table(TABLE_QUIZ_TEST_QUESTION);
@@ -982,8 +983,8 @@ abstract class Question
 	 * the parameter tells if the question is removed from all exercises (value = 0),
 	 * or just from one exercise (value = exercise ID)
 	 *
-	 * @author - Olivier Brouckaert
-	 * @param - integer $deleteFromEx - exercise ID if the question is only removed from one exercise
+	 * @author Olivier Brouckaert
+	 * @param integer $deleteFromEx - exercise ID if the question is only removed from one exercise
 	 */
 	function delete($deleteFromEx = 0) {
         $course_id = api_get_course_int_id();
@@ -1203,7 +1204,7 @@ abstract class Question
 
 		// Question type
         $answerType = isset($_REQUEST['answerType']) ? intval($_REQUEST['answerType']) : null;
-		$form->addElement('hidden','answerType', $_REQUEST['answerType']);
+		$form->addElement('hidden','answerType', $answerType);
 
 		// html editor
 		$editor_config = array('ToolbarSet' => 'TestQuestionDescription', 'Width' => '100%', 'Height' => '150');
@@ -1303,8 +1304,8 @@ abstract class Question
 
 	/**
 	 * function which process the creation of questions
-	 * @param FormValidator $form the formvalidator instance
-	 * @param Exercise $objExercise the Exercise instance
+	 * @param FormValidator $form
+	 * @param Exercise $objExercise
 	 */
 	function processCreation ($form, $objExercise = null) {
         //$this->updateParentId($form->getSubmitValue('parent_id'));
@@ -1432,9 +1433,9 @@ abstract class Question
     /**
      * Shows question title an description
      *
-     * @param type $feedback_type
-     * @param type $counter
-     * @param type $score
+     * @param string $feedback_type
+     * @param int $counter
+     * @param float $score
      */
 	function return_header($feedback_type = null, $counter = null, $score = null)
     {
@@ -1505,7 +1506,7 @@ abstract class Question
         $sql = "INSERT INTO $tbl_quiz_question (c_id, question, description, ponderation, position, type, level)
                 VALUES ($course_id, '".Database::escape_string($question_name)."', '".Database::escape_string($question_description)."', '$max_score', $max_position, $type, $level)";
 
-        $rs = Database::query($sql);
+        Database::query($sql);
         // Get the question ID
         $question_id = Database::get_last_insert_id();
 
@@ -1519,13 +1520,12 @@ abstract class Question
         $sql = "INSERT INTO $tbl_quiz_rel_question "
             ."(c_id, question_id,exercice_id,question_order)"
             ." VALUES($course_id, $question_id, $quiz_id, $max_order)";
-        $rs = Database::query($sql);
+        Database::query($sql);
         return $question_id;
     }
 
     /**
-     * return the image filename of the question type
-     *
+     * @return array the image filename of the question type
     */
     public function get_type_icon_html() {
     	$type            = $this->selectType();
@@ -1549,13 +1549,16 @@ abstract class Question
             array(
                 'limit' => " $start, $limit",
                 'where' => $default_where,
-                'order' => "$sidx $sord"));
+                'order' => "$sidx $sord")
+        );
         return $result;
     }
 
     /**
      * Get count course medias
      * @param int course id
+     *
+     * @return int
      */
     static function get_count_course_medias($course_id) {
         $table_question = Database::get_course_table(TABLE_QUIZ_QUESTION);
@@ -1567,6 +1570,10 @@ abstract class Question
         return 0;
     }
 
+    /**
+     * @param int $course_id
+     * @return array
+     */
     static function prepare_course_media_select($course_id) {
         $medias = self::get_course_medias($course_id);
         $media_list = array();
@@ -1580,7 +1587,11 @@ abstract class Question
         return $media_list;
     }
 
-    static function get_default_levels() {
+    /**
+     * @return array
+     */
+    static function get_default_levels()
+    {
         $select_level = array(
                 1=>1,
                 2=>2,
@@ -1591,7 +1602,11 @@ abstract class Question
         return $select_level;
     }
 
-    function show_media_content() {
+    /**
+     * @return null|string
+     */
+    function show_media_content()
+    {
         $html = null;
         if ($this->parent_id != 0) {
             $parent_question = Question::read($this->parent_id);

+ 2 - 2
main/exercice/testcategory.class.php

@@ -380,10 +380,10 @@ class Testcategory
         echo self::returnCategoryAndTitle($in_questionID, $in_display_category_name);
 	}
 
-
     public static function returnCategoryAndTitle($in_questionID, $in_display_category_name = 1) {
         $is_student = !(api_is_allowed_to_edit(null,true) || api_is_session_admin());
-        $objExercise = $_SESSION['objExercise'];
+        // @todo fix $_SESSION['objExercise']
+        $objExercise = isset($_SESSION['objExercise']) ? $_SESSION['objExercise'] : null;
         if (!empty($objExercise)) {
             $in_display_category_name = $objExercise->display_category_name;
         }

+ 13 - 3
main/forum/forumfunction.inc.php

@@ -1219,7 +1219,7 @@ function get_forums_in_category($cat_id)
  * @author Patrick Cool <patrick.cool@UGent.be>, Ghent University
  * @version february 2006, dokeos 1.8
  */
-function get_forums($id = '', $course_code = '')
+function get_forums($id = '', $course_code = '', $includeGroupsForum = true)
 {
     $course_info = api_get_course_info($course_code);
 
@@ -1237,6 +1237,11 @@ function get_forums($id = '', $course_code = '')
 
     $forum_list = array();
 
+    $includeGroupsForumSelect = "";
+    if (!$includeGroupsForum) {
+        $includeGroupsForumSelect = " AND forum_of_group = 0 ";
+    }
+
     if ($id == '') {
         // Student
         // Select all the forum information of all forums (that are visible to students).
@@ -1248,6 +1253,7 @@ function get_forums($id = '', $course_code = '')
                     $condition_session AND
                     forum.c_id = $course_id AND
                     item_properties.c_id = $course_id
+                    $includeGroupsForumSelect
                 ORDER BY forum.forum_order ASC";
 
         // Select the number of threads of the forums (only the threads that are visible).
@@ -1286,6 +1292,7 @@ function get_forums($id = '', $course_code = '')
                         $condition_session AND
                         forum.c_id = $course_id AND
                         item_properties.c_id = $course_id
+                        $includeGroupsForumSelect
                     ORDER BY forum_order ASC";
 
             // Select the number of threads of the forums (only the threads that are not deleted).
@@ -3958,6 +3965,8 @@ function get_forums_of_group($group_id)
     // Handling all the forum information.
 
     $result = Database::query($sql);
+    $forum_list = array();
+
     while ($row = Database::fetch_array($result, 'ASSOC')) {
         $forum_list[$row['forum_id']] = $row;
     }
@@ -3976,14 +3985,15 @@ function get_forums_of_group($group_id)
     $result3 = Database::query($sql3);
     while ($row3 = Database::fetch_array($result3, 'ASSOC')) {
         if (is_array($forum_list)) {
-            if (array_key_exists($row3['forum_id'], $forum_list)) { // This is needed because sql3 takes also the deleted forums into account.
+            if (array_key_exists($row3['forum_id'], $forum_list)) {
+                // This is needed because sql3 takes also the deleted forums into account.
                 $forum_list[$row3['forum_id']]['number_of_posts'] = $row3['number_of_posts'];
             }
         }
     }
 
     // Finding the last post information (last_post_id, last_poster_id, last_post_date, last_poster_name, last_poster_lastname, last_poster_firstname).
-    if (is_array($forum_list)) {
+    if (!empty($forum_list)) {
         foreach ($forum_list as $key => $value) {
             $last_post_info_of_forum = get_last_post_information($key, is_allowed_to_edit());
             $forum_list[$key]['last_post_id'] = $last_post_info_of_forum['last_post_id'];

+ 5 - 4
main/forum/index.php

@@ -147,7 +147,8 @@ event_access_tool(TOOL_FORUM);
 $forumCategories = get_forum_categories();
 
 // Step 2: We find all the forums (only the visible ones if it is a student).
-$forum_list	= get_forums();
+// display group forum in general forum tool depending to configuration option
+$forum_list	= get_forums('', '', apiGetDisplayGroupsForumInGeneralTool());
 $user_id = api_get_user_id();
 
 /* RETRIEVING ALL GROUPS AND THOSE OF THE USER */
@@ -227,7 +228,7 @@ if (is_array($forumCategories)) {
         }
 
         if (empty($forumCategory['cat_title'])) {
-            $forumCategory['cat_title'] = get_lang('NoCategory');
+            $forumCategory['cat_title'] = get_lang('WithoutCategory');
         }
 
         echo '<table class="forum_table">';
@@ -283,7 +284,7 @@ if (is_array($forumCategories)) {
                 }
 
                 // Note: This can be speeded up if we transform the $forum_list to an array that uses the forum_category as the key.
-                if ($forum['forum_category'] == $forumCategory['cat_id']) {
+                if (isset($forum['forum_category']) && $forum['forum_category'] == $forumCategory['cat_id']) {
                     $show_forum = false;
 
                     // SHOULD WE SHOW THIS PARTICULAR FORUM
@@ -322,7 +323,7 @@ if (is_array($forumCategories)) {
 								{
 									$td_width = $image_size['width'];
 								}
-                                $forum_image =  "<img src=\"$image_path\" $img_attributes>";								
+                                $forum_image =  "<img src=\"$image_path\" $img_attributes>";
                             } else {
                                 $forum_image = '';
 								$td_width = 20;

+ 1 - 1
main/forum/viewthread_threaded.inc.php

@@ -68,7 +68,7 @@ foreach ($rows as $post) {
         $post_image=Display::return_icon('forumpost.gif');
     }
     $thread_structure.= $post_image;
-    if ($_GET['post']==$post['post_id'] OR ($counter==1 AND !isset($_GET['post']))) {
+    if (isset($_GET['post']) && $_GET['post']==$post['post_id'] OR ($counter==1 AND !isset($_GET['post']))) {
         $thread_structure.='<strong>'.prepare4display($post['post_title']).'</strong></div>';
         $prev_next_array[]=$post['post_id'];
     } else {

+ 1 - 0
main/gradebook/lib/fe/flatviewtable.class.php

@@ -308,6 +308,7 @@ class FlatViewTable extends SortableTable
                             //$Test->drawTreshold(0,143,55,72,TRUE,TRUE);
 
                             // Draw the bar graph
+                            $Test->setFontProperties(api_get_path(LIBRARY_PATH)."pchart/fonts/tahoma.ttf",11);
                             $Test->drawBarGraph($DataSet->GetData(),$DataSet->GetDataDescription(),TRUE);
 
                             //Set legend properties: width, height and text color and font

+ 220 - 188
main/gradebook/lib/gradebook_data_generator.class.php

@@ -13,222 +13,254 @@
 class GradebookDataGenerator
 {
 
-	// Sorting types constants
-	const GDG_SORT_TYPE            = 1;
-	const GDG_SORT_NAME            = 2;
-	const GDG_SORT_DESCRIPTION     = 4;
-	const GDG_SORT_WEIGHT          = 8;
-	const GDG_SORT_DATE            = 16;
-
-	const GDG_SORT_ASC             = 32;
-	const GDG_SORT_DESC            = 64;
+    // Sorting types constants
+    const GDG_SORT_TYPE            = 1;
+    const GDG_SORT_NAME            = 2;
+    const GDG_SORT_DESCRIPTION     = 4;
+    const GDG_SORT_WEIGHT          = 8;
+    const GDG_SORT_DATE            = 16;
+
+    const GDG_SORT_ASC             = 32;
+    const GDG_SORT_DESC            = 64;
     
     const GDG_SORT_ID              = 128;
 
 
-	private $items;
-	private $evals_links;
+    private $items;
+    private $evals_links;
+
+    function GradebookDataGenerator($cats = array(), $evals = array(), $links = array())
+    {
+        $allcats = (isset($cats) ? $cats : array());
+        $allevals = (isset($evals) ? $evals : array());
+        $alllinks = (isset($links) ? $links : array());
+
+        // if we are in the root category and if there are sub categories
+        // display only links depending of the root category and not link that belongs
+        // to a sub category https://support.chamilo.org/issues/6602
+        $tabLinkToDisplay = $alllinks;
+        if (count($allcats) > 0) {
+            // get sub categories id
+            $tabCategories = array();
+            for ($i=0; $i < count($allcats); $i++) {
+                $tabCategories[] = $allcats[$i]->get_id();
+            }
+            // dont display links that belongs to a sub category
+            $tabLinkToDisplay = array();
+            for ($i=0; $i < count($alllinks); $i++) {
+                if (!in_array($alllinks[$i]->get_category_id(), $tabCategories)) {
+                    $tabLinkToDisplay[] = $alllinks[$i];
+                }
+            }
+        }
 
-    function GradebookDataGenerator($cats = array(), $evals = array(), $links = array()) {
-		$allcats = (isset($cats) ? $cats : array());
-		$allevals = (isset($evals) ? $evals : array());
-		$alllinks = (isset($links) ? $links : array());
-		// merge categories, evaluations and links
-		$this->items = array_merge($allcats, $allevals, $alllinks);        
-		$this->evals_links = array_merge($allevals, $alllinks);
+        // merge categories, evaluations and links
+        $this->items = array_merge($allcats, $allevals, $tabLinkToDisplay);
+        $this->evals_links = array_merge($allevals, $tabLinkToDisplay);
     }
 
-	/**
-	 * Get total number of items (rows)
-	 */
-	public function get_total_items_count() {
-		return count($this->items);
-	}
-	
-	/**
-	 * Get actual array data
-	 * @return array 2-dimensional array - each array contains the elements:
-	 * 0: cat/eval/link object
-	 * 1: item name
-	 * 2: description
-	 * 3: weight
-	 * 4: date
-	 * 5: student's score (if student logged in)
-	 */
-	public function get_data($sorting = 0, $start = 0, $count = null, $ignore_score_color = false) {
-		//$status = CourseManager::get_user_in_course_status(api_get_user_id(), api_get_course_id());
-		// do some checks on count, redefine if invalid value
-		if (!isset($count)) {
-			$count = count ($this->items) - $start;
-		}
-		if ($count < 0) {
-			$count = 0;
-		}
+    /**
+     * Get total number of items (rows)
+     */
+    public function get_total_items_count()
+    {
+        return count($this->items);
+    }
+    
+    /**
+     * Get actual array data
+     * @return array 2-dimensional array - each array contains the elements:
+     * 0: cat/eval/link object
+     * 1: item name
+     * 2: description
+     * 3: weight
+     * 4: date
+     * 5: student's score (if student logged in)
+     */
+    public function get_data($sorting = 0, $start = 0, $count = null, $ignore_score_color = false)
+    {
+        //$status = CourseManager::get_user_in_course_status(api_get_user_id(), api_get_course_id());
+        // do some checks on count, redefine if invalid value
+        if (!isset($count)) {
+            $count = count ($this->items) - $start;
+        }
+        if ($count < 0) {
+            $count = 0;
+        }
         
-		$allitems = $this->items;
-		// sort array
-		if ($sorting & self :: GDG_SORT_TYPE) {
-			usort($allitems, array('GradebookDataGenerator', 'sort_by_type'));
+        $allitems = $this->items;
+        // sort array
+        if ($sorting & self :: GDG_SORT_TYPE) {
+            usort($allitems, array('GradebookDataGenerator', 'sort_by_type'));
         } elseif ($sorting & self :: GDG_SORT_ID) {
             usort($allitems, array('GradebookDataGenerator', 'sort_by_id'));
-		} elseif ($sorting & self :: GDG_SORT_NAME) {
-			usort($allitems, array('GradebookDataGenerator', 'sort_by_name'));
-		} elseif ($sorting & self :: GDG_SORT_DESCRIPTION) {
-			usort($allitems, array('GradebookDataGenerator', 'sort_by_description'));
-		} elseif ($sorting & self :: GDG_SORT_WEIGHT) {
-			usort($allitems, array('GradebookDataGenerator', 'sort_by_weight'));
-		} elseif ($sorting & self :: GDG_SORT_DATE) {
-			//usort($allitems, array('GradebookDataGenerator', 'sort_by_date'));
-		}
-		if ($sorting & self :: GDG_SORT_DESC) {
-			$allitems = array_reverse($allitems);
-		}
-		// get selected items
-		$visibleitems = array_slice($allitems, $start, $count);
-		//status de user in course
-	    $user_id      = api_get_user_id();
-		$course_code  = api_get_course_id();
-		$status_user  = api_get_status_of_user_in_course($user_id, $course_code);
+        } elseif ($sorting & self :: GDG_SORT_NAME) {
+            usort($allitems, array('GradebookDataGenerator', 'sort_by_name'));
+        } elseif ($sorting & self :: GDG_SORT_DESCRIPTION) {
+            usort($allitems, array('GradebookDataGenerator', 'sort_by_description'));
+        } elseif ($sorting & self :: GDG_SORT_WEIGHT) {
+            usort($allitems, array('GradebookDataGenerator', 'sort_by_weight'));
+        } elseif ($sorting & self :: GDG_SORT_DATE) {
+            //usort($allitems, array('GradebookDataGenerator', 'sort_by_date'));
+        }
+        if ($sorting & self :: GDG_SORT_DESC) {
+            $allitems = array_reverse($allitems);
+        }
+        // get selected items
+        $visibleitems = array_slice($allitems, $start, $count);
+        //status de user in course
+        $user_id      = api_get_user_id();
+        $course_code  = api_get_course_id();
+        $status_user  = api_get_status_of_user_in_course($user_id, $course_code);
         
-		// generate the data to display
-		$data = array();
+        // generate the data to display
+        $data = array();
         
-		foreach ($visibleitems as $item) {
-			$row = array ();
-			$row[] = $item;
-			$row[] = $item->get_name();
+        foreach ($visibleitems as $item) {
+            $row = array ();
+            $row[] = $item;
+            $row[] = $item->get_name();
             // display the 2 first line of description, and all description on mouseover (https://support.chamilo.org/issues/6588)
-			$row[] = '<span title="'.api_remove_tags_with_space($item->get_description()).'">'.api_get_short_text_from_html($item->get_description(), 160).'</span>';
-			$row[] = $item->get_weight();
-			/*if (api_is_allowed_to_edit(null, true)) {
-				$row[] = $this->build_date_column($item);
-			}*/			
-			if (count($this->evals_links) > 0) {
-				if (!api_is_allowed_to_edit() || $status_user != 1 ) {                    
-					$row[] = $this->build_result_column($item, $ignore_score_color);
+            $row[] = '<span title="'.api_remove_tags_with_space($item->get_description()).'">'.api_get_short_text_from_html($item->get_description(), 160).'</span>';
+            $row[] = $item->get_weight();
+            /*if (api_is_allowed_to_edit(null, true)) {
+                $row[] = $this->build_date_column($item);
+            }*/            
+            if (count($this->evals_links) > 0) {
+                if (!api_is_allowed_to_edit() || $status_user != 1 ) {                    
+                    $row[] = $this->build_result_column($item, $ignore_score_color);
                     $row[] = $item;
-				}
-			}			
-		    $data[] = $row;
+                }
+            }            
+            $data[] = $row;
+        }
+        return $data;
+    }
+
+    /**
+     * Returns the link to the certificate generation, if the score is enough, otherwise
+     * returns an empty string. This only works with categories.
+     * @param    object Item
+     */
+    function get_certificate_link($item)
+    {
+        if (is_a($item, 'Category')) {
+            if($item->is_certificate_available(api_get_user_id())) {
+                $link = '<a href="'.Security::remove_XSS($_SESSION['gradebook_dest']).'?export_certificate=1&cat='.$item->get_id().'&user='.api_get_user_id().'">'.get_lang('Certificate').'</a>';
+                return $link;
+            }
         }
-		return $data;
-	}
-
-	/**
-	 * Returns the link to the certificate generation, if the score is enough, otherwise
-	 * returns an empty string. This only works with categories.
-	 * @param	object Item
-	 */
-	function get_certificate_link($item) {
-		if (is_a($item, 'Category')) {
-			if($item->is_certificate_available(api_get_user_id())) {
-				$link = '<a href="'.Security::remove_XSS($_SESSION['gradebook_dest']).'?export_certificate=1&cat='.$item->get_id().'&user='.api_get_user_id().'">'.get_lang('Certificate').'</a>';
-				return $link;
-			}
-		}
-		return '';
-	}
+        return '';
+    }
     // Sort functions
     // Make sure to only use functions as defined in the GradebookItem interface !
 
-	function sort_by_name($item1, $item2) {
-		return api_strnatcmp($item1->get_name(), $item2->get_name());
-	}
+    function sort_by_name($item1, $item2)
+    {
+        return api_strnatcmp($item1->get_name(), $item2->get_name());
+    }
     
-    function sort_by_id($item1, $item2) {
+    function sort_by_id($item1, $item2)
+    {
         return api_strnatcmp($item1->get_id(), $item2->get_id());
     }    
 
-	function sort_by_type($item1, $item2) {
-		if ($item1->get_item_type() == $item2->get_item_type()) {
-			return $this->sort_by_name($item1,$item2);
-		} else {
-			return ($item1->get_item_type() < $item2->get_item_type() ? -1 : 1);
-		}
-	}
-
-	function sort_by_description($item1, $item2) {
-		$result = api_strcmp($item1->get_description(), $item2->get_description());
-		if ($result == 0) {
-			return $this->sort_by_name($item1,$item2);
-		}
-		return $result;
-	}
-
-	function sort_by_weight($item1, $item2) {
-		if ($item1->get_weight() == $item2->get_weight()) {
-			return $this->sort_by_name($item1,$item2);
-		} else {
-			return ($item1->get_weight() < $item2->get_weight() ? -1 : 1);
-		}
-	}
-
-	function sort_by_date($item1, $item2) {
-		if (is_int($item1->get_date())) {
-			$timestamp1 = $item1->get_date();
-		} else {
-		    $date = $item1->get_date();
+    function sort_by_type($item1, $item2)
+    {
+        if ($item1->get_item_type() == $item2->get_item_type()) {
+            return $this->sort_by_name($item1,$item2);
+        } else {
+            return ($item1->get_item_type() < $item2->get_item_type() ? -1 : 1);
+        }
+    }
+
+    function sort_by_description($item1, $item2)
+    {
+        $result = api_strcmp($item1->get_description(), $item2->get_description());
+        if ($result == 0) {
+            return $this->sort_by_name($item1,$item2);
+        }
+        return $result;
+    }
+
+    function sort_by_weight($item1, $item2)
+    {
+        if ($item1->get_weight() == $item2->get_weight()) {
+            return $this->sort_by_name($item1,$item2);
+        } else {
+            return ($item1->get_weight() < $item2->get_weight() ? -1 : 1);
+        }
+    }
+
+    function sort_by_date($item1, $item2)
+    {
+        if (is_int($item1->get_date())) {
+            $timestamp1 = $item1->get_date();
+        } else {
+            $date = $item1->get_date();
             if (!empty($date)) {
-			 $timestamp1 = api_strtotime($date, 'UTC');
+             $timestamp1 = api_strtotime($date, 'UTC');
             } else {
                 $timestamp1 = null;
             }
-		}
-		
-		if(is_int($item2->get_date())) {
-			$timestamp2 = $item2->get_date();
-		} else {
-			$timestamp2 = api_strtotime($item2->get_date(), 'UTC');
-		}
-		
-		if ($timestamp1 == $timestamp2) {
-			return $this->sort_by_name($item1,$item2);
-		} else {
-			return ($timestamp1 < $timestamp2 ? -1 : 1);
-		}
-	}
+        }
+        
+        if(is_int($item2->get_date())) {
+            $timestamp2 = $item2->get_date();
+        } else {
+            $timestamp2 = api_strtotime($item2->get_date(), 'UTC');
+        }
+        
+        if ($timestamp1 == $timestamp2) {
+            return $this->sort_by_name($item1,$item2);
+        } else {
+            return ($timestamp1 < $timestamp2 ? -1 : 1);
+        }
+    }
 
     //  Other functions
-	private function build_result_column($item, $ignore_score_color) {
-		$scoredisplay = ScoreDisplay :: instance();        
-		$score 	     = $item->calc_score(api_get_user_id());
-		
-        if (!empty($score)) {        	
-    		switch ($item->get_item_type()) {
-    			// category
-    			case 'C' :
-    				if ($score != null) {
-    					$displaytype = SCORE_PERCENT;
-    					if ($ignore_score_color) {
-    						$displaytype |= SCORE_IGNORE_SPLIT;
-    					}
-    					return get_lang('Total') . ' : '. $scoredisplay->display_score($score, $displaytype);
-    				} else {
-    					return '';
-    				}
-    			// evaluation and link
-    			case 'E' :
-    			case 'L' :
-    				$displaytype = SCORE_DIV_PERCENT;
-    				if ($ignore_score_color) {    				    
-    					$displaytype |= SCORE_IGNORE_SPLIT;
-    				}
-    				return $scoredisplay->display_score($score, SCORE_DIV_PERCENT_WITH_CUSTOM);
-    		}
+    private function build_result_column($item, $ignore_score_color)
+    {
+        $scoredisplay = ScoreDisplay :: instance();        
+        $score          = $item->calc_score(api_get_user_id());
+        
+        if (!empty($score)) {            
+            switch ($item->get_item_type()) {
+                // category
+                case 'C' :
+                    if ($score != null) {
+                        $displaytype = SCORE_PERCENT;
+                        if ($ignore_score_color) {
+                            $displaytype |= SCORE_IGNORE_SPLIT;
+                        }
+                        return get_lang('Total') . ' : '. $scoredisplay->display_score($score, $displaytype);
+                    } else {
+                        return '';
+                    }
+                // evaluation and link
+                case 'E' :
+                case 'L' :
+                    $displaytype = SCORE_DIV_PERCENT;
+                    if ($ignore_score_color) {                        
+                        $displaytype |= SCORE_IGNORE_SPLIT;
+                    }
+                    return $scoredisplay->display_score($score, SCORE_DIV_PERCENT_WITH_CUSTOM);
+            }
         }
         return null;
-	}
-
-	private function build_date_column($item) {
-		$date = $item->get_date();
-		if (!isset($date) || empty($date)) {
-			return '';
-		} else {
-			if(is_int($date)) {
-				return api_convert_and_format_date($date);
-			} else {
-				return api_format_date($date);
-			}
-		}
-	}
+    }
+
+    private function build_date_column($item)
+    {
+        $date = $item->get_date();
+        if (!isset($date) || empty($date)) {
+            return '';
+        } else {
+            if(is_int($date)) {
+                return api_convert_and_format_date($date);
+            } else {
+                return api_format_date($date);
+            }
+        }
+    }
 }

+ 0 - 0
main/img/btn_previus.png → main/img/btn_previous.png


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


+ 7 - 7
main/inc/ajax/agenda.ajax.php

@@ -91,11 +91,11 @@ 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;
 
@@ -103,8 +103,8 @@ switch ($action) {
             $start,
             $end,
             api_get_course_int_id(),
-            $group_id,
-            $user_id
+            $groupId,
+            $userId
         );
         echo $events;
         break;

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

@@ -24,6 +24,8 @@ switch($action) {
             exit;
         }
 
+        $ifExists = isset($_POST['if_exists']) ? $_POST['if_exists'] : null;
+
         if (!empty($_FILES)) {
             require_once api_get_path(LIBRARY_PATH).'fileDisplay.lib.php';
             $file = $_FILES['file'];
@@ -33,7 +35,7 @@ switch($action) {
                 $file['name'],
                 null,
                 0,
-                $_POST['if_exists'],
+                $ifExists,
                 false,
                 false
             );

+ 83 - 28
main/inc/ajax/exercise.ajax.php

@@ -77,29 +77,41 @@ switch ($action) {
             $start = 0;
         }
 
-        $sql = "SELECT  exe_id,
-                        exe_user_id,
-                        firstname,
-                        lastname,
-                        aa.status,
-                        start_date,
-                        exe_result,
-                        exe_weighting,
-                        exe_result/exe_weighting as score,
-                        exe_duration,
-                        questions_to_check,
-                        orig_lp_id
+        $sql = "SELECT
+                    exe_id,
+                    exe_user_id,
+                    firstname,
+                    lastname,
+                    aa.status,
+                    start_date,
+                    exe_result,
+                    exe_weighting,
+                    exe_result/exe_weighting as score,
+                    exe_duration,
+                    questions_to_check,
+                    orig_lp_id
                 FROM $user_table u
                 INNER JOIN (
-                    SELECT  t.exe_id, t.exe_user_id, status,
-                    start_date, exe_result, exe_weighting, exe_result/exe_weighting as score, exe_duration, questions_to_check, orig_lp_id
-                    FROM  $track_exercise  t LEFT JOIN $track_attempt a ON (a.exe_id = t.exe_id AND  t.exe_user_id = a.user_id )
-                    WHERE t.status = 'incomplete' AND
-                          $where_condition
+                    SELECT
+                    t.exe_id,
+                    t.exe_user_id,
+                    status,
+                    start_date,
+                    exe_result,
+                    exe_weighting,
+                    exe_result/exe_weighting as score,
+                    exe_duration,
+                    questions_to_check,
+                    orig_lp_id
+                    FROM  $track_exercise  t
+                    LEFT JOIN $track_attempt a
+                    ON (a.exe_id = t.exe_id AND t.exe_user_id = a.user_id )
+                    WHERE t.status = 'incomplete' AND $where_condition
                     GROUP BY exe_user_id
                 ) as aa
                 ON aa.exe_user_id = user_id
-                ORDER BY $sidx $sord LIMIT $start, $limit";
+                ORDER BY $sidx $sord
+                LIMIT $start, $limit";
 
         $result = Database::query($sql);
         $results = array();
@@ -118,9 +130,13 @@ switch ($action) {
 
         if (!empty($results)) {
             foreach ($results as $row) {
-                $sql = "SELECT SUM(count_question_id) as count_question_id FROM (
-                            SELECT 1 as count_question_id FROM  $track_attempt a
-                            WHERE user_id = {$row['exe_user_id']} and exe_id = {$row['exe_id']}
+                $sql = "SELECT SUM(count_question_id) as count_question_id
+                        FROM (
+                            SELECT 1 as count_question_id
+                            FROM $track_attempt a
+                            WHERE
+                              user_id = {$row['exe_user_id']} AND
+                              exe_id = {$row['exe_id']}
                             GROUP by question_id
                         ) as count_table";
                 $result_count = Database::query($sql);
@@ -156,7 +172,15 @@ switch ($action) {
             Database::query("DELETE FROM $table WHERE session_id = $session_id AND c_id = $course_id");
             //Insert all
             foreach ($new_list as $new_order_id) {
-                Database::insert($table, array('exercise_order' => $counter, 'session_id' => $session_id, 'exercise_id' => intval($new_order_id), 'c_id' => $course_id));
+                Database::insert(
+                    $table,
+                    array(
+                        'exercise_order' => $counter,
+                        'session_id' => $session_id,
+                        'exercise_id' => intval($new_order_id),
+                        'c_id' => $course_id
+                    )
+                );
                 $counter++;
             }
             Display::display_confirmation_message(get_lang('Saved'));
@@ -165,7 +189,6 @@ switch ($action) {
     case 'update_question_order':
         $course_info = api_get_course_info($course_code);
         $course_id = $course_info['real_id'];
-
         $exercise_id = isset($_REQUEST['exercise_id']) ? $_REQUEST['exercise_id'] : null;
 
         if (empty($exercise_id)) {
@@ -176,19 +199,28 @@ switch ($action) {
             $TBL_QUESTIONS = Database::get_course_table(TABLE_QUIZ_TEST_QUESTION);
             $counter = 1;
             foreach ($new_question_list as $new_order_id) {
-                Database::update($TBL_QUESTIONS, array('question_order' => $counter), array('question_id = ? AND c_id = ? AND exercice_id = ? '=>array(intval($new_order_id), $course_id, $exercise_id)));
+                Database::update(
+                    $TBL_QUESTIONS,
+                    array('question_order' => $counter),
+                    array('question_id = ? AND c_id = ? AND exercice_id = ? ' => array(intval($new_order_id), $course_id, $exercise_id)))
+                ;
                 $counter++;
             }
             Display::display_confirmation_message(get_lang('Saved'));
         }
         break;
     case 'add_question_to_reminder':
+        /** @var Exercise $objExercise */
         $objExercise  = $_SESSION['objExercise'];
         if (empty($objExercise)) {
             echo 0;
             exit;
         } else {
-            $objExercise->edit_question_to_remind($_REQUEST['exe_id'], $_REQUEST['question_id'], $_REQUEST['action']);
+            $objExercise->edit_question_to_remind(
+                $_REQUEST['exe_id'],
+                $_REQUEST['question_id'],
+                $_REQUEST['action']
+            );
         }
         break;
     case 'save_exercise_by_now':
@@ -226,6 +258,7 @@ switch ($action) {
             }
 
             // Exercise information.
+            /** @var Exercise $objExercise */
             $objExercise = isset($_SESSION['objExercise']) ? $_SESSION['objExercise'] : null;
 
             // Question info.
@@ -346,7 +379,17 @@ switch ($action) {
 
                 if ($type == 'simple') {
                     // Getting old attempt in order to decrees the total score.
-                    $old_result = $objExercise->manage_answer($exe_id, $my_question_id, null, 'exercise_show', array(), false, true, false, $objExercise->selectPropagateNeg());
+                    $old_result = $objExercise->manage_answer(
+                        $exe_id,
+                        $my_question_id,
+                        null,
+                        'exercise_show',
+                        array(),
+                        false,
+                        true,
+                        false,
+                        $objExercise->selectPropagateNeg()
+                    );
 
                     // Removing old score.
                     $total_score = $total_score - $old_result['score'];
@@ -359,7 +402,7 @@ switch ($action) {
                     }
                     delete_attempt($exe_id, api_get_user_id(), $course_code, $session_id, $my_question_id);
                     if ($objQuestionTmp->type  == HOT_SPOT) {
-                        delete_attempt_hotspot($exe_id, api_get_user_id(), $course_code, $my_question_id);
+                        delete_attempt_hotspot($exe_id, api_get_user_id(), $course_code, $session_id, $my_question_id);
                     }
 
                     if (isset($attempt_list[$my_question_id]) && isset($attempt_list[$my_question_id]['marks'])) {
@@ -368,7 +411,19 @@ switch ($action) {
                 }
 
                 // We're inside *one* question. Go through each possible answer for this question
-                $result = $objExercise->manage_answer($exe_id, $my_question_id, $my_choice, 'exercise_result', $hot_spot_coordinates, true, false, false, $objExercise->selectPropagateNeg(), $hotspot_delineation_result, true);
+                $result = $objExercise->manage_answer(
+                    $exe_id,
+                    $my_question_id,
+                    $my_choice,
+                    'exercise_result',
+                    $hot_spot_coordinates,
+                    true,
+                    false,
+                    false,
+                    $objExercise->selectPropagateNeg(),
+                    $hotspot_delineation_result,
+                    true
+                );
 
                 //  Adding the new score.
                 $total_score += $result['score'];

+ 2 - 2
main/inc/ajax/model.ajax.php

@@ -603,7 +603,7 @@ switch ($action) {
                 'firstname', 'lastname', 'username', 'group_name', 'exe_duration', 'start_date', 'exe_date', 'score', 'status', 'lp', 'actions'
             );
         }
-        $result = get_exam_results_data($start, $limit, $sidx, $sord, $exercise_id, $where_condition);
+        $result = get_exam_results_data($start, $limit, $sidx, $sord, $exercise_id, $whereCondition);
         break;
     case 'get_hotpotatoes_exercise_results':
         $course = api_get_course_info();
@@ -613,7 +613,7 @@ switch ($action) {
         } else {
             $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);
+        $result = get_exam_results_hotpotatoes_data($start, $limit, $sidx, $sord, $hotpot_path, $whereCondition); //get_exam_results_data($start, $limit, $sidx, $sord, $exercise_id, $where_condition);
         break;
     case 'get_work_student_list_overview':
         if (!api_is_allowed_to_edit()) {

+ 6 - 5
main/inc/ajax/work.ajax.php

@@ -5,16 +5,17 @@
  */
 
 require_once '../global.inc.php';
-
 require_once api_get_path(SYS_CODE_PATH).'work/work.lib.php';
 
 $action = isset($_REQUEST['a']) ? $_REQUEST['a'] : null;
-
-$is_allowed_to_edit = api_is_allowed_to_edit();
+$isAllowedToEdit = api_is_allowed_to_edit();
 
 switch ($action) {
     case 'delete_work':
-        if ($is_allowed_to_edit) {
+        if ($isAllowedToEdit) {
+            if (empty($_REQUEST['id'])) {
+                return false;
+            }
             $workList = explode(',', $_REQUEST['id']);
             foreach ($workList as $workId) {
                 deleteDirWork($workId);
@@ -25,4 +26,4 @@ switch ($action) {
         echo '';
         break;
 }
-exit;
+exit;

+ 1 - 1
main/inc/global.inc.php

@@ -487,7 +487,7 @@ if (!empty($valid_languages)) {
     if (!empty($language_priority1) && api_get_language_from_type($language_priority1) !== false ) {
         $language_interface =  api_get_language_from_type($language_priority1);
     } else {
-        if ($_course['language']) {
+        if (isset($_course['language'])) {
             $language_interface = $_course['language'];
         }
     }

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

@@ -636,7 +636,7 @@ function return_breadcrumb($interbreadcrumb, $language_file, $nameTools) {
         }
 
         if (!empty($lis)) {
-            $html .= Display::tag('ul', $lis, array('class'=>'breadcrumb'));
+            $html .= Display::tag('ul', $lis, array('class'=>'breadcrumb','style'=>'margin-top: 0'));
         }
     }
     return $html ;

+ 1224 - 1055
main/inc/lib/browser/Browser.php

@@ -1,1055 +1,1224 @@
-<?php
-/**
- * File: Browser.php
- * Author: Chris Schuld (http://chrisschuld.com/)
- * Last Modified: August 20th, 2010
- * @version 1.9
- *
- * Copyright (C) 2008-2010 Chris Schuld  (chris@chrisschuld.com)
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details at:
- * http://www.gnu.org/copyleft/gpl.html
- *
- *
- * Typical Usage:
- *
- *   $browser = new Browser();
- *   if( $browser->getBrowser() == Browser::BROWSER_FIREFOX && $browser->getVersion() >= 2 ) {
- *   	echo 'You have FireFox version 2 or greater';
- *   }
- *
- * User Agents Sampled from: http://www.useragentstring.com/
- *
- * This implementation is based on the original work from Gary White
- * http://apptools.com/phptools/browser/
- *
- * UPDATES:
- *
- * 2010-08-20 (v1.9):
- *  + Added MSN Explorer Browser (legacy)
- *  + Added Bing/MSN Robot (Thanks Rob MacDonald)
- *  + Added the Android Platform (PLATFORM_ANDROID)
- *  + Fixed issue with Android 1.6/2.2 (Thanks Tom Hirashima)
- *
- * 2010-04-27 (v1.8):
- *  + Added iPad Support
- *
- * 2010-03-07 (v1.7):
- *  + *MAJOR* Rebuild (preg_match and other "slow" routine removal(s))
- *  + Almost allof Gary's original code has been replaced
- *  + Large PHPUNIT testing environment created to validate new releases and additions
- *  + Added FreeBSD Platform
- *  + Added OpenBSD Platform
- *  + Added NetBSD Platform
- *  + Added SunOS Platform
- *  + Added OpenSolaris Platform
- *  + Added support of the Iceweazel Browser
- *  + Added isChromeFrame() call to check if chromeframe is in use
- *  + Moved the Opera check in front of the Firefox check due to legacy Opera User Agents
- *  + Added the __toString() method (Thanks Deano)
- *
- * 2009-11-15:
- *  + Updated the checkes for Firefox
- *  + Added the NOKIA platform
- *  + Added Checks for the NOKIA brower(s)
- *  
- * 2009-11-08:
- *  + PHP 5.3 Support
- *  + Added support for BlackBerry OS and BlackBerry browser
- *  + Added support for the Opera Mini browser
- *  + Added additional documenation
- *  + Added support for isRobot() and isMobile()
- *  + Added support for Opera version 10
- *  + Added support for deprecated Netscape Navigator version 9
- *  + Added support for IceCat
- *  + Added support for Shiretoko
- *
- * 2010-04-27 (v1.8):
- *  + Added iPad Support
- *
- * 2009-08-18:
- *  + Updated to support PHP 5.3 - removed all deprecated function calls
- *  + Updated to remove all double quotes (") -- converted to single quotes (')
- *
- * 2009-04-27:
- *  + Updated the IE check to remove a typo and bug (thanks John)
- *
- * 2009-04-22:
- *  + Added detection for GoogleBot
- *  + Added detection for the W3C Validator.
- *  + Added detection for Yahoo! Slurp
- *
- * 2009-03-14:
- *  + Added detection for iPods.
- *  + Added Platform detection for iPhones
- *  + Added Platform detection for iPods
- *
- * 2009-02-16: (Rick Hale)
- *  + Added version detection for Android phones.
- *
- * 2008-12-09:
- *  + Removed unused constant
- *
- * 2008-11-07:
- *  + Added Google's Chrome to the detection list
- *  + Added isBrowser(string) to the list of functions special thanks to
- *    Daniel 'mavrick' Lang for the function concept (http://mavrick.id.au)
- *
- *
- * Gary White noted: "Since browser detection is so unreliable, I am
- * no longer maintaining this script. You are free to use and or
- * modify/update it as you want, however the author assumes no
- * responsibility for the accuracy of the detected values."
- *
- * Anyone experienced with Gary's script might be interested in these notes:
- *
- *   Added class constants
- *   Added detection and version detection for Google's Chrome
- *   Updated the version detection for Amaya
- *   Updated the version detection for Firefox
- *   Updated the version detection for Lynx
- *   Updated the version detection for WebTV
- *   Updated the version detection for NetPositive
- *   Updated the version detection for IE
- *   Updated the version detection for OmniWeb
- *   Updated the version detection for iCab
- *   Updated the version detection for Safari
- *   Updated Safari to remove mobile devices (iPhone)
- *   Added detection for iPhone
- *   Added detection for robots
- *   Added detection for mobile devices
- *   Added detection for BlackBerry
- *   Removed Netscape checks (matches heavily with firefox & mozilla)
- *
- * @package chamilo.browser
- */
-
-class Browser {
-	private $_agent = '';
-	private $_browser_name = '';
-	private $_version = '';
-	private $_platform = '';
-	private $_os = '';
-	private $_is_aol = false;
-	private $_is_mobile = false;
-	private $_is_robot = false;
-	private $_aol_version = '';
-
-	const BROWSER_UNKNOWN = 'unknown';
-	const VERSION_UNKNOWN = 'unknown';
-
-	const BROWSER_OPERA = 'Opera';                            // http://www.opera.com/
-	const BROWSER_OPERA_MINI = 'Opera Mini';                  // http://www.opera.com/mini/
-	const BROWSER_WEBTV = 'WebTV';                            // http://www.webtv.net/pc/
-	const BROWSER_IE = 'Internet Explorer';                   // http://www.microsoft.com/ie/
-	const BROWSER_POCKET_IE = 'Pocket Internet Explorer';     // http://en.wikipedia.org/wiki/Internet_Explorer_Mobile
-	const BROWSER_KONQUEROR = 'Konqueror';                    // http://www.konqueror.org/
-	const BROWSER_ICAB = 'iCab';                              // http://www.icab.de/
-	const BROWSER_OMNIWEB = 'OmniWeb';                        // http://www.omnigroup.com/applications/omniweb/
-	const BROWSER_FIREBIRD = 'Firebird';                      // http://www.ibphoenix.com/
-	const BROWSER_FIREFOX = 'Firefox';                        // http://www.mozilla.com/en-US/firefox/firefox.html
-	const BROWSER_ICEWEASEL = 'Iceweasel';                    // http://www.geticeweasel.org/
-	const BROWSER_SHIRETOKO = 'Shiretoko';                    // http://wiki.mozilla.org/Projects/shiretoko
-	const BROWSER_MOZILLA = 'Mozilla';                        // http://www.mozilla.com/en-US/
-	const BROWSER_AMAYA = 'Amaya';                            // http://www.w3.org/Amaya/
-	const BROWSER_LYNX = 'Lynx';                              // http://en.wikipedia.org/wiki/Lynx
-	const BROWSER_SAFARI = 'Safari';                          // http://apple.com
-	const BROWSER_IPHONE = 'iPhone';                          // http://apple.com
-	const BROWSER_IPOD = 'iPod';                              // http://apple.com
-	const BROWSER_IPAD = 'iPad';                              // http://apple.com
-	const BROWSER_CHROME = 'Chrome';                          // http://www.google.com/chrome
-	const BROWSER_ANDROID = 'Android';                        // http://www.android.com/
-	const BROWSER_GOOGLEBOT = 'GoogleBot';                    // http://en.wikipedia.org/wiki/Googlebot
-	const BROWSER_SLURP = 'Yahoo! Slurp';                     // http://en.wikipedia.org/wiki/Yahoo!_Slurp
-	const BROWSER_W3CVALIDATOR = 'W3C Validator';             // http://validator.w3.org/
-	const BROWSER_BLACKBERRY = 'BlackBerry';                  // http://www.blackberry.com/
-	const BROWSER_ICECAT = 'IceCat';                          // http://en.wikipedia.org/wiki/GNU_IceCat
-	const BROWSER_NOKIA_S60 = 'Nokia S60 OSS Browser';        // http://en.wikipedia.org/wiki/Web_Browser_for_S60
-	const BROWSER_NOKIA = 'Nokia Browser';                    // * all other WAP-based browsers on the Nokia Platform
-	const BROWSER_MSN = 'MSN Browser';                        // http://explorer.msn.com/
-	const BROWSER_MSNBOT = 'MSN Bot';                         // http://search.msn.com/msnbot.htm
-	                                                          // http://en.wikipedia.org/wiki/Msnbot  (used for Bing as well)
-	
-	const BROWSER_NETSCAPE_NAVIGATOR = 'Netscape Navigator';  // http://browser.netscape.com/ (DEPRECATED)
-	const BROWSER_GALEON = 'Galeon';                          // http://galeon.sourceforge.net/ (DEPRECATED)
-	const BROWSER_NETPOSITIVE = 'NetPositive';                // http://en.wikipedia.org/wiki/NetPositive (DEPRECATED)
-	const BROWSER_PHOENIX = 'Phoenix';                        // http://en.wikipedia.org/wiki/History_of_Mozilla_Firefox (DEPRECATED)
-
-	const PLATFORM_UNKNOWN = 'unknown';
-	const PLATFORM_WINDOWS = 'Windows';
-	const PLATFORM_WINDOWS_CE = 'Windows CE';
-	const PLATFORM_APPLE = 'Apple';
-	const PLATFORM_LINUX = 'Linux';
-	const PLATFORM_OS2 = 'OS/2';
-	const PLATFORM_BEOS = 'BeOS';
-	const PLATFORM_IPHONE = 'iPhone';
-	const PLATFORM_IPOD = 'iPod';
-	const PLATFORM_IPAD = 'iPad';
-	const PLATFORM_BLACKBERRY = 'BlackBerry';
-	const PLATFORM_NOKIA = 'Nokia';
-	const PLATFORM_FREEBSD = 'FreeBSD';
-	const PLATFORM_OPENBSD = 'OpenBSD';
-	const PLATFORM_NETBSD = 'NetBSD';
-	const PLATFORM_SUNOS = 'SunOS';
-	const PLATFORM_OPENSOLARIS = 'OpenSolaris';
-	const PLATFORM_ANDROID = 'Android';
-	
-	const OPERATING_SYSTEM_UNKNOWN = 'unknown';
-
-	public function Browser($useragent="") {
-		$this->reset();
-		if( $useragent != "" ) {
-			$this->setUserAgent($useragent);
-		}
-		else {
-			$this->determine();
-		}
-	}
-
-	/**
-	* Reset all properties
-	*/
-	public function reset() {
-		$this->_agent = isset($_SERVER['HTTP_USER_AGENT']) ? $_SERVER['HTTP_USER_AGENT'] : "";
-		$this->_browser_name = self::BROWSER_UNKNOWN;
-		$this->_version = self::VERSION_UNKNOWN;
-		$this->_platform = self::PLATFORM_UNKNOWN;
-		$this->_os = self::OPERATING_SYSTEM_UNKNOWN;
-		$this->_is_aol = false;
-		$this->_is_mobile = false;
-		$this->_is_robot = false;
-		$this->_aol_version = self::VERSION_UNKNOWN;
-	}
-
-	/**
-	* Check to see if the specific browser is valid
-	* @param string $browserName
-	* @return True if the browser is the specified browser
-	*/
-	function isBrowser($browserName) { return( 0 == strcasecmp($this->_browser_name, trim($browserName))); }
-
-	/**
-	* The name of the browser.  All return types are from the class contants
-	* @return string Name of the browser
-	*/
-	public function getBrowser() { return $this->_browser_name; }
-	/**
-	* Set the name of the browser
-	* @param $browser The name of the Browser
-	*/
-	public function setBrowser($browser) { return $this->_browser_name = $browser; }
-	/**
-	* The name of the platform.  All return types are from the class contants
-	* @return string Name of the browser
-	*/
-	public function getPlatform() { return $this->_platform; }
-	/**
-	* Set the name of the platform
-	* @param $platform The name of the Platform
-	*/
-	public function setPlatform($platform) { return $this->_platform = $platform; }
-	/**
-	* The version of the browser.
-	* @return string Version of the browser (will only contain alpha-numeric characters and a period)
-	*/
-	public function getVersion() { return $this->_version; }
-	/**
-	* Set the version of the browser
-	* @param $version The version of the Browser
-	*/
-	public function setVersion($version) { $this->_version = preg_replace('/[^0-9,.,a-z,A-Z-]/','',$version); }
-	/**
-	* The version of AOL.
-	* @return string Version of AOL (will only contain alpha-numeric characters and a period)
-	*/
-	public function getAolVersion() { return $this->_aol_version; }
-	/**
-	* Set the version of AOL
-	* @param $version The version of AOL
-	*/
-	public function setAolVersion($version) { $this->_aol_version = preg_replace('/[^0-9,.,a-z,A-Z]/','',$version); }
-	/**
-	* Is the browser from AOL?
-	* @return boolean True if the browser is from AOL otherwise false
-	*/
-	public function isAol() { return $this->_is_aol; }
-	/**
-	* Is the browser from a mobile device?
-	* @return boolean True if the browser is from a mobile device otherwise false
-	*/
-	public function isMobile() { return $this->_is_mobile; }
-	/**
-	* Is the browser from a robot (ex Slurp,GoogleBot)?
-	* @return boolean True if the browser is from a robot otherwise false
-	*/
-	public function isRobot() { return $this->_is_robot; }
-	/**
-	* Set the browser to be from AOL
-	* @param $isAol
-	*/
-	public function setAol($isAol) { $this->_is_aol = $isAol; }
-	/**
-	 * Set the Browser to be mobile
-	 * @param boolean $value is the browser a mobile brower or not
-	 */
-	protected function setMobile($value=true) { $this->_is_mobile = $value; }
-	/**
-	 * Set the Browser to be a robot
-	 * @param boolean $value is the browser a robot or not
-	 */
-	protected function setRobot($value=true) { $this->_is_robot = $value; }
-	/**
-	* Get the user agent value in use to determine the browser
-	* @return string The user agent from the HTTP header
-	*/
-	public function getUserAgent() { return $this->_agent; }
-	/**
-	* Set the user agent value (the construction will use the HTTP header value - this will overwrite it)
-	* @param $agent_string The value for the User Agent
-	*/
-	public function setUserAgent($agent_string) {
-		$this->reset();
-		$this->_agent = $agent_string;
-		$this->determine();
-	}
-	/**
-	 * Used to determine if the browser is actually "chromeframe"
-	 * @since 1.7
-	 * @return boolean True if the browser is using chromeframe
-	 */
-	public function isChromeFrame() {
-		return( strpos($this->_agent,"chromeframe") !== false );
-	}
-	/**
-	* Returns a formatted string with a summary of the details of the browser.
-	* @return string formatted string with a summary of the browser
-	*/
-	public function __toString() {
-		return "<strong>Browser Name:</strong>{$this->getBrowser()}<br/>\n" .
-		       "<strong>Browser Version:</strong>{$this->getVersion()}<br/>\n" .
-		       "<strong>Browser User Agent String:</strong>{$this->getUserAgent()}<br/>\n" .
-		       "<strong>Platform:</strong>{$this->getPlatform()}<br/>";
-	}
-	/**
-	 * Protected routine to calculate and determine what the browser is in use (including platform)
-	 */
-	protected function determine() {
-		$this->checkPlatform();
-		$this->checkBrowsers();
-		$this->checkForAol();
-	}
-	/**
-	 * Protected routine to determine the browser type
-	 * @return boolean True if the browser was detected otherwise false
-	 */
-	 protected function checkBrowsers() {
-		return (
-			// well-known, well-used
-			// Special Notes:
-			// (1) Opera must be checked before FireFox due to the odd
-			//     user agents used in some older versions of Opera
-			// (2) WebTV is strapped onto Internet Explorer so we must
-			//     check for WebTV before IE
-			// (3) (deprecated) Galeon is based on Firefox and needs to be
-			//     tested before Firefox is tested
-			// (4) OmniWeb is based on Safari so OmniWeb check must occur
-			//     before Safari
-			// (5) Netscape 9+ is based on Firefox so Netscape checks
-			//     before FireFox are necessary
-			$this->checkBrowserWebTv() ||
-			$this->checkBrowserInternetExplorer() ||
-			$this->checkBrowserOpera() ||
-			$this->checkBrowserGaleon() ||
-			$this->checkBrowserNetscapeNavigator9Plus() ||
-			$this->checkBrowserFirefox() ||
-			$this->checkBrowserChrome() ||
-			$this->checkBrowserOmniWeb() ||
-
-			// common mobile
-			$this->checkBrowserAndroid() ||
-			$this->checkBrowseriPad() ||
-			$this->checkBrowseriPod() ||
-			$this->checkBrowseriPhone() ||
-			$this->checkBrowserBlackBerry() ||
-			$this->checkBrowserNokia() ||
-
-			// common bots
-			$this->checkBrowserGoogleBot() ||
-			$this->checkBrowserMSNBot() ||
-			$this->checkBrowserSlurp() ||
-
-			// WebKit base check (post mobile and others)
-			$this->checkBrowserSafari() ||
-			
-			// everyone else
-			$this->checkBrowserNetPositive() ||
-			$this->checkBrowserFirebird() ||
-			$this->checkBrowserKonqueror() ||
-			$this->checkBrowserIcab() ||
-			$this->checkBrowserPhoenix() ||
-			$this->checkBrowserAmaya() ||
-			$this->checkBrowserLynx() ||
-			$this->checkBrowserShiretoko() ||
-			$this->checkBrowserIceCat() ||
-			$this->checkBrowserW3CValidator() ||
-			$this->checkBrowserMozilla() /* Mozilla is such an open standard that you must check it last */
-		);
-    }
-
-    /**
-     * Determine if the user is using a BlackBerry (last updated 1.7)
-     * @return boolean True if the browser is the BlackBerry browser otherwise false
-     */
-    protected function checkBrowserBlackBerry() {
-	    if( stripos($this->_agent,'blackberry') !== false ) {
-		    $aresult = explode("/",stristr($this->_agent,"BlackBerry"));
-		    $aversion = explode(' ',$aresult[1]);
-		    $this->setVersion($aversion[0]);
-		    $this->_browser_name = self::BROWSER_BLACKBERRY;
-		    $this->setMobile(true);
-		    return true;
-	    }
-	    return false;
-    }
-
-    /**
-     * Determine if the user is using an AOL User Agent (last updated 1.7)
-     * @return boolean True if the browser is from AOL otherwise false
-     */
-    protected function checkForAol() {
-		$this->setAol(false);
-		$this->setAolVersion(self::VERSION_UNKNOWN);
-
-		if( stripos($this->_agent,'aol') !== false ) {
-		    $aversion = explode(' ',stristr($this->_agent, 'AOL'));
-		    $this->setAol(true);
-		    $this->setAolVersion(preg_replace('/[^0-9\.a-z]/i', '', $aversion[1]));
-		    return true;
-	    }
-	    return false;
-    }
-
-    /**
-     * Determine if the browser is the GoogleBot or not (last updated 1.7)
-     * @return boolean True if the browser is the GoogletBot otherwise false
-     */
-    protected function checkBrowserGoogleBot() {
-	    if( stripos($this->_agent,'googlebot') !== false ) {
-			$aresult = explode('/',stristr($this->_agent,'googlebot'));
-			$aversion = explode(' ',$aresult[1]);
-			$this->setVersion(str_replace(';','',$aversion[0]));
-			$this->_browser_name = self::BROWSER_GOOGLEBOT;
-			$this->setRobot(true);
-			return true;
-	    }
-	    return false;
-    }
-
-	/**
-     * Determine if the browser is the MSNBot or not (last updated 1.9)
-     * @return boolean True if the browser is the MSNBot otherwise false
-     */
-	protected function checkBrowserMSNBot() {
-		if( stripos($this->_agent,"msnbot") !== false ) {
-			$aresult = explode("/",stristr($this->_agent,"msnbot"));
-			$aversion = explode(" ",$aresult[1]);
-			$this->setVersion(str_replace(";","",$aversion[0]));
-			$this->_browser_name = self::BROWSER_MSNBOT;
-			$this->setRobot(true);
-			return true;
-		}
-		return false;
-	}	    
-    
-    /**
-     * Determine if the browser is the W3C Validator or not (last updated 1.7)
-     * @return boolean True if the browser is the W3C Validator otherwise false
-     */
-    protected function checkBrowserW3CValidator() {
-	    if( stripos($this->_agent,'W3C-checklink') !== false ) {
-		    $aresult = explode('/',stristr($this->_agent,'W3C-checklink'));
-		    $aversion = explode(' ',$aresult[1]);
-		    $this->setVersion($aversion[0]);
-		    $this->_browser_name = self::BROWSER_W3CVALIDATOR;
-		    return true;
-	    }
-	    else if( stripos($this->_agent,'W3C_Validator') !== false ) {
-			// Some of the Validator versions do not delineate w/ a slash - add it back in
-			$ua = str_replace("W3C_Validator ", "W3C_Validator/", $this->_agent);
-		    $aresult = explode('/',stristr($ua,'W3C_Validator'));
-		    $aversion = explode(' ',$aresult[1]);
-		    $this->setVersion($aversion[0]);
-		    $this->_browser_name = self::BROWSER_W3CVALIDATOR;
-		    return true;
-	    }
-	    return false;
-    }
-
-    /**
-     * Determine if the browser is the Yahoo! Slurp Robot or not (last updated 1.7)
-     * @return boolean True if the browser is the Yahoo! Slurp Robot otherwise false
-     */
-    protected function checkBrowserSlurp() {
-	    if( stripos($this->_agent,'slurp') !== false ) {
-		    $aresult = explode('/',stristr($this->_agent,'Slurp'));
-		    $aversion = explode(' ',$aresult[1]);
-		    $this->setVersion($aversion[0]);
-		    $this->_browser_name = self::BROWSER_SLURP;
-			$this->setRobot(true);
-			$this->setMobile(false);
-		    return true;
-	    }
-	    return false;
-    }
-
-    /**
-     * Determine if the browser is Internet Explorer or not (last updated 1.7)
-     * @return boolean True if the browser is Internet Explorer otherwise false
-     */
-    protected function checkBrowserInternetExplorer() {
-
-	    // Test for v1 - v1.5 IE
-	    if( stripos($this->_agent,'microsoft internet explorer') !== false ) {
-		    $this->setBrowser(self::BROWSER_IE);
-		    $this->setVersion('1.0');
-		    $aresult = stristr($this->_agent, '/');
-		    if( preg_match('/308|425|426|474|0b1/i', $aresult) ) {
-			    $this->setVersion('1.5');
-		    }
-			return true;
-	    }
-	    // Test for versions > 1.5
-	    else if( stripos($this->_agent,'msie') !== false && stripos($this->_agent,'opera') === false ) {
-	    	// See if the browser is the odd MSN Explorer
-	    	if( stripos($this->_agent,'msnb') !== false ) {
-		    	$aresult = explode(' ',stristr(str_replace(';','; ',$this->_agent),'MSN'));
-			    $this->setBrowser( self::BROWSER_MSN );
-			    $this->setVersion(str_replace(array('(',')',';'),'',$aresult[1]));
-			    return true;
-	    	}
-	    	$aresult = explode(' ',stristr(str_replace(';','; ',$this->_agent),'msie'));
-	    	$this->setBrowser( self::BROWSER_IE );
-	    	$this->setVersion(str_replace(array('(',')',';'),'',$aresult[1]));
-	    	return true;
-	    }
-	    // Test for Pocket IE
-	    else if( stripos($this->_agent,'mspie') !== false || stripos($this->_agent,'pocket') !== false ) {
-		    $aresult = explode(' ',stristr($this->_agent,'mspie'));
-		    $this->setPlatform( self::PLATFORM_WINDOWS_CE );
-		    $this->setBrowser( self::BROWSER_POCKET_IE );
-		    $this->setMobile(true);
-
-		    if( stripos($this->_agent,'mspie') !== false ) {
-			    $this->setVersion($aresult[1]);
-		    }
-		    else {
-			    $aversion = explode('/',$this->_agent);
-			    $this->setVersion($aversion[1]);
-		    }
-		    return true;
-	    }
-		return false;
-    }
-
-    /**
-     * Determine if the browser is Opera or not (last updated 1.7)
-     * @return boolean True if the browser is Opera otherwise false
-     */
-    protected function checkBrowserOpera() {
-	    if( stripos($this->_agent,'opera mini') !== false ) {
-		    $resultant = stristr($this->_agent, 'opera mini');
-		    if( preg_match('/\//',$resultant) ) {
-			    $aresult = explode('/',$resultant);
-			    $aversion = explode(' ',$aresult[1]);
-			    $this->setVersion($aversion[0]);
-			}
-		    else {
-			    $aversion = explode(' ',stristr($resultant,'opera mini'));
-			    $this->setVersion($aversion[1]);
-		    }
-		    $this->_browser_name = self::BROWSER_OPERA_MINI;
-			$this->setMobile(true);
-			return true;
-	    }
-	    else if( stripos($this->_agent,'opera') !== false ) {
-		    $resultant = stristr($this->_agent, 'opera');
-		    if( preg_match('/Version\/(10.*)$/',$resultant,$matches) ) {
-			    $this->setVersion($matches[1]);
-		    }
-		    else if( preg_match('/\//',$resultant) ) {
-			    $aresult = explode('/',str_replace("("," ",$resultant));
-			    $aversion = explode(' ',$aresult[1]);
-			    $this->setVersion($aversion[0]);
-		    }
-		    else {
-			    $aversion = explode(' ',stristr($resultant,'opera'));
-			    $this->setVersion(isset($aversion[1])?$aversion[1]:"");
-		    }
-		    $this->_browser_name = self::BROWSER_OPERA;
-		    return true;
-	    }
-		return false;
-    }
-
-    /**
-     * Determine if the browser is Chrome or not (last updated 1.7)
-     * @return boolean True if the browser is Chrome otherwise false
-     */
-    protected function checkBrowserChrome() {
-	    if( stripos($this->_agent,'Chrome') !== false ) {
-		    $aresult = explode('/',stristr($this->_agent,'Chrome'));
-		    $aversion = explode(' ',$aresult[1]);
-		    $this->setVersion($aversion[0]);
-		    $this->setBrowser(self::BROWSER_CHROME);
-		    return true;
-	    }
-	    return false;
-    }
-
-
-    /**
-     * Determine if the browser is WebTv or not (last updated 1.7)
-     * @return boolean True if the browser is WebTv otherwise false
-     */
-    protected function checkBrowserWebTv() {
-	    if( stripos($this->_agent,'webtv') !== false ) {
-		    $aresult = explode('/',stristr($this->_agent,'webtv'));
-		    $aversion = explode(' ',$aresult[1]);
-		    $this->setVersion($aversion[0]);
-		    $this->setBrowser(self::BROWSER_WEBTV);
-		    return true;
-	    }
-	    return false;
-    }
-
-    /**
-     * Determine if the browser is NetPositive or not (last updated 1.7)
-     * @return boolean True if the browser is NetPositive otherwise false
-     */
-    protected function checkBrowserNetPositive() {
-	    if( stripos($this->_agent,'NetPositive') !== false ) {
-		    $aresult = explode('/',stristr($this->_agent,'NetPositive'));
-		    $aversion = explode(' ',$aresult[1]);
-		    $this->setVersion(str_replace(array('(',')',';'),'',$aversion[0]));
-		    $this->setBrowser(self::BROWSER_NETPOSITIVE);
-		    return true;
-	    }
-	    return false;
-    }
-
-    /**
-     * Determine if the browser is Galeon or not (last updated 1.7)
-     * @return boolean True if the browser is Galeon otherwise false
-     */
-    protected function checkBrowserGaleon() {
-	    if( stripos($this->_agent,'galeon') !== false ) {
-		    $aresult = explode(' ',stristr($this->_agent,'galeon'));
-		    $aversion = explode('/',$aresult[0]);
-		    $this->setVersion($aversion[1]);
-		    $this->setBrowser(self::BROWSER_GALEON);
-		    return true;
-	    }
-	    return false;
-    }
-
-    /**
-     * Determine if the browser is Konqueror or not (last updated 1.7)
-     * @return boolean True if the browser is Konqueror otherwise false
-     */
-    protected function checkBrowserKonqueror() {
-	    if( stripos($this->_agent,'Konqueror') !== false ) {
-		    $aresult = explode(' ',stristr($this->_agent,'Konqueror'));
-		    $aversion = explode('/',$aresult[0]);
-		    $this->setVersion($aversion[1]);
-		    $this->setBrowser(self::BROWSER_KONQUEROR);
-		    return true;
-	    }
-	    return false;
-    }
-
-    /**
-     * Determine if the browser is iCab or not (last updated 1.7)
-     * @return boolean True if the browser is iCab otherwise false
-     */
-    protected function checkBrowserIcab() {
-	    if( stripos($this->_agent,'icab') !== false ) {
-		    $aversion = explode(' ',stristr(str_replace('/',' ',$this->_agent),'icab'));
-		    $this->setVersion($aversion[1]);
-		    $this->setBrowser(self::BROWSER_ICAB);
-		    return true;
-	    }
-	    return false;
-    }
-
-    /**
-     * Determine if the browser is OmniWeb or not (last updated 1.7)
-     * @return boolean True if the browser is OmniWeb otherwise false
-     */
-    protected function checkBrowserOmniWeb() {
-	    if( stripos($this->_agent,'omniweb') !== false ) {
-		    $aresult = explode('/',stristr($this->_agent,'omniweb'));
-		    $aversion = explode(' ',isset($aresult[1])?$aresult[1]:"");
-		    $this->setVersion($aversion[0]);
-		    $this->setBrowser(self::BROWSER_OMNIWEB);
-		    return true;
-	    }
-	    return false;
-    }
-
-    /**
-     * Determine if the browser is Phoenix or not (last updated 1.7)
-     * @return boolean True if the browser is Phoenix otherwise false
-     */
-    protected function checkBrowserPhoenix() {
-	    if( stripos($this->_agent,'Phoenix') !== false ) {
-		    $aversion = explode('/',stristr($this->_agent,'Phoenix'));
-		    $this->setVersion($aversion[1]);
-		    $this->setBrowser(self::BROWSER_PHOENIX);
-		    return true;
-	    }
-	    return false;
-    }
-
-    /**
-     * Determine if the browser is Firebird or not (last updated 1.7)
-     * @return boolean True if the browser is Firebird otherwise false
-     */
-    protected function checkBrowserFirebird() {
-	    if( stripos($this->_agent,'Firebird') !== false ) {
-		    $aversion = explode('/',stristr($this->_agent,'Firebird'));
-		    $this->setVersion($aversion[1]);
-		    $this->setBrowser(self::BROWSER_FIREBIRD);
-			return true;
-	    }
-	    return false;
-    }
-
-    /**
-     * Determine if the browser is Netscape Navigator 9+ or not (last updated 1.7)
-	 * NOTE: (http://browser.netscape.com/ - Official support ended on March 1st, 2008)
-     * @return boolean True if the browser is Netscape Navigator 9+ otherwise false
-     */
-    protected function checkBrowserNetscapeNavigator9Plus() {
-	    if( stripos($this->_agent,'Firefox') !== false && preg_match('/Navigator\/([^ ]*)/i',$this->_agent,$matches) ) {
-		    $this->setVersion($matches[1]);
-		    $this->setBrowser(self::BROWSER_NETSCAPE_NAVIGATOR);
-		    return true;
-	    }
-	    else if( stripos($this->_agent,'Firefox') === false && preg_match('/Netscape6?\/([^ ]*)/i',$this->_agent,$matches) ) {
-		    $this->setVersion($matches[1]);
-		    $this->setBrowser(self::BROWSER_NETSCAPE_NAVIGATOR);
-		    return true;
-	    }
-	    return false;
-    }
-
-    /**
-     * Determine if the browser is Shiretoko or not (https://wiki.mozilla.org/Projects/shiretoko) (last updated 1.7)
-     * @return boolean True if the browser is Shiretoko otherwise false
-     */
-    protected function checkBrowserShiretoko() {
-	    if( stripos($this->_agent,'Mozilla') !== false && preg_match('/Shiretoko\/([^ ]*)/i',$this->_agent,$matches) ) {
-		    $this->setVersion($matches[1]);
-		    $this->setBrowser(self::BROWSER_SHIRETOKO);
-		    return true;
-	    }
-	    return false;
-    }
-
-    /**
-     * Determine if the browser is Ice Cat or not (http://en.wikipedia.org/wiki/GNU_IceCat) (last updated 1.7)
-     * @return boolean True if the browser is Ice Cat otherwise false
-     */
-    protected function checkBrowserIceCat() {
-	    if( stripos($this->_agent,'Mozilla') !== false && preg_match('/IceCat\/([^ ]*)/i',$this->_agent,$matches) ) {
-		    $this->setVersion($matches[1]);
-		    $this->setBrowser(self::BROWSER_ICECAT);
-		    return true;
-	    }
-	    return false;
-    }
-
-    /**
-     * Determine if the browser is Nokia or not (last updated 1.7)
-     * @return boolean True if the browser is Nokia otherwise false
-     */
-    protected function checkBrowserNokia() {
-	    if( preg_match("/Nokia([^\/]+)\/([^ SP]+)/i",$this->_agent,$matches) ) {
-		    $this->setVersion($matches[2]);
-			if( stripos($this->_agent,'Series60') !== false || strpos($this->_agent,'S60') !== false ) {
-				$this->setBrowser(self::BROWSER_NOKIA_S60);
-			}
-			else {
-				$this->setBrowser( self::BROWSER_NOKIA );
-			}
-		    $this->setMobile(true);
-		    return true;
-	    }
-		return false;
-    }
-
-    /**
-     * Determine if the browser is Firefox or not (last updated 1.7)
-     * @return boolean True if the browser is Firefox otherwise false
-     */
-    protected function checkBrowserFirefox() {
-	    if( stripos($this->_agent,'safari') === false ) {
-			if( preg_match("/Firefox[\/ \(-]([^ ;\)]+)/i",$this->_agent,$matches) ) {
-				$this->setVersion($matches[1]);
-				$this->setBrowser(self::BROWSER_FIREFOX);
-				return true;
-			}
-			else if( preg_match("/Firefox$/i",$this->_agent,$matches) ) {
-				$this->setVersion("");
-				$this->setBrowser(self::BROWSER_FIREFOX);
-				return true;
-			}
-                else if( preg_match("/Namoroka[\/ \(-]([^ ;\)]+)/i",$this->_agent,$matches) ) {
-                    $this->setVersion($matches[1]);
-                    $this->setBrowser(self::BROWSER_FIREFOX);
-                    return true;
-                }
-		}
-	    return false;
-    }
-
-	/**
-     * Determine if the browser is Firefox or not (last updated 1.7)
-     * @return boolean True if the browser is Firefox otherwise false
-     */
-    protected function checkBrowserIceweasel() {
-		if( stripos($this->_agent,'Iceweasel') !== false ) {
-			$aresult = explode('/',stristr($this->_agent,'Iceweasel'));
-			$aversion = explode(' ',$aresult[1]);
-			$this->setVersion($aversion[0]);
-			$this->setBrowser(self::BROWSER_ICEWEASEL);
-			return true;
-		}
-		return false;
-	}
-    /**
-     * Determine if the browser is Mozilla or not (last updated 1.7)
-     * @return boolean True if the browser is Mozilla otherwise false
-     */
-    protected function checkBrowserMozilla() {
-	    if( stripos($this->_agent,'mozilla') !== false  && preg_match('/rv:[0-9].[0-9][a-b]?/i',$this->_agent) && stripos($this->_agent,'netscape') === false) {
-		    $aversion = explode(' ',stristr($this->_agent,'rv:'));
-		    preg_match('/rv:[0-9].[0-9][a-b]?/i',$this->_agent,$aversion);
-		    $this->setVersion(str_replace('rv:','',$aversion[0]));
-		    $this->setBrowser(self::BROWSER_MOZILLA);
-		    return true;
-	    }
-	    else if( stripos($this->_agent,'mozilla') !== false && preg_match('/rv:[0-9]\.[0-9]/i',$this->_agent) && stripos($this->_agent,'netscape') === false ) {
-		    $aversion = explode('',stristr($this->_agent,'rv:'));
-		    $this->setVersion(str_replace('rv:','',$aversion[0]));
-		    $this->setBrowser(self::BROWSER_MOZILLA);
-		    return true;
-	    }
-	    else if( stripos($this->_agent,'mozilla') !== false  && preg_match('/mozilla\/([^ ]*)/i',$this->_agent,$matches) && stripos($this->_agent,'netscape') === false ) {
-		    $this->setVersion($matches[1]);
-		    $this->setBrowser(self::BROWSER_MOZILLA);
-		    return true;
-	    }
-		return false;
-    }
-
-    /**
-     * Determine if the browser is Lynx or not (last updated 1.7)
-     * @return boolean True if the browser is Lynx otherwise false
-     */
-    protected function checkBrowserLynx() {
-	    if( stripos($this->_agent,'lynx') !== false ) {
-		    $aresult = explode('/',stristr($this->_agent,'Lynx'));
-		    $aversion = explode(' ',(isset($aresult[1])?$aresult[1]:""));
-		    $this->setVersion($aversion[0]);
-		    $this->setBrowser(self::BROWSER_LYNX);
-		    return true;
-	    }
-	    return false;
-    }
-
-    /**
-     * Determine if the browser is Amaya or not (last updated 1.7)
-     * @return boolean True if the browser is Amaya otherwise false
-     */
-    protected function checkBrowserAmaya() {
-	    if( stripos($this->_agent,'amaya') !== false ) {
-		    $aresult = explode('/',stristr($this->_agent,'Amaya'));
-		    $aversion = explode(' ',$aresult[1]);
-		    $this->setVersion($aversion[0]);
-		    $this->setBrowser(self::BROWSER_AMAYA);
-		    return true;
-	    }
-	    return false;
-    }
-
-    /**
-     * Determine if the browser is Safari or not (last updated 1.7)
-     * @return boolean True if the browser is Safari otherwise false
-     */
-    protected function checkBrowserSafari() {
-	    if( stripos($this->_agent,'Safari') !== false && stripos($this->_agent,'iPhone') === false && stripos($this->_agent,'iPod') === false ) {
-		    $aresult = explode('/',stristr($this->_agent,'Version'));
-		    if( isset($aresult[1]) ) {
-			    $aversion = explode(' ',$aresult[1]);
-			    $this->setVersion($aversion[0]);
-		    }
-		    else {
-			    $this->setVersion(self::VERSION_UNKNOWN);
-		    }
-		    $this->setBrowser(self::BROWSER_SAFARI);
-		    return true;
-	    }
-	    return false;
-    }
-
-    /**
-     * Determine if the browser is iPhone or not (last updated 1.7)
-     * @return boolean True if the browser is iPhone otherwise false
-     */
-    protected function checkBrowseriPhone() {
-	    if( stripos($this->_agent,'iPhone') !== false ) {
-		    $aresult = explode('/',stristr($this->_agent,'Version'));
-		    if( isset($aresult[1]) ) {
-			    $aversion = explode(' ',$aresult[1]);
-			    $this->setVersion($aversion[0]);
-		    }
-		    else {
-			    $this->setVersion(self::VERSION_UNKNOWN);
-		    }
-		    $this->setMobile(true);
-		    $this->setBrowser(self::BROWSER_IPHONE);
-		    return true;
-	    }
-	    return false;
-    }
-
-    /**
-     * Determine if the browser is iPod or not (last updated 1.7)
-     * @return boolean True if the browser is iPod otherwise false
-     */
-    protected function checkBrowseriPad() {
-	    if( stripos($this->_agent,'iPad') !== false ) {
-		    $aresult = explode('/',stristr($this->_agent,'Version'));
-		    if( isset($aresult[1]) ) {
-			    $aversion = explode(' ',$aresult[1]);
-			    $this->setVersion($aversion[0]);
-		    }
-		    else {
-			    $this->setVersion(self::VERSION_UNKNOWN);
-		    }
-		    $this->setMobile(true);
-		    $this->setBrowser(self::BROWSER_IPAD);
-		    return true;
-	    }
-	    return false;
-    }
-
-    /**
-     * Determine if the browser is iPod or not (last updated 1.7)
-     * @return boolean True if the browser is iPod otherwise false
-     */
-    protected function checkBrowseriPod() {
-	    if( stripos($this->_agent,'iPod') !== false ) {
-		    $aresult = explode('/',stristr($this->_agent,'Version'));
-		    if( isset($aresult[1]) ) {
-			    $aversion = explode(' ',$aresult[1]);
-			    $this->setVersion($aversion[0]);
-		    }
-		    else {
-			    $this->setVersion(self::VERSION_UNKNOWN);
-		    }
-		    $this->setMobile(true);
-		    $this->setBrowser(self::BROWSER_IPOD);
-		    return true;
-	    }
-	    return false;
-    }
-
-    /**
-     * Determine if the browser is Android or not (last updated 1.7)
-     * @return boolean True if the browser is Android otherwise false
-     */
-    protected function checkBrowserAndroid() {
-	    if( stripos($this->_agent,'Android') !== false ) {
-		    $aresult = explode(' ',stristr($this->_agent,'Android'));
-		    if( isset($aresult[1]) ) {
-			    $aversion = explode(' ',$aresult[1]);
-			    $this->setVersion($aversion[0]);
-		    }
-		    else {
-			    $this->setVersion(self::VERSION_UNKNOWN);
-		    }
-		    $this->setMobile(true);
-		    $this->setBrowser(self::BROWSER_ANDROID);
-		    return true;
-	    }
-	    return false;
-    }
-
-    /**
-     * Determine the user's platform (last updated 1.7)
-     */
-    protected function checkPlatform() {
-	    if( stripos($this->_agent, 'windows') !== false ) {
-		    $this->_platform = self::PLATFORM_WINDOWS;
-	    }
-	    else if( stripos($this->_agent, 'iPad') !== false ) {
-		    $this->_platform = self::PLATFORM_IPAD;
-	    }
-	    else if( stripos($this->_agent, 'iPod') !== false ) {
-		    $this->_platform = self::PLATFORM_IPOD;
-	    }
-	    else if( stripos($this->_agent, 'iPhone') !== false ) {
-		    $this->_platform = self::PLATFORM_IPHONE;
-	    }
-	    elseif( stripos($this->_agent, 'mac') !== false ) {
-		    $this->_platform = self::PLATFORM_APPLE;
-	    }
-	    elseif( stripos($this->_agent, 'android') !== false ) {
-		    $this->_platform = self::PLATFORM_ANDROID;
-	    }
-	    elseif( stripos($this->_agent, 'linux') !== false ) {
-		    $this->_platform = self::PLATFORM_LINUX;
-	    }
-	    else if( stripos($this->_agent, 'Nokia') !== false ) {
-		    $this->_platform = self::PLATFORM_NOKIA;
-	    }
-	    else if( stripos($this->_agent, 'BlackBerry') !== false ) {
-		    $this->_platform = self::PLATFORM_BLACKBERRY;
-	    }
-	    elseif( stripos($this->_agent,'FreeBSD') !== false ) {
-		    $this->_platform = self::PLATFORM_FREEBSD;
-	    }
-	    elseif( stripos($this->_agent,'OpenBSD') !== false ) {
-		    $this->_platform = self::PLATFORM_OPENBSD;
-	    }
-	    elseif( stripos($this->_agent,'NetBSD') !== false ) {
-		    $this->_platform = self::PLATFORM_NETBSD;
-	    }
-	    elseif( stripos($this->_agent, 'OpenSolaris') !== false ) {
-		    $this->_platform = self::PLATFORM_OPENSOLARIS;
-	    }
-	    elseif( stripos($this->_agent, 'SunOS') !== false ) {
-		    $this->_platform = self::PLATFORM_SUNOS;
-	    }
-	    elseif( stripos($this->_agent, 'OS\/2') !== false ) {
-		    $this->_platform = self::PLATFORM_OS2;
-	    }
-	    elseif( stripos($this->_agent, 'BeOS') !== false ) {
-		    $this->_platform = self::PLATFORM_BEOS;
-	    }
-	    elseif( stripos($this->_agent, 'win') !== false ) {
-		    $this->_platform = self::PLATFORM_WINDOWS;
-	    }
-
-    }
-}
+<?php
+/**
+ * File: Browser.php
+ * Author: Chris Schuld (http://chrisschuld.com/)
+ * Last Modified: August 20th, 2010
+ * @version 1.9
+ * @package PegasusPHP
+ *
+ * Copyright (C) 2008-2010 Chris Schuld  (chris@chrisschuld.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details at:
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ *
+ * Typical Usage:
+ *
+ *   $browser = new Browser();
+ *   if( $browser->getBrowser() == Browser::BROWSER_FIREFOX && $browser->getVersion() >= 2 ) {
+ *    echo 'You have FireFox version 2 or greater';
+ *   }
+ *
+ * User Agents Sampled from: http://www.useragentstring.com/
+ *
+ * This implementation is based on the original work from Gary White
+ * http://apptools.com/phptools/browser/
+ * Git and Packagist info: https://github.com/cbschuld/Browser.php
+ */
+
+class Browser
+{
+    private $_agent = '';
+    private $_browser_name = '';
+    private $_version = '';
+    private $_platform = '';
+    private $_os = '';
+    private $_is_aol = false;
+    private $_is_mobile = false;
+    private $_is_tablet = false;
+    private $_is_robot = false;
+    private $_is_facebook = false;
+    private $_aol_version = '';
+
+    const BROWSER_UNKNOWN = 'unknown';
+    const VERSION_UNKNOWN = 'unknown';
+
+    const BROWSER_OPERA = 'Opera'; // http://www.opera.com/
+    const BROWSER_OPERA_MINI = 'Opera Mini'; // http://www.opera.com/mini/
+    const BROWSER_WEBTV = 'WebTV'; // http://www.webtv.net/pc/
+    const BROWSER_IE = 'Internet Explorer'; // http://www.microsoft.com/ie/
+    const BROWSER_POCKET_IE = 'Pocket Internet Explorer'; // http://en.wikipedia.org/wiki/Internet_Explorer_Mobile
+    const BROWSER_KONQUEROR = 'Konqueror'; // http://www.konqueror.org/
+    const BROWSER_ICAB = 'iCab'; // http://www.icab.de/
+    const BROWSER_OMNIWEB = 'OmniWeb'; // http://www.omnigroup.com/applications/omniweb/
+    const BROWSER_FIREBIRD = 'Firebird'; // http://www.ibphoenix.com/
+    const BROWSER_FIREFOX = 'Firefox'; // http://www.mozilla.com/en-US/firefox/firefox.html
+    const BROWSER_ICEWEASEL = 'Iceweasel'; // http://www.geticeweasel.org/
+    const BROWSER_SHIRETOKO = 'Shiretoko'; // http://wiki.mozilla.org/Projects/shiretoko
+    const BROWSER_MOZILLA = 'Mozilla'; // http://www.mozilla.com/en-US/
+    const BROWSER_AMAYA = 'Amaya'; // http://www.w3.org/Amaya/
+    const BROWSER_LYNX = 'Lynx'; // http://en.wikipedia.org/wiki/Lynx
+    const BROWSER_SAFARI = 'Safari'; // http://apple.com
+    const BROWSER_IPHONE = 'iPhone'; // http://apple.com
+    const BROWSER_IPOD = 'iPod'; // http://apple.com
+    const BROWSER_IPAD = 'iPad'; // http://apple.com
+    const BROWSER_CHROME = 'Chrome'; // http://www.google.com/chrome
+    const BROWSER_ANDROID = 'Android'; // http://www.android.com/
+    const BROWSER_GOOGLEBOT = 'GoogleBot'; // http://en.wikipedia.org/wiki/Googlebot
+    const BROWSER_SLURP = 'Yahoo! Slurp'; // http://en.wikipedia.org/wiki/Yahoo!_Slurp
+    const BROWSER_W3CVALIDATOR = 'W3C Validator'; // http://validator.w3.org/
+    const BROWSER_BLACKBERRY = 'BlackBerry'; // http://www.blackberry.com/
+    const BROWSER_ICECAT = 'IceCat'; // http://en.wikipedia.org/wiki/GNU_IceCat
+    const BROWSER_NOKIA_S60 = 'Nokia S60 OSS Browser'; // http://en.wikipedia.org/wiki/Web_Browser_for_S60
+    const BROWSER_NOKIA = 'Nokia Browser'; // * all other WAP-based browsers on the Nokia Platform
+    const BROWSER_MSN = 'MSN Browser'; // http://explorer.msn.com/
+    const BROWSER_MSNBOT = 'MSN Bot'; // http://search.msn.com/msnbot.htm
+    const BROWSER_BINGBOT = 'Bing Bot'; // http://en.wikipedia.org/wiki/Bingbot
+
+    const BROWSER_NETSCAPE_NAVIGATOR = 'Netscape Navigator'; // http://browser.netscape.com/ (DEPRECATED)
+    const BROWSER_GALEON = 'Galeon'; // http://galeon.sourceforge.net/ (DEPRECATED)
+    const BROWSER_NETPOSITIVE = 'NetPositive'; // http://en.wikipedia.org/wiki/NetPositive (DEPRECATED)
+    const BROWSER_PHOENIX = 'Phoenix'; // http://en.wikipedia.org/wiki/History_of_Mozilla_Firefox (DEPRECATED)
+
+    const PLATFORM_UNKNOWN = 'unknown';
+    const PLATFORM_WINDOWS = 'Windows';
+    const PLATFORM_WINDOWS_CE = 'Windows CE';
+    const PLATFORM_APPLE = 'Apple';
+    const PLATFORM_LINUX = 'Linux';
+    const PLATFORM_OS2 = 'OS/2';
+    const PLATFORM_BEOS = 'BeOS';
+    const PLATFORM_IPHONE = 'iPhone';
+    const PLATFORM_IPOD = 'iPod';
+    const PLATFORM_IPAD = 'iPad';
+    const PLATFORM_BLACKBERRY = 'BlackBerry';
+    const PLATFORM_NOKIA = 'Nokia';
+    const PLATFORM_FREEBSD = 'FreeBSD';
+    const PLATFORM_OPENBSD = 'OpenBSD';
+    const PLATFORM_NETBSD = 'NetBSD';
+    const PLATFORM_SUNOS = 'SunOS';
+    const PLATFORM_OPENSOLARIS = 'OpenSolaris';
+    const PLATFORM_ANDROID = 'Android';
+
+    const OPERATING_SYSTEM_UNKNOWN = 'unknown';
+
+    public function Browser($userAgent = "")
+    {
+        $this->reset();
+        if ($userAgent != "") {
+            $this->setUserAgent($userAgent);
+        } else {
+            $this->determine();
+        }
+    }
+
+    /**
+     * Reset all properties
+     */
+    public function reset()
+    {
+        $this->_agent = isset($_SERVER['HTTP_USER_AGENT']) ? $_SERVER['HTTP_USER_AGENT'] : "";
+        $this->_browser_name = self::BROWSER_UNKNOWN;
+        $this->_version = self::VERSION_UNKNOWN;
+        $this->_platform = self::PLATFORM_UNKNOWN;
+        $this->_os = self::OPERATING_SYSTEM_UNKNOWN;
+        $this->_is_aol = false;
+        $this->_is_mobile = false;
+        $this->_is_tablet = false;
+        $this->_is_robot = false;
+        $this->_is_facebook = false;
+        $this->_aol_version = self::VERSION_UNKNOWN;
+    }
+
+    /**
+     * Check to see if the specific browser is valid
+     * @param string $browserName
+     * @return bool True if the browser is the specified browser
+     */
+    function isBrowser($browserName)
+    {
+        return (0 == strcasecmp($this->_browser_name, trim($browserName)));
+    }
+
+    /**
+     * The name of the browser.  All return types are from the class contants
+     * @return string Name of the browser
+     */
+    public function getBrowser()
+    {
+        return $this->_browser_name;
+    }
+
+    /**
+     * Set the name of the browser
+     * @param $browser string The name of the Browser
+     */
+    public function setBrowser($browser)
+    {
+        $this->_browser_name = $browser;
+    }
+
+    /**
+     * The name of the platform.  All return types are from the class contants
+     * @return string Name of the browser
+     */
+    public function getPlatform()
+    {
+        return $this->_platform;
+    }
+
+    /**
+     * Set the name of the platform
+     * @param string $platform The name of the Platform
+     */
+    public function setPlatform($platform)
+    {
+        $this->_platform = $platform;
+    }
+
+    /**
+     * The version of the browser.
+     * @return string Version of the browser (will only contain alpha-numeric characters and a period)
+     */
+    public function getVersion()
+    {
+        return $this->_version;
+    }
+
+    /**
+     * Set the version of the browser
+     * @param string $version The version of the Browser
+     */
+    public function setVersion($version)
+    {
+        $this->_version = preg_replace('/[^0-9,.,a-z,A-Z-]/', '', $version);
+    }
+
+    /**
+     * The version of AOL.
+     * @return string Version of AOL (will only contain alpha-numeric characters and a period)
+     */
+    public function getAolVersion()
+    {
+        return $this->_aol_version;
+    }
+
+    /**
+     * Set the version of AOL
+     * @param string $version The version of AOL
+     */
+    public function setAolVersion($version)
+    {
+        $this->_aol_version = preg_replace('/[^0-9,.,a-z,A-Z]/', '', $version);
+    }
+
+    /**
+     * Is the browser from AOL?
+     * @return boolean True if the browser is from AOL otherwise false
+     */
+    public function isAol()
+    {
+        return $this->_is_aol;
+    }
+
+    /**
+     * Is the browser from a mobile device?
+     * @return boolean True if the browser is from a mobile device otherwise false
+     */
+    public function isMobile()
+    {
+        return $this->_is_mobile;
+    }
+
+    /**
+     * Is the browser from a tablet device?
+     * @return boolean True if the browser is from a tablet device otherwise false
+     */
+    public function isTablet()
+    {
+        return $this->_is_tablet;
+    }
+
+    /**
+     * Is the browser from a robot (ex Slurp,GoogleBot)?
+     * @return boolean True if the browser is from a robot otherwise false
+     */
+    public function isRobot()
+    {
+        return $this->_is_robot;
+    }
+
+    /**
+    * Is the browser from facebook?
+    * @return boolean True if the browser is from facebook otherwise false
+    */
+    public function isFacebook() 
+    { 
+        return $this->_is_facebook;
+    }
+
+    /**
+     * Set the browser to be from AOL
+     * @param $isAol
+     */
+    public function setAol($isAol)
+    {
+        $this->_is_aol = $isAol;
+    }
+
+    /**
+     * Set the Browser to be mobile
+     * @param boolean $value is the browser a mobile browser or not
+     */
+    protected function setMobile($value = true)
+    {
+        $this->_is_mobile = $value;
+    }
+
+    /**
+     * Set the Browser to be tablet
+     * @param boolean $value is the browser a tablet browser or not
+     */
+    protected function setTablet($value = true)
+    {
+        $this->_is_tablet = $value;
+    }
+
+    /**
+     * Set the Browser to be a robot
+     * @param boolean $value is the browser a robot or not
+     */
+    protected function setRobot($value = true)
+    {
+        $this->_is_robot = $value;
+    }
+
+    /**
+     * Set the Browser to be a Facebook request
+     * @param boolean $value is the browser a robot or not
+     */
+    protected function setFacebook($value = true) 
+    { 
+        $this->_is_facebook = $value; 
+    }
+
+    /**
+     * Get the user agent value in use to determine the browser
+     * @return string The user agent from the HTTP header
+     */
+    public function getUserAgent()
+    {
+        return $this->_agent;
+    }
+
+    /**
+     * Set the user agent value (the construction will use the HTTP header value - this will overwrite it)
+     * @param string $agent_string The value for the User Agent
+     */
+    public function setUserAgent($agent_string)
+    {
+        $this->reset();
+        $this->_agent = $agent_string;
+        $this->determine();
+    }
+
+    /**
+     * Used to determine if the browser is actually "chromeframe"
+     * @since 1.7
+     * @return boolean True if the browser is using chromeframe
+     */
+    public function isChromeFrame()
+    {
+        return (strpos($this->_agent, "chromeframe") !== false);
+    }
+
+    /**
+     * Returns a formatted string with a summary of the details of the browser.
+     * @return string formatted string with a summary of the browser
+     */
+    public function __toString()
+    {
+        return "<strong>Browser Name:</strong> {$this->getBrowser()}<br/>\n" .
+        "<strong>Browser Version:</strong> {$this->getVersion()}<br/>\n" .
+        "<strong>Browser User Agent String:</strong> {$this->getUserAgent()}<br/>\n" .
+        "<strong>Platform:</strong> {$this->getPlatform()}<br/>";
+    }
+
+    /**
+     * Protected routine to calculate and determine what the browser is in use (including platform)
+     */
+    protected function determine()
+    {
+        $this->checkPlatform();
+        $this->checkBrowsers();
+        $this->checkForAol();
+    }
+
+    /**
+     * Protected routine to determine the browser type
+     * @return boolean True if the browser was detected otherwise false
+     */
+    protected function checkBrowsers()
+    {
+        return (
+            // well-known, well-used
+            // Special Notes:
+            // (1) Opera must be checked before FireFox due to the odd
+            //     user agents used in some older versions of Opera
+            // (2) WebTV is strapped onto Internet Explorer so we must
+            //     check for WebTV before IE
+            // (3) (deprecated) Galeon is based on Firefox and needs to be
+            //     tested before Firefox is tested
+            // (4) OmniWeb is based on Safari so OmniWeb check must occur
+            //     before Safari
+            // (5) Netscape 9+ is based on Firefox so Netscape checks
+            //     before FireFox are necessary
+            $this->checkBrowserWebTv() ||
+            $this->checkBrowserInternetExplorer() ||
+            $this->checkBrowserOpera() ||
+            $this->checkBrowserGaleon() ||
+            $this->checkBrowserNetscapeNavigator9Plus() ||
+            $this->checkBrowserFirefox() ||
+            $this->checkBrowserChrome() ||
+            $this->checkBrowserOmniWeb() ||
+
+            // common mobile
+            $this->checkBrowserAndroid() ||
+            $this->checkBrowseriPad() ||
+            $this->checkBrowseriPod() ||
+            $this->checkBrowseriPhone() ||
+            $this->checkBrowserBlackBerry() ||
+            $this->checkBrowserNokia() ||
+
+            // common bots
+            $this->checkBrowserGoogleBot() ||
+            $this->checkBrowserMSNBot() ||
+            $this->checkBrowserBingBot() ||
+            $this->checkBrowserSlurp() ||
+
+            // check for facebook external hit when loading URL
+            $this->checkFacebookExternalHit() ||
+
+            // WebKit base check (post mobile and others)
+            $this->checkBrowserSafari() ||
+
+            // everyone else
+            $this->checkBrowserNetPositive() ||
+            $this->checkBrowserFirebird() ||
+            $this->checkBrowserKonqueror() ||
+            $this->checkBrowserIcab() ||
+            $this->checkBrowserPhoenix() ||
+            $this->checkBrowserAmaya() ||
+            $this->checkBrowserLynx() ||
+            $this->checkBrowserShiretoko() ||
+            $this->checkBrowserIceCat() ||
+            $this->checkBrowserIceweasel() || 
+            $this->checkBrowserW3CValidator() ||
+            $this->checkBrowserMozilla() /* Mozilla is such an open standard that you must check it last */
+        );
+    }
+
+    /**
+     * Determine if the user is using a BlackBerry (last updated 1.7)
+     * @return boolean True if the browser is the BlackBerry browser otherwise false
+     */
+    protected function checkBrowserBlackBerry()
+    {
+        if (stripos($this->_agent, 'blackberry') !== false) {
+            $aresult = explode("/", stristr($this->_agent, "BlackBerry"));
+            $aversion = explode(' ', $aresult[1]);
+            $this->setVersion($aversion[0]);
+            $this->_browser_name = self::BROWSER_BLACKBERRY;
+            $this->setMobile(true);
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * Determine if the user is using an AOL User Agent (last updated 1.7)
+     * @return boolean True if the browser is from AOL otherwise false
+     */
+    protected function checkForAol()
+    {
+        $this->setAol(false);
+        $this->setAolVersion(self::VERSION_UNKNOWN);
+
+        if (stripos($this->_agent, 'aol') !== false) {
+            $aversion = explode(' ', stristr($this->_agent, 'AOL'));
+            $this->setAol(true);
+            $this->setAolVersion(preg_replace('/[^0-9\.a-z]/i', '', $aversion[1]));
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * Determine if the browser is the GoogleBot or not (last updated 1.7)
+     * @return boolean True if the browser is the GoogletBot otherwise false
+     */
+    protected function checkBrowserGoogleBot()
+    {
+        if (stripos($this->_agent, 'googlebot') !== false) {
+            $aresult = explode('/', stristr($this->_agent, 'googlebot'));
+            $aversion = explode(' ', $aresult[1]);
+            $this->setVersion(str_replace(';', '', $aversion[0]));
+            $this->_browser_name = self::BROWSER_GOOGLEBOT;
+            $this->setRobot(true);
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * Determine if the browser is the MSNBot or not (last updated 1.9)
+     * @return boolean True if the browser is the MSNBot otherwise false
+     */
+    protected function checkBrowserMSNBot()
+    {
+        if (stripos($this->_agent, "msnbot") !== false) {
+            $aresult = explode("/", stristr($this->_agent, "msnbot"));
+            $aversion = explode(" ", $aresult[1]);
+            $this->setVersion(str_replace(";", "", $aversion[0]));
+            $this->_browser_name = self::BROWSER_MSNBOT;
+            $this->setRobot(true);
+            return true;
+        }
+        return false;
+    }
+    
+    /**
+     * Determine if the browser is the BingBot or not (last updated 1.9)
+     * @return boolean True if the browser is the BingBot otherwise false
+     */
+    protected function checkBrowserBingBot()
+    {
+        if (stripos($this->_agent, "bingbot") !== false) {
+            $aresult = explode("/", stristr($this->_agent, "bingbot"));
+            $aversion = explode(" ", $aresult[1]);
+            $this->setVersion(str_replace(";", "", $aversion[0]));
+            $this->_browser_name = self::BROWSER_BINGBOT;
+            $this->setRobot(true);
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * Determine if the browser is the W3C Validator or not (last updated 1.7)
+     * @return boolean True if the browser is the W3C Validator otherwise false
+     */
+    protected function checkBrowserW3CValidator()
+    {
+        if (stripos($this->_agent, 'W3C-checklink') !== false) {
+            $aresult = explode('/', stristr($this->_agent, 'W3C-checklink'));
+            $aversion = explode(' ', $aresult[1]);
+            $this->setVersion($aversion[0]);
+            $this->_browser_name = self::BROWSER_W3CVALIDATOR;
+            return true;
+        } else if (stripos($this->_agent, 'W3C_Validator') !== false) {
+            // Some of the Validator versions do not delineate w/ a slash - add it back in
+            $ua = str_replace("W3C_Validator ", "W3C_Validator/", $this->_agent);
+            $aresult = explode('/', stristr($ua, 'W3C_Validator'));
+            $aversion = explode(' ', $aresult[1]);
+            $this->setVersion($aversion[0]);
+            $this->_browser_name = self::BROWSER_W3CVALIDATOR;
+            return true;
+        } else if (stripos($this->_agent, 'W3C-mobileOK') !== false) {
+            $this->_browser_name = self::BROWSER_W3CVALIDATOR;
+            $this->setMobile(true);
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * Determine if the browser is the Yahoo! Slurp Robot or not (last updated 1.7)
+     * @return boolean True if the browser is the Yahoo! Slurp Robot otherwise false
+     */
+    protected function checkBrowserSlurp()
+    {
+        if (stripos($this->_agent, 'slurp') !== false) {
+            $aresult = explode('/', stristr($this->_agent, 'Slurp'));
+            $aversion = explode(' ', $aresult[1]);
+            $this->setVersion($aversion[0]);
+            $this->_browser_name = self::BROWSER_SLURP;
+            $this->setRobot(true);
+            $this->setMobile(false);
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * Determine if the browser is Internet Explorer or not (last updated 1.7)
+     * @return boolean True if the browser is Internet Explorer otherwise false
+     */
+    protected function checkBrowserInternetExplorer()
+    {
+
+        // Test for v1 - v1.5 IE
+        if (stripos($this->_agent, 'microsoft internet explorer') !== false) {
+            $this->setBrowser(self::BROWSER_IE);
+            $this->setVersion('1.0');
+            $aresult = stristr($this->_agent, '/');
+            if (preg_match('/308|425|426|474|0b1/i', $aresult)) {
+                $this->setVersion('1.5');
+            }
+            return true;
+        } // Test for versions > 1.5
+        else if (stripos($this->_agent, 'msie') !== false && stripos($this->_agent, 'opera') === false) {
+            // See if the browser is the odd MSN Explorer
+            if (stripos($this->_agent, 'msnb') !== false) {
+                $aresult = explode(' ', stristr(str_replace(';', '; ', $this->_agent), 'MSN'));
+                $this->setBrowser(self::BROWSER_MSN);
+                $this->setVersion(str_replace(array('(', ')', ';'), '', $aresult[1]));
+                return true;
+            }
+            $aresult = explode(' ', stristr(str_replace(';', '; ', $this->_agent), 'msie'));
+            $this->setBrowser(self::BROWSER_IE);
+            $this->setVersion(str_replace(array('(', ')', ';'), '', $aresult[1]));
+            if(stripos($this->_agent, 'IEMobile') !== false) {
+                $this->setBrowser(self::BROWSER_POCKET_IE);
+                $this->setMobile(true);
+            }
+            return true;
+        } // Test for versions > IE 10
+		else if(stripos($this->_agent, 'trident') !== false) {
+			$this->setBrowser(self::BROWSER_IE);
+			$result = explode('rv:', $this->_agent);
+			$this->setVersion(preg_replace('/[^0-9.]+/', '', $result[1]));
+			$this->_agent = str_replace(array("Mozilla", "Gecko"), "MSIE", $this->_agent);
+		} // Test for Pocket IE
+        else if (stripos($this->_agent, 'mspie') !== false || stripos($this->_agent, 'pocket') !== false) {
+            $aresult = explode(' ', stristr($this->_agent, 'mspie'));
+            $this->setPlatform(self::PLATFORM_WINDOWS_CE);
+            $this->setBrowser(self::BROWSER_POCKET_IE);
+            $this->setMobile(true);
+
+            if (stripos($this->_agent, 'mspie') !== false) {
+                $this->setVersion($aresult[1]);
+            } else {
+                $aversion = explode('/', $this->_agent);
+                $this->setVersion($aversion[1]);
+            }
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * Determine if the browser is Opera or not (last updated 1.7)
+     * @return boolean True if the browser is Opera otherwise false
+     */
+    protected function checkBrowserOpera()
+    {
+        if (stripos($this->_agent, 'opera mini') !== false) {
+            $resultant = stristr($this->_agent, 'opera mini');
+            if (preg_match('/\//', $resultant)) {
+                $aresult = explode('/', $resultant);
+                $aversion = explode(' ', $aresult[1]);
+                $this->setVersion($aversion[0]);
+            } else {
+                $aversion = explode(' ', stristr($resultant, 'opera mini'));
+                $this->setVersion($aversion[1]);
+            }
+            $this->_browser_name = self::BROWSER_OPERA_MINI;
+            $this->setMobile(true);
+            return true;
+        } else if (stripos($this->_agent, 'opera') !== false) {
+            $resultant = stristr($this->_agent, 'opera');
+            if (preg_match('/Version\/(1*.*)$/', $resultant, $matches)) {
+                $this->setVersion($matches[1]);
+            } else if (preg_match('/\//', $resultant)) {
+                $aresult = explode('/', str_replace("(", " ", $resultant));
+                $aversion = explode(' ', $aresult[1]);
+                $this->setVersion($aversion[0]);
+            } else {
+                $aversion = explode(' ', stristr($resultant, 'opera'));
+                $this->setVersion(isset($aversion[1]) ? $aversion[1] : "");
+            }
+            if (stripos($this->_agent, 'Opera Mobi') !== false) {
+                $this->setMobile(true);
+            }
+            $this->_browser_name = self::BROWSER_OPERA;
+            return true;
+        } else if (stripos($this->_agent, 'OPR') !== false) {
+            $resultant = stristr($this->_agent, 'OPR');
+            if (preg_match('/\//', $resultant)) {
+                $aresult = explode('/', str_replace("(", " ", $resultant));
+                $aversion = explode(' ', $aresult[1]);
+                $this->setVersion($aversion[0]);
+            }
+            if (stripos($this->_agent, 'Mobile') !== false) {
+                $this->setMobile(true);
+            }
+            $this->_browser_name = self::BROWSER_OPERA;
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * Determine if the browser is Chrome or not (last updated 1.7)
+     * @return boolean True if the browser is Chrome otherwise false
+     */
+    protected function checkBrowserChrome()
+    {
+        if (stripos($this->_agent, 'Chrome') !== false) {
+            $aresult = explode('/', stristr($this->_agent, 'Chrome'));
+            $aversion = explode(' ', $aresult[1]);
+            $this->setVersion($aversion[0]);
+            $this->setBrowser(self::BROWSER_CHROME);
+            //Chrome on Android
+            if (stripos($this->_agent, 'Android') !== false) {
+                if (stripos($this->_agent, 'Mobile') !== false) {
+                    $this->setMobile(true);
+                } else {
+                    $this->setTablet(true);
+                }
+            }
+            return true;
+        }
+        return false;
+    }
+
+
+    /**
+     * Determine if the browser is WebTv or not (last updated 1.7)
+     * @return boolean True if the browser is WebTv otherwise false
+     */
+    protected function checkBrowserWebTv()
+    {
+        if (stripos($this->_agent, 'webtv') !== false) {
+            $aresult = explode('/', stristr($this->_agent, 'webtv'));
+            $aversion = explode(' ', $aresult[1]);
+            $this->setVersion($aversion[0]);
+            $this->setBrowser(self::BROWSER_WEBTV);
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * Determine if the browser is NetPositive or not (last updated 1.7)
+     * @return boolean True if the browser is NetPositive otherwise false
+     */
+    protected function checkBrowserNetPositive()
+    {
+        if (stripos($this->_agent, 'NetPositive') !== false) {
+            $aresult = explode('/', stristr($this->_agent, 'NetPositive'));
+            $aversion = explode(' ', $aresult[1]);
+            $this->setVersion(str_replace(array('(', ')', ';'), '', $aversion[0]));
+            $this->setBrowser(self::BROWSER_NETPOSITIVE);
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * Determine if the browser is Galeon or not (last updated 1.7)
+     * @return boolean True if the browser is Galeon otherwise false
+     */
+    protected function checkBrowserGaleon()
+    {
+        if (stripos($this->_agent, 'galeon') !== false) {
+            $aresult = explode(' ', stristr($this->_agent, 'galeon'));
+            $aversion = explode('/', $aresult[0]);
+            $this->setVersion($aversion[1]);
+            $this->setBrowser(self::BROWSER_GALEON);
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * Determine if the browser is Konqueror or not (last updated 1.7)
+     * @return boolean True if the browser is Konqueror otherwise false
+     */
+    protected function checkBrowserKonqueror()
+    {
+        if (stripos($this->_agent, 'Konqueror') !== false) {
+            $aresult = explode(' ', stristr($this->_agent, 'Konqueror'));
+            $aversion = explode('/', $aresult[0]);
+            $this->setVersion($aversion[1]);
+            $this->setBrowser(self::BROWSER_KONQUEROR);
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * Determine if the browser is iCab or not (last updated 1.7)
+     * @return boolean True if the browser is iCab otherwise false
+     */
+    protected function checkBrowserIcab()
+    {
+        if (stripos($this->_agent, 'icab') !== false) {
+            $aversion = explode(' ', stristr(str_replace('/', ' ', $this->_agent), 'icab'));
+            $this->setVersion($aversion[1]);
+            $this->setBrowser(self::BROWSER_ICAB);
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * Determine if the browser is OmniWeb or not (last updated 1.7)
+     * @return boolean True if the browser is OmniWeb otherwise false
+     */
+    protected function checkBrowserOmniWeb()
+    {
+        if (stripos($this->_agent, 'omniweb') !== false) {
+            $aresult = explode('/', stristr($this->_agent, 'omniweb'));
+            $aversion = explode(' ', isset($aresult[1]) ? $aresult[1] : "");
+            $this->setVersion($aversion[0]);
+            $this->setBrowser(self::BROWSER_OMNIWEB);
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * Determine if the browser is Phoenix or not (last updated 1.7)
+     * @return boolean True if the browser is Phoenix otherwise false
+     */
+    protected function checkBrowserPhoenix()
+    {
+        if (stripos($this->_agent, 'Phoenix') !== false) {
+            $aversion = explode('/', stristr($this->_agent, 'Phoenix'));
+            $this->setVersion($aversion[1]);
+            $this->setBrowser(self::BROWSER_PHOENIX);
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * Determine if the browser is Firebird or not (last updated 1.7)
+     * @return boolean True if the browser is Firebird otherwise false
+     */
+    protected function checkBrowserFirebird()
+    {
+        if (stripos($this->_agent, 'Firebird') !== false) {
+            $aversion = explode('/', stristr($this->_agent, 'Firebird'));
+            $this->setVersion($aversion[1]);
+            $this->setBrowser(self::BROWSER_FIREBIRD);
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * Determine if the browser is Netscape Navigator 9+ or not (last updated 1.7)
+     * NOTE: (http://browser.netscape.com/ - Official support ended on March 1st, 2008)
+     * @return boolean True if the browser is Netscape Navigator 9+ otherwise false
+     */
+    protected function checkBrowserNetscapeNavigator9Plus()
+    {
+        if (stripos($this->_agent, 'Firefox') !== false && preg_match('/Navigator\/([^ ]*)/i', $this->_agent, $matches)) {
+            $this->setVersion($matches[1]);
+            $this->setBrowser(self::BROWSER_NETSCAPE_NAVIGATOR);
+            return true;
+        } else if (stripos($this->_agent, 'Firefox') === false && preg_match('/Netscape6?\/([^ ]*)/i', $this->_agent, $matches)) {
+            $this->setVersion($matches[1]);
+            $this->setBrowser(self::BROWSER_NETSCAPE_NAVIGATOR);
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * Determine if the browser is Shiretoko or not (https://wiki.mozilla.org/Projects/shiretoko) (last updated 1.7)
+     * @return boolean True if the browser is Shiretoko otherwise false
+     */
+    protected function checkBrowserShiretoko()
+    {
+        if (stripos($this->_agent, 'Mozilla') !== false && preg_match('/Shiretoko\/([^ ]*)/i', $this->_agent, $matches)) {
+            $this->setVersion($matches[1]);
+            $this->setBrowser(self::BROWSER_SHIRETOKO);
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * Determine if the browser is Ice Cat or not (http://en.wikipedia.org/wiki/GNU_IceCat) (last updated 1.7)
+     * @return boolean True if the browser is Ice Cat otherwise false
+     */
+    protected function checkBrowserIceCat()
+    {
+        if (stripos($this->_agent, 'Mozilla') !== false && preg_match('/IceCat\/([^ ]*)/i', $this->_agent, $matches)) {
+            $this->setVersion($matches[1]);
+            $this->setBrowser(self::BROWSER_ICECAT);
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * Determine if the browser is Nokia or not (last updated 1.7)
+     * @return boolean True if the browser is Nokia otherwise false
+     */
+    protected function checkBrowserNokia()
+    {
+        if (preg_match("/Nokia([^\/]+)\/([^ SP]+)/i", $this->_agent, $matches)) {
+            $this->setVersion($matches[2]);
+            if (stripos($this->_agent, 'Series60') !== false || strpos($this->_agent, 'S60') !== false) {
+                $this->setBrowser(self::BROWSER_NOKIA_S60);
+            } else {
+                $this->setBrowser(self::BROWSER_NOKIA);
+            }
+            $this->setMobile(true);
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * Determine if the browser is Firefox or not (last updated 1.7)
+     * @return boolean True if the browser is Firefox otherwise false
+     */
+    protected function checkBrowserFirefox()
+    {
+        if (stripos($this->_agent, 'safari') === false) {
+            if (preg_match("/Firefox[\/ \(]([^ ;\)]+)/i", $this->_agent, $matches)) {
+                $this->setVersion($matches[1]);
+                $this->setBrowser(self::BROWSER_FIREFOX);
+                //Firefox on Android
+                if (stripos($this->_agent, 'Android') !== false) {
+                    if (stripos($this->_agent, 'Mobile') !== false) {
+                        $this->setMobile(true);
+                    } else {
+                        $this->setTablet(true);
+                    }
+                }
+                return true;
+            } else if (preg_match("/Firefox$/i", $this->_agent, $matches)) {
+                $this->setVersion("");
+                $this->setBrowser(self::BROWSER_FIREFOX);
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Determine if the browser is Firefox or not (last updated 1.7)
+     * @return boolean True if the browser is Firefox otherwise false
+     */
+    protected function checkBrowserIceweasel()
+    {
+        if (stripos($this->_agent, 'Iceweasel') !== false) {
+            $aresult = explode('/', stristr($this->_agent, 'Iceweasel'));
+            $aversion = explode(' ', $aresult[1]);
+            $this->setVersion($aversion[0]);
+            $this->setBrowser(self::BROWSER_ICEWEASEL);
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * Determine if the browser is Mozilla or not (last updated 1.7)
+     * @return boolean True if the browser is Mozilla otherwise false
+     */
+    protected function checkBrowserMozilla()
+    {
+        if (stripos($this->_agent, 'mozilla') !== false && preg_match('/rv:[0-9].[0-9][a-b]?/i', $this->_agent) && stripos($this->_agent, 'netscape') === false) {
+            $aversion = explode(' ', stristr($this->_agent, 'rv:'));
+            preg_match('/rv:[0-9].[0-9][a-b]?/i', $this->_agent, $aversion);
+            $this->setVersion(str_replace('rv:', '', $aversion[0]));
+            $this->setBrowser(self::BROWSER_MOZILLA);
+            return true;
+        } else if (stripos($this->_agent, 'mozilla') !== false && preg_match('/rv:[0-9]\.[0-9]/i', $this->_agent) && stripos($this->_agent, 'netscape') === false) {
+            $aversion = explode('', stristr($this->_agent, 'rv:'));
+            $this->setVersion(str_replace('rv:', '', $aversion[0]));
+            $this->setBrowser(self::BROWSER_MOZILLA);
+            return true;
+        } else if (stripos($this->_agent, 'mozilla') !== false && preg_match('/mozilla\/([^ ]*)/i', $this->_agent, $matches) && stripos($this->_agent, 'netscape') === false) {
+            $this->setVersion($matches[1]);
+            $this->setBrowser(self::BROWSER_MOZILLA);
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * Determine if the browser is Lynx or not (last updated 1.7)
+     * @return boolean True if the browser is Lynx otherwise false
+     */
+    protected function checkBrowserLynx()
+    {
+        if (stripos($this->_agent, 'lynx') !== false) {
+            $aresult = explode('/', stristr($this->_agent, 'Lynx'));
+            $aversion = explode(' ', (isset($aresult[1]) ? $aresult[1] : ""));
+            $this->setVersion($aversion[0]);
+            $this->setBrowser(self::BROWSER_LYNX);
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * Determine if the browser is Amaya or not (last updated 1.7)
+     * @return boolean True if the browser is Amaya otherwise false
+     */
+    protected function checkBrowserAmaya()
+    {
+        if (stripos($this->_agent, 'amaya') !== false) {
+            $aresult = explode('/', stristr($this->_agent, 'Amaya'));
+            $aversion = explode(' ', $aresult[1]);
+            $this->setVersion($aversion[0]);
+            $this->setBrowser(self::BROWSER_AMAYA);
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * Determine if the browser is Safari or not (last updated 1.7)
+     * @return boolean True if the browser is Safari otherwise false
+     */
+    protected function checkBrowserSafari()
+    {
+        if (stripos($this->_agent, 'Safari') !== false
+            && stripos($this->_agent, 'iPhone') === false
+            && stripos($this->_agent, 'iPod') === false) {
+
+            $aresult = explode('/', stristr($this->_agent, 'Version'));
+            if (isset($aresult[1])) {
+                $aversion = explode(' ', $aresult[1]);
+                $this->setVersion($aversion[0]);
+            } else {
+                $this->setVersion(self::VERSION_UNKNOWN);
+            }
+            $this->setBrowser(self::BROWSER_SAFARI);
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * Detect if URL is loaded from FacebookExternalHit
+     * @return boolean True if it detects FacebookExternalHit otherwise false
+     */
+    protected function checkFacebookExternalHit()
+    {
+        if(stristr($this->_agent,'FacebookExternalHit'))
+        {
+            $this->setRobot(true);
+            $this->setFacebook(true);
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * Detect if URL is being loaded from internal Facebook browser
+     * @return boolean True if it detects internal Facebook browser otherwise false
+     */
+    protected function checkForFacebookIos()
+    {
+        if(stristr($this->_agent,'FBIOS'))
+        {
+            $this->setFacebook(true);
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * Detect Version for the Safari browser on iOS devices
+     * @return boolean True if it detects the version correctly otherwise false
+     */
+    protected function getSafariVersionOnIos() 
+    {
+        $aresult = explode('/',stristr($this->_agent,'Version'));
+        if( isset($aresult[1]) ) 
+        {
+            $aversion = explode(' ',$aresult[1]);
+            $this->setVersion($aversion[0]);
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * Detect Version for the Chrome browser on iOS devices
+     * @return boolean True if it detects the version correctly otherwise false
+     */
+    protected function getChromeVersionOnIos() 
+    {
+        $aresult = explode('/',stristr($this->_agent,'CriOS'));
+        if( isset($aresult[1]) ) 
+        {
+            $aversion = explode(' ',$aresult[1]);
+            $this->setVersion($aversion[0]);
+            $this->setBrowser(self::BROWSER_CHROME);
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * Determine if the browser is iPhone or not (last updated 1.7)
+     * @return boolean True if the browser is iPhone otherwise false
+     */
+    protected function checkBrowseriPhone() {
+        if( stripos($this->_agent,'iPhone') !== false ) {
+            $this->setVersion(self::VERSION_UNKNOWN);
+            $this->setBrowser(self::BROWSER_IPHONE);
+            $this->getSafariVersionOnIos();
+            $this->getChromeVersionOnIos();
+            $this->checkForFacebookIos();
+            $this->setMobile(true);
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * Determine if the browser is iPad or not (last updated 1.7)
+     * @return boolean True if the browser is iPad otherwise false
+     */
+    protected function checkBrowseriPad() {
+        if( stripos($this->_agent,'iPad') !== false ) {
+            $this->setVersion(self::VERSION_UNKNOWN);
+            $this->setBrowser(self::BROWSER_IPAD);
+            $this->getSafariVersionOnIos();
+            $this->getChromeVersionOnIos();
+            $this->checkForFacebookIos();
+            $this->setTablet(true);
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * Determine if the browser is iPod or not (last updated 1.7)
+     * @return boolean True if the browser is iPod otherwise false
+     */
+    protected function checkBrowseriPod() {
+        if( stripos($this->_agent,'iPod') !== false ) {
+            $this->setVersion(self::VERSION_UNKNOWN);
+            $this->setBrowser(self::BROWSER_IPOD);
+            $this->getSafariVersionOnIos();
+            $this->getChromeVersionOnIos();
+            $this->checkForFacebookIos();
+            $this->setMobile(true);
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * Determine if the browser is Android or not (last updated 1.7)
+     * @return boolean True if the browser is Android otherwise false
+     */
+    protected function checkBrowserAndroid()
+    {
+        if (stripos($this->_agent, 'Android') !== false) {
+            $aresult = explode(' ', stristr($this->_agent, 'Android'));
+            if (isset($aresult[1])) {
+                $aversion = explode(' ', $aresult[1]);
+                $this->setVersion($aversion[0]);
+            } else {
+                $this->setVersion(self::VERSION_UNKNOWN);
+            }
+            if (stripos($this->_agent, 'Mobile') !== false) {
+                $this->setMobile(true);
+            } else {
+                $this->setTablet(true);
+            }
+            $this->setBrowser(self::BROWSER_ANDROID);
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * Determine the user's platform (last updated 1.7)
+     */
+    protected function checkPlatform()
+    {
+        if (stripos($this->_agent, 'windows') !== false) 
+        {
+            $this->_platform = self::PLATFORM_WINDOWS;
+        } 
+        else if (stripos($this->_agent, 'iPad') !== false) 
+        {
+            $this->_platform = self::PLATFORM_IPAD;
+        } 
+        else if (stripos($this->_agent, 'iPod') !== false) 
+        {
+            $this->_platform = self::PLATFORM_IPOD;
+        } 
+        else if (stripos($this->_agent, 'iPhone') !== false) 
+        {
+            $this->_platform = self::PLATFORM_IPHONE;
+        } 
+        elseif (stripos($this->_agent, 'mac') !== false) 
+        {
+            $this->_platform = self::PLATFORM_APPLE;
+        } 
+        elseif (stripos($this->_agent, 'android') !== false) 
+        {
+            $this->_platform = self::PLATFORM_ANDROID;
+        } 
+        elseif (stripos($this->_agent, 'linux') !== false) 
+        {
+            $this->_platform = self::PLATFORM_LINUX;
+        } 
+        else if (stripos($this->_agent, 'Nokia') !== false) 
+        {
+            $this->_platform = self::PLATFORM_NOKIA;
+        } 
+        else if (stripos($this->_agent, 'BlackBerry') !== false) 
+        {
+            $this->_platform = self::PLATFORM_BLACKBERRY;
+        } 
+        elseif (stripos($this->_agent, 'FreeBSD') !== false) 
+        {
+            $this->_platform = self::PLATFORM_FREEBSD;
+        } 
+        elseif (stripos($this->_agent, 'OpenBSD') !== false) 
+        {
+            $this->_platform = self::PLATFORM_OPENBSD;
+        } 
+        elseif (stripos($this->_agent, 'NetBSD') !== false) 
+        {
+            $this->_platform = self::PLATFORM_NETBSD;
+        } 
+        elseif (stripos($this->_agent, 'OpenSolaris') !== false) 
+        {
+            $this->_platform = self::PLATFORM_OPENSOLARIS;
+        } 
+        elseif (stripos($this->_agent, 'SunOS') !== false) 
+        {
+            $this->_platform = self::PLATFORM_SUNOS;
+        } 
+        elseif (stripos($this->_agent, 'OS\/2') !== false) 
+        {
+            $this->_platform = self::PLATFORM_OS2;
+        } 
+        elseif (stripos($this->_agent, 'BeOS') !== false) 
+        {
+            $this->_platform = self::PLATFORM_BEOS;
+        } 
+        elseif (stripos($this->_agent, 'win') !== false) 
+        {
+            $this->_platform = self::PLATFORM_WINDOWS;
+        }
+
+    }
+}
+
+?>

+ 45 - 34
main/inc/lib/course_home.lib.php

@@ -105,13 +105,10 @@ class CourseHome
 
         foreach ($all_tools as & $tool) {
             if ($tool['image'] == 'scormbuilder.gif') {
-                // display links to lp only for current session
-                /* if (api_get_session_id() != $tool['session_id']) {
-                  continue;
-                  } */
                 // check if the published learnpath is visible for student
                 $published_lp_id = self::get_published_lp_id_from_link($tool['link']);
-                if (!api_is_allowed_to_edit(null, true) && !learnpath::is_lp_visible_for_student($published_lp_id, api_get_user_id())) {
+                if (!api_is_allowed_to_edit(null, true) &&
+                    !learnpath::is_lp_visible_for_student($published_lp_id, api_get_user_id(), api_get_course_id(), api_get_session_id())) {
                     continue;
                 }
             }
@@ -293,7 +290,8 @@ class CourseHome
                     // check if the published learnpath is visible for student
                     $published_lp_id = self::get_published_lp_id_from_link($tool['link']);
 
-                    if (!api_is_allowed_to_edit(null, true) && !learnpath::is_lp_visible_for_student($published_lp_id, api_get_user_id())) {
+                    if (!api_is_allowed_to_edit(null, true) &&
+                        !learnpath::is_lp_visible_for_student($published_lp_id, api_get_user_id(), api_get_course_id(), api_get_session_id())) {
                         continue;
                     }
                 }
@@ -460,7 +458,7 @@ class CourseHome
         $check = false;
 
         foreach ($list as $line) {
-            //Admin can see all tools even if the course_hide_tools configuration is set
+            // Admin can see all tools even if the course_hide_tools configuration is set
             if ($is_platform_admin) {
                 continue;
             }
@@ -471,21 +469,39 @@ class CourseHome
         }
 
         while ($temp_row = Database::fetch_assoc($result)) {
+            $add = false;
             if ($check) {
                 if (!in_array($temp_row['name'], $hide_list)) {
-                    $all_tools_list[] = $temp_row;
+                    $add = true;
                 }
             } else {
+                $add = true;
+            }
+
+            if ($temp_row['image'] == 'scormbuilder.gif') {
+                $lp_id = self::get_published_lp_id_from_link($temp_row['link']);
+                $lp = new learnpath(api_get_course_id(), $lp_id, api_get_user_id());
+                $path = $lp->get_preview_image_path(64);
+                $add = $lp->is_lp_visible_for_student(
+                    $lp_id,
+                    api_get_user_id(),
+                    api_get_course_id(),
+                    api_get_session_id()
+                );
+                if ($path) {
+                    $temp_row['custom_image'] = $path;
+                }
+            }
+
+            if ($add) {
                 $all_tools_list[] = $temp_row;
             }
         }
 
-        $i = 0;
         // Grabbing all the links that have the property on_homepage set to 1
         $course_link_table = Database::get_course_table(TABLE_LINK);
         $course_item_property_table = Database::get_course_table(TABLE_ITEM_PROPERTY);
 
-
         switch ($course_tool_category) {
             case TOOL_AUTHORING:
                 $sql_links = "SELECT tl.*, tip.visibility
@@ -622,16 +638,13 @@ class CourseHome
                 $tool['original_link'] = $tool['link'];
 
                 if ($tool['image'] == 'scormbuilder.gif') {
-                    // display links to lp only for current session
-                    /* if ($session_id != $tool['session_id']) {
-                      continue;
-                      } */
                     // check if the published learnpath is visible for student
                     $published_lp_id = self::get_published_lp_id_from_link($tool['link']);
                     if (api_is_allowed_to_edit(null, true)) {
                         $studentview = true;
                     }
-                    if (!api_is_allowed_to_edit(null, true) && !learnpath::is_lp_visible_for_student($published_lp_id, api_get_user_id())) {
+                    if (!api_is_allowed_to_edit(null, true) &&
+                        !learnpath::is_lp_visible_for_student($published_lp_id, api_get_user_id(), api_get_course_id(), api_get_session_id())) {
                         continue;
                     }
                 }
@@ -741,7 +754,7 @@ class CourseHome
                 // Creating title and the link
 
                 if (isset($tool['category']) && $tool['category'] == 'plugin') {
-                    $plugin_info = $app_plugin->getPluginInfo($tool['name']);
+                    $plugin_info = $app_plugin->get_plugin_info($tool['name']);
                     if (isset($plugin_info) && isset($plugin_info['title'])) {
                         $tool_name = $plugin_info['title'];
                     }
@@ -770,7 +783,6 @@ class CourseHome
         }
 
         $i = 0;
-
         $html = '';
 
         if (!empty($items)) {
@@ -781,28 +793,27 @@ class CourseHome
                         $html .= '<div class="span4 course-tool">';
                         $image = (substr($item['tool']['image'], 0, strpos($item['tool']['image'], '.'))).'.png';
 
-                        $original_image = Display::return_icon($image, $item['name'], array('id' => 'toolimage_'.$item['tool']['id']), ICON_SIZE_BIG, false);
-
-                        switch ($image) {
-                            case 'scormbuilder.png':
-                                $image = $original_image;
-                                $lp_id = self::get_published_lp_id_from_link($item['link']);
-                                if ($lp_id) {
-                                    $lp = new learnpath(api_get_course_id(), $lp_id, api_get_user_id());
-                                    $path = $lp->get_preview_image_path(64);
-                                    if ($path) {
-                                        $image = '<img src="'.$path.'">';
-                                    }
-                                }
-                                break;
-                            default:
-                                $image = $original_image;
+                        if (isset($item['tool']['custom_image'])) {
+                            $original_image = Display::img(
+                                $item['tool']['custom_image'],
+                                $item['name'],
+                                array('id' => 'toolimage_'.$item['tool']['id'])
+                            );
+                        } else {
+                            $original_image = Display::return_icon(
+                                $image,
+                                $item['name'],
+                                array('id' => 'toolimage_'.$item['tool']['id']),
+                                ICON_SIZE_BIG,
+                                false
+                            );
                         }
 
-                        $data .= Display::url($image, $item['url_params']['href'], $item['url_params']);
+                        $data .= Display::url($original_image, $item['url_params']['href'], $item['url_params']);
                         $html .= Display::div($data, array('class' => 'big_icon')); //box-image reflection
                         $html .= Display::div('<h4>'.$item['visibility'].$item['extra'].$item['link'].'</h4>', array('class' => 'content'));
                         $html .= '</div>';
+
                         break;
                     case 'activity':
                         $html .= '<div class="offset2 span4 course-tool">';

+ 6 - 1
main/inc/lib/display.lib.php

@@ -60,7 +60,12 @@ class Display
      */
     public static function display_header($tool_name ='', $help = null, $page_header = null)
     {
-        self::$global_template = new Template($tool_name);
+        $origin = api_get_origin();
+        $showHeader = true;
+        if (isset($origin) && $origin == 'learnpath') {
+            $showHeader = false;
+        }
+        self::$global_template = new Template($tool_name, $showHeader, $showHeader);
 
         // Fixing tools with any help it takes xxx part of main/xxx/index.php
         if (empty($help)) {

+ 4 - 3
main/inc/lib/document.lib.php

@@ -1833,7 +1833,6 @@ class DocumentManager
         $attributes = array();
         $wanted_attributes = array('src', 'url', '@import', 'href', 'value', 'flashvars');
         $explode_attributes = array('flashvars' => 'file');
-
         $abs_path = '';
 
         if ($recursivity > $max) {
@@ -1869,6 +1868,8 @@ class DocumentManager
             }
         }
 
+        $files_list = array();
+
         switch ($type) {
             case TOOL_DOCUMENT :
             case TOOL_QUIZ:
@@ -2482,7 +2483,7 @@ class DocumentManager
      * @param string $title
      * @param string $comment
      * @param int $unzip unzip or not the file
-     * @param int $if_exists if_exists overwrite, rename or warn if exists (default)
+     * @param string $if_exists overwrite, rename or warn (default)
      * @param bool $index_document index document (search xapian module)
      * @param bool $show_output print html messages
      * @return array|bool
@@ -2532,7 +2533,7 @@ class DocumentManager
                         if (!empty($title)) {
                             $params['title'] = get_document_title($title);
                         } else {
-                            if (isset($if_exists) && $if_exists == 'rename') {
+                            if ($if_exists == 'rename') {
                                 $new_path = basename($new_path);
                                 $params['title'] = get_document_title($new_path);
                             } else {

+ 64 - 30
main/inc/lib/events.lib.inc.php

@@ -125,17 +125,17 @@ function event_access_course() {
     }
     $sql = "INSERT INTO ".$TABLETRACK_ACCESS."  (access_user_id, access_cours_code, access_date, access_session_id) VALUES
             (".$user_id.", '".$_cid."', '".$now."','".$id_session."')";
-    $res = Database::query($sql);
+    Database::query($sql);
 
     // added for "what's new" notification
     $sql = "UPDATE $TABLETRACK_LASTACCESS  SET access_date = '$now'
             WHERE access_user_id = $user_id AND access_cours_code = '$_cid' AND access_tool IS NULL AND access_session_id=".$id_session;
-    $res = Database::query($sql);
+    Database::query($sql);
 
     if (Database::affected_rows() == 0) {
         $sql = "INSERT INTO $TABLETRACK_LASTACCESS (access_user_id, access_cours_code, access_date, access_session_id)
                 VALUES (".$user_id.", '".$_cid."', '$now', '".$id_session."')";
-        $res = Database::query($sql);
+        Database::query($sql);
     }
     // end "what's new" notification
     return 1;
@@ -191,17 +191,17 @@ function event_access_tool($tool, $id_session = 0)
         			'".$tool."',
         			'".$reallyNow."',
         			'".$id_session."')";
-        $res = Database::query($sql);
+        Database::query($sql);
     }
     // "what's new" notification
     $sql = "UPDATE $TABLETRACK_LASTACCESS
         	SET access_date = '$reallyNow'
         	WHERE access_user_id = ".$user_id." AND access_cours_code = '".$_cid."' AND access_tool = '".$tool."' AND access_session_id=".$id_session;
-    $res = Database::query($sql);
+    Database::query($sql);
     if (Database::affected_rows() == 0) {
         $sql = "INSERT INTO $TABLETRACK_LASTACCESS (access_user_id,access_cours_code,access_tool, access_date, access_session_id)
         		VALUES (".$user_id.", '".$_cid."' , '$tool', '$reallyNow', $id_session)";
-        $res = Database::query($sql);
+        Database::query($sql);
     }
     return 1;
 }
@@ -270,7 +270,7 @@ function event_link($link_id)
         		 '".$reallyNow."',
         		 '".api_get_session_id()."'
         		)";
-    $res = Database::query($sql);
+    Database::query($sql);
     return 1;
 }
 
@@ -290,8 +290,21 @@ function event_link($link_id)
  * @author Julio Montoya Armas <gugli100@gmail.com> Reworked 2010
  * @desc Record result of user when an exercice was done
 */
-function update_event_exercice($exeid, $exo_id, $score, $weighting, $session_id, $learnpath_id = 0, $learnpath_item_id = 0, $learnpath_item_view_id = 0, $duration = 0, $question_list = array(), $status = '', $remind_list = array() , $end_date = null)
-{
+function update_event_exercice(
+    $exeid,
+    $exo_id,
+    $score,
+    $weighting,
+    $session_id,
+    $learnpath_id = 0,
+    $learnpath_item_id = 0,
+    $learnpath_item_view_id = 0,
+    $duration = 0,
+    $question_list = array(),
+    $status = '',
+    $remind_list = array(),
+    $end_date = null
+) {
     require_once api_get_path(SYS_CODE_PATH).'exercice/exercise.lib.php';
     global $debug;
 
@@ -543,10 +556,18 @@ function exercise_attempt_hotspot($exe_id, $question_id, $answer_id, $correct, $
  * @param	string	Timestamp (defaults to null)
  * @param	integer	User ID (defaults to null)
  * @param	string	Course code (defaults to null)
+ * @param	integer	Session ID (defaults to null - only stored from 1.10 onwards)
  * @assert ('','','') === false
  */
-function event_system($event_type, $event_value_type, $event_value, $datetime = null, $user_id = null, $course_code = null)
-{
+function event_system(
+    $event_type,
+    $event_value_type,
+    $event_value,
+    $datetime = null,
+    $user_id = null,
+    $course_code = null,
+    $session_id = null
+) {
     global $TABLETRACK_DEFAULT;
     if (empty($event_type)) {
         return false;
@@ -606,7 +627,7 @@ function event_system($event_type, $event_value_type, $event_value, $datetime =
  * Get every email stored in the database
  *
  * @param int $etId
- * @return type
+ * @return array
  * @assert () !== false
  */
 function get_all_event_types() {
@@ -617,7 +638,7 @@ function get_all_event_types() {
             INNER JOIN '.Database::get_main_table(TABLE_MAIN_LANGUAGE).' l
             ON etm.language_id = l.id';
 
-    $events_types = Database::store_result(Database::query($sql),'ASSOC');
+    $events_types = Database::store_result(Database::query($sql), 'ASSOC');
 
     $to_return = array();
     foreach ($events_types as $et) {
@@ -631,8 +652,9 @@ function get_all_event_types() {
 /**
  * Get users linked to an event
  *
- * @param int $etId
- * @return type
+ * @param string $event_name
+ *
+ * @return string
  */
 function get_users_subscribed_to_event($event_name) {
     $event_name = Database::escape_string($event_name);
@@ -655,7 +677,9 @@ function get_users_subscribed_to_event($event_name) {
 function get_event_users($event_name)
 {
     $event_name = Database::escape_string($event_name);
-    $sql = 'SELECT user.user_id,  user.firstname, user.lastname FROM '.Database::get_main_table(TABLE_MAIN_USER).' user JOIN '.Database::get_main_table(TABLE_EVENT_TYPE_REL_USER).' relUser
+    $sql = 'SELECT user.user_id,  user.firstname, user.lastname
+            FROM '.Database::get_main_table(TABLE_MAIN_USER).' user
+            JOIN '.Database::get_main_table(TABLE_EVENT_TYPE_REL_USER).' relUser
             ON relUser.user_id = user.user_id
             WHERE user.status <> '.ANONYMOUS.' AND relUser.event_type_name = "'.$event_name.'"';
     $user_list = Database::store_result(Database::query($sql), 'ASSOC');
@@ -752,7 +776,7 @@ function save_event_type_message($event_name, $users, $message, $subject, $event
     // set activated at every save
     $sql = 'UPDATE '.Database::get_main_table(TABLE_EVENT_EMAIL_TEMPLATE).'
                 SET activated = '.$activated.'
-                WHERE event_type_name = "'.$event_name.'"';
+            WHERE event_type_name = "'.$event_name.'"';
     Database::query($sql);
 }
 
@@ -902,7 +926,6 @@ function delete_student_lp_events($user_id, $lp_id, $course, $session_id) {
     if (Database::num_rows($result)) {
         $view          = Database::fetch_array($result, 'ASSOC');
         $lp_view_id    = $view['id'];
-
         $sql = "DELETE FROM $lp_item_view_table WHERE c_id = $course_id AND lp_view_id = $lp_view_id ";
         Database::query($sql);
     }
@@ -927,6 +950,7 @@ function delete_student_lp_events($user_id, $lp_id, $course, $session_id) {
         $sql_delete = "DELETE FROM $recording_table     WHERE exe_id IN (".implode(',',$exe_list).")";
         Database::query($sql_delete);
     }
+    event_system(LOG_LP_ATTEMPT_DELETE, LOG_LP_ID, $lp_id, null, null, $course['code'], $session_id);
 }
 
 /**
@@ -948,6 +972,7 @@ function delete_all_incomplete_attempts($user_id, $exercise_id, $course_code, $s
         $sql = "DELETE FROM $track_e_exercises  WHERE exe_user_id = $user_id AND exe_exo_id = $exercise_id AND exe_cours_id = '$course_code' AND session_id = $session_id AND status = 'incomplete' ";
         Database::query($sql);
     }
+    event_system(LOG_EXERCISE_RESULT_DELETE, LOG_EXERCISE_AND_USER_ID, $exercise_id.'-'.$user_id, null, null, $course_code, $session_id);
 }
 
 /**
@@ -1011,7 +1036,9 @@ function get_all_exercise_results_by_course($course_code, $session_id = 0, $get_
     if ($get_count) {
         $select = 'count(*) as count';
     }
-    $sql = "SELECT $select FROM $table_track_exercises WHERE status = ''  AND exe_cours_id = '$course_code' AND session_id = $session_id  AND orig_lp_id = 0 AND orig_lp_item_id = 0 ORDER BY exe_id";
+    $sql = "SELECT $select FROM $table_track_exercises
+            WHERE status = ''  AND exe_cours_id = '$course_code' AND session_id = $session_id  AND orig_lp_id = 0 AND orig_lp_item_id = 0
+            ORDER BY exe_id";
     $res = Database::query($sql);
     if ($get_count) {
         $row = Database::fetch_array($res,'ASSOC');
@@ -1047,19 +1074,20 @@ function get_all_exercise_results_by_user($user_id,  $course_code, $session_id =
     $session_id = intval($session_id);
     $user_id    = intval($user_id);
 
-    $sql = "SELECT * FROM $table_track_exercises WHERE status = '' AND exe_user_id = $user_id AND exe_cours_id = '$course_code' AND session_id = $session_id AND orig_lp_id = 0 AND orig_lp_item_id = 0   ORDER by exe_id";
+    $sql = "SELECT * FROM $table_track_exercises
+            WHERE status = '' AND exe_user_id = $user_id AND exe_cours_id = '$course_code' AND session_id = $session_id AND orig_lp_id = 0 AND orig_lp_item_id = 0
+            ORDER by exe_id";
 
     $res = Database::query($sql);
     $list = array();
     while($row = Database::fetch_array($res,'ASSOC')) {
         $list[$row['exe_id']] = $row;
-    $sql = "SELECT * FROM $table_track_attempt WHERE exe_id = {$row['exe_id']}";
+        $sql = "SELECT * FROM $table_track_attempt WHERE exe_id = {$row['exe_id']}";
         $res_question = Database::query($sql);
-    while($row_q = Database::fetch_array($res_question,'ASSOC')) {
-    $list[$row['exe_id']]['question_list'][$row_q['question_id']] = $row_q;
+        while($row_q = Database::fetch_array($res_question,'ASSOC')) {
+            $list[$row['exe_id']]['question_list'][$row_q['question_id']] = $row_q;
         }
     }
-    //echo '<pre>'; print_r($list);
     return $list;
 }
 
@@ -1145,7 +1173,8 @@ function get_exercise_results_by_user($user_id, $exercise_id, $course_code, $ses
     $list = array();
     while($row = Database::fetch_array($res,'ASSOC')) {
         //Checking if this attempt was revised by a teacher
-        $sql_revised = 'SELECT exe_id FROM ' . $table_track_attempt_recording . ' WHERE author != "" AND exe_id = '.$row['exe_id'].' LIMIT 1';
+        $sql_revised = 'SELECT exe_id FROM ' . $table_track_attempt_recording . '
+                        WHERE author != "" AND exe_id = '.$row['exe_id'].' LIMIT 1';
         $res_revised = Database::query($sql_revised);
         $row['attempt_revised'] = 0;
      	if (Database::num_rows($res_revised) > 0) {
@@ -1161,8 +1190,6 @@ function get_exercise_results_by_user($user_id, $exercise_id, $course_code, $ses
     return $list;
 }
 
-
-
 /**
  * Count exercise attempts (NO Exercises in LPs ) from a given exercise id, course, session
  * @param   int     exercise id
@@ -1391,7 +1418,8 @@ function get_comments($exe_id, $question_id)
 {
     $table_track_attempt   = Database::get_statistic_table(TABLE_STATISTIC_TRACK_E_ATTEMPT);
     $sql = "SELECT teacher_comment FROM ".$table_track_attempt."
-            WHERE exe_id='".Database::escape_string($exe_id)."' AND question_id = '".Database::escape_string($question_id)."' ORDER by question_id";
+            WHERE exe_id='".Database::escape_string($exe_id)."' AND question_id = '".Database::escape_string($question_id)."'
+            ORDER by question_id";
     $sqlres = Database::query($sql);
     $comm = Database::result($sqlres, 0, "teacher_comment");
     return $comm;
@@ -1436,6 +1464,7 @@ function delete_attempt($exe_id, $user_id, $course_code, $session_id, $question_
     $sql = "DELETE FROM $table_track_attempt
             WHERE exe_id = $exe_id AND user_id = $user_id AND course_code = '$course_code' AND session_id = $session_id AND question_id = $question_id ";
     Database::query($sql);
+    event_system(LOG_QUESTION_RESULT_DELETE, LOG_EXERCISE_ATTEMPT_QUESTION_ID, $exe_id.'-'.$question_id, null, null, $course_code, $session_id);
 }
 
 /**
@@ -1443,19 +1472,21 @@ function delete_attempt($exe_id, $user_id, $course_code, $session_id, $question_
  * @param int $user_id
  * @param string $course_code
  * @param int $question_id
+ * @todo add session_id for 1.10
  */
-function delete_attempt_hotspot($exe_id, $user_id, $course_code, $question_id) {
+function delete_attempt_hotspot($exe_id, $user_id, $course_code, $session_id = 0, $question_id) {
     $table_track_attempt   = Database::get_statistic_table(TABLE_STATISTIC_TRACK_E_HOTSPOT);
 
     $exe_id          = intval($exe_id);
     $user_id         = intval($user_id);
     $course_code     = Database::escape_string($course_code);
-    //$session_id      = intval($session_id);
+    $session_id      = intval($session_id);
     $question_id     = intval($question_id);
 
     $sql = "DELETE FROM $table_track_attempt
             WHERE hotspot_exe_id = $exe_id AND hotspot_user_id = $user_id AND hotspot_course_code = '$course_code' AND hotspot_question_id = $question_id ";
     Database::query($sql);
+    event_system(LOG_QUESTION_RESULT_DELETE, LOG_EXERCISE_ATTEMPT_QUESTION_ID, $exe_id.'-'.$question_id, null, null, $course_code, $session_id);
 }
 
 /**
@@ -1503,6 +1534,9 @@ function event_send_mail($event_name, $params)
  * @return boolean
  */
 function check_if_mail_already_sent($event_name, $user_from, $user_to = null) {
+    $event_name = Database::escape_string($event_name);
+    $user_to = Database::escape_string($user_to);
+    $user_from = Database::escape_string($user_from);
     if ($user_to == null) {
         $sql = 'SELECT COUNT(*) as total FROM ' . Database::get_main_table(TABLE_EVENT_SENT) . '
                 WHERE user_from = '.$user_from.' AND event_type_name = "'.$event_name.'"';

+ 11 - 11
main/inc/lib/fckeditor/editor/plugins/ajaxfilemanager/inc/class.pagination.php

@@ -122,9 +122,9 @@ class pagination
 	function setUrl($value="") {
 	    $protocol = "http://";
         if (isset($_SERVER['HTTPS'])) {
-            $protocol = "https://";    
+            $protocol = "https://";
         }
-        
+
 		if(empty($value))
 		{
 			if($this->friendlyUrl)
@@ -216,7 +216,7 @@ class pagination
 	/**
 	 * get the first item number
 	 *
-	 * @return interger the first item number displayed within current page
+	 * @return int the first item number displayed within current page
 	 */
 	function getFirstItem()
 	{
@@ -232,7 +232,7 @@ class pagination
 	/**
 	 * get the last item number displayed within current page
 	 *
-	 * @return interger the last item number
+	 * @return int the last item number
 	 */
 	function getLastItem()
 	{
@@ -532,8 +532,8 @@ class pagination
 		{
 			case "2":
 				//comment while integrating with Chamilo
-			
-				//$output .= "<span class=\"pagination_summany\">" . $this->getFirstItem() . " to " . $this->getLastItem() . " of " . $this->getTotal() . " results.</span> ";	
+
+				//$output .= "<span class=\"pagination_summany\">" . $this->getFirstItem() . " to " . $this->getLastItem() . " of " . $this->getTotal() . " results.</span> ";
 			//if($previousUrl = $this->getPreviousUrl())
 			//{
 			//	$output .= " " . $previousUrl;
@@ -542,7 +542,7 @@ class pagination
 			//if($nextUrl = $this->getNextUrl())
 			{
 			//	$output .= " " . $nextUrl;
-			}							
+			}
 				break;
 			case 1:
 				//get full summary pagination
@@ -575,13 +575,13 @@ class pagination
 			//{
 			//	$itemPerPage .= "<option value=\"" . $v . "\" " . ($v==$this->itemsPerPage?'selected="selected"':'') . ">" . $v . "</option>\n";
 			//}
-			//$itemPerPage .= "</select>\n"; 
-		
+			//$itemPerPage .= "</select>\n";
+
 		    $itemPerPage ="100000";//hack for Chamilo
 			//$output .= "<span class=\"pagination_items_per_page\">";
 			//$output .= sprintf(PAGINATION_ITEMS_PER_PAGE, $itemPerPage);
 			//$output .= "</span>";
-			
+
 			//end comment while integrating with Chamilo
 			$output .= "<span class=\"pagination_parent\"><a href=\"#\" onclick=\"goParentFolder();\" id=\"pagination_parent_link\" title=\"" . PAGINATION_GO_PARENT . "\">&nbsp;".PAGINATION_GO_PARENT."</a></span>";
 		}
@@ -591,4 +591,4 @@ class pagination
 	}
 
 }
-?>
+?>

+ 10 - 14
main/inc/lib/fckeditor/fckeditor.php

@@ -49,14 +49,10 @@ function FCKeditor_IsCompatibleBrowser()
             $sAgent = $HTTP_USER_AGENT ;
         }
     }
-
-    if ( strpos($sAgent, 'MSIE') !== false && strpos($sAgent, 'mac') === false && strpos($sAgent, 'Opera') === false )
-    {
+    if ( strpos($sAgent, 'MSIE') !== false && strpos($sAgent, 'mac') === false && strpos($sAgent, 'Opera') === false ) {
         $iVersion = (float)substr($sAgent, strpos($sAgent, 'MSIE') + 5, 3) ;
         return ($iVersion >= 5.5) ;
-    }
-    else if ( strpos($sAgent, 'Gecko/') !== false )
-    {
+    } else if ( strpos($sAgent, 'Gecko/') !== false ) {
         $iVersion = substr($sAgent, strpos($sAgent, 'Gecko/') + 6, 8) ;
         // Special fix for Firefox 17 and followers - see #5752
         if ( preg_match('/^\d{2,3}\.\d{1,4}\s/', $iVersion) ) {
@@ -65,19 +61,19 @@ function FCKeditor_IsCompatibleBrowser()
         $iVersion = (int)$iVersion;
         //return ($iVersion >= 20030210) ;
         return true;
-    }
-    else if ( strpos($sAgent, 'Opera/') !== false )
-    {
+    } else if ( strpos($sAgent, 'Opera/') !== false ) {
         $fVersion = (float)substr($sAgent, strpos($sAgent, 'Opera/') + 6, 4) ;
         return ($fVersion >= 9.5) ;
-    }
-    else if ( preg_match( "|AppleWebKit/(\d+)|i", $sAgent, $matches ) )
-    {
+    } else if ( preg_match( "|AppleWebKit/(\d+)|i", $sAgent, $matches ) ) {
         $iVersion = $matches[1] ;
         return ( $matches[1] >= 522 ) ;
-    }
-    else
+    } else if ( strpos($sAgent, 'Gecko') !== false && strpos($sAgent, 'rv:') !== false ) {
+        // Internet Explorer 11 - goes with a X-UA-Compatible IE=EmulateIE9 header
+        $iVersion = (int)substr($sAgent, strpos($sAgent, 'rv:') + 3, 2) ;
+        return ($iVersion >= 11);
+    } else {
         return false ;
+    }
 }
 
 class FCKeditor

+ 30 - 15
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,13 +264,13 @@ function handle_uploaded_document(
 			$file_size = $uploaded_file['size'];
 
 			$files_perm = api_get_permissions_for_new_files();
-                       $doc_path = '/'.$clean_name;
-                       $docId = DocumentManager :: get_document_id($_course, $doc_path, $current_session_id);
-      		        // 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);
@@ -328,11 +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;
-                                  }
+                    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;
 
@@ -383,6 +390,7 @@ function handle_uploaded_document(
                                 // Redo visibility
                                 api_set_default_visibility(TOOL_DOCUMENT, $document_id);
 							}
+
 							// If the file is in a folder, we need to update all parent folders
 							item_property_update_on_folder($_course,$upload_path,$user_id);
 
@@ -392,7 +400,7 @@ function handle_uploaded_document(
 							}
 							return $file_path;
 						} else {
-						    if ($output){
+						    if ($output) {
                                 Display::display_error_message(get_lang('UplUnableToSaveFile'));
 							}
 							return false;
@@ -751,7 +759,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;
@@ -760,11 +775,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'];
 	}
 
@@ -782,12 +796,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;
 }
 

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

@@ -7,7 +7,6 @@ require_once 'HTML/QuickForm/date.php';
  */
 class DatePicker extends HTML_QuickForm_text
 {
-    public $addLibrary = false;
 	/**
 	 * Constructor
 	 */

+ 8 - 25
main/inc/lib/formvalidator/Element/DateRangePicker.php

@@ -7,7 +7,6 @@ require_once 'HTML/QuickForm/date.php';
  */
 class DateRangePicker extends HTML_QuickForm_text
 {
-    public $addLibrary = false;
 	/**
 	 * Constructor
 	 */
@@ -47,22 +46,6 @@ class DateRangePicker extends HTML_QuickForm_text
 	{
         $js = null;
 
-        if ($this->addLibrary == true) {
-            $js .= '<script src="'.api_get_path(WEB_LIBRARY_PATH).'javascript/daterange/moment.min.js" type="text/javascript"></script>';
-            $js .= '<script src="'.api_get_path(WEB_LIBRARY_PATH).'javascript/daterange/daterangepicker.js" type="text/javascript"></script>';
-            $js .='<link  href="'.api_get_path(WEB_LIBRARY_PATH).'javascript/daterange/daterangepicker-bs2.css" rel="stylesheet" type="text/css" />';
-
-            $isocode = api_get_language_isocode();
-            if ($isocode != 'en') {
-                $js .= api_get_js('jquery-ui/jquery-ui-i18n.min.js');
-                $js .= '<script>
-                $(function(){
-                    moment.lang("'.$isocode.'");
-                });
-                </script>';
-            }
-        }
-
         $id = $this->getAttribute('id');
         //timeFormat: 'hh:mm'
         $js .= "<script>
@@ -73,18 +56,18 @@ class DateRangePicker extends HTML_QuickForm_text
                     timePickerIncrement: 30,
                     timePicker12Hour: false,
                     ranges: {
-                         '".get_lang('Today')."': [moment(), moment()],
-                         '".get_lang('ThisWeek')."': [moment().weekday(1), moment().weekday(5)],
-                         '".get_lang('NextWeek')."': [moment().weekday(8), moment().weekday(12)]
+                         '".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: '".get_lang('Apply')."',
-                        cancelLabel: '".get_lang('Cancel')."',
-                        fromLabel: '".get_lang('From')."',
-                        toLabel: '".get_lang('To')."',
-                        customRangeLabel: '".get_lang('CustomRange')."',
+                        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'))."',
                     }
                 });
             });

+ 4 - 20
main/inc/lib/formvalidator/Element/DateTimePicker.php

@@ -7,7 +7,6 @@ require_once 'HTML/QuickForm/date.php';
  */
 class DateTimePicker extends HTML_QuickForm_text
 {
-    public $addLibrary = false;
 	/**
 	 * Constructor
 	 */
@@ -31,6 +30,9 @@ class DateTimePicker extends HTML_QuickForm_text
 		return $js.parent::toHtml();
 	}
 
+    /**
+     * @param string $value
+     */
     function setValue($value)
     {
         $value = substr($value, 0, 16);
@@ -47,24 +49,6 @@ class DateTimePicker extends HTML_QuickForm_text
 	private function getElementJS()
 	{
         $js = null;
-
-        if ($this->addLibrary == true) {
-            $js .= '<script src="'.api_get_path(WEB_LIBRARY_PATH).'javascript/datetimepicker/jquery-ui-timepicker-addon.js" type="text/javascript"></script>';
-            $js .='<link  href="'.api_get_path(WEB_LIBRARY_PATH).'javascript/datetimepicker/jquery-ui-timepicker-addon.css" rel="stylesheet" type="text/css" />';
-
-            $isocode = api_get_language_isocode();
-            if ($isocode != 'en') {
-                $js .= '<script src="'.api_get_path(WEB_LIBRARY_PATH).'javascript/datetimepicker/i18n/jquery-ui-timepicker-'.$isocode.'.js" type="text/javascript"></script>';
-
-                $js .= api_get_js('jquery-ui/jquery-ui-i18n.min.js');
-                $js .= '<script>
-                $(function(){
-                    $.datepicker.setDefaults($.datepicker.regional["'.$isocode.'"]);
-                });
-                </script>';
-            }
-        }
-
         $id = $this->getAttribute('id');
         //timeFormat: 'hh:mm'
         $js .= "<script>
@@ -75,7 +59,7 @@ class DateTimePicker extends HTML_QuickForm_text
                 });
             });
         </script>";
+
 		return $js;
 	}
-
 }

+ 41 - 4
main/inc/lib/formvalidator/FormValidator.class.php

@@ -255,6 +255,14 @@ EOT;
         }
     }
 
+    /**
+     * date_range_picker element creates 2 hidden fields
+     * elementName + "_start" elementName "_end"
+     * @param string $name
+     * @param string $label
+     * @param bool $required
+     * @param array $attributes
+     */
     public function addDateRangePicker($name, $label, $required = true, $attributes = array())
     {
         $this->addElement('date_range_picker', $name, $label, $attributes);
@@ -266,7 +274,10 @@ EOT;
         }
     }
 
-
+    /**
+     * @param string $name
+     * @param string $value
+     */
     function add_hidden($name, $value)
     {
         $this->addElement('hidden', $name, $value);
@@ -540,16 +551,45 @@ EOT;
     function return_form()
     {
         $error = false;
+        $addDateLibraries = false;
+        $dateElementTypes = array('date_range_picker', 'date_time_picker', 'date_picker', 'datepicker', 'datetimepicker');
+        /** @var HTML_QuickForm_element $element */
         foreach ($this->_elements as $element) {
+            if (in_array($element->getType(),$dateElementTypes)) {
+                $addDateLibraries = true;
+            }
             if (!is_null(parent::getElementError($element->getName()))) {
                 $error = true;
                 break;
             }
         }
         $return_value = '';
+        $js = null;
+        if ($addDateLibraries) {
+            $js = api_get_js('jquery-ui/jquery-ui-i18n.min.js');
+            $js .= '<script src="'.api_get_path(WEB_LIBRARY_PATH).'javascript/datetimepicker/jquery-ui-timepicker-addon.js" type="text/javascript"></script>';
+            $js .= '<link href="'.api_get_path(WEB_LIBRARY_PATH).'javascript/datetimepicker/jquery-ui-timepicker-addon.css" rel="stylesheet" type="text/css" />';
+            $js .= '<script src="'.api_get_path(WEB_LIBRARY_PATH).'javascript/daterange/moment.min.js" type="text/javascript"></script>';
+            $js .= '<script src="'.api_get_path(WEB_LIBRARY_PATH).'javascript/daterange/daterangepicker.js" type="text/javascript"></script>';
+            $js .= '<link href="'.api_get_path(WEB_LIBRARY_PATH).'javascript/daterange/daterangepicker-bs2.css" rel="stylesheet" type="text/css" />';
+
+            $isocode = api_get_language_isocode();
+            if ($isocode != 'en') {
+                $js .= '<script src="'.api_get_path(WEB_LIBRARY_PATH).'javascript/datetimepicker/i18n/jquery-ui-timepicker-'.$isocode.'.js" type="text/javascript"></script>';
+                $js .= '<script>
+                $(function(){
+                    $.datepicker.setDefaults($.datepicker.regional["'.$isocode.'"]);
+                     moment.lang("'.$isocode.'");
+                });
+                </script>';
+            }
+        }
+
         if ($error) {
             $return_value = Display::return_message(get_lang('FormHasErrorsPleaseComplete'), 'warning');
         }
+
+        $return_value .= $js;
         $return_value .= parent::toHtml();
         // Add div-element which is to hold the progress bar
         if (isset($this->with_progress_bar) && $this->with_progress_bar) {
@@ -557,9 +597,6 @@ EOT;
         }
         return $return_value;
     }
-
-
-
 }
 
 /**

+ 10 - 13
main/inc/lib/internationalization.lib.php

@@ -3795,22 +3795,19 @@ function setting_gettext() {
     textdomain($domain);
 }
 
+
 /**
- * Return true is $in_date is a valid date
- * date format yyyy-mm-dd hh:mm:ss
- * @param $in_date
+ * Return true a date is valid
+
+ * @param string $date example: 2014-06-30 13:05:05
+ * @param string $format example: "Y-m-d H:i:s"
+ *
+ * @return bool
  */
-function api_is_valid_date($in_date) {
-    if (preg_match('/^([0-9]{4})-([0-1][0-9])-([0-3][0-9])( ([0-2][0-9]):([0-5][0-9]):([0-5][0-9]))?$/', $in_date, $tab_matches)) {
-        if (checkdate($tab_matches[2], $tab_matches[3], $tab_matches[1])
-            && (($tab_matches[5] <= 23 && $tab_matches[6] <= 59 && $tab_matches[7] <= 59)
-                || ($tab_matches[5] == 24 && $tab_matches[6] == '00' && $tab_matches[7] == '00'))) {
-            return true;
-        }
-    }
-    return false;
+function api_is_valid_date($date, $format = 'Y-m-d H:i:s') {
+    $d = DateTime::createFromFormat($format, $date);
+    return $d && $d->format($format) == $date;
 }
-
 /**
  * Return the encoding country code for jquery datepicker
  * used for exemple in main/exercice/exercise_report.php

BIN
main/inc/lib/javascript/chosen/chosen-sprite@2x.png


+ 300 - 278
main/inc/lib/javascript/chosen/chosen.css

@@ -1,413 +1,435 @@
+/*!
+Chosen, a Select Box Enhancer for jQuery and Prototype
+by Patrick Filler for Harvest, http://getharvest.com
+
+Version 1.1.0
+Full source at https://github.com/harvesthq/chosen
+Copyright (c) 2011 Harvest http://getharvest.com
+
+MIT License, https://github.com/harvesthq/chosen/blob/master/LICENSE.md
+This file is generated by `grunt build`, do not edit it by hand.
+*/
+
 /* @group Base */
-.chzn-container {
-  font-size: 13px;
+.chosen-container {
   position: relative;
   display: inline-block;
+  vertical-align: middle;
+  font-size: 13px;
   zoom: 1;
   *display: inline;
+  -webkit-user-select: none;
+  -moz-user-select: none;
+  user-select: none;
 }
-.chzn-container .chzn-drop {
-  background: #fff;
+.chosen-container .chosen-drop {
+  position: absolute;
+  top: 100%;
+  left: -9999px;
+  z-index: 1010;
+  -webkit-box-sizing: border-box;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+  width: 100%;
   border: 1px solid #aaa;
   border-top: 0;
-  position: absolute;
-  top: 29px;
+  background: #fff;
+  box-shadow: 0 4px 5px rgba(0, 0, 0, 0.15);
+}
+.chosen-container.chosen-with-drop .chosen-drop {
   left: 0;
-  -webkit-box-shadow: 0 4px 5px rgba(0,0,0,.15);
-  -moz-box-shadow   : 0 4px 5px rgba(0,0,0,.15);
-  box-shadow        : 0 4px 5px rgba(0,0,0,.15);
-  z-index: 1010;
 }
-/* @end */
+.chosen-container a {
+  cursor: pointer;
+}
 
+/* @end */
 /* @group Single Chosen */
-.chzn-container-single .chzn-single {
-  background-color: #ffffff;
-  filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#ffffff', endColorstr='#eeeeee', GradientType=0 );
-  background-image: -webkit-gradient(linear, 0 0, 0 100%, color-stop(20%, #ffffff), color-stop(50%, #f6f6f6), color-stop(52%, #eeeeee), color-stop(100%, #f4f4f4));
-  background-image: -webkit-linear-gradient(top, #ffffff 20%, #f6f6f6 50%, #eeeeee 52%, #f4f4f4 100%);
-  background-image: -moz-linear-gradient(top, #ffffff 20%, #f6f6f6 50%, #eeeeee 52%, #f4f4f4 100%);
-  background-image: -o-linear-gradient(top, #ffffff 20%, #f6f6f6 50%, #eeeeee 52%, #f4f4f4 100%);
-  background-image: linear-gradient(#ffffff 20%, #f6f6f6 50%, #eeeeee 52%, #f4f4f4 100%);
-  -webkit-border-radius: 5px;
-  -moz-border-radius   : 5px;
-  border-radius        : 5px;
-  -moz-background-clip   : padding;
-  -webkit-background-clip: padding-box;
-  background-clip        : padding-box;
-  border: 1px solid #aaaaaa;
-  -webkit-box-shadow: 0 0 3px #ffffff inset, 0 1px 1px rgba(0,0,0,0.1);
-  -moz-box-shadow   : 0 0 3px #ffffff inset, 0 1px 1px rgba(0,0,0,0.1);
-  box-shadow        : 0 0 3px #ffffff inset, 0 1px 1px rgba(0,0,0,0.1);
+.chosen-container-single .chosen-single {
+  position: relative;
   display: block;
   overflow: hidden;
-  white-space: nowrap;
-  position: relative;
-  height: 23px;
-  line-height: 24px;
   padding: 0 0 0 8px;
-  color: #444444;
+  height: 23px;
+  border: 1px solid #aaa;
+  border-radius: 5px;
+  background-color: #fff;
+  background: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(20%, #ffffff), color-stop(50%, #f6f6f6), color-stop(52%, #eeeeee), color-stop(100%, #f4f4f4));
+  background: -webkit-linear-gradient(top, #ffffff 20%, #f6f6f6 50%, #eeeeee 52%, #f4f4f4 100%);
+  background: -moz-linear-gradient(top, #ffffff 20%, #f6f6f6 50%, #eeeeee 52%, #f4f4f4 100%);
+  background: -o-linear-gradient(top, #ffffff 20%, #f6f6f6 50%, #eeeeee 52%, #f4f4f4 100%);
+  background: linear-gradient(top, #ffffff 20%, #f6f6f6 50%, #eeeeee 52%, #f4f4f4 100%);
+  background-clip: padding-box;
+  box-shadow: 0 0 3px white inset, 0 1px 1px rgba(0, 0, 0, 0.1);
+  color: #444;
   text-decoration: none;
+  white-space: nowrap;
+  line-height: 24px;
 }
-.chzn-container-single .chzn-default {
+.chosen-container-single .chosen-default {
   color: #999;
 }
-.chzn-container-single .chzn-single span {
-  margin-right: 26px;
+.chosen-container-single .chosen-single span {
   display: block;
   overflow: hidden;
-  white-space: nowrap;
-  -o-text-overflow: ellipsis;
-  -ms-text-overflow: ellipsis;
+  margin-right: 26px;
   text-overflow: ellipsis;
+  white-space: nowrap;
 }
-.chzn-container-single .chzn-single abbr {
-  display: block;
+.chosen-container-single .chosen-single-with-deselect span {
+  margin-right: 38px;
+}
+.chosen-container-single .chosen-single abbr {
   position: absolute;
-  right: 26px;
   top: 6px;
+  right: 26px;
+  display: block;
   width: 12px;
   height: 12px;
-  font-size: 1px;
   background: url('chosen-sprite.png') -42px 1px no-repeat;
+  font-size: 1px;
 }
-.chzn-container-single .chzn-single abbr:hover {
+.chosen-container-single .chosen-single abbr:hover {
   background-position: -42px -10px;
 }
-.chzn-container-single.chzn-disabled .chzn-single abbr:hover {
+.chosen-container-single.chosen-disabled .chosen-single abbr:hover {
   background-position: -42px -10px;
 }
-.chzn-container-single .chzn-single div {
+.chosen-container-single .chosen-single div {
   position: absolute;
-  right: 0;
   top: 0;
+  right: 0;
   display: block;
-  height: 100%;
   width: 18px;
+  height: 100%;
 }
-.chzn-container-single .chzn-single div b {
-  background: url('chosen-sprite.png') no-repeat 0px 2px;
+.chosen-container-single .chosen-single div b {
   display: block;
   width: 100%;
   height: 100%;
+  background: url('chosen-sprite.png') no-repeat 0px 2px;
 }
-.chzn-container-single .chzn-search {
-  padding: 3px 4px;
+.chosen-container-single .chosen-search {
   position: relative;
+  z-index: 1010;
   margin: 0;
+  padding: 3px 4px;
   white-space: nowrap;
-  z-index: 1010;
 }
-.chzn-container-single .chzn-search input {
-  background: #fff url('chosen-sprite.png') no-repeat 100% -20px;
-  background: url('chosen-sprite.png') no-repeat 100% -20px, -webkit-gradient(linear, 0 0, 0 100%, color-stop(1%, #eeeeee), color-stop(15%, #ffffff));
-  background: url('chosen-sprite.png') no-repeat 100% -20px, -webkit-linear-gradient(top, #eeeeee 1%, #ffffff 15%);
-  background: url('chosen-sprite.png') no-repeat 100% -20px, -moz-linear-gradient(top, #eeeeee 1%, #ffffff 15%);
-  background: url('chosen-sprite.png') no-repeat 100% -20px, -o-linear-gradient(top, #eeeeee 1%, #ffffff 15%);
-  background: url('chosen-sprite.png') no-repeat 100% -20px, linear-gradient(#eeeeee 1%, #ffffff 15%);
+.chosen-container-single .chosen-search input[type="text"] {
+  -webkit-box-sizing: border-box;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
   margin: 1px 0;
   padding: 4px 20px 4px 5px;
+  width: 100%;
+  height: auto;
   outline: 0;
   border: 1px solid #aaa;
-  font-family: sans-serif;
+  background: white url('chosen-sprite.png') no-repeat 100% -20px;
+  background: url('chosen-sprite.png') no-repeat 100% -20px;
   font-size: 1em;
+  font-family: sans-serif;
+  line-height: normal;
+  border-radius: 0;
 }
-.chzn-container-single .chzn-drop {
-  -webkit-border-radius: 0 0 4px 4px;
-  -moz-border-radius   : 0 0 4px 4px;
-  border-radius        : 0 0 4px 4px;
-  -moz-background-clip   : padding;
-  -webkit-background-clip: padding-box;
-  background-clip        : padding-box;
+.chosen-container-single .chosen-drop {
+  margin-top: -1px;
+  border-radius: 0 0 4px 4px;
+  background-clip: padding-box;
 }
-/* @end */
-
-.chzn-container-single-nosearch .chzn-search input {
+.chosen-container-single.chosen-container-single-nosearch .chosen-search {
   position: absolute;
-  left: -9000px;
+  left: -9999px;
 }
 
+/* @end */
+/* @group Results */
+.chosen-container .chosen-results {
+  position: relative;
+  overflow-x: hidden;
+  overflow-y: auto;
+  margin: 0 4px 4px 0;
+  padding: 0 0 0 4px;
+  max-height: 240px;
+  -webkit-overflow-scrolling: touch;
+}
+.chosen-container .chosen-results li {
+  display: none;
+  margin: 0;
+  padding: 5px 6px;
+  list-style: none;
+  line-height: 15px;
+  -webkit-touch-callout: none;
+}
+.chosen-container .chosen-results li.active-result {
+  display: list-item;
+  cursor: pointer;
+}
+.chosen-container .chosen-results li.disabled-result {
+  display: list-item;
+  color: #ccc;
+  cursor: default;
+}
+.chosen-container .chosen-results li.highlighted {
+  background-color: #3875d7;
+  background-image: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(20%, #3875d7), color-stop(90%, #2a62bc));
+  background-image: -webkit-linear-gradient(#3875d7 20%, #2a62bc 90%);
+  background-image: -moz-linear-gradient(#3875d7 20%, #2a62bc 90%);
+  background-image: -o-linear-gradient(#3875d7 20%, #2a62bc 90%);
+  background-image: linear-gradient(#3875d7 20%, #2a62bc 90%);
+  color: #fff;
+}
+.chosen-container .chosen-results li.no-results {
+  display: list-item;
+  background: #f4f4f4;
+}
+.chosen-container .chosen-results li.group-result {
+  display: list-item;
+  font-weight: bold;
+  cursor: default;
+}
+.chosen-container .chosen-results li.group-option {
+  padding-left: 15px;
+}
+.chosen-container .chosen-results li em {
+  font-style: normal;
+  text-decoration: underline;
+}
+
+/* @end */
 /* @group Multi Chosen */
-.chzn-container-multi .chzn-choices {
-  background-color: #fff;
-  background-image: -webkit-gradient(linear, 0 0, 0 100%, color-stop(1%, #eeeeee), color-stop(15%, #ffffff));
-  background-image: -webkit-linear-gradient(top, #eeeeee 1%, #ffffff 15%);
-  background-image: -moz-linear-gradient(top, #eeeeee 1%, #ffffff 15%);
-  background-image: -o-linear-gradient(top, #eeeeee 1%, #ffffff 15%);
-  background-image: linear-gradient(#eeeeee 1%, #ffffff 15%);
-  border: 1px solid #aaa;
+.chosen-container-multi .chosen-choices {
+  position: relative;
+  overflow: hidden;
+  -webkit-box-sizing: border-box;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
   margin: 0;
   padding: 0;
-  cursor: text;
-  overflow: hidden;
+  width: 100%;
   height: auto !important;
   height: 1%;
-  position: relative;
+  border: 1px solid #aaa;
+  background-color: #fff;
+  background-image: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(1%, #eeeeee), color-stop(15%, #ffffff));
+  background-image: -webkit-linear-gradient(#eeeeee 1%, #ffffff 15%);
+  background-image: -moz-linear-gradient(#eeeeee 1%, #ffffff 15%);
+  background-image: -o-linear-gradient(#eeeeee 1%, #ffffff 15%);
+  background-image: linear-gradient(#eeeeee 1%, #ffffff 15%);
+  cursor: text;
 }
-.chzn-container-multi .chzn-choices li {
+.chosen-container-multi .chosen-choices li {
   float: left;
   list-style: none;
 }
-.chzn-container-multi .chzn-choices .search-field {
-  white-space: nowrap;
+.chosen-container-multi .chosen-choices li.search-field {
   margin: 0;
   padding: 0;
+  white-space: nowrap;
 }
-.chzn-container-multi .chzn-choices .search-field input {
-  color: #666;
-  background: transparent !important;
-  border: 0 !important;
-  font-family: sans-serif;
-  font-size: 100%;
-  height: 15px;
-  padding: 5px;
+.chosen-container-multi .chosen-choices li.search-field input[type="text"] {
   margin: 1px 0;
+  padding: 5px;
+  height: 15px;
   outline: 0;
-  -webkit-box-shadow: none;
-  -moz-box-shadow   : none;
-  box-shadow        : none;
+  border: 0 !important;
+  background: transparent !important;
+  box-shadow: none;
+  color: #666;
+  font-size: 100%;
+  font-family: sans-serif;
+  line-height: normal;
+  border-radius: 0;
 }
-.chzn-container-multi .chzn-choices .search-field .default {
+.chosen-container-multi .chosen-choices li.search-field .default {
   color: #999;
 }
-.chzn-container-multi .chzn-choices .search-choice {
-  -webkit-border-radius: 3px;
-  -moz-border-radius   : 3px;
-  border-radius        : 3px;
-  -moz-background-clip   : padding;
-  -webkit-background-clip: padding-box;
-  background-clip        : padding-box;
+.chosen-container-multi .chosen-choices li.search-choice {
+  position: relative;
+  margin: 3px 0 3px 5px;
+  padding: 3px 20px 3px 5px;
+  border: 1px solid #aaa;
+  border-radius: 3px;
   background-color: #e4e4e4;
-  filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#f4f4f4', endColorstr='#eeeeee', GradientType=0 );
-  background-image: -webkit-gradient(linear, 0 0, 0 100%, color-stop(20%, #f4f4f4), color-stop(50%, #f0f0f0), color-stop(52%, #e8e8e8), color-stop(100%, #eeeeee));
-  background-image: -webkit-linear-gradient(top, #f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%);
-  background-image: -moz-linear-gradient(top, #f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%);
-  background-image: -o-linear-gradient(top, #f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%);
+  background-image: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(20%, #f4f4f4), color-stop(50%, #f0f0f0), color-stop(52%, #e8e8e8), color-stop(100%, #eeeeee));
+  background-image: -webkit-linear-gradient(#f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%);
+  background-image: -moz-linear-gradient(#f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%);
+  background-image: -o-linear-gradient(#f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%);
   background-image: linear-gradient(#f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%);
-  -webkit-box-shadow: 0 0 2px #ffffff inset, 0 1px 0 rgba(0,0,0,0.05);
-  -moz-box-shadow   : 0 0 2px #ffffff inset, 0 1px 0 rgba(0,0,0,0.05);
-  box-shadow        : 0 0 2px #ffffff inset, 0 1px 0 rgba(0,0,0,0.05);
+  background-clip: padding-box;
+  box-shadow: 0 0 2px white inset, 0 1px 0 rgba(0, 0, 0, 0.05);
   color: #333;
-  border: 1px solid #aaaaaa;
   line-height: 13px;
-  padding: 3px 20px 3px 5px;
-  margin: 3px 0 3px 5px;
-  position: relative;
   cursor: default;
 }
-.chzn-container-multi .chzn-choices .search-choice.search-choice-disabled {
-  background-color: #e4e4e4;
-  filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#f4f4f4', endColorstr='#eeeeee', GradientType=0 );
-  background-image: -webkit-gradient(linear, 0% 0%, 0% 100%, color-stop(20%, #f4f4f4), color-stop(50%, #f0f0f0), color-stop(52%, #e8e8e8), color-stop(100%, #eeeeee));
-  background-image: -webkit-linear-gradient(top, #f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%);
-  background-image: -moz-linear-gradient(top, #f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%);
-  background-image: -o-linear-gradient(top, #f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%);
-  background-image: -ms-linear-gradient(top, #f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%);
-  background-image: linear-gradient(top, #f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%);
-  color: #666;
-  border: 1px solid #cccccc;
-  padding-right: 5px;
-}
-.chzn-container-multi .chzn-choices .search-choice-focus {
-  background: #d4d4d4;
-}
-.chzn-container-multi .chzn-choices .search-choice .search-choice-close {
-  display: block;
+.chosen-container-multi .chosen-choices li.search-choice .search-choice-close {
   position: absolute;
-  right: 3px;
   top: 4px;
+  right: 3px;
+  display: block;
   width: 12px;
   height: 12px;
-  font-size: 1px;
   background: url('chosen-sprite.png') -42px 1px no-repeat;
+  font-size: 1px;
 }
-.chzn-container-multi .chzn-choices .search-choice .search-choice-close:hover {
+.chosen-container-multi .chosen-choices li.search-choice .search-choice-close:hover {
   background-position: -42px -10px;
 }
-.chzn-container-multi .chzn-choices .search-choice-focus .search-choice-close {
-  background-position: -42px -10px;
+.chosen-container-multi .chosen-choices li.search-choice-disabled {
+  padding-right: 5px;
+  border: 1px solid #ccc;
+  background-color: #e4e4e4;
+  background-image: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(20%, #f4f4f4), color-stop(50%, #f0f0f0), color-stop(52%, #e8e8e8), color-stop(100%, #eeeeee));
+  background-image: -webkit-linear-gradient(top, #f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%);
+  background-image: -moz-linear-gradient(top, #f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%);
+  background-image: -o-linear-gradient(top, #f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%);
+  background-image: linear-gradient(top, #f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%);
+  color: #666;
 }
-/* @end */
-
-/* @group Results */
-.chzn-container .chzn-results {
-  margin: 0 4px 4px 0;
-  max-height: 240px;
-  padding: 0 0 0 4px;
-  position: relative;
-  overflow-x: hidden;
-  overflow-y: auto;
-  -webkit-overflow-scrolling: touch;
+.chosen-container-multi .chosen-choices li.search-choice-focus {
+  background: #d4d4d4;
 }
-.chzn-container-multi .chzn-results {
-  margin: -1px 0 0;
-  padding: 0;
+.chosen-container-multi .chosen-choices li.search-choice-focus .search-choice-close {
+  background-position: -42px -10px;
 }
-.chzn-container .chzn-results li {
-  display: none;
-  line-height: 15px;
-  padding: 5px 6px;
+.chosen-container-multi .chosen-results {
   margin: 0;
-  list-style: none;
-}
-.chzn-container .chzn-results .active-result {
-  cursor: pointer;
-  display: list-item;
-}
-.chzn-container .chzn-results .highlighted {
-  background-color: #3875d7;
-  filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#3875d7', endColorstr='#2a62bc', GradientType=0 );
-  background-image: -webkit-gradient(linear, 0 0, 0 100%, color-stop(20%, #3875d7), color-stop(90%, #2a62bc));
-  background-image: -webkit-linear-gradient(top, #3875d7 20%, #2a62bc 90%);
-  background-image: -moz-linear-gradient(top, #3875d7 20%, #2a62bc 90%);
-  background-image: -o-linear-gradient(top, #3875d7 20%, #2a62bc 90%);
-  background-image: linear-gradient(#3875d7 20%, #2a62bc 90%);
-  color: #fff;
-}
-.chzn-container .chzn-results li em {
-  background: #feffde;
-  font-style: normal;
-}
-.chzn-container .chzn-results .highlighted em {
-  background: transparent;
+  padding: 0;
 }
-.chzn-container .chzn-results .no-results {
-  background: #f4f4f4;
+.chosen-container-multi .chosen-drop .result-selected {
   display: list-item;
-}
-.chzn-container .chzn-results .group-result {
+  color: #ccc;
   cursor: default;
-  color: #999;
-  font-weight: bold;
-}
-.chzn-container .chzn-results .group-option {
-  padding-left: 15px;
-}
-.chzn-container-multi .chzn-drop .result-selected {
-  display: none;
-}
-.chzn-container .chzn-results-scroll {
-  background: white;
-  margin: 0 4px;
-  position: absolute;
-  text-align: center;
-  width: 321px; /* This should by dynamic with js */
-  z-index: 1;
 }
-.chzn-container .chzn-results-scroll span {
-  display: inline-block;
-  height: 17px;
-  text-indent: -5000px;
-  width: 9px;
-}
-.chzn-container .chzn-results-scroll-down {
-  bottom: 0;
-}
-.chzn-container .chzn-results-scroll-down span {
-  background: url('chosen-sprite.png') no-repeat -4px -3px;
-}
-.chzn-container .chzn-results-scroll-up span {
-  background: url('chosen-sprite.png') no-repeat -22px -3px;
-}
-/* @end */
 
+/* @end */
 /* @group Active  */
-.chzn-container-active .chzn-single {
-  -webkit-box-shadow: 0 0 5px rgba(0,0,0,.3);
-  -moz-box-shadow   : 0 0 5px rgba(0,0,0,.3);
-  box-shadow        : 0 0 5px rgba(0,0,0,.3);
+.chosen-container-active .chosen-single {
   border: 1px solid #5897fb;
+  box-shadow: 0 0 5px rgba(0, 0, 0, 0.3);
 }
-.chzn-container-active .chzn-single-with-drop {
+.chosen-container-active.chosen-with-drop .chosen-single {
   border: 1px solid #aaa;
-  -webkit-box-shadow: 0 1px 0 #fff inset;
-  -moz-box-shadow   : 0 1px 0 #fff inset;
-  box-shadow        : 0 1px 0 #fff inset;
-  background-color: #eee;
-  filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#eeeeee', endColorstr='#ffffff', GradientType=0 );
-  background-image: -webkit-gradient(linear, 0 0, 0 100%, color-stop(20%, #eeeeee), color-stop(80%, #ffffff));
-  background-image: -webkit-linear-gradient(top, #eeeeee 20%, #ffffff 80%);
-  background-image: -moz-linear-gradient(top, #eeeeee 20%, #ffffff 80%);
-  background-image: -o-linear-gradient(top, #eeeeee 20%, #ffffff 80%);
-  background-image: linear-gradient(#eeeeee 20%, #ffffff 80%);
-  -webkit-border-bottom-left-radius : 0;
-  -webkit-border-bottom-right-radius: 0;
-  -moz-border-radius-bottomleft : 0;
   -moz-border-radius-bottomright: 0;
-  border-bottom-left-radius : 0;
   border-bottom-right-radius: 0;
+  -moz-border-radius-bottomleft: 0;
+  border-bottom-left-radius: 0;
+  background-image: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(20%, #eeeeee), color-stop(80%, #ffffff));
+  background-image: -webkit-linear-gradient(#eeeeee 20%, #ffffff 80%);
+  background-image: -moz-linear-gradient(#eeeeee 20%, #ffffff 80%);
+  background-image: -o-linear-gradient(#eeeeee 20%, #ffffff 80%);
+  background-image: linear-gradient(#eeeeee 20%, #ffffff 80%);
+  box-shadow: 0 1px 0 #fff inset;
 }
-.chzn-container-active .chzn-single-with-drop div {
-  background: transparent;
+.chosen-container-active.chosen-with-drop .chosen-single div {
   border-left: none;
+  background: transparent;
 }
-.chzn-container-active .chzn-single-with-drop div b {
+.chosen-container-active.chosen-with-drop .chosen-single div b {
   background-position: -18px 2px;
 }
-.chzn-container-active .chzn-choices {
-  -webkit-box-shadow: 0 0 5px rgba(0,0,0,.3);
-  -moz-box-shadow   : 0 0 5px rgba(0,0,0,.3);
-  box-shadow        : 0 0 5px rgba(0,0,0,.3);
+.chosen-container-active .chosen-choices {
   border: 1px solid #5897fb;
+  box-shadow: 0 0 5px rgba(0, 0, 0, 0.3);
 }
-.chzn-container-active .chzn-choices .search-field input {
+.chosen-container-active .chosen-choices li.search-field input[type="text"] {
   color: #111 !important;
 }
-/* @end */
 
+/* @end */
 /* @group Disabled Support */
-.chzn-disabled {
+.chosen-disabled {
+  opacity: 0.5 !important;
   cursor: default;
-  opacity:0.5 !important;
 }
-.chzn-disabled .chzn-single {
+.chosen-disabled .chosen-single {
   cursor: default;
 }
-.chzn-disabled .chzn-choices .search-choice .search-choice-close {
+.chosen-disabled .chosen-choices .search-choice .search-choice-close {
   cursor: default;
 }
 
+/* @end */
 /* @group Right to Left */
-.chzn-rtl { text-align: right; }
-.chzn-rtl .chzn-single { padding: 0 8px 0 0; overflow: visible; }
-.chzn-rtl .chzn-single span { margin-left: 26px; margin-right: 0; direction: rtl; }
-
-.chzn-rtl .chzn-single div { left: 3px; right: auto; }
-.chzn-rtl .chzn-single abbr {
+.chosen-rtl {
+  text-align: right;
+}
+.chosen-rtl .chosen-single {
+  overflow: visible;
+  padding: 0 8px 0 0;
+}
+.chosen-rtl .chosen-single span {
+  margin-right: 0;
+  margin-left: 26px;
+  direction: rtl;
+}
+.chosen-rtl .chosen-single-with-deselect span {
+  margin-left: 38px;
+}
+.chosen-rtl .chosen-single div {
+  right: auto;
+  left: 3px;
+}
+.chosen-rtl .chosen-single abbr {
+  right: auto;
   left: 26px;
+}
+.chosen-rtl .chosen-choices li {
+  float: right;
+}
+.chosen-rtl .chosen-choices li.search-field input[type="text"] {
+  direction: rtl;
+}
+.chosen-rtl .chosen-choices li.search-choice {
+  margin: 3px 5px 3px 0;
+  padding: 3px 5px 3px 19px;
+}
+.chosen-rtl .chosen-choices li.search-choice .search-choice-close {
   right: auto;
+  left: 4px;
 }
-.chzn-rtl .chzn-choices .search-field input { direction: rtl; }
-.chzn-rtl .chzn-choices li { float: right; }
-.chzn-rtl .chzn-choices .search-choice { padding: 3px 5px 3px 19px; margin: 3px 5px 3px 0; }
-.chzn-rtl .chzn-choices .search-choice .search-choice-close { left: 4px; right: auto; }
-.chzn-rtl.chzn-container-single .chzn-results { margin: 0 0 4px 4px; padding: 0 4px 0 0; }
-.chzn-rtl .chzn-results .group-option { padding-left: 0; padding-right: 15px; }
-.chzn-rtl.chzn-container-active .chzn-single-with-drop div { border-right: none; }
-.chzn-rtl .chzn-search input {
-  background: #fff url('chosen-sprite.png') no-repeat -30px -20px;
-  background: url('chosen-sprite.png') no-repeat -30px -20px, -webkit-gradient(linear, 0 0, 0 100%, color-stop(1%, #eeeeee), color-stop(15%, #ffffff));
-  background: url('chosen-sprite.png') no-repeat -30px -20px, -webkit-linear-gradient(top, #eeeeee 1%, #ffffff 15%);
-  background: url('chosen-sprite.png') no-repeat -30px -20px, -moz-linear-gradient(top, #eeeeee 1%, #ffffff 15%);
-  background: url('chosen-sprite.png') no-repeat -30px -20px, -o-linear-gradient(top, #eeeeee 1%, #ffffff 15%);
-  background: url('chosen-sprite.png') no-repeat -30px -20px, linear-gradient(#eeeeee 1%, #ffffff 15%);
+.chosen-rtl.chosen-container-single-nosearch .chosen-search,
+.chosen-rtl .chosen-drop {
+  left: 9999px;
+}
+.chosen-rtl.chosen-container-single .chosen-results {
+  margin: 0 0 4px 4px;
+  padding: 0 4px 0 0;
+}
+.chosen-rtl .chosen-results li.group-option {
+  padding-right: 15px;
+  padding-left: 0;
+}
+.chosen-rtl.chosen-container-active.chosen-with-drop .chosen-single div {
+  border-right: none;
+}
+.chosen-rtl .chosen-search input[type="text"] {
   padding: 4px 5px 4px 20px;
+  background: white url('chosen-sprite.png') no-repeat -30px -20px;
+  background: url('chosen-sprite.png') no-repeat -30px -20px;
   direction: rtl;
 }
-.chzn-container-single.chzn-rtl .chzn-single div b {
+.chosen-rtl.chosen-container-single .chosen-single div b {
   background-position: 6px 2px;
 }
-.chzn-container-single.chzn-rtl .chzn-single-with-drop div b {
+.chosen-rtl.chosen-container-single.chosen-with-drop .chosen-single div b {
   background-position: -12px 2px;
 }
-/* @end */
 
+/* @end */
 /* @group Retina compatibility */
-@media only screen and (-webkit-min-device-pixel-ratio: 2), only screen and (min-resolution: 144dpi)  {
-  .chzn-rtl .chzn-search input, .chzn-container-single .chzn-single abbr, .chzn-container-single .chzn-single div b, .chzn-container-single .chzn-search input, .chzn-container-multi .chzn-choices .search-choice .search-choice-close, .chzn-container .chzn-results-scroll-down span, .chzn-container .chzn-results-scroll-up span {
-      background-image: url('chosen-sprite@2x.png') !important;
-      background-repeat: no-repeat !important;
-      background-size: 52px 37px !important;
+@media only screen and (-webkit-min-device-pixel-ratio: 2), only screen and (min-resolution: 144dpi) {
+  .chosen-rtl .chosen-search input[type="text"],
+  .chosen-container-single .chosen-single abbr,
+  .chosen-container-single .chosen-single div b,
+  .chosen-container-single .chosen-search input[type="text"],
+  .chosen-container-multi .chosen-choices .search-choice .search-choice-close,
+  .chosen-container .chosen-results-scroll-down span,
+  .chosen-container .chosen-results-scroll-up span {
+    background-image: url('chosen-sprite@2x.png') !important;
+    background-size: 52px 37px !important;
+    background-repeat: no-repeat !important;
   }
 }
-/* @end */
+/* @end */

File diff suppressed because it is too large
+ 487 - 274
main/inc/lib/javascript/chosen/chosen.jquery.js


File diff suppressed because it is too large
+ 1 - 1089
main/inc/lib/javascript/chosen/chosen.jquery.min.js


+ 0 - 1646
main/inc/lib/javascript/jquery-ui/ui/i18n/jquery-ui-i18n.js

@@ -1,1646 +0,0 @@
-/*! jQuery UI - v1.8.21 - 2012-06-05
-* https://github.com/jquery/jquery-ui
-* Includes: jquery.ui.datepicker-af.js, jquery.ui.datepicker-ar-DZ.js, jquery.ui.datepicker-ar.js, jquery.ui.datepicker-az.js, jquery.ui.datepicker-bg.js, jquery.ui.datepicker-bs.js, jquery.ui.datepicker-ca.js, jquery.ui.datepicker-cs.js, jquery.ui.datepicker-cy-GB.js, jquery.ui.datepicker-da.js, jquery.ui.datepicker-de.js, jquery.ui.datepicker-el.js, jquery.ui.datepicker-en-AU.js, jquery.ui.datepicker-en-GB.js, jquery.ui.datepicker-en-NZ.js, jquery.ui.datepicker-eo.js, jquery.ui.datepicker-es.js, jquery.ui.datepicker-et.js, jquery.ui.datepicker-eu.js, jquery.ui.datepicker-fa.js, jquery.ui.datepicker-fi.js, jquery.ui.datepicker-fo.js, jquery.ui.datepicker-fr-CH.js, jquery.ui.datepicker-fr.js, jquery.ui.datepicker-gl.js, jquery.ui.datepicker-he.js, jquery.ui.datepicker-hi.js, jquery.ui.datepicker-hr.js, jquery.ui.datepicker-hu.js, jquery.ui.datepicker-hy.js, jquery.ui.datepicker-id.js, jquery.ui.datepicker-is.js, jquery.ui.datepicker-it.js, jquery.ui.datepicker-ja.js, jquery.ui.datepicker-ka.js, jquery.ui.datepicker-kk.js, jquery.ui.datepicker-km.js, jquery.ui.datepicker-ko.js, jquery.ui.datepicker-lb.js, jquery.ui.datepicker-lt.js, jquery.ui.datepicker-lv.js, jquery.ui.datepicker-mk.js, jquery.ui.datepicker-ml.js, jquery.ui.datepicker-ms.js, jquery.ui.datepicker-nl-BE.js, jquery.ui.datepicker-nl.js, jquery.ui.datepicker-no.js, jquery.ui.datepicker-pl.js, jquery.ui.datepicker-pt-BR.js, jquery.ui.datepicker-pt.js, jquery.ui.datepicker-rm.js, jquery.ui.datepicker-ro.js, jquery.ui.datepicker-ru.js, jquery.ui.datepicker-sk.js, jquery.ui.datepicker-sl.js, jquery.ui.datepicker-sq.js, jquery.ui.datepicker-sr-SR.js, jquery.ui.datepicker-sr.js, jquery.ui.datepicker-sv.js, jquery.ui.datepicker-ta.js, jquery.ui.datepicker-th.js, jquery.ui.datepicker-tj.js, jquery.ui.datepicker-tr.js, jquery.ui.datepicker-uk.js, jquery.ui.datepicker-vi.js, jquery.ui.datepicker-zh-CN.js, jquery.ui.datepicker-zh-HK.js, jquery.ui.datepicker-zh-TW.js
-* Copyright (c) 2012 AUTHORS.txt; Licensed MIT, GPL */
-
-/* Afrikaans initialisation for the jQuery UI date picker plugin. */
-/* Written by Renier Pretorius. */
-jQuery(function($){
-	$.datepicker.regional['af'] = {
-		closeText: 'Selekteer',
-		prevText: 'Vorige',
-		nextText: 'Volgende',
-		currentText: 'Vandag',
-		monthNames: ['Januarie','Februarie','Maart','April','Mei','Junie',
-		'Julie','Augustus','September','Oktober','November','Desember'],
-		monthNamesShort: ['Jan', 'Feb', 'Mrt', 'Apr', 'Mei', 'Jun',
-		'Jul', 'Aug', 'Sep', 'Okt', 'Nov', 'Des'],
-		dayNames: ['Sondag', 'Maandag', 'Dinsdag', 'Woensdag', 'Donderdag', 'Vrydag', 'Saterdag'],
-		dayNamesShort: ['Son', 'Maa', 'Din', 'Woe', 'Don', 'Vry', 'Sat'],
-		dayNamesMin: ['So','Ma','Di','Wo','Do','Vr','Sa'],
-		weekHeader: 'Wk',
-		dateFormat: 'dd/mm/yy',
-		firstDay: 1,
-		isRTL: false,
-		showMonthAfterYear: false,
-		yearSuffix: ''};
-	$.datepicker.setDefaults($.datepicker.regional['af']);
-});
-
-/* Algerian Arabic Translation for jQuery UI date picker plugin. (can be used for Tunisia)*/
-/* Mohamed Cherif BOUCHELAGHEM -- cherifbouchelaghem@yahoo.fr */
-
-jQuery(function($){
-	$.datepicker.regional['ar-DZ'] = {
-		closeText: 'إغلاق',
-		prevText: '&#x3c;السابق',
-		nextText: 'التالي&#x3e;',
-		currentText: 'اليوم',
-		monthNames: ['جانفي', 'فيفري', 'مارس', 'أفريل', 'ماي', 'جوان',
-		'جويلية', 'أوت', 'سبتمبر','أكتوبر', 'نوفمبر', 'ديسمبر'],
-		monthNamesShort: ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12'],
-		dayNames: ['الأحد', 'الاثنين', 'الثلاثاء', 'الأربعاء', 'الخميس', 'الجمعة', 'السبت'],
-		dayNamesShort: ['الأحد', 'الاثنين', 'الثلاثاء', 'الأربعاء', 'الخميس', 'الجمعة', 'السبت'],
-		dayNamesMin: ['الأحد', 'الاثنين', 'الثلاثاء', 'الأربعاء', 'الخميس', 'الجمعة', 'السبت'],
-		weekHeader: 'أسبوع',
-		dateFormat: 'dd/mm/yy',
-		firstDay: 6,
-  		isRTL: true,
-		showMonthAfterYear: false,
-		yearSuffix: ''};
-	$.datepicker.setDefaults($.datepicker.regional['ar-DZ']);
-});
-
-/* Arabic Translation for jQuery UI date picker plugin. */
-/* Khaled Alhourani -- me@khaledalhourani.com */
-/* NOTE: monthNames are the original months names and they are the Arabic names, not the new months name فبراير - يناير and there isn't any Arabic roots for these months */
-jQuery(function($){
-	$.datepicker.regional['ar'] = {
-		closeText: 'إغلاق',
-		prevText: '&#x3c;السابق',
-		nextText: 'التالي&#x3e;',
-		currentText: 'اليوم',
-		monthNames: ['كانون الثاني', 'شباط', 'آذار', 'نيسان', 'مايو', 'حزيران',
-		'تموز', 'آب', 'أيلول',	'تشرين الأول', 'تشرين الثاني', 'كانون الأول'],
-		monthNamesShort: ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12'],
-		dayNames: ['الأحد', 'الاثنين', 'الثلاثاء', 'الأربعاء', 'الخميس', 'الجمعة', 'السبت'],
-		dayNamesShort: ['الأحد', 'الاثنين', 'الثلاثاء', 'الأربعاء', 'الخميس', 'الجمعة', 'السبت'],
-		dayNamesMin: ['ح', 'ن', 'ث', 'ر', 'خ', 'ج', 'س'],
-		weekHeader: 'أسبوع',
-		dateFormat: 'dd/mm/yy',
-		firstDay: 6,
-  		isRTL: true,
-		showMonthAfterYear: false,
-		yearSuffix: ''};
-	$.datepicker.setDefaults($.datepicker.regional['ar']);
-});
-/* Azerbaijani (UTF-8) initialisation for the jQuery UI date picker plugin. */
-/* Written by Jamil Najafov (necefov33@gmail.com). */
-jQuery(function($) {
-	$.datepicker.regional['az'] = {
-		closeText: 'Bağla',
-		prevText: '&#x3c;Geri',
-		nextText: 'İrəli&#x3e;',
-		currentText: 'Bugün',
-		monthNames: ['Yanvar','Fevral','Mart','Aprel','May','İyun',
-		'İyul','Avqust','Sentyabr','Oktyabr','Noyabr','Dekabr'],
-		monthNamesShort: ['Yan','Fev','Mar','Apr','May','İyun',
-		'İyul','Avq','Sen','Okt','Noy','Dek'],
-		dayNames: ['Bazar','Bazar ertəsi','Çərşənbə axşamı','Çərşənbə','Cümə axşamı','Cümə','Şənbə'],
-		dayNamesShort: ['B','Be','Ça','Ç','Ca','C','Ş'],
-		dayNamesMin: ['B','B','Ç','С','Ç','C','Ş'],
-		weekHeader: 'Hf',
-		dateFormat: 'dd.mm.yy',
-		firstDay: 1,
-		isRTL: false,
-		showMonthAfterYear: false,
-		yearSuffix: ''};
-	$.datepicker.setDefaults($.datepicker.regional['az']);
-});
-/* Bulgarian initialisation for the jQuery UI date picker plugin. */
-/* Written by Stoyan Kyosev (http://svest.org). */
-jQuery(function($){
-    $.datepicker.regional['bg'] = {
-        closeText: 'затвори',
-        prevText: '&#x3c;назад',
-        nextText: 'напред&#x3e;',
-		nextBigText: '&#x3e;&#x3e;',
-        currentText: 'днес',
-        monthNames: ['Януари','Февруари','Март','Април','Май','Юни',
-        'Юли','Август','Септември','Октомври','Ноември','Декември'],
-        monthNamesShort: ['Яну','Фев','Мар','Апр','Май','Юни',
-        'Юли','Авг','Сеп','Окт','Нов','Дек'],
-        dayNames: ['Неделя','Понеделник','Вторник','Сряда','Четвъртък','Петък','Събота'],
-        dayNamesShort: ['Нед','Пон','Вто','Сря','Чет','Пет','Съб'],
-        dayNamesMin: ['Не','По','Вт','Ср','Че','Пе','Съ'],
-		weekHeader: 'Wk',
-        dateFormat: 'dd.mm.yy',
-		firstDay: 1,
-        isRTL: false,
-		showMonthAfterYear: false,
-		yearSuffix: ''};
-    $.datepicker.setDefaults($.datepicker.regional['bg']);
-});
-
-/* Bosnian i18n for the jQuery UI date picker plugin. */
-/* Written by Kenan Konjo. */
-jQuery(function($){
-	$.datepicker.regional['bs'] = {
-		closeText: 'Zatvori', 
-		prevText: '&#x3c;', 
-		nextText: '&#x3e;', 
-		currentText: 'Danas', 
-		monthNames: ['Januar','Februar','Mart','April','Maj','Juni',
-		'Juli','August','Septembar','Oktobar','Novembar','Decembar'],
-		monthNamesShort: ['Jan','Feb','Mar','Apr','Maj','Jun',
-		'Jul','Aug','Sep','Okt','Nov','Dec'],
-		dayNames: ['Nedelja','Ponedeljak','Utorak','Srijeda','Četvrtak','Petak','Subota'],
-		dayNamesShort: ['Ned','Pon','Uto','Sri','Čet','Pet','Sub'],
-		dayNamesMin: ['Ne','Po','Ut','Sr','Če','Pe','Su'],
-		weekHeader: 'Wk',
-		dateFormat: 'dd.mm.yy',
-		firstDay: 1,
-		isRTL: false,
-		showMonthAfterYear: false,
-		yearSuffix: ''};
-	$.datepicker.setDefaults($.datepicker.regional['bs']);
-});
-/* Inicialització en català per a l'extenció 'calendar' per jQuery. */
-/* Writers: (joan.leon@gmail.com). */
-jQuery(function($){
-	$.datepicker.regional['ca'] = {
-		closeText: 'Tancar',
-		prevText: '&#x3c;Ant',
-		nextText: 'Seg&#x3e;',
-		currentText: 'Avui',
-		monthNames: ['Gener','Febrer','Mar&ccedil;','Abril','Maig','Juny',
-		'Juliol','Agost','Setembre','Octubre','Novembre','Desembre'],
-		monthNamesShort: ['Gen','Feb','Mar','Abr','Mai','Jun',
-		'Jul','Ago','Set','Oct','Nov','Des'],
-		dayNames: ['Diumenge','Dilluns','Dimarts','Dimecres','Dijous','Divendres','Dissabte'],
-		dayNamesShort: ['Dug','Dln','Dmt','Dmc','Djs','Dvn','Dsb'],
-		dayNamesMin: ['Dg','Dl','Dt','Dc','Dj','Dv','Ds'],
-		weekHeader: 'Sm',
-		dateFormat: 'dd/mm/yy',
-		firstDay: 1,
-		isRTL: false,
-		showMonthAfterYear: false,
-		yearSuffix: ''};
-	$.datepicker.setDefaults($.datepicker.regional['ca']);
-});
-/* Czech initialisation for the jQuery UI date picker plugin. */
-/* Written by Tomas Muller (tomas@tomas-muller.net). */
-jQuery(function($){
-	$.datepicker.regional['cs'] = {
-		closeText: 'Zavřít',
-		prevText: '&#x3c;Dříve',
-		nextText: 'Později&#x3e;',
-		currentText: 'Nyní',
-		monthNames: ['leden','únor','březen','duben','květen','červen',
-        'červenec','srpen','září','říjen','listopad','prosinec'],
-		monthNamesShort: ['led','úno','bře','dub','kvě','čer',
-		'čvc','srp','zář','říj','lis','pro'],
-		dayNames: ['neděle', 'pondělí', 'úterý', 'středa', 'čtvrtek', 'pátek', 'sobota'],
-		dayNamesShort: ['ne', 'po', 'út', 'st', 'čt', 'pá', 'so'],
-		dayNamesMin: ['ne','po','út','st','čt','pá','so'],
-		weekHeader: 'Týd',
-		dateFormat: 'dd.mm.yy',
-		firstDay: 1,
-		isRTL: false,
-		showMonthAfterYear: false,
-		yearSuffix: ''};
-	$.datepicker.setDefaults($.datepicker.regional['cs']);
-});
-
-/* Welsh/UK initialisation for the jQuery UI date picker plugin. */
-/* Written by William Griffiths. */
-jQuery(function($){
-	$.datepicker.regional['cy-GB'] = {
-		closeText: 'Done',
-		prevText: 'Prev',
-		nextText: 'Next',
-		currentText: 'Today',
-		monthNames: ['Ionawr','Chwefror','Mawrth','Ebrill','Mai','Mehefin',
-		'Gorffennaf','Awst','Medi','Hydref','Tachwedd','Rhagfyr'],
-		monthNamesShort: ['Ion', 'Chw', 'Maw', 'Ebr', 'Mai', 'Meh',
-		'Gor', 'Aws', 'Med', 'Hyd', 'Tac', 'Rha'],
-		dayNames: ['Dydd Sul', 'Dydd Llun', 'Dydd Mawrth', 'Dydd Mercher', 'Dydd Iau', 'Dydd Gwener', 'Dydd Sadwrn'],
-		dayNamesShort: ['Sul', 'Llu', 'Maw', 'Mer', 'Iau', 'Gwe', 'Sad'],
-		dayNamesMin: ['Su','Ll','Ma','Me','Ia','Gw','Sa'],
-		weekHeader: 'Wy',
-		dateFormat: 'dd/mm/yy',
-		firstDay: 1,
-		isRTL: false,
-		showMonthAfterYear: false,
-		yearSuffix: ''};
-	$.datepicker.setDefaults($.datepicker.regional['cy-GB']);
-});
-/* Danish initialisation for the jQuery UI date picker plugin. */
-/* Written by Jan Christensen ( deletestuff@gmail.com). */
-jQuery(function($){
-    $.datepicker.regional['da'] = {
-		closeText: 'Luk',
-        prevText: '&#x3c;Forrige',
-		nextText: 'Næste&#x3e;',
-		currentText: 'Idag',
-        monthNames: ['Januar','Februar','Marts','April','Maj','Juni',
-        'Juli','August','September','Oktober','November','December'],
-        monthNamesShort: ['Jan','Feb','Mar','Apr','Maj','Jun',
-        'Jul','Aug','Sep','Okt','Nov','Dec'],
-		dayNames: ['Søndag','Mandag','Tirsdag','Onsdag','Torsdag','Fredag','Lørdag'],
-		dayNamesShort: ['Søn','Man','Tir','Ons','Tor','Fre','Lør'],
-		dayNamesMin: ['Sø','Ma','Ti','On','To','Fr','Lø'],
-		weekHeader: 'Uge',
-        dateFormat: 'dd-mm-yy',
-		firstDay: 1,
-		isRTL: false,
-		showMonthAfterYear: false,
-		yearSuffix: ''};
-    $.datepicker.setDefaults($.datepicker.regional['da']);
-});
-
-/* German initialisation for the jQuery UI date picker plugin. */
-/* Written by Milian Wolff (mail@milianw.de). */
-jQuery(function($){
-	$.datepicker.regional['de'] = {
-		closeText: 'schließen',
-		prevText: '&#x3c;zurück',
-		nextText: 'Vor&#x3e;',
-		currentText: 'heute',
-		monthNames: ['Januar','Februar','März','April','Mai','Juni',
-		'Juli','August','September','Oktober','November','Dezember'],
-		monthNamesShort: ['Jan','Feb','Mär','Apr','Mai','Jun',
-		'Jul','Aug','Sep','Okt','Nov','Dez'],
-		dayNames: ['Sonntag','Montag','Dienstag','Mittwoch','Donnerstag','Freitag','Samstag'],
-		dayNamesShort: ['So','Mo','Di','Mi','Do','Fr','Sa'],
-		dayNamesMin: ['So','Mo','Di','Mi','Do','Fr','Sa'],
-		weekHeader: 'KW',
-		dateFormat: 'dd.mm.yy',
-		firstDay: 1,
-		isRTL: false,
-		showMonthAfterYear: false,
-		yearSuffix: ''};
-	$.datepicker.setDefaults($.datepicker.regional['de']);
-});
-
-/* Greek (el) initialisation for the jQuery UI date picker plugin. */
-/* Written by Alex Cicovic (http://www.alexcicovic.com) */
-jQuery(function($){
-	$.datepicker.regional['el'] = {
-		closeText: 'Κλείσιμο',
-		prevText: 'Προηγούμενος',
-		nextText: 'Επόμενος',
-		currentText: 'Τρέχων Μήνας',
-		monthNames: ['Ιανουάριος','Φεβρουάριος','Μάρτιος','Απρίλιος','Μάιος','Ιούνιος',
-		'Ιούλιος','Αύγουστος','Σεπτέμβριος','Οκτώβριος','Νοέμβριος','Δεκέμβριος'],
-		monthNamesShort: ['Ιαν','Φεβ','Μαρ','Απρ','Μαι','Ιουν',
-		'Ιουλ','Αυγ','Σεπ','Οκτ','Νοε','Δεκ'],
-		dayNames: ['Κυριακή','Δευτέρα','Τρίτη','Τετάρτη','Πέμπτη','Παρασκευή','Σάββατο'],
-		dayNamesShort: ['Κυρ','Δευ','Τρι','Τετ','Πεμ','Παρ','Σαβ'],
-		dayNamesMin: ['Κυ','Δε','Τρ','Τε','Πε','Πα','Σα'],
-		weekHeader: 'Εβδ',
-		dateFormat: 'dd/mm/yy',
-		firstDay: 1,
-		isRTL: false,
-		showMonthAfterYear: false,
-		yearSuffix: ''};
-	$.datepicker.setDefaults($.datepicker.regional['el']);
-});
-/* English/Australia initialisation for the jQuery UI date picker plugin. */
-/* Based on the en-GB initialisation. */
-jQuery(function($){
-	$.datepicker.regional['en-AU'] = {
-		closeText: 'Done',
-		prevText: 'Prev',
-		nextText: 'Next',
-		currentText: 'Today',
-		monthNames: ['January','February','March','April','May','June',
-		'July','August','September','October','November','December'],
-		monthNamesShort: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
-		'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'],
-		dayNames: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'],
-		dayNamesShort: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'],
-		dayNamesMin: ['Su','Mo','Tu','We','Th','Fr','Sa'],
-		weekHeader: 'Wk',
-		dateFormat: 'dd/mm/yy',
-		firstDay: 1,
-		isRTL: false,
-		showMonthAfterYear: false,
-		yearSuffix: ''};
-	$.datepicker.setDefaults($.datepicker.regional['en-AU']);
-});
-
-/* English/UK initialisation for the jQuery UI date picker plugin. */
-/* Written by Stuart. */
-jQuery(function($){
-	$.datepicker.regional['en-GB'] = {
-		closeText: 'Done',
-		prevText: 'Prev',
-		nextText: 'Next',
-		currentText: 'Today',
-		monthNames: ['January','February','March','April','May','June',
-		'July','August','September','October','November','December'],
-		monthNamesShort: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
-		'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'],
-		dayNames: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'],
-		dayNamesShort: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'],
-		dayNamesMin: ['Su','Mo','Tu','We','Th','Fr','Sa'],
-		weekHeader: 'Wk',
-		dateFormat: 'dd/mm/yy',
-		firstDay: 1,
-		isRTL: false,
-		showMonthAfterYear: false,
-		yearSuffix: ''};
-	$.datepicker.setDefaults($.datepicker.regional['en-GB']);
-});
-
-/* English/New Zealand initialisation for the jQuery UI date picker plugin. */
-/* Based on the en-GB initialisation. */
-jQuery(function($){
-	$.datepicker.regional['en-NZ'] = {
-		closeText: 'Done',
-		prevText: 'Prev',
-		nextText: 'Next',
-		currentText: 'Today',
-		monthNames: ['January','February','March','April','May','June',
-		'July','August','September','October','November','December'],
-		monthNamesShort: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
-		'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'],
-		dayNames: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'],
-		dayNamesShort: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'],
-		dayNamesMin: ['Su','Mo','Tu','We','Th','Fr','Sa'],
-		weekHeader: 'Wk',
-		dateFormat: 'dd/mm/yy',
-		firstDay: 1,
-		isRTL: false,
-		showMonthAfterYear: false,
-		yearSuffix: ''};
-	$.datepicker.setDefaults($.datepicker.regional['en-NZ']);
-});
-
-/* Esperanto initialisation for the jQuery UI date picker plugin. */
-/* Written by Olivier M. (olivierweb@ifrance.com). */
-jQuery(function($){
-	$.datepicker.regional['eo'] = {
-		closeText: 'Fermi',
-		prevText: '&lt;Anta',
-		nextText: 'Sekv&gt;',
-		currentText: 'Nuna',
-		monthNames: ['Januaro','Februaro','Marto','Aprilo','Majo','Junio',
-		'Julio','Aŭgusto','Septembro','Oktobro','Novembro','Decembro'],
-		monthNamesShort: ['Jan','Feb','Mar','Apr','Maj','Jun',
-		'Jul','Aŭg','Sep','Okt','Nov','Dec'],
-		dayNames: ['Dimanĉo','Lundo','Mardo','Merkredo','Ĵaŭdo','Vendredo','Sabato'],
-		dayNamesShort: ['Dim','Lun','Mar','Mer','Ĵaŭ','Ven','Sab'],
-		dayNamesMin: ['Di','Lu','Ma','Me','Ĵa','Ve','Sa'],
-		weekHeader: 'Sb',
-		dateFormat: 'dd/mm/yy',
-		firstDay: 0,
-		isRTL: false,
-		showMonthAfterYear: false,
-		yearSuffix: ''};
-	$.datepicker.setDefaults($.datepicker.regional['eo']);
-});
-
-/* Inicialización en español para la extensión 'UI date picker' para jQuery. */
-/* Traducido por Vester (xvester@gmail.com). */
-jQuery(function($){
-	$.datepicker.regional['es'] = {
-		closeText: 'Cerrar',
-		prevText: '&#x3c;Ant',
-		nextText: 'Sig&#x3e;',
-		currentText: 'Hoy',
-		monthNames: ['Enero','Febrero','Marzo','Abril','Mayo','Junio',
-		'Julio','Agosto','Septiembre','Octubre','Noviembre','Diciembre'],
-		monthNamesShort: ['Ene','Feb','Mar','Abr','May','Jun',
-		'Jul','Ago','Sep','Oct','Nov','Dic'],
-		dayNames: ['Domingo','Lunes','Martes','Mi&eacute;rcoles','Jueves','Viernes','S&aacute;bado'],
-		dayNamesShort: ['Dom','Lun','Mar','Mi&eacute;','Juv','Vie','S&aacute;b'],
-		dayNamesMin: ['Do','Lu','Ma','Mi','Ju','Vi','S&aacute;'],
-		weekHeader: 'Sm',
-		dateFormat: 'dd/mm/yy',
-		firstDay: 1,
-		isRTL: false,
-		showMonthAfterYear: false,
-		yearSuffix: ''};
-	$.datepicker.setDefaults($.datepicker.regional['es']);
-});
-/* Estonian initialisation for the jQuery UI date picker plugin. */
-/* Written by Mart Sõmermaa (mrts.pydev at gmail com). */
-jQuery(function($){
-	$.datepicker.regional['et'] = {
-		closeText: 'Sulge',
-		prevText: 'Eelnev',
-		nextText: 'Järgnev',
-		currentText: 'Täna',
-		monthNames: ['Jaanuar','Veebruar','Märts','Aprill','Mai','Juuni',
-		'Juuli','August','September','Oktoober','November','Detsember'],
-		monthNamesShort: ['Jaan', 'Veebr', 'Märts', 'Apr', 'Mai', 'Juuni',
-		'Juuli', 'Aug', 'Sept', 'Okt', 'Nov', 'Dets'],
-		dayNames: ['Pühapäev', 'Esmaspäev', 'Teisipäev', 'Kolmapäev', 'Neljapäev', 'Reede', 'Laupäev'],
-		dayNamesShort: ['Pühap', 'Esmasp', 'Teisip', 'Kolmap', 'Neljap', 'Reede', 'Laup'],
-		dayNamesMin: ['P','E','T','K','N','R','L'],
-		weekHeader: 'näd',
-		dateFormat: 'dd.mm.yy',
-		firstDay: 1,
-		isRTL: false,
-		showMonthAfterYear: false,
-		yearSuffix: ''};
-	$.datepicker.setDefaults($.datepicker.regional['et']);
-}); 
-/* Euskarako oinarria 'UI date picker' jquery-ko extentsioarentzat */
-/* Karrikas-ek itzulia (karrikas@karrikas.com) */
-jQuery(function($){
-	$.datepicker.regional['eu'] = {
-		closeText: 'Egina',
-		prevText: '&#x3c;Aur',
-		nextText: 'Hur&#x3e;',
-		currentText: 'Gaur',
-		monthNames: ['urtarrila','otsaila','martxoa','apirila','maiatza','ekaina',
-			'uztaila','abuztua','iraila','urria','azaroa','abendua'],
-		monthNamesShort: ['urt.','ots.','mar.','api.','mai.','eka.',
-			'uzt.','abu.','ira.','urr.','aza.','abe.'],
-		dayNames: ['igandea','astelehena','asteartea','asteazkena','osteguna','ostirala','larunbata'],
-		dayNamesShort: ['ig.','al.','ar.','az.','og.','ol.','lr.'],
-		dayNamesMin: ['ig','al','ar','az','og','ol','lr'],
-		weekHeader: 'As',
-		dateFormat: 'yy-mm-dd',
-		firstDay: 1,
-		isRTL: false,
-		showMonthAfterYear: false,
-		yearSuffix: ''};
-	$.datepicker.setDefaults($.datepicker.regional['eu']);
-});
-/* Persian (Farsi) Translation for the jQuery UI date picker plugin. */
-/* Javad Mowlanezhad -- jmowla@gmail.com */
-/* Jalali calendar should supported soon! (Its implemented but I have to test it) */
-jQuery(function($) {
-	$.datepicker.regional['fa'] = {
-		closeText: 'بستن',
-		prevText: '&#x3C;قبلی',
-		nextText: 'بعدی&#x3E;',
-		currentText: 'امروز',
-		monthNames: [
-			'فروردين',
-			'ارديبهشت',
-			'خرداد',
-			'تير',
-			'مرداد',
-			'شهريور',
-			'مهر',
-			'آبان',
-			'آذر',
-			'دی',
-			'بهمن',
-			'اسفند'
-		],
-		monthNamesShort: ['1','2','3','4','5','6','7','8','9','10','11','12'],
-		dayNames: [
-			'يکشنبه',
-			'دوشنبه',
-			'سه‌شنبه',
-			'چهارشنبه',
-			'پنجشنبه',
-			'جمعه',
-			'شنبه'
-		],
-		dayNamesShort: [
-			'ی',
-			'د',
-			'س',
-			'چ',
-			'پ',
-			'ج', 
-			'ش'
-		],
-		dayNamesMin: [
-			'ی',
-			'د',
-			'س',
-			'چ',
-			'پ',
-			'ج', 
-			'ش'
-		],
-		weekHeader: 'هف',
-		dateFormat: 'yy/mm/dd',
-		firstDay: 6,
-		isRTL: true,
-		showMonthAfterYear: false,
-		yearSuffix: ''};
-	$.datepicker.setDefaults($.datepicker.regional['fa']);
-});
-/* Finnish initialisation for the jQuery UI date picker plugin. */
-/* Written by Harri Kilpiö (harrikilpio@gmail.com). */
-jQuery(function($){
-	$.datepicker.regional['fi'] = {
-		closeText: 'Sulje',
-		prevText: '&#xAB;Edellinen',
-		nextText: 'Seuraava&#xBB;',
-		currentText: 'T&#xE4;n&#xE4;&#xE4;n',
-		monthNames: ['Tammikuu','Helmikuu','Maaliskuu','Huhtikuu','Toukokuu','Kes&#xE4;kuu',
-		'Hein&#xE4;kuu','Elokuu','Syyskuu','Lokakuu','Marraskuu','Joulukuu'],
-		monthNamesShort: ['Tammi','Helmi','Maalis','Huhti','Touko','Kes&#xE4;',
-		'Hein&#xE4;','Elo','Syys','Loka','Marras','Joulu'],
-		dayNamesShort: ['Su','Ma','Ti','Ke','To','Pe','La'],
-		dayNames: ['Sunnuntai','Maanantai','Tiistai','Keskiviikko','Torstai','Perjantai','Lauantai'],
-		dayNamesMin: ['Su','Ma','Ti','Ke','To','Pe','La'],
-		weekHeader: 'Vk',
-		dateFormat: 'dd.mm.yy',
-		firstDay: 1,
-		isRTL: false,
-		showMonthAfterYear: false,
-		yearSuffix: ''};
-	$.datepicker.setDefaults($.datepicker.regional['fi']);
-});
-
-/* Faroese initialisation for the jQuery UI date picker plugin */
-/* Written by Sverri Mohr Olsen, sverrimo@gmail.com */
-jQuery(function($){
-	$.datepicker.regional['fo'] = {
-		closeText: 'Lat aftur',
-		prevText: '&#x3c;Fyrra',
-		nextText: 'Næsta&#x3e;',
-		currentText: 'Í dag',
-		monthNames: ['Januar','Februar','Mars','Apríl','Mei','Juni',
-		'Juli','August','September','Oktober','November','Desember'],
-		monthNamesShort: ['Jan','Feb','Mar','Apr','Mei','Jun',
-		'Jul','Aug','Sep','Okt','Nov','Des'],
-		dayNames: ['Sunnudagur','Mánadagur','Týsdagur','Mikudagur','Hósdagur','Fríggjadagur','Leyardagur'],
-		dayNamesShort: ['Sun','Mán','Týs','Mik','Hós','Frí','Ley'],
-		dayNamesMin: ['Su','Má','Tý','Mi','Hó','Fr','Le'],
-		weekHeader: 'Vk',
-		dateFormat: 'dd-mm-yy',
-		firstDay: 0,
-		isRTL: false,
-		showMonthAfterYear: false,
-		yearSuffix: ''};
-	$.datepicker.setDefaults($.datepicker.regional['fo']);
-});
-
-/* Swiss-French initialisation for the jQuery UI date picker plugin. */
-/* Written Martin Voelkle (martin.voelkle@e-tc.ch). */
-jQuery(function($){
-	$.datepicker.regional['fr-CH'] = {
-		closeText: 'Fermer',
-		prevText: '&#x3c;Préc',
-		nextText: 'Suiv&#x3e;',
-		currentText: 'Courant',
-		monthNames: ['Janvier','Février','Mars','Avril','Mai','Juin',
-		'Juillet','Août','Septembre','Octobre','Novembre','Décembre'],
-		monthNamesShort: ['Jan','Fév','Mar','Avr','Mai','Jun',
-		'Jul','Aoû','Sep','Oct','Nov','Déc'],
-		dayNames: ['Dimanche','Lundi','Mardi','Mercredi','Jeudi','Vendredi','Samedi'],
-		dayNamesShort: ['Dim','Lun','Mar','Mer','Jeu','Ven','Sam'],
-		dayNamesMin: ['Di','Lu','Ma','Me','Je','Ve','Sa'],
-		weekHeader: 'Sm',
-		dateFormat: 'dd.mm.yy',
-		firstDay: 1,
-		isRTL: false,
-		showMonthAfterYear: false,
-		yearSuffix: ''};
-	$.datepicker.setDefaults($.datepicker.regional['fr-CH']);
-});
-/* French initialisation for the jQuery UI date picker plugin. */
-/* Written by Keith Wood (kbwood{at}iinet.com.au),
-              Stéphane Nahmani (sholby@sholby.net),
-              Stéphane Raimbault <stephane.raimbault@gmail.com> */
-jQuery(function($){
-	$.datepicker.regional['fr'] = {
-		closeText: 'Fermer',
-		prevText: 'Précédent',
-		nextText: 'Suivant',
-		currentText: 'Aujourd\'hui',
-		monthNames: ['Janvier','Février','Mars','Avril','Mai','Juin',
-		'Juillet','Août','Septembre','Octobre','Novembre','Décembre'],
-		monthNamesShort: ['Janv.','Févr.','Mars','Avril','Mai','Juin',
-		'Juil.','Août','Sept.','Oct.','Nov.','Déc.'],
-		dayNames: ['Dimanche','Lundi','Mardi','Mercredi','Jeudi','Vendredi','Samedi'],
-		dayNamesShort: ['Dim.','Lun.','Mar.','Mer.','Jeu.','Ven.','Sam.'],
-		dayNamesMin: ['D','L','M','M','J','V','S'],
-		weekHeader: 'Sem.',
-		dateFormat: 'dd/mm/yy',
-		firstDay: 1,
-		isRTL: false,
-		showMonthAfterYear: false,
-		yearSuffix: ''};
-	$.datepicker.setDefaults($.datepicker.regional['fr']);
-});
-
-/* Galician localization for 'UI date picker' jQuery extension. */
-/* Translated by Jorge Barreiro <yortx.barry@gmail.com>. */
-jQuery(function($){
-	$.datepicker.regional['gl'] = {
-		closeText: 'Pechar',
-		prevText: '&#x3c;Ant',
-		nextText: 'Seg&#x3e;',
-		currentText: 'Hoxe',
-		monthNames: ['Xaneiro','Febreiro','Marzo','Abril','Maio','Xuño',
-		'Xullo','Agosto','Setembro','Outubro','Novembro','Decembro'],
-		monthNamesShort: ['Xan','Feb','Mar','Abr','Mai','Xuñ',
-		'Xul','Ago','Set','Out','Nov','Dec'],
-		dayNames: ['Domingo','Luns','Martes','M&eacute;rcores','Xoves','Venres','S&aacute;bado'],
-		dayNamesShort: ['Dom','Lun','Mar','M&eacute;r','Xov','Ven','S&aacute;b'],
-		dayNamesMin: ['Do','Lu','Ma','M&eacute;','Xo','Ve','S&aacute;'],
-		weekHeader: 'Sm',
-		dateFormat: 'dd/mm/yy',
-		firstDay: 1,
-		isRTL: false,
-		showMonthAfterYear: false,
-		yearSuffix: ''};
-	$.datepicker.setDefaults($.datepicker.regional['gl']);
-});
-/* Hebrew initialisation for the UI Datepicker extension. */
-/* Written by Amir Hardon (ahardon at gmail dot com). */
-jQuery(function($){
-	$.datepicker.regional['he'] = {
-		closeText: 'סגור',
-		prevText: '&#x3c;הקודם',
-		nextText: 'הבא&#x3e;',
-		currentText: 'היום',
-		monthNames: ['ינואר','פברואר','מרץ','אפריל','מאי','יוני',
-		'יולי','אוגוסט','ספטמבר','אוקטובר','נובמבר','דצמבר'],
-		monthNamesShort: ['ינו','פבר','מרץ','אפר','מאי','יוני',
-		'יולי','אוג','ספט','אוק','נוב','דצמ'],
-		dayNames: ['ראשון','שני','שלישי','רביעי','חמישי','שישי','שבת'],
-		dayNamesShort: ['א\'','ב\'','ג\'','ד\'','ה\'','ו\'','שבת'],
-		dayNamesMin: ['א\'','ב\'','ג\'','ד\'','ה\'','ו\'','שבת'],
-		weekHeader: 'Wk',
-		dateFormat: 'dd/mm/yy',
-		firstDay: 0,
-		isRTL: true,
-		showMonthAfterYear: false,
-		yearSuffix: ''};
-	$.datepicker.setDefaults($.datepicker.regional['he']);
-});
-
-/* Hindi initialisation for the jQuery UI date picker plugin. */
-/* Written by Michael Dawart. */
-jQuery(function($){
-	$.datepicker.regional['hi'] = {
-		closeText: 'बंद',
-		prevText: 'पिछला',
-		nextText: 'अगला',
-		currentText: 'आज',
-		monthNames: ['जनवरी ','फरवरी','मार्च','अप्रेल','मई','जून',
-		'जूलाई','अगस्त ','सितम्बर','अक्टूबर','नवम्बर','दिसम्बर'],
-		monthNamesShort: ['जन', 'फर', 'मार्च', 'अप्रेल', 'मई', 'जून',
-		'जूलाई', 'अग', 'सित', 'अक्ट', 'नव', 'दि'],
-		dayNames: ['रविवार', 'सोमवार', 'मंगलवार', 'बुधवार', 'गुरुवार', 'शुक्रवार', 'शनिवार'],
-		dayNamesShort: ['रवि', 'सोम', 'मंगल', 'बुध', 'गुरु', 'शुक्र', 'शनि'],
-		dayNamesMin: ['रवि', 'सोम', 'मंगल', 'बुध', 'गुरु', 'शुक्र', 'शनि'],
-		weekHeader: 'हफ्ता',
-		dateFormat: 'dd/mm/yy',
-		firstDay: 1,
-		isRTL: false,
-		showMonthAfterYear: false,
-		yearSuffix: ''};
-	$.datepicker.setDefaults($.datepicker.regional['hi']);
-});
-
-/* Croatian i18n for the jQuery UI date picker plugin. */
-/* Written by Vjekoslav Nesek. */
-jQuery(function($){
-	$.datepicker.regional['hr'] = {
-		closeText: 'Zatvori',
-		prevText: '&#x3c;',
-		nextText: '&#x3e;',
-		currentText: 'Danas',
-		monthNames: ['Siječanj','Veljača','Ožujak','Travanj','Svibanj','Lipanj',
-		'Srpanj','Kolovoz','Rujan','Listopad','Studeni','Prosinac'],
-		monthNamesShort: ['Sij','Velj','Ožu','Tra','Svi','Lip',
-		'Srp','Kol','Ruj','Lis','Stu','Pro'],
-		dayNames: ['Nedjelja','Ponedjeljak','Utorak','Srijeda','Četvrtak','Petak','Subota'],
-		dayNamesShort: ['Ned','Pon','Uto','Sri','Čet','Pet','Sub'],
-		dayNamesMin: ['Ne','Po','Ut','Sr','Če','Pe','Su'],
-		weekHeader: 'Tje',
-		dateFormat: 'dd.mm.yy.',
-		firstDay: 1,
-		isRTL: false,
-		showMonthAfterYear: false,
-		yearSuffix: ''};
-	$.datepicker.setDefaults($.datepicker.regional['hr']);
-});
-/* Hungarian initialisation for the jQuery UI date picker plugin. */
-/* Written by Istvan Karaszi (jquery@spam.raszi.hu). */
-jQuery(function($){
-	$.datepicker.regional['hu'] = {
-		closeText: 'bezár',
-		prevText: 'vissza',
-		nextText: 'előre',
-		currentText: 'ma',
-		monthNames: ['Január', 'Február', 'Március', 'Április', 'Május', 'Június',
-		'Július', 'Augusztus', 'Szeptember', 'Október', 'November', 'December'],
-		monthNamesShort: ['Jan', 'Feb', 'Már', 'Ápr', 'Máj', 'Jún',
-		'Júl', 'Aug', 'Szep', 'Okt', 'Nov', 'Dec'],
-		dayNames: ['Vasárnap', 'Hétfő', 'Kedd', 'Szerda', 'Csütörtök', 'Péntek', 'Szombat'],
-		dayNamesShort: ['Vas', 'Hét', 'Ked', 'Sze', 'Csü', 'Pén', 'Szo'],
-		dayNamesMin: ['V', 'H', 'K', 'Sze', 'Cs', 'P', 'Szo'],
-		weekHeader: 'Hét',
-		dateFormat: 'yy.mm.dd.',
-		firstDay: 1,
-		isRTL: false,
-		showMonthAfterYear: true,
-		yearSuffix: ''};
-	$.datepicker.setDefaults($.datepicker.regional['hu']);
-});
-
-/* Armenian(UTF-8) initialisation for the jQuery UI date picker plugin. */
-/* Written by Levon Zakaryan (levon.zakaryan@gmail.com)*/
-jQuery(function($){
-	$.datepicker.regional['hy'] = {
-		closeText: 'Փակել',
-		prevText: '&#x3c;Նախ.',
-		nextText: 'Հաջ.&#x3e;',
-		currentText: 'Այսօր',
-		monthNames: ['Հունվար','Փետրվար','Մարտ','Ապրիլ','Մայիս','Հունիս',
-		'Հուլիս','Օգոստոս','Սեպտեմբեր','Հոկտեմբեր','Նոյեմբեր','Դեկտեմբեր'],
-		monthNamesShort: ['Հունվ','Փետր','Մարտ','Ապր','Մայիս','Հունիս',
-		'Հուլ','Օգս','Սեպ','Հոկ','Նոյ','Դեկ'],
-		dayNames: ['կիրակի','եկուշաբթի','երեքշաբթի','չորեքշաբթի','հինգշաբթի','ուրբաթ','շաբաթ'],
-		dayNamesShort: ['կիր','երկ','երք','չրք','հնգ','ուրբ','շբթ'],
-		dayNamesMin: ['կիր','երկ','երք','չրք','հնգ','ուրբ','շբթ'],
-		weekHeader: 'ՇԲՏ',
-		dateFormat: 'dd.mm.yy',
-		firstDay: 1,
-		isRTL: false,
-		showMonthAfterYear: false,
-		yearSuffix: ''};
-	$.datepicker.setDefaults($.datepicker.regional['hy']);
-});
-/* Indonesian initialisation for the jQuery UI date picker plugin. */
-/* Written by Deden Fathurahman (dedenf@gmail.com). */
-jQuery(function($){
-	$.datepicker.regional['id'] = {
-		closeText: 'Tutup',
-		prevText: '&#x3c;mundur',
-		nextText: 'maju&#x3e;',
-		currentText: 'hari ini',
-		monthNames: ['Januari','Februari','Maret','April','Mei','Juni',
-		'Juli','Agustus','September','Oktober','Nopember','Desember'],
-		monthNamesShort: ['Jan','Feb','Mar','Apr','Mei','Jun',
-		'Jul','Agus','Sep','Okt','Nop','Des'],
-		dayNames: ['Minggu','Senin','Selasa','Rabu','Kamis','Jumat','Sabtu'],
-		dayNamesShort: ['Min','Sen','Sel','Rab','kam','Jum','Sab'],
-		dayNamesMin: ['Mg','Sn','Sl','Rb','Km','jm','Sb'],
-		weekHeader: 'Mg',
-		dateFormat: 'dd/mm/yy',
-		firstDay: 0,
-		isRTL: false,
-		showMonthAfterYear: false,
-		yearSuffix: ''};
-	$.datepicker.setDefaults($.datepicker.regional['id']);
-});
-/* Icelandic initialisation for the jQuery UI date picker plugin. */
-/* Written by Haukur H. Thorsson (haukur@eskill.is). */
-jQuery(function($){
-	$.datepicker.regional['is'] = {
-		closeText: 'Loka',
-		prevText: '&#x3c; Fyrri',
-		nextText: 'N&aelig;sti &#x3e;',
-		currentText: '&Iacute; dag',
-		monthNames: ['Jan&uacute;ar','Febr&uacute;ar','Mars','Apr&iacute;l','Ma&iacute','J&uacute;n&iacute;',
-		'J&uacute;l&iacute;','&Aacute;g&uacute;st','September','Okt&oacute;ber','N&oacute;vember','Desember'],
-		monthNamesShort: ['Jan','Feb','Mar','Apr','Ma&iacute;','J&uacute;n',
-		'J&uacute;l','&Aacute;g&uacute;','Sep','Okt','N&oacute;v','Des'],
-		dayNames: ['Sunnudagur','M&aacute;nudagur','&THORN;ri&eth;judagur','Mi&eth;vikudagur','Fimmtudagur','F&ouml;studagur','Laugardagur'],
-		dayNamesShort: ['Sun','M&aacute;n','&THORN;ri','Mi&eth;','Fim','F&ouml;s','Lau'],
-		dayNamesMin: ['Su','M&aacute;','&THORN;r','Mi','Fi','F&ouml;','La'],
-		weekHeader: 'Vika',
-		dateFormat: 'dd/mm/yy',
-		firstDay: 0,
-		isRTL: false,
-		showMonthAfterYear: false,
-		yearSuffix: ''};
-	$.datepicker.setDefaults($.datepicker.regional['is']);
-});
-/* Italian initialisation for the jQuery UI date picker plugin. */
-/* Written by Antonello Pasella (antonello.pasella@gmail.com). */
-jQuery(function($){
-	$.datepicker.regional['it'] = {
-		closeText: 'Chiudi',
-		prevText: '&#x3c;Prec',
-		nextText: 'Succ&#x3e;',
-		currentText: 'Oggi',
-		monthNames: ['Gennaio','Febbraio','Marzo','Aprile','Maggio','Giugno',
-			'Luglio','Agosto','Settembre','Ottobre','Novembre','Dicembre'],
-		monthNamesShort: ['Gen','Feb','Mar','Apr','Mag','Giu',
-			'Lug','Ago','Set','Ott','Nov','Dic'],
-		dayNames: ['Domenica','Luned&#236','Marted&#236','Mercoled&#236','Gioved&#236','Venerd&#236','Sabato'],
-		dayNamesShort: ['Dom','Lun','Mar','Mer','Gio','Ven','Sab'],
-		dayNamesMin: ['Do','Lu','Ma','Me','Gi','Ve','Sa'],
-		weekHeader: 'Sm',
-		dateFormat: 'dd/mm/yy',
-		firstDay: 1,
-		isRTL: false,
-		showMonthAfterYear: false,
-		yearSuffix: ''};
-	$.datepicker.setDefaults($.datepicker.regional['it']);
-});
-
-/* Japanese initialisation for the jQuery UI date picker plugin. */
-/* Written by Kentaro SATO (kentaro@ranvis.com). */
-jQuery(function($){
-	$.datepicker.regional['ja'] = {
-		closeText: '閉じる',
-		prevText: '&#x3c;前',
-		nextText: '次&#x3e;',
-		currentText: '今日',
-		monthNames: ['1月','2月','3月','4月','5月','6月',
-		'7月','8月','9月','10月','11月','12月'],
-		monthNamesShort: ['1月','2月','3月','4月','5月','6月',
-		'7月','8月','9月','10月','11月','12月'],
-		dayNames: ['日曜日','月曜日','火曜日','水曜日','木曜日','金曜日','土曜日'],
-		dayNamesShort: ['日','月','火','水','木','金','土'],
-		dayNamesMin: ['日','月','火','水','木','金','土'],
-		weekHeader: '週',
-		dateFormat: 'yy/mm/dd',
-		firstDay: 0,
-		isRTL: false,
-		showMonthAfterYear: true,
-		yearSuffix: '年'};
-	$.datepicker.setDefaults($.datepicker.regional['ja']);
-});
-/* Georgian (UTF-8) initialisation for the jQuery UI date picker plugin. */
-/* Written by Lado Lomidze (lado.lomidze@gmail.com). */
-jQuery(function($){
-	$.datepicker.regional['ka'] = {
-		closeText: 'დახურვა',
-		prevText: '&#x3c; წინა',
-		nextText: 'შემდეგი &#x3e;',
-		currentText: 'დღეს',
-		monthNames: ['იანვარი','თებერვალი','მარტი','აპრილი','მაისი','ივნისი', 'ივლისი','აგვისტო','სექტემბერი','ოქტომბერი','ნოემბერი','დეკემბერი'],
-		monthNamesShort: ['იან','თებ','მარ','აპრ','მაი','ივნ', 'ივლ','აგვ','სექ','ოქტ','ნოე','დეკ'],
-		dayNames: ['კვირა','ორშაბათი','სამშაბათი','ოთხშაბათი','ხუთშაბათი','პარასკევი','შაბათი'],
-		dayNamesShort: ['კვ','ორშ','სამ','ოთხ','ხუთ','პარ','შაბ'],
-		dayNamesMin: ['კვ','ორშ','სამ','ოთხ','ხუთ','პარ','შაბ'],
-		weekHeader: 'კვირა',
-		dateFormat: 'dd-mm-yy',
-		firstDay: 1,
-		isRTL: false,
-		showMonthAfterYear: false,
-		yearSuffix: ''};
-	$.datepicker.setDefaults($.datepicker.regional['ka']);
-});
-
-/* Kazakh (UTF-8) initialisation for the jQuery UI date picker plugin. */
-/* Written by Dmitriy Karasyov (dmitriy.karasyov@gmail.com). */
-jQuery(function($){
-	$.datepicker.regional['kk'] = {
-		closeText: 'Жабу',
-		prevText: '&#x3c;Алдыңғы',
-		nextText: 'Келесі&#x3e;',
-		currentText: 'Бүгін',
-		monthNames: ['Қаңтар','Ақпан','Наурыз','Сәуір','Мамыр','Маусым',
-		'Шілде','Тамыз','Қыркүйек','Қазан','Қараша','Желтоқсан'],
-		monthNamesShort: ['Қаң','Ақп','Нау','Сәу','Мам','Мау',
-		'Шіл','Там','Қыр','Қаз','Қар','Жел'],
-		dayNames: ['Жексенбі','Дүйсенбі','Сейсенбі','Сәрсенбі','Бейсенбі','Жұма','Сенбі'],
-		dayNamesShort: ['жкс','дсн','ссн','срс','бсн','жма','снб'],
-		dayNamesMin: ['Жк','Дс','Сс','Ср','Бс','Жм','Сн'],
-		weekHeader: 'Не',
-		dateFormat: 'dd.mm.yy',
-		firstDay: 1,
-		isRTL: false,
-		showMonthAfterYear: false,
-		yearSuffix: ''};
-	$.datepicker.setDefaults($.datepicker.regional['kk']);
-});
-
-/* Khmer initialisation for the jQuery calendar extension. */
-/* Written by Chandara Om (chandara.teacher@gmail.com). */
-jQuery(function($){
-	$.datepicker.regional['km'] = {
-		closeText: 'ធ្វើ​រួច',
-		prevText: 'មុន',
-		nextText: 'បន្ទាប់',
-		currentText: 'ថ្ងៃ​នេះ',
-		monthNames: ['មករា','កុម្ភៈ','មីនា','មេសា','ឧសភា','មិថុនា',
-		'កក្កដា','សីហា','កញ្ញា','តុលា','វិច្ឆិកា','ធ្នូ'],
-		monthNamesShort: ['មករា','កុម្ភៈ','មីនា','មេសា','ឧសភា','មិថុនា',
-		'កក្កដា','សីហា','កញ្ញា','តុលា','វិច្ឆិកា','ធ្នូ'],
-		dayNames: ['អាទិត្យ', 'ចន្ទ', 'អង្គារ', 'ពុធ', 'ព្រហស្បតិ៍', 'សុក្រ', 'សៅរ៍'],
-		dayNamesShort: ['អា', 'ច', 'អ', 'ពុ', 'ព្រហ', 'សុ', 'សៅ'],
-		dayNamesMin: ['អា', 'ច', 'អ', 'ពុ', 'ព្រហ', 'សុ', 'សៅ'],
-		weekHeader: 'សប្ដាហ៍',
-		dateFormat: 'dd-mm-yy',
-		firstDay: 1,
-		isRTL: false,
-		showMonthAfterYear: false,
-		yearSuffix: ''};
-	$.datepicker.setDefaults($.datepicker.regional['km']);
-});
-
-/* Korean initialisation for the jQuery calendar extension. */
-/* Written by DaeKwon Kang (ncrash.dk@gmail.com), Edited by Genie. */
-jQuery(function($){
-	$.datepicker.regional['ko'] = {
-		closeText: '닫기',
-		prevText: '이전달',
-		nextText: '다음달',
-		currentText: '오늘',
-		monthNames: ['1월','2월','3월','4월','5월','6월',
-		'7월','8월','9월','10월','11월','12월'],
-		monthNamesShort: ['1월','2월','3월','4월','5월','6월',
-		'7월','8월','9월','10월','11월','12월'],
-		dayNames: ['일요일','월요일','화요일','수요일','목요일','금요일','토요일'],
-		dayNamesShort: ['일','월','화','수','목','금','토'],
-		dayNamesMin: ['일','월','화','수','목','금','토'],
-		weekHeader: 'Wk',
-		dateFormat: 'yy-mm-dd',
-		firstDay: 0,
-		isRTL: false,
-		showMonthAfterYear: true,
-		yearSuffix: '년'};
-	$.datepicker.setDefaults($.datepicker.regional['ko']);
-});
-/* Luxembourgish initialisation for the jQuery UI date picker plugin. */
-/* Written by Michel Weimerskirch <michel@weimerskirch.net> */
-jQuery(function($){
-	$.datepicker.regional['lb'] = {
-		closeText: 'Fäerdeg',
-		prevText: 'Zréck',
-		nextText: 'Weider',
-		currentText: 'Haut',
-		monthNames: ['Januar','Februar','Mäerz','Abrëll','Mee','Juni',
-		'Juli','August','September','Oktober','November','Dezember'],
-		monthNamesShort: ['Jan', 'Feb', 'Mäe', 'Abr', 'Mee', 'Jun',
-		'Jul', 'Aug', 'Sep', 'Okt', 'Nov', 'Dez'],
-		dayNames: ['Sonndeg', 'Méindeg', 'Dënschdeg', 'Mëttwoch', 'Donneschdeg', 'Freideg', 'Samschdeg'],
-		dayNamesShort: ['Son', 'Méi', 'Dën', 'Mët', 'Don', 'Fre', 'Sam'],
-		dayNamesMin: ['So','Mé','Dë','Më','Do','Fr','Sa'],
-		weekHeader: 'W',
-		dateFormat: 'dd.mm.yy',
-		firstDay: 1,
-		isRTL: false,
-		showMonthAfterYear: false,
-		yearSuffix: ''};
-	$.datepicker.setDefaults($.datepicker.regional['lb']);
-});
-
-/* Lithuanian (UTF-8) initialisation for the jQuery UI date picker plugin. */
-/* @author Arturas Paleicikas <arturas@avalon.lt> */
-jQuery(function($){
-	$.datepicker.regional['lt'] = {
-		closeText: 'Uždaryti',
-		prevText: '&#x3c;Atgal',
-		nextText: 'Pirmyn&#x3e;',
-		currentText: 'Šiandien',
-		monthNames: ['Sausis','Vasaris','Kovas','Balandis','Gegužė','Birželis',
-		'Liepa','Rugpjūtis','Rugsėjis','Spalis','Lapkritis','Gruodis'],
-		monthNamesShort: ['Sau','Vas','Kov','Bal','Geg','Bir',
-		'Lie','Rugp','Rugs','Spa','Lap','Gru'],
-		dayNames: ['sekmadienis','pirmadienis','antradienis','trečiadienis','ketvirtadienis','penktadienis','šeštadienis'],
-		dayNamesShort: ['sek','pir','ant','tre','ket','pen','šeš'],
-		dayNamesMin: ['Se','Pr','An','Tr','Ke','Pe','Še'],
-		weekHeader: 'Wk',
-		dateFormat: 'yy-mm-dd',
-		firstDay: 1,
-		isRTL: false,
-		showMonthAfterYear: false,
-		yearSuffix: ''};
-	$.datepicker.setDefaults($.datepicker.regional['lt']);
-});
-/* Latvian (UTF-8) initialisation for the jQuery UI date picker plugin. */
-/* @author Arturas Paleicikas <arturas.paleicikas@metasite.net> */
-jQuery(function($){
-	$.datepicker.regional['lv'] = {
-		closeText: 'Aizvērt',
-		prevText: 'Iepr',
-		nextText: 'Nāka',
-		currentText: 'Šodien',
-		monthNames: ['Janvāris','Februāris','Marts','Aprīlis','Maijs','Jūnijs',
-		'Jūlijs','Augusts','Septembris','Oktobris','Novembris','Decembris'],
-		monthNamesShort: ['Jan','Feb','Mar','Apr','Mai','Jūn',
-		'Jūl','Aug','Sep','Okt','Nov','Dec'],
-		dayNames: ['svētdiena','pirmdiena','otrdiena','trešdiena','ceturtdiena','piektdiena','sestdiena'],
-		dayNamesShort: ['svt','prm','otr','tre','ctr','pkt','sst'],
-		dayNamesMin: ['Sv','Pr','Ot','Tr','Ct','Pk','Ss'],
-		weekHeader: 'Nav',
-		dateFormat: 'dd-mm-yy',
-		firstDay: 1,
-		isRTL: false,
-		showMonthAfterYear: false,
-		yearSuffix: ''};
-	$.datepicker.setDefaults($.datepicker.regional['lv']);
-});
-/* Macedonian i18n for the jQuery UI date picker plugin. */
-/* Written by Stojce Slavkovski. */
-jQuery(function($){
-	$.datepicker.regional['mk'] = {
-		closeText: 'Затвори',
-		prevText: '&#x3C;',
-		nextText: '&#x3E;',
-		currentText: 'Денес',
-		monthNames: ['Јануари','Февруари','Март','Април','Мај','Јуни',
-		'Јули','Август','Септември','Октомври','Ноември','Декември'],
-		monthNamesShort: ['Јан','Фев','Мар','Апр','Мај','Јун',
-		'Јул','Авг','Сеп','Окт','Ное','Дек'],
-		dayNames: ['Недела','Понеделник','Вторник','Среда','Четврток','Петок','Сабота'],
-		dayNamesShort: ['Нед','Пон','Вто','Сре','Чет','Пет','Саб'],
-		dayNamesMin: ['Не','По','Вт','Ср','Че','Пе','Са'],
-		weekHeader: 'Сед',
-		dateFormat: 'dd.mm.yy',
-		firstDay: 1,
-		isRTL: false,
-		showMonthAfterYear: false,
-		yearSuffix: ''};
-	$.datepicker.setDefaults($.datepicker.regional['mk']);
-});
-
-/* Malayalam (UTF-8) initialisation for the jQuery UI date picker plugin. */
-/* Written by Saji Nediyanchath (saji89@gmail.com). */
-jQuery(function($){
-	$.datepicker.regional['ml'] = {
-		closeText: 'ശരി',
-		prevText: 'മുന്നത്തെ',  
-		nextText: 'അടുത്തത് ',
-		currentText: 'ഇന്ന്',
-		monthNames: ['ജനുവരി','ഫെബ്രുവരി','മാര്‍ച്ച്','ഏപ്രില്‍','മേയ്','ജൂണ്‍',
-		'ജൂലൈ','ആഗസ്റ്റ്','സെപ്റ്റംബര്‍','ഒക്ടോബര്‍','നവംബര്‍','ഡിസംബര്‍'],
-		monthNamesShort: ['ജനു', 'ഫെബ്', 'മാര്‍', 'ഏപ്രി', 'മേയ്', 'ജൂണ്‍',
-		'ജൂലാ', 'ആഗ', 'സെപ്', 'ഒക്ടോ', 'നവം', 'ഡിസ'],
-		dayNames: ['ഞായര്‍', 'തിങ്കള്‍', 'ചൊവ്വ', 'ബുധന്‍', 'വ്യാഴം', 'വെള്ളി', 'ശനി'],
-		dayNamesShort: ['ഞായ', 'തിങ്ക', 'ചൊവ്വ', 'ബുധ', 'വ്യാഴം', 'വെള്ളി', 'ശനി'],
-		dayNamesMin: ['ഞാ','തി','ചൊ','ബു','വ്യാ','വെ','ശ'],
-		weekHeader: 'ആ',
-		dateFormat: 'dd/mm/yy',
-		firstDay: 1,
-		isRTL: false,
-		showMonthAfterYear: false,
-		yearSuffix: ''};
-	$.datepicker.setDefaults($.datepicker.regional['ml']);
-});
-
-/* Malaysian initialisation for the jQuery UI date picker plugin. */
-/* Written by Mohd Nawawi Mohamad Jamili (nawawi@ronggeng.net). */
-jQuery(function($){
-	$.datepicker.regional['ms'] = {
-		closeText: 'Tutup',
-		prevText: '&#x3c;Sebelum',
-		nextText: 'Selepas&#x3e;',
-		currentText: 'hari ini',
-		monthNames: ['Januari','Februari','Mac','April','Mei','Jun',
-		'Julai','Ogos','September','Oktober','November','Disember'],
-		monthNamesShort: ['Jan','Feb','Mac','Apr','Mei','Jun',
-		'Jul','Ogo','Sep','Okt','Nov','Dis'],
-		dayNames: ['Ahad','Isnin','Selasa','Rabu','Khamis','Jumaat','Sabtu'],
-		dayNamesShort: ['Aha','Isn','Sel','Rab','kha','Jum','Sab'],
-		dayNamesMin: ['Ah','Is','Se','Ra','Kh','Ju','Sa'],
-		weekHeader: 'Mg',
-		dateFormat: 'dd/mm/yy',
-		firstDay: 0,
-		isRTL: false,
-		showMonthAfterYear: false,
-		yearSuffix: ''};
-	$.datepicker.setDefaults($.datepicker.regional['ms']);
-});
-/* Dutch (Belgium) initialisation for the jQuery UI date picker plugin. */
-/* David De Sloovere @DavidDeSloovere */
-jQuery(function($){
-	$.datepicker.regional['nl-BE'] = {
-		closeText: 'Sluiten',
-		prevText: '←',
-		nextText: '→',
-		currentText: 'Vandaag',
-		monthNames: ['januari', 'februari', 'maart', 'april', 'mei', 'juni',
-		'juli', 'augustus', 'september', 'oktober', 'november', 'december'],
-		monthNamesShort: ['jan', 'feb', 'mrt', 'apr', 'mei', 'jun',
-		'jul', 'aug', 'sep', 'okt', 'nov', 'dec'],
-		dayNames: ['zondag', 'maandag', 'dinsdag', 'woensdag', 'donderdag', 'vrijdag', 'zaterdag'],
-		dayNamesShort: ['zon', 'maa', 'din', 'woe', 'don', 'vri', 'zat'],
-		dayNamesMin: ['zo', 'ma', 'di', 'wo', 'do', 'vr', 'za'],
-		weekHeader: 'Wk',
-		dateFormat: 'dd/mm/yy',
-		firstDay: 1,
-		isRTL: false,
-		showMonthAfterYear: false,
-		yearSuffix: ''};
-	$.datepicker.setDefaults($.datepicker.regional['nl-BE']);
-});
-
-/* Dutch (UTF-8) initialisation for the jQuery UI date picker plugin. */
-/* Written by Mathias Bynens <http://mathiasbynens.be/> */
-jQuery(function($){
-	$.datepicker.regional.nl = {
-		closeText: 'Sluiten',
-		prevText: '←',
-		nextText: '→',
-		currentText: 'Vandaag',
-		monthNames: ['januari', 'februari', 'maart', 'april', 'mei', 'juni',
-		'juli', 'augustus', 'september', 'oktober', 'november', 'december'],
-		monthNamesShort: ['jan', 'feb', 'mrt', 'apr', 'mei', 'jun',
-		'jul', 'aug', 'sep', 'okt', 'nov', 'dec'],
-		dayNames: ['zondag', 'maandag', 'dinsdag', 'woensdag', 'donderdag', 'vrijdag', 'zaterdag'],
-		dayNamesShort: ['zon', 'maa', 'din', 'woe', 'don', 'vri', 'zat'],
-		dayNamesMin: ['zo', 'ma', 'di', 'wo', 'do', 'vr', 'za'],
-		weekHeader: 'Wk',
-		dateFormat: 'dd-mm-yy',
-		firstDay: 1,
-		isRTL: false,
-		showMonthAfterYear: false,
-		yearSuffix: ''};
-	$.datepicker.setDefaults($.datepicker.regional.nl);
-});
-/* Norwegian initialisation for the jQuery UI date picker plugin. */
-/* Written by Naimdjon Takhirov (naimdjon@gmail.com). */
-
-jQuery(function($){
-  $.datepicker.regional['no'] = {
-    closeText: 'Lukk',
-    prevText: '&laquo;Forrige',
-    nextText: 'Neste&raquo;',
-    currentText: 'I dag',
-    monthNames: ['januar','februar','mars','april','mai','juni','juli','august','september','oktober','november','desember'],
-    monthNamesShort: ['jan','feb','mar','apr','mai','jun','jul','aug','sep','okt','nov','des'],
-    dayNamesShort: ['søn','man','tir','ons','tor','fre','lør'],
-    dayNames: ['søndag','mandag','tirsdag','onsdag','torsdag','fredag','lørdag'],
-    dayNamesMin: ['sø','ma','ti','on','to','fr','lø'],
-    weekHeader: 'Uke',
-    dateFormat: 'dd.mm.yy',
-    firstDay: 1,
-    isRTL: false,
-    showMonthAfterYear: false,
-    yearSuffix: ''
-  };
-  $.datepicker.setDefaults($.datepicker.regional['no']);
-});
-
-/* Polish initialisation for the jQuery UI date picker plugin. */
-/* Written by Jacek Wysocki (jacek.wysocki@gmail.com). */
-jQuery(function($){
-	$.datepicker.regional['pl'] = {
-		closeText: 'Zamknij',
-		prevText: '&#x3c;Poprzedni',
-		nextText: 'Następny&#x3e;',
-		currentText: 'Dziś',
-		monthNames: ['Styczeń','Luty','Marzec','Kwiecień','Maj','Czerwiec',
-		'Lipiec','Sierpień','Wrzesień','Październik','Listopad','Grudzień'],
-		monthNamesShort: ['Sty','Lu','Mar','Kw','Maj','Cze',
-		'Lip','Sie','Wrz','Pa','Lis','Gru'],
-		dayNames: ['Niedziela','Poniedziałek','Wtorek','Środa','Czwartek','Piątek','Sobota'],
-		dayNamesShort: ['Nie','Pn','Wt','Śr','Czw','Pt','So'],
-		dayNamesMin: ['N','Pn','Wt','Śr','Cz','Pt','So'],
-		weekHeader: 'Tydz',
-		dateFormat: 'dd.mm.yy',
-		firstDay: 1,
-		isRTL: false,
-		showMonthAfterYear: false,
-		yearSuffix: ''};
-	$.datepicker.setDefaults($.datepicker.regional['pl']);
-});
-
-/* Brazilian initialisation for the jQuery UI date picker plugin. */
-/* Written by Leonildo Costa Silva (leocsilva@gmail.com). */
-jQuery(function($){
-	$.datepicker.regional['pt-BR'] = {
-		closeText: 'Fechar',
-		prevText: '&#x3c;Anterior',
-		nextText: 'Pr&oacute;ximo&#x3e;',
-		currentText: 'Hoje',
-		monthNames: ['Janeiro','Fevereiro','Mar&ccedil;o','Abril','Maio','Junho',
-		'Julho','Agosto','Setembro','Outubro','Novembro','Dezembro'],
-		monthNamesShort: ['Jan','Fev','Mar','Abr','Mai','Jun',
-		'Jul','Ago','Set','Out','Nov','Dez'],
-		dayNames: ['Domingo','Segunda-feira','Ter&ccedil;a-feira','Quarta-feira','Quinta-feira','Sexta-feira','S&aacute;bado'],
-		dayNamesShort: ['Dom','Seg','Ter','Qua','Qui','Sex','S&aacute;b'],
-		dayNamesMin: ['Dom','Seg','Ter','Qua','Qui','Sex','S&aacute;b'],
-		weekHeader: 'Sm',
-		dateFormat: 'dd/mm/yy',
-		firstDay: 0,
-		isRTL: false,
-		showMonthAfterYear: false,
-		yearSuffix: ''};
-	$.datepicker.setDefaults($.datepicker.regional['pt-BR']);
-});
-/* Portuguese initialisation for the jQuery UI date picker plugin. */
-jQuery(function($){
-	$.datepicker.regional['pt'] = {
-		closeText: 'Fechar',
-		prevText: '&#x3c;Anterior',
-		nextText: 'Seguinte',
-		currentText: 'Hoje',
-		monthNames: ['Janeiro','Fevereiro','Mar&ccedil;o','Abril','Maio','Junho',
-		'Julho','Agosto','Setembro','Outubro','Novembro','Dezembro'],
-		monthNamesShort: ['Jan','Fev','Mar','Abr','Mai','Jun',
-		'Jul','Ago','Set','Out','Nov','Dez'],
-		dayNames: ['Domingo','Segunda-feira','Ter&ccedil;a-feira','Quarta-feira','Quinta-feira','Sexta-feira','S&aacute;bado'],
-		dayNamesShort: ['Dom','Seg','Ter','Qua','Qui','Sex','S&aacute;b'],
-		dayNamesMin: ['Dom','Seg','Ter','Qua','Qui','Sex','S&aacute;b'],
-		weekHeader: 'Sem',
-		dateFormat: 'dd/mm/yy',
-		firstDay: 0,
-		isRTL: false,
-		showMonthAfterYear: false,
-		yearSuffix: ''};
-	$.datepicker.setDefaults($.datepicker.regional['pt']);
-});
-/* Romansh initialisation for the jQuery UI date picker plugin. */
-/* Written by Yvonne Gienal (yvonne.gienal@educa.ch). */
-jQuery(function($){
-	$.datepicker.regional['rm'] = {
-		closeText: 'Serrar',
-		prevText: '&#x3c;Suandant',
-		nextText: 'Precedent&#x3e;',
-		currentText: 'Actual',
-		monthNames: ['Schaner','Favrer','Mars','Avrigl','Matg','Zercladur', 'Fanadur','Avust','Settember','October','November','December'],
-		monthNamesShort: ['Scha','Fev','Mar','Avr','Matg','Zer', 'Fan','Avu','Sett','Oct','Nov','Dec'],
-		dayNames: ['Dumengia','Glindesdi','Mardi','Mesemna','Gievgia','Venderdi','Sonda'],
-		dayNamesShort: ['Dum','Gli','Mar','Mes','Gie','Ven','Som'],
-		dayNamesMin: ['Du','Gl','Ma','Me','Gi','Ve','So'],
-		weekHeader: 'emna',
-		dateFormat: 'dd/mm/yy',
-		firstDay: 1,
-		isRTL: false,
-		showMonthAfterYear: false,
-		yearSuffix: ''};
-	$.datepicker.setDefaults($.datepicker.regional['rm']);
-});
-
-/* Romanian initialisation for the jQuery UI date picker plugin.
- *
- * Written by Edmond L. (ll_edmond@walla.com)
- * and Ionut G. Stan (ionut.g.stan@gmail.com)
- */
-jQuery(function($){
-	$.datepicker.regional['ro'] = {
-		closeText: 'Închide',
-		prevText: '&laquo; Luna precedentă',
-		nextText: 'Luna următoare &raquo;',
-		currentText: 'Azi',
-		monthNames: ['Ianuarie','Februarie','Martie','Aprilie','Mai','Iunie',
-		'Iulie','August','Septembrie','Octombrie','Noiembrie','Decembrie'],
-		monthNamesShort: ['Ian', 'Feb', 'Mar', 'Apr', 'Mai', 'Iun',
-		'Iul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'],
-		dayNames: ['Duminică', 'Luni', 'Marţi', 'Miercuri', 'Joi', 'Vineri', 'Sâmbătă'],
-		dayNamesShort: ['Dum', 'Lun', 'Mar', 'Mie', 'Joi', 'Vin', 'Sâm'],
-		dayNamesMin: ['Du','Lu','Ma','Mi','Jo','Vi','Sâ'],
-		weekHeader: 'Săpt',
-		dateFormat: 'dd.mm.yy',
-		firstDay: 1,
-		isRTL: false,
-		showMonthAfterYear: false,
-		yearSuffix: ''};
-	$.datepicker.setDefaults($.datepicker.regional['ro']);
-});
-
-/* Russian (UTF-8) initialisation for the jQuery UI date picker plugin. */
-/* Written by Andrew Stromnov (stromnov@gmail.com). */
-jQuery(function($){
-	$.datepicker.regional['ru'] = {
-		closeText: 'Закрыть',
-		prevText: '&#x3c;Пред',
-		nextText: 'След&#x3e;',
-		currentText: 'Сегодня',
-		monthNames: ['Январь','Февраль','Март','Апрель','Май','Июнь',
-		'Июль','Август','Сентябрь','Октябрь','Ноябрь','Декабрь'],
-		monthNamesShort: ['Янв','Фев','Мар','Апр','Май','Июн',
-		'Июл','Авг','Сен','Окт','Ноя','Дек'],
-		dayNames: ['воскресенье','понедельник','вторник','среда','четверг','пятница','суббота'],
-		dayNamesShort: ['вск','пнд','втр','срд','чтв','птн','сбт'],
-		dayNamesMin: ['Вс','Пн','Вт','Ср','Чт','Пт','Сб'],
-		weekHeader: 'Нед',
-		dateFormat: 'dd.mm.yy',
-		firstDay: 1,
-		isRTL: false,
-		showMonthAfterYear: false,
-		yearSuffix: ''};
-	$.datepicker.setDefaults($.datepicker.regional['ru']);
-});
-/* Slovak initialisation for the jQuery UI date picker plugin. */
-/* Written by Vojtech Rinik (vojto@hmm.sk). */
-jQuery(function($){
-	$.datepicker.regional['sk'] = {
-		closeText: 'Zavrieť',
-		prevText: '&#x3c;Predchádzajúci',
-		nextText: 'Nasledujúci&#x3e;',
-		currentText: 'Dnes',
-		monthNames: ['Január','Február','Marec','Apríl','Máj','Jún',
-		'Júl','August','September','Október','November','December'],
-		monthNamesShort: ['Jan','Feb','Mar','Apr','Máj','Jún',
-		'Júl','Aug','Sep','Okt','Nov','Dec'],
-		dayNames: ['Nedeľa','Pondelok','Utorok','Streda','Štvrtok','Piatok','Sobota'],
-		dayNamesShort: ['Ned','Pon','Uto','Str','Štv','Pia','Sob'],
-		dayNamesMin: ['Ne','Po','Ut','St','Št','Pia','So'],
-		weekHeader: 'Ty',
-		dateFormat: 'dd.mm.yy',
-		firstDay: 1,
-		isRTL: false,
-		showMonthAfterYear: false,
-		yearSuffix: ''};
-	$.datepicker.setDefaults($.datepicker.regional['sk']);
-});
-
-/* Slovenian initialisation for the jQuery UI date picker plugin. */
-/* Written by Jaka Jancar (jaka@kubje.org). */
-/* c = &#x10D;, s = &#x161; z = &#x17E; C = &#x10C; S = &#x160; Z = &#x17D; */
-jQuery(function($){
-	$.datepicker.regional['sl'] = {
-		closeText: 'Zapri',
-		prevText: '&lt;Prej&#x161;nji',
-		nextText: 'Naslednji&gt;',
-		currentText: 'Trenutni',
-		monthNames: ['Januar','Februar','Marec','April','Maj','Junij',
-		'Julij','Avgust','September','Oktober','November','December'],
-		monthNamesShort: ['Jan','Feb','Mar','Apr','Maj','Jun',
-		'Jul','Avg','Sep','Okt','Nov','Dec'],
-		dayNames: ['Nedelja','Ponedeljek','Torek','Sreda','&#x10C;etrtek','Petek','Sobota'],
-		dayNamesShort: ['Ned','Pon','Tor','Sre','&#x10C;et','Pet','Sob'],
-		dayNamesMin: ['Ne','Po','To','Sr','&#x10C;e','Pe','So'],
-		weekHeader: 'Teden',
-		dateFormat: 'dd.mm.yy',
-		firstDay: 1,
-		isRTL: false,
-		showMonthAfterYear: false,
-		yearSuffix: ''};
-	$.datepicker.setDefaults($.datepicker.regional['sl']);
-});
-
-/* Albanian initialisation for the jQuery UI date picker plugin. */
-/* Written by Flakron Bytyqi (flakron@gmail.com). */
-jQuery(function($){
-	$.datepicker.regional['sq'] = {
-		closeText: 'mbylle',
-		prevText: '&#x3c;mbrapa',
-		nextText: 'Përpara&#x3e;',
-		currentText: 'sot',
-		monthNames: ['Janar','Shkurt','Mars','Prill','Maj','Qershor',
-		'Korrik','Gusht','Shtator','Tetor','Nëntor','Dhjetor'],
-		monthNamesShort: ['Jan','Shk','Mar','Pri','Maj','Qer',
-		'Kor','Gus','Sht','Tet','Nën','Dhj'],
-		dayNames: ['E Diel','E Hënë','E Martë','E Mërkurë','E Enjte','E Premte','E Shtune'],
-		dayNamesShort: ['Di','Hë','Ma','Më','En','Pr','Sh'],
-		dayNamesMin: ['Di','Hë','Ma','Më','En','Pr','Sh'],
-		weekHeader: 'Ja',
-		dateFormat: 'dd.mm.yy',
-		firstDay: 1,
-		isRTL: false,
-		showMonthAfterYear: false,
-		yearSuffix: ''};
-	$.datepicker.setDefaults($.datepicker.regional['sq']);
-});
-
-/* Serbian i18n for the jQuery UI date picker plugin. */
-/* Written by Dejan Dimić. */
-jQuery(function($){
-	$.datepicker.regional['sr-SR'] = {
-		closeText: 'Zatvori',
-		prevText: '&#x3c;',
-		nextText: '&#x3e;',
-		currentText: 'Danas',
-		monthNames: ['Januar','Februar','Mart','April','Maj','Jun',
-		'Jul','Avgust','Septembar','Oktobar','Novembar','Decembar'],
-		monthNamesShort: ['Jan','Feb','Mar','Apr','Maj','Jun',
-		'Jul','Avg','Sep','Okt','Nov','Dec'],
-		dayNames: ['Nedelja','Ponedeljak','Utorak','Sreda','Četvrtak','Petak','Subota'],
-		dayNamesShort: ['Ned','Pon','Uto','Sre','Čet','Pet','Sub'],
-		dayNamesMin: ['Ne','Po','Ut','Sr','Če','Pe','Su'],
-		weekHeader: 'Sed',
-		dateFormat: 'dd/mm/yy',
-		firstDay: 1,
-		isRTL: false,
-		showMonthAfterYear: false,
-		yearSuffix: ''};
-	$.datepicker.setDefaults($.datepicker.regional['sr-SR']);
-});
-
-/* Serbian i18n for the jQuery UI date picker plugin. */
-/* Written by Dejan Dimić. */
-jQuery(function($){
-	$.datepicker.regional['sr'] = {
-		closeText: 'Затвори',
-		prevText: '&#x3c;',
-		nextText: '&#x3e;',
-		currentText: 'Данас',
-		monthNames: ['Јануар','Фебруар','Март','Април','Мај','Јун',
-		'Јул','Август','Септембар','Октобар','Новембар','Децембар'],
-		monthNamesShort: ['Јан','Феб','Мар','Апр','Мај','Јун',
-		'Јул','Авг','Сеп','Окт','Нов','Дец'],
-		dayNames: ['Недеља','Понедељак','Уторак','Среда','Четвртак','Петак','Субота'],
-		dayNamesShort: ['Нед','Пон','Уто','Сре','Чет','Пет','Суб'],
-		dayNamesMin: ['Не','По','Ут','Ср','Че','Пе','Су'],
-		weekHeader: 'Сед',
-		dateFormat: 'dd/mm/yy',
-		firstDay: 1,
-		isRTL: false,
-		showMonthAfterYear: false,
-		yearSuffix: ''};
-	$.datepicker.setDefaults($.datepicker.regional['sr']);
-});
-
-/* Swedish initialisation for the jQuery UI date picker plugin. */
-/* Written by Anders Ekdahl ( anders@nomadiz.se). */
-jQuery(function($){
-    $.datepicker.regional['sv'] = {
-		closeText: 'Stäng',
-        prevText: '&laquo;Förra',
-		nextText: 'Nästa&raquo;',
-		currentText: 'Idag',
-        monthNames: ['Januari','Februari','Mars','April','Maj','Juni',
-        'Juli','Augusti','September','Oktober','November','December'],
-        monthNamesShort: ['Jan','Feb','Mar','Apr','Maj','Jun',
-        'Jul','Aug','Sep','Okt','Nov','Dec'],
-		dayNamesShort: ['Sön','Mån','Tis','Ons','Tor','Fre','Lör'],
-		dayNames: ['Söndag','Måndag','Tisdag','Onsdag','Torsdag','Fredag','Lördag'],
-		dayNamesMin: ['Sö','Må','Ti','On','To','Fr','Lö'],
-		weekHeader: 'Ve',
-        dateFormat: 'yy-mm-dd',
-		firstDay: 1,
-		isRTL: false,
-		showMonthAfterYear: false,
-		yearSuffix: ''};
-    $.datepicker.setDefaults($.datepicker.regional['sv']);
-});
-
-/* Tamil (UTF-8) initialisation for the jQuery UI date picker plugin. */
-/* Written by S A Sureshkumar (saskumar@live.com). */
-jQuery(function($){
-	$.datepicker.regional['ta'] = {
-		closeText: 'மூடு',
-		prevText: 'முன்னையது',
-		nextText: 'அடுத்தது',
-		currentText: 'இன்று',
-		monthNames: ['தை','மாசி','பங்குனி','சித்திரை','வைகாசி','ஆனி',
-		'ஆடி','ஆவணி','புரட்டாசி','ஐப்பசி','கார்த்திகை','மார்கழி'],
-		monthNamesShort: ['தை','மாசி','பங்','சித்','வைகா','ஆனி',
-		'ஆடி','ஆவ','புர','ஐப்','கார்','மார்'],
-		dayNames: ['ஞாயிற்றுக்கிழமை','திங்கட்கிழமை','செவ்வாய்க்கிழமை','புதன்கிழமை','வியாழக்கிழமை','வெள்ளிக்கிழமை','சனிக்கிழமை'],
-		dayNamesShort: ['ஞாயிறு','திங்கள்','செவ்வாய்','புதன்','வியாழன்','வெள்ளி','சனி'],
-		dayNamesMin: ['ஞா','தி','செ','பு','வி','வெ','ச'],
-		weekHeader: 'Не',
-		dateFormat: 'dd/mm/yy',
-		firstDay: 1,
-		isRTL: false,
-		showMonthAfterYear: false,
-		yearSuffix: ''};
-	$.datepicker.setDefaults($.datepicker.regional['ta']);
-});
-
-/* Thai initialisation for the jQuery UI date picker plugin. */
-/* Written by pipo (pipo@sixhead.com). */
-jQuery(function($){
-	$.datepicker.regional['th'] = {
-		closeText: 'ปิด',
-		prevText: '&laquo;&nbsp;ย้อน',
-		nextText: 'ถัดไป&nbsp;&raquo;',
-		currentText: 'วันนี้',
-		monthNames: ['มกราคม','กุมภาพันธ์','มีนาคม','เมษายน','พฤษภาคม','มิถุนายน',
-		'กรกฎาคม','สิงหาคม','กันยายน','ตุลาคม','พฤศจิกายน','ธันวาคม'],
-		monthNamesShort: ['ม.ค.','ก.พ.','มี.ค.','เม.ย.','พ.ค.','มิ.ย.',
-		'ก.ค.','ส.ค.','ก.ย.','ต.ค.','พ.ย.','ธ.ค.'],
-		dayNames: ['อาทิตย์','จันทร์','อังคาร','พุธ','พฤหัสบดี','ศุกร์','เสาร์'],
-		dayNamesShort: ['อา.','จ.','อ.','พ.','พฤ.','ศ.','ส.'],
-		dayNamesMin: ['อา.','จ.','อ.','พ.','พฤ.','ศ.','ส.'],
-		weekHeader: 'Wk',
-		dateFormat: 'dd/mm/yy',
-		firstDay: 0,
-		isRTL: false,
-		showMonthAfterYear: false,
-		yearSuffix: ''};
-	$.datepicker.setDefaults($.datepicker.regional['th']);
-});
-/* Tajiki (UTF-8) initialisation for the jQuery UI date picker plugin. */
-/* Written by Abdurahmon Saidov (saidovab@gmail.com). */
-jQuery(function($){
-	$.datepicker.regional['tj'] = {
-		closeText: 'Идома',
-		prevText: '&#x3c;Қафо',
-		nextText: 'Пеш&#x3e;',
-		currentText: 'Имрӯз',
-		monthNames: ['Январ','Феврал','Март','Апрел','Май','Июн',
-		'Июл','Август','Сентябр','Октябр','Ноябр','Декабр'],
-		monthNamesShort: ['Янв','Фев','Мар','Апр','Май','Июн',
-		'Июл','Авг','Сен','Окт','Ноя','Дек'],
-		dayNames: ['якшанбе','душанбе','сешанбе','чоршанбе','панҷшанбе','ҷумъа','шанбе'],
-		dayNamesShort: ['якш','душ','сеш','чор','пан','ҷум','шан'],
-		dayNamesMin: ['Як','Дш','Сш','Чш','Пш','Ҷм','Шн'],
-		weekHeader: 'Хф',
-		dateFormat: 'dd.mm.yy',
-		firstDay: 1,
-		isRTL: false,
-		showMonthAfterYear: false,
-		yearSuffix: ''};
-	$.datepicker.setDefaults($.datepicker.regional['tj']);
-});
-/* Turkish initialisation for the jQuery UI date picker plugin. */
-/* Written by Izzet Emre Erkan (kara@karalamalar.net). */
-jQuery(function($){
-	$.datepicker.regional['tr'] = {
-		closeText: 'kapat',
-		prevText: '&#x3c;geri',
-		nextText: 'ileri&#x3e',
-		currentText: 'bugün',
-		monthNames: ['Ocak','Şubat','Mart','Nisan','Mayıs','Haziran',
-		'Temmuz','Ağustos','Eylül','Ekim','Kasım','Aralık'],
-		monthNamesShort: ['Oca','Şub','Mar','Nis','May','Haz',
-		'Tem','Ağu','Eyl','Eki','Kas','Ara'],
-		dayNames: ['Pazar','Pazartesi','Salı','Çarşamba','Perşembe','Cuma','Cumartesi'],
-		dayNamesShort: ['Pz','Pt','Sa','Ça','Pe','Cu','Ct'],
-		dayNamesMin: ['Pz','Pt','Sa','Ça','Pe','Cu','Ct'],
-		weekHeader: 'Hf',
-		dateFormat: 'dd.mm.yy',
-		firstDay: 1,
-		isRTL: false,
-		showMonthAfterYear: false,
-		yearSuffix: ''};
-	$.datepicker.setDefaults($.datepicker.regional['tr']);
-});
-/* Ukrainian (UTF-8) initialisation for the jQuery UI date picker plugin. */
-/* Written by Maxim Drogobitskiy (maxdao@gmail.com). */
-/* Corrected by Igor Milla (igor.fsp.milla@gmail.com). */
-jQuery(function($){
-	$.datepicker.regional['uk'] = {
-		closeText: 'Закрити',
-		prevText: '&#x3c;',
-		nextText: '&#x3e;',
-		currentText: 'Сьогодні',
-		monthNames: ['Січень','Лютий','Березень','Квітень','Травень','Червень',
-		'Липень','Серпень','Вересень','Жовтень','Листопад','Грудень'],
-		monthNamesShort: ['Січ','Лют','Бер','Кві','Тра','Чер',
-		'Лип','Сер','Вер','Жов','Лис','Гру'],
-		dayNames: ['неділя','понеділок','вівторок','середа','четвер','п’ятниця','субота'],
-		dayNamesShort: ['нед','пнд','вів','срд','чтв','птн','сбт'],
-		dayNamesMin: ['Нд','Пн','Вт','Ср','Чт','Пт','Сб'],
-		weekHeader: 'Тиж',
-		dateFormat: 'dd/mm/yy',
-		firstDay: 1,
-		isRTL: false,
-		showMonthAfterYear: false,
-		yearSuffix: ''};
-	$.datepicker.setDefaults($.datepicker.regional['uk']);
-});
-/* Vietnamese initialisation for the jQuery UI date picker plugin. */
-/* Translated by Le Thanh Huy (lthanhhuy@cit.ctu.edu.vn). */
-jQuery(function($){
-	$.datepicker.regional['vi'] = {
-		closeText: 'Đóng',
-		prevText: '&#x3c;Trước',
-		nextText: 'Tiếp&#x3e;',
-		currentText: 'Hôm nay',
-		monthNames: ['Tháng Một', 'Tháng Hai', 'Tháng Ba', 'Tháng Tư', 'Tháng Năm', 'Tháng Sáu',
-		'Tháng Bảy', 'Tháng Tám', 'Tháng Chín', 'Tháng Mười', 'Tháng Mười Một', 'Tháng Mười Hai'],
-		monthNamesShort: ['Tháng 1', 'Tháng 2', 'Tháng 3', 'Tháng 4', 'Tháng 5', 'Tháng 6',
-		'Tháng 7', 'Tháng 8', 'Tháng 9', 'Tháng 10', 'Tháng 11', 'Tháng 12'],
-		dayNames: ['Chủ Nhật', 'Thứ Hai', 'Thứ Ba', 'Thứ Tư', 'Thứ Năm', 'Thứ Sáu', 'Thứ Bảy'],
-		dayNamesShort: ['CN', 'T2', 'T3', 'T4', 'T5', 'T6', 'T7'],
-		dayNamesMin: ['CN', 'T2', 'T3', 'T4', 'T5', 'T6', 'T7'],
-		weekHeader: 'Tu',
-		dateFormat: 'dd/mm/yy',
-		firstDay: 0,
-		isRTL: false,
-		showMonthAfterYear: false,
-		yearSuffix: ''};
-	$.datepicker.setDefaults($.datepicker.regional['vi']);
-});
-
-/* Chinese initialisation for the jQuery UI date picker plugin. */
-/* Written by Cloudream (cloudream@gmail.com). */
-jQuery(function($){
-	$.datepicker.regional['zh-CN'] = {
-		closeText: '关闭',
-		prevText: '&#x3c;上月',
-		nextText: '下月&#x3e;',
-		currentText: '今天',
-		monthNames: ['一月','二月','三月','四月','五月','六月',
-		'七月','八月','九月','十月','十一月','十二月'],
-		monthNamesShort: ['一','二','三','四','五','六',
-		'七','八','九','十','十一','十二'],
-		dayNames: ['星期日','星期一','星期二','星期三','星期四','星期五','星期六'],
-		dayNamesShort: ['周日','周一','周二','周三','周四','周五','周六'],
-		dayNamesMin: ['日','一','二','三','四','五','六'],
-		weekHeader: '周',
-		dateFormat: 'yy-mm-dd',
-		firstDay: 1,
-		isRTL: false,
-		showMonthAfterYear: true,
-		yearSuffix: '年'};
-	$.datepicker.setDefaults($.datepicker.regional['zh-CN']);
-});
-
-/* Chinese initialisation for the jQuery UI date picker plugin. */
-/* Written by SCCY (samuelcychan@gmail.com). */
-jQuery(function($){
-	$.datepicker.regional['zh-HK'] = {
-		closeText: '關閉',
-		prevText: '&#x3c;上月',
-		nextText: '下月&#x3e;',
-		currentText: '今天',
-		monthNames: ['一月','二月','三月','四月','五月','六月',
-		'七月','八月','九月','十月','十一月','十二月'],
-		monthNamesShort: ['一','二','三','四','五','六',
-		'七','八','九','十','十一','十二'],
-		dayNames: ['星期日','星期一','星期二','星期三','星期四','星期五','星期六'],
-		dayNamesShort: ['周日','周一','周二','周三','周四','周五','周六'],
-		dayNamesMin: ['日','一','二','三','四','五','六'],
-		weekHeader: '周',
-		dateFormat: 'dd-mm-yy',
-		firstDay: 0,
-		isRTL: false,
-		showMonthAfterYear: true,
-		yearSuffix: '年'};
-	$.datepicker.setDefaults($.datepicker.regional['zh-HK']);
-});
-
-/* Chinese initialisation for the jQuery UI date picker plugin. */
-/* Written by Ressol (ressol@gmail.com). */
-jQuery(function($){
-	$.datepicker.regional['zh-TW'] = {
-		closeText: '關閉',
-		prevText: '&#x3c;上月',
-		nextText: '下月&#x3e;',
-		currentText: '今天',
-		monthNames: ['一月','二月','三月','四月','五月','六月',
-		'七月','八月','九月','十月','十一月','十二月'],
-		monthNamesShort: ['一','二','三','四','五','六',
-		'七','八','九','十','十一','十二'],
-		dayNames: ['星期日','星期一','星期二','星期三','星期四','星期五','星期六'],
-		dayNamesShort: ['周日','周一','周二','周三','周四','周五','周六'],
-		dayNamesMin: ['日','一','二','三','四','五','六'],
-		weekHeader: '周',
-		dateFormat: 'yy/mm/dd',
-		firstDay: 1,
-		isRTL: false,
-		showMonthAfterYear: true,
-		yearSuffix: '年'};
-	$.datepicker.setDefaults($.datepicker.regional['zh-TW']);
-});

+ 0 - 23
main/inc/lib/javascript/jquery-ui/ui/i18n/jquery.ui.datepicker-af.js

@@ -1,23 +0,0 @@
-/* Afrikaans initialisation for the jQuery UI date picker plugin. */
-/* Written by Renier Pretorius. */
-jQuery(function($){
-	$.datepicker.regional['af'] = {
-		closeText: 'Selekteer',
-		prevText: 'Vorige',
-		nextText: 'Volgende',
-		currentText: 'Vandag',
-		monthNames: ['Januarie','Februarie','Maart','April','Mei','Junie',
-		'Julie','Augustus','September','Oktober','November','Desember'],
-		monthNamesShort: ['Jan', 'Feb', 'Mrt', 'Apr', 'Mei', 'Jun',
-		'Jul', 'Aug', 'Sep', 'Okt', 'Nov', 'Des'],
-		dayNames: ['Sondag', 'Maandag', 'Dinsdag', 'Woensdag', 'Donderdag', 'Vrydag', 'Saterdag'],
-		dayNamesShort: ['Son', 'Maa', 'Din', 'Woe', 'Don', 'Vry', 'Sat'],
-		dayNamesMin: ['So','Ma','Di','Wo','Do','Vr','Sa'],
-		weekHeader: 'Wk',
-		dateFormat: 'dd/mm/yy',
-		firstDay: 1,
-		isRTL: false,
-		showMonthAfterYear: false,
-		yearSuffix: ''};
-	$.datepicker.setDefaults($.datepicker.regional['af']);
-});

+ 0 - 23
main/inc/lib/javascript/jquery-ui/ui/i18n/jquery.ui.datepicker-ar-DZ.js

@@ -1,23 +0,0 @@
-/* Algerian Arabic Translation for jQuery UI date picker plugin. (can be used for Tunisia)*/
-/* Mohamed Cherif BOUCHELAGHEM -- cherifbouchelaghem@yahoo.fr */
-
-jQuery(function($){
-	$.datepicker.regional['ar-DZ'] = {
-		closeText: 'إغلاق',
-		prevText: '&#x3c;السابق',
-		nextText: 'التالي&#x3e;',
-		currentText: 'اليوم',
-		monthNames: ['جانفي', 'فيفري', 'مارس', 'أفريل', 'ماي', 'جوان',
-		'جويلية', 'أوت', 'سبتمبر','أكتوبر', 'نوفمبر', 'ديسمبر'],
-		monthNamesShort: ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12'],
-		dayNames: ['الأحد', 'الاثنين', 'الثلاثاء', 'الأربعاء', 'الخميس', 'الجمعة', 'السبت'],
-		dayNamesShort: ['الأحد', 'الاثنين', 'الثلاثاء', 'الأربعاء', 'الخميس', 'الجمعة', 'السبت'],
-		dayNamesMin: ['الأحد', 'الاثنين', 'الثلاثاء', 'الأربعاء', 'الخميس', 'الجمعة', 'السبت'],
-		weekHeader: 'أسبوع',
-		dateFormat: 'dd/mm/yy',
-		firstDay: 6,
-  		isRTL: true,
-		showMonthAfterYear: false,
-		yearSuffix: ''};
-	$.datepicker.setDefaults($.datepicker.regional['ar-DZ']);
-});

+ 0 - 23
main/inc/lib/javascript/jquery-ui/ui/i18n/jquery.ui.datepicker-ar.js

@@ -1,23 +0,0 @@
-/* Arabic Translation for jQuery UI date picker plugin. */
-/* Khaled Alhourani -- me@khaledalhourani.com */
-/* NOTE: monthNames are the original months names and they are the Arabic names, not the new months name فبراير - يناير and there isn't any Arabic roots for these months */
-jQuery(function($){
-	$.datepicker.regional['ar'] = {
-		closeText: 'إغلاق',
-		prevText: '&#x3c;السابق',
-		nextText: 'التالي&#x3e;',
-		currentText: 'اليوم',
-		monthNames: ['كانون الثاني', 'شباط', 'آذار', 'نيسان', 'مايو', 'حزيران',
-		'تموز', 'آب', 'أيلول',	'تشرين الأول', 'تشرين الثاني', 'كانون الأول'],
-		monthNamesShort: ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12'],
-		dayNames: ['الأحد', 'الاثنين', 'الثلاثاء', 'الأربعاء', 'الخميس', 'الجمعة', 'السبت'],
-		dayNamesShort: ['الأحد', 'الاثنين', 'الثلاثاء', 'الأربعاء', 'الخميس', 'الجمعة', 'السبت'],
-		dayNamesMin: ['ح', 'ن', 'ث', 'ر', 'خ', 'ج', 'س'],
-		weekHeader: 'أسبوع',
-		dateFormat: 'dd/mm/yy',
-		firstDay: 6,
-  		isRTL: true,
-		showMonthAfterYear: false,
-		yearSuffix: ''};
-	$.datepicker.setDefaults($.datepicker.regional['ar']);
-});

+ 0 - 23
main/inc/lib/javascript/jquery-ui/ui/i18n/jquery.ui.datepicker-az.js

@@ -1,23 +0,0 @@
-/* Azerbaijani (UTF-8) initialisation for the jQuery UI date picker plugin. */
-/* Written by Jamil Najafov (necefov33@gmail.com). */
-jQuery(function($) {
-	$.datepicker.regional['az'] = {
-		closeText: 'Bağla',
-		prevText: '&#x3c;Geri',
-		nextText: 'İrəli&#x3e;',
-		currentText: 'Bugün',
-		monthNames: ['Yanvar','Fevral','Mart','Aprel','May','İyun',
-		'İyul','Avqust','Sentyabr','Oktyabr','Noyabr','Dekabr'],
-		monthNamesShort: ['Yan','Fev','Mar','Apr','May','İyun',
-		'İyul','Avq','Sen','Okt','Noy','Dek'],
-		dayNames: ['Bazar','Bazar ertəsi','Çərşənbə axşamı','Çərşənbə','Cümə axşamı','Cümə','Şənbə'],
-		dayNamesShort: ['B','Be','Ça','Ç','Ca','C','Ş'],
-		dayNamesMin: ['B','B','Ç','С','Ç','C','Ş'],
-		weekHeader: 'Hf',
-		dateFormat: 'dd.mm.yy',
-		firstDay: 1,
-		isRTL: false,
-		showMonthAfterYear: false,
-		yearSuffix: ''};
-	$.datepicker.setDefaults($.datepicker.regional['az']);
-});

+ 0 - 24
main/inc/lib/javascript/jquery-ui/ui/i18n/jquery.ui.datepicker-bg.js

@@ -1,24 +0,0 @@
-/* Bulgarian initialisation for the jQuery UI date picker plugin. */
-/* Written by Stoyan Kyosev (http://svest.org). */
-jQuery(function($){
-    $.datepicker.regional['bg'] = {
-        closeText: 'затвори',
-        prevText: '&#x3c;назад',
-        nextText: 'напред&#x3e;',
-		nextBigText: '&#x3e;&#x3e;',
-        currentText: 'днес',
-        monthNames: ['Януари','Февруари','Март','Април','Май','Юни',
-        'Юли','Август','Септември','Октомври','Ноември','Декември'],
-        monthNamesShort: ['Яну','Фев','Мар','Апр','Май','Юни',
-        'Юли','Авг','Сеп','Окт','Нов','Дек'],
-        dayNames: ['Неделя','Понеделник','Вторник','Сряда','Четвъртък','Петък','Събота'],
-        dayNamesShort: ['Нед','Пон','Вто','Сря','Чет','Пет','Съб'],
-        dayNamesMin: ['Не','По','Вт','Ср','Че','Пе','Съ'],
-		weekHeader: 'Wk',
-        dateFormat: 'dd.mm.yy',
-		firstDay: 1,
-        isRTL: false,
-		showMonthAfterYear: false,
-		yearSuffix: ''};
-    $.datepicker.setDefaults($.datepicker.regional['bg']);
-});

+ 0 - 23
main/inc/lib/javascript/jquery-ui/ui/i18n/jquery.ui.datepicker-bs.js

@@ -1,23 +0,0 @@
-/* Bosnian i18n for the jQuery UI date picker plugin. */
-/* Written by Kenan Konjo. */
-jQuery(function($){
-	$.datepicker.regional['bs'] = {
-		closeText: 'Zatvori', 
-		prevText: '&#x3c;', 
-		nextText: '&#x3e;', 
-		currentText: 'Danas', 
-		monthNames: ['Januar','Februar','Mart','April','Maj','Juni',
-		'Juli','August','Septembar','Oktobar','Novembar','Decembar'],
-		monthNamesShort: ['Jan','Feb','Mar','Apr','Maj','Jun',
-		'Jul','Aug','Sep','Okt','Nov','Dec'],
-		dayNames: ['Nedelja','Ponedeljak','Utorak','Srijeda','Četvrtak','Petak','Subota'],
-		dayNamesShort: ['Ned','Pon','Uto','Sri','Čet','Pet','Sub'],
-		dayNamesMin: ['Ne','Po','Ut','Sr','Če','Pe','Su'],
-		weekHeader: 'Wk',
-		dateFormat: 'dd.mm.yy',
-		firstDay: 1,
-		isRTL: false,
-		showMonthAfterYear: false,
-		yearSuffix: ''};
-	$.datepicker.setDefaults($.datepicker.regional['bs']);
-});

+ 0 - 23
main/inc/lib/javascript/jquery-ui/ui/i18n/jquery.ui.datepicker-ca.js

@@ -1,23 +0,0 @@
-/* Inicialització en català per a l'extenció 'calendar' per jQuery. */
-/* Writers: (joan.leon@gmail.com). */
-jQuery(function($){
-	$.datepicker.regional['ca'] = {
-		closeText: 'Tancar',
-		prevText: '&#x3c;Ant',
-		nextText: 'Seg&#x3e;',
-		currentText: 'Avui',
-		monthNames: ['Gener','Febrer','Mar&ccedil;','Abril','Maig','Juny',
-		'Juliol','Agost','Setembre','Octubre','Novembre','Desembre'],
-		monthNamesShort: ['Gen','Feb','Mar','Abr','Mai','Jun',
-		'Jul','Ago','Set','Oct','Nov','Des'],
-		dayNames: ['Diumenge','Dilluns','Dimarts','Dimecres','Dijous','Divendres','Dissabte'],
-		dayNamesShort: ['Dug','Dln','Dmt','Dmc','Djs','Dvn','Dsb'],
-		dayNamesMin: ['Dg','Dl','Dt','Dc','Dj','Dv','Ds'],
-		weekHeader: 'Sm',
-		dateFormat: 'dd/mm/yy',
-		firstDay: 1,
-		isRTL: false,
-		showMonthAfterYear: false,
-		yearSuffix: ''};
-	$.datepicker.setDefaults($.datepicker.regional['ca']);
-});

+ 0 - 23
main/inc/lib/javascript/jquery-ui/ui/i18n/jquery.ui.datepicker-cs.js

@@ -1,23 +0,0 @@
-/* Czech initialisation for the jQuery UI date picker plugin. */
-/* Written by Tomas Muller (tomas@tomas-muller.net). */
-jQuery(function($){
-	$.datepicker.regional['cs'] = {
-		closeText: 'Zavřít',
-		prevText: '&#x3c;Dříve',
-		nextText: 'Později&#x3e;',
-		currentText: 'Nyní',
-		monthNames: ['leden','únor','březen','duben','květen','červen',
-        'červenec','srpen','září','říjen','listopad','prosinec'],
-		monthNamesShort: ['led','úno','bře','dub','kvě','čer',
-		'čvc','srp','zář','říj','lis','pro'],
-		dayNames: ['neděle', 'pondělí', 'úterý', 'středa', 'čtvrtek', 'pátek', 'sobota'],
-		dayNamesShort: ['ne', 'po', 'út', 'st', 'čt', 'pá', 'so'],
-		dayNamesMin: ['ne','po','út','st','čt','pá','so'],
-		weekHeader: 'Týd',
-		dateFormat: 'dd.mm.yy',
-		firstDay: 1,
-		isRTL: false,
-		showMonthAfterYear: false,
-		yearSuffix: ''};
-	$.datepicker.setDefaults($.datepicker.regional['cs']);
-});

+ 0 - 23
main/inc/lib/javascript/jquery-ui/ui/i18n/jquery.ui.datepicker-cy-GB.js

@@ -1,23 +0,0 @@
-/* Welsh/UK initialisation for the jQuery UI date picker plugin. */
-/* Written by William Griffiths. */
-jQuery(function($){
-	$.datepicker.regional['cy-GB'] = {
-		closeText: 'Done',
-		prevText: 'Prev',
-		nextText: 'Next',
-		currentText: 'Today',
-		monthNames: ['Ionawr','Chwefror','Mawrth','Ebrill','Mai','Mehefin',
-		'Gorffennaf','Awst','Medi','Hydref','Tachwedd','Rhagfyr'],
-		monthNamesShort: ['Ion', 'Chw', 'Maw', 'Ebr', 'Mai', 'Meh',
-		'Gor', 'Aws', 'Med', 'Hyd', 'Tac', 'Rha'],
-		dayNames: ['Dydd Sul', 'Dydd Llun', 'Dydd Mawrth', 'Dydd Mercher', 'Dydd Iau', 'Dydd Gwener', 'Dydd Sadwrn'],
-		dayNamesShort: ['Sul', 'Llu', 'Maw', 'Mer', 'Iau', 'Gwe', 'Sad'],
-		dayNamesMin: ['Su','Ll','Ma','Me','Ia','Gw','Sa'],
-		weekHeader: 'Wy',
-		dateFormat: 'dd/mm/yy',
-		firstDay: 1,
-		isRTL: false,
-		showMonthAfterYear: false,
-		yearSuffix: ''};
-	$.datepicker.setDefaults($.datepicker.regional['cy-GB']);
-});

Some files were not shown because too many files changed in this diff