Browse Source

Merge branch '1.10.x' into bootstrap

aragonc 10 years ago
parent
commit
2be5f72a35
45 changed files with 550 additions and 2193 deletions
  1. 5 3
      .travis.yml
  2. 2 0
      composer.json
  3. 0 13
      index.php
  4. 2 2
      main/admin/system_announcements.php
  5. 15 6
      main/attendance/attendance_calendar.php
  6. 6 1
      main/auth/courses.php
  7. 23 7
      main/auth/courses_controller.php
  8. 13 9
      main/exercice/exercise_submit.php
  9. 1 1
      main/gradebook/index.php
  10. 25 2
      main/gradebook/lib/be/abstractlink.class.php
  11. 93 81
      main/gradebook/lib/be/category.class.php
  12. 3 3
      main/gradebook/lib/fe/dataform.class.php
  13. 1 1
      main/gradebook/lib/fe/displaygradebook.php
  14. 2 1
      main/gradebook/lib/fe/linkaddeditform.class.php
  15. 3 2
      main/gradebook/lib/flatview_data_generator.class.php
  16. 3 3
      main/group/group.php
  17. 12 12
      main/group/group_space.php
  18. 25 18
      main/inc/global.inc.php
  19. 0 1
      main/inc/lib/add_courses_to_session_functions.lib.php
  20. 4 1
      main/inc/lib/add_many_session_to_category_functions.lib.php
  21. 38 10
      main/inc/lib/api.lib.php
  22. 1 0
      main/inc/lib/formvalidator/Element/Number.php
  23. 1 1
      main/inc/lib/formvalidator/FormValidator.class.php
  24. 1 1
      main/inc/lib/groupmanager.lib.php
  25. 1 1
      main/inc/lib/template.lib.php
  26. 1 0
      main/inc/lib/usermanager.lib.php
  27. 3 3
      main/install/configuration.dist.php
  28. 15 10
      main/newscorm/learnpath.class.php
  29. 2 2
      main/template/default/layout/show_header.tpl
  30. 13 10
      main/work/work.lib.php
  31. 22 2
      plugin/advanced_subscription/ajax/advanced_subscription.ajax.php
  32. 1 0
      plugin/advanced_subscription/config.php
  33. 117 42
      plugin/advanced_subscription/src/AdvancedSubscriptionPlugin.php
  34. 1 0
      plugin/advanced_subscription/src/admin_view.php
  35. 1 8
      plugin/advanced_subscription/src/terms_and_conditions.php
  36. 2 2
      src/Chamilo/UserBundle/Entity/User.php
  37. 81 0
      tests/features/bootstrap/FeatureContext.php
  38. 11 0
      tests/features/createUser.feature
  39. 0 110
      tests/phpunit/classes/AccessTest.class.php
  40. 0 47
      tests/phpunit/classes/AccessurleditcoursestourlTest.lib.php
  41. 0 47
      tests/phpunit/classes/AccessurledituserstourlTest.lib.php
  42. 0 69
      tests/phpunit/classes/AddCourseToSessionTest.lib.php
  43. 0 55
      tests/phpunit/classes/AddManySessionToCategoryFunctionsTest.lib.php
  44. 0 280
      tests/phpunit/classes/AppPluginTest.class.php
  45. 0 1326
      tests/phpunit/classes/UserManagerTest.lib.php

+ 5 - 3
.travis.yml

@@ -1,13 +1,15 @@
 language: php
 
 php:
-  - 5.3
   - 5.4
   - 5.5
 
-before_script: composer install -n
+before_script:
+  - composer --self-update
+  - composer install -n
+  - composer update
 before_install:
   - sudo apt-get update -qq
-  - sudo apt-get install -qq php5-imagick php5-curl
+  - sudo apt-get install -qq php5-imagick php5-curl php5-intl php5-json
 
 script: phpunit -c tests/phpunit

+ 2 - 0
composer.json

@@ -54,6 +54,8 @@
         "sonata-project/user-bundle": "~2.2",
         "fxp/composer-asset-plugin": "~1.0",
 
+        "behat/behat": "3.0.*@stable",
+
         "bower-asset/bootstrap": "3.3.*",
         "bower-asset/fontawesome": "4.3.*",
         "bower-asset/moment": "2.9",

+ 0 - 13
index.php

@@ -26,19 +26,6 @@ if (!api_is_anonymous()) {
     $header_title = " ";
 }
 
-$htmlHeadXtra[] ='
-<script type="text/javascript">
-    $(document).ready(function(){
-        $("#slider").bxSlider({
-            infiniteLoop : true,
-            auto : true,
-            pager : true,
-            autoHover : true,
-            pause : 10000
-        });
-    });
-</script>';
-
 $controller = new IndexManager($header_title);
 
 //Actions

+ 2 - 2
main/admin/system_announcements.php

