Browse Source

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

Julio 8 years ago
parent
commit
7634755df1
100 changed files with 1699 additions and 1228 deletions
  1. 1 0
      .scrutinizer.yml
  2. 1 1
      README.md
  3. 16 2
      documentation/changelog.html
  4. 11 8
      documentation/optimization.html
  5. 1 1
      main/admin/add_users_to_usergroup.php
  6. 24 0
      main/admin/index.php
  7. 11 6
      main/auth/external_login/newUser.ldap.php
  8. 2 1
      main/course_info/tools.php
  9. 54 44
      main/coursecopy/classes/Announcement.class.php
  10. 13 13
      main/coursecopy/classes/Attendance.class.php
  11. 36 33
      main/coursecopy/classes/CourseDescription.class.php
  12. 1 2
      main/coursecopy/classes/CourseSelectForm.class.php
  13. 19 18
      main/coursecopy/classes/CourseSession.class.php
  14. 284 283
      main/coursecopy/classes/DummyCourseCreator.class.php
  15. 1 1
      main/coursecopy/classes/Event.class.php
  16. 3 2
      main/coursecopy/classes/Forum.class.php
  17. 1 1
      main/coursecopy/classes/ForumCategory.class.php
  18. 2 2
      main/coursecopy/classes/ForumTopic.class.php
  19. 25 25
      main/coursecopy/classes/Glossary.class.php
  20. 36 37
      main/coursecopy/classes/Link.class.php
  21. 33 33
      main/coursecopy/classes/LinkCategory.class.php
  22. 4 0
      main/coursecopy/classes/Quiz.class.php
  23. 37 16
      main/coursecopy/classes/Resource.class.php
  24. 11 11
      main/coursecopy/classes/ScormDocument.class.php
  25. 103 103
      main/coursecopy/classes/Survey.class.php
  26. 46 46
      main/coursecopy/classes/SurveyInvitation.class.php
  27. 88 87
      main/coursecopy/classes/SurveyQuestion.class.php
  28. 1 1
      main/coursecopy/classes/Thematic.class.php
  29. 75 75
      main/coursecopy/classes/ToolIntro.class.php
  30. 1 1
      main/coursecopy/classes/Work.class.php
  31. 42 42
      main/coursecopy/classes/wiki.class.php
  32. 3 1
      main/gradebook/certificate_template/template.html
  33. 1 1
      main/gradebook/exercise_jump.php
  34. 1 1
      main/gradebook/gradebook_display_summary.php
  35. 1 1
      main/gradebook/index.php
  36. 1 1
      main/gradebook/lib/GradebookUtils.php
  37. 16 8
      main/inc/ajax/admin.ajax.php
  38. 3 9
      main/inc/ajax/lp.ajax.php
  39. 9 3
      main/inc/lib/course_home.lib.php
  40. 9 0
      main/inc/lib/document.lib.php
  41. 14 12
      main/inc/lib/exercise.lib.php
  42. 34 0
      main/inc/lib/message.lib.php
  43. 8 8
      main/inc/lib/pear/PEAR.php
  44. 1 0
      main/inc/lib/social.lib.php
  45. 17 9
      main/inc/lib/usermanager.lib.php
  46. 2 2
      main/inc/local.inc.php
  47. 5 0
      main/install/configuration.dist.php
  48. 1 1
      main/lang/english/trad4all.inc.php
  49. 2 1
      main/lang/french/trad4all.inc.php
  50. 2 2
      main/lang/spanish/trad4all.inc.php
  51. 2 1
      main/mySpace/myStudents.php
  52. 7 3
      main/newscorm/learnpath.class.php
  53. 69 55
      main/newscorm/lp_final_item.php
  54. 11 15
      main/newscorm/lp_nav.php
  55. 2 2
      main/newscorm/scorm_api.php
  56. 8 9
      main/social/profile.php
  57. 8 8
      main/template/default/learnpath/view.tpl
  58. 13 0
      main/template/default/mail/new_user_mail_to_admin.tpl
  59. 30 2
      main/template/default/social/user_block.tpl
  60. 17 0
      plugin/azure_active_directory/README.md
  61. 14 0
      plugin/azure_active_directory/index.php
  62. 20 0
      plugin/azure_active_directory/lang/english.php
  63. 9 0
      plugin/azure_active_directory/plugin.php
  64. 30 0
      plugin/azure_active_directory/readme.txt
  65. 102 0
      plugin/azure_active_directory/src/AzureActiveDirectory.php
  66. 55 0
      plugin/azure_active_directory/src/callback.php
  67. 12 0
      plugin/azure_active_directory/view/block.tpl
  68. 15 5
      plugin/bbb/lib/bbb.lib.php
  69. 27 3
      plugin/createdrupaluser/README.md
  70. 31 1
      plugin/skype/README.md
  71. 0 9
      plugin/skype/config.php
  72. 0 6
      plugin/skype/index.php
  73. 0 10
      plugin/skype/install.php
  74. 2 0
      plugin/skype/lang/english.php
  75. 2 0
      plugin/skype/lang/spanish.php
  76. 0 1
      plugin/skype/plugin.php
  77. 40 1
      plugin/skype/readme.txt
  78. 0 34
      plugin/skype/src/HookSkype.php
  79. 6 61
      plugin/skype/src/Skype.php
  80. 0 10
      plugin/skype/uninstall.php
  81. 6 1
      src/Chamilo/CoreBundle/Entity/ExtraFieldValues.php
  82. 3 3
      src/Chamilo/CoreBundle/Entity/Language.php
  83. 1 0
      src/Chamilo/CoreBundle/Entity/SysCalendar.php
  84. 1 0
      src/Chamilo/CoreBundle/Entity/SystemTemplate.php
  85. 10 11
      src/Chamilo/CoreBundle/Entity/Tag.php
  86. 1 0
      src/Chamilo/CoreBundle/Entity/Templates.php
  87. 1 0
      src/Chamilo/CoreBundle/Entity/TrackCourseRanking.php
  88. 1 0
      src/Chamilo/CoreBundle/Entity/TrackEAccess.php
  89. 1 0
      src/Chamilo/CoreBundle/Entity/TrackEAttempt.php
  90. 1 0
      src/Chamilo/CoreBundle/Entity/TrackEAttemptCoeff.php
  91. 10 11
      src/Chamilo/CoreBundle/Entity/TrackEAttemptRecording.php
  92. 10 11
      src/Chamilo/CoreBundle/Entity/TrackECourseAccess.php
  93. 1 0
      src/Chamilo/CoreBundle/Entity/TrackEDownloads.php
  94. 1 0
      src/Chamilo/CoreBundle/Entity/TrackEExercises.php
  95. 1 0
      src/Chamilo/CoreBundle/Entity/TrackEHotpotatoes.php
  96. 1 0
      src/Chamilo/CoreBundle/Entity/TrackEHotspot.php
  97. 1 0
      src/Chamilo/CoreBundle/Entity/TrackEItemProperty.php
  98. 1 0
      src/Chamilo/CoreBundle/Entity/TrackELastaccess.php
  99. 1 0
      src/Chamilo/CoreBundle/Entity/TrackELinks.php
  100. 1 0
      src/Chamilo/CoreBundle/Entity/TrackELogin.php

+ 1 - 0
.scrutinizer.yml

@@ -21,6 +21,7 @@ filter:
         - web/*
         - vendor/*
         - main/admin/db.php
+        - app/Migrations/*
 checks:
     php:
         code_rating: true

+ 1 - 1
README.md

@@ -168,7 +168,7 @@ php bin/doctrine.php migrations:execute 20150527120703 --up --configuration=app/
 
 You can also print the differences between your database and what it should be by issuing the following command from the Chamilo base folder:
 ```
-php bin/doctrine.php orm:schema:update --dump-sql
+php bin/doctrine.php orm:schema-tool:update --dump-sql
 ```
 
 ## Contributing

+ 16 - 2
documentation/changelog.html

@@ -49,7 +49,7 @@
 
     <a name="1.10.6"></a>
 
-    <h1>Chamilo 1.10.6 - Zacatecas, 23rd of May 2016</h1>
+    <h1>Chamilo 1.10.6 - Zacatecas, 24th of May 2016</h1>
     <h3>Release notes - summary</h3>
     <p>Chamilo 1.10.6 is a minor, bugfix release of the 1.10.x branch, with a few new features and bugfixes on top of 1.10.4.</p>
     <h3>Release name</h3>
@@ -61,7 +61,6 @@
     <h3>Notable new Features</h3>
     <h4>For end-users, teachers and Chamilo admins</h4>
     <ul>
-        <li>(<a href="https://github.com/chamilo/chamilo-lms/commit/700d3516f86c441460f30d5feb64916465d1d545">700d3516</a> - <a href="https://task.beeznest.com/issues/11186">BT#11186</a>) Fix random questions</li>
         <li>(<a href="https://github.com/chamilo/chamilo-lms/commit/dd051695d71cb7e69969d6b3644a5b1ee79bedfb">dd051695</a>) Add option to show right answers only during the last exercise attempt (RESULT_DISABLE_SHOW_SCORE_ATTEMPT_SHOW_ANSWERS_LAST_ATTEMPT)</li>
         <li>(<a href="https://github.com/chamilo/chamilo-lms/commit/1c76446ff2967542afc9f1ec963f6444593b3c5e">1c76446f</a>) Add course setting "bbb_enable_conference_in_groups" to allow for conferences through course groups (requires the BigBlueButton plugin)</li>
         <li>(<a href="https://github.com/chamilo/chamilo-lms/commit/88842fd706130a593d2a5e95cd37784a4d0de389">88842fd7</a> - <a href="https://task.beeznest.com/issues/11141">BT#11141</a>) Allow platform admins to manage all sessions</li>
@@ -86,6 +85,21 @@
     </ul>
     <h3>Improvements (minor features) and debug</h3>
     <ul>
+        <li>(<a href="https://github.com/chamilo/chamilo-lms/commit/700d3516f86c441460f30d5feb64916465d1d545">700d3516</a> - <a href="https://task.beeznest.com/issues/11186">BT#11186</a>) Fix random questions</li>
+        <li>(<a href="https://github.com/chamilo/chamilo-lms/commit/c7dc81a679f944f868c0243b8bb66a545cd6d783">c7dc81a6</a> - <a href="https://task.beeznest.com/issues/11202">BT#11202</a>) Fix option  RESULT_DISABLE_SHOW_SCORE_ATTEMPT_SHOW_ANSWERS_LAST_ATTEMPT BT#11202</li>
+        <li>(<a href="https://github.com/chamilo/chamilo-lms/commit/397c9dcfd1bccc648b78ba423b132ccacc5aae2a">397c9dcf</a>) Update version to 1.10.6 in main/install/version.php</li>
+        <li>(<a href="https://github.com/chamilo/chamilo-lms/commit/0ad4eaee3cfa47acbc8bbab2bf70f55d92ed49bc">0ad4eaee</a> - <a href="https://support.chamilo.org/issues/1170">#1170</a>) Scrutinizer Auto-Fixes (#1170)</li>
+        <li>(<a href="https://github.com/chamilo/chamilo-lms/commit/8f76ee8d0cf33a8c52313b19067c2d7566e823e6">8f76ee8d</a> - <a href="https://support.chamilo.org/issues/8237">#8237</a>) Save calculated answer without correct answer</li>
+        <li>(<a href="https://github.com/chamilo/chamilo-lms/commit/6b3e77efabf6750a7aeec266eb7ad1fa8b3fbed0">6b3e77ef</a> - <a href="https://support.chamilo.org/issues/8237">#8237</a>) Fix read question of calculated answer type</li>
+        <li>(<a href="https://github.com/chamilo/chamilo-lms/commit/aafde67b9c4e1dca98e2064bd3d4774979e045ca">aafde67b</a> - <a href="https://support.chamilo.org/issues/8237">#8237</a>) Order code + showw CALCULATED_ANSWER questions</li>
+        <li>(<a href="https://github.com/chamilo/chamilo-lms/commit/dfaa4f873da912c58dbc9b8a588b56e3c83d159d">dfaa4f87</a> - <a href="https://task.beeznest.com/issues/11202">BT#11202</a>) Fix hotspot question result by a new parameter</li>
+        <li>(<a href="https://github.com/chamilo/chamilo-lms/commit/73a570bfd0163e84361856f78dec57a2d9ea953e">73a570bf</a>) Update gitlog to better ignore language terms messages</li>
+        <li>(<a href="https://github.com/chamilo/chamilo-lms/commit/a82e76b76648e86490c2f6481e1febd0ed7ea6b8">a82e76b7</a> - <a href="https://support.chamilo.org/issues/8237">#8237</a>) Revert "Fix CALCULATED_ANSWER</li>
+        <li>(<a href="https://github.com/chamilo/chamilo-lms/commit/d3a5c1e8db761f738dcfe98181a473a87084759e">d3a5c1e8</a> - <a href="https://support.chamilo.org/issues/8237">#8237</a>) Revert "Fix questions list with calculated questions</li>
+        <li>(<a href="https://github.com/chamilo/chamilo-lms/commit/ee763e840555125e82549213e040178961934525">ee763e84</a> - <a href="https://support.chamilo.org/issues/8237">#8237</a>) Revert "Fix showing resuls for calculated answers</li>
+        <li>(<a href="https://github.com/chamilo/chamilo-lms/commit/ee874accf2a186902a8815a5e45244bf381f2b98">ee874acc</a> - <a href="https://support.chamilo.org/issues/8237">#8237</a>) Revert "Fix questions list for calculated answers</li>
+        <li>(<a href="https://github.com/chamilo/chamilo-lms/commit/9cb2a9214cba10f5a3b40465211bc084d7e4bf69">9cb2a921</a> - <a href="https://support.chamilo.org/issues/8237">#8237</a>) Revert "Fix conflict</li>
+        <li>(<a href="https://github.com/chamilo/chamilo-lms/commit/6096b797f6c210fa8444d34ff7a3d95487fd4d63">6096b797</a> - <a href="https://support.chamilo.org/issues/8237">#8237</a>) Revert "Save the calculated answer without whished anser</li>
         <li>(<a href="https://github.com/chamilo/chamilo-lms/commit/6b51fae1a37d3c7b3f7c656e3631cb2eb50d028e">6b51fae1</a> - <a href="https://task.beeznest.com/issues/10052">BT#10052</a>) Add function needed for exercises categories</li>
         <li>(<a href="https://github.com/chamilo/chamilo-lms/commit/1eac339bacb87237413064b9f20f6047d4093dad">1eac339b</a>) Fix the update of API keys when no key exists previously (update_api_key())</li>
         <li>(<a href="https://github.com/chamilo/chamilo-lms/commit/f40efabc34cbffb840a47f44495e0fa59fc476e9">f40efabc</a>) Fix - Enable/disable tickets plugin from menu, display blank screen</li>

+ 11 - 8
documentation/optimization.html

@@ -342,7 +342,7 @@ ALTER TABLE user_rel_tag ADD INDEX idx_user_rel_tag_user (user_id);
 In Chamilo 1.10.0 (the first version of the serie), many indexes were forgotten, so you can boost your database by adding the following indexes:<br />
 <pre>
 alter table extra_field_values add index idx_extra_field_values (field_id, item_id);
-alter table usergroup_rel_user add index idx_usergroup_ru (group_id);
+alter table usergroup_rel_user add index idx_usergroup_ru (usergroup_id);
 alter table usergroup_rel_user add index idx_usergroup_ru_u (user_id);
 alter table c_student_publication add index idxstudpub_cid (c_id);
 alter table c_student_publication add index idxstudpub_uid (user_id);
@@ -351,10 +351,13 @@ alter table c_quiz_rel_question ADD INDEX idx_cqrq_qid (question_id);
 alter table c_quiz_rel_question ADD INDEX idx_cqrq_cid (c_id);
 alter table c_quiz_answer add index idx_qa_cidqid (c_id, question_id);
 </pre>
+In Chamilo 1.10.6, an additional query was confirmed to still have effect a considerable effect:
+<pre>
+alter table c_quiz_question_rel_category add index idx_qqrc_qid (question_id);
+</pre>
 <hr />
 <h2><a name="3.Indexes-caching"></a>3. Indexes caching</h2>
 One good reference: <a href="http://dev.mysql.com/doc/refman/5.1/en/multiple-key-caches.html">MySQL documentation on multiple key caches</a><br />
-
 <hr />
 
 <h2><a name="4.Sessions-directories"></a>4. Sessions directories</h2>
@@ -555,23 +558,23 @@ This is easy, doesn't require a server reload and you should see the results pre
     you should avoid using this technique.
 </p>
 <p>
-You can also mitigate the risk by disabling permissions check only 
+You can also mitigate the risk by disabling permissions check only
 for some static resource like css,js and fonts files.
 <br/>
-For that is required to load header module  
+For that is required to load header module
 in apache (check with a2enmod in your favorite root terminal)<br />
 add theses line after RewriteBase /courses/:
 <pre>
 &lt;IfModule mod_headers.c&gt;
     # all file name ended with these  extensions names will bypass the permission check   (and also served by the browser cache at  the next request)
     &lt;FilesMatch &quot;\.(gif|jpg|jpeg|png|js|pdf|ico|icon|css|swf|avi|mp3|ogg|wav|ttf|otf|eot|woff)$&quot;&gt;
-        Header unset Cache-Control  
-        Header set Cache-Control &quot;public, max-age=29030400&quot; 
-        RequestHeader unset Cookie      
+        Header unset Cache-Control
+        Header set Cache-Control &quot;public, max-age=29030400&quot;
+        RequestHeader unset Cookie
         Header unset ETag
     &lt;/FilesMatch&gt;
 &lt;/IfModule&gt;
-# also adjust files here 
+# also adjust files here
 RewriteRule (\.(html|gif|jpg|jpeg|png|js|pdf|ico|icon|css|swf|avi|mp3|ogg|wav|ttf|otf|eot|woff))$ - [L]
 </pre>
 </p>

+ 1 - 1
main/admin/add_users_to_usergroup.php

@@ -177,7 +177,7 @@ if ($use_extra_fields) {
     if (count($extra_field_result)>1) {
         for ($i=0; $i<count($extra_field_result)-1; $i++) {
             if (is_array($extra_field_result[$i+1])) {
-                $final_result  = array_intersect($extra_field_result[$i], $extra_field_result[$i+1]);
+                $final_result = array_intersect($extra_field_result[$i], $extra_field_result[$i+1]);
             }
         }
     } else {

+ 24 - 0
main/admin/index.php

@@ -438,6 +438,30 @@ if (api_is_platform_admin()) {
             $blocks = $data['blocks'];
         }
     }
+
+    //Hack for fix migration on session_rel_user
+    $tableColumns = Database::getManager()
+        ->getConnection()
+        ->getSchemaManager()
+        ->listTableColumns(
+            Database::get_main_table(TABLE_MAIN_SESSION_USER)
+        );
+
+    if (!array_key_exists('duration', $tableColumns)) {
+        try {
+            $dbSchema = Database::getManager()->getConnection()->getSchemaManager();
+            $durationColumn = new \Doctrine\DBAL\Schema\Column(
+                'duration',
+                Doctrine\DBAL\Types\Type::getType(\Doctrine\DBAL\Types\Type::INTEGER),
+                ['notnull' => false]
+            );
+            $tableDiff = new \Doctrine\DBAL\Schema\TableDiff('session_rel_user', [$durationColumn]);
+            $dbSchema->alterTable($tableDiff);
+        } catch (Exception $e) {
+            error_log($e->getMessage());
+        }
+    }
+    //end hack
 }
 $admin_ajax_url = api_get_path(WEB_AJAX_PATH) . 'admin.ajax.php';
 

+ 11 - 6
main/auth/external_login/newUser.ldap.php

@@ -44,26 +44,31 @@ require_once dirname(__FILE__) . '/functions.inc.php';
 
 $ldap_user = extldap_authenticate($login, $password);
 if ($ldap_user !== false) {
+    $em = Database::getManager();
     $chamilo_user = extldap_get_chamilo_user($ldap_user);
     //username is not on the ldap, we have to use $login variable
     $chamilo_user['username'] = $login;
     $chamilo_uid = external_add_user($chamilo_user);
-    if ($chamilo_uid !== false) {
+
+    $chamiloUser = $em->find('ChamiloUserBundle:User', $chamilo_uid);
+
+    if ($chamiloUser) {
         $loginFailed = false;
-        $_user['user_id'] = $chamilo_uid;
-        $_user['status'] = (isset($chamilo_user['status']) ? $chamilo_user['status'] : 5);
+        $_user['user_id'] = $chamiloUser->getId();
+        $_user['status'] = $chamiloUser->getStatus();
         $_user['uidReset'] = true;
         Session::write('_user', $_user);
         $uidReset = true;
         // Is user admin?
         if ($chamilo_user['admin'] === true) {
             $is_platformAdmin = true;
-            Database::query("INSERT INTO admin values ('$chamilo_uid')");
+            Database::query("INSERT INTO admin values ('{$chamiloUser->getId()}')");
         }
-        Event::event_login($chamilo_uid);
+        Event::event_login($chamiloUser->getId());
+
+        MessageManager::sendNotificationByRegisteredUser($chamiloUser);
     }
 } else {
     $loginFailed = true;
     $uidReset = false;
-    unset($_user['user_id']);
 }

+ 2 - 1
main/course_info/tools.php

@@ -44,7 +44,7 @@ switch ($action) {
         }
 
         $interbreadcrumb[] = array('url' => api_get_self().'?'.api_get_cidreq(), 'name' => get_lang('CustomizeIcons'));
-        $toolName = $tool['name'];
+        $toolName = Security::remove_XSS(stripslashes($tool['name']));
 
         $currentUrl = api_get_self().'?action=edit_icon&id=' . $id.'&'.api_get_cidreq();
 
@@ -115,6 +115,7 @@ switch ($action) {
         $iconsTools .= Display::page_header(get_lang('CustomizeIcons'), null, 'h4');
         $iconsTools .= '<div class="row">';
         foreach ($toolList as $tool) {
+            $tool['name'] = Security::remove_XSS(stripslashes($tool['name']));
             $toolIconName = 'Tool' . api_underscore_to_camel_case($tool['name']);
             $toolIconName = isset($$toolIconName) ? get_lang($toolIconName) : $tool['name'];
 

+ 54 - 44
main/coursecopy/classes/Announcement.class.php

@@ -10,25 +10,25 @@ require_once 'Resource.class.php';
  */
 class Announcement extends Coursecopy\Resource
 {
-	/**
-	 * The title of the announcement
-	 */
+    /**
+     * The title of the announcement
+     */
     public $title;
-	/**
-	 * The content of the announcement
-	 */
+    /**
+     * The content of the announcement
+     */
     public $content;
-	/**
-	 * The date on which this announcement was made
-	 */
+    /**
+     * The date on which this announcement was made
+     */
     public $date;
-	/**
-	 * The display order of this announcement
-	 */
+    /**
+     * The display order of this announcement
+     */
     public $display_order;
-	/**
-	 * Has the e-mail been sent?
-	 */
+    /**
+     * Has the e-mail been sent?
+     */
     public $email_sent;
 
     public $attachment_path;
@@ -39,36 +39,46 @@ class Announcement extends Coursecopy\Resource
 
     public $attachment_comment;
 
-	/**
-	 * Create a new announcement
-	 * @param int $id
-	 * @param string $title
-	 * @param string $content
-	 * @param string $date
-	 * @param int display_order
-	 */
-    function __construct($id, $title, $content, $date, $display_order, $email_sent, $path, $filename, $size, $comment)
-    {
-		parent::__construct($id,RESOURCE_ANNOUNCEMENT);
+    /**
+     * Create a new announcement
+     * @param int $id
+     * @param string $title
+     * @param string $content
+     * @param string $date
+     * @param int display_order
+     */
+    public function __construct(
+        $id,
+        $title,
+        $content,
+        $date,
+        $display_order,
+        $email_sent,
+        $path,
+        $filename,
+        $size,
+        $comment
+    ) {
+        parent::__construct($id,RESOURCE_ANNOUNCEMENT);
 
-		$this->content	= $content;
-		$this->title 	= $title;
-		$this->date 	= $date;
-		$this->display_order	= $display_order;
-		$this->email_sent	 	= $email_sent;
+        $this->content	= $content;
+        $this->title 	= $title;
+        $this->date 	= $date;
+        $this->display_order	= $display_order;
+        $this->email_sent	 	= $email_sent;
 
-		$this->attachment_path 	= $path;
-		$this->attachment_filename = $filename;
-		$this->attachment_size 	= $size;
-		$this->attachment_comment 	= $comment;
-	}
+        $this->attachment_path 	= $path;
+        $this->attachment_filename = $filename;
+        $this->attachment_size 	= $size;
+        $this->attachment_comment 	= $comment;
+    }
 
-	/**
-	 * Show this announcement
-	 */
-	function show()
-	{
-		parent::show();
-		echo $this->date.': '.$this->title;
-	}
+    /**
+     * Show this announcement
+     */
+    function show()
+    {
+        parent::show();
+        echo $this->date.': '.$this->title;
+    }
 }

