Browse Source

Merging from 19x

Julio Montoya 10 years ago
parent
commit
51dd3f40fb

+ 8 - 6
main/inc/lib/attendance.lib.php

@@ -35,13 +35,16 @@ class Attendance
 	 * Get the total number of attendance inside current course and current session
 	 * @see SortableTable#get_total_number_of_items()
 	 */
-	static function get_number_of_attendances() {
+	static function get_number_of_attendances($active = -1) {
 		$tbl_attendance = Database :: get_course_table(TABLE_ATTENDANCE);
 		$session_id = api_get_session_id();
 		$condition_session = api_get_session_condition($session_id);
         $course_id = api_get_course_int_id();
 		$sql = "SELECT COUNT(att.id) AS total_number_of_items FROM $tbl_attendance att
-		        WHERE c_id = $course_id AND att.active = 1 $condition_session ";
+		        WHERE c_id = $course_id $condition_session ";
+        if ($active == 1 || $active == 0) {
+            $sql .= "AND att.active = $active";
+        }
 		$res = Database::query($sql);
 		$obj = Database::fetch_object($res);
 		return $obj->total_number_of_items;
@@ -57,14 +60,14 @@ class Attendance
 		// Initializing database table and variables
 		$tbl_attendance = Database :: get_course_table(TABLE_ATTENDANCE);
 		$data = array();
-        //@todo user seters/gettrs
+
 		if (empty($course_id)) {
 			$course_id = api_get_course_int_id();
 		} else {
 		    $course_id = intval($course_id);
 		}
 
-        $session_id = isset($session_id) ? intval($session_id):api_get_session_id();
+        $session_id = isset($session_id)?intval($session_id):api_get_session_id();
         $condition_session = api_get_session_condition($session_id);
 
 		// Get attendance data
@@ -247,7 +250,7 @@ class Attendance
 
 	/**
 	 * Add attendaces sheet inside table. This is the *list of* dates, not
-         * a specific date in itself.
+     * a specific date in itself.
 	 * @param  bool   true for adding link in gradebook or false otherwise (optional)
 	 * @return int    last attendance id
 	 */
@@ -332,7 +335,6 @@ class Attendance
             api_item_property_update($_course, TOOL_ATTENDANCE, $attendance_id,"AttendanceUpdated", $user_id);
 
             // add link to gradebook
-
             if ($link_to_gradebook && !empty($this->category_id)) {
                 $description = '';
                 $link_id = is_resource_in_course_gradebook($course_code, 7, $attendance_id, $session_id);

+ 31 - 16
main/inc/lib/career.lib.php

@@ -1,17 +1,14 @@
 <?php
 /* For licensing terms, see /license.txt */
-/**
-*	This class provides methods for the notebook management.
-*	Include/require it in your code to use its features.
-*	@package chamilo.library
-*/
-/**
- * Code
- */
+
 require_once 'promotion.lib.php';
 
 /**
- * @package chamilo.library
+ * Class Career
+ *
+ *	This class provides methods for the notebook management.
+ *	Include/require it in your code to use its features.
+ *	@package chamilo.library
  */
 class Career extends Model
 {
@@ -34,7 +31,12 @@ class Career extends Model
         return $row['count'];
     }
 
-    public function get_all($where_conditions = array()) {
+    /**
+     * @param array $where_conditions
+     * @return array
+     */
+    public function get_all($where_conditions = array())
+    {
         return Database::select('*',$this->table, array('where'=>$where_conditions,'order' =>'name ASC'));
     }
 
@@ -43,7 +45,8 @@ class Career extends Model
      * @param   int     career id
      * @param   int     status (1 or 0)
     */
-    public function update_all_promotion_status_by_career_id($career_id, $status) {
+    public function update_all_promotion_status_by_career_id($career_id, $status)
+    {
         $promotion = new Promotion();
         $promotion_list = $promotion->get_all_promotions_by_career_id($career_id);
         if (!empty($promotion_list)) {
@@ -61,7 +64,6 @@ class Career extends Model
      */
 	public function display()
     {
-		// action links
 		echo '<div class="actions" style="margin-bottom:20px">';
         echo '<a href="career_dashboard.php">'.Display::return_icon('back.png',get_lang('Back'),'','32').'</a>';
 		echo '<a href="'.api_get_self().'?action=add">'.Display::return_icon('new_career.png',get_lang('Add'),'','32').'</a>';
@@ -69,6 +71,9 @@ class Career extends Model
         echo Display::grid_html('careers');
 	}
 
+    /**
+     * @return array
+     */
     public function get_status_list()
     {
         return array(self::CAREER_STATUS_ACTIVE => get_lang('Unarchived'), self::CAREER_STATUS_INACTIVE => get_lang('Archived'));
@@ -130,7 +135,8 @@ class Career extends Model
      * @param   boolean     Whether or not to copy the promotions inside
      * @return  integer     New career ID on success, false on failure
      */
-    public function copy($id, $copy_promotions = false) {
+    public function copy($id, $copy_promotions = false)
+    {
         $career = $this->get($id);
         $new = array();
         foreach ($career as $key => $val) {
@@ -165,7 +171,12 @@ class Career extends Model
         return $cid;
     }
 
-     public function get_status($career_id) {
+    /**
+     * @param int $career_id
+     * @return bool
+     */
+    public function get_status($career_id)
+    {
         $TBL_CAREER             = Database::get_main_table(TABLE_CAREER);
         $career_id = intval($career_id);
         $sql 	= "SELECT status FROM $TBL_CAREER WHERE id = '$career_id'";
@@ -176,7 +187,6 @@ class Career extends Model
         } else {
             return false;
         }
-
     }
 
 
@@ -188,7 +198,12 @@ class Career extends Model
    		return $id;
     }
 
-    public function delete($id) {
+     /**
+     * @param int $id
+     * @return bool|void
+     */
+    public function delete($id) 
+    {
 	    parent::delete($id);
 	    Event::addEvent(LOG_CAREER_DELETE, LOG_CAREER_ID, $id, api_get_utc_datetime(), api_get_user_id());
     }

+ 5 - 9
main/inc/lib/certificate.lib.php

@@ -1,12 +1,12 @@
 <?php
 /* For licensing terms, see /license.txt */
+
 /**
  * Certificate Class
  * The certificates class is used to generate certificates from inside the
  * gradebook tool.
  * @package chamilo.library.certificates
  */
-
 class Certificate extends Model
 {
     public $table;
@@ -76,7 +76,6 @@ class Certificate extends Model
         }
     }
 
-
     /**
      * Checks if the certificate user path directory is created
      */
@@ -89,7 +88,6 @@ class Certificate extends Model
         $web_path_info = UserManager::get_user_picture_path_by_id($this->user_id, 'web');
 
         if (!empty($path_info) && isset($path_info['dir'])) {
-
             $this->certification_user_path = $path_info['dir'].'certificate/';
             $this->certification_web_user_path = $web_path_info['dir'].'certificate/';
 
@@ -111,7 +109,6 @@ class Certificate extends Model
     public function delete($force_delete = false)
     {
         if (!empty($this->certificate_data)) {
-
             if (!is_null($this->html_file) || $this->html_file != '' || strlen($this->html_file)) {
                 //Deleting HTML file
                 if (is_file($this->html_file)) {
@@ -137,9 +134,8 @@ class Certificate extends Model
     }
 
     /**
-     * Generates an HTML Certificate and fills the path_certificate field in the DB
-     * */
-
+    *  Generates an HTML Certificate and fills the path_certificate field in the DB
+    **/
     public function generate($params = array())
     {
         //The user directory should be set
@@ -368,7 +364,6 @@ class Certificate extends Model
         //Read file or preview file
         if (!empty($this->certificate_data['path_certificate'])) {
             $user_certificate = $this->certification_user_path.basename($this->certificate_data['path_certificate']);
-
             if (file_exists($user_certificate)) {
                 if ($returnContent) {
                     return file_get_contents($user_certificate);
@@ -386,7 +381,8 @@ class Certificate extends Model
         exit;
     }
 
-    static function getCertificatePublicURL($id) {
+    static function getCertificatePublicURL($id)
+    {
         return api_get_path(WEB_PUBLIC_PATH).'certificates/'.$id;
     }
 }

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

@@ -135,7 +135,6 @@ class Chat extends Model
             }
         }
 
-        //print_r($_SESSION['chatHistory']);
         $sql = "UPDATE ".$this->table." SET recd = 1 WHERE to_user = '".$to_user_id."' AND recd = 0";
         Database::query($sql);
 
@@ -144,6 +143,7 @@ class Chat extends Model
         }
         echo json_encode(array('items' => $items));
     }
+
     /*
      * Returns an array of messages inside a chat session with a specific user
      * @param int The ID of the user with whom the current user is chatting
@@ -258,4 +258,4 @@ class Chat extends Model
         }
         return false;
     }
-}
+}

+ 21 - 9
main/inc/lib/course.lib.php

@@ -491,13 +491,14 @@ class CourseManager
      * @param   int     Status (STUDENT, COURSEMANAGER, COURSE_ADMIN, NORMAL_COURSE_MEMBER)
      * @return  bool    True on success, false on failure
      * @see add_user_to_course
+     * @assert ('', '') === false
      */
     public static function subscribe_user($user_id, $course_code, $status = STUDENT, $session_id = 0)
     {
-
         if ($user_id != strval(intval($user_id))) {
             return false; //detected possible SQL injection
         }
+
         $course_code = Database::escape_string($course_code);
         $courseInfo = api_get_course_info($course_code);
         $courseId = $courseInfo['real_id'];
@@ -601,9 +602,9 @@ class CourseManager
     public static function get_course_code_from_original_id($original_course_id_value, $original_course_id_name) {
         $t_cfv = Database::get_main_table(TABLE_MAIN_COURSE_FIELD_VALUES);
         $table_field = Database::get_main_table(TABLE_MAIN_COURSE_FIELD);
-        $sql_course = "SELECT course_code FROM $table_field cf INNER JOIN $t_cfv cfv ON cfv.field_id=cf.id
-                       WHERE field_variable='$original_course_id_name' AND field_value='$original_course_id_value'";
-        $res = Database::query($sql_course);
+        $sql = "SELECT course_code FROM $table_field cf INNER JOIN $t_cfv cfv ON cfv.field_id=cf.id
+                WHERE field_variable='$original_course_id_name' AND field_value='$original_course_id_value'";
+        $res = Database::query($sql);
         $row = Database::fetch_object($res);
         if ($row) {
             return $row->course_code;
@@ -619,7 +620,8 @@ class CourseManager
      * @return string Course code
      * @assert ('') === false
      */
-    public static function get_course_code_from_course_id($id) {
+    public static function get_course_code_from_course_id($id)
+    {
         $table = Database::get_main_table(TABLE_MAIN_COURSE);
         $id = intval($id);
         $sql = "SELECT code FROM $table WHERE id = '$id' ";
@@ -744,10 +746,16 @@ class CourseManager
         return $courses_as_admin;
     }
 
-    public static function get_user_list_from_courses_as_coach($user_id, $include_sessions = true) {
+    /**
+     * @param int $user_id
+     * @param bool $include_sessions
+     * @return array
+     */
+    public static function get_user_list_from_courses_as_coach($user_id, $include_sessions = true)
+    {
         $students_in_courses = array();
-
         $sessions = CourseManager::get_course_list_as_coach($user_id, true);
+
         if (!empty($sessions)) {
             foreach($sessions as $session_id => $courses) {
                 if (!$include_sessions) {
@@ -794,9 +802,12 @@ class CourseManager
     }
 
     /**
-     *    @return an array with the course info of all the courses of whichthe current user is course admin
+     * @param int $user_id
+     * @return an array with the course info of all the courses (real and virtual)
+     * of which the current user is course admin.
      */
-    public static function get_course_list_of_user_as_course_admin($user_id) {
+    public static function get_course_list_of_user_as_course_admin($user_id)
+    {
         if ($user_id != strval(intval($user_id))) {
             return array();
         }
@@ -890,6 +901,7 @@ class CourseManager
                 ' WHERE id='.$session_id.' AND id_coach='.$user_id)) > 0) {
             return true;
         }
+
         return false;
     }
 

+ 12 - 6
main/inc/lib/course_description.lib.php

@@ -26,7 +26,10 @@ class CourseDescription
    	/**
 	 * Constructor
 	 */
-	public function __construct() {}
+	public function __construct()
+    {
+
+    }
 
 	/**
 	 * Returns an array of objects of type CourseDescription corresponding to a specific course, without session ids (session id = 0)
@@ -65,7 +68,8 @@ class CourseDescription
      * first you must set session_id property with the object CourseDescription
      * @return array
      */
-	public function get_description_data() {
+	public function get_description_data()
+    {
 		$tbl_course_description = Database::get_course_table(TABLE_COURSE_DESCRIPTION);
 		$condition_session = api_get_session_condition($this->session_id, true, true);
         $course_id = api_get_course_int_id();
@@ -140,7 +144,6 @@ class CourseDescription
 		return $data;
 	}
 
-
     public function get_data_by_id($id, $course_code = '', $session_id = null) {
 		$tbl_course_description = Database::get_course_table(TABLE_COURSE_DESCRIPTION);
 		$course_id = api_get_course_int_id();
@@ -267,7 +270,8 @@ class CourseDescription
      * Delete a description, first you must set description_type and session_id properties with the object CourseDescription
      * @return int	affected rows
      */
-	public function delete() {
+	public function delete()
+    {
 		$tbl_course_description = Database::get_course_table(TABLE_COURSE_DESCRIPTION);
 		$course_id = api_get_course_int_id();
 		$sql = "DELETE FROM $tbl_course_description WHERE c_id = $course_id AND id = '".intval($this->id)."' AND session_id = '".intval($this->session_id)."'";
@@ -285,7 +289,8 @@ class CourseDescription
 	 * @param int description type
 	 * @return int description id
 	 */
-	public function get_id_by_description_type($description_type) {
+	public function get_id_by_description_type($description_type)
+    {
 		$tbl_course_description = Database::get_course_table(TABLE_COURSE_DESCRIPTION);
         $course_id = api_get_course_int_id();
 
@@ -330,7 +335,8 @@ class CourseDescription
 	 * Get description titles by default
 	 * @return array
 	 */
-	public function get_default_description_title() {
+	public function get_default_description_title()
+    {
 		$default_description_titles = array();
 		$default_description_titles[1]= get_lang('GeneralDescription');
 		$default_description_titles[2]= get_lang('Objectives');

+ 254 - 115
main/inc/lib/plugin.class.php

@@ -2,16 +2,17 @@
 /* For licensing terms, see /license.txt */
 
 /**
+ * Class Plugin
  * Base class for plugins
  *
  * This class has to be extended by every plugin. It defines basic methods
  * to install/uninstall and get information about a plugin
  *
- * @copyright (c) 2012 University of Geneva
- * @license GNU General Public License - http://www.gnu.org/copyleft/gpl.html
- * @author Laurent Opprecht <laurent@opprecht.info>
- * @author Julio Montoya <gugli100@gmail.com> added course settings support + lang variable fixes
- * @author Yannick Warnier <ywarnier@beeznest.org> added documentation
+ * @author    Julio Montoya <gugli100@gmail.com>
+ * @author    Yannick Warnier <ywarnier@beeznest.org>
+ * @author    Laurent Opprecht    <laurent@opprecht.info>
+ * @copyright 2012 University of Geneva
+ * @license   GNU General Public License - http://www.gnu.org/copyleft/gpl.html
  *
  */
 class Plugin
@@ -19,10 +20,10 @@ class Plugin
     protected $version = '';
     protected $author = '';
     protected $fields = array();
-
     private $settings = null;
-    private $strings = null; //translation strings
-    public $is_course_plugin = false;
+    // Translation strings.
+    private $strings = null;
+    public $isCoursePlugin = false;
 
     /**
      * When creating a new course, these settings are added to the course, in
@@ -33,9 +34,9 @@ class Plugin
      * main/img/icons/64/plugin_name_na.png
      * @example
      * $course_settings = array(
-     * array('name' => 'big_blue_button_welcome_message',  'type' => 'text'),
-     * array('name' => 'big_blue_button_record_and_store', 'type' => 'checkbox')
-     * );
+          array('name' => 'big_blue_button_welcome_message',  'type' => 'text'),
+          array('name' => 'big_blue_button_record_and_store', 'type' => 'checkbox')
+       );
      */
     public $course_settings = array();
     /**
@@ -47,9 +48,9 @@ class Plugin
     /**
      * Default constructor for the plugin class. By default, it only sets
      * a few attributes of the object
-     * @param  string  $version Version of this plugin
-     * @param  string  $author Author of this plugin
-     * @param  array   $settings Array of global settings to be proposed to configure the plugin
+     * @param string $version   of this plugin
+     * @param string $author    of this plugin
+     * @param array  $settings  settings to be proposed to configure the plugin
      */
     protected function __construct($version, $author, $settings = array())
     {
@@ -65,16 +66,15 @@ class Plugin
      * Gets an array of information about this plugin (name, version, ...)
      * @return  array Array of information elements about this plugin
      */
-    function get_info()
+    public function get_info()
     {
         $result = array();
-
-        $result['title'] = $this->get_title();
-        $result['comment'] = $this->get_comment();
-        $result['version'] = $this->get_version();
-        $result['author'] = $this->get_author();
-        $result['plugin_class'] = get_class($this);
-        $result['is_course_plugin'] = $this->is_course_plugin;
+        $result['title']            = $this->get_title();
+        $result['comment']          = $this->get_comment();
+        $result['version']          = $this->get_version();
+        $result['author']           = $this->get_author();
+        $result['plugin_class']     = get_class($this);
+        $result['is_course_plugin'] = $this->isCoursePlugin;
 
         if ($form = $this->get_settings_form()) {
             $result['settings_form'] = $form;
@@ -83,77 +83,74 @@ class Plugin
                 $result[$name] = $value;
             }
         }
+
         return $result;
     }
 
     /**
      * Returns the "system" name of the plugin in lowercase letters
-     * @param string Name of the plugin
      * @return string
      */
-    function get_name()
+    public function get_name()
     {
         $result = get_class($this);
         $result = str_replace('Plugin', '', $result);
         $result = strtolower($result);
+
         return $result;
     }
 
     /**
      * Returns the title of the plugin
-     * @param string Title of the plugin
      * @return string
      */
-    function get_title()
+    public function get_title()
     {
         return $this->get_lang('plugin_title');
     }
 
     /**
      * Returns the description of the plugin
-     * @param string Description of the plugin
      * @return string
      */
-    function get_comment()
+    public function get_comment()
     {
         return $this->get_lang('plugin_comment');
     }
 
     /**
      * Returns the version of the plugin
-     * @param string Version of the plugin
      * @return string
      */
-    function get_version()
+    public function get_version()
     {
         return $this->version;
     }
 
     /**
      * Returns the author of the plugin
-     * @param string Author(s) of the plugin
      * @return string
      */
-    function get_author()
+    public function get_author()
     {
         return $this->author;
     }
 
     /**
      * Returns the contents of the CSS defined by the plugin
-     * @param string The CSS string
      * @return array
      */
-    function get_css()
+    public function get_css()
     {
         $name = $this->get_name();
-        $path = api_get_path(SYS_PLUGIN_PATH) . "$name/resources/$name.css";
+        $path = api_get_path(SYS_PLUGIN_PATH)."$name/resources/$name.css";
         if (!is_readable($path)) {
             return '';
         }
         $css = array();
         $css[] = file_get_contents($path);
         $result = implode($css);
+
         return $result;
     }
 
@@ -161,7 +158,7 @@ class Plugin
      * Returns an HTML form (generated by FormValidator) of the plugin settings
      * @return string FormValidator-generated form
      */
-    function get_settings_form()
+    public function get_settings_form()
     {
         $result = new FormValidator($this->get_name());
 
@@ -173,8 +170,8 @@ class Plugin
             $type = isset($type) ? $type : 'text';
 
             $help = null;
-            if ($this->get_lang_plugin_exists($name . '_help')) {
-                $help = $this->get_lang($name . '_help');
+            if ($this->get_lang_plugin_exists($name.'_help')) {
+                $help = $this->get_lang($name.'_help');
             }
 
             switch ($type) {
@@ -185,51 +182,29 @@ class Plugin
                     $result->add_html_editor($name, $this->get_lang($name));
                     break;
                 case 'text':
-                    $result->addElement(
-                        $type,
-                        $name,
-                        array($this->get_lang($name), $help)
-                    );
+                    $result->addElement($type, $name, array($this->get_lang($name), $help));
                     break;
                 case 'boolean':
                     $group = array();
-                    $group[] = $result->createElement(
-                        'radio',
-                        $name,
-                        '',
-                        get_lang('Yes'),
-                        'true'
-                    );
-                    $group[] = $result->createElement(
-                        'radio',
-                        $name,
-                        '',
-                        get_lang('No'),
-                        'false'
-                    );
-                    $result->addGroup(
-                        $group,
-                        null,
-                        array($this->get_lang($name), $help)
-                    );
+                    $group[] = $result->createElement('radio', $name, '', get_lang('Yes'), 'true');
+                    $group[] = $result->createElement('radio', $name, '', get_lang('No'), 'false');
+                    $result->addGroup($group, null, array($this->get_lang($name), $help));
                     break;
             }
         }
         $result->setDefaults($defaults);
-        $result->addElement(
-            'style_submit_button',
-            'submit_button',
-            $this->get_lang('Save')
-        );
+        $result->addElement('style_submit_button', 'submit_button', $this->get_lang('Save'));
+
         return $result;
     }
 
     /**
      * Returns the value of a given plugin global setting
-     * @param string Name of the plugin
+     * @param string $name of the plugin
+     *
      * @return string Value of the plugin
      */
-    function get($name)
+    public function get($name)
     {
         $settings = $this->get_settings();
         foreach ($settings as $setting) {
@@ -237,6 +212,7 @@ class Plugin
                 return $setting['selected_value'];
             }
         }
+
         return false;
     }
 
@@ -249,23 +225,20 @@ class Plugin
         if (is_null($this->settings)) {
             $settings = api_get_settings_params(
                 array(
-                    "subkey = ? AND category = ? AND type = ? " => array(
-                        $this->get_name(),
-                        'Plugins',
-                        'setting'
-                    )
+                    "subkey = ? AND category = ? AND type = ? " => array($this->get_name(), 'Plugins', 'setting')
                 )
             );
             $this->settings = $settings;
         }
+
         return $this->settings;
     }
 
     /**
      * Tells whether language variables are defined for this plugin or not
-     * @param string System name of the plugin
-     * @return boolean True if the plugin has language variables defined,
-     * false otherwise
+     * @param string $name System name of the plugin
+     *
+     * @return bool True if the plugin has language variables defined, false otherwise
      */
     public function get_lang_plugin_exists($name)
     {
@@ -274,7 +247,8 @@ class Plugin
 
     /**
      * Hook for the get_lang() function to check for plugin-defined language terms
-     * @param string Name of the language variable we are looking for
+     * @param string $name of the language variable we are looking for
+     *
      * @return string The translated language term of the plugin
      */
     public function get_lang($name)
@@ -287,13 +261,13 @@ class Plugin
             $plugin_name = $this->get_name();
 
             //1. Loading english if exists
-            $english_path = $root . $plugin_name . "/lang/english.php";
+            $english_path = $root.$plugin_name."/lang/english.php";
             if (is_readable($english_path)) {
                 include $english_path;
                 $this->strings = $strings;
             }
 
-            $path = $root . $plugin_name . "/lang/$language_interface.php";
+            $path = $root.$plugin_name."/lang/$language_interface.php";
             //2. Loading the system language
             if (is_readable($path)) {
                 include $path;
@@ -308,94 +282,106 @@ class Plugin
         if (isset($this->strings[$name])) {
             return $this->strings[$name];
         }
+
         return get_lang($name);
     }
 
     /**
      * Caller for the install_course_fields() function
-     * @param int The course's integer ID
-     * @param boolean Whether to add a tool link on the course homepage
+     * @param int $courseId
+     * @param boolean $addToolLink Whether to add a tool link on the course homepage
+     *
      * @return void
      */
-    function course_install($course_id, $add_tool_link = true)
+    public function course_install($courseId, $addToolLink = true)
     {
-        $this->install_course_fields($course_id, $add_tool_link);
+        $this->install_course_fields($courseId, $addToolLink);
     }
 
-
     /**
      * Add course settings and, if not asked otherwise, add a tool link on the course homepage
-     * @param int Course integer ID
-     * @param boolean Whether to add a tool link or not (some tools might just offer a configuration section and act on the backend)
+     * @param int $courseId Course integer ID
+     * @param boolean $add_tool_link Whether to add a tool link or not
+     * (some tools might just offer a configuration section and act on the backend)
      * @return boolean  False on error, null otherwise
      */
-    public function install_course_fields($course_id, $add_tool_link = true)
+    public function install_course_fields($courseId, $add_tool_link = true)
     {
         $plugin_name = $this->get_name();
         $t_course = Database::get_course_table(TABLE_COURSE_SETTING);
+        $courseId = intval($courseId);
 
-        $course_id = intval($course_id);
-        if (empty($course_id)) {
+        if (empty($courseId)) {
             return false;
         }
-        //Ads course settings
+
+        // Adding course settings.
         if (!empty($this->course_settings)) {
             foreach ($this->course_settings as $setting) {
                 $variable = Database::escape_string($setting['name']);
-                $value = '';
+                $value ='';
+
                 if (isset($setting['init_value'])) {
                     $value = Database::escape_string($setting['init_value']);
                 }
+
                 $type = 'textfield';
                 if (isset($setting['type'])) {
                     $type = Database::escape_string($setting['type']);
                 }
+
                 if (isset($setting['group'])) {
                     $group = Database::escape_string($setting['group']);
-                    $sql = "SELECT value FROM $t_course WHERE c_id = $course_id AND variable = '$group' AND subkey = '$variable' ";
+                    $sql = "SELECT value FROM $t_course
+                            WHERE c_id = $courseId AND variable = '$group' AND subkey = '$variable' ";
                     $result = Database::query($sql);
                     if (!Database::num_rows($result)) {
-                        $sql_course = "INSERT INTO $t_course (c_id, variable, subkey, value, category, type) VALUES ($course_id, '$group', '$variable', '$value', 'plugins', '$type')";
-                        $r = Database::query($sql_course);
+                        $sql = "INSERT INTO $t_course (c_id, variable, subkey, value, category, type) VALUES
+                                ($courseId, '$group', '$variable', '$value', 'plugins', '$type')";
+                        Database::query($sql);
                     }
                 } else {
-                    $sql = "SELECT value FROM $t_course WHERE c_id = $course_id AND variable = '$variable' ";
+                    $sql = "SELECT value FROM $t_course
+                            WHERE c_id = $courseId AND variable = '$variable' ";
                     $result = Database::query($sql);
                     if (!Database::num_rows($result)) {
-                        $sql_course = "INSERT INTO $t_course (c_id, variable, value, category, subkey, type) VALUES ($course_id, '$variable','$value', 'plugins', '$plugin_name', '$type')";
-                        $r = Database::query($sql_course);
+                        $sql = "INSERT INTO $t_course (c_id, variable, value, category, subkey, type) VALUES
+                                ($courseId, '$variable','$value', 'plugins', '$plugin_name', '$type')";
+                        Database::query($sql);
                     }
                 }
             }
         }
+
         // Stop here if we don't want a tool link on the course homepage
         if (!$add_tool_link) {
             return true;
         }
+
         //Add an icon in the table tool list
         $t_tool = Database::get_course_table(TABLE_TOOL_LIST);
-        $sql = "SELECT name FROM $t_tool WHERE c_id = $course_id AND name = '$plugin_name' ";
+        $sql = "SELECT name FROM $t_tool
+                WHERE c_id = $courseId AND name = '$plugin_name' ";
         $result = Database::query($sql);
         if (!Database::num_rows($result)) {
             $tool_link = "$plugin_name/start.php";
-            $visibility = Text::string2binary(
-                api_get_setting('course_create_active_tools', $plugin_name)
-            );
-            $sql_course = "INSERT INTO $t_tool VALUES ($course_id, NULL, '$plugin_name', '$tool_link', '$plugin_name.png',' " . $visibility . "','0', 'squaregrey.gif','NO','_self','plugin','0')";
-            Database::query($sql_course);
+            $visibility = string2binary(api_get_setting('course_create_active_tools', $plugin_name));
+            $sql = "INSERT INTO $t_tool VALUES
+            ($courseId, NULL, '$plugin_name', '$tool_link', '$plugin_name.png',' ".$visibility."','0', 'squaregrey.gif','NO','_self','plugin','0')";
+            Database::query($sql);
         }
     }
 
     /**
      * Delete the fields added to the course settings page and the link to the
      * tool on the course's homepage
-     * @param int The integer course ID
+     * @param int $courseId
      * @return void
      */
-    public function uninstall_course_fields($course_id)
+    public function uninstall_course_fields($courseId)
     {
-        $course_id = intval($course_id);
-        if (empty($course_id)) {
+        $courseId = intval($courseId);
+        if (empty($courseId)) {
             return false;
         }
         $plugin_name = $this->get_name();
@@ -409,25 +395,32 @@ class Plugin
                 if (!empty($setting['group'])) {
                     $variable = Database::escape_string($setting['group']);
                 }
-                $sql = "DELETE FROM $t_course WHERE c_id = $course_id AND variable = '$variable'";
+                if (empty($variable)) {
+                    continue;
+                }
+                $sql = "DELETE FROM $t_course
+                        WHERE c_id = $courseId AND variable = '$variable'";
                 Database::query($sql);
             }
         }
 
-        $sql = "DELETE FROM $t_tool WHERE c_id = $course_id AND name = '$plugin_name'";
+        $plugin_name = Database::escape_string($plugin_name);
+        $sql = "DELETE FROM $t_tool
+                WHERE c_id = $courseId AND name = '$plugin_name'";
         Database::query($sql);
     }
 
     /**
      * Install the course fields and tool link of this plugin in all courses
      * @param boolean Whether we want to add a plugin link on the course homepage
+     *
      * @return void
      */
-    function install_course_fields_in_all_courses($add_tool_link = true)
+    public function install_course_fields_in_all_courses($add_tool_link = true)
     {
         // Update existing courses to add conference settings
         $t_courses = Database::get_main_table(TABLE_MAIN_COURSE);
-        $sql = "SELECT id, code FROM $t_courses ORDER BY id";
+        $sql = "SELECT id FROM $t_courses ORDER BY id";
         $res = Database::query($sql);
         while ($row = Database::fetch_assoc($res)) {
             $this->install_course_fields($row['id'], $add_tool_link);
@@ -438,24 +431,170 @@ class Plugin
      * Uninstall the plugin settings fields from all courses
      * @return void
      */
-    function uninstall_course_fields_in_all_courses()
+    public function uninstall_course_fields_in_all_courses()
     {
         // Update existing courses to add conference settings
         $t_courses = Database::get_main_table(TABLE_MAIN_COURSE);
-        $sql = "SELECT id, code FROM $t_courses ORDER BY id";
+        $sql = "SELECT id FROM $t_courses ORDER BY id";
         $res = Database::query($sql);
         while ($row = Database::fetch_assoc($res)) {
             $this->uninstall_course_fields($row['id']);
         }
     }
 
+    /**
+     * @return array
+     */
+    public function getCourseSettings()
+    {
+        $settings = array();
+        if (is_array($this->course_settings)) {
+            foreach ($this->course_settings as $item) {
+                if (isset($item['group'])) {
+                    if (!in_array($item['group'], $settings)) {
+                        $settings[] = $item['group'];
+                    }
+                } else {
+                    $settings[] = $item['name'];
+                }
+            }
+        }
+
+        return $settings;
+    }
+
     /**
      * Method to be extended when changing the setting in the course
      * configuration should trigger the use of a callback method
-     * @param array Values sent back from the course configuration script
+     * @param array $values sent back from the course configuration script
+     *
      * @return void
      */
     public function course_settings_updated($values = array())
     {
+
+    }
+
+   /**
+    * Add a tab to platform
+    * @param string   $tabName
+    * @param string   $url
+    *
+    * @return boolean
+    */
+    public function addTab($tabName, $url)
+    {
+        $sql = "SELECT * FROM settings_current
+            WHERE
+            variable = 'show_tabs' AND
+            subkey like 'custom_tab_%'";
+        $result = Database::query($sql);
+        $customTabsNum = Database::num_rows($result);
+
+        $tabNum = $customTabsNum + 1;
+
+        //Avoid Tab Name Spaces
+        $tabNameNoSpaces = preg_replace('/\s+/', '', $tabName);
+        $subkeytext = "Tabs" . $tabNameNoSpaces;
+
+
+        //Check if it is already added
+        $checkCondition = array(
+            'where' =>
+                array(
+                    "variable = 'show_tabs' AND subkeytext = ?" => array(
+                        $subkeytext
+                    )
+                )
+        );
+        $checkDuplicate = Database::select('*', 'settings_current', $checkCondition);
+        if (!empty($checkDuplicate)) {
+            return false;
+        }
+        //End Check
+        $subkey = 'custom_tab_' . $tabNum;
+        $attributes = array(
+            'variable' => 'show_tabs',
+            'subkey' => $subkey,
+            'type' => 'checkbox',
+            'category' => 'Platform',
+            'selected_value' => 'true',
+            'title' => $tabName,
+            'comment' => $url,
+            'subkeytext' => $subkeytext,
+            'access_url' => 1,
+            'access_url_changeable' => 0,
+            'access_url_locked' => 0
+        );
+        $resp = Database::insert('settings_current', $attributes);
+
+        //Save the id
+        $settings = $this->get_settings();
+        $setData = array (
+            'comment' => $subkey
+        );
+        $whereCondition = array(
+            'id = ?' => key($settings)
+        );
+        Database::update('settings_current', $setData, $whereCondition);
+
+        return $resp;
+    }
+
+    /**
+     * Delete a tab to chamilo's platform
+     * @param string $key
+     * @return boolean $resp Transaction response
+     */
+    public function deleteTab($key)
+    {
+        $sql = "SELECT *
+                FROM settings_current
+                WHERE variable = 'show_tabs'
+                AND subkey <> '$key'
+                AND subkey like 'custom_tab_%'
+                ";
+        $resp = $result = Database::query($sql);
+        $customTabsNum = Database::num_rows($result);
+
+        if (!empty($key)) {
+            $whereCondition = array(
+                'variable = ? AND subkey = ?' => array('show_tabs', $key)
+            );
+            $resp = Database::delete('settings_current', $whereCondition);
+
+            //if there is more than one tab
+            //re enumerate them
+            if (!empty($customTabsNum) && $customTabsNum > 0) {
+                $tabs = Database::store_result($result, 'ASSOC');
+                $i = 1;
+                foreach ($tabs as $row) {
+                    $attributes = array(
+                        'subkey' => 'custom_tab_' . $i
+                    );
+                    $this->updateTab($row['subkey'], $attributes);
+                    $i++;
+                }
+            }
+        }
+
+        return $resp;
+    }
+
+    /**
+     * Update the tabs attributes
+     * @param string $key
+     * @param array  $attributes
+     *
+     * @return boolean
+     */
+    public function updateTab($key, $attributes)
+    {
+        $whereCondition = array(
+            'variable = ? AND subkey = ?' => array('show_tabs', $key)
+        );
+        $resp = Database::update('settings_current', $attributes, $whereCondition);
+
+        return $resp;
     }
 }

+ 315 - 176
main/inc/lib/plugin.lib.php

@@ -1,9 +1,14 @@
 <?php
 /* See license terms in /license.txt */
 
+/**
+ * Class AppPlugin
+ */
 class AppPlugin
 {
     public $plugin_regions = array(
+        'main_top',
+        'main_bottom',
         'login_top',
         'login_bottom',
         'menu_top',
@@ -20,133 +25,264 @@ class AppPlugin
         'course_tool_plugin'
     );
 
+    public $installedPluginListName = array();
+    public $installedPluginListObject = array();
+
+    /**
+     *
+     */
     public function __construct()
     {
     }
 
-    function read_plugins_from_path() {
+    /**
+     * Read plugin from path
+     * @return array
+     */
+    public function read_plugins_from_path()
+    {
         /* We scan the plugin directory. Each folder is a potential plugin. */
-        $pluginpath = api_get_path(SYS_PLUGIN_PATH);
-        $possible_plugins = array();
-        $handle = @opendir($pluginpath);
+        $pluginPath = api_get_path(SYS_PLUGIN_PATH);
+        $plugins = array();
+        $handle = @opendir($pluginPath);
         while (false !== ($file = readdir($handle))) {
             if ($file != '.' && $file != '..' && is_dir(api_get_path(SYS_PLUGIN_PATH).$file)) {
-                $possible_plugins[] = $file;
+                $plugins[] = $file;
             }
         }
         @closedir($handle);
-        sort($possible_plugins);
-        return $possible_plugins;
+        sort($plugins);
+
+        return $plugins;
     }
 
-    function get_installed_plugins_by_region(){
-        $used_plugins = array();
+    /**
+     * @return array
+     */
+    public function get_installed_plugins_by_region()
+    {
+        $plugins = array();
         /* We retrieve all the active plugins. */
         $result = api_get_settings('Plugins');
-        foreach ($result as $row) {
-            $used_plugins[$row['variable']][] = $row['selected_value'];
+        if (!empty($result)) {
+            foreach ($result as $row) {
+                $plugins[$row['variable']][] = $row['selected_value'];
+            }
         }
-        return $used_plugins;
+
+        return $plugins;
     }
 
-    function get_installed_plugins() {
-        $installed_plugins = array();
-        $plugin_array = api_get_settings_params(array("variable = ? AND selected_value = ? AND category = ? " =>
-                                                array('status', 'installed', 'Plugins')));
+    /**
+     * @return array
+     */
+    public function getInstalledPluginListName()
+    {
+        if (empty($this->installedPluginListName)) {
+            $this->installedPluginListName = $this->get_installed_plugins();
+        }
+
+        return $this->installedPluginListName;
+    }
+
+    /**
+     * @return array List of Plugin
+     */
+    public function getInstalledPluginListObject()
+    {
+        if (empty($this->installedPluginListObject)) {
+            $this->setInstalledPluginListObject();
+        }
+
+        return $this->installedPluginListObject;
+    }
 
-        if (!empty($plugin_array)) {
-            foreach ($plugin_array as $row) {
-                $installed_plugins[$row['subkey']] = true;
+    /**
+     * @return array
+     */
+    public function setInstalledPluginListObject()
+    {
+        $pluginListName = $this->getInstalledPluginListName();
+        $pluginList = array();
+        if (!empty($pluginListName)) {
+            foreach ($pluginListName as $pluginName) {
+                $plugin_info = $this->getPluginInfo($pluginName);
+                if (isset($plugin_info['plugin_class'])) {
+                    $pluginList[] = $plugin_info['plugin_class']::create();
+                }
             }
-            $installed_plugins = array_keys($installed_plugins);
         }
-        return $installed_plugins;
+        $this->installedPluginListObject = $pluginList;
     }
 
-    function install($plugin_name, $access_url_id = null) {
-        if (empty($access_url_id)) {
-            $access_url_id = api_get_current_access_url_id();
-        } else {
-            $access_url_id = intval($access_url_id);
+    /**
+     * @return array
+     */
+    public function get_installed_plugins()
+    {
+        $installedPlugins = array();
+        $plugins = api_get_settings_params(
+            array(
+                "variable = ? AND selected_value = ? AND category = ? " => array('status', 'installed', 'Plugins')
+            )
+        );
+
+        if (!empty($plugins)) {
+            foreach ($plugins as $row) {
+                $installedPlugins[$row['subkey']] = true;
+            }
+            $installedPlugins = array_keys($installedPlugins);
         }
-        api_add_setting('installed', 'status', $plugin_name, 'setting', 'Plugins', $plugin_name, null, null, null, $access_url_id, 1);
 
-        //api_add_setting($plugin, $area, $plugin, null, 'Plugins', $plugin, null, null, null, $_configuration['access_url'], 1);
-        $pluginpath = api_get_path(SYS_PLUGIN_PATH).$plugin_name.'/install.php';
+        return $installedPlugins;
+    }
+
+    /**
+     * @param string $pluginName
+     * @param int    $urlId
+     */
+    public function install($pluginName, $urlId = null)
+    {
+        if (empty($urlId)) {
+            $urlId = api_get_current_access_url_id();
+        } else {
+            $urlId = intval($urlId);
+        }
 
-        if (is_file($pluginpath) && is_readable($pluginpath)) {
-            // Executes the install procedure
-            require $pluginpath;
+        api_add_setting(
+            'installed',
+            'status',
+            $pluginName,
+            'setting',
+            'Plugins',
+            $pluginName,
+            null,
+            null,
+            null,
+            $urlId,
+            1
+        );
+
+        $pluginPath = api_get_path(SYS_PLUGIN_PATH).$pluginName.'/install.php';
+
+        if (is_file($pluginPath) && is_readable($pluginPath)) {
+            // Execute the install procedure.
+
+            require $pluginPath;
         }
     }
 
-    function uninstall($plugin_name, $access_url_id = null) {
-        if (empty($access_url_id)) {
-            $access_url_id = api_get_current_access_url_id();
+    /**
+    * @param string $pluginName
+    * @param int    $urlId
+    */
+    public function uninstall($pluginName, $urlId = null)
+    {
+        if (empty($urlId)) {
+            $urlId = api_get_current_access_url_id();
         } else {
-            $access_url_id = intval($access_url_id);
+            $urlId = intval($urlId);
         }
-        api_delete_settings_params(array('category = ? AND access_url = ? AND subkey = ? ' =>
-                                   array('Plugins', $access_url_id, $plugin_name)));
-        $pluginpath = api_get_path(SYS_PLUGIN_PATH).$plugin_name.'/uninstall.php';
-        if (is_file($pluginpath) && is_readable($pluginpath)) {
-            //execute the uninstall procedure
-            require $pluginpath;
+        // First call the custom uninstall to allow full access to global settings
+        $pluginPath = api_get_path(SYS_PLUGIN_PATH).$pluginName.'/uninstall.php';
+        if (is_file($pluginPath) && is_readable($pluginPath)) {
+            // Execute the uninstall procedure.
+
+            require $pluginPath;
         }
+        // Second remove all remaining global settings
+        api_delete_settings_params(
+            array('category = ? AND access_url = ? AND subkey = ? ' => array('Plugins', $urlId, $pluginName))
+        );
     }
 
-    function get_areas_by_plugin($plugin_name) {
+    /**
+     * @param string $pluginName
+     *
+     * @return array
+     */
+    public function get_areas_by_plugin($pluginName)
+    {
         $result = api_get_settings('Plugins');
         $areas = array();
         foreach ($result as $row) {
-            if ($plugin_name == $row['selected_value']) {
+            if ($pluginName == $row['selected_value']) {
                 $areas[] = $row['variable'];
             }
         }
+
         return $areas;
     }
 
-    function is_valid_plugin_location($location) {
+    /**
+     * @param string $location
+     *
+     * @return bool
+     */
+    public function is_valid_plugin_location($location)
+    {
         return in_array($location, $this->plugin_list);
     }
 
-    function is_valid_plugin($plugin_name) {
-        if (is_dir(api_get_path(SYS_PLUGIN_PATH).$plugin_name)) {
-            if (is_file(api_get_path(SYS_PLUGIN_PATH).$plugin_name.'/index.php')) {
+    /**
+     * @param string $pluginName
+     *
+     * @return bool
+     */
+    public function is_valid_plugin($pluginName)
+    {
+        if (is_dir(api_get_path(SYS_PLUGIN_PATH).$pluginName)) {
+            if (is_file(api_get_path(SYS_PLUGIN_PATH).$pluginName.'/index.php')) {
                 return true;
             }
         }
+
         return false;
     }
 
-    function get_plugin_regions() {
+    /**
+     * @return array
+     */
+    public function get_plugin_regions()
+    {
         sort($this->plugin_regions);
+
         return $this->plugin_regions;
     }
 
-    function load_region($plugins, $region, $main_template, $forced = false)
+    /**
+    * @param string $region
+    * @param string $template
+    * @param bool   $forced
+    *
+    * @return null|string
+    */
+    public function load_region($region, $template, $forced = false)
     {
         if ($region == 'course_tool_plugin') {
             return null;
         }
         ob_start();
-        $this->get_all_plugin_contents_by_region($plugins, $region, $main_template, $forced);
+        $this->get_all_plugin_contents_by_region($region, $template, $forced);
         $content = ob_get_contents();
         ob_end_clean();
+
         return $content;
     }
 
     /**
      * Loads the translation files inside a plugin if exists. It loads by default english see the hello world plugin
      *
-     * @todo add caching
      * @param string $plugin_name
+     *
+     * @todo add caching
      */
-    function load_plugin_lang_variables($plugin_name) {
+    public function load_plugin_lang_variables($plugin_name)
+    {
         global $language_interface;
         $root = api_get_path(SYS_PLUGIN_PATH);
 
-        //1. Loading english if exists
+        // 1. Loading english if exists
         $english_path = $root.$plugin_name."/lang/english.php";
 
         if (is_readable($english_path)) {
@@ -157,7 +293,7 @@ class AppPlugin
             }
         }
 
-        //2. Loading the system language
+        // 2. Loading the system language
         if ($language_interface != 'english') {
             $path = $root.$plugin_name."/lang/$language_interface.php";
 
@@ -173,20 +309,24 @@ class AppPlugin
     }
 
     /**
+     * @param string    $region
+     * @param Template  $template
+     * @param bool      $forced
+     *
+     * @return bool
      *
-     * @param string $block
-     * @param obj   template obj
      * @todo improve this function
      */
-    function get_all_plugin_contents_by_region($_plugins, $region, $template, $forced = false)
+    public function get_all_plugin_contents_by_region($region, $template, $forced = false)
     {
+        global $_plugins;
         if (isset($_plugins[$region]) && is_array($_plugins[$region])) {
         //if (1) {
             //Load the plugin information
             foreach ($_plugins[$region] as $plugin_name) {
 
                 //The plugin_info variable is available inside the plugin index
-                $plugin_info = $this->get_plugin_info($plugin_name, $forced);
+                $plugin_info = $this->getPluginInfo($plugin_name, $forced);
 
                 //We also know where the plugin is
                 $plugin_info['current_region'] = $region;
@@ -235,15 +375,29 @@ class AppPlugin
         return true;
     }
 
+    /**
+     * @param string    $plugin_name
+     * @param bool      $forced
+     *
+     * @deprecated
+     */
+    public function get_plugin_info($plugin_name, $forced = false)
+    {
+        return $this->getPluginInfo($plugin_name, $forced);
+    }
+
     /**
      * Loads plugin info
+     *
      * @staticvar array $plugin_data
-     * @param string plugin name
-     * @param bool load from DB or from the static array
-     * @todo filter setting_form
+     * @param string    $plugin_name
+     * @param bool      $forced load from DB or from the static array
+     *
      * @return array
+     * @todo filter setting_form
      */
-    function get_plugin_info($plugin_name, $forced = false) {
+    public function getPluginInfo($plugin_name, $forced = false)
+    {
         static $plugin_data = array();
 
         if (isset($plugin_data[$plugin_name]) && $forced == false) {
@@ -257,8 +411,11 @@ class AppPlugin
             }
 
             //extra options
-            $plugin_settings = api_get_settings_params(array("subkey = ? AND category = ? AND type = ? " =>
-                                            array($plugin_name, 'Plugins','setting')));
+            $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'];
@@ -269,11 +426,14 @@ class AppPlugin
         }
     }
 
-    /*
+    /**
      * Get the template list
+     * @param  string $pluginName
+     * @return bool
      */
-    function get_templates_list($plugin_name) {
-        $plugin_info = $this->get_plugin_info($plugin_name);
+    public function get_templates_list($pluginName)
+    {
+        $plugin_info = $this->getPluginInfo($pluginName);
         if (isset($plugin_info) && isset($plugin_info['templates'])) {
             return $plugin_info['templates'];
         } else {
@@ -281,156 +441,135 @@ class AppPlugin
         }
     }
 
-    /* *
+    /**
      * Remove all regions of an specific plugin
      */
-    function remove_all_regions($plugin) {
+    public function remove_all_regions($plugin)
+    {
         $access_url_id = api_get_current_access_url_id();
         if (!empty($plugin)) {
-            api_delete_settings_params(array('category = ? AND type = ? AND access_url = ? AND subkey = ? ' =>
-                                array('Plugins', 'region', $access_url_id, $plugin)));
-
+            api_delete_settings_params(
+                array(
+                    'category = ? AND type = ? AND access_url = ? AND subkey = ? ' => array('Plugins', 'region', $access_url_id, $plugin)
+                )
+            );
         }
     }
 
-    /*
+    /**
      * Add a plugin to a region
+     * @param string $plugin
+     * @param string $region
      */
-    function add_to_region($plugin, $region) {
+    public function add_to_region($plugin, $region)
+    {
         $access_url_id = api_get_current_access_url_id();
         api_add_setting($plugin, $region, $plugin, 'region', 'Plugins', $plugin, null, null, null, $access_url_id, 1);
     }
 
-    function install_course_plugins($course_id) {
-        $plugin_list = $this->get_installed_plugins();
+    /**
+     * @param int $courseId
+     */
+    public function install_course_plugins($courseId)
+    {
+        $pluginList = $this->getInstalledPluginListObject();
+
+        if (!empty($pluginList)) {
+            /** @var Plugin $obj */
+            foreach ($pluginList as $obj) {
+                $pluginName = $obj->get_name();
+                $plugin_path = api_get_path(SYS_PLUGIN_PATH).$pluginName.'/plugin.php';
 
-        if (!empty($plugin_list)) {
-            foreach ($plugin_list as $plugin_name) {
-                $plugin_path = api_get_path(SYS_PLUGIN_PATH).$plugin_name.'/plugin.php';
                 if (file_exists($plugin_path)) {
-                    require_once $plugin_path;
+                    require $plugin_path;
                     if (isset($plugin_info) && isset($plugin_info['plugin_class'])) {
-                        $plugin_info['plugin_class']::create()->course_install($course_id);
+                        $obj->course_install($courseId);
                     }
                 }
             }
         }
     }
 
-    function add_course_settings_form($form) {
-        $plugin_list = $this->get_installed_plugins();
-        foreach ($plugin_list as $plugin_name) {
-            $plugin_info = $this->get_plugin_info($plugin_name);
-            if (isset($plugin_info['plugin_class'])) {
-                $obj = $plugin_info['plugin_class']::create();
-
-                if (!empty($obj->course_settings)) {
-                    $icon = Display::return_icon($plugin_name.'.png', Security::remove_XSS($plugin_info['title']),'', ICON_SIZE_SMALL);
-                    //$icon = null;
-                    $form->addElement('html', '<div><h3>'.$icon.' '.Security::remove_XSS($plugin_info['title']).'</h3><div>');
-
-                    $groups = array();
-                    foreach ($obj->course_settings as $setting) {
-                        if ($setting['type'] != 'checkbox') {
-                            $form->addElement($setting['type'], $setting['name'], $obj->get_lang($setting['name']));
-                        } else {
-                            //if (isset($groups[$setting['group']])) {
-                                $element = & $form->createElement($setting['type'], $setting['name'], '', $obj->get_lang($setting['name']));
-                                if ($setting['init_value'] == 1) {
-                                    $element->setChecked(true);
-                                }
-                                $groups[$setting['group']][] = $element;
-                            //}
+    /**
+     * @param FormValidator $form
+     */
+    public function add_course_settings_form($form)
+    {
+        $pluginList = $this->getInstalledPluginListObject();
+        /** @var Plugin $obj */
+        foreach ($pluginList as $obj) {
+            $plugin_name = $obj->get_name();
+            $pluginTitle = $obj->get_title();
+            if (!empty($obj->course_settings)) {
+                $icon = Display::return_icon($plugin_name.'.png', Security::remove_XSS($pluginTitle),'', ICON_SIZE_SMALL);
+                //$icon = null;
+                $form->addElement('html', '<div><h3>'.$icon.' '.Security::remove_XSS($pluginTitle).'</h3><div>');
+
+                $groups = array();
+                foreach ($obj->course_settings as $setting) {
+                    if ($setting['type'] != 'checkbox') {
+                        $form->addElement($setting['type'], $setting['name'], $obj->get_lang($setting['name']));
+                    } else {
+                        $element = & $form->createElement($setting['type'], $setting['name'], '', $obj->get_lang($setting['name']));
+                        if ($setting['init_value'] == 1) {
+                            $element->setChecked(true);
                         }
+                        $groups[$setting['group']][] = $element;
                     }
-                    foreach ($groups as $k => $v) {
-                        $form->addGroup($groups[$k], $k, array($obj->get_lang($k)));
-                    }
-                    $form->addElement('style_submit_button', null, get_lang('SaveSettings'), 'class="save"');
-                    $form->addElement('html', '</div></div>');
                 }
+                foreach ($groups as $k => $v) {
+                    $form->addGroup($groups[$k], $k, array($obj->get_lang($k)));
+                }
+                $form->addElement('style_submit_button', null, get_lang('SaveSettings'), 'class="save"');
+                $form->addElement('html', '</div></div>');
             }
         }
     }
 
-    function set_course_settings_defaults(& $values) {
-        $plugin_list = $this->get_installed_plugins();
-
-        foreach ($plugin_list as $plugin_name) {
-            $plugin_info = $this->get_plugin_info($plugin_name);
-            if (isset($plugin_info['plugin_class'])) {
-                $obj = $plugin_info['plugin_class']::create();
-                if (!empty($obj->course_settings)) {
-                    foreach ($obj->course_settings as $setting) {
-                        if (isset($setting['name'])) {
-                             $result = api_get_course_setting($setting['name']);
-                             if ($result != '-1') {
-                                $values[$setting['name']] = $result;
-                             }
-                        }
-                    }
-                }
+    /**
+     * Get all course settings from all installed plugins.
+     * @return array
+     */
+    public function getAllPluginCourseSettings()
+    {
+        $pluginList = $this->getInstalledPluginListObject();
+        /** @var Plugin $obj */
+        $courseSettings = array();
+        if (!empty($pluginList)) {
+            foreach ($pluginList as $obj) {
+                $pluginCourseSetting = $obj->getCourseSettings();
+                $courseSettings = array_merge($courseSettings, $pluginCourseSetting);
             }
         }
+        return $courseSettings;
     }
 
     /**
      * When saving the plugin values in the course settings, check whether
      * a callback method should be called and send it the updated settings
-     * @param array The new settings the user just saved
+     * @param array $values The new settings the user just saved
      * @return void
      */
-    function save_course_settings($values) {
-        $plugin_list = $this->get_installed_plugins();
-        foreach ($plugin_list as $plugin_name) {
-            $settings = $this->get_plugin_course_settings($plugin_name);
-            $subvalues = array();
-            $i = 0;
-            foreach ($settings as $v) {
-                if (isset($values[$v])) {
-                    $subvalues[$v] = $values[$v];
-                    $i++;
-                }
-            }
-            if ($i>0) {
-                $plugin_info = $this->get_plugin_info($plugin_name);
+    public function saveCourseSettingsHook($values)
+    {
+        $pluginList = $this->getInstalledPluginListObject();
 
-                if (isset($plugin_info['plugin_class'])) {
-                    $obj = $plugin_info['plugin_class']::create();
-                    $obj->course_settings_updated($subvalues);
-                }
-            }
-        }
-    }
+        /** @var Plugin $obj */
+        foreach ($pluginList as $obj) {
+            $settings = $obj->getCourseSettings();
 
-    /**
-     * Gets a nice array of keys for just the plugin's course settings
-     * @param string The plugin ID
-     * @return array Nice array of keys for course settings
-     */
-    public function get_plugin_course_settings($plugin_name) {
-        $settings = array();
-        if (empty($plugin_name)) {
-            return $settings;
-        }
-        $plugin_info = $this->get_plugin_info($plugin_name);
-
-        if (isset($plugin_info['plugin_class'])) {
-            $obj = $plugin_info['plugin_class']::create();
-            if (is_array($obj->course_settings)) {
-                foreach ($obj->course_settings as $item) {
-                    if (isset($item['group'])) {
-                        if (!in_array($item['group'],$settings)) {
-                            $settings[] = $item['group'];
-                        }
-                    } else {
-                        $settings[] = $item['name'];
+            $subValues = array();
+            if (!empty($settings)) {
+                foreach ($settings as $v) {
+                    if (isset($values[$v])) {
+                        $subValues[$v] = $values[$v];
                     }
                 }
             }
-            unset($obj);
-            unset($plugin_info);
+
+            if (!empty($subValues)) {
+                $obj->course_settings_updated($subValues);
+            }
         }
-        return $settings;
     }
-}
+}

+ 1233 - 131
main/inc/lib/sessionmanager.lib.php

@@ -1,16 +1,16 @@
 <?php
 /* For licensing terms, see /license.txt */
+
 /**
-* This is the session library for Chamilo.
-* All main sessions functions should be placed here.
-* This class provides methods for sessions management.
-* Include/require it in your code to use its features.
-* @package chamilo.library
-*/
-/**
- * The SessionManager class manages all the Chamilo sessions (as in course
- * groups).
- * @package chamilo.library.session
+ * Class SessionManager
+ *
+ * This is the session library for Chamilo.
+ * All main sessions functions should be placed here.
+ * This class provides methods for sessions management.
+ * Include/require it in your code to use its features.
+ *
+ * @package chamilo.library
+ *
  */
 class SessionManager
 {
@@ -2136,41 +2136,49 @@ class SessionManager
         return Database::store_result($result);
     }
 
+    /**
+     * @param int $user_id
+     * @param bool $ignore_visibility_for_admins
+     * @return array
+     */
     public static function get_sessions_by_user($user_id, $ignore_visibility_for_admins = false)
     {
-       $session_categories = UserManager::get_sessions_by_category($user_id, false, false, false, 0, null, null, $ignore_visibility_for_admins);
-       $session_array = array();
-       if (!empty($session_categories)) {
-           foreach ($session_categories as $category) {
-               if (isset($category['sessions'])) {
-                   foreach ($category['sessions'] as $session) {
-                       $session_array[] = $session;
-                   }
-               }
-           }
-       }
-       return $session_array;
+        $session_categories = UserManager::get_sessions_by_category($user_id, false, $ignore_visibility_for_admins);
+        $session_array = array();
+        if (!empty($session_categories)) {
+            foreach ($session_categories as $category) {
+                if (isset($category['sessions'])) {
+                    foreach ($category['sessions'] as $session) {
+                        $session_array[] = $session;
+                    }
+                }
+            }
+        }
+        return $session_array;
     }
 
     /**
      * @param string $file
-     * @param bool $updatesession options:
-     * true: if the session exists it will be updated
-     * false: if session exists a new session will be created adding a counter session1, session2, etc
-     * @param int $user_id
-     * @param $logger
-     * @param array convert a file row to an extra field. Example in CSV file there's a SessionID then it will
+     * @param bool $updateSession options:
+     *  true: if the session exists it will be updated.
+     *  false: if session exists a new session will be created adding a counter session1, session2, etc
+     * @param int $defaultUserId
+     * @param mixed $logger
+     * @param array $extraFields convert a file row to an extra field. Example in CSV file there's a SessionID then it will
      * converted to extra_external_session_id if you set this: array('SessionId' => 'extra_external_session_id')
-     * @param array extra fields
-     * @param string extra field id
+     * @param string $extraFieldId
      * @param int $daysCoachAccessBeforeBeginning
      * @param int $daysCoachAccessAfterBeginning
      * @param int $sessionVisibility
+     * @param array $fieldsToAvoidUpdate
+     * @param bool $deleteUsersNotInList
+     * @param bool $updateCourseCoaches
+     * @param bool $sessionWithCoursesModifier
      * @return array
      */
     static function importCSV(
         $file,
-        $updatesession,
+        $updateSession,
         $defaultUserId = null,
         $logger = null,
         $extraFields = array(),
@@ -2178,9 +2186,11 @@ class SessionManager
         $daysCoachAccessBeforeBeginning = null,
         $daysCoachAccessAfterBeginning = null,
         $sessionVisibility = 1,
-        $fieldsToAvoidUpdate = array()
-    )
-    {
+        $fieldsToAvoidUpdate = array(),
+        $deleteUsersNotInList = false,
+        $updateCourseCoaches = false,
+        $sessionWithCoursesModifier = false
+    ) {
         $content = file($file);
 
         $error_message = null;
@@ -2191,7 +2201,7 @@ class SessionManager
         }
 
         $eol = PHP_EOL;
-        if (PHP_SAPI !='cli') {
+        if (PHP_SAPI != 'cli') {
             $eol = '<br />';
         }
 
@@ -2208,9 +2218,9 @@ class SessionManager
         }
 
         $tbl_session = Database::get_main_table(TABLE_MAIN_SESSION);
-        $tbl_session_user           = Database::get_main_table(TABLE_MAIN_SESSION_USER);
-        $tbl_session_course         = Database::get_main_table(TABLE_MAIN_SESSION_COURSE);
-        $tbl_session_course_user    = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
+        $tbl_session_user = Database::get_main_table(TABLE_MAIN_SESSION_USER);
+        $tbl_session_course  = Database::get_main_table(TABLE_MAIN_SESSION_COURSE);
+        $tbl_session_course_user = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
 
         $sessions = array();
 
@@ -2236,6 +2246,7 @@ class SessionManager
                 }
             }
 
+            $sessionList = array();
             // Looping the sessions.
             foreach ($sessions as $enreg) {
                 $user_counter = 0;
@@ -2243,15 +2254,26 @@ class SessionManager
 
                 if (isset($extraFields) && !empty($extraFields)) {
                     foreach ($extraFields as $original => $to) {
-                        $enreg[$to] = $enreg[$original];
+                        $enreg[$to] = isset($enreg[$original]) ? $enreg[$original] : null;
                     }
                 }
 
-                $session_name           = Database::escape_string($enreg['SessionName']);
+                $session_name = Database::escape_string($enreg['SessionName']);
+
+                if (empty($session_name)) {
+                    continue;
+                }
+
                 $date_start             = $enreg['DateStart'];
                 $date_end               = $enreg['DateEnd'];
                 $visibility             = isset($enreg['Visibility']) ? $enreg['Visibility'] : $sessionVisibility;
                 $session_category_id    = isset($enreg['SessionCategory']) ? $enreg['SessionCategory'] : null;
+                $sessionDescription     = isset($enreg['SessionDescription']) ? $enreg['SessionDescription'] : null;
+
+                $extraSessionParameters = null;
+                if (!empty($sessionDescription)) {
+                    $extraSessionParameters = " , description = '".Database::escape_string($sessionDescription)."'";
+                }
 
                 // Searching a general coach.
                 if (!empty($enreg['Coach'])) {
@@ -2264,17 +2286,17 @@ class SessionManager
                     $coach_id = $defaultUserId;
                 }
 
-                if (!$updatesession) {
+                if (!$updateSession) {
                     // Always create a session.
-                    $unique_name = false; // This MUST be initializead.
+                    $unique_name = false;
                     $i = 0;
                     // Change session name, verify that session doesn't exist.
                     $suffix = null;
                     while (!$unique_name) {
                         if ($i > 1) {
-                            $suffix = ' - '.$i;
+                            $suffix = ' - ' . $i;
                         }
-                        $sql = 'SELECT 1 FROM '.$tbl_session.' WHERE name="'.$session_name.$suffix.'"';
+                        $sql = 'SELECT 1 FROM ' . $tbl_session . ' WHERE name="' . $session_name . $suffix . '"';
                         $rs = Database::query($sql);
 
                         if (Database::result($rs, 0, 0)) {
@@ -2286,30 +2308,19 @@ class SessionManager
                     }
 
                     // Creating the session.
-                    /*$sql_session = "INSERT IGNORE INTO $tbl_session SET
-                            name = '".$session_name."',
+                    $sql = "INSERT IGNORE INTO $tbl_session SET
+                            name = '" . $session_name . "',
                             id_coach = '$coach_id',
                             date_start = '$date_start',
                             date_end = '$date_end',
                             visibility = '$visibility',
                             session_category_id = '$session_category_id',
-                            session_admin_id=".intval($defaultUserId).$extraParameters;
-                    Database::query($sql_session);*/
-
-                    $params = array (
-                        'id_coach' => $coach_id,
-                        'visibility' => $visibility,
-                        'name' => $session_name,
-                        'access_start_date' => $date_start,
-                        'access_end_date' => $date_end,
-                        'session_category_id' => $session_category_id,
-                        'session_admin_id' => $defaultUserId,
-                    );
-                    $session_id = SessionManager::add($params);
+                            session_admin_id = " . intval($defaultUserId) . $extraParameters . $extraSessionParameters;
+                    Database::query($sql);
 
+                    $session_id = Database::insert_id();
                     if ($debug) {
                         if ($session_id) {
-
                             foreach ($enreg as $key => $value) {
                                 if (substr($key, 0, 6) == 'extra_') { //an extra field
                                     self::update_session_extra_field_value($session_id, substr($key, 6), $value);
@@ -2324,10 +2335,8 @@ class SessionManager
                     $session_counter++;
                 } else {
                     $sessionId = null;
-
-                    if (isset($extraFields) && !empty($extraFields)) {
+                    if (isset($extraFields) && !empty($extraFields) && !empty($enreg['extra_'.$extraFieldId])) {
                         $sessionId = self::get_session_id_from_original_id($enreg['extra_'.$extraFieldId], $extraFieldId);
-
                         if (empty($sessionId)) {
                             $my_session_result = false;
                         } else {
@@ -2340,50 +2349,70 @@ class SessionManager
                     if ($my_session_result === false) {
 
                         // Creating a session.
-                        /*$sql_session = "INSERT IGNORE INTO $tbl_session SET
+                        $sql_session = "INSERT IGNORE INTO $tbl_session SET
                                 name = '$session_name',
                                 id_coach = '$coach_id',
                                 date_start = '$date_start',
                                 date_end = '$date_end',
                                 visibility = '$visibility',
-                                session_category_id = '$session_category_id' ".$extraParameters;*/
-                        $params = array (
-                            'id_coach' => $coach_id,
-                            'visibility' => $visibility,
-                            'name' => $session_name,
-                            'access_start_date' => $date_start,
-                            'access_end_date' => $date_end,
-                            'session_category_id' => $session_category_id,
-                            'session_admin_id' => $defaultUserId,
-                        );
-                        $session_id = SessionManager::add($params);
+                                session_category_id = '$session_category_id' " . $extraParameters . $extraSessionParameters;
+
+                        Database::query($sql_session);
 
                         // We get the last insert id.
-                        /*$my_session_result = SessionManager::get_session_by_name($enreg['SessionName']);
-                        $session_id = $my_session_result['id'];*/
+                        $my_session_result = SessionManager::get_session_by_name($enreg['SessionName']);
+                        $session_id = $my_session_result['id'];
+
+                        if ($session_id) {
 
-                        if ($debug) {
                             if ($session_id) {
                                 foreach ($enreg as $key => $value) {
                                     if (substr($key, 0, 6) == 'extra_') { //an extra field
                                         self::update_session_extra_field_value($session_id, substr($key, 6), $value);
                                     }
                                 }
-                                $logger->addInfo("Sessions - #$session_id created: $session_name");
+                                if ($debug) {
+                                    $logger->addInfo("Sessions - #$session_id created: $session_name");
+                                }
                             } else {
-                                $logger->addError("Sessions - Session NOT created: $session_name");
+                                if ($debug) {
+                                    $logger->addError("Sessions - Session NOT created: $session_name");
+                                }
+                            }
+
+                            // Delete session-user relation only for students
+                            $sql = "DELETE FROM $tbl_session_user
+                                    WHERE id_session = '$session_id' AND relation_type <> " . SESSION_RELATION_TYPE_RRHH;
+                            Database::query($sql);
+
+                            $sql = "DELETE FROM $tbl_session_course WHERE id_session = '$session_id'";
+                            Database::query($sql);
+
+                            // Delete session-course-user relationships students and coaches.
+                            if ($updateCourseCoaches) {
+                                $sql = "DELETE FROM $tbl_session_course_user WHERE id_session = '$session_id' AND status in ('0', '2')";
+                                Database::query($sql);
+                            } else {
+                                // Delete session-course-user relation ships *only* for students.
+                                $sql = "DELETE FROM $tbl_session_course_user WHERE id_session = '$session_id' AND status <> 2";
+                                Database::query($sql);
                             }
                         }
                     } else {
 
+                        // Updating the session.
                         $params = array(
-                            'id_coach' =>  $coach_id,
+                            'id_coach' => $coach_id,
                             'date_start' => $date_start,
                             'date_end' => $date_end,
                             'visibility' => $visibility,
                             'session_category_id' => $session_category_id
                         );
 
+                        if (!empty($sessionDescription)) {
+                            $params['description'] = $sessionDescription;
+                        }
+
                         if (!empty($fieldsToAvoidUpdate)) {
                             foreach ($fieldsToAvoidUpdate as $field) {
                                 unset($params[$field]);
@@ -2391,7 +2420,6 @@ class SessionManager
                         }
 
                         if (isset($sessionId) && !empty($sessionId)) {
-                            // The session already exists, update it then.
                             Database::update($tbl_session, $params, array('id = ?' => $sessionId));
                             $session_id = $sessionId;
                         } else {
@@ -2401,26 +2429,47 @@ class SessionManager
                             list($session_id) = Database::fetch_array($row);
                         }
 
-                        foreach ($enreg as $key => $value) {
-                            if (substr($key, 0, 6) == 'extra_') { //an extra field
-                                self::update_session_extra_field_value($session_id, substr($key, 6), $value);
+                        if ($session_id) {
+
+                            foreach ($enreg as $key => $value) {
+                                if (substr($key, 0, 6) == 'extra_') { //an extra field
+                                    self::update_session_extra_field_value($session_id, substr($key, 6), $value);
+                                }
                             }
-                        }
 
-                        Database::query("DELETE FROM $tbl_session_user WHERE id_session='$session_id'");
-                        Database::query("DELETE FROM $tbl_session_course WHERE id_session='$session_id'");
-                        Database::query("DELETE FROM $tbl_session_course_user WHERE id_session='$session_id'");
+                            // Delete session-user relation only for students
+                            $sql = "DELETE FROM $tbl_session_user
+                                    WHERE id_session = '$session_id' AND relation_type <> " . SESSION_RELATION_TYPE_RRHH;
+                            Database::query($sql);
+
+                            $sql = "DELETE FROM $tbl_session_course WHERE id_session = '$session_id'";
+                            Database::query($sql);
+
+                            // Delete session-course-user relationships students and coaches.
+                            if ($updateCourseCoaches) {
+                                $sql = "DELETE FROM $tbl_session_course_user WHERE id_session = '$session_id' AND status in ('0', '2')";
+                                Database::query($sql);
+                            } else {
+                                // Delete session-course-user relation ships *only* for students.
+                                $sql = "DELETE FROM $tbl_session_course_user WHERE id_session = '$session_id' AND status <> 2";
+                                Database::query($sql);
+                            }
+                        }
                     }
                     $session_counter++;
                 }
 
+                $sessionList[] = $session_id;
+
                 $users = explode('|', $enreg['Users']);
 
                 // Adding the relationship "Session - User".
+                $userList = array();
                 if (is_array($users)) {
                     foreach ($users as $user) {
                         $user_id = UserManager::get_user_id_from_username($user);
                         if ($user_id !== false) {
+                            $userList[] = $user_id;
                             // Insert new users.
                             $sql = "INSERT IGNORE INTO $tbl_session_user SET
                                     id_user = '$user_id',
@@ -2434,11 +2483,48 @@ class SessionManager
                     }
                 }
 
+                if ($deleteUsersNotInList) {
+                    // Getting user in DB in order to compare to the new list.
+                    $usersListInDatabase = self::get_users_by_session($session_id, 0);
+
+                    if (!empty($usersListInDatabase)) {
+                        if (empty($userList)) {
+                            foreach ($usersListInDatabase as $userInfo) {
+                                self::unsubscribe_user_from_session($session_id, $userInfo['user_id']);
+                            }
+                        } else {
+                            foreach ($usersListInDatabase as $userInfo) {
+                                if (!in_array($userInfo['user_id'], $userList)) {
+                                    self::unsubscribe_user_from_session($session_id, $userInfo['user_id']);
+                                }
+                            }
+                        }
+                    }
+                }
+
                 $courses = explode('|', $enreg['Courses']);
 
+                // See BT#6449
+                $onlyAddFirstCoachOrTeacher = false;
+                $removeAllTeachersFromCourse = false;
+
+                if ($sessionWithCoursesModifier) {
+
+                    if (count($courses) >= 2) {
+                        // Only first teacher in course session;
+                        $onlyAddFirstCoachOrTeacher = true;
+
+                        // Remove all teachers from course.
+                        $removeAllTeachersFromCourse = true;
+                    }
+                }
+
                 foreach ($courses as $course) {
-                    $course_code = api_strtoupper(api_substr($course, 0, api_strpos($course, '[')));
+                    $courseArray = bracketsToArray($course);
+                    $course_code = $courseArray[0];
+
                     if (CourseManager::course_exists($course_code)) {
+
                         $courseInfo = api_get_course_info($course_code);
                         $courseId = $courseInfo['real_id'];
 
@@ -2446,67 +2532,136 @@ class SessionManager
                         $sql_course = "INSERT IGNORE INTO $tbl_session_course
                                        SET c_id = '".$courseId."', id_session = '$session_id'";
                         Database::query($sql_course);
+                        $course_info = api_get_course_info($course_code);
+                        SessionManager::installCourse($session_id, $course_info['real_id']);
 
                         if ($debug) {
                             $logger->addInfo("Sessions - Adding course '$course_code' to session #$session_id");
                         }
-                        $course_counter++;
 
-                        $pattern = "/\[(.*?)\]/";
-                        preg_match_all($pattern, $course, $matches);
+                        $course_counter++;
 
-                        if (isset($matches[1])) {
-                            $course_coaches = $matches[1][0];
-                            $course_users   = $matches[1][1];
-                        }
+                        $course_coaches = isset($courseArray[1]) ? $courseArray[1] : null;
+                        $course_users   = isset($courseArray[2]) ? $courseArray[2] : null;
 
                         $course_users   = explode(',', $course_users);
                         $course_coaches = explode(',', $course_coaches);
 
+                        // Checking if the flag is set TeachersWillBeAddedAsCoachInAllCourseSessions (course_edit.php)
+                        $addTeachersToSession = true;
+
+                        if (array_key_exists('add_teachers_to_sessions_courses', $courseInfo)) {
+                            $addTeachersToSession = $courseInfo['add_teachers_to_sessions_courses'];
+                        }
+
+                        // If any user provided for a course, use the users array.
+                        if (empty($course_users)) {
+                            if (!empty($userList)) {
+                                SessionManager::subscribe_users_to_session_course($userList, $session_id, $course_code);
+                                if ($debug) {
+                                    $msg = "Sessions - Adding student list ".implode(', #', $userList)." to course: '$course_code' and session #$session_id";
+                                    $logger->addInfo($msg);
+                                }
+                            }
+                        }
+
                         // Adding coaches to session course user
                         if (!empty($course_coaches)) {
-                            foreach ($course_coaches as $course_coach) {
-                                $coach_id = UserManager::get_user_id_from_username($course_coach);
-                                if ($coach_id !== false) {
-                                    $sql = "INSERT IGNORE INTO $tbl_session_course_user SET
-                                            id_user='$coach_id',
-                                            c_id ='$courseId',
-                                            id_session = '$session_id',
-                                            status = 2 ";
-                                    Database::query($sql);
-                                    if ($debug) {
-                                        $logger->addInfo("Sessions - Adding course coach: user #$coach_id ($course_coach) to course: '$course_code' and session #$session_id");
+                            $savedCoaches = array();
+                            // only edit if add_teachers_to_sessions_courses is set.
+                            if ($addTeachersToSession) {
+                                // Adding course teachers as course session teachers.
+                                $alreadyAddedTeachers = CourseManager::get_teacher_list_from_course_code($course_code);
+
+                                if (!empty($alreadyAddedTeachers)) {
+                                    $teachersToAdd = array();
+                                    foreach ($alreadyAddedTeachers as $user) {
+                                        $teachersToAdd[] = $user['username'];
+                                    }
+                                    $course_coaches = array_merge($course_coaches, $teachersToAdd);
+                                }
+                                foreach ($course_coaches as $course_coach) {
+                                    $coach_id = UserManager::get_user_id_from_username($course_coach);
+                                    if ($coach_id !== false) {
+                                        // Just insert new coaches
+                                        SessionManager::updateCoaches($session_id, $course_code, array($coach_id), false);
+
+                                        if ($debug) {
+                                            $logger->addInfo("Sessions - Adding course coach: user #$coach_id ($course_coach) to course: '$course_code' and session #$session_id");
+                                        }
+                                        $savedCoaches[] = $coach_id;
+                                    } else {
+                                        $error_message .= get_lang('UserDoesNotExist').' : '.$course_coach.$eol;
                                     }
-                                } else {
-                                    $error_message .= get_lang('UserDoesNotExist').' : '.$course_coach.$eol;
                                 }
                             }
-                        }
 
-                        $users_in_course_counter = 0;
-
-                        // Adding the relationship "Session - Course - User".
+                            // Custom courses/session coaches
+                            $teacherToAdd = null;
+                            if ($onlyAddFirstCoachOrTeacher == true) {
+                                foreach ($course_coaches as $course_coach) {
+                                    $coach_id = UserManager::get_user_id_from_username($course_coach);
+                                    if ($coach_id !== false) {
+                                        $teacherToAdd = $coach_id;
+                                        break;
+                                    }
+                                }
+                                if (!empty($teacherToAdd)) {
+                                    SessionManager::updateCoaches($session_id, $course_code, array($teacherToAdd), true);
+                                }
+                            }
 
-                        foreach ($course_users as $user) {
-                            $user_id = UserManager::get_user_id_from_username($user);
+                            if ($removeAllTeachersFromCourse && !empty($teacherToAdd)) {
+                                // Deleting all course teachers and adding the only coach as teacher.
+                                $teacherList = CourseManager::get_teacher_list_from_course_code($course_code);
+                                if (!empty($teacherList)) {
+                                    foreach ($teacherList as $teacher) {
+                                        CourseManager::unsubscribe_user($teacher['user_id'], $course_code);
+                                    }
+                                }
+                                CourseManager::subscribe_user($teacherToAdd, $course_code, COURSEMANAGER);
+                            }
 
-                            if ($user_id !== false) {
-                                $sql = "INSERT IGNORE INTO $tbl_session_course_user SET
-                                        id_user='$user_id',
-                                        c_id = '$courseId',
-                                        id_session = '$session_id'";
-                                Database::query($sql);
-                                if ($debug) {
-                                    $logger->addInfo("Sessions - Adding student: user #$user_id ($user) to course: '$course_code' and session #$session_id");
+                            // Continue default behaviour.
+                            if ($onlyAddFirstCoachOrTeacher == false) {
+                                // Checking one more time see BT#6449#note-149
+                                $coaches = SessionManager::getCoachesByCourseSession($session_id, $course_code);
+
+                                if (empty($coaches)) {
+                                    foreach ($course_coaches as $course_coach) {
+                                        $course_coach = trim($course_coach);
+                                        $coach_id = UserManager::get_user_id_from_username($course_coach);
+                                        if ($coach_id !== false) {
+                                            // Just insert new coaches
+                                            SessionManager::updateCoaches($session_id, $course_code, array($coach_id), false);
+
+                                            if ($debug) {
+                                                $logger->addInfo("Sessions - Adding course coach: user #$coach_id ($course_coach) to course: '$course_code' and session #$session_id");
+                                            }
+                                            $savedCoaches[] = $coach_id;
+                                        } else {
+                                            $error_message .= get_lang('UserDoesNotExist').' : '.$course_coach.$eol;
+                                        }
+                                    }
                                 }
-                                $users_in_course_counter++;
-                            } else {
-                                $error_message .= get_lang('UserDoesNotExist').': '.$user.$eol;
                             }
                         }
 
-                        $sql = "UPDATE $tbl_session_course SET nbr_users='$users_in_course_counter' WHERE c_id ='$courseId'";
-                        Database::query($sql);
+                        // Adding Students, updating relationship "Session - Course - User".
+                        if (!empty($course_users)) {
+                            foreach ($course_users as $user) {
+                                $user_id = UserManager::get_user_id_from_username($user);
+
+                                if ($user_id !== false) {
+                                    SessionManager::subscribe_users_to_session_course(array($user_id), $session_id, $course_code);
+                                    if ($debug) {
+                                        $logger->addInfo("Sessions - Adding student: user #$user_id ($user) to course: '$course_code' and session #$session_id");
+                                    }
+                                } else {
+                                    $error_message .= get_lang('UserDoesNotExist').': '.$user.$eol;
+                                }
+                            }
+                        }
 
                         $course_info = CourseManager::get_course_information($course_code);
                         $inserted_in_course[$course_code] = $course_info['title'];
@@ -2514,17 +2669,964 @@ class SessionManager
                 }
                 $access_url_id = api_get_current_access_url_id();
                 UrlManager::add_session_to_url($session_id, $access_url_id);
-                $sql_update_users = "UPDATE $tbl_session SET nbr_users ='$user_counter', nbr_courses='$course_counter' WHERE id='$session_id'";
+                $sql_update_users = "UPDATE $tbl_session SET nbr_users = '$user_counter', nbr_courses = '$course_counter' WHERE id = '$session_id'";
                 Database::query($sql_update_users);
             }
         }
 
         return array(
             'error_message' => $error_message,
-            'session_counter' =>  $session_counter
+            'session_counter' => $session_counter,
+            'session_list' => $sessionList
         );
     }
 
+    /**
+     * @param int $sessionId
+     * @param string $courseCode
+     * @return array
+     */
+    public static function getCoachesByCourseSession($sessionId, $courseCode)
+    {
+        $tbl_session_rel_course_rel_user = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
+        $sessionId = intval($sessionId);
+        $courseCode = Database::escape_string($courseCode);
+
+        $sql = "SELECT id_user FROM $tbl_session_rel_course_rel_user WHERE id_session = '$sessionId' AND course_code = '$courseCode' AND status = 2";
+        $result = Database::query($sql);
+
+        $coaches = array();
+        if (Database::num_rows($result) > 0) {
+            while ($row = Database::fetch_row($result)) {
+                $coaches[] = $row[0];
+            }
+        }
+        return $coaches;
+    }
+
+    /**
+     * Get all coaches added in the session - course relationship
+     * @param int $sessionId
+     * @return array
+     */
+    public static function getCoachesBySession($sessionId)
+    {
+        $table = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
+        $sessionId = intval($sessionId);
+
+        $sql = "SELECT DISTINCT id_user FROM $table
+                WHERE id_session = '$sessionId' AND status = 2";
+        $result = Database::query($sql);
+
+        $coaches = array();
+        if (Database::num_rows($result) > 0) {
+            while ($row = Database::fetch_array($result)) {
+                $coaches[] = $row['id_user'];
+            }
+        }
+        return $coaches;
+    }
+
+    /**
+     * @param int $userId
+     * @return array
+     */
+    public static function getAllCoursesFromAllSessionFromDrh($userId)
+    {
+        $sessions = SessionManager::get_sessions_followed_by_drh($userId);
+        $coursesFromSession = array();
+        if (!empty($sessions)) {
+            foreach ($sessions as $session) {
+                $courseList = SessionManager::get_course_list_by_session_id($session['id']);
+                foreach ($courseList as $course) {
+                    $coursesFromSession[] = $course['code'];
+                }
+            }
+        }
+        return $coursesFromSession;
+    }
+
+    /**
+     * @param string $status
+     * @param int $userId
+     * @param bool $getCount
+     * @param int  $from
+     * @param int  $numberItems
+     * @param int $column
+     * @param string $direction
+     * @param string $keyword
+     * @param string $active
+     * @param string $lastConnectionDate
+     * @param array $sessionIdList
+     * @param array $studentIdList
+     * @param int $filterByStatus
+     * @return array|int
+     */
+    public static function getAllUsersFromCoursesFromAllSessionFromStatus(
+        $status,
+        $userId,
+        $getCount = false,
+        $from = null,
+        $numberItems = null,
+        $column = 1,
+        $direction = 'asc',
+        $keyword = null,
+        $active = null,
+        $lastConnectionDate = null,
+        $sessionIdList = array(),
+        $studentIdList = array(),
+        $filterByStatus = null
+    ) {
+        $filterByStatus = intval($filterByStatus);
+
+        $tbl_user = Database::get_main_table(TABLE_MAIN_USER);
+        $tbl_session = Database::get_main_table(TABLE_MAIN_SESSION);
+        $tbl_course = Database::get_main_table(TABLE_MAIN_COURSE);
+        $tbl_course_user = Database::get_main_table(TABLE_MAIN_COURSE_USER);
+        $tbl_course_rel_access_url = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_COURSE);
+        $tbl_session_rel_course_rel_user = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
+        $tbl_session_rel_access_url = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_SESSION);
+
+        $direction = in_array(strtolower($direction), array('asc', 'desc')) ? $direction : 'asc';
+        $column = Database::escape_string($column);
+        $userId = intval($userId);
+
+        $limitCondition = null;
+
+        if (isset($from) && isset($numberItems)) {
+            $from = intval($from);
+            $numberItems = intval($numberItems);
+            $limitCondition = "LIMIT $from, $numberItems";
+        }
+
+        $urlId = api_get_current_access_url_id();
+
+        $sessionConditions = null;
+        $courseConditions = null;
+        $userConditions = null;
+
+        if (isset($active)) {
+            $active = intval($active);
+            $userConditions .= " AND active = $active";
+        }
+
+        switch ($status) {
+            case 'drh':
+                // Classic DRH
+                if (empty($studentIdList)) {
+                    $studentListSql = UserManager::get_users_followed_by_drh(
+                        $userId,
+                        $filterByStatus,
+                        true,
+                        false
+                    );
+                    $studentIdList = array_keys($studentListSql);
+                    $studentListSql = "'".implode("','", $studentIdList)."'";
+                } else {
+                    $studentIdList = array_map('intval', $studentIdList);
+                    $studentListSql = "'".implode("','", $studentIdList)."'";
+                }
+                if (!empty($studentListSql)) {
+                    $userConditions = " AND u.user_id IN (".$studentListSql.") ";
+                }
+                break;
+            case 'drh_all':
+                // Show all by DRH
+                if (empty($sessionIdList)) {
+                    $sessionsListSql = SessionManager::get_sessions_followed_by_drh(
+                        $userId,
+                        null,
+                        null,
+                        false,
+                        true,
+                        true
+                    );
+                } else {
+                    $sessionIdList = array_map('intval', $sessionIdList);
+                    $sessionsListSql = "'".implode("','", $sessionIdList)."'";
+                }
+                if (!empty($sessionsListSql)) {
+                    $sessionConditions = " AND s.id IN (".$sessionsListSql.") ";
+                }
+                break;
+            case 'session_admin';
+                $sessionConditions = " AND s.id_coach = $userId ";
+                break;
+            case 'admin':
+                break;
+            case 'teacher':
+                $sessionConditions = " AND s.id_coach = $userId ";
+
+                // $statusConditions = " AND s.id_coach = $userId";
+                break;
+        }
+
+        $select = "SELECT DISTINCT u.* ";
+        $masterSelect = "SELECT DISTINCT * FROM ";
+
+        if ($getCount) {
+            $select = "SELECT DISTINCT u.user_id ";
+            $masterSelect = "SELECT COUNT(DISTINCT(user_id)) as count FROM ";
+        }
+
+        if (!empty($filterByStatus)) {
+            $userConditions .= " AND u.status = ".$filterByStatus;
+        }
+
+        if (!empty($lastConnectionDate)) {
+            $lastConnectionDate = Database::escape_string($lastConnectionDate);
+            $userConditions .=  " AND u.last_login <= '$lastConnectionDate' ";
+        }
+
+        if (!empty($keyword)) {
+            $keyword = Database::escape_string($keyword);
+            $userConditions .= " AND (
+                u.username LIKE '%$keyword%' OR
+                u.firstname LIKE '%$keyword%' OR
+                u.lastname LIKE '%$keyword%' OR
+                u.official_code LIKE '%$keyword%' OR
+                u.email LIKE '%$keyword%'
+            )";
+        }
+
+        $where = " WHERE
+                   access_url_id = $urlId
+                   $userConditions
+        ";
+
+        $sql = "$masterSelect (
+                ($select
+                FROM $tbl_session s
+                    INNER JOIN $tbl_session_rel_course_rel_user su ON (s.id = su.id_session)
+                    INNER JOIN $tbl_user u ON (u.user_id = su.id_user AND s.id = id_session)
+                    INNER JOIN $tbl_session_rel_access_url url ON (url.session_id = s.id)
+                    $where
+                    $sessionConditions
+                )
+                UNION (
+                    $select
+                    FROM $tbl_course c
+                    INNER JOIN $tbl_course_user cu ON (cu.course_code = c.code)
+                    INNER JOIN $tbl_user u ON (u.user_id = cu.user_id)
+                    INNER JOIN $tbl_course_rel_access_url url ON (url.course_code = c.code)
+                    $where
+                    $courseConditions
+                )
+                ) as t1
+                ";
+
+        if ($getCount) {
+            ///var_dump($sql);
+            $result = Database::query($sql);
+            $count = 0;
+            if (Database::num_rows($result)) {
+                $rows = Database::fetch_array($result);
+                $count = $rows['count'];
+            }
+            return $count;
+        }
+
+        if (!empty($column) && !empty($direction)) {
+            $column = str_replace('u.', '', $column);
+            $sql .= " ORDER BY $column $direction ";
+        }
+
+        $sql .= $limitCondition;
+        $result = Database::query($sql);
+        $result = Database::store_result($result);
+
+        return $result ;
+    }
+
+    /**
+     * @param int $sessionId
+     * @param string $courseCode
+     * @param array $coachList
+     * @param bool $deleteCoachesNotInList
+     */
+    public static function updateCoaches($sessionId, $courseCode, $coachList, $deleteCoachesNotInList = false)
+    {
+        $currentCoaches = self::getCoachesByCourseSession($sessionId, $courseCode);
+
+        if (!empty($coachList)) {
+            foreach ($coachList as $userId) {
+                self::set_coach_to_course_session($userId, $sessionId, $courseCode);
+            }
+        }
+
+        if ($deleteCoachesNotInList) {
+            if (!empty($coachList)) {
+                $coachesToDelete = array_diff($currentCoaches, $coachList);
+            } else {
+                $coachesToDelete = $currentCoaches;
+            }
+
+            if (!empty($coachesToDelete)) {
+                foreach ($coachesToDelete as $userId) {
+                    self::set_coach_to_course_session($userId, $sessionId, $courseCode, true);
+                }
+            }
+        }
+    }
+
+    /**
+     * @param array $sessions
+     * @param array $sessionsDestination
+     * @return string
+     */
+    public static function copyStudentsFromSession($sessions, $sessionsDestination)
+    {
+        $messages = array();
+        if (!empty($sessions)) {
+            foreach ($sessions as $sessionId) {
+                $sessionInfo = self::fetch($sessionId);
+                $userList = self::get_users_by_session($sessionId, 0);
+                if (!empty($userList)) {
+                    $newUserList = array();
+                    $userToString = null;
+                    foreach ($userList as $userInfo) {
+                        $newUserList[] = $userInfo['user_id'];
+                        $userToString .= $userInfo['firstname'] . ' ' . $userInfo['lastname'] . '<br />';
+                    }
+
+                    if (!empty($sessionsDestination)) {
+                        foreach ($sessionsDestination as $sessionDestinationId) {
+                            $sessionDestinationInfo = self::fetch($sessionDestinationId);
+                            $messages[] = Display::return_message(
+                                sprintf(get_lang('AddingStudentsFromSessionXToSessionY'), $sessionInfo['name'], $sessionDestinationInfo['name']), 'info', false
+                            );
+                            if ($sessionId == $sessionDestinationId) {
+                                $messages[] = Display::return_message(sprintf(get_lang('SessionXSkipped'), $sessionDestinationId), 'warning', false);
+                                continue;
+                            }
+                            $messages[] = Display::return_message(get_lang('StudentList') . '<br />' . $userToString, 'info', false);
+                            SessionManager::suscribe_users_to_session($sessionDestinationId, $newUserList, SESSION_VISIBLE_READ_ONLY, false);
+                        }
+                    } else {
+                        $messages[] = Display::return_message(get_lang('NoDestinationSessionProvided'), 'warning');
+                    }
+                } else {
+                    $messages[] = Display::return_message(get_lang('NoStudentsFoundForSession') . ' #' . $sessionInfo['name'], 'warning');
+                }
+            }
+        } else {
+            $messages[] = Display::return_message(get_lang('NoData'), 'warning');
+        }
+        return $messages;
+    }
+
+    /**
+     * Assign coaches of a session(s) as teachers to a given course (or courses)
+     * @param array A list of session IDs
+     * @param array A list of course IDs
+     * @return string
+     */
+    public static function copyCoachesFromSessionToCourse($sessions, $courses)
+    {
+        $coachesPerSession = array();
+        foreach ($sessions as $sessionId) {
+            $coaches = self::getCoachesBySession($sessionId);
+            $coachesPerSession[$sessionId] = $coaches;
+        }
+
+        $result = array();
+
+        if (!empty($courses)) {
+            foreach ($courses as $courseId) {
+                $courseInfo = api_get_course_info_by_id($courseId);
+                foreach ($coachesPerSession as $sessionId => $coachList) {
+                    CourseManager::updateTeachers(
+                        $courseInfo['code'], $coachList, false, false, false
+                    );
+                    $result[$courseInfo['code']][$sessionId] = $coachList;
+                }
+            }
+        }
+        $sessionUrl = api_get_path(WEB_CODE_PATH) . 'admin/resume_session.php?id_session=';
+
+        $htmlResult = null;
+
+        if (!empty($result)) {
+            foreach ($result as $courseCode => $data) {
+                $url = api_get_course_url($courseCode);
+                $htmlResult .= sprintf(get_lang('CoachesSubscribedAsATeacherInCourseX'), Display::url($courseCode, $url, array('target' => '_blank')));
+                foreach ($data as $sessionId => $coachList) {
+                    $sessionInfo = self::fetch($sessionId);
+                    $htmlResult .= '<br />';
+                    $htmlResult .= Display::url(
+                        get_lang('Session') . ': ' . $sessionInfo['name'] . ' <br />', $sessionUrl . $sessionId, array('target' => '_blank')
+                    );
+                    $teacherList = array();
+                    foreach ($coachList as $coachId) {
+                        $userInfo = api_get_user_info($coachId);
+                        $teacherList[] = $userInfo['complete_name'];
+                    }
+                    if (!empty($teacherList)) {
+                        $htmlResult .= implode(', ', $teacherList);
+                    } else {
+                        $htmlResult .= get_lang('NothingToAdd');
+                    }
+                }
+                $htmlResult .= '<br />';
+            }
+            $htmlResult = Display::return_message($htmlResult, 'normal', false);
+        }
+        return $htmlResult;
+    }
+
+    /**
+     * @param string $keyword
+     * @param string $active
+     * @param string $lastConnectionDate
+     * @param array $sessionIdList
+     * @param array $studentIdList
+     * @param int $userStatus STUDENT|COURSEMANAGER constants
+     *
+     * @return array|int
+     */
+    public static function getCountUserTracking(
+        $keyword = null,
+        $active = null,
+        $lastConnectionDate = null,
+        $sessionIdList = array(),
+        $studentIdList = array(),
+        $filterUserStatus = null
+    ) {
+        $userId = api_get_user_id();
+        $drhLoaded = false;
+
+        if (api_is_drh()) {
+            if (api_drh_can_access_all_session_content()) {
+                $count = self::getAllUsersFromCoursesFromAllSessionFromStatus(
+                    'drh_all',
+                    $userId,
+                    true,
+                    null,
+                    null,
+                    null,
+                    null,
+                    $keyword,
+                    $active,
+                    $lastConnectionDate,
+                    $sessionIdList,
+                    $studentIdList,
+                    $filterUserStatus
+                );
+                $drhLoaded = true;
+            }
+        }
+
+        if ($drhLoaded == false) {
+            $count = UserManager::getUsersFollowedByUser(
+                $userId,
+                $filterUserStatus,
+                false,
+                false,
+                true,
+                null,
+                null,
+                null,
+                null,
+                $active,
+                $lastConnectionDate,
+                COURSEMANAGER,
+                $keyword
+            );
+        }
+
+        return $count;
+    }
+
+    /**
+     * Get teachers followed by a user
+     * @param int $userId
+     * @param int $active
+     * @param string $lastConnectionDate
+     * @param bool $getCount
+     * @param array $sessionIdList
+     * @return array|int
+     */
+    public static function getTeacherTracking(
+        $userId,
+        $active = 1,
+        $lastConnectionDate = null,
+        $getCount = false,
+        $sessionIdList = array()
+    ) {
+        $teacherResult = array();
+
+        if (api_is_drh() || api_is_platform_admin()) {
+            // Followed teachers by drh
+            if (api_drh_can_access_all_session_content()) {
+                if (empty($sessionIdList)) {
+                    $sessions = SessionManager::get_sessions_followed_by_drh($userId);
+                    $sessionIdList = array();
+                    foreach ($sessions as $session) {
+                        $sessionIdList[] = $session['id'];
+                    }
+                }
+
+                $sessionIdList = array_map('intval', $sessionIdList);
+                $sessionToString = implode("', '",  $sessionIdList);
+
+                $course = Database::get_main_table(TABLE_MAIN_COURSE);
+                $sessionCourse = Database::get_main_table(TABLE_MAIN_SESSION_COURSE);
+                $courseUser = Database::get_main_table(TABLE_MAIN_COURSE_USER);
+
+                // Select the teachers.
+                $sql = "SELECT DISTINCT(cu.user_id) FROM $course c
+                        INNER JOIN $sessionCourse src ON c.code = src.course_code
+                        INNER JOIN $courseUser cu ON (cu.course_code = c.code)
+		                WHERE src.id_session IN ('$sessionToString') AND cu.status = 1";
+                $result = Database::query($sql);
+                $teacherListId = array();
+                while($row = Database::fetch_array($result, 'ASSOC')) {
+                    $teacherListId[$row['user_id']] = $row['user_id'];
+                }
+            } else {
+                $teacherResult = UserManager::get_users_followed_by_drh($userId, COURSEMANAGER);
+                $teacherListId = array();
+                foreach ($teacherResult as $userInfo) {
+                    $teacherListId[] = $userInfo['user_id'];
+                }
+            }
+        }
+
+        if (!empty($teacherListId)) {
+            $tableUser = Database::get_main_table(TABLE_MAIN_USER);
+
+            $select = "SELECT DISTINCT u.* ";
+            if ($getCount) {
+                $select = "SELECT count(DISTINCT(u.user_id)) as count";
+            }
+
+            $sql = "$select FROM $tableUser u";
+
+            if (!empty($lastConnectionDate)) {
+                $tableLogin = Database::get_main_table(TABLE_STATISTIC_TRACK_E_LOGIN);
+                //$sql .= " INNER JOIN $tableLogin l ON (l.login_user_id = u.user_id) ";
+            }
+            $active = intval($active);
+            $teacherListId = implode("','", $teacherListId);
+            $where = " WHERE u.active = $active AND u.user_id IN ('$teacherListId') ";
+
+            if (!empty($lastConnectionDate)) {
+                $lastConnectionDate = Database::escape_string($lastConnectionDate);
+                //$where .= " AND l.login_date <= '$lastConnectionDate' ";
+            }
+
+            $sql .= $where;
+            $result = Database::query($sql);
+            if (Database::num_rows($result)) {
+                if ($getCount) {
+                    $row = Database::fetch_array($result);
+                    return $row['count'];
+                } else {
+
+                    return Database::store_result($result, 'ASSOC');
+                }
+            }
+        }
+
+        return 0;
+    }
+
+    /**
+     * Get the list of course tools that have to be dealt with in case of
+     * registering any course to a session
+     * @return array The list of tools to be dealt with (literal names)
+     */
+    public static function getCourseToolToBeManaged()
+    {
+        return array(
+            'courseDescription',
+            'courseIntroduction'
+        );
+    }
+
+    /**
+     * Calls the methods bound to each tool when a course is registered into a session
+     * @param int $sessionId
+     * @param int $courseId
+     * @return void
+     */
+    public static function installCourse($sessionId, $courseId)
+    {
+        return true;
+        $toolList = self::getCourseToolToBeManaged();
+
+        foreach ($toolList as $tool) {
+            $method = 'add' . $tool;
+            if (method_exists(get_class(), $method)) {
+                self::$method($sessionId, $courseId);
+            }
+        }
+    }
+
+    /**
+     * Calls the methods bound to each tool when a course is unregistered from
+     * a session
+     * @param int $sessionId
+     * @param int $courseId
+     */
+    public static function unInstallCourse($sessionId, $courseId)
+    {
+        return true;
+        $toolList = self::getCourseToolToBeManaged();
+
+        foreach ($toolList as $tool) {
+            $method = 'remove' . $tool;
+            if (method_exists(get_class(), $method)) {
+                self::$method($sessionId, $courseId);
+            }
+        }
+    }
+
+    /**
+     * @param int $sessionId
+     * @param int $courseId
+     */
+    public static function addCourseIntroduction($sessionId, $courseId)
+    {
+        // @todo create a tool intro lib
+        $sessionId = intval($sessionId);
+        $courseId = intval($courseId);
+
+        $TBL_INTRODUCTION = Database::get_course_table(TABLE_TOOL_INTRO);
+        $sql = "SELECT * FROM $TBL_INTRODUCTION WHERE c_id = $courseId";
+        $result = Database::query($sql);
+        $result = Database::store_result($result, 'ASSOC');
+
+        if (!empty($result)) {
+            foreach ($result as $result) {
+                // @todo check if relation exits.
+                $result['session_id'] = $sessionId;
+                Database::insert($TBL_INTRODUCTION, $result);
+            }
+        }
+    }
+
+    /**
+     * @param int $sessionId
+     * @param int $courseId
+     */
+    public static function removeCourseIntroduction($sessionId, $courseId)
+    {
+        $sessionId = intval($sessionId);
+        $courseId = intval($courseId);
+        $TBL_INTRODUCTION = Database::get_course_table(TABLE_TOOL_INTRO);
+        $sql = "DELETE FROM $TBL_INTRODUCTION WHERE c_id = $courseId AND session_id = $sessionId";
+        Database::query($sql);
+    }
+
+    /**
+     * @param int $sessionId
+     * @param int $courseId
+     */
+    public static function addCourseDescription($sessionId, $courseId)
+    {
+        /* $description = new CourseDescription();
+          $descriptions = $description->get_descriptions($courseId);
+          foreach ($descriptions as $description) {
+          } */
+    }
+
+    /**
+     * @param int $sessionId
+     * @param int $courseId
+     */
+    public static function removeCourseDescription($sessionId, $courseId)
+    {
+
+    }
+
+    /**
+     * @param array $list  format see self::importSessionDrhCSV()
+     * @param bool $sendEmail
+     * @param bool $removeOldRelationShips
+     * @return string
+     */
+    public static function subscribeDrhToSessionList($userSessionList, $sendEmail, $removeOldRelationShips)
+    {
+        if (!empty($userSessionList)) {
+            foreach ($userSessionList as $userId => $data) {
+                $sessionList = array();
+                foreach ($data['session_list'] as $sessionInfo) {
+                    $sessionList[] = $sessionInfo['session_id'];
+                }
+                $userInfo = $data['user_info'];
+                self::suscribe_sessions_to_hr_manager($userInfo, $sessionList, $sendEmail, $removeOldRelationShips);
+            }
+        }
+    }
+
+    /**
+     * @param array $userSessionList format see self::importSessionDrhCSV()
+     */
+    public static function checkSubscribeDrhToSessionList($userSessionList)
+    {
+        $message = null;
+        if (!empty($userSessionList)) {
+            if (!empty($userSessionList)) {
+                foreach ($userSessionList as $userId => $data) {
+                    $userInfo = $data['user_info'];
+
+                    $sessionListSubscribed = self::get_sessions_followed_by_drh($userId);
+                    if (!empty($sessionListSubscribed)) {
+                        $sessionListSubscribed = array_keys($sessionListSubscribed);
+                    }
+
+                    $sessionList = array();
+                    if (!empty($data['session_list'])) {
+                        foreach ($data['session_list'] as $sessionInfo) {
+                            if (in_array($sessionInfo['session_id'], $sessionListSubscribed)) {
+                                $sessionList[] = $sessionInfo['session_info']['name'];
+                            }
+                        }
+                    }
+
+                    $message .= '<strong>' . get_lang('User') . '</strong> ' . $userInfo['complete_name'] . ' <br />';
+
+                    if (!in_array($userInfo['status'], array(DRH)) && !api_is_platform_admin_by_id($userInfo['user_id'])) {
+                        $message .= get_lang('UserMustHaveTheDrhRole') . '<br />';
+                        continue;
+                    }
+
+                    if (!empty($sessionList)) {
+                        $message .= '<strong>' . get_lang('Sessions') . ':</strong> <br />';
+                        $message .= implode(', ', $sessionList) . '<br /><br />';
+                    } else {
+                        $message .= get_lang('NoSessionProvided') . ' <br /><br />';
+                    }
+                }
+            }
+        }
+        return $message;
+    }
+
+    /**
+     * @param string $file
+     * @param bool $sendEmail
+     * @param bool $removeOldRelationShips
+     */
+    public static function importSessionDrhCSV($file, $sendEmail, $removeOldRelationShips)
+    {
+        $list = Import::csv_reader($file);
+
+        if (!empty($list)) {
+            $userSessionList = array();
+            foreach ($list as $data) {
+                $userInfo = api_get_user_info_from_username($data['Username']);
+                $sessionInfo = self::get_session_by_name($data['SessionName']);
+
+                if (!empty($userInfo) && !empty($sessionInfo)) {
+                    $userSessionList[$userInfo['user_id']]['session_list'][] = array(
+                        'session_id' => $sessionInfo['id'],
+                        'session_info' => $sessionInfo
+                    );
+                    $userSessionList[$userInfo['user_id']]['user_info'] = $userInfo;
+                }
+            }
+
+            self::subscribeDrhToSessionList($userSessionList, $sendEmail, $removeOldRelationShips);
+            return self::checkSubscribeDrhToSessionList($userSessionList);
+        }
+    }
+
+    /**
+     * Courses re-ordering in resume_session.php flag see BT#8316
+     */
+    public static function orderCourseIsEnabled()
+    {
+        global $_configuration;
+        if (isset($_configuration['session_course_ordering']) &&
+            $_configuration['session_course_ordering']
+        ) {
+            return true;
+        }
+
+        return false;
+    }
+
+    /**
+     * @param string $direction (up/down)
+     * @param int $sessionId
+     * @param string $courseCode
+     * @return bool
+     */
+    public static function move($direction, $sessionId, $courseCode)
+    {
+        if (!self::orderCourseIsEnabled()) {
+            return false;
+        }
+
+        $sessionId = intval($sessionId);
+        $courseCode = Database::escape_string($courseCode);
+
+        $table = Database::get_main_table(TABLE_MAIN_SESSION_COURSE);
+        $courseList = self::get_course_list_by_session_id($sessionId, null, 'position');
+
+        $position = array();
+        $count = 0;
+
+        foreach ($courseList as $course) {
+            if ($course['position'] == '') {
+                $course['position'] = $count;
+            }
+            $position[$course['code']] = $course['position'];
+            // Saving current order.
+            $sql = "UPDATE $table SET position = $count
+                    WHERE id_session = $sessionId AND course_code = '".$course['code']."'";
+            Database::query($sql);
+            $count++;
+        }
+
+        // Loading new positions.
+        $courseList = self::get_course_list_by_session_id($sessionId, null, 'position');
+
+        $found = false;
+
+        switch ($direction) {
+            case 'up':
+                $courseList = array_reverse($courseList);
+                break;
+            case 'down':
+                break;
+        }
+
+        foreach ($courseList as $course) {
+            if ($found) {
+                $nextId = $course['code'];
+                $nextOrder = $course['position'];
+                break;
+            }
+
+            if ($courseCode == $course['code']) {
+                $thisCourseCode = $course['code'];
+                $thisOrder = $course['position'];
+                $found = true;
+            }
+        }
+
+        $sql1 = "UPDATE $table SET position = '".intval($nextOrder)."'
+                 WHERE id_session = $sessionId AND course_code =  '".$thisCourseCode."'";
+
+        $sql2 = "UPDATE $table SET position = '".intval($thisOrder)."'
+                 WHERE id_session = $sessionId AND course_code =  '".$nextId."'";
+        Database::query($sql1);
+        Database::query($sql2);
+
+        return true;
+    }
+
+    /**
+     * @param int $sessionId
+     * @param string $courseCode
+     * @return bool
+     */
+    public static function moveUp($sessionId, $courseCode)
+    {
+        return self::move('up', $sessionId, $courseCode);
+    }
+
+    /**
+     * @param int $sessionId
+     * @param string $courseCode
+     * @return bool
+     */
+    public static function moveDown($sessionId, $courseCode)
+    {
+        return self::move('down', $sessionId, $courseCode);
+    }
+
+    /**
+     * Use the session duration to allow/block user access see BT#8317
+     * Needs these DB changes
+     * ALTER TABLE session ADD COLUMN duration int;
+     * ALTER TABLE session_rel_user ADD COLUMN duration int;
+     */
+    public static function durationPerUserIsEnabled()
+    {
+        global $_configuration;
+        if (isset($_configuration['session_duration_feature']) &&
+            $_configuration['session_duration_feature']
+        ) {
+            return true;
+        }
+
+        return false;
+    }
+
+    /**
+     * @param int $userId
+     * @param int $sessionId
+     * @param int $duration in days
+     * @return int
+     */
+    public static function getDayLeftInSession($sessionId, $userId, $duration)
+    {
+        $courseAccess = CourseManager::getFirstCourseAccessPerSessionAndUser(
+            $sessionId,
+            $userId
+        );
+
+        $currentTime = time();
+
+        $firstAccess = api_strtotime($courseAccess['login_course_date'], 'UTC');
+
+        $endDateInSeconds = $firstAccess + $duration*24*60*60;
+        $leftDays = round(($endDateInSeconds- $currentTime) / 60 / 60 / 24);
+
+        return $leftDays;
+    }
+
+    /**
+     * @param int $duration
+     * @param int $userId
+     * @param int $sessionId
+     */
+    public static function editUserSessionDuration($duration, $userId, $sessionId)
+    {
+        $duration = intval($duration);
+        $userId = intval($userId);
+        $sessionId = intval($sessionId);
+
+        if (empty($userId) || empty($sessionId)) {
+            return false;
+        }
+
+        $table = Database::get_main_table(TABLE_MAIN_SESSION_USER);
+        $parameters = array('duration' => $duration);
+        $where = array('id_session = ? AND id_user = ? ' => array($sessionId, $userId));
+        Database::update($table, $parameters, $where);
+    }
+
+    /**
+     * @param int $userId
+     * @param int $sessionId
+     *
+     * @param return array
+     */
+    public static function getUserSession($userId, $sessionId)
+    {
+        $userId = intval($userId);
+        $sessionId = intval($sessionId);
+
+        if (empty($userId) || empty($sessionId)) {
+            return false;
+        }
+
+        $table = Database::get_main_table(TABLE_MAIN_SESSION_USER);
+        $sql = "SELECT * FROM $table WHERE id_session =$sessionId AND id_user = $userId";
+        $result = Database::query($sql);
+        $values = array();
+        if (Database::num_rows($result)) {
+            $values = Database::fetch_array($result, 'ASSOC');
+        }
+
+        return $values;
+    }
+
     /**
      *  @todo Add constatns in a DB table
      */

+ 243 - 168
main/inc/lib/skill.lib.php

@@ -1,37 +1,41 @@
 <?php
 /* For licensing terms, see /license.txt */
 /**
-*   This class provides methods for the notebook management.
-*   Include/require it in your code to use its features.
-*   @package chamilo.library
-*/
-/**
- * Code
+ *   This class provides methods for the notebook management.
+ *   Include/require it in your code to use its features.
+ * @package chamilo.library
  */
 
+
+require_once api_get_path(LIBRARY_PATH).'model.lib.php';
+
 class SkillProfile extends Model
 {
     public $columns = array('id', 'name', 'description');
-    public function __construct() {
-        $this->table = Database::get_main_table(TABLE_MAIN_SKILL_PROFILE);
+
+    public function __construct()
+    {
+        $this->table             = Database::get_main_table(TABLE_MAIN_SKILL_PROFILE);
         $this->table_rel_profile = Database::get_main_table(TABLE_MAIN_SKILL_REL_PROFILE);
     }
 
-    public function get_profiles() {
-        $sql = "SELECT * FROM $this->table p INNER JOIN $this->table_rel_profile sp ON(p.id = sp.profile_id) ";
-        $result     = Database::query($sql);
-        $profiles   = Database::store_result($result,'ASSOC');
+    public function get_profiles()
+    {
+        $sql      = "SELECT * FROM $this->table p INNER JOIN $this->table_rel_profile sp ON(p.id = sp.profile_id) ";
+        $result   = Database::query($sql);
+        $profiles = Database::store_result($result, 'ASSOC');
         return $profiles;
     }
 
-    public function save($params, $show_query = false) {
+    public function save($params, $show_query = false)
+    {
         if (!empty($params)) {
-           $profile_id = parent::save($params, $show_query);
+            $profile_id = parent::save($params, $show_query);
             if ($profile_id) {
                 $skill_rel_profile = new SkillRelProfile();
                 if (isset($params['skills'])) {
-                    foreach($params['skills'] as $skill_id) {
-                        $attributes = array('skill_id' => $skill_id, 'profile_id'=>$profile_id);
+                    foreach ($params['skills'] as $skill_id) {
+                        $attributes = array('skill_id' => $skill_id, 'profile_id' => $profile_id);
                         $skill_rel_profile->save($attributes);
                     }
                 }
@@ -42,17 +46,21 @@ class SkillProfile extends Model
     }
 }
 
-class SkillRelProfile extends Model {
-    var $columns = array('id', 'skill_id', 'profile_id');
-    public function __construct() {
+class SkillRelProfile extends Model
+{
+    public $columns = array('id', 'skill_id', 'profile_id');
+
+    public function __construct()
+    {
         $this->table = Database::get_main_table(TABLE_MAIN_SKILL_REL_PROFILE);
     }
 
-    public function get_skills_by_profile($profile_id) {
-        $skills =  $this->get_all(array('where'=>array('profile_id = ? ' => $profile_id)));
+    public function get_skills_by_profile($profile_id)
+    {
+        $skills       = $this->get_all(array('where' => array('profile_id = ? ' => $profile_id)));
         $return_array = array();
         if (!empty($skills)) {
-            foreach($skills as $skill_data) {
+            foreach ($skills as $skill_data) {
                 $return_array[] = $skill_data['skill_id'];
             }
         }
@@ -60,29 +68,36 @@ class SkillRelProfile extends Model {
     }
 }
 
-class SkillRelSkill extends Model {
-    var $columns = array('skill_id', 'parent_id','relation_type', 'level');
-    public function __construct() {
+class SkillRelSkill extends Model
+{
+    public $columns = array('skill_id', 'parent_id', 'relation_type', 'level');
+
+    public function __construct()
+    {
         $this->table = Database::get_main_table(TABLE_MAIN_SKILL_REL_SKILL);
     }
 
     /**
      * Gets an element
      */
-    public function get_skill_info($id) {
-        if (empty($id)) { return array(); }
-        $result = Database::select('*',$this->table, array('where'=>array('skill_id = ?'=>intval($id))), 'first');
+    public function get_skill_info($id)
+    {
+        if (empty($id)) {
+            return array();
+        }
+        $result = Database::select('*', $this->table, array('where' => array('skill_id = ?' => intval($id))), 'first');
         return $result;
     }
 
-    public function get_skill_parents($skill_id, $add_child_info = true) {
+    public function get_skill_parents($skill_id, $add_child_info = true)
+    {
         $skill_id = intval($skill_id);
-        $sql = 'SELECT child.* FROM '.$this->table.' child LEFT JOIN '.$this->table.' parent
+        $sql      = 'SELECT child.* FROM '.$this->table.' child LEFT JOIN '.$this->table.' parent
                 ON child.parent_id = parent.skill_id
                 WHERE child.skill_id = '.$skill_id.' ';
-        $result = Database::query($sql);
-        $skill  = Database::store_result($result,'ASSOC');
-        $skill  = isset($skill[0]) ? $skill[0] : null;
+        $result   = Database::query($sql);
+        $skill    = Database::store_result($result, 'ASSOC');
+        $skill    = isset($skill[0]) ? $skill[0] : null;
 
         $parents = array();
         if (!empty($skill)) {
@@ -96,14 +111,15 @@ class SkillRelSkill extends Model {
         return $parents;
     }
 
-    public function get_direct_parents($skill_id) {
+    public function get_direct_parents($skill_id)
+    {
         $skill_id = intval($skill_id);
-        $sql = 'SELECT parent_id as skill_id FROM '.$this->table.'
+        $sql      = 'SELECT parent_id as skill_id FROM '.$this->table.'
                 WHERE skill_id = '.$skill_id.' ';
-        $result = Database::query($sql);
-        $skill  = Database::store_result($result,'ASSOC');
-        $skill  = isset($skill[0]) ? $skill[0] : null;
-        $parents = array();
+        $result   = Database::query($sql);
+        $skill    = Database::store_result($result, 'ASSOC');
+        $skill    = isset($skill[0]) ? $skill[0] : null;
+        $parents  = array();
         if (!empty($skill)) {
             $parents[] = $skill;
         }
@@ -111,14 +127,15 @@ class SkillRelSkill extends Model {
     }
 
 
-    public function get_children($skill_id, $load_user_data = false, $user_id = false) {
-        $skills = $this->find('all', array('where'=> array('parent_id = ? '=> $skill_id)));
-        $skill_obj = new Skill();
+    public function get_children($skill_id, $load_user_data = false, $user_id = false)
+    {
+        $skills         = $this->find('all', array('where' => array('parent_id = ? ' => $skill_id)));
+        $skill_obj      = new Skill();
         $skill_rel_user = new SkillRelUser();
 
         if ($load_user_data) {
             $passed_skills = $skill_rel_user->get_user_skills($user_id);
-            $done_skills = array();
+            $done_skills   = array();
             foreach ($passed_skills as $done_skill) {
                 $done_skills[] = $done_skill['skill_id'];
             }
@@ -129,29 +146,34 @@ class SkillRelSkill extends Model {
                 $skill['data'] = $skill_obj->get($skill['skill_id']);
                 if (isset($skill['data']) && !empty($skill['data'])) {
                     if (!empty($done_skills)) {
-                        $skill['data']['passed'] =  0;
+                        $skill['data']['passed'] = 0;
                         if (in_array($skill['skill_id'], $done_skills)) {
-                            $skill['data']['passed'] =  1;
+                            $skill['data']['passed'] = 1;
                         }
                     }
                 } else {
-                    $skill  = null;
+                    $skill = null;
                 }
             }
         }
         return $skills;
     }
 
-    function update_by_skill($params) {
-        $result = Database::update($this->table, $params, array('skill_id = ? '=> $params['skill_id']));
+    function update_by_skill($params)
+    {
+        $result = Database::update($this->table, $params, array('skill_id = ? ' => $params['skill_id']));
         if ($result) {
             return true;
         }
         return false;
     }
 
-    function relation_exists($skill_id, $parent_id) {
-        $result = $this->find('all', array('where'=>array('skill_id = ? AND parent_id = ?' => array($skill_id, $parent_id))));
+    function relation_exists($skill_id, $parent_id)
+    {
+        $result = $this->find(
+            'all',
+            array('where' => array('skill_id = ? AND parent_id = ?' => array($skill_id, $parent_id)))
+        );
         if (!empty($result)) {
             return true;
         }
@@ -159,18 +181,24 @@ class SkillRelSkill extends Model {
     }
 }
 
- /**
+/**
  * @package chamilo.library
  */
-class SkillRelGradebook extends Model {
-    var $columns = array('id', 'gradebook_id','skill_id');
+class SkillRelGradebook extends Model
+{
+    public $columns = array('id', 'gradebook_id', 'skill_id');
 
-    public function __construct() {
+    public function __construct()
+    {
         $this->table = Database::get_main_table(TABLE_MAIN_SKILL_REL_GRADEBOOK);
     }
 
-    public function exists_gradebook_skill($gradebook_id, $skill_id) {
-        $result = $this->find('all', array('where'=>array('gradebook_id = ? AND skill_id = ?' => array($gradebook_id, $skill_id))));
+    public function exists_gradebook_skill($gradebook_id, $skill_id)
+    {
+        $result = $this->find(
+            'all',
+            array('where' => array('gradebook_id = ? AND skill_id = ?' => array($gradebook_id, $skill_id)))
+        );
         if (!empty($result)) {
             return true;
         }
@@ -180,16 +208,25 @@ class SkillRelGradebook extends Model {
     /**
      * Gets an element
      */
-    public function get_skill_info($skill_id, $gradebook_id) {
-        if (empty($skill_id)) { return array(); }
-        $result = Database::select('*',$this->table, array('where'=>array('skill_id = ? AND gradebook_id = ? '=>array($skill_id, $gradebook_id))),'first');
+    public function get_skill_info($skill_id, $gradebook_id)
+    {
+        if (empty($skill_id)) {
+            return array();
+        }
+        $result = Database::select(
+            '*',
+            $this->table,
+            array('where' => array('skill_id = ? AND gradebook_id = ? ' => array($skill_id, $gradebook_id))),
+            'first'
+        );
         return $result;
     }
 
-    public function update_gradebooks_by_skill($skill_id, $gradebook_list) {
-        $original_gradebook_list = $this->find('all', array('where'=>array('skill_id = ?' => array($skill_id))));
-        $gradebooks_to_remove = array();
-        $gradebooks_to_add = array();
+    public function update_gradebooks_by_skill($skill_id, $gradebook_list)
+    {
+        $original_gradebook_list     = $this->find('all', array('where' => array('skill_id = ?' => array($skill_id))));
+        $gradebooks_to_remove        = array();
+        $gradebooks_to_add           = array();
         $original_gradebook_list_ids = array();
 
         if (!empty($original_gradebook_list)) {
@@ -198,33 +235,35 @@ class SkillRelGradebook extends Model {
                     $gradebooks_to_remove[] = $gradebook['id'];
                 }
             }
-            foreach($original_gradebook_list as $gradebook_item) {
+            foreach ($original_gradebook_list as $gradebook_item) {
                 $original_gradebook_list_ids[] = $gradebook_item['gradebook_id'];
             }
         }
 
-        if (!empty($gradebook_list))
-        foreach($gradebook_list as $gradebook_id) {
-            if (!in_array($gradebook_id, $original_gradebook_list_ids)) {
-                $gradebooks_to_add[] = $gradebook_id;
+        if (!empty($gradebook_list)) {
+            foreach ($gradebook_list as $gradebook_id) {
+                if (!in_array($gradebook_id, $original_gradebook_list_ids)) {
+                    $gradebooks_to_add[] = $gradebook_id;
+                }
             }
         }
-
+        //var_dump($gradebooks_to_add, $gradebooks_to_remove);
         if (!empty($gradebooks_to_remove)) {
-            foreach($gradebooks_to_remove as $id) {
-               $this->delete($id);
+            foreach ($gradebooks_to_remove as $id) {
+                $this->delete($id);
             }
         }
 
         if (!empty($gradebooks_to_add)) {
-            foreach($gradebooks_to_add as $gradebook_id) {
-               $attributes = array('skill_id' => $skill_id, 'gradebook_id' => $gradebook_id);
-               $this->save($attributes);
+            foreach ($gradebooks_to_add as $gradebook_id) {
+                $attributes = array('skill_id' => $skill_id, 'gradebook_id' => $gradebook_id);
+                $this->save($attributes);
             }
         }
     }
 
-    function update_by_skill($params) {
+    function update_by_skill($params)
+    {
         $skill_info = $this->exists_gradebook_skill($params['gradebook_id'], $params['skill_id']);
 
         if ($skill_info) {
@@ -239,17 +278,21 @@ class SkillRelGradebook extends Model {
     }
 }
 
- /**
+/**
  * @package chamilo.library
  */
-class SkillRelUser extends Model {
-    var $columns = array('id', 'user_id','skill_id','acquired_skill_at','assigned_by');
-    public function __construct() {
-        $this->table        = Database::get_main_table(TABLE_MAIN_SKILL_REL_USER);
+class SkillRelUser extends Model
+{
+    public $columns = array('id', 'user_id', 'skill_id', 'acquired_skill_at', 'assigned_by');
+
+    public function __construct()
+    {
+        $this->table = Database::get_main_table(TABLE_MAIN_SKILL_REL_USER);
         //$this->table_user   = Database::get_main_table(TABLE_MAIN_USER);
     }
 
-    public function get_user_by_skills($skill_list) {
+    public function get_user_by_skills($skill_list)
+    {
         $users = array();
         if (!empty($skill_list)) {
             $skill_list = array_map('intval', $skill_list);
@@ -263,17 +306,26 @@ class SkillRelUser extends Model {
         return $users;
     }
 
-    public function get_user_skills($user_id) {
-        if (empty($user_id)) { return array(); }
-        $result = Database::select('skill_id',$this->table, array('where'=>array('user_id = ?'=>intval($user_id))), 'all');
+    public function get_user_skills($user_id)
+    {
+        if (empty($user_id)) {
+            return array();
+        }
+        $result = Database::select(
+            'skill_id',
+            $this->table,
+            array('where' => array('user_id = ?' => intval($user_id))),
+            'all'
+        );
         return $result;
     }
 }
 
 
-class Skill extends Model {
-    var $columns  = array('id', 'name','description', 'access_url_id', 'short_code');
-    var $required = array('name');
+class Skill extends Model
+{
+    public $columns = array('id', 'name', 'description', 'access_url_id', 'short_code');
+    public $required = array('name');
 
     /** Array of colours by depth, for the coffee wheel. Each depth has 4 col */
     /*var $colours = array(
@@ -290,27 +342,30 @@ class Skill extends Model {
      10 => array('#393e64', '#393e64', '#393e64', '#393e64'),
     );*/
 
-    public function __construct() {
-        $this->table                      = Database::get_main_table(TABLE_MAIN_SKILL);
-        $this->table_user                      = Database::get_main_table(TABLE_MAIN_USER);
-        $this->table_skill_rel_gradebook  = Database::get_main_table(TABLE_MAIN_SKILL_REL_GRADEBOOK);
-        $this->table_skill_rel_user       = Database::get_main_table(TABLE_MAIN_SKILL_REL_USER);
-        $this->table_course               = Database::get_main_table(TABLE_MAIN_COURSE);
-        $this->table_skill_rel_skill      = Database::get_main_table(TABLE_MAIN_SKILL_REL_SKILL);
-        $this->table_gradebook            = Database::get_main_table(TABLE_MAIN_GRADEBOOK_CATEGORY);
+    public function __construct()
+    {
+        $this->table                     = Database::get_main_table(TABLE_MAIN_SKILL);
+        $this->table_user                = Database::get_main_table(TABLE_MAIN_USER);
+        $this->table_skill_rel_gradebook = Database::get_main_table(TABLE_MAIN_SKILL_REL_GRADEBOOK);
+        $this->table_skill_rel_user      = Database::get_main_table(TABLE_MAIN_SKILL_REL_USER);
+        $this->table_course              = Database::get_main_table(TABLE_MAIN_COURSE);
+        $this->table_skill_rel_skill     = Database::get_main_table(TABLE_MAIN_SKILL_REL_SKILL);
+        $this->table_gradebook           = Database::get_main_table(TABLE_MAIN_GRADEBOOK_CATEGORY);
     }
 
-    function get_skill_info($id) {
+    function get_skill_info($id)
+    {
         $skill_rel_skill = new SkillRelSkill();
         $skill_info = $this->get($id);
         if (!empty($skill_info)) {
-            $skill_info['extra']        = $skill_rel_skill->get_skill_info($id);
-            $skill_info['gradebooks']   = self::get_gradebooks_by_skill($id);
+            $skill_info['extra']      = $skill_rel_skill->get_skill_info($id);
+            $skill_info['gradebooks'] = self::get_gradebooks_by_skill($id);
         }
         return $skill_info;
     }
 
-    function get_skills_info($skill_list) {
+    function get_skills_info($skill_list)
+    {
         $skill_list = array_map('intval', $skill_list);
         $skill_list = implode("', '", $skill_list);
 
@@ -321,7 +376,8 @@ class Skill extends Model {
         return $users;
     }
 
-    function get_all($load_user_data = false, $user_id = false, $id = null, $parent_id = null) {
+    function get_all($load_user_data = false, $user_id = false, $id = null, $parent_id = null)
+    {
         $id_condition = '';
         if (isset($id) && !empty($id)) {
             $id = intval($id);
@@ -346,10 +402,10 @@ class Skill extends Model {
 
         if (Database::num_rows($result)) {
             while ($row = Database::fetch_array($result, 'ASSOC')) {
-                $skill_rel_skill = new SkillRelSkill();
-                $a = $skill_rel_skill->get_skill_parents($row['id']);
-                $row['level'] = count($a)-1;
-                $row['gradebooks'] = self::get_gradebooks_by_skill($row['id']);
+                $skill_rel_skill    = new SkillRelSkill();
+                $a                  = $skill_rel_skill->get_skill_parents($row['id']);
+                $row['level']       = count($a) - 1;
+                $row['gradebooks']  = self::get_gradebooks_by_skill($row['id']);
                 $skills[$row['id']] = $row;
             }
         }
@@ -370,7 +426,7 @@ class Skill extends Model {
         if (!empty($skills) && !empty($parent_id)) {
             foreach ($skills as $skill) {
                 $children = self::get_all($load_user_data, $user_id, $id, $skill['id']);
-                 if (!empty($children)) {
+                if (!empty($children)) {
                     //$skills = array_merge($skills, $children);
                     $skills = $skills + $children;
                 }
@@ -379,7 +435,8 @@ class Skill extends Model {
         return $skills;
     }
 
-    function get_gradebooks_by_skill($skill_id) {
+    function get_gradebooks_by_skill($skill_id)
+    {
         $skill_id = intval($skill_id);
         $sql = "SELECT g.* FROM {$this->table_gradebook} g INNER JOIN {$this->table_skill_rel_gradebook} sg
                     ON g.id = sg.gradebook_id
@@ -390,11 +447,12 @@ class Skill extends Model {
     }
 
     /* Get one level childrens */
-    function get_children($skill_id, $load_user_data = false) {
+    function get_children($skill_id, $load_user_data = false)
+    {
         $skill_rel_skill = new SkillRelSkill();
         if ($load_user_data) {
             $user_id = api_get_user_id();
-            $skills = $skill_rel_skill->get_children($skill_id, true, $user_id);
+            $skills  = $skill_rel_skill->get_children($skill_id, true, $user_id);
         } else {
             $skills = $skill_rel_skill->get_children($skill_id);
         }
@@ -402,7 +460,8 @@ class Skill extends Model {
     }
 
     /* Get all children of the current node (recursive)*/
-    function get_all_children($skill_id) {
+    function get_all_children($skill_id)
+    {
         $skill_rel_skill = new SkillRelSkill();
         $children = $skill_rel_skill->get_children($skill_id);
         foreach ($children as $child) {
@@ -418,10 +477,11 @@ class Skill extends Model {
     /**
      * Gets all parents from from the wanted skill
      */
-    function get_parents($skill_id) {
+    function get_parents($skill_id)
+    {
         $skill_rel_skill = new SkillRelSkill();
-        $skills = $skill_rel_skill->get_skill_parents($skill_id, true);
-        foreach($skills as &$skill) {
+        $skills          = $skill_rel_skill->get_skill_parents($skill_id, true);
+        foreach ($skills as &$skill) {
             $skill['data'] = self::get($skill['skill_id']);
         }
         return $skills;
@@ -430,7 +490,8 @@ class Skill extends Model {
     /**
      * All direct parents
      */
-    function get_direct_parents($skill_id) {
+    function get_direct_parents($skill_id)
+    {
         $skill_rel_skill = new SkillRelSkill();
         $skills = $skill_rel_skill->get_direct_parents($skill_id, true);
         foreach($skills as &$skill) {
@@ -444,7 +505,8 @@ class Skill extends Model {
     /*
      * Adds a new skill
      */
-    public function add($params) {
+    public function add($params)
+    {
         if (!isset($params['parent_id'])) {
             $params['parent_id'] = 1;
         }
@@ -466,10 +528,10 @@ class Skill extends Model {
                 $relation_exists = $skill_rel_skill->relation_exists($skill_id, $parent_id);
                 if (!$relation_exists) {
                     $attributes = array(
-                                    'skill_id'      => $skill_id,
-                                    'parent_id'     => $parent_id,
-                                    'relation_type' => $params['relation_type'],
-                                    //'level'         => $params['level'],
+                        'skill_id'      => $skill_id,
+                        'parent_id'     => $parent_id,
+                        'relation_type' => $params['relation_type'],
+                        //'level'         => $params['level'],
                     );
                     $skill_rel_skill->save($attributes);
                 }
@@ -488,19 +550,21 @@ class Skill extends Model {
         return null;
     }
 
-    public function add_skill_to_user($user_id, $gradebook_id) {
+    public function add_skill_to_user($user_id, $gradebook_id)
+    {
         $skill_gradebook = new SkillRelGradebook();
         $skill_rel_user  = new SkillRelUser();
 
-        $skill_gradebooks = $skill_gradebook->get_all(array('where'=>array('gradebook_id = ?' =>$gradebook_id)));
+        $skill_gradebooks = $skill_gradebook->get_all(array('where' => array('gradebook_id = ?' => $gradebook_id)));
         if (!empty($skill_gradebooks)) {
             foreach ($skill_gradebooks as $skill_gradebook) {
                 $user_has_skill = $this->user_has_skill($user_id, $skill_gradebook['skill_id']);
                 if (!$user_has_skill) {
-                    $params = array(    'user_id'   => $user_id,
-                                        'skill_id'  => $skill_gradebook['skill_id'],
-                                        'acquired_skill_at'  => api_get_utc_datetime(),
-                                   );
+                    $params = array(
+                        'user_id'           => $user_id,
+                        'skill_id'          => $skill_gradebook['skill_id'],
+                        'acquired_skill_at' => api_get_utc_datetime(),
+                    );
                     $skill_rel_user->save($params);
                 }
             }
@@ -508,7 +572,8 @@ class Skill extends Model {
     }
 
     /* Deletes a skill */
-    public function delete($skill_id) {
+    public function delete($skill_id)
+    {
         /*$params = array('skill_id' => $skill_id);
 
         $skill_rel_skill     = new SkillRelSkill();
@@ -525,7 +590,8 @@ class Skill extends Model {
 
     }
 
-    public function edit($params) {
+    public function edit($params)
+    {
         if (!isset($params['parent_id'])) {
             $params['parent_id'] = 1;
         }
@@ -548,10 +614,10 @@ class Skill extends Model {
                 $relation_exists = $skill_rel_skill->relation_exists($skill_id, $parent_id);
                 if (!$relation_exists) {
                     $attributes = array(
-                                    'skill_id'      => $skill_id,
-                                    'parent_id'     => $parent_id,
-                                    'relation_type' => $params['relation_type'],
-                                    //'level'         => $params['level'],
+                        'skill_id'      => $skill_id,
+                        'parent_id'     => $parent_id,
+                        'relation_type' => $params['relation_type'],
+                        //'level'         => $params['level'],
                     );
                     $skill_rel_skill->update_by_skill($attributes);
                 }
@@ -563,14 +629,14 @@ class Skill extends Model {
         return null;
     }
 
-
     /**
-    * Get user's skills
-    *
-    * @param int $userId User's id
-    */
+     * Get user's skills
+     *
+     * @param int $userId User's id
+     */
 
-    public function get_user_skills($user_id, $get_skill_data = false) {
+    public function get_user_skills($user_id, $get_skill_data = false)
+    {
         $user_id = intval($user_id);
         $sql = 'SELECT DISTINCT s.id, s.name FROM '.$this->table_skill_rel_user.' u INNER JOIN '.$this->table.' s
                 ON u.skill_id = s.id
@@ -591,8 +657,9 @@ class Skill extends Model {
         return $clean_skill;
     }
 
-    public function get_skills_tree($user_id = null, $skill_id = null, $return_flat_array = false, $add_root = false) {
-        if ($skill_id == 1 ) {
+    public function get_skills_tree($user_id = null, $skill_id = null, $return_flat_array = false, $add_root = false)
+    {
+        if ($skill_id == 1) {
             $skill_id = 0;
         }
         if (isset($user_id) && !empty($user_id)) {
@@ -701,10 +768,10 @@ class Skill extends Model {
             }
 
             $skills_tree = array(
-                'name'      => get_lang('SkillRootName'),
-                'id'        => 'root',
-                'children'  => $refs['root']['children'],
-                'data'      => array()
+                'name'     => get_lang('SkillRootName'),
+                'id'       => 'root',
+                'children' => $refs['root']['children'],
+                'data'     => array()
             );
         }
         if ($return_flat_array) {
@@ -722,14 +789,16 @@ class Skill extends Model {
      * @param int depth of the skills
      *
      */
-    public function get_skills_tree_json($user_id = null, $skill_id = null, $return_flat_array = false, $main_depth = 2) {
+    public function get_skills_tree_json($user_id = null, $skill_id = null, $return_flat_array = false, $main_depth = 2)
+    {
         $tree = $this->get_skills_tree($user_id, $skill_id, $return_flat_array, true);
         $simple_tree = array();
         if (!empty($tree['children'])) {
             foreach ($tree['children'] as $element) {
-                $simple_tree[] = array( 'name'      => $element['name'],
-                                        'children'  => $this->get_skill_json($element['children'], 1, $main_depth),
-                                        );
+                $simple_tree[] = array(
+                    'name'     => $element['name'],
+                    'children' => $this->get_skill_json($element['children'], 1, $main_depth),
+                );
             }
         }
         //var_dump($simple_tree[0]['children']);
@@ -739,7 +808,8 @@ class Skill extends Model {
     /**
      * Get JSON element
      */
-    public function get_skill_json($subtree, $depth = 1, $max_depth = 2) {
+    public function get_skill_json($subtree, $depth = 1, $max_depth = 2)
+    {
         $simple_sub_tree = array();
         if (is_array($subtree)) {
             $counter = 1;
@@ -749,7 +819,7 @@ class Skill extends Model {
                 $tmp['id'] = $elem['id'];
 
                 if (is_array($elem['children'])) {
-                    $tmp['children'] = $this->get_skill_json($elem['children'], $depth+1, $max_depth);
+                    $tmp['children'] = $this->get_skill_json($elem['children'], $depth + 1, $max_depth);
                 } else {
                     //$tmp['colour'] = $this->colours[$depth][rand(0,3)];
                 }
@@ -773,11 +843,12 @@ class Skill extends Model {
         return null;
     }
 
-    function get_user_skill_ranking($user_id) {
+    function get_user_skill_ranking($user_id)
+    {
         $user_id = intval($user_id);
         $sql = "SELECT count(skill_id) count FROM {$this->table} s INNER JOIN {$this->table_skill_rel_user} su ON (s.id = su.skill_id)
                 WHERE user_id = $user_id";
-        $result = Database::query($sql);
+        $result  = Database::query($sql);
         if (Database::num_rows($result)) {
             $result = Database::fetch_row($result);
             return $result[0];
@@ -785,7 +856,8 @@ class Skill extends Model {
         return false;
     }
 
-    function get_user_list_skill_ranking($start, $limit, $sidx, $sord, $where_condition) {
+    function get_user_list_skill_ranking($start, $limit, $sidx, $sord, $where_condition)
+    {
         $start = intval($start);
         $limit = intval($limit);
         /*  ORDER BY $sidx $sord */
@@ -804,8 +876,9 @@ class Skill extends Model {
         return array();
     }
 
-    function get_user_list_skill_ranking_count() {
-        $sql = "SELECT count(*) FROM (
+    function get_user_list_skill_ranking_count()
+    {
+        $sql    = "SELECT count(*) FROM (
                         SELECT count(distinct 1)
                         FROM {$this->table} s INNER JOIN {$this->table_skill_rel_user} su ON (s.id = su.skill_id)
                         INNER JOIN {$this->table_user} u ON u.user_id = su.user_id
@@ -820,7 +893,8 @@ class Skill extends Model {
         return 0;
     }
 
-    function get_count_skills_by_course($course_code) {
+    function get_count_skills_by_course($course_code)
+    {
         $sql = "SELECT count(skill_id) as count FROM {$this->table_gradebook} g INNER JOIN {$this->table_skill_rel_gradebook} sg ON g.id = sg.gradebook_id
                 WHERE course_code = '$course_code'";
 
@@ -832,32 +906,33 @@ class Skill extends Model {
         return 0;
     }
 
-    function get_courses_by_skill($skill_id) {
+    function get_courses_by_skill($skill_id)
+    {
         $skill_id = intval($skill_id);
         $sql = "SELECT c.title, c.code FROM {$this->table_gradebook} g INNER JOIN {$this->table_skill_rel_gradebook} sg ON g.id = sg.gradebook_id
                  INNER JOIN {$this->table_course} c ON c.code = g.course_code
                  WHERE sg.skill_id = $skill_id";
-        $result = Database::query($sql);
+        $result   = Database::query($sql);
         return Database::store_result($result, 'ASSOC');
     }
 
-
     /**
-    * Return true if the user has the skill
-    *
-    * @param int $userId User's id
-    * @param int $skillId Skill's id
-    * @param int $checkInParents if true, function will search also in parents of the given skill id
-    *
-    * @return bool
-    */
-    public function user_has_skill($user_id, $skill_id) {
+     * Return true if the user has the skill
+     *
+     * @param int $userId User's id
+     * @param int $skillId Skill's id
+     * @param int $checkInParents if true, function will search also in parents of the given skill id
+     *
+     * @return bool
+     */
+    public function user_has_skill($user_id, $skill_id)
+    {
         $skills = $this->get_user_skills($user_id);
-        foreach($skills as $my_skill_id) {
+        foreach ($skills as $my_skill_id) {
             if ($my_skill_id == $skill_id) {
                 return true;
             }
         }
         return false;
     }
-}
+}

+ 118 - 80
main/inc/lib/social.lib.php

@@ -27,18 +27,18 @@ class SocialManager extends UserManager
      * @author isaac flores paz
      * @return array
      */
-    public static function show_list_type_friends () {
-        $friend_relation_list=array();
-        $count_list=0;
+    public static function show_list_type_friends()
+    {
+        $friend_relation_list = array();
         $tbl_my_friend_relation_type = Database :: get_main_table(TABLE_MAIN_USER_FRIEND_RELATION_TYPE);
-        $sql='SELECT id,title FROM '.$tbl_my_friend_relation_type.' WHERE id<>6 ORDER BY id ASC';
-        $result=Database::query($sql);
-        while ($row=Database::fetch_array($result,'ASSOC')) {
-            $friend_relation_list[]=$row;
-        }
-        $count_list=count($friend_relation_list);
-        if ($count_list==0) {
-            $friend_relation_list[]=get_lang('Unknown');
+        $sql = 'SELECT id,title FROM '.$tbl_my_friend_relation_type.' WHERE id<>6 ORDER BY id ASC';
+        $result = Database::query($sql);
+        while ($row = Database::fetch_array($result, 'ASSOC')) {
+            $friend_relation_list[] = $row;
+        }
+        $count_list = count($friend_relation_list);
+        if ($count_list == 0) {
+            $friend_relation_list[] = get_lang('Unknown');
         } else {
             return $friend_relation_list;
         }
@@ -50,10 +50,11 @@ class SocialManager extends UserManager
      * @return int
      * @author isaac flores paz
      */
-    public static function get_relation_type_by_name ($relation_type_name) {
+    public static function get_relation_type_by_name($relation_type_name)
+    {
         $list_type_friend = self::show_list_type_friends();
         foreach ($list_type_friend as $value_type_friend) {
-            if (strtolower($value_type_friend['title'])==$relation_type_name) {
+            if (strtolower($value_type_friend['title']) == $relation_type_name) {
                 return $value_type_friend['id'];
             }
         }
@@ -66,14 +67,22 @@ class SocialManager extends UserManager
      * @param string
      * @author isaac flores paz
      */
-    public static function get_relation_between_contacts ($user_id,$user_friend) {
+    public static function get_relation_between_contacts($user_id, $user_friend)
+    {
         $tbl_my_friend_relation_type = Database :: get_main_table(TABLE_MAIN_USER_FRIEND_RELATION_TYPE);
         $tbl_my_friend = Database :: get_main_table(TABLE_MAIN_USER_REL_USER);
-        $sql= 'SELECT rt.id as id FROM '.$tbl_my_friend_relation_type.' rt ' .
-              'WHERE rt.id=(SELECT uf.relation_type FROM '.$tbl_my_friend.' uf WHERE  user_id='.((int)$user_id).' AND friend_user_id='.((int)$user_friend).' AND uf.relation_type <> '.USER_RELATION_TYPE_RRHH.' )';
-        $res=Database::query($sql);
-        if (Database::num_rows($res)>0) {
-            $row = Database::fetch_array($res,'ASSOC');
+        $sql = 'SELECT rt.id as id FROM '.$tbl_my_friend_relation_type.' rt
+                WHERE rt.id = (
+                    SELECT uf.relation_type FROM '.$tbl_my_friend.' uf
+                    WHERE
+                        user_id='.((int) $user_id).' AND
+                        friend_user_id='.((int) $user_friend).' AND
+                        uf.relation_type <> '.USER_RELATION_TYPE_RRHH.'
+                    LIMIT 1
+                )';
+        $res = Database::query($sql);
+        if (Database::num_rows($res) > 0) {
+            $row = Database::fetch_array($res, 'ASSOC');
             return $row['id'];
         } else {
             return USER_UNKNOW;
@@ -90,12 +99,13 @@ class SocialManager extends UserManager
      * @author Julio Montoya <gugli100@gmail.com> Cleaning code, function renamed, $load_extra_info option added
      * @author isaac flores paz
      */
-    public static function get_friends($user_id, $id_group = null, $search_name = null, $load_extra_info = true) {
-        $list_ids_friends=array();
+    public static function get_friends($user_id, $id_group = null, $search_name = null, $load_extra_info = true)
+    {
+        $list_ids_friends = array();
         $tbl_my_friend = Database :: get_main_table(TABLE_MAIN_USER_REL_USER);
         $tbl_my_user = Database :: get_main_table(TABLE_MAIN_USER);
-        $sql='SELECT friend_user_id FROM '.$tbl_my_friend.' WHERE relation_type NOT IN ('.USER_RELATION_TYPE_DELETED.', '.USER_RELATION_TYPE_RRHH.') AND friend_user_id<>'.((int)$user_id).' AND user_id='.((int)$user_id);
-        if (isset($id_group) && $id_group>0) {
+        $sql = 'SELECT friend_user_id FROM '.$tbl_my_friend.' WHERE relation_type NOT IN ('.USER_RELATION_TYPE_DELETED.', '.USER_RELATION_TYPE_RRHH.') AND friend_user_id<>'.((int) $user_id).' AND user_id='.((int) $user_id);
+        if (isset($id_group) && $id_group > 0) {
             $sql.=' AND relation_type='.$id_group;
         }
         if (isset($search_name)) {
@@ -123,7 +133,6 @@ class SocialManager extends UserManager
         return $list_ids_friends;
     }
 
-
     /**
      * get list web path of contacts by user id
      * @param int user id
@@ -132,13 +141,14 @@ class SocialManager extends UserManager
      * @param array
      * @author isaac flores paz
      */
-    public static function get_list_path_web_by_user_id ($user_id,$id_group=null,$search_name=null) {
+    public static function get_list_path_web_by_user_id($user_id, $id_group = null, $search_name = null)
+    {
         $combine_friend = array();
-        $list_ids = self::get_friends($user_id,$id_group,$search_name);
+        $list_ids = self::get_friends($user_id, $id_group, $search_name);
         if (is_array($list_ids)) {
             foreach ($list_ids as $values_ids) {
-                $list_path_image_friend[] = UserManager::get_user_picture_path_by_id($values_ids['friend_user_id'],'web',false,true);
-                $combine_friend=array('id_friend'=>$list_ids,'path_friend'=>$list_path_image_friend);
+                $list_path_image_friend[] = UserManager::get_user_picture_path_by_id($values_ids['friend_user_id'], 'web', false, true);
+                $combine_friend = array('id_friend' => $list_ids, 'path_friend' => $list_path_image_friend);
             }
         }
         return $combine_friend;
@@ -151,11 +161,12 @@ class SocialManager extends UserManager
      * @param int user id
      * @return array
      */
-    public static function get_list_web_path_user_invitation_by_user_id ($user_id) {
-        $list_ids = self::get_list_invitation_of_friends_by_user_id((int)$user_id);
+    public static function get_list_web_path_user_invitation_by_user_id($user_id)
+    {
+        $list_ids = self::get_list_invitation_of_friends_by_user_id((int) $user_id);
         $list_path_image_friend = array();
         foreach ($list_ids as $values_ids) {
-            $list_path_image_friend[] = UserManager::get_user_picture_path_by_id($values_ids['user_sender_id'],'web',false,true);
+            $list_path_image_friend[] = UserManager::get_user_picture_path_by_id($values_ids['user_sender_id'], 'web', false, true);
         }
         return $list_path_image_friend;
     }
@@ -170,7 +181,8 @@ class SocialManager extends UserManager
      * @author isaac flores paz
      * @author Julio Montoya <gugli100@gmail.com> Cleaning code
      */
-    public static function send_invitation_friend($user_id, $friend_id, $message_title, $message_content) {
+    public static function send_invitation_friend($user_id, $friend_id, $message_title, $message_content)
+    {
         $tbl_message = Database::get_main_table(TABLE_MAIN_MESSAGE);
         $user_id = intval($user_id);
         $friend_id = intval($friend_id);
@@ -178,19 +190,19 @@ class SocialManager extends UserManager
         //Just in case we replace the and \n and \n\r while saving in the DB
         $message_content = str_replace(array("\n", "\n\r"), '<br />', $message_content);
 
-        $clean_message_title   = Database::escape_string($message_title);
+        $clean_message_title = Database::escape_string($message_title);
         $clean_message_content = Database::escape_string($message_content);
 
         $now = api_get_utc_datetime();
 
-        $sql_exist='SELECT COUNT(*) AS count FROM '.$tbl_message.' WHERE user_sender_id='.$user_id.' AND user_receiver_id='.$friend_id.' AND msg_status IN(5,6,7);';
+        $sql_exist = 'SELECT COUNT(*) AS count FROM '.$tbl_message.' WHERE user_sender_id='.$user_id.' AND user_receiver_id='.$friend_id.' AND msg_status IN(5,6,7);';
 
         $res_exist = Database::query($sql_exist);
-        $row_exist = Database::fetch_array($res_exist,'ASSOC');
+        $row_exist = Database::fetch_array($res_exist, 'ASSOC');
 
-        if ($row_exist['count']==0) {
+        if ($row_exist['count'] == 0) {
 
-            $sql=' INSERT INTO '.$tbl_message.'(user_sender_id,user_receiver_id,msg_status,send_date,title,content)
+            $sql = ' INSERT INTO '.$tbl_message.'(user_sender_id,user_receiver_id,msg_status,send_date,title,content)
                    VALUES('.$user_id.','.$friend_id.','.MESSAGE_STATUS_INVITATION_PENDING.',"'.$now.'","'.$clean_message_title.'","'.$clean_message_content.'") ';
             Database::query($sql);
 
@@ -201,11 +213,11 @@ class SocialManager extends UserManager
             return true;
         } else {
             //invitation already exist
-            $sql_if_exist ='SELECT COUNT(*) AS count, id FROM '.$tbl_message.' WHERE user_sender_id='.$user_id.' AND user_receiver_id='.$friend_id.' AND msg_status = 7';
+            $sql_if_exist = 'SELECT COUNT(*) AS count, id FROM '.$tbl_message.' WHERE user_sender_id='.$user_id.' AND user_receiver_id='.$friend_id.' AND msg_status = 7';
             $res_if_exist = Database::query($sql_if_exist);
-            $row_if_exist = Database::fetch_array($res_if_exist,'ASSOC');
-            if ($row_if_exist['count']==1) {
-                $sql_if_exist_up='UPDATE '.$tbl_message.'SET msg_status=5, content = "'.$clean_message_content.'"  WHERE user_sender_id='.$user_id.' AND user_receiver_id='.$friend_id.' AND msg_status = 7 ';
+            $row_if_exist = Database::fetch_array($res_if_exist, 'ASSOC');
+            if ($row_if_exist['count'] == 1) {
+                $sql_if_exist_up = 'UPDATE '.$tbl_message.'SET msg_status=5, content = "'.$clean_message_content.'"  WHERE user_sender_id='.$user_id.' AND user_receiver_id='.$friend_id.' AND msg_status = 7 ';
                 Database::query($sql_if_exist_up);
                 return true;
             } else {
@@ -213,17 +225,19 @@ class SocialManager extends UserManager
             }
         }
     }
+
     /**
      * Get number messages of the inbox
      * @author isaac flores paz
      * @param int user receiver id
      * @return int
      */
-    public static function get_message_number_invitation_by_user_id ($user_receiver_id) {
-        $tbl_message=Database::get_main_table(TABLE_MAIN_MESSAGE);
-        $sql='SELECT COUNT(*) as count_message_in_box FROM '.$tbl_message.' WHERE user_receiver_id='.intval($user_receiver_id).' AND msg_status='.MESSAGE_STATUS_INVITATION_PENDING;
-        $res=Database::query($sql);
-        $row=Database::fetch_array($res,'ASSOC');
+    public static function get_message_number_invitation_by_user_id($user_receiver_id)
+    {
+        $tbl_message = Database::get_main_table(TABLE_MAIN_MESSAGE);
+        $sql = 'SELECT COUNT(*) as count_message_in_box FROM '.$tbl_message.' WHERE user_receiver_id='.intval($user_receiver_id).' AND msg_status='.MESSAGE_STATUS_INVITATION_PENDING;
+        $res = Database::query($sql);
+        $row = Database::fetch_array($res, 'ASSOC');
         return $row['count_message_in_box'];
     }
 
@@ -233,14 +247,15 @@ class SocialManager extends UserManager
      * @param int user id
      * @return array()
      */
-    public static function get_list_invitation_of_friends_by_user_id ($user_id)
+    public static function get_list_invitation_of_friends_by_user_id($user_id)
     {
-        $list_friend_invitation=array();
+        $list_friend_invitation = array();
         $tbl_message = Database::get_main_table(TABLE_MAIN_MESSAGE);
-        $sql = 'SELECT user_sender_id,send_date,title,content FROM '.$tbl_message.'
+        $sql = 'SELECT user_sender_id,send_date,title,content
+                FROM '.$tbl_message.'
                 WHERE user_receiver_id='.intval($user_id).' AND msg_status = '.MESSAGE_STATUS_INVITATION_PENDING;
         $res = Database::query($sql);
-        while ($row = Database::fetch_array($res,'ASSOC')) {
+        while ($row = Database::fetch_array($res, 'ASSOC')) {
             $list_friend_invitation[] = $row;
         }
         return $list_friend_invitation;
@@ -252,30 +267,39 @@ class SocialManager extends UserManager
      * @param int user id
      * @return array()
      */
-
-    public static function get_list_invitation_sent_by_user_id ($user_id) {
-        $list_friend_invitation=array();
-        $tbl_message=Database::get_main_table(TABLE_MAIN_MESSAGE);
-        $sql='SELECT user_receiver_id, send_date,title,content FROM '.$tbl_message.' WHERE user_sender_id = '.intval($user_id).' AND msg_status = '.MESSAGE_STATUS_INVITATION_PENDING;
-        $res=Database::query($sql);
-        while ($row=Database::fetch_array($res,'ASSOC')) {
-            $list_friend_invitation[$row['user_receiver_id']]=$row;
+    public static function get_list_invitation_sent_by_user_id($user_id)
+    {
+        $list_friend_invitation = array();
+        $tbl_message = Database::get_main_table(TABLE_MAIN_MESSAGE);
+        $sql = 'SELECT user_receiver_id, send_date,title,content
+                FROM '.$tbl_message.'
+                WHERE user_sender_id = '.intval($user_id).' AND msg_status = '.MESSAGE_STATUS_INVITATION_PENDING;
+        $res = Database::query($sql);
+        while ($row = Database::fetch_array($res, 'ASSOC')) {
+            $list_friend_invitation[$row['user_receiver_id']] = $row;
         }
         return $list_friend_invitation;
     }
 
     /**
      * Accepts invitation
-     * @param int user sender id
-     * @param int user receiver id
+     * @param int $user_send_id
+     * @param int $user_receiver_id
      * @author isaac flores paz
      * @author Julio Montoya <gugli100@gmail.com> Cleaning code
      */
-    public static function invitation_accepted ($user_send_id,$user_receiver_id) {
-        $tbl_message=Database::get_main_table(TABLE_MAIN_MESSAGE);
-        $sql='UPDATE '.$tbl_message.' SET msg_status='.MESSAGE_STATUS_INVITATION_ACCEPTED.' WHERE user_sender_id='.((int)$user_send_id).' AND user_receiver_id='.((int)$user_receiver_id).';';
+    public static function invitation_accepted($user_send_id, $user_receiver_id)
+    {
+        $tbl_message = Database::get_main_table(TABLE_MAIN_MESSAGE);
+        $sql = "UPDATE $tbl_message
+                SET msg_status = ".MESSAGE_STATUS_INVITATION_ACCEPTED."
+                WHERE
+                    user_sender_id = ".((int) $user_send_id)." AND
+                    user_receiver_id=".((int) $user_receiver_id)." AND
+                    msg_status = ".MESSAGE_STATUS_INVITATION_PENDING;
         Database::query($sql);
     }
+
     /**
      * Denies invitation
      * @param int user sender id
@@ -283,13 +307,17 @@ class SocialManager extends UserManager
      * @author isaac flores paz
      * @author Julio Montoya <gugli100@gmail.com> Cleaning code
      */
-    public static function invitation_denied ($user_send_id,$user_receiver_id) {
-        $tbl_message=Database::get_main_table(TABLE_MAIN_MESSAGE);
-        //$msg_status=7;
-        //$sql='UPDATE '.$tbl_message.' SET msg_status='.$msg_status.' WHERE user_sender_id='.((int)$user_send_id).' AND user_receiver_id='.((int)$user_receiver_id).';';
-        $sql='DELETE FROM '.$tbl_message.' WHERE user_sender_id='.((int)$user_send_id).' AND user_receiver_id='.((int)$user_receiver_id).';';
+    public static function invitation_denied($user_send_id, $user_receiver_id)
+    {
+        $tbl_message = Database::get_main_table(TABLE_MAIN_MESSAGE);
+        $sql = 'DELETE FROM '.$tbl_message.'
+                WHERE
+                    user_sender_id =  '.((int) $user_send_id).' AND
+                    user_receiver_id='.((int) $user_receiver_id).' AND
+                    msg_status = '.MESSAGE_STATUS_INVITATION_PENDING;
         Database::query($sql);
     }
+
     /**
      * allow attach to group
      * @author isaac flores paz
@@ -297,12 +325,15 @@ class SocialManager extends UserManager
      * @param int kind of rating
      * @return void()
      */
-    public static function qualify_friend ($id_friend_qualify,$type_qualify) {
-        $tbl_user_friend=Database::get_main_table(TABLE_MAIN_USER_REL_USER);
-        $user_id=api_get_user_id();
-        $sql='UPDATE '.$tbl_user_friend.' SET relation_type='.((int)$type_qualify).' WHERE user_id='.((int)$user_id).' AND friend_user_id='.((int)$id_friend_qualify).';';
+    public static function qualify_friend($id_friend_qualify, $type_qualify)
+    {
+        $tbl_user_friend = Database::get_main_table(TABLE_MAIN_USER_REL_USER);
+        $user_id = api_get_user_id();
+        $sql = 'UPDATE '.$tbl_user_friend.' SET relation_type='.((int) $type_qualify).'
+                WHERE user_id = '.((int) $user_id).' AND friend_user_id='.(int) $id_friend_qualify;
         Database::query($sql);
     }
+
     /**
      * Sends invitations to friends
      * @author Isaac Flores Paz <isaac.flores.paz@gmail.com>
@@ -310,7 +341,8 @@ class SocialManager extends UserManager
      * @param void
      * @return string message invitation
      */
-    public static function send_invitation_friend_user($userfriend_id, $subject_message = '', $content_message = '') {
+    public static function send_invitation_friend_user($userfriend_id, $subject_message = '', $content_message = '')
+    {
         global $charset;
 
         $user_info = array();
@@ -322,21 +354,21 @@ class SocialManager extends UserManager
             $send_message = MessageManager::send_message($userfriend_id, $subject_message, $content_message);
 
             if ($send_message) {
-                echo Display::display_confirmation_message($succes,true);
+                echo Display::display_confirmation_message($succes, true);
             } else {
-                echo Display::display_error_message(get_lang('ErrorSendingMessage'),true);
+                echo Display::display_error_message(get_lang('ErrorSendingMessage'), true);
             }
             return false;
         } elseif (isset($userfriend_id) && !isset($subject_message)) {
             $count_is_true = false;
-            if (isset($userfriend_id) && $userfriend_id>0) {
+            if (isset($userfriend_id) && $userfriend_id > 0) {
                 $message_title = get_lang('Invitation');
                 $count_is_true = self::send_invitation_friend(api_get_user_id(), $userfriend_id, $message_title, $content_message);
 
                 if ($count_is_true) {
-                    echo Display::display_confirmation_message(api_htmlentities(get_lang('InvitationHasBeenSent'), ENT_QUOTES,$charset),false);
+                    echo Display::display_confirmation_message(api_htmlentities(get_lang('InvitationHasBeenSent'), ENT_QUOTES, $charset), false);
                 } else {
-                    echo Display::display_warning_message(api_htmlentities(get_lang('YouAlreadySentAnInvitation'), ENT_QUOTES,$charset),false);
+                    echo Display::display_warning_message(api_htmlentities(get_lang('YouAlreadySentAnInvitation'), ENT_QUOTES, $charset), false);
                 }
             }
         }
@@ -897,14 +929,20 @@ class SocialManager extends UserManager
         }
     }
 
-    public static function social_wrapper_div($content, $span_count) {
+    /**
+     * @param string $content
+     * @param string $span_count
+     * @return string
+     */
+    public static function social_wrapper_div($content, $span_count)
+    {
         $span_count = intval($span_count);
         $html = '<div class="span'.$span_count.'">';
         $html .= '<div class="well_border">';
         $html .= $content;
         $html .= '</div></div>';
-        return $html;
 
+        return $html;
     }
 
     /**

+ 62 - 28
main/inc/lib/sortable_table.class.php

@@ -114,7 +114,7 @@ class SortableTable extends HTML_Table
      * on one page
      * @param string $default_order_direction The default order direction;
      * either the constant 'ASC' or 'DESC'
-     * @param int $table_id
+     * @param string $table_id
      */
     public function __construct(
         $table_name = 'table',
@@ -130,9 +130,9 @@ class SortableTable extends HTML_Table
         }
         $this->table_id = $table_id;
 
-        parent :: __construct(array( 'id' => $table_id, 'class' => 'table table-striped table-hover table-bordered'));
+        parent::__construct(array('id' => $table_id, 'class' => 'table table-striped table-hover table-bordered'));
         $this->table_name = $table_name;
-        $this->additional_parameters = array ();
+        $this->additional_parameters = array();
         $this->param_prefix = $table_name.'_';
 
         $this->page_nr = isset($_SESSION[$this->param_prefix.'page_nr']) ? intval($_SESSION[$this->param_prefix.'page_nr']) : 1;
@@ -175,8 +175,8 @@ class SortableTable extends HTML_Table
         // Allow to change paginate in multiples tabs
         unset($_SESSION[$this->param_prefix.'per_page']);
 
-        $this->per_page = isset ($_SESSION[$this->param_prefix.'per_page']) ? intval($_SESSION[$this->param_prefix.'per_page']) : $default_items_per_page;
-        $this->per_page = isset ($_GET[$this->param_prefix.'per_page']) ? intval($_GET[$this->param_prefix.'per_page']) : $this->per_page;
+        $this->per_page = isset($_SESSION[$this->param_prefix.'per_page']) ? intval($_SESSION[$this->param_prefix.'per_page']) : $default_items_per_page;
+        $this->per_page = isset($_GET[$this->param_prefix.'per_page']) ? intval($_GET[$this->param_prefix.'per_page']) : $this->per_page;
 
         $_SESSION[$this->param_prefix.'per_page']  = $this->per_page;
         $_SESSION[$this->param_prefix.'direction'] = $this->direction ;
@@ -230,6 +230,9 @@ class SortableTable extends HTML_Table
         return $this->pager;
     }
 
+    /**
+     * Display the table
+     */
     public function display()
     {
         echo $this->return_table();
@@ -443,12 +446,14 @@ class SortableTable extends HTML_Table
      * @param array      options of visibility
      * @param bool       hide navigation optionally
      * @param int        content per page when show navigation (optional)
-     * @param bool         sort data optionally
+     * @param bool       sort data optionally
      * @return string    grid html
      */
     public function display_simple_grid($visibility_options, $hide_navigation = true, $per_page = 20, $sort_data = true, $grid_class = array())
     {
         $empty_table = false;
+        $total = $this->get_total_number_of_items();
+
         if ($this->get_total_number_of_items() == 0) {
             $cols = $this->getColCount();
             //$this->setCellAttributes(1, 0, 'style="font-style: italic;text-align:center;" colspan='.$cols);
@@ -457,10 +462,12 @@ class SortableTable extends HTML_Table
             $empty_table = true;
         }
         $html = '';
+
         if (!$empty_table) {
             // If we show the pagination
             if (!$hide_navigation) {
                 $form = '&nbsp;';
+
                 if ($this->get_total_number_of_items() > $per_page) {
                     if ($per_page > 10) {
                         $form = $this->get_page_select_form();
@@ -564,7 +571,8 @@ class SortableTable extends HTML_Table
     /**
      * Get the HTML-code with the data-table.
      */
-    public function get_table_html() {
+    public function get_table_html()
+    {
         $pager    = $this->get_pager();
         $offset   = $pager->getOffsetByPageId();
         $from     = $offset[0] - 1;
@@ -620,10 +628,10 @@ class SortableTable extends HTML_Table
     }
 
     /**
-     * Get the HTML-code wich represents a form to select how many items a page
+     * Get the HTML-code which represents a form to select how many items a page
      * should contain.
      */
-    public function get_page_select_form ()
+    public function get_page_select_form()
     {
         $total_number_of_items = $this->get_total_number_of_items();
         if ($total_number_of_items <= $this->default_items_per_page) {
@@ -842,10 +850,11 @@ class SortableTable extends HTML_Table
                 $row[0] .= '/>';
             }
         }
-
-        foreach ($row as $index => & $value) {
-            if (empty($value)) {
-                $value = '-';
+        if (is_array($row)) {
+            foreach ($row as & $value) {
+                if (empty($value)) {
+                     $value = '-';
+                }
             }
         }
         return $row;
@@ -876,12 +885,12 @@ class SortableTable extends HTML_Table
      * @param string $direction In which order should the data be sorted (ASC
      * or DESC)
      */
-    public function get_table_data ($from = null, $per_page = null, $column = null, $direction = null, $sort = null)
+    public function get_table_data($from = null, $per_page = null, $column = null, $direction = null, $sort = null)
     {
         if (!is_null($this->get_data_function)) {
             return call_user_func($this->get_data_function, $from, $this->per_page, $this->column, $this->direction);
         }
-        return array ();
+        return array();
     }
 }
 
@@ -902,9 +911,8 @@ class SortableTableFromArray extends SortableTable
      * @param int $default_column
      * @param int $default_items_per_page
      */
-    public function __construct($table_data, $default_column = 1, $default_items_per_page = 20, $tablename = 'tablename')
-    {
-        parent :: __construct ($tablename, null, null, $default_column, $default_items_per_page);
+    public function __construct($table_data, $default_column = 1, $default_items_per_page = 20, $tablename = 'tablename', $get_total_number_function = null) {
+        parent :: __construct ($tablename, $get_total_number_function, null, $default_column, $default_items_per_page);
         $this->table_data = $table_data;
     }
 
@@ -915,7 +923,7 @@ class SortableTableFromArray extends SortableTable
     public function get_table_data($from = 1, $per_page = null, $column = null, $direction = null, $sort = true)
     {
         if ($sort) {
-            $content = TableSort :: sort_table($this->table_data, $this->column, $this->direction == 'ASC' ? SORT_ASC : SORT_DESC);
+            $content = TableSort::sort_table($this->table_data, $this->column, $this->direction == 'ASC' ? SORT_ASC : SORT_DESC);
         } else {
             $content = $this->table_data;
         }
@@ -928,7 +936,11 @@ class SortableTableFromArray extends SortableTable
      */
     public function get_total_number_of_items()
     {
-        return count($this->table_data);
+        if (isset($this->total_number_of_items) && !empty($this->total_number_of_items)) {
+            return $this->total_number_of_items;
+        } else {
+            return count($this->table_data);
+        }
     }
 }
 
@@ -959,7 +971,6 @@ class SortableTableFromArrayConfig extends SortableTable
      * The array containing all data for this table
      */
     private $table_data;
-
     private $doc_filter;
 
     /**
@@ -970,14 +981,23 @@ class SortableTableFromArrayConfig extends SortableTable
      * @param int $tablename Name of the table
      * @param array $column_show An array with binary values 1: we show the column 2: we don't show it
      * @param array $column_order An array of integers that let us decide how the columns are going to be sort.
-     * @param bool special modification to fix the document name order
+     * @param string $direction
+     * @param bool $doc_filter special modification to fix the document name order
      */
-    public function __construct($table_data, $default_column = 1, $default_items_per_page = 20, $tablename = 'tablename', $column_show = null, $column_order = null, $direction = 'ASC', $doc_filter = false)
-    {
+    public function __construct(
+        $table_data,
+        $default_column = 1,
+        $default_items_per_page = 20,
+        $tablename = 'tablename',
+        $column_show = array(),
+        $column_order = array(),
+        $direction = 'ASC',
+        $doc_filter = false
+    ) {
         $this->column_show  = $column_show;
         $this->column_order = $column_order;
         $this->doc_filter   = $doc_filter;
-        parent :: __construct ($tablename, null, null, $default_column, $default_items_per_page, $direction);
+        parent::__construct($tablename, null, null, $default_column, $default_items_per_page, $direction);
         $this->table_data = $table_data;
     }
 
@@ -985,9 +1005,23 @@ class SortableTableFromArrayConfig extends SortableTable
      * Get table data to show on current page
      * @see SortableTable#get_table_data
      */
-    public function get_table_data($from = 1, $per_page = null, $column = null, $direction = null, $sort = true)
-    {
-        $content = TableSort :: sort_table_config($this->table_data, $this->column, $this->direction == 'ASC' ? SORT_ASC : SORT_DESC, $this->column_show, $this->column_order, SORT_REGULAR, $this->doc_filter);
+    public function get_table_data(
+        $from = 1,
+        $per_page = null,
+        $column = null,
+        $direction = null,
+        $sort = true
+    ) {
+        $content = TableSort::sort_table_config(
+            $this->table_data,
+            $this->column,
+            $this->direction == 'ASC' ? SORT_ASC : SORT_DESC,
+            $this->column_show,
+            $this->column_order,
+            SORT_REGULAR,
+            $this->doc_filter
+        );
+
         return array_slice($content, $from, $this->per_page);
     }
 

+ 33 - 38
main/inc/lib/surveymanager.lib.php

@@ -12,7 +12,8 @@
  * Manage the "versioning" of a conditional survey
  * @package chamilo.survey
  * */
-class SurveyTree {
+class SurveyTree
+{
 	public $surveylist;
 	public $plainsurveylist;
 	public $numbersurveys;
@@ -20,7 +21,8 @@ class SurveyTree {
 	/**
 	 * Sets the surveylist and the plainsurveylist
 	 */
-	public function __construct() {
+	public function __construct()
+    {
         // Database table definitions
 		$table_survey 			= Database :: get_course_table(TABLE_SURVEY);
 		$table_survey_question 	= Database :: get_course_table(TABLE_SURVEY_QUESTION);
@@ -32,15 +34,14 @@ class SurveyTree {
 			$search_restriction = ' AND '.$search_restriction;
 		}
 		
-		$course_id = api_get_course_int_id();
-		
+		$course_id = api_get_course_int_id();		
 
 		$sql = "SELECT survey.survey_id , survey.parent_id, survey_version, survey.code as name
 				FROM $table_survey survey LEFT JOIN $table_survey_question  survey_question
 				ON survey.survey_id = survey_question.survey_id , $table_user user
 				WHERE
-					survey.c_id 			=  $course_id AND 
-					survey_question.c_id 	=  $course_id AND 
+					survey.c_id 			=  $course_id AND
+					survey_question.c_id 	=  $course_id AND
 					survey.author 			= user.user_id
 				GROUP BY survey.survey_id";
 
@@ -48,7 +49,7 @@ class SurveyTree {
 		$surveys_parents = array ();
 		$refs = array();
 		$list = array();
-		$last=array();
+		$last = array();
 		$plain_array=array();
 
 		while ($survey = Database::fetch_array($res,'ASSOC'))
@@ -60,18 +61,16 @@ class SurveyTree {
 			$thisref['name'] = $survey['name'];
 			$thisref['id'] = $survey['survey_id'];
 			$thisref['survey_version'] = $survey['survey_version'];
-			if ($survey['parent_id'] == 0)
-			{
+			if ($survey['parent_id'] == 0) {
 				$list[ $survey['survey_id'] ] = &$thisref;
-			}
-			else
-			{
+			} else {
 				$refs[ $survey['parent_id'] ]['children'][ $survey['survey_id'] ] = &$thisref;
 			}
 		}
         $this->surveylist = $list;
         $this->plainsurveylist = $plain_array;
     }
+
 	/**
 	 * This function gets the parent id of a survey
 	 *
@@ -81,53 +80,49 @@ class SurveyTree {
 	 * @author Julio Montoya <gugli100@gmail.com>, Dokeos
 	 * @version September 2008
 	 */
-	public function getParentId ($id) {
+	public function getParentId($id)
+    {
 		$node = $this->plainsurveylist[$id];
-		if (is_array($node)&& !empty($node['parent_id']))
+		if (is_array($node)&& !empty($node['parent_id'])) {
 			return $node['parent_id'];
-		else
+        } else {
 			return -1;
+        }
 	}
+
 	/**
 	 * This function creates a list of all surveys id
 	 * @param  list of nodes
 	 * @return array with the structure survey_id => survey_name
-	 * @author Julio Montoya <gugli100@gmail.com>, Dokeos
+	 * @author Julio Montoya <gugli100@gmail.com>
 	 * @version September 2008
-	 *
 	 */
-	public function createList ($list) {
-		$result=array();
-		if(is_array($list)) {
+	public function createList ($list)
+    {
+		$result = array();
+		if (is_array($list)) {
 			foreach ($list as $key=>$node) {
-				if (is_array($node['children']))
-				{
+				if (isset($node['children']) && is_array($node['children'])) {
 					//echo $key; echo '--<br>';
 					//print_r($node);
 					//echo '<br>';
 					$result[$key]= $node['name'];
-					$re=self::createList($node['children']);
-					if (!empty($re))
-					{
-						if (is_array($re))
-							foreach ($re as $key=>$r)
-							{
-								$result[$key]=''.$r;
-							}
-						else
-						{
+					$re = self::createList($node['children']);
+					if (!empty($re)) {
+						if (is_array($re)) {
+							foreach ($re as $key=>$r) {
+                                $result[$key]=''.$r;
+                            }
+                        } else {
 							$result[]=$re;
 						}
-
 					}
-				}
-				else
-				{
-					//echo $key; echo '-<br>';
+				} else {
 					$result[$key]=$node['name'];
 				}
 			}
 		}
+
 		return $result;
 	}
-}
+}

+ 34 - 25
main/inc/lib/system_announcements.lib.php

@@ -1,11 +1,5 @@
 <?php
 /* For licensing terms, see /license.txt */
-/**
- * @package chamilo.library
- */
-/**
- * Code
- */
 /**
 *	This is the system announcements library.
 *
@@ -329,9 +323,9 @@ class SystemAnnouncementManager
         $visible_guest = 0,
         $lang = null,
         $send_mail = 0,
-        $add_to_calendar = false
+        $add_to_calendar = false,
+        $sendEmailTest = false
     ) {
-
 		$original_content = $content;
 		$a_dateS = explode(' ',$date_start);
 		$a_arraySD = explode('-',$a_dateS[0]);
@@ -349,12 +343,10 @@ class SystemAnnouncementManager
 			Display :: display_normal_message(get_lang('InvalidStartDate'));
 			return false;
 		}
-
 		if (($date_end_to_compare[1] || $date_end_to_compare[2] || $date_end_to_compare[0]) && !checkdate($date_end_to_compare[1], $date_end_to_compare[2], $date_end_to_compare[0])) {
 			Display :: display_normal_message(get_lang('InvalidEndDate'));
 			return false;
 		}
-
 		if (strlen(trim($title)) == 0) {
 			Display::display_normal_message(get_lang('InvalidTitle'));
 			return false;
@@ -381,9 +373,13 @@ class SystemAnnouncementManager
 		$sql = "INSERT INTO ".$db_table." (title,content,date_start,date_end,visible_teacher,visible_student,visible_guest, lang, access_url_id)
 				VALUES ('".$title."','".$content."','".$start."','".$end."','".$visible_teacher."','".$visible_student."','".$visible_guest."',".$langsql.", ".$current_access_url_id.")";
 
-		if ($send_mail==1) {
-			SystemAnnouncementManager::send_system_announcement_by_email($title, $content,$visible_teacher, $visible_student, $lang);
-		}
+        if ($sendEmailTest) {
+            SystemAnnouncementManager::send_system_announcement_by_email($title, $content,$visible_teacher, $visible_student, $lang, true);
+        } else {
+            if ($send_mail == 1) {
+                SystemAnnouncementManager::send_system_announcement_by_email($title, $content,$visible_teacher, $visible_student, $lang);
+            }
+        }
 		$res = Database::query($sql);
 		if ($res === false) {
 			Debug::log_s(mysql_error());
@@ -469,14 +465,17 @@ class SystemAnnouncementManager
 			Display :: display_normal_message(get_lang('InvalidStartDate'));
 			return false;
 		}
+
 		if (($date_end_to_compare[1] || $date_end_to_compare[2] || $date_end_to_compare[0]) && !checkdate($date_end_to_compare[1], $date_end_to_compare[2], $date_end_to_compare[0])) {
 			Display :: display_normal_message(get_lang('InvalidEndDate'));
 			return false;
 		}
-		if( strlen(trim($title)) == 0) {
+
+		if (strlen(trim($title)) == 0) {
 			Display::display_normal_message(get_lang('InvalidTitle'));
 			return false;
 		}
+
 	    $start    = api_get_utc_datetime($date_start);
         $end      = api_get_utc_datetime($date_end);
 
@@ -491,9 +490,13 @@ class SystemAnnouncementManager
 		$sql = "UPDATE ".$db_table." SET lang=$langsql,title='".$title."',content='".$content."',date_start='".$start."',date_end='".$end."', ";
 		$sql .= " visible_teacher = '".$visible_teacher."', visible_student = '".$visible_student."', visible_guest = '".$visible_guest."' , access_url_id = '".api_get_current_access_url_id()."'  WHERE id = ".$id;
 
-		if ($send_mail==1) {
-			SystemAnnouncementManager::send_system_announcement_by_email($title, $content,$visible_teacher, $visible_student, $lang);
-		}
+        if ($sendEmailTest) {
+            SystemAnnouncementManager::send_system_announcement_by_email($title, $content, null, null, $lang, $sendEmailTest);
+        } else {
+            if ($send_mail==1) {
+                SystemAnnouncementManager::send_system_announcement_by_email($title, $content, $visible_teacher, $visible_student, $lang);
+            }
+        }
 		$res = Database::query($sql);
 		if ($res === false) {
 			Debug::log_s(mysql_error());
@@ -501,6 +504,7 @@ class SystemAnnouncementManager
 		}
 		return true;
 	}
+
 	/**
 	 * Deletes an announcement
 	 * @param 	int $id The identifier of the announcement that should be
@@ -524,7 +528,8 @@ class SystemAnnouncementManager
 	 * @param 	int		$id The identifier of the announcement that should be
 	 * @return	object	Object of class StdClass or the required class, containing the query result row
 	 */
-	public static function get_announcement($id) {
+	public static function get_announcement($id)
+    {
 		$db_table = Database :: get_main_table(TABLE_MAIN_SYSTEM_ANNOUNCEMENTS);
 		$id = intval($id);
 		$sql = "SELECT * FROM ".$db_table." WHERE id = ".$id;
@@ -568,19 +573,26 @@ class SystemAnnouncementManager
 	 * @param	string	Language (optional, considered for all languages if left empty)
      * @return  bool    True if the message was sent or there was no destination matching. False on database or e-mail sending error.
 	 */
-	public static function send_system_announcement_by_email($title, $content, $teacher, $student, $language = null)
+	public static function send_system_announcement_by_email($title, $content, $teacher, $student, $language = null, $sendEmailTest = false)
     {
 		global $charset;
 
+        $title = api_html_entity_decode(stripslashes($title), ENT_QUOTES, $charset);
+        $content = api_html_entity_decode(stripslashes(str_replace(array('\r\n', '\n', '\r'),'', $content)), ENT_QUOTES, $charset);
+
+        if ($sendEmailTest) {
+            MessageManager::send_message_simple(api_get_user_id(), $title, $content);
+            return true;
+        }
+
+        $user_table = Database :: get_main_table(TABLE_MAIN_USER);
         if (api_is_multiple_url_enabled()) {
             $current_access_url_id = api_get_current_access_url_id();
             $url_rel_user = Database :: get_main_table(TABLE_MAIN_ACCESS_URL_REL_USER);
             $url_condition = " INNER JOIN $url_rel_user uu ON uu.user_id = u.user_id ";
         }
 
-		$user_table = Database :: get_main_table(TABLE_MAIN_USER);
-
-		if ($teacher <> 0 AND $student == 0) {
+        if ($teacher <> 0 AND $student == 0) {
 			$sql = "SELECT DISTINCT u.user_id FROM $user_table u $url_condition WHERE status = '1' ";
 		}
 
@@ -612,9 +624,6 @@ class SystemAnnouncementManager
 			return false;
 		}
 
-        $title      = api_html_entity_decode(stripslashes($title), ENT_QUOTES, $charset);
-        $content    = api_html_entity_decode(stripslashes(str_replace(array('\r\n', '\n', '\r'),'', $content)), ENT_QUOTES, $charset);
-
         $message_sent = false;
 
 		while ($row = Database::fetch_array($result,'ASSOC')) {

+ 152 - 130
main/inc/lib/table_sort.class.php

@@ -14,64 +14,65 @@ define('SORT_IMAGE', 4);
 /**
  *	@package chamilo.library
  */
-class TableSort {
+class TableSort
+{
+    /**
+    * Sorts 2-dimensional table.
+    * @param array $data The data to be sorted.
+    * @param int $column The column on which the data should be sorted (default = 0)
+    * @param int $direction The direction to sort (SORT_ASC (default) or SORT_DESC)
+    * @param int $type How should data be sorted (SORT_REGULAR, SORT_NUMERIC,
+    * SORT_STRING,SORT_DATE,SORT_IMAGE)
+    * @return array The sorted dataset
+    * @author bart.mollet@hogent.be
+    */
+	public static function sort_table($data, $column = 0, $direction = SORT_ASC, $type = SORT_REGULAR)
+    {
+        if (!is_array($data) || empty($data)) {
+            return array();
+        }
+        if ($column != strval(intval($column))) {
+            // Probably an attack
+            return $data;
+        }
+        if (!in_array($direction, array(SORT_ASC, SORT_DESC))) {
+            // Probably an attack
+            return $data;
+        }
 
-	/**
-	 * Sorts 2-dimensional table.
-	 * @param array $data The data to be sorted.
-	 * @param int $column The column on which the data should be sorted (default = 0)
-	 * @param string $direction The direction to sort (SORT_ASC (default) or SORT_DESC)
-	 * @param constant $type How should data be sorted (SORT_REGULAR, SORT_NUMERIC,
-	 * SORT_STRING,SORT_DATE,SORT_IMAGE)
-	 * @return array The sorted dataset
-	 * @author bart.mollet@hogent.be
-	 */
-	public static function sort_table($data, $column = 0, $direction = SORT_ASC, $type = SORT_REGULAR) {
-		if (!is_array($data) || empty($data)) {
-			return array();
-		}
-		if ($column != strval(intval($column))) {
-			// Probably an attack
-			return $data;
-		}
-		if (!in_array($direction, array(SORT_ASC, SORT_DESC))) {
-			// Probably an attack
-			return $data;
-		}
+        if ($type == SORT_REGULAR) {
+            if (TableSort::is_image_column($data, $column)) {
+                $type = SORT_IMAGE;
+            } elseif (TableSort::is_date_column($data, $column)) {
+                $type = SORT_DATE;
+            } elseif (TableSort::is_numeric_column($data, $column)) {
+                $type = SORT_NUMERIC;
+            } else {
+                $type = SORT_STRING;
+            }
+        }
 
-		if ($type == SORT_REGULAR) {
-			if (TableSort::is_image_column($data, $column)) {
-				$type = SORT_IMAGE;
-			} elseif (TableSort::is_date_column($data, $column)) {
-				$type = SORT_DATE;
-			} elseif (TableSort::is_numeric_column($data, $column)) {
-				$type = SORT_NUMERIC;
-			} else {
-				$type = SORT_STRING;
-			}
-		}
+        $compare_operator = $direction == SORT_ASC ? '>' : '<=';
+        switch ($type) {
+            case SORT_NUMERIC:
+                $compare_function = 'return strip_tags($a['.$column.']) '.$compare_operator.' strip_tags($b['.$column.']);';
+                break;
+            case SORT_IMAGE:
+                $compare_function = 'return api_strnatcmp(api_strtolower(strip_tags($a['.$column.'], "<img>")), api_strtolower(strip_tags($b['.$column.'], "<img>"))) '.$compare_operator.' 0;';
+                break;
+            case SORT_DATE:
+                $compare_function = 'return strtotime(strip_tags($a['.$column.'])) '.$compare_operator.' strtotime(strip_tags($b['.$column.']));';
+                break;
+            case SORT_STRING:
+            default:
+                $compare_function = 'return api_strnatcmp(api_strtolower(strip_tags($a['.$column.'])), api_strtolower(strip_tags($b['.$column.']))) '.$compare_operator.' 0;';
+                break;
+        }
 
-		$compare_operator = $direction == SORT_ASC ? '>' : '<=';
-		switch ($type) {
-			case SORT_NUMERIC:
-				$compare_function = 'return strip_tags($a['.$column.']) '.$compare_operator.' strip_tags($b['.$column.']);';
-				break;
-			case SORT_IMAGE:
-				$compare_function = 'return api_strnatcmp(api_strtolower(strip_tags($a['.$column.'], "<img>")), api_strtolower(strip_tags($b['.$column.'], "<img>"))) '.$compare_operator.' 0;';
-				break;
-			case SORT_DATE:
-				$compare_function = 'return strtotime(strip_tags($a['.$column.'])) '.$compare_operator.' strtotime(strip_tags($b['.$column.']));';
-				break;
-			case SORT_STRING:
-			default:
-				$compare_function = 'return api_strnatcmp(api_strtolower(strip_tags($a['.$column.'])), api_strtolower(strip_tags($b['.$column.']))) '.$compare_operator.' 0;';
-				break;
-		}
-
-		// Sort the content
-		usort($data, create_function('$a, $b', $compare_function));
+        // Sort the content
+        usort($data, create_function('$a, $b', $compare_function));
 
-		return $data;
+        return $data;
 	}
 
 	/**
@@ -85,101 +86,120 @@ class TableSort {
 	 * @return array The sorted dataset
 	 * @author bart.mollet@hogent.be
 	 */
-	public static function sort_table_config($data, $column = 0, $direction = SORT_ASC, $column_show = null, $column_order = null, $type = SORT_REGULAR, $doc_filter = false) {
+	public static function sort_table_config(
+        $data,
+        $column = 0,
+        $direction = SORT_ASC,
+        $column_show = null,
+        $column_order = null,
+        $type = SORT_REGULAR,
+        $doc_filter = false
+    ) {
+        if (!is_array($data) || empty($data)) {
+            return array();
+        }
 
-		if (!is_array($data) || empty($data)) {
-			return array();
-		}
-		if ($column != strval(intval($column))) {
-			// Probably an attack
-			return $data;
-		}
-		if (!in_array($direction, array(SORT_ASC, SORT_DESC))) {
-			// Probably an attack
-			return $data;
-		}
+        if ($column != strval(intval($column))) {
+            // Probably an attack
+            return $data;
+        }
 
-		// Change columns sort
-	 	// Here we say that the real way of how the columns are going to be order is manage by the $column_order array
-	 	if (is_array($column_order)) {
-	 		$column = isset($column_order[$column]) ? $column_order[$column] : $column;
-	 	}
+        if (!in_array($direction, array(SORT_ASC, SORT_DESC))) {
+            // Probably an attack
+            return $data;
+        }
+
+        // Change columns sort
+        // Here we say that the real way of how the columns are going to be order is manage by the $column_order array
+        if (is_array($column_order)) {
+            $column = isset($column_order[$column]) ? $column_order[$column] : $column;
+        }
+
+        if ($type == SORT_REGULAR) {
+            if (TableSort::is_image_column($data, $column)) {
+                $type = SORT_IMAGE;
+            } elseif (TableSort::is_date_column($data, $column)) {
+                $type = SORT_DATE;
+            } elseif (TableSort::is_numeric_column($data, $column)) {
+                $type = SORT_NUMERIC;
+            } else {
+                $type = SORT_STRING;
+            }
+        }
+
+        //This fixes only works in the document tool when ordering by name
+        if ($doc_filter && in_array($type, array(SORT_STRING))) {
+            $folder_to_sort = array();
+            $new_data = array();
+            if (!empty($data)) {
+                foreach ($data as $document) {
+                    if ($document['type'] == 'folder') {
+                      $docs_to_sort[$document['id']]   = api_strtolower($document['name']);
+                    } else {
+                      $folder_to_sort[$document['id']] = api_strtolower($document['name']);
+                    }
+                    $new_data[$document['id']] = $document;
+                }
 
-		if ($type == SORT_REGULAR) {
-			if (TableSort::is_image_column($data, $column)) {
-				$type = SORT_IMAGE;
-			} elseif (TableSort::is_date_column($data, $column)) {
-				$type = SORT_DATE;
-			} elseif (TableSort::is_numeric_column($data, $column)) {
-				$type = SORT_NUMERIC;
-			} else {
-				$type = SORT_STRING;
-			}
-		}
-		
-		//This fixs only works in the document tool when ordering by name
-		if ($doc_filter && in_array($type, array(SORT_STRING))) {
-    		$data_to_sort = $folder_to_sort = array();
-    		$new_data = array();
-    		if (!empty($data)) {
-        		foreach ($data as $document) {
-        		    if ($document['type'] == 'folder') {
-        		      $docs_to_sort[$document['id']]   = api_strtolower($document['name']);
-        		    } else {
-        		      $folder_to_sort[$document['id']] = api_strtolower($document['name']);  
-        		    }
-        		    $new_data[$document['id']] = $document;    		        		     
-        		}   
                 if ($direction == SORT_ASC) {
                     if (!empty($docs_to_sort)) {
-                        api_natrsort($docs_to_sort);
+                        api_natsort($docs_to_sort);
                     }
                     if (!empty($folder_to_sort)) {
-                        api_natrsort($folder_to_sort);
-                    }                
+                        api_natsort($folder_to_sort);
+                    }
                 } else {
                     if (!empty($docs_to_sort)) {
-                        api_natsort($docs_to_sort);
+                        api_natrsort($docs_to_sort);
                     }
                     if (!empty($folder_to_sort)) {
-                        api_natsort($folder_to_sort);
+                        api_natrsort($folder_to_sort);
                     }
                 }
+
                 $new_data_order = array();
                 if (!empty($docs_to_sort)) {
                     foreach($docs_to_sort as $id => $document) {
-                        $new_data_order[] = $new_data[$id];
+                        if (isset($new_data[$id])) {
+                            $new_data_order[] = $new_data[$id];
+                        }
                     }
                 }
+
                 if (!empty($folder_to_sort)) {
                     foreach($folder_to_sort as $id => $document) {
-                        $new_data_order[] = $new_data[$id];
+                        if (isset($new_data[$id])) {
+                            $new_data_order[] = $new_data[$id];
+                        }
                     }
                 }
-                $data = $new_data_order; 		
-    		}              
-		} else {		
-    		$compare_operator = $direction == SORT_ASC ? '>' : '<=';    		
-    		switch ($type) {
-    			case SORT_NUMERIC:
-    				$compare_function = 'return strip_tags($a['.$column.']) '.$compare_operator.' strip_tags($b['.$column.']);';
-    				break;
-    			case SORT_IMAGE:
-    				$compare_function = 'return api_strnatcmp(api_strtolower(strip_tags($a['.$column.'], "<img>")), api_strtolower(strip_tags($b['.$column.'], "<img>"))) '.$compare_operator.' 0;';
-    				break;
-    			case SORT_DATE:
-    				$compare_function = 'return strtotime(strip_tags($a['.$column.'])) '.$compare_operator.' strtotime(strip_tags($b['.$column.']));';
-    				break;
-    			case SORT_STRING:
-    			default:
-    			    $compare_function = 'return api_strnatcmp(api_strtolower(strip_tags($a['.$column.'])), api_strtolower(strip_tags($b['.$column.']))) '.$compare_operator.' 0;';
-    				break;
-    		}		
-        	// Sort the content
-    		usort($data, create_function('$a, $b', $compare_function));
-		}
+                $data = $new_data_order;
+            }
+        } else {
+            $compare_operator = $direction == SORT_ASC ? '>' : '<=';
+
+            switch ($type) {
+                case SORT_NUMERIC:
+                    $compare_function = 'return strip_tags($a['.$column.']) '.$compare_operator.' strip_tags($b['.$column.']);';
+                    break;
+                case SORT_IMAGE:
+                    $compare_function = 'return api_strnatcmp(api_strtolower(strip_tags($a['.$column.'], "<img>")), api_strtolower(strip_tags($b['.$column.'], "<img>"))) '.$compare_operator.' 0;';
+                    break;
+                case SORT_DATE:
+                    $compare_function = 'return strtotime(strip_tags($a['.$column.'])) '.$compare_operator.' strtotime(strip_tags($b['.$column.']));';
+                    break;
+                case SORT_STRING:
+                default:
+                    $compare_function = 'return api_strnatcmp(api_strtolower(strip_tags($a['.$column.'])), api_strtolower(strip_tags($b['.$column.']))) '.$compare_operator.' 0;';
+                    break;
+            }
+
+            // Sort the content
+            usort($data, create_function('$a, $b', $compare_function));
+        }
+
+		if (is_array($column_show) && !empty($column_show)) {
 
-		if (is_array($column_show)) {
 			// We show only the columns data that were set up on the $column_show array
 			$new_order_data = array();
 			$count_data = count($data);
@@ -208,7 +228,8 @@ class TableSort {
 	 * @todo Take locale into account (eg decimal point or comma ?)
 	 * @author bart.mollet@hogent.be
 	 */
-	private static function is_numeric_column(& $data, $column) {
+	private static function is_numeric_column(& $data, $column)
+    {
 		$is_numeric = true;
 		foreach ($data as $index => & $row) {
 			$is_numeric &= is_numeric(strip_tags($row[$column]));
@@ -226,7 +247,8 @@ class TableSort {
 	 * @return bool				TRUE if column contains only dates, FALSE otherwise
 	 * @author bart.mollet@hogent.be
 	 */
-	private static function is_date_column(& $data, $column) {
+	private static function is_date_column(& $data, $column)
+    {
 		$is_date = true;
 		foreach ($data as $index => & $row) {
 			if (strlen(strip_tags($row[$column])) != 0) {
@@ -251,7 +273,8 @@ class TableSort {
 	 * @return bool				TRUE if column contains only images, FALSE otherwise
 	 * @author bart.mollet@hogent.be
 	 */
-	private static function is_image_column(& $data, $column) {
+	private static function is_image_column(& $data, $column)
+    {
 		$is_image = true;
 		foreach ($data as $index => & $row) {
 			$is_image &= strlen(trim(strip_tags($row[$column], '<img>'))) > 0; // at least one img-tag
@@ -262,5 +285,4 @@ class TableSort {
 		}
 		return $is_image;
 	}
-
 }

+ 59 - 0
main/inc/lib/text.lib.php

@@ -629,4 +629,63 @@ class Text
         $number = (int)$number;
         return ($number < 10) ? '0'.$number : $number;
     }
+
+    
+    /**
+     * Transform the file size in a human readable format.
+     *
+     * @param  int      Size of the file in bytes
+     * @return string A human readable representation of the file size
+     */
+    function format_file_size($file_size) {
+        $file_size = intval($file_size);
+        if($file_size >= 1073741824) {
+            $file_size = round($file_size / 1073741824 * 100) / 100 . 'G';
+        } elseif($file_size >= 1048576) {
+            $file_size = round($file_size / 1048576 * 100) / 100 . 'M';
+        } elseif($file_size >= 1024) {
+            $file_size = round($file_size / 1024 * 100) / 100 . 'k';
+        } else {
+            $file_size = $file_size . 'B';
+        }
+        return $file_size;
+    }
+
+    function return_datetime_from_array($array) {
+        $year	 = '0000';
+        $month = $day = $hours = $minutes = $seconds = '00';
+        if (isset($array['Y']) && (isset($array['F']) || isset($array['M']))  && isset($array['d']) && isset($array['H']) && isset($array['i'])) {
+            $year = $array['Y'];
+            $month = isset($array['F'])?$array['F']:$array['M'];
+            if (intval($month) < 10 ) $month = '0'.$month;
+            $day = $array['d'];
+            if (intval($day) < 10 ) $day = '0'.$day;
+            $hours = $array['H'];
+            if (intval($hours) < 10 ) $hours = '0'.$hours;
+            $minutes = $array['i'];
+            if (intval($minutes) < 10 ) $minutes = '0'.$minutes;
+        }
+        if (checkdate($month,$day,$year)) {
+            $datetime = $year.'-'.$month.'-'.$day.' '.$hours.':'.$minutes.':'.$seconds;
+        }
+        return $datetime;
+    }
+
+    /**
+     * Converts an string CLEANYO[admin][amann,acostea]
+     * into an array:
+     *
+     * array(
+     *  CLEANYO
+     *  admin
+     *  amann,acostea
+     * )
+     *
+     * @param $array
+     * @return array
+     */
+    function bracketsToArray($array)
+    {
+        return preg_split('/[\[\]]+/', $array, -1, PREG_SPLIT_NO_EMPTY);
+    }
 }

File diff suppressed because it is too large
+ 609 - 392
main/inc/lib/tracking.lib.php


+ 400 - 129
main/inc/lib/urlmanager.lib.php

@@ -1,9 +1,13 @@
 <?php
 /* For licensing terms, see /license.txt */
 /**
- * This library provides functions for the access_url management.
- * Include/require it in your code to use its functionality.
- * @package chamilo.library
+*	This library provides functions for the access_url management.
+*	Include/require it in your code to use its functionality.
+*
+*	@package chamilo.library
+*/
+/**
+ * Class UrlManager
  */
 class UrlManager
 {
@@ -96,24 +100,22 @@ class UrlManager
      * @param    array    Extra parameters for type > 1
      * @return    boolean if success
      */
-    public static function udpate($url_id, $url, $description, $active, $type, $extra_params)
+    public static function update($url_id, $url, $description, $active, $type, $extra_params)
     {
-        $url_id           = intval($url_id);
-        $table_access_url = Database :: get_main_table(TABLE_MAIN_ACCESS_URL);
-        $tms              = time();
-        $sql              = "UPDATE $table_access_url
+        $url_id = intval($url_id);
+        $table_access_url= Database :: get_main_table(TABLE_MAIN_ACCESS_URL);
+        $tms = time();
+        $sql = "UPDATE $table_access_url
                 SET url 	= '".Database::escape_string($url)."',
                 description = '".Database::escape_string($description)."',
                 active 		= '".Database::escape_string($active)."',
                 created_by 	= '".api_get_user_id()."',
                 tms 		= FROM_UNIXTIME(".$tms.")
                 WHERE id = '$url_id'";
-        $result           = Database::query($sql);
-
+        $result = Database::query($sql);
         return $result;
     }
 
-
     /**
      * Deletes an url
      * @author Julio Montoya
@@ -140,28 +142,28 @@ class UrlManager
     }
 
     /**
-     *
-     * */
+     * @param string $url
+     * @return int
+     */
     public static function url_exist($url)
     {
-        $table_access_url = Database :: get_main_table(TABLE_MAIN_ACCESS_URL);
-        $sql              = "SELECT id FROM $table_access_url WHERE url = '".Database::escape_string($url)."' ";
-        $res              = Database::query($sql);
-        $num              = Database::num_rows($res);
-
+        $table_access_url= Database :: get_main_table(TABLE_MAIN_ACCESS_URL);
+        $sql = "SELECT id FROM $table_access_url WHERE url = '".Database::escape_string($url)."' ";
+        $res = Database::query($sql);
+        $num = Database::num_rows($res);
         return $num;
     }
 
     /**
-     *
-     * */
+     * @param string $url
+     * @return int
+     */
     public static function url_id_exist($url)
     {
-        $table_access_url = Database :: get_main_table(TABLE_MAIN_ACCESS_URL);
-        $sql              = "SELECT id FROM $table_access_url WHERE id = '".Database::escape_string($url)."' ";
-        $res              = Database::query($sql);
-        $num              = Database::num_rows($res);
-
+        $table_access_url= Database :: get_main_table(TABLE_MAIN_ACCESS_URL);
+        $sql = "SELECT id FROM $table_access_url WHERE id = '".Database::escape_string($url)."' ";
+        $res = Database::query($sql);
+        $num = Database::num_rows($res);
         return $num;
     }
 
@@ -172,12 +174,11 @@ class UrlManager
      * */
     public static function url_count()
     {
-        $table_access_url = Database :: get_main_table(TABLE_MAIN_ACCESS_URL);
-        $sql              = "SELECT count(id) as count_result FROM $table_access_url";
-        $res              = Database::query($sql);
-        $url              = Database::fetch_array($res, 'ASSOC');
-        $result           = $url['count_result'];
-
+        $table_access_url= Database :: get_main_table(TABLE_MAIN_ACCESS_URL);
+        $sql = "SELECT count(id) as count_result FROM $table_access_url";
+        $res = Database::query($sql);
+        $url = Database::fetch_array($res,'ASSOC');
+        $result = $url['count_result'];
         return $result;
     }
 
@@ -209,6 +210,7 @@ class UrlManager
     /**
      * Gets the id, url, description, and active status of ALL URLs
      * @author Julio Montoya
+     * @param int $url_id
      * @return array
      * */
     public static function get_url_data_from_id($url_id)
@@ -229,11 +231,13 @@ class UrlManager
         return $row;
     }
 
-    /** Gets the inner join of users and urls table
+    /**
+     * Gets the inner join of users and urls table
      * @author Julio Montoya
      * @param int  access url id
+     * @param string $order_by
      * @return array   Database::store_result of the result
-     * */
+     **/
     public static function get_url_rel_user_data($access_url_id = null, $order_by = null)
     {
         $where              = '';
@@ -248,18 +252,17 @@ class UrlManager
         } else {
             $order_clause = $order_by;
         }
-        $sql    = "SELECT u.user_id, lastname, firstname, username, official_code, access_url_id
+        $sql = "SELECT u.user_id, lastname, firstname, username, official_code, access_url_id
 			FROM $tbl_user u
 			INNER JOIN $table_url_rel_user
 			ON $table_url_rel_user.user_id = u.user_id
 			$where  $order_clause";
         $result = Database::query($sql);
-        $users  = Database::store_result($result);
+        $users = Database::store_result($result);
 
         return $users;
     }
 
-
     /**
      * Gets the inner join of access_url and the course table
      * @author Julio Montoya
@@ -289,6 +292,37 @@ class UrlManager
         return $courses;
     }
 
+    /**
+     * Gets the inner join of access_url and the usergroup table
+     *
+     * @author Julio Montoya
+     * @param int  access url id
+     * @return array   Database::store_result of the result
+     **/
+
+    public static function getUrlRelCourseCategory($access_url_id = null)
+    {
+
+        $table_url_rel = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_COURSE_CATEGORY);
+        $table = Database::get_main_table(TABLE_MAIN_CATEGORY);
+        $where = " WHERE 1=1 ";
+        if (!empty($access_url_id)) {
+            $where .= " AND $table_url_rel.access_url_id = ".intval($access_url_id);
+        }
+        $where .= " AND (parent_id IS NULL) ";
+
+        $sql = "SELECT id, name, access_url_id
+            FROM $table u
+            INNER JOIN $table_url_rel
+            ON $table_url_rel.course_category_id = u.id
+            $where
+            ORDER BY name";
+
+        $result = Database::query($sql);
+        $courses = Database::store_result($result, 'ASSOC');
+        return $courses;
+    }
+
     /** Gets the inner join of access_url and the session table
      * @author Julio Montoya
      * @param int  access url id
@@ -342,87 +376,97 @@ class UrlManager
     }
 
     /**
-     * Checks the relationship between an URL and a User (return the num_rows)
-     * @author Julio Montoya
-     * @param int user id
-     * @param int url id
-     * @return boolean true if success
-     * */
+    * Checks the relationship between an URL and a User (return the num_rows)
+    * @author Julio Montoya
+    * @param int user id
+    * @param int url id
+    * @return boolean true if success
+    * */
     public static function relation_url_user_exist($user_id, $url_id)
     {
-        $table_url_rel_user = Database :: get_main_table(TABLE_MAIN_ACCESS_URL_REL_USER);
-        $sql                = "SELECT user_id FROM $table_url_rel_user WHERE access_url_id = ".Database::escape_string(
-                $url_id
-            )." AND  user_id = ".Database::escape_string($user_id)." ";
-        $result             = Database::query($sql);
-        $num                = Database::num_rows($result);
+        $table_url_rel_user= Database :: get_main_table(TABLE_MAIN_ACCESS_URL_REL_USER);
+        $sql= "SELECT user_id FROM $table_url_rel_user
+               WHERE access_url_id = ".Database::escape_string($url_id)." AND  user_id = ".Database::escape_string($user_id)." ";
+        $result = Database::query($sql);
+        $num = Database::num_rows($result);
 
         return $num;
-    }
+	}
 
     /**
-     * Checks the relationship between an URL and a Course (return the num_rows)
-     * @author Julio Montoya
-     * @param int user id
-     * @param int url id
-     * @return boolean true if success
-     * */
+    * Checks the relationship between an URL and a Course (return the num_rows)
+    * @author Julio Montoya
+    * @param int user id
+    * @param int url id
+    * @return boolean true if success
+    * */
     public static function relation_url_course_exist($course_id, $url_id)
     {
-        $table_url_rel_course = Database :: get_main_table(TABLE_MAIN_ACCESS_URL_REL_COURSE);
-        $sql                  = "SELECT c_id FROM $table_url_rel_course
-                                WHERE access_url_id = ".Database::escape_string(
-                $url_id
-            )." AND c_id = '".Database::escape_string($course_id)."'";
-        $result               = Database::query($sql);
-        $num                  = Database::num_rows($result);
-
+        $table_url_rel_course= Database :: get_main_table(TABLE_MAIN_ACCESS_URL_REL_COURSE);
+        $sql= "SELECT course_code FROM $table_url_rel_course
+               WHERE access_url_id = ".Database::escape_string($url_id)." AND
+                     course_code = '".Database::escape_string($course_id)."'";
+        $result = Database::query($sql);
+        $num = Database::num_rows($result);
         return $num;
     }
 
-
     /**
-     * Checks the relationship between an URL and a Session (return the num_rows)
+     * Checks the relationship between an URL and a UserGr
+     * oup (return the num_rows)
      * @author Julio Montoya
-     * @param int user id
-     * @param int url id
+     * @param int $userGroupId
+     * @param int $urlId
      * @return boolean true if success
      * */
-    public static function relation_url_session_exist($session_id, $url_id)
+    public static function relation_url_usergroup_exist($userGroupId, $urlId)
     {
-        $table_url_rel_session = Database :: get_main_table(TABLE_MAIN_ACCESS_URL_REL_SESSION);
-        $session_id            = intval($session_id);
-        $url_id                = intval($url_id);
-        $sql                   = "SELECT session_id FROM $table_url_rel_session WHERE access_url_id = ".Database::escape_string(
-                $url_id
-            )." AND session_id = ".Database::escape_string($session_id);
-        $result                = Database::query($sql);
-        $num                   = Database::num_rows($result);
-
+        $table = Database :: get_main_table(TABLE_MAIN_ACCESS_URL_REL_USERGROUP);
+        $sql= "SELECT usergroup_id FROM $table
+               WHERE access_url_id = ".Database::escape_string($urlId)." AND
+                     usergroup_id = ".Database::escape_string($userGroupId);
+        $result = Database::query($sql);
+        $num = Database::num_rows($result);
         return $num;
     }
 
+    /**
+    * Checks the relationship between an URL and a Session (return the num_rows)
+    * @author Julio Montoya
+    * @param int user id
+    * @param int url id
+    * @return boolean true if success
+    * */
+    public static function relation_url_session_exist($session_id, $url_id)
+    {
+        $table_url_rel_session= Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_SESSION);
+        $session_id = intval($session_id);
+        $url_id		= intval($url_id);
+        $sql= "SELECT session_id FROM $table_url_rel_session WHERE access_url_id = ".Database::escape_string($url_id)." AND session_id = ".Database::escape_string($session_id);
+        $result 	= Database::query($sql);
+        $num 		= Database::num_rows($result);
+        return $num;
+    }
 
     /**
      * Add a group of users into a group of URLs
      * @author Julio Montoya
      * @param  array of user_ids
      * @param  array of url_ids
+     * @return array
      * */
     public static function add_users_to_urls($user_list, $url_list)
     {
         $table_url_rel_user = Database :: get_main_table(TABLE_MAIN_ACCESS_URL_REL_USER);
-        $result_array       = array();
+        $result_array = array();
 
-        if (is_array($user_list) && is_array($url_list)) {
+        if (is_array($user_list) && is_array($url_list)){
             foreach ($url_list as $url_id) {
                 foreach ($user_list as $user_id) {
-                    $count = UrlManager::relation_url_user_exist($user_id, $url_id);
-                    if ($count == 0) {
-                        $sql    = "INSERT INTO $table_url_rel_user
-		               			SET user_id = ".Database::escape_string(
-                                $user_id
-                            ).", access_url_id = ".Database::escape_string($url_id);
+                    $count = UrlManager::relation_url_user_exist($user_id,$url_id);
+                    if ($count==0) {
+                        $sql = "INSERT INTO $table_url_rel_user
+                                SET user_id = ".Database::escape_string($user_id).", access_url_id = ".Database::escape_string($url_id);
                         $result = Database::query($sql);
                         if ($result) {
                             $result_array[$url_id][$user_id] = 1;
@@ -443,8 +487,9 @@ class UrlManager
      * @author Julio Montoya
      * @param  array of course ids
      * @param  array of url_ids
-     * */
-    public static function add_courses_to_urls($course_list, $url_list)
+     * @return array
+     **/
+    public static function add_courses_to_urls($course_list,$url_list)
     {
         $table_url_rel_course = Database :: get_main_table(TABLE_MAIN_ACCESS_URL_REL_COURSE);
         $result_array         = array();
@@ -472,17 +517,103 @@ class UrlManager
         return $result_array;
     }
 
+    /**
+     * Add a group of user group into a group of URLs
+     * @author Julio Montoya
+     * @param  array of course ids
+     * @param  array of url_ids
+     * @return array
+     **/
+    public static function addCourseCategoryListToUrl($courseCategoryList, $urlList)
+    {
+        $resultArray = array();
+        if (is_array($courseCategoryList) && is_array($urlList)) {
+            foreach ($urlList as $urlId) {
+                foreach ($courseCategoryList as $categoryCourseId) {
+                    $count = self::relationUrlCourseCategoryExist($categoryCourseId, $urlId);
+                    if ($count == 0) {
+                        $result = self::addCourseCategoryToUrl($categoryCourseId, $urlId);
+                        if ($result) {
+                            $resultArray[$urlId][$categoryCourseId] = 1;
+                        } else {
+                            $resultArray[$urlId][$categoryCourseId] = 0;
+                        }
+                    }
+                }
+            }
+        }
+
+        return 	$resultArray;
+    }
+
+    /**
+     * Checks the relationship between an URL and a UserGr
+     * oup (return the num_rows)
+     * @author Julio Montoya
+     * @param int $categoryCourseId
+     * @param int $urlId
+     * @return boolean true if success
+     * */
+    public static function relationUrlCourseCategoryExist($categoryCourseId, $urlId)
+    {
+        $table = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_COURSE_CATEGORY);
+        $sql= "SELECT course_category_id FROM $table
+               WHERE access_url_id = ".Database::escape_string($urlId)." AND
+                     course_category_id = ".Database::escape_string($categoryCourseId);
+        $result = Database::query($sql);
+        $num = Database::num_rows($result);
+        return $num;
+    }
+
+    /**
+     * @param int $userGroupId
+     * @param int $urlId
+     * @return int
+     */
+    public static function addUserGroupToUrl($userGroupId, $urlId)
+    {
+        $urlRelUserGroupTable = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_USERGROUP);
+        $sql = "INSERT INTO $urlRelUserGroupTable
+                SET
+                usergroup_id = '".intval($userGroupId)."',
+                access_url_id = ".intval($urlId);
+        Database::query($sql);
+        return Database::insert_id();
+    }
+
+    /**
+     * @param int $categoryId
+     * @param int $urlId
+     * @return int
+     */
+    public static function addCourseCategoryToUrl($categoryId, $urlId)
+    {
+        $exists = self::relationUrlCourseCategoryExist($categoryId, $urlId);
+        if (empty($exists)) {
+            $table = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_COURSE_CATEGORY);
+
+            $sql = "INSERT INTO $table
+                    SET
+                    course_category_id = '".intval($categoryId)."',
+                    access_url_id = ".intval($urlId);
+            Database::query($sql);
+
+            return Database::insert_id();
+        }
+        return 0;
+    }
 
     /**
      * Add a group of sessions into a group of URLs
      * @author Julio Montoya
      * @param  array of session ids
      * @param  array of url_ids
+     * @return array
      * */
     public static function add_sessions_to_urls($session_list, $url_list)
     {
         $table_url_rel_session = Database :: get_main_table(TABLE_MAIN_ACCESS_URL_REL_SESSION);
-        $result_array          = array();
+        $result_array = array();
 
         if (is_array($session_list) && is_array($url_list)) {
             foreach ($url_list as $url_id) {
@@ -524,15 +655,18 @@ class UrlManager
         $count  = UrlManager::relation_url_user_exist($user_id, $url_id);
         $result = true;
         if (empty($count)) {
-            $sql    = "INSERT INTO $table_url_rel_user (user_id, access_url_id)  VALUES ('".Database::escape_string(
-                    $user_id
-                )."', '".Database::escape_string($url_id)."') ";
+            $sql = "INSERT INTO $table_url_rel_user (user_id, access_url_id)  VALUES ('".Database::escape_string($user_id)."', '".Database::escape_string($url_id)."') ";
             $result = Database::query($sql);
         }
 
         return $result;
     }
 
+    /**
+     * @param string $course_code
+     * @param int $url_id
+     * @return resource
+     */
     public static function add_course_to_url($courseId, $url_id = 1)
     {
         $table_url_rel_course = Database :: get_main_table(TABLE_MAIN_ACCESS_URL_REL_COURSE);
@@ -564,29 +698,26 @@ class UrlManager
         if (empty($url_id)) {
             $url_id = 1;
         }
-        $result     = false;
-        $count      = UrlManager::relation_url_session_exist($session_id, $url_id);
-        $session_id = intval($session_id);
+        $result = false;
+        $count = UrlManager::relation_url_session_exist($session_id, $url_id);
+        $session_id	= intval($session_id);
         if (empty($count) && !empty($session_id)) {
             $url_id = intval($url_id);
-            $sql    = "INSERT INTO $table_url_rel_session
-           			SET session_id = ".Database::escape_string(
-                    $session_id
-                ).", access_url_id = ".Database::escape_string($url_id);
+            $sql = "INSERT INTO $table_url_rel_session
+                    SET session_id = ".Database::escape_string($session_id).", access_url_id = ".Database::escape_string($url_id);
             $result = Database::query($sql);
         }
 
         return $result;
     }
 
-
     /**
-     * Deletes an url and user relationship
-     * @author Julio Montoya
-     * @param int user id
-     * @param int url id
-     * @return boolean true if success
-     * */
+    * Deletes an url and user relationship
+    * @author Julio Montoya
+    * @param int user id
+    * @param int url id
+    * @return boolean true if success
+    * */
     public static function delete_url_rel_user($user_id, $url_id)
     {
         $table_url_rel_user = Database :: get_main_table(TABLE_MAIN_ACCESS_URL_REL_USER);
@@ -625,18 +756,34 @@ class UrlManager
      * @param  int url id
      * @return boolean true if success
      * */
+    public static function deleteUrlRelCourseCategory($userGroupId, $urlId)
+    {
+        $table = Database :: get_main_table(TABLE_MAIN_ACCESS_URL_REL_COURSE_CATEGORY);
+        $sql= "DELETE FROM $table
+               WHERE course_category_id = '".intval($userGroupId)."' AND
+                     access_url_id=".intval($urlId)."  ";
+        $result = Database::query($sql);
+        return $result;
+    }
+
+
+
+    /**
+    * Deletes an url and session relationship
+    * @author Julio Montoya
+    * @param  char  course code
+    * @param  int url id
+    * @return boolean true if success
+    * */
     public static function delete_url_rel_session($session_id, $url_id)
     {
         $table_url_rel_session = Database :: get_main_table(TABLE_MAIN_ACCESS_URL_REL_SESSION);
-        $sql                   = "DELETE FROM $table_url_rel_session WHERE session_id = ".Database::escape_string(
-                $session_id
-            )." AND access_url_id=".Database::escape_string($url_id)."  ";
-        $result                = Database::query($sql, 'ASSOC');
-
+        $sql= "DELETE FROM $table_url_rel_session
+               WHERE session_id = ".Database::escape_string($session_id)." AND access_url_id=".Database::escape_string($url_id)."  ";
+        $result = Database::query($sql,'ASSOC');
         return $result;
     }
 
-
     /**
      * Updates the access_url_rel_user table  with a given user list
      * @author Julio Montoya
@@ -645,10 +792,10 @@ class UrlManager
      * */
     public static function update_urls_rel_user($user_list, $access_url_id)
     {
-        $table_url_rel_user = Database :: get_main_table(TABLE_MAIN_ACCESS_URL_REL_USER);
-        $sql                = "SELECT user_id FROM $table_url_rel_user WHERE access_url_id = ".intval($access_url_id);
-        $result             = Database::query($sql);
-        $existing_users     = array();
+        $table_url_rel_user	= Database :: get_main_table(TABLE_MAIN_ACCESS_URL_REL_USER);
+        $sql = "SELECT user_id FROM $table_url_rel_user WHERE access_url_id = ".intval($access_url_id);
+        $result = Database::query($sql);
+        $existing_users = array();
 
         // Getting all users
         while ($row = Database::fetch_array($result)) {
@@ -684,7 +831,6 @@ class UrlManager
         return array('users_added' => $users_added, 'users_deleted' => $users_deleted);
     }
 
-
     /**
      * Updates the access_url_rel_course table  with a given user list
      * @author Julio Montoya
@@ -720,6 +866,88 @@ class UrlManager
         }
     }
 
+    /**
+     * Updates the access_url_rel_course table  with a given user list
+     * @author Julio Montoya
+     * @param array user list
+     * @param int access_url_id
+     * */
+    public static function update_urls_rel_usergroup($userGroupList, $urlId)
+    {
+        $table = Database :: get_main_table(TABLE_MAIN_ACCESS_URL_REL_USERGROUP);
+
+        $sql = "SELECT usergroup_id FROM $table WHERE access_url_id = ".intval($urlId);
+        $result = Database::query($sql);
+        $existingItems = array();
+
+        while ($row = Database::fetch_array($result)){
+            $existingItems[] = $row['usergroup_id'];
+        }
+
+        // Adding
+        foreach ($userGroupList as $userGroupId) {
+            if (!in_array($userGroupId, $existingItems)) {
+                UrlManager::addUserGroupToUrl($userGroupId, $urlId);
+            }
+        }
+
+        // Deleting old items
+        foreach ($existingItems as $userGroupId) {
+            if (!in_array($userGroupId, $userGroupList)) {
+                UrlManager::delete_url_rel_usergroup($userGroupId, $urlId);
+            }
+        }
+    }
+
+    /**
+     * Updates the access_url_rel_course_category table with a given list
+     * @author Julio Montoya
+     * @param array course category list
+     * @param int access_url_id
+     **/
+    public static function updateUrlRelCourseCategory($list, $urlId)
+    {
+        $table = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_COURSE_CATEGORY);
+
+        $sql = "SELECT course_category_id FROM $table WHERE access_url_id = ".intval($urlId);
+        $result = Database::query($sql);
+        $existingItems = array();
+
+        while ($row = Database::fetch_array($result)){
+            $existingItems[] = $row['course_category_id'];
+        }
+
+        // Adding
+
+        foreach ($list as $id) {
+            UrlManager::addCourseCategoryToUrl($id, $urlId);
+            $categoryInfo = getCategoryById($id);
+            $children = getChildren($categoryInfo['code']);
+            if (!empty($children)) {
+                foreach ($children as $category) {
+                    UrlManager::addCourseCategoryToUrl($category['id'], $urlId);
+                }
+            }
+        }
+
+        // Deleting old items
+        foreach ($existingItems as $id) {
+            if (!in_array($id, $list)) {
+                UrlManager::deleteUrlRelCourseCategory($id, $urlId);
+                $categoryInfo = getCategoryById($id);
+
+                $children = getChildren($categoryInfo['code']);
+                if (!empty($children)) {
+                    foreach ($children as $category) {
+                        UrlManager::deleteUrlRelCourseCategory($category['id'], $urlId);
+                    }
+                }
+            }
+        }
+    }
+
+
+
     /**
      * Updates the access_url_rel_session table with a given user list
      * @author Julio Montoya
@@ -760,7 +988,10 @@ class UrlManager
         }
     }
 
-
+    /**
+     * @param int $user_id
+     * @return array
+     */
     public static function get_access_url_from_user($user_id)
     {
         $table_url_rel_user = Database :: get_main_table(TABLE_MAIN_ACCESS_URL_REL_USER);
@@ -774,30 +1005,70 @@ class UrlManager
         return $url_list;
     }
 
+    /**
+     * @param $session_id
+     * @return array
+     */
     public static function get_access_url_from_session($session_id)
     {
         $table_url_rel_session = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_SESSION);
-        $table_url             = Database :: get_main_table(TABLE_MAIN_ACCESS_URL);
-        $sql                   = "SELECT url, access_url_id FROM $table_url_rel_session url_rel_session INNER JOIN $table_url u
+        $table_url  = Database :: get_main_table(TABLE_MAIN_ACCESS_URL);
+        $sql = "SELECT url, access_url_id FROM $table_url_rel_session url_rel_session INNER JOIN $table_url u
                 ON (url_rel_session.access_url_id = u.id)
                 WHERE session_id = ".Database::escape_string($session_id);
-        $result                = Database::query($sql);
-        $url_list              = Database::store_result($result);
+        $result = Database::query($sql);
+        $url_list = Database::store_result($result);
 
         return $url_list;
     }
 
+   /**
+     * @param string $url
+     * @return bool|mixed|null
+     */
+    public static function get_url_id($url)
+    {
+        $table_access_url= Database :: get_main_table(TABLE_MAIN_ACCESS_URL);
+        $sql = "SELECT id FROM $table_access_url WHERE url = '".Database::escape_string($url)."'";
+        $result = Database::query($sql);
+        $access_url_id = Database::result($result, 0, 0);
+        return $access_url_id;
+    }
 
     /**
      *
-     * */
-    public static function get_url_id($url)
+     * @param string $needle
+     * @return XajaxResponse
+     */
+    public static function searchCourseCategoryAjax($needle)
     {
-        $table_access_url = Database :: get_main_table(TABLE_MAIN_ACCESS_URL);
-        $sql              = "SELECT id FROM $table_access_url WHERE url = '".Database::escape_string($url)."'";
-        $result           = Database::query($sql);
-        $access_url_id    = Database::result($result, 0, 0);
-
-        return $access_url_id;
+        $response = new XajaxResponse();
+        $return = '';
+
+        if (!empty($needle)) {
+            // xajax send utf8 datas... datas in db can be non-utf8 datas
+            $charset = api_get_system_encoding();
+            $needle = api_convert_encoding($needle, $charset, 'utf-8');
+            $needle = Database::escape_string($needle);
+            // search courses where username or firstname or lastname begins likes $needle
+            $sql = 'SELECT id, name FROM '.Database::get_main_table(TABLE_MAIN_CATEGORY).' u
+                    WHERE name LIKE "'.$needle.'%" AND (parent_id IS NULL or parent_id = 0)
+                    ORDER BY name
+                    LIMIT 11';
+            $result = Database::query($sql);
+            $i = 0;
+            while ($data = Database::fetch_array($result)) {
+                $i++;
+                if ($i <= 10) {
+                    $return .= '<a
+                    href="javascript: void(0);"
+                    onclick="javascript: add_user_to_url(\''.addslashes($data['id']).'\',\''.addslashes($data['name']).' \')">'.$data['name'].' </a><br />';
+                } else {
+                    $return .= '...<br />';
+                }
+            }
+        }
+        $response->addAssign('ajax_list_courses', 'innerHTML', api_utf8_encode($return));
+        return $response;
     }
 }

+ 475 - 48
main/inc/lib/usergroup.lib.php

@@ -5,13 +5,9 @@
  * Include/require it in your code to use its features.
  * @package chamilo.library
  */
-/**
- * Code
- */
 
 /**
- * Class
- * @package chamilo.library
+ * Class UserGroup
  */
 class UserGroup extends Model
 {
@@ -40,80 +36,230 @@ class UserGroup extends Model
         $this->table_course = Database::get_main_table(TABLE_MAIN_COURSE);
     }
 
-    public function get_count()
+    /**
+     * @return bool
+     */
+    public function getUseMultipleUrl()
+    {
+        return $this->useMultipleUrl;
+    }
+
+    /**
+     * @return int
+     */
+    public function getTotalCount()
     {
         $row = Database::select('count(*) as count', $this->table, array(), 'first');
+
         return $row['count'];
     }
 
+    /**
+     * @return int
+     */
+    public function get_count()
+    {
+        if ($this->useMultipleUrl) {
+            $urlId = api_get_current_access_url_id();
+            $sql = "SELECT count(u.id) as count FROM ".$this->table." u
+                    INNER JOIN ".$this->access_url_rel_usergroup." a
+                        ON (u.id = a.usergroup_id)
+                    WHERE access_url_id = $urlId
+            ";
+            $result = Database::query($sql);
+            if (Database::num_rows($result)) {
+                $row  = Database::fetch_array($result);
+
+                return $row['count'];
+            }
+
+            return 0;
+        } else {
+            return $this->getTotalCount();
+        }
+    }
+
+    /**
+     * @param int $course_id
+     *
+     * @return mixed
+     */
     public function get_usergroup_by_course_with_data_count($course_id)
     {
-        $row = Database::select('count(*) as count', $this->usergroup_rel_course_table, array('where' => array('course_id = ?' => $course_id)), 'first');
-        return $row['count'];
+        if ($this->useMultipleUrl) {
+            $course_id = intval($course_id);
+            $urlId = api_get_current_access_url_id();
+            $sql = "SELECT count(c.usergroup_id) as count FROM {$this->usergroup_rel_course_table} c
+                    INNER JOIN {$this->access_url_rel_usergroup} a ON (c.usergroup_id = a.usergroup_id)
+                    WHERE access_url_id = $urlId AND course_id = $course_id
+            ";
+            $result = Database::query($sql);
+            if (Database::num_rows($result)) {
+                $row  = Database::fetch_array($result);
+                return $row['count'];
+            }
+
+            return 0;
+        } else {
+            $row = Database::select(
+                'count(*) as count',
+                $this->usergroup_rel_course_table,
+                array('where' => array('course_id = ?' => $course_id)),
+                'first'
+            );
+
+            return $row['count'];
+        }
     }
 
+    /**
+     * @param string $name
+     *
+     * @return mixed
+     */
     public function get_id_by_name($name)
     {
         $row = Database::select('id', $this->table, array('where' => array('name = ?' => $name)), 'first');
+
         return $row['id'];
     }
 
     /**
      * Displays the title + grid
      */
-    function display()
+    public function display()
     {
         // action links
         echo '<div class="actions">';
         echo '<a href="../admin/index.php">'.Display::return_icon('back.png', get_lang('BackTo').' '.get_lang('PlatformAdmin'), '', '32').'</a>';
-
         echo '<a href="'.api_get_self().'?action=add">'.Display::return_icon('new_class.png', get_lang('AddClasses'), '', '32').'</a>';
-
         echo Display::url(Display::return_icon('import_csv.png', get_lang('Import'), array(), ICON_SIZE_MEDIUM), 'usergroup_import.php');
         echo Display::url(Display::return_icon('export_csv.png', get_lang('Export'), array(), ICON_SIZE_MEDIUM), 'usergroup_export.php');
-
         echo '</div>';
         echo Display::grid_html('usergroups');
     }
 
-    function display_teacher_view()
+    /**
+     * Get HTML grid
+     */
+    public function display_teacher_view()
     {
-        // action links
         echo Display::grid_html('usergroups');
     }
 
     /**
      * Gets a list of course ids by user group
-     * @param   int     user group id
+     * @param int user group id
+     * @param array $loadCourseData
      * @return  array
      */
-    public function get_courses_by_usergroup($id)
+    public function get_courses_by_usergroup($id, $loadCourseData = false)
     {
-        $results = Database::select('course_id', $this->usergroup_rel_course_table, array('where' => array('usergroup_id = ?' => $id)));
+        if ($this->useMultipleUrl) {
+            $urlId = api_get_current_access_url_id();
+            $from = $this->usergroup_rel_course_table." c
+                    INNER JOIN {$this->access_url_rel_usergroup} a
+                    ON (a.usergroup_id = c.usergroup_id) ";
+            $whereConditionSql = 'a.usergroup_id = ? AND access_url_id = ? ';
+            $whereConditionValues = array($id, $urlId);
+        } else {
+            $whereConditionSql = 'usergroup_id = ?';
+            $whereConditionValues = array($id);
+            $from = $this->usergroup_rel_course_table." c ";
+        }
+
+        if ($loadCourseData) {
+            $from .= " INNER JOIN {$this->table_course} as course ON c.course_id = course.id";
+        }
+
+        /*
+        if (!empty($conditionsLike)) {
+            $from .= " INNER JOIN {$this->table_course} as course ON c.course_id = course.id";
+            $conditionSql = array();
+            foreach ($conditionsLike as $field => $value) {
+                $conditionSql[] = $field.' LIKE %?%';
+                $whereConditionValues[] = $value;
+            }
+            $whereConditionSql .= ' AND '.implode(' AND ', $conditionSql);
+        }*/
+
+        $where = array('where' => array($whereConditionSql => $whereConditionValues));
+
+        if ($loadCourseData) {
+            $select = 'course.*';
+        } else {
+            $select = 'course_id';
+        }
+
+        $results = Database::select(
+            $select,
+            $from,
+            $where
+        );
+
         $array = array();
         if (!empty($results)) {
             foreach ($results as $row) {
-                $array[] = $row['course_id'];
+                if ($loadCourseData) {
+                    $array[$row['id']] = $row;
+                } else {
+                    $array[] = $row['course_id'];
+                }
             }
         }
+
         return $array;
     }
 
+    /**
+     * @param array $options
+     *
+     * @return array
+     */
     public function get_usergroup_in_course($options = array())
     {
-        $sql = "SELECT u.* FROM {$this->usergroup_rel_course_table} usergroup
-                INNER JOIN  {$this->table} u
-                ON (u.id = usergroup.usergroup_id)
-                INNER JOIN {$this->table_course} c
-                ON (usergroup.course_id = c.id)
-               ";
+        if ($this->useMultipleUrl) {
+            $sql = "SELECT u.* FROM {$this->usergroup_rel_course_table} usergroup
+                    INNER JOIN  {$this->table} u
+                    ON (u.id = usergroup.usergroup_id)
+                    INNER JOIN {$this->table_course} c
+                    ON (usergroup.course_id = c.id)
+                    INNER JOIN {$this->access_url_rel_usergroup} a ON (a.usergroup_id = u.id)
+                   ";
+        } else {
+            $sql = "SELECT u.* FROM {$this->usergroup_rel_course_table} usergroup
+                    INNER JOIN  {$this->table} u
+                    ON (u.id = usergroup.usergroup_id)
+                    INNER JOIN {$this->table_course} c
+                    ON (usergroup.course_id = c.id)
+                   ";
+        }
         $conditions = Database::parse_conditions($options);
         $sql .= $conditions;
+        if ($this->useMultipleUrl) {
+            $urlId = api_get_current_access_url_id();
+            $sql .= " AND access_url_id = $urlId ";
+        }
+
+        if (isset($options['LIMIT'])) {
+            $limits = explode(',', $options['LIMIT']);
+            $limits = array_map('intval', $limits);
+            if (isset($limits[0]) && isset($limits[1])) {
+                $sql .= " LIMIT ".$limits[0].', '.$limits[1];
+            }
+        }
+
         $result = Database::query($sql);
         $array = Database::store_result($result, 'ASSOC');
+
         return $array;
     }
 
+    /**
+     * @param array $options
+     *
+     * @return array|bool
+     */
     public function get_usergroup_not_in_course($options = array())
     {
         $course_id = null;
@@ -125,22 +271,60 @@ class UserGroup extends Model
         if (empty($course_id)) {
             return false;
         }
-        $sql = "SELECT DISTINCT u.id, name
-                FROM {$this->table} u
-                LEFT OUTER JOIN {$this->usergroup_rel_course_table} urc
-                ON (u.id = urc.usergroup_id AND course_id = $course_id)
-               ";
+
+        if ($this->useMultipleUrl) {
+            $urlId = api_get_current_access_url_id();
+            $sql = "SELECT DISTINCT u.id, name
+                    FROM {$this->table} u
+                    INNER JOIN {$this->access_url_rel_usergroup} a
+                    ON (a.usergroup_id = u.id)
+                    LEFT OUTER JOIN {$this->usergroup_rel_course_table} urc
+                    ON (u.id = urc.usergroup_id AND course_id = $course_id)
+            ";
+        } else {
+            $sql = "SELECT DISTINCT u.id, name
+                    FROM {$this->table} u
+                    LEFT OUTER JOIN {$this->usergroup_rel_course_table} urc
+                    ON (u.id = urc.usergroup_id AND course_id = $course_id)
+            ";
+        }
         $conditions = Database::parse_conditions($options);
         $sql .= $conditions;
+
+        if ($this->useMultipleUrl) {
+            $sql .= " AND access_url_id = $urlId";
+        }
+
+        if (isset($options['LIMIT'])) {
+            $limits = explode(',', $options['LIMIT']);
+            $limits = array_map('intval', $limits);
+            if (isset($limits[0]) && isset($limits[1])) {
+                $sql .= " LIMIT ".$limits[0].', '.$limits[1];
+            }
+        }
         $result = Database::query($sql);
         $array = Database::store_result($result, 'ASSOC');
+
         return $array;
     }
 
+    /**
+     * @param int $course_id
+     * @return array
+     */
     public function get_usergroup_by_course($course_id)
     {
-        $options = array('where' => array('course_id = ?' => $course_id));
-        $results = Database::select('usergroup_id', $this->usergroup_rel_course_table, $options);
+        if ($this->useMultipleUrl) {
+            $urlId = api_get_current_access_url_id();
+            $options = array('where' => array('c.course_id = ? AND access_url_id = ?' => array($course_id, $urlId)));
+            $from = $this->usergroup_rel_course_table." as c INNER JOIN ".$this->access_url_rel_usergroup." a
+                    ON c.usergroup_id = a.usergroup_id";
+        } else {
+            $options = array('where' => array('c.course_id = ?' => $course_id));
+            $from = $this->usergroup_rel_course_table." c";
+        }
+
+        $results = Database::select('c.usergroup_id', $from, $options);
         $array = array();
         if (!empty($results)) {
             foreach ($results as $row) {
@@ -150,9 +334,18 @@ class UserGroup extends Model
         return $array;
     }
 
+    /**
+     * @param int $usergroup_id
+     * @param int $course_id
+     * @return bool
+     */
     public function usergroup_was_added_in_course($usergroup_id, $course_id)
     {
-        $results = Database::select('usergroup_id', $this->usergroup_rel_course_table, array('where' => array('course_id = ? AND usergroup_id = ?' => array($course_id, $usergroup_id))));
+        $results = Database::select(
+            'usergroup_id',
+            $this->usergroup_rel_course_table,
+            array('where' => array('course_id = ? AND usergroup_id = ?' => array($course_id, $usergroup_id)))
+        );
         if (empty($results)) {
             return false;
         }
@@ -166,7 +359,12 @@ class UserGroup extends Model
      */
     public function get_sessions_by_usergroup($id)
     {
-        $results = Database::select('session_id', $this->usergroup_rel_session_table, array('where' => array('usergroup_id = ?' => $id)));
+        $results = Database::select(
+            'session_id',
+            $this->usergroup_rel_session_table,
+            array('where' => array('usergroup_id = ?' => $id))
+        );
+
         $array = array();
         if (!empty($results)) {
             foreach ($results as $row) {
@@ -201,10 +399,25 @@ class UserGroup extends Model
     /**
      * Gets the usergroup id list by user id
      * @param   int user id
+     * @return array
      */
-    public function get_usergroup_by_user($id)
+    public function get_usergroup_by_user($userId)
     {
-        $results = Database::select('usergroup_id', $this->usergroup_rel_user_table, array('where' => array('user_id = ?' => $id)));
+        if ($this->useMultipleUrl) {
+            $urlId = api_get_current_access_url_id();
+            $from = $this->usergroup_rel_user_table." u
+                    INNER JOIN {$this->access_url_rel_usergroup} a ON (a.usergroup_id AND u.usergroup_id)";
+            $where =  array('where' => array('user_id = ? AND access_url_id = ? ' => array($userId, $urlId)));
+        } else {
+            $from = $this->usergroup_rel_user_table." u ";
+            $where =  array('where' => array('user_id = ?' => $userId));
+        }
+
+        $results = Database::select(
+            'u.usergroup_id',
+            $from,
+            $where
+        );
         $array = array();
         if (!empty($results)) {
             foreach ($results as $row) {
@@ -219,7 +432,7 @@ class UserGroup extends Model
      * @param   int     usergroup id
      * @param   array   list of session ids
      */
-    function subscribe_sessions_to_usergroup($usergroup_id, $list)
+    public function subscribe_sessions_to_usergroup($usergroup_id, $list)
     {
         $current_list = self::get_sessions_by_usergroup($usergroup_id);
         $user_list = self::get_users_by_usergroup($usergroup_id);
@@ -248,7 +461,10 @@ class UserGroup extends Model
                         SessionManager::unsubscribe_user_from_session($session_id, $user_id);
                     }
                 }
-                Database::delete($this->usergroup_rel_session_table, array('usergroup_id = ? AND session_id = ?' => array($usergroup_id, $session_id)));
+                Database::delete(
+                    $this->usergroup_rel_session_table,
+                    array('usergroup_id = ? AND session_id = ?' => array($usergroup_id, $session_id))
+                );
             }
         }
 
@@ -269,8 +485,9 @@ class UserGroup extends Model
      * Subscribes courses to a group (also adding the members of the group in the course)
      * @param   int     usergroup id
      * @param   array   list of course ids (integers)
+     * @param bool $delete_groups
      */
-    function subscribe_courses_to_usergroup($usergroup_id, $list, $delete_groups = true)
+    public function subscribe_courses_to_usergroup($usergroup_id, $list, $delete_groups = true)
     {
         $current_list = self::get_courses_by_usergroup($usergroup_id);
         $user_list = self::get_users_by_usergroup($usergroup_id);
@@ -305,14 +522,17 @@ class UserGroup extends Model
                         CourseManager::subscribe_user($user_id, $course_info['code']);
                     }
                 }
-
                 $params = array('course_id' => $course_id, 'usergroup_id' => $usergroup_id);
                 Database::insert($this->usergroup_rel_course_table, $params);
             }
         }
     }
 
-    function unsubscribe_courses_from_usergroup($usergroup_id, $delete_items)
+    /**
+     * @param int $usergroup_id
+     * @param bool $delete_items
+     */
+    public function unsubscribe_courses_from_usergroup($usergroup_id, $delete_items)
     {
         //Deleting items
         if (!empty($delete_items)) {
@@ -330,11 +550,12 @@ class UserGroup extends Model
     }
 
     /**
-     * Subscribes users to a group
-     * @param   int     usergroup id
-     * @param   array   list of user ids
+     * Subscribe users to a group
+     * @param int     usergroup id
+     * @param array   list of user ids
+     * @param bool $delete_users_not_present_in_list
      */
-    function subscribe_users_to_usergroup($usergroup_id, $list, $delete_users_not_present_in_list = true)
+    public function subscribe_users_to_usergroup($usergroup_id, $list, $delete_users_not_present_in_list = true)
     {
         $current_list = self::get_users_by_usergroup($usergroup_id);
         $course_list = self::get_courses_by_usergroup($usergroup_id);
@@ -375,7 +596,10 @@ class UserGroup extends Model
                         SessionManager::unsubscribe_user_from_session($session_id, $user_id);
                     }
                 }
-                Database::delete($this->usergroup_rel_user_table, array('usergroup_id = ? AND user_id = ?' => array($usergroup_id, $user_id)));
+                Database::delete(
+                    $this->usergroup_rel_user_table,
+                    array('usergroup_id = ? AND user_id = ?' => array($usergroup_id, $user_id))
+                );
             }
         }
 
@@ -387,6 +611,7 @@ class UserGroup extends Model
                     SessionManager::suscribe_users_to_session($session_id, $new_items, null, false);
                 }
             }
+
             foreach ($new_items as $user_id) {
                 //Adding courses
                 if (!empty($course_list)) {
@@ -401,14 +626,216 @@ class UserGroup extends Model
         }
     }
 
-    function usergroup_exists($name)
+    /**
+     * @param string $name
+     * @return bool
+     */
+    public function usergroup_exists($name)
     {
-        $sql = "SELECT * FROM $this->table WHERE name='".Database::escape_string($name)."'";
+        if ($this->useMultipleUrl) {
+            $urlId = api_get_current_access_url_id();
+            $sql = "SELECT * FROM $this->table u
+                    INNER JOIN {$this->access_url_rel_usergroup} a ON (a.usergroup_id = u.id)
+                    WHERE name = '".Database::escape_string($name)."' AND access_url_id = $urlId";
+        } else {
+            $sql = "SELECT * FROM $this->table WHERE name = '".Database::escape_string($name)."'";
+        }
         $res = Database::query($sql);
         return Database::num_rows($res) != 0;
     }
+    
+    /**
+     * @param int $sidx
+     * @param int $sord
+     * @param int $start
+     * @param int $limit
+     * @return array
+     */
+    public function getUsergroupsPagination($sidx, $sord, $start, $limit)
+    {
+        $sord = in_array(strtolower($sord), array('asc', 'desc')) ? $sord : 'desc';
+
+        $start = intval($start);
+        $limit = intval($limit);
+        if ($this->useMultipleUrl) {
+            $urlId = api_get_current_access_url_id();
+            $from = $this->table." u INNER JOIN {$this->access_url_rel_usergroup} a ON (u.id = a.usergroup_id)";
+            $where = array(' access_url_id = ?' => $urlId);
+        } else {
+            $from = $this->table." u ";
+            $where = array();
+        }
+
+        $result = Database::select(
+            'u.*',
+            $from,
+            array('where' => $where, 'order'=> "name $sord", 'LIMIT'=> "$start , $limit")
+        );
+
+        $new_result = array();
+        if (!empty($result)) {
+            foreach ($result as $group) {
+                $group['sessions']   = count($this->get_sessions_by_usergroup($group['id']));
+                $group['courses']    = count($this->get_courses_by_usergroup($group['id']));
+                $group['users']      = count($this->get_users_by_usergroup($group['id']));
+                $new_result[]        = $group;
+            }
+            $result = $new_result;
+        }
+        $columns = array('id', 'name', 'users', 'courses','sessions');
+
+        if (!in_array($sidx, $columns)) {
+            $sidx = 'name';
+        }
+
+        // Multidimensional sort
+        $result = msort($result, $sidx, $sord);
+
+        return $result;
+    }
+
+    /**
+     * @param array $options
+     * @return array
+     */
+    public function get_all_for_export($options = null)
+    {
+        if ($this->useMultipleUrl) {
+            $urlId = api_get_current_access_url_id();
+            $from = $this->table." u INNER JOIN {$this->access_url_rel_usergroup} a ON (u.id = a.usergroup_id)";
+            $options = array('where' => array('access_url_id = ? ' => $urlId));
+            return Database::select('a.id, name, description', $from, $options);
+        } else {
+            return Database::select('id, name, description', $this->table, $options);
+        }
+    }
+
+    /**
+     * @param string $firstLetter
+     * @return array
+     */
+    public function filterByFirstLetter($firstLetter)
+    {
+        $firstLetter = Database::escape_string($firstLetter);
+        $sql = "SELECT id, name FROM $this->table
+		        WHERE name LIKE '".$firstLetter."%' OR name LIKE '".api_strtolower($firstLetter)."%'
+		        ORDER BY name DESC ";
+
+        $result = Database::query($sql);
+        return Database::store_result($result);
+    }
 
-    function save($values, $show_query = false) {
+    /**
+     * Select user group not in list
+     * @param array $list
+     * @return array
+     */
+    public function getUserGroupNotInList($list)
+    {
+        if (empty($list)) {
+            return array();
+        }
+
+        $list = array_map('intval', $list);
+        $listToString = implode("','", $list);
+
+        $sql = "SELECT * FROM {$this->table} WHERE id NOT IN ('$listToString')";
+        $result = Database::query($sql);
+        return Database::store_result($result, 'ASSOC');
+    }
+
+    /**
+     * @param $params
+     * @param bool $show_query
+     * @return bool|void
+     */
+    public function save($params, $show_query = false)
+    {
+        $id = parent::save($params, $show_query);
+        if ($this->useMultipleUrl) {
+            $this->subscribeToUrl($id, api_get_current_access_url_id());
+        }
+        return $id;
+    }
+
+    /**
+     * @param int $id
+     * @return bool|void
+     */
+    public function delete($id)
+    {
+        $result = parent::delete($id);
+        if ($this->useMultipleUrl) {
+            if ($result) {
+                $this->unsubscribeToUrl($id, api_get_current_access_url_id());
+            }
+        }
+    }
+
+    /**
+     * @param int $id
+     * @param int $urlId
+     */
+    public function subscribeToUrl($id, $urlId)
+    {
+        Database::insert(
+            $this->access_url_rel_usergroup,
+            array(
+                'access_url_id' => $urlId,
+                'usergroup_id' =>$id
+            )
+        );
+    }
+
+    /**
+     * @param int $id
+     * @param int $urlId
+     */
+    public function unsubscribeToUrl($id, $urlId)
+    {
+        Database::delete(
+            $this->access_url_rel_usergroup,
+            array(
+                'access_url_id = ? AND usergroup_id = ? ' => array($urlId, $id)
+            )
+        );
+    }
+
+    public static function searchUserGroupAjax($needle)
+    {
+        $response = new XajaxResponse();
+        $return = '';
+
+        if (!empty($needle)) {
+            // xajax send utf8 datas... datas in db can be non-utf8 datas
+            $charset = api_get_system_encoding();
+            $needle = api_convert_encoding($needle, $charset, 'utf-8');
+            $needle = Database::escape_string($needle);
+            // search courses where username or firstname or lastname begins likes $needle
+            $sql = 'SELECT id, name FROM '.Database::get_main_table(TABLE_USERGROUP).' u
+                    WHERE name LIKE "'.$needle.'%"
+                    ORDER BY name
+                    LIMIT 11';
+            $result = Database::query($sql);
+            $i = 0;
+            while ($data = Database::fetch_array($result)) {
+                $i++;
+                if ($i <= 10) {
+                    $return .= '<a
+                    href="javascript: void(0);"
+                    onclick="javascript: add_user_to_url(\''.addslashes($data['id']).'\',\''.addslashes($data['name']).' \')">'.$data['name'].' </a><br />';
+                } else {
+                    $return .= '...<br />';
+                }
+            }
+        }
+        $response->addAssign('ajax_list_courses','innerHTML', api_utf8_encode($return));
+
+        return $response;
+    }
+
+    function save($values, $show_query = false)
+    {
         $values['updated_on'] = $values['created_on'] = api_get_utc_datetime();
         $values['group_type'] = isset($values['group_type']) ? intval($values['group_type']) : $this->getGroupType();
 

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