Browse Source

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

Yannick Warnier 8 years ago
parent
commit
fe0255227d
65 changed files with 5328 additions and 176 deletions
  1. 612 0
      app/Migrations/Schema/V110/Version110.php
  2. 181 0
      app/Migrations/Schema/V110/Version20150423093100.php
  3. 77 0
      app/Migrations/Schema/V110/Version20150504182600.php
  4. 64 0
      app/Migrations/Schema/V110/Version20150505132304.php
  5. 77 0
      app/Migrations/Schema/V110/Version20150505142900.php
  6. 242 0
      app/Migrations/Schema/V110/Version20150507152600.php
  7. 43 0
      app/Migrations/Schema/V110/Version20150511133949.php
  8. 29 0
      app/Migrations/Schema/V110/Version20150519153200.php
  9. 31 0
      app/Migrations/Schema/V110/Version20150521113600.php
  10. 49 0
      app/Migrations/Schema/V110/Version20150522112023.php
  11. 821 0
      app/Migrations/Schema/V110/Version20150522222222.php
  12. 55 0
      app/Migrations/Schema/V110/Version20150527101600.php
  13. 33 0
      app/Migrations/Schema/V110/Version20150527114220.php
  14. 31 0
      app/Migrations/Schema/V110/Version20150527120703.php
  15. 76 0
      app/Migrations/Schema/V110/Version20150528103216.php
  16. 67 0
      app/Migrations/Schema/V110/Version20150529164400.php
  17. 70 0
      app/Migrations/Schema/V110/Version20150603142550.php
  18. 32 0
      app/Migrations/Schema/V110/Version20150603151200.php
  19. 101 0
      app/Migrations/Schema/V110/Version20150603181728.php
  20. 29 0
      app/Migrations/Schema/V110/Version20150604145047.php
  21. 70 0
      app/Migrations/Schema/V110/Version20150608104600.php
  22. 35 0
      app/Migrations/Schema/V110/Version20150609113500.php
  23. 29 0
      app/Migrations/Schema/V110/Version20150610143426.php
  24. 34 0
      app/Migrations/Schema/V110/Version20150615171900.php
  25. 35 0
      app/Migrations/Schema/V110/Version20150616093200.php
  26. 35 0
      app/Migrations/Schema/V110/Version20150624164100.php
  27. 35 0
      app/Migrations/Schema/V110/Version20150625155000.php
  28. 36 0
      app/Migrations/Schema/V110/Version20150706135000.php
  29. 29 0
      app/Migrations/Schema/V110/Version20150709083710.php
  30. 35 0
      app/Migrations/Schema/V110/Version20150713132630.php
  31. 111 0
      app/Migrations/Schema/V110/Version20150803163400.php
  32. 37 0
      app/Migrations/Schema/V110/Version20150803171220.php
  33. 40 0
      app/Migrations/Schema/V110/Version20150805161000.php
  34. 29 0
      app/Migrations/Schema/V110/Version20150810132615.php
  35. 75 0
      app/Migrations/Schema/V110/Version20150812230500.php
  36. 166 0
      app/Migrations/Schema/V110/Version20150813143000.php
  37. 71 0
      app/Migrations/Schema/V110/Version20150813200000.php
  38. 45 0
      app/Migrations/Schema/V110/Version20150819095300.php
  39. 178 0
      app/Migrations/Schema/V110/Version20150821150000.php
  40. 67 0
      app/Migrations/Schema/V110/Version20150825141100.php
  41. 41 0
      app/Migrations/Schema/V110/Version20151101082200.php
  42. 312 0
      app/Migrations/Schema/V110/Version20151101082300.php
  43. 34 0
      app/Migrations/Schema/V110/Version20151119082400.php
  44. 32 0
      app/Migrations/Schema/V110/Version20151214164000.php
  45. 129 0
      app/Migrations/Schema/V110/Version20151214170800.php
  46. 52 0
      app/Migrations/Schema/V110/Version20151221150100.php
  47. 29 0
      app/Migrations/Schema/V110/Version20160707131900.php
  48. 7 2
      app/Migrations/Schema/V111/Version111.php
  49. 25 6
      app/Migrations/Schema/V111/Version20160330103045.php
  50. 2 2
      app/Migrations/Schema/V111/Version20160405112100.php
  51. 48 37
      app/Resources/public/css/base.css
  52. 1 1
      app/console
  53. 6 6
      main/admin/email_tester.php
  54. 1 1
      main/auth/profile.php
  55. 3 1
      main/inc/ajax/social.ajax.php
  56. 0 36
      main/inc/lib/api.lib.php
  57. 1 1
      main/inc/lib/document.lib.php
  58. 17 10
      main/inc/lib/fileUpload.lib.php
  59. 21 21
      main/inc/lib/usermanager.lib.php
  60. 10 13
      main/install/index.php
  61. 606 0
      main/install/install.lib.php
  62. 18 13
      main/social/invitations.php
  63. 12 23
      main/social/profile.php
  64. 7 3
      main/template/default/admin/email_tester.tpl
  65. 2 0
      src/Chamilo/CourseBundle/Component/CourseCopy/CourseRestorer.php

+ 612 - 0
app/Migrations/Schema/V110/Version110.php

@@ -0,0 +1,612 @@
+<?php
+/* For licensing terms, see /license.txt */
+
+namespace Application\Migrations\Schema\V110;
+
+use Application\Migrations\AbstractMigrationChamilo;
+use Doctrine\DBAL\Schema\Schema;
+use \Doctrine\DBAL\Types\Type;
+
+/**
+ * Class Version110
+ *
+ * Migrate file to updated to Chamilo 1.10
+ *
+ * @package Application\Migrations\Schema\V110
+ */
+class Version110 extends AbstractMigrationChamilo
+{
+    /**
+     * @param Schema $schema
+     */
+    public function preUp(Schema $schema)
+    {
+        $this->addSql("ALTER TABLE session_rel_course ENGINE=InnoDB");
+        $this->addSql("ALTER TABLE session_rel_course_rel_user ENGINE=InnoDB");
+        $this->addSql("ALTER TABLE session_rel_user ENGINE=InnoDB");
+        $this->addSql("UPDATE session SET session.id_coach = 1 WHERE id_coach NOT IN ( SELECT user_id FROM user)");
+    }
+
+    /**
+     * @param Schema $schema
+     *
+     * @throws \Doctrine\DBAL\Schema\SchemaException
+     */
+    public function up(Schema $schema)
+    {
+        // Use $schema->createTable
+        $this->addSql('set sql_mode=""');
+
+        $this->addSql("CREATE TABLE IF NOT EXISTS course_field_options (id INT NOT NULL PRIMARY KEY AUTO_INCREMENT, field_id INT NOT NULL, option_value TEXT, option_display_text VARCHAR(64), option_order INT, tms DATETIME)");
+        $this->addSql("CREATE TABLE IF NOT EXISTS session_field_options (id INT NOT NULL PRIMARY KEY AUTO_INCREMENT, field_id INT NOT NULL, option_value TEXT, option_display_text VARCHAR(64), option_order INT, tms DATETIME)");
+        $this->addSql("CREATE TABLE IF NOT EXISTS hook_observer( id int UNSIGNED NOT NULL AUTO_INCREMENT, class_name varchar(255) UNIQUE, path varchar(255) NOT NULL, plugin_name varchar(255) NULL, PRIMARY KEY PK_hook_management_hook_observer(id))");
+        $this->addSql("CREATE TABLE IF NOT EXISTS hook_event( id int UNSIGNED NOT NULL AUTO_INCREMENT, class_name varchar(255) UNIQUE, description varchar(255), PRIMARY KEY PK_hook_management_hook_event(id))");
+        $this->addSql("CREATE TABLE IF NOT EXISTS hook_call( id int UNSIGNED NOT NULL AUTO_INCREMENT, hook_event_id int UNSIGNED NOT NULL, hook_observer_id int UNSIGNED NOT NULL, type tinyint NOT NULL, hook_order int UNSIGNED NOT NULL, enabled tinyint NOT NULL, PRIMARY KEY PK_hook_management_hook_call(id))");
+        $this->addSql("CREATE TABLE IF NOT EXISTS c_student_publication_rel_document (iid INT NOT NULL PRIMARY KEY, id INT NULL, work_id INT NOT NULL, document_id INT NOT NULL, c_id INT NOT NULL)");
+        $this->addSql("CREATE TABLE IF NOT EXISTS c_student_publication_rel_user (iid INT NOT NULL AUTO_INCREMENT PRIMARY KEY, id INT NULL, work_id INT NOT NULL, user_id INT NOT NULL, c_id INT NOT NULL)");
+        $this->addSql("CREATE TABLE IF NOT EXISTS c_student_publication_comment (iid INT NOT NULL PRIMARY KEY, id INT NULL, work_id INT NOT NULL, c_id INT NOT NULL, comment text, file VARCHAR(255), user_id int NOT NULL, sent_at datetime NOT NULL)");
+        $this->addSql("CREATE TABLE IF NOT EXISTS c_attendance_calendar_rel_group (iid int NOT NULL auto_increment PRIMARY KEY, id INT, c_id INT NOT NULL, group_id INT NOT NULL, calendar_id INT NOT NULL)");
+
+        $this->addSql("ALTER TABLE session MODIFY COLUMN date_start date default NULL, MODIFY COLUMN date_end date default NULL");
+        $this->addSql("ALTER TABLE skill_rel_user MODIFY COLUMN acquired_skill_at datetime default NULL");
+        $this->addSql("ALTER TABLE track_e_access MODIFY COLUMN access_date datetime DEFAULT NULL");
+        $this->addSql("ALTER TABLE track_e_lastaccess MODIFY COLUMN access_date datetime DEFAULT NULL");
+
+        $table = $schema->getTable('skill_rel_user');
+
+        if (!$table->hasColumn('course_id')) {
+            $this->addSql("ALTER TABLE skill_rel_user ADD COLUMN course_id INT NOT NULL DEFAULT 0 AFTER id");
+        }
+
+        if (!$table->hasColumn('session_id')) {
+            $this->addSql("ALTER TABLE skill_rel_user ADD COLUMN session_id INT NOT NULL DEFAULT 0 AFTER course_id");
+        }
+
+        $this->addSql("ALTER TABLE skill_rel_user ADD INDEX idx_select_cs (course_id, session_id)");
+
+        // Delete info of session_rel_user if session does not exists;
+        $this->addSql("DELETE FROM session_rel_user WHERE id_session NOT IN (SELECT id FROM session)");
+
+        // Delete info of usergroup_rel_user if usergroup does not exists;
+        $this->addSql("DELETE FROM usergroup_rel_user WHERE usergroup_id NOT IN (SELECT id FROM usergroup)");
+
+        $session = $schema->getTable('session');
+        $session->getColumn('id')->setType(Type::getType(Type::INTEGER))->setUnsigned(false);
+        if (!$session->hasColumn('description')) {
+            $session->addColumn(
+                'description',
+                'text'
+            );
+        }
+
+        if (!$session->hasColumn('show_description')) {
+            $session->addColumn(
+                'show_description',
+                'smallint',
+                array('default' => 0, 'unsigned' => true)
+            );
+        }
+
+        $sessionTable = $schema->getTable('session');
+        if (!$sessionTable->hasColumn('duration')) {
+            $this->addSql("ALTER TABLE session ADD COLUMN duration int");
+        }
+
+        $sessionRelUser = $schema->getTable('session_rel_user');
+        if (!$sessionRelUser->hasColumn('duration')) {
+            $this->addSql("ALTER TABLE session_rel_user ADD COLUMN duration int");
+        }
+
+        $this->addSql("ALTER TABLE skill ADD COLUMN criteria text");
+        $this->addSql("ALTER TABLE gradebook_category ADD COLUMN generate_certificates TINYINT NOT NULL DEFAULT 0");
+        $this->addSql("ALTER TABLE track_e_access ADD COLUMN c_id int NOT NULL");
+
+        $this->addSql("ALTER TABLE track_e_lastaccess ADD COLUMN c_id int NOT NULL");
+        $this->addSql("ALTER TABLE track_e_exercices ADD COLUMN c_id int NOT NULL");
+        $this->addSql("ALTER TABLE track_e_downloads ADD COLUMN c_id int NOT NULL");
+        $this->addSql("ALTER TABLE track_e_hotpotatoes ADD COLUMN c_id int NOT NULL");
+        $this->addSql("ALTER TABLE track_e_links ADD COLUMN c_id int NOT NULL");
+        $this->addSql("ALTER TABLE track_e_course_access ADD COLUMN c_id int NOT NULL");
+        $this->addSql("ALTER TABLE track_e_online ADD COLUMN c_id int NOT NULL");
+        $this->addSql("ALTER TABLE track_e_attempt ADD COLUMN c_id int NOT NULL");
+        $table = $schema->getTable('track_e_default');
+        if (!$table->hasColumn('session_id')) {
+            $this->addSql("ALTER TABLE track_e_default ADD COLUMN session_id int NOT NULL");
+        }
+
+        if (!$table->hasColumn('c_id')) {
+            $this->addSql("ALTER TABLE track_e_default ADD COLUMN c_id int NOT NULL");
+        }
+
+        $this->addSql("ALTER TABLE track_e_access ADD COLUMN user_ip varchar(39) NOT NULL default ''");
+        $this->addSql("ALTER TABLE track_e_exercices ADD COLUMN user_ip varchar(39) NOT NULL default ''");
+        $this->addSql("ALTER TABLE track_e_course_access ADD COLUMN user_ip varchar(39) NOT NULL default ''");
+        $this->addSql("ALTER TABLE track_e_online CHANGE COLUMN login_ip user_ip varchar(39) NOT NULL DEFAULT ''");
+        $this->addSql("ALTER TABLE track_e_login CHANGE COLUMN login_ip user_ip varchar(39) NOT NULL DEFAULT ''");
+
+		$this->addSql("ALTER TABLE user MODIFY COLUMN user_id int unsigned NOT NULL");
+        $this->addSql("ALTER TABLE user DROP PRIMARY KEY");
+        $this->addSql("ALTER TABLE user MODIFY COLUMN user_id int unsigned DEFAULT NULL");
+        $this->addSql("ALTER TABLE user ADD COLUMN id INT DEFAULT NULL");
+        $this->addSql("UPDATE user SET id = user_id");
+        $this->addSql("ALTER TABLE user MODIFY COLUMN id INT NOT NULL PRIMARY KEY AUTO_INCREMENT AFTER user_id");
+
+        $this->addSql("ALTER TABLE user MODIFY COLUMN chatcall_date datetime default NULL");
+        $this->addSql("ALTER TABLE user MODIFY COLUMN chatcall_text varchar(50) default NULL");
+        $this->addSql("ALTER TABLE user MODIFY COLUMN chatcall_user_id int unsigned default 0");
+        $this->addSql("ALTER TABLE user MODIFY COLUMN expiration_date datetime default NULL");
+        $this->addSql("ALTER TABLE user MODIFY COLUMN registration_date datetime NOT NULL");
+
+        $this->addSql("ALTER TABLE course ADD COLUMN add_teachers_to_sessions_courses tinyint NOT NULL default 0");
+        $this->addSql("ALTER TABLE course DROP COLUMN target_course_code");
+        $this->addSql("ALTER TABLE session MODIFY COLUMN name char(100) NOT NULL DEFAULT ''");
+        $this->addSql("ALTER TABLE course_rel_user ADD COLUMN c_id int default NULL");
+        $this->addSql("ALTER TABLE course_field_values ADD COLUMN c_id int default NULL");
+
+        $this->addSql("ALTER TABLE session_rel_course_rel_user ADD COLUMN c_id int default NULL");
+        $this->addSql("ALTER TABLE session_rel_course_rel_user CHANGE id_session session_id int");
+        $this->addSql("ALTER TABLE session_rel_course_rel_user CHANGE id_user user_id int");
+
+        $this->addSql("ALTER TABLE access_url_rel_course ADD COLUMN c_id int");
+
+        $this->addSql("ALTER TABLE session_rel_course ADD COLUMN position int NOT NULL default 0");
+        $this->addSql("ALTER TABLE session_rel_course ADD COLUMN category varchar(255) default ''");
+        $this->addSql("ALTER TABLE session_rel_course ADD COLUMN c_id int unsigned");
+        $this->addSql("ALTER TABLE session_rel_course CHANGE id_session session_id int");
+        $this->addSql('DELETE FROM session_rel_course WHERE session_id NOT IN (SELECT id FROM session)');
+
+        $this->addSql("DELETE FROM course_rel_user WHERE course_code NOT IN (SELECT code FROM course)");
+        $this->addSql("UPDATE course_rel_user SET c_id = (SELECT id FROM course WHERE code = course_code)");
+
+        // Add iid
+        $tables = [
+            'c_announcement',
+            'c_announcement_attachment',
+            'c_attendance',
+            'c_attendance_calendar',
+            //'c_attendance_calendar_rel_group',
+            'c_attendance_result',
+            //'c_attendance_sheet',
+            'c_attendance_sheet_log',
+            //'c_blog',
+            'c_blog_attachment',
+            //'c_blog_comment',
+            //'c_blog_post',
+            //'c_blog_rating',
+            //'c_blog_rel_user',
+            //'c_blog_task',
+            //'c_blog_task_rel_user',
+            'c_calendar_event',
+            'c_calendar_event_attachment',
+            //'c_calendar_event_repeat',
+            //'c_calendar_event_repeat_not',
+            'c_chat_connected',
+            'c_course_description',
+            'c_course_setting',
+            'c_document',
+            //'c_dropbox_category',
+            //'c_dropbox_feedback',
+            'c_dropbox_file',
+            //'c_dropbox_person',
+            //'c_dropbox_post',
+            'c_forum_attachment',
+            //'c_forum_category',
+            //'c_forum_forum',
+            'c_forum_mailcue',
+            'c_forum_notification',
+            //'c_forum_post',
+            //'c_forum_thread',
+            'c_forum_thread_qualify',
+            'c_forum_thread_qualify_log',
+            //'c_glossary',
+            'c_group_category',
+            'c_group_info',
+            'c_group_rel_tutor',
+            'c_group_rel_user',
+            'c_item_property',
+            'c_link',
+            'c_link_category',
+            'c_lp',
+            'c_lp_item',
+            'c_lp_item_view',
+            'c_lp_iv_interaction',
+            'c_lp_iv_objective',
+            'c_lp_view',
+            //'c_notebook',
+            //'c_online_connected',
+            'c_online_link',
+            'c_permission_group',
+            'c_permission_task',
+            'c_permission_user',
+            'c_quiz',
+            //'c_quiz_answer',
+            'c_quiz_question',
+            'c_quiz_question_category',
+            'c_quiz_question_option',
+            //'c_quiz_question_rel_category',
+            //'c_quiz_rel_question',
+            'c_resource',
+            //'c_role',
+            'c_role_group',
+            'c_role_permissions',
+            //'c_role_user',
+            'c_student_publication',
+            'c_student_publication_assignment',
+            //'c_student_publication_comment',
+            //'c_student_publication_rel_document',
+            //'c_student_publication_rel_user',
+            //'c_survey',
+            //'c_survey_answer',
+            'c_survey_group',
+            //'c_survey_invitation',
+            //'c_survey_question',
+            //'c_survey_question_option',
+            'c_thematic',
+            'c_thematic_advance',
+            'c_thematic_plan',
+            'c_tool',
+            //'c_tool_intro',
+            'c_userinfo_content',
+            'c_userinfo_def',
+            'c_wiki',
+            //'c_wiki_conf',
+            'c_wiki_discuss',
+            'c_wiki_mailcue'
+        ];
+
+        foreach ($tables as $table) {
+            if ($schema->hasTable($table)) {
+                $this->addSql("ALTER TABLE $table MODIFY COLUMN id INT NOT NULL");
+                $this->addSql("ALTER TABLE $table MODIFY COLUMN c_id INT NOT NULL");
+                $this->addSql("ALTER TABLE $table DROP PRIMARY KEY");
+                $this->addSql("ALTER TABLE $table MODIFY COLUMN id INT NULL");
+                $this->addSql("ALTER TABLE $table ADD COLUMN iid int NOT NULL PRIMARY KEY AUTO_INCREMENT");
+            }
+        }
+
+        if ($schema->hasTable('c_attendance_calendar_rel_group')) {
+            $this->addSql("ALTER TABLE c_attendance_calendar_rel_group MODIFY COLUMN id INT NOT NULL");
+            $this->addSql("ALTER TABLE c_attendance_calendar_rel_group DROP PRIMARY KEY");
+            $this->addSql("ALTER TABLE c_attendance_calendar_rel_group MODIFY COLUMN id INT NULL DEFAULT NULL");
+            $this->addSql("ALTER TABLE c_attendance_calendar_rel_group ADD COLUMN iid int NOT NULL PRIMARY KEY AUTO_INCREMENT");
+        }
+
+        $this->addSql("ALTER TABLE c_attendance_sheet MODIFY COLUMN c_id INT NOT NULL");
+        $this->addSql("ALTER TABLE c_attendance_sheet DROP PRIMARY KEY");
+        $this->addSql("ALTER TABLE c_attendance_sheet ADD COLUMN iid int NOT NULL PRIMARY KEY AUTO_INCREMENT");
+
+        $this->addSql("ALTER TABLE c_blog MODIFY COLUMN blog_id int unsigned NOT NULL");
+        $this->addSql("ALTER TABLE c_blog MODIFY COLUMN c_id INT NOT NULL");
+        $this->addSql("ALTER TABLE c_blog DROP PRIMARY KEY");
+        $this->addSql("ALTER TABLE c_blog MODIFY COLUMN blog_id int unsigned DEFAULT NULL");
+        $this->addSql("ALTER TABLE c_blog ADD COLUMN iid int  NOT NULL PRIMARY KEY AUTO_INCREMENT");
+
+        $this->addSql("ALTER TABLE c_blog_comment MODIFY COLUMN comment_id int NOT NULL");
+        $this->addSql("ALTER TABLE c_blog_comment MODIFY COLUMN c_id INT NOT NULL");
+        $this->addSql("ALTER TABLE c_blog_comment DROP PRIMARY KEY");
+        $this->addSql("ALTER TABLE c_blog_comment MODIFY COLUMN comment_id int DEFAULT NULL");
+        $this->addSql("ALTER TABLE c_blog_comment ADD COLUMN iid int NOT NULL PRIMARY KEY AUTO_INCREMENT");
+
+        $this->addSql("ALTER TABLE c_blog_post MODIFY COLUMN post_id int unsigned NOT NULL");
+        $this->addSql("ALTER TABLE c_blog_post MODIFY COLUMN c_id INT NOT NULL");
+        $this->addSql("ALTER TABLE c_blog_post DROP PRIMARY KEY");
+        $this->addSql("ALTER TABLE c_blog_post MODIFY COLUMN post_id int unsigned DEFAULT NULL");
+        $this->addSql("ALTER TABLE c_blog_post ADD COLUMN iid int NOT NULL PRIMARY KEY AUTO_INCREMENT");
+
+        $this->addSql("ALTER TABLE c_blog_rating MODIFY COLUMN rating_id int unsigned NOT NULL");
+        $this->addSql("ALTER TABLE c_blog_rating MODIFY COLUMN c_id INT NOT NULL");
+        $this->addSql("ALTER TABLE c_blog_rating DROP PRIMARY KEY");
+        $this->addSql("ALTER TABLE c_blog_rating MODIFY COLUMN rating_id int unsigned DEFAULT NULL");
+        $this->addSql("ALTER TABLE c_blog_rating ADD COLUMN iid int NOT NULL PRIMARY KEY AUTO_INCREMENT");
+
+        $this->addSql("ALTER TABLE c_blog_rel_user DROP PRIMARY KEY");
+        $this->addSql("ALTER TABLE c_blog_rel_user MODIFY COLUMN c_id INT NOT NULL");
+        $this->addSql("ALTER TABLE c_blog_rel_user MODIFY COLUMN blog_id int unsigned DEFAULT NULL");
+        $this->addSql("ALTER TABLE c_blog_rel_user MODIFY COLUMN user_id int unsigned DEFAULT NULL");
+        $this->addSql("ALTER TABLE c_blog_rel_user ADD COLUMN iid int NOT NULL PRIMARY KEY AUTO_INCREMENT");
+
+        $this->addSql("ALTER TABLE c_blog_task MODIFY COLUMN task_id int unsigned NOT NULL");
+        $this->addSql("ALTER TABLE c_blog_task MODIFY COLUMN c_id INT NOT NULL");
+        $this->addSql("ALTER TABLE c_blog_task DROP PRIMARY KEY");
+        $this->addSql("ALTER TABLE c_blog_task MODIFY COLUMN task_id int unsigned DEFAULT NULL");
+        $this->addSql("ALTER TABLE c_blog_task ADD COLUMN iid int NOT NULL PRIMARY KEY AUTO_INCREMENT");
+
+        $this->addSql("ALTER TABLE c_blog_task_rel_user DROP PRIMARY KEY");
+        $this->addSql("ALTER TABLE c_blog_task_rel_user MODIFY COLUMN blog_id int unsigned DEFAULT NULL");
+        $this->addSql("ALTER TABLE c_blog_task_rel_user MODIFY COLUMN user_id int unsigned DEFAULT NULL");
+        $this->addSql("ALTER TABLE c_blog_task_rel_user MODIFY COLUMN task_id int unsigned DEFAULT NULL");
+        $this->addSql("ALTER TABLE c_blog_task_rel_user ADD COLUMN iid int NOT NULL PRIMARY KEY AUTO_INCREMENT");
+
+        $this->addSql("ALTER TABLE c_calendar_event_repeat DROP PRIMARY KEY");
+        $this->addSql("ALTER TABLE c_calendar_event_repeat MODIFY COLUMN cal_id int unsigned DEFAULT NULL");
+        $this->addSql("ALTER TABLE c_calendar_event_repeat MODIFY COLUMN c_id INT NOT NULL");
+        $this->addSql("ALTER TABLE c_calendar_event_repeat ADD COLUMN iid int NOT NULL PRIMARY KEY AUTO_INCREMENT");
+
+        $this->addSql("ALTER TABLE c_calendar_event_repeat_not DROP PRIMARY KEY");
+        $this->addSql("ALTER TABLE c_calendar_event_repeat_not MODIFY COLUMN cal_id int unsigned DEFAULT NULL");
+        $this->addSql("ALTER TABLE c_calendar_event_repeat_not MODIFY COLUMN c_id INT NOT NULL");
+        $this->addSql("ALTER TABLE c_calendar_event_repeat_not ADD COLUMN iid int NOT NULL PRIMARY KEY AUTO_INCREMENT");
+
+        $this->addSql("ALTER TABLE c_dropbox_category MODIFY COLUMN cat_id int unsigned NOT NULL");
+        $this->addSql("ALTER TABLE c_dropbox_category DROP PRIMARY KEY");
+        $this->addSql("ALTER TABLE c_dropbox_category MODIFY COLUMN cat_id int unsigned DEFAULT NULL");
+        $this->addSql("ALTER TABLE c_dropbox_category MODIFY COLUMN c_id INT NOT NULL");
+        $this->addSql("ALTER TABLE c_dropbox_category ADD COLUMN iid int NOT NULL PRIMARY KEY AUTO_INCREMENT");
+
+        $this->addSql("ALTER TABLE c_dropbox_feedback MODIFY COLUMN feedback_id int unsigned NOT NULL");
+        $this->addSql("ALTER TABLE c_dropbox_feedback DROP PRIMARY KEY");
+        $this->addSql("ALTER TABLE c_dropbox_feedback MODIFY COLUMN feedback_id int unsigned DEFAULT NULL");
+        $this->addSql("ALTER TABLE c_dropbox_feedback MODIFY COLUMN c_id INT NOT NULL");
+        $this->addSql("ALTER TABLE c_dropbox_feedback ADD COLUMN iid int NOT NULL PRIMARY KEY AUTO_INCREMENT");
+
+        $this->addSql("ALTER TABLE c_dropbox_person DROP PRIMARY KEY");
+        $this->addSql("ALTER TABLE c_dropbox_person MODIFY COLUMN file_id int unsigned DEFAULT NULL");
+        $this->addSql("ALTER TABLE c_dropbox_person MODIFY COLUMN c_id INT NOT NULL");
+        $this->addSql("ALTER TABLE c_dropbox_person ADD COLUMN iid int NOT NULL PRIMARY KEY AUTO_INCREMENT");
+
+        $this->addSql("ALTER TABLE c_dropbox_post DROP PRIMARY KEY");
+        $this->addSql("ALTER TABLE c_dropbox_post MODIFY COLUMN file_id int unsigned DEFAULT NULL");
+        $this->addSql("ALTER TABLE c_dropbox_post MODIFY COLUMN c_id INT NOT NULL");
+        $this->addSql("ALTER TABLE c_dropbox_post ADD COLUMN iid int NOT NULL PRIMARY KEY AUTO_INCREMENT");
+
+        $this->addSql("ALTER TABLE c_forum_category MODIFY COLUMN cat_id int unsigned NOT NULL");
+        $this->addSql("ALTER TABLE c_forum_category DROP PRIMARY KEY");
+        $this->addSql("ALTER TABLE c_forum_category MODIFY COLUMN cat_id int unsigned DEFAULT NULL");
+        $this->addSql("ALTER TABLE c_forum_category MODIFY COLUMN c_id INT NOT NULL");
+        $this->addSql("ALTER TABLE c_forum_category ADD COLUMN iid int NOT NULL PRIMARY KEY AUTO_INCREMENT");
+
+        $this->addSql("ALTER TABLE c_forum_forum MODIFY COLUMN forum_id int unsigned NOT NULL");
+        $this->addSql("ALTER TABLE c_forum_forum DROP PRIMARY KEY");
+        $this->addSql("ALTER TABLE c_forum_forum MODIFY COLUMN forum_id int unsigned DEFAULT NULL");
+        $this->addSql("ALTER TABLE c_forum_forum MODIFY COLUMN c_id INT NOT NULL");
+        $this->addSql("ALTER TABLE c_forum_forum ADD COLUMN iid int NOT NULL PRIMARY KEY AUTO_INCREMENT");
+
+        $this->addSql("ALTER TABLE c_forum_post MODIFY COLUMN post_id int unsigned NOT NULL");
+        $this->addSql("ALTER TABLE c_forum_post DROP PRIMARY KEY");
+        $this->addSql("ALTER TABLE c_forum_post MODIFY COLUMN post_id int unsigned DEFAULT NULL");
+        $this->addSql("ALTER TABLE c_forum_post MODIFY COLUMN c_id INT NOT NULL");
+        $this->addSql("ALTER TABLE c_forum_post ADD COLUMN iid int NOT NULL PRIMARY KEY AUTO_INCREMENT");
+
+        $this->addSql("ALTER TABLE c_forum_thread MODIFY COLUMN thread_id int unsigned NOT NULL");
+        $this->addSql("ALTER TABLE c_forum_thread DROP PRIMARY KEY");
+        $this->addSql("ALTER TABLE c_forum_thread MODIFY COLUMN forum_id int unsigned DEFAULT NULL");
+        $this->addSql("ALTER TABLE c_forum_thread MODIFY COLUMN c_id INT NOT NULL");
+        $this->addSql("ALTER TABLE c_forum_thread MODIFY COLUMN thread_id int unsigned DEFAULT NULL");
+        $this->addSql("ALTER TABLE c_forum_thread ADD COLUMN iid int NOT NULL PRIMARY KEY AUTO_INCREMENT");
+
+        $this->addSql("ALTER TABLE c_forum_thread ADD COLUMN thread_peer_qualify tinyint default 0");
+
+        $this->addSql("ALTER TABLE c_glossary MODIFY COLUMN glossary_id int unsigned NOT NULL");
+        $this->addSql("ALTER TABLE c_glossary MODIFY COLUMN c_id INT NOT NULL");
+        $this->addSql("ALTER TABLE c_glossary DROP PRIMARY KEY");
+        $this->addSql("ALTER TABLE c_glossary MODIFY COLUMN glossary_id int unsigned DEFAULT NULL");
+        $this->addSql("ALTER TABLE c_glossary ADD COLUMN iid int NOT NULL PRIMARY KEY AUTO_INCREMENT");
+
+        $this->addSql("ALTER TABLE c_notebook MODIFY COLUMN notebook_id int unsigned NOT NULL");
+        $this->addSql("ALTER TABLE c_notebook MODIFY COLUMN c_id INT NOT NULL");
+        $this->addSql("ALTER TABLE c_notebook DROP PRIMARY KEY");
+        $this->addSql("ALTER TABLE c_notebook MODIFY COLUMN notebook_id int unsigned DEFAULT NULL");
+        $this->addSql("ALTER TABLE c_notebook ADD COLUMN iid int NOT NULL PRIMARY KEY AUTO_INCREMENT");
+
+        $this->addSql("ALTER TABLE c_online_connected MODIFY COLUMN c_id INT NOT NULL");
+        $this->addSql("ALTER TABLE c_online_connected DROP PRIMARY KEY");
+        $this->addSql("ALTER TABLE c_online_connected ADD COLUMN iid int NOT NULL PRIMARY KEY AUTO_INCREMENT");
+
+        // For some reason c_tool_intro.id is a varchar in 1.9.x
+        $this->addSql("ALTER TABLE c_tool_intro MODIFY COLUMN id VARCHAR(50) NOT NULL");
+        $this->addSql("ALTER TABLE c_tool_intro MODIFY COLUMN c_id INT NOT NULL");
+        $this->addSql("ALTER TABLE c_tool_intro MODIFY COLUMN session_id int unsigned NOT NULL");
+        $this->addSql("ALTER TABLE c_tool_intro DROP PRIMARY KEY");
+        $this->addSql("ALTER TABLE c_tool_intro MODIFY COLUMN session_id int unsigned DEFAULT NULL");
+        $this->addSql("ALTER TABLE c_tool_intro ADD COLUMN iid int NOT NULL PRIMARY KEY AUTO_INCREMENT");
+
+        $this->addSql("ALTER TABLE c_quiz_answer MODIFY COLUMN c_id INT NOT NULL");
+        $this->addSql("ALTER TABLE c_quiz_answer MODIFY COLUMN id_auto int unsigned NOT NULL");
+        $this->addSql("ALTER TABLE c_quiz_answer DROP PRIMARY KEY");
+        $this->addSql("ALTER TABLE c_quiz_answer MODIFY COLUMN id_auto int unsigned DEFAULT NULL");
+        $this->addSql("ALTER TABLE c_quiz_answer ADD COLUMN iid int NOT NULL PRIMARY KEY AUTO_INCREMENT");
+
+        $this->addSql("ALTER TABLE c_quiz_question_rel_category MODIFY COLUMN c_id INT NOT NULL");
+        $this->addSql("ALTER TABLE c_quiz_question_rel_category MODIFY COLUMN question_id int unsigned NOT NULL");
+        $this->addSql("ALTER TABLE c_quiz_question_rel_category DROP PRIMARY KEY");
+        $this->addSql("ALTER TABLE c_quiz_question_rel_category MODIFY COLUMN question_id int unsigned DEFAULT NULL");
+        $this->addSql("ALTER TABLE c_quiz_question_rel_category ADD COLUMN iid int NOT NULL PRIMARY KEY AUTO_INCREMENT");
+
+        $this->addSql("ALTER TABLE session_rel_user MODIFY COLUMN id_session int");
+        $this->addSql("ALTER TABLE session_rel_user MODIFY COLUMN id_user int");
+        $this->addSql("ALTER TABLE session_rel_user MODIFY COLUMN relation_type int unsigned DEFAULT 0");
+        $this->addSql("ALTER TABLE session_rel_user DROP PRIMARY KEY");
+
+        $this->addSql("ALTER TABLE session_rel_user CHANGE id_session session_id int");
+        $this->addSql("ALTER TABLE session_rel_user CHANGE id_user user_id int");
+        $this->addSql("DELETE FROM session_rel_user WHERE user_id NOT IN (SELECT user_id FROM user)");
+        $this->addSql("ALTER TABLE session_rel_user ADD COLUMN id int NOT NULL PRIMARY KEY AUTO_INCREMENT");
+
+        $this->addSql("ALTER TABLE c_item_property CHANGE id_session session_id int");
+        $this->addSql("ALTER TABLE course_rel_user CHANGE tutor_id is_tutor int");
+
+        $this->addSql("ALTER TABLE c_quiz_rel_question MODIFY COLUMN c_id INT NOT NULL");
+        $this->addSql("ALTER TABLE c_quiz_rel_question DROP PRIMARY KEY");
+        $this->addSql("ALTER TABLE c_quiz_rel_question MODIFY COLUMN question_id int unsigned DEFAULT NULL");
+        $this->addSql("ALTER TABLE c_quiz_rel_question MODIFY COLUMN exercice_id int unsigned DEFAULT NULL");
+        $this->addSql("ALTER TABLE c_quiz_rel_question ADD COLUMN iid int NOT NULL PRIMARY KEY AUTO_INCREMENT");
+
+        $this->addSql("ALTER TABLE c_role MODIFY COLUMN role_id int unsigned NOT NULL");
+        $this->addSql("ALTER TABLE c_role MODIFY COLUMN c_id INT NOT NULL");
+        $this->addSql("ALTER TABLE c_role DROP PRIMARY KEY");
+        $this->addSql("ALTER TABLE c_role MODIFY COLUMN role_id int unsigned DEFAULT NULL");
+        $this->addSql("ALTER TABLE c_role ADD COLUMN iid int NOT NULL PRIMARY KEY AUTO_INCREMENT");
+
+        $this->addSql("ALTER TABLE c_role_user DROP PRIMARY KEY");
+        $this->addSql("ALTER TABLE c_role_user MODIFY COLUMN role_id int unsigned DEFAULT NULL");
+        $this->addSql("ALTER TABLE c_role_user MODIFY COLUMN user_id int unsigned DEFAULT NULL");
+        $this->addSql("ALTER TABLE c_role_user MODIFY COLUMN c_id INT NOT NULL");
+        $this->addSql("ALTER TABLE c_role_user ADD COLUMN iid int NOT NULL PRIMARY KEY AUTO_INCREMENT");
+
+        $this->addSql("ALTER TABLE c_survey MODIFY COLUMN survey_id int NOT NULL");
+        $this->addSql("ALTER TABLE c_survey MODIFY COLUMN c_id INT NOT NULL");
+        $this->addSql("ALTER TABLE c_survey DROP PRIMARY KEY");
+        $this->addSql("ALTER TABLE c_survey MODIFY COLUMN survey_id int NULL");
+        $this->addSql("ALTER TABLE c_survey ADD COLUMN iid int NOT NULL PRIMARY KEY AUTO_INCREMENT");
+
+        $this->addSql("ALTER TABLE c_survey_answer MODIFY COLUMN answer_id int unsigned NOT NULL");
+        $this->addSql("ALTER TABLE c_survey_answer MODIFY COLUMN c_id INT NOT NULL");
+        $this->addSql("ALTER TABLE c_survey_answer DROP PRIMARY KEY");
+        $this->addSql("ALTER TABLE c_survey_answer MODIFY COLUMN answer_id int unsigned DEFAULT NULL");
+        $this->addSql("ALTER TABLE c_survey_answer ADD COLUMN iid int NOT NULL PRIMARY KEY AUTO_INCREMENT");
+
+        $this->addSql("ALTER TABLE c_survey_invitation MODIFY COLUMN survey_invitation_id int unsigned NOT NULL");
+        $this->addSql("ALTER TABLE c_survey_invitation MODIFY COLUMN c_id INT NOT NULL");
+        $this->addSql("ALTER TABLE c_survey_invitation DROP PRIMARY KEY");
+        $this->addSql("ALTER TABLE c_survey_invitation MODIFY COLUMN survey_invitation_id int unsigned DEFAULT NULL");
+        $this->addSql("ALTER TABLE c_survey_invitation ADD COLUMN iid int NOT NULL PRIMARY KEY AUTO_INCREMENT");
+
+        $this->addSql("ALTER TABLE c_survey_question MODIFY COLUMN question_id int unsigned NOT NULL");
+        $this->addSql("ALTER TABLE c_survey_question MODIFY COLUMN c_id INT NOT NULL");
+        $this->addSql("ALTER TABLE c_survey_question DROP PRIMARY KEY");
+        $this->addSql("ALTER TABLE c_survey_question MODIFY COLUMN question_id int unsigned DEFAULT NULL");
+        $this->addSql("ALTER TABLE c_survey_question ADD COLUMN iid int NOT NULL PRIMARY KEY AUTO_INCREMENT");
+
+        $this->addSql("ALTER TABLE c_survey_question_option MODIFY COLUMN question_option_id int unsigned NOT NULL");
+        $this->addSql("ALTER TABLE c_survey_question_option MODIFY COLUMN c_id INT NOT NULL");
+        $this->addSql("ALTER TABLE c_survey_question_option DROP PRIMARY KEY");
+        $this->addSql("ALTER TABLE c_survey_question_option MODIFY COLUMN question_option_id int unsigned DEFAULT NULL");
+        $this->addSql("ALTER TABLE c_survey_question_option ADD COLUMN iid int NOT NULL PRIMARY KEY AUTO_INCREMENT");
+
+        $this->addSql("ALTER TABLE c_wiki_conf DROP PRIMARY KEY");
+        $this->addSql("ALTER TABLE c_wiki_conf MODIFY COLUMN page_id int unsigned DEFAULT NULL");
+        $this->addSql("ALTER TABLE c_wiki_conf MODIFY COLUMN c_id INT NOT NULL");
+        $this->addSql("ALTER TABLE c_wiki_conf ADD COLUMN iid int NOT NULL PRIMARY KEY AUTO_INCREMENT");
+
+        // Course
+        $this->addSql("ALTER TABLE c_survey ADD COLUMN visible_results INT UNSIGNED DEFAULT 0");
+        $this->addSql("ALTER TABLE c_survey_invitation ADD COLUMN group_id INT NOT NULL");
+        $this->addSql("ALTER TABLE c_lp_item ADD COLUMN prerequisite_min_score float");
+        $this->addSql("ALTER TABLE c_lp_item ADD COLUMN prerequisite_max_score float");
+        $this->addSql("ALTER TABLE c_group_info ADD COLUMN status tinyint DEFAULT 1");
+        $this->addSql("ALTER TABLE c_student_publication ADD COLUMN document_id int DEFAULT 0");
+        $this->addSql("ALTER TABLE c_lp_item MODIFY COLUMN description VARCHAR(511) DEFAULT ''");
+        $this->addSql("ALTER TABLE course_category MODIFY COLUMN auth_course_child VARCHAR(40) DEFAULT 'TRUE' ");
+        $this->addSql("ALTER TABLE course_category MODIFY COLUMN auth_cat_child VARCHAR(40) DEFAULT 'TRUE'");
+        $this->addSql("ALTER TABLE c_quiz_answer MODIFY COLUMN hotspot_type varchar(40) default NULL");
+        $this->addSql("ALTER TABLE c_tool MODIFY COLUMN target varchar(20) NOT NULL default '_self' ");
+        $this->addSql("ALTER TABLE c_link MODIFY COLUMN on_homepage char(10) NOT NULL default '0' ");
+        $this->addSql("ALTER TABLE c_blog_rating MODIFY COLUMN rating_type char(40) NOT NULL default 'post' ");
+        $this->addSql("ALTER TABLE c_survey MODIFY COLUMN anonymous char(10) NOT NULL default '0'");
+        $this->addSql("ALTER TABLE c_course_setting MODIFY COLUMN value varchar(255) default ''");
+
+        $this->addSql("UPDATE course_field SET field_type = 13 WHERE field_variable = 'special_course'");
+        $this->addSql("UPDATE user SET registration_date = NULL WHERE registration_date = '0000-00-00 00:00:00'");
+        $this->addSql("UPDATE user SET expiration_date = NULL WHERE expiration_date = '0000-00-00 00:00:00'");
+        $this->addSql("UPDATE track_e_default SET default_date = NULL WHERE default_date = '0000-00-00 00:00:00'");
+        $this->addSql("UPDATE track_e_lastaccess SET access_date = NULL WHERE access_date = '0000-00-00 00:00:00'");
+        $this->addSql("UPDATE track_e_downloads SET down_date = NULL WHERE down_date = '0000-00-00 00:00:00'");
+        $this->addSql("UPDATE track_e_access SET access_date = NULL WHERE access_date = '0000-00-00 00:00:00'");
+        $this->addSql("UPDATE track_e_access SET c_id = (SELECT id FROM course WHERE code = access_cours_code)");
+        $this->addSql("UPDATE track_e_default SET c_id = (SELECT id FROM course WHERE code = default_cours_code)");
+        $this->addSql("UPDATE track_e_lastaccess SET c_id = (SELECT id FROM course WHERE code = access_cours_code)");
+        $this->addSql("UPDATE track_e_exercices SET c_id = (SELECT id FROM course WHERE code = exe_cours_id)");
+        $this->addSql("UPDATE track_e_downloads SET c_id = (SELECT id FROM course WHERE code = down_cours_id)");
+        $this->addSql("UPDATE track_e_hotpotatoes SET c_id = (SELECT id FROM course WHERE code = exe_cours_id)");
+        $this->addSql("UPDATE track_e_links SET c_id = (SELECT id FROM course WHERE code = links_cours_id)");
+        $this->addSql("UPDATE track_e_course_access SET c_id = (SELECT id FROM course WHERE code = course_code)");
+        $this->addSql("UPDATE track_e_online SET c_id = (SELECT id FROM course WHERE code = course)");
+        $this->addSql("UPDATE track_e_attempt SET c_id = (SELECT id FROM course WHERE code = course_code)");
+        $this->addSql("UPDATE course_field_values SET c_id = (SELECT id FROM course WHERE code = course_code)");
+        $this->addSql("UPDATE session_rel_course_rel_user SET c_id = (SELECT id FROM course WHERE code = course_code)");
+        $this->addSql('DELETE FROM session_rel_course WHERE course_code NOT IN (SELECT code FROM course)');
+        $this->addSql("UPDATE session_rel_course SET c_id = (SELECT id FROM course WHERE code = course_code)");
+
+        $this->addSql("DELETE FROM access_url_rel_course WHERE course_code NOT IN (SELECT code FROM course)");
+        $this->addSql("UPDATE access_url_rel_course SET c_id = (SELECT id FROM course WHERE code = course_code)");
+
+        $this->addSql("ALTER TABLE settings_current DROP INDEX unique_setting");
+        $this->addSql("ALTER TABLE settings_options DROP INDEX unique_setting_option");
+
+        $this->addSql("DELETE FROM settings_current WHERE variable = 'wcag_anysurfer_public_pages'");
+
+        $this->addSql("DELETE FROM settings_current WHERE variable = 'wcag_anysurfer_public_pages'");
+        $this->addSql("DELETE FROM settings_options WHERE variable = 'wcag_anysurfer_public_pages'");
+        $this->addSql("DELETE FROM settings_current WHERE variable = 'advanced_filemanager'");
+        $this->addSql("DELETE FROM settings_options WHERE variable = 'advanced_filemanager'");
+
+        $this->addSql("INSERT INTO settings_current (variable, subkey, type, category, selected_value, title, comment, scope, subkeytext, access_url_changeable) VALUES ('institution_address', NULL, 'textfield', 'Platform', '', 'InstitutionAddressTitle', 'InstitutionAddressComment', NULL, NULL, 1)");
+        $this->addSql("INSERT INTO settings_current (variable, subkey, type, category, selected_value, title, comment, scope, subkeytext, access_url_changeable) VALUES ('prevent_session_admins_to_manage_all_users', NULL, 'radio', 'Session', 'false', 'PreventSessionAdminsToManageAllUsersTitle', 'PreventSessionAdminsToManageAllUsersComment', NULL, NULL, 1)");
+        $this->addSql("INSERT INTO settings_options (variable, value, display_text) VALUES ('prevent_session_admins_to_manage_all_users', 'true', 'Yes'), ('prevent_session_admins_to_manage_all_users', 'false', 'No')");
+        $this->addSql("INSERT INTO settings_options (variable, value, display_text) VALUES ('show_glossary_in_extra_tools', 'none', 'None')");
+        $this->addSql("INSERT INTO settings_options (variable, value, display_text) VALUES ('show_glossary_in_extra_tools', 'exercise', 'Exercise')");
+        $this->addSql("INSERT INTO settings_options (variable, value, display_text) VALUES ('show_glossary_in_extra_tools', 'lp', 'Learning path')");
+        $this->addSql("INSERT INTO settings_options (variable, value, display_text) VALUES ('show_glossary_in_extra_tools', 'exercise_and_lp', 'ExerciseAndLearningPath')");
+        $this->addSql("INSERT INTO settings_current (variable, subkey, type, category, selected_value, title, comment, scope, subkeytext, access_url_changeable) VALUES ('documents_default_visibility_defined_in_course', NULL,'radio','Tools','false','DocumentsDefaultVisibilityDefinedInCourseTitle','DocumentsDefaultVisibilityDefinedInCourseComment',NULL, NULL, 1)");
+        $this->addSql("INSERT INTO settings_options (variable, value, display_text) VALUES ('documents_default_visibility_defined_in_course', 'true', 'Yes')");
+        $this->addSql("INSERT INTO settings_options (variable, value, display_text) VALUES ('documents_default_visibility_defined_in_course', 'false', 'No')");
+        $this->addSql("INSERT INTO settings_current (variable, subkey, type, category, selected_value, title, comment, scope, subkeytext, access_url_changeable) VALUES ('enabled_mathjax', NULL, 'radio', 'Editor', 'false', 'EnableMathJaxTitle', 'EnableMathJaxComment', NULL, NULL, 0)");
+        $this->addSql("INSERT INTO settings_options (variable, value, display_text) VALUES ('enabled_mathjax', 'true', 'Yes')");
+        $this->addSql("INSERT INTO settings_options (variable, value, display_text) VALUES ('enabled_mathjax', 'false', 'No')");
+
+        $this->addSql("INSERT INTO language (original_name, english_name, isocode, dokeos_folder, available) VALUES ('Føroyskt', 'faroese', 'fo', 'faroese', 0), ('Tagalog', 'tagalog', 'tl', 'tagalog',1), ('Tibetan', 'tibetan', 'bo', 'tibetan', 0), ('isiXhosa', 'xhosa', 'xh', 'xhosa', 0)");
+        $this->addSql("DELETE FROM settings_options WHERE variable = 'show_glossary_in_extra_tools'");
+
+        $this->addSql("ALTER TABLE c_student_publication MODIFY COLUMN date_of_qualification DATETIME NULL DEFAULT NULL");
+        $this->addSql("ALTER TABLE c_student_publication MODIFY COLUMN sent_date DATETIME NULL DEFAULT NULL");
+        $this->addSql("UPDATE c_student_publication SET date_of_qualification = NULL WHERE date_of_qualification = '0000-00-00 00:00:00'");
+        $this->addSql("UPDATE c_student_publication SET sent_date = NULL WHERE sent_date = '0000-00-00 00:00:00'");
+
+        $this->addSql("ALTER TABLE c_student_publication_assignment MODIFY COLUMN expires_on DATETIME NULL DEFAULT NULL");
+        $this->addSql("ALTER TABLE c_student_publication_assignment MODIFY COLUMN ends_on DATETIME NULL DEFAULT NULL");
+        $this->addSql("UPDATE c_student_publication_assignment SET expires_on = NULL WHERE expires_on = '0000-00-00 00:00:00'");
+        $this->addSql("UPDATE c_student_publication_assignment SET ends_on = NULL WHERE ends_on = '0000-00-00 00:00:00'");
+
+        $this->addSql("UPDATE settings_current SET type = 'checkbox' WHERE variable = 'registration' AND category = 'User'");
+
+        $this->addSql("UPDATE settings_current SET selected_value = 'UTF-8' WHERE variable = 'platform_charset'");
+
+        $this->addSql("ALTER TABLE course_rel_user DROP PRIMARY KEY");
+        $this->addSql("ALTER TABLE course_rel_user ADD COLUMN id INT NOT NULL PRIMARY KEY AUTO_INCREMENT");
+        $this->addSql("ALTER TABLE course_rel_user MODIFY COLUMN user_id INT NULL");
+
+        $this->addSql("ALTER TABLE user MODIFY COLUMN user_id INT NULL");
+
+        $this->addSql("ALTER TABLE access_url_rel_course DROP PRIMARY KEY");
+        $this->addSql("ALTER TABLE access_url_rel_course ADD COLUMN id INT NOT NULL PRIMARY KEY AUTO_INCREMENT");
+        $this->addSql("ALTER TABLE access_url_rel_course DROP COLUMN course_code");
+        $this->addSql("ALTER TABLE access_url_rel_course ADD INDEX idx_select_c (c_id)");
+        $this->addSql("ALTER TABLE access_url_rel_course ADD INDEX idx_select_u (access_url_id)");
+
+        $this->addSql("ALTER TABLE access_url ADD COLUMN url_type TINYINT(1) NULL");
+
+        $this->addSql("ALTER TABLE course_rel_user ADD INDEX idx_select_c (c_id)");
+
+        $this->addSql("ALTER TABLE track_e_uploads ADD COLUMN c_id INT NOT NULL");
+        $this->addSql("UPDATE track_e_uploads SET c_id = (SELECT id FROM course WHERE code = upload_cours_id)");
+
+        //postUp
+        $this->addSql("ALTER TABLE track_e_access DROP COLUMN access_cours_code");
+        $this->addSql("ALTER TABLE track_e_default DROP COLUMN default_cours_code");
+        $this->addSql("ALTER TABLE track_e_lastaccess DROP COLUMN access_cours_code");
+        $this->addSql("ALTER TABLE track_e_exercices DROP COLUMN exe_cours_id");
+        $this->addSql("ALTER TABLE track_e_downloads DROP COLUMN down_cours_id");
+        $this->addSql("ALTER TABLE track_e_hotpotatoes DROP COLUMN exe_cours_id");
+        $this->addSql("ALTER TABLE track_e_links DROP COLUMN links_cours_id");
+        $this->addSql("ALTER TABLE track_e_course_access DROP COLUMN course_code");
+        $this->addSql("ALTER TABLE track_e_online DROP COLUMN course");
+        $this->addSql("ALTER TABLE track_e_attempt DROP COLUMN course_code");
+
+        $this->addSql("ALTER TABLE course_rel_user DROP COLUMN group_id");
+        $this->addSql("ALTER TABLE course_rel_user DROP COLUMN role");
+
+        $this->addSql("DROP TABLE track_c_countries");
+        $this->addSql("DROP TABLE track_c_browsers");
+        $this->addSql("DROP TABLE track_c_os");
+        $this->addSql("DROP TABLE track_c_providers");
+        $this->addSql("DROP TABLE track_c_referers");
+    }
+
+    /**
+     * We don't allow downgrades yet
+     * @param Schema $schema
+     */
+    public function down(Schema $schema)
+    {
+    }
+}

