Browse Source

Merge pull request #1177 from aragonc/ofaj

Ofaj
Yannick Warnier 8 years ago
parent
commit
444be324e9
85 changed files with 1597 additions and 1536 deletions
  1. 8 2
      app/Migrations/Schema/V111/Version111.php
  2. 24 5
      app/Resources/public/css/base.css
  3. 8 6
      app/Resources/public/css/themes/rainbow/default.css
  4. 15 15
      main/admin/configure_plugin.php
  5. 0 1
      main/admin/settings.lib.php
  6. 1 1
      main/auth/courses.php
  7. 49 11
      main/coursecopy/classes/CourseRestorer.class.php
  8. 1 1
      main/coursecopy/classes/CourseSelectForm.class.php
  9. 4 2
      main/inc/ajax/plugin.ajax.php
  10. 13 1
      main/inc/lib/api.lib.php
  11. 23 24
      main/inc/lib/course.lib.php
  12. 19 0
      main/inc/lib/course_category.lib.php
  13. 11 12
      main/inc/lib/display.lib.php
  14. 1 2
      main/inc/lib/formvalidator/Element/DateTimePicker.php
  15. 2 2
      main/inc/lib/formvalidator/Element/SelectAjax.php
  16. 2 2
      main/inc/lib/internationalization.lib.php
  17. 24 24
      main/inc/lib/message.lib.php
  18. 81 159
      main/inc/lib/pear/HTML/QuickForm/select.php
  19. 36 19
      main/inc/lib/plugin.class.php
  20. 13 12
      main/inc/lib/plugin.lib.php
  21. 6 5
      main/inc/lib/social.lib.php
  22. 31 9
      main/inc/lib/template.lib.php
  23. 2 2
      main/inc/lib/usergroup.lib.php
  24. 38 26
      main/inc/lib/userportal.lib.php
  25. 2 2
      main/session/session_add.php
  26. 1 3
      main/social/group_topics.php
  27. 6 6
      main/social/group_view.php
  28. 4 0
      main/template/default/auth/session_catalog.tpl
  29. 91 0
      main/template/default/user_portal/grid_session.tpl
  30. 0 3
      main/template/default/user_portal/index.tpl
  31. 0 5
      main/template/default/user_portal/index_grid.tpl
  32. 58 53
      main/template/default/user_portal/session.tpl
  33. 0 99
      plugin/advanced_subscription/readme.txt
  34. 2 2
      plugin/buycourses/index.php
  35. 87 0
      plugin/courseblock/CourseBlockPlugin.php
  36. 8 0
      plugin/courseblock/README.md
  37. 5 0
      plugin/courseblock/config.php
  38. 2 0
      plugin/courseblock/index.php
  39. 9 0
      plugin/courseblock/install.php
  40. 11 0
      plugin/courseblock/lang/english.php
  41. 2 0
      plugin/courseblock/lang/french.php
  42. 2 0
      plugin/courseblock/lang/spanish.php
  43. 4 0
      plugin/courseblock/plugin.php
  44. 2 1
      plugin/courselegal/README.md
  45. 0 1
      plugin/courselegal/config.php
  46. 1 2
      plugin/courselegal/plugin.php
  47. 0 2
      plugin/olpc_peru_filter/lib/olpc_peru_filter_plugin.class.php
  48. 4 0
      plugin/openmeetings/README.md
  49. 1 1
      plugin/openmeetings/config.php
  50. 1 1
      plugin/openmeetings/plugin.php
  51. 0 2
      plugin/skype/readme.txt
  52. 1 0
      plugin/ticket/README.md
  53. 0 12
      plugin/ticket/config.install.php
  54. 0 23
      plugin/ticket/config.php
  55. 40 36
      plugin/ticket/database.php
  56. 5 3
      plugin/ticket/lang/english.php
  57. 2 0
      plugin/ticket/lang/french.php
  58. 2 0
      plugin/ticket/lang/spanish.php
  59. 0 1
      plugin/ticket/readme.txt
  60. 1 1
      plugin/ticket/src/assign_tickets.php
  61. 13 7
      plugin/ticket/src/categories.php
  62. 6 3
      plugin/ticket/src/categories_add_user.php
  63. 1 1
      plugin/ticket/src/course_user_list.php
  64. 1 1
      plugin/ticket/src/download.php
  65. 2 2
      plugin/ticket/src/index.php
  66. 120 256
      plugin/ticket/src/myticket.php
  67. 31 72
      plugin/ticket/src/new_ticket.php
  68. 1 2
      plugin/ticket/src/report.php
  69. 0 15
      plugin/ticket/src/test.html
  70. 367 381
      plugin/ticket/src/ticket.class.php
  71. 1 1
      plugin/ticket/src/ticket_assign_log.php
  72. 185 89
      plugin/ticket/src/ticket_details.php
  73. 1 5
      plugin/ticket/src/ticket_plugin.class.php
  74. 2 2
      plugin/ticket/src/tutor.php
  75. 3 3
      plugin/ticket/src/update_report.php
  76. 0 25
      plugin/tour/readme.txt
  77. 5 5
      plugin/vchamilo/README.md
  78. 1 10
      plugin/vchamilo/index.php
  79. 1 1
      plugin/vchamilo/lang/english.php
  80. 50 30
      plugin/vchamilo/lib.php
  81. 1 1
      plugin/vchamilo/plugin.php
  82. 2 2
      plugin/vchamilo/views/editinstance.controller.php
  83. 11 3
      plugin/vchamilo/views/editinstance_form.php
  84. 25 16
      plugin/vchamilo/views/manage.controller.php
  85. 1 1
      plugin/vchamilo/views/manage.php

+ 8 - 2
app/Migrations/Schema/V111/Version111.php

@@ -137,9 +137,15 @@ class Version111 extends AbstractMigrationChamilo
         $this->addSql('DROP TABLE group_rel_tag');
         $this->addSql('DROP TABLE group_rel_group');
         $this->addSql('DROP TABLE groups');
-    }
 
-    /**
+        if ($schema->hasTable('plugin_ticket_ticket')) {
+            $this->addSql('ALTER TABLE plugin_ticket_ticket ADD COLUMN subject varchar(255) DEFAULT NULL;');
+            $this->addSql('ALTER TABLE plugin_ticket_ticket ADD COLUMN message text NOT NULL;');
+            $this->addSql('UPDATE plugin_ticket_ticket t INNER JOIN plugin_ticket_message as m  ON(t.ticket_id = m.ticket_id and message_id =1)  SET t.subject = m.subject');
+            $this->addSql('UPDATE plugin_ticket_ticket t INNER JOIN plugin_ticket_message as m  ON(t.ticket_id = m.ticket_id and message_id =1)  SET t.message = m.message');
+            $this->addSql('DELETE FROM plugin_ticket_message WHERE message_id = 1');
+        }
+}    /**
      * @param Schema $schema
      */
     public function postUp(Schema $schema)

+ 24 - 5
app/Resources/public/css/base.css

@@ -4705,7 +4705,21 @@ div#chat-remote-video video {
     display: inline-block;
 }
 /* list my course user*/
-
+.session .info-session{
+    margin-bottom: 10px;
+    font-size: 12px;
+}
+.session .info-session span{
+    margin-right: 10px;
+}
+.session .teachers{
+    font-size: 12px;
+}
+.session .sessions-items .courses{
+    padding-bottom: 10px;
+    padding-top: 10px;
+    border-bottom: 1px solid #ECF0F1;
+}
 .grid-courses .items{
     /* position: relative; */
     vertical-align: top;
@@ -4723,18 +4737,22 @@ div#chat-remote-video video {
 }
 .grid-courses .items .title{
     line-height: 1.4;
-    font-size: 13px;
-    min-height: 40px;
+    font-size: 14px;
     padding: 0px;
     margin: 5px;
 }
 .grid-courses .items .toolbar{
     text-align: right;
 }
