Merge 1.10.x

ofaj
jmontoyaa 10 years ago
commit c18487259b
  1. 11
      .travis.yml
  2. 2
      app/Migrations/AbstractMigrationChamilo.php
  3. 93
      app/Migrations/Schema/V110/Version110.php
  4. 27
      app/Resources/public/css/base.css
  5. 115
      documentation/changelog.html
  6. 2
      index.php
  7. 81
      main/admin/settings.lib.php
  8. 26
      main/admin/statistics/index.php
  9. 399
      main/admin/sub_language_add.php
  10. 2
      main/admin/user_import.php
  11. 29
      main/admin/user_information.php
  12. 2
      main/admin/user_list.php
  13. 2
      main/admin/user_update_import.php
  14. 12
      main/admin/usergroups.php
  15. 2
      main/attendance/attendance_controller.php
  16. 203
      main/auth/cas/authcas.php
  17. 2421
      main/auth/cas/lib/CAS.php
  18. 8
      main/auth/cas/lib/CAS/PGTStorage/pgt-db.php
  19. 14
      main/auth/cas/lib/CAS/PGTStorage/pgt-file.php
  20. 4
      main/auth/cas/lib/CAS/PGTStorage/pgt-main.php
  21. 5352
      main/auth/cas/lib/CAS/client.php
  22. 1204
      main/auth/cas/lib/CAS/domxml-php4-to-php5.php
  23. 3
      main/auth/courses_controller.php
  24. 7
      main/auth/external_login/facebook-php-sdk/src/Facebook/Entities/AccessToken.php
  25. 4
      main/auth/external_login/facebook-php-sdk/src/Facebook/Entities/SignedRequest.php
  26. 1
      main/auth/external_login/facebook-php-sdk/src/Facebook/HttpClients/FacebookGuzzleHttpClient.php
  27. 6
      main/auth/external_login/facebook.inc.php
  28. 2
      main/auth/external_login/functions.inc.php
  29. 4
      main/auth/key/key_auth.class.php
  30. 5
      main/auth/ldap/authldap.php
  31. 1
      main/auth/openid/login.php
  32. 16
      main/auth/openid/openid.lib.php
  33. 2
      main/auth/reset.php
  34. 2
      main/auth/shibboleth/app/model/shibboleth_store.class.php
  35. 3
      main/auth/shibboleth/app/model/user.class.php
  36. 3
      main/auth/shibboleth/app/shibboleth.class.php
  37. 6
      main/auth/shibboleth/app/view/shibboleth_display.class.php
  38. 757
      main/document/create_audio.php
  39. 43
      main/document/create_draw.php
  40. 4
      main/document/document.php
  41. 18
      main/document/edit_draw.php
  42. 1
      main/exercice/answer.class.php
  43. 21
      main/exercice/calculated_answer.class.php
  44. 176
      main/exercice/exercise.class.php
  45. 2
      main/exercice/exercise_reminder.php
  46. 7
      main/exercice/exercise_result.php
  47. 158
      main/exercice/exercise_show.php
  48. 19
      main/exercice/fill_blanks.class.php
  49. 7
      main/exercice/global_multiple_answer.class.php
  50. 12
      main/exercice/hotspot_actionscript.as.php
  51. 2
      main/exercice/overview.php
  52. BIN
      main/img/icons/32/add-class.png
  53. 3538
      main/img/icons/svg/add-class.svg
  54. 5
      main/inc/ajax/exercise.ajax.php
  55. 11
      main/inc/global.inc.php
  56. 22
      main/inc/lib/api.lib.php
  57. 5
      main/inc/lib/course.lib.php
  58. 32
      main/inc/lib/diagnoser.lib.php
  59. 4
      main/inc/lib/display.lib.php
  60. 73
      main/inc/lib/exercise.lib.php
  61. 150
      main/inc/lib/exercise_show_functions.lib.php
  62. 14408
      main/inc/lib/icalcreator/iCalcreator.class.php
  63. 2
      main/inc/lib/javascript/svgedit/browser-not-supported.html
  64. 0
      main/inc/lib/javascript/svgedit/browser.js
  65. 2021
      main/inc/lib/javascript/svgedit/canvg/canvg.js
  66. 0
      main/inc/lib/javascript/svgedit/canvg/rgbcolor.js
  67. 3
      main/inc/lib/javascript/svgedit/config-sample.js
  68. 17
      main/inc/lib/javascript/svgedit/config.js
  69. 0
      main/inc/lib/javascript/svgedit/contextmenu.js
  70. 404
      main/inc/lib/javascript/svgedit/contextmenu/jquery.contextMenu.js
  71. 9
      main/inc/lib/javascript/svgedit/coords.js
  72. 6
      main/inc/lib/javascript/svgedit/custom.css
  73. 0
      main/inc/lib/javascript/svgedit/draw.js
  74. 79
      main/inc/lib/javascript/svgedit/embedapi-dom.js
  75. 17
      main/inc/lib/javascript/svgedit/embedapi.html
  76. 46
      main/inc/lib/javascript/svgedit/embedapi.js
  77. 5
      main/inc/lib/javascript/svgedit/extensions/allowedMimeTypes.php
  78. 0
      main/inc/lib/javascript/svgedit/extensions/closepath_icons.svg
  79. 9
      main/inc/lib/javascript/svgedit/extensions/executablebuilder-icocreator.svg
  80. 0
      main/inc/lib/javascript/svgedit/extensions/ext-arrows.js
  81. 0
      main/inc/lib/javascript/svgedit/extensions/ext-closepath.js
  82. 2
      main/inc/lib/javascript/svgedit/extensions/ext-connector.js
  83. 67
      main/inc/lib/javascript/svgedit/extensions/ext-executablebuilder.js
  84. 0
      main/inc/lib/javascript/svgedit/extensions/ext-eyedropper.js
  85. 2
      main/inc/lib/javascript/svgedit/extensions/ext-foreignobject.js
  86. 21
      main/inc/lib/javascript/svgedit/extensions/ext-grid.js
  87. 2
      main/inc/lib/javascript/svgedit/extensions/ext-helloworld.js
  88. 474
      main/inc/lib/javascript/svgedit/extensions/ext-imagelib.js
  89. 26
      main/inc/lib/javascript/svgedit/extensions/ext-imagelib.xml
  90. 0
      main/inc/lib/javascript/svgedit/extensions/ext-markers.js
  91. 4
      main/inc/lib/javascript/svgedit/extensions/ext-mathjax.js
  92. 16
      main/inc/lib/javascript/svgedit/extensions/ext-overview_window.js
  93. 0
      main/inc/lib/javascript/svgedit/extensions/ext-panning.js
  94. 0
      main/inc/lib/javascript/svgedit/extensions/ext-panning.xml
  95. 0
      main/inc/lib/javascript/svgedit/extensions/ext-php_savefile.js
  96. 34
      main/inc/lib/javascript/svgedit/extensions/ext-php_savefile_chamilo.js
  97. 3
      main/inc/lib/javascript/svgedit/extensions/ext-polygon.js
  98. 10
      main/inc/lib/javascript/svgedit/extensions/ext-server_moinsave.js
  99. 94
      main/inc/lib/javascript/svgedit/extensions/ext-server_opensave.js
  100. 8
      main/inc/lib/javascript/svgedit/extensions/ext-shapes.js
  101. Some files were not shown because too many files have changed in this diff Show More

@ -4,6 +4,7 @@ php:
#- 5.4 // Removed because of Chash dependencies on PHP 5.5
- 5.5
- 5.6
- 7.0
before_install:
#- sudo apt-get install python-software-properties
@ -28,8 +29,12 @@ before_script:
#- composer global require "fxp/composer-asset-plugin:1.0.3"
# You can either use the composer install method and face the Github limit
#- composer install -n
- composer -v update
# ...OR use the proxy repository to download the necessary dependencies
- composer update
# ...OR you can try the option --prefer-dist, that will reuse composer packages cache
#- composer update --prefer-dist
# ...OR you can try the --prefer-source option to download from source whenever it's possible (but it's much slower)
#- composer update --prefer-source
# ...OR use the proxy repository to download the necessary dependencies, but this repo is not always updated
#- git clone -b 1.10.x --depth=1 https://github.com/ywarnier/chamilo-vendors.git
#- sudo mv chamilo-vendors/vendor .
#- sudo mv chamilo-vendors/web .
@ -67,6 +72,8 @@ before_script:
#- cd ../..
# install Chamilo with Chash - see reference https://github.com/sonnym/travis-ci-drupal-module-example/blob/master/.travis.yml
- cd /home/travis/build/chamilo/chamilo-lms
# There's an issue with Chash, starting in version 1.10, whereby PHP CLI on Travis-ci is PHP5.3, whatever the version you ask for.
# This effectively breaks the installer and renders these tests useless. We are looking for a solution (for example using containers)
- sudo chash chash:chamilo_install --no-interaction --sitename="Chamilo" --site_url="http://localhost/" --institution="Chamilo" --institution_url="https://chamilo.org" --encrypt_method="sha1" --firstname="John" --lastname="Doe" --language="english" --driver="mysqlnd" --host="localhost" --port="3306" --dbname="chamilo" --dbuser="root" --permissions_for_new_directories="0777" --permissions_for_new_files="0666" --linux-user="www-data" --linux-group="www-data" --username="admin" --password="admin" --email="admin@example.com" --phone="555-5555" 1.10.x
script:

@ -124,7 +124,7 @@ abstract class AbstractMigrationChamilo extends AbstractMigration
}
/**
* @param $variable
* @param string $variable
* @return mixed
*/
public function getConfigurationValue($variable)

@ -123,8 +123,9 @@ class Version110 extends AbstractMigrationChamilo
$this->addSql("ALTER TABLE track_e_online CHANGE COLUMN login_ip user_ip varchar(39) NOT NULL DEFAULT ''");
$this->addSql("ALTER TABLE track_e_login CHANGE COLUMN login_ip user_ip varchar(39) NOT NULL DEFAULT ''");
$this->addSql("ALTER TABLE user MODIFY COLUMN user_id int unsigned DEFAULT NULL");
$this->addSql("ALTER TABLE user MODIFY COLUMN user_id int unsigned NOT NULL");
$this->addSql("ALTER TABLE user DROP PRIMARY KEY");
$this->addSql("ALTER TABLE user MODIFY COLUMN user_id int unsigned DEFAULT NULL");
$this->addSql("ALTER TABLE user ADD COLUMN id INT DEFAULT NULL");
$this->addSql("UPDATE user SET id = user_id");
$this->addSql("ALTER TABLE user MODIFY COLUMN id INT NOT NULL PRIMARY KEY AUTO_INCREMENT AFTER user_id");
@ -252,16 +253,18 @@ class Version110 extends AbstractMigrationChamilo
foreach ($tables as $table) {
if ($schema->hasTable($table)) {
$this->addSql("ALTER TABLE $table MODIFY COLUMN id INT NULL");
$this->addSql("ALTER TABLE $table MODIFY COLUMN id INT NOT NULL");
$this->addSql("ALTER TABLE $table MODIFY COLUMN c_id INT NOT NULL");
$this->addSql("ALTER TABLE $table DROP PRIMARY KEY");
$this->addSql("ALTER TABLE $table MODIFY COLUMN id INT NULL");
$this->addSql("ALTER TABLE $table ADD COLUMN iid int NOT NULL PRIMARY KEY AUTO_INCREMENT");
}
}
if ($schema->hasTable('c_attendance_calendar_rel_group')) {
$this->addSql("ALTER TABLE c_attendance_calendar_rel_group MODIFY COLUMN id INT NULL DEFAULT NULL");
$this->addSql("ALTER TABLE c_attendance_calendar_rel_group MODIFY COLUMN id INT NOT NULL");
$this->addSql("ALTER TABLE c_attendance_calendar_rel_group DROP PRIMARY KEY");
$this->addSql("ALTER TABLE c_attendance_calendar_rel_group MODIFY COLUMN id INT NULL DEFAULT NULL");
$this->addSql("ALTER TABLE c_attendance_calendar_rel_group ADD COLUMN iid int NOT NULL PRIMARY KEY AUTO_INCREMENT");
}
@ -269,104 +272,117 @@ class Version110 extends AbstractMigrationChamilo
$this->addSql("ALTER TABLE c_attendance_sheet DROP PRIMARY KEY");
$this->addSql("ALTER TABLE c_attendance_sheet ADD COLUMN iid int NOT NULL PRIMARY KEY AUTO_INCREMENT");
$this->addSql("ALTER TABLE c_blog MODIFY COLUMN blog_id int unsigned DEFAULT NULL");
$this->addSql("ALTER TABLE c_blog MODIFY COLUMN blog_id int unsigned NOT NULL");
$this->addSql("ALTER TABLE c_blog MODIFY COLUMN c_id INT NOT NULL");
$this->addSql("ALTER TABLE c_blog DROP PRIMARY KEY");
$this->addSql("ALTER TABLE c_blog MODIFY COLUMN blog_id int unsigned DEFAULT NULL");
$this->addSql("ALTER TABLE c_blog ADD COLUMN iid int NOT NULL PRIMARY KEY AUTO_INCREMENT");
$this->addSql("ALTER TABLE c_blog_comment MODIFY COLUMN comment_id int DEFAULT NULL");
$this->addSql("ALTER TABLE c_blog_comment MODIFY COLUMN comment_id int NOT NULL");
$this->addSql("ALTER TABLE c_blog_comment MODIFY COLUMN c_id INT NOT NULL");
$this->addSql("ALTER TABLE c_blog_comment DROP PRIMARY KEY");
$this->addSql("ALTER TABLE c_blog_comment MODIFY COLUMN comment_id int DEFAULT NULL");
$this->addSql("ALTER TABLE c_blog_comment ADD COLUMN iid int NOT NULL PRIMARY KEY AUTO_INCREMENT");
$this->addSql("ALTER TABLE c_blog_post MODIFY COLUMN post_id int unsigned DEFAULT NULL");
$this->addSql("ALTER TABLE c_blog_post MODIFY COLUMN post_id int unsigned NOT NULL");
$this->addSql("ALTER TABLE c_blog_post MODIFY COLUMN c_id INT NOT NULL");
$this->addSql("ALTER TABLE c_blog_post DROP PRIMARY KEY");
$this->addSql("ALTER TABLE c_blog_post MODIFY COLUMN post_id int unsigned DEFAULT NULL");
$this->addSql("ALTER TABLE c_blog_post ADD COLUMN iid int NOT NULL PRIMARY KEY AUTO_INCREMENT");
$this->addSql("ALTER TABLE c_blog_rating MODIFY COLUMN rating_id int unsigned DEFAULT NULL");
$this->addSql("ALTER TABLE c_blog_rating MODIFY COLUMN rating_id int unsigned NOT NULL");
$this->addSql("ALTER TABLE c_blog_rating MODIFY COLUMN c_id INT NOT NULL");
$this->addSql("ALTER TABLE c_blog_rating DROP PRIMARY KEY");
$this->addSql("ALTER TABLE c_blog_rating MODIFY COLUMN rating_id int unsigned DEFAULT NULL");
$this->addSql("ALTER TABLE c_blog_rating ADD COLUMN iid int NOT NULL PRIMARY KEY AUTO_INCREMENT");
$this->addSql("ALTER TABLE c_blog_rel_user DROP PRIMARY KEY");
$this->addSql("ALTER TABLE c_blog_rel_user MODIFY COLUMN c_id INT NOT NULL");
$this->addSql("ALTER TABLE c_blog_rel_user MODIFY COLUMN blog_id int unsigned DEFAULT NULL");
$this->addSql("ALTER TABLE c_blog_rel_user MODIFY COLUMN user_id int unsigned DEFAULT NULL");
$this->addSql("ALTER TABLE c_blog_rel_user DROP PRIMARY KEY");
$this->addSql("ALTER TABLE c_blog_rel_user ADD COLUMN iid int NOT NULL PRIMARY KEY AUTO_INCREMENT");
$this->addSql("ALTER TABLE c_blog_task MODIFY COLUMN task_id int unsigned DEFAULT NULL");
$this->addSql("ALTER TABLE c_blog_task MODIFY COLUMN task_id int unsigned NOT NULL");
$this->addSql("ALTER TABLE c_blog_task MODIFY COLUMN c_id INT NOT NULL");
$this->addSql("ALTER TABLE c_blog_task DROP PRIMARY KEY");
$this->addSql("ALTER TABLE c_blog_task MODIFY COLUMN task_id int unsigned DEFAULT NULL");
$this->addSql("ALTER TABLE c_blog_task ADD COLUMN iid int NOT NULL PRIMARY KEY AUTO_INCREMENT");
$this->addSql("ALTER TABLE c_blog_task_rel_user DROP PRIMARY KEY");
$this->addSql("ALTER TABLE c_blog_task_rel_user MODIFY COLUMN blog_id int unsigned DEFAULT NULL");
$this->addSql("ALTER TABLE c_blog_task_rel_user MODIFY COLUMN user_id int unsigned DEFAULT NULL");
$this->addSql("ALTER TABLE c_blog_task_rel_user MODIFY COLUMN task_id int unsigned DEFAULT NULL");
$this->addSql("ALTER TABLE c_blog_task_rel_user DROP PRIMARY KEY");
$this->addSql("ALTER TABLE c_blog_task_rel_user ADD COLUMN iid int NOT NULL PRIMARY KEY AUTO_INCREMENT");
$this->addSql("ALTER TABLE c_calendar_event_repeat DROP PRIMARY KEY");
$this->addSql("ALTER TABLE c_calendar_event_repeat MODIFY COLUMN cal_id int unsigned DEFAULT NULL");
$this->addSql("ALTER TABLE c_calendar_event_repeat MODIFY COLUMN c_id INT NOT NULL");
$this->addSql("ALTER TABLE c_calendar_event_repeat DROP PRIMARY KEY");
$this->addSql("ALTER TABLE c_calendar_event_repeat ADD COLUMN iid int NOT NULL PRIMARY KEY AUTO_INCREMENT");
$this->addSql("ALTER TABLE c_calendar_event_repeat_not DROP PRIMARY KEY");
$this->addSql("ALTER TABLE c_calendar_event_repeat_not MODIFY COLUMN cal_id int unsigned DEFAULT NULL");
$this->addSql("ALTER TABLE c_calendar_event_repeat_not MODIFY COLUMN c_id INT NOT NULL");
$this->addSql("ALTER TABLE c_calendar_event_repeat_not DROP PRIMARY KEY");
$this->addSql("ALTER TABLE c_calendar_event_repeat_not ADD COLUMN iid int NOT NULL PRIMARY KEY AUTO_INCREMENT");
$this->addSql("ALTER TABLE c_dropbox_category MODIFY COLUMN cat_id int unsigned NOT NULL");
$this->addSql("ALTER TABLE c_dropbox_category DROP PRIMARY KEY");
$this->addSql("ALTER TABLE c_dropbox_category MODIFY COLUMN cat_id int unsigned DEFAULT NULL");
$this->addSql("ALTER TABLE c_dropbox_category MODIFY COLUMN c_id INT NOT NULL");
$this->addSql("ALTER TABLE c_dropbox_category DROP PRIMARY KEY");
$this->addSql("ALTER TABLE c_dropbox_category ADD COLUMN iid int NOT NULL PRIMARY KEY AUTO_INCREMENT");
$this->addSql("ALTER TABLE c_dropbox_feedback MODIFY COLUMN feedback_id int unsigned NOT NULL");
$this->addSql("ALTER TABLE c_dropbox_feedback DROP PRIMARY KEY");
$this->addSql("ALTER TABLE c_dropbox_feedback MODIFY COLUMN feedback_id int unsigned DEFAULT NULL");
$this->addSql("ALTER TABLE c_dropbox_feedback MODIFY COLUMN c_id INT NOT NULL");
$this->addSql("ALTER TABLE c_dropbox_feedback DROP PRIMARY KEY");
$this->addSql("ALTER TABLE c_dropbox_feedback ADD COLUMN iid int NOT NULL PRIMARY KEY AUTO_INCREMENT");
$this->addSql("ALTER TABLE c_dropbox_person DROP PRIMARY KEY");
$this->addSql("ALTER TABLE c_dropbox_person MODIFY COLUMN file_id int unsigned DEFAULT NULL");
$this->addSql("ALTER TABLE c_dropbox_person MODIFY COLUMN c_id INT NOT NULL");
$this->addSql("ALTER TABLE c_dropbox_person DROP PRIMARY KEY");
$this->addSql("ALTER TABLE c_dropbox_person ADD COLUMN iid int NOT NULL PRIMARY KEY AUTO_INCREMENT");
$this->addSql("ALTER TABLE c_dropbox_post DROP PRIMARY KEY");
$this->addSql("ALTER TABLE c_dropbox_post MODIFY COLUMN file_id int unsigned DEFAULT NULL");
$this->addSql("ALTER TABLE c_dropbox_post MODIFY COLUMN c_id INT NOT NULL");
$this->addSql("ALTER TABLE c_dropbox_post DROP PRIMARY KEY");
$this->addSql("ALTER TABLE c_dropbox_post ADD COLUMN iid int NOT NULL PRIMARY KEY AUTO_INCREMENT");
$this->addSql("ALTER TABLE c_forum_category MODIFY COLUMN cat_id int unsigned NOT NULL");
$this->addSql("ALTER TABLE c_forum_category DROP PRIMARY KEY");
$this->addSql("ALTER TABLE c_forum_category MODIFY COLUMN cat_id int unsigned DEFAULT NULL");
$this->addSql("ALTER TABLE c_forum_category MODIFY COLUMN c_id INT NOT NULL");
$this->addSql("ALTER TABLE c_forum_category DROP PRIMARY KEY");
$this->addSql("ALTER TABLE c_forum_category ADD COLUMN iid int NOT NULL PRIMARY KEY AUTO_INCREMENT");
$this->addSql("ALTER TABLE c_forum_forum MODIFY COLUMN forum_id int unsigned NOT NULL");
$this->addSql("ALTER TABLE c_forum_forum DROP PRIMARY KEY");
$this->addSql("ALTER TABLE c_forum_forum MODIFY COLUMN forum_id int unsigned DEFAULT NULL");
$this->addSql("ALTER TABLE c_forum_forum MODIFY COLUMN c_id INT NOT NULL");
$this->addSql("ALTER TABLE c_forum_forum DROP PRIMARY KEY");
$this->addSql("ALTER TABLE c_forum_forum ADD COLUMN iid int NOT NULL PRIMARY KEY AUTO_INCREMENT");
$this->addSql("ALTER TABLE c_forum_post MODIFY COLUMN post_id int unsigned NOT NULL");
$this->addSql("ALTER TABLE c_forum_post DROP PRIMARY KEY");
$this->addSql("ALTER TABLE c_forum_post MODIFY COLUMN post_id int unsigned DEFAULT NULL");
$this->addSql("ALTER TABLE c_forum_post MODIFY COLUMN c_id INT NOT NULL");
$this->addSql("ALTER TABLE c_forum_post DROP PRIMARY KEY");
$this->addSql("ALTER TABLE c_forum_post ADD COLUMN iid int NOT NULL PRIMARY KEY AUTO_INCREMENT");
$this->addSql("ALTER TABLE c_forum_thread MODIFY COLUMN thread_id int unsigned NOT NULL");
$this->addSql("ALTER TABLE c_forum_thread DROP PRIMARY KEY");
$this->addSql("ALTER TABLE c_forum_thread MODIFY COLUMN forum_id int unsigned DEFAULT NULL");
$this->addSql("ALTER TABLE c_forum_thread MODIFY COLUMN c_id INT NOT NULL");
$this->addSql("ALTER TABLE c_forum_thread MODIFY COLUMN thread_id int unsigned DEFAULT NULL");
$this->addSql("ALTER TABLE c_forum_thread DROP PRIMARY KEY");
$this->addSql("ALTER TABLE c_forum_thread ADD COLUMN iid int NOT NULL PRIMARY KEY AUTO_INCREMENT");
$this->addSql("ALTER TABLE c_forum_thread ADD COLUMN thread_peer_qualify tinyint default 0");
$this->addSql("ALTER TABLE c_glossary MODIFY COLUMN glossary_id int unsigned DEFAULT NULL");
$this->addSql("ALTER TABLE c_glossary MODIFY COLUMN glossary_id int unsigned NOT NULL");
$this->addSql("ALTER TABLE c_glossary MODIFY COLUMN c_id INT NOT NULL");
$this->addSql("ALTER TABLE c_glossary DROP PRIMARY KEY");
$this->addSql("ALTER TABLE c_glossary MODIFY COLUMN glossary_id int unsigned DEFAULT NULL");
$this->addSql("ALTER TABLE c_glossary ADD COLUMN iid int NOT NULL PRIMARY KEY AUTO_INCREMENT");
$this->addSql("ALTER TABLE c_notebook MODIFY COLUMN notebook_id int unsigned DEFAULT NULL");
$this->addSql("ALTER TABLE c_notebook MODIFY COLUMN notebook_id int unsigned NOT NULL");
$this->addSql("ALTER TABLE c_notebook MODIFY COLUMN c_id INT NOT NULL");
$this->addSql("ALTER TABLE c_notebook DROP PRIMARY KEY");
$this->addSql("ALTER TABLE c_notebook MODIFY COLUMN notebook_id int unsigned DEFAULT NULL");
$this->addSql("ALTER TABLE c_notebook ADD COLUMN iid int NOT NULL PRIMARY KEY AUTO_INCREMENT");
$this->addSql("ALTER TABLE c_online_connected MODIFY COLUMN c_id INT NOT NULL");
@ -376,18 +392,21 @@ class Version110 extends AbstractMigrationChamilo
// For some reason c_tool_intro.id is a varchar in 1.9.x
$this->addSql("ALTER TABLE c_tool_intro MODIFY COLUMN id VARCHAR(50) NOT NULL");
$this->addSql("ALTER TABLE c_tool_intro MODIFY COLUMN c_id INT NOT NULL");
$this->addSql("ALTER TABLE c_tool_intro MODIFY COLUMN session_id int unsigned DEFAULT NULL");
$this->addSql("ALTER TABLE c_tool_intro MODIFY COLUMN session_id int unsigned NOT NULL");
$this->addSql("ALTER TABLE c_tool_intro DROP PRIMARY KEY");
$this->addSql("ALTER TABLE c_tool_intro MODIFY COLUMN session_id int unsigned DEFAULT NULL");
$this->addSql("ALTER TABLE c_tool_intro ADD COLUMN iid int NOT NULL PRIMARY KEY AUTO_INCREMENT");
$this->addSql("ALTER TABLE c_quiz_answer MODIFY COLUMN c_id INT NOT NULL");
$this->addSql("ALTER TABLE c_quiz_answer MODIFY COLUMN id_auto int unsigned DEFAULT NULL");
$this->addSql("ALTER TABLE c_quiz_answer MODIFY COLUMN id_auto int unsigned NOT NULL");
$this->addSql("ALTER TABLE c_quiz_answer DROP PRIMARY KEY");
$this->addSql("ALTER TABLE c_quiz_answer MODIFY COLUMN id_auto int unsigned DEFAULT NULL");
$this->addSql("ALTER TABLE c_quiz_answer ADD COLUMN iid int NOT NULL PRIMARY KEY AUTO_INCREMENT");
$this->addSql("ALTER TABLE c_quiz_question_rel_category MODIFY COLUMN c_id INT NOT NULL");
$this->addSql("ALTER TABLE c_quiz_question_rel_category MODIFY COLUMN question_id int unsigned DEFAULT NULL");
$this->addSql("ALTER TABLE c_quiz_question_rel_category MODIFY COLUMN question_id int unsigned NOT NULL");
$this->addSql("ALTER TABLE c_quiz_question_rel_category DROP PRIMARY KEY");
$this->addSql("ALTER TABLE c_quiz_question_rel_category MODIFY COLUMN question_id int unsigned DEFAULT NULL");
$this->addSql("ALTER TABLE c_quiz_question_rel_category ADD COLUMN iid int NOT NULL PRIMARY KEY AUTO_INCREMENT");
$this->addSql("ALTER TABLE session_rel_user MODIFY COLUMN id_session int");
@ -403,50 +422,56 @@ class Version110 extends AbstractMigrationChamilo
$this->addSql("ALTER TABLE course_rel_user CHANGE tutor_id is_tutor int");
$this->addSql("ALTER TABLE c_quiz_rel_question MODIFY COLUMN c_id INT NOT NULL");
$this->addSql("ALTER TABLE c_quiz_rel_question DROP PRIMARY KEY");
$this->addSql("ALTER TABLE c_quiz_rel_question MODIFY COLUMN question_id int unsigned DEFAULT NULL");
$this->addSql("ALTER TABLE c_quiz_rel_question MODIFY COLUMN exercice_id int unsigned DEFAULT NULL");
$this->addSql("ALTER TABLE c_quiz_rel_question DROP PRIMARY KEY");
$this->addSql("ALTER TABLE c_quiz_rel_question ADD COLUMN iid int NOT NULL PRIMARY KEY AUTO_INCREMENT");
$this->addSql("ALTER TABLE c_role MODIFY COLUMN role_id int unsigned DEFAULT NULL");
$this->addSql("ALTER TABLE c_role MODIFY COLUMN role_id int unsigned NOT NULL");
$this->addSql("ALTER TABLE c_role MODIFY COLUMN c_id INT NOT NULL");
$this->addSql("ALTER TABLE c_role DROP PRIMARY KEY");
$this->addSql("ALTER TABLE c_role MODIFY COLUMN role_id int unsigned DEFAULT NULL");
$this->addSql("ALTER TABLE c_role ADD COLUMN iid int NOT NULL PRIMARY KEY AUTO_INCREMENT");
$this->addSql("ALTER TABLE c_role_user DROP PRIMARY KEY");
$this->addSql("ALTER TABLE c_role_user MODIFY COLUMN role_id int unsigned DEFAULT NULL");
$this->addSql("ALTER TABLE c_role_user MODIFY COLUMN user_id int unsigned DEFAULT NULL");
$this->addSql("ALTER TABLE c_role_user MODIFY COLUMN c_id INT NOT NULL");
$this->addSql("ALTER TABLE c_role_user DROP PRIMARY KEY");
$this->addSql("ALTER TABLE c_role_user ADD COLUMN iid int NOT NULL PRIMARY KEY AUTO_INCREMENT");
$this->addSql("ALTER TABLE c_survey MODIFY COLUMN survey_id int NULL");
$this->addSql("ALTER TABLE c_survey MODIFY COLUMN survey_id int NOT NULL");
$this->addSql("ALTER TABLE c_survey MODIFY COLUMN c_id INT NOT NULL");
$this->addSql("ALTER TABLE c_survey DROP PRIMARY KEY");
$this->addSql("ALTER TABLE c_survey MODIFY COLUMN survey_id int NULL");
$this->addSql("ALTER TABLE c_survey ADD COLUMN iid int NOT NULL PRIMARY KEY AUTO_INCREMENT");
$this->addSql("ALTER TABLE c_survey_answer MODIFY COLUMN answer_id int unsigned DEFAULT NULL");
$this->addSql("ALTER TABLE c_survey_answer MODIFY COLUMN answer_id int unsigned NOT NULL");
$this->addSql("ALTER TABLE c_survey_answer MODIFY COLUMN c_id INT NOT NULL");
$this->addSql("ALTER TABLE c_survey_answer DROP PRIMARY KEY");
$this->addSql("ALTER TABLE c_survey_answer MODIFY COLUMN answer_id int unsigned DEFAULT NULL");
$this->addSql("ALTER TABLE c_survey_answer ADD COLUMN iid int NOT NULL PRIMARY KEY AUTO_INCREMENT");
$this->addSql("ALTER TABLE c_survey_invitation MODIFY COLUMN survey_invitation_id int unsigned DEFAULT NULL");
$this->addSql("ALTER TABLE c_survey_invitation MODIFY COLUMN survey_invitation_id int unsigned NOT NULL");
$this->addSql("ALTER TABLE c_survey_invitation MODIFY COLUMN c_id INT NOT NULL");
$this->addSql("ALTER TABLE c_survey_invitation DROP PRIMARY KEY");
$this->addSql("ALTER TABLE c_survey_invitation MODIFY COLUMN survey_invitation_id int unsigned DEFAULT NULL");
$this->addSql("ALTER TABLE c_survey_invitation ADD COLUMN iid int NOT NULL PRIMARY KEY AUTO_INCREMENT");
$this->addSql("ALTER TABLE c_survey_question MODIFY COLUMN question_id int unsigned DEFAULT NULL");
$this->addSql("ALTER TABLE c_survey_question MODIFY COLUMN question_id int unsigned NOT NULL");
$this->addSql("ALTER TABLE c_survey_question MODIFY COLUMN c_id INT NOT NULL");
$this->addSql("ALTER TABLE c_survey_question DROP PRIMARY KEY");
$this->addSql("ALTER TABLE c_survey_question MODIFY COLUMN question_id int unsigned DEFAULT NULL");
$this->addSql("ALTER TABLE c_survey_question ADD COLUMN iid int NOT NULL PRIMARY KEY AUTO_INCREMENT");
$this->addSql("ALTER TABLE c_survey_question_option MODIFY COLUMN question_option_id int unsigned DEFAULT NULL");
$this->addSql("ALTER TABLE c_survey_question_option MODIFY COLUMN question_option_id int unsigned NOT NULL");
$this->addSql("ALTER TABLE c_survey_question_option MODIFY COLUMN c_id INT NOT NULL");
$this->addSql("ALTER TABLE c_survey_question_option DROP PRIMARY KEY");
$this->addSql("ALTER TABLE c_survey_question_option MODIFY COLUMN question_option_id int unsigned DEFAULT NULL");
$this->addSql("ALTER TABLE c_survey_question_option ADD COLUMN iid int NOT NULL PRIMARY KEY AUTO_INCREMENT");
$this->addSql("ALTER TABLE c_wiki_conf DROP PRIMARY KEY");
$this->addSql("ALTER TABLE c_wiki_conf MODIFY COLUMN page_id int unsigned DEFAULT NULL");
$this->addSql("ALTER TABLE c_wiki_conf MODIFY COLUMN c_id INT NOT NULL");
$this->addSql("ALTER TABLE c_wiki_conf DROP PRIMARY KEY");
$this->addSql("ALTER TABLE c_wiki_conf ADD COLUMN iid int NOT NULL PRIMARY KEY AUTO_INCREMENT");
// Course