+ 181 - 0
app/Migrations/Schema/V110/Version20150423093100.php

@@ -0,0 +1,181 @@
+<?php
+/* For licensing terms, see /license.txt */
+
+namespace Application\Migrations\Schema\V110;
+
+use Application\Migrations\AbstractMigrationChamilo;
+use Doctrine\DBAL\Schema\Schema;
+use Doctrine\DBAL\Types\Type;
+
+/**
+ * Class Version20150423093100
+ *
+ * @package Application\Migrations\Schema\V110
+ */
+class Version20150423093100 extends AbstractMigrationChamilo
+{
+    /**
+     * @param Schema $schema
+     *
+     * @throws \Doctrine\DBAL\Schema\SchemaException
+     */
+    public function up(Schema $schema)
+    {
+        // Sequence changes
+        if (!$schema->hasTable('sequence_rule')) {
+            $sequenceRule = $schema->createTable('sequence_rule');
+            $sequenceRule->addColumn('id', Type::INTEGER)->setAutoincrement(true);
+            $sequenceRule->addColumn('text', Type::TEXT);
+            $sequenceRule->setPrimaryKey(['id']);
+        }
+
+        if (!$schema->hasTable('sequence_condition')) {
+            $sequenceCondition = $schema->createTable('sequence_condition');
+            $sequenceCondition->addColumn('id', Type::INTEGER)->setAutoincrement(true);
+            $sequenceCondition->addColumn('description', Type::TEXT);
+            $sequenceCondition->addColumn('mat_op', Type::INTEGER);
+            $sequenceCondition->addColumn('param', Type::FLOAT);
+            $sequenceCondition->addColumn('act_true', Type::INTEGER);
+            $sequenceCondition->addColumn('act_false', Type::INTEGER);
+            $sequenceCondition->setPrimaryKey(['id']);
+        }
+
+        if (!$schema->hasTable('sequence_rule_condition')) {
+            $sequenceRuleCondition = $schema->createTable('sequence_rule_condition');
+            $sequenceRuleCondition->addColumn('id', Type::INTEGER)->setAutoincrement(true);
+            $sequenceRuleCondition->addColumn('sequence_rule_id', Type::INTEGER)->setNotnull(false);
+            $sequenceRuleCondition->addColumn('sequence_condition_id', Type::INTEGER)->setNotnull(false);
+            $sequenceRuleCondition->setPrimaryKey(['id']);
+            $sequenceRuleCondition->addIndex(['sequence_rule_id']);
+            $sequenceRuleCondition->addIndex(['sequence_condition_id']);
+            $sequenceRuleCondition->addForeignKeyConstraint('sequence_condition', ['sequence_condition_id'], ['id']);
+            $sequenceRuleCondition->addForeignKeyConstraint('sequence_rule', ['sequence_rule_id'], ['id']);
+        }
+
+        if (!$schema->hasTable('sequence_method')) {
+            $sequenceMethod = $schema->createTable('sequence_method');
+            $sequenceMethod->addColumn('id', Type::INTEGER)->setAutoincrement(true);
+            $sequenceMethod->addColumn('description', Type::TEXT);
+            $sequenceMethod->addColumn('formula', Type::TEXT);
+            $sequenceMethod->addColumn('assign', Type::INTEGER);
+            $sequenceMethod->addColumn('met_type', Type::INTEGER);
+            $sequenceMethod->addColumn('act_false', Type::INTEGER);
+            $sequenceMethod->setPrimaryKey(['id']);
+        }
+
+        if (!$schema->hasTable('sequence_rule_method')) {
+            $sequenceRuleMethod = $schema->createTable('sequence_rule_method');
+            $sequenceRuleMethod->addColumn('id', Type::INTEGER)->setAutoincrement(true);
+            $sequenceRuleMethod->addColumn('sequence_rule_id', Type::INTEGER)->setNotnull(false);
+            $sequenceRuleMethod->addColumn('sequence_method_id', Type::INTEGER)->setNotnull(false);
+            $sequenceRuleMethod->addColumn('method_order', Type::INTEGER);
+            $sequenceRuleMethod->setPrimaryKey(['id']);
+            $sequenceRuleMethod->addIndex(['sequence_rule_id']);
+            $sequenceRuleMethod->addIndex(['sequence_method_id']);
+            $sequenceRuleMethod->addForeignKeyConstraint('sequence_method', ['sequence_method_id'], ['id']);
+            $sequenceRuleMethod->addForeignKeyConstraint('sequence_rule', ['sequence_rule_id'], ['id']);
+        }
+
+        if (!$schema->hasTable('sequence_variable')) {
+            $sequenceVariable = $schema->createTable('sequence_variable');
+            $sequenceVariable->addColumn('id', Type::INTEGER)->setAutoincrement(true);
+            $sequenceVariable->addColumn('name', Type::STRING)->setLength(255)->setNotnull(false);
+            $sequenceVariable->addColumn('description', Type::TEXT)->setNotnull(false);
+            $sequenceVariable->addColumn('default_val', Type::STRING)->setLength(255)->setNotnull(false);
+            $sequenceVariable->setPrimaryKey(['id']);
+        }
+
+        if (!$schema->hasTable('sequence_formula')) {
+            $sequenceFormula = $schema->createTable('sequence_formula');
+            $sequenceFormula->addColumn('id', Type::INTEGER)->setAutoincrement(true);
+            $sequenceFormula->addColumn('sequence_method_id', Type::INTEGER)->setNotnull(false);
+            $sequenceFormula->addColumn('sequence_variable_id', Type::INTEGER)->setNotnull(false);
+            $sequenceFormula->setPrimaryKey(['id']);
+            $sequenceFormula->addIndex(['sequence_method_id']);
+            $sequenceFormula->addIndex(['sequence_variable_id']);
+            $sequenceFormula->addForeignKeyConstraint('sequence_variable', ['sequence_variable_id'], ['id']);
+            $sequenceFormula->addForeignKeyConstraint('sequence_method', ['sequence_method_id'], ['id']);
+        }
+
+        if (!$schema->hasTable('sequence_valid')) {
+            $sequenceValid = $schema->createTable('sequence_valid');
+            $sequenceValid->addColumn('id', Type::INTEGER)->setAutoincrement(true);
+            $sequenceValid->addColumn('sequence_variable_id', Type::INTEGER)->setNotnull(false);
+            $sequenceValid->addColumn('sequence_condition_id', Type::INTEGER)->setNotnull(false);
+            $sequenceValid->setPrimaryKey(['id']);
+            $sequenceValid->addIndex(['sequence_variable_id']);
+            $sequenceValid->addIndex(['sequence_condition_id']);
+            $sequenceValid->addForeignKeyConstraint('sequence_condition', ['sequence_condition_id'], ['id']);
+            $sequenceValid->addForeignKeyConstraint('sequence_variable', ['sequence_variable_id'], ['id']);
+        }
+
+        if (!$schema->hasTable('sequence_type_entity')) {
+            $sequenceTypeEntity = $schema->createTable('sequence_type_entity');
+            $sequenceTypeEntity->addColumn('id', Type::INTEGER)->setAutoincrement(true);
+            $sequenceTypeEntity->addColumn('name', Type::STRING)->setLength(255);
+            $sequenceTypeEntity->addColumn('description', Type::TEXT);
+            $sequenceTypeEntity->addColumn('ent_table', Type::STRING)->setLength(255);
+            $sequenceTypeEntity->setPrimaryKey(['id']);
+        }
+
+        if (!$schema->hasTable('sequence_row_entity')) {
+            $sequenceRowEntity = $schema->createTable('sequence_row_entity');
+            $sequenceRowEntity->addColumn('id', Type::INTEGER)->setAutoincrement(true);
+            $sequenceRowEntity->addColumn('sequence_type_entity_id', Type::INTEGER)->setNotnull(false);
+            $sequenceRowEntity->addColumn('c_id', Type::INTEGER);
+            $sequenceRowEntity->addColumn('session_id', Type::INTEGER);
+            $sequenceRowEntity->addColumn('row_id', Type::INTEGER);
+            $sequenceRowEntity->addColumn('name', Type::STRING)->setLength(255);
+            $sequenceRowEntity->setPrimaryKey(['id']);
+            $sequenceRowEntity->addIndex(['sequence_type_entity_id']);
+            $sequenceRowEntity->addForeignKeyConstraint('sequence_type_entity', ['sequence_type_entity_id'], ['id']);
+        }
+
+        if (!$schema->hasTable('sequence')) {
+            $sequence = $schema->createTable('sequence');
+            $sequence->addColumn('id', Type::INTEGER)->setAutoincrement(true);
+            $sequence->addColumn('name', Type::STRING)->setLength(255);
+            $sequence->addColumn('graph', Type::TEXT)->setNotnull(false);
+            $sequence->addColumn('created_at', Type::DATETIME);
+            $sequence->addColumn('updated_at', Type::DATETIME);
+            $sequence->setPrimaryKey(['id']);
+        }
+
+        if (!$schema->hasTable('sequence_value')) {
+            $sequenceValue = $schema->createTable('sequence_value');
+            $sequenceValue->addColumn('id', Type::INTEGER)->setAutoincrement(true);
+            $sequenceValue->addColumn('sequence_row_entity_id', Type::INTEGER)->setNotnull(false);
+            $sequenceValue->addColumn('user_id', Type::INTEGER);
+            $sequenceValue->addColumn('advance', Type::FLOAT);
+            $sequenceValue->addColumn('complete_items', Type::INTEGER);
+            $sequenceValue->addColumn('total_items', Type::INTEGER);
+            $sequenceValue->addColumn('success', Type::BOOLEAN);
+            $sequenceValue->addColumn('success_date', Type::DATETIME)->setNotnull(false);
+            $sequenceValue->addColumn('available', Type::BOOLEAN);
+            $sequenceValue->addColumn('available_start_date', Type::DATETIME)->setNotnull(false);
+            $sequenceValue->addColumn('available_end_date', Type::DATETIME)->setNotnull(false);
+            $sequenceValue->setPrimaryKey(['id']);
+            $sequenceValue->addIndex(['sequence_row_entity_id']);
+            $sequenceValue->addForeignKeyConstraint('sequence_row_entity', ['sequence_row_entity_id'], ['id']);
+        }
+
+        if (!$schema->hasTable('sequence_resource')) {
+            $sequenceResource = $schema->createTable('sequence_resource');
+            $sequenceResource->addColumn('id', Type::INTEGER)->setAutoincrement(true);
+            $sequenceResource->addColumn('sequence_id', Type::INTEGER)->setNotnull(false);
+            $sequenceResource->addColumn('type', Type::INTEGER);
+            $sequenceResource->addColumn('resource_id', Type::INTEGER);
+            $sequenceResource->setPrimaryKey(['id']);
+            $sequenceResource->addIndex(['sequence_id']);
+            $sequenceResource->addForeignKeyConstraint('sequence', ['sequence_id'], ['id']);
+        }
+    }
+
+    /**
+     * We don't allow downgrades yet
+     * @param Schema $schema
+     */
+    public function down(Schema $schema)
+    {
+    }
+}

+ 77 - 0
app/Migrations/Schema/V110/Version20150504182600.php