+ 13 - 13
main/coursecopy/classes/Attendance.class.php

@@ -13,28 +13,28 @@ class Attendance extends Coursecopy\Resource
     public $params = array();
     public $attendance_calendar = array();
 
-	/**
-	 * Create a new Thematic
-	 *
-	 * @param array parameters
-	 */
+    /**
+     * Create a new Thematic
+     *
+     * @param array parameters
+     */
     public function __construct($params)
     {
-		parent::__construct($params['id'], RESOURCE_ATTENDANCE);
-		$this->params = $params;
-	}
+        parent::__construct($params['id'], RESOURCE_ATTENDANCE);
+        $this->params = $params;
+    }
 
     /**
      * @inheritdoc
      */
     public function show()
     {
-		parent::show();
-		echo $this->params['name'];
-	}
+        parent::show();
+        echo $this->params['name'];
+    }
 
     public function add_attendance_calendar($data)
     {
-		$this->attendance_calendar[] = $data;
-	}
+        $this->attendance_calendar[] = $data;
+    }
 }

+ 36 - 33
main/coursecopy/classes/CourseDescription.class.php

@@ -1,6 +1,7 @@
 <?php
 /* For licensing terms, see /license.txt */
 namespace Coursecopy;
+
 require_once 'Resource.class.php';
 
 /**
@@ -10,39 +11,41 @@ require_once 'Resource.class.php';
  */
 class CourseDescription extends Resource
 {
-	/**
-	 * The title
-	 */
-	public $title;
-	/**
-	 * The content
-	 */
-	public $content;
-	/**
-	 * The description type
-	 */
-	public $description_type;
+    /**
+     * The title
+     */
+    public $title;
+    
+    /**
+     * The content
+     */
+    public $content;
+
+    /**
+     * The description type
+     */
+    public $description_type;
 
-	/**
-	 * Create a new course description
-	 * @param int $id
-	 * @param string $title
-	 * @param string $content
-	 */
-	public function __construct($id,$title,$content,$description_type)
-	{
-		parent::__construct($id,RESOURCE_COURSEDESCRIPTION);
-		$this->title = $title;
-		$this->content = $content;
-		$this->description_type = $description_type;
-	}
+    /**
+     * Create a new course description
+     * @param int $id
+     * @param string $title
+     * @param string $content
+     */
+    public function __construct($id, $title, $content, $description_type)
+    {
+        parent::__construct($id, RESOURCE_COURSEDESCRIPTION);
+        $this->title = $title;
+        $this->content = $content;
+        $this->description_type = $description_type;
+    }
 
-	/**
-	 * Show this Event
-	 */
-	function show()
-	{
-		parent::show();
-		echo $this->title;
-	}
+    /**
+     * Show this Event
+     */
+    public function show()
+    {
+        parent::show();
+        echo $this->title;
+    }
 }

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

@@ -16,7 +16,7 @@ class CourseSelectForm
 	 * @param array $hidden_fields Hidden fields to add to the form.
 	 * @param boolean the document array will be serialize. This is used in the course_copy.php file
 	 */