@ -1931,17 +1931,29 @@ div.admin_section h4 {
.ribbon .success {
color: green;
}
.exercise_save_now_button img {
position: relative;
top: 4px;
}
.exercise_save_now_button {
margin-top:10px;
padding-left: 25px;
}
.exercise_save_now_button, .exercise_button{
/* padding:5px; */
.exercise_save_now_button .checkbox input[type="checkbox"]{
margin-left: -25px;
}
.question-check-test{
padding-left: 35px;
margin-bottom: 35px;
}
.question-check-test label{
font-weight: normal;
}
.question-check-test .checkbox input[type="checkbox"]{
margin-left: -25px;
}
.form-actions{
margin-top: 20px;
margin-bottom: 25px;
}
/* Exercise clock*/
.count_down{
@ -3980,6 +3992,9 @@ i.size-32.icon-new-work{
display:block;
width: 100%;
}
.actions #groups .bootstrap-select{
width: 300px;
}
ul.holder{
list-style: none;
margin: 0;
@ -5202,7 +5217,7 @@ div#chat-remote-video video {
border-radius: 5px;
-moz-border-radius: 5px;
-webkit-border-radius: 5px;
min-height: 320px;
min-height: 330px;
margin-bottom: 10px;
}
.items-course .items-course-info .title{

@ -1,3 +1,4 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
@ -48,34 +49,129 @@
<a name="1.10.6"></a>
<h1>Chamilo 1.10.6 - ???, ?? of April 2016</h1>
<h1>Chamilo 1.10.6 - ???, ?? 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>
<p><a href="http://www.openstreetmap.org/node/1947201#map=14/51.3786/-2.3580">NNNh</a> .....</p>
<h3>Security fixes</h3>
<ul>
<li>None that we know of.</li>
</ul>
<p>None that we know of.</p>
<h3>Possibly breaking changes</h3>
<ul>
<li>None that we know of.</li>
</ul>
<p>None that we know of.</p>
<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/34e9b7442d2c4114ec6fb3d52477b249344117bc">34e9b744</a>) Add svg edit 2.8.1 as is.</li>
<li>(<a href="https://github.com/chamilo/chamilo-lms/commit/0ea0a859c58de592b14759c1541ad7cefc87a462">0ea0a859</a> - <a href="https://support.chamilo.org/issues/8233">#8233</a>) Load ckeditor js plugin only when user is logged on</li>
<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 new exercise option: 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"</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 to platform admin manage all sessions</li>
<li>(<a href="https://github.com/chamilo/chamilo-lms/commit/652538011f33cb4ebef14455adfbbd30f0b704cf">65253801</a> - <a href="https://support.chamilo.org/issues/8156">#8156</a>) Fix login with Facebook</li>
<li>(<a href="https://github.com/chamilo/chamilo-lms/commit/f1db277f1ac8565266006ceba4309710af1d8d6d">f1db277f</a> - <a href="https://support.chamilo.org/issues/8156">#8156</a>) Fix logout with facebook</li>
<li>(<a href="https://github.com/chamilo/chamilo-lms/commit/06c15644a8f091b74470e0bdedfcdbe2faf5342d">06c15644</a> - <a href="https://task.beeznest.com/issues/11073">BT#11073</a>) Add Classes to Reporting fields</li>
<li>(<a href="https://github.com/chamilo/chamilo-lms/commit/391cc31bd185dec1cdd701eea07a190ee2854dde">391cc31b</a>) Add new option to $_configuration['courses_list_session_title_link']</li>
<li>(<a href="https://github.com/chamilo/chamilo-lms/commit/10729dea98234918de3e7e8c8718503ba5e2efbd">10729dea</a> - <a href="https://task.beeznest.com/issues/10952">BT#10952</a>) Add multiple attachment in agenda</li>
<li>(<a href="https://github.com/chamilo/chamilo-lms/commit/940fbdd51c97e6feecebbd156130ba8818d98ad8">940fbdd5</a> - <a href="https://task.beeznest.com/issues/10052">BT#10052</a>) Adding setting "exercise_enable_category_order"</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 BT#10052</li>
</ul>
<h4>For developers and sysadmins</h4>
<ul>
<li>(<a href="https://github.com/chamilo/chamilo-lms/commit/7b00cc61c2ececae41c4b38b8bdc28fd4a28cd1e">7b00cc61</a> - <a href="https://support.chamilo.org/issues/8218">#8218</a>) Require PHPWord</li>
<li>(<a href="https://github.com/chamilo/chamilo-lms/commit/1826f23d58b1ab280219fd45c420d13f06d8eb9c">1826f23d</a> - <a href="https://support.chamilo.org/issues/8218">#8218</a>) Remove phpdocx library</li>
<li>(<a href="https://github.com/chamilo/chamilo-lms/commit/91ebd4677be9f6ebd7965dd3d84cd3cb3ece50b4">91ebd467</a> - <a href="https://support.chamilo.org/issues/8225">#8225</a>) Add section about PHP limits to optimization guide</li>
<li>(<a href="https://github.com/chamilo/chamilo-lms/commit/761be6d5a6f43a4e3340a7d6383f06404b6a3270">761be6d5</a>) Add Behat test for reply/delete/quote a forum message</li>
<li>(<a href="https://github.com/chamilo/chamilo-lms/commit/d9b490b537d1188a61f57f62f5ed3482b3b65c52">d9b490b5</a> - <a href="https://support.chamilo.org/issues/8200">#8200</a>) Add sql_mode = '' to avoid errors in php 5.7</li>
<li>(<a href="https://github.com/chamilo/chamilo-lms/commit/7b82a178a2059ca4784d66419ad8887d0745a5a0">7b82a178</a> - <a href="https://task.beeznest.com/issues/11005">BT#11005</a>) Save track_e_course_access before removing the session information</li>
<li>(<a href="https://github.com/chamilo/chamilo-lms/commit/12c7e7eccbf933ccf29306dcb720972792a9f8f2">12c7e7ec</a> - <a href="https://support.chamilo.org/issues/8175">#8175</a>) Use custom CKEditor</li>
</ul>
<h3>Improvements (minor features) and debug</h3>
<ul>
<li>(<a href="https://github.com/chamilo/chamilo-lms/commit/0907a64acdf89143cb1aeec8fd3e76f54476e466">0907a64a</a>) Update "upgraded from versions"</li>
<li>(<a href="https://github.com/chamilo/chamilo-lms/commit/2e64b949bdf7cf00f02a2688817d4936d3d8b247">2e64b949</a> - <a href="https://task.beeznest.com/issues/8236">BT#8236</a>) Use latest version of svgedit see #8236</li>
<li>(<a href="https://github.com/chamilo/chamilo-lms/commit/b472658a4379cae03dcda44ae028e87a6b6b28c3">b472658a</a>) Remove E_NOTICE on installer when no connection</li>
<li>(<a href="https://github.com/chamilo/chamilo-lms/commit/ec3e41c584aacc88d00362ed1a0ad2b08988ab73">ec3e41c5</a> - <a href="https://support.chamilo.org/issues/8232">#8232</a>) Fix get_course_extra_field_value and subscribe_user2course.php</li>
<li>(<a href="https://github.com/chamilo/chamilo-lms/commit/c39a86fb1c89e86a7229206a6d3ac4a13187545f">c39a86fb</a> - <a href="https://support.chamilo.org/issues/8233">#8233</a>) Fix Load ckeditor js plugin only when user is logged on</li>
<li>(<a href="https://github.com/chamilo/chamilo-lms/commit/ec93280321de6938faf3bc0f6f14090196e8e60c">ec932803</a> - <a href="https://support.chamilo.org/issues/8210">#8210</a>) Remove unused file</li>
<li>(<a href="https://github.com/chamilo/chamilo-lms/commit/c312f5a1ada22229451f231770247e2ea90ba068">c312f5a1</a> - <a href="https://task.beeznest.com/issues/11195">BT#11195</a>) Add student boss in user_edit.php and user_information see BT#11195</li>
<li>(<a href="https://github.com/chamilo/chamilo-lms/commit/52e3a414bfc9cc387679e1882fbd10bd317b19ab">52e3a414</a> - <a href="https://support.chamilo.org/issues/8218">#8218</a>) Fix export gradebook results to docx</li>
<li>(<a href="https://github.com/chamilo/chamilo-lms/commit/e79d2fc2bf9cd0702abdf64555c75da3f1dc8373">e79d2fc2</a> - <a href="https://support.chamilo.org/issues/8200">#8200</a>) Revert "Fix issue setting PRIMARY KEY to possible NULL in migration from 1.9 to 1.10</li>
<li>(<a href="https://github.com/chamilo/chamilo-lms/commit/3b3cbc97fde6ee1286661b3fa626fbb37ccf6c44">3b3cbc97</a> - <a href="https://task.beeznest.com/issues/11148">BT#11148</a>) Fix exercise creation</li>
<li>(<a href="https://github.com/chamilo/chamilo-lms/commit/181e18546f528cfa747396387cdac187db3ed551">181e1854</a> - <a href="https://task.beeznest.com/issues/11148">BT#11148</a>) Fix return session list when coach start date is null</li>
<li>(<a href="https://github.com/chamilo/chamilo-lms/commit/e4239dd983fac3ef9092aaa53779cc0f0b56bfec">e4239dd9</a>) Add CSS theme for Holi indian festival, contribution by official provider contidosdixitais.com</li>
<li>(<a href="https://github.com/chamilo/chamilo-lms/commit/f35ec7b874a19e4529b71fbb532c5408dbedf784">f35ec7b8</a> - <a href="https://support.chamilo.org/issues/8203">#8203</a>) Fix style break for the floating header in attendances list</li>
<li>(<a href="https://github.com/chamilo/chamilo-lms/commit/a32a3a251bd9b0a806f7671507fce0b07833a271">a32a3a25</a>) Add validateCourseSetting function to show/hide course plugin settings.</li>
<li>(<a href="https://github.com/chamilo/chamilo-lms/commit/c88a5e9ea16027daeef1e6588b1beb2af63e8d99">c88a5e9e</a>) Fix infocourse when using checkbox</li>
<li>(<a href="https://github.com/chamilo/chamilo-lms/commit/123d3dc396ec9a1069bd6b32790ca25d3f9e0992">123d3dc3</a>) Remove the api_is_plugin_installedfunction because not used</li>
<li>(<a href="https://github.com/chamilo/chamilo-lms/commit/92218a89a43e1e08a2fa5a999377e60842cfcf93">92218a89</a> - <a href="https://task.beeznest.com/issues/11014">BT#11014</a>) Add link in group_space if tool is enabled + group setting is on. BT#11014</li>
<li>(<a href="https://github.com/chamilo/chamilo-lms/commit/0111ccbc6b3aff96fac56cf64fe209d035f655a8">0111ccbc</a>) Update function api_get_cidreq typos</li>
<li>(<a href="https://github.com/chamilo/chamilo-lms/commit/911a81e0201b648ef39756c24794ace8d61d6e46">911a81e0</a> - <a href="https://support.chamilo.org/issues/8218">#8218</a>) Fix table when exporting gradebook tool to PDf</li>
<li>(<a href="https://github.com/chamilo/chamilo-lms/commit/45a64220ef6839ae79f584ba5ca58422b2d84a89">45a64220</a> - <a href="https://support.chamilo.org/issues/8214">#8214</a>) Fix display issue in forum category style when adding an image aligned left</li>
<li>(<a href="https://github.com/chamilo/chamilo-lms/commit/621fefae922bef53a35adcfc9847d4d9c2a67d3f">621fefae</a> - <a href="https://task.beeznest.com/issues/11014">BT#11014</a>) WIP: Add group conference support</li>
<li>(<a href="https://github.com/chamilo/chamilo-lms/commit/a47b7ace6005e4817a027af8ec34d38c24f6dc88">a47b7ace</a> - <a href="https://task.beeznest.com/issues/11157">BT#11157</a>) WIP: Add global conference support</li>
<li>(<a href="https://github.com/chamilo/chamilo-lms/commit/f2fc062700f91d0715e88a6330c695c5a9c6334c">f2fc0627</a> - <a href="https://support.chamilo.org/issues/8218">#8218</a>) Fix generate data for flatview in gradebook</li>
<li>(<a href="https://github.com/chamilo/chamilo-lms/commit/b603d25e4357430b8e0f6878c2cc4272ebd30f0b">b603d25e</a>) Fix plugin creation/update add Database::tableExists function</li>
<li>(<a href="https://github.com/chamilo/chamilo-lms/commit/f8e8ec98a2d070558139197fd49b1f6a59a608c8">f8e8ec98</a>) Fix twig view for user_portal</li>
<li>(<a href="https://github.com/chamilo/chamilo-lms/commit/9a71abb7faab51e902d23aa0ba95a98b0dc3ba16">9a71abb7</a> - <a href="https://support.chamilo.org/issues/8219">#8219</a>) Fix custom plugin icons in course when they are disabled on course home page</li>
<li>(<a href="https://github.com/chamilo/chamilo-lms/commit/440ee1831e3324e72e855e2916b5a1c412855803">440ee183</a> - <a href="https://support.chamilo.org/issues/8212">#8212</a>) Fix AsciiMath on learning paths</li>
<li>(<a href="https://github.com/chamilo/chamilo-lms/commit/70c7ef3799973aeada684f7c016c71d9a28e1e2f">70c7ef37</a> - <a href="https://support.chamilo.org/issues/8200">#8200</a>) Fix issue setting PRIMARY KEY to possible NULL in migration from 1.9 to 1.10</li>
<li>(<a href="https://github.com/chamilo/chamilo-lms/commit/4c5f4c80f90b9c6e5d9c902f443b4c9aa1eadfe6">4c5f4c80</a>) Use id selectors for buttons in forum tool</li>
<li>(<a href="https://github.com/chamilo/chamilo-lms/commit/b402c0f3f116ae35512aa8eeb6a3f422cfcc7fdb">b402c0f3</a> - <a href="https://support.chamilo.org/issues/8221">#8221</a>) Fix auth/inscription.php url</li>
<li>(<a href="https://github.com/chamilo/chamilo-lms/commit/00ff6fe1d2125ae1320cd6e171f08947de716414">00ff6fe1</a>) Set post_parent_id field in c_forum_post to null instead of 0</li>
<li>(<a href="https://github.com/chamilo/chamilo-lms/commit/7158ee4186b8cf2b884b0415d55e7608eeaf15f5">7158ee41</a>) Revert "Fix thread creation"</li>
<li>(<a href="https://github.com/chamilo/chamilo-lms/commit/870291c28dac13bce55945822ad4584479330a62">870291c2</a>) Fix size of input blank width reducing when you are writing in the ckeditor</li>
<li>(<a href="https://github.com/chamilo/chamilo-lms/commit/ab9ee71f5a9dcb66c5fd22b4ecc2af2c0638af82">ab9ee71f</a>) Fix HTTPS inclusion of HTTP resources in documentation</li>
<li>(<a href="https://github.com/chamilo/chamilo-lms/commit/1e2f740042432206f502e9d8091da443d6fa9991">1e2f7400</a>) Fix form to create forum thread + fix its behat test</li>
<li>(<a href="https://github.com/chamilo/chamilo-lms/commit/1324e42ec2cf2aea612870e1e60574e586f41b50">1324e42e</a>) Fix HTTPS inclusion of HTTP resources in documentation</li>
<li>(<a href="https://github.com/chamilo/chamilo-lms/commit/8dc508bda4caeb72e078c864511c127b2652285c">8dc508bd</a> - <a href="https://support.chamilo.org/issues/8183">#8183</a>) Fix bug when you set a value in in score field it show the default value if you editing it</li>
<li>(<a href="https://github.com/chamilo/chamilo-lms/commit/3eec0c93af0514172ab7a0c1225dc7d46263a262">3eec0c93</a>) Add Behat feature to test forum tool as a platform admin</li>
<li>(<a href="https://github.com/chamilo/chamilo-lms/commit/d30235711163af546b45cc91f978ed5addd85acf">d3023571</a> - <a href="https://support.chamilo.org/issues/8177">#8177</a>) Add number validators</li>
<li>(<a href="https://github.com/chamilo/chamilo-lms/commit/ab8df6b2cde25511fe119567684bb62482c58b98">ab8df6b2</a> - <a href="https://support.chamilo.org/issues/8191">#8191</a>) Added My Certificates link in dropdown user menu</li>
<li>(<a href="https://github.com/chamilo/chamilo-lms/commit/97c0d24a2cdd6f78da5c9731c406884296d2feaa">97c0d24a</a> - <a href="https://support.chamilo.org/issues/8200">#8200</a>) Fix migration using the group idd instead of group id in c_item_property</li>
<li>(<a href="https://github.com/chamilo/chamilo-lms/commit/4a3e2c04f008dd8532159b8d74f32a136b1b8707">4a3e2c04</a> - <a href="https://support.chamilo.org/issues/8176">#8176</a>) Fix fatal error see #8176</li>
<li>(<a href="https://github.com/chamilo/chamilo-lms/commit/5aaa2d297106e5b8af8c5fedf8f207e5d99a9015">5aaa2d29</a>) Fix SCORM creation</li>
<li>(<a href="https://github.com/chamilo/chamilo-lms/commit/3d9ba22f9e55e191659b3d48b16fdf05a6eabbff">3d9ba22f</a>) Add ignoring language updates in packaging script</li>
<li>(<a href="https://github.com/chamilo/chamilo-lms/commit/c5b4291d7868ddeea74ea2e04da27b18686c04c5">c5b4291d</a> - <a href="https://support.chamilo.org/issues/8196">#8196</a>) Fix userID reference in getJoinMeetingURL() for BBB plugin</li>
<li>(<a href="https://github.com/chamilo/chamilo-lms/commit/1d609c992d91c45dd5995e0e5fde6b5d29714529">1d609c99</a> - <a href="https://task.beeznest.com/issues/11141">BT#11141</a>) Fix allow delete session to platform admin when he is different of session_admin_id</li>
<li>(<a href="https://github.com/chamilo/chamilo-lms/commit/eaeadc65c19b1bd24a5e765e2d5baafbf096b728">eaeadc65</a> - <a href="https://support.chamilo.org/issues/8207">#8207</a>) Fix Nginx rewrite example for issued badges page</li>
<li>(<a href="https://github.com/chamilo/chamilo-lms/commit/f1c94b89ed228cdab048a60cd7bbfe751b4ae1ff">f1c94b89</a> - <a href="https://support.chamilo.org/issues/8200">#8200</a>) Fix mirations for extra fields</li>
<li>(<a href="https://github.com/chamilo/chamilo-lms/commit/35dcc6ca980e1be18b3060f5c5af95a0b67ef8e3">35dcc6ca</a> - <a href="https://support.chamilo.org/issues/8154">#8154</a>) Fix announcement email attachment</li>
<li>(<a href="https://github.com/chamilo/chamilo-lms/commit/bc8e0a49b8da0f20d5886b4c74cb8dee48cbee5e">bc8e0a49</a>) Fix thread creation</li>
<li>(<a href="https://github.com/chamilo/chamilo-lms/commit/aa21c8774ae673d8f43cfc3f5c8b91b68f7fec1f">aa21c877</a> - <a href="https://support.chamilo.org/issues/8214">#8214</a>) Fix forum HTML description</li>
<li>(<a href="https://github.com/chamilo/chamilo-lms/commit/23ef568c5130f78df9eb3596565333230f26a48c">23ef568c</a> - <a href="https://task.beeznest.com/issues/11021">BT#11021</a>) Fix LP view on ecf16fb</li>
<li>(<a href="https://github.com/chamilo/chamilo-lms/commit/289550f8c6339787716d5b2d8217db644d71e551">289550f8</a> - <a href="https://task.beeznest.com/issues/10674">BT#10674</a>) Adding extldap message</li>
<li>(<a href="https://github.com/chamilo/chamilo-lms/commit/4ae0f135e3575bd1405108cb42c45df5ef0808d6">4ae0f135</a> - <a href="https://support.chamilo.org/issues/8200">#8200</a>) Remove c_item_property if group doesn't exist</li>
<li>(<a href="https://github.com/chamilo/chamilo-lms/commit/48dd825326ce9a80e6331599d589510851a6e4d6">48dd8253</a>) Set htmleditor instead of textarea for works tool</li>
<li>(<a href="https://github.com/chamilo/chamilo-lms/commit/8465ef5e7a5deb8c070049f485328c1ea488c7ad">8465ef5e</a>) Fix class constructor of FormValidator's checkbox</li>
<li>(<a href="https://github.com/chamilo/chamilo-lms/commit/0e6d9a208d521a09b318432271f15d05c6f14472">0e6d9a20</a>) Remove DocumentConverter.java.orig file because not used</li>
<li>(<a href="https://github.com/chamilo/chamilo-lms/commit/f3982ca0ac258fc7379fde551f66a04178b3ddfb">f3982ca0</a>) Fix queries when inserting event's track_e_uploads and work tables</li>
<li>(<a href="https://github.com/chamilo/chamilo-lms/commit/acc912da7769ead11258cdc6f7e549963837a3aa">acc912da</a>) Fix default values</li>
<li>(<a href="https://github.com/chamilo/chamilo-lms/commit/915749b26f6563a3002bef09928c19d7555198ba">915749b2</a> - <a href="https://task.beeznest.com/issues/11048">BT#11048</a>) Fix language issue in certificate page at the end of learning paths</li>
<li>(<a href="https://github.com/chamilo/chamilo-lms/commit/4c93468b27de33f0352dffcdf8730c1c86b4dc20">4c93468b</a> - <a href="https://support.chamilo.org/issues/11048">#11048</a>) Fix LPFinalItem to hide for the position list</li>
<li>(<a href="https://github.com/chamilo/chamilo-lms/commit/b3ef9036fc15697401d5f9dc1ab1b0bb26f43b2e">b3ef9036</a> - <a href="https://task.beeznest.com/issues/11048">BT#11048</a>) Fix generation of last item page with certificates and badges in learning path</li>
<li>(<a href="https://github.com/chamilo/chamilo-lms/commit/f701abf01c25a85b54a58ca20dc0641ba29a272b">f701abf0</a> - <a href="https://task.beeznest.com/issues/11048">BT#11048</a>) Fix condition to generate skills so it doesn't depend on certificates</li>
<li>(<a href="https://github.com/chamilo/chamilo-lms/commit/81e1d972386985d050caadb9c6ed405bc3bd5cf3">81e1d972</a> - <a href="https://task.beeznest.com/issues/7683">BT#7683</a>) fix link unsubscribe social BT#7683</li>
<li>(<a href="https://github.com/chamilo/chamilo-lms/commit/c36a9c308818ea77e7d89846e1305c8392576244">c36a9c30</a>) Add info to README about upgrading Chamilo to Git-based from a package-based installation</li>
<li>(<a href="https://github.com/chamilo/chamilo-lms/commit/77f9c3e46ef8da29aae396ec7dae4f96812a941b">77f9c3e4</a> - <a href="https://support.chamilo.org/issues/8205">#8205</a>) Fix wrong session_rel_user.duration bug</li>
<li>(<a href="https://github.com/chamilo/chamilo-lms/commit/ce3ab0c51a02a27d4a49848a6a541eaf2eb63025">ce3ab0c5</a> - <a href="https://task.beeznest.com/issues/8205">BT#8205</a>) Adding session_rel_user.duration validation</li>
<li>(<a href="https://github.com/chamilo/chamilo-lms/commit/1e092a112a96a6f8b7c0ca4bbb24bb2002f1b874">1e092a11</a>) Fix LP Final Item show finished page to 100%</li>
<li>(<a href="https://github.com/chamilo/chamilo-lms/commit/54f1ccc787b52cc0b9234aba9a36bdf47b4e5c56">54f1ccc7</a> - <a href="https://task.beeznest.com/issues/11048">BT#11048</a>) Remove useless JS code added in previous commit</li>
<li>(<a href="https://github.com/chamilo/chamilo-lms/commit/658fb16d414a3c4ea7b0aca5e9a7d64f5ff811a6">658fb16d</a> - <a href="https://task.beeznest.com/issues/11048">BT#11048</a>) Move code block placed in the wrong condition in previous commit - Fix twitter:site meta not appearing in badges page</li>
<li>(<a href="https://github.com/chamilo/chamilo-lms/commit/960a90abaa140578528eceb6687f20fded07df8e">960a90ab</a> - <a href="https://task.beeznest.com/issues/11048">BT#11048</a>) Add social share buttons to issued badge page</li>
<li>(<a href="https://github.com/chamilo/chamilo-lms/commit/aeb1521fb73efbf63aef08ee4fa4e6c9c1092436">aeb1521f</a> - <a href="https://task.beeznest.com/issues/11108">BT#11108</a>) Fix access to users list for admins: allow platform admin to enter open courses (visibility 2). There was apparently a condition allowing admins to enter all courses but the ones open to the platform - loosely refs BT#11108</li>
<li>(<a href="https://github.com/chamilo/chamilo-lms/commit/9554dbf76feac837d6f34ca2fc7ae4842edc497d">9554dbf7</a> - <a href="https://support.chamilo.org/issues/10992">#10992</a>) Fix Twitter:card conflict with OpenGraph meta in user badge page</li>
<li>(<a href="https://github.com/chamilo/chamilo-lms/commit/c49934ae80a9e86765a78ee0ca2f0d4974e0f031">c49934ae</a>) Remove unused database.sql file.</li>
<li>(<a href="https://github.com/chamilo/chamilo-lms/commit/c44bfa0b5c73cb4fa8a891ccfb066ed9e6dae341">c44bfa0b</a> - <a href="https://support.chamilo.org/issues/8200">#8200</a>) Clean c_item_property of courses that don't exist</li>
<li>(<a href="https://github.com/chamilo/chamilo-lms/commit/82dce71bf5b427b123a77da806096e3b90fc5bec">82dce71b</a> - <a href="https://support.chamilo.org/issues/8201">#8201</a>) Fix missing lib on installer</li>
<li>(<a href="https://github.com/chamilo/chamilo-lms/commit/30648a5154d2e3b31217ef8baeaccd722ddff36e">30648a51</a> - <a href="https://task.beeznest.com/issues/8200">BT#8200</a>) Adding hasColumn conditions for migration</li>
<li>(<a href="https://github.com/chamilo/chamilo-lms/commit/9c952de7420ccfc484277f956d14904b20ae2402">9c952de7</a>) Show course description when course_catalog_hide_private is false</li>
<li>(<a href="https://github.com/chamilo/chamilo-lms/commit/ff8290cb87eced2991d8919fa086eeba5a2fb304">ff8290cb</a>) Fix table name</li>
<li>(<a href="https://github.com/chamilo/chamilo-lms/commit/5d85e2a36f71b74c2b72e05c86b451b119ff641a">5d85e2a3</a> - <a href="https://support.chamilo.org/issues/8194">#8194</a>) Add required rules when editon custom icon on course homepage</li>
<li>(<a href="https://github.com/chamilo/chamilo-lms/commit/91150cfe5cbf061de682d3dd581bd049950d02dc">91150cfe</a> - <a href="https://support.chamilo.org/issues/8194">#8194</a>) Fix translation for custom icon on course homepage</li>
<li>(<a href="https://github.com/chamilo/chamilo-lms/commit/26639296e83eb1c630c35bd431130ec2f9b4a69b">26639296</a>) Fix mail content format.</li>
<li>(<a href="https://github.com/chamilo/chamilo-lms/commit/ae30908e756132c07e050b8411fb65cfc6a9725b">ae30908e</a> - <a href="https://task.beeznest.com/issues/11067">BT#11067</a>) Fix email format - add nl2br</li>
<li>(<a href="https://github.com/chamilo/chamilo-lms/commit/046ca86376979d423407d96a9fe46c21d1739a49">046ca863</a>) Finalización Archivement</li>
<li>(<a href="https://github.com/chamilo/chamilo-lms/commit/37d5af337e3ea895f6b5b7dec55e9dc4dbecfe2e">37d5af33</a>) Fix forms when adding/editing lp items</li>
<li>(<a href="https://github.com/chamilo/chamilo-lms/commit/36635d142199d3c8e6a5adbfd1b531dbbe85d318">36635d14</a>) Fix URL for create forum in lp</li>
<li>(<a href="https://github.com/chamilo/chamilo-lms/commit/1f0c917fc949132afbc50f070dd2bb3ef25f18a6">1f0c917f</a>) Fix report titles.</li>
@ -89,14 +185,13 @@
<li>(<a href="https://github.com/chamilo/chamilo-lms/commit/f34bae386d81c613c11411c921d81e7d9656cfd0">f34bae38</a> - <a href="https://support.chamilo.org/issues/8188">#8188</a>) Fix menu tabs (broken in 1.10.4)</li>
<li>(<a href="https://github.com/chamilo/chamilo-lms/commit/88b3acf7002421f9e7c60b1619d507bfd15c9d9d">88b3acf7</a> - <a href="https://support.chamilo.org/issues/8185">#8185</a>) Update bower assets</li>
<li>(<a href="https://github.com/chamilo/chamilo-lms/commit/cede17daf3925bfe56b108476dfb33140023d164">cede17da</a>) Use 1 setting instead of 2</li>
<li>(<a href="https://github.com/chamilo/chamilo-lms/commit/7f42c3251a15e3b91bc114fdd3db5ec8cb6dc04f">7f42c325</a>) Use __construct</li>
<li>(<a href="https://github.com/chamilo/chamilo-lms/commit/997288805472841bbfc3bf3caedf996f1db0acba">99728880</a> - <a href="https://support.chamilo.org/issues/8157">#8157</a>) Replace mysql with pdo_mysql extension</li>
<li>(<a href="https://github.com/chamilo/chamilo-lms/commit/c002d1e8f752b14e111e43ee65926eba37e558f7">c002d1e8</a>) Fix fatal error.</li>
<li>(<a href="https://github.com/chamilo/chamilo-lms/commit/c002d1e8f752b14e111e43ee65926eba37e558f7">c002d1e8</a>) Fix fatal error on blog tool.</li>
<li>(<a href="https://github.com/chamilo/chamilo-lms/commit/64f6ccf359425a726f4be99df86c371ad59e9c16">64f6ccf3</a> - <a href="https://task.beeznest.com/issues/11021">BT#11021</a>) Remove button for download video file in lp</li>
<li>(<a href="https://github.com/chamilo/chamilo-lms/commit/380db06ab13e4524247999e92cb4065aeaf12ef1">380db06a</a> - <a href="https://task.beeznest.com/issues/11021">BT#11021</a>) Fix template for jplayer viewer</li>
<li>(<a href="https://github.com/chamilo/chamilo-lms/commit/ecf16fb37b0e14bd54ec624bf6055925f8d26366">ecf16fb3</a> - <a href="https://task.beeznest.com/issues/11021">BT#11021</a>) Show lp video items in iframe</li>
<li>(<a href="https://github.com/chamilo/chamilo-lms/commit/615a1224e97b16a510a65b1f9fe389f74aec011c">615a1224</a> - <a href="https://task.beeznest.com/issues/10936">BT#10936</a>) Set user id from function</li>
<li>(<a href="https://github.com/chamilo/chamilo-lms/commit/a231628dc85d72a6728c6b2a3360d8c94011817e">a231628d</a> - <a href="https://task.beeznest.com/issues/10936">BT#10936</a>) Fix fatal error</li>
<li>(<a href="https://github.com/chamilo/chamilo-lms/commit/a231628dc85d72a6728c6b2a3360d8c94011817e">a231628d</a> - <a href="https://task.beeznest.com/issues/10936">BT#10936</a>) Fix fatal error when using a web service </li>
<li>(<a href="https://github.com/chamilo/chamilo-lms/commit/db12470781fa479ed7c25d0a61af62eda07cb2af">db124707</a> - <a href="https://task.beeznest.com/issues/10936">BT#10936</a>) Fix fatal error</li>
<li>(<a href="https://github.com/chamilo/chamilo-lms/commit/8f864966c9bc725047b09270e21db891399fb1ab">8f864966</a> - <a href="https://support.chamilo.org/issues/8173">#8173</a>) Fix Renaming a document in upload document's form</li>
<li>(<a href="https://github.com/chamilo/chamilo-lms/commit/8f652341004346d57558183aa9f9134a97a58339">8f652341</a>) Fix select bootstrap overflow visible</li>

@ -7,6 +7,8 @@
use \ChamiloSession as Session;
define('CHAMILO_HOMEPAGE', true);
// Avoid loading CKeditor lib on homepage (very heavy lib)
define('CHAMILO_LOAD_WYSIWYG', false);
/* Flag forcing the 'current course' reset, as we're not inside a course anymore. */
// Maybe we should change this into an api function? an example: CourseManager::unset();

@ -99,6 +99,7 @@ function handle_extensions()
echo '<a class="btn btn-success" href="configure_extensions.php?display=ppt2lp" role="button">'.get_lang('Ppt2lp').'</a>';
}
/**
* This function allows easy activating and inactivating of plugins
* @todo: a similar function needs to be written to activate or inactivate additional tools.
@ -231,12 +232,28 @@ function handle_stylesheets()
'post',
'settings.php?category=Stylesheets#tabs-3'
);
$form->addElement('text', 'name_stylesheet', get_lang('NameStylesheet'), array('size' => '40', 'maxlength' => '40'));
$form->addElement('text', 'name_stylesheet', get_lang('NameStylesheet'),
array('size' => '40', 'maxlength' => '40'));
$form->addRule('name_stylesheet', get_lang('ThisFieldIsRequired'), 'required');
$form->addElement('file', 'new_stylesheet', get_lang('UploadNewStylesheet'));
$allowed_file_types = array('css', 'zip', 'jpeg', 'jpg', 'png', 'gif', 'ico', 'psd', 'xcf', 'svg', 'webp', 'woff', 'woff2');
$allowed_file_types = array(
'css',
'zip',
'jpeg',
'jpg',
'png',
'gif',
'ico',
'psd',
'xcf',
'svg',
'webp',
'woff',
'woff2'
);
$form->addRule('new_stylesheet', get_lang('InvalidExtension').' ('.implode(',', $allowed_file_types).')', 'filetype', $allowed_file_types);
$form->addRule('new_stylesheet', get_lang('InvalidExtension') . ' (' . implode(',', $allowed_file_types) . ')',
'filetype', $allowed_file_types);
$form->addRule('new_stylesheet', get_lang('ThisFieldIsRequired'), 'required');
$form->addButtonUpload(get_lang('Upload'), 'stylesheet_upload');
@ -553,8 +570,9 @@ function upload_stylesheet($values, $picture)
$extraction_path = $cssToUpload.$style_name.'/';
for ($i = 0; $i < $num_files; $i++) {
$entry = $zip->getNameIndex($i);
if (substr($entry, -1) == '/')
if (substr($entry, -1) == '/') {
continue;
}
$pos_slash = strpos($entry, '/');
$entry_without_first_dir = substr($entry, $pos_slash + 1);
@ -875,7 +893,8 @@ function handle_search()
* @version August 2008
* @since Dokeos 1.8.6
*/
function handle_templates() {
function handle_templates()
{
/* Drive-by fix to avoid undefined var warnings, without repeating
* isset() combos all over the place. */
$action = isset($_GET['action']) ? $_GET['action'] : "invalid";
@ -947,7 +966,8 @@ function display_templates()
* @version August 2008
* @since Dokeos 1.8.6
*/
function get_number_of_templates() {
function get_number_of_templates()
{
// Database table definition.
$table_system_template = Database :: get_main_table('system_template');
@ -973,7 +993,8 @@ function get_number_of_templates() {
* @version August 2008
* @since Dokeos 1.8.6
*/
function get_template_data($from, $number_of_items, $column, $direction) {
function get_template_data($from, $number_of_items, $column, $direction)
{
// Database table definition.
$table_system_template = Database :: get_main_table('system_template');
@ -995,7 +1016,7 @@ function get_template_data($from, $number_of_items, $column, $direction) {
* display the edit and delete icons in the sortable table
*
* @param integer $id the id of the template
* @return html code for the link to edit and delete the template
* @return string code for the link to edit and delete the template
*
* @author Patrick Cool <patrick.cool@UGent.be>, Ghent University, Belgium
* @version August 2008
@ -1011,13 +1032,14 @@ function actions_filter($id) {
* Display the image of the template in the sortable table
*
* @param string $image the image
* @return html code for the image
* @return string code for the image
*
* @author Patrick Cool <patrick.cool@UGent.be>, Ghent University, Belgium
* @version August 2008
* @since Dokeos 1.8.6
*/
function image_filter($image) {
function image_filter($image)
{
if (!empty($image)) {
return '<img src="'.api_get_path(WEB_APP_PATH).'home/default_platform_document/template_thumb/'.$image.'" alt="'.get_lang('TemplatePreview').'"/>';
} else {
@ -1033,7 +1055,8 @@ function image_filter($image) {
* @version August 2008
* @since Dokeos 1.8.6
*/
function add_edit_template() {
function add_edit_template()
{
// Initialize the object.
$id = isset($_GET['id']) ? '&id='.Security::remove_XSS($_GET['id']) : '';
$form = new FormValidator('template', 'post', 'settings.php?category=Templates&action='.Security::remove_XSS($_GET['action']).$id);
@ -1076,9 +1099,11 @@ function add_edit_template() {
// Adding an extra field: a preview of the image that is currently used.
if (!empty($row['image'])) {
$form->addElement('static', 'template_image_preview', '', '<img src="'.api_get_path(WEB_APP_PATH).'home/default_platform_document/template_thumb/'.$row['image'].'" alt="'.get_lang('TemplatePreview').'"/>');
$form->addElement('static', 'template_image_preview', '',
'<img src="' . api_get_path(WEB_APP_PATH) . 'home/default_platform_document/template_thumb/' . $row['image'] . '" alt="' . get_lang('TemplatePreview') . '"/>');
} else {
$form->addElement('static', 'template_image_preview', '', '<img src="'.api_get_path(WEB_APP_PATH).'home/default_platform_document/template_thumb/noimage.gif" alt="'.get_lang('NoTemplatePreview').'"/>');
$form->addElement('static', 'template_image_preview', '',
'<img src="' . api_get_path(WEB_APP_PATH) . 'home/default_platform_document/template_thumb/noimage.gif" alt="' . get_lang('NoTemplatePreview') . '"/>');
}
// Setting the information of the template that we are editing.
@ -1175,7 +1200,8 @@ function add_edit_template() {
* @version August 2008
* @since Dokeos 1.8.6
*/
function delete_template($id) {
function delete_template($id)
{
// First we remove the image.
$table_system_template = Database :: get_main_table('system_template');
$sql = "SELECT * FROM $table_system_template WHERE id = ".intval($id)."";
@ -1201,7 +1227,8 @@ function delete_template($id) {
* @author Guillaume Viguier <guillaume.viguier@beeznest.com>
* @since Chamilo 1.8.7
*/
function select_timezone_value() {
function select_timezone_value()
{
return api_get_timezones();
}
@ -1216,7 +1243,8 @@ function select_gradebook_number_decimals() {
return array('0', '1', '2');
}
function select_gradebook_default_grade_model_id() {
function select_gradebook_default_grade_model_id()
{
$grade_model = new GradeModel();
$models = $grade_model->get_all();
$options = array();
@ -1237,7 +1265,8 @@ function select_gradebook_default_grade_model_id() {
*
* @author Guillaume Viguier <guillaume.viguier@beeznest.com>
*/
function update_gradebook_score_display_custom_values($values) {
function update_gradebook_score_display_custom_values($values)
{
$scoredisplay = ScoreDisplay::instance();
$scores = $values['gradebook_score_display_custom_values_endscore'];
$displays = $values['gradebook_score_display_custom_values_displaytext'];
@ -1260,7 +1289,8 @@ function generate_settings_form($settings, $settings_by_access_list)
$form = new FormValidator('settings', 'post', 'settings.php?category='.Security::remove_XSS($_GET['category']));
$form->addElement('hidden', 'search_field', (!empty($_GET['search_field'])?Security::remove_XSS($_GET['search_field']):null));
$form->addElement('hidden', 'search_field',
(!empty($_GET['search_field']) ? Security::remove_XSS($_GET['search_field']) : null));
$url_id = api_get_current_access_url_id();
@ -1320,17 +1350,21 @@ function generate_settings_form($settings, $settings_by_access_list)
$hideme = array('disabled');
} elseif ($url_info['active'] == 1) {
// We show the elements.
if (empty($row['variable']))
if (empty($row['variable'])) {
$row['variable'] = 0;
if (empty($row['subkey']))
}
if (empty($row['subkey'])) {
$row['subkey'] = 0;
if (empty($row['category']))
}
if (empty($row['category'])) {
$row['category'] = 0;
}
if (is_array($settings_by_access_list[ $row['variable'] ] [ $row['subkey'] ] [ $row['category'] ])) {
// We are sure that the other site have a selected value.
if ($settings_by_access_list[ $row['variable'] ] [ $row['subkey'] ] [ $row['category'] ]['selected_value'] != '')
if ($settings_by_access_list[$row['variable']] [$row['subkey']] [$row['category']]['selected_value'] != '') {
$row['selected_value'] = $settings_by_access_list[$row['variable']] [$row['subkey']] [$row['category']]['selected_value'];
}
}
// There is no else{} statement because we load the default $row['selected_value'] of the main Chamilo site.
}
@ -1493,7 +1527,8 @@ function generate_settings_form($settings, $settings_by_access_list)
);
break;
case 'link':
$form->addElement('static', null, array(get_lang($row['title']), get_lang($row['comment'])), get_lang('CurrentValue').' : '.$row['selected_value'], $hideme);
$form->addElement('static', null, array(get_lang($row['title']), get_lang($row['comment'])),
get_lang('CurrentValue') . ' : ' . $row['selected_value'], $hideme);
break;
case 'select':
/*

@ -16,19 +16,19 @@ $report = isset($_REQUEST['report']) ? $_REQUEST['report'] : '';
if ($report) {
$htmlHeadXtra[] = api_get_js('chartjs/Chart.min.js');
$htmlHeadXtra[] = ''
. '<script type="text/javascript">'
. '$(document).ready(function() {'
. '$.ajax({'
. 'url: "'. api_get_path(WEB_CODE_PATH) .'inc/ajax/statistics.ajax.php?a=recentlogins",'
. 'type: "POST",'
. 'success: function(data) {'
. 'Chart.defaults.global.responsive = true;'
. 'var myLine = new Chart(document.getElementById("canvas").getContext("2d")).Line(data);'
. '}'
. '});'
. '});'
. '</script>';
$htmlHeadXtra[] = '
<script>
$(document).ready(function() {
$.ajax({
url: "'. api_get_path(WEB_CODE_PATH) .'inc/ajax/statistics.ajax.php?a=recentlogins",
type: "POST",
success: function(data) {
Chart.defaults.global.responsive = true;
var myLine = new Chart(document.getElementById("canvas").getContext("2d")).Line(data);
}
});
});
</script>';
}
$tool_name = get_lang('Statistics');

@ -12,14 +12,14 @@ $this_section = SECTION_PLATFORM_ADMIN;
api_protect_admin_script();
/**
* MAIN CODE
* MAIN CODE
*/
// setting the name of the tool
$tool_name = get_lang('CreateSubLanguage');
// setting breadcrumbs
$interbreadcrumb[] = array ('url' => 'index.php', 'name' => get_lang('PlatformAdmin'));
$interbreadcrumb[] = array ('url' => 'languages.php', 'name' => get_lang('PlatformLanguages'));
$interbreadcrumb[] = array('url' => 'index.php', 'name' => get_lang('PlatformAdmin'));
$interbreadcrumb[] = array('url' => 'languages.php', 'name' => get_lang('PlatformLanguages'));
/**
* Add sub-language
@ -28,18 +28,19 @@ $interbreadcrumb[] = array ('url' => 'languages.php', 'name' => get_lang('Platfo
* @param string ISO code (fr_FR, ...)
* @param int Whether the sublanguage is published (0=unpublished, 1=published)
* @param int ID del idioma padre
* @return int New sub language ID or false on error
* @return false|string New sub language ID or false on error
*/
function add_sub_language ($original_name,$english_name,$isocode,$sublanguage_available,$parent_id) {
$tbl_admin_languages = Database :: get_main_table(TABLE_MAIN_LANGUAGE);
$original_name = Database::escape_string($original_name);
$english_name = Database::escape_string($english_name);
$isocode = Database::escape_string($isocode);
$sublanguage_available = Database::escape_string($sublanguage_available);
$parent_id = intval($parent_id);
$sql = 'INSERT INTO '.$tbl_admin_languages.'(original_name,english_name,isocode,dokeos_folder,available,parent_id)
VALUES ("'.$original_name.'","'.$english_name.'","'.$isocode.'","'.$english_name.'","'.$sublanguage_available.'","'.$parent_id.'")';
function add_sub_language($original_name, $english_name, $isocode, $sublanguage_available, $parent_id)
{
$tbl_admin_languages = Database:: get_main_table(TABLE_MAIN_LANGUAGE);
$original_name = Database::escape_string($original_name);
$english_name = Database::escape_string($english_name);
$isocode = Database::escape_string($isocode);
$sublanguage_available = Database::escape_string($sublanguage_available);
$parent_id = intval($parent_id);
$sql = 'INSERT INTO ' . $tbl_admin_languages . '(original_name,english_name,isocode,dokeos_folder,available,parent_id)
VALUES ("' . $original_name . '","' . $english_name . '","' . $isocode . '","' . $english_name . '","' . $sublanguage_available . '","' . $parent_id . '")';
$res = Database::query($sql);
if ($res === false) {
return false;
@ -61,44 +62,45 @@ function add_sub_language ($original_name,$english_name,$isocode,$sublanguage_av
* @todo This function is not transaction-safe and should probably be included
* inside the add_sub_language function.
*/
function check_if_language_exist ($original_name, $english_name, $isocode, $sublanguage_available) {
$tbl_admin_languages = Database :: get_main_table(TABLE_MAIN_LANGUAGE);
$sql_original_name='SELECT count(*) AS count_original_name FROM '.$tbl_admin_languages.' WHERE original_name="'.Database::escape_string($original_name).'" ';
$sql_english_name='SELECT count(*) AS count_english_name FROM '.$tbl_admin_languages.' WHERE english_name="'.Database::escape_string($english_name).'" ';
//$sql_isocode='SELECT count(*) AS count_isocode FROM '.$tbl_admin_languages.' WHERE isocode="'.Database::escape_string($isocode).'" ';
$rs_original_name=Database::query($sql_original_name);
$rs_english_name=Database::query($sql_english_name);
//$rs_isocode=Database::query($sql_isocode);
$count_original_name=Database::result($rs_original_name,0,'count_original_name');
$count_english_name=Database::result($rs_english_name,0,'count_english_name');
//$count_isocode=Database::result($rs_isocode,0,'count_isocode');
$has_error=false;
$message_information=array();
if ($count_original_name==1) {
$has_error=true;
$message_information['original_name']=true;
}
if ($count_english_name==1) {
$has_error=true;
$message_information['english_name']=true;
}
$iso_list = api_get_platform_isocodes();
$iso_list = array_values($iso_list);
if (!in_array($isocode, $iso_list)) {
$has_error=true;
$message_information['isocode']=true;
}
if ($has_error===true) {
$message_information['execute_add']=false;
}
if ($has_error===false) {
$message_information['execute_add']=true;
}
return $message_information;
function check_if_language_exist($original_name, $english_name, $isocode, $sublanguage_available)
{
$tbl_admin_languages = Database:: get_main_table(TABLE_MAIN_LANGUAGE);
$sql_original_name = 'SELECT count(*) AS count_original_name FROM ' . $tbl_admin_languages . ' WHERE original_name="' . Database::escape_string($original_name) . '" ';
$sql_english_name = 'SELECT count(*) AS count_english_name FROM ' . $tbl_admin_languages . ' WHERE english_name="' . Database::escape_string($english_name) . '" ';
//$sql_isocode='SELECT count(*) AS count_isocode FROM '.$tbl_admin_languages.' WHERE isocode="'.Database::escape_string($isocode).'" ';
$rs_original_name = Database::query($sql_original_name);
$rs_english_name = Database::query($sql_english_name);
//$rs_isocode=Database::query($sql_isocode);
$count_original_name = Database::result($rs_original_name, 0, 'count_original_name');
$count_english_name = Database::result($rs_english_name, 0, 'count_english_name');
//$count_isocode=Database::result($rs_isocode,0,'count_isocode');
$has_error = false;
$message_information = array();
if ($count_original_name == 1) {
$has_error = true;
$message_information['original_name'] = true;
}
if ($count_english_name == 1) {
$has_error = true;
$message_information['english_name'] = true;
}
$iso_list = api_get_platform_isocodes();
$iso_list = array_values($iso_list);
if (!in_array($isocode, $iso_list)) {
$has_error = true;
$message_information['isocode'] = true;
}
if ($has_error === true) {
$message_information['execute_add'] = false;
}
if ($has_error === false) {
$message_information['execute_add'] = true;
}
return $message_information;
}
/**
@ -108,193 +110,204 @@ function check_if_language_exist ($original_name, $english_name, $isocode, $subl
* @return bool
* @todo deprecate this function and use the static method directly
*/
function check_if_exist_language_by_id ($language_id) {
return SubLanguageManager::check_if_exist_language_by_id($language_id);
function check_if_exist_language_by_id($language_id)
{
return SubLanguageManager::check_if_exist_language_by_id($language_id);
}
/**
* Check if the given language is a parent of any sub-language
* @param int Language ID of the presumed parent
* @return bool True if this language has children, false otherwise
*/
function ckeck_if_is_parent_of_sub_language ($parent_id) {
$sql='SELECT count(*) AS count FROM language WHERE parent_id= '.intval($parent_id).'';
$rs=Database::query($sql);
if (Database::num_rows($rs)>0 && Database::result($rs,0,'count')==1) {
return true;
} else {
return false;
}
function ckeck_if_is_parent_of_sub_language($parent_id)
{
$sql = 'SELECT count(*) AS count FROM language WHERE parent_id= ' . intval($parent_id) . '';
$rs = Database::query($sql);
if (Database::num_rows($rs) > 0 && Database::result($rs, 0, 'count') == 1) {
return true;
} else {
return false;
}
}
/**
* Get all information of sub-language
* @param int Parent language ID
* @param int Child language ID
* @return array
*/
function allow_get_all_information_of_sub_language ($parent_id,$sub_language_id) {
return SubLanguageManager::get_all_information_of_sub_language($parent_id,$sub_language_id);
function allow_get_all_information_of_sub_language($parent_id, $sub_language_id)
{
return SubLanguageManager::get_all_information_of_sub_language($parent_id, $sub_language_id);
}
/*end declare functions*/
//add data
if (isset($_GET['sub_language_id']) && $_GET['sub_language_id']==strval(intval($_GET['sub_language_id']))) {
$language_name=SubLanguageManager::get_name_of_language_by_id($_GET['sub_language_id']);
if (check_if_exist_language_by_id ($_GET['sub_language_id'])===true) {
$sub_language_id=$_GET['sub_language_id'];
$sub_language_id_exist=true;
} else {
$sub_language_id_exist=false;
}
if (isset($_GET['sub_language_id']) && $_GET['sub_language_id'] == strval(intval($_GET['sub_language_id']))) {
$language_name = SubLanguageManager::get_name_of_language_by_id($_GET['sub_language_id']);
if (check_if_exist_language_by_id($_GET['sub_language_id']) === true) {
$sub_language_id = $_GET['sub_language_id'];
$sub_language_id_exist = true;
} else {
$sub_language_id_exist = false;
}
}
$language_details = array();
$language_name='';
if (isset($_GET['id']) && $_GET['id']==strval(intval($_GET['id']))) {
$language_details = SubLanguageManager::get_all_information_of_language($_GET['id']);
$language_name = $language_details['original_name'];
if (check_if_exist_language_by_id ($_GET['id'])===true) {
$parent_id=$_GET['id'];
$language_id_exist=true;
} else {
$language_id_exist=false;
}
$language_name = '';
if (isset($_GET['id']) && $_GET['id'] == strval(intval($_GET['id']))) {
$language_details = SubLanguageManager::get_all_information_of_language($_GET['id']);
$language_name = $language_details['original_name'];
if (check_if_exist_language_by_id($_GET['id']) === true) {
$parent_id = $_GET['id'];
$language_id_exist = true;
} else {
$language_id_exist = false;
}
} else {
$language_id_exist=false;
$language_id_exist = false;
}
//removed and register
if ((isset($_GET['id']) && $_GET['id']==strval(intval($_GET['id']))) && (isset($_GET['sub_language_id']) && $_GET['sub_language_id']==strval(intval($_GET['sub_language_id'])))) {
if (check_if_exist_language_by_id($_GET['id'])===true && check_if_exist_language_by_id($_GET['sub_language_id'])===true) {
$get_all_information=allow_get_all_information_of_sub_language ($_GET['id'],$_GET['sub_language_id']);
$original_name=$get_all_information['original_name'];
$english_name=$get_all_information['english_name'];
$isocode=$get_all_information['isocode'];
if ((isset($_GET['id']) && $_GET['id'] == strval(intval($_GET['id']))) && (isset($_GET['sub_language_id']) && $_GET['sub_language_id'] == strval(intval($_GET['sub_language_id'])))) {
if (check_if_exist_language_by_id($_GET['id']) === true && check_if_exist_language_by_id($_GET['sub_language_id']) === true) {
$get_all_information = allow_get_all_information_of_sub_language($_GET['id'], $_GET['sub_language_id']);
$original_name = $get_all_information['original_name'];
$english_name = $get_all_information['english_name'];
$isocode = $get_all_information['isocode'];
}
}
}
$language_name=get_lang('CreateSubLanguageForLanguage').' ( '.strtolower($language_name).' )';
$language_name = get_lang('CreateSubLanguageForLanguage') . ' ( ' . strtolower($language_name) . ' )';
if (ckeck_if_is_parent_of_sub_language($parent_id)===true && isset($_GET['action']) && $_GET['action']=='deletesublanguage') {
$language_name=get_lang('DeleteSubLanguage');
if (ckeck_if_is_parent_of_sub_language($parent_id) === true && isset($_GET['action']) && $_GET['action'] == 'deletesublanguage') {
$language_name = get_lang('DeleteSubLanguage');
}
$msg = '';
if (isset($_POST['SubmitAddNewLanguage'])) {
$original_name=$_POST['original_name'];
$english_name=$_POST['english_name'];
$isocode=$_POST['isocode'];
$english_name=str_replace(' ','_',$english_name);
$isocode=str_replace(' ','_',$isocode);
$sublanguage_available=$_POST['sub_language_is_visible'];
$check_information=array();
$check_information=check_if_language_exist($original_name,$english_name,$isocode,$sublanguage_available);
foreach ($check_information as $index_information => $value_information) {
$allow_insert_info=false;
if ($index_information=='original_name') {
$msg .= Display::return_message(get_lang('AlreadyExists').' "'.get_lang('OriginalName').'" '.'('.$original_name.')','error');
}
if ($index_information=='english_name') {
$msg .= Display::return_message(get_lang('AlreadyExists').' "'.get_lang('EnglishName').'" '.'('.$english_name.')','error');
}
if ($index_information=='isocode') {
$msg .= Display::return_message(get_lang('CodeDoesNotExists').': '.$isocode.'','error');
}
if ($index_information=='execute_add' && $value_information===true) {
$allow_insert_info=true;
}
}
if (strlen($original_name)>0 && strlen($english_name)>0 && strlen($isocode)>0) {
if ($allow_insert_info===true && $language_id_exist===true) {
$english_name=str_replace(' ','_',$english_name);
//Fixes BT#1636
$english_name=api_strtolower($english_name);
$isocode=str_replace(' ','_',$isocode);
$str_info='<br/>'.get_lang('OriginalName').' : '.$original_name.'<br/>'.get_lang('EnglishName').' : '.$english_name.'<br/>'.get_lang('PlatformCharsetTitle').' : '.$isocode;
$mkdir_result=SubLanguageManager::add_language_directory($english_name);
if ($mkdir_result) {
$sl_id = add_sub_language($original_name,$english_name,$isocode,$sublanguage_available,$parent_id);
if ($sl_id === false) {
SubLanguageManager::remove_language_directory($english_name);
$msg .= Display::return_message(get_lang('LanguageDirectoryNotWriteableContactAdmin'),'error');
} else {
// Here we build the confirmation message and we send the user to the sub language terms definition page, using a little hack - see #3712
$_SESSION['msg'] = Display::return_message(get_lang('TheNewSubLanguageHasBeenAdded').$str_info.'confirm',false);
unset($interbreadcrumb);
$_GET['sub_language_id'] = $_REQUEST['sub_language_id'] = $sl_id;
require 'sub_language.php';
exit();
}
} else {
$msg .= Display::return_message(get_lang('LanguageDirectoryNotWriteableContactAdmin'),'error');
}
} else {
if ($language_id_exist===false) {
$msg .= Display::return_message(get_lang('LanguageParentNotExist'),'error');
}
}
} else {
$msg .= Display::return_message(get_lang('FormHasErrorsPleaseComplete'),'error');
}
$original_name = $_POST['original_name'];
$english_name = $_POST['english_name'];
$isocode = $_POST['isocode'];
$english_name = str_replace(' ', '_', $english_name);
$isocode = str_replace(' ', '_', $isocode);
$sublanguage_available = $_POST['sub_language_is_visible'];
$check_information = array();
$check_information = check_if_language_exist($original_name, $english_name, $isocode, $sublanguage_available);
foreach ($check_information as $index_information => $value_information) {
$allow_insert_info = false;
if ($index_information == 'original_name') {
$msg .= Display::return_message(get_lang('AlreadyExists') . ' "' . get_lang('OriginalName') . '" ' . '(' . $original_name . ')',
'error');
}
if ($index_information == 'english_name') {
$msg .= Display::return_message(get_lang('AlreadyExists') . ' "' . get_lang('EnglishName') . '" ' . '(' . $english_name . ')',
'error');
}
if ($index_information == 'isocode') {
$msg .= Display::return_message(get_lang('CodeDoesNotExists') . ': ' . $isocode . '', 'error');
}
if ($index_information == 'execute_add' && $value_information === true) {
$allow_insert_info = true;
}
}
if (strlen($original_name) > 0 && strlen($english_name) > 0 && strlen($isocode) > 0) {
if ($allow_insert_info === true && $language_id_exist === true) {
$english_name = str_replace(' ', '_', $english_name);
//Fixes BT#1636
$english_name = api_strtolower($english_name);
$isocode = str_replace(' ', '_', $isocode);
$str_info = '<br/>' . get_lang('OriginalName') . ' : ' . $original_name . '<br/>' . get_lang('EnglishName') . ' : ' . $english_name . '<br/>' . get_lang('PlatformCharsetTitle') . ' : ' . $isocode;
$mkdir_result = SubLanguageManager::add_language_directory($english_name);
if ($mkdir_result) {
$sl_id = add_sub_language($original_name, $english_name, $isocode, $sublanguage_available, $parent_id);
if ($sl_id === false) {
SubLanguageManager::remove_language_directory($english_name);
$msg .= Display::return_message(get_lang('LanguageDirectoryNotWriteableContactAdmin'), 'error');
} else {
// Here we build the confirmation message and we send the user to the sub language terms definition page, using a little hack - see #3712
$_SESSION['msg'] = Display::return_message(get_lang('TheNewSubLanguageHasBeenAdded') . $str_info . 'confirm',
false);
unset($interbreadcrumb);
$_GET['sub_language_id'] = $_REQUEST['sub_language_id'] = $sl_id;
require 'sub_language.php';
exit();
}
} else {
$msg .= Display::return_message(get_lang('LanguageDirectoryNotWriteableContactAdmin'), 'error');
}
} else {
if ($language_id_exist === false) {
$msg .= Display::return_message(get_lang('LanguageParentNotExist'), 'error');
}
}
} else {
$msg .= Display::return_message(get_lang('FormHasErrorsPleaseComplete'), 'error');
}
}
Display :: display_header($language_name);
Display:: display_header($language_name);
echo $msg;
if (isset($_POST['SubmitAddDeleteLanguage'])) {
$rs = SubLanguageManager::remove_sub_language($_GET['id'], $_GET['sub_language_id']);
if ($rs===true) {
Display::display_confirmation_message(get_lang('TheSubLanguageHasBeenRemoved'));
} else {
Display::display_error_message(get_lang('TheSubLanguageHasNotBeenRemoved'));
}
$rs = SubLanguageManager::remove_sub_language($_GET['id'], $_GET['sub_language_id']);
if ($rs === true) {
Display::display_confirmation_message(get_lang('TheSubLanguageHasBeenRemoved'));
} else {
Display::display_error_message(get_lang('TheSubLanguageHasNotBeenRemoved'));
}
}
// ckeck_if_is_parent_of_sub_language($parent_id)===false
//
if (isset($_GET['action']) && $_GET['action']=='definenewsublanguage') {
$text = $language_name;
$form = new FormValidator('addsublanguage', 'post', 'sub_language_add.php?id='.Security::remove_XSS($_GET['id']).'&action=definenewsublanguage');
$class='add';
$form->addElement('header', '', $text);
$form->addElement('text', 'original_name', get_lang('OriginalName'),'class="input_titles"');
$form->addRule('original_name', get_lang('ThisFieldIsRequired'), 'required');
$form->addElement('text', 'english_name', get_lang('EnglishName'),'class="input_titles"');
$form->addRule('english_name', get_lang('ThisFieldIsRequired'), 'required');
$form->addElement('text', 'isocode', get_lang('ISOCode'), 'class="input_titles"');
$form->addRule('isocode', get_lang('ThisFieldIsRequired'), 'required');
$form->addElement('static', null, '&nbsp;', '<i>en, es, fr</i>');
$form->addElement('checkbox', 'sub_language_is_visible', '', get_lang('Visibility'));
$form->addButtonCreate(get_lang('CreateSubLanguage'), 'SubmitAddNewLanguage');
//$values['original_name'] = $language_details['original_name'].'...'; -> cannot be used because of quickform filtering (freeze)
$values['english_name'] = $language_details['english_name'].'2';
$values['isocode'] = $language_details['isocode'];
$form->setDefaults($values);
$form->display();
if (isset($_GET['action']) && $_GET['action'] == 'definenewsublanguage') {
$text = $language_name;
$form = new FormValidator('addsublanguage', 'post',
'sub_language_add.php?id=' . Security::remove_XSS($_GET['id']) . '&action=definenewsublanguage');
$class = 'add';
$form->addElement('header', '', $text);
$form->addElement('text', 'original_name', get_lang('OriginalName'), 'class="input_titles"');
$form->addRule('original_name', get_lang('ThisFieldIsRequired'), 'required');
$form->addElement('text', 'english_name', get_lang('EnglishName'), 'class="input_titles"');
$form->addRule('english_name', get_lang('ThisFieldIsRequired'), 'required');
$form->addElement('text', 'isocode', get_lang('ISOCode'), 'class="input_titles"');
$form->addRule('isocode', get_lang('ThisFieldIsRequired'), 'required');
$form->addElement('static', null, '&nbsp;', '<i>en, es, fr</i>');
$form->addElement('checkbox', 'sub_language_is_visible', '', get_lang('Visibility'));
$form->addButtonCreate(get_lang('CreateSubLanguage'), 'SubmitAddNewLanguage');
//$values['original_name'] = $language_details['original_name'].'...'; -> cannot be used because of quickform filtering (freeze)
$values['english_name'] = $language_details['english_name'] . '2';
$values['isocode'] = $language_details['isocode'];
$form->setDefaults($values);
$form->display();
} else {
if (isset($_GET['action']) && $_GET['action']=='deletesublanguage') {
$text=$language_name;
$form = new FormValidator('deletesublanguage', 'post', 'sub_language_add.php?id='.Security::remove_XSS($_GET['id']).'&sub_language_id='.Security::remove_XSS($_GET['sub_language_id']));
$class='minus';
$form->addElement('header', '', $text);
$form->addElement('static', '', get_lang('OriginalName'),$original_name);
$form->addElement('static', '', get_lang('EnglishName'),$english_name);
$form->addElement('static', '', get_lang('PlatformCharsetTitle'),$isocode);
$form->addButtonCreate(get_lang('DeleteSubLanguage'), 'SubmitAddDeleteLanguage');
$form->display();
}
if (isset($_GET['action']) && $_GET['action']=='definenewsublanguage') {
Display::display_normal_message(get_lang('TheSubLanguageForThisLanguageHasBeenAdded'));
}
if (isset($_GET['action']) && $_GET['action'] == 'deletesublanguage') {
$text = $language_name;
$form = new FormValidator('deletesublanguage', 'post',
'sub_language_add.php?id=' . Security::remove_XSS($_GET['id']) . '&sub_language_id=' . Security::remove_XSS($_GET['sub_language_id']));
$class = 'minus';
$form->addElement('header', '', $text);
$form->addElement('static', '', get_lang('OriginalName'), $original_name);
$form->addElement('static', '', get_lang('EnglishName'), $english_name);
$form->addElement('static', '', get_lang('PlatformCharsetTitle'), $isocode);
$form->addButtonCreate(get_lang('DeleteSubLanguage'), 'SubmitAddDeleteLanguage');
$form->display();
}
if (isset($_GET['action']) && $_GET['action'] == 'definenewsublanguage') {
Display::display_normal_message(get_lang('TheSubLanguageForThisLanguageHasBeenAdded'));
}
}
/**
* Footer
*/
Display :: display_footer();
Display:: display_footer();

@ -6,7 +6,7 @@
*/
$cidReset = true;
require '../inc/global.inc.php';
require_once '../inc/global.inc.php';
// Set this option to true to enforce strict purification for usenames.
$purification_option_for_usernames = false;

@ -58,7 +58,7 @@ if (api_is_platform_admin()) {
),
api_get_path(WEB_PATH).'main/social/vcard_export.php?userId='.$userId
);
}
// Show info about who created this user and when
@ -381,7 +381,6 @@ if (api_is_multiple_url_enabled()) {
}
}
$studentBossList = UserManager::getStudentBossList($userId);
$studentBossListToString = '';
if ($studentBossList) {
@ -391,7 +390,7 @@ if ($studentBossList) {
$row = 1;
foreach ($studentBossList as $studentBossId) {
$studentBoss = api_get_user_info($studentBossId);
$studentBoss = api_get_user_info($studentBossId['boss_id']);
$table->setCellContents($row, 0, $studentBoss['complete_name_with_username']);
$csvContent[] = array($studentBoss['complete_name_with_username']);
$row++;
@ -404,21 +403,28 @@ $message = null;
if (isset($_GET['action'])) {
switch ($_GET['action']) {
case 'unsubscribe':
if (CourseManager::get_user_in_course_status($_GET['user_id'], $_GET['course_code']) == STUDENT) {
CourseManager::unsubscribe_user($_GET['user_id'], $_GET['course_code'], $_GET['id_session']);
$userId = empty($_GET['user_id']) ? 0 : intval($_GET['user_id']);
$courseCode = empty($_GET['course_code']) ? '' : intval($_GET['course_code']);
$sessionId = empty($_GET['id_session']) ? 0 : intval($_GET['id_session']);
if (CourseManager::get_user_in_course_status($userId, $courseCode) == STUDENT) {
CourseManager::unsubscribe_user($userId, $courseCode, $sessionId);
$message = Display::return_message(get_lang('UserUnsubscribed'));
} else {
$message = Display::return_message(
get_lang('CannotUnsubscribeUserFromCourse'),
'error'
'error',
false
);
}
break;
case 'unsubscribeSessionCourse':
$userId = empty($_GET['user_id']) ? 0 : intval($_GET['user_id']);
$courseCode = empty($_GET['course_code']) ? '' : intval($_GET['course_code']);
$sessionId = empty($_GET['id_session']) ? 0 : intval($_GET['id_session']);
SessionManager::removeUsersFromCourseSession(
array($_GET['user_id']),
$_GET['id_session'],
api_get_course_info($_GET['course_code'])
array($userId),
$sessionId,
api_get_course_info($courseCode)
);
$message = Display::return_message(get_lang('UserUnsubscribed'));
break;
@ -454,13 +460,14 @@ $fullUrl = UserManager::getUserPicture(
);
echo '<div class="row">';
echo $message;
echo '<div class="col-md-2">';
echo '<a class="expand-image" href="'.$fullUrlBig.'">'
.'<img src="'.$fullUrl.'" /></a><br />';
echo '</div>';
echo $message;
echo '<div class="col-md-5">';
echo $userInformation;
echo '</div>';

@ -288,7 +288,7 @@ function prepare_user_sql_query($is_count)
* This function defines globals.
* @param int $userId
*
* @return bool False on failure, redirection on success
* @return false|null False on failure, redirection on success
* @author Evie Embrechts
* @author Yannick Warnier <yannick.warnier@dokeos.com>
*/

@ -128,7 +128,7 @@ function complete_missing_data($user)
/**
* Update users from the imported data
* @param array $users List of users
* @return void
* @return false|null
* @uses global variable $inserted_in_course, which returns the list of courses the user was inserted in
*/

@ -85,11 +85,21 @@ $action_links = 'function action_formatter (cellvalue, options, rowObject) {
$(function() {
<?php
// grid definition see the $usergroup>display() function
echo Display::grid_js('usergroups', $url, $columns, $column_model, $extra_params, array(), $action_links, true);
echo Display::grid_js(
'usergroups',
$url,
$columns,
$column_model,
$extra_params,
array(),
$action_links,
true
);
?>
});
</script>
<?php
// Tool introduction
Display::display_introduction_section(get_lang('Classes'));

@ -206,7 +206,7 @@ class AttendanceController
/**
* Restores an attendance entry and fallback to attendances rendering
* @param int $attendanceId
* @param int $attendance_id
*/
public function attendance_restore($attendance_id)
{

@ -5,16 +5,17 @@
* Gets all the info via the ldap module (ldap has to work)
*/
require_once api_get_path(SYS_PATH).'main/auth/cas/cas_var.inc.php';
require_once api_get_path(SYS_PATH).'main/auth/external_login/ldap.inc.php';
require_once api_get_path(SYS_PATH).'main/auth/external_login/functions.inc.php';
require_once api_get_path(SYS_PATH) . 'main/auth/cas/cas_var.inc.php';
require_once api_get_path(SYS_PATH) . 'main/auth/external_login/ldap.inc.php';
require_once api_get_path(SYS_PATH) . 'main/auth/external_login/functions.inc.php';
/**
* @return true if cas is configured
*
**/
function cas_configured() {
global $cas_auth_ver, $cas_auth_server, $cas_auth_port, $cas_auth_uri;
* @return true if cas is configured
*
**/
function cas_configured()
{
global $cas_auth_ver, $cas_auth_server, $cas_auth_port, $cas_auth_uri;
$res = false;
if (!empty($cas_auth_ver) && !empty($cas_auth_server) && !empty($cas_auth_port)) {
$res = true;
@ -24,109 +25,111 @@ function cas_configured() {
}
/**
* checks if the user already get a session
* @return the user login if the user already has a session ,false otherwise
**/
* checks if the user already get a session
* @return the user login if the user already has a session ,false otherwise
**/
function cas_is_authenticated()
{
global $cas_auth_ver, $cas_auth_server, $cas_auth_port, $cas_auth_uri;
global $PHPCAS_CLIENT;
global $logout;
global $cas_auth_ver, $cas_auth_server, $cas_auth_port, $cas_auth_uri;
global $PHPCAS_CLIENT;
global $logout;
if (!cas_configured()) {
return;
}
if (!is_object($PHPCAS_CLIENT)) {
phpCAS::client($cas_auth_ver,$cas_auth_server,$cas_auth_port,$cas_auth_uri);
phpCAS::setNoCasServerValidation();
}
$auth = phpCAS::checkAuthentication();
if ($auth) {
$login= trim(phpCAS::getUser());
/*
Get user attributes. Here are the attributes for crdp platform
sn => name
ENTPersonMailInterne => mail
ENTPersonAlias => login
ENTPersonProfils => profil
givenName => first name
*/
/*$user=phpCAS::getAttributes();
$firstName = trim($user['givenName']);
$lastName = trim($user['sn']);
$login = trim($user['ENTPersonAlias']);
$profil = trim($user['ENTPersonProfils']);
$email = trim($user['ENTPersonMailInterne']);
$satus=5;
switch ($profil){
case 'admin_etab':
$status=3; //Session admin
break;
case 'admin_sie':
$status=3; //Session admin
break;
case 'National_3':
$status=1; // Teacher
break;
case 'National_1':
$status=5; // Student
break;
default:
$status=5; // Student
}*/
if (!$logout){
// get user info from username
$tab_user_info = api_get_user_info($login);
// user found in the chamilo database
if (is_array($tab_user_info)) {
// if option is on we update user automatically from ldap server
if (api_get_setting("update_user_info_cas_with_ldap") == "true") {
if (!is_object($PHPCAS_CLIENT)) {
phpCAS::client($cas_auth_ver, $cas_auth_server, $cas_auth_port, $cas_auth_uri);
phpCAS::setNoCasServerValidation();
}
$auth = phpCAS::checkAuthentication();
if ($auth) {
$login = trim(phpCAS::getUser());
/*
Get user attributes. Here are the attributes for crdp platform
sn => name
ENTPersonMailInterne => mail
ENTPersonAlias => login
ENTPersonProfils => profil
givenName => first name
*/
/*$user=phpCAS::getAttributes();
$firstName = trim($user['givenName']);
$lastName = trim($user['sn']);
$login = trim($user['ENTPersonAlias']);
$profil = trim($user['ENTPersonProfils']);
$email = trim($user['ENTPersonMailInterne']);
$satus=5;
switch ($profil){
case 'admin_etab':
$status=3; //Session admin
break;
case 'admin_sie':
$status=3; //Session admin
break;
case 'National_3':
$status=1; // Teacher
break;
case 'National_1':
$status=5; // Student
break;
default:
$status=5; // Student
}*/
if (!$logout) {
// get user info from username
$tab_user_info = api_get_user_info($login);
// user found in the chamilo database
if (is_array($tab_user_info)) {
// if option is on we update user automatically from ldap server
if (api_get_setting("update_user_info_cas_with_ldap") == "true") {
$ldapuser = extldap_authenticate($login, 'nopass', true);
if ($ldapuser !== false) {
$chamilo_user = extldap_get_chamilo_user($ldapuser);
$chamilo_user['user_id'] = $tab_user_info['user_id'];
$chamilo_user['status'] = $tab_user_info['status'];
UserManager::update_user ($chamilo_user["user_id"], $chamilo_user["firstname"], $chamilo_user["lastname"], $login, null, null, $chamilo_user["email"], $chamilo_user["status"], '', '', '', '', 1, null, 0, null,'') ;
}
}
return $login;
}
// user not found
else {
// if option is on we can ADD user automatically from ldap server or by modify own profil
$user_added = false;
switch (api_get_setting("cas_add_user_activate")) {
case PLATFORM_AUTH_SOURCE :
// user will have to modify firstname, lastname, email in chamilo profil edit
$userdata = get_lang("EditInProfil");
UserManager::create_user($userdata, $userdata, '5', $userdata, $login, 'casplaceholder', '','','','',CAS_AUTH_SOURCE);
$user_added = $login;
break;
case LDAP_AUTH_SOURCE :
// user info are read from ldap connexion
// get user info from ldap server
// user has already been authenticated by CAS
// If user not found in LDAP, user not created
$ldapuser = extldap_authenticate($login, 'nopass', true);
if ($ldapuser !== false) {
$chamilo_user = extldap_get_chamilo_user($ldapuser);
UserManager::update_user($chamilo_user["user_id"], $chamilo_user["firstname"],
$chamilo_user["lastname"], $login, null, null, $chamilo_user["email"],
$chamilo_user["status"], '', '', '', '', 1, null, 0, null, '');
}
}
return $login;
} // user not found
else {
// if option is on we can ADD user automatically from ldap server or by modify own profil
$user_added = false;
switch (api_get_setting("cas_add_user_activate")) {
case PLATFORM_AUTH_SOURCE :
// user will have to modify firstname, lastname, email in chamilo profil edit
$userdata = get_lang("EditInProfil");
UserManager::create_user($userdata, $userdata, '5', $userdata, $login, 'casplaceholder', '', '',
'', '', CAS_AUTH_SOURCE);
$user_added = $login;
break;
case LDAP_AUTH_SOURCE :
// user info are read from ldap connexion
// get user info from ldap server
// user has already been authenticated by CAS
// If user not found in LDAP, user not created
$ldapuser = extldap_authenticate($login, 'nopass', true);
if ($ldapuser !== false) {
$chamilo_user = extldap_get_chamilo_user($ldapuser);
$chamilo_user['username'] = $login;
$chamilo_user['auth_source'] = CAS_AUTH_SOURCE;
$chamilo_uid = external_add_user($chamilo_user);
$user_added = $login;
}
break;
default : break;
}
return $user_added;
}
}
$user_added = $login;
}
break;
default :
break;
}
return $user_added;
}
}
// //If the user is in the dokeos database and we are ,not in a logout request, we upgrade his infomration by ldap
// if (! $logout){
// $user_table = Database::get_main_table(TABLE_MAIN_USER);
@ -148,10 +151,10 @@ function cas_is_authenticated()
//
// }
// }
return $login;
return $login;
} else {
return false;
}
return false;
}
}
/**
@ -163,7 +166,7 @@ function cas_is_authenticated()
*
* @see online_logout()
*/
function cas_logout($uinfo=null, $location=null)
function cas_logout($uinfo = null, $location = null)
{
global $cas_auth_ver, $cas_auth_server, $cas_auth_port, $cas_auth_uri;
global $PHPCAS_CLIENT;
@ -184,14 +187,14 @@ function cas_logout($uinfo=null, $location=null)
*/
function get_cas_direct_URL($in_course_code)
{
return api_get_path(WEB_PATH).'main/auth/cas/logincas.php?firstpage='.$in_course_code;
return api_get_path(WEB_PATH) . 'main/auth/cas/logincas.php?firstpage=' . $in_course_code;
}
function getCASLogoHTML()
{
$out_res = "";
if (api_get_setting("casLogoURL") != "") {
$out_res = "<img src='".api_get_setting("casLogoURL")."' alt='CAS Logo' />";
$out_res = "<img src='" . api_get_setting("casLogoURL") . "' alt='CAS Logo' />";
}
return $out_res;
}

File diff suppressed because it is too large Load Diff

@ -62,7 +62,7 @@ class PGTStorageDB extends PGTStorage
/**
* This method returns the PEAR DB URL to use to connect to the database.
*
* @return a PEAR DB URL
* @return string PEAR DB URL
*
* @private
*/
@ -105,7 +105,7 @@ class PGTStorageDB extends PGTStorage
/**
* This method returns the name of the table where PGT's are stored.
*
* @return the name of a table.
* @return string name of a table.
*
* @private
*/
@ -122,7 +122,7 @@ class PGTStorageDB extends PGTStorage
* This method returns an informational string giving the type of storage
* used by the object (used for debugging purposes).
*
* @return an informational string.
* @return string informational string.
* @public
*/
function getStorageType()
@ -148,7 +148,7 @@ class PGTStorageDB extends PGTStorage
/**
* The class constructor, called by CASClient::SetPGTStorageDB().
*
* @param $cas_parent the CASClient instance that creates the object.
* @param CASClient $cas_parent the CASClient instance that creates the object.
* @param $user the user to access the data with
* @param $password the user's password
* @param $database_type the type of the database hosting the data

@ -98,7 +98,7 @@ class PGTStorageFile extends PGTStorage
* This method returns an informational string giving the type of storage
* used by the object (used for debugging purposes).
*
* @return an informational string.
* @return string informational string.
* @public
*/
function getStorageType()
@ -110,7 +110,7 @@ class PGTStorageFile extends PGTStorage
* This method returns an informational string giving informations on the
* parameters of the storage.(used for debugging purposes).
*
* @return an informational string.
* @return string informational string.
* @public
*/
function getStorageInfo()
@ -125,9 +125,9 @@ class PGTStorageFile extends PGTStorage
/**
* The class constructor, called by CASClient::SetPGTStorageFile().
*
* @param $cas_parent the CASClient instance that creates the object.
* @param $format the format used to store the PGT's (`plain' and `xml' allowed).
* @param $path the path where the PGT's should be stored
* @param CASClient $cas_parent the CASClient instance that creates the object.
* @param string $format the format used to store the PGT's (`plain' and `xml' allowed).
* @param string $path the path where the PGT's should be stored
*
* @public
*/
@ -202,7 +202,7 @@ class PGTStorageFile extends PGTStorage
*
* @param $pgt_iou the PGT iou.
*
* @return a filename
* @return string filename
* @private
*/
function getPGTIouFilename($pgt_iou)
@ -243,7 +243,7 @@ class PGTStorageFile extends PGTStorage
*
* @param $pgt_iou the PGT iou
*
* @return the corresponding PGT, or FALSE on error
* @return false|string corresponding PGT, or FALSE on error
*
* @public
*/

@ -126,7 +126,7 @@ class PGTStorage
/**
* This method returns an error message set by PGTStorage::setErrorMessage().
*
* @return an error message when set by PGTStorage::setErrorMessage(), FALSE
* @return boolean error message when set by PGTStorage::setErrorMessage(), FALSE
* otherwise.
*
* @public
@ -153,7 +153,7 @@ class PGTStorage
/**
* This method tells if the storage has already been intialized.
*
* @return a boolean
* @return boolean boolean
*
* @protected
*/

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

@ -33,6 +33,7 @@ class CoursesController
* render to courses_list view
* @param string action
* @param string confirmation message(optional)
* @param string $action
*/
public function courses_list($action, $message = '')
{
@ -79,7 +80,7 @@ class CoursesController
/**
* It's used for listing courses with categories,
* render to courses_categories view
* @param $action
* @param string $action
* @param string $category_code
* @param string $message
* @param string $error

@ -62,6 +62,7 @@ class AccessToken
* @param string $accessToken
* @param int $expiresAt
* @param string|null machineId
* @param string $machineId
*/
public function __construct($accessToken, $expiresAt = 0, $machineId = null)
{
@ -97,7 +98,7 @@ class AccessToken
/**
* Getter for machineId.
*
* @return string|null
* @return string
*/
public function getMachineId()
{
@ -191,11 +192,11 @@ class AccessToken
/**
* Get a valid code from an access token.
*
* @param AccessToken|string $accessToken
* @param AccessToken $accessToken
* @param string|null $appId
* @param string|null $appSecret
*
* @return AccessToken
* @return string
*/
public static function getCodeFromAccessToken($accessToken, $appId = null, $appSecret = null)
{

@ -63,7 +63,7 @@ class SignedRequest
/**
* Returns the raw signed request data.
*
* @return string|null
* @return string
*/
public function getRawSignedRequest()
{
@ -84,7 +84,7 @@ class SignedRequest
* Returns a property from the signed request data if available.
*
* @param string $key
* @param mixed|null $default
* @param integer $default
*
* @return mixed|null
*/

@ -24,7 +24,6 @@
namespace Facebook\HttpClients;
use Facebook\FacebookSDKException;
use GuzzleHttp\Client;
use GuzzleHttp\Exception\AdapterException;
use GuzzleHttp\Exception\RequestException;

@ -18,14 +18,8 @@ require_once dirname(__FILE__) . '/facebook-php-sdk/autoload.php';
use Facebook\FacebookSession;
use Facebook\FacebookRedirectLoginHelper;
use Facebook\FacebookRequest;
use Facebook\FacebookResponse;
use Facebook\FacebookSDKException;
use Facebook\FacebookRequestException;
use Facebook\FacebookAuthorizationException;
use Facebook\GraphObject;
use Facebook\Entities\AccessToken;
use Facebook\HttpClients\FacebookCurlHttpClient;
use Facebook\HttpClients\FacebookHttpable;
require_once dirname(__FILE__) . '/functions.inc.php';

@ -148,7 +148,7 @@ function external_add_user($u) {
* - language
* - courses : string of all courses code separated by '|'
* - admin : boolean
* @return boolean
* @return boolean|null
* @author ndiechburg <noel@cblue.be>
* */
function external_update_user($new_user) {

@ -65,6 +65,7 @@ class KeyAuth
* If empty it disables authentication.
*
* !! 10 chars max !!
* @param string $_
*/
public static function enable_services($_)
{
@ -254,6 +255,9 @@ class KeyAuth
return Request::get('cidReq', 0);
}
/**
* @return integer
*/
public function get_group_id()
{
return Request::get('gidReq', 0);

@ -67,7 +67,7 @@ require_once api_get_path(SYS_CODE_PATH).'auth/external_login/ldap.inc.php';
require 'ldap_var.inc.php';
/**
* Check login and password with LDAP
* @return true when login & password both OK, false otherwise
* @return boolean when login & password both OK, false otherwise
* @author Roan Embrechts (based on code from Universit<EFBFBD> Jean Monet)
*/
@ -305,7 +305,7 @@ function ldap_authentication_check ($uname, $passwd) {
} // end of check
/**
* Set the protocol version with version from config file (enables LDAP version 3)
* @param resource The LDAP connexion resource, passed by reference.
* @param resource resource LDAP connexion resource, passed by reference.
* @return void
*/
function ldap_set_version(&$resource) {
@ -323,6 +323,7 @@ function ldap_set_version(&$resource) {
* Handle bind (whether authenticated or not)
* @param resource The LDAP handler to which we are connecting (by reference)
* @param resource The LDAP bind handler we will be modifying
* @param boolean $ldap_bind
* @return boolean Status of the bind assignment. True for success, false for failure.
*/
function ldap_handle_bind(&$ldap_handler,&$ldap_bind) {

@ -337,6 +337,7 @@ function openid_verify_assertion($op_endpoint, $response) {
/**
* Make a HTTP request - This function has been copied straight over from Drupal 6 code (drupal_http_request)
* @param string $data
*/
function openid_http_request($url, $headers = array(), $method = 'GET', $data = NULL, $retry = 3) {
$result = new stdClass();

@ -121,6 +121,7 @@ function _openid_create_message($data) {
/**
* Encode a message from _openid_create_message for HTTP Post
* @param null|string $message
*/
function _openid_encode_message($message) {
$encoded_message = '';
@ -173,6 +174,7 @@ function _openid_nonce() {
/**
* Pull the href attribute out of an html link element.
* @param string $rel
*/
function _openid_link_href($rel, $html) {
$rel = preg_quote($rel);
@ -186,6 +188,7 @@ function _openid_link_href($rel, $html) {
/**
* Pull the http-equiv attribute out of an html meta element
* @param string $equiv
*/
function _openid_meta_httpequiv($equiv, $html) {
preg_match('|<meta\s+http-equiv=["\']' . $equiv . '["\'](.*)/?>|iU', $html, $matches);
@ -221,6 +224,10 @@ function _openid_signature($association, $message_array, $keys_to_sign) {
return base64_encode($signature);
}
/**
* @param string $key
* @param null|string $text
*/
function _openid_hmac($key, $text) {
if (strlen($key) > OPENID_SHA1_BLOCKSIZE) {
$key = _openid_sha1($key, true);
@ -256,6 +263,9 @@ function _openid_dh_long_to_base64($str) {
return base64_encode(_openid_dh_long_to_binary($str));
}
/**
* @param string $str
*/
function _openid_dh_binary_to_long($str) {
$bytes = array_merge(unpack('C*', $str));
@ -297,6 +307,9 @@ function _openid_dh_long_to_binary($long) {
return $string;
}
/**
* @param string $secret
*/
function _openid_dh_xorsecret($shared, $secret) {
$dh_shared_str = _openid_dh_long_to_binary($shared);
$sha1_dh_shared = _openid_sha1($dh_shared_str);
@ -308,6 +321,9 @@ function _openid_dh_xorsecret($shared, $secret) {
return $xsecret;
}
/**
* @param string $stop
*/
function _openid_dh_rand($stop) {
static $duplicate_cache = array();

@ -1,8 +1,6 @@
<?php
/* For license terms, see /license.txt */
use ChamiloSession as Session;
require_once '../inc/global.inc.php';
$token = isset($_GET['token']) ? $_GET['token'] : '';

@ -17,7 +17,7 @@ class ShibbolethStore
/**
*
* @return ShibbolethData
* @return ShibbolethStore
*/
public static function instance()
{

@ -56,6 +56,9 @@ class UserStore extends _UserStore
return $this->get(array('shibb_unique_id' => $id));
}
/**
* @param string $id
*/
public function shibboleth_id_exists($id)
{
return $this->exist(array('shibb_unique_id' => $id));

@ -128,7 +128,7 @@ class Shibboleth
/**
*
* @param ShibbolethUser $user
* @param ShibbolethUser $shibb_user
*/
public static function save($shibb_user)
{
@ -230,6 +230,7 @@ class Shibboleth
* Sends an email to the Chamilo and Shibboleth administrators in the name
* of the logged-in user.
*
* @param string $subject
*/
public static function email_admin($subject, $message)
{

@ -27,6 +27,9 @@ class ShibbolethDisplay
return $result;
}
/**
* @param string $message
*/
public function error_page($message)
{
$page_title = get_lang('ShibbolethLogin');
@ -37,6 +40,9 @@ class ShibbolethDisplay
die;
}
/**
* @param string $message
*/
public function message_page($message, $title = '')
{
$title = $title ? $title : get_lang('ShibbolethLogin');

@ -2,14 +2,14 @@
/* For licensing terms, see /license.txt */
/**
* This file allows creating audio files from a text.
* This file allows creating audio files from a text.
*
* @package chamilo.document
* @package chamilo.document
*
* @author Juan Carlos Raña Trabado
* @since 8/January/2011
* TODO:clean all file
*/
*/
require_once '../inc/global.inc.php';
$_SESSION['whereami'] = 'document/createaudio';
@ -23,26 +23,26 @@ api_block_anonymous_users();
$groupId = api_get_group_id();
if (api_get_setting('enabled_text2audio') == 'false') {
api_not_allowed(true);
api_not_allowed(true);
}
$document_data = DocumentManager::get_document_data_by_id(
$_REQUEST['id'],
api_get_course_id()
$_REQUEST['id'],
api_get_course_id()
);
if (empty($document_data)) {
if (api_is_in_group()) {
$group_properties = GroupManager::get_group_properties(
$groupId
);
$document_id = DocumentManager::get_document_id(
api_get_course_info(),
$group_properties['directory']
);
$document_data = DocumentManager::get_document_data_by_id(
$document_id,
api_get_course_id()
);
$group_properties = GroupManager::get_group_properties(
$groupId
);
$document_id = DocumentManager::get_document_id(
api_get_course_info(),
$group_properties['directory']
);
$document_data = DocumentManager::get_document_data_by_id(
$document_id,
api_get_course_id()
);
}
}
$document_id = $document_data['id'];
@ -55,53 +55,59 @@ $is_allowed_to_edit = api_is_allowed_to_edit(null, true);
// Please, do not modify this dirname formatting
if (strstr($dir, '..')) {
$dir = '/';
$dir = '/';
}
if ($dir[0] == '.') {
$dir = substr($dir, 1);
$dir = substr($dir, 1);
}
if ($dir[0] != '/') {
$dir = '/'.$dir;
$dir = '/' . $dir;
}
if ($dir[strlen($dir) - 1] != '/') {
$dir .= '/';
$dir .= '/';
}
$filepath = api_get_path(SYS_COURSE_PATH).$_course['path'].'/document'.$dir;
$filepath = api_get_path(SYS_COURSE_PATH) . $_course['path'] . '/document' . $dir;
if (!is_dir($filepath)) {
$filepath = api_get_path(SYS_COURSE_PATH).$_course['path'].'/document/';
$dir = '/';
$filepath = api_get_path(SYS_COURSE_PATH) . $_course['path'] . '/document/';
$dir = '/';
}
//groups //TODO: clean
if (!empty($groupId)) {
$interbreadcrumb[] = array("url" => "../group/group_space.php?".api_get_cidreq(), "name" => get_lang('GroupSpace'));
$group = GroupManager :: get_group_properties($groupId);
$path = explode('/', $dir);
if ('/'.$path[1] != $group['directory']) {
api_not_allowed(true);
}
$interbreadcrumb[] = array(
"url" => "../group/group_space.php?" . api_get_cidreq(),
"name" => get_lang('GroupSpace')
);
$group = GroupManager:: get_group_properties($groupId);
$path = explode('/', $dir);
if ('/' . $path[1] != $group['directory']) {
api_not_allowed(true);
}
}
$interbreadcrumb[] = array ("url" => "./document.php?curdirpath=".urlencode($dir)."&".api_get_cidreq(), "name" => get_lang('Documents'));
$interbreadcrumb[] = array(
"url" => "./document.php?curdirpath=" . urlencode($dir) . "&" . api_get_cidreq(),
"name" => get_lang('Documents')
);
if (!$is_allowed_in_course) {
api_not_allowed(true);
api_not_allowed(true);
}
if (!($is_allowed_to_edit || $_SESSION['group_member_with_upload_rights'] ||
DocumentManager::is_my_shared_folder(
api_get_user_id(),
Security::remove_XSS($dir),
api_get_session_id()
))
DocumentManager::is_my_shared_folder(
api_get_user_id(),
Security::remove_XSS($dir),
api_get_session_id()
))
) {
api_not_allowed(true);
api_not_allowed(true);
}
@ -110,93 +116,96 @@ Event::event_access_tool(TOOL_DOCUMENT);
$display_dir = $dir;
if (isset ($group)) {
$display_dir = explode('/', $dir);
unset ($display_dir[0]);
unset ($display_dir[1]);
$display_dir = implode('/', $display_dir);
$display_dir = explode('/', $dir);
unset ($display_dir[0]);
unset ($display_dir[1]);
$display_dir = implode('/', $display_dir);
}
// Interbreadcrumb for the current directory root path
// Copied from document.php
$dir_array = explode('/', $dir);
$array_len = count($dir_array);
$dir_acum = '';
for ($i = 0; $i < $array_len; $i++) {
$url_dir = 'document.php?&curdirpath='.$dir_acum.$dir_array[$i];
//Max char 80
$url_to_who = cut($dir_array[$i],80);
$interbreadcrumb[] = array('url' => $url_dir, 'name' => $url_to_who);
$dir_acum .= $dir_array[$i].'/';
$url_dir = 'document.php?&curdirpath=' . $dir_acum . $dir_array[$i];
//Max char 80
$url_to_who = cut($dir_array[$i], 80);
$interbreadcrumb[] = array('url' => $url_dir, 'name' => $url_to_who);
$dir_acum .= $dir_array[$i] . '/';
}
Display :: display_header($nameTools, 'Doc');
echo '<div class="actions">';
echo '<a href="document.php?id='.$document_id.'">'.
Display::return_icon('back.png',get_lang('BackTo').' '.get_lang('DocumentsOverview'),'',ICON_SIZE_MEDIUM).'</a>';
echo '<a href="create_audio.php?'.api_get_cidreq().'&amp;id='.$document_id.'&amp;dt2a=google">'.
Display::return_icon('google.png',get_lang('GoogleAudio'),'',ICON_SIZE_MEDIUM).'</a>';
echo '<a href="create_audio.php?'.api_get_cidreq().'&amp;id='.$document_id.'&amp;dt2a=pediaphon">'.
Display::return_icon('pediaphon.png', get_lang('Pediaphon'),'',ICON_SIZE_MEDIUM).'</a>';
echo '</div>';
$service = isset($_GET['service']) ? $_GET['service'] : 'pediaphon';
?>
<!-- javascript and styles for textareaCounter-->
<script type="text/javascript">
var info;
$(document).ready(function(){
var options = {
'maxCharacterSize': 100,
'originalStyle': 'originalTextareaInfo',
'warningStyle' : 'warningTextareaInfo',
'warningNumber': 20,
'displayFormat' : '#input/#max'
};
$('#textarea_google').textareaCount(options, function(data){
$('#textareaCallBack').html(data);
});
});
</script>
<style>
.overview {
background: #FFEC9D;
padding: 10px;
width: 90%;
border: 1px solid #CCCCCC;
}
Display:: display_header($nameTools, 'Doc');
.originalTextareaInfo {
font-size: 12px;
color: #000000;
text-align: right;
}
echo '<div class="actions">';
echo '<a href="document.php?id=' . $document_id . '">' .
Display::return_icon('back.png', get_lang('BackTo') . ' ' . get_lang('DocumentsOverview'), '',
ICON_SIZE_MEDIUM) . '</a>';
.warningTextareaInfo {
color: #FF0000;
font-weight:bold;
text-align: right;
}
echo '<a href="create_audio.php?' . api_get_cidreq() . '&id=' . $document_id . '&service=pediaphon">' .
Display::return_icon('pediaphon.png', get_lang('Pediaphon'), '', ICON_SIZE_MEDIUM) . '</a>';
#showData {
height: 70px;
width: 200px;
border: 1px solid #CCCCCC;
padding: 10px;
margin: 10px;
}
</style>
<div id="textareaCallBack"></div>
echo '<a href="create_audio.php?' . api_get_cidreq() . '&id=' . $document_id . '&service=google">' .
Display::return_icon('google.png', get_lang('GoogleAudio'), '', ICON_SIZE_MEDIUM) . '</a>';
echo '</div>';
?>
<!-- javascript and styles for textareaCounter-->
<script>
var info;
$(document).ready(function () {
var options = {
'maxCharacterSize': 100,
'originalStyle': 'originalTextareaInfo',
'warningStyle': 'warningTextareaInfo',
'warningNumber': 20,
'displayFormat': '#input/#max'
};
$('#textarea_google').textareaCount(options, function (data) {
$('#textareaCallBack').html(data);
});
});
</script>
<style>
.overview {
background: #FFEC9D;
padding: 10px;
width: 90%;
border: 1px solid #CCCCCC;
}
.originalTextareaInfo {
font-size: 12px;
color: #000000;
text-align: right;
}
.warningTextareaInfo {
color: #FF0000;
font-weight: bold;
text-align: right;
}
#showData {
height: 70px;
width: 200px;
border: 1px solid #CCCCCC;
padding: 10px;
margin: 10px;
}
</style>
<div id="textareaCallBack"></div>
<?php
if (isset($_POST['text2voice_mode']) && $_POST['text2voice_mode'] == 'google') {
downloadMP3_google($filepath, $dir);
downloadMP3_google($filepath, $dir);
} elseif (isset($_POST['text2voice_mode']) && $_POST['text2voice_mode'] == 'pediaphon') {
downloadMP3_pediaphon($filepath, $dir);
downloadMP3_pediaphon($filepath, $dir);
}
$tbl_admin_languages = Database :: get_main_table(TABLE_MAIN_LANGUAGE);
$tbl_admin_languages = Database:: get_main_table(TABLE_MAIN_LANGUAGE);
$sql_select = "SELECT * FROM $tbl_admin_languages";
$result_select = Database::query($sql_select);
@ -204,96 +213,94 @@ $options = $options_pedia = array();
$selected_language = null;
while ($row = Database::fetch_array($result_select)) {
$options[$row['isocode']] =$row['original_name'].' ('.$row['english_name'].')';
if (in_array($row['isocode'], array('de', 'en', 'es', 'fr'))){
$options_pedia[$row['isocode']] =$row['original_name'].' ('.$row['english_name'].')';
}
$options[$row['isocode']] = $row['original_name'] . ' (' . $row['english_name'] . ')';
if (in_array($row['isocode'], array('de', 'en', 'es', 'fr'))) {
$options_pedia[$row['isocode']] = $row['original_name'] . ' (' . $row['english_name'] . ')';
}
}
$icon = Display::return_icon('text2audio.png', get_lang('HelpText2Audio'),'',ICON_SIZE_MEDIUM);
echo '<div class="page-header"><h2>'.$icon.get_lang('HelpText2Audio').'</h2></div>';
if (Security::remove_XSS($_GET['dt2a']) == 'google') {
$selected_language = api_get_language_isocode();//lang default is the course language
echo '<div>';
$form = new FormValidator('form1', 'post', null, '', array('id' => 'form1'));
$form->addElement('hidden', 'text2voice_mode', 'google');
$form->addElement('hidden', 'id', $document_id);
$form->addElement('text', 'title', get_lang('Title'));
$form->addElement('select', 'lang', get_lang('Language'), $options);
$form->addElement('textarea', 'text', get_lang('InsertText2Audio'), array('id' => 'textarea_google'));
//echo Display :: return_icon('info3.gif', get_lang('HelpGoogleAudio'), array('align' => 'absmiddle', 'hspace' => '3px'), false);
$form->addButtonSave(get_lang('SaveMP3'));
$defaults = array();
$defaults['lang'] = $selected_language;
$form->setDefaults($defaults);
$form->display();
echo '</div>';
if ($service == 'google') {
$selected_language = api_get_language_isocode();//lang default is the course language
$form = new FormValidator('form1', 'post', api_get_self().'?'.api_get_cidreq(), '', array('id' => 'form1'));
$form->addHeader(get_lang('HelpText2Audio'));
$form->addElement('hidden', 'text2voice_mode', 'google');
$form->addElement('hidden', 'id', $document_id);
$form->addElement('text', 'title', get_lang('Title'));
$form->addElement('select', 'lang', get_lang('Language'), $options);
$form->addElement('textarea', 'text', get_lang('InsertText2Audio'), array('id' => 'textarea_google'));
$form->addButtonSave(get_lang('SaveMP3'));
$defaults = array();
$defaults['lang'] = $selected_language;
$form->setDefaults($defaults);
$form->display();
}
if (Security::remove_XSS($_GET['dt2a']) == 'pediaphon') {
//lang default is a default message
$selected_language = "defaultmessage";
$options_pedia['defaultmessage'] =get_lang('FirstSelectALanguage');
$options['defaultmessage'] =get_lang('FirstSelectALanguage');
echo '<div>';
$form = new FormValidator('form2', 'post', null, '', array('id' => 'form2'));
$form->addElement('hidden', 'text2voice_mode','pediaphon');
$form->addElement('hidden', 'id', $document_id);
$form->addElement('text', 'title', get_lang('Title'));
$form->addElement('select', 'lang', get_lang('Language'), $options_pedia, array('onclick' => 'update_voices(this.selectedIndex);'));
$form->addElement('select', 'voices', get_lang('Voice'), array(get_lang('FirstSelectALanguage')), array());
$speed_options = array();
$speed_options['1'] = get_lang('Normal');
$speed_options['0.75'] = get_lang('GoFaster');
$speed_options['0.8'] = get_lang('Fast');
$speed_options['1.2'] = get_lang('Slow');
$speed_options['1.6'] = get_lang('SlowDown');
$form->addElement('select', 'speed', get_lang('Speed'), $speed_options, array());
$form->addElement('textarea', 'text', get_lang('InsertText2Audio'), array('id' => 'textarea_pediaphon'));
//echo Display :: return_icon('info3.gif', get_lang('HelpPediaphon'), array('align' => 'absmiddle', 'hspace' => '3px'), false);
$form->addButtonSave(get_lang('SaveMP3'));
$defaults = array();
$defaults['lang'] = $selected_language;
$form->setDefaults($defaults);
$form->display();
echo '</div>';
?>
<!-- javascript form name form2 update voices -->
<script type="text/javascript">
var langslist=document.form2.lang
var voiceslist=document.form2.voices
var voices=new Array()
<!--German -->
voices[0]=["<?php echo get_lang('Female').' (de1)'; ?>|de1", "<?php echo get_lang('Male').' (de2)'; ?>|de2", "<?php echo get_lang('Female').' (de3)'; ?>|de3", "<?php echo get_lang('Male').' (de4)'; ?>|de4", "<?php echo get_lang('Female').' (de5)'; ?>|de5", "<?php echo get_lang('Male').' (de6)'; ?>|de6", "<?php echo get_lang('Female').' (de7)'; ?>|de7", "<?php echo get_lang('Female').' (de8 HQ)'; ?>|de8"]
<!--English -->
voices[1]=["<?php echo get_lang('Male').' (en1)'; ?>|en1", "<?php echo get_lang('Male').' (en2 HQ)'; ?>|en2", "<?php echo get_lang('Female').' (us1)'; ?>| us1", "<?php echo get_lang('Male').' (us2)'; ?>|us2", "<?php echo get_lang('Male').' (us3)'; ?>|us3", "<?php echo get_lang('Female').'(us4 HQ)'; ?>|us4"]
<!--Spanish -->
voices[2]=["<?php echo get_lang('Male').' (es5 HQ)'; ?>|es5"]
<!--French -->
voices[3]=["<?php echo get_lang('Female').' (fr8 HQ)'; ?>|fr8"]
function update_voices(selectedvoicegroup){
voiceslist.options.length=0
for (i=0; i<voices[selectedvoicegroup].length; i++)
voiceslist.options[voiceslist.options.length]=new Option(voices[selectedvoicegroup][i].split("|")[0], voices[selectedvoicegroup][i].split("|")[1])
}
</script>
<?php
if ($service == 'pediaphon') {
//lang default is a default message
$selected_language = "defaultmessage";
$options_pedia['defaultmessage'] = get_lang('FirstSelectALanguage');
$options['defaultmessage'] = get_lang('FirstSelectALanguage');
$form = new FormValidator('form2', 'post', api_get_self().'?'.api_get_cidreq(), '', array('id' => 'form2'));
$form->addHeader(get_lang('HelpText2Audio'));
$form->addElement('hidden', 'text2voice_mode', 'pediaphon');
$form->addElement('hidden', 'id', $document_id);
$form->addElement('text', 'title', get_lang('Title'));
$form->addSelect('lang', get_lang('Language'), $options_pedia, array('class' => 'lang'));
$form->addSelect('voices', get_lang('Voice'), array(get_lang('FirstSelectALanguage')), array('id' => 'voices'));
$speed_options = array();
$speed_options['1'] = get_lang('Normal');
$speed_options['0.75'] = get_lang('GoFaster');
$speed_options['0.8'] = get_lang('Fast');
$speed_options['1.2'] = get_lang('Slow');
$speed_options['1.6'] = get_lang('SlowDown');
$form->addElement('select', 'speed', get_lang('Speed'), $speed_options, array());
$form->addElement('textarea', 'text', get_lang('InsertText2Audio'), array('id' => 'textarea_pediaphon'));
//echo Display :: return_icon('info3.gif', get_lang('HelpPediaphon'), array('align' => 'absmiddle', 'hspace' => '3px'), false);
$form->addButtonSave(get_lang('SaveMP3'));
$defaults = array();
$defaults['lang'] = $selected_language;
$form->setDefaults($defaults);
$form->display();
?>
<!-- javascript form name form2 update voices -->
<script>
var langslist = document.form2.lang
var voiceslist = document.form2.voices
var voices = new Array()
<!--German -->
voices['de'] = ["<?php echo get_lang('Female') . ' (de1)'; ?>|de1", "<?php echo get_lang('Male') . ' (de2)'; ?>|de2", "<?php echo get_lang('Female') . ' (de3)'; ?>|de3", "<?php echo get_lang('Male') . ' (de4)'; ?>|de4", "<?php echo get_lang('Female') . ' (de5)'; ?>|de5", "<?php echo get_lang('Male') . ' (de6)'; ?>|de6", "<?php echo get_lang('Female') . ' (de7)'; ?>|de7", "<?php echo get_lang('Female') . ' (de8 HQ)'; ?>|de8"]
<!--English -->
voices['en'] = ["<?php echo get_lang('Male') . ' (en1)'; ?>|en1", "<?php echo get_lang('Male') . ' (en2 HQ)'; ?>|en2", "<?php echo get_lang('Female') . ' (us1)'; ?>|us1", "<?php echo get_lang('Male') . ' (us2)'; ?>|us2", "<?php echo get_lang('Male') . ' (us3)'; ?>|us3", "<?php echo get_lang('Female') . '(us4 HQ)'; ?>|us4"]
<!--Spanish -->
voices['es'] = ["<?php echo get_lang('Male') . ' (es5 HQ)'; ?>|es5"]
<!--French -->
voices['fr'] = ["<?php echo get_lang('Female') . ' (fr8 HQ)'; ?>|fr8"]
$(document).ready(function () {
$('.lang').on('change', function () {
var selectedvoicegroup = this.value;
$('#voices').empty();
for (i = 0; i < voices[selectedvoicegroup].length; i++) {
var value = voices[selectedvoicegroup][i].split("|")[1];
var text = voices[selectedvoicegroup][i].split("|")[0];
var newOption = $('<option value="' + value + '">' + text + '</option>');
$('#voices').append(newOption);
$('#voices').selectpicker('refresh');
}
});
});
</script>
<?php
}//end pediaphon
echo '</div>';
Display :: display_footer();
Display:: display_footer();
/**
* This function save a post into a file mp3 from google services
@ -305,105 +312,95 @@ Display :: display_footer();
*/
function downloadMP3_google($filepath, $dir)
{
$location='create_audio.php?'.api_get_cidreq().'&id='.intval($_POST['id']).'&dt2a=google';
//security
if (!isset($_POST['lang']) && !isset($_POST['text']) && !isset($_POST['title']) && !isset($filepath) && !isset($dir)) {
echo '<script>window.location.href="'.$location.'"</script>';
return;
}
$_course = api_get_course_info();
$_user = api_get_user_info();
$clean_title=trim($_POST['title']);
$clean_text=trim($_POST['text']);
if(empty($clean_title) || empty($clean_text)){
echo '<script>window.location.href="'.$location.'"</script>';
return;
}
$clean_title = Security::remove_XSS($clean_title);
$clean_title = Database::escape_string($clean_title);
$clean_title = str_replace(' ', '_', $clean_title);//compound file names
$clean_text = Security::remove_XSS($clean_text);
$clean_lang = Security::remove_XSS($_POST['lang']);
$extension='mp3';
$audio_filename=$clean_title.'.'.$extension;
$audio_title = str_replace('_',' ',$clean_title);
//prevent duplicates
if (file_exists($filepath.'/'.$clean_title.'.'.$extension)){
$i = 1;
while (file_exists($filepath.'/'.$clean_title.'_'.$i.'.'.$extension)) $i++;
$audio_filename = $clean_title . '_' . $i . '.'.$extension;
$audio_title = $clean_title . '_' . $i . '.'.$extension;
$audio_title = str_replace('_',' ',$audio_title);
}
$documentPath = $filepath.'/'.$audio_filename;
/*
//prev for a fine unicode, borrowed from main api TODO:clean
// Safe replacements for some non-letter characters (whitout blank spaces)
$search = array("\0", "\t", "\n", "\r", "\x0B", '/', "\\", '"', "'", '?', '*', '>', '<', '|', ':', '$', '(', ')', '^', '[', ']', '#', '+', '&', '%');
$replace = array('', '_', '_', '_', '_', '-', '-', '-', '_', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-');
$filename=$clean_text;
// Encoding detection.
$encoding = api_detect_encoding($filename);
// Converting html-entities into encoded characters.
$filename = api_html_entity_decode($filename, ENT_QUOTES, $encoding);
// Transliteration to ASCII letters, they are not dangerous for filesystems.
$filename = api_transliterate($filename, 'x', $encoding);
// Replacing remaining dangerous non-letter characters.
$clean_text = str_replace($search, $replace, $filename);*/
$clean_text = api_replace_dangerous_char($clean_text);
// adding the file
// add new file to disk
$proxySettings = api_get_configuration_value('proxy_settings');
$url = "http://translate.google.com/translate_tts?tl=".$clean_lang."&q=".urlencode($clean_text)."";
if (empty($proxySettings)) {
$content = file_get_contents($url);
} else {
$context = stream_context_create($proxySettings);
$content = file_get_contents($url, false, $context);
}
$location = 'create_audio.php?' . api_get_cidreq() . '&id=' . intval($_POST['id']) . '&service=google';
//security
if (!isset($_POST['lang']) && !isset($_POST['text']) && !isset($_POST['title']) && !isset($filepath) && !isset($dir)) {
echo '<script>window.location.href="' . $location . '"</script>';
return;
}
$_course = api_get_course_info();
$_user = api_get_user_info();
$clean_title = trim($_POST['title']);
$clean_text = trim($_POST['text']);
if (empty($clean_title) || empty($clean_text)) {
echo '<script>window.location.href="' . $location . '"</script>';
return;
}
$clean_title = Security::remove_XSS($clean_title);
$clean_title = Database::escape_string($clean_title);
$clean_title = str_replace(' ', '_', $clean_title);//compound file names
$clean_text = Security::remove_XSS($clean_text);
$clean_lang = Security::remove_XSS($_POST['lang']);
$extension = 'mp3';
$audio_filename = $clean_title . '.' . $extension;
$audio_title = str_replace('_', ' ', $clean_title);
//prevent duplicates
if (file_exists($filepath . '/' . $clean_title . '.' . $extension)) {
$i = 1;
while (file_exists($filepath . '/' . $clean_title . '_' . $i . '.' . $extension)) {
$i++;
}
$audio_filename = $clean_title . '_' . $i . '.' . $extension;
$audio_title = $clean_title . '_' . $i . '.' . $extension;
$audio_title = str_replace('_', ' ', $audio_title);
}
$documentPath = $filepath . '/' . $audio_filename;
$clean_text = api_replace_dangerous_char($clean_text);
// adding the file
// add new file to disk
$proxySettings = api_get_configuration_value('proxy_settings');
$key = api_get_configuration_value('translate_app_google_key');
$url = "https://www.googleapis.com/language/translate/v2?key=$key&" . $clean_lang . "&target=$clean_lang&q=" . urlencode($clean_text) . "";
if (empty($proxySettings)) {
$content = file_get_contents($url);
} else {
$context = stream_context_create($proxySettings);
$content = file_get_contents($url, false, $context);
}
file_put_contents(
$documentPath,
$content
);
// add document to database
$current_session_id = api_get_session_id();
$groupId = api_get_group_id();
$relativeUrlPath=$dir;
$doc_id = add_document(
$_course,
$relativeUrlPath.$audio_filename,
'file',
filesize($documentPath),
$audio_title
);
api_item_property_update(
$_course,
TOOL_DOCUMENT,
$doc_id,
'DocumentAdded',
$_user['user_id'],
$groupId,
null,
null,
null,
$current_session_id
);
Display::display_confirmation_message(get_lang('DocumentCreated'));
//return to location
echo '<script>window.location.href="'.$location.'"</script>';
// add document to database
$current_session_id = api_get_session_id();
$groupId = api_get_group_id();
$relativeUrlPath = $dir;
$doc_id = add_document(
$_course,
$relativeUrlPath . $audio_filename,
'file',
filesize($documentPath),
$audio_title
);
api_item_property_update(
$_course,
TOOL_DOCUMENT,
$doc_id,
'DocumentAdded',
$_user['user_id'],
$groupId,
null,
null,
null,
$current_session_id
);
Display::display_confirmation_message(get_lang('DocumentCreated'));
//return to location
echo '<script>window.location.href="' . $location . '"</script>';
}
/**
@ -416,99 +413,107 @@ function downloadMP3_google($filepath, $dir)
*/
function downloadMP3_pediaphon($filepath, $dir)
{
$location='create_audio.php?'.api_get_cidreq().'&id='.intval($_POST['id']).'&dt2a=pediaphon';
//security
if(!isset($_POST['lang']) && !isset($_POST['text']) && !isset($_POST['title']) && !isset($filepath) && !isset($dir)) {
echo '<script>window.location.href="'.$location.'"</script>';
return;
}
$_course = api_get_course_info();
$_user = api_get_user_info();
$clean_title=trim($_POST['title']);
$clean_title= Database::escape_string($clean_title);
$clean_text=trim($_POST['text']);
$clean_voices=Security::remove_XSS($_POST['voices']);
if(empty($clean_title) || empty($clean_text) || empty($clean_voices)){
echo '<script>window.location.href="'.$location.'"</script>';
return;
}
$clean_title = Security::remove_XSS($clean_title);
$clean_title = Database::escape_string($clean_title);
$clean_title = str_replace(' ', '_', $clean_title);//compound file names
$clean_text = Security::remove_XSS($clean_text);
$clean_lang = Security::remove_XSS($_POST['lang']);
$clean_speed = Security::remove_XSS($_POST['speed']);
$extension='mp3';
$audio_filename=$clean_title.'.'.$extension;
$audio_title = str_replace('_',' ',$clean_title);
//prevent duplicates
if (file_exists($filepath.'/'.$clean_title.'.'.$extension)){
$i = 1;
while (file_exists($filepath.'/'.$clean_title.'_'.$i.'.'.$extension)) $i++;
$audio_filename = $clean_title . '_' . $i . '.'.$extension;
$audio_title = $clean_title . '_' . $i . '.'.$extension;
$audio_title = str_replace('_',' ',$audio_title);
}
$documentPath = $filepath.'/'.$audio_filename;
/*//prev for a fine unicode, borrowed from main api TODO:clean
// Safe replacements for some non-letter characters (whitout blank spaces)
$search = array("\0", "\t", "\n", "\r", "\x0B", '/', "\\", '"', "'", '?', '*', '>', '<', '|', ':', '$', '(', ')', '^', '[', ']', '#', '+', '&', '%');
$replace = array('', '_', '_', '_', '_', '-', '-', '-', '_', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-');
$filename=$clean_text;
// Encoding detection.
$encoding = api_detect_encoding($filename);
// Converting html-entities into encoded characters.
$filename = api_html_entity_decode($filename, ENT_QUOTES, $encoding);
// Transliteration to ASCII letters, they are not dangerous for filesystems.
$filename = api_transliterate($filename, 'x', $encoding);
// Replacing remaining dangerous non-letter characters.
$clean_text = str_replace($search, $replace, $filename);*/
$clean_text = api_replace_dangerous_char($clean_text);
//adding the file
if ($clean_lang=='de') {
$url_pediaphon='http://www.pediaphon.org/~bischoff/radiopedia/sprich_multivoice.cgi';
$find_t2v = '/http\:\/\/www\.pediaphon\.org\/\~bischoff\/radiopedia\/mp3\/(.*)\.mp3\"/';
} else {
$url_pediaphon='http://www.pediaphon.org/~bischoff/radiopedia/sprich_multivoice_'.$clean_lang.'.cgi';//en, es, fr
$find_t2v = '/http\:\/\/www\.pediaphon\.org\/\~bischoff\/radiopedia\/mp3\/'.$clean_lang.'\/(.*)\.mp3\"/';
}
$data="stimme=".$clean_voices."&inputtext=".$clean_text."&speed=".$clean_speed."&go=speak";
$opts = array('http' =>
array(
'method' => 'POST',
'header' =>"Content-Type: application/x-www-form-urlencoded\r\n",
"Content-Length: " . strlen($data) . "\r\n",
'content' => $data
)
);
$context = stream_context_create($opts);
// Download the whole HTML page
$previous_returntext2voice = file_get_contents($url_pediaphon,false,$context);
//extract the audio file path
$search_source = preg_match($find_t2v, $previous_returntext2voice, $hits);
$souce_end = substr($hits[0], 0, -1);
//download file
$returntext2voice = file_get_contents($souce_end);
//save file
$f = @file_put_contents($documentPath, $returntext2voice);
if ($f === false && !empty($php_errormsg)) {
error_log($php_errormsg);
}
//add document to database
$current_session_id = api_get_session_id();
$groupId = api_get_group_id();
$relativeUrlPath=$dir;
$doc_id = add_document($_course, $relativeUrlPath.$audio_filename, 'file', filesize($documentPath), $audio_title);
api_item_property_update($_course, TOOL_DOCUMENT, $doc_id, 'DocumentAdded', $_user['user_id'], $groupId, null, null, null, $current_session_id);
$location = 'create_audio.php?' . api_get_cidreq() . '&id=' . intval($_POST['id']) . '&service=pediaphon';
//security
if (!isset($_POST['lang']) && !isset($_POST['text']) && !isset($_POST['title']) && !isset($filepath) && !isset($dir)) {
echo '<script>window.location.href="' . $location . '"</script>';
return;
}
$_course = api_get_course_info();
$_user = api_get_user_info();
$clean_title = trim($_POST['title']);
$clean_title = Database::escape_string($clean_title);
$clean_text = trim($_POST['text']);
$clean_voices = Security::remove_XSS($_POST['voices']);
if (empty($clean_title) || empty($clean_text) || empty($clean_voices)) {
echo '<script>window.location.href="' . $location . '"</script>';
return;
}
$clean_title = Security::remove_XSS($clean_title);
$clean_title = Database::escape_string($clean_title);
$clean_title = str_replace(' ', '_', $clean_title);//compound file names
$clean_text = Security::remove_XSS($clean_text);
$clean_lang = Security::remove_XSS($_POST['lang']);
$clean_speed = Security::remove_XSS($_POST['speed']);
$extension = 'mp3';
$audio_filename = $clean_title . '.' . $extension;
$audio_title = str_replace('_', ' ', $clean_title);
//prevent duplicates
if (file_exists($filepath . '/' . $clean_title . '.' . $extension)) {
$i = 1;
while (file_exists($filepath . '/' . $clean_title . '_' . $i . '.' . $extension)) {
$i++;
}
$audio_filename = $clean_title . '_' . $i . '.' . $extension;
$audio_title = $clean_title . '_' . $i . '.' . $extension;
$audio_title = str_replace('_', ' ', $audio_title);
}
$documentPath = $filepath . '/' . $audio_filename;
$clean_text = api_replace_dangerous_char($clean_text);
//adding the file
if ($clean_lang == 'de') {
$url_pediaphon = 'http://www.pediaphon.org/~bischoff/radiopedia/sprich_multivoice.cgi';
$find_t2v = '/http\:\/\/www\.pediaphon\.org\/\~bischoff\/radiopedia\/mp3\/(.*)\.mp3\"/';
} else {
$url_pediaphon = 'http://www.pediaphon.org/~bischoff/radiopedia/sprich_multivoice_' . $clean_lang . '.cgi';//en, es, fr
$find_t2v = '/http\:\/\/www\.pediaphon\.org\/\~bischoff\/radiopedia\/mp3\/' . $clean_lang . '\/(.*)\.mp3\"/';
}
$data = "stimme=" . $clean_voices . "&inputtext=" . $clean_text . "&speed=" . $clean_speed . "&go=speak";
$opts = array(
'http' =>
array(
'method' => 'POST',
'header' => "Content-Type: application/x-www-form-urlencoded\r\n",
"Content-Length: " . strlen($data) . "\r\n",
'content' => $data
)
);
$context = stream_context_create($opts);
// Download the whole HTML page
$previous_returntext2voice = file_get_contents($url_pediaphon, false, $context);
//extract the audio file path
$search_source = preg_match($find_t2v, $previous_returntext2voice, $hits);
$souce_end = substr($hits[0], 0, -1);
//download file
$returntext2voice = file_get_contents($souce_end);
//save file
$f = @file_put_contents($documentPath, $returntext2voice);
if ($f === false && !empty($php_errormsg)) {
error_log($php_errormsg);
}
//add document to database
$current_session_id = api_get_session_id();
$groupId = api_get_group_id();
$relativeUrlPath = $dir;
$doc_id = add_document(
$_course,
$relativeUrlPath.$audio_filename,
'file',
filesize($documentPath),
$audio_title
);
api_item_property_update(
$_course,
TOOL_DOCUMENT,
$doc_id,
'DocumentAdded',
$_user['user_id'],
$groupId,
null,
null,
null,
$current_session_id
);
Display::display_confirmation_message(get_lang('DocumentCreated'));
//return to location
echo '<script>window.location.href="'.$location.'"</script>';
//return to location
echo '<script>window.location.href="' . $location . '"</script>';
}

@ -23,21 +23,21 @@ api_block_anonymous_users();
$document_data = DocumentManager::get_document_data_by_id($_GET['id'], api_get_course_id(), true);
if (empty($document_data)) {
if (api_is_in_group()) {
$group_properties = GroupManager::get_group_properties(api_get_group_id());
$document_id = DocumentManager::get_document_id(api_get_course_info(), $group_properties['directory']);
$document_data = DocumentManager::get_document_data_by_id($document_id, api_get_course_id());
$group_properties = GroupManager::get_group_properties(api_get_group_id());
$document_id = DocumentManager::get_document_id(api_get_course_info(), $group_properties['directory']);
$document_data = DocumentManager::get_document_data_by_id($document_id, api_get_course_id());
}
}
$document_id = $document_data['id'];
$dir = $document_data['path'];
$document_id = $document_data['id'];
$dir = $document_data['path'];
/* Constants and variables */
//path for svg-edit save
$_SESSION['draw_dir'] = Security::remove_XSS($dir);
if ($_SESSION['draw_dir']=='/'){
$_SESSION['draw_dir']='';
if ($_SESSION['draw_dir'] == '/') {
$_SESSION['draw_dir'] = '';
}
$dir = isset($dir) ? Security::remove_XSS($dir) : (isset($_POST['dir']) ? Security::remove_XSS($_POST['dir']) : '/');
@ -71,7 +71,10 @@ if (!is_dir($filepath)) {
$groupId = api_get_group_id();
if (!empty($groupId)) {
$interbreadcrumb[] = array ("url" => "../group/group_space.php?".api_get_cidreq(), "name" => get_lang('GroupSpace'));
$interbreadcrumb[] = array (
"url" => "../group/group_space.php?".api_get_cidreq(),
"name" => get_lang('GroupSpace')
);
$noPHP_SELF = true;
$group = GroupManager :: get_group_properties($groupId);
$path = explode('/', $dir);
@ -80,14 +83,21 @@ if (!empty($groupId)) {
}
}
$interbreadcrumb[] = array ("url" => "./document.php?".api_get_cidreq(), "name" => get_lang('Documents'));
$interbreadcrumb[] = array(
"url" => "./document.php?".api_get_cidreq(),
"name" => get_lang('Documents')
);
if (!$is_allowed_in_course) {
api_not_allowed(true);
}
if (!($is_allowed_to_edit || $_SESSION['group_member_with_upload_rights'] ||
DocumentManager::is_my_shared_folder(api_get_user_id(), Security::remove_XSS($dir), api_get_session_id()))) {
DocumentManager::is_my_shared_folder(
api_get_user_id(),
Security::remove_XSS($dir),
api_get_session_id()))
) {
api_not_allowed(true);
}
@ -111,8 +121,11 @@ $array_len = count($dir_array);
if (empty($document_data['parents'])) {
$interbreadcrumb[] = array('url' => '#', 'name' => $document_data['title']);
} else {
foreach($document_data['parents'] as $document_sub_data) {
$interbreadcrumb[] = array('url' => $document_sub_data['document_url'], 'name' => $document_sub_data['title']);
foreach ($document_data['parents'] as $document_sub_data) {
$interbreadcrumb[] = array(
'url' => $document_sub_data['document_url'],
'name' => $document_sub_data['title']
);
}
}
Display :: display_header($nameTools, 'Doc');
@ -126,10 +139,10 @@ if (api_browser_support('svg')) {
//automatic loading the course language
$svgedit_code_translation_table = array('' => 'en', 'pt' => 'pt-Pt', 'sr' => 'sr_latn');
$langsvgedit = api_get_language_isocode();
$langsvgedit = api_get_language_isocode();
$langsvgedit = isset($svgedit_code_translation_table[$langsvgedit]) ? $svgedit_code_translation_table[$langsvgedit] : $langsvgedit;
$langsvgedit = file_exists(api_get_path(LIBRARY_PATH).'svg-edit/locale/lang.'.$langsvgedit.'.js') ? $langsvgedit : 'en';
$svg_url= api_get_path(WEB_LIBRARY_PATH).'svg-edit/svg-editor.php?lang='.$langsvgedit;
$langsvgedit = file_exists(api_get_path(LIBRARY_PATH).'javascript/svgedit/locale/lang.'.$langsvgedit.'.js') ? $langsvgedit : 'en';
$svg_url= api_get_path(WEB_LIBRARY_PATH).'javascript/svgedit/svg-editor.php?lang='.$langsvgedit;
?>
<script>
document.write ('<iframe id="frame" frameborder="0" scrolling="no" src="<?php echo $svg_url; ?>" width="100%" height="100%"><noframes><p>Sorry, your browser does not handle frames</p></noframes></iframe>');

@ -1596,11 +1596,9 @@ if ($is_allowed_to_edit ||
// Create new audio from text
if (api_get_setting('enabled_text2audio') == 'true') {
$dt2a = 'google';
$req_dt2a = '&amp;dt2a='.$dt2a;
$actionsLeft .= Display::url(
Display::return_icon('new_sound.png', get_lang('CreateAudio'), '', ICON_SIZE_MEDIUM),
api_get_path(WEB_CODE_PATH).'document/create_audio.php?'.api_get_cidreq().'&id='.$document_id.$req_dt2a
api_get_path(WEB_CODE_PATH).'document/create_audio.php?'.api_get_cidreq().'&id='.$document_id
);
}
}

@ -18,7 +18,11 @@ $this_section = SECTION_COURSES;
api_protect_course_script(true);
api_block_anonymous_users();
$document_data = DocumentManager::get_document_data_by_id($_GET['id'], api_get_course_id(), true);
$document_data = DocumentManager::get_document_data_by_id(
$_GET['id'],
api_get_course_id(),
true
);
if (empty($document_data)) {
api_not_allowed();
@ -27,7 +31,7 @@ if (empty($document_data)) {
$file_path = $document_data['path'];
$dir = dirname($document_data['path']);
$parent_id = DocumentManager::get_document_id(api_get_course_info(), $dir);
$my_cur_dir_path = Security::remove_XSS($_GET['curdirpath']);
$my_cur_dir_path = isset($_GET['curdirpath']) ? Security::remove_XSS($_GET['curdirpath']) : '';
}
//and urlencode each url $curdirpath (hack clean $curdirpath under Windows - Bug #3261)
$dir = str_replace('\\', '/', $dir);
@ -131,12 +135,10 @@ if (api_browser_support('svg')) {
$svgedit_code_translation_table = array('' => 'en', 'pt' => 'pt-Pt', 'sr' => 'sr_latn');
$langsvgedit = api_get_language_isocode();
$langsvgedit = isset($svgedit_code_translation_table[$langsvgedit]) ? $svgedit_code_translation_table[$langsvgedit] : $langsvgedit;
$langsvgedit = file_exists(api_get_path(LIBRARY_PATH).'svg-edit/locale/lang.'.$langsvgedit.'.js') ? $langsvgedit : 'en';
//$svg_url= api_get_path(WEB_LIBRARY_PATH).'svg-edit/svg-editor.php?url=../../../../courses/'.$courseDir.$dir.$file.'&amp;lang='.$langsvgedit;
$svg_url= api_get_path(WEB_LIBRARY_PATH).'svg-edit/svg-editor.php?url=../../../..'.api_get_path(REL_COURSE_PATH).$courseDir.$dir.$file.'&lang='.$langsvgedit;
$langsvgedit = file_exists(api_get_path(LIBRARY_PATH).'javascript/svgedit/locale/lang.'.$langsvgedit.'.js') ? $langsvgedit : 'en';
$svg_url = api_get_path(WEB_LIBRARY_PATH).'javascript/svgedit/svg-editor.php?url=../../../../../courses/'.$courseDir.$dir.$file.'&lang='.$langsvgedit;
?>
<script type="text/javascript">
<script>
document.write ('<iframe id="frame" frameborder="0" scrolling="no" src="<?php echo $svg_url; ?>" width="100%" height="100%"><noframes><p>Sorry, your browser does not handle frames</p></noframes></iframe>');
function resizeIframe() {
var height = window.innerHeight -50;
@ -148,7 +150,9 @@ if (api_browser_support('svg')) {
};
document.getElementById('frame').onload = resizeIframe;
window.onresize = resizeIframe;
</script>
<?php
echo '<noscript>';
echo '<iframe style="height: 550px; width: 100%;" scrolling="no" frameborder="0\' src="'.$svg_url.'"<noframes><p>Sorry, your browser does not handle frames</p></noframes></iframe>';

@ -72,7 +72,6 @@ class Answer
$objExercise = new Exercise($this->course_id);
$exerciseId = isset($_REQUEST['exerciseId']) ? $_REQUEST['exerciseId'] : null;
$objExercise->read($exerciseId);
if ($objExercise->random_answers == '1') {
$this->readOrderedBy('rand()', '');// randomize answers
} else {

@ -21,8 +21,8 @@ class CalculatedAnswer extends Question
public function __construct()
{
parent::__construct();
$this -> type = CALCULATED_ANSWER;
$this -> isContent = $this-> getIsContent();
$this->type = CALCULATED_ANSWER;
$this->isContent = $this->getIsContent();
}
/**
@ -37,12 +37,9 @@ class CalculatedAnswer extends Question
$objAnswer = new Answer($this->id);
$preArray = explode('@@', $objAnswer->selectAnswer(1));
$defaults['formula'] = array_pop($preArray);
$defaults['answer'] = array_shift($preArray);
$defaults['answer'] = preg_replace("/\[.*\]/", "", $defaults['answer']);
$defaults['weighting'] = $this->weighting;
} else {
$defaults['answer'] = get_lang('DefaultTextInBlanks');
}
@ -126,7 +123,7 @@ class CalculatedAnswer extends Question
$form->addElement(
'html_editor',
'answer',
Display::returnIconPath('fill_field.png'),
Display::return_icon('fill_field.png'),
array(
'id' => 'answer',
'onkeyup' => 'javascript: updateBlanks(this);'
@ -149,11 +146,12 @@ class CalculatedAnswer extends Question
)
);
$form->addElement(
'label', null,
$notationListButton);
'label',
null,
$notationListButton
);
$form->addElement('label', null, get_lang('FormulaExample'));
$form->addElement('text', 'formula', get_lang('Formula'), array('id' => 'formula'));
$form->addRule('formula', get_lang('GiveFormula'), 'required');
@ -181,7 +179,7 @@ class CalculatedAnswer extends Question
* abstract function which creates the form to create / edit the answers of the question
* @param FormValidator $form
*/
function processAnswersCreation($form)
public function processAnswersCreation($form)
{
if (!self::isAnswered()) {
$table = Database::get_course_table(TABLE_QUIZ_ANSWER);
@ -200,6 +198,7 @@ class CalculatedAnswer extends Question
$highestValues = $form->getSubmitValue('highestValue');
$answerVariations = $form->getSubmitValue('answerVariations');
$this->weighting = $form->getSubmitValue('weighting');
// Create as many answers as $answerVariations
for ($j=0 ; $j < $answerVariations; $j++) {
$auxAnswer = $answer;
@ -247,7 +246,7 @@ class CalculatedAnswer extends Question
* @param null $score
* @return null|string
*/
function return_header($feedback_type = null, $counter = null, $score = null)
public function return_header($feedback_type = null, $counter = null, $score = null)
{
$header = parent::return_header($feedback_type, $counter, $score);
$header .= '<table class="'.$this->question_table_class .'">

@ -1,6 +1,8 @@
<?php
/* For licensing terms, see /license.txt */
use ChamiloSession as Session;
/**
* Class Exercise
*
@ -160,9 +162,7 @@ class Exercise
$this->display_category_name = $object->display_category_name;
$this->pass_percentage = $object->pass_percentage;
$this->sessionId = $object->session_id;
$this->is_gradebook_locked = api_resource_is_locked_by_gradebook($id, LINK_EXERCISE);
$this->review_answers = (isset($object->review_answers) && $object->review_answers == 1) ? true : false;
$this->globalCategoryId = isset($object->global_category_id) ? $object->global_category_id : null;
$this->questionSelectionType = isset($object->question_selection_type) ? $object->question_selection_type : null;
@ -1114,7 +1114,6 @@ class Exercise
}
return $this->questionList;
}
/**
@ -3108,7 +3107,8 @@ class Exercise
$from_database = false,
$show_result = true,
$propagate_neg = 0,
$hotspot_delineation_result = array()
$hotspot_delineation_result = array(),
$showTotalScoreAndUserChoices = false
) {
global $debug;
//needed in order to use in the exercise_attempt() for the time
@ -3423,7 +3423,7 @@ class Exercise
$real_answers[$answerId] = false;
}
} else {
$studentChoice = $choice[$answerAutoId];
$studentChoice = isset($choice[$answerAutoId]) ? $choice[$answerAutoId] : '';
if ($answerCorrect == $studentChoice) {
//$answerCorrect = 1;
$real_answers[$answerId] = true;
@ -3715,11 +3715,18 @@ class Exercise
$listCorrectAnswers
);
}
break;
// for calculated answer
case CALCULATED_ANSWER:
$answer = $objAnswerTmp->selectAnswer($_SESSION['calculatedAnswerId'][$questionId]);
$calculatedAnswerId = Session::read('calculatedAnswerId');
$answer = '';
if ($calculatedAnswerId) {
$calculatedAnswerInfo = Session::read('calculatedAnswerInfo');
if (isset($calculatedAnswerInfo[$questionId])) {
$answer = $calculatedAnswerInfo[$questionId];
} else {
$answer = $objAnswerTmp->selectAnswer($calculatedAnswerId[$questionId]);
}
}
$preArray = explode('@@', $answer);
$last = count($preArray) - 1;
$answer = '';
@ -3785,6 +3792,18 @@ class Exercise
}
$answer = '';
$realCorrectTags = $correctTags;
if ($from_database && empty($calculatedAnswerId)) {
$queryfill = "SELECT answer, marks FROM ".$TBL_TRACK_ATTEMPT."
WHERE
exe_id = '".$exeId."' AND
question_id= ".intval($questionId) ;
$resfill = Database::query($queryfill);
$rowFill = Database::fetch_assoc($resfill);
$answer = $rowFill['answer'];
$questionScore = $rowFill['marks'];
}
for ($i = 0; $i < count($realCorrectTags); $i++) {
if ($i == 0) {
$answer .= $realText[0];
@ -3807,13 +3826,27 @@ class Exercise
$answer .= ''; // remove &nbsp; that causes issue
}
// adds the correct word, followed by ] to close the blank
$answer .= ' / <font color="green"><b>' . $realCorrectTags[$i] . '</b></font>]';
$addCorrecWord = true;
if (
Session::has('objExercise') &&
Session::read('objExercise')->selectResultsDisabled() == EXERCISE_FEEDBACK_TYPE_EXAM
) {
$addCorrecWord = false;
}
if ($addCorrecWord) {
// adds the correct word, followed by ] to close the blank
$answer .= ' / <font color="green"><b>' . $realCorrectTags[$i] . '</b></font>';
}
$answer .= ']';
if (isset($realText[$i +1])) {
$answer .= $realText[$i +1];
}
}
break;
// for free answer
case FREE_ANSWER:
if ($from_database) {
$query = "SELECT answer, marks FROM ".$TBL_TRACK_ATTEMPT."
@ -3954,12 +3987,15 @@ class Exercise
}
if ($show_result) {
if ($showTotalScoreAndUserChoices == true) {
$user_answer = '';
}
echo '<tr>';
echo '<td>' . $s_answer_label . '</td>';
echo '<td>' . $user_answer;
if (in_array($answerType, [MATCHING, MATCHING_DRAGGABLE])) {
if (isset($real_list[$i_answer_correct_answer])) {
if (isset($real_list[$i_answer_correct_answer]) && $showTotalScoreAndUserChoices == false) {
echo Display::span(
$real_list[$i_answer_correct_answer],
['style' => 'color: #008000; font-weight: bold;']
@ -4107,15 +4143,11 @@ class Exercise
} // end switch Answertype
if ($show_result) {
if ($debug) error_log('show result '.$show_result);
if ($debug) error_log('Showing questions $from '.$from);
if ($from == 'exercise_result') {
if ($debug) error_log('Showing questions $from '.$from);
//display answers (if not matching type, or if the answer is correct)
if (
!in_array(
$answerType,
[MATCHING, DRAGGABLE, MATCHING_DRAGGABLE]
) ||
!in_array($answerType, [MATCHING, DRAGGABLE, MATCHING_DRAGGABLE]) ||
$answerCorrect
) {
if (
@ -4131,7 +4163,6 @@ class Exercise
)
)
) {
//if ($origin != 'learnpath') {
ExerciseShowFunctions::display_unique_or_multiple_answer(
$feedback_type,
$answerType,
@ -4142,11 +4173,10 @@ class Exercise
0,
0,
0,
$results_disabled
$results_disabled,
$showTotalScoreAndUserChoices
);
//}
} elseif ($answerType == MULTIPLE_ANSWER_TRUE_FALSE) {
//if ($origin!='learnpath') {
ExerciseShowFunctions::display_multiple_answer_true_false(
$feedback_type,
$answerType,
@ -4157,11 +4187,10 @@ class Exercise
0,
$questionId,
0,
$results_disabled
$results_disabled,
$showTotalScoreAndUserChoices
);
//}
} elseif ($answerType == MULTIPLE_ANSWER_COMBINATION_TRUE_FALSE ) {
// if ($origin!='learnpath') {
ExerciseShowFunctions::display_multiple_answer_combination_true_false(
$feedback_type,
$answerType,
@ -4172,40 +4201,48 @@ class Exercise
0,
0,
0,
$results_disabled
$results_disabled,
$showTotalScoreAndUserChoices
);
//}
} elseif ($answerType == FILL_IN_BLANKS) {
//if ($origin!='learnpath') {
ExerciseShowFunctions::display_fill_in_blanks_answer($feedback_type, $answer,0,0, $results_disabled);
// }
ExerciseShowFunctions::display_fill_in_blanks_answer(
$feedback_type,
$answer,
0,
0,
$results_disabled,
'',
$showTotalScoreAndUserChoices
);
} elseif ($answerType == CALCULATED_ANSWER) {
//if ($origin!='learnpath') {
ExerciseShowFunctions::display_calculated_answer($feedback_type, $answer,0,0);
// }
ExerciseShowFunctions::display_calculated_answer(
$feedback_type,
$answer,
0,
0,
$results_disabled,
$showTotalScoreAndUserChoices
);
} elseif ($answerType == FREE_ANSWER) {
//if($origin != 'learnpath') {
ExerciseShowFunctions::display_free_answer(
$feedback_type,
$choice,
$exeId,
$questionId,
$questionScore
$questionScore,
$results_disabled
);
//}
} elseif ($answerType == ORAL_EXPRESSION) {
// to store the details of open questions in an array to be used in mail
//if ($origin != 'learnpath') {
ExerciseShowFunctions::display_oral_expression_answer(
$feedback_type,
$choice,
0,
0,
$objQuestionTmp->getFileUrl()
$nano,
$results_disabled
);
//}
} elseif ($answerType == HOT_SPOT) {
//if ($origin != 'learnpath') {
foreach ($orderedHotspots as $correctAnswerId => $hotspot) {
if ($hotspot->getHotspotAnswerId() == $answerAutoId) {
break;
@ -4219,11 +4256,10 @@ class Exercise
$studentChoice,
$answerComment,
$results_disabled,
$answerId
$answerId,
$showTotalScoreAndUserChoices
);
// }
} elseif ($answerType == HOT_SPOT_ORDER) {
//if ($origin != 'learnpath') {
ExerciseShowFunctions::display_hotspot_order_answer(
$feedback_type,
$answerId,
@ -4231,7 +4267,6 @@ class Exercise
$studentChoice,
$answerComment
);
//}
} elseif ($answerType == HOT_SPOT_DELINEATION) {
$user_answer = $_SESSION['exerciseResultCoordinates'][$questionId];
@ -4425,7 +4460,8 @@ class Exercise
$exeId,
$questionId,
$answerId,
$results_disabled
$results_disabled,
$showTotalScoreAndUserChoices
);
} else {
ExerciseShowFunctions::display_unique_or_multiple_answer(
@ -4437,8 +4473,9 @@ class Exercise
$answerCorrect,
$exeId,
$questionId,
"",
$results_disabled
'',
$results_disabled,
$showTotalScoreAndUserChoices
);
}
break;
@ -4454,7 +4491,8 @@ class Exercise
$exeId,
$questionId,
$answerId,
$results_disabled
$results_disabled,
$showTotalScoreAndUserChoices
);
} else {
ExerciseShowFunctions::display_multiple_answer_combination_true_false(
@ -4466,8 +4504,9 @@ class Exercise
$answerCorrect,
$exeId,
$questionId,
"",
$results_disabled
'',
$results_disabled,
$showTotalScoreAndUserChoices
);
}
break;
@ -4483,7 +4522,8 @@ class Exercise
$exeId,
$questionId,
$answerId,
$results_disabled
$results_disabled,
$showTotalScoreAndUserChoices
);
} else {
ExerciseShowFunctions::display_multiple_answer_true_false(
@ -4495,8 +4535,9 @@ class Exercise
$answerCorrect,
$exeId,
$questionId,
"",
$results_disabled
'',
$results_disabled,
$showTotalScoreAndUserChoices
);
}
break;
@ -4507,7 +4548,8 @@ class Exercise
$exeId,
$questionId,
$results_disabled,
$str
$str,
$showTotalScoreAndUserChoices
);
break;
case CALCULATED_ANSWER:
@ -4515,7 +4557,10 @@ class Exercise
$feedback_type,
$answer,
$exeId,
$questionId
$questionId,
$results_disabled,
'',
$showTotalScoreAndUserChoices
);
break;
case FREE_ANSWER:
@ -4524,7 +4569,8 @@ class Exercise
$choice,
$exeId,
$questionId,
$questionScore
$questionScore,
$results_disabled
);
break;
case ORAL_EXPRESSION:
@ -4534,7 +4580,8 @@ class Exercise
$choice,
$exeId,
$questionId,
$objQuestionTmp->getFileUrl()
$objQuestionTmp->getFileUrl(),
$results_disabled
) . '</td>
</tr>
</table>';
@ -4546,7 +4593,9 @@ class Exercise
$answer,
$studentChoice,
$answerComment,
$results_disabled);
$results_disabled,
$answerId
);
break;
case HOT_SPOT_DELINEATION:
$user_answer = $user_array;
@ -5636,7 +5685,7 @@ class Exercise
}
//3. We check if the time limits are on
if ((!empty($this->start_time)) || (!empty($this->end_time))) {
if (!empty($this->start_time) || !empty($this->end_time)) {
$limitTimeExists = true;
} else {
$limitTimeExists = false;
@ -5995,16 +6044,17 @@ class Exercise
$questionList = array();
$tabCategoryQuestions = TestCategory::getQuestionsByCat($this->id);
$isRandomByCategory = $this->selectRandomByCat();
// on tri les categories en fonction du terme entre [] en tete de la description de la categorie
/*
* ex de catégories :
// We sort categories based on the term between [] in the head
// of the category's description
/* examples of categories :
* [biologie] Maitriser les mecanismes de base de la genetique
* [biologie] Relier les moyens de depenses et les agents infectieux
* [biologie] Savoir ou est produite l'enrgie dans les cellules et sous quelle forme
* [chimie] Classer les molles suivant leur pouvoir oxydant ou reacteur
* [chimie] Connaître la denition de la theoie acide/base selon Brönsted
* [chimie] Connaître les charges des particules
* On veut dans l'ordre des groupes definis par le terme entre crochet au debut du titre de la categorie
* We want that in the order of the groups defined by the term
* between brackets at the beginning of the category title
*/
// If test option is Grouped By Categories
if ($isRandomByCategory == 2) {
@ -7368,7 +7418,6 @@ class Exercise
$selected = 'selected="selected"';
$selectedValue = $val['id'];
}
//$s .= '<option value="'.$val['id'].'" '.$selected.'>'.$val['letter'].'</option>';
$s .= '<option value="'.$item.'" '.$selected.'>'.$val['letter'].'</option>';
$item++;
}
@ -7382,7 +7431,6 @@ class Exercise
</script>';
}
if (isset($select_items[$lines_count])) {
$s.= '<div id="window_'.$windowId.'_answer" class="">
<b>'.$select_items[$lines_count]['letter'].'.</b> '.$select_items[$lines_count]['answer'].'

@ -236,7 +236,7 @@ foreach ($question_list as $questionId) {
$table .= Display::div($question_title, array('class'=>'exercise_reminder_item'));
} // end foreach() block that loops over all questions
echo Display::div($table, array('class'=>'span10'));
echo Display::div($table, array('class'=>'question-check-test'));
$exercise_actions = Display::url(get_lang('EndTest'), 'javascript://', array('onclick'=>'final_submit();', 'class'=>'btn btn-warning'));
$exercise_actions .= '&nbsp;'.Display::url(get_lang('ReviewQuestions'), 'javascript://', array('onclick'=>'review_questions();','class'=>'btn btn-success'));

@ -174,7 +174,7 @@ if (!empty($exercise_stat_info)) {
$max_score = $objExercise->get_max_score();
Display :: display_normal_message(get_lang('Saved').'<br />',false);
Display::display_normal_message(get_lang('Saved').'<br />',false);
// Display and save questions
ExerciseLib::display_question_list_by_attempt($objExercise, $exe_id, true);
@ -199,8 +199,9 @@ if ($origin != 'learnpath') {
if (api_is_allowed_to_session_edit()) {
Session::erase('objExercise');
Session::erase('exe_id');
Session::erase('calculatedAnswerId');
Session::erase('calculatedAnswerInfo');
}
Display::display_footer();
} else {
$lp_mode = isset($_SESSION['lp_mode']) ? $_SESSION['lp_mode'] : null;
@ -210,6 +211,8 @@ if ($origin != 'learnpath') {
if (api_is_allowed_to_session_edit()) {
Session::erase('objExercise');
Session::erase('exe_id');
Session::erase('calculatedAnswerId');
Session::erase('calculatedAnswerInfo');
}
// Record the results in the learning path, using the SCORM interface (API)

@ -1,6 +1,8 @@
<?php
/* For licensing terms, see /license.txt */
use ChamiloSession as Session;
/**
* Shows the exercise results
*
@ -12,8 +14,6 @@
*
*/
use ChamiloSession as Session;
require_once '../inc/global.inc.php';
$debug = false;
if (empty($origin) ) {
@ -27,10 +27,10 @@ if ($origin == 'learnpath') {
}
// Database table definitions
$TBL_EXERCISE_QUESTION = Database::get_course_table(TABLE_QUIZ_TEST_QUESTION);
$TBL_QUESTIONS = Database::get_course_table(TABLE_QUIZ_QUESTION);
$TBL_TRACK_EXERCISES = Database::get_main_table(TABLE_STATISTIC_TRACK_E_EXERCISES);
$TBL_TRACK_ATTEMPT = Database::get_main_table(TABLE_STATISTIC_TRACK_E_ATTEMPT);
$TBL_EXERCISE_QUESTION = Database::get_course_table(TABLE_QUIZ_TEST_QUESTION);
$TBL_QUESTIONS = Database::get_course_table(TABLE_QUIZ_QUESTION);
$TBL_TRACK_EXERCISES = Database::get_main_table(TABLE_STATISTIC_TRACK_E_EXERCISES);
$TBL_TRACK_ATTEMPT = Database::get_main_table(TABLE_STATISTIC_TRACK_E_ATTEMPT);
// General parameters passed via POST/GET
if ($debug) { error_log('Entered exercise_result.php: '.print_r($_POST,1)); }
@ -77,13 +77,13 @@ if (empty($track_exercise_info)) {
api_not_allowed(true);
}
$exercise_id = $track_exercise_info['id'];
$exercise_date = $track_exercise_info['start_date'];
$student_id = $track_exercise_info['exe_user_id'];
$learnpath_id = $track_exercise_info['orig_lp_id'];
$learnpath_item_id = $track_exercise_info['orig_lp_item_id'];
$lp_item_view_id = $track_exercise_info['orig_lp_item_view_id'];
$current_user_id = api_get_user_id();
$exercise_id = $track_exercise_info['id'];
$exercise_date = $track_exercise_info['start_date'];
$student_id = $track_exercise_info['exe_user_id'];
$learnpath_id = $track_exercise_info['orig_lp_id'];
$learnpath_item_id = $track_exercise_info['orig_lp_item_id'];
$lp_item_view_id = $track_exercise_info['orig_lp_item_view_id'];
$current_user_id = api_get_user_id();
if (api_is_excluded_user_type(true, $student_id)) {
api_not_allowed(true);
@ -116,7 +116,7 @@ $fromlink = '';
$interbreadcrumb[]= array("url" => "exercise.php?".api_get_cidreq(),"name" => get_lang('Exercises'));
$interbreadcrumb[]= array("url" => "overview.php?exerciseId=".$exercise_id.'&'.api_get_cidreq(),"name" => $objExercise->name);
$interbreadcrumb[]= array("url" => "#","name" => get_lang('Result'));
$interbreadcrumb[]= array("url" => "#", "name" => get_lang('Result'));
$this_section = SECTION_COURSES;
@ -174,14 +174,16 @@ function getFCK(vals,marksid) {
<?php
$show_results = true;
$show_only_total_score = false;
$showTotalScoreAndUserChoices = true;
// Avoiding the "Score 0/0" message when the exe_id is not set
if (!empty($track_exercise_info)) {
// if the results_disabled of the Quiz is 1 when block the script
$result_disabled = $track_exercise_info['results_disabled'];
if (!(api_is_platform_admin() || api_is_course_admin() || api_is_course_coach()) ) {
if ($result_disabled == 1) {
if (true) {
//if (!(api_is_platform_admin() || api_is_course_admin() || api_is_course_coach()) ) {
if ($result_disabled == RESULT_DISABLE_NO_SCORE_AND_EXPECTED_ANSWERS) {
$show_results = false;
if ($origin != 'learnpath') {
echo '<table width="100%" border="0" cellspacing="0" cellpadding="0">
@ -195,7 +197,7 @@ if (!empty($track_exercise_info)) {
</tr>
</table>';
}
} elseif ($result_disabled == 2) {
} elseif ($result_disabled == RESULT_DISABLE_SHOW_SCORE_ONLY) {
$show_results = false;
$show_only_total_score = true;
if ($origin != 'learnpath') {
@ -207,6 +209,26 @@ if (!empty($track_exercise_info)) {
</tr>
</table>';
}
} elseif ($result_disabled == RESULT_DISABLE_SHOW_SCORE_ATTEMPT_SHOW_ANSWERS_LAST_ATTEMPT) {
$attempts = Event::getExerciseResultsByUser(
api_get_user_id(),
$objExercise->id,
api_get_course_int_id(),
api_get_session_id(),
$track_exercise_info['orig_lp_id'],
$track_exercise_info['orig_lp_item_id'],
'desc'
);
$numberAttempts = count($attempts);
if ($numberAttempts >= $track_exercise_info['max_attempt']) {
$show_results = true;
$show_only_total_score = true;
$showTotalScoreAndUserChoices = false;
} else {
$show_results = true;
$show_only_total_score = true;
$showTotalScoreAndUserChoices = true;
}
}
}
} else {
@ -218,7 +240,7 @@ if ($origin == 'learnpath' && !isset($_GET['fb_type']) ) {
$show_results = false;
}
if ($show_results || $show_only_total_score) {
if ($show_results || $show_only_total_score || $showTotalScoreAndUserChoices) {
$user_info = api_get_user_info($student_id);
//Shows exercise header
echo $objExercise->show_exercise_result_header(
@ -237,7 +259,7 @@ if ($debug > 0) {
}
$arrques = array();
$arrans = array();
$arrans = array();
$user_restriction = $is_allowedToEdit ? '' : "AND user_id=".intval($student_id)." ";
$sql = "SELECT attempts.question_id, answer
@ -300,7 +322,6 @@ foreach ($questionList as $questionId) {
$counter = 1;
$exercise_content = null;
$category_list = array();
$useAdvancedEditor = true;
if (!empty($maxEditors) && count($questionList) > $maxEditors) {
@ -313,17 +334,15 @@ foreach ($questionList as $questionId) {
// destruction of the Question object
unset($objQuestionTmp);
// creates a temporary Question object
$objQuestionTmp = Question::read($questionId);
$questionWeighting = $objQuestionTmp->selectWeighting();
$answerType = $objQuestionTmp->selectType();
// creates a temporary Question object
$objQuestionTmp = Question::read($questionId);
$questionWeighting = $objQuestionTmp->selectWeighting();
$answerType = $objQuestionTmp->selectType();
// Start buffer
ob_start();
/* Use switch
switch ($answerType) {
}*/
// Use switch
if ($answerType == MULTIPLE_ANSWER || $answerType == MULTIPLE_ANSWER_TRUE_FALSE) {
$question_result = $objExercise->manage_answer(
@ -335,7 +354,9 @@ foreach ($questionList as $questionId) {
false,
true,
$show_results,
$objExercise->selectPropagateNeg()
$objExercise->selectPropagateNeg(),
[],
$showTotalScoreAndUserChoices
);
$questionScore = $question_result['score'];
$totalScore += $question_result['score'];
@ -350,7 +371,9 @@ foreach ($questionList as $questionId) {
false,
true,
$show_results,
$objExercise->selectPropagateNeg()
$objExercise->selectPropagateNeg(),
[],
$showTotalScoreAndUserChoices
);
$questionScore = $question_result['score'];
$totalScore += $question_result['score'];
@ -364,7 +387,9 @@ foreach ($questionList as $questionId) {
false,
true,
$show_results,
$objExercise->selectPropagateNeg()
$objExercise->selectPropagateNeg(),
[],
$showTotalScoreAndUserChoices
);
$questionScore = $question_result['score'];
$totalScore += $question_result['score'];
@ -379,7 +404,25 @@ foreach ($questionList as $questionId) {
false,
true,
$show_results,
$objExercise->selectPropagateNeg()
$objExercise->selectPropagateNeg(),
[],
$showTotalScoreAndUserChoices
);
$questionScore = $question_result['score'];
$totalScore += $question_result['score'];
} elseif ($answerType == CALCULATED_ANSWER) {
$question_result = $objExercise->manage_answer(
$id,
$questionId,
$choice,
'exercise_show',
array(),
false,
true,
$show_results,
$objExercise->selectPropagateNeg(),
[],
$showTotalScoreAndUserChoices
);
$questionScore = $question_result['score'];
$totalScore += $question_result['score'];
@ -393,7 +436,9 @@ foreach ($questionList as $questionId) {
false,
true,
$show_results,
$objExercise->selectPropagateNeg()
$objExercise->selectPropagateNeg(),
[],
$showTotalScoreAndUserChoices
);
$questionScore = $question_result['score'];
$totalScore += $question_result['score'];
@ -407,7 +452,9 @@ foreach ($questionList as $questionId) {
false,
true,
$show_results,
$objExercise->selectPropagateNeg()
$objExercise->selectPropagateNeg(),
[],
$showTotalScoreAndUserChoices
);
$questionScore = $question_result['score'];
$totalScore += $question_result['score'];
@ -421,7 +468,9 @@ foreach ($questionList as $questionId) {
false,
true,
$show_results,
$objExercise->selectPropagateNeg()
$objExercise->selectPropagateNeg(),
[],
$showTotalScoreAndUserChoices
);
$questionScore = $question_result['score'];
$totalScore += $question_result['score'];
@ -435,12 +484,14 @@ foreach ($questionList as $questionId) {
false,
true,
$show_results,
$objExercise->selectPropagateNeg()
$objExercise->selectPropagateNeg(),
[],
$showTotalScoreAndUserChoices
);
$questionScore = $question_result['score'];
$totalScore += $question_result['score'];
} elseif ($answerType == HOT_SPOT) {
if ($show_results) {
if ($show_results || $showTotalScoreAndUserChoices) {
echo '<table width="500" border="0"><tr>
<td valign="top" align="center" style="padding-left:0px;" >
<table border="1" bordercolor="#A4A4A4" style="border-collapse: collapse;" width="552">';
@ -454,7 +505,9 @@ foreach ($questionList as $questionId) {
false,
true,
$show_results,
$objExercise->selectPropagateNeg()
$objExercise->selectPropagateNeg(),
[],
$showTotalScoreAndUserChoices
);
$questionScore = $question_result['score'];
$totalScore += $question_result['score'];
@ -495,7 +548,9 @@ foreach ($questionList as $questionId) {
true,
$show_results,
$objExercise->selectPropagateNeg(),
'database'
'database',
[],
$showTotalScoreAndUserChoices
);
$questionScore = $question_result['score'];
@ -610,7 +665,8 @@ foreach ($questionList as $questionId) {
}
//showing the score
$queryfree = "select marks from ".$TBL_TRACK_ATTEMPT." WHERE exe_id = ".intval($id)." and question_id= ".intval($questionId)."";
$queryfree = "SELECT marks FROM ".$TBL_TRACK_ATTEMPT."
WHERE exe_id = ".intval($id)." and question_id= ".intval($questionId)."";
$resfree = Database::query($queryfree);
$questionScore= Database::result($resfree,0,"marks");
$totalScore+=$questionScore;
@ -675,7 +731,13 @@ foreach ($questionList as $questionId) {
}
}
echo '<br />';
echo Display::url($url_name, 'javascript://', array('class' => 'btn', 'onclick'=>"showfck('".$name."', '".$marksname."');"));
echo Display::url(
$url_name,
'javascript://',
array(
'class' => 'btn btn-default',
'onclick' => "showfck('".$name."', '".$marksname."');")
);
echo '<br />';
echo '<div id="feedback_'.$name.'" style="width:100%">';
@ -756,7 +818,7 @@ foreach ($questionList as $questionId) {
}
}
$my_total_score = $questionScore;
$my_total_score = $questionScore;
$my_total_weight = $questionWeighting;
$totalWeighting += $questionWeighting;
$category_was_added_for_this_test = false;
@ -804,9 +866,9 @@ foreach ($questionList as $questionId) {
$score = array();
if ($show_results) {
$score['result'] = get_lang('Score')." : ".ExerciseLib::show_score($my_total_score, $my_total_weight, false, false);
$score['pass'] = $my_total_score >= $my_total_weight ? true : false;
$score['type'] = $answerType;
$score['score'] = $my_total_score;
$score['pass'] = $my_total_score >= $my_total_weight ? true : false;
$score['type'] = $answerType;
$score['score'] = $my_total_score;
$score['weight'] = $my_total_weight;
$score['comments'] = isset($comnt) ? $comnt : null;
}
@ -815,11 +877,9 @@ foreach ($questionList as $questionId) {
$i++;
$contents = ob_get_clean();
$question_content = '<div class="question_row">';
if ($show_results) {
//Shows question title an description
// Shows question title an description
$question_content .= $objQuestionTmp->return_header(null, $counter, $score);
}
$counter++;
@ -832,7 +892,7 @@ $total_score_text = null;
//Total score
if ($origin!='learnpath' || ($origin == 'learnpath' && isset($_GET['fb_type']))) {
if ($show_results || $show_only_total_score) {
if ($show_results || $show_only_total_score || $showTotalScoreAndUserChoices) {
$total_score_text .= '<div class="question_row">';
$my_total_score_temp = $totalScore;
if ($objExercise->selectPropagateNeg() == 0 && $my_total_score_temp < 0) {
@ -848,7 +908,7 @@ if ($origin!='learnpath' || ($origin == 'learnpath' && isset($_GET['fb_type'])))
}
}
if (!empty($category_list) && ($show_results || $show_only_total_score)) {
if (!empty($category_list) && ($show_results || $show_only_total_score || $showTotalScoreAndUserChoices)) {
// Adding total
$category_list['total'] = array(
'score' => $my_total_score_temp,

@ -254,7 +254,7 @@ class FillBlanks extends Question
$form->addElement(
'html_editor',
'answer',
Display::returnIconPath('fill_field.png'),
Display::return_icon('fill_field.png'),
['id' => 'answer', 'onkeyup' => "javascript: updateBlanks(this);"],
array('ToolbarSet' => 'TestQuestionDescription')
);
@ -725,7 +725,7 @@ class FillBlanks extends Question
return $listAnswerResults;
}
/**
* Return an array of student state answers for fill the blank questions
* for each students that answered the question
@ -1037,14 +1037,23 @@ class FillBlanks extends Question
* return the HTML display of the answer
* @param string $answer
* @param bool $resultsDisabled
* @param bool $showTotalScoreAndUserChoices
*
* @return string
*/
public static function getHtmlDisplayForAnswer($answer, $resultsDisabled = false)
public static function getHtmlDisplayForAnswer($answer, $resultsDisabled = false, $showTotalScoreAndUserChoices = false)
{
$result = "";
$result = '';
$listStudentAnswerInfo = self::getAnswerInfo($answer, true);
if ($resultsDisabled == RESULT_DISABLE_SHOW_SCORE_ATTEMPT_SHOW_ANSWERS_LAST_ATTEMPT) {
if ($showTotalScoreAndUserChoices) {
$resultsDisabled = true;
} else {
$resultsDisabled = false;
}
}
// rebuild the answer with good HTML style
// this is the student answer, right or wrong
for ($i=0; $i < count($listStudentAnswerInfo['studentanswer']); $i++) {
@ -1094,7 +1103,7 @@ class FillBlanks extends Question
$type = FillBlanks::getFillTheBlankAnswerType($correct);
switch ($type) {
case self::FILL_THE_BLANK_MENU:
$correctAnswerHtml = "";
$correctAnswerHtml = '';
$listPossibleAnswers = FillBlanks::getFillTheBlankMenuAnswers($correct, false);
$correctAnswerHtml .= "<span style='color: green'>".$listPossibleAnswers[0]."</span>";
$correctAnswerHtml .= " <span style='font-weight:normal'>(";

@ -45,7 +45,12 @@ class GlobalMultipleAnswer extends Question
$html .='<th>' . get_lang('Comment') . '</th>';
$html .='</tr>';
$form->addElement('label', get_lang('Answers') . '<br /> '.Display::returnIconPath('fill_field.png'), $html);
$form->addElement(
'label',
get_lang('Answers') .
'<br /> '.Display::return_icon('fill_field.png'),
$html
);
$defaults = array();
$correct = 0;
$answer = false;

@ -116,13 +116,15 @@ while ($hotspot = Database::fetch_assoc($result))
$attemptList = Event::getAllExerciseEventByExeId($exerciseId);
if (!empty($attemptList)) {
$questionAttempt = $attemptList[$questionId][0];
if (isset($attemptList[$questionId])) {
$questionAttempt = $attemptList[$questionId][0];
if (!empty($questionAttempt['answer'])) {
$coordinates = explode('|', $questionAttempt['answer']);
if (!empty($questionAttempt['answer'])) {
$coordinates = explode('|', $questionAttempt['answer']);
foreach ($coordinates as $coordinate) {
$data['answers'][] = Geometry::decodePoint($coordinate);
foreach ($coordinates as $coordinate) {
$data['answers'][] = Geometry::decodePoint($coordinate);
}
}
}
}

@ -171,7 +171,7 @@ if ($current_browser == 'Internet Explorer') {
$blockShowAnswers = false;
if ($objExercise->results_disabled == RESULT_DISABLE_SHOW_SCORE_ATTEMPT_SHOW_ANSWERS_LAST_ATTEMPT) {
if (count($attempts) < $objExercise->attempts ) {
if (count($attempts) < $objExercise->attempts) {
$blockShowAnswers = true;
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 KiB

After

Width:  |  Height:  |  Size: 2.0 KiB

File diff suppressed because it is too large Load Diff

Before

Width:  |  Height:  |  Size: 80 KiB

After

Width:  |  Height:  |  Size: 53 KiB

@ -351,8 +351,7 @@ switch ($action) {
continue;
}
$my_choice = isset($choice[$my_question_id]) ?
$choice[$my_question_id] : null;
$my_choice = isset($choice[$my_question_id]) ? $choice[$my_question_id] : null;
if ($debug) {
error_log("my_choice = ".print_r($my_choice, 1)."");
@ -362,7 +361,7 @@ switch ($action) {
$objQuestionTmp = Question::read($my_question_id, $course_id);
// Getting free choice data.
if ($objQuestionTmp->type == FREE_ANSWER && $type == 'all') {
if ($objQuestionTmp->type == FREE_ANSWER && $type == 'all') {
$my_choice = isset($_REQUEST['free_choice'][$my_question_id]) && !empty($_REQUEST['free_choice'][$my_question_id]) ? $_REQUEST['free_choice'][$my_question_id]: null;
}

@ -23,6 +23,14 @@
// Showing/hiding error codes in global error messages.
define('SHOW_ERROR_CODES', false);
// Make sure the CHAMILO_LOAD_WYSIWYG constant is defined
// To remove CKeditor libs from HTML, set this constant to true before loading
// global.inc.php
if (!defined('CHAMILO_LOAD_WYSIWYG')) {
define('CHAMILO_LOAD_WYSIWYG', true);
}
// Include the libraries that are necessary everywhere
require_once __DIR__.'/../../vendor/autoload.php';
require_once __DIR__.'/../../app/AppKernel.php';
@ -434,8 +442,7 @@ if (!empty($valid_languages)) {
$language_interface = api_get_language_from_type($language_priority4);
} else {
$language_interface = api_get_setting('platformLanguage');
}
}
if (!empty($language_priority3) && api_get_language_from_type($language_priority3) !== false) {
$language_interface = api_get_language_from_type($language_priority3);

@ -5711,23 +5711,29 @@ function api_is_in_course($course_code = null) {
* @return boolean
* @author Ivan Tcholakov
*/
function api_is_in_group($group_id = null, $course_code = null) {
if (!empty($course_code)) {
if (isset($_SESSION['_course']['sysCode'])) {
if ($course_code != $_SESSION['_course']['sysCode']) return false;
function api_is_in_group($groupIdParam = null, $courseCodeParam = null)
{
if (!empty($courseCodeParam)) {
$courseCode = api_get_course_id();
if (!empty($courseCode)) {
if ($courseCodeParam != $courseCode) {
return false;
}
} else {
return false;
}
}
if (isset($_SESSION['_gid']) && $_SESSION['_gid'] != '') {
if (!empty($group_id)) {
return $group_id == $_SESSION['_gid'];
$groupId = api_get_group_id();
if (isset($groupId) && $groupId != '') {
if (!empty($groupIdParam)) {
return $groupIdParam == $groupId;
} else {
return true;
}
}
return false;
}

@ -316,12 +316,15 @@ class CourseManager
* @param int $user_id
* @param string $course_code
*
* @return int the status of the user in that course
* @return int|bool the status of the user in that course (or false if the user is not in that course)
*/
public static function get_user_in_course_status($user_id, $course_code)
{
$courseInfo = api_get_course_info($course_code);
$courseId = $courseInfo['real_id'];
if (empty($courseId)) {
return false;
}
$result = Database::fetch_array(
Database::query(
"SELECT status FROM " . Database::get_main_table(TABLE_MAIN_COURSE_USER) . "

@ -27,8 +27,7 @@ class Diagnoser
public function show_html()
{
$sections = array('chamilo', 'php', 'database', 'webserver', 'paths');
$currentSection = isset($_GET['section']) ? $_GET['section'] : 'chamilo';
$sections = array('chamilo', 'php', 'database', 'webserver');
if (!in_array(trim($currentSection), $sections)) {
$currentSection = 'chamilo';
@ -143,6 +142,35 @@ class Diagnoser
$app_version = api_get_setting('chamilo_database_version');
$array[] = $this->build_setting(self :: STATUS_INFORMATION, '[DB]', 'chamilo_database_version', '#', $app_version, 0, null, 'Chamilo DB version');
$access_url_id = api_get_current_access_url_id();
if ($access_url_id === 1) {
global $_configuration;
$message2 = '';
if ($access_url_id === 1) {
if (api_is_windows_os()) {
$message2 .= get_lang('SpaceUsedOnSystemCannotBeMeasuredOnWindows');
} else {
$dir = api_get_path(SYS_PATH);
$du = exec('du -sh ' . $dir, $err);
list($size, $none) = explode("\t", $du);
$limit = $_configuration[$access_url_id]['hosting_limit_disk_space'];
$message2 .= sprintf(get_lang('TotalSpaceUsedByPortalXLimitIsYMB'), $size, $limit);
}
}
$array[] = $this->build_setting(
self :: STATUS_OK,
'[FILES]',
'hosting_limit_disk_space',
'#',
$size,
0,
null,
$message2
);
}
return $array;
}

@ -773,7 +773,7 @@ class Display
// it checks if there is an SVG version. If so, it uses it.
// When moving this to production, the return_icon() calls should
// ask for the SVG version directly
/*$testServer = api_get_setting('server_type');
$testServer = api_get_setting('server_type');
if ($testServer == 'test' && $return_only_path == false) {
$svgImage = substr($image, 0, -3) . 'svg';
if (is_file($code_path . $theme . 'svg/' . $svgImage)) {
@ -788,7 +788,7 @@ class Display
if (empty($additional_attributes['width'])) {
$additional_attributes['width'] = $size;
}
}*/
}
$icon = api_get_cdn_path($icon);

@ -89,6 +89,13 @@ class ExerciseLib
$objAnswerTmp = new Answer($questionId);
$nbrAnswers = $objAnswerTmp->selectNbrAnswers();
if ($answerType == FREE_ANSWER ||
$answerType == ORAL_EXPRESSION ||
$answerType == CALCULATED_ANSWER
) {
$nbrAnswers = 1;
}
$quiz_question_options = Question::readQuestionOption(
$questionId,
$course_id
@ -615,6 +622,7 @@ class ExerciseLib
$s .= $answer;
} elseif ($answerType == CALCULATED_ANSWER) {
/*
* In the CALCULATED_ANSWER test
* you mustn't have [ and ] in the textarea
@ -623,17 +631,20 @@ class ExerciseLib
* the text to find mustn't contains HTML tags
* the text to find mustn't contains char "
*/
if ($origin !== null) {
global $exe_id;
$trackAttempts = Database::get_main_table(
TABLE_STATISTIC_TRACK_E_ATTEMPT
);
$sql = 'SELECT answer FROM ' . $trackAttempts . '
WHERE exe_id=' . $exe_id . ' AND question_id=' . $questionId;
$rsLastAttempt = Database::query($sql);
$rowLastAttempt = Database::fetch_array($rsLastAttempt);
$answer = $rowLastAttempt['answer'];
if (empty($answer)) {
global $exerciseId;
$trackAttempts = Database::get_main_table(
TABLE_STATISTIC_TRACK_E_ATTEMPT
);
$sql = 'SELECT answer FROM ' . $trackAttempts . '
WHERE exe_id=' . $exerciseId . ' AND question_id=' . $questionId;
$rsLastAttempt = Database::query($sql);
$rowLastAttempt = Database::fetch_array($rsLastAttempt);
$answer = $rowLastAttempt['answer'];
$calculatedAnswerId = Session::read('calculatedAnswerId');
$calculatedAnswerInfo = Session::read('calculatedAnswerInfo');
if (empty($answer)) {
if (empty($calculatedAnswerId)) {
$_SESSION['calculatedAnswerId'][$questionId] = mt_rand(
1,
$nbrAnswers
@ -641,8 +652,17 @@ class ExerciseLib
$answer = $objAnswerTmp->selectAnswer(
$_SESSION['calculatedAnswerId'][$questionId]
);
Session::write('calculatedAnswerInfo', [$questionId => $answer]);
} else {
$calculatedAnswerInfo = Session::read('calculatedAnswerInfo');
if (isset($calculatedAnswerInfo[$questionId])) {
$answer = $calculatedAnswerInfo[$questionId];
}
}
}
list($answer) = explode('@@', $answer);
// $correctAnswerList array of array with correct anwsers 0=> [0=>[\p] 1=>[plop]]
api_preg_match_all(
@ -650,6 +670,8 @@ class ExerciseLib
$answer,
$correctAnswerList
);
// get student answer to display it if student go back to previous calculated answer question in a test
if (isset($user_choice[0]['answer'])) {
api_preg_match_all(
@ -688,11 +710,13 @@ class ExerciseLib
$studentAnswerList[] = $answerCorrected;
}
}
// If display preview of answer in test view for exemple, set the student answer to the correct answers
if ($debug_mark_answer) {
// contain the rights answers surronded with brackets
$studentAnswerList = $correctAnswerList[0];
}
/*
Split the response by bracket
tabComments is an array with text surrounding the text to find
@ -3488,8 +3512,11 @@ HOTSPOT;
$show_only_score = false;
}
$show_total_score_and_user_choices = false;
if ($objExercise->results_disabled == RESULT_DISABLE_SHOW_SCORE_ATTEMPT_SHOW_ANSWERS_LAST_ATTEMPT) {
$show_only_score = true;
$show_results = true;
if ($objExercise->attempts > 0) {
$attempts = Event::getExerciseResultsByUser(
api_get_user_id(),
@ -3509,7 +3536,10 @@ HOTSPOT;
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;
}
}
}
}
@ -3528,7 +3558,6 @@ HOTSPOT;
);
}
// Display text when test is finished #4074 and for LP #4227
$end_of_message = $objExercise->selectTextWhenFinished();
if (!empty($end_of_message)) {
@ -3556,23 +3585,19 @@ HOTSPOT;
$questionId,
null,
'exercise_result',
array(),
[],
$save_user_result,
true,
$show_results,
$objExercise->selectPropagateNeg(),
array()
[],
$show_total_score_and_user_choices
);
if (empty($result)) {
continue;
}
// In case of global score, make sure the calculated total score is integer
/*if (!is_int($result['score'])) {
$result['score'] = round($result['score']);
}*/
$total_score += $result['score'];
$total_weight += $result['weight'];
@ -3658,13 +3683,7 @@ HOTSPOT;
$question_content = '';
if ($show_results) {
$question_content = '<div class="question_row_answer">';
$show_media = false;
/*if ($objQuestionTmp->parent_id != 0 && !in_array($objQuestionTmp->parent_id, $media_list)) {
$show_media = true;
$media_list[] = $objQuestionTmp->parent_id;
}*/
//Shows question title an description
// Shows question title an description
$question_content .= $objQuestionTmp->return_header(
null,
$counter,

@ -19,16 +19,25 @@ class ExerciseShowFunctions
{
/**
* Shows the answer to a fill-in-the-blanks question, as HTML
* @param string Answer text
* @param int Exercise ID
* @param int Question ID
* @param int $feedbackType
* @param string $answer
* @param int $id Exercise ID
* @param int $questionId Question ID
* @param int $resultsDisabled
* @param string $originalStudentAnswer
*
* @return void
*/
public static function display_fill_in_blanks_answer($feedbackType, $answer, $id, $questionId, $resultsDisabled, $originalStudentAnswer = '')
{
$answerHTML = FillBlanks::getHtmlDisplayForAnswer($answer, $resultsDisabled);
public static function display_fill_in_blanks_answer(
$feedbackType,
$answer,
$id,
$questionId,
$resultsDisabled,
$originalStudentAnswer = '',
$showTotalScoreAndUserChoices
) {
$answerHTML = FillBlanks::getHtmlDisplayForAnswer($answer, $resultsDisabled, $showTotalScoreAndUserChoices);
if (strpos($originalStudentAnswer, 'font color') !== false) {
$answerHTML = $originalStudentAnswer;
}
@ -64,8 +73,14 @@ class ExerciseShowFunctions
* @param int Question ID
* @return void
*/
public static function display_calculated_answer($feedback_type, $answer, $id, $questionId)
{
public static function display_calculated_answer(
$feedback_type,
$answer,
$id,
$questionId,
$results_disabled,
$showTotalScoreAndUserChoices
) {
if (empty($id)) {
echo '<tr><td>'. Security::remove_XSS($answer).'</td></tr>';
} else {
@ -97,8 +112,14 @@ class ExerciseShowFunctions
* @param int Question ID
* @return void
*/
public static function display_free_answer($feedback_type, $answer, $exe_id, $questionId, $questionScore = null)
{
public static function display_free_answer(
$feedback_type,
$answer,
$exe_id,
$questionId,
$questionScore = null,
$results_disabled = 0
) {
$comments = Event::get_comments($exe_id, $questionId);
if (!empty($answer)) {
@ -117,7 +138,15 @@ class ExerciseShowFunctions
}
}
public static function display_oral_expression_answer($feedback_type, $answer, $id, $questionId, $fileUrl = null)
/**
* @param $feedback_type
* @param $answer
* @param $id
* @param $questionId
* @param null $nano
* @param int $results_disabled
*/
public static function display_oral_expression_answer($feedback_type, $answer, $id, $questionId, $fileUrl = null, $results_disabled = 0)
{
if (isset($fileUrl)) {
echo '
@ -162,7 +191,7 @@ class ExerciseShowFunctions
* @param string $answer
* @param string $studentChoice
* @param string $answerComment
* @param string $in_results_disabled
* @param int $resultsDisabled
* @param int $orderColor
*/
public static function display_hotspot_answer(
@ -171,15 +200,23 @@ class ExerciseShowFunctions
$answer,
$studentChoice,
$answerComment,
$in_results_disabled,
$orderColor
)
{
$resultsDisabled,
$orderColor,
$showTotalScoreAndUserChoices
) {
$hide_expected_answer = false;
if ($feedback_type == 0 && $in_results_disabled == 2) {
if ($feedback_type == 0 && $resultsDisabled == 2) {
$hide_expected_answer = true;
}
if ($resultsDisabled == RESULT_DISABLE_SHOW_SCORE_ATTEMPT_SHOW_ANSWERS_LAST_ATTEMPT) {
if ($showTotalScoreAndUserChoices) {
$hide_expected_answer = true;
} else {
$hide_expected_answer = false;
}
}
$hotspot_colors = array(
"", // $i starts from 1 on next loop (ugly fix)
"#4271B5",
@ -194,7 +231,9 @@ class ExerciseShowFunctions
"#F4EB24",
"#ED2024",
"#3B3B3B",
"#F7BDE2");
"#F7BDE2"
);
?>
<table class="data_table">
<tr>
@ -207,7 +246,7 @@ class ExerciseShowFunctions
<td class="text-left" width="10%">
<?php
if (!$hide_expected_answer) {
$my_choice = ($studentChoice)?get_lang('Correct'):get_lang('Fault');
$my_choice = $studentChoice ? get_lang('Correct') : get_lang('Fault');
echo $my_choice;
}
?>
@ -250,13 +289,23 @@ class ExerciseShowFunctions
$id,
$questionId,
$ans,
$in_results_disabled
$resultsDisabled,
$showTotalScoreAndUserChoices
) {
$hide_expected_answer = false;
if ($feedback_type == 0 && $in_results_disabled == 2) {
if ($feedback_type == 0 && ($resultsDisabled == RESULT_DISABLE_SHOW_SCORE_ONLY)) {
$hide_expected_answer = true;
}
if ($resultsDisabled == RESULT_DISABLE_SHOW_SCORE_ATTEMPT_SHOW_ANSWERS_LAST_ATTEMPT) {
if ($showTotalScoreAndUserChoices) {
$hide_expected_answer = true;
} else {
$hide_expected_answer = false;
}
}
$icon = in_array($answerType, array(UNIQUE_ANSWER, UNIQUE_ANSWER_NO_OPTION)) ? 'radio':'checkbox';
$icon .= $studentChoice?'_on':'_off';
$icon .= '.gif';
@ -294,14 +343,10 @@ class ExerciseShowFunctions
$color = 'black';
//echo '<span style="font-weight: bold; color: #FF0000;">'.nl2br($answerComment).'</span>';
}
echo '<span style="font-weight: bold; color: '.$color.';">'.nl2br($answerComment).'</span>';
} else {
if ($answerCorrect) {
//echo '<span style="font-weight: bold; color: #000;">'.nl2br($answerComment).'</span>';
} else {
//echo '<span style="font-weight: normal; color: #000;">'.nl2br($answerComment).'</span>';
if ($hide_expected_answer) {
$color = '';
}
echo '<span style="font-weight: bold; color: '.$color.';">'.nl2br($answerComment).'</span>';
}
?>
</td>
@ -340,18 +385,27 @@ class ExerciseShowFunctions
$id,
$questionId,
$ans,
$in_results_disabled
$resultsDisabled,
$showTotalScoreAndUserChoices
) {
$hide_expected_answer = false;
if ($feedback_type == 0 && $in_results_disabled == 2) {
if ($feedback_type == 0 && ($resultsDisabled == RESULT_DISABLE_SHOW_SCORE_ONLY)) {
$hide_expected_answer = true;
}
if ($resultsDisabled == RESULT_DISABLE_SHOW_SCORE_ATTEMPT_SHOW_ANSWERS_LAST_ATTEMPT) {
if ($showTotalScoreAndUserChoices) {
$hide_expected_answer = true;
} else {
$hide_expected_answer = false;
}
}
?>
<tr>
<td width="5%">
<?php
$question = new MultipleAnswerTrueFalse();
$course_id = api_get_course_int_id();
$new_options = Question::readQuestionOption($questionId, $course_id);
@ -391,6 +445,11 @@ class ExerciseShowFunctions
if ($studentChoice == $answerCorrect) {
$color = "green";
}
if ($hide_expected_answer) {
$color = '';
}
echo '<span style="font-weight: bold; color: '.$color.';">'.nl2br($answerComment).'</span>';
}
?>
@ -420,7 +479,7 @@ class ExerciseShowFunctions
* @param boolean Whether to show the answer comment or not
* @return void
*/
static function display_multiple_answer_combination_true_false(
public static function display_multiple_answer_combination_true_false(
$feedback_type,
$answerType,
$studentChoice,
@ -430,12 +489,22 @@ class ExerciseShowFunctions
$id,
$questionId,
$ans,
$in_results_disabled
$resultsDisabled,
$showTotalScoreAndUserChoices
) {
$hide_expected_answer = false;
if ($feedback_type == 0 && $in_results_disabled == 2) {
if ($feedback_type == 0 && ($resultsDisabled == RESULT_DISABLE_SHOW_SCORE_ONLY)) {
$hide_expected_answer = true;
}
if ($resultsDisabled == RESULT_DISABLE_SHOW_SCORE_ATTEMPT_SHOW_ANSWERS_LAST_ATTEMPT) {
if ($showTotalScoreAndUserChoices) {
$hide_expected_answer = true;
} else {
$hide_expected_answer = false;
}
}
?>
<tr>
<td width="5%">
@ -480,16 +549,11 @@ class ExerciseShowFunctions
if ($studentChoice == $answerCorrect) {
$color = "green";
}
echo '<span style="font-weight: bold; color: '.$color.';">'.nl2br($answerComment).'</span>';
}
if ($studentChoice == 2 || $studentChoice == '') {
//echo '<span style="font-weight: bold; color: #000;">'.nl2br($answerComment).'</span>';
} else {
if ($studentChoice == $answerCorrect) {
//echo '<span style="font-weight: bold; color: #008000;">'.nl2br($answerComment).'</span>';
} else {
//echo '<span style="font-weight: bold; color: #FF0000;">'.nl2br($answerComment).'</span>';
if ($hide_expected_answer) {
$color = '';
}
echo '<span style="font-weight: bold; color: '.$color.';">'.nl2br($answerComment).'</span>';
}
?>
</td>

File diff suppressed because it is too large Load Diff

@ -1,7 +1,7 @@
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-type" content="text/html;charset=UTF-8" />
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="chrome=1"/>
<link rel="icon" type="image/png" href="images/logo.png"/>
<link rel="stylesheet" href="svg-editor.css" type="text/css"/>

@ -28,7 +28,7 @@ svgEditor.setConfig({
// preventURLContentLoading: true,
/**
To override the ability for URLs to set other configuration (including
extensions), uncomment the following:
extension config), uncomment the following:
*/
// preventAllURLConfig: true,
/**
@ -71,6 +71,7 @@ svgEditor.setConfig({
// initOpacity: 1,
// colorPickerCSS: null,
// initTool: 'select',
// exportWindowType: 'new', // 'same'
// wireframe: false,
// showlayers: false,
// no_save_warning: false,

@ -0,0 +1,17 @@
/*globals svgEditor*/
/* see https://code.google.com/p/svg-edit/wiki/ConfigOptions */
svgEditor.setConfig({
extensions: [
'ext-php_savefile_chamilo.js',
'ext-eyedropper.js',
'ext-shapes.js',
'ext-polygon.js',
'ext-star.js'
],
noStorageOnLoad: 'true',
selectNew: true,
no_save_warning: true,
emptyStorageOnDecline: true,
iconsize: 'm',
allowedOrigins: [window.location.origin] // May be 'null' (as a string) when used as a file:// URL
});

@ -1,203 +1,203 @@
// jQuery Context Menu Plugin
//
// Version 1.01
//
// Cory S.N. LaViska
// A Beautiful Site (http://abeautifulsite.net/)
// Modified by Alexis Deveria
//
// More info: http://abeautifulsite.net/2008/09/jquery-context-menu-plugin/
//
// Terms of Use
//
// This plugin is dual-licensed under the GNU General Public License
// and the MIT License and is copyright A Beautiful Site, LLC.
//
if(jQuery)( function() {
var win = $(window);
var doc = $(document);
$.extend($.fn, {
contextMenu: function(o, callback) {
// Defaults
if( o.menu == undefined ) return false;
if( o.inSpeed == undefined ) o.inSpeed = 150;
if( o.outSpeed == undefined ) o.outSpeed = 75;
// 0 needs to be -1 for expected results (no fade)
if( o.inSpeed == 0 ) o.inSpeed = -1;
if( o.outSpeed == 0 ) o.outSpeed = -1;
// Loop each context menu
$(this).each( function() {
var el = $(this);
var offset = $(el).offset();
var menu = $('#' + o.menu);
// Add contextMenu class
menu.addClass('contextMenu');
// Simulate a true right click
$(this).bind( "mousedown", function(e) {
var evt = e;
$(this).mouseup( function(e) {
var srcElement = $(this);
srcElement.unbind('mouseup');
if( evt.button === 2 || o.allowLeft || (evt.ctrlKey && svgedit.browser.isMac()) ) {
e.stopPropagation();
// Hide context menus that may be showing
$(".contextMenu").hide();
// Get this context menu
if( el.hasClass('disabled') ) return false;
// Detect mouse position
var d = {}, x = e.pageX, y = e.pageY;
var x_off = win.width() - menu.width(),
y_off = win.height() - menu.height();
if(x > x_off - 15) x = x_off-15;
if(y > y_off - 30) y = y_off-30; // 30 is needed to prevent scrollbars in FF
// Show the menu
doc.unbind('click');
menu.css({ top: y, left: x }).fadeIn(o.inSpeed);
// Hover events
menu.find('A').mouseover( function() {
menu.find('LI.hover').removeClass('hover');
$(this).parent().addClass('hover');
}).mouseout( function() {
menu.find('LI.hover').removeClass('hover');
});
// Keyboard
doc.keypress( function(e) {
switch( e.keyCode ) {
case 38: // up
if( !menu.find('LI.hover').length ) {
menu.find('LI:last').addClass('hover');
} else {
menu.find('LI.hover').removeClass('hover').prevAll('LI:not(.disabled)').eq(0).addClass('hover');
if( !menu.find('LI.hover').length ) menu.find('LI:last').addClass('hover');
}
break;
case 40: // down
if( menu.find('LI.hover').length == 0 ) {
menu.find('LI:first').addClass('hover');
} else {
menu.find('LI.hover').removeClass('hover').nextAll('LI:not(.disabled)').eq(0).addClass('hover');
if( !menu.find('LI.hover').length ) menu.find('LI:first').addClass('hover');
}
break;
case 13: // enter
menu.find('LI.hover A').trigger('click');
break;
case 27: // esc
doc.trigger('click');
break
}
});
// When items are selected
menu.find('A').unbind('mouseup');
menu.find('LI:not(.disabled) A').mouseup( function() {
doc.unbind('click').unbind('keypress');
$(".contextMenu").hide();
// Callback
if( callback ) callback( $(this).attr('href').substr(1), $(srcElement), {x: x - offset.left, y: y - offset.top, docX: x, docY: y} );
return false;
});
// Hide bindings
setTimeout( function() { // Delay for Mozilla
doc.click( function() {
doc.unbind('click').unbind('keypress');
menu.fadeOut(o.outSpeed);
return false;
});
}, 0);
}
});
});
// Disable text selection
if( $.browser.mozilla ) {
$('#' + o.menu).each( function() { $(this).css({ 'MozUserSelect' : 'none' }); });
} else if( $.browser.msie ) {
$('#' + o.menu).each( function() { $(this).bind('selectstart.disableTextSelect', function() { return false; }); });
} else {
$('#' + o.menu).each(function() { $(this).bind('mousedown.disableTextSelect', function() { return false; }); });
}
// Disable browser context menu (requires both selectors to work in IE/Safari + FF/Chrome)
$(el).add($('UL.contextMenu')).bind('contextmenu', function() { return false; });
});
return $(this);
},
// Disable context menu items on the fly
disableContextMenuItems: function(o) {
if( o == undefined ) {
// Disable all
$(this).find('LI').addClass('disabled');
return( $(this) );
}
$(this).each( function() {
if( o != undefined ) {
var d = o.split(',');
for( var i = 0; i < d.length; i++ ) {
$(this).find('A[href="' + d[i] + '"]').parent().addClass('disabled');
}
}
});
return( $(this) );
},
// Enable context menu items on the fly
enableContextMenuItems: function(o) {
if( o == undefined ) {
// Enable all
$(this).find('LI.disabled').removeClass('disabled');
return( $(this) );
}
$(this).each( function() {
if( o != undefined ) {
var d = o.split(',');
for( var i = 0; i < d.length; i++ ) {
$(this).find('A[href="' + d[i] + '"]').parent().removeClass('disabled');
}
}
});
return( $(this) );
},
// Disable context menu(s)
disableContextMenu: function() {
$(this).each( function() {
$(this).addClass('disabled');
});
return( $(this) );
},
// Enable context menu(s)
enableContextMenu: function() {
$(this).each( function() {
$(this).removeClass('disabled');
});
return( $(this) );
},
// Destroy context menu(s)
destroyContextMenu: function() {
// Destroy specified context menus
$(this).each( function() {
// Disable action
$(this).unbind('mousedown').unbind('mouseup');
});
return( $(this) );
}
});
// jQuery Context Menu Plugin
//
// Version 1.01
//
// Cory S.N. LaViska
// A Beautiful Site (http://abeautifulsite.net/)
// Modified by Alexis Deveria
//
// More info: http://abeautifulsite.net/2008/09/jquery-context-menu-plugin/
//
// Terms of Use
//
// This plugin is dual-licensed under the GNU General Public License
// and the MIT License and is copyright A Beautiful Site, LLC.
//
if(jQuery)( function() {
var win = $(window);
var doc = $(document);
$.extend($.fn, {
contextMenu: function(o, callback) {
// Defaults
if( o.menu == undefined ) return false;
if( o.inSpeed == undefined ) o.inSpeed = 150;
if( o.outSpeed == undefined ) o.outSpeed = 75;
// 0 needs to be -1 for expected results (no fade)
if( o.inSpeed == 0 ) o.inSpeed = -1;
if( o.outSpeed == 0 ) o.outSpeed = -1;
// Loop each context menu
$(this).each( function() {
var el = $(this);
var offset = $(el).offset();
var menu = $('#' + o.menu);
// Add contextMenu class
menu.addClass('contextMenu');
// Simulate a true right click
$(this).bind( "mousedown", function(e) {
var evt = e;
$(this).mouseup( function(e) {
var srcElement = $(this);
srcElement.unbind('mouseup');
if( evt.button === 2 || o.allowLeft || (evt.ctrlKey && svgedit.browser.isMac()) ) {
e.stopPropagation();
// Hide context menus that may be showing
$(".contextMenu").hide();
// Get this context menu
if( el.hasClass('disabled') ) return false;
// Detect mouse position
var d = {}, x = e.pageX, y = e.pageY;
var x_off = win.width() - menu.width(),
y_off = win.height() - menu.height();
if(x > x_off - 15) x = x_off-15;
if(y > y_off - 30) y = y_off-30; // 30 is needed to prevent scrollbars in FF
// Show the menu
doc.unbind('click');
menu.css({ top: y, left: x }).fadeIn(o.inSpeed);
// Hover events
menu.find('A').mouseover( function() {
menu.find('LI.hover').removeClass('hover');
$(this).parent().addClass('hover');
}).mouseout( function() {
menu.find('LI.hover').removeClass('hover');
});
// Keyboard
doc.keypress( function(e) {
switch( e.keyCode ) {
case 38: // up
if( !menu.find('LI.hover').length ) {
menu.find('LI:last').addClass('hover');
} else {
menu.find('LI.hover').removeClass('hover').prevAll('LI:not(.disabled)').eq(0).addClass('hover');
if( !menu.find('LI.hover').length ) menu.find('LI:last').addClass('hover');
}
break;
case 40: // down
if( menu.find('LI.hover').length == 0 ) {
menu.find('LI:first').addClass('hover');
} else {
menu.find('LI.hover').removeClass('hover').nextAll('LI:not(.disabled)').eq(0).addClass('hover');
if( !menu.find('LI.hover').length ) menu.find('LI:first').addClass('hover');
}
break;
case 13: // enter
menu.find('LI.hover A').trigger('click');
break;
case 27: // esc
doc.trigger('click');
break
}
});
// When items are selected
menu.find('A').unbind('mouseup');
menu.find('LI:not(.disabled) A').mouseup( function() {
doc.unbind('click').unbind('keypress');
$(".contextMenu").hide();
// Callback
if( callback ) callback( $(this).attr('href').substr(1), $(srcElement), {x: x - offset.left, y: y - offset.top, docX: x, docY: y} );
return false;
});
// Hide bindings
setTimeout( function() { // Delay for Mozilla
doc.click( function() {
doc.unbind('click').unbind('keypress');
menu.fadeOut(o.outSpeed);
return false;
});
}, 0);
}
});
});
// Disable text selection
if( $.browser.mozilla ) {
$('#' + o.menu).each( function() { $(this).css({ 'MozUserSelect' : 'none' }); });
} else if( $.browser.msie ) {
$('#' + o.menu).each( function() { $(this).bind('selectstart.disableTextSelect', function() { return false; }); });
} else {
$('#' + o.menu).each(function() { $(this).bind('mousedown.disableTextSelect', function() { return false; }); });
}
// Disable browser context menu (requires both selectors to work in IE/Safari + FF/Chrome)
$(el).add($('UL.contextMenu')).bind('contextmenu', function() { return false; });
});
return $(this);
},
// Disable context menu items on the fly
disableContextMenuItems: function(o) {
if( o == undefined ) {
// Disable all
$(this).find('LI').addClass('disabled');
return( $(this) );
}
$(this).each( function() {
if( o != undefined ) {
var d = o.split(',');
for( var i = 0; i < d.length; i++ ) {
$(this).find('A[href="' + d[i] + '"]').parent().addClass('disabled');
}
}
});
return( $(this) );
},
// Enable context menu items on the fly
enableContextMenuItems: function(o) {
if( o == undefined ) {
// Enable all
$(this).find('LI.disabled').removeClass('disabled');
return( $(this) );
}
$(this).each( function() {
if( o != undefined ) {
var d = o.split(',');
for( var i = 0; i < d.length; i++ ) {
$(this).find('A[href="' + d[i] + '"]').parent().removeClass('disabled');
}
}
});
return( $(this) );
},
// Disable context menu(s)
disableContextMenu: function() {
$(this).each( function() {
$(this).addClass('disabled');
});
return( $(this) );
},
// Enable context menu(s)
enableContextMenu: function() {
$(this).each( function() {
$(this).removeClass('disabled');
});
return( $(this) );
},
// Destroy context menu(s)
destroyContextMenu: function() {
// Destroy specified context menus
$(this).each( function() {
// Disable action
$(this).unbind('mousedown').unbind('mouseup');
});
return( $(this) );
}
});
})(jQuery);

@ -10,10 +10,11 @@
// Dependencies:
// 1) jquery.js
// 2) math.js
// 3) browser.js
// 4) svgutils.js
// 5) units.js
// 6) svgtransformlist.js
// 3) pathseg.js
// 4) browser.js
// 5) svgutils.js
// 6) units.js
// 7) svgtransformlist.js
var svgedit = svgedit || {};

@ -0,0 +1,6 @@
#main_icon {
width:38px !important;
}
#tools_top {
left: 55px !important;
}

@ -0,0 +1,79 @@
/*globals $, EmbeddedSVGEdit*/
/*jslint vars: true */
var initEmbed;
// Todo: Get rid of frame.contentWindow dependencies so can be more easily adjusted to work cross-domain
$(function () {'use strict';
var svgCanvas = null;
var frame;
initEmbed = function () {
var doc, mainButton;
svgCanvas = new EmbeddedSVGEdit(frame);
// Hide main button, as we will be controlling new, load, save, etc. from the host document
doc = frame.contentDocument || frame.contentWindow.document;
mainButton = doc.getElementById('main_button');
mainButton.style.display = 'none';
};
function handleSvgData(data, error) {
if (error) {
alert('error ' + error);
} else {
alert('Congratulations. Your SVG string is back in the host page, do with it what you will\n\n' + data);
}
}
function loadSvg() {
var svgexample = '<svg width="640" height="480" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg"><g><title>Layer 1</title><rect stroke-width="5" stroke="#000000" fill="#FF0000" id="svg_1" height="35" width="51" y="35" x="32"/><ellipse ry="15" rx="24" stroke-width="5" stroke="#000000" fill="#0000ff" id="svg_2" cy="60" cx="66"/></g></svg>';
svgCanvas.setSvgString(svgexample);
}
function saveSvg() {
svgCanvas.getSvgString()(handleSvgData);
}
function exportPNG() {
var str = frame.contentWindow.svgEditor.uiStrings.notification.loadingImage;
var exportWindow = window.open(
'data:text/html;charset=utf-8,' + encodeURIComponent('<title>' + str + '</title><h1>' + str + '</h1>'),
'svg-edit-exportWindow'
);
svgCanvas.rasterExport('PNG', null, exportWindow.name);
}
function exportPDF() {
var str = frame.contentWindow.svgEditor.uiStrings.notification.loadingImage;
/**
// If you want to handle the PDF blob yourself, do as follows
svgCanvas.bind('exportedPDF', function (win, data) {
alert(data.dataurlstring);
});
svgCanvas.exportPDF(); // Accepts two args: optionalWindowName supplied back to bound exportPDF handler and optionalOutputType (defaults to dataurlstring)
return;
*/
var exportWindow = window.open(
'data:text/html;charset=utf-8,' + encodeURIComponent('<title>' + str + '</title><h1>' + str + '</h1>'),
'svg-edit-exportWindow'
);
svgCanvas.exportPDF(exportWindow.name);
}
// Add event handlers
$('#load').click(loadSvg);
$('#save').click(saveSvg);
$('#exportPNG').click(exportPNG);
$('#exportPDF').click(exportPDF);
$('body').append(
$('<iframe src="svg-editor.html?extensions=ext-xdomain-messaging.js' +
window.location.href.replace(/\?(.*)$/, '&$1') + // Append arguments to this file onto the iframe
'" width="900px" height="600px" id="svgedit" onload="initEmbed();"></iframe>'
)
);
frame = document.getElementById('svgedit');
});

@ -0,0 +1,17 @@
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta charset="utf-8" />
<title>Embed API</title>
<script src="jquery.js"></script>
<script src="embedapi.js"></script>
<script src="embedapi-dom.js"></script>
</head>
<body>
<button id="load">Load example</button>
<button id="save">Save data</button>
<button id="exportPNG">Export data to PNG</button>
<button id="exportPDF">Export data to PDF</button>
<br/>
</body>
</html>

@ -10,9 +10,9 @@ svgCanvas.setSvgString('string')
- Or if a callback is needed:
svgCanvas.setSvgString('string')(function(data, error){
if (error){
// There was an error
// There was an error
} else{
// Handle data
// Handle data
}
})
@ -41,13 +41,13 @@ var cbid = 0;
function getCallbackSetter (d) {
return function () {
var t = this, // New callback
args = [].slice.call(arguments),
cbid = t.send(d, args, function(){}); // The callback (currently it's nothing, but will be set later)
var t = this, // New callback
args = [].slice.call(arguments),
cbid = t.send(d, args, function(){}); // The callback (currently it's nothing, but will be set later)
return function(newcallback){
t.callbacks[cbid] = newcallback; // Set callback
};
return function(newcallback){
t.callbacks[cbid] = newcallback; // Set callback
};
};
}
@ -60,11 +60,11 @@ function addCallback (t, data) {
var result = data.result || data.error,
cbid = data.id;
if (t.callbacks[cbid]) {
if (data.result) {
t.callbacks[cbid](result);
} else {
t.callbacks[cbid](result, 'error');
}
if (data.result) {
t.callbacks[cbid](result);
} else {
t.callbacks[cbid](result, 'error');
}
}
}
@ -72,15 +72,15 @@ function messageListener (e) {
// We accept and post strings as opposed to objects for the sake of IE9 support; this
// will most likely be changed in the future
if (typeof e.data !== 'string') {
return;
return;
}
var allowedOrigins = this.allowedOrigins,
data = e.data && JSON.parse(e.data);
data = e.data && JSON.parse(e.data);
if (!data || typeof data !== 'object' || data.namespace !== 'svg-edit' ||
e.source !== this.frame.contentWindow ||
(allowedOrigins.indexOf('*') === -1 && allowedOrigins.indexOf(e.origin) === -1)
e.source !== this.frame.contentWindow ||
(allowedOrigins.indexOf('*') === -1 && allowedOrigins.indexOf(e.origin) === -1)
) {
return;
return;
}
addCallback(this, data);
}
@ -94,12 +94,12 @@ function getMessageListener (t) {
/**
* @param {HTMLIFrameElement} frame
* @param {array} [allowedOrigins=[]] Array of origins from which incoming
* messages will be allowed when same origin is not used; defaults to none.
* If supplied, it should probably be the same as svgEditor's allowedOrigins
* messages will be allowed when same origin is not used; defaults to none.
* If supplied, it should probably be the same as svgEditor's allowedOrigins
*/
function EmbeddedSVGEdit (frame, allowedOrigins) {
if (!(this instanceof EmbeddedSVGEdit)) { // Allow invocation without 'new' keyword
return new EmbeddedSVGEdit(frame);
return new EmbeddedSVGEdit(frame);
}
this.allowedOrigins = allowedOrigins || [];
// Initialize communication
@ -120,12 +120,12 @@ function EmbeddedSVGEdit (frame, allowedOrigins) {
// Run in svgedit itself
var i,
functions = [
'clearSvgContentElement', 'setIdPrefix', 'getCurrentDrawing', 'addSvgElementFromJson', 'getTransformList', 'matrixMultiply', 'hasMatrixTransform', 'transformListToTransform', 'convertToNum', 'findDefs', 'getUrlFromAttr', 'getHref', 'setHref', 'getBBox', 'getRotationAngle', 'getElem', 'getRefElem', 'assignAttributes', 'cleanupElement', 'remapElement', 'recalculateDimensions', 'sanitizeSvg', 'runExtensions', 'addExtension', 'round', 'getIntersectionList', 'getStrokedBBox', 'getVisibleElements', 'getVisibleElementsAndBBoxes', 'groupSvgElem', 'getId', 'getNextId', 'call', 'bind', 'prepareSvg', 'setRotationAngle', 'recalculateAllSelectedDimensions', 'clearSelection', 'addToSelection', 'selectOnly', 'removeFromSelection', 'selectAllInCurrentLayer', 'getMouseTarget', 'removeUnusedDefElems', 'svgCanvasToString', 'svgToString', 'embedImage', 'setGoodImage', 'open', 'save', 'rasterExport', 'getSvgString', 'randomizeIds', 'uniquifyElems', 'setUseData', 'convertGradients', 'convertToGroup', 'setSvgString', 'importSvgString', 'identifyLayers', 'createLayer', 'cloneLayer', 'deleteCurrentLayer', 'setCurrentLayer', 'renameCurrentLayer', 'setCurrentLayerPosition', 'setLayerVisibility', 'moveSelectedToLayer', 'mergeLayer', 'mergeAllLayers', 'leaveContext', 'setContext', 'clear', 'linkControlPoints', 'getContentElem', 'getRootElem', 'getSelectedElems', 'getResolution', 'getZoom', 'getVersion', 'setUiStrings', 'setConfig', 'getTitle', 'setGroupTitle', 'getDocumentTitle', 'setDocumentTitle', 'getEditorNS', 'setResolution', 'getOffset', 'setBBoxZoom', 'setZoom', 'getMode', 'setMode', 'getColor', 'setColor', 'setGradient', 'setPaint', 'setStrokePaint', 'setFillPaint', 'getStrokeWidth', 'setStrokeWidth', 'setStrokeAttr', 'getStyle', 'getOpacity', 'setOpacity', 'getFillOpacity', 'getStrokeOpacity', 'setPaintOpacity', 'getPaintOpacity', 'getBlur', 'setBlurNoUndo', 'setBlurOffsets', 'setBlur', 'getBold', 'setBold', 'getItalic', 'setItalic', 'getFontFamily', 'setFontFamily', 'setFontColor', 'getFontColor', 'getFontSize', 'setFontSize', 'getText', 'setTextContent', 'setImageURL', 'setLinkURL', 'setRectRadius', 'makeHyperlink', 'removeHyperlink', 'setSegType', 'convertToPath', 'changeSelectedAttribute', 'deleteSelectedElements', 'cutSelectedElements', 'copySelectedElements', 'pasteElements', 'groupSelectedElements', 'pushGroupProperties', 'ungroupSelectedElement', 'moveToTopSelectedElement', 'moveToBottomSelectedElement', 'moveUpDownSelected', 'moveSelectedElements', 'cloneSelectedElements', 'alignSelectedElements', 'updateCanvas', 'setBackground', 'cycleElement', 'getPrivateMethods', 'zoomChanged', 'ready'
'clearSvgContentElement', 'setIdPrefix', 'getCurrentDrawing', 'addSvgElementFromJson', 'getTransformList', 'matrixMultiply', 'hasMatrixTransform', 'transformListToTransform', 'convertToNum', 'findDefs', 'getUrlFromAttr', 'getHref', 'setHref', 'getBBox', 'getRotationAngle', 'getElem', 'getRefElem', 'assignAttributes', 'cleanupElement', 'remapElement', 'recalculateDimensions', 'sanitizeSvg', 'runExtensions', 'addExtension', 'round', 'getIntersectionList', 'getStrokedBBox', 'getVisibleElements', 'getVisibleElementsAndBBoxes', 'groupSvgElem', 'getId', 'getNextId', 'call', 'bind', 'prepareSvg', 'setRotationAngle', 'recalculateAllSelectedDimensions', 'clearSelection', 'addToSelection', 'selectOnly', 'removeFromSelection', 'selectAllInCurrentLayer', 'getMouseTarget', 'removeUnusedDefElems', 'svgCanvasToString', 'svgToString', 'embedImage', 'setGoodImage', 'open', 'save', 'rasterExport', 'exportPDF', 'getSvgString', 'randomizeIds', 'uniquifyElems', 'setUseData', 'convertGradients', 'convertToGroup', 'setSvgString', 'importSvgString', 'identifyLayers', 'createLayer', 'cloneLayer', 'deleteCurrentLayer', 'setCurrentLayer', 'renameCurrentLayer', 'setCurrentLayerPosition', 'setLayerVisibility', 'moveSelectedToLayer', 'mergeLayer', 'mergeAllLayers', 'leaveContext', 'setContext', 'clear', 'linkControlPoints', 'getContentElem', 'getRootElem', 'getSelectedElems', 'getResolution', 'getZoom', 'getVersion', 'setUiStrings', 'setConfig', 'getTitle', 'setGroupTitle', 'getDocumentTitle', 'setDocumentTitle', 'getEditorNS', 'setResolution', 'getOffset', 'setBBoxZoom', 'setZoom', 'getMode', 'setMode', 'getColor', 'setColor', 'setGradient', 'setPaint', 'setStrokePaint', 'setFillPaint', 'getStrokeWidth', 'setStrokeWidth', 'setStrokeAttr', 'getStyle', 'getOpacity', 'setOpacity', 'getFillOpacity', 'getStrokeOpacity', 'setPaintOpacity', 'getPaintOpacity', 'getBlur', 'setBlurNoUndo', 'setBlurOffsets', 'setBlur', 'getBold', 'setBold', 'getItalic', 'setItalic', 'getFontFamily', 'setFontFamily', 'setFontColor', 'getFontColor', 'getFontSize', 'setFontSize', 'getText', 'setTextContent', 'setImageURL', 'setLinkURL', 'setRectRadius', 'makeHyperlink', 'removeHyperlink', 'setSegType', 'convertToPath', 'changeSelectedAttribute', 'deleteSelectedElements', 'cutSelectedElements', 'copySelectedElements', 'pasteElements', 'groupSelectedElements', 'pushGroupProperties', 'ungroupSelectedElement', 'moveToTopSelectedElement', 'moveToBottomSelectedElement', 'moveUpDownSelected', 'moveSelectedElements', 'cloneSelectedElements', 'alignSelectedElements', 'updateCanvas', 'setBackground', 'cycleElement', 'getPrivateMethods', 'zoomChanged', 'ready'
];
// TODO: rewrite the following, it's pretty scary.
for (i = 0; i < functions.length; i++) {
this[functions[i]] = getCallbackSetter(functions[i]);
this[functions[i]] = getCallbackSetter(functions[i]);
}
// Older IE may need a polyfill for addEventListener, but so it would for SVG

@ -1,11 +1,12 @@
<?php
$allowedMimeTypesBySuffix = array(
'svg' => 'image/svg+xml;charset=utf-8',
'svg' => 'image/svg+xml;charset=UTF-8',
'png' => 'image/png',
'jpeg' => 'image/jpeg',
'bmp' => 'image/bmp',
'webp' => 'image/webp'
'webp' => 'image/webp',
'pdf' => 'application/pdf'
);
?>

@ -0,0 +1,9 @@
<?xml version="1.0"?>
<svg width="1000" height="1000" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg">
<g>
<title>Layer 1</title>
<rect id="svg_2" height="717.432104" width="862.814821" y="87.209869" x="63.851915" stroke-linecap="null" stroke-linejoin="null" stroke-dasharray="null" stroke-width="null" fill="#00ffff"/>
<text font-style="italic" font-weight="normal" transform="matrix(14.5579, 0, 0, 19.1025, -3784.43, -4491.74)" xml:space="preserve" text-anchor="middle" font-family="Cursive" font-size="24" id="svg_1" y="267.244915" x="291.750555" stroke-linecap="null" stroke-linejoin="null" stroke-dasharray="null" stroke-width="0" fill="#000000">ICO</text>
</g>
</svg>

After

Width:  |  Height:  |  Size: 708 B

@ -83,7 +83,7 @@ svgEditor.addExtension("Connector", function(S) {
function showPanel(on) {
var conn_rules = $('#connector_rules');
if(!conn_rules.length) {
conn_rules = $('<style id="connector_rules"><\/style>').appendTo('head');
conn_rules = $('<style id="connector_rules"></style>').appendTo('head');
}
conn_rules.text(!on?"":"#tool_clone, #tool_topath, #tool_angle, #xy_panel { display: none !important; }");
$('#connector_panel').toggle(on);

@ -0,0 +1,67 @@
/*globals svgEditor*/
/*
Depends on Firefox add-on and executables from https://github.com/brettz9/webappfind
Todos:
1. See WebAppFind Readme for SVG-related todos
*/
(function () {'use strict';
var pathID,
saveMessage = 'webapp-save',
readMessage = 'webapp-read',
excludedMessages = [readMessage, saveMessage];
window.addEventListener('message', function(e) {
if (e.origin !== window.location.origin || // PRIVACY AND SECURITY! (for viewing and saving, respectively)
(!Array.isArray(e.data) || excludedMessages.indexOf(e.data[0]) > -1) // Validate format and avoid our post below
) {
return;
}
var svgString,
messageType = e.data[0];
switch (messageType) {
case 'webapp-view':
// Populate the contents
pathID = e.data[1];
svgString = e.data[2];
svgEditor.loadFromString(svgString);
/*if ($('#tool_save_file')) {
$('#tool_save_file').disabled = false;
}*/
break;
case 'webapp-save-end':
alert('save complete for pathID ' + e.data[1] + '!');
break;
default:
throw 'Unexpected mode';
}
}, false);
window.postMessage([readMessage], window.location.origin !== 'null' ? window.location.origin : '*'); // Avoid "null" string error for file: protocol (even though file protocol not currently supported by add-on)
svgEditor.addExtension('WebAppFind', function() {
return {
name: 'WebAppFind',
svgicons: svgEditor.curConfig.extPath + 'executablebuilder-icocreator.svg',
buttons: [{
id: 'webappfind_ico_export', //
type: 'app_menu',
title: 'Export ICO Image back to Disk',
position: 4, // Before 0-based index position 4 (after the regular "Save Image (S)")
events: {
click: function () {
if (!pathID) { // Not ready yet as haven't received first payload
return;
}
window.postMessage([saveMessage, pathID, svgEditor.canvas.getSvgString()], window.location.origin);
}
}
}]
};
});
}());

@ -30,7 +30,7 @@ svgEditor.addExtension("foreignObject", function(S) {
function showPanel(on) {
var fc_rules = $('#fc_rules');
if(!fc_rules.length) {
fc_rules = $('<style id="fc_rules"><\/style>').appendTo('head');
fc_rules = $('<style id="fc_rules"></style>').appendTo('head');
}
fc_rules.text(!on?"":" #tool_topath { display: none !important; }");
$('#foreignObject_panel').toggle(on);

@ -18,7 +18,7 @@ svgEditor.addExtension('view_grid', function() { 'use strict';
var NS = svgedit.NS,
svgdoc = document.getElementById('svgcanvas').ownerDocument,
showGrid = false,
showGrid = svgEditor.curConfig.showGrid || false,
assignAttributes = svgCanvas.assignAttributes,
hcanvas = document.createElement('canvas'),
canvBG = $('#canvasBackground'),
@ -127,6 +127,13 @@ svgEditor.addExtension('view_grid', function() { 'use strict';
svgCanvas.setHref(gridimg, datauri);
}
function gridUpdate () {
if (showGrid) {
updateGrid(svgCanvas.getZoom());
}
$('#canvasGrid').toggle(showGrid);
$('#view_grid').toggleClass('push_button_pressed tool_button');
}
return {
name: 'view_grid',
svgicons: svgEditor.curConfig.extPath + 'grid-icon.xml',
@ -134,7 +141,11 @@ svgEditor.addExtension('view_grid', function() { 'use strict';
zoomChanged: function(zoom) {
if (showGrid) {updateGrid(zoom);}
},
callback: function () {
if (showGrid) {
gridUpdate();
}
},
buttons: [{
id: 'view_grid',
type: 'context',
@ -143,11 +154,7 @@ svgEditor.addExtension('view_grid', function() { 'use strict';
events: {
click: function() {
svgEditor.curConfig.showGrid = showGrid = !showGrid;
if (showGrid) {
updateGrid(svgCanvas.getZoom());
}
$('#canvasGrid').toggle(showGrid);
$('#view_grid').toggleClass('push_button_pressed tool_button');
gridUpdate();
}
}
}]

@ -20,7 +20,7 @@ svgEditor.addExtension("Hello World", function() {'use strict';
return {
name: "Hello World",
// For more notes on how to make an icon file, see the source of
// the hellorworld-icon.xml
// the helloworld-icon.xml
svgicons: svgEditor.curConfig.extPath + "helloworld-icon.xml",
// Multiple buttons can be added in this array

@ -0,0 +1,474 @@
/*globals $, svgEditor, svgedit, svgCanvas, DOMParser*/
/*jslint vars: true, eqeq: true, es5: true, todo: true */
/*
* ext-imagelib.js
*
* Licensed under the MIT License
*
* Copyright(c) 2010 Alexis Deveria
*
*/
svgEditor.addExtension("imagelib", function() {'use strict';
var uiStrings = svgEditor.uiStrings;
$.extend(uiStrings, {
imagelib: {
select_lib: 'Select an image library',
show_list: 'Show library list',
import_single: 'Import single',
import_multi: 'Import multiple',
open: 'Open as new document'
}
});
var img_libs = [
{
name: 'Local library (local)',
url: 'extensions/imagelib/index.php',
//description: 'Demonstration library for SVG-edit on this server'// Chamilo change this line by below
description: 'Course gallery'
},
{
name: 'Local library',
url: 'extensions/imagelib/groups.php',
//description: 'Demonstration library for SVG-edit on this server'// Chamilo change this line by below
description: 'Group gallery'
},
{
name: 'Local library',
url: 'extensions/imagelib/users.php',
//description: 'Demonstration library for SVG-edit on this server'// Chamilo change this line by below
description: 'Personal gallery'
},
{
name: 'IAN Symbol Libraries',
url: 'http://ian.umces.edu/symbols/catalog/svgedit/album_chooser.php',
description: 'Free library of illustrations'
}
];
function closeBrowser() {
$('#imgbrowse_holder').hide();
}
function importImage(url) {
var newImage = svgCanvas.addSvgElementFromJson({
"element": "image",
"attr": {
"x": 0,
"y": 0,
"width": 0,
"height": 0,
"id": svgCanvas.getNextId(),
"style": "pointer-events:inherit"
}
});
svgCanvas.clearSelection();
svgCanvas.addToSelection([newImage]);
svgCanvas.setImageURL(url);
}
var mode = 's';
var multi_arr = [];
var cur_meta;
var tranfer_stopped = false;
var pending = {};
var preview, submit;
window.addEventListener("message", function(evt) {
// Receive postMessage data
var response = evt.data;
if (!response || typeof response !== "string") { // Todo: Should namespace postMessage API for this extension and filter out here
// Do nothing
return;
}
try { // This block can be removed if embedAPI moves away from a string to an object (if IE9 support not needed)
var res = JSON.parse(response);
if (res.namespace) { // Part of embedAPI communications
return;
}
}
catch (e) {}
var char1 = response.charAt(0);
var id;
var svg_str;
var img_str;
if (char1 != "{" && tranfer_stopped) {
tranfer_stopped = false;
return;
}
if (char1 == '|') {
var secondpos = response.indexOf('|', 1);
id = response.substr(1, secondpos-1);
response = response.substr(secondpos+1);
char1 = response.charAt(0);
}
// Hide possible transfer dialog box
$('#dialog_box').hide();
var entry, cur_meta;
switch (char1) {
case '{':
// Metadata
tranfer_stopped = false;
cur_meta = JSON.parse(response);
pending[cur_meta.id] = cur_meta;
var name = (cur_meta.name || 'file');
var message = uiStrings.notification.retrieving.replace('%s', name);
if (mode != 'm') {
$.process_cancel(message, function() {
tranfer_stopped = true;
// Should a message be sent back to the frame?
$('#dialog_box').hide();
});
} else {
entry = $('<div>' + message + '</div>').data('id', cur_meta.id);
preview.append(entry);
cur_meta.entry = entry;
}
return;
case '<':
svg_str = true;
break;
case 'd':
if (response.indexOf('data:image/svg+xml') === 0) {
var pre = 'data:image/svg+xml;base64,';
var src = response.substring(pre.length);
response = svgedit.utilities.decode64(src);
svg_str = true;
break;
} else if (response.indexOf('data:image/') === 0) {
img_str = true;
break;
}
// Else fall through
default:
// TODO: See if there's a way to base64 encode the binary data stream
// var str = 'data:;base64,' + svgedit.utilities.encode64(response, true);
// Assume it's raw image data
// importImage(str);
// Don't give warning as postMessage may have been used by something else
if (mode !== 'm') {
closeBrowser();
} else {
pending[id].entry.remove();
}
// $.alert('Unexpected data was returned: ' + response, function() {
// if (mode !== 'm') {
// closeBrowser();
// } else {
// pending[id].entry.remove();
// }
// });
return;
}
switch (mode) {
case 's':
// Import one
if (svg_str) {
svgCanvas.importSvgString(response);
} else if (img_str) {
importImage(response);
}
closeBrowser();
break;
case 'm':
// Import multiple
multi_arr.push([(svg_str ? 'svg' : 'img'), response]);
var title;
cur_meta = pending[id];
if (svg_str) {
if (cur_meta && cur_meta.name) {
title = cur_meta.name;
} else {
// Try to find a title
var xml = new DOMParser().parseFromString(response, 'text/xml').documentElement;
title = $(xml).children('title').first().text() || '(SVG #' + response.length + ')';
}
if (cur_meta) {
preview.children().each(function() {
if ($(this).data('id') == id) {
if (cur_meta.preview_url) {
$(this).html('<img src="' + cur_meta.preview_url + '">' + title);
} else {
$(this).text(title);
}
submit.removeAttr('disabled');
}
});
} else {
preview.append('<div>'+title+'</div>');
submit.removeAttr('disabled');
}
} else {
if (cur_meta && cur_meta.preview_url) {
title = cur_meta.name || '';
}
if (cur_meta && cur_meta.preview_url) {
entry = '<img src="' + cur_meta.preview_url + '">' + title;
} else {
entry = '<img src="' + response + '">';
}
if (cur_meta) {
preview.children().each(function() {
if ($(this).data('id') == id) {
$(this).html(entry);
submit.removeAttr('disabled');
}
});
} else {
preview.append($('<div>').append(entry));
submit.removeAttr('disabled');
}
}
break;
case 'o':
// Open
if (!svg_str) {break;}
svgEditor.openPrep(function(ok) {
if (!ok) {return;}
svgCanvas.clear();
svgCanvas.setSvgString(response);
// updateCanvas();
});
closeBrowser();
break;
}
}, true);
function toggleMulti(show) {
$('#lib_framewrap, #imglib_opts').css({right: (show ? 200 : 10)});
if (!preview) {
preview = $('<div id=imglib_preview>').css({
position: 'absolute',
top: 45,
right: 10,
width: 180,
bottom: 45,
background: '#fff',
overflow: 'auto'
}).insertAfter('#lib_framewrap');
submit = $('<button disabled>Import selected</button>')
.appendTo('#imgbrowse')
.on("click touchend", function() {
$.each(multi_arr, function(i) {
var type = this[0];
var data = this[1];
if (type == 'svg') {
svgCanvas.importSvgString(data);
} else {
importImage(data);
}
svgCanvas.moveSelectedElements(i*20, i*20, false);
});
preview.empty();
multi_arr = [];
$('#imgbrowse_holder').hide();
}).css({
position: 'absolute',
bottom: 10,
right: -10
});
}
preview.toggle(show);
submit.toggle(show);
}
function showBrowser() {
var browser = $('#imgbrowse');
if (!browser.length) {
$('<div id=imgbrowse_holder><div id=imgbrowse class=toolbar_button>\
</div></div>').insertAfter('#svg_docprops');
browser = $('#imgbrowse');
var all_libs = uiStrings.imagelib.select_lib;
var lib_opts = $('<ul id=imglib_opts>').appendTo(browser);
var frame = $('<iframe/>').prependTo(browser).hide().wrap('<div id=lib_framewrap>');
var header = $('<h1>').prependTo(browser).text(all_libs).css({
position: 'absolute',
top: 0,
left: 0,
width: '100%'
});
var cancel = $('<button>' + uiStrings.common.cancel + '</button>')
.appendTo(browser)
.on("click touchend", function() {
$('#imgbrowse_holder').hide();
}).css({
position: 'absolute',
top: 5,
right: -10
});
var leftBlock = $('<span>').css({position:'absolute',top:5,left:10}).appendTo(browser);
var back = $('<button hidden>' + uiStrings.imagelib.show_list + '</button>')
.appendTo(leftBlock)
.on("click touchend", function() {
frame.attr('src', 'about:blank').hide();
lib_opts.show();
header.text(all_libs);
back.hide();
}).css({
'margin-right': 5
}).hide();
var type = $('<select><option value=s>' +
uiStrings.imagelib.import_single + '</option><option value=m>' +
uiStrings.imagelib.import_multi + '</option><option value=o>' +
uiStrings.imagelib.open + '</option></select>').appendTo(leftBlock).change(function() {
mode = $(this).val();
switch (mode) {
case 's':
case 'o':
toggleMulti(false);
break;
case 'm':
// Import multiple
toggleMulti(true);
break;
}
}).css({
'margin-top': 10
});
cancel.prepend($.getSvgIcon('cancel', true));
back.prepend($.getSvgIcon('tool_imagelib', true));
$.each(img_libs, function(i, opts) {
$('<li>')
.appendTo(lib_opts)
.text(opts.name)
.on("click touchend", function() {
frame.attr('src', opts.url).show();
header.text(opts.name);
lib_opts.hide();
back.show();
}).append('<span>' + opts.description + '</span>');
});
} else {
$('#imgbrowse_holder').show();
}
}
return {
svgicons: svgEditor.curConfig.extPath + "ext-imagelib.xml",
buttons: [{
id: "tool_imagelib",
type: "app_menu", // _flyout
position: 4,
title: "Image library",
events: {
"mouseup": showBrowser
}
}],
callback: function() {
$('<style>').text('\
#imgbrowse_holder {\
position: absolute;\
top: 0;\
left: 0;\
width: 100%;\
height: 100%;\
background-color: rgba(0, 0, 0, .5);\
z-index: 5;\
}\
\
#imgbrowse {\
position: absolute;\
top: 25px;\
left: 25px;\
right: 25px;\
bottom: 25px;\
min-width: 300px;\
min-height: 200px;\
background: #B0B0B0;\
border: 1px outset #777;\
}\
#imgbrowse h1 {\
font-size: 20px;\
margin: .4em;\
text-align: center;\
}\
#lib_framewrap,\
#imgbrowse > ul {\
position: absolute;\
top: 45px;\
left: 10px;\
right: 10px;\
bottom: 10px;\
background: white;\
margin: 0;\
padding: 0;\
}\
#imgbrowse > ul {\
overflow: auto;\
}\
#imgbrowse > div {\
border: 1px solid #666;\
}\
#imglib_preview > div {\
padding: 5px;\
font-size: 12px;\
}\
#imglib_preview img {\
display: block;\
margin: 0 auto;\
max-height: 100px;\
}\
#imgbrowse li {\
list-style: none;\
padding: .5em;\
background: #E8E8E8;\
border-bottom: 1px solid #B0B0B0;\
line-height: 1.2em;\
font-style: sans-serif;\
}\
#imgbrowse li > span {\
color: #666;\
font-size: 15px;\
display: block;\
}\
#imgbrowse li:hover {\
background: #FFC;\
cursor: pointer;\
}\
#imgbrowse iframe {\
width: 100%;\
height: 100%;\
border: 0;\
}\
').appendTo('head');
}
};
});

@ -1,14 +1,14 @@
<svg xmlns="http://www.w3.org/2000/svg">
<g id="tool_imagelib">
<svg width="201" height="211" xmlns="http://www.w3.org/2000/svg">
<g>
<path fill="#efe8b8" stroke="#d6c47c" stroke-linecap="round" d="m2.75,49.51761l56.56,-46.26761c12.73,8.25 25.71001,7 46.44,0.75l-56.03999,47.23944l-22.72002,25.01056l-24.23999,-26.73239z" id="svg_2" stroke-width="7"/>
<path fill="#a03333" stroke="#3f3f3f" d="m3.75,203.25002c14.33301,7 30.66699,7 46,0l0,-152.00002c-14.66699,8 -32.33301,8 -47,0l1,152.00002zm45.75,-152.25002l56.25,-46.75l0,151l-56,48.00002m-47.25,-154.25002l57.25,-46.5" id="svg_1" stroke-width="7" stroke-linecap="round"/>
<path fill="#efe8b8" stroke="#d6c47c" stroke-linecap="round" d="m49.75,49.51801l56.56,-46.26801c12.72998,8.25 25.71002,7 46.44,0.75l-56.03998,47.239l-22.72003,25.011l-24.23999,-26.73199z" stroke-width="7" id="svg_5"/>
<path fill="#2f8e2f" stroke="#3f3f3f" d="m50.75,202.25c14.33301,7 30.66699,7.04253 46,0.04253l0,-151.04253c-14.66699,8 -32.33301,8 -47,0l1,151zm45.75,-151.25l56.25,-46.75l0,144.01219l-56,51.98782m-47.25,-151.25002l57.25,-46.5" stroke-width="7" stroke-linecap="round" id="svg_6"/>
<path fill="#efe8b8" stroke="#d6c47c" stroke-linecap="round" d="m95.75,49.51801l56.56,-46.26801c12.72998,8.25 25.71002,7 46.44,0.75l-56.03998,47.239l-22.72003,25.011l-24.23999,-26.73199z" stroke-width="7" id="svg_10"/>
<path fill="#336393" stroke="#3f3f3f" d="m96.75,200.29445c14.33301,7 30.66699,7 46,0l0,-149.04445c-14.66699,8 -32.33301,8 -47,0l1,149.04445zm45.75,-149.29445l56.25,-46.75l0,148.04445l-56,48m-47.25,-151.29445l57.25,-46.5" stroke-width="7" stroke-linecap="round" id="svg_11"/>
</g>
</svg>
</g>
<svg xmlns="http://www.w3.org/2000/svg">
<g id="tool_imagelib">
<svg width="201" height="211" xmlns="http://www.w3.org/2000/svg">
<g>
<path fill="#efe8b8" stroke="#d6c47c" stroke-linecap="round" d="m2.75,49.51761l56.56,-46.26761c12.73,8.25 25.71001,7 46.44,0.75l-56.03999,47.23944l-22.72002,25.01056l-24.23999,-26.73239z" id="svg_2" stroke-width="7"/>
<path fill="#a03333" stroke="#3f3f3f" d="m3.75,203.25002c14.33301,7 30.66699,7 46,0l0,-152.00002c-14.66699,8 -32.33301,8 -47,0l1,152.00002zm45.75,-152.25002l56.25,-46.75l0,151l-56,48.00002m-47.25,-154.25002l57.25,-46.5" id="svg_1" stroke-width="7" stroke-linecap="round"/>
<path fill="#efe8b8" stroke="#d6c47c" stroke-linecap="round" d="m49.75,49.51801l56.56,-46.26801c12.72998,8.25 25.71002,7 46.44,0.75l-56.03998,47.239l-22.72003,25.011l-24.23999,-26.73199z" stroke-width="7" id="svg_5"/>
<path fill="#2f8e2f" stroke="#3f3f3f" d="m50.75,202.25c14.33301,7 30.66699,7.04253 46,0.04253l0,-151.04253c-14.66699,8 -32.33301,8 -47,0l1,151zm45.75,-151.25l56.25,-46.75l0,144.01219l-56,51.98782m-47.25,-151.25002l57.25,-46.5" stroke-width="7" stroke-linecap="round" id="svg_6"/>
<path fill="#efe8b8" stroke="#d6c47c" stroke-linecap="round" d="m95.75,49.51801l56.56,-46.26801c12.72998,8.25 25.71002,7 46.44,0.75l-56.03998,47.239l-22.72003,25.011l-24.23999,-26.73199z" stroke-width="7" id="svg_10"/>
<path fill="#336393" stroke="#3f3f3f" d="m96.75,200.29445c14.33301,7 30.66699,7 46,0l0,-149.04445c-14.66699,8 -32.33301,8 -47,0l1,149.04445zm45.75,-149.29445l56.25,-46.75l0,148.04445l-56,48m-47.25,-151.29445l57.25,-46.5" stroke-width="7" stroke-linecap="round" id="svg_11"/>
</g>
</svg>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 1.6 KiB

@ -115,14 +115,14 @@ svgEditor.addExtension("mathjax", function() {'use strict';
}
return {
name: "MatJax",
name: "MathJax",
svgicons: svgEditor.curConfig.extPath + "mathjax-icons.xml",
buttons: [{
id: "tool_mathjax",
type: "mode",
title: "Add Mathematics",
events: {
'click': function() {
click: function() {
// Only load Mathjax when needed, we don't want to strain Svg-Edit any more.
// From this point on it is very probable that it will be needed, so load it.
if (mathjaxLoaded === false) {

@ -17,13 +17,13 @@ svgEditor.addExtension("overview_window", function() { 'use strict';
<div id=\"overview_window_content\" style=\"position:relative; left:12px; top:0px;\">\
<div style=\"background-color:#A0A0A0; display:inline-block; overflow:visible;\">\
<svg id=\"overviewMiniView\" width=\"150\" height=\"100\" x=\"0\" y=\"0\" viewBox=\"0 0 4800 3600\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">\
<use x=\"0\" y=\"0\" xlink:href=\"#svgroot\"> <\/use>\
<use x=\"0\" y=\"0\" xlink:href=\"#svgroot\"> </use>\
</svg>\
<div id=\"overview_window_view_box\" style=\"min-width:50px; min-height:50px; position:absolute; top:30px; left:30px; z-index:5; background-color:rgba(255,0,102,0.3);\">\
<\/div>\
<\/div>\
<\/div>\
<\/div>";
</div>\
</div>\
</div>\
</div>";
$("#sidepanels").append(propsWindowHtml);
//define dynamic animation of the view box.
@ -134,9 +134,9 @@ svgEditor.addExtension("overview_window", function() { 'use strict';
updateViewPortFromViewBox();
});
return{
return {
name: "overview window",
canvasUpdated:updateViewDimensions,
workareaResized:updateViewBox
canvasUpdated: updateViewDimensions,
workareaResized: updateViewBox
};
});

@ -0,0 +1,34 @@
/*globals $, svgCanvas, svgEditor*/
/*jslint regexp:true*/
// TODO: Might add support for "exportImage" custom
// handler as in "ext-server_opensave.js" (and in savefile.php)
svgEditor.addExtension("php_savefile_chamilo", {
callback: function() {
'use strict';
function getFileNameFromTitle () {
var title = svgCanvas.getDocumentTitle();
return $.trim(title);
}
var save_svg_action = svgEditor.curConfig.extPath + 'savefile.php';
svgEditor.setCustomHandlers({
save: function(win, data) {
var svg = '<?xml version="1.0" encoding="UTF-8"?>\n' + data,
filename = getFileNameFromTitle();
$.post(
save_svg_action,
{output_svg: svg, filename: filename}
).done(function(data) {
var response = jQuery.parseJSON(data);
console.log(response.message);
alert(response.message);
if (response.url != '') {
window.top.location.href = response.url;
}
}
);
}
});
}
});

@ -40,7 +40,7 @@ svgEditor.addExtension("polygon", function(S) {'use strict';
function showPanel(on){
var fc_rules = $('#fc_rules');
if (!fc_rules.length) {
fc_rules = $('<style id="fc_rules"><\/style>').appendTo('head');
fc_rules = $('<style id="fc_rules"></style>').appendTo('head');
}
fc_rules.text(!on ? "" : " #tool_topath { display: none !important; }");
$('#polygon_panel').toggle(on);
@ -138,7 +138,6 @@ svgEditor.addExtension("polygon", function(S) {'use strict';
events: {
change: function(){
setAttr('sides', this.value);
}
}
}],

@ -14,7 +14,7 @@
svgEditor.addExtension("server_opensave", {
callback: function() {'use strict';
var Utils = svgedit.utilities;
var save_svg_action = '/+modify';
// Create upload target (hidden iframe)
@ -25,18 +25,18 @@ svgEditor.addExtension("server_opensave", {
var svg = "<?xml version=\"1.0\"?>\n" + data;
var qstr = $.param.querystring();
var name = qstr.substr(9).split('/+get/')[1];
var svg_data = svgedit.utilities.encode64(svg);
var svg_data = Utils.encode64(svg);
if(!$('#export_canvas').length) {
$('<canvas>', {id: 'export_canvas'}).hide().appendTo('body');
}
var c = $('#export_canvas')[0];
c.width = svgCanvas.contentW;
c.height = svgCanvas.contentH;
$.getScript('canvg/canvg.js', function() {
Utils.buildCanvgCallback(function () {
canvg(c, svg, {renderCallback: function() {
var datauri = c.toDataURL('image/png');
// var uiStrings = svgEditor.uiStrings;
var png_data = svgedit.utilities.encode64(datauri);
var png_data = Utils.encode64(datauri); // Brett: This encoding seems unnecessary
var form = $('<form>').attr({
method: 'post',
action: save_svg_action + '/' + name,
@ -48,7 +48,7 @@ svgEditor.addExtension("server_opensave", {
.appendTo('body')
.submit().remove();
}});
});
})();
alert("Saved! Return to Item View!");
top.window.location = '/'+name;
}

@ -1,5 +1,5 @@
/*globals svgEditor, svgedit, svgCanvas, canvg, $*/
/*jslint eqeq: true*/
/*jslint eqeq: true, browser:true*/
/*
* ext-server_opensave.js
*
@ -34,7 +34,8 @@ svgEditor.addExtension("server_opensave", {
save_svg_action = svgEditor.curConfig.extPath + 'filesave.php',
save_img_action = svgEditor.curConfig.extPath + 'filesave.php',
// Create upload target (hidden iframe)
cancelled = false;
cancelled = false,
Utils = svgedit.utilities;
$('<iframe name="output_frame" src="#"/>').hide().appendTo('body');
svgEditor.setCustomHandlers({
@ -42,7 +43,7 @@ svgEditor.addExtension("server_opensave", {
var svg = '<?xml version="1.0" encoding="UTF-8"?>\n' + data, // Firefox doesn't seem to know it is UTF-8 (no matter whether we use or skip the clientDownload code) despite the Content-Disposition header containing UTF-8, but adding the encoding works
filename = getFileNameFromTitle();
if (clientDownloadSupport(filename, '.svg', 'data:image/svg+xml;charset=UTF-8;base64,' + svgedit.utilities.encode64(svg))) {
if (clientDownloadSupport(filename, '.svg', 'data:image/svg+xml;charset=UTF-8;base64,' + Utils.encode64(svg))) {
return;
}
@ -55,6 +56,23 @@ svgEditor.addExtension("server_opensave", {
.appendTo('body')
.submit().remove();
},
exportPDF: function (win, data) {
var filename = getFileNameFromTitle(),
datauri = data.dataurlstring;
if (clientDownloadSupport(filename, '.pdf', datauri)) {
return;
}
$('<form>').attr({
method: 'post',
action: save_img_action,
target: 'output_frame'
}).append('<input type="hidden" name="output_img" value="' + datauri + '">')
.append('<input type="hidden" name="mime" value="application/pdf">')
.append('<input type="hidden" name="filename" value="' + xhtmlEscape(filename) + '">')
.appendTo('body')
.submit().remove();
},
// Todo: Integrate this extension with a new built-in exportWindowType, "download"
exportImage: function(win, data) {
var c,
issues = data.issues,
@ -68,41 +86,41 @@ svgEditor.addExtension("server_opensave", {
c.width = svgCanvas.contentW;
c.height = svgCanvas.contentH;
canvg(c, data.svg, {renderCallback: function() {
var pre, filename, suffix,
datauri = quality ? c.toDataURL(mimeType, quality) : c.toDataURL(mimeType),
// uiStrings = svgEditor.uiStrings,
note = '';
// Check if there are issues
if (issues.length) {
pre = "\n \u2022 ";
note += ("\n\n" + pre + issues.join(pre));
}
if(note.length) {
alert(note);
}
filename = getFileNameFromTitle();
suffix = '.' + data.type.toLowerCase();
if (clientDownloadSupport(filename, suffix, datauri)) {
return;
}
Utils.buildCanvgCallback(function () {
canvg(c, data.svg, {renderCallback: function() {
var pre, filename, suffix,
datauri = quality ? c.toDataURL(mimeType, quality) : c.toDataURL(mimeType),
// uiStrings = svgEditor.uiStrings,
note = '';
// Check if there are issues
if (issues.length) {
pre = "\n \u2022 ";
note += ("\n\n" + pre + issues.join(pre));
}
if(note.length) {
alert(note);
}
filename = getFileNameFromTitle();
suffix = '.' + data.type.toLowerCase();
if (clientDownloadSupport(filename, suffix, datauri)) {
return;
}
$('<form>').attr({
method: 'post',
action: save_img_action,
target: 'output_frame'
}).append('<input type="hidden" name="output_img" value="' + datauri + '">')
.append('<input type="hidden" name="mime" value="' + mimeType + '">')
.append('<input type="hidden" name="filename" value="' + xhtmlEscape(filename) + '">')
.appendTo('body')
.submit().remove();
}});
$('<form>').attr({
method: 'post',
action: save_img_action,
target: 'output_frame'
}).append('<input type="hidden" name="output_img" value="' + datauri + '">')
.append('<input type="hidden" name="mime" value="' + mimeType + '">')
.append('<input type="hidden" name="filename" value="' + xhtmlEscape(filename) + '">')
.appendTo('body')
.submit().remove();
}});
})();
}
});
@ -125,7 +143,7 @@ svgEditor.addExtension("server_opensave", {
$('#dialog_box').hide();
if (type !== 'import_img') {
xmlstr = svgedit.utilities.decode64(str64);
xmlstr = Utils.decode64(str64);
}
switch (type) {

@ -88,7 +88,7 @@ svgEditor.addExtension('shapes', function() {'use strict';
var vb = [-off, -off, size + off*2, size + off*2].join(' ');
var stroke = fill ? 0: (size/30);
var shape_icon = new DOMParser().parseFromString(
'<svg xmlns="http://www.w3.org/2000/svg"><svg viewBox="' + vb + '"><path fill="'+(fill?'#333':'none')+'" stroke="#000" stroke-width="' + stroke + '" /><\/svg><\/svg>',
'<svg xmlns="http://www.w3.org/2000/svg"><svg viewBox="' + vb + '"><path fill="'+(fill?'#333':'none')+'" stroke="#000" stroke-width="' + stroke + '" /></svg></svg>',
'text/xml');
var width = 24;
@ -248,7 +248,7 @@ svgEditor.addExtension('shapes', function() {'use strict';
start_y = opts.start_y;
var y = start_y;
var cur_style = canv.getStyle();
startClientPos.x = opts.event.clientX;
startClientPos.y = opts.event.clientY;
@ -343,8 +343,8 @@ svgEditor.addExtension('shapes', function() {'use strict';
mouseUp: function(opts) {
var mode = canv.getMode();
if (mode !== mode_id) {return;}
var keepObject = (opts.event.clientX != startClientPos.x && opts.event.clientY != startClientPos.y);
var keepObject = (opts.event.clientX != startClientPos.x && opts.event.clientY != startClientPos.y);
return {
keep: keepObject,

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

Loading…
Cancel
Save