@@ -0,0 +1,77 @@
+<?php
+/* For licensing terms, see /license.txt */
+
+namespace Application\Migrations\Schema\V110;
+
+use Application\Migrations\AbstractMigrationChamilo;
+use Doctrine\DBAL\Schema\Schema;
+
+/**
+ * Class Version20150504182600
+ *
+ * @package Application\Migrations\Schema\V110
+ */
+class Version20150504182600 extends AbstractMigrationChamilo
+{
+    /**
+     * @param Schema $schema
+     *
+     * @throws \Doctrine\DBAL\Schema\SchemaException
+     */
+    public function up(Schema $schema)
+    {
+        // Set parent language to Spanish for all close-by languages. Same for Italian,
+        // French, Portuguese and Chinese
+        $connection = $this->connection;
+        $sql = "SELECT id, english_name
+                FROM language
+                WHERE english_name IN ('spanish', 'italian', 'portuguese', 'simpl_chinese', 'french')";
+        $result = $connection->executeQuery($sql);
+        $dataList = $result->fetchAll();
+        $languages = array();
+
+        if (!empty($dataList)) {
+            foreach ($dataList as $data) {
+                $languages[$data['english_name']] = $data['id'];
+            }
+        }
+        $this->addSql("
+            UPDATE language SET parent_id = " . $languages['spanish'] . " WHERE english_name = 'quechua_cusco'
+        ");
+        $this->addSql("
+            UPDATE language SET parent_id = " . $languages['spanish'] . " WHERE english_name = 'galician'
+        ");
+        $this->addSql("
+            UPDATE language SET parent_id = " . $languages['spanish'] . " WHERE english_name = 'esperanto'
+        ");
+        $this->addSql("
+            UPDATE language SET parent_id = " . $languages['spanish'] . " WHERE english_name = 'catalan'
+        ");
+        $this->addSql("
+            UPDATE language SET parent_id = " . $languages['spanish'] . " WHERE english_name = 'asturian'
+        ");
+        $this->addSql("
+            UPDATE language SET parent_id = " . $languages['spanish'] . " WHERE english_name = 'friulian'
+        ");
+        $this->addSql("
+            UPDATE language SET parent_id = " . $languages['french'] . " WHERE english_name = 'occitan'
+        ");
+        $this->addSql("
+            UPDATE language SET parent_id = " . $languages['portuguese'] . " WHERE english_name = 'brazilian'
+        ");
+        $this->addSql("
+            UPDATE language SET parent_id = " . $languages['simpl_chinese'] . " WHERE english_name = 'trad_chinese'
+        ");
+    }
+
+    /**
+     * We don't allow downgrades yet
+     * @param Schema $schema
+     */
+    public function down(Schema $schema)
+    {
+        $this->addSql("
+            UPDATE language SET parent_id = 0 WHERE english_name IN ('trad_chinese', 'brazilian', 'occitan', 'friulian', 'asturian', 'catalan', 'esperanto', 'galician', 'quechua_cusco')
+        ");
+    }
+}

+ 64 - 0
app/Migrations/Schema/V110/Version20150505132304.php

@@ -0,0 +1,64 @@
+<?php
+/* For licensing terms, see /license.txt */
+
+namespace Application\Migrations\Schema\V110;
+
+use Application\Migrations\AbstractMigrationChamilo;
+use Doctrine\DBAL\Schema\Schema;
+
+/**
+ * Extra fields changes
+ */
+class Version20150505132304 extends AbstractMigrationChamilo
+{
+    /**
+     * @param Schema $schema
+     */
+    public function up(Schema $schema)
+    {
+        // Force table creation in order to do updates/insert later.
+        $this->connection->executeQuery('CREATE TABLE IF NOT EXISTS extra_field (id INT AUTO_INCREMENT NOT NULL, extra_field_type INT NOT NULL, field_type INT NOT NULL, variable VARCHAR(64) NOT NULL, display_text VARCHAR(255) DEFAULT NULL, default_value LONGTEXT, field_order INT DEFAULT NULL, visible TINYINT(1) DEFAULT NULL, changeable TINYINT(1) DEFAULT NULL, filter TINYINT(1) DEFAULT NULL, created_at DATETIME NOT NULL, PRIMARY KEY(id))');
+        $this->connection->executeQuery('CREATE TABLE IF NOT EXISTS extra_field_values (id INT AUTO_INCREMENT NOT NULL, value VARCHAR(255) DEFAULT NULL, field_id INT NOT NULL, item_id INT NOT NULL, comment LONGTEXT, created_at DATETIME NOT NULL, updated_at DATETIME NOT NULL, PRIMARY KEY(id))');
+        $this->connection->executeQuery('CREATE TABLE IF NOT EXISTS extra_field_options (id INT AUTO_INCREMENT NOT NULL, field_id INT DEFAULT NULL, option_value LONGTEXT, display_text VARCHAR(64) DEFAULT NULL, option_order INT DEFAULT NULL, priority VARCHAR(255) DEFAULT NULL, priority_message VARCHAR(255) DEFAULT NULL, INDEX IDX_A572E3AE443707B0 (field_id), PRIMARY KEY(id))');
+
+        if (!$schema->hasTable('extra_field_options')) {
+            $this->connection->executeQuery(
+                'ALTER TABLE extra_field_options ADD CONSTRAINT FK_A572E3AE443707B0 FOREIGN KEY (field_id) REFERENCES extra_field (id)'
+            );
+        }
+
+        $this->addSql('CREATE TABLE IF NOT EXISTS extra_field_option_rel_field_option (id INT AUTO_INCREMENT NOT NULL, field_id INT DEFAULT NULL, field_option_id INT DEFAULT NULL, related_field_option_id INT DEFAULT NULL, role_id INT DEFAULT NULL, UNIQUE INDEX idx (field_id, role_id, field_option_id, related_field_option_id), PRIMARY KEY(id))');
+
+        /*
+        $this->addSql('DROP TABLE course_field');
+        $this->addSql('DROP TABLE course_field_options');
+        $this->addSql('DROP TABLE course_field_values');
+        $this->addSql('DROP TABLE session_field');
+        $this->addSql('DROP TABLE session_field_options');
+        $this->addSql('DROP TABLE session_field_values');
+        $this->addSql('DROP TABLE user_field');
+        $this->addSql('DROP TABLE user_field_options');
+        $this->addSql('DROP TABLE user_field_values');
+        */
+    }
+
+    /**
+     * @param Schema $schema
+     */
+    public function postUp(Schema $schema)
+    {
+
+    }
+
+    /**
+     * @param Schema $schema
+     */
+    public function down(Schema $schema)
+    {
+        $this->addSql('ALTER TABLE extra_field_options DROP FOREIGN KEY FK_A572E3AE443707B0');
+        $this->addSql('DROP TABLE extra_field_option_rel_field_option');
+        $this->addSql('DROP TABLE extra_field_options');
+        $this->addSql('DROP TABLE extra_field');
+        $this->addSql('DROP TABLE extra_field_values');
+    }
+}

+ 77 - 0
app/Migrations/Schema/V110/Version20150505142900.php

@@ -0,0 +1,77 @@
+<?php
+/* For licensing terms, see /license.txt */
+
+namespace Application\Migrations\Schema\V110;
+
+use Application\Migrations\AbstractMigrationChamilo;
+use Doctrine\DBAL\Schema\Schema;
+use Doctrine\DBAL\Types\Type;
+
+/**
+ * Class Version20150505142900
+ *
+ * @package Application\Migrations\Schema\V110
+ */
+class Version20150505142900 extends AbstractMigrationChamilo
+{
+    /**
+     * @param Schema $schema
+     *
+     * @throws \Doctrine\DBAL\Schema\SchemaException
+     */
+    public function up(Schema $schema)
+    {
+        // Create table for video chat
+        if (!$schema->hasTable('chat_video')) {
+            $chatVideoTable = $schema->createTable('chat_video');
+            $chatVideoTable->addColumn(
+                'id',
+                Type::INTEGER,
+                ['autoincrement' => true, 'notnull' => true]
+            );
+            $chatVideoTable->addColumn(
+                'from_user',
+                Type::INTEGER,
+                ['notnull' => true]
+            );
+            $chatVideoTable->addColumn(
+                'to_user',
+                Type::INTEGER,
+                ['notnull' => true]
+            );
+            $chatVideoTable->addColumn(
+                'room_name',
+                Type::STRING,
+                ['length' => 255, 'notnull' => true]
+            );
+            $chatVideoTable->addColumn(
+                'datetime',
+                Type::DATETIME,
+                ['notnull' => true]
+            );
+            $chatVideoTable->setPrimaryKey(['id']);
+            $chatVideoTable->addIndex(
+                ['from_user'],
+                'idx_chat_video_from_user'
+            );
+            $chatVideoTable->addIndex(['to_user'], 'idx_chat_video_to_user');
+            $chatVideoTable->addIndex(
+                ['from_user', 'to_user'],
+                'idx_chat_video_users'
+            );
+            $chatVideoTable->addIndex(
+                ['room_name'],
+                'idx_chat_video_room_name'
+            );
+        }
+    }
+
+    /**
+     * We don't allow downgrades yet
+     * @param Schema $schema
+     */
+    public function down(Schema $schema)
+    {
+        $schema->dropTable('chat_video');
+    }
+}

+ 242 - 0
app/Migrations/Schema/V110/Version20150507152600.php

@@ -0,0 +1,242 @@
+<?php
+/* For licensing terms, see /license.txt */
+
+namespace Application\Migrations\Schema\V110;
+
+use Application\Migrations\AbstractMigrationChamilo;
+use Doctrine\DBAL\Schema\Schema;
+
+/**
+ * Class Version20150507152600
+ *
+ * @package Application\Migrations\Schema\V110
+ */
+class Version20150507152600 extends AbstractMigrationChamilo
+{
+    /**
+     * @param Schema $schema
+     *
+     * @throws \Doctrine\DBAL\Schema\SchemaException
+     */
+    public function up(Schema $schema)
+    {
+        // Move some settings from configuration.php to the database
+        // Current settings categories are:
+        // Platform, Course, Session, Languages, User, Tools, Editor, Security,
+        // Tuning, Gradebook, Timezones, Tracking, Search, stylesheets (lowercase),
+        // LDAP, CAS, Shibboleth, Facebook
+
+        // Setting $_configuration['hide_home_top_when_connected'] = true;
+        $value = $this->getConfigurationValue('hide_home_top_when_connected');
+
+        $this->addSettingCurrent(
+            'hide_home_top_when_connected',
+            '',
+            'radio',
+            'Platform',
+            ($value ? 'true' : 'false'),
+            'HideHomeTopContentWhenLoggedInText',
+            'HideHomeTopContentWhenLoggedInComment',
+            null,
+            '',
+            1,
+            true,
+            false,
+            [
+                0 => ['value' => 'true', 'text' => 'Yes'],
+                1 => ['value' => 'false', 'text' => 'No'],
+            ]
+        );
+
+        // Hide the global announcements for non-connected users
+        //$_configuration['hide_global_announcements_when_not_connected'] = true;
+        $value = $this->getConfigurationValue('hide_global_announcements_when_not_connected');
+        $this->addSettingCurrent(
+            'hide_global_announcements_when_not_connected',
+            '',
+            'radio',
+            'Platform',
+            ($value?'true':'false'),
+            'HideGlobalAnnouncementsWhenNotLoggedInText',
+            'HideGlobalAnnouncementsWhenNotLoggedInComment',
+            null,
+            '',
+            1,
+            true,
+            false,
+            [
+                0 => ['value' => 'true', 'text' => 'Yes'],
+                1 => ['value' => 'false', 'text' => 'No'],
+            ]
+        );
+
+        // Use this course as template for all new courses (define course real ID as value)
+        //$_configuration['course_creation_use_template'] = 14;
+        $value = $this->getConfigurationValue('course_creation_use_template');
+        $this->addSettingCurrent(
+            'course_creation_use_template',
+            '',
+            'textfield',
+            'Course',
+            ($value?$value:''),
+            'CourseCreationUsesTemplateText',
+            'CourseCreationUsesTemplateComment',
+            null,
+            '',
+            1,
+            true,
+            false,
+            [
+                0 => ['value' => 'true', 'text' => 'Yes'],
+                1 => ['value' => 'false', 'text' => 'No'],
+            ]
+        );
+
+        // Add password strength checker
+        //$_configuration['allow_strength_pass_checker'] = true;
+        $value = $this->getConfigurationValue('allow_strength_pass_checker');
+        $this->addSettingCurrent(
+            'allow_strength_pass_checker',
+            '',
+            'radio',
+            'Security',
+            ($value?'true':'false'),
+            'EnablePasswordStrengthCheckerText',
+            'EnablePasswordStrengthCheckerComment',
+            null,
+            '',
+            1,
+            true,
+            false,
+            [
+                0 => ['value' => 'true', 'text' => 'Yes'],
+                1 => ['value' => 'false', 'text' => 'No'],
+            ]
+        );
+
+        // Enable captcha
+        // $_configuration['allow_captcha'] = true;
+        $value = $this->getConfigurationValue('allow_captcha');
+        $this->addSettingCurrent(
+            'allow_captcha',
+            '',
+            'radio',
+            'Security',
+            ($value?'true':'false'),
+            'EnableCaptchaText',
+            'EnableCaptchaComment',
+            null,
+            '',
+            1,
+            true,
+            false,
+            [0 => ['value' => 'true', 'text' => 'Yes'], 1 => ['value' => 'false', 'text' => 'No']]
+        );
+        // Prevent account from logging in for a certain amount of time
+        // if captcha is wrong for the specified number of times
+        //$_configuration['captcha_number_mistakes_to_block_account'] = 5;
+        $value = $this->getConfigurationValue('captcha_number_mistakes_to_block_account');
+        $this->addSettingCurrent(
+            'captcha_number_mistakes_to_block_account',
+            '',
+            'textfield',
+            'Security',
+            ($value?$value:5),
+            'CaptchaNumberOfMistakesBeforeBlockingAccountText',
+            'CaptchaNumberOfMistakesBeforeBlockingAccountComment',
+            null,
+            '',
+            1,
+            true,
+            false
+        );
+        // Prevent account from logging in for the specified number of minutes
+        //$_configuration['captcha_time_to_block'] = 5;//minutes
+        $value = $this->getConfigurationValue('captcha_time_to_block');
+        $this->addSettingCurrent(
+            'captcha_time_to_block',
+            '',
+            'textfield',
+            'Security',
+            ($value?$value:5),
+            'CaptchaTimeAccountIsLockedText',
+            'CaptchaTimeAccountIsLockedComment',
+            null,
+            '',
+            1,
+            true,
+            false
+        );
+
+        // Allow DRH role to access all content and users from the sessions he follows
+        //$_configuration['drh_can_access_all_session_content'] = true;
+        $value = $this->getConfigurationValue('drh_can_access_all_session_content');
+        $this->addSettingCurrent(
+            'drh_can_access_all_session_content',
+            '',
+            'radio',
+            'Session',
+            ($value?'true':'false'),
+            'DRHAccessToAllSessionContentText',
+            'DRHAccessToAllSessionContentComment',
+            null,
+            '',
+            1,
+            true,
+            false,
+            [0 => ['value' => 'true', 'text' => 'Yes'], 1 => ['value' => 'false', 'text' => 'No']]
+        );
+
+        // Display group's forum in general forum tool
+        //$_configuration['display_groups_forum_in_general_tool'] = true;
+        $value = $this->getConfigurationValue('display_groups_forum_in_general_tool');
+        $this->addSettingCurrent(
+            'display_groups_forum_in_general_tool',
+            '',
+            'radio',
+            'Tools',
+            ($value?'true':'false'),
+            'ShowGroupForaInGeneralToolText',
+            'ShowGroupForaInGeneralToolComment',
+            null,
+            '',
+            1,
+            true,
+            false,
+            [0 => ['value' => 'true', 'text' => 'Yes'], 1 => ['value' => 'false', 'text' => 'No']]
+        );
+
+        // Allow course tutors in sessions to add existing students to their session
+        //$_configuration['allow_tutors_to_assign_students_to_session'] = 'false';
+        $value = $this->getConfigurationValue('allow_tutors_to_assign_students_to_session');
+        $this->addSettingCurrent(
+            'allow_tutors_to_assign_students_to_session',
+            '',
+            'radio',
+            'Session',
+            ($value?'true':'false'),
+            'TutorsCanAssignStudentsToSessionsText',
+            'TutorsCanAssignStudentsToSessionsComment',
+            null,
+            '',
+            1,
+            true,
+            false,
+            [0 => ['value' => 'true', 'text' => 'Yes'], 1 => ['value' => 'false', 'text' => 'No']]
+        );
+    }
+
+    /**
+     * We don't allow downgrades yet
+     * @param Schema $schema
+     */
+    public function down(Schema $schema)
+    {
+        $this->addSql("
+            DELETE FROM settings_options WHERE variable IN ('hide_home_top_when_connected', 'hide_global_announcements_when_not_connected', 'course_creation_use_template', 'allow_strength_pass_checker', 'allow_captcha', 'captcha_number_mistakes_to_block_account', 'captcha_time_to_block', 'drh_can_access_all_session_content', 'display_groups_forum_in_general_tool', 'allow_tutors_to_assign_students_to_session')
+        ");
+        $this->addSql("
+            DELETE FROM settings_current WHERE variable IN ('hide_home_top_when_connected', 'hide_global_announcements_when_not_connected', 'course_creation_use_template', 'allow_strength_pass_checker', 'allow_captcha', 'captcha_number_mistakes_to_block_account', 'captcha_time_to_block', 'drh_can_access_all_session_content', 'display_groups_forum_in_general_tool', 'allow_tutors_to_assign_students_to_session')
+        ");
+    }
+}

+ 43 - 0
app/Migrations/Schema/V110/Version20150511133949.php

@@ -0,0 +1,43 @@
+<?php
+/* For licensing terms, see /license.txt */
+
+namespace Application\Migrations\Schema\V110;
+
+use Application\Migrations\AbstractMigrationChamilo;
+use Doctrine\DBAL\Schema\Schema;
+
+/**
+ * Username changes
+ */
+class Version20150511133949 extends AbstractMigrationChamilo
+{
+    /**
+     * @param Schema $schema
+     */
+    public function up(Schema $schema)
+    {
+        $this->addSql('ALTER TABLE user ADD salt VARCHAR(255) NOT NULL');
+        $this->addSql('ALTER TABLE user ADD username_canonical VARCHAR(100) NOT NULL');
+        //$this->addSql('CREATE UNIQUE INDEX UNIQ_8D93D64992FC23A8 ON user (username_canonical)');
+        $this->addSql('ALTER TABLE user CHANGE password password VARCHAR(255) NOT NULL');
+
+        $this->addSql("INSERT INTO settings_current (variable, subkey, type, category, selected_value, title, comment, scope, subkeytext, access_url_changeable) VALUES ('allow_teachers_to_create_sessions', NULL,'radio','Session','false','AllowTeachersToCreateSessionsTitle','AllowTeachersToCreateSessionsComment', NULL, NULL, 0)");
+        $this->addSql("INSERT INTO settings_options (variable, value, display_text) VALUES ('allow_teachers_to_create_sessions', 'true', 'Yes')");
+        $this->addSql("INSERT INTO settings_options (variable, value, display_text) VALUES ('allow_teachers_to_create_sessions', 'false', 'No')");
+
+    }
+
+    /**
+     * @param Schema $schema
+     */
+    public function down(Schema $schema)
+    {
+        $this->addSql('ALTER TABLE user DROP salt');
+        $this->addSql('DROP INDEX UNIQ_8D93D64992FC23A8 ON user');
+        $this->addSql('ALTER TABLE user DROP username_canonical');
+        $this->addSql('ALTER TABLE user CHANGE password password VARCHAR(50) NOT NULL COLLATE utf8_unicode_ci');
+
+        $this->addSql('DELETE FROM settings_current WHERE variable = "allow_teachers_to_create_sessions" ');
+        $this->addSql('DELETE FROM settings_options WHERE variable = "allow_teachers_to_create_sessions" ');
+    }
+}

+ 29 - 0
app/Migrations/Schema/V110/Version20150519153200.php

@@ -0,0 +1,29 @@
+<?php
+/* For licensing terms, see /license.txt */
+
+namespace Application\Migrations\Schema\V110;
+
+use Application\Migrations\AbstractMigrationChamilo;
+use Doctrine\DBAL\Schema\Schema;
+
+/**
+ * Username changes
+ */
+class Version20150519153200 extends AbstractMigrationChamilo
+{
+    /**
+     * @param Schema $schema
+     */
+    public function up(Schema $schema)
+    {
+        $this->addSql('ALTER TABLE session_rel_user ADD COLUMN registered_at DATETIME NOT NULL');
+    }
+
+    /**
+     * @param Schema $schema
+     */
+    public function down(Schema $schema)
+    {
+        $this->addSql('ALTER TABLE session_rel_user DROP COLUMN registered_at');
+    }
+}

+ 31 - 0
app/Migrations/Schema/V110/Version20150521113600.php

@@ -0,0 +1,31 @@
+<?php
+/* For licensing terms, see /license.txt */
+
+namespace Application\Migrations\Schema\V110;
+
+use Application\Migrations\AbstractMigrationChamilo;
+use Doctrine\DBAL\Schema\Schema;
+
+/**
+ * Username changes
+ */
+class Version20150521113600 extends AbstractMigrationChamilo
+{
+    /**
+     * @param Schema $schema
+     */
+    public function up(Schema $schema)
+    {
+        $this->addSql('ALTER TABLE c_forum_thread MODIFY thread_replies int UNSIGNED NOT NULL DEFAULT 0');
+        $this->addSql('ALTER TABLE c_forum_thread MODIFY thread_views int UNSIGNED NOT NULL DEFAULT 0');
+    }
+
+    /**
+     * @param Schema $schema
+     */
+    public function down(Schema $schema)
+    {
+        $this->addSql('ALTER TABLE c_forum_thread MODIFY thread_replies int NULL');
+        $this->addSql('ALTER TABLE c_forum_thread MODIFY thread_views int NULL');
+    }
+}

+ 49 - 0
app/Migrations/Schema/V110/Version20150522112023.php

@@ -0,0 +1,49 @@
+<?php
+/* For licensing terms, see /license.txt */
+
+namespace Application\Migrations\Schema\V110;
+
+use Application\Migrations\AbstractMigrationChamilo;
+use Doctrine\DBAL\Schema\Schema;
+
+/**
+ * Usergroup changes
+ */
+class Version20150522112023 extends AbstractMigrationChamilo
+{
+    /**
+     * @param Schema $schema
+     */
+    public function up(Schema $schema)
+    {
+        // Set 0 if there's no group category.
+        $this->addSql('UPDATE c_group_info SET category_id = 0 WHERE category_id = 2');
+
+        $this->addSql('ALTER TABLE usergroup ADD group_type INT NOT NULL, ADD created_at DATETIME NOT NULL, ADD updated_at DATETIME NOT NULL');
+        $this->addSql('ALTER TABLE usergroup ADD picture VARCHAR(255) DEFAULT NULL, ADD url VARCHAR(255) DEFAULT NULL, ADD visibility VARCHAR(255) NOT NULL, ADD allow_members_leave_group INT NOT NULL, CHANGE description description LONGTEXT');
+        $this->addSql('CREATE TABLE usergroup_rel_usergroup (id INT AUTO_INCREMENT NOT NULL, group_id INT NOT NULL, subgroup_id INT NOT NULL, relation_type INT NOT NULL, PRIMARY KEY(id))');
+        $this->addSql('ALTER TABLE usergroup_rel_user ADD relation_type INT');
+
+        if (!$schema->hasTable('access_url_rel_usergroup')) {
+            $this->addSql(
+                'CREATE TABLE access_url_rel_usergroup (id INT AUTO_INCREMENT NOT NULL, access_url_id INT NOT NULL, usergroup_id INT NOT NULL, PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE = InnoDB'
+            );
+            $sql = 'SELECT * FROM usergroup';
+            $result = $this->connection->query($sql);
+            $results = $result->fetchAll();
+            foreach ($results as $result) {
+                $groupId = $result['id'];
+                $sql = "INSERT INTO access_url_rel_usergroup (access_url_id, usergroup_id) VALUES ('1', '$groupId')";
+                $this->addSql($sql);
+            }
+        }
+    }
+
+    /**
+     * @param Schema $schema
+     */
+    public function down(Schema $schema)
+    {
+        $this->addSql('DROP TABLE access_url_rel_usergroup');
+    }
+}

+ 821 - 0
app/Migrations/Schema/V110/Version20150522222222.php

@@ -0,0 +1,821 @@
+<?php
+/* For licensing terms, see /license.txt */
+
+namespace Application\Migrations\Schema\V110;
+
+use Application\Migrations\AbstractMigrationChamilo;
+use Doctrine\DBAL\Schema\Schema;
+
+/**
+ * Class Version20150522222222
+ * @package Application\Migrations\Schema\V11010
+ */
+class Version20150522222222 extends AbstractMigrationChamilo
+{
+    /**
+     * @param Schema $schema
+     */
+    public function up(Schema $schema)
+    {
+        // The first ALTER queries here requires a check because the field might already exist
+        $connection = $this->connection;
+        $fieldExists = false;
+        $sql = "SELECT *
+                FROM user
+                LIMIT 1";
+        $result = $connection->executeQuery($sql);
+        $dataList = $result->fetchAll();
+        if (!empty($dataList)) {
+            foreach ($dataList as $data) {
+                if (isset($data['last_login'])) {
+                    $fieldExists = true;
+                }
+            }
+        }
+        if (!$fieldExists) {
+            $this->addSql('ALTER TABLE user ADD COLUMN last_login datetime DEFAULT NULL');
+        }
+        // calendar events comments
+        $fieldExists = false;
+        $sql = "SELECT *
+                FROM c_calendar_event
+                LIMIT 1";
+        $result = $connection->executeQuery($sql);
+        $dataList = $result->fetchAll();
+        if (!empty($dataList)) {
+            foreach ($dataList as $data) {
+                if (isset($data['comment'])) {
+                    $fieldExists = true;
+                }
+            }
+        }
+        if (!$fieldExists) {
+            $this->addSql("ALTER TABLE c_calendar_event ADD COLUMN comment TEXT");
+        }
+
+        // Move some settings from configuration.php to the database
+        // Current settings categories are:
+        // Platform, Course, Session, Languages, User, Tools, Editor, Security,
+        // Tuning, Gradebook, Timezones, Tracking, Search, stylesheets (lowercase),
+        // LDAP, CAS, Shibboleth, Facebook
+
+        // Allow select the return link in the LP view
+        $value = $this->getConfigurationValue('allow_lp_return_link');
+        $this->addSettingCurrent(
+            'allow_lp_return_link',
+            '',
+            'radio',
+            'Course',
+            ($value?$value:'true'),
+            'AllowLearningPathReturnLinkTitle',
+            'AllowLearningPathReturnLinkComment',
+            null,
+            '',
+            1,
+            true,
+            false,
+            [0 => ['value' => 'true', 'text' => 'Yes'], 1 => ['value' => 'false', 'text' => 'No']]
+        );
+
+        // If true the export link is blocked.
+        $value = $this->getConfigurationValue('hide_scorm_export_link');
+        $this->addSettingCurrent(
+            'hide_scorm_export_link',
+            '',
+            'radio',
+            'Course',
+            ($value?$value:'false'),
+            'HideScormExportLinkTitle',
+            'HideScormExportLinkComment',
+            null,
+            '',
+            1,
+            true,
+            false,
+            [0 => ['value' => 'true', 'text' => 'Yes'], 1 => ['value' => 'false', 'text' => 'No']]
+        );
+
+        // If true the copy link is blocked.
+        //$_configuration['hide_scorm_copy_link'] = false;
+        $value = $this->getConfigurationValue('hide_scorm_copy_link');
+        $this->addSettingCurrent(
+            'hide_scorm_copy_link',
+            '',
+            'radio',
+            'Course',
+            ($value?$value:'false'),
+            'HideScormCopyLinkTitle',
+            'HideScormCopyLinkComment',
+            null,
+            '',
+            1,
+            true,
+            false,
+            [0 => ['value' => 'true', 'text' => 'Yes'], 1 => ['value' => 'false', 'text' => 'No']]
+        );
+
+        // If true the pdf export link is blocked.
+        //$_configuration['hide_scorm_pdf_link'] = false;
+        $value = $this->getConfigurationValue('hide_scorm_pdf_link');
+        $this->addSettingCurrent(
+            'hide_scorm_pdf_link',
+            '',
+            'radio',
+            'Course',
+            ($value?$value:'false'),
+            'HideScormPdfLinkTitle',
+            'HideScormPdfLinkComment',
+            null,
+            '',
+            1,
+            true,
+            false,
+            [0 => ['value' => 'true', 'text' => 'Yes'], 1 => ['value' => 'false', 'text' => 'No']]
+        );
+
+        // Default session days before coach access
+        //$_configuration['session_days_before_coach_access'] = 0;
+        $value = $this->getConfigurationValue('session_days_before_coach_access');
+        $this->addSettingCurrent(
+            'session_days_before_coach_access',
+            '',
+            'textfield',
+            'Session',
+            ($value?$value:'0'),
+            'SessionDaysBeforeCoachAccessTitle',
+            'SessionDaysBeforeCoachAccessComment',
+            null,
+            '',
+            1,
+            true,
+            false
+        );
+
+
+        // Default session days after coach access
+        //$_configuration['session_days_after_coach_access'] = 0;
+        $value = $this->getConfigurationValue('session_days_after_coach_access');
+        $this->addSettingCurrent(
+            'session_days_after_coach_access',
+            '',
+            'textfield',
+            'Session',
+            ($value?$value:'0'),
+            'SessionDaysAfterCoachAccessTitle',
+            'SessionDaysAfterCoachAccessComment',
+            null,
+            '',
+            1,
+            true,
+            false
+        );
+
+        // PDF Logo header in app/Resources/public/css/themes/xxx/images/pdf_logo_header.png
+        //$_configuration['pdf_logo_header'] = false;
+        $value = $this->getConfigurationValue('pdf_logo_header');
+        $this->addSettingCurrent(
+            'pdf_logo_header',
+            '',
+            'radio',
+            'Course',
+            ($value?$value:'false'),
+            'PdfLogoHeaderTitle',
+            'PdfLogoHeaderComment',
+            null,
+            '',
+            1,
+            true,
+            false,
+            [0 => ['value' => 'true', 'text' => 'Yes'], 1 => ['value' => 'false', 'text' => 'No']]
+        );
+
+        // Order inscription user list by official_code
+        //$_configuration['order_user_list_by_official_code'] = false;
+        $value = $this->getConfigurationValue('order_user_list_by_official_code');
+        $this->addSettingCurrent(
+            'order_user_list_by_official_code',
+            '',
+            'radio',
+            'Platform',
+            ($value?$value:'false'),
+            'OrderUserListByOfficialCodeTitle',
+            'OrderUserListByOfficialCodeComment',
+            null,
+            '',
+            1,
+            true,
+            false,
+            [0 => ['value' => 'true', 'text' => 'Yes'], 1 => ['value' => 'false', 'text' => 'No']]
+        );
+
+        // Default course setting "email_alert_manager_on_new_quiz"
+        //$_configuration['email_alert_manager_on_new_quiz'] = 1;
+        $value = $this->getConfigurationValue('email_alert_manager_on_new_quiz');
+        $this->addSettingCurrent(
+            'email_alert_manager_on_new_quiz',
+            '',
+            'radio',
+            'Course',
+            ($value?$value:'true'),
+            'AlertManagerOnNewQuizTitle',
+            'AlertManagerOnNewQuizComment',
+            null,
+            '',
+            1,
+            true,
+            false,
+            [0 => ['value' => 'true', 'text' => 'Yes'], 1 => ['value' => 'false', 'text' => 'No']]
+        );
+
+        // Show official code in exercise report list.
+        //$_configuration['show_official_code_exercise_result_list'] = false;
+        $value = $this->getConfigurationValue('show_official_code_exercise_result_list');
+        $this->addSettingCurrent(
+            'show_official_code_exercise_result_list',
+            '',
+            'radio',
+            'Tools',
+            ($value?$value:'false'),
+            'ShowOfficialCodeInExerciseResultListTitle',
+            'ShowOfficialCodeInExerciseResultListComment',
+            null,
+            '',
+            1,
+            true,
+            false,
+            [0 => ['value' => 'true', 'text' => 'Yes'], 1 => ['value' => 'false', 'text' => 'No']]
+        );
+
+
+        // Hide private courses from course catalog
+        //$_configuration['course_catalog_hide_private'] = false;
+        $value = $this->getConfigurationValue('course_catalog_hide_private');
+        $this->addSettingCurrent(
+            'course_catalog_hide_private',
+            '',
+            'radio',
+            'Platform',
+            ($value?$value:'false'),
+            'HidePrivateCoursesFromCourseCatalogTitle',
+            'HidePrivateCoursesFromCourseCatalogComment',
+            null,
+            '',
+            1,
+            true,
+            false,
+            [0 => ['value' => 'true', 'text' => 'Yes'], 1 => ['value' => 'false', 'text' => 'No']]
+        );
+
+        // Display sessions catalog
+        // 0 = show only courses; 1 = show only sessions; 2 = show courses and sessions
+        //$_configuration['catalog_show_courses_sessions'] = 0;
+        $value = $this->getConfigurationValue('catalog_show_courses_sessions');
+        $this->addSettingCurrent(
+            'catalog_show_courses_sessions',
+            '',
+            'radio',
+            'Platform',
+            ($value?$value:'0'),
+            'CoursesCatalogueShowSessionsTitle',
+            'CoursesCatalogueShowSessionsComment',
+            null,
+            '',
+            1,
+            true,
+            false,
+            [0 => ['value' => '0', 'text' => 'CatalogueShowOnlyCourses'], 1 => ['value' => '1', 'text' => 'CatalogueShowOnlySessions'], 2 => ['value' => '2', 'text' => 'CatalogueShowCoursesAndSessions']]
+        );
+
+        // Auto detect language custom pages.
+        // $_configuration['auto_detect_language_custom_pages'] = true;
+        $value = $this->getConfigurationValue('auto_detect_language_custom_pages');
+        $this->addSettingCurrent(
+            'auto_detect_language_custom_pages',
+            '',
+            'radio',
+            'Platform',
+            ($value?$value:'true'),
+            'AutoDetectLanguageCustomPagesTitle',
+            'AutoDetectLanguageCustomPagesComment',
+            null,
+            '',
+            1,
+            true,
+            false,
+            [0 => ['value' => 'true', 'text' => 'Yes'], 1 => ['value' => 'false', 'text' => 'No']]
+        );
+
+        // Show reduce LP report
+        //$_configuration['lp_show_reduced_report'] = false;
+        $value = $this->getConfigurationValue('lp_show_reduced_report');
+        $this->addSettingCurrent(
+            'lp_show_reduced_report',
+            '',
+            'radio',
+            'Tools',
+            ($value?$value:'false'),
+            'LearningPathShowReducedReportTitle',
+            'LearningPathShowReducedReportComment',
+            null,
+            '',
+            1,
+            true,
+            false,
+            [0 => ['value' => 'true', 'text' => 'Yes'], 1 => ['value' => 'false', 'text' => 'No']]
+        );
+
+        //Allow session-to-session copy
+        //$_configuration['allow_session_course_copy_for_teachers'] = true;
+        $value = $this->getConfigurationValue('allow_session_course_copy_for_teachers');
+        $this->addSettingCurrent(
+            'allow_session_course_copy_for_teachers',
+            '',
+            'radio',
+            'Session',
+            ($value?$value:'false'),
+            'AllowSessionCourseCopyForTeachersTitle',
+            'AllowSessionCourseCopyForTeachersComment',
+            null,
+            '',
+            1,
+            true,
+            false,
+            [0 => ['value' => 'true', 'text' => 'Yes'], 1 => ['value' => 'false', 'text' => 'No']]
+        );
+
+        // Hide the logout button
+        //$_configuration['hide_logout_button'] = true;
+        $value = $this->getConfigurationValue('hide_logout_button');
+        $this->addSettingCurrent(
+            'hide_logout_button',
+            '',
+            'radio',
+            'Security',
+            ($value?$value:'false'),
+            'HideLogoutButtonTitle',
+            'HideLogoutButtonComment',
+            null,
+            '',
+            1,
+            true,
+            false,
+            [0 => ['value' => 'true', 'text' => 'Yes'], 1 => ['value' => 'false', 'text' => 'No']]
+        );
+
+        // Prevent redirecting admin to admin page
+        //$_configuration['redirect_admin_to_courses_list'] = true;
+        $value = $this->getConfigurationValue('redirect_admin_to_courses_list');
+        $this->addSettingCurrent(
+            'redirect_admin_to_courses_list',
+            '',
+            'radio',
+            'Platform',
+            ($value?$value:'false'),
+            'RedirectAdminToCoursesListTitle',
+            'RedirectAdminToCoursesListComment',
+            null,
+            '',
+            1,
+            true,
+            false,
+            [0 => ['value' => 'true', 'text' => 'Yes'], 1 => ['value' => 'false', 'text' => 'No']]
+        );
+
+        // Shows the custom course icon instead of the classic green board icon
+        //$_configuration['course_images_in_courses_list'] = false;
+        $value = $this->getConfigurationValue('course_images_in_courses_list');
+        $this->addSettingCurrent(
+            'course_images_in_courses_list',
+            '',
+            'radio',
+            'Course',
+            ($value?$value:'false'),
+            'CourseImagesInCoursesListTitle',
+            'CourseImagesInCoursesListComment',
+            null,
+            '',
+            1,
+            true,
+            false,
+            [0 => ['value' => 'true', 'text' => 'Yes'], 1 => ['value' => 'false', 'text' => 'No']]
+        );
+
+        // Which student publication will be taken when connected to the gradebook: first|last
+        //$_configuration['student_publication_to_take_in_gradebook'] = 'first';
+        $value = $this->getConfigurationValue('student_publication_to_take_in_gradebook');
+        $this->addSettingCurrent(
+            'student_publication_to_take_in_gradebook',
+            '',
+            'radio',
+            'Gradebook',
+            ($value?$value:'first'),
+            'StudentPublicationSelectionForGradebookTitle',
+            'StudentPublicationSelectionForGradebookComment',
+            null,
+            '',
+            1,
+            true,
+            false,
+            [0 => ['value' => 'first', 'text' => 'First'], 1 => ['value' => 'last', 'text' => 'Last']]
+        );
+
+        // Show a filter by official code
+        //$_configuration['certificate_filter_by_official_code'] = false;
+        $value = $this->getConfigurationValue('certificate_filter_by_official_code');
+        $this->addSettingCurrent(
+            'certificate_filter_by_official_code',
+            '',
+            'radio',
+            'Gradebook',
+            ($value?$value:'false'),
+            'FilterCertificateByOfficialCodeTitle',
+            'FilterCertificateByOfficialCodeComment',
+            null,
+            '',
+            1,
+            true,
+            false,
+            [0 => ['value' => 'true', 'text' => 'Yes'], 1 => ['value' => 'false', 'text' => 'No']]
+        );
+
+        // Max quantity of fkceditor allowed in the exercise result page otherwise
+        // Textareas are used.
+        //$_configuration['exercise_max_ckeditors_in_page'] = 0;
+        $value = $this->getConfigurationValue('exercise_max_ckeditors_in_page');
+        $this->addSettingCurrent(
+            'exercise_max_ckeditors_in_page',
+            '',
+            'textfield',
+            'Tools',
+            ($value?$value:'0'),
+            'MaxCKeditorsOnExerciseResultsPageTitle',
+            'MaxCKeditorsOnExerciseResultsPageComment',
+            null,
+            '',
+            1,
+            true,
+            false,
+            array()
+        );
+
+        // Default upload option
+        //$_configuration['document_if_file_exists_option'] = 'rename'; // overwrite
+        $value = $this->getConfigurationValue('document_if_file_exists_option');
+        $this->addSettingCurrent(
+            'document_if_file_exists_option',
+            '',
+            'radio',
+            'Tools',
+            ($value?$value:'rename'),
+            'DocumentDefaultOptionIfFileExistsTitle',
+            'DocumentDefaultOptionIfFileExistsComment',
+            null,
+            '',
+            1,
+            true,
+            false,
+            [0 => ['value' => 'rename', 'text' => 'Rename'], 1 => ['value' => 'overwrite', 'text' => 'Overwrite']]
+        );
+        // Enable add_gradebook_certificates.php cron task
+        //$_configuration['add_gradebook_certificates_cron_task_enabled'] = true;
+        $value = $this->getConfigurationValue('add_gradebook_certificates_cron_task_enabled');
+        $this->addSettingCurrent(
+            'add_gradebook_certificates_cron_task_enabled',
+            '',
+            'radio',
+            'Tools',
+            ($value?$value:'false'),
+            'GradebookCronTaskGenerationTitle',
+            'GradebookCronTaskGenerationComment',
+            null,
+            '',
+            1,
+            true,
+            false,
+            [0 => ['value' => 'true', 'text' => 'Yes'], 1 => ['value' => 'false', 'text' => 'No']]
+        );
+
+        // Which OpenBadges backpack send the badges
+        //$_configuration['openbadges_backpack'] = 'https://backpack.openbadges.org/';
+        $value = $this->getConfigurationValue('openbadges_backpack');
+        $this->addSettingCurrent(
+            'openbadges_backpack',
+            '',
+            'textfield',
+            'Gradebook',
+            ($value?$value:'https://backpack.openbadges.org/'),
+            'OpenBadgesBackpackUrlTitle',
+            'OpenBadgesBackpackUrlComment',
+            null,
+            '',
+            1,
+            true,
+            false,
+            []
+        );
+
+        // Shows a warning message explaining that the site uses cookies
+        //$_configuration['cookie_warning'] = false;
+        $value = $this->getConfigurationValue('cookie_warning');
+        $this->addSettingCurrent(
+            'cookie_warning',
+            '',
+            'radio',
+            'Tools',
+            ($value?$value:'false'),
+            'CookieWarningTitle',
+            'CookieWarningComment',
+            null,
+            '',
+            1,
+            true,
+            false,
+            [0 => ['value' => 'true', 'text' => 'Yes'], 1 => ['value' => 'false', 'text' => 'No']]
+        );
+
+        // If there are any tool available and the user is not registered hide the group
+        //$_configuration['hide_course_group_if_no_tools_available'] = false;
+        $value = $this->getConfigurationValue('hide_course_group_if_no_tools_available');
+        $this->addSettingCurrent(
+            'hide_course_group_if_no_tools_available',
+            '',
+            'radio',
+            'Tools',
+            ($value?$value:'false'),
+            'HideCourseGroupIfNoToolAvailableTitle',
+            'HideCourseGroupIfNoToolAvailableComment',
+            null,
+            '',
+            1,
+            true,
+            false,
+            [0 => ['value' => 'true', 'text' => 'Yes'], 1 => ['value' => 'false', 'text' => 'No']]
+        );
+
+        // Allow student to enroll into a session without an approval needing
+        //$_configuration['catalog_allow_session_auto_subscription'] = false;
+        $value = $this->getConfigurationValue('catalog_allow_session_auto_subscription');
+        $this->addSettingCurrent(
+            'catalog_allow_session_auto_subscription',
+            '',
+            'radio',
+            'Session',
+            ($value?$value:'false'),
+            'CatalogueAllowSessionAutoSubscriptionTitle',
+            'CatalogueAllowSessionAutoSubscriptionComment',
+            null,
+            '',
+            1,
+            true,
+            false,
+            [0 => ['value' => 'true', 'text' => 'Yes'], 1 => ['value' => 'false', 'text' => 'No']]
+        );
+
+        // Decode UTF-8 from Web Services (option passed to SOAP)
+        //$_configuration['registration.soap.php.decode_utf8'] = false;
+        $value = $this->getConfigurationValue('registration.soap.php.decode_utf8');
+        $this->addSettingCurrent(
+            'registration.soap.php.decode_utf8',
+            '',
+            'radio',
+            'Platform',
+            ($value?$value:'false'),
+            'SoapRegistrationDecodeUtf8Title',
+            'SoapRegistrationDecodeUtf8Comment',
+            null,
+            '',
+            1,
+            true,
+            false,
+            [0 => ['value' => 'true', 'text' => 'Yes'], 1 => ['value' => 'false', 'text' => 'No']]
+        );
+
+        // Show delete option in attendance
+        //$_configuration['allow_delete_attendance'] = false;
+        $value = $this->getConfigurationValue('allow_delete_attendance');
+        $this->addSettingCurrent(
+            'allow_delete_attendance',
+            '',
+            'radio',
+            'Tools',
+            ($value?$value:'false'),
+            'AttendanceDeletionEnableTitle',
+            'AttendanceDeletionEnableComment',
+            null,
+            '',
+            1,
+            true,
+            false,
+            [0 => ['value' => 'true', 'text' => 'Yes'], 1 => ['value' => 'false', 'text' => 'No']]
+        );
+
+        // Enable Gravatar profile image if no local image has been given
+        //$_configuration['gravatar_enabled'] = true;
+        $value = $this->getConfigurationValue('gravatar_enabled');
+        $this->addSettingCurrent(
+            'gravatar_enabled',
+            '',
+            'radio',
+            'Platform',
+            ($value?$value:'false'),
+            'GravatarPicturesTitle',
+            'GravatarPicturesComment',
+            null,
+            '',
+            1,
+            true,
+            false,
+            [0 => ['value' => 'true', 'text' => 'Yes'], 1 => ['value' => 'false', 'text' => 'No']]
+        );
+
+        // If Gravatar is enabled, tells which type of picture we want (default is "mm").
+        // Options: mm | identicon | monsterid | wavatar
+        //$_configuration['gravatar_type'] = 'mm';
+        $value = $this->getConfigurationValue('gravatar_type');
+        $this->addSettingCurrent(
+            'gravatar_type',
+            '',
+            'radio',
+            'Platform',
+            ($value?$value:'mm'),
+            'GravatarPicturesTypeTitle',
+            'GravatarPicturesTypeComment',
+            null,
+            '',
+            1,
+            true,
+            false,
+            [
+                0 => ['value' => 'mm', 'text' => 'mystery-man'],
+                1 => ['value' => 'identicon', 'text' => 'identicon'],
+                2 => ['value' => 'monsterid', 'text' => 'monsterid'],
+                3 => ['value' => 'wavatar', 'text' => 'wavatar']
+            ]
+        );
+
+        // Limit for the Session Admin role. The administration page show only
+        // User block -> Add user
+        // Course Sessions block -> Training session list
+        //$_configuration['limit_session_admin_role'] = false;
+        $value = $this->getConfigurationValue('limit_session_admin_role');
+        $this->addSettingCurrent(
+            'limit_session_admin_role',
+            '',
+            'radio',
+            'Session',
+            ($value?$value:'false'),
+            'SessionAdminPermissionsLimitTitle',
+            'SessionAdminPermissionsLimitComment',
+            null,
+            '',
+            1,
+            true,
+            false,
+            [0 => ['value' => 'true', 'text' => 'Yes'], 1 => ['value' => 'false', 'text' => 'No']]
+        );
+
+        // Show session description
+        //$_configuration['show_session_description'] = false;
+        $value = $this->getConfigurationValue('show_session_description');
+        $this->addSettingCurrent(
+            'show_session_description',
+            '',
+            'radio',
+            'Session',
+            ($value?$value:'false'),
+            'ShowSessionDescriptionTitle',
+            'ShowSessionDescriptionComment',
+            null,
+            '',
+            1,
+            true,
+            false,
+            [0 => ['value' => 'true', 'text' => 'Yes'], 1 => ['value' => 'false', 'text' => 'No']]
+        );
+
+        // Hide only for students the link to export certificates to PDF
+        //$_configuration['hide_certificate_export_link_students'] = false;
+        $value = $this->getConfigurationValue('hide_certificate_export_link_students');
+        $this->addSettingCurrent(
+            'hide_certificate_export_link_students',
+            '',
+            'radio',
+            'Gradebook',
+            ($value?$value:'false'),
+            'CertificateHideExportLinkStudentTitle',
+            'CertificateHideExportLinkStudentComment',
+            null,
+            '',
+            1,
+            true,
+            false,
+            [0 => ['value' => 'true', 'text' => 'Yes'], 1 => ['value' => 'false', 'text' => 'No']]
+        );
+
+        // Hide for all user roles the link to export certificates to PDF
+        //$_configuration['hide_certificate_export_link'] = false;
+        $value = $this->getConfigurationValue('hide_certificate_export_link');
+        $this->addSettingCurrent(
+            'hide_certificate_export_link',
+            '',
+            'radio',
+            'Gradebook',
+            ($value?$value:'false'),
+            'CertificateHideExportLinkTitle',
+            'CertificateHideExportLinkComment',
+            null,
+            '',
+            1,
+            true,
+            false,
+            [0 => ['value' => 'true', 'text' => 'Yes'], 1 => ['value' => 'false', 'text' => 'No']]
+        );
+
+        // Hide session course coach in dropbox sent to user list
+        //$_configuration['dropbox_hide_course_coach'] = false;
+        $value = $this->getConfigurationValue('dropbox_hide_course_coach');
+        $this->addSettingCurrent(
+            'dropbox_hide_course_coach',
+            '',
+            'radio',
+            'Tools',
+            ($value ? $value : 'false'),
+            'DropboxHideCourseCoachTitle',
+            'DropboxHideCourseCoachComment',
+            null,
+            '',
+            1,
+            true,
+            false,
+            [0 => ['value' => 'true', 'text' => 'Yes'], 1 => ['value' => 'false', 'text' => 'No']]
+        );
+
+        $value = $this->getConfigurationValue('dropbox_hide_general_coach');
+        $this->addSettingCurrent(
+            'dropbox_hide_general_coach',
+            '',
+            'radio',
+            'Tools',
+            ($value ? $value : 'false'),
+            'DropboxHideGeneralCoachTitle',
+            'DropboxHideGeneralCoachComment',
+            null,
+            '',
+            1,
+            true,
+            false,
+            [0 => ['value' => 'true', 'text' => 'Yes'], 1 => ['value' => 'false', 'text' => 'No']]
+        );
+
+        // If SSO is used, the redirection to the master server is forced.
+        //$_configuration['force_sso_redirect'] = false;
+        $value = $this->getConfigurationValue('force_sso_redirect');
+        $this->addSettingCurrent(
+            'sso_force_redirect',
+            '',
+            'radio',
+            'Security',
+            ($value?$value:'false'),
+            'SSOForceRedirectTitle',
+            'SSOForceRedirectComment',
+            null,
+            '',
+            1,
+            true,
+            false,
+            [0 => ['value' => 'true', 'text' => 'Yes'], 1 => ['value' => 'false', 'text' => 'No']]
+        );
+
+        // Session course ordering in the the session view.
+        // false = alphabetic order (default)
+        // true = based in the session course list
+        //$_configuration['session_course_ordering'] = false;
+        $value = $this->getConfigurationValue('session_course_ordering');
+        $this->addSettingCurrent(
+            'session_course_ordering',
+            '',
+            'radio',
+            'Session',
+            ($value?$value:'false'),
+            'SessionCourseOrderingTitle',
+            'SessionCourseOrderingComment',
+            null,
+            '',
+            1,
+            true,
+            false,
+            [0 => ['value' => 'true', 'text' => 'Yes'], 1 => ['value' => 'false', 'text' => 'No']]
+        );
+    }
+
+    /**
+     * @param Schema $schema
+     */
+    public function down(Schema $schema)
+    {
+        $this->addSql("DELETE FROM settings_options WHERE variable IN ('session_course_ordering', 'sso_force_redirect', 'dropbox_hide_course_coach', 'hide_certificate_export_link', 'hide_certificate_export_link_students', 'show_session_description', 'limit_session_admin_role', 'gravatar_type', 'gravatar_enabled', 'allow_delete_attendance', 'registration.soap.php.decode_utf8', 'catalog_allow_session_auto_subscription', 'hide_course_group_if_no_tools_available', 'cookie_warning', 'openbadges_backpack', 'add_gradebook_certificates_cron_task_enabled', 'document_if_file_exists_option', 'exercise_max_ckeditors_in_page', 'certificate_filter_by_official_code', 'student_publication_to_take_in_gradebook', 'course_images_in_courses_list', 'redirect_admin_to_courses_list', 'hide_logout_button', 'allow_session_course_copy_for_teachers', 'lp_show_reduced_report', 'auto_detect_language_custom_pages', 'catalog_show_courses_sessions', 'course_catalog_hide_private', 'show_official_code_exercise_result_list', 'allow_lp_return_link', 'hide_scorm_export_link', 'hide_scorm_copy_link', 'hide_scorm_pdf_link', 'session_days_before_coach_access', 'session_days_after_coach_access', 'pdf_logo_header', 'order_user_list_by_official_code', 'email_alert_manager_on_new_quiz')");
+        $this->addSql("DELETE FROM settings_current WHERE variable IN ('session_course_ordering', 'sso_force_redirect', 'dropbox_hide_course_coach', 'hide_certificate_export_link', 'hide_certificate_export_link_students', 'show_session_description', 'limit_session_admin_role', 'gravatar_type', 'gravatar_enabled', 'allow_delete_attendance', 'registration.soap.php.decode_utf8', 'catalog_allow_session_auto_subscription', 'hide_course_group_if_no_tools_available', 'cookie_warning', 'openbadges_backpack', 'add_gradebook_certificates_cron_task_enabled', 'document_if_file_exists_option', 'exercise_max_ckeditors_in_page', 'certificate_filter_by_official_code', 'student_publication_to_take_in_gradebook', 'course_images_in_courses_list', 'redirect_admin_to_courses_list', 'hide_logout_button', 'allow_session_course_copy_for_teachers', 'lp_show_reduced_report', 'auto_detect_language_custom_pages', 'catalog_show_courses_sessions', 'course_catalog_hide_private', 'show_official_code_exercise_result_list', 'allow_lp_return_link', 'hide_scorm_export_link', 'hide_scorm_copy_link', 'hide_scorm_pdf_link', 'session_days_before_coach_access', 'session_days_after_coach_access', 'pdf_logo_header', 'order_user_list_by_official_code', 'email_alert_manager_on_new_quiz')");
+
+        $this->addSql('ALTER TABLE user DROP COLUMN last_login');
+    }
+}

+ 55 - 0
app/Migrations/Schema/V110/Version20150527101600.php

@@ -0,0 +1,55 @@
+<?php
+/* For licensing terms, see /license.txt */
+
+namespace Application\Migrations\Schema\V110;
+
+use Application\Migrations\AbstractMigrationChamilo;
+use Doctrine\DBAL\Schema\Schema;
+
+/**
+ * Class Version20150527120703
+ * LP autolunch -> autolaunch
+ * @package Application\Migrations\Schema\V11010
+ */
+class Version20150527101600 extends AbstractMigrationChamilo
+{
+    /**
+     * @param Schema $schema
+     */
+    public function up(Schema $schema)
+    {
+        $this->addSettingCurrent(
+            'gamification_mode',
+            '',
+            'radio',
+            'Platform',
+            0,
+            'GamificationModeTitle',
+            'GamificationModeComment',
+            null,
+            '',
+            1,
+            true,
+            false,
+            [
+                [
+                    'value' => 1,
+                    'text' => 'Yes'
+                ],
+                [
+                    'value' => 0,
+                    'text' => 'No'
+                ]
+            ]
+        );
+    }
+
+    /**
+     * @param Schema $schema
+     */
+    public function down(Schema $schema)
+    {
+        $this->addSql("DELETE FROM settings_options WHERE variable = 'gamification_mode'");
+        $this->addSql("DELETE FROM settings_current WHERE variable = 'gamification_mode'");
+    }
+}

+ 33 - 0
app/Migrations/Schema/V110/Version20150527114220.php

@@ -0,0 +1,33 @@
+<?php
+/* For licensing terms, see /license.txt */
+
+namespace Application\Migrations\Schema\V110;
+
+use Application\Migrations\AbstractMigrationChamilo;
+use Doctrine\DBAL\Schema\Schema;
+
+/**
+ * Class Version20150527114220
+ * Lp category
+ * @package Application\Migrations\Schema\V11010
+ */
+class Version20150527114220 extends AbstractMigrationChamilo
+{
+    /**
+     * @param Schema $schema
+     */
+    public function up(Schema $schema)
+    {
+        $this->addSql('CREATE TABLE c_lp_category (iid INT AUTO_INCREMENT NOT NULL, c_id INT NOT NULL, name VARCHAR(255) NOT NULL, position INT NOT NULL, PRIMARY KEY(iid)) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE = InnoDB');
+        $this->addSql('ALTER TABLE c_lp ADD category_id INT NOT NULL DEFAULT 0');
+    }
+
+    /**
+     * @param Schema $schema
+     */
+    public function down(Schema $schema)
+    {
+        $this->addSql('DROP TABLE c_lp_category');
+        $this->addSql('ALTER TABLE c_lp DROP category_id');
+    }
+}

+ 31 - 0
app/Migrations/Schema/V110/Version20150527120703.php

@@ -0,0 +1,31 @@
+<?php
+/* For licensing terms, see /license.txt */
+
+namespace Application\Migrations\Schema\V110;
+
+use Application\Migrations\AbstractMigrationChamilo;
+use Doctrine\DBAL\Schema\Schema;
+
+/**
+ * Class Version20150527120703
+ * LP autolunch -> autolaunch
+ * @package Application\Migrations\Schema\V11010
+ */
+class Version20150527120703 extends AbstractMigrationChamilo
+{
+    /**
+     * @param Schema $schema
+     */
+    public function up(Schema $schema)
+    {
+        $this->addSql('ALTER TABLE c_lp CHANGE COLUMN autolunch autolaunch INT NOT NULL DEFAULT 0');
+    }
+
+    /**
+     * @param Schema $schema
+     */
+    public function down(Schema $schema)
+    {
+        $this->addSql('ALTER TABLE c_lp CHANGE COLUMN autolaunch autolunch INT NOT NULL');
+    }
+}

+ 76 - 0
app/Migrations/Schema/V110/Version20150528103216.php

@@ -0,0 +1,76 @@
+<?php
+/* For licensing terms, see /license.txt */
+
+namespace Application\Migrations\Schema\V110;
+
+use Application\Migrations\AbstractMigrationChamilo;
+use Doctrine\DBAL\Schema\Schema;
+
+/**
+ * Session date changes
+ */
+class Version20150528103216 extends AbstractMigrationChamilo
+{
+    /**
+     * @param Schema $schema
+     */
+    public function up(Schema $schema)
+    {
+  	    $this->addSql('ALTER TABLE session ADD COLUMN access_start_date datetime');
+        $this->addSql('ALTER TABLE session ADD COLUMN access_end_date datetime');
+        $this->addSql('ALTER TABLE session ADD COLUMN coach_access_start_date datetime');
+        $this->addSql('ALTER TABLE session ADD COLUMN coach_access_end_date datetime');
+        $this->addSql('ALTER TABLE session ADD COLUMN display_start_date datetime');
+        $this->addSql('ALTER TABLE session ADD COLUMN display_end_date datetime');
+
+
+        $this->addSql('UPDATE session SET access_start_date = date_start');
+        $this->addSql("UPDATE session SET access_end_date = CONVERT(CONCAT(date_end, ' 23:59:59'), DATETIME)");
+
+        $this->addSql('UPDATE session SET coach_access_start_date = CONVERT(DATE_SUB(date_start, INTERVAL nb_days_access_before_beginning DAY), DATETIME) ');
+        $this->addSql('UPDATE session SET coach_access_start_date = NULL WHERE nb_days_access_before_beginning = 0');
+
+        $this->addSql('UPDATE session SET coach_access_end_date = CONVERT(DATE_ADD(date_end, INTERVAL nb_days_access_after_end DAY), DATETIME) ');
+        $this->addSql('UPDATE session SET coach_access_end_date = NULL WHERE nb_days_access_after_end = 0');
+
+        $this->addSql('UPDATE session SET display_start_date = access_start_date');
+        $this->addSql('UPDATE session SET display_end_date = access_end_date');
+
+        // Set dates to NULL
+
+        $this->addSql('UPDATE session SET access_start_date = NULL WHERE access_start_date = "0000-00-00 00:00:00"');
+        $this->addSql('UPDATE session SET access_end_date = NULL WHERE access_end_date = "0000-00-00 00:00:00"');
+
+        $this->addSql('UPDATE session SET coach_access_start_date = NULL WHERE coach_access_start_date = "0000-00-00 00:00:00"');
+        $this->addSql('UPDATE session SET coach_access_end_date = NULL WHERE coach_access_end_date = "0000-00-00 00:00:00"');
+
+        $this->addSql('UPDATE session SET display_start_date = NULL WHERE display_start_date = "0000-00-00 00:00:00"');
+        $this->addSql('UPDATE session SET display_end_date = NULL WHERE display_end_date = "0000-00-00 00:00:00"');
+    }
+
+    /**
+     * @param Schema $schema
+     */
+    public function down(Schema $schema)
+    {
+        $this->addSql('ALTER TABLE session CREATE date_start date NOT NULL');
+        $this->addSql('ALTER TABLE session CREATE date_end date NOT NULL');
+        $this->addSql('ALTER TABLE session CREATE nb_days_access_before_beginning TINYINT');
+        $this->addSql('ALTER TABLE session CREATE nb_days_access_after_end TINYINT');
+
+        $this->addSql('UPDATE session SET date_start = access_start_date');
+        $this->addSql('UPDATE session SET date_end = access_end_date');
+
+        $this->addSql('UPDATE session SET nb_days_access_before_beginning = DATEDIFF(access_start_date, coach_access_start_date) WHERE access_start_date != coach_access_start_date AND coach_access_start_date IS NOT NULL');
+        $this->addSql('UPDATE session SET nb_days_access_after_end = DATEDIFF(coach_access_end_date, coach_access_end_date) WHERE access_end_date != coach_access_end_date AND coach_access_end_date IS NOT NULL');
+        $this->addSql('UPDATE session SET nb_days_access_before_beginning = 0 WHERE access_start_date = coach_access_start_date OR coach_access_start_date IS NULL');
+        $this->addSql('UPDATE session SET nb_days_access_after_end = 0 WHERE access_end_date = coach_access_end_date OR coach_access_end_date IS NULL');
+
+        $this->addSql('ALTER TABLE session DROP access_start_date');
+        $this->addSql('ALTER TABLE session DROP access_end_date');
+        $this->addSql('ALTER TABLE session DROP coach_access_start_date');
+        $this->addSql('ALTER TABLE session DROP coach_access_end_date');
+        $this->addSql('ALTER TABLE session DROP display_start_date');
+        $this->addSql('ALTER TABLE session DROP display_end_date');
+    }
+}

+ 67 - 0
app/Migrations/Schema/V110/Version20150529164400.php

@@ -0,0 +1,67 @@
+<?php
+/* For licensing terms, see /license.txt */
+
+namespace Application\Migrations\Schema\V110;
+
+use Application\Migrations\AbstractMigrationChamilo;
+use Doctrine\DBAL\Schema\Schema;
+use Doctrine\DBAL\Types\Type as TableColumnType;
+
+/**
+ * Session date changes
+ */
+class Version20150529164400 extends AbstractMigrationChamilo
+{
+    /**
+     * @param Schema $schema
+     */
+    public function up(Schema $schema)
+    {
+        if (!$schema->hasTable('gradebook_score_log')) {
+            $gradebookScoreLog = $schema->createTable('gradebook_score_log');
+            $gradebookScoreLog->addColumn(
+                'id',
+                TableColumnType::INTEGER,
+                ['unsigned' => true, 'autoincrement' => true, 'notnull' => true]
+            );
+            $gradebookScoreLog->addColumn(
+                'category_id',
+                TableColumnType::INTEGER,
+                ['unsigned' => true, 'notnull' => true]
+            );
+            $gradebookScoreLog->addColumn(
+                'user_id',
+                TableColumnType::INTEGER,
+                ['unsigned' => true, 'notnull' => true]
+            );
+            $gradebookScoreLog->addColumn(
+                'score',
+                TableColumnType::FLOAT,
+                ['notnull' => true, 'scale' => 0, 'precision' => 10]
+            );
+            $gradebookScoreLog->addColumn(
+                'registered_at',
+                TableColumnType::DATETIME,
+                ['notnull' => true]
+            );
+            $gradebookScoreLog->setPrimaryKey(['id']);
+            $gradebookScoreLog->addIndex(
+                ['user_id'],
+                'idx_gradebook_score_log_user'
+            );
+            $gradebookScoreLog->addIndex(
+                ['user_id', 'category_id'],
+                'idx_gradebook_score_log_user_category'
+            );
+        }
+    }
+
+    /**
+     * @param Schema $schema
+     */
+    public function down(Schema $schema)
+    {
+        $schema->dropTable('gradebook_score_log');
+    }
+
+}

+ 70 - 0
app/Migrations/Schema/V110/Version20150603142550.php

@@ -0,0 +1,70 @@
+<?php
+/* For licensing terms, see /license.txt */
+
+namespace Application\Migrations\Schema\V110;
+
+use Application\Migrations\AbstractMigrationChamilo;
+use Doctrine\DBAL\Schema\Schema;
+
+/**
+ * Add branch
+ */
+class Version20150603142550 extends AbstractMigrationChamilo
+{
+    /**
+     * @param Schema $schema
+     */
+    public function preUp(Schema $schema)
+    {
+        $this->addSql("ALTER TABLE c_calendar_event ENGINE=InnoDB");
+        $this->addSql("ALTER TABLE c_thematic_advance ENGINE=InnoDB");
+    }
+
+    /**
+     * @param Schema $schema
+     */
+    public function up(Schema $schema)
+    {
+        $this->addSql('CREATE TABLE room (id INT AUTO_INCREMENT NOT NULL, branch_id INT DEFAULT NULL, title VARCHAR(255) DEFAULT NULL, description LONGTEXT, geolocation VARCHAR(255) DEFAULT NULL, ip VARCHAR(39) DEFAULT NULL, ip_mask VARCHAR(6) DEFAULT NULL, INDEX IDX_729F519BDCD6CC49 (branch_id), PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE = InnoDB');
+        $this->addSql('CREATE TABLE branch_transaction_status (id INT AUTO_INCREMENT NOT NULL, title VARCHAR(255) DEFAULT NULL, PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE = InnoDB');
+        $this->addSql('CREATE TABLE branch_transaction (id BIGINT AUTO_INCREMENT NOT NULL, status_id INT DEFAULT NULL, branch_id INT DEFAULT NULL, transaction_id BIGINT NOT NULL, action VARCHAR(20) DEFAULT NULL, item_id VARCHAR(255) DEFAULT NULL, origin VARCHAR(255) DEFAULT NULL, dest_id VARCHAR(255) DEFAULT NULL, external_info VARCHAR(255) DEFAULT NULL, time_insert DATETIME NOT NULL, time_update DATETIME NOT NULL, failed_attempts INT NOT NULL, INDEX IDX_FEFBA12B6BF700BD (status_id), INDEX IDX_FEFBA12BDCD6CC49 (branch_id), PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE = InnoDB');
+        $this->addSql('CREATE TABLE branch_sync (id INT AUTO_INCREMENT NOT NULL, parent_id INT DEFAULT NULL, access_url_id INT NOT NULL, unique_id VARCHAR(50) NOT NULL, branch_name VARCHAR(250) NOT NULL, description LONGTEXT, branch_ip VARCHAR(40) DEFAULT NULL, latitude NUMERIC(10, 0) DEFAULT NULL, longitude NUMERIC(10, 0) DEFAULT NULL, dwn_speed INT DEFAULT NULL, up_speed INT DEFAULT NULL, delay INT DEFAULT NULL, admin_mail VARCHAR(250) DEFAULT NULL, admin_name VARCHAR(250) DEFAULT NULL, admin_phone VARCHAR(250) DEFAULT NULL, last_sync_trans_id BIGINT DEFAULT NULL, last_sync_trans_date DATETIME DEFAULT NULL, last_sync_type VARCHAR(20) DEFAULT NULL, ssl_pub_key VARCHAR(250) DEFAULT NULL, branch_type VARCHAR(250) DEFAULT NULL, lft INT DEFAULT NULL, rgt INT DEFAULT NULL, lvl INT DEFAULT NULL, root INT DEFAULT NULL, UNIQUE INDEX UNIQ_F62F45EDE3C68343 (unique_id), INDEX IDX_F62F45ED727ACA70 (parent_id), PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE = InnoDB');
+        $this->addSql('ALTER TABLE room ADD CONSTRAINT FK_729F519BDCD6CC49 FOREIGN KEY (branch_id) REFERENCES branch_sync (id)');
+        $this->addSql('ALTER TABLE branch_transaction ADD CONSTRAINT FK_FEFBA12B6BF700BD FOREIGN KEY (status_id) REFERENCES branch_transaction_status (id)');
+        $this->addSql('ALTER TABLE branch_transaction ADD CONSTRAINT FK_FEFBA12BDCD6CC49 FOREIGN KEY (branch_id) REFERENCES branch_sync (id)');
+        $this->addSql('ALTER TABLE branch_sync ADD CONSTRAINT FK_F62F45ED727ACA70 FOREIGN KEY (parent_id) REFERENCES branch_sync (id) ON DELETE SET NULL');
+        $this->addSql('ALTER TABLE course ADD room_id INT DEFAULT NULL');
+        $this->addSql('ALTER TABLE course ADD CONSTRAINT FK_169E6FB954177093 FOREIGN KEY (room_id) REFERENCES room (id)');
+        $this->addSql('CREATE INDEX IDX_169E6FB954177093 ON course (room_id)');
+        $this->addSql('ALTER TABLE c_calendar_event ADD room_id INT DEFAULT NULL');
+        $this->addSql('ALTER TABLE c_calendar_event ADD CONSTRAINT FK_A062258154177093 FOREIGN KEY (room_id) REFERENCES room (id)');
+        $this->addSql('CREATE INDEX IDX_A062258154177093 ON c_calendar_event (room_id)');
+        $this->addSql('ALTER TABLE c_thematic_advance ADD room_id INT DEFAULT NULL');
+        $this->addSql('ALTER TABLE c_thematic_advance ADD CONSTRAINT FK_62798E9754177093 FOREIGN KEY (room_id) REFERENCES room (id)');
+        $this->addSql('CREATE INDEX IDX_62798E9754177093 ON c_thematic_advance (room_id)');
+    }
+
+    /**
+     * @param Schema $schema
+     */
+    public function down(Schema $schema)
+    {
+        $this->addSql('ALTER TABLE course DROP FOREIGN KEY FK_169E6FB954177093');
+        $this->addSql('ALTER TABLE c_calendar_event DROP FOREIGN KEY FK_A062258154177093');
+        $this->addSql('ALTER TABLE c_thematic_advance DROP FOREIGN KEY FK_62798E9754177093');
+        $this->addSql('ALTER TABLE branch_transaction DROP FOREIGN KEY FK_FEFBA12B6BF700BD');
+        $this->addSql('ALTER TABLE room DROP FOREIGN KEY FK_729F519BDCD6CC49');
+        $this->addSql('ALTER TABLE branch_transaction DROP FOREIGN KEY FK_FEFBA12BDCD6CC49');
+        $this->addSql('ALTER TABLE branch_sync DROP FOREIGN KEY FK_F62F45ED727ACA70');
+        $this->addSql('DROP TABLE room');
+        $this->addSql('DROP TABLE branch_transaction_status');
+        $this->addSql('DROP TABLE branch_transaction');
+        $this->addSql('DROP TABLE branch_sync');
+        $this->addSql('DROP INDEX IDX_A062258154177093 ON c_calendar_event');
+        $this->addSql('ALTER TABLE c_calendar_event DROP room_id');
+        $this->addSql('DROP INDEX IDX_62798E9754177093 ON c_thematic_advance');
+        $this->addSql('ALTER TABLE c_thematic_advance DROP room_id');
+        $this->addSql('DROP INDEX IDX_169E6FB954177093 ON course');
+        $this->addSql('ALTER TABLE course DROP room_id');
+    }
+}

+ 32 - 0
app/Migrations/Schema/V110/Version20150603151200.php

@@ -0,0 +1,32 @@
+<?php
+/* For licensing terms, see /license.txt */
+
+namespace Application\Migrations\Schema\V110;
+
+use Application\Migrations\AbstractMigrationChamilo;
+use Doctrine\DBAL\Schema\Schema;
+
+/**
+ * Session date changes
+ */
+class Version20150603151200 extends AbstractMigrationChamilo
+{
+    /**
+     * @param Schema $schema
+     */
+    public function up(Schema $schema)
+    {
+        $this->addSql('ALTER TABLE c_forum_forum ADD lp_id INTEGER UNSIGNED NOT NULL');
+        $this->addSql('ALTER TABLE c_forum_thread ADD lp_item_id INTEGER UNSIGNED NOT NULL');
+    }
+
+    /**
+     * @param Schema $schema
+     */
+    public function down(Schema $schema)
+    {
+        $this->addSql('ALTER TABLE c_forum_forum DROP lp_id');
+        $this->addSql('ALTER TABLE c_forum_thread DROP lp_item_id');
+    }
+
+}

+ 101 - 0
app/Migrations/Schema/V110/Version20150603181728.php

@@ -0,0 +1,101 @@
+<?php
+/* For licensing terms, see /license.txt */
+
+namespace Application\Migrations\Schema\V110;
+
+use Application\Migrations\AbstractMigrationChamilo;
+use Doctrine\DBAL\Schema\Schema;
+
+/**
+ * Lp changes
+ */
+class Version20150603181728 extends AbstractMigrationChamilo
+{
+    /**
+     * @param Schema $schema
+     */
+    public function preUp(Schema $schema)
+    {
+        $this->addSql("ALTER TABLE course ENGINE=InnoDB");
+        $this->addSql("ALTER TABLE c_group_info ENGINE=InnoDB");
+        $this->addSql("ALTER TABLE session ENGINE=InnoDB");
+        $this->addSql("ALTER TABLE user ENGINE=InnoDB");
+        $this->addSql("ALTER TABLE c_item_property ENGINE=InnoDB");
+    }
+
+    /**
+     * @param Schema $schema
+     */
+    public function up(Schema $schema)
+    {
+        $table = $schema->getTable('c_lp');
+        if (!$table->hasColumn('max_attempts')) {
+            $this->addSql('ALTER TABLE c_lp ADD max_attempts INT NOT NULL');
+
+        }
+
+        if (!$table->hasColumn('subscribe_users')) {
+            $this->addSql('ALTER TABLE c_lp ADD subscribe_users INT NOT NULL DEFAULT 0');
+        }
+
+        $this->addSql('
+            ALTER TABLE c_item_property
+            MODIFY c_id INT DEFAULT NULL,
+            MODIFY lastedit_user_id INT NOT NULL,
+            MODIFY to_group_id INT NULL,
+            MODIFY insert_user_id INT DEFAULT NULL,
+            MODIFY start_visible DATETIME DEFAULT NULL,
+            MODIFY end_visible DATETIME DEFAULT NULL,
+            MODIFY session_id INT DEFAULT NULL,
+            MODIFY to_user_id INT NULL
+        ');
+        $this->addSql("UPDATE c_item_property SET session_id = NULL WHERE session_id NOT IN (SELECT id FROM session)");
+        $this->addSql("UPDATE c_item_property SET to_group_id = NULL WHERE to_group_id NOT IN (SELECT iid FROM c_group_info)");
+        $this->addSql("UPDATE c_item_property SET to_user_id = NULL WHERE to_user_id NOT IN (SELECT user_id FROM user)");
+        $this->addSql("UPDATE c_item_property SET start_visible = NULL WHERE start_visible = '0000-00-00 00:00:00'");
+        $this->addSql("UPDATE c_item_property SET end_visible = NULL WHERE end_visible = '0000-00-00 00:00:00'");
+        $this->addSql("UPDATE c_item_property SET to_user_id = NULL WHERE to_user_id NOT IN (SELECT id FROM user)");
+        $this->addSql("UPDATE c_item_property SET insert_user_id = NULL WHERE insert_user_id NOT IN (SELECT id FROM user)");
+        $this->addSql("UPDATE c_item_property SET session_id = NULL WHERE session_id NOT IN (SELECT id FROM session)");
+
+        // Remove inconsistencies about non-existing courses
+        $this->addSql("DELETE FROM c_item_property WHERE c_id NOT IN (SELECT user_id FROM user)");
+        // Remove inconsistencies about non-existing users
+        $this->addSql("DELETE FROM course_rel_user WHERE user_id NOT IN (SELECT user_id FROM user)");
+
+        $this->addSql("DELETE FROM c_item_property WHERE c_id NOT IN (SELECT id FROM course)");
+        $this->addSql("DELETE FROM c_item_property WHERE to_group_id NOT IN (SELECT id FROM c_group_info)");
+
+        $this->addSql('UPDATE c_item_property cip SET cip.to_group_id = (SELECT cgi.iid FROM c_group_info cgi WHERE cgi.c_id = cip.c_id AND cgi.id = cip.to_group_id)');
+
+        $this->addSql('ALTER TABLE c_item_property ADD CONSTRAINT FK_1D84C18191D79BD3 FOREIGN KEY (c_id) REFERENCES course(id)');
+        $this->addSql('ALTER TABLE c_item_property ADD CONSTRAINT FK_1D84C181330D47E9 FOREIGN KEY (to_group_id) REFERENCES c_group_info (iid)');
+        $this->addSql('ALTER TABLE c_item_property ADD CONSTRAINT FK_1D84C18129F6EE60 FOREIGN KEY (to_user_id) REFERENCES user (id)');
+        $this->addSql('ALTER TABLE c_item_property ADD CONSTRAINT FK_1D84C1819C859CC3 FOREIGN KEY (insert_user_id) REFERENCES user (id)');
+        $this->addSql('ALTER TABLE c_item_property ADD CONSTRAINT FK_1D84C181613FECDF FOREIGN KEY (session_id) REFERENCES session (id)');
+        $this->addSql('CREATE INDEX IDX_1D84C18191D79BD3 ON c_item_property (c_id)');
+        $this->addSql('CREATE INDEX IDX_1D84C181330D47E9 ON c_item_property (to_group_id)');
+        $this->addSql('CREATE INDEX IDX_1D84C18129F6EE60 ON c_item_property (to_user_id)');
+        $this->addSql('CREATE INDEX IDX_1D84C1819C859CC3 ON c_item_property (insert_user_id)');
+        $this->addSql('CREATE INDEX IDX_1D84C181613FECDF ON c_item_property (session_id)');
+    }
+
+    /**
+     * @param Schema $schema
+     */
+    public function down(Schema $schema)
+    {
+        $this->addSql('ALTER TABLE c_lp DROP max_attempts, DROP subscribe_users');
+        $this->addSql('ALTER TABLE c_item_property DROP FOREIGN KEY FK_1D84C18191D79BD3');
+        $this->addSql('ALTER TABLE c_item_property DROP FOREIGN KEY FK_1D84C181330D47E9');
+        $this->addSql('ALTER TABLE c_item_property DROP FOREIGN KEY FK_1D84C18129F6EE60');
+        $this->addSql('ALTER TABLE c_item_property DROP FOREIGN KEY FK_1D84C1819C859CC3');
+        $this->addSql('ALTER TABLE c_item_property DROP FOREIGN KEY FK_1D84C181613FECDF');
+        $this->addSql('DROP INDEX IDX_1D84C18191D79BD3 ON c_item_property');
+        $this->addSql('DROP INDEX IDX_1D84C181330D47E9 ON c_item_property');
+        $this->addSql('DROP INDEX IDX_1D84C18129F6EE60 ON c_item_property');
+        $this->addSql('DROP INDEX IDX_1D84C1819C859CC3 ON c_item_property');
+        $this->addSql('DROP INDEX IDX_1D84C181613FECDF ON c_item_property');
+        $this->addSql('ALTER TABLE c_item_property CHANGE c_id c_id INT NOT NULL, CHANGE insert_user_id insert_user_id INT NOT NULL, CHANGE session_id session_id INT NOT NULL, CHANGE start_visible start_visible DATETIME NOT NULL, CHANGE end_visible end_visible DATETIME NOT NULL');
+    }
+}

+ 29 - 0
app/Migrations/Schema/V110/Version20150604145047.php

@@ -0,0 +1,29 @@
+<?php
+/* For licensing terms, see /license.txt */
+
+namespace Application\Migrations\Schema\V110;
+
+use Application\Migrations\AbstractMigrationChamilo;
+use Doctrine\DBAL\Schema\Schema;
+
+/**
+ * track_e_default changes
+ */
+class Version20150604145047 extends AbstractMigrationChamilo
+{
+    /**
+     * @param Schema $schema
+     */
+    public function up(Schema $schema)
+    {
+        $this->addSql('ALTER TABLE track_e_default CHANGE default_event_type default_event_type VARCHAR(255) NOT NULL, CHANGE default_value_type default_value_type VARCHAR(255) NOT NULL');
+    }
+
+    /**
+     * @param Schema $schema
+     */
+    public function down(Schema $schema)
+    {
+        $this->addSql('ALTER TABLE track_e_default CHANGE default_event_type default_event_type VARCHAR(20) NOT NULL COLLATE utf8_unicode_ci, CHANGE default_value_type default_value_type VARCHAR(20) NOT NULL COLLATE utf8_unicode_ci');
+    }
+}

+ 70 - 0
app/Migrations/Schema/V110/Version20150608104600.php

@@ -0,0 +1,70 @@
+<?php
+/* For licensing terms, see /license.txt */
+
+namespace Application\Migrations\Schema\V110;
+
+use Application\Migrations\AbstractMigrationChamilo;
+use Doctrine\DBAL\Schema\Schema;
+use Doctrine\DBAL\Types\Type as TableColumnType;
+
+/**
+ * Session date changes
+ */
+class Version20150608104600 extends AbstractMigrationChamilo
+{
+    /**
+     * @param Schema $schema
+     */
+    public function up(Schema $schema)
+    {
+        if (!$schema->hasTable('extra_field_rel_tag')) {
+            $extraFieldRelTag = $schema->createTable('extra_field_rel_tag');
+            $extraFieldRelTag->addColumn(
+                'id',
+                TableColumnType::INTEGER,
+                ['unsigned' => true, 'autoincrement' => true, 'notnull' => true]
+            );
+            $extraFieldRelTag->addColumn(
+                'field_id',
+                TableColumnType::INTEGER,
+                ['unsigned' => true, 'notnull' => true]
+            );
+            $extraFieldRelTag->addColumn(
+                'item_id',
+                TableColumnType::INTEGER,
+                ['unsigned' => true, 'notnull' => true]
+            );
+            $extraFieldRelTag->addColumn(
+                'tag_id',
+                TableColumnType::INTEGER,
+                ['unsigned' => true, 'notnull' => true]
+            );
+            $extraFieldRelTag->setPrimaryKey(['id']);
+            $extraFieldRelTag->addIndex(
+                ['field_id'],
+                'idx_frt_field'
+            );
+            $extraFieldRelTag->addIndex(
+                ['item_id'],
+                'idx_frt_item'
+            );
+            $extraFieldRelTag->addIndex(
+                ['tag_id'],
+                'idx_frt_tag'
+            );
+            $extraFieldRelTag->addIndex(
+                ['field_id', 'item_id', 'tag_id'],
+                'idx_frt_field_item_tag'
+            );
+        }
+    }
+
+    /**
+     * @param Schema $schema
+     */
+    public function down(Schema $schema)
+    {
+        $schema->dropTable('extra_field_rel_tag');
+    }
+
+}

+ 35 - 0
app/Migrations/Schema/V110/Version20150609113500.php

@@ -0,0 +1,35 @@
+<?php
+/* For licensing terms, see /license.txt */
+
+namespace Application\Migrations\Schema\V110;
+
+use Application\Migrations\AbstractMigrationChamilo;
+use Doctrine\DBAL\Schema\Schema;
+
+/**
+ * Session date changes
+ */
+class Version20150609113500 extends AbstractMigrationChamilo
+{
+    /**
+     * @param Schema $schema
+     */
+    public function up(Schema $schema)
+    {
+        $this->addSql("INSERT INTO extra_field
+            (extra_field_type, field_type, variable, display_text, visible, changeable, created_at)
+            VALUES (2, 10, 'tags', 'Tags', 1, 1, NOW())");
+    }
+
+    /**
+     * @param Schema $schema
+     */
+    public function down(Schema $schema)
+    {
+        $this->addSql("DELETE FROM extra_field
+            WHERE variable = 'tags' AND
+                extra_field_type = 2 AND
+                field_type = 10");
+    }
+
+}

+ 29 - 0
app/Migrations/Schema/V110/Version20150610143426.php

@@ -0,0 +1,29 @@
+<?php
+/* For licensing terms, see /license.txt */
+
+namespace Application\Migrations\Schema\V110;
+
+use Application\Migrations\AbstractMigrationChamilo;
+use Doctrine\DBAL\Schema\Schema;
+
+/**
+ * Tool changes
+ */
+class Version20150610143426 extends AbstractMigrationChamilo
+{
+    /**
+     * @param Schema $schema
+     */
+    public function up(Schema $schema)
+    {
+        $this->addSql('ALTER TABLE c_tool ADD description LONGTEXT, ADD custom_icon VARCHAR(255) DEFAULT NULL');
+    }
+
+    /**
+     * @param Schema $schema
+     */
+    public function down(Schema $schema)
+    {
+        $this->addSql('ALTER TABLE c_tool DROP description, DROP custom_icon');
+    }
+}

+ 34 - 0
app/Migrations/Schema/V110/Version20150615171900.php

@@ -0,0 +1,34 @@
+<?php
+/* For licensing terms, see /license.txt */
+
+namespace Application\Migrations\Schema\V110;
+
+use Application\Migrations\AbstractMigrationChamilo;
+use Doctrine\DBAL\Schema\Schema;
+
+/**
+ * Version20150615171900 class
+ * Change in CCourseDescription entity
+ *
+ * @author Angel Fernando Quiroz Campos <angel.quiroz@beeznest.com>
+ */
+class Version20150615171900 extends AbstractMigrationChamilo
+{
+
+    /**
+     * @param Schema $schema
+     */
+    public function up(Schema $schema)
+    {
+        $this->addSql('ALTER TABLE c_course_description CHANGE description_type description_type INTEGER NOT NULL DEFAULT 1');
+    }
+
+    /**
+     * @param Schema $schema
+     */
+    public function down(Schema $schema)
+    {
+        $this->addSql('ALTER TABLE c_course_description CHANGE description_type description_type BOOLEAN NOT NULL');
+    }
+
+}

+ 35 - 0
app/Migrations/Schema/V110/Version20150616093200.php

@@ -0,0 +1,35 @@
+<?php
+/* For licensing terms, see /license.txt */
+
+namespace Application\Migrations\Schema\V110;
+
+use Application\Migrations\AbstractMigrationChamilo;
+use Doctrine\DBAL\Schema\Schema;
+
+/**
+ * Session date changes
+ */
+class Version20150616093200 extends AbstractMigrationChamilo
+{
+    /**
+     * @param Schema $schema
+     */
+    public function up(Schema $schema)
+    {
+        $this->addSql("INSERT INTO extra_field (
+            extra_field_type, field_type, variable, display_text, visible, changeable, created_at)
+            VALUES (2, 19, 'video_url', 'VideoUrl', 1, 1, NOW())");
+    }
+
+    /**
+     * @param Schema $schema
+     */
+    public function down(Schema $schema)
+    {
+        $this->addSql("DELETE FROM extra_field
+            WHERE variable = 'video_url' AND
+                extra_field_type = 2 AND
+                field_type = 19");
+    }
+
+}

+ 35 - 0
app/Migrations/Schema/V110/Version20150624164100.php

@@ -0,0 +1,35 @@
+<?php
+/* For licensing terms, see /license.txt */
+
+namespace Application\Migrations\Schema\V110;
+
+use Application\Migrations\AbstractMigrationChamilo;
+use Doctrine\DBAL\Schema\Schema;
+
+/**
+ * Session date changes
+ */
+class Version20150624164100 extends AbstractMigrationChamilo
+{
+    /**
+     * @param Schema $schema
+     */
+    public function up(Schema $schema)
+    {
+        $this->addSql("INSERT INTO extra_field
+            (extra_field_type, field_type, variable, display_text, visible, changeable, created_at)
+            VALUES (3, 16, 'image', 'Image', 1, 1, NOW())");
+    }
+
+    /**
+     * @param Schema $schema
+     */
+    public function down(Schema $schema)
+    {
+        $this->addSql("DELETE FROM extra_field
+            WHERE variable = 'image' AND
+                extra_field_type = 3 AND
+                field_type = 16");
+    }
+
+}

+ 35 - 0
app/Migrations/Schema/V110/Version20150625155000.php

@@ -0,0 +1,35 @@
+<?php
+/* For licensing terms, see /license.txt */
+
+namespace Application\Migrations\Schema\V110;
+
+use Application\Migrations\AbstractMigrationChamilo;
+use Doctrine\DBAL\Schema\Schema;
+
+/**
+ * Session date changes
+ */
+class Version20150625155000 extends AbstractMigrationChamilo
+{
+    /**
+     * @param Schema $schema
+     */
+    public function up(Schema $schema)
+    {
+        $this->addSql("INSERT INTO extra_field
+            (extra_field_type, field_type, variable, display_text, visible, changeable, created_at)
+            VALUES (1, 1, 'captcha_blocked_until_date', 'Account locked until', 0, 0, NOW())");
+    }
+
+    /**
+     * @param Schema $schema
+     */
+    public function down(Schema $schema)
+    {
+        $this->addSql("DELETE FROM extra_field
+            WHERE variable = 'captcha_blocked_until_date' AND
+                extra_field_type = 1 AND
+                field_type = 1");
+    }
+
+}

+ 36 - 0
app/Migrations/Schema/V110/Version20150706135000.php

@@ -0,0 +1,36 @@
+<?php
+/* For licensing terms, see /license.txt */
+
+namespace Application\Migrations\Schema\V110;
+
+use Application\Migrations\AbstractMigrationChamilo;
+use Doctrine\DBAL\Schema\Schema;
+
+/**
+ * GradebookCategory changes
+ */
+class Version20150706135000 extends AbstractMigrationChamilo
+{
+    /**
+     * @param Schema $schema
+     */
+    public function up(Schema $schema)
+    {
+        $gradebookCategory = $schema->getTable('gradebook_category');
+
+        $isRequirement = $gradebookCategory->addColumn(
+            'is_requirement',
+            \Doctrine\DBAL\Types\Type::BOOLEAN
+        );
+        $isRequirement->setNotnull(true)->setDefault(false);
+    }
+
+    /**
+     * @param Schema $schema
+     */
+    public function down(Schema $schema)
+    {
+        $gradebookCategory = $schema->getTable('gradebook_category');
+        $gradebookCategory->dropColumn('is_requirement');
+    }
+}

+ 29 - 0
app/Migrations/Schema/V110/Version20150709083710.php

@@ -0,0 +1,29 @@
+<?php
+/* For licensing terms, see /license.txt */
+
+namespace Application\Migrations\Schema\V110;
+
+use Application\Migrations\AbstractMigrationChamilo;
+use Doctrine\DBAL\Schema\Schema;
+
+/**
+ * Agenda
+ */
+class Version20150709083710 extends AbstractMigrationChamilo
+{
+    /**
+     * @param Schema $schema
+     */
+    public function up(Schema $schema)
+    {
+        $this->addSql('ALTER TABLE c_calendar_event ADD color VARCHAR(100) DEFAULT NULL');
+    }
+
+    /**
+     * @param Schema $schema
+     */
+    public function down(Schema $schema)
+    {
+        $this->addSql('ALTER TABLE c_calendar_event DROP color');
+    }
+}

+ 35 - 0
app/Migrations/Schema/V110/Version20150713132630.php

@@ -0,0 +1,35 @@
+<?php
+/* For licensing terms, see /license.txt */
+
+namespace Application\Migrations\Schema\V110;
+
+use Application\Migrations\AbstractMigrationChamilo;
+use Doctrine\DBAL\Schema\Schema;
+
+/**
+ * Class Version20150713132630
+ *
+ * @package Application\Migrations\Schema\V11010
+ */
+class Version20150713132630 extends AbstractMigrationChamilo
+{
+    /**
+     * @param Schema $schema
+     */
+    public function up(Schema $schema)
+    {
+        if ($schema->hasTable('c_student_publication')) {
+            $this->addSql('ALTER TABLE c_student_publication ADD url_correction VARCHAR(255) DEFAULT NULL');
+            $this->addSql('ALTER TABLE c_student_publication ADD title_correction VARCHAR(255) DEFAULT NULL');
+        }
+    }
+
+    /**
+     * @param Schema $schema
+     */
+    public function down(Schema $schema)
+    {
+        $this->addSql('ALTER TABLE c_student_publication DROP url_correction');
+        $this->addSql('ALTER TABLE c_student_publication DROP title_correction');
+    }
+}

+ 111 - 0
app/Migrations/Schema/V110/Version20150803163400.php

@@ -0,0 +1,111 @@
+<?php
+/* For licensing terms, see /license.txt */
+
+namespace Application\Migrations\Schema\V110;
+
+use Application\Migrations\AbstractMigrationChamilo;
+use Doctrine\DBAL\Schema\Schema;
+
+/**
+ * Class Version20150803163400
+ *
+ * @package Application\Migrations\Schema\V110
+ */
+class Version20150803163400 extends AbstractMigrationChamilo
+{
+    /**
+     * @param Schema $schema
+     */
+    public function up(Schema $schema)
+    {
+        $this->addSettingCurrent(
+            'cron_remind_course_expiration_activate',
+            null,
+            'radio',
+            'Crons',
+            'false',
+            'CronRemindCourseExpirationActivateTitle',
+            'CronRemindCourseExpirationActivateComment',
+            null,
+            null,
+            1,
+            true,
+            false,
+            [
+                0 => ['value' => 'true', 'text' => 'Yes'],
+                1 => ['value' => 'false', 'text' => 'No']
+            ]
+        );
+
+        $this->addSettingCurrent(
+            'cron_remind_course_expiration_frequency',
+            null,
+            'textfield',
+            'Crons',
+            '2',
+            'CronRemindCourseExpirationFrecuenqyTitle',
+            'CronRemindCourseExpirationFrecuenqyComment',
+            null,
+            null,
+            1,
+            true,
+            false
+        );
+
+        $this->addSettingCurrent(
+            'cron_course_finished_activate',
+            null,
+            'radio',
+            'Crons',
+            'false',
+            'CronCourseFinishedActivateTitle',
+            'CronCourseFinishedActivateComment',
+            null,
+            null,
+            1,
+            true,
+            false,
+            [
+                0 => ['value' => 'true', 'text' => 'Yes'],
+                1 => ['value' => 'false', 'text' => 'No']
+            ]
+        );
+    }
+
+    /**
+     * @param Schema $schema
+     */
+    public function down(Schema $schema)
+    {
+        $entityManage = $this->getEntityManager();
+
+        $deleteOptions = $entityManage->createQueryBuilder();
+
+        $deleteOptions->delete('ChamiloCoreBundle:SettingsOptions', 'o')
+            ->andWhere(
+                $deleteOptions->expr()->in(
+                    'o.variable',
+                    [
+                        'cron_remind_course_expiration_activate',
+                        'cron_course_finished_activate'
+                    ]
+                )
+            );
+        $deleteOptions->getQuery()->execute();
+
+        $deleteSettings = $entityManage->createQueryBuilder();
+        $deleteSettings->delete('ChamiloCoreBundle:SettingsCurrent', 's')
+            ->andWhere(
+                $deleteSettings->expr()->in(
+                    's.variable',
+                    [
+                        'cron_remind_course_expiration_activate',
+                        'cron_remind_course_expiration_frequency',
+                        'cron_course_finished_activate'
+                    ]
+                )
+            );
+        $deleteSettings->getQuery()->execute();
+    }
+
+}

+ 37 - 0
app/Migrations/Schema/V110/Version20150803171220.php

@@ -0,0 +1,37 @@
+<?php
+/* For licensing terms, see /license.txt */
+
+namespace Application\Migrations\Schema\V110;
+
+use Application\Migrations\AbstractMigrationChamilo;
+use Doctrine\DBAL\Schema\Schema;
+
+/**
+ * Class Version20150803171220
+ *
+ * @package Application\Migrations\Schema\V110
+ */
+class Version20150803171220 extends AbstractMigrationChamilo
+{
+    /**
+     * @param Schema $schema
+     */
+    public function up(Schema $schema)
+    {
+        $this->addSql('UPDATE user SET username_canonical = username');
+        $this->addSql('ALTER TABLE user ADD confirmation_token VARCHAR(255) NULL');
+        $this->addSql('ALTER TABLE user ADD password_requested_at DATETIME DEFAULT NULL');
+        $this->addSql('RENAME TABLE track_e_exercices TO track_e_exercises');
+        // This drops the old table
+        // $schema->renameTable('track_e_exercices', 'track_e_exercises');
+    }
+
+    /**
+     * @param Schema $schema
+     */
+    public function down(Schema $schema)
+    {
+        $this->addSql('ALTER TABLE user DROP confirmation_token');
+        $this->addSql('ALTER TABLE user DROP password_requested_at');
+    }
+}

+ 40 - 0
app/Migrations/Schema/V110/Version20150805161000.php

@@ -0,0 +1,40 @@
+<?php
+/* For licensing terms, see /license.txt */
+
+namespace Application\Migrations\Schema\V110;
+
+use Application\Migrations\AbstractMigrationChamilo;
+use Doctrine\DBAL\Schema\Schema;
+
+/**
+ * Class Version20150713132630
+ *
+ * @package Application\Migrations\Schema\V11010
+ */
+class Version20150805161000 extends AbstractMigrationChamilo
+{
+
+    /**
+     * @param Schema $schema
+     */
+    public function up(Schema $schema)
+    {
+        $sessionTable = $schema->getTable('session');
+
+        $sessionTable->addColumn(
+            'send_subscription_notification',
+            \Doctrine\DBAL\Types\Type::BOOLEAN,
+            ['default' => false]
+        );
+    }
+
+    /**
+     * @param Schema $schema
+     */
+    public function down(Schema $schema)
+    {
+        $sessionTable = $schema->getTable('session');
+        $sessionTable->dropColumn('send_subscription_notification');
+    }
+
+}

+ 29 - 0
app/Migrations/Schema/V110/Version20150810132615.php

@@ -0,0 +1,29 @@
+<?php
+/* For licensing terms, see /license.txt */
+
+namespace Application\Migrations\Schema\V110;
+
+use Application\Migrations\AbstractMigrationChamilo;
+use Doctrine\DBAL\Schema\Schema;
+
+/**
+ * Calendar color
+ */
+class Version20150810132615 extends AbstractMigrationChamilo
+{
+    /**
+     * @param Schema $schema
+     */
+    public function up(Schema $schema)
+    {
+        $this->addSql('ALTER TABLE personal_agenda ADD color VARCHAR(255) DEFAULT NULL');
+    }
+
+    /**
+     * @param Schema $schema
+     */
+    public function down(Schema $schema)
+    {
+        $this->addSql('ALTER TABLE personal_agenda DROP color');
+    }
+}

+ 75 - 0
app/Migrations/Schema/V110/Version20150812230500.php

@@ -0,0 +1,75 @@
+<?php
+/* For licensing terms, see /license.txt */
+
+namespace Application\Migrations\Schema\V110;
+
+use Application\Migrations\AbstractMigrationChamilo;
+use Doctrine\DBAL\Schema\Schema;
+
+/**
+ * Class Version20150812230500
+ *
+ * @package Application\Migrations\Schema\V11010
+ */
+class Version20150812230500 extends AbstractMigrationChamilo
+{
+
+    /**
+     * @param Schema $schema
+     */
+    public function up(Schema $schema)
+    {
+        $this->addSettingCurrent(
+            'allow_coach_feedback_exercises',
+            null,
+            'radio',
+            'Session',
+            'false',
+            'AllowCoachFeedbackExercisesTitle',
+            'AllowCoachFeedbackExercisesComment',
+            null,
+            null,
+            1,
+            true,
+            false,
+            [
+                ['value' => 'true', 'text' => 'Yes'],
+                ['value' => 'false', 'text' => 'No']
+            ]
+        );
+    }
+
+    /**
+     * @param Schema $schema
+     */
+    public function down(Schema $schema)
+    {
+        $entityManage = $this->getEntityManager();
+
+        $deleteOptions = $entityManage->createQueryBuilder();
+
+        $deleteOptions->delete('ChamiloCoreBundle:SettingsOptions', 'o')
+            ->andWhere(
+                $deleteOptions->expr()->in(
+                    'o.variable',
+                    [
+                        'allow_coach_feedback_exercises'
+                    ]
+                )
+            );
+        $deleteOptions->getQuery()->execute();
+
+        $deleteSettings = $entityManage->createQueryBuilder();
+        $deleteSettings->delete('ChamiloCoreBundle:SettingsCurrent', 's')
+            ->andWhere(
+                $deleteSettings->expr()->in(
+                    's.variable',
+                    [
+                        'allow_coach_feedback_exercises'
+                    ]
+                )
+            );
+        $deleteSettings->getQuery()->execute();
+    }
+
+}

+ 166 - 0
app/Migrations/Schema/V110/Version20150813143000.php

@@ -0,0 +1,166 @@
+<?php
+/* For licensing terms, see /license.txt */
+
+namespace Application\Migrations\Schema\V110;
+
+use Application\Migrations\AbstractMigrationChamilo;
+use Doctrine\DBAL\Schema\Schema;
+
+/**
+ * Calendar color
+ */
+class Version20150813143000 extends AbstractMigrationChamilo
+{
+    /**
+     * @param Schema $schema
+     */
+    public function up(Schema $schema)
+    {
+        $this->addSettingCurrent(
+            'prevent_multiple_simultaneous_login',
+            null,
+            'radio',
+            'Security',
+            'false',
+            'PreventMultipleSimultaneousLoginTitle',
+            'PreventMultipleSimultaneousLoginComment',
+            null,
+            null,
+            1,
+            false,
+            true,
+            [
+                0 => ['value' => 'true', 'text' => 'Yes'],
+                1 => ['value' => 'false', 'text' => 'No']
+            ]
+        );
+        $this->addSettingCurrent(
+            'gradebook_detailed_admin_view',
+            null,
+            'radio',
+            'Gradebook',
+            'false',
+            'ShowAdditionalColumnsInStudentResultsPageTitle',
+            'ShowAdditionalColumnsInStudentResultsPageComment',
+            null,
+            null,
+            1,
+            true,
+            false,
+            [
+                0 => ['value' => 'true', 'text' => 'Yes'],
+                1 => ['value' => 'false', 'text' => 'No']
+            ]
+        );
+        $this->addSettingCurrent(
+            'course_catalog_published',
+            null,
+            'radio',
+            'Course',
+            'false',
+            'CourseCatalogIsPublicTitle',
+            'CourseCatalogIsPublicComment',
+            null,
+            null,
+            1,
+            false,
+            true,
+            [
+                0 => ['value' => 'true', 'text' => 'Yes'],
+                1 => ['value' => 'false', 'text' => 'No']
+            ]
+        );
+        $this->addSettingCurrent(
+            'user_reset_password',
+            null,
+            'radio',
+            'Security',
+            'false',
+            'ResetPasswordTokenTitle',
+            'ResetPasswordTokenComment',
+            null,
+            null,
+            1,
+            false,
+            true,
+            [
+                0 => ['value' => 'true', 'text' => 'Yes'],
+                1 => ['value' => 'false', 'text' => 'No']
+            ]
+        );
+        $this->addSettingCurrent(
+            'user_reset_password_token_limit',
+            null,
+            'textfield',
+            'Security',
+            '3600',
+            'ResetPasswordTokenLimitTitle',
+            'ResetPasswordTokenLimitComment',
+            null,
+            null,
+            1,
+            false,
+            true
+        );
+        $this->addSettingCurrent(
+            'my_courses_view_by_session',
+            null,
+            'radio',
+            'Session',
+            'false',
+            'ViewMyCoursesListBySessionTitle',
+            'ViewMyCoursesListBySessionComment',
+            null,
+            null,
+            1,
+            true,
+            false,
+            [
+                0 => ['value' => 'true', 'text' => 'Yes'],
+                1 => ['value' => 'false', 'text' => 'No']
+            ]
+        );
+    }
+
+    /**
+     * @param Schema $schema
+     */
+    public function down(Schema $schema)
+    {
+        $entityManage = $this->getEntityManager();
+
+        $deleteOptions = $entityManage->createQueryBuilder();
+        $deleteSettings = $entityManage->createQueryBuilder();
+
+        $deleteOptions->delete('ChamiloCoreBundle:SettingsOptions', 'o')
+            ->andWhere(
+                $deleteOptions->expr()->in(
+                    'o.variable',
+                    [
+                        'prevent_multiple_simultaneous_login',
+                        'gradebook_detailed_admin_view',
+                        'course_catalog_published',
+                        'user_reset_password',
+                        'user_reset_password_token_limit',
+                        'my_courses_view_by_session'
+                    ]
+                )
+            );
+        $deleteOptions->getQuery()->execute();
+
+        $deleteSettings->delete('ChamiloCoreBundle:SettingsCurrent', 's')
+            ->andWhere(
+                $deleteSettings->expr()->in(
+                    's.variable',
+                    [
+                        'prevent_multiple_simultaneous_login',
+                        'gradebook_detailed_admin_view',
+                        'course_catalog_published',
+                        'user_reset_password',
+                        'my_courses_view_by_session'
+                    ]
+                )
+            );
+        $deleteSettings->getQuery()->execute();
+    }
+}

+ 71 - 0
app/Migrations/Schema/V110/Version20150813200000.php

@@ -0,0 +1,71 @@
+<?php
+/* For licensing terms, see /license.txt */
+
+namespace Application\Migrations\Schema\V110;
+
+use Application\Migrations\AbstractMigrationChamilo;
+use Doctrine\DBAL\Schema\Schema;
+
+/**
+ * Calendar color
+ */
+class Version20150813200000 extends AbstractMigrationChamilo
+{
+    /**
+     * @param Schema $schema
+     */
+    public function up(Schema $schema)
+    {
+        $entityManage = $this->getEntityManager();
+
+        $deleteOptions = $entityManage->createQueryBuilder();
+        $deleteSettings = $entityManage->createQueryBuilder();
+
+        $deleteOptions->delete('ChamiloCoreBundle:SettingsOptions', 'o')
+            ->andWhere(
+                $deleteOptions->expr()->in(
+                    'o.variable',
+                    [
+                        'math_mimetex'
+                    ]
+                )
+            );
+        $deleteOptions->getQuery()->execute();
+
+        $deleteSettings->delete('ChamiloCoreBundle:SettingsCurrent', 's')
+            ->andWhere(
+                $deleteSettings->expr()->in(
+                    's.variable',
+                    [
+                        'math_mimetex'
+                    ]
+                )
+            );
+        $deleteSettings->getQuery()->execute();
+    }
+
+    /**
+     * @param Schema $schema
+     */
+    public function down(Schema $schema)
+    {
+        $this->addSettingCurrent(
+            'math_mimetex',
+            null,
+            'radio',
+            'Editor',
+            'false',
+            'MathMimetexTitle',
+            'MathMimetexComment',
+            null,
+            null,
+            1,
+            false,
+            true,
+            [
+                0 => ['value' => 'true', 'text' => 'Yes'],
+                1 => ['value' => 'false', 'text' => 'No']
+            ]
+        );
+    }
+}

+ 45 - 0
app/Migrations/Schema/V110/Version20150819095300.php

@@ -0,0 +1,45 @@
+<?php
+/* For licensing terms, see /license.txt */
+
+namespace Application\Migrations\Schema\V110;
+
+use Application\Migrations\AbstractMigrationChamilo;
+use Doctrine\DBAL\Schema\Schema;
+
+/**
+ * Class Version20150819095300
+ *
+ * @package Application\Migrations\Schema\V11010
+ */
+class Version20150819095300 extends AbstractMigrationChamilo
+{
+
+    /**
+     * @param Schema $schema
+     */
+    public function up(Schema $schema)
+    {
+        $skillTable = $schema->getTable('skill');
+
+        $skillTable->addColumn(
+            'status',
+            \Doctrine\DBAL\Types\Type::INTEGER,
+            ['default' => 1]
+        );
+        $skillTable->addColumn(
+            'updated_at',
+            \Doctrine\DBAL\Types\Type::DATETIME
+        );
+    }
+
+    /**
+     * @param Schema $schema
+     */
+    public function down(Schema $schema)
+    {
+        $skillTable = $schema->getTable('skill');
+        $skillTable->dropColumn('status');
+        $skillTable->dropColumn('updated_at');
+    }
+
+}

+ 178 - 0
app/Migrations/Schema/V110/Version20150821150000.php

@@ -0,0 +1,178 @@
+<?php
+/* For licensing terms, see /license.txt */
+
+namespace Application\Migrations\Schema\V110;
+
+use Application\Migrations\AbstractMigrationChamilo;
+use Doctrine\DBAL\Schema\Schema;
+
+/**
+ * Class Version20150821150000
+ *
+ * @package Application\Migrations\Schema\V11010
+ */
+class Version20150821150000 extends AbstractMigrationChamilo
+{
+
+    /**
+     * @param Schema $schema
+     */
+    public function up(Schema $schema)
+    {
+        $entityManage = $this->getEntityManager();
+
+        $deleteOptions = $entityManage->createQueryBuilder();
+        $deleteSettings = $entityManage->createQueryBuilder();
+
+        $deleteOptions->delete('ChamiloCoreBundle:SettingsOptions', 'o')
+            ->andWhere(
+                $deleteOptions->expr()->in(
+                    'o.variable',
+                    [
+                        'display_mini_month_calendar'
+                    ]
+                )
+            );
+        $deleteOptions->getQuery()->execute();
+
+        $deleteSettings->delete('ChamiloCoreBundle:SettingsCurrent', 's')
+            ->andWhere(
+                $deleteSettings->expr()->in(
+                    's.variable',
+                    [
+                        'display_mini_month_calendar'
+                    ]
+                )
+            );
+        $deleteSettings->getQuery()->execute();
+        $deleteOptions->delete('ChamiloCoreBundle:SettingsOptions', 'o')
+            ->andWhere(
+                $deleteOptions->expr()->in(
+                    'o.variable',
+                    [
+                        'display_upcoming_events'
+                    ]
+                )
+            );
+        $deleteOptions->getQuery()->execute();
+
+        $deleteSettings->delete('ChamiloCoreBundle:SettingsCurrent', 's')
+            ->andWhere(
+                $deleteSettings->expr()->in(
+                    's.variable',
+                    [
+                        'display_upcoming_events'
+                    ]
+                )
+            );
+        $deleteSettings->getQuery()->execute();
+        $deleteSettings->delete('ChamiloCoreBundle:SettingsCurrent', 's')
+            ->andWhere(
+                $deleteSettings->expr()->in(
+                    's.variable',
+                    [
+                        'number_of_upcoming_events'
+                    ]
+                )
+            );
+        $deleteSettings->getQuery()->execute();
+
+        $deleteOptions->delete('ChamiloCoreBundle:SettingsOptions', 'o')
+            ->andWhere(
+                $deleteOptions->expr()->in(
+                    'o.variable',
+                    [
+                        'allow_reservation'
+                    ]
+                )
+            );
+        $deleteOptions->getQuery()->execute();
+
+        $deleteSettings->delete('ChamiloCoreBundle:SettingsCurrent', 's')
+            ->andWhere(
+                $deleteSettings->expr()->in(
+                    's.variable',
+                    [
+                        'allow_reservation'
+                    ]
+                )
+            );
+        $deleteSettings->getQuery()->execute();
+    }
+
+    /**
+     * @param Schema $schema
+     */
+    public function down(Schema $schema)
+    {
+        $this->addSettingCurrent(
+            'display_mini_month_calendar',
+            null,
+            'radio',
+            'Tools',
+            'true',
+            'DisplayMiniMonthCalendarTitle',
+            'DisplayMiniMonthCalendarComment',
+            null,
+            null,
+            1,
+            false,
+            false,
+            [
+                0 => ['value' => 'true', 'text' => 'Yes'],
+                1 => ['value' => 'false', 'text' => 'No']
+            ]
+        );
+        $this->addSettingCurrent(
+            'display_upcoming_events',
+            null,
+            'radio',
+            'Tools',
+            'true',
+            'DisplayUpcomingEventsTitle',
+            'DisplayUpcomingEventsComment',
+            null,
+            null,
+            1,
+            false,
+            false,
+            [
+                0 => ['value' => 'true', 'text' => 'Yes'],
+                1 => ['value' => 'false', 'text' => 'No']
+            ]
+        );
+        $this->addSettingCurrent(
+            'number_of_upcoming_events',
+            null,
+            'textfield',
+            'Tools',
+            '1',
+            'NumberOfUpcomingEventsTitle',
+            'NumberOfUpcomingEventsComment',
+            null,
+            null,
+            1,
+            false,
+            false
+        );
+        $this->addSettingCurrent(
+            'allow_reservation',
+            null,
+            'radio',
+            'Tools',
+            'false',
+            'AllowReservationTitle',
+            'AllowReservationComment',
+            null,
+            null,
+            1,
+            true,
+            false,
+            [
+                0 => ['value' => 'true', 'text' => 'Yes'],
+                1 => ['value' => 'false', 'text' => 'No']
+            ]
+        );
+    }
+
+}

+ 67 - 0
app/Migrations/Schema/V110/Version20150825141100.php

@@ -0,0 +1,67 @@
+<?php
+/* For licensing terms, see /license.txt */
+
+namespace Application\Migrations\Schema\V110;
+
+use Application\Migrations\AbstractMigrationChamilo;
+use Doctrine\DBAL\Schema\Schema;
+
+/**
+ * Calendar color
+ */
+class Version20150825141100 extends AbstractMigrationChamilo
+{
+    /**
+     * @param Schema $schema
+     */
+    public function up(Schema $schema)
+    {
+        $this->addSettingCurrent(
+            'show_full_skill_name_on_skill_wheel',
+            null,
+            'radio',
+            'Platform',
+            'false',
+            'ShowFullSkillNameOnSkillWheelTitle',
+            'ShowFullSkillNameOnSkillWheelComment',
+            null,
+            null,
+            1,
+            false,
+            true,
+            [
+                ['value' => 'true', 'text' => 'Yes'],
+                ['value' => 'false', 'text' => 'No']
+            ]
+        );
+    }
+
+    /**
+     * @param Schema $schema
+     */
+    public function down(Schema $schema)
+    {
+        $entityManage = $this->getEntityManager();
+
+        $deleteOptions = $entityManage->createQueryBuilder();
+        $deleteSettings = $entityManage->createQueryBuilder();
+
+        $deleteOptions->delete('ChamiloCoreBundle:SettingsOptions', 'o')
+            ->andWhere(
+                $deleteOptions->expr()->in(
+                    'o.variable',
+                    ['show_full_skill_name_on_skill_wheel']
+                )
+            );
+        $deleteOptions->getQuery()->execute();
+
+        $deleteSettings->delete('ChamiloCoreBundle:SettingsCurrent', 's')
+            ->andWhere(
+                $deleteSettings->expr()->in(
+                    's.variable',
+                    ['show_full_skill_name_on_skill_wheel']
+                )
+            );
+        $deleteSettings->getQuery()->execute();
+    }
+}

+ 41 - 0
app/Migrations/Schema/V110/Version20151101082200.php

@@ -0,0 +1,41 @@
+<?php
+/* For licensing terms, see /license.txt */
+
+namespace Application\Migrations\Schema\V110;
+
+use Application\Migrations\AbstractMigrationChamilo;
+use Doctrine\DBAL\Schema\Schema;
+
+/**
+ * Calendar color
+ */
+class Version20151101082200 extends AbstractMigrationChamilo
+{
+    /**
+     * @param Schema $schema
+     */
+    public function up(Schema $schema)
+    {
+        $this->addSql("ALTER TABLE access_url ENGINE=InnoDB");
+        $this->addSql("ALTER TABLE access_url_rel_course ENGINE=InnoDB");
+        $this->addSql("ALTER TABLE course_rel_user ENGINE=InnoDB");
+        $this->addSql("ALTER TABLE session_category ENGINE=InnoDB");
+        $this->addSql("ALTER TABLE settings_current ENGINE=InnoDB");
+        $this->addSql("ALTER TABLE settings_options ENGINE=InnoDB");
+        $this->addSql("ALTER TABLE usergroup ENGINE=InnoDB");
+        $this->addSql("ALTER TABLE usergroup_rel_user ENGINE=InnoDB");
+
+        $this->addSql("ALTER TABLE session_rel_course DROP PRIMARY KEY");
+        $this->addSql("ALTER TABLE session_rel_course_rel_user DROP PRIMARY KEY");
+        $this->addSql("ALTER TABLE session MODIFY session_category_id INT NULL");
+
+        $this->addSql("UPDATE session SET session_category_id = NULL WHERE session_category_id NOT IN (SELECT id FROM session_category)");
+    }
+
+    /**
+     * @param Schema $schema
+     */
+    public function down(Schema $schema)
+    {
+    }
+}

+ 312 - 0
app/Migrations/Schema/V110/Version20151101082300.php

@@ -0,0 +1,312 @@
+<?php
+/* For licensing terms, see /license.txt */
+
+namespace Application\Migrations\Schema\V110;
+
+use Application\Migrations\AbstractMigrationChamilo;
+use Doctrine\DBAL\Schema\Schema;
+use Doctrine\DBAL\Types\Type;
+
+/**
+ * Calendar color
+ */
+class Version20151101082300 extends AbstractMigrationChamilo
+{
+    /**
+     * @param Schema $schema
+     */
+    public function up(Schema $schema)
+    {
+        $accessUrl = $schema->getTable('access_url');
+        $accessUrl->getColumn('id')->setUnsigned(false);
+
+        $this->connection->executeQuery('UPDATE access_url_rel_course SET access_url_id = NULL WHERE access_url_id NOT IN (SELECT id FROM access_url)');
+
+        $accessUrlRelCourse = $schema->getTable('access_url_rel_course');
+        $accessUrlRelCourse->getColumn('access_url_id')->setUnsigned(false);
+        $accessUrlRelCourse->addForeignKeyConstraint('access_url', ['access_url_id'], ['id']);
+        $accessUrlRelCourse->addForeignKeyConstraint('course', ['c_id'], ['id']);
+
+        $schema->renameTable('class', 'class_item');
+
+        $classUser = $schema->getTable('class_user');
+        $classUser->getColumn('class_id')->setUnsigned(false);
+        $classUser->getColumn('user_id')->setUnsigned(false);
+
+        $course = $schema->getTable('course');
+        $course->getColumn('course_type_id')->setUnsigned(false);
+        $course->addForeignKeyConstraint('room', ['room_id'], ['id']);
+
+        $courseRelClass = $schema->getTable('course_rel_class');
+        $courseRelClass->getColumn('class_id')->setUnsigned(false)->setType(Type::getType(Type::INTEGER));
+
+        $courseRelUser = $schema->getTable('course_rel_user');
+        $courseRelUser->addForeignKeyConstraint('course', ['c_id'], ['id']);
+        $courseRelUser->addForeignKeyConstraint('user', ['user_id'], ['id']);
+
+        $courseType = $schema->getTable('course_type');
+        $courseType->getColumn('id')->setUnsigned(false);
+
+        $schema->getTable('c_announcement')->addIndex(['c_id']);
+        $schema->getTable('c_announcement_attachment')->addIndex(['c_id']);
+        $schema->getTable('c_attendance')->addIndex(['c_id']);
+        $schema->getTable('c_attendance_calendar')->addIndex(['c_id']);
+
+        $cAttendanceCalendarRelGroup = $schema->getTable('c_attendance_calendar_rel_group');
+        $cAttendanceCalendarRelGroup->addIndex(['c_id']);
+        $cAttendanceCalendarRelGroup->addIndex(['group_id']);
+
+        $schema->getTable('c_attendance_result')->addIndex(['c_id']);
+
+        $cAttendanceSheet = $schema->getTable('c_attendance_sheet');
+        $cAttendanceSheet->addIndex(['c_id']);
+        $cAttendanceSheet->addIndex(['user_id']);
+
+        $schema->getTable('c_attendance_sheet_log')->addIndex(['c_id']);
+        $schema->getTable('c_blog')->addIndex(['c_id']);
+        $schema->getTable('c_blog_attachment')->addIndex(['c_id']);
+        $schema->getTable('c_blog_comment')->addIndex(['c_id']);
+        $schema->getTable('c_blog_post')->addIndex(['c_id']);
+        $schema->getTable('c_blog_rating')->addIndex(['c_id']);
+
+        $cBlogRelUser = $schema->getTable('c_blog_rel_user');
+        $cBlogRelUser->getColumn('blog_id')->setUnsigned(false);
+        $cBlogRelUser->getColumn('user_id')->setUnsigned(false);
+        $cBlogRelUser->addIndex(['c_id']);
+
+        $schema->getTable('c_blog_task')->addIndex(['c_id']);
+
+        $cBlogTaskRelUser = $schema->getTable('c_blog_task_rel_user');
+        $cBlogTaskRelUser->getColumn('blog_id')->setUnsigned(false);
+        $cBlogTaskRelUser->getColumn('user_id')->setUnsigned(false);
+        $cBlogTaskRelUser->getColumn('task_id')->setUnsigned(false);
+        $cBlogTaskRelUser->addIndex(['c_id']);
+        $cBlogTaskRelUser->addIndex(['user_id']);
+        $cBlogTaskRelUser->addIndex(['task_id']);
+
+        $cCalendarEvent = $schema->getTable('c_calendar_event');
+        $cCalendarEvent->addIndex(['c_id']);
+
+        $schema->getTable('c_calendar_event_attachment')->addIndex(['c_id']);
+        $schema->getTable('c_calendar_event_repeat')->addIndex(['c_id']);
+        $schema->getTable('c_calendar_event_repeat_not')->addIndex(['c_id']);
+
+        $cChatConnected = $schema->getTable('c_chat_connected');
+        $cChatConnected->addIndex(['c_id']);
+        $cChatConnected->addIndex(['user_id']);
+
+        $schema->getTable('c_course_setting')->addIndex(['c_id']);
+        $schema->getTable('c_document')->addIndex(['c_id']);
+        $schema->getTable('c_dropbox_category')->addIndex(['c_id']);
+        $schema->getTable('c_dropbox_feedback')->addIndex(['c_id']);
+        $schema->getTable('c_dropbox_file')->addIndex(['c_id']);
+
+        $cDropboxPerson = $schema->getTable('c_dropbox_person');
+        $cDropboxPerson->addIndex(['c_id']);
+        $cDropboxPerson->addIndex(['user_id']);
+
+        $cDropboxPost = $schema->getTable('c_dropbox_post');
+        $cDropboxPost->addIndex(['c_id']);
+        $cDropboxPost->addIndex(['dest_user_id']);
+
+        $schema->getTable('c_forum_attachment')->addIndex(['c_id']);
+        $schema->getTable('c_forum_category')->addIndex(['c_id']);
+        $schema->getTable('c_forum_forum')->addIndex(['c_id']);
+
+        $cForumMailcue = $schema->getTable('c_forum_mailcue');
+        $cForumMailcue->addIndex(['c_id']);
+        $cForumMailcue->addIndex(['thread_id']);
+        $cForumMailcue->addIndex(['user_id']);
+        $cForumMailcue->addIndex(['post_id']);
+
+        $cForumNotification = $schema->getTable('c_forum_notification');
+        $cForumNotification->addIndex(['c_id']);
+        $cForumNotification->addIndex(['thread_id']);
+        $cForumNotification->addIndex(['post_id']);
+
+        $schema->getTable('c_forum_post')->addIndex(['c_id']);
+        $schema->getTable('c_forum_thread')->addIndex(['c_id']);
+        $schema->getTable('c_forum_thread_qualify')->addIndex(['c_id']);
+        $schema->getTable('c_forum_thread_qualify_log')->addIndex(['c_id']);
+        $schema->getTable('c_glossary')->addIndex(['c_id']);
+        $schema->getTable('c_group_category')->addIndex(['c_id']);
+        $schema->getTable('c_group_info')->addIndex(['c_id']);
+        $schema->getTable('c_group_rel_tutor')->addIndex(['c_id']);
+
+        $schema->getTable('c_group_rel_user')->addIndex(['c_id']);
+        $schema->getTable('c_link')->addIndex(['c_id']);
+        $schema->getTable('c_link_category')->addIndex(['c_id']);
+        $schema->getTable('c_lp')->addIndex(['c_id']);
+        $schema->getTable('c_lp_category')->addIndex(['c_id']);
+        $schema->getTable('c_lp_item')->addIndex(['c_id']);
+        $schema->getTable('c_lp_item_view')->addIndex(['c_id']);
+        $schema->getTable('c_lp_iv_interaction')->addIndex(['c_id']);
+        $schema->getTable('c_lp_iv_objective')->addIndex(['c_id']);
+        $schema->getTable('c_lp_view')->addIndex(['c_id']);
+        $schema->getTable('c_notebook')->addIndex(['c_id']);
+        $schema->getTable('c_online_connected')->addIndex(['c_id']);
+        $schema->getTable('c_online_link')->addIndex(['c_id']);
+        $schema->getTable('c_permission_group')->addIndex(['c_id']);
+        $schema->getTable('c_permission_task')->addIndex(['c_id']);
+        $schema->getTable('c_permission_user')->addIndex(['c_id']);
+        $schema->getTable('c_quiz')->addIndex(['c_id']);
+        $schema->getTable('c_quiz_answer')->addIndex(['c_id']);
+        $schema->getTable('c_quiz_question')->addIndex(['c_id']);
+        $schema->getTable('c_quiz_question_category')->addIndex(['c_id']);
+        $schema->getTable('c_quiz_question_option')->addIndex(['c_id']);
+        $schema->getTable('c_quiz_question_rel_category')->addIndex(['c_id']);
+
+        $cQuizRelQuestion = $schema->getTable('c_quiz_rel_question');
+        $cQuizRelQuestion->addIndex(['c_id']);
+        $cQuizRelQuestion->addIndex(['question_id']);
+        $cQuizRelQuestion->addIndex(['exercice_id']);
+
+        $schema->getTable('c_resource')->addIndex(['c_id']);
+
+        $schema->getTable('c_role')->addIndex(['c_id']);
+
+        $cRoleGroup = $schema->getTable('c_role_group');
+        $cRoleGroup->addIndex(['c_id']);
+        $cRoleGroup->addIndex(['group_id']);
+
+        $cRolePermissions = $schema->getTable('c_role_permissions');
+        $cRolePermissions->addIndex(['c_id']);
+        $cRolePermissions->addIndex(['role_id']);
+
+        $cRoleUser = $schema->getTable('c_role_user');
+        $cRoleUser->addIndex(['c_id']);
+        $cRoleUser->addIndex(['user_id']);
+
+        $schema->getTable('c_student_publication')->addIndex(['c_id']);
+        $schema->getTable('c_student_publication_assignment')->addIndex(['c_id']);
+
+        $cStudentPublicationComment = $schema->getTable('c_student_publication_comment');
+        $cStudentPublicationComment->addIndex(['c_id']);
+        $cStudentPublicationComment->addIndex(['user_id']);
+        $cStudentPublicationComment->addIndex(['work_id']);
+
+        $cStudentPublicationComment = $schema->getTable('c_student_publication_rel_document');
+        $cStudentPublicationComment->addIndex(['c_id']);
+        $cStudentPublicationComment->addIndex(['work_id']);
+        $cStudentPublicationComment->addIndex(['document_id']);
+
+        $cStudentPublicationComment = $schema->getTable('c_student_publication_rel_user');
+        $cStudentPublicationComment->addIndex(['c_id']);
+        $cStudentPublicationComment->addIndex(['work_id']);
+        $cStudentPublicationComment->addIndex(['user_id']);
+
+        $schema->getTable('c_survey')->addIndex(['c_id']);
+        $schema->getTable('c_survey_answer')->addIndex(['c_id']);
+        $schema->getTable('c_survey_group')->addIndex(['c_id']);
+        $schema->getTable('c_survey_invitation')->addIndex(['c_id']);
+        $schema->getTable('c_survey_question')->addIndex(['c_id']);
+        $schema->getTable('c_survey_question_option')->addIndex(['c_id']);
+        $schema->getTable('c_thematic')->addIndex(['c_id']);
+        $schema->getTable('c_thematic_advance')->addIndex(['c_id']);
+        $schema->getTable('c_thematic_plan')->addIndex(['c_id']);
+        $schema->getTable('c_tool')->addIndex(['c_id']);
+        $schema->getTable('c_tool_intro')->addIndex(['c_id']);
+        $schema->getTable('c_userinfo_content')->addIndex(['c_id']);
+        $schema->getTable('c_userinfo_def')->addIndex(['c_id']);
+        $schema->getTable('c_wiki')->addIndex(['c_id']);
+        $schema->getTable('c_wiki_conf')->addIndex(['c_id']);
+        $schema->getTable('c_wiki_discuss')->addIndex(['c_id']);
+
+        $cWikiMailcue = $schema->getTable('c_wiki_mailcue');
+        $cWikiMailcue->addIndex(['c_id']);
+        $cWikiMailcue->addIndex(['user_id']);
+
+        $schema->getTable('extra_field_values')->addForeignKeyConstraint('extra_field', ['field_id'], ['id']);
+
+        $session = $schema->getTable('session');
+        $session->getColumn('id_coach')->setUnsigned(false);
+        $session->addIndex(['session_category_id']);
+        $session->addIndex(['id_coach']);
+        $session->addForeignKeyConstraint('session_category', ['session_category_id'], ['id']);
+        $session->addForeignKeyConstraint('user', ['id_coach'], ['id']);
+
+        $this->connection->executeQuery('UPDATE session_category SET access_url_id = 1 WHERE access_url_id NOT IN (SELECT id FROM access_url)');
+
+        $sessionCategory = $schema->getTable('session_category');
+        $sessionCategory->addIndex(['access_url_id']);
+        $sessionCategory->addForeignKeyConstraint('access_url', ['access_url_id'], ['id']);
+
+        $sessionRelCourse = $schema->getTable('session_rel_course');
+        $sessionRelCourse->dropColumn('course_code');
+        $sessionRelCourse->addColumn('id', Type::INTEGER)->setAutoincrement(true);
+        $sessionRelCourse->getColumn('c_id')->setUnsigned(false);
+        $sessionRelCourse->setPrimaryKey(['id']);
+        $sessionRelCourse->addIndex(['c_id']);
+        $sessionRelCourse->addIndex(['session_id']);
+        $sessionRelCourse->addForeignKeyConstraint('course', ['c_id'], ['id']);
+        $sessionRelCourse->addForeignKeyConstraint('session', ['session_id'], ['id']);
+
+        $this->connection->executeQuery('DELETE FROM session_rel_course_rel_user WHERE c_id NOT IN (SELECT id FROM course)');
+        $this->connection->executeQuery('DELETE FROM session_rel_course_rel_user WHERE session_id NOT IN (SELECT id FROM session)');
+        $this->connection->executeQuery('DELETE FROM session_rel_course_rel_user WHERE user_id NOT IN (SELECT id FROM user)');
+
+        $sessionRelCourseRelUser = $schema->getTable('session_rel_course_rel_user');
+        $sessionRelCourseRelUser->dropColumn('course_code');
+        $sessionRelCourseRelUser->addColumn('id', Type::INTEGER)->setAutoincrement(true);
+        $sessionRelCourseRelUser->getColumn('c_id')->setUnsigned(false);
+        $sessionRelCourseRelUser->setPrimaryKey(['id']);
+        $sessionRelCourseRelUser->addIndex(['c_id']);
+        $sessionRelCourseRelUser->addIndex(['session_id']);
+        $sessionRelCourseRelUser->addForeignKeyConstraint('course', ['c_id'], ['id']);
+        $sessionRelCourseRelUser->addForeignKeyConstraint('session', ['session_id'], ['id']);
+        $sessionRelCourseRelUser->addForeignKeyConstraint('user', ['user_id'], ['id']);
+
+        $this->connection->executeQuery('DELETE FROM session_rel_user WHERE user_id NOT IN (SELECT id FROM user)');
+        $this->connection->executeQuery('DELETE FROM session_rel_user WHERE session_id NOT IN (SELECT id FROM session)');
+
+        $sessionRelUser = $schema->getTable('session_rel_user');
+        $sessionRelUser->addColumn('moved_to', Type::INTEGER)->setNotnull(false);
+        $sessionRelUser->addColumn('moved_status', Type::INTEGER)->setNotnull(false);
+        $sessionRelUser->addColumn('moved_at', Type::DATETIME)->setNotnull(false);
+        $sessionRelUser->addIndex(['session_id']);
+        $sessionRelUser->addIndex(['user_id']);
+        $sessionRelUser->addIndex(['user_id', 'moved_to']);
+        $sessionRelUser->addForeignKeyConstraint('user', ['user_id'], ['id']);
+        $sessionRelUser->addForeignKeyConstraint('session', ['session_id'], ['id']);
+
+        $settingsCurrent = $schema->getTable('settings_current');
+        $settingsCurrent->addUniqueIndex(['variable', 'subkey', 'access_url']);
+
+        $settingsCurrent = $schema->getTable('settings_options');
+        $settingsCurrent->dropIndex('id');
+        $settingsCurrent->addUniqueIndex(['variable', 'value']);
+
+        $schema->getTable('track_e_access')->addIndex(['c_id']);
+        $schema->getTable('track_e_attempt')->addIndex(['c_id']);
+        $schema->getTable('track_e_course_access')->addIndex(['c_id']);
+
+        $trackEDefault = $schema->getTable('track_e_default');
+        $trackEDefault->addIndex(['c_id']);
+        $trackEDefault->addIndex(['session_id']);
+
+        $schema->getTable('track_e_downloads')->addIndex(['c_id']);
+        $schema->getTable('track_e_exercises')->addIndex(['c_id']);
+        $schema->getTable('track_e_hotpotatoes')->addIndex(['c_id']);
+        $schema->getTable('track_e_lastaccess')->addIndex(['c_id']);
+        $schema->getTable('track_e_links')->addIndex(['c_id']);
+        $schema->getTable('track_e_online')->addIndex(['c_id']);
+        $schema->getTable('track_e_uploads')->addIndex(['c_id']);
+        $schema->getTable('user')->addUniqueIndex(['username_canonical']);
+
+        $this->connection->executeQuery('DELETE FROM usergroup_rel_user WHERE user_id NOT IN (SELECT id FROM user)');
+        $this->connection->executeQuery('DELETE FROM usergroup_rel_user WHERE usergroup_id NOT IN (SELECT id FROM usergroup)');
+
+        $usergroupRelUSer = $schema->getTable('usergroup_rel_user');
+        $usergroupRelUSer->addIndex(['user_id']);
+        $usergroupRelUSer->addIndex(['usergroup_id']);
+        $usergroupRelUSer->addForeignKeyConstraint('usergroup', ['usergroup_id'], ['id']);
+        $usergroupRelUSer->addForeignKeyConstraint('user', ['user_id'], ['id']);
+    }
+
+    /**
+     * @param Schema $schema
+     */
+    public function down(Schema $schema)
+    {
+    }
+}

+ 34 - 0
app/Migrations/Schema/V110/Version20151119082400.php

@@ -0,0 +1,34 @@
+<?php
+/* For licensing terms, see /license.txt */
+
+namespace Application\Migrations\Schema\V110;
+
+use Application\Migrations\AbstractMigrationChamilo;
+use Doctrine\DBAL\Schema\Schema;
+use Doctrine\DBAL\Types\Type;
+
+/**
+ * Add new indexes
+ */
+class Version20151119082400 extends AbstractMigrationChamilo
+{
+    /**
+     * @param Schema $schema
+     */
+    public function up(Schema $schema)
+    {
+        $user = $schema->getTable('user');
+        $user->addIndex(['user_id']);
+
+        $userRelTag = $schema->getTable('user_rel_tag');
+        $userRelTag->addIndex(['user_id']);
+        $userRelTag->addIndex(['tag_id']);
+    }
+
+    /**
+     * @param Schema $schema
+     */
+    public function down(Schema $schema)
+    {
+    }
+}

+ 32 - 0
app/Migrations/Schema/V110/Version20151214164000.php

@@ -0,0 +1,32 @@
+<?php
+/* For licensing terms, see /license.txt */
+
+namespace Application\Migrations\Schema\V110;
+
+use Application\Migrations\AbstractMigrationChamilo;
+use Doctrine\DBAL\Schema\Schema;
+
+/**
+ * Add indexes
+ */
+class Version20151214164000 extends AbstractMigrationChamilo
+{
+    /**
+     * @param Schema $schema
+     */
+    public function up(Schema $schema)
+    {
+        $extraFieldValueTable = $schema->getTable('extra_field_values');
+        $extraFieldValueTable->addIndex(['field_id', 'item_id']);
+
+        $extraFieldTable = $schema->getTable('extra_field');
+        $extraFieldTable->addIndex(['extra_field_type']);
+    }
+
+    /**
+     * @param Schema $schema
+     */
+    public function down(Schema $schema)
+    {
+    }
+}

+ 129 - 0
app/Migrations/Schema/V110/Version20151214170800.php

@@ -0,0 +1,129 @@
+<?php
+/* For licensing terms, see /license.txt */
+
+namespace Application\Migrations\Schema\V110;
+
+use Application\Migrations\AbstractMigrationChamilo;
+use Doctrine\DBAL\Schema\Schema;
+use Doctrine\DBAL\Types\Type;
+
+/**
+ * Fix track_e_hotspot table and migrate hotspot/values
+ * In the wake of an issue with the hotspot code not being possible to update without moving from AS2 to AS3 (Flash), we
+ * have decided to rewrite the hotspot tool in JS.
+ * Little did we know that we would find out that the coordinates system in use by the Flash version of hotspot was in
+ * fact a projection into a square form of 360x360, not depending on the original size of the image, and that a square
+ * was defined by its center's coordinates and its width, with an initial not-null margin on the left and top borders.
+ * The migration below fixes those parallax issues.
+ */
+class Version20151214170800 extends AbstractMigrationChamilo
+{
+    /**
+     * @param Schema $schema
+     */
+    public function up(Schema $schema)
+    {
+        $this->addSql("ALTER TABLE track_e_hotspot ADD c_id INT NULL");
+        $this->addSql("ALTER TABLE track_e_hotspot MODIFY COLUMN hotspot_coordinate LONGTEXT NOT NULL");
+        $this->addSql("UPDATE track_e_hotspot SET c_id = (SELECT id FROM course WHERE code = hotspot_course_code)");
+
+        $answers = $this->connection->fetchAll("
+            SELECT a.iid, a.c_id, a.question_id, a.hotspot_coordinates, a.hotspot_type, q.picture, c.directory
+            FROM c_quiz_answer a
+            INNER JOIN c_quiz_question q
+                ON a.question_id = q.id
+            INNER JOIN course c
+                ON (a.c_id = c.id AND q.c_id = c.id)
+            WHERE a.hotspot_type IN ('square', 'circle', 'poly', 'delineation', 'oar')
+        ");
+
+        foreach ($answers as $answer) {
+            // Recover the real image size to recalculate coordinates
+            $imagePath = api_get_path(SYS_PATH) . "courses/{$answer['directory']}/document/images/{$answer['picture']}";
+            $imageSize = getimagesize($imagePath);
+            $widthRatio = $imageSize[0] / 360;
+            $heightRatio = $imageSize[1] / 360;
+            $oldCoords = $answer['hotspot_coordinates'];
+            $oldPairedString = explode('|', $oldCoords);
+            $newPairedString = [];
+
+            switch ($answer['hotspot_type']) {
+                case 'square':
+                    $oldCenter = explode(';', $oldPairedString[0]);
+
+                    $oldCenterX = intval($oldCenter[0]);
+                    $oldCenterY = intval($oldCenter[1]);
+                    $oldWidth = intval($oldPairedString[1]);
+                    $oldHeight = intval($oldPairedString[2]);
+
+                    $newX = floor(($oldCenterX - $oldWidth / 2) * $widthRatio) + ceil($widthRatio);
+                    $newY = floor(($oldCenterY - $oldHeight / 2) * $heightRatio) + ceil($heightRatio);
+                    $newWidth = ceil($oldWidth * $widthRatio) + ceil(1 * $heightRatio);
+                    $newHeight = ceil($oldHeight * $heightRatio) + floor(1 * $heightRatio);
+
+                    $newPairedString[] = implode(';', [$newX, $newY]);
+                    $newPairedString[] = $newWidth;
+                    $newPairedString[] = $newHeight;
+                    break;
+
+                case 'circle':
+                    $oldCenter = explode(';', $oldPairedString[0]);
+
+                    $oldCenterX = intval($oldCenter[0]);
+                    $oldCenterY = intval($oldCenter[1]);
+                    $oldRadiusX = intval($oldPairedString[1]) / 2;
+                    $oldRadiusY = intval($oldPairedString[2]) / 2;
+
+                    $newCenterX = floor($oldCenterX * $widthRatio) + ceil($widthRatio);
+                    $newCenterY = floor($oldCenterY * $heightRatio) + ceil($heightRatio);
+                    $newRadiusX = floor($oldRadiusX * $widthRatio);
+                    $newRadiusY = floor($oldRadiusY * $heightRatio);
+
+                    $newPairedString[] = implode(';', [$newCenterX, $newCenterY]);
+                    $newPairedString[] = $newRadiusX;
+                    $newPairedString[] = $newRadiusY;
+                    break;
+
+                case 'poly':
+                    //no break;
+                case 'delineation':
+                    //no break
+                case 'oar':
+                    $paired = [];
+
+                    foreach ($oldPairedString as $pairString) {
+                        $pair = explode(';', $pairString);
+                        $x = isset($pair[0]) ? intval($pair[0]) : 0;
+                        $y = isset($pair[1]) ? intval($pair[1]) : 0;
+
+                        $paired[] = [$x, $y];
+                    }
+
+                    foreach ($paired as $pair) {
+                        $x = floor($pair[0] * $widthRatio) + ceil($widthRatio);
+                        $y = ceil($pair[1] * $heightRatio);
+
+                        $newPairedString[] = implode(';', [$x, $y]);
+                    }
+                    break;
+            }
+
+            $stmt = $this->connection->prepare("
+                UPDATE c_quiz_answer
+                SET hotspot_coordinates = :coordinates
+                WHERE iid = :iid AND c_id = :cid
+            ");
+            $stmt->bindValue('coordinates', implode('|', $newPairedString), Type::TEXT);
+            $stmt->bindValue('iid', $answer['iid'], Type::INTEGER);
+            $stmt->bindValue('cid', $answer['c_id'], Type::INTEGER);
+            $stmt->execute();
+        }
+    }
+
+    /**
+     * @param Schema $schema
+     */
+    public function down(Schema $schema)
+    {
+    }
+}

+ 52 - 0
app/Migrations/Schema/V110/Version20151221150100.php

@@ -0,0 +1,52 @@
+<?php
+/* For licensing terms, see /license.txt */
+
+namespace Application\Migrations\Schema\V110;
+
+use Application\Migrations\AbstractMigrationChamilo;
+use Doctrine\DBAL\Schema\Schema;
+
+/**
+ * Fix c_quiz_answer's correct field for id_auto
+ */
+class Version20151221150100 extends AbstractMigrationChamilo
+{
+    /**
+     * @param Schema $schema
+     */
+    public function up(Schema $schema)
+    {
+        $this->addSql("
+            UPDATE track_e_attempt a
+            INNER JOIN c_quiz_answer qa
+            ON a.question_id = qa.question_id
+            INNER JOIN c_quiz_question q
+            ON qa.question_id = q.id
+            SET a.answer = qa.id_auto
+            WHERE
+                a.answer = qa.id AND
+                q.c_id = a.c_id AND
+                q.type IN (" . MATCHING . ", " . DRAGGABLE . ", " . MATCHING_DRAGGABLE . ")
+        ");
+
+        $this->addSql("
+            UPDATE c_quiz_answer a
+            INNER JOIN c_quiz_answer b
+            ON a.question_id = b.question_id
+            INNER JOIN c_quiz_question q
+            ON b.question_id = q.id
+            SET a.correct = b.id_auto
+            WHERE
+                a.correct = b.id AND
+                q.c_id = a.c_id AND
+                q.type IN (" . MATCHING . ", " . DRAGGABLE . ", " . MATCHING_DRAGGABLE . ")
+        ");
+    }
+
+    /**
+     * @param Schema $schema
+     */
+    public function down(Schema $schema)
+    {
+    }
+}

+ 29 - 0
app/Migrations/Schema/V110/Version20160707131900.php

@@ -0,0 +1,29 @@
+<?php
+/* For licensing terms, see /license.txt */
+
+namespace Application\Migrations\Schema\V110;
+
+use Application\Migrations\AbstractMigrationChamilo;
+use Doctrine\DBAL\Schema\Schema;
+
+/**
+ * Fix c_quiz_answer's correct field for id_auto
+ */
+class Version20160707131900 extends AbstractMigrationChamilo
+{
+    /**
+     * @param Schema $schema
+     */
+    public function up(Schema $schema)
+    {
+        $this->addSql(" 
+            ALTER TABLE c_quiz_answer ADD INDEX idx_cqa_q (question_id)");
+    }
+
+    /**
+     * @param Schema $schema
+     */
+    public function down(Schema $schema)
+    {
+    }
+}

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

@@ -278,14 +278,19 @@ class Version111 extends AbstractMigrationChamilo
         $this->addSql("INSERT INTO settings_options (variable, value, display_text) VALUES ('show_link_ticket_notification', 'true', 'Yes'), ('show_link_ticket_notification', 'false', 'No')");
 
         $this->addSql("ALTER TABLE c_quiz_question_rel_category ADD INDEX idx_qqrc_qid (question_id)");
-        $this->addSql("ALTER TABLE c_quiz_answer ADD INDEX idx_cqa_q (question_id)");
+        $table = $schema->getTable('c_quiz_answer');
+        $hasIndex = $table->hasIndex('idx_cqa_q');
+        if (!$hasIndex) {
+            $this->addSql("ALTER TABLE c_quiz_answer ADD INDEX idx_cqa_q (question_id)");
+        }
         $this->addSql("ALTER TABLE c_student_publication ADD INDEX idx_csp_u (user_id)");
 
+        $this->addSql('ALTER TABLE legal MODIFY COLUMN language_id INT NOT NULL');
+        $this->addSql('ALTER TABLE legal MODIFY COLUMN legal_id INT NOT NULL');
         $this->addSql('ALTER TABLE legal DROP PRIMARY KEY;');
         $this->addSql('ALTER TABLE legal ADD id INT');
         $this->addSql('UPDATE legal SET id = legal_id');
         $this->addSql('UPDATE legal SET id = 1 WHERE id = 0');
-        $this->addSql('ALTER TABLE legal MODIFY COLUMN language_id INT NOT NULL');
         $this->addSql('ALTER TABLE legal DROP legal_id');
         $this->addSql('ALTER TABLE legal CHANGE id id INT AUTO_INCREMENT NOT NULL PRIMARY KEY;');
 

+ 25 - 6
app/Migrations/Schema/V111/Version20160330103045.php

@@ -2,13 +2,13 @@
 
 namespace Application\Migrations\Schema\V111;
 
-use Doctrine\DBAL\Migrations\AbstractMigration;
+use Application\Migrations\AbstractMigrationChamilo;
 use Doctrine\DBAL\Schema\Schema;
 
 /**
  * Auto-generated Migration: Please modify to your needs!
  */
-class Version20160330103045 extends AbstractMigration
+class Version20160330103045 extends AbstractMigrationChamilo
 {
     /**
      * @param Schema $schema
@@ -109,11 +109,30 @@ class Version20160330103045 extends AbstractMigration
         //$this->addSql("CREATE UNIQUE INDEX UNIQ_8D93D649A0D96FBF ON user (email_canonical);");
         */
         $this->addSql('DROP TABLE extra_field_saved_search');
-        $this->addSql('DROP INDEX user_sco_course_sv_stack ON track_stored_values_stack');
-        $this->addSql('ALTER TABLE session_rel_user ADD duration INT DEFAULT NULL');
-        $this->addSql('DROP INDEX user_sco_course_sv ON track_stored_values');
+        $table = $schema->getTable('track_stored_values_stack');
+        $hasIndex = $table->hasIndex('user_sco_course_sv_stack');
+        if ($hasIndex) {
+            $this->addSql('DROP INDEX user_sco_course_sv_stack ON track_stored_values_stack');
+        }
+
+        $table = $schema->getTable('session_rel_user');
+        $hasColumn = $table->hasColumn('duration');
+        if (!$hasColumn) {
+            $this->addSql('ALTER TABLE session_rel_user ADD duration INT DEFAULT NULL');
+        }
+
+        $table = $schema->getTable('track_stored_values');
+        $hasIndex = $table->hasIndex('user_sco_course_sv');
+        if ($hasIndex) {
+            $this->addSql('DROP INDEX user_sco_course_sv ON track_stored_values');
+        }
+
+        $table = $schema->getTable('user');
+        $hasIndex = $table->hasIndex('UNIQ_8D93D649F85E0677');
+        if ($hasIndex) {
+            $this->addSql('DROP INDEX UNIQ_8D93D649F85E0677 ON user');
+        }
 
-        $this->addSql('DROP INDEX UNIQ_8D93D649F85E0677 ON user');
         $this->addSql(
             'ALTER TABLE user ADD email_canonical VARCHAR(255) NOT NULL, ADD credentials_expired TINYINT(1), ADD credentials_expire_at DATETIME DEFAULT NULL, ADD locked TINYINT(1),ADD enabled TINYINT(1) NOT NULL, ADD expired TINYINT(1) NOT NULL, ADD expires_at DATETIME DEFAULT NULL, CHANGE username username VARCHAR(255) NOT NULL, CHANGE username_canonical username_canonical VARCHAR(255) NOT NULL, CHANGE email email VARCHAR(255) NOT NULL'
         );

+ 2 - 2
app/Migrations/Schema/V111/Version20160405112100.php

@@ -2,10 +2,10 @@
 
 namespace Application\Migrations\Schema\V111;
 
-use Doctrine\DBAL\Migrations\AbstractMigration;
+use Application\Migrations\AbstractMigrationChamilo;
 use Doctrine\DBAL\Schema\Schema;
 
-class Version20160405112100 extends AbstractMigration
+class Version20160405112100 extends AbstractMigrationChamilo
 {
     /**
      * @param Schema $schema

+ 48 - 37
app/Resources/public/css/base.css

@@ -5368,13 +5368,11 @@ div#chat-remote-video video {
 }
 #whoisonline .items-user{
   text-align: center;
-  /*border:1px solid #dddddd; */
   padding: 15px;
   border-radius: 4px;
   -moz-border-radius: 4px;
   -webkit-border-radius: 4px;
-  box-shadow: 0 2px 3px #C8C8C8;
-  border: 1px solid #e6e6e6;
+  border: 1px solid #ECF0F1;
   margin-bottom: 20px;
   min-height: 230px;
 }
@@ -5803,6 +5801,41 @@ footer{
     margin-bottom: 2px;
 }
 /* CSS BACKUP *****/
+.elfinder-cwd-filename {
+    color: black !important;
+}
+.skill-badge-img{
+    width: 150px;
+    overflow: hidden;
+}
+.text-light{
+    color: #00CCFF;
+}
+#dropzone {
+    position: relative;
+    overflow: hidden;
+    direction: ltr;
+    cursor: pointer;
+    text-align: center;
+    color: #333;
+    font-weight: bold;
+    -moz-border-radius: 10px;
+    -webkit-border-radius: 10px;
+    border-radius: 10px;
+    width: auto;
+    margin-left: auto;
+    margin-right: auto;
+    height: auto;
+    line-height: 50px;
+    background-color: #D4E6F0;
+    border: 2px dashed #bbbbbb;
+    font-size: 120%;
+    margin-bottom: 0;
+}
+
+#upload_form .fa-plus-square-o, #upload_form .fa-minus-square-o {
+    cursor:pointer;
+}
 .item-backup{
     padding-top: 5px;
     padding-bottom: 5px;
@@ -5831,6 +5864,18 @@ footer{
 #invitations-acordion .list-group .list-group-item img{
     margin-right: 5px;
 }
+.block-invitation{
+    padding:10px;
+    border-radius: 5px;
+    border: 1px solid #ECF0F1;
+    margin-bottom: 10px;
+}
+.block-invitation .date-invitation{
+    font-size: 12px;
+}
+.block-invitation .title-profile{
+    font-weight: bold;
+}
 /* CSS NEW TOP ******************************************************************************/
 /* CSS Responsive */
 @media (min-width: 1025px) and (max-width: 1200px) {
@@ -6034,41 +6079,7 @@ footer{
         margin: -2.5px -15px;
     }
 }
-.elfinder-cwd-filename {
-    color: black !important;
-}
-.skill-badge-img{
-    width: 150px;
-    overflow: hidden;
-}
-.text-light{
-    color: #00CCFF;
-}
-#dropzone {
-    position: relative;
-    overflow: hidden;
-    direction: ltr;
-    cursor: pointer;
-    text-align: center;
-    color: #333;
-    font-weight: bold;
-    -moz-border-radius: 10px;
-    -webkit-border-radius: 10px;
-    border-radius: 10px;
-    width: auto;
-    margin-left: auto;
-    margin-right: auto;
-    height: auto;
-    line-height: 50px;
-    background-color: #D4E6F0;
-    border: 2px dashed #bbbbbb;
-    font-size: 120%;
-    margin-bottom: 0;
-}
 
-#upload_form .fa-plus-square-o, #upload_form .fa-minus-square-o {
-    cursor:pointer;
-}
 
 @-moz-keyframes wobblebar-loader {
     0% {

+ 1 - 1
app/console

@@ -1,6 +1,6 @@
 #!/usr/bin/env php
 <?php
-
+exit;
 use Symfony\Bundle\FrameworkBundle\Console\Application;
 use Symfony\Component\Console\Input\ArgvInput;
 use Symfony\Component\Debug\Debug;

+ 6 - 6
main/admin/email_tester.php

@@ -17,12 +17,12 @@ $this_section = SECTION_PLATFORM_ADMIN;
 $toolName = get_lang('EMailTester');
 
 $form = new FormValidator('email_tester');
-$form->addText('smtp_host', get_lang('Host'), false, ['cols-size' => [3, 8, 1]]);
-$form->addText('smtp_port', get_lang('Port'), false, ['cols-size' => [3, 8, 1]]);
-$form->addText('destination', get_lang('Destination'), true, ['cols-size' => [3, 8, 1]]);
-$form->addText('subject', get_lang('Subject'), true, ['cols-size' => [3, 8, 1]]);
-$form->addHtmlEditor('content', get_lang('Message'), true, false, ['ToolbarSet' => 'Minimal', 'cols-size' => [3, 8, 1]]);
-$form->addButtonSend(get_lang('SendMessage'), 'submit', false, ['cols-size' => [3, 8, 1]]);
+$form->addText('smtp_host', get_lang('Host'), false, ['cols-size' => [2, 8, 2]]);
+$form->addText('smtp_port', get_lang('Port'), false, ['cols-size' => [2, 8, 2]]);
+$form->addText('destination', get_lang('Destination'), true, ['cols-size' => [2, 8, 2]]);
+$form->addText('subject', get_lang('Subject'), true, ['cols-size' => [2, 8, 2]]);
+$form->addHtmlEditor('content', get_lang('Message'), true, false, ['ToolbarSet' => 'Minimal', 'cols-size' => [2, 8, 2]]);
+$form->addButtonSend(get_lang('SendMessage'), 'submit', false, ['cols-size' => [2, 8, 2]]);
 $form->setDefaults([
     'smtp_host' => $platform_email['SMTP_HOST'],
     'smtp_port' => $platform_email['SMTP_PORT']

+ 1 - 1
main/auth/profile.php

@@ -340,7 +340,7 @@ if (is_profile_editable() && api_get_setting('profile', 'picture') == 'true') {
         ($user_data['picture_uri'] != '' ? get_lang('UpdateImage') : get_lang(
             'AddImage'
         )),
-        array('id' => 'picture', 'class' => 'picture-form', 'crop_image' => true, 'crop_ratio' => '16 / 9')
+        array('id' => 'picture', 'class' => 'picture-form', 'crop_image' => true, 'crop_ratio' => '1 / 1')
     );
 
     $form->add_progress_bar();

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

@@ -25,7 +25,9 @@ switch ($action) {
             UserManager::relate_users($current_user_id, $my_current_friend, $relation_type);
             UserManager::relate_users($my_current_friend, $current_user_id, $relation_type);
             SocialManager::invitation_accepted($my_current_friend, $current_user_id);
-            Display::display_normal_message(api_xml_http_response_encode(get_lang('AddedContactToList')));
+            Display::addFlash(
+                Display::return_message(get_lang('AddedContactToList'), 'success')
+            );
 
             header('Location: ' . api_get_path(WEB_CODE_PATH) . 'social/invitations.php');
         }

+ 0 - 36
main/inc/lib/api.lib.php

@@ -5698,42 +5698,6 @@ function api_is_element_in_the_session($tool, $element_id, $session_id = null) {
 function api_replace_dangerous_char($filename)
 {
     return URLify::filter($filename, 250, '', true);
-
-    /*
-    // Safe replacements for some non-letter characters.
-    static $search  = array(',', "\0", ' ', "\t", "\n", "\r", "\x0B", '/', "\\", '"', "'", '?', '*', '>', '<', '|', ':', '$', '(', ')', '^', '[', ']', '#', '+', '&', '%');
-    static $replace = array('_', '', '_', '_', '_', '_', '_', '-', '-', '-', '_', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-');
-
-    // Encoding detection.
-    $encoding = api_detect_encoding($filename);
-    // Converting html-entities into encoded characters.
-    $filename = api_html_entity_decode($filename, ENT_QUOTES, $encoding);
-    // Transliteration to ASCII letters, they are not dangerous for filesystems.
-    $filename = api_transliterate($filename, 'x', $encoding);
-
-    // Trimming leading/trailing whitespace.
-    $filename = trim($filename);
-    // Trimming any leading/trailing dots.
-    $filename = trim($filename, '.');
-    $filename = trim($filename);
-
-    // Replacing remaining dangerous non-letter characters.
-    $filename = str_replace($search, $replace, $filename);
-    if ($strict == 'strict') {
-        //$filename = str_replace('-', '_', $filename); // See task #1848.
-        //$filename = preg_replace('/[^0-9A-Za-z_.\-]/', '', $filename);
-        //Removing "_" character see BT#3628
-        $filename = preg_replace('/[^0-9A-Za-z.\-_]/', '', $filename);
-    }
-
-    // Length is to be limited, so the file name to be acceptable by some operating systems.
-    $extension = (string)strrchr($filename, '.');
-    $extension_len = strlen($extension);
-    if ($extension_len > 0 && $extension_len < 250) {
-        $filename = substr($filename, 0, -$extension_len);
-        return substr($filename, 0, 250 - $extension_len).$extension;
-    }
-    return substr($filename, 0, 250);*/
 }
 
 /**

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

@@ -1387,7 +1387,7 @@ class DocumentManager
             return false;
         }
 
-        $session_id = is_null($session_id) ? api_get_session_id() : intval($session_id);
+        $session_id = empty($session_id) ? api_get_session_id() : intval($session_id);
 
         $www = api_get_path(WEB_COURSE_PATH).$course_info['path'].'/document';
 

+ 17 - 10
main/inc/lib/fileUpload.lib.php

@@ -42,7 +42,8 @@ function htaccess2txt($filename) {
  * @see php2phps()
  * @see htaccess2txt()
  */
-function disable_dangerous_file($filename) {
+function disable_dangerous_file($filename)
+{
     return htaccess2txt(php2phps($filename));
 }
 
@@ -1121,14 +1122,17 @@ function unzip_uploaded_document(
  * This function is a callback function that is used while extracting a zipfile
  * http://www.phpconcept.net/pclzip/man/en/index.php?options-pclzip_cb_pre_extract
  *
- * @param object $p_event
- * @param object $p_header
+ * @param array $p_event
+ * @param array $p_header
  * @return int (If the function returns 1, then the extraction is resumed, if 0 the path was skipped)
  */
 function clean_up_files_in_zip($p_event, &$p_header)
 {
-    $res = clean_up_path($p_header['filename']);
-    return $res;
+    $originalStoredFileName = $p_header['stored_filename'];
+    $modifiedStoredFileName = clean_up_path($originalStoredFileName);
+    $p_header['filename'] = str_replace($originalStoredFileName, $modifiedStoredFileName, $p_header['filename']);
+
+    return 1;
 }
 
 /**
@@ -1136,15 +1140,17 @@ function clean_up_files_in_zip($p_event, &$p_header)
  * by eliminating dangerous file names and cleaning them
  *
  * @param string $path
- * @return $path
+ *
+ * @return string
+ *
  * @see disable_dangerous_file()
  * @see api_replace_dangerous_char()
  */
-function clean_up_path(&$path)
+function clean_up_path($path)
 {
     // Split the path in folders and files
     $path_array = explode('/', $path);
-    // Clean up every foler and filename in the path
+    // Clean up every folder and filename in the path
     foreach ($path_array as $key => & $val) {
         // We don't want to lose the dots in ././folder/file (cfr. zipfile)
         if ($val != '.') {
@@ -1153,8 +1159,9 @@ function clean_up_path(&$path)
     }
     // Join the "cleaned" path (modified in-place as passed by reference)
     $path = implode('/', $path_array);
-    $res = filter_extension($path);
-    return $res;
+    filter_extension($path);
+
+    return $path;
 }
 
 /**

+ 21 - 21
main/inc/lib/usermanager.lib.php

@@ -3849,31 +3849,31 @@ class UserManager
                     VALUES ('.$friend_id.','.$my_user_id.','.$relation_type.',"'.$current_date.'")';
             Database::query($sql);
             return true;
-        } else {
-            $sql = 'SELECT COUNT(*) as count, relation_type  FROM '.$tbl_my_friend.'
-                    WHERE
-                        friend_user_id='.$friend_id.' AND
-                        user_id='.$my_user_id.' AND
-                        relation_type <> '.USER_RELATION_TYPE_RRHH.' ';
-            $result = Database::query($sql);
-            $row = Database :: fetch_array($result, 'ASSOC');
-            if ($row['count'] == 1) {
-                //only for the case of a RRHH
-                if ($row['relation_type'] != $relation_type && $relation_type == USER_RELATION_TYPE_RRHH) {
-                    $sql = 'INSERT INTO '.$tbl_my_friend.'(friend_user_id,user_id,relation_type,last_edit)
-                            VALUES ('.$friend_id.','.$my_user_id.','.$relation_type.',"'.$current_date.'")';
-                } else {
-                    $sql = 'UPDATE '.$tbl_my_friend.' SET relation_type='.$relation_type.'
-                            WHERE friend_user_id='.$friend_id.' AND user_id='.$my_user_id;
-                }
-                Database::query($sql);
+        }
 
-                return true;
-            } else {
+        $sql = 'SELECT COUNT(*) as count, relation_type  FROM '.$tbl_my_friend.'
+                WHERE
+                    friend_user_id='.$friend_id.' AND
+                    user_id='.$my_user_id.' AND
+                    relation_type <> '.USER_RELATION_TYPE_RRHH.' ';
+        $result = Database::query($sql);
+        $row = Database :: fetch_array($result, 'ASSOC');
 
-                return false;
+        if ($row['count'] == 1) {
+            //only for the case of a RRHH
+            if ($row['relation_type'] != $relation_type && $relation_type == USER_RELATION_TYPE_RRHH) {
+                $sql = 'INSERT INTO '.$tbl_my_friend.'(friend_user_id,user_id,relation_type,last_edit)
+                        VALUES ('.$friend_id.','.$my_user_id.','.$relation_type.',"'.$current_date.'")';
+            } else {
+                $sql = 'UPDATE '.$tbl_my_friend.' SET relation_type='.$relation_type.'
+                        WHERE friend_user_id='.$friend_id.' AND user_id='.$my_user_id;
             }
+            Database::query($sql);
+
+            return true;
         }
+
+        return false;
     }
 
     /**

+ 10 - 13
main/install/index.php

@@ -682,6 +682,9 @@ if (@$_POST['step2']) {
 
         error_log('Starting migration process from '.$my_old_version.' ('.date('Y-m-d H:i:s').')');
 
+        echo '<a class="btn btn-default" href="javascript:void(0)" id="details_button">'.get_lang('Details').'</a><br />';
+        echo '<div id="details" style="display:none">';
+
         switch ($my_old_version) {
             case '1.9.0':
             case '1.9.2':
@@ -705,8 +708,6 @@ if (@$_POST['step2']) {
                 Database::query("ALTER TABLE c_document MODIFY COLUMN filetype char(10) NOT NULL default 'file'");
                 Database::query("ALTER TABLE c_student_publication MODIFY COLUMN filetype char(10) NOT NULL default 'file'");
 
-                echo '<a class="btn btn-default" href="javascript:void(0)" id="details_button">'.get_lang('Details').'</a><br />';
-                echo '<div id="details" style="display:none">';
                 // Migrate using the migration files located in:
                 // src/Chamilo/CoreBundle/Migrations/Schema/V110
                 $result = migrate(
@@ -714,8 +715,6 @@ if (@$_POST['step2']) {
                     $manager
                 );
 
-                echo '</div>';
-
                 if ($result) {
                     error_log('Migrations files were executed.');
 
@@ -746,18 +745,17 @@ if (@$_POST['step2']) {
                         }
                     }
 
-                    error_log('Upgrade process concluded! ('.date('Y-m-d H:i:s').')');
+                    error_log('Upgrade 1.10.x process concluded! ('.date('Y-m-d H:i:s').')');
                 } else {
                     error_log('There was an error during running migrations. Check error.log');
+                    break;
                 }
-                //TODO: check if this can be used to migrate directly from 1.9 to 1.11
-                break;
             case '1.10.0':
                 // no break
             case '1.10.2':
-            // no break
+                // no break
             case '1.10.4':
-            // no break
+                // no break
             case '1.10.6':
                 // Migrate using the migration files located in:
                 // src/Chamilo/CoreBundle/Migrations/Schema/V111
@@ -766,12 +764,10 @@ if (@$_POST['step2']) {
                     $manager
                 );
 
-                echo '</div>';
-
                 if ($result) {
                     error_log('Migrations files were executed.');
                     include 'update-files-1.10.0-1.11.0.inc.php';
-                    error_log('Upgrade process concluded!  ('.date('Y-m-d H:i:s').')');
+                    error_log('Upgrade 1.11.x process concluded!  ('.date('Y-m-d H:i:s').')');
                 } else {
                     error_log('There was an error during running migrations. Check error.log');
                 }
@@ -779,6 +775,7 @@ if (@$_POST['step2']) {
             default:
                 break;
         }
+        echo '</div>';
     } else {
         set_file_folder_permissions();
 
@@ -915,7 +912,7 @@ if (@$_POST['step2']) {
         $connection->executeQuery("ALTER TABLE faq_question ADD CONSTRAINT FK_4A55B05912469DE2 FOREIGN KEY (category_id) REFERENCES faq_category (id);");
         */
         // Add version table
-        $connection->executeQuery('CREATE TABLE version (version varchar(255), PRIMARY KEY(version))');
+        $connection->executeQuery('CREATE TABLE version (id int unsigned NOT NULL AUTO_INCREMENT, version varchar(255), PRIMARY KEY(id), UNIQUE(version))');
 
         // Tickets
         $table = Database::get_main_table(TABLE_TICKET_PROJECT);

+ 606 - 0
main/install/install.lib.php

@@ -2070,6 +2070,561 @@ function fixIds(EntityManager $em)
         error_log('fixIds');
     }
 
+    // Create temporary indexes to increase speed of the following operations
+    // Adding and removing indexes will usually take much less time than
+    // the execution without indexes of the queries in this function, particularly
+    // for large tables
+    $sql = "ALTER TABLE c_document ADD INDEX tmpidx_doc(c_id, id)";
+    $connection->executeQuery($sql);
+    $sql = "ALTER TABLE c_student_publication ADD INDEX tmpidx_stud (c_id, id)";
+    $connection->executeQuery($sql);
+    $sql = "ALTER TABLE c_quiz ADD INDEX tmpidx_quiz (c_id, id)";
+    $connection->executeQuery($sql);
+    $sql = "ALTER TABLE c_item_property ADD INDEX tmpidx_ip (to_group_id)";
+    $connection->executeQuery($sql);
+
+    $sql = "SELECT * FROM c_lp_item";
+    $result = $connection->fetchAll($sql);
+    foreach ($result as $item) {
+        $courseId = $item['c_id'];
+        $iid = isset($item['iid']) ? intval($item['iid']) : 0;
+        $ref = isset($item['ref']) ? intval($item['ref']) : 0;
+        $sql = null;
+
+        $newId = '';
+
+        switch ($item['item_type']) {
+            case TOOL_LINK:
+                $sql = "SELECT * FROM c_link WHERE c_id = $courseId AND id = $ref";
+                $data = $connection->fetchAssoc($sql);
+                if ($data) {
+                    $newId = $data['iid'];
+                }
+                break;
+            case TOOL_STUDENTPUBLICATION:
+                $sql = "SELECT * FROM c_student_publication WHERE c_id = $courseId AND id = $ref";
+                $data = $connection->fetchAssoc($sql);
+                if ($data) {
+                    $newId = $data['iid'];
+                }
+                break;
+            case TOOL_QUIZ:
+                $sql = "SELECT * FROM c_quiz WHERE c_id = $courseId AND id = $ref";
+                $data = $connection->fetchAssoc($sql);
+                if ($data) {
+                    $newId = $data['iid'];
+                }
+                break;
+            case TOOL_DOCUMENT:
+                $sql = "SELECT * FROM c_document WHERE c_id = $courseId AND id = $ref";
+                $data = $connection->fetchAssoc($sql);
+                if ($data) {
+                    $newId = $data['iid'];
+                }
+                break;
+            case TOOL_FORUM:
+                $sql = "SELECT * FROM c_forum_forum WHERE c_id = $courseId AND forum_id = $ref";
+                $data = $connection->fetchAssoc($sql);
+                if ($data) {
+                    $newId = $data['iid'];
+                }
+                break;
+            case 'thread':
+                $sql = "SELECT * FROM c_forum_thread WHERE c_id = $courseId AND thread_id = $ref";
+                $data = $connection->fetchAssoc($sql);
+                if ($data) {
+                    $newId = $data['iid'];
+                }
+                break;
+        }
+
+        if (!empty($sql) && !empty($newId) && !empty($iid)) {
+            $sql = "UPDATE c_lp_item SET ref = $newId WHERE iid = $iid";
+
+            $connection->executeQuery($sql);
+        }
+    }
+
+    // Set NULL if session = 0
+    $sql = "UPDATE c_item_property SET session_id = NULL WHERE session_id = 0";
+    $connection->executeQuery($sql);
+
+    // Set NULL if group = 0
+    $sql = "UPDATE c_item_property SET to_group_id = NULL WHERE to_group_id = 0";
+    $connection->executeQuery($sql);
+
+    // Set NULL if insert_user_id = 0
+    $sql = "UPDATE c_item_property SET insert_user_id = NULL WHERE insert_user_id = 0";
+    $connection->executeQuery($sql);
+
+    // Delete session data of sessions that don't exist.
+    $sql = "DELETE FROM c_item_property
+            WHERE session_id IS NOT NULL AND session_id NOT IN (SELECT id FROM session)";
+    $connection->executeQuery($sql);
+
+    // Delete group data of groups that don't exist.
+    $sql = "DELETE FROM c_item_property
+            WHERE to_group_id IS NOT NULL AND to_group_id NOT IN (SELECT DISTINCT id FROM c_group_info)";
+    $connection->executeQuery($sql);
+
+    // This updates the group_id with c_group_info.iid instead of c_group_info.id
+
+    if ($debug) {
+        error_log('update iids');
+    }
+
+    $groupTableToFix = [
+        'c_group_rel_user',
+        'c_group_rel_tutor',
+        'c_permission_group',
+        'c_role_group',
+        'c_survey_invitation',
+        'c_attendance_calendar_rel_group'
+    ];
+
+    foreach ($groupTableToFix as $table) {
+        $sql = "SELECT * FROM $table";
+        $result = $connection->fetchAll($sql);
+        foreach ($result as $item) {
+            $iid = $item['iid'];
+            $courseId = $item['c_id'];
+            $groupId = intval($item['group_id']);
+
+            // Fix group id
+            if (!empty($groupId)) {
+                $sql = "SELECT * FROM c_group_info
+                        WHERE c_id = $courseId AND id = $groupId
+                        LIMIT 1";
+                $data = $connection->fetchAssoc($sql);
+                if (!empty($data)) {
+                    $newGroupId = $data['iid'];
+                    $sql = "UPDATE $table SET group_id = $newGroupId
+                            WHERE iid = $iid";
+                    $connection->executeQuery($sql);
+                } else {
+                    // The group does not exists clean this record
+                    $sql = "DELETE FROM $table WHERE iid = $iid";
+                    $connection->executeQuery($sql);
+                }
+            }
+        }
+    }
+
+    // Fix c_item_property
+    if ($debug) {
+        error_log('update c_item_property');
+    }
+
+    $sql = "SELECT * FROM course";
+    $courseList = $connection->fetchAll($sql);
+    if ($debug) {
+        error_log('Getting course list');
+    }
+
+    $totalCourse = count($courseList);
+    $counter = 0;
+
+    foreach ($courseList as $courseData) {
+        $courseId = $courseData['id'];
+        if ($debug) {
+            error_log('Updating course: '.$courseData['code']);
+        }
+
+        $sql = "SELECT * FROM c_item_property WHERE c_id = $courseId";
+        $result = $connection->fetchAll($sql);
+
+        foreach ($result as $item) {
+            //$courseId = $item['c_id'];
+            $sessionId = intval($item['session_id']);
+            $groupId = intval($item['to_group_id']);
+            $iid = $item['iid'];
+            $ref = $item['ref'];
+
+            // Fix group id
+            if (!empty($groupId)) {
+                $sql = "SELECT * FROM c_group_info
+                        WHERE c_id = $courseId AND id = $groupId";
+                $data = $connection->fetchAssoc($sql);
+                if (!empty($data)) {
+                    $newGroupId = $data['iid'];
+                    $sql = "UPDATE c_item_property SET to_group_id = $newGroupId
+                            WHERE iid = $iid";
+                    $connection->executeQuery($sql);
+                } else {
+                    // The group does not exists clean this record
+                    $sql = "DELETE FROM c_item_property WHERE iid = $iid";
+                    $connection->executeQuery($sql);
+                }
+            }
+
+            $sql = '';
+            $newId = '';
+            switch ($item['tool']) {
+                case TOOL_LINK:
+                    $sql = "SELECT * FROM c_link WHERE c_id = $courseId AND id = $ref ";
+                    break;
+                case TOOL_STUDENTPUBLICATION:
+                    $sql = "SELECT * FROM c_student_publication WHERE c_id = $courseId AND id = $ref";
+                    break;
+                case TOOL_QUIZ:
+                    $sql = "SELECT * FROM c_quiz WHERE c_id = $courseId AND id = $ref";
+                    break;
+                case TOOL_DOCUMENT:
+                    $sql = "SELECT * FROM c_document WHERE c_id = $courseId AND id = $ref";
+                    break;
+                case TOOL_FORUM:
+                    $sql = "SELECT * FROM c_forum_forum WHERE c_id = $courseId AND id = $ref";
+                    break;
+                case 'thread':
+                    $sql = "SELECT * FROM c_forum_thread WHERE c_id = $courseId AND id = $ref";
+                    break;
+            }
+
+            if (!empty($sql) && !empty($newId)) {
+                $data = $connection->fetchAssoc($sql);
+                if (isset($data['iid'])) {
+                    $newId = $data['iid'];
+                }
+                $sql = "UPDATE c_item_property SET ref = $newId WHERE iid = $iid";
+                error_log($sql);
+                $connection->executeQuery($sql);
+            }
+
+            if ($debug) {
+                // Print a status in the log once in a while
+                error_log("Process item #$counter/$totalCourse");
+            }
+            $counter++;
+        }
+    }
+
+    if ($debug) {
+        error_log('update gradebook_link');
+    }
+
+    // Fix gradebook_link
+    $sql = "SELECT * FROM gradebook_link";
+    $result = $connection->fetchAll($sql);
+    foreach ($result as $item) {
+        $courseCode = $item['course_code'];
+        $courseInfo = api_get_course_info($courseCode);
+
+        if (empty($courseInfo)) {
+            continue;
+        }
+        $courseId = $courseInfo['real_id'];
+        $ref = $item['ref_id'];
+        $iid = $item['id'];
+        $sql = '';
+
+        switch ($item['type']) {
+            case LINK_LEARNPATH:
+                $sql = "SELECT * FROM c_link WHERE c_id = $courseId AND id = $ref ";
+                break;
+            case LINK_STUDENTPUBLICATION:
+                $sql = "SELECT * FROM c_student_publication WHERE c_id = $courseId AND id = $ref";
+                break;
+            case LINK_EXERCISE:
+                $sql = "SELECT * FROM c_quiz WHERE c_id = $courseId AND id = $ref";
+                break;
+            case LINK_ATTENDANCE:
+                //$sql = "SELECT * FROM c_document WHERE c_id = $courseId AND id = $ref";
+                break;
+            case LINK_FORUM_THREAD:
+                $sql = "SELECT * FROM c_forum_thread WHERE c_id = $courseId AND thread_id = $ref";
+                break;
+        }
+
+        if (!empty($sql)) {
+            $data = $connection->fetchAssoc($sql);
+            if (isset($data) && isset($data['iid'])) {
+                $newId = $data['iid'];
+                $sql = "UPDATE gradebook_link SET ref_id = $newId
+                        WHERE id = $iid";
+                $connection->executeQuery($sql);
+            }
+        }
+    }
+
+    if ($debug) {
+        error_log('update groups');
+    }
+
+    $sql = "SELECT * FROM groups";
+    $result = $connection->executeQuery($sql);
+    $groups = $result->fetchAll();
+
+    $oldGroups = array();
+
+    if (!empty($groups)) {
+        foreach ($groups as $group) {
+            if (empty($group['name'])) {
+                continue;
+            }
+
+            /*$group['description'] = Database::escape_string($group['description']);
+            $group['name'] = Database::escape_string($group['name']);
+            $sql = "INSERT INTO usergroup (name, group_type, description, picture, url, visibility, updated_at, created_at)
+                    VALUES ('{$group['name']}', '1', '{$group['description']}', '{$group['picture_uri']}', '{$group['url']}', '{$group['visibility']}', '{$group['updated_on']}', '{$group['created_on']}')";
+            */
+            $params = [
+                'name' => $group['name'],
+                'description' => $group['description'],
+                'group_type' => 1,
+                'picture' => $group['picture_uri'],
+                'url' => $group['url'],
+                'visibility' => $group['visibility'],
+                'updated_at' => $group['updated_on'],
+                'created_at' => $group['created_on']
+            ];
+            $connection->insert('usergroup', $params);
+            //$connection->executeQuery($sql);
+            $id = $connection->lastInsertId('id');
+            $oldGroups[$group['id']] = $id;
+        }
+    }
+
+    if (!empty($oldGroups)) {
+        foreach ($oldGroups as $oldId => $newId) {
+            $path = get_group_picture_path_by_id(
+                $oldId,
+                'system'
+            );
+
+            if (!empty($path)) {
+                $newPath = str_replace(
+                    "groups/$oldId/",
+                    "groups/$newId/",
+                    $path['dir']
+                );
+                $command = "mv {$path['dir']} $newPath ";
+                system($command);
+            }
+        }
+
+        $sql = "SELECT * FROM group_rel_user";
+        $result = $connection->executeQuery($sql);
+        $dataList = $result->fetchAll();
+
+        if (!empty($dataList)) {
+            foreach ($dataList as $data) {
+                if (isset($oldGroups[$data['group_id']])) {
+                    $data['group_id'] = $oldGroups[$data['group_id']];
+
+                    $userId = $data['user_id'];
+
+                    $sql = "SELECT id FROM user WHERE user_id = $userId";
+                    $userResult = $connection->executeQuery($sql);
+                    $userInfo = $userResult->fetch();
+                    if (empty($userInfo)) {
+                        continue;
+                    }
+
+                    $sql = "INSERT INTO usergroup_rel_user (usergroup_id, user_id, relation_type)
+                            VALUES ('{$data['group_id']}', '{$userId}', '{$data['relation_type']}')";
+                    $connection->executeQuery($sql);
+                }
+            }
+        }
+
+        $sql = "SELECT * FROM group_rel_group";
+        $result = $connection->executeQuery($sql);
+        $dataList = $result->fetchAll();
+
+        if (!empty($dataList)) {
+            foreach ($dataList as $data) {
+                if (isset($oldGroups[$data['group_id']]) && isset($oldGroups[$data['subgroup_id']])) {
+                    $data['group_id'] = $oldGroups[$data['group_id']];
+                    $data['subgroup_id'] = $oldGroups[$data['subgroup_id']];
+                    $sql = "INSERT INTO usergroup_rel_usergroup (group_id, subgroup_id, relation_type)
+                            VALUES ('{$data['group_id']}', '{$data['subgroup_id']}', '{$data['relation_type']}')";
+                    $connection->executeQuery($sql);
+                }
+            }
+        }
+
+        $sql = "SELECT * FROM announcement_rel_group";
+        $result = $connection->executeQuery($sql);
+        $dataList = $result->fetchAll();
+
+        if (!empty($dataList)) {
+            foreach ($dataList as $data) {
+                if (isset($oldGroups[$data['group_id']])) {
+                    // Deleting relation
+                    $sql = "DELETE FROM announcement_rel_group WHERE group_id = {$data['group_id']}";
+                    $connection->executeQuery($sql);
+
+                    // Add new relation
+                    $data['group_id'] = $oldGroups[$data['group_id']];
+                    $sql = "INSERT INTO announcement_rel_group(group_id, announcement_id)
+                            VALUES ('{$data['group_id']}', '{$data['announcement_id']}')";
+                    $connection->executeQuery($sql);
+                }
+            }
+        }
+
+        $sql = "SELECT * FROM group_rel_tag";
+        $result = $connection->executeQuery($sql);
+        $dataList = $result->fetchAll();
+        if (!empty($dataList)) {
+            foreach ($dataList as $data) {
+                if (isset($oldGroups[$data['group_id']])) {
+                    $data['group_id'] = $oldGroups[$data['group_id']];
+                    $sql = "INSERT INTO usergroup_rel_tag (tag_id, usergroup_id)
+                            VALUES ('{$data['tag_id']}', '{$data['group_id']}')";
+                    $connection->executeQuery($sql);
+                }
+            }
+        }
+    }
+
+    if ($debug) {
+        error_log('update extra fields');
+    }
+
+    // Extra fields
+    $extraFieldTables = [
+        ExtraField::USER_FIELD_TYPE => Database::get_main_table(TABLE_MAIN_USER_FIELD),
+        ExtraField::COURSE_FIELD_TYPE => Database::get_main_table(TABLE_MAIN_COURSE_FIELD),
+        //ExtraField::LP_FIELD_TYPE => Database::get_main_table(TABLE_MAIN_LP_FIELD),
+        ExtraField::SESSION_FIELD_TYPE => Database::get_main_table(TABLE_MAIN_SESSION_FIELD),
+        //ExtraField::CALENDAR_FIELD_TYPE => Database::get_main_table(TABLE_MAIN_CALENDAR_EVENT_FIELD),
+        //ExtraField::QUESTION_FIELD_TYPE => Database::get_main_table(TABLE_MAIN_CALENDAR_EVENT_FIELD),
+        //ExtraField::USER_FIELD_TYPE => //Database::get_main_table(TABLE_MAIN_SPECIFIC_FIELD),
+    ];
+
+    foreach ($extraFieldTables as $type => $table) {
+        $sql = "SELECT * FROM $table ";
+        if ($debug) {
+            error_log($sql);
+        }
+        $result = $connection->query($sql);
+        $fields = $result->fetchAll();
+
+        foreach ($fields as $field) {
+            if ($debug) {
+                error_log("Loading field: ".$field['field_variable']);
+            }
+            $originalId = $field['id'];
+            $extraField = new ExtraField();
+            $extraField
+                ->setExtraFieldType($type)
+                ->setVariable($field['field_variable'])
+                ->setFieldType($field['field_type'])
+                ->setDisplayText($field['field_display_text'])
+                ->setDefaultValue($field['field_default_value'])
+                ->setFieldOrder($field['field_order'])
+                ->setVisible($field['field_visible'])
+                ->setChangeable($field['field_changeable'])
+                ->setFilter($field['field_filter']);
+
+            $em->persist($extraField);
+            $em->flush();
+
+            $values = array();
+            $handlerId = null;
+            switch ($type) {
+                case ExtraField::USER_FIELD_TYPE:
+                    $optionTable = Database::get_main_table(
+                        TABLE_MAIN_USER_FIELD_OPTIONS
+                    );
+                    $valueTable = Database::get_main_table(
+                        TABLE_MAIN_USER_FIELD_VALUES
+                    );
+                    $handlerId = 'user_id';
+                    break;
+                case ExtraField::COURSE_FIELD_TYPE:
+                    $optionTable = Database::get_main_table(
+                        TABLE_MAIN_COURSE_FIELD_OPTIONS
+                    );
+                    $valueTable = Database::get_main_table(
+                        TABLE_MAIN_COURSE_FIELD_VALUES
+                    );
+                    $handlerId = 'c_id';
+                    break;
+                case ExtraField::SESSION_FIELD_TYPE:
+                    $optionTable = Database::get_main_table(
+                        TABLE_MAIN_SESSION_FIELD_OPTIONS
+                    );
+                    $valueTable = Database::get_main_table(
+                        TABLE_MAIN_SESSION_FIELD_VALUES
+                    );
+                    $handlerId = 'session_id';
+                    break;
+            }
+
+            if (!empty($optionTable)) {
+                $sql = "SELECT * FROM $optionTable WHERE field_id = $originalId ";
+                $result = $connection->query($sql);
+                $options = $result->fetchAll();
+
+                foreach ($options as $option) {
+                    $extraFieldOption = new ExtraFieldOptions();
+                    $extraFieldOption
+                        ->setDisplayText($option['option_display_text'])
+                        ->setField($extraField)
+                        ->setOptionOrder($option['option_order'])
+                        ->setValue($option['option_value']);
+                    $em->persist($extraFieldOption);
+                    $em->flush();
+                }
+
+                $sql = "SELECT * FROM $valueTable WHERE field_id = $originalId ";
+                $result = $connection->query($sql);
+                $values = $result->fetchAll();
+                if ($debug) {
+                    error_log("Fetch all values for field");
+                }
+            }
+
+            if (!empty($values)) {
+                if ($debug) {
+                    error_log("Saving field value in new table");
+                }
+                $k = 0;
+                foreach ($values as $value) {
+                    if (isset($value[$handlerId])) {
+                        /*
+                        $extraFieldValue = new ExtraFieldValues();
+                        $extraFieldValue
+                            ->setValue($value['field_value'])
+                            ->setField($extraField)
+                            ->setItemId($value[$handlerId]);
+                        $em->persist($extraFieldValue);
+                        $em->flush();
+                        */
+                        // Insert without the use of the entity as it reduces
+                        // speed to 2 records per second (much too slow)
+                        $params = [
+                            'field_id' => $extraField->getId(),
+                            'value' => $value['field_value'],
+                            'item_id' => $value[$handlerId]
+                        ];
+                        $connection->insert('extra_field_values', $params);
+                        if ($debug && ($k % 10000 == 0)) {
+                            error_log("Saving field $k");
+                        }
+                        $k++;
+                    }
+                }
+            }
+        }
+    }
+
+    if ($debug) {
+        error_log('Remove index');
+    }
+
+    // Drop temporary indexes added to increase speed of this function's queries
+    $sql = "ALTER TABLE c_document DROP INDEX tmpidx_doc";
+    $connection->executeQuery($sql);
+    $sql = "ALTER TABLE c_student_publication DROP INDEX tmpidx_stud";
+    $connection->executeQuery($sql);
+    $sql = "ALTER TABLE c_quiz DROP INDEX tmpidx_quiz";
+    $connection->executeQuery($sql);
+    $sql = "ALTER TABLE c_item_property DROP INDEX tmpidx_ip";
+    $connection->executeQuery($sql);
+
     if ($debug) {
         error_log('Finish fixId function');
     }
@@ -2270,3 +2825,54 @@ function rrmdir($dir)
         rmdir($dir);
     }
 }
+
+function get_group_picture_path_by_id($id, $type = 'web', $preview = false, $anonymous = false)
+{
+    switch ($type) {
+        case 'system': // Base: absolute system path.
+            $base = api_get_path(SYS_UPLOAD_PATH);
+            break;
+        case 'web': // Base: absolute web path.
+        default:
+            $base = api_get_path(WEB_UPLOAD_PATH);
+            break;
+    }
+
+    $noPicturePath = array('dir' => $base.'img/', 'file' => 'unknown.jpg');
+
+    if (empty($id) || empty($type)) {
+        return $anonymous ? $noPicturePath : array('dir' => '', 'file' => '');
+    }
+
+    $id = intval($id);
+
+    //$group_table = Database :: get_main_table(TABLE_MAIN_GROUP);
+    $group_table = 'groups';
+    $sql = "SELECT picture_uri FROM $group_table WHERE id=".$id;
+    $res = Database::query($sql);
+
+    if (!Database::num_rows($res)) {
+        return $anonymous ? $noPicturePath : array('dir' => '', 'file' => '');
+    }
+
+    $user = Database::fetch_array($res);
+    $picture_filename = trim($user['picture_uri']);
+
+    if (api_get_setting('split_users_upload_directory') === 'true') {
+        if (!empty($picture_filename)) {
+            $dir = $base.'groups/'.substr($picture_filename, 0, 1).'/'.$id.'/';
+        } elseif ($preview) {
+            $dir = $base.'groups/'.substr((string) $id, 0, 1).'/'.$id.'/';
+        } else {
+            $dir = $base.'groups/'.$id.'/';
+        }
+    } else {
+        $dir = $base.'groups/'.$id.'/';
+    }
+
+    if (empty($picture_filename) && $anonymous) {
+        return $noPicturePath;
+    }
+
+    return array('dir' => $dir, 'file' => $picture_filename);
+}

+ 18 - 13
main/social/invitations.php

@@ -115,45 +115,50 @@ if ($number_loop != 0) {
         $sender_user_id = $invitation['user_sender_id'];
         $user_info = api_get_user_info($sender_user_id);
         $userPicture = $user_info['avatar'];
-        $invitationHtml .= '<div id="id_'.$sender_user_id.'" class="panel panel-default">';
+        $invitationHtml .= '<div id="id_'.$sender_user_id.'" class="block-invitation">';
 
         $title = Security::remove_XSS($invitation['title'], STUDENT, true);
         $content = Security::remove_XSS($invitation['content'], STUDENT, true);
         $date = api_convert_and_format_date($invitation['send_date'], DATE_TIME_FORMAT_LONG);
         $invitationHtml .= '<div class="row">';
         $invitationHtml .= '<div class="col-md-2">';
-        $invitationHtml .= '<a href="profile.php?u='.$sender_user_id.'"><img class="img-responsive" src="'.$userPicture.'"/></a>';
+        $invitationHtml .= '<a href="profile.php?u='.$sender_user_id.'"><img class="img-responsive img-rounded" src="'.$userPicture.'"/></a>';
         $invitationHtml .= '</div>';
         $invitationHtml .= '<div class="col-md-10">';
-        $invitationHtml .= '<h4 class="title-profile"><a href="profile.php?u='.$sender_user_id.'">
-                                    '.$user_info['complete_name'].'</a>:
-                                    </h4>';
-        $invitationHtml .= '<div class="content-invitation">'.$content.'</div>';
-        $invitationHtml .= '<div class="date-invitation">'.get_lang('DateSend').' : '.$date.'</div>';
-
-        $invitationHtml .= '<div class="btn-group" role="group">';
+        
+        $invitationHtml .= '<div class="pull-right">';
+        $invitationHtml .= '<div class="btn-group btn-group-sm" role="group">';
         $invitationHtml .= Display::toolbarButton(
-            get_lang('AcceptInvitation'),
+            null,
             api_get_path(WEB_AJAX_PATH) . 'social.ajax.php?' . http_build_query([
                 'a' => 'add_friend',
                 'friend_id' => $sender_user_id,
                 'is_my_friend' => 'friend'
             ]),
             'check',
-            'success',
+            'default',
             ['id' => 'btn-accept-' . $sender_user_id]
         );
         $invitationHtml .= Display::toolbarButton(
-            get_lang('DenyInvitation'),
+            null,
             api_get_path(WEB_AJAX_PATH) . 'social.ajax.php?' . http_build_query([
                 'a' => 'deny_friend',
                 'denied_friend_id' => $sender_user_id,
             ]),
             'times',
-            'danger',
+            'default',
             ['id' => 'btn-deny-' . $sender_user_id]
         );
         $invitationHtml .= '</div>';
+        $invitationHtml .= '</div>';
+        
+        $invitationHtml .= '<h5 class="title-profile"><a href="profile.php?u='.$sender_user_id.'">
+                            '.$user_info['complete_name'].'</a>:
+                            </h5>';
+        $invitationHtml .= '<div class="content-invitation">'.$content.'</div>';
+        $invitationHtml .= '<div class="date-invitation">'.get_lang('DateSend').' : '.$date.'</div>';
+        
+        
         $invitationHtml .= '</div>';
         $invitationHtml .= '</div></div>';
     }

+ 12 - 23
main/social/profile.php

@@ -182,27 +182,6 @@ $(document).ready(function (){
 function timeAgo() {
     $(".timeago").timeago();
 }
-
-function register_friend(element_input) {
-    if (confirm("'.get_lang('AddToFriends').'")) {
-        name_button=$(element_input).attr("id");
-        name_div_id="id_"+name_button.substring(13);
-        user_id=name_div_id.split("_");
-        user_friend_id=user_id[1];
-        $.ajax({
-            contentType: "application/x-www-form-urlencoded",
-            beforeSend: function(objeto) {
-                $("li#dpending_"+user_friend_id).html("<img src=\'../inc/lib/javascript/indicator.gif\' />");
-            },
-            type: "POST",
-            url: "'.api_get_path(WEB_AJAX_PATH).'social.ajax.php?a=add_friend",
-            data: "friend_id="+user_friend_id+"&is_my_friend="+"friend",
-            success: function(datos) {
-                $("#dpending_" + user_friend_id).html(datos);
-            }
-        });
-    }
-}
 </script>';
 
 $link_shared = '';
@@ -610,8 +589,18 @@ if ($show_full_profile) {
                                  .api_get_person_name($userInfo['firstname'],$userInfo['lastname']).'</a>';
                     
                     $invitations .='<div class="pull-right">';
-                    $invitations .=  '<a title="'.get_lang('SocialAddToFriends').'" id="btn_accepted_'.$user_invitation_id.'" class="btn btn-default btn-sm" onclick="register_friend(this)" href="javascript:void(0)">'
-                                . Display::returnFontAwesomeIcon('plus').'</a>';
+                    $invitations .= Display::toolbarButton(
+                        get_lang('SocialAddToFriends'),
+                        api_get_path(WEB_AJAX_PATH) . 'social.ajax.php?' . http_build_query([
+                            'a' => 'add_friend',
+                            'friend_id' => $user_invitation_id,
+                            'is_my_friend' => 'friend'
+                        ]),
+                        'plus',
+                        'default',
+                        ['class' => 'btn-sm'],
+                        false
+                    );
                     $invitations .= '</div>';
                     $invitations .=  '<div id="id_response"></div>';
                     $invitations .=  '</li>';

+ 7 - 3
main/template/default/admin/email_tester.tpl

@@ -1,9 +1,13 @@
 <div class="row">
-    <div class="col-sm-5">
+    {% if errors is empty %}
+    <div class="col-md-12">
         {{ form }}
     </div>
-    {% if not errors is empty %}
-        <div class="col-sm-7">
+    {% else %}
+        <div class="col-md-6">
+            {{ form }}
+        </div>
+        <div class="col-md-6">
             <h4 class="page-header">{{ 'Errors'|get_lang }}</h4>
             <ul>
                 {% for error in errors %}

+ 2 - 0
src/Chamilo/CourseBundle/Component/CourseCopy/CourseRestorer.php

@@ -2555,6 +2555,8 @@ class CourseRestorer
                         $path = $this->get_new_id($item['item_type'], $path);
                     }
 
+                    $item['item_type'] = $item['item_type'] == 'dokeos_chapter' ? 'dir' : $item['item_type'];
+
                     $params = [
                         'c_id' => $this->destination_course_id,
                         'lp_id' => self::DBUTF8($new_lp_id),