-	static function display_form($course, $hidden_fields = null, $avoid_serialize = false)
+	public static function display_form($course, $hidden_fields = null, $avoid_serialize = false)
     {
         global $charset;
         $resource_titles[RESOURCE_GRADEBOOK] = get_lang('Gradebook');
@@ -224,7 +224,6 @@ class CourseSelectForm
 
 						foreach ($resources as $id => $resource) {
                             if ($resource) {
-								// Event obj in 1.9.x in 1.10.x the class is CalendarEvent
                                 Coursecopy\Resource::setClassType($resource);
                                 echo '<label class="checkbox">';
                                 echo '<input type="checkbox" name="resource['.$type.']['.$id.']"  id="resource['.$type.']['.$id.']" />';

+ 19 - 18
main/coursecopy/classes/CourseSession.class.php

@@ -11,24 +11,25 @@ require_once 'Resource.class.php';
 class CourseSession extends Coursecopy\Resource
 {
     // The title session
-	public $title;
+    public $title;
 
-	/**
-	 * Create a new Session
-	 * @param int $id
-	 * @param string $title
-	 */
-	public function __construct($id,$title)
-	{
-		parent::__construct($id, RESOURCE_SESSION_COURSE);
-		$this->title = $title;
-	}
+    /**
+     * Create a new Session
+     * @param int $id
+     * @param string $title
+     */
+    public function __construct($id,$title)
+    {
+        parent::__construct($id, RESOURCE_SESSION_COURSE);
+        $this->title = $title;
+    }
 
-	/**
-	 * Show this Event
-	 */
-	function show() {
-		parent::show();
-		echo $this->title;
-	}
+    /**
+     * Show this Event
+     */
+    public function show()
+    {
+        parent::show();
+        echo $this->title;
+    }
 }

+ 284 - 283
main/coursecopy/classes/DummyCourseCreator.class.php

@@ -20,289 +20,290 @@ require_once 'CourseRestorer.class.php';
  */
 class DummyCourseCreator
 {
-	/**
-	 * The dummy course
-	 */
-	public $course;
-	/**
-	 *
-	 */
-	public $default_property = array();
+    /**
+     * The dummy course
+     */
+    public $course;
+    /**
+     *
+     */
+    public $default_property = array();
 
-	/**
-	 * Create the dummy course
-	 */
-	public function create_dummy_course($course_code)
-	{
-		$this->default_property['insert_user_id'] = '1';
-		$this->default_property['insert_date'] = date('Y-m-d H:i:s');
-		$this->default_property['lastedit_date'] = date('Y-m-d H:i:s');
-		$this->default_property['lastedit_user_id'] = '1';
-		$this->default_property['to_group_id'] = '0';
-		$this->default_property['to_user_id'] = null;
-		$this->default_property['visibility'] = '1';
-		$this->default_property['start_visible'] = '0000-00-00 00:00:00';
-		$this->default_property['end_visible'] =  '0000-00-00 00:00:00';
+    /**
+     * Create the dummy course
+     */
+    public function create_dummy_course($course_code)
+    {
+        $this->default_property['insert_user_id'] = '1';
+        $this->default_property['insert_date'] = date('Y-m-d H:i:s');
+        $this->default_property['lastedit_date'] = date('Y-m-d H:i:s');
+        $this->default_property['lastedit_user_id'] = '1';
+        $this->default_property['to_group_id'] = '0';
+        $this->default_property['to_user_id'] = null;
+        $this->default_property['visibility'] = '1';
+        $this->default_property['start_visible'] = '0000-00-00 00:00:00';
+        $this->default_property['end_visible'] =  '0000-00-00 00:00:00';
 
-		$course = api_get_course_info($course_code);
-		$this->course = new Course();
-		$tmp_path = api_get_path(SYS_COURSE_PATH).$course['directory'].'/document/tmp_'.uniqid('');
-		@mkdir($tmp_path, api_get_permissions_for_new_directories(), true);
-		$this->course->backup_path = $tmp_path;
-		$this->create_dummy_links();
-		$this->create_dummy_events();
-		$this->create_dummy_forums();
-		$this->create_dummy_announcements();
-		$this->create_dummy_documents();
-		$this->create_dummy_learnpaths();
-		$cr = new CourseRestorer($this->course);
-		$cr->set_file_option(FILE_OVERWRITE);
-		$cr->restore($course_code);
-		rmdirr($tmp_path);
-	}
-	/**
-	 * Create dummy documents
-	 */
-	function create_dummy_documents()
-	{
-		$course = api_get_course_info();
-		$course_doc_path = $this->course->backup_path.'/document/';
-		$number_of_documents = rand(10, 30);
-		$extensions = array ('html', 'doc');
-		$directories = array();
-		$property = $this->default_property;
-		$property['lastedit_type'] = 'DocumentAdded';
-		$property['tool'] = TOOL_DOCUMENT;
-		$doc_id = 0;
-		for ($doc_id = 1; $doc_id < $number_of_documents; $doc_id ++)
-		{
-			$path = '';
-			$doc_type = rand(0, count($extensions) - 1);
-			$extension = $extensions[$doc_type];
-			$filename = $this->get_dummy_content('title').'_'.$doc_id.'.'.$extension;
-			$content = $this->get_dummy_content('text');
-			$dirs = rand(0, 3);
-			for ($i = 0; $i < $dirs; $i ++)
-			{
-				$path .= 'directory/';
-				$directories[$path] = 1;
-			}
-			$dir_to_make = $course_doc_path.$path;
-			if (!is_dir($dir_to_make))
-			{
-				@mkdir($dir_to_make, api_get_permissions_for_new_directories(), true);
-			}
-			$file = $course_doc_path.$path.$filename;
-			$fp = fopen($file, 'w');
-			fwrite($fp, $content);
-			fclose($fp);
-			$size = filesize($file);
-			$document = new Document($doc_id, '/'.$path.$filename,$this->get_dummy_content('description'),$this->get_dummy_content('title'), 'file', $size);
-			$document->item_properties[] = $property;
-			$this->course->add_resource($document);
-		}
-		foreach($directories as $path => $flag)
-		{
-			$path = substr($path,0,strlen($path)-1);
-			$document = new Document($doc_id++,'/'.$path, $this->get_dummy_content('description'),$this->get_dummy_content('title'),'folder',0);
-			$property['lastedit_type'] = 'FolderCreated';
-			$document->item_properties[] = $property;
-			$this->course->add_resource($document);
-		}
-	}
-	/**
-	 * Create dummy announcements
-	 */
-	function create_dummy_announcements()
-	{
-		$property = $this->default_property;
-		$property['lastedit_type'] = 'AnnouncementAdded';
-		$property['tool'] = TOOL_ANNOUNCEMENT;
-		$number_of_announcements = rand(10, 30);
-		for ($i = 0; $i < $number_of_announcements; $i ++)
-		{
-			$time = mktime(rand(1, 24), rand(1, 60), 0, rand(1, 12), rand(1, 28), intval(date('Y')));
-			$date = date('Y-m-d', $time);
-			$announcement = new Announcement($i,$this->get_dummy_content('title'),$this->get_dummy_content('text'), $date,0);
-			$announcement->item_properties[] = $property;
-			$this->course->add_resource($announcement);
-		}
-	}
-	/**
-	 * Create dummy events
-	 */
-	function create_dummy_events()
-	{
-		$number_of_events = rand(10, 30);
-		$property = $this->default_property;
-		$property['lastedit_type'] = 'AgendaAdded';
-		$property['tool'] = TOOL_CALENDAR_EVENT;
-		for ($i = 0; $i < $number_of_events; $i ++)
-		{
-			$hour = rand(1,24);
-			$minute = rand(1,60);
-			$second = rand(1,60);
-			$day = rand(1,28);
-			$month = rand(1,12);
-			$year = intval(date('Y'));
-			$time = mktime($hour,$minute,$second,$month,$day,$year);
-			$start_date = date('Y-m-d H:m:s', $time);
-			$hour = rand($hour,24);
-			$minute = rand($minute,60);
-			$second = rand($second,60);
-			$day = rand($day,28);
-			$month = rand($month,12);
-			$year = intval(date('Y'));
-			$time = mktime($hour,$minute,$second,$month,$day,$year);
-			$end_date = date('Y-m-d H:m:s', $time);
-			$event = new CalendarEvent(
-				$i,
-				$this->get_dummy_content('title'),
-				$this->get_dummy_content('text'),
-				$start_date,
-				$end_date
-			);
-			$event->item_properties[] = $property;
-			$this->course->add_resource($event);
-		}
-	}
-	/**
-	 * Create dummy links
-	 */
-	function create_dummy_links()
-	{
-		// create categorys
-		$number_of_categories = rand(5, 10);
-		for ($i = 0; $i < $number_of_categories; $i ++)
-		{
-			$linkcat = new LinkCategory($i, $this->get_dummy_content('title'), $this->get_dummy_content('description'),$i);
-			$this->course->add_resource($linkcat);
-		}
-		// create links
-		$number_of_links = rand(5, 50);
-		$on_homepage = rand(0,20) == 0 ? 1 : 0;
-		$property = $this->default_property;
-		$property['lastedit_type'] = 'LinkAdded';
-		$property['tool'] = TOOL_LINK;
-		for ($i = 0; $i < $number_of_links; $i ++)
-		{
-			$link = new Link($i, $this->get_dummy_content('title'), 'http://www.google.com/search?q='.$this->get_dummy_content('title'), $this->get_dummy_content('description'), rand(0, $number_of_categories -1),$on_homepage);
-			$link->item_properties[] = $property;
-			$this->course->add_resource($link);
-		}
-	}
-	/**
-	 * Create dummy forums
-	 */
-	function create_dummy_forums()
-	{
-		$number_of_categories = rand(2, 6);
-		$number_of_forums = rand(5, 50);
-		$number_of_topics = rand(30, 100);
-		$number_of_posts = rand(100, 1000);
-		$last_forum_post = array ();
-		$last_topic_post = array ();
-		// create categorys
-		$order = 1;
-		for ($i = 1; $i <= $number_of_categories; $i ++)
-		{
-			$forumcat = new ForumCategory($i, $this->get_dummy_content('title'), $this->get_dummy_content('description'), $order, 0, 0);
-			$this->course->add_resource($forumcat);
-			$order++;
-		}
-		// create posts
-		for ($post_id = 1; $post_id <= $number_of_posts; $post_id ++)
-		{
-			$topic_id = rand(1, $number_of_topics);
-			$last_topic_post[$topic_id] = $post_id;
-			$post = new ForumPost($post_id, $this->get_dummy_content('title'), $this->get_dummy_content('text'), date('Y-m-d H:i:s'), 1, 'Portal Administrator', 0, 0, $topic_id, 0, 1);
-			$this->course->add_resource($post);
-		}
-		// create topics
-		for ($topic_id = 1; $topic_id <= $number_of_topics; $topic_id ++)
-		{
-			$forum_id = rand(1, $number_of_forums);
-			$last_forum_post[$forum_id] = $last_topic_post[$topic_id];
-			$topic = new ForumTopic($topic_id, $this->get_dummy_content('title'), '2011-03-31 12:10:00', 'Chamilo', 'Administrator', 0, $forum_id, $last_topic_post[$topic_id]);
-			$this->course->add_resource($topic);
-		}
-		// create forums
-		for ($forum_id = 1; $forum_id <= $number_of_forums; $forum_id ++)
-		{
-			$forum = new Forum($forum_id, $this->get_dummy_content('title'),$this->get_dummy_content('description'), rand(1, $number_of_categories), $last_forum_post[$forum_id]);
-			$this->course->add_resource($forum);
-		}
-	}
-	/**
-	 * Create dummy learnpaths
-	 */
-	function create_dummy_learnpaths()
-	{
-		$number_of_learnpaths = rand(3,5);
-		$global_item_id = 1;
-		for($i=1; $i<=$number_of_learnpaths;$i++)
-		{
-		$chapters = array();
-		$number_of_chapters = rand(1,6);
-		for($chapter_id = 1; $chapter_id <= $number_of_chapters; $chapter_id++)
-		{
-			$chapter['name'] = $this->get_dummy_content('title');
-			$chapter['description'] = $this->get_dummy_content('description');
-			$chapter['display_order'] = $chapter_id;
-			$chapter['items'] = array();
-			$number_of_items = rand(5,20);
-			for( $item_id = 1; $item_id<$number_of_items; $item_id++)
-			{
-				$types = array(RESOURCE_ANNOUNCEMENT, RESOURCE_EVENT, RESOURCE_DOCUMENT,RESOURCE_LINK,RESOURCE_FORUM,RESOURCE_FORUMPOST,RESOURCE_FORUMTOPIC);
-				$type = $types[rand(0,count($types)-1)];
-				$resources = $this->course->resources[$type];
-				$resource = $resources[rand(0,count($resources)-1)];
-				$item = array();
-				$item['type'] = $resource->type;
-				$item['id'] = $resource->source_id;
-				$item['display_order'] = $item_id;
-				$item['title'] = $this->get_dummy_content('title');
-				$item['description'] = $this->get_dummy_content('description');
-				$item['ref_id'] = $global_item_id;
-				if( rand(0,5) == 1 && $item_id > 1)
-				{
-					$item['prereq_type'] = 'i';
-					$item['prereq'] = rand($global_item_id - $item_id,$global_item_id-1);
-				}
-				$chapter['items'][] = $item;
-				$global_item_id++;
-			}
-			$chapters[] = $chapter;
-		}
-		$lp = new CourseCopyLearnpath($i,$this->get_dummy_content('title'),$this->get_dummy_content('description'),1,$chapters);
-		$this->course->add_resource($lp);
-		}
-	}
-	/**
-	 * Get dummy titles, descriptions and texts
-	 */
-	function get_dummy_content($type)
-	{
-		$dummy_text = 'Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Quisque lectus. Duis sodales. Vivamus et nunc. Phasellus interdum est a lorem. Fusce venenatis luctus lectus. Mauris quis turpis ac erat rhoncus suscipit. Phasellus elit dui, semper at, porta ut, egestas ac, enim. Quisque pellentesque, nisl nec consequat mollis, ipsum justo pellentesque nibh, non faucibus odio ante at lorem. Donec vitae pede ut felis ultricies semper. Suspendisse velit nibh, interdum quis, gravida nec, dapibus ac, leo. Cras id sem ut tellus tincidunt scelerisque. Aenean ac magna feugiat dolor accumsan dignissim. Integer eget nisl.
-		Ut sit amet nulla. Vestibulum venenatis posuere mauris. Nullam magna leo, blandit luctus, consequat quis, gravida nec, justo. Nam pede. Etiam ut nisl. In at quam scelerisque sapien faucibus commodo. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos hymenaeos. Proin mattis lorem quis nunc. Praesent placerat ligula id elit. Aenean blandit, purus sit amet pharetra auctor, libero orci rutrum felis, sit amet sodales mauris ipsum ultricies sapien. Vivamus wisi. Cras elit elit, ullamcorper ac, interdum nec, pulvinar nec, lacus. In lacus. Vivamus auctor, arcu vitae tincidunt porta, eros lacus tristique justo, vitae semper risus neque eget massa. Vivamus turpis.
-		Aenean ac wisi non enim aliquam scelerisque. Praesent eget mi. Vestibulum volutpat pulvinar justo. Phasellus sapien ante, pharetra id, bibendum sed, porta non, purus. Maecenas leo velit, luctus quis, porta non, feugiat sit amet, sapien. Proin vitae augue ut massa adipiscing placerat. Morbi ac risus. Proin dapibus eros egestas quam. Fusce fermentum lobortis elit. Duis lectus tellus, convallis nec, lobortis vel, accumsan ut, nunc. Nunc est. Donec ullamcorper laoreet quam.
-		Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos hymenaeos. Suspendisse potenti. Mauris mi. Vivamus risus lacus, faucibus sit amet, sollicitudin a, blandit et, justo. In hendrerit. Sed imperdiet, eros at fringilla tempor, turpis augue semper enim, quis rhoncus nibh enim quis dui. Sed massa sapien, mattis et, laoreet sit amet, dignissim nec, urna. Integer laoreet quam quis lectus. Curabitur convallis gravida dui. Nam metus. Ut sit amet augue in nibh interdum scelerisque. Donec venenatis, lacus et pulvinar euismod, libero massa condimentum pede, commodo tristique nunc massa eu quam. Donec vulputate. Aenean in nibh. Phasellus porttitor. Donec molestie, sem ac porttitor vulputate, mauris dui egestas libero, ac lobortis dolor sem vel ligula. Nam vulputate pretium libero. Cras accumsan. Vivamus lacinia sapien sit amet elit.
-		Duis bibendum elementum justo. Duis posuere. Fusce nulla odio, posuere eget, condimentum nec, venenatis eu, elit. In hac habitasse platea dictumst. Aenean ac sem in enim imperdiet feugiat. Integer tincidunt lectus at elit. Integer magna lacus, vehicula quis, eleifend eget, suscipit vitae, leo. Nunc porta augue nec enim. Curabitur vehicula volutpat enim. Aliquam consequat. Vestibulum rhoncus tellus vitae erat. Integer est. Quisque fermentum leo nec odio. Suspendisse lobortis sollicitudin augue. Nullam urna mi, suscipit eu, sagittis laoreet, ultrices ac, sem. Aliquam enim tortor, hendrerit non, cursus a, tristique sit amet, sapien. Suspendisse potenti. Aenean semper placerat neque.';
-		switch($type)
-		{
-		 case 'description':
-		 	$descriptions = explode(".",$dummy_text);
-		 	return $descriptions[rand(0,count($descriptions)-1)];
-		 	break;
-		 case 'title':
-		 	$dummy_text = str_replace(array("\n",'.',',',"\t"),array(' ','','',' '),$dummy_text);
-		 	$titles = explode(" ",$dummy_text);
-		 	return trim($titles[rand(0,count($titles)-1)]);
-		 	break;
-		 case 'text':
-		 	$texts = explode("\n",$dummy_text);
-		 	return $texts[rand(0,count($texts)-1)];
-		 	break;
-		}
-	}
+        $course = api_get_course_info($course_code);
+        $this->course = new Course();
+        $tmp_path = api_get_path(SYS_COURSE_PATH).$course['directory'].'/document/tmp_'.uniqid('');
+        @mkdir($tmp_path, api_get_permissions_for_new_directories(), true);
+        $this->course->backup_path = $tmp_path;
+        $this->create_dummy_links();
+        $this->create_dummy_events();
+        $this->create_dummy_forums();
+        $this->create_dummy_announcements();
+        $this->create_dummy_documents();
+        $this->create_dummy_learnpaths();
+        $cr = new CourseRestorer($this->course);
+        $cr->set_file_option(FILE_OVERWRITE);
+        $cr->restore($course_code);
+        rmdirr($tmp_path);
+    }
+    
+    /**
+     * Create dummy documents
+     */
+    public function create_dummy_documents()
+    {
+        $course = api_get_course_info();
+        $course_doc_path = $this->course->backup_path.'/document/';
+        $number_of_documents = rand(10, 30);
+        $extensions = array ('html', 'doc');
+        $directories = array();
+        $property = $this->default_property;
+        $property['lastedit_type'] = 'DocumentAdded';
+        $property['tool'] = TOOL_DOCUMENT;
+        $doc_id = 0;
+        for ($doc_id = 1; $doc_id < $number_of_documents; $doc_id ++)
+        {
+            $path = '';
+            $doc_type = rand(0, count($extensions) - 1);
+            $extension = $extensions[$doc_type];
+            $filename = $this->get_dummy_content('title').'_'.$doc_id.'.'.$extension;
+            $content = $this->get_dummy_content('text');
+            $dirs = rand(0, 3);
+            for ($i = 0; $i < $dirs; $i ++)
+            {
+                $path .= 'directory/';
+                $directories[$path] = 1;
+            }
+            $dir_to_make = $course_doc_path.$path;
+            if (!is_dir($dir_to_make))
+            {
+                @mkdir($dir_to_make, api_get_permissions_for_new_directories(), true);
+            }
+            $file = $course_doc_path.$path.$filename;
+            $fp = fopen($file, 'w');
+            fwrite($fp, $content);
+            fclose($fp);
+            $size = filesize($file);
+            $document = new Document($doc_id, '/'.$path.$filename,$this->get_dummy_content('description'),$this->get_dummy_content('title'), 'file', $size);
+            $document->item_properties[] = $property;
+            $this->course->add_resource($document);
+        }
+        foreach($directories as $path => $flag)
+        {
+            $path = substr($path,0,strlen($path)-1);
+            $document = new Document($doc_id++,'/'.$path, $this->get_dummy_content('description'),$this->get_dummy_content('title'),'folder',0);
+            $property['lastedit_type'] = 'FolderCreated';
+            $document->item_properties[] = $property;
+            $this->course->add_resource($document);
+        }
+    }
+    /**
+     * Create dummy announcements
+     */
+    function create_dummy_announcements()
+    {
+        $property = $this->default_property;
+        $property['lastedit_type'] = 'AnnouncementAdded';
+        $property['tool'] = TOOL_ANNOUNCEMENT;
+        $number_of_announcements = rand(10, 30);
+        for ($i = 0; $i < $number_of_announcements; $i ++)
+        {
+            $time = mktime(rand(1, 24), rand(1, 60), 0, rand(1, 12), rand(1, 28), intval(date('Y')));
+            $date = date('Y-m-d', $time);
+            $announcement = new Announcement($i,$this->get_dummy_content('title'),$this->get_dummy_content('text'), $date,0);
+            $announcement->item_properties[] = $property;
+            $this->course->add_resource($announcement);
+        }
+    }
+    /**
+     * Create dummy events
+     */
+    function create_dummy_events()
+    {
+        $number_of_events = rand(10, 30);
+        $property = $this->default_property;
+        $property['lastedit_type'] = 'AgendaAdded';
+        $property['tool'] = TOOL_CALENDAR_EVENT;
+        for ($i = 0; $i < $number_of_events; $i ++)
+        {
+            $hour = rand(1,24);
+            $minute = rand(1,60);
+            $second = rand(1,60);
+            $day = rand(1,28);
+            $month = rand(1,12);
+            $year = intval(date('Y'));
+            $time = mktime($hour,$minute,$second,$month,$day,$year);
+            $start_date = date('Y-m-d H:m:s', $time);
+            $hour = rand($hour,24);
+            $minute = rand($minute,60);
+            $second = rand($second,60);
+            $day = rand($day,28);
+            $month = rand($month,12);
+            $year = intval(date('Y'));
+            $time = mktime($hour,$minute,$second,$month,$day,$year);
+            $end_date = date('Y-m-d H:m:s', $time);
+            $event = new CalendarEvent(
+                $i,
+                $this->get_dummy_content('title'),
+                $this->get_dummy_content('text'),
+                $start_date,
+                $end_date
+            );
+            $event->item_properties[] = $property;
+            $this->course->add_resource($event);
+        }
+    }
+    /**
+     * Create dummy links
+     */
+    function create_dummy_links()
+    {
+        // create categorys
+        $number_of_categories = rand(5, 10);
+        for ($i = 0; $i < $number_of_categories; $i ++)
+        {
+            $linkcat = new LinkCategory($i, $this->get_dummy_content('title'), $this->get_dummy_content('description'),$i);
+            $this->course->add_resource($linkcat);
+        }
+        // create links
+        $number_of_links = rand(5, 50);
+        $on_homepage = rand(0,20) == 0 ? 1 : 0;
+        $property = $this->default_property;
+        $property['lastedit_type'] = 'LinkAdded';
+        $property['tool'] = TOOL_LINK;
+        for ($i = 0; $i < $number_of_links; $i ++)
+        {
+            $link = new Link($i, $this->get_dummy_content('title'), 'http://www.google.com/search?q='.$this->get_dummy_content('title'), $this->get_dummy_content('description'), rand(0, $number_of_categories -1),$on_homepage);
+            $link->item_properties[] = $property;
+            $this->course->add_resource($link);
+        }
+    }
+    /**
+     * Create dummy forums
+     */
+    function create_dummy_forums()
+    {
+        $number_of_categories = rand(2, 6);
+        $number_of_forums = rand(5, 50);
+        $number_of_topics = rand(30, 100);
+        $number_of_posts = rand(100, 1000);
+        $last_forum_post = array ();
+        $last_topic_post = array ();
+        // create categorys
+        $order = 1;
+        for ($i = 1; $i <= $number_of_categories; $i ++)
+        {
+            $forumcat = new ForumCategory($i, $this->get_dummy_content('title'), $this->get_dummy_content('description'), $order, 0, 0);
+            $this->course->add_resource($forumcat);
+            $order++;
+        }
+        // create posts
+        for ($post_id = 1; $post_id <= $number_of_posts; $post_id ++)
+        {
+            $topic_id = rand(1, $number_of_topics);
+            $last_topic_post[$topic_id] = $post_id;
+            $post = new ForumPost($post_id, $this->get_dummy_content('title'), $this->get_dummy_content('text'), date('Y-m-d H:i:s'), 1, 'Portal Administrator', 0, 0, $topic_id, 0, 1);
+            $this->course->add_resource($post);
+        }
+        // create topics
+        for ($topic_id = 1; $topic_id <= $number_of_topics; $topic_id ++)
+        {
+            $forum_id = rand(1, $number_of_forums);
+            $last_forum_post[$forum_id] = $last_topic_post[$topic_id];
+            $topic = new ForumTopic($topic_id, $this->get_dummy_content('title'), '2011-03-31 12:10:00', 'Chamilo', 'Administrator', 0, $forum_id, $last_topic_post[$topic_id]);
+            $this->course->add_resource($topic);
+        }
+        // create forums
+        for ($forum_id = 1; $forum_id <= $number_of_forums; $forum_id ++)
+        {
+            $forum = new Forum($forum_id, $this->get_dummy_content('title'),$this->get_dummy_content('description'), rand(1, $number_of_categories), $last_forum_post[$forum_id]);
+            $this->course->add_resource($forum);
+        }
+    }
+    /**
+     * Create dummy learnpaths
+     */
+    function create_dummy_learnpaths()
+    {
+        $number_of_learnpaths = rand(3,5);
+        $global_item_id = 1;
+        for($i=1; $i<=$number_of_learnpaths;$i++)
+        {
+        $chapters = array();
+        $number_of_chapters = rand(1,6);
+        for($chapter_id = 1; $chapter_id <= $number_of_chapters; $chapter_id++)
+        {
+            $chapter['name'] = $this->get_dummy_content('title');
+            $chapter['description'] = $this->get_dummy_content('description');
+            $chapter['display_order'] = $chapter_id;
+            $chapter['items'] = array();
+            $number_of_items = rand(5,20);
+            for( $item_id = 1; $item_id<$number_of_items; $item_id++)
+            {
+                $types = array(RESOURCE_ANNOUNCEMENT, RESOURCE_EVENT, RESOURCE_DOCUMENT,RESOURCE_LINK,RESOURCE_FORUM,RESOURCE_FORUMPOST,RESOURCE_FORUMTOPIC);
+                $type = $types[rand(0,count($types)-1)];
+                $resources = $this->course->resources[$type];
+                $resource = $resources[rand(0,count($resources)-1)];
+                $item = array();
+                $item['type'] = $resource->type;
+                $item['id'] = $resource->source_id;
+                $item['display_order'] = $item_id;
+                $item['title'] = $this->get_dummy_content('title');
+                $item['description'] = $this->get_dummy_content('description');
+                $item['ref_id'] = $global_item_id;
+                if( rand(0,5) == 1 && $item_id > 1)
+                {
+                    $item['prereq_type'] = 'i';
+                    $item['prereq'] = rand($global_item_id - $item_id,$global_item_id-1);
+                }
+                $chapter['items'][] = $item;
+                $global_item_id++;
+            }
+            $chapters[] = $chapter;
+        }
+        $lp = new CourseCopyLearnpath($i,$this->get_dummy_content('title'),$this->get_dummy_content('description'),1,$chapters);
+        $this->course->add_resource($lp);
+        }
+    }
+    /**
+     * Get dummy titles, descriptions and texts
+     */
+    function get_dummy_content($type)
+    {
+        $dummy_text = 'Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Quisque lectus. Duis sodales. Vivamus et nunc. Phasellus interdum est a lorem. Fusce venenatis luctus lectus. Mauris quis turpis ac erat rhoncus suscipit. Phasellus elit dui, semper at, porta ut, egestas ac, enim. Quisque pellentesque, nisl nec consequat mollis, ipsum justo pellentesque nibh, non faucibus odio ante at lorem. Donec vitae pede ut felis ultricies semper. Suspendisse velit nibh, interdum quis, gravida nec, dapibus ac, leo. Cras id sem ut tellus tincidunt scelerisque. Aenean ac magna feugiat dolor accumsan dignissim. Integer eget nisl.
+        Ut sit amet nulla. Vestibulum venenatis posuere mauris. Nullam magna leo, blandit luctus, consequat quis, gravida nec, justo. Nam pede. Etiam ut nisl. In at quam scelerisque sapien faucibus commodo. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos hymenaeos. Proin mattis lorem quis nunc. Praesent placerat ligula id elit. Aenean blandit, purus sit amet pharetra auctor, libero orci rutrum felis, sit amet sodales mauris ipsum ultricies sapien. Vivamus wisi. Cras elit elit, ullamcorper ac, interdum nec, pulvinar nec, lacus. In lacus. Vivamus auctor, arcu vitae tincidunt porta, eros lacus tristique justo, vitae semper risus neque eget massa. Vivamus turpis.
+        Aenean ac wisi non enim aliquam scelerisque. Praesent eget mi. Vestibulum volutpat pulvinar justo. Phasellus sapien ante, pharetra id, bibendum sed, porta non, purus. Maecenas leo velit, luctus quis, porta non, feugiat sit amet, sapien. Proin vitae augue ut massa adipiscing placerat. Morbi ac risus. Proin dapibus eros egestas quam. Fusce fermentum lobortis elit. Duis lectus tellus, convallis nec, lobortis vel, accumsan ut, nunc. Nunc est. Donec ullamcorper laoreet quam.
+        Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos hymenaeos. Suspendisse potenti. Mauris mi. Vivamus risus lacus, faucibus sit amet, sollicitudin a, blandit et, justo. In hendrerit. Sed imperdiet, eros at fringilla tempor, turpis augue semper enim, quis rhoncus nibh enim quis dui. Sed massa sapien, mattis et, laoreet sit amet, dignissim nec, urna. Integer laoreet quam quis lectus. Curabitur convallis gravida dui. Nam metus. Ut sit amet augue in nibh interdum scelerisque. Donec venenatis, lacus et pulvinar euismod, libero massa condimentum pede, commodo tristique nunc massa eu quam. Donec vulputate. Aenean in nibh. Phasellus porttitor. Donec molestie, sem ac porttitor vulputate, mauris dui egestas libero, ac lobortis dolor sem vel ligula. Nam vulputate pretium libero. Cras accumsan. Vivamus lacinia sapien sit amet elit.
+        Duis bibendum elementum justo. Duis posuere. Fusce nulla odio, posuere eget, condimentum nec, venenatis eu, elit. In hac habitasse platea dictumst. Aenean ac sem in enim imperdiet feugiat. Integer tincidunt lectus at elit. Integer magna lacus, vehicula quis, eleifend eget, suscipit vitae, leo. Nunc porta augue nec enim. Curabitur vehicula volutpat enim. Aliquam consequat. Vestibulum rhoncus tellus vitae erat. Integer est. Quisque fermentum leo nec odio. Suspendisse lobortis sollicitudin augue. Nullam urna mi, suscipit eu, sagittis laoreet, ultrices ac, sem. Aliquam enim tortor, hendrerit non, cursus a, tristique sit amet, sapien. Suspendisse potenti. Aenean semper placerat neque.';
+        switch($type)
+        {
+         case 'description':
+            $descriptions = explode(".",$dummy_text);
+            return $descriptions[rand(0,count($descriptions)-1)];
+            break;
+         case 'title':
+            $dummy_text = str_replace(array("\n",'.',',',"\t"),array(' ','','',' '),$dummy_text);
+            $titles = explode(" ",$dummy_text);
+            return trim($titles[rand(0,count($titles)-1)]);
+            break;
+         case 'text':
+            $texts = explode("\n",$dummy_text);
+            return $texts[rand(0,count($texts)-1)];
+            break;
+        }
+    }
 }

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

@@ -80,7 +80,7 @@ class CalendarEvent extends Coursecopy\Resource
     /**
      * Show this Event
      */
-    function show()
+    public function show()
     {
         parent::show();
         echo $this->title.' ('.$this->start_date.' -> '.$this->end_date.')';

+ 3 - 2
main/coursecopy/classes/Forum.class.php

@@ -103,7 +103,7 @@ class Forum extends Coursecopy\Resource
     /**
      * Create a new Forum
      */
-    function __construct($obj)
+    public function __construct($obj)
     {
         parent::__construct($obj->forum_id, RESOURCE_FORUM);
         $this->obj = $obj;
@@ -112,7 +112,8 @@ class Forum extends Coursecopy\Resource
     /**
      * Show this resource
      */
-    function show() {
+    public function show()
+    {
         parent::show();
         echo $this->obj->forum_title;
     }

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

@@ -22,7 +22,7 @@ class ForumCategory extends Coursecopy\Resource
     /**
      * Show this resource
      */
-    function show()
+    public function show()
     {
         parent::show();
         echo $this->obj->cat_title;

+ 2 - 2
main/coursecopy/classes/ForumTopic.class.php

@@ -15,7 +15,7 @@ class ForumTopic extends Coursecopy\Resource
      */
     /* function ForumTopic($id, $title, $time, $topic_poster_id, $topic_poster_name, $forum_id, $last_post, $replies, $views = 0, $sticky = 0, $locked = 0,
       $time_closed = null, $weight = 0, $title_qualify = null, $qualify_max = 0) */
-    function __construct($obj)
+    public function __construct($obj)
     {
         parent::__construct($obj->thread_id, RESOURCE_FORUMTOPIC);
         $this->obj = $obj;
@@ -39,7 +39,7 @@ class ForumTopic extends Coursecopy\Resource
     /**
      * Show this resource
      */
-    function show()
+    public function show()
     {
         parent::show();
         $extra = api_convert_and_format_date($this->obj->thread_date);

+ 25 - 25
main/coursecopy/classes/Glossary.class.php

@@ -10,33 +10,33 @@ require_once 'Resource.class.php';
  */
 class Glossary extends Coursecopy\Resource
 {
-	public $glossary_id;
-	public $name;
-	public $description;
-	public $display_order;
+    public $glossary_id;
+    public $name;
+    public $description;
+    public $display_order;
 
-	/**
-	 * Create a new Glossary
-	 * @param int $id
-	 * @param string $name
-	 * @param string $description
-	 * @param int $display_order
-	 */
+    /**
+     * Create a new Glossary
+     * @param int $id
+     * @param string $name
+     * @param string $description
+     * @param int $display_order
+     */
     public function __construct($id,$name,$description,$display_order)
-	{
-		parent::__construct($id,RESOURCE_GLOSSARY);
-		$this->glossary_id = $id;
-		$this->name = $name;
-		$this->description = $description;
-		$this->display_order = $display_order;
-	}
+    {
+        parent::__construct($id,RESOURCE_GLOSSARY);
+        $this->glossary_id = $id;
+        $this->name = $name;
+        $this->description = $description;
+        $this->display_order = $display_order;
+    }
 
-	/**
-	 * Show this glossary
-	 */
-	public function show()
+    /**
+     * Show this glossary
+     */
+    public function show()
     {
-		parent::show();
-		echo $this->name;
-	}
+        parent::show();
+        echo $this->name;
+    }
 }

+ 36 - 37
main/coursecopy/classes/Link.class.php

@@ -11,33 +11,33 @@ require_once 'Resource.class.php';
  */
 class Link extends Coursecopy\Resource
 {
-	/**
-	 * The title
-	 */
+    /**
+     * The title
+     */
     public $title;
-	/**
-	 * The URL
-	 */
+    /**
+     * The URL
+     */
     public $url;
-	/**
-	 * The description
-	 */
+    /**
+     * The description
+     */
     public $description;
-	/**
-	 * Id of this links category
-	 */
+    /**
+     * Id of this links category
+     */
     public $category_id;
-	/**
-	 * Display link on course homepage
-	 */
+    /**
+     * Display link on course homepage
+     */
     public $on_homepage;
-	/**
-	 * Create a new Link
-	 * @param int $id The id of this link in the Chamilo-course
-	 * @param string $title
-	 * @param string $url
-	 * @param string $description
-	 */
+    /**
+     * Create a new Link
+     * @param int $id The id of this link in the Chamilo-course
+     * @param string $title
+     * @param string $url
+     * @param string $description
+     */
     public function __construct(
         $id,
         $title,
@@ -45,22 +45,21 @@ class Link extends Coursecopy\Resource
         $description,
         $category_id,
         $on_homepage
-    )
-	{
-		parent::__construct($id,RESOURCE_LINK);
-		$this->title = $title;
-		$this->url = $url;
-		$this->description = $description;
-		$this->category_id = $category_id;
-		$this->on_homepage = $on_homepage;
-	}
+    ) {
+        parent::__construct($id,RESOURCE_LINK);
+        $this->title = $title;
+        $this->url = $url;
+        $this->description = $description;
+        $this->category_id = $category_id;
+        $this->on_homepage = $on_homepage;
+    }
 
     /**
-	 * Show this resource
-	 */
+     * Show this resource
+     */
     public function show()
-	{
-		parent::show();
-		echo $this->title.' ('.$this->url.')';
-	}
+    {
+        parent::show();
+        echo $this->title.' ('.$this->url.')';
+    }
 }

+ 33 - 33
main/coursecopy/classes/LinkCategory.class.php

@@ -10,39 +10,39 @@ require_once 'Resource.class.php';
  */
 class LinkCategory extends Coursecopy\Resource
 {
-	/**
-	 * The title
-	 */
-	public $title;
-	/**
-	 * The description
-	 */
-	public $description;
-	/**
-	 * The display order
-	 */
-	public $display_order;
+    /**
+     * The title
+     */
+    public $title;
+    /**
+     * The description
+     */
+    public $description;
+    /**
+     * The display order
+     */
+    public $display_order;
 
-	/**
-	 * Create a new LinkCategory
-	 * @param int $id
-	 * @param string $title
-	 * @param string $description
-	 */
-	function __construct($id,$title,$description,$display_order)
-	{
-		parent::__construct($id,RESOURCE_LINKCATEGORY);
-		$this->title = $title;
-		$this->description = $description;
-		$this->display_order = $display_order;
-	}
+    /**
+     * Create a new LinkCategory
+     * @param int $id
+     * @param string $title
+     * @param string $description
+     */
+    public function __construct($id,$title,$description,$display_order)
+    {
+        parent::__construct($id,RESOURCE_LINKCATEGORY);
+        $this->title = $title;
+        $this->description = $description;
+        $this->display_order = $display_order;
+    }
 
-	/**
-	 * Show this LinkCategory
-	 */
-	function show()
-	{
-		parent::show();
-		echo $this->title.' '.$this->description.'<br />';
-	}
+    /**
+     * Show this LinkCategory
+     */
+    public function show()
+    {
+        parent::show();
+        echo $this->title.' '.$this->description.'<br />';
+    }
 }

+ 4 - 0
main/coursecopy/classes/Quiz.class.php

@@ -21,6 +21,10 @@ class Quiz extends Coursecopy\Resource
      */
     public $obj; //question
 
+    /**
+     * Quiz constructor.
+     * @param int $obj
+     */
     public function __construct($obj)
     {
         $this->obj = $obj;

+ 37 - 16
main/coursecopy/classes/Resource.class.php

@@ -233,28 +233,49 @@ class Resource
     }
 
     /**
-     * Fix objects coming from  1.9.x to 1.10.x
+     * Fix objects coming from 1.9.x to 1.10.x
      * Example class Event to CalendarEvent
      *
      * @param Resource $resource
      */
     public static function setClassType(&$resource)
     {
-        if (get_class($resource) == 'Event') {
-            /** @var $resource CalendarEvent */
-            $newResource = new CalendarEvent(
-                $resource->source_id,
-                $resource->title,
-                $resource->content,
-                $resource->start_date,
-                $resource->end_date,
-                $resource->attachment_path,
-                $resource->attachment_filename,
-                $resource->attachment_size,
-                $resource->attachment_comment,
-                $resource->all_day
-            );
-            $resource = $newResource;
+        $class = get_class($resource);
+        switch ($class) {
+            case 'Event':
+                /** @var $resource \CalendarEvent */
+                $newResource = new \CalendarEvent(
+                    $resource->source_id,
+                    $resource->title,
+                    $resource->content,
+                    $resource->start_date,
+                    $resource->end_date,
+                    $resource->attachment_path,
+                    $resource->attachment_filename,
+                    $resource->attachment_size,
+                    $resource->attachment_comment,
+                    $resource->all_day
+                );
+                $resource = $newResource;
+                break;
+            case 'CourseDescription':
+                if (!method_exists($resource, 'show')) {
+                    $resource = (array) $resource;
+                    $newResource = new CourseDescription(
+                        isset($resource['id']) ? $resource['id'] : '',
+                        $resource['title'],
+                        $resource['content'],
+                        $resource['description_type']
+                    );
+                    $newResource->source_id = $resource['source_id'];
+                    $newResource->destination_id = $resource['source_id'];
+                    $newResource->linked_resources = $resource['source_id'];
+                    $newResource->item_properties = $resource['source_id'];
+                    $newResource->obj = $resource['obj'];
+                    $resource = $newResource;
+                }
+
+                break;
         }
     }
 }

+ 11 - 11
main/coursecopy/classes/ScormDocument.class.php

@@ -13,18 +13,18 @@ class ScormDocument extends Coursecopy\Resource
     public $path;
     public $title;
 
-	/**
-	 * Create a new Scorm Document
-	 * @param int $id
-	 * @param string $path
-	 * @param string $title
-	 */
+    /**
+     * Create a new Scorm Document
+     * @param int $id
+     * @param string $path
+     * @param string $title
+     */
     public function __construct($id, $path, $title)
-	{
-		parent::__construct($id,RESOURCE_SCORM);
-		$this->path = 'scorm'.$path;
-		$this->title = $title;
-	}
+    {
+        parent::__construct($id,RESOURCE_SCORM);
+        $this->path = 'scorm'.$path;
+        $this->title = $title;
+    }
 
     /**
      * Show this document

+ 103 - 103
main/coursecopy/classes/Survey.class.php

@@ -10,86 +10,86 @@ require_once 'Resource.class.php';
  */
 class Survey extends Coursecopy\Resource
 {
-	/**
-	 * The survey code
-	 */
+    /**
+     * The survey code
+     */
     public $code;
-	/**
-	 * The title and subtitle
-	 */
+    /**
+     * The title and subtitle
+     */
     public $title;
     public $subtitle;
-	/**
-	 * The author's name
-	 */
+    /**
+     * The author's name
+     */
     public $author;
-	/**
-	 * The survey's language
-	 */
+    /**
+     * The survey's language
+     */
     public $lang;
-	/**
-	 * The availability period
-	 */
+    /**
+     * The availability period
+     */
     public $avail_from;
     public $avail_till;
-	/**
-	 * Flag for shared status
-	 */
+    /**
+     * Flag for shared status
+     */
     public $is_shared;
-	/**
-	 * Template used
-	 */
+    /**
+     * Template used
+     */
     public $template;
-	/**
-	 * Introduction text
-	 */
+    /**
+     * Introduction text
+     */
     public $intro;
-	/**
-	 * Thanks text
-	 */
+    /**
+     * Thanks text
+     */
     public $surveythanks;
-	/**
-	 * Creation date
-	 */
+    /**
+     * Creation date
+     */
     public $creation_date;
-	/**
-	 * Invitation status
-	 */
+    /**
+     * Invitation status
+     */
     public $invited;
-	/**
-	 * Answer status
-	 */
+    /**
+     * Answer status
+     */
     public $answered;
-	/**
-	 * Invitation and reminder mail contents
-	 */
+    /**
+     * Invitation and reminder mail contents
+     */
     public $invite_mail;
     public $reminder_mail;
-	/**
-	 * Questions and invitations lists
-	 */
+    /**
+     * Questions and invitations lists
+     */
     public $question_ids;
     public $invitation_ids;
 
-	/**
-	 * Create a new Survey
-	 * @param string $code
-	 * @param string $title
-	 * @param string $subtitle
-	 * @param string $author
-	 * @param string $lang
-	 * @param string $avail_from
-	 * @param string $avail_till
-	 * @param char $is_shared
-	 * @param string $template
-	 * @param string $intro
-	 * @param string $surveythanks
-	 * @param string $creation_date
-	 * @param int $invited
-	 * @param int $answered
-	 * @param string $invite_mail
-	 * @param string $reminder_mail
-	 */
+    /**
+     * Create a new Survey
+     * @param string $code
+     * @param string $title
+     * @param string $subtitle
+     * @param string $author
+     * @param string $lang
+     * @param string $avail_from
+     * @param string $avail_till
+     * @param char $is_shared
+     * @param string $template
+     * @param string $intro
+     * @param string $surveythanks
+     * @param string $creation_date
+     * @param int $invited
+     * @param int $answered
+     * @param string $invite_mail
+     * @param string $reminder_mail
+     */
     public function __construct(
         $id,
         $code,
@@ -109,49 +109,49 @@ class Survey extends Coursecopy\Resource
         $invite_mail,
         $reminder_mail
     ) {
-		parent::__construct($id,RESOURCE_SURVEY);
-		$this->code = $code;
-		$this->title = $title;
-		$this->subtitle = $subtitle;
-		$this->author = $author;
-		$this->lang = $lang;
-		$this->avail_from = $avail_from;
-		$this->avail_till = $avail_till;
-		$this->is_shared = $is_shared;
-		$this->template = $template;
-		$this->intro = $intro;
-		$this->surveythanks = $surveythanks;
-		$this->creation_date = $creation_date;
-		$this->invited = $invited;
-		$this->answered = $answered;
-		$this->invite_mail = $invite_mail;
-		$this->reminder_mail = $reminder_mail;
-		$this->question_ids = array();
-		$this->invitation_ids = array();
-	}
+        parent::__construct($id, RESOURCE_SURVEY);
+        $this->code = $code;
+        $this->title = $title;
+        $this->subtitle = $subtitle;
+        $this->author = $author;
+        $this->lang = $lang;
+        $this->avail_from = $avail_from;
+        $this->avail_till = $avail_till;
+        $this->is_shared = $is_shared;
+        $this->template = $template;
+        $this->intro = $intro;
+        $this->surveythanks = $surveythanks;
+        $this->creation_date = $creation_date;
+        $this->invited = $invited;
+        $this->answered = $answered;
+        $this->invite_mail = $invite_mail;
+        $this->reminder_mail = $reminder_mail;
+        $this->question_ids = array();
+        $this->invitation_ids = array();
+    }
 
-	/**
-	 * Add a question to this survey
-	 */
-	function add_question($id)
-	{
-		$this->question_ids[] = $id;
-	}
+    /**
+     * Add a question to this survey
+     */
+    public function add_question($id)
+    {
+        $this->question_ids[] = $id;
+    }
 
-	/**
-	 * Add an invitation to this survey
-	 */
-	function add_invitation($id)
-	{
-		$this->invitation_ids[] = $id;
-	}
+    /**
+     * Add an invitation to this survey
+     */
+    public function add_invitation($id)
+    {
+        $this->invitation_ids[] = $id;
+    }
 
-	/**
-	 * Show this survey
-	 */
-	function show()
-	{
-		parent::show();
-		echo $this->code.' - '.$this->title;
-	}
+    /**
+     * Show this survey
+     */
+    public function show()
+    {
+        parent::show();
+        echo $this->code.' - '.$this->title;
+    }
 }

+ 46 - 46
main/coursecopy/classes/SurveyInvitation.class.php

@@ -10,52 +10,52 @@ require_once 'Resource.class.php';
  */
 class SurveyInvitation extends Coursecopy\Resource
 {
-	/**
-	 * Survey code
-	 */
-	public $code;
-	/**
-	 * User info
-	 */
-	public $user;
-	/**
-	 * Invitation code
-	 */
-	public $invitation_code;
-	/**
-	 * Invitation date
-	 */
-	public $invitation_date;
-	/**
-	 * Reminder date
-	 */
-	public $reminder_date;
+    /**
+     * Survey code
+     */
+    public $code;
+    /**
+     * User info
+     */
+    public $user;
+    /**
+     * Invitation code
+     */
+    public $invitation_code;
+    /**
+     * Invitation date
+     */
+    public $invitation_date;
+    /**
+     * Reminder date
+     */
+    public $reminder_date;
 
-	/**
-	 * Create a new SurveyInvitation
-	 * @param	int	 $id
-	 * @param string $code
-	 * @param string $user
-	 * @param string $invitation_code
-	 * @param string $invitation_date
-	 * @param string $reminder_date
-	 */
-	public function __construct($id,$code,$user,$invitation_code,$invitation_date,$reminder_date)
-	{
-		parent::__construct($id, RESOURCE_SURVEYINVITATION);
-		$this->code = $code;
-		$this->user = $user;
-		$this->invitation_code = $invitation_code;
-		$this->invitation_date = $invitation_date;
-		$this->reminder_date = $reminder_date;
-	}
+    /**
+     * Create a new SurveyInvitation
+     * @param int	 $id
+     * @param string $code
+     * @param string $user
+     * @param string $invitation_code
+     * @param string $invitation_date
+     * @param string $reminder_date
+     */
+    public function __construct($id, $code, $user, $invitation_code, $invitation_date, $reminder_date)
+    {
+        parent::__construct($id, RESOURCE_SURVEYINVITATION);
+        $this->code = $code;
+        $this->user = $user;
+        $this->invitation_code = $invitation_code;
+        $this->invitation_date = $invitation_date;
+        $this->reminder_date = $reminder_date;
+    }
 
-	/**
-	 * Show this invitation
-	 */
-	function show()
-	{
-		parent::show();
-		echo $this->invitation_code;
-	}
+    /**
+     * Show this invitation
+     */
+    public function show()
+    {
+        parent::show();
+        echo $this->invitation_code;
+    }
 }

+ 88 - 87
main/coursecopy/classes/SurveyQuestion.class.php

@@ -10,93 +10,94 @@ require_once 'Resource.class.php';
  */
 class SurveyQuestion extends Coursecopy\Resource
 {
-	/**
-	 * Survey ID
-	 */
-	public $survey_id;
-	/**
-	 * Question and question comment
-	 */
-	public $survey_question;
-	public $survey_question_comment;
-	/**
-	 * Question type
-	 */
-	public $survey_question_type;
-	/**
-	 * Display ?
-	 */
-	public $display;
-	/**
-	 * Sorting order
-	 */
-	public $sort;
-	/**
-	 * Shared question ID
-	 */
-	public $shared_question_id;
-	/**
-	 * Maximum value for the vote
-	 */
-	public $max_value;
+    /**
+     * Survey ID
+     */
+    public $survey_id;
+    /**
+     * Question and question comment
+     */
+    public $survey_question;
+    public $survey_question_comment;
+    /**
+     * Question type
+     */
+    public $survey_question_type;
+    /**
+     * Display ?
+     */
+    public $display;
+    /**
+     * Sorting order
+     */
+    public $sort;
+    /**
+     * Shared question ID
+     */
+    public $shared_question_id;
+    /**
+     * Maximum value for the vote
+     */
+    public $max_value;
 
-	/**
-	 * Question's options
-	 */
-	public $options;
+    /**
+     * Question's options
+     */
+    public $options;
 
-	/**
-	 * Create a new SurveyQuestion
-	 * @param int	 $id
-	 * @param int 	 $survey_id
-	 * @param string $survey_question
-	 * @param string $survey_question_comment
-	 * @param string $type
-	 * @param string $display
-	 * @param int	 $sort
-	 * @param int	 $shared_question_id
-	 * @param int	 $max_value
-	 */
-	function __construct(
-		$id,
-		$survey_id,
-		$survey_question,
-		$survey_question_comment,
-		$type,
-		$display,
-		$sort,
-		$shared_question_id,
-		$max_value
-	) {
-		parent::__construct($id,RESOURCE_SURVEYQUESTION);
-		$this->survey_id = $survey_id;
-		$this->survey_question = $survey_question;
-		$this->survey_question_comment = $survey_question_comment;
-		$this->survey_question_type = $type;
-		$this->display = $display;
-		$this->sort = $sort;
-		$this->shared_question_id = $shared_question_id;
-		$this->max_value = $max_value;
-		$this->answers = array();
-	}
-	/**
-	 * Add an answer option to this SurveyQuestion
-	 * @param string $option_text
-	 * @param int	 $sort
-	 */
-	function add_answer($option_text,$sort)
-	{
-		$answer = array();
-		$answer['option_text'] = $option_text;
-		$answer['sort'] = $sort;
-		$this->answers[] = $answer;
-	}
-	/**
-	 * Show this question
-	 */
-	function show()
-	{
-		parent::show();
-		echo $this->survey_question;
-	}
+    /**
+     * Create a new SurveyQuestion
+     * @param int	 $id
+     * @param int 	 $survey_id
+     * @param string $survey_question
+     * @param string $survey_question_comment
+     * @param string $type
+     * @param string $display
+     * @param int	 $sort
+     * @param int	 $shared_question_id
+     * @param int	 $max_value
+     */
+    public function __construct(
+        $id,
+        $survey_id,
+        $survey_question,
+        $survey_question_comment,
+        $type,
+        $display,
+        $sort,
+        $shared_question_id,
+        $max_value
+    ) {
+        parent::__construct($id, RESOURCE_SURVEYQUESTION);
+        $this->survey_id = $survey_id;
+        $this->survey_question = $survey_question;
+        $this->survey_question_comment = $survey_question_comment;
+        $this->survey_question_type = $type;
+        $this->display = $display;
+        $this->sort = $sort;
+        $this->shared_question_id = $shared_question_id;
+        $this->max_value = $max_value;
+        $this->answers = array();
+    }
+
+    /**
+     * Add an answer option to this SurveyQuestion
+     * @param string $option_text
+     * @param int	 $sort
+     */
+    public function add_answer($option_text,$sort)
+    {
+        $answer = array();
+        $answer['option_text'] = $option_text;
+        $answer['sort'] = $sort;
+        $this->answers[] = $answer;
+    }
+    /**
+     * Show this question
+     */
+    public function show()
+    {
+        parent::show();
+        echo $this->survey_question;
+    }
 }

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

@@ -16,7 +16,7 @@ class Thematic extends Coursecopy\Resource
     /**
     * Create a new Thematic
     *
-    * @param array parameters
+    * @param array $params
     */
     public function __construct($params)
     {

+ 75 - 75
main/coursecopy/classes/ToolIntro.class.php

@@ -10,82 +10,82 @@ require_once 'Resource.class.php';
  */
 class ToolIntro extends Coursecopy\Resource
 {
-	public $id;
+    public $id;
 
-	/**
-	 * intro text
-	 */
-	public $intro_text;
+    /**
+     * intro text
+     */
+    public $intro_text;
 
-	/**
-	 * Create a new text introduction
-	 * @param int $id The id of this tool introduction in the Chamilo-course
-	 * @param string $intro_text
-	 */
-	public function __construct($id, $intro_text)
-	{
-		parent::__construct($id, RESOURCE_TOOL_INTRO);
-		$this->id = $id;
-		$this->intro_text = $intro_text;
-	}
+    /**
+     * Create a new text introduction
+     * @param int $id The id of this tool introduction in the Chamilo-course
+     * @param string $intro_text
+     */
+    public function __construct($id, $intro_text)
+    {
+        parent::__construct($id, RESOURCE_TOOL_INTRO);
+        $this->id = $id;
+        $this->intro_text = $intro_text;
+    }
 
-	/**
-	 * Show this resource
-	 */
-	function show()
-	{
-		parent::show();
-		switch ($this->id)
-		{
-			case TOOL_DOCUMENT:
-				$lang_id = 'Documents';
-				break;
-			case TOOL_CALENDAR_EVENT:
-				$lang_id = 'Agenda';
-				break;
-			case TOOL_LINK:
-				$lang_id = 'Links';
-				break;
-			case TOOL_LEARNPATH:
-				$lang_id = 'LearningPath';
-				break;
-			case TOOL_ANNOUNCEMENT:
-				$lang_id = 'Announcements';
-				break;
-			case TOOL_FORUM:
-				$lang_id = 'Forums';
-				break;
-			case TOOL_DROPBOX:
-				$lang_id = 'Dropbox';
-				break;
-			case TOOL_QUIZ:
-				$lang_id = 'Exercises';
-				break;
-			case TOOL_USER:
-				$lang_id = 'Users';
-				break;
-			case TOOL_GROUP:
-				$lang_id = 'Group';
-				break;
-			case TOOL_WIKI:
-				$lang_id = 'Wiki';
-				break;
-			case TOOL_STUDENTPUBLICATION:
-				$lang_id = 'StudentPublications';
-				break;
-			case TOOL_COURSE_HOMEPAGE:
-				$lang_id = 'CourseHomepageLink';
-				break;
-			case TOOL_GLOSSARY:
-				$lang_id = 'Glossary';
-				break;
-			case TOOL_NOTEBOOK:
-				$lang_id = 'Notebook';
-				break;
-			default:
-				$lang_id = ucfirst($this->id); // This is a wild guess.
-		}
-		echo '<strong>'.get_lang($lang_id, '').':</strong><br />';
-		echo $this->intro_text;
-	}
+    /**
+     * Show this resource
+     */
+    public function show()
+    {
+        parent::show();
+        switch ($this->id)
+        {
+            case TOOL_DOCUMENT:
+                $lang_id = 'Documents';
+                break;
+            case TOOL_CALENDAR_EVENT:
+                $lang_id = 'Agenda';
+                break;
+            case TOOL_LINK:
+                $lang_id = 'Links';
+                break;
+            case TOOL_LEARNPATH:
+                $lang_id = 'LearningPath';
+                break;
+            case TOOL_ANNOUNCEMENT:
+                $lang_id = 'Announcements';
+                break;
+            case TOOL_FORUM:
+                $lang_id = 'Forums';
+                break;
+            case TOOL_DROPBOX:
+                $lang_id = 'Dropbox';
+                break;
+            case TOOL_QUIZ:
+                $lang_id = 'Exercises';
+                break;
+            case TOOL_USER:
+                $lang_id = 'Users';
+                break;
+            case TOOL_GROUP:
+                $lang_id = 'Group';
+                break;
+            case TOOL_WIKI:
+                $lang_id = 'Wiki';
+                break;
+            case TOOL_STUDENTPUBLICATION:
+                $lang_id = 'StudentPublications';
+                break;
+            case TOOL_COURSE_HOMEPAGE:
+                $lang_id = 'CourseHomepageLink';
+                break;
+            case TOOL_GLOSSARY:
+                $lang_id = 'Glossary';
+                break;
+            case TOOL_NOTEBOOK:
+                $lang_id = 'Notebook';
+                break;
+            default:
+                $lang_id = ucfirst($this->id); // This is a wild guess.
+        }
+        echo '<strong>'.get_lang($lang_id, '').':</strong><br />';
+        echo $this->intro_text;
+    }
 }

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

@@ -15,7 +15,7 @@ class Work extends Coursecopy\Resource
     /**
      * Create a new Work
      *
-     * @param array parameters
+     * @param array $params
      */
     public function __construct($params)
     {

+ 42 - 42
main/coursecopy/classes/wiki.class.php

@@ -9,43 +9,43 @@
  */
 class Wiki extends Coursecopy\Resource
 {
-	public $id;
-	public $page_id;
-	public $reflink;
-	public $title;
-	public $content;
-	public $user_id;
-	public $group_id;
-	public $timestamp;
-	public $progress;
-	public $version;
+    public $id;
+    public $page_id;
+    public $reflink;
+    public $title;
+    public $content;
+    public $user_id;
+    public $group_id;
+    public $timestamp;
+    public $progress;
+    public $version;
 
-	/**
-	 * Wiki constructor.
-	 * @param int $id
-	 * @param int $page_id
-	 * @param $reflink
-	 * @param $title
-	 * @param $content
-	 * @param $user_id
-	 * @param $group_id
-	 * @param $timestamp
-	 * @param $progress
-	 * @param $version
-	 */
-	public function __construct(
-		$id,
-		$page_id,
-		$reflink,
-		$title,
-		$content,
-		$user_id,
-		$group_id,
-		$timestamp,
-		$progress,
-		$version
-	) {
-		parent::__construct($id,RESOURCE_WIKI);
+    /**
+     * Wiki constructor.
+     * @param int $id
+     * @param int $page_id
+     * @param $reflink
+     * @param $title
+     * @param $content
+     * @param $user_id
+     * @param $group_id
+     * @param $timestamp
+     * @param $progress
+     * @param $version
+     */
+    public function __construct(
+        $id,
+        $page_id,
+        $reflink,
+        $title,
+        $content,
+        $user_id,
+        $group_id,
+        $timestamp,
+        $progress,
+        $version
+    ) {
+        parent::__construct($id,RESOURCE_WIKI);
         $this->id = $id;
         $this->page_id = $page_id;
         $this->reflink = $reflink;
@@ -56,11 +56,11 @@ class Wiki extends Coursecopy\Resource
         $this->dtime = $timestamp;
         $this->progress = $progress;
         $this->version = $version;
-	}
+    }
 
-	public function show()
-	{
-		parent::show();
-		echo $this->reflink.' ('. (empty($this->group_id) ? get_lang('Everyone') : get_lang('Group') . ' ' .  $this->group_id) .') ' . '<i>(' . $this->dtime . ')</i>';
-	}
+    public function show()
+    {
+        parent::show();
+        echo $this->reflink.' ('. (empty($this->group_id) ? get_lang('Everyone') : get_lang('Group') . ' ' .  $this->group_id) .') ' . '<i>(' . $this->dtime . ')</i>';
+    }
 }

+ 3 - 1
main/gradebook/certificate_template/template.html

@@ -1,10 +1,12 @@
-<html prefix="og: http://ogp.me/ns/article#">
+<!DOCTYPE html>
+<html prefix="og:http://ogp.me/ns/article#">
     <head>
         <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
         <title>((course_title)) - ((user_firstname)) ((user_lastname)) - ((date_certificate_no_time))</title>
         <meta property="og:type" content="article" />
         <meta property="og:title" content="((course_title)) - Certificate for ((user_firstname)) ((user_lastname))" />
         <meta property="og:url" content="((certificate_link))" />
+        <style>((external_style))</style>
     </head>
     <body style="background-color: #fff;">
         <div style="width: 1072px;margin-left: auto;margin-right: auto;">

+ 1 - 1
main/gradebook/exercise_jump.php

@@ -24,7 +24,7 @@ $type = Security::remove_XSS($_GET['type']);
 $doExerciseUrl = null;
 
 if (isset($_GET['doexercise'])) {
-    $doExerciseUrl = api_get_path(WEB_CODE_PATH) . 'exercise/overview.php?' . http_build_query([
+    $doExerciseUrl = api_get_path(WEB_CODE_PATH) . 'exercice/overview.php?' . http_build_query([
         'session_id' => $session_id,
         'cidReq' => $cidReq,
         'gradebook' => $gradebook,

+ 1 - 1
main/gradebook/gradebook_display_summary.php

@@ -57,7 +57,7 @@ switch ($action) {
 
         $courseInfo = api_get_course_info();
         $params = array(
-            'pdf_title' => sprintf(get_lang('GradeFromX'), $courseInfo['department_name']),
+            'pdf_title' => sprintf(get_lang('GradeFromX'), $courseInfo['name']),
             'session_info' => '',
             'course_info' => '',
             'pdf_date' => '',

+ 1 - 1
main/gradebook/index.php

@@ -949,7 +949,7 @@ if (isset($first_time) && $first_time==1 && api_is_allowed_to_edit(null,true)) {
                     $sessionName = api_get_session_name(api_get_session_id());
                     $sessionName = !empty($sessionName) ? " - $sessionName" : '';
                     $params = array(
-                        'pdf_title' => sprintf(get_lang('GradeFromX'), $courseInfo['department_name']),
+                        'pdf_title' => sprintf(get_lang('GradeFromX'), $courseInfo['name']),
                         'course_code' => api_get_course_id(),
                         'session_info' => '',
                         'course_info' => '',

+ 1 - 1
main/gradebook/lib/GradebookUtils.php

@@ -1387,7 +1387,7 @@ class GradebookUtils
         $sessionName = !empty($sessionName) ? " - $sessionName" : '';
 
         $params = array(
-            'pdf_title' => sprintf(get_lang('GradeFromX'), $courseInfo['department_name']),
+            'pdf_title' => sprintf(get_lang('GradeFromX'), $courseInfo['name']),
             'session_info' => '',
             'course_info' => '',
             'pdf_date' => '',

+ 16 - 8
main/inc/ajax/admin.ajax.php

@@ -127,6 +127,10 @@ function check_system_version()
 
         // The number of sessions
         $number_of_sessions = Statistics::countSessions();
+        $packager = api_get_configuration_value('packager');
+        if (empty($packager)) {
+            $packager = 'chamilo';
+        }
 
         $data = array(
             'url' => api_get_path(WEB_PATH),
@@ -144,6 +148,11 @@ function check_system_version()
             'language' => api_get_setting('platformLanguage'), //helps us know the spread of language usage for campuses, by main language
             'adminname' => api_get_setting('administratorName').' '.api_get_setting('administratorSurname'), //not sure this is necessary...
             'ip' => $_SERVER['REMOTE_ADDR'], //the admin's IP address, with the only purpose of trying to geolocate portals around the globe to draw a map
+            // Reference to the packager system or provider through which
+            // Chamilo is installed/downloaded. Packagers can change this in
+            // the default config file (main/install/configuration.dist.php)
+            // or in the installed config file. The default value is 'chamilo'
+            'packager' => $packager,
         );
         $version = null;
         // version.php has been updated to include the version in an HTTP header
@@ -182,14 +191,13 @@ function check_system_version()
 /**
  * Function to make an HTTP request through fsockopen (specialised for GET)
  * Derived from Jeremy Saintot: http://www.php.net/manual/en/function.fsockopen.php#101872
- * @param string IP or hostname
- * @param int    Target port
- * @param string URI (defaults to '/')
- * @param array  GET data
- * @param float  Timeout
- * @param bool   Include HTTP Request headers?
- * @param bool   Include HTTP Response headers?
- * @param string $ip
+ * @param string $ip IP or hostname
+ * @param int    $port Target port
+ * @param string $uri URI (defaults to '/')
+ * @param array  $getdata GET data
+ * @param int    $timeout Timeout
+ * @param bool   $req_hdr Include HTTP Request headers?
+ * @param bool   $res_hdr Include HTTP Response headers?
  * @return string
  */
 function _http_request($ip, $port = 80, $uri = '/', $getdata = array(), $timeout = 5, $req_hdr = false, $res_hdr = false)

+ 3 - 9
main/inc/ajax/lp.ajax.php

@@ -64,9 +64,8 @@ switch ($action) {
     case 'update_lp_item_order':
         if (api_is_allowed_to_edit(null, true)) {
 
-            $new_order   = $_POST['new_order'];
-
-            $sections	= explode('^', $new_order);
+            $new_order = $_POST['new_order'];
+            $sections = explode('^', $new_order);
             $new_array = array();
 
             // We have to update parent_item_id, previous_item_id, next_item_id, display_order in the database
@@ -189,12 +188,7 @@ switch ($action) {
             break;
         }
 
-        $learningPath = new learnpath(
-            api_get_course_id(),
-            $lpId,
-            api_get_user_id()
-        );
-
+        $learningPath = learnpath::getLpFromSession(api_get_course_id(), $lpId, api_get_user_id());
         $lpItem = $learningPath->getItem($lpItemId);
 
         if (empty($lpItem)) {

+ 9 - 3
main/inc/lib/course_home.lib.php

@@ -1053,10 +1053,16 @@ class CourseHome
             'external_na.gif'
         );
 
+        $toolName = Security::remove_XSS(stripslashes($tool['name']));
+
         if (in_array($tool['image'], $already_translated_icons)) {
-            $toolName = Security::remove_XSS(stripslashes($tool['name']));
-        } else {
-            $toolName = get_lang('Tool'.api_underscore_to_camel_case($tool['name']));
+            return $toolName;
+        }
+
+        $toolName = api_underscore_to_camel_case($toolName);
+
+        if (isset($GLOBALS['Tool' . $toolName])) {
+            return get_lang('Tool' . $toolName);
         }
 
         return $toolName;

+ 9 - 0
main/inc/lib/document.lib.php

@@ -1901,6 +1901,13 @@ class DocumentManager
 
         $url = api_get_path(WEB_PATH) . 'certificates/index.php?id=' . $info_grade_certificate['id'];
 
+        $externalStyleFile = api_get_path(SYS_CSS_PATH) . 'themes/' . api_get_visual_theme() . '/certificate.css';
+        $externalStyle = '';
+
+        if (is_file($externalStyleFile)) {
+            $externalStyle = file_get_contents($externalStyleFile);
+        }
+
         //replace content
         $info_to_replace_in_content_html = array(
             $first_name,
@@ -1918,6 +1925,7 @@ class DocumentManager
             $url,
             '<a href="' . $url . '" target="_blank">' . get_lang('CertificateOnlineLink') . '</a>',
             '((certificate_barcode))',
+            $externalStyle
         );
 
         $info_to_be_replaced_in_content_html = array('((user_firstname))',
@@ -1935,6 +1943,7 @@ class DocumentManager
             '((certificate_link))',
             '((certificate_link_html))',
             '((certificate_barcode))',
+            '((external_style))'
         );
 
         if (!empty($extraFields)) {

+ 14 - 12
main/inc/lib/exercise.lib.php

@@ -3461,8 +3461,7 @@ HOTSPOT;
         $objExercise,
         $exe_id,
         $save_user_result = false
-    )
-    {
+    ) {
         global $origin;
 
         // Getting attempt info
@@ -3532,16 +3531,19 @@ HOTSPOT;
 
                 if ($attempts) {
                     $numberAttempts = count($attempts);
-                    if ($save_user_result) {
-                        $numberAttempts++;
-                    }
-                    if ($numberAttempts >= $objExercise->attempts) {
-                        $show_results = true;
-                        $show_only_score = false;
-                        $show_total_score_and_user_choices = false;
-                    } else {
-                        $show_total_score_and_user_choices = true;
-                    }
+                } else {
+                    $numberAttempts = 0;
+                }
+
+                if ($save_user_result) {
+                    $numberAttempts++;
+                }
+                if ($numberAttempts >= $objExercise->attempts) {
+                    $show_results = true;
+                    $show_only_score = false;
+                    $show_total_score_and_user_choices = false;
+                } else {
+                    $show_total_score_and_user_choices = true;
                 }
             }
         }

+ 34 - 0
main/inc/lib/message.lib.php

@@ -1834,4 +1834,38 @@ class MessageManager
 
         return $form;
     }
+
+    /**
+     * Send a notification to all amdinistrators when a new user is registered
+     * @param \Chamilo\UserBundle\Entity\User $user
+     */
+    public static function sendNotificationByRegisteredUser(\Chamilo\UserBundle\Entity\User $user)
+    {
+        $tplMailBody = new Template(null, false, false, false, false, false, false);
+        $tplMailBody->assign('user', $user);
+        $tplMailBody->assign('is_western_name_order', api_is_western_name_order());
+        $tplMailBody->assign('manageUrl', api_get_path(WEB_CODE_PATH) . 'admin/user_edit.php?user_id=' . $user->getId());
+
+        $layoutContent = $tplMailBody->get_template('mail/new_user_mail_to_admin.tpl');
+
+        $emailsubject = '[' . get_lang('UserRegistered') . '] ' . $user->getUsername();
+        $emailbody = $tplMailBody->fetch($layoutContent);
+
+        $admins = UserManager::get_all_administrators();
+
+        foreach ($admins as $admin_info) {
+            MessageManager::send_message(
+                $admin_info['user_id'],
+                $emailsubject,
+                $emailbody,
+                [],
+                [],
+                null,
+                null,
+                null,
+                null,
+                $user->getId()
+            );
+        }
+    }
 }

+ 8 - 8
main/inc/lib/pear/PEAR.php

@@ -19,10 +19,6 @@
  * @since      File available since Release 0.1
  */
 
-// Added by Chamilo team, 16-MAR-2010
-if (class_exists('pear')) { return; }
-//
-
 /**#@+
  * ERROR constants
  */
@@ -156,7 +152,7 @@ class PEAR
      * @access public
      * @return void
      */
-    function PEAR($error_class = null)
+    public function __construct($error_class = null)
     {
         $classname = strtolower(get_class($this));
         if ($this->_debug) {
@@ -867,9 +863,13 @@ class PEAR_Error
      * @access public
      *
      */
-    function PEAR_Error($message = 'unknown error', $code = null,
-                        $mode = null, $options = null, $userinfo = null)
-    {
+    public function __constructor(
+        $message = 'unknown error',
+        $code = null,
+        $mode = null,
+        $options = null,
+        $userinfo = null
+    ) {
         if ($mode === null) {
             $mode = PEAR_ERROR_RETURN;
         }

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

@@ -1724,6 +1724,7 @@ class SocialManager extends UserManager
         $template->assign('chat_enabled', $chatEnabled);
         $template->assign('user_relation', $userRelationType);
         $template->assign('user_relation_type_friend', USER_RELATION_TYPE_FRIEND);
+        $template->assign('show_full_profile', $show_full_profile);
         $templateName = $template->get_template('social/user_block.tpl');
 
         if (in_array($groupBlock, ['groups', 'group_edit', 'member_list'])) {

+ 17 - 9
main/inc/lib/usermanager.lib.php

@@ -2269,24 +2269,28 @@ class UserManager
     }
 
     /** Get extra user data by value
-     * @param string the internal variable name of the field
-     * @param string the internal value of the field
+     * @param string $field_variable the internal variable name of the field
+     * @param string $field_value the internal value of the field
+     * @param bool $all_visibility
+     *
      * @return array with extra data info of a user i.e array('field_variable'=>'value');
      */
-    public static function get_extra_user_data_by_value($field_variable, $field_value)
+     public static function get_extra_user_data_by_value($field_variable, $field_value, $all_visibility = true)
     {
         $extraField = new ExtraFieldValue('user');
 
-        $data = $extraField->get_item_id_from_field_variable_and_field_value(
+        $data = $extraField->get_values_by_handler_and_field_variable(
             $field_variable,
             $field_value,
-            true
+            null,
+            true,
+            intval($all_visibility)
         );
 
         $result = [];
         if (!empty($data)) {
             foreach ($data as $data) {
-                $result[] = $data;
+                $result[] = $data['item_id'];
             }
         }
 
@@ -3602,7 +3606,7 @@ class UserManager
             $finalResult = array();
             if (count($extraFieldResult)>1) {
                 for ($i=0; $i < count($extraFieldResult) -1; $i++) {
-                    if (is_array($extraFieldResult[$i+1])) {
+                if (is_array($extraFieldResult[$i]) && is_array($extraFieldResult[$i+1])) {
                         $finalResult  = array_intersect($extraFieldResult[$i], $extraFieldResult[$i+1]);
                     }
                 }
@@ -3626,7 +3630,7 @@ class UserManager
      * @param string $query the value of the search box
      * @return string HTML form
      */
-    public static function get_search_form($query)
+    public static function get_search_form($query, $defaultParams = [])
     {
         $searchType = isset($_GET['search_type']) ? $_GET['search_type'] : null;
         $form = new FormValidator(
@@ -3678,6 +3682,10 @@ class UserManager
 
         $defaults['search_type'] = intval($searchType);
         $defaults['q'] = api_htmlentities(Security::remove_XSS($query));
+
+        if (!empty($defaultParams)) {
+            $defaults = array_merge($defaults, $defaultParams);
+        }
         $form->setDefaults($defaults);
 
         $form->addButtonSearch(get_lang('Search'));
@@ -4815,7 +4823,7 @@ EOF;
 
     /**
      * Subscribe boss to students
-     * 
+     *
      * @param int $bossId The boss id
      * @param array $usersId The users array
      * @return int Affected rows

+ 2 - 2
main/inc/local.inc.php

@@ -555,11 +555,11 @@ if (!empty($_SESSION['_user']['user_id']) && !($login || $logout)) {
 
             if (isset($extAuthSource) && is_array($extAuthSource)) {
                 foreach ($extAuthSource as $thisAuthSource) {
-                    if (!empty($thisAuthSource['newUser']) && file_exists($thisAuthSource['newUser'])) {
+                    if (isset($thisAuthSource['newUser']) && file_exists($thisAuthSource['newUser'])) {
                         include_once($thisAuthSource['newUser']);
                     } else {
                         error_log(
-                            'Chamilo Authentication file '. $thisAuthSource['newUser'].
+                            'Chamilo Authentication external file' .
                             ' could not be found - this might prevent your system from using'.
                             ' the authentication process in the user creation process',
                             0

+ 5 - 0
main/install/configuration.dist.php

@@ -242,3 +242,8 @@ $_configuration['system_stable'] = NEW_VERSION_STABLE;
 //$_configuration['messaging_gdc_api_key'] = '';
 // Text to speech google app id
 //$_configuration['translate_app_google_key'] = '';
+// Reference to the packager system or provider through which
+// Chamilo is installed/downloaded. Packagers can change this
+// to reflect their packaging method. The default value is 'chamilo'. This will
+// be reflected on the https://version.chamilo.org/stats page in the future.
+//$_configuration['packager'] = 'chamilo';

File diff suppressed because it is too large
+ 1 - 1
main/lang/english/trad4all.inc.php


+ 2 - 1
main/lang/french/trad4all.inc.php

@@ -7651,4 +7651,5 @@ $RecordAudio = "Enregistrement audio";
 $StartRecordingAudio = "Lancer l'enregistrement";
 $StopRecordingAudio = "Arrêter l'enregistrement";
 $SaveRecordedAudio = "Sauvegarder l'audio enregistré";
-?>
+$GradeFromX = "Bulletin pour le cours: %s";
+?>

File diff suppressed because it is too large
+ 2 - 2
main/lang/spanish/trad4all.inc.php


+ 2 - 1
main/mySpace/myStudents.php

@@ -12,7 +12,8 @@ api_block_anonymous_users();
 if (!api_is_allowed_to_create_course() &&
     !api_is_session_admin() &&
     !api_is_drh() &&
-    !api_is_student_boss()
+    !api_is_student_boss() &&
+    !api_is_platform_admin()
 ) {
     // Check if the user is tutor of the course
     $user_course_status = CourseManager::get_tutor_in_course_status(

+ 7 - 3
main/newscorm/learnpath.class.php

@@ -1686,9 +1686,10 @@ class learnpath
 
     /**
      * Gets the number of items currently completed
+     * @param bool $failedStatusException flag to determine the failed status is not considered progressed
      * @return integer The number of items currently completed
      */
-    public function get_complete_items_count()
+    public function get_complete_items_count($failedStatusException = false)
     {
         if ($this->debug > 0) {
             error_log('New LP - In learnpath::get_complete_items_count()', 0);
@@ -1698,10 +1699,13 @@ class learnpath
             'completed',
             'passed',
             'succeeded',
-            'browsed',
-            'failed'
+            'browsed'
         );
 
+        if (!$failedStatusException) {
+            $completedStatusList[] = 'failed';
+        }
+
         foreach ($this->items as $id => $dummy) {
             // Trying failed and browsed considered "progressed" as well.
             if ($this->items[$id]->status_is($completedStatusList) &&

+ 69 - 55
main/newscorm/lp_final_item.php

@@ -7,8 +7,10 @@
  */
 // Initialize context
 $_in_course = true;
-require_once __DIR__.'/../inc/global.inc.php';
-$current_course_tool  = TOOL_GRADEBOOK;
+
+require_once __DIR__ . '/../inc/global.inc.php';
+
+$current_course_tool = TOOL_GRADEBOOK;
 
 // Make sure no anonymous user gets here without permission
 api_protect_course_script(true);
@@ -35,12 +37,16 @@ $finalItemTemplate = '';
 // Check prerequisites and total completion of the learning path
 $lp = new Learnpath($courseCode, $lpId, $userId);
 $count = $lp->get_total_items_count_without_chapters();
-$completed = $lp->get_complete_items_count();
+$completed = $lp->get_complete_items_count(true);
 $currentItemId = $lp->get_current_item_id();
 $currentItem = $lp->items[$currentItemId];
 $currentItemStatus = $currentItem->get_status();
 $accessGranted = false;
-if (($count - $completed == 0) or (($count - $completed == 1 && ($currentItemStatus == 'incomplete') or ($currentItemStatus == 'not attempted') ))) {
+
+if (
+    ($count - $completed == 0) or
+    ($count - $completed == 1 && ($currentItemStatus == 'incomplete') or ($currentItemStatus == 'not attempted'))
+) {
     if ($lp->prerequisites_match($currentItemId)) {
         $accessGranted = true;
     }
@@ -62,10 +68,14 @@ if ($accessGranted == false) {
     // If not gradebook has been defined
     if (empty($catLoad)) {
 
-        $finalItemTemplate = generateLPFinalItemTemplate($id, $courseCode, $sessionId, $downloadCertificateLink,
-            $badgeLink);
+        $finalItemTemplate = generateLPFinalItemTemplate(
+            $id,
+            $courseCode,
+            $sessionId,
+            $downloadCertificateLink,
+            $badgeLink
+        );
         // TODO: Missing validation of learning path completion
-
     } else {
         // A gradebook was found, proceed...
         $categoryId = $catLoad[0]->get_id();
@@ -78,10 +88,8 @@ if ($accessGranted == false) {
 
             if ($show_message == '') {
                 if (!api_is_allowed_to_edit() && !api_is_excluded_user_type()) {
-                    $certificate = Category::register_user_certificate(
-                        $categoryId,
-                        $userId
-                    );
+                    $certificate = Category::register_user_certificate($categoryId, $userId);
+
                     if (!empty($certificate['pdf_url']) || !empty($certificate['badge_link'])) {
                         if (is_array($certificate) && isset($certificate['pdf_url'])) {
                             $downloadCertificateLink = generateLPFinalItemTemplateCertificateLinks($certificate);
@@ -92,13 +100,18 @@ if ($accessGranted == false) {
                             $badgeLink = generateLPFinalItemTemplateBadgeLinks($userId, $courseId, $sessionId);
                         }
                     }
+
                     $currentScore = Category::getCurrentScore($userId, $categoryId, $courseCode, $sessionId, true);
                     Category::registerCurrentScore($currentScore, $userId, $categoryId);
                 }
             }
         }
-        $finalItemTemplate = generateLPFinalItemTemplate($id, $courseCode, $sessionId, $downloadCertificateLink,
-            $badgeLink);
+
+        $finalItemTemplate = generateLPFinalItemTemplate($id, $courseCode, $downloadCertificateLink, $badgeLink);
+
+        if (!$finalItemTemplate) {
+            Display::display_warning_message(get_lang('FileNotFound'));
+        }
     }
 }
 
@@ -118,7 +131,7 @@ $tpl->display_one_col_template();
  * @param string $badgeLink
  * @return mixed|string
  */
-function generateLPFinalItemTemplate($lpItemId, $courseCode, $sessionId=0, $downloadCertificateLink='', $badgeLink='')
+function generateLPFinalItemTemplate($lpItemId, $courseCode, $sessionId = 0, $downloadCertificateLink = '', $badgeLink = '')
 {
     $documentInfo = DocumentManager::get_document_data_by_id(
         $lpItemId,
@@ -131,6 +144,7 @@ function generateLPFinalItemTemplate($lpItemId, $courseCode, $sessionId=0, $down
 
     $finalItemTemplate = str_replace('((certificate))', $downloadCertificateLink, $finalItemTemplate);
     $finalItemTemplate = str_replace('((skill))', $badgeLink, $finalItemTemplate);
+
     return $finalItemTemplate;
 }
 
@@ -141,48 +155,48 @@ function generateLPFinalItemTemplate($lpItemId, $courseCode, $sessionId=0, $down
  * @param int $sessionId
  * @return string HTML string for badges
  */
-function generateLPFinalItemTemplateBadgeLinks($userId, $courseId, $sessionId=0)
+function generateLPFinalItemTemplateBadgeLinks($userId, $courseId, $sessionId = 0)
 {
+    $em = Database::getManager();
     $skillRelUser = new SkillRelUser();
     $userSkills = $skillRelUser->get_user_skills($userId, $courseId, $sessionId);
     $skillList = '';
     $badgeLink = '';
 
     if ($userSkills) {
-        $skill = new Skill();
         foreach ($userSkills as $userSkill) {
-            $oneSkill = $skill->get($userSkill['skill_id']);
+            $skill = $em->find('ChamiloCoreBundle:Skill', $userSkill['skill_id']);
             $skillList .= "
-                                    <div class='row'>
-                                        <div class='col-md-2 col-xs-6'>
-                                            <div class='thumbnail'>
-                                              <img class='skill-badge-img' src='" . $oneSkill['web_icon_path'] . "' >
-                                            </div>
-                                        </div>
-                                        <div class='col-md-8 col-xs-6'>
-                                            <h5><b>" . $oneSkill['name'] . "</b></h5>
-                                            " . $oneSkill['description'] . "
-                                        </div>
-                                        <div class='col-md-2 col-xs-12'>
-                                            <h5><b>" . get_lang('ShareWithYourFriends') . "</b></h5>
-                                            <a href='http://www.facebook.com/sharer.php?u=" . api_get_path(WEB_PATH) . "badge/" . $oneSkill['id'] . "/user/" . $userId . "' target='_new'>
-                                                <em class='fa fa-facebook-square fa-3x text-info' aria-hidden='true'></em>
-                                            </a>
-                                            <a href='https://twitter.com/home?status=" . api_get_path(WEB_PATH) . "badge/" . $oneSkill['id'] . "/user/" . $userId . "' target='_new'>
-                                                <em class='fa fa-twitter-square fa-3x text-light' aria-hidden='true'></em>
-                                            </a>
-                                        </div>
-                                    </div>
-                                ";
+                <div class='row'>
+                    <div class='col-md-2 col-xs-4'>
+                        <div class='thumbnail'>
+                          <img class='skill-badge-img' src='" . $skill->getWebIconPath() . "' >
+                        </div>
+                    </div>
+                    <div class='col-md-8 col-xs-8'>
+                        <h5><b>" . $skill->getName() . "</b></h5>
+                        " . $skill->getDescription() . "
+                    </div>
+                    <div class='col-md-2 col-xs-12'>
+                        <h5><b>" . get_lang('ShareWithYourFriends') . "</b></h5>
+                        <a href='http://www.facebook.com/sharer.php?u=" . api_get_path(WEB_PATH) . "badge/" . $skill->getId() . "/user/" . $userId . "' target='_new'>
+                            <em class='fa fa-facebook-square fa-3x text-info' aria-hidden='true'></em>
+                        </a>
+                        <a href='https://twitter.com/home?status=" . sprintf(get_lang('IHaveObtainedSkillXOnY'), '"' . $skill->getName() . '"', api_get_setting('siteName')) . ' - ' . api_get_path(WEB_PATH) . 'badge/' . $skill->getId() . '/user/' . $userId . "' target='_new'>
+                            <em class='fa fa-twitter-square fa-3x text-light' aria-hidden='true'></em>
+                        </a>
+                    </div>
+                </div>
+            ";
         }
         $badgeLink .= "
-                                <div class='panel panel-default'>
-                                    <div class='panel-body'>
-                                        <h3 class='text-center'>" . get_lang('AdditionallyYouHaveObtainedTheFollowingSkills') . "</h3>
-                                        $skillList
-                                    </div>
-                                </div>
-                            ";
+            <div class='panel panel-default'>
+                <div class='panel-body'>
+                    <h3 class='text-center'>" . get_lang('AdditionallyYouHaveObtainedTheFollowingSkills') . "</h3>
+                    $skillList
+                </div>
+            </div>
+        ";
     }
     return $badgeLink;
 }
@@ -194,19 +208,19 @@ function generateLPFinalItemTemplateBadgeLinks($userId, $courseId, $sessionId=0)
  */
 function generateLPFinalItemTemplateCertificateLinks($certificate)
 {
-    $downloadCertificateLink = Display::url(Display::returnFontAwesomeIcon('file-pdf-o') .
-        get_lang('DownloadCertificatePdf'),
+    $downloadCertificateLink = Display::url(
+        Display::returnFontAwesomeIcon('file-pdf-o') . get_lang('DownloadCertificatePdf'),
         $certificate['pdf_url'],
         ['class' => 'btn btn-default']
     );
     $viewCertificateLink = $certificate['certificate_link'];
     $downloadCertificateLink = "
-                            <div class='panel panel-default'>
-                                <div class='panel-body'>
-                                    <h3 class='text-center'>" . get_lang('NowDownloadYourCertificateClickHere') . "</h3>
-                                    <div class='text-center'>$downloadCertificateLink $viewCertificateLink</div>
-                                </div>
-                            </div>
-                        ";
+        <div class='panel panel-default'>
+            <div class='panel-body'>
+                <h3 class='text-center'>" . get_lang('NowDownloadYourCertificateClickHere') . "</h3>
+                <div class='text-center'>$downloadCertificateLink $viewCertificateLink</div>
+            </div>
+        </div>
+    ";
     return $downloadCertificateLink;
-}
+}

+ 11 - 15
main/newscorm/lp_nav.php

@@ -21,22 +21,18 @@ $navigation_bar = '';
 $display_mode = '';
 $autostart = 'true';
 
-if (isset($_SESSION['lpobject'])) {
-    $oLP = unserialize($_SESSION['lpobject']);
-    if (is_object($oLP)) {
-        $_SESSION['oLP'] = $oLP;
-    } else {
-        die('Could not instanciate lp object');
-    }
-    $display_mode = $_SESSION['oLP']->mode;
+$myLP = learnpath::getLpFromSession(api_get_course_id(), '', '');
+
+if ($myLP) {
+    $display_mode = $myLP->mode;
     $scorm_css_header = true;
-    $lp_theme_css = $_SESSION['oLP']->get_theme();
+    $lp_theme_css = $myLP->get_theme();
 
     $my_style = api_get_visual_theme();
 
     // Setting up the CSS theme if exists
     $mycourselptheme = null;
-    if (api_get_setting('allow_course_theme') == 'true') {
+    if (api_get_setting('allow_course_theme') === 'true') {
         $mycourselptheme = api_get_course_setting('allow_learning_path_theme');
     }
 
@@ -46,13 +42,13 @@ if (isset($_SESSION['lpobject'])) {
         $lp_theme_css = $my_style;
     }
 
-    $progress_bar 	= $_SESSION['oLP']->getProgressBar();
-    $navigation_bar = $_SESSION['oLP']->get_navigation_bar();
-    $mediaplayer 	= $_SESSION['oLP']->get_mediaplayer($autostart);
+    $progress_bar = $myLP->getProgressBar();
+    $navigation_bar = $myLP->get_navigation_bar();
+    $mediaplayer = $myLP->get_mediaplayer($autostart);
 }
 session_write_close();
 ?>
-<script type="text/javascript">
+<script>
     $(document).ready(function() {
         jQuery('video:not(.skip), audio:not(.skip)').mediaelementplayer({
             success: function(player, node) {
@@ -61,5 +57,5 @@ session_write_close();
     });
 </script>
 <span>
-    <?php echo (!empty($mediaplayer)) ? $mediaplayer : '&nbsp;' ?>
+    <?php echo !empty($mediaplayer) ? $mediaplayer : '&nbsp;' ?>
 </span>

+ 2 - 2
main/newscorm/scorm_api.php

@@ -1663,7 +1663,7 @@ function switch_item(current_item, next_item){
     });
     olms.switch_finished = 0; //only changed back once LMSInitialize() happens
 
-    loadForumThead(olms.lms_lp_id, next_item);
+    loadForumThread(olms.lms_lp_id, next_item);
 
     return true;
 }
@@ -1671,7 +1671,7 @@ function switch_item(current_item, next_item){
 /**
  * Get a forum info when the learning path item has a associated forum
  */
-var loadForumThead = function(lpId, lpItemId) {
+var loadForumThread = function(lpId, lpItemId) {
     var loadForum = $.getJSON('<?php echo api_get_path(WEB_AJAX_PATH) ?>lp.ajax.php', {
             a: 'get_forum_thread',
             lp: lpId,

+ 8 - 9
main/social/profile.php

@@ -347,6 +347,9 @@ if ($show_full_profile) {
         $extra_information_value = '<ul class="list-group">';
         $extraField = new ExtraField('user');
         foreach ($extra_user_data as $key => $data) {
+            if (empty($data)) {
+                continue;
+            }
             // Avoiding parameters
             if (in_array(
                 $key,
@@ -365,6 +368,10 @@ if ($show_full_profile) {
                 $field_variable
             );
 
+            if (in_array($extraFieldInfo['variable'], ['skype', 'linkedin_url'])) {
+                break;
+            }
+
             if ($extraFieldInfo['visible'] != 1) {
                 continue;
             }
@@ -421,15 +428,7 @@ if ($show_full_profile) {
                         $extra_information_value .= '<li class="list-group-item">'.$data.'</li>';
                         break;
                     default:
-                        if (!empty($data)) {
-                            $extra_field_title = ucfirst($extraFieldInfo['display_text']);
-                            if ($extra_field_title == 'Skype') {
-                                $data = '<a href="skype:' . $data . '?chat">' . get_lang('Chat') . '</a>';
-                                $extra_information_value .= '<li class="list-group-item">'.Display::return_icon('skype.png', $extraFieldInfo['display_text'], null, ICON_SIZE_TINY, false) . ' ' . $data.'</li>';
-                            } else {
-                                $extra_information_value .= '<dt>'.ucfirst($extraFieldInfo['display_text']).':</dt><dd>'.$data.'</dd>';
-                            }
-                        }
+                        $extra_information_value .= '<li class="list-group-item">'.ucfirst($extraFieldInfo['display_text']) . ': ' . $data . '</li>';
                     break;
                 }
             }

+ 8 - 8
main/template/default/learnpath/view.tpl

@@ -33,7 +33,7 @@
 
                                 {% if gamification_mode == 1 %}
                                     <hr>
-                                    <!--- gamification -->    
+                                    <!--- gamification -->
                                     <div id="scorm-gamification">
                                         <div class="row">
                                             <div class="col-xs-6">
@@ -61,8 +61,8 @@
                                             </div>
                                         </div>
                                     </div>
-                                   <!--- end gamification -->          
-                                {% else %}         
+                                   <!--- end gamification -->
+                                {% else %}
                                     <div id="progress_bar">
                                         {{ progress_bar }}
                                     </div>
@@ -79,7 +79,7 @@
                                     <em class="fa fa-home"></em> <span class="hidden-xs hidden-sm"></span>
                                 </a>
                             </div>
-                            
+
                         </div>
                     </div>
 
@@ -139,7 +139,7 @@
                                 {% endif %}
                             </div>
                             <div role="tabpanel" class="tab-pane" id="lp-view-forum">
-                                
+
                             </div>
                         </div>
                     </div>
@@ -161,7 +161,7 @@
         };
 
         $(document).on('ready', function () {
-            
+
             {% if lp_mode == 'embedframe' %}
                 //$('#learning_path_main').addClass('lp-view-collapsed');
                 $('#lp-view-expand-button, #lp-view-expand-toggle').on('click', function (e) {
@@ -181,7 +181,7 @@
                 $('#lp-view-expand-toggle span.fa').toggleClass('fa-expand');
                 $('#lp-view-expand-toggle span.fa').toggleClass('fa-compress');
             });
-            
+
             {% endif %}
 
             $('.lp-view-tabs').on('click', '.disabled', function (e) {
@@ -214,7 +214,7 @@
                 $('.lp-view-tabs').fadeIn();
             });
 
-            loadForumThead({{ lp_id }}, {{ lp_current_item_id }});
+            loadForumThread({{ lp_id }}, {{ lp_current_item_id }});
 
             {% if glossary_extra_tools in glossary_tool_availables %}
                 // Loads the glossary library.

+ 13 - 0
main/template/default/mail/new_user_mail_to_admin.tpl

@@ -0,0 +1,13 @@
+<h4>{{ 'UserRegistered'|get_lang }}</h4>
+<ul>
+    {% if is_western_name_order %}
+        <li>{{ 'FirstName'|get_lang }}: {{ user.getFirstName() }}</li>
+        <li>{{ 'LastName' }}: {{ user.getLastName() }}</li>
+    {% else  %}
+        <li>{{ 'LastName' }}: {{ user.getLastName() }}</li>
+        <li>{{ 'FirstName' }}: {{ user.getFirstName() }}</li>
+    {% endif %}
+    <li>{{ 'Email'|get_lang }}: {{ user.getEmail() }}</li>
+    <li>{{ 'Status'|get_lang }}: {{ user.getStatus() }}</li>
+</ul>
+<p>{{ 'ManageUser'|get_lang }}: <a href="{{ manageUrl }}">{{ manageUrl }}</a></p>

+ 30 - 2
main/template/default/social/user_block.tpl

@@ -17,7 +17,7 @@
                             <li class="item">
                                 {{ user.complete_name }}
                             </li>
-                            {% if vcard_user_link  %}
+                            {% if show_full_profile  %}
                                 <li class="item">
                                     <a href="{{ _p.web }}main/messages/new_message.php">
                                     <img src="{{ "instant_message.png" | icon }}" alt="{{ "Email" | get_lang }}">
@@ -30,6 +30,34 @@
                                     {{ "BusinessCard" | get_lang }}
                                     </a>
                                 </li>
+
+                                {% set skype_account = '' %}
+                                {% set linkedin_url = '' %}
+                                {% for extra in user.extra %}
+                                    {% if extra.value.getField().getVariable() == 'skype' %}
+                                        {% set skype_account = extra.value.getValue() %}
+                                    {% endif %}
+
+                                    {% if extra.value.getField().getVariable() == 'linkedin_url' %}
+                                        {% set linkedin_url = extra.value.getValue() %}
+                                    {% endif %}
+                                {% endfor %}
+
+                                {% if 'allow_show_skype_account'|get_setting == 'true' and not skype_account is empty %}
+                                    <li class="item">
+                                        <a href="skype:{{ skype_account }}?chat">
+                                            <span class="fa fa-skype fa-fw" aria-hidden="true"></span> {{ 'Skype'|get_lang }}
+                                        </a>
+                                    </li>
+                                {% endif %}
+
+                                {% if 'allow_show_linkedin_url'|get_setting == 'true' and not linkedin_url is empty %}
+                                    <li class="item">
+                                        <a href="{{ linkedin_url }}" target="_blank">
+                                            <span class="fa fa-linkedin fa-fw" aria-hidden="true"></span> {{ 'LinkedIn'|get_lang }}
+                                        </a>
+                                    </li>
+                                {% endif %}
                             {% endif %}
                         {% if chat_enabled == 1 %}
                             {% if user.user_is_online_in_chat != 0 %}
@@ -49,7 +77,7 @@
                         
                         {% if not profile_edition_link is empty %}
                         <li class="item">
-                            <a class="btn link btn-sm btn-block" href="{{ profile_edition_link }}">
+                            <a class="btn btn-link btn-sm btn-block" href="{{ profile_edition_link }}">
                             <em class="fa fa-edit"></em>{{ "EditProfile" | get_lang }}
                             </a>
                         </li>

+ 17 - 0
plugin/azure_active_directory/README.md

@@ -0,0 +1,17 @@
+# The Azure Active Directory Plugin
+Allow authentication with Microsoft's Azure Active Directory
+
+### To configure Azure Active Directory
+* [Create an Azure AD B2C tenant](https://azure.microsoft.com/en-us/documentation/articles/active-directory-b2c-get-started/)
+* [Register your application](https://azure.microsoft.com/en-us/documentation/articles/active-directory-b2c-app-registration/)
+* [Configure Facebook, Google+, Microsoft account, Amazon, and LinkedIn accounts for use in your consumer-facing applications](https://azure.microsoft.com/en-us/documentation/articles/active-directory-b2c-overview/#how-to-articles)
+
+### To configure this plugin
+* Enable
+* Application ID: Enter the Application Id assinged to your app by the Azure portal, e.g. 580e250c-8f26-49d0-bee8-1c078add1609
+* Tenant: Enter the name of your B2C directory, e.g. contoso.onmicrosoft.com
+* Sign up policy: Enter your sign up policy name, e.g. b2c_1_sign_up
+* Sign in policy: Enter your sign in policy name, e.g. b2c_1_sign_in
+* Block name: (Optional) The name to show above the buttons
+
+And assign a region. Preferably `login_bottom`

+ 14 - 0
plugin/azure_active_directory/index.php

@@ -0,0 +1,14 @@
+<?php
+/* For licensing terms, see /license.txt */
+/**
+ * @author Angel Fernando Quiroz Campos <angel.quiroz@beeznest.com>
+ * @package chamilo.plugin.azure_active_directory
+ */
+$activeDirectoryPlugin = AzureActiveDirectory::create();
+
+if ($activeDirectoryPlugin->get(AzureActiveDirectory::SETTING_ENABLE) === 'true') {
+    $_template['block_title'] = $activeDirectoryPlugin->get(AzureActiveDirectory::SETTING_BLOCK_NAME);
+    $_template['signup_url'] = $activeDirectoryPlugin->getUrl(AzureActiveDirectory::URL_TYPE_SIGNUP);
+    $_template['signin_url'] = $activeDirectoryPlugin->getUrl(AzureActiveDirectory::URL_TYPE_SIGNIN);
+    $_template['signout_url'] = $activeDirectoryPlugin->getUrl(AzureActiveDirectory::URL_TYPE_SIGNOUT);
+}

+ 20 - 0
plugin/azure_active_directory/lang/english.php

@@ -0,0 +1,20 @@
+<?php
+/* For licensing terms, see /license.txt */
+/**
+ * Strings to english L10n
+ * @author Angel Fernando Quiroz Campos <angel.quiroz@beeznest.com>
+ * @package chamilo.plugin.azure_active_directory
+ */
+$strings['plugin_title'] = 'Azure Active Directory';
+$strings['plugin_comment'] = 'Allow authentication with Microsoft\'s Azure Active Directory';
+
+$strings['enable'] = 'Enable';
+$strings['app_id'] = 'Application ID';
+$strings['app_id_help'] = 'Enter the Application Id assinged to your app by the Azure portal, e.g. 580e250c-8f26-49d0-bee8-1c078add1609';
+$strings['tenant'] = 'Tenant';
+$strings['tenant_help'] = 'Enter the name of your B2C directory, e.g. contoso.onmicrosoft.com';
+$strings['signup_policy'] = 'Sign up policy';
+$strings['signup_policy_help'] = 'Enter your sign up policy name, e.g.g b2c_1_sign_up';
+$strings['signin_policy'] = 'Sign in policy';
+$strings['signin_policy_help'] = 'Enter your sign in policy name, e.g. b2c_1_sign_in';
+$strings['block_name'] = 'Block name';

+ 9 - 0
plugin/azure_active_directory/plugin.php

@@ -0,0 +1,9 @@
+<?php
+/* For licensing terms, see /license.txt */
+/**
+ * @author Angel Fernando Quiroz Campos <angel.quiroz@beeznest.com>
+ * @package chamilo.plugin.azure_active_directory
+ */
+$plugin_info = AzureActiveDirectory::create()->get_info();
+
+$plugin_info['templates'] = array('view/block.tpl');

+ 30 - 0
plugin/azure_active_directory/readme.txt

@@ -0,0 +1,30 @@
+<h1 class="page-header">The Azure Active Directory Plugin</h1>
+<p>Allow authentication with Microsoft's Azure Active Directory</p>
+<h3>To configure Azure Active Directory</h3>
+<ul>
+    <li>
+        <a href="https://azure.microsoft.com/en-us/documentation/articles/active-directory-b2c-get-started/">
+            Create an Azure AD B2C tenant
+        </a>
+    </li>
+    <li>
+        <a href="https://azure.microsoft.com/en-us/documentation/articles/active-directory-b2c-app-registration/">
+            Register your application
+        </a>
+    </li>
+    <li>
+        <a href="https://azure.microsoft.com/en-us/documentation/articles/active-directory-b2c-overview/#how-to-articles">
+            Configure Facebook, Google+, Microsoft account, Amazon, and LinkedIn accounts for use in your consumer-facing applications
+        </a>
+    </li>
+</ul>
+<h3>To configure this plugin</h3>
+<ul>
+    <li>Enable</li>
+    <li>Application ID: Enter the Application Id assinged to your app by the Azure portal, e.g. 580e250c-8f26-49d0-bee8-1c078add1609</li>
+    <li>Tenant: Enter the name of your B2C directory, e.g. contoso.onmicrosoft.com</li>
+    <li>Sign up policy: Enter your sign up policy name, e.g. b2c_1_sign_up</li>
+    <li>Sign in policy: Enter your sign in policy name, e.g. b2c_1_sign_in</li>
+    <li>Block name: (Optional) The name to show above the buttons</li>
+</ul>
+<p>And assign a region. Preferably <code>login_bottom</code></p>

+ 102 - 0
plugin/azure_active_directory/src/AzureActiveDirectory.php

@@ -0,0 +1,102 @@
+<?php
+/**
+ * AzureActiveDirectory plugin class
+ * @author Angel Fernando Quiroz Campos <angel.quiroz@beeznest.com>
+ * @package chamilo.plugin.azure_active_directory
+ */
+class AzureActiveDirectory extends Plugin
+{
+    const SETTING_ENABLE = 'enable';
+    const SETTING_APP_ID = 'app_id';
+    const SETTING_TENANT = 'tenant';
+    const SETTING_SIGNUP_POLICY = 'signup_policy';
+    const SETTING_SIGNIN_POLICY = 'signin_policy';
+    const SETTING_BLOCK_NAME = 'block_name';
+    const URL_TYPE_SIGNUP = 'sign-up';
+    const URL_TYPE_SIGNIN = 'sign-in';
+    const URL_TYPE_SIGNOUT = 'sign-out';
+
+    /**
+     * AzureActiveDirectory constructor.
+     */
+    protected function __construct()
+    {
+        $settings = [
+            self::SETTING_ENABLE => 'boolean',
+            self::SETTING_APP_ID => 'text',
+            self::SETTING_TENANT => 'text',
+            self::SETTING_SIGNUP_POLICY => 'text',
+            self::SETTING_SIGNIN_POLICY => 'text',
+            self::SETTING_BLOCK_NAME => 'text'
+        ];
+
+        parent::__construct('1.0', 'Angel Fernando Quiroz Campos', $settings);
+    }
+
+    /**
+     * Instance the plugin
+     * @staticvar null $result
+     * @return Tour
+     */
+    static function create()
+    {
+        static $result = null;
+
+        return $result ? $result : $result = new self();
+    }
+
+    /**
+     * @return string
+     */
+    public function get_name()
+    {
+        return 'azure_active_directory';
+    }
+
+    /**
+     * @param $urlType Type of URL to generate
+     * @return string
+     */
+    public function getUrl($urlType)
+    {
+        $settingsInfo = $this->get_settings();
+        $settings = [];
+
+        foreach ($settingsInfo as $settingInfo) {
+            $variable = str_replace($this->get_name() . '_', '', $settingInfo['variable']);
+
+            $settings[$variable] = $settingInfo['selected_value'];
+        }
+
+        $url = "https://login.microsoftonline.com/{$settings[self::SETTING_TENANT]}/oauth2/v2.0/";
+        $callback = api_get_path(WEB_PLUGIN_PATH) . $this->get_name() . '/src/callback.php';
+
+        if ($urlType === self::URL_TYPE_SIGNOUT) {
+            $action = 'logout';
+            $urlParams = [
+                'p' => $settings[self::SETTING_SIGNIN_POLICY],
+                'post_logout_redirect_uri' => $callback
+            ];
+        } else {
+            $action = 'authorize';
+            $policy = $settings[self::SETTING_SIGNUP_POLICY];
+
+            if ($urlType === self::URL_TYPE_SIGNIN) {
+                $policy = $settings[self::SETTING_SIGNIN_POLICY];
+            }
+
+            $urlParams = [
+                'client_id' => $settings[self::SETTING_APP_ID],
+                'response_type' => 'id_token',
+                'redirect_uri' => $callback,
+                'scope' => 'openid',
+                'response_mode' => 'form_post',
+                'state' => time(),
+                'nonce' => time(),
+                'p' => $policy
+            ];
+        }
+
+        return $url . $action . '?' . http_build_query($urlParams);
+    }
+}

+ 55 - 0
plugin/azure_active_directory/src/callback.php

@@ -0,0 +1,55 @@
+<?php
+require dirname(__FILE__) . '/../../../main/inc/global.inc.php';
+require_once dirname(__FILE__) . '/../../../main/auth/external_login/functions.inc.php';
+
+if (isset($_POST['error']) || empty($_REQUEST)) {
+    header('Location: ' . api_get_path(WEB_PATH) . 'index.php?logout=logout');
+    exit;
+}
+
+list($jwtHeader, $jwtPayload, $jwtSignature) = explode('.', $_REQUEST['id_token']);
+
+$jwtHeader = json_decode(
+    base64_decode($jwtHeader)
+);
+
+$jwtPayload = json_decode(
+    base64_decode($jwtPayload)
+);
+
+$u = array(
+    'firstname' => $jwtPayload->given_name,
+    'lastname' => $jwtPayload->family_name,
+    'status' => STUDENT,
+    'email' => $jwtPayload->emails[0],
+    'username' => $jwtPayload->emails[0],
+    'language' => 'en',
+    'password' => 'azure_active_directory',
+    'auth_source' => 'azure_active_directory ' . $jwtPayload->idp,
+    'extra' => array()
+);
+
+$userInfo = api_get_user_info_from_email($jwtPayload->emails[0]);
+
+if ($userInfo === false) {
+    // we have to create the user
+    $chamilo_uid = external_add_user($u);
+
+    if ($chamilo_uid !== false) {
+        $_user['user_id'] = $chamilo_uid;
+        $_user['uidReset'] = true;
+        $_SESSION['_user'] = $_user;
+    }
+} else {
+    // User already exists, update info and login
+    $chamilo_uid = $userInfo['user_id'];
+    $u['user_id'] = $chamilo_uid;
+    external_update_user($u);
+
+    $_user['user_id'] = $chamilo_uid;
+    $_user['uidReset'] = true;
+    $_SESSION['_user'] = $_user;
+}
+
+header('Location: ' . api_get_path(WEB_PATH));
+exit;

+ 12 - 0
plugin/azure_active_directory/view/block.tpl

@@ -0,0 +1,12 @@
+<div id="azure-active-directory-login">
+    {% if _u.logged %}
+        {# <a href="{{ azure_active_directory.signout_url }}" class="btn btn-primary">{{ 'Logout'|get_lang }}</a> #}
+    {% else %}
+        {% if not azure_active_directory.block_title is empty %}
+            <h4>{{ azure_active_directory.block_title }}</h4>
+        {% endif %}
+
+        <a href="{{ azure_active_directory.signin_url }}" class="btn btn-default">{{ 'SignIn'|get_lang }}</a>
+        <a href="{{ azure_active_directory.signup_url }}" class="btn btn-success">{{ 'SignUp'|get_lang }}</a>
+    {% endif %}
+</div>

+ 15 - 5
plugin/bbb/lib/bbb.lib.php

@@ -55,16 +55,26 @@ class bbb
         $this->groupSupport = isset($columns['group_id']) ? true : false;
 
         if ($this->groupSupport) {
+            // Plugin check
             $this->groupSupport = (bool) $plugin->get('enable_conference_in_course_groups');
             if ($this->groupSupport) {
-                $courseInfo = api_get_course_info();
-                if ($courseInfo) {
-                    $this->groupSupport = api_get_course_setting('bbb_enable_conference_in_groups') === '1';
+
+                // Platform check
+                $bbbSetting = api_get_setting('bbb_enable_conference_in_course_groups');
+                $bbbSetting = isset($bbbSetting['bbb']) ? $bbbSetting['bbb'] === 'true' : false;
+
+                if ($bbbSetting) {
+                    // Course check
+                    $courseInfo = api_get_course_info();
+
+                    if ($courseInfo) {
+                        $this->groupSupport = api_get_course_setting('bbb_enable_conference_in_groups') === '1';
+                    }
                 }
             }
         }
 
-        if ($bbbPlugin === true) {
+        if ($bbbPlugin == true) {
             $userInfo = api_get_user_info();
             $this->userCompleteName = $userInfo['complete_name'];
             $this->salt = $bbb_salt;
@@ -152,7 +162,7 @@ class bbb
         # a user joins. If after this period, a user hasn't joined, the meeting is
         # removed from memory.
         defaultMeetingCreateJoinDuration=5
-     * 
+     *
      * @return mixed
      */
     public function createMeeting($params)

+ 27 - 3
plugin/createdrupaluser/README.md

@@ -1,4 +1,28 @@
-Create Drupal user
-==================
+Create Drupal user plugin
+=========================
+
+This plugin creates a user on a Drupal portal when a user is registered in 
+Chamilo.
+
+This uses the Hook mechanism available to Chamilo plugins: when enabling this 
+plugin, the HookCreateDrupalUser is automatically added to the hooks stack, and
+the UserManager::create_user() method calls the HookCreateUser hook and notifies
+it, resulting in the plugin code to be executed.
+
+The Drupal portal settings must be configured in the configuration panel for the
+plugin. A SOAP call is then initiated inside the plugin code, that will use the
+Drupal's addUser() web service. See src/HookCreateDrupalUser.php for more info
+on the call parameters.
+
+After calling the web service and receiving a positive answer, Chamilo stores
+the remote (Drupal) user ID inside the extra_field_values table, as field name
+"drupal_user_id". This later serves for updates and other synchronisation
+purposes.
+
+Extending
+---------
+
+Other plugins could easily be created by copying this one and modifying the
+class names and web services to call. Simply review every variable coined with
+the "drupal" name and update according to your own portal.
 
-Create a user in Drupal website when a user is registered in Chamilo LMS

+ 31 - 1
plugin/skype/README.md

@@ -1,4 +1,34 @@
 Skype Plugin
 ==============
 
-Create Skype user field
+This pluging was integrated within Chamilo LMS core
+
+To configure this plugin you need execute this SQL queries:
+
+* Enable the Skype extra field:
+```sql
+INSERT INTO extra_field (extra_field_type, field_type, variable, display_text, visible, changeable, created_at)
+VALUES
+(1, 1, 'skype', 'Skype', 1, 1, now());
+```
+* Enable the LinkedInURl extra field:
+```sql
+INSERT INTO extra_field (extra_field_type, field_type, variable, display_text, visible, changeable, created_at)
+VALUES
+(1, 1, 'linkedin_url', 'LinkedInUrl', 1, 1, now());
+```
+* Enable the configuration settings:
+```sql
+INSERT INTO settings_current (variable, subkey, type, category, selected_value, title, comment, access_url_changeable)
+VALUES
+('allow_show_skype_account', NULL, 'radio', 'Platform', 'true', 'AllowShowSkypeAccountTitle', 'AllowShowSkypeAccountComment', 1),
+('allow_show_linkedin_url', NULL, 'radio', 'Platform', 'true', 'AllowShowLinkedInUrlTitle', 'AllowShowLinkedInUrlComment', 1);
+```
+```sql
+INSERT INTO settings_options (variable, value, display_text)
+VALUES
+('allow_show_skype_account', 'true', 'Yes'),
+('allow_show_skype_account', 'false', 'No'),
+('allow_show_linkedin_url', 'true', 'Yes'),
+('allow_show_linkedin_url', 'false', 'No');
+```

+ 0 - 9
plugin/skype/config.php

@@ -1,9 +0,0 @@
-<?php
-/* For licensing terms, see /license.txt */
-/**
- * Config the plugin
- * @author Imanol Losada Oriol <imanol.losada@beeznest.com>
- * @package chamilo.plugin.skype
- */
-
-require_once api_get_path(SYS_PATH) . 'main/inc/global.inc.php';

+ 0 - 6
plugin/skype/index.php

@@ -1,8 +1,2 @@
 <?php
 /* For licensing terms, see /license.txt */
-/**
- * Config the plugin
- * @author Imanol Losada Oriol <imanol.losada@beeznest.com>
- * @package chamilo.plugin.skype
- */
-require_once __DIR__ . '/config.php';

+ 0 - 10
plugin/skype/install.php

@@ -1,10 +0,0 @@
-<?php
-/* For licensing terms, see /license.txt */
-/**
- * Initialization install
- * @author Imanol Losada Oriol <imanol.losada@beeznest.com>
- * @package chamilo.plugin.skype
- */
-require_once __DIR__ . '/config.php';
-
-Skype::create()->install();

+ 2 - 0
plugin/skype/lang/english.php

@@ -7,3 +7,5 @@
  */
 $strings['plugin_title'] = 'Skype';
 $strings['plugin_comment'] = 'This plugin creates a Skype user field.';
+
+$strings['ReadTheReadmeFile'] = '<p>Please read the <a href="/plugin/skype/readme.txt" class="ajax" data-size="lg">Readme.txt file</a> to configure this plugin.</p>';

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

@@ -7,3 +7,5 @@
  */
 $strings['plugin_title'] = 'Skype';
 $strings['plugin_comment'] = 'Este plugin crea un campo de usuario Skype.';
+
+$strings['ReadTheReadmeFile'] = '<p>Por favor, lee el<a href="/plugin/skype/readme.txt" class="ajax" data-size="lg">archivo Readme.txt</a> para configurar este plugin.</p>';

+ 0 - 1
plugin/skype/plugin.php

@@ -5,6 +5,5 @@
  * @author Imanol Losada Oriol <imanol.losada@beeznest.com>
  * @package chamilo.plugin.skype
  */
-require_once __DIR__.'/config.php';
 
 $plugin_info = Skype::create()->get_info();

+ 40 - 1
plugin/skype/readme.txt

@@ -1,2 +1,41 @@
 <h1>Skype Plugin</h1>
-<p>Create Skype user field</p>
+
+<p>This pluging was integrated within Chamilo LMS core</p>
+
+<p>To configure this plugin you need execute this SQL queries:</p>
+
+<ul>
+<li>Enable the Skype extra field:</li>
+</ul>
+
+<pre><code>INSERT INTO extra_field (extra_field_type, field_type, variable, display_text, visible, changeable, created_at)
+VALUES
+(1, 1, 'skype', 'Skype', 1, 1, now());
+</code></pre>
+
+<ul>
+<li>Enable the LinkedInURl extra field:</li>
+</ul>
+
+<pre><code>INSERT INTO extra_field (extra_field_type, field_type, variable, display_text, visible, changeable, created_at)
+VALUES
+(1, 1, 'linkedin_url', 'LinkedInUrl', 1, 1, now());
+</code></pre>
+
+<ul>
+<li>Enable the configuration settings:</li>
+</ul>
+
+<pre><code>INSERT INTO settings_current (variable, subkey, type, category, selected_value, title, comment, access_url_changeable)
+VALUES
+('allow_show_skype_account', NULL, 'radio', 'Platform', 'true', 'AllowShowSkypeAccountTitle', 'AllowShowSkypeAccountComment', 1),
+('allow_show_linkedin_url', NULL, 'radio', 'Platform', 'true', 'AllowShowLinkedInUrlTitle', 'AllowShowLinkedInUrlComment', 1);
+</code></pre>
+
+<pre><code>INSERT INTO settings_options (variable, value, display_text)
+VALUES
+('allow_show_skype_account', 'true', 'Yes'),
+('allow_show_skype_account', 'false', 'No'),
+('allow_show_linkedin_url', 'true', 'Yes'),
+('allow_show_linkedin_url', 'false', 'No');
+</code></pre>

+ 0 - 34
plugin/skype/src/HookSkype.php

@@ -1,34 +0,0 @@
-<?php
-/* For licensing terms, see /license.txt */
-
-/**
- * Create Skype user field
- *
- * @author Imanol Losada Oriol <imanol.losada@beeznest.com>
- * @package chamilo.plugin.skype
- */
-class HookObserverSkype extends HookObserver implements HookSkypeObserverInterface
-{
-
-    /**
-     * Class constructor
-     */
-    public function __construct()
-    {
-        parent::__construct(
-            'plugin/skype/src/Skype.php', 'skype'
-        );
-    }
-
-    /**
-     * Create Skype user field when plugin is enabled
-     * @param HookSkypeEventInterface $hook The hook
-     */
-    public function hookEventSkype(HookSkypeEventInterface $hook)
-    {
-        $data = $hook->getEventData();
-        if ($data['type'] === HOOK_EVENT_TYPE_PRE) {
-            // Code
-        }
-    }
-}

+ 6 - 61
plugin/skype/src/Skype.php

@@ -7,7 +7,7 @@
  * @author Imanol Losada Oriol <imanol.losada@beeznest.com>
  * @package chamilo.plugin.skype
  */
-class Skype extends Plugin implements HookPluginInterface
+class Skype extends Plugin
 {
 
     /**
@@ -15,7 +15,11 @@ class Skype extends Plugin implements HookPluginInterface
      */
     protected function __construct()
     {
-        parent::__construct('0.1', 'Imanol Losada Oriol');
+        parent::__construct(
+            '0.2',
+            'Imanol Losada Oriol',
+            [$this->get_lang('ReadTheReadmeFile') => 'html']
+        );
     }
 
     /**
@@ -29,63 +33,4 @@ class Skype extends Plugin implements HookPluginInterface
 
         return $result ? $result : $result = new self();
     }
-
-    /**
-     * Install the plugin
-     */
-    public function install()
-    {
-        $this->installHook();
-
-        $result = Database::select(
-            'variable',
-            Database::get_main_table(TABLE_EXTRA_FIELD),
-            array(
-                'where'=> array(
-                    'variable = ?' => array(
-                        'skype'
-                    )
-                )
-            )
-        );
-
-        if (empty($result)) {
-            $extraField = new ExtraField('user');
-            $extraField->save(array(
-                'field_type' => ExtraField::FIELD_TYPE_TEXT,
-                'variable' => 'skype',
-                'display_text' => 'Skype',
-                'visible' => 1,
-                'changeable' => 1
-            ));
-        }
-    }
-
-    /**
-     * Uninstall the plugin
-     * @return void
-     */
-    public function uninstall()
-    {
-        $this->uninstallHook();
-    }
-
-    /**
-     * Install the Skype hook
-     */
-    public function installHook()
-    {
-        $hook = HookObserverSkype::create();
-        HookEventSkype::create()->attach($hook);
-    }
-
-    /**
-     * Uninstall the Skype hook
-     */
-    public function uninstallHook()
-    {
-        $hook = HookObserverSkype::create();
-        HookEventSkype::create()->detach($hook);
-    }
-
 }

+ 0 - 10
plugin/skype/uninstall.php

@@ -1,10 +0,0 @@
-<?php
-/* For licensing terms, see /license.txt */
-/**
- * Initialization uninstall
- * @author Imanol Losada Oriol <imanol.losada@beeznest.com>
- * @package chamilo.plugin.skype
- */
-require_once __DIR__ . '/config.php';
-
-Skype::create()->uninstall();

+ 6 - 1
src/Chamilo/CoreBundle/Entity/ExtraFieldValues.php

@@ -10,7 +10,12 @@ use Sylius\Component\Attribute\Model\AttributeValue as BaseAttributeValue;
 /**
  * Class ExtraFieldValues
  *
- * @ORM\Table(name="extra_field_values")
+ * @ORM\Table(
+ *     name="extra_field_values",
+ *     indexes={
+ *         @ORM\Index(name="idx_efv_fiii", columns={"field_id", "item_id"}),
+ *     }
+ * )
  * @ORM\Entity(repositoryClass="Chamilo\CoreBundle\Entity\Repository\ExtraFieldValuesRepository")
  * @ORM\MappedSuperclass
  */

+ 3 - 3
src/Chamilo/CoreBundle/Entity/Language.php

@@ -13,7 +13,7 @@ use Doctrine\ORM\Mapping as ORM;
 class Language
 {
     /**
-     * @var boolean
+     * @var integer
      *
      * @ORM\Column(name="id", type="integer")
      * @ORM\Id
@@ -57,9 +57,9 @@ class Language
     private $available;
 
     /**
-     * @var boolean
+     * @var integer
      *
-     * @ORM\Column(name="parent_id", type="boolean", nullable=true)
+     * @ORM\Column(name="parent_id", type="integer", nullable=true)
      */
     private $parentId;
 

+ 1 - 0
src/Chamilo/CoreBundle/Entity/SysCalendar.php

@@ -1,4 +1,5 @@
 <?php
+/* For licensing terms, see /license.txt */
 
 namespace Chamilo\CoreBundle\Entity;
 

+ 1 - 0
src/Chamilo/CoreBundle/Entity/SystemTemplate.php

@@ -1,4 +1,5 @@
 <?php
+/* For licensing terms, see /license.txt */
 
 namespace Chamilo\CoreBundle\Entity;
 

+ 10 - 11
src/Chamilo/CoreBundle/Entity/Tag.php

@@ -1,4 +1,5 @@
 <?php
+/* For licensing terms, see /license.txt */
 
 namespace Chamilo\CoreBundle\Entity;
 
@@ -12,6 +13,15 @@ use Doctrine\ORM\Mapping as ORM;
  */
 class Tag
 {
+    /**
+     * @var integer
+     *
+     * @ORM\Column(name="id", type="integer")
+     * @ORM\Id
+     * @ORM\GeneratedValue
+     */
+    private $id;
+
     /**
      * @var string
      *
@@ -33,17 +43,6 @@ class Tag
      */
     private $count;
 
-    /**
-     * @var integer
-     *
-     * @ORM\Column(name="id", type="integer")
-     * @ORM\Id
-     * @ORM\GeneratedValue(strategy="IDENTITY")
-     */
-    private $id;
-
-
-
     /**
      * Set tag
      *

+ 1 - 0
src/Chamilo/CoreBundle/Entity/Templates.php

@@ -1,4 +1,5 @@
 <?php
+/* For licensing terms, see /license.txt */
 
 namespace Chamilo\CoreBundle\Entity;
 

+ 1 - 0
src/Chamilo/CoreBundle/Entity/TrackCourseRanking.php

@@ -1,4 +1,5 @@
 <?php
+/* For licensing terms, see /license.txt */
 
 namespace Chamilo\CoreBundle\Entity;
 

+ 1 - 0
src/Chamilo/CoreBundle/Entity/TrackEAccess.php

@@ -1,4 +1,5 @@
 <?php
+/* For licensing terms, see /license.txt */
 
 namespace Chamilo\CoreBundle\Entity;
 

+ 1 - 0
src/Chamilo/CoreBundle/Entity/TrackEAttempt.php

@@ -1,4 +1,5 @@
 <?php
+/* For licensing terms, see /license.txt */
 
 namespace Chamilo\CoreBundle\Entity;
 

+ 1 - 0
src/Chamilo/CoreBundle/Entity/TrackEAttemptCoeff.php

@@ -1,4 +1,5 @@
 <?php
+/* For licensing terms, see /license.txt */
 
 namespace Chamilo\CoreBundle\Entity;
 

+ 10 - 11
src/Chamilo/CoreBundle/Entity/TrackEAttemptRecording.php

@@ -1,4 +1,5 @@
 <?php
+/* For licensing terms, see /license.txt */
 
 namespace Chamilo\CoreBundle\Entity;
 
@@ -12,6 +13,15 @@ use Doctrine\ORM\Mapping as ORM;
  */
 class TrackEAttemptRecording
 {
+    /**
+     * @var integer
+     *
+     * @ORM\Column(name="id", type="integer")
+     * @ORM\Id
+     * @ORM\GeneratedValue
+     */
+    private $id;
+
     /**
      * @var integer
      *
@@ -61,17 +71,6 @@ class TrackEAttemptRecording
      */
     private $sessionId;
 
-    /**
-     * @var integer
-     *
-     * @ORM\Column(name="id", type="integer")
-     * @ORM\Id
-     * @ORM\GeneratedValue(strategy="IDENTITY")
-     */
-    private $id;
-
-
-
     /**
      * Set exeId
      *

+ 10 - 11
src/Chamilo/CoreBundle/Entity/TrackECourseAccess.php

@@ -1,4 +1,5 @@
 <?php
+/* For licensing terms, see /license.txt */
 
 namespace Chamilo\CoreBundle\Entity;
 
@@ -20,6 +21,15 @@ use Doctrine\ORM\Mapping as ORM;
  */
 class TrackECourseAccess
 {
+    /**
+     * @var integer
+     *
+     * @ORM\Column(name="course_access_id", type="integer")
+     * @ORM\Id
+     * @ORM\GeneratedValue
+     */
+    private $courseAccessId;
+
     /**
      * @var integer
      *
@@ -69,17 +79,6 @@ class TrackECourseAccess
      */
     private $userIp;
 
-    /**
-     * @var integer
-     *
-     * @ORM\Column(name="course_access_id", type="integer")
-     * @ORM\Id
-     * @ORM\GeneratedValue(strategy="IDENTITY")
-     */
-    private $courseAccessId;
-
-
-
     /**
      * Set cId
      *

+ 1 - 0
src/Chamilo/CoreBundle/Entity/TrackEDownloads.php

@@ -1,4 +1,5 @@
 <?php
+/* For licensing terms, see /license.txt */
 
 namespace Chamilo\CoreBundle\Entity;
 

+ 1 - 0
src/Chamilo/CoreBundle/Entity/TrackEExercises.php

@@ -1,4 +1,5 @@
 <?php
+/* For licensing terms, see /license.txt */
 
 namespace Chamilo\CoreBundle\Entity;
 

+ 1 - 0
src/Chamilo/CoreBundle/Entity/TrackEHotpotatoes.php

@@ -1,4 +1,5 @@
 <?php
+/* For licensing terms, see /license.txt */
 
 namespace Chamilo\CoreBundle\Entity;
 

+ 1 - 0
src/Chamilo/CoreBundle/Entity/TrackEHotspot.php

@@ -1,4 +1,5 @@
 <?php
+/* For licensing terms, see /license.txt */
 
 namespace Chamilo\CoreBundle\Entity;
 

+ 1 - 0
src/Chamilo/CoreBundle/Entity/TrackEItemProperty.php

@@ -1,4 +1,5 @@
 <?php
+/* For licensing terms, see /license.txt */
 
 namespace Chamilo\CoreBundle\Entity;
 

+ 1 - 0
src/Chamilo/CoreBundle/Entity/TrackELastaccess.php

@@ -1,4 +1,5 @@
 <?php
+/* For licensing terms, see /license.txt */
 
 namespace Chamilo\CoreBundle\Entity;
 

+ 1 - 0
src/Chamilo/CoreBundle/Entity/TrackELinks.php

@@ -1,4 +1,5 @@
 <?php
+/* For licensing terms, see /license.txt */
 
 namespace Chamilo\CoreBundle\Entity;
 

+ 1 - 0
src/Chamilo/CoreBundle/Entity/TrackELogin.php

@@ -1,4 +1,5 @@
 <?php
+/* For licensing terms, see /license.txt */
 
 namespace Chamilo\CoreBundle\Entity;
 

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