-.grid-courses .session-date{
+.grid-courses .items .toolbar .info{
+    float: left;
+    font-size: 12px;
+}
+.grid-courses .session-date,
+.grid-courses .session-info{
     color: #fff;
     font-size: 12px;
-    padding: 10px;
+    padding: 5px 10px;
 }
 .grid-courses .items .image{
     position: relative;
@@ -4838,6 +4856,7 @@ div#chat-remote-video video {
     color: #fff;
 }
 /* Catalog session */
+
 .search-session{
     margin-bottom: 30px;
     margin-top: 25px;

+ 8 - 6
app/Resources/public/css/themes/rainbow/default.css

@@ -283,12 +283,12 @@ a:focus {
    background-color: transparent;
 }
 .btn-primary{
-    background-color: #E53140;
-    border-color: #E53140;
+    background-color: #009EE0;
+    border-color: #009EE0;
 }
 .btn-primary:hover{
-    background-color: #CE2D30;
-    border-color: #CE2D30;
+    background-color: #000080;
+    border-color: #000080;
 }
 .navbar-inverse li a{
   line-height: 30px;
@@ -360,7 +360,7 @@ a:focus {
 }
 /* End Jquery UI */
 footer{
-  background-color:#E53140;
+  background-color:#009EE0;
 }
 footer{
   color: #ffffff;
@@ -368,7 +368,9 @@ footer{
 footer a{
   color: #ffffff;
 }
-
+footer a:hover{
+    color: #FFD42A;
+}
 .navbar-default .navbar-brand {
   color:white;
 }

+ 15 - 15
main/admin/configure_plugin.php

@@ -25,17 +25,23 @@ if (!in_array($pluginName, $installedPlugins) || empty($pluginInfo)) {
 
 global $_configuration;
 
-$message = null;
-$content = null;
+$message = '';
+$content = '';
 
 $currentUrl = api_get_self() . "?name=$pluginName";
 
 if (isset($pluginInfo['settings_form'])) {
+    /** @var FormValidator $form */
     $form = $pluginInfo['settings_form'];
     if (isset($form)) {
-        //We override the form attributes
+
+        // We override the form attributes
         $attributes = array('action' => $currentUrl, 'method' => 'POST');
         $form->updateAttributes($attributes);
+
+        if (isset($pluginInfo['settings'])) {
+            $form->setDefaults($pluginInfo['settings']);
+        }
         $content = Display::page_header($pluginInfo['title']);
         $content .= $form->toHtml();
     }
@@ -46,8 +52,6 @@ if (isset($pluginInfo['settings_form'])) {
 if (isset($form)) {
     if ($form->validate()) {
         $values = $form->exportValues();
-
-        //api_delete_category_settings_by_subkey($pluginName);
         $accessUrlId = api_get_current_access_url_id();
 
         api_delete_settings_params(
@@ -64,7 +68,8 @@ if (isset($form)) {
 
         foreach ($values as $key => $value) {
             api_add_setting(
-                $value, Database::escape_string($pluginName . '_' . $key),
+                $value,
+                Database::escape_string($pluginName . '_' . $key),
                 $pluginName,
                 'setting',
                 'Plugins',
@@ -76,28 +81,23 @@ if (isset($form)) {
                 1
             );
         }
+
         if (isset($values['show_main_menu_tab'])) {
             $objPlugin = $pluginInfo['plugin_class']::create();
             $objPlugin->manageTab($values['show_main_menu_tab']);
         }
 
-        $message = Display::return_message(get_lang('Updated'), 'success');
-
-        Session::write('message', $message);
+        Display::addFlash(Display::return_message(get_lang('Updated'), 'success'));
 
         header("Location: $currentUrl");
         exit;
     } else {
         foreach ($form->_errors as $error) {
-            $message .= Display::return_message($error, 'error');
+            Display::addFlash(Display::return_message($error, 'error'));
         }
     }
 }
 
-if (Session::has('message')) {
-    $message = Session::read('message');
-}
-
 $interbreadcrumb[] = array(
     'url' => api_get_path(WEB_CODE_PATH) . 'admin/index.php',
     'name' => get_lang('PlatformAdmin')
@@ -108,7 +108,7 @@ $interbreadcrumb[] = array(
 );
 
 $tpl = new Template($pluginName, true, true, false, true, false);
-$tpl->assign('message', $message);
+$tpl->assign('message', '');
 $tpl->assign('content', $content);
 $tpl->display_one_col_template();
 

+ 0 - 1
main/admin/settings.lib.php

@@ -167,7 +167,6 @@ function handle_plugins()
                 echo '<input type="checkbox" name="plugin_'.$plugin.'[]">';
             }
             echo '</td><td>';
-
             echo '<h4>'.$plugin_info['title'].' <small>v '.$plugin_info['version'].'</small></h4>';
             echo '<p>'.$plugin_info['comment'].'</p>';
             echo '<p>'.get_lang('Author').': '.$plugin_info['author'].'</p>';

+ 1 - 1
main/auth/courses.php

@@ -18,7 +18,7 @@ require_once '../inc/global.inc.php';
 $ctok = Security::get_existing_token();
 
 // Get Limit data
-$limit = CourseCategory::getLimitArray();
+$limit = CourseCategory::getLimitFilterFromArray();
 
 // Section for the tabs.
 $this_section = SECTION_CATALOG;

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

@@ -465,6 +465,7 @@ class CourseRestorer
                                             'filetype' => self::DBUTF8($document->file_type),
                                             'size' => self::DBUTF8($document->size),
                                             'session_id' => $my_session_id,
+                                            'readonly' => 0
                                         ];
 
     									$document_id = Database::insert($table, $params);
@@ -889,6 +890,7 @@ class CourseRestorer
                                 'filetype' => self::DBUTF8($document->file_type),
                                 'size' => self::DBUTF8($document->size),
                                 'session_id' => $my_session_id,
+                                'readonly' => 0
                             ];
 
                             $document_id = Database::insert($table, $params);
@@ -1051,7 +1053,9 @@ class CourseRestorer
                 $params['forum_category'] = $cat_id;
                 $params['session_id'] = $sessionId;
 
-                unset($params['forum_id']);
+                $params['start_time'] = isset($params['start_time']) && $params['start_time'] === '0000-00-00 00:00:00' ? null : $params['start_time'];
+                $params['end_time'] = isset($params['end_time']) && $params['end_time'] === '0000-00-00 00:00:00' ? null : $params['end_time'];
+                $params['forum_id'] = 0;
                 unset($params['iid']);
 
                 $params['forum_comment'] = DocumentManager::replace_urls_inside_content_html_from_copy_course(
@@ -1131,8 +1135,7 @@ class CourseRestorer
                         $this->course->info['path']
                     );
                     $params['session_id'] = intval($sessionId);
-
-                    unset($params['cat_id']);
+                    $params['cat_id'] = 0;
                     unset($params['iid']);
 
                     $params = self::DBUTF8_array($params);
@@ -1172,7 +1175,8 @@ class CourseRestorer
         $params['thread_replies'] = 0;
         $params['thread_views'] = 0;
         $params['session_id'] = intval($sessionId);
-        unset($params['thread_id']);
+        $params['thread_id'] = 0;
+
         unset($params['iid']);
 
         $new_id = Database::insert($table, $params);
@@ -1223,7 +1227,7 @@ class CourseRestorer
         $params['thread_id'] = $topic_id;
         $params['poster_id'] = $this->first_teacher_id;
         $params['post_date'] = api_get_utc_datetime();
-        unset($params['post_id']);
+        $params['post_id'] = 0;
         unset($params['iid']);
         $params['post_text'] = DocumentManager::replace_urls_inside_content_html_from_copy_course(
             $params['post_text'],
@@ -1545,6 +1549,7 @@ class CourseRestorer
                 $params['description_type'] = self::DBUTF8($descriptionType);
                 $params['title'] = self::DBUTF8($title);
                 $params['content'] = self::DBUTF8($description_content);
+                $params['progress'] = 0;
 
                 $id = Database::insert($table, $params);
                 if ($id) {
@@ -1736,6 +1741,9 @@ class CourseRestorer
                         $this->course->info['path']
                     );
 
+                    $quiz->start_time = $quiz->start_time == '0000-00-00 00:00:00' ? null : $quiz->start_time;
+                    $quiz->end_time = $quiz->end_time == '0000-00-00 00:00:00' ? null : $quiz->end_time;
+
 					global $_custom;
 					if (isset($_custom['exercises_clean_dates_when_restoring']) &&
                         $_custom['exercises_clean_dates_when_restoring']
@@ -1744,6 +1752,7 @@ class CourseRestorer
 						$quiz->end_time   = null;
 					}
 
+
                     $params = array(
                         'c_id' => $this->destination_course_id,
                         'title' => self::DBUTF8($quiz->title),
@@ -1755,9 +1764,7 @@ class CourseRestorer
                         'max_attempt' => (int)$quiz->max_attempt,
                         'results_disabled' => (int)$quiz->results_disabled,
                         'access_condition' => $quiz->access_condition,
-                        'start_time' => $quiz->start_time,
                         'pass_percentage' => $quiz->pass_percentage,
-                        'end_time' => $quiz->end_time,
                         'feedback_type' => (int)$quiz->feedback_type,
                         'random_answers' => (int)$quiz->random_answers,
                         'random_by_category' => $quiz->random_by_category,
@@ -1765,6 +1772,10 @@ class CourseRestorer
                         'propagate_neg' => $quiz->propagate_neg,
                         'text_when_finished' => $quiz->text_when_finished,
                         'expired_time' => (int)$quiz->expired_time,
+                        'start_time' => $quiz->start_time,
+                        'end_time' => $quiz->end_time,
+                        'save_correct_answers' => 0,
+                        'display_category_name' => 0
                     );
 
                     if ($respect_base_content) {
@@ -1902,6 +1913,8 @@ class CourseRestorer
                         'position' => $answer['position'],
                         'hotspot_coordinates' => $answer['hotspot_coordinates'],
                         'hotspot_type' => $answer['hotspot_type'],
+                        'id_auto' => 0,
+                        'destination' => ''
                     ];
                     $answerId = Database::insert($table_ans, $params);
 
@@ -1943,6 +1956,8 @@ class CourseRestorer
                         'position' => $answer['position'],
                         'hotspot_coordinates' => $answer['hotspot_coordinates'],
                         'hotspot_type' => $answer['hotspot_type'],
+                        'id_auto' => 0,
+                        'destination' => ''
                     ];
 
                     $answerId = Database::insert($table_ans, $params);
@@ -2461,6 +2476,9 @@ class CourseRestorer
                     }
                 }
 
+                $lp->expired_on = isset($lp->expired_on) && $lp->expired_on === '0000-00-00 00:00:00' ? null : $lp->expired_on;
+                $lp->publicated_on = isset($lp->publicated_on) && $lp->publicated_on === '0000-00-00 00:00:00' ? null : $lp->publicated_on;
+
                 $params = [
                     'c_id' => $this->destination_course_id,
                     'lp_type' => $lp->lp_type,
@@ -2486,6 +2504,14 @@ class CourseRestorer
                     'publicated_on' => empty($lp->publicated_on) ? api_get_utc_datetime() : self::DBUTF8($lp->publicated_on),
                     'expired_on' => self::DBUTF8($lp->expired_on),
                     'debug' => self::DBUTF8($lp->debug),
+                    'theme' => '',
+                    'session_id' => $session_id,
+                    'prerequisite' => 0,
+                    'hide_toc_frame' => 0,
+                    'seriousgame_mode' => 0,
+                    'category_id' => 0,
+                    'max_attempts' => 0,
+                    'subscribe_users' => 0
                 ];
 
                 if (!empty($condition_session)) {
@@ -2868,7 +2894,7 @@ class CourseRestorer
                 $params['description'] = self::DBUTF8($glossary->description);
                 $params['display_order'] = $glossary->display_order;
                 $params['name'] = self::DBUTF8($glossary->name);
-
+                $params['glossary_id'] = 0;
                 $my_id = Database::insert($table_glossary, $params);
                 if ($my_id) {
 
@@ -2930,6 +2956,18 @@ class CourseRestorer
                     'progress' => self::DBUTF8($wiki->progress),
                     'version' => intval($wiki->version),
                     'session_id' => !empty($session_id) ? intval($session_id) : 0,
+                    'addlock' => 0,
+                    'editlock' => 0,
+                    'visibility' => 0,
+                    'addlock_disc' => 0,
+                    'visibility_disc' => 0,
+                    'ratinglock_disc' => 0,
+                    'assignment' => 0,
+                    'comment' => '',
+                    'is_editing' => 0,
+                    'linksto' => 0,
+                    'tag' => '',
+                    'user_ip' => ''
                 ];
 
 				$new_id = Database::insert($table_wiki, $params);
@@ -2953,11 +2991,11 @@ class CourseRestorer
                         'fprogress1' => '',
                         'fprogress2' => '',
                         'fprogress3' => '',
-                        'max_size' => '',
+                        'max_size' => 0,
                         'max_text' => 0,
                         'max_version' => 0,
-                        'startdate_assig' => '',
-                        'enddate_assig' => '',
+                        'startdate_assig' => null,
+                        'enddate_assig' => null,
                         'delayedsubmit' => 0,
                     ];
 

+ 1 - 1
main/coursecopy/classes/CourseSelectForm.class.php

@@ -48,7 +48,7 @@ class CourseSelectForm
 				}
 				else{
 					el.style.display='none';
-					document.getElementById('img_'+item).src='<?php echo Display::returnIconPath('O.gif'); ?>';
+					document.getElementById('img_'+item).src='<?php echo Display::returnIconPath('0.gif'); ?>';
 				}
 			}
 

+ 4 - 2
main/inc/ajax/plugin.ajax.php

@@ -14,12 +14,14 @@ switch ($action) {
     case 'md_to_html':
         $plugin = isset($_GET['plugin']) ? $_GET['plugin'] : '';
         $appPlugin = new AppPlugin();
-        $pluginList = $appPlugin->get_installed_plugins();
+        $pluginInfo = $appPlugin->getPluginInfo($plugin);
+        
         $html = '';
-        if (in_array($plugin, $pluginList)) {
+        if (!empty($pluginInfo)) {
             $file = api_get_path(SYS_PLUGIN_PATH).$plugin.'/README.md';
             if (file_exists($file)) {
                 $content = file_get_contents($file);
+
                 $html = MarkdownExtra::defaultTransform($content);
             }
         }

+ 13 - 1
main/inc/lib/api.lib.php

@@ -5274,7 +5274,19 @@ function api_delete_category_settings_by_subkey($subkey, $access_url_id = 1) {
  * @param string $c
  * @return boolean  true on success, false on failure
  */
-function api_add_setting($val, $var, $sk = null, $type = 'textfield', $c = null, $title = '', $com = '', $sc = null, $skt = null, $a = 1, $v = 0) {
+function api_add_setting(
+    $val,
+    $var,
+    $sk = null,
+    $type = 'textfield',
+    $c = null,
+    $title = '',
+    $com = '',
+    $sc = null,
+    $skt = null,
+    $a = 1,
+    $v = 0
+) {
     if (empty($var) || !isset($val)) { return false; }
     $t_settings = Database::get_main_table(TABLE_MAIN_SETTINGS_CURRENT);
     $var = Database::escape_string($var);

+ 23 - 24
main/inc/lib/course.lib.php

@@ -3936,9 +3936,11 @@ class CourseManager
         $params = array();
         $params['icon'] = Display::return_icon(
             'blackboard_blue.png',
-            api_htmlentities($course_info['name']),
+            null,
             array(),
-            ICON_SIZE_LARGE
+            ICON_SIZE_LARGE,
+            null,
+            true  
         );
 
         // Display the "what's new" icons
@@ -3965,7 +3967,7 @@ class CourseManager
 
                 if ($user_in_course_status == COURSEMANAGER || $sessionCourseAvailable) {
                     $session_url = $course_info['course_public_url'] . '?id_session=' . $course_info['id_session'];
-                    $session_title = '<h4><a href="' . $session_url. '">'. $course_info['name'] . '</a>'.$notifications.'</h4>';
+                    $session_title = '<a href="' . $session_url. '">'. $course_info['name'] . '</a>'.$notifications;
                 } else {
                     $session_title = $course_info['name'];
                 }
@@ -3977,37 +3979,33 @@ class CourseManager
         } else {
             $session_title = $course_info['name'];
         }
-
+        
         $showCustomIcon = api_get_setting('course_images_in_courses_list');
         $iconName = basename($course_info['course_image']);
         if ($showCustomIcon === 'true' && $iconName != 'course.png') {
-            $params['icon'] = Display::img(
-                $course_info['course_image'],
-                api_htmlentities($course_info['name']),
-                array()
-            );
+            $params['icon'] = $course_info['course_image_large'];
         }
 
         $params['link'] = $session_url;
         $params['title'] = $session_title;
-        $params['right_actions'] = '';
-
+        $params['edit_actions'] = '';
+        $params['document'] = '';
+        
         if ($course_visibility != COURSE_VISIBILITY_CLOSED &&
             $course_visibility != COURSE_VISIBILITY_HIDDEN
         ) {
+            if (api_is_platform_admin()) {
+                $params['edit_actions'] .= api_get_path(WEB_CODE_PATH) . 'course_info/infocours.php?cidReq=' . $course_info['code'];
             if ($load_dirs) {
-                $params['right_actions'] .= '<a id="document_preview_' . $course_info['real_id'] . '_' . $course_info['id_session'] . '" class="document_preview" href="javascript:void(0);">' .
-                    Display::return_icon('folder.png',
-                        get_lang('Documents'),
-                        array('align' => 'absmiddle'),
-                        ICON_SIZE_SMALL
-                    ) . '</a>';
-                $params['right_actions'] .= Display::div('', array(
+                $params['document'] .= '<a id="document_preview_' . $course_info['real_id'] . '_' . $course_info['id_session'] . '" class="document_preview btn btn-default btn-sm" href="javascript:void(0);">' .
+                    Display::returnFontAwesomeIcon('folder-open') . '</a>';
+                $params['document'] .= Display::div('', array(
                     'id' => 'document_result_' . $course_info['real_id'] . '_' . $course_info['id_session'],
                     'class' => 'document_preview_container'
                 ));
             }
         }
+        }
 
         if (api_get_setting('display_coursecode_in_courselist') == 'true') {
             $session_title .= ' (' . $course_info['visual_code'] . ') ';
@@ -4015,23 +4013,24 @@ class CourseManager
 
         if (api_get_setting('display_teacher_in_courselist') === 'true') {
 
-            $teacher_list = CourseManager::get_teacher_list_from_course_code_to_string(
-                $course_info['code'],
-                self::USER_SEPARATOR,
-                true
+            $teacher_list = CourseManager::getTeachersFromCourseByCode(
+                $course_info['code']
             );
+            
             $course_coachs = self::get_coachs_from_course(
                 $course_info['id_session'],
                 $course_info['real_id']
             );
 
-            if ($course_info['status'] == COURSEMANAGER ||
+            /* if ($course_info['status'] == COURSEMANAGER ||
                 ($course_info['status'] == STUDENT && empty($course_info['id_session'])) ||
                 empty($course_info['status'])
             ) {
                 $params['teachers'] = $teacher_list;
             }
-
+            */
+            $params['teachers'] = $teacher_list;
+            
             if (($course_info['status'] == STUDENT && !empty($course_info['id_session'])) ||
                 ($is_coach && $course_info['status'] != COURSEMANAGER)
             ) {

+ 19 - 0
main/inc/lib/course_category.lib.php

@@ -918,6 +918,25 @@ class CourseCategory
         return Database::store_result($result, 'ASSOC');
     }
 
+    /**
+     * @return array
+     */
+    public static function getLimitArray()
+    {
+        $pageCurrent = isset($_REQUEST['pageCurrent']) ?
+            intval($_GET['pageCurrent']) :
+            1;
+        $pageLength = isset($_REQUEST['pageLength']) ?
+            intval($_GET['pageLength']) :
+            10;
+
+        return array(
+            'start' => ($pageCurrent - 1) * $pageLength,
+            'current' => $pageCurrent,
+            'length' => $pageLength,
+        );
+    }
+
     /**
      * Return LIMIT to filter SQL query
      * @param array $limit

+ 11 - 12
main/inc/lib/display.lib.php

@@ -1523,9 +1523,11 @@ class Display
             $rs = Database::query($sql);
             $session_info = Database::store_result($rs, 'ASSOC');
             $session_info = $session_info[0];
-
+            
             $session = array();
+            $session['category_id'] = $session_info['session_category_id'];
             $session['title'] = $session_info['name'];
+            $session['id_coach'] = $session_info['id_coach'];
             $session['coach'] = '';
             $session['dates'] =  '';
 
@@ -1578,14 +1580,11 @@ class Display
                     $session_info['access_end_date'] = $session_info['access_end_date'];
                 }
                 if ($start && $stop) {
-                    $session['dates'] = Display::tag(
-                        'em',
-                        sprintf(
+                    $session['dates'] = sprintf(
                             get_lang('FromDateXToDateY'),
                             api_format_date($start_buffer),
                             api_format_date($stop_buffer)
-                        )
-                    );
+                        );
                 } else {
                     $start_buffer = $stop_buffer = null;
 
@@ -1603,14 +1602,12 @@ class Display
                         );
                     }
 
-                    $session['dates'] = Display::tag(
-                        'em',
-                        "$start_buffer $stop_buffer"
-                    );
+                    $session['dates'] = $start_buffer . " " . $stop_buffer;
+                   
                 }
 
                 if ( api_get_setting('show_session_coach') === 'true' ) {
-                    $session['coach'] = get_lang('GeneralCoach') . ': ' . api_get_person_name(
+                    $session['coach'] = api_get_person_name(
                         $session_info['firstname'],
                         $session_info['lastname']
                     );
@@ -1619,7 +1616,9 @@ class Display
             }
             $session['active'] = $active;
             $session['session_category_id'] = $session_info['session_category_id'];
-
+            $session['visibility'] = $session_info['visibility'];
+            $session['num_users'] = $session_info['nbr_users'];
+            $session['num_courses'] = $session_info['nbr_courses'];
             $session['description'] = $session_info['description'];
             $session['show_description'] = $session_info['show_description'];
 

+ 1 - 2
main/inc/lib/formvalidator/Element/DateTimePicker.php

@@ -32,12 +32,11 @@ class DateTimePicker extends HTML_QuickForm_text
 
         $id = $this->getAttribute('id');
         $value = $this->getValue();
-        $label = $this->getLabel();
 
         if (!empty($value)) {
             $value = api_format_date($value, DATE_TIME_FORMAT_LONG_24H);
         }
-
+        
         return $this->getElementJS() . '
             <div class="input-group">
                 <span class="input-group-addon">

+ 2 - 2
main/inc/lib/formvalidator/Element/SelectAjax.php

@@ -7,9 +7,9 @@
 class SelectAjax extends HTML_QuickForm_select
 {
     /**
-     * Class constructor
+     * @inheritdoc
      */
-    public function __construct($elementName = null, $elementLabel = null, $options = null, $attributes = null)
+    public function __construct($elementName, $elementLabel = '', $options = null, $attributes = null)
     {
         parent::__construct($elementName, $elementLabel, $options, $attributes);
     }

+ 2 - 2
main/inc/lib/internationalization.lib.php

@@ -1964,13 +1964,13 @@ function _api_convert_encoding_supports($encoding) {
  */
 function apiGetHumanDateTime($date, $showTime = true, $humanForm = false) {
     if ($showTime) {
-        if ($dateHuman) {
+        if ($humanForm) {
            return $date->format('j M Y H:i:s');    
         } else {
            return $date->format('Y-m-d H:i:s');     
         }
     } else {
-        if ($dateHuman) {
+        if ($humanForm) {
            return $date->format('j M Y');    
         } else {
            return $date->format('Y-m-d');     

+ 24 - 24
main/inc/lib/message.lib.php

@@ -281,7 +281,6 @@ class MessageManager
         if (!empty($receiver_user_id) || !empty($group_id)) {
 
             // message for user friend
-            $clean_subject = Database::escape_string($subject);
             $clean_content = Database::escape_string($content);
 
             //message in inbox for user friend
@@ -347,9 +346,10 @@ class MessageManager
                     $o = 0;
                     foreach ($file_attachments as $file_attach) {
                         if ($file_attach['error'] == 0) {
+                            $comment = isset($file_comments[$o]) ? $file_comments[$o] : '';
                             self::save_message_attachment_file(
                                 $file_attach,
-                                $file_comments[$o],
+                                $comment,
                                 $outbox_last_id,
                                 $user_sender_id
                             );
@@ -1292,10 +1292,10 @@ class MessageManager
         $name = $user_sender_info['complete_name'];
 
         $topic_page_nr = isset($_GET['topics_page_nr']) ? intval($_GET['topics_page_nr']) : null;
-        
+
         $links.= '<div class="pull-right">';
         $links.= '<div class="btn-group">';
-        
+
         if (($my_group_role == GROUP_USER_PERMISSION_ADMIN ||
             $my_group_role == GROUP_USER_PERMISSION_MODERATOR) ||
             $main_message['user_sender_id'] == $current_user_id
@@ -1314,23 +1314,23 @@ class MessageManager
             ]);
             if (api_is_platform_admin()) {
                 $links .= Display::url(
-                        Display::returnFontAwesomeIcon('trash'),
-                        'group_topics.php?action=delete&id='.$group_id.'&topic_id='.$topic_id,
-                        [
-                            'class' => 'btn btn-default'
-                        ]
-                        );
-            }            
+                    Display::returnFontAwesomeIcon('trash'),
+                    'group_topics.php?action=delete&id='.$group_id.'&topic_id='.$topic_id,
+                    [
+                        'class' => 'btn btn-default'
+                    ]
+                );
+            }
             $links .= Display::url(
-                        Display::returnFontAwesomeIcon('pencil'),
-                        $urlEdit,
-                        [
-                            'class' => 'btn btn-default ajax',
-                            'title' => get_lang('Edit'),
-                            'data-title' => get_lang('Edit'),
-                            'data-size' => 'lg'
-                        ]
-                    );
+                Display::returnFontAwesomeIcon('pencil'),
+                $urlEdit,
+                [
+                    'class' => 'btn btn-default ajax',
+                    'title' => get_lang('Edit'),
+                    'data-title' => get_lang('Edit'),
+                    'data-size' => 'lg'
+                ]
+            );
         }
 
         $urlReply = api_get_path(WEB_CODE_PATH);
@@ -1357,9 +1357,9 @@ class MessageManager
         );
         $links.= '</div>';
         $links.= '</div>';
-        
-        $title = '<h4>'.Security::remove_XSS($main_message['title'].$delete_button, STUDENT, true).$links.'</h4>';
-        
+
+        $title = '<h4>'.Security::remove_XSS($main_message['title'], STUDENT, true).$links.'</h4>';
+
         $userPicture = $user_sender_info['avatar'];
         $main_content .= '<div class="avatar-author">';
         $main_content .= '<img src="'.$userPicture.'" alt="'.$name.'" class="img-responsive img-circle" width="64" height="64" title="'.$name.'" />';
@@ -1410,7 +1410,7 @@ class MessageManager
                 $userPicture = $user_sender_info['avatar'];
                 $user_link = '<a href="'.api_get_path(WEB_PATH).'main/social/profile.php?u='.$topic['user_sender_id'].'">'.$name.'&nbsp</a>';
                 $html_items.= '<div class="avatar-author"><img src="'.$userPicture.'" alt="'.$name.'" class="img-responsive img-circle"  width="64" height="64" title="'.$name.'" />'.$user_link.'</div>';
-                
+
 
                 $date = '';
                 if ($topic['send_date'] != $topic['update_date']) {

+ 81 - 159
main/inc/lib/pear/HTML/QuickForm/select.php

@@ -54,26 +54,25 @@ class HTML_QuickForm_select extends HTML_QuickForm_element
      * @access    private
      */
     protected $_values = null;
-
     private $columnsSize;
 
     /**
      * Class constructor
      *
-     * @param     string    Select name attribute
-     * @param     mixed     Label(s) for the select
-     * @param     mixed     Data to be used to populate options
-     * @param     mixed     Either a typical HTML attribute string or an associative array
+     * @param     string    $elementName Select name attribute
+     * @param     mixed     $elementLabel Label(s) for the select
+     * @param     mixed     $options Data to be used to populate options
+     * @param     mixed     $attributes Either a typical HTML attribute string or an associative array
      * @since     1.0
      * @access    public
-     * @return    void
      */
     public function __construct(
-        $elementName = null,
-        $elementLabel = null,
+        $elementName,
+        $elementLabel = '',
         $options = null,
         $attributes = null
     ) {
+        $addBlank = '';
         if (is_array($attributes) || empty($attributes)) {
             $oldClass = '';
             if (!empty($attributes['class'])) {
@@ -81,17 +80,90 @@ class HTML_QuickForm_select extends HTML_QuickForm_element
             }
             $attributes['class'] = $oldClass . ' selectpicker show-tick form-control';
             $attributes['data-live-search'] = 'true';
+
+            if (isset($attributes['placeholder'])) {
+                $addBlank =  $attributes['placeholder'];
+            }
+
+
         }
         $columnsSize = isset($attributes['cols-size']) ? $attributes['cols-size'] : null;
         $this->setColumnsSize($columnsSize);
         parent::__construct($elementName, $elementLabel, $attributes);
         $this->_persistantFreeze = true;
         $this->_type = 'select';
+
+        if ($addBlank !== '') {
+            if (isset($options)) {
+                $options = ['' => $addBlank] + $options;
+            } else {
+                $options = ['' => $addBlank];
+            }
+        }
         if (isset($options)) {
             $this->load($options);
         }
     }
 
+     /**
+     * Loads options from different types of data sources
+     *
+     * This method is a simulated overloaded method.  The arguments, other than the
+     * first are optional and only mean something depending on the type of the first argument.
+     * If the first argument is an array then all arguments are passed in order to loadArray.
+     * If the first argument is a db_result then all arguments are passed in order to loadDbResult.
+     * If the first argument is a string or a DB connection then all arguments are
+     * passed in order to loadQuery.
+     * @param     mixed     $options     Options source currently supports assoc array or DB_result
+     * @param     mixed     $param1     (optional) See function detail
+     * @param     mixed     $param2     (optional) See function detail
+     * @param     mixed     $param3     (optional) See function detail
+     * @param     mixed     $param4     (optional) See function detail
+     * @since     1.1
+     * @access    public
+     * @return    PEAR_Error on error or true
+     * @throws    PEAR_Error
+     */
+    private function load(&$options, $param1=null, $param2=null, $param3=null, $param4=null)
+    {
+        switch (true) {
+            case is_array($options):
+                return $this->loadArray($options, $param1);
+                break;
+        }
+    }
+
+    /**
+     * Loads the options from an associative array
+     *
+     * @param     array    $arr     Associative array of options
+     * @param     mixed    $values  (optional) Array or comma delimited string of selected values
+     * @since     1.0
+     * @access    public
+     * @return    PEAR_Error on error or true
+     * @throws    PEAR_Error
+     */
+    private function loadArray($arr, $values = null)
+    {
+        if (!is_array($arr)) {
+            return false;
+        }
+        if (isset($values)) {
+            $this->setSelected($values);
+        }
+        foreach ($arr as $key => $val) {
+            // Fix in order to use list of entities.
+            if (is_object($val)) {
+                $key = $val->getId();
+                $val = $val->__toString();
+            }
+
+            // Warning: new API since release 2.3
+            $this->addOption($val, $key);
+        }
+        return true;
+    }
+
     /**
      * Returns the current API version
      *
@@ -363,156 +435,6 @@ class HTML_QuickForm_select extends HTML_QuickForm_element
         $this->_optgroups[] = array('label' => $label, 'options' => $options);
     }
 
-    /**
-     * Loads the options from an associative array
-     *
-     * @param     array    $arr     Associative array of options
-     * @param     mixed    $values  (optional) Array or comma delimited string of selected values
-     * @since     1.0
-     * @access    public
-     * @return    PEAR_Error on error or true
-     * @throws    PEAR_Error
-     */
-    function loadArray($arr, $values=null)
-    {
-        if (!is_array($arr)) {
-            return PEAR::raiseError('Argument 1 of HTML_Select::loadArray is not a valid array');
-        }
-        if (isset($values)) {
-            $this->setSelected($values);
-        }
-        foreach ($arr as $key => $val) {
-            // Fix in order to use list of entities.
-            if (is_object($val)) {
-                $key = $val->getId();
-                $val = $val->__toString();
-            }
-            // Warning: new API since release 2.3
-            $this->addOption($val, $key);
-        }
-        return true;
-    } // end func loadArray
-
-    // }}}
-    // {{{ loadDbResult()
-
-    /**
-     * Loads the options from DB_result object
-     *
-     * If no column names are specified the first two columns of the result are
-     * used as the text and value columns respectively
-     * @param     object    $result     DB_result object
-     * @param     string    $textCol    (optional) Name of column to display as the OPTION text
-     * @param     string    $valueCol   (optional) Name of column to use as the OPTION value
-     * @param     mixed     $values     (optional) Array or comma delimited string of selected values
-     * @since     1.0
-     * @access    public
-     * @return    PEAR_Error on error or true
-     * @throws    PEAR_Error
-     */
-    function loadDbResult(&$result, $textCol=null, $valueCol=null, $values=null)
-    {
-        if (!is_object($result) || !is_a($result, 'db_result')) {
-            return PEAR::raiseError('Argument 1 of HTML_Select::loadDbResult is not a valid DB_result');
-        }
-        if (isset($values)) {
-            $this->setValue($values);
-        }
-        $fetchMode = ($textCol && $valueCol) ? DB_FETCHMODE_ASSOC : DB_FETCHMODE_ORDERED;
-        while (is_array($row = $result->fetchRow($fetchMode)) ) {
-            if ($fetchMode == DB_FETCHMODE_ASSOC) {
-                $this->addOption($row[$textCol], $row[$valueCol]);
-            } else {
-                $this->addOption($row[0], $row[1]);
-            }
-        }
-        return true;
-    } // end func loadDbResult
-
-    // }}}
-    // {{{ loadQuery()
-
-    /**
-     * Queries a database and loads the options from the results
-     *
-     * @param     mixed     $conn       Either an existing DB connection or a valid dsn
-     * @param     string    $sql        SQL query string
-     * @param     string    $textCol    (optional) Name of column to display as the OPTION text
-     * @param     string    $valueCol   (optional) Name of column to use as the OPTION value
-     * @param     mixed     $values     (optional) Array or comma delimited string of selected values
-     * @since     1.1
-     * @access    public
-     * @return    void
-     * @throws    PEAR_Error
-     */
-    function loadQuery(&$conn, $sql, $textCol=null, $valueCol=null, $values=null)
-    {
-        if (is_string($conn)) {
-            require_once('DB.php');
-            $dbConn = &DB::connect($conn, true);
-            if (DB::isError($dbConn)) {
-                return $dbConn;
-            }
-        } elseif (is_subclass_of($conn, "db_common")) {
-            $dbConn = &$conn;
-        } else {
-            return PEAR::raiseError('Argument 1 of HTML_Select::loadQuery is not a valid type');
-        }
-        $result = $dbConn->query($sql);
-        if (DB::isError($result)) {
-            return $result;
-        }
-        $this->loadDbResult($result, $textCol, $valueCol, $values);
-        $result->free();
-        if (is_string($conn)) {
-            $dbConn->disconnect();
-        }
-        return true;
-    } // end func loadQuery
-
-    // }}}
-    // {{{ load()
-
-    /**
-     * Loads options from different types of data sources
-     *
-     * This method is a simulated overloaded method.  The arguments, other than the
-     * first are optional and only mean something depending on the type of the first argument.
-     * If the first argument is an array then all arguments are passed in order to loadArray.
-     * If the first argument is a db_result then all arguments are passed in order to loadDbResult.
-     * If the first argument is a string or a DB connection then all arguments are
-     * passed in order to loadQuery.
-     * @param     mixed     $options     Options source currently supports assoc array or DB_result
-     * @param     mixed     $param1     (optional) See function detail
-     * @param     mixed     $param2     (optional) See function detail
-     * @param     mixed     $param3     (optional) See function detail
-     * @param     mixed     $param4     (optional) See function detail
-     * @since     1.1
-     * @access    public
-     * @return    PEAR_Error on error or true
-     * @throws    PEAR_Error
-     */
-    function load(&$options, $param1=null, $param2=null, $param3=null, $param4=null)
-    {
-        switch (true) {
-            case is_array($options):
-                return $this->loadArray($options, $param1);
-                break;
-            case (is_a($options, 'db_result')):
-                return $this->loadDbResult($options, $param1, $param2, $param3);
-                break;
-            // Disabled by Chamilo team, 16-MAR-2010.
-            // TODO: To be verified (why it has been disabled).
-            //case (is_string($options) && !empty($options) || is_subclass_of($options, "db_common")):
-            //    return $this->loadQuery($options, $param1, $param2, $param3, $param4);
-            //    break;
-            //
-        }
-    } // end func load
-
-    // }}}
-    // {{{ toHtml()
-
     /**
      * Returns the SELECT in HTML
      *
@@ -520,7 +442,7 @@ class HTML_QuickForm_select extends HTML_QuickForm_element
      * @access    public
      * @return    string
      */
-    function toHtml()
+    public function toHtml()
     {
         if ($this->_flagFrozen) {
             return $this->getFrozenHtml();

+ 36 - 19
main/inc/lib/plugin.class.php

@@ -19,8 +19,8 @@ class Plugin
 {
     protected $version = '';
     protected $author = '';
-    protected $fields = array();
-    private $settings = null;
+    protected $fields = [];
+    private $settings = [];
     // Translation strings.
     private $strings = null;
     public $isCoursePlugin = false;
@@ -70,6 +70,7 @@ class Plugin
     public function get_info()
     {
         $result = array();
+        $result['obj'] = $this;
         $result['title'] = $this->get_title();
         $result['comment'] = $this->get_comment();
         $result['version'] = $this->get_version();
@@ -80,8 +81,10 @@ class Plugin
 
         if ($form = $this->get_settings_form()) {
             $result['settings_form'] = $form;
+
             foreach ($this->fields as $name => $type) {
                 $value = $this->get($name);
+
                 if (is_array($type)) {
                     $value = $type['options'];
                 }
@@ -182,13 +185,12 @@ class Plugin
 
         foreach ($this->fields as $name => $type) {
             $options = null;
-            if (is_array($type) && isset($type['type']) && $type['type'] === "select") {
+            if (is_array($type) && isset($type['type']) && $type['type'] === 'select') {
                 $options = $type['options'];
                 $type = $type['type'];
             }
 
             $value = $this->get($name);
-
             $defaults[$name] = $value;
             $type = isset($type) ? $type : 'text';
 
@@ -266,7 +268,8 @@ class Plugin
     {
         $settings = $this->get_settings();
         foreach ($settings as $setting) {
-            if ($setting['variable'] == ($this->get_name() . '_' . $name)) {
+            if ($setting['variable'] == $this->get_name() . '_' . $name) {
+
                 return $setting['selected_value'];
             }
         }
@@ -280,7 +283,7 @@ class Plugin
      */
     public function get_settings()
     {
-        if (is_null($this->settings)) {
+        if (empty($this->settings)) {
             $settings = api_get_settings_params(
                 array(
                     "subkey = ? AND category = ? AND type = ? " => array($this->get_name(), 'Plugins', 'setting')
@@ -321,7 +324,7 @@ class Plugin
 
             $interfaceLanguageId = api_get_language_id($language_interface);
             $interfaceLanguageInfo = api_get_language_info($interfaceLanguageId);
-            $languageParentId = (!empty($interfaceLanguageInfo['parent_id'])?intval($interfaceLanguageInfo['parent_id']):0);
+            $languageParentId = !empty($interfaceLanguageInfo['parent_id']) ? (int) $interfaceLanguageInfo['parent_id'] : 0;
 
             //1. Loading english if exists
             $english_path = $root.$plugin_name."/lang/english.php";
@@ -333,8 +336,7 @@ class Plugin
             }
 
             $path = $root.$plugin_name."/lang/$language_interface.php";
-
-            //2. Loading the system language
+            // 2. Loading the system language
             if (is_readable($path)) {
                 include $path;
                 if (!empty($strings)) {
@@ -391,9 +393,10 @@ class Plugin
     {
         $plugin_name = $this->get_name();
         $t_course = Database::get_course_table(TABLE_COURSE_SETTING);
-        $courseId = intval($courseId);
+        $courseId = (int) $courseId;
 
         if (empty($courseId)) {
+
             return false;
         }
 
@@ -428,7 +431,8 @@ class Plugin
                             'subkey' => $variable,
                             'value' => $value,
                             'category' => 'plugins',
-                            'type' => $type
+                            'type' => $type,
+                            'title' => ''
                         ];
                         Database::insert($t_course, $params);
                     }
@@ -444,7 +448,8 @@ class Plugin
                             'subkey' => $plugin_name,
                             'value' => $value,
                             'category' => 'plugins',
-                            'type' => $type
+                            'type' => $type,
+                            'title' => ''
                         ];
                         Database::insert($t_course, $params);
                     }
@@ -464,8 +469,6 @@ class Plugin
         $result = Database::query($sql);
         if (!Database::num_rows($result)) {
             $tool_link = "$plugin_name/start.php";
-            //$visibility = AddCourse::string2binary(api_get_setting('course_create_active_tools', $plugin_name));
-
             $cToolId = AddCourse::generateToolId($courseId);
 
             Database::insert(
@@ -479,7 +482,7 @@ class Plugin
                     'visibility' => 1,
                     'admin' => 0,
                     'address' => 'squaregrey.gif',
-                    'added_tool' => 'NO',
+                    'added_tool' => 0,
                     'target' => '_self',
                     'category' => 'plugin',
                     'session_id' => 0
@@ -498,7 +501,9 @@ class Plugin
     public function uninstall_course_fields($courseId)
     {
         $courseId = intval($courseId);
+
         if (empty($courseId)) {
+
             return false;
         }
         $plugin_name = $this->get_name();
@@ -611,11 +616,11 @@ class Plugin
 
         $tabNum = $customTabsNum + 1;
 
-        //Avoid Tab Name Spaces
+        // Avoid Tab Name Spaces
         $tabNameNoSpaces = preg_replace('/\s+/', '', $tabName);
         $subkeytext = "Tabs" . $tabNameNoSpaces;
 
-        //Check if it is already added
+        // Check if it is already added
         $checkCondition = array(
             'where' =>
                 array(
@@ -624,11 +629,14 @@ class Plugin
                     )
                 )
         );
+
         $checkDuplicate = Database::select('*', 'settings_current', $checkCondition);
         if (!empty($checkDuplicate)) {
+
             return false;
         }
-        //End Check
+
+        // End Check
         $subkey = 'custom_tab_' . $tabNum;
         $attributes = array(
             'variable' => 'show_tabs',
@@ -645,7 +653,7 @@ class Plugin
         );
         $resp = Database::insert('settings_current', $attributes);
 
-        //Save the id
+        // Save the id
         $settings = $this->get_settings();
         $setData = array (
             'comment' => $subkey
@@ -757,4 +765,13 @@ class Plugin
     {
         return true;
     }
+
+    /**
+     * @param string $region
+     * @return string
+     */
+    public function renderRegion($region)
+    {
+        return '';
+    }
 }

+ 13 - 12
main/inc/lib/plugin.lib.php

@@ -261,8 +261,9 @@ class AppPlugin
     public function load_region($region, $template, $forced = false)
     {
         if ($region == 'course_tool_plugin') {
-            return null;
+            return '';
         }
+
         ob_start();
         $this->get_all_plugin_contents_by_region($region, $template, $forced);
         $content = ob_get_contents();
@@ -331,9 +332,9 @@ class AppPlugin
     }
 
     /**
-     * @param string    $region
-     * @param Template  $template
-     * @param bool      $forced
+     * @param string $region
+     * @param Template $template
+     * @param bool $forced
      *
      * @return bool
      *
@@ -343,14 +344,13 @@ class AppPlugin
     {
         global $_plugins;
         if (isset($_plugins[$region]) && is_array($_plugins[$region])) {
-        //if (1) {
-            //Load the plugin information
+            // Load the plugin information
             foreach ($_plugins[$region] as $plugin_name) {
 
-                //The plugin_info variable is available inside the plugin index
+                // The plugin_info variable is available inside the plugin index
                 $plugin_info = $this->getPluginInfo($plugin_name, $forced);
 
-                //We also know where the plugin is
+                // We also know where the plugin is
                 $plugin_info['current_region'] = $region;
 
                 // Loading the plugin/XXX/index.php file
@@ -361,10 +361,10 @@ class AppPlugin
                     //Loading the lang variables of the plugin if exists
                     self::load_plugin_lang_variables($plugin_name);
 
-                    //Printing the plugin index.php file
+                    // Printing the plugin index.php file
                     require $plugin_file;
 
-                    //If the variable $_template is set we assign those values to be accesible in Twig
+                    // If the variable $_template is set we assign those values to be accessible in Twig
                     if (isset($_template)) {
                         $_template['plugin_info'] = $plugin_info;
                     } else {
@@ -384,7 +384,6 @@ class AppPlugin
                     if (!empty($template_list)) {
                         foreach ($template_list as $plugin_tpl) {
                             if (!empty($plugin_tpl)) {
-                                //$template_plugin_file = api_get_path(SYS_PLUGIN_PATH)."$plugin_name/$plugin_tpl"; //for smarty
                                 $template_plugin_file = "$plugin_name/$plugin_tpl"; // for twig
                                 $template->display($template_plugin_file, false);
                             }
@@ -418,15 +417,17 @@ class AppPlugin
 
             $plugin_info = array();
             if (file_exists($plugin_file)) {
+
                 require $plugin_file;
             }
 
-            //extra options
+            // Extra options
             $plugin_settings = api_get_settings_params(
                 array(
                     "subkey = ? AND category = ? AND type = ? " => array($plugin_name, 'Plugins','setting')
                 )
             );
+            
             $settings_filtered = array();
             foreach ($plugin_settings as $item) {
                 $settings_filtered[$item['variable']] = $item['selected_value'];

+ 6 - 5
main/inc/lib/social.lib.php

@@ -1697,7 +1697,7 @@ class SocialManager extends UserManager
             $groupId,
             $userId
         );
-        
+
         $profileEditionLink = null;
 
         if ($currentUserId === $userId) {
@@ -1815,7 +1815,7 @@ class SocialManager extends UserManager
      * @param $show_full_profile
      * @return string
      */
-    public static function listMyFriendsBlock($user_id, $link_shared, $show_full_profile)
+    public static function listMyFriendsBlock($user_id, $link_shared = '', $show_full_profile = '')
     {
         //SOCIALGOODFRIEND , USER_RELATION_TYPE_FRIEND, USER_RELATION_TYPE_PARENT
         $friends = SocialManager::get_friends($user_id, USER_RELATION_TYPE_FRIEND);
@@ -1828,8 +1828,9 @@ class SocialManager extends UserManager
             $friendHtml.= '<div class="list-group">';
             $j = 1;
             for ($k=0; $k < $number_friends; $k++) {
-                if ($j > $number_of_images) break;
-
+                if ($j > $number_of_images) {
+                    break;
+                }
                 if (isset($friends[$k])) {
                     $friend = $friends[$k];
                     $name_user = api_get_person_name($friend['firstName'], $friend['lastName']);
@@ -1854,7 +1855,7 @@ class SocialManager extends UserManager
                         $friendHtml .=  $friend_avatar.' <span class="username">' . $name_user . '</span>';
                         $friendHtml .= '<span class="status">' . $statusIcon . '</span>';
                     } else {
-                        $link_shared = (empty($link_shared)) ? '' : '&'.$link_shared;
+                        $link_shared = empty($link_shared) ? '' : '&'.$link_shared;
                         $friendHtml .= '<a href="profile.php?' .'u=' . $friend['friend_user_id'] . $link_shared . '" class="list-group-item">';
                         $friendHtml .=  $friend_avatar.' <span class="username-all">' . $name_user . '</span>';
                     }

+ 31 - 9
main/inc/lib/template.lib.php

@@ -185,8 +185,8 @@ class Template
                 $this->plugin = new AppPlugin();
 
                 //1. Showing installed plugins in regions
-                $plugin_regions = $this->plugin->get_plugin_regions();
-                foreach ($plugin_regions as $region) {
+                $pluginRegions = $this->plugin->get_plugin_regions();
+                foreach ($pluginRegions as $region) {
                     $this->set_plugin_region($region);
                 }
 
@@ -1166,17 +1166,39 @@ class Template
 
     /**
      * Sets the plugin content in a template variable
-     * @param string $plugin_region
+     * @param string $pluginRegion
      * @return null
      */
-    public function set_plugin_region($plugin_region)
+    public function set_plugin_region($pluginRegion)
     {
-        if (!empty($plugin_region)) {
-            $region_content = $this->plugin->load_region($plugin_region, $this, $this->force_plugin_load);
-            if (!empty($region_content)) {
-                $this->assign('plugin_'.$plugin_region, $region_content);
+        if (!empty($pluginRegion)) {
+            $regionContent = $this->plugin->load_region($pluginRegion, $this, $this->force_plugin_load);
+
+            $pluginList = $this->plugin->get_installed_plugins();
+            foreach ($pluginList as $plugin_name) {
+
+                // The plugin_info variable is available inside the plugin index
+                $pluginInfo = $this->plugin->getPluginInfo($plugin_name);
+
+                if (isset($pluginInfo['is_course_plugin']) && $pluginInfo['is_course_plugin']) {
+                    $courseInfo = api_get_course_info();
+
+                    if (!empty($courseInfo)) {
+                        if (isset($pluginInfo['obj']) && $pluginInfo['obj'] instanceof Plugin) {
+                            /** @var Plugin $plugin */
+                            $plugin = $pluginInfo['obj'];
+                            $regionContent .= $plugin->renderRegion($pluginRegion);
+                        }
+                    }
+                } else {
+                    continue;
+                }
+            }
+
+            if (!empty($regionContent)) {
+                $this->assign('plugin_'.$pluginRegion, $regionContent);
             } else {
-                $this->assign('plugin_'.$plugin_region, null);
+                $this->assign('plugin_'.$pluginRegion, null);
             }
         }
         return null;

+ 2 - 2
main/inc/lib/usergroup.lib.php

@@ -2060,10 +2060,10 @@ class UserGroup extends Model
                 break;
         }
         if (!empty($links)) {
-            $list .= '<ul class="nav nav-pills">';
+            $list = '<ul class="nav nav-pills">';
             $list .= $links;
             $list .= '</ul>';
-            $html .= Display::panelCollapse(get_lang('SocialGroups'), $list, 'sm-groups', array(), 'groups-acordeon', 'groups-collapse');    
+            $html .= Display::panelCollapse(get_lang('SocialGroups'), $list, 'sm-groups', array(), 'groups-acordeon', 'groups-collapse');
         }
         return $html;
     }

+ 38 - 26
main/inc/lib/userportal.lib.php

@@ -1205,29 +1205,35 @@ class IndexManager
                             );
                             $session_box = Display::get_session_title_box($session_id);
 
-                            $extra_info = !empty($session_box['coach']) ? $session_box['coach'] : null;
-                            $extra_info .= !empty($session_box['coach'])
-                                ? ' - ' . $session_box['dates']
-                                : $session_box['dates'];
-                            $extra_info .= isset($session_box['duration'])
-                                ? ' ' . $session_box['duration']
-                                : null;
-
-                            $params['extra_fields'] = $session_box['extra_fields'];
-                            $params['course_list_session_style'] = $coursesListSessionStyle;
-
-                            $params['title'] = $session_box['title'];
-                            $params['subtitle'] = $extra_info;
-                            $params['show_actions'] = api_is_platform_admin() ? true : false;
-
-                            if (api_get_setting('hide_courses_in_sessions') == 'false') {
-                                // $params['extra'] .=  $html_courses_session;
+                            $actions = null;
+                            if (api_is_platform_admin()) {
+                                $actions = api_get_path(WEB_CODE_PATH) .'session/resume_session.php?id_session='.$session_id;
                             }
-
-                            $params['description'] = $session_box['description'];
+                            
+                            $coachId = $session_box['id_coach'];
+                            $extraFieldValue = new ExtraFieldValue('session');
+                            $imageField = $extraFieldValue->get_values_by_handler_and_field_variable($session_id, 'image');
+                            
+                            $params['category_id'] = $session_box['category_id'];
+                            $params['title'] = $session_box['title'];
+                            //$params['subtitle'] = $extra_info;
+                            $params['id_coach'] = $coachId;
+                            $params['coach_url'] = api_get_path(WEB_AJAX_PATH) . 'user_manager.ajax.php?a=get_user_popup&user_id=' . $coachId;
+                            $params['coach_name'] = !empty($session_box['coach']) ? $session_box['coach'] : null;
+                            $params['coach_avatar'] =UserManager::getUserPicture($coachId, USER_IMAGE_SIZE_SMALL);
+                            $params['date'] =  $session_box['dates'];
+                            $params['image'] = isset($imageField['value']) ? $imageField['value'] : null;
+                            $params['duration'] = isset($session_box['duration']) ? ' ' . $session_box['duration'] : null;
+                            $params['edit_actions'] = $actions;
                             $params['show_description'] = $session_box['show_description'];
-                            $params['courses'] = $html_courses_session;
+                            $params['description'] = $session_box['description'];   
+                            $params['visibility'] = $session_box['visibility'];
                             $params['show_simple_session_info'] = false;
+                            $params['course_list_session_style'] = $coursesListSessionStyle;                          
+                            $params['num_users'] = $session_box['num_users'];
+                            $params['num_courses'] = $session_box['num_courses'];
+                            $params['courses'] = $html_courses_session;
+                            //$params['extra_fields'] = $session_box['extra_fields'];
 
                             if (
                                 isset($_configuration['show_simple_session_info']) &&
@@ -1241,14 +1247,20 @@ class IndexManager
                                 $params['progress'] = GamificationUtils::getSessionProgress($params['id'], $this->user_id);
                                 $params['points'] = GamificationUtils::getSessionPoints($params['id'], $this->user_id);
                             }
-
-                            $this->tpl->assign('session', $params);
+                            $listSession[] = $params;
+                            $this->tpl->assign('session', $listSession);
+                            $this->tpl->assign('show_tutor', (api_get_setting('show_session_coach')==='true' ? true : false));
                             $this->tpl->assign('gamification_mode', $gamificationModeIsActive);
 
-                            $sessions_with_no_category .= $this->tpl->fetch(
-                                $this->tpl->get_template('/user_portal/session.tpl')
-                            );
-
+                            if (api_get_configuration_value('view_grid_courses')){
+                                $sessions_with_no_category = $this->tpl->fetch(
+                                    $this->tpl->get_template('/user_portal/grid_session.tpl')
+                                );
+                            } else {
+                                $sessions_with_no_category = $this->tpl->fetch(
+                                    $this->tpl->get_template('/user_portal/session.tpl')
+                                );
+                            }
                             $sessionCount++;
                         }
                     }

+ 2 - 2
main/session/session_add.php

@@ -19,8 +19,8 @@ SessionManager::protectSession(null, false);
 
 api_protect_limit_for_session_admin();
 
-$formSent=0;
-$errorMsg='';
+$formSent = 0;
+$errorMsg = '';
 
 // Crop picture plugin for session images
 $htmlHeadXtra[] = '<link  href="'. api_get_path(WEB_PATH) .'web/assets/cropper/dist/cropper.min.css" rel="stylesheet">';

+ 1 - 3
main/social/group_topics.php

@@ -51,9 +51,7 @@ if (isset($_REQUEST['action']) && $_REQUEST['action'] == 'delete') {
 }
 // My friends
 $friend_html = SocialManager::listMyFriendsBlock(
-    $user_id,
-    $link_shared,
-    $show_full_profile
+    $user_id
 );
 $content = null;
 $social_right_content = '';

+ 6 - 6
main/social/group_view.php

@@ -119,7 +119,7 @@ $usergroup = new UserGroup();
 
 if ($group_id != 0) {
     $group_info = $usergroup->get($group_id);
-    
+
 
     $interbreadcrumb[]= array ('url' =>'#','name' => $group_info['name']);
 
@@ -236,14 +236,14 @@ if ($is_group_member || $group_info['visibility'] == GROUP_PERMISSION_OPEN) {
     }
     $members = $usergroup->get_users_by_group($group_id, true);
     $member_content = '';
-    
+
     // My friends
     $friend_html = SocialManager::listMyFriendsBlock(
         $user_id,
-        $link_shared,
-        $show_full_profile
+        '',
+        ''
     );
-    
+
     // Members
     if (count($members) > 0) {
         if ($role == GROUP_USER_PERMISSION_ADMIN) {
@@ -288,7 +288,7 @@ if ($is_group_member || $group_info['visibility'] == GROUP_PERMISSION_OPEN) {
     }
     $headers = array(get_lang('Discussions'), get_lang('Members'));
     $socialForum = Display::tabs($headers, array($content, $member_content),'tabs');
-    
+
 } else {
     // if I already sent an invitation message
     if (!in_array(

+ 4 - 0
main/template/default/auth/session_catalog.tpl

@@ -99,6 +99,10 @@
                         </a>
                     </h4>
                     <div class="toolbar">
+                        <div class="info">
+                            <span><i class="fa fa-book" aria-hidden="true"></i> {{ item.nbr_courses }} {{ 'Courses'|get_lang }}</span>
+                            <span><i class="fa fa-user" aria-hidden="true"></i> {{ item.nbr_users }} {{ 'NbUsers'|get_lang }} </span>
+                        </div>
                         {% if not _u.logged %}
                             &nbsp;
                         {% else %}

+ 91 - 0
main/template/default/user_portal/grid_session.tpl

@@ -0,0 +1,91 @@
+{% for row in session %}
+<div id="session-{{ item.id }}" class="session panel panel-default">
+    <div class="panel-heading">
+        <img id="session_img_{{ row.id }}" src="{{ "window_list.png"|icon(32) }}" width="32" height="32" alt="{{ row.title }}" title="{{ row.title }}" /> {{ row.title }}
+        
+        {% if row.edit_actions != '' %}
+        <div class="pull-right">
+            <a class="btn btn-default btn-sm" href="{{ row.edit_actions }}">
+                <i class="fa fa-pencil" aria-hidden="true"></i>
+            </a>
+        </div>
+        {% endif %}
+    </div>
+    <div class="panel-body">
+        {% if row.description != '' %}
+            {{ row.description }}
+        {% endif %}
+        <div class="info-session">
+            <span><i class="fa fa-user" aria-hidden="true"></i>
+            {{ row.coach_name }}
+            </span>
+            <span><i class="fa fa-calendar" aria-hidden="true"></i>
+            {{ row.date }}
+            </span>
+        </div>
+        <div class="grid-courses">
+            <div class="row">
+            {% for item in row.courses %}
+            <div class="col-md-4 col-sm-4 col-xs-6">
+                <div class="items">
+                    <div class="image">
+                        <img src="{{ item.icon }}" class="img-responsive">
+                        {% if item.category != '' %}
+                        <span class="category">{{ item.category }}</span>
+                        <div class="cribbon"></div>
+                        {% endif %}
+                        <div class="black-shadow">
+                            <div class="author-card">  
+                            {% for teacher in item.teachers %}
+                                {% set counter = counter + 1 %}
+                                {% if counter <= 3 %}
+                                <a href="{{ teacher.url }}" class="ajax" data-title="{{ teacher.firstname }} {{ teacher.lastname }}">
+                                    <img src="{{ teacher.avatar }}"/>
+                                </a>
+                                <div class="teachers-details">
+                                     <h5>
+                                        <a href="{{ teacher.url }}" class="ajax" data-title="{{ teacher.firstname }} {{ teacher.lastname }}">
+                                            {{ teacher.firstname }} {{ teacher.lastname }}
+                                        </a>
+                                     </h5>
+                                </div>       
+                                {% endif %}
+                            {% endfor %}
+                            </div>
+                        </div>
+                        {% if item.edit_actions != '' %}
+                            <div class="admin-actions">
+                                {% if item.document == '' %}
+                                    <a class="btn btn-default btn-sm" href="{{ item.edit_actions }}">
+                                        <i class="fa fa-pencil" aria-hidden="true"></i>
+                                    </a>
+                                {% else %}
+                                    <div class="btn-group" role="group">
+                                        <a class="btn btn-default btn-sm" href="{{ item.edit_actions }}">
+                                            <i class="fa fa-pencil" aria-hidden="true"></i>
+                                        </a>
+                                        {{ item.document }}
+                                    </div> 
+                                {% endif %}
+                            </div>
+                        {% endif %}
+                    </div>
+                    <div class="description">
+                        <h4 class="title">
+                            {% if item.visibility == constant('COURSE_VISIBILITY_CLOSED') %}
+                                {{ item.title }} {{ item.code_course }}
+                            {% else %}
+                                <a href="{{ item.link }}">{{ item.title }} {{ item.code_course }}</a>
+                            {% endif %}
+                        </h4>
+                        <div class="notifications">{{ item.notifications }}</div>
+
+                    </div>
+                </div>
+            </div>
+        {% endfor %}
+        </div>
+        </div>
+    </div>
+</div>
+{% endfor %}

+ 0 - 3
main/template/default/user_portal/index.tpl

@@ -1,3 +0,0 @@
-{% for item in items %}
-    {{ item }}
-{% endfor %}

+ 0 - 5
main/template/default/user_portal/index_grid.tpl

@@ -1,5 +0,0 @@
-{% for item in items %}
-    <div class="well">
-        {{ item }}
-    </div>
-{% endfor %}

+ 58 - 53
main/template/default/user_portal/session.tpl

@@ -1,29 +1,30 @@
+{% for row in session %}
 <div class="panel panel-default">
-    {% if not session.show_simple_session_info %}
-    {% set collapsable = '' %}
+    {% if not row.show_simple_session_info %}
+        {% set collapsable = '' %}
         <div class="panel-heading">
-        {% if session.course_list_session_style == 1 %}
+        {% if row.course_list_session_style == 1 %}
             {# Classic #}
-                <a href="{{ _p.web_main ~ 'session/index.php?session_id=' ~ session.id }}">
-                <img id="session_img_{{ session.id }}" src="{{ "window_list.png"|icon(32) }}" width="32" height="32" alt="{{ session.title }}" title="{{ session.title }}" />
-                    {{ session.title }}
+                <a href="{{ _p.web_main ~ 'session/index.php?session_id=' ~ row.id }}">
+                <img id="session_img_{{ row.id }}" src="{{ "window_list.png"|icon(32) }}" width="32" height="32" alt="{{ row.title }}" title="{{ row.title }}" />
+                    {{ row.title }}
                 </a>
-        {% elseif session.course_list_session_style == 2 %}
+        {% elseif row.course_list_session_style == 2 %}
             {# No link #}
-            <img id="session_img_{{ session.id }}" src="{{ "window_list.png"|icon(32) }}" width="32" height="32" alt="{{ session.title }}" title="{{ session.title }}" />
-                {{ session.title }}
-        {% elseif session.course_list_session_style == 3 %}
+            <img id="session_img_{{ row.id }}" src="{{ "window_list.png"|icon(32) }}" width="32" height="32" alt="{{ row.title }}" title="{{ row.title }}" />
+                {{ row.title }}
+        {% elseif row.course_list_session_style == 3 %}
             {# Foldable #}
-            <a role="button" data-toggle="collapse" data-parent="#page-content" href="#collapse_{{ session.id }}" aria-expanded="false" >
-                <img id="session_img_{{ session.id }}" src="{{ "window_list.png"|icon(32) }}" width="32" height="32" alt="{{ session.title }}" title="{{ session.title }}" />
-                {{ session.title }}
+            <a role="button" data-toggle="collapse" data-parent="#page-content" href="#collapse_{{ row.id }}" aria-expanded="false" >
+                <img id="session_img_{{ row.id }}" src="{{ "window_list.png"|icon(32) }}" width="32" height="32" alt="{{ row.title }}" title="{{ row.title }}" />
+                {{ row.title }}
             </a>
             {% set collapsable = 'collapse' %}
             {% endif %}
 
-            {% if session.show_actions %}
+            {% if row.show_actions %}
                 <div class="pull-right">
-                    <a href="{{ _p.web_main ~ "session/resume_session.php?id_session=" ~ session.id }}">
+                    <a href="{{ _p.web_main ~ "session/resume_session.php?id_session=" ~ row.id }}">
                     <img src="{{ "edit.png"|icon(22) }}" width="22" height="22" alt="{{ "Edit"|get_lang }}" title="{{ "Edit"|get_lang }}" />
                     </a>
                 </div>
@@ -31,35 +32,30 @@
         </div>
     {% endif %}
 
-<div class="sessions panel-body {{ collapsable }}" id="collapse_{{ session.id }}">
-    {% if session.show_simple_session_info %}
+    <div class="session panel-body {{ collapsable }}" id="collapse_{{ row.id }}">
+    {% if row.show_simple_session_info %}
         <div class="row">
             <div class="col-md-7">
-                <h3>
-                    {{ session.title ~ session.notifications }}
-                </h3>
-                {% if session.show_description %}
-                    <div>
-                        {{ session.description }}
-                    </div>
-                {% endif %}
-
-                {% if session.subtitle %}
-                    <small>{{ session.subtitle }}</small>
-                {% endif %}
-
-                {% if session.teachers %}
-                    <h5 class="teacher-name">{{ "teacher.png"|icon(16) ~ session.teachers }}</h5>
+                {% if row.description != '' %}
+                    {{ row.description }}
                 {% endif %}
+                <div class="info-session">
+                    <span><i class="fa fa-user" aria-hidden="true"></i>
+                    {{ row.coach_name }}
+                    </span>
+                    <span><i class="fa fa-calendar" aria-hidden="true"></i>
+                    {{ row.date }}
+                    </span>
+                </div>
 
-                {% if session.coaches %}
-                    <h5 class="teacher-name">{{ "teacher.png"|icon(16) ~ session.coaches }}</h5>
+                {% if row.coaches %}
+                    <h5 class="teacher-name">{{ "teacher.png"|icon(16) ~ row.coaches }}</h5>
                 {% endif %}
             </div>
 
-            {% if session.show_actions %}
+            {% if row.show_actions %}
                 <div class="col-md-5 text-right">
-                    <a href="{{ _p.web_main ~ "session/resume_session.php?id_session=" ~ session.id }}">
+                    <a href="{{ _p.web_main ~ "session/resume_session.php?id_session=" ~ row.id }}">
                         <img src="{{ "edit.png"|icon(22) }}" width="22" height="22" alt="{{ "Edit"|get_lang }}" title="{{ "Edit"|get_lang }}">
                     </a>
                 </div>
@@ -68,39 +64,47 @@
     {% else %}
         <div class="row">
             <div class="col-md-12">
-                {% if session.subtitle %}
-                    <div class="subtitle-session">
-                        <em class="fa fa-clock-o"></em> {{ session.subtitle }}
-                    </div>
-                {% endif %}
-                {% if session.show_description %}
-                    <div class="description-session">
-                        {{ session.description }}
-                    </div>
+                {% if row.description != '' %}
+                    {{ row.description }}
                 {% endif %}
-                <div class="sessions-items">
-                    {% for item in session.courses %}
+                <div class="info-session">
+                    <span><i class="fa fa-user" aria-hidden="true"></i>
+                    {{ row.coach_name }}
+                    </span>
+                    <span><i class="fa fa-calendar" aria-hidden="true"></i>
+                    {{ row.date }}
+                    </span>
+                </div>
+                <div class="sessions-items"> 
+                    {% for item in row.courses %}
+                    <div class="courses">
                         <div class="row">
                             <div class="col-md-2">
                                 {% if item.link %}
-                                    <a href="{{ item.link }}" class="thumbnail">{{ item.icon }}</a>
+                                    <a href="{{ item.link }}" class="thumbnail">
+                                        <img class="img-responsive" src="{{ item.icon }}">
+                                    </a>
                                 {% else %}
-                                    {{ item.icon }}
+                                    {{ 'blackboard.png' | img(48, item.title ) }}
                                 {% endif %}
                             </div>
                             <div class="col-md-10">
-                                {{ item.title }}
-                                {% if item.coaches|length > 0 %}
+                                <h4>{{ item.title }}</h4>
+                                <div class="teachers">
+                                {% if item.teachers|length > 0 %}
                                     <img src="{{ 'teacher.png'|icon(16) }}" width="16" height="16">
-                                    {% for coach in item.coaches %}
+                                    {% for coach in item.teachers %}
                                         {{ loop.index > 1 ? ' | ' }}
                                         <a href="{{ _p.web_ajax ~ 'user_manager.ajax.php?' ~ {'a': 'get_user_popup', 'user_id': coach.user_id}|url_encode() }}" data-title="{{ coach.full_name }}" class="ajax">
-                                            {{ coach.full_name }}
+                                            {{ coach.firstname }},
+                                            {{ coach.lastname }}
                                         </a>
                                     {% endfor %}
                                 {% endif %}
+                                </div>
                             </div>
                         </div>
+                    </div>
                     {% endfor %}
                 </div>
             </div>
@@ -108,3 +112,4 @@
     {% endif %}
     </div>
 </div>
+{% endfor %}

+ 0 - 99
plugin/advanced_subscription/readme.txt

@@ -1,99 +0,0 @@
-<h1>
-<a id="user-content-advanced-subscription-plugin-for-chamilo-lms" class="anchor" href="#advanced-subscription-plugin-for-chamilo-lms" aria-hidden="true"><span class="octicon octicon-link"></span></a>Advanced subscription plugin for Chamilo LMS</h1>
-
-<p>Plugin for managing the registration queue and communication to sessions
-from an external website creating a queue to control session subscription
-and sending emails to approve student subscription request</p>
-
-<h1>
-<a id="user-content-requirements" class="anchor" href="#requirements" aria-hidden="true"><span class="octicon octicon-link"></span></a>Requirements</h1>
-
-<p>Chamilo LMS 1.10 or greater</p>
-
-<h1>
-<a id="user-content-settings" class="anchor" href="#settings" aria-hidden="true"><span class="octicon octicon-link"></span></a>Settings</h1>
-
-<table>
-<thead>
-<tr>
-<th>Parameters</th>
-<th>Description</th>
-</tr>
-</thead>
-<tbody>
-<tr>
-<td>Webservice url</td>
-<td>Url to external website to get user profile (SOAP)</td>
-</tr>
-<tr>
-<td>Induction requirement</td>
-<td>Checkbox to enable induction as requirement</td>
-</tr>
-<tr>
-<td>Courses count limit</td>
-<td>Number of times a student is allowed at most to course by year</td>
-</tr>
-<tr>
-<td>Yearly hours limit</td>
-<td>Teaching hours a student is allowed at most  to course by year</td>
-</tr>
-<tr>
-<td>Yearly cost unit converter</td>
-<td>The cost of a taxation unit value (TUV)</td>
-</tr>
-<tr>
-<td>Yearly cost limit</td>
-<td>Number of TUV student courses is allowed at most to cost by year</td>
-</tr>
-<tr>
-<td>Year start date</td>
-<td>Date (dd/mm) when the year limit is renewed</td>
-</tr>
-<tr>
-<td>Minimum percentage profile</td>
-<td>Minimum percentage required from external website profile</td>
-</tr>
-</tbody>
-</table>
-
-<h1>
-<a id="user-content-hooks" class="anchor" href="#hooks" aria-hidden="true"><span class="octicon octicon-link"></span></a>Hooks</h1>
-
-<p>This plugin use the next hooks:</p>
-
-<ul class="task-list">
-<li>HookAdminBlock</li>
-<li>HookWSRegistration</li>
-<li>HookNotificationContent</li>
-<li>HookNotificationTitle</li>
-</ul>
-
-<h1>
-<a id="user-content-web-services" class="anchor" href="#web-services" aria-hidden="true"><span class="octicon octicon-link"></span></a>Web services</h1>
-
-<ul class="task-list">
-<li>HookAdvancedSubscription..WSSessionListInCategory</li>
-<li>HookAdvancedSubscription..WSSessionGetDetailsByUser</li>
-<li>HookAdvancedSubscription..WSListSessionsDetailsByCategory</li>
-</ul>
-
-<p>See <code>/plugin/advanced_subscription/src/HookAdvancedSubscription.php</code> to check Web services inputs and outputs</p>
-
-<h1>
-<a id="user-content-how-plugin-works" class="anchor" href="#how-plugin-works" aria-hidden="true"><span class="octicon octicon-link"></span></a>How plugin works?</h1>
-
-<p>After install plugin, fill the parameters needed (described above)
-Use Web services to communicate course session inscription from external website
-This allow to student to search course session and subscribe if is qualified
-and allowed to subscribe.
-The normal process is:</p>
-
-<ul class="task-list">
-<li>Student search course session</li>
-<li>Student read session info depending student data</li>
-<li>Student request a subscription</li>
-<li>A confirmation email is send to student</li>
-<li>An email is send to users (superior or admins) who will accept or reject student request</li>
-<li>When the user aceept o reject, an email will be send to student, superior or admins respectively</li>
-<li>To complete the subscription, the request must be validated and accepted by an admin</li>
-</ul>

+ 2 - 2
plugin/buycourses/index.php

@@ -3,5 +3,5 @@
 /**
  * Show form
  */
-require_once('config.php');
-require_once('src/index.buycourses.php');
+require_once 'config.php';
+require_once 'src/index.buycourses.php';

+ 87 - 0
plugin/courseblock/CourseBlockPlugin.php

@@ -0,0 +1,87 @@
+<?php
+/* For licensing terms, see /license.txt */
+
+/**
+ * Class CourseBlockPlugin
+ */
+class CourseBlockPlugin extends Plugin
+{
+    public $isCoursePlugin = true;
+
+    // When creating a new course this settings are added to the course
+    public $course_settings = array(
+        array(
+            'name' => 'course_block_footer_left',
+            'type' => 'textarea'
+        ),
+        array(
+            'name' => 'course_block_footer_center',
+            'type' => 'textarea'
+        ),
+        array(
+            'name' => 'course_block_footer_right',
+            'type' => 'textarea'
+        )
+    );
+
+    /**
+     * @return CourseBlockPlugin
+     */
+    public static function create()
+    {
+        static $result = null;
+        return $result ? $result : $result = new self();
+    }
+
+    /**
+     *
+     */
+    protected function __construct()
+    {
+        parent::__construct(
+            '0.1',
+            'Julio Montoya',
+            array(
+                'tool_enable' => 'boolean'
+            )
+        );
+    }
+
+    ///public function
+
+    public function install()
+    {
+        // Installing course settings
+        $this->install_course_fields_in_all_courses(false);
+    }
+
+    public function uninstall()
+    {
+        // Deleting course settings
+        $this->uninstall_course_fields_in_all_courses();
+    }
+
+        /**
+     * @param string $region
+     * @return string
+     */
+    public function renderRegion($region)
+    {
+        $content = '';
+        switch ($region) {
+            case 'footer_left':
+                $content = api_get_course_setting('course_block_footer_left');
+                $content = $content === -1 ? '' : $content;
+                break;
+            case 'footer_center':
+                $content = api_get_course_setting('course_block_footer_center');
+                $content = $content === -1 ? '' : $content;
+                break;
+            case 'footer_right':
+                $content = api_get_course_setting('course_block_footer_right');
+                $content = $content === -1 ? '' : $content;
+                break;
+        }
+        return $content;
+    }
+}

+ 8 - 0
plugin/courseblock/README.md

@@ -0,0 +1,8 @@
+1. Enabled the plugin from the list of plugins.
+2. Click "Configure" once the plugin was enabled.
+3. Select tool_enable = Yes and save.
+4. Go into a *course* (not course session) and enter the Settings tool.
+5. In the "Course block" section fill the footer options.
+6. Once the form was saved, you will notice that the text you fill in step .5
+   will appear in the Chamilo footer.
+

+ 5 - 0
plugin/courseblock/config.php

@@ -0,0 +1,5 @@
+<?php
+/* For licensing terms, see /license.txt */
+
+require_once __DIR__ . '/../../main/inc/global.inc.php';
+require_once __DIR__.'/CourseBlockPlugin.php';

+ 2 - 0
plugin/courseblock/index.php

@@ -0,0 +1,2 @@
+<?php
+

+ 9 - 0
plugin/courseblock/install.php

@@ -0,0 +1,9 @@
+<?php
+/* For license terms, see /license.txt */
+
+require_once dirname(__FILE__) . '/config.php';
+
+if (!api_is_platform_admin()) {
+    die ('You must have admin permissions to install plugins');
+}
+CourseBlockPlugin::create()->install();

+ 11 - 0
plugin/courseblock/lang/english.php

@@ -0,0 +1,11 @@
+<?php
+
+$strings['plugin_title'] = "Course block";
+$strings['plugin_comment'] = "Add header and footer in a course";
+$strings['tool_enable'] = 'Enable plugin';
+$strings['tool_enable_help'] = 'Once enabled, you will have to configure the plugin inside the course configuration, then from the course homepage (a button will appear there only for the teacher)';
+
+$strings['course_block_footer_left'] = 'Footer left';
+$strings['course_block_footer_center'] = 'Footer center';
+$strings['course_block_footer_right'] = 'Footer right';
+

+ 2 - 0
plugin/courseblock/lang/french.php

@@ -0,0 +1,2 @@
+<?php
+

+ 2 - 0
plugin/courseblock/lang/spanish.php

@@ -0,0 +1,2 @@
+<?php
+

+ 4 - 0
plugin/courseblock/plugin.php

@@ -0,0 +1,4 @@
+<?php
+
+require_once __DIR__ . '/config.php';
+$plugin_info = CourseBlockPlugin::create()->get_info();

+ 2 - 1
plugin/courselegal/readme.txt → plugin/courselegal/README.md

@@ -1,4 +1,5 @@
-README
+Installation
+============
 
 1. Enabled the plugin from the list of plugins.
 2. Click "Configure" once the plugin was enabled.

+ 0 - 1
plugin/courselegal/config.php

@@ -2,5 +2,4 @@
 /* For licensing terms, see /license.txt */
 
 require_once __DIR__ . '/../../main/inc/global.inc.php';
-require_once api_get_path(LIBRARY_PATH).'plugin.class.php';
 require_once __DIR__.'/CourseLegalPlugin.php';

+ 1 - 2
plugin/courselegal/plugin.php

@@ -1,5 +1,4 @@
 <?php
 
-require_once dirname(__FILE__) . '/config.php';
-
+require_once __DIR__ . '/config.php';
 $plugin_info = CourseLegalPlugin::create()->get_info();

+ 0 - 2
plugin/olpc_peru_filter/lib/olpc_peru_filter_plugin.class.php

@@ -15,8 +15,6 @@ class OLPC_Peru_FilterPlugin extends Plugin
 
     //When creating a new course, these settings are added to the course
     public $course_settings = array(
-//                    array('name' => 'big_blue_button_welcome_message',  'type' => 'text'),
-//                    array('name' => 'big_blue_button_record_and_store', 'type' => 'checkbox')
     );
     public $course_settings_callback = true;
     public $error = '';

+ 4 - 0
plugin/openmeetings/readme.txt → plugin/openmeetings/README.md

@@ -4,11 +4,15 @@ settings to configure this tool.
 
 More info on OpenMeetings: http://openmeetings.apache.org/
 More info on Chamilo: http://www.chamilo.org
+
 The tasks related to the development of this plugin:
+
 * https://support.chamilo.org/issues/5491
 * (private system access) https://task.beeznest.com/issues/7046
 * https://issues.apache.org/jira/browse/OPENMEETINGS-802
+
 People involved:
+
 * Financed by the Commission Scolaire des Hautes-Rivières, Québec, Canada (and coordinated/executed by the TICFP team)
 * First draft developed by Francis Gonzales Tello - Independent (at the time)
 * First stable version published by Yannick Warnier - BeezNest/Chamilo team

+ 1 - 1
plugin/openmeetings/config.php

@@ -3,7 +3,7 @@
 
 /* Openmeetings parameters that will be registered in the course settings */
 
-require_once '../../main/inc/global.inc.php';
+require_once __DIR__.'/../../main/inc/global.inc.php';
 
 require_once 'lib/openmeetings.class.php';
 require_once 'lib/openmeetings_plugin.class.php';

+ 1 - 1
plugin/openmeetings/plugin.php

@@ -1,5 +1,5 @@
 <?php
 
-require_once dirname(__FILE__).'/config.php';
+require_once __DIR__.'/config.php';
 $plugin_info = openmeetingsPlugin::create()->get_info();
 

+ 0 - 2
plugin/skype/readme.txt

@@ -1,2 +0,0 @@
-<h1>Skype Plugin</h1>
-<p>Create Skype user field</p>

+ 1 - 0
plugin/ticket/README.md

@@ -0,0 +1 @@
+Ticket management system features for Chamilo.

+ 0 - 12
plugin/ticket/config.install.php

@@ -1,12 +0,0 @@
-<?php
-/* For licensing terms, see /license.txt */
-
-/**
- * Loading of necessary libs
- *
- * @package chamilo.plugin.ticket
- */
-
-require_once '../../main/inc/global.inc.php';
-require_once 'src/ticket.class.php';
-require_once 'src/ticket_plugin.class.php';

+ 0 - 23
plugin/ticket/config.php

@@ -17,29 +17,6 @@ define('TABLE_TICKET_TICKET', 'plugin_ticket_ticket');
 define('TABLE_TICKET_CATEGORY_REL_USER', 'plugin_ticket_category_rel_user');
 define('TABLE_TICKET_MESSAGE_ATTACHMENTS', 'plugin_ticket_message_attachments');
 
-/* Ticket status constants */
-define('NEWTCK', 'NAT'); // New ticket unassigned responsible
-define('PENDING', 'PND'); // User waiting answer
-define('UNCONFIRMED', 'XCF'); // Waiting for user response
-define('CLOSE', 'CLS'); // Close ticket
-define('REENVIADO', 'REE'); // @todo delete option. This is a location of USIL
-
-/* Ticket priority constants */
-define('NORMAL', 'NRM');
-define('HIGH', 'HGH');
-define('LOW', 'LOW');
-
-/* Ticket source constants */
-define('SRC_EMAIL', 'MAI');
-define('SRC_PHONE', 'TEL');
-define('SRC_PRESC', 'PRE');
-define('SRC_PLATFORM', 'PLA');
-
-/* Ticket category constants */
-define('CAT_DOCU', 'DOC');
-define('CAT_FORO', 'FOR');
-define('CAT_ANNU', 'ANN');
-
 require_once __DIR__ . '/../../main/inc/global.inc.php';
 
 require_once api_get_path(SYS_PLUGIN_PATH) . PLUGIN_NAME . '/src/ticket_plugin.class.php';

+ 40 - 36
plugin/ticket/database.php

@@ -11,17 +11,6 @@ $objPlugin = TicketPlugin::create();
 $table = Database::get_main_table(TABLE_TICKET_CATEGORY);
 
 if (!Database::tableExists($table)) {
-    $table = Database::get_main_table(TABLE_TICKET_ASSIGNED_LOG);
-    $sql = "CREATE TABLE IF NOT EXISTS ".$table." (
-            id int UNSIGNED NOT NULL AUTO_INCREMENT,
-            ticket_id int UNSIGNED DEFAULT NULL,
-            user_id int UNSIGNED DEFAULT NULL,
-            assigned_date datetime DEFAULT NULL,
-            sys_insert_user_id int UNSIGNED DEFAULT NULL,
-            PRIMARY KEY PK_ticket_assigned_log (id),
-            KEY FK_ticket_assigned_log (ticket_id))";
-    Database::query($sql);
-
     $sql = "CREATE TABLE IF NOT EXISTS $table (
             id int UNSIGNED NOT NULL AUTO_INCREMENT,
             category_id char(3) NOT NULL,
@@ -37,6 +26,17 @@ if (!Database::tableExists($table)) {
             PRIMARY KEY (id))";
     $result = Database::query($sql);
 
+    $tableLog = Database::get_main_table(TABLE_TICKET_ASSIGNED_LOG);
+    $sql = "CREATE TABLE IF NOT EXISTS $tableLog (
+            id int UNSIGNED NOT NULL AUTO_INCREMENT,
+            ticket_id int UNSIGNED DEFAULT NULL,
+            user_id int UNSIGNED DEFAULT NULL,
+            assigned_date datetime DEFAULT NULL,
+            sys_insert_user_id int UNSIGNED DEFAULT NULL,
+            PRIMARY KEY PK_ticket_assigned_log (id),
+            KEY FK_ticket_assigned_log (ticket_id))";
+    Database::query($sql);
+
     // Default Categories
     $categories = array(
         $objPlugin->get_lang('Enrollment') => $objPlugin->get_lang('TicketsAboutEnrollment'),
@@ -65,7 +65,8 @@ if (!Database::tableExists($table)) {
                 'category_id' => $i,
                 'project_id' => 1,
                 'description' => $description,
-                'name' => $category
+                'name' => $category,
+                'course_required' => 0
             );
         }
 
@@ -75,11 +76,11 @@ if (!Database::tableExists($table)) {
 }
 
 $table = Database::get_main_table(TABLE_TICKET_MESSAGE);
-$sql = "CREATE TABLE IF NOT EXISTS ".$table." (
+$sql = "CREATE TABLE IF NOT EXISTS $table (
         id int UNSIGNED NOT NULL AUTO_INCREMENT,
         message_id int UNSIGNED NOT NULL,
         ticket_id int UNSIGNED NOT NULL,
-        subject varchar(150) DEFAULT NULL,
+        subject varchar(255) DEFAULT NULL,
         message text NOT NULL,
         status char(3) NOT NULL,
         ip_address varchar(16) DEFAULT NULL,
@@ -88,11 +89,11 @@ $sql = "CREATE TABLE IF NOT EXISTS ".$table." (
         sys_lastedit_user_id int UNSIGNED DEFAULT NULL,
         sys_lastedit_datetime datetime DEFAULT NULL,
         PRIMARY KEY (id),
-        KEY FK_tick_message (ticket_id) )";
+        KEY FK_tick_message (ticket_id))";
 Database::query($sql);
 
 $table = Database::get_main_table(TABLE_TICKET_MESSAGE_ATTACHMENTS);
-$sql = "CREATE TABLE IF NOT EXISTS ".$table." (
+$sql = "CREATE TABLE IF NOT EXISTS $table (
         id int UNSIGNED NOT NULL AUTO_INCREMENT,
         message_attch_id char(2) NOT NULL,
         message_id char(2) NOT NULL,
@@ -112,7 +113,7 @@ Database::query($sql);
 $table = Database::get_main_table(TABLE_TICKET_PRIORITY);
 
 if (!Database::tableExists($table)) {
-    $sql = "CREATE TABLE IF NOT EXISTS ".$table." (
+    $sql = "CREATE TABLE IF NOT EXISTS $table (
             id int UNSIGNED NOT NULL AUTO_INCREMENT,
             priority_id char(3) NOT NULL,
             priority varchar(20) DEFAULT NULL,
@@ -126,12 +127,13 @@ if (!Database::tableExists($table)) {
             PRIMARY KEY (id))";
     Database::query($sql);
 
-    //Default Priorities
+    // Default Priorities
     $defaultPriorities = array(
-        'NRM' => $objPlugin->get_lang('PriorityNormal'),
-        'HGH' => $objPlugin->get_lang('PriorityHigh'),
-        'LOW' => $objPlugin->get_lang('PriorityLow')
+        TicketManager::PRIORITY_NORMAL => $objPlugin->get_lang('PriorityNormal'),
+        TicketManager::PRIORITY_HIGH => $objPlugin->get_lang('PriorityHigh'),
+        TicketManager::PRIORITY_LOW => $objPlugin->get_lang('PriorityLow')
     );
+
     $i = 1;
     foreach ($defaultPriorities as $pId => $priority) {
         $attributes = array(
@@ -147,7 +149,7 @@ if (!Database::tableExists($table)) {
 
 $table = Database::get_main_table(TABLE_TICKET_PROJECT);
 if (!Database::tableExists($table)) {
-    $sql = "CREATE TABLE IF NOT EXISTS ".$table." (
+    $sql = "CREATE TABLE IF NOT EXISTS $table (
             id int UNSIGNED NOT NULL AUTO_INCREMENT,
             project_id char(3) NOT NULL,
             name varchar(50) DEFAULT NULL,
@@ -161,7 +163,7 @@ if (!Database::tableExists($table)) {
             PRIMARY KEY (id))";
     Database::query($sql);
 
-    //Default Project Table Ticket
+    // Default Project Table Ticket
     $attributes = array(
         'id' => 1,
         'project_id' => 1,
@@ -170,10 +172,10 @@ if (!Database::tableExists($table)) {
     Database::insert($table, $attributes);
 }
 
-//STATUS
+// STATUS
 $table = Database::get_main_table(TABLE_TICKET_STATUS);
 if (!Database::tableExists($table)) {
-    $sql = "CREATE TABLE IF NOT EXISTS ".$table." (
+    $sql = "CREATE TABLE IF NOT EXISTS $table (
             id int UNSIGNED NOT NULL AUTO_INCREMENT,
             status_id char(3) NOT NULL,
             name varchar(100) NOT NULL,
@@ -181,13 +183,13 @@ if (!Database::tableExists($table)) {
             PRIMARY KEY (id))";
     Database::query($sql);
 
-    //Default status
+    // Default status
     $defaultStatus = array(
-        'NAT' => $objPlugin->get_lang('StatusNew'),
-        'PND' => $objPlugin->get_lang('StatusPending'),
-        'XCF' => $objPlugin->get_lang('StatusUnconfirmed'),
-        'CLS' => $objPlugin->get_lang('StatusClose'),
-        'REE' => $objPlugin->get_lang('StatusForwarded')
+        TicketManager::STATUS_NEW => $objPlugin->get_lang('StatusNew'),
+        TicketManager::STATUS_PENDING => $objPlugin->get_lang('StatusPending'),
+        TicketManager::STATUS_UNCONFIRMED => $objPlugin->get_lang('StatusUnconfirmed'),
+        TicketManager::STATUS_CLOSE => $objPlugin->get_lang('StatusClose'),
+        TicketManager::STATUS_FORWARDED => $objPlugin->get_lang('StatusForwarded')
     );
 
     $i = 1;
@@ -203,19 +205,20 @@ if (!Database::tableExists($table)) {
 }
 
 $table = Database::get_main_table(TABLE_TICKET_TICKET);
-$sql = "CREATE TABLE IF NOT EXISTS ".$table." (
+$sql = "CREATE TABLE IF NOT EXISTS $table (
         ticket_id int UNSIGNED NOT NULL AUTO_INCREMENT,
         ticket_code char(12) DEFAULT NULL,
         project_id char(3) DEFAULT NULL,
         category_id char(3) NOT NULL,
         priority_id char(3) NOT NULL,
         course_id int UNSIGNED NOT NULL,
-        session_id int UNSIGNED NOT NULL DEFAULT '0',
-        request_user int UNSIGNED NOT NULL,
+        session_id int UNSIGNED NOT NULL DEFAULT '0',        
         personal_email varchar(150) DEFAULT NULL,
         assigned_last_user int UNSIGNED NOT NULL DEFAULT '0',
         status_id char(3) NOT NULL,
         total_messages int UNSIGNED NOT NULL DEFAULT '0',
+        subject varchar(255) DEFAULT NULL,
+        message text NOT NULL,
         keyword varchar(250) DEFAULT NULL,
         source char(3) NOT NULL,
         start_date datetime NOT NULL,
@@ -231,13 +234,14 @@ $sql = "CREATE TABLE IF NOT EXISTS ".$table." (
 Database::query($sql);
 
 $table = Database::get_main_table(TABLE_TICKET_CATEGORY_REL_USER);
-$sql = "CREATE TABLE IF NOT EXISTS ".$table." (
+$sql = "CREATE TABLE IF NOT EXISTS $table (
         id int UNSIGNED PRIMARY KEY NOT NULL AUTO_INCREMENT,
         category_id INT NOT NULL,
         user_id INT NOT NULL
 )";
+Database::query($sql);
 
-//Menu main tabs
+// Menu main tabs
 $rsTab = $objPlugin->addTab('Ticket', 'plugin/ticket/src/myticket.php');
 
 if ($rsTab) {

+ 5 - 3
plugin/ticket/lang/english.php

@@ -46,6 +46,7 @@ $strings['Priority'] = "Priority";
 $strings['PriorityHigh'] = "High";
 $strings['PriorityNormal'] = "Normal";
 $strings['PriorityLow'] = "Low";
+$strings['SrcPlatform'] = "Platforme";
 $strings['SrcEmail'] = "E-mail";
 $strings['SrcPhone'] = "Phone";
 $strings['SrcPresential'] = "In-person";
@@ -87,14 +88,15 @@ $strings['RequestConfirmation'] = "Request confirmation";
 $strings['TicketUpdated'] = "Ticket updated";
 $strings['TicketClosed'] = "Ticket closed";
 
-$strings['TicketXCreated'] = "Ticket <b>%s</b>created";
+$strings['TicketXCreated'] = "Ticket <b>%s</b> created";
 $strings['allow_category_edition'] = "Allow category edition";
 $strings['warn_admin_no_user_in_category'] = "Warn admin if category doesn't have users related";
 $strings['send_warning_to_all_admins'] = "Send warning to all admins, if category doesn't have users related";
 $strings['WarningCategoryXDoesntHaveUsers'] = "Warning: The category '%s' doesn't have users assigned";
 $strings['TicketInformation'] = 'Ticket information';
-$strings['CategoryWithNoUserNotificationSentToAdmins'] = 'Category <b>%s</b> with no user sent to all administrators.';
+$strings['CategoryWithNoUserNotificationSentToAdmins'] = 'Category <b>%s</b> has users, Ticket sent to all administrators.';
 $strings['TicketXAssignedToUserX'] = 'Ticket <b>#%s</b> assigned to user <b>%s</b>';
 $strings['TicketXCreatedWithNoCategory'] = 'Ticket <b>#%s</b> created with no category';
 
-
+$strings['UpdatedByX'] = 'Updated by %s';
+$strings['AssignedChangeFromXToY'] = 'Assignee changed from %s to %s';

+ 2 - 0
plugin/ticket/lang/french.php

@@ -85,3 +85,5 @@ $strings['PleaseBeforeRegisterATicketSelectOneUser'] = "Veuillez sélectionner u
 $strings['RequestConfirmation'] = "Demander confirmation";
 $strings['TicketUpdated'] = "Ticket modifié";
 $strings['TicketClosed'] = "Ticket fermé";
+$strings['SrcPlatform'] = "Platforme";
+$strings['UpdatedByX'] = 'Updated by %s';

+ 2 - 0
plugin/ticket/lang/spanish.php

@@ -89,3 +89,5 @@ $strings['PleaseBeforeRegisterATicketSelectOneUser'] = "Por favor, antes de regi
 $strings['RequestConfirmation'] = "Solicitar confirmación";
 $strings['TicketUpdated'] = "Ticket actualizado";
 $strings['TicketClosed'] = "Ticket cerrado";
+$strings['SrcPlatform'] = "Plataforma";
+$strings['UpdatedByX'] = 'Actualizado por %s';

+ 0 - 1
plugin/ticket/readme.txt

@@ -1 +0,0 @@
-This plugin provides the support ticket management system features

+ 1 - 1
plugin/ticket/src/assign_tickets.php

@@ -6,7 +6,7 @@
  * @package chamilo.plugin.ticket
  */
 
-require_once '../config.php';
+require_once __DIR__.'/../config.php';
 $plugin = TicketPlugin::create();
 
 api_protect_course_script();

+ 13 - 7
plugin/ticket/src/categories.php

@@ -9,14 +9,13 @@
 $cidReset = true;
 // needed in order to load the plugin lang variables
 $course_plugin = 'ticket';
-require_once '../config.php';
+require_once __DIR__.'/../config.php';
 
 $plugin = TicketPlugin::create();
 
 api_protect_admin_script(true);
 
-$tool_name = $plugin->get_lang('LastEdit');
-
+$toolName = $plugin->get_lang('Categories');
 
 $libPath = api_get_path(LIBRARY_PATH);
 $webLibPath = api_get_path(WEB_LIBRARY_PATH);
@@ -38,6 +37,8 @@ if ($table->per_page == 0) {
 $formToString = '';
 $id = isset($_GET['id']) ? intval($_GET['id']) : 0;
 
+$interbreadcrumb[] = array('url' => 'myticket.php', 'name' => $plugin->get_lang('MyTickets'));
+
 if (isset($_GET['action'])) {
     global $table;
     $action = $_GET['action'];
@@ -49,6 +50,8 @@ if (isset($_GET['action'])) {
             header("Location: ".api_get_self());
             break;
         case 'add':
+            $toolName = get_lang('Add');
+            $interbreadcrumb[] = array('url' => 'categories.php', 'name' => $plugin->get_lang('Categories'));
             $url = api_get_self().'?action=add';
             $form = TicketManager::getCategoryForm($url);
             $formToString = $form->returnForm();
@@ -60,7 +63,10 @@ if (isset($_GET['action'])) {
                     'description' => $values['description'],
                     'total_tickets' => 0,
                     'sys_insert_user_id' => api_get_user_id(),
-                    'sys_insert_datetime' => api_get_utc_datetime()
+                    'sys_insert_datetime' => api_get_utc_datetime(),
+                    'category_id' => 0,
+                    'project_id' => 0,
+                    'course_required' => ''
                 ];
                 TicketManager::addCategory($params);
 
@@ -71,6 +77,8 @@ if (isset($_GET['action'])) {
             }
             break;
         case 'edit':
+            $toolName = get_lang('Edit');
+            $interbreadcrumb[] = array('url' => 'categories.php', 'name' => $plugin->get_lang('Categories'));
             $url = api_get_self().'?action=edit&id='.$id;
             $form = TicketManager::getCategoryForm($url);
 
@@ -134,9 +142,7 @@ $table->set_header(3, $plugin->get_lang('TotalTickets'), false);
 $table->set_header(4, get_lang('Actions'), true);
 $table->set_column_filter(4, 'modify_filter');
 
-$interbreadcrumb[] = array('url' => 'myticket.php', 'name' => $plugin->get_lang('MyTickets'));
-
-Display::display_header($plugin->get_lang('Categories'));
+Display::display_header($toolName);
 
 $items = [
     [

+ 6 - 3
plugin/ticket/src/categories_add_user.php

@@ -6,17 +6,20 @@
  * @package chamilo.plugin.ticket
  */
 $cidReset = true;
-require_once '../config.php';
+require_once __DIR__.'/../config.php';
 $plugin = TicketPlugin::create();
 
 api_protect_admin_script(true);
 
 $categoryId = isset($_REQUEST['id']) ? intval($_REQUEST['id']) : 0;
-if (empty($categoryId)) {
+$categoryInfo = TicketManager::getCategory($categoryId);
+
+if (empty($categoryInfo)) {
     api_not_allowed(true);
 }
 
 $form = new FormValidator('edit', 'post', api_get_self().'?id='.$categoryId);
+$form->addHeader($categoryInfo['name']);
 $users = UserManager::get_user_list([], ['firstname']);
 $users = array_column($users, 'complete_name', 'user_id');
 
@@ -48,5 +51,5 @@ if ($form->validate()) {
 
 $interbreadcrumb[] = array('url' => 'myticket.php', 'name' => $plugin->get_lang('MyTickets'));
 $interbreadcrumb[] = array('url' => 'categories.php', 'name' => get_lang('Categories'));
-Display::display_header();
+Display::display_header(get_lang('Users'));
 $form->display();

+ 1 - 1
plugin/ticket/src/course_user_list.php

@@ -5,7 +5,7 @@
  * @package chamilo.plugin.ticket
  */
 
-require_once '../config.php';
+require_once __DIR__.'/../config.php';
 $plugin = TicketPlugin::create();
 
 $userId = intval($_GET['user_id']);

+ 1 - 1
plugin/ticket/src/download.php

@@ -5,7 +5,7 @@
  * @package chamilo.plugin.ticket
  */
 
-require_once '../config.php';
+require_once __DIR__.'/../config.php';
 $plugin = TicketPlugin::create();
 
 api_block_anonymous_users();

+ 2 - 2
plugin/ticket/src/index.php

@@ -6,6 +6,6 @@
  * @package chamilo.plugin.ticket
  */
 
-require_once '../config.php';
-header('location:' . api_get_path(WEB_PLUGIN_PATH) . PLUGIN_NAME . '/src/myticket.php?message=success');
+require_once __DIR__.'/../config.php';
+header('Location:' . api_get_path(WEB_PLUGIN_PATH) . PLUGIN_NAME . '/src/myticket.php');
 exit;

+ 120 - 256
plugin/ticket/src/myticket.php

@@ -9,17 +9,17 @@
 $cidReset = true;
 // needed in order to load the plugin lang variables
 $course_plugin = 'ticket';
-require_once '../config.php';
+require_once __DIR__.'/../config.php';
 
-$plugin = TicketPlugin::create();
+api_block_anonymous_users();
 
+$plugin = TicketPlugin::create();
 $tool_name = $plugin->get_lang('LastEdit');
-api_block_anonymous_users();
 
 $libPath = api_get_path(LIBRARY_PATH);
 $webLibPath = api_get_path(WEB_LIBRARY_PATH);
-$htmlHeadXtra[] = '<script type="text/javascript">
-function load_history_ticket (div_course,ticket_id) {
+$htmlHeadXtra[] = '<script>
+function load_history_ticket(div_course, ticket_id) {
     $.ajax({
         contentType: "application/x-www-form-urlencoded",
         beforeSend: function(object) {
@@ -34,21 +34,16 @@ function load_history_ticket (div_course,ticket_id) {
         }
     });
 }
-function clear_course_list (div_course) {
+function clear_course_list(div_course) {
     $("div#"+div_course).html("&nbsp;");
     $("div#"+div_course).hide("");
 }
 
-$(function() {
-    $( "#keyword_start_date_start" ).datepicker({ dateFormat: ' . "'dd/mm/yy'" . ' });
-    $( "#keyword_start_date_end" ).datepicker({ dateFormat: ' . "'dd/mm/yy'" . ' });
-});
-
 $(document).ready(function() {
     $("#advanced_search_form").css("display","none");
 });
 
-function display_advanced_search_form () {
+function display_advanced_search_form() {
     if ($("#advanced_search_form").css("display") == "none") {
         $("#advanced_search_form").css("display","block");
         $("#img_plus_and_minus").html(\'&nbsp;' . Display::return_icon('div_hide.gif', get_lang('Hide'), array('style' => 'vertical-align:middle')) . '&nbsp;' . get_lang('AdvancedSearch') . '\');
@@ -57,70 +52,7 @@ function display_advanced_search_form () {
         $("#img_plus_and_minus").html(\'&nbsp;' . Display::return_icon('div_show.gif', get_lang('Show'), array('style' => 'vertical-align:middle')) . '&nbsp;' . get_lang('AdvancedSearch') . '\');
     }
 }
-</script>
-<style>
-.label2 {
-    float: left;
-    text-align: left;
-    width: 75px;
-}
-
-.label3 {
-    margin-left: 20px;
-    float: left;
-    text-align: left;
-    margin-top: 10px;
-    width: 95px;
-}
-
-.label4 {
-    float: left;
-    text-align: left;
-    margin-top: 10px;
-    width: 75px;
-}
-
-.formw2 {
-    float: left;
-    margin-left: 4px;
-    margin-top: 5px;
-}
-
-.blackboard_show {
-    float: left;
-    position: absolute;
-    border: 1px solid black;
-    width: 350px;
-    background-color: white;
-    z-index: 99;
-    padding: 3px;
-    display: inline;
-}
-
-.blackboard_hide {
-    display: none;
-}
-
-.advanced-parameters {
-    margin-top: 5px;
-}
-
-.remove-margin-top {
-    margin-top: 0px;
-}
-
-.select-margin-top {
-    margin-top: -5px;
-}
-
-.input-width {
-    width: 170px;
-}
-
-.fleft {
-    float: left;
-}
-</style>';
+</script>';
 
 $this_section = 'tickets';
 unset($_SESSION['this_section']);
@@ -138,68 +70,69 @@ if ($table->per_page == 0) {
     $table->per_page = 20;
 }
 
-if (isset($_GET['action'])) {
-    global $table;
-    $action = $_GET['action'];
-    switch ($action) {
-        case 'assign':
-            if ($isAdmin && isset($_GET['ticket_id']))
-                TicketManager::assign_ticket_user($_GET['ticket_id'], $user_id);
-            break;
-        case 'unassign':
-            if ($isAdmin && isset($_GET['ticket_id']))
-                TicketManager::assign_ticket_user($_GET['ticket_id'], 0);
-            break;
-        case 'alert':
-            if (!$isAdmin && isset($_GET['ticket_id']))
-                TicketManager::send_alert($_GET['ticket_id'], $user_id);
-            break;
-        case 'export':
-            $data = array(
-                array(
-                    $plugin->get_lang('TicketNum'),
-                    $plugin->get_lang('Date'),
-                    $plugin->get_lang('DateLastEdition'),
-                    $plugin->get_lang('Category'),
-                    $plugin->get_lang('User'),
-                    $plugin->get_lang('Program'),
-                    $plugin->get_lang('Responsible'),
-                    $plugin->get_lang('Status'),
-                    $plugin->get_lang('Description')
-                )
+$action = isset($_GET['action']) ? $_GET['action'] : '';
+
+switch ($action) {
+    case 'assign':
+        if ($isAdmin && isset($_GET['ticket_id'])) {
+            TicketManager::assign_ticket_user($_GET['ticket_id'], $user_id);
+        }
+        break;
+    case 'unassign':
+        if ($isAdmin && isset($_GET['ticket_id'])) {
+            TicketManager::assign_ticket_user($_GET['ticket_id'], 0);
+        }
+        break;
+    case 'alert':
+        if (!$isAdmin && isset($_GET['ticket_id'])) {
+            TicketManager::send_alert($_GET['ticket_id'], $user_id);
+        }
+        break;
+    case 'export':
+        $data = array(
+            array(
+                $plugin->get_lang('TicketNum'),
+                $plugin->get_lang('Date'),
+                $plugin->get_lang('DateLastEdition'),
+                $plugin->get_lang('Category'),
+                $plugin->get_lang('User'),
+                $plugin->get_lang('Program'),
+                $plugin->get_lang('Responsible'),
+                $plugin->get_lang('Status'),
+                $plugin->get_lang('Description')
+            )
+        );
+        $datos = $table->get_clean_html();
+        foreach ($datos as $ticket) {
+            $ticket[0] = substr(strip_tags($ticket[0]), 0, 12);
+            $ticket_rem = array(
+                utf8_decode(strip_tags($ticket[0])),
+                utf8_decode(api_html_entity_decode($ticket[1])),
+                utf8_decode(strip_tags($ticket[2])),
+                utf8_decode(strip_tags($ticket[3])),
+                utf8_decode(strip_tags($ticket[4])),
+                utf8_decode(strip_tags($ticket[5])),
+                utf8_decode(strip_tags($ticket[6])),
+                utf8_decode(strip_tags($ticket[7])),
+                utf8_decode(strip_tags(str_replace('&nbsp;', ' ', $ticket[9])))
             );
-            $datos = $table->get_clean_html();
-            foreach ($datos as $ticket) {
-                $ticket[0] = substr(strip_tags($ticket[0]), 0, 12);
-                $ticket_rem = array(
-                    utf8_decode(strip_tags($ticket[0])),
-                    utf8_decode(api_html_entity_decode($ticket[1])),
-                    utf8_decode(strip_tags($ticket[2])),
-                    utf8_decode(strip_tags($ticket[3])),
-                    utf8_decode(strip_tags($ticket[4])),
-                    utf8_decode(strip_tags($ticket[5])),
-                    utf8_decode(strip_tags($ticket[6])),
-                    utf8_decode(strip_tags($ticket[7])),
-                    utf8_decode(strip_tags(str_replace('&nbsp;', ' ', $ticket[9])))
-                );
-                $data[] = $ticket_rem;
-            }
-            Export::arrayToXls($data, $plugin->get_lang('Tickets'));
-            exit;
-            break;
-        case 'close_tickets':
-            TicketManager::close_old_tickets();
-            break;
-        default:
-            break;
-    }
+            $data[] = $ticket_rem;
+        }
+        Export::arrayToXls($data, $plugin->get_lang('Tickets'));
+        exit;
+        break;
+    case 'close_tickets':
+        TicketManager::close_old_tickets();
+        break;
+    default:
+        break;
 }
 
-// $nameTools = api_xml_http_response_encode($plugin->get_lang('MyTickets'));
 $user_id = api_get_user_id();
 $isAdmin = api_is_platform_admin();
 
 Display::display_header($plugin->get_lang('MyTickets'));
+
 if ($isAdmin) {
     $getParameters = [
         'keyword',
@@ -236,50 +169,43 @@ if ($isAdmin) {
     if (isset($_GET['submit_simple'])) {
         $get_parameter .= "&submit_simple=";
     }
-    //select categories
-    $select_types = '<select class="chzn-select" name = "keyword_category" id="keyword_category" ">';
-    $select_types .= '<option value="">---' . get_lang('Select') . '---</option>';
+
+    // Select categories
+    $selectTypes = [];
     $types = TicketManager::get_all_tickets_categories();
     foreach ($types as $type) {
-        $select_types.= "<option value = '" . $type['category_id'] . "'>" . $type['name'] . "</option>";
+        $selectTypes[$type['category_id']] = $type['name'];
     }
-    $select_types .= "</select>";
-    //select admins
-    $select_admins = '<select  class ="chzn-select" name = "keyword_admin" id="keyword_admin" ">';
-    $select_admins .= '<option value="">---' . get_lang('Select') . '---</option>';
-    $select_admins .= '<option value = "0">' . $plugin->get_lang('Unassigned') . '</option>';
+
     $admins = UserManager::get_user_list_like(array("status" => "1"), array("username"), true);
+    $selectAdmins = [
+        0 => $plugin->get_lang('Unassigned')
+    ];
     foreach ($admins as $admin) {
-        $select_admins.= "<option value = '" . $admin['user_id'] . "'>" . $admin['lastname'] . " ," . $admin['firstname'] . "</option>";
+        $selectAdmins[$admin['user_id']] = $admin['complete_name'];
     }
-    $select_admins .= "</select>";
-    //select status
-    $select_status = '<select  class ="chzn-select" name = "keyword_status" id="keyword_status" >';
-    $select_status .= '<option value="">---' . get_lang('Select') . '---</option>';
     $status = TicketManager::get_all_tickets_status();
+    $selectStatus = [];
     foreach ($status as $stat) {
-        $select_status.= "<option value = '" . $stat['status_id'] . "'>" . $stat['name'] . "</option>";
+        $selectStatus[$stat['status_id']] = $stat['name'];
     }
-    $select_status .= "</select>";
-    //select priority
-    $select_priority = '<select  name = "keyword_priority" id="keyword_priority" >';
-    $select_priority .= '<option value="">' . get_lang('All') . '</option>';
-    $select_priority .= '<option value="NRM">' . $plugin->get_lang('PriorityNormal') . '</option>';
-    $select_priority .= '<option value="HGH">' . $plugin->get_lang('PriorityHigh') . '</option>';
-    $select_priority .= '<option value="LOW">' . $plugin->get_lang('PriorityLow') . '</option>';
-    $select_priority .= "</select>";
 
-    //select unread
-    $select_unread = '<select  name = "keyword_unread" id="keyword_unread" >';
-    $select_unread .= '<option value="">' . get_lang('All') . '</option>';
-    $select_unread .= '<option value="yes">' . $plugin->get_lang('Unread') . '</option>';
-    $select_unread .= '<option value="no">' . $plugin->get_lang('Read')  . '</option>';
-    $select_unread .= "</select>";
+    $selectPriority = [
+        '' => get_lang('All'),
+        TicketManager::PRIORITY_NORMAL => $plugin->get_lang('PriorityNormal'),
+        TicketManager::PRIORITY_HIGH => $plugin->get_lang('PriorityHigh'),
+        TicketManager::PRIORITY_LOW => $plugin->get_lang('PriorityLow')
+    ];
+
+    $selectStatusUnread = [
+        '' => get_lang('All'),
+        'yes' => $plugin->get_lang('Unread'),
+        'no' => $plugin->get_lang('Read')
+    ];
+
     // Create a search-box
-    $form = new FormValidator('search_simple', 'get', '', '', null, false);
-    $renderer = & $form->defaultRenderer();
-    $renderer->setCustomElementTemplate('<span>{element}</span> ');
-    $form->addElement('text', 'keyword', get_lang('Keyword'), 'size="25"');
+    $form = new FormValidator('search_simple', 'get', '', '', array(), FormValidator::LAYOUT_INLINE);
+    $form->addText('keyword', get_lang('Keyword'), 'size="25"');
     $form->addButtonSearch(get_lang('Search'), 'submit_simple');
     $form->addElement('static', 'search_advanced_link', null,
             '<a href="javascript://" class = "advanced-parameters" onclick="display_advanced_search_form();">'
@@ -291,11 +217,9 @@ if ($isAdmin) {
     if (api_is_platform_admin()) {
         echo '<span class="left">' .
                 '<a href="' . api_get_path(WEB_PLUGIN_PATH) . 'ticket/src/new_ticket.php">' .
-                    Display::return_icon('add.png', $plugin->get_lang('TckNew'), '', '32') . '</a>' .
+                    Display::return_icon('add.png', $plugin->get_lang('TckNew'), '', ICON_SIZE_MEDIUM) . '</a>' .
                 '<a href="' . api_get_self() . '?action=export' . $get_parameter . $get_parameter2 . '">' .
-                    Display::return_icon('export_excel.png', get_lang('Export'), '', '32') . '</a>';
-
-
+                    Display::return_icon('export_excel.png', get_lang('Export'), '', ICON_SIZE_MEDIUM) . '</a>';
         if ($plugin->get('allow_category_edition')) {
             echo Display::url(
                 Display::return_icon('folder_document.gif'),
@@ -303,92 +227,36 @@ if ($isAdmin) {
             );
         }
 
+        echo Display::url(
+            Display::return_icon('settings.png'),
+            api_get_path(WEB_CODE_PATH) . 'admin/configure_plugin.php?name=ticket'
+        );
+
         echo '</span>';
 
     }
     $form->display();
     echo '</div>';
-    echo '<form action="' . api_get_self() . '" method="get" name="advanced_search" id="advanced_search" display:"none">
-            <div id="advanced_search_form" style="display: block;">
-            <div>
-               <div class="form_header">' . get_lang('AdvancedSearch') . '</div>
-            </div>
-            <table >
-               <tbody>
-                  <tr>
-                     <td>
-                        <div>
-                           <div class="label2">' . get_lang('Category') . ': </div>
-                           <div class="formw2" style="margin-top: -5px;">' . $select_types . '</div>
-                        </div>
-                     </td>
-                     <td>
-                        <div>
-                           <div class="label3">' . get_lang('User') . ': </div>
-                           <div class="formw2"><input class="input-width" id="keyword_request_user" name="keyword_request_user" type="text"></div>
-                        </div>
-                     </td>
-                     <td>
-                        <div>
-                           <div class="label3">' . $plugin->get_lang('RegisterDate') . ': </div>
-                           <div class="formw2"><input class="input-width" id="keyword_start_date_start" name="keyword_start_date_start" type="text"></div>
-                        </div>
-                     </td>
-                     <td>
-                        <div>
-                           <div class="label3"><input type="checkbox" name="keyword_dates" value="1">' . $plugin->get_lang('Untill') . '</div>
-                           <div class="formw2"><input class="input-width" id="keyword_start_date_end" name="keyword_start_date_end" type="text"></div>
-                        </div>
-                     </td>
-                  </tr>
-                  <tr >
-                     <td>
-                        <div>
-                           <div class="label2">' . $plugin->get_lang('AssignedTo') . ': </div>
-                           <div class="formw2 select-margin-top">' . $select_admins . '</div>
-                        </div>
-                     </td>
-                     <td>
-                        <div>
-                           <div class="label3 remove-margin-top">' . get_lang('Status') . ':</div>
-                           <div class="formw2 select-margin-top">' . $select_status . '</div>
-                        </div>
-                     </td>
-                     <td>
-                        <div>
-                        <div>
-                           <div class="label3">' . $plugin->get_lang('Priority') . ': </div>
-                           <div class="formw2">' . $select_priority . '</div>
-                        </div>
-                     </td>
-                     <td>
-                        <div>
-                           <div>
-                              <div class="label3">' . get_lang('Status') . ': </div>
-                              <div class="formw2">' . $select_unread . '</div>
-                           </div>
-                     </td>
-                  </tr>
-                  <tr>
-                  <td>
-                  <div >
-                  <div class="label4">' . get_lang('Course') . ': </div>
-                  <div class="formw2">
-                  <input id="keyword_course" style="width: 170px;" name="keyword_course" type="text"></div>
-                  </div>
-                  </td>
-                  <td colspan= "3">
-                  <div>
-                  <button  name="submit_advanced" type="submit">' . get_lang('AdvancedSearch') . '</button>
-                  </div>
-                  </td>
-                  </tr>
-               </tbody>
-            </table>
-            </div>
-            <input name="_qf__advanced_search" type="hidden" value="">
-            <div class="clear">&nbsp;</div>
-         </form>';
+
+    $advancedSearchForm = new FormValidator(
+        'advanced_search',
+        'get',
+        api_get_self(),
+        null,
+        ['style' => 'display:"none"', 'id' => 'advanced_search_form']
+    );
+    $advancedSearchForm->addHeader(get_lang('AdvancedSearch'));
+    $advancedSearchForm->addSelect('keyword_category', get_lang('Category'), $selectTypes, ['placeholder' => get_lang('Select')]);
+    //$advancedSearchForm->addText('keyword_request_user', get_lang('User'), false);
+    $advancedSearchForm->addDateTimePicker('keyword_start_date_start', $plugin->get_lang('RegisterDate'));
+    $advancedSearchForm->addDateTimePicker('keyword_start_date_end', $plugin->get_lang('Untill'));
+    $advancedSearchForm->addSelect('keyword_admin', $plugin->get_lang('AssignedTo') , $selectAdmins, ['placeholder' => get_lang('All')]);
+    $advancedSearchForm->addSelect('keyword_status', get_lang('Status'), $selectStatus, ['placeholder' => get_lang('Select')]);
+    $advancedSearchForm->addSelect('keyword_priority', $plugin->get_lang('Priority'), $selectPriority, ['placeholder' => get_lang('All')]);
+    $advancedSearchForm->addSelect('keyword_unread', get_lang('Status'), $selectStatusUnread, ['placeholder' => get_lang('All')]);
+    $advancedSearchForm->addText('keyword_course', get_lang('Course'), false);
+    $advancedSearchForm->addButtonSearch(get_lang('AdvancedSearch'), 'submit_advanced');
+    $advancedSearchForm->display();
 } else {
     if ($plugin->get('allow_student_add') == 'true') {
         echo '<div class="actions" >';
@@ -397,8 +265,6 @@ if ($isAdmin) {
                     Display::return_icon('add.png', $plugin->get_lang('TckNew'), '', '32') .
                 '</a>' .
               '</span>';
-        echo '<span style="float:right;">' .
-        '</span>';
         echo '</div>';
     }
 }
@@ -408,11 +274,10 @@ if ($isAdmin) {
     $table->set_header(1, $plugin->get_lang('Date'), true);
     $table->set_header(2, $plugin->get_lang('DateLastEdition'), true);
     $table->set_header(3, $plugin->get_lang('Category'), true);
-    $table->set_header(4, $plugin->get_lang('User'), true);
-    $table->set_header(5, $plugin->get_lang('Responsible'), true);
+    $table->set_header(4, $plugin->get_lang('CreatedBy'), true);
+    $table->set_header(5, $plugin->get_lang('AssignedTo'), true);
     $table->set_header(6, $plugin->get_lang('Status'), true);
     $table->set_header(7, $plugin->get_lang('Message'), true);
-    $table->set_header(8, get_lang('Actions'), true);
 } else {
     echo '<center><h1>' . $plugin->get_lang('MyTickets') . '</h1></center>';
     echo '<center><p>' . $plugin->get_lang('MsgWelcome') . '</p></center>';
@@ -424,8 +289,7 @@ if ($isAdmin) {
     $table->set_header(2, $plugin->get_lang('DateLastEdition'), true);
     $table->set_header(3, $plugin->get_lang('Category'));
     $table->set_header(4, $plugin->get_lang('Status'), false);
-    $table->set_header(5, get_lang('Actions'), false);
-}       
+}
 
 $table->display();
 Display::display_footer();

+ 31 - 72
plugin/ticket/src/new_ticket.php

@@ -6,7 +6,7 @@
  */
 
 $cidReset = true;
-require_once '../config.php';
+require_once __DIR__.'/../config.php';
 $plugin = TicketPlugin::create();
 
 if (!api_is_platform_admin() &&
@@ -151,7 +151,7 @@ div.divTicket {
     padding-top: 100px;
 }
 </style>';
-$types = TicketManager::get_all_tickets_categories();
+$types = TicketManager::get_all_tickets_categories('category.name ASC');
 $htmlHeadXtra[] = '<script language="javascript">
     var projects = ' . js_array($types, 'projects', 'project_id') . '
     var course_required = ' . js_array($types, 'course_required', 'course_required') . '
@@ -195,7 +195,7 @@ function show_form_send_ticket()
     // Category List
     $categoryList = array();
     foreach ($types as $type) {
-        $categoryList[$type['category_id']] = $type['name'] . ": " . $type['description'];
+        $categoryList[$type['category_id']] = $type['name'].': '.$type['description'];
     }
 
     // Status List
@@ -205,52 +205,51 @@ function show_form_send_ticket()
         'id' => 'status_id',
         'for' => 'status_id'
     );
-    $statusList[NEWTCK] = $plugin->get_lang('StatusNew');
+
+    $statusList[TicketManager::STATUS_NEW] = $plugin->get_lang('StatusNew');
     if (api_is_platform_admin()) {
         $statusAttributes = array(
             'id' => 'status_id',
             'for' => 'status_id',
             'style' => 'width: 562px;'
         );
-        $statusList[PENDING] = $plugin->get_lang('StatusPending');
-        $statusList[UNCONFIRMED] = $plugin->get_lang('StatusUnconfirmed');
-        $statusList[CLOSE] = $plugin->get_lang('StatusClose');
-        $statusList[REENVIADO] = $plugin->get_lang('StatusForwarded');
+        $statusList[TicketManager::STATUS_PENDING] = $plugin->get_lang('StatusPending');
+        $statusList[TicketManager::STATUS_UNCONFIRMED] = $plugin->get_lang('StatusUnconfirmed');
+        $statusList[TicketManager::STATUS_CLOSE] = $plugin->get_lang('StatusClose');
+        $statusList[TicketManager::STATUS_FORWARDED] = $plugin->get_lang('StatusForwarded');
     }
     //End Status List
 
-    //Source List
+    // Source List
     $sourceList = array();
     $sourceAttributes = array(
         'style' => 'display: none;',
         'id' => 'source_id',
         'for' => 'source_id'
     );
-    $sourceList[SRC_PLATFORM] = $plugin->get_lang('SrcPlatform');
+    $sourceList[TicketManager::SOURCE_PLATFORM] = $plugin->get_lang('SrcPlatform');
     if (api_is_platform_admin()) {
         $sourceAttributes = array(
             'id' => 'source_id',
             'for' => 'source_id',
             'style' => 'width: 562px;'
         );
-        $sourceList[SRC_EMAIL] = $plugin->get_lang('SrcEmail');
-        $sourceList[SRC_PHONE] = $plugin->get_lang('SrcPhone');
-        $sourceList[SRC_PRESC] = $plugin->get_lang('SrcPresential');
+        $sourceList[TicketManager::SOURCE_EMAIL] = $plugin->get_lang('SrcEmail');
+        $sourceList[TicketManager::SOURCE_PHONE] = $plugin->get_lang('SrcPhone');
+        $sourceList[TicketManager::SOURCE_PRESENTIAL] = $plugin->get_lang('SrcPresential');
     }
-    //End Source List
 
-    //Priority List
+    // Priority List
     $priorityList = array();
-    $priorityList[NORMAL] = $plugin->get_lang('PriorityNormal');
-    $priorityList[HIGH] = $plugin->get_lang('PriorityHigh');
-    $priorityList[LOW] = $plugin->get_lang('PriorityLow');
-    //End Priority List
+    $priorityList[TicketManager::PRIORITY_NORMAL] = $plugin->get_lang('PriorityNormal');
+    $priorityList[TicketManager::PRIORITY_HIGH] = $plugin->get_lang('PriorityHigh');
+    $priorityList[TicketManager::PRIORITY_LOW] = $plugin->get_lang('PriorityLow');
 
     $form = new FormValidator(
         'send_ticket',
         'POST',
         api_get_self(),
-        "",
+        '',
         array(
             'enctype' => 'multipart/form-data',
             'onsubmit' => 'return validate()'
@@ -325,7 +324,7 @@ function show_form_send_ticket()
             'Height' => '250'
         )
     );
-    
+
     //if (api_is_platform_admin()) {
         $form->addElement(
             'SelectAjax',
@@ -336,8 +335,6 @@ function show_form_send_ticket()
         );
     //}
 
-    
-
     $form->addElement(
         'text',
         'personal_email',
@@ -347,7 +344,6 @@ function show_form_send_ticket()
         )
     );
 
-
     $form->addLabel('',
         Display::div(
             '',
@@ -393,7 +389,6 @@ function show_form_send_ticket()
         )
     );
 
-
     $form->addElement('file', 'attach_1', get_lang('FilesAttachment'));
     $form->addLabel('', '<span id="filepaths"><div id="filepath_1"></div></span>');
 
@@ -429,7 +424,7 @@ function save_ticket()
     global $plugin;
     $category_id = $_POST['category_id'];
     $content = $_POST['content'];
-    if ($_POST['phone'] != "") {
+    if ($_POST['phone'] != '') {
         $content .= '<p style="color:red">&nbsp;' . get_lang('Phone') . ': ' . Security::remove_XSS($_POST['phone']). '</p>';
     }
     $course_id = isset($_POST['course_id']) ? $_POST['course_id'] : 0;
@@ -443,8 +438,7 @@ function save_ticket()
     $priority = $_POST['priority_id'];
     $status = $_POST['status_id'];
     $file_attachments = $_FILES;
-    $responsible = (api_is_platform_admin() ? api_get_user_id() : 0);
-  
+
     if (TicketManager::insert_new_ticket(
         $category_id,
         $course_id,
@@ -458,11 +452,12 @@ function save_ticket()
         $source,
         $priority,
         $status,
-        $user_id,
-        $responsible
-    )
-    ) {
-        header('location:' . api_get_path(WEB_PLUGIN_PATH) . PLUGIN_NAME . '/src/myticket.php?message=success');
+        $user_id
+    )) {
+        Display::addFlash(
+            Display::return_message($plugin->get_lang('TckSuccessSave'), 'success')
+        );
+        header('Location:' . api_get_path(WEB_PLUGIN_PATH) . PLUGIN_NAME . '/src/myticket.php');
         exit;
     } else {
         Display::display_header(get_lang('ComposeMessage'));
@@ -576,48 +571,12 @@ function get_user_data($from, $number_of_items, $column, $direction)
     return $users;
 }
 
+
+$interbreadcrumb[] = array('url' => 'myticket.php', 'name' => $plugin->get_lang('MyTickets'));
+
 if (!isset($_POST['compose'])) {
     if (api_is_platform_admin()) {
         Display::display_header(get_lang('ComposeMessage'));
-
-        /*
-        $message = $plugin->get_lang('PleaseBeforeRegisterATicketSelectOneUser');
-        Display::display_warning_message($message);
-        echo '
-            <div class="actions">
-              <span style="float: right;">&nbsp;</span>
-              <form id="search_simple" name="search_simple" method="get" action="' . api_get_self() . '" class="form-search">
-                <fieldset>
-                <span><label for="keyword">' . get_lang('SearchAUser') . ': &nbsp;</label><input type="text" name="keyword" size="25"></span>
-                <span><button type="submit" name="submit" class="btn btn">' . get_lang('Search') . '</button></span>
-                <div class="clear"></div>
-                </fieldset>
-              </form>
-            </div>';
-        echo '<div class="users-list">';
-        $order = (api_is_western_name_order() || api_sort_by_first_name()) ? 3 : 2;
-        $table = new SortableTable(
-            'users',
-            'get_number_of_users',
-            'get_user_data',
-            $order,
-            10
-        );
-        $table->set_header(0, '', false, 'width="18px"');
-        $table->set_header(0, get_lang('Photo'), false);
-        $table->set_header(1, get_lang('OfficialCode'));
-        if (api_is_western_name_order()) {
-            $table->set_header(2, get_lang('FirstName'));
-            $table->set_header(3, get_lang('LastName'));
-        } else {
-            $table->set_header(2, get_lang('LastName'));
-            $table->set_header(3, get_lang('FirstName'));
-        }
-        $table->set_header(4, get_lang('LoginName'));
-        $table->set_header(5, get_lang('Email'));
-        $table->set_header(6, get_lang('Action'));
-        $table->display();
-        echo '</div>';*/
     } else {
         $userInfo = api_get_user_info();
         $htmlHeadXtra[] = "

+ 1 - 2
plugin/ticket/src/report.php

@@ -5,9 +5,8 @@
  * @package chamilo.plugin.ticket
  */
 
-$language_file = array('trad4all');
 $cidReset = true;
-require_once '../config.php';
+require_once __DIR__.'/../config.php';
 $plugin = TicketPlugin::create();
 
 api_block_anonymous_users();

+ 0 - 15
plugin/ticket/src/test.html

@@ -1,15 +0,0 @@
-<div class="actions">
-  <span style="float: right;">
-    <a href="/main/admin/user_add.php"><img title="Añadir usuarios" alt="Añadir usuarios" src="/main/img/icons/32/new_user.png"></a>
-  </span>
-  <form id="search_simple" name="search_simple" method="get" action="/main/admin/user_list.php" class="form-search">
-    <fieldset>
-    <span><input type="text" name="keyword" size="25"></span>
-    <span><button type="submit" name="submit" class="btn btn">Buscar</button></span>
-    <span><a onclick="display_advanced_search_form();" class="advanced_parameters" href="javascript://">
-      <span id="img_plus_and_minus">&nbsp;<img title="Mostrar" alt="Mostrar" src="/main/img/div_show.gif" style="vertical-align: middle">&nbsp;Advanced search</span></a>
-    </span>
-    <div class="clear"></div>
-    </fieldset>
-  </form>
-</div>

File diff suppressed because it is too large
+ 367 - 381
plugin/ticket/src/ticket.class.php


+ 1 - 1
plugin/ticket/src/ticket_assign_log.php

@@ -5,7 +5,7 @@
  * @package chamilo.plugin.ticket
  */
 
-require_once '../config.php';
+require_once __DIR__.'/../config.php';
 
 $plugin = TicketPlugin::create();
 

+ 185 - 89
plugin/ticket/src/ticket_details.php

@@ -6,7 +6,7 @@
  * @package chamilo.plugin.ticket
  */
 $cidReset = true;
-require_once '../config.php';
+require_once __DIR__.'/../config.php';
 $plugin = TicketPlugin::create();
 
 api_block_anonymous_users();
@@ -16,15 +16,14 @@ $isAdmin = api_is_platform_admin();
 $interbreadcrumb[] = array('url' => 'myticket.php', 'name' => $plugin->get_lang('MyTickets'));
 $interbreadcrumb[] = array('url' => '#', 'name' => $plugin->get_lang('TicketDetail'));
 
-$disableReponseButtons = "";
-if ($isAdmin) {
+$disableReponseButtons = '';
+/*if ($isAdmin) {
     $disableReponseButtons = "$('#responseyes').attr('disabled', 'disabled');
                               $('#responseno').attr('disabled', 'disabled');";
-}
+}*/
 
-$htmlHeadXtra[] = '
-<script language="javascript">
-$(document).ready(function(){
+$htmlHeadXtra[] = '<script>
+$(document).ready(function() {
 	$("#dialog-form").dialog({
 		autoOpen: false,
 		height: 450,
@@ -44,7 +43,7 @@ $(document).ready(function(){
             $( "#dialog-form" ).dialog( "open" );
         });
 
-        $("input#responseyes").click(function () {
+        $(".responseyes").click(function () {
             if(!confirm("' . $plugin->get_lang('AreYouSure') . ' : ' . strtoupper(get_lang('Yes')) . '. ' . $plugin->get_lang('IfYouAreSureTheTicketWillBeClosed') . '")){
                 return false;
             }
@@ -67,8 +66,7 @@ $(document).ready(function(){
                 return false;
             }
         });
-
-    ' . $disableReponseButtons . '
+        '.$disableReponseButtons.'
 });
 
 function validate() {
@@ -133,8 +131,7 @@ function add_image_form() {
 }
 </script>';
 
-$htmlHeadXtra[] = '
-<style>
+$htmlHeadXtra[] = '<style>
 div.row div.label2 {
 	float:left;
 	text-align: right;
@@ -195,13 +192,13 @@ if (!isset($_GET['ticket_id'])) {
 if (isset($_POST['response'])) {
     if ($user_id == $ticket['ticket']['request_user']) {
         $response = ($_POST['response'] == "1") ? true : ($_POST['response'] == "0" ? false : null);
-        if ($response && $ticket['ticket']['status_id'] == 'XCF') {
+        if ($response && $ticket['ticket']['status_id'] == TicketManager::STATUS_UNCONFIRMED) {
             TicketManager::close_ticket($_GET['ticket_id'], $user_id);
-            $ticket['ticket']['status_id'] = 'CLS';
+            $ticket['ticket']['status_id'] = TicketManager::STATUS_CLOSE;
             $ticket['ticket']['status'] = $plugin->get_lang('Closed');
-        } else if (!is_null($response) && $ticket['ticket']['status_id'] == 'XCF') {
-            TicketManager::update_ticket_status('PND', $_GET['ticket_id'], $user_id);
-            $ticket['ticket']['status_id'] = 'PND';
+        } else if (!is_null($response) && $ticket['ticket']['status_id'] == TicketManager::STATUS_UNCONFIRMED) {
+            TicketManager::update_ticket_status(TicketManager::STATUS_PENDING, $_GET['ticket_id'], $user_id);
+            $ticket['ticket']['status_id'] = TicketManager::STATUS_PENDING;
             $ticket['ticket']['status'] = $plugin->get_lang('StatusPending');
         }
     }
@@ -210,42 +207,46 @@ if (isset($_REQUEST['action'])) {
     $action = $_REQUEST['action'];
     switch ($action) {
         case 'assign':
-            if (api_is_platform_admin() && isset($_GET['ticket_id']))
+            if (api_is_platform_admin() && isset($_GET['ticket_id'])) {
                 TicketManager::assign_ticket_user($_GET['ticket_id'], $_POST['admins']);
-            $ticket['ticket']['assigned_last_user'] = $_POST['admins'];
+            }
+            Display::addFlash(Display::return_message(get_lang('Updated')));
+            header("Location:" . api_get_self() . "?ticket_id=" . $ticket_id);
+            exit;
             break;
         case 'unassign':
-            if (api_is_platform_admin() && isset($_GET['ticket_id']))
+            if (api_is_platform_admin() && isset($_GET['ticket_id'])) {
                 TicketManager::assign_ticket_user($_GET['ticket_id'], 0);
-            $ticket['ticket']['assigned_last_user'] = 0;
+            }
+            Display::addFlash(Display::return_message(get_lang('Updated')));
+            header("Location:" . api_get_self() . "?ticket_id=" . $ticket_id);
+            exit;
             break;
         default:
             break;
     }
 }
 
-$titulo = 'Ticket #' . $ticket['ticket']['ticket_code'];
-$firstMessage = is_array($ticket['messages']) ? $ticket['messages'][0] : '';
-$subTitle = '';
-if (!empty($firstMessage) && isset($firstMessage['subject'])) {
-    $subTitle = $firstMessage['subject'];
-}
+$title = 'Ticket #' . $ticket['ticket']['ticket_code'];
 
 if (!isset($_POST['compose'])) {
     if (isset($_REQUEST['close'])) {
         TicketManager::close_ticket($_REQUEST['ticket_id'], $user_id);
-        $ticket['ticket']['status_id'] = 'CLS';
+        $ticket['ticket']['status_id'] = TicketManager::STATUS_CLOSE;
         $ticket['ticket']['status'] = $plugin->get_lang('Closed');
     }
-    $ticket['ticket']['request_user'] = intval($ticket['ticket']['request_user']);
+    /*$ticket['ticket']['request_user'] = intval($ticket['ticket']['request_user']);
     if ($ticket['ticket']['request_user'] == $user_id || intval($ticket['ticket']['assigned_last_user']) == $user_id) {
         TicketManager::update_message_status($ticket_id, $ticket['ticket']['request_user']);
-    }
+    }*/
     Display::display_header();
-    $form_close_ticket = "";
-    if ($ticket['ticket']['status_id'] != 'REE' && $ticket['ticket']['status_id'] != 'CLS' && $isAdmin) {
+    $form_close_ticket = '';
+        if ($ticket['ticket']['status_id'] != TicketManager::STATUS_FORWARDED &&
+            $ticket['ticket']['status_id'] != TicketManager::STATUS_CLOSE &&
+            $isAdmin
+        ) {
         if (intval($ticket['ticket']['assigned_last_user']) == $user_id) {
-            if ($ticket['ticket']['status_id'] != 'CLS') {
+            if ($ticket['ticket']['status_id'] != TicketManager::STATUS_CLOSE) {
                 $form_close_ticket.= '<a href="' . api_get_self() . '?close=1&ticket_id=' . $ticket['ticket']['ticket_id'] . '" id="close" class="btn btn-danger" >';
                 $form_close_ticket.= get_lang('Close') . '</a>';
             }
@@ -253,19 +254,18 @@ if (!isset($_POST['compose'])) {
     }
 
     $img_assing = '';
-    if ($isAdmin && $ticket['ticket']['status_id'] != 'CLS' && $ticket['ticket']['status_id'] != 'REE') {
-        if ($ticket['ticket']['assigned_last_user'] != 0 && $ticket['ticket']['assigned_last_user'] == $user_id) {
-            $img_assing = '<a class="btn btn-warning" href="' . api_get_self() . '?ticket_id=' . $ticket['ticket']['ticket_id'] . '&amp;action=unassign" id="unassign">
-                           '.get_lang('Unassign').'
-                           </a>';
-        } else {
-            $img_assing = '<a href="#" id="assign" class="btn btn-success">'.get_lang('Assign').'</a>';
-
+    if (empty($ticket['ticket']['assigned_last_user'])) {
+        $img_assing = '<a href="#" id="assign" class="btn btn-success">'.get_lang('Assign').'</a>';
+    } else {
+        if ($isAdmin) {
+            $img_assing = '<a class="btn btn-warning" href="#" id="assign">
+                   '.get_lang('ChangeAssign').'
+                   </a>';
         }
     }
     $bold = '';
 
-    if ($ticket['ticket']['status_id'] == 'CLS') {
+    if ($ticket['ticket']['status_id'] == TicketManager::STATUS_CLOSE) {
         $bold = 'style = "font-weight: bold;"';
         echo "<style>
                 #confirmticket {
@@ -274,17 +274,17 @@ if (!isset($_POST['compose'])) {
               </style>";
     }
     if ($isAdmin) {
-        $senderData = get_lang('AddedBy') . ' ' . $ticket['ticket']['user_url'] . ' (' . $ticket['usuario']['username'] . ').';
+        $senderData = get_lang('AddedBy'). ' '.$ticket['ticket']['user_url'].' (' . $ticket['usuario']['username'] . ').';
     } else {
-        $senderData = get_lang('AddedBy') . ' ' . $ticket['usuario']['complete_name'] . ' (' . $ticket['usuario']['username'] . ').';
+        $senderData = get_lang('AddedBy'). ' '.$ticket['usuario']['complete_name'].' (' . $ticket['usuario']['username']. ').';
     }
 
     echo '
 			<table width="100%" >
 				<tr>
-	              <td colspan="3" style="width:65%">
-	              <h1>' . $titulo . ' '.$form_close_ticket.' '.$img_assing.' </h1>
-	              <h2>'.$subTitle.'</h2>
+	              <td colspan="3">
+	              <h1>'.$title.' '.$form_close_ticket.' '.$img_assing.' </h1>
+	              <h2>'.$ticket['ticket']['subject'].'</h2>
 	              <p>
 	                '.$senderData.' ' .
                     get_lang('Created') . ' '.
@@ -311,6 +311,17 @@ if (!isset($_POST['compose'])) {
 	            <tr>
 	                <td><p><b>' . $plugin->get_lang('Priority') . ': </b>' . $ticket['ticket']['priority'] . '<p></td>
 	            </tr>';
+
+    if (!empty($ticket['ticket']['assigned_last_user'])) {
+        $assignedUser = api_get_user_info($ticket['ticket']['assigned_last_user']);
+        echo '<tr>
+                <td><p><b>' . $plugin->get_lang('AssignedTo') . ': </b>' . $assignedUser['complete_name'] . '<p></td>
+            </tr>';
+    } else {
+        echo '<tr>
+                <td><p><b>' . $plugin->get_lang('AssignedTo') . ': </b>-<p></td>
+            </tr>';
+    }
     if ($ticket['ticket']['course_url'] != null) {
         echo '<tr>
 				<td><p>' . get_lang('Course') . ':</p></td>
@@ -320,17 +331,28 @@ if (!isset($_POST['compose'])) {
 	          </tr>';
     }
     echo '<tr>
-            <td><b>' . get_lang('Description') . ':</b> <br />
-            '.$firstMessage['message'].'</td>
+            <td>
+            <hr />
+            <b>' . get_lang('Description') . ':</b> <br />
+            '.$ticket['ticket']['message'].'
+            <hr />
+            </td>            
          </tr>
         ';
 
-    // select admins
+    // Select admins
     $select_admins = '<select  class ="chzn-select" style="width: 350px; " name = "admins" id="admins" ">';
 
-    $admins = UserManager::get_user_list_like(array("status" => "1"), array("username"), true);
+    $admins = UserManager::get_user_list_like(
+        array('status' => COURSEMANAGER), array('username'),
+        true
+    );
+
+    $select_admins .= '<option value="" >'.get_lang('None').'</option>';
+
     foreach ($admins as $admin) {
-        $select_admins.= "<option value = '" . $admin['user_id'] . "' " . (($user_id == $admin['user_id']) ? ("selected='selected'") : "") . ">" . $admin['lastname'] . ", " . $admin['firstname'] . "</option>";
+        $select_admins.= "<option value = '" . $admin['user_id'] . "' " . (($user_id == $admin['user_id']) ? ("selected='selected'") : '') . ">" .
+           $admin['complete_name'] . "</option>";
     }
     $select_admins .= "</select>";
     echo '<div id="dialog-form" title="' . $plugin->get_lang('AssignTicket') . '" >';
@@ -345,84 +367,158 @@ if (!isset($_POST['compose'])) {
     echo '</table>';
     $messages = $ticket['messages'];
 
-    unset($messages[0]);
+    $logs = TicketManager::get_assign_log($ticket_id);
+    $counter = 1;
     foreach ($messages as $message) {
-        $type = "success";
+        $date = Display::url(
+            date_to_str_ago($message['sys_insert_datetime']),
+            '#',
+            ['title' => api_get_local_time($message['sys_insert_datetime']), 'class' => 'boot-tooltip']
+        );
 
-        if ($message['admin']) {
-            $type = "normal";
-            if ($isAdmin) {
-                $message['message'] .= '<br/><b>' . $plugin->get_lang('AttendedBy') . ': ' . $message['user_created'] . " - " . api_convert_and_format_date(api_get_local_time($message['sys_insert_datetime']), DATE_TIME_FORMAT_LONG, _api_get_timezone()) . "</b>";
-            }
-        }else {
-            $message['message'] .= '<br /><b>' . get_lang('Sent') . ':</b> ' . api_convert_and_format_date(api_get_local_time($message['sys_insert_datetime']), DATE_TIME_FORMAT_LONG, _api_get_timezone());
+        $receivedMessage = '';
+        if (!empty($message['subject'])) {
+            $receivedMessage = '<b>'.get_lang('Subject') . ': </b> '.$message['subject'].'<br/>';
         }
+        $receivedMessage = '<b>'.get_lang('Message') . ':</b><br/>'.$message['message'].'<br/>';
 
-        $receivedMessage = '<b>' . get_lang('Subject') . ': </b> ' . $message['subject'] . '<br/>
-                            <b>' . get_lang('Message') . ':</b><br/>' . $message['message'] . '<br/>';
-        $attachementLinks = "";
-
-        if (isset($message['atachments'])) {
+        $attachmentLinks = '';
+        if (isset($message['attachments'])) {
             $attributeClass = array(
                 'class' => 'attachment-link'
             );
-            foreach ($message['atachments'] as $attach) {
-                $attachementLinks .= Display::tag('div', $attach['attachment_link'], $attributeClass);
+            foreach ($message['attachments'] as $attach) {
+                $attachmentLinks .= Display::tag('div', $attach['attachment_link'], $attributeClass);
             }
         }
 
-        $entireMessage = $receivedMessage . $attachementLinks;
-        echo Display::return_message($entireMessage, $type, false);
+        $entireMessage = $receivedMessage . $attachmentLinks;
+        $counterLink = Display::url('#'.$counter, api_get_self().'?ticket_id='.$ticket_id.'#note-'.$counter);
+        echo '<a id="note-'.$counter.'"> </a><h4>' . sprintf($plugin->get_lang('UpdatedByX'), $message['user_created']).' '.$date.
+            ' <span class="pull-right">'.$counterLink.'</span></h4>';
+        echo Display::div(
+            $entireMessage, ['class' => 'well']
+        );
+        $counter++;
     }
 
-    $subject = get_lang('ReplyShort') .": " . $firstMessage['subject'];
-    $user_admin = api_is_platform_admin();
-    if ($ticket['ticket']['status_id'] != 'REE' AND $ticket['ticket']['status_id'] != 'CLS') {
-        if (!$isAdmin && $ticket['ticket']['status_id'] != 'XCF') {
-            show_form_send_message();
+    $subject = get_lang('ReplyShort') .': '.$ticket['ticket']['subject'];
+
+    if ($ticket['ticket']['status_id'] != TicketManager::STATUS_FORWARDED &&
+        $ticket['ticket']['status_id'] != TicketManager::STATUS_CLOSE
+    ) {
+        if (!$isAdmin && $ticket['ticket']['status_id'] != TicketManager::STATUS_UNCONFIRMED) {
+            show_form_send_message($ticket['ticket']);
         } else {
-            if (intval($ticket['ticket']['assigned_last_user']) == $user_id) {
-                show_form_send_message();
-                $cheked = "";
+            if (
+                $ticket['ticket']['assigned_last_user'] == $user_id ||
+                $ticket['ticket']['sys_insert_user_id'] == $user_id ||
+                $isAdmin
+            ) {
+                show_form_send_message($ticket['ticket']);
             }
         }
     }
 
     Display::display_footer();
-
 } else {
     $ticket_id = $_POST['ticket_id'];
     $content = $_POST['content'];
     $subject = $_POST['subject'];
-    $mensajeconfirmacion = isset($_POST['confirmation']) ? true : false;
+    $message = isset($_POST['confirmation']) ? true : false;
     $file_attachments = $_FILES;
     $user_id = api_get_user_id();
-    TicketManager::insert_message($ticket_id, $subject, $content, $file_attachments, $user_id, 'NOL', $mensajeconfirmacion);
-    header("location:" . api_get_self() . "?ticket_id=" . $ticket_id);
+
+    TicketManager::insert_message(
+        $ticket_id,
+        $subject,
+        $content,
+        $file_attachments,
+        $user_id,
+        'NOL',
+        $message
+    );
+
+    if ($isAdmin) {
+        TicketManager::updateTicket(
+            [
+                'priority_id' => $_POST['priority_id'],
+                'status_id' => $_POST['status_id']
+            ],
+            $ticket_id,
+            api_get_user_id()
+        );
+    }
+    Display::addFlash(Display::return_message(get_lang('Saved')));
+    header("Location:" . api_get_self() . "?ticket_id=" . $ticket_id);
     exit;
 }
 
-function show_form_send_message()
+/**
+ * @param array $ticket
+ */
+function show_form_send_message($ticket)
 {
     global $isAdmin;
-    global $ticket;
     global $subject;
     global $plugin;
 
-    Display::div('', array('span2'));
-
     $form = new FormValidator(
         'send_ticket',
         'POST',
-        api_get_self() . '?ticket_id=' . $ticket['ticket']['ticket_id'],
+        api_get_self() . '?ticket_id=' . $ticket['ticket_id'],
         '',
         array(
             'enctype' => 'multipart/form-data',
             'onsubmit' => 'return validate()',
-            'class' => 'span9 offset1 form-horizontal'
+            'class' => 'form-horizontal'
         )
     );
 
+    if ($isAdmin) {
+        $statusList[TicketManager::STATUS_NEW] = $plugin->get_lang('StatusNew');
+        $statusAttributes = array(
+            'id' => 'status_id',
+            'for' => 'status_id',
+            'style' => 'width: 562px;'
+        );
+        $statusList[TicketManager::STATUS_PENDING] = $plugin->get_lang('StatusPending');
+        $statusList[TicketManager::STATUS_UNCONFIRMED] = $plugin->get_lang('StatusUnconfirmed');
+        $statusList[TicketManager::STATUS_CLOSE] = $plugin->get_lang('StatusClose');
+        $statusList[TicketManager::STATUS_FORWARDED] = $plugin->get_lang('StatusForwarded');
+
+        $form->addElement(
+            'select',
+            'status_id',
+            get_lang('Status'),
+            $statusList,
+            $statusAttributes
+        );
+
+        $priorityList = array();
+        $priorityList[TicketManager::PRIORITY_NORMAL] = $plugin->get_lang('PriorityNormal');
+        $priorityList[TicketManager::PRIORITY_HIGH] = $plugin->get_lang('PriorityHigh');
+        $priorityList[TicketManager::PRIORITY_LOW] = $plugin->get_lang('PriorityLow');
+
+        $form->addElement(
+            'select',
+            'priority_id',
+            $plugin->get_lang('Priority'),
+            $priorityList,
+            array(
+                'id' => 'priority_id',
+                'for' => 'priority_id'
+            )
+        );
+
+        $form->setDefaults(
+            [
+                'priority_id' =>  $ticket['priority_id'],
+                'status_id' =>  $ticket['status_id'],
+            ]
+        );
+    }
+
     $form->addElement(
         'text',
         'subject',
@@ -434,7 +530,7 @@ function show_form_send_message()
         )
     );
 
-    $form->addElement('hidden', 'ticket_id', $_GET['ticket_id']);
+    $form->addElement('hidden', 'ticket_id', $ticket['ticket_id']);
 
     $form->addHtmlEditor(
         'content',

+ 1 - 5
plugin/ticket/src/ticket_plugin.class.php

@@ -34,7 +34,7 @@ class TicketPlugin extends Plugin
         );
 
         parent::__construct(
-            '2.0',
+            '3.0',
             'Kenny Rodas Chavez, Genesis Lopez, Francis Gonzales, Yannick Warnier, Julio Montoya',
             $settings
         );
@@ -55,8 +55,6 @@ class TicketPlugin extends Plugin
     public function uninstall()
     {
         $tblSettings = Database::get_main_table(TABLE_MAIN_SETTINGS_CURRENT);
-        $t_options = Database::get_main_table(TABLE_MAIN_SETTINGS_OPTIONS);
-        $t_tool = Database::get_course_table(TABLE_TOOL_LIST);
         $tblTicketTicket = Database::get_main_table(TABLE_TICKET_TICKET);
         $tblTicketStatus = Database::get_main_table(TABLE_TICKET_STATUS);
         $tblTicketProject = Database::get_main_table(TABLE_TICKET_PROJECT);
@@ -97,6 +95,4 @@ class TicketPlugin extends Plugin
             echo "<script>location.href = '" . $_SERVER['REQUEST_URI'] . "';</script>";
         }
     }
-
-
 }

+ 2 - 2
plugin/ticket/src/tutor.php

@@ -5,10 +5,10 @@
  * @package chamilo.plugin.ticket
  */
 
-require_once '../config.php';
+require_once __DIR__.'/../config.php';
 $plugin = TicketPlugin::create();
 
-require_once 'tutor_report.lib.php';
+require_once __DIR__.'/tutor_report.lib.php';
 
 $htmlHeadXtra[] = '
 	<script type="text/javascript">

+ 3 - 3
plugin/ticket/src/update_report.php

@@ -5,7 +5,7 @@
  * @package chamilo.plugin.ticket
  */
 
-require_once '../config.php';
+require_once __DIR__.'/../config.php';
 $plugin = TicketPlugin::create();
 
 $work_id = intval($_POST['work_id']);
@@ -17,8 +17,8 @@ if (!api_is_allowed_to_edit()) {
     Display::display_error_message($plugin->get_lang("DeniedAccess"));
 } else {
     $sql = "UPDATE " . Database::get_main_table('rp_reporte_semanas') . "
-        SET work_id = '$work_id', forum_id = '$forum_id'
-        WHERE  id ='$rs_id'";
+            SET work_id = '$work_id', forum_id = '$forum_id'
+            WHERE  id ='$rs_id'";
     Database::query($sql);
     Display::display_confirmation_message(get_lang('UpdatedSuccessfully'));
 }

+ 0 - 25
plugin/tour/readme.txt

@@ -1,25 +0,0 @@
-<h1>Chamilo Tour Plugin</h1>
-<p>Shows people how to use your Chamilo LMS</p>
-<h2>Set the blocks for the tour</h2>
-<p>Edit the <code>plugin/tour/config/tour.json</code> file adding the page classes and steps</p>
-<p>To set the steps in a page, add an object like this:</p>
-<pre>
-{
-    "pageClass": "page unique class selector",
-    "steps": [
-        {
-            "elementSelector": "element class or id",
-            "message": "LanguageVariable"
-        },
-        {
-            "elementSelector": "element class or id",
-            "message": "LanguageVariable"
-        },
-    ]
-}
-</pre>
-Then set the language variables inside the <code>plugin/tour/lang/$language.php</code> file<br>
-<h2>Set a region to plugin</h2>
-<p>You must assign a Region to Tour plugin in the Configuration Settings</p>
-<p>Choose preferably <code>header_right</code></p>
-<br>

+ 5 - 5
plugin/vchamilo/README.md

@@ -1,7 +1,7 @@
 Virtual Chamilo
 ===================
 
-Author : Valery Fremaux (valery.fremaux@gmail.com), Julio Montoya
+Authors : Valery Fremaux (valery.fremaux@gmail.com), Julio Montoya
 
 Virtual chamilo is a feature that allows running several chamilo instances sharing the same
 code base.
@@ -20,20 +20,20 @@ You need :
 
 1. Install the vchamilo package into the <chamiloroot>/plugin directory
 2. Install the plugin in chamilo administration
-3. Insert the virtualisation hook into the chamilo master configuration :
+3. Insert the virtualisation hook into the chamilo master configuration file:
 
 ```
-file : <chamiloroot>/app/config/configuration.php
+<chamiloroot>/app/config/configuration.php
 ```
 
-Insert the hook:
+Insert the hook at the end of the file.
 
 ```
 include_once $_configuration['root_sys'].'plugin/vchamilo/lib.php';
 vchamilo_hook_configuration($_configuration);
 ```
 
-What you need for a virtual node is :
+What you need for a virtual node is:
 -------------
 
 - a blank database copy of chamilo

+ 1 - 10
plugin/vchamilo/index.php

@@ -18,15 +18,7 @@ $_template['show_message'] = true;
 $_template['title'] = $plugininstance->get_lang('hostlist');
 
 $tablename = Database::get_main_table('vchamilo');
-$sql = "
-    SELECT 
-        sitename,
-        root_web
-    FROM
-        $tablename
-    WHERE
-        visible = 1
-";
+$sql = "SELECT sitename, root_web FROM $tablename WHERE visible = 1";
 
 if ($virtualChamilo == '%'){
     $result = Database::query($sql);
@@ -36,5 +28,4 @@ if ($virtualChamilo == '%'){
             $_template['hosts'][] = $vchamilo;
         }
     }
-} else {
 }

+ 1 - 1
plugin/vchamilo/lang/english.php

@@ -62,7 +62,7 @@ $strings['sitename'] = 'Site Name';
 $strings['snapshotinstance'] = 'Snapshot';
 $strings['snapshotmaster'] = 'Snapshot master Chamilo';
 $strings['statisticsdatabase'] = 'Statistics database';
-$strings['successfinishedcapture'] = 'Capture of chamilo is finished';
+$strings['successfinishedcapture'] = 'Snapshot of chamilo is finished';
 $strings['sync_settings'] = 'Synchronize settings';
 $strings['tableprefix'] = 'Table prefix';
 $strings['template'] = 'Template';

+ 50 - 30
plugin/vchamilo/lib.php

@@ -20,7 +20,6 @@ function vchamilo_hook_configuration(&$_configuration)
     $virtualChamiloWebRoot = $_configuration['vchamilo_web_root'].'/';
 
     $virtualChamilo = [];
-
     if ($_configuration['root_web'] == $virtualChamiloWebRoot) {
 
         return;
@@ -35,39 +34,41 @@ function vchamilo_hook_configuration(&$_configuration)
     $query = "SELECT * FROM $table WHERE root_web = '$virtualChamiloWebRoot'";
     $result = $connection->executeQuery($query);
 
-    $excludes = array('id', 'name');
-
-    $query = "SELECT * FROM settings_current WHERE subkey = 'vchamilo'";
-    $virtualSettings = $connection->executeQuery($query);
-    $virtualSettings = $virtualSettings->fetchAll();
-
-    $homePath = '';
-    $coursePath = '';
-    $archivePath = '';
-
-    foreach ($virtualSettings as $setting) {
-        switch ($setting['variable']) {
-            case 'vchamilo_home_real_root':
-                $homePath = $setting['selected_value'];
-                break;
-            case 'vchamilo_course_real_root':
-                $coursePath = $setting['selected_value'];
-                break;
-            case 'vchamilo_archive_real_root':
-                $archivePath = $setting['selected_value'];
-                break;
+    if ($result->rowCount()) {
+        $data = $result->fetch();
+
+        $excludes = array('id', 'name');
+
+        $query = "SELECT * FROM settings_current WHERE subkey = 'vchamilo'";
+        $virtualSettings = $connection->executeQuery($query);
+        $virtualSettings = $virtualSettings->fetchAll();
+
+        $homePath = '';
+        $coursePath = '';
+        $archivePath = '';
+
+        foreach ($virtualSettings as $setting) {
+            switch ($setting['variable']) {
+                case 'vchamilo_home_real_root':
+                    $homePath = $setting['selected_value'];
+                    break;
+                case 'vchamilo_course_real_root':
+                    $coursePath = $setting['selected_value'];
+                    break;
+                case 'vchamilo_archive_real_root':
+                    $archivePath = $setting['selected_value'];
+                    break;
+            }
         }
-    }
 
-    if (empty($homePath) || empty($coursePath) || empty($archivePath)) {
-        echo 'Configure correctly the vchamilo plugin';
-        exit;
-    }
+        if (empty($homePath) || empty($coursePath) || empty($archivePath)) {
+            echo 'Configure correctly the vchamilo plugin';
+            exit;
+        }
 
-    if ($result->rowCount()) {
-        $data = $result->fetch();
         // Only load if is visible
-        if ($data['visible']) {
+        if ($data && $data['visible'] === '1') {
+
             foreach ($data as $key => $value) {
                 if (!in_array($key, $excludes)) {
                     $_configuration[$key] = $value;
@@ -80,6 +81,8 @@ function vchamilo_hook_configuration(&$_configuration)
             $data['SYS_COURSE_PATH'] = $coursePath.'/'.$data['slug'];
 
             $virtualChamilo = $data;
+        } else {
+            exit("This portal is disabled. Please contact your administrator");
         }
     } else {
         // Platform was not configured yet
@@ -1133,6 +1136,23 @@ function vchamilo_check_settings()
     if (empty($coursePath) || empty($homePath) || empty($archivePath) || empty($cmdSql)|| empty($cmdMySql)) {
         api_not_allowed(true, 'You have to complete all plugin settings.');
     }
+    $separator = DIRECTORY_SEPARATOR;
+    $templatePath = api_get_path(SYS_PATH).'plugin'.$separator.'vchamilo'.$separator.'templates';
+
+    $paths = [
+        $coursePath,
+        $homePath,
+        $archivePath,
+        $templatePath
+    ];
+
+    foreach ($paths as $path) {
+        if (!is_writable($path)) {
+            Display::addFlash(
+                Display::return_message('Directory must have writable permissions: '.$path, 'warning')
+            );
+        }
+    }
 }
 
 /**

+ 1 - 1
plugin/vchamilo/plugin.php

@@ -59,7 +59,7 @@ $wwwroot = $_configuration['root_web'];
 
 //A simple select
 $options = array(0 => $plugininstance->get_lang('no'), 1 => $plugininstance->get_lang('yes'));
-$form->addlabel('', '<a class="btn btn-primary" href="'.api_get_path(WEB_PLUGIN_PATH).'vchamilo/views/manage.php">'.
+$form->addLabel('', '<a class="btn btn-primary" href="'.api_get_path(WEB_PLUGIN_PATH).'vchamilo/views/manage.php">'.
     $plugininstance->get_lang('manage_instances').'</a>');
 $form->addElement('header', $plugininstance->get_lang('enabling'));
 $form->addElement('select', 'enable_virtualisation', $plugininstance->get_lang('enable_virtualisation'), $options);

+ 2 - 2
plugin/vchamilo/views/editinstance.controller.php

@@ -70,12 +70,12 @@ if ($data->what == 'addinstance' || $data->what == 'registerinstance') {
         ctrace("Creating physical course dir in $coursedir");
         mkdir($coursedir, 0777, true);
         // initiate default index
-        $indexFile = fopen($coursedir.'/index.html', 'w');
+        $indexFile = $coursedir.'/index.html';
         if ($indexFile) {
             file_put_contents($indexFile, vchamilo_get_default_course_index_fragment());
         }
 
-        $htaccessFile = fopen($coursedir.'/.htaccess', 'w');
+        $htaccessFile = $coursedir.'/.htaccess';
         if ($htaccessFile) {
             file_put_contents($htaccessFile, vchamilo_get_htaccess_fragment($slug));
         }

+ 11 - 3
plugin/vchamilo/views/editinstance_form.php

@@ -405,7 +405,7 @@ class InstanceForm extends ChamiloForm
             'onclick="opencnxpopup(\''.$_configuration['root_web'].'\'); return false;"'
         );
 
-        /*
+        /**
          * Template selection.
          */
         if ($this->is_in_add_mode()) {
@@ -414,10 +414,17 @@ class InstanceForm extends ChamiloForm
             $templateoptions = vchamilo_get_available_templates();
 
             // Template choice
-            $form->addElement('select', 'template', $this->_plugin->get_lang('template'), $templateoptions);
+            $form->addSelect(
+                'template',
+                $this->_plugin->get_lang('template'),
+                $templateoptions
+            );
         } else {
             if ($this->instance) {
-                $form->addLabel($this->_plugin->get_lang('template'), $this->instance->template);
+                $form->addLabel(
+                    $this->_plugin->get_lang('template'),
+                    $this->instance['template']
+                );
             }
         }
 
@@ -432,6 +439,7 @@ class InstanceForm extends ChamiloForm
             null,
             'client'
         );
+
         $form->addRule('root_web', $this->_plugin->get_lang('rootwebinputerror'), 'required', null, 'client');
         $form->addRule(
             'main_database',

+ 25 - 16
plugin/vchamilo/views/manage.controller.php

@@ -80,7 +80,7 @@ if ($action == 'fulldeleteinstances') {
                 Display::addFlash(Display::return_message("Deleting $archivedir"));
                 removeDir($archivedir);
             }
-                                    
+
             $sql = "DELETE FROM {$table} WHERE id = ".$instance['id'];
             Database::query($sql);
 
@@ -111,23 +111,28 @@ if ($action == 'snapshotinstance') {
     // Make template directory (files and SQL).
     $separator = DIRECTORY_SEPARATOR;
 
-    $backupDir = $_configuration['root_sys'].'plugin'.$separator.'vchamilo'.$separator.'templates'.$separator.$vhost->slug.$separator;
+    $backupDir = api_get_path(SYS_PATH).'plugin'.$separator.'vchamilo'.$separator.'templates'.$separator.$vhost->slug.$separator;
 
     $absolute_datadir = $backupDir.'data';
     $absolute_sqldir = $backupDir.'dump.sql';
 
     if (!is_dir($backupDir)) {
-        Display::addFlash(
-            Display::return_message('Directory created: '.$backupDir)
-        );
-        mkdir($backupDir, 0777, true);
+        $result = mkdir($backupDir, 0777, true);
+        if ($result) {
+            Display::addFlash(
+                Display::return_message('Directory created: '.$backupDir)
+            );
+        } else {
+            Display::addFlash(
+                Display::return_message("Cannot create directory: $backupDir check the folder permissions", 'error')
+            );
+        }
     }
 
     if ($vchamilostep == 0) {
         // Create directories, if necessary.
         if (!is_dir($absolute_datadir)) {
             mkdir($absolute_datadir, 0777, true);
-            //mkdir($absolute_datadir.'/archive', 0777, true);
             mkdir($absolute_datadir.'/home', 0777, true);
         }
 
@@ -147,7 +152,7 @@ if ($action == 'snapshotinstance') {
             $tpl->assign('content', $content);
             $tpl->display_one_col_template();
 
-            die;
+            exit;
         } else {
             // continue next step
             $vchamilostep = 1;
@@ -218,26 +223,28 @@ if ($action == 'snapshotinstance') {
 
         Display::addFlash(Display::return_message("Copying from '$coursePath' to '$absolute_datadir/courses' "));
         copyDirTo($coursePath, $absolute_datadir.'/courses/', false);
-        /*Display::addFlash(Display::return_message("Copying from $archivePath to {$absolute_datadir}/archive "));
-        copyDirTo($varchivepath, $absolute_datadir.'/archive', false);*/
 
         // Store original hostname and some config info for further database or filestore replacements.
         $FILE = fopen($backupDir.$separator.'manifest.php', 'w');
         fwrite($FILE, '<'.'?php ');
         fwrite($FILE, "\$templatewwwroot = '".$wwwroot."';\n");
-        //fwrite($FILE, "\$templatevdbprefix = '".$vhost->table_prefix."';\n ");
-        //fwrite($FILE, "\$coursefolder = '".$vhost->course_folder."';\n ");
         fwrite($FILE, '?'.'>');
         fclose($FILE);
 
         // Every step was SUCCESS.
         if (empty($fullautomation)) {
-            Display::addFlash(Display::return_message($plugininstance->get_lang('successfinishedcapture'), 'success'));
+            Display::addFlash(
+                Display::return_message($plugininstance->get_lang('successfinishedcapture'),
+                    'success'
+                )
+            );
 
             if (empty($vid)) {
                 $template = vchamilo_get_config('vchamilo', 'default_template');
                 if (empty($template)) {
-                    Display::addFlash(Display::return_message('Set default template as <b>'.$vhost->slug.'</b>', 'success', false));
+                    Display::addFlash(
+                        Display::return_message('Set default template as <b>'.$vhost->slug.'</b>', 'success', false)
+                    );
                     $params = [
                         'subkey' => 'vchamilo',
                         'title' => 'default_template',
@@ -249,7 +256,9 @@ if ($action == 'snapshotinstance') {
                     ];
                     api_set_setting_simple($params);
                 } else {
-                    Display::addFlash(Display::return_message('Default template is: <b>'.$vhost->slug.'</b>', 'success', false));
+                    Display::addFlash(
+                        Display::return_message('Default template is: <b>'.$vhost->slug.'</b>', 'success', false)
+                    );
                 }
             }
 
@@ -264,7 +273,7 @@ if ($action == 'snapshotinstance') {
             $tpl->assign('content', $content);
             $tpl->display_one_col_template();
 
-            die;
+            exit;
         }
     }
 }

+ 1 - 1
plugin/vchamilo/views/manage.php

@@ -94,7 +94,7 @@ foreach ($instances as $instance) {
     $crondate = $instance->lastcron ? date('r', $instance->lastcron) : '';
     $data = array(
         $checkbox,
-        $sitelink.' ('.Display::url($instance->root_web, $instance->root_web).')',
+        $sitelink.' ('.Display::url($instance->root_web, $instance->root_web, array('target' => '_blank')).')',
         $instance->institution,
         $instance->db_host.' - '.$instance->main_database,
         $instance->slug,

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