@@ -97,8 +97,8 @@ switch($action) {
         $values['end']   = date('Y-m-d H:i:s',api_strtotime(api_get_local_time()) + (7 * 24 * 60 * 60));
 
         $values['range'] =
-            substr(api_get_local_time(api_get_local_time()), 0, 16).' / '.
-            substr(api_get_local_time(api_get_local_time()) + (7 * 24 * 60 * 60), 0, 16);
+            substr(api_get_local_time(time()), 0, 16).' / '.
+            substr(api_get_local_time(time() + (7 * 24 * 60 * 60)), 0, 16);
         $action_todo = true;
         break;
     case 'edit':

+ 15 - 6
main/attendance/attendance_calendar.php

@@ -47,13 +47,14 @@ if (isset($error_checkdate) && $error_checkdate) {
     Display::display_error_message($message, false);
 }
 
-$groupList = GroupManager::get_group_list(null, null, 1);
-$groupIdList = array('--');
-foreach ($groupList as $group) {
-    $groupIdList[$group['id']] = $group['name'];
-}
 
 if (isset($action) && $action == 'calendar_add') {
+    $groupList = GroupManager::get_group_list(null, null, 1);
+    $groupIdList = array('--');
+    foreach ($groupList as $group) {
+        $groupIdList[$group['id']] = $group['name'];
+    }
+
     // calendar add form
     $form = new FormValidator(
         'attendance_calendar_add',
@@ -104,6 +105,12 @@ if (isset($action) && $action == 'calendar_add') {
 } else {
     // Calendar list
 
+    $groupList = GroupManager::get_group_list();
+    $groupIdList = array('--');
+    foreach ($groupList as $group) {
+        $groupIdList[$group['id']] = $group['name'];
+    }
+
     echo Display::page_subheader(get_lang('CalendarList'));
     echo '<div class="attendance-calendar-list">';
     if (!empty($attendance_calendar)) {
@@ -131,8 +138,10 @@ if (isset($action) && $action == 'calendar_add') {
                 echo '</div>';
             } else {
                 echo Display::return_icon(
-                        'lp_calendar_event.png', get_lang('DateTime')
+                        'lp_calendar_event.png',
+                        get_lang('DateTime')
                     ).' '.substr($calendar['date_time'], 0, strlen($calendar['date_time'])- 3) .'&nbsp;';
+
                 if (isset($calendar['groups']) && !empty($calendar['groups'])) {
                     foreach ($calendar['groups'] as $group) {
                         echo '&nbsp;'.Display::label($groupIdList[$group['group_id']]);

+ 6 - 1
main/auth/courses.php

@@ -80,7 +80,8 @@ $actions = array(
     'display_courses',
     'display_random_courses',
     'subscribe_user_with_password',
-    'display_sessions'
+    'display_sessions',
+    'subscribe_to_session'
 );
 
 $action = CoursesAndSessionsCatalog::is(CATALOG_SESSIONS) ? 'display_sessions' : 'display_random_courses';
@@ -208,4 +209,8 @@ switch ($action) {
     case 'display_sessions':
         $courses_controller->sessionsList($action, $nameTools, $limit);
         break;
+    case 'subscribe_to_session':
+        SessionManager::suscribe_users_to_session($_GET['session_id'], array($_GET['user_id']));
+        header('Location: courses.php');
+        break;
 }

+ 23 - 7
main/auth/courses_controller.php

@@ -483,14 +483,17 @@ class CoursesController
 
     /**
      * Get a HTML button for subscribe to session
-     * @param string $sessionName The session name
-     * @return string The button
+     * @param string    The session data
+     * @param boolean   Session autosubscription set. False by default.
+     * @return string   The button
      */
-    public function getRegisterInSessionButton($sessionName)
+    public function getRegisterInSessionButton($sessionData, $catalogSessionAutoSubscriptionAllowed = false)
     {
-        $sessionName = urlencode($sessionName);
-
-        $url = api_get_path(WEB_PATH) . "main/inc/email_editor.php?action=subscribe_me_to_session&session=$sessionName";
+        $url = $catalogSessionAutoSubscriptionAllowed ?
+            api_get_path(WEB_CODE_PATH)."auth/courses.php?action=subscribe_to_session&session_id=".
+            intval($sessionData)."&user_id=".api_get_user_id() :
+            api_get_path(WEB_CODE_PATH)."inc/email_editor.php?action=subscribe_me_to_session&session=".
+            Security::remove_XSS($sessionData);
 
         return Display::url(get_lang('Subscribe'), $url, array(
             'class' => 'btn btn-large btn-primary',
@@ -526,6 +529,8 @@ class CoursesController
      */
     public function sessionsList($action, $nameTools, $limit = array())
     {
+        global $_configuration;
+
         $date = isset($_POST['date']) ? $_POST['date'] : date('Y-m-d');
         $hiddenLinks = isset($_GET['hidden_links']) ? intval($_GET['hidden_links']) == 1 : false;
 
@@ -546,6 +551,14 @@ class CoursesController
         // Get session search catalogue URL
         $courseUrl = getCourseCategoryUrl(1, $limit['length'], null, 0, 'subscribe');
 
+        $key = 'name';
+        $catalogSessionAutoSubscriptionAllowed = false;
+        if (isset($_configuration['catalog_allow_session_auto_subscription']) &&
+            $_configuration['catalog_allow_session_auto_subscription']) {
+            $key = 'id';
+            $catalogSessionAutoSubscriptionAllowed = true;
+        }
+
         foreach ($sessions as $session) {
             $sessionsBlock = array(
                 'id' => $session['id'],
@@ -556,7 +569,10 @@ class CoursesController
                 'is_subscribed' => $session['is_subscribed'],
                 'icon' => $this->getSessionIcon($session['name']),
                 'date' => SessionManager::getSessionFormattedDate($session),
-                'subscribe_button' => $this->getRegisterInSessionButton($session['name']),
+                'subscribe_button' => $this->getRegisterInSessionButton(
+                    $session[$key],
+                    $catalogSessionAutoSubscriptionAllowed
+                ),
                 'showDescription' => $session['show_description']
             );
 

+ 13 - 9
main/exercice/exercise_submit.php

@@ -895,11 +895,13 @@ if (!empty($error)) {
             var hotspot = $(\'*[name*="hotspot[\'+question_id+\']"]\').serialize();
 
             // Checking FCK
-            if (CKEDITOR.instances["choice["+question_id+"]"]) {
-                fck_content = CKEDITOR.instances["choice["+question_id+"]"].getData();
-                my_choice = {};
-                my_choice["choice["+question_id+"]"] = fck_content;
-                my_choice = $.param(my_choice);
+            if (question_id) {
+                if (CKEDITOR.instances["choice["+question_id+"]"]) {
+                    var ckContent = CKEDITOR.instances["choice["+question_id+"]"].getData();
+                    my_choice = {};
+                    my_choice["choice["+question_id+"]"] = ckContent;
+                    my_choice = $.param(my_choice);
+                }
             }
 
             if ($(\'input[name="remind_list[\'+question_id+\']"]\').is(\':checked\')) {
@@ -964,9 +966,11 @@ if (!empty($error)) {
 
             $.each(question_list, function(index, my_question_id) {
                 // Checking FCK
-                if (CKEDITOR.instances["choice["+question_id+"]"]) {
-                    fck_content = CKEDITOR.instances["choice["+question_id+"]"].getData();
-                    free_answers["free_choice["+my_question_id+"]"] = fck_content;
+                if (my_question_id) {
+                    if (CKEDITOR.instances["choice["+my_question_id+"]"]) {
+                        var ckContent = CKEDITOR.instances["choice["+my_question_id+"]"].getData();
+                        free_answers["free_choice["+my_question_id+"]"] = ckContent;
+                    }
                 }
             });
 
@@ -1084,7 +1088,7 @@ if (!empty($error)) {
                 $exercise_actions .= $objExercise->show_button($questionId, $current_question);
                 break;
             case ALL_ON_ONE_PAGE :
-                $button  = '<a href="javascript://" class="btn" onclick="save_now(\''.$questionId.'\'); ">'.get_lang('SaveForNow').'</a>';
+                $button  = '<a href="javascript://" class="btn btn-info" onclick="save_now(\''.$questionId.'\'); ">'.get_lang('SaveForNow').'</a>';
                 $button .= '<span id="save_for_now_'.$questionId.'"></span>&nbsp;';
                 $exercise_actions  .= Display::div($button, array('class'=>'exercise_save_now_button'));
                 break;

+ 1 - 1
main/gradebook/index.php

@@ -801,7 +801,7 @@ if (isset($first_time) && $first_time==1 && api_is_allowed_to_edit(null,true)) {
                 if (!empty($grade_models)) {
                     $form_grade = new FormValidator('grade_model_settings');
                     $obj->fill_grade_model_select_in_form($form_grade, 'grade_model_id', $grade_model_id);
-                    $form_grade->addElement('style_submit_button', 'submit', get_lang('Save'), 'class="save"');
+                    $form->addButtonSave(get_lang('Save'));
 
                     if ($form_grade->validate()) {
                         $value = $form_grade->exportValue('grade_model_id');

+ 25 - 2
main/gradebook/lib/be/abstractlink.class.php

@@ -19,6 +19,7 @@ abstract class AbstractLink implements GradebookItem
     protected $ref_id;
     protected $user_id;
     protected $course_code;
+    /** @var Category */
     protected $category;
     protected $created_at;
     protected $weight;
@@ -26,36 +27,57 @@ abstract class AbstractLink implements GradebookItem
     protected $session_id;
     public $course_id;
 
+    /**
+     * Constructor
+     */
     public function __construct()
     {
         $this->course_id = api_get_course_int_id();
     }
 
+    /**
+     * @return int
+     */
     public function get_id()
     {
         return $this->id;
     }
 
+    /**
+     * @return string
+     */
     public function get_type()
     {
         return $this->type;
     }
 
+    /**
+     * @return int
+     */
     public function get_ref_id()
     {
         return $this->ref_id;
     }
 
+    /**
+     * @return int
+     */
     public function get_session_id()
     {
         return $this->session_id;
     }
 
+    /**
+     * @return int
+     */
     public function get_user_id()
     {
         return $this->user_id;
     }
 
+    /**
+     * @return string
+     */
     public function get_course_code()
     {
         return $this->course_code;
@@ -306,7 +328,7 @@ abstract class AbstractLink implements GradebookItem
             $sql = "SELECT count(*) FROM ".$tbl_grade_links."
                     WHERE
                         ref_id=".$this->get_ref_id()." AND
-                        category_id =  ".$this->category." AND
+                        category_id =  ".$this->category->get_id()." AND
                         course_code = '".$this->course_code."' AND
                         type =  ".$this->type." ";
 
@@ -332,6 +354,7 @@ abstract class AbstractLink implements GradebookItem
         } else {
             die('Error in AbstractLink add: required field empty');
         }
+
         return false;
     }
 
@@ -409,7 +432,7 @@ abstract class AbstractLink implements GradebookItem
 
         $crscats = Category::load(null,null,$this->get_course_code(),0);
         foreach ($crscats as $cat) {
-            $targets[] = array ($cat->get_id(), $cat->get_name(), $level+1);
+            $targets[] = array($cat->get_id(), $cat->get_name(), $level+1);
             $targets = $this->add_target_subcategories($targets, $level+1, $cat->get_id());
         }
 

+ 93 - 81
main/gradebook/lib/be/category.class.php

@@ -1762,10 +1762,6 @@ class Category implements GradebookItem
             return false;
         }
 
-        $alleval_course = $category->get_evaluations($user_id, true);
-        $alllink_course = $category->get_links($user_id, true);
-        $evals_links = array_merge($alleval_course, $alllink_course);
-
         //@todo move these in a function
         $sum_categories_weight_array = array();
         if (isset($cats_course) && !empty($cats_course)) {
@@ -1781,21 +1777,6 @@ class Category implements GradebookItem
 
         $main_weight = $cats_course[0]->get_weight();
 
-        $item_total_value = 0;
-        for ($count=0; $count < count($evals_links); $count++) {
-            /** @var AbstractLink $item */
-            $item = $evals_links[$count];
-            $score = $item->calc_score($user_id);
-            $item_value = 0;
-            if (!empty($score)) {
-                $divide = $score[1] == 0 ? 1 : $score[1];
-                $item_value = $score[0] / $divide * $item->get_weight();
-            }
-            $item_total_value += $item_value;
-        }
-
-        $item_total_value = (float)$item_total_value;
-
         $cattotal = Category::load($category_id);
         $scoretotal = $cattotal[0]->calc_score($user_id);
 
@@ -1804,77 +1785,72 @@ class Category implements GradebookItem
         $scoredisplay = ScoreDisplay::instance();
         $my_score_in_gradebook = $scoredisplay->display_score($scoretotal, SCORE_SIMPLE);
 
-        // Show certificate
-        $certificate_min_score = $cats_course[0]->get_certificate_min_score();
-
         // A student always sees only the teacher's repartition
         $scoretotal_display = $scoredisplay->display_score($scoretotal, SCORE_DIV_PERCENT);
 
-        if (isset($certificate_min_score) &&
-            $item_total_value >= $certificate_min_score
-        ) {
+        if (!self::userFinishedCourse($user_id, $cats_course[0])) {
+            return false;
+        }
+
+        $my_certificate = GradebookUtils::get_certificate_by_user_id($cats_course[0]->get_id(), $user_id);
+        if (empty($my_certificate)) {
+            GradebookUtils::register_user_info_about_certificate(
+                $category_id,
+                $user_id,
+                $my_score_in_gradebook,
+                api_get_utc_datetime()
+            );
             $my_certificate = GradebookUtils::get_certificate_by_user_id($cats_course[0]->get_id(), $user_id);
-            if (empty($my_certificate)) {
-                GradebookUtils::register_user_info_about_certificate(
-                    $category_id,
-                    $user_id,
-                    $my_score_in_gradebook,
-                    api_get_utc_datetime()
+        }
+        $html = array();
+        if (!empty($my_certificate)) {
+            $certificate_obj = new Certificate($my_certificate['id']);
+            $fileWasGenerated = $certificate_obj->html_file_is_generated();
+
+            if (!empty($fileWasGenerated)) {
+                $url = api_get_path(WEB_PATH) . 'certificates/index.php?id=' . $my_certificate['id'];
+                $certificates = Display::url(
+                    '&nbsp;'.get_lang('DownloadCertificate'),
+                    $url,
+                    array(
+                        'target' => '_blank',
+                        'class' => 'btn'
+                    )
+                );
+                $exportToPDF = Display::url(
+                    Display::return_icon(
+                        'pdf.png',
+                        get_lang('ExportToPDF'),
+                        array(),
+                        ICON_SIZE_MEDIUM
+                    ),
+                    "$url&action=export"
+                );
+                $html = array(
+                    'certificate_link' => $certificates,
+                    'pdf_link' => $exportToPDF
                 );
-                $my_certificate = GradebookUtils::get_certificate_by_user_id($cats_course[0]->get_id(), $user_id);
-            }
-            $html = array();
-            if (!empty($my_certificate)) {
-                $certificate_obj = new Certificate($my_certificate['id']);
-                $fileWasGenerated = $certificate_obj->html_file_is_generated();
-
-                if (!empty($fileWasGenerated)) {
-                    $url = api_get_path(WEB_PATH) . 'certificates/index.php?id=' . $my_certificate['id'];
-                    $certificates = Display::url(
-                        '&nbsp;'.get_lang('DownloadCertificate'),
-                        $url,
-                        array(
-                            'target' => '_blank',
-                            'class' => 'btn'
-                        )
-                    );
-                    $exportToPDF = Display::url(
-                        Display::return_icon(
-                            'pdf.png',
-                            get_lang('ExportToPDF'),
-                            array(),
-                            ICON_SIZE_MEDIUM
-                        ),
-                        "$url&action=export"
-                    );
-                    $html = array(
-                        'certificate_link' => $certificates,
-                        'pdf_link' => $exportToPDF
-                    );
 
-                    if (api_get_setting('allow_skills_tool') == 'true') {
-                        $courseId = api_get_course_int_id();
-                        $sessionId = api_get_session_id();
-
-                        $objSkillRelUser = new SkillRelUser();
-                        $userSkills = $objSkillRelUser->get_user_skills($user_id, $courseId, $sessionId);
-
-                        if (!empty($userSkills)) {
-                            $html['badge_link'] = Display::url(
-                                get_lang('DownloadBadges'),
-                                api_get_path(WEB_CODE_PATH) . "gradebook/get_badges.php?user=$user_id",
-                                array(
-                                    'target' => '_blank',
-                                    'class' => 'btn'
-                                )
-                            );
-                        }
+                if (api_get_setting('allow_skills_tool') == 'true') {
+                    $courseId = api_get_course_int_id();
+                    $sessionId = api_get_session_id();
+
+                    $objSkillRelUser = new SkillRelUser();
+                    $userSkills = $objSkillRelUser->get_user_skills($user_id, $courseId, $sessionId);
+
+                    if (!empty($userSkills)) {
+                        $html['badge_link'] = Display::url(
+                            get_lang('DownloadBadges'),
+                            api_get_path(WEB_CODE_PATH) . "gradebook/get_badges.php?user=$user_id",
+                            array(
+                                'target' => '_blank',
+                                'class' => 'btn'
+                            )
+                        );
                     }
                 }
-                return $html;
             }
-        } else {
-            return false;
+            return $html;
         }
     }
 
@@ -1961,4 +1937,40 @@ class Category implements GradebookItem
             }
         }
     }
+
+    /**
+     * Check whether a user has finished a course by its gradebook
+     * @param int $userId The user ID
+     * @param \Category $category The gradebook category
+     * @return boolean
+     */
+    public static function userFinishedCourse($userId, \Category $category)
+    {
+        $courseEvaluations = $category->get_evaluations($userId, true);
+        $courseLinks = $category->get_links($userId, true);
+
+        $evaluationsAndLinks = array_merge($courseEvaluations, $courseLinks);
+
+        $totalItemValue = 0;
+
+        for ($i = 0; $i < count($evaluationsAndLinks); $i++) {
+            $item = $evaluationsAndLinks[$i];
+            $score = $item->calc_score($userId);
+            $itemValue = 0;
+
+            if (!empty($score)) {
+                $divider = $score[1] == 0 ? 1 : $score[1];
+                $itemValue = $score[0] / $divider * $item->get_weight();
+            }
+
+            $totalItemValue += $itemValue;
+        }
+
+        $totalItemValue = floatval($totalItemValue);
+
+        $minCertificateScore = $category->get_certificate_min_score();
+
+        return !empty($minCertificateScore) && $totalItemValue >= $minCertificateScore;
+    }
+
 }

+ 3 - 3
main/gradebook/lib/fe/dataform.class.php

@@ -46,7 +46,7 @@ class DataForm extends FormValidator
 		$this->addElement('header', get_lang('ChooseOrientation'));
 		$this->addElement('radio', 'orientation', null, get_lang('Portrait'), 'portrait');
 		$this->addElement('radio', 'orientation', null, get_lang('Landscape'), 'landscape');
-		$this->addElement('style_submit_button', 'submit', get_lang('Export'), 'class="upload"');
+		$this->addButtonExport(get_lang('Export'));
 		$this->setDefaults(array (
 			'orientation' => 'portrait'
 		));
@@ -58,7 +58,7 @@ class DataForm extends FormValidator
 		$this->addElement('radio', 'file_type', get_lang('OutputFileType'), 'CSV (Comma-Separated Values)', 'csv');
 		$this->addElement('radio', 'file_type', null, 'XML (Extensible Markup Language)', 'xml');
 		$this->addElement('radio', 'file_type', null, 'PDF (Portable Document Format)', 'pdf');
-		$this->addElement('style_submit_button', 'submit', get_lang('Export'), 'class="upload"');
+		$this->addButtonExport(get_lang('Export'));
 		$this->setDefaults(array (
 			'file_type' => 'csv'
 		));
@@ -70,7 +70,7 @@ class DataForm extends FormValidator
 		$this->addElement('radio', 'file_type', get_lang('OutputFileType'), 'CSV (Comma-Separated Values)', 'csv');
 		$this->addElement('radio', 'file_type', null, 'XML (Extensible Markup Language)', 'xml');
 		$this->addElement('radio', 'file_type', Display::return_icon('info3.gif',get_lang('ToExportMustLockEvaluation')), 'PDF (Portable Document Format)', 'pdf', array('disabled'));
-		$this->addElement('style_submit_button', 'submit', get_lang('Export'), 'class="upload"');
+		$this->addButtonExport(get_lang('Export'));
 		$this->setDefaults(array (
 			'file_type' => 'csv'
 		));

+ 1 - 1
main/gradebook/lib/fe/displaygradebook.php

@@ -565,7 +565,7 @@ class DisplayGradebook
                                     '',
                                     ICON_SIZE_MEDIUM
                                 ),
-                                "gradebook_display_certificate.php?$my_api_cidreq&amp;cat_id=" . intval($_GET['selectcat'])
+                                "gradebook_display_certificate.php?$my_api_cidreq&cat_id=" . intval($_GET['selectcat'])
                             )
                             . "</td>";
                     }

+ 2 - 1
main/gradebook/lib/fe/linkaddeditform.class.php

@@ -30,9 +30,10 @@ class LinkAddEditForm extends FormValidator
 		// set or create link object
 		if (isset($link_object)) {
 			$link = $link_object;
-		} elseif (isset ($link_type) && isset ($category_object)) {
+		} elseif (isset($link_type) && isset($category_object)) {
 			$link = LinkFactory :: create ($link_type);
 			$link->set_course_code(api_get_course_id());
+			$link->set_category_id($category_object[0]->get_id());
 		} else {
 			die ('LinkAddEditForm error: define link_type/category_object or link_object');
 		}

+ 3 - 2
main/gradebook/lib/flatview_data_generator.class.php

@@ -237,6 +237,7 @@ class FlatViewDataGenerator
             $item = $this->evals_links [$count + $items_start];
             $headers[] = $item->get_name();
         }
+
         return $headers;
     }
 
@@ -556,7 +557,7 @@ class FlatViewDataGenerator
             $divide = isset($score[1]) && !empty($score[1]) ? $score[1] : 1;
 
             // Sub cat weight
-            $sub_cat_percentage = $sum_categories_weight_array[$item->get_category_id()];
+            //$sub_cat_percentage = $sum_categories_weight_array[$item->get_category_id()];
 
             $item_value = isset($score[0]) ? $score[0]/$divide : 0;
 
@@ -722,7 +723,7 @@ class FlatViewDataGenerator
                 $score_final = ($score[0] / $score_denom) * 100;
                 $row[] = $score_final;
             }
-            $total_score = array($item_value, $item_total);
+            //$total_score = array($item_value, $item_total);
             $score_final = ($item_value / $item_total) * 100;
 
             $row[] = $score_final;

+ 3 - 3
main/group/group.php

@@ -212,17 +212,17 @@ if (api_get_setting('allow_group_categories') == 'true') {
             $actions .=
                 Display::url(
                     Display::return_icon('delete.png', get_lang('Delete'), '', ICON_SIZE_SMALL),
-                    'group.php?'.api_get_cidreq().'&action=delete_category&amp;id='.$category['id'],
+                    'group.php?'.api_get_cidreq().'&action=delete_category&id='.$category['id'],
                     array(
                         'onclick' => 'javascript:if(!confirm('."'".addslashes(api_htmlentities(get_lang('ConfirmYourChoice'), ENT_QUOTES))."'".')) return false;'
                     )
                 );
             if ($index != 0) {
-                $actions .=  ' <a href="group.php?'.api_get_cidreq().'&action=swap_cat_order&amp;id1='.$category['id'].'&amp;id2='.$group_cats[$index -1]['id'].'">'.
+                $actions .=  ' <a href="group.php?'.api_get_cidreq().'&action=swap_cat_order&id1='.$category['id'].'&id2='.$group_cats[$index -1]['id'].'">'.
                     Display::return_icon('up.png','&nbsp;','',ICON_SIZE_SMALL).'</a>';
             }
             if ($index != count($group_cats) - 1) {
-                $actions .= ' <a href="group.php?'.api_get_cidreq().'&action=swap_cat_order&amp;id1='.$category['id'].'&amp;id2='.$group_cats[$index +1]['id'].'">'.
+                $actions .= ' <a href="group.php?'.api_get_cidreq().'&action=swap_cat_order&id1='.$category['id'].'&id2='.$group_cats[$index +1]['id'].'">'.
                     Display::return_icon('down.png','&nbsp;','',ICON_SIZE_SMALL).'</a>';
             }
         }

+ 12 - 12
main/group/group_space.php

@@ -106,7 +106,7 @@ echo '<a href="group.php">'.
  */
 $subscribe_group = '';
 if (GroupManager :: is_self_registration_allowed($user_id, $current_group['id'])) {
-    $subscribe_group = '<a class="btn" href="'.api_get_self().'?selfReg=1&amp;group_id='.$current_group['id'].'" onclick="javascript: if(!confirm('."'".addslashes(api_htmlentities(get_lang("ConfirmYourChoice"), ENT_QUOTES))."'".')) return false;">'.
+    $subscribe_group = '<a class="btn" href="'.api_get_self().'?selfReg=1&group_id='.$current_group['id'].'" onclick="javascript: if(!confirm('."'".addslashes(api_htmlentities(get_lang("ConfirmYourChoice"), ENT_QUOTES))."'".')) return false;">'.
         get_lang("RegIntoGroup").'</a>';
 }
 
@@ -176,7 +176,7 @@ if (api_is_allowed_to_edit(false, true) OR
                     api_is_allowed_to_edit(false, true)
                 ) {
                     $actions_array[] = array(
-                        'url' => '../forum/viewforum.php?forum='.$value['forum_id'].'&gidReq='.Security::remove_XSS($current_group['id']).'&amp;origin=group',
+                        'url' => '../forum/viewforum.php?forum='.$value['forum_id'].'&gidReq='.Security::remove_XSS($current_group['id']).'&origin=group',
                         'content' => Display::return_icon('forum.png', get_lang('Forum').': '.$value['forum_title'] , array(), 32)
                     );
                 }
@@ -221,7 +221,7 @@ if (api_is_allowed_to_edit(false, true) OR
     if ($current_group['wiki_state'] != GroupManager::TOOL_NOT_AVAILABLE) {
         // Link to the wiki area of this group
         $actions_array[] = array(
-            'url' => '../wiki/index.php?'.api_get_cidreq().'&amp;action=show&amp;title=index&amp;session_id='.api_get_session_id().'&amp;group_id='.$current_group['id'],
+            'url' => '../wiki/index.php?'.api_get_cidreq().'&action=show&title=index&session_id='.api_get_session_id().'&group_id='.$current_group['id'],
             'content' => Display::return_icon('wiki.png', get_lang('GroupWiki'), array(), 32)
         );
     }
@@ -237,7 +237,7 @@ if (api_is_allowed_to_edit(false, true) OR
             );
         } else {
             $actions_array[] = array(
-                'url' => "../chat/chat.php?".api_get_cidreq()."&amp;toolgroup=".$current_group['id'],
+                'url' => "../chat/chat.php?".api_get_cidreq()."&toolgroup=".$current_group['id'],
                 'content' => Display::return_icon('chat.png', get_lang('Chat'), array(), 32)
             );
         }
@@ -258,7 +258,7 @@ if (api_is_allowed_to_edit(false, true) OR
             foreach ($forums_of_groups as $key => $value) {
                 if ($value['forum_group_public_private'] == 'public' ) {
                     $actions_array[] = array(
-                        'url' => '../forum/viewforum.php?cidReq='.api_get_course_id().'&forum='.$value['forum_id'].'&gidReq='.Security::remove_XSS($current_group['id']).'&amp;origin=group',
+                        'url' => '../forum/viewforum.php?cidReq='.api_get_course_id().'&forum='.$value['forum_id'].'&gidReq='.Security::remove_XSS($current_group['id']).'&origin=group',
                         'content' => Display::return_icon('forum.png', get_lang('GroupForum'), array(), ICON_SIZE_MEDIUM)
                     );
                 }
@@ -269,7 +269,7 @@ if (api_is_allowed_to_edit(false, true) OR
     if ($current_group['doc_state'] == GroupManager::TOOL_PUBLIC) {
         // Link to the documents area of this group
         $actions_array[] = array(
-            'url' => '../document/document.php?'.api_get_cidreq().'&amp;origin='.$origin,
+            'url' => '../document/document.php?'.api_get_cidreq().'&origin='.$origin,
             'content' => Display::return_icon('folder.png', get_lang('GroupDocument'), array(), ICON_SIZE_MEDIUM)
         );
     }
@@ -298,7 +298,7 @@ if (api_is_allowed_to_edit(false, true) OR
     if ($current_group['wiki_state'] == GroupManager::TOOL_PUBLIC) {
         // Link to the wiki area of this group
         $actions_array[] = array(
-            'url' => '../wiki/index.php?'.api_get_cidreq().'&amp;action=show&amp;title=index&amp;session_id='.api_get_session_id().'&amp;group_id='.$current_group['id'],
+            'url' => '../wiki/index.php?'.api_get_cidreq().'&action=show&title=index&session_id='.api_get_session_id().'&group_id='.$current_group['id'],
             'content' => Display::return_icon('wiki.png', get_lang('GroupWiki'), array(), 32)
         );
     }
@@ -306,12 +306,12 @@ if (api_is_allowed_to_edit(false, true) OR
         // Link to the chat area of this group
         if (api_get_course_setting('allow_open_chat_window')) {
             $actions_array[] = array(
-                'url' => "javascript: void(0);\" onclick=\"window.open('../chat/chat.php?".api_get_cidreq()."&amp;toolgroup=".$current_group['id']."','window_chat_group_".$_SESSION['_cid']."_".$_SESSION['_gid']."','height=380, width=625, left=2, top=2, toolbar=no, menubar=no, scrollbars=yes, resizable=yes, location=no, directories=no, status=no') \"",
+                'url' => "javascript: void(0);\" onclick=\"window.open('../chat/chat.php?".api_get_cidreq()."&toolgroup=".$current_group['id']."','window_chat_group_".$_SESSION['_cid']."_".$_SESSION['_gid']."','height=380, width=625, left=2, top=2, toolbar=no, menubar=no, scrollbars=yes, resizable=yes, location=no, directories=no, status=no') \"",
                 'content' => Display::return_icon('chat.png', get_lang('Chat'), array(), 32)
             );
         } else {
             $actions_array[] = array(
-                'url' => "../chat/chat.php?".api_get_cidreq()."&amp;toolgroup=".$current_group['id'],
+                'url' => "../chat/chat.php?".api_get_cidreq()."&toolgroup=".$current_group['id'],
                 'content' => Display::return_icon('chat.png', get_lang('Chat'), array(), 32)
             );
         }
@@ -340,7 +340,7 @@ if (count($tutors) == 0) {
         $existing_image = $image_path['file'];
         $completeName = api_get_person_name($tutor['firstname'], $tutor['lastname']);
         $photo = '<img src="'.$image_repository.$existing_image.'" alt="'.$completeName.'" width="32" height="32" title="'.$completeName.'" />';
-        $tutor_info .= '<li><a href="'.api_get_path(WEB_CODE_PATH).'user/userInfo.php?origin='.$my_origin.'&amp;uInfo='.$tutor['user_id'].'">'.
+        $tutor_info .= '<li><a href="'.api_get_path(WEB_CODE_PATH).'user/userInfo.php?origin='.$my_origin.'&uInfo='.$tutor['user_id'].'">'.
             $photo.'&nbsp;'.$completeName.'</a></li>';
     }
     $tutor_info .= '</ul>';
@@ -519,7 +519,7 @@ function user_icon_filter($user_id)
     $image_repository = $image_path['dir'];
     $existing_image = $image_path['file'];
     $photo = '<center><img src="'.$image_repository.$existing_image.'" alt="'.$userinfo['complete_name'].'"  width="22" height="22" title="'.$userinfo['complete_name'].'" /></center>';
-    return '<a href="../user/userInfo.php?origin='.$origin.'&amp;uInfo='.$user_id.'">'.$photo;
+    return '<a href="../user/userInfo.php?origin='.$origin.'&uInfo='.$user_id.'">'.$photo;
 }
 
 /**
@@ -536,7 +536,7 @@ function user_name_filter($name, $url_params, $row)
 {
     $tab_user_info = api_get_user_info($row[0]);
     $username = api_htmlentities(sprintf(get_lang('LoginX'), $tab_user_info['username']), ENT_QUOTES);
-    return '<a href="../user/userInfo.php?uInfo='.$row[0].'&amp;'.$url_params.'" title="'.$username.'">'.$name.'</a>';
+    return '<a href="../user/userInfo.php?uInfo='.$row[0].'&'.$url_params.'" title="'.$username.'">'.$name.'</a>';
 }
 
 // Footer

+ 25 - 18
main/inc/global.inc.php

@@ -195,6 +195,7 @@ $config->setEntityNamespaces(
 $entityManager = EntityManager::create($dbParams, $config);
 
 use Doctrine\Common\Annotations\AnnotationRegistry;
+
 AnnotationRegistry::registerAutoloadNamespace(
     'Symfony\Component\Validator\Constraint',
     api_get_path(SYS_PATH)."vendor/symfony/validator"
@@ -223,14 +224,20 @@ if (!empty($_configuration['multiple_access_urls'])) {
     $access_urls = api_get_access_urls();
 
     $root_rel = api_get_self();
-    $root_rel = substr($root_rel,1);
-    $pos = strpos($root_rel,'/');
-    $root_rel = substr($root_rel,0,$pos);
+    $root_rel = substr($root_rel, 1);
+    $pos = strpos($root_rel, '/');
+    $root_rel = substr($root_rel, 0, $pos);
     $protocol = ((!empty($_SERVER['HTTPS']) && strtoupper($_SERVER['HTTPS']) != 'OFF') ? 'https' : 'http').'://';
     //urls with subdomains (HTTP_HOST is preferred - see #6764)
-    $request_url_root = $protocol.$_SERVER['HTTP_HOST'].'/';
-    if (empty($request_url_root)) {
-        $request_url_root = $protocol.$_SERVER['SERVER_NAME'].'/';
+    $request_url_root = '';
+    if (empty($_SERVER['HTTP_HOST'])) {
+        if (empty($_SERVER['SERVER_NAME'])) {
+            $request_url_root = $protocol . 'localhost/';
+        } else {
+            $request_url_root = $protocol . $_SERVER['SERVER_NAME'] . '/';
+        }
+    } else {
+        $request_url_root = $protocol.$_SERVER['HTTP_HOST'].'/';
     }
     //urls with subdirs
     $request_url_sub = $request_url_root.$root_rel.'/';
@@ -299,10 +306,10 @@ Chamilo::session()->start($already_installed);
 // Remove quotes added by PHP  - get_magic_quotes_gpc() is deprecated in PHP 5 see #2970
 
 if (function_exists('get_magic_quotes_gpc') && get_magic_quotes_gpc()) {
-	array_walk_recursive_limited($_GET,     	'stripslashes', true);
-	array_walk_recursive_limited($_POST, 	'stripslashes', true);
-	array_walk_recursive_limited($_COOKIE,  'stripslashes', true);
-	array_walk_recursive_limited($_REQUEST, 'stripslashes', true);
+    array_walk_recursive_limited($_GET, 'stripslashes', true);
+    array_walk_recursive_limited($_POST, 'stripslashes', true);
+    array_walk_recursive_limited($_COOKIE, 'stripslashes', true);
+    array_walk_recursive_limited($_REQUEST, 'stripslashes', true);
 }
 
 // access_url == 1 is the default chamilo location
@@ -418,7 +425,7 @@ if (api_get_setting('server_type') == 'test') {
     error_reporting(E_COMPILE_ERROR | E_ERROR | E_CORE_ERROR);
 }
 
-/*	LOAD LANGUAGE FILES SECTION */
+/*  LOAD LANGUAGE FILES SECTION */
 
 // if we use the javascript version (without go button) we receive a get
 // if we use the non-javascript version (with the go button) we receive a post
@@ -482,7 +489,7 @@ if (isset($this_script) && $this_script == 'sub_language') {
         $parent_language_array[$language_file_item] = compact($lang_list_result);
 
         //cleaning the variables
-        foreach($lang_list_result as $item) {
+        foreach ($lang_list_result as $item) {
             unset(${$item});
         }
 
@@ -495,7 +502,7 @@ if (isset($this_script) && $this_script == 'sub_language') {
         $sub_language_array[$language_file_item] = compact($lang_list_result);
 
         //cleaning the variables
-        foreach($lang_list_result as $item) {
+        foreach ($lang_list_result as $item) {
             unset(${$item});
         }
     }
@@ -523,13 +530,13 @@ if (!empty($valid_languages)) {
         $platformLanguage = $user_selected_language;
     }
 
-    if (!empty($language_priority4) && api_get_language_from_type($language_priority4) !== false ) {
+    if (!empty($language_priority4) && api_get_language_from_type($language_priority4) !== false) {
         $language_interface =  api_get_language_from_type($language_priority4);
     } else {
         $language_interface = api_get_setting('platformLanguage');
     }
 
-    if (!empty($language_priority3) && api_get_language_from_type($language_priority3) !== false ) {
+    if (!empty($language_priority3) && api_get_language_from_type($language_priority3) !== false) {
         $language_interface =  api_get_language_from_type($language_priority3);
     } else {
         if (isset($_SESSION['user_language_choice'])) {
@@ -537,14 +544,14 @@ if (!empty($valid_languages)) {
         }
     }
 
-    if (!empty($language_priority2) && api_get_language_from_type($language_priority2) !== false ) {
+    if (!empty($language_priority2) && api_get_language_from_type($language_priority2) !== false) {
         $language_interface =  api_get_language_from_type($language_priority2);
     } else {
         if (isset($_user['language'])) {
             $language_interface = $_user['language'];
         }
     }
-    if (!empty($language_priority1) && api_get_language_from_type($language_priority1) !== false ) {
+    if (!empty($language_priority1) && api_get_language_from_type($language_priority1) !== false) {
         $language_interface =  api_get_language_from_type($language_priority1);
     } else {
         if (isset($_course['language'])) {
@@ -645,7 +652,7 @@ if (!isset($_SESSION['login_as']) && isset($_user)) {
         // is the latest logout_date still relevant?
         $sql_logout_date = "SELECT logout_date FROM $tbl_track_login WHERE login_id=$i_id_last_connection";
         $q_logout_date = Database::query($sql_logout_date);
-        $res_logout_date = convert_sql_date(Database::result($q_logout_date,0,'logout_date'));
+        $res_logout_date = convert_sql_date(Database::result($q_logout_date, 0, 'logout_date'));
 
         if ($res_logout_date < time() - $_configuration['session_lifetime']) {
             // it isn't, we should create a fresh entry

+ 0 - 1
main/inc/lib/add_courses_to_session_functions.lib.php

@@ -11,7 +11,6 @@ class AddCourseToSession
 	 * @param string $needle Search string
 	 * @param string $type Type of search box ('single' or anything else)
 	 * @return string XajaxResponse
-	 * @assert () !== null
 	 * @assert ('abc', 'single') !== null
 	 * @assert ('abc', 'multiple') !== null
 	 */

+ 4 - 1
main/inc/lib/add_many_session_to_category_functions.lib.php

@@ -4,7 +4,10 @@
  * Definition of the AddManySessionToCategoryFunctions class
  * @package chamilo.library
  */
-
+/**
+ * Requires
+ */
+require_once ('xajax/xajax.inc.php');
 /**
  * AddManySessionToCategoryFunctions class
  */

+ 38 - 10
main/inc/lib/api.lib.php

@@ -1214,10 +1214,11 @@ function api_protect_teacher_script($allow_sessions_admins = false) {
  *
  * @author Roan Embrechts
  */
-function api_block_anonymous_users($print_headers = true) {
+function api_block_anonymous_users($printHeaders = true)
+{
     $_user = api_get_user_info();
     if (!(isset($_user['user_id']) && $_user['user_id']) || api_is_anonymous($_user['user_id'], true)) {
-        api_not_allowed($print_headers);
+        api_not_allowed($printHeaders);
         return false;
     }
 
@@ -1451,7 +1452,11 @@ function _api_format_user($user, $add_password = false)
  */
 function api_get_user_info($user_id = '', $check_if_user_is_online = false, $show_password = false) {
     if ($user_id == '') {
-        return _api_format_user($GLOBALS['_user']);
+        if (isset($GLOBALS['_user'])) {
+            return _api_format_user($GLOBALS['_user']);
+        }
+        // @todo trigger an exception here
+        return false;
     }
     $sql = "SELECT * FROM ".Database :: get_main_table(TABLE_MAIN_USER)."
             WHERE user_id='".intval($user_id)."'";
@@ -2732,7 +2737,7 @@ function api_is_coach($session_id = 0, $course_code = null, $check_student_view
  * @return boolean True if current user is a course administrator
  */
 function api_is_session_admin() {
-    global $_user;
+    $_user = api_get_user_info();
     return isset($_user['status']) && $_user['status'] == SESSIONADMIN;
 }
 
@@ -2741,7 +2746,7 @@ function api_is_session_admin() {
  * @return boolean True if current user is a human resources manager
  */
 function api_is_drh() {
-    global $_user;
+    $_user = api_get_user_info();
     return isset($_user['status']) && $_user['status'] == DRH;
 }
 
@@ -2750,7 +2755,7 @@ function api_is_drh() {
  * @return boolean True if current user is a human resources manager
  */
 function api_is_student() {
-    global $_user;
+    $_user = api_get_user_info();
     return isset($_user['status']) && $_user['status'] == STUDENT;
 
 }
@@ -2759,7 +2764,7 @@ function api_is_student() {
  * @return boolean True if current user is a human resources manager
  */
 function api_is_teacher() {
-    global $_user;
+    $_user = api_get_user_info();
     return isset($_user['status']) && $_user['status'] == COURSEMANAGER;
 }
 
@@ -2768,7 +2773,7 @@ function api_is_teacher() {
  * @return boolean
  */
 function api_is_invitee() {
-    global $_user;
+    $_user = api_get_user_info();
 
     return isset($_user['status']) && $_user['status'] == INVITEE;
 }
@@ -7657,12 +7662,13 @@ function api_register_campus($listCampus = true) {
  * @global array $_user
  * @return boolean
  */
-function api_is_student_boss ()
+function api_is_student_boss()
 {
-    global $_user;
+    $_user = api_get_user_info();
 
     return isset($_user['status']) && $_user['status'] == STUDENT_BOSS;
 }
+
 /**
  * Check whether the user type should be exclude.
  * Such as invited or anonymous users
@@ -8000,3 +8006,25 @@ function api_protect_course_group($tool, $showHeader = true)
         }
     }
 }
+
+/**
+ * Check if Chmailo is installed correctly. If so, return the version
+ * @return array ('installed' => 0/1, 'message' => error/db version)
+ */
+function apiIsSystemInstalled()
+{
+    $root = __DIR__.'/../../../';
+    $configFile = $root.'main/inc/conf/configuration.php';
+    if (!is_readable($configFile)) {
+        return array ('installed' => 0, 'message' => 'No config file');
+    }
+    $result = Database::query(
+        "SELECT selected _value FROM settings_current WHERE variable = 'chamilo_database_version'"
+    );
+    if ($result == false) {
+        return array ('installed' => 0, 'message' => 'No way to recover version');
+    }
+    $settingsRow = Database::fetch_assoc($result);
+    $version = $settingsRow['selected_value'];
+    return array('installed' => 1, 'message' => $version);
+}

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

@@ -20,6 +20,7 @@ class Number extends HTML_QuickForm_text
         }
         
         $attributes['type'] = 'number';
+        $attributes['class'] = 'form-control';
 
         HTML_QuickForm_element::HTML_QuickForm_element($elementName, $elementLabel, $attributes);
         $this->_appendName = true;

+ 1 - 1
main/inc/lib/formvalidator/FormValidator.class.php

@@ -586,7 +586,7 @@ EOT;
      * @param string $label
      * @param array  $attributes
      */
-    public function add_file($name, $label, $attributes = array())
+    public function addFile($name, $label, $attributes = array())
     {
         $this->addElement('file', $name, $label, $attributes);
     }

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

@@ -2730,7 +2730,7 @@ class GroupManager
     public static function getSearchForm()
     {
         $url = api_get_path(WEB_CODE_PATH).'group/group_overview.php?'.api_get_cidreq();
-        $form = new FormValidator('search_groups', 'get', $url, null, array(), FormValidator::LAYOUT_INLINE);
+        $form = new FormValidator('search_groups', 'get', $url, null, array('class' => 'form-search'), FormValidator::LAYOUT_INLINE);
         $form->addElement('text', 'keyword');
         $form->addButtonSearch();
         return $form->toHtml();

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

@@ -610,9 +610,9 @@ class Template
             'jquery-ui/jquery-ui.min.js',
             'bootstrap/dist/js/bootstrap.min.js',
             'ckeditor/ckeditor.js',
+            'moment/min/moment-with-locales.min.js',
             'bootstrap-daterangepicker/daterangepicker.js',
             'jquery-timeago/jquery.timeago.js',
-            'moment/min/moment-with-locales.min.js',
             'mediaelement/build/mediaelement-and-player.min.js',
             'jqueryui-timepicker-addon/dist/jquery-ui-timepicker-addon.min.js'
         ];

+ 1 - 0
main/inc/lib/usermanager.lib.php

@@ -33,6 +33,7 @@ class UserManager
 
     /**
      * The default constructor only instanciates an empty user object
+     * @assert () === null
      */
     public function __construct()
     {

+ 3 - 3
main/install/configuration.dist.php

@@ -307,11 +307,11 @@ $_configuration['system_stable']     = NEW_VERSION_STABLE;
 // Attach a document to a work
 //$_configuration['add_document_to_work'] = false;
 // Allow user comments in work
-//$_configuration['work_user_comments'] = false;
-
+// $_configuration['work_user_comments'] = false;
+// Allow student to enroll into a session without an approval needing
+//$_configuration['catalog_allow_session_auto_subscription'] = true;
 // Decode UTF-8 from Web Services (option passed to SOAP)
 //$_configuration['registration.soap.php.decode_utf8'] = false;
-
 // Show delete option in attendance
 //$_configuration['allow_delete_attendance'] = false;
 

+ 15 - 10
main/newscorm/learnpath.class.php

@@ -7232,7 +7232,7 @@ class learnpath
             reset($arrLP);
         }
 
-        $form->addElement('style_submit_button', 'submit_button', get_lang('SaveSection'), 'class="save"');
+        $form->addButtonSave(get_lang('SaveSection'), 'submit_button');
 
         if ($item_type == 'module' || $item_type == 'dokeos_module') {
             $form->addElement('hidden', 'parent', '0');
@@ -7360,7 +7360,7 @@ class learnpath
         $result = Database::query($sql);
         $arrLP = array ();
         while ($row = Database :: fetch_array($result)) {
-            $arrLP[] = array (
+            $arrLP[] = array(
                 'id' 				=> $row['id'],
                 'item_type' 		=> $row['item_type'],
                 'title' 			=> $row['title'],
@@ -7548,26 +7548,28 @@ class learnpath
                             $relative_prefix = '../../';
                         }
 
-                        $editor_config = array( 'ToolbarSet' 			=> 'LearningPathDocuments',
+                        $editor_config = array(
+                            'ToolbarSet'=> 'LearningPathDocuments',
                             'Width' 				=> '100%',
                             'Height' 				=> '500',
                             'FullPage' 				=> true,
                             'CreateDocumentDir' 	=> $relative_prefix,
                             'CreateDocumentWebDir' 	=> api_get_path(WEB_COURSE_PATH) . api_get_course_path().'/document/',
                             'BaseHref' 				=> api_get_path(WEB_COURSE_PATH) . api_get_course_path().'/document/'.$relative_path
-
                         );
 
                         if ($_GET['action'] == 'add_item') {
                             $class = 'add';
                             $text = get_lang('LPCreateDocument');
-                        } else
+                        } else {
                             if ($_GET['action'] == 'edit_item') {
                                 $class = 'save';
                                 $text = get_lang('SaveDocument');
                             }
+                        }
 
-                        $form->addElement('style_submit_button', 'submit_button', $text, 'class="' . $class . '"');
+                        //$form->addElement('style_submit_button', 'submit_button', $text, 'class="' . $class . '"');
+                        $form->addButtonSave($text, 'submit_button');
                         $renderer = $form->defaultRenderer();
                         $renderer->setElementTemplate('<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{label}<br />{element}', 'content_lp');
                         $form->addElement('html', '<div>');
@@ -7576,7 +7578,8 @@ class learnpath
                         $defaults['content_lp'] = $content;
                     }
                 } elseif (is_numeric($extra_info)) {
-                    $form->addElement('style_submit_button', 'submit_button', get_lang('SaveDocument'), 'class="save"');
+                    $form->addButtonSave(get_lang('SaveDocument'), 'submit_button');
+
                     $return = $this->display_document($extra_info, true, true, true);
                     $form->addElement('html', $return);
                 }
@@ -7588,15 +7591,16 @@ class learnpath
             $form->addElement('hidden', 'description', $item_description);
         }
         if (is_numeric($extra_info)) {
-            $form->addElement('style_submit_button', 'submit_button', get_lang('SaveDocument'), 'value="submit_button", class="save"');
+            $form->addButtonSave(get_lang('SaveDocument'), 'submit_button');
             $form->addElement('hidden', 'path', $extra_info);
         } elseif (is_array($extra_info)) {
-            $form->addElement('style_submit_button', 'submit_button', get_lang('SaveDocument'), 'class="save"');
+            $form->addButtonSave(get_lang('SaveDocument'), 'submit_button');
             $form->addElement('hidden', 'path', $extra_info['path']);
         }
         $form->addElement('hidden', 'type', TOOL_DOCUMENT);
         $form->addElement('hidden', 'post_time', time());
         $form->setDefaults($defaults);
+
         return $form->return_form();
     }
 
@@ -8249,6 +8253,7 @@ class learnpath
 
     /**
      * Return HTML form to allow prerequisites selection
+     * @todo use FormValidator
      * @param	integer Item ID
      * @return	string	HTML form
      */
@@ -8377,7 +8382,7 @@ class learnpath
         $return .= '</tr>';
         $return .= '</table>';
         $return .= '<div style="padding-top:3px;">';
-        $return .= '<button class="save" name="submit_button" type="submit">' . get_lang('ModifyPrerequisites') . '</button>';
+        $return .= '<button class="btn btn-default" name="submit_button" type="submit">' . get_lang('ModifyPrerequisites') . '</button>';
         $return .= '</form>';
 
         return $return;

+ 2 - 2
main/template/default/layout/show_header.tpl

@@ -7,11 +7,11 @@
 #}
 {% if show_header == true %}
     {% if plugin_content_top is not null %}
-        <div id="plugin_content_top" class="span12">
+        <div id="plugin_content_top" class="col-md-12">
             {{ plugin_content_top }}
         </div>
     {% endif %}
-    <div class="span12">
+    <div class="col-md-12">
         {% include template ~ "/layout/page_body.tpl" %}
         <section id="main_content">
 {% endif %}

+ 13 - 10
main/work/work.lib.php

@@ -4026,7 +4026,7 @@ function addDir($params, $user_id, $courseInfo, $group_id, $session_id)
                 filetype            = 'folder',
                 post_group_id       = '".$group_id."',
                 sent_date           = '".$today."',
-                qualification       = '".(($params['qualification'] != '') ? Database::escape_string($params['qualification']) : '') ."',
+                qualification       = '".($params['qualification'] != '' ? Database::escape_string($params['qualification']) : '') ."',
                 parent_id           = '',
                 qualificator_id     = '',
                 date_of_qualification   = '0000-00-00 00:00:00',
@@ -4051,6 +4051,7 @@ function addDir($params, $user_id, $courseInfo, $group_id, $session_id)
                 $user_id,
                 $group_id
             );
+
             updatePublicationAssignment($id, $params, $courseInfo, $group_id);
 
             if (api_get_course_setting('email_alert_students_on_new_homework') == 1) {
@@ -4065,7 +4066,7 @@ function addDir($params, $user_id, $courseInfo, $group_id, $session_id)
 /**
  * @param int $workId
  * @param array $courseInfo
- * @return array
+ * @return int
  */
 function agendaExistsForWork($workId, $courseInfo)
 {
@@ -4176,8 +4177,8 @@ function updatePublicationAssignment($workId, $params, $courseInfo, $groupId)
     }
 
     $qualification = isset($params['qualification']) && !empty($params['qualification']) ? 1 : 0;
-    $expiryDate = (isset($params['enableExpiryDate']) && $params['enableExpiryDate'] == 1) ? api_get_utc_datetime($params['expires_on']) : '0000-00-00 00:00:00';
-    $endDate = ((isset($params['enableEndDate']) && $params['enableEndDate']==1) ? api_get_utc_datetime($params['ends_on']) : '0000-00-00 00:00:00');
+    $expiryDate = isset($params['enableExpiryDate']) && $params['enableExpiryDate'] == 1 ? api_get_utc_datetime($params['expires_on']) : '0000-00-00 00:00:00';
+    $endDate = isset($params['enableEndDate']) && $params['enableEndDate'] == 1 ? api_get_utc_datetime($params['ends_on']) : '0000-00-00 00:00:00';
 
     $data = get_work_assignment_by_id($workId, $course_id);
 
@@ -4185,11 +4186,11 @@ function updatePublicationAssignment($workId, $params, $courseInfo, $groupId)
 
         $sql = "INSERT INTO $table SET
                 c_id = $course_id ,
-                expires_on              = '".Database::escape_string($expiryDate)."',
-                ends_on                 = '".Database::escape_string($endDate)."',
-                add_to_calendar         = $agendaId,
-                enable_qualification    = '$qualification',
-                publication_id          = '$workId'";
+                expires_on = '".Database::escape_string($expiryDate)."',
+                ends_on = '".Database::escape_string($endDate)."',
+                add_to_calendar = $agendaId,
+                enable_qualification = '$qualification',
+                publication_id = '$workId'";
         Database::query($sql);
 
         $my_last_id = Database::insert_id();
@@ -4226,7 +4227,9 @@ function updatePublicationAssignment($workId, $params, $courseInfo, $groupId)
             $linkId = $link_info['id'];
         }
 
-        if (isset($params['make_calification']) && $params['make_calification'] == 1) {
+        if (isset($params['make_calification']) &&
+            $params['make_calification'] == 1
+        ) {
             if (empty($linkId)) {
                 GradebookUtils::add_resource_to_course_gradebook(
                     $params['category_id'],

+ 22 - 2
plugin/advanced_subscription/ajax/advanced_subscription.ajax.php

@@ -28,6 +28,7 @@ $data['accept_terms'] = isset($_REQUEST['accept_terms']) ? intval($_REQUEST['acc
 $data['courseId'] = isset($_REQUEST['c']) ? intval($_REQUEST['c']) : 0;
 // Init result array
 $result = array('error' => true, 'errorMessage' => get_lang('ThereWasAnError'));
+$showJSON = true;
 // Check if data is valid or is for start subscription
 $verified = $plugin->checkHash($data, $hash) || $data['action'] == 'subscribe';
 if ($verified) {
@@ -208,6 +209,8 @@ if ($verified) {
                         $result['errorMessage'] = 'User can not be subscribed';
                     }
                     $result['pass'] = false;
+                    $url = $plugin->getTermsUrl($data, ADVANCED_SUBSCRIPTION_TERMS_MODE_FINAL);
+                    Header::location($url);
                 }
             }
 
@@ -215,6 +218,21 @@ if ($verified) {
         case 'confirm':
             // Check if new status is set
             if (isset($data['newStatus'])) {
+                if ($data['newStatus'] === ADVANCED_SUBSCRIPTION_QUEUE_STATUS_ADMIN_APPROVED) {
+                    try {
+                        $isAllowToDoRequest = $plugin->isAllowedToDoRequest($data['studentUserId'], $data);
+                    } catch (Exception $ex) {
+                        $messageTemplate = new Template(null, false, false);
+                        $messageTemplate->assign(
+                            'content',
+                            Display::return_message($ex->getMessage(), 'error', false)
+                        );
+                        $messageTemplate->display_no_layout_template();
+                        $showJSON = false;
+                        break;
+                    }
+                }
+
                 // Update queue status
                 $res = $plugin->updateQueueStatus($data, $data['newStatus']);
                 if ($res === true) {
@@ -346,5 +364,7 @@ if ($verified) {
     }
 }
 
-// Echo result as json
-echo json_encode($result);
+if ($showJSON) {
+    // Echo result as json
+    echo json_encode($result);
+}

+ 1 - 0
plugin/advanced_subscription/config.php

@@ -29,6 +29,7 @@ define('ADVANCED_SUBSCRIPTION_QUEUE_STATUS_ADMIN_APPROVED', 10);
 
 define('ADVANCED_SUBSCRIPTION_TERMS_MODE_POPUP', 0);
 define('ADVANCED_SUBSCRIPTION_TERMS_MODE_REJECT', 1);
+define('ADVANCED_SUBSCRIPTION_TERMS_MODE_FINAL', 2);
 
 
 

+ 117 - 42
plugin/advanced_subscription/src/AdvancedSubscriptionPlugin.php

@@ -208,21 +208,10 @@ class AdvancedSubscriptionPlugin extends Plugin implements HookPluginInterface
             }
         }
 
-        $checkInduction = $plugin->get('check_induction');
-        // @TODO: check if user have completed at least one induction session
-        $completedInduction = true;
-
-        if ($checkInduction && !$completedInduction) {
-            $this->errorMessages[] = $this->get_lang('AdvancedSubscriptionIncompleteInduction');
-
-            if (!$collectErrors) {
-                throw new \Exception($this->get_lang('AdvancedSubscriptionIncompleteInduction'));
-            }
-        }
-
-        $uitMax = $plugin->get('yearly_cost_unit_converter');
-        $uitMax *= $plugin->get('yearly_cost_limit');
-        $uitUser = 0;
+        $yearlyCostLimit = $plugin->get('yearly_cost_limit');
+        $maxCost = $plugin->get('yearly_cost_unit_converter');
+        $maxCost *= $yearlyCostLimit;
+        $userCost = 0;
         $now = new DateTime(api_get_utc_datetime());
         $newYearDate = $plugin->get('course_session_credit_year_start_date');
         $newYearDate = !empty($newYearDate) ?
@@ -249,17 +238,31 @@ class AdvancedSubscriptionPlugin extends Plugin implements HookPluginInterface
             $whereSession
         );
 
+        $expendedTimeMax = $plugin->get('yearly_hours_limit');
+        $expendedTime = 0;
+
         if (is_array($sessions) && count($sessions) > 0) {
             foreach ($sessions as $session) {
-                $var = $extra->get_values_by_handler_and_field_variable($session['id'], 'cost');
-                $uitUser += $var['field_value'];
+                $costField = $extra->get_values_by_handler_and_field_variable($session['id'], 'cost');
+                $userCost += $costField['field_value'];
+
+                $teachingHoursField = $extra->get_values_by_handler_and_field_variable($session['id'], 'teaching_hours');
+                $expendedTime += $teachingHoursField['field_value'];
             }
         }
 
-        if ($uitMax < $uitUser) {
+        if (isset($params['sessionId'])) {
+            $costField = $extra->get_values_by_handler_and_field_variable($params['sessionId'], 'cost');
+            $userCost += $costField['field_value'];
+
+            $teachingHoursField = $extra->get_values_by_handler_and_field_variable($params['sessionId'], 'teaching_hours');
+            $expendedTime += $teachingHoursField['field_value'];
+        }
+
+        if ($maxCost <= $userCost) {
             $errorMessage = sprintf(
                 $this->get_lang('AdvancedSubscriptionCostXLimitReached'),
-                $uitMax
+                $yearlyCostLimit
             );
 
             $this->errorMessages[] = $errorMessage;
@@ -269,17 +272,7 @@ class AdvancedSubscriptionPlugin extends Plugin implements HookPluginInterface
             }
         }
 
-        $expendedTimeMax = $plugin->get('yearly_hours_limit');
-        $expendedTime = 0;
-
-        if (is_array($sessions) && count($sessions) > 0) {
-            foreach ($sessions as $session) {
-                $var = $extra->get_values_by_handler_and_field_variable($session['id'], 'teaching_hours');
-                $expendedTime += $var['field_value'];
-            }
-        }
-
-        if ($expendedTimeMax < $expendedTime) {
+        if ($expendedTimeMax <= $expendedTime) {
             $errorMessage = sprintf(
                 $this->get_lang('AdvancedSubscriptionTimeXLimitReached'),
                 $expendedTimeMax
@@ -295,7 +288,7 @@ class AdvancedSubscriptionPlugin extends Plugin implements HookPluginInterface
         $expendedNumMax = $plugin->get('courses_count_limit');
         $expendedNum = count($sessions);
 
-        if ($expendedNumMax < $expendedNum) {
+        if ($expendedNumMax <= $expendedNum) {
             $errorMessage = sprintf(
                 $this->get_lang('AdvancedSubscriptionCourseXLimitReached'),
                 $expendedNumMax
@@ -308,6 +301,18 @@ class AdvancedSubscriptionPlugin extends Plugin implements HookPluginInterface
             }
         }
 
+        $checkInduction = $plugin->get('check_induction');
+        $numberOfApprovedInductionSessions = $this->getApprovedInductionSessions($userId);
+        $completedInduction = $numberOfApprovedInductionSessions > 0;
+
+        if ($checkInduction == 'true' && !$completedInduction) {
+            $this->errorMessages[] = $this->get_lang('AdvancedSubscriptionIncompleteInduction');
+
+            if (!$collectErrors) {
+                throw new \Exception($this->get_lang('AdvancedSubscriptionIncompleteInduction'));
+            }
+        }
+
         return empty($this->errorMessages);
     }
 
@@ -1199,17 +1204,32 @@ class AdvancedSubscriptionPlugin extends Plugin implements HookPluginInterface
      */
     public function getTermsUrl($params, $mode = ADVANCED_SUBSCRIPTION_TERMS_MODE_POPUP)
     {
-        $url = api_get_path(WEB_PLUGIN_PATH) . 'advanced_subscription/src/terms_and_conditions.php?' .
-            'a=' . Security::remove_XSS($params['action']) . '&' .
-            's=' . intval($params['sessionId']) . '&' .
-            'current_user_id=' . intval($params['currentUserId']) . '&' .
-            'e=' . intval($params['newStatus']) . '&' .
-            'u=' . intval($params['studentUserId']) . '&' .
-            'q=' . intval($params['queueId']) . '&' .
-            'is_connected=' . 1 . '&' .
-            'profile_completed=' . intval($params['profile_completed']) . '&' .
-            'r=' . intval($mode) . '&' .
-            'v=' . $this->generateHash($params);
+        $urlParams = array(
+            'a' => Security::remove_XSS($params['action']),
+            's' => intval($params['sessionId']),
+            'current_user_id' => intval($params['currentUserId']),
+            'e' => intval($params['newStatus']),
+            'u' => intval($params['studentUserId']),
+            'q' => intval($params['queueId']),
+            'is_connected' => 1,
+            'profile_completed' => intval($params['profile_completed']),
+            'v' => $this->generateHash($params)
+        );
+
+        switch ($mode) {
+            case ADVANCED_SUBSCRIPTION_TERMS_MODE_POPUP:
+                // no break
+            case ADVANCED_SUBSCRIPTION_TERMS_MODE_FINAL:
+                $urlParams['r'] = 0;
+                break;
+            case ADVANCED_SUBSCRIPTION_TERMS_MODE_REJECT:
+                $urlParams['r'] = 1;
+                break;
+        }
+
+        $url = api_get_path(WEB_PLUGIN_PATH) . "advanced_subscription/src/terms_and_conditions.php?";
+        $url .= http_build_query($urlParams);
+
         // Launch popup
         if ($mode == ADVANCED_SUBSCRIPTION_TERMS_MODE_POPUP) {
             $url = 'javascript:void(window.open(\'' . $url .'\',\'AdvancedSubscriptionTerms\', \'toolbar=no,location=no,status=no,menubar=no,scrollbars=yes,resizable=yes,width=700px,height=600px\', \'100\' ))';
@@ -1276,4 +1296,59 @@ class AdvancedSubscriptionPlugin extends Plugin implements HookPluginInterface
 
         return $templateContent;
     }
+
+    /**
+     * Get the count of approved induction sessions by a user
+     * @param int $userId The user id
+     * @return int The count of approved sessions
+     */
+    private function getApprovedInductionSessions($userId)
+    {
+        $sql = "SELECT s.id FROM session AS s "
+            . "INNER JOIN session_field_values AS sfv ON s.id = sfv.session_id "
+            . "INNER JOIN session_field AS sf ON sfv.field_id = sf.id "
+            . "INNER JOIN session_rel_user AS su ON s.id = su.id_session "
+            . "WHERE sf.field_variable = 'is_induccion_session' "
+            . "AND su.relation_type = 0 "
+            . "AND su.id_user = " . intval($userId);
+
+        $result = Database::query($sql);
+
+        if ($result === false) {
+            return 0;
+        }
+
+        $numberOfApproved = 0;
+
+        while ($session = Database::fetch_assoc($result)) {
+            $numberOfApprovedCourses = 0;
+            $courses = SessionManager::get_course_list_by_session_id($session['id']);
+
+            foreach ($courses as $course) {
+                $courseCategories = Category::load(
+                    null,
+                    null,
+                    $course['code'],
+                    null,
+                    null,
+                    $session['id'],
+                    false
+                );
+
+                if (
+                    count($courseCategories) > 0 &&
+                    Category::userFinishedCourse($userId, $courseCategories[0])
+                ) {
+                    $numberOfApprovedCourses++;
+                }
+            }
+
+            if ($numberOfApprovedCourses === count($courses)) {
+                $numberOfApproved++;
+            }
+        }
+
+        return $numberOfApproved;
+    }
+
 }

+ 1 - 0
plugin/advanced_subscription/src/admin_view.php

@@ -65,6 +65,7 @@ if (!empty($sessionId)) {
         $student['userLink'] = api_get_path(WEB_CODE_PATH).'social/profile.php?u='.$studentId;
         $data['queueId'] = intval($student['queue_id']);
         $data['newStatus'] = ADVANCED_SUBSCRIPTION_QUEUE_STATUS_ADMIN_APPROVED;
+        $data['profile_completed'] = 100;
         $student['acceptUrl'] = $plugin->getQueueUrl($data);
         $data['newStatus'] = ADVANCED_SUBSCRIPTION_QUEUE_STATUS_ADMIN_DISAPPROVED;
         $student['rejectUrl'] = $plugin->getQueueUrl($data);

+ 1 - 8
plugin/advanced_subscription/src/terms_and_conditions.php

@@ -24,14 +24,7 @@ $data['termsRejected'] = isset($_REQUEST['r']) ? intval($_REQUEST['r']) : 0;
 // Init template
 $tpl = new Template($plugin->get_lang('plugin_title'));
 
-$isAllowToDoRequest = $plugin->isAllowedToDoRequest(
-    $data['studentUserId'],
-    array(
-        'is_connected' => $data['is_connected'],
-        'profile_completed' => $data['profile_completed']
-    ),
-    true
-);
+$isAllowToDoRequest = $plugin->isAllowedToDoRequest( $data['studentUserId'], $data, true);
 
 if (!$isAllowToDoRequest) {
     $tpl->assign('errorMessages', $plugin->getErrorMessages());

+ 2 - 2
src/Chamilo/UserBundle/Entity/User.php

@@ -105,9 +105,9 @@ class User extends BaseUser //implements ParticipantInterface, ThemeUser
     /**
      * @var boolean
      *
-     * @ORM\Column(name="status", type="integer", nullable=true)
+     * @ORM\Column(name="status", type="integer", nullable=false)
      */
-    private $status;
+    private $status = STUDENT;
 
     /**
      * @var string

+ 81 - 0
tests/features/bootstrap/FeatureContext.php

@@ -0,0 +1,81 @@
+<?php
+
+use Behat\Behat\Context\Context;
+use Behat\Behat\Context\SnippetAcceptingContext;
+use Behat\Gherkin\Node\PyStringNode;
+use Behat\Gherkin\Node\TableNode;
+
+/**
+ * Defines application features from the specific context.
+ */
+class FeatureContext implements Context, SnippetAcceptingContext
+{
+    /**
+     * Initializes context.
+     *
+     * Every scenario gets its own context instance.
+     * You can also pass arbitrary arguments to the
+     * context constructor through behat.yml.
+     */
+    public function __construct()
+    {
+
+    }
+
+    /**
+     * Check Chamilo is installed - otherwise try to install it
+     * @param   BeforeSuiteScope $scope The context scope
+     * @BeforeSuite
+     */
+    public static function prepare($scope)
+    {
+        // prepare system for test suite
+        // before it runs
+        require __DIR__.'/../../../main/inc/lib/api.lib.php';
+        $installed = apiIsSystemInstalled();
+        if ($installed['installed'] == 0) {
+            // Try to install Chamilo
+            //apiInstallChamilo();
+        } else {
+            // show version
+        }
+        require __DIR__.'/../../../main/inc/global.inc.php';
+    }
+
+    /**
+     * @Given I am logged in
+     */
+    public function iAmLoggedIn()
+    {
+        if (api_get_user_id() == 0) {
+            throw new Exception('I am not connected as a user yet');
+        }
+    }
+
+    /**
+     * @Given I am an administrator
+     */
+    public function iAmAnAdministrator()
+    {
+        if (!api_is_platform_admin()) {
+            throw new Exception('I am not connected as an admin');
+        }
+    }
+
+    /**
+     * @When I create a user with e-mail :arg1
+     */
+    public function iCreateAUserWithEMail($email)
+    {
+        throw new PendingException();
+    }
+
+    /**
+     * @Then the user should be added
+     */
+    public function theUserShouldBeAdded()
+    {
+        throw new PendingException();
+    }
+
+}

+ 11 - 0
tests/features/createUser.feature

@@ -0,0 +1,11 @@
+@administration
+Feature: User creation as admin
+  In order to add users
+  As an administrator
+  I need to be able to create new users
+
+Scenario: Create a user with only user's e-mail
+  Given I am logged in
+  And I am an administrator
+  When I create a user with e-mail "sam@example.com"
+  Then the user should be added

+ 0 - 110
tests/phpunit/classes/AccessTest.class.php

@@ -1,110 +0,0 @@
-<?php
-/**
- * Generated by PHPUnit_SkeletonGenerator on 2013-02-17 at 00:36:52.
- */
-// exiting because generates fatal error:
-// Fatal error: Cannot instantiate abstract class Access in /var/lib/jenkins/jobs/chamilo-lms-1.9/workspace/tests/phpunit/classes/AccessTest.class.php on line 18
-//exit;
-return;
-class AccessTest extends PHPUnit_Framework_TestCase
-{
-    /**
-     * @var Access
-     */
-    protected $object;
-
-    /**
-     * Sets up the fixture, for example, opens a network connection.
-     * This method is called before a test is executed.
-     */
-    protected function setUp()
-    {
-        require_once dirname(__FILE__).'/../../../main/inc/global.inc.php';
-        $this->object = new Access;
-    }
-
-    /**
-     * Tears down the fixture, for example, closes a network connection.
-     * This method is called after a test is executed.
-     */
-    protected function tearDown()
-    {
-    }
-
-    /**
-     * Generated from @assert () !== null.
-     *
-     * @covers Access::all
-     */
-    public function testAll()
-    {
-        $this->assertNotSame(
-          null,
-          Access::all()
-        );
-    }
-
-    /**
-     * Generated from @assert () === null.
-     *
-     * @covers Access::forbidden
-     */
-    public function testForbidden()
-    {
-        $this->assertSame(
-          null,
-          Access::forbidden()
-        );
-    }
-
-    /**
-     * Generated from @assert () === false.
-     *
-     * @covers Access::is_token_valid
-     */
-    public function testIs_token_valid()
-    {
-        $this->assertSame(
-          false,
-          $this->object->is_token_valid()
-        );
-    }
-
-    /**
-     * Generated from @assert () !== null.
-     *
-     * @covers Access::get_session_token
-     */
-    public function testGet_session_token()
-    {
-        $this->assertNotSame(
-          null,
-          $this->object->get_session_token()
-        );
-    }
-
-    /**
-     * Generated from @assert () === false.
-     *
-     * @covers Access::authorize
-     */
-    public function testAuthorize()
-    {
-        $this->assertSame(
-          false,
-          $this->object->authorize()
-        );
-    }
-
-    /**
-     * @covers Access::get_token
-     * @todo   Implement testGet_token().
-     */
-    public function testGet_token()
-    {
-        // Remove the following lines when you implement this test.
-        $this->markTestIncomplete(
-          'This test has not been implemented yet.'
-        );
-    }
-}

+ 0 - 47
tests/phpunit/classes/AccessurleditcoursestourlTest.lib.php

@@ -1,47 +0,0 @@
-<?php
-/**
- * Generated by PHPUnit_SkeletonGenerator on 2013-02-17 at 00:38:16.
- */
-class AccessurleditcoursestourlTest extends PHPUnit_Framework_TestCase
-{
-    /**
-     * @var Accessurleditcoursestourl
-     */
-    protected $object;
-
-    /**
-     * Sets up the fixture, for example, opens a network connection.
-     * This method is called before a test is executed.
-     */
-    protected function setUp()
-    {
-        ob_start();
-        require_once dirname(__FILE__).'/../../../main/inc/lib/access_url_edit_courses_to_url_functions.lib.php';
-        require_once dirname(__FILE__).'/../../../main/inc/lib/api.lib.php';
-        $this->object = new Accessurleditcoursestourl;
-    }
-
-    /**
-     * Tears down the fixture, for example, closes a network connection.
-     * This method is called after a test is executed.
-     */
-    protected function tearDown()
-    {
-        ob_end_clean();
-    }
-
-    /**
-     * Generated from @assert () === false.
-     *
-     * @covers Accessurleditcoursestourl::search_courses
-     */
-    public function testSearch_courses()
-    {
-        $this->assertThat(
-          false,
-          $this->logicalNot(
-            $this->equalTo($this->object->search_courses(null, null))
-          )
-        );
-    }
-}

+ 0 - 47
tests/phpunit/classes/AccessurledituserstourlTest.lib.php

@@ -1,47 +0,0 @@
-<?php
-/**
- * Generated by PHPUnit_SkeletonGenerator on 2013-02-17 at 00:39:52.
- */
-class AccessurledituserstourlTest extends PHPUnit_Framework_TestCase
-{
-    /**
-     * @var Accessurledituserstourl
-     */
-    protected $object;
-
-    /**
-     * Sets up the fixture, for example, opens a network connection.
-     * This method is called before a test is executed.
-     */
-    protected function setUp()
-    {
-        ob_start();
-        require_once dirname(__FILE__).'/../../../main/inc/lib/access_url_edit_users_to_url_functions.lib.php';
-        require_once dirname(__FILE__).'/../../../main/inc/lib/api.lib.php';
-        $this->object = new Accessurledituserstourl;
-    }
-
-    /**
-     * Tears down the fixture, for example, closes a network connection.
-     * This method is called after a test is executed.
-     */
-    protected function tearDown()
-    {
-        ob_end_clean();
-    }
-
-    /**
-     * Generated from @assert () === false.
-     *
-     * @covers Accessurledituserstourl::search_users
-     */
-    public function testSearch_users()
-    {
-        $this->assertThat(
-          false,
-          $this->logicalNot(
-            $this->equalTo($this->object->search_users(null, null))
-          )
-        );
-    }
-}

+ 0 - 69
tests/phpunit/classes/AddCourseToSessionTest.lib.php

@@ -1,69 +0,0 @@
-<?php
-/**
- * Generated by PHPUnit_SkeletonGenerator on 2013-02-17 at 00:43:47.
- */
-class AddCourseToSessionTest extends PHPUnit_Framework_TestCase
-{
-    /**
-     * @var AddCourseToSession
-     */
-    protected $object;
-
-    /**
-     * Sets up the fixture, for example, opens a network connection.
-     * This method is called before a test is executed.
-     */
-    protected function setUp()
-    {
-        require_once dirname(__FILE__).'/../../../main/inc/global.inc.php';
-        require_once dirname(__FILE__).'/../../../main/inc/lib/database.lib.php';
-        $this->object = new AddCourseToSession;
-    }
-
-    /**
-     * Tears down the fixture, for example, closes a network connection.
-     * This method is called after a test is executed.
-     */
-    protected function tearDown()
-    {
-    }
-
-    /**
-     * Generated from @assert () !== null.
-     *
-     * @covers AddCourseToSession::search_courses
-     */
-    public function testSearch_courses()
-    {
-        $this->assertNotSame(
-          null,
-          $this->object->search_courses()
-        );
-    }
-
-    /**
-     * Generated from @assert ('abc', 'single') !== null.
-     *
-     * @covers AddCourseToSession::search_courses
-     */
-    public function testSearch_courses2()
-    {
-        $this->assertNotSame(
-          null,
-          $this->object->search_courses('abc', 'single')
-        );
-    }
-
-    /**
-     * Generated from @assert ('abc', 'multiple') !== null.
-     *
-     * @covers AddCourseToSession::search_courses
-     */
-    public function testSearch_courses3()
-    {
-        $this->assertNotSame(
-          null,
-          $this->object->search_courses('abc', 'multiple')
-        );
-    }
-}

+ 0 - 55
tests/phpunit/classes/AddManySessionToCategoryFunctionsTest.lib.php

@@ -1,55 +0,0 @@
-<?php
-/**
- * Generated by PHPUnit_SkeletonGenerator on 2013-02-17 at 01:03:12.
- */
-class AddManySessionToCategoryFunctionsTest extends PHPUnit_Framework_TestCase
-{
-    /**
-     * @var AddManySessionToCategoryFunctions
-     */
-    protected $object;
-
-    /**
-     * Sets up the fixture, for example, opens a network connection.
-     * This method is called before a test is executed.
-     */
-    protected function setUp()
-    {
-        require_once dirname(__FILE__).'/../../../main/inc/global.inc.php';
-        $this->object = new AddManySessionToCategoryFunctions;
-    }
-
-    /**
-     * Tears down the fixture, for example, closes a network connection.
-     * This method is called after a test is executed.
-     */
-    protected function tearDown()
-    {
-    }
-
-    /**
-     * Generated from @assert () !== ''.
-     *
-     * @covers AddManySessionToCategoryFunctions::search_courses
-     */
-    public function testSearch_courses()
-    {
-        $this->assertNotSame(
-          '',
-          $this->object->search_courses()
-        );
-    }
-
-    /**
-     * Generated from @assert ('abc','single') !== ''.
-     *
-     * @covers AddManySessionToCategoryFunctions::search_courses
-     */
-    public function testSearch_courses2()
-    {
-        $this->assertNotSame(
-          '',
-          $this->object->search_courses('abc','single')
-        );
-    }
-}

+ 0 - 280
tests/phpunit/classes/AppPluginTest.class.php

@@ -1,280 +0,0 @@
-<?php
-/**
- * Generated by PHPUnit_SkeletonGenerator on 2013-01-07 at 09:29:53.
- */
-class AppPluginTest extends PHPUnit_Framework_TestCase
-{
-    /**
-     * @var AppPlugin
-     */
-    protected $object;
-
-    /**
-     * Sets up the fixture, for example, opens a network connection.
-     * This method is called before a test is executed.
-     */
-    protected function setUp()
-    {
-        $this->object = new AppPlugin;
-    }
-
-    /**
-     * Tears down the fixture, for example, closes a network connection.
-     * This method is called after a test is executed.
-     */
-    protected function tearDown()
-    {
-    }
-
-    /**
-     * @covers AppPlugin::read_plugins_from_path
-     * @todo   Implement testRead_plugins_from_path().
-     */
-    public function testRead_plugins_from_path()
-    {
-        // Remove the following lines when you implement this test.
-        $this->markTestIncomplete(
-          'This test has not been implemented yet.'
-        );
-    }
-
-    /**
-     * @covers AppPlugin::get_installed_plugins_by_region
-     * @todo   Implement testGet_installed_plugins_by_region().
-     */
-    public function testGet_installed_plugins_by_region()
-    {
-        // Remove the following lines when you implement this test.
-        $this->markTestIncomplete(
-          'This test has not been implemented yet.'
-        );
-    }
-
-    /**
-     * @covers AppPlugin::get_installed_plugins
-     * @todo   Implement testGet_installed_plugins().
-     */
-    public function testGet_installed_plugins()
-    {
-        // Remove the following lines when you implement this test.
-        $this->markTestIncomplete(
-          'This test has not been implemented yet.'
-        );
-    }
-
-    /**
-     * @covers AppPlugin::install
-     * @todo   Implement testInstall().
-     */
-    public function testInstall()
-    {
-        // Remove the following lines when you implement this test.
-        $this->markTestIncomplete(
-          'This test has not been implemented yet.'
-        );
-    }
-
-    /**
-     * @covers AppPlugin::uninstall
-     * @todo   Implement testUninstall().
-     */
-    public function testUninstall()
-    {
-        // Remove the following lines when you implement this test.
-        $this->markTestIncomplete(
-          'This test has not been implemented yet.'
-        );
-    }
-
-    /**
-     * @covers AppPlugin::get_areas_by_plugin
-     * @todo   Implement testGet_areas_by_plugin().
-     */
-    public function testGet_areas_by_plugin()
-    {
-        // Remove the following lines when you implement this test.
-        $this->markTestIncomplete(
-          'This test has not been implemented yet.'
-        );
-    }
-
-    /**
-     * @covers AppPlugin::is_valid_plugin_location
-     * @todo   Implement testIs_valid_plugin_location().
-     */
-    public function testIs_valid_plugin_location()
-    {
-        // Remove the following lines when you implement this test.
-        $this->markTestIncomplete(
-          'This test has not been implemented yet.'
-        );
-    }
-
-    /**
-     * @covers AppPlugin::is_valid_plugin
-     * @todo   Implement testIs_valid_plugin().
-     */
-    public function testIs_valid_plugin()
-    {
-        // Remove the following lines when you implement this test.
-        $this->markTestIncomplete(
-          'This test has not been implemented yet.'
-        );
-    }
-
-    /**
-     * @covers AppPlugin::get_plugin_regions
-     * @todo   Implement testGet_plugin_regions().
-     */
-    public function testGet_plugin_regions()
-    {
-        // Remove the following lines when you implement this test.
-        $this->markTestIncomplete(
-          'This test has not been implemented yet.'
-        );
-    }
-
-    /**
-     * @covers AppPlugin::load_region
-     * @todo   Implement testLoad_region().
-     */
-    public function testLoad_region()
-    {
-        // Remove the following lines when you implement this test.
-        $this->markTestIncomplete(
-          'This test has not been implemented yet.'
-        );
-    }
-
-    /**
-     * @covers AppPlugin::load_plugin_lang_variables
-     * @todo   Implement testLoad_plugin_lang_variables().
-     */
-    public function testLoad_plugin_lang_variables()
-    {
-        // Remove the following lines when you implement this test.
-        $this->markTestIncomplete(
-          'This test has not been implemented yet.'
-        );
-    }
-
-    /**
-     * @covers AppPlugin::get_all_plugin_contents_by_region
-     * @todo   Implement testGet_all_plugin_contents_by_region().
-     */
-    public function testGet_all_plugin_contents_by_region()
-    {
-        // Remove the following lines when you implement this test.
-        $this->markTestIncomplete(
-          'This test has not been implemented yet.'
-        );
-    }
-
-    /**
-     * @covers AppPlugin::get_plugin_info
-     * @todo   Implement testGet_plugin_info().
-     */
-    public function testGet_plugin_info()
-    {
-        // Remove the following lines when you implement this test.
-        $this->markTestIncomplete(
-          'This test has not been implemented yet.'
-        );
-    }
-
-    /**
-     * @covers AppPlugin::get_templates_list
-     * @todo   Implement testGet_templates_list().
-     */
-    public function testGet_templates_list()
-    {
-        // Remove the following lines when you implement this test.
-        $this->markTestIncomplete(
-          'This test has not been implemented yet.'
-        );
-    }
-
-    /**
-     * @covers AppPlugin::remove_all_regions
-     * @todo   Implement testRemove_all_regions().
-     */
-    public function testRemove_all_regions()
-    {
-        // Remove the following lines when you implement this test.
-        $this->markTestIncomplete(
-          'This test has not been implemented yet.'
-        );
-    }
-
-    /**
-     * @covers AppPlugin::add_to_region
-     * @todo   Implement testAdd_to_region().
-     */
-    public function testAdd_to_region()
-    {
-        // Remove the following lines when you implement this test.
-        $this->markTestIncomplete(
-          'This test has not been implemented yet.'
-        );
-    }
-
-    /**
-     * @covers AppPlugin::install_course_plugins
-     * @todo   Implement testInstall_course_plugins().
-     */
-    public function testInstall_course_plugins()
-    {
-        // Remove the following lines when you implement this test.
-        $this->markTestIncomplete(
-          'This test has not been implemented yet.'
-        );
-    }
-
-    /**
-     * @covers AppPlugin::add_course_settings_form
-     * @todo   Implement testAdd_course_settings_form().
-     */
-    public function testAdd_course_settings_form()
-    {
-        // Remove the following lines when you implement this test.
-        $this->markTestIncomplete(
-          'This test has not been implemented yet.'
-        );
-    }
-
-    /**
-     * @covers AppPlugin::set_course_settings_defaults
-     * @todo   Implement testSet_course_settings_defaults().
-     */
-    public function testSet_course_settings_defaults()
-    {
-        // Remove the following lines when you implement this test.
-        $this->markTestIncomplete(
-          'This test has not been implemented yet.'
-        );
-    }
-
-    /**
-     * @covers AppPlugin::save_course_settings
-     * @todo   Implement testSave_course_settings().
-     */
-    public function testSave_course_settings()
-    {
-        // Remove the following lines when you implement this test.
-        $this->markTestIncomplete(
-          'This test has not been implemented yet.'
-        );
-    }
-
-    /**
-     * @covers AppPlugin::get_plugin_course_settings
-     * @todo   Implement testGet_plugin_course_settings().
-     */
-    public function testGet_plugin_course_settings()
-    {
-        // Remove the following lines when you implement this test.
-        $this->markTestIncomplete(
-          'This test has not been implemented yet.'
-        );
-    }
-}

+ 0 - 1326
tests/phpunit/classes/UserManagerTest.lib.php

@@ -1,1326 +0,0 @@
-<?php
-/**
- * Generated by PHPUnit_SkeletonGenerator on 2013-01-07 at 09:32:19.
- */
-class UserManagerTest extends PHPUnit_Framework_TestCase
-{
-    /**
-     * @var UserManager
-     */
-    protected $object;
-
-    /**
-     * Sets up the fixture, for example, opens a network connection.
-     * This method is called before a test is executed.
-     */
-    protected function setUp()
-    {
-        require_once dirname(__FILE__).'/../../../main/inc/global.inc.php';
-        $this->object = new UserManager;
-    }
-
-    /**
-     * Tears down the fixture, for example, closes a network connection.
-     * This method is called after a test is executed.
-     */
-    protected function tearDown()
-    {
-    }
-
-    /**
-     * Generated from @assert ('Sam','Gamegie',5,'sam@example.com','jo','jo') > 1.
-     *
-     * @covers UserManager::create_user
-     */
-    public function testCreate_user()
-    {
-        $this->assertGreaterThan(
-          1,
-          UserManager::create_user('Sam','Gamgee',5,'sam@example.com','jo','jo')
-        );
-    }
-
-    /**
-     * Generated from @assert ('Pippin','Took',null,null,'jo','jo') === false.
-     *
-     * @covers UserManager::create_user
-     */
-    public function testCreate_user2()
-    {
-        $this->assertSame(
-          false,
-          UserManager::create_user('Pippin','Brandybuck',null,null,'jo','jo')
-        );
-    }
-    /**
-     * Test multiple URL case with users hosting limit
-     */
-    public function testCreate_user3()
-    {
-        global $_configuration;
-        $_configuration[1]['hosting_limit_users'] = 50;
-        $this->assertSame(
-          false,
-          UserManager::create_user('Merry','Brandybuck',null,null,'jo','jo')
-        );
-    }
-    /**
-     * Test teachers hosting limit
-     */
-    public function testCreate_user4()
-    {
-        global $_configuration;
-        $_configuration[1]['hosting_limit_teachers'] = 50;
-        $this->assertSame(
-          false,
-          UserManager::create_user('Pippin','Took',1,null,'jo','jo')
-        );
-    }
-    /**
-     * Test language non-existence
-     */
-    public function testCreate_user5()
-    {
-        global $_configuration;
-        $this->assertSame(
-          false,
-          UserManager::create_user('Pippin','Tooky',null,null,'jo','jo',null,'spaniard')
-        );
-    }
-
-    /**
-     * Generated from @assert (null) === false.
-     *
-     * @covers UserManager::can_delete_user
-     */
-    /*
-    public function testCan_delete_user()
-    {
-        $this->assertSame(
-          false,
-          UserManager::can_delete_user(null)
-        );
-    }
-    */
-    /**
-     * Generated from @assert (-1) === false.
-     *
-     * @covers UserManager::can_delete_user
-     */
-    public function testCan_delete_user2()
-    {
-        $this->assertSame(
-          false,
-          UserManager::can_delete_user(-1)
-        );
-    }
-
-    /**
-     * Generated from @assert ('abc') === false.
-     *
-     * @covers UserManager::can_delete_user
-     */
-    public function testCan_delete_user3()
-    {
-        $this->assertSame(
-          false,
-          UserManager::can_delete_user('abc')
-        );
-    }
-
-    /**
-     * Generated from @assert (null) === false.
-     *
-     * @covers UserManager::delete_user
-     */
-    public function testDelete_user()
-    {
-        $this->assertSame(
-          false,
-          UserManager::delete_user(null)
-        );
-    }
-
-    /**
-     * Generated from @assert ('abc') === false.
-     *
-     * @covers UserManager::delete_user
-     */
-    public function testDelete_user2()
-    {
-        $this->assertSame(
-          false,
-          UserManager::delete_user('abc')
-        );
-    }
-
-    /**
-     * Generated from @assert (null) === false.
-     *
-     * @covers UserManager::delete_users
-     */
-    public function testDelete_users()
-    {
-        $this->assertSame(
-          false,
-          UserManager::delete_users(null)
-        );
-    }
-
-    /**
-     * Generated from @assert (-1) === false.
-     *
-     * @covers UserManager::delete_users
-     */
-    public function testDelete_users2()
-    {
-        $this->assertSame(
-          false,
-          UserManager::delete_users(-1)
-        );
-    }
-
-    /**
-     * Generated from @assert (array(-1)) === false.
-     *
-     * @covers UserManager::delete_users
-     */
-    public function testDelete_users3()
-    {
-        $this->assertSame(
-          false,
-          UserManager::delete_users(array(-1))
-        );
-    }
-
-    /**
-     * Generated from @assert (null) === false.
-     *
-     * @covers UserManager::deactivate_users
-     */
-    public function testDeactivate_users()
-    {
-        $this->assertSame(
-          false,
-          UserManager::deactivate_users(null)
-        );
-    }
-
-    /**
-     * Generated from @assert (array(-1)) === false.
-     *
-     * @covers UserManager::deactivate_users
-     */
-    public function testDeactivate_users2()
-    {
-        $this->assertSame(
-          false,
-          UserManager::deactivate_users(array(-1))
-        );
-    }
-
-    /**
-     * Generated from @assert (null) === false.
-     *
-     * @covers UserManager::activate_users
-     */
-    public function testActivate_users()
-    {
-        $this->assertSame(
-          false,
-          UserManager::activate_users(null)
-        );
-    }
-
-    /**
-     * Generated from @assert (array(-1)) === false.
-     *
-     * @covers UserManager::activate_users
-     */
-    public function testActivate_users2()
-    {
-        $this->assertSame(
-          false,
-          UserManager::activate_users(array(-1))
-        );
-    }
-
-    /**
-     * Generated from @assert (false,'') === false.
-     *
-     * @covers UserManager::update_openid
-     */
-    public function testUpdate_openid()
-    {
-        $this->assertSame(
-          false,
-          UserManager::update_openid(false,'')
-        );
-    }
-
-    /**
-     * Generated from @assert (-1,'') === false.
-     *
-     * @covers UserManager::update_openid
-     */
-    public function testUpdate_openid2()
-    {
-        $this->assertSame(
-          false,
-          UserManager::update_openid(-1,'')
-        );
-    }
-
-    /**
-     * Generated from @assert (false, false, false, false, false, false, false, false, false, false, false, false, false) === false.
-     *
-     * @covers UserManager::update_user
-     */
-    public function testUpdate_user()
-    {
-        $this->assertSame(
-          false,
-          UserManager::update_user(false,false,false,false,false,false,false,false,false,false,false,false,false)
-        );
-    }
-
-    /**
-     * Generated from @assert (0) === false.
-     *
-     * @covers UserManager::disable
-     */
-    public function testDisable()
-    {
-        $this->assertSame(
-          false,
-          UserManager::disable(0)
-        );
-    }
-
-    /**
-     * Generated from @assert (0) === false.
-     *
-     * @covers UserManager::enable
-     */
-    public function testEnable()
-    {
-        $this->assertSame(
-          false,
-          UserManager::enable(0)
-        );
-    }
-
-    /**
-     * Generated from @assert ('0','---') === 0.
-     *
-     * @covers UserManager::get_user_id_from_original_id
-     */
-    public function testGet_user_id_from_original_id()
-    {
-        $this->assertSame(
-          0,
-          UserManager::get_user_id_from_original_id('0','---')
-        );
-    }
-
-    /**
-     * Generated from @assert ('') === false.
-     *
-     * @covers UserManager::is_username_available
-     */
-    public function testIs_username_available()
-    {
-        $this->assertSame(
-          false,
-          UserManager::is_username_available('')
-        );
-    }
-
-    /**
-     * Generated from @assert ('xyzxyzxyz') === true.
-     *
-     * @covers UserManager::is_username_available
-     */
-    public function testIs_username_available2()
-    {
-        $this->assertSame(
-          true,
-          UserManager::is_username_available('xyzxyzxyz')
-        );
-    }
-
-    /**
-     * Generated from @assert ('','') === false.
-     *
-     * @covers UserManager::create_username
-     */
-    public function testCreate_username()
-    {
-        $this->assertSame(
-          false,
-          UserManager::create_username('','')
-        );
-    }
-
-    /**
-     * Generated from @assert ('a','b') === 'ab'.
-     *
-     * @covers UserManager::create_username
-     */
-    public function testCreate_username2()
-    {
-        $this->assertSame(
-          'ab',
-          UserManager::create_username('a','b')
-        );
-    }
-
-    /**
-     * @covers UserManager::create_unique_username
-     * @todo   Implement testCreate_unique_username().
-     */
-    public function testCreate_unique_username()
-    {
-        // Remove the following lines when you implement this test.
-        $this->markTestIncomplete(
-          'This test has not been implemented yet.'
-        );
-    }
-
-    /**
-     * @covers UserManager::purify_username
-     * @todo   Implement testPurify_username().
-     */
-    public function testPurify_username()
-    {
-        // Remove the following lines when you implement this test.
-        $this->markTestIncomplete(
-          'This test has not been implemented yet.'
-        );
-    }
-
-    /**
-     * @covers UserManager::is_user_id_valid
-     * @todo   Implement testIs_user_id_valid().
-     */
-    public function testIs_user_id_valid()
-    {
-        // Remove the following lines when you implement this test.
-        $this->markTestIncomplete(
-          'This test has not been implemented yet.'
-        );
-    }
-
-    /**
-     * @covers UserManager::is_username_valid
-     * @todo   Implement testIs_username_valid().
-     */
-    public function testIs_username_valid()
-    {
-        // Remove the following lines when you implement this test.
-        $this->markTestIncomplete(
-          'This test has not been implemented yet.'
-        );
-    }
-
-    /**
-     * @covers UserManager::is_username_empty
-     * @todo   Implement testIs_username_empty().
-     */
-    public function testIs_username_empty()
-    {
-        // Remove the following lines when you implement this test.
-        $this->markTestIncomplete(
-          'This test has not been implemented yet.'
-        );
-    }
-
-    /**
-     * @covers UserManager::is_username_too_long
-     * @todo   Implement testIs_username_too_long().
-     */
-    public function testIs_username_too_long()
-    {
-        // Remove the following lines when you implement this test.
-        $this->markTestIncomplete(
-          'This test has not been implemented yet.'
-        );
-    }
-
-    /**
-     * @covers UserManager::get_user_list_by_ids
-     * @todo   Implement testGet_user_list_by_ids().
-     */
-    public function testGet_user_list_by_ids()
-    {
-        // Remove the following lines when you implement this test.
-        $this->markTestIncomplete(
-          'This test has not been implemented yet.'
-        );
-    }
-
-    /**
-     * @covers UserManager::get_user_list
-     * @todo   Implement testGet_user_list().
-     */
-    public function testGet_user_list()
-    {
-        // Remove the following lines when you implement this test.
-        $this->markTestIncomplete(
-          'This test has not been implemented yet.'
-        );
-    }
-
-    /**
-     * @covers UserManager::get_user_list_like
-     * @todo   Implement testGet_user_list_like().
-     */
-    public function testGet_user_list_like()
-    {
-        // Remove the following lines when you implement this test.
-        $this->markTestIncomplete(
-          'This test has not been implemented yet.'
-        );
-    }
-
-    /**
-     * @covers UserManager::get_user_info
-     * @todo   Implement testGet_user_info().
-     */
-    public function testGet_user_info()
-    {
-        // Remove the following lines when you implement this test.
-        $this->markTestIncomplete(
-          'This test has not been implemented yet.'
-        );
-    }
-
-    /**
-     * @covers UserManager::get_user_info_by_id
-     * @todo   Implement testGet_user_info_by_id().
-     */
-    public function testGet_user_info_by_id()
-    {
-        // Remove the following lines when you implement this test.
-        $this->markTestIncomplete(
-          'This test has not been implemented yet.'
-        );
-    }
-
-    /**
-     * @covers UserManager::get_teacher_list
-     * @todo   Implement testGet_teacher_list().
-     */
-    public function testGet_teacher_list()
-    {
-        // Remove the following lines when you implement this test.
-        $this->markTestIncomplete(
-          'This test has not been implemented yet.'
-        );
-    }
-
-    /**
-     * @covers UserManager::get_user_picture_path_by_id
-     * @todo   Implement testGet_user_picture_path_by_id().
-     */
-    public function testGet_user_picture_path_by_id()
-    {
-        // Remove the following lines when you implement this test.
-        $this->markTestIncomplete(
-          'This test has not been implemented yet.'
-        );
-    }
-
-    /**
-     * @covers UserManager::update_user_picture
-     * @todo   Implement testUpdate_user_picture().
-     */
-    public function testUpdate_user_picture()
-    {
-        // Remove the following lines when you implement this test.
-        $this->markTestIncomplete(
-          'This test has not been implemented yet.'
-        );
-    }
-
-    /**
-     * @covers UserManager::delete_user_picture
-     * @todo   Implement testDelete_user_picture().
-     */
-    public function testDelete_user_picture()
-    {
-        // Remove the following lines when you implement this test.
-        $this->markTestIncomplete(
-          'This test has not been implemented yet.'
-        );
-    }
-
-    /**
-     * @covers UserManager::build_production_list
-     * @todo   Implement testBuild_production_list().
-     */
-    public function testBuild_production_list()
-    {
-        // Remove the following lines when you implement this test.
-        $this->markTestIncomplete(
-          'This test has not been implemented yet.'
-        );
-    }
-
-    /**
-     * @covers UserManager::get_user_productions
-     * @todo   Implement testGet_user_productions().
-     */
-    public function testGet_user_productions()
-    {
-        // Remove the following lines when you implement this test.
-        $this->markTestIncomplete(
-          'This test has not been implemented yet.'
-        );
-    }
-
-    /**
-     * @covers UserManager::remove_user_production
-     * @todo   Implement testRemove_user_production().
-     */
-    public function testRemove_user_production()
-    {
-        // Remove the following lines when you implement this test.
-        $this->markTestIncomplete(
-          'This test has not been implemented yet.'
-        );
-    }
-
-    /**
-     * @covers UserManager::update_extra_field
-     * @todo   Implement testUpdate_extra_field().
-     */
-    public function testUpdate_extra_field()
-    {
-        // Remove the following lines when you implement this test.
-        $this->markTestIncomplete(
-          'This test has not been implemented yet.'
-        );
-    }
-
-    /**
-     * @covers UserManager::update_extra_field_value
-     * @todo   Implement testUpdate_extra_field_value().
-     */
-    public function testUpdate_extra_field_value()
-    {
-        // Remove the following lines when you implement this test.
-        $this->markTestIncomplete(
-          'This test has not been implemented yet.'
-        );
-    }
-
-    /**
-     * @covers UserManager::get_extra_fields
-     * @todo   Implement testGet_extra_fields().
-     */
-    public function testGet_extra_fields()
-    {
-        // Remove the following lines when you implement this test.
-        $this->markTestIncomplete(
-          'This test has not been implemented yet.'
-        );
-    }
-
-    /**
-     * @covers UserManager::get_extra_field_options
-     * @todo   Implement testGet_extra_field_options().
-     */
-    public function testGet_extra_field_options()
-    {
-        // Remove the following lines when you implement this test.
-        $this->markTestIncomplete(
-          'This test has not been implemented yet.'
-        );
-    }
-
-    /**
-     * @covers UserManager::get_number_of_extra_fields
-     * @todo   Implement testGet_number_of_extra_fields().
-     */
-    public function testGet_number_of_extra_fields()
-    {
-        // Remove the following lines when you implement this test.
-        $this->markTestIncomplete(
-          'This test has not been implemented yet.'
-        );
-    }
-
-    /**
-     * @covers UserManager::create_extra_field
-     * @todo   Implement testCreate_extra_field().
-     */
-    public function testCreate_extra_field()
-    {
-        // Remove the following lines when you implement this test.
-        $this->markTestIncomplete(
-          'This test has not been implemented yet.'
-        );
-    }
-
-    /**
-     * @covers UserManager::save_extra_field_changes
-     * @todo   Implement testSave_extra_field_changes().
-     */
-    public function testSave_extra_field_changes()
-    {
-        // Remove the following lines when you implement this test.
-        $this->markTestIncomplete(
-          'This test has not been implemented yet.'
-        );
-    }
-
-    /**
-     * @covers UserManager::is_extra_field_available
-     * @todo   Implement testIs_extra_field_available().
-     */
-    public function testIs_extra_field_available()
-    {
-        // Remove the following lines when you implement this test.
-        $this->markTestIncomplete(
-          'This test has not been implemented yet.'
-        );
-    }
-
-    /**
-     * @covers UserManager::get_extra_user_data
-     * @todo   Implement testGet_extra_user_data().
-     */
-    public function testGet_extra_user_data()
-    {
-        // Remove the following lines when you implement this test.
-        $this->markTestIncomplete(
-          'This test has not been implemented yet.'
-        );
-    }
-
-    /**
-     * @covers UserManager::get_extra_user_data_by_field
-     * @todo   Implement testGet_extra_user_data_by_field().
-     */
-    public function testGet_extra_user_data_by_field()
-    {
-        // Remove the following lines when you implement this test.
-        $this->markTestIncomplete(
-          'This test has not been implemented yet.'
-        );
-    }
-
-    /**
-     * @covers UserManager::get_extra_field_information_by_name
-     * @todo   Implement testGet_extra_field_information_by_name().
-     */
-    public function testGet_extra_field_information_by_name()
-    {
-        // Remove the following lines when you implement this test.
-        $this->markTestIncomplete(
-          'This test has not been implemented yet.'
-        );
-    }
-
-    /**
-     * @covers UserManager::get_all_extra_field_by_type
-     * @todo   Implement testGet_all_extra_field_by_type().
-     */
-    public function testGet_all_extra_field_by_type()
-    {
-        // Remove the following lines when you implement this test.
-        $this->markTestIncomplete(
-          'This test has not been implemented yet.'
-        );
-    }
-
-    /**
-     * @covers UserManager::get_extra_field_information
-     * @todo   Implement testGet_extra_field_information().
-     */
-    public function testGet_extra_field_information()
-    {
-        // Remove the following lines when you implement this test.
-        $this->markTestIncomplete(
-          'This test has not been implemented yet.'
-        );
-    }
-
-    /**
-     * @covers UserManager::get_extra_user_data_by_value
-     * @todo   Implement testGet_extra_user_data_by_value().
-     */
-    public function testGet_extra_user_data_by_value()
-    {
-        // Remove the following lines when you implement this test.
-        $this->markTestIncomplete(
-          'This test has not been implemented yet.'
-        );
-    }
-
-    /**
-     * @covers UserManager::get_extra_user_data_by_field_variable
-     * @todo   Implement testGet_extra_user_data_by_field_variable().
-     */
-    public function testGet_extra_user_data_by_field_variable()
-    {
-        // Remove the following lines when you implement this test.
-        $this->markTestIncomplete(
-          'This test has not been implemented yet.'
-        );
-    }
-
-    /**
-     * @covers UserManager::get_sessions_by_category
-     * @todo   Implement testGet_sessions_by_category().
-     */
-    public function testGet_sessions_by_category()
-    {
-        // Remove the following lines when you implement this test.
-        $this->markTestIncomplete(
-          'This test has not been implemented yet.'
-        );
-    }
-
-    /**
-     * @covers UserManager::get_personal_session_course_list
-     * @todo   Implement testGet_personal_session_course_list().
-     */
-    public function testGet_personal_session_course_list()
-    {
-        // Remove the following lines when you implement this test.
-        $this->markTestIncomplete(
-          'This test has not been implemented yet.'
-        );
-    }
-
-    /**
-     * @covers UserManager::get_courses_list_by_session
-     * @todo   Implement testGet_courses_list_by_session().
-     */
-    public function testGet_courses_list_by_session()
-    {
-        // Remove the following lines when you implement this test.
-        $this->markTestIncomplete(
-          'This test has not been implemented yet.'
-        );
-    }
-
-    /**
-     * @covers UserManager::get_user_id_from_username
-     * @todo   Implement testGet_user_id_from_username().
-     */
-    public function testGet_user_id_from_username()
-    {
-        // Remove the following lines when you implement this test.
-        $this->markTestIncomplete(
-          'This test has not been implemented yet.'
-        );
-    }
-
-    /**
-     * @covers UserManager::get_user_upload_files_by_course
-     * @todo   Implement testGet_user_upload_files_by_course().
-     */
-    public function testGet_user_upload_files_by_course()
-    {
-        // Remove the following lines when you implement this test.
-        $this->markTestIncomplete(
-          'This test has not been implemented yet.'
-        );
-    }
-
-    /**
-     * @covers UserManager::get_api_keys
-     * @todo   Implement testGet_api_keys().
-     */
-    public function testGet_api_keys()
-    {
-        // Remove the following lines when you implement this test.
-        $this->markTestIncomplete(
-          'This test has not been implemented yet.'
-        );
-    }
-
-    /**
-     * @covers UserManager::add_api_key
-     * @todo   Implement testAdd_api_key().
-     */
-    public function testAdd_api_key()
-    {
-        // Remove the following lines when you implement this test.
-        $this->markTestIncomplete(
-          'This test has not been implemented yet.'
-        );
-    }
-
-    /**
-     * @covers UserManager::delete_api_key
-     * @todo   Implement testDelete_api_key().
-     */
-    public function testDelete_api_key()
-    {
-        // Remove the following lines when you implement this test.
-        $this->markTestIncomplete(
-          'This test has not been implemented yet.'
-        );
-    }
-
-    /**
-     * @covers UserManager::update_api_key
-     * @todo   Implement testUpdate_api_key().
-     */
-    public function testUpdate_api_key()
-    {
-        // Remove the following lines when you implement this test.
-        $this->markTestIncomplete(
-          'This test has not been implemented yet.'
-        );
-    }
-
-    /**
-     * @covers UserManager::get_api_key_id
-     * @todo   Implement testGet_api_key_id().
-     */
-    public function testGet_api_key_id()
-    {
-        // Remove the following lines when you implement this test.
-        $this->markTestIncomplete(
-          'This test has not been implemented yet.'
-        );
-    }
-
-    /**
-     * @covers UserManager::is_admin
-     * @todo   Implement testIs_admin().
-     */
-    public function testIs_admin()
-    {
-        // Remove the following lines when you implement this test.
-        $this->markTestIncomplete(
-          'This test has not been implemented yet.'
-        );
-    }
-
-    /**
-     * @covers UserManager::get_number_of_users
-     * @todo   Implement testGet_number_of_users().
-     */
-    public function testGet_number_of_users()
-    {
-        // Remove the following lines when you implement this test.
-        $this->markTestIncomplete(
-          'This test has not been implemented yet.'
-        );
-    }
-
-    /**
-     * @covers UserManager::resize_picture
-     * @todo   Implement testResize_picture().
-     */
-    public function testResize_picture()
-    {
-        // Remove the following lines when you implement this test.
-        $this->markTestIncomplete(
-          'This test has not been implemented yet.'
-        );
-    }
-
-    /**
-     * @covers UserManager::get_picture_user
-     * @todo   Implement testGet_picture_user().
-     */
-    public function testGet_picture_user()
-    {
-        // Remove the following lines when you implement this test.
-        $this->markTestIncomplete(
-          'This test has not been implemented yet.'
-        );
-    }
-
-    /**
-     * @covers UserManager::send_message_in_outbox
-     * @todo   Implement testSend_message_in_outbox().
-     */
-    public function testSend_message_in_outbox()
-    {
-        // Remove the following lines when you implement this test.
-        $this->markTestIncomplete(
-          'This test has not been implemented yet.'
-        );
-    }
-
-    /**
-     * @covers UserManager::get_tags
-     * @todo   Implement testGet_tags().
-     */
-    public function testGet_tags()
-    {
-        // Remove the following lines when you implement this test.
-        $this->markTestIncomplete(
-          'This test has not been implemented yet.'
-        );
-    }
-
-    /**
-     * @covers UserManager::get_top_tags
-     * @todo   Implement testGet_top_tags().
-     */
-    public function testGet_top_tags()
-    {
-        // Remove the following lines when you implement this test.
-        $this->markTestIncomplete(
-          'This test has not been implemented yet.'
-        );
-    }
-
-    /**
-     * @covers UserManager::get_user_tags
-     * @todo   Implement testGet_user_tags().
-     */
-    public function testGet_user_tags()
-    {
-        // Remove the following lines when you implement this test.
-        $this->markTestIncomplete(
-          'This test has not been implemented yet.'
-        );
-    }
-
-    /**
-     * @covers UserManager::get_user_tags_to_string
-     * @todo   Implement testGet_user_tags_to_string().
-     */
-    public function testGet_user_tags_to_string()
-    {
-        // Remove the following lines when you implement this test.
-        $this->markTestIncomplete(
-          'This test has not been implemented yet.'
-        );
-    }
-
-    /**
-     * @covers UserManager::get_tag_id
-     * @todo   Implement testGet_tag_id().
-     */
-    public function testGet_tag_id()
-    {
-        // Remove the following lines when you implement this test.
-        $this->markTestIncomplete(
-          'This test has not been implemented yet.'
-        );
-    }
-
-    /**
-     * @covers UserManager::get_tag_id_from_id
-     * @todo   Implement testGet_tag_id_from_id().
-     */
-    public function testGet_tag_id_from_id()
-    {
-        // Remove the following lines when you implement this test.
-        $this->markTestIncomplete(
-          'This test has not been implemented yet.'
-        );
-    }
-
-    /**
-     * @covers UserManager::add_tag
-     * @todo   Implement testAdd_tag().
-     */
-    public function testAdd_tag()
-    {
-        // Remove the following lines when you implement this test.
-        $this->markTestIncomplete(
-          'This test has not been implemented yet.'
-        );
-    }
-
-    /**
-     * @covers UserManager::delete_user_tags
-     * @todo   Implement testDelete_user_tags().
-     */
-    public function testDelete_user_tags()
-    {
-        // Remove the following lines when you implement this test.
-        $this->markTestIncomplete(
-          'This test has not been implemented yet.'
-        );
-    }
-
-    /**
-     * @covers UserManager::process_tags
-     * @todo   Implement testProcess_tags().
-     */
-    public function testProcess_tags()
-    {
-        // Remove the following lines when you implement this test.
-        $this->markTestIncomplete(
-          'This test has not been implemented yet.'
-        );
-    }
-
-    /**
-     * @covers UserManager::get_all_administrators
-     * @todo   Implement testGet_all_administrators().
-     */
-    public function testGet_all_administrators()
-    {
-        // Remove the following lines when you implement this test.
-        $this->markTestIncomplete(
-          'This test has not been implemented yet.'
-        );
-    }
-
-    /**
-     * @covers UserManager::get_all_user_tags
-     * @todo   Implement testGet_all_user_tags().
-     */
-    public function testGet_all_user_tags()
-    {
-        // Remove the following lines when you implement this test.
-        $this->markTestIncomplete(
-          'This test has not been implemented yet.'
-        );
-    }
-
-    /**
-     * @covers UserManager::get_search_form
-     * @todo   Implement testGet_search_form().
-     */
-    public function testGet_search_form()
-    {
-        // Remove the following lines when you implement this test.
-        $this->markTestIncomplete(
-          'This test has not been implemented yet.'
-        );
-    }
-
-    /**
-     * @covers UserManager::show_menu
-     * @todo   Implement testShow_menu().
-     */
-    public function testShow_menu()
-    {
-        // Remove the following lines when you implement this test.
-        $this->markTestIncomplete(
-          'This test has not been implemented yet.'
-        );
-    }
-
-    /**
-     * @covers UserManager::get_special_course_list
-     * @todo   Implement testGet_special_course_list().
-     */
-    public function testGet_special_course_list()
-    {
-        // Remove the following lines when you implement this test.
-        $this->markTestIncomplete(
-          'This test has not been implemented yet.'
-        );
-    }
-
-    /**
-     * @covers UserManager::relate_users
-     * @todo   Implement testRelate_users().
-     */
-    public function testRelate_users()
-    {
-        // Remove the following lines when you implement this test.
-        $this->markTestIncomplete(
-          'This test has not been implemented yet.'
-        );
-    }
-
-    /**
-     * @covers UserManager::remove_user_rel_user
-     * @todo   Implement testRemove_user_rel_user().
-     */
-    public function testRemove_user_rel_user()
-    {
-        // Remove the following lines when you implement this test.
-        $this->markTestIncomplete(
-          'This test has not been implemented yet.'
-        );
-    }
-
-    /**
-     * @covers UserManager::get_users_followed_by_drh
-     * @todo   Implement testGet_users_followed_by_drh().
-     */
-    public function testGet_users_followed_by_drh()
-    {
-        // Remove the following lines when you implement this test.
-        $this->markTestIncomplete(
-          'This test has not been implemented yet.'
-        );
-    }
-
-    /**
-     * @covers UserManager::suscribe_users_to_hr_manager
-     * @todo   Implement testSuscribe_users_to_hr_manager().
-     */
-    public function testSuscribe_users_to_hr_manager()
-    {
-        // Remove the following lines when you implement this test.
-        $this->markTestIncomplete(
-          'This test has not been implemented yet.'
-        );
-    }
-
-    /**
-     * @covers UserManager::is_user_followed_by_drh
-     * @todo   Implement testIs_user_followed_by_drh().
-     */
-    public function testIs_user_followed_by_drh()
-    {
-        // Remove the following lines when you implement this test.
-        $this->markTestIncomplete(
-          'This test has not been implemented yet.'
-        );
-    }
-
-    /**
-     * @covers UserManager::get_user_id_of_course_admin_or_session_admin
-     * @todo   Implement testGet_user_id_of_course_admin_or_session_admin().
-     */
-/*
-    public function testGet_user_id_of_course_admin_or_session_admin()
-    {
-        // Remove the following lines when you implement this test.
-        $this->markTestIncomplete(
-          'This test has not been implemented yet.'
-        );
-    }
-*/
-    /**
-     * @covers UserManager::is_user_certified
-     * @todo   Implement testIs_user_certified().
-     */
-    public function testIs_user_certified()
-    {
-        // Remove the following lines when you implement this test.
-        $this->markTestIncomplete(
-          'This test has not been implemented yet.'
-        );
-    }
-
-    /**
-     * @covers UserManager::get_info_gradebook_certificate
-     * @todo   Implement testGet_info_gradebook_certificate().
-     */
-    public function testGet_info_gradebook_certificate()
-    {
-        // Remove the following lines when you implement this test.
-        $this->markTestIncomplete(
-          'This test has not been implemented yet.'
-        );
-    }
-
-    /**
-     * @covers UserManager::get_user_path_certificate
-     * @todo   Implement testGet_user_path_certificate().
-     */
-    public function testGet_user_path_certificate()
-    {
-        // Remove the following lines when you implement this test.
-        $this->markTestIncomplete(
-          'This test has not been implemented yet.'
-        );
-    }
-
-    /**
-     * @covers UserManager::is_session_course_coach
-     * @todo   Implement testIs_session_course_coach().
-     */
-    public function testIs_session_course_coach()
-    {
-        // Remove the following lines when you implement this test.
-        $this->markTestIncomplete(
-          'This test has not been implemented yet.'
-        );
-    }
-
-    /**
-     * @covers UserManager::get_favicon_from_url
-     * @todo   Implement testGet_favicon_from_url().
-     */
-    public function testGet_favicon_from_url()
-    {
-        // Remove the following lines when you implement this test.
-        $this->markTestIncomplete(
-          'This test has not been implemented yet.'
-        );
-    }
-
-    /**
-     * @covers UserManager::delete_inactive_student
-     * @todo   Implement testDelete_inactive_student().
-     */
-    public function testDelete_inactive_student()
-    {
-        // Remove the following lines when you implement this test.
-        $this->markTestIncomplete(
-          'This test has not been implemented yet.'
-        );
-    }
-
-    /**
-     * @covers UserManager::set_extra_fields_in_form
-     * @todo   Implement testSet_extra_fields_in_form().
-     */
-    public function testSet_extra_fields_in_form()
-    {
-        // Remove the following lines when you implement this test.
-        $this->markTestIncomplete(
-          'This test has not been implemented yet.'
-        );
-    }
-
-    /**
-     * @covers UserManager::get_user_field_types
-     * @todo   Implement testGet_user_field_types().
-     */
-    public function testGet_user_field_types()
-    {
-        // Remove the following lines when you implement this test.
-        $this->markTestIncomplete(
-          'This test has not been implemented yet.'
-        );
-    }
-
-    /**
-     * @covers UserManager::add_user_as_admin
-     * @todo   Implement testAdd_user_as_admin().
-     */
-    public function testAdd_user_as_admin()
-    {
-        // Remove the following lines when you implement this test.
-        $this->markTestIncomplete(
-          'This test has not been implemented yet.'
-        );
-    }
-
-    /**
-     * @covers UserManager::remove_user_admin
-     * @todo   Implement testRemove_user_admin().
-     */
-    public function testRemove_user_admin()
-    {
-        // Remove the following lines when you implement this test.
-        $this->markTestIncomplete(
-          'This test has not been implemented yet.'
-        );
-    }
-
-    /**
-     * @covers UserManager::update_all_user_languages
-     * @todo   Implement testUpdate_all_user_languages().
-     */
-    public function testUpdate_all_user_languages()
-    {
-        // Remove the following lines when you implement this test.
-        $this->markTestIncomplete(
-          'This test has not been implemented yet.'
-        );
-    }
-}