Ver Fonte

[svn r9834] desactivate upgrade button (not yet tested)

Ludovic Gasc há 18 anos atrás
commit
3f54b7927e
100 ficheiros alterados com 26583 adições e 0 exclusões
  1. 17 0
      .project
  2. 447 0
      CREDITS.txt
  3. 333 0
      INSTALL.txt
  4. 190 0
      README.txt
  5. 2 0
      archive/.htaccess
  6. 6 0
      archive/index.html
  7. 6 0
      courses/index.html
  8. 61 0
      documentation/dependencies.html
  9. 33 0
      documentation/index.html
  10. 406 0
      documentation/installation_guide_french.html
  11. 458 0
      documentation/installation_guide_german.html
  12. 845 0
      documentation/installation_guide_slovenian.html
  13. BIN
      favicon.ico
  14. 1 0
      home/home_menu.html
  15. 2 0
      home/home_news.html
  16. 2 0
      home/home_notice.html
  17. 11 0
      home/home_top.html
  18. BIN
      home/large_dokeos_logo.gif
  19. 609 0
      index.php
  20. 412 0
      installation_guide.html
  21. 340 0
      license.txt
  22. 288 0
      main/admin/add_courses_to_session.php
  23. 377 0
      main/admin/add_users_to_session.php
  24. 59 0
      main/admin/class_add.php
  25. 64 0
      main/admin/class_edit.php
  26. 140 0
      main/admin/class_import.php
  27. 126 0
      main/admin/class_information.php
  28. 150 0
      main/admin/class_list.php
  29. 213 0
      main/admin/class_user_import.php
  30. 323 0
      main/admin/configure_extensions.php
  31. 708 0
      main/admin/configure_homepage.php
  32. 150 0
      main/admin/course_add.php
  33. 361 0
      main/admin/course_category.php
  34. 70 0
      main/admin/course_create_content.php
  35. 159 0
      main/admin/course_edit.php
  36. 216 0
      main/admin/course_import.php
  37. 193 0
      main/admin/course_information.php
  38. 217 0
      main/admin/course_list.php
  39. 232 0
      main/admin/course_user_import.php
  40. 425 0
      main/admin/course_virtual.php
  41. 3 0
      main/admin/exemple.csv
  42. 25 0
      main/admin/exemple.xml
  43. 379 0
      main/admin/index.php
  44. 200 0
      main/admin/languages.php
  45. 279 0
      main/admin/resume_session.php
  46. 291 0
      main/admin/session_add.php
  47. 128 0
      main/admin/session_course_edit.php
  48. 106 0
      main/admin/session_course_list.php
  49. 107 0
      main/admin/session_course_user_list.php
  50. 317 0
      main/admin/session_edit.php
  51. 296 0
      main/admin/session_export.php
  52. 444 0
      main/admin/session_import.php
  53. 139 0
      main/admin/session_list.php
  54. 449 0
      main/admin/settings.php
  55. 63 0
      main/admin/statistics.php
  56. 156 0
      main/admin/style_preview.php
  57. 180 0
      main/admin/subscribe_class2course.php
  58. 191 0
      main/admin/subscribe_user2class.php
  59. 201 0
      main/admin/subscribe_user2course.php
  60. 265 0
      main/admin/system_announcements.php
  61. 234 0
      main/admin/user_add.php
  62. 314 0
      main/admin/user_edit.php
  63. 118 0
      main/admin/user_export.php
  64. 393 0
      main/admin/user_import.php
  65. 152 0
      main/admin/user_information.php
  66. 478 0
      main/admin/user_list.php
  67. 736 0
      main/announcements/announcements.inc.php
  68. 1473 0
      main/announcements/announcements.php
  69. 7 0
      main/announcements/index.html
  70. 1110 0
      main/auth/courses.php
  71. 7 0
      main/auth/index.html
  72. 250 0
      main/auth/inscription.php
  73. 277 0
      main/auth/inscription_second.php
  74. 364 0
      main/auth/ldap/authldap.php
  75. 6 0
      main/auth/ldap/index.html
  76. 77 0
      main/auth/ldap/ldap_var.inc.php
  77. 68 0
      main/auth/ldap/login.php
  78. 63 0
      main/auth/ldap/newUser.php
  79. 109 0
      main/auth/lostPassword.php
  80. 124 0
      main/auth/lost_password.lib.php
  81. 519 0
      main/auth/my_progress.php
  82. 595 0
      main/auth/profile.php
  83. 458 0
      main/blog/blog.php
  84. 123 0
      main/blog/blog_admin.php
  85. 376 0
      main/blog/blog_backup_may3_surbhi.php
  86. 130 0
      main/blog/calendar.php
  87. 159 0
      main/blog/tbl_change.js
  88. 2172 0
      main/calendar/agenda.inc.php
  89. 355 0
      main/calendar/agenda.php
  90. 133 0
      main/calendar/calendar.php
  91. 7 0
      main/calendar/index.html
  92. 1387 0
      main/calendar/myagenda.php
  93. 82 0
      main/calendar/print.php
  94. 159 0
      main/calendar/tbl_change.js
  95. 102 0
      main/chat/chat.php
  96. 7 0
      main/chat/index.html
  97. 1 0
      main/chat/phpfreechat/AUTHORS
  98. 17 0
      main/chat/phpfreechat/COPYING
  99. 14 0
      main/chat/phpfreechat/admin/configuration.php
  100. 556 0
      main/chat/phpfreechat/admin/htaccess.class.php

+ 17 - 0
.project

@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>dokeosSVN</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>net.sourceforge.phpeclipse.parserbuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>net.sourceforge.phpeclipse.phpnature</nature>
+	</natures>
+</projectDescription>

+ 447 - 0
CREDITS.txt

@@ -0,0 +1,447 @@
+========================
+ DOKEOS 1.8 - CREDITS
+========================
+------------------------------
+ Creator
+------------------------------
+Thomas De Praetere (thomas.depraetere@dokeos.com)
+
+--------------------------------
+ Dokeos Main Developers Team
+--------------------------------
+Olivier Brouckaert (oli.brouckaert@dokeos.com)
+Patrick Cool (patrick.cool@ugent.be)
+Roan Embrechts (roan.embrechts@vub.ac.be)
+Rene Haentjens (rene.haentjens@intec.ugent.be)
+Bart Mollet (bart.mollet@hogent.be)
+Wolfgang Schneider (webmaster@bibelcenter.de)
+Bert Vanderkimpen (bert.vanderkimpen@ugent.be)
+Yannick Warnier (ywarnier@beeznest.org)
+Eric Marguin
+Ludovic Gasc (ludovic.gasc@dokeos.com)
+
+--------------------------------
+ Bugfix contributions
+--------------------------------
+(besides all core developers)
+Paolo Mioni
+Diederik De Deckere
+Eric Remy
+Roel Visseren
+Hubert Borderiou
+Ludovic Gasc
+
+--------------------------------
+ Course navigation menu
+--------------------------------
+Sandra Mathijs
+Roan Embrechts
+Wolfgang Schneider
+
+--------------------------------
+ Extensions and plugins
+--------------------------------
+Yannick Warnier
+Patrick Cool
+(see also http://www.dokeos.com/extensions/ )
+
+--------------------------------
+ QuickForm
+--------------------------------
+Bart Mollet
+
+
+---------------------------------
+ Who is online in a course
+---------------------------------
+Patrick Cool
+
+---------------------------------
+ Other
+--------------------------------
+for some other improvements by non-core developers,
+thanks go to
+Thomas Corthals (forum: Turboke)
+Dietrich Van Damme (images)
+Koen Heirbaut (xhtml)
+
+--------------------------------
+ Icons
+--------------------------------
+Icons for the messages: confirmation, error, normal and warning
+Icons used from the Crystal icon theme by Everaldo
+http://linuxcult.com
+
+---------------------------------
+ Messages (integrated extension)
+---------------------------------
+original code written by
+Díaz Braga Alan Israel (bafles2@hotmail.com)
+Menéndez Domínguez Victor Hugo (mdoming@uady.mx)
+Torre Díaz Manuel
+Tuk Sulú Walter Lorenzo (walt_30_ 1@hotmail.com)
+Vargas Palma Rubén (thiefdp@hotmail.com)
+-> Facultad de Matematicas, UADY (México)
+integration by Evie, Free University of Brussels
+
+========================
+ DOKEOS 1.6 - CREDITS
+========================
+We keep these credits here because much of the code of Dokeos 1.8 is
+an improvement of code written for 1.6.
+
+------------------------------
+ Creator
+------------------------------
+Thomas De Praetere (thomas.depraetere@dokeos.com)
+
+--------------------------------
+ Dokeos Main Developers Team
+--------------------------------
+Jan Bols (jan.bols@ugent.be)
+Olivier Brouckaert (oli.brouckaert@dokeos.com)
+Olivier Cauberghe <olivier.cauberghe@ugent.be>
+Patrick Cool (patrick.cool@ugent.be)
+Roan Embrechts (roan.embrechts@vub.ac.be)
+Rene Haentjens (rene.haentjens@intec.ugent.be)
+Bart Mollet (bart.mollet@hogent.be)
+Denes Nagy (darkden@evk.bke.hu)
+Pablo Rey (prey@cesga.es)
+Wolfgang Schneider (webmaster@bibelcenter.de)
+Bert Vanderkimpen (bert.vanderkimpen@ugent.be)
+Toon Van Hoecke (toon.vanhoecke@ugent.be)
+Yannick Warnier (ywarnier@beeznest.org)
+
+--------------------------------
+ Claroline (Dokeos before v1.5) Main Developers Team
+--------------------------------
+Thomas De Praetere (thomas.depraetere@dokeos.com)
+Christophe Gesché (gesche@ipm.ucl.ac.be) aka Moosh
+Hugues Peeters     (peeters@ipm.ucl.ac.be)
+
+--------------------------------
+ Tool Contributions
+--------------------------------
+Documents tool (1.7 commit)
+Bert Vanderkimpen (bert.vanderkimpen@ugent.be)
+
+Announcement tool improvements (completely reworked)
+Pablo Rey (prey@cesga.es)
+Roan Embrechts
+Patrick Cool (patrick.cool@ugent.be)
+Frederik Vermeire
+
+Course quota, improved
+Roan Embrechts
+
+Database refactoring
+Yannick Warnier
+(with thanks to lots of other contributors)
+
+Drop Box
+Jan Bols (jan.bols@UGent.be)
+
+Forum tool
+adapted from PHPBB 1.4 (http://www.phpbb.com)
+modifications: Patrick Cool (patrick.cool@ugent.be)
+
+LDAP
+Roan Embrechts
+L'universit�Jean Monnet de Saint Etienne
+
+Link tool (completely reworked)
+Patrick Cool (patrick.cool@ugent.be)
+
+My Agenda
+Eric Remy
+Toon Van Hoecke (toon.vanhoecke@ugent.be)
+Patrick Cool (patrick.cool@ugent.be)
+
+Resource Linker
+Patrick Cool (patrick.cool@ugent.be)
+
+Rich Text Editor (WYSIWYG html editor)
+** now removed, replaced by HtmlArea **
+Kevin Roth
+
+Single DB customisation
+Roger Hedlund (rhedlund@passagen.se)
+
+Stats tool
+Based on ezBoo (http://www.ezboo.com)
+
+Table of contents
+** now removed, replaced by learning path **
+Roan Embrechts
+
+Test / Quizz Tool
+Olivier Brouckaert (oli.brouckaert@dokeos.com)
+Denes Nagy
+
+Tracking system
+Sebastien Piraux (piraux_seb@hotmail.com)
+
+User Image
+Miguel (miguel@cesga.es)
+Patrick Cool(patrick.cool@ugent.be)
+
+User tool, subscribe existing users
+Elie Harfouche (elie at harfdesign dot com)
+Roan Embrechts
+Bart Mollet
+
+Virtual course support / Combined courses
+Roan Embrechts
+Bart Mollet
+(with thanks to Toon Van Hoecke and Olivier Cauberghe)
+
+Web adjustable (admin) settings
+Jan Bols
+Patrick Cool (patrick.cool@ugent.be)
+Roan Embrechts
+Toon Van Hoecke (toon.vanhoecke@ugent.be)
+
+Zip / unzipping option
+PclZip library - Vincent Blavet (http://www.phpconcept.net)
+
+--------------------------------
+ Library Contributions
+--------------------------------
+main_api
+all developers
+
+database library
+Roan Embrechts
+Bart Mollet
+Yannick Warnier
+
+display, course, group, user libraries
+Roan Embrechts
+Bart Mollet
+
+xml mini dom parser and xml html template library
+Rene Haentjens
+
+--------------------------------
+ Other Contributions
+--------------------------------
+New header implementation and interface ideas
+Sandra Matthys
+
+CSS Stylesheets
+Wolfgang Schneider (webmaster@bibelcenter.de)
+
+Debugging
+Many users have contributed, we'd like to thank them all
+and specifically thank the following people for their feedback:
+Domingos de Freitas (forum: domifreitas)
+Emmanuel Pecquet (forum: Emmanuel)
+Furio Petrossi (forum: petrossi)
+Mark (forum: Mark111)
+Thomas Corthals (forum: Turboke)
+
+Database abstraction layer ideas
+Dardo
+
+Original Developer Manual
+** now absorbed and expanded in the dokeos wiki **
+** http://www.dokeos.com/wiki/ **
+Roan Embrechts, Hugues Peeters, Ren�Haentjens
+
+--------------------------------
+ Translations
+--------------------------------
+
+---- Arabic ----
+Jason Githeko 
+Yassine Jelman (yjelmam@myrealbox.com)
+Ali Pakdel
+Koen Vanmeerbeek
+
+---- Brazilian ----
+Luiz Caetano
+Renato Cintra
+Leonardo Delpino
+Eziquiel Menta
+Marcelo Minholi
+
+---- Bosnian ----
+Silvia Arlone
+Yll Ferizi
+
+---- Bulgarian ----
+Dikran Hachikian
+
+---- Catalan ----
+Xavier de Pedro (xavidp@confluencia.net)
+
+---- Croatian ----
+Dragan Cisic
+Milica Hranjec
+
+---- Chinese ----
+Maizeman (Maizeman@21cn.com)
+
+---- Croatian ----
+Dragan Misovic
+Milica Hranjec
+
+---- Dutch ----
+Tom Belmans
+Thomas Berton
+Karel Beuckelaere
+Hilde Bossuyt
+Olivier Cauberghe
+Patrick Cool (patrick.cool@ugent.be)
+Isabel Deprez (isabel.deprez@rug.ac.be)
+Stefan De Wannemacker (sdwannem@cage.rug.ac.be)
+In� Du Four (inesdufour@hotmail.com)
+Roan Embrechts
+Ren�Haentjens
+Bart Mollet
+Denis Smidts (Smidts@ipm.ucl.ac.be)
+Bert Vanderkimpen
+Toon Van Hoecke (toon.vanhoecke@ugent.be)
+Frederik Vermeire,  
+Herwig Vroman
+Willem Wieme (willem.wieme@ugent.be)
+
+---- English ----
+Vikas Bamotra
+Karel Beuckelaere
+Roan Embrechts
+Patrick Cool
+Bart Mollet
+Ren�Haentjens
+Yannick Warnier
+
+---- Finnish ----
+Asmo Koskinen (asmo.koskinen@asmokoskinen.net)
+Gaurav Shah
+
+---- French ----
+S�astien Boisvert
+Andr�Boivin
+Patrick Cool
+Thomas Depraetere
+Ren�Haentjens
+Didier Nakache
+Yannick Warnier
+
+---- Galician ----
+Maria Jose Rodriges Malmierca
+
+---- German ----
+Gerald Menzel
+Wolfgang Schneider
+Nikolai Stiehl  (nikolai.stiehl@web.de)
+
+---- Greek ----
+Yannis Exidaridis (jexi@noc.uoa.gr)
+Ren�Haentjens
+Eleni Postantzi
+Costas Tsibanis (costas@noc.uoa.gr)
+
+---- Hungarian ----
+Janos Foldessy
+Peter Fuchs
+Istvan Mandak
+Denes Nagy (darkden@evk.bke.hu)
+
+---- Indonesian ----
+Yeni Riwayanti
+Kurnia Muludi
+
+---- Italian ----
+Maurizio Guercio  (mguercio@libero.it),
+Furio Petrossi  (Furio.Petrossi@scuolefvg.org)
+Massimo Grion
+Philippe Verstraete
+Giuseppe Zappal�
+---- Japanese ----
+Hiroki Inou9e
+Akira Yoshii (yoshii@cc.hokkyodai.ac.jp)
+
+---- Norwegian ----
+Thor-Anders Pedersen
+
+---- Persian ----
+Ali Pakdel
+
+---- Polish ----
+Wojtek Anielski
+Slawomir Gurdala (guslaw@uni.lodz.pl)
+Tomasz Jantczak
+
+---- Portuguese ----
+Ant�io Carvalho
+Mauricio Cavalcante
+Domingos Freitas
+Marcello R. Minholi (minholi@unipar.be)
+Sandro Pavan
+Fernando Rebelo
+Manuel Russo
+
+---- Simplified Chinese ----
+Yang Yankan
+Tian Xu
+Juchun Hsia
+Cheng Jizhong
+
+---- Slovenian ----
+Marko Kastelic
+
+---- Swedish ----
+Gert H.T.S. Blomkvist
+Jan Olsson (jano@artedi.nordmaling.se)
+Fredrik Pernros
+
+---- Spanish ----
+Congrio Atarip
+Valent� Barr�
+Oda Begares (begaeres@arch.ucl.ac.be)
+Selin Carrasco
+Xavier Casassas ( xcc@mail.ics.co.at)
+Fernando Dougnac
+Esteban Eid
+Mansilla Federico
+Bania Fuentealba
+Rob Gar
+Alexis Garcia
+Fernando Giraldo Montero
+Jorge Gonzales ( jgonzalez@athenasoft.com.mx)
+Jose Padron
+Javier Picado Ladr� de Guevara (jpicado@eurosur.com)
+Yvan Pinto
+Maria J. Rodriguez Malmierca <mjrm@cesga.es>
+Jose Ramon Roca
+Juan Carlos Ra� Trabado
+Cecilia Vargas
+Jaime Zarate
+
+---- Tha�----
+Sutas Jitchuen (dtsjc@mucc.mahidol.ac.th)
+
+---- Turkish ----
+Cuneyt Birkok (cbirkok@insanbilimleri.com)
+Ender Atesman
+
+---- Vietnamese ----
+Nguyen Nguyen Hong
+
+--------------------------------
+Dokeos Documentation
+--------------------------------
+Andrew Lynn (alynn@strathclyde.ac.be)
+Emmanuel Pecquet (emmanuel.pecquet@wanadoo.fr)
+Nikolai Stiehl (nikolai.stiehl@web.de)
+Isabel Deprez (isabel.deprez@rug.ac.be)
+Philippe Danckaert
+Slawomir Gurdala
+Dalton Piegas Simoni
+Maria Jose Rodriges Malmierca
+
+=======================================================================
+Europe, Belgium
+December, 2005.
+================================== END ================================

+ 333 - 0
INSTALL.txt

@@ -0,0 +1,333 @@
+*****************************************
+ Dokeos 1.8 INSTALLATION
+*****************************************
+Thank you for downloading Dokeos! This text will guide you through the
+basics of installing Dokeos 1.8. Please read this fully
+before proceeding with the installation.
+
+This is only a short installation guide. We are writing a manual with more
+info on installation, but this was not ready at the time of writing. When
+ready, this manual will be accessible through the Dokeos documentation
+page:
+http://www.dokeos.com/documentation.php
+You can also read the work in progress manual on our web writing area:
+http://www.dokeos.com/wiki/index.php/Manual
+
+Contents
+
+1. Requirements
+2. Installing a new version of Dokeos
+3. Upgrading from a previous version of Dokeos
+4. Troubleshooting
+5. Administration section
+6. Ldap (optional)
+
+=================
+ 1. Requirements
+=================
+
+Dokeos is a web application which requires some other software to function:
+a web server, PHP, and the MySQL database server. These software packages
+have to be installed on the computer where you will install Dokeos. 
+
+You can install all these software packages separately, which often gives
+the best results. However, beginning users who want to test Dokeos can use
+a combination package that installs all these software packages in one
+simple install. If you want to use a combination package, we recommend
+Wamp (you also need the PHP4 add-on for WAMP) or XAMP.
+WAMP5 website: http://www.wampserver.com/en/index.php
+WAMP PHP4 add-on: http://www.wampserver.com/en/add-ons.php
+XAMP: http://www.apachefriends.org/en/index.html
+
+1.1. A web server
+
+The Apache web server is recommended, and Dokeos is configured to use some
+Apache security enhancements if possible. However, other web servers will
+work too. For best security results, you need to have the Apache module
+mod_rewrite activated. The mod_rewrite rules for Dokeos are read from a
+.htaccess file in the courses folder, so Apache needs to allow this
+(AllowOverride FileInfo in httpd.conf).
+
+Download Apache web server:
+http://httpd.apache.org/download.cgi
+
+1.2. PHP
+
+You need PHP version 4.3.2 or later (4.x versions), configured with the
+following modules : mysql, zlib, preg, xml. PHP versions 5 or later are not
+supported by Dokes yet. You need the ldap module too if you want to use ldap
+with Dokeos. Most of the PHP4 compiled distributions are provided with these
+modules. Their presence is also checked by the Dokeos install script. 
+
+Download PHP:
+http://www.php.net/downloads.php
+
+Some users could meet problems if their PHP setting doesn't fit these ones:
+
+short_open_tag = On
+safe_mode = Off
+magic_quotes_gpc = On
+magic_quotes_runtime = Off
+
+Past Dokeos versions required register_globals to be set to On. This is no
+longer necessary, this can be set to Off and Dokeos will work fine.
+
+BSD users:
+these php libraries have to be included during php installation:
+- php-mysql The mysql shared extension for php
+- php-pcre The pcre shared extension for php
+- php-session The session shared extension for php
+- php-zlib The zlib shared extension for php
+- (optional) php-ldap if you want to be able to use LDAP authentication
+
+
+1.3. The MySQL database server
+
+And a login/password allowing to administrate and create at least one
+database. By default, Dokeos will create a new database for each course
+created. It means your host should allow you to create and administrate
+several databases. If you want to use Dokeos on a 'single database host'
+you have to select this option during the installation. 
+
+Download MySQL server:
+http://dev.mysql.com/downloads/
+
+Note:
+It seems the backticks characters (`) inserted inside most of the Dokeos SQL
+queries since version 1.3 don't work with MySQL versions before 3.23.6.
+
+1.4. Permissions 
+Furthermore, you need web Write access to web directory where Dokeos has
+been moved or unzipped to. On a Windows machine locally, this is not a
+problem. Remotely, you need to be allowed to CHMOD through FTP, telnet or
+any means.
+
+=======================================
+ 2. Installing a new version of Dokeos
+=======================================
+
+2.1. Download the Dokeos 1.8 install package (.zip for Windows users
+or .tar.gz for all others) from the Dokeos download page:
+http://www.dokeos.com/download.php
+
+2.2. Unzip or untar the downloaded install package. Most current operating
+systems can do this with a built-in graphical application, if this doesn't
+work you can open a commandline, go to the download directory and type
+tar -zxvf dokeos-1.8.tar.gz
+
+2.3. Move by any means (FTP, SCP, local file copy) the contents of the
+Dokeos install package to your website on your webserver (whether webroot
+or subdirectory). Your webserver can also be your local computer. Be sure
+to copy all the folders (archive, home, claroline, courses) as well as all
+the .php files.
+
+For Windows users: If you use e.g easyphp locally (http://www.easyphp.org),
+just drag and drop the contents of the Dokeos install package into
+C:\Program Files\easyphp\www\
+
+2.4. The following files need to be readable and writeable for everyone:
+
+dokeos/main/inc/conf/claro_main.conf.php (if present)
+dokeos/home/*.html
+
+On Linux, Mac OS X and BSD operating systems you can use the CHMOD 666
+command for this. In Windows, you may need to check the properties of
+the folders.
+
+NOTE:
+Do not modify the home_*.html files directly. Instead, choose "Configure
+the homepage" in the Dokeos administration section.
+
+2.5. The following directories need to be readable, writeable and executable
+for everyone:
+
+dokeos/main/inc/conf/
+dokeos/main/garbage/
+dokeos/main/upload/
+dokeos/archive/
+dokeos/courses/
+dokeos/home/
+
+On Linux, Mac OS X and BSD operating systems you can use the CHMOD 777
+command for this. In Windows, you may need to check the properties of
+the folders.
+
+2.6. Open a web browser and go to 
+http://www.yourserver.org/yoursite/dokeos/index.php
+
+For Windows users locally, with e.g easyphp or another combination package,
+open http://localhost/dokeos/index.php
+
+2.7. Click on the install button and follow instructions. Windows: with
+combination packages like easyphp, out of the box, login and password for
+MySQL should probably remain empty.
+
+2.8. Security after installation
+
+Protect your configuration file
+make sure no one can overwrite it. You can find the config file in (dokeos
+folder)/main/inc/conf/claro_main.conf.php. Make it read-only
+(windows/xwindows: right-click the file to edit the properties.
+linux/bsd/macosx: use the chmod 444 command).
+
+Protect your installation folder
+if the (dokeos folder)/main/install folder is still accessible,
+someone could install over your existing version (you could lose your data
+that way). Move the folder somewhere out of the web directories so it is
+not accessible, change its name, or edit its properties so no one can read
+or execute it.
+
+===============================================
+ 3. Upgrading from a previous version of Dokeos
+===============================================
+
+Before upgrading we heavily recommend you do a full backup of the previous Claroline or Dokeos directories and databases. If you are unsure how to achieve this please ask your hosting provider for advice.
+
+3.1. Download the Dokeos 1.8 install package (.zip for Windows users
+or .tar.gz for all others) from the Dokeos download page:
+http://www.dokeos.com/download.php
+
+3.2. Unzip or untar the downloaded install package. Most current operating systems can do this with a built-in graphical application, if this doesn't work you can open a commandline, go to the download directory and type tar -zxvf dokeos-1.6.beta.tar.gz
+
+3.3. Move the Dokeos directory to a different path from the previous version
+
+WARNING:
+Do not delete the previous Dokeos installation directory before installing the new one. When the update is successfully finished, you can remove the old path.
+
+TIP:
+If you want Dokeos 1.8 to be installed in the same directory as the previous version :
+
+move the old directory to a new location (e.g. move dokeos/ to dokeos_old/)
+uncompress Dokeos 1.8 to the old version directory (e.g. uncompress Dokeos 1.6 to dokeos/)
+go to next step
+
+3.4. The following files need to be readable and writeable for everyone:
+
+dokeos/main/inc/conf/claro_main.conf.php (if present)
+dokeos/home/*.html
+
+On Linux, Mac OS X and BSD operating systems you can use the CHMOD 666 command for this. In Windows, you may need to check the properties of the folders.
+
+NOTE:
+Do not modify the home_*.html files directly. Instead, choose "Configure the homepage" in the Dokeos administration section.
+
+3.5. The following directories need to be readable, writeable and executable for everyone:
+
+dokeos/main/inc/conf/
+dokeos/main/garbage/
+dokeos/main/upload/
+dokeos/archive/
+dokeos/courses/
+dokeos/home/
+
+On Linux, Mac OS X and BSD operating systems you can use the CHMOD 777 command for this. In Windows, you may need to check the properties of the folders.
+3.6. Open a web browser and go to http://www.yourserver.org/yoursite/dokeos/index.php Windows locally, with e.g easyphp or another combination package, open: http://localhost/dokeos/index.php
+
+3.7. Click on the install button, then click on "Update from Dokeos 1.5 | 1.5.4 | 1.5.5" and follow the instructions.
+
+3.8. This part is optional!
+Since after version 1.5.5, the following tables in the dokeos_main database can be removed when upgrading from a 1.5.5 version or lower, provided that you don't use them for a customisation of your Dokeos system:
+
+`todo`
+`pma_bookmark`
+`pma_column_comments`
+`pma_pdf_pages`
+`pma_relation`
+`pma_table_coords`
+`pma_table_info`
+These tables can be removed by connecting to the database as the Dokeos user and executing this query: DROP TABLE dokeos_main.my_table; where dokeos_main is the main dokeos database name and my_table is each of the preceding tables (repeat query for each) 
+
+A clean-up of the useless fields has also influenced some code: The main_db.cours.cours_id has been removed, as all references to that field throughout the official Dokeos code. The course code (literal) is used instead. Please update your custom code if any. 
+
+Under the same circumstances as tables removal, the following fields can be removed if not used by your code, using a query similar to: ALTER TABLE database.table drop column abc where database is the database name (dokeos_main? or code of a course) table is the table name (cours?) abc is the name of the field to drop You can thus drop the following fields:
+`_dokeos_main_`.`cours`.`versionDb`
+`_dokeos_main_`.`cours`.`versionClaro`
+`_dokeos_main_`.`cours`.`cahier_charges`
+`_dokeos_main_`.`faculte`.`bc` 
+# the table `faculte` has been renamed to `course_category` since 1.6
+`_cours_`.`announcement`.`code_cours`
+`_cours_`.`course_description`.`upDate`
+
+===========================
+ 4. Troubleshooting
+===========================
+
+In the future we will also provide instructions on how to do a "manual"
+install of Dokeos, by creating the database tables yourself. If you have
+any problems, go to the Dokeos website and ask a question on our support
+forum. Please read the previous messages first to see if there is already
+an answer to your question. We also maintain a list of Frequently Asked
+Questions (FAQ).
+
+Dokeos website: http://www.dokeos.com/
+Support forum: http://www.dokeos.com/forum/
+Frequently Asked Questions: http://www.dokeos.com/wiki/index.php/FAQ
+
+===========================
+ 5. Administration section
+===========================
+
+To access the Dokeos administration section, open browser, go to your Dokeos adress and log in with the admin user. Then you will see a "Platform admin section" link in the header of the web page.
+
+===========================
+ 6. LDAP
+===========================
+
+This part is optional, only organisations with an LDAP server will need to read this.
+An LDAP module is already provided in Dokeos, but it has to be configured to make it work.
+
+6.0. Compiling
+Linux servers: It's possible that you have to recompile php with ldap support.
+Newer distributions also allow downloading rpms for additional packages.
+
+6.1. Activating
+In main/inc/conf/claro_main.conf.php, around line 90, you see
+//for new login module
+//uncomment these to activate ldap
+//$extAuthSource['ldap']['login'] = "./main/auth/ldap/login.php";
+//$extAuthSource['ldap']['newUser'] = "./main/auth/ldap/newUser.php";
+
+remove the // from the last two lines to activate LDAP.
+
+6.2. Settings
+Ask the LDAP server admin for the settings:
+- ldap server name
+- ldap server port (usually 389)
+- ldap dc
+You must enter these in
+main/auth/ldap/ldap_var.inc.php
+
+//parameters for LDAP module
+$usesLDAP						=	TRUE;
+$usesCurriculum					=	FALSE;
+$ldaphost = "myldapserver.com";  // your ldap server
+$ldapport = 389;                 // your ldap server's port number
+$ldapDc = "dc=xx, dc=yy, dc=zz"; //domain
+
+6.3. Teacher/student status
+If you wish, you can give teacher/student status to dokeos users according to settings in the ldap server.
+This is not a standard field however, so you'll have to change some code.
+main/auth/ldap/ldap_var.inc.php
+around line 189,	function putUserInfoInClaroline ($login, $infoArray)
+if (<your criterium>)
+{
+	$statut = STUDENT;
+}
+else
+{
+	$statut = COURSEMANAGER;
+}
+
+If this seems too difficult, the simplest solution is to just put
+$statut = STUDENT;
+and give course manager rights through the admin panel.
+
+6.4. Some LDAP servers do not support anonymous use of the directory services.
+In this case, you need code that binds with a name and password - this code has already been provided,
+just ask on a forum or email for this.
+
+==========================================================================
+Contact address: Dokeos, 44 rue des palais, B-1030 Brussels, Belgium
+Mail: info@dokeos.com
+May 2005
+================================== END ===================================

+ 190 - 0
README.txt

@@ -0,0 +1,190 @@
+=======================================
+ Dokeos 1.8 README
+=======================================
+
+Dokeos is an elearning and course management web application,
+and is free software (GNU GPL). It's translated into 30 languages,
+SCORM compliant, and light and flexible.
+
+Dokeos supports many different kinds of learning and collaboration activities.
+Teachers/trainers can create, manage and publish their courses through the web.
+Students/trainees can follow courses, read content or participate actively
+through groups, forums, chat.
+
+Technically, Dokeos is a web application written in PHP that stores data in a 
+MySQL database. Users access it using a web browser.
+
+If you would like to know more or help develop this software, please visit
+our homepage at http://www.dokeos.com/
+
+
+INSTALLING DOKEOS
+=================
+Please read the installation_guide.html for instructions on how to
+install Dokeos.
+
+
+DOCUMENTATION
+=============
+We have some short guides available inside this release package,
+in the documentation folder.
+
+More detailed documentation can be found at
+http://www.dokeos.com/documentation.php contains
+
+- Student manual
+- Teacher manual
+- And much more
+
+Developers will find all the info they need on our wiki:
+http://www.dokeos.com/wiki/
+
+
+SCORM
+=====
+
+Dokeos imports Scorm 1.2 and 1.3. compliant learning contents.
+For more information on Scorm normalisation, see http://www.adlnet.org
+
+
+LICENSE
+=======
+
+Dokeos is distributed under the GNU General Public license (GPL).
+See the file license.txt for all details.
+
+
+PORTABILITY
+===========
+
+Dokeos is an AMP software. This means it should work on any platform running Apache
++ MySQL + PHP. It is then supposed to work on the following Operating Systems :
+
+	Linux
+	Windows (98, Me, NT4, 2000, XP)
+	Unix
+	Mac OS X
+
+We tested it on
+- Fedora, Mandrake, Red Hat Enterprise Server,
+- Windows XP, Windows 2000
+- Mac OS X 10.3
+
+Email functions remain silent on systems where there is no mail sending software
+(Sendmail, Postfix, Hamster...), which is the case by default on a Windows machine.
+
+
+INTEROPERABILITY
+================
+
+Dokeos imports Scorm compliant learning contents. It imports then "On the shelve"
+contents from many companies : NETg, Skillsoft, Explio, Microsoft, Macromedia, etc.
+
+Admin interface imports users through CSV and XML. You can create a CSV file from
+a list of users in MS Excel. OpenOffice can export to both CSV and XML formats.
+Many database management systems, like Oracle, SAP, Access, SQL-Server, LDAP ...
+export to CSV and/or XML.
+
+Dokeos includes a LDAP module that allows admin to deactivate MySQL authentication
+and replace it by connection to a LDAP directory.
+
+Client side, Dokeos runs on any browser : Firefox, MS Internet Explorer (5.0+), Netscape (4.7+),
+Mozilla (1.2+), Safari, Opera, ...
+
+
+PHP Configuration
+=================
+ 
+Dokeos needs PHP version 4.3.2 or later (4.x versions), configured with the
+following modules : mysql, zlib, preg, xml. PHP versions 5 or later are not
+supported by Dokes yet. It will accept the following settings :
+
+safe_mode				= Off
+magic_quotes_gpc		= On
+magic_quotes_runtime	= Off
+short_open_tag			= On
+
+The backticks charachter (`) inserted inside some of the Dokeos SQL queries doesn't
+work with MySQL versions previous to 3.23.6
+
+In some sections (Backup, Documents, Learning Path..), Dokeos requires the "zlib"
+library on windows servers or the unzip shell software on Linux/Unix servers.
+
+
+SECURITY
+==============
+
+In Dokeos 1.6, security and interoperability have been improved. Protection
+for documents has improved, and courses have more accessibility options.
+Password encryption is enabled by default. The php.ini setting 
+"register globals" does not have be on anymore.
+
+NEW FEATURES IN DOKEOS 1.8
+===========================
+Release notes - summary
+
+
+NEW FEATURES IN DOKEOS 1.6
+===========================
+Release notes - summary
+http://www.dokeos.com/wiki/index.php/Dokeos_1.6_release_notes
+
+Complete roadmap
+http://www.dokeos.com/wiki/index.php/Roadmap_1.6
+
+- Campus home page can be edited online
+- Improved translations, made with the new Dokeos translation tool
+- Language switch - when you enter the portal, you can choose your language.
+- Who is online: a list of users who are logged in, you can click to see
+  their pictures and portfolio, or click to talk to them through our built-in web chat tool.
+- Learning path - import and export of SCORM packages, improved layout,
+  prerequisites based on score in tests
+- Agenda - many new options, e.g. every user can add personal agenda items.
+- Document tool - many new options, improved layout, improved HtmlArea
+- Security - PHP register globals setting don't need to be on anymore
+- Administration section - all functions are easier to access, you can
+  configure many options through the web interface instead of by digging through the code.
+- Improved course management - completely rewritten course import/export
+  functions, easily copy content from one course to another
+- Plugins and modularity - new system to add plugins to Dokeos more easily
+- API libraries - our function libraries have been expanded and improved
+- Interoperability: support for SCORM import/export, XML import/export for
+  some features, IEEE LOM Metadata support in documents and groups, import of
+  Hotpotatoes, connection with QuestionMark (this last one will be available
+  as plugin).
+
+NEW FEATURES IN DOKEOS 1.5
+===========================
+- Learning path : Scorm content import tool
+- WYSIWYG editor : create content on the fly
+- Table of contents : structure content on the fly
+- Dropbox : peer2peer content sharing manegement
+- Links categories : structure links catalogue
+- New navigation : one click to tool
+- Events since my last visit : be informed of what has changed since your last login
+- My agenda : synthetic weekly view of all the events related to you
+- Add a picture to my profile : see who is who
+- Security : privacy and anti-cracking protection
+- 5 more languages : russian, catalan, vietnamese, brazilian, thai and a revised chinese
+- New chat tool : real-time textual discussion
+- Audio & video conference : real-time live broadcasting of events + textual interaction with ore than 200 people.
+- Announcements to some users or some groups only
+- Time-based learning management : add resources to time line in Agenda
+- Audio & video in Tests tool : create listening comprehensions, situation-based questions on the fly
+- Forum thread/flat view : see discussions in more detail
+- Forum email notification : get an email when your forum topic is active
+- language revision : dokeos vocabulary has been generalised to be adapted
+  to different types of organisations and not only universities
+
+
+CREDITS
+=======
+
+See CREDITS.txt file
+
+
+=========================================================================
+Contact address: Dokeos, 44 rue des palais, B-1030 Brussels, Belgium
+Mail: info@dokeos.com
+September 2006
+================================== END ===================================

+ 2 - 0
archive/.htaccess

@@ -0,0 +1,2 @@
+order deny,allow
+deny from all

+ 6 - 0
archive/index.html

@@ -0,0 +1,6 @@
+<html>
+<head>
+</head>
+<body>
+</body>
+</html>

+ 6 - 0
courses/index.html

@@ -0,0 +1,6 @@
+<html>
+<head>
+</head>
+<body>
+</body>
+</html>

+ 61 - 0
documentation/dependencies.html

@@ -0,0 +1,61 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+	   "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+<html xmlns="http://www.w3.org/1999/xhtml" lang="en_US" xml:lang="en_US">
+ <head>
+  <title>Dokeos Server Dependencies</title>
+ </head>
+ <body>
+ <h1>Dokeos server dependencies</h1>
+ <h2>Introduction</h2>
+ <p>In the ever-evoluting web environment, Dokeos has to rely on state-of-the-art third-party 
+ software in order to provide you with useful and practical features. Some of this third-party software
+ usually come bundled with your operating system, but some don't. This means that if that software is
+ not installed on your Dokeos server, along with Dokeos, you might not enjoy the best possible
+ experience with your Dokeos platform. To avoid this problem, most of the sofware we used is bundled 
+ into a typical Dokeos install.<br/> 
+ However, if such a third-party software is too big to be included, or if it doesn't make sense to 
+ includ it for whatever reason, you must make sure it is installed on your system. 
+ This is the goal of this list: to help you keep a track of what software is needed and, 
+ as much as possible, where to get the required information to install it.</p>
+ <p>The third-party software we have bundled inside Dokeos can be found in the 
+ <a href="#included_dependencies">Included Dependencies</a> section below. The software you need
+ to install manually is located in the <a href="#dependencies">section</a>.</p>
+ <a name="dependencies"></a>
+ <h2>Dependencies</h2>
+ <ul>
+ 	<li> Apache 1.3 or 2</li>
+ 	<li> PHP4.3.0 (or greater) with MySQL bindings
+ 	</li>
+	<li> MySQL database server
+	</li>
+ </ul>
+ <br/>
+ <a name="included_dependencies"></a>
+ <h2>Included Dependencies</h2>
+ <ul>
+ 	<li>FCKEditor (previously HTMLArea)
+ 	</li>
+ 	<li>FormValidator
+ 	</li>
+ 	<li>kSes
+ 	</li>
+ 	<li>MIMETex
+ 	</li>
+ 	<li>MP3Player
+ 	</li>
+ 	<li>PCLZip
+ 	</li>
+ 	<li>PHPMailer
+ 	</li>
+ 	<li>xajax
+ 	</li>
+ 	<li>PEAR::HTML_Common
+ 	</li>
+ 	<li>PEAR::HTML_QuickForm
+ 	</li>
+ 	<li>PEAR::Pager
+ 	</li>
+ </ul>
+ </body>
+</html>

+ 33 - 0
documentation/index.html

@@ -0,0 +1,33 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+   "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html>
+	<head>
+		<title>Dokeos documentation overview</title>
+
+		<link rel="stylesheet" href="../main/css/default.css" type="text/css" media="screen,projection" />
+		<link rel="shortcut icon" href="../favicon.ico" type="image/x-icon" />
+	</head>
+
+	<body>
+		<div id="header1">
+			<h1>Dokeos documentation overview</h1>
+		</div>
+
+		<div id="outerframe">
+		  <div id="main">
+				<h2>Installing and upgrading</h2>
+				<ul>
+					<li><a href="../installation_guide.html">English installation guide</a></li>
+					<li><a href="installation_guide_french.html">French installation guide</a></li>
+					<li><a href="installation_guide_german.html">German installation guide</a></li>
+					<li><a href="installation_guide_slovenian.html">Slovenian installation guide</a></li>
+				</ul>
+
+			  <p>
+				  Are you interested in translating the installation guide to your own language? The best way to proceed is to ask us on the <a href="http://www.dokeos.com/forum/">Dokeos forum</a> for the latest version &ndash; there may be updates to the guide since this version was released &ndash; and send new translations off to the <a href="mailto:&#116;&#114;&#097;&#110;&#115;&#108;&#097;&#116;&#105;&#111;&#110;&#064;&#100;&#111;&#107;&#101;&#111;&#115;&#046;&#099;&#111;&#109;">&#116;&#114;&#097;&#110;&#115;&#108;&#097;&#116;&#105;&#111;&#110;&#064;&#100;&#111;&#107;&#101;&#111;&#115;&#046;&#099;&#111;&#109;</a> email address.
+			  </p>
+		  </div>
+		</div>
+		<hr/>
+	</body>
+</html>

+ 406 - 0
documentation/installation_guide_french.html

@@ -0,0 +1,406 @@
+<html>
+<head>
+<title>Dokeos community release 2.0 guide d'installation</title>
+<link rel="stylesheet" href="../main/css/default.css" type="text/css" media="screen,projection" />
+<link rel="shortcut icon" href="../favicon.ico" type="image/x-icon" />
+</head>
+<body>
+
+<div id="header1">
+<h1>Dokeos community release 2.0 guide d'installation </h1>
+</div>
+
+<div id="outerframe">
+<div id="main">
+
+<p>Merci d'avoir choisi  Dokeos !
+Ce texte vous guidera durant l'installation de Dokeos community release 2.0.
+Merci de prendre int&eacute;gralement connaissance des informations qu'il contient avant de proc&eacute;der &agrave; l'installation.</p>
+
+<p>Ce guide ne constitue qu'une aide br&egrave;ve pour l'installation. Nous r&eacute;digeons un manuel plus complet concernant l'installation, mais il n'est pas encore disponible au moment o&ugrave; vous lisez ces lignes. Lorsqu'il sera disponible, ce manuel sera accessible via la <a href="http://www.dokeos.com/documentation.php">page de documentation de Dokeos </a>. Vous pouvez aussi consulter la progression du travail de r&eacute;daction du manuel d'installation sur le <a href="http://www.dokeos.com/wiki/index.php/Manual">wiki</a>. Une FAQ est aussi disponible en ligne: <a href="http://www.dokeos.com/wiki/index.php/FAQ">Frequently Asked Questions</a>. </p>
+
+<p>
+<b>Contenu du guide d'installation </b>
+<ol>
+<li>El&eacute;ments requis pour l'installation </li>
+<li>Installer une nouvelle version de  Dokeos (installation fra&icirc;che) </li>
+<li>Mettre &agrave; jour  une version de Dokeos d&eacute;j&agrave; install&eacute;e </li>
+<li>Dysfonctionnements</li>
+<li>Administration</li>
+<li>Authentification Ldap (optionnel)</li>
+</ol>
+</p>
+
+<h2>1. El&eacute;ments requis pour l'installation</h2>
+<p>Dokeos est une application web qui n&eacute;cessite d'autres logiciels pour fonctionner:</p>
+<ul>
+<li>Un serveur web - Nous recommandons <strong>Apache</strong></li>
+<li><strong>PHP</strong></li>
+<li>Un serveur de bases de donn&eacute;es <strong>MySQL</strong></li>
+</ul>
+<p>
+Ces &eacute;lements doivent &ecirc;tre install&eacute;s sur votre serveur avant de proc&eacute;der &agrave; l'installation de Dokeos. 
+<br/>
+Vous pouvez installer ces &eacute;l&eacute;ments s&eacute;par&eacute;ment, m&eacute;thode qui donne souvent les meilleurs r&eacute;sultats. Cependant, l'utilisateur d&eacute;butant qui souhaite tester  Dokeos peut utiliser un <i> package</i> qui installe tous ces &eacute;l&eacute;ments en une seule fois. Si vous souhaitez utiliser un tel <i>package</i>, nous vous recommandons d'installer Wamp (t&eacute;l&eacute;chargeable &agrave; l'adresse <a href="http://www.wampserver.com/en/index.php">WAMP5</a>, vous aurez alors besoin de <a href="http://www.wampserver.com/en/add-ons.php">PHP4 add-on</a>) ou <a href="http://www.apachefriends.org/en/index.html">XAMP</a>.
+</p>
+
+<h3>1.1. Un serveur web</h3>
+<p>
+Le serveur web Apache est recommand&eacute;, et Dokeos est pr&eacute;-configur&eacute; pour utiliser les fonctions de s&eacute;curit&eacute; d'Apache si cel&agrave; est possible. Cependant, d'autres serveus web feront aussi l'affaire. Pour une meilleure s&eacute;curit&eacute;, vous devez activer le module Apache  mod_rewrite. Les r&egrave;gles mod_rewrite pour Dokeos sont inscrites dans un fichier.htaccess  dans le dossier de chaque cours, Apache doit permettre cette utilisation (AllowOverride FileInfo dans le fichier httpd.conf).
+<br/>
+<br/>
+<a href="http://httpd.apache.org/download.cgi">T&eacute;l&eacute;charger le serveur web Apache</a><br/>
+<a href="http://httpd.apache.org/docs-project/">Consulter le manuel du serveur web Apache</a>
+</p>
+
+<h3>1.2. PHP</h3>
+<p>
+Vous avez besoin de PHP version 4.3.2 ou plus r&eacute;cent (versions 4.x ), configur&eacute; avec les modules suivants : mysql, zlib, preg, xml. PHP  5 ou plus r&eacute;cent n'est pas encore support&eacute; par Dokeos.
+Vous aurez aussi besoin du module ldap si vous souhaitez utiliser une authentification ldap avec Dokeos.
+La plupart des distributions compil&eacute;es de PHP 4 sont fournies avec ces modules.
+De toute fa&ccedil;on, leur pr&eacute;sence est v&eacute;rifi&eacute;e par Dokeos au moment de l'installation.
+<br/>
+<br/>
+<a href="http://www.php.net/downloads.php">T&eacute;l&eacute;charger PHP</a><br/>
+<a href="http://www.php.net/docs.php">Consulter le manuel de PHP</a>
+</p>
+
+<p>
+Vous pourriez rencontrer des probl&egrave;mes si PHP  comprend un param&eacute;trage diff&eacute;rent de :</p>
+<ul>
+<li>short_open_tag       = On</li>
+<li>safe_mode            = Off</li>
+<li>magic_quotes_gpc     = On</li>
+<li>magic_quotes_runtime = Off</li>
+</ul>
+<p>
+Les versions ant&eacute;rieures de Dokeos n&eacute;cessitaient register_globals param&eacute;tr&eacute; sur On. Ce n'est plus n&eacute;cessaire, ce param&egrave;tre peut &ecirc;tre r&eacute;gl&eacute; sur Off, Dokeos fonctionnera correctement.
+</p>
+
+<p><strong>Utilisateus de BSD:</strong> ces librairies php doivent &ecirc;tre incluses durant l'installation de php:</p>
+<ul>
+<li>php-mysql extension mysql pour php</li>
+<li>php-pcre extension pcre pour php</li>
+<li>php-session extension session pour php</li>
+<li>php-zlib extension zlib pour php</li>
+<li>php-xml</li>
+<li>(optionnel) php-ldap si vous souhaitez utiliser une authentification LDAP</li>
+</ul>
+
+<h3>1.3. Un serveur de bases de donn&eacute;es MySQL</h3>
+<p>
+Vous aurez besoin d'un identifiant et d'un mot de passe autorisant l'administration
+   et la cr&eacute;ation d'au moins une base de donn&eacute;es. Par d&eacute;faut, Dokeos cr&eacute;&eacute; une nouvelle base de donn&eacute;es pour chaque nouveau cours. Cela signifie que votre h&eacute;bergeur doit vous autoriser &agrave; cr&eacute;er et administrer plusieurs bases de donn&eacute;es.  Vous pouvez aussi proc&eacute;der &agrave; l'installation de Dokeos en utilisant une seule base de donn&eacute;es, pour cela, s&eacute;lectionnez l'option correspondante durant l'
+   installation.
+<br/><br/>
+<a href="http://dev.mysql.com/downloads/">T&eacute;l&eacute;charger le serveur de base de donn&eacute;es  MySQL</a><br/>
+<a href="http://dev.mysql.com/doc/mysql/en/index.html">Consulter le manuel de MySQL</a>
+</p>
+
+<p>
+<b>Note:</b><br/>
+Il semble que les caract&egrave;res (`) contenu dans les requ&ecirc;tes SQL de Dokeos depuis la version 1.3 ne fonctionnent pas avec les versions de MySQL
+ant&eacute;rieures &agrave; 3.23.6.
+</p>
+
+<h3>1.4. Autorisations </h3>
+<p>
+En outre, vous avez besoin d'un acc&egrave;s en &eacute;criture sur le dossier o&ugrave; Dokeos a &eacute;t&eacute; upload&eacute; ou d&eacute;compress&eacute;. En utilisation locale, sur une machine &eacute;quip&eacute;e de Windows, cela ne constitue pas un probl&egrave;me. A distance, vous devez &ecirc;tre autoris&eacute; &agrave; effectuer des modifications de CHMOD
+par FTP, telnet ou tout autre moyen.
+</p>
+
+<hr>
+<h2>2. Installer une nouvelle version de Dokeos (installation fra&icirc;che) </h2>
+
+<p>
+2.1. T&eacute;lecharger le package d'installation de Dokeos community 2.0 (.zip pour les utilisateurs de Windows ou .tar.gz pour les utilisateurs d'autres syst&egrave;mes d'exploitation) depuis la <a href="http://www.dokeos.com/download.php">page de t��hargement de Dokeos</a>.
+</p>
+
+<p>
+2.2. D&eacute;compressez le package d'installation. 
+La plupart des syst&egrave;mes d'exploitation effectuent cette op&eacute;ration au travers d'une interface graphique, si cela ne fonctionne pas, vous pouvez utiliser la ligne de commande, acc&eacute;der au dossier dans lequel vous avez t&eacute;l&eacute;charg&eacute; le package d'installation et saisir 
+   tar -zxvf dokeos-2.0.tar.gz
+</p>
+
+<p>
+2.3. Transf&eacute;rer par n'importe quel moyen (FTP, SCP, copie locale des fichiers) le contenu du  package d'installation de Dokeos 2.0 vers le site web sur votre serveur (racine ou sous-dossier). Le serveur web peut aussi &ecirc;tre votre machine, en local. Assurez-vous de copier tous les fichiers (archive, home, claroline, courses) ainsi que tous les fichiers .php.
+</p>
+
+<p>
+Pour les utilisateurs de Windows qui effectuent l'installation en local: si vous utilisez un package Apache/PHP/MySQL, vous devez simplement r&eacute;aliser un glisser/d&eacute;poser du contenu du  package d'installation de Dokeos vers le dossier web du package correspondant:</p>
+<ul>
+<li><strong>EasyPHP</strong> - C:\Program Files\easyphp\www\</li>
+<li><strong>WAMP</strong> - C:\Program Files\wamp\www\
+<li><strong>XAMP</strong> - C:\Program Files\xamp\www\</li>
+</ul> 
+
+<p>
+2.4. Les dossiers suivants doivent &ecirc;tre param&eacute;tr&eacute;s en lecture, &eacute;criture et ex&eacute;cution pour tous les utilisateurs:
+</p>
+<ul>
+<li>dokeos/main/inc/conf/</li>
+<li>dokeos/main/garbage/</li>
+<li>dokeos/main/upload/</li>
+<li>dokeos/archive/</li>
+<li>dokeos/courses/</li>
+<li>dokeos/home/</li>
+</ul>
+<p>
+Sur les syst&egrave;mes d'exploitation Linux, Mac OS X et BSD  vous pouvez r&eacute;aliser un CHMOD 777.
+Avec Windows, vous avez besoin de v&eacute;rifier les propri&eacute;t&eacute;s des dossiers (en effectuant un clic droit au dessus du nom).
+</p>
+
+<p>
+2.5. Les fichiers suivants doivent &ecirc;tre param&eacute;tr&eacute;s en lecture et &eacute;criture pour tous les utilisateurs:
+</p>
+<ul>
+<li>dokeos/main/inc/conf/claro_main.conf.php (si present)</li>
+<li>dokeos/home/*.html</li>
+</ul>
+<p>
+Sur les syst&egrave;mes d'exploitation Linux, Mac OS X et BSD vous pouvez r&eacute;aliser un CHMOD 666.
+Avec Windows, vous avez besoin de v&eacute;rifier les propri&eacute;t&eacute;s des dossiers (en effectuant un clic droit au dessus du nom). </p>
+
+<p>
+<b>NOTE:</b><br/>
+Ne modifiez pas les fichiers home_*.html directement. Pour r&eacute;aliser les modifications sur ces fichiers, choisissez
+"Configurer la page d'accueil " dans la section administration de  Dokeos.
+</p>
+
+<p>
+2.6. Ouvrez votre navigateur et saisissez l'adresse
+   http://www.yourserver.org/yoursite/dokeos/index.php.
+
+   Si vous installez Dokeos localement (pas sur un serveur distant) saisissez l'adresse:
+   http://localhost/dokeos/index.php
+</p>
+<p>
+2.7. Cliquez sur le bouton &quot;Installer&quot; et suivez les instructions qui s'affichent &agrave; l'&eacute;cran.
+
+   Pour les utilisateurs Windows: avec un package comme easyphp, dont les param&eacute;trages initiaux n'ont pas &eacute;t&eacute; modifi&eacute;s, l'identifiant et le mot de passe pour MySQL doivent rester vides.
+</p>
+<p>
+<strong>2.8. Configuration et securit&eacute; apr&egrave;s l'installation</strong>
+</p>
+
+<ul>
+<li><strong>Prot&eacute;ger le fichier de configuration : </strong>
+assurez-vous que personne ne puisse en modifier le contenu. Vous trouverez le fichier de configuration dans <em>(dokeos folder)</em>/main/inc/conf/claro_main.conf.php. R&eacute;duisez ses droits &agrave; la lecture seule (windows/xwindows: effectuez un clic droit au dessus du nom pour modifier les propri&eacute;t&eacute;s du fichier. Linux/bsd/macosx: r&eacute;alisez un CHMOD 444). Le fichier de configuration est cr&eacute;&eacute; par  Apache, ainsi, vous devez poss&eacute;der les droits n&eacute;cessaires (root) pour modifier les permissions.</li>
+<li><strong>Prot&eacute;ger le dossier d'installation : </strong> si le dossier
+<em>(dokeos folder)</em>/main/install est toujours accessible, une nouvelle installation &eacute;crasant la v&ocirc;tre est possible (vous perdriez ainsi toutes vos donn&eacute;es). D&eacute;placez le dossier en dehors de votre dossier web pour le rendre inaccessible, modifiez son nom, ou modifiez ses propri&eacute;t&eacute;s de telle sorte que personne ne puisse le lire ou l'&eacute;xecuter.</li>
+<li><strong>Pour une meilleure s&eacute;curit&eacute; : </strong>
+affecter les droits en &eacute;criture sur les fichiers rendra plus facile l'installation, et r&eacute;soudra de nombreux probl&egrave;mes pour ceux qui ne poss&egrave;dent pas une exp&eacute;rience avanc&eacute;e d'administrateur. Cependant, vous am&eacute;liorerez la s&eacute;curit&eacute; en rendant le propri&eacute;taire du processus apache (appel&eacute; apache ou www-data) aussi propri&eacute;taire de tous les fichiers et dossiers de Dokeos. Ainsi les fichiers doivent seulement &ecirc;tre en lecture et &eacute;criture pour le propri&eacute;taire du processus Apache, pas pour l'ensemble des utilisateurs.</li>
+<li><strong>Configurer votre installation Dokeos : </strong>
+dans la section administration de Dokeos, vous pouvez utiliser le param&eacute;trage de configuration de Dokeos pour modifier le comportement de votre installation.</li>
+<li><strong>Configurer la fonction mail de Dokeos : </strong>
+la plupart des utilisateurs de Dokeos utilisent les param&eacute;trages du fichier php.ini. Cependant, l'outils annonces exploite phpMailer (un autre projet open-source) et le param&eacute;trage de cet outil doit &ecirc;tre ajust&eacute; dans <em>(dokeos folder)</em>/main/inc/conf/mail.conf.php.</li>
+</ul>
+
+<hr>
+<h2>3. Mettre &agrave; jour une version de Dokeos d&eacute;j&agrave; install&eacute;e </h2>
+
+<p>
+Avant de proc&eacute;der &agrave; la mise &agrave; jour, nous vous recommandons tr&egrave;s vivement de r&eacute;aliser une sauvegarde compl&egrave;te de la pr&eacute;c&eacute;dente installation (dossiers et bases de donn&eacute;es). Si vous n'&ecirc;tes pas certain de savoir mener  la proc&eacute;dure de sauvegarde, demandez conseil &agrave; votre h&eacute;bergeur pour pouvoir ensuite r&eacute;aliser cette op&eacute;ration.
+
+Si vous mettez &agrave; jour depuis Dokeos 1.6 ou 1.6.1, vous pouvez simplement copier les nouveaux fichiers de la version  1.6.2 afin d'&eacute;craser les fichiers de l'ancienne version. Si vous upgradez depuis une version plus ancienne (1.5.x),
+utilisez l'outil de mise &agrave; niveau, comme d&eacute;crit ci-dessous.
+</p>
+
+<p>
+3.1. T&eacute;l&eacute;chargez le package d'installation Dokeos 1.6.2 (.zip pour les utilisateurs Windows ou.tar.gz pour les autres utilisateurs) depuis la <a href="http://www.dokeos.com/download.php">page de t&eacute;l&eacute;chargement de Dokeos</a>. </p>
+
+<p>
+3.2. D&eacute;compressez le package d'installation. La plupart des syst&egrave;mes d'exploitation effectuent cette op&eacute;ration au travers d'une interface graphique, si cela ne fonctionne pas, vous pouvez utiliser la ligne de commande, acc&eacute;der au dossier dans lequel vous avez t&eacute;l&eacute;charg&eacute; le package d'installation et saisir tar -zxvf dokeos-1.6.2.tar.gz </p>
+
+<p>
+3.3. D&eacute;placez le dossier Dokeos  vers une localisation diff&eacute;rente de la pr&eacute;c&eacute;dente version</p>
+<p>
+<b>Attention:</b><br/>
+Ne supprimez pas le pr&eacute;c&eacute;dent dossier d'installation de Dokeos avant d'installer la nouvelle version. Lorsque le mise &agrave; jour sera termin&eacute;e, vous pourrez supprimer l'ancienne localisation.
+</p>
+<p>
+<b>Astuce:</b><br/>
+Si vous souhaitez que Dokeos 1.6.2 soit install&eacute; dans le m&ecirc;me dossier que l'installation pr&eacute;c&eacute;dente:
+
+<ul>
+<li>d&eacute;placez l'ancien dossier vers une nouvelle localisation (par exemple de dokeos/ vers dokeos_old/)</li>
+<li>d&eacute;compressez Dokeos 1.6.2 dans l'ancien dossier (par exemple dans  dokeos/)</li>
+<li>passez &agrave; l'&eacute;tape suivante </li>
+</ul>
+</p>
+3.4. Les fichiers suivants doivent &ecirc;tre param&eacute;tr&eacute;s en lecture et &eacute;criture pour tous les utilisateurs:
+<ul>
+<li>dokeos/main/inc/conf/claro_main.conf.php (si present)</li>
+<li>dokeos/home/*.html</li>
+</ul>
+
+Sur les syst&egrave;mes d'exploitation Linux, Mac OS X et BSD vous pouvez r&eacute;aliser un CHMOD 666. Avec Windows, vous avez besoin de v&eacute;rifier les propri&eacute;t&eacute;s des dossiers (en effectuant un clic droit au dessus du nom).
+<p>
+<b>NOTE:</b><br/>
+Ne modifiez pas les fichiers home_*.html directement. Pour r&eacute;aliser les modifications sur ces fichiers, choisissez "Configurer la page d'accueil " dans la section administration de Dokeos.</p>
+
+<p>
+3.5. Les dossiers suivants doivent &ecirc;tre param&eacute;tr&eacute;s en lecture, &eacute;criture et ex&eacute;cution pour tous les utilisateurs:
+<ul>
+<li>dokeos/main/inc/conf/</li>
+<li>dokeos/main/garbage/</li>
+<li>dokeos/main/upload/</li>
+<li>dokeos/archive/</li>
+<li>dokeos/courses/</li>
+<li>dokeos/home/</li>
+</ul>
+
+Sur les syst&egrave;mes d'exploitation Linux, Mac OS X et BSD vous pouvez r&eacute;aliser un CHMOD 777. Avec Windows, vous avez besoin de v&eacute;rifier les propri&eacute;t&eacute;s des dossiers (en effectuant un clic droit au dessus du nom).
+</p>
+
+<p>
+3.6.  Ouvrez votre navigateur et saisissez l'adresse
+   http://www.yourserver.org/yoursite/dokeos/index.php.
+
+   Si vous installez Dokeos localement (pas sur un serveur distant) saisissez l'adresse:
+   http://localhost/dokeos/index.php</p>
+
+<p>
+3.7. Cliquez sur le bouton &quot;Installer&quot;, puis sur "Update from Dokeos 1.5 | 1.5.4 | 1.5.5" et suivez les instructions qui s'affichent &agrave; l'&eacute;cran.
+</p>
+
+<p>
+3.8. <i>Cette partie de l'installation est optionnelle !</i><br/>
+   Depuis apr&egrave;s la version 1.5.5, les tables suivantes appartenant &agrave; la base dokeos_main peuvent &ecirc;tre supprim&eacute;es lors de la mise &agrave; jour depuis une version  1.5.5 version ou ant&eacute;rieure, &agrave; condition que vous ne les utilisiez pas pour une personnalisation de votre installation  Dokeos:
+
+<ul>
+<li>`todo`</li>
+<li>`pma_bookmark`</li>
+<li>`pma_column_comments`</li>
+<li>`pma_pdf_pages`</li>
+<li>`pma_relation`</li>
+<li>`pma_table_coords`</li>
+<li>`pma_table_info`</li>
+</ul>
+   
+Ces tables peuvent &ecirc;tre supprim&eacute;es en se connectant &agrave; la base de donn&eacute;es comme administrateur et en ex&eacute;cutant la requ&ecirc;te:
+     DROP TABLE dokeos_main.my_table;
+o&ugrave;   dokeos_main   est le nom de la base de donn&eacute;es principale de Dokeos et o&ugrave; 
+           my_table	 repr&eacute;sente chacune des tables pr&eacute;c&eacute;dentes (r&eacute;peter la requ&ecirc;te pour chacune des tables).
+
+<br/>
+<br/>
+   Le nettoyage des champs inutilis&eacute;s a aussi eu une influence sur le code:
+   	 main_db.cours. cours_id a &eacute;t&eacute; supprim&eacute;, comme toutes les r&eacute;f&eacute;rences &agrave; ce champ contenues dans le code officiel de Dokeos. Le code du cours (litt&eacute;ral) est utilis&eacute; &agrave; la place. Mettez &agrave; jour  les adaptations de votre code si c'est n&eacute;cessaire.
+
+<br/>
+<br/>
+   Comme pour la suppression des tables, les champs suivants peuvent &ecirc;tre supprim&eacute;s &agrave; la condition qu'ils ne soient pas utilis&eacute;s &agrave; des fins de personnalisation dans votre code, en utilisant une requ&ecirc;te:
+     ALTER TABLE database.table drop column abc
+   o&ugrave;   database     est le nom de la base de donn&eacute;es (dokeos_main? or code of a course),
+           table	est le nom de la table (cours?)
+	   abc		est le nom du champ &agrave; &eacute;liminer.
+   Vous pouvez aussi &eacute;liminer les champs suivants:
+   
+   <ul>
+<li>`_dokeos_main_`.`cours`.`versionDb`</li>
+<li>`_dokeos_main_`.`cours`.`versionClaro`</li>
+<li>`_dokeos_main_`.`cours`.`cahier_charges`</li>
+<li>`_dokeos_main_`.`faculte`.`bc`
+<br/>
+<i># la table `faculte` a &eacute;t&eacute; renomm&eacute;e  `course_category` depuis la version 1.6</i></li>
+<li>`_cours_`.`announcement`.`code_cours`</li>
+<li>`_cours_`.`course_description`.`upDate`</li>
+</ul>
+     
+</p>
+
+<h2>4. Dysfonctionnements </h2>
+<p>
+Dans le futur, nous fournirons aussi les instructions pour r&eacute;aliser une installation &quot;manuelle&quot; de  Dokeos, en cr&eacute;ant les tables par vous-m&ecirc;me.
+
+Si vous rencontrez un quelconque probl&egrave;me, consultez le <a href="http://www.dokeos.com">site de Dokeos</a> et posez vos questions sur le <a href="http://www.dokeos.com/forum/">forum de support</a>. Prenez d'abord connaissance des messages  post&eacute;s ant&eacute;rieurement pour voir si une r&eacute;ponse &agrave; votre question n'est pas d&eacute;ja disponible. Une FAQ est aussi disponible en ligne: <a href="http://www.dokeos.com/wiki/index.php/FAQ">Frequently Asked Questions</a>.
+</p>
+
+<h2>5. Administration</h2>
+<p>
+Pour acc&eacute;der &agrave; la section Administration de Dokeos, ouvrez votre navigateur,
+saisissez l'adresse de votre site Dokeos et identifiez-vous en tant qu'administrateur. Vous acc&egrave;derez &agrave; la plate-forme d'administration via un lien situ&eacute; dans l'ent&ecirc;te de la page.
+</p>
+
+<h2>6. LDAP</h2>
+<p>
+<i>Cette partie est optionnelle, seules les organisations utilisant un serveur LDAP ont besoin de ces informations.</i><br/>
+Un module LDAP est fourni avec Dokeos, mais il doit &ecirc;tre configur&eacute; pour pouvoir &ecirc;tre exploitable.
+</p>
+
+<p>
+<b>Compilation</b><br/>
+Serveurs Linux: il est possible que vous ayez &agrave; recompiler php avec le support de ldap.
+Les distributions r&eacute;centes autorisent le t&eacute;l&eacute;chargement de rpms pour les packages aditionnels.
+</p>
+
+<p>
+<b>Activer LDAP dans Dokeos</b><br/>
+Dans (dokeos folder)/main/inc/conf/claro_main.conf.php, aux environs de la ligne 90, vous pouvez lire: <br/>
+//for new login module<br/>
+//uncomment these to activate ldap<br/>
+//$extAuthSource['ldap']['login'] = "./main/auth/ldap/login.php";<br/>
+//$extAuthSource['ldap']['newUser'] = "./main/auth/ldap/newUser.php";<br/>
+<br/>
+supprimez les // situ&eacute;s devant les deux derni&egrave;res lignes pour activer LDAP.<br/>
+</p>
+
+<p>
+<b>Param&eacute;trages</b><br/>
+R&eacute;cup&eacute;rez les informations du serveur LDAP aupr&egrave;s de l'administrateur:
+<ul>
+<li>ldap server name</li>
+<li>ldap server port (habituellement 389)</li>
+<li>ldap dc</li>
+</ul>
+Vous devez saisir ces informations dans (dokeos folder)/main/auth/ldap/ldap_var.inc.php
+<br/>
+//parameters for LDAP module<br/>
+$usesLDAP						=	TRUE;<br/>
+$usesCurriculum					=	FALSE;<br/>
+$ldaphost = "myldapserver.com";  // your ldap server<br/>
+$ldapport = 389;                 // your ldap server's port number<br/>
+$ldapDc = "dc=xx, dc=yy, dc=zz"; //domain<br/>
+</p>
+
+<p>
+<b>Statut Enseignant/Etudiant</b><br/>
+Si vous le souhaitez, vous pouvez affecter le statut d'Enseignant ou d'Etudiant aux utilisateurs de Dokeos conform&eacute;ment aux informations disponibles dans le serveur ldap.
+Cependant, ce n'est pas automatique, vous devrez modifier le code:
+main/auth/ldap/ldap_var.inc.php
+aux environs de la ligne 189, fonction putUserInfoInClaroline ($login, $infoArray)
+</p>
+
+<p>
+if (<i>votre crit&egrave;re </i>)<br/>
+{<br/>
+   $statut = STUDENT;<br/>
+}<br/>
+else<br/>
+{<br/>
+   $statut = COURSEMANAGER;<br/>
+}<br/>
+</p>
+
+<p>
+Si cela vous semble trop difficile, une solution plus simple consiste &agrave; &eacute;crire
+$statut = STUDENT; et &agrave; donner les droits d'Enseignant via la section Administration de Dokeos.
+</p>
+
+<p>
+<b>Serveurs LDAP prot&eacute;g&eacute;s </b><br/>
+Quelques serveurs LDAP ne supportent pas l'utilisation anonyme du dossier services.
+Dans ce cas, vous devrez mettre en place un code utilisant identifiant et mot de passe. Ce code est disponible, adressez une demande sur le forum ou par courriel pour l'obtenir.</p>
+
+<p>
+<hr>
+Contact address: Dokeos, 44 rue des palais, B-1030 Brussels, Belgium<br/>
+Mail: info@dokeos.com
+<hr>
+</p>
+
+</div>
+</div>
+
+</body></html>

+ 458 - 0
documentation/installation_guide_german.html

@@ -0,0 +1,458 @@
+<html><head><title>Dokeos community release 2.0 Installationshandbuch</title>
+
+<link rel="stylesheet" href="../main/css/default.css" type="text/css" media="screen,projection"> 
+<link rel="shortcut icon" href="http://cvs.sourceforge.net/viewcvs.py/*checkout*/dokeos/dokeos/dokeos/favicon.ico" type="image/x-icon"></head>
+<body>
+
+<div id="header1">
+<h1>Dokeos community release 2.0 Installationshandbuch</h1>
+</div>
+
+<div id="outerframe">
+<div id="main">
+
+<p>Herzlichen Dank fr das Herunterladen von Dokeos!
+Dieser Text wird Ihnen die Grundlagen der Installation von Dokeos 2.0 fhren.
+Lesen sie die Informationen bitte sorgf�tig durch, bevor Sie mit der Installation beginnen.</p>
+
+<p>Dies ist lediglich eine kurze Anleitung fr die Installatin. Wir sind dabei, ein Handbuch mit weiteren 
+Informationen zu schreiben; dieses ist leider zum jetzigen Zeitpunkt noch nicht fertig. Nach Fertigstellung 
+wird das Handbuch ber die <a href="http://www.dokeos.com/documentation.php">Dokeos documentation</a> Seite 
+verfgbar sein. Sie k�nen die Arbeitskopie im jetzigen Stand auf unserem <a href="http://www.dokeos.com/wiki/index.php/Manual">Web WIKI</a> anschauen.</p>
+
+<p>
+<b>Inhalt</b>
+</p><ol>
+<li>Voraussetzungen</li>
+<li>Installation einer neuen Dokeos Version</li>
+<li>Upgrade einer vorigen Dokeos Version</li>
+<li>M�liche Probleme</li>
+<li>Administration</li>
+<li>Ldap (optional)</li>
+</ol>
+<p></p>
+
+<h2>1. Voraussetzungen</h2>
+<p>Dokeos ist eine Web Applikation, die einige andere Software ben�igt:</p>
+<ul>
+<li>Webserver - wir empfehlen <strong>Apache</strong></li>
+<li><strong>PHP</strong></li>
+<li><strong>MySQL</strong> Datenbankserver</li>
+</ul>
+<p>
+Diese Software Pakete mssen auf dem Computer installiert sein, wo Sie Dokeos installieren wollen. 
+<br>
+Sie k�nen diese Software Pakete separat installieren, was oft zu den besten Ergebnissen fhrt. Allerdings k�nen 
+Anwender mit weniger Kenntnissen, die Dokeos testen wollen, ein <i>kombiniertes Paket</i> benutzen; wir empfehlen 
+Wamp (Download von <a href="http://www.wampserver.com/en/index.php">The WAMP5 Website</a>, zus�zlich ben�igt man 
+das <a href="http://www.wampserver.com/en/add-ons.php">PHP4 add-on</a>) oder <a href="http://www.apachefriends.org/en/index.html">XAMP</a>.</p>
+
+<h3>1.1. Webserver</h3>
+<p>
+Der Apache Webserver wird empfohlen, und Dokeos ist so konfiguriert, da�einige 
+der Apache Erweiterungen benutzt werden, falls vorhanden. Andere Webserver sind aber 
+m�lich. Die besten Ergebnisse fr Sicherheit erreicht man, wenn das Apache Modul mod_rewrite 
+aktiviert ist. Die mod_reqrite Regeln fr Dokeos werden aus einer .htaccess Datei im Kursverzeichnis 
+gelesen, daher mu�Apache dies gestatten (AllowOverride FileInfo in httpd.conf).
+<br><br>
+<a href="http://httpd.apache.org/download.cgi">Download Apache Webserver</a><br>
+<a href="http://httpd.apache.org/docs-project/">Apache Webserver Handbuch</a>
+</p>
+
+<h3>1.2. PHP</h3>
+<p>PHP Version 4.3.2 oder sp�er (4.x Versionen) sind notwendig, und die folgenden Module mssen 
+konfiguriert sein: mysql, zlib, preg, xml. PHP Version 5 oder sp�er wird bislang von Dokeos noch 
+nicht untersttzt.
+Falls Ldap mit Dokeos benutzt werden soll, mu�auch das ldap Modul eingebunden sein. 
+Die meisten der kompilierten PHP4 Distributionen enthalten diese Module.
+Dokeos prft bei der Installation, ob diese vorhanden sind.<br><br>
+<a href="http://www.php.net/downloads.php">Download PHP</a><br>
+<a href="http://www.php.net/docs.php">PHP Handbuch</a>
+</p>
+                                    
+<p>
+Einige Benutzer k�nten Probleme haben, wenn PHP folgende Einstellungen nicht hat:</p>
+<ul>
+<li>short_open_tag       = On</li>
+<li>safe_mode            = Off</li>
+<li>magic_quotes_gpc     = On</li>
+<li>magic_quotes_runtime = Off</li>
+</ul>
+<p>
+�tere Dokeos Versionsn erforderten Past register_globals = on. Dies ist nicht mehr l�ger 
+erforderlich, auch bei off wird Dokeos korrekt laufen.</p>
+
+<p><strong>BSD Benutzer:</strong> Die nachfolgenden Bibliotheken mssen w�rend der PHP Installation 
+eingebunden werden:</p>
+<ul>
+<li>php-mysql Die mySQL Erweiterung fr PHP</li>
+<li>php-pcre Die pcre Erweiterung fr PHP</li>
+<li>php-session Die session Erweiterung fr PHP</li>
+<li>php-zlib Die zlib Erweiterung fr PHP</li>
+<li>php-xml</li>
+<li>(optional) php-ldap falls die LDAP Authentifizierung benutzt werden soll</li>
+</ul>
+
+<h3>1.3. Der MySQL Datenbankserver</h3>
+<p>Sie ben�igen ein Login und Passwort, mit dem Sie den Server administrieren oder zumindest eine Datenbank 
+anlegen k�nen. Per Default legt Dokeos fr jeden Kurs eine neue Datenbank an; was bedeutet, da�Ihr 
+Provider Ihnen gestatten sollte, mehrere Datenbanken anzulegen und zu administrieren. Die k�nen Dokeos auch 
+installieren mit der Option, nur eine Datenbank zu verwenden, diese Option mssen Sie dann w�rend der 
+Intallation ausw�len.
+<br><br>
+<a href="http://dev.mysql.com/downloads/">Download MySQL Server</a><br>
+<a href="http://dev.mysql.com/doc/mysql/en/index.html">MySQL Server Handbuch</a>
+</p>
+
+<p>
+<b>Bitte beachten:</b><br>
+Es scheint, als wrden ` Zeichen, die in SQL Abfragen eingefgtsind, nicht 
+mit �teren MySQL Versionen (�ter als 3.23.6) nicht funktionieren.</p>
+
+<h3>1.4. Erlaubnisse</h3>
+<p>
+Weiterhin ben�igt das Serververzeichnis, in das Sie Dokeos entpackt haben "Write" Rechte. Auf einem lokalen 
+Windows Rechner ist das kein Problem. Auf einem remote Server mssen Sie die Rechte vergeben k�nen durch CHMOD 
+per FTP, Telnet o.�
+</p>
+
+<hr>
+<h2>2. Installation einer neuen Dokeos Version</h2>
+
+<p>
+2.1. Download des Dokeos 1.6.1 Installationspakets (.zip fr Windows Benutzer oder  .tar.gz fr alle anderen) 
+von der <a href="http://www.dokeos.com/download.php">Dokeos download</a> Seite.
+</p>
+
+<p>
+2.2. Unzip oder untar das heruntergeladene Paket. 
+Die meisten neueren Betriebssysteme k�nen dies mittels einer integrierten Software, falls das nicht geht, 
+�fnen Sie die Kommandozeile, gehen zum Download Verzeichnis und geben ein: 
+   tar -zxvf dokeos-1.6.1.beta.tar.gz
+</p>
+
+<p>2.3. Inhalt des Dokeos Installationspakets auf Ihre Website auf dem Webserver hochladen 
+(z.B. per FTP, SCP, Datei kopieren), entweder in das webroot Verzeichnis oder ein Unterverzeichnis. Der 
+Webserver kann auch ihr lokaler Computer sein.  Vergewissern Sie sich, da�alle Verzeichnisse angelegt 
+werden (archive, home, claroline, courses) und alle php Dateien kopiert wurden.
+</p>
+
+<p>Fr Windows Benutzer, die Dokeos loakl installieren: Falls Sie ein 
+Apache/PHP/MySQL Paket benutzen, kopieren Sie den Inhalt des Dokeos Pakets einfach in das Web Verzeichnis 
+des Kombipakets:</p>
+<ul>
+<li><strong>EasyPHP</strong> - C:\Program Files\easyphp\www\</li>
+<li><strong>WAMP</strong> - C:\Program Files\wamp\www\
+</li><li><strong>XAMP</strong> - C:\Program Files\xamp\www\</li>
+</ul> 
+
+<p>
+2.4. Die nachfolgenden Verzeichnisse mssen fr alle readable, writeable und executable sein:
+</p>
+<ul>
+<li>dokeos/main/inc/conf/</li>
+<li>dokeos/main/garbage/</li>
+<li>dokeos/main/upload/</li>
+<li>dokeos/archive/</li>
+<li>dokeos/courses/</li>
+<li>dokeos/home/</li>
+</ul>
+<p>
+Auf Linux, Mac OS X und BSD Betriebssystemen k�nen Sie hierfr den CHMOD 777 Befehl verwenden.
+In Windows mssen Sie vielleicht die Verzeichnis Eigenschaften (per rechts Klick) prfen.
+</p>
+
+<p>
+2.5. Die nachfolgenden Dateien mssen fr alle readable und writeable sein:
+</p>
+<ul>
+<li>dokeos/main/inc/conf/claro_main.conf.php (wenn vorhanden)</li>
+<li>dokeos/home/*.html</li>
+</ul>
+<p>
+Auf Linux, Mac OS X und BSD Betriebssystemen k�nen Sie hierfr den CHMOD 666 Befehl verwenden.
+In Windows mssen Sie vielleicht die Verzeichnis Eigenschaften (per rechts Klick) prfen.
+</p>
+
+<p>
+<b>Bitte beachten:</b><br>
+Die home_*.html Dateien nicht direkt bearbeiten. Benutzen Sie stattdessen die "Homepage konfigurieren" Option 
+in der Dokeos Administration.
+</p>
+
+<p>
+2.6. �fnen sie einen Webbrowser und gehen Sie zu 
+   http://www.ihrserver.org/ihresite/dokeos/index.php
+
+   Falls Sie Dokeos lokal installieren (nicht auf einem remote Server) �fnen Sie:
+   http://localhost/dokeos/index.php
+</p>
+<p>
+2.7. Klicken Sie auf den "Installieren" Button und folgen Sie den Anweisungen.
+
+   Windows: Mit Kombinationspaketen wie easyphp, wo nichts ver�dert wurde, sollten Login und Passwort
+   fr MySQL wahrscheinlich leer bleiben.
+</p>
+<p>
+<strong>2.8. Konfiguration und Sicherheit nach der Installation</strong>
+</p>
+
+<ul>
+<li><strong>Schtzen Sie ihre Konfigurationsdatei: </strong>
+Vergewissern Sie sich, da�niemand die Datei berschreiben kann. Die Konfigurationsdatei befindet sich hier: <em>(Dokeos Verzeichnis)</em>/main/inc/conf/claro_main.conf.php.
+Die Datei sollte nur lesbar sein (Windows/XWindows: rechts Klick auf die Datei und die Eigenschaften anpassen. 
+linux/bsd/macosx: den chmod 444 Befehl benutzen). Die Konfigurationsdatei wird von Apache erstellt, daher mssen Sie 
+eventuell ein "root" Benutzer sein, um die Erlaubnisse zu ver�dern.</li>
+<li><strong>Installationsverzeichnis schtzen: </strong>
+falls das <em>(Dokeos Verzeichnis)</em>/main/install Verzeichnis weiterhin erreichbar ist, k�nte 
+jemand ber Ihre vorhandene Installation neu installieren (Sie k�nten Daten verlieren). Verschieben Sie 
+das Verzeichnis ausserhalb der Webverzeichnisse, wo es nicht mehr fr einen Browser erreichbar ist, �dern Sie 
+den Verzeichnisnamen, oder bearbeiten Sie die Eigenschaften, damit niemand das Verzeichnis lesen oder Dateien 
+darin ausfhren kann.
+</li>
+<li><strong>Verbesserte Sicherheit: </strong>
+Die Dateien fr alle lesbar machen, erleichtert die Installation und hilft bei Problemen fr 
+die, welche keine Adminsitrator Erfahrung haben. Es ist aber sicherer, den Eigentmer des Apache Prozesses 
+(oft als apache oder www-data bezeichnet) auch zum Eigentmer aller Dokeos Verzeichnisse und Dateien zu 
+machen. So brauchen diese Dateien lediglich fr den Apache Prozess readable und writeable zu sein, nicht aber 
+fr alle.</li>
+<li><strong>Ihre Dokeos Installation konfigurieren: </strong>
+In der Administration von Dokeos, k�nen Sie die Dokeos Konfiguration benutzen, um das Verhalten Ihrer Dokeos 
+Installation anzupassen.</li>
+<li><strong>Dokeos Mail konfigurieren: </strong>
+Dokeos benutzt zumeist die Mail Einstellungen aus der php.ini Datei. Das Modul "Ankndigungen" benutzt 
+phpMailer (ein anderes freies Software Projekt) und die Einstellungen fr dieses Werkzeug k�nen angepa� werden 
+in der <em>(Dokeos Verzeichnis)</em>/main/inc/conf/mail.conf.php Datei.</li>
+</ul>
+
+<hr>
+<h2>3. Upgrade von einer �teren Dokeos Version</h2>
+
+<p>
+Vor einem Upgrade empfehlen wir, da�Sie unbedingt ein vollst�diges Backup der vorigen Dokeos Verzeichnisse und 
+Datenbanken durchfhren. Sollten Sie sich nicht sicher sein, wie man das erreicht, erkundigen Sie sich bei Ihrem 
+Provider nach Hilfestellung.
+
+Falls Sie ein Upgrade von Dokeos 1.6 durchfhren, k�nen Sie einfach die neuen Dateien von 1.6.1 ber die Dateien der vorigen Version kopieren. Falls Sie ein Upgrade von einer �teren Version durchfhren (1.5.x), mssen Sie die integrierte Upgrade 
+Funktion benutzen (Anleitungen weiter unten).
+</p>
+
+<p>
+3.1. Download des Dokeos 1.6.1 Installationspakets (.zip fr Windows users oderr .tar.gz fr alle anderen) von der <a href="http://www.dokeos.com/download.php">Dokeos Download</a> Seite.
+</p>
+
+<p>
+3.2. Unzip oder untar das heruntergeladene Installationspaket. 
+Die meisten neueren Betriebssysteme k�nen dies mittels einer integrierten Software, falls das nicht geht, 
+�fnen Sie die Kommandozeile, gehen zum Download Verzeichnis und geben ein: 
+   tar -zxvf dokeos-1.6.1.beta.tar.gz
+</p>
+
+<p>
+3.3. Verschieben Sie das Dokeos Verzeichnis in einen neuen Pfad, nicht in das der vorherigen Version.
+</p>
+<p>
+<b>WARNUNG:</b><br>
+L�chen Sie das Installationsverzeichnis der vorherigen Version nicht vor der Installation der neuen Version! Nachdem das 
+Update erfolgreich durchgefhrt wurde, k�nen Sie den alten Pfad entfernen.
+</p>
+<p>
+<b>TIPP:</b><br>
+Falls Sie Dokeos 1.6.1 im gleichen Verzeichnis wie die vorherige Version installieren wollen:
+
+</p><ul>
+<li>verschieben Sie das alte Verzeichnis an einen neuen Ort (z.B. verschieben Sie dokeos/ nach dokeos_old/)</li>
+<li>entpacken Sie Dokeos 1.6.1 in das Verzeichnis der alten Version (z.B. entpacken Sie Dokeos 1.6.1 nach dokeos/)</li>
+<li>gehen Sie zum n�hsten Schritt</li>
+</ul>
+<p></p>
+
+<p>
+3.4. Die nachfolgenden Dateien mssen fr alle readable und writeable sein:
+
+</p><ul>
+<li>dokeos/main/inc/conf/claro_main.conf.php (falls vorhanden)</li>
+<li>dokeos/home/*.html</li>
+</ul>
+<p>
+Auf Linux, Mac OS X und BSD Betriebssystemen k�nen Sie hierfr den CHMOD 666 Befehl verwenden.
+In Windows mssen Sie vielleicht die Verzeichnis Eigenschaften prfen.
+</p>
+
+<p>
+<b>Bitte beachten:</b><br>
+Die home_*.html Dateien nicht direkt bearbeiten. Benutzen Sie stattdessen die "Homepage konfigurieren" Option 
+in der Dokeos Administration.
+</p>
+
+<p>
+3.5. Die nachfolgenden Verzeichnisse mssen fr alle readable, writeable und executable sein:
+</p>
+<ul>
+<li>dokeos/main/inc/conf/</li>
+<li>dokeos/main/garbage/</li>
+<li>dokeos/main/upload/</li>
+<li>dokeos/archive/</li>
+<li>dokeos/courses/</li>
+<li>dokeos/home/</li>
+</ul>
+<p>
+Auf Linux, Mac OS X und BSD Betriebssystemen k�nen Sie hierfr den CHMOD 777 Befehl verwenden.
+In Windows mssen Sie vielleicht die Verzeichnis Eigenschaften prfen.
+</p>
+
+<p>
+3.6. �fnen sie einen Webbrowser und gehen Sie zu 
+   http://www.ihrserver.org/ihresite/dokeos/index.php
+
+   Falls Sie Dokeos lokal installieren (nicht auf einem remote Server) �fnen Sie:
+   http://localhost/dokeos/index.php
+</p>
+<p>
+3.7. Klicken Sie auf den "Installieren" Button, danach auf "Update from Dokeos 1.5 | 1.5.4 | 1.5.5" 
+    und folgen Sie den Anweisungen.
+</p>
+
+<p>
+3.8. <i>Dieser Teil ist optional!</i><br>
+   Nach der Version 1.5.5 k�nen nachfolgende Tabellen aus der dokeos_main Datenbank entfernt werden, wenn 
+   man ein Update von 1.5.5 oder �ter durchgfhrt, vorausgesetzt, Sie benutzen diese nicht fr bestimmte 
+   Anpassungen Ihrer Dokeos Installation:
+
+</p><ul>
+<li>`todo`</li>
+<li>`pma_bookmark`</li>
+<li>`pma_column_comments`</li>
+<li>`pma_pdf_pages`</li>
+<li>`pma_relation`</li>
+<li>`pma_table_coords`</li>
+<li>`pma_table_info`</li>
+</ul>
+   
+Diese Tabellen kann man entfernen, indem man sich als Dokeos User mit der Datenbank verbindet und folgende Abfrage 
+durchfhrt:
+     DROP TABLE dokeos_main.my_table;
+     where dokeos_main   is the main dokeos database name and
+           my_table	 is each of the preceding tables (fr jede Tabelle wiederholen)
+
+<br><br>
+   Eine Bereinigung der nicht mehr benutzten Felder hat ebenfalls den Code beeinflu�:
+   	Das Feld main_db.cours.cours_id wurde entfernt, wie auch alle Bezugnahmen auf dieses Feld innerhalb des 
+   	offiziellen Dokeos Codes. Der Kurs Code wird stattdessen benutzt. �dern/erg�zen Sie von Ihnen angepa�en 
+   	Code dementsprechend, falls dies notwendig ist.
+
+<br><br>
+   Unter den gleichen Umst�den wie bei der Entfernung von Tabellen k�nen auch die nachfolgenden Felder 
+   entfernt werden, solange sie nicht von Ihrem speziellen Code benutzt werden, indem Sie folgende Abfrage 
+   durchfhren:
+     ALTER TABLE database.table drop column abc
+     where database     ist der Datenbankname (dokeos_main? oder Code eines Kurses)
+           table	ist der Tabellenname (Kurs?)
+	   abc		ist der Name des zu entfernenden Feldes
+   Sie k�nen auf diese Weise folgende Felder entfernen:
+   
+<ul>
+<li>`_dokeos_main_`.`cours`.`versionDb`</li>
+<li>`_dokeos_main_`.`cours`.`versionClaro`</li>
+<li>`_dokeos_main_`.`cours`.`cahier_charges`</li>
+<li>`_dokeos_main_`.`faculte`.`bc`
+<br><i># die Tabelle `faculte` wurde seit 1.6 umbenannt in `course_category`</i></li>
+<li>`_cours_`.`announcement`.`code_cours`</li>
+<li>`_cours_`.`course_description`.`upDate`</li>
+</ul>
+     
+<p></p>
+
+<h2>4. Problembehandlung</h2>
+<p>
+In Zukunft werden wir auch Anleitungen fr eine Dokeos Installation "per Hand" bereitstellen, wo Sie die Datenbank Tabellen selbst erstellen.
+
+Bei Problemen gehen Sie zur  <a href="http://www.dokeos.com/">Dokeos Website</a> und stellen Sie Ihre Fragen in unserem  
+<a href="http://www.dokeos.com/forum/">Support Forum</a>. Lesen Sie bitte zuerst frhere Nachrichten, um zu sehen, ob es bereits eine Antwort auf Ihre Frage gibt. Wir fhren auch eine Liste von 
+<a href="http://www.dokeos.com/wiki/index.php/FAQ">H�fig gestellte Fragen</a>.
+</p>
+
+<h2>5. Administration</h2>
+<p>
+Um die Dokeos Administration zu benutzen, �fnen Sie den Browser, gehen Sie zu Ihrer Dokeos Adresse und loggen Sie sich als Administrator ein. Dann sehen Sie einen Link fr "Plattform Administration" imKopfbereich der Seite.
+</p>
+
+<h2>6. LDAP</h2>
+<p>
+<i>Dieser Teil ist optional. Nur Organisationen mit einem LDAP Server werden diese Information ben�igen</i><br>
+Ein LDAP Modul wird in Dokeos bereitgestellt, mu�aber zur Benutzung manuell konfiguriert werden.
+</p>
+
+<p>
+<b>Kompilieren</b><br>
+Linux Server: Es k�nte sein, da�Sie PHP mit LDAP Untersttzung neu kompilieren mssen. Neuere Distributionen erlauben auch Download von rpms fr zus�zliche Pakete.</p>
+
+<p>
+<b>LDAP in Dokeos aktivieren</b><br>
+In (Dokeos Verzeichnis)/main/inc/conf/claro_main.conf.php, etwa in Zeile 90, sehen Sie <br>
+//for new login module<br>
+//uncomment these to activate ldap<br>
+//$extAuthSource['ldap']['login'] = "./main/auth/ldap/login.php";<br>
+//$extAuthSource['ldap']['newUser'] = "./main/auth/ldap/newUser.php";<br>
+<br>
+Entfernen Sie die // vor den beiden letzten Zeilen, um LDAP zu aktivieren</p>
+
+<p>
+<b>Einstellungen</b><br>
+Fragen Sie den Administrator des LDAP server fr die Einstellungen:
+</p><ul>
+<li>ldap Server Name</li>
+<li>ldap Server Port (gew�nlich  389)</li>
+<li>ldap dc</li>
+</ul>
+Diese Werte mssen Sie eingeben in 
+(Dokeos Verzeichnis)/main/auth/ldap/ldap_var.inc.php
+<br>
+//parameters for LDAP module<br>
+$usesLDAP	 =	TRUE;<br>
+$usesCurriculum	 =	FALSE;<br>
+$ldaphost = "myldapserver.com";  // your ldap server<br>
+$ldapport = 389;                 // your ldap server's port number<br>
+$ldapDc = "dc=xx, dc=yy, dc=zz"; //domain<br>
+<p></p>
+
+<p>
+<b>Kursleiter/Student Status</b><br>
+Falls gewnscht, k�nen Sie Kursleiter/Student Stauts entsprechend der Einstellungen auf dem LDAP Server 
+an Dokeos Benutzer vergeben.
+Dies ist allerdings kein Standardfeld, Sie mssen dazu den Code ein wenig ver�dern.
+main/auth/ldap/ldap_var.inc.php
+etwa in Zeile 189, function putUserInfoInClaroline ($login, $infoArray)
+</p>
+
+<p>
+if (<i>Ihr Kriterium</i>)<br>
+{<br>
+   $statut = STUDENT;<br>
+}<br>
+else<br>
+{<br>
+   $statut = COURSEMANAGER;<br>
+}<br>
+</p>
+
+<p>
+Falls dies zu schwierig erscheint, ist die einfachste L�ung, zun�hst einfach 
+$statut = STUDENT anzugeben; und Kursleitern dann ber die Dokeos Administration Rechte zu vergeben.
+</p>
+
+<p>
+<b>Geschtzte LDAP Server</b><br>
+Einige LDAP Server untersttzen keine anonymous Benutzung der Verzeichnis Dienste. In diesem Fall ben�igen Sie Code, der mit einem Namen und Passwort bindet - dieser Code wurde schon bereitgestellt, fragen Sie im Forum danach oder schicken Sie uns eine E-Mail.</p>
+
+<p>
+</p><hr>
+Kontakt Adresse: Dokeos, 44 rue des palais, B-1030 Brussels, Belgien<br>
+E-Mail: info@dokeos.com
+<hr>
+<p></p>
+
+</div>
+</div>
+
+</body></html>

+ 845 - 0
documentation/installation_guide_slovenian.html

@@ -0,0 +1,845 @@
+<html><head><title>VodiÄ? po namestitvi Dokeos community release 2.0</title>
+
+<meta http-equiv="Content-Type" content="text/html; charset=windows-1250" />
+
+<link rel="stylesheet" href="../main/css/default.css" type="text/css" media="screen,projection" />
+
+<link rel="shortcut icon" href="../favicon.ico" type="image/x-icon" />
+
+
+
+</head>
+
+<body>
+
+
+
+<div id="header1">
+
+<h1>VodiÄ? po namestitvi Dokeos community release 2.0</h1>
+
+</div>
+
+
+
+<div id="outerframe">
+
+<div id="main">
+
+
+
+<p>Zahvaljujemo se vam, ker ste si prenesli Dokeos!
+
+To besedilo vas bo vodilo preko osnovnih korakov namestitve Dokeos 2.0.
+
+Preberite ga v celoti preden priÄ?nete z namestitvijo.</p>
+
+
+
+<p>Ta vodiÄ? je dostopen tudi v drugih jezikih, seznam se nahaja na <a href="documentation/index.html">tej strani</a>. Spletna stran Dokeos bo vsebovala obvestilo vsakiÄ?, ko bo dostopen nov prevod.</p>
+
+
+
+<p>Tole je le kratek vodiÄ? po postopku namestitve. Pripravljamo priroÄ?nik
+
+s podrobnejšimi informacijami o namestitvi, ki pa v Ä?asu nastanka tega dokumenta še ni na voljo. Ko bo, bo priroÄ?nik dostopen na naslovu <a href="http://www.dokeos.com/documentation.php">Dokeos documentation page</a>. Nastajanje priroÄ?nika si lahko ogledate na <a href="http://www.dokeos.com/wiki/index.php/Manual">web writing area</a>. VzdrĹľujemo tudi seznam <a href="http://www.dokeos.com/wiki/index.php/FAQ">pogosto zastavljenih vprašanj (FAQ)</a>.</p>
+
+
+
+<p>
+
+<b>Vsebina</b>
+
+
+
+</p><ol>
+
+<li>Zahteve</li>
+
+<li>Namestitev nove razliÄ?ice Dokeos</li>
+
+<li>Nadgradnja predhodne razliÄ?ice Dokeos</li>
+
+<li>Odpravljanje teĹľav</li>
+
+<li>Administracija</li>
+
+<li>Ldap (opcijsko)</li>
+
+</ol>
+
+<p></p>
+
+
+
+<h2>1. Zahteve</h2>
+
+
+
+<p>Dokeos je spletna aplikacija, ki za svoje delovanje zahteva nekaj dodatne programske opreme:</p>
+
+<ul>
+
+<li>Spletni streĹľnik - priporoÄ?amo <strong>Apache</strong></li>
+
+<li><strong>PHP</strong></li>
+
+<li><strong>MySQL</strong> streĹľnik podatkovne baze</li>
+
+</ul>
+
+<p>
+
+Ta programska oprema mora biti namešÄ?ena na raÄ?unalniškem sistemu preden priÄ?nete z namestitvijo Dokeos. 
+
+<br />
+
+Zahtevano programsko opremo lahko namestite po delih (vsako posamezno), kar ponavadi daje boljše rezultate. Uporabniki zaÄ?etniki, ki bi Ĺľeleli preskusiti
+
+Dokeos, pa lahko uporabijo <i>sestavljen paket programske opreme (bundle)</i>
+
+
+
+, ki vse potrebno namesti z enim samim namestitvenim postopkom. ÄŚe Ĺľelite tak sestavljen paket, priporoÄ?amo Wamp (dostopen na <a href="http://www.wampserver.com/en/index.php">WAMP5 spletni strani</a>, pri tem potrebujete tudi <a href="http://www.wampserver.com/en/add-ons.php">PHP4 add-on</a>) ali <a href="http://www.apachefriends.org/en/index.html">XAMP</a>.
+
+</p>
+
+
+
+<h3>1.1. Spletni streĹľnik</h3>
+
+<p>
+
+PriporoÄ?amo Apache spletni streĹľnik. Dokeos vsebuje moĹľnosti izkorišÄ?anja
+
+nakaterih Apache varnostnih mehanizmov. ÄŚe vam ta ne odgovorja, lahko uporabite poljuben drug spletni streĹľnik.
+
+ Za ustrezno uporabo varnostnih mehanizmov Apache spletnega streĹľnika, morate namestiti in aktivirati Apache modul <b>mod_rewrite</b>. Pravila mod_rewrite za Dokeos
+
+so zapisana v <b>.htaccess</b> datoteki mape <b>courses</b>, torej jih morate omogoÄ?iti v nastavitvah streĹľnika Apache (<b>AllowOverride FileInfo</b> v datoteki <b>httpd.conf</b>).
+
+
+
+<br /><br />
+
+<a href="http://httpd.apache.org/download.cgi">Prenesi si Apache spletni streĹľnik</a><br />
+
+<a href="http://httpd.apache.org/docs-project/">PriroÄ?nik za uporabo Apache spletnega streĹľnika</a>
+
+</p>
+
+
+
+<h3>1.2. PHP</h3>
+
+<p>Potrebujete PHP verzije 4.3.2 ali kasnejše (4.x verzije), konfiguriranega z
+
+naslednjimi moduli : mysql, zlib, preg, xml. PHP verzije 5 ali novejši
+
+še niso podprti s strani Dokes.
+
+Potrebujete tudi ldap modul , Ä?e Ĺľelite uporabljati ldap v povezavi z Dokeos.
+
+VeÄ?ina PHP4 predprevedenih distribucij prihaja z vsemi naštetimi moduli.
+
+Kakorkoli Ĺľe, njihova prisotnost se preveri v Dokeos namestitvenem postopku.
+
+<br /><br />
+
+<a href="http://www.php.net/downloads.php">Prenesi si PHP</a><br />
+
+<a href="http://www.php.net/docs.php">PHP priroÄ?nik</a>
+
+</p>
+
+
+
+<p>
+
+Nekateri uporabniki lahko naletijo na teĹľave v primeru, de se nastavitev PHP razlikuje od:</p>
+
+<ul>
+
+<li>short_open_tag       = On</li>
+
+<li>safe_mode            = Off</li>
+
+<li>magic_quotes_gpc     = On</li>
+
+<li>magic_quotes_runtime = Off</li>
+
+</ul>
+
+<p>
+
+Predhodne razliÄ?ice Dokeos zahtevajo <b>register_globals</b> nastavljen na vrednost <b>On</b>. To ni veÄ? potrebno.
+
+
+
+</p>
+
+
+
+<p><strong>BSD uporabniki:</strong> naslednje php knjiĹľnjice (moduli) morajo biti vkljuÄ?eni v namestitev php:</p>
+
+<ul>
+
+<li><b>php-mysql</b> The mysql shared extension for php</li>
+
+<li><b>php-pcre</b> The pcre shared extension for php</li>
+
+<li><b>php-session</b> The session shared extension for php</li>
+
+<li><b>php-zlib</b> The zlib shared extension for php</li>
+
+<li><b>php-xml</b></li>
+
+<li>(opcijsko) <b>php-ldap</b> Ä?e Ĺľelite uporabiti LDAP autentifikacijo</li>
+
+</ul>
+
+
+
+<h3>1.3. MySQL streĹľnik podatkovne baze</h3>
+
+<p>Potrebujete uporabniško ime in geslo, ki dovoljujeta upravljanje in kreiranje vsaj ene podatkovne baze.
+
+Dokeos vam prednastavljeno kreira novo podatkovno bazo z vsakim kreiranim teÄ?ajem.
+
+To pomeni, da vam mora streĹľnik dovoliti kreiranje in upravljanje veÄ?ih podatkovnih baz.
+
+V postopku namestitve lahko izberete namestitev z eno samo podatkovno bazo, Ä?e vam ponudnik storitve ne omogoÄ?a kreiranje veÄ?ih.
+
+<br /><br />
+
+<a href="http://dev.mysql.com/downloads/">Prenesi si MySQL streĹľnik</a><br />
+
+
+
+<a href="http://dev.mysql.com/doc/mysql/en/index.html">MySQL uporabniški priroÄ?nik</a>
+
+</p>
+
+
+
+<p>
+
+<b><i>Opomba:</i></b><br />
+
+Vse kaĹľe da znak za povešenko /backticks character/ <b>(`)</b>, vstavljen v veÄ?ino
+
+Dokeos SQL povpraševanj od razliÄ?ice 1.3 ne deluje z MySQL
+
+verzijami pred 3.23.6.
+
+</p>
+
+
+
+<h3>1.4. Pravice dostopa</h3>
+
+<p>
+
+Nadalje, potrebujete pisalni dostop (Write access) pri dostopu do spletnih map, kjer se nahaja namešÄ?en Dokeos. Na Windows platformah z lokalno namestitvijo to ni problem. Pri oddaljenem dostopu pa potrebujete dovoljenje za funkcijo CHMOD vsled uporabe protokolov FTP, telnet ali drugih.
+
+</p>
+
+
+
+<hr>
+
+<h2>2. Namestitev nove razliÄ?ice Dokeos</h2>
+
+
+
+<p>
+
+2.1. Prenesite si 2.0 namestitveni paket (.zip za Windows uporabnike ali .tar.gz za ostale) s <a href="http://www.dokeos.com/download.php">Dokeos spletnega naslova</a>.
+
+</p>
+
+
+
+<p>
+
+2.2. Dekomprimirajte (unzip / untar) prenesen namestitveni paket. 
+
+VeÄ?ina novejših operacijskih sistemov
+
+   je to zmoĹľna izvesti z vgrajenimi grafiÄ?nimi aplikacijami, Ä?e pa to ne deluje,
+
+   lahko to izvedete preko ukaznega poziva: v mapi, kamor ste si prenesli namestitveni paket odtipkajte
+
+   <b>tar -zxvf dokeos-2.0.tar.gz</b>
+
+</p>
+
+
+
+<p>2.3. Prestavite (FTP, SCP, lokalno kopiranje datotek) vsebino Dokeos namestitvenega paketa na Ĺľeleno spletno stran spletnega streĹľnika (ali v korensko mapo spletnega streĹľnika ali njegovo poljubno podmapo). Vaš spletni streĹľnik je lahko tudi vaš lokalni raÄ?unalnik. Pazite, da boste prestavili vse mape (archive, home, claroline,
+
+courses) kot tudi vse .php datoteke.
+
+</p>
+
+
+
+<p>Za Windows uporabnike, ki namešÄ?ajo Dokeos lokalno: Ä?e uporabljate
+
+Apache/PHP/MySQL sestavljen paket, uporabite funkcijo povleci in izpusti (drag and drop) na vsebini Dokeos namestitvenega paketa v WWW mapo namešÄ?enega sestavljenega paketa:</p>
+
+<ul>
+
+<li><strong>EasyPHP</strong> - C:\Program Files\easyphp\www\</li>
+
+<li><strong>WAMP</strong> - C:\Program Files\wamp\www\</li>
+
+<li><strong>XAMP</strong> - C:\Program Files\xamp\www\</li>
+
+
+
+</ul> 
+
+
+
+<p>
+
+2.4. Naslednje mape morajo imeti bralne, pisalne in izvršilne pravice za vse in vsakogar:
+
+</p>
+
+<ul>
+
+<li>dokeos/main/inc/conf/</li>
+
+<li>dokeos/main/garbage/</li>
+
+<li>dokeos/main/upload/</li>
+
+<li>dokeos/archive/</li>
+
+<li>dokeos/courses/</li>
+
+<li>dokeos/home/</li>
+
+
+
+</ul>
+
+<p>
+
+Na operacijskih sistemih Linux, Mac OS X in BSD lahko uporabite ukaz CHMOD 777 za dodeljevanje pravic.
+
+Pri Windows OS, preverite lastnosti map (klik z desnim miškinim gumbom na mapi).
+
+</p>
+
+
+
+<p>
+
+2.5. Naslednje mape morajo imeti bralne in pisalne pravice za vse in vsakogar:
+
+</p>
+
+<ul>
+
+<li>dokeos/main/inc/conf/claro_main.conf.php (Ä?e obstaja)</li>
+
+<li>dokeos/home/*.html</li>
+
+</ul>
+
+<p>
+
+Na operacijskih sistemih Linux, Mac OS X in BSD lahko uporabite ukaz CHMOD 666.
+
+Pri Windows OS, preverite lastnosti map (klik z desnim miškinim gumbom na mapi).
+
+</p>
+
+
+
+<p>
+
+<b><i>OPOMBA:</i></b><br />
+
+Ne spreminjajte vsebine <b>home_*.html</b> datotek direktno. Namesto tega,
+
+uporabite moĹľnost "Uredi domaÄ?o stran" v Dokeos administracijskem podroÄ?ju.
+
+</p>
+
+
+
+<p>
+
+2.6. Odprite okno spletnega brskalnika in pojdite na
+
+   http://www.vasstreznik.org/vasastran/dokeos/index.php
+
+
+
+   ÄŚe ste Dokeos namestili lokalno, odprite:
+
+   http://localhost/dokeos/index.php
+
+</p>
+
+<p>
+
+2.7. Kliknite na gumb <b>install</b> in sledite navodilom.
+
+
+
+   Windows: pri uporabi sestavljenega paketa, kot je npr. easyphp, bosta uporabniško ime in geslo
+
+   za MySQL verjetno prazna /ju ni/.
+
+
+
+</p>
+
+<p>
+
+<strong>2.8. Nastavitve in varnost po postopku namestitve</strong>
+
+</p>
+
+
+
+<ul>
+
+<li><strong>ZašÄ?ita datoteke z nastavitvami: </strong>
+
+zagotovite, da je nihÄ?e ne bo mogel spremeniti. Datoteko z nastavitvami najdete na <em>(dokeos mapa)</em>/main/inc/conf/claro_main.conf.php.
+
+Naredite jo zgolj bralno (windows/xwindows: desni miškin klik na datoteki, lastnosti. 
+
+linux/bsd/macosx: uporabite ukaz chmod 444 ). Datoteka z nastavitvami je generirana s strani Apache, torej boste morali imeti pravice root uporabnika za spremembo pravic.</li>
+
+<li><strong>ZašÄ?ita namestitvene mape: </strong>
+
+v primeru, da je <em>(dokeos mapa)</em>/main/install
+
+mapa še vedno dostopna, lahko nepooblašÄ?ena oseba izvrši novo namestitev preko trenutne namestitve  (s ponovno namestitvijo so vaši trenutni podatki lahko izgubljeni). Premaknite mapo nekam izven obsega
+
+vaših spletnih map, da preko spletnega streĹľnika ne bo dosegljiva, in spremenite lastnosti tako, da datotek ne bo mogel nihÄ?e brati in izvrševati.</li>
+
+
+
+<li><strong>Za boljšo varnost: </strong>
+
+nastavitev pravic dostopa na naÄ?in, da so vse datoteke in mape dostopne vsem pri pisalnih in izvršilnih dostopih, je lahko v pomoÄ? pri namestivi portala, in je tudi lahko v pomoÄ? pri reševanju doloÄ?enih problemov, predvsem za uporabnike z malo ali niÄ? administratorske prakse. Kakorkoli Ĺľe, za varnost je veliko bolje, da je lastnik vseh datotek in map Dokeos namestitve apache proces (obiÄ?ajno poimenovan apache, www ali httpd). Na ta naÄ?in, morajo datoteke namestitve biti le bralne in pisalne za lastnika (Apache proces), ne pa tudi za vse ostale.</li>
+
+<li><strong>Konfiguracija in prilagajanje Dokeos namestitve: </strong>
+
+v administracijskem podroÄ?ju Dokeos lahko uporabite Dokeos nastavitve za prilagoditev vaše namestitve.</li>
+
+<li><strong>Nastavitev Dokeos e-poštnih storitev: </strong>
+
+pretežni del Dokeos-a uporablja poštne nastavitve iz php.ini datoteke. Le
+
+orodje obvestil uporablja phpMailer (drug odprtokodni projekt)
+
+in nastavitve za to orodje se nahajajo v datoteki <em>(dokeos mapa)</em>/main/inc/conf/mail.conf.php.</li>
+
+</ul>
+
+
+
+<hr>
+
+
+
+<h2>3. Nadgradnja predhodne razliÄ?ice Dokeos</h2>
+
+
+
+<p>
+
+Pred nagraditvijo toplo priporoÄ?amo izdelavo popolne rezervne kopije trenutnih Dokeos map, njihove vsebine in podatkovnih baz. ÄŚe niste prepriÄ?ani, kako boste to izvedli, se obrnite po nasvet na gostitelja oz. ponudnika storitve. <br/>
+
+
+
+</p>
+
+
+
+<p>
+
+3.1. Prenesite si Dokeos 2.0 namestitveni paket (.zip za Windows uporabnike ali .tar.gz za vse ostale) s spletnega naslova <a href="http://www.dokeos.com/download.php">Dokeos download page</a>.
+
+</p>
+
+
+
+<p>
+
+3.2. Dekomprimirajte (unzip / untar) prenesen namestitveni paket. 
+
+VeÄ?ina novejših operacijskih sistemov
+
+   je to zmoĹľno izvesti z vgrajenimi grafiÄ?nimi aplikacijami, Ä?e pa to ne deluje,
+
+   lahko to izvedete preko ukaznega poziva: v mapi, kamor ste si prenesli namestitveni paket odtipkajte
+
+   <b>tar -zxvf dokeos-2.0.tar.gz</b>
+
+
+
+</p>
+
+
+
+<p>
+
+3.3. Premaknite Dokeos mapo pod koren mape spletnega streĹľnika, proÄ? od obstojeÄ?e namestitve
+
+</p>
+
+<p>
+
+<b><i>OPOZORILO:</i></b><br />
+
+Ne brišite obstojeÄ?e namestitve Dokeos pred namestitvijo nove. Staro namestitev lahko odstranite šele po uspešnem zakljuÄ?ku nadgraditve.
+
+</p>
+
+<p>
+
+<b><i>NASVET:</i></b><br />
+
+ÄŚe Ĺľelite namestiti Dokeos 2.0 v isto mapo, kot je bil namešÄ?en pred nadgraditvijo:
+
+
+
+<ul>
+
+<li>prestavite mapo s staro namestitvijo na novo mesto (npr. move dokeos/  dokeos_old/)</li>
+
+
+
+<li>dekomprimirajte Dokeos 2.0 na mesto stare namestitve (npr. dekomprimirajte Dokeos 2.0 v dokeos/)</li>
+
+<li>pojdite na naslednji korak nadgraditve</li>
+
+</ul>
+
+</p>
+
+
+
+<p>
+
+3.4. Naslednje datoteke morajo biti bralne in pisalne za vsakogar:
+
+
+
+<ul>
+
+<li>dokeos/main/inc/conf/claro_main.conf.php (Ä?e obstaja)</li>
+
+<li>dokeos/home/*.html</li>
+
+</ul>
+
+
+
+Na operacijskih sistemih Linux, Mac OS X in BSD lahko uporabite ukaz CHMOD 666.
+
+Pri Windows OS, preverite lastnosti map (klik z desnim miškinim gumbom na mapi).
+
+
+
+</p>
+
+
+
+<p>
+
+<b><i>OPOMBA:</i></b><br />
+
+Ne spreminjajte vsebine <b>home_*.html</b> datotek direktno. Namesto tega 
+
+uporabite moĹľnost "Uredi domaÄ?o stran" v Dokeos administracijski sekciji.
+
+</p>
+
+
+
+<p>
+
+3.5. Naslednje mape morajo biti bralne, pisalne in izvršne za vsakogar:
+
+
+
+</p><ul>
+
+<li>dokeos/main/inc/conf/</li>
+
+<li>dokeos/main/garbage/</li>
+
+
+
+<li>dokeos/main/upload/</li>
+
+<li>dokeos/archive/</li>
+
+<li>dokeos/courses/</li>
+
+<li>dokeos/home/</li>
+
+</ul>
+
+
+
+Na operacijskih sistemih Linux, Mac OS X in BSD lahko uporabite ukaz CHMOD 777 za doseljevanje pravic.
+
+Pri Windows OS, preverite lastnosti map (klik z desnim miškinim gumbom na mapi).
+
+<p></p>
+
+
+
+<p>
+
+3.6. Odprite okno spletnega brskalnika in pojdite na
+
+   http://www.yourserver.org/yoursite/dokeos/index.php .<br />
+
+
+
+   Windows lokalno, z npr. easyphp ali drugim primerljivim, pojdite na:
+
+   http://localhost/dokeos/index.php
+
+</p>
+
+
+
+<p>
+
+3.7. Kliknite gumb install , nato kliknite na "Update from Dokeos 1.5 | 1.5.4 | 1.5.5" in sledite navodilom.
+
+</p>
+
+
+
+
+
+
+
+<h2>4. Odpravljanje teĹľav</h2>
+
+<p>
+
+V prihodnosti imamo namen zagotoviti navodila za "roÄ?no" namestitev Dokeos, vkljuÄ?no z "roÄ?nim" kreiranjem podatkovne baze in vseh potrebnih tabel.
+
+
+
+Če naletite na kakršenkoli problem, pojdite na <a href="http://www.dokeos.com/">Dokeos spletno stran</a> in zastavite vprašanje na našem
+
+
+
+<a href="http://www.dokeos.com/forum/">forumu podpore</a>. Preberi prosim najprej predhodna sporoÄ?ila! Lahko, da je bil vaš problem Ĺľe rešen, vprašanje predhodno Ĺľe zastavljeno. VzdrĹľujemo tudi seznam
+
+<a href="http://www.dokeos.com/wiki/index.php/FAQ">pogosto zastavljanih vprašanj</a>.
+
+</p>
+
+
+
+<h2>5. Administracija</h2>
+
+<p>
+
+Za dostop do Dokeos administracijskega podroÄ?ja, odprite brskalnik,
+
+pojdite na Dokeos naslov vašega portala in se prijavite kot adminstratorski uporabnik.
+
+Videli boste "Platform admin section / podroÄ?je Upravitelj teÄ?aja" povezavo v glavi spletne strani portala.
+
+</p>
+
+
+
+<h2>6. LDAP</h2>
+
+<p>
+
+<i>Ta del je opcijski, sledeÄ?e besedilo je namenjeno le organizacijam z LDAP streĹľnikom .</i><br />
+
+
+
+ LDAP modul je integriran v Dokeos distribucijo, potrebno ga je le ustrezno nastaviti, da ga usposobite za delo.
+
+</p>
+
+
+
+<p>
+
+<b>Prevajanje</b><br />
+
+Linux streĹľniki: MoĹľno je, da boste morali ponovno prevesti php z ldap podporo.
+
+Novejše distribucije tudi dovoljujejo selektiven prenos rpm-jev za dodatne podporne pakete.<br/> Enako velja tudi za BSD uporabnike.
+
+</p>
+
+
+
+<p>
+
+<b>Activiranje LDAP v Dokeos</b><br/>
+
+V (dokeos mapa)/main/inc/conf/claro_main.conf.php, okoli vrstice 90, se nahaja naslednje besedilo<br/>
+
+
+
+//for new login module<br/>
+
+//uncomment these to activate ldap<br/>
+
+//$extAuthSource['ldap']['login'] = "./main/auth/ldap/login.php";<br/>
+
+//$extAuthSource['ldap']['newUser'] = "./main/auth/ldap/newUser.php";<br/>
+
+<br/>
+
+odstranite // izpred zadnjih dveh vrstic za aktiviranje LDAP.<br/>
+
+</p>
+
+
+
+<p>
+
+<b>Nastavitve</b><br/>
+
+Pozanimajte se pri upravitelju LDAP streĹľnika za naslednje nastavitve:
+
+
+
+<ul>
+
+<li>ldap ime streĹľnika</li>
+
+<li>ldap streĹľniška vrata (obiÄ?ajno 389)</li>
+
+<li>ldap dc</li>
+
+</ul>
+
+Te vrednosti morate vnesti v datoteko
+
+(dokeos mapa)/main/auth/ldap/ldap_var.inc.php
+
+<br/>
+
+//parameters for LDAP module<br/>
+
+$usesLDAP                       =   TRUE;<br/>
+
+$usesCurriculum                 =   FALSE;<br/>
+
+$ldaphost = "myldapserver.com";  // vaš ldap strežnik<br/>
+
+
+
+$ldapport = 389;                 // vaša ldap številka strežniških vrat<br/>
+
+$ldapDc = "dc=xx, dc=yy, dc=zz"; //domena<br/>
+
+</p>
+
+
+
+<p>
+
+<b>UÄ?itelj/teÄ?ajnik status</b><br />
+
+ÄŚe Ĺľelite, lahko uÄ?itelju/teÄ?ajniku dodelite znotraj dokeos status iz vpisov ldap streĹľnika.
+
+To ni standarna moĹľnost, torej boste morali rahlo spremeniti programsko kodo:
+
+main/auth/ldap/ldap_var.inc.php
+
+okoli vrstice 189, function putUserInfoInClaroline ($login, $infoArray)
+
+</p>
+
+
+
+<p>
+
+if (<i>tvoj kriterij</i>)<br />
+
+
+
+{<br />
+
+   $statut = STUDENT;<br />
+
+}<br />
+
+else<br />
+
+{<br />
+
+   $statut = COURSEMANAGER;<br />
+
+}<br />
+
+</p>
+
+
+
+<p>
+
+ÄŚe se vam to zdi preteĹľko, je najenostavnejša rešitev ta, da enostavno doloÄ?ite
+
+$statut = STUDENT; in dodeljute upravljalcu teÄ?aja pravice preko administracijske sekcije portala.
+
+</p>
+
+
+
+<p>
+
+<b>ZašÄ?iteni LDAP streĹľniki</b><br />
+
+Nekateri LDAP streĹľniki ne podpirajo anonimne uporabe direktorijskih storitev
+
+V tem primeru, potrebujete dodatno programsko kodo, ki bo povezovala LDAP z uporabniškim imenom in geslom - koda je zagotovljena,
+
+le vprašajte na forumu ali jo zahtevajte preko e-pošte.
+
+</p>
+
+
+
+<p>
+
+<hr>
+
+Kontaktni naslov: Dokeos, 44 rue des palais, B-1030 Brussels, Belgium<br />
+
+E-pošta: info@dokeos.com
+
+<hr>
+
+
+
+</p>
+
+
+
+</div>
+
+</div>
+
+
+
+</body></html>

BIN
favicon.ico


+ 1 - 0
home/home_menu.html

@@ -0,0 +1 @@
+<li><a href="http://www.dokeos.com/forum/" target="_self">Forum</a></li>

+ 2 - 0
home/home_news.html

@@ -0,0 +1,2 @@
+<b>Dokeos News</b><br/><br/>
+To add, modify, remove news, go to the administration area of the portal.

+ 2 - 0
home/home_notice.html

@@ -0,0 +1,2 @@
+<b>Example notice</b><br/>
+To modify this notice, go to the administration area of the portal.

+ 11 - 0
home/home_top.html

@@ -0,0 +1,11 @@
+<br/>
+<img src="./home/large_dokeos_logo.gif" alt="Dokeos logo" />
+<br/>
+<br/>
+<b>Welcome on Soandso Online Campus</b>
+<br/>
+<br/>
+Introduction text (...).
+<br/>
+<br/>
+To modify this introduction text, go to the administration area of the portal.

BIN
home/large_dokeos_logo.gif


+ 609 - 0
index.php

@@ -0,0 +1,609 @@
+<?php
+/*
+==============================================================================
+	Dokeos - elearning and course management software
+
+	Copyright (c) 2004-2005 Dokeos S.A.
+	Copyright (c) 2003 Ghent University (UGent)
+	Copyright (c) 2001 Universite catholique de Louvain (UCL)
+	Copyright (c) various contributors
+
+	For a full list of contributors, see "credits.txt".
+	The full license can be read in "license.txt".
+
+	This program is free software; you can redistribute it and/or
+	modify it under the terms of the GNU General Public License
+	as published by the Free Software Foundation; either version 2
+	of the License, or (at your option) any later version.
+
+	See the GNU General Public License for more details.
+
+	Contact address: Dokeos, 44 rue des palais, B-1030 Brussels, Belgium
+	Mail: info@dokeos.com
+==============================================================================
+*/
+/**
+==============================================================================
+*	This is the index file displayed when a user arrives at Dokeos.
+*
+*	It dispalys:
+*	- tree of courses and categories
+*	- login form
+*	- public menu
+*
+*	Search for
+*	CONFIGURATION parameters
+*	to modify settings
+*
+*	@todo rewrite code to separate display, logic, database code
+*	@package dokeos.main
+==============================================================================
+*/
+/*
+==============================================================================
+	   INIT SECTION
+==============================================================================
+*/
+// only this script should have this constant defined
+define('DOKEOS_HOMEPAGE', true);
+// Don't change these settings
+define("SCRIPTVAL_No", 0);
+define("SCRIPTVAL_InCourseList", 1);
+define("SCRIPTVAL_UnderCourseList", 2);
+define("SCRIPTVAL_Both", 3);
+define("SCRIPTVAL_NewEntriesOfTheDay", 4);
+define("SCRIPTVAL_NewEntriesOfTheDayOfLastLogin", 5);
+define("SCRIPTVAL_NoTimeLimit", 6);
+// End 'don't change' section
+
+$langFile = array ('courses', 'index');
+$cidReset = true; /* Flag forcing the 'current course' reset,
+                   as we're not inside a course anymore  */
+/*
+-----------------------------------------------------------
+	Included libraries
+-----------------------------------------------------------
+*/
+//this includes main_api too:
+include_once ('./main/inc/global.inc.php');
+
+$this_section = SECTION_CAMPUS;
+
+
+include_once (api_get_path(LIBRARY_PATH).'course.lib.php');
+include_once (api_get_path(LIBRARY_PATH).'debug.lib.inc.php');
+include_once (api_get_path(LIBRARY_PATH).'events.lib.inc.php');
+include_once (api_get_path(LIBRARY_PATH).'system_announcements.lib.php');
+include_once (api_get_path(LIBRARY_PATH).'groupmanager.lib.php');
+include_once (api_get_path(LIBRARY_PATH).'formvalidator/FormValidator.class.php');
+if ($_GET['logout'])
+{
+	$query_string='';
+
+	if(!empty($_SESSION['user_language_choice']))
+	{
+		$query_string='?language='.$_SESSION['user_language_choice'];
+	}
+	
+	
+	//LoginDelete($_uid, $statsDbName);
+	LoginDelete($_GET["uid"], $statsDbName);
+	api_session_destroy();
+
+	header("Location: index.php$query_string");
+	exit();
+}
+/*
+-----------------------------------------------------------
+	Table definitions
+-----------------------------------------------------------
+*/
+//new table definitions, using database library
+//these already have backticks around them!
+$main_course_table = Database :: get_main_table(MAIN_COURSE_TABLE);
+$main_category_table = Database :: get_main_table(MAIN_CATEGORY_TABLE);
+$track_login_table = Database :: get_statistic_table(STATISTIC_TRACK_E_LOGIN_TABLE);
+/*
+-----------------------------------------------------------
+	Constants and CONFIGURATION parameters
+-----------------------------------------------------------
+*/
+// ---- Category list options ----
+/** defines wether or not anonymous visitors can see a list of the courses on
+the Dokeos homepage that are open to the world */
+define('DISPLAY_COURSES_TO_ANONYMOUS_USERS', true);
+define('CONFVAL_showNodeEmpty', true);
+define('CONFVAL_showNumberOfChild', false); // actually count are only for direct children
+define('CONFVAL_ShowLinkBackToTopOfTree', false);
+// ---- Course list options ----
+define("CONFVAL_showCourseLangIfNotSameThatPlatform", TRUE);
+// Preview of course content
+// to disable all: set CONFVAL_maxTotalByCourse = 0
+// to enable all: set e.g. CONFVAL_maxTotalByCourse = 5
+// by default disabled since what's new icons are better (see function display_digest() )
+define("CONFVAL_maxValvasByCourse", 2); // Maximum number of entries
+define("CONFVAL_maxAgendaByCourse", 2); //  collected from each course
+define("CONFVAL_maxTotalByCourse", 0); //  and displayed in summary.
+define("CONFVAL_NB_CHAR_FROM_CONTENT", 80);
+// Order to sort data
+$orderKey = array('keyTools', 'keyTime', 'keyCourse'); // default "best" Choice
+//$orderKey = array('keyTools', 'keyCourse', 'keyTime');
+//$orderKey = array('keyCourse', 'keyTime', 'keyTools');
+//$orderKey = array('keyCourse', 'keyTools', 'keyTime');
+define('CONFVAL_showExtractInfo', SCRIPTVAL_UnderCourseList);
+// SCRIPTVAL_InCourseList    // best choice if $orderKey[0] == 'keyCourse'
+// SCRIPTVAL_UnderCourseList // best choice
+// SCRIPTVAL_Both // probably only for debug
+//$dateFormatForInfosFromCourses = $dateFormatShort;
+$dateFormatForInfosFromCourses = $dateFormatLong;
+//define("CONFVAL_limitPreviewTo",SCRIPTVAL_NewEntriesOfTheDay);
+//define("CONFVAL_limitPreviewTo",SCRIPTVAL_NoTimeLimit);
+define("CONFVAL_limitPreviewTo", SCRIPTVAL_NewEntriesOfTheDayOfLastLogin);
+if (isset ($_uid))
+{
+	$nameTools = api_get_setting('siteName');
+}
+
+/*
+-----------------------------------------------------------
+	Check configuration parameters integrity
+-----------------------------------------------------------
+*/
+if (CONFVAL_showExtractInfo != SCRIPTVAL_UnderCourseList and $orderKey[0] != "keyCourse")
+{
+	// CONFVAL_showExtractInfo must be SCRIPTVAL_UnderCourseList to accept $orderKey[0] !="keyCourse"
+	if (DEBUG || api_is_platform_admin()) // Show bug if admin. Else force a new order
+		die("
+					<strong>
+					config error:".__FILE__."</strong>
+					<br/>
+					set
+					<ul>
+						<li>
+							CONFVAL_showExtractInfo=SCRIPTVAL_UnderCourseList
+							(actually : ".CONFVAL_showExtractInfo.")
+						</li>
+					</ul>
+					or
+					<ul>
+						<li>
+							\$orderKey[0] !=\"keyCourse\"
+							(actually : ".$orderKey[0].")
+						</li>
+					</ul>");
+	else
+	{
+		$orderKey = array ("keyCourse", "keyTools", "keyTime");
+	}
+}
+/*
+==============================================================================
+		LOGIN
+==============================================================================
+*/
+if ($_GET["submitAuth"] == 1)
+{
+	echo "Attempted breakin - sysadmins notified.";
+	session_destroy();
+	die();
+}
+if ($_POST["submitAuth"])
+{
+	// To ensure legacy compatibility, we set the following variables.
+	// But they should be removed at last.
+	$uid = $_uid;
+	$lastname		 = $_user['lastName'];
+	$firstname	 = $_user['firstName'];
+	$email			 = $_user['mail'];
+	$status			 = $uData['status'];
+	if (isset ($_uid))
+	{
+		$sqlLastLogin = "SELECT UNIX_TIMESTAMP(login_date)
+								FROM $track_login_table
+								WHERE login_user_id = '$_uid'
+								ORDER BY login_date DESC LIMIT 1";
+		$resLastLogin = api_sql_query($sqlLastLogin, __FILE__, __LINE__);
+		if (!$resLastLogin)
+			if (mysql_num_rows($resLastLogin) > 0)
+			{
+				$user_last_login_datetime = mysql_fetch_array($resLastLogin);
+				$user_last_login_datetime = $user_last_login_datetime[0];
+				api_session_register('user_last_login_datetime');
+			}
+		mysql_free_result($resLastLogin);
+		event_login();
+		if (api_is_platform_admin())
+		{
+			// decode all open event informations and fill the track_c_* tables
+			include (api_get_path(LIBRARY_PATH)."stats.lib.inc.php");
+			decodeOpenInfos();
+		}
+	}
+} // end login -- if($submit)
+else
+{
+	// only if login form was not sent because if the form is sent the user was
+	// already on the page.
+	event_open();
+}
+/*
+-----------------------------------------------------------
+	Header
+	include the HTTP, HTML headers plus the top banner
+-----------------------------------------------------------
+*/
+
+$help = "Clar";
+
+Display :: display_header('', $help);
+
+/*
+==============================================================================
+		FUNCTIONS
+
+		display_anonymous_right_menu()
+		display_anonymous_course_list()
+
+		display_login_form()
+		handle_login_failed()
+
+		display_lost_password_info()
+==============================================================================
+*/
+
+/*
+-----------------------------------------------------------
+	Display functions
+-----------------------------------------------------------
+*/
+
+/**
+ * Displays the right-hand menu for anonymous users:
+ * login form, useful links, help section
+ * Warning: function defines globals
+ * @version 1.0.1
+ */
+function display_anonymous_right_menu()
+{
+	global $loginFailed, $_plugins;
+
+	$platformLanguage = api_get_setting('platformLanguage');
+
+	$_uid = api_get_user_id();
+	if ( !(isset($_uid) && $_uid) ) // only display if the user isn't logged in
+	{
+		api_display_language_form();
+		display_login_form();
+		
+		if ($loginFailed)
+			handle_login_failed();
+		if (api_get_setting('allow_lostpassword') == 'true' OR api_get_setting('allow_registration') == 'true')
+		{
+			echo '<div class="menusection"><span class="menusectioncaption">'.get_lang('MenuUser').'</span><ul class="menulist">';
+			if (get_setting('allow_registration') <> 'false')
+			{
+				echo '<li><a href="main/auth/inscription.php">'.get_lang('Reg').'</a></li>';
+			}
+			if (get_setting('allow_lostpassword') == 'true')
+			{
+				display_lost_password_info();
+			}
+			echo '</ul></div>';
+		}
+		api_plugin('loginpage_menu');
+	}
+	
+	/*** hide right menu "general" and other parts on anonymous right menu  *****/
+	echo "<div class=\"menusection\">", "<span class=\"menusectioncaption\">".get_lang("MenuGeneral")."</span>";
+	 echo "<ul class=\"menulist\">";
+
+	$user_selected_language = $_SESSION["user_language_choice"];
+	if (!isset ($user_selected_language))
+		$user_selected_language = $platformLanguage;
+
+	if(!file_exists('home/home_menu_'.$user_selected_language.'.html'))
+	{
+		include ('home/home_menu.html');
+	}
+	else
+	{
+		include('home/home_menu_'.$user_selected_language.'.html');
+	}
+	 echo '</ul>';
+	echo '</div>';
+	
+	if ($_uid)
+	{
+		api_plugin('campushomepage_menu');
+	}
+
+/**** use this comment to hide notice file section from right menu ****
+
+	echo '<div class="note">';
+	// includes for any files to be displayed below anonymous right menu 
+	if(!file_exists('home/home_notice_'.$user_selected_language.'.html'))
+	{
+		include ('home/home_notice.html');
+	}
+	else
+	{
+		include('home/home_notice_'.$user_selected_language.'.html');
+	}
+	echo '</div>';
+
+**** end of hide various right menu items on anonymous right menu ****/
+}
+
+/**
+*	Reacts on a failed login:
+*	displays an explanation with
+*	a link to the registration form.
+*
+*	@version 1.0.1
+*/
+function handle_login_failed()
+{
+	switch ($_GET['error'])
+	{
+		case '':
+			$message = get_lang("InvalidId");
+			if (api_is_self_registration_allowed())
+			{
+				$message = get_lang("InvalidForSelfRegistration");
+			}		
+			break;
+		case 'account_expired':
+			$message=get_lang('AccountExpired');
+			break;
+		case 'account_inactive':
+			$message=get_lang('AccountInactive');
+			break;
+		case 'user_password_incorrect':
+			$message=get_lang('InvalidId');
+			break;						
+	}
+	echo "<div id=\"login_fail\">".$message."</div>";
+}
+
+/**
+*	Adds a form to let users login
+*	@version 1.1
+*/
+function display_login_form()
+{
+	$form = new FormValidator('formLogin');
+	$form->addElement('static',null,null,get_lang('UserName'));
+	$form->addElement('text','login','',array('size'=>15));
+	$form->addElement('static',null,null,get_lang('Pass'));
+	$form->addElement('password','password','',array('size'=>15));
+	$form->addElement('submit','submitAuth',get_lang('Ok'));
+	$form->display();
+}
+/**
+ * Displays a link to the lost password section
+ */
+function display_lost_password_info()
+{
+	echo "<li><a href=\"main/auth/lostPassword.php\">".get_lang("LostPassword")."</a></li>";
+}
+
+/**
+* Display list of courses in a category.
+* (for anonymous users)
+*
+* Warning: this function defines globals.
+* @version 1.0
+*/
+function display_anonymous_course_list()
+{
+	//init
+	global $coursesRepositoryWeb;
+	$web_course_path = api_get_path(WEB_COURSE_PATH);
+	$category = $_GET["category"];
+	$main_course_table = Database :: get_main_table(MAIN_COURSE_TABLE);
+	$main_category_table = Database :: get_main_table(MAIN_CATEGORY_TABLE);
+	$platformLanguage = api_get_setting('platformLanguage');
+
+	//get list of courses in category $category
+	$sql_get_course_list = "SELECT * FROM $main_course_table cours
+								WHERE category_code = '".$category."'
+								ORDER BY UPPER(visual_code)";
+	//removed: AND cours.visibility='".COURSE_VISIBILITY_OPEN_WORLD."'
+	$sql_result_courses = api_sql_query($sql_get_course_list, __FILE__, __LINE__);
+	
+	while ($course_result = mysql_fetch_array($sql_result_courses))
+	{
+		$course_list[] = $course_result;
+	}
+	
+	$sqlGetSubCatList = "
+				SELECT t1.name,t1.code,t1.parent_id,t1.children_count,COUNT(DISTINCT t3.code) AS nbCourse
+				FROM $main_category_table t1
+				LEFT JOIN $main_category_table t2 ON t1.code=t2.parent_id
+				LEFT JOIN $main_course_table t3 ON (t3.category_code=t1.code AND t3.visibility='".COURSE_VISIBILITY_OPEN_WORLD."')
+				WHERE t1.parent_id ". (empty ($category) ? "IS NULL" : "='$category'")."
+				GROUP BY t1.name,t1.code,t1.parent_id,t1.children_count ORDER BY t1.tree_pos";
+	
+	$resCats = api_sql_query($sqlGetSubCatList, __FILE__, __LINE__);
+	$thereIsSubCat = FALSE;
+	if (mysql_num_rows($resCats) > 0)
+	{
+		$htmlListCat = "<h4 style=\"margin-top: 0px;\">".get_lang("CatList")."</h4>"."<ul>";
+		while ($catLine = mysql_fetch_array($resCats))
+		{
+			if ($catLine['code'] != $category)
+			{
+				$htmlListCat .= "<li>";
+				
+				$category_has_open_courses = category_has_open_courses($catLine['code']);
+				if ($category_has_open_courses)
+				{
+					//the category contains courses accessible to anonymous visitors
+					$htmlListCat .= "<a href=\"".$_SERVER['PHP_SELF']."?category=".$catLine['code']."\">".$catLine['name']."</a>";
+					if (CONFVAL_showNumberOfChild)
+					{
+						$htmlListCat .= " (".$catLine['nbCourse']." ".get_lang("Courses").")";
+					}
+				}
+				elseif ($catLine['children_count'] > 0)
+				{
+					//the category has children, subcategories
+					$htmlListCat .= "<a href=\"".$_SERVER['PHP_SELF']."?category=".$catLine['code']."\">".$catLine['name']."</a>";
+				}
+				/************************************************************************
+				 end changed code to eliminate the (0 courses) after empty categories
+				 ************************************************************************/
+				elseif (CONFVAL_showNodeEmpty)
+				{
+					$htmlListCat .= $catLine['name'];
+				}
+				$htmlListCat .= "</li>\n";
+				$thereIsSubCat = true;
+			}
+			else
+			{
+				$htmlTitre = "<p>";
+				if (CONFVAL_ShowLinkBackToTopOfTree)
+				{
+					$htmlTitre .= "<a href=\"".$_SERVER['PHP_SELF']."\">"."&lt;&lt; ".get_lang("BackToHomePage")."</a>";
+				}
+				if (!is_null($catLine['parent_id']) || (!CONFVAL_ShowLinkBackToTopOfTree && !is_null($catLine['code'])))
+				{
+					$htmlTitre .= "<a href=\"".$_SERVER['PHP_SELF']."?category=".$catLine['parent_id']."\">"."&lt;&lt; ".get_lang("Up")."</a>";
+				}
+				$htmlTitre .= "</p>\n";
+				if ($category != "" && !is_null($catLine['code']))
+				{
+					$htmlTitre .= "<h3>".$catLine['name']."</h3>\n";
+				}
+				else
+				{
+					$htmlTitre .= "<h3>".get_lang("Categories")."</h3>\n";
+				}
+			}
+		}
+		$htmlListCat .= "</ul>\n";
+	}
+	echo $htmlTitre;
+	if ($thereIsSubCat)
+		echo $htmlListCat;
+	while ($categoryName = mysql_fetch_array($resCats))
+	{
+		echo "<h3>", $categoryName['name'], "</h3>\n";
+	}
+	$numrows = mysql_num_rows($sql_result_courses);
+	if ($numrows > 0)
+	{
+		if ($thereIsSubCat)
+			echo "<hr size=\"1\" noshade=\"noshade\">\n";
+		echo "<h4 style=\"margin-top: 0px;\">", get_lang("CourseList"), "</h4>\n", "<ul>\n";
+		while ($course = mysql_fetch_array($sql_result_courses))
+		{
+			echo "<li>\n", "<a href=\"".$web_course_path.$course['directory'], "/\">", $course['title'], "</a>", "<br/>", $course['visual_code'], " - ", $course['tutor_name'], ((CONFVAL_showCourseLangIfNotSameThatPlatform && $course['course_language'] != $platformLanguage) ? " - ".$course['course_language'] : ""), "\n", "</li>\n";
+		}
+		echo "</ul>\n";
+	}
+	else
+	{
+		// echo "<blockquote>",get_lang('_No_course_publicly_available'),"</blockquote>\n";
+	}
+	if ($category != "")
+	{
+		echo "<p>", "<a href=\"".$_SERVER['PHP_SELF']."\"><b>&lt;&lt;</b> ", get_lang("BackToHomePage"), "</a>", "</p>\n";
+	}
+}
+
+function category_has_open_courses($category)
+{
+	$main_course_table = Database :: get_main_table(MAIN_COURSE_TABLE);
+	$sql_query = "SELECT * FROM $main_course_table WHERE category_code='$category'";
+	$sql_result = api_sql_query($sql_query, __FILE__, __LINE__);
+	while ($course = mysql_fetch_array($sql_result))
+	{	
+		if ($is_allowed_anonymous_access) 
+		return true; //at least one open course
+	}
+	
+	return false;
+}
+
+/*
+==============================================================================
+		MAIN CODE
+==============================================================================
+*/
+
+echo '<div class="maincontent">';
+/*
+-----------------------------------------------------------------------------
+	Plugins for loginpage_main AND campushomepage_main
+-----------------------------------------------------------------------------
+*/
+if (!$_uid)
+{
+	api_plugin('loginpage_main'); 
+}
+else 
+{
+	api_plugin('campushomepage_main');
+}
+
+
+if (!empty ($_GET['include']) && !strstr($_GET['include'], '/') && strstr($_GET['include'], '.html'))
+{
+	include ('./home/'.$_GET['include']);
+	$pageIncluded = true;
+}
+else
+{
+	if(!file_exists('home/home_news_'.$user_selected_language.'.html'))
+	{
+	include ('home/home_top.html');
+	}
+	else
+	{
+	include('home/home_top_'.$user_selected_language.'.html');
+	}
+}
+
+// Display System announcements
+$announcement = $_GET['announcement'] ? $_GET['announcement'] : -1;
+SystemAnnouncementManager :: display_announcements(VISIBLE_GUEST, $announcement);
+
+// Display courses and category list
+if (!$pageIncluded)
+{
+//	echo '<div class="clear">&nbsp;</div>';
+	echo '<div class="home_cats">';
+	if (DISPLAY_COURSES_TO_ANONYMOUS_USERS)
+	{
+		display_anonymous_course_list();
+	}
+	echo '</div>';
+/*
+	echo '<div class="home_news">';
+	if(!file_exists('home/home_news_'.$user_selected_language.'.html'))
+	{
+		include ('home/home_news.html');
+	}
+	else
+	{
+		include('home/home_news_'.$user_selected_language.'.html');
+	}
+	echo '</div>';
+*/
+}
+echo '</div>';
+
+// Right Menu
+// language form, login section + useful weblinks
+echo '<div class="menu">';
+display_anonymous_right_menu();
+echo '</div>';
+/*
+==============================================================================
+		FOOTER
+==============================================================================
+*/
+Display :: display_footer();
+?>

+ 412 - 0
installation_guide.html

@@ -0,0 +1,412 @@
+<html>
+<head>
+<title>Dokeos 1.8 installation guide</title>
+<link rel="stylesheet" href="./main/css/default.css" type="text/css" media="screen,projection" />
+<link rel="shortcut icon" href="./favicon.ico" type="image/x-icon" />
+</head>
+<body>
+
+<div id="header1">
+<h1>Dokeos 1.8 installation guide</h1>
+</div>
+
+<div id="outerframe">
+<div id="main">
+
+<p>
+Thank you for downloading Dokeos!
+This text will guide you through the basics of installing Dokeos 1.8.
+Please read this fully before proceeding with the installation.
+</p>
+
+<p>
+The installation guide is also available in other languages, please see <a href="documentation/index.html">this overview page</a> for a list. The Dokeos website will notify when new translations are available.
+</p>
+<p>
+This is only a short installation guide. We are writing a manual with more info on installation, but this was not ready at the time of writing. When ready, this manual will be accessible through the <a href="http://www.dokeos.com/documentation.php">Dokeos documentation page</a>. You can read the work in progress manual on our <a href="http://www.dokeos.com/wiki/index.php/Manual">web writing area</a>. We also maintain a list of <a href="http://www.dokeos.com/wiki/index.php/FAQ">Frequently Asked Questions (FAQ)</a>.
+</p>
+
+<p>
+<b>Contents</b>
+<ol>
+<li><a href="#requirements">Requirements</a></li>
+<li><a href="#install_new_version">Installing a new version of Dokeos</a></li>
+<li><a href="#upgrade_previous_version">Upgrading from a previous version of Dokeos</a></li>
+<li><a href="#troubleshooting">Troubleshooting</a></li>
+<li><a href="#admin_section">Administration section</a></li>
+<li><a href="#ldap">Ldap (optional)</a></li>
+</ol>
+</p>
+
+<h2><a name="requirements">1. Requirements</a></h2>
+<p>Dokeos is a web application which requires some other software to function:</p>
+<ul>
+<li>A web server - we recommend <strong>Apache</strong></li>
+<li><strong>PHP</strong></li>
+<li>The <strong>MySQL</strong> database server</li>
+</ul>
+<p>
+These software packages have to be installed on the computer where you will install Dokeos. 
+<br/>
+You can install all these software packages separately, which often gives the best results. However, beginning users who want to test Dokeos can use a <i>combination package</i> that installs all these software packages in one simple install. If you want to use a combination package, we recommend Wamp (Download at <a href="http://www.wampserver.com/en/index.php">the WAMP5 website</a>, you also need the <a href="http://www.wampserver.com/en/add-ons.php">PHP4 add-on</a>) or <a href="http://www.apachefriends.org/en/index.html">XAMP</a>.
+</p>
+
+<h3>1.1. A web server</h3>
+<p>
+The Apache web server is recommended, and Dokeos is configured to use some Apache security enhancements if possible. However, other web servers will work too. For best security results, you need to have the Apache module mod_rewrite activated. The mod_rewrite rules for Dokeos are read from a .htaccess file in the courses folder, so Apache needs to allow this (AllowOverride FileInfo in httpd.conf).
+<br/><br/>
+<a href="http://httpd.apache.org/download.cgi">Download Apache web server</a><br/>
+<a href="http://httpd.apache.org/docs-project/">Apache web server manual</a>
+</p>
+
+<h3>1.2. PHP</h3>
+<p>
+You need PHP version 4.3.2 or later (4.x versions), configured with the following modules : mysql, zlib, preg, xml. PHP versions 5 or later are not supported by Dokes yet.
+You need the ldap module too if you want to use ldap with Dokeos.
+Most of the PHP4 compiled distributions are provided with these modules.
+Anyway, their presence is checked by the Dokeos install script.
+<br/><br/>
+<a href="http://www.php.net/downloads.php">Download PHP</a><br/>
+<a href="http://www.php.net/docs.php">PHP manual</a>
+</p>
+
+<p>
+Some users could meet problems if their PHP setting doesn't fit
+these ones:</p>
+<ul>
+<li>short_open_tag       = On</li>
+<li>safe_mode            = Off</li>
+<li>magic_quotes_gpc     = On</li>
+<li>magic_quotes_runtime = Off</li>
+</ul>
+<p>
+Past Dokeos versions required register_globals to be set to On. This is
+no longer necessary, this can be set to Off and Dokeos will work fine.
+</p>
+
+<p><strong>BSD users:</strong> these php libraries have to be included during php installation:</p>
+<ul>
+<li>php-mysql The mysql shared extension for php</li>
+<li>php-pcre The pcre shared extension for php</li>
+<li>php-session The session shared extension for php</li>
+<li>php-zlib The zlib shared extension for php</li>
+<li>php-xml</li>
+<li>(optional) php-ldap if you want to be able to use LDAP authentication</li>
+</ul>
+
+<h3>1.3. The MySQL database server</h3>
+<p>
+You will need a login and password allowing to administrate
+   and create at least one database. By default, Dokeos will create a new
+   database for each course created. It means your host should allow you to
+   create and administrate several databases. You can also install DOkeos using only one database, in that case you have to select this option during the
+   installation.
+<br/><br/>
+<a href="http://dev.mysql.com/downloads/">Download MySQL server</a><br/>
+<a href="http://dev.mysql.com/doc/mysql/en/index.html">MySQL server manual</a>
+</p>
+
+<p>
+<b>Note:</b><br/>
+It seems the backticks characters (`) inserted inside most of
+the Dokeos SQL queries since version 1.3 don't work with MySQL
+versions before 3.23.6.
+</p>
+
+<h3>1.4. Permissions</h3>
+<p>
+Furthermore, you need web Write access to web directory where Dokeos has been moved
+or unzipped to. On a Windows machine locally, this
+is not a problem. Remotely, you need to be allowed to CHMOD
+through FTP, telnet or any means.
+</p>
+
+<hr>
+<h2><a name="install_new_version">2. Installing a new version of Dokeos</a></h2>
+
+<p>
+2.1. Download the Dokeos 1.8 install package (.zip for Windows users or .tar.gz for all others) from the <a href="http://www.dokeos.com/download.php">Dokeos download page</a>.
+</p>
+
+<p>
+2.2. Unzip or untar the downloaded install package. 
+Most current operating systems
+   can do this with a built-in graphical application, if this doesn't work
+   you can open a commandline, go to the download directory and type
+   tar -zxvf dokeos-community-1.8.tar.gz
+</p>
+
+<p>
+2.3. Move by any means (FTP, SCP, local file copy) the contents of the 
+Dokeos install package to your website on your webserver (whether webroot or subdirectory). Your webserver can also be your local computer. Be sure to copy all the folders (archive, home, claroline, courses) as well as all the .php files.
+</p>
+
+<p>
+For Windows users who install Dokeos locally: if you use an Apache/PHP/MySQL combination package, just drag and drop the contents of the Dokeos install package into the web directory of the combination package:</p>
+<ul>
+<li><strong>EasyPHP</strong> - C:\Program Files\easyphp\www\</li>
+<li><strong>WAMP</strong> - C:\Program Files\wamp\www\
+<li><strong>XAMP</strong> - C:\Program Files\xamp\www\</li>
+</ul> 
+
+<p>
+2.4. The following directories need to be readable, writeable and executable for everyone:
+</p>
+<ul>
+<li>dokeos/main/inc/conf/</li>
+<li>dokeos/main/garbage/</li>
+<li>dokeos/main/upload/</li>
+<li>dokeos/archive/</li>
+<li>dokeos/courses/</li>
+<li>dokeos/home/</li>
+</ul>
+<p>
+On Linux, Mac OS X and BSD operating systems you can use the CHMOD 777 command for this.
+In Windows, you may need to check the properties of the folders (by right-clicking on them).
+</p>
+
+<p>
+2.5. The following files need to be readable and writeable for everyone:
+</p>
+<ul>
+<li>dokeos/main/inc/conf/claro_main.conf.php (if present)</li>
+<li>dokeos/home/*.html</li>
+</ul>
+<p>
+On Linux, Mac OS X and BSD operating systems you can use the CHMOD 666 command for this.
+In Windows, you may need to check the properties of the files and folders (by right-clicking on them).
+</p>
+
+<p>
+<b>NOTE:</b><br/>
+Do not modify the home_*.html files directly. Instead,
+choose "Configure the homepage" in the Dokeos administration section.
+</p>
+
+<p>
+2.6. Open a web browser and go to
+   http://www.yourserver.org/yoursite/dokeos/index.php
+
+   If you install Dokeos locally (not on a server) open:
+   http://localhost/dokeos/index.php
+</p>
+<p>
+2.7. Click on the install button and follow instructions.
+
+   Windows: with combination packages like easyphp, out of the box, login and password
+   for MySQL should probably remain empty.
+</p>
+<p>
+<strong>2.8. Configuration and security after installation</strong>
+</p>
+
+<ul>
+<li><strong>Protect your configuration file: </strong>
+make sure no one can overwrite it. You can find the config file in <em>(dokeos folder)</em>/main/inc/conf/claro_main.conf.php. Make it read-only (windows/xwindows: right-click the file to edit the properties. linux/bsd/macosx: use the chmod 444 command). The config file is created by Apache so you may need to be root user to change its permissions.</li>
+<li><strong>Protect your installation folder: </strong>
+if the <em>(dokeos folder)</em>/main/install folder is still accessible, someone could install over your existing version (you could lose your data that way). Move the folder somewhere out of the web directories so it is not accessible, change its name, or edit its properties so no one can read or execute it.</li>
+<li><strong>For better security: </strong>
+making the files world-writable will help you install, and solves many issues for people without much admin experience. However, it's better security to make the owner of the apache process (often called apache or www-data) also owner of all the dokeos files and folders. Ths way, these files need only be readable and writable by the Apache process owner, not by the entire world.</li>
+<li><strong>Configure your Dokeos installation: </strong>
+in the administration section of Dokeos, you can use the Dokeos Config Settings to adjust the behavior of your installation.</li>
+<li><strong>Configure Dokeos mail: </strong>
+most of Dokeos uses the mail settings from the php.ini file. However, the announcements tool uses phpMailer (another free software project) and the settings for this tool can be adjusted in <em>(dokeos folder)</em>/main/inc/conf/mail.conf.php.</li>
+</ul>
+
+<hr>
+<h2><a name="upgrade_previous_version">3. Upgrading from a previous version of Dokeos</a></h2>
+
+<p>
+Before upgrading we heavily recommend you do a full backup of the previous
+Dokeos directories and databases. If you are unsure how to achieve this
+please ask your hosting provider for advice.<br/></p>
+
+<p>
+<em>If you upgrade from Dokeos 1.8</em>, you can simply copy the new files of 2.0.1 over
+the files of the older version. You should not copy over the home, courses or archive folders, otherwise you might lose data. If you accidentally copy over those folders, you can simply replace them with the folders from your backup.<br/>
+
+<em>If you upgrade from a lower version of Dokeos (1.6.x)</em>,
+you'll have to use the built-in upgrade facility, as described below.
+</p>
+
+<p>
+3.1. Download the Dokeos 1.8 install package (.zip for Windows users or .tar.gz for all others) from the <a href="http://www.dokeos.com/download.php">Dokeos download page</a>.
+</p>
+
+<p>
+3.2. Unzip or untar the downloaded install package. 
+Most current operating systems
+   can do this with a built-in graphical application, if this doesn't work
+   you can open a commandline, go to the download directory and type
+   tar -zxvf dokeos-community-1.8.tar.gz
+</p>
+
+<p>
+3.3. Move the Dokeos directory to a different path from the previous version
+</p>
+<p>
+<b>WARNING:</b><br/>
+Do not delete the previous Dokeos installation directory before installing
+the new one. When the update is successfully finished, you can remove
+the old path.
+</p>
+<p>
+<b>TIP:</b><br/>
+If you want Dokeos 1.8 to be installed in the same directory as
+the previous version :
+
+<ul>
+<li>move the old directory to a new location (e.g. move dokeos/ to dokeos_old/)</li>
+<li>uncompress Dokeos 1.8 to the old version directory (e.g. uncompress Dokeos 2.0.1 to dokeos/)</li>
+<li>go to next step</li>
+</ul>
+</p>
+
+<p>
+3.4. The following files need to be readable and writeable for everyone:
+
+<ul>
+<li>dokeos/main/inc/conf/claro_main.conf.php (if present)</li>
+<li>dokeos/home/*.html</li>
+</ul>
+
+On Linux, Mac OS X and BSD operating systems you can use the CHMOD 666 command for this.
+In Windows, you may need to check the properties of the folders.
+</p>
+
+<p>
+<b>NOTE:</b><br/>
+Do not modify the home_*.html files directly. Instead,
+choose "Configure the homepage" in the Dokeos administration section.
+</p>
+
+<p>
+3.5. The following directories need to be readable, writeable and executable for everyone:
+
+<ul>
+<li>dokeos/main/inc/conf/</li>
+<li>dokeos/main/garbage/</li>
+<li>dokeos/main/upload/</li>
+<li>dokeos/archive/</li>
+<li>dokeos/courses/</li>
+<li>dokeos/home/</li>
+</ul>
+
+On Linux, Mac OS X and BSD operating systems you can use the CHMOD 777 command for this.
+In Windows, you may need to check the properties of the folders.
+</p>
+
+<p>
+3.6. Open a web browser and go to
+   http://www.yourserver.org/yoursite/dokeos/index.php
+
+   Windows locally, with e.g easyphp or another combination package, open:
+   http://localhost/dokeos/index.php
+</p>
+
+<p>
+3.7. Click on the install button, then click on "Update from Dokeos 1.6, 1.6.1, 1.6.2, 1.6.3" and follow the instructions.
+</p>
+
+<h2><a name="troubleshooting">4. Troubleshooting</a></h2>
+<p>
+In the future we will also provide instructions on how to do a "manual" install
+of Dokeos, by creating the database tables yourself.
+
+If you have any problems, go to the <a href="http://www.dokeos.com">Dokeos website</a> and ask a question on our
+<a href="http://www.dokeos.com/forum/">support forum</a>. Please read the previous messages first to see if there is
+already an answer to your question. We also maintain a list of
+<a href="http://www.dokeos.com/wiki/index.php/FAQ">Frequently Asked Questions</a>.
+</p>
+
+<h2><a name="admin_section">5. Administration section</a></h2>
+<p>
+To access the Dokeos administration section, open browser,
+go to your Dokeos adress and log in with the admin user.
+Then you will see a "Platform admin section" link in the header of the web page.
+</p>
+
+<h2><a name="ldap">6. LDAP</a></h2>
+<p>
+<i>This part is optional, only organisations with an LDAP server will need to read this.</i><br/>
+An LDAP module is already provided in Dokeos, but it has to be configured to make it work.
+</p>
+
+<p>
+<b>Compiling</b><br/>
+Linux servers: It's possible that you have to recompile php with ldap support.
+Newer distributions also allow downloading rpms for additional packages.
+</p>
+
+<p>
+<b>Activating LDAP in Dokeos</b><br/>
+In (dokeos folder)/main/inc/conf/claro_main.conf.php, around line 90, you see<br/>
+//for new login module<br/>
+//uncomment these to activate ldap<br/>
+//$extAuthSource['ldap']['login'] = "./main/auth/ldap/login.php";<br/>
+//$extAuthSource['ldap']['newUser'] = "./main/auth/ldap/newUser.php";<br/>
+<br/>
+remove the // from the last two lines to activate LDAP.<br/>
+</p>
+
+<p>
+<b>Settings</b><br/>
+Ask the LDAP server admin for the settings:
+<ul>
+<li>ldap server name</li>
+<li>ldap server port (usually 389)</li>
+<li>ldap dc</li>
+</ul>
+You must enter these in
+(dokeos folder)/main/auth/ldap/ldap_var.inc.php
+<br/>
+//parameters for LDAP module<br/>
+$usesLDAP						=	TRUE;<br/>
+$usesCurriculum					=	FALSE;<br/>
+$ldaphost = "myldapserver.com";  // your ldap server<br/>
+$ldapport = 389;                 // your ldap server's port number<br/>
+$ldapDc = "dc=xx, dc=yy, dc=zz"; //domain<br/>
+</p>
+
+<p>
+<b>Teacher/student status</b><br/>
+If you wish, you can give teacher/student status to dokeos users according to settings in the ldap server.
+This is not a standard field however, so you'll have to change some code.
+main/auth/ldap/ldap_var.inc.php
+around line 189, function putUserInfoInClaroline ($login, $infoArray)
+</p>
+
+<p>
+if (<i>your criterium</i>)<br/>
+{<br/>
+   $statut = STUDENT;<br/>
+}<br/>
+else<br/>
+{<br/>
+   $statut = COURSEMANAGER;<br/>
+}<br/>
+</p>
+
+<p>
+If this seems too difficult, the simplest solution is to just put
+$statut = STUDENT; and give course manager rights through the administration section.
+</p>
+
+<p>
+<b>Protected LDAP servers</b><br/>
+Some LDAP servers do not support anonymous use of the directory services
+In this case, you need code that binds with a name and password - this code has already been provided,
+just ask on a forum or email for this.
+</p>
+
+<p>
+<hr>
+Contact address: Dokeos, 44 rue des palais, B-1030 Brussels, Belgium<br/>
+Mail: info@dokeos.com
+<hr>
+</p>
+
+</div>
+</div>
+
+</body></html>

+ 340 - 0
license.txt

@@ -0,0 +1,340 @@
+		    GNU GENERAL PUBLIC LICENSE
+		       Version 2, June 1991
+
+Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+Everyone is permitted to copy and distribute verbatim copies
+of this license document, but changing it is not allowed.
+
+			    Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users.  This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it.  (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.)  You can apply it to
+your programs, too.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+  To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+  For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have.  You must make sure that they, too, receive or can get the
+source code.  And you must show them these terms so they know their
+rights.
+
+  We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+  Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software.  If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+  Finally, any free program is threatened constantly by software
+patents.  We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary.  To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+
+		    GNU GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License.  The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language.  (Hereinafter, translation is included without limitation in
+the term "modification".)  Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+  1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+  2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) You must cause the modified files to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    b) You must cause any work that you distribute or publish, that in
+    whole or in part contains or is derived from the Program or any
+    part thereof, to be licensed as a whole at no charge to all third
+    parties under the terms of this License.
+
+    c) If the modified program normally reads commands interactively
+    when run, you must cause it, when started running for such
+    interactive use in the most ordinary way, to print or display an
+    announcement including an appropriate copyright notice and a
+    notice that there is no warranty (or else, saying that you provide
+    a warranty) and that users may redistribute the program under
+    these conditions, and telling the user how to view a copy of this
+    License.  (Exception: if the Program itself is interactive but
+    does not normally print such an announcement, your work based on
+    the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+    a) Accompany it with the complete corresponding machine-readable
+    source code, which must be distributed under the terms of Sections
+    1 and 2 above on a medium customarily used for software interchange; or,
+
+    b) Accompany it with a written offer, valid for at least three
+    years, to give any third party, for a charge no more than your
+    cost of physically performing source distribution, a complete
+    machine-readable copy of the corresponding source code, to be
+    distributed under the terms of Sections 1 and 2 above on a medium
+    customarily used for software interchange; or,
+
+    c) Accompany it with the information you received as to the offer
+    to distribute corresponding source code.  (This alternative is
+    allowed only for noncommercial distribution and only if you
+    received the program in object code or executable form with such
+    an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it.  For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable.  However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+  4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License.  Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+  5. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Program or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+  6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+  7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+  8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded.  In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+  9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time.  Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number.  If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation.  If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+  10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission.  For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this.  Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+			    NO WARRANTY
+
+  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+		     END OF TERMS AND CONDITIONS
+
+	    How to Apply These Terms to Your New Programs
+
+  If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+  To do so, attach the following notices to the program.  It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the program's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+    Gnomovision version 69, Copyright (C) year name of author
+    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+    This is free software, and you are welcome to redistribute it
+    under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License.  Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary.  Here is a sample; alter the names:
+
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+  `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+  <signature of Ty Coon>, 1 April 1989
+  Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs.  If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library.  If this is what you want to do, use the GNU Library General
+Public License instead of this License.

+ 288 - 0
main/admin/add_courses_to_session.php

@@ -0,0 +1,288 @@
+<?php
+/*
+==============================================================================
+	Dokeos - elearning and course management software
+
+	Copyright (c) 2004 Dokeos S.A.
+	Copyright (c) 2003 University of Ghent (UGent)
+	Copyright (c) 2001 Universite catholique de Louvain (UCL)
+	Copyright (c) Olivier Brouckaert
+
+	For a full list of contributors, see "credits.txt".
+	The full license can be read in "license.txt".
+
+	This program is free software; you can redistribute it and/or
+	modify it under the terms of the GNU General Public License
+	as published by the Free Software Foundation; either version 2
+	of the License, or (at your option) any later version.
+
+	See the GNU General Public License for more details.
+
+	Contact: Dokeos, 181 rue Royale, B-1000 Brussels, Belgium, info@dokeos.com
+==============================================================================
+*/
+/**
+==============================================================================
+*	@package dokeos.admin
+==============================================================================
+*/
+
+$langFile='admin';
+
+$cidReset=true;
+
+require('../inc/global.inc.php');
+
+api_protect_admin_script();
+
+$id_session=intval($_GET['id_session']);
+
+$formSent=0;
+$errorMsg=$firstLetterCourse=$firstLetterSession='';
+$CourseList=$SessionList=array();
+$courses=$sessions=array();
+$tbl_session_rel_course_rel_user=Database::get_main_table(MAIN_SESSION_COURSE_USER_TABLE);
+$tbl_session=Database::get_main_table(MAIN_SESSION_TABLE);
+$tbl_session_rel_user=Database::get_main_table(MAIN_SESSION_USER_TABLE);
+$tbl_session_rel_course=Database::get_main_table(MAIN_SESSION_COURSE_TABLE);
+$tbl_course=Database::get_main_table(MAIN_COURSE_TABLE);
+
+$noPHP_SELF=true;
+
+$tool_name= get_lang('SubscribeCoursesToSession');
+
+$interbreadcrumb[]=array("url" => "index.php","name" => get_lang('AdministrationTools'));
+$interbreadcrumb[]=array("url" => "session_list.php","name" => "Liste des sessions");
+
+if($_POST['formSent'])
+{
+	$formSent=$_POST['formSent'];
+	$firstLetterCourse=$_POST['firstLetterCourse'];
+	$firstLetterSession=$_POST['firstLetterSession'];
+	$CourseList=$_POST['SessionCoursesList'];
+	if(!is_array($CourseList))
+	{
+		$CourseList=array();
+	}
+	$nbr_courses=0;	
+	
+	$id_coach = api_sql_query("SELECT id_coach FROM $tbl_session WHERE id=$id_session");
+	$id_coach = mysql_fetch_array($id_coach);
+	$id_coach = $id_coach[0];
+	
+	$rs = api_sql_query("SELECT course_code FROM $tbl_session_rel_course WHERE id_session=$id_session");
+	$existingCourses = api_store_result($rs);				
+	
+	$sql="SELECT id_user
+		FROM $tbl_session_rel_user
+		WHERE id_session = $id_session";
+	$result=api_sql_query($sql,__FILE__,__LINE__);
+	
+	$UserList=api_store_result($result);
+	
+	
+	foreach($CourseList as $enreg_course)
+	{
+		$exists = false;
+		foreach($existingCourses as $existingCourse){
+			if($enreg_course == $existingCourse['course_code']){
+				$exists=true;
+			}
+		}		
+		if(!$exists){				
+			api_sql_query("INSERT INTO $tbl_session_rel_course(id_session,course_code, id_coach) VALUES('$id_session','$enreg_course','$id_coach')",__FILE__,__LINE__);
+			
+			
+			$nbr_users=0;
+			foreach($UserList as $enreg_user)
+			{
+				$enreg_user = $enreg_user['id_user'];
+				api_sql_query("INSERT IGNORE INTO $tbl_session_rel_course_rel_user(id_session,course_code,id_user) VALUES('$id_session','$enreg_course','$enreg_user')",__FILE__,__LINE__);
+				
+				if(mysql_affected_rows())
+				{
+					$nbr_users++;
+				}
+			}
+			api_sql_query("UPDATE $tbl_session_rel_course SET nbr_users=$nbr_users WHERE id_session='$id_session' AND course_code='$enreg_course'",__FILE__,__LINE__);
+		}
+		
+	}
+	
+	foreach($existingCourses as $existingCourse) {
+		if(!in_array($existingCourse['course_code'], $CourseList)){
+			api_sql_query("DELETE FROM $tbl_session_rel_course WHERE course_code='".$existingCourse['course_code']."' AND id_session=$id_session");
+			api_sql_query("DELETE FROM $tbl_session_rel_course_rel_user WHERE course_code='".$existingCourse['course_code']."' AND id_session=$id_session");
+			
+		}
+	}
+	$nbr_courses=count($CourseList);
+	api_sql_query("UPDATE $tbl_session SET nbr_courses=$nbr_courses WHERE id='$id_session'",__FILE__,__LINE__);
+
+	if(isset($_GET['add']))
+		header('Location: add_users_to_session.php?id_session='.$id_session.'&add=true');
+	else 
+		header('Location: resume_session.php?id_session='.$id_session);
+		//header('Location: '.$_GET['page'].'?id_session='.$id_session);
+	
+		
+	
+	
+}
+
+Display::display_header($tool_name);
+
+api_display_tool_title($tool_name);
+
+
+$sql="SELECT code, title, visual_code, id_session
+		FROM $tbl_course 
+		LEFT JOIN $tbl_session_rel_course
+			ON code = course_code
+		ORDER BY ".(sizeof($courses)?"(code IN(".implode(',',$courses).")) DESC,":"")." title";
+
+$result=api_sql_query($sql,__FILE__,__LINE__);
+
+$Courses=api_store_result($result);
+$nosessionCourses = $sessionCourses = array();
+
+
+foreach($Courses as $course)
+	if($course['id_session'] == $id_session) 
+		$sessionCourses[$course['code']] = $course ;
+				
+foreach($Courses as $course)
+	if(empty($sessionCourses[$course['code']]) && empty($nosessionCourses[$course['code']]))
+		$nosessionCourses[$course['code']] = $course ;
+		
+		
+unset($Courses);
+?>
+
+<form name="formulaire" method="post" action="<?php echo $_SERVER['PHP_SELF']; ?>?page=<?php echo $_GET['page'] ?>&id_session=<?php echo $id_session; ?><?php if(!empty($_GET['add'])) echo '&add=true' ; ?>" style="margin:0px;">
+<input type="hidden" name="formSent" value="1" />
+
+<?php
+if(!empty($errorMsg))
+{
+	Display::display_normal_message($errorMsg); //main API
+}
+?>
+
+<table border="0" cellpadding="5" cellspacing="0" width="100%" align="center">
+<tr>
+  <td width="45%" align="center"><b><?php echo get_lang('CourseListInPlatform') ?> :</b></td>
+  
+  <td width="10%">&nbsp;</td>
+  <td align="center" width="45%"><b><?php echo get_lang('CourseListInSession') ?> :</b></td>
+</tr>
+<tr>
+  <td width="45%" align="center"><select id="origin" name="NoSessionCoursesList[]" multiple="multiple" size="20" style="width:300px;">
+
+<?php
+foreach($nosessionCourses as $enreg)
+{
+?>
+
+	<option value="<?php echo $enreg['code']; ?>" <?php if(in_array($enreg['code'],$CourseList)) echo 'selected="selected"'; ?>><?php echo $enreg['title'].' ('.$enreg['visual_code'].')'; ?></option>
+
+<?php
+}
+
+unset($nosessionCourses);
+?>
+
+  </select></td>
+  <td width="10%" valign="middle" align="center">
+	<input type="button" onclick="moveItem(document.getElementById('origin'), document.getElementById('destination'))" value=">>" />
+	<br /><br />
+	<input type="button" onclick="moveItem(document.getElementById('destination'), document.getElementById('origin'))" value="<<" />
+	<br /><br /><br /><br /><br /><br />
+	<?php
+	if(isset($_GET['add']))
+	{
+		echo '<input type="button" value="'.get_lang('NextStep').'" onclick="valide()" />';
+	}
+	else
+	{
+		echo '<input type="button" value="'.get_lang('Ok').'" onclick="valide()" />';
+	}
+	?>
+  </td>
+  <td width="45%" align="center"><select id='destination' name="SessionCoursesList[]" multiple="multiple" size="20" style="width:300px;">
+
+<?php
+foreach($sessionCourses as $enreg)
+{
+?>
+
+	<option value="<?php echo $enreg['code']; ?>"><?php echo $enreg['title'].' ('.$enreg['visual_code'].')'; ?></option>
+
+<?php
+}
+
+unset($sessionCourses);
+?>
+
+  </select></td>
+</tr>
+</table>
+
+</form>
+<script type="text/javascript">
+<!--
+function moveItem(origin , destination){
+	
+	for(var i = 0 ; i<origin.options.length ; i++) {
+		if(origin.options[i].selected) {	
+			destination.options[destination.length] = new Option(origin.options[i].text,origin.options[i].value);
+			origin.options[i]=null;	
+			i = i-1;
+		}
+	}
+	destination.selectedIndex = -1;
+	sortOptions(destination.options);
+	
+}
+
+function sortOptions(options) { 
+
+	newOptions = new Array();
+	for (i = 0 ; i<options.length ; i++)
+		newOptions[i] = options[i];
+		
+	newOptions = newOptions.sort(mysort);	
+	options.length = 0;
+	for(i = 0 ; i < newOptions.length ; i++)
+		options[i] = newOptions[i];
+	
+}
+
+function mysort(a, b){
+	if(a.text.toLowerCase() > b.text.toLowerCase()){
+		return 1;
+	}
+	if(a.text.toLowerCase() < b.text.toLowerCase()){
+		return -1;
+	}
+	return 0;
+}
+
+function valide(){
+	var options = document.getElementById('destination').options;
+	for (i = 0 ; i<options.length ; i++)
+		options[i].selected = true;
+		
+	document.forms.formulaire.submit();
+}
+-->
+
+</script>
+<?php
+/*
+==============================================================================
+		FOOTER
+==============================================================================
+*/
+Display::display_footer();
+?>

+ 377 - 0
main/admin/add_users_to_session.php

@@ -0,0 +1,377 @@
+<?php
+/*
+==============================================================================
+	Dokeos - elearning and course management software
+
+	Copyright (c) 2004 Dokeos S.A.
+	Copyright (c) 2003 University of Ghent (UGent)
+	Copyright (c) 2001 Universite catholique de Louvain (UCL)
+	Copyright (c) Olivier Brouckaert
+
+	For a full list of contributors, see "credits.txt".
+	The full license can be read in "license.txt".
+
+	This program is free software; you can redistribute it and/or
+	modify it under the terms of the GNU General Public License
+	as published by the Free Software Foundation; either version 2
+	of the License, or (at your option) any later version.
+
+	See the GNU General Public License for more details.
+
+	Contact: Dokeos, 181 rue Royale, B-1000 Brussels, Belgium, info@dokeos.com
+==============================================================================
+*/
+/**
+==============================================================================
+*	@package dokeos.admin
+==============================================================================
+*/
+
+$langFile='admin';
+
+$cidReset=true;
+
+require('../inc/global.inc.php');
+
+api_protect_admin_script();
+
+$id_session=intval($_GET['id_session']);
+
+$formSent=0;
+$errorMsg=$firstLetterUser=$firstLetterSession='';
+$UserList=$SessionList=array();
+$users=$sessions=array();
+
+$tbl_session=Database::get_main_table(MAIN_SESSION_TABLE);
+$tbl_session_rel_class=Database::get_main_table(MAIN_SESSION_CLASS_TABLE);
+$tbl_session_rel_course=Database::get_main_table(MAIN_SESSION_COURSE_TABLE);
+$tbl_session_rel_course_rel_user=Database::get_main_table(MAIN_SESSION_COURSE_USER_TABLE);
+$tbl_course=Database::get_main_table(MAIN_COURSE_TABLE);
+$tbl_user=Database::get_main_table(MAIN_USER_TABLE);
+$tbl_session_rel_user=Database::get_main_table(MAIN_SESSION_USER_TABLE);
+$tbl_class=Database::get_main_table(MAIN_CLASS_TABLE);
+$tbl_class_user=Database::get_main_table(MAIN_CLASS_USER_TABLE);
+
+$noPHP_SELF=true;
+
+$tool_name=get_lang('SubscribeUsersToSession');
+
+$interbreadcrumb[]=array("url" => "index.php","name" => get_lang('AdministrationTools'));
+$interbreadcrumb[]=array("url" => "session_list.php","name" => "Liste des sessions");
+
+if($_POST['formSent'])
+{
+	$formSent=$_POST['formSent'];
+	$firstLetterUser=$_POST['firstLetterUser'];
+	$firstLetterSession=$_POST['firstLetterSession'];
+	$UserList=$_POST['sessionUsersList'];
+	$ClassList=$_POST['sessionClassesList'];
+	if(!is_array($UserList))
+	{
+		$UserList=array();
+	}
+
+	if($formSent == 1)
+	{
+		$result = api_sql_query("SELECT id_user FROM $tbl_session_rel_user WHERE id_session='$id_session'");
+		$existingUsers = array();
+		while($row = mysql_fetch_array($result)){
+			$existingUsers[] = $row['id_user'];
+		}
+		
+		$result=api_sql_query("SELECT course_code FROM $tbl_session_rel_course WHERE id_session='$id_session'",__FILE__,__LINE__);
+
+		$CourseList=array();
+
+		while($row=mysql_fetch_array($result))
+		{
+			$CourseList[]=$row['course_code'];
+		}
+		
+		foreach($CourseList as $enreg_course)
+		{
+			$nbr_users=0;
+			foreach($UserList as $enreg_user)
+			{
+				if(!in_array($enreg_user, $existingUsers)){
+					api_sql_query("INSERT IGNORE INTO $tbl_session_rel_course_rel_user(id_session,course_code,id_user) VALUES('$id_session','$enreg_course','$enreg_user')",__FILE__,__LINE__);
+					
+					if(mysql_affected_rows())
+					{
+						$nbr_users++;
+					}
+				}
+			}
+			
+			foreach($ClassList as $class){
+				$result = api_sql_query ("SELECT user_id FROM $tbl_class_user WHERE class_id=$class");
+				$usersTmp = api_store_result($result);	
+				foreach($usersTmp as $enreg_user){
+					api_sql_query("INSERT IGNORE INTO $tbl_session_rel_course_rel_user(id_session,course_code,id_user) VALUES('$id_session','$enreg_course','{$enreg_user['user_id']}')",__FILE__,__LINE__);
+					if(mysql_affected_rows())
+					{
+					$nbr_users++;
+					}
+				}
+			}
+			$sql = "SELECT COUNT(id_user) as nbUsers FROM $tbl_session_rel_course_rel_user WHERE id_session='$id_session' AND course_code='$enreg_course'";
+			$rs = api_sql_query($sql, __FILE__, __LINE__);
+			list($nbr_users) = mysql_fetch_array($rs);
+			api_sql_query("UPDATE $tbl_session_rel_course SET nbr_users=$nbr_users WHERE id_session='$id_session' AND course_code='$enreg_course'",__FILE__,__LINE__);
+			
+		}
+		
+		api_sql_query("DELETE FROM $tbl_session_rel_class WHERE session_id = $id_session");
+		api_sql_query("DELETE FROM $tbl_session_rel_user WHERE id_session = $id_session");
+		
+		$nbr_users = 0;
+		foreach($UserList as $enreg_user){
+			$nbr_users++;
+			api_sql_query("INSERT IGNORE INTO $tbl_session_rel_user(id_session, id_user) VALUES('$id_session','$enreg_user')",__FILE__,__LINE__);
+			
+		}
+		$nbr_users = count($UserList);
+		api_sql_query("UPDATE $tbl_session SET nbr_classes=0, nbr_users= $nbr_users WHERE id='$id_session' ",__FILE__,__LINE__);
+		
+		//if(empty($_GET['add']))
+			//header('Location: '.$_GET['page'].'?id_session='.$id_session);
+		//else
+		header('Location: resume_session.php?id_session='.$id_session);
+			
+	}
+}
+
+Display::display_header($tool_name);
+
+api_display_tool_title($tool_name);
+
+$nosessionUsersList = $sessionUsersList = $nosessionClassesList = $sessionClassesList = array();
+
+//classes
+$sql="SELECT id, name FROM $tbl_class ORDER BY name";
+$result=api_sql_query($sql,__FILE__,__LINE__);
+
+$Classes=api_store_result($result);
+foreach($Classes as $classe)
+	if($classe['id_session'] == $id_session)
+		$sessionClassesList[$classe['id']] = $classe ;
+				
+foreach($Classes as $classe)
+	if(empty($sessionClassesList[$classe['user_id']]) && empty($nosessionClassesList[$classe['user_id']]))
+		$nosessionClassesList[$classe['id']] = $classe ;
+
+
+//users
+$sql="SELECT user_id, lastname, firstname, username, id_session
+		FROM $tbl_user 
+		LEFT JOIN $tbl_session_rel_user
+			ON $tbl_session_rel_user.id_user = $tbl_user.user_id
+		ORDER BY lastname,firstname,username";
+
+$result=api_sql_query($sql,__FILE__,__LINE__);
+
+$Users=api_store_result($result);
+
+foreach($Users as $user)
+	if($user['id_session'] == $id_session) 
+		$sessionUsersList[$user['user_id']] = $user ;
+				
+foreach($Users as $user)
+	if(empty($sessionUsersList[$user['user_id']]) && empty($nosessionUsersList[$user['user_id']]))
+		$nosessionUsersList[$user['user_id']] = $user ;
+		
+
+	
+
+
+?>
+
+<form name="formulaire" method="post" action="<?php echo $_SERVER['PHP_SELF']; ?>?page=<?php echo $_GET['page'] ?>&id_session=<?php echo $id_session; ?><?php if(!empty($_GET['add'])) echo '&add=true' ; ?>" style="margin:0px;">
+<input type="hidden" name="formSent" value="1" />
+
+<?php
+if(!empty($errorMsg))
+{
+	Display::display_normal_message($errorMsg); //main API
+}
+?>
+
+<table border="0" cellpadding="5" cellspacing="0" width="100%">
+
+
+<!-- Users -->
+<tr>
+  <td align="center"><b><?php echo get_lang('UserListInPlatform') ?> :</b>
+  </td>
+  <td></td>
+  <td align="center"><b><?php echo get_lang('UserListInSession') ?> :</b></td>
+</tr>
+
+<tr>
+  <td align="center">
+  <div id="content_source">
+	  <select id="origin_users" name="nosessionUsersList[]" multiple="multiple" size="15" style="width:300px;">
+	
+		<?php
+		foreach($nosessionUsersList as $enreg)
+		{
+		?>
+		
+			<option value="<?php echo $enreg['user_id']; ?>"><?php echo $enreg['lastname'].' '.$enreg['firstname'].' ('.$enreg['username'].')'; ?></option>
+		
+		<?php
+		}
+		
+		unset($nosessionUsersList);
+		?>
+	
+	  </select>
+  </div>
+  </td>
+  <td width="10%" valign="middle" align="center">
+	<input type="button" onclick="moveItem(document.getElementById('origin_users'), document.getElementById('destination_users'))" value=">>" />
+	<br /><br />
+	<input type="button" onclick="moveItem(document.getElementById('destination_users'), document.getElementById('origin_users'))" value="<<" />
+	<br /><br /><br /><br /><br /><br />
+  </td>
+  <td align="center">
+  <select id="destination_users" name="sessionUsersList[]" multiple="multiple" size="15" style="width:300px;">
+
+<?php
+foreach($sessionUsersList as $enreg)
+{
+?>
+
+	<option value="<?php echo $enreg['user_id']; ?>"><?php echo $enreg['lastname'].' '.$enreg['firstname'].' ('.$enreg['username'].')'; ?></option>
+
+<?php
+}
+
+unset($sessionUsersList);
+?>
+
+  </select></td>
+</tr>
+
+<tr>
+	<td colspan="3" align="center">
+		<br />
+		<?php
+		if(isset($_GET['add']))
+			echo '<input type="button" value="'.get_lang("FinishSessionCreation").'" onclick="valide()" />';
+		else	
+			echo '<input type="button" value="'.get_lang('Ok').'" onclick="valide()" />';
+		?>
+	</td>
+</tr>
+
+
+
+
+</table>
+
+</form>
+<script type="text/javascript">
+<!--
+function moveItem(origin , destination){
+	
+	for(var i = 0 ; i<origin.options.length ; i++) {
+		if(origin.options[i].selected) {
+			destination.options[destination.length] = new Option(origin.options[i].text,origin.options[i].value);
+			origin.options[i]=null;	
+			i = i-1;
+		}
+	}
+	destination.selectedIndex = -1;
+	sortOptions(destination.options);
+	
+}
+
+function sortOptions(options) { 
+
+	newOptions = new Array();
+	for (i = 0 ; i<options.length ; i++)
+		newOptions[i] = options[i];
+		
+	newOptions = newOptions.sort(mysort);	
+	options.length = 0;
+	for(i = 0 ; i < newOptions.length ; i++)
+		options[i] = newOptions[i];
+	
+}
+
+function mysort(a, b){
+	if(a.text.toLowerCase() > b.text.toLowerCase()){
+		return 1;
+	}
+	if(a.text.toLowerCase() < b.text.toLowerCase()){
+		return -1;
+	}
+	return 0;
+}
+
+function valide(){
+	var options = document.getElementById('destination_users').options;
+	for (i = 0 ; i<options.length ; i++)
+		options[i].selected = true;
+	/*
+	var options = document.getElementById('destination_classes').options;
+	for (i = 0 ; i<options.length ; i++)
+		options[i].selected = true;
+		*/
+	document.forms.formulaire.submit();
+}
+
+
+function loadUsersInSelect(select){
+	
+	var xhr_object = null; 
+	
+	if(window.XMLHttpRequest) // Firefox 
+		xhr_object = new XMLHttpRequest(); 
+	else if(window.ActiveXObject) // Internet Explorer 
+		xhr_object = new ActiveXObject("Microsoft.XMLHTTP"); 
+	else  // XMLHttpRequest non supporté par le navigateur 
+	alert("Votre navigateur ne supporte pas les objets XMLHTTPRequest..."); 
+	
+	//xhr_object.open("GET", "loadUsersInSelect.ajax.php?id_session=<?php echo $id_session ?>&letter="+select.options[select.selectedIndex].text, false); 
+	xhr_object.open("POST", "loadUsersInSelect.ajax.php");
+	 		
+	xhr_object.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
+	
+	
+	nosessionUsers = makepost(document.getElementById('origin_users'));
+	sessionUsers = makepost(document.getElementById('destination_users'));
+	nosessionClasses = makepost(document.getElementById('origin_classes'));
+	sessionClasses = makepost(document.getElementById('destination_classes'));
+	xhr_object.send("nosessionusers="+nosessionUsers+"&sessionusers="+sessionUsers+"&nosessionclasses="+nosessionClasses+"&sessionclasses="+sessionClasses);
+	
+	xhr_object.onreadystatechange = function() { 
+		if(xhr_object.readyState == 4) {
+			document.getElementById('content_source').innerHTML = result = xhr_object.responseText;		
+			//alert(xhr_object.responseText);
+		}
+	} 
+}
+
+function makepost(select){
+
+	var options = select.options;
+	var ret = "";
+	for (i = 0 ; i<options.length ; i++)
+		ret = ret + options[i].value +'::'+options[i].text+";;";
+	
+	return ret;
+
+}
+-->
+
+</script>
+<?php
+/*
+==============================================================================
+		FOOTER
+==============================================================================
+*/
+Display::display_footer();
+?>

+ 59 - 0
main/admin/class_add.php

@@ -0,0 +1,59 @@
+<?php
+// $Id: class_add.php 9246 2006-09-25 13:24:53Z bmol $
+/*
+==============================================================================
+	Dokeos - elearning and course management software
+
+	Copyright (c) 2004 Dokeos S.A.
+	Copyright (c) 2003 Ghent University (UGent)
+	Copyright (c) 2001 Universite catholique de Louvain (UCL)
+	Copyright (c) Olivier Brouckaert
+	Copyright (c) Bart Mollet, Hogeschool Gent
+
+	For a full list of contributors, see "credits.txt".
+	The full license can be read in "license.txt".
+
+	This program is free software; you can redistribute it and/or
+	modify it under the terms of the GNU General Public License
+	as published by the Free Software Foundation; either version 2
+	of the License, or (at your option) any later version.
+
+	See the GNU General Public License for more details.
+
+	Contact: Dokeos, 181 rue Royale, B-1000 Brussels, Belgium, info@dokeos.com
+==============================================================================
+*/
+/**
+==============================================================================
+*	@package dokeos.admin
+==============================================================================
+*/
+
+$langFile = 'admin';
+$cidReset = true;
+include ('../inc/global.inc.php');
+$this_section=SECTION_PLATFORM_ADMIN;
+require_once (api_get_path(LIBRARY_PATH).'classmanager.lib.php');
+require_once (api_get_path(LIBRARY_PATH).'formvalidator/FormValidator.class.php');
+api_protect_admin_script();
+$form = new FormValidator('add_class');
+$form->add_textfield('name',get_lang('ClassName'));
+$form->addElement('submit','submit',get_lang('Ok'));
+if($form->validate())
+{
+	$values = $form->exportValues();
+	ClassManager :: create_class($values['name']);
+	header('Location: class_list.php');
+}
+$tool_name = get_lang("AddClasses");
+//$interbreadcrumb[] = array ("url" => "index.php", "name" => get_lang('PlatformAdmin'));
+Display :: display_header($tool_name);
+//api_display_tool_title($tool_name);
+$form->display();
+/*
+==============================================================================
+		FOOTER 
+==============================================================================
+*/
+Display :: display_footer();
+?>

+ 64 - 0
main/admin/class_edit.php

@@ -0,0 +1,64 @@
+<?php
+// $Id: class_edit.php 9246 2006-09-25 13:24:53Z bmol $
+
+/*
+==============================================================================
+	Dokeos - elearning and course management software
+
+	Copyright (c) 2004 Dokeos S.A.
+	Copyright (c) 2003 Ghent University (UGent)
+	Copyright (c) 2001 Universite catholique de Louvain (UCL)
+	Copyright (c) Olivier Brouckaert
+
+	For a full list of contributors, see "credits.txt".
+	The full license can be read in "license.txt".
+
+	This program is free software; you can redistribute it and/or
+	modify it under the terms of the GNU General Public License
+	as published by the Free Software Foundation; either version 2
+	of the License, or (at your option) any later version.
+
+	See the GNU General Public License for more details.
+
+	Contact: Dokeos, 181 rue Royale, B-1000 Brussels, Belgium, info@dokeos.com
+==============================================================================
+*/
+/**
+==============================================================================
+*	@package dokeos.admin
+==============================================================================
+*/
+$langFile = 'admin';
+$cidReset = true;
+include ('../inc/global.inc.php');
+$this_section=SECTION_PLATFORM_ADMIN;
+require_once(api_get_path(LIBRARY_PATH).'classmanager.lib.php');
+require_once (api_get_path(LIBRARY_PATH).'formvalidator/FormValidator.class.php');
+api_protect_admin_script();
+$tool_name = get_lang('ModifyClassInfo');
+//$interbreadcrumb[] = array ("url" => "index.php", "name" => get_lang('PlatformAdmin'));
+$interbreadcrumb[] = array ("url" => "class_list.php", "name" => get_lang('AdminClasses'));
+$class_id = intval($_GET['idclass']);
+$class = ClassManager :: get_class_info($class_id);
+$form = new FormValidator('edit_class','post','class_edit.php?idclass='.$class_id);
+$form->add_textfield('name',get_lang('ClassName'));
+$form->addElement('submit','submit',get_lang('Ok'));
+$form->setDefaults(array('name'=>$class['name']));
+if($form->validate())
+{
+	$values = $form->exportValues();
+	ClassManager :: set_name($values['name'], $class_id);
+	header('Location: class_list.php');
+}
+$tool_name = get_lang("AddClasses");
+//$interbreadcrumb[] = array ("url" => "index.php", "name" => get_lang('PlatformAdmin'));
+Display :: display_header($tool_name);
+//api_display_tool_title($tool_name);
+$form->display();
+/*
+==============================================================================
+		FOOTER 
+==============================================================================
+*/
+Display :: display_footer();
+?>

+ 140 - 0
main/admin/class_import.php

@@ -0,0 +1,140 @@
+<?php
+// $Id: class_import.php 9246 2006-09-25 13:24:53Z bmol $
+/*
+==============================================================================
+	Dokeos - elearning and course management software
+
+	Copyright (c) 2004 Dokeos S.A.
+	Copyright (c) 2003 Ghent University (UGent)
+	Copyright (c) 2001 Universite catholique de Louvain (UCL)
+	Copyright (c) Olivier Brouckaert
+	Copyright (c) Bart Mollet, Hogeschool Gent
+
+	For a full list of contributors, see "credits.txt".
+	The full license can be read in "license.txt".
+
+	This program is free software; you can redistribute it and/or
+	modify it under the terms of the GNU General Public License
+	as published by the Free Software Foundation; either version 2
+	of the License, or (at your option) any later version.
+
+	See the GNU General Public License for more details.
+
+	Contact: Dokeos, 181 rue Royale, B-1000 Brussels, Belgium, info@dokeos.com
+==============================================================================
+*/
+/**
+==============================================================================
+*   This     tool allows platform admins to add classes by uploading a CSV file
+* @todo Add some langvars to DLTT
+	@package dokeos.admin
+==============================================================================
+*/
+/**
+ * Validate the imported data
+ */
+function validate_data($classes)
+{
+	$errors = array();
+	foreach($classes as $index => $class)
+	{
+		//1. Check if ClassName is available
+		if(!isset($class['ClassName']) || strlen(trim($class['ClassName'])) == 0)
+		{
+			$class['line'] = $index+2;
+			$class['error'] = get_lang('MissingClassName');
+			$errors[] = $class;
+		}	
+		//2. Check if class doesn't exist yet
+		else
+		{
+			if(ClassManager::class_name_exists($class['ClassName']))
+			{
+				$class['line'] = $index+2;
+				$class['error'] = get_lang('ClassNameExists');
+				$errors[] = $class;					
+			}	
+		}
+	}
+	return $errors;
+}
+/**
+ * Save imported class data to database
+ */
+function save_data($classes)
+{
+	$number_of_added_classes = 0;
+	foreach($classes as $index => $class)
+	{
+		if(ClassManager::create_class($class['ClassName']))
+		{
+			$number_of_added_classes++;	
+		}	
+	}
+	return $number_of_added_classes;
+}
+
+
+
+$langFile = array ('admin', 'registration');
+
+$cidReset = true;
+
+include ('../inc/global.inc.php');
+api_protect_admin_script();
+require_once (api_get_path(LIBRARY_PATH).'fileManage.lib.php');
+require_once (api_get_path(LIBRARY_PATH).'classmanager.lib.php');
+require_once (api_get_path(LIBRARY_PATH).'import.lib.php');
+require_once (api_get_path(LIBRARY_PATH).'formvalidator/FormValidator.class.php');
+
+$tool_name = get_lang('ImportClassListCSV');
+
+//$interbreadcrumb[] = array ("url" => "index.php", "name" => get_lang('PlatformAdmin'));
+Display :: display_header($tool_name);
+//api_display_tool_title($tool_name);
+$form = new FormValidator('import_classes');
+$form->addElement('file','import_file',get_lang('ImportCSVFileLocation'));
+$form->addElement('submit','submit',get_lang('Ok'));
+if( $form->validate())
+{
+	$classes = Import::csv_to_array($_FILES['import_file']['tmp_name']);
+	$errors = validate_data($classes);
+	if (count($errors) == 0)
+	{
+		$number_of_added_classes = save_data($classes);
+		Display::display_normal_message($number_of_added_classes.' '.get_lang('ClassesCreated'));
+	}		
+	else
+	{
+		$error_message = get_lang('ErrorsWhenImportingFile');
+		$error_message .= '<ul>';
+		foreach ($errors as $index => $error_class)
+		{
+			$error_message .= '<li>'.$error_class['error'].' ('.get_lang('Line').' '.$error_class['line'].')';
+			$error_message .= '</li>';
+		}
+		$error_message .= '</ul>';
+		$error_message .= get_lang('NoClassesHaveBeenCreated');
+		Display :: display_error_message($error_message);
+	}
+}
+$form->display();
+?>
+<p><?php echo get_lang('CSVMustLookLike').' ('.get_lang('MandatoryFields').')'; ?> :</p>
+<blockquote>
+ <pre>
+  <b>ClassName</b>
+  <b>1A</b>
+  <b>1B</b>
+  <b>2A group 1</b>
+  <b>2A group 2</b>
+ </pre>
+</blockquote>
+<?php
+/*
+==============================================================================
+		FOOTER 
+==============================================================================
+*/
+Display :: display_footer();
+?>

+ 126 - 0
main/admin/class_information.php

@@ -0,0 +1,126 @@
+<?php // $Id: class_information.php 9246 2006-09-25 13:24:53Z bmol $
+/*
+==============================================================================
+	Dokeos - elearning and course management software
+
+	Copyright (c) 2004 Dokeos S.A.
+	Copyright (c) 2003 Ghent University (UGent)
+	Copyright (c) 2001 Universite catholique de Louvain (UCL)
+	Copyright (c) Olivier Brouckaert
+
+	For a full list of contributors, see "credits.txt".
+	The full license can be read in "license.txt".
+
+	This program is free software; you can redistribute it and/or
+	modify it under the terms of the GNU General Public License
+	as published by the Free Software Foundation; either version 2
+	of the License, or (at your option) any later version.
+
+	See the GNU General Public License for more details.
+
+	Contact: Dokeos, 181 rue Royale, B-1000 Brussels, Belgium, info@dokeos.com
+==============================================================================
+*/
+/**
+============================================================================== 
+*	@author	 Bart Mollet
+*	@package dokeos.admin
+============================================================================== 
+*/
+
+/*
+==============================================================================
+		INIT SECTION
+==============================================================================
+*/ 
+
+$langFile='admin';
+
+$cidReset=true;
+
+require('../inc/global.inc.php');
+$this_section=SECTION_PLATFORM_ADMIN;
+
+api_protect_admin_script();
+require(api_get_path(LIBRARY_PATH).'classmanager.lib.php');
+if( !isset($_GET['id']))
+{
+	api_not_allowed();	
+}
+//$interbreadcrumb[] = array ("url" => "index.php", "name" => get_lang('PlatformAdmin'));
+$interbreadcrumb[] = array ("url" => 'class_list.php', "name" => get_lang('AdminClasses'));
+$class_id = $_GET['id'];
+$class = ClassManager::get_class_info($class_id);
+
+$tool_name = $class['name'];
+Display::display_header($tool_name);
+//api_display_tool_title($tool_name);
+/**
+ * Show all users subscribed in this class
+ */
+echo '<h4>'.get_lang('Users').'</h4>';
+echo '<blockquote>';
+
+$users = ClassManager::get_users($class_id);
+if( count($users) > 0)
+{
+$table_header[] = array (get_lang('OfficialCode'), true);
+$table_header[] = array (get_lang('FirstName'), true);
+$table_header[] = array (get_lang('LastName'), true);
+$table_header[] = array (get_lang('Email'), true);
+$table_header[] = array (get_lang('Status'), true);
+$table_header[] = array ('', false);
+$data = array();
+foreach($users as $index => $user)
+{
+	$row = array ();
+	$row[] = $user['official_code'];
+	$row[] = $user['firstname'];
+	$row[] = $user['lastname'];
+	$row[] = Display :: encrypted_mailto_link($user['email'], $user['email']);
+	$row[] = $user['status'] == 5 ? get_lang('Student') : get_lang('Teacher');
+	$row[] = '<a href="user_information.php?user_id='.$user['user_id'].'"><img src="../img/info_small.gif" border="0" /></a>';
+	$data[] = $row;
+}
+Display::display_sortable_table($table_header,$data,array(),array(),array('id'=>$_GET['id']));
+}
+else
+{
+	echo get_lang('NoUsersInClass');	
+}
+echo '</blockquote>';
+/**
+ * Show all courses in which this class is subscribed
+ */
+$courses = ClassManager::get_courses($class_id);
+if (count($courses) > 0)
+{
+	$header[] = array (get_lang('Code'), true);
+	$header[] = array (get_lang('Title'), true);
+	$header[] = array ('', false);
+	$data = array ();
+	foreach( $courses as $index=>$course)
+	{
+		$row = array ();
+		$row[] = $course['code'];
+		$row[] = $course['title'];
+		$row[] = '<a href="course_information.php?code='.$course['code'].'"><img src="../img/info_small.gif" border="0" /></a>'.'<a href="'.api_get_path(WEB_COURSE_PATH).$course['directory'].'"><img src="../img/home_small.gif" border="0"/></a>' .
+				'<a href="course_edit.php?course_code='.$course['code'].'"><img src="../img/edit.gif" border="0" title="'.get_lang('Edit').'" alt="'.get_lang('Edit').'"/></a>';
+		$data[] = $row;
+	}
+	echo '<p><b>'.get_lang('Courses').'</b></p>';
+	echo '<blockquote>';
+	Display :: display_sortable_table($header, $data, array (), array (), array('id'=>$_GET['id']));
+	echo '</blockquote>';
+}
+else
+{
+	echo '<p>'.get_lang('NoCoursesForThisClass').'</p>';
+}
+/*
+==============================================================================
+		FOOTER 
+==============================================================================
+*/ 
+Display::display_footer();
+?> 

+ 150 - 0
main/admin/class_list.php

@@ -0,0 +1,150 @@
+<?php
+// $Id: class_list.php 9406 2006-10-10 11:28:36Z bmol $
+/*
+==============================================================================
+	Dokeos - elearning and course management software
+
+	Copyright (c) 2004 Dokeos S.A.
+	Copyright (c) 2003 Ghent University (UGent)
+	Copyright (c) 2001 Universite catholique de Louvain (UCL)
+	Copyright (c) Olivier Brouckaert
+
+	For a full list of contributors, see "credits.txt".
+	The full license can be read in "license.txt".
+
+	This program is free software; you can redistribute it and/or
+	modify it under the terms of the GNU General Public License
+	as published by the Free Software Foundation; either version 2
+	of the License, or (at your option) any later version.
+
+	See the GNU General Public License for more details.
+
+	Contact: Dokeos, 181 rue Royale, B-1000 Brussels, Belgium, info@dokeos.com
+==============================================================================
+*/
+/**
+==============================================================================
+*	@package dokeos.admin
+==============================================================================
+*/
+$langFile = 'admin';
+$cidReset = true;
+require ('../inc/global.inc.php');
+$this_section = SECTION_PLATFORM_ADMIN;
+
+/**
+ * Gets the total number of classes
+ */
+function get_number_of_classes()
+{
+	$tbl_class = Database :: get_main_table(MAIN_CLASS_TABLE);
+	$sql = "SELECT COUNT(*) AS number_of_classes FROM $tbl_class";
+	if (isset ($_GET['keyword']))
+	{
+		$sql .= " WHERE (name LIKE '%".mysql_real_escape_string(trim($_GET['keyword']))."%')";
+	}
+	$res = api_sql_query($sql, __FILE__, __LINE__);
+	$obj = mysql_fetch_object($res);
+	return $obj->number_of_classes;
+}
+/**
+ * Gets the information about some classes
+ * @param int $from
+ * @param int $number_of_items
+ * @param string $direction
+ */
+function get_class_data($from, $number_of_items, $column, $direction)
+{
+	$tbl_class_user = Database :: get_main_table(MAIN_CLASS_USER_TABLE);
+	$tbl_class = Database :: get_main_table(MAIN_CLASS_TABLE);
+	$sql = "SELECT 	id AS col0,
+							name AS col1,
+							COUNT(user_id) AS col2,
+							id AS col3
+						FROM $tbl_class
+					LEFT JOIN $tbl_class_user ON id=class_id ";
+	if (isset ($_GET['keyword']))
+	{
+		$sql .= " WHERE (name LIKE '%".mysql_real_escape_string(trim($_GET['keyword']))."%')";
+	}
+	$sql .= "GROUP BY id,name ORDER BY col$column $direction LIMIT $from,$number_of_items";
+	$res = api_sql_query($sql, __FILE__, __LINE__);
+	$classes = array ();
+	while ($class = mysql_fetch_row($res))
+	{
+		$classes[] = $class;
+	}
+	return $classes;
+}
+/**
+ * Filter for sortable table to display edit icons for class
+ */
+function modify_filter($class_id)
+{
+	$result = '<a href="class_information.php?id='.$class_id.'"><img src="../img/info_small.gif" border="0" title="'.get_lang('Info').'" alt="'.get_lang('Info').'"/></a>';
+	$result .= '<a href="class_edit.php?idclass='.$class_id.'"><img src="../img/edit.gif" border="0" title="'.get_lang('Edit').'" alt="'.get_lang('Edit').'"/></a>';
+	$result .= '<a href="class_list.php?action=delete_class&amp;class_id='.$class_id.'" onclick="javascript:if(!confirm('."'".addslashes(htmlentities(get_lang("ConfirmYourChoice")))."'".')) return false;"><img src="../img/delete.gif" border="0" title="'.get_lang('Delete').'" alt="'.get_lang('Delete').'"/></a>';
+	$result .= '<a href="subscribe_user2class.php?idclass='.$class_id.'"><img src="../img/group_small.gif" border="0" alt="'.get_lang('AddUsersToAClass').'" title="'.get_lang('AddUsersToAClass').'"/></a>';
+	return $result;
+}
+
+api_protect_admin_script();
+require (api_get_path(LIBRARY_PATH).'fileManage.lib.php');
+require (api_get_path(LIBRARY_PATH).'classmanager.lib.php');
+require_once (api_get_path(LIBRARY_PATH).'formvalidator/FormValidator.class.php');
+$tool_name = get_lang('ClassList');
+//$interbreadcrumb[] = array ("url" => "index.php", "name" => get_lang('PlatformAdmin'));
+
+Display :: display_header($tool_name);
+//api_display_tool_title($tool_name);
+if (isset ($_POST['action']))
+{
+	switch ($_POST['action'])
+	{
+		// Delete selected classes
+		case 'delete_classes' :
+			$classes = $_POST['class'];
+			if (count($classes) > 0)
+			{
+				foreach ($classes as $index => $class_id)
+				{
+					ClassManager :: delete_class($class_id);
+				}
+				Display :: display_normal_message(get_lang('ClassesDeleted'));
+			}
+			break;
+	}
+}
+if (isset ($_GET['action']))
+{
+	switch ($_GET['action'])
+	{
+		case 'delete_class' :
+			ClassManager :: delete_class($_GET['class_id']);
+			Display :: display_normal_message(get_lang('ClassDeleted'));
+	}
+}
+// Create a search-box
+$form = new FormValidator('search_simple','get','','',null,false);
+$renderer =& $form->defaultRenderer();
+$renderer->setElementTemplate('<span>{element}</span> ');
+$form->addElement('text','keyword',get_lang('keyword'));
+$form->addElement('submit','submit',get_lang('Search'));
+$form->display();
+// Create the sortable table with class information
+$table = new SortableTable('classes', 'get_number_of_classes', 'get_class_data', 1);
+$table->set_additional_parameters(array('keyword'=>$_GET['keyword']));
+$table->set_header(0, '', false);
+$table->set_header(1, get_lang('ClassName'));
+$table->set_header(2, get_lang('NumberOfUsers'));
+$table->set_header(3, '', false);
+$table->set_column_filter(3, 'modify_filter');
+$table->set_form_actions(array ('delete_classes' => get_lang('DeleteSelectedClasses')),'class');
+$table->display();
+/*
+==============================================================================
+		FOOTER
+==============================================================================
+*/
+Display :: display_footer();
+?>

+ 213 - 0
main/admin/class_user_import.php

@@ -0,0 +1,213 @@
+<?php
+
+// $Id: class_user_import.php 9018 2006-06-28 15:11:16Z evie_em $
+/*
+==============================================================================
+	Dokeos - elearning and course management software
+
+	Copyright (c) 2005 Bart Mollet <bart.mollet@hogent.be>
+
+	For a full list of contributors, see "credits.txt".
+	The full license can be read in "license.txt".
+
+	This program is free software; you can redistribute it and/or
+	modify it under the terms of the GNU General Public License
+	as published by the Free Software Foundation; either version 2
+	of the License, or (at your option) any later version.
+
+	See the GNU General Public License for more details.
+
+	Contact: Dokeos, 181 rue Royale, B-1000 Brussels, Belgium, info@dokeos.com
+==============================================================================
+*/
+/**
+==============================================================================
+* This tool allows platform admins to update class-user relations by uploading a
+* CSVfile
+* @package dokeos.admin
+==============================================================================
+*/
+/**
+ * validate the imported data
+ */
+function validate_data($user_classes)
+{
+	$errors = array ();
+	$classcodes = array ();
+	foreach ($user_classes as $index => $user_class)
+	{
+		$user_class['line'] = $index +1;
+		//1. check if mandatory fields are set
+		$mandatory_fields = array ('UserName', 'ClassName');
+		foreach ($mandatory_fields as $key => $field)
+		{
+			if (!isset ($user_class[$field]) || strlen($user_class[$field]) == 0)
+			{
+				$user_class['error'] = get_lang($field.'Mandatory');
+				$errors[] = $user_class;
+			}
+		}
+		//2. check if classcode exists
+		if (isset ($user_class['ClassName']) && strlen($user_class['ClassName']) != 0)
+		{
+			//2.1 check if code allready used in this CVS-file
+			if (!isset ($classcodes[$user_class['ClassName']]))
+			{
+				//2.1.1 check if code exists in DB
+				$class_table = Database :: get_main_table(MAIN_CLASS_TABLE);
+				$sql = "SELECT * FROM $class_table WHERE name = '".mysql_real_escape_string($user_class['ClassName'])."'";
+				$res = api_sql_query($sql, __FILE__, __LINE__);
+				if (mysql_num_rows($res) == 0)
+				{
+					$user_class['error'] = get_lang('CodeDoesNotExists');
+					$errors[] = $user_class;
+				}
+				else
+				{
+					$classcodes[$user_class['CourseCode']] = 1;
+				}
+			}
+		}
+		//3. check if username exists
+		if (isset ($user_class['UserName']) && strlen($user_class['UserName']) != 0)
+		{
+			if (UserManager :: is_username_available($user_class['UserName']))
+			{
+				$user_class['error'] = get_lang('UnknownUser');
+				$errors[] = $user_class;
+			}
+		}
+	}
+	return $errors;
+}
+
+/**
+ * Save the imported data
+ */
+function save_data($users_classes)
+{
+	$user_table = Database :: get_main_table(MAIN_USER_TABLE);
+	$class_user_table = Database :: get_main_table(MAIN_CLASS_USER_TABLE);
+	$class_table = Database :: get_main_table(MAIN_CLASS_TABLE);
+	$csv_data = array ();
+	foreach ($users_classes as $index => $user_class)
+	{
+		$sql = "SELECT * FROM $class_table WHERE name = '".mysql_real_escape_string($user_class['ClassName'])."'";
+		$res = api_sql_query($sql, __FILE__, __LINE__);
+		$obj = mysql_fetch_object($res);
+		$csv_data[$user_class['UserName']][$obj->id] = 1;
+	}
+	foreach ($csv_data as $username => $csv_subscriptions)
+	{
+		$user_id = 0;
+		$sql = "SELECT * FROM $user_table u WHERE u.username = '".mysql_real_escape_string($username)."'";
+		$res = api_sql_query($sql, __FILE__, __LINE__);
+		$obj = mysql_fetch_object($res);
+		$user_id = $obj->user_id;
+		$sql = "SELECT * FROM $class_user_table cu WHERE cu.user_id = $user_id";
+		$res = api_sql_query($sql, __FILE__, __LINE__);
+		$db_subscriptions = array ();
+		while ($obj = mysql_fetch_object($res))
+		{
+			$db_subscriptions[$obj->class_id] = 1;
+		}
+		$to_subscribe = array_diff(array_keys($csv_subscriptions), array_keys($db_subscriptions));
+		$to_unsubscribe = array_diff(array_keys($db_subscriptions), array_keys($csv_subscriptions));
+		if ($_POST['subscribe'])
+		{
+			foreach ($to_subscribe as $index => $class_id)
+			{
+				ClassManager :: add_user($user_id, $class_id);
+				//echo get_lang('Subscription').' : '.$course_code.'<br />';
+			}
+		}
+		if ($_POST['unsubscribe'])
+		{
+			foreach ($to_unsubscribe as $index => $class_id)
+			{
+				ClassManager :: unsubscribe_user($user_id, $class_id);
+				//echo get_lang('Unsubscription').' : '.$course_code.'<br />';
+			}
+		}
+	}
+}
+/**
+ * Read the CSV-file
+ * @param string $file Path to the CSV-file
+ * @return array All course-information read from the file
+ */
+function parse_csv_data($file)
+{
+	$courses = Import :: csv_to_array($file);
+	return $courses;
+}
+
+$langFile = array ('admin', 'registration');
+
+$cidReset = true;
+
+include ('../inc/global.inc.php');
+
+
+require_once (api_get_path(LIBRARY_PATH).'fileManage.lib.php');
+require_once (api_get_path(LIBRARY_PATH).'import.lib.php');
+require_once (api_get_path(LIBRARY_PATH).'usermanager.lib.php');
+require_once (api_get_path(LIBRARY_PATH).'classmanager.lib.php');
+require_once (api_get_path(LIBRARY_PATH).'formvalidator/FormValidator.class.php');
+$formSent = 0;
+$errorMsg = '';
+
+$tool_name = get_lang('AddUsersToAClass').' CSV';
+
+$interbredcrump[] = array ('url' => 'index.php', 'name' => get_lang('PlatformAdmin'));
+
+set_time_limit(0);
+$form = new FormValidator('class_user_import');
+$form->addElement('file', 'import_file', get_lang('ImportFileLocation'));
+$form->addElement('checkbox', 'subscribe', get_lang('Action'), get_lang('SubscribeUserIfNotAllreaySubscribed'));
+$form->addElement('checkbox', 'unsubscribe', '', get_lang('UnsubscribeUserIfSubscriptionIsNotInFile'));
+$form->addElement('submit', 'submit', get_lang('Ok'));
+if ($form->validate())
+{
+	$users_classes = parse_csv_data($_FILES['import_file']['tmp_name']);
+	$errors = validate_data($users_classes);
+	if (count($errors) == 0)
+	{
+		save_data($users_classes);
+		header('Location: class_list.php?action=show_message&message='.urlencode(get_lang('FileImported')));
+		exit ();
+	}
+}
+Display :: display_header($tool_name);
+api_display_tool_title($tool_name);
+if (count($errors) != 0)
+{
+	$error_message = '<ul>';
+	foreach ($errors as $index => $error_class_user)
+	{
+		$error_message .= '<li>'.get_lang('Line').' '.$error_class_user['line'].': <b>'.$error_class_user['error'].'</b>: ';
+		$error_message .= '</li>';
+	}
+	$error_message .= '</ul>';
+	Display :: display_error_message($error_message);
+}
+
+$form->display();
+?>
+<p><?php echo get_lang('CSVMustLookLike').' ('.get_lang('MandatoryFields').')'; ?> :</p>
+<blockquote>
+<pre>
+<b>UserName</b>;<b>ClassName</b>
+jdoe;class01
+a.dam;class01
+</pre>
+</blockquote>
+<?php
+
+/*
+==============================================================================
+		FOOTER
+==============================================================================
+*/
+Display :: display_footer();
+?>

+ 323 - 0
main/admin/configure_extensions.php

@@ -0,0 +1,323 @@
+<?php // $Id: configure_homepage.php 9246 2006-09-25 13:24:53 +0000 (lun., 25 sept. 2006) bmol $
+/*
+==============================================================================
+	Dokeos - elearning and course management software
+
+	Copyright (c) 2004 Dokeos S.A.
+	Copyright (c) 2003 Ghent University (UGent)
+	Copyright (c) 2001 Universite catholique de Louvain (UCL)
+	Copyright (c) Olivier Brouckaert
+
+	For a full list of contributors, see "credits.txt".
+	The full license can be read in "license.txt".
+
+	This program is free software; you can redistribute it and/or
+	modify it under the terms of the GNU General Public License
+	as published by the Free Software Foundation; either version 2
+	of the License, or (at your option) any later version.
+
+	See the GNU General Public License for more details.
+
+	Contact: Dokeos, 181 rue Royale, B-1000 Brussels, Belgium, info@dokeos.com
+==============================================================================
+*/
+
+$langFile='admin';
+
+$cidReset=true;
+
+include('../inc/global.inc.php');
+$this_section=SECTION_PLATFORM_ADMIN;
+
+api_protect_admin_script();
+
+$tbl_settings_services = Database::get_main_table(MAIN_SETTINGS_SERVICE_TABLE);
+$message = '';
+
+if(isset($_POST['activeExtension'])){
+	
+	switch ($_POST['extension_code']){
+		
+		case 'visio' :
+			$sql = 'UPDATE '.$tbl_settings_services.' SET
+					value="true"
+					WHERE variable="active"
+					AND code_service="visio"';
+			$rs = api_sql_query($sql, __FILE__, __LINE__);			
+			if(mysql_affected_rows()>0){
+				$message = get_lang('ServiceActivated');
+			}
+			
+			// select all the courses and insert the tool inside
+			$sql = 'SELECT db_name FROM '.Database::get_main_table(MAIN_COURSE_TABLE);
+			echo $sql;
+			$rs = api_sql_query($sql);
+			while($row = mysql_fetch_array($rs)){
+				
+				$sql = 'INSERT INTO '.$row['db_name'].'.'.TOOL_LIST_TABLE.' SET 
+						name="visio",
+						link="conf/",
+						image="",
+						visibility="1",
+						admin="0",
+						address="squaregrey.gif",
+						target="_self",
+						category="authoring"';
+				
+				api_sql_query($sql);
+
+			}
+			
+			break;	
+			
+		case 'ppt2lp' :
+			$sql = 'UPDATE '.$tbl_settings_services.' SET
+					value="true"
+					WHERE variable="active"
+					AND code_service="ppt2lp"';
+			$rs = api_sql_query($sql, __FILE__, __LINE__);
+			if(mysql_affected_rows()>0){
+				$message = get_lang('ServiceActivated');
+			}
+			break;		
+	}
+	
+}
+
+
+$listActiveServices = array();
+
+// get the list of active services
+$sql = 'SELECT code_service FROM '.$tbl_settings_services.' WHERE variable="active" and value="true"';
+$rs = api_sql_query($sql, __FILE__, __LINE__);
+while($row = mysql_fetch_array($rs)){
+	$listActiveServices[] = $row['code_service'];
+}
+
+
+$javascript_service_displayed = '';
+if(isset($_GET['display'])){
+	$javascript_service_displayed = 'document.getElementById("extension_content_'.$_GET['display'].'").style.display = "block"';
+}
+
+// javascript to handle accordion behaviour
+$javascript_message = '';
+if(!empty($message)){
+	$javascript_message = 
+	'
+	document.getElementById("message").style.display = "block";
+	var timer = setTimeout(hideMessage,5000);
+	';
+}
+$htmlHeadXtra[]= '
+<script type="text/javascript">
+var listeDiv;
+var extensionsHeader = new Array();
+var extensionsContent = new Array();
+window.onload = loadTables;
+function loadTables(){
+	'.$javascript_message.'
+	var listeDiv = document.getElementsByTagName("div");
+	
+	// fill extensionsHeader and extensionsContent
+	for(var i=0 ; i < listeDiv.length ; i++){
+		if(listeDiv[i].id.indexOf(\'extension_header\')!=-1){
+			listeDiv[i].onclick = afficheContent;
+			extensionsHeader.push(listeDiv[i]);		
+		}
+		if(listeDiv[i].id.indexOf("extension_content")!=-1){
+			extensionsContent.push(listeDiv[i]);
+		}
+	}
+'.$javascript_service_displayed.'
+}
+
+function hideMessage(){
+	document.getElementById("message").style.display = "none";
+}
+
+function afficheContent(event){	
+	var id = this.id.replace("header","content");
+	switch(document.getElementById(id).style.display){
+		case "block" : 			
+			document.getElementById(id).style.display = "none";
+			break;
+		case "none" :
+			document.getElementById(id).style.display = "block";
+			for(var i=0 ; i < extensionsContent.length ; i++){
+				if(extensionsContent[i].id != id)
+					extensionsContent[i].style.display = "none";				
+			}
+			break;
+	}
+}
+</script>';
+
+$nameTool = get_lang('ConfigureExtensions');
+Display::display_header($nameTool);
+
+?>
+
+
+<div id="message" style="display: none">
+	<?php 
+	if(!empty($message))
+		Display::display_normal_message($message) 
+	?>
+</div>
+
+<div id="content" align="center">
+
+
+
+<!-- INSTRUCTIONS TO ADD AN EXTENSION HERE
+- copy paste a "main_*" div 
+- set the names of the subdiv to extension_header_yourextension and extension_content_yourextension
+- extension_content_yourextension is the hidden div where you have to put your form / activation process
+- extension_header_yourextension is the name of your extension
+- you do not need to add javascript to display / hide your divs
+- please fill free to improve the global display of the document
+-->
+	<!-- VISIOCONFERENCE -->
+	<div id="main_visio">
+		<div id="extension_header_visio" class="accordion_header">
+			<a href="#"><?php echo get_lang('Visioconf') ?></a>
+		</div>
+		<div id="extension_content_visio" style="display:none" class="accordion_content">		
+			<?php echo get_lang('VisioconfDescription') ?><br /><br />
+			<table width="100%">
+				<tr>
+					<td>
+						<img src="<?php echo api_get_path(WEB_IMG_PATH).'screenshot_conf.jpg' ?>" />
+					</td>
+					<td align="center" width="50%">
+						<form method="POST" action="<?php echo $_SERVER['PHP_SELF'] ?>">
+						<?php 
+						if(in_array('visio',$listActiveServices)){
+							echo get_lang('ExtensionActivedButNotYetOperational');
+						}
+						else {
+								echo '
+									<input type="hidden" name="extension_code" value="visio" />
+									<input type="submit" name="activeExtension" value="'.get_lang('ActiveExtension').'" />';
+						}
+						?>
+						</form>
+					</td>
+				</tr>
+			</table>
+		</div>
+	</div>
+	
+	<!-- PPT2LP -->
+	<div id="main_ppt2lp">
+		<div id="extension_header_ppt2lp" class="accordion_header">
+			<a href="#"><?php echo get_lang('Ppt2lp') ?></a>
+		</div>
+		<div id="extension_content_ppt2lp" style="display:none" class="accordion_content">		
+			<?php echo get_lang('Ppt2lpDescription') ?><br /><br />
+			<table width="100%">
+				<tr>
+					<td width="50%">
+						<img src="<?php echo api_get_path(WEB_IMG_PATH).'screenshot_ppt2lp.jpg' ?>" />
+					</td>
+					<td align="center" width="50%">
+						<form method="POST" action="<?php echo $_SERVER['PHP_SELF'] ?>">
+						<?php 
+						if(in_array('ppt2lp',$listActiveServices)){
+							echo get_lang('ExtensionActivedButNotYetOperational');
+						}
+						else {
+								echo '
+									<input type="hidden" name="extension_code" value="ppt2lp" />
+									<input type="submit" name="activeExtension" value="'.get_lang('ActiveExtension').'" />';
+						}
+						?>
+						</form>
+					</td>
+				</tr>
+			</table>
+		</div>
+	</div>
+	
+	<!-- SEARCH -->
+	<div id="main_search">
+		<div id="extension_header_search" class="accordion_header">
+			<a href="#"><?php echo get_lang('SearchEngine') ?></a>
+		</div>
+		<div id="extension_content_search" style="display:none" class="accordion_content">		
+			<?php echo get_lang('SearchEngineDescription') ?><br /><br />
+			<table width="100%">
+				<tr>
+					<td width="50%">
+						<img src="<?php echo api_get_path(WEB_IMG_PATH).'screenshot_search.jpg' ?>" />
+					</td>
+					<td align="center" width="50%">
+						<form method="POST" action="<?php echo $_SERVER['PHP_SELF'] ?>">
+						<input type="hidden" name="extension_code" value="search" />
+						<input type="submit" name="activeExtension" value="<?php echo get_lang('ActiveExtension') ?>" />
+						</form>
+					</td>
+				</tr>
+			</table>
+		</div>
+	</div>
+	
+	<!-- SERVER STATS -->
+	<div id="main_serverstats">
+		<div id="extension_header_serverstats" class="accordion_header">
+			<a href="#"><?php echo get_lang('ServerStatistics') ?></a>
+		</div>
+		<div id="extension_content_serverstats" style="display:none" class="accordion_content">		
+			<?php echo get_lang('ServerStatisticsDescription') ?><br /><br />
+			<table width="100%">
+				<tr>
+					<td width="50%">
+						<img src="<?php echo api_get_path(WEB_IMG_PATH).'screenshot_serverstats.jpg' ?>" />
+					</td>
+					<td align="center" width="50%">
+						<form method="POST" action="<?php echo $_SERVER['PHP_SELF'] ?>">
+						<input type="hidden" name="extension_code" value="serverstats" />
+						<input type="submit" name="activeExtension" value="<?php echo get_lang('ActiveExtension') ?>" />
+						</form>
+					</td>
+				</tr>
+			</table>
+		</div>
+	</div>
+	
+	<!-- BANDWIDTH STATS -->
+	<div id="main_bandwidthstats">
+		<div id="extension_header_bandwidthstats" class="accordion_header">
+			<a href="#"><?php echo get_lang('BandWidthStatistics') ?></a>
+		</div>
+		<div id="extension_content_bandwidthstats" style="display:none" class="accordion_content">		
+			<?php echo get_lang('BandWidthStatisticsDescription') ?><br /><br />
+			<table width="100%">
+				<tr>
+					<td width="50%">
+						<img src="<?php echo api_get_path(WEB_IMG_PATH).'screenshot_bandwidth.jpg' ?>" />
+					</td>
+					<td align="center" width="50%">
+						<form method="POST" action="<?php echo $_SERVER['PHP_SELF'] ?>">
+						<input type="hidden" name="extension_code" value="bandwidthstats" />
+						<input type="submit" name="activeExtension" value="<?php echo get_lang('ActiveExtension') ?>" />
+						</form>
+					</td>
+				</tr>
+			</table>
+		</div>
+	</div>
+	
+</div><!-- /content -->
+	
+
+<?php
+
+/*
+==============================================================================
+		FOOTER
+==============================================================================
+*/
+Display::display_footer();
+?>

+ 708 - 0
main/admin/configure_homepage.php

@@ -0,0 +1,708 @@
+<?php // $Id: configure_homepage.php 9246 2006-09-25 13:24:53Z bmol $
+/*
+==============================================================================
+	Dokeos - elearning and course management software
+
+	Copyright (c) 2004 Dokeos S.A.
+	Copyright (c) 2003 Ghent University (UGent)
+	Copyright (c) 2001 Universite catholique de Louvain (UCL)
+	Copyright (c) Olivier Brouckaert
+
+	For a full list of contributors, see "credits.txt".
+	The full license can be read in "license.txt".
+
+	This program is free software; you can redistribute it and/or
+	modify it under the terms of the GNU General Public License
+	as published by the Free Software Foundation; either version 2
+	of the License, or (at your option) any later version.
+
+	See the GNU General Public License for more details.
+
+	Contact: Dokeos, 181 rue Royale, B-1000 Brussels, Belgium, info@dokeos.com
+==============================================================================
+*/
+
+$langFile='admin';
+
+$cidReset=true;
+
+include('../inc/global.inc.php');
+$this_section=SECTION_PLATFORM_ADMIN;
+
+api_protect_admin_script();
+include_once(api_get_path(LIBRARY_PATH).'fileUpload.lib.php');
+
+$action=$_GET['action'];
+
+$tbl_category=Database::get_main_table(MAIN_CATEGORY_TABLE);
+
+$tool_name=get_lang('ConfigureHomePage');
+
+//$interbreadcrumb[]=array("url" => "index.php","name" => get_lang('PlatformAdmin'));
+
+$menu_language=$_SESSION['user_language_choice'];
+
+if(!isset($menu_language))
+{
+	$menu_language=$platformLanguage;
+}
+
+if(!file_exists('../../home/home_menu_'.$menu_language.'.html'))
+{
+	copy('../../home/home_menu.html','../../home/home_menu_'.$menu_language.'.html');
+}
+
+$errorMsg='';
+
+if(!empty($action))
+{
+	if($_POST['formSent'])
+	{
+		if($action == 'edit_top')
+		{
+			$home_top=trim(stripslashes($_POST['home_top']));
+
+			if(!is_writable('../../home/home_top.html'))
+			{
+				$errorMsg=get_lang('HomePageFilesNotWritable');
+			}
+			elseif(!empty($home_top))
+			{
+				$fp=fopen('../../home/home_top.html','w');
+
+				fputs($fp,$home_top);
+
+				fclose($fp);
+			}
+		}
+		elseif($action == 'edit_notice')
+		{
+			$notice_title=trim(strip_tags(stripslashes($_POST['notice_title'])));
+			$notice_text=trim(str_replace(array("\r","\n"),array("","<br />"),strip_tags(stripslashes($_POST['notice_text']),'<a>')));
+
+			if(empty($notice_title))
+			{
+				$errorMsg=get_lang('PleaseEnterNoticeTitle');
+			}
+			elseif(empty($notice_text))
+			{
+				$errorMsg=get_lang('PleaseEnterNoticeText');
+			}
+			elseif(!is_writable('../../home/home_notice.html'))
+			{
+				$errorMsg=get_lang('HomePageFilesNotWritable');
+			}
+			else
+			{
+				$fp=fopen('../../home/home_notice.html','w');
+
+				fputs($fp,"<b>$notice_title</b><br />\n$notice_text");
+
+				fclose($fp);
+			}
+		}
+		elseif($action == 'edit_news')
+		{
+			$home_news=trim(stripslashes($_POST['home_news']));
+
+			if(!is_writable('../../home/home_news.html'))
+			{
+				$errorMsg=get_lang('HomePageFilesNotWritable');
+			}
+			elseif(!empty($home_news))
+			{
+				$fp=fopen('../../home/home_news.html','w');
+
+				fputs($fp,$home_news);
+
+				fclose($fp);
+			}
+		}
+		elseif($action == 'insert_link' || $action == 'edit_link')
+		{
+			$link_index=intval($_POST['link_index']);
+			$insert_where=intval($_POST['insert_where']);
+			$link_name=trim(stripslashes($_POST['link_name']));
+			$link_url=trim(stripslashes($_POST['link_url']));
+			$link_html=trim(stripslashes($_POST['link_html']));
+			$filename=trim(stripslashes($_POST['filename']));
+			$target_blank=$_POST['target_blank']?true:false;
+
+			if($link_url == 'http://')
+			{
+				$link_url='';
+			}
+			elseif(!empty($link_url) && !strstr($link_url,'://'))
+			{
+				$link_url='http://'.$link_url;
+			}
+
+			if(!is_writable('../../home/home_menu_'.$menu_language.'.html'))
+			{
+				$errorMsg=get_lang('HomePageFilesNotWritable');
+			}
+			elseif(empty($link_name))
+			{
+				$errorMsg=get_lang('PleaseEnterLinkName');
+			}
+			else
+			{
+				if($action == 'insert_link' || empty($filename) || strstr($filename,'/') || !strstr($filename,'.html'))
+				{
+					$filename=replace_dangerous_char($link_name,'strict').'.html';
+				}
+
+				if(!empty($filename))
+				{
+					$filename=str_replace('home_','user_',$filename);
+				}
+
+				if(!strstr($filename,'_'.$menu_language.'.html'))
+				{
+					$filename=str_replace('.html','_'.$menu_language.'.html',$filename);
+				}
+
+				$home_menu=file('../../home/home_menu_'.$menu_language.'.html');
+
+				if($insert_where < -1 || $insert_where > (sizeof($home_menu) - 1))
+				{
+					$insert_where=sizeof($home_menu) - 1;
+				}
+
+				foreach($home_menu as $key=>$enreg)
+				{
+					$home_menu[$key]=trim($enreg);
+				}
+
+				if(empty($link_url))
+				{
+					$link_url=$rootWeb.'index.php?include='.urlencode($filename);
+
+					if(!file_exists($rootSys.'home/'.$filename))
+					{
+						$fp=@fopen($rootSys.'home/'.$filename,'w');
+
+						if($fp)
+						{
+							fputs($fp,get_lang('MyTextHere'));
+
+							fclose($fp);
+						}
+					}
+				}
+
+				if($action == 'edit_link' && !empty($link_html))
+				{
+					$fp=@fopen($rootSys.'home/'.$filename,'w');
+
+					if($fp)
+					{
+						fputs($fp,$link_html);
+
+						fclose($fp);
+					}
+				}
+
+				if($action == 'insert_link')
+				{
+					for($i=sizeof($home_menu);$i;$i--)
+					{
+						if($i > $insert_where)
+						{
+							$home_menu[$i]=$home_menu[$i-1];
+						}
+						else
+						{
+							break;
+						}
+					}
+
+					$home_menu[$insert_where+1]='<li><a href="'.$link_url.'" target="'.($target_blank?'_blank':'_self').'">'.$link_name.'</a></li>';
+				}
+				else
+				{
+					$home_menu[$link_index]='<li><a href="'.$link_url.'" target="'.($target_blank?'_blank':'_self').'">'.$link_name.'</a></li>';
+				}
+
+				$home_menu=implode("\n",$home_menu);
+
+				$fp=fopen('../../home/home_menu_'.$menu_language.'.html','w');
+
+				fputs($fp,$home_menu);
+
+				fclose($fp);
+			}
+		}
+
+		if(empty($errorMsg))
+		{
+			header('Location: '.$_SERVER['PHP_SELF']);
+			exit();
+		}
+	}
+	elseif($action == 'open_link')
+	{
+		$link=$_GET['link'];
+
+		if(strstr($link,'/') || !strstr($link,'.html'))
+		{
+			$link='';
+			$action='';
+		}
+	}
+	elseif($action == 'delete_link')
+	{
+		$link_index=intval($_GET['link_index']);
+
+		$home_menu=file('../../home/home_menu_'.$menu_language.'.html');
+
+		foreach($home_menu as $key=>$enreg)
+		{
+			if($key == $link_index)
+			{
+				unset($home_menu[$key]);
+			}
+			else
+			{
+				$home_menu[$key]=trim($enreg);
+			}
+		}
+
+		$home_menu=implode("\n",$home_menu);
+
+		$fp=fopen('../../home/home_menu_'.$menu_language.'.html','w');
+
+		fputs($fp,$home_menu);
+
+		fclose($fp);
+
+		header('Location: '.$_SERVER['PHP_SELF']);
+		exit();
+	}
+	elseif($action == 'edit_top')
+	{
+		$home_top=file('../../home/home_top.html');
+
+		$home_top=implode('',$home_top);
+	}
+	elseif($action == 'edit_notice')
+	{
+		$home_notice=file('../../home/home_notice.html');
+
+		$notice_title=strip_tags($home_notice[0]);
+		$notice_text=strip_tags(str_replace('<br />',"\n",$home_notice[1]),'<a>');
+	}
+	elseif($action == 'edit_news')
+	{
+		$home_news=file('../../home/home_news.html');
+
+		$home_news=implode('',$home_news);
+	}
+	elseif($action == 'insert_link')
+	{
+		$home_menu=file('../../home/home_menu_'.$menu_language.'.html');
+	}
+	elseif($action == 'edit_link')
+	{
+		$link_index=intval($_GET['link_index']);
+
+		$home_menu=file('../../home/home_menu_'.$menu_language.'.html');
+
+		$target_blank=false;
+		$link_name='';
+		$link_url='';
+
+		foreach($home_menu as $key=>$enreg)
+		{
+			if($key == $link_index)
+			{
+				if(strstr($enreg,'target="_blank"'))
+				{
+					$target_blank=true;
+				}
+
+				$link_name=strip_tags($enreg);
+
+				$enreg=explode('href="',$enreg);
+
+				list($link_url)=explode('"',$enreg[sizeof($enreg)-1]);
+
+				if(strstr($link_url,$rootWeb) && strstr($link_url,'?include='))
+				{
+					$link_url=explode('?include=',$link_url);
+
+					$filename=$link_url[sizeof($link_url)-1];
+
+					if(!strstr($filename,'/') && strstr($filename,'.html'))
+					{
+						$link_html=file($rootWeb.'home/'.$filename);
+
+						$link_html=implode('',$link_html);
+
+						$link_url='';
+					}
+					else
+					{
+						$filename='';
+					}
+				}
+
+				break;
+			}
+		}
+	}
+}
+else
+{
+	$result=api_sql_query("SELECT name FROM $tbl_category WHERE parent_id IS NULL ORDER BY tree_pos",__FILE__,__LINE__);
+
+	$Categories=api_store_result($result);
+}
+
+Display::display_header($tool_name);
+
+//api_display_tool_title($tool_name);
+
+if($action == 'open_link')
+{
+?>
+
+<div style="margin-bottom: 10px;">
+<a href="<?php echo $_SERVER['PHP_SELF']; ?>">&lt;&lt; <?php echo get_lang('Back'); ?></a>
+</div>
+
+<?php
+	include('../../home/'.$link);
+}
+elseif($action == 'edit_notice')
+{
+?>
+
+<div style="margin-bottom: 10px;">
+<a href="<?php echo $_SERVER['PHP_SELF']; ?>">&lt;&lt; <?php echo get_lang('Back'); ?></a>
+</div>
+
+<form action="<?php echo $_SERVER['PHP_SELF']; ?>?action=<?php echo $action; ?>" method="post" style="margin:0px;">
+<input type="hidden" name="formSent" value="1"/>
+
+<table border="0" cellpadding="5" cellspacing="0">
+
+<?php
+if(!empty($errorMsg))
+{
+?>
+
+<tr>
+  <td colspan="2">
+
+<?php
+	Display::display_normal_message($errorMsg); //main API
+?>
+
+  </td>
+</tr>
+
+<?php
+}
+?>
+
+<tr>
+  <td nowrap="nowrap"><?php echo get_lang('NoticeTitle'); ?> :</td>
+  <td><input type="text" name="notice_title" size="30" maxlength="50" value="<?php echo htmlentities($notice_title); ?>" style="width: 350px;"/></td>
+</tr>
+<tr>
+  <td nowrap="nowrap" valign="top"><?php echo get_lang('NoticeText'); ?> :</td>
+  <td><textarea name="notice_text" cols="30" rows="5" wrap="virtual" style="width: 350px;"><?php echo htmlentities($notice_text); ?></textarea></td>
+</tr>
+<tr>
+  <td>&nbsp;</td>
+  <td><input type="submit" value="<?php echo get_lang('Ok'); ?>"/></td>
+</tr>
+</table>
+
+</form>
+
+<?php
+}
+elseif($action == 'insert_link' || $action == 'edit_link')
+{
+?>
+
+<div style="margin-bottom: 10px;">
+<a href="<?php echo $_SERVER['PHP_SELF']; ?>">&lt;&lt; <?php echo get_lang('Back'); ?></a>
+</div>
+
+<form action="<?php echo $_SERVER['PHP_SELF']; ?>?action=<?php echo $action; ?>" method="post" style="margin:0px;">
+<input type="hidden" name="formSent" value="1"/>
+<input type="hidden" name="link_index" value="<?php if($action == 'edit_link') echo $link_index; else echo '0'; ?>"/>
+<input type="hidden" name="filename" value="<?php if($action == 'edit_link') echo $filename; else echo ''; ?>"/>
+
+<table border="0" cellpadding="5" cellspacing="0">
+
+<?php
+if(!empty($errorMsg))
+{
+?>
+
+<tr>
+  <td colspan="2">
+
+<?php
+	Display::display_normal_message($errorMsg); //main API
+?>
+
+  </td>
+</tr>
+
+<?php
+}
+?>
+
+<tr>
+  <td nowrap="nowrap"><?php echo get_lang('LinkName'); ?> :</td>
+  <td><input type="text" name="link_name" size="30" maxlength="50" value="<?php echo htmlentities($link_name); ?>" style="width: 350px;"/></td>
+</tr>
+<tr>
+  <td nowrap="nowrap"><?php echo get_lang('LinkURL'); ?> (<?php echo get_lang('Optional'); ?>) :</td>
+  <td><input type="text" name="link_url" size="30" maxlength="100" value="<?php if(empty($link_url)) echo 'http://'; else echo htmlentities($link_url); ?>" style="width: 350px;"/></td>
+</tr>
+
+<?php if($action == 'insert_link'): ?>
+<tr>
+  <td nowrap="nowrap"><?php echo get_lang('InsertThisLink'); ?> :</td>
+  <td><select name="insert_where">
+  <option value="-1"><?php echo get_lang('FirstPlace'); ?></option>
+
+<?php
+foreach($home_menu as $key=>$enreg)
+{
+?>
+
+  <option value="<?php echo $key; ?>" <?php if($formSent && $insert_where == $key) echo 'selected="selected"'; ?> ><?php echo get_lang('After'); ?> &quot;<?php echo trim(strip_tags($enreg)); ?>&quot;</option>
+
+<?php
+}
+?>
+
+  </select></td>
+</tr>
+<?php endif; ?>
+
+<tr>
+  <td nowrap="nowrap"><?php echo get_lang('OpenInNewWindow'); ?> ?</td>
+  <td><input class="checkbox" type="checkbox" name="target_blank" value="1" <?php if($target_blank) echo 'checked="checked"'; ?> /> <?php echo get_lang('Yes'); ?></td>
+</tr>
+
+<?php if($action == 'edit_link' && empty($link_url)): ?>
+</table>
+<table border="0" cellpadding="5" cellspacing="0" width="100%">
+<tr>
+  <td>
+
+<?php
+    api_disp_html_area('link_html',isset($_POST['link_html'])?$_POST['link_html']:$link_html,'400px');
+?>
+
+  </td>
+</tr>
+<tr>
+  <td><input type="submit" value="<?php echo get_lang('Ok'); ?>"/></td>
+</tr>
+<?php else: ?>
+<tr>
+  <td>&nbsp;</td>
+  <td><input type="submit" value="<?php echo get_lang('Ok'); ?>"/></td>
+</tr>
+<?php endif; ?>
+
+</table>
+
+</form>
+
+<?php
+}
+elseif($action == 'edit_top' || $action == 'edit_news')
+{
+	if($action == 'edit_top')
+	{
+		$open='home_top';
+	}
+	else
+	{
+		$open='home_news';
+	}
+?>
+
+<div style="margin-bottom: 10px;">
+<a href="<?php echo $_SERVER['PHP_SELF']; ?>">&lt;&lt; <?php echo get_lang('Back'); ?></a>
+</div>
+
+<form action="<?php echo $_SERVER['PHP_SELF']; ?>?action=<?php echo $action; ?>" method="post" style="margin:0px;">
+<input type="hidden" name="formSent" value="1"/>
+
+<?php
+if(!empty($errorMsg))
+{
+	Display::display_normal_message($errorMsg); //main API
+}
+?>
+
+<table border="0" cellpadding="5" cellspacing="0" width="100%">
+<tr>
+  <td>
+
+<?php
+    api_disp_html_area($open,isset($_POST[$open])?trim(stripslashes($_POST[$open])):${$open},'400px');
+?>
+
+  </td>
+</tr>
+<tr>
+  <td><input type="submit" value="<?php echo get_lang('Ok'); ?>"/></td>
+</tr>
+</table>
+
+</form>
+
+<?php
+}
+else
+{
+?>
+
+<table border="0" cellpadding="5" cellspacing="0" width="100%">
+<tr>
+  <td width="80%" colspan="2">
+	<a href="<?php echo $_SERVER['PHP_SELF']; ?>?action=edit_top"><img src="../img/edit.gif" border="0" title="<?php echo htmlentities(get_lang('Modify')); ?>"/></a> <a href="<?php echo $_SERVER['PHP_SELF']; ?>?action=edit_top"><?php echo get_lang('EditHomePage'); ?></a>
+  </td>
+  <td width="20%">
+	<a href="<?php echo $_SERVER['PHP_SELF']; ?>?action=insert_link"><img src="../img/insert_row.png" border="0"/></a> <a href="<?php echo $_SERVER['PHP_SELF']; ?>?action=insert_link"/><?php echo get_lang('InsertLink'); ?></a>
+  </td>
+</tr>
+<tr>
+  <td width="80%" colspan="2" valign="top">
+	<table border="0" cellpadding="5" cellspacing="0" width="100%">
+	<tr>
+	  <td colspan="2">
+
+<?php
+	include('../../home/home_top.html');
+?>
+
+	  </td>
+	</tr>
+	<tr>
+	  <td width="50%">
+		<br />
+		<a href="course_category.php"><img src="../img/edit.gif" border="0" title="<?php echo htmlentities(get_lang('Modify')); ?>"/></a> <a href="course_category.php"><?php echo get_lang('EditCategories'); ?></a>
+	  </td>
+	  <td width="50%">
+		<br />
+		<a href="<?php echo $_SERVER['PHP_SELF']; ?>?action=edit_news"><img src="../img/edit.gif" border="0" title="<?php echo htmlentities(get_lang('Modify')); ?>"/></a> <a href="<?php echo $_SERVER['PHP_SELF']; ?>?action=edit_news"><?php echo get_lang('EditNews'); ?></a>
+	  </td>
+	</tr>
+	<tr>
+	  <td width="50%" valign="top">
+		<table border="0" cellpadding="5" cellspacing="0" width="100%">
+
+	<?php
+		if(sizeof($Categories))
+		{
+			foreach($Categories as $enreg)
+			{
+	?>
+
+		  <tr>
+			<td><img src="../img/opendir.gif" border="0" alt=""/>&nbsp;<?php echo $enreg['name']; ?></td>
+		  </tr>
+
+	<?php
+			}
+
+			unset($Categories);
+		}
+		else
+		{
+			echo get_lang('NoCategories');
+		}
+	?>
+
+		</table>
+	  </td>
+	  <td width="50%" valign="top">
+
+	<?php
+		include('../../home/home_news.html');
+	?>
+
+	  </td>
+	</tr>
+	</table>
+  </td>
+  <td width="20%" rowspan="3" valign="top">
+	<div class="menu" style="width: 100%;">
+	<?php
+	api_display_language_form();
+	?>
+	<form id="loginform">
+	<label><?php echo get_lang('LoginName'); ?></label>
+	<input type="text" id="login" size="15" value="" disabled="disabled" />
+	<label><?php echo get_lang('UserPassword'); ?></label>
+	<input type="password" id="password" size="15" disabled="disabled" />
+	<input type="button" value="<?php echo get_lang('Ok'); ?>" disabled="disabled" />
+	</form>
+	<div class="menusection">
+	<span class="menusectioncaption"><?php echo get_lang('User'); ?></span>
+	<ul class="menulist">
+	<li><span style="color: #9D9DA1; font-weight: bold;"><?php echo ucfirst(get_lang('Registration')); ?></span></li>
+	<li><span style="color: #9D9DA1; font-weight: bold;"><?php echo ucfirst(get_lang('LostPassword')); ?></span></li>
+	</ul>
+	</div>
+	<div class="menusection">
+	<span class="menusectioncaption"><?php echo ucfirst(get_lang('General')); ?></span>
+	<ul class="menulist">
+
+<?php
+	$home_menu=file('../../home/home_menu_'.$menu_language.'.html');
+
+	foreach($home_menu as $key=>$enreg)
+	{
+		$enreg=trim($enreg);
+
+		if(!empty($enreg))
+		{
+			$edit_link='<a href="'.$_SERVER['PHP_SELF'].'?action=edit_link&amp;link_index='.$key.'"><img src="../img/edit.gif" border="0" style="margin-top: 2px;" title="'.htmlentities(get_lang('Modify')).'"/></a>';
+			$delete_link='<a href="'.$_SERVER['PHP_SELF'].'?action=delete_link&amp;link_index='.$key.'" onclick="javascript:if(!confirm(\''.addslashes(htmlentities(get_lang('ConfirmYourChoice'))).'\')) return false;"><img src="../img/delete.gif" border="0" style="margin-top: 2px;" title="'.htmlentities(get_lang('Delete')).'"/></a>';
+
+			echo str_replace(array('href="'.$rootWeb.'index.php?include=','</li>'),array('href="'.api_get_path(WEB_CODE_PATH).'admin/'.basename($_SERVER['PHP_SELF']).'?action=open_link&link=','<br />'.$edit_link.' '.$delete_link.'</li>'),$enreg);
+		}
+	}
+?>
+
+	</ul>
+	</div>
+
+	<br />
+	&nbsp;&nbsp;<a href="<?php echo $_SERVER['PHP_SELF']; ?>?action=edit_notice"><img src="../img/edit.gif" border="0" title="<?php echo htmlentities(get_lang('Modify')); ?>"/></a> <a href="<?php echo $_SERVER['PHP_SELF']; ?>?action=edit_notice"><?php echo get_lang('EditNotice'); ?></a>
+
+	<div class="note">
+
+<?php
+	include('../../home/home_notice.html');
+?>
+
+	</div>
+	</div>
+  </td>
+</tr>
+</table>
+
+<?php
+}
+/*
+==============================================================================
+		FOOTER
+==============================================================================
+*/
+Display::display_footer();
+?>

+ 150 - 0
main/admin/course_add.php

@@ -0,0 +1,150 @@
+<?php
+// $Id: course_add.php 9403 2006-10-10 10:21:34Z bmol $
+/*
+==============================================================================
+	Dokeos - elearning and course management software
+
+	Copyright (c) 2004 Dokeos S.A.
+	Copyright (c) 2003 Ghent University (UGent)
+	Copyright (c) 2001 Universite catholique de Louvain (UCL)
+	Copyright (c) Olivier Brouckaert
+	Copyright (c) Bart Mollet, Hogeschool Gent
+
+	For a full list of contributors, see "credits.txt".
+	The full license can be read in "license.txt".
+
+	This program is free software; you can redistribute it and/or
+	modify it under the terms of the GNU General Public License
+	as published by the Free Software Foundation; either version 2
+	of the License, or (at your option) any later version.
+
+	See the GNU General Public License for more details.
+
+	Contact: Dokeos, 181 rue Royale, B-1000 Brussels, Belgium, info@dokeos.com
+==============================================================================
+*/
+/**
+==============================================================================
+*	@package dokeos.admin
+==============================================================================
+*/
+/*
+==============================================================================
+		INIT SECTION
+==============================================================================
+*/
+$langFile = array('admin','create_course');
+$cidReset = true;
+require_once ('../inc/global.inc.php');
+$this_section=SECTION_PLATFORM_ADMIN;
+
+api_protect_admin_script();
+require_once (api_get_path(LIBRARY_PATH).'fileManage.lib.php');
+require_once (api_get_path(CONFIGURATION_PATH).'add_course.conf.php');
+require_once (api_get_path(LIBRARY_PATH).'add_course.lib.inc.php');
+require_once (api_get_path(LIBRARY_PATH).'formvalidator/FormValidator.class.php');
+$table_course = Database::get_main_table(MAIN_COURSE_TABLE);
+$tool_name = get_lang('AddCourse');
+//$interbreadcrumb[] = array ("url" => "index.php", "name" => get_lang('PlatformAdmin'));
+
+/*
+==============================================================================
+		MAIN CODE
+==============================================================================
+*/
+
+// Get all course categories
+$table_course_category = Database :: get_main_table(MAIN_CATEGORY_TABLE);
+$sql = "SELECT code,name FROM ".$table_course_category." WHERE auth_course_child ='TRUE' ORDER BY tree_pos";
+$res = api_sql_query($sql, __FILE__, __LINE__);
+while ($cat = mysql_fetch_array($res))
+{
+	$categories[$cat['code']] = '('.$cat['code'].') '.$cat['name'];
+}
+
+// Get all possible teachers
+$table_user = Database :: get_main_table(MAIN_USER_TABLE);
+$sql = "SELECT user_id,lastname,firstname FROM $table_user WHERE status=1 ORDER BY lastname,firstname";
+$res = api_sql_query($sql,__FILE__,__LINE__);
+$teachers = array();
+while($obj = mysql_fetch_object($res))
+{
+		$teachers[$obj->user_id] = $obj->lastname.' '.$obj->firstname;
+}
+// Build the form
+$form = new FormValidator('update_course');
+$form->add_textfield( 'visual_code', get_lang('CourseCode'),true,array('size'=>'20','maxlength'=>20));
+$form->applyFilter('visual_code','strtoupper');
+$form->addRule('wanted_code',get_lang('Max'),'maxlength',20);
+$form->addElement('select', 'tutor_id', get_lang('CourseTitular'), $teachers);
+$form->add_textfield('title', get_lang('Title'),true, array ('size' => '60'));
+$form->addElement('select', 'category_code', get_lang('CourseFaculty'), $categories);
+$form->add_textfield('department_name', get_lang('CourseDepartment'),false, array ('size' => '60'));
+$form->add_textfield('department_url', get_lang('CourseDepartmentURL'),false, array ('size' => '60'));
+$form->addElement('select_language', 'course_language', get_lang('CourseLanguage'));
+$form->addElement('radio', 'visibility', get_lang("CourseAccess"), get_lang('OpenToTheWorld'), COURSE_VISIBILITY_OPEN_WORLD);
+$form->addElement('radio', 'visibility', null, get_lang('OpenToThePlatform'), COURSE_VISIBILITY_OPEN_PLATFORM);
+$form->addElement('radio', 'visibility', null, get_lang('Private'), COURSE_VISIBILITY_REGISTERED);
+$form->addElement('radio', 'visibility', null, get_lang('CourseVisibilityClosed'), COURSE_VISIBILITY_CLOSED);
+$form->addElement('radio', 'subscribe', get_lang('Subscription'), get_lang('Allowed'), 1);
+$form->addElement('radio', 'subscribe', null, get_lang('Denied'), 0);
+$form->addElement('radio', 'unsubscribe', get_lang('Unsubscription'), get_lang('AllowedToUnsubscribe'), 1);
+$form->addElement('radio', 'unsubscribe', null, get_lang('NotAllowedToUnsubscribe'), 0);
+$form->add_textfield('disk_quota',get_lang('CourseQuota'));
+$form->addRule('disk_quota',get_lang('ThisFieldShouldBeNumeric'),'numeric');
+$form->add_progress_bar();
+$form->addElement('submit', null, get_lang('Ok'));
+// Set some default values
+$values['course_language'] = get_setting('platformLanguage');
+$values['disk_quota'] = get_setting('default_document_quotum');
+$values['visibility'] = COURSE_VISIBILITY_OPEN_PLATFORM;
+$values['subscribe'] = 1;
+$values['unsubscribe'] = 0;
+$form->setDefaults($values);
+// Validate form
+if( $form->validate())
+{
+	$course = $form->exportValues();
+	$code = $course['visual_code'];
+	$tutor_name = $teachers[$course['tutor_id']];
+	$teacher_id = $course['tutor_id'];
+	$title = $course['title'];
+	$category = $course['category_code'];
+	$department_name = $course['department_name'];
+	$department_url = $course['department_url'];
+	$course_language = $course['course_language'];
+	$disk_quota = $course['disk_quota'];
+	if (!stristr($department_url, 'http://'))
+	{
+		$department_url = 'http://'.$department_url;
+	}
+	$keys = define_course_keys($code, "", $dbNamePrefix);
+	if (sizeof($keys))
+	{
+		$currentCourseCode = $keys["currentCourseCode"];
+		$currentCourseId = $keys["currentCourseId"];
+		$currentCourseDbName = $keys["currentCourseDbName"];
+		$currentCourseRepository = $keys["currentCourseRepository"];
+		$expiration_date = time() + $firstExpirationDelay;
+		prepare_course_repository($currentCourseRepository, $currentCourseId);
+		update_Db_course($currentCourseDbName);
+		fill_course_repository($currentCourseRepository);
+		fill_Db_course($currentCourseDbName, $currentCourseRepository, $course_language);
+		register_course($currentCourseId, $currentCourseCode, $currentCourseRepository, $currentCourseDbName, $tutor_name, $category, $title, $course_language, $teacher_id, $expiration_date);
+		$sql = "UPDATE $table_course SET disk_quota = '".$disk_quota."', visibility = '".mysql_real_escape_string($course['visibility'])."', subscribe = '".mysql_real_escape_string($course['subscribe'])."', unsubscribe='".mysql_real_escape_string($course['unsubscribe'])."' WHERE code = '".$currentCourseId."'";
+		api_sql_query($sql,__FILE__,__LINE__);
+		header('Location: course_list.php');
+		exit ();
+	}
+}
+Display::display_header($tool_name);
+//api_display_tool_title($tool_name);
+// Display the form
+$form->display();
+/*
+==============================================================================
+		FOOTER
+==============================================================================
+*/
+Display :: display_footer();
+?>

+ 361 - 0
main/admin/course_category.php

@@ -0,0 +1,361 @@
+<?php // $Id: course_category.php 9246 2006-09-25 13:24:53Z bmol $
+/*
+==============================================================================
+	Dokeos - elearning and course management software
+
+	Copyright (c) 2004 Dokeos S.A.
+	Copyright (c) 2003 Ghent University (UGent)
+	Copyright (c) 2001 Universite catholique de Louvain (UCL)
+	Copyright (c) Olivier Brouckaert
+
+	For a full list of contributors, see "credits.txt".
+	The full license can be read in "license.txt".
+
+	This program is free software; you can redistribute it and/or
+	modify it under the terms of the GNU General Public License
+	as published by the Free Software Foundation; either version 2
+	of the License, or (at your option) any later version.
+
+	See the GNU General Public License for more details.
+
+	Contact: Dokeos, 181 rue Royale, B-1000 Brussels, Belgium, info@dokeos.com
+==============================================================================
+*/
+/**
+==============================================================================
+*	@package dokeos.admin
+==============================================================================
+*/
+
+$langFile='admin';
+
+$cidReset=true;
+
+require('../inc/global.inc.php');
+$this_section=SECTION_PLATFORM_ADMIN;
+
+api_protect_admin_script();
+$category=$_GET['category'];
+$action=$_GET['action'];
+
+$tbl_course  = Database::get_main_table(MAIN_COURSE_TABLE);
+$tbl_category = Database::get_main_table(MAIN_CATEGORY_TABLE);
+
+$errorMsg='';
+
+if(!empty($action))
+{
+	if($action == 'delete')
+	{
+		deleteNode($_GET['id']);
+
+		header('Location: '.$_SERVER['PHP_SELF'].'?category='.$category);
+		exit();
+	}
+	elseif(($action == 'add' || $action == 'edit') && $_POST['formSent'])
+	{
+		$_POST['categoryCode']=trim($_POST['categoryCode']);
+		$_POST['categoryName']=trim($_POST['categoryName']);
+
+		if(!empty($_POST['categoryCode']) && !empty($_POST['categoryName']))
+		{
+			if($action == 'add')
+			{
+				$ret=addNode($_POST['categoryCode'],$_POST['categoryName'],$_POST['canHaveCourses'],$category);
+			}
+			else
+			{
+				$ret=editNode($_POST['categoryCode'],$_POST['categoryName'],$_POST['canHaveCourses'],$_GET['id']);
+			}
+
+			if($ret)
+			{
+				$action='';
+			}
+			else
+			{
+				$errorMsg=get_lang('CatCodeAlreadyUsed');
+			}
+		}
+		else
+		{
+			$errorMsg=get_lang('PleaseEnterCategoryInfo');
+		}
+	}
+	elseif($action == 'edit')
+	{
+		$categoryCode=$_GET['id'];
+
+		$result=api_sql_query("SELECT name,auth_course_child FROM $tbl_category WHERE code='$categoryCode'",__FILE__,__LINE__);
+
+		list($categoryName,$canHaveCourses)=mysql_fetch_row($result);
+
+		$canHaveCourses=($canHaveCourses == 'FALSE')?0:1;
+	}
+	elseif($action == 'moveUp')
+	{
+		moveNodeUp($_GET['id'],$_GET['tree_pos'],$category);
+
+		header('Location: '.$_SERVER['PHP_SELF'].'?category='.$category);
+		exit();
+	}
+}
+
+$tool_name=get_lang('AdminCategories');
+
+//$interbreadcrumb[]=array("url" => "index.php","name" => get_lang('PlatformAdmin'));
+
+Display::display_header($tool_name);
+
+//api_display_tool_title($tool_name);
+
+
+if(empty($action))
+{
+	$result=api_sql_query("SELECT t1.name,t1.code,t1.parent_id,t1.tree_pos,t1.children_count,COUNT(DISTINCT t3.code) AS nbr_courses FROM $tbl_category t1 LEFT JOIN $tbl_category t2 ON t1.code=t2.parent_id LEFT JOIN $tbl_course t3 ON t3.category_code=t1.code WHERE t1.parent_id ".(empty($category)?"IS NULL":"='$category'")." GROUP BY t1.name,t1.code,t1.parent_id,t1.tree_pos,t1.children_count ORDER BY t1.tree_pos",__FILE__,__LINE__);
+
+	$Categories=api_store_result($result);
+}
+
+if(!empty($category) && empty($action))
+{
+	$result=api_sql_query("SELECT parent_id FROM $tbl_category WHERE code='$category'",__FILE__,__LINE__);
+
+	list($parent_id)=mysql_fetch_row($result);
+?>
+
+<a href="<?php echo $_SERVER['PHP_SELF']; ?>?category=<?php echo urlencode($parent_id); ?>">&lt;&lt; <?php echo get_lang("Back"); if(!empty($parent_id)) echo ' ('.$parent_id.')'; ?></a>
+
+<?php
+}
+
+if($action == 'add' || $action == 'edit')
+{
+?>
+
+<a href="<?php echo $_SERVER['PHP_SELF']; ?>?category=<?php echo urlencode($category); ?>">&lt;&lt; <?php echo get_lang("Back"); if(!empty($category)) echo ' ('.$category.')'; ?></a>
+
+<h3><?php echo ($action == 'add')?get_lang('AddACategory'):get_lang('EditNode'); if(!empty($category)) echo ' '.get_lang('Into').' '.$category; ?></h3>
+
+<form method="post" action="<?php echo $_SERVER['PHP_SELF']; ?>?action=<?php echo $action; ?>&category=<?php echo urlencode($category); ?>&amp;id=<?php echo urlencode(stripslashes($_GET['id'])); ?>">
+<input type="hidden" name="formSent" value="1" />
+<table border="0" cellpadding="5" cellspacing="0">
+
+<?php
+if(!empty($errorMsg))
+{
+?>
+
+<tr>
+  <td colspan="2">
+
+<?php
+	Display::display_normal_message($errorMsg); //main API
+?>
+
+  </td>
+</tr>
+
+<?php
+}
+?>
+
+<tr>
+  <td nowrap="nowrap"><?php echo get_lang("CategoryCode"); ?> :</td>
+  <td><input type="text" name="categoryCode" size="20" maxlength="20" value="<?php echo htmlentities(stripslashes($categoryCode)); ?>" /></td>
+</tr>
+<tr>
+  <td nowrap="nowrap"><?php echo get_lang("CategoryName"); ?> :</td>
+  <td><input type="text" name="categoryName" size="20" maxlength="100" value="<?php echo htmlentities(stripslashes($categoryName)); ?>" /></td>
+</tr>
+<tr>
+  <td nowrap="nowrap"><?php echo get_lang("AllowCoursesInCategory"); ?></td>
+  <td>
+	<input class="checkbox" type="radio" name="canHaveCourses" value="0" <?php if(($action == 'edit' && !$canHaveCourses) || ($action == 'add' && $formSent && !$canHaveCourses)) echo 'checked="checked"'; ?> /><?php echo get_lang("No"); ?>
+	<input class="checkbox" type="radio" name="canHaveCourses" value="1" <?php if(($action == 'edit' && $canHaveCourses) || ($action == 'add' && !$formSent || $canHaveCourses)) echo 'checked="checked"'; ?> /><?php echo get_lang("Yes"); ?>
+  </td>
+</tr>
+<tr>
+  <td>&nbsp;</td>
+  <td><input type="submit" value="<?php echo get_lang("Ok"); ?>" /></td>
+</tr>
+</table>
+</form>
+
+<?php
+}
+else
+{
+?>
+
+<ul>
+
+<?php
+	if(sizeof($Categories))
+	{
+		foreach($Categories as $enreg)
+		{
+?>
+
+  <li>
+	<a href="<?php echo $_SERVER['PHP_SELF']; ?>?category=<?php echo urlencode($enreg['code']); ?>"><img src="../img/opendir.gif" border="0" title="<?php echo get_lang("OpenNode"); ?>" alt="" /></a>
+	<a href="<?php echo $_SERVER['PHP_SELF']; ?>?category=<?php echo urlencode($category); ?>&amp;action=edit&amp;id=<?php echo urlencode($enreg['code']); ?>"><img src="../img/edit.gif" border="0" title="<?php echo get_lang("EditNode"); ?>" alt ="" /></a>
+	<a href="<?php echo $_SERVER['PHP_SELF']; ?>?category=<?php echo urlencode($category); ?>&amp;action=delete&amp;id=<?php echo urlencode($enreg['code']); ?>" onclick="javascript:if(!confirm('<?php echo addslashes(htmlentities(get_lang('ConfirmYourChoice'))); ?>')) return false;"><img src="../img/delete.gif" border="0" title="<?php echo get_lang("DeleteNode"); ?>" alt="" /></a>
+	<a href="<?php echo $_SERVER['PHP_SELF']; ?>?category=<?php echo urlencode($category); ?>&amp;action=moveUp&amp;id=<?php echo urlencode($enreg['code']); ?>&amp;tree_pos=<?php echo $enreg['tree_pos']; ?>"><img src="../img/up.gif" border="0" title="<?php echo get_lang("UpInSameLevel"); ?>" alt="" /></a>
+	<?php echo $enreg['name']; ?>
+	(<?php echo $enreg['children_count']; ?> <?php echo get_lang("Categories"); ?> - <?php echo $enreg['nbr_courses']; ?> <?php echo get_lang("Courses"); ?>)
+  </li>
+
+<?php
+		}
+
+		unset($Categories);
+	}
+	else
+	{
+		echo get_lang("NoCategories");
+	}
+?>
+
+</ul>
+
+<a href="<?php echo $_SERVER['PHP_SELF']; ?>?category=<?php echo $category; ?>&amp;action=add"><?php echo get_lang("AddACategory"); if(!empty($category)) echo ' '.get_lang('Into').' '.$category; ?></a>
+
+<?php
+}
+
+/*
+==============================================================================
+		FOOTER 
+==============================================================================
+*/ 
+Display::display_footer();
+
+/******** Functions ********/
+
+function deleteNode($node)
+{
+	global $tbl_category, $tbl_course;
+
+	$result=api_sql_query("SELECT parent_id,tree_pos FROM $tbl_category WHERE code='$node'",__FILE__,__LINE__);
+
+	if($row=mysql_fetch_array($result))
+	{
+		if(!empty($row['parent_id']))
+		{
+			api_sql_query("UPDATE $tbl_course SET category_code='$row[parent_id]' WHERE category_code='$node'",__FILE__,__LINE__);
+			api_sql_query("UPDATE $tbl_category SET parent_id='$row[parent_id]' WHERE parent_id='$node'",__FILE__,__LINE__);
+		}
+		else
+		{
+			api_sql_query("UPDATE $tbl_course SET category_code='' WHERE category_code='$node'",__FILE__,__LINE__);
+			api_sql_query("UPDATE $tbl_category SET parent_id=NULL WHERE parent_id='$node'",__FILE__,__LINE__);
+		}
+
+		api_sql_query("UPDATE $tbl_category SET tree_pos=tree_pos-1 WHERE tree_pos > '$row[tree_pos]'",__FILE__,__LINE__);
+		api_sql_query("DELETE FROM $tbl_category WHERE code='$node'",__FILE__,__LINE__);
+
+		if(!empty($row['parent_id']))
+		{
+			updateFils($row['parent_id']);
+		}
+	}
+}
+
+function addNode($code,$name,$canHaveCourses,$parent_id)
+{
+	global $tbl_category;
+
+	$canHaveCourses=$canHaveCourses?'TRUE':'FALSE';
+
+	$result=api_sql_query("SELECT 1 FROM $tbl_category WHERE code='$code'",__FILE__,__LINE__);
+
+	if(mysql_num_rows($result))
+	{
+		return false;
+	}
+
+	$result=api_sql_query("SELECT MAX(tree_pos) AS maxTreePos FROM $tbl_category",__FILE__,__LINE__);
+
+	$row=mysql_fetch_array($result);
+
+	$tree_pos=$row['maxTreePos']+1;
+
+	api_sql_query("INSERT INTO $tbl_category(name,code,parent_id,tree_pos,children_count,auth_course_child) VALUES('$name','$code',".(empty($parent_id)?"NULL":"'$parent_id'").",'$tree_pos','0','$canHaveCourses')",__FILE__,__LINE__);
+
+	updateFils($parent_id);
+
+	return true;
+}
+
+function editNode($code,$name,$canHaveCourses,$old_code)
+{
+	global $tbl_category;
+
+	$canHaveCourses=$canHaveCourses?'TRUE':'FALSE';
+
+	if($code != $old_code)
+	{
+		$result=api_sql_query("SELECT 1 FROM $tbl_category WHERE code='$code'",__FILE__,__LINE__);
+
+		if(mysql_num_rows($result))
+		{
+			return false;
+		}
+	}
+
+	api_sql_query("UPDATE $tbl_category SET name='$name',code='$code',auth_course_child='$canHaveCourses' WHERE code='$old_code'",__FILE__,__LINE__);
+
+	return true;
+}
+
+function moveNodeUp($code,$tree_pos,$parent_id)
+{
+	global $tbl_category;
+
+	$result=api_sql_query("SELECT code,tree_pos FROM $tbl_category WHERE parent_id ".(empty($parent_id)?"IS NULL":"='$parent_id'")." AND tree_pos<'$tree_pos' ORDER BY tree_pos DESC LIMIT 0,1",__FILE__,__LINE__);
+
+	if(!$row=mysql_fetch_array($result))
+	{
+		$result=api_sql_query("SELECT code,tree_pos FROM $tbl_category WHERE parent_id ".(empty($parent_id)?"IS NULL":"='$parent_id'")." AND tree_pos>'$tree_pos' ORDER BY tree_pos DESC LIMIT 0,1",__FILE__,__LINE__);
+
+		if(!$row=mysql_fetch_array($result))
+		{
+			return false;
+		}
+	}
+
+	api_sql_query("UPDATE $tbl_category SET tree_pos='".$row['tree_pos']."' WHERE code='$code'",__FILE__,__LINE__);
+	api_sql_query("UPDATE $tbl_category SET tree_pos='$tree_pos' WHERE code='$row[code]'",__FILE__,__LINE__);
+}
+
+function updateFils($category)
+{
+	global $tbl_category;
+
+	$result=api_sql_query("SELECT parent_id FROM $tbl_category WHERE code='$category'",__FILE__,__LINE__);
+
+	if($row=mysql_fetch_array($result))
+	{
+		updateFils($row['parent_id']);
+	}
+
+	$children_count=compterFils($category,0)-1;
+
+	api_sql_query("UPDATE $tbl_category SET children_count='$children_count' WHERE code='$category'",__FILE__,__LINE__);
+}
+
+function compterFils($pere,$cpt)
+{
+	global $tbl_category;
+
+	$result=api_sql_query("SELECT code FROM $tbl_category WHERE parent_id='$pere'",__FILE__,__LINE__);
+
+	while($row=mysql_fetch_array($result))
+	{
+		$cpt=compterFils($row['code'],$cpt);
+	}
+
+	return ($cpt+1);
+}
+?>

+ 70 - 0
main/admin/course_create_content.php

@@ -0,0 +1,70 @@
+<?php
+// $Id: course_create_content.php 9246 2006-09-25 13:24:53Z bmol $
+/*
+============================================================================== 
+	Dokeos - elearning and course management software
+	
+	Copyright (c) 2004 Dokeos S.A.
+	Copyright (c) 2003 Ghent University (UGent)
+	Copyright (c) 2001 Universite catholique de Louvain (UCL)
+	Copyright (c) Bart Mollet (bart.mollet@hogent.be)
+	
+	For a full list of contributors, see "credits.txt".
+	The full license can be read in "license.txt".
+	
+	This program is free software; you can redistribute it and/or
+	modify it under the terms of the GNU General Public License
+	as published by the Free Software Foundation; either version 2
+	of the License, or (at your option) any later version.
+	
+	See the GNU General Public License for more details.
+	
+	Contact address: Dokeos, 44 rue des palais, B-1030 Brussels, Belgium
+	Mail: info@dokeos.com
+============================================================================== 
+*/
+/**
+ * ==============================================================================
+ * This script allows a platform admin to add dummy content to a course.
+ * 
+ * @author Bart Mollet <bart.mollet@hogent.be>
+ * @package dokeos.admin
+ * ==============================================================================
+ */
+/*
+==============================================================================
+		INIT SECTION
+==============================================================================
+*/ 
+$langFile = 'admin';
+include ('../inc/global.inc.php');
+$this_section=SECTION_PLATFORM_ADMIN;
+
+api_protect_admin_script();
+$tool_name = get_lang('DummyCourseCreator');
+//$interbreadcrumb[] = array ("url" => "index.php", "name" => get_lang('PlatformAdmin'));
+Display::display_header($tool_name);
+//api_display_tool_title($tool_name);
+if( get_setting('server_type') != 'test')
+{
+	echo get_lang('DummyCourseOnlyOnTestServer');	
+}
+elseif( isset($_POST['action']))
+{
+	require_once('../coursecopy/classes/DummyCourseCreator.class.php');
+	$dcc = new DummyCourseCreator();
+	$dcc->create_dummy_course($_POST['course_code']);
+	echo get_lang('Done');
+}
+else
+{
+	echo get_lang('DummyCourseDescription');
+	echo '<form method="post"><input type="hidden" name="course_code" value="'.$_GET['course_code'].'"/><input type="submit" name="action" value="'.get_lang('Ok').'"/></form>';
+}
+/*
+==============================================================================
+		FOOTER 
+==============================================================================
+*/
+Display::display_footer();
+?>

+ 159 - 0
main/admin/course_edit.php

@@ -0,0 +1,159 @@
+<?php
+
+// $Id: course_edit.php 9246 2006-09-25 13:24:53Z bmol $
+/*
+==============================================================================
+	Dokeos - elearning and course management software
+
+	Copyright (c) 2004 Dokeos S.A.
+	Copyright (c) 2003 Ghent University (UGent)
+	Copyright (c) 2001 Universite catholique de Louvain (UCL)
+	Copyright (c) Olivier Brouckaert
+	Copyright (c) Bart Mollet, Hogeschool Gent
+
+	For a full list of contributors, see "credits.txt".
+	The full license can be read in "license.txt".
+
+	This program is free software; you can redistribute it and/or
+	modify it under the terms of the GNU General Public License
+	as published by the Free Software Foundation; either version 2
+	of the License, or (at your option) any later version.
+
+	See the GNU General Public License for more details.
+
+	Contact: Dokeos, 181 rue Royale, B-1000 Brussels, Belgium, info@dokeos.com
+==============================================================================
+*/
+/**
+==============================================================================
+*	@package dokeos.admin
+==============================================================================
+*/
+/*
+==============================================================================
+		INIT SECTION
+==============================================================================
+*/
+$langFile = 'admin';
+$cidReset = true;
+include ('../inc/global.inc.php');
+$this_section=SECTION_PLATFORM_ADMIN;
+
+api_protect_admin_script();
+include (api_get_path(LIBRARY_PATH).'fileManage.lib.php');
+require_once (api_get_path(LIBRARY_PATH).'formvalidator/FormValidator.class.php');
+$course_table = Database::get_main_table(MAIN_COURSE_TABLE);
+$course_code = isset($_GET['course_code']) ? $_GET['course_code'] : $_POST['code'];
+$noPHP_SELF = true;
+$tool_name = get_lang('ModifyCourseInfo');
+//$interbreadcrumb[] = array ("url" => "index.php", "name" => get_lang('PlatformAdmin'));
+$interbreadcrumb[] = array ("url" => "course_list.php", "name" => get_lang('AdminCourses'));
+/*
+-----------------------------------------------------------
+	Libraries
+-----------------------------------------------------------
+*/
+/*
+==============================================================================
+		FUNCTIONS
+==============================================================================
+*/
+
+/*
+==============================================================================
+		MAIN CODE
+==============================================================================
+*/
+// Get all course categories
+$table_course_category = Database :: get_main_table(MAIN_CATEGORY_TABLE);
+$sql = "SELECT code,name FROM ".$table_course_category." WHERE auth_course_child ='TRUE' ORDER BY tree_pos";
+$res = api_sql_query($sql, __FILE__, __LINE__);
+while ($cat = mysql_fetch_array($res))
+{
+	$categories[$cat['code']] = '('.$cat['code'].') '.$cat['name'];
+}
+
+// Build the form
+$form = new FormValidator('update_course');
+$form->addElement('hidden','code',$course_code);
+$form->add_textfield('visual_code', get_lang('CourseCode'));
+$form->applyFilter('visual_code','strtoupper');
+$form->add_textfield('tutor_name', get_lang('CourseTitular'));
+$form->add_textfield( 'title', get_lang('Title'),true, array ('size' => '60'));
+$form->addElement('select', 'category_code', get_lang('CourseFaculty'), $categories);
+$form->add_textfield( 'department_name', get_lang('CourseDepartment'), false,array ('size' => '60'));
+$form->add_textfield( 'department_url', get_lang('CourseDepartmentURL'),false, array ('size' => '60'));
+$form->addElement('select_language', 'course_language', get_lang('CourseLanguage'));
+$form->addElement('radio', 'visibility', get_lang("CourseAccess"), get_lang('OpenToTheWorld'), COURSE_VISIBILITY_OPEN_WORLD);
+$form->addElement('radio', 'visibility', null, get_lang('OpenToThePlatform'), COURSE_VISIBILITY_OPEN_PLATFORM);
+$form->addElement('radio', 'visibility', null, get_lang('Private'), COURSE_VISIBILITY_REGISTERED);
+$form->addElement('radio', 'visibility', null, get_lang('CourseVisibilityClosed'), COURSE_VISIBILITY_CLOSED);
+$form->addElement('radio', 'subscribe', get_lang('Subscription'), get_lang('Allowed'), 1);
+$form->addElement('radio', 'subscribe', null, get_lang('Denied'), 0);
+$form->addElement('radio', 'unsubscribe', get_lang('Unsubscription'), get_lang('AllowedToUnsubscribe'), 1);
+$form->addElement('radio', 'unsubscribe', null, get_lang('NotAllowedToUnsubscribe'), 0);
+$form->addElement('text','disk_quota',get_lang('CourseQuota'));
+$form->addRule('disk_quota', get_lang('ThisFieldIsRequired'),'required');
+$form->addRule('disk_quota',get_lang('ThisFieldShouldBeNumeric'),'numeric');
+$form->addElement('submit', null, get_lang('Ok'));
+// Set some default values
+$sql = "SELECT * FROM $course_table WHERE code='".mysql_real_escape_string($course_code)."'";
+$result = api_sql_query($sql, __FILE__, __LINE__);
+if (mysql_num_rows($result) != 1)
+{
+	header('Location: course_list.php');
+	exit ();
+}
+$course = mysql_fetch_array($result,MYSQL_ASSOC);
+$course_db_name = $course['db_name'];
+$form->setDefaults($course);
+// Validate form
+if( $form->validate())
+{
+	$course = $form->exportValues();
+	$dbName = $_POST['dbName'];
+	$course_code = $course['code'];
+	$visual_code = $course['visual_code'];
+	$tutor_name = $course['tutor_name'];
+	$title = $course['title'];
+	$category_code = $course['category_code'];
+	$department_name = $course['department_name'];
+	$department_url = $course['department_url'];
+	$course_language = $course['course_language'];
+	$disk_quota = $course['disk_quota'];
+	$visibility = $course['visibility'];
+	$subscribe = $course['subscribe'];
+	$unsubscribe = $course['unsubscribe'];
+	if (!stristr($department_url, 'http://'))
+	{
+		$department_url = 'http://'.$department_url;
+	}
+	$sql = "UPDATE $course_table SET course_language='".mysql_real_escape_string($course_language)."',
+								title='".mysql_real_escape_string($title)."',
+								category_code='".mysql_real_escape_string($category_code)."',
+								tutor_name='".mysql_real_escape_string($tutor_name)."',
+								visual_code='".mysql_real_escape_string($visual_code)."',
+								department_name='".mysql_real_escape_string($department_name)."',
+								department_url='".mysql_real_escape_string($department_url)."',
+								disk_quota='".mysql_real_escape_string($disk_quota)."',
+								visibility = '".mysql_real_escape_string($visibility)."', 
+								subscribe = '".mysql_real_escape_string($subscribe)."',
+								unsubscribe='".mysql_real_escape_string($unsubscribe)."'
+							WHERE code='".mysql_real_escape_string($course_code)."'";
+	api_sql_query($sql, __FILE__, __LINE__);
+	$forum_config_table = Database::get_course_table(FORUM_CONFIG_TABLE,$course_db_name);
+	$sql = "UPDATE ".$forum_config_table." SET default_lang='".mysql_real_escape_string($course_language)."'";
+	header('Location: course_list.php');
+	exit ();
+}
+Display::display_header($tool_name);
+//api_display_tool_title($tool_name);
+// Display the form
+$form->display();
+/*
+==============================================================================
+		FOOTER 
+==============================================================================
+*/
+Display :: display_footer();
+?>

+ 216 - 0
main/admin/course_import.php

@@ -0,0 +1,216 @@
+<?php
+
+// $Id: course_import.php 8216 2006-03-15 16:33:13Z turboke $
+/*
+==============================================================================
+	Dokeos - elearning and course management software
+
+	Copyright (c) 2005 Bart Mollet <bart.mollet@hogent.be>
+
+	For a full list of contributors, see "credits.txt".
+	The full license can be read in "license.txt".
+
+	This program is free software; you can redistribute it and/or
+	modify it under the terms of the GNU General Public License
+	as published by the Free Software Foundation; either version 2
+	of the License, or (at your option) any later version.
+
+	See the GNU General Public License for more details.
+
+	Contact: Dokeos, 181 rue Royale, B-1000 Brussels, Belgium, info@dokeos.com
+==============================================================================
+*/
+/**
+==============================================================================
+* This tool allows platform admins to create courses by uploading a CSV file
+* @todo Add some langvars to DLTT
+* @package dokeos.admin
+==============================================================================
+*/
+/**
+ * validate the imported data
+ */
+function validate_data($courses)
+{
+	$errors = array ();
+	$coursecodes = array ();
+	foreach ($courses as $index => $course)
+	{
+		$course['line'] = $index +1;
+		//1. check if mandatory fields are set
+		$mandatory_fields = array ('Code', 'Title', 'CourseCategory', 'Teacher');
+		foreach ($mandatory_fields as $key => $field)
+		{
+			if (!isset ($course[$field]) || strlen($course[$field]) == 0)
+			{
+				$course['error'] = get_lang($field.'Mandatory');
+				$errors[] = $course;
+			}
+		}
+		//2. check if code isn't in use
+		if (isset ($course['Code']) && strlen($course['Code']) != 0)
+		{
+			//2.1 check if code allready used in this CVS-file
+			if (isset ($coursecodes[$course['Code']]))
+			{
+				$course['error'] = get_lang('CodeTwiceInFile');
+				$errors[] = $course;
+			}
+			elseif(strlen($course['Code']) > 20)
+			{
+				$course['error'] = get_lang('Max');
+				$errors[] = $course;
+			}
+			//2.3 check if code allready used in DB
+			else
+			{
+				$course_table = Database :: get_main_table(MAIN_COURSE_TABLE);
+				$sql = "SELECT * FROM $course_table WHERE code = '".mysql_real_escape_string($course['Code'])."'";
+				$res = api_sql_query($sql, __FILE__, __LINE__);
+				if (mysql_num_rows($res) > 0)
+				{
+					$course['error'] = get_lang('CodeExists');
+					$errors[] = $course;
+				}
+			}
+			$coursecodes[$course['Code']] = 1;
+		}
+		//3. check if teacher exists
+		if (isset ($course['Teacher']) && strlen($course['Teacher']) != 0)
+		{
+			if (UserManager :: is_username_available($course['Teacher']))
+			{
+				$course['error'] = get_lang('UnknownTeacher');
+				$errors[] = $course;
+			}
+		}
+		//4. check if category exists
+		if (isset ($course['CourseCategory']) && strlen($course['CourseCategory']) != 0)
+		{
+			$category_table = Database :: get_main_table(MAIN_CATEGORY_TABLE);
+			$sql = "SELECT * FROM $category_table WHERE code = '".mysql_real_escape_string($course['CourseCategory'])."'";
+			$res = api_sql_query($sql, __FILE__, __LINE__);
+			if (mysql_num_rows($res) == 0)
+			{
+				$course['error'] = get_lang('UnkownCategory');
+				$errors[] = $course;
+			}
+		}
+	}
+	return $errors;
+}
+
+/**
+ * Save the imported data
+ */
+function save_data($courses)
+{
+	global $dbNamePrefix,$firstExpirationDelay;
+	foreach($courses as $index => $course)
+	{
+		$keys = define_course_keys($course['Code'], "", $dbNamePrefix);
+		$user_table = Database::get_main_table(MAIN_USER_TABLE);
+		$sql = "SELECT user_id, CONCAT(lastname,' ',firstname) AS name FROM $user_table WHERE username = '".mysql_real_escape_string($course['Teacher'])."'";
+		$res = api_sql_query($sql,__FILE__,__LINE__);
+		$teacher = mysql_fetch_object($res);
+		$visual_code = $keys["currentCourseCode"];
+		$code = $keys["currentCourseId"];
+		$db_name = $keys["currentCourseDbName"];
+		$directory = $keys["currentCourseRepository"];
+		$expiration_date = time() + $firstExpirationDelay;
+		prepare_course_repository($directory, $code);
+		update_Db_course($db_name);
+		fill_course_repository($directory);
+		fill_Db_course($db_name, $directory, api_get_setting('platformLanguage'));
+		register_course($code, $visual_code, $directory, $db_name, $teacher->name, $course['CourseCategory'], $course['Title'], api_get_setting('platformLanguage'), $teacher->user_id, $expiration_date);
+		echo $code.' CREATED<br />';
+	}
+}
+/**
+ * Read the CSV-file
+ * @param string $file Path to the CSV-file
+ * @return array All course-information read from the file
+ */
+function parse_csv_data($file)
+{
+	$courses = Import :: csv_to_array($file);
+	return $courses;
+}
+
+$langFile = array ('admin', 'registration','create_course');
+
+$cidReset = true;
+
+include ('../inc/global.inc.php');
+api_protect_admin_script();
+require_once (api_get_path(LIBRARY_PATH).'fileManage.lib.php');
+require_once (api_get_path(LIBRARY_PATH).'import.lib.php');
+require_once (api_get_path(LIBRARY_PATH).'usermanager.lib.php');
+require_once (api_get_path(CONFIGURATION_PATH).'add_course.conf.php');
+require_once (api_get_path(LIBRARY_PATH).'add_course.lib.inc.php');
+$formSent = 0;
+$errorMsg = '';
+$defined_auth_sources[] = PLATFORM_AUTH_SOURCE;
+if (is_array($extAuthSource))
+{
+	$defined_auth_sources = array_merge($defined_auth_sources, array_keys($extAuthSource));
+}
+
+$tool_name = get_lang('AddCourse').' CSV';
+
+$interbredcrump[] = array ('url' => 'index.php', 'name' => get_lang('PlatformAdmin'));
+
+set_time_limit(0);
+Display :: display_header($tool_name);
+api_display_tool_title($tool_name);
+if ($_POST['formSent'])
+{
+	$file_type = $_POST['file_type'];
+	$courses = parse_csv_data($_FILES['import_file']['tmp_name']);
+	$errors = validate_data($courses);
+	if (count($errors) == 0)
+	{
+		//$users = complete_missing_data($courses);
+		save_data($courses);
+		//header('Location: user_list.php?action=show_message&message='.urlencode(get_lang('FileImported')));
+		//exit ();
+	}
+}
+
+if (count($errors) != 0)
+{
+	$error_message = '<ul>';
+	foreach ($errors as $index => $error_course)
+	{
+		$error_message .= '<li>'.get_lang('Line').' '.$error_course['line'].': <b>'.$error_course['error'].'</b>: ';
+		$error_message .= $error_course['Code'].' '.$error_course['Title'];
+		$error_message .= '</li>';
+	}
+	$error_message .= '</ul>';
+	Display :: display_error_message($error_message);
+}
+?>
+<form method="post" action="<?php echo $_SERVER['PHP_SELF']; ?>" enctype="multipart/form-data" style="margin:0px;">
+<input type="file" name="import_file"/>
+<input type="hidden" name="formSent" value="1"/>
+<input type="submit" value="<?php echo get_lang('Ok'); ?>"/>
+</form>
+<p><?php echo get_lang('CSVMustLookLike').' ('.get_lang('MandatoryFields').')'; ?> :</p>
+
+<blockquote>
+<pre>
+<b>Code</b>;<b>Title</b>;<b>CourseCategory</b>;<b>Teacher</b>
+BIO0015;Biology;BIO;username
+</pre>
+</blockquote>
+
+<?php
+
+
+/*
+==============================================================================
+		FOOTER
+==============================================================================
+*/
+Display :: display_footer();
+?>

+ 193 - 0
main/admin/course_information.php

@@ -0,0 +1,193 @@
+<?php
+// $Id: course_information.php 9246 2006-09-25 13:24:53Z bmol $
+/*
+==============================================================================
+	Dokeos - elearning and course management software
+
+	Copyright (c) 2004 Dokeos S.A.
+	Copyright (c) 2003 Ghent University (UGent)
+	Copyright (c) 2001 Universite catholique de Louvain (UCL)
+	Copyright (c) Olivier Brouckaert
+
+	For a full list of contributors, see "credits.txt".
+	The full license can be read in "license.txt".
+
+	This program is free software; you can redistribute it and/or
+	modify it under the terms of the GNU General Public License
+	as published by the Free Software Foundation; either version 2
+	of the License, or (at your option) any later version.
+
+	See the GNU General Public License for more details.
+
+	Contact: Dokeos, 181 rue Royale, B-1000 Brussels, Belgium, info@dokeos.com
+==============================================================================
+*/
+/**
+============================================================================== 
+	@author Bart Mollet
+*	@package dokeos.admin
+============================================================================== 
+*/
+/*
+==============================================================================
+		INIT SECTION
+==============================================================================
+*/
+$langFile = 'admin';
+$cidReset = true;
+require ('../inc/global.inc.php');
+require_once(api_get_path(LIBRARY_PATH).'sortabletable.class.php');
+$this_section=SECTION_PLATFORM_ADMIN;
+
+api_protect_admin_script();
+/**
+ * 
+ */
+function get_course_usage($course_code)
+{
+	$table = Database::get_main_table(MAIN_COURSE_TABLE);
+	$sql = "SELECT * FROM $table WHERE code='".$course_code."'";
+	$res = api_sql_query($sql,__FILE__,__LINE__);
+	$course = mysql_fetch_object($res);
+	// Learnpaths
+	$table = Database :: get_course_table(LEARNPATH_MAIN_TABLE, $course->db_name);
+	$usage[] = array (get_lang(TOOL_LEARNPATH), Database::count_rows($table));
+	// Forums
+	$table = Database :: get_course_table(FORUM_TABLE, $course->db_name);
+	$usage[] = array (get_lang(TOOL_BB_FORUM), Database::count_rows($table));
+	// Quizzes
+	$table = Database :: get_course_table(QUIZ_TEST_TABLE, $course->db_name);
+	$usage[] = array (get_lang(TOOL_QUIZ), Database::count_rows($table));
+	// Documents
+	$table = Database :: get_course_table(DOCUMENT_TABLE, $course->db_name);
+	$usage[] = array (get_lang(TOOL_DOCUMENT), Database::count_rows($table));
+	// Groups
+	$table = Database :: get_course_table(GROUP_TABLE, $course->db_name);
+	$usage[] = array (get_lang(TOOL_GROUP), Database::count_rows($table));
+	// Calendar
+	$table = Database :: get_course_table(AGENDA_TABLE, $course->db_name);
+	$usage[] = array (get_lang(TOOL_CALENDAR_EVENT), Database::count_rows($table));
+	// Link
+	$table = Database::get_course_table(LINK_TABLE, $course->db_name);
+	$usage[] = array(get_lang(TOOL_LINK), Database::count_rows($table));
+	// Announcements
+	$table = Database::get_course_table(ANNOUNCEMENT_TABLE, $course->db_name);
+	$usage[] = array(get_lang(TOOL_ANNOUNCEMENT), Database::count_rows($table));
+	return $usage;
+}
+/*****************************************************************/
+if (!isset ($_GET['code']))
+{
+	api_not_allowed();
+}
+//$interbreadcrumb[] = array ("url" => "index.php", "name" => get_lang('PlatformAdmin'));
+$interbreadcrumb[] = array ("url" => 'course_list.php', "name" => get_lang('Courses'));
+$table_course = Database :: get_main_table(MAIN_COURSE_TABLE);
+$code = $_GET['code'];
+$sql = "SELECT * FROM $table_course WHERE code = '".$code."'";
+$res = api_sql_query($sql,__FILE__,__LINE__);
+$course = mysql_fetch_object($res);
+$tool_name = $course->title.' ('.$course->code.')';
+Display::display_header($tool_name);
+//api_display_tool_title($tool_name);
+?>
+<p>
+<a href="<?php echo api_get_path(WEB_COURSE_PATH).$course->directory; ?>"><img src="../img/home_small.gif" border="0" /> <?php echo api_get_path(WEB_COURSE_PATH).$course->directory; ?></a>
+<br/>
+<?php
+if( get_setting('server_type') == 'test')
+{
+	?>
+	<a href="course_create_content.php?course_code=<?php echo $course->code ?>"><?php echo get_lang('AddDummyContentToCourse') ?></a>
+	<?php
+}
+?>
+</p>
+<?php
+
+echo '<h4>'.get_lang('CourseUsage').'</h4>';
+echo '<blockquote>';
+$table = new SortableTableFromArray(get_course_usage($course->code),0,20,'usage_table');
+$table->set_additional_parameters(array ('code' => $_GET['code']));
+$table->set_other_tables(array('user_table','class_table'));
+$table->set_header(0,get_lang('Tool'), true);
+$table->set_header(1,get_lang('NumberOfItems'), true);
+$table->display();
+echo '</blockquote>';
+/**
+ * Show all users subscribed in this course
+ */
+echo '<h4>'.get_lang('Users').'</h4>';
+echo '<blockquote>';
+$table_course_user = Database :: get_main_table(MAIN_COURSE_USER_TABLE);
+$table_user = Database :: get_main_table(MAIN_USER_TABLE);
+$sql = 'SELECT *,cu.status as course_status FROM '.$table_course_user.' cu, '.$table_user." u WHERE cu.user_id = u.user_id AND cu.course_code = '".$code."' ";
+$res = api_sql_query($sql,__FILE__,__LINE__);
+if (mysql_num_rows($res) > 0)
+{
+	$users = array ();
+	while ($obj = mysql_fetch_object($res))
+	{
+		$user = array ();
+		$user[] = $obj->official_code;
+		$user[] = $obj->firstname;
+		$user[] = $obj->lastname;
+		$user[] = Display :: encrypted_mailto_link($obj->email, $obj->email);
+		$user[] = $obj->course_status == 5 ? get_lang('Student') : get_lang('Teacher');
+		$user[] = '<a href="user_information.php?user_id='.$obj->user_id.'"><img src="../img/info_small.gif" border="0" /></a>';
+		$users[] = $user;
+	}
+	$table = new SortableTableFromArray($users,0,20,'user_table');
+	$table->set_additional_parameters(array ('code' => $_GET['code']));
+	$table->set_other_tables(array('usage_table','class_table'));
+	$table->set_header(0,get_lang('OfficialCode'), true);
+	$table->set_header(1,get_lang('FirstName'), true);
+	$table->set_header(2,get_lang('LastName'), true);
+	$table->set_header(3,get_lang('Email'), true);
+	$table->set_header(4,get_lang('Status'), true);
+	$table->set_header(5,'', false);
+	$table->display();
+}
+else
+{
+	echo get_lang('NoUsersInCourse');
+}
+echo '</blockquote>';
+/**
+ * Show all classes subscribed in this course
+ */
+$table_course_class = Database :: get_main_table(MAIN_COURSE_CLASS_TABLE);
+$table_class = Database :: get_main_table(MAIN_CLASS_TABLE);
+$sql = 'SELECT * FROM '.$table_course_class.' cc, '.$table_class.' c WHERE cc.class_id = c.id AND cc.course_code = '."'".$_GET['code']."'";
+$res = api_sql_query($sql,__FILE__,__LINE__);
+if (mysql_num_rows($res) > 0)
+{
+	$data = array ();
+	while ($class = mysql_fetch_object($res))
+	{
+		$row = array ();
+		$row[] = $class->name;
+		$row[] = '<a href="class_information.php?id='.$class->id.'"><img src="../img/info_small.gif" border="0" /></a>';
+		$data[] = $row;
+	}
+	echo '<p><b>'.get_lang('AdminClasses').'</b></p>';
+	echo '<blockquote>';
+	$table = new SortableTableFromArray($data,0,20,'class_table');
+	$table->set_additional_parameters(array ('code' => $_GET['code']));
+	$table->set_other_tables(array('usage_table','user_table'));
+	$table->set_header(0,get_lang('Title'));
+	$table->set_header(1,'');
+	$table->display();
+	echo '</blockquote>';
+}
+else
+{
+	echo '<p>'.get_lang('NoClassesForThisCourse').'</p>';
+}
+/*
+==============================================================================
+		FOOTER 
+==============================================================================
+*/ 
+Display::display_footer();
+?>

+ 217 - 0
main/admin/course_list.php

@@ -0,0 +1,217 @@
+<?php
+// $Id: course_list.php 9246 2006-09-25 13:24:53Z bmol $
+/*
+==============================================================================
+	Dokeos - elearning and course management software
+
+	Copyright (c) 2004 Dokeos S.A.
+	Copyright (c) 2003 Ghent University (UGent)
+	Copyright (c) 2001 Universite catholique de Louvain (UCL)
+	Copyright (c) Olivier Brouckaert
+	Copyright (c) Bart Mollet, Hogeschool Gent
+
+	For a full list of contributors, see "credits.txt".
+	The full license can be read in "license.txt".
+
+	This program is free software; you can redistribute it and/or
+	modify it under the terms of the GNU General Public License
+	as published by the Free Software Foundation; either version 2
+	of the License, or (at your option) any later version.
+
+	See the GNU General Public License for more details.
+
+	Contact: Dokeos, 181 rue Royale, B-1000 Brussels, Belgium, info@dokeos.com
+==============================================================================
+*/
+/**
+==============================================================================
+*	@package dokeos.admin
+============================================================================== 
+*/
+/*
+==============================================================================
+		INIT SECTION
+==============================================================================
+*/
+$langFile = 'admin';
+$cidReset = true;
+require ('../inc/global.inc.php');
+$this_section = SECTION_PLATFORM_ADMIN;
+
+api_protect_admin_script();
+require_once (api_get_path(LIBRARY_PATH)."course.lib.php");
+require_once (api_get_path(LIBRARY_PATH).'formvalidator/FormValidator.class.php');
+require_once (api_get_path(LIBRARY_PATH).'sortabletable.class.php');
+/**
+ * Get the number of courses which will be displayed
+ */
+function get_number_of_courses()
+{
+	$course_table = Database :: get_main_table(MAIN_COURSE_TABLE);
+	$sql = "SELECT COUNT(code) AS total_number_of_items FROM $course_table";
+	if (isset ($_GET['keyword']))
+	{
+		$keyword = mysql_real_escape_string($_GET['keyword']);
+		$sql .= " WHERE title LIKE '%".$keyword."%' OR code LIKE '%".$keyword."%'";
+	}
+	elseif (isset ($_GET['keyword_code']))
+	{
+		$keyword_code = mysql_real_escape_string($_GET['keyword_code']);
+		$keyword_title = mysql_real_escape_string($_GET['keyword_title']);
+		$keyword_category = mysql_real_escape_string($_GET['keyword_category']);
+		$keyword_language = mysql_real_escape_string($_GET['keyword_language']);
+		$keyword_visibility = mysql_real_escape_string($_GET['keyword_visibility']);
+		$keyword_subscribe = mysql_real_escape_string($_GET['keyword_subscribe']);
+		$keyword_unsubscribe = mysql_real_escape_string($_GET['keyword_unsubscribe']);
+		$sql .= " WHERE code LIKE '%".$keyword_code."%' AND title LIKE '%".$keyword_title."%' AND category_code LIKE '%".$keyword_category."%'  AND course_language LIKE '%".$keyword_language."%'   AND visibility LIKE '%".$keyword_visibility."%'    AND subscribe LIKE '".$keyword_subscribe."'AND unsubscribe LIKE '".$keyword_unsubscribe."'";
+	}
+	$res = api_sql_query($sql, __FILE__, __LINE__);
+	$obj = mysql_fetch_object($res);
+	return $obj->total_number_of_items;
+}
+/**
+ * Get course data to display
+ */
+function get_course_data($from, $number_of_items, $column, $direction)
+{
+	$course_table = Database :: get_main_table(MAIN_COURSE_TABLE);
+	$sql = "SELECT code AS col0, visual_code AS col1, title AS col2, course_language AS col3, category_code AS col4, subscribe AS col5, unsubscribe AS col6, code AS col7, code AS col8 FROM $course_table";
+	if (isset ($_GET['keyword']))
+	{
+		$keyword = mysql_real_escape_string($_GET['keyword']);
+		$sql .= " WHERE title LIKE '%".$keyword."%' OR code LIKE '%".$keyword."%'";
+	}
+	elseif (isset ($_GET['keyword_code']))
+	{
+		$keyword_code = mysql_real_escape_string($_GET['keyword_code']);
+		$keyword_title = mysql_real_escape_string($_GET['keyword_title']);
+		$keyword_category = mysql_real_escape_string($_GET['keyword_category']);
+		$keyword_language = mysql_real_escape_string($_GET['keyword_language']);
+		$keyword_visibility = mysql_real_escape_string($_GET['keyword_visibility']);
+		$keyword_subscribe = mysql_real_escape_string($_GET['keyword_subscribe']);
+		$keyword_unsubscribe = mysql_real_escape_string($_GET['keyword_unsubscribe']);
+		$sql .= " WHERE code LIKE '%".$keyword_code."%' AND title LIKE '%".$keyword_title."%' AND category_code LIKE '%".$keyword_category."%'  AND course_language LIKE '%".$keyword_language."%'   AND visibility LIKE '%".$keyword_visibility."%'    AND subscribe LIKE '".$keyword_subscribe."'AND unsubscribe LIKE '".$keyword_unsubscribe."'";
+	}
+	$sql .= " ORDER BY col$column $direction ";
+	$sql .= " LIMIT $from,$number_of_items";
+	$res = api_sql_query($sql, __FILE__, __LINE__);
+	$courses = array ();
+	while ($course = mysql_fetch_row($res))
+	{
+		$course[5] = $course[5] == SUBSCRIBE_ALLOWED ? get_lang('Yes') : get_lang('No');
+		$course[6] = $course[6] == UNSUBSCRIBE_ALLOWED ? get_lang('Yes') : get_lang('No');
+		$course[7] = CourseManager :: is_virtual_course_from_system_code($course[7]) ? get_lang('Yes') : get_lang('No');
+		$courses[] = $course;
+	}
+	return $courses;
+}
+/**
+ * Filter to display the edit-buttons
+ */
+function modify_filter($code)
+{
+	return
+		'<a href="course_information.php?code='.$code.'"><img src="../img/info_small.gif" border="0" style="vertical-align: middle" title="'.get_lang('Info').'" alt="'.get_lang('Info').'"/></a>'.
+		'<a href="../course_home/course_home.php?cidReq='.$code.'"><img src="../img/home_small.gif" border="0" style="vertical-align: middle" title="'.get_lang('CourseHomepage').'" alt="'.get_lang('CourseHomepage').'"/></a>'.
+		'<a href="course_edit.php?course_code='.$code.'"><img src="../img/edit.gif" border="0" style="vertical-align: middle" title="'.get_lang('Edit').'" alt="'.get_lang('Edit').'"/></a>'.
+		'<a href="course_list.php?delete_course='.$code.'"  onclick="javascript:if(!confirm('."'".addslashes(htmlentities(get_lang("ConfirmYourChoice")))."'".')) return false;"><img src="../img/delete.gif" border="0" style="vertical-align: middle" title="'.get_lang('Delete').'" alt="'.get_lang('Delete').'"/></a>';	
+}
+if (isset ($_POST['action']))
+{
+	switch ($_POST['action'])
+	{
+		// Delete selected courses
+		case 'delete_courses' :
+			$course_codes = $_POST['course'];
+			if (count($course_codes) > 0)
+			{
+				foreach ($course_codes as $index => $course_code)
+				{
+					CourseManager :: delete_course($course_code);
+				}
+			}
+			break;
+	}
+}
+if (isset ($_GET['search']) && $_GET['search'] == 'advanced')
+{
+	// Get all course categories
+	$table_course_category = Database :: get_main_table(MAIN_CATEGORY_TABLE);
+	$sql = "SELECT code,name FROM ".$table_course_category." WHERE auth_course_child ='TRUE' ORDER BY tree_pos";
+	$res = api_sql_query($sql, __FILE__, __LINE__);
+	$categories['%'] = get_lang('All');
+	while ($cat = mysql_fetch_array($res))
+	{
+		$categories[$cat['code']] = '('.$cat['code'].') '.$cat['name'];
+	}
+	//$interbreadcrumb[] = array ("url" => "index.php", "name" => get_lang('PlatformAdmin'));
+	$interbreadcrumb[] = array ("url" => 'course_list.php', "name" => get_lang('CourseList'));
+	$tool_name = get_lang('SearchACourse');
+	Display :: display_header($tool_name);
+	//api_display_tool_title($tool_name);
+	$form = new FormValidator('advanced_course_search', 'get');
+	$form->add_textfield('keyword_code', get_lang('CourseCode'), false);
+	$form->add_textfield('keyword_title', get_lang('Title'), false);
+	$form->addElement('select', 'keyword_category', get_lang('CourseFaculty'), $categories);
+	$el = & $form->addElement('select_language', 'keyword_language', get_lang('CourseLanguage'));
+	$el->addOption(get_lang('All'), '%');
+	$form->addElement('radio', 'keyword_visibility', get_lang("CourseAccess"), get_lang('OpenToTheWorld'), COURSE_VISIBILITY_OPEN_WORLD);
+	$form->addElement('radio', 'keyword_visibility', null, get_lang('OpenToThePlatform'), COURSE_VISIBILITY_OPEN_PLATFORM);
+	$form->addElement('radio', 'keyword_visibility', null, get_lang('Private'), COURSE_VISIBILITY_REGISTERED);
+	$form->addElement('radio', 'keyword_visibility', null, get_lang('CourseVisibilityClosed'), COURSE_VISIBILITY_CLOSED);
+	$form->addElement('radio', 'keyword_visibility', null, get_lang('All'), '%');
+	$form->addElement('radio', 'keyword_subscribe', get_lang('Subscription'), get_lang('Allowed'), 1);
+	$form->addElement('radio', 'keyword_subscribe', null, get_lang('Denied'), 0);
+	$form->addElement('radio', 'keyword_subscribe', null, get_lang('All'), '%');
+	$form->addElement('radio', 'keyword_unsubscribe', get_lang('Unsubscription'), get_lang('AllowedToUnsubscribe'), 1);
+	$form->addElement('radio', 'keyword_unsubscribe', null, get_lang('NotAllowedToUnsubscribe'), 0);
+	$form->addElement('radio', 'keyword_unsubscribe', null, get_lang('All'), '%');
+	$form->addElement('submit', 'submit', get_lang('Ok'));
+	$defaults['keyword_language'] = '%';
+	$defaults['keyword_visibility'] = '%';
+	$defaults['keyword_subscribe'] = '%';
+	$defaults['keyword_unsubscribe'] = '%';
+	$form->setDefaults($defaults);
+	$form->display();
+}
+else
+{
+	//$interbreadcrumb[] = array ("url" => "index.php", "name" => get_lang('PlatformAdmin'));
+	$tool_name = get_lang('CourseList');
+	Display :: display_header($tool_name);
+	//api_display_tool_title($tool_name);
+	if (isset ($_GET['delete_course']))
+	{
+		CourseManager :: delete_course($_GET['delete_course']);
+	}
+	// Create a search-box
+	$form = new FormValidator('search_simple','get','','',null,false);
+	$renderer =& $form->defaultRenderer();
+	$renderer->setElementTemplate('<span>{element}</span> ');
+	$form->addElement('text','keyword',get_lang('keyword'));
+	$form->addElement('submit','submit',get_lang('Search'));
+	$form->addElement('static','search_advanced_link',null,'<a href="course_list.php?search=advanced">'.get_lang('AdvancedSearch').'</a>');
+	$form->display();
+	// Create a sortable table with the course data
+	$table = new SortableTable('courses', 'get_number_of_courses', 'get_course_data',2);
+	$table->set_additional_parameters($parameters);
+	$table->set_header(0, '', false);
+	$table->set_header(1, get_lang('Code'));
+	$table->set_header(2, get_lang('Title'));
+	$table->set_header(3, get_lang('Language'));
+	$table->set_header(4, get_lang('Category'));
+	$table->set_header(5, get_lang('SubscriptionAllowed'));
+	$table->set_header(6, get_lang('UnsubscriptionAllowed'));
+	$table->set_header(7, get_lang('IsVirtualCourse'));
+	$table->set_header(8, '', false);
+	$table->set_column_filter(8,'modify_filter');
+	$table->set_form_actions(array ('delete_courses' => get_lang('DeleteCourse')),'course');
+	$table->display();
+}
+/*
+==============================================================================
+		FOOTER 
+==============================================================================
+*/
+Display :: display_footer();
+?>

+ 232 - 0
main/admin/course_user_import.php

@@ -0,0 +1,232 @@
+<?php
+// $Id: course_user_import.php 8216 2006-03-15 16:33:13Z turboke $
+/*
+==============================================================================
+	Dokeos - elearning and course management software
+
+	Copyright (c) 2005 Bart Mollet <bart.mollet@hogent.be>
+
+	For a full list of contributors, see "credits.txt".
+	The full license can be read in "license.txt".
+
+	This program is free software; you can redistribute it and/or
+	modify it under the terms of the GNU General Public License
+	as published by the Free Software Foundation; either version 2
+	of the License, or (at your option) any later version.
+
+	See the GNU General Public License for more details.
+
+	Contact: Dokeos, 181 rue Royale, B-1000 Brussels, Belgium, info@dokeos.com
+==============================================================================
+*/
+/**
+==============================================================================
+* This tool allows platform admins to update course-user relations by uploading
+* a CSVfile
+* @package dokeos.admin
+==============================================================================
+*/
+/**
+ * validate the imported data
+ */
+function validate_data($users_courses)
+{
+	$errors = array ();
+	$coursecodes = array ();
+	foreach ($users_courses as $index => $user_course)
+	{
+		$user_course['line'] = $index +1;
+		//1. check if mandatory fields are set
+		$mandatory_fields = array ('UserName', 'CourseCode', 'Status');
+		foreach ($mandatory_fields as $key => $field)
+		{
+			if (!isset ($user_course[$field]) || strlen($user_course[$field]) == 0)
+			{
+				$user_course['error'] = get_lang($field.'Mandatory');
+				$errors[] = $user_course;
+			}
+		}
+		//2. check if coursecode exists
+		if (isset ($user_course['CourseCode']) && strlen($user_course['CourseCode']) != 0)
+		{
+			//2.1 check if code allready used in this CVS-file
+			if (!isset ($coursecodes[$user_course['CourseCode']]))
+			{
+				//2.1.1 check if code exists in DB
+				$course_table = Database :: get_main_table(MAIN_COURSE_TABLE);
+				$sql = "SELECT * FROM $course_table WHERE code = '".mysql_real_escape_string($user_course['CourseCode'])."'";
+				$res = api_sql_query($sql, __FILE__, __LINE__);
+				if (mysql_num_rows($res) == 0)
+				{
+					$user_course['error'] = get_lang('CodeDoesNotExists');
+					$errors[] = $user_course;
+				}
+				else
+				{
+					$coursecodes[$user_course['CourseCode']] = 1;
+				}
+			}
+		}
+		//3. check if username exists
+		if (isset ($user_course['UserName']) && strlen($user_course['UserName']) != 0)
+		{
+			if (UserManager :: is_username_available($user_course['UserName']))
+			{
+				$user_course['error'] = get_lang('UnknownUser');
+				$errors[] = $user_course;
+			}
+		}
+		//4. check if status is valid
+		if (isset ($user_course['Status']) && strlen($user_course['Status']) != 0)
+		{
+			if ($user_course['Status'] != COURSEMANAGER && $user_course['Status'] != STUDENT)
+			{
+				$user_course['error'] = get_lang('UnknownStatus');
+				$errors[] = $user_course;
+			}
+		}
+	}
+	return $errors;
+}
+
+/**
+ * Save the imported data
+ */
+function save_data($users_courses)
+{
+	$user_table= Database::get_main_table(MAIN_USER_TABLE);
+	$course_user_table= Database::get_main_table(MAIN_COURSE_USER_TABLE);
+	$csv_data = array();
+	foreach ($users_courses as $index => $user_course)
+	{
+		$csv_data[$user_course['UserName']][$user_course['CourseCode']] = $user_course['Status'];
+	}
+	foreach($csv_data as $username => $csv_subscriptions)
+	{
+		$user_id = 0;
+		$sql = "SELECT * FROM $user_table u WHERE u.username = '".mysql_real_escape_string($username)."'";
+		$res = api_sql_query($sql,__FILE__,__LINE__);
+		$obj = mysql_fetch_object($res);
+		$user_id = $obj->user_id;
+		$sql = "SELECT * FROM $course_user_table cu WHERE cu.user_id = $user_id";
+		$res = api_sql_query($sql,__FILE__,__LINE__);
+		$db_subscriptions = array();
+		while($obj = mysql_fetch_object($res))
+		{
+			$db_subscriptions[$obj->course_code] = $obj->status;
+		}
+		//echo '<b>User '.$username.'</b><br />';
+		$to_subscribe = array_diff(array_keys($csv_subscriptions),array_keys($db_subscriptions));
+		$to_unsubscribe = array_diff(array_keys($db_subscriptions),array_keys($csv_subscriptions));
+//		echo '<pre>';
+//		echo "CSV SUBSCRIPTION\n";
+//		print_r($csv_subscriptions);
+//		echo "DB SUBSCRIPTION\n";
+//		print_r($db_subscriptions);
+//		echo "TO SUBSCRIBE\n";
+//		print_r($to_subscribe);
+//		echo "TO UNSUBSCRIBE\n";
+//		print_r($to_unsubscribe);
+//		echo '</pre>';
+		if($_POST['subscribe'])
+		{
+			foreach($to_subscribe as $index => $course_code)
+			{
+				CourseManager::add_user_to_course($user_id,$course_code,$csv_subscriptions[$course_code]);
+				echo get_lang('Subscription').' : '.$course_code.'<br />';
+			}
+		}
+		if($_POST['unsubscribe'])
+		{
+			foreach($to_unsubscribe as $index => $course_code)
+			{
+				CourseManager::unsubscribe_user($user_id,$course_code);
+				echo get_lang('Unsubscription').' : '.$course_code.'<br />';
+			}
+		}
+	}
+}
+/**
+ * Read the CSV-file
+ * @param string $file Path to the CSV-file
+ * @return array All course-information read from the file
+ */
+function parse_csv_data($file)
+{
+	$courses = Import :: csv_to_array($file);
+	return $courses;
+}
+
+$langFile = array ('admin', 'registration');
+
+$cidReset = true;
+
+include ('../inc/global.inc.php');
+api_protect_admin_script();
+require_once (api_get_path(LIBRARY_PATH).'fileManage.lib.php');
+require_once (api_get_path(LIBRARY_PATH).'import.lib.php');
+require_once (api_get_path(LIBRARY_PATH).'usermanager.lib.php');
+require_once (api_get_path(LIBRARY_PATH).'course.lib.php');
+require_once (api_get_path(LIBRARY_PATH).'formvalidator/FormValidator.class.php');
+$formSent = 0;
+$errorMsg = '';
+
+$tool_name = get_lang('AddUsersToACourse').' CSV';
+
+$interbredcrump[] = array ('url' => 'index.php', 'name' => get_lang('PlatformAdmin'));
+
+set_time_limit(0);
+$form = new FormValidator('course_user_import');
+$form->addElement('file','import_file', get_lang('ImportFileLocation'));
+$form->addElement('checkbox','subscribe',get_lang('Action'),get_lang('SubscribeUserIfNotAllreadySubscribed'));
+$form->addElement('checkbox','unsubscribe','',get_lang('UnsubscribeUserIfSubscriptionIsNotInFile'));
+$form->addElement('submit','submit',get_lang('Ok'));
+if ($form->validate())
+{
+	$users_courses = parse_csv_data($_FILES['import_file']['tmp_name']);
+	$errors = validate_data($users_courses);
+	if (count($errors) == 0)
+	{
+		save_data($users_courses);
+		header('Location: user_list.php?action=show_message&message='.urlencode(get_lang('FileImported')));
+		exit ();
+	}
+}
+Display :: display_header($tool_name);
+api_display_tool_title($tool_name);
+if (count($errors) != 0)
+{
+	$error_message = '<ul>';
+	foreach ($errors as $index => $error_course)
+	{
+		$error_message .= '<li>'.get_lang('Line').' '.$error_course['line'].': <b>'.$error_course['error'].'</b>: ';
+		$error_message .= $error_course['Code'].' '.$error_course['Title'];
+		$error_message .= '</li>';
+	}
+	$error_message .= '</ul>';
+	Display :: display_error_message($error_message);
+}
+
+$form->display();
+?>
+<p><?php echo get_lang('CSVMustLookLike').' ('.get_lang('MandatoryFields').')'; ?> :</p>
+<blockquote>
+<pre>
+<b>UserName</b>;<b>CourseCode</b>;<b>Status</b>
+jdoe;course01;<?php echo COURSEMANAGER; ?>
+
+a.dam;course01;<?php echo STUDENT; ?>
+</pre>
+<?php
+echo COURSEMANAGER.': '.get_lang('Teacher').'<br />';
+echo STUDENT.': '.get_lang('Student').'<br />';
+?>
+</blockquote>
+<?php
+/*
+==============================================================================
+		FOOTER
+==============================================================================
+*/
+Display :: display_footer();
+?>

+ 425 - 0
main/admin/course_virtual.php

@@ -0,0 +1,425 @@
+<?php // $Id: course_virtual.php 9246 2006-09-25 13:24:53Z bmol $ 
+/*
+============================================================================== 
+	Dokeos - elearning and course management software
+	
+	Copyright (c) 2004-2005 Dokeos S.A.
+	Copyright (c) 2003 Ghent University (UGent)
+	Copyright (c) 2001 Universite catholique de Louvain (UCL)
+	Copyright (c) Roan Embrechts (Vrije Universiteit Brussel)
+	
+	For a full list of contributors, see "credits.txt".
+	The full license can be read in "license.txt".
+	
+	This program is free software; you can redistribute it and/or
+	modify it under the terms of the GNU General Public License
+	as published by the Free Software Foundation; either version 2
+	of the License, or (at your option) any later version.
+	
+	See the GNU General Public License for more details.
+	
+	Contact address: Dokeos, 44 rue des palais, B-1030 Brussels, Belgium
+	Mail: info@dokeos.com
+============================================================================== 
+*/
+/**
+============================================================================== 
+*	@author Roan Embrechts - initial admin interface
+*	@package dokeos.admin
+============================================================================== 
+*/
+
+/*
+============================================================================== 
+		INIT SECTION
+============================================================================== 
+*/ 
+
+// name of the language file which needs to be included 
+// 'inc.php' is automatically appended to the file name 
+$langFile = "admin"; 
+$extra_lang_file = "create_course";
+
+// global settings initialisation 
+// also provides access to main api (inc/lib/main_api.lib.php)
+include("../inc/global.inc.php"); 
+$this_section=SECTION_PLATFORM_ADMIN;
+
+api_protect_admin_script();
+
+if (isset($extra_lang_file)) include(api_get_path(INCLUDE_PATH)."../lang/english/".$extra_lang_file.".inc.php");
+if (isset($extra_lang_file)) include(api_get_path(INCLUDE_PATH)."../lang/".$language_interface."/".$extra_lang_file.".inc.php");
+
+/*
+-----------------------------------------------------------
+	Libraries
+-----------------------------------------------------------
+*/ 
+
+include_once(api_get_path(LIBRARY_PATH) . 'course.lib.php');
+
+/*
+-----------------------------------------------------------
+	Constants
+-----------------------------------------------------------
+*/ 
+
+define ("CREATE_VIRTUAL_COURSE_OPTION", "create_virtual_course");
+define ("DISPLAY_VIRTUAL_COURSE_LIST_OPTION", "display_virtual_course_list");
+
+define ("FORM_ELEMENT_CODE_SIZE", "20");
+define ("FORM_ELEMENT_TEXT_SIZE", "60");
+define ("SELECT_BOX_SIZE", "10");
+
+define ("COURSE_TITLE_FORM_NAME", "course_title");
+define ("LANGUAGE_SELECT_FORM_NAME" , "course_language");
+define ("REAL_COURSE_SELECT_FORM_NAME" , "real_course_code");
+define ("WANTED_COURSE_CODE_FORM_NAME" , "wanted_course_code");
+define ("COURSE_CATEGORY_FORM_NAME" , "course_category");
+
+/*
+-----------------------------------------------------------
+	Header
+-----------------------------------------------------------
+*/ 
+
+$tool_name = get_lang('AdminManageVirtualCourses'); // title of the page (should come from the language file) 
+
+//$interbreadcrumb[]=array("url" => "index.php","name" => get_lang('PlatformAdmin'));
+
+Display::display_header($tool_name);
+
+/*
+============================================================================== 
+		DISPLAY FUNCTIONS
+============================================================================== 
+*/ 
+
+function make_strong($text)
+{
+	return "<strong>" . $text . "</strong>";
+}
+
+
+/**
+*	Return a list of language directories.
+*	@todo function does not belong here, move to code library,
+*	also see infocours.php and index.php which contain a similar function
+*/
+function get_language_folder_list($dirname)
+{
+	if($dirname[strlen($dirname)-1]!='/') $dirname.='/';
+	$handle=opendir($dirname);
+	while ($entries = readdir($handle))
+	{
+		if ($entries=='.' || $entries=='..' || $entries=='CVS') continue;
+		if (is_dir($dirname.$entries))
+		{
+			$language_list[] = $entries;
+		}
+	}
+	closedir($handle);
+	return $language_list;
+}
+
+/**
+* Displays a select element (drop down menu) so the user can select 
+* the course language.
+* @todo function does not belong here, move to (display?) library,
+* @todo language display used apparently no longer existing array, converted to english for now.
+* but we should switch to display the real language names.
+*/
+function display_language_select($element_name)
+{
+	global $platformLanguage;
+	
+	//get language list
+	$dirname = api_get_path(SYS_PATH)."main/lang/";
+	$language_list = get_language_folder_list($dirname);
+	sort($language_list);
+	
+	//build array with strings to display
+	foreach ($language_list as $this_language)
+	{	
+		$language_to_display[$this_language] = $this_language;
+	}
+	
+	//sort alphabetically
+	//warning: key,value association needs to be maintained --> asort instead of sort
+	asort($language_to_display);
+			 
+	$user_selected_language = $_SESSION["user_language_choice"];
+	if (! isset($user_selected_language) ) $user_selected_language = $platformLanguage;
+	
+	//display
+	echo "<select name=\"$element_name\">";
+	foreach ($language_to_display as $key => $value)
+	{
+		if ($key == $user_selected_language) $option_end = "selected >";
+		else $option_end = ">";
+		echo "<option value=\"$key\" $option_end";
+
+		echo $value;
+		echo "</option>\n";
+	}
+	echo "</select>";
+}
+
+/**
+*	This code creates a select form element to let the user
+*	choose a real course to link to.
+*
+*	We display the course code, but internally store the course id.
+*/
+function display_real_course_code_select($element_name)
+{	
+	$real_course_list = CourseManager::get_real_course_list();
+			
+	echo "<select name=\"$element_name\" size=\"".SELECT_BOX_SIZE."\" >\n";
+	foreach($real_course_list as $real_course)
+	{
+		$course_code = $real_course["code"];
+		echo "<option value=\"". $course_code ."\">";
+		echo $course_code;
+		echo "</option>\n";
+	}
+	echo "</select>\n";
+}
+
+
+function display_create_virtual_course_form()
+{
+	$category_table = Database::get_main_table(MAIN_CATEGORY_TABLE);
+
+	$message = make_strong(get_lang('AdminCreateVirtualCourse')) . "<br/>" . get_lang('AdminCreateVirtualCourseExplanation') . "<br/>This feature is in development phase, bug reports welcome.";
+	?>
+	<p><?php echo $message;	?></p>
+	<b><?php echo get_lang('MandatoryFields') ?></b>
+	<form method="post" action="<?php echo $_SERVER['PHP_SELF'] ?>">
+	<table>
+	<tr valign="top">
+	<td colspan="2">
+	
+	</td>
+	</tr>
+	
+	<tr valign="top">
+	<td align="right">
+		<?php
+			echo make_strong(get_lang('CourseTitle')) . "&nbsp;";
+			echo "</td>";
+			echo "<td valign=\"top\">";
+			echo "<input type=\"Text\" name=\"".COURSE_TITLE_FORM_NAME."\" size=\"".FORM_ELEMENT_TEXT_SIZE."\" value=\"$valueIntitule\"/><br />".get_lang('Ex') ;
+		?>
+	</td>
+	</tr>
+	
+	<tr valign="top">
+	<td align="right"><?php echo make_strong(get_lang('CourseFaculty')) . "&nbsp;"; ?> </td>
+	<td>
+		<?php
+			echo "<select name=\"".COURSE_CATEGORY_FORM_NAME."\">";
+			
+			$sql_query = "SELECT code, name
+									FROM $category_table
+									WHERE auth_course_child ='TRUE'
+									ORDER BY tree_pos";
+			$category_result = api_sql_query($sql_query, __FILE__, __LINE__);
+		
+			while ($current_category = mysql_fetch_array($category_result))
+			{
+				echo "<option value=\"", $current_category["code"], "\"";
+				echo ">(", $current_category["code"], ") ", $current_category["name"];
+				echo "</option>\n";
+			}
+		?>
+	</select>
+	<br /><?php echo make_strong(get_lang('TargetFac'))  . "&nbsp;" ?>
+	</td>
+	</tr>
+	
+	<tr valign="top">
+	<td align="right"><?php echo make_strong(get_lang('Code'))  . "&nbsp;" ?> </td>
+	<td>
+	<?php
+	echo "<input type=\"Text\" name=\"".WANTED_COURSE_CODE_FORM_NAME."\" maxlength=\"".FORM_ELEMENT_CODE_SIZE."\" value=\"$valuePublicCode\"/>
+	<br/>" . get_lang('Max');
+	?>
+	</td>
+	</tr>
+	
+	<tr valign="top">
+	<td align="right">
+	<?php echo make_strong(get_lang('RealCourseCode'))  . "&nbsp;" ?> 
+	</td>
+	<td>
+		<?php
+			display_real_course_code_select(REAL_COURSE_SELECT_FORM_NAME);
+			//echo "<input type=\"Text\" name=\"real_course_code\" maxlength=\"".FORM_ELEMENT_CODE_SIZE."\" value=\"" . htmlentities($valueTitular) . "\"/>";
+		?>
+	</td>
+	</tr>
+	
+	<tr valign="top">
+	<td align="right">
+		<?php 
+			echo make_strong(get_lang('CourseLanguage')) . "&nbsp;";
+		?> 
+	</td>
+	<td> <?php  display_language_select(LANGUAGE_SELECT_FORM_NAME); ?>
+
+	</td>
+	</tr>
+	<tr valign="top">
+	<td>
+	</td>
+	<td>
+	<input type="Submit" name="submit_create_virtual_course" value="<?php echo get_lang('Ok')?>"/>
+	</td>
+	</tr>
+	</table>
+	</form>
+	<?php
+}
+
+function display_main_options()
+{
+	$message = "<ul><li><a href=\"?action=".CREATE_VIRTUAL_COURSE_OPTION."\">".get_lang('CreateVirtualCourse')."</a></li>";
+	$message .= "<li><a href=\"?action=".DISPLAY_VIRTUAL_COURSE_LIST_OPTION."\">".get_lang('DisplayListVirtualCourses')."</a></li></ul>";
+	echo $message;
+}
+
+function display_virtual_course_list()
+{
+	$course_list = CourseManager::get_virtual_course_list();
+	if (! is_array($course_list) )
+	{
+		//there are no virtual courses
+		echo "<i>".get_lang('ThereAreNoVirtualCourses')."</i>";
+		return;
+	}
+	
+	$column_header[] = array(get_lang('Title'),true);					
+	$column_header[] = array(get_lang('Code'),true);				
+	$column_header[] = array(get_lang('VisualCode'),true);				
+	$column_header[] = array(get_lang('LinkedCourseTitle'),true);	
+	$column_header[] = array(get_lang('LinkedCourseCode'),true);		
+	$table_data = array();
+	for($i = 0; $i < count($course_list); $i++)
+	{
+		$course_list[$i] = Database::generate_abstract_course_field_names($course_list[$i]);
+		$target_course_code = $course_list[$i]["target_course_code"];
+		$real_course_info = Database::get_course_info($target_course_code);
+		
+		$row = array();
+		$row[] = $course_list[$i]["title"];
+		$row[] = $course_list[$i]["system_code"];
+		$row[] = $course_list[$i]["visual_code"];
+		$row[] = $real_course_info["title"];
+		$row[]= $real_course_info["system_code"];
+		$table_data[] = $row;
+	}
+	Display::display_sortable_table($column_header,$table_data,array(),array(),array('action'=>$_GET['action']));
+}
+
+
+/*
+============================================================================== 
+		TOOL LOGIC FUNCTIONS
+============================================================================== 
+*/
+
+/**
+*	Checks all parameters needed to create a virtual course.
+*	If they are all set, the virtual course creation procedure is called.
+*	Call this function instead of create_virtual_course
+*/
+function attempt_create_virtual_course($real_course_code, $course_title, $wanted_course_code, $course_language, $course_category)
+{		
+	//better: create parameter list, check the entire list, when false display errormessage	
+	CourseManager::check_parameter_or_fail($real_course_code, "Unspecified parameter: real course id.");
+	CourseManager::check_parameter_or_fail($course_title, "Unspecified parameter: course title.");
+	CourseManager::check_parameter_or_fail($wanted_course_code, "Unspecified parameter: wanted course code.");
+	CourseManager::check_parameter_or_fail($course_language, "Unspecified parameter: course language.");
+	CourseManager::check_parameter_or_fail($course_category, "Unspecified parameter: course category.");
+	
+	$message = get_lang('AttemptedCreationVirtualCourse') . "<br/>";
+	$message .= get_lang('CourseTitle') . " " . $course_title . "<br/>";
+	$message .= get_lang('WantedCourseCode') . " " . $wanted_course_code . "<br/>";
+	$message .= get_lang('CourseLanguage') . " " . $course_language . "<br/>";
+	$message .= get_lang('CourseFaculty') . " " . $course_category . "<br/>";
+	$message .= get_lang('LinkedToRealCourseCode') . " " . $real_course_code . "<br/>";
+	
+	Display::display_normal_message($message);
+	
+	$creation_success = CourseManager::create_virtual_course( $real_course_code, $course_title, $wanted_course_code, $course_language, $course_category );
+	
+	if ($creation_success == true)
+	{
+		Display::display_normal_message( $course_title . " - " . get_lang('CourseCreationSucceeded') );
+		return true;
+	}
+	return false;
+}
+	
+/*
+============================================================================== 
+		MAIN CODE
+============================================================================== 
+*/ 
+
+$action = $_GET["action"];
+$attempt_create_virtual_course = $_POST["submit_create_virtual_course"];
+
+//api_display_tool_title($tool_name);
+
+if ( isset($attempt_create_virtual_course) && $attempt_create_virtual_course )
+{
+	$real_course_code = $_POST[REAL_COURSE_SELECT_FORM_NAME];
+	$course_title = $_POST[COURSE_TITLE_FORM_NAME];
+	$wanted_course_code = $_POST[WANTED_COURSE_CODE_FORM_NAME];
+	$course_language = $_POST[LANGUAGE_SELECT_FORM_NAME];
+	$course_category = $_POST[COURSE_CATEGORY_FORM_NAME];
+	
+	$message = get_lang('AttemptedCreationVirtualCourse') . "<br/>";
+	$message .= get_lang('CourseTitle') . " " . $course_title . "<br/>";
+	$message .= get_lang('WantedCourseCode') . " " . $wanted_course_code . "<br/>";
+	$message .= get_lang('CourseLanguage') . " " . $course_language . "<br/>";
+	$message .= get_lang('CourseFaculty') . " " . $course_category . "<br/>";
+	$message .= get_lang('LinkedToRealCourseCode') . " " . $real_course_code . "<br/>";
+	
+	Display::display_normal_message($message);
+	
+	$creation_success = CourseManager::attempt_create_virtual_course($real_course_code, $course_title, $wanted_course_code, $course_language, $course_category);
+	
+	if ($creation_success == true)
+	{
+		Display::display_normal_message( $course_title . " - " . get_lang('CourseCreationSucceeded') );
+	}
+	else
+	{
+		//should display error message
+	}
+	echo "<br/>";
+}
+
+
+display_main_options();
+
+switch($action)
+{
+	case CREATE_VIRTUAL_COURSE_OPTION:
+							display_create_virtual_course_form();
+							break;
+	case DISPLAY_VIRTUAL_COURSE_LIST_OPTION:
+							display_virtual_course_list();
+							break;
+}
+
+/*
+==============================================================================
+		FOOTER 
+==============================================================================
+*/ 
+Display::display_footer();
+?>

+ 3 - 0
main/admin/exemple.csv

@@ -0,0 +1,3 @@
+LastName;FirstName;UserName;Password;Email;OfficialCode;PhoneNumber;Status;Courses
+Gates;Bill;BillGates;secret_password;bill.gates@microsoft.com;12345678;001-123-456-789;user;COURSE1|COURSE2|COURSE3
+Bush;Georges;;;georges_bush@usa.org;;;teacher;COURSE2

+ 25 - 0
main/admin/exemple.xml

@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<Contacts>
+    <Contact>
+        <LastName>Gates</LastName>
+        <FirstName>Bill</FirstName>
+        <UserName>BillGates</UserName>
+        <Password>secret_password</Password>
+        <Email>bill.gates@microsoft.com</Email>
+        <OfficialCode>12345678</OfficialCode>
+        <PhoneNumber>001-123-456-789</PhoneNumber>
+        <Status>user</Status>
+        <Courses>COURSE1|COURSE2|COURSE3</Courses>
+    </Contact>
+    <Contact>
+        <LastName>Bush</LastName>
+        <FirstName>Georges</FirstName>
+        <UserName></UserName>
+        <Password></Password>
+        <Email>georges_bush@usa.org</Email>
+        <OfficialCode />
+        <PhoneNumber />
+        <Status>teacher</Status>
+        <Courses>COURSE2</Courses>
+    </Contact>
+</Contacts>

+ 379 - 0
main/admin/index.php

@@ -0,0 +1,379 @@
+<?php // $Id: index.php 9797 2006-10-26 06:47:10Z pcool $
+/*
+==============================================================================
+	Dokeos - elearning and course management software
+
+	Copyright (c) 2004 Dokeos S.A.
+	Copyright (c) 2003 Ghent University (UGent)
+	Copyright (c) 2001 Universite catholique de Louvain (UCL)
+	Copyright (c) Olivier Brouckaert
+
+	For a full list of contributors, see "credits.txt".
+	The full license can be read in "license.txt".
+
+	This program is free software; you can redistribute it and/or
+	modify it under the terms of the GNU General Public License
+	as published by the Free Software Foundation; either version 2
+	of the License, or (at your option) any later version.
+
+	See the GNU General Public License for more details.
+
+	Contact: Dokeos, 181 rue Royale, B-1000 Brussels, Belgium, info@dokeos.com
+==============================================================================
+*/
+/**
+==============================================================================
+*	Index of the admin tools
+*
+*	@package dokeos.admin
+==============================================================================
+*/
+
+$langFile='admin';
+
+$cidReset=true;
+
+include('../inc/global.inc.php');
+include_once('../inc/installedVersion.inc.php');
+$this_section=SECTION_PLATFORM_ADMIN;
+
+api_protect_admin_script();
+$tool_name=get_lang("PlatformAdmin");
+
+Display::display_header();
+
+/*
+==============================================================================
+		ACTION HANDLING
+==============================================================================
+*/
+if ($_POST['Register'])
+{
+	register_site();
+	Display :: display_confirmation_message('Version Check Enabled');
+}
+
+/*
+==============================================================================
+		MAIN SECTION
+==============================================================================
+*/
+
+?>
+
+<div class="admin_section">
+<h4><img src="../img/members.gif" border="0" style="vertical-align: middle;" alt="" /> <?php echo ucfirst(get_lang('Users')); ?></h4>
+	<ul><li style="list-style-type:none"><form method="get" action="user_list.php">
+
+	<input type="text" name="keyword" value="<?php echo $_GET['keyword']; ?>"/>
+	<input type="submit" value="<?php echo get_lang('Search'); ?>"/>
+	</form></li>
+	<li>
+<a href="user_list.php?search=advanced"><?php echo get_lang('AdvancedSearch'); ?></a>
+	
+</li>
+<li><a href="user_list.php"><?php echo get_lang('UserList') ?></a></li>
+<li><a href="user_add.php"><?php echo get_lang('AddUsers') ?></a></li>
+<li><a href="user_export.php"><?php echo get_lang('ExportUserListXMLCSV') ?></a></li>
+<li><a href="user_import.php"><?php echo get_lang('ImportUserListXMLCSV') ?></a></li>
+</ul>
+</div>
+
+<div class="admin_section">
+<h4><img src="../img/course.gif" border="0" style="vertical-align: middle;" alt="" /> <?php echo ucfirst(get_lang('Courses')); ?></h4>
+	<ul><li style="list-style-type:none"><form method="get" action="course_list.php">
+
+	<input type="text" name="keyword" value="<?php echo $_GET['keyword']; ?>"/>
+	<input type="submit" value="<?php echo get_lang('Search'); ?>"/>
+	</form></li>
+	<li>
+	<a href="course_list.php?search=advanced"><?php echo get_lang('AdvancedSearch'); ?></a>
+	
+</li>
+<li><a href="course_list.php"><?php echo get_lang('CourseList') ?></a></li>
+<li><a href="course_add.php"><?php echo get_lang('AddCourse') ?></a></li>
+<li><a href="course_import.php"><?php echo get_lang('AddCourse').' CSV'; ?></a></li>
+<!--<li><a href="course_virtual.php"><?php //echo get_lang('AdminManageVirtualCourses') ?></a></li>-->
+<li><a href="course_category.php"><?php echo get_lang("AdminCategories"); ?></a></li>
+<li><a href="subscribe_class2course.php"><?php echo get_lang('AddClassesToACourse'); ?></a></li>
+<li><a href="subscribe_user2course.php"><?php echo get_lang('AddUsersToACourse'); ?></a></li>
+<li><a href="course_user_import.php"><?php echo get_lang('AddUsersToACourse').' CSV'; ?></a></li>
+</ul>
+</div>
+
+<div class="admin_section">
+ <h4>
+  <img src="../img/settings.gif" border="0" style="vertical-align: middle;" alt="" />
+  <?php echo ucfirst(get_lang('Platform')); ?>
+ </h4>
+ <ul>
+  <li><a href="settings.php"><?php echo get_lang('DokeosConfigSettings') ?></a></li>
+  <li><a href="system_announcements.php"><?php echo get_lang('SystemAnnouncements') ?></a></li>
+  <li><a href="languages.php"><?php echo get_lang('Languages'); ?></a></li>
+  <li><a href="configure_homepage.php"><?php echo get_lang('ConfigureHomePage'); ?></a></li>
+  <!-- <li><a href="configure_extensions.php"><?php echo get_lang('ConfigureExtensions'); ?></a></li> -->
+  <li><a href="configure_extensions.php?display=visio"><?php echo get_lang('Visioconf'); ?></a></li>
+  <li><a href="configure_extensions.php?display=ppt2lp"><?php echo get_lang('Ppt2lp'); ?></a></li>
+  <li><a href="configure_extensions.php?display=search"><?php echo get_lang('SearchEngine'); ?></a></li>
+  <li><a href="configure_extensions.php?display=serverstats"><?php echo get_lang('ServerStatistics'); ?></a></li>
+  <li><a href="configure_extensions.php?display=bandwidthstats"><?php echo get_lang('BandWidthStatistics'); ?></a></li>
+  
+  <?php if(!empty($phpMyAdminPath)): ?>
+  <li><a href="<?php echo $phpMyAdminPath; ?>" target="_blank"><?php echo get_lang("AdminDatabases"); ?></a><br />(<?php echo get_lang("DBManagementOnlyForServerAdmin"); ?>)</li>
+  <?php endif; ?>
+
+ </ul>
+</div>
+
+
+<?php
+if(api_get_setting('use_session_mode')=='true')
+{
+?>
+
+<div class="admin_section">
+ <h4>
+  <img src="../img/agenda.gif" border="0" align="absmiddle" alt="" />
+  <?php echo get_lang('Sessions') ?>
+ </h4>
+ <ul>
+ <li style="list-style-type:none"><form method="POST" action="session_list.php">
+	<input type="text" name="keyword" value="<?php echo $_GET['keyword']; ?>"/>
+	<input type="submit" value="<?php echo get_lang('Search'); ?>"/>
+	</form>
+</li>
+  <li><a href="session_list.php"><?php echo get_lang('ListSession') ?></a></li>
+  <li><a href="session_add.php"><?php echo get_lang('AddSession') ?></a></li>
+  <li><a href="session_import.php"><?php echo get_lang('ImportSessionListXMLCSV') ?></a></li>
+  <li><a href="session_export.php"><?php echo get_lang('ExportSessionListXMLCSV') ?></a></li>
+  </ul>
+</div>
+
+<?php
+}
+else
+{
+?>
+
+<div class="admin_section">
+<h4><img src="../img/group.gif" border="0" style="vertical-align: middle;" alt="" /> <?php echo ucfirst(get_lang('AdminClasses')); ?></h4>
+<ul>
+<li style="list-style-type:none"><form method="get" action="class_list.php">
+
+	<input type="text" name="keyword" value="<?php echo $_GET['keyword']; ?>"/>
+	<input type="submit" value="<?php echo get_lang('Search'); ?>"/>
+	</form>
+</li>
+<li><a href="class_list.php"><?php echo get_lang('ClassList'); ?></a></li>
+<li><a href="class_add.php"><?php echo get_lang('AddClasses'); ?></a></li>
+<li><a href="class_import.php"><?php echo get_lang('ImportClassListCSV'); ?></a></li>
+<li><a href="class_user_import.php"><?php echo get_lang('AddUsersToAClass'); ?> CSV</a></li>
+</ul>
+</div>
+<?php
+}
+?>
+
+
+<div class="admin_section">
+ <h4>
+  <img src="../img/dokeos.gif" border="0" style="vertical-align: middle;" alt="" />
+  <?php echo "dokeos.com"; ?>
+ </h4>
+ <ul>
+  <li><a href="http://www.dokeos.com/"><?php echo get_lang('DokeosHomepage'); ?></a></li>
+  <li><a href="http://www.dokeos.com/forum/"><?php echo get_lang('DokeosForum'); ?></a></li>
+  <li><a href="http://www.dokeos.com/community_add_portal.php?url=<?php echo $rootWeb; ?>&amp;name=<?php echo urlencode(get_setting('siteName'));?>&amp;organisation=<?php echo urlencode(get_setting('InstitutionUrl'));?>&amp;manager=<?php echo urlencode(get_setting('administratorSurname')." ".get_setting('administratorName'));?>&amp;manageremail=<?php echo urlencode(get_setting('emailAdministrator'));?>"><?php echo get_lang('RegisterYourPortal'); ?></a></li>
+  <li><a href="http://www.dokeos.com/extensions/"><?php echo get_lang('DokeosExtensions'); ?></a></li>
+  <li>
+  <?php
+  //try to display a maximum before we check the dokeos version and all that
+	flush(); //send data to client as much as allowed by the web server
+	ob_flush();
+	echo get_lang('VersionCheck').': '.version_check();
+  ?>
+  </li>
+ </ul>
+</div>
+
+
+<?php
+/**
+ * Displays either the text for the registration or the message that the installation is (not) up to date
+ *
+ * @return string html code
+ * @author Patrick Cool <patrick.cool@UGent.be>, Ghent University
+ * @version august 2006
+ * @todo have a 6monthly re-registration
+ */
+function version_check()
+{
+	// The site has not been registered yet
+	if (get_setting('registered')=='false' OR get_setting('registered') == false )
+	{
+		$return = '';
+		$return .= '<form action="'.$_SERVER['PHP_SELF'].'" id="VersionCheck" name="VersionCheck" method="post">';
+		$return .= get_lang('VersionCheckExplanation'); 
+		$return .= '<input type="checkbox" name="donotlistcampus" value="1" id="checkbox" /> Do not display my campus in the list of Dokeos platforms';
+		$return .= '<input type="submit" name="Register" value="Enable Version Check" id="register" />';
+		$return .= '</form>';
+	}
+	else
+	{
+		// The site has been registered already but is seriously out of date (registration date + 15552000 seconds)
+		if ((get_setting('registered') + 15552000) > mktime())
+		{
+			$return = 'It has been a long time since about your campus has been updated on Dokeos.com';
+			$return .= '<form action="'.$_SERVER['PHP_SELF'].'" id="VersionCheck" name="VersionCheck" method="post">';
+			$return .= '<input type="submit" name="Register" value="Enable Version Check" id="register" />';
+			$return .= '</form>';
+		}
+		else
+		{
+			$return = 'site registered';
+			$return .= check_dokeos_version2();
+		}
+	}
+
+	return $return;
+
+}
+
+/**
+ * This setting changes the registration status for the campus
+ *
+ * @author Patrick Cool <patrick.cool@UGent.be>, Ghent University
+ * @version August 2006
+ *
+ * @todo the $_settings should be reloaded here. => write api function for this and use this in global.inc.php also.
+ */
+function register_site()
+{
+	// the settings table
+	$tbl_settings = Database :: get_main_table(MAIN_SETTINGS_CURRENT_TABLE);
+
+	// the SQL statment
+	$sql = "UPDATE $tbl_settings SET selected_value='true' WHERE variable='registered'";
+	$result = api_sql_query($sql);
+
+	//
+	if ($_POST['donotlistcampus'])
+	{
+		$sql = "UPDATE $tbl_settings SET selected_value='true' WHERE variable='donotlistcampus'";
+		$result = api_sql_query($sql);
+	}
+
+	// reload the settings
+}
+
+/**
+* Check if the current installation is up to date
+* The code is borrowed from phpBB and slighlty modified
+* @author The phpBB Group <support@phpbb.com> (the code)
+* @author Patrick Cool <patrick.cool@UGent.be>, Ghent University (the modifications)
+* @copyright (C) 2001 The phpBB Group
+* @return language string with some layout (color)
+*/
+function check_dokeos_version2()
+{
+	global $dokeos_version; // the dokeos version of your installation
+
+	if (ini_get('allow_url_fopen')==1)
+	{
+		// the number of courses
+		$sql="SELECT code FROM ".Database::get_main_table(MAIN_COURSE_TABLE);
+		$result=api_sql_query($sql);
+		$number_of_courses = mysql_num_rows($result);
+
+		// the number of users
+		$sql="SELECT user_id FROM ".Database::get_main_table(MAIN_USER_TABLE);
+		$result=api_sql_query($sql);
+		$number_of_users = mysql_num_rows($result);
+
+		$version_url= 'http://www.dokeos.com/version.php?url='.urlencode(api_get_path(WEB_PATH)).'&campus='.urlencode(api_get_setting('siteName')).'&contact='.urlencode(get_setting('emailAdministrator')).'&version='.urlencode($dokeos_version).'&numberofcourses='.urlencode($number_of_courses).'&numberofusers='.urlencode($number_of_users).'&donotlistcampus='.get_setting('donotlistcampus');
+		$handle=@fopen($version_url,'r');
+		$version_info=@fread($handle, 1024);
+
+		if ($dokeos_version<>$version_info)
+		{
+			$output='<span style="color:red">' . get_lang('YourVersionNotUpToDate') . '. '.get_lang('LatestVersionIs').' <b>Dokeos '.$version_info.'</b>. '.get_lang('YourVersionIs').' <b>Dokeos '.$dokeos_version. '</b>. '.str_replace('http://www.dokeos.com','<a href="http://www.dokeos.com">http://www.dokeos.com</a>',get_lang('PleaseVisitDokeos')).'</span>';
+		}
+		else
+		{
+			$output = '<span style="color:green">'.get_lang('VersionUpToDate').': Dokeos '.$version_info.'</span>';
+		}
+	}
+	else
+	{
+		$output = '<span style="color:red">' . get_lang('AllowurlfopenIsSetToOff') . '</span>';
+	}
+	return $output;
+}
+
+/**
+* Check if the current installation is up to date
+* The code is borrowed from phpBB and slighlty modified
+* @author The phpBB Group <support@phpbb.com> (the code)
+* @author Patrick Cool <patrick.cool@UGent.be>, Ghent University (the modifications)
+* @copyright (C) 2001 The phpBB Group
+* @return language string with some layout (color)
+* @deprecated 	For some reason this code adds a 9 in front and a 0 at the end of what normally gets displayed by
+				the http://www.dokeos.com/version.php page (instead of version.txt) . That's why I chose to use fopen which requires however
+				that allow_url_open is set to true
+*/
+function check_dokeos_version()
+{
+	global $dokeos_version; // the dokeos version of your installation
+
+	if ($fsock = @fsockopen('www.dokeos.com', 80, $errno, $errstr))
+	{
+		@fputs($fsock, "GET /version.php HTTP/1.1\r\n");
+		@fputs($fsock, "HOST: www.dokeos.com\r\n");
+		@fputs($fsock, "Connection: close\r\n\r\n");
+
+		$get_info = false;
+		while (!@feof($fsock))
+		{
+			if ($get_info)
+			{
+				$version_info .= @fread($fsock, 1024);
+			}
+			else
+			{
+				if (@fgets($fsock, 1024) == "\r\n")
+				{
+					$get_info = true;
+				}
+			}
+		}
+		@fclose($fsock);
+
+		if ($dokeos_version<>$version_info)
+		{
+			$output='<span style="color:red">' . get_lang('YourVersionNotUpToDate') . '. '.get_lang('LatestVersionIs').' <b>Dokeos '.$version_info.'</b>. '.get_lang('YourVersionIs').' <b>Dokeos '.$dokeos_version. '</b>. '.str_replace('http://www.dokeos.com','<a href="http://www.dokeos.com">http://www.dokeos.com</a>',get_lang('PleaseVisitDokeos')).'</span>';
+		}
+		else
+		{
+			$output = '<span style="color:green">'.get_lang('VersionUpToDate').': Dokeos '.$version_info.'</span>';
+		}
+	}
+	else
+	{
+		if ($errstr)
+		{
+			$output = '<span style="color:red">' . get_lang('ConnectSocketError') . ': '. $errstr . '</span>';
+		}
+		else
+		{
+			$output = '<span>' . get_lang('SocketFunctionsDisabled') . '</span>';
+		}
+	}
+	return $output;
+}
+/*
+==============================================================================
+		FOOTER
+==============================================================================
+*/
+Display::display_footer();
+?>

+ 200 - 0
main/admin/languages.php

@@ -0,0 +1,200 @@
+<?php
+// $Id: languages.php 9246 2006-09-25 13:24:53Z bmol $
+/*
+==============================================================================
+	Dokeos - elearning and course management software
+
+	Copyright (c) 2004-2005 Dokeos S.A.
+	Copyright (c) 2003 Ghent University (UGent)
+	Copyright (c) Bart Mollet, Hogeschool Gent
+
+	For a full list of contributors, see "credits.txt".
+	The full license can be read in "license.txt".
+
+	This program is free software; you can redistribute it and/or
+	modify it under the terms of the GNU General Public License
+	as published by the Free Software Foundation; either version 2
+	of the License, or (at your option) any later version.
+
+	See the GNU General Public License for more details.
+
+	Contact: Dokeos, 181 rue Royale, B-1000 Brussels, Belgium, info@dokeos.com
+==============================================================================
+*/
+/**
+==============================================================================
+* This page allows the platform admin to decide which languages should
+* be available in the language selection menu in the login page. This can be
+* useful for countries with more than one official language (like Belgium: 
+* Dutch, French and German) or international organisations that are active in	
+* a limited number of countries. 
+* 
+* @author Patrick Cool, main author
+* @author Roan EMbrechts, code cleaning
+* @since Dokeos 1.6
+* @package dokeos.admin
+==============================================================================
+*/
+
+/*
+============================================================================== 
+	   INIT SECTION
+============================================================================== 
+*/
+// language file to be included 
+$langFile = 'admin';
+
+// we are in the admin area so we do not need a course id
+$cidReset = true;
+
+// include global script
+include ('../inc/global.inc.php');
+$this_section = SECTION_PLATFORM_ADMIN;
+
+api_protect_admin_script();
+// setting the table that is needed for the styles management (there is a check if it exists later in this code)
+$tbl_admin_languages = Database :: get_main_table(MAIN_LANGUAGE_TABLE);
+$tbl_settings_current = Database :: get_main_table(MAIN_SETTINGS_CURRENT_TABLE);
+
+/*
+============================================================================== 
+		STORING THE CHANGES
+============================================================================== 
+*/
+// we change the availability
+if ($_GET['action'] == 'makeunavailable')
+{
+	$sql_make_unavailable = "UPDATE $tbl_admin_languages SET available='0' WHERE id='{$_GET['id']}'";
+	$result = api_sql_query($sql_make_unavailable);
+}
+if ($_GET['action'] == 'makeavailable')
+{
+	$sql_make_available = "UPDATE $tbl_admin_languages SET available='1' WHERE id='{$_GET['id']}'";
+	$result = api_sql_query($sql_make_available);
+}
+
+if ($_POST['Submit'])
+{
+	// changing the name
+	$sql_update = "UPDATE $tbl_admin_languages SET original_name='{$_POST['txt_name']}' WHERE id='{$_POST['edit_id']}'";
+	$result = api_sql_query($sql_update);
+	// changing the Platform language
+	if ($_POST['platformlanguage'] && $_POST['platformlanguage'] <> '')
+	{
+		$sql_update_2 = "UPDATE $tbl_settings_current SET selected_value='{$_POST['platformlanguage']}' WHERE variable='platformLanguage'";
+		$result_2 = api_sql_query($sql_update_2);
+	}
+}
+elseif (isset($_POST['action']))
+{
+	switch ($_POST['action'])
+	{
+		case 'makeavailable' :
+			if (count($_POST['id']) > 0)
+			{
+				$ids = array ();
+				foreach ($_POST['id'] as $index => $id)
+				{
+					$ids[] = mysql_real_escape_string($id);
+				}
+				$sql = "UPDATE $tbl_admin_languages SET available='1' WHERE id IN ('".implode("','", $ids)."')";
+				api_sql_query($sql,__FILE__,__LINE__);
+			}
+			break;
+		case 'makeunavailable' :
+			if (count($_POST['id']) > 0)
+			{
+				$ids = array ();
+				foreach ($_POST['id'] as $index => $id)
+				{
+					$ids[] = mysql_real_escape_string($id);
+				}
+				$sql = "UPDATE $tbl_admin_languages SET available='0' WHERE id IN ('".implode("','", $ids)."')";
+				api_sql_query($sql,__FILE__,__LINE__);
+			}
+			break;
+	}
+}
+
+/*
+============================================================================== 
+		MAIN CODE
+============================================================================== 
+*/
+// setting the name of the tool
+$tool_name = get_lang('PlatformLanguages');
+
+// setting breadcrumbs
+$interbreadcrumb[] = array ('url' => 'index.php', 'name' => get_lang('PlatformAdmin'));
+
+// including the header file (which includes the banner itself)
+Display :: display_header($tool_name);
+
+// displaying the naam of the tool 
+//api_display_tool_title($tool_name);
+
+// displaying the explanation for this tool
+echo '<p>'.get_lang('PlatformLanguagesExplanation').'</p>';
+
+// selecting all the languages	
+$sql_select = "SELECT * FROM $tbl_admin_languages";
+$result_select = api_sql_query($sql_select);
+
+/*
+--------------------------------------
+		DISPLAY THE TABLE
+--------------------------------------
+*/
+
+// the table data
+$language_data = array ();
+while ($row = mysql_fetch_array($result_select))
+{
+	$row_td = array ();
+	$row_td[] = $row['id'];
+	// the first column is the original name of the language OR a form containing the original name
+	if ($_GET['action'] == 'edit' and $row['id'] == $_GET['id'])
+	{
+		$row_td[] = '<input type="hidden" name="edit_id" value="'.$_GET['id'].'" /><input type="text" name="txt_name" value="'.$row['original_name'].'" /> '
+			. '<input type="checkbox" name="platformlanguage" id="platformlanguage" value="'.$row['english_name'].'" /><label for="platformlanguage">'.$row['original_name'].' '.get_lang('AsPlatformLanguage').'</label> <input type="submit" name="Submit" value="'.get_lang('Ok').'" />';
+	}
+	else
+	{
+		$row_td[] = $row['original_name'];
+	}
+	// the second column
+	$row_td[] = $row['english_name'];
+	// the third column
+	$row_td[] = $row['dokeos_folder'];
+	// the fourth column with the visibility icon and the edit icon
+	if ($row['available'] == 1)
+	{
+		$row_td[] = "<a href='".$_SERVER['PHP_SELF']."?action=makeinavailable&id=".$row['id']."'><img src='../img/visible.gif' border='0'></a> <a href='".$_SERVER['PHP_SELF']."?action=edit&id=".$row['id']."'><img src='../img/edit.gif' border='0'></a>";
+	}
+	else
+	{
+		$row_td[] = "<a href='".$_SERVER['PHP_SELF']."?action=makeavailable&id=".$row['id']."'><img src='../img/invisible.gif' border='0'></a> <a href='".$_SERVER['PHP_SELF']."?action=edit&id=".$row['id']."'><img src='../img/edit.gif' border='0'></a>";
+	}
+
+	$language_data[] = $row_td;
+}
+
+$table = new SortableTableFromArray($language_data, 1, count($language_data));
+$table->set_header(0, '');
+$table->set_header(1, get_lang('OriginalName'));
+$table->set_header(2, get_lang('EnglishName'));
+$table->set_header(3, get_lang('DokeosFolder'));
+$table->set_header(4, get_lang('Properties'));
+$form_actions = array ();
+$form_actions['makeavailable'] = get_lang('MakeAvailable');
+$form_actions['makeunavailable'] = get_lang('MakeUnavailable');
+$table->set_form_actions($form_actions);
+$table->display();
+
+/*
+==============================================================================
+		FOOTER 
+==============================================================================
+*/
+Display :: display_footer();
+?>

+ 279 - 0
main/admin/resume_session.php

@@ -0,0 +1,279 @@
+<?php
+// $Id: course_list.php,v 1.15.2.1 2005/10/31 09:15:57 olivierb78 Exp $
+/*
+==============================================================================
+	Dokeos - elearning and course management software
+
+	Copyright (c) 2004 Dokeos S.A.
+	Copyright (c) 2003 University of Ghent (UGent)
+	Copyright (c) 2001 Universite catholique de Louvain (UCL)
+	Copyright (c) Olivier Brouckaert
+
+	For a full list of contributors, see "credits.txt".
+	The full license can be read in "license.txt".
+
+	This program is free software; you can redistribute it and/or
+	modify it under the terms of the GNU General Public License
+	as published by the Free Software Foundation; either version 2
+	of the License, or (at your option) any later version.
+
+	See the GNU General Public License for more details.
+
+	Contact: Dokeos, 181 rue Royale, B-1000 Brussels, Belgium, info@dokeos.com
+==============================================================================
+*/
+/**
+============================================================================== 
+	@author Bart Mollet
+*	@package dokeos.admin
+============================================================================== 
+*/
+/*
+==============================================================================
+		INIT SECTION
+==============================================================================
+*/
+$langFile = 'admin';
+$cidReset = true;
+require ('../inc/global.inc.php');
+api_protect_admin_script();
+$tool_name = "Résumé de la session";
+$interbreadcrumb[]=array("url" => "index.php","name" => get_lang('AdministrationTools'));
+$interbreadcrumb[]=array("url" => "session_list.php","name" => "Liste des sessions");
+
+$tbl_session=Database::get_main_table(MAIN_SESSION_TABLE);
+$tbl_session_rel_class=Database::get_main_table(MAIN_SESSION_CLASS_TABLE);
+$tbl_session_rel_course=Database::get_main_table(MAIN_SESSION_COURSE_TABLE);
+$tbl_course=Database::get_main_table(MAIN_COURSE_TABLE);
+$tbl_user=Database::get_main_table(MAIN_USER_TABLE);
+$tbl_session_rel_user=Database::get_main_table(MAIN_SESSION_USER_TABLE);
+$tbl_session_rel_course_rel_user=Database::get_main_table(MAIN_SESSION_COURSE_USER_TABLE);
+$tbl_class=Database::get_main_table(MAIN_CLASS_TABLE);
+$tbl_class_rel_user=Database::get_main_table(MAIN_CLASS_USER_TABLE);
+
+$id_session = $_GET['id_session'];
+
+
+
+if($_GET['action'] == 'delete')
+{
+	$isChecked = $_GET['isChecked'];
+	if(is_array($idChecked))
+	{
+		$idChecked="'".implode("','",$idChecked)."'";
+
+		api_sql_query("DELETE FROM $tbl_session_rel_course WHERE id_session='$id_session' AND course_code IN($idChecked)",__FILE__,__LINE__);
+		
+		$nbr_affected_rows=mysql_affected_rows();
+
+		api_sql_query("DELETE FROM $tbl_session_rel_course_rel_user WHERE id_session='$id_session' AND course_code IN($idChecked)",__FILE__,__LINE__);
+
+		api_sql_query("UPDATE $tbl_session SET nbr_courses=nbr_courses-$nbr_affected_rows WHERE id='$id_session'",__FILE__,__LINE__);
+	}
+	
+	if(!empty($_GET['class'])){
+		api_sql_query("DELETE FROM $tbl_session_rel_class WHERE session_id='$id_session' AND class_id=".$_GET['class'],__FILE__,__LINE__);
+		
+		$nbr_affected_rows=mysql_affected_rows();
+
+		api_sql_query("UPDATE $tbl_session SET nbr_classes=nbr_classes-$nbr_affected_rows WHERE id='$id_session'",__FILE__,__LINE__);
+		
+	}
+	
+	if(!empty($_GET['user'])){
+		api_sql_query("DELETE FROM $tbl_session_rel_user WHERE id_session='$id_session' AND id_user=".$_GET['user'],__FILE__,__LINE__);
+		$nbr_affected_rows=mysql_affected_rows();
+		api_sql_query("UPDATE $tbl_session SET nbr_users=nbr_users-$nbr_affected_rows WHERE id='$id_session'",__FILE__,__LINE__);
+		
+		api_sql_query("DELETE FROM $tbl_session_rel_course_rel_user WHERE id_session='$id_session' AND id_user=".$_GET['user'],__FILE__,__LINE__);
+		$nbr_affected_rows=mysql_affected_rows();
+		api_sql_query("UPDATE $tbl_session_rel_course SET nbr_users=nbr_users-$nbr_affected_rows WHERE id_session='$id_session'",__FILE__,__LINE__);
+	}
+}		
+
+$sql = 'SELECT name, nbr_courses, nbr_users, nbr_classes, DATE_FORMAT(date_start,"%d-%m-%Y") as date_start, DATE_FORMAT(date_end,"%d-%m-%Y") as date_end, lastname, firstname, username
+		FROM '.$tbl_session.' 
+		LEFT JOIN '.$tbl_user.'
+			ON id_coach = user_id
+		WHERE '.$tbl_session.'.id='.$id_session;
+
+$rs = api_sql_query($sql, __FILE__, __LINE__);
+$session = api_store_result($rs);
+$session = $session[0];
+
+
+
+Display::display_header($tool_name);
+
+api_display_tool_title($tool_name);
+?>
+<!-- General properties -->
+<table class="data_table" width="100%">
+<tr>
+  <th colspan="2">Propriétés générales
+  	<a href="session_edit.php?page=resume_session.php&id=<?php echo $id_session; ?>"><img src="../img/edit.gif" border="0" align="absmiddle" title="Editer"></a></th>
+  </th>
+</tr>
+<tr>
+	<td>Nom de la session :</td>
+	<td><?php echo $session['name'] ?></td>
+</tr>
+<tr>
+	<td>Coach général :</td>
+	<td><?php echo $session['lastname'].' '.$session['firstname'].' ('.$session['username'].')' ?></td>
+</tr>
+<tr>
+	<td>Dates :</td>	
+	<td>
+	<?php 
+		if($session['date_start']=='00-00-0000')
+			echo 'Pas de limites de temps';
+		else
+			echo 'Du '.$session['date_start'].' au '.$session['date_end'];
+		 ?>
+	</td>
+</tr>
+</table>
+
+<br />
+
+<!--List of courses -->
+<table class="data_table" width="100%">
+<tr>
+  <th colspan="4">Liste des cours
+  	<a href="add_courses_to_session.php?page=resume_session.php&id_session=<?php echo $id_session; ?>"><img src="../img/edit.gif" border="0" align="absmiddle" title="Editer"></a></th>
+  </th>
+</tr>
+<tr>
+  <tr>
+  <th width="35%">Titre du cours</th>
+  <th width="30%">Coach du cours</th>
+  <th width="20%">Nombre d'utilisateurs</th>
+  <th width="15%">Actions</th>
+</tr>
+</tr>
+<?php
+if($session['nbr_courses']==0){
+	echo '
+		<tr>
+			<td colspan="4">Pas de cours pour cette session</td>
+		</tr>';
+}
+else {
+	$sql = "SELECT code,title,nbr_users, lastname, firstname, username
+			FROM $tbl_course,$tbl_session_rel_course 
+			LEFT JOIN $tbl_user
+				ON $tbl_session_rel_course.id_coach = $tbl_user.user_id
+			WHERE course_code=code
+			AND id_session='$id_session'
+			ORDER BY title";
+	$result=api_sql_query($sql,__FILE__,__LINE__);
+	$courses=api_store_result($result);
+	foreach($courses as $course){
+		if(empty($course['username']))
+			$coach = 'Aucun';
+		else
+			$coach = $course['lastname'].' '.$course['firstname'].' ('.$course['username'].')';
+		echo '
+		<tr>
+			<td>'.$course['title'].' ('.$course['code'].')</td>
+			<td>'.$coach.'</td>
+			<td>'.$course['nbr_users'].'</td>
+			<td>
+				<a href="session_course_edit.php?id_session='.$id_session.'&page=resume_session.php&course_code='.$course['code'].'"><img src="../img/edit.gif" border="0" align="absmiddle" title="Editer"></a>
+				<a href="'.$_SERVER['PHP_SELF'].'?id_session='.$id_session.'&action=delete&idChecked[]='.$course['code'].'" onclick="javascript:if(!confirm(\'Veuillez confirmer votre choix.\')) return false;"><img src="../img/delete.gif" border="0" align="absmiddle" title="Effacer"></a>
+			</td>
+		</tr>';
+	}
+}
+?>
+</table>
+
+<br />
+
+<!--List of courses -->
+<table class="data_table" width="100%">
+<tr>
+  <th colspan="4">Liste des utilisateurs
+  	<a href="add_users_to_session.php?page=resume_session.php&id_session=<?php echo $id_session; ?>"><img src="../img/edit.gif" border="0" align="absmiddle" title="Editer"></a></th>
+  </th>
+</tr>
+</tr>
+<?php
+if($session['nbr_users']==0){
+	echo '
+		<tr>
+			<td colspan="2">Pas d\'utilisateurs pour cette session</td>
+		</tr>';
+}
+else {
+	/*
+	$sql = "SELECT $tbl_user.user_id, lastname, firstname, username, name as class_name, $tbl_class.id as class_id
+			FROM $tbl_user
+			INNER JOIN $tbl_class_rel_user
+				ON $tbl_class_rel_user.user_id = $tbl_user.user_id
+			INNER JOIN $tbl_class
+				ON $tbl_class_rel_user.class_id = $tbl_class.id
+			INNER JOIN $tbl_session_rel_class
+				ON $tbl_session_rel_class.class_id = $tbl_class_rel_user.class_id
+				AND session_id='$id_session'
+			ORDER BY lastname";
+	
+	$result=api_sql_query($sql,__FILE__,__LINE__);
+	$classesusers=api_store_result($result);
+	
+	$classes = array();
+	foreach($classesusers as $user){
+		if(!in_array($user['class_id'],$classes)){
+			echo '<tr>
+					<td width="90%">
+						<b>Classe : '.$user['class_name'].'</b>
+					</td>
+					<td>
+						<a href="'.$_SERVER['PHP_SELF'].'?id_session='.$id_session.'&action=delete&class='.$user['class_id'].'" onclick="javascript:if(!confirm(\'Veuillez confirmer votre choix.\')) return false;"><img src="../img/delete.gif" border="0" align="absmiddle" title="Effacer"></a>
+					</td>
+				  </tr>';
+			$classes[]=$user['class_id'];
+		}
+		echo '
+		<tr>
+			<td colspan="2">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;'.$user['lastname'].' '.$user['firstname'].' ('.$user['username'].')</td>
+		</tr>';
+	}
+	*/ // classe development, obsolete for the moment
+	
+	$sql = 'SELECT '.$tbl_user.'.user_id, lastname, firstname, username
+			FROM '.$tbl_user.'
+			INNER JOIN '.$tbl_session_rel_user.'
+				ON '.$tbl_user.'.user_id = '.$tbl_session_rel_user.'.id_user
+				AND '.$tbl_session_rel_user.'.id_session = '.$id_session.'
+			ORDER BY lastname, firstname';
+	
+	$result=api_sql_query($sql,__FILE__,__LINE__);
+	$users=api_store_result($result);
+	foreach($users as $user){
+		echo '<tr>
+					<td width="90%">
+						<b>'.$user['lastname'].' '.$user['firstname'].' ('.$user['username'].')</b>
+					</td>
+					<td>
+						<a href="'.$_SERVER['PHP_SELF'].'?id_session='.$id_session.'&action=delete&user='.$user['user_id'].'" onclick="javascript:if(!confirm(\'Veuillez confirmer votre choix.\')) return false;"><img src="../img/delete.gif" border="0" align="absmiddle" title="Effacer"></a>
+					</td>
+				  </tr>';
+	}
+}
+?>
+</table>
+<?php
+
+/*
+==============================================================================
+		FOOTER 
+==============================================================================
+*/
+Display :: display_footer();
+?> 
+
+
+
+

+ 291 - 0
main/admin/session_add.php

@@ -0,0 +1,291 @@
+<?php
+$langFile='admin';
+
+$cidReset=true;
+
+include('../inc/global.inc.php');
+
+api_protect_admin_script();
+
+$formSent=0;
+$errorMsg='';
+
+$tbl_user=Database::get_main_table(MAIN_USER_TABLE);
+$tbl_session=Database::get_main_table(MAIN_SESSION_TABLE);
+
+$tool_name = get_lang('AddSession');
+
+$interbreadcrumb[]=array("url" => "index.php","name" => get_lang('AdministrationTools'));
+$interbreadcrumb[]=array("url" => "session_list.php","name" => get_lang('SessionList'));
+
+if($_POST['formSent'])
+{
+	$formSent=1;
+
+	$name=trim(stripslashes($_POST['name']));
+	$year_start=intval($_POST['year_start']);
+	$month_start=intval($_POST['month_start']);
+	$day_start=intval($_POST['day_start']);
+	$year_end=intval($_POST['year_end']);
+	$month_end=intval($_POST['month_end']);
+	$day_end=intval($_POST['day_end']);
+	$id_coach=intval($_POST['id_coach']);
+
+	if(empty($_POST['nolimit'])){
+		$date_start="$year_start-".(($month_start < 10)?"0$month_start":$month_start)."-".(($day_start < 10)?"0$day_start":$day_start);
+		$date_end="$year_end-".(($month_end < 10)?"0$month_end":$month_end)."-".(($day_end < 10)?"0$day_end":$day_end);
+	}
+	else {
+		$date_start="000-00-00";
+		$date_end="000-00-00";
+	}
+	if(empty($name)) $errorMsg=get_lang('SessionNameIsRequired');
+	elseif(empty($_POST['nolimit']) && (!$month_start || !$day_start || !$year_start || !checkdate($month_start,$day_start,$year_start))) $errorMsg="Veuillez introduire une date de début valide !";
+	elseif(empty($_POST['nolimit']) && (!$month_end || !$day_end || !$year_end || !checkdate($month_end,$day_end,$year_end))) $errorMsg="Veuillez introduire une date de fin valide !";
+	elseif(empty($_POST['nolimit']) && $date_start >= $date_end) $errorMsg="La date de fin doit être postérieure à la date de début !";
+	else
+	{
+		$rs = api_sql_query("SELECT 1 FROM $tbl_session WHERE name='".addslashes($name)."'");
+		if(mysql_num_rows($rs)){
+			$errorMsg = get_lang('SessionNameSoonExists');
+		}
+		else {
+			api_sql_query("INSERT INTO $tbl_session(name,date_start,date_end,id_coach) VALUES('".addslashes($name)."','$date_start','$date_end','$id_coach')",__FILE__,__LINE__);
+			$id_session=mysql_insert_id();
+	
+			header('Location: add_courses_to_session.php?id_session='.$id_session.'&add=true');
+			exit();
+		}
+	}
+}
+
+$sql="SELECT user_id,lastname,firstname,username FROM $tbl_user WHERE status='1' ORDER BY lastname,firstname,username";
+
+$result=api_sql_query($sql,__FILE__,__LINE__);
+
+$Coaches=api_store_result($result);
+
+$thisYear=date('Y');
+$thisMonth=date('m');
+$thisDay=date('d');
+
+Display::display_header($tool_name);
+
+api_display_tool_title($tool_name);
+?>
+
+<form method="post" name="form" action="<?php echo $_SERVER['PHP_SELF']; ?>" style="margin:0px;">
+<input type="hidden" name="formSent" value="1">
+
+<table border="0" cellpadding="5" cellspacing="0" width="550">
+
+<?php
+if(!empty($errorMsg))
+{
+?>
+
+<tr>
+  <td colspan="2">
+
+<?php
+	Display::display_normal_message($errorMsg);
+?>
+
+  </td>
+</tr>
+
+<?php
+}
+?>
+
+<tr>
+  <td width="30%"><?php echo get_lang('SessionName') ?>&nbsp;&nbsp;</td>
+  <td width="70%"><input type="text" name="name" size="50" maxlength="50" value="<?php if($formSent) echo htmlentities($name); ?>"></td>
+</tr>
+<tr>
+  <td width="30%"><?php echo get_lang('CoachName') ?>&nbsp;&nbsp;</td>
+  <td width="70%"><select name="id_coach" value="true" style="width:250px;">
+	<option value="0">Aucun</option>
+
+<?php
+foreach($Coaches as $enreg)
+{
+?>
+
+	<option value="<?php echo $enreg['user_id']; ?>" <?php if($sent && $enreg['user_id'] == $id_coach) echo 'selected="selected"'; ?>><?php echo $enreg['lastname'].' '.$enreg['firstname'].' ('.$enreg['username'].')'; ?></option>
+
+<?php
+}
+
+unset($Coaches);
+?>
+
+  </select></td>
+</tr>
+<tr>
+  <td width="30%"><?php echo get_lang('NoTimeLimits') ?></td>
+  <td width="70%">
+  	<input type="checkbox" name="nolimit" onChange="setDisable(this)" />
+  </td>
+<tr>
+  <td width="30%"><?php echo get_lang('DateStart') ?>&nbsp;&nbsp;</td>
+  <td width="70%">
+  <select name="day_start">
+	<option value="1">01</option>
+	<option value="2" <?php if((!$formSent && $thisDay == 2) || ($formSent && $day_start == 2)) echo 'selected="selected"'; ?> >02</option>
+	<option value="3" <?php if((!$formSent && $thisDay == 3) || ($formSent && $day_start == 3)) echo 'selected="selected"'; ?> >03</option>
+	<option value="4" <?php if((!$formSent && $thisDay == 4) || ($formSent && $day_start == 4)) echo 'selected="selected"'; ?> >04</option>
+	<option value="5" <?php if((!$formSent && $thisDay == 5) || ($formSent && $day_start == 5)) echo 'selected="selected"'; ?> >05</option>
+	<option value="6" <?php if((!$formSent && $thisDay == 6) || ($formSent && $day_start == 6)) echo 'selected="selected"'; ?> >06</option>
+	<option value="7" <?php if((!$formSent && $thisDay == 7) || ($formSent && $day_start == 7)) echo 'selected="selected"'; ?> >07</option>
+	<option value="8" <?php if((!$formSent && $thisDay == 8) || ($formSent && $day_start == 8)) echo 'selected="selected"'; ?> >08</option>
+	<option value="9" <?php if((!$formSent && $thisDay == 9) || ($formSent && $day_start == 9)) echo 'selected="selected"'; ?> >09</option>
+	<option value="10" <?php if((!$formSent && $thisDay == 10) || ($formSent && $day_start == 10)) echo 'selected="selected"'; ?> >10</option>
+	<option value="11" <?php if((!$formSent && $thisDay == 11) || ($formSent && $day_start == 11)) echo 'selected="selected"'; ?> >11</option>
+	<option value="12" <?php if((!$formSent && $thisDay == 12) || ($formSent && $day_start == 12)) echo 'selected="selected"'; ?> >12</option>
+	<option value="13" <?php if((!$formSent && $thisDay == 13) || ($formSent && $day_start == 13)) echo 'selected="selected"'; ?> >13</option>
+	<option value="14" <?php if((!$formSent && $thisDay == 14) || ($formSent && $day_start == 14)) echo 'selected="selected"'; ?> >14</option>
+	<option value="15" <?php if((!$formSent && $thisDay == 15) || ($formSent && $day_start == 15)) echo 'selected="selected"'; ?> >15</option>
+	<option value="16" <?php if((!$formSent && $thisDay == 16) || ($formSent && $day_start == 16)) echo 'selected="selected"'; ?> >16</option>
+	<option value="17" <?php if((!$formSent && $thisDay == 17) || ($formSent && $day_start == 17)) echo 'selected="selected"'; ?> >17</option>
+	<option value="18" <?php if((!$formSent && $thisDay == 18) || ($formSent && $day_start == 18)) echo 'selected="selected"'; ?> >18</option>
+	<option value="19" <?php if((!$formSent && $thisDay == 19) || ($formSent && $day_start == 19)) echo 'selected="selected"'; ?> >19</option>
+	<option value="20" <?php if((!$formSent && $thisDay == 20) || ($formSent && $day_start == 20)) echo 'selected="selected"'; ?> >20</option>
+	<option value="21" <?php if((!$formSent && $thisDay == 21) || ($formSent && $day_start == 21)) echo 'selected="selected"'; ?> >21</option>
+	<option value="22" <?php if((!$formSent && $thisDay == 22) || ($formSent && $day_start == 22)) echo 'selected="selected"'; ?> >22</option>
+	<option value="23" <?php if((!$formSent && $thisDay == 23) || ($formSent && $day_start == 23)) echo 'selected="selected"'; ?> >23</option>
+	<option value="24" <?php if((!$formSent && $thisDay == 24) || ($formSent && $day_start == 24)) echo 'selected="selected"'; ?> >24</option>
+	<option value="25" <?php if((!$formSent && $thisDay == 25) || ($formSent && $day_start == 25)) echo 'selected="selected"'; ?> >25</option>
+	<option value="26" <?php if((!$formSent && $thisDay == 26) || ($formSent && $day_start == 26)) echo 'selected="selected"'; ?> >26</option>
+	<option value="27" <?php if((!$formSent && $thisDay == 27) || ($formSent && $day_start == 27)) echo 'selected="selected"'; ?> >27</option>
+	<option value="28" <?php if((!$formSent && $thisDay == 28) || ($formSent && $day_start == 28)) echo 'selected="selected"'; ?> >28</option>
+	<option value="29" <?php if((!$formSent && $thisDay == 29) || ($formSent && $day_start == 29)) echo 'selected="selected"'; ?> >29</option>
+	<option value="30" <?php if((!$formSent && $thisDay == 30) || ($formSent && $day_start == 30)) echo 'selected="selected"'; ?> >30</option>
+	<option value="31" <?php if((!$formSent && $thisDay == 31) || ($formSent && $day_start == 31)) echo 'selected="selected"'; ?> >31</option>
+  </select>
+  /
+  <select name="month_start">
+	<option value="1">01</option>
+	<option value="2" <?php if((!$formSent && $thisMonth == 2) || ($formSent && $month_start == 2)) echo 'selected="selected"'; ?> >02</option>
+	<option value="3" <?php if((!$formSent && $thisMonth == 3) || ($formSent && $month_start == 3)) echo 'selected="selected"'; ?> >03</option>
+	<option value="4" <?php if((!$formSent && $thisMonth == 4) || ($formSent && $month_start == 4)) echo 'selected="selected"'; ?> >04</option>
+	<option value="5" <?php if((!$formSent && $thisMonth == 5) || ($formSent && $month_start == 5)) echo 'selected="selected"'; ?> >05</option>
+	<option value="6" <?php if((!$formSent && $thisMonth == 6) || ($formSent && $month_start == 6)) echo 'selected="selected"'; ?> >06</option>
+	<option value="7" <?php if((!$formSent && $thisMonth == 7) || ($formSent && $month_start == 7)) echo 'selected="selected"'; ?> >07</option>
+	<option value="8" <?php if((!$formSent && $thisMonth == 8) || ($formSent && $month_start == 8)) echo 'selected="selected"'; ?> >08</option>
+	<option value="9" <?php if((!$formSent && $thisMonth == 9) || ($formSent && $month_start == 9)) echo 'selected="selected"'; ?> >09</option>
+	<option value="10" <?php if((!$formSent && $thisMonth == 10) || ($formSent && $month_start == 10)) echo 'selected="selected"'; ?> >10</option>
+	<option value="11" <?php if((!$formSent && $thisMonth == 11) || ($formSent && $month_start == 11)) echo 'selected="selected"'; ?> >11</option>
+	<option value="12" <?php if((!$formSent && $thisMonth == 12) || ($formSent && $month_start == 12)) echo 'selected="selected"'; ?> >12</option>
+  </select>
+  /
+  <select name="year_start">
+  
+<?php
+for($i=$thisYear-5;$i <= ($thisYear+5);$i++)
+{
+?>
+
+	<option value="<?php echo $i; ?>" <?php if((!$formSent && $thisYear == $i) || ($formSent && $year_start == $i)) echo 'selected="selected"'; ?> ><?php echo $i; ?></option>
+
+<?php
+}
+?>
+
+  </select>
+  </td>
+</tr>
+<tr>
+  <td width="30%"><?php echo get_lang('DateEnd') ?>&nbsp;&nbsp;</td>
+  <td width="70%">
+  <select name="day_end">
+	<option value="1">01</option>
+	<option value="2" <?php if((!$formSent && $thisDay == 2) || ($formSent && $day_end == 2)) echo 'selected="selected"'; ?> >02</option>
+	<option value="3" <?php if((!$formSent && $thisDay == 3) || ($formSent && $day_end == 3)) echo 'selected="selected"'; ?> >03</option>
+	<option value="4" <?php if((!$formSent && $thisDay == 4) || ($formSent && $day_end == 4)) echo 'selected="selected"'; ?> >04</option>
+	<option value="5" <?php if((!$formSent && $thisDay == 5) || ($formSent && $day_end == 5)) echo 'selected="selected"'; ?> >05</option>
+	<option value="6" <?php if((!$formSent && $thisDay == 6) || ($formSent && $day_end == 6)) echo 'selected="selected"'; ?> >06</option>
+	<option value="7" <?php if((!$formSent && $thisDay == 7) || ($formSent && $day_end == 7)) echo 'selected="selected"'; ?> >07</option>
+	<option value="8" <?php if((!$formSent && $thisDay == 8) || ($formSent && $day_end == 8)) echo 'selected="selected"'; ?> >08</option>
+	<option value="9" <?php if((!$formSent && $thisDay == 9) || ($formSent && $day_end == 9)) echo 'selected="selected"'; ?> >09</option>
+	<option value="10" <?php if((!$formSent && $thisDay == 10) || ($formSent && $day_end == 10)) echo 'selected="selected"'; ?> >10</option>
+	<option value="11" <?php if((!$formSent && $thisDay == 11) || ($formSent && $day_end == 11)) echo 'selected="selected"'; ?> >11</option>
+	<option value="12" <?php if((!$formSent && $thisDay == 12) || ($formSent && $day_end == 12)) echo 'selected="selected"'; ?> >12</option>
+	<option value="13" <?php if((!$formSent && $thisDay == 13) || ($formSent && $day_end == 13)) echo 'selected="selected"'; ?> >13</option>
+	<option value="14" <?php if((!$formSent && $thisDay == 14) || ($formSent && $day_end == 14)) echo 'selected="selected"'; ?> >14</option>
+	<option value="15" <?php if((!$formSent && $thisDay == 15) || ($formSent && $day_end == 15)) echo 'selected="selected"'; ?> >15</option>
+	<option value="16" <?php if((!$formSent && $thisDay == 16) || ($formSent && $day_end == 16)) echo 'selected="selected"'; ?> >16</option>
+	<option value="17" <?php if((!$formSent && $thisDay == 17) || ($formSent && $day_end == 17)) echo 'selected="selected"'; ?> >17</option>
+	<option value="18" <?php if((!$formSent && $thisDay == 18) || ($formSent && $day_end == 18)) echo 'selected="selected"'; ?> >18</option>
+	<option value="19" <?php if((!$formSent && $thisDay == 19) || ($formSent && $day_end == 19)) echo 'selected="selected"'; ?> >19</option>
+	<option value="20" <?php if((!$formSent && $thisDay == 20) || ($formSent && $day_end == 20)) echo 'selected="selected"'; ?> >20</option>
+	<option value="21" <?php if((!$formSent && $thisDay == 21) || ($formSent && $day_end == 21)) echo 'selected="selected"'; ?> >21</option>
+	<option value="22" <?php if((!$formSent && $thisDay == 22) || ($formSent && $day_end == 22)) echo 'selected="selected"'; ?> >22</option>
+	<option value="23" <?php if((!$formSent && $thisDay == 23) || ($formSent && $day_end == 23)) echo 'selected="selected"'; ?> >23</option>
+	<option value="24" <?php if((!$formSent && $thisDay == 24) || ($formSent && $day_end == 24)) echo 'selected="selected"'; ?> >24</option>
+	<option value="25" <?php if((!$formSent && $thisDay == 25) || ($formSent && $day_end == 25)) echo 'selected="selected"'; ?> >25</option>
+	<option value="26" <?php if((!$formSent && $thisDay == 26) || ($formSent && $day_end == 26)) echo 'selected="selected"'; ?> >26</option>
+	<option value="27" <?php if((!$formSent && $thisDay == 27) || ($formSent && $day_end == 27)) echo 'selected="selected"'; ?> >27</option>
+	<option value="28" <?php if((!$formSent && $thisDay == 28) || ($formSent && $day_end == 28)) echo 'selected="selected"'; ?> >28</option>
+	<option value="29" <?php if((!$formSent && $thisDay == 29) || ($formSent && $day_end == 29)) echo 'selected="selected"'; ?> >29</option>
+	<option value="30" <?php if((!$formSent && $thisDay == 30) || ($formSent && $day_end == 30)) echo 'selected="selected"'; ?> >30</option>
+	<option value="31" <?php if((!$formSent && $thisDay == 31) || ($formSent && $day_end == 31)) echo 'selected="selected"'; ?> >31</option>
+  </select>
+  /
+  <select name="month_end">
+	<option value="1">01</option>
+	<option value="2" <?php if((!$formSent && $thisMonth == 2) || ($formSent && $month_end == 2)) echo 'selected="selected"'; ?> >02</option>
+	<option value="3" <?php if((!$formSent && $thisMonth == 3) || ($formSent && $month_end == 3)) echo 'selected="selected"'; ?> >03</option>
+	<option value="4" <?php if((!$formSent && $thisMonth == 4) || ($formSent && $month_end == 4)) echo 'selected="selected"'; ?> >04</option>
+	<option value="5" <?php if((!$formSent && $thisMonth == 5) || ($formSent && $month_end == 5)) echo 'selected="selected"'; ?> >05</option>
+	<option value="6" <?php if((!$formSent && $thisMonth == 6) || ($formSent && $month_end == 6)) echo 'selected="selected"'; ?> >06</option>
+	<option value="7" <?php if((!$formSent && $thisMonth == 7) || ($formSent && $month_end == 7)) echo 'selected="selected"'; ?> >07</option>
+	<option value="8" <?php if((!$formSent && $thisMonth == 8) || ($formSent && $month_end == 8)) echo 'selected="selected"'; ?> >08</option>
+	<option value="9" <?php if((!$formSent && $thisMonth == 9) || ($formSent && $month_end == 9)) echo 'selected="selected"'; ?> >09</option>
+	<option value="10" <?php if((!$formSent && $thisMonth == 10) || ($formSent && $month_end == 10)) echo 'selected="selected"'; ?> >10</option>
+	<option value="11" <?php if((!$formSent && $thisMonth == 11) || ($formSent && $month_end == 11)) echo 'selected="selected"'; ?> >11</option>
+	<option value="12" <?php if((!$formSent && $thisMonth == 12) || ($formSent && $month_end == 12)) echo 'selected="selected"'; ?> >12</option>
+  </select>
+  /
+  <select name="year_end">
+
+<?php
+for($i=$thisYear-5;$i <= ($thisYear+5);$i++)
+{
+?>
+
+	<option value="<?php echo $i; ?>" <?php if((!$formSent && ($thisYear+1) == $i) || ($formSent && $year_end == $i)) echo 'selected="selected"'; ?> ><?php echo $i; ?></option>
+
+<?php
+}
+?>
+
+  </select>
+  </td>
+</tr>
+<tr>
+  <td>&nbsp;</td>
+  <td><input type="submit" value="<?php echo get_lang('NextStep') ?>"></td>
+</tr>
+
+</table>
+
+</form>
+<script type="text/javascript">
+
+function setDisable(select){
+	
+	document.form.day_start.disabled = (select.checked) ? true : false;
+	document.form.month_start.disabled = (select.checked) ? true : false;
+	document.form.year_start.disabled = (select.checked) ? true : false;
+	
+	document.form.day_end.disabled = (select.checked) ? true : false;
+	document.form.month_end.disabled = (select.checked) ? true : false;
+	document.form.year_end.disabled = (select.checked) ? true : false;
+	
+	
+}
+</script>
+<?php
+Display::display_footer();
+?>

+ 128 - 0
main/admin/session_course_edit.php

@@ -0,0 +1,128 @@
+<?php
+$langFile='admin';
+
+$cidReset=true;
+
+include('../inc/global.inc.php');
+
+api_protect_admin_script();
+
+$id_session=intval($_GET['id_session']);
+$course_code=trim(stripslashes($_GET['course_code']));
+
+$formSent=0;
+$errorMsg='';
+
+$tbl_user=Database::get_main_table(MAIN_USER_TABLE);
+$tbl_course=Database::get_main_table(MAIN_COURSE_TABLE);
+$tbl_session=Database::get_main_table(MAIN_SESSION_TABLE);
+$tbl_session_course=Database::get_main_table(MAIN_SESSION_COURSE_TABLE);
+
+$tool_name=get_lang('ModifySessionCourse');
+
+$result=api_sql_query("SELECT name,title FROM $tbl_session_course,$tbl_session,$tbl_course WHERE id_session=id AND course_code=code AND id_session='$id_session' AND course_code='".addslashes($course_code)."'",__FILE__,__LINE__);
+
+if(!list($session_name,$course_title)=mysql_fetch_row($result))
+{
+	header('Location: session_course_list.php?id_session='.$id_session);
+	exit();
+}
+
+$interbreadcrumb[]=array("url" => "index.php","name" => get_lang('AdministrationTools'));
+$interbreadcrumb[]=array("url" => "session_list.php","name" => get_lang("SessionList"));
+$interbreadcrumb[]=array("url" => "session_course_list.php?id_session=$id_session","name" => get_lang("CourseSessionList")." &quot;".htmlentities($session_name)."&quot;");
+
+if($_POST['formSent'])
+{
+	$formSent=1;
+
+	$id_coach=intval($_POST['id_coach']);
+
+	if(!$id_coach) $errorMsg=gget_lang("SelectACoach");
+	else
+	{
+		api_sql_query("UPDATE $tbl_session_course
+					   SET id_coach='$id_coach'
+					   WHERE id_session='$id_session' AND course_code='$course_code'",__FILE__,__LINE__);
+		header('Location: '.$_GET['page'].'?id_session='.$id_session);
+		exit();
+	}
+}
+else
+{
+	$result=api_sql_query("SELECT id_coach FROM $tbl_session_course WHERE id_session='$id_session' AND course_code='$course_code'",__FILE__,__LINE__);
+
+	if(!$infos=mysql_fetch_array($result))
+	{
+		//header('Location: '.$_GET['page'].'?id_session='.$id_session);
+		exit();
+	}
+}
+
+$sql="SELECT user_id,lastname,firstname,username FROM $tbl_user WHERE status='1' ORDER BY lastname,firstname,username";
+
+$result=api_sql_query($sql,__FILE__,__LINE__);
+
+$Coaches=api_store_result($result);
+
+Display::display_header($tool_name);
+
+api_display_tool_title($tool_name);
+?>
+
+<form method="post" action="<?php echo $_SERVER['PHP_SELF']; ?>?id_session=<?php echo $id_session; ?>&course_code=<?php echo urlencode($course_code); ?>&page=<?php echo $_GET['page'] ?>" style="margin:0px;">
+<input type="hidden" name="formSent" value="1">
+
+<table border="0" cellpadding="5" cellspacing="0" width="550">
+
+<?php
+if(!empty($errorMsg))
+{
+?>
+
+<tr>
+  <td colspan="2">
+
+<?php
+	Display::display_normal_message($errorMsg);
+?>
+
+  </td>
+</tr>
+
+<?php
+}
+?>
+
+<tr>
+  <td width="30%"><?php echo get_lang("CoachName") ?>&nbsp;&nbsp;</td>
+  <td width="70%"><select name="id_coach" style="width:250px;">
+	<option value="0">----- <?php echo get_lang("Choose") ?> -----</option>
+
+<?php
+foreach($Coaches as $enreg)
+{
+?>
+
+	<option value="<?php echo $enreg['user_id']; ?>" <?php if((!$sent && $enreg['user_id'] == $infos['id_coach']) || ($sent && $enreg['user_id'] == $id_coach)) echo 'selected="selected"'; ?>><?php echo $enreg['lastname'].' '.$enreg['firstname'].' ('.$enreg['username'].')'; ?></option>
+
+<?php
+}
+
+unset($Coaches);
+?>
+
+  </select></td>
+</tr>
+<tr>
+  <td>&nbsp;</td>
+  <td><input type="submit" value="<?php echo get_lang('Ok'); ?>"></td>
+</tr>
+
+</table>
+
+</form>
+
+<?php
+Display::display_footer();
+?>

+ 106 - 0
main/admin/session_course_list.php

@@ -0,0 +1,106 @@
+<?php
+$langFile='admin';
+
+$cidReset=true;
+
+include('../inc/global.inc.php');
+
+api_protect_admin_script();
+
+$tbl_course=Database::get_main_table(MAIN_COURSE_TABLE);
+$tbl_session=Database::get_main_table(MAIN_SESSION_TABLE);
+$tbl_session_rel_course=Database::get_main_table(MAIN_SESSION_COURSE_TABLE);
+$tbl_session_rel_course_rel_user=Database::get_main_table(MAIN_SESSION_COURSE_USER_TABLE);
+
+$id_session=intval($_GET['id_session']);
+$page=intval($_GET['page']);
+$action=$_REQUEST['action'];
+$sort=in_array($_GET['sort'],array('title','nbr_users'))?$_GET['sort']:'title';
+
+$result=api_sql_query("SELECT name FROM $tbl_session WHERE id='$id_session'",__FILE__,__LINE__);
+
+if(!list($session_name)=mysql_fetch_row($result))
+{
+	header('Location: session_list.php');
+	exit();
+}
+
+if($action == 'delete')
+{
+	$idChecked = $_POST['idChecked'];
+	if(is_array($idChecked))
+	{
+		$idChecked="'".implode("','",$idChecked)."'";
+
+		api_sql_query("DELETE FROM $tbl_session_rel_course WHERE id_session='$id_session' AND course_code IN($idChecked)",__FILE__,__LINE__);
+
+		$nbr_affected_rows=mysql_affected_rows();
+
+		api_sql_query("DELETE FROM $tbl_session_rel_course_rel_user WHERE id_session='$id_session' AND course_code IN($idChecked)",__FILE__,__LINE__);
+
+		api_sql_query("UPDATE $tbl_session SET nbr_courses=nbr_courses-$nbr_affected_rows WHERE id='$id_session'",__FILE__,__LINE__);
+	}
+
+	header('Location: '.$PHP_SELF.'?id_session='.$id_session.'&sort='.$sort);
+	exit();
+}
+
+$limit=20;
+$from=$page * $limit;
+
+$result=api_sql_query("SELECT code,title,nbr_users FROM $tbl_session_rel_course,$tbl_course WHERE course_code=code AND id_session='$id_session' ORDER BY $sort LIMIT $from,".($limit+1),__FILE__,__LINE__);
+
+$Courses=api_store_result($result);
+
+$nbr_results=sizeof($Sessions);
+
+$tool_name = htmlentities($session_name).' : '.get_lang('CourseListInSession');
+
+$interbreadcrumb[]=array("url" => "index.php","name" => get_lang('AdministrationTools'));
+$interbreadcrumb[]=array("url" => "session_list.php","name" => get_lang('SessionList'));
+
+Display::display_header($tool_name);
+
+api_display_tool_title($tool_name);
+?>
+
+<div id="main">
+
+<form method="post" action="<?php echo $PHP_SELF; ?>?id_session=<?php echo $id_session; ?>&sort=<?php echo $sort; ?>" onsubmit="javascript:if(!confirm('Veuillez confirmer votre choix.')) return false;">
+
+<br>
+
+
+<?php
+$tableHeader = array();
+$tableHeader[] = array(' ');
+$tableHeader[] = array(get_lang('CourseTitle'));
+$tableHeader[] = array(get_lang('NbUsers'));
+$tableHeader[] = array(get_lang('Actions'));
+
+
+$tableCourses = array();
+foreach($Courses as $key=>$enreg)
+{
+	$course = array();
+	$course[] = '<input type="checkbox" name="idChecked[]" value="'.$enreg['code'].'">';
+	$course[] = htmlentities($enreg['title']);
+	$course[] = '<a href="session_course_user_list.php?id_session='.$id_session.'&course_code='.$enreg['code'].'">'.$enreg['nbr_users'].' '.get_lang('Users').'</a>';
+	$course[] = '<a href="session_course_edit.php?id_session='.$id_session.'&page=session_course_list.php&course_code='.$enreg['code'].'"><img src="../img/edit.gif" border="0" align="absmiddle" title="'.get_lang('Edit').'"></a>
+				<a href="'.$PHP_SELF.'?id_session='.$id_session.'&sort='.$sort.'&action=delete&idChecked[]='.$enreg['code'].'" onclick="javascript:if(!confirm(\''.addslashes(htmlentities(get_lang("ConfirmYourChoice"))).'\')) return false;"><img src="../img/delete.gif" border="0" align="absmiddle" title="'.get_lang('Delete').'"></a>';
+	$tableCourses[] = $course;
+}
+echo '<form method="post" action="'.$PHP_SELF.'">';
+Display :: display_sortable_table($tableHeader, $tableCourses, array (), array ());
+echo '
+	<select name="action">
+	<option value="delete">'.get_lang('UnsubscribeCoursesFromSession').'</option>
+	</select>
+	<input type="submit" value="'.get_lang('Ok').'">
+	</form>';
+?>
+
+
+<?php
+Display::display_footer();
+?>

+ 107 - 0
main/admin/session_course_user_list.php

@@ -0,0 +1,107 @@
+<?php
+$langFile='admin';
+
+$cidReset=true;
+
+include('../inc/global.inc.php');
+
+api_protect_admin_script();
+
+$tbl_user=Database::get_main_table(MAIN_USER_TABLE);
+$tbl_course=Database::get_main_table(MAIN_COURSE_TABLE);
+$tbl_session=Database::get_main_table(MAIN_SESSION_TABLE);
+$tbl_session_rel_course=Database::get_main_table(MAIN_SESSION_COURSE_TABLE);
+$tbl_session_rel_course_rel_user=Database::get_main_table(MAIN_SESSION_COURSE_USER_TABLE);
+
+$id_session=intval($_GET['id_session']);
+$course_code=trim(stripslashes($_GET['course_code']));
+$page=intval($_GET['page']);
+$action=$_REQUEST['action'];
+$sort=in_array($_GET['sort'],array('lastname','firstname','username'))?$_GET['sort']:'lastname';
+
+$result=api_sql_query("SELECT name,title FROM $tbl_session,$tbl_course WHERE id='$id_session' AND code='".addslashes($course_code)."'",__FILE__,__LINE__);
+
+if(!list($session_name,$course_title)=mysql_fetch_row($result))
+{
+	header('Location: session_course_list.php?id_session='.$id_session);
+	exit();
+}
+
+if($action == 'delete')
+{
+	$idChecked = $_POST['idChecked'];
+	if(is_array($idChecked))
+	{
+		$idChecked=implode(',',$idChecked);
+
+		api_sql_query("DELETE FROM $tbl_session_rel_course_rel_user WHERE id_session='$id_session' AND course_code='".addslashes($course_code)."' AND id_user IN($idChecked)",__FILE__,__LINE__);
+
+		$nbr_affected_rows=mysql_affected_rows();
+
+		api_sql_query("UPDATE $tbl_session_rel_course SET nbr_users=nbr_users-$nbr_affected_rows WHERE id_session='$id_session' AND course_code='".addslashes($course_code)."'",__FILE__,__LINE__);
+	}
+
+}
+
+$limit=20;
+$from=$page * $limit;
+
+$result=api_sql_query("SELECT user_id,lastname,firstname,username FROM $tbl_session_rel_course_rel_user,$tbl_user WHERE user_id=id_user AND id_session='$id_session' AND course_code='".addslashes($course_code)."' ORDER BY $sort LIMIT $from,".($limit+1),__FILE__,__LINE__);
+
+$Users=api_store_result($result);
+
+$nbr_results=sizeof($Sessions);
+
+$tool_name = "Liste des utilisateurs inscrits au cours &quot;".htmlentities($course_title)."&quot; pour la session &quot;".htmlentities($session_name)."&quot;";
+
+$interbreadcrumb[]=array("url" => "index.php","name" => get_lang('AdministrationTools'));
+$interbreadcrumb[]=array("url" => "session_list.php","name" => "Liste des sessions");
+$interbreadcrumb[]=array("url" => "session_course_list.php?id_session=$id_session","name" => "Liste des cours de la session &quot;".htmlentities($session_name)."&quot;");
+
+Display::display_header($tool_name);
+
+api_display_tool_title($tool_name);
+
+$tableHeader = array();
+$tableHeader[] = array(' ');
+$tableHeader[] = array(get_lang('LastName'));
+$tableHeader[] = array(get_lang('FirstName'));
+$tableHeader[] = array(get_lang('LoginName'));
+$tableHeader[] = array(get_lang('Actions'));
+
+?>
+
+<div id="main">
+
+
+<?php
+$tableUsers = array();
+
+foreach($Users as $key=>$enreg)
+{
+	if($key == $limit)
+	{
+		break;
+	}
+	$user = array();
+	$user[] = '<input type="checkbox" name="idChecked[]" value="'.$enreg['user_id'].'">';
+	$user[] = htmlentities($enreg['lastname']);
+	$user[] = htmlentities($enreg['firstname']);
+	$user[] = htmlentities($enreg['username']);
+	$user[] = '<a href="'.$PHP_SELF.'?id_session='.$id_session.'&course_code='.urlencode($course_code).'&sort='.$sort.'&action=delete&idChecked[]='.$enreg['user_id'].'" onclick="javascript:if(!confirm(\''.get_lang('Confirm').'\')) return false;"><img src="../img/delete.gif" border="0" align="absmiddle" title="'.get_lang('Delete').'"></a>';
+	$tableUsers[] = $user;
+}
+echo '<form method="post" action="'.$PHP_SELF.'">';
+Display :: display_sortable_table($tableHeader, $tableUsers, array (), array ());
+
+echo '
+<select name="action">
+<option value="delete">'.get_lang('UnsubscribeUsersFromCourse').'</option>
+</select>
+<input type="submit" value="'.get_lang('Ok').'"></form>';
+
+
+echo '</div>';
+
+Display::display_footer();
+?>

+ 317 - 0
main/admin/session_edit.php

@@ -0,0 +1,317 @@
+<?php
+$langFile='admin';
+
+$cidReset=true;
+
+include('../inc/global.inc.php');
+
+api_protect_admin_script();
+
+$id=intval($_GET['id']);
+
+$formSent=0;
+$errorMsg='';
+
+$tbl_user=Database::get_main_table(MAIN_USER_TABLE);
+$tbl_session=Database::get_main_table(MAIN_SESSION_TABLE);
+
+$tool_name = get_lang('EditSession');
+
+$interbreadcrumb[]=array("url" => "index.php","name" => get_lang('AdministrationTools'));
+$interbreadcrumb[]=array("url" => "session_list.php","name" => get_lang('SessionList'));
+
+if($_POST['formSent'])
+{
+	$formSent=1;
+
+	$name=trim(stripslashes($_POST['name']));
+
+	$year_start=intval($_POST['year_start']);
+	$month_start=intval($_POST['month_start']);
+	$day_start=intval($_POST['day_start']);
+	$year_end=intval($_POST['year_end']);
+	$month_end=intval($_POST['month_end']);
+	$day_end=intval($_POST['day_end']);
+	$id_coach=intval($_POST['id_coach']);
+	
+	if(empty($_POST['nolimit'])){
+		$date_start="$year_start-".(($month_start < 10)?"0$month_start":$month_start)."-".(($day_start < 10)?"0$day_start":$day_start);
+		$date_end="$year_end-".(($month_end < 10)?"0$month_end":$month_end)."-".(($day_end < 10)?"0$day_end":$day_end);
+	}
+	else {
+		$date_start="000-00-00";
+		$date_end="000-00-00";
+	}
+	if(empty($name)) $errorMsg=get_lang('SessionNameIsRequired');
+	elseif(empty($_POST['nolimit']) && (!$month_start || !$day_start || !$year_start || !checkdate($month_start,$day_start,$year_start))) $errorMsg="Veuillez introduire une date de début valide !";
+	elseif(empty($_POST['nolimit']) && (!$month_end || !$day_end || !$year_end || !checkdate($month_end,$day_end,$year_end))) $errorMsg="Veuillez introduire une date de fin valide !";
+	elseif(empty($_POST['nolimit']) && $date_start >= $date_end) $errorMsg=get_lang('DateStartMoreThanDateEnd');
+	else
+	{
+		
+		$rs = api_sql_query("SELECT id FROM $tbl_session WHERE name='".addslashes($name)."'");
+		$exists = false;
+		while($row = mysql_fetch_array($rs)){
+			if($row['id']!=$id)
+				$exists = true;			
+		}
+		if($exists){
+			$errorMsg = get_lang('SessionNameSoonExists');
+		}
+		else {
+			api_sql_query("UPDATE $tbl_session
+					   SET name='".addslashes($name)."',
+						   date_start='$date_start',
+						   date_end='$date_end',
+						   id_coach='$id_coach'
+					   WHERE id='$id'",__FILE__,__LINE__);
+			header('Location: resume_session?id_session='.$id);
+			exit();
+		}
+	}
+}
+else
+{
+	$result=api_sql_query("SELECT name,date_start,date_end,id_coach FROM $tbl_session WHERE id='$id'",__FILE__,__LINE__);
+
+	if(!$infos=mysql_fetch_array($result))
+	{
+		header('Location: session_list.php');
+		exit();
+	}
+
+	list($year_start,$month_start,$day_start)=explode('-',$infos['date_start']);
+	list($year_end,$month_end,$day_end)=explode('-',$infos['date_end']);
+}
+
+$sql="SELECT user_id,lastname,firstname,username FROM $tbl_user WHERE status='1' ORDER BY lastname,firstname,username";
+
+$result=api_sql_query($sql,__FILE__,__LINE__);
+
+$Coaches=api_store_result($result);
+
+$thisYear=date('Y');
+
+Display::display_header($tool_name);
+
+api_display_tool_title($tool_name);
+?>
+
+<form method="post" name="form" action="<?php echo $_SERVER['PHP_SELF']; ?>?page=<?php echo $_GET['page'] ?>&id=<?php echo $id; ?>" style="margin:0px;">
+<input type="hidden" name="formSent" value="1">
+
+<table border="0" cellpadding="5" cellspacing="0" width="550">
+
+<?php
+if(!empty($errorMsg))
+{
+?>
+
+<tr>
+  <td colspan="2">
+
+<?php
+	Display::display_normal_message($errorMsg);
+?>
+
+  </td>
+</tr>
+
+<?php
+}
+?>
+
+<tr>
+  <td width="30%"><?php echo get_lang('SessionName') ?>&nbsp;&nbsp;</td>
+  <td width="70%"><input type="text" name="name" size="50" maxlength="50" value="<?php if($formSent) echo htmlentities($name); else echo htmlentities($infos['name']); ?>"></td>
+</tr>
+<tr>
+  <td width="30%"><?php echo get_lang('CoachName') ?>&nbsp;&nbsp;</td>
+  <td width="70%"><select name="id_coach" style="width:250px;">
+	<option value="0">----- <?php echo get_lang('Choose') ?> -----</option>
+
+<?php
+foreach($Coaches as $enreg)
+{
+?>
+
+	<option value="<?php echo $enreg['user_id']; ?>" <?php if((!$sent && $enreg['user_id'] == $infos['id_coach']) || ($sent && $enreg['user_id'] == $id_coach)) echo 'selected="selected"'; ?>><?php echo $enreg['lastname'].' '.$enreg['firstname'].' ('.$enreg['username'].')'; ?></option>
+
+<?php
+}
+
+unset($Coaches);
+?>
+
+  </select></td>
+</tr>
+<tr>
+  <td width="30%"><?php echo get_lang('NoTimeLimits') ?></td>
+  <td width="70%">
+  	<input type="checkbox" name="nolimit" onChange="setDisable(this)" <?php if($year_start=="0000") echo "checked"; ?>/>
+  </td>
+<tr>
+<tr>
+  <td width="30%"><?php echo get_lang('DateStartSession') ?>&nbsp;&nbsp;</td>
+  <td width="70%">
+  <select name="day_start">
+	<option value="1">01</option>
+	<option value="2" <?php if($day_start == 2) echo 'selected="selected"'; ?> >02</option>
+	<option value="3" <?php if($day_start == 3) echo 'selected="selected"'; ?> >03</option>
+	<option value="4" <?php if($day_start == 4) echo 'selected="selected"'; ?> >04</option>
+	<option value="5" <?php if($day_start == 5) echo 'selected="selected"'; ?> >05</option>
+	<option value="6" <?php if($day_start == 6) echo 'selected="selected"'; ?> >06</option>
+	<option value="7" <?php if($day_start == 7) echo 'selected="selected"'; ?> >07</option>
+	<option value="8" <?php if($day_start == 8) echo 'selected="selected"'; ?> >08</option>
+	<option value="9" <?php if($day_start == 9) echo 'selected="selected"'; ?> >09</option>
+	<option value="10" <?php if($day_start == 10) echo 'selected="selected"'; ?> >10</option>
+	<option value="11" <?php if($day_start == 11) echo 'selected="selected"'; ?> >11</option>
+	<option value="12" <?php if($day_start == 12) echo 'selected="selected"'; ?> >12</option>
+	<option value="13" <?php if($day_start == 13) echo 'selected="selected"'; ?> >13</option>
+	<option value="14" <?php if($day_start == 14) echo 'selected="selected"'; ?> >14</option>
+	<option value="15" <?php if($day_start == 15) echo 'selected="selected"'; ?> >15</option>
+	<option value="16" <?php if($day_start == 16) echo 'selected="selected"'; ?> >16</option>
+	<option value="17" <?php if($day_start == 17) echo 'selected="selected"'; ?> >17</option>
+	<option value="18" <?php if($day_start == 18) echo 'selected="selected"'; ?> >18</option>
+	<option value="19" <?php if($day_start == 19) echo 'selected="selected"'; ?> >19</option>
+	<option value="20" <?php if($day_start == 20) echo 'selected="selected"'; ?> >20</option>
+	<option value="21" <?php if($day_start == 21) echo 'selected="selected"'; ?> >21</option>
+	<option value="22" <?php if($day_start == 22) echo 'selected="selected"'; ?> >22</option>
+	<option value="23" <?php if($day_start == 23) echo 'selected="selected"'; ?> >23</option>
+	<option value="24" <?php if($day_start == 24) echo 'selected="selected"'; ?> >24</option>
+	<option value="25" <?php if($day_start == 25) echo 'selected="selected"'; ?> >25</option>
+	<option value="26" <?php if($day_start == 26) echo 'selected="selected"'; ?> >26</option>
+	<option value="27" <?php if($day_start == 27) echo 'selected="selected"'; ?> >27</option>
+	<option value="28" <?php if($day_start == 28) echo 'selected="selected"'; ?> >28</option>
+	<option value="29" <?php if($day_start == 29) echo 'selected="selected"'; ?> >29</option>
+	<option value="30" <?php if($day_start == 30) echo 'selected="selected"'; ?> >30</option>
+	<option value="31" <?php if($day_start == 31) echo 'selected="selected"'; ?> >31</option>
+  </select>
+  /
+  <select name="month_start">
+	<option value="1">01</option>
+	<option value="2" <?php if($month_start == 2) echo 'selected="selected"'; ?> >02</option>
+	<option value="3" <?php if($month_start == 3) echo 'selected="selected"'; ?> >03</option>
+	<option value="4" <?php if($month_start == 4) echo 'selected="selected"'; ?> >04</option>
+	<option value="5" <?php if($month_start == 5) echo 'selected="selected"'; ?> >05</option>
+	<option value="6" <?php if($month_start == 6) echo 'selected="selected"'; ?> >06</option>
+	<option value="7" <?php if($month_start == 7) echo 'selected="selected"'; ?> >07</option>
+	<option value="8" <?php if($month_start == 8) echo 'selected="selected"'; ?> >08</option>
+	<option value="9" <?php if($month_start == 9) echo 'selected="selected"'; ?> >09</option>
+	<option value="10" <?php if($month_start == 10) echo 'selected="selected"'; ?> >10</option>
+	<option value="11" <?php if($month_start == 11) echo 'selected="selected"'; ?> >11</option>
+	<option value="12" <?php if($month_start == 12) echo 'selected="selected"'; ?> >12</option>
+  </select>
+  /
+  <select name="year_start">
+
+<?php
+for($i=$thisYear-5;$i <= ($thisYear+5);$i++)
+{
+?>
+
+	<option value="<?php echo $i; ?>" <?php if($year_start == $i) echo 'selected="selected"'; ?> ><?php echo $i; ?></option>
+
+<?php
+}
+?>
+
+  </select>
+  </td>
+</tr>
+<tr>
+  <td width="30%"><?php echo get_lang('DateEndSession') ?>&nbsp;&nbsp;</td>
+  <td width="70%">
+  <select name="day_end">
+	<option value="1">01</option>
+	<option value="2" <?php if($day_end == 2) echo 'selected="selected"'; ?> >02</option>
+	<option value="3" <?php if($day_end == 3) echo 'selected="selected"'; ?> >03</option>
+	<option value="4" <?php if($day_end == 4) echo 'selected="selected"'; ?> >04</option>
+	<option value="5" <?php if($day_end == 5) echo 'selected="selected"'; ?> >05</option>
+	<option value="6" <?php if($day_end == 6) echo 'selected="selected"'; ?> >06</option>
+	<option value="7" <?php if($day_end == 7) echo 'selected="selected"'; ?> >07</option>
+	<option value="8" <?php if($day_end == 8) echo 'selected="selected"'; ?> >08</option>
+	<option value="9" <?php if($day_end == 9) echo 'selected="selected"'; ?> >09</option>
+	<option value="10" <?php if($day_end == 10) echo 'selected="selected"'; ?> >10</option>
+	<option value="11" <?php if($day_end == 11) echo 'selected="selected"'; ?> >11</option>
+	<option value="12" <?php if($day_end == 12) echo 'selected="selected"'; ?> >12</option>
+	<option value="13" <?php if($day_end == 13) echo 'selected="selected"'; ?> >13</option>
+	<option value="14" <?php if($day_end == 14) echo 'selected="selected"'; ?> >14</option>
+	<option value="15" <?php if($day_end == 15) echo 'selected="selected"'; ?> >15</option>
+	<option value="16" <?php if($day_end == 16) echo 'selected="selected"'; ?> >16</option>
+	<option value="17" <?php if($day_end == 17) echo 'selected="selected"'; ?> >17</option>
+	<option value="18" <?php if($day_end == 18) echo 'selected="selected"'; ?> >18</option>
+	<option value="19" <?php if($day_end == 19) echo 'selected="selected"'; ?> >19</option>
+	<option value="20" <?php if($day_end == 20) echo 'selected="selected"'; ?> >20</option>
+	<option value="21" <?php if($day_end == 21) echo 'selected="selected"'; ?> >21</option>
+	<option value="22" <?php if($day_end == 22) echo 'selected="selected"'; ?> >22</option>
+	<option value="23" <?php if($day_end == 23) echo 'selected="selected"'; ?> >23</option>
+	<option value="24" <?php if($day_end == 24) echo 'selected="selected"'; ?> >24</option>
+	<option value="25" <?php if($day_end == 25) echo 'selected="selected"'; ?> >25</option>
+	<option value="26" <?php if($day_end == 26) echo 'selected="selected"'; ?> >26</option>
+	<option value="27" <?php if($day_end == 27) echo 'selected="selected"'; ?> >27</option>
+	<option value="28" <?php if($day_end == 28) echo 'selected="selected"'; ?> >28</option>
+	<option value="29" <?php if($day_end == 29) echo 'selected="selected"'; ?> >29</option>
+	<option value="30" <?php if($day_end == 30) echo 'selected="selected"'; ?> >30</option>
+	<option value="31" <?php if($day_end == 31) echo 'selected="selected"'; ?> >31</option>
+  </select>
+  /
+  <select name="month_end">
+	<option value="1">01</option>
+	<option value="2" <?php if($month_end == 2) echo 'selected="selected"'; ?> >02</option>
+	<option value="3" <?php if($month_end == 3) echo 'selected="selected"'; ?> >03</option>
+	<option value="4" <?php if($month_end == 4) echo 'selected="selected"'; ?> >04</option>
+	<option value="5" <?php if($month_end == 5) echo 'selected="selected"'; ?> >05</option>
+	<option value="6" <?php if($month_end == 6) echo 'selected="selected"'; ?> >06</option>
+	<option value="7" <?php if($month_end == 7) echo 'selected="selected"'; ?> >07</option>
+	<option value="8" <?php if($month_end == 8) echo 'selected="selected"'; ?> >08</option>
+	<option value="9" <?php if($month_end == 9) echo 'selected="selected"'; ?> >09</option>
+	<option value="10" <?php if($month_end == 10) echo 'selected="selected"'; ?> >10</option>
+	<option value="11" <?php if($month_end == 11) echo 'selected="selected"'; ?> >11</option>
+	<option value="12" <?php if($month_end == 12) echo 'selected="selected"'; ?> >12</option>
+  </select>
+  /
+  <select name="year_end">
+
+<?php
+for($i=$thisYear-5;$i <= ($thisYear+5);$i++)
+{
+?>
+
+	<option value="<?php echo $i; ?>" <?php if($year_end == $i) echo 'selected="selected"'; ?> ><?php echo $i; ?></option>
+
+<?php
+}
+?>
+
+  </select>
+  </td>
+</tr>
+<tr>
+  <td>&nbsp;</td>
+  <td><input type="submit" value="<?php echo get_lang('Ok'); ?>"></td>
+</tr>
+
+</table>
+
+</form>
+<script type="text/javascript">
+
+<?php if($year_start=="0000") echo "setDisable(document.form.nolimit);\r\n"; ?>
+
+function setDisable(select){
+	
+	document.form.day_start.disabled = (select.checked) ? true : false;
+	document.form.month_start.disabled = (select.checked) ? true : false;
+	document.form.year_start.disabled = (select.checked) ? true : false;
+	
+	document.form.day_end.disabled = (select.checked) ? true : false;
+	document.form.month_end.disabled = (select.checked) ? true : false;
+	document.form.year_end.disabled = (select.checked) ? true : false;
+	
+	
+}
+</script>
+<?php
+Display::display_footer();
+?>

+ 296 - 0
main/admin/session_export.php

@@ -0,0 +1,296 @@
+<?php // $Id: session_export.php,v 1.1 2006/04/20 09:58:01 elixir_inter Exp $
+/*
+==============================================================================
+	Dokeos - elearning and course management software
+
+	Copyright (c) 2004 Dokeos S.A.
+	Copyright (c) 2003 University of Ghent (UGent)
+	Copyright (c) 2001 Universite catholique de Louvain (UCL)
+	Copyright (c) Olivier Brouckaert
+
+	For a full list of contributors, see "credits.txt".
+	The full license can be read in "license.txt".
+
+	This program is free software; you can redistribute it and/or
+	modify it under the terms of the GNU General Public License
+	as published by the Free Software Foundation; either version 2
+	of the License, or (at your option) any later version.
+
+	See the GNU General Public License for more details.
+
+	Contact: Dokeos, 181 rue Royale, B-1000 Brussels, Belgium, info@dokeos.com
+==============================================================================
+*/
+/**
+==============================================================================
+*	@package dokeos.admin
+==============================================================================
+*/
+
+$langFile='admin';
+
+$cidReset=true;
+
+include('../inc/global.inc.php');
+api_protect_admin_script();
+include(api_get_library_path().'/fileManage.lib.php');
+
+$session_id=$_GET['session_id'];
+$formSent=0;
+$errorMsg='';
+
+$tbl_user=Database::get_main_table(MAIN_USER_TABLE); 
+$tbl_course      = Database::get_main_table(MAIN_COURSE_TABLE); 
+$tbl_course_user = Database::get_main_table(MAIN_COURSE_USER_TABLE);
+$tbl_session      = Database::get_main_table(MAIN_SESSION_TABLE);
+$tbl_session_user      = Database::get_main_table(MAIN_SESSION_USER_TABLE);
+$tbl_session_course      = Database::get_main_table(MAIN_SESSION_COURSE_TABLE);
+$tbl_session_course_user      = Database::get_main_table(MAIN_SESSION_COURSE_USER_TABLE);
+
+
+$archivePath=api_get_path(SYS_PATH).$archiveDirName.'/';
+$archiveURL=api_get_path(WEB_CODE_PATH).'course_info/download.php?archive=';
+
+$tool_name=get_lang('ExportSessionListXMLCSV');
+
+$interbreadcrumb[]=array("url" => "index.php","name" => get_lang('AdministrationTools'));
+
+set_time_limit(0);
+
+if($_POST['formSent'] )
+{
+	$formSent=$_POST['formSent'];
+	$file_type=($_POST['file_type'] == 'csv')?'csv':'xml';
+	$session_id=$_POST['session_id'];
+	if(empty($session_id))
+	{
+		$result=api_sql_query("SELECT id,name,id_coach,date_start,date_end FROM $tbl_session ORDER BY id",__FILE__,__LINE__);
+	}
+	else
+	{
+		$sql = "SELECT id,name,username,date_start,date_end 
+				FROM $tbl_session 
+				INNER JOIN $tbl_user
+					ON $tbl_user.user_id = $tbl_session.id_coach
+				WHERE id='$session_id'";
+		
+		$result = api_sql_query($sql,__FILE__,__LINE__);
+		
+	}
+
+	if(mysql_num_rows($result))
+	{
+		if(!file_exists($archivePath))
+		{
+			mkpath($archivePath);
+		}
+
+		if(!file_exists($archivePath.'index.html'))
+		{
+			$fp=fopen($archivePath.'index.html','w');
+
+			fputs($fp,'<html><head></head><body></body></html>');
+
+			fclose($fp);
+		}
+
+		$archiveFile='export_sessions_'.$session_id.'_'.date('Y-m-d_H-i-s').'.'.$file_type;
+		
+		while( file_exists($archivePath.$archiveFile))
+		{
+			$archiveFile='export_users_'.$session_id.'_'.date('Y-m-d_H-i-s').'_'.uniqid('').'.'.$file_type;		
+		}
+		$fp=fopen($archivePath.$archiveFile,'w');
+
+		if($file_type == 'csv')
+		{
+			$cvs = true;
+			fputs($fp,"SessionName;Coach;DateStart;DateEnd;Users;Courses;\n");
+		}
+		else
+		{
+			$cvs = false;
+			fputs($fp,"<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\n<Sessions>\n");
+		}
+
+		while($row=mysql_fetch_array($result))
+		{
+			
+			
+			$add = '';
+			$row['name'] = str_replace(';',',',$row['name']);
+			$row['username'] = str_replace(';',',',$row['username']);
+			$row['date_start'] = str_replace(';',',',$row['date_start']);
+			$row['date_end'] = str_replace(';',',',$row['date_end']);
+			if($cvs){
+				$add.= $row['name'].';'.$row['username'].';'.$row['date_start'].';'.$row['date_end'].';';
+			}
+			else {
+				$add = "\t<Session>\n"
+						 ."\t\t<SessionName>$row[name]</SessionName>\n"
+						 ."\t\t<Coach>$row[username]</Coach>\n"
+						 ."\t\t<DateStart>$row[date_start]</DateStart>\n"
+						 ."\t\t<DateEnd>$row[date_end]</DateEnd>\n";
+			}
+			
+			//users
+			$sql = "SELECT DISTINCT $tbl_user.username FROM $tbl_user
+					INNER JOIN $tbl_session_user
+						ON $tbl_user.user_id = $tbl_session_user.id_user
+						AND $tbl_session_user.id_session = '".$row['id']."'";
+			
+			$rsUsers = api_sql_query($sql,__FILE__,__LINE__);
+			$users = '';
+			while($rowUsers = mysql_fetch_array($rsUsers)){
+				if($cvs){
+					$users .= str_replace(';',',',$rowUsers['username']).'|';
+				}
+				else {
+					$users .= "\t\t<User>$rowUsers[username]</User>\n";
+				}
+			}
+			if(!empty($users) && $cvs)
+				$users = substr($users , 0, strlen($users)-1);
+			
+			if($cvs) 
+				$users .= ';';
+			
+			$add .= $users;
+			
+			
+			
+			
+			//courses
+			$sql = "SELECT DISTINCT $tbl_course.code, $tbl_user.username FROM $tbl_course
+					INNER JOIN $tbl_session_course
+						ON $tbl_course.code = $tbl_session_course.course_code
+						AND $tbl_session_course.id_session = '".$row['id']."'
+					LEFT JOIN $tbl_user
+						ON $tbl_user.user_id = $tbl_session_course.id_coach";
+			$rsCourses = api_sql_query($sql,__FILE__,__LINE__);
+			
+			$courses = '';
+			while($rowCourses = mysql_fetch_array($rsCourses)){
+				
+				if($cvs){
+					$courses .= str_replace(';',',',$rowCourses['code']);
+					$courses .= '['.str_replace(';',',',$rowCourses['username']).'][';
+				}
+				else {
+					$courses .= "\t\t<Course>\n";
+					$courses .= "\t\t\t<CourseCode>$rowCourses[code]</CourseCode>\n";
+					$courses .= "\t\t\t<Coach>$rowCourses[username]</Coach>\n";
+				}
+				
+				// rel user courses
+				$sql = "SELECT DISTINCT username 
+						FROM $tbl_user
+						INNER JOIN $tbl_session_course_user
+							ON $tbl_session_course_user.id_user = $tbl_user.user_id
+							AND $tbl_session_course_user.course_code='".$rowCourses['code']."'
+							AND id_session='".$row['id']."'";
+				
+				$rsUsersCourse = api_sql_query($sql,__FILE__,__LINE__);
+				while($rowUsersCourse = mysql_fetch_array($rsUsersCourse)){
+					if($cvs){
+						$userscourse .= str_replace(';',',',$rowUsersCourse['username']).',';
+					}
+					else {
+						$courses .= "\t\t\t<User>$rowUsersCourse[username]</User>\n";
+					}
+				}
+				if($cvs){
+					if(!empty($userscourse))
+						$userscourse = substr($userscourse , 0, strlen($userscourse)-1);
+					
+					$courses .= $userscourse.']|';
+				}
+				else {
+					$courses .= "\t\t</Course>\n";
+				}
+			}
+			if(!empty($courses) && $cvs)
+				$courses = substr($courses , 0, strlen($courses)-1);
+			$add .= $courses;
+			
+			if($cvs)
+				$add .= ';';
+			else
+				$add .= "\t</Session>\n";
+
+			fputs($fp, $add);
+		}
+		
+		if(!$cvs)
+			fputs($fp,"</Sessions>\n");
+		fclose($fp);
+
+		$errorMsg=get_lang('UserListHasBeenExported').'<br/><a href="'.$archiveURL.$archiveFile.'">'.get_lang('ClickHereToDownloadTheFile').'</a>';
+	}
+}
+
+Display::display_header($tool_name);
+
+api_display_tool_title($tool_name);
+
+
+//select of sessions
+$sql = "SELECT id, name FROM $tbl_session ORDER BY name";
+
+$result=api_sql_query($sql,__FILE__,__LINE__);
+
+$Sessions=api_store_result($result);
+?>
+
+<?php
+if(!empty($errorMsg))
+{
+	Display::display_normal_message($errorMsg); //main API
+}
+?>
+
+<form method="post" action="<?php echo $_SERVER['PHP_SELF']; ?>" style="margin:0px;">
+<input type="hidden" name="formSent" value="1">
+<table border="0" cellpadding="5" cellspacing="0">
+<tr>
+  <td nowrap="nowrap" valign="top"><?php echo get_lang('OutputFileType'); ?> :</td>
+  <td>
+	<input class="checkbox" type="radio" name="file_type" id="file_type_xml" value="xml" <?php if($formSent && $file_type == 'xml') echo 'checked="checked"'; ?>> <label for="file_type_xml">XML</label><br>
+	<input class="checkbox" type="radio" name="file_type" id="file_type_csv"  value="csv" <?php if(!$formSent || $file_type == 'csv') echo 'checked="checked"'; ?>> <label for="file_type_csv">CSV</label><br>
+  </td>
+</tr>
+<tr>
+  <td><?php echo get_lang('WhichSessionToExport'); ?> :</td>
+  <td><select name="session_id">
+	<option value=""><?php echo get_lang('AllSessions') ?></option>
+
+<?php
+foreach($Sessions as $enreg)
+{
+?>
+
+	<option value="<?php echo $enreg['id']; ?>" <?php if($session_id == $enreg['id']) echo 'selected="selected"'; ?>><?php echo $enreg['name']; ?></option>
+
+<?php
+}
+
+unset($Courses);
+?>
+
+  </select></td>
+</tr>
+<tr>
+  <td>&nbsp;</td>
+  <td><input type="submit" value="<?php echo get_lang('Ok'); ?>"></td>
+</tr>
+</table>
+</form>
+
+<?php
+/*
+==============================================================================
+		FOOTER 
+==============================================================================
+*/ 
+Display::display_footer();
+?>

+ 444 - 0
main/admin/session_import.php

@@ -0,0 +1,444 @@
+<?php // $Id: session_import.php,v 1.1 2006/04/20 09:58:01 elixir_inter Exp $
+/*
+==============================================================================
+	Dokeos - elearning and course management software
+
+	Copyright (c) 2004 Dokeos S.A.
+	Copyright (c) 2003 University of Ghent (UGent)
+	Copyright (c) 2001 Universite catholique de Louvain (UCL)
+	Copyright (c) Olivier Brouckaert
+
+	For a full list of contributors, see "credits.txt".
+	The full license can be read in "license.txt".
+
+	This program is free software; you can redistribute it and/or
+	modify it under the terms of the GNU General Public License
+	as published by the Free Software Foundation; either version 2
+	of the License, or (at your option) any later version.
+
+	See the GNU General Public License for more details.
+
+	Contact: Dokeos, 181 rue Royale, B-1000 Brussels, Belgium, info@dokeos.com
+==============================================================================
+*/
+/**
+==============================================================================
+*	@package dokeos.admin
+==============================================================================
+*/
+
+$langFile = array('admin','registration');
+
+$cidReset=true;
+
+include('../inc/global.inc.php');
+
+api_protect_admin_script();
+
+include(api_get_library_path().'/fileManage.lib.php');
+include(api_get_library_path().'/xmllib.php');
+
+$formSent=0;
+$errorMsg='';
+
+$tbl_user      = Database::get_main_table(MAIN_USER_TABLE);
+$tbl_course      = Database::get_main_table(MAIN_COURSE_TABLE);
+$tbl_session      = Database::get_main_table(MAIN_SESSION_TABLE);
+$tbl_session_user      = Database::get_main_table(MAIN_SESSION_USER_TABLE);
+$tbl_session_course      = Database::get_main_table(MAIN_SESSION_COURSE_TABLE);
+$tbl_session_course_user      = Database::get_main_table(MAIN_SESSION_COURSE_USER_TABLE);
+
+$tool_name=get_lang('ImportSessionListXMLCSV');
+
+$interbreadcrumb[]=array("url" => "index.php","name" => get_lang('AdministrationTools'));
+
+set_time_limit(0);
+
+if($_POST['formSent'])
+{
+	$formSent=$_POST['formSent'];
+	$file_type=$_POST['file_type'];
+	$sendMail=$_POST['sendMail']?1:0;
+	
+
+	/*if($_FILES['import_file']['size'])
+	{
+		$content=file($_FILES['import_file']['tmp_name']);
+	}
+	else
+	{
+		$content=array('');
+	}*/
+
+	$sessions=array();
+	
+	///////////////////////
+	//XML/////////////////
+	/////////////////////
+
+	if($file_type == 'xml')
+	{
+		$xmlparser = new XmlLib_xmlParser($_FILES['import_file']['tmp_name']);
+		$racine = $xmlparser->getDocument();
+		$sessionNodes = $racine->children('Session');
+		foreach ($sessionNodes as $sessionNode){ // foreach session
+		
+			$countCourses = 0;
+			$countUsers = 0;
+			
+			list($SessionName) = $sessionNode->children('SessionName'); 
+			$SessionName = $SessionName->nodeValue();
+			
+			list($Coach) = $sessionNode->children('Coach'); 
+			if(!empty($Coach)){
+				$Coach = $Coach->nodeValue();
+				$sqlCoach = "SELECT user_id FROM $tbl_user WHERE username='$Coach'";
+				$rsCoach = api_sql_query($sqlCoach);
+				list($Coach) = (mysql_fetch_array($rsCoach));
+			}
+			else {
+				$Coach = '';
+			}
+			
+			list($DateStart) = $sessionNode->children('DateStart'); 
+			$DateStart = $DateStart->nodeValue();
+			
+			list($DateEnd) = $sessionNode->children('DateEnd'); 
+			$DateEnd = $DateEnd->nodeValue();
+			
+			$sqlSession = "INSERT IGNORE INTO $tbl_session SET
+							name = '$SessionName',
+							id_coach = '$Coach',
+							date_start = '$DateStart',
+							date_end = '$DateEnd'";
+			$rsSession = api_sql_query($sqlSession, __FILE__, __LINE__);
+			$update = false;
+			if(!mysql_affected_rows($rsSession)){	
+				$update = true;
+				$sqlSession = "UPDATE $tbl_session SET								
+								id_coach = '$Coach',
+								date_start = '$DateStart',
+								date_end = '$DateEnd'
+								WHERE name = '$SessionName'";
+				$rsSession = api_sql_query($sqlSession, __FILE__, __LINE__);
+				
+				$session_id = api_sql_query("SELECT id FROM $tbl_session WHERE name='$SessionName'",__FILE__,__LINE__);
+				list($session_id) = mysql_fetch_array($session_id);				
+				
+				api_sql_query("DELETE FROM $tbl_session_user WHERE id_session='$session_id'",__FILE__,__LINE__);
+				api_sql_query("DELETE FROM $tbl_session_course WHERE id_session='$session_id'",__FILE__,__LINE__);
+				api_sql_query("DELETE FROM $tbl_session_course_user WHERE id_session='$session_id'",__FILE__,__LINE__);
+			}
+			else {
+				$session_id = mysql_insert_id($rsSession);
+			}
+			
+			$userNodes = $sessionNode->children('User');
+			foreach ($userNodes as $userNode){				
+				$sqlUser = "SELECT user_id FROM $tbl_user WHERE username='".$userNode->nodeValue()."'";
+				$rsUser = api_sql_query($sqlUser);
+				list($user_id) = (mysql_fetch_array($rsUser));
+				if(!empty($user_id)){
+					$sql = "INSERT INTO $tbl_session_user SET 
+							id_user='$user_id',
+							id_session = '$session_id'";
+					
+					$rsUser = api_sql_query($sql,__FILE__,__LINE__);
+					if(mysql_affected_rows()){
+						$countUsers++;
+					}
+				}
+			}
+			
+			$courseNodes = $sessionNode->children('Course');
+			foreach($courseNodes as $courseNode){
+				
+				list($CourseCode) = $courseNode->children('CourseCode'); 
+				$CourseCode = $CourseCode->nodeValue();
+				
+				list($Coach) = $courseNode->children('Coach'); 
+				if(!empty($Coach)){
+					$Coach = $Coach->nodeValue();
+					$sqlCoach = "SELECT user_id FROM $tbl_user WHERE username='$Coach'";
+					$rsCoach = api_sql_query($sqlCoach,__FILE__,__LINE__);
+					list($Coach) = (mysql_fetch_array($rsCoach));
+				}
+				else {
+					$Coach = '';
+				}
+				
+				$sqlCourse = "INSERT INTO $tbl_session_course SET
+							  course_code = '$CourseCode',
+							  id_coach='$Coach',
+							  id_session='$session_id'";
+				$rsCourse = api_sql_query($sqlCourse,__FILE__,__LINE__);
+				if(mysql_affected_rows()){
+					$countCourses++;
+					
+					$userNodes = $courseNode->children('User');
+					$countUsersCourses = 0;
+					foreach ($userNodes as $userNode){
+						$sqlUser = "SELECT user_id FROM $tbl_user WHERE username='".$userNode->nodeValue()."'";
+						$rsUser = api_sql_query($sqlUser);
+						list($user_id) = (mysql_fetch_array($rsUser));
+						$sql = "INSERT INTO $tbl_session_course_user SET 
+								id_user='$user_id',
+								course_code='$CourseCode',
+								id_session = '$session_id'";
+						$rsUsers = api_sql_query($sql,__FILE__,__LINE__);
+						if(mysql_affected_rows())
+							$countUsersCourses++;
+					}		
+					api_sql_query("UPDATE $tbl_session_course SET nbr_users='$countUsersCourses' WHERE course_code='$CourseCode'",__FILE__,__LINE__);	
+				}
+			}
+			api_sql_query("UPDATE $tbl_session SET nbr_users='$countUsers', nbr_courses='$countCourses' WHERE id='$session_id'",__FILE__,__LINE__);
+			
+		}
+		
+	}
+	
+	
+	
+	
+	/////////////////////
+	// CSV /////////////
+	///////////////////
+	
+	
+	else
+	{
+		$content=file($_FILES['import_file']['tmp_name']);
+		if(!strstr($content[0],';'))
+		{
+			$errorMsg=get_lang('NotCSV');
+		}
+		else
+		{
+			
+			$tag_names=array();
+
+			foreach($content as $key=>$enreg)
+			{
+				$enreg=explode(';',trim($enreg));
+
+				if($key)
+				{
+					foreach($tag_names as $tag_key=>$tag_name)
+					{
+						$sessions[$key-1][$tag_name]=$enreg[$tag_key];
+					}
+				}
+				else
+				{
+					foreach($enreg as $tag_name)
+					{
+						$tag_names[]=eregi_replace('[^a-z0-9_-]','',$tag_name);
+					}
+
+					if(!in_array('SessionName',$tag_names) || !in_array('DateStart',$tag_names) || !in_array('DateEnd',$tag_names))
+					{
+						$errorMsg=get_lang('NoNeededData');
+
+						break;
+					}
+				}
+			}
+			
+			foreach($sessions as $enreg) {
+				$SessionName = $enreg['SessionName'];
+				$DateStart = $enreg['DateStart'];
+				$DateEnd = $enreg['DateEnd'];
+				if(!empty($enreg['Coach'])){
+					$sqlCoach = "SELECT user_id FROM $tbl_user WHERE username='".$enreg['Coach']."'";
+					$rsCoach = api_sql_query($sqlCoach);
+					list($Coach) = (mysql_fetch_array($rsCoach));
+				}
+				else {
+					$Coach = '';
+				}
+				
+				$sqlSession = "INSERT IGNORE INTO $tbl_session SET
+							name = '$SessionName',
+							id_coach = '$Coach',
+							date_start = '$DateStart',
+							date_end = '$DateEnd'";
+				$rsSession = api_sql_query($sqlSession, __FILE__, __LINE__);
+				$update = false;
+				if(!mysql_affected_rows($rsSession)){
+					$update = true;
+					$sqlSession = "UPDATE $tbl_session SET								
+									id_coach = '$Coach',
+									date_start = '$DateStart',
+									date_end = '$DateEnd'
+									WHERE name = '$SessionName'";
+					$rsSession = api_sql_query($sqlSession, __FILE__, __LINE__);
+					
+					$session_id = api_sql_query("SELECT id FROM $tbl_session WHERE name='$SessionName'",__FILE__,__LINE__);
+					list($session_id) = mysql_fetch_array($session_id);				
+					
+					api_sql_query("DELETE FROM $tbl_session_user WHERE id_session='$session_id'",__FILE__,__LINE__);
+					api_sql_query("DELETE FROM $tbl_session_course WHERE id_session='$session_id'",__FILE__,__LINE__);
+					api_sql_query("DELETE FROM $tbl_session_course_user WHERE id_session='$session_id'",__FILE__,__LINE__);
+				}
+				else {
+					$session_id = mysql_insert_id($rsSession);
+				}
+				
+				$users = explode('|',$enreg['Users']);
+				foreach ($users as $user){				
+					$sqlUser = "SELECT user_id FROM $tbl_user WHERE username='".$user."'";
+					$rsUser = api_sql_query($sqlUser);
+					list($user_id) = (mysql_fetch_array($rsUser));
+					$sql = "INSERT INTO $tbl_session_user SET 
+							id_user='$user_id',
+							id_session = '$session_id'";
+					
+					$rsUser = api_sql_query($sql,__FILE__,__LINE__);
+					if(mysql_affected_rows()){
+						$countUsers++;
+					}
+				}
+				
+				$courses = explode('|',$enreg['Courses']);
+				foreach($courses as $course){
+					$CourseCode = substr($course,0,strpos($course,'['));
+					
+					$Coach = strstr($course,'[');
+					$Coach = substr($Coach,1,strpos($Coach,']')-1);
+					
+					if(!empty($Coach)){
+						$sqlCoach = "SELECT user_id FROM $tbl_user WHERE username='$Coach'";
+						$rsCoach = api_sql_query($sqlCoach,__FILE__,__LINE__);
+						list($Coach) = (mysql_fetch_array($rsCoach));
+					}
+					else {
+						$Coach = '';
+					}
+					
+					$sqlCourse = "INSERT INTO $tbl_session_course SET
+								  course_code = '$CourseCode',
+								  id_coach='$Coach',
+								  id_session='$session_id'";
+					
+					$rsCourse = api_sql_query($sqlCourse,__FILE__,__LINE__);
+					if(mysql_affected_rows()){
+						$countCourses++;
+						
+						$users = substr($course , strpos($course,'[',1)+1 , strpos($course,']',1));
+						$users = explode('|',$enreg['Users']);
+						$countUsersCourses = 0;
+						foreach ($users as $user){
+							$sqlUser = "SELECT user_id FROM $tbl_user WHERE username='".$user."'";
+							$rsUser = api_sql_query($sqlUser);
+							list($user_id) = (mysql_fetch_array($rsUser));
+							$sql = "INSERT INTO $tbl_session_course_user SET 
+									id_user='$user_id',
+									course_code='$CourseCode',
+									id_session = '$session_id'";
+							$rsUsers = api_sql_query($sql,__FILE__,__LINE__);
+							if(mysql_affected_rows())
+								$countUsersCourses++;
+						}		
+						api_sql_query("UPDATE $tbl_session_course SET nbr_users='$countUsersCourses' WHERE course_code='$CourseCode'",__FILE__,__LINE__);	
+					}
+				}
+				api_sql_query("UPDATE $tbl_session SET nbr_users='$countUsers', nbr_courses='$countCourses' WHERE id='$session_id'",__FILE__,__LINE__);
+				
+			}
+		}
+	}
+	header('Location: session_list.php?action=show_message&message='.urlencode(get_lang('FileImported')));
+}
+
+Display::display_header($tool_name);
+
+api_display_tool_title($tool_name);
+
+
+?>
+
+<form method="post" action="<?php echo $_SERVER['PHP_SELF']; ?>" enctype="multipart/form-data" style="margin:0px;">
+<input type="hidden" name="formSent" value="1">
+<table border="0" cellpadding="5" cellspacing="0">
+
+<?php
+if(!empty($errorMsg))
+{
+?>
+
+<tr>
+  <td colspan="2">
+
+<?php
+	Display::display_normal_message($errorMsg); //main API
+?>
+
+  </td>
+</tr>
+
+<?php
+}
+?>
+
+<tr>
+  <td nowrap="nowrap"><?php echo get_lang('ImportFileLocation'); ?> :</td>
+  <td><input type="file" name="import_file" size="30"></td>
+</tr>
+<tr>
+  <td nowrap="nowrap" valign="top"><?php echo get_lang('FileType'); ?> :</td>
+  <td>
+	<input class="checkbox" type="radio" name="file_type" id="file_type_xml" value="xml" <?php if($formSent && $file_type == 'xml') echo 'checked="checked"'; ?>> <label for="file_type_xml">XML</label> (<a href="exemple.xml" target="_blank"><?php echo get_lang('ExampleXMLFile'); ?></a>)<br>
+	<input class="checkbox" type="radio" name="file_type" id="file_type_csv"  value="csv" <?php if(!$formSent || $file_type == 'csv') echo 'checked="checked"'; ?>> <label for="file_type_csv">CSV</label> (<a href="exemple.csv" target="_blank"><?php echo get_lang('ExampleCSVFile'); ?></a>)<br>
+  </td>
+</tr>
+<tr>
+  <td>&nbsp;</td>
+  <td><input type="submit" value="<?php echo get_lang('Ok'); ?>"></td>
+</tr>
+</table>
+</form>
+
+<font color="gray">
+<p><?php echo get_lang('CSVMustLookLike').' ('.get_lang('MandatoryFields').')'; ?> :</p>
+
+<blockquote>
+<pre>
+<b>SessionName</b>;Coach;<b>DateStart</b>;<b>DateEnd</b>;Users;Courses
+<b>xxx</b>;xxx;<b>xxx;xxx</b>;username1|username2;course1[coach1][username1,username2,...]|course2[coach1][username1,username2,...]
+</pre>
+</blockquote>
+
+<p><?php echo get_lang('XMLMustLookLike').' ('.get_lang('MandatoryFields').')'; ?> :</p>
+
+<blockquote>
+<pre>
+&lt;?xml version=&quot;1.0&quot; encoding=&quot;ISO-8859-1&quot;?&gt;
+&lt;Sessions&gt;
+    &lt;Session&gt;
+        <b>&lt;SessionName&gt;xxx&lt;/SessionName&gt;</b>
+        &lt;Coach&gt;xxx&lt;/Coach&gt;
+        <b>&lt;DateStart&gt;xxx&lt;/DateStart&gt;</b>
+        <b>&lt;DateEnd&gt;xxx&lt;/DateEnd&gt;</b>
+        &lt;User&gt;xxx&lt;/User&gt;
+        &lt;User&gt;xxx&lt;/User&gt;
+    	&lt;Course&gt;
+    		&lt;CourseCode&gt;coursecode1&lt;/CourseCode&gt;
+    		&lt;Coach&gt;coach1&lt;/Coach&gt;
+		&lt;User&gt;username1&lt;/User&gt;
+		&lt;User&gt;username2&lt;/User&gt;
+    	&lt;/Course&gt;
+    &lt;/Session&gt;
+&lt;/Sessions&gt;
+</pre>
+</blockquote>
+</font>
+
+<?php
+/*
+==============================================================================
+		FOOTER
+==============================================================================
+*/
+Display::display_footer();
+?>

+ 139 - 0
main/admin/session_list.php

@@ -0,0 +1,139 @@
+<?php
+$langFile='admin';
+
+$cidReset=true;
+
+include('../inc/global.inc.php');
+
+api_protect_admin_script();
+
+$tbl_session=Database::get_main_table(MAIN_SESSION_TABLE);
+$tbl_session_rel_course=Database::get_main_table(MAIN_SESSION_COURSE_TABLE);
+$tbl_session_rel_course_rel_user=Database::get_main_table(MAIN_SESSION_COURSE_USER_TABLE);
+
+$page=intval($_GET['page']);
+$action=$_REQUEST['action'];
+$sort=in_array($_GET['sort'],array('name','nbr_courses','date_start','date_end'))?$_GET['sort']:'name';
+
+if($action == 'delete')
+{
+	$idChecked = $_POST['idChecked'];
+	if(is_array($idChecked))
+	{
+		$idChecked=implode(',',$idChecked);
+	}
+	else
+	{
+		$idChecked=intval($idChecked);
+	}
+
+	api_sql_query("DELETE FROM $tbl_session WHERE id IN($idChecked)",__FILE__,__LINE__);
+	
+	api_sql_query("DELETE FROM $tbl_session_rel_course WHERE id_session IN($idChecked)",__FILE__,__LINE__);
+
+	api_sql_query("DELETE FROM $tbl_session_rel_course_rel_user WHERE id_session IN($idChecked)",__FILE__,__LINE__);
+
+	//header('Location: '.$PHP_SELF.'?sort='.$sort);
+	//exit();
+}
+
+$limit=20;
+$from=$page * $limit;
+
+$result=api_sql_query("SELECT id,name,nbr_courses,date_start,date_end FROM $tbl_session ".(empty($_POST['keyword']) ? "" : "WHERE name LIKE '%".addslashes($_POST['keyword'])."%'")." ORDER BY $sort LIMIT $from,".($limit+1),__FILE__,__LINE__);
+
+$Sessions=api_store_result($result);
+
+$nbr_results=sizeof($Sessions);
+
+$tool_name = get_lang('ListSession');
+
+$interbreadcrumb[]=array("url" => "index.php","name" => get_lang('AdministrationTools'));
+
+Display::display_header($tool_name);
+
+api_display_tool_title($tool_name);
+?>
+
+<div id="main">
+
+<?php
+
+if(isset($_GET['action'])){
+	Display::display_normal_message(stripslashes($_GET['message']));
+}
+
+?>
+<form method="POST" action="session_list.php">
+		<input type="text" name="keyword" value="<?php echo $_GET['keyword']; ?>"/>
+	<input type="submit" value="<?php echo get_lang('Search'); ?>"/>
+	</form>
+<form method="post" action="<?php echo $PHP_SELF; ?>?sort=<?php echo $sort; ?>" onsubmit="javascript:if(!confirm('Veuillez confirmer votre choix.')) return false;">
+
+<div align="left">
+
+<?php
+
+if(count($Sessions)==0 && isset($_POST['keyword']))
+{
+	echo get_lang('NoSearchResults');
+}
+else 
+{
+	
+	
+	$table_header[] = array (' ', false);
+	$table_header[] = array (get_lang('SessionName'), true);
+	$table_header[] = array (get_lang('NbCourses'), true);
+	$table_header[] = array (get_lang('DateStart'), true);
+	$table_header[] = array (get_lang('DateEnd'), true);
+	$table_header[] = array ('Actions', false);
+		
+	$i=0;
+	$sessions = array();
+	foreach($Sessions as $key=>$enreg)
+	{
+		if($key == $limit)
+		{
+			break;
+		}
+		$session = array();
+		$session[] = '<input type="checkbox" name="idChecked[]" value="'.$enreg['id'].'">';
+		$session[] = '<a href="resume_session.php?id_session='.$enreg['id'].'">'.htmlentities($enreg['name']).'</a>';
+		$session[] = '<a href="session_course_list.php?id_session='.$enreg['id'].'">'.htmlentities($enreg['nbr_courses']).' cours</a>';
+		$session[] = htmlentities($enreg['date_start']);
+		$session[] = htmlentities($enreg['date_end']);
+		$session[] = '<a href="add_users_to_session.php?page=session_list.php&id_session='.$enreg['id'].'"><img src="../img/group_small.gif" border="0" align="absmiddle" title="'.get_lang('SubscribeUsersToSession').'"></a>
+					<a href="add_courses_to_session.php?page=session_list.php&id_session='.$enreg['id'].'"><img src="../img/info_small.gif" border="0" align="absmiddle" title="'.get_lang('SubscribeCoursesToSession').'"></a>
+					<a href="session_edit.php?page=session_list.php&id='.$enreg['id'].'"><img src="../img/edit.gif" border="0" align="absmiddle" title="'.get_lang('Edit').'"></a>
+					<a href="'.$PHP_SELF.'?sort='.$sort.'&action=delete&idChecked='.$enreg['id'].'" onclick="javascript:if(!confirm(\''.get_lang('Confirm').'\')) return false;"><img src="../img/delete.gif" border="0" align="absmiddle" title="'.get_lang('Delete').'"></a>';
+		$sessions[] = $session;
+
+		$i=$i ? 0 : 1;
+	}
+	
+	unset($Sessions);
+
+	echo '<form method="post" action="'.$PHP_SELF.'">';
+	Display :: display_sortable_table($table_header, $sessions, array (), array (), $parameters);
+	echo '<select name="action">
+			<option value="delete">'.get_lang('DeleteSelectedSessions').'</option>
+			</select>
+			<input type="submit" value="'.get_lang('Ok').'">
+			</form>';
+}
+	?>
+	
+</div>
+
+<br>
+
+
+</table>
+
+</div>
+
+<?php
+
+Display::display_footer();
+?>

+ 449 - 0
main/admin/settings.php

@@ -0,0 +1,449 @@
+<?php
+// $Id: settings.php 9589 2006-10-19 13:53:43Z bmol $
+/*
+==============================================================================
+	Dokeos - elearning and course management software
+
+	Copyright (c) 2004-2005 Dokeos S.A.
+	Copyright (c) 2003 Ghent University
+	Copyright (c) Patrick Cool, Ghent University
+	Copyright (c) Roan Embrechts, Vrije Universiteit Brussel
+	Copyright (c) Bart Mollet, Hogeschool Gent
+
+	For a full list of contributors, see "credits.txt".
+	The full license can be read in "license.txt".
+
+	This program is free software; you can redistribute it and/or
+	modify it under the terms of the GNU General Public License
+	as published by the Free Software Foundation; either version 2
+	of the License, or (at your option) any later version.
+
+	See the GNU General Public License for more details.
+
+	Contact address: Dokeos, 44 rue des palais, B-1030 Brussels, Belgium
+	Mail: info@dokeos.com
+==============================================================================
+*/
+/**
+==============================================================================
+* With this tool you can easily adjust non critical configuration settings.
+* Non critical means that changing them will not result in a broken campus.
+*
+* @author Patrick Cool
+* @since Dokeos 1.6
+* @package dokeos.admin
+==============================================================================
+*/
+
+/*
+==============================================================================
+		INIT SECTION
+==============================================================================
+*/
+// stating the language file
+$langFile = 'admin';
+// including some necessary dokeos files
+include ('../inc/global.inc.php');
+require_once (api_get_path(LIBRARY_PATH).'formvalidator/FormValidator.class.php');
+$this_section = SECTION_PLATFORM_ADMIN;
+
+api_protect_admin_script();
+
+// Submit Stylesheets
+if ($_POST['SubmitStylesheets'])
+{
+	$message = store_stylesheets();
+	header("Location: http://{$_SERVER['HTTP_HOST']}{$_SERVER['PHP_SELF']}?category=stylesheets");
+	exit;
+}
+
+$table_settings_current = Database :: get_main_table(MAIN_SETTINGS_CURRENT_TABLE);
+// setting breadcrumbs
+//$interbreadcrumb[] = array ("url" => "index.php", "name" => get_lang('PlatformAdmin'));
+// setting the name of the tool
+$tool_name = get_lang('DokeosConfigSettings');
+
+// Build the form
+if ($_GET['category'] and $_GET['category'] <> "Plugins" and $_GET['category'] <> "stylesheets")
+{
+	$form = new FormValidator('settings', 'post', 'settings.php?category='.$_GET['category']);
+	$renderer = & $form->defaultRenderer();
+	$renderer->setHeaderTemplate('<div class="settingtitle">{header}</div>'."\n");
+	$renderer->setElementTemplate('<div class="settingcomment">{label}</div>'."\n".'<div class="settingvalue">{element}</div>'."\n");
+	$sqlsettings = "SELECT DISTINCT * FROM $table_settings_current WHERE category='".$_GET['category']."' GROUP BY variable ORDER BY id ASC";
+	$resultsettings = api_sql_query($sqlsettings, __FILE__, __LINE__);
+	while ($row = mysql_fetch_array($resultsettings))
+	{
+		$form->addElement('header', null, get_lang($row['title']));
+		switch ($row['type'])
+		{
+			case 'textfield' :
+				$form->addElement('text', $row['variable'], get_lang($row['comment']));
+				$default_values[$row['variable']] = $row['selected_value'];
+				break;
+			case 'textarea' :
+				$form->addElement('textarea', $row['variable'], get_lang($row['comment']));
+				$default_values[$row['variable']] = $row['selected_value'];
+				break;
+			case 'radio' :
+				$values = get_settings_options($row['variable']);
+				$group = array ();
+				foreach ($values as $key => $value)
+				{
+					$group[] = $form->createElement('radio', $row['variable'], '', get_lang($value['display_text']), $value['value']);
+				}
+				$form->addGroup($group, $row['variable'], get_lang($row['comment']), '<br />', false);
+				$default_values[$row['variable']] = $row['selected_value'];
+				break;
+			case 'checkbox';
+				$sql = "SELECT * FROM settings_current WHERE variable='".$row['variable']."'";
+				$result = api_sql_query($sql, __FILE__, __LINE__);
+				$group = array ();
+				while ($rowkeys = mysql_fetch_array($result))
+				{
+					$element = & $form->createElement('checkbox', $rowkeys['subkey'], '', get_lang($rowkeys['subkeytext']));
+					if ($rowkeys['selected_value'] == 'true' && ! $form->isSubmitted())
+					{
+						$element->setChecked(true);
+					}
+					$group[] = $element;
+				}
+				$form->addGroup($group, $row['variable'], get_lang($row['comment']), '<br />'."\n");
+				break;
+			case "link" :
+				$form->addElement('static', null, get_lang($row['comment']), get_lang('CurrentValue').' : '.$row['selected_value']);
+		}
+	}
+	$form->addElement('submit', null, get_lang('Ok'));
+	$form->setDefaults($default_values);
+	if ($form->validate())
+	{
+		$values = $form->exportValues();
+		// the first step is to set all the variables that have type=checkbox of the category
+		// to false as the checkbox that is unchecked is not in the $_POST data and can
+		// therefore not be set to false
+		$sql = "UPDATE $table_settings_current SET selected_value='false' WHERE category='".mysql_real_escape_string($_GET['category'])."' AND type='checkbox'";
+		$result = api_sql_query($sql, __FILE__, __LINE__);
+		// Save the settings
+		foreach ($values as $key => $value)
+		{
+			if (!is_array($value))
+			{
+				$sql = "UPDATE $table_settings_current SET selected_value='".mysql_real_escape_string($value)."' WHERE variable='$key'";
+				$result = api_sql_query($sql, __FILE__, __LINE__);
+			}
+			else
+			{
+				foreach ($value as $subkey => $subvalue)
+				{
+					$sql = "UPDATE $table_settings_current SET selected_value='true' WHERE variable='$key' AND subkey = '$subkey'";
+					$result = api_sql_query($sql, __FILE__, __LINE__);
+				}
+			}
+		}
+		header('Location: settings.php?action=stored&category='.$_GET['category']);
+		exit;
+	}
+}
+
+// including the header (banner)
+Display :: display_header($tool_name);
+//api_display_tool_title($tool_name);
+
+// displaying the message that the settings have been stored
+if ($_GET['action'] == "stored")
+{
+	Display :: display_normal_message($SettingsStored);
+}
+// grabbing the categories
+$selectcategories = "SELECT DISTINCT category FROM ".$table_settings_current." WHERE category NOT IN ('stylesheets','Plugins')";
+$resultcategories = api_sql_query($selectcategories, __FILE__, __LINE__);
+echo "\n<div><ul>";
+while ($row = mysql_fetch_array($resultcategories))
+{
+	echo "\n\t<li><a href=\"".$_SERVER['PHP_SELF']."?category=".$row['category']."\">".get_lang($row['category'])."</a></li>";
+}
+echo "\n\t<li><a href=\"".$_SERVER['PHP_SELF']."?category=Plugins\">".get_lang('Plugins')."</a></li>";
+echo "\n\t<li><a href=\"".$_SERVER['PHP_SELF']."?category=stylesheets\">".get_lang('Stylesheets')."</a></li>";
+echo "\n</ul></div>";
+
+if (isset ($_GET['category']))
+{
+	switch ($_GET['category'])
+	{
+		// displaying the extensions: plugins
+		case 'Plugins' :
+			handle_plugins();
+			break;
+			// displaying the extensions: Stylesheets
+		case 'stylesheets' :
+			handle_stylesheets();
+			break;
+		default :
+			$form->display();
+	}
+}
+
+/*
+==============================================================================
+		FOOTER
+==============================================================================
+*/
+Display :: display_footer();
+
+/**
+ * The function that retrieves all the possible settings for a certain config setting
+ * @author Patrick Cool <patrick.cool@UGent.be>, Ghent University
+*/
+function get_settings_options($var)
+{
+	$table_settings_options = Database :: get_main_table(MAIN_SETTINGS_OPTIONS_TABLE);
+	$sql = "SELECT * FROM $table_settings_options WHERE variable='$var'";
+	$result = api_sql_query($sql, __FILE__, __LINE__);
+	while ($row = mysql_fetch_array($result))
+	{
+		$temp_array = array ('value' => $row['value'], 'display_text' => $row['display_text']);
+		$settings_options_array[] = $temp_array;
+	}
+	return $settings_options_array;
+}
+
+/**
+ * This function allows easy activating and inactivating of plugins
+ * @todo: a similar function needs to be written to activate or inactivate additional tools.
+ * @author Patrick Cool <patrick.cool@UGent.be>, Ghent University
+*/
+function handle_plugins()
+{
+	global $SettingsStored;
+	$table_settings_current = Database :: get_main_table(MAIN_SETTINGS_CURRENT_TABLE);
+
+	if ($_POST['SubmitPlugins'])
+	{
+		store_plugins();
+		Display :: display_normal_message($SettingsStored);
+	}
+
+	echo get_lang('AvailablePlugins')."<br/><br/>";
+
+	/* We scan the plugin directory. Each folder is a potential plugin. */
+	$pluginpath = api_get_path(SYS_PLUGIN_PATH);
+
+	$handle = opendir($pluginpath);
+	while (false !== ($file = readdir($handle)))
+	{
+		if (is_dir(api_get_path(SYS_PLUGIN_PATH).$file) AND $file <> '.' AND $file <> '..')
+		{
+			$possibleplugins[] = $file;
+		}
+	}
+	closedir($handle);
+
+	/* 	for each of the possible plugin dirs we check if a file plugin.php (that contains all the needed information about this plugin)
+	 	can be found in the dir.
+		this plugin.php file looks like
+		$plugin_info['title']='The title of the plugin'; //
+		$plugin_info['comment']="Some comment about the plugin";
+		$plugin_info['location']=array("loginpage_menu", "campushomepage_menu","banner"); // the possible locations where the plugins can be used
+		$plugin_info['version']='0.1 alpha'; // The version number of the plugin
+		$plugin_info['author']='Patrick Cool'; // The author of the plugin
+	*/
+	echo '<form name="plugins" method="post" action="'.$_SERVER['PHP_SELF'].'?category='.$_GET['category'].'">';
+	echo "<table class=\"data_table\">\n";
+	echo "\t<tr>\n";
+	echo "\t\t<th>\n";
+	echo get_lang('Plugin');
+	echo "\t\t</th>\n";
+	echo "\t\t<th>\n";
+	echo get_lang('MainMenu');
+	echo "\t\t</th>\n";
+	echo "\t\t<th>\n";
+	echo get_lang('MainMenuLogged');
+	echo "\t\t</th>\n";
+	echo "\t\t<th>\n";
+	echo get_lang('Banner');
+	echo "\t\t</th>\n";
+	echo "\t</tr>\n";
+
+	/* We retrieve all the active plugins. */
+	$sql = "SELECT * FROM $table_settings_current WHERE category='Plugins'";
+	$result = api_sql_query($sql);
+	while ($row = mysql_fetch_array($result))
+	{
+		$usedplugins[$row['variable']][] = $row['selected_value'];
+	}
+
+	/* We display all the possible plugins and the checkboxes */
+	foreach ($possibleplugins as $testplugin)
+	{
+		$plugin_info_file = api_get_path(SYS_PLUGIN_PATH).$testplugin."/plugin.php";
+		if (file_exists($plugin_info_file))
+		{
+			include ($plugin_info_file);
+
+			echo "\t<tr>\n";
+			echo "\t\t<td>\n";
+			foreach ($plugin_info as $key => $value)
+			{
+				if ($key <> 'location')
+				{
+					if ($key == 'title')
+					{
+						$value = '<strong>'.$value.'</strong>';
+					}
+					echo get_lang($key).': '.$value.'<br />';
+				}
+			}
+			if (file_exists(api_get_path(SYS_PLUGIN_PATH).$testplugin.'/readme.txt'))
+			{
+				echo "<a href='".api_get_path(WEB_PLUGIN_PATH).$testplugin."/readme.txt'>readme.txt</a>";
+			}
+			echo "\t\t</td>\n";
+
+			echo "\t\t<td align=\"center\">\n";
+			if (in_array('loginpage_menu', $plugin_info['location']))
+			{
+				if (in_array($testplugin, $usedplugins['loginpage_menu']))
+				{
+					$checked = "checked";
+				}
+				else
+				{
+					$checked = '';
+				}
+				echo '<input type="checkbox" name="'.$testplugin.'-loginpage_menu" value="true" '.$checked.'/>';
+			}
+			echo "\t\t</td>\n";
+
+			echo "\t\t<td align=\"center\">\n";
+			if (in_array('campushomepage_menu', $plugin_info['location']))
+			{
+				if (in_array($testplugin, $usedplugins['campushomepage_menu']))
+				{
+					$checked = "checked";
+				}
+				else
+				{
+					$checked = '';
+				}
+				echo '<input type="checkbox" name="'.$testplugin.'-campushomepage_menu" value="true" '.$checked.'/>';
+			}
+			echo "\t\t</td>\n";
+
+			echo "\t\t<td align=\"center\">\n";
+			if (in_array('banner', $plugin_info['location']))
+			{
+				if (in_array($testplugin, $usedplugins['banner']))
+				{
+					$checked = "checked";
+				}
+				else
+				{
+					$checked = '';
+				}
+				echo '<input type="checkbox" name="'.$testplugin.'-banner" value="true"'.$checked.'/>';
+			}
+			echo "\t\t</td>\n";
+			echo "\t</tr>\n";
+		}
+	}
+	echo '</table>';
+
+	echo '<input type="submit" name="SubmitPlugins" value="Submit" /></form>';
+}
+
+/**
+ * This function allows the platform admin to choose the default stylesheet
+ * @author Patrick Cool <patrick.cool@UGent.be>, Ghent University
+*/
+function handle_stylesheets()
+{
+	// Current style
+	$currentstyle = api_get_setting('stylesheets');
+
+	// Preview of the stylesheet
+	echo '<div><iframe src="style_preview.php" width="100%" height="300" name="preview"></iframe></div>';
+
+	echo '<form name="stylesheets" method="post" action="'.$_SERVER['PHP_SELF'].'?category='.$_GET['category'].'">';
+	if ($handle = opendir(api_get_path(SYS_PATH).'main/css/'))
+	{
+		$counter=1;
+		while (false !== ($style_dir = readdir($handle)))
+		{
+			if(substr($style_dir,0,1)=='.'){continue;} //skip dirs starting with a '.'
+			$dirpath = api_get_path(SYS_PATH).'main/css/'.$style_dir;
+			if (is_dir($dirpath))
+			{
+				if ($style_dir != '.' && $style_dir != '..')
+				{
+					if ($currentstyle == $style_dir OR ($style_dir == 'default' AND !$currentstyle))
+					{
+						$selected = 'checked="checked"';
+					}
+					else
+					{
+						$selected = '';
+					}
+
+					echo "<input type=\"radio\" name=\"style\" value=\"".$style_dir."\" ".$selected." onClick=\"parent.preview.location='style_preview.php?style=".$style_dir."';\"/>";
+					echo '<a href="style_preview.php?style='.$style_dir.'" target="preview">'.$style_dir.'</a>';
+					//echo '<div id="Layer'.$counter.'" style="position:relative; width:687px; z-index:2; visibility: hidden;">';
+					//echo '<a href="#" onClick="MM_showHideLayers(\'Layer'.$counter.'\',\'\',\'hide\')">'.get_lang('Close').'</a>';
+					//echo '<iframe src="style_preview.php?style='.$file.'" width="100%" style="float:right;"></iframe></div>';
+					echo "<br />\n";
+					$counter++;
+				}
+			}
+		}
+		closedir($handle);
+	}
+	echo '<input type="submit" name="SubmitStylesheets" value="Submit" /></form>';
+}
+
+/**
+ * This function allows easy activating and inactivating of plugins
+ * @todo: a similar function needs to be written to activate or inactivate additional tools.
+ * @author Patrick Cool <patrick.cool@UGent.be>, Ghent University
+*/
+function store_plugins()
+{
+	$table_settings_current = Database :: get_main_table(MAIN_SETTINGS_CURRENT_TABLE);
+
+	// Step 1 : we remove all the plugins
+	$sql = "DELETE FROM $table_settings_current WHERE category='Plugins'";
+	api_sql_query($sql, __LINE__, __FILE__);
+
+	// step 2: looping through all the post values we only store these which end on loginpage_menu or campushomepage_menu or banner
+	foreach ($_POST as $form_name => $formvalue)
+	{
+		$form_name_elements = explode("-", $form_name);
+		if (in_array('loginpage_menu', $form_name_elements) OR in_array('campushomepage_menu', $form_name_elements) OR in_array('banner', $form_name_elements))
+		{
+			$sql = "INSERT into $table_settings_current (variable,category,selected_value) VALUES ('".$form_name_elements['1']."','Plugins','".$form_name_elements['0']."')";
+			api_sql_query($sql, __LINE__, __FILE__);
+		}
+	}
+}
+
+/**
+ * This function allows the platform admin to choose which should be the default stylesheet
+ * @author Patrick Cool <patrick.cool@UGent.be>, Ghent University
+*/
+function store_stylesheets()
+{
+	$table_settings_current = Database :: get_main_table(MAIN_SETTINGS_CURRENT_TABLE);
+
+	// Delete the current stylesheet (if there is one). We are not sure there is one
+	$sql = "DELETE FROM $table_settings_current WHERE category='stylesheets'";
+	api_sql_query($sql, __LINE__, __FILE__);
+
+	// Insert the stylesheet
+	if ($_POST['style'] <> 'default')
+	{
+		$sql = "INSERT into $table_settings_current (variable,category,selected_value) VALUES ('stylesheets','stylesheets','".$_POST['style']."')";
+		api_sql_query($sql, __LINE__, __FILE__);
+	}
+
+	return true;
+}
+?>

+ 63 - 0
main/admin/statistics.php

@@ -0,0 +1,63 @@
+<?php // $Id: statistics.php 9246 2006-09-25 13:24:53Z bmol $
+/*
+==============================================================================
+	Dokeos - elearning and course management software
+
+	Copyright (c) 2004 Dokeos S.A.
+	Copyright (c) 2003 Ghent University (UGent)
+	Copyright (c) 2001 Universite catholique de Louvain (UCL)
+	Copyright (c) Olivier Brouckaert
+
+	For a full list of contributors, see "credits.txt".
+	The full license can be read in "license.txt".
+
+	This program is free software; you can redistribute it and/or
+	modify it under the terms of the GNU General Public License
+	as published by the Free Software Foundation; either version 2
+	of the License, or (at your option) any later version.
+
+	See the GNU General Public License for more details.
+
+	Contact: Dokeos, 181 rue Royale, B-1000 Brussels, Belgium, info@dokeos.com
+==============================================================================
+*/
+/**
+==============================================================================
+*	@package dokeos.admin
+==============================================================================
+*/
+
+/*
+==============================================================================
+		INIT SECTION
+==============================================================================
+*/
+
+$langFile='admin';
+$cidReset=true;
+include('../inc/global.inc.php');
+$this_section=SECTION_PLATFORM_ADMIN;
+
+api_protect_admin_script();
+
+include_once(api_get_path(LIBRARY_PATH).'fileManage.lib.php');
+
+//$interbreadcrumb[]=array("url" => "index.php","name" => get_lang('PlatformAdmin'));
+$tool_name = get_lang('Statistics');
+Display::display_header($tool_name);
+
+//api_display_tool_title($tool_name);
+
+/*
+==============================================================================
+		MAIN CODE
+==============================================================================
+*/ 
+
+/*
+==============================================================================
+		FOOTER 
+==============================================================================
+*/ 
+Display::display_footer();
+?>

+ 156 - 0
main/admin/style_preview.php

@@ -0,0 +1,156 @@
+<?php
+include_once('../inc/global.inc.php');
+if (isset($_GET['style']) AND $_GET['style']<>'')
+{
+	$htmlHeadXtra[] = '<link href="../css/'.$_GET['style'].'/default.css" rel="stylesheet" type="text/css">';
+}
+Display::display_header($tool_name);
+?>
+
+  <!-- start of #main wrapper for #content and #menu divs -->
+  <!--   Begin Of script Output   -->
+  <div class="maincontent">
+    <h3>tool title</h3>
+    <div id="courseintro">
+      <p>This is the introduction text.
+    </div>
+    <div id="courseintro_icons"><a href="#"><img src="../img/edit.gif" alt="edit"/></a><a href="#"><img src="../img/delete.gif" alt="delete"/></a></div>
+    <div class="normal-message"> Normal Message </div>
+    <div class="error-message"> Error Message </div>
+    <table width="750">
+      <tr>
+        <td><table>
+            <tr>
+              <td width="220"><table id="smallcalendar">
+                  <tr id="title">
+                    <td width="10%"><a href="#">«</a></td>
+                    <td width="80%" colspan="5"> 2006</td>
+                    <td width="10%"><a href="#">»</a></td>
+                  </tr>
+                  <tr>
+                    <td class="weekdays">Mon</td>
+                    <td class="weekdays">Tue</td>
+                    <td class="weekdays">Wed</td>
+                    <td class="weekdays">Thu</td>
+                    <td class="weekdays">Fri</td>
+                    <td class="weekdays">Sat</td>
+                    <td class="weekdays">Sun</td>
+                  </tr>
+                  <tr>
+                    <td>&nbsp;</td>
+                    <td>&nbsp;</td>
+                    <td>&nbsp;</td>
+                    <td>&nbsp;</td>
+                    <td>&nbsp;</td>
+                    <td>&nbsp;</td>
+                    <td class="days_weekend">1</td>
+                  </tr>
+                  <tr>
+                    <td class="days_week">2</td>
+                    <td class="days_week">3</td>
+                    <td class="days_week">4</td>
+                    <td class="days_week">5</td>
+                    <td class="days_week">6</td>
+                    <td class="days_weekend">7</td>
+                    <td class="days_weekend">8</td>
+                  </tr>
+                  <tr>
+                    <td class="days_week">9</td>
+                    <td class="days_week">10</td>
+                    <td class="days_week">11</td>
+                    <td class="days_week">12</td>
+                    <td class="days_week">13</td>
+                    <td class="days_weekend">14</td>
+                    <td class="days_weekend">15</td>
+                  </tr>
+                  <tr>
+                    <td class="days_week">16</td>
+                    <td class="days_week">17</td>
+                    <td class="days_week">18</td>
+                    <td class="days_week">19</td>
+                    <td class="days_week">20</td>
+                    <td class="days_weekend">21</td>
+                    <td class="days_weekend">22</td>
+                  </tr>
+                  <tr>
+                    <td class="days_week">23</td>
+                    <td class="days_today">24</td>
+                    <td class="days_week">25</td>
+                    <td class="days_week">26</td>
+                    <td class="days_week">27</td>
+                    <td class="days_weekend">28</td>
+                    <td class="days_weekend">29</td>
+                  </tr>
+                  <tr>
+                    <td class="days_week">30</td>
+                    <td class="days_week">31</td>
+                    <td>&nbsp;</td>
+                    <td>&nbsp;</td>
+                    <td>&nbsp;</td>
+                    <td>&nbsp;</td>
+                    <td>&nbsp;</td>
+                  </tr>
+                </table>
+              </td>
+            </tr>
+          </table>
+        </td>
+        <td width="500">
+          <table width="100%">
+            <tr>
+              <td></td>
+              <td align="right"></td>
+            </tr>
+          </table>
+          <table class="data_table" width="100%">
+            <tr>
+              <th style="width:100px"><a href="#">firstname</a>&nbsp;&#8595; </th>
+              <th style="width:100px"><a href="#">lastname</a></th>
+            </tr>
+            <tr class="row_even">
+              <td >Firstname</td>
+              <td >Lastname</td>
+            </tr>
+            <tr class="row_odd">
+              <td >Patrick</td>
+              <td >Cool</td>
+            </tr>
+            <tr class="row_even">
+              <td >Patrick</td>
+              <td >Cool</td>
+            </tr>
+            <tr class="row_odd">
+              <td >Patrick</td>
+              <td >Cool</td>
+            </tr>
+          </table>
+          <table width="100%">
+            <tr>
+              <td></td>
+              <td align="right"></td>
+            </tr>
+          </table>
+        </td>
+      </tr>
+    </table>
+  </div>
+  <div class="menu">
+    <form action="#" method="post" id="loginform" name="loginform">
+      <label>Username</label>
+      <input type="text" name="login" id="login" size="15" value="" />
+      <label>Password</label>
+      <input type="password" name="password" id="password" size="15" />
+      <input type="submit" value="OK" name="submitAuth" class="submitauth"/>
+    </form>
+    <div class="menusection"><span class="menusectioncaption">User</span>
+      <ul class="menulist">
+        <li><a href="#">Course Management</a></li>
+        <li><a href="#">Create Course</a></li>
+      </ul>
+    </div>
+    <div class="note"><b>Example notice</b><br />
+      To modify this notice, go to the administration area of the portal.</div>
+  </div>
+<?php
+Display::display_footer();
+?>

+ 180 - 0
main/admin/subscribe_class2course.php

@@ -0,0 +1,180 @@
+<?php
+
+// $Id: subscribe_class2course.php 9246 2006-09-25 13:24:53Z bmol $
+/*
+==============================================================================
+	Dokeos - elearning and course management software
+
+	Copyright (c) 2004 Dokeos S.A.
+	Copyright (c) 2003 Ghent University (UGent)
+	Copyright (c) 2001 Universite catholique de Louvain (UCL)
+	Copyright (c) Olivier Brouckaert
+
+	For a full list of contributors, see "credits.txt".
+	The full license can be read in "license.txt".
+
+	This program is free software; you can redistribute it and/or
+	modify it under the terms of the GNU General Public License
+	as published by the Free Software Foundation; either version 2
+	of the License, or (at your option) any later version.
+
+	See the GNU General Public License for more details.
+
+	Contact: Dokeos, 181 rue Royale, B-1000 Brussels, Belgium, info@dokeos.com
+==============================================================================
+*/
+/**
+============================================================================== 
+*	@package dokeos.admin
+============================================================================== 
+*/
+
+$langFile = 'admin';
+
+$cidReset = true;
+
+require ('../inc/global.inc.php');
+$this_section=SECTION_PLATFORM_ADMIN;
+
+require_once (api_get_path(LIBRARY_PATH).'course.lib.php');
+require_once (api_get_path(LIBRARY_PATH).'classmanager.lib.php');
+api_protect_admin_script();
+$classes = $_GET['classes'];
+$form_sent = 0;
+$error_message = '';
+$first_letter_class = '';
+$first_letter_course = '';
+$courses = array ();
+$classes = array();
+
+$tbl_course = Database :: get_main_table(MAIN_COURSE_TABLE);
+$tbl_class = Database :: get_main_table(MAIN_CLASS_TABLE);
+
+$tool_name = get_lang('AddClassesToACourse');
+
+//$interbreadcrumb[] = array ("url" => "index.php", "name" => get_lang('PlatformAdmin'));
+
+Display :: display_header($tool_name);
+
+//api_display_tool_title($tool_name);
+
+
+if ($_POST['formSent'])
+{
+	$form_sent = $_POST['formSent'];
+	$classes = is_array($_POST['ClassList']) ? $_POST['ClassList'] : array();
+	$courses = is_array($_POST['CourseList']) ? $_POST['CourseList'] : array();
+	$first_letter_class = $_POST['firstLetterClass'];
+	$first_letter_course = $_POST['firstLetterCourse'];
+
+	if ($form_sent == 1)
+	{
+		if (count($classes) == 0 || count($courses) == 0)
+		{
+			Display::display_error_message(get_lang('AtLeastOneClassAndOneCourse'));
+		}
+		elseif (substr($_POST['formSubmit'], -2) == '>>') // add classes to courses 
+		{
+			foreach ($courses as $course_code)
+			{
+				foreach ($classes as $class_id)
+				{
+					ClassManager :: subscribe_to_course($class_id, $course_code);
+				}
+			}
+			Display::display_normal_message(get_lang('ClassesSubscribed'));
+		}
+		else // remove classes from courses
+			{
+			foreach ($courses as $course_code)
+			{
+				foreach ($classes as $class_id)
+				{
+					ClassManager :: unsubscribe_from_course($class_id, $course_code);
+				}
+			}
+			Display::display_normal_message(get_lang('ClassesUnsubscribed'));
+		}
+	}
+}
+
+$sql = "SELECT id,name FROM $tbl_class WHERE name LIKE '".$first_letter_class."%' ORDER BY ". (count($classes) > 0 ? "(id IN('".implode("','", $classes)."')) DESC," : "")." name";
+$result = api_sql_query($sql, __FILE__, __LINE__);
+$db_classes = api_store_result($result);
+$sql = "SELECT code,visual_code,title FROM $tbl_course WHERE visual_code LIKE '".$first_letter_course."%' ORDER BY ". (count($courses) > 0 ? "(code IN('".implode("','", $courses)."')) DESC," : "")." visual_code";
+$result = api_sql_query($sql, __FILE__, __LINE__);
+$db_courses = api_store_result($result);
+if (!empty ($error_message))
+{
+	Display :: display_normal_message($error_message); 
+}
+?>
+<form name="formulaire" method="post" action="<?php echo $_SERVER['PHP_SELF']; ?>" style="margin:0px;">
+ <input type="hidden" name="formSent" value="1"/>
+ <table border="0" cellpadding="5" cellspacing="0" width="100%">
+  <tr>
+   <td width="40%" align="center">
+    <b><?php echo get_lang('ClassList'); ?></b>
+    <br/><br/>
+    <?php echo get_lang('FirstLetterClass'); ?> : 
+    <select name="firstLetterClass" onchange="javascript:document.formulaire.formSent.value='2'; document.formulaire.submit();">
+     <option value="">--</option>
+     <?php
+     echo Display::get_alphabet_options($first_letter_class);
+     ?>
+    </select>
+   </td>
+   <td width="20%">&nbsp;</td>
+   <td width="40%" align="center">
+    <b><?php echo get_lang('CourseList'); ?> :</b>
+    <br/><br/>
+    <?php echo get_lang('FirstLetterCourse'); ?> : 
+    <select name="firstLetterCourse" onchange="javascript:document.formulaire.formSent.value='2'; document.formulaire.submit();">
+     <option value="">--</option>
+     <?php
+     echo Display::get_alphabet_options($first_letter_course);
+     ?>
+    </select>
+   </td>
+  </tr>
+  <tr>
+   <td width="40%" align="center">
+    <select name="ClassList[]" multiple="multiple" size="20" style="width:230px;">
+<?php
+foreach ($db_classes as $class)
+{
+?>
+	<option value="<?php echo $class['id']; ?>" <?php if(in_array($class['id'],$classes)) echo 'selected="selected"'; ?>><?php echo $class['name']; ?></option>
+<?php
+}
+?>
+    </select>
+   </td>
+   <td width="20%" valign="middle" align="center">
+    <input type="submit" name="formSubmit" value="<?php echo get_lang('AddToThatCourse'); ?> &gt;&gt;"/>
+    <br/>
+    <input type="submit" name="formSubmit" value="&lt;&lt; <?php echo get_lang('DeleteSelectedClasses'); ?>"/>
+   </td>
+   <td width="40%" align="center">
+    <select name="CourseList[]" multiple="multiple" size="20" style="width:230px;">
+<?php
+foreach ($db_courses as $course)
+{
+?>
+	<option value="<?php echo $course['code']; ?>" <?php if(in_array($course['code'],$courses)) echo 'selected="selected"'; ?>><?php echo '('.$course['visual_code'].') '.$course['title']; ?></option>
+<?php
+}
+?>
+    </select>
+   </td>
+  </tr>
+ </table>
+</form>
+<?php
+/*
+==============================================================================
+		FOOTER 
+==============================================================================
+*/
+Display :: display_footer();
+?>

+ 191 - 0
main/admin/subscribe_user2class.php

@@ -0,0 +1,191 @@
+<?php
+// $Id: subscribe_user2class.php 9246 2006-09-25 13:24:53Z bmol $
+/*
+==============================================================================
+	Dokeos - elearning and course management software
+
+	Copyright (c) 2004 Dokeos S.A.
+	Copyright (c) 2003 Ghent University (UGent)
+	Copyright (c) 2001 Universite catholique de Louvain (UCL)
+	Copyright (c) Olivier Brouckaert
+
+	For a full list of contributors, see "credits.txt".
+	The full license can be read in "license.txt".
+
+	This program is free software; you can redistribute it and/or
+	modify it under the terms of the GNU General Public License
+	as published by the Free Software Foundation; either version 2
+	of the License, or (at your option) any later version.
+
+	See the GNU General Public License for more details.
+
+	Contact: Dokeos, 181 rue Royale, B-1000 Brussels, Belgium, info@dokeos.com
+==============================================================================
+*/
+/**
+============================================================================== 
+*	@package dokeos.admin
+============================================================================== 
+*/
+
+$langFile = 'admin';
+
+$cidReset = true;
+
+require ('../inc/global.inc.php');
+require_once (api_get_path(LIBRARY_PATH).'classmanager.lib.php');
+api_protect_admin_script();
+$course = $_GET['course'];
+$class_id = intval($_GET['idclass']);
+$form_sent = 0;
+$error_message = '';
+$first_letter_left = '';
+$first_letter_right = '';
+$left_user_list = array();
+$right_user_list = array ();
+
+$tbl_class = Database :: get_main_table(MAIN_CLASS_TABLE);
+$tbl_class_user = Database :: get_main_table(MAIN_CLASS_USER_TABLE);
+$tbl_user = Database :: get_main_table(MAIN_USER_TABLE);
+
+$sql = "SELECT name FROM $tbl_class WHERE id='$class_id'";
+$result = api_sql_query($sql, __FILE__, __LINE__);
+
+if (!list ($class_name) = mysql_fetch_row($result))
+{
+	header('Location: class_list.php?filtreCours='.urlencode($course));
+	exit ();
+}
+
+$noPHP_SELF = true;
+
+$tool_name = get_lang('AddUsersToAClass').' ('.$class_name.')';
+
+//$interbreadcrumb[] = array ("url" => "index.php", "name" => get_lang('PlatformAdmin'));
+$interbreadcrumb[] = array ("url" => "class_list.php?filtreCours=".urlencode($course), "name" => get_lang('AdminClasses'));
+
+if ($_POST['formSent'])
+{
+	$form_sent = $_POST['formSent'];
+	$first_letter_left = $_POST['firstLetterLeft'];
+	$first_letter_right = $_POST['firstLetterRight'];
+	$left_user_list = is_array($_POST['LeftUserList']) ? $_POST['LeftUserList'] : array();
+	$right_user_list = is_array($_POST['RightUserList']) ? $_POST['RightUserList'] : array();
+	$add_to_class = empty ($_POST['addToClass']) ? 0 : 1;
+	$remove_from_class = empty ($_POST['removeFromClass']) ? 0 : 1;
+	if ($form_sent == 1)
+	{
+		if ($add_to_class)
+		{
+			if (count($left_user_list) == 0)
+			{
+				$error_message = get_lang('AtLeastOneUser');
+			}
+			else
+			{
+				foreach ($left_user_list as $user_id)
+				{
+					ClassManager :: add_user($user_id, $class_id);
+				}
+				header('Location: class_list.php?filtreCours='.urlencode($course));
+				exit ();
+			}
+		}
+		elseif ($remove_from_class)
+		{
+			if (count($right_user_list) == 0)
+				$error_message = get_lang('AtLeastOneUser');
+			else
+			{
+				foreach ($right_user_list as $index => $user_id)
+				{
+					ClassManager :: unsubscribe_user($user_id, $class_id);
+				}
+				header('Location: class_list.php?filtreCours='.urlencode($course));
+				exit ();
+			}
+		}
+	}
+}
+Display :: display_header($tool_name);
+//api_display_tool_title($tool_name);
+$sql = "SELECT u.user_id,lastname,firstname,username FROM $tbl_user u LEFT JOIN $tbl_class_user cu ON u.user_id=cu.user_id AND class_id='$class_id' WHERE lastname LIKE '".$first_letter_left."%' AND class_id IS NULL ORDER BY ". (count($left_user_list) > 0 ? "(user_id IN(".implode(',', $left_user_list).")) DESC," : "")." lastname";
+$result = api_sql_query($sql, __FILE__, __LINE__);
+$left_users = api_store_result($result);
+$sql = "SELECT u.user_id,lastname,firstname,username FROM $tbl_user u,$tbl_class_user cu WHERE cu.user_id=u.user_id AND class_id='$class_id' AND lastname LIKE '".$first_letter_right."%' ORDER BY ". (count($right_user_list) > 0 ? "(user_id IN(".implode(',', $right_user_list).")) DESC," : "")." lastname";
+$result = api_sql_query($sql, __FILE__, __LINE__);
+$right_users = api_store_result($result);
+if (!empty ($error_message))
+{
+	Display :: display_normal_message($error_message); 
+}
+?>
+<form name="formulaire" method="post" action="<?php echo $_SERVER['PHP_SELF']; ?>?course=<?php echo urlencode($course); ?>&amp;idclass=<?php echo $class_id; ?>" style="margin:0px;">
+ <input type="hidden" name="formSent" value="1"/>
+ <table border="0" cellpadding="5" cellspacing="0" width="100%">
+  <tr>
+   <td width="40%" align="center">
+    <b><?php echo get_lang('UsersOutsideClass'); ?> :</b>
+    <br/><br/>
+    <?php echo get_lang('FirstLetterUser'); ?> : 
+    <select name="firstLetterLeft" onchange="javascript:document.formulaire.formSent.value='2'; document.formulaire.submit();">
+     <option value="">--</option>
+      <?php
+      echo Display :: get_alphabet_options($first_letter_left);
+      ?>  
+    </select>
+   </td>
+   <td width="20%">&nbsp;</td>
+   <td width="40%" align="center">
+    <b><?php echo get_lang('UsersInsideClass'); ?> :</b>
+    <br/><br/>
+    <?php echo get_lang('FirstLetterUser'); ?> : 
+    <select name="firstLetterRight" onchange="javascript:document.formulaire.formSent.value='2'; document.formulaire.submit();">
+     <option value="">--</option>
+<?php
+echo Display :: get_alphabet_options($first_letter_right);
+?>
+   </select>
+   </td>
+  </tr>
+  <tr>
+   <td width="40%" align="center">
+    <select name="LeftUserList[]" multiple="multiple" size="20" style="width:230px;">
+<?php
+foreach ($left_users as $user)
+{
+?>
+     <option value="<?php echo $user['user_id']; ?>" <?php if(in_array($user['user_id'],$left_user_list)) echo 'selected="selected"'; ?>><?php echo $user['lastname'].' '.$user['firstname'].' ('.$user['username'].')'; ?></option>
+<?php
+}
+?>
+    </select>
+   </td>
+   <td width="20%" valign="middle" align="center">
+	<input type="submit" name="addToClass" value="<?php echo get_lang('AddToClass'); ?> &gt;&gt;"/>
+	<br/><br/>
+	<input type="submit" name="removeFromClass" value="&lt;&lt; <?php echo get_lang('RemoveFromClass'); ?>"/>
+   </td>
+   <td width="40%" align="center">
+    <select name="RightUserList[]" multiple="multiple" size="20" style="width:230px;">
+<?php
+foreach ($right_users as $user)
+{
+?>
+     <option value="<?php echo $user['user_id']; ?>" <?php if(in_array($user['user_id'],$right_user_list)) echo 'selected="selected"'; ?>><?php echo $user['lastname'].' '.$user['firstname'].' ('.$user['username'].')'; ?></option>
+<?php
+}
+?>
+    </select>
+   </td>
+  </tr>
+ </table>
+</form>
+<?php
+/*
+==============================================================================
+		FOOTER 
+==============================================================================
+*/
+Display :: display_footer();
+?>

+ 201 - 0
main/admin/subscribe_user2course.php

@@ -0,0 +1,201 @@
+<?php
+// $Id: subscribe_user2course.php 9246 2006-09-25 13:24:53Z bmol $
+/*
+==============================================================================
+	Dokeos - elearning and course management software
+	
+	Copyright (c) 2004 Dokeos S.A.
+	Copyright (c) 2003 Ghent University (UGent)
+	Copyright (c) 2001 Universite catholique de Louvain (UCL)
+	Copyright (c) Olivier Brouckaert
+	
+	For a full list of contributors, see "credits.txt".
+	The full license can be read in "license.txt".
+	
+	This program is free software; you can redistribute it and/or
+	modify it under the terms of the GNU General Public License
+	as published by the Free Software Foundation; either version 2
+	of the License, or (at your option) any later version.
+	
+	See the GNU General Public License for more details.
+	
+	Contact address: Dokeos, 44 rue des palais, B-1030 Brussels, Belgium
+	Mail: info@dokeos.com
+==============================================================================
+*/
+/**
+============================================================================== 
+*	This script allows platform admins to add users to courses.
+*	It displays a list of users and a list of courses;
+*	you can select multiple users and courses and then click on
+*	'Add to this(these) course(s)'.
+*
+*	@package dokeos.admin
+============================================================================== 
+*/
+
+/*
+==============================================================================
+		INIT SECTION
+==============================================================================
+*/
+
+$langFile = 'admin';
+
+$cidReset = true;
+
+require ('../inc/global.inc.php');
+$this_section=SECTION_PLATFORM_ADMIN;
+
+require_once(api_get_path(LIBRARY_PATH).'course.lib.php');
+api_protect_admin_script();
+/*
+-----------------------------------------------------------
+	Global constants and variables
+-----------------------------------------------------------
+*/
+
+$users = $_GET['users'];
+$form_sent = 0;
+$first_letter_user = '';
+$first_letter_course = '';
+$courses = array ();
+$users = array();
+$tbl_course = Database :: get_main_table(MAIN_COURSE_TABLE);
+$tbl_user = Database :: get_main_table(MAIN_USER_TABLE);
+
+/*
+-----------------------------------------------------------
+	Header
+-----------------------------------------------------------
+*/
+$tool_name = get_lang('AddUsersToACourse');
+//$interbreadcrumb[] = array ("url" => "index.php", "name" => get_lang('PlatformAdmin'));
+Display :: display_header($tool_name);
+//api_display_tool_title($tool_name);
+
+/*
+==============================================================================
+		MAIN CODE
+==============================================================================
+*/
+
+/*
+-----------------------------------------------------------
+	React on POSTed request
+-----------------------------------------------------------
+*/
+if ($_POST['formSent'])
+{
+	$form_sent = $_POST['formSent'];
+	$users = is_array($_POST['UserList']) ? $_POST['UserList'] : array() ;
+	$courses = is_array($_POST['CourseList']) ? $_POST['CourseList'] : array() ;
+	$first_letter_user = $_POST['firstLetterUser'];
+	$first_letter_course = $_POST['firstLetterCourse'];
+
+	foreach($users as $key => $value)
+	{
+		$users[$key] = intval($value);	
+	}
+
+	if ($form_sent == 1)
+	{
+		if ( count($users) == 0 || count($courses) == 0)
+		{
+			Display :: display_error_message(get_lang('AtLeastOneUserAndOneCourse'));
+		}
+		else
+		{
+			foreach ($courses as $course_code)
+			{
+				foreach ($users as $user_id)
+				{
+					CourseManager::subscribe_user($user_id,$course_code);
+				}
+			}
+			Display :: display_normal_message(get_lang('UsersAreSubscibedToCourse'));
+		}
+	}
+}
+
+/*
+-----------------------------------------------------------
+	Display GUI
+-----------------------------------------------------------
+*/
+
+$sql = "SELECT user_id,lastname,firstname,username FROM $tbl_user WHERE lastname LIKE '".$first_letter_user."%' ORDER BY ". (count($users) > 0 ? "(user_id IN(".implode(',', $users).")) DESC," : "")." lastname";
+$result = api_sql_query($sql, __FILE__, __LINE__);
+$db_users = api_store_result($result);
+$sql = "SELECT code,visual_code,title FROM $tbl_course WHERE visual_code LIKE '".$first_letter_course."%' ORDER BY ". (count($courses) > 0 ? "(code IN('".implode("','", $courses)."')) DESC," : "")." visual_code";
+$result = api_sql_query($sql, __FILE__, __LINE__);
+$db_courses = api_store_result($result);
+?>
+
+<form name="formulaire" method="post" action="<?php echo $_SERVER['PHP_SELF']; ?>" style="margin:0px;">
+ <input type="hidden" name="formSent" value="1"/>
+  <table border="0" cellpadding="5" cellspacing="0" width="100%">
+   <tr>
+    <td width="40%" align="center">
+     <b><?php echo get_lang('UserList'); ?></b>
+     <br/><br/>
+     <?php echo get_lang('FirstLetterUser'); ?> : 
+     <select name="firstLetterUser" onchange="javascript:document.formulaire.formSent.value='2'; document.formulaire.submit();">
+      <option value="">--</option>
+      <?php
+        echo Display :: get_alphabet_options($first_letter_user);
+      ?>
+     </select>
+    </td>
+    <td width="20%">&nbsp;</td>
+    <td width="40%" align="center">
+     <b><?php echo get_lang('CourseList'); ?> :</b>
+     <br/><br/>
+     <?php echo get_lang('FirstLetterCourse'); ?> : 
+     <select name="firstLetterCourse" onchange="javascript:document.formulaire.formSent.value='2'; document.formulaire.submit();">
+      <option value="">--</option>
+      <?php
+      echo Display :: get_alphabet_options($first_letter_course);
+      ?> 
+     </select>
+    </td>
+   </tr>
+   <tr>
+    <td width="40%" align="center">
+     <select name="UserList[]" multiple="multiple" size="20" style="width:230px;">
+<?php
+foreach ($db_users as $user)
+{
+?>
+	  <option value="<?php echo $user['user_id']; ?>" <?php if(in_array($user['user_id'],$users)) echo 'selected="selected"'; ?>><?php echo $user['lastname'].' '.$user['firstname'].' ('.$user['username'].')'; ?></option>
+<?php
+}
+?>
+    </select>
+   </td>
+   <td width="20%" valign="middle" align="center">
+    <input type="submit" value="<?php echo get_lang('AddToThatCourse'); ?> &gt;&gt;"/>
+   </td>
+   <td width="40%" align="center">
+    <select name="CourseList[]" multiple="multiple" size="20" style="width:230px;">
+<?php
+foreach ($db_courses as $course)
+{
+?>
+	 <option value="<?php echo $course['code']; ?>" <?php if(in_array($course['code'],$courses)) echo 'selected="selected"'; ?>><?php echo '('.$course['visual_code'].') '.$course['title']; ?></option>
+<?php
+}
+?>
+    </select>
+   </td>
+  </tr>
+ </table>
+</form>
+<?php
+/*
+==============================================================================
+		FOOTER 
+==============================================================================
+*/
+Display :: display_footer();
+?>

+ 265 - 0
main/admin/system_announcements.php

@@ -0,0 +1,265 @@
+<?php
+// $Id: system_announcements.php 9246 2006-09-25 13:24:53Z bmol $
+/*
+==============================================================================
+	Dokeos - elearning and course management software
+
+	Copyright (c) 2004 Dokeos S.A.
+	Copyright (c) 2003 Ghent University (UGent)
+	Copyright (c) 2001 Universite catholique de Louvain (UCL)
+	Copyright (c) 2005 Bart Mollet, Hogeschool Gent
+
+	For a full list of contributors, see "credits.txt".
+	The full license can be read in "license.txt".
+
+	This program is free software; you can redistribute it and/or
+	modify it under the terms of the GNU General Public License
+	as published by the Free Software Foundation; either version 2
+	of the License, or (at your option) any later version.
+
+	See the GNU General Public License for more details.
+
+	Contact: Dokeos, 181 rue Royale, B-1000 Brussels, Belgium, info@dokeos.com
+==============================================================================
+*/
+/**
+==============================================================================
+*	This page allows the administrator to manage the system announcements.
+*	@package dokeos.admin
+==============================================================================
+*/
+/*
+==============================================================================
+		INIT SECTION
+==============================================================================
+*/
+$langFile = array ('admin', 'agenda');
+$cidReset = true;
+include ('../inc/global.inc.php');
+$this_section=SECTION_PLATFORM_ADMIN;
+
+require_once api_get_path(LIBRARY_PATH).'formvalidator/FormValidator.class.php';
+api_protect_admin_script();
+if(empty($_GET['lang']))
+{
+    $_GET['lang']=$_SESSION['user_language_choice'];
+}
+/*
+-----------------------------------------------------------
+	Libraries
+-----------------------------------------------------------
+*/
+include (api_get_path(LIBRARY_PATH).'system_announcements.lib.php');
+$tool_name = get_lang('SystemAnnouncements');
+//$interbreadcrumb[] = array ("url" => "index.php", "name" => get_lang('PlatformAdmin'));
+
+/*
+-----------------------------------------------------------
+	Header
+-----------------------------------------------------------
+*/
+Display :: display_header($tool_name);
+//api_display_tool_title($tool_name);
+/*
+==============================================================================
+		MAIN CODE
+==============================================================================
+*/
+
+if($_GET['action'] != 'add' && $_GET['action'] != 'edit'){
+
+	$form = new FormValidator('languagechange','GET');
+	$language_list = api_get_languages();
+	$language_list_with_keys = array();
+	for($i=0; $i<count($language_list['name']) ; $i++) {
+		$language_list_with_keys[$language_list['folder'][$i]] = $language_list['name'][$i];
+	}
+	$form->addElement('select', 'lang',get_lang('Language'),$language_list_with_keys);
+	$form->addElement('submit', 'submit', get_lang('Ok'));
+	$form->display();
+	echo '<a href="?action=add">'.get_lang('AddAnnouncement').'</a>';
+}
+$form_action = "";
+$show_announcement_list = true;
+if (isset ($_GET['action']) && $_GET['action'] == 'make_visible')
+{
+	switch ($_GET['person'])
+	{
+		case VISIBLE_TEACHER :
+			SystemAnnouncementManager :: set_visibility($_GET['id'], VISIBLE_TEACHER, true);
+			break;
+		case VISIBLE_STUDENT :
+			SystemAnnouncementManager :: set_visibility($_GET['id'], VISIBLE_STUDENT, true);
+			break;
+		case VISIBLE_GUEST :
+			SystemAnnouncementManager :: set_visibility($_GET['id'], VISIBLE_GUEST, true);
+			break;
+	}
+}
+if (isset ($_GET['action']) && $_GET['action'] == 'make_invisible')
+{
+	switch ($_GET['person'])
+	{
+		case VISIBLE_TEACHER :
+			SystemAnnouncementManager :: set_visibility($_GET['id'], VISIBLE_TEACHER, false);
+			break;
+		case VISIBLE_STUDENT :
+			SystemAnnouncementManager :: set_visibility($_GET['id'], VISIBLE_STUDENT, false);
+			break;
+		case VISIBLE_GUEST :
+			SystemAnnouncementManager :: set_visibility($_GET['id'], VISIBLE_GUEST, false);
+			break;
+	}
+}
+
+// Form was posted?
+if (isset ($_POST['action']))
+{
+	$action_todo = true;
+}
+
+// Delete an announcement
+if (isset ($_GET['action']) && $_GET['action'] == 'delete')
+{
+	SystemAnnouncementManager :: delete_announcement($_GET['id']);
+	Display :: display_normal_message(get_lang('AnnouncementDeleted'));
+}
+// Delete selected announcements
+if (isset ($_POST['action']) && $_POST['action'] == 'delete_selected')
+{
+	foreach($_POST['id'] as $index => $id)
+	{
+		SystemAnnouncementManager :: delete_announcement($id);	
+	}
+	Display :: display_normal_message(get_lang('AnnouncementDeleted'));
+	$action_todo = false;
+}
+// Add an announcement
+if (isset ($_GET['action']) && $_GET['action'] == 'add')
+{
+	$values['action'] = 'add';
+	// Set default time window: NOW -> NEXT WEEK
+	$values['start'] = date('Y-m-d H:i:s');
+	$values['end'] = date('Y-m-d H:i:s',time() + (7 * 24 * 60 * 60));
+	$action_todo = true;
+}
+// Edit an announcement
+if (isset ($_GET['action']) && $_GET['action'] == 'edit')
+{
+	$announcement = SystemAnnouncementManager :: get_announcement($_GET['id']);
+	$values['id'] = $announcement->id;
+	$values['title'] = $announcement->title;
+	$values['content'] = $announcement->content;
+	$values['start'] = $announcement->date_start;
+	$values['end'] = $announcement->date_end;
+	$values['visible_teacher'] = $announcement->visible_teacher;
+	$values['visible_student'] = $announcement->visible_student ;
+	$values['visible_guest'] = $announcement->visible_guest ;
+	$values['lang'] = $announcement->lang;
+	$values['action'] = 'edit';
+	$action_todo = true;
+}
+
+if ($action_todo)
+{
+	$form = new FormValidator('system_announcement');
+	$form->add_textfield('title', get_lang('Title'));
+	$language_list = api_get_languages();
+	$language_list_with_keys = array();
+	for($i=0; $i<count($language_list['name']) ; $i++) {
+		$language_list_with_keys[$language_list['folder'][$i]] = $language_list['name'][$i];
+	}
+	$form->addElement('select', 'lang',get_lang('Language'),$language_list_with_keys);
+	$form->add_html_editor('content', get_lang('Content'));
+	$form->add_timewindow('start','end',get_lang('StartTimeWindow'),get_lang('EndTimeWindow'));
+	$form->addElement('checkbox', 'visible_teacher', get_lang('Visible'), get_lang('Teacher'));
+	$form->addElement('checkbox', 'visible_student', null, get_lang('Student'));
+	$form->addElement('checkbox', 'visible_guest', null, get_lang('Guest'));
+	$form->addElement('hidden', 'action');
+	$form->addElement('hidden', 'id');
+	$form->addElement('submit', 'submit', get_lang('Ok'));
+	$form->setDefaults($values);
+	if($form->validate())
+	{
+		$values = $form->exportValues();
+		if( !isset($values['visible_teacher']))
+		{
+			$values['visible_teacher'] = false;	
+		}
+		if( !isset($values['visible_student']))
+		{
+			$values['visible_student'] = false;	
+		}
+		if( !isset($values['visible_guest']))
+		{
+			$values['visible_guest'] = false;	
+		}
+		switch($values['action'])
+		{
+			case 'add':
+				if(SystemAnnouncementManager::add_announcement($values['title'],$values['content'],$values['start'],$values['end'],$values['visible_teacher'],$values['visible_student'],$values['visible_guest'], $values['lang']))
+					Display :: display_normal_message(get_lang('AnnouncementAdded'));
+				else {
+					$show_announcement_list = false;
+					$form->display();
+				}
+				break;
+			case 'edit':
+				if (SystemAnnouncementManager::update_announcement($values['id'],$values['title'],$values['content'],$values['start'],$values['end'],$values['visible_teacher'],$values['visible_student'],$values['visible_guest'], $values['lang']))
+					Display :: display_normal_message(get_lang('AnnouncementUpdated'));
+				else {
+					$show_announcement_list = false;
+					$form->display();
+				}
+				break;
+			default:	
+				break;
+		}
+		$show_announcement_list = true;
+	}
+	else
+	{
+		$form->display();
+		$show_announcement_list = false;
+	}
+}
+if ($show_announcement_list)
+{
+	$announcements = SystemAnnouncementManager :: get_all_announcements($_GET['lang']);
+	$announcement_data = array ();
+	foreach ($announcements as $index => $announcement)
+	{
+		$row = array ();
+		$row[] = $announcement->id;
+		$row[] = "<img src=\"../img/". ($announcement->visible ? 'visible.gif' : 'invisible.gif')."\"/>";
+		$row[] = $announcement->date_start;
+		$row[] = $announcement->date_end;
+		$row[] = "<a href=\"?id=".$announcement->id."&amp;person=".VISIBLE_TEACHER."&amp;action=". ($announcement->visible_teacher ? 'make_invisible' : 'make_visible')."\"><img src=\"../img/". ($announcement->visible_teacher  ? 'visible.gif' : 'invisible.gif')."\" border=\"0\"></a>";
+		$row[] = "<a href=\"?id=".$announcement->id."&amp;person=".VISIBLE_STUDENT."&amp;action=". ($announcement->visible_student  ? 'make_invisible' : 'make_visible')."\"><img src=\"../img/". ($announcement->visible_student ? 'visible.gif' : 'invisible.gif')."\" border=\"0\"></a>";
+		$row[] = "<a href=\"?id=".$announcement->id."&amp;person=".VISIBLE_GUEST."&amp;action=". ($announcement->visible_guest ? 'make_invisible' : 'make_visible')."\"><img src=\"../img/". ($announcement->visible_guest  ? 'visible.gif' : 'invisible.gif')."\" border=\"0\"></a>";
+		$row[] = $announcement->title;
+		$row[] = "<a href=\"?action=edit&id=".$announcement->id."\"><img src=\"../img/edit.gif\" border=\"0\"/></a> <a href=\"?action=delete&id=".$announcement->id."\"  onclick=\"javascript:if(!confirm('".addslashes(htmlentities(get_lang("ConfirmYourChoice")))."')) return false;\"><img src=\"../img/delete.gif\" border=\"0\"/></a>";
+		$announcement_data[] = $row;
+	}
+	$table = new SortableTableFromArray($announcement_data);
+	$table->set_header(0,'',false);
+	$table->set_header(1,'', false);
+	$table->set_header(2,get_lang('StartTimeWindow'));
+	$table->set_header(3,get_lang('EndTimeWindow'));
+	$table->set_header(4,get_lang('Teacher'));
+	$table->set_header(5,get_lang('Student'));
+	$table->set_header(6,get_lang('Guest'));
+	$table->set_header(7,get_lang('Title'));
+	$table->set_header(8,get_lang('Modify'), false);
+	$form_actions = array();
+	$form_actions['delete_selected'] = get_lang('Delete');
+	$table->set_form_actions($form_actions);
+	$table->display();
+}
+/*
+==============================================================================
+		FOOTER 
+==============================================================================
+*/
+Display :: display_footer();
+?>

+ 234 - 0
main/admin/user_add.php

@@ -0,0 +1,234 @@
+<?php // $Id: user_add.php 9812 2006-10-26 08:57:18Z bmol $
+/*
+==============================================================================
+	Dokeos - elearning and course management software
+
+	Copyright (c) 2004 Dokeos S.A.
+	Copyright (c) 2003 Ghent University (UGent)
+	Copyright (c) 2001 Universite catholique de Louvain (UCL)
+	Copyright (c) Olivier Brouckaert
+	Copyright (c) Bart Mollet, Hogeschool Gent
+
+	For a full list of contributors, see "credits.txt".
+	The full license can be read in "license.txt".
+
+	This program is free software; you can redistribute it and/or
+	modify it under the terms of the GNU General Public License
+	as published by the Free Software Foundation; either version 2
+	of the License, or (at your option) any later version.
+
+	See the GNU General Public License for more details.
+
+	Contact: Dokeos, 181 rue Royale, B-1000 Brussels, Belgium, info@dokeos.com
+==============================================================================
+*/
+/**
+==============================================================================
+*	@package dokeos.admin
+==============================================================================
+*/
+$langFile = array('admin','registration');
+$cidReset = true;
+include ('../inc/global.inc.php');
+$this_section=SECTION_PLATFORM_ADMIN;
+
+api_protect_admin_script();
+$table_admin = Database :: get_main_table(MAIN_ADMIN_TABLE);
+$table_user = Database :: get_main_table(MAIN_USER_TABLE);
+
+include (api_get_path(LIBRARY_PATH).'fileManage.lib.php');
+include (api_get_path(LIBRARY_PATH).'fileUpload.lib.php');
+include (api_get_path(LIBRARY_PATH).'usermanager.lib.php');
+require_once (api_get_path(LIBRARY_PATH).'formvalidator/FormValidator.class.php');
+
+
+$htmlHeadXtra[] = '
+<script language="JavaScript" type="text/JavaScript">
+<!--
+function enable_expiration_date() { //v2.0
+	document.user_add.radio_expiration_date[0].checked=false;
+	document.user_add.radio_expiration_date[1].checked=true;
+}
+//-->
+</script>';
+
+if(!empty($_GET['message'])){
+	$message = urldecode($_GET['message']);
+}
+
+//$interbreadcrumb[] = array ("url" => "index.php", "name" => get_lang('PlatformAdmin'));
+$tool_name = get_lang('AddUsers');
+// Create the form
+$form = new FormValidator('user_add');
+// Lastname
+$form->addElement('text','lastname',get_lang('LastName'));
+$form->applyFilter('lastname','html_filter');
+$form->applyFilter('lastname','trim');
+$form->addRule('lastname', get_lang('ThisFieldIsRequired'), 'required');
+// Firstname
+$form->addElement('text','firstname',get_lang('FirstName'));
+$form->applyFilter('firstname','html_filter');
+$form->applyFilter('firstname','trim');
+$form->addRule('firstname', get_lang('ThisFieldIsRequired'), 'required');
+// Official code
+$form->addElement('text', 'official_code', get_lang('OfficialCode'),array('size' => '40'));
+$form->applyFilter('official_code','html_filter');
+$form->applyFilter('official_code','trim');
+// Email
+$form->addElement('text', 'email', get_lang('Email'),array('size' => '40'));
+$form->addRule('email', get_lang('EmailWrong'), 'email');
+$form->addRule('email', get_lang('EmailWrong'), 'required');
+// Phone
+$form->addElement('text','phone',get_lang('PhoneNumber'));
+// Picture
+$form->addElement('file', 'picture', get_lang('AddPicture'));
+$allowed_picture_types = array ('jpg', 'jpeg', 'png', 'gif');
+$form->addRule('picture', get_lang('OnlyImagesAllowed').' ('.implode(',', $allowed_picture_types).')', 'filetype', $allowed_picture_types);
+// Username
+$form->addElement('text', 'username', get_lang('LoginName'),array('maxlength'=>20));
+$form->addRule('username', get_lang('ThisFieldIsRequired'), 'required');
+$form->addRule('username', get_lang('OnlyLettersAndNumbersAllowed'), 'username');
+$form->addRule('username', '', 'maxlength',20);
+$form->addRule('username', get_lang('UserTaken'), 'username_available', $user_data['username']);
+// Password
+$group = array();
+$auth_sources = 0; //make available wider as we need it in case of form reset (see below)
+if(count($extAuthSource) > 0)
+{
+	$group[] =& HTML_QuickForm::createElement('radio','password_auto',null,get_lang('ExternalAuthentication').' ',2);
+	$auth_sources = array();
+	foreach($extAuthSource as $key => $info)
+	{
+		$auth_sources[$key] = $key;
+	}
+	$group[] =& HTML_QuickForm::createElement('select','auth_source',null,$auth_sources);
+	$group[] =& HTML_QuickForm::createElement('static','','','<br />');
+}
+$group[] =& HTML_QuickForm::createElement('radio','password_auto',get_lang('Password'),get_lang('AutoGeneratePassword').'<br />',1);
+$group[] =& HTML_QuickForm::createElement('radio', 'password_auto',null,null,0);
+$group[] =& HTML_QuickForm::createElement('password', 'password',null,null);
+$form->addGroup($group, 'password', get_lang('Password'), '');
+// Status
+$status = array();
+$status[COURSEMANAGER]  = get_lang('CourseAdmin');
+$status[STUDENT] = get_lang('Student');
+$form->addElement('select','status',get_lang('Status'),$status);
+// Platform admin
+$group = array();
+$group[] =& HTML_QuickForm::createElement('radio', 'platform_admin',null,get_lang('Yes'),1);
+$group[] =& HTML_QuickForm::createElement('radio', 'platform_admin',null,get_lang('No'),0);
+$form->addGroup($group, 'admin', get_lang('PlatformAdmin'), '&nbsp;');
+// Send email
+$group = array();
+$group[] =& HTML_QuickForm::createElement('radio', 'send_mail',null,get_lang('Yes'),1);
+$group[] =& HTML_QuickForm::createElement('radio', 'send_mail',null,get_lang('No'),0);
+$form->addGroup($group, 'mail', get_lang('SendMailToNewUser'), '&nbsp;');
+// Expiration Date
+$form->addElement('radio', 'radio_expiration_date', get_lang('ExpirationDate'), get_lang('NeverExpires'), 0);
+$group = array ();
+$group[] = & $form->createElement('radio', 'radio_expiration_date', null, get_lang('On'), 1);
+$group[] = & $form->createElement('datepicker','expiration_date', null, array ('form_name' => $form->getAttribute('name'), 'onChange'=>'enable_expiration_date()'));
+$form->addGroup($group, 'max_member_group', null, '', false);
+// Active account or inactive account
+$form->addElement('radio','active',get_lang('ActiveAccount'),get_lang('Active'),1);
+$form->addElement('radio','active','',get_lang('Inactive'),0);
+// Set default values
+$defaults['admin']['platform_admin'] = 0;
+$defaults['mail']['send_mail'] = 1;
+$defaults['password']['password_auto'] = 1;
+$defaults['active'] = 1;
+$defaults['expiration_date']=array();
+$days = api_get_setting('account_valid_duration');
+$time = strtotime('+'.$days.' day');
+$defaults['expiration_date']['d']=date('d',$time);
+$defaults['expiration_date']['F']=date('m',$time);
+$defaults['expiration_date']['Y']=date('Y',$time);
+$defaults['radio_expiration_date'] = 0;
+$form->setDefaults($defaults);
+// Submit button
+$form->addElement('submit', 'submit', get_lang('Add'));
+$form->addElement('submit', 'submit_plus', get_lang('Add').'+');
+// Validate form
+if( $form->validate())
+{
+	$user = $form->exportValues();
+	$picture_element = & $form->getElement('picture');
+	$picture = $picture_element->getValue();
+	$picture_uri = '';
+	if (strlen($picture['name']) > 0)
+	{
+		$picture_uri = uniqid('').'_'.replace_dangerous_char($picture['name']);
+		$picture_location = api_get_path(SYS_CODE_PATH).'upload/users/'.$picture_uri;
+		move_uploaded_file($picture['tmp_name'], $picture_location);
+	}
+	$lastname = $user['lastname'];
+	$firstname = $user['firstname'];
+	$official_code = $user['official_code'];
+	$email = $user['email'];
+	$phone = $user['phone'];
+	$username = $user['username'];
+	$status = intval($user['status']);
+	$picture = $_FILES['picture'];
+	$platform_admin = intval($user['platform_admin']);
+	$send_mail = intval($user['mail']['send_mail']);
+	if(count($extAuthSource) > 0 && $user['password']['password_auto'] == '2')
+	{
+		$auth_source = $user['password']['auth_source'];
+		$password = 'PLACEHOLDER';
+	}
+	else
+	{
+		$auth_source = PLATFORM_AUTH_SOURCE;
+		$password = $user['password']['password_auto'] == '1' ? api_generate_password() : $user['password']['password'];
+	}
+	if ($user['radio_expiration_date']=='1' )
+	{
+		$expiration_date=$user['expiration_date'];
+	}
+	else
+	{
+		$expiration_date='0000-00-00 00:00:00';
+	}
+	$active = intval($user['active']);
+
+	$user_id = UserManager::create_user($firstname,$lastname,$status,$email,$username,$password,$official_code,api_get_setting('platformLanguage'),$phone,$picture_uri,$auth_source,$expiration_date,$active);
+	if ($platform_admin)
+	{
+		$sql = "INSERT INTO $table_admin SET user_id = '".$user_id."'";
+		api_sql_query($sql,__FILE__,__LINE__);
+	}
+	if (!empty ($email) && $send_mail)
+	{
+		$emailto = '"'.$firstname.' '.$lastname.'" <'.$email.'>';
+		$emailsubject = '['.get_setting('siteName').'] '.get_lang('YourReg').' '.get_setting('siteName');
+		$emailheaders = 'From: '.get_setting('administratorName').' '.get_setting('administratorSurname').' <'.get_setting('emailAdministrator').">\n";
+		$emailheaders .= 'Reply-To: '.get_setting('emailAdministrator');
+		$emailbody=get_lang('langDear')." ".stripslashes("$firstname $lastname").",\n\n".get_lang('langYouAreReg')." ". get_setting('siteName') ." ".get_lang('langSettings')." ". $username ."\n". get_lang('langPass')." : ".stripslashes($password)."\n\n" .get_lang('langAddress') ." ". get_setting('siteName') ." ". get_lang('langIs') ." : ". $rootWeb ."\n\n". get_lang('langProblem'). "\n\n". get_lang('langFormula').",\n\n".get_setting('administratorName')." ".get_setting('administratorSurname')."\n". get_lang('langManager'). " ".get_setting('siteName')."\nT. ".get_setting('administratorTelephone')."\n" .get_lang('langEmail') ." : ".get_setting('emailAdministrator');
+		@api_send_mail($emailto, $emailsubject, $emailbody, $emailheaders);
+	}
+	if(isset($user['submit_plus']))
+	{
+		//we want to add more. Prepare report message and redirect to the same page (to clean the form)
+		header('Location: user_add.php?message='.urlencode(get_lang('UserAdded')));
+		exit ();
+	}
+	else
+	{
+		header('Location: user_list.php?action=show_message&message='.urlencode(get_lang('UserAdded')));
+		exit ();
+	}
+}
+// Display form
+Display::display_header($tool_name);
+//api_display_tool_title($tool_name);
+if(!empty($message)){
+	Display::display_normal_message(stripslashes($message));
+}
+$form->display();
+/*
+==============================================================================
+		FOOTER
+==============================================================================
+*/
+Display::display_footer();
+?>

+ 314 - 0
main/admin/user_edit.php

@@ -0,0 +1,314 @@
+<?php // $Id: user_edit.php 9617 2006-10-20 12:39:54Z bmol $
+/*
+==============================================================================
+	Dokeos - elearning and course management software
+
+	Copyright (c) 2004 Dokeos S.A.
+	Copyright (c) 2003 Ghent University (UGent)
+	Copyright (c) 2001 Universite catholique de Louvain (UCL)
+	Copyright (c) Olivier Brouckaert
+	Copyright (c) Bart Mollet, Hogeschool Gent
+
+	For a full list of contributors, see "credits.txt".
+	The full license can be read in "license.txt".
+
+	This program is free software; you can redistribute it and/or
+	modify it under the terms of the GNU General Public License
+	as published by the Free Software Foundation; either version 2
+	of the License, or (at your option) any later version.
+
+	See the GNU General Public License for more details.
+
+	Contact: Dokeos, 181 rue Royale, B-1000 Brussels, Belgium, info@dokeos.com
+==============================================================================
+*/
+/**
+==============================================================================
+*	@package dokeos.admin
+==============================================================================
+*/
+
+$langFile=array('admin','registration');
+$cidReset=true;
+include('../inc/global.inc.php');
+$this_section=SECTION_PLATFORM_ADMIN;
+
+api_protect_admin_script();
+
+
+$htmlHeadXtra[] = '
+<script language="JavaScript" type="text/JavaScript">
+<!--
+function enable_expiration_date() { //v2.0
+	document.user_add.radio_expiration_date[0].checked=false;
+	document.user_add.radio_expiration_date[1].checked=true;
+}
+//-->
+</script>';
+
+
+include(api_get_path(LIBRARY_PATH).'fileManage.lib.php');
+include(api_get_path(LIBRARY_PATH).'fileUpload.lib.php');
+include(api_get_path(LIBRARY_PATH).'usermanager.lib.php');
+require_once (api_get_path(LIBRARY_PATH).'formvalidator/FormValidator.class.php');
+$user_id=isset($_GET['user_id']) ? intval($_GET['user_id']) : intval($_POST['user_id']);
+$noPHP_SELF=true;
+$tool_name=get_lang('ModifyUserInfo');
+
+//$interbreadcrumb[]=array("url" => "index.php","name" => get_lang('PlatformAdmin'));
+$interbreadcrumb[]=array("url" => "user_list.php","name" => get_lang('UserList'));
+
+$table_user = Database::get_main_table(MAIN_USER_TABLE);
+$table_admin = Database::get_main_table(MAIN_ADMIN_TABLE);
+$sql = "SELECT u.*, a.user_id AS is_admin FROM $table_user u LEFT JOIN $table_admin a ON a.user_id = u.user_id WHERE u.user_id = '".$user_id."'";
+$res = api_sql_query($sql,__FILE__,__LINE__);
+if(mysql_num_rows($res) != 1)
+{
+	header('Location: user_list.php');
+	exit;
+}
+$user_data = mysql_fetch_array($res,MYSQL_ASSOC);
+$user_data['platform_admin'] = is_null($user_data['is_admin']) ? 0 : 1;
+$user_data['send_mail'] = 0;
+$user_data['old_password'] = $user_data['password'];
+unset($user_data['password']);
+
+// Create the form
+$form = new FormValidator('user_add','post','','',array('style' => 'width: 60%; float: '.($text_dir=='rtl'?'right;':'left;')));
+$form->addElement('hidden','user_id',$user_id);
+
+// Lastname
+$form->addElement('text','lastname',get_lang('LastName'));
+$form->applyFilter('lastname','html_filter');
+$form->applyFilter('lastname','trim');
+$form->addRule('lastname', get_lang('ThisFieldIsRequired'), 'required');
+
+// Firstname
+$form->addElement('text','firstname',get_lang('FirstName'));
+$form->applyFilter('firstname','html_filter');
+$form->applyFilter('firstname','trim');
+$form->addRule('firstname', get_lang('ThisFieldIsRequired'), 'required');
+
+// Official code
+$form->addElement('text', 'official_code', get_lang('OfficialCode'),array('size' => '40'));
+$form->applyFilter('official_code','html_filter');
+$form->applyFilter('official_code','trim');
+
+// Email
+$form->addElement('text', 'email', get_lang('Email'),array('size' => '40'));
+$form->addRule('email', get_lang('EmailWrong'), 'email');
+$form->addRule('email', get_lang('EmailWrong'), 'required');
+
+// Phone
+$form->addElement('text','phone',get_lang('PhoneNumber'));
+
+// Picture
+$form->addElement('file', 'picture', get_lang('AddPicture'));
+$allowed_picture_types = array ('jpg', 'jpeg', 'png', 'gif');
+$form->addRule('picture', get_lang('OnlyImagesAllowed').' ('.implode(',', $allowed_picture_types).')', 'filetype', $allowed_picture_types);
+if (strlen($user_data['picture_uri']) > 0 )
+{
+	$form->addElement('checkbox', 'delete_picture', '', get_lang('DelImage'));
+}
+
+// Username
+$form->addElement('text', 'username', get_lang('LoginName'),array('maxlength'=>20));
+$form->addRule('username', get_lang('ThisFieldIsRequired'), 'required');
+$form->addRule('username', get_lang('OnlyLettersAndNumbersAllowed'), 'username');
+$form->addRule('username', '', 'maxlength',20);
+$form->addRule('username', get_lang('UserTaken'), 'username_available', $user_data['username']);
+
+// Password
+$form->addElement('radio','reset_password',get_lang('Password'),get_lang('DontResetPassword'),0);
+if(count($extAuthSource) > 0)
+{
+	$group[] =& HTML_QuickForm::createElement('radio','reset_password',null,get_lang('ExternalAuthentication').' ',3);
+	$auth_sources = array();
+	foreach($extAuthSource as $key => $info)
+	{
+		$auth_sources[$key] = $key;
+	}
+	$group[] =& HTML_QuickForm::createElement('select','auth_source',null,$auth_sources);
+	$group[] =& HTML_QuickForm::createElement('static','','','<br />');
+	$form->addGroup($group, 'password', null, '',false);
+}
+$form->addElement('radio','reset_password',null,get_lang('AutoGeneratePassword'),1);
+$group = array();
+$group[] =& HTML_QuickForm::createElement('radio', 'reset_password',null,null,2);
+$group[] =& HTML_QuickForm::createElement('password', 'password',null,null);
+$form->addGroup($group, 'password', null, '',false);
+
+// Status
+$status = array();
+$status[COURSEMANAGER]  = get_lang('CourseAdmin');
+$status[STUDENT] = get_lang('Student');
+$form->addElement('select','status',get_lang('Status'),$status);
+
+// Platform admin
+// Only when changing another user!
+if($user_id != $_SESSION['_uid'])
+{
+	$group = array();
+	$group[] =& HTML_QuickForm::createElement('radio', 'platform_admin',null,get_lang('Yes'),1);
+	$group[] =& HTML_QuickForm::createElement('radio', 'platform_admin',null,get_lang('No'),0);
+	$form->addGroup($group, 'admin', get_lang('PlatformAdmin'), '&nbsp;',false);
+}
+
+// Send email
+$group = array();
+$group[] =& HTML_QuickForm::createElement('radio', 'send_mail',null,get_lang('Yes'),1);
+$group[] =& HTML_QuickForm::createElement('radio', 'send_mail',null,get_lang('No'),0);
+$form->addGroup($group, 'mail', get_lang('SendMailToNewUser'), '&nbsp;',false);
+
+// Registration Date
+$form->addElement('static','registration_date', get_lang('RegistrationDate'), $user_data['registration_date']);
+
+if(! $user_data['platform_admin'] )
+{
+	// Expiration Date
+	$form->addElement('radio', 'radio_expiration_date', get_lang('ExpirationDate'), get_lang('NeverExpires'), 0);
+	$group = array ();
+	$group[] = & $form->createElement('radio', 'radio_expiration_date', null, get_lang('On'), 1);
+	$group[] = & $form->createElement('datepicker', 'expiration_date',null, array ('form_name' => $form->getAttribute('name'), 'onChange'=>'enable_expiration_date()'));
+	$form->addGroup($group, 'max_member_group', null, '', false);
+
+	// Active account or inactive account
+	$form->addElement('radio','active',get_lang('ActiveAccount'),get_lang('Active'),1);
+	$form->addElement('radio','active','',get_lang('Inactive'),0);
+}
+// Submit button
+$form->addElement('submit', 'submit', 'OK');
+
+// Set default values
+$expiration_date=$user_data['expiration_date'];
+if ($expiration_date=='0000-00-00 00:00:00')
+{
+	$user_data['radio_expiration_date']=0;
+	$user_data['expiration_date']=array();
+	$user_data['expiration_date']['d']=date('d');
+	$user_data['expiration_date']['F']=date('m');
+	$user_data['expiration_date']['Y']=date('Y');
+}
+else
+{
+	$user_data['radio_expiration_date']=1;
+	$user_data['expiration_date']=array();
+	$user_data['expiration_date']['d']=substr($expiration_date,8,2);
+	$user_data['expiration_date']['F']=substr($expiration_date,5,2);
+	$user_data['expiration_date']['Y']=substr($expiration_date,0,4);
+}
+$form->setDefaults($user_data);
+
+
+// Validate form
+if( $form->validate())
+{
+	$user = $form->exportValues();
+	$picture_element = & $form->getElement('picture');
+	$picture = $picture_element->getValue();
+	$picture_uri = '';
+	if (strlen($picture['name']) > 0)
+	{
+		$picture_uri = uniqid('').'_'.replace_dangerous_char($picture['name']);
+		$picture_location = api_get_path(SYS_CODE_PATH).'upload/users/'.$picture_uri;
+		move_uploaded_file($picture['tmp_name'], $picture_location);
+	}
+	elseif(isset($user['delete_picture']))
+	{
+		@unlink('../upload/users/'.$user_data['picture_uri']);
+	}
+	$lastname = $user['lastname'];
+	$firstname = $user['firstname'];
+	$official_code = $user['official_code'];
+	$email = $user['email'];
+	$phone = $user['phone'];
+	$username = $user['username'];
+	$status = intval($user['status']);
+	$picture = $_FILES['picture'];
+	$platform_admin = intval($user['platform_admin']);
+	$send_mail = intval($user['send_mail']);
+	$reset_password = intval($user['reset_password']);
+	if ($user['radio_expiration_date']=='1' && ! $user_data['platform_admin'] )
+	{
+		$expiration_date=$user['expiration_date'];
+	}
+	else
+	{
+		$expiration_date='0000-00-00 00:00:00';
+	}
+	$active = $user_data['platform_admin'] ? 1 : intval($user['active']);
+
+	if( $reset_password == 0)
+	{
+		$password = null;
+		$auth_source = $user_data['auth_source'];
+	}
+	elseif($reset_password == 1)
+	{
+		$password = api_generate_password();
+		$auth_source = PLATFORM_AUTH_SOURCE;
+	}
+	else
+	{
+		$password = $user['password'];
+		$auth_source = PLATFORM_AUTH_SOURCE;
+	}
+	UserManager::update_user($user_id,$firstname,$lastname,$username,$password,$auth_source,$email,$status,$official_code,$phone,$picture_uri,$expiration_date, $active);
+	if($user_id != $_SESSION['_uid'])
+	{
+		if($platform_admin == 1)
+		{
+			$sql = "INSERT IGNORE INTO $table_admin SET user_id = '".$user_id."'";
+			api_sql_query($sql,__FILE__,__LINE__);
+		}
+		else
+		{
+			$sql = "DELETE FROM $table_admin WHERE user_id = '".$user_id."'";
+			api_sql_query($sql,__FILE__,__LINE__);
+		}
+	}
+	if (!empty ($email) && $send_mail)
+	{
+		$emailto = '"'.$firstname.' '.$lastname.'" <'.$email.'>';
+		$emailsubject = '['.get_setting('siteName').'] '.get_lang('YourReg').' '.get_setting('siteName');
+		$emailheaders = 'From: '.get_setting('administratorName').' '.get_setting('administratorSurname').' <'.get_setting('emailAdministrator').">\n";
+		$emailheaders .= 'Reply-To: '.get_setting('emailAdministrator');
+		$emailbody = get_lang('langDear')." ".stripslashes("$form_firstname $lastname").",\n\n".get_lang('langYouAreReg')." ". get_setting('siteName') ." ".get_lang('langSettings')." ". $username;
+		if($reset_password != 0 || !$userPasswordCrypted )
+		{
+			$emaibody .= "\n".get_lang('langPass')." : ".stripslashes($password);
+		}
+		$emailbody .= "\n\n" .get_lang('langAddress') ." ". get_setting('siteName') ." ". get_lang('langIs') ." : ". $rootWeb ."\n\n". get_lang('langProblem'). "\n\n". get_lang('langFormula').",\n\n".get_setting('administratorName')." ".get_setting('administratorSurname')."\n". get_lang('langManager'). " ".get_setting('siteName')."\nT. ".get_setting('administratorTelephone')."\n" .get_lang('langEmail') ." : ".get_setting('emailAdministrator');
+		@api_send_mail($emailto, $emailsubject, $emailbody, $emailheaders);
+	}
+	header('Location: user_list.php?action=show_message&message='.urlencode(get_lang('UserUpdated')));
+	exit();
+}
+
+Display::display_header($tool_name);
+//api_display_tool_title($tool_name);
+// Show the users picture
+if (strlen($user_data['picture_uri']) > 0)
+{
+	$picture_url = api_get_path(WEB_CODE_PATH).'upload/users/'.$user_data['picture_uri'];
+}
+else
+{
+	$picture_url = api_get_path(WEB_CODE_PATH)."img/unknown.jpg";
+}
+$image_size = @getimagesize($picture_url);
+$img_attributes = 'src="'.$picture_url.'?rand='.time().'" '
+	.'alt="'.$user_data['lastname'].' '.$user_data['firstname'].'" '
+	.'style="float:'.($text_dir == 'rtl' ? 'left' : 'right').'; padding:5px;" ';
+if ($image_size[0] > 200) //limit display width to 300px
+	$img_attributes .= 'width="200" ';
+echo '<img '.$img_attributes.'/>';
+// Display form
+$form->display();
+/*
+==============================================================================
+		FOOTER
+==============================================================================
+*/
+Display::display_footer();
+?>

+ 118 - 0
main/admin/user_export.php

@@ -0,0 +1,118 @@
+<?php
+// $Id: user_export.php 9246 2006-09-25 13:24:53Z bmol $
+/*
+==============================================================================
+	Dokeos - elearning and course management software
+
+	Copyright (c) 2004 Dokeos S.A.
+	Copyright (c) 2003 Ghent University (UGent)
+	Copyright (c) 2001 Universite catholique de Louvain (UCL)
+	Copyright (c) Olivier Brouckaert
+	Copyright (c) Bart Mollet, Hogeschool Gent
+
+	For a full list of contributors, see "credits.txt".
+	The full license can be read in "license.txt".
+
+	This program is free software; you can redistribute it and/or
+	modify it under the terms of the GNU General Public License
+	as published by the Free Software Foundation; either version 2
+	of the License, or (at your option) any later version.
+
+	See the GNU General Public License for more details.
+
+	Contact: Dokeos, 181 rue Royale, B-1000 Brussels, Belgium, info@dokeos.com
+==============================================================================
+*/
+/**
+==============================================================================
+*	@package dokeos.admin
+==============================================================================
+*/
+
+$langFile = 'admin';
+
+$cidReset = true;
+
+include ('../inc/global.inc.php');
+$this_section = SECTION_PLATFORM_ADMIN;
+
+api_protect_admin_script();
+include (api_get_path(LIBRARY_PATH).'fileManage.lib.php');
+include (api_get_path(LIBRARY_PATH).'export.lib.inc.php');
+include (api_get_path(LIBRARY_PATH).'formvalidator/FormValidator.class.php');
+
+$course_table = Database :: get_main_table(MAIN_COURSE_TABLE);
+$user_table = Database :: get_main_table(MAIN_USER_TABLE);
+$course_user_table = Database :: get_main_table(MAIN_COURSE_USER_TABLE);
+
+$tool_name = get_lang('ExportUserListXMLCSV');
+
+//$interbreadcrumb[] = array ("url" => "index.php", "name" => get_lang('PlatformAdmin'));
+
+set_time_limit(0);
+
+$courses = array ();
+$courses[''] = '--';
+$sql = "SELECT code,visual_code,title FROM $course_table ORDER BY visual_code";
+$result = api_sql_query($sql, __FILE__, __LINE__);
+while ($course = mysql_fetch_object($result))
+{
+	$courses[$course->code] = $course->visual_code.' - '.$course->title;
+}
+$form = new FormValidator('export_users');
+$form->addElement('radio', 'file_type', get_lang('OutputFileType'), 'XML','xml');
+$form->addElement('radio', 'file_type', null, 'CSV','csv');
+$form->addElement('select', 'course_code', get_lang('OnlyUsersFromCourse'), $courses);
+$form->addElement('submit', 'submit', get_lang('Ok'));
+$form->setDefaults(array('file_type'=>'csv'));
+if ($form->validate())
+{
+	$export = $form->exportValues();
+	$file_type = $export['file_type'];
+	$course_code = $export['course_code'];
+	$sql = "SELECT  u.user_id 	AS UserId,
+					u.lastname 	AS LastName,
+					u.firstname 	AS FirstName,
+					u.email 		AS Email,
+					u.username	AS UserName,
+					u.password	AS Password,
+					u.auth_source	AS AuthSource,
+					u.status		AS Statut,
+					u.official_code	AS OfficialCode,
+					u.phone		AS Phone";
+	if (strlen($course_code) > 0)
+	{
+		$sql .= " FROM $user_table u, $course_user_table cu WHERE u.user_id = cu.user_id ORDER BY lastname,firstname";
+		$filename = 'export_users_'.$course_code.'_'.date('Y-m-d_H-i-s');
+	}
+	else
+	{
+		$sql .= " FROM $user_table u ORDER BY lastname,firstname";
+		$filename = 'export_users_'.date('Y-m-d_H-i-s');
+	}
+	$res = api_sql_query($sql,__FILE__,__LINE__);
+	$data = array();
+	while($user = mysql_fetch_array($res,MYSQL_ASSOC))
+	{
+		$data[] = $user	;
+	}
+	switch($file_type)
+	{
+		case 'xml':
+			Export::export_table_xml($data,$filename,'Contact','Contacts');
+			break;
+		case 'csv':
+			Export::export_table_csv($data,$filename);
+			break;
+	}
+}
+Display :: display_header($tool_name);
+//api_display_tool_title($tool_name);
+$form->display();
+/*
+==============================================================================
+		FOOTER 
+==============================================================================
+*/
+Display :: display_footer();
+?>

+ 393 - 0
main/admin/user_import.php

@@ -0,0 +1,393 @@
+<?php
+
+// $Id: user_import.php 9246 2006-09-25 13:24:53Z bmol $
+/*
+==============================================================================
+	Dokeos - elearning and course management software
+
+	Copyright (c) 2004 Dokeos S.A.
+	Copyright (c) 2003 Ghent University (UGent)
+	Copyright (c) 2001 Universite catholique de Louvain (UCL)
+	Copyright (c) Olivier Brouckaert
+	Copyright (c) 2005 Bart Mollet <bart.mollet@hogent.be>
+
+	For a full list of contributors, see "credits.txt".
+	The full license can be read in "license.txt".
+
+	This program is free software; you can redistribute it and/or
+	modify it under the terms of the GNU General Public License
+	as published by the Free Software Foundation; either version 2
+	of the License, or (at your option) any later version.
+
+	See the GNU General Public License for more details.
+
+	Contact: Dokeos, 181 rue Royale, B-1000 Brussels, Belgium, info@dokeos.com
+==============================================================================
+*/
+/**
+==============================================================================
+*   This tool allows platform admins to add users by uploading a CSV or XML file
+* @todo Add some langvars to DLTT
+*	@package dokeos.admin
+==============================================================================
+*/
+/**
+ * validate the imported data
+ */
+function validate_data($users)
+{
+	global $defined_auth_sources;
+	$errors = array ();
+	$usernames = array ();
+	foreach ($users as $index => $user)
+	{
+		//1. check if mandatory fields are set	
+		$mandatory_fields = array ('LastName', 'FirstName');
+		if (api_get_setting('registration', 'email') == 'true')
+		{
+			$mandatory_fields[] = 'Email';	
+		}
+		foreach ($mandatory_fields as $key => $field)
+		{
+			if (!isset ($user[$field]) || strlen($user[$field]) == 0)
+			{
+				$user['error'] = get_lang($field.'Mandatory');
+				$errors[] = $user;
+			}
+		}
+		//2. check username
+		if (isset ($user['UserName']) && strlen($user['UserName']) != 0)
+		{
+			//2.1. check if no username was used twice in import file
+			if (isset ($usernames[$user['UserName']]))
+			{
+				$user['error'] = get_lang('UserNameUsedTwice');
+				$errors[] = $user;
+			}
+			$usernames[$user['UserName']] = 1;
+			//2.2. check if username isn't allready in use in database
+			if (!UserManager :: is_username_available($user['UserName']))
+			{
+				$user['error'] = get_lang('UserNameNotAvailable');
+				$errors[] = $user;
+			}
+			//2.3. check if username isn't longer than the 20 allowed characters
+			if (strlen($user['UserName']) > 20)
+			{
+				$user['error'] = get_lang('UserNameTooLong');
+				$errors[] = $user;
+			}
+		}
+		//3. check status
+		if (isset ($user['Status']) && ($user['Status'] != COURSEMANAGER && $user['Status'] != STUDENT))
+		{
+			$user['error'] = get_lang('WrongStatus');
+			$errors[] = $user;
+		}
+		//4. Check classname
+		if (isset ($user['ClassName']) && strlen($user['ClassName']) != 0)
+		{
+			if (!ClassManager :: class_name_exists($user['ClassName']))
+			{
+				$user['error'] = get_lang('ClassNameNotAvailable');
+				$errors[] = $user;
+			}
+		}
+		//5. Check authentication source
+		if (isset ($user['AuthSource']) && strlen($user['AuthSource']) != 0)
+		{
+			if (!in_array($user['AuthSource'], $defined_auth_sources))
+			{
+				$user['error'] = get_lang('AuthSourceNotAvailable');
+				$errors[] = $user;
+			}
+		}
+	}
+	return $errors;
+}
+/**
+ * Add missing user-information (which isn't required, like password, username
+ * etc)
+ */
+function complete_missing_data($users)
+{
+	foreach ($users as $index => $user)
+	{
+		//1. Create a username if necessary
+		if (!isset ($user['UserName']) || strlen($user['UserName']) == 0)
+		{
+			$username = strtolower(ereg_replace('[^a-zA-Z]', '', substr($user['FirstName'], 0, 3).' '.substr($user['LastName'], 0, 4)));
+			if (!UserManager :: is_username_available($username))
+			{
+				$i = 0;
+				$temp_username = $username.$i;
+				while (!UserManager :: is_username_available($temp_username))
+				{
+					$temp_username = $username.++$i;
+				}
+				$username = $temp_username;
+			}
+			$users[$index]['UserName'] = $username;
+		}
+		//2. generate a password if necessary
+		if (!isset ($user['Password']) || strlen($user['Password']) == 0)
+		{
+			$users[$index]['Password'] = api_generate_password();
+		}
+		//3. set status if not allready set
+		if (!isset ($user['Status']) || strlen($user['Status']) == 0)
+		{
+			$users[$index]['Status'] = 'user';
+		}
+		//4. set authsource if not allready set
+		if (!isset ($user['AuthSource']) || strlen($user['AuthSource']) == 0)
+		{
+			$users[$index]['AuthSource'] = PLATFORM_AUTH_SOURCE;
+		}
+	}
+	return $users;
+}
+/**
+ * Save the imported data
+ */
+function save_data($users)
+{
+	$user_table = Database :: get_main_table(MAIN_USER_TABLE);
+	$sendMail = $_POST['sendMail'] ? 1 : 0;
+	foreach ($users as $index => $user)
+	{
+		$user_id = UserManager :: create_user($user['FirstName'], $user['LastName'], $user['Status'], $user['Email'], $user['UserName'], $user['Password'], $user['OfficialCode'], $user['PhoneNumber'], '', $user['AuthSource']);
+		foreach ($user['Courses'] as $index => $course)
+		{
+			CourseManager :: subscribe_user($user_id, $course);
+		}
+		if (strlen($user['ClassName']) > 0)
+		{
+			$class_id = ClassManager :: get_class_id($user['ClassName']);
+			ClassManager :: add_user($user_id, $class_id);
+		}
+		if ($sendMail)
+		{
+			$emailto = '"'.$user['FirstName'].' '.$user['LastName'].'" <'.$user['Email'].'>';
+			$emailsubject = '['.get_setting('siteName').'] '.get_lang('YourReg').' '.get_setting('siteName');
+			$emailbody = get_lang('Dear').$user['FirstName'].' '.$user['LastName'].",\n\n".get_lang('YouAreReg')." ".get_setting('siteName')." ".get_lang('Settings')." $user[UserName]\n".get_lang('Pass')." : $user[Password]\n\n".get_lang('Address')." ".get_setting('siteName')." ".get_lang('Is')." : ".api_get_path('WEB_PATH')." \n\n".get_lang('Problem')."\n\n".get_lang('Formula').",\n\n".get_setting('administratorName')." ".get_setting('administratorSurname')."\n".get_lang('Manager')." ".get_setting('siteName')."\nT. ".get_setting('administratorTelephone')."\n".get_lang('Email')." : ".get_setting('emailAdministrator')."";
+			$emailheaders = 'From: '.get_setting('administratorName').' '.get_setting('administratorSurname').' <'.get_setting('emailAdministrator').">\n";
+			$emailheaders .= 'Reply-To: '.get_setting('emailAdministrator');
+			@ api_send_mail($emailto, $emailsubject, $emailbody, $emailheaders);
+		}
+
+	}
+}
+/**
+ * Read the CSV-file 
+ * @param string $file Path to the CSV-file
+ * @return array All userinformation read from the file
+ */
+function parse_csv_data($file)
+{
+	$users = Import :: csv_to_array($file);
+	foreach ($users as $index => $user)
+	{
+		if (isset ($user['Courses']))
+		{
+			$user['Courses'] = explode('|', trim($user['Courses']));
+		}
+		if ($user['Status'] == 'user')
+		{
+			$user['Status'] = STUDENT;
+		}
+		if ($user['Status'] == 'teacher')
+		{
+			$user['Status'] = COURSEMANAGER;
+		}
+		$users[$index] = $user;
+	}
+	return $users;
+}
+/**
+ * XML-parser: handle start of element
+ */
+function element_start($parser, $data)
+{
+	global $user;
+	global $current_tag;
+	switch ($data)
+	{
+		case 'Contact' :
+			$user = array ();
+			break;
+		default :
+			$current_tag = $data;
+	}
+}
+/**
+ * XML-parser: handle end of element
+ */
+function element_end($parser, $data)
+{
+	global $user;
+	global $users;
+	global $current_value;
+	switch ($data)
+	{
+		case 'Contact' :
+			if ($user['Status'] == '5')
+			{
+				$user['Status'] = STUDENT;
+			}
+			if ($user['Status'] == '1')
+			{
+				$user['Status'] = COURSEMANAGER;
+			}
+			$users[] = $user;
+			break;
+		default :
+			$user[$data] = $current_value;
+			break;
+	}
+}
+/**
+ * XML-parser: handle character data
+ */
+function character_data($parser, $data)
+{
+	global $current_value;
+	$current_value = $data;
+}
+/**
+ * Read the XML-file
+ * @param string $file Path to the XML-file
+ * @return array All userinformation read from the file
+ */
+function parse_xml_data($file)
+{
+	global $current_tag;
+	global $current_value;
+	global $user;
+	global $users;
+	$users = array ();
+	$parser = xml_parser_create();
+	xml_set_element_handler($parser, 'element_start', 'element_end');
+	xml_set_character_data_handler($parser, "character_data");
+	xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, false);
+	xml_parse($parser, file_get_contents($file));
+	xml_parser_free($parser);
+	return $users;
+}
+
+$langFile = array ('admin', 'registration');
+
+$cidReset = true;
+include ('../inc/global.inc.php');
+$this_section = SECTION_PLATFORM_ADMIN;
+api_protect_admin_script();
+require_once (api_get_path(LIBRARY_PATH).'fileManage.lib.php');
+require_once (api_get_path(LIBRARY_PATH).'usermanager.lib.php');
+require_once (api_get_path(LIBRARY_PATH).'classmanager.lib.php');
+require_once (api_get_path(LIBRARY_PATH).'import.lib.php');
+require_once (api_get_path(LIBRARY_PATH).'formvalidator/FormValidator.class.php');
+$formSent = 0;
+$errorMsg = '';
+$defined_auth_sources[] = PLATFORM_AUTH_SOURCE;
+if (is_array($extAuthSource))
+{
+	$defined_auth_sources = array_merge($defined_auth_sources, array_keys($extAuthSource));
+}
+
+$tool_name = get_lang('ImportUserListXMLCSV');
+
+//$interbreadcrumb[] = array ("url" => "index.php", "name" => get_lang('PlatformAdmin'));
+
+set_time_limit(0);
+
+if ($_POST['formSent'])
+{
+	$file_type = $_POST['file_type'];
+	if ($file_type == 'csv')
+	{
+		$users = parse_csv_data($_FILES['import_file']['tmp_name']);
+	}
+	else
+	{
+		$users = parse_xml_data($_FILES['import_file']['tmp_name']);
+	}
+	$errors = validate_data($users);
+	if (count($errors) == 0)
+	{
+		$users = complete_missing_data($users);
+		save_data($users);
+		header('Location: user_list.php?action=show_message&message='.urlencode(get_lang('FileImported')));
+		exit ();
+	}
+}
+Display :: display_header($tool_name);
+//api_display_tool_title($tool_name);
+if (count($errors) != 0)
+{
+	$error_message = '<ul>';
+	foreach ($errors as $index => $error_user)
+	{
+		$error_message .= '<li><b>'.$error_user['error'].'</b>: ';
+		$error_message .= $error_user['FirstName'].' '.$error_user['LastName'];
+		$error_message .= '</li>';
+	}
+	$error_message .= '</ul>';
+	Display :: display_error_message($error_message);
+}
+$form = new FormValidator('user_import');
+$form->addElement('hidden', 'formSent');
+$form->addElement('file', 'import_file', get_lang('ImportFileLocation'));
+$allowed_file_types = array ('xml', 'csv');
+$form->addRule('file', get_lang('InvalidExtension').' ('.implode(',', $allowed_file_types).')', 'filetype', $allowed_file_types);
+$form->addElement('radio', 'file_type', get_lang('FileType'), 'XML (<a href="exemple.xml" target="_blank">'.get_lang('ExampleXMLFile').'</a>)', 'xml');
+$form->addElement('radio', 'file_type', null, 'CSV (<a href="exemple.csv" target="_blank">'.get_lang('ExampleCSVFile').'</a>)', 'csv');
+$form->addElement('radio', 'sendMail', get_lang('SendMailToUsers'), get_lang('Yes'), 1);
+$form->addElement('radio', 'sendMail', null, get_lang('No'), 0);
+$form->addElement('submit', 'submit', get_lang('Ok'));
+$defaults['formSent'] = 1;
+$defaults['file_type'] = 'xml';
+$form->setDefaults($defaults);
+$form->display();
+?>
+<p><?php echo get_lang('CSVMustLookLike').' ('.get_lang('MandatoryFields').')'; ?> :</p>
+
+<blockquote>
+<pre>
+<b>LastName</b>;<b>FirstName</b>;UserName;Password;AuthSource;<b>Email</b>;OfficialCode;PhoneNumber;Status;Courses;ClassName
+<b>xxx</b>;<b>xxx</b>;xxx;xxx;<?php echo implode('/',$defined_auth_sources); ?>;<b>xxx</b>;xxx;xxx;user/teacher;xxx1|xxx2|xxx3;xxx
+</pre>
+</blockquote>
+
+<p><?php echo get_lang('XMLMustLookLike').' ('.get_lang('MandatoryFields').')'; ?> :</p>
+
+<blockquote>
+<pre>
+&lt;?xml version=&quot;1.0&quot; encoding=&quot;ISO-8859-1&quot;?&gt;
+&lt;Contacts&gt;
+    &lt;Contact&gt;
+        <b>&lt;LastName&gt;xxx&lt;/LastName&gt;</b>
+        <b>&lt;FirstName&gt;xxx&lt;/FirstName&gt;</b>
+        &lt;UserName&gt;xxx&lt;/UserName&gt;
+        &lt;Password&gt;xxx&lt;/Password&gt;
+        &lt;AuthSource&gt;<?php echo implode('/',$defined_auth_sources); ?>&lt;/AuthSource&gt;
+        <b>&lt;Email&gt;xxx&lt;/Email&gt;</b>
+        &lt;OfficialCode&gt;xxx&lt;/OfficialCode&gt;
+        &lt;PhoneNumber&gt;xxx&lt;/PhoneNumber&gt;
+        &lt;Status&gt;user/teacher&lt;/Status&gt;
+        &lt;Courses&gt;xxx1|xxx2|xxx3&lt;/Courses&gt;
+        &lt;ClassName&gt;class 1&lt;/ClassName&gt;
+    &lt;/Contact&gt;
+&lt;/Contacts&gt;
+</pre>
+</blockquote>
+
+<?php
+
+
+/*
+==============================================================================
+		FOOTER 
+==============================================================================
+*/
+Display :: display_footer();
+?>

+ 152 - 0
main/admin/user_information.php

@@ -0,0 +1,152 @@
+<?php
+// $Id: user_information.php 9246 2006-09-25 13:24:53Z bmol $
+/*
+==============================================================================
+	Dokeos - elearning and course management software
+
+	Copyright (c) 2004 Dokeos S.A.
+	Copyright (c) 2003 Ghent University (UGent)
+	Copyright (c) 2001 Universite catholique de Louvain (UCL)
+	Copyright (c) Olivier Brouckaert
+
+	For a full list of contributors, see "credits.txt".
+	The full license can be read in "license.txt".
+
+	This program is free software; you can redistribute it and/or
+	modify it under the terms of the GNU General Public License
+	as published by the Free Software Foundation; either version 2
+	of the License, or (at your option) any later version.
+
+	See the GNU General Public License for more details.
+
+	Contact: Dokeos, 181 rue Royale, B-1000 Brussels, Belgium, info@dokeos.com
+==============================================================================
+*/
+/**
+============================================================================== 
+	@author Bart Mollet
+*	@package dokeos.admin
+============================================================================== 
+*/
+/*
+==============================================================================
+		INIT SECTION
+==============================================================================
+*/
+$langFile = 'admin';
+$cidReset = true;
+require ('../inc/global.inc.php');
+$this_section=SECTION_PLATFORM_ADMIN;
+
+api_protect_admin_script();
+require_once(api_get_path(LIBRARY_PATH).'course.lib.php');
+//$interbreadcrumb[] = array ("url" => "index.php", "name" => get_lang('PlatformAdmin'));
+$interbreadcrumb[] = array ("url" => 'user_list.php', "name" => get_lang('UserList'));
+if( ! isset($_GET['user_id']))
+{
+	api_not_allowed();	
+}
+$user = api_get_user_info($_GET['user_id']);
+$tool_name = $user['firstName'].' '.$user['lastName'].(empty($user['official_code'])?'':' ('.$user['official_code'].')');
+Display::display_header($tool_name);
+$table_course_user = Database :: get_main_table(MAIN_COURSE_USER_TABLE);
+$table_course = Database :: get_main_table(MAIN_COURSE_TABLE);
+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']);
+				Display::display_normal_message('UserUnsubscribed');
+			}
+			else
+			{
+				Display::display_error_message('CannotUnsubscribeUserFromCourse');	
+			}
+			break;	
+	}	
+}
+api_display_tool_title($tool_name);
+if ($user['picture_uri'] != '')
+{
+	echo '<p><img src="'.api_get_path(WEB_CODE_PATH).'upload/users/'.$user['picture_uri'].'" style="width:150px;"/></p>';
+}
+echo '<p>'. ($user['status'] == 1 ? get_lang('Teacher') : get_lang('Student')).'</p>';
+echo '<p>'.Display :: encrypted_mailto_link($user['mail'], $user['mail']).'</p>';
+/**
+ * Show the courses in which this user is subscribed
+ */
+$sql = 'SELECT * FROM '.$table_course_user.' cu, '.$table_course.' c WHERE cu.user_id = '.$user['user_id'].' AND cu.course_code = c.code';
+$res = api_sql_query($sql,__FILE__,__LINE__);
+if (mysql_num_rows($res) > 0)
+{
+	$header[] = array (get_lang('Code'), true);
+	$header[] = array (get_lang('Title'), true);
+	$header[] = array (get_lang('Status'), true);
+	$header[] = array ('', false);
+	$data = array ();
+	while ($course = mysql_fetch_object($res))
+	{
+		$row = array ();
+		$row[] = $course->code;
+		$row[] = $course->title;
+		$row[] = $course->status == STUDENT ? get_lang('Student') : get_lang('Teacher');
+		$tools = '<a href="course_information.php?code='.$course->code.'"><img src="../img/info_small.gif" border="0" style="vertical-align: middle" /></a>'.
+				'<a href="'.api_get_path(WEB_COURSE_PATH).$course->directory.'"><img src="../img/home_small.gif" border="0" style="vertical-align: middle" /></a>' .
+				'<a href="course_edit.php?course_code='.$course->code.'"><img src="../img/edit.gif" border="0" style="vertical-align: middle" title="'.get_lang('Edit').'" alt="'.get_lang('Edit').'"/></a>';
+		if( $course->status == STUDENT )
+		{
+			$tools .= '<a href="user_information.php?action=unsubscribe&course_code='.$course->code.'&user_id='.$user['user_id'].'"><img src="../img/delete.gif"/></a>';
+				
+		}
+		$row[] = $tools;
+		$data[] = $row;
+	}
+	echo '<p><b>'.get_lang('Courses').'</b></p>';
+	echo '<blockquote>';
+	Display :: display_sortable_table($header, $data, array (), array (), array ('user_id' => $_GET['user_id']));
+	echo '</blockquote>';
+}
+else
+{
+	echo '<p>'.get_lang('NoCoursesForThisUser').'</p>';
+}
+/**
+ * Show the classes in which this user is subscribed
+ */
+$table_class_user = Database :: get_main_table(MAIN_CLASS_USER_TABLE);
+$table_class = Database :: get_main_table(MAIN_CLASS_TABLE);
+$sql = 'SELECT * FROM '.$table_class_user.' cu, '.$table_class.' c WHERE cu.user_id = '.$user['user_id'].' AND cu.class_id = c.id';
+$res = api_sql_query($sql,__FILE__,__LINE__);
+if (mysql_num_rows($res) > 0)
+{
+	$header = array();
+	$header[] = array (get_lang('ClassName'), true);
+	$header[] = array ('', false);
+	$data = array ();
+	while ($class = mysql_fetch_object($res))
+	{
+		$row = array();
+		$row[] = $class->name;
+		$row[] = '<a href="class_information.php?id='.$class->id.'"><img src="../img/info_small.gif" border="0" style="vertical-align: middle" /></a>';
+		$data[] = $row;
+	}
+	echo '<p><b>'.get_lang('Classes').'</b></p>';
+	echo '<blockquote>';
+	Display :: display_sortable_table($header, $data, array (), array (), array ('user_id' => $_GET['user_id']));
+	echo '</blockquote>';
+}
+else
+{
+	echo '<p>'.get_lang('NoClassesForThisUser').'</p>';
+}
+/*
+==============================================================================
+		FOOTER 
+==============================================================================
+*/ 
+Display::display_footer();
+?> 
+

+ 478 - 0
main/admin/user_list.php

@@ -0,0 +1,478 @@
+<?php
+
+// $Id: user_list.php 9555 2006-10-18 10:05:15Z elixir_inter $
+/*
+==============================================================================
+	Dokeos - elearning and course management software
+
+	Copyright (c) 2004 Dokeos S.A.
+	Copyright (c) 2003 Ghent University (UGent)
+	Copyright (c) 2001 Universite catholique de Louvain (UCL)
+	Copyright (c) Olivier Brouckaert
+
+	For a full list of contributors, see "credits.txt".
+	The full license can be read in "license.txt".
+
+	This program is free software; you can redistribute it and/or
+	modify it under the terms of the GNU General Public License
+	as published by the Free Software Foundation; either version 2
+	of the License, or (at your option) any later version.
+
+	See the GNU General Public License for more details.
+
+	Contact: Dokeos, 181 rue Royale, B-1000 Brussels, Belgium, info@dokeos.com
+==============================================================================
+*/
+/**
+==============================================================================
+	@author Bart Mollet
+*	@package dokeos.admin
+==============================================================================
+*/
+
+
+$langFile = 'admin';
+$cidReset = true;
+require ('../inc/global.inc.php');
+require_once (api_get_path(LIBRARY_PATH).'sortabletable.class.php');
+require_once (api_get_path(LIBRARY_PATH).'formvalidator/FormValidator.class.php');
+$this_section = SECTION_PLATFORM_ADMIN;
+
+api_protect_admin_script();
+/**
+*	Make sure this function is protected
+*	because it does NOT check password!
+*
+*	This function defines globals.
+*	@author Roan Embrechts
+*/
+function login_user($user_id)
+{
+	//init ---------------------------------------------------------------------
+	global $_uid, $uidReset, $loginFailed, $uidReset, $is_trackingEnabled, $_user;
+	global $is_platformAdmin, $is_allowedCreateCourse;
+
+	$main_user_table = Database :: get_main_table(MAIN_USER_TABLE);
+	$main_admin_table = Database :: get_main_table(MAIN_ADMIN_TABLE);
+	$track_e_login_table = Database :: get_statistic_table(STATISTIC_TRACK_E_LOGIN_TABLE);
+
+	//logic --------------------------------------------------------------------
+	//unset($_uid); // uid not in session ? prevent any hacking
+
+	if (!isset ($user_id))
+	{
+		$uidReset = true;
+		return;
+	}
+
+	$sql_query = "SELECT * FROM $main_user_table WHERE user_id='$user_id'";
+	$sql_result = api_sql_query($sql_query, __FILE__, __LINE__);
+	$result = Database :: fetch_array($sql_result);
+
+	$firstname = $result["firstname"];
+	$lastname = $result["lastname"];
+	$user_id = $result["user_id"];
+
+	$message = "Attempting to login as ".$firstname." ".$lastname." (id ".$user_id.")";
+
+	$_uid = $user_id;
+	//bug: this only works if $_uid is global
+	api_session_register('_uid');
+
+	$loginFailed = false;
+	$uidReset = false;
+
+	if ($user_id) // a uid is given (log in succeeded)
+	{
+		if ($is_trackingEnabled)
+		{
+			$sql_query = "SELECT user.*, a.user_id is_admin,
+				UNIX_TIMESTAMP(login.login_date) login_date
+				FROM $main_user_table
+				LEFT JOIN $main_admin_table a
+				ON user.user_id = a.user_id
+				LEFT JOIN $track_e_login_table login
+				ON user.user_id = login.login_user_id
+				WHERE user.user_id = '$_uid'
+				ORDER BY login.login_date DESC LIMIT 1";
+		}
+		else
+		{
+			$sql_query = "SELECT user.*, a.user_id is_admin
+				FROM $main_user_table
+				LEFT JOIN $main_admin_table a
+				ON user.user_id = a.user_id
+				WHERE user.user_id = '$_uid'";
+		}
+
+		$sql_result = api_sql_query($sql_query, __FILE__, __LINE__);
+
+		if (mysql_num_rows($sql_result) > 0)
+		{
+			// Extracting the user data
+
+			$user_data = mysql_fetch_array($sql_result);
+
+			$_user['firstName'] = $user_data['firstname'];
+			$_user['lastName'] = $user_data['lastname'];
+			$_user['mail'] = $user_data['email'];
+			$_user['lastLogin'] = $user_data['login_date'];
+			$_user['official_code'] = $user_data['official_code'];
+			$_user['picture_uri'] = $user_data['picture_uri'];
+
+			$is_platformAdmin = (bool) (!is_null($user_data['is_admin']));
+			$is_allowedCreateCourse = (bool) ($user_data['status'] == 1);
+			
+			LoginDelete($_SESSION["_user"]["user_id"], $statsDbName);
+			
+			//bug: this only works if $_user is global
+			api_session_register('_user');
+			api_session_register('is_platformAdmin');
+			api_session_register('is_allowedCreateCourse');
+
+			$target_url = api_get_path(WEB_PATH)."user_portal.php";
+			$message .= "<br/>Login successful. Go to <a href=\"$target_url\">$target_url</a>";
+			Display :: display_header(get_lang('UserList'));
+			Display :: display_normal_message($message);
+			Display :: display_footer();
+			exit;
+		}
+		else
+		{
+			exit ("<br/>WARNING UNDEFINED UID !! ");
+		}
+	}
+}
+/**
+ * Get the total number of users on the platform
+ * @see SortableTable#get_total_number_of_items()
+ */
+function get_number_of_users()
+{
+	$user_table = Database :: get_main_table(MAIN_USER_TABLE);
+	$sql = "SELECT COUNT(user_id) AS total_number_of_items FROM $user_table";
+	if (isset ($_GET['keyword']))
+	{
+		$keyword = mysql_real_escape_string($_GET['keyword']);
+		$sql .= " WHERE firstname LIKE '%".$keyword."%' OR lastname LIKE '%".$keyword."%'  OR email LIKE '%".$keyword."%'  OR official_code LIKE '%".$keyword."%'";
+	}
+	elseif (isset ($_GET['keyword_firstname']))
+	{
+		$keyword_firstname = mysql_real_escape_string($_GET['keyword_firstname']);
+		$keyword_lastname = mysql_real_escape_string($_GET['keyword_lastname']);
+		$keyword_email = mysql_real_escape_string($_GET['keyword_email']);
+		$keyword_username = mysql_real_escape_string($_GET['keyword_username']);
+		$keyword_status = mysql_real_escape_string($_GET['keyword_status']);
+		$keyword_active = isset($_GET['keyword_active']);
+		$keyword_inactive = isset($_GET['keyword_inactive']);
+		$sql .= " WHERE firstname LIKE '%".$keyword_firstname."%' AND lastname LIKE '%".$keyword_lastname."%' AND username LIKE '%".$keyword_username."%'  AND email LIKE '%".$keyword_email."%'   AND official_code LIKE '%".$keyword_officialcode."%'    AND status LIKE '".$keyword_status."'";
+		if($keyword_active && !$keyword_inactive)
+		{
+			$sql .= " AND active='1'";
+		}
+		elseif($keyword_inactive && !$keyword_active)
+		{
+			$sql .= " AND active='0'";
+		}
+	}
+	$res = api_sql_query($sql, __FILE__, __LINE__);
+	$obj = mysql_fetch_object($res);
+	return $obj->total_number_of_items;
+}
+/**
+ * Get the users to display on the current page.
+ * @see SortableTable#get_table_data($from)
+ */
+function get_user_data($from, $number_of_items, $column, $direction)
+{
+	$user_table = Database :: get_main_table(MAIN_USER_TABLE);
+	$sql = "SELECT
+                 user_id			AS col0,
+                 official_code		AS col1,
+                 lastname 			AS col2,
+                 firstname 			AS col3,
+                 username			AS col4,
+                 email				AS col5,
+                 IF(status=1,'".get_lang('Teacher')."','".get_lang('Student')."')	 AS col6,
+                 active				AS col7,
+                 user_id			AS col8
+
+             FROM
+                 $user_table ";
+	if (isset ($_GET['keyword']))
+	{
+		$keyword = mysql_real_escape_string($_GET['keyword']);
+		$sql .= " WHERE firstname LIKE '%".$keyword."%' OR lastname LIKE '%".$keyword."%'  OR username LIKE '%".$keyword."%'  OR official_code LIKE '%".$keyword."%'";
+	}
+	elseif (isset ($_GET['keyword_firstname']))
+	{
+		$keyword_firstname = mysql_real_escape_string($_GET['keyword_firstname']);
+		$keyword_lastname = mysql_real_escape_string($_GET['keyword_lastname']);
+		$keyword_email = mysql_real_escape_string($_GET['keyword_email']);
+		$keyword_username = mysql_real_escape_string($_GET['keyword_username']);
+		$keyword_status = mysql_real_escape_string($_GET['keyword_status']);
+		$keyword_active = isset($_GET['keyword_active']);
+		$keyword_inactive = isset($_GET['keyword_inactive']);
+		$sql .= " WHERE firstname LIKE '%".$keyword_firstname."%' AND lastname LIKE '%".$keyword_lastname."%' AND username LIKE '%".$keyword_username."%'  AND email LIKE '%".$keyword_email."%'   AND official_code LIKE '%".$keyword_officialcode."%'    AND status LIKE '".$keyword_status."'";
+		if($keyword_active && !$keyword_inactive)
+		{
+			$sql .= " AND active='1'";
+		}
+		elseif($keyword_inactive && !$keyword_active)
+		{
+			$sql .= " AND active='0'";
+		}
+	}
+	$sql .= " ORDER BY col$column $direction ";
+	$sql .= " LIMIT $from,$number_of_items";
+	$res = api_sql_query($sql, __FILE__, __LINE__);
+	$users = array ();
+	while ($user = mysql_fetch_row($res))
+	{
+		$users[] = $user;
+	}
+	return $users;
+}
+/**
+* Returns a mailto-link
+* @param string $email An email-address
+* @return string HTML-code with a mailto-link
+*/
+function email_filter($email)
+{
+	return Display :: encrypted_mailto_link($email, $email);
+}
+/**
+ * Build the modify-column of the table
+ * @param int $user_id The user id
+ * @param string $url_params
+ * @return string Some HTML-code with modify-buttons
+ */
+function modify_filter($user_id,$url_params)
+{
+	$result .= '<a href="user_information.php?user_id='.$user_id.'"><img src="../img/info_small.gif" border="0" style="vertical-align: middle;" title="'.get_lang('Info').'" alt="'.get_lang('Info').'"/></a>';
+	$result .= '<a href="user_list.php?action=login_as&amp;user_id='.$user_id.'"><img src="../img/loginas.gif" border="0" style="vertical-align: middle;" alt="'.get_lang('LoginAs').'" title="'.get_lang('LoginAs').'"/></a>';
+	$result .= '<a href="user_edit.php?user_id='.$user_id.'"><img src="../img/edit.gif" border="0" style="vertical-align: middle;" title="'.get_lang('Edit').'" alt="'.get_lang('Edit').'"/></a>';
+	$result .= '<a href="user_list.php?action=delete_user&amp;user_id='.$user_id.'&amp;'.$url_params.'"  onclick="javascript:if(!confirm('."'".addslashes(htmlentities(get_lang("ConfirmYourChoice")))."'".')) return false;"><img src="../img/delete.gif" border="0" style="vertical-align: middle;" title="'.get_lang('Delete').'" alt="'.get_lang('Delete').'"/></a>';
+	return $result;
+}
+
+
+/**
+ * Build the active-column of the table to lock or unlock a certain user
+ * lock = the user can no longer use this account
+ * @author Patrick Cool <patrick.cool@UGent.be>, Ghent University
+ * @param int $active the current state of the account
+ * @param int $user_id The user id
+ * @param string $url_params
+ * @return string Some HTML-code with the lock/unlock button
+ */
+function active_filter($active, $url_params, $row)
+{
+	global $_uid;
+
+	if ($active=='1')
+	{
+		$action='lock';
+		$image='right';
+	}
+	if ($active=='0')
+	{
+		$action='unlock';
+		$image='wrong';
+	}
+
+	if ($row['0']<>$_uid) // you cannot lock yourself out otherwise you could disable all the accounts including your own => everybody is locked out and nobody can change it anymore.
+	{
+		$result = '<a href="user_list.php?action='.$action.'&amp;user_id='.$row['0'].'&amp;'.$url_params.'"><img src="../img/'.$image.'.gif" border="0" style="vertical-align: middle;" alt="'.get_lang($action).'" title="'.get_lang($action).'"/></a>';
+	}
+	return $result;
+}
+
+/**
+ * lock or unlock a user
+ * @author Patrick Cool <patrick.cool@UGent.be>, Ghent University
+ * @param int $status, do we want to lock the user ($status=lock) or unlock it ($status=unlock)
+ * @param int $user_id The user id
+ * @return language variable
+ */
+function lock_unlock_user($status,$user_id)
+{
+	$user_table = Database :: get_main_table(MAIN_USER_TABLE);
+
+	if ($status=='lock')
+	{
+		$status_db='0';
+		$return_message=get_lang('UserLocked');
+	}
+	if ($status=='unlock')
+	{
+		$status_db='1';
+		$return_message=get_lang('UserUnlocked');
+	}
+
+	if(($status_db=='1' OR $status_db=='0') AND is_numeric($user_id))
+	{
+		$sql="UPDATE $user_table SET active='".mysql_real_escape_string($status_db)."' WHERE user_id='".mysql_real_escape_string($user_id)."'";
+		$result = api_sql_query($sql, __FILE__, __LINE__);
+	}
+
+	if ($result)
+	{
+		return $return_message;
+	}
+}
+
+
+/**
+==============================================================================
+		INIT SECTION
+==============================================================================
+*/
+require_once (api_get_path(LIBRARY_PATH).'usermanager.lib.php');
+$action = $_GET["action"];
+$login_as_user_id = $_GET["user_id"];
+
+// Login as ...
+if ($_GET['action'] == "login_as" && isset ($login_as_user_id))
+{
+	login_user($login_as_user_id);
+}
+
+if (isset ($_GET['search']) && $_GET['search'] == 'advanced')
+{
+	//$interbreadcrumb[] = array ("url" => "index.php", "name" => get_lang('PlatformAdmin'));
+	$interbreadcrumb[] = array ("url" => 'user_list.php', "name" => get_lang('UserList'));
+	$tool_name = get_lang('SearchAUser');
+	Display :: display_header($tool_name);
+	//api_display_tool_title($tool_name);
+	$form = new FormValidator('advanced_search','get');
+	$form->add_textfield('keyword_firstname',get_lang('FirstName'),false);
+	$form->add_textfield('keyword_lastname',get_lang('LastName'),false);
+	$form->add_textfield('keyword_username',get_lang('LoginName'),false);
+	$form->add_textfield('keyword_email',get_lang('Email'),false);
+	$form->add_textfield('keyword_officialcode',get_lang('OfficialCode'),false);
+	$status_options = array();
+	$status_options['%'] = get_lang('All');
+	$status_options[STUDENT] = get_lang('Student');
+	$status_options[COURSEMANAGER] = get_lang('Teacher');
+	$form->addElement('select','keyword_status',get_lang('Status'),$status_options);
+	$active_group = array();
+	$active_group[] = $form->createElement('checkbox','keyword_active','',get_lang('Active'));
+	$active_group[] = $form->createElement('checkbox','keyword_inactive','',get_lang('Inactive'));
+	$form->addGroup($active_group,'',get_lang('ActiveAccount'),'<br/>',false);
+	$form->addElement('submit','submit',get_lang('Ok'));
+	$defaults['keyword_active'] = 1;
+	$defaults['keyword_inactive'] = 1;
+	$form->setDefaults($defaults);
+	$form->display();
+}
+else
+{
+	//$interbreadcrumb[] = array ("url" => "index.php", "name" => get_lang('PlatformAdmin'));
+	$tool_name = get_lang('UserList');
+	Display :: display_header($tool_name, "");
+	//api_display_tool_title($tool_name);
+	if (isset ($_GET['action']))
+	{
+		switch ($_GET['action'])
+		{
+			case 'show_message' :
+				Display :: display_normal_message(stripslashes($_GET['message']));
+				break;
+			case 'delete_user' :
+				if ($user_id != $_uid && UserManager :: delete_user($_GET['user_id']))
+				{
+					Display :: display_normal_message(get_lang('UserDeleted'));
+				}
+				else
+				{
+					Display :: display_error_message(get_lang('CannotDeleteUser'));
+				}
+				break;
+			case 'lock' :
+				$message=lock_unlock_user('lock',$_GET['user_id']);
+				Display :: display_normal_message($message);
+				break;
+			case 'unlock';
+				$message=lock_unlock_user('unlock',$_GET['user_id']);
+				Display :: display_normal_message($message);
+				break;
+
+		}
+	}
+	if (isset ($_POST['action']))
+	{
+		switch ($_POST['action'])
+		{
+			case 'delete' :
+				$number_of_selected_users = count($_POST['id']);
+				$number_of_deleted_users = 0;
+				foreach ($_POST['id'] as $index => $user_id)
+				{
+					if($user_id != $_uid)
+					{
+						if(UserManager :: delete_user($user_id))
+						{
+							$number_of_deleted_users++;
+						}
+					}
+				}
+				if($number_of_selected_users == $number_of_deleted_users)
+				{
+					Display :: display_normal_message(get_lang('SelectedUsersDeleted'));
+				}
+				else
+				{
+					Display :: display_error_message(get_lang('SomeUsersNotDeleted'));
+				}
+				break;
+		}
+	}
+	// Create a search-box
+	$form = new FormValidator('search_simple','get','','',null,false);
+	$renderer =& $form->defaultRenderer();
+	$renderer->setElementTemplate('<span>{element}</span> ');
+	$form->addElement('text','keyword',get_lang('keyword'));
+	$form->addElement('submit','submit',get_lang('Search'));
+	$form->addElement('static','search_advanced_link',null,'<a href="user_list.php?search=advanced">'.get_lang('AdvancedSearch').'</a>');
+	$form->display();
+	if (isset ($_GET['keyword']))
+	{
+		$parameters = array ('keyword' => $_GET['keyword']);
+	}
+	elseif (isset ($_GET['keyword_firstname']))
+	{
+		$parameters['keyword_firstname'] = $_GET['keyword_firstname'];
+		$parameters['keyword_lastname'] = $_GET['keyword_lastname'];
+		$parameters['keyword_email'] = $_GET['keyword_email'];
+		$parameters['keyword_officialcode'] = $_GET['keyword_officialcode'];
+		$parameters['keyword_status'] = $_GET['keyword_status'];
+		$parameters['keyword_active'] = $_GET['keyword_active'];
+		$parameters['keyword_inactive'] = $_GET['keyword_inactive'];
+	}
+	// Create a sortable table with user-data
+	$table = new SortableTable('users', 'get_number_of_users', 'get_user_data',2);
+	$table->set_additional_parameters($parameters);
+	$table->set_header(0, '', false);
+	$table->set_header(1, get_lang('OfficialCode'));
+	$table->set_header(2, get_lang('LastName'));
+	$table->set_header(3, get_lang('FirstName'));
+	$table->set_header(4, get_lang('LoginName'));
+	$table->set_header(5, get_lang('Email'));
+	$table->set_header(6, get_lang('Status'));
+	$table->set_header(7, get_lang('Active'));
+	$table->set_header(8, get_lang('Modify'));
+	$table->set_column_filter(5, 'email_filter');
+	$table->set_column_filter(7, 'active_filter');
+	$table->set_column_filter(8, 'modify_filter');
+	$table->set_form_actions(array ('delete' => get_lang('DeleteFromPlatform')));
+	$table->display();
+}
+/*
+==============================================================================
+		FOOTER
+==============================================================================
+*/
+Display :: display_footer();
+?>

+ 736 - 0
main/announcements/announcements.inc.php

@@ -0,0 +1,736 @@
+<?php //$Id: announcements.inc.php 9246 2006-09-25 13:24:53Z bmol $
+/*
+==============================================================================
+	Dokeos - elearning and course management software
+
+	Copyright (c) 2004-2005 Dokeos S.A.
+	Copyright (c) various contributors
+
+	For a full list of contributors, see "credits.txt".
+	The full license can be read in "license.txt".
+
+	This program is free software; you can redistribute it and/or
+	modify it under the terms of the GNU General Public License
+	as published by the Free Software Foundation; either version 2
+	of the License, or (at your option) any later version.
+
+	See the GNU General Public License for more details.
+
+	Contact address: Dokeos, 44 rue des palais, B-1030 Brussels, Belgium
+	Mail: info@dokeos.com
+==============================================================================
+*/
+/**
+==============================================================================
+* Include file with functions for the announcements module.
+* @package dokeos.announcements
+==============================================================================
+*/
+
+/*
+==============================================================================
+		DISPLAY FUNCTIONS
+==============================================================================
+*/
+/**
+* displays one specific announcement
+* @param $announcement_id, the id of the announcement you want to display
+* @todo remove globals
+* @todo more security checking
+*/
+function display_announcement($announcement_id)
+{
+	global $_uid, $dateFormatLong;
+	$tbl_announcement 	= Database::get_course_table('announcement');
+	$tbl_item_property	= Database::get_course_table('item_property');
+	
+	if ($_uid)
+	{
+		$sql_query = "	SELECT announcement.*, toolitemproperties.*
+						FROM $tbl_announcement announcement, $tbl_item_property toolitemproperties
+						WHERE announcement.id = toolitemproperties.ref
+						AND announcement.id = '$announcement_id'
+						AND toolitemproperties.tool='announcement'
+						AND (toolitemproperties.to_user_id=$_uid OR toolitemproperties.to_group_id='0')
+						AND toolitemproperties.visibility='1'
+						ORDER BY display_order DESC";
+
+	}
+	else
+	{
+		$sql_query = "	SELECT announcement.*, toolitemproperties.*
+						FROM $tbl_announcement announcement, $tbl_item_property toolitemproperties
+						WHERE announcement.id = toolitemproperties.ref
+						AND announcement.id = '$announcement_id'
+						AND toolitemproperties.tool='announcement'
+						AND toolitemproperties.to_group_id='0'
+						AND toolitemproperties.visibility='1'";
+	}
+	$sql_result = api_sql_query($sql_query,__FILE__,__LINE__);
+	$result = mysql_fetch_array($sql_result);
+	
+	$title		 = $result['title'];
+	$content	 = $result['content'];
+	$content     = make_clickable($content);
+	$content     = text_filter($content);
+	$last_post_datetime = $myrow['temps'];// post time format  datetime de mysql
+	list($last_post_date, $last_post_time) = split(" ", $last_post_datetime);
+	
+	echo "<table height=\"100\" width=\"100%\" border=\"1\" cellpadding=\"5\" cellspacing=\"0\" id=\"agenda_list\">\n";
+	echo "<tr class=\"data\"><td>" . $title . "</td></tr>\n";
+	echo "<tr><td class=\"announcements_datum\">" . get_lang('AnnouncementPublishedOn') . " : " . ucfirst(format_locale_date($dateFormatLong,strtotime($last_post_date) ) ) . "</td></tr>\n";
+	echo "<tr class=\"text\"><td>$content</td></tr>\n";
+	echo "</table>";
+}
+
+/*======================================
+	          SHOW_TO_FORM
+======================================*/
+/**
+* this function shows the form for sending a message to a specific group or user.
+*/
+function show_to_form($to_already_selected)
+{
+	$user_list=get_course_users();
+	$group_list=get_course_groups();
+
+	echo "\n<table>\n";
+	echo "\t<tr>\n";
+	
+	// the form containing all the groups and all the users of the course
+	echo "\t\t<td>\n";
+	construct_not_selected_select_form($group_list,$user_list,$to_already_selected);
+	echo "\t\t</td>\n";
+	
+	// the buttons for adding or removing groups/users
+	echo "\n\t\t<td valign=\"middle\">\n";
+	echo "\t\t<input	type=\"button\"	",
+				"onClick=\"move(this.form.elements[1],this.form.elements[4])\" ",               // 7 & 4 : fonts
+				"value=\"   >>   \">",
+
+				"\n\t\t<p>&nbsp;</p>",
+
+				"\n\t\t<input	type=\"button\"",
+				"onClick=\"move(this.form.elements[4],this.form.elements[1])\" ",
+				"value=\"   <<   \">";
+	echo "\t\t</td>\n";
+	echo "\n\t\t<td>\n";
+	
+	// the form containing the selected groups and users
+	construct_selected_select_form($group_list,$user_list,$to_already_selected);
+	echo "\t\t</td>\n";
+	echo "\t</tr>\n";
+	echo "</table>";
+}
+
+
+/*===========================================
+	  CONSTRUCT_NOT_SELECT_SELECT_FORM
+===========================================*/
+/**
+* this function shows the form for sending a message to a specific group or user.
+*/
+function construct_not_selected_select_form($group_list=null, $user_list=null,$to_already_selected)
+{
+
+	echo "\t\t<select name=\"not_selected_form[]\" size=5 style=\"width:200px\" multiple>\n";
+	// adding the groups to the select form
+	if ($group_list)
+	{
+		foreach($group_list as $this_group)
+		{
+			if (!in_array("GROUP:".$this_group[id],$to_already_selected)) // $to_already_selected is the array containing the groups (and users) that are already selected
+			{
+				echo	"\t\t<option value=\"GROUP:".$this_group[id]."\">",
+				"G: ",$this_group[name]," - " . $this_group[userNb] . " " . get_lang('Users') .
+				"</option>\n";
+			}
+		}
+		// a divider
+		echo	"\t\t<option value=\"\">---------------------------------------------------------</option>\n";
+	}
+	// adding the individual users to the select form
+	foreach($user_list as $this_user)
+	{
+		if (!in_array("USER:".$this_user[uid],$to_already_selected)) // $to_already_selected is the array containing the users (and groups) that are already selected
+		{
+			echo	"\t\t<option value=\"USER:",$this_user[uid],"\">",
+				"",$this_user[lastName]," ",$this_user[firstName],
+				"</option>\n";
+		}
+	}
+	echo "\t\t</select>\n";
+}
+
+
+
+/*==========================================
+	   CONSTRUCT_SELECTED_SELECT_FORM
+==========================================*/
+/**
+* this function shows the form for sending a message to a specific group or user.
+*/
+function construct_selected_select_form($group_list=null, $user_list=null,$to_already_selected)
+{
+	// we separate the $to_already_selected array (containing groups AND users into
+	// two separate arrays
+	if (is_array($groupuser))
+	{
+		$groupuser=separate_users_groups($to_already_selected);
+	}
+	$groups_to_already_selected=$groupuser['groups'];
+	$users_to_already_selected=$groupuser['users'];
+
+	// we load all the groups and all the users into a reference array that we use to search the name of the group / user
+	$ref_array_groups=get_course_groups();
+	$ref_array_users=get_course_users();
+
+	// we construct the form of the already selected groups / users
+	echo "\t\t<select name=\"selectedform[]\" size=\"5\" multiple style=\"width:200px\" width=\"200px\">";
+	foreach($to_already_selected as $groupuser)
+	{
+		list($type,$id)=explode(":",$groupuser);
+		if ($type=="GROUP")
+		{
+			echo "\t\t<option value=\"".$groupuser."\">G: ".$ref_array_groups[$id]['name']."</option>";
+		}
+		else
+		{
+			echo "\t\t<option value=\"".$groupuser."\">".$ref_array_users[$id]['lastName']." ".$ref_array_users[$id]['firstName']."</option>";
+		}
+	}
+	echo "</select>\n";
+}
+
+
+/*
+==============================================================================
+		DATA FUNCTIONS
+==============================================================================
+*/
+
+/**
+* this function gets all the users of the course,
+* including users from linked courses
+*/
+function get_course_users()
+{
+	//this would return only the users from real courses:
+	//$user_list = CourseManager::get_user_list_from_course_code(api_get_course_id());
+	
+	$user_list = CourseManager::get_real_and_linked_user_list(api_get_course_id());
+	return $user_list;
+}
+
+/**
+* this function gets all the groups of the course,
+* not including linked courses
+*/
+function get_course_groups()
+{
+	$new_group_list = CourseManager::get_group_list_of_course(api_get_course_id());
+	return $new_group_list;
+}
+
+/*======================================
+	          LOAD_EDIT_USERS
+======================================*/
+/**
+* This tools loads all the users and all the groups who have received
+* a specific item (in this case an announcement item)
+*/
+function load_edit_users($tool, $id)
+{
+	global $_course;
+	global $tbl_item_property;
+
+	$sql="SELECT * FROM $tbl_item_property WHERE tool='$tool' AND ref='$id'";
+	$result=api_sql_query($sql,__FILE__,__LINE__) or die (mysql_error());
+	while ($row=mysql_fetch_array($result))
+	{
+		$to_group=$row['to_group_id'];
+		switch ($to_group)
+		{
+			// it was send to one specific user
+			case null:
+				$to[]="USER:".$row['to_user_id'];
+				break;
+			// it was sent to everyone
+			case 0:
+				 return "everyone";
+				 exit;
+				 break;
+			default:
+				$to[]="GROUP:".$row['to_group_id'];
+		}
+	}
+	return $to;
+}
+
+
+
+/*======================================
+	 USER_GROUP_FILTER_JAVASCRIPT
+======================================*/
+/**
+* returns the javascript for setting a filter
+* this goes into the $htmlHeadXtra[] array
+*/
+function user_group_filter_javascript()
+{
+	return "<script language=\"JavaScript\" type=\"text/JavaScript\">
+	<!--
+	function jumpMenu(targ,selObj,restore)
+	{
+	  eval(targ+\".location='\"+selObj.options[selObj.selectedIndex].value+\"'\");
+	  if (restore) selObj.selectedIndex=0;
+	}
+	//-->
+	</script>
+	";
+}
+
+
+/*======================================
+	         TO_JAVASCRIPT
+========================================*/
+/**
+* returns all the javascript that is required for easily
+* setting the target people/groups
+* this goes into the $htmlHeadXtra[] array
+*/
+function to_javascript()
+{
+	return "<script type=\"text/javascript\" language=\"JavaScript\">
+
+	<!-- Begin javascript menu swapper
+
+	function move(fbox,	tbox)
+	{
+		var	arrFbox	= new Array();
+		var	arrTbox	= new Array();
+		var	arrLookup =	new	Array();
+
+		var	i;
+		for	(i = 0;	i <	tbox.options.length; i++)
+		{
+			arrLookup[tbox.options[i].text]	= tbox.options[i].value;
+			arrTbox[i] = tbox.options[i].text;
+		}
+
+		var	fLength	= 0;
+		var	tLength	= arrTbox.length;
+
+		for(i =	0; i < fbox.options.length;	i++)
+		{
+			arrLookup[fbox.options[i].text]	= fbox.options[i].value;
+
+			if (fbox.options[i].selected &&	fbox.options[i].value != \"\")
+			{
+				arrTbox[tLength] = fbox.options[i].text;
+				tLength++;
+			}
+			else
+			{
+				arrFbox[fLength] = fbox.options[i].text;
+				fLength++;
+			}
+		}
+
+		arrFbox.sort();
+		arrTbox.sort();
+		fbox.length	= 0;
+		tbox.length	= 0;
+
+		var	c;
+		for(c =	0; c < arrFbox.length; c++)
+		{
+			var	no = new Option();
+			no.value = arrLookup[arrFbox[c]];
+			no.text	= arrFbox[c];
+			fbox[c]	= no;
+		}
+		for(c =	0; c < arrTbox.length; c++)
+		{
+			var	no = new Option();
+			no.value = arrLookup[arrTbox[c]];
+			no.text	= arrTbox[c];
+			tbox[c]	= no;
+		}
+	}
+
+	function validate()
+	{
+		var	f =	document.new_calendar_item;
+		f.submit();
+		return true;
+	}
+
+
+	function selectAll(cbList,bSelect,showwarning)
+	{
+		if (cbList.length <	1) {
+			alert(\"".get_lang('Send2All')."\");
+			return;
+		}
+		for	(var i=0; i<cbList.length; i++)
+			cbList[i].selected = cbList[i].checked = bSelect
+	}
+
+	function reverseAll(cbList)
+	{
+		for	(var i=0; i<cbList.length; i++)
+		{
+			cbList[i].checked  = !(cbList[i].checked)
+			cbList[i].selected = !(cbList[i].selected)
+		}
+	}
+	//	End	-->
+	</script>";
+}
+
+
+/*======================================
+			SENT_TO_FORM
+======================================*/
+/**
+* constructs the form to display all the groups and users the message has been sent to
+* input: 	$sent_to_array is a 2 dimensional array containing the groups and the users
+*			the first level is a distinction between groups and users:
+*			$sent_to_array['groups'] * and $sent_to_array['users']
+*			$sent_to_array['groups'] (resp. $sent_to_array['users']) is also an array
+*			containing all the id's of the groups (resp. users) who have received this message.
+* @author Patrick Cool <patrick.cool@>
+*/
+function sent_to_form($sent_to_array)
+{
+	// we find all the names of the groups
+	$group_names=get_course_groups();
+
+	count($sent_to_array);
+
+	// we count the number of users and the number of groups
+	if (isset($sent_to_array['users']))
+	{
+		$number_users=count($sent_to_array['users']);
+	}
+	else
+	{
+		$number_users=0;
+	}
+	if (isset($sent_to_array['groups']))
+	{
+		$number_groups=count($sent_to_array['groups']);
+	}
+	else
+	{
+			$number_groups=0;
+	}
+	$total_numbers=$number_users+$number_groups;
+
+	// starting the form if there is more than one user/group
+	if ($total_numbers >1)
+	{
+		$output="<select name=\"sent to\">\n";
+		$output.="<option>".get_lang("SentTo")."</option>";
+		// outputting the name of the groups
+		if (is_array($sent_to_array['groups']))
+		{
+			foreach ($sent_to_array['groups'] as $group_id)
+			{
+				$output.="\t<option value=\"\">G: ".$group_names[$group_id]['name']."</option>\n";
+			}
+		}
+		
+		if (isset($sent_to_array['users']))
+		{
+			if (is_array($sent_to_array['users']))
+			{
+				foreach ($sent_to_array['users'] as $user_id)
+				{
+					$user_info=api_get_user_info($user_id);
+					$output.="\t<option value=\"\">".$user_info['lastName']." ".$user_info['firstName']."</option>\n";
+				}
+			}
+		}
+		
+		// ending the form
+		$output.="</select>\n";
+	}
+	else // there is only one user/group
+	{
+		if (is_array($sent_to_array['users']))
+		{
+			$user_info=api_get_user_info($sent_to_array['users'][0]);
+			echo $user_info['lastName']." ".$user_info['firstName'];
+		}
+		if (is_array($sent_to_array['groups']) and $sent_to_array['groups'][0]!==0)
+		{
+			$group_id=$sent_to_array['groups'][0];
+			echo $group_names[$group_id]['name'];
+		}
+		if (is_array($sent_to_array['groups']) and $sent_to_array['groups'][0]==0)
+		{
+			echo get_lang("Everybody");
+		}
+	}
+
+	echo $output;
+}
+
+
+/*======================================
+			SEPARATE_USERS_GROUPS
+	======================================*/
+/**
+* This function separates the users from the groups
+* users have a value USER:XXX (with XXX the dokeos id
+* groups have a value GROUP:YYY (with YYY the group id)
+*/
+function separate_users_groups($to)
+{
+	foreach($to as $to_item)
+	{
+		list($type, $id) = explode(':', $to_item);
+
+		switch($type)
+		{
+			case 'GROUP':
+				$grouplist[] =$id;
+				break;
+			case 'USER':
+				$userlist[] =$id;
+				break;
+		}
+	}
+
+	$send_to['groups']=$grouplist;
+	$send_to['users']=$userlist;
+	return $send_to;
+}
+
+
+
+/*======================================
+	 			SENT_TO()
+  ======================================*/
+/**
+* returns all the users and all the groups a specific announcement item
+* has been sent to
+*/
+function sent_to($tool, $id)
+{
+	global $_course;
+	global $tbl_item_property;
+
+	$sql="SELECT * FROM $tbl_item_property WHERE tool='$tool' AND ref='".$id."'";
+	$result = api_sql_query($sql,__FILE__,__LINE__);
+
+	while ($row=mysql_fetch_array($result))
+	{
+		// if to_group_id is null then it is sent to a specific user
+		// if to_group_id = 0 then it is sent to everybody
+		if (!is_null($row['to_group_id']))
+		{
+			$sent_to_group[]=$row['to_group_id'];
+		}
+		// if to_user_id <> 0 then it is sent to a specific user
+		if ($row['to_user_id'] <> 0)
+		{
+			$sent_to_user[]=$row['to_user_id'];
+		}
+	}
+	if (isset($sent_to_group))
+	{
+		$sent_to['groups']=$sent_to_group;
+	}
+	if (isset($sent_to_user))
+	{
+		$sent_to['users']=$sent_to_user;
+	}
+	return $sent_to;
+}
+
+
+/*===================================================
+	           CHANGE_VISIBILITY($tool,$id)
+  =================================================*/
+/**
+* This functions swithes the visibility a course resource
+* using the visibility field in 'item_property'
+* values: 0 = invisibility for
+*/
+function change_visibility($tool,$id)
+{
+	global $_course;
+	global $tbl_item_property;
+
+	$sql="SELECT * FROM $tbl_item_property WHERE tool='$tool' AND ref='$id'";
+
+	$result=api_sql_query($sql,__FILE__,__LINE__) or die (mysql_error());
+	$row=mysql_fetch_array($result);
+
+	if ($row['visibility']=='1')
+	{
+		$sql_visibility="UPDATE $tbl_item_property SET visibility='0' WHERE tool='$tool' AND ref='$id'";
+	}
+	else
+	{
+		$sql_visibility="UPDATE $tbl_item_property SET visibility='1' WHERE tool='$tool' AND ref='$id'";
+	}
+
+	$result=api_sql_query($sql_visibility,__FILE__,__LINE__) or die (mysql_error());
+}
+
+
+/*====================================================
+	            STORE_ADVALVAS_ITEM
+====================================================*/
+
+function store_advalvas_item($emailTitle,$newContent, $order, $to)
+{
+
+	global $_course;
+	global $nameTools;
+	global $_uid;
+
+	global $tbl_announcement;
+	global $tbl_item_property;
+
+	// store in the table announcement
+	$sql = "INSERT INTO $tbl_announcement SET content = '$newContent', title = '$emailTitle', end_date = NOW(), display_order ='$order'";
+	$result = api_sql_query($sql,__FILE__,__LINE__) or die (mysql_error());
+	$last_id= mysql_insert_id();
+
+	// store in item_property (first the groups, then the users
+	if (!is_null($to)) // !is_null($to): when no user is selected we send it to everyone
+	{
+		$send_to=separate_users_groups($to);
+		// storing the selected groups
+		if (is_array($send_to['groups']))
+		{
+			foreach ($send_to['groups'] as $group)
+			{
+				api_item_property_update($_course, TOOL_ANNOUNCEMENT, $last_id, "AnnouncementAdded", $_uid, $group); 
+			}
+		}
+
+		// storing the selected users
+		if (is_array($send_to['users']))
+		{
+			foreach ($send_to['users'] as $user)
+			{
+					api_item_property_update($_course, TOOL_ANNOUNCEMENT, $last_id, "AnnouncementAdded", $_uid, '', $user);
+			}
+		}
+	}
+	else // the message is sent to everyone, so we set the group to 0
+	{
+		api_item_property_update($_course, TOOL_ANNOUNCEMENT, $last_id, "AnnouncementAdded", $_uid, '0');
+	}
+
+	return $last_id;
+
+}
+
+
+/*==================================================
+	           EDIT_VALVAS_ITEM
+==================================================*/
+/**
+* This function stores the announcement Item in the table announcement
+* and updates the item_property also
+*/
+function edit_advalvas_item($id,$emailTitle,$newContent,$to)
+{
+	global $_course;
+	global $nameTools;
+	global $_uid;
+
+	global $tbl_announcement;
+	global $tbl_item_property;
+
+	// store the modifications in the table announcement
+	$sql = "UPDATE $tbl_announcement SET content='$newContent', title = '$emailTitle' WHERE id='$id'";
+
+	$result = api_sql_query($sql,__FILE__,__LINE__) or die (mysql_error());
+
+	// we remove everything from item_property for this
+	$sql_delete="DELETE FROM $tbl_item_property WHERE ref='$id' AND tool='announcement'";
+	$result = api_sql_query($sql_delete,__FILE__,__LINE__) or die (mysql_error());
+
+	// store in item_property (first the groups, then the users
+	if (!is_null($to)) // !is_null($to): when no user is selected we send it to everyone
+	{
+		$send_to=separate_users_groups($to);
+		// storing the selected groups
+		if (is_array($send_to['groups']))
+		{
+			foreach ($send_to['groups'] as $group)
+			{
+				api_item_property_update($_course, TOOL_ANNOUNCEMENT, $id, "AnnouncementUpdated", $_uid, $group);
+			}
+		}
+		// storing the selected users
+		if (is_array($send_to['users']))
+		{
+			foreach ($send_to['users'] as $user)
+			{
+					api_item_property_update($_course, TOOL_ANNOUNCEMENT, $id, "AnnouncementUpdated", $_uid, '', $user);
+			}
+		}
+	}
+	else // the message is sent to everyone, so we set the group to 0
+	{
+		api_item_property_update($_course, TOOL_ANNOUNCEMENT, $id, "AnnouncementUpdated", $_uid, '0');
+	}
+}
+
+
+/*
+==============================================================================
+		MAIL FUNCTIONS
+==============================================================================
+*/
+
+/**
+* Sends an announcement by email to a list of users.
+* Emails are sent one by one to try to avoid antispam.
+*/
+function send_announcement_email($user_list, $course_code, $_course, $mail_title, $mail_content)
+{
+	foreach ($user_list as $this_user)
+	{
+		/*    Header : Bericht van uw lesgever - GES ($course_code) - Morgen geen les! ($mail_title)
+				Body :   John Doe (prenom + nom) <john_doe@hotmail.com> (email)
+
+						Morgen geen les! ($mail_title)
+
+						Morgen is er geen les, de les wordt geschrapt wegens vergadering (newContent)
+		*/
+		$mail_subject = get_lang('professorMessage').' - '.$_course['official_code'].' - '.$mail_title;
+
+		$mail_body = '['.$_course['official_code'].'] - ['.$_course['name']."]\n";
+		$mail_body .= $this_user['lastname'].' '.$this_user['firstname'].' <'.$this_user["email"]."> \n\n".stripslashes($mail_title)."\n\n".trim(stripslashes(html_entity_decode(strip_tags(str_replace(array('<p>','</p>','<br />'),array('',"\n","\n"),$mail_content)))))." \n\n-- \n";
+		$mail_body .= $_user['firstName'].' '.$_user['lastName'].' ';
+		$mail_body .= '<'.$_user['mail'].">\n";
+		$mail_body .= $_course['official_code'].' '.$_course['name'];
+		
+		//set the charset and use it for the encoding of the email - small fix, not really clean (should check the content encoding origin first)
+		//here we use the encoding used for the webpage where the text is encoded (ISO-8859-1 in this case)
+		if(empty($charset)){$charset='ISO-8859-1';}
+		$encoding = 'Content-Type: text/plain; charset='. $charset;
+		
+		$newmail = api_mail($this_user['lastname'].' '.$this_user['firstname'], $this_user['email'], $mail_subject, $mail_body, $_SESSION['_user']['lastName'].' '.$_SESSION['_user']['firstName'], $_SESSION['_user']['mail'], $encoding);
+	}
+}
+
+function update_mail_sent($insert_id)
+{
+	global $_course;
+	global $tbl_announcement;
+
+	// store the modifications in the table tbl_annoucement
+	$sql = "UPDATE $tbl_announcement SET email_sent='1' WHERE id='$insert_id'";
+	api_sql_query($sql,__FILE__,__LINE__);
+}

+ 1473 - 0
main/announcements/announcements.php

@@ -0,0 +1,1473 @@
+<?php //$Id: announcements.php 9654 2006-10-24 08:24:19Z bmol $
+/*
+==============================================================================
+	Dokeos - elearning and course management software
+
+	Copyright (c) 2004-2005 Dokeos S.A.
+	Copyright (c) 2003 Ghent University (UGent)
+	Copyright (c) 2001 Universite catholique de Louvain (UCL)
+	Copyright (c) various contributors
+
+	For a full list of contributors, see "credits.txt".
+	The full license can be read in "license.txt".
+
+	This program is free software; you can redistribute it and/or
+	modify it under the terms of the GNU General Public License
+	as published by the Free Software Foundation; either version 2
+	of the License, or (at your option) any later version.
+
+	See the GNU General Public License for more details.
+
+	Contact address: Dokeos, 44 rue des palais, B-1030 Brussels, Belgium
+	Mail: info@dokeos.com
+==============================================================================
+*/
+/**
+==============================================================================
+ * @author Frederik Vermeire <frederik.vermeire@pandora.be>, UGent Internship
+ * @author Patrick Cool <patrick.cool@UGent.be>, Ghent University: code cleaning
+ * @abstract The task of the internship was to integrate the 'send messages to specific users' with the
+ *			 Announcements tool and also add the resource linker here. The database also needed refactoring
+ *			 as there was no title field (the title was merged into the content field)
+ * @package dokeos.announcements
+ * @todo make AWACS out of the configuration settings
+ * @todo this file is 1200+ lines without any functions -> needs to be split into
+ * multiple functions
+==============================================================================
+*/
+/*
+==============================================================================
+		INIT SECTION
+==============================================================================
+*/
+// setting the language file
+$langFile[] = "announcements";
+$langFile[] = "group";
+$langFile[] = "survey";
+
+// setting the global file that gets the general configuration, the databases, the languages, ...
+include('../inc/global.inc.php');
+$this_section=SECTION_COURSES;
+
+$nameTools = get_lang('Announcement');
+
+
+//session
+if(isset($_GET['id_session']))
+	$_SESSION['id_session'] = $_GET['id_session'];
+
+/* ------------	ACCESS RIGHTS ------------ */
+// notice for unauthorized people.
+api_protect_course_script();
+
+/*
+-----------------------------------------------------------
+	Constants and variables
+-----------------------------------------------------------
+*/
+// Configuration settings
+$display_announcement_list = true;
+$display_form             = false;
+$display_title_list 		 = true;
+
+// Maximum title messages to display
+$maximum 	= '12';
+
+// Length of the titles
+$length 	= '36';
+
+// Database variables
+$tbl_course_user   		= Database::get_main_table(MAIN_COURSE_USER_TABLE);
+$tbl_user          		= Database::get_main_table(MAIN_USER_TABLE);
+$tbl_courses			= Database::get_main_table(MAIN_COURSE_TABLE);
+$tbl_sessions			= Database::get_main_table(MAIN_SESSION_TABLE);
+$tbl_session_course_user= Database::get_main_table(MAIN_SESSION_COURSE_USER_TABLE);
+$tbl_group     			= Database::get_course_table(GROUP_TABLE);
+$tbl_groupUser  		= Database::get_course_table(GROUP_USER_TABLE);
+$tbl_announcement		= Database::get_course_table(ANNOUNCEMENT_TABLE);
+$tbl_item_property  = Database::get_course_table(ITEM_PROPERTY_TABLE);
+
+/*
+-----------------------------------------------------------
+	Resource linker
+-----------------------------------------------------------
+*/
+$_SESSION['source_type']="Ad_Valvas";
+include('../resourcelinker/resourcelinker.inc.php');
+
+if ($_POST['addresources']) // When the "Add Resource" button is clicked we store all the form data into a session
+{
+	include('announcements.inc.php');
+
+    $form_elements= array ('emailTitle'=>stripslashes($emailTitle), 'newContent'=>stripslashes($newContent), 'id'=>$id, 'to'=>$selectedform, 'emailoption'=>$email_ann);
+    $_SESSION['formelements']=$form_elements;
+
+    if($id) // this is to correctly handle edits
+	{
+		  $action="edit";
+    }else
+    {
+		  $action="add";
+    }
+
+	// ============== //
+	// 7 = Ad_Valvas	//
+	// ============== //
+	if($surveyid)
+	{
+		header("Location: ../resourcelinker/resourcelinker.php?source_id=7&action=$action&id=$id&originalresource=no&publish_survey=$surveyid&db_name=$db_name&cidReq=$cidReq");
+		exit;
+	}
+	else
+	{
+		header("Location: ../resourcelinker/resourcelinker.php?source_id=7&action=$action&id=$id&originalresource=no");
+		exit;
+	}
+	exit;
+}
+
+/*
+-----------------------------------------------------------
+	Tracking
+-----------------------------------------------------------
+*/
+include(api_get_path(LIBRARY_PATH).'events.lib.inc.php');
+event_access_tool(TOOL_ANNOUNCEMENT);
+
+/*
+-----------------------------------------------------------
+	Libraries
+-----------------------------------------------------------
+*/
+require_once(api_get_path(LIBRARY_PATH).'groupmanager.lib.php');
+require_once('announcements.inc.php');
+require_once(api_get_path(INCLUDE_PATH).'lib/mail.lib.inc.php');
+require_once(api_get_path(INCLUDE_PATH).'conf/mail.conf.php');
+require_once(api_get_path(LIBRARY_PATH).'debug.lib.inc.php');
+
+/*
+-----------------------------------------------------------
+	POST TO
+-----------------------------------------------------------
+*/
+if ($_POST['To'])
+{
+	$display_form = true;
+
+	$form_elements= array ('emailTitle'=>stripslashes($emailTitle), 'newContent'=>stripslashes($newContent), 'id'=>$id, 'emailoption'=>$email_ann);
+    $_SESSION['formelements']=$form_elements;
+
+    $form_elements            	= $_SESSION['formelements'];
+
+	$title_to_modify            = $form_elements["emailTitle"];
+
+	$content_to_modify          = $form_elements["newContent"];
+
+	$announcement_to_modify     = $form_elements["id"];
+}
+
+/*
+-----------------------------------------------------------
+	Show/hide user/group form
+-----------------------------------------------------------
+*/
+
+$setting_select_groupusers=true;
+if (!$_POST['To'] and !$_SESSION['select_groupusers'])
+{
+	$_SESSION['select_groupusers']="hide";
+}
+$select_groupusers_status=$_SESSION['select_groupusers'];
+if ($_POST['To'] and ($select_groupusers_status=="hide"))
+{
+	$_SESSION['select_groupusers']="show";
+}
+if ($_POST['To'] and ($select_groupusers_status=="show"))
+{
+	$_SESSION['select_groupusers']="hide";
+}
+
+/*
+-----------------------------------------------------------
+	Action handling
+-----------------------------------------------------------
+*/
+
+// display the form
+if (($_GET['action'] == 'add' && $_GET['origin'] == "") || $_GET['action'] == 'edit' || $_POST['To'])
+{
+	$display_form = true;
+}
+
+// clear all resources
+if ($originalresource!=="no" and $action=="add")
+{
+	$_SESSION["formelements"]=null;
+	unset_session_resources();
+}
+
+/*
+-----------------------------------------------------------
+	Javascript
+-----------------------------------------------------------
+*/
+// this is a quick and dirty hack that fixes a bug http://www.dokeos.com/forum/viewtopic.php?t=5263
+// when you edit an announcement that was sent to specific users/groups
+if ($_SESSION['select_groupusers'] =="show" or $_GET['action']=='modify')
+{
+	// this javascript should only be loaded when we show the forms to send messages to individual users/groups
+	// because otherwise it produces a bug (=> year is set to 2009 on submit due to the javascript selectAll
+	$htmlHeadXtra[] = to_javascript();
+}
+
+/*
+-----------------------------------------------------------
+	Filter user/group
+-----------------------------------------------------------
+*/
+
+/*	if ($_GET['user'] or $_GET['group'])
+		{
+			$_SESSION['user']=$_GET['user'];
+			$_SESSION['group']=$_GET['group'];
+		}
+	if ($_GET['user']=="none" or $_GET['group']=="none")
+		{
+			api_session_unregister("user");
+			api_session_unregister("group");
+		}
+	if ($_GET['isStudentView']=="false")
+		{
+			api_session_unregister("user");
+			api_session_unregister("group");
+		}
+*/
+
+if(!empty($_GET['toolgroup'])){
+	if($_GET['toolgroup'] == strval(intval($_GET['toolgroup']))){ //check is integer
+		$toolgroup = $_GET['toolgroup'];
+		$_SESSION['select_groupusers'] = 'hide';
+	}else{
+		$toolgroup = 0;
+	}
+	api_session_register("toolgroup");
+}
+
+
+/*
+-----------------------------------------------------------
+	Sessions
+-----------------------------------------------------------
+*/
+if ($_SESSION['formelements'] and $_GET['originalresource'] == 'no')
+{
+	$form_elements			= $_SESSION['formelements'];
+	$title_to_modify		= $form_elements['emailTitle'];
+	$content_to_modify		= $form_elements['newContent'];
+	$announcement_to_modify	= $form_elements['id'];
+	$to						= $form_elements['to'];
+	//load_edit_users('announcement',$announcement_to_modify);
+
+	$email_ann				= $form_elements['emailoption'];
+}
+/*
+-----------------------------------------------------------
+	Survey
+-----------------------------------------------------------
+*/
+$surveyid=$_REQUEST['publish_survey'];
+$cidReq=$_REQUEST['cidReq'];
+if($surveyid)
+{
+$db_name=$_REQUEST['db_name'];
+$sql_temp = "SELECT * FROM $db_name.survey WHERE survey_id='$surveyid'";
+$res_temp = api_sql_query($sql_temp, __FILE__, __LINE__);
+$obj=@mysql_fetch_object($res_temp);
+$template=$obj->template;
+}
+if($surveyid)
+{
+$interbreadcrumb[] = array ("url" => "../survey/survey_list.php?cidReq=$cidReq", "name" => get_lang('Survey'));
+$nameTools = get_lang('PublishSurvey');
+}
+else
+$nameTools = get_lang('Announcement');
+
+$nameTools12 = get_lang('PublishSurvey');
+
+
+
+/*
+-----------------------------------------------------------
+	Learning path & css
+-----------------------------------------------------------
+*/
+// showing the header if we are not in the learning path, if we are in
+// the learning path, we do not include the banner so we have to explicitly
+// include the stylesheet, which is normally done in the header
+if ($_GET['origin'] !== 'learnpath')
+{
+	//we are not in the learning path
+	Display::Display_header($nameTools,"Announcements");
+}
+else
+{
+	//we are in the learning path, only display central data and change css
+	$display_title_list = false;
+	$display_announcement_list = false;
+	$display_specific_announcement = true;
+	$announcement_id = $_REQUEST['ann_id'];
+	?> <link rel="stylesheet" type="text/css" href="<?php echo $clarolineRepositoryWeb ?>css/default.css">
+	<!-- css file for announcements -->
+	<link href="../css/announcements.css" rel="stylesheet" type="text/css">
+	<?php
+}
+
+// inserting an anchor (top) so one can jump back to the top of the page
+echo "<a name=\"top\"></a>";
+
+/*=============================================
+			  ACTION HANDLING
+=============================================*/
+
+if (api_is_allowed_to_edit() OR api_get_course_setting('allow_user_edit_announcement'))
+{
+	/*
+	-----------------------------------------------------------
+		Change visibility of announcement
+	-----------------------------------------------------------
+	*/
+	// $_GET['isStudentView']<>"false" is added to prevent that the visibility
+	// is changed after you do the following:
+	// change visibility -> studentview -> course manager view
+	if ($_GET['isStudentView']<>"false")
+	{
+		if (isset($_GET['id']) AND $_GET['id'] AND isset($_GET['action']) AND $_GET['action']=="showhide")
+		{
+			$id=intval(addslashes($_GET['id']));
+			change_visibility(TOOL_ANNOUNCEMENT,$id);
+			$message = get_lang("Visible");
+		}
+	}
+
+	/*
+	-----------------------------------------------------------
+		Delete announcement
+	-----------------------------------------------------------
+	*/
+	if ($_GET['action']=="delete" AND isset($_GET['id']))
+	{
+		//api_sql_query("DELETE FROM  $tbl_announcement WHERE id='$delete'",__FILE__,__LINE__);
+		$id=intval(addslashes($_GET['id']));
+
+		// tooledit : visibility = 2 : only visibile for platform administrator
+		api_sql_query("UPDATE $tbl_item_property SET visibility='2' WHERE tool='".TOOL_ANNOUNCEMENT."' and ref='".$id."'",__FILE__,__LINE__);
+
+		delete_added_resource("Ad_Valvas", $delete);
+
+		$id = null;
+		$emailTitle = null;
+		$newContent = null;
+
+		$message = get_lang("AnnouncementDeleted");
+	}
+
+	/*
+	-----------------------------------------------------------
+		Delete all announcements
+	-----------------------------------------------------------
+	*/
+	if ($_GET['action']=="delete_all")
+	{
+
+		//api_sql_query("DELETE FROM $tbl_announcement",__FILE__,__LINE__);
+
+		api_sql_query("UPDATE $tbl_item_property SET visibility='2' WHERE tool='".TOOL_ANNOUNCEMENT."'",__FILE__,__LINE__);
+
+		delete_all_resources_type("Ad_Valvas");
+
+		$id = null;
+		$emailTitle = null;
+		$newContent = null;
+
+		$message = get_lang("AnnouncementDeletedAll");
+	}
+
+	/*
+	-----------------------------------------------------------
+		Modify announcement
+	-----------------------------------------------------------
+	*/
+	if ($_GET['action']=="modify" AND isset($_GET['id']))
+	{
+		$display_form = true;
+
+		// RETRIEVE THE CONTENT OF THE ANNOUNCEMENT TO MODIFY
+		$sql="SELECT * FROM  $tbl_announcement WHERE id='".$_GET['id']."'";
+		$result = api_sql_query($sql,__FILE__,__LINE__);
+		$myrow = mysql_fetch_array($result);
+
+		if ($myrow)
+		{
+			$announcement_to_modify 	= $myrow['id'];
+			$content_to_modify 		= $myrow['content'];
+
+			$title_to_modify 			= $myrow['title'];
+
+			if ($originalresource!=="no") // and !addresources)
+			{
+				//unset_session_resources();
+				edit_added_resources("Ad_Valvas", $announcement_to_modify);
+				$to=load_edit_users("announcement", $announcement_to_modify);
+			}
+
+			$display_announcement_list = false;
+		}
+
+		if ($to=="everyone" OR !empty($_SESSION['toolgroup']))
+		{
+			$_SESSION['select_groupusers']="hide";
+		}
+		else
+		{
+			$_SESSION['select_groupusers']="show";
+		}
+
+	}
+
+	/*
+	-----------------------------------------------------------
+		Move announcement up/down
+	-----------------------------------------------------------
+	*/
+	if ($_GET['down'])
+	{
+		$thisAnnouncementId = $_GET['down'];
+		$sortDirection = "DESC";
+	}
+
+	if ($_GET['up'])
+	{
+		$thisAnnouncementId = $_GET['up'];
+		$sortDirection = "ASC";
+	}
+
+	if ($sortDirection)
+	{
+		if (!in_array(trim(strtoupper($sortDirection)), array('ASC', 'DESC')))
+		{
+			$sortDirection='ASC';
+		}
+		$my_sql = "SELECT announcement.id, announcement.display_order " .
+				"FROM $tbl_announcement announcement, " .
+				"$tbl_item_property itemproperty " .
+				"WHERE itemproperty.ref=announcement.id " .
+				"AND itemproperty.tool='".TOOL_ANNOUNCEMENT."' " .
+				"AND itemproperty.visibility<>2 " .
+				"ORDER BY display_order $sortDirection";
+		$result = api_sql_query($my_sql,__FILE__,__LINE__);
+
+		while (list ($announcementId, $announcementOrder) = mysql_fetch_row($result))
+		{
+			// STEP 2 : FOUND THE NEXT ANNOUNCEMENT ID AND ORDER.
+			//          COMMIT ORDER SWAP ON THE DB
+
+			if (isset ($thisAnnouncementOrderFound) && $thisAnnouncementOrderFound == true)
+			{
+				$nextAnnouncementId = $announcementId;
+				$nextAnnouncementOrder = $announcementOrder;
+				api_sql_query("UPDATE $tbl_announcement " .
+						"SET display_order = '$nextAnnouncementOrder' " .
+						"WHERE id =  '$thisAnnouncementId'",__FILE__,__LINE__);
+				api_sql_query("UPDATE $tbl_announcement " .
+						"SET display_order = '$thisAnnouncementOrder' " .
+						"WHERE id =  '$nextAnnouncementId.'",__FILE__,__LINE__);
+
+				break;
+			}
+
+			// STEP 1 : FIND THE ORDER OF THE ANNOUNCEMENT
+
+			if ($announcementId == $thisAnnouncementId)
+			{
+				$thisAnnouncementOrder = $announcementOrder;
+				$thisAnnouncementOrderFound = true;
+			}
+		}
+		// show message
+		$message = get_lang('AnnouncementMoved');
+	}
+
+	/*
+	-----------------------------------------------------------
+		Submit announcement
+	-----------------------------------------------------------
+	*/
+	if (api_is_allowed_to_edit() OR api_get_course_setting('allow_user_edit_announcement'))
+	{
+
+		$emailTitle=$_POST['emailTitle'];
+		$newContent=$_POST['newContent'];
+		$submitAnnouncement=isset($_POST['submitAnnouncement'])?$_POST['submitAnnouncement']:0;
+
+		$id=intval($_POST['id']);
+
+		if ($submitAnnouncement)
+		{
+			
+			if(isset($id)&&$id) // there is an Id => the announcement already exists => update mode
+			{
+				$edit_id = edit_advalvas_item($id,$emailTitle,$newContent,$selectedform);
+				if(!$delete)
+				{
+				    update_added_resources("Ad_Valvas", $id);
+				}
+				$message = get_lang('AnnouncementModified');
+			}
+			else //insert mode
+			{
+				if(!$surveyid){
+					$result = api_sql_query("SELECT MAX(display_order) FROM $tbl_announcement",__FILE__,__LINE__);
+	
+					list($orderMax) = mysql_fetch_row($result);
+					$order = $orderMax + 1;
+	
+					if(!empty($_SESSION['toolgroup'])){
+						$insert_id=store_advalvas_item($_POST['emailTitle'],$_POST['newContent'],$order,array('GROUP:'.$_SESSION['toolgroup']));
+					}else{
+						$insert_id=store_advalvas_item($_POST['emailTitle'],$_POST['newContent'],$order,$_POST['selectedform']);
+					}
+	
+				    store_resources($_SESSION['source_type'],$insert_id);
+	
+				    $_SESSION['select_groupusers']="hide";
+	
+				    $message = get_lang('AnnouncementAdded');
+				}
+
+/*============================================================
+MAIL WHEN USER COMES FROM SURVEY
+======================================================= */
+
+if($_POST['emailsAdd'])
+{
+
+	 $to_email_address =$_POST['emailsAdd'];
+	 $to_email_to = explode(',', $to_email_address);
+	 $to_email = array_unique($to_email_to);
+	 $db_name = $_REQUEST['db_name'];
+	for($i=0;$i<count($to_email);$i++)
+   {
+
+			$to= trim($to_email[$i]);
+			$db_name = $_REQUEST['db_name'];
+			$newContentone=str_replace("#page#","choose_language.php",$newContent);
+			$newContenttwo=str_replace("#temp#",$template,$newContentone);
+			$newContentthree=str_replace("#sid#",$surveyid,$newContenttwo);
+			$newContentfour=str_replace("#mail#",$to,$newContentthree);
+            $newContentfive=str_replace("#db_name#",$db_name,$newContentfour);
+			$newContentsix=str_replace("#uid#","",$newContentfive);
+
+if(eregi('^[0-9a-z_\.-]+@(([0-9]{1,3}\.){3}[0-9]{1,3}|([0-9a-z][0-9a-z-]*[0-9a-z]\.)+[a-z]{2,3})$', $to ))
+	{
+	  $subject=stripslashes($emailTitle);
+	 $message=stripslashes($newContentsix);
+
+    $sender_name = $_SESSION['_user']['lastName'].' '.$_SESSION['_user']['firstName'];
+    $email = $_SESSION['_user']['mail'];
+	$headers="From:$sender_name\r\nReply-to: $email\r\nContent-type: text/html; charset=iso-8859-15";
+	//@mail($to,$subject,$message,$headers);
+	//api_send_mail($to,$subject,$message,$headers);
+	api_mail('',$to,$subject,$message,$sender_name,$email,$headers);
+	$sql_date="SELECT * FROM $db_name.survey WHERE survey_id='$surveyid'";
+	$res_date=api_sql_query($sql_date);
+	$obj_date=mysql_fetch_object($res_date);
+	$end_date=$obj_date->avail_till;
+	$table_reminder = Database :: get_main_table(MAIN_SURVEY_REMINDER_TABLE);
+	if($_REQUEST['reminder']=="1")
+	{
+		$time=getdate();
+		$time = $time['yday'];
+		$time = $time+7;
+		$sql_insert="INSERT INTO $table_reminder(sid,db_name,email,subject,content,reminder_choice,reminder_time,avail_till) values('$surveyid','$db_name','$to','".addslashes($subject)."','".addslashes($message)."','1','$time','$end_date')";
+		api_sql_query($sql_insert);
+	}
+	else if($_REQUEST['reminder']=="2")
+	{
+		$time=getdate();
+		$time = $time['yday'];
+		$time = $time+14;
+		$sql_insert="INSERT INTO $table_reminder(sid,db_name,email,subject,content,reminder_choice,reminder_time,avail_till) values('$surveyid','$db_name','$to','".addslashes($subject)."','".addslashes($message)."','1','$time','$end_date')";
+		api_sql_query($sql_insert);
+	}
+	else if($_REQUEST['reminder']=="3")
+	{
+		$time=getdate();
+		$time = $time['yday'];
+		$time = $time+30;
+		$sql_insert="INSERT INTO $table_reminder(sid,db_name,email,subject,content,reminder_choice,reminder_time,avail_till) values('$surveyid','$db_name','$to','".addslashes($subject)."','".addslashes($message)."','1','$time','$end_date')";
+		api_sql_query($sql_insert);
+	}
+  }
+ }
+}
+
+				/*===================================================================
+				    							MAIL FUNCTION
+				===================================================================*/
+
+				if ($_POST['email_ann'] && empty($_POST['onlyThoseMails']))
+				{
+				  	$sent_to=sent_to("announcement", $insert_id);
+
+				    $userlist   = $sent_to['users'];
+				    $grouplist  = $sent_to['groups'];
+
+				        // groepen omzetten in users
+				        if ($grouplist)
+						{
+
+							$grouplist = "'".implode("', '",$grouplist)."'";	//protect individual elements with surrounding quotes
+							$sql = "SELECT user_id
+									FROM $tbl_groupUser gu
+									WHERE gu.group_id IN (".$grouplist.")";
+
+
+							$groupMemberResult = api_sql_query($sql,__FILE__,__LINE__);
+
+
+							if ($groupMemberResult)
+							{
+								while ($u = mysql_fetch_array($groupMemberResult))
+								{
+									$userlist [] = $u [user_id]; // complete the user id list ...
+								}
+							}
+						}
+
+
+					    if(is_array($userlist))
+					    {
+					    	$userlist = "'".implode("', '", array_unique($userlist) )."'";
+
+					    	// send to the created 'userlist'
+						    $sqlmail = "SELECT user_id, lastname, firstname, email
+							       					 FROM $tbl_user
+							       					 WHERE user_id IN (".$userlist.")";
+					    }
+				    	else if(empty($_POST['not_selected_form']))
+				    	{
+				    		// send to everybody
+				    		$sqlmail = "SELECT user.user_id, user.email, user.lastname, user.firstname
+								                     FROM $tbl_course_user, $tbl_user
+								                     WHERE course_code='".mysql_real_escape_string($_course['sysCode'])."'
+								                     AND course_rel_user.user_id = user.user_id";
+
+				    	}
+
+						if($sqlmail!=''){
+							$result = api_sql_query($sqlmail,__FILE__,__LINE__);
+
+					    	/*=================================================================================
+								    				send email one by one to avoid antispam
+						    =================================================================================*/
+
+
+							while ($myrow = mysql_fetch_array($result))
+							{
+								/*    Header : Bericht van uw lesgever - GES ($_cid)
+
+									  Body :   John Doe (prenom + nom) <john_doe@hotmail.com> (email)
+
+									  		   Morgen geen les!! (emailTitle)
+
+									  		   Morgen is er geen les, de les wordt geschrapt wegens vergadering (newContent)
+							    */
+
+								$emailsubjbericht = get_lang('professorMessage');
+								$emailSubject = $emailsubjbericht. " - ".$_course['official_code'];
+
+	                            $db_name = $_REQUEST['db_name'];
+
+
+
+	                            if($surveyid) {
+	                            	$newContentone=str_replace("#page#","choose_language.php",$newContent);
+									$newContenttwo=str_replace("#temp#",$template,$newContentone);
+									$newContentthree=str_replace("#sid#",$surveyid,$newContenttwo);
+									$newContentfour=str_replace("#mail#",$myrow["email"],$newContentthree);
+		                            $newContentfive=str_replace("#db_name#",$db_name,$newContentfour);
+									$newContentsix=str_replace("#uid#",$myrow["user_id"],$newContentfive);
+	                    			$message=stripslashes($newContentsix);
+
+								    $sender_name = $_SESSION['_user']['lastName'].' '.$_SESSION['_user']['firstName'];
+								    $email = $_SESSION['_user']['mail'];
+
+
+									$headers="From:$sender_name\r\nReply-to: $email\r\nContent-type: text/html; charset=iso-8859-15";
+									//@mail($myrow["email"],stripslashes($emailTitle),$message,$headers);
+									api_mail('',$myrow["email"],stripslashes($emailTitle),$message,$sender_name,$email);
+	                            }
+	                            else{
+									$mail_body = $myrow["lastname"]." ".$myrow["firstname"]." <".$myrow["email"]."><br /> \n\n".stripslashes($emailTitle)."<br />".trim(stripslashes($newContentsix))." <br /><br />-- <br />";
+									$mail_body .= $_user['firstName'].' '.$_user['lastName']." ";
+									$mail_body .= "<".$_user['mail'].">\n";
+									$mail_body .= $_course['official_code'].' '.$_course['name'];
+
+									//set the charset and use it for the encoding of the email - small fix, not really clean (should check the content encoding origin first)
+									//here we use the encoding used for the webpage where the text is encoded (ISO-8859-1 in this case)
+
+									//$to_email_address =$_POST['emailsAdd'];
+									//$mail_body;
+
+		                          	if(empty($charset)){$charset='ISO-8859-1';}
+									$encoding = 'Content-Type: text/html; charset='. $charset;
+			                        $mailid=$myrow["email"];
+
+									$newmail = api_mail($myrow["lastname"].' '.$myrow["firstname"], $myrow["email"],    $emailSubject, $mail_body, $_SESSION['_user']['lastName'].' '.$_SESSION['_user']['firstName'], $_SESSION['_user']['mail'],$encoding);
+	                            }
+								$sql_date="SELECT * FROM $db_name.survey WHERE survey_id='$surveyid'";
+								$res_date=api_sql_query($sql_date);
+								$obj_date=mysql_fetch_object($res_date);
+								$end_date=$obj_date->avail_till;
+								$table_reminder = Database :: get_main_table(MAIN_SURVEY_REMINDER_TABLE);
+								if($_REQUEST['reminder']=="1")
+								{
+									$time=getdate();
+									$time = $time['yday'];
+									$time = $time+7;
+									$sql="INSERT INTO $table_reminder(sid,db_name,email,subject,content,reminder_choice,reminder_time,avail_till) values('$surveyid','$db_name','$mailid','".addslashes($emailSubject)."','".addslashes($mail_body)."','1','$time','$end_date')";
+									api_sql_query($sql);
+								}
+								else if($_REQUEST['reminder']=="2")
+								{
+									$time=getdate();
+									$time = $time['yday'];
+									$time = $time+14;
+									$sql="INSERT INTO $table_reminder(sid,db_name,email,subject,content,reminder_choice,reminder_time,avail_till) values('$surveyid','$db_name','$mailid','".addslashes($emailSubject)."','".addslashes($mail_body)."','1','$time','$end_date')";
+									api_sql_query($sql);
+
+								}
+								else if($_REQUEST['reminder']=="3")
+								{
+									$time=getdate();
+									$time = $time['yday'];
+									$time = $time+30;
+									$sql="INSERT INTO $table_reminder(sid,db_name,email,subject,content,reminder_choice,reminder_time,avail_till) values('$surveyid','$db_name','$mailid','".addslashes($emailSubject)."','".addslashes($mail_body)."','1','$time','$end_date')";
+									api_sql_query($sql);
+								}
+
+
+
+							}
+
+							update_mail_sent($insert_id);
+							$message = $added_and_sent;
+						}
+
+					} // $email_ann*/
+
+				}	// isset
+
+
+			// UNSET VARIABLES
+
+				unset_session_resources();
+				unset($form_elements);
+				$_SESSION['formelements']=null;
+
+				$newContent = null;
+				$emailTitle = null;
+
+				unset($emailTitle);
+				unset($newContent);
+				unset($content_to_modify);
+				unset($title_to_modify);
+
+
+
+if($_REQUEST['publish_survey'])
+{
+
+ $surveyid=$_REQUEST['surveyid'];
+ $cidReq = $_REQUEST['cidReq'];
+ ?>
+<script>
+	window.location.href="../survey/survey_list.php?cidReq=<?php echo  $cidReq; ?>&published=published&surveyid=<?php echo $_REQUEST['publish_survey']; ?>";
+</script>
+<?php
+}
+
+	}	// if $submit Announcement
+
+
+
+
+
+  }
+
+}
+
+/*====================================================
+		     		Tool Title
+====================================================*/
+if ($_GET['origin'] !== 'learnpath')
+{
+	//api_display_tool_title($nameTools);
+	//Display::display_introduction_section(TOOL_ANNOUNCEMENT, $is_allowed);
+}
+
+/*
+==============================================================================
+		MAIN SECTION
+==============================================================================
+*/
+
+/*=====================================================================================
+                                          MAIN CODE     HTML
+=====================================================================================*/
+
+	// The commands below will change these display settings if they need it
+
+
+		if ($_GET['origin'] !== 'learnpath')
+		{
+			echo "\n\n<table width=\"100%\" border=\"0\" cellspacing=\"0\" cellpadding=\"0\">\n";
+			echo "\t<tr>\n";
+
+	    	echo "\t\t<td width=\"20%\" valign=\"top\">\n";
+		}
+      /*======================================================================
+                              DISPLAY LEFT COLUMN
+      ======================================================================*/
+		if(api_is_allowed_to_edit() OR api_get_course_setting('allow_user_edit_announcement')) // check teacher status
+		{
+	      	if ($_GET['origin'] !== 'learnpath')
+				{
+
+					$sql="SELECT
+							announcement.*, toolitemproperties.*
+							FROM $tbl_announcement announcement, $tbl_item_property toolitemproperties
+							WHERE announcement.id = toolitemproperties.ref
+							AND toolitemproperties.tool='announcement'
+							AND toolitemproperties.visibility<>'2'
+							GROUP BY toolitemproperties.ref
+							ORDER BY display_order DESC
+							LIMIT 0,$maximum";
+				}
+		}
+		else 	// students only get to see the visible announcements
+		{
+			if ($_GET['origin'] !== 'learnpath')
+				{
+					$group_memberships=GroupManager::get_group_ids($_course['dbName'], $_uid);
+
+					// the user is member of several groups => display personal announcements AND his group announcements AND the general announcements
+					if (is_array($group_memberships))
+					{
+						$sql="SELECT
+							announcement.*, toolitemproperties.*
+							FROM $tbl_announcement announcement, $tbl_item_property toolitemproperties
+							WHERE announcement.id = toolitemproperties.ref
+							AND toolitemproperties.tool='announcement'
+							AND toolitemproperties.visibility='1'
+							AND	( toolitemproperties.to_user_id=$_uid " .
+								"OR toolitemproperties.to_group_id IN (0, ".implode(", ", $group_memberships).") )
+							GROUP BY toolitemproperties.ref
+							ORDER BY display_order DESC
+							LIMIT 0,$maximum";
+					}
+					// the user is not member of any group
+					else
+					{
+						// this is an identified user => show the general announcements AND his personal announcements
+						if ($_uid)
+						{
+							$sql="SELECT
+								announcement.*, toolitemproperties.*
+								FROM $tbl_announcement announcement, $tbl_item_property toolitemproperties
+								WHERE announcement.id = toolitemproperties.ref
+								AND toolitemproperties.tool='announcement'
+								AND toolitemproperties.visibility='1'
+								AND ( toolitemproperties.to_user_id=$_uid OR toolitemproperties.to_group_id='0')
+								GROUP BY toolitemproperties.ref
+								ORDER BY display_order DESC
+								LIMIT 0,$maximum";
+						}
+						// the user is not identiefied => show only the general announcements
+						else
+						{
+							$sql="SELECT
+								announcement.*, toolitemproperties.*
+								FROM $tbl_announcement announcement, $tbl_item_property toolitemproperties
+								WHERE announcement.id = toolitemproperties.ref
+								AND toolitemproperties.tool='announcement'
+								AND toolitemproperties.visibility='1'
+								AND toolitemproperties.to_group_id='0'
+								GROUP BY toolitemproperties.ref
+								ORDER BY display_order DESC
+								LIMIT 0,$maximum";
+						}
+					}
+				}
+		}
+
+
+$result = api_sql_query($sql,__FILE__,__LINE__);
+
+$announcement_number = mysql_num_rows($result);
+
+/*----------------------------------------------------
+				ADD ANNOUNCEMENT / DELETE ALL
+----------------------------------------------------*/
+if(!$surveyid)
+{
+		if ((api_is_allowed_to_edit() OR api_get_course_setting('allow_user_edit_announcement')) and ($_GET['origin'] !== 'learnpath'))
+		{
+
+			echo "<a href='".$_SERVER['PHP_SELF']."?action=add&origin=".$_GET['origin']."'><img src=\"../img/valves_add.gif\"> ".get_lang("AddAnnouncement")."</a><br/>";
+			if ($announcement_number > 1)
+			{
+				echo "<a href=\"".$_SERVER['PHP_SELF']."?action=delete_all\" onclick=\"javascript:if(!confirm('".get_lang("ConfirmYourChoice")."')) return false;\"><img src=\"../img/valves_delete.gif\"/> ".get_lang("AnnouncementDeleteAll")."</a>\n";
+			}	// if announcementNumber > 1
+			echo "<hr noshade size=\"1\">";
+		}
+}
+
+/*----------------------------------------------------
+				ANNOUNCEMENTS LIST
+----------------------------------------------------*/
+if(!$surveyid)
+{
+	
+if ($display_title_list == true)
+{
+	echo "\t\t\t<table>\n";
+	while ($myrow = mysql_fetch_array($result))
+	{
+			$title = $myrow['title'];
+
+			echo "\t\t\t\t<tr>\n";
+			echo "\t\t\t\t\t<td width=\"15%\">\n";
+			if ($myrow['visibility']==0)
+				{ $class="class=\"invisible\"";}
+			else
+			{ $class="";}
+			echo "\t\t\t\t\t\t<a style=\"text-decoration:none\" href=\"announcements.php#".$myrow['id']."\" ".$class.">" . api_trunc_str($title,$length) . "</a>\n";
+			echo "\t\t\t\t\t</td>\n\t\t\t\t</tr>\n";
+	}
+	echo "\t\t\t</table>\n";
+} // end $display_title_list == true
+}
+
+if ($_GET['origin'] !== 'learnpath')
+{
+	echo   "\t\t</td>\n";
+	echo "\t\t<td width=\"20\" background=\"../img/verticalruler.gif\">&nbsp;</td>\n";
+	// START RIGHT PART
+	echo	"\t\t<td valign=\"top\">\n";
+}
+
+/*=======================================
+	        DISPLAY ACTION MESSAGE
+=======================================*/
+
+if ($message == true)
+{
+	Display::display_normal_message($message);
+	$display_announcement_list = true;
+	$display_form             = false;
+}
+
+/*==================================================================================
+		   						DISPLAY FORM
+==================================================================================*/
+
+
+	if ($display_form == true)
+	{
+
+		// DISPLAY ADD ANNOUNCEMENT COMMAND
+
+		echo "<form method=\"post\" name=\"f1\" action=\"".$_SERVER['PHP_SELF']."?publish_survey=$surveyid&id=$_GET[id]&db_name=$db_name&cidReq=$_GET[cidReq]&action=$_GET[action]\" style=\"margin:0px;\">\n";
+
+		//this variable defines if the course administrator can send a message to a specific user / group
+		// or not
+		//echo "sessiewaarde: ".$_SESSION['select_groupusers'];
+	if(empty($_SESSION['toolgroup'])){
+		if ($_SESSION['select_groupusers']=="hide")
+		{
+			echo "<table><tr><td>";
+			echo get_lang("SentTo").": ";
+			echo "</td><td>";
+			echo get_lang("Everybody");
+			echo "</td><td>";
+			echo "<input type=\"submit\" name=\"To\" value=\"".get_lang("SelectGroupsUsers")."\" style=\"float:left\">" ;
+			echo "</td></tr></table>";
+		}
+
+		if ($_SESSION['select_groupusers']=="show")
+		{
+			echo "<table><tr><td>";
+			echo get_lang("SentTo").": ";
+			echo "</td><td>";
+			echo get_lang('SelectedUsersGroups');
+			echo '</td><td>';
+			echo "<input type=\"submit\" name=\"To\" value=\"".get_lang("SelectEverybody")."\" style=\"float:left\">" ;
+			echo "</td></tr></table>";
+			show_to_form($to);
+		}
+
+		echo "<br /><br />";
+
+		if (!isset($announcement_to_modify) ) $announcement_to_modify ="";
+		if ($announcement_to_modify=='')
+		{
+			($email_ann=='1')?$checked='checked':$checked='';
+			echo "<input class=\"checkbox\" type=checkbox value=\"1\" name=\"email_ann\" $checked> ".get_lang('EmailOption')," : ",
+			"<br /><br />";
+		}
+	}else{
+			if (!isset($announcement_to_modify) ) $announcement_to_modify ="";
+			if ($announcement_to_modify=='')
+			{
+				($email_ann=='1' || !empty($surveyid))?$checked='checked':$checked='';
+				//echo "<input class=\"checkbox\" type=checkbox value=\"1\" name=\"email_ann\" $checked> ".get_lang('EmailOption')," : ".get_lang('MyGroup'),
+				"<br><br>";
+			}
+		}
+		if($surveyid){
+			echo	get_lang('EmailAddress').": <input type=\"text\" name=\"emailsAdd\" value=\"".$emails_add."\" size=\"52\">(Comma separated for multiple)<br>";
+			echo	get_lang('OnlyThoseAddresses').": <input type=\"checkbox\" name=\"onlyThoseMails\"><br>";
+		}
+		echo	get_lang('EmailTitle').": <input type=\"text\" name=\"emailTitle\" value=\"".$title_to_modify."\" size=\"52\"><br />";
+
+				unset($title_to_modify);
+		    	$title_to_modify = null;
+
+
+		if (!isset($announcement_to_modify) ) $announcement_to_modify ="";
+		if (!isset($content_to_modify) ) 		$content_to_modify ="";
+		if (!isset($title_to_modify)) 		$title_to_modify = "";
+
+	    echo	"<br />\n<input type=\"hidden\" name=\"id\" value=\"".$announcement_to_modify."\">";
+		if($surveyid){
+			$content_to_modify='<br /><a href="'.api_get_path(WEB_CODE_PATH).'/survey/#page#?temp=#temp#&surveyid=#sid#&uid=#uid#&mail=#mail#&db_name=#db_name">'.get_lang('ClickHereToOpenSurvey').'</a><br />
+											'.get_lang('OrCopyPasteUrl').' <br />
+											'.api_get_path(WEB_CODE_PATH).'/survey/#page#?temp=#temp#&surveyid=#sid#&uid=#uid#&mail=#mail#&db_name=#db_name&nbsp';
+		}
+	            api_disp_html_area('newContent',$content_to_modify,'250px');
+
+				  echo "<br /><table>",
+			           "<tr>",
+			           "<td colspan=7>";
+			            if ($_SESSION['select_groupusers']=="show")
+					   	{
+							show_addresource_button("onClick=\"selectAll(this.form.elements[4],true)\"");
+					   	}
+						else
+						{
+							show_addresource_button();
+						}
+
+					  // sessies
+					  $form_elements=$_SESSION['formelements'];
+
+					  echo "</td>",
+			               "</tr>";
+
+			          if ($_SESSION['addedresource']){
+			          	if(!$surveyid){
+				            echo "<tr>";
+				            echo "<td colspan='7'>";
+				            echo display_resources(0);
+				            $test=$_SESSION['addedresource'];
+				            echo "</td></tr>";
+			          	}
+			          }
+					  echo "</table>";
+
+		?>
+                <br /><input type="Submit" name="submitAnnouncement" value="<?php echo get_lang('Ok') ?>" onclick="selectAll(this.form.elements[4],true)" /><br /><br />
+
+        <?php
+
+				"</form><br />\n";
+    } // displayform
+
+
+
+/*===============================================
+	          DISPLAY ANNOUNCEMENT LIST
+===============================================*/
+
+
+	if ($display_announcement_list && !$surveyid)
+	{
+		// by default we use the id of the current user. The course administrator can see the announcement of other users by using the user / group filter
+		$user_id=$_uid;
+		if ($_SESSION['user']!==null)
+		{
+			$user_id=$_SESSION['user'];
+		}
+		if ($_SESSION['group']!==null)
+		{
+			$group_id=$_SESSION['group'];
+		}
+
+		//$group_memberships=GroupManager::get_group_ids($_course['dbName'], $_uid);
+		$group_memberships=GroupManager::get_group_ids($_course['dbName'],$_uid);
+
+		if (api_is_allowed_to_edit() OR api_get_course_setting('allow_user_edit_announcement'))
+		{
+			// A.1. you are a course admin with a USER filter
+			// => see only the messages of this specific user + the messages of the group (s)he is member of.
+
+			if ($_SESSION['user']!==null)
+			{
+				if (is_array($group_memberships))
+				{
+					$sql="SELECT
+						announcement.*, toolitemproperties.*
+						FROM $tbl_announcement announcement, $tbl_item_property toolitemproperties
+						WHERE announcement.id = toolitemproperties.ref
+						AND toolitemproperties.tool='announcement'
+						AND	(toolitemproperties.to_user_id=$user_id OR toolitemproperties.to_group_id IN (0, ".implode(", ", $group_memberships).") )
+						ORDER BY display_order DESC";
+
+				}
+				else
+				{
+					$sql="SELECT
+						announcement.*, toolitemproperties.*
+						FROM $tbl_announcement announcement, $tbl_item_property toolitemproperties
+						WHERE announcement.id = toolitemproperties.ref
+						AND toolitemproperties.tool='announcement'
+						AND (toolitemproperties.to_user_id=$user_id OR toolitemproperties.to_group_id='0')
+						AND toolitemproperties.visibility='1'
+						ORDER BY display_order DESC";
+
+				}
+			}
+
+			// A.2. you are a course admin with a GROUP filter
+			// => see only the messages of this specific group
+			elseif ($_SESSION['group']!==null)
+			{
+				$sql="SELECT
+					announcement.*, toolitemproperties.*
+					FROM $tbl_announcement announcement, $tbl_item_property toolitemproperties
+					WHERE announcement.id = toolitemproperties.ref
+					AND toolitemproperties.tool='announcement'
+					AND (toolitemproperties.to_group_id=$group_id OR toolitemproperties.to_group_id='0')
+					GROUP BY toolitemproperties.ref
+					ORDER BY display_order DESC";
+			}
+
+			// A.3 you are a course admin without any group or user filter
+			else
+			{
+				// A.3.a you are a course admin without user or group filter but WITH studentview
+				// => see all the messages of all the users and groups without editing possibilities
+
+				if ($isStudentView=="true")
+				{
+
+					$sql="SELECT
+						announcement.*, toolitemproperties.*
+						FROM $tbl_announcement announcement, $tbl_item_property toolitemproperties
+						WHERE announcement.id = toolitemproperties.ref
+						AND toolitemproperties.tool='announcement'
+						AND toolitemproperties.visibility='1'
+						GROUP BY toolitemproperties.ref
+						ORDER BY display_order DESC";
+				}
+
+				// A.3.a you are a course admin without user or group filter and WTIHOUT studentview (= the normal course admin view)
+				// => see all the messages of all the users and groups with editing possibilities
+				else
+				{
+					$sql="SELECT
+						announcement.*, toolitemproperties.*
+						FROM $tbl_announcement announcement, $tbl_item_property toolitemproperties
+						WHERE announcement.id = toolitemproperties.ref
+						AND toolitemproperties.tool='announcement'
+						AND (toolitemproperties.visibility='0' or toolitemproperties.visibility='1')
+						GROUP BY toolitemproperties.ref
+						ORDER BY display_order DESC";
+
+				}
+			}
+
+	}
+	else  //STUDENT
+	{
+		if (is_array($group_memberships))
+		{
+
+			$sql="SELECT
+				announcement.*, toolitemproperties.*
+				FROM $tbl_announcement announcement, $tbl_item_property toolitemproperties
+				WHERE announcement.id = toolitemproperties.ref
+				AND toolitemproperties.tool='announcement'
+				AND	(toolitemproperties.to_user_id=$user_id OR toolitemproperties.to_group_id IN (0, ".implode(", ", $group_memberships).") )
+				AND toolitemproperties.visibility='1'
+				ORDER BY display_order DESC";
+
+		}
+		else
+		{
+			if ($_uid)
+			{
+				$sql="SELECT
+					announcement.*, toolitemproperties.*
+					FROM $tbl_announcement announcement, $tbl_item_property toolitemproperties
+					WHERE announcement.id = toolitemproperties.ref
+					AND toolitemproperties.tool='announcement'
+					AND (toolitemproperties.to_user_id=$_uid OR toolitemproperties.to_group_id='0')
+					AND toolitemproperties.visibility='1'
+					ORDER BY display_order DESC";
+
+			}
+			else
+			{
+				$sql="SELECT
+					announcement.*, toolitemproperties.*
+					FROM $tbl_announcement announcement, $tbl_item_property toolitemproperties
+					WHERE announcement.id = toolitemproperties.ref
+					AND toolitemproperties.tool='announcement'
+					AND toolitemproperties.to_group_id='0'
+					AND toolitemproperties.visibility='1'";
+
+			}
+		}
+	}
+
+
+		$result = api_sql_query($sql,__FILE__,__LINE__);
+
+		$num_rows = mysql_num_rows($result);
+
+
+		/*=================================================
+		               DISPLAY: NO ITEMS
+ 		=================================================*/
+
+		if ($num_rows == 0)
+		{
+			echo "<table><tr><td>".get_lang('NoAnnouncements')."</td></tr></table>";
+		}
+
+		$iterator = 1;
+
+		$bottomAnnouncement = $announcement_number;
+
+
+		echo "\t\t\t<table width=\"100%\" border=\"1\" cellpadding=\"5\" cellspacing=\"0\"  id=\"agenda_list\">\n";
+
+		$displayed=array();
+
+		while ($myrow = mysql_fetch_array($result))
+		{
+			if (!in_array($myrow['id'], $displayed))
+			{
+				$title		 = $myrow['title'];
+				$content	 = $myrow['content'];
+
+				$content     = make_clickable($content);
+				$content     = text_filter($content);
+
+
+				/*================================================
+								       DATE
+				================================================*/
+
+				$last_post_datetime = $myrow['end_date'];
+
+				list($last_post_date, $last_post_time) = split(" ", $last_post_datetime);
+				list($year, $month, $day) = explode("-", $last_post_date);
+				list($hour, $min) = explode(":", $last_post_time);
+				$announceDate = mktime($hour, $min, 0, $month, $day, $year);
+
+				// the styles
+				if ($myrow['visibility']=='0')
+				{
+					$style="data_hidden";
+					$stylenotbold="datanotbold_hidden";
+					$text_style="text_hidden";
+				}
+				else
+				{
+					$style="data";
+					$stylenotbold="datanotbold";
+					$text_style="text";
+				}
+
+				echo	"\t\t\t\t<tr class=\"".$style."\">";
+
+
+				/*===================================================================
+											THE ICONS
+				===================================================================*/
+				echo "\t\t\t\t\t<td>\n";
+				// anchoring
+				echo "<a name=\"".(int)($myrow["id"])."\"></a>\n";
+				// User or group icon
+				if ($myrow['to_group_id']!== '0' and $myrow['to_group_id']!== 'NULL')
+				{
+					echo "\t\t\t\t\t\t<img alt=\"$alt_ug\" src='../img/group.gif'>\n";
+				}
+				// the email icon
+				if ($myrow['email_sent'] == '1')
+				{
+					echo "\t\t\t\t\t\t<img alt=\"$alt_mail\" src='../img/email.png'>\n";
+				}
+				echo "\t\t\t\t\t</td>\n";
+				/*==================================================================
+											TITLE
+				==================================================================*/
+
+				echo "\t\t\t\t\t<td>".$title."</td>\n";
+
+
+				/*==================================================================
+											SENT TO
+				===================================================================*/
+
+				echo "\t\t\t\t\t<td class=\"".$stylenotbold."\">" . get_lang("SentTo") . " : &nbsp; ";
+				$sent_to=sent_to("announcement", $myrow['id']);
+				// echo $myrow['id'];
+
+				$sent_to_form=sent_to_form($sent_to);
+				echo $sent_to_form,
+
+				"\t\t\t\t\t</td>\n",
+				"\t\t\t\t</tr>\n";
+
+
+				/*=========================================================
+											TITLE
+				=========================================================*/
+				echo "\t\t\t\t<tr>\n",
+				"\t\t\t\t\t<td class=\"announcements_datum\" colspan=\"3\">",
+
+				get_lang('AnnouncementPublishedOn')," : ",ucfirst(format_locale_date($dateFormatLong,strtotime($last_post_date))),
+
+
+
+				"</td>\n",
+				"\t\t\t\t</tr>\n",
+
+
+				/*=========================================================
+										CONTENT
+				=========================================================*/
+
+				"\t\t\t\t<tr class=\"$text_style\">\n",
+				"\t\t\t\t\t<td colspan=\"3\">\n",
+
+				$content,
+
+				"\t\t\t\t\t</td>\n",
+				"\t\t\t\t</tr>\n",
+
+
+				/*========================================================
+										RESOURCES
+				========================================================*/
+
+				"<tr>\n",
+				"<td colspan=\"3\">\n";
+
+
+				if (check_added_resources("Ad_Valvas", $myrow["id"]))
+				{
+					echo "<i>".get_lang('AddedResources')."</i><br />";
+					display_added_resources("Ad_Valvas", $myrow["id"]);
+				}
+
+				echo   "<br />";
+
+
+				if(api_is_allowed_to_edit())
+				{
+					/*=====================================================================
+												SHOW MOD/DEL/VIS FUNCTIONS
+					=====================================================================*/
+					echo "<table><tr>";
+					echo	"<td valign=\"top\"><a href=\"".$_SERVER['PHP_SELF']."?action=modify&id=".$myrow['id']."\">",
+							"<img src=\"../img/edit.gif\" title=\"",get_lang('Modify'),"\" border=\"0\" align=\"absmiddle\">",
+							"</a></td>";
+
+
+					if (api_is_allowed_to_edit()) echo "<td valign=\"top\"><a href=\"".$_SERVER['PHP_SELF']."?action=delete&id=".$myrow['id']."\" onclick=\"javascript:if(!confirm('".addslashes(htmlentities(get_lang('ConfirmYourChoice')))."')) return false;\">",
+							"<img src=\"../img/delete.gif\" title=\"",get_lang('Delete'),"\" border=\"0\" align=\"absmiddle\">",
+							"</a></td>";
+
+							if ($myrow['visibility']==1)
+							{
+									$image_visibility="visible";
+							}
+							else
+							{
+									$image_visibility="invisible";
+							}
+
+							echo 	"<td valign=\"top\"><a href=\"".$_SERVER['PHP_SELF']."?origin=".$_GET['origin']."&action=showhide&id=".$myrow['id']."\">",
+									"<img src=\"../img/".$image_visibility.".gif\" border=\"0\" alt=\"".get_lang('Visible')."\"/></a></td>";
+
+
+
+
+							// DISPLAY MOVE UP COMMAND only if it is not the top announcement
+							if($iterator != 1)
+							{
+
+							echo	"<td valign=\"top\"><a href=\"".$_SERVER['PHP_SELF']."?up=",$myrow["id"],"\">",
+									"<img src=../img/up.gif border=0 title=\"".get_lang('Up')."\" align=\"absmiddle\">",
+									"</a></td>";
+							}
+
+
+							if($iterator < $bottomAnnouncement)
+							{
+
+							echo	"<td valign=\"top\"><a href=\"".$_SERVER['PHP_SELF']."?down=".$myrow["id"]."\">",
+									"<img src=\"../img/down.gif\" border=\"0\" title=\"".get_lang('Down')."\" align=\"absmiddle\">",
+									"</a></td>";
+							}
+
+							echo "</tr></table>";
+
+
+
+					echo	"</td>\n",
+							"</tr>\n";
+
+					$iterator ++;
+				} // is_allowed_to_edit
+
+				echo "<tr><td width=\"100%\" colspan=\"3\"><a href=\"#top\"><img src=\"../img/top.gif\" border=\"0\" alt=\"To top\" align=\"right\"></a></td></tr>";
+			}
+			$displayed[]=$myrow['id'];
+		}	// end while ($myrow = mysql_fetch_array($result))
+
+		echo "</table>";
+
+}	// end: if ($displayAnnoucementList)
+
+echo "</table>";
+
+if ($display_specific_announcement) display_announcement($announcement_id);
+
+/*
+==============================================================================
+		FOOTER
+==============================================================================
+*/
+if ($_GET['origin'] !== 'learnpath')
+{
+	//we are not in learnpath tool
+	Display::display_footer();
+}
+?>

+ 7 - 0
main/announcements/index.html

@@ -0,0 +1,7 @@
+<html>
+<head>
+<meta http-equiv="refresh" content="0; url=announcements.php">
+</head>
+<body>
+</body>
+</html>

+ 1110 - 0
main/auth/courses.php

@@ -0,0 +1,1110 @@
+<?php // $Id: courses.php 9721 2006-10-25 08:23:18Z grayd0n $
+/*
+==============================================================================
+	Dokeos - elearning and course management software
+
+	Copyright (c) 2004 Dokeos S.A.
+	Copyright (c) 2003 Ghent University (UGent)
+	Copyright (c) 2001 Universite catholique de Louvain (UCL)
+	Copyright (c) various contributors
+
+	For a full list of contributors, see "credits.txt".
+	The full license can be read in "license.txt".
+
+	This program is free software; you can redistribute it and/or
+	modify it under the terms of the GNU General Public License
+	as published by the Free Software Foundation; either version 2
+	of the License, or (at your option) any later version.
+
+	See the GNU General Public License for more details.
+
+	Contact: Dokeos, 181 rue Royale, B-1000 Brussels, Belgium, info@dokeos.com
+==============================================================================
+*/
+/**
+==============================================================================
+*	@package dokeos.auth
+*	@todo check if unsubscribing from a course WITH group memberships works as it should
+*	@todo constants are in uppercase, variables aren't
+==============================================================================
+*/
+
+/*
+==============================================================================
+		INIT SECTION
+==============================================================================
+*/
+// including the relevant language file
+$langFile = 'courses';
+
+// including the global file
+include('../inc/global.inc.php');
+$this_section=SECTION_COURSES;
+
+api_block_anonymous_users();
+
+/*
+-----------------------------------------------------------
+	Libraries
+-----------------------------------------------------------
+*/
+include_once(api_get_path(LIBRARY_PATH) . 'debug.lib.inc.php');
+include_once(api_get_path(LIBRARY_PATH) . 'course.lib.php');
+
+/*
+-----------------------------------------------------------
+	Variables
+-----------------------------------------------------------
+*/
+$tbl_course             = Database::get_main_table(MAIN_COURSE_TABLE);
+$tbl_courses_nodes      = Database::get_main_table(MAIN_CATEGORY_TABLE);
+$tbl_courseUser         = Database::get_main_table(MAIN_COURSE_USER_TABLE);
+$tbl_user               = Database::get_main_table(MAIN_USER_TABLE);
+
+/*
+-----------------------------------------------------------
+	Header
+-----------------------------------------------------------
+*/
+
+// title of the page
+$nameTools= get_lang('CourseManagement');
+
+
+
+Display::display_header($nameTools);
+api_display_tool_title($nameTools);
+
+/*
+==============================================================================
+		COMMANDS SECTION
+==============================================================================
+*/
+$userId = $_uid;
+unset($message);
+// we are moving a course or category of the user up/down the list (=Sort My Courses)
+if (isset($_GET['move']))
+{
+	if (isset($_GET['course']))
+	{
+		$message=move_course($_GET['move'], $_GET['course'],$_GET['category']);
+	}
+	if (isset($_GET['category']) and !$_GET['course'])
+	{
+		$message=move_category($_GET['move'], $_GET['category']);
+	}
+}
+
+// we are moving the course of the user to a different user defined course category (=Sort My Courses)
+if (isset($_POST['submit_change_course_category']))
+{
+	$message=store_changecoursecategory($_POST['course_2_edit_category'], $_POST['course_categories']);
+}
+// we are creating a new user defined course category (= Create Course Category)
+if (isset($_POST['create_course_category']) AND isset($_POST['title_course_category']) AND strlen(trim($_POST['title_course_category'])) > 0)
+{
+	$message=store_course_category();
+}
+
+if (isset($_POST['submit_edit_course_category']) AND isset($_POST['title_course_category']) AND strlen(trim($_POST['title_course_category'])) > 0)
+{
+	$message=store_edit_course_category();
+}
+
+// we are subcribing to a course (=Subscribe to course)
+if (isset($_POST['subscribe']))
+{
+	$message = subscribe_user($_POST['subscribe']);
+}
+
+// we are unsubscribing from a course (=Unsubscribe from course)
+if (isset($_POST['unsubscribe']))
+{
+	$message=remove_user_from_course($_uid, $_POST['unsubscribe']);
+}
+// we are deleting a course category
+if ($_GET['action']=='deletecoursecategory' AND isset($_GET['id']))
+{
+	$message=delete_course_category($_GET['id']);
+}
+
+// we are displaying any result messages;
+if (isset($message))
+{
+	Display::display_normal_message($message);
+}
+
+/*
+==============================================================================
+					DISPLAY SECTION
+==============================================================================
+*/
+// The menu with the different options in the course management
+echo "<div>\n";
+echo "\t<ul>\n";
+echo "\t\t<li><a href=\"".$_SERVER['PHP_SELF']."?action=sortmycourses\">".get_lang("SortMyCourses")."</a></li>\n";
+echo "\t\t<li><a href=\"".$_SERVER['PHP_SELF']."?action=createcoursecategory\">".get_lang("CreateCourseCategory")."</a></li>\n";
+echo "\t\t<li><a href=\"".$_SERVER['PHP_SELF']."?action=subscribe\">".get_lang("SubscribeToCourse")."</a></li>\n";
+echo "\t</ul>\n";
+echo "</div>";
+
+echo "<div>";
+switch ($_GET['action'])
+{
+	case 'subscribe':
+		api_display_tool_title(get_lang('SubscribeToCourse'));
+		courses_subscribing();
+		break;
+	case 'unsubscribe':
+		api_display_tool_title(get_lang('UnsubscribeFromCourse'));
+		$user_courses=get_courses_of_user($_uid);
+		display_courses($_uid, true, $user_courses);
+		break;
+	case 'createcoursecategory':
+		api_display_tool_title(get_lang('CreateCourseCategory'));
+		display_create_course_category_form();
+		break;
+	case 'deletecoursecategory':
+	case 'sortmycourses':
+	default:
+		api_display_tool_title(get_lang('SortMyCourses'));
+		$user_courses=get_courses_of_user($_uid);
+		display_courses($_uid, true, $user_courses);
+		break;
+}
+echo '</div>';
+Display :: display_footer();
+
+
+
+
+
+
+
+
+/*
+==============================================================================
+		FUNCTIONS
+==============================================================================
+*/
+ /**
+  * Subscribe the user to a given course
+  * @author Patrick Cool <patrick.cool@UGent.be>, Ghent University
+  * @param string $course_code the code of the course the user wants to subscribe to
+  * @return string we return the message that is displayed when the action is succesfull
+ */
+function subscribe_user($course_code)
+{
+	global $_uid;
+
+	$all_course_information =  CourseManager::get_course_information($course_code);
+
+	if ($all_course_information['registration_code']=='' OR $_POST['course_registration_code']==$all_course_information['registration_code'])
+	{
+		if (CourseManager::add_user_to_course($_uid, $course_code))
+		{
+			return get_lang('EnrollToCourseSuccessful');
+		}
+		else
+		{
+			return get_lang('ErrorContactPlatformAdmin');
+		}
+	}
+	else
+	{
+		$return='';
+		if (isset($_POST['course_registration_code']) AND $_POST['course_registration_code']<>$all_course_information['registration_code'])
+		{
+			Display::display_error_message(get_lang('CourseRegistrationCodeIncorrect'));
+		}
+		$return.=get_lang('CourseRequiresPassword').'<br/>';
+		$return.=$all_course_information['visual_code'].' - '.$all_course_information['title'];
+
+		$return.="<form action=\"".$_SERVER["REQUEST_URI"]."\" method=\"post\">";
+		$return.="<input type=\"hidden\" name=\"subscribe\" value=\"".$all_course_information['code']."\" />";
+		$return.="<input type=\"text\" name=\"course_registration_code\" value=\"".$_POST['course_registration_code']."\" />";
+		$return.="<input type=\"Submit\" name=\"submit_course_registration_code\" value=\"OK\" alt=\"".get_lang("SubmitRegistrationCode")."\" /></form>";
+		return $return;
+	}
+}
+/**
+ * unsubscribe the user from a given course
+ * @author Patrick Cool <patrick.cool@UGent.be>, Ghent University
+ * @param int $user_id The user id of the user that is performing the unsubscribe action
+ * @param string $course_code the course code of the course the user wants to unsubscribe from
+ * @return string we return the message that is displayed when the action is succesfull
+*/
+function remove_user_from_course($user_id, $course_code)
+{
+	$tbl_course_user         = Database::get_main_table(MAIN_COURSE_USER_TABLE);
+
+	// we check (once again) if the user is not course administrator
+	// because the course administrator cannot unsubscribe himself
+	// (s)he can only delete the course
+	$sql_check="SELECT * FROM $tbl_course_user WHERE user_id='".$user_id."' AND course_code='".$course_code."' AND status='1'";
+	$result_check=api_sql_query($sql_check);
+	$number_of_rows=mysql_num_rows($result_check);
+
+	if ($number_of_rows>0)
+	{return false;}
+	else
+	{
+		CourseManager::unsubscribe_user($user_id,$course_code);
+		return get_lang("YouAreNowUnsubscribed");
+	}
+}
+
+
+/**
+ * handles the display of the courses to which the user can subscribe
+ * @author Patrick Cool <patrick.cool@UGent.be>, Ghent University
+*/
+function courses_subscribing()
+{
+	browse_courses();
+	display_search_courses();
+}
+
+/**
+ * allows you to browse through the course categories (faculties) and subscribe to the courses of
+ * this category (faculty)
+ * @author Patrick Cool <patrick.cool@UGent.be>, Ghent University
+*/
+function browse_courses()
+{
+	browse_course_categories();
+	if (!isset($_POST['search_course']))
+		{
+		browse_courses_in_category();
+		}
+}
+
+/**
+ * counts the number of courses in a given course category
+*/
+function count_courses_in_category($category)
+{
+	$tbl_course         = Database::get_main_table(MAIN_COURSE_TABLE);
+	$sql="SELECT * FROM $tbl_course WHERE category_code".(empty($category)?" IS NULL":"='".$category."'");
+	$result=api_sql_query($sql);
+	return mysql_num_rows($result);
+}
+
+
+/**
+ * displays the browsing of the course categories (faculties)
+ * @author Patrick Cool <patrick.cool@UGent.be>, Ghent University
+ * @return HTML code containing a list with all the categories and subcategories and the navigation to go one category up(if needed)
+*/
+function browse_course_categories()
+{
+	$tbl_courses_nodes      = Database::get_main_table(MAIN_CATEGORY_TABLE);
+
+	echo "<p><b>".get_lang('CourseCategories')."</b>";
+
+	$sql= "SELECT * FROM $tbl_courses_nodes WHERE parent_id ".(empty($_GET['category'])?"IS NULL":"='".$_GET['category']."'")." GROUP BY code, parent_id  ORDER BY tree_pos ASC";
+	$result=mysql_query($sql);
+	echo "<ul>";
+	while ($row=mysql_fetch_array($result))
+	{
+		if ($row['children_count'] > 0 OR count_courses_in_category($row['code'])>0)
+		{
+			echo	"<li><a href=\"".$_SERVER['PHP_SELF']."?action=subscribe&amp;category=".$row['code']."&amp;up=".$_GET['category']."\">".$row['name']."</a>".
+				" (".count_courses_in_category($row['code']).")</li>";
+		}
+		elseif ($row['nbChilds'] > 0)
+		{
+			echo	"<li><a href=\"".$_SERVER['PHP_SELF']."?action=subscribe&amp;category=".$row['code']."&amp;up=".$_GET['category']."\">".$row['name']."</a></li>";
+		}
+		else
+		{
+			echo "<li>".$row['name']."</li>";
+		}
+
+	}
+	echo "</ul>";
+	if ($_GET['category'])
+	{
+		echo "<a href=\"".$_SERVER['PHP_SELF']."?action=subscribe&amp;category=".$_GET['up']."\">&lt; ".get_lang('UpOneCategory')."</a>";
+	}
+}
+
+/**
+ * Display all the courses in the given course category. I could have used a parameter here
+ * but instead I use the already available $_GET['category']
+ * @author Patrick Cool <patrick.cool@UGent.be>, Ghent University
+ * @return HTML code: a table with all the courses in a given category (title, code, tutor) and a subscription icon if applicable)
+*/
+function browse_courses_in_category()
+{
+	$tbl_course         = Database::get_main_table(MAIN_COURSE_TABLE);
+
+
+	echo "<p><b>".get_lang('CoursesInCategory')."</b>";
+
+	$sql="SELECT * FROM $tbl_course WHERE category_code".(empty($_GET['category'])?" IS NULL":"='".$_GET['category']."'");
+	$result=api_sql_query($sql);
+	while ($row=mysql_fetch_array($result))
+	{
+		if ($row['registration_code']=='')
+		{
+			$registration_code=false;
+		}
+		else
+		{
+			$registration_code=true;
+		}
+		$courses[]=array("code" => $row['code'], "directory" => $row['directory'], "db"=> $row['db_name'], "visual_code" => $row['visual_code'], "title" => $row['title'], "tutor" => $row['tutor_name'], "subscribe" => $row['subscribe'], "unsubscribe" => $row['unsubscribe'], 'registration_code'=> $registration_code);
+	}
+	display_subscribe_to_courses($courses);
+}
+
+
+/**
+ * displays the form for searching for a course and the results if a query has been submitted.
+ * @author Patrick Cool <patrick.cool@UGent.be>, Ghent University
+ * @return HTML code: the form for searching for a course
+*/
+function display_search_courses()
+{
+	global $_uid;
+	echo "<p><b>".get_lang("SearchCourse")."</b><br />";
+	echo "<form class=\"course_list\" method=\"post\" action=\"".$_SERVER['PHP_SELF']."?action=subscribe\">",
+					"<input type=\"hidden\" name=\"search_course\" value=\"1\" />",
+					"<input type=\"text\" name=\"search_term\" />",
+					"&nbsp;<input type=\"submit\" value=\"",get_lang("_search"),"\" />",
+					"</form>";
+	if (isset($_POST['search_course']))
+		{
+		echo "<p><b>".get_lang("SearchResultsFor")." ".$_POST['search_term']."</b><br />";
+		$result_search_courses_array=search_courses($_POST['search_term']);
+		display_subscribe_to_courses($result_search_courses_array);
+		}
+}
+
+/**
+ * This function displays the list of course that can be subscribed to.
+ * This list can come from the search results or from the browsing of the platform course categories
+*/
+function display_subscribe_to_courses($courses)
+{
+
+	global $_uid;
+	// getting all the courses to which the user is subscribed to
+	$user_courses=get_courses_of_user($_uid);
+	$user_coursecodes=array();
+
+	// we need only the course codes as these will be used to match against the courses of the category
+	if ($user_courses<>"")
+	{
+		foreach ($user_courses as $key=>$value)
+		{
+			$user_coursecodes[]=$value['code'];
+		}
+	}
+
+	if ($courses==0)
+		{
+			return false;
+		}
+
+	echo "<table cellpadding=\"4\">\n";
+	foreach ($courses as $key=>$course)
+	{
+		// displaying the course title, visual code and teacher/teaching staff
+		echo "\t<tr>\n";
+		echo "\t\t<td>\n";
+		echo "<b>".$course['title']."</b><br />";
+		if (get_setting("display_coursecode_in_courselist") == "true")
+		{
+			echo $course['visual_code'];
+		}
+		if (get_setting("display_coursecode_in_courselist") == "true" AND get_setting("display_teacher_in_courselist") == "true")
+		{
+			echo " - ";
+		}
+		if (get_setting("display_teacher_in_courselist") == "true")
+		{
+			echo $course['tutor'];
+		}
+		echo "\t\t</td>\n";
+
+		echo "\t\t<td>\n";
+		if ($course['registration_code'])
+		{
+			Display::display_icon('passwordprotected.png','',array('style'=>'float:left;'));
+		}
+		display_subscribe_icon($course, $user_coursecodes);
+		echo "\t\t</td>\n";
+
+		echo "</tr>";
+
+	}
+	echo "</table>";
+}
+
+
+/**
+ * This function filters dangerous stuff out. It does addslashes when the php.ini setting
+ * magic_quotes is set to off.
+ * @author Olivier Cauberghe <olivier.cauberghe@UGent.be>, Ghent University
+ * @param string something that possibly needs addslashing
+ * @return string the addslahed version of the input
+*/
+function escape($s)
+{
+    if(!get_magic_quotes_gpc())
+    return addslashes($s);
+    else return $s;
+}
+
+
+/**
+ * Search the courses database for a course that matches the search term.
+ * The search is done on the code, title and tutor field of the course table.
+ * @author Patrick Cool <patrick.cool@UGent.be>, Ghent University
+ * @param string $search_term: the string that the user submitted, what we are looking for
+ * @return array an array containing a list of all the courses (the code, directory, dabase, visual_code, title, ... )
+ * 			matching the the search term.
+*/
+function search_courses($search_term)
+{
+	$TABLECOURS = Database::get_main_table(MAIN_COURSE_TABLE);
+
+	$search_term_safe=escape($search_term);
+
+	$sql_find="SELECT * FROM $TABLECOURS WHERE code LIKE '%".$search_term_safe."%' OR title LIKE '%".$search_term_safe."%' OR tutor_name LIKE '%".$search_term_safe."%'";
+	$result_find=mysql_query($sql_find) or die(mysql_error());
+
+	while ($row=mysql_fetch_array($result_find))
+		{
+		$courses[]=array("code" => $row['code'], "directory" => $row['directory'], "db"=> $row['db_name'], "visual_code" => $row['visual_code'], "title" => $row['title'], "tutor" => $row['tutor_name'], "subscribe" => $row['subscribe'], "unsubscribe" => $row['unsubscribe']);
+		}
+	return $courses;
+}
+
+
+/**
+ * deletes a course category and moves all the courses that were in this category to main category
+ * @author Patrick Cool <patrick.cool@UGent.be>, Ghent University
+ * @param int $id: the id of the user_course_category
+ * @return string a language variable saying that the deletion went OK.
+*/
+function delete_course_category($id)
+{
+	global $_uid, $user_personal_database;
+
+	$DATABASE_USER_TOOLS = $user_personal_database;
+	$TABLE_USER_COURSE_CATEGORY = $DATABASE_USER_TOOLS."`.`user_course_category";
+	$TABLECOURSUSER=Database::get_main_table(MAIN_COURSE_USER_TABLE);
+
+	$sql_delete="DELETE FROM `$TABLE_USER_COURSE_CATEGORY` WHERE id='".$id."' and user_id='".$_uid."'";
+	$sql_update="UPDATE $TABLECOURSUSER SET user_course_cat='0' WHERE user_course_cat='".$id."' AND user_id='".$_uid."'";
+	mysql_query($sql_delete) or die(mysql_error());
+	mysql_query($sql_update) or die(mysql_error());
+
+	return get_lang("CourseCategoryDeleted");
+}
+
+
+/**
+ * stores the user course category in the dokeos_user database
+ * @author Patrick Cool <patrick.cool@UGent.be>, Ghent University
+ * @return string a language variable saying that the user course category was stored
+*/
+function store_course_category()
+{
+	global $_uid, $user_personal_database;
+
+	$DATABASE_USER_TOOLS = $user_personal_database;
+	$TABLE_USER_COURSE_CATEGORY = $DATABASE_USER_TOOLS."`.`user_course_category";
+
+	// step 1: we determine the max value of the user defined course categories
+	$sql="SELECT sort FROM `$TABLE_USER_COURSE_CATEGORY` WHERE user_id='".$_uid."' ORDER BY sort DESC";
+	$result=api_sql_query($sql);
+	$maxsort=mysql_fetch_array($result);
+	$nextsort=$maxsort['sort']+1;
+
+
+	$sql_insert="INSERT INTO `$TABLE_USER_COURSE_CATEGORY` (user_id, title,sort) VALUES ('".$_uid."', '".htmlentities($_POST['title_course_category'])."', '".$nextsort."')";
+	api_sql_query($sql_insert);
+	return get_lang("CourseCategoryStored");
+}
+
+
+/**
+ * displays the form that is needed to create a course category.
+ * @author Patrick Cool <patrick.cool@UGent.be>, Ghent University
+ * @return HTML the form (input field + submit button) to create a user course category
+*/
+function display_create_course_category_form()
+{
+	global $_uid, $user_personal_database;
+
+	echo "<form name=\"create_course_category\" method=\"post\" action=\"".$_SERVER['PHP_SELF']."?action=sortmycourses\">\n";
+	echo "<input type=\"text\" name=\"title_course_category\" />\n";
+	echo "<input type=\"submit\" name=\"create_course_category\" value=\"".get_lang("Ok")."\" />\n";
+	echo "</form>\n";
+
+	echo get_lang("ExistingCourseCategories");
+	$DATABASE_USER_TOOLS = $user_personal_database;
+	$TABLE_USER_COURSE_CATEGORY = $DATABASE_USER_TOOLS."`.`user_course_category";
+	$sql="SELECT * FROM `$TABLE_USER_COURSE_CATEGORY` WHERE user_id='".$_uid."'";
+	$result=api_sql_query($sql, __LINE__, __FILE__);
+	if (mysql_num_rows($result)>0)
+	{
+		echo "<ul>\n";
+		while ($row=mysql_fetch_array($result))
+		{
+			echo "\t<li>".$row['title']."</li>\n";
+		}
+		echo "</ul>\n";
+	}
+}
+// ***************************************************************************
+// this function stores the changes in a course category
+//
+// ***************************************************************************
+
+/**
+ * stores the changes in a course category (moving a course to a different course category)
+ * @author Patrick Cool <patrick.cool@UGent.be>, Ghent University
+ * @param string $course_code : the course_code of the course we are moving
+ *		  int $newcategory : the id of the user course category we are moving the course to.
+ * @return string a language variable saying that the course was moved.
+*/
+function store_changecoursecategory($course_code, $newcategory)
+{
+	global $_uid;
+	$TABLECOURSUSER = Database::get_main_table(MAIN_COURSE_USER_TABLE);
+
+	$max_sort_value=api_max_sort_value($newcategory,$_uid); //max_sort_value($newcategory);
+
+	$sql="UPDATE $TABLECOURSUSER SET user_course_cat='".$newcategory."', sort='".($max_sort_value+1)."' WHERE course_code='".$course_code."' AND user_id='".$_uid."'";
+	$result=api_sql_query($sql);
+	return get_lang("EditCourseCategorySucces");
+}
+/**
+ * moves the course one place up or down
+ * @author Patrick Cool <patrick.cool@UGent.be>, Ghent University
+ * @param string $direction : the direction we are moving the course to (up or down)
+ *		  string $course2move : the course we are moving
+ * @return string a language variable saying that the course was moved.
+*/
+function move_course($direction, $course2move, $category)
+{
+	global $_uid;
+	$TABLECOURSUSER = Database::get_main_table(MAIN_COURSE_USER_TABLE);
+
+	$all_user_courses=get_courses_of_user($_uid);
+
+	// we need only the courses of the category we are moving in
+	foreach ($all_user_courses as $key=>$course)
+	{
+		if ($course['user_course_category']==$category)
+		{
+			$user_courses[]=$course;
+		}
+	}
+
+
+
+
+	foreach ($user_courses as $key=>$course)
+	{
+		if ($course2move==$course['code'])
+		{
+			// source_course is the course where we clicked the up or down icon
+			$source_course=$course;
+			// target_course is the course before/after the source_course (depending on the up/down icon)
+			if ($direction=="up")
+				{$target_course=$user_courses[$key-1];}
+			else
+				{$target_course=$user_courses[$key+1];}
+		} // if ($course2move==$course['code'])
+	}
+
+	$sql_update1="UPDATE $TABLECOURSUSER SET sort='".$target_course['sort']."' WHERE course_code='".$source_course['code']."' AND user_id='".$_uid."'";
+	$sql_update2="UPDATE $TABLECOURSUSER SET sort='".$source_course['sort']."' WHERE course_code='".$target_course['code']."' AND user_id='".$_uid."'";
+	mysql_query($sql_update2);
+	mysql_query($sql_update1);
+	return get_lang("CourseSortingDone");
+}
+
+
+/**
+ * moves the course one place up or down
+ * @author Patrick Cool <patrick.cool@UGent.be>, Ghent University
+ * @param string $direction : the direction we are moving the course to (up or down)
+ *		  string $course2move : the course we are moving
+ * @return string a language variable saying that the course was moved.
+*/
+function move_category($direction, $category2move)
+{
+	global $_uid;
+	// the database definition of the table that stores the user defined course categories
+	$table_user_defined_category = Database::get_user_personal_table(USER_COURSE_CATEGORY_TABLE);
+
+	$user_coursecategories=get_user_course_categories();
+
+
+	foreach ($user_coursecategories as $key=>$categoryid)
+		{
+		if ($category2move==$categoryid)
+			{
+			// source_course is the course where we clicked the up or down icon
+			$source_category=get_user_course_category($category2move);
+			// target_course is the course before/after the source_course (depending on the up/down icon)
+			if ($direction=="up")
+				{$target_category=get_user_course_category($user_coursecategories[$key-1]);}
+			else
+				{$target_category=get_user_course_category($user_coursecategories[$key+1]);}
+			 } // if ($course2move==$course['code'])
+		} // foreach ($user_courses as $key=>$course)
+
+	$sql_update1="UPDATE $table_user_defined_category SET sort='".$target_category['sort']."' WHERE id='".$source_category['id']."' AND user_id='".$_uid."'";
+	$sql_update2="UPDATE $table_user_defined_category SET sort='".$source_category['sort']."' WHERE id='".$target_category['id']."' AND user_id='".$_uid."'";
+	mysql_query($sql_update2);
+	mysql_query($sql_update1);
+	return get_lang("CategorySortingDone");
+}
+
+/**
+ * displays everything that is needed when the user wants to manage his current courses (sorting, subscribing, unsubscribing, ...)
+ * @author Patrick Cool <patrick.cool@UGent.be>, Ghent University
+ * @param int $user_id: the user_id of the current user
+ *		  string $parameter: determines weither we are displaying for the sorting, subscribing or unsubscribin
+ 		  array $user_courses:  the courses to which the user is subscribed
+ * @return html a table containing courses and the appropriate icons (sub/unsub/move)
+*/
+
+function display_courses($user_id, $show_course_icons, $user_courses)
+{
+	global $_uid, $user_personal_database;
+
+	echo "<table cellpadding=\"4\">\n";
+
+	// building an array that contains all the id's of the user defined course categories
+	// initially this was inside the display_courses_in_category function but when we do it here we have fewer
+	// sql executions = performance increase.
+	$all_user_categories=get_user_course_categories();
+
+	// step 0: we display the course without a user category
+	display_courses_in_category(0,'true');
+
+	// Step 1: we get all the categories of the user
+	$DATABASE_USER_TOOLS = $user_personal_database;
+	$TABLE_USER_COURSE_CATEGORY = $DATABASE_USER_TOOLS."`.`user_course_category";
+	$sql="SELECT * FROM `$TABLE_USER_COURSE_CATEGORY` WHERE user_id=$_uid ORDER BY sort ASC";
+	$result=api_sql_query($sql);
+	while ($row=mysql_fetch_array($result))
+	{
+		if ($show_course_icons=true)
+		{
+
+			// the edit link is clicked: we display the edit form for the category
+			if (isset($_GET['categoryid']) AND $_GET['categoryid']==$row['id'])
+			{
+				echo "<tr><td colspan=\"2\"  class=\"user_course_category\">";
+				echo '<a name="category'.$row['id'].'"></a>'; // display an internal anchor.
+				display_edit_course_category_form($row['id']);
+			}
+			// we simply display the title of the catgory
+			else
+			{
+				$info_this_user_course_category=get_user_course_category($row['id']);
+				echo "<tr><td colspan=\"2\"  class=\"user_course_category\">";
+				echo '<a name="category'.$row['id'].'"></a>'; // display an internal anchor.
+				echo $info_this_user_course_category['title'];
+			}
+			echo "</td><td class=\"user_course_category\">";
+			display_category_icons($row['id'],$all_user_categories);
+			echo "</td></tr>";
+		}
+		// Step 2: show the courses inside this category
+		display_courses_in_category($row['id'], $show_course_icons);
+	}
+	echo "</table>\n";
+}
+
+/**
+ * This function displays all the courses in the particular user category;
+ * @author Patrick Cool <patrick.cool@UGent.be>, Ghent University
+ * @param int id: the id of the user defined course category
+ * @return string: the name of the user defined course category
+*/
+function display_courses_in_category($user_category_id, $showicons)
+{
+	global $_uid;
+
+	// table definitions
+	$TABLECOURS=Database::get_main_table(MAIN_COURSE_TABLE);
+	$TABLECOURSUSER=Database::get_main_table(MAIN_COURSE_USER_TABLE);
+	$TABLE_USER_COURSE_CATEGORY = "`".Database::get_user_personal_database()."`.`user_course_category`";
+
+
+	$sql_select_courses="SELECT course.code, course.visual_code, course.subscribe subscr, course.unsubscribe unsubscr,
+								course.title title, course.tutor_name tutor, course.db_name, course.directory, course_rel_user.status status,
+								course_rel_user.sort sort, course_rel_user.user_course_cat user_course_cat
+		                        FROM    $TABLECOURS       course,
+										$TABLECOURSUSER  course_rel_user
+		                        WHERE course.code = course_rel_user.course_code
+		                        AND   course_rel_user.user_id = '".$_uid."'
+		                        AND course_rel_user.user_course_cat='".$user_category_id."'
+		                        ORDER BY course_rel_user.user_course_cat, course_rel_user.sort ASC";
+	$result = api_sql_query($sql_select_courses) or die(mysql_error());
+	$number_of_courses=mysql_num_rows($result);
+	$key=0;
+	while ($course=mysql_fetch_array($result))
+	{
+		echo "\t<tr>\n";
+		echo "\t\t<td>\n";
+		echo '<a name="course'.$course['code'].'"></a>'; // display an internal anchor.
+		echo "<b>".$course['title']."</b><br />";
+		if (get_setting("display_coursecode_in_courselist") == "true")
+		{
+			echo $course['visual_code'];
+		}
+		if (get_setting("display_coursecode_in_courselist") == "true" AND get_setting("display_teacher_in_courselist") == "true")
+		{
+			echo " - ";
+		}
+		if (get_setting("display_teacher_in_courselist") == "true")
+		{
+			echo $course['tutor'];
+		}
+		echo "\t\t</td>\n";
+		// displaying the up/down/edit icons when we are sorting courses
+		echo "\t\t<td valign=\"top\">\n";
+		//if ($parameter=="sorting")
+		//{
+			display_course_icons($key, $number_of_courses, $course, $user_courses);
+		//}
+		// displaying the delete icon when we are unsubscribing from courses
+		//if($parameter=="deleting")
+		//{
+		//	display_unsubscribe_icons($course);
+		//}
+		// display the subscribing icon when we are to courses.
+		//if ($parameter=="subscribing")
+		//{
+		//	display_subscribe_icon($course);
+		//}
+		echo "\t\t</td>\n";
+		echo "\t</tr>\n";
+		$key++;
+	}
+}
+
+/**
+ * gets the title of the user course category
+ * @author Patrick Cool <patrick.cool@UGent.be>, Ghent University
+ * @param int id: the id of the user defined course category
+ * @return string: the name of the user defined course category
+*/
+function get_user_course_category($id)
+{
+	global $_uid, $user_personal_database;
+
+	$DATABASE_USER_TOOLS = $user_personal_database;
+	$TABLE_USER_COURSE_CATEGORY = $DATABASE_USER_TOOLS."`.`user_course_category";
+
+	$sql="SELECT * FROM `".$TABLE_USER_COURSE_CATEGORY."` WHERE user_id='$_uid' AND id='$id'";
+	$result=mysql_query($sql) or die(mysql_error());
+	$row=mysql_fetch_array($result);
+	return $row;
+}
+
+
+/**
+ * displays the subscribe icon if the subscribing is allowed and if the user is not yet
+ * subscribe to this course
+ * @author Patrick Cool <patrick.cool@UGent.be>, Ghent University
+ * @param string $current_course: the course code of the course we need to display the subscribe icon for
+ * @return string a subscribe icon or the text that subscribing is not allowed or the user is already subscribed
+*/
+function display_subscribe_icon($current_course, $user_coursecodes)
+{
+
+	// we display the icon to subscribe or the text already subscribed
+	if (in_array($current_course['code'],$user_coursecodes))
+	{
+		echo get_lang("AlreadySubscribed");
+	}
+	else
+	{
+		if ($current_course['subscribe'] == SUBSCRIBE_ALLOWED)
+		{
+			echo "<form action=\"".$_SERVER["REQUEST_URI"]."\" method=\"post\">";
+			echo "<input type=\"hidden\" name=\"subscribe\" value=\"".$current_course['code']."\" />";
+			echo "<input type=\"image\" name=\"unsub\" src=\"../img/enroll.gif\" alt=\"".get_lang("Subscribe")."\" />".get_lang("Subscribe")."</form>";
+		}
+		else
+		{
+			echo get_lang("SubscribingNotAllowed");
+		}
+	}
+}
+
+/**
+ * displays the subscribe icon if the subscribing is allowed and if the user is not yet
+ * subscribed to this course
+ * @author Patrick Cool <patrick.cool@UGent.be>, Ghent University
+ * @param  $key:
+ *		   $number_of_courses
+ *		   $course
+ *		   $user_courses
+ * @return html a small table containing the up/down icons and the edit icon (for moving to a different user course category)
+ * @todo complete the comments on this function: the parameter section
+*/
+function display_course_icons($key, $number_of_courses, $course, $user_courses)
+{
+	//print_r($course);
+
+	echo "<table><tr><td>";
+	// the up icon
+	if ($key>0 AND $user_courses[$key-1]['user_course_category']==$course['user_course_category'])
+	{
+		echo "<a href=\"courses.php?action=".$_GET['action']."&amp;move=up&amp;course=".$course['code']."&amp;category=".$course['user_course_cat']."\">";
+		echo "<img src=\"../img/up.gif\" alt=\"".htmlentities(get_lang("Up"))."\"></a>";
+	}
+	echo "</td>";
+	// the edit icon OR the edit dropdown list
+	if (isset($_GET['edit']) and $course['code']==$_GET['edit'])
+	{
+		echo "<td rowspan=\"2\" valign=\"top\">".display_change_course_category_form($_GET['edit'])."</td>";
+	}
+	else
+	{
+		echo "<td rowspan=\"2\" valign=\"middle\"><a href=\"courses.php?action=".$_GET['action']."&amp;edit=".$course['code']."\">";
+		Display::display_icon('edit.gif',get_lang('Edit'));
+		echo "</a></td>";
+	}
+	echo "<td rowspan=\"2\" valign=\"top\">";
+	if ($course['status'] != 1)
+	{
+		if ($course['unsubscr'] == 1)
+			{	// changed link to submit to avoid action by the search tool indexer
+				echo	"<form action=\"".$_SERVER['PHP_SELF']."\" method=\"post\" onsubmit=\"javascript:if(!confirm('".addslashes(htmlentities(get_lang("ConfirmUnsubscribeFromCourse")))."')) return false;\">";
+				echo 	"<input type=\"hidden\" name=\"unsubscribe\" value=\"".$course['code']."\" />";
+				echo 	"<input type=\"image\" name=\"unsub\" src=\"../img/delete.gif\" alt=\"".get_lang("_unsubscribe")."\" /></form>";
+			}
+		else
+			{display_info_text(get_lang("UnsubscribeNotAllowed"));}
+	}
+	else
+	{
+		display_info_text(get_lang("CourseAdminUnsubscribeNotAllowed"));
+	}
+	echo "</td>";
+	echo "</tr><tr><td>";
+	if ($key<$number_of_courses-1 AND $user_courses[$key+1]['user_course_category']==$course['user_course_category'])
+	{
+		echo "<a href=\"courses.php?action=".$_GET['action']."&amp;move=down&amp;course=".$course['code']."&amp;category=".$course['user_course_cat']."\">";
+		echo "<img src=\"../img/down.gif\" alt=\"".htmlentities(get_lang("Down"))."\"></a>";
+	}
+	echo "</td></tr></table>";
+}
+
+/**
+ * displays the relevant icons for the category (if applicable):move up, move down, edit, delete
+ * @author Patrick Cool <patrick.cool@UGent.be>, Ghent University
+ * @param 	$current_category the id of the current category
+ * 			$allcategories an associative array containing all the categories.
+ * @return html: a small table containing the up/down icons and the edit icon (for moving to a different user course category)
+ * @todo complete the comments on this function: the parameter section
+*/
+function display_category_icons($current_category, $all_user_categories)
+{
+	$max_category_key=count($all_user_categories);
+
+	if ($_GET['action']<>'unsubscribe') // we are in the unsubscribe section then we do not show the icons.
+	{
+		echo "<table>";
+		echo "<tr>";
+		echo "<td>";
+		if ($current_category<>$all_user_categories[0])
+		{
+			echo "<a href=\"courses.php?action=".$_GET['action']."&amp;move=up&amp;category=".$current_category."\">";
+			echo "<img src=\"../img/up.gif\" alt=\"".htmlentities(get_lang("Up"))."\"></a>";
+		}
+		echo "</td>";
+   		echo " <td rowspan=\"2\">";
+ 		echo " <a href=\"courses.php?action=sortmycourses&amp;categoryid=".$current_category."#category".$current_category."\">";
+		Display::display_icon('edit.gif',get_lang('Edit'));
+		echo "</a>";
+   		echo "</td>";
+		echo "<td rowspan=\"2\">";
+		echo " <a href=\"courses.php?action=deletecoursecategory&amp;id=".$current_category."\">";
+		Display::display_icon('delete.gif',get_lang('Edit'),array('onclick'=>"javascript:if(!confirm('".addslashes(htmlentities(get_lang("CourseCategoryAbout2bedeleted")))."')) return false;"));
+		echo "</a>";
+		echo "</td>";
+ 		echo "</tr>";
+  		echo "<tr>";
+		echo " <td>";
+		if ($current_category<>$all_user_categories[$max_category_key-1])
+		{
+			echo "<a href=\"courses.php?action=".$_GET['action']."&amp;move=down&amp;category=".$current_category."\">";
+			echo "<img src=\"../img/down.gif\" alt=\"".htmlentities(get_lang("Down"))."\"></a>";
+		}
+		echo "</td>";
+ 		echo " </tr>";
+		echo "</table>";
+	}
+}
+
+/**
+ * This function displays the form (dropdown list) to move a course to a
+ * different course_category (after the edit icon has been changed)
+ * @author Patrick Cool <patrick.cool@UGent.be>, Ghent University
+ * @param string $edit_course:
+ * @return html a dropdown list containing all the user defined course categories and a submit button
+ * @todo when editing (moving) a course inside a user defined course category to a different user defined category
+ *			the dropdown list should have the current course category selected.
+*/
+function display_change_course_category_form($edit_course)
+{
+	global $_uid, $user_personal_database;
+
+	$DATABASE_USER_TOOLS = $user_personal_database;
+	$TABLE_USER_COURSE_CATEGORY = $DATABASE_USER_TOOLS."`.`user_course_category";
+	$sql="SELECT * FROM `$TABLE_USER_COURSE_CATEGORY` WHERE user_id='".$_uid."'";
+	$result=api_sql_query($sql);
+
+
+	$output="<form name=\"edit_course_category\" method=\"post\" action=\"courses.php?action=".$_GET['action']."\">\n";
+	$output.="<input type=\"hidden\" name=\"course_2_edit_category\" value=\"".$edit_course."\" />";
+	$output.="\t<select name=\"course_categories\">\n";
+	$output.="\t\t<option value=\"0\">".get_lang("NoCourseCategory")."</option>";
+	while ($row=mysql_fetch_array($result))
+		{$output.="\t\t<option value=\"".$row['id']."\">".$row['title']."</option>";}
+	$output.="\t</select>\n";
+	$output.="\t<input type=\"submit\" name=\"submit_change_course_category\" value=\"".get_lang("Ok")."\" />\n";
+	$output.="</form>";
+	return $output;
+}
+
+
+/**
+ * This function displays the unsubscribe part which can be
+ * 1. the unsubscribe link
+ * 2. text: you are course admin of this course (=> unsubscription is not possible
+ * 3. text: you are not allowed to unsubscribe from this course
+ * @author Patrick Cool <patrick.cool@UGent.be>, Ghent University
+ * @param array $course: the array with all the course & course_rel_user information
+ * @return html a delete icon or a text that unsubscribing is not possible (course admin) or not allowed.
+*/
+function display_unsubscribe_icons($course)
+{
+	if ($course['status'] != 1)
+	{
+		if ($course['unsubscribe'] == 1)
+			{	// changed link to submit to avoid action by the search tool indexer
+				echo	"<form action=\"".$_SERVER['PHP_SELF']."\" method=\"post\" onsubmit=\"javascript:if(!confirm('".addslashes(htmlentities(get_lang("ConfirmUnsubscribeFromCourse")))."')) return false;\">";
+				echo 	"<input type=\"hidden\" name=\"unsubscribe\" value=\"".$course['code']."\" />";
+				echo 	"<input type=\"image\" name=\"unsub\" src=\"../img/delete.gif\" alt=\"".get_lang("_unsubscribe")."\" /></form>";
+			}
+		else
+			{display_info_text(get_lang("UnsubscribeNotAllowed"));}
+	}
+	else
+	{
+		display_info_text(get_lang("CourseAdminUnsubscribeNotAllowed"));
+	}
+}
+
+
+/**
+ * retrieves all the courses that the user has already subscribed to
+ * @author Patrick Cool <patrick.cool@UGent.be>, Ghent University
+ * @param int $user_id: the id of the user
+ * @return array an array containing all the information of the courses of the given user
+*/
+function get_courses_of_user($user_id)
+{
+	$TABLECOURS=Database::get_main_table(MAIN_COURSE_TABLE);
+	$TABLECOURSUSER=Database::get_main_table(MAIN_COURSE_USER_TABLE);
+
+	// Secondly we select the courses that are in a category (user_course_cat<>0) and sort these according to the sort of the category
+	$sql_select_courses="SELECT course.code k, course.visual_code  vc, course.subscribe subscr, course.unsubscribe unsubscr,
+								course.title i, course.tutor_name t, course.db_name db, course.directory dir, course_rel_user.status status,
+								course_rel_user.sort sort, course_rel_user.user_course_cat user_course_cat
+		                        FROM    $TABLECOURS       course,
+										$TABLECOURSUSER  course_rel_user
+		                        WHERE course.code = course_rel_user.course_code
+		                        AND   course_rel_user.user_id = '".$user_id."'
+		                        ORDER BY course_rel_user.sort ASC";
+	$result = api_sql_query($sql_select_courses) or die(mysql_error());
+	while ($row=mysql_fetch_array($result))
+	{
+		// we only need the database name of the course
+		$courses[]=array("db"=> $row['db'], "code" => $row['k'], "visual_code" => $row['vc'], "title" => $row['i'], "directory" => $row['dir'], "status" => $row['status'], "tutor" => $row['t'], "subscribe" => $row['subscr'], "unsubscribe" => $row['unsubscr'], "sort" => $row['sort'], "user_course_category" => $row['user_course_cat']);
+		}
+
+	return $courses;
+}
+
+/**
+ * retrieves the user defined course categories
+ * @author Patrick Cool <patrick.cool@UGent.be>, Ghent University
+ * @return array containing all the titles of the user defined courses with the id as key of the array
+*/
+function get_user_course_categories()
+{
+	global $_uid;
+	$table_category = Database::get_user_personal_table(USER_COURSE_CATEGORY_TABLE);
+	$sql = "SELECT * FROM ".$table_category." WHERE user_id='".$_uid."' ORDER BY sort ASC";
+	$result = api_sql_query($sql,__FILE__,__LINE__);
+	while ($row = mysql_fetch_array($result))
+	{
+		$output[] = $row['id'];
+	}
+	return $output;
+}
+
+
+
+/**
+ * @author unknown
+ * @param string $text: the text that has to be written in grey
+ * @return string: the text with the grey formatting
+ * @todo move this to a stylesheet
+*/
+function display_info_text($text)
+{
+	echo "<font color=\"#808080\">" . $text . "</font>\n";
+}
+
+/**
+ * @author Patrick Cool <patrick.cool@UGent.be>, Ghent University
+ * @param string $edit_course:
+ * @return html output: the form
+*/
+function display_edit_course_category_form($edit_course_category)
+{
+	echo "<form name=\"edit_course_category\" method=\"post\" action=\"courses.php?action=".$_GET['action']."\">\n";
+	echo "\t<input type=\"hidden\" name=\"edit_course_category\" value=\"".$edit_course_category."\" />\n";
+	$info_this_user_course_category=get_user_course_category($edit_course_category);
+	echo "\t<input type=\"text\" name=\"title_course_category\" value=\"".$info_this_user_course_category['title']."\" />";
+	echo "\t<input type=\"submit\" name=\"submit_edit_course_category\" value=\"".get_lang("Ok")."\" />\n";
+	echo "</form>";
+}
+
+/**
+ * Updates the user course category in the dokeos_user database
+ * @author Patrick Cool <patrick.cool@UGent.be>, Ghent University
+ * @return string a language variable saying that the user course category was stored
+*/
+function store_edit_course_category()
+{
+	global $_uid, $user_personal_database;
+
+	$DATABASE_USER_TOOLS = $user_personal_database;
+	$TABLE_USER_COURSE_CATEGORY = $DATABASE_USER_TOOLS."`.`user_course_category";
+
+	$sql_update="UPDATE `$TABLE_USER_COURSE_CATEGORY` SET title='".htmlentities($_POST['title_course_category'])."' WHERE id='".(int)$_POST['edit_course_category']."'";
+	mysql_query($sql_update) or die(mysql_error());
+	//api_sql_query(sql_update);
+	return get_lang("CourseCategoryEditStored");
+}
+?>

+ 7 - 0
main/auth/index.html

@@ -0,0 +1,7 @@
+<html>
+<head>
+<meta http-equiv="refresh" content="0; url=courses.php">
+</head>
+<body>
+</body>
+</html>

+ 250 - 0
main/auth/inscription.php

@@ -0,0 +1,250 @@
+<?php
+// $Id: inscription.php 9730 2006-10-25 09:15:58Z elixir_inter $
+/*
+==============================================================================
+	Dokeos - elearning and course management software
+
+	Copyright (c) 2004 Dokeos S.A.
+	Copyright (c) 2003 Ghent University (UGent)
+	Copyright (c) 2001 Universite catholique de Louvain (UCL)
+	Copyright (c) various contributors
+	Copyright (c) Bart Mollet, Hogeschool Gent
+
+	For a full list of contributors, see "credits.txt".
+	The full license can be read in "license.txt".
+
+	This program is free software; you can redistribute it and/or
+	modify it under the terms of the GNU General Public License
+	as published by the Free Software Foundation; either version 2
+	of the License, or (at your option) any later version.
+
+	See the GNU General Public License for more details.
+
+	Contact: Dokeos, 181 rue Royale, B-1000 Brussels, Belgium, info@dokeos.com
+==============================================================================
+*/
+/**
+==============================================================================
+*	This script displays a form for registering new users.
+*	@package	 dokeos.auth
+==============================================================================
+*/
+
+$langFile = "registration";
+
+include ("../inc/global.inc.php");
+
+require_once (api_get_path(LIBRARY_PATH).'formvalidator/FormValidator.class.php');
+require_once (api_get_path(LIBRARY_PATH).'usermanager.lib.php');
+require_once (api_get_path(CONFIGURATION_PATH).'profile.conf.inc.php');
+$tool_name = get_lang('Registration');
+
+Display :: display_header($tool_name);
+
+// Forbidden to self-register
+if (get_setting('allow_registration') == 'false')
+{
+	api_not_allowed();
+}
+//api_display_tool_title($tool_name);
+if (get_setting('allow_registration')=='approval')
+{
+	Display::display_normal_message(get_lang('YourAccountHasToBeApproved'));
+}
+
+
+$form = new FormValidator('registration');
+//	LAST NAME and FIRST NAME
+$form->addElement('text', 'lastname',  get_lang('Lastname'),  array('size' => 40));
+$form->addElement('text', 'firstname', get_lang('Firstname'), array('size' => 40));
+$form->addRule('lastname',  get_lang('ThisFieldIsRequired'), 'required');
+$form->addRule('firstname', get_lang('ThisFieldIsRequired'), 'required');
+//	EMAIL
+$form->addElement('text', 'email', get_lang('Email'), array('size' => 40));
+if (api_get_setting('registration', 'email') == 'true')
+	$form->addRule('email', get_lang('ThisFieldIsRequired'), 'required');
+$form->addRule('email', get_lang('EmailWrong'), 'email');
+//	OFFICIAL CODE
+if (CONFVAL_ASK_FOR_OFFICIAL_CODE)
+{
+	$form->addElement('text', 'official_code', get_lang('OfficialCode'), array('size' => 40));
+	if (api_get_setting('registration', 'officialcode') == 'true')
+		$form->addRule('official_code', get_lang('ThisFieldIsRequired'), 'required');
+}
+//	USERNAME
+$form->addElement('text', 'username', get_lang('Username'), array('size' => 40));
+$form->addRule('username', get_lang('ThisFieldIsRequired'), 'required');
+$form->addRule('username', get_lang('UsernameWrong'), 'username');
+$form->addRule('username', get_lang('UserTaken'), 'username_available');
+//	PASSWORD
+$form->addElement('password', 'pass1', get_lang('Pass'),         array('size' => 40));
+$form->addElement('password', 'pass2', get_lang('Confirmation'), array('size' => 40));
+$form->addRule('pass1', get_lang('ThisFieldIsRequired'), 'required');
+$form->addRule(array('pass1', 'pass2'), get_lang('PassTwo'), 'compare');
+if (CHECK_PASS_EASY_TO_FIND)
+	$form->addRule('password1', get_lang('PassTooEasy').': '.api_generate_password(), 'callback', 'api_check_password');
+//	LANGUAGE
+if (get_setting('registration', 'language') == 'true')
+{
+	$form->addElement('select_language', 'language', get_lang('Language'));
+}
+//	STUDENT/TEACHER
+if (get_setting('allow_registration_as_teacher') <> 'false')
+{
+	$form->addElement('radio', 'status', get_lang('Status'), get_lang('RegStudent'), STUDENT);
+	$form->addElement('radio', 'status', null, get_lang('RegAdmin'), COURSEMANAGER);
+}
+$form->addElement('submit', 'submit', get_lang('Ok'));
+//$defaults['language'] = api_get_setting('platformLanguage');
+$defaults['status'] = STUDENT;
+$form->setDefaults($defaults);
+
+if ($form->validate())
+{
+	/*-----------------------------------------------------
+	  STORE THE NEW USER DATA INSIDE THE MAIN DOKEOS DATABASE
+	  -----------------------------------------------------*/
+	$values = $form->exportValues();
+	
+	if (get_setting('allow_registration_as_teacher') == 'false')
+	{
+		$values['status'] = STUDENT;	
+	}
+
+	// creating a new user
+	$user_id = UserManager::create_user($values['firstname'],$values['lastname'],$values['status'],$values['email'],$values['username'],$values['pass1'],$values['official_code'], $values['language']);
+	
+
+	
+	if ($user_id)
+	{
+		// TODO: add language to parameter list of UserManager::create_user(...)
+		$sql = "UPDATE ".Database::get_main_table(MAIN_USER_TABLE)."
+		             SET language	= '".mysql_real_escape_string($values['language'])."'
+					WHERE user_id = '".$_uid."'	 ";
+		//api_sql_query($sql,__FILE__,__LINE__);
+		
+		// if there is a default duration of a valid account then we have to change the expiration_date accordingly
+		if (get_setting('account_valid_duration')<>'')
+		{
+			$sql = "UPDATE ".Database::get_main_table(MAIN_USER_TABLE)."
+						SET expiration_date='registration_date+1' WHERE user_id='".$_uid."'";
+			api_sql_query($sql,__FILE__,__LINE__);
+		}
+		
+		// if the account has to be approved then we set the account to inactive, sent a mail to the platform admin and exit the page.
+		if (get_setting('allow_registration')=='approval')
+		{
+			// 1. set account inactive
+			$sql = "UPDATE ".Database::get_main_table(MAIN_USER_TABLE)."
+						SET active='0' WHERE user_id='".$_uid."'";
+			api_sql_query($sql,__FILE__,__LINE__);
+			
+			// 2. send mail to the platform admin
+			$emailfromaddr 	= api_get_setting('emailAdministrator');
+			$emailfromname 	= api_get_setting('siteName');
+			$emailto		= api_get_setting('emailAdministrator');
+			$emailsubject	= get_lang('ApprovalForNewAccount').': '.$values['username'];
+			$emailbody		= get_lang('ApprovalForNewAccount')."\n";
+			$emailbody		.=get_lang('Username').': '.$values['username']."\n";
+			$emailbody		.=get_lang('Lastname').': '.$values['lastname']."\n";
+			$emailbody		.=get_lang('Firstname').': '.$values['firstname']."\n";
+			$emailbody		.=get_lang('Email').': '.$values['email']."\n";
+			$emailbody		.=get_lang('Status').': '.$values['status']."\n\n";
+			$emailbody		.=get_lang('ManageUser').': '.api_get_path(WEB_CODE_PATH).'admin/user_edit.php?user_id='.$user_id;
+			$emailheaders = "From: ".get_setting('administratorSurname')." ".get_setting('administratorName')." <".get_setting('emailAdministrator').">\n";
+			$emailheaders .= "Reply-To: ".get_setting('emailAdministrator');
+			@ api_send_mail($emailto, $emailsubject, $emailbody, $emailheaders);			
+			
+			// 3. exit the page
+			unset($_uid);
+			Display :: display_footer();
+			exit; 
+		}
+		
+		
+		/*--------------------------------------
+		          SESSION REGISTERING
+		  --------------------------------------*/
+		$_uid=$user_id; 
+		$_user['firstName'] = stripslashes($values['firstname']);
+		$_user['lastName'] = stripslashes($values['lastname']);
+		$_user['mail'] = $values['email'];
+		$_user['language'] = $values['language'];
+		$is_allowedCreateCourse = ($values['status'] == 1) ? true : false;
+		api_session_register('_uid');
+		api_session_register('_user');
+		api_session_register('is_allowedCreateCourse');
+
+		//stats
+		include (api_get_path(LIBRARY_PATH)."events.lib.inc.php");
+		event_login();
+		// last user login date is now
+		$user_last_login_datetime = 0; // used as a unix timestamp it will correspond to : 1 1 1970
+
+		api_session_register('user_last_login_datetime');
+
+		/*--------------------------------------
+		             EMAIL NOTIFICATION
+		  --------------------------------------*/
+
+		if (strstr($values['email'], '@'))
+		{
+			// Lets predefine some variables. Be sure to change the from address!
+			$firstname = $values['firstname'];
+			$lastname = $values['lastname'];
+			$emailto = "\"$firstname $lastname\" <".$values['email'].">";
+			$emailfromaddr = api_get_setting('emailAdministrator');
+			$emailfromname = api_get_setting('siteName');
+			$emailsubject = "[".get_setting('siteName')."] ".get_lang('YourReg')." ".get_setting('siteName');
+
+			// The body can be as long as you wish, and any combination of text and variables
+
+			$emailbody = get_lang('langDear')." ".stripslashes("$firstname $lastname").",\n\n".get_lang('langYouAreReg')." ".get_setting('siteName')." ".get_lang('langSettings')." ".$values['username']."\n".get_lang('langPass')." : ".stripslashes($values['pass1'])."\n\n".get_lang('langAddress')." ".get_setting('siteName')." ".get_lang('langIs')." : ".$rootWeb."\n\n".get_lang('langProblem')."\n\n".get_lang('langFormula').",\n\n".get_setting('administratorName')." ".get_setting('administratorSurname')."\n".get_lang('langManager')." ".get_setting('siteName')."\nT. ".get_setting('administratorTelephone')."\n".get_lang('langEmail')." : ".get_setting('emailAdministrator');
+
+			// Here we are forming one large header line
+			// Every header must be followed by a \n except the last
+			$emailheaders = "From: ".get_setting('administratorSurname')." ".get_setting('administratorName')." <".get_setting('emailAdministrator').">\n";
+			$emailheaders .= "Reply-To: ".get_setting('emailAdministrator');
+
+			// Because I predefined all of my variables, this api_send_mail() function looks nice and clean hmm?
+			@ api_send_mail($emailto, $emailsubject, $emailbody, $emailheaders);
+		}
+	}
+
+	echo "<p>".get_lang('langDear')." ".stripslashes("$firstname $lastname").",<br><br>".get_lang('langPersonalSettings').".</p>\n";
+
+	if (!empty ($values['email']))
+	{
+		echo "<p>".get_lang('langMailHasBeenSent').".</p>";
+	}
+
+	if ($is_allowedCreateCourse)
+	{
+		echo "<p>", get_lang('langNowGoCreateYourCourse'), ".</p>\n";
+		$actionUrl = "../create_course/add_course.php";
+	}
+	else
+	{
+		echo "<p>", get_lang('langNowGoChooseYourCourses'), ".</p>\n";
+		$actionUrl = "courses.php?action=subscribe";
+	}
+	// ?uidReset=true&uidReq=$_uid
+	echo "<form action=\"", $actionUrl, "\"  method=\"post\">\n", "<input type=\"submit\" name=\"next\" value=\"", get_lang('langNext'), "\" validationmsg=\" ", get_lang('langNext'), " \">\n", "</form>\n";
+
+}
+else
+{
+	$form->display();
+}
+?>
+<a href="<?php echo api_get_path(WEB_PATH); ?>">&lt;&lt; <?php echo get_lang('Back'); ?></a>
+<?php
+/*
+==============================================================================
+		FOOTER
+==============================================================================
+*/
+
+Display :: display_footer();
+?>

+ 277 - 0
main/auth/inscription_second.php

@@ -0,0 +1,277 @@
+<?php // $Id: inscription_second.php 9246 2006-09-25 13:24:53Z bmol $ 
+/*
+============================================================================== 
+	Dokeos - elearning and course management software
+	
+	Copyright (c) 2004 Dokeos S.A.
+	Copyright (c) 2003 Ghent University (UGent)
+	Copyright (c) 2001 Universite catholique de Louvain (UCL)
+	Copyright (c) various contributors
+	
+	For a full list of contributors, see "credits.txt".
+	The full license can be read in "license.txt".
+	
+	This program is free software; you can redistribute it and/or
+	modify it under the terms of the GNU General Public License
+	as published by the Free Software Foundation; either version 2
+	of the License, or (at your option) any later version.
+	
+	See the GNU General Public License for more details.
+	
+	Contact: Dokeos, 181 rue Royale, B-1000 Brussels, Belgium, info@dokeos.com
+============================================================================== 
+*/
+/**
+==============================================================================
+*	This script reacts on the form data normally delivered by inscription.php
+*	to register users into Dokeos.
+*	(but malicious users can easily send POST data from their own scripts).
+*
+*	@package dokeos.auth
+*   @deprecated File not in use
+============================================================================== 
+*/
+
+/*==========================
+             INIT
+  ==========================*/
+
+$langFile = "registration";
+require("../inc/global.inc.php");
+
+$TABLEUSER      = Database::get_main_table(MAIN_USER_TABLE);
+
+define ("CHECK_PASS_EASY_TO_FIND", false);
+
+if (!isset($userPasswordCrypted))  $userPasswordCrypted	 = false;
+
+$regDataOk = false; // default value...
+
+if(!empty($_POST['submitRegistration']))
+{
+	$regexp = "^[0-9a-z_\.-]+@(([0-9]{1,3}\.){3}[0-9]{1,3}|([0-9a-z][0-9a-z-]*[0-9a-z]\.)+[a-z]{2,4})$";
+	$uname         = trim ($_POST["uname"     ]);
+	$email         = trim ($_POST["email"     ]);
+	$official_code = trim ($_POST["official_code" ]);
+	$lastname      = trim ($_POST["lastname"  ]);
+	$firstname     = trim ($_POST["firstname" ]);
+	$password      = trim ($_POST["password"  ]);
+	$password1     = trim ($_POST["password1" ]);
+	$language	= $_POST['form_user_language'];
+	
+	$status=($_POST['status'] == COURSEMANAGER)?COURSEMANAGER:STUDENT;
+
+	$uname=eregi_replace('[^a-z0-9_.-]','_',strtr(stripslashes($uname),'ÀÁÂÃÄÅàáâãäåÒÓÔÕÖØòóôõöøÈÉÊËèéêëÇçÌÍÎÏìíîïÙÚÛÜùúûüÿÑñ','AAAAAAaaaaaaOOOOOOooooooEEEEeeeeCcIIIIiiiiUUUUuuuuyNn'));
+
+	/*==========================
+	   DATA SUBIMITED CHECKIN
+	  ==========================*/
+
+	// CHECK THE LANGUAGE OF THE USER PROFILE
+	// we use the platform language if the user cannot select his language or if the chosen language is not valid (spoofed form)
+	if (get_setting('registration', 'language') == "true")
+	{
+	// check if the submitted value is a valid language. If not we use the platform language (against form sppofing)
+		$language_list=api_get_languages();
+		$language_name=$language_list['name'];
+		$language_folder=$language_list['folder'];
+		if (!in_array($language,$language_folder))
+		{
+			$language=get_setting('platformLanguage');
+		}
+
+	}
+	else
+	{
+	// we use the platform languange as the language for the profile
+		$language=get_setting('platformLanguage');
+	}
+
+
+
+
+	// CHECK IF THERE IS NO EMPTY FIELD
+
+	if (
+		   empty($lastname)
+		OR empty($firstname)
+		OR (empty($official_code) 
+			AND (get_setting('registration','officialcode')=="true"))
+		OR empty($password1)
+		OR empty($password)
+		OR empty($uname)
+		OR (empty($email) AND api_get_setting('registration','email')=="true")
+			)
+	{
+		$regDataOk = false;
+
+		unset($password1, $password);
+
+		$error_message .=	"<p>".get_lang('langEmptyFields')."</p>\n";
+	}
+
+	// CHECK IF THE TWO PASSWORD TOKEN ARE IDENTICAL
+
+	elseif($password1 != $password)
+	{
+		$regDataOk = false;
+		unset($password1, $password);
+
+		$error_message .=		"<p>".get_lang('langPassTwice')."</p>\n";
+	}
+	elseif(CHECK_PASS_EASY_TO_FIND && !api_check_password($password))
+	{
+		$error_message .= "<p>".get_lang('langPassTooEasy')." : <code>".api_generate_password()."</code><br></p>";
+	}
+	// CHECK EMAIL ADDRESS VALIDITY
+
+    elseif( !empty($email) && ! eregi( $regexp, $email ))
+	{
+		$regDataOk = false;
+		unset($password1, $password, $email);
+
+		$error_message .=	"<p>".get_lang('langEmailWrong').".</p>\n";
+	}
+
+	// CHECK IF THE LOGIN NAME IS ALREADY OWNED BY ANOTHER USER
+
+	else
+	{
+		$result = api_sql_query("SELECT user_id FROM $TABLEUSER
+							   WHERE username='$uname'");
+
+		if (mysql_num_rows($result) > 0)
+		{
+			$regDataOk = false;
+			unset($password1, $password, $uname);
+
+			$error_message .=	"<p>".get_lang('langUserFree')."</p>";
+		}
+		else
+		{
+			$regDataOk = true;
+		}
+	}
+}
+$nameTools = get_lang('Registration');
+if ( ! $regDataOk)
+{
+	Display::display_header($nameTools);
+	api_display_tool_title($nameTools);
+	echo 	$error_message;
+	echo	"<p>",
+			"<a href=\"inscription.php?lastname=",urlencode(stripslashes($lastname)),"&firstname=",urlencode(stripslashes($firstname)),"&official_code=",urlencode(stripslashes($official_code)),"&uname=",urlencode(stripslashes($uname)),"&email=",urlencode(stripslashes($email)),"&status=",$status,"\">",
+			get_lang('langAgain'),
+			"</a>",
+			"</p>\n";
+	Display::display_footer();
+	exit;		
+	
+}
+
+
+/*> > > > > > > > > > > > REGISTRATION ACCEPTED < < < < < < < < < < < <*/
+
+if ($regDataOk)
+{
+	/*-----------------------------------------------------
+	  STORE THE NEW USER DATA INSIDE THE CLAROLINE DATABASE
+	  -----------------------------------------------------*/
+
+	api_sql_query("INSERT INTO ".$TABLEUSER."
+	             SET lastname     = '".$lastname."',
+	                 firstname   	= '".$firstname."',
+	                 username 	= '".$uname."',
+	                 password 	= '".($userPasswordCrypted?md5($password):$password)."',
+	                 email    	= '".$email."',
+	                 status   	= '".$status."',
+	                 official_code	= '".$official_code."',
+					 language	= '".$language."'
+					 ");
+
+	$_uid = mysql_insert_id();
+
+
+if ($_uid)
+{
+	/*--------------------------------------
+	          SESSION REGISTERING
+	  --------------------------------------*/
+
+		$_user['firstName']     = stripslashes($firstname);
+		$_user['lastName' ]     = stripslashes($lastname);
+		$_user['mail'     ]     = $email;
+		$_user['language'] 		= $language; 
+		$is_allowedCreateCourse = ($status == 1) ? true : false ;
+
+    	api_session_register('_uid');
+		api_session_register('_user');
+		api_session_register('is_allowedCreateCourse');
+
+        //stats
+        include(api_get_path(LIBRARY_PATH)."events.lib.inc.php");
+        event_login();
+        // last user login date is now
+        $user_last_login_datetime = 0; // used as a unix timestamp it will correspond to : 1 1 1970
+
+        api_session_register('user_last_login_datetime');
+
+	/*--------------------------------------
+	             EMAIL NOTIFICATION
+	  --------------------------------------*/
+
+	if(strstr($email,'@'))
+	{
+		// Lets predefine some variables. Be sure to change the from address!
+
+		$emailto       = "\"$firstname $lastname\" <$email>";
+		$emailfromaddr = api_get_setting('emailAdministrator');
+		$emailfromname = api_get_setting('siteName');
+		$emailsubject  = "[".get_setting('siteName')."] ".get_lang('YourReg')." ".get_setting('siteName');
+
+		// The body can be as long as you wish, and any combination of text and variables
+
+		$emailbody=get_lang('langDear')." ".stripslashes("$firstname $lastname").",\n\n".get_lang('langYouAreReg')." ". get_setting('siteName') ." ".get_lang('langSettings')." ". $uname ."\n". get_lang('langPass')." : ".stripslashes($password)."\n\n" .get_lang('langAddress') ." ". api_get_setting('siteName') ." ". get_lang('langIs') ." : ". $rootWeb ."\n\n". get_lang('langProblem'). "\n\n". get_lang('langFormula').",\n\n".get_setting('administratorName')." ".get_setting('administratorSurname')."\n". get_lang('langManager'). " ".get_setting('siteName')."\nT. ".get_setting('administratorTelephone')."\n" .get_lang('langEmail') ." : ".get_setting('emailAdministrator');
+
+		// Here we are forming one large header line
+		// Every header must be followed by a \n except the last
+		$emailheaders = "From: ".get_setting('administratorSurname')." ".get_setting('administratorName')." <".get_setting('emailAdministrator').">\n";
+		$emailheaders .= "Reply-To: ".get_setting('emailAdministrator');
+
+		// Because I predefined all of my variables, this api_send_mail() function looks nice and clean hmm?
+		@api_send_mail( $emailto, $emailsubject, $emailbody, $emailheaders);
+	}
+}
+
+
+Display::display_header($nameTools);
+api_display_tool_title($nameTools);
+
+	echo "<p>".get_lang('langDear')." ".stripslashes("$firstname $lastname").",<br><br>".get_lang('langPersonalSettings').".</p>\n";
+
+	if(!empty($email))
+	{
+		echo "<p>".get_lang('langMailHasBeenSent').".</p>";
+	}
+
+	if($is_allowedCreateCourse)
+	{
+		echo "<p>",get_lang('langNowGoCreateYourCourse'),".</p>\n";
+		$actionUrl = "../create_course/add_course.php";
+	}
+	else
+	{
+		echo "<p>",get_lang('langNowGoChooseYourCourses'),".</p>\n";
+		$actionUrl = "courses.php?action=subscribe";
+	}
+// ?uidReset=true&uidReq=$_uid
+	echo	"<form action=\"",$actionUrl,"\"  method=\"post\">\n",
+			"<input type=\"submit\" name=\"next\" value=\"",get_lang('langNext'),"\" validationmsg=\" ",get_lang('langNext')," \">\n",
+			"</form>\n";
+
+}	// else Registration accepted
+
+$already_second=1;
+
+Display::display_footer();
+?>

+ 364 - 0
main/auth/ldap/authldap.php

@@ -0,0 +1,364 @@
+<?php // $Id: authldap.php 9730 2006-10-25 09:15:58Z elixir_inter $
+/*
+==============================================================================
+	Dokeos - elearning and course management software
+
+	Copyright (c) 2004 Dokeos S.A.
+	Copyright (c) 2003 Ghent University (UGent)
+	Copyright (c) 2001 Universite catholique de Louvain (UCL)
+	Copyright (c) Universite Jean Monnet de Saint Etienne
+	Copyright (c) Roan Embrechts (Vrije Universiteit Brussel)
+
+	For a full list of contributors, see "credits.txt".
+	The full license can be read in "license.txt".
+
+	This program is free software; you can redistribute it and/or
+	modify it under the terms of the GNU General Public License
+	as published by the Free Software Foundation; either version 2
+	of the License, or (at your option) any later version.
+
+	See the GNU General Public License for more details.
+
+	Contact address: Dokeos, 44 rue des palais, B-1030 Brussels, Belgium
+	Mail: info@dokeos.com
+==============================================================================
+*/
+/**
+=======================================================================
+*	LDAP module functions
+*
+*	If the application uses LDAP, these functions are used
+*	for logging in, searching user info, adding this info
+*	to the Dokeos database...
+=======================================================================
+	- function loginWithLdap($login, $password)
+	- function findUserInfoInLdap ($login)
+	- function putUserInfoInClaroline ($login, $infoArray)
+
+	known bugs
+	----------
+	- (fixed 18 june 2003) code has been internationalized
+	- (fixed 07/05/2003) fixed some non-relative urls or includes
+	- (fixed 28/04/2003) we now use global config.inc variables instead of local ones
+	- (fixed 22/04/2003) the last name of a user was restricted to the first part
+	- (fixed 11/04/2003) the user was never registered as a course manager
+
+	version history
+	---------------
+	3.0	- updated to use ldap_var.inc.php instead of ldap_var.inc (deprecated)
+		(November 2003)
+	2.9	- further changes for new login procedure
+		- (busy) translating french functions to english
+		(October 2003)
+	2.8	- adapted for new Claroline login procedure
+		- ldap package now becomes a standard, in auth/ldap
+	2.7 - uses more standard LDAP field names: mail, sn, givenname
+			instead of mail, preferredsn, preferredgivenname
+			there are still
+		- code cleanup
+		- fixed bug: dc = xx, dc = yy was configured for UGent
+			and put literally in the code, this is now a variable
+			in claro_main.conf.php ($ldapDc)
+
+	with thanks to
+	- Stefan De Wannemacker (Ghent University)
+	- Université Jean Monet (J Dubois / Michel Courbon)
+	- Michel Panckoucke for reporting and fixing a bug
+	- Patrick Cool: fixing security hole
+
+	*	@author Roan Embrechts
+	*	@version 3.0
+	*	@package dokeos.auth.ldap
+=======================================================================
+*/
+
+include ('ldap_var.inc.php');
+
+	/*
+	----------------------------------------------------
+		Necessary constants for the LDAP functions
+	----------------------------------------------------
+		These should be placed in the claro_main.conf.php.
+		done: $usesLDAP, $ldaphost, $ldapport, $usesCurriculum --> config.inc
+	*/
+	$PLACEHOLDER = "PLACEHOLDER";
+
+	//debug:
+	//echo ($usesLDAP == false) ? "LDAP disabled<br>" : "LDAP enabled<br>";
+
+	/**
+	===============================================================
+		function
+		CHECK LOGIN & PASSWORD WITH LDAP
+	*	@return true when login & password both OK, false otherwise
+	===============================================================
+	*	@author Roan Embrechts (based on code from Université Jean Monet)
+	*/
+	//include_once("$includePath/../connect/authldap.php");
+
+	function loginWithLdap($login, $password)
+	{
+		$res = Authentif($login, $password);
+
+		// res=-1 -> the user does not exist in the ldap database
+		// res=1 -> invalid password (user does exist)
+
+		if ($res==1) //WRONG PASSWORD
+		{
+			//$errorMessage = "LDAP Username or password incorrect, please try again.<br>";
+			if (isset($log)) unset($log); if (isset($uid)) unset($uid);
+			$loginLdapSucces = false;
+		}
+		if ($res==-1) //WRONG USERNAME
+		{
+			//$errorMessage =  "LDAP Username or password incorrect, please try again.<br>";
+			$loginLdapSucces = false;
+		}
+		if ($res==0) //LOGIN & PASSWORD OK - SUCCES
+		{
+			//$errorMessage = "Successful login w/ LDAP.<br>";
+			$loginLdapSucces = true;
+		}
+
+		//$result = "This is the result: $errorMessage";
+		$result = $loginLdapSucces;
+		return $result;
+	}
+
+
+	/**
+	===============================================================
+		function
+		FIND USER INFO IN LDAP
+	*	@return an array with positions "firstname", "name", "email", "employeenumber"
+	===============================================================
+	*	@author Stefan De Wannemacker
+	*	@author Roan Embrechts
+	*/
+	function findUserInfoInLdap ($login)
+	{
+		global $ldaphost, $ldapport, $ldapDc;
+		// basic sequence with LDAP is connect, bind, search,
+		// interpret search result, close connection
+
+		// using ldap bind
+		$ldaprdn  = 'uname';     // ldap rdn or dn
+		$ldappass = 'password';  // associated password
+
+		//echo "<h3>LDAP query</h3>";
+		//echo "Connecting ...";
+		$ldapconnect = ldap_connect( $ldaphost, $ldapport);
+		if ($ldapconnect) {
+		    	//echo " Connect to LDAP server successful ";
+		    	//echo "Binding ...";
+
+				// this is an "anonymous" bind, typically read-only access:
+		    	$ldapbind = ldap_bind($ldapconnect);
+
+		    	if ($ldapbind)
+				{
+		  	  	//echo " LDAP bind successful... ";
+		    	  	//echo " Searching for uid... ";
+		    		// Search surname entry
+		    		//OLD: $sr=ldap_search($ldapconnect,"dc=rug, dc=ac, dc=be", "uid=$login");
+					//echo "<p> ldapDc = '$ldapDc' </p>";
+		    		$sr=ldap_search($ldapconnect, $ldapDc, "uid=$login");
+
+					//echo " Search result is ".$sr;
+		    		//echo " Number of entries returned is ".ldap_count_entries($ldapconnect,$sr);
+
+		    		//echo " Getting entries ...";
+		    		$info = ldap_get_entries($ldapconnect, $sr);
+		    		//echo "Data for ".$info["count"]." items returned:<p>";
+
+		    	}
+			else
+			{
+				//echo "LDAP bind failed...";
+		    }
+	    	//echo "Closing LDAP connection<hr>";
+	    	ldap_close($ldapconnect);
+		}
+		else
+		{
+			//echo "<h3>Unable to connect to LDAP server</h3>";
+		}
+
+		//DEBUG: $result["firstname"] = "Jan"; $result["name"] = "De Test"; $result["email"] = "email@ugent.be";
+		$result["firstname"] = $info[0]["givenname"][0];
+		$result["name"] = $info[0]["sn"][0];
+		$result["email"] = $info[0]["mail"][0];
+		$result["employeenumber"] = $info[0]["employeenumber"][0];
+
+		return $result;
+	}
+
+
+	/**
+	===============================================================
+	*	function
+	*	PUT USER INFO IN CLAROLINE
+	*	this function uses the data from findUserInfoInLdap()
+	*	to add the userdata to Claroline
+	*
+	*	the "rugid" field is specifically for the Ghent University.
+	*
+	*	"firstname", "name", "email", "isEmployee"
+	===============================================================
+	*	@author Roan Embrechts
+	*/
+	function putUserInfoInClaroline ($login, $infoArray)
+	{
+		global $_POST;
+		global $PLACEHOLDER;
+		global $submitRegistration, $submit, $uname, $email,
+				$nom, $prenom, $password, $password1, $status;
+		global $includePath, $platformLanguage;
+		global $loginFailed, $uidReset, $_uid;
+
+		/*----------------------------------------------------------
+			1. set the necessary variables
+		------------------------------------------------------------ */
+
+		$uname      = $login;
+		$email      = $infoArray["email"];
+		$nom        = $infoArray["name"];
+		$prenom     = $infoArray["firstname"];
+		$password   = $PLACEHOLDER;
+		$password1  = $PLACEHOLDER;
+
+		define ("STUDENT",5);
+		define ("COURSEMANAGER",1);
+
+		if (empty($infoArray["employeenumber"]))
+		{
+			$status = STUDENT;
+		}
+		else
+		{
+			$status = COURSEMANAGER;
+		}
+
+		//$official_code = xxx; //example: choose an attribute
+
+		/*----------------------------------------------------------
+			2. add info to Dokeos
+		------------------------------------------------------------ */
+
+
+		include_once("$includePath/lib/usermanager.lib.php");
+
+
+
+		$_userId = UserManager::create_user($prenom, $nom, $status,
+						 $email, $uname, $password, $official_code,
+						 'english','', '', 'ldap');
+
+		//echo "new user added to claroline, id = $_userId";
+
+		//user_id, username, password, auth_source
+
+		/*----------------------------------------------------------
+			3. register session
+		------------------------------------------------------------ */
+
+		$uData['user_id'] = $_userId;
+		$uData['username'] = $uname;
+		$uData['auth_source'] = "ldap";
+
+		$loginFailed = false;
+		$uidReset = true;
+		$_uid = $uData['user_id'];
+		api_session_register('_uid');
+	}
+
+/* >>>>>>>>>>>>>>>> end of UGent LDAP routines <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< */
+
+/* >>>>> Older but necessary code of Université Jean-Monet <<<<< */
+
+/*
+===========================================================
+	The code of UGent uses these functions to authenticate.
+	* function AuthVerifEnseignant ($uname, $passwd)
+	* function AuthVerifEtudiant ($uname, $passwd)
+	* function Authentif ($uname, $passwd)
+===========================================================
+	To Do
+	* translate the comments and code to english
+	* let these functions use the variables in config.inc instead of ldap_var.inc
+*/
+
+//*** variables en entrée
+// $uname : username entré au clavier
+// $passwd : password fournit par l'utilisateur
+
+//*** en sortie : 3 valeurs possibles
+// 0 -> authentif réussie
+// 1 -> password incorrect
+// -1 -> ne fait partie du LDAP
+
+//---------------------------------------------------
+// verification de l'existence du membre dans le LDAP
+function AuthVerif ($uname, $passwd)
+{
+	global $LDAPserv, $LDAPport, $LDAPbasedn, $LDAPserv2, $LDAPport2;
+	// Establish anonymous connection with LDAP server
+	// Etablissement de la connexion anonyme avec le serveur LDAP
+	 $ds=ldap_connect($LDAPserv,$LDAPport);
+       $TestBind=ldap_bind($ds);
+       //en cas de probleme on utlise le replica
+       if(!$TestBind){
+         $ds=ldap_connect($LDAPserv2,$LDAPport2);
+       }
+	 if ($ds) {
+		// Creation du filtre contenant les valeurs saisies par l'utilisateur
+	    $filter="(uid=$uname)";
+		// Open anonymous LDAP connection
+		// Ouverture de la connection anonyme ldap
+	    $result=ldap_bind($ds);
+		// Execution de la recherche avec $filtre en parametre
+		  $sr=ldap_search($ds,"$LDAPbasedn", "$filter");
+		// La variable $info recoit le resultat de la requete
+		  $info = ldap_get_entries($ds, $sr);
+		  $dn=($info[0]["dn"]);
+		//affichage debug !!	echo"<br> dn = $dn<br> pass = $passwd<br>";
+		// fermeture de la 1ere connexion
+			ldap_close($ds);
+		}
+
+	// teste le Distinguish Name de la 1ere connection
+	  if ($dn==""){
+			 return (-1);		// ne fait pas partie de l'annuaire
+		}
+ //bug ldap.. si password vide.. retourne vrai !!
+	if ($passwd=="") {
+		 return(1);
+		 }
+	// Ouverture de la 2em connection Ldap : connexion user pour verif mot de passe
+	 $ds=ldap_connect($LDAPserv,$LDAPport);
+       if(!$TestBind){
+         $ds=ldap_connect($LDAPserv2,$LDAPport2);
+       }
+	// retour en cas d'erreur de connexion password incorrecte
+	 if (!(@ldap_bind( $ds, $dn , $passwd)) == true) {
+		 return (1); // mot passe invalide
+		 }
+	// connection correcte
+	else	{
+		return (0);
+	}
+
+} // fin de la verif
+
+//---------------------------------------------------
+
+//-------------------------------------------------------
+//  authentification
+
+function Authentif ($uname, $passwd)
+{
+    $res=AuthVerif($uname,$passwd);
+    return($res); // fait partie du LDAP enseignant
+} // fin Authentif
+
+?>

+ 6 - 0
main/auth/ldap/index.html

@@ -0,0 +1,6 @@
+<html>
+<head>
+</head>
+<body>
+</body>
+</html>

+ 77 - 0
main/auth/ldap/ldap_var.inc.php

@@ -0,0 +1,77 @@
+<?php // $Id: ldap_var.inc.php 5291 2005-06-01 09:31:57Z olivierb78 $
+/*
+==============================================================================
+	Dokeos - elearning and course management software
+
+	Copyright (c) 2004 Dokeos S.A.
+	Copyright (c) 2003 Ghent University (UGent)
+	Copyright (c) 2001 Universite catholique de Louvain (UCL)
+	Copyright (c) Roan Embrechts (Vrije Universiteit Brussel)
+
+	For a full list of contributors, see "credits.txt".
+	The full license can be read in "license.txt".
+
+	This program is free software; you can redistribute it and/or
+	modify it under the terms of the GNU General Public License
+	as published by the Free Software Foundation; either version 2
+	of the License, or (at your option) any later version.
+
+	See the GNU General Public License for more details.
+
+	Contact address: Dokeos, 44 rue des palais, B-1030 Brussels, Belgium
+	Mail: info@dokeos.com
+==============================================================================
+*/
+/**
+==============================================================================
+*	LDAP settings
+*	In the older code, there was a distinction between
+*	the teacher and student LDAP server. Later I decided not
+*	to make this distinction. However, it could be built in
+*	in the future but then perhaps in a more general way.
+*
+*	Originally, Thomas and I agreed to store all settings in one file
+*	(claro_main.conf.php) to make it easier for claroline admins to make changes.
+*	Since October 2003, this changed: the include directory has been
+*	changed to be called "inc", and all tools should have their own file(s).
+*
+*	This file "ldap_var.inc.php" was already used by the
+*	older french authentification functions. I have moved the new
+*	variables from the claro_main.conf.php to here as well.
+*
+*	@author Roan Embrechts
+*	@package dokeos.auth.ldap
+==============================================================================
+*/
+
+/*
+==============================================================================
+		INIT SECTION
+==============================================================================
+*/
+
+//parameters for LDAP module
+$usesLDAP						=	TRUE;
+$usesCurriculum					=	FALSE;
+// your ldap server
+$ldaphost = "adresse du serveur LDAP";
+// your ldap server's port number
+$ldapport = "port";
+//domain
+$ldapDc = "OU";
+
+//older variables for French Univ. Jean Monet code
+
+// Variable pour l'annuaire LDAP Enseignant
+$LDAPserv = $ldaphost;
+$LDAPport = $ldapport;
+$LDAPbasedn = $ldapDc;
+
+$critereRechercheEtu = "employeeType";
+
+//ajout C2M pour utiliser replica en cas de problème
+$LDAPserv2 = "adresse replica LDAP";
+$LDAPport2 = "port replica";
+
+
+?>

+ 68 - 0
main/auth/ldap/login.php

@@ -0,0 +1,68 @@
+<?php // $Id: login.php 9246 2006-09-25 13:24:53Z bmol $
+/*
+==============================================================================
+	Dokeos - elearning and course management software
+	
+	Copyright (c) 2004 Dokeos S.A.
+	Copyright (c) 2003 Ghent University (UGent)
+	Copyright (c) 2001 Universite catholique de Louvain (UCL)
+	Copyright (c) Roan Embrechts
+	
+	For a full list of contributors, see "credits.txt".
+	The full license can be read in "license.txt".
+	
+	This program is free software; you can redistribute it and/or
+	modify it under the terms of the GNU General Public License
+	as published by the Free Software Foundation; either version 2
+	of the License, or (at your option) any later version.
+	
+	See the GNU General Public License for more details.
+	
+	Contact address: Dokeos, 44 rue des palais, B-1030 Brussels, Belgium
+	Mail: info@dokeos.com
+==============================================================================
+*/
+/**
+==============================================================================
+*	Users trying to login, who already exist in the Dokeos database 
+*	and have ldap as authentication type, get verified here.
+*
+*	@author Roan Embrechts
+*	@package dokeos.auth.ldap
+==============================================================================
+*/
+	/*
+		An external authentification module
+		needs to set
+		- $loginFailed
+		- $uidReset
+		- $_uid
+		- register the $_uid in the session
+		As the LDAP code shows, this is not as difficult as you might think.
+	*/
+	/*
+	===============================================
+		LDAP authentification module
+		this calls the loginWithLdap function
+		from the LDAP library, and sets a few 
+		variables based on the result.
+	===============================================
+	*/
+	include_once("./main/auth/ldap/authldap.php");
+
+	$loginLdapSucces = loginWithLdap($login, $password);	
+
+	if ($loginLdapSucces)
+	{
+		$loginFailed = false;
+		$uidReset = true;
+		$_uid = $uData['user_id'];
+		api_session_register('_uid');
+	}
+	else
+	{
+		$loginFailed = true;
+		unset($_uid);
+    	$uidReset = false;
+	}
+?>

+ 63 - 0
main/auth/ldap/newUser.php

@@ -0,0 +1,63 @@
+<?php # $Id: newUser.php 9246 2006-09-25 13:24:53Z bmol $
+/*
+==============================================================================
+	Dokeos - elearning and course management software
+	
+	Copyright (c) 2004 Dokeos S.A.
+	Copyright (c) 2003 Ghent University (UGent)
+	Copyright (c) 2001 Universite catholique de Louvain (UCL)
+	Copyright (c) Roan Embrechts
+	
+	For a full list of contributors, see "credits.txt".
+	The full license can be read in "license.txt".
+	
+	This program is free software; you can redistribute it and/or
+	modify it under the terms of the GNU General Public License
+	as published by the Free Software Foundation; either version 2
+	of the License, or (at your option) any later version.
+	
+	See the GNU General Public License for more details.
+	
+	Contact address: Dokeos, 44 rue des palais, B-1030 Brussels, Belgium
+	Mail: info@dokeos.com
+==============================================================================
+*/
+/**
+==============================================================================
+*	Users trying to login, who do not yet exist in the Dokeos database, 
+*	can be added by this script which tries to retrieve ldap information about them.
+*
+*	@author Roan Embrechts
+*	@package dokeos.auth.ldap
+==============================================================================
+*/
+	
+/*
+==================================================
+	when a user does not exist yet in claroline, 
+	but he or she does exist in the LDAP,
+	we add him to the claroline database
+==================================================
+*/
+
+include_once('./main/auth/ldap/authldap.php');
+
+$loginLdapSucces = loginWithLdap($login, $password);	
+
+if ($loginLdapSucces)
+{
+	/*
+		In here, we know that
+		- the user does not exist in Claroline
+		- the users login and password are correct
+	*/
+	$infoArray = findUserInfoInLdap($login);
+	putUserInfoInClaroline ($login, $infoArray);
+}
+else
+{
+	$loginFailed = true;
+	unset($_uid);
+	$uidReset = false;
+}
+?>

+ 109 - 0
main/auth/lostPassword.php

@@ -0,0 +1,109 @@
+<?php
+
+// $Id: lostPassword.php 9246 2006-09-25 13:24:53Z bmol $ 
+/*
+============================================================================== 
+	Dokeos - elearning and course management software
+	
+	Copyright (c) 2004 Dokeos S.A.
+	Copyright (c) 2003 Ghent University (UGent)
+	Copyright (c) 2001 Universite catholique de Louvain (UCL)
+	Copyright (c) various contributors
+	
+	For a full list of contributors, see "credits.txt".
+	The full license can be read in "license.txt".
+	
+	This program is free software; you can redistribute it and/or
+	modify it under the terms of the GNU General Public License
+	as published by the Free Software Foundation; either version 2
+	of the License, or (at your option) any later version.
+	
+	See the GNU General Public License for more details.
+	
+	Contact: Dokeos, 181 rue Royale, B-1000 Brussels, Belgium, info@dokeos.com
+============================================================================== 
+*/
+/**
+==============================================================================
+ * SCRIPT PURPOSE :
+ *
+ * This script allows users to retrieve the password of their profile(s)
+ * on the basis of their e-mail address. The password is send via email
+ * to the user.
+ *
+ * Special case : If the password are encrypted in the database, we have
+ * to generate a new one.
+*
+*	@todo refactor, move relevant functions to code libraries
+*
+*	@package dokeos.auth
+============================================================================== 
+*/
+$langFile = "registration";
+require ('../inc/global.inc.php');
+require_once ('lost_password.lib.php');
+require_once (api_get_path(LIBRARY_PATH).'formvalidator/FormValidator.class.php');
+$tool_name = get_lang('_lost_password');
+Display :: display_header($tool_name);
+
+// Forbidden to retrieve the lost password
+if (get_setting('allow_lostpassword') == "false")
+{
+	api_not_allowed();
+}
+api_display_tool_title($tool_name);
+$tbl_user = Database :: get_main_table(MAIN_USER_TABLE);
+if (isset ($_GET["reset"]) && isset ($_GET["id"]))
+{
+	$msg = reset_password($_GET["reset"], $_GET["id"]);
+	$msg .= '. <br/>'.get_lang('_your_password_has_been_emailed_to_you');
+	$msg .= '<br/><br/><a href="'.api_get_path(WEB_PATH).'main/auth/lostPassword.php">&lt;&lt; '.get_lang('Back').'</a>';
+	echo $msg;
+}
+else
+{
+	$form = new FormValidator('lost_password');
+	$form->add_textfield('email', get_lang('Email'), false, 'size="40"');
+	$form->applyFilter('email','strtolower');
+	$form->addElement('submit', 'submit', get_lang('Ok'));
+	if ($form->validate())
+	{
+		$values = $form->exportValues();
+		$email = $values['email'];
+		$result = api_sql_query("SELECT user_id AS uid, lastname AS lastName, firstname AS firstName,
+											username AS loginName, password, email, status AS status,
+											official_code, phone, picture_uri, creator_id
+											FROM ".$tbl_user."
+											WHERE LOWER(email) = '".mysql_real_escape_string($email)."'
+											AND   email != '' ", __FILE__, __LINE__);
+		if ($result && mysql_num_rows($result))
+		{
+			while ($data = mysql_fetch_array($result))
+				$user[] = $data;
+			if ($userPasswordCrypted)
+				$msg = handle_encrypted_password($user);
+			else
+				$msg = send_password_to_user($user, get_lang('_your_password_has_been_emailed_to_you'));
+		}
+		else
+		{
+			$msg = get_lang('_no_user_account_with_this_email_address');
+		}
+		$msg .= '<br/><br/><a href="'.api_get_path(WEB_PATH).'main/auth/lostPassword.php">&lt;&lt; '.get_lang('Back').'</a>';
+		echo '<p>'.$msg.'</p>';
+	}
+	else
+	{
+		echo '<p>';
+		echo get_lang('_enter_email_and_well_send_you_password');
+		echo '</p>';
+		$form->display();
+		?>
+		<a href="<?php echo api_get_path(WEB_PATH); ?>">&lt;&lt; <?php echo get_lang('Back'); ?></a>
+		<?php
+	}
+}
+
+Display :: display_footer();
+//////////////////////////////////////////////////////////////////////////////
+?> 

+ 124 - 0
main/auth/lost_password.lib.php

@@ -0,0 +1,124 @@
+<?php
+// $Id: lost_password.lib.php 9246 2006-09-25 13:24:53Z bmol $ 
+/*
+============================================================================== 
+	Dokeos - elearning and course management software
+	
+	Copyright (c) 2004 Dokeos S.A.
+	Copyright (c) 2003 Ghent University (UGent)
+	Copyright (c) 2001 Universite catholique de Louvain (UCL)
+	Copyright (c) various contributors
+	
+	For a full list of contributors, see "credits.txt".
+	The full license can be read in "license.txt".
+	
+	This program is free software; you can redistribute it and/or
+	modify it under the terms of the GNU General Public License
+	as published by the Free Software Foundation; either version 2
+	of the License, or (at your option) any later version.
+	
+	See the GNU General Public License for more details.
+	
+	Contact: Dokeos, 181 rue Royale, B-1000 Brussels, Belgium, info@dokeos.com
+============================================================================== 
+*/
+
+/*** By Olivier Cauberghe, UGent ***/
+//-----------------------------------------------------------------------------
+function get_email_headers()
+{
+	global $charset;
+	$emailHeaders = "From: \"".addslashes(get_setting('administratorSurname')." ".get_setting('administratorName'))."\" <".get_setting('emailAdministrator').">\n";
+	$emailHeaders .= "Reply-To: ".get_setting('emailAdministrator')."\n";
+	$emailHeaders .= "X-Sender: ".get_setting('emailAdministrator')."\n";
+	$emailHeaders .= "X-Mailer: PHP / ".phpversion()."\n";
+	$emailHeaders .= "Content-Type: text/plain;\n\tcharset=\"".$charset."\"\n";
+	$emailHeaders .= "Mime-Version: 1.0";
+	return $emailHeaders;
+}
+/*** By Olivier Cauberghe, UGent ***/
+//-----------------------------------------------------------------------------
+function get_user_account_list($user, $reset = false)
+{
+	global $rootWeb;
+	foreach ($user as $thisUser)
+	{
+		$secretword = get_secret_word($thisUser["email"]);
+		if ($reset)
+			$reset_link = "\tReset link : $rootWeb"."main/auth/lostPassword.php?reset=$secretword&id=$thisUser[uid]";
+		else
+			$reset_link = "\t".get_lang('Pass')." : $thisUser[password]";
+		$userAccountList[] = $thisUser["firstName"]." ".$thisUser["lastName"]."\n\n"."\t".get_lang('Username')." : ".$thisUser["loginName"]."\n"."$reset_link\n\n";
+	}
+	if ($userAccountList)
+		$userAccountList = implode("------------------------\n", $userAccountList);
+	return $userAccountList;
+}
+/*** By Olivier Cauberghe, UGent ***/
+//-----------------------------------------------------------------------------
+function send_password_to_user($user, $success_msg)
+{
+	global $charset;
+	global $rootWeb;
+	$emailHeaders = get_email_headers(); // Email Headers
+	$emailSubject = "[".get_setting('siteName')."] ".get_lang('LoginRequest'); // SUBJECT
+	$userAccountList = get_user_account_list($user); // BODY
+	$emailBody = get_lang('YourAccountParam')." $rootWeb\n\n$userAccountList";
+	// SEND MESSAGE
+	$emailTo = $user[0]["email"];
+	if (@ api_send_mail($emailTo, $emailSubject, $emailBody, $emailHeaders))
+		return $success_msg;
+	else
+		return "<p>The system is unable to send you an e-mail.<br/>Please contact the ".Display :: encrypted_mailto_link(get_setting('emailAdministrator'), "Platform administrator").".</p>";
+}
+//-----------------------------------------------------------------------------
+/*** By Olivier Cauberghe, UGent ***/
+function handle_encrypted_password($user)
+{
+	global $security_key;
+	global $charset;
+	global $rootWeb;
+	$emailHeaders = get_email_headers(); // Email Headers
+	$emailSubject = "[".get_setting('siteName')."] ".get_lang('LoginRequest'); // SUBJECT
+	$userAccountList = get_user_account_list($user, true); // BODY
+	$emailTo = $user[0]["email"];
+	$secretword = get_secret_word($emailTo);
+	$emailBody = get_lang("password_request")."\n\n\n".get_lang("YourAccountParam")." $rootWeb\n\n".$userAccountList;
+	if (@ api_send_mail($emailTo, $emailSubject, $emailBody, $emailHeaders))
+		return get_lang("lang_your_password_has_been_emailed_to_you");
+	else
+		echo "<p>", "The system is unable to send you an e-mail.<br/>", "Please contact the ", Display::encrypted_mailto_link(get_setting('emailAdministrator'),"platform administrator"), ".<p>";
+	return "";
+}
+//-----------------------------------------------------------------------------
+function get_secret_word($add)
+{
+	global $security_key;
+	return $secretword = md5($security_key.$add);
+}
+//-----------------------------------------------------------------------------
+function reset_password($secret, $id)
+{
+	global $your_password_has_been_reset,$userPasswordCrypted;
+	$tbl_user = Database::get_main_table(MAIN_USER_TABLE);
+	$sql = "SELECT user_id AS uid, lastname AS lastName, firstname AS firstName, username AS loginName, password, email FROM ".$tbl_user." WHERE user_id=$id";
+	$result = api_sql_query($sql,__FILE__,__LINE__);
+	if ($result && mysql_num_rows($result))
+		$user[] = mysql_fetch_array($result);
+	else
+		return "Could not reset password.";
+	if (get_secret_word($user[0]["email"]) == $secret) // OK, secret word is good. Now change password and mail it.
+	{
+		$user[0]["password"] = api_generate_password();
+		$crypted = $user[0]["password"];
+		if( $userPasswordCrypted)
+		{
+			$crypted = md5($crypted);	
+		}
+		api_sql_query("UPDATE ".$tbl_user." SET password='$crypted' WHERE user_id=$id");
+		return send_password_to_user($user, $your_password_has_been_reset);
+	}
+	else
+		return "Not allowed.";
+}
+?>

+ 519 - 0
main/auth/my_progress.php

@@ -0,0 +1,519 @@
+<?php
+$langFile = array('registration','tracking');
+
+$cidReset = true;
+
+$nameTools="Ma progression";
+
+require ('../inc/global.inc.php');
+
+if(isset($_GET['id_session']))
+{
+	$id_session = intval($_GET['id_session']);
+
+	$_SESSION['id_session']=$id_session;
+}
+elseif(isset($_SESSION['id_session']))
+{
+	$id_session=$_SESSION['id_session'];
+}
+else
+{
+	$id_session=0;
+}
+
+api_block_anonymous_users();
+
+Display :: display_header($nameTools);
+
+$tbl_course = Database :: get_main_table(MAIN_COURSE_TABLE);
+$tbl_user = Database :: get_main_table(MAIN_USER_TABLE);
+$tbl_session = Database :: get_main_table(MAIN_SESSION_TABLE);
+$tbl_course_user = Database :: get_main_table(MAIN_COURSE_USER_TABLE);
+$tbl_session_course = Database :: get_main_table(MAIN_SESSION_COURSE_TABLE);
+$tbl_session_course_user = Database :: get_main_table(MAIN_SESSION_COURSE_USER_TABLE);
+$tbl_stats_lastaccess = Database :: get_statistic_table(STATISTIC_TRACK_E_LASTACCESS_TABLE);
+$tbl_stats_exercices = Database :: get_statistic_table(STATISTIC_TRACK_E_EXERCICES_TABLE);
+$tbl_course_lp_view = Database :: get_course_table('lp_view');
+$tbl_course_lp_view_item = Database :: get_course_table('lp_item_view');
+$tbl_course_lp = Database :: get_course_table('lp');
+$tbl_course_lp_item = Database :: get_course_table('lp_item');
+$tbl_course_quiz = Database :: get_course_table('quiz');
+
+$result=api_sql_query("SELECT DISTINCT id, name, date_start, date_end FROM session_rel_course_rel_user,session WHERE id_session=id AND id_user=$_uid ORDER BY date_start, date_end, name",__FILE__,__LINE__);
+
+$Sessions=api_store_result($result);
+
+$Courses=array();
+
+if($id_session)
+{
+   /*
+	$result=api_sql_query("SELECT code, title, CONCAT(user.lastname,' ',user.firstname) coach, email
+							FROM $tbl_session_course_user AS session_course_user, $tbl_session_course AS session_course, $tbl_course AS course, $tbl_user AS user
+							WHERE session_course_user.id_session='$id_session'
+							AND session_course_user.id_user='$_uid'
+							AND session_course_user.course_code=course.code
+							AND session_course_user.id_session=session_course.id_session
+							AND session_course_user.course_code=session_course.course_code
+							AND session_course.id_coach=user.user_id
+							ORDER BY title",__FILE__,__LINE__);
+	*/
+			
+	$sql = "SELECT DISTINCT code,title, CONCAT(lastname, ' ',firstname) coach, username, date_start, date_end, db_name
+			FROM $tbl_course , $tbl_session_course
+			LEFT JOIN $tbl_user
+				ON $tbl_session_course.id_coach = $tbl_user.user_id
+			INNER JOIN $tbl_session_course_user
+				ON $tbl_session_course_user.id_session = $tbl_session_course.id_session
+				AND $tbl_session_course_user.id_user = '$_uid'
+			INNER JOIN $tbl_session ON $tbl_session.id = $tbl_session_course.id_session
+			WHERE $tbl_session_course.course_code=code
+			AND $tbl_session_course.id_session='$id_session'
+			ORDER BY title";
+
+	$result=api_sql_query($sql);
+	
+	$Courses=api_store_result($result);
+}
+
+api_display_tool_title($nameTools);
+
+$now=date('Y-m-d');
+?>
+
+Commencez par sélectionner une session de cours ci-dessous.<br><br>
+Vous pourrez ensuite suivre votre progression pour chaque cours auquel vous êtes inscrit.<br><br>
+
+<form method="get" action="<?php echo $_SERVER['PHP_SELF']; ?>" style="margin: 0px;">
+<center>
+Session de cours :
+<select name="id_session">
+<option value="0">---------- Choisissez ----------</option>
+
+<?php
+$date_start=$date_end=$now;
+
+foreach($Sessions as $enreg)
+{
+	if($enreg['id'] == $id_session)
+	{
+		$date_start=$enreg['date_start'];
+		$date_end=$enreg['date_end'];
+	}
+	$enreg['date_start']=explode('-',$enreg['date_start']);
+	$enreg['date_start']=$enreg['date_start'][2].'/'.$enreg['date_start'][1].'/'.$enreg['date_start'][0];
+
+	$enreg['date_end']=explode('-',$enreg['date_end']);
+	$enreg['date_end']=$enreg['date_end'][2].'/'.$enreg['date_end'][1].'/'.$enreg['date_end'][0];
+	
+?>
+
+<option value="<?php echo $enreg['id']; ?>" <?php if($enreg['id'] == $id_session) echo 'selected="selected"'; ?> ><?php echo htmlentities($enreg['name']); if($date_start!='0000-00-00') { ?> (du <?php echo $enreg['date_start']; ?> au <?php echo $enreg['date_end']; ?>)<?php } ?></option>
+
+<?php
+}
+
+unset($Sessions);
+?>
+
+</select>
+<input type="submit" value="Valider">
+</center>
+</form>
+
+<br><br>
+
+<table class="data_table" width="100%">
+<tr class="tableName">
+	<td colspan="6">
+		<strong><?php echo get_lang('MyLearnpath'); ?></strong>
+	</td>
+</tr>
+<tr>
+  <th><?php echo get_lang('Course'); ?></th>
+  <th><?php echo get_lang('Time'); ?></th>
+  <th><?php echo get_lang('Progress'); ?></th>
+  <th><?php echo get_lang('Score'); ?></th>
+  <th><?php echo get_lang('LastConnexion'); ?></th>
+  <th><?php echo get_lang('Details'); ?></th>
+</tr>
+
+<?php
+$i = 0;
+$totalWeighting = 0;
+$totalScore = 0;
+$totalItem = 0;
+$totalProgress = 0;
+
+foreach($Courses as $enreg)
+{
+	$sqlTime = "SELECT total_time
+				FROM ".$enreg['db_name'].'.'.$tbl_course_lp_view_item." AS lpi
+				INNER JOIN ".$enreg['db_name'].'.'.$tbl_course_lp_view." AS lpv
+					ON lpv.lp_id = lpi.lp_view_id
+					AND lpv.user_id = ".$_uid
+				;
+	$result = api_sql_query($sqlTime);
+	while($totalTime = mysql_fetch_array($result))
+	{
+		//print_r($totalTime);
+	}
+	
+	$sqlScore = "SELECT exe_result,exe_weighting
+				 FROM $tbl_stats_exercices
+				 WHERE exe_user_id = ".$_uid."
+				 AND exe_cours_id = '".$enreg['code']."'
+				";
+				
+	$resultScore = api_sql_query($sqlScore);
+	$i = 0;
+	$score = 0;
+	while($a_score = mysql_fetch_array($resultScore))
+	{
+		$score = $score + $a_score['exe_result'];
+		$weighting = $weighting + $a_score['exe_weighting'];
+		$i++;
+	}
+	
+	$totalScore = $totalScore + $score;
+	$totalWeighting = $totalWeighting + $weighting;
+	
+	$pourcentageScore = round(($score*100)/$weighting);
+	
+	$weighting = 0;
+	
+	$sqlLastAccess = "	SELECT access_date
+						FROM $tbl_stats_lastaccess
+						WHERE access_user_id = ".$_uid."
+						AND access_cours_code = '".$enreg['code']."'
+						ORDER BY access_date DESC LIMIT 0,1"
+					;
+	$result = api_sql_query($sqlLastAccess);
+	$lastAccess = mysql_fetch_array($result);
+	
+	if(!empty($lastAccess['access_date']))
+	{
+		$a_lastConnexion = explode(' ',$lastAccess['access_date']);
+		$a_date = explode('-',$a_lastConnexion[0]);
+		$a_heure = explode(':',$a_lastConnexion[1]);
+		$lastConnexion = $a_date[2]."/".$a_date[1]."/".$a_date[0];
+		$lastAccessTms  = mktime ( $a_heure[0], $a_heure[1] ,$a_heure[2] ,$a_date[1], $a_date[2],$a_date[0]);
+	}
+	else
+	{
+		$lastConnexion = get_lang('NoConnexion');
+	}
+	$sqlProgress = "SELECT COUNT(DISTINCT item_view.lp_item_id) AS nbItem
+					FROM ".$enreg['db_name'].".".$tbl_course_lp_view_item." AS item_view
+					INNER JOIN ".$enreg['db_name'].".".$tbl_course_lp_view." AS view
+						ON view.user_id = ".$_uid."
+					WHERE item_view.status = 'completed'
+					";
+	$resultProgress = api_sql_query($sqlProgress);
+	$a_nbItem = mysql_fetch_array($resultProgress);
+	
+	$table = $enreg['db_name'].'.'.$tbl_course_lp_item;
+	$nbTotalItem = Database :: count_rows($table);
+
+	$totalItem = $totalItem + $nbTotalItem;
+	$totalProgress = $totalProgress + $a_nbItem['nbItem'];
+	
+	$progress = round(($a_nbItem['nbItem'] * 100)/$nbTotalItem);
+	
+	/*$time = $lastAccessTms - $firstAccessTms;
+	
+	if($time >= 60)
+	{
+		$minute = round($time/60);
+		if($minute >= 60)
+		{
+			$heure = round($minute/60);
+			$minute = $minute - round((60*(($time/60)/60)));
+			if($minute == 0)
+			{
+				$minute = '00';
+			}
+		}
+		else
+		{
+			$heure = 0;
+		}
+		$temps = $heure.'h'.$minute;
+	}
+	else
+	{
+		$temps = '0h00';
+	}
+	$totalTime .= $time; */
+?>
+
+<tr class='<?php echo $i?'row_odd':'row_even'; ?>'>
+  	<td>
+		<?php echo htmlentities($enreg['title']); ?>
+  	</td>
+  
+  	<td align='center'>
+		<?php echo $temps; ?>
+  	</td>
+
+  	<td align='center'>
+  		<?php echo $progress.'%'; ?>
+  	</td>
+
+  	<td align='center'>
+		<?php echo $pourcentageScore.'%'; ?>
+  	</td>
+
+  	<td align='center'>
+		<?php echo $lastConnexion; ?>
+  	</td>
+
+  	<td align='center'>
+		<a href="<?php echo $SERVER['PHP_SELF']; ?>?course=<?php echo $enreg['code']; ?>"> -> </a>
+  	</td>
+</tr>
+
+<?php
+
+
+
+	$i=$i ? 0 : 1;
+}
+
+unset($Courses);
+
+/*if($totalTime >= 60)
+{
+	 $minute = round($totalTime / 60);
+
+	if($minute >= 60)
+	{
+		$heure = round($minute / 60);
+		$minute = $minute - round((60*(($time/60)/60)));
+		if($minute == 0)
+		{
+			$minute = '00';
+		}
+			
+	}
+	else
+	{
+		$heure = 0;
+	}
+	
+	$totalTemps = $heure.'h'.$minute;
+}
+else
+{
+	$totalTemps = '0h00';
+}*/
+
+$totalPourcentageScore = round(($totalScore*100)/$totalWeighting);
+$progress = round(($totalProgress*100)/$totalItem);
+
+?>
+<tr class='total'>
+  	<td>
+		<strong><?php echo get_lang('Total'); ?></strong>
+  	</td>
+  
+  	<td align='center'>
+		<?php echo $totalTemps; ?>
+  	</td>
+
+  	<td align='center'>
+		<?php echo $progress.'%'; ?>
+  	</td>
+
+  	<td align='center'>
+		<?php echo $totalPourcentageScore.'%'; ?>
+  	</td>
+
+  	<td>
+  	</td>
+
+  	<td>
+  	</td>
+</tr>
+</table>
+
+<br/><br/>
+
+<?php
+/*
+ * **********************************************************************************************
+ * 	
+ * 	Details for one course
+ * 
+ * **********************************************************************************************
+ */
+	if(isset($_GET['course']))
+	{
+		$sqlInfosCourse = "	SELECT course.code,course.title,course.db_name,CONCAT(user.firstname,' ',user.lastname,' / ',user.email) as tutor_infos
+							FROM $tbl_user as user,$tbl_course as course
+							INNER JOIN $tbl_session_course as sessionCourse
+								ON sessionCourse.course_code = course.code
+							WHERE sessionCourse.id_coach = user.user_id
+							AND course.code= '".$_GET['course']."'
+						 ";
+		
+		$resultInfosCourse = api_sql_query($sqlInfosCourse);
+		
+		$a_infosCours = mysql_fetch_array($resultInfosCourse);
+		$tableTitle = $a_infosCours['title'].' - '.get_lang('Tutor').' : '.$a_infosCours['tutor_infos'];
+		
+		
+		
+		?>
+		<table class="data_table" width="100%">
+			<tr class="tableName">
+				<td colspan="4">
+					<strong><?php echo $tableTitle; ?></strong>
+				</td>
+			</tr>
+			<tr>
+			  <th class="head"><?php echo get_lang('Learnpath'); ?></th>
+			  <th class="head"><?php echo get_lang('Time'); ?></th>
+			  <th class="head"><?php echo get_lang('Progress'); ?></th>
+			  <th class="head"><?php echo get_lang('LastConnexion'); ?></th>
+			</tr>
+			<?php
+				$sqlLearnpath = "	SELECT lp.name,lp.id
+									FROM ".$a_infosCours['db_name'].".".$tbl_course_lp." AS lp
+								";
+
+				$resultLearnpath = api_sql_query($sqlLearnpath);
+				
+				if(mysql_num_rows($resultLearnpath)>0)
+				{
+					while($a_learnpath = mysql_fetch_array($resultLearnpath))
+					{
+						$sqlProgress = "SELECT COUNT(DISTINCT lp_item_id) AS nbItem
+										FROM ".$a_infosCours['db_name'].".".$tbl_course_lp_view_item." AS item_view
+										INNER JOIN ".$a_infosCours['db_name'].".".$tbl_course_lp_view." AS view
+											ON item_view.lp_view_id = view.id
+											AND view.lp_id = ".$a_learnpath['id']."
+											AND view.user_id = ".$_uid."
+										WHERE item_view.status = 'completed'
+										";
+						$resultProgress = api_sql_query($sqlProgress);
+						$a_nbItem = mysql_fetch_array($resultProgress);
+		
+						$sqlTotalItem = "	SELECT	COUNT(item_type) AS totalItem
+											FROM ".$a_infosCours['db_name'].".".$tbl_course_lp_item." 
+											WHERE lp_id = ".$a_learnpath['id']
+										;
+						$resultItem = api_sql_query($sqlTotalItem);
+						$a_totalItem = mysql_fetch_array($resultItem);
+						
+						$progress = round(($a_nbItem['nbItem'] * 100)/$a_totalItem['totalItem']);
+						
+						
+						echo "<tr>
+								<td>
+							 ";
+						echo 		$a_learnpath['name'];
+						echo "	</td>
+								<td>
+							 ";
+						echo "	</td>
+								<td align='center'>
+							 ";
+						echo		$progress.'%';
+						echo "	</td>
+								<td align='center'>
+							 ";
+						echo		"unknown";
+						echo "	</td>
+							  </tr>
+							 ";
+					}
+					
+				}
+				else
+				{
+					echo "	<tr>	
+								<td colspan='4'>
+									".get_lang('NoLearnpath')."
+								</td>
+							</tr>
+						 ";
+				}
+				
+				
+			
+			?>
+			<tr>
+			  <th class="head"><?php echo get_lang('Exercices'); ?></th>
+			  <th class="head"><?php echo get_lang('Score'); ?></th>
+			  <th class="head"><?php echo get_lang('Essais'); ?></th>
+			  <th class="head"><?php echo get_lang('Correction'); ?></th>
+			</tr>
+			
+			<?php
+			
+				$sqlExercices = "	SELECT quiz.title,id
+								FROM ".$a_infosCours['db_name'].".".$tbl_course_quiz." AS quiz
+							";
+		
+					
+				$resuktExercices = api_sql_query($sqlExercices);
+				while($a_exercices = mysql_fetch_array($resuktExercices))
+				{
+					$sqlEssais = "	SELECT COUNT(ex.exe_id) as essais
+									FROM $tbl_stats_exercices AS ex
+									WHERE  ex.exe_cours_id = '".$a_infosCours['code']."'
+									AND ex.exe_exo_id = ".$a_exercices['id']
+								 ;
+					$resultEssais = api_sql_query($sqlEssais);
+					$a_essais = mysql_fetch_array($resultEssais);
+					
+					$sqlScore = "SELECT exe_result,exe_weighting
+								 FROM $tbl_stats_exercices
+								 WHERE exe_user_id = ".$_uid."
+								 AND exe_cours_id = '".$a_infosCours['code']."'
+								 AND exe_exo_id = ".$a_exercices['id']
+									;
+							
+					$resultScore = api_sql_query($sqlScore);
+					$score = 0; 
+					while($a_score = mysql_fetch_array($resultScore))
+					{
+						$score = $score + $a_score['exe_result'];
+						$weighting = $weighting + $a_score['exe_weighting'];
+					}
+					$pourcentageScore = round(($score*100)/$weighting);
+	
+					$weighting = 0;
+					
+					echo "<tr>
+							<td>
+						 ";
+					echo 		$a_exercices['title'];
+					echo "	</td>
+						 ";
+					echo "	<td align='center'>
+						  ";
+					echo $pourcentageScore.'%';
+					echo "	</td>
+					
+							<td align='center'>
+						 ";
+					echo 		$a_essais['essais'];
+					echo "	</td>
+							<td>
+						 ";
+					echo "	</td>
+						  </tr>
+						 ";
+				}
+				
+			
+			?>
+		</table>
+		<?php
+	}
+
+Display :: display_footer();
+?>

+ 595 - 0
main/auth/profile.php

@@ -0,0 +1,595 @@
+<?php
+// $Id: profile.php 9548 2006-10-18 08:19:15Z elixir_inter $
+/*
+==============================================================================
+	Dokeos - elearning and course management software
+
+	Copyright (c) 2004 Dokeos S.A.
+	Copyright (c) 2003 Ghent University (UGent)
+	Copyright (c) 2001 Universite catholique de Louvain (UCL)
+	Copyright (c) Roan Embrechts (Vrije Universiteit Brussel)
+
+	For a full list of contributors, see "credits.txt".
+	The full license can be read in "license.txt".
+
+	This program is free software; you can redistribute it and/or
+	modify it under the terms of the GNU General Public License
+	as published by the Free Software Foundation; either version 2
+	of the License, or (at your option) any later version.
+
+	See the GNU General Public License for more details.
+
+	Contact address: Dokeos, 44 rue des palais, B-1030 Brussels, Belgium
+	Mail: info@dokeos.com
+==============================================================================
+*/
+/**
+==============================================================================
+* This file displays the user's profile,
+* optionally it allows users to modify their profile as well.
+*
+* See inc/conf/profile.conf.inc.php to modify settings
+*
+* @package dokeos.auth
+==============================================================================
+*/
+
+/*
+==============================================================================
+		INIT SECTION
+==============================================================================
+*/
+$langFile = 'registration';
+$cidReset = true;
+
+require ('../inc/global.inc.php');
+require_once (api_get_path(LIBRARY_PATH).'formvalidator/FormValidator.class.php');
+$this_section = SECTION_MYPROFILE;
+
+api_block_anonymous_users();
+
+$htmlHeadXtra[] = '<script type="text/javascript">
+function confirmation(name)
+{
+	if (confirm("'.get_lang('AreYouSureToDelete').' " + name + " ?"))
+		{return true;}
+	else
+		{return false;}
+}
+</script>';
+
+if (!empty ($_GET['coursePath']))
+{
+	$course_url = api_get_path(WEB_COURSE_PATH).$_GET['coursePath'].'/index.php';
+	$interbreadcrumb[] = array ('url' => $course_url, 'name' => $_GET['courseCode']);
+}
+
+/*
+-----------------------------------------------------------
+	Configuration file
+-----------------------------------------------------------
+*/
+require_once (api_get_path(CONFIGURATION_PATH).'profile.conf.inc.php');
+
+/*
+-----------------------------------------------------------
+	Libraries
+-----------------------------------------------------------
+*/
+include_once (api_get_path(LIBRARY_PATH).'fileManage.lib.php');
+include_once (api_get_path(LIBRARY_PATH).'fileUpload.lib.php');
+
+if (is_profile_editable())
+	$tool_name = get_lang('ModifProfile');
+else
+	$tool_name = get_lang('ViewProfile');
+
+$table_user = Database :: get_main_table(MAIN_USER_TABLE);
+
+/*
+-----------------------------------------------------------
+	Form
+-----------------------------------------------------------
+*/
+/*
+ * Get initial values for all fields.
+ */
+$sql = "SELECT * FROM $table_user WHERE user_id = '$_uid'";
+$result = api_sql_query($sql, __FILE__, __LINE__);
+if ($result)
+{
+	$user_data = mysql_fetch_array($result, MYSQL_ASSOC);
+
+	if (is_null($user_data['language']))
+		$user_data['language'] = api_get_setting('platformLanguage');
+}
+
+/*
+ * Initialize the form.
+ */
+$form = new FormValidator('profile', 'post', "{$_SERVER['PHP_SELF']}?{$_SERVER['QUERY_STRING']}", null, array('style' => 'width: 60%; float: '.($text_dir=='rtl'?'right;':'left;')));
+
+/* Make sure this is the first submit on the form, even though it is hidden!
+ * Otherwise, if a user has productions and presses ENTER to submit, he will
+ * attempt to delete the first production in the list. */
+if (is_profile_editable())
+	$form->addElement('submit', null, get_lang('Ok'), array('style' => 'visibility:hidden;'));
+
+//	LAST NAME and FIRST NAME
+$form->addElement('text', 'lastname',  get_lang('Lastname'),  array('size' => 40));
+$form->addElement('text', 'firstname', get_lang('Firstname'), array('size' => 40));
+if (api_get_setting('profile', 'name') !== 'true')
+	$form->freeze(array('lastname', 'firstname'));
+$form->applyFilter(array('lastname', 'firstname'), 'stripslashes');
+$form->applyFilter(array('lastname', 'firstname'), 'trim');
+$form->addRule('lastname' , get_lang('ThisFieldIsRequired'), 'required');
+$form->addRule('firstname', get_lang('ThisFieldIsRequired'), 'required');
+
+//	OFFICIAL CODE
+if (CONFVAL_ASK_FOR_OFFICIAL_CODE)
+{
+	$form->addElement('text', 'official_code', get_lang('OfficialCode'), array('size' => 40));
+	if (api_get_setting('profile', 'officialcode') !== 'true')
+		$form->freeze('official_code');
+	$form->applyFilter('official_code', 'stripslashes');
+	$form->applyFilter('official_code', 'trim');
+	if (api_get_setting('registration', 'officialcode') == 'true')
+		$form->addRule('official_code', get_lang('ThisFieldIsRequired'), 'required');
+}
+
+//	EMAIL
+$form->addElement('text', 'email', get_lang('Email'), array('size' => 40));
+if (api_get_setting('profile', 'email') !== 'true')
+	$form->freeze('email');
+$form->applyFilter('email', 'stripslashes');
+$form->applyFilter('email', 'trim');
+if (api_get_setting('registration', 'email') == 'true')
+	$form->addRule('email', get_lang('ThisFieldIsRequired'), 'required');
+$form->addRule('email', get_lang('EmailWrong'), 'email');
+
+
+//	PHONE
+$form->addElement('text', 'phone', get_lang('phone'), array('size' => 20));
+if (api_get_setting('profile', 'phone') !== 'true')
+	$form->freeze('phone');
+$form->applyFilter('phone', 'stripslashes');
+$form->applyFilter('phone', 'trim');
+/*if (api_get_setting('registration', 'phone') == 'true')
+	$form->addRule('phone', get_lang('ThisFieldIsRequired'), 'required');
+$form->addRule('phone', get_lang('EmailWrong'), 'email');*/
+
+
+//	PICTURE
+if (is_profile_editable() && api_get_setting('profile', 'picture') == 'true')
+{
+	$form->addElement('file', 'picture', (get_user_image($_uid) != '' ? get_lang('UpdateImage') : get_lang('AddImage')));
+	$form->add_progress_bar();
+	if( strlen($user_data['picture_uri']) > 0)
+	{
+		$form->addElement('checkbox', 'remove_picture', null, get_lang('DelImage'));
+	}
+	$form->addRule('picture', get_lang('OnlyImagesAllowed'), 'mimetype', array('image/gif', 'image/jpeg', 'image/png'));
+}
+
+//	USERNAME
+$form->addElement('text', 'username', get_lang('Username'), array('size' => 40));
+if (api_get_setting('profile', 'login') !== 'true')
+	$form->freeze('username');
+$form->applyFilter('username', 'stripslashes');
+$form->applyFilter('username', 'trim');
+$form->addRule('username', get_lang('ThisFieldIsRequired'), 'required');
+$form->addRule('username', get_lang('UsernameWrong'), 'username');
+$form->addRule('username', get_lang('UserTaken'), 'username_available', $user_data['username']);
+
+//	LANGUAGE
+$form->addElement('select_language', 'language', get_lang('Language'));
+if (api_get_setting('profile', 'language') !== 'true')
+	$form->freeze('language');
+
+//	EXTENDED PROFILE
+if (api_get_setting('extended_profile') == 'true')
+{
+	$form->addElement('static', null, '<em>'.get_lang('OptionalTextFields').'</em>');
+
+	//	MY COMPETENCES
+	$form->addElement('textarea', 'competences', get_lang('MyCompetences'), array('cols' => 30, 'rows' => 2));
+
+	//	MY DIPLOMAS
+	$form->addElement('textarea', 'diplomas', get_lang('MyDiplomas'), array('cols' => 30, 'rows' => 2));
+
+	//	WHAT I AM ABLE TO TEACH
+	$form->addElement('textarea', 'teach', get_lang('MyTeach'), array('cols' => 30, 'rows' => 2));
+
+	//	MY PRODUCTIONS
+	$form->addElement('file', 'production', get_lang('MyProductions'));
+	if ($production_list = build_production_list($_uid))
+		$form->addElement('static', 'productions', null, $production_list);
+
+	//	MY PERSONAL OPEN AREA
+	$form->add_html_editor('openarea', get_lang('MyPersonalOpenArea'), false);
+
+	$form->applyFilter(array('competences', 'diplomas', 'teach', 'openarea'), 'stripslashes');
+	$form->applyFilter(array('competences', 'diplomas', 'teach'), 'trim'); // openarea is untrimmed for maximum openness
+}
+
+//	PASSWORD
+if (is_profile_editable() && api_get_setting('profile', 'password') == 'true')
+{
+	$form->addElement('static', null, null, '<em>'.get_lang('Enter2passToChange').'</em>');
+
+	$form->addElement('password', 'password1', get_lang('Pass'),         array('size' => 40));
+	$form->addElement('password', 'password2', get_lang('Confirmation'), array('size' => 40));
+
+	//	user must enter identical password twice so we can prevent some user errors
+	$form->addRule(array('password1', 'password2'), get_lang('PassTwo'), 'compare');
+	if (CHECK_PASS_EASY_TO_FIND)
+		$form->addRule('password1', get_lang('PassTooEasy').': '.api_generate_password(), 'callback', 'api_check_password');
+}
+
+//	SUBMIT
+if (is_profile_editable())
+{
+	$form->addElement('submit', 'apply_change', get_lang('Ok'));
+}
+else
+{
+	$form->freeze();
+}
+
+/*
+ * Set initial values for all fields.
+ */
+$form->setDefaults($user_data);
+
+/*
+==============================================================================
+		FUNCTIONS
+==============================================================================
+*/
+
+/*
+-----------------------------------------------------------
+	LOGIC FUNCTIONS
+-----------------------------------------------------------
+*/
+
+/**
+ * Can a user edit his/her profile?
+ *
+ * @return	boolean	Editability of the profile
+ */
+function is_profile_editable()
+{
+	return $GLOBALS['profileIsEditable'];
+}
+
+/*
+-----------------------------------------------------------
+	USER IMAGE FUNCTIONS
+-----------------------------------------------------------
+*/
+
+/**
+ * Get a user's display picture. If the user doesn't have a picture, this
+ * function will return an empty string.
+ *
+ * @param	$_uid	User id
+ * @return	The uri to the picture
+ */
+function get_user_image($_uid)
+{
+	$table_user = Database :: get_main_table(MAIN_USER_TABLE);
+	$sql = "SELECT picture_uri FROM $table_user WHERE user_id = '$_uid'";
+	$result = api_sql_query($sql, __FILE__, __LINE__);
+
+	if ($result && $row = mysql_fetch_array($result, MYSQL_ASSOC))
+		$image = trim($row['picture_uri']);
+	else
+		$image = '';
+
+	return $image;
+}
+
+/**
+ * Upload a submitted user image.
+ *
+ * @param	$_uid	User id
+ * @return	The filename of the new picture or FALSE if the upload has failed
+ */
+function upload_user_image($_uid)
+{
+	/* Originally added by Miguel (miguel@cesga.es) - 2003-11-04
+	 * Code Refactoring by Hugues Peeters (hugues.peeters@claroline.net) - 2003-11-24
+	 * Moved inside a function and refactored by Thomas Corthals - 2005-11-04
+	 */
+
+	$image_repository = api_get_path(SYS_CODE_PATH).'upload/users/';
+	$existing_image = get_user_image($_uid);
+
+	$file_extension = explode('.', $_FILES['picture']['name']);
+	$file_extension = strtolower($file_extension[sizeof($file_extension) - 1]);
+
+	if (!file_exists($image_repository))
+		mkpath($image_repository);
+
+	if ($existing_image != '')
+	{
+		if (KEEP_THE_NAME_WHEN_CHANGE_IMAGE)
+		{
+			$picture_filename = $existing_image;
+			$old_picture_filename = 'saved_'.date('Y_m_d_H_i_s').'_'.uniqid('').'_'.$existing_image;
+		}
+		else
+		{
+			$old_picture_filename = $existing_image;
+			$picture_filename = (PREFIX_IMAGE_FILENAME_WITH_UID ? 'u'.$_uid.'_' : '').uniqid('').'.'.$file_extension;
+		}
+
+		if (KEEP_THE_OLD_IMAGE_AFTER_CHANGE)
+			rename($image_repository.$existing_image, $image_repository.$old_picture_filename);
+		else
+			unlink($image_repository.$existing_image);
+	}
+	else
+	{
+		$picture_filename = (PREFIX_IMAGE_FILENAME_WITH_UID ? $_uid.'_' : '').uniqid('').'.'.$file_extension;
+	}
+
+	if (move_uploaded_file($_FILES['picture']['tmp_name'], $image_repository.$picture_filename))
+		return $picture_filename;
+
+	return false; // this should be returned if anything went wrong with the upload
+}
+
+/**
+ * Remove an existing user image.
+ *
+ * @param	$_uid	User id
+ */
+function remove_user_image($_uid)
+{
+	$image_repository = api_get_path(SYS_CODE_PATH).'upload/users/';
+	$image = get_user_image($_uid);
+
+	if ($image != '')
+	{
+		if (KEEP_THE_OLD_IMAGE_AFTER_CHANGE)
+			rename($image_repository.$image, $image_repository.'deleted_'.date('Y_m_d_H_i_s').'_'.$image);
+		else
+			unlink($image_repository.$image);
+	}
+}
+
+/*
+-----------------------------------------------------------
+	PRODUCTIONS FUNCTIONS
+-----------------------------------------------------------
+*/
+
+/**
+ * Returns an XHTML formatted list of productions for a user, or FALSE if he
+ * doesn't have any.
+ *
+ * If there has been a request to remove a production, the function will return
+ * without building the list unless forced to do so by the optional second
+ * parameter. This increases performance by avoiding to read through the
+ * productions on the filesystem before the removal request has been carried
+ * out because they'll have to be re-read afterwards anyway.
+ *
+ * @param	$_uid	User id
+ * @param	$force	Optional parameter to force building after a removal request
+ * @return	A string containing the XHTML code to dipslay the production list, or FALSE
+ */
+function build_production_list($_uid, $force = false)
+{
+	if (!$force && $_POST['remove_production'])
+		return true; // postpone reading from the filesystem
+
+	$productions = get_user_productions($_uid);
+
+	if (empty($productions))
+		return false;
+
+	$production_dir = api_get_path(WEB_CODE_PATH)."upload/users/$_uid/";
+	$del_image = api_get_path(WEB_CODE_PATH).'img/delete.gif';
+	$del_text = get_lang('Delete');
+
+	$production_list = '<ul id="productions">';
+
+	foreach ($productions as $file)
+	{
+		$production_list .= '<li><a href="'.$production_dir.urlencode($file).'" target="_blank">'.htmlentities($file).'</a>';
+		$production_list .= '<input type="image" name="remove_production['.urlencode($file).']" src="'.$del_image.'" alt="'.$del_text.'" title="'.$del_text.' '.htmlentities($file).'" onclick="return confirmation(\''.htmlentities($file).'\');" /></li>';
+	}
+
+	$production_list .= '</ul>';
+
+	return $production_list;
+}
+
+/**
+ * Returns an array with the user's productions.
+ *
+ * @param	$_uid	User id
+ * @return	An array containing the user's productions
+ */
+function get_user_productions($_uid)
+{
+	$production_repository = api_get_path(SYS_CODE_PATH)."upload/users/$_uid/";
+	$productions = array();
+
+	if (is_dir($production_repository))
+	{
+		$handle = opendir($production_repository);
+
+		while ($file = readdir($handle))
+		{
+			if ($file == '.' || $file == '..' || $file == '.htaccess')
+				continue; // skip current/parent directory and .htaccess
+
+			$productions[] = $file;
+		}
+	}
+
+	return $productions; // can be an empty array
+}
+
+/**
+ * Upload a submitted user production.
+ *
+ * @param	$_uid	User id
+ * @return	The filename of the new production or FALSE if the upload has failed
+ */
+function upload_user_production($_uid)
+{
+	$production_repository = api_get_path(SYS_CODE_PATH)."upload/users/$_uid/";
+
+	if (!file_exists($production_repository))
+		mkpath($production_repository);
+
+	$filename = replace_dangerous_char($_FILES['production']['name']);
+	$filename = php2phps($filename);
+
+	if (move_uploaded_file($_FILES['production']['tmp_name'], $production_repository.$filename))
+		return $filename;
+
+	return false; // this should be returned if anything went wrong with the upload
+}
+
+/**
+ * Remove a user production.
+ *
+ * @param	$_uid		User id
+ * @param	$production	The production to remove
+ */
+function remove_user_production($_uid, $production)
+{
+	unlink(api_get_path(SYS_CODE_PATH)."upload/users/$_uid/$production");
+}
+
+/*
+==============================================================================
+		MAIN CODE
+==============================================================================
+*/
+if ($_SESSION['profile_update'])
+{
+	$update_success = ($_SESSION['profile_update'] == 'success');
+
+	unset($_SESSION['profile_update']);
+}
+elseif ($_POST['remove_production'])
+{
+	foreach (array_keys($_POST['remove_production']) as $production)
+		remove_user_production($_uid, urldecode($production));
+
+	if ($production_list = build_production_list($_uid, true))
+		$form->insertElementBefore($form->createElement('static', null, null, $production_list), 'productions');
+
+	$form->removeElement('productions');
+
+	$file_deleted = true;
+}
+elseif ($form->validate())
+{
+	$user_data = $form->exportValues();
+
+	// set password if a new one was provided
+	if ($user_data['password1'])
+		$password = $user_data['password1'];
+
+	// upload picture if a new one is provided
+	if ($_FILES['picture']['size'])
+	{
+		if ($new_picture = upload_user_image($_uid))
+			$user_data['picture_uri'] = $new_picture;
+	}
+	// remove existing picture if asked
+	elseif ($user_data['remove_picture'])
+	{
+		remove_user_image($_uid);
+
+		$user_data['picture_uri'] = '';
+	}
+
+	// upload production if a new one is provided
+	if ($_FILES['production']['size'])
+		upload_user_production($_uid);
+
+	// remove values that shouldn't go in the database
+	unset($user_data['password1'], $user_data['password2'], $user_data['MAX_FILE_SIZE'],
+		$user_data['remove_picture'], $user_data['apply_change']);
+
+	// build SQL query
+	$sql = "UPDATE $table_user SET";
+
+	foreach($user_data as $key => $value)
+	{
+		$sql .= " $key = '".addslashes($value)."',";
+	}
+
+	if (isset($password))
+	{
+		if ($userPasswordCrypted)
+		{
+			$sql .= " password = MD5('".addslashes($password)."')";
+		}
+		else
+		{
+			$sql .= " password = '".addslashes($password)."'";
+		}
+	}
+	else // remove trailing , from the query we have so far
+	{
+		$sql = rtrim($sql, ',');
+	}
+
+	$sql .= " WHERE user_id  = '$_uid'";
+
+	api_sql_query($sql, __FILE__, __LINE__);
+
+	// re-init the system to take new settings into account
+	$uidReset = true;
+	include (api_get_path(INCLUDE_PATH).'local.inc.php');
+	$_SESSION['profile_update'] = 'success';
+	header("Location: http://{$_SERVER['HTTP_HOST']}{$_SERVER['PHP_SELF']}?{$_SERVER['QUERY_STRING']}");
+	exit;
+}
+
+/*
+==============================================================================
+		MAIN DISPLAY SECTION
+==============================================================================
+*/
+Display :: display_header(get_lang('ModifyProfile'));
+
+if ($file_deleted)
+{
+	Display :: display_normal_message(get_lang('FileDeleted'));
+}
+elseif ($update_success)
+{
+	Display :: display_normal_message(get_lang('ProfileReg'));
+}
+//	USER PICTURE
+$image = get_user_image($_uid);
+$image_file = ($image != '' ? api_get_path(WEB_CODE_PATH)."upload/users/$image" : api_get_path(WEB_CODE_PATH).'img/unknown.jpg');
+$image_size = @getimagesize($image_file);
+
+$img_attributes = 'src="'.$image_file.'?rand='.time().'" '
+	.'alt="'.$user_data['lastname'].' '.$user_data['firstname'].'" '
+	.'style="float:'.($text_dir == 'rtl' ? 'left' : 'right').'; padding:5px;" ';
+
+if ($image_size[0] > 300) //limit display width to 300px
+	$img_attributes .= 'width="300" ';
+
+echo '<img '.$img_attributes.'/>';
+
+$form->display();
+
+echo '<div style="clear:both; border-top:thin solid; padding-top:2px;">
+	<a href="'.api_get_path(WEB_CODE_PATH).'tracking/personnalLog.php">'.get_lang('MyStats').'</a>
+	| <a href="'.api_get_path(WEB_CODE_PATH).'auth/courses.php">'.get_lang('MyCourses').'</a></div>';
+
+Display :: display_footer();
+?>

+ 458 - 0
main/blog/blog.php

@@ -0,0 +1,458 @@
+<?php
+/*
+==============================================================================
+	Dokeos - elearning and course management software
+
+	Copyright (c) 2004 Dokeos S.A.
+	Copyright (c) 2003 University of Ghent (UGent)
+	Copyright (c) 2001 Universite catholique de Louvain (UCL)
+	Copyright (c) various contributors
+
+	For a full list of contributors, see "credits.txt".
+	The full license can be read in "license.txt".
+
+	This program is free software; you can redistribute it and/or
+	modify it under the terms of the GNU General Public License
+	as published by the Free Software Foundation; either version 2
+	of the License, or (at your option) any later version.
+
+	See the GNU General Public License for more details.
+
+	Contact: Dokeos, 181 rue Royale, B-1000 Brussels, Belgium, info@dokeos.com
+
+==============================================================================
+
+    BLOG HOMEPAGE
+
+	This file takes care of all blog navigation and displaying.
+
+	@package dokeos.blogs
+==============================================================================
+*/
+
+/*
+==============================================================================
+	INIT
+==============================================================================
+*/
+$langFile = "blog";
+$blog_id = intval($_GET['blog_id']);
+
+include ('../inc/global.inc.php');
+
+//session
+if(isset($_GET['id_session']))
+	$_SESSION['id_session'] = $_GET['id_session'];
+
+require_once (api_get_path(LIBRARY_PATH)."/display.lib.php");
+require_once (api_get_path(LIBRARY_PATH)."/text.lib.php");
+require_once (api_get_path(LIBRARY_PATH)."/blog.lib.php");
+require_once (api_get_path(LIBRARY_PATH)."/fckeditor.lib.php");
+
+$nameTools = get_lang("blogs");
+$DaysShort = array (get_lang("SundayShort"), get_lang("MondayShort"), get_lang("TuesdayShort"), get_lang("WednesdayShort"), get_lang("ThursdayShort"), get_lang("FridayShort"), get_lang("SaturdayShort"));
+$DaysLong = array (get_lang("SundayLong"), get_lang("MondayLong"), get_lang("TuesdayLong"), get_lang("WednesdayLong"), get_lang("ThursdayLong"), get_lang("FridayLong"), get_lang("SaturdayLong"));
+$MonthsLong = array (get_lang("JanuaryLong"), get_lang("FebruaryLong"), get_lang("MarchLong"), get_lang("AprilLong"), get_lang("MayLong"), get_lang("JuneLong"), get_lang("JulyLong"), get_lang("AugustLong"), get_lang("SeptemberLong"), get_lang("OctoberLong"), get_lang("NovemberLong"), get_lang("DecemberLong"));
+
+$current_page = $_GET['action'];
+
+/*
+==============================================================================
+	PROCESSING
+==============================================================================
+*/
+if ($_POST['new_post_submit'])
+{
+	Blog :: create_post(mysql_real_escape_string($_POST['post_title']), mysql_real_escape_string($_POST['post_full_text']), $blog_id);
+}
+if ($_POST['edit_post_submit'])
+{
+	Blog :: edit_post(mysql_real_escape_string($_POST['post_id']), mysql_real_escape_string($_POST['post_title']), mysql_real_escape_string($_POST['post_full_text']), $blog_id);
+}
+if ($_POST['new_comment_submit'])
+{
+	Blog :: create_comment(mysql_real_escape_string($_POST['comment_title']), mysql_real_escape_string($_POST['comment_text']), $blog_id, mysql_real_escape_string($_GET['post_id']), mysql_real_escape_string($_POST['comment_parent_id']));
+}
+
+if ($_POST['new_task_submit'])
+{
+	Blog :: create_task($blog_id, mysql_real_escape_string($_POST['task_name']), mysql_real_escape_string($_POST['task_description']), mysql_real_escape_string($_POST['chkArticleDelete']), mysql_real_escape_string($_POST['chkArticleEdit']), mysql_real_escape_string($_POST['chkCommentsDelete']), mysql_real_escape_string($_POST['task_color']));
+}
+if ($_POST['edit_task_submit'])
+{
+	Blog :: edit_task(mysql_real_escape_string($_POST['blog_id']), mysql_real_escape_string($_POST['task_id']), mysql_real_escape_string($_POST['task_name']), mysql_real_escape_string($_POST['task_description']), mysql_real_escape_string($_POST['chkArticleDelete']), mysql_real_escape_string($_POST['chkArticleEdit']), mysql_real_escape_string($_POST['chkCommentsDelete']), mysql_real_escape_string($_POST['task_color']));
+}
+if ($_POST['assign_task_submit'])
+{
+	Blog :: assign_task($blog_id, mysql_real_escape_string($_POST['task_user_id']), mysql_real_escape_string($_POST['task_task_id']), mysql_real_escape_string($_POST['task_year'])."-".mysql_real_escape_string($_POST['task_month'])."-".mysql_real_escape_string($_POST['task_day']));
+}
+
+if ($_POST['assign_task_edit_submit'])
+{
+	Blog :: edit_assigned_task($blog_id, mysql_real_escape_string($_POST['task_user_id']), mysql_real_escape_string($_POST['task_task_id']), mysql_real_escape_string($_POST['task_year'])."-".mysql_real_escape_string($_POST['task_month'])."-".mysql_real_escape_string($_POST['task_day']), mysql_real_escape_string($_POST['old_user_id']), mysql_real_escape_string($_POST['old_task_id']), mysql_real_escape_string($_POST['old_target_date']));
+}
+if ($_POST['new_task_execution_submit'])
+{
+	Blog :: create_comment(mysql_real_escape_string($_POST['comment_title']), mysql_real_escape_string($_POST['comment_text']), $blog_id, mysql_real_escape_string($_GET['post_id']), mysql_real_escape_string($_POST['comment_parent_id']), mysql_real_escape_string($_POST['task_id']));
+}
+if ($_POST['register'])
+{
+	foreach ($_POST['user'] as $index => $user_id)
+	{
+		Blog :: set_user_subscribed(mysql_real_escape_string($_GET['blog_id']), mysql_real_escape_string($user_id));
+	}
+}
+if ($_POST['unregister'])
+{
+	foreach ($_POST['user'] as $index => $user_id)
+	{
+		Blog :: set_user_unsubscribed(mysql_real_escape_string($_GET['blog_id']), mysql_real_escape_string($user_id));
+	}
+}
+if ($_GET['register'])
+{
+	Blog :: set_user_subscribed(mysql_real_escape_string($_GET['blog_id']), mysql_real_escape_string($_GET['user_id']));
+	$flag = 1;
+}
+if ($_GET['unregister'])
+{
+	Blog :: set_user_unsubscribed(mysql_real_escape_string($_GET['blog_id']), mysql_real_escape_string($_GET['user_id']));
+}
+
+if ($_GET['action'] == 'manage_tasks')
+{
+	if ($_GET['do'] == 'delete')
+		Blog :: delete_task($blog_id, mysql_real_escape_string($_GET['task_id']));
+
+	if ($_GET['do'] == 'delete_assignment')
+		Blog :: delete_assigned_task($blog_id, mysql_real_escape_string($_GET['assignment_id']));
+}
+
+if ($_GET['action'] == 'view_post')
+{
+	$task_id = (isset ($_GET['task_id']) && is_numeric($_GET['task_id'])) ? $_GET['task_id'] : 0;
+
+	if ($_GET['do'] == 'delete_comment')
+	{
+		if (api_is_allowed_to_edit('BLOG_'.$blog_id, 'article_comments_delete', $task_id))
+		{
+			Blog :: delete_comment($blog_id, mysql_real_escape_string($_GET['comment_id']));
+		}
+		else
+		{
+			$error = true;
+			$message = get_lang('ActionNotAllowed');
+		}
+	}
+
+	if ($_GET['do'] == 'delete_article')
+	{
+		if (api_is_allowed_to_edit('BLOG_'.$blog_id, 'article_delete', $task_id))
+		{
+			Blog :: delete_post($blog_id, mysql_real_escape_string($_GET['article_id']));
+			$current_page = ''; // Article is gone, go to blog home
+		}
+		else
+		{
+			$error = true;
+			$message = get_lang('ActionNotAllowed');
+		}
+	}
+	if ($_GET['do'] == 'rate')
+	{
+		if ($_GET['type'] == 'post')
+		{
+			if (api_is_allowed_to_edit('BLOG_'.$blog_id, 'article_rate'))
+			{
+				Blog :: add_rating('post', $blog_id, mysql_real_escape_string($_GET['post_id']), mysql_real_escape_string($_GET['rating']));
+			}
+		}
+		if ($_GET['type'] == 'comment')
+		{
+			if (api_is_allowed_to_edit('BLOG_'.$blog_id, 'article_comments_add'))
+			{
+				Blog :: add_rating('comment', $blog_id, mysql_real_escape_string($_GET['comment_id']), mysql_real_escape_string($_GET['rating']));
+			}
+		}
+	}
+}
+/*
+==============================================================================
+	DISPLAY
+==============================================================================
+*/
+$htmlHeadXtra[] = "<script src=\"tbl_change.js\" type=\"text/javascript\" language=\"javascript\"></script>";
+
+// Set bredcrumb
+switch ($current_page)
+{
+	case "new_post" :
+		$nameTools = get_lang('langNewPost');
+		$interbreadcrumb[] = array ("url" => "blog.php?blog_id=$blog_id", "name" => Blog :: get_blog_title($blog_id));
+		Display :: display_header($nameTools, 'blogs');
+		break;
+	case "manage_tasks" :
+		$nameTools = get_lang('langTaskManager');
+		$interbreadcrumb[] = array ("url" => "blog.php?blog_id=$blog_id", "name" => Blog :: get_blog_title($blog_id));
+		Display :: display_header($nameTools, 'blogs');
+		break;
+	case "manage_members" :
+		$nameTools = get_lang('langMemberManager');
+		$interbreadcrumb[] = array ("url" => "blog.php?blog_id=$blog_id", "name" => Blog :: get_blog_title($blog_id));
+		Display :: display_header($nameTools, 'blogs');
+		break;
+	case "manage_rights" :
+		$nameTools = get_lang('langRightsManager');
+		$interbreadcrumb[] = array ("url" => "blog.php?blog_id=$blog_id", "name" => Blog :: get_blog_title($blog_id));
+		Display :: display_header($nameTools, 'blogs');
+		break;
+	case "view_search_result" :
+		$nameTools = get_lang('langSearchResults');
+		$interbreadcrumb[] = array ("url" => "blog.php?blog_id=$blog_id", "name" => Blog :: get_blog_title($blog_id));
+		Display :: display_header($nameTools, 'blogs');
+		break;
+	case "execute_task" :
+		$nameTools = get_lang('langExecuteThisTask');
+		$interbreadcrumb[] = array ("url" => "blog.php?blog_id=$blog_id", "name" => Blog :: get_blog_title($blog_id));
+		Display :: display_header($nameTools, 'blogs');
+		break;
+	default :
+		$nameTools = Blog :: get_blog_title($blog_id);
+		Display :: display_header($nameTools, 'blogs');
+}
+
+//Display::display_header($nameTools,'Blogs');
+?>
+<span class="blog_title"><?php echo Blog::get_blog_title($blog_id) ?></span><br />
+<span class="blog_subtitle"><?php echo Blog::get_blog_subtitle($blog_id) ?></span>
+<br /><br />
+<table width="100%">
+<tr>
+	<td width="220" class="blog_left" valign="top">
+		<?php
+
+
+$month = $_GET['month'] ? $_GET['month'] : (int) date('m');
+$year = $_GET['year'] ? $_GET['year'] : date('Y');
+Blog :: display_minimonthcalendar($month, $year, $blog_id);
+?>
+		<br />
+		<table width="100%">
+			<tr>
+				<td class="blog_menu_title"><?php echo get_lang('langThisBlog') ?></td>
+			</tr>
+			<tr>
+				<td class="blog_menu">
+					<ul>
+						<li><a href="<?php echo $_SERVER['PHP_SELF'] ?>?blog_id=<?php echo $blog_id ?>" title="<?php echo get_lang('langHome') ?>"><?php echo get_lang('langHome') ?></a></li>
+						<?php if(api_is_allowed_to_edit('BLOG_'.$blog_id, 'article_add')) { ?><li><a href="<?php echo $_SERVER['PHP_SELF'] ?>?action=new_post&amp;blog_id=<?php echo $blog_id ?>" title="<?php echo get_lang('langNewPost') ?>"><?php echo get_lang('langNewPost') ?></a></li><?php } ?>
+						<?php if(api_is_allowed_to_edit('BLOG_'.$blog_id, 'task_management')) { ?><li><a href="<?php echo $_SERVER['PHP_SELF'] ?>?action=manage_tasks&amp;blog_id=<?php echo $blog_id ?>" title="<?php echo get_lang('langManageTasks') ?>"><?php echo get_lang('langTaskManager') ?></a></li> <?php } ?>
+						<?php if(api_is_allowed_to_edit('BLOG_'.$blog_id, 'member_management')) { ?><li><a href="<?php echo $_SERVER['PHP_SELF'] ?>?action=manage_members&amp;blog_id=<?php echo $blog_id ?>" title="<?php echo get_lang('langManageMembers') ?>"><?php echo get_lang('langMemberManager') ?></a></li><?php } ?>
+					</ul>
+				</td>
+			</tr>
+		</table>
+		<br />
+		<table width="100%">
+			<tr>
+				<td class="blog_menu_title"><?php echo get_lang('langSearch') ?></td>
+			</tr>
+			<tr>
+				<td class="blog_menu">
+					<form action="blog.php" method="get" enctype="multipart/form-data">
+						<input type="hidden" name="blog_id" value="<?php echo $blog_id ?>" />
+						<input type="hidden" name="action" value="view_search_result" />
+						<input type="text" size="20" name="q" value="<?php echo (isset($_GET['q']) ? $_GET['q'] : ''); ?>" /><input type="submit" value="Go" />
+					</form>
+				</td>
+			</tr>
+		</table>
+		<br />
+		<table width="100%">
+			<tr>
+				<td class="blog_menu_title"><?php echo get_lang('langMyTasks') ?></td>
+			</tr>
+			<tr>
+				<td class="blog_menu">
+					<?php Blog::get_personal_task_list(); ?>
+				</td>
+			</tr>
+		</table>
+		<!--
+		<br />
+		<table width="100%">
+			<tr>
+				<td class="blog_menu_title"><?php echo get_lang('langFavoriteBlogs') ?></td>
+			</tr>
+			<tr>
+				<td class="blog_menu">
+					<ul>
+						<li>Favorite 1</li>
+						<li>Favorite 2</li>
+						<li>Favorite 3</li>
+					</ul>
+				</td>
+			</tr>
+		</table>
+		<br />
+		<table width="100%">
+			<tr>
+				<td class="blog_menu_title"><?php echo get_lang('langTopTen') ?></td>
+			</tr>
+			<tr>
+				<td class="blog_menu">
+					<ul>
+						<li>Blog 1</li>
+						<li>Blog 2</li>
+						<li>Blog 3</li>
+					</ul>
+				</td>
+			</tr>
+		</table>
+	-->
+	</td>
+	<td valign="top" class="blog_right">
+		<?php
+
+
+if ($error)
+	Display :: display_error_message($message);
+
+if ($flag == '1')
+{
+	$current_page = "manage_tasks";
+	Blog :: display_assign_task_form($blog_id);
+}
+
+$user_task = false;
+
+if (isset ($_GET['task_id']) && is_numeric($_GET['task_id']))
+	$task_id = $_GET['task_id'];
+else
+{
+	$task_id = 0;
+
+	$tbl_blogs_tasks_rel_user = Database :: get_course_table(BLOGS_TASKS_REL_USER);
+
+	$sql = "
+							SELECT COUNT(*) as `number`
+							FROM ".$tbl_blogs_tasks_rel_user."
+							WHERE
+								`blog_id` = ".$blog_id." AND
+								`user_id` = ".$_uid." AND
+								`task_id` = ".$task_id;
+
+	$result = api_sql_query($sql, __LINE__, __FILE__);
+	$row = mysql_fetch_array($result, MYSQL_ASSOC);
+
+	if ($row['number'] == 1)
+		$user_task = true;
+}
+
+switch ($current_page)
+{
+	case 'new_post' :
+		if (api_is_allowed_to_edit('BLOG_'.$blog_id, 'article_add', $user_task ? $task_id : 0))
+		{
+			Blog :: display_form_new_post($blog_id);
+		}
+		else
+		{
+			api_not_allowed();
+		}
+		break;
+	case 'view_post' :
+		Blog :: display_post($blog_id, mysql_real_escape_string($_GET['post_id']));
+		break;
+	case 'edit_post' :
+		$task_id = (isset ($_GET['task_id']) && is_numeric($_GET['task_id'])) ? $_GET['task_id'] : 0;
+
+		if (api_is_allowed_to_edit('BLOG_'.$blog_id, 'article_edit', $task_id))
+			Blog :: display_form_edit_post($blog_id, mysql_real_escape_string($_GET['post_id']));
+		else
+			api_not_allowed();
+
+		break;
+	case 'manage_members' :
+		if (api_is_allowed_to_edit('BLOG_'.$blog_id, 'member_management'))
+		{
+			Blog :: display_form_user_subscribe($blog_id);
+			echo '<br /><br />';
+			Blog :: display_form_user_unsubscribe($blog_id);
+		}
+		else
+			api_not_allowed();
+
+		break;
+	case 'manage_rights' :
+		Blog :: display_form_user_rights($blog_id);
+		break;
+	case 'manage_tasks' :
+		if (api_is_allowed_to_edit('BLOG_'.$blog_id, 'task_management'))
+		{
+			if ($_GET['do'] == 'add')
+			{
+				Blog :: display_new_task_form($blog_id);
+			}
+			if ($_GET['do'] == 'assign')
+			{
+				Blog :: display_assign_task_form($blog_id);
+			}
+			if ($_GET['do'] == 'edit')
+			{
+				Blog :: display_edit_task_form($blog_id, mysql_real_escape_string($_GET['task_id']));
+			}
+			if ($_GET['do'] == 'edit_assignment')
+			{
+				Blog :: display_edit_assigned_task_form($blog_id, mysql_real_escape_string($_GET['assignment_id']));
+			}
+			Blog :: display_task_list($blog_id);
+			echo '<br /><br />';
+			Blog :: display_assigned_task_list($blog_id);
+			echo '<br /><br />';
+			if (api_is_allowed_to_edit('BLOG_'.$blog_id, 'role_management'))
+			{
+			?>
+				<a href="<?php echo $_SERVER['PHP_SELF'] ?>?action=manage_rights&amp;blog_id=<?php echo $blog_id ?>" title="<?php echo get_lang('langManageRights') ?>"><?php echo get_lang('langRightsManager') ?></a>
+			<?php
+			}
+		}
+		else
+			api_not_allowed();
+
+		break;
+	case 'execute_task' :
+		if (isset ($_GET['post_id']))
+			Blog :: display_post($blog_id, mysql_real_escape_string($_GET['post_id']));
+		else
+			Blog :: display_select_task_post($blog_id, mysql_real_escape_string($_GET['task_id']));
+
+		break;
+	case 'view_search_result' :
+		Blog :: display_search_results($blog_id, mysql_real_escape_string($_GET['q']));
+		break;
+	case '' :
+	default :
+		if (isset ($_GET['filter']) && !empty ($_GET['filter']))
+		{
+			Blog :: display_day_results($blog_id, mysql_real_escape_string($_GET['filter']));
+		}
+		else
+		{
+			Blog :: display_blog_posts($blog_id);
+		}
+}
+?>
+	</td>
+</tr>
+</table>
+
+<?php
+
+
+// The footer is displayed only if we are not in the learnpath
+if ($_GET['origin'] != 'learnpath')
+{
+	include ($includePath."/claro_init_footer.inc.php");
+}
+?>

+ 123 - 0
main/blog/blog_admin.php

@@ -0,0 +1,123 @@
+<?php
+/*
+==============================================================================
+	Dokeos - elearning and course management software
+
+	Copyright (c) 2004 Dokeos S.A.
+	Copyright (c) 2003 University of Ghent (UGent)
+	Copyright (c) 2001 Universite catholique de Louvain (UCL)
+	Copyright (c) various contributors
+
+	For a full list of contributors, see "credits.txt".
+	The full license can be read in "license.txt".
+
+	This program is free software; you can redistribute it and/or
+	modify it under the terms of the GNU General Public License
+	as published by the Free Software Foundation; either version 2
+	of the License, or (at your option) any later version.
+
+	See the GNU General Public License for more details.
+
+	Contact: Dokeos, 181 rue Royale, B-1000 Brussels, Belgium, info@dokeos.com
+
+============================================================================== 
+
+    BLOG HOMEPAGE
+
+	This file takes care of all blog navigation and displaying.
+
+	@package dokeos.blogs
+============================================================================== 
+*/
+
+// Init
+$langFile = "blog";
+
+include('../inc/global.inc.php');
+require_once(api_get_path(LIBRARY_PATH) . "blog.lib.php");
+
+$nameTools = get_lang("blog_management");
+
+
+// showing the header if we are not in the learning path, if we are in 
+// the learning path, we do not include the banner so we have to explicitly 
+// include the stylesheet, which is normally done in the header
+if ($_GET['origin'] != 'learnpath') 
+{ 	
+	Display::display_header($nameTools,'Blogs');
+}
+else 
+{
+	echo "<link rel=\"stylesheet\" type=\"text/css\" href=\"".$clarolineRepositoryWeb."css/default.css\"/>";
+}
+/*
+==============================================================================
+	PROCESSING..
+============================================================================== 
+*/
+if ($_POST['new_blog_submit'])
+{
+	Blog::create_blog(mysql_real_escape_string($_POST['blog_name']),mysql_real_escape_string($_POST['blog_subtitle']));
+}
+if ($_POST['edit_blog_submit'])
+{
+	Blog::edit_blog(mysql_real_escape_string($_POST['blog_id']),mysql_real_escape_string($_POST['blog_name']),mysql_real_escape_string($_POST['blog_subtitle']));
+}
+if ($_GET['action'] == 'visibility')
+{	
+	Blog::change_blog_visibility(mysql_real_escape_string($_GET['blog_id']));
+}
+if ($_GET['action'] == 'delete')
+{
+	Blog::delete_blog(mysql_real_escape_string($_GET['blog_id']));
+}
+
+
+/*
+==============================================================================
+	DISPLAY
+============================================================================== 
+*/
+api_display_tool_title($nameTools);
+//api_introductionsection(TOOL_BLOG);
+
+
+	if ($_GET['action'] == 'add')
+	{
+		Blog::display_new_blog_form();
+	}
+	if ($_GET['action'] == 'edit')
+	{
+		Blog::display_edit_blog_form(mysql_real_escape_string($_GET['blog_id']));
+	}
+
+	echo "<a href='".$_SERVER['PHP_SELF']."?action=add'>",
+	"<img src='../img/blog.gif' border=\"0\" align=\"absmiddle\" alt='scormbuilder'>&nbsp;&nbsp;".get_lang('langAddBlog')."</a>";
+	echo "<table width=\"100%\" border=\"0\" cellspacing=\"2\" class='data_table'>";
+	echo	"<tr bgcolor=\"$color2\" align=\"center\" valign=\"top\">",
+				 "<td width='290'><b>",get_lang("langTitle"),"</b></td>\n",
+				 "<td><b>",get_lang("langSubtitle"),"</b></td>\n",
+				 "<td width='200'><b>",get_lang("Modify"),"</b></td>\n",
+			"</tr>\n";
+	Blog::display_blog_list();
+	echo "</table>";
+
+
+// The footer is displayed only if we are not in the learnpath
+if ($_GET['origin'] != 'learnpath') 
+{ 
+	include($includePath."/claro_init_footer.inc.php");
+}
+
+
+
+
+
+/*
+==============================================================================
+	FUNCTIONS
+============================================================================== 
+*/
+
+
+?>

+ 376 - 0
main/blog/blog_backup_may3_surbhi.php

@@ -0,0 +1,376 @@
+<?php
+/*
+==============================================================================
+	Dokeos - elearning and course management software
+
+	Copyright (c) 2004 Dokeos S.A.
+	Copyright (c) 2003 University of Ghent (UGent)
+	Copyright (c) 2001 Universite catholique de Louvain (UCL)
+	Copyright (c) various contributors
+
+	For a full list of contributors, see "credits.txt".
+	The full license can be read in "license.txt".
+
+	This program is free software; you can redistribute it and/or
+	modify it under the terms of the GNU General Public License
+	as published by the Free Software Foundation; either version 2
+	of the License, or (at your option) any later version.
+
+	See the GNU General Public License for more details.
+
+	Contact: Dokeos, 181 rue Royale, B-1000 Brussels, Belgium, info@dokeos.com
+
+============================================================================== 
+
+    BLOG HOMEPAGE
+
+	This file takes care of all blog navigation and displaying.
+
+	@package dokeos.blogs
+============================================================================== 
+*/
+
+/*
+==============================================================================
+	INIT
+============================================================================== 
+*/
+$langFile = "blog";
+$blog_id = intval($_GET['blog_id']);
+include('../inc/claro_init_global.inc.php');
+require_once(api_get_library_path() . "/display.lib.php");
+require_once(api_get_library_path() . "/text.lib.php");
+require_once(api_get_library_path() . "/blog.lib.php");
+require_once(api_get_library_path() . "/fckeditor.lib.php");
+$nameTools = get_lang("blogs");
+$DaysShort = array (get_lang("SundayShort"), get_lang("MondayShort"), get_lang("TuesdayShort"), get_lang("WednesdayShort"), get_lang("ThursdayShort"), get_lang("FridayShort"), get_lang("SaturdayShort"));
+$DaysLong = array (get_lang("SundayLong"), get_lang("MondayLong"), get_lang("TuesdayLong"), get_lang("WednesdayLong"), get_lang("ThursdayLong"), get_lang("FridayLong"), get_lang("SaturdayLong"));
+$MonthsLong = array (get_lang("JanuaryLong"), get_lang("FebruaryLong"), get_lang("MarchLong"), get_lang("AprilLong"), get_lang("MayLong"), get_lang("JuneLong"), get_lang("JulyLong"), get_lang("AugustLong"), get_lang("SeptemberLong"), get_lang("OctoberLong"), get_lang("NovemberLong"), get_lang("DecemberLong"));
+
+$current_page = $_GET['action'];
+
+/*
+==============================================================================
+	PROCESSING
+============================================================================== 
+*/
+if ($_POST['new_post_submit'])
+{
+	Blog::create_post(mysql_real_escape_string($_POST['post_title']), mysql_real_escape_string($_POST['post_full_text']),$blog_id);
+}
+if ($_POST['edit_post_submit'])
+{
+	Blog::edit_post(mysql_real_escape_string($_POST['post_id']), mysql_real_escape_string($_POST['post_title']), mysql_real_escape_string($_POST['post_full_text']),$blog_id);
+}
+if ($_POST['new_comment_submit'])
+{
+	Blog::create_comment(mysql_real_escape_string($_POST['comment_title']),mysql_real_escape_string($_POST['comment_text']),$blog_id,mysql_real_escape_string($_GET['post_id']),mysql_real_escape_string($_POST['comment_parent_id']));
+}
+if ($_POST['new_task_submit'])
+{
+	Blog::create_task($blog_id,mysql_real_escape_string($_POST['task_name']),mysql_real_escape_string($_POST['task_description']),mysql_real_escape_string($_POST['task_color']));
+}
+if ($_POST['edit_task_submit'])
+{
+	Blog::edit_task(mysql_real_escape_string($_POST['task_id']),mysql_real_escape_string($_POST['task_name']),mysql_real_escape_string($_POST['task_description']),mysql_real_escape_string($_POST['task_color']));
+}
+if ($_POST['assign_task_submit'])
+{
+	Blog::assign_task($blog_id,mysql_real_escape_string($_POST['task_user_id']),mysql_real_escape_string($_POST['task_task_id']),mysql_real_escape_string($_POST['task_year'])."-".mysql_real_escape_string($_POST['task_month'])."-".mysql_real_escape_string($_POST['task_day']));
+}
+if ($_POST['new_task_execution_submit'])
+{
+	Blog::create_comment(mysql_real_escape_string($_POST['comment_title']),mysql_real_escape_string($_POST['comment_text']),$blog_id,mysql_real_escape_string($_GET['post_id']),mysql_real_escape_string($_POST['comment_parent_id']), mysql_real_escape_string($_POST['task_id']));
+}
+if ($_POST['register'])
+{
+	foreach($_POST['user'] as $index => $user_id)
+	{
+		Blog::set_user_subscribed(mysql_real_escape_string($_GET['blog_id']),mysql_real_escape_string($user_id));
+	}
+}
+if ($_POST['unregister'])
+{
+	foreach($_POST['user'] as $index => $user_id)
+	{
+		Blog::set_user_unsubscribed(mysql_real_escape_string($_GET['blog_id']),mysql_real_escape_string($user_id));
+	}
+}
+if ($_GET['register'])
+{
+	Blog::set_user_subscribed(mysql_real_escape_string($_GET['blog_id']),mysql_real_escape_string($_GET['user_id']));
+}
+if ($_GET['unregister'])
+{
+	Blog::set_user_unsubscribed(mysql_real_escape_string($_GET['blog_id']),mysql_real_escape_string($_GET['user_id']));
+}
+if ($_GET['action'] == 'manage_tasks')
+{
+	if ($_GET['do'] == 'delete')
+	{
+		Blog::delete_task($blog_id, mysql_real_escape_string($_GET['task_id']));
+	}
+	// assigned tasks
+	if ($_GET['do'] == 'delete_assignment')
+	{
+		Blog::delete_assigned_task($blog_id, mysql_real_escape_string($_GET['assignment_id']));
+	}
+	if ($_GET['do'] == 'edit_assignment')
+	{
+		Blog::display_edit_assigned_task_form($blog_id, mysql_real_escape_string($_GET['assignment_id']));
+	}
+}
+if ($_GET['action'] == 'view_post')
+{
+	if ($_GET['do'] == 'delete_comment')
+	{
+		if(api_is_allowed_to_edit('BLOG_'.$blog_id, 'article_comments_delete')) {
+			Blog::delete_comment($blog_id, mysql_real_escape_string($_GET['comment_id']));
+		}
+		else
+		{
+			$error = true;
+			$message = get_lang('ActionNotAllowed');
+		}
+	}
+	if ($_GET['do'] == 'delete_article')
+	{
+		if(api_is_allowed_to_edit('BLOG_'.$blog_id, 'article_delete')) {
+			Blog::delete_post($blog_id, mysql_real_escape_string($_GET['article_id']));
+			$current_page = ''; // Article is gone, go to blog home
+		}
+		else
+		{
+			$error = true;
+			$message = get_lang('ActionNotAllowed');
+		}
+	}
+	if ($_GET['do'] == 'rate')
+	{
+		if ($_GET['type'] == 'post')
+		{
+			if(api_is_allowed_to_edit('BLOG_'.$blog_id, 'article_rate')) {
+				Blog::add_rating('post',$blog_id, mysql_real_escape_string($_GET['post_id']), mysql_real_escape_string($_GET['rating']));
+			}
+		}
+		if ($_GET['type'] == 'comment')
+		{
+			if(api_is_allowed_to_edit('BLOG_'.$blog_id, 'article_comments_add')) {
+				Blog::add_rating('comment',$blog_id, mysql_real_escape_string($_GET['comment_id']), mysql_real_escape_string($_GET['rating']));
+			}
+		}
+	}
+}
+/*
+==============================================================================
+	DISPLAY
+============================================================================== 
+*/
+$htmlHeadXtra[] = "<script src=\"tbl_change.js\" type=\"text/javascript\" language=\"javascript\"></script>";
+
+// Set bredcrumb
+switch ($current_page)
+{
+	case "new_post":
+		$nameTools = get_lang('langNewPost');
+		$interbreadcrumb[] = array ("url" => "blog.php?blog_id=$blog_id", "name" => Blog::get_blog_title($blog_id));
+		Display::display_header($nameTools,'blogs');
+		break;
+	case "manage_tasks":
+		$nameTools = get_lang('langTaskManager');
+		$interbreadcrumb[] = array ("url" => "blog.php?blog_id=$blog_id", "name" => Blog::get_blog_title($blog_id));
+		Display::display_header($nameTools,'blogs');
+		break;
+	case "manage_members":
+		$nameTools = get_lang('langMemberManager');
+		$interbreadcrumb[] = array ("url" => "blog.php?blog_id=$blog_id", "name" => Blog::get_blog_title($blog_id));
+		Display::display_header($nameTools,'blogs');
+		break;
+	case "manage_rights":
+		$nameTools = get_lang('langRightsManager');
+		$interbreadcrumb[] = array ("url" => "blog.php?blog_id=$blog_id", "name" => Blog::get_blog_title($blog_id));
+		Display::display_header($nameTools,'blogs');
+		break;
+	case "view_search_result":
+		$nameTools = get_lang('langSearchResults');
+		$interbreadcrumb[] = array ("url" => "blog.php?blog_id=$blog_id", "name" => Blog::get_blog_title($blog_id));
+		Display::display_header($nameTools,'blogs');
+		break;
+	case "execute_task":
+		$nameTools = get_lang('langExecuteThisTask');
+		$interbreadcrumb[] = array ("url" => "blog.php?blog_id=$blog_id", "name" => Blog::get_blog_title($blog_id));
+		Display::display_header($nameTools,'blogs');
+		break;
+	default:
+		$nameTools = Blog::get_blog_title($blog_id);
+		Display::display_header($nameTools,'blogs');
+}
+
+//Display::display_header($nameTools,'Blogs');
+
+?>
+<span class="blog_title"><?php echo Blog::get_blog_title($blog_id) ?></span><br />
+<span class="blog_subtitle"><?php echo Blog::get_blog_subtitle($blog_id) ?></span>
+<br /><br />
+<table width="100%">
+<tr>
+	<td width="220" class="blog_left" valign="top">
+		<?php
+			$month = $_GET['month'] ? $_GET['month'] : (int)date('m');
+			$year = $_GET['year'] ? $_GET['year'] : date('Y');
+			Blog::display_minimonthcalendar($month, $year, $blog_id);
+		?>
+		<br />
+		<table width="100%">
+			<tr>
+				<td class="blog_menu_title"><?php echo get_lang('langThisBlog') ?></td>
+			</tr>
+			<tr>
+				<td class="blog_menu">
+					<ul>
+						<li><a href="<?php echo $_SERVER['PHP_SELF'] ?>?blog_id=<?php echo $blog_id ?>" title="<?php echo get_lang('langHome') ?>"><?php echo get_lang('langHome') ?></a></li>
+						<?php if(api_is_allowed_to_edit('BLOG_'.$blog_id, 'article_add')) { ?><li><a href="<?php echo $_SERVER['PHP_SELF'] ?>?action=new_post&amp;blog_id=<?php echo $blog_id ?>" title="<?php echo get_lang('langNewPost') ?>"><?php echo get_lang('langNewPost') ?></a></li><?php } ?>
+						<?php if(api_is_allowed_to_edit('BLOG_'.$blog_id, 'task_management')) { ?><li><a href="<?php echo $_SERVER['PHP_SELF'] ?>?action=manage_tasks&amp;blog_id=<?php echo $blog_id ?>" title="<?php echo get_lang('langManageTasks') ?>"><?php echo get_lang('langTaskManager') ?></a></li> <?php } ?>
+						<?php if(api_is_allowed_to_edit('BLOG_'.$blog_id, 'member_management')) { ?><li><a href="<?php echo $_SERVER['PHP_SELF'] ?>?action=manage_members&amp;blog_id=<?php echo $blog_id ?>" title="<?php echo get_lang('langManageMembers') ?>"><?php echo get_lang('langMemberManager') ?></a></li><?php } ?>
+						<?php if(api_is_allowed_to_edit('BLOG_'.$blog_id, 'role_management')) { ?><li><a href="<?php echo $_SERVER['PHP_SELF'] ?>?action=manage_rights&amp;blog_id=<?php echo $blog_id ?>" title="<?php echo get_lang('langManageRights') ?>"><?php echo get_lang('langRightsManager') ?></a></li><?php } ?>
+					</ul>
+				</td>
+			</tr>
+		</table>
+		<br />
+		<table width="100%">
+			<tr>
+				<td class="blog_menu_title"><?php echo get_lang('langSearch') ?></td>
+			</tr>
+			<tr>
+				<td class="blog_menu">
+					<form action="blog.php" method="get" enctype="multipart/form-data">
+						<input type="hidden" name="blog_id" value="<?php echo $blog_id ?>" />
+						<input type="hidden" name="action" value="view_search_result" />
+						<input type="text" size="20" name="q" value="<?php echo (isset($_GET['q']) ? $_GET['q'] : ''); ?>" /><input type="submit" value="Go" />
+					</form>
+				</td>
+			</tr>
+		</table>
+		<br />
+		<table width="100%">
+			<tr>
+				<td class="blog_menu_title"><?php echo get_lang('langMyTasks') ?></td>
+			</tr>
+			<tr>
+				<td class="blog_menu">
+					<?php Blog::get_personal_task_list(); ?>
+				</td>
+			</tr>
+		</table>
+		<!--
+		<br />
+		<table width="100%">
+			<tr>
+				<td class="blog_menu_title"><?php echo get_lang('langFavoriteBlogs') ?></td>
+			</tr>
+			<tr>
+				<td class="blog_menu">
+					<ul>
+						<li>Favorite 1</li>
+						<li>Favorite 2</li>
+						<li>Favorite 3</li>
+					</ul>
+				</td>
+			</tr>
+		</table>
+		<br />
+		<table width="100%">
+			<tr>
+				<td class="blog_menu_title"><?php echo get_lang('langTopTen') ?></td>
+			</tr>
+			<tr>
+				<td class="blog_menu">
+					<ul>
+						<li>Blog 1</li>
+						<li>Blog 2</li>
+						<li>Blog 3</li>
+					</ul>
+				</td>
+			</tr>
+		</table>
+	-->
+	</td>
+	<td valign="top" class="blog_right">
+		<?php
+			if ($error)
+			{
+				Display::display_error_message($message);
+			}
+			switch ($current_page)
+			{
+				case 'new_post':
+					Blog::display_form_new_post($blog_id);
+					break;
+				case 'view_post':
+					Blog::display_post($blog_id, mysql_real_escape_string($_GET['post_id']));
+					break;
+				case 'edit_post':
+					Blog::display_form_edit_post($blog_id, mysql_real_escape_string($_GET['post_id']));
+					break;
+				case 'manage_members':
+					Blog::display_form_user_subscribe($blog_id);
+					echo '<br /><br />';
+					Blog::display_form_user_unsubscribe($blog_id);
+					break;
+				case 'manage_rights':
+					Blog::display_form_user_rights($blog_id);
+					break;
+				case 'manage_tasks':
+					if ($_GET['do'] == 'add')
+					{
+						Blog::display_new_task_form($blog_id);
+					}
+					if ($_GET['do'] == 'assign')
+					{
+						Blog::display_assign_task_form($blog_id);
+					}
+					if ($_GET['do'] == 'edit')
+					{
+						Blog::display_edit_task_form($blog_id, mysql_real_escape_string($_GET['task_id']));
+					}
+					Blog::display_task_list($blog_id);
+					echo '<br /><br />';
+					Blog::display_assigned_task_list($blog_id);
+					break;
+				case 'execute_task':
+					if (isset($_GET['post_id']))
+					{
+						Blog::display_post($blog_id, mysql_real_escape_string($_GET['post_id']));
+					}
+					else
+					{
+						Blog::display_select_task_post($blog_id, mysql_real_escape_string($_GET['task_id']));
+					}
+					break;
+				case 'view_search_result':
+					Blog::display_search_results($blog_id,mysql_real_escape_string($_GET['q']));
+					break;
+				case '':
+				default:
+					if(isset($_GET['filter']) && !empty($_GET['filter']))
+					{
+						Blog::display_day_results($blog_id, mysql_real_escape_string($_GET['filter']));
+					}
+					else
+					{
+						Blog::display_blog_posts($blog_id);
+					}
+			}
+		 ?>
+	</td>
+</tr>
+</table>
+
+<?php
+// The footer is displayed only if we are not in the learnpath
+if ($_GET['origin'] != 'learnpath') 
+{ 
+	include($includePath."/claro_init_footer.inc.php");
+}
+?>

+ 130 - 0
main/blog/calendar.php

@@ -0,0 +1,130 @@
+<?php
+// including the relevant language file
+$langFile = "agenda";
+// including the claroline global 
+include('../inc/claro_init_global.inc.php');
+
+// the variables for the days and the months
+// Defining the shorts for the days
+$DaysShort = array(get_lang("SundayShort"), get_lang("MondayShort"), get_lang("TuesdayShort"), get_lang("WednesdayShort"), get_lang("ThursdayShort"), get_lang("FridayShort"), get_lang("SaturdayShort")); 
+// Defining the days of the week to allow translation of the days
+$DaysLong = array(get_lang("SundayLong"), get_lang("MondayLong"), get_lang("TuesdayLong"), get_lang("WednesdayLong"), get_lang("ThursdayLong"), get_lang("FridayLong"), get_lang("SaturdayLong")); 
+// Defining the months of the year to allow translation of the months
+$MonthsLong = array(get_lang("JanuaryLong"), get_lang("FebruaryLong"), get_lang("MarchLong"), get_lang("AprilLong"), get_lang("MayLong"), get_lang("JuneLong"), get_lang("JulyLong"), get_lang("AugustLong"), get_lang("SeptemberLong"), get_lang("OctoberLong"), get_lang("NovemberLong"), get_lang("DecemberLong")); 
+
+?>
+<html>
+<head>
+<title>Calendar</title>
+
+<style type="text/css">
+table.calendar
+{
+	width: 100%;	
+	font-size: 11px;
+	font-family: verdana, arial, helvetica, sans-serif;
+}
+table.calendar .monthyear
+{
+	background-color: #4171B5;
+	text-align: center;
+	color: #ffffff;
+}
+table.calendar .daynames
+{
+	background-color: #D3DFF1;
+	text-align: center;
+}
+table.calendar td
+{
+	width: 25px;
+	height: 25px;
+	background-color: #f5f5f5;	
+	text-align: center;
+}
+table.calendar td.selected
+{
+	border: 1px solid #ff0000; 
+	background-color: #FFCECE;
+}
+table.calendar td a
+{
+	width: 25px;
+	height: 25px;
+	text-decoration: none;
+}
+table.calendar td a:hover
+{
+	background-color: #ffff00;
+}
+table.calendar .monthyear a
+{
+	text-align: center;
+	color: #ffffff;
+}
+table.calendar .monthyear a:hover
+{
+	text-align: center;
+	color: #ff0000;
+	background-color: #ffff00;
+}
+</style>
+<script language="JavaScript" type="text/javascript">
+<!--
+    /* added 2004-06-10 by Michael Keck
+     *       we need this for Backwards-Compatibility and resolving problems
+     *       with non DOM browsers, which may have problems with css 2 (like NC 4)
+    */
+    var isDOM      = (typeof(document.getElementsByTagName) != 'undefined'
+                      && typeof(document.createElement) != 'undefined')
+                   ? 1 : 0;
+    var isIE4      = (typeof(document.all) != 'undefined'
+                      && parseInt(navigator.appVersion) >= 4)
+                   ? 1 : 0;
+    var isNS4      = (typeof(document.layers) != 'undefined')
+                   ? 1 : 0;
+    var capable    = (isDOM || isIE4 || isNS4)
+                   ? 1 : 0;
+    // Uggly fix for Opera and Konqueror 2.2 that are half DOM compliant
+    if (capable) {
+        if (typeof(window.opera) != 'undefined') {
+            var browserName = ' ' + navigator.userAgent.toLowerCase();
+            if ((browserName.indexOf('konqueror 7') == 0)) {
+                capable = 0;
+            }
+        } else if (typeof(navigator.userAgent) != 'undefined') {
+            var browserName = ' ' + navigator.userAgent.toLowerCase();
+            if ((browserName.indexOf('konqueror') > 0) && (browserName.indexOf('konqueror/3') == 0)) {
+                capable = 0;
+            }
+        } // end if... else if...
+    } // end if
+//-->
+</script>
+<script type="text/javascript" src="tbl_change.js"></script>
+<script type="text/javascript">
+<!--
+var month_names = new Array(
+<?php
+foreach($MonthsLong as $index => $month)
+{
+	echo '"'.$month.'",';
+}
+?>
+"");
+var day_names = new Array(
+<?php
+foreach($DaysShort as $index => $day)
+{
+	echo '"'.$day.'",';
+}
+?>
+"");
+//-->
+</script>
+</head>
+<body onload="initCalendar();">
+<div id="calendar_data"></div>
+<div id="clock_data"></div>
+</body>
+</html>

+ 159 - 0
main/blog/tbl_change.js

@@ -0,0 +1,159 @@
+var day;
+var month;
+var year;
+var hour;
+var minute;
+var second;
+var clock_set = 0;
+
+/**
+ * Opens calendar window.
+ *
+ * @param   string      form name
+ * @param   string      field name
+ */
+function openCalendar(form, field) {
+    window.open("./calendar.php", "calendar", "width=220,height=200,status=no");
+	day = eval("document." + form + "." + field + "day.options["+ "document." + form + "." + field + "day.selectedIndex].value");
+    month = eval("document." + form + "." + field + "month.options["+ "document." + form + "." + field + "month.selectedIndex].value");
+   	month = month-1;
+    year = eval("document." + form + "." + field + "year.options["+ "document." + form + "." + field + "year.selectedIndex].value");
+	formName = form;
+	fieldName =field;
+}
+
+/**
+ * Formats number to two digits.
+ *
+ * @param   int number to format.
+ */
+function formatNum2(i, valtype) {
+    f = (i < 10 ? '0' : '') + i;
+    if (valtype && valtype != '') {
+        switch(valtype) {
+            case 'month':
+                f = (f > 12 ? 12 : f);
+                break;
+
+            case 'day':
+                f = (f > 31 ? 31 : f);
+                break;
+        }
+    }
+
+    return f;
+}
+
+/**
+ * Formats number to four digits.
+ *
+ * @param   int number to format.
+ */
+function formatNum4(i) {
+    return (i < 1000 ? i < 100 ? i < 10 ? '000' : '00' : '0' : '') + i;
+}
+
+/**
+ * Initializes calendar window.
+ */
+function initCalendar() {
+    if (!year && !month && !day) {
+		day = window.opener.day;
+		month = window.opener.month;
+		year  = window.opener.year;   
+        if (isNaN(year) || isNaN(month) || isNaN(day) || day == 0) {
+            dt      = new Date();
+            year    = dt.getFullYear();
+            month   = dt.getMonth();
+            day     = dt.getDate();
+        }
+    } else {
+        /* Moving in calendar */
+        if (month > 11) {
+            month = 0;
+            year++;
+        }
+        if (month < 0) {
+            month = 11;
+            year--;
+        }
+    }
+
+    if (document.getElementById) {
+        cnt = document.getElementById("calendar_data");
+    } else if (document.all) {
+        cnt = document.all["calendar_data"];
+    }
+
+    cnt.innerHTML = "";
+
+    str = ""
+
+    //heading table
+    str += '<table class="calendar"><tr><th class="monthyear" width="50%">';
+    str += '<a href="javascript:month--; initCalendar();">&laquo;</a> ';
+    str += month_names[month];
+    str += ' <a href="javascript:month++; initCalendar();">&raquo;</a>';
+    str += '</th><th class="monthyear" width="50%">';
+    str += '<a href="javascript:year--; initCalendar();">&laquo;</a> ';
+    str += year;
+    str += ' <a href="javascript:year++; initCalendar();">&raquo;</a>';
+    str += '</th></tr></table>';
+
+    str += '<table class="calendar"><tr>';
+    for (i = 0; i < 7; i++) {
+        str += "<th  class='daynames'>" + day_names[i] + "</th>";
+    }
+    str += "</tr>";
+
+    var firstDay = new Date(year, month, 1).getDay();
+    var lastDay = new Date(year, month + 1, 0).getDate();
+
+    str += "<tr>";
+
+    dayInWeek = 0;
+    for (i = 0; i < firstDay; i++) {
+        str += "<td>&nbsp;</td>";
+        dayInWeek++;
+    }
+    for (i = 1; i <= lastDay; i++) {
+        if (dayInWeek == 7) {
+            str += "</tr><tr>";
+            dayInWeek = 0;
+        }
+
+        dispmonth = 1 + month;
+        actVal = formatNum4(year) + "-" + formatNum2(dispmonth, 'month') + "-" + formatNum2(i, 'day');
+        if (i == day) {
+            style = ' class="selected"';
+        } else {
+            style = '';
+        }
+        str += "<td" + style + "><a href=\"javascript:returnDate(" + i +","+month+","+year + ");\">" + i + "</a></td>"
+        dayInWeek++;
+    }
+    for (i = dayInWeek; i < 7; i++) {
+        str += "<td>&nbsp;</td>";
+    }
+
+    str += "</tr></table>";
+
+    cnt.innerHTML = str;
+}
+
+/**
+ * Returns date from calendar.
+ *
+ * @param   string     date text
+ */
+function returnDate(d,m,y) {
+	cmd = "window.opener.document."+window.opener.formName+"."+window.opener.fieldName+"day.selectedIndex = "+(d-1);
+	eval(cmd);
+	cmd = "window.opener.document."+window.opener.formName+"."+window.opener.fieldName+"month.selectedIndex = "+m;
+	eval(cmd);
+	date = new Date();
+    year = date.getFullYear()-1;
+	cmd = "window.opener.document."+window.opener.formName+"."+window.opener.fieldName+"year.selectedIndex = "+(y-year);
+	eval(cmd);
+    window.close();
+}

+ 2172 - 0
main/calendar/agenda.inc.php

@@ -0,0 +1,2172 @@
+<?php //$Id: agenda.inc.php 9414 2006-10-10 12:59:14Z sbil136 $
+/*
+==============================================================================
+	Dokeos - elearning and course management software
+
+	Copyright (c) 2004-2005 Dokeos S.A.
+	Copyright (c) 2003 Ghent University (UGent)
+	Copyright (c) 2001 Universite catholique de Louvain (UCL)
+
+	For a full list of contributors, see "credits.txt".
+	The full license can be read in "license.txt".
+
+	This program is free software; you can redistribute it and/or
+	modify it under the terms of the GNU General Public License
+	as published by the Free Software Foundation; either version 2
+	of the License, or (at your option) any later version.
+
+	See the GNU General Public License for more details.
+
+	Contact address: Dokeos, 44 rue des palais, B-1030 Brussels, Belgium
+	Mail: info@dokeos.com
+==============================================================================
+	@author: Patrick Cool, patrick.cool@UGent.be
+	@version: 1.1
+	@todo: synchronisation with the function in myagenda.php (for instance: using one function for the mini_calendar
+==============================================================================
+	Large parts of the code are recycled from the old agenda tool, but I
+	reworked it and cleaned the code to make it more readable. The code for
+	the small calender on the left is taken from the My Agenda tool.
+
+	Reabability is also the reason why I use the if ($is_allowedToEdit)
+	check for each part of the code. I'm aware that is duplication, but
+	it makes the code much easier to read.
+==============================================================================
+*/
+
+/*
+-----------------------------------------------------------
+	Constants and variables 
+-----------------------------------------------------------
+*/
+// the variables for the days and the months
+// Defining the shorts for the days
+$DaysShort = array (get_lang("SundayShort"), get_lang("MondayShort"), get_lang("TuesdayShort"), get_lang("WednesdayShort"), get_lang("ThursdayShort"), get_lang("FridayShort"), get_lang("SaturdayShort"));
+// Defining the days of the week to allow translation of the days
+$DaysLong = array (get_lang("SundayLong"), get_lang("MondayLong"), get_lang("TuesdayLong"), get_lang("WednesdayLong"), get_lang("ThursdayLong"), get_lang("FridayLong"), get_lang("SaturdayLong"));
+// Defining the months of the year to allow translation of the months
+$MonthsLong = array (get_lang("JanuaryLong"), get_lang("FebruaryLong"), get_lang("MarchLong"), get_lang("AprilLong"), get_lang("MayLong"), get_lang("JuneLong"), get_lang("JulyLong"), get_lang("AugustLong"), get_lang("SeptemberLong"), get_lang("OctoberLong"), get_lang("NovemberLong"), get_lang("DecemberLong"));
+
+/*
+============================================================================== 
+		FUNCTIONS
+============================================================================== 
+*/
+
+/**
+* Retrieves all the agenda items from the table
+* @author: Patrick Cool <patrick.cool@UGent.be>, Ghent University
+* @param integer $month: the integer value of the month we are viewing
+* @param integer $year: the 4-digit year indication e.g. 2005
+* @return array
+*/
+function get_kalender_items($month, $year)
+{
+	global $courseTablePrefix, $dbGlu;
+	global $_uid, $_course;
+	global $is_allowedToEdit;
+
+	// database variables
+	$TABLEAGENDA=Database::get_course_table(AGENDA_TABLE);
+	$TABLE_ITEM_PROPERTY=Database::get_course_table(LAST_TOOL_EDIT_TABLE);
+
+	$group_memberships=GroupManager::get_group_ids($_course['dbName'], $_uid);
+
+	if (is_allowed_to_edit() OR api_get_course_setting('allow_user_edit_agenda'))
+	{
+		//echo "course admin";
+		// added GROUP BY `agenda`.`id` to prevent double display of a message that has been sent to two groups
+		$sql="SELECT
+			DISTINCT agenda.*, toolitemproperties.*
+			FROM ".$TABLEAGENDA." agenda, ".$TABLE_ITEM_PROPERTY." toolitemproperties
+			WHERE `agenda`.`id` = `toolitemproperties`.`ref`   ".$show_all_current."
+			AND MONTH(`agenda`.`start_date`)='".$month."' AND YEAR(`agenda`.`start_date`)='".$year."'
+			AND `toolitemproperties`.`tool`='".TOOL_CALENDAR_EVENT."'
+			AND `toolitemproperties`.`visibility`='1'
+			GROUP BY `agenda`.`id`
+			ORDER BY  start_date ".$sort;
+	}
+	// if the user is not an administrator of that course
+	else
+	{
+		//echo "GEEN course admin";
+		if (is_array($group_memberships))
+		{
+			$sql="SELECT
+				agenda.*, toolitemproperties.*
+				FROM ".$TABLEAGENDA." agenda,	".$TABLE_ITEM_PROPERTY." toolitemproperties
+				WHERE `agenda`.`id` = `toolitemproperties`.`ref`   ".$show_all_current."
+				AND MONTH(`agenda`.`start_date`)='".$month."'
+				AND `toolitemproperties`.`tool`='".TOOL_CALENDAR_EVENT."'
+				AND	( `toolitemproperties`.`to_user_id`='".$_uid."' OR `toolitemproperties`.`to_group_id` IN (0, ".implode(", ", $group_memberships).") )
+				AND `toolitemproperties`.`visibility`='1'
+				ORDER BY  start_date ".$sort;
+		}
+		else
+		{
+			$sql="SELECT
+				agenda.*, toolitemproperties.*
+				FROM ".$TABLEAGENDA." agenda, ".$TABLE_ITEM_PROPERTY." toolitemproperties
+				WHERE `agenda`.`id` = `toolitemproperties`.`ref`   ".$show_all_current."
+				AND MONTH(`agenda`.`start_date`)='".$month."'
+				AND `toolitemproperties`.`tool`='".TOOL_CALENDAR_EVENT."'
+				AND ( `toolitemproperties`.`to_user_id`='".$_uid."' OR `toolitemproperties`.`to_group_id`='0')
+				AND `toolitemproperties`.`visibility`='1'
+				ORDER BY  start_date ".$sort;
+		}
+	}
+	$result=api_sql_query($sql,__FILE__,__LINE__);
+	$data=array();
+	while ($row=mysql_fetch_array($result))
+	{
+		$datum_item=(int)substr($row["start_date"],8,2);
+		//$dag_item=date("d",strtotime($datum_item));
+		$data[$datum_item]=intval($datum_item);
+	}
+	return $data;
+}
+
+
+/**
+* show the mini calender of the given month
+* @author: Patrick Cool <patrick.cool@UGent.be>, Ghent University
+* @param array an array containing all the agenda items for the given month
+* @param integer $month: the integer value of the month we are viewing
+* @param integer $year: the 4-digit year indication e.g. 2005
+* @param string $monthName: the language variable for the mont name
+* @return html code
+* @todo refactor this so that $monthName is no longer needed as a parameter
+*/
+function display_minimonthcalendar($agendaitems, $month, $year, $monthName)
+{
+	global $DaysShort;
+	//Handle leap year
+	$numberofdays = array (0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31);
+	if (($year % 400 == 0) or ($year % 4 == 0 and $year % 100 <> 0))
+		$numberofdays[2] = 29;
+	//Get the first day of the month
+	$dayone = getdate(mktime(0, 0, 0, $month, 1, $year));
+	//Start the week on monday
+	$startdayofweek = $dayone['wday'] <> 0 ? ($dayone['wday'] - 1) : 6;
+	$backwardsURL = $_SERVER['PHP_SELF']."?coursePath=".$_GET['coursePath']."&amp;courseCode=".$_GET['courseCode']."&amp;month=". ($month == 1 ? 12 : $month -1)."&amp;year=". ($month == 1 ? $year -1 : $year);
+	$forewardsURL = $_SERVER['PHP_SELF']."?coursePath=".$_GET['coursePath']."&amp;courseCode=".$_GET['courseCode']."&amp;month=". ($month == 12 ? 1 : $month +1)."&amp;year=". ($month == 12 ? $year +1 : $year);
+
+	echo 	"<table id=\"smallcalendar\">\n",
+			"<tr class=\"title\">\n",
+			"<td width=\"10%\"><a href=\"", $backwardsURL, "\"></a></td>\n",
+			"<td width=\"80%\" colspan=\"5\">", $monthName, " ", $year, "</td>\n",
+			"<td width=\"10%\"><a href=\"", $forewardsURL, "\"></a></td>\n", "</tr>\n";
+
+	echo "<tr>\n";
+	for ($ii = 1; $ii < 8; $ii ++)
+	{
+		echo "<td class=\"weekdays\">", $DaysShort[$ii % 7], "</td>\n";
+	}
+	echo "</tr>\n";
+	$curday = -1;
+	$today = getdate();
+	while ($curday <= $numberofdays[$month])
+	{
+		echo "<tr>\n";
+		for ($ii = 0; $ii < 7; $ii ++)
+		{
+			if (($curday == -1) && ($ii == $startdayofweek))
+			{
+				$curday = 1;
+			}
+			if (($curday > 0) && ($curday <= $numberofdays[$month]))
+			{
+				$bgcolor = $ii < 5 ? $class="class=\"days_week\"" : $class="class=\"days_weekend\"";
+				$dayheader = "$curday";
+				if (($curday == $today[mday]) && ($year == $today[year]) && ($month == $today[mon]))
+				{
+					$dayheader = "$curday";
+					$class = "class=\"days_today\"";
+				}
+				echo "\t<td ".$class.">";
+				if ($agendaitems[$curday] <> "")
+				{
+					echo "<a href=\"".$_SERVER['PHP_SELF']."?action=view&amp;view=day&amp;day=".$curday."&amp;month=".$month."&amp;year=".$year."\">".$dayheader."</a>";
+				}
+				else
+				{
+					echo $dayheader;
+				}
+				// "a".$dayheader." <span class=\"agendaitem\">".$agendaitems[$curday]."</span>\n";
+				echo "</td>\n";
+				$curday ++;
+			}
+			else
+			{
+				echo "<td>&nbsp;</td>\n";
+			}
+		}
+		echo "</tr>\n";
+	}
+	echo "</table>\n";
+}
+
+
+/**
+* show the calender of the given month
+* @author: Patrick Cool <patrick.cool@UGent.be>, Ghent University
+* @param integer $month: the integer value of the month we are viewing
+* @param integer $year: the 4-digit year indication e.g. 2005
+* @return html code
+*/
+function display_monthcalendar($month, $year)
+{
+	global $MonthsLong;
+	global $datakalenderitems;
+	global $DaysShort;
+	global $origin;
+
+	// grabbing all the kalender items for this year and storing it in a array
+	$data=get_kalender_items($month,$year);
+
+
+	//Handle leap year
+	$numberofdays = array(0,31,28,31,30,31,30,31,31,30,31,30,31);
+	if (($year%400 == 0) or ($year%4==0 and $year%100<>0)) $numberofdays[2] = 29;
+
+	//Get the first day of the month
+	$dayone = getdate(mktime(0,0,0,$month,1,$year));
+  	//Start the week on monday
+	$startdayofweek = $dayone['wday']<>0 ? ($dayone['wday']-1) : 6;
+
+	$backwardsURL = $_SERVER['PHP_SELF']."?origin=$origin&amp;month=".($month==1 ? 12 : $month-1)."&amp;year=".($month==1 ? $year-1 : $year);
+	$forewardsURL = $_SERVER['PHP_SELF']."?origin=$origin&amp;month=".($month==12 ? 1 : $month+1)."&amp;year=".($month==12 ? $year+1 : $year);
+
+	   $maand_array_maandnummer=$month-1;
+
+	echo "<table id=\"smallcalendar\">\n",
+		"<tr class=\"title\">\n",
+		"<td width=\"10%\"><a href=\"",$backwardsURL,"\"></a></td>\n",
+		"<td width=\"80%\" colspan=\"5\">",$MonthsLong[$maand_array_maandnummer]," ",$year,"</td>\n",
+		"<td width=\"10%\"><a href=\"",$forewardsURL,"\"></a></td>\n",
+		"</tr>\n";
+
+	echo "<tr>\n";
+
+	for ($ii=1;$ii<8; $ii++)
+	{
+	echo "<td id=\"weekdays\">",$DaysShort[$ii%7],"</td>\n";
+  }
+
+	echo "</tr>\n";
+	$curday = -1;
+	$today = getdate();
+	while ($curday <=$numberofdays[$month])
+  	{
+	echo "<tr>\n";
+    	for ($ii=0; $ii<7; $ii++)
+	  	{
+	  		if (($curday == -1)&&($ii==$startdayofweek))
+			{
+	    		$curday = 1;
+			}
+			if (($curday>0)&&($curday<=$numberofdays[$month]))
+			{
+				$bgcolor = $ii<5 ? "class=\"alternativeBgLight\"" : "class=\"alternativeBgDark\"";
+
+				$dayheader = "$curday";
+				if (in_array($curday,$data))
+					{ $dayheader="<a href='".$_SERVER['PHP_SELF']."?origin=$origin&amp;month=$month&amp;year=$year&amp;day=$curday#$curday'>".$curday."</a>"; }
+
+				if (($curday==$today['mday'])&&($year ==$today['year'])&&($month == $today[mon]))
+				{
+			echo "<td id=\"today\" ",$bgcolor,"\">".$dayheader." \n";
+      }
+				else
+				{
+			echo "<td id=\"days\" ",$bgcolor,"\">".$dayheader." \n";
+				}
+			echo "</td>\n";
+
+	      		$curday++;
+	    }
+	  		else
+	    {
+	echo "<td>&nbsp;</td>";
+
+	    }
+		}
+	echo "</tr>";
+    }
+echo "</table>";
+}
+
+
+/**
+* returns all the javascript that is required for easily selecting the target people/groups this goes into the $htmlHeadXtra[] array
+* @author: Patrick Cool <patrick.cool@UGent.be>, Ghent University
+* @return javascript code
+*/
+function to_javascript()
+{
+$Send2All=get_lang("Send2All");
+
+
+return "<script type=\"text/javascript\" language=\"JavaScript\">
+
+<!-- Begin javascript menu swapper
+
+function move(fbox,	tbox)
+{
+	var	arrFbox	= new Array();
+	var	arrTbox	= new Array();
+	var	arrLookup =	new	Array();
+
+	var	i;
+	for	(i = 0;	i <	tbox.options.length; i++)
+	{
+		arrLookup[tbox.options[i].text]	= tbox.options[i].value;
+		arrTbox[i] = tbox.options[i].text;
+	}
+
+	var	fLength	= 0;
+	var	tLength	= arrTbox.length;
+
+	for(i =	0; i < fbox.options.length;	i++)
+	{
+		arrLookup[fbox.options[i].text]	= fbox.options[i].value;
+
+		if (fbox.options[i].selected &&	fbox.options[i].value != \"\")
+		{
+			arrTbox[tLength] = fbox.options[i].text;
+			tLength++;
+		}
+		else
+		{
+			arrFbox[fLength] = fbox.options[i].text;
+			fLength++;
+		}
+	}
+
+	arrFbox.sort();
+	arrTbox.sort();
+	fbox.length	= 0;
+	tbox.length	= 0;
+
+	var	c;
+	for(c =	0; c < arrFbox.length; c++)
+	{
+		var	no = new Option();
+		no.value = arrLookup[arrFbox[c]];
+		no.text	= arrFbox[c];
+		fbox[c]	= no;
+	}
+	for(c =	0; c < arrTbox.length; c++)
+	{
+		var	no = new Option();
+		no.value = arrLookup[arrTbox[c]];
+		no.text	= arrTbox[c];
+		tbox[c]	= no;
+	}
+}
+
+function validate()
+{
+	var	f =	document.new_calendar_item;
+	f.submit();
+	return true;
+}
+
+function selectAll(cbList,bSelect,showwarning)
+{
+	if (cbList.length <	1) {
+		alert(\"$Send2All\");
+		return;
+	}
+	for	(var i=0; i<cbList.length; i++)
+		cbList[i].selected = cbList[i].checked = bSelect
+}
+
+function reverseAll(cbList)
+{
+	for	(var i=0; i<cbList.length; i++)
+	{
+		cbList[i].checked  = !(cbList[i].checked)
+		cbList[i].selected = !(cbList[i].selected)
+	}
+}
+//	End	-->
+</script>";
+}
+
+
+/**
+* returns the javascript for setting a filter. This is a jump menu
+* @author: Patrick Cool <patrick.cool@UGent.be>, Ghent University
+* @return javascript code
+*/
+function user_group_filter_javascript()
+{
+return "<script language=\"JavaScript\" type=\"text/JavaScript\">
+<!--
+function MM_jumpMenu(targ,selObj,restore){
+  eval(targ+\".location='\"+selObj.options[selObj.selectedIndex].value+\"'\");
+  if (restore) selObj.selectedIndex=0;
+}
+//-->
+</script>
+";
+}
+
+
+/**
+* this function gets all the users of the current course
+* @author Patrick Cool <patrick.cool@UGent.be>, Ghent University
+* @return array: associative array where the key is the id of the user and the value is an array containing
+			the first name, the last name, the user id
+*/
+function get_course_users()
+{
+global $tbl_user;
+global $tbl_courseUser, $tbl_session_course_user;
+global $_cid;
+
+// not 100% if this is necessary, this however prevents a notice
+if (!isset($courseadmin_filter))
+	{$courseadmin_filter='';}
+
+if(api_get_setting("use_session_mode") != "true")
+{
+	$sql =	"SELECT u.lastname lastName, u.firstname firstName, u.user_id uid
+			         FROM ".$tbl_user." u, ".$tbl_courseUser." cu
+			         WHERE cu.course_code = '".$_cid."'
+			         AND cu.user_id = u.user_id $courseadmin_filter
+			         ORDER BY u.lastname, u.firstname";
+}
+else 
+{
+	$sql = "SELECT u.lastname lastName, u.firstName firstName, u.user_id uid 
+			FROM $tbl_session_course_user AS session_course_user
+			INNER JOIN $tbl_user u
+				ON u.user_id = session_course_user.id_user
+			WHERE id_session='".$_SESSION['id_session']."' 
+			AND course_code='$_cid'";
+}
+$result = api_sql_query($sql,__FILE__,__LINE__) or die(mysql_error());
+while ($user_data = mysql_fetch_array($result))
+	{
+	$user_list [$user_data['uid']] = $user_data;
+	}
+return $user_list;
+}
+
+
+/**
+* this function gets all the groups of the course
+* @author Patrick Cool <patrick.cool@UGent.be>, Ghent University
+* @return array
+*/
+function get_course_groups()
+{
+global $tbl_group;
+global $tbl_groupUser;
+
+$sql = "SELECT g.id, g.name, COUNT(gu.id) userNb
+		        FROM ".$tbl_group." AS g LEFT JOIN ".$tbl_groupUser." gu
+		        ON g.id = gu.group_id
+		        GROUP BY g.id";
+
+$result = api_sql_query($sql,__FILE__,__LINE__) or die(mysql_error());
+while ($group_data = mysql_fetch_array($result))
+	{
+	$group_list [$group_data['id']] = $group_data;
+	}
+return $group_list;
+}
+
+
+/**
+* this function shows the form for sending a message to a specific group or user.
+* @author: Patrick Cool <patrick.cool@UGent.be>, Ghent University
+* @return html code
+*/
+function show_to_form($to_already_selected)
+{
+$user_list=get_course_users();
+$group_list=get_course_groups();
+
+echo "\n<table>\n";
+	echo "\t<tr>\n";
+	// the form containing all the groups and all the users of the course
+	echo "\t\t<td>\n";
+		construct_not_selected_select_form($group_list,$user_list,$to_already_selected);
+	echo "\t\t</td>\n";
+	// the buttons for adding or removing groups/users
+	echo "\n\t\t<td valign=\"middle\">\n";
+	echo "\t\t<input type=\"button\" ",
+				"onclick=\"move(this.form.elements[3],this.form.elements[6])\" ",
+				"value=\"   &gt;&gt;   \" />",
+
+				"\n\t\t<p>&nbsp;</p>",
+
+				"\n\t\t<input type=\"button\" ",
+				"onclick=\"move(this.form.elements[6],this.form.elements[3])\" ",
+				"value=\"   &lt;&lt;   \" />";
+	echo "\t\t</td>\n";
+	echo "\n\t\t<td>\n";
+		construct_selected_select_form($group_list,$user_list,$to_already_selected);
+	echo "\t\t</td>\n";
+	echo "\t</tr>\n";
+echo "</table>";
+}
+
+
+/**
+* this function shows the form with the user that were not selected
+* @author: Patrick Cool <patrick.cool@UGent.be>, Ghent University
+* @return html code
+*/
+function construct_not_selected_select_form($group_list=null, $user_list=null,$to_already_selected)
+{
+	echo "\t\t<select name=\"not_selected_form[]\" size=\"5\" multiple=\"multiple\" style=\"width:200px\">\n";
+
+	// adding the groups to the select form
+	if (is_array($group_list))
+	{
+		foreach($group_list as $this_group)
+		{
+			//api_display_normal_message("group " . $thisGroup[id] . $thisGroup[name]);
+			if (!in_array("GROUP:".$this_group['id'],$to_already_selected)) // $to_already_selected is the array containing the groups (and users) that are already selected
+				{
+				echo	"\t\t<option value=\"GROUP:".$this_group['id']."\">",
+					"G: ",$this_group['name']," &ndash; " . $this_group['userNb'] . " " . get_lang('Users') .
+					"</option>\n";
+			}
+		}
+		// a divider
+		echo	"\t\t<option value=\"\">---------------------------------------------------------</option>\n";
+	}
+
+	// adding the individual users to the select form
+	foreach($user_list as $this_user)
+	{
+		if (!in_array("USER:".$this_user['uid'],$to_already_selected)) // $to_already_selected is the array containing the users (and groups) that are already selected
+		{
+			echo	"\t\t<option value=\"USER:",$this_user['uid'],"\">",
+				"",$this_user['lastName']," ",$this_user['firstName'],
+				"</option>\n";
+		}
+	}
+	echo "\t\t</select>\n";
+}
+
+
+
+/**
+* this function shows the form with the user that were selected
+* @author: Patrick Cool <patrick.cool@UGent.be>, Ghent University
+* @return html code
+*/
+function construct_selected_select_form($group_list=null, $user_list=null,$to_already_selected)
+{
+	// we separate the $to_already_selected array (containing groups AND users into
+	// two separate arrays
+	if (is_array($groupuser))
+	{
+		 $groupuser=separate_users_groups($to_already_selected);
+	}
+	$groups_to_already_selected=$groupuser['groups'];
+	$users_to_already_selected=$groupuser['users'];
+
+	// we load all the groups and all the users into a reference array that we use to search the name of the group / user
+	$ref_array_groups=get_course_groups();
+	$ref_array_users=get_course_users();
+
+	// we construct the form of the already selected groups / users
+	echo "\t\t<select name=\"selectedform[]\" size=\"5\" multiple=\"multiple\" style=\"width:200px\">";
+	foreach($to_already_selected as $groupuser)
+	{
+		list($type,$id)=explode(":",$groupuser);
+		if ($type=="GROUP")
+		{
+			echo "\t\t<option value=\"".$groupuser."\">G: ".$ref_array_groups[$id]['name']."</option>";
+		}
+		else
+		{
+			echo "\t\t<option value=\"".$groupuser."\">".$ref_array_users[$id]['lastName']." ".$ref_array_users[$id]['firstName']."</option>";
+		}
+	}
+	echo "</select>\n";
+}
+
+
+
+/**
+* This function stores the Agenda Item in the table calendar_event and updates the item_property table also
+* @author: Patrick Cool <patrick.cool@UGent.be>, Ghent University
+* @return integer the id of the last added agenda item
+*/
+function store_new_agenda_item()
+{
+global $TABLEAGENDA;
+global $_uid;
+
+// some filtering of the input data
+$title=strip_tags(trim($_POST['title'])); // no html allowed in the title
+$content=trim($_POST['content']);
+$start_date=(int)$_POST['fyear']."-".(int)$_POST['fmonth']."-".(int)$_POST['fday']." ".(int)$_POST['fhour'].":".(int)$_POST['fminute'].":00";
+$end_date=(int)$_POST['end_fyear']."-".(int)$_POST['end_fmonth']."-".(int)$_POST['end_fday']." ".(int)$_POST['end_fhour'].":".(int)$_POST['end_fminute'].":00";
+
+
+// store in the table calendar_event
+$sql = "INSERT INTO ".$TABLEAGENDA."
+				        (title,content, start_date, end_date)
+				        VALUES
+				        ('".$title."','".$content."', '".$start_date."','".$end_date."')";
+
+$result = api_sql_query($sql,__FILE__,__LINE__) or die (mysql_error());
+$last_id=mysql_insert_id();
+
+
+// store in last_tooledit (first the groups, then the users
+$to=$_POST['selectedform'];
+if (($_SESSION['allow_individual_calendar']=="show" and !is_null($to))or (!empty($_SESSION['toolgroup']))) // !is_null($to): when no user is selected we send it to everyone
+	{
+	$send_to=separate_users_groups($to);
+	// storing the selected groups
+	if (is_array($send_to['groups']))
+		{
+		foreach ($send_to['groups'] as $group)
+			{
+				api_item_property_update($_course, TOOL_CALENDAR_EVENT, $last_id,"AgendaAdded", $_uid, $group,'',$start_visible, $end_visible);
+			}
+		}
+	// storing the selected users
+	if (is_array($send_to['users']))
+		{
+		foreach ($send_to['users'] as $user)
+			{
+				api_item_property_update($_course, TOOL_CALENDAR_EVENT, $last_id,"AgendaAdded", $_uid,'',$user, $start_visible,$end_visible);
+			}
+		}
+	}
+else // the message is sent to everyone, so we set the group to 0
+	{
+	api_item_property_update($_course, TOOL_CALENDAR_EVENT, $last_id,"AgendaAdded", $_uid, '','',$start_visible,$end_visible);
+	}
+
+// storing the resources
+store_resources($_SESSION['source_type'],$last_id);
+
+return $last_id;
+}
+
+/**
+ * Stores the given agenda item as an announcement (unlinked copy)
+ * @param	integer		Agenda item's ID
+ * @return	integer		New announcement item's ID
+ */
+function store_agenda_item_as_announcement($item_id){
+	$table_agenda = Database::get_course_table(AGENDA_TABLE);
+	$table_ann = Database::get_course_table(ANNOUNCEMENT_TABLE); 
+	//check params 
+	if(empty($item_id) or $item_id != strval(intval($item_id))){return -1;}
+	//get the agenda item
+	$sql = "SELECT * FROM $table_agenda WHERE id = '".$item_id."'";
+	$res = api_sql_query($sql,__FILE__,__LINE__);
+	if(Database::num_rows($res)>0){
+		$row = Database::fetch_array($res);
+		//we have the agenda event, copy it
+		//get the maximum value for display order in announcement table
+		$sql_max = "SELECT MAX(display_order) FROM $table_ann";
+		$res_max = api_sql_query($sql_max,__FILE__,__LINE__);
+		$row_max = Database::fetch_array($res_max);
+		$max = $row_max[0]+1;
+		//build the announcement text
+		$content = $row['start_date']." - ".$row['end_date']."\n\n".$row['content'];
+		//insert announcement
+		
+		$sql_ins = "INSERT INTO $table_ann (title,content,end_date,display_order) " .
+				"VALUES ('".$row['title']."','$content','".$row['end_date']."','$max')";
+		$res_ins = api_sql_query($sql_ins,__FILE__,__LINE__);
+		if($res > 0)
+		{
+			$ann_id = Database::get_last_insert_id();
+			//Now also get the list of item_properties rows for this agenda_item (calendar_event)
+			//and copy them into announcement item_properties
+			$table_props = Database::get_course_table(ITEM_PROPERTY_TABLE);
+			$sql_props = "SELECT * FROM $table_props WHERE tool = 'calendar_event' AND ref='$item_id'";
+			$res_props = api_sql_query($sql_props,__FILE__,__LINE__);
+			if(Database::num_rows($res_props)>0)
+			{
+				while($row_props = Database::fetch_array($res_props))
+				{
+					//insert into announcement item_property
+					$time = date("Y-m-d H:i:s", time());
+					$sql_ins_props = "INSERT INTO $table_props " .
+							"(tool, insert_user_id, insert_date, " .
+							"lastedit_date, ref, lastedit_type," .
+							"lastedit_user_id, to_group_id, to_user_id, " .
+							"visibility, start_visible, end_visible)" .
+							" VALUES " .
+							"('announcement','".$row_props['insert_user_id']."','".$time."'," .
+							"'$time','$ann_id','AnnouncementAdded'," .
+							"'".$row_props['last_edit_user_id']."','".$row_props['to_group_id']."','".$row_props['to_user_id']."'," .
+							"'".$row_props['visibility']."','".$row_props['start_visible']."','".$row_props['end_visible']."')";
+					$res_ins_props = api_sql_query($sql_ins_props,__FILE__,__LINE__);
+					if($res_ins_props <= 0){
+						error_log('SQL Error in '.__FILE__.' at line '.__LINE__.': '.$sql_ins_props);
+					}else{
+						//copy was a success
+						return $ann_id;
+					}
+				}
+			}
+		}else{
+			return -1;
+		}
+	}
+	return -1;
+}
+
+/**
+* This function separates the users from the groups
+* users have a value USER:XXX (with XXX the dokeos id
+* groups have a value GROUP:YYY (with YYY the group id)
+* @author: Patrick Cool <patrick.cool@UGent.be>, Ghent University
+* @return array
+*/
+function separate_users_groups($to)
+{
+foreach($to as $to_item)
+	{
+	list($type, $id) = explode(':', $to_item);
+
+	switch($type)
+		{
+		case 'GROUP':
+			$grouplist[] =$id;
+			break;
+		case 'USER':
+			$userlist[] =$id;
+			break;
+		}
+	}
+$send_to['groups']=$grouplist;
+$send_to['users']=$userlist;
+return $send_to;
+}
+
+
+
+/**
+* returns all the users and all the groups a specific Agenda item has been sent to
+* @author: Patrick Cool <patrick.cool@UGent.be>, Ghent University
+* @return array
+*/
+function sent_to($tool, $id)
+{
+global $_course;
+$TABLE_ITEM_PROPERTY = Database::get_course_table(LAST_TOOL_EDIT_TABLE);
+
+$sql="SELECT * FROM $TABLE_ITEM_PROPERTY WHERE tool='".$tool."' AND ref='".$id."'";
+$result=api_sql_query($sql,__FILE__,__LINE__);
+while ($row=mysql_fetch_array($result))
+	{
+	// if to_group_id is null then it is sent to a specific user
+	// if to_group_id = 0 then it is sent to everybody
+	if (!is_null($row['to_group_id']) )
+		{
+		$sent_to_group[]=$row['to_group_id'];
+		//echo $row['to_group_id'];
+		}
+	// if to_user_id <> 0 then it is sent to a specific user
+	if ($row['to_user_id']<>0)
+		{
+		$sent_to_user[]=$row['to_user_id'];
+		}
+	}
+if (isset($sent_to_group))
+	{
+	$sent_to['groups']=$sent_to_group;
+	}
+if (isset($sent_to_user))
+	{
+	$sent_to['users']=$sent_to_user;
+	}
+return $sent_to;
+}
+
+
+
+/**
+* constructs the form to display all the groups and users the message has been sent to
+* @author: Patrick Cool <patrick.cool@UGent.be>, Ghent University
+* @param  array $sent_to_array: a 2 dimensional array containing the groups and the users
+*				the first level is a distinction between groups and users: $sent_to_array['groups'] and $sent_to_array['users']
+*				$sent_to_array['groups'] (resp. $sent_to_array['users']) is also an array containing all the id's of the
+*				groups (resp. users) who have received this message.
+* @return html
+*/
+function sent_to_form($sent_to_array)
+{
+// we find all the names of the groups
+$group_names=get_course_groups();
+
+count($sent_to_array);
+
+// we count the number of users and the number of groups
+if (isset($sent_to_array['users']))
+	{
+	$number_users=count($sent_to_array['users']);
+	}
+else
+	{
+	$number_users=0;
+	}
+if (isset($sent_to_array['groups']))
+	{
+	$number_groups=count($sent_to_array['groups']);
+	}
+else
+	{
+	$number_groups=0;
+	}
+$total_numbers=$number_users+$number_groups;
+
+// starting the form if there is more than one user/group
+if ($total_numbers >1)
+	{
+	$output="<select name=\"sent to\">\n";
+	$output.="<option>".get_lang("SentTo")."</option>";
+	// outputting the name of the groups
+	if (is_array($sent_to_array['groups']))
+		{
+		foreach ($sent_to_array['groups'] as $group_id)
+			{
+			$output.="\t<option value=\"\">G: ".$group_names[$group_id]['name']."</option>\n";
+			}
+		}
+	if (isset($sent_to_array['users']))
+	{
+		if (is_array($sent_to_array['users']))
+			{
+			foreach ($sent_to_array['users'] as $user_id)
+				{
+				$user_info=api_get_user_info($user_id);
+				$output.="\t<option value=\"\">".$user_info['firstName']." ".$user_info['lastName']."</option>\n";
+				}
+			}
+	}
+
+	// ending the form
+	$output.="</select>\n";
+	}
+else // there is only one user/group
+	{
+	if (is_array($sent_to_array['users']))
+		{
+		$user_info=api_get_user_info($sent_to_array['users'][0]);
+		echo $user_info['firstName']." ".$user_info['lastName'];
+		}
+	if (is_array($sent_to_array['groups']) and $sent_to_array['groups'][0]!==0)
+		{
+		$group_id=$sent_to_array['groups'][0];
+		echo $group_names[$group_id]['name'];
+		}
+	if (is_array($sent_to_array['groups']) and $sent_to_array['groups'][0]==0)
+		{
+		echo get_lang("Everybody");
+		}
+	//.$sent_to_array['groups'][0];
+	}
+
+echo $output;
+}
+
+
+/**
+* This function displays a dropdown list that allows the course administrator do view the calendar items of one specific group
+* @author: Patrick Cool <patrick.cool@UGent.be>, Ghent University
+*/
+function show_group_filter_form()
+{
+$group_list=get_course_groups();
+
+echo "<select name=\"select\" onchange=\"MM_jumpMenu('parent',this,0)\">";
+echo "<option value=\"agenda.php?group=none\">show all groups</option>";
+foreach($group_list as $this_group)
+	{
+	// echo "<option value=\"agenda.php?isStudentView=true&amp;group=".$this_group['id']."\">".$this_group['name']."</option>";
+	echo "<option value=\"agenda.php?group=".$this_group['id']."\" ";
+	echo ($this_group['id']==$_SESSION['group'])? " selected":"" ;
+	echo ">".$this_group['name']."</option>";
+	}
+echo "</select>";
+}
+
+
+
+/**
+* This function displays a dropdown list that allows the course administrator do view the calendar items of one specific group
+* @author: Patrick Cool <patrick.cool@UGent.be>, Ghent University
+*/
+function show_user_filter_form()
+{
+$user_list=get_course_users();
+
+echo "<select name=\"select\" onchange=\"MM_jumpMenu('parent',this,0)\">";
+echo "<option value=\"agenda.php?user=none\">show all users</option>";
+foreach($user_list as $this_user)
+	{
+	// echo "<option value=\"agenda.php?isStudentView=true&amp;user=".$this_user['uid']."\">".$this_user['lastName']." ".$this_user['firstName']."</option>";
+	echo "<option value=\"agenda.php?user=".$this_user['uid']."\" ";
+	echo ($this_user['uid']==$_SESSION['user'])? " selected":"" ;
+	echo ">".$this_user['lastName']." ".$this_user['firstName']."</option>";
+	}
+echo "</select>";
+}
+
+
+
+/**
+* This function displays a dropdown list that allows the course administrator do view the calendar items of one specific group
+* @author: Patrick Cool <patrick.cool@UGent.be>, Ghent University
+*/
+function show_user_group_filter_form()
+{
+	echo "\n<select name=\"select\" onchange=\"MM_jumpMenu('parent',this,0)\">";
+	echo "\n\t<option value=\"agenda.php?user=none\">".get_lang("ShowAll")."</option>";
+
+	// Groups
+	echo "\n\t<optgroup label=\"".get_lang("Groups")."\">";
+	$group_list=get_course_groups();
+	foreach($group_list as $this_group)
+	{
+		// echo "<option value=\"agenda.php?isStudentView=true&amp;group=".$this_group['id']."\">".$this_group['name']."</option>";
+		echo "\n\t\t<option value=\"agenda.php?group=".$this_group['id']."\" ";
+		echo ($this_group['id']==$_SESSION['group'])? " selected":"" ;
+		echo ">".$this_group['name']."</option>";
+	}
+	echo "\n\t</optgroup>";
+
+	// Users
+	echo "\n\t<optgroup label=\"".get_lang("Users")."\">";
+	$user_list=get_course_users();
+	foreach($user_list as $this_user)
+		{
+		// echo "<option value=\"agenda.php?isStudentView=true&amp;user=".$this_user['uid']."\">".$this_user['lastName']." ".$this_user['firstName']."</option>";
+		echo "\n\t\t<option value=\"agenda.php?user=".$this_user['uid']."\" ";
+		echo ($this_user['uid']==$_SESSION['user'])? " selected":"" ;
+		echo ">".$this_user['lastName']." ".$this_user['firstName']."</option>";
+		}
+	echo "\n\t</optgroup>";	
+	echo "</select>";
+}
+
+
+
+/**
+* This tools loads all the users and all the groups who have received a specific item (in this case an agenda item)
+* @author: Patrick Cool <patrick.cool@UGent.be>, Ghent University
+*/
+function load_edit_users($tool, $id)
+{
+global $_course;
+$TABLE_ITEM_PROPERTY = Database::get_course_table(LAST_TOOL_EDIT_TABLE);
+
+$sql="SELECT * FROM $TABLE_ITEM_PROPERTY WHERE tool='$tool' AND ref='$id'";
+$result=api_sql_query($sql,__FILE__,__LINE__) or die (mysql_error());
+while ($row=mysql_fetch_array($result))
+	{
+	$to_group=$row['to_group_id'];
+	switch ($to_group)
+		{
+		// it was send to one specific user
+		case null:
+			$to[]="USER:".$row['to_user_id'];
+			break;
+		// it was sent to everyone
+		case 0:
+			 return "everyone";
+			 exit;
+			break;
+		default:
+			$to[]="GROUP:".$row['to_group_id'];
+		}
+	}
+return $to;
+}
+
+
+
+/**
+* This functions swithes the visibility a course resource using the visible field in 'last_tooledit' values: 0 = invisible
+* @author: Patrick Cool <patrick.cool@UGent.be>, Ghent University
+*/
+function change_visibility($tool,$id)
+{
+	global $_course;
+	$TABLE_ITEM_PROPERTY = Database::get_course_table(LAST_TOOL_EDIT_TABLE);
+
+	$sql="SELECT * FROM $TABLE_ITEM_PROPERTY WHERE tool='".TOOL_CALENDAR_EVENT."' AND ref='$id'";
+	$result=api_sql_query($sql,__FILE__,__LINE__) or die (mysql_error());
+	$row=mysql_fetch_array($result);
+
+	if ($row['visibility']=='1')
+	{
+		$sql_visibility="UPDATE $TABLE_ITEM_PROPERTY SET visibility='0' WHERE tool='$tool' AND ref='$id'";
+		api_item_property_update($_course,TOOL_CALENDAR_EVENT,$id,"invisible");
+	}
+	else
+	{
+		$sql_visibility="UPDATE $TABLE_ITEM_PROPERTY SET visibility='1' WHERE tool='$tool' AND ref='$id'";
+		api_item_property_update($_course,TOOL_CALENDAR_EVENT,$id,"visible");
+	}
+}
+
+
+
+/**
+* The links that allows the course administrator to add a new agenda item, to filter on groups or users
+* @author Patrick Cool <patrick.cool@UGent.be>, Ghent University
+*/
+function display_courseadmin_links()
+{	
+	echo "<li><a href='".$_SERVER['PHP_SELF']."?action=add&amp;origin=".$_GET['origin']."'><img src=\"../img/calendar_add.gif\" align=\"absmiddle\" border=\"0\" /> ".get_lang("AgendaAdd")."</a><br /></li>";
+	if (empty ($_SESSION['toolgroup']))
+	{
+		echo "<li>".get_lang(UserGroupFilter)."<br/>";
+		echo "<form name=\"filter\">";
+		show_user_group_filter_form();
+		echo "</form>";
+	}
+	echo "</li>";
+}
+
+
+
+/**
+* The links that allows the student AND course administrator to show all agenda items and sort up/down
+* @author Patrick Cool <patrick.cool@UGent.be>, Ghent University
+*/
+function display_student_links()
+{
+	global $show;
+	if ($_SESSION['sort'] == 'DESC')
+	{
+		echo "<li><a href='".$_SERVER['PHP_SELF']."?sort=asc&amp;origin=".$_GET['origin']."'><img src=\"../img/calendar_up.gif\" border=\"0\" /> ".get_lang("AgendaSortChronologicallyUp")."</a></li>";
+	}
+	else
+	{
+		echo "<li><a href='".$_SERVER['PHP_SELF']."?sort=desc&amp;origin=".$_GET['origin']."'><img src=\"../img/calendar_down.gif\" border=\"0\" /> ".get_lang("AgendaSortChronologicallyDown")."</a></li>";
+	}
+
+	// showing the link to show all items or only those of the current month
+	if ($_SESSION['show']=="showcurrent")
+	{
+		echo "<li><a href='".$_SERVER['PHP_SELF']."?action=showall&amp;origin=".$_GET['origin']."'><img src=\"../img/calendar_select.gif\" border=\"0\" /> ".get_lang("ShowAll")."</a></li>";
+	}
+	else
+	{
+		echo "<li><a href='".$_SERVER['PHP_SELF']."?action=showcurrent&amp;origin=".$_GET['origin']."'><img src=\"../img/calendar_month.gif\" border=\"0\" /> ".get_lang("ShowCurrent")."</a></li>";
+	}
+}
+
+
+
+/**
+* get all the information of the agenda_item from the database
+* @author Patrick Cool <patrick.cool@UGent.be>, Ghent University
+* @param integer the id of the agenda item we are getting all the information of
+* @return an associative array that contains all the information of the agenda item. The keys are the database fields
+*/
+function get_agenda_item($id)
+{
+	global $TABLEAGENDA;
+	$id=(int)addslashes($_GET['id']);
+	$sql 			= "SELECT * FROM ".$TABLEAGENDA." WHERE id='".$id."'";
+	$result			= api_sql_query($sql,__FILE__,__LINE__);
+	$entry_to_edit 	= mysql_fetch_array($result);
+	$item['title']	= $entry_to_edit["title"];
+	$item['content']		= $entry_to_edit["content"];
+	$item['start_date']	= $entry_to_edit["start_date"];
+	$item['end_date']		= $entry_to_edit["end_date"];
+	$item['to']=load_edit_users(TOOL_CALENDAR_EVENT, $id);
+	// if the item has been sent to everybody then we show the compact to form
+	if ($item['to']=="everyone")
+	{
+		$_SESSION['allow_individual_calendar']="hide";
+	}
+	else
+	{
+		$_SESSION['allow_individual_calendar']="show";
+	}
+	//echo "<br />IN get_agenda_item".$_SESSION['allow_individual_calendar'];
+	return $item;
+}
+/**
+* This is the function that updates an agenda item. It does 3 things
+* 1. storethe start_date, end_date, title and message in the calendar_event table
+* 2. store the groups/users who this message is meant for in the item_property table
+* 3. modify the attachments (if needed)
+* @author Patrick Cool <patrick.cool@UGent.be>, Ghent University
+*/
+function store_edited_agenda_item()
+{
+	global $_uid;
+
+	// database definitions
+	$TABLE_ITEM_PROPERTY = Database::get_course_table(LAST_TOOL_EDIT_TABLE);
+
+	// STEP 1: editing the calendar_event table
+	// 1.a.  some filtering of the input data
+	$id=(int)$_POST['id'];
+	$title=strip_tags(trim($_POST['title'])); // no html allowed in the title
+	$content=trim($_POST['content']);
+	$start_date=(int)$_POST['fyear']."-".(int)$_POST['fmonth']."-".(int)$_POST['fday']." ".(int)$_POST['fhour'].":".(int)$_POST['fminute'].":00";
+	$end_date=(int)$_POST['end_fyear']."-".(int)$_POST['end_fmonth']."-".(int)$_POST['end_fday']." ".(int)$_POST['end_fhour'].":".(int)$_POST['end_fminute'].":00";
+	$to=$_POST['selectedform'];
+	// 1.b. the actual saving in calendar_event table
+	$edit_result=save_edit_agenda_item($id,$title,$content,$start_date,$end_date);
+
+	// step 2: editing the item_propery table (=delete all and add the new destination users/groups)
+	if ($edit_result=true)
+	{
+		// 2.a. delete everything for the users
+		$sql_delete="DELETE FROM ".$TABLE_ITEM_PROPERTY." WHERE ref='$id' AND tool='".TOOL_CALENDAR_EVENT."'";
+
+		$result = api_sql_query($sql_delete,__FILE__,__LINE__) or die (mysql_error());
+		// 2.b. storing the new users/groups
+		if ($_SESSION['allow_individual_calendar']=="show" and !is_null($to)) // !is_null($to): when no user is selected we send it to everyone
+		{
+			$send_to=separate_users_groups($to);
+			// storing the selected groups
+			if (is_array($send_to['groups']))
+			{
+				foreach ($send_to['groups'] as $group)
+				{
+					api_item_property_update($_course, TOOL_CALENDAR_EVENT, $id,"AgendaModified", $_uid, $group,'',$start_visible, $end_visible);
+				}
+			}
+			// storing the selected users
+			if (is_array($send_to['users']))
+			{
+				foreach ($send_to['users'] as $user)
+				{
+					api_item_property_update($_course, TOOL_CALENDAR_EVENT, $id,"AgendaModified", $_uid,'',$user, $start_visible,$end_visible);
+				}
+			}
+		}
+		else // the message is sent to everyone, so we set the group to 0
+		{
+			api_item_property_update($_course, TOOL_CALENDAR_EVENT, $id,"AgendaModified", $_uid, '','',$start_visible,$end_visible);
+		}
+
+	} //if ($edit_result=true)
+
+	// step 3: update the attachments (=delete all and add those in the session
+	update_added_resources("Agenda", $id);
+
+	// return the message;
+	Display::display_normal_message(get_lang("EditSuccess"));
+
+}
+
+/**
+* This function stores the Agenda Item in the table calendar_event and updates the item_property table also (after an edit)
+* @author: Patrick Cool <patrick.cool@UGent.be>, Ghent University
+*/
+function save_edit_agenda_item($id,$title,$content,$start_date,$end_date)
+{
+	$TABLEAGENDA 		= Database::get_course_table(AGENDA_TABLE);
+
+	// store the modifications in the table calendar_event
+	$sql = "UPDATE ".$TABLEAGENDA."
+								SET title='".$title."',
+									content='".$content."',
+									start_date='".$start_date."',
+									end_date='".$end_date."'
+								WHERE id='".$id."'";
+	$result = api_sql_query($sql,__FILE__,__LINE__) or die (mysql_error());
+	return true;
+}
+
+/**
+* This is the function that deletes an agenda item.
+* The agenda item is no longer fycically deleted but the visibility in the item_property table is set to 2
+* which means that it is invisible for the student AND course admin. Only the platform administrator can see it.
+* This will in a later stage allow the platform administrator to recover resources that were mistakenly deleted
+* by the course administrator
+* @author Patrick Cool <patrick.cool@UGent.be>, Ghent University
+* @param integer the id of the agenda item wa are deleting
+*/
+function delete_agenda_item($id)
+{
+	if (is_allowed_to_edit()  OR api_get_course_setting('allow_user_edit_agenda'))
+		{
+		if (isset($_GET['id'])&&$_GET['id']&&isset($_GET['action'])&&$_GET['action']=="delete")
+			{
+			//$sql = "DELETE FROM ".$TABLEAGENDA." WHERE id='$id'";
+			//$sql= "UPDATE ".$TABLE_ITEM_PROPERTY." SET visibility='2' WHERE tool='Agenda' and ref='$id'";
+			//$result = api_sql_query($sql,__FILE__,__LINE__) or die (mysql_error());
+			$id=(int)addslashes($_GET['id']);
+			api_item_property_update($_course,TOOL_CALENDAR_EVENT,$id,"delete");
+
+			// delete the resources that were added to this agenda item
+			// 2DO: as we no longer fysically delete the agenda item (to make it possible to 'restore'
+			//		deleted items, we should not delete the added resources either.
+			// delete_added_resource("Agenda", $id); // -> this is no longer needed as the message is not really deleted but only visibility=2 (only platform admin can see it)
+
+			//resetting the $id;
+			$id=null;
+
+			// displaying the result message in the yellow box
+			Display::display_normal_message(get_lang("AgendaDeleteSuccess"));
+			}	  // if (isset($id)&&$id&&isset($action)&&$action=="delete")
+		} // if ($is_allowedToEdit)
+
+}
+/**
+* Makes an agenda item visible or invisible for a student
+* @author Patrick Cool <patrick.cool@UGent.be>, Ghent University
+* @param integer id the id of the agenda item we are changing the visibility of
+*/
+function showhide_agenda_item($id)
+{
+	/*==================================================
+				SHOW / HIDE A CALENDAR ITEM
+	  ==================================================*/
+	//  and $_GET['isStudentView']<>"false" is added to prevent that the visibility is changed after you do the following:
+	// change visibility -> studentview -> course manager view
+	if ((is_allowed_to_edit() OR api_get_course_setting('allow_user_edit_agenda')) and $_GET['isStudentView']<>"false") 
+	{
+		if (isset($_GET['id'])&&$_GET['id']&&isset($_GET['action'])&&$_GET['action']=="showhide")
+		{
+			$id=(int)addslashes($_GET['id']);
+			change_visibility($_GLOBAL['nameTools'],$id);
+			Display::display_normal_message(get_lang("VisibilityChanged"));
+		}
+	}
+}
+/**
+* Displays all the agenda items
+* @author Patrick Cool <patrick.cool@UGent.be>, Ghent University
+*/
+function display_agenda_items()
+{
+	global $TABLEAGENDA;
+	global $TABLE_ITEM_PROPERTY;
+	global $select_month, $select_year;
+	global $DaysShort, $DaysLong, $MonthsLong;
+	global $is_courseAdmin;
+	global $dateFormatLong, $timeNoSecFormat;
+	global $_uid;
+	
+	// getting the group memberships
+	$group_memberships=GroupManager::get_group_ids($_course['dbName'],$_uid);
+
+	// getting the name of the groups
+	$group_names=get_course_groups();
+
+	/*--------------------------------------------------
+			CONSTRUCT THE SQL STATEMENT
+	  --------------------------------------------------*/
+
+	// this is to make a difference between showing everything (all months) or only the current month)
+	// $show_all_current is a part of the sql statement
+	if ($_SESSION['show']!=="showall")
+	{
+		$show_all_current=" AND MONTH(start_date)=$select_month AND year(start_date)=$select_year";
+	}
+	else
+	{
+		$show_all_current="";
+	}
+
+	// by default we use the id of the current user. The course administrator can see the agenda of other users by using the user / group filter
+	$user_id=$_uid;
+	if ($_SESSION['user']!==null)
+	{
+		$user_id=$_SESSION['user'];
+	}
+	if ($_SESSION['group']!==null)
+	{
+		$group_id=$_SESSION['group'];
+	}
+	if ($_SESSION['toolgroup']!==null)
+	{
+		$group_id=$_SESSION['toolgroup'];
+	}
+	//echo "user:".$_SESSION['user']."group: ".$_SESSION['group'];
+	// A. you are a course admin
+	//if ($is_courseAdmin)
+	if (is_allowed_to_edit() OR api_get_course_setting('allow_user_edit_agenda'))
+	{
+		// A.1. you are a course admin with a USER filter
+		// => see only the messages of this specific user + the messages of the group (s)he is member of.
+		if ($_SESSION['user']!==null)
+		{
+			$group_memberships=GroupManager::get_group_ids($_course['dbName'],$_SESSION['user']);
+			if (is_array($group_memberships))
+			{
+				$sql="SELECT
+					agenda.*, toolitemproperties.*
+					FROM ".$TABLEAGENDA." agenda, ".$TABLE_ITEM_PROPERTY." toolitemproperties
+					WHERE `agenda`.`id` = `toolitemproperties`.`ref`   ".$show_all_current."
+					AND `toolitemproperties`.`tool`='".TOOL_CALENDAR_EVENT."'
+					AND	( `toolitemproperties`.`to_user_id`=$user_id OR `toolitemproperties`.`to_group_id` IN (0, ".implode(", ", $group_memberships).") )
+					AND `toolitemproperties`.`visibility`='1'
+					ORDER BY start_date ".$_SESSION['sort'];
+			}
+			else
+			{
+				$sql="SELECT
+					agenda.*, toolitemproperties.*
+					FROM ".$TABLEAGENDA." agenda, ".$TABLE_ITEM_PROPERTY." toolitemproperties
+					WHERE `agenda`.`id` = `toolitemproperties`.`ref`   ".$show_all_current."
+					AND `toolitemproperties`.`tool`='".TOOL_CALENDAR_EVENT."'
+					AND ( `toolitemproperties`.`to_user_id`=$user_id OR `toolitemproperties`.`to_group_id`='0')
+					AND `toolitemproperties`.`visibility`='1'
+					ORDER BY start_date ".$_SESSION['sort'];
+			}
+		}
+		// A.2. you are a course admin with a GROUP filter
+		// => see only the messages of this specific group
+		elseif ($_SESSION['group']!==null)
+		{
+			$sql="SELECT
+				agenda.*, toolitemproperties.*
+				FROM ".$TABLEAGENDA." agenda, ".$TABLE_ITEM_PROPERTY." toolitemproperties
+				WHERE `agenda`.`id` = `toolitemproperties`.`ref`  ".$show_all_current."
+				AND `toolitemproperties`.`tool`='".TOOL_CALENDAR_EVENT."'
+				AND ( `toolitemproperties`.`to_group_id`=$group_id OR `toolitemproperties`.`to_group_id`='0')
+				AND `toolitemproperties`.`visibility`='1'
+				GROUP BY `toolitemproperties`.`ref`
+				ORDER BY start_date ".$_SESSION['sort'];
+
+		}
+		// A.3 you are a course admin without any group or user filter
+		else
+		{
+			// A.3.a you are a course admin without user or group filter but WITH studentview
+			// => see all the messages of all the users and groups without editing possibilities
+			if ($isStudentView=="true")
+			{
+				$sql="SELECT
+					agenda.*, toolitemproperties.*
+					FROM ".$TABLEAGENDA." agenda, ".$TABLE_ITEM_PROPERTY." toolitemproperties
+					WHERE `agenda`.`id` = `toolitemproperties`.`ref`  ".$show_all_current."
+					AND `toolitemproperties`.`tool`='".TOOL_CALENDAR_EVENT."'
+					AND `toolitemproperties`.`visibility`='1'
+					GROUP BY `toolitemproperties`.`ref`
+					ORDER BY start_date ".$_SESSION['sort'];
+
+			}
+			// A.3.b you are a course admin without user or group filter and WTIHOUT studentview (= the normal course admin view)
+			// => see all the messages of all the users and groups with editing possibilities
+			else
+			{
+				$sql="SELECT
+					agenda.*, toolitemproperties.*
+					FROM ".$TABLEAGENDA." agenda, ".$TABLE_ITEM_PROPERTY." toolitemproperties
+					WHERE `agenda`.`id` = `toolitemproperties`.`ref`  ".$show_all_current."
+					AND `toolitemproperties`.`tool`='".TOOL_CALENDAR_EVENT."'
+					AND ( `toolitemproperties`.`visibility`='0' or `toolitemproperties`.`visibility`='1')
+					GROUP BY `toolitemproperties`.`ref`
+					ORDER BY start_date ".$_SESSION['sort'];
+			}
+		}
+
+	} //if (is_allowed_to_edit() OR api_get_course_setting('allow_user_edit_agenda'))
+
+	// B. you are a student
+	else
+	{
+		if (is_array($group_memberships))
+		{
+			$sql="SELECT
+				agenda.*, toolitemproperties.*
+				FROM ".$TABLEAGENDA." agenda, ".$TABLE_ITEM_PROPERTY." toolitemproperties
+				WHERE `agenda`.`id` = `toolitemproperties`.`ref`   ".$show_all_current."
+				AND `toolitemproperties`.`tool`='".TOOL_CALENDAR_EVENT."'
+				AND	( `toolitemproperties`.`to_user_id`=$user_id OR `toolitemproperties`.`to_group_id` IN (0, ".implode(", ", $group_memberships).") )
+				AND `toolitemproperties`.`visibility`='1'
+				ORDER BY start_date ".$_SESSION['sort'];
+		}
+		else
+		{
+			if ($_uid)
+			{
+				$sql="SELECT
+					agenda.*, toolitemproperties.*
+					FROM ".$TABLEAGENDA." agenda, ".$TABLE_ITEM_PROPERTY." toolitemproperties
+					WHERE `agenda`.`id` = `toolitemproperties`.`ref`   ".$show_all_current."
+					AND `toolitemproperties`.`tool`='".TOOL_CALENDAR_EVENT."'
+					AND ( `toolitemproperties`.`to_user_id`=$user_id OR `toolitemproperties`.`to_group_id`='0')
+					AND `toolitemproperties`.`visibility`='1'
+					ORDER BY start_date ".$_SESSION['sort'];
+			}
+			else
+			{
+				$sql="SELECT
+					agenda.*, toolitemproperties.*
+					FROM ".$TABLEAGENDA." agenda, ".$TABLE_ITEM_PROPERTY." toolitemproperties
+					WHERE `agenda`.`id` = `toolitemproperties`.`ref`   ".$show_all_current."
+					AND `toolitemproperties`.`tool`='".TOOL_CALENDAR_EVENT."'
+					AND `toolitemproperties`.`to_group_id`='0'
+					AND `toolitemproperties`.`visibility`='1'
+					ORDER BY start_date ".$_SESSION['sort'];
+			}
+		}
+	} // you are a student
+
+	//echo "<pre>".$sql."</pre>";
+	$result=api_sql_query($sql,__FILE__,__LINE__) or die(mysql_error());
+	$number_items=mysql_num_rows($result);
+
+
+	/*--------------------------------------------------
+			DISPLAY: NO ITEMS
+	  --------------------------------------------------*/
+	if ($number_items==0)
+		{
+		 echo "<table id=\"agenda_list\" ><tr><td>".get_lang("NoAgendaItems")."</td></tr></table>";
+		}
+
+	/*--------------------------------------------------
+			DISPLAY: THE ITEMS
+	  --------------------------------------------------*/
+	echo "<table id=\"agenda_list\">\n";
+
+	$month_bar="";
+	$event_list="";
+	while ($myrow=mysql_fetch_array($result))
+{
+
+/*--------------------------------------------------
+		display: the month bar
+  --------------------------------------------------*/
+// Make the month bar appear only once.
+	if ($month_bar != date("m",strtotime($myrow["start_date"])).date("Y",strtotime($myrow["start_date"])))
+		{
+		$month_bar = date("m",strtotime($myrow["start_date"])).date("Y",strtotime($myrow["start_date"]));
+			echo "\t<tr>\n\t\t<td class=\"agenda_month_divider\" colspan=\"2\" valign=\"top\">".
+			ucfirst(format_locale_date("%B %Y",strtotime($myrow["start_date"]))).
+			"</td>\n\t</tr>\n";
+		}
+
+/*--------------------------------------------------
+ display: the icon, title, destinees of the item
+  --------------------------------------------------*/
+	echo "\t<tr>\n";
+
+	// highlight: if a date in the small calendar is clicked we highlight the relevant items
+	$db_date=(int)date("d",strtotime($myrow["start_date"])).date("n",strtotime($myrow["start_date"])).date("Y",strtotime($myrow["start_date"]));
+	if ($_GET["day"].$_GET["month"].$_GET["year"] <>$db_date)
+	{
+		if ($myrow['visibility']=='0')
+		{
+			$style="data_hidden";
+			$stylenotbold="datanotbold_hidden";
+			$text_style="text_hidden";
+		}
+		else
+		{
+			$style="data";
+			$stylenotbold="datanotbold";
+			$text_style="text";
+		}
+
+	}
+	else
+	{
+		$style="datanow";
+		$stylenotbold="datanotboldnow";
+		$text_style="textnow";
+	}
+
+
+
+	echo "\t\t<td class=\"".$style."\">\n";
+
+	// adding an internal anchor
+	echo "\t\t\t<a name=\"".(int)date("d",strtotime($myrow["start_date"]))."\"></a>";
+
+	// the icons. If the message is sent to one or more specific users/groups
+	// we add the groups icon
+	// 2do: if it is sent to groups we display the group icon, if it is sent to a user we show the user icon
+	echo "<img src=\"../img/agenda.gif\" border=\"0\" />";
+	if ($myrow['to_group_id']!=='0')
+		{
+		echo "<img src=\"../img/group.gif\" border=\"0\" />";
+		}
+	echo " ".$myrow['title']."\n";
+	echo "\t\t</td>\n";
+
+	// the message has been sent to
+	echo "\t\t<td class=\"".$stylenotbold."\">".get_lang("SentTo").": ";
+	$sent_to=sent_to(TOOL_CALENDAR_EVENT, $myrow["ref"]);
+	$sent_to_form=sent_to_form($sent_to);
+	echo $sent_to_form;
+	echo "</td>\n\t</tr>\n";
+
+/*--------------------------------------------------
+ 			display: the title
+  --------------------------------------------------*/
+	echo "\t<tr class=\"".$stylenotbold."\">\n";
+	echo "\t\t<td>".get_lang("StartTimeWindow").": ";
+	echo ucfirst(format_locale_date($dateFormatLong,strtotime($myrow["start_date"])))."&nbsp;&nbsp;&nbsp;";
+	echo ucfirst(strftime($timeNoSecFormat,strtotime($myrow["start_date"])))."";
+	echo "</td>\n";
+	echo "\t\t<td>";
+	if ($myrow["end_date"]<>"0000-00-00 00:00:00")
+	{
+		echo get_lang("EndTimeWindow").": ";
+		echo ucfirst(format_locale_date($dateFormatLong,strtotime($myrow["end_date"])))."&nbsp;&nbsp;&nbsp;";
+		echo ucfirst(strftime($timeNoSecFormat,strtotime($myrow["end_date"])))."";
+	}
+	echo "</td>\n";
+	echo "\n\t</tr>\n";
+
+/*--------------------------------------------------
+ 			display: the content
+  --------------------------------------------------*/
+	$content = $myrow['content'];
+	$content = make_clickable($content);
+	$content = text_filter($content);
+	echo "\t<tr>\n\t\t<td class=\"".$text_style."\" colspan='2'>";
+
+	echo '<a href="#" onclick="javascript:win_print=window.open(\'print.php?id='.$myrow['id'].'\',\'popup\',\'left=100,top=100,width=700,height=500,scrollbars=1,resizable=0\'); win_print.focus(); return false;"><img src="../img/print.png" border="0" title="'.htmlentities(get_lang('Print')).'" /></a>&nbsp;';
+
+	echo $content;
+	echo "</td></tr>";
+
+/*--------------------------------------------------
+ 			display: the added resources
+  --------------------------------------------------*/
+	if (check_added_resources("Agenda", $myrow["id"]))
+		{
+		echo "<tr><td colspan='2'>";
+		echo "<i>".get_lang("AddedResources")."</i><br/>";
+		if ($myrow['visibility']==0)
+		{
+			$addedresource_style="invisible";
+		}
+		display_added_resources("Agenda", $myrow["id"], $addedresource_style);
+		echo "</td></tr>";
+		}
+
+/*--------------------------------------------------
+	display: edit delete button (course admin only)
+  --------------------------------------------------*/
+  
+	$event_list.=$myrow['id'].',';
+  
+	echo "<tr><td>";
+			if (is_allowed_to_edit() OR api_get_course_setting('allow_user_edit_agenda'))
+	{
+		// edit
+		echo 	"<a href=\"".$_SERVER['PHP_SELF']."?origin=".$_GET['origin']."&action=edit&id=".$myrow['id']."\">",
+				"<img src=\"../img/edit.gif\" border=\"0\" align=\"absmiddle\" alt=\"".get_lang("ModifyCalendarItem")."\" /></a>",
+				"<a href=\"".$_SERVER['PHP_SELF']."?origin=".$_GET['origin']."&action=delete&id=".$myrow['id']."\" onclick=\"javascript:if(!confirm('".addslashes(htmlentities(get_lang("ConfirmYourChoice")))."')) return false;\">",
+				"<img src=\"../img/delete.gif\" border=\"0\" align=\"absmiddle\" alt=\"".get_lang("Delete")."\"/></a>";
+		echo 	"<a href=\"".$_SERVER['PHP_SELF']."?origin=".$_GET['origin']."&action=announce&id=".$myrow['id']."\">".
+				"<img src=\"../img/valves_add.gif\" border=\"0\" align=\"absmiddle\" alt=\"".get_lang("AddAnnouncement")."\"/></a>";
+		if ($myrow['visibility']==1)
+		{
+			$image_visibility="visible";
+		}
+		else
+		{
+			$image_visibility="invisible";
+		}
+		echo 	"<a href=\"".$_SERVER['PHP_SELF']."?origin=".$_GET['origin']."&amp;action=showhide&amp;id=".$myrow['id']."\">",
+				"<img src=\"../img/".$image_visibility.".gif\" border=\"0\" align=\"absmiddle\" alt=\"".get_lang("Visible")."\" /></a><br /><br />";
+	}
+	echo "</td>";
+
+/*--------------------------------------------------
+	display: jump-to-top icon
+  --------------------------------------------------*/
+	echo "<td><a href=\"#top\"><img src=\"../img/top.gif\" border=\"0\" alt=\"to top\" align=\"right\" /></a></td></tr>";
+} // end while ($myrow=mysql_fetch_array($result))
+echo "</table>";
+
+if(!empty($event_list))
+{
+	$event_list=substr($event_list,0,-1);
+}
+else
+{
+	$event_list='0';
+}
+
+echo "<form name=\"event_list_form\"><input type=\"hidden\" name=\"event_list\" value=\"$event_list\" /></form>";
+
+// closing the layout table
+echo "</td>",
+	"</tr>",
+	"</table>";
+}
+
+/**
+* Displays only 1 agenda item. This is used when an agenda item is added to the learning path.
+* @author Patrick Cool <patrick.cool@UGent.be>, Ghent University
+*/
+function display_one_agenda_item($agenda_id)
+{
+	global $TABLEAGENDA;
+	global $TABLE_ITEM_PROPERTY;
+	global $select_month, $select_year;
+	global $DaysShort, $DaysLong, $MonthsLong;
+	global $is_courseAdmin;
+	global $dateFormatLong, $timeNoSecFormat;
+	global $_uid;
+	//echo "displaying agenda items";
+
+
+	// getting the name of the groups
+	$group_names=get_course_groups();
+
+	/*--------------------------------------------------
+			CONSTRUCT THE SQL STATEMENT
+	  --------------------------------------------------*/
+
+	$sql="SELECT agenda.*, toolitemproperties.*
+					FROM ".$TABLEAGENDA." agenda, ".$TABLE_ITEM_PROPERTY." toolitemproperties
+					WHERE `agenda`.`id` = `toolitemproperties`.`ref`
+					AND `toolitemproperties`.`tool`='".TOOL_CALENDAR_EVENT."'
+					AND `toolitemproperties`.`visibility`='1'
+					AND `agenda`.`id`='$agenda_id'";
+	$result=api_sql_query($sql,__FILE__,__LINE__) or die(mysql_error());
+	$number_items=mysql_num_rows($result);
+	$myrow=mysql_fetch_array($result); // there should be only one item so no need for a while loop
+
+	/*--------------------------------------------------
+			DISPLAY: NO ITEMS
+	  --------------------------------------------------*/
+	if ($number_items==0)
+		{
+		 echo "<table id=\"agenda_list\" ><tr><td>".get_lang("NoAgendaItems")."</td></tr></table>";
+		}
+
+	/*--------------------------------------------------
+			DISPLAY: THE ITEMS
+	  --------------------------------------------------*/
+	echo "<table id=\"agenda_list\">\n";
+
+
+
+
+	/*--------------------------------------------------
+	 DISPLAY : the icon, title, destinees of the item
+	  --------------------------------------------------*/
+	echo "\t<tr>\n";
+
+	// highlight: if a date in the small calendar is clicked we highlight the relevant items
+	$db_date=(int)date("d",strtotime($myrow["start_date"])).date("n",strtotime($myrow["start_date"])).date("Y",strtotime($myrow["start_date"]));
+	if ($_GET["day"].$_GET["month"].$_GET["year"] <>$db_date)
+	{
+		if ($myrow['visibility']=='0')
+		{
+			$style="data_hidden";
+			$stylenotbold="datanotbold_hidden";
+			$text_style="text_hidden";
+		}
+		else
+		{
+			$style="data";
+			$stylenotbold="datanotbold";
+			$text_style="text";
+		}
+
+	}
+	else
+	{
+		$style="datanow";
+		$stylenotbold="datanotboldnow";
+		$text_style="textnow";
+	}
+
+
+	echo "\t\t<td class=\"".$style."\">\n";
+
+	// adding an internal anchor
+	echo "\t\t\t<a name=\"".(int)date("d",strtotime($myrow["start_date"]))."\"></a>";
+
+	// the icons. If the message is sent to one or more specific users/groups
+	// we add the groups icon
+	// 2do: if it is sent to groups we display the group icon, if it is sent to a user we show the user icon
+	echo "<img src=\"../img/agenda.gif\" border=\"0\" />";
+	if ($myrow['to_group_id']!=='0')
+		{
+		echo "<img src=\"../img/group.gif\" border=\"0\" />";
+		}
+	echo " ".$myrow['title']."\n";
+	echo "\t\t</td>\n";
+
+	// the message has been sent to
+	echo "\t\t<td class=\"".$stylenotbold."\">".get_lang("SentTo").": ";
+	$sent_to=sent_to(TOOL_CALENDAR_EVENT, $myrow["ref"]);
+	$sent_to_form=sent_to_form($sent_to);
+	echo $sent_to_form;
+	echo "</td>\n\t</tr>\n";
+
+	/*--------------------------------------------------
+	 			DISPLAY: the title
+	  --------------------------------------------------*/
+	echo "\t<tr class=\"".$stylenotbold."\">\n";
+	echo "\t\t<td>".get_lang("StartTime").": ";
+	echo ucfirst(format_locale_date($dateFormatLong,strtotime($myrow["start_date"])))."&nbsp;&nbsp;&nbsp;";
+	echo ucfirst(strftime($timeNoSecFormat,strtotime($myrow["start_date"])))."";
+	echo "</td>\n";
+	echo "\t\t<td>".get_lang("EndTime").": ";
+	echo ucfirst(format_locale_date($dateFormatLong,strtotime($myrow["end_date"])))."&nbsp;&nbsp;&nbsp;";
+	echo ucfirst(strftime($timeNoSecFormat,strtotime($myrow["end_date"])))."";
+	echo "</td>\n";
+	echo "\n\t</tr>\n";
+
+	/*--------------------------------------------------
+	 			DISPLAY: the content
+	  --------------------------------------------------*/
+	$content = $myrow['content'];
+	$content = make_clickable($content);
+	$content = text_filter($content);
+	echo "\t<tr>\n\t\t<td class=\"".$text_style."\" colspan='2'>";
+	echo $content;
+	echo "</td></tr>";
+
+	/*--------------------------------------------------
+	 			DISPLAY: the added resources
+	  --------------------------------------------------*/
+	if (check_added_resources("Agenda", $myrow["id"]))
+		{
+		echo "<tr><td colspan='2'>";
+		echo "<i>".get_lang("AddedResources")."</i><br/>";
+		if ($myrow['visibility']==0)
+		{
+			$addedresource_style="invisible";
+		}
+		display_added_resources("Agenda", $myrow["id"], $addedresource_style);
+		echo "</td></tr>";
+		}
+
+	/*--------------------------------------------------
+		DISPLAY: edit delete button (course admin only)
+	  --------------------------------------------------*/
+	echo "<tr><td>";
+	if (is_allowed_to_edit())
+		{
+		// edit
+		echo 	"<a href=\"".$_SERVER['PHP_SELF']."?origin=".$_GET['origin']."&amp;action=edit&amp;id=".$myrow['id']."\">",
+				"<img src=\"../img/edit.gif\" border=\"0\" alt=\"".get_lang("ModifyCalendarItem")."\" /></a>",
+				"<a href=\"".$_SERVER['PHP_SELF']."?origin=".$_GET['origin']."&amp;action=delete&amp;id=".$myrow['id']."\" onclick=\"javascript:if(!confirm('".addslashes(htmlentities(get_lang("ConfirmYourChoice")))."')) return false;\">",
+				"<img src=\"../img/delete.gif\" border=\"0\" alt=\"".get_lang("Delete")."\" /></a>";
+		if ($myrow['visibility']==1)
+			{
+			$image_visibility="visible";
+			}
+		else
+			{
+			$image_visibility="invisible";
+			}
+		echo 	"<a href=\"".$_SERVER['PHP_SELF']."?origin=".$_GET['origin']."&amp;action=showhide&amp;id=".$myrow['id']."\">",
+				"<img src=\"../img/".$image_visibility.".gif\" border=\"0\" alt=\"".get_lang("Visible")."\" /></a><br /><br />";
+		}
+	echo "</td>";
+	echo "</table>";
+
+	// closing the layout table
+	echo "</td>",
+		"</tr>",
+		"</table>";
+}
+
+
+
+
+/**
+* Show the form for adding a new agenda item. This is the same function that is used whenever we are editing an
+* agenda item. When the id parameter is empty (default behaviour), then we show an empty form, else we are editing and
+* we have to retrieve the information that is in the database and use this information in the forms.
+* @author Patrick Cool <patrick.cool@UGent.be>, Ghent University
+* @param integer id, the id of the agenda itme we are editing. By default this is empty which means that we are adding an
+*		 agenda item.
+*/
+function show_add_form($id = '')
+{
+	global $MonthsLong;
+
+	// the default values for the forms
+	if ($_GET['originalresource'] !== 'no')
+	{
+		$day	= date('d');
+		$month	= date('m');
+		$year	= date('Y');
+		$hours	= date('H');
+		$minutes= date('i');
+
+		$end_day	= date('d');
+		$end_month	= date('m');
+		$end_year	= date('Y');
+		$end_hours	= date('H');
+		$end_minutes= date('i');
+	}
+	else
+	{
+
+		// we are coming from the resource linker so there might already have been some information in the form.
+		// When we clicked on the button to add resources we stored every form information into a session and now we
+		// are doing the opposite thing: getting the information out of the session and putting it into variables to
+		// display it in the forms.
+		$form_elements=$_SESSION['formelements'];
+		$day=$form_elements['day'];
+		$month=$form_elements['month'];
+		$year=$form_elements['year'];
+		$hours=$form_elements['hour'];
+		$minutes=$form_elements['minutes'];
+		$end_day=$form_elements['end_day'];
+		$end_month=$form_elements['end_month'];
+		$end_year=$form_elements['end_year'];
+		$end_hours=$form_elements['end_hours'];
+		$end_minutes=$form_elements['end_minutes'];
+		$title=$form_elements['title'];
+		$content=$form_elements['content'];
+		$id=$form_elements['id'];
+		$to=$form_elements['to'];
+	}
+
+
+	//	switching the send to all/send to groups/send to users
+	if ($_POST['To'])
+	{
+			$day			= $_POST['fday'];
+			$month			= $_POST['fmonth'];
+			$year			= $_POST['fyear'];
+			$hours			= $_POST['fhour'];
+			$minutes		= $_POST['fminute'];
+			$end_day		= $_POST['end_fday'];
+			$end_month		= $_POST['end_fmonth'];
+			$end_year		= $_POST['end_fyear'];
+			$end_hours		= $_POST['end_fhour'];
+			$end_minutes	= $_POST['end_fminute'];
+			$title 			= $_POST['title'];
+			$content		= $_POST['content'];
+			// the invisible fields
+			$action			= $_POST['action'];
+			$id				= $_POST['id'];
+		}
+
+
+	// if the id is set then we are editing an agenda item
+	if (is_int($id))
+	{
+		//echo "before get_agenda_item".$_SESSION['allow_individual_calendar'];
+		$item_2_edit=get_agenda_item($id);
+		$title	= $item_2_edit['title'];
+		$content= $item_2_edit['content'];
+		// start date
+		list($datepart, $timepart) = split(" ", $item_2_edit['start_date']);
+		list($year, $month, $day) = explode("-", $datepart);
+		list($hours, $minutes, $seconds) = explode(":", $timepart);
+		// end date
+		list($datepart, $timepart) = split(" ", $item_2_edit['end_date']);
+		list($end_year, $end_month, $end_day) = explode("-", $datepart);
+		list($end_hours, $end_minutes, $end_seconds) = explode(":", $timepart);
+		// attachments
+		edit_added_resources("Agenda", $id);
+		$to=$item_2_edit['to'];
+		//echo "<br />after get_agenda_item".$_SESSION['allow_individual_calendar'];
+	}
+
+	// we start a completely new item, we do not come from the resource linker
+	if ($_GET['originalresource']!=="no" and $_GET['action']=="add")
+	{
+
+		$_SESSION["formelements"]=null;
+		unset_session_resources();
+	}
+?>
+
+<!-- START OF THE FORM  -->
+<form action="<?php echo $_SERVER['PHP_SELF'].'?origin='.$_GET['origin'].'&amp;action='.$_GET['action']; ?>" method="post" name="new_calendar_item">
+<input type="hidden" name="id" value="<?php if (isset($id)) echo $id; ?>" />
+<input type="hidden" name="action" value="<?php if (isset($_GET['action'])) echo $_GET['action']; ?>" />
+
+<table border="0" cellpadding="5" cellspacing="0" width="100%" id="newedit_form">
+	<!-- the title -->
+	<tr class="title">
+		<td colspan="3">
+		<h4><?php echo (isset($id) AND $id<>'')?get_lang('ModifyCalendarItem'):get_lang("AddCalendarItem"); ?></h4>
+		</td>
+	</tr>
+
+	<!--  the select specific users / send to all form -->
+	<?php
+	if (isset ($_SESSION['toolgroup']))
+	{
+		echo '<tr id="subtitle">';
+		echo '<td colspan="3">';
+		echo '<input type="hidden" name="selectedform[0]" value="GROUP:'.$_SESSION['toolgroup'].'"/>' ; 
+		echo '<input type="hidden" name="To" value="true"/>' ; 
+		echo '</td>';
+		echo '</tr>'; 
+	
+	}else{ 
+		?>
+		<tr class="subtitle">
+			<td valign="top" colspan="3">
+				<?php
+				// this variable defines if the course administrator can send a message to a specific user / group
+				// or not 
+				echo "<input type=\"submit\" name=\"To\" value=\"".get_lang("SelectGroupsUsers")."\" style=\"float:left\">" ;
+	
+				//echo "sessiewaarde: ".$_SESSION['allow_individual_calendar'];
+				if ($_SESSION['allow_individual_calendar']=="hide")
+				{
+					echo '<select name="selectedform[]" size="1" multiple="multiple" style="width:200px" width="200px"><option>'.get_lang("Everybody").'</option></select>';
+				}
+				if ($_SESSION['allow_individual_calendar']=="show")
+				{
+					show_to_form($to);
+				}
+			?>
+			<hr noshade="noshade" color="#cccccc" />
+		</td>
+	</tr>
+
+	<?php 
+	} 
+	?>
+
+	<!-- START date and time -->
+	<tr class="subtitle">
+		<td>
+			<!-- date: 1 -> 31 -->
+			<?php echo get_lang('StartDate').": \n"; ?>
+			<select name="fday" onchange="javascript:document.new_calendar_item.end_fday.value=this.value;">
+				<?php
+					// small loop for filling all the dates
+					// 2do: the available dates should be those of the selected month => february is from 1 to 28 (or 29) and not to 31
+					echo "\n";
+					foreach (range(1, 31) as $i)
+					{
+						// values have to have double digits
+						$value = ($i <= 9 ? '0'.$i : $i );
+						// the current day is indicated with [] around the date
+						if ($value==$day)
+						{ 
+							echo "\t\t\t\t <option value=\"".$value."\" selected> ".$i." </option>\n";
+						}
+						else
+						{
+							echo "\t\t\t\t<option value=\"$value\">$i</option>\n";
+						}
+					}
+					 ?>
+			</select>
+
+			<!-- month: january -> december -->
+			<select name="fmonth" onchange="javascript:document.new_calendar_item.end_fmonth.value=this.value;">
+				<?php
+					echo "\n";
+					for ($i=1; $i<=12; $i++)
+					{
+						// values have to have double digits
+						if ($i<=9)
+						{
+							$value="0".$i;
+						}
+						else
+						{
+							$value=$i;
+						}
+						if ($value==$month)
+						{ 
+							echo "\t\t\t\t <option value=\"".$value."\" selected>".$MonthsLong[$i-1]."</option>\n"; 
+						}
+						else
+						{ 
+							echo "\t\t\t\t <option value=\"".$value."\">".$MonthsLong[$i-1]."</option>\n"; 
+						}
+					} ?>
+			</select>
+
+			<select name="fyear" onchange="javascript:document.new_calendar_item.end_fyear.value=this.value;">
+				<option value="<?php echo ($year-1); ?>"><?php echo ($year-1); ?></option>
+				<option value="<?php echo $year; ?>" selected="selected"><?php echo $year; ?></option>
+				<?php
+					echo "\n";
+					for ($i=1; $i<=5; $i++)
+					{
+						$value=$year+$i;
+						echo "\t\t\t\t<option value=\"$value\">$value</option>\n";
+					} ?>
+			</select>
+			<a href="javascript:openCalendar('new_calendar_item', 'f')"><img src="../img/calendar_select.gif" border="0" /></a>
+		</td>
+		<td>
+			<?php echo get_lang('StartTime').': '; ?>
+			<select name="fhour" onchange="javascript:document.new_calendar_item.end_fhour.value=this.value;">
+				<option value="--">--</option>
+				<?php
+					echo "\n";
+					foreach (range(1, 24) as $i)
+					{
+						// values have to have double digits
+						$value = ($i <= 9 ? '0'.$i : $i );
+						// the current hour is indicated with [] around the hour
+						if ($hours==$value)
+						{ 
+							echo "\t\t\t\t<option value=\"".$value."\" selected> ".$value." </option>\n"; 
+						}
+						else
+						{
+							echo "\t\t\t\t<option value=\"$value\">$value</option>\n";
+						}
+					} ?>
+			</select>
+			<?php echo get_lang('HourMinuteDivider'); ?>
+			<select name="fminute" onchange="javascript:document.new_calendar_item.end_fminute.value=this.value;">
+				<option value="<?php echo $minutes ?>"><?php echo $minutes; ?></option>
+				<option value="--">--</option>
+				<?php
+					foreach (range(0, 59) as $i)
+					{
+						// values have to have double digits
+						$value = ($i <= 9 ? '0'.$i : $i );
+						echo "\t\t\t\t<option value=\"$value\">$value</option>\n";
+					} ?>
+			</select>
+		</td>
+	</tr>
+	<!-- END date and time -->
+
+	<tr class="subtitle">
+		<td>
+			<!-- date: 1 -> 31 -->
+			<?php echo get_lang('EndDate').": \n"; ?>
+			<select name="end_fday">
+				<?php
+					// small loop for filling all the dates
+					// 2do: the available dates should be those of the selected month => february is from 1 to 28 (or 29) and not to 31
+					echo "\n";
+					foreach (range(1, 31) as $i)
+					{
+						// values have to have double digits
+						$value = ($i <= 9 ? '0'.$i : $i );
+						// the current day is indicated with [] around the date
+						if ($value==$end_day)
+							{ echo "\t\t\t\t <option value=\"".$value."\" selected> ".$i." </option>\n";}
+						else
+							{ echo "\t\t\t\t <option value=\"".$value."\">".$i."</option>\n"; }
+						}?>
+				</select>
+
+				<!-- month: january -> december -->
+				<select name="end_fmonth">
+					<?php
+					echo "\n";
+					foreach (range(1, 12) as $i)
+					{
+						// values have to have double digits
+						$value = ($i <= 9 ? '0'.$i : $i );
+						if ($value==$end_month)
+							{ echo "\t\t\t\t <option value=\"".$value."\" selected>".$MonthsLong[$i-1]."</option>\n"; }
+						else
+							{ echo "\t\t\t\t <option value=\"".$value."\">".$MonthsLong[$i-1]."</option>\n"; }
+						}?>
+				</select>
+
+				<select name="end_fyear">
+					<option value="<?php echo ($end_year-1) ?>"><?php echo ($end_year-1) ?></option>
+					<option value="<?php echo $end_year ?>" selected> <?php echo $end_year ?> </option>
+					<?php
+					echo "\n";
+					for ($i=1; $i<=5; $i++)
+					{
+						$value=$end_year+$i;
+						echo "\t\t\t\t<option value=\"$value\">$value</option>\n";
+					} ?>
+			</select>
+			<a href="javascript:openCalendar('new_calendar_item', 'end_f')"><img src="../img/calendar_select.gif" border="0" /></a>
+		</td>
+
+		<td>
+			<?php echo get_lang('EndTime').': ';?>
+			<select name="end_fhour">
+				<option value="--">--</option>
+				<?php
+					echo "\n";
+					foreach (range(1, 24) as $i)
+					{
+						// values have to have double digits
+						$value = ($i <= 9 ? '0'.$i : $i );
+						// the current hour is indicated with [] around the hour
+						if ($end_hours==$value)
+							{ echo "\t\t\t\t<option value=\"".$value."\" selected> ".$value." </option>\n"; }
+						else
+							{ echo "\t\t\t\t<option value=\"".$value."\"> ".$value." </option>\n"; }
+					} ?>
+			</select>
+			<?php echo get_lang('HourMinuteDivider'); ?>
+			<select name="end_fminute">
+				<option value="<?php echo $end_minutes; ?>"><?php echo $end_minutes; ?></option>
+				<option value="--">--</option>
+				<?php
+					foreach (range(0, 59) as $i)
+					{
+						// values have to have double digits
+						$value = ($i <= 9 ? '0'.$i : $i );
+						echo "\t\t\t\t<option value=\"$value\">$value</option>\n";
+					} ?>
+			</select>
+		</td>
+	</tr>
+
+	<tr class="subtitle">
+		<td colspan="3" valign="top"><hr noshade="noshade" color="#cccccc" /><?php echo get_lang('ItemTitle'); ?> :
+			<textarea name="title" cols="50" rows="2" wrap="virtual" style="vertical-align:top; width:75%; height:50px;"><?php  if (isset($title)) echo $title; ?></textarea>
+			<!-- <input type="text" size="60" name="title" value="<?php  if (isset($title)) echo $title; ?>" /> -->
+		</td>
+	</tr>
+
+	<tr>
+		<td colspan="7"><?php echo get_lang('Detail'); ?> :</td>
+	</tr>
+
+	<tr>
+		<td colspan="7">
+			<?php api_disp_html_area('content',$content,'300px'); ?><br />
+		</td>
+	</tr>
+	<?php /* ADDED BY UGENT, Patrick Cool, march 2004 */ ?>
+	<tr>
+		<td colspan="7">
+	    <?php
+			//onclick="selectAll(this.form.elements[6],true)"
+			if ($_SESSION['allow_individual_calendar']=='show')
+				show_addresource_button('onclick="selectAll(this.form.elements[6],true)"');
+			else
+				show_addresource_button();
+			$form_elements=$_SESSION['formelements'];
+		?>
+		</td>
+	</tr>
+	<?php
+	   //if ($_SESSION['addedresource'])
+	   echo "\t<tr>\n";
+	   echo "\t\t<td colspan=\"7\">\n";
+	   echo display_resources(0);
+	   $test=$_SESSION['addedresource'];
+	   echo "\t\t</td>\n\t</tr>\n";
+	   /* END ADDED BY UGENT, Patrick Cool, march 2004 */
+	?>
+
+	<tr>
+		<td colspan="7">
+			<input type="submit" name="submit_event" value="<?php echo get_lang('Ok'); ?>" onclick="selectAll(this.form.elements[6],true)" />
+		</td>
+	</tr>
+</table>
+</form>
+<p>&nbsp;</p>
+<?php
+}
+?>

+ 355 - 0
main/calendar/agenda.php

@@ -0,0 +1,355 @@
+<?php //$Id: agenda.php 9246 2006-09-25 13:24:53Z bmol $
+/*
+==============================================================================
+	Dokeos - elearning and course management software
+
+	Copyright (c) 2004-2005 Dokeos S.A.
+	Copyright (c) 2003-2005 Ghent University (UGent)
+	Copyright (c) various contributors
+
+	For a full list of contributors, see "credits.txt".
+	The full license can be read in "license.txt".
+
+	This program is free software; you can redistribute it and/or
+	modify it under the terms of the GNU General Public License
+	as published by the Free Software Foundation; either version 2
+	of the License, or (at your option) any later version.
+
+	See the GNU General Public License for more details.
+
+	Contact address: Dokeos, 44 rue des palais, B-1030 Brussels, Belgium
+	Mail: info@dokeos.com
+==============================================================================
+*/
+/*
+============================================================================== 
+	   INIT SECTION
+============================================================================== 
+*/
+// setting the language file
+$langFile = 'agenda';
+
+// setting the global file that gets the general configuration, the databases, the languages, ...
+include('../inc/global.inc.php');
+
+//session
+if(isset($_GET['id_session']))
+{
+	$_SESSION['id_session'] = $_GET['id_session'];
+}
+
+$this_section=SECTION_COURSES;
+
+//error_reporting(E_ALL);
+require (api_get_path(LIBRARY_PATH).'groupmanager.lib.php');
+
+/* ============================================================================== 
+  			ACCESS RIGHTS
+============================================================================== */
+// notice for unauthorized people. 
+api_protect_course_script();
+
+/*
+-----------------------------------------------------------
+	Resource linker (Patrick Cool, march 2004)
+-----------------------------------------------------------
+*/
+$_SESSION['source_type'] = 'Agenda';
+include('../resourcelinker/resourcelinker.inc.php');
+if ($addresources) // When the "Add Resource" button is clicked we store all the form data into a session
+{
+$form_elements= array ('day'=>$_POST['fday'], 'month'=>$_POST['fmonth'], 'year'=>$_POST['fyear'], 'hour'=>$_POST['fhour'], 'minutes'=>$_POST['fminute'],
+						'end_day'=>$_POST['end_fday'], 'end_month'=>$_POST['end_fmonth'], 'end_year'=>$_POST['end_fyear'], 'end_hours'=>$_POST['end_fhour'], 'end_minutes'=>$_POST['end_fminute'], 
+						'title'=>stripslashes($_POST['title']), 'content'=>stripslashes($_POST['content']), 'id'=>$_POST['id'], 'action'=>$_POST['action'], 'to'=>$_POST['selectedform']);
+$_SESSION['formelements']=$form_elements;
+if($id) // this is to correctly handle edits
+	{$action="edit";}
+//print_r($form_elements);
+header('Location: '.api_get_path(WEB_CODE_PATH)."resourcelinker/resourcelinker.php?source_id=1&action=$action&id=$id&originalresource=no");
+exit;
+}
+
+/*
+-----------------------------------------------------------
+	Libraries
+-----------------------------------------------------------
+*/
+// containing the functions for the agenda tool
+include "agenda.inc.php";
+// some debug functions
+include($includePath."/lib/debug.lib.inc.php");
+
+/*============================================================================== 
+  			TREATING THE PARAMETERS 
+			1. viewing month only or everything
+			2. sort ascending or descending
+			3. showing or hiding the send-to-specific-groups-or-users form
+			4. filter user or group
+  ============================================================================== */
+// 1. show all or show current month?
+if (!$_SESSION['show'])
+{
+	$_SESSION['show']="showall";
+}
+if ($_GET['action']=="showcurrent")
+{
+	$_SESSION['show']="showcurrent";
+}
+if ($_GET['action']=="showall")
+{
+	$_SESSION['show']="showall";
+}
+//echo $_SESSION['show'];
+	
+// 2. sorting order (ASC or DESC)
+if (!$_GET['sort'] and !$_SESSION['sort'])
+{
+	$_SESSION['sort']="DESC";
+}
+if ($_GET['sort']=="asc")
+{
+	$_SESSION['sort']="ASC";
+}
+if ($_GET['sort']=="desc")
+{
+	$_SESSION['sort']="DESC";
+}
+		
+// 3. showing or hiding the send-to-specific-groups-or-users form	
+$setting_allow_individual_calendar=true; 
+if (!$_POST['To'] and !$_SESSION['allow_individual_calendar'])
+{
+	$_SESSION['allow_individual_calendar']="hide";
+}
+$allow_individual_calendar_status=$_SESSION['allow_individual_calendar']; 
+if ($_POST['To'] and ($allow_individual_calendar_status=="hide"))
+{
+	$_SESSION['allow_individual_calendar']="show";
+}
+if ($_POST['To'] and ($allow_individual_calendar_status=="show"))
+{
+	$_SESSION['allow_individual_calendar']="hide";
+}
+		
+// 4. filter user or group
+if ($_GET['user'] or $_GET['group'])
+{
+	$_SESSION['user']=$_GET['user'];
+	$_SESSION['group']=$_GET['group'];
+}
+if ($_GET['user']=="none" or $_GET['group']=="none")
+{
+	api_session_unregister("user"); 
+	api_session_unregister("group"); 
+	}
+if (!$is_courseAdmin){
+	if (!empty($_GET['toolgroup'])){
+		//$_SESSION['toolgroup']=$_GET['toolgroup'];
+		$toolgroup=$_GET['toolgroup'];
+		api_session_register('toolgroup');
+		}
+	}
+	//It comes from the group tools. If it's define it overwrites $_SESSION['group'] 	
+if ($_GET['isStudentView']=="false")
+{
+	api_session_unregister("user"); 
+	api_session_unregister("group"); 
+}
+
+// setting the javascripts 
+if ($_SESSION['allow_individual_calendar']=="show")
+{
+	// this javascript should only be loaded when we show the forms to send messages to individual users/groups
+	// because otherwise it produces a bug (=> year is set to 2009 on submit due to the javascript selectAll
+	$htmlHeadXtra[] = to_javascript();
+}
+$htmlHeadXtra[] = user_group_filter_javascript(); 
+// this loads the javascript that is needed for the date popup selection
+$htmlHeadXtra[] = "<script src=\"tbl_change.js\" type=\"text/javascript\" language=\"javascript\"></script>";
+
+// setting the name of the tool
+$nameTools = get_lang("langcalendar_event"); // language variable in trad4all.inc.php
+
+// showing the header if we are not in the learning path, if we are in 
+// the learning path, we do not include the banner so we have to explicitly 
+// include the stylesheet, which is normally done in the header
+if ($_GET['origin'] != 'learnpath') 
+{ 
+	Display::display_header($nameTools,'Agenda');
+}
+else 
+{
+	echo "<link rel=\"stylesheet\" type=\"text/css\" href=\"".$clarolineRepositoryWeb."css/default.css\"/>";
+	}
+
+/* ============================================================================== 
+  			TRACKING
+==============================================================================  */
+include('../inc/lib/events.lib.inc.php');
+event_access_tool(TOOL_CALENDAR_EVENT);
+
+/* ============================================================================== 
+  			SETTING SOME VARIABLES
+============================================================================== */
+// Variable definitions
+$dateNow 			= format_locale_date($dateTimeFormatLong);
+// Defining the shorts for the days. We use camelcase because these are arrays of language variables
+$DaysShort = array (get_lang("SundayShort"), get_lang("MondayShort"), get_lang("TuesdayShort"), get_lang("WednesdayShort"), get_lang("ThursdayShort"), get_lang("FridayShort"), get_lang("SaturdayShort"));
+// Defining the days of the week to allow translation of the days. We use camelcase because these are arrays of language variables
+$DaysLong = array (get_lang("SundayLong"), get_lang("MondayLong"), get_lang("TuesdayLong"), get_lang("WednesdayLong"), get_lang("ThursdayLong"), get_lang("FridayLong"), get_lang("SaturdayLong"));
+// Defining the months of the year to allow translation of the months. We use camelcase because these are arrays of language variables
+$MonthsLong = array (get_lang("JanuaryLong"), get_lang("FebruaryLong"), get_lang("MarchLong"), get_lang("AprilLong"), get_lang("MayLong"), get_lang("JuneLong"), get_lang("JulyLong"), get_lang("AugustLong"), get_lang("SeptemberLong"), get_lang("OctoberLong"), get_lang("NovemberLong"), get_lang("DecemberLong"));
+
+// setting the database variables
+$TABLEAGENDA 		= Database::get_course_table(AGENDA_TABLE);
+$TABLE_ITEM_PROPERTY = Database::get_course_table(LAST_TOOL_EDIT_TABLE);
+$tbl_user       = Database::get_main_table(MAIN_USER_TABLE);
+$tbl_courseUser = Database::get_main_table(MAIN_COURSE_USER_TABLE);
+$tbl_group      = Database::get_course_table(GROUP_TABLE);
+$tbl_groupUser  = Database::get_course_table(GROUP_USER_TABLE);
+$tbl_session_course_user= Database::get_main_table(MAIN_SESSION_COURSE_USER_TABLE);
+
+
+
+/* ============================================================================== 
+  			ACCESS RIGHTS
+============================================================================== */
+// permission stuff
+$is_allowedToEdit 	= is_allowed_to_edit();
+$is_allowed_to_edit = is_allowed_to_edit();
+
+/* ============================================================================== 
+  			TITLE 
+============================================================================== */
+// Displaying the title of the tool 
+//api_display_tool_title($nameTools);
+
+// tool introduction
+Display::display_introduction_section(TOOL_CALENDAR_EVENT);
+
+// insert an anchor (top) so one can jump back to the top of the page
+echo "<a name=\"top\"></a>";
+
+/*
+============================================================================== 
+		MAIN SECTION
+============================================================================== 
+*/
+
+//setting the default year and month
+$select_year = $_GET['year'];
+$select_month = $_GET['month'];
+if (($select_year==NULL) && ($select_month==NULL))
+{
+	$today = getdate();
+	$select_year = $today['year'];
+	$select_month = $today['mon'];
+}
+
+
+
+echo "<table width=\"100%\" border=\"0\" cellspacing=\"0\" cellpadding=\"0\">"
+		. "<tr>";
+
+// THE LEFT PART
+if ($_GET['origin']!='learnpath') 
+{ 
+	echo '<td width="220" height="19" valign="top">';
+	// the small calendar
+	$MonthName = $MonthsLong[$select_month -1];
+	$agenda_items=get_kalender_items($select_month,$select_year);
+	display_minimonthcalendar($agenda_items, $select_month,$select_year, $MonthName); 
+	// the links for adding, filtering, showall, ...
+	echo "<ul id=\"agenda_select\">";
+	if (is_allowed_to_edit())
+	{
+		display_courseadmin_links(); 
+	}
+	display_student_links();
+	echo "</ul>";
+	echo "</td>";
+	echo "<td width=\"20\" background=\"../img/verticalruler.gif\">&nbsp;</td>";
+}
+	
+
+
+
+// THE RIGHT PART
+echo "<td valign=\"top\">";
+
+if (is_allowed_to_edit())
+{
+	switch ($_GET['action'])
+	{
+		case "add":
+		
+			if ($_POST['submit_event'])
+			{
+				store_new_agenda_item();
+				display_agenda_items();
+			}
+			else
+			{
+				show_add_form();
+			}
+			break;
+		
+		case "edit":
+			if ($_POST['submit_event'])
+			{
+					store_edited_agenda_item();
+					display_agenda_items();
+			}
+			else
+			{
+					$id=(int)$_GET['id'];
+					show_add_form($id);
+			}
+			break;
+	
+		case "delete":
+			$id=(int)$_GET['id'];
+			delete_agenda_item($id);
+			display_agenda_items();
+			break;
+	
+		case "showhide":
+			$id=(int)$_GET['id'];
+			showhide_agenda_item($id);
+			display_agenda_items();
+			break;	
+		case "announce": //copying the agenda item into an announcement
+			$id=(int)$_GET['id'];
+			$ann_id = store_agenda_item_as_announcement($id);
+			$tool_group_link = (isset($_SESSION['toolgroup'])?'&toolgroup='.$_SESSION['toolgroup']:'');
+			Display::display_normal_message('Copied as announcement: <a href="../announcements/announcements.php?id='.$ann_id.$tool_group_link.'">New announcement</a>');
+			display_agenda_items();	
+	}
+}
+
+
+// this is for students and whenever the courseaministrator has not chosen any action. It is in fact the default behaviour
+if (!$_GET['action'] OR $_GET['action']=="showall"  OR $_GET['action']=="showcurrent" OR $_GET['action']=="view")
+{
+	if ($_GET['origin'] != 'learnpath') 
+	{
+		display_agenda_items();
+	}
+	else 
+	{
+		display_one_agenda_item($_GET['agenda_id']);
+	}
+}
+echo "&nbsp;</td></tr></table>";
+
+/*
+============================================================================== 
+		FOOTER 
+============================================================================== 
+*/
+// The footer is displayed only if we are not in the learnpath
+if ($_GET['origin'] != 'learnpath') 
+{ 
+	Display::display_footer();
+}	
+?>

+ 133 - 0
main/calendar/calendar.php

@@ -0,0 +1,133 @@
+<?php
+// including the relevant language file
+$langFile = "agenda";
+// including the claroline global 
+include('../inc/global.inc.php');
+
+//session
+if(isset($_GET['id_session']))
+	$_SESSION['id_session'] = $_GET['id_session'];
+	
+// the variables for the days and the months
+// Defining the shorts for the days
+$DaysShort = array(get_lang("SundayShort"), get_lang("MondayShort"), get_lang("TuesdayShort"), get_lang("WednesdayShort"), get_lang("ThursdayShort"), get_lang("FridayShort"), get_lang("SaturdayShort")); 
+// Defining the days of the week to allow translation of the days
+$DaysLong = array(get_lang("SundayLong"), get_lang("MondayLong"), get_lang("TuesdayLong"), get_lang("WednesdayLong"), get_lang("ThursdayLong"), get_lang("FridayLong"), get_lang("SaturdayLong")); 
+// Defining the months of the year to allow translation of the months
+$MonthsLong = array(get_lang("JanuaryLong"), get_lang("FebruaryLong"), get_lang("MarchLong"), get_lang("AprilLong"), get_lang("MayLong"), get_lang("JuneLong"), get_lang("JulyLong"), get_lang("AugustLong"), get_lang("SeptemberLong"), get_lang("OctoberLong"), get_lang("NovemberLong"), get_lang("DecemberLong")); 
+
+?>
+<html>
+<head>
+<title>Calendar</title>
+<style type="text/css">
+table.calendar
+{
+	width: 100%;	
+	font-size: 11px;
+	font-family: verdana, arial, helvetica, sans-serif;
+}
+table.calendar .monthyear
+{
+	background-color: #4171B5;
+	text-align: center;
+	color: #ffffff;
+}
+table.calendar .daynames
+{
+	background-color: #D3DFF1;
+	text-align: center;
+}
+table.calendar td
+{
+	width: 25px;
+	height: 25px;
+	background-color: #f5f5f5;	
+	text-align: center;
+}
+table.calendar td.selected
+{
+	border: 1px solid #ff0000; 
+	background-color: #FFCECE;
+}
+table.calendar td a
+{
+	width: 25px;
+	height: 25px;
+	text-decoration: none;
+}
+table.calendar td a:hover
+{
+	background-color: #ffff00;
+}
+table.calendar .monthyear a
+{
+	text-align: center;
+	color: #ffffff;
+}
+table.calendar .monthyear a:hover
+{
+	text-align: center;
+	color: #ff0000;
+	background-color: #ffff00;
+}
+</style>
+<script language="JavaScript" type="text/javascript">
+<!--
+    /* added 2004-06-10 by Michael Keck
+     *       we need this for Backwards-Compatibility and resolving problems
+     *       with non DOM browsers, which may have problems with css 2 (like NC 4)
+    */
+    var isDOM      = (typeof(document.getElementsByTagName) != 'undefined'
+                      && typeof(document.createElement) != 'undefined')
+                   ? 1 : 0;
+    var isIE4      = (typeof(document.all) != 'undefined'
+                      && parseInt(navigator.appVersion) >= 4)
+                   ? 1 : 0;
+    var isNS4      = (typeof(document.layers) != 'undefined')
+                   ? 1 : 0;
+    var capable    = (isDOM || isIE4 || isNS4)
+                   ? 1 : 0;
+    // Uggly fix for Opera and Konqueror 2.2 that are half DOM compliant
+    if (capable) {
+        if (typeof(window.opera) != 'undefined') {
+            var browserName = ' ' + navigator.userAgent.toLowerCase();
+            if ((browserName.indexOf('konqueror 7') == 0)) {
+                capable = 0;
+            }
+        } else if (typeof(navigator.userAgent) != 'undefined') {
+            var browserName = ' ' + navigator.userAgent.toLowerCase();
+            if ((browserName.indexOf('konqueror') > 0) && (browserName.indexOf('konqueror/3') == 0)) {
+                capable = 0;
+            }
+        } // end if... else if...
+    } // end if
+//-->
+</script>
+<script type="text/javascript" src="tbl_change.js"></script>
+<script type="text/javascript">
+<!--
+var month_names = new Array(
+<?php
+foreach($MonthsLong as $index => $month)
+{
+	echo '"'.$month.'",';
+}
+?>
+"");
+var day_names = new Array(
+<?php
+foreach($DaysShort as $index => $day)
+{
+	echo '"'.$day.'",';
+}
+?>
+"");
+//-->
+</script>
+</head>
+<body onload="initCalendar();">
+<div id="calendar_data"></div>
+<div id="clock_data"></div>
+</body>
+</html>

+ 7 - 0
main/calendar/index.html

@@ -0,0 +1,7 @@
+<html>
+<head>
+<meta http-equiv="refresh" content="0; url=agenda.php">
+</head>
+<body>
+</body>
+</html>

+ 1387 - 0
main/calendar/myagenda.php

@@ -0,0 +1,1387 @@
+<?php
+
+/*
+==============================================================================
+	Dokeos - elearning and course management software
+
+	Copyright (c) 2004 Dokeos S.A.
+	Copyright (c) 2003 Ghent University (UGent)
+
+	For a full list of contributors, see "credits.txt".
+	The full license can be read in "license.txt".
+
+	This program is free software; you can redistribute it and/or
+	modify it under the terms of the GNU General Public License
+	as published by the Free Software Foundation; either version 2
+	of the License, or (at your option) any later version.
+
+	See the GNU General Public License for more details.
+
+	Contact: Dokeos, 181 rue Royale, B-1000 Brussels, Belgium, info@dokeos.com
+==============================================================================
+	@author: Patrick Cool <patrick.cool@UGent.be>, Ghent University
+	@author: Toon Van Hoecke <toon.vanhoecke@ugent.be>, Ghent University
+	@author: Eric Remy (initial version)
+	@version: 2.2 alpha
+	@description: 	this file generates a general agenda of all items of the
+					courses the user is registered for
+==============================================================================
+	version info:
+	-------------
+	-> version 2.2 : Patrick Cool, patrick.cool@ugent.be, november 2004
+	Personal Agenda added. The user can add personal agenda items. The items
+	are stored in a dokeos_user database because it is not course or platform
+	based. A personal agenda view was also added. This lists all the personal
+	agenda items of that user.
+
+	-> version 2.1 : Patrick Cool, patrick.cool@ugent.be, , oktober 2004
+	This is the version that works with the Group based Agenda tool.
+
+	-> version 2.0 (alpha): Patrick Cool, patrick.cool@ugent.be, , oktober 2004
+	The 2.0 version introduces besides the month view also a week- and day view.
+	In the 2.5 (final) version it will be possible for the student to add his/her
+	own agenda items. The platform administrator can however decide if the students
+	are allowed to do this or not.
+	The alpha version only contains the three views. The personal agenda feature is
+	not yet completely finished. There are however already some parts of the code
+	for adding a personal agenda item present.
+	this code was not released in an official dokeos but was only used in the offical
+	server of the Ghent University where it underwent serious testing
+
+	-> version 1.5: Toon Van Hoecke, toon.vanhoecke@ugent.be, december 2003
+
+	-> version 1.0: Eric Remy, eremy@rmwc.edu, 6 Oct 2003
+	The tool was initially called master-calendar as it collects all the calendar
+	items of all the courses one is subscribed to. It was very soon integrated in
+	Dokeos as this was a really basic and very usefull tool.
+
+/* ==============================================================================
+				  			HEADER
+============================================================================== */
+
+
+// loading the language file
+$langFile = 'agenda';
+// we are not inside a course, so we reset the course id
+$cidReset = true;
+// setting the global file that gets the general configuration, the databases, the languages, ...
+require ('../inc/global.inc.php');
+$this_section = SECTION_MYAGENDA;
+
+require (api_get_path(LIBRARY_PATH).'groupmanager.lib.php');
+// setting the name of the tool
+$nameTools = get_lang('MyAgenda');
+
+// if we come from inside a course and click on the 'My Agenda' link we show a link back to the course
+// in the breadcrumbs
+if (!empty ($_GET['coursePath']))
+{
+	$interbreadcrumb[] = array ('url' => api_get_path(WEB_COURSE_PATH).$_GET['coursePath'].'/index.php', 'name' => $_GET['courseCode']);
+}
+// this loads the javascript that is needed for the date popup selection
+$htmlHeadXtra[] = "<script src=\"tbl_change.js\" type=\"text/javascript\" language=\"javascript\"></script>";
+// showing the header
+Display::display_header(get_lang('MyAgenda'));
+/* ==============================================================================
+  						SETTING SOME VARIABLES
+============================================================================== */
+// setting the database variables
+$TABLECOURS = Database :: get_main_table(MAIN_COURSE_TABLE);
+$TABLECOURSUSER = Database :: get_main_table(MAIN_COURSE_USER_TABLE);
+$TABLEAGENDA = Database :: get_course_table(AGENDA_TABLE);
+$TABLE_ITEMPROPERTY = Database :: get_course_table(LAST_TOOL_EDIT_TABLE);
+$TABLE_PERSONAL_AGENDA = Database :: get_user_personal_table(PERSONAL_AGENDA);
+
+// the variables for the days and the months
+// Defining the shorts for the days
+$DaysShort = array (get_lang("SundayShort"), get_lang("MondayShort"), get_lang("TuesdayShort"), get_lang("WednesdayShort"), get_lang("ThursdayShort"), get_lang("FridayShort"), get_lang("SaturdayShort"));
+// Defining the days of the week to allow translation of the days
+$DaysLong = array (get_lang("SundayLong"), get_lang("MondayLong"), get_lang("TuesdayLong"), get_lang("WednesdayLong"), get_lang("ThursdayLong"), get_lang("FridayLong"), get_lang("SaturdayLong"));
+// Defining the months of the year to allow translation of the months
+$MonthsLong = array (get_lang("JanuaryLong"), get_lang("FebruaryLong"), get_lang("MarchLong"), get_lang("AprilLong"), get_lang("MayLong"), get_lang("JuneLong"), get_lang("JulyLong"), get_lang("AugustLong"), get_lang("SeptemberLong"), get_lang("OctoberLong"), get_lang("NovemberLong"), get_lang("DecemberLong"));
+
+/* ==============================================================================
+  						SANITY CHECK
+============================================================================== */
+// You can delete this if you have manually added the new database and tables
+// this piece of code was added to avoid having to explain to non sys-admin
+// what has to be done in order to get this tool working
+if (get_setting("allow_personal_agenda") == "true")
+{
+	// I use a separate database for storing all the information of user driven tools
+	// as the Personal Agenda tool has the potential to create a large database.
+	// If you do not want a separate database for the personal agenda tool you can add the table to
+	// the main dokeos database by changing $DATABASE_USER_TOOLS above to $mainDbName
+	$sql_create_database = "CREATE DATABASE IF NOT EXISTS `$DATABASE_USER_TOOLS`";
+	$result = api_sql_query($sql_create_database);
+	$sql_create_table = "CREATE TABLE IF NOT EXISTS $TABLE_PERSONAL_AGENDA (
+					`id` int(11) NOT NULL auto_increment,
+					`user` int(11),
+					`title` text,
+					`text` text,
+					`date` datetime default NULL,
+					`course` varchar(255),
+					UNIQUE KEY `id` (`id`))
+					TYPE=MyISAM AUTO_INCREMENT=1";
+	$result = api_sql_query($sql_create_table);
+}
+/*==============================================================================
+  			TREATING THE URL PARAMETERS
+			1. The default values
+			2. storing it in the session
+			3. possible view
+				3.a Month view
+				3.b Week view
+				3.c day view
+				3.d personal view (only the personal agenda items)
+			4. add personal agenda
+			5. edit personal agenda
+			6. delete personal agenda
+  ============================================================================== */
+// 1. The default values. if there is no session yet, we have by default the month view
+if (!$_SESSION['view'])
+{
+	$_SESSION['view'] = "month";
+}
+// 2. Storing it in the session. If we change the view by clicking on the links left, we change the session
+if ($_GET['view'])
+{
+	$_SESSION['view'] = $_GET['view'];
+}
+// 3. The views: (month, week, day, personal)
+if ($_SESSION['view'])
+{
+	switch ($_SESSION['view'])
+	{
+		// 3.a Month view
+		case "month" :
+			$proces = "month_view";
+			break;
+			// 3.a Week view
+		case "week" :
+			$proces = "week_view";
+			break;
+			// 3.a Day view
+		case "day" :
+			$proces = "day_view";
+			break;
+			// 3.a Personal view
+		case "personal" :
+			$proces = "personal_view";
+			break;
+	}
+}
+// 4. add personal agenda
+if ($_GET['action'] == "add_personal_agenda_item" and !$_POST['Submit'])
+{
+	$proces = "add_personal_agenda_item";
+}
+if ($_GET['action'] == "add_personal_agenda_item" and $_POST['Submit'])
+{
+	$proces = "store_personal_agenda_item";
+}
+// 5. edit personal agenda
+if ($_GET['action'] == "edit_personal_agenda_item" and !$_POST['Submit'])
+{
+	$proces = "edit_personal_agenda_item";
+}
+if ($_GET['action'] == "edit_personal_agenda_item" and $_POST['Submit'])
+{
+	$proces = "store_personal_agenda_item";
+}
+// 6. delete personal agenda
+if ($_GET['action'] == "delete" AND $_GET['id'])
+{
+	$proces = "delete_personal_agenda_item";
+}
+/* ==============================================================================
+  						OUTPUT
+============================================================================== */
+if (isset ($_uid))
+{
+	// getting all the courses that this user is subscribed to
+	$courses_dbs = get_courses_of_user();
+	if (!is_array($courses_dbs)) // this is for the special case if the user has no courses (otherwise you get an error)
+	{
+		$courses_dbs = array ();
+	}
+	// setting and/or getting the year, month, day, week
+	$today = getdate();
+	$year = $_GET['year'];
+	if ($year == NULL)
+	{
+		$year = $today['year'];
+	}
+	$month = $_GET['month'];
+	if ($month == NULL)
+	{
+		$month = $today['mon'];
+	}
+	$day = $_GET['day'];
+	if ($day == NULL)
+	{
+		$day = $today['mday'];
+	}
+	$week = $_GET['week'];
+	if ($week == NULL)
+	{
+		$week = date("W");
+	}
+	// The name of the current Month
+	$monthName = $MonthsLong[$month -1];
+	// Starting the output
+	echo "<table width=\"100%\" border=\"0\" cellspacing=\"0\" cellpadding=\"0\">";
+	echo "<tr>";
+	// output: the small calendar item on the left and the view / add links
+	echo "<td width=\"220\" valign=\"top\">";
+	$agendaitems = get_agendaitems($rootWeb, $courses_dbs, $month, $year);
+	if (get_setting('allow_personal_agenda') == 'true')
+	{
+		$agendaitems = get_personal_agendaitems($rootWeb, $agendaitems, $day, $month, $year, $week, "month_view");
+	}
+	display_minimonthcalendar($agendaitems, $month, $year, $monthName);
+	echo "\n<ul id=\"agenda_select\">\n";
+	echo "\t<li><a href=\"".$_SERVER['PHP_SELF']."?action=view&amp;view=month\"><img src=\"../img/calendar_month.gif\" border=\"0\" alt=\"".get_lang('MonthView')."\" /> ".get_lang('MonthView')."</a></li>\n";
+	echo "\t<li><a href=\"".$_SERVER['PHP_SELF']."?action=view&amp;view=week\"><img src=\"../img/calendar_week.gif\" border=\"0\" alt=\"".get_lang('WeekView')."\" /> ".get_lang('WeekView')."</a></li>\n";
+	echo "\t<li><a href=\"".$_SERVER['PHP_SELF']."?action=view&amp;view=day\"><img src=\"../img/calendar_day.gif\" border=\"0\" alt=\"".get_lang('DayView')."\" /> ".get_lang('DayView')."</a></li>\n";
+	if (get_setting('allow_personal_agenda') == 'true')
+	{
+		echo "\t<li><a href=\"".$_SERVER['PHP_SELF']."?action=add_personal_agenda_item\"><img src=\"../img/calendar_personal_add.gif\" border=\"0\" /> ".get_lang("AddPersonalItem")."</a></li>\n";
+		echo "\t<li><a href=\"".$_SERVER['PHP_SELF']."?action=view&amp;view=personal\"><img src=\"../img/calendar_personal.gif\" border=\"0\" />  ".get_lang("ViewPersonalItem")."</a></li>\n";
+	}
+	echo "</ul>\n\n";
+	echo "</td>";
+	// the divider
+	// OlivierB : the image has a white background, which causes trouble if the portal has another background color. Image should be transparent. ----> echo "<td width=\"20\" background=\"../img/verticalruler.gif\">&nbsp;</td>";
+	echo "<td width=\"20\">&nbsp;</td>";
+	// the main area: day, week, month view
+	echo "<td valign=\"top\">";
+	switch ($proces)
+	{
+		case "month_view" :
+			$agendaitems = get_agendaitems($rootWeb, $courses_dbs, $month, $year);
+			if (get_setting("allow_personal_agenda") == "true")
+			{
+				$agendaitems = get_personal_agendaitems($rootWeb, $agendaitems, $day, $month, $year, $week, "month_view");
+			}
+			display_monthcalendar($agendaitems, $month, $year, $langDay_of_weekNames['long'], $monthName);
+			break;
+		case "week_view" :
+			$agendaitems = get_week_agendaitems($rootWeb, $courses_dbs, $month, $year, $week);
+			if (get_setting("allow_personal_agenda") == "true")
+			{
+				$agendaitems = get_personal_agendaitems($rootWeb, $agendaitems, $day, $month, $year, $week, "week_view");
+			}
+			display_weekcalendar($agendaitems, $month, $year, $langDay_of_weekNames['long'], $monthName);
+			break;
+		case "day_view" :
+			$agendaitems = get_day_agendaitems($rootWeb, $courses_dbs, $month, $year, $day);
+			if (get_setting("allow_personal_agenda") == "true")
+			{
+				$agendaitems = get_personal_agendaitems($rootWeb, $agendaitems, $day, $month, $year, $week, "day_view");
+			}
+			display_daycalendar($agendaitems, $day, $month, $year, $langDay_of_weekNames['long'], $monthName);
+			break;
+		case "personal_view" :
+			show_personal_agenda();
+			break;
+		case "add_personal_agenda_item" :
+			show_new_item_form();
+			break;
+		case "store_personal_agenda_item" :
+			store_personal_item($_POST['frm_day'], $_POST['frm_month'], $_POST['frm_year'], $_POST['frm_hour'], $_POST['frm_minute'], $_POST['frm_title'], $_POST['frm_content'], $_GET['id']);
+			if ($_GET['id'])
+			{
+				Display :: display_normal_message(get_lang("PeronalAgendaItemEdited"));
+			}
+			else
+			{
+				Display :: display_normal_message(get_lang("PeronalAgendaItemAdded"));
+			}
+			show_personal_agenda();
+			break;
+		case "edit_personal_agenda_item" :
+			show_new_item_form($_GET['id']);
+			break;
+		case "delete_personal_agenda_item" :
+			delete_personal_agenda($_GET['id']);
+			Display :: display_normal_message(get_lang('PeronalAgendaItemDeleted'));
+			show_personal_agenda();
+			break;
+	}
+}
+echo "</td></tr></table>";
+Display :: display_footer();
+
+/*============================================================================
+	 get_agendaitems($rootWeb, $courses_db, $month, $year)
+  ============================================================================*/
+// This function retrieves all the agenda items of all the course of the user
+function get_agendaitems($rootWeb, $courses_dbs, $month, $year)
+{
+	global $courseTablePrefix, $dbGlu;
+	global $_uid;
+	$items = array ();
+	// get agenda-items for every course
+	foreach ($courses_dbs as $key => $array_course_info)
+	{
+		//databases of the courses
+		$TABLEAGENDA = Database :: get_course_table(AGENDA_TABLE, $array_course_info["db"]);
+		$TABLE_ITEMPROPERTY = Database :: get_course_table(LAST_TOOL_EDIT_TABLE, $array_course_info["db"]);
+
+		$group_memberships = GroupManager :: get_group_ids($array_course_info["db"], $_uid);
+		// if the user is administrator of that course we show all the agenda items
+		if ($array_course_info['status'] == '1')
+		{
+			//echo "course admin";
+			$sqlquery = "SELECT
+										DISTINCT agenda.*, item_property.*
+										FROM ".$TABLEAGENDA." agenda,
+											 ".$TABLE_ITEMPROPERTY." item_property
+										WHERE `agenda`.`id` = `item_property`.`ref`   ".$show_all_current."
+										AND MONTH(`agenda`.`start_date`)='".$month."'
+										AND YEAR(`agenda`.`start_date`)='".$year."'
+										AND `item_property`.`tool`='".TOOL_CALENDAR_EVENT."'
+										AND `item_property`.`visibility`='1'
+										ORDER BY start_date ".$sort;
+		}
+		// if the user is not an administrator of that course
+		else
+		{
+			//echo "GEEN course admin";
+			if (is_array($group_memberships))
+			{
+				$sqlquery = "SELECT
+													agenda.*, item_property.*
+													FROM ".$TABLEAGENDA." agenda,
+														".$TABLE_ITEMPROPERTY." item_property
+													WHERE `agenda`.`id` = `item_property`.`ref`   ".$show_all_current."
+													AND MONTH(`agenda`.`start_date`)='".$month."'
+													AND YEAR(`agenda`.`start_date`)='".$year."'
+													AND `item_property`.`tool`='".TOOL_CALENDAR_EVENT."'
+													AND	( `item_property`.`to_user_id`='".$_uid."' OR `item_property`.`to_group_id` IN (0, ".implode(", ", $group_memberships).") )
+													AND `item_property`.`visibility`='1'
+													ORDER BY start_date ".$sort;
+			}
+			else
+			{
+				$sqlquery = "SELECT
+													agenda.*, item_property.*
+													FROM ".$TABLEAGENDA." agenda,
+														".$TABLE_ITEMPROPERTY." item_property
+													WHERE `agenda`.`id` = `item_property`.`ref`   ".$show_all_current."
+													AND MONTH(`agenda`.`start_date`)='".$month."'
+													AND YEAR(`agenda`.`start_date`)='".$year."'
+													AND `item_property`.`tool`='".TOOL_CALENDAR_EVENT."'
+													AND ( `item_property`.`to_user_id`='".$_uid."' OR `item_property`.`to_group_id`='0')
+													AND `item_property`.`visibility`='1'
+													ORDER BY start_date ".$sort;
+			}
+		}
+
+		$result = api_sql_query($sqlquery, __FILE__, __LINE__);
+		while ($item = mysql_fetch_array($result))
+		{
+			$agendaday = date("j",strtotime($item['start_date']));
+			$time= date("H:i",strtotime($item['start_date']));
+			$URL = $rootWeb."main/calendar/agenda.php?cidReq=".urlencode($array_course_info["code"])."&amp;day=$agendaday&amp;month=$month&amp;year=$year#$agendaday"; // RH  //Patrick Cool: to highlight the relevant agenda item
+			$items[$agendaday][$item['start_time']] .= "<i>".$time."</i> <a href=\"$URL\" title=\"".$array_course_info["name"]."\">".$array_course_info["visual_code"]."</a>  ".$item['title']."<br />";
+		}
+	}
+	// sorting by hour for every day
+	$agendaitems = array ();
+	while (list ($agendaday, $tmpitems) = each($items))
+	{
+		sort($tmpitems);
+		while (list ($key, $val) = each($tmpitems))
+		{
+			$agendaitems[$agendaday] .= $val;
+		}
+	}
+	//print_r($agendaitems);
+	return $agendaitems;
+}
+/*============================================================================
+	 display_monthcalendar($agendaitems, $month, $year, $weekdaynames, $monthName)
+  ============================================================================*/
+// show the monthcalender of the given month
+function display_monthcalendar($agendaitems, $month, $year, $weekdaynames, $monthName)
+{
+	global $DaysShort;
+	//Handle leap year
+	$numberofdays = array (0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31);
+	if (($year % 400 == 0) or ($year % 4 == 0 and $year % 100 <> 0))
+		$numberofdays[2] = 29;
+	//Get the first day of the month
+	$dayone = getdate(mktime(0, 0, 0, $month, 1, $year));
+	//Start the week on monday
+	$startdayofweek = $dayone['wday'] <> 0 ? ($dayone['wday'] - 1) : 6;
+	$backwardsURL = $_SERVER['PHP_SELF']."?coursePath=".htmlentities($_GET['coursePath'])."&amp;courseCode=".htmlentities($_GET['courseCode'])."&amp;action=view&amp;view=month&amp;month=". ($month == 1 ? 12 : $month -1)."&amp;year=". ($month == 1 ? $year -1 : $year);
+	$forewardsURL = $_SERVER['PHP_SELF']."?coursePath=".htmlentities($_GET['coursePath'])."&amp;courseCode=".htmlentities($_GET['courseCode'])."&amp;action=view&amp;view=month&amp;month=". ($month == 12 ? 1 : $month +1)."&amp;year=". ($month == 12 ? $year +1 : $year);
+
+	echo "<table id=\"agenda_list\">\n", "<tr class=\"title\">\n", "<td width=\"10%\"><a href=\"", $backwardsURL, "\">«</a></td>\n", "<td width=\"80%\" colspan=\"5\">", $monthName, " ", $year, "</td>\n", "<td width=\"10%\"><a href=\"", $forewardsURL, "\">»</a></td>\n", "</tr>\n";
+
+	echo "<tr>\n";
+	for ($ii = 1; $ii < 8; $ii ++)
+	{
+		echo "<td class=\"weekdays\">", $DaysShort[$ii % 7], "</td>\n";
+	}
+	echo "</tr>\n";
+	$curday = -1;
+	$today = getdate();
+	while ($curday <= $numberofdays[$month])
+	{
+		echo "<tr>\n";
+		for ($ii = 0; $ii < 7; $ii ++)
+		{
+			if (($curday == -1) && ($ii == $startdayofweek))
+			{
+				$curday = 1;
+			}
+			if (($curday > 0) && ($curday <= $numberofdays[$month]))
+			{
+				$bgcolor = $ii < 5 ? $class = "class=\"days_week\"" : $class = "class=\"days_weekend\"";
+				$dayheader = "<b>$curday</b>";
+				if (($curday == $today[mday]) && ($year == $today[year]) && ($month == $today[mon]))
+				{
+					$dayheader = "$curday - ".get_lang("Today")."<br />";
+					$class = "class=\"days_today\"";
+				}
+				echo "<td ".$class.">", "".$dayheader;
+				if (!empty($agendaitems[$curday]))
+				{
+					echo "<span class=\"agendaitem\">".$agendaitems[$curday]."</span>";
+				}
+				echo "</td>\n";
+				$curday ++;
+			}
+			else
+			{
+				echo "<td>&nbsp;</td>\n";
+			}
+		}
+		echo "</tr>\n";
+	}
+	echo "</table>\n";
+}
+/*============================================================================
+	 display_minimonthcalendar($agendaitems, $month, $year, $monthName)
+  ============================================================================*/
+// show the mini calender of the given month
+function display_minimonthcalendar($agendaitems, $month, $year, $monthName)
+{
+	global $DaysShort;
+	//Handle leap year
+	$numberofdays = array (0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31);
+	if (($year % 400 == 0) or ($year % 4 == 0 and $year % 100 <> 0))
+		$numberofdays[2] = 29;
+	//Get the first day of the month
+	$dayone = getdate(mktime(0, 0, 0, $month, 1, $year));
+	//Start the week on monday
+	$startdayofweek = $dayone['wday'] <> 0 ? ($dayone['wday'] - 1) : 6;
+	$backwardsURL = $_SERVER['PHP_SELF']."?coursePath=".$_GET['coursePath']."&amp;courseCode=".$_GET['courseCode']."&amp;month=". ($month == 1 ? 12 : $month -1)."&amp;year=". ($month == 1 ? $year -1 : $year);
+	$forewardsURL = $_SERVER['PHP_SELF']."?coursePath=".$_GET['coursePath']."&amp;courseCode=".$_GET['courseCode']."&amp;month=". ($month == 12 ? 1 : $month +1)."&amp;year=". ($month == 12 ? $year +1 : $year);
+
+	echo "<table id=\"smallcalendar\">\n", "<tr class=\"title\">\n", "<td width=\"10%\"><a href=\"", $backwardsURL, "\">«</a></td>\n", "<td width=\"80%\" colspan=\"5\">", $monthName, " ", $year, "</td>\n", "<td width=\"10%\"><a href=\"", $forewardsURL, "\">»</a></td>\n", "</tr>\n";
+
+	echo "<tr>\n";
+	for ($ii = 1; $ii < 8; $ii ++)
+	{
+		echo "<td class=\"weekdays\">", $DaysShort[$ii % 7], "</td>\n";
+	}
+	echo "</tr>\n";
+	$curday = -1;
+	$today = getdate();
+	while ($curday <= $numberofdays[$month])
+	{
+		echo "<tr>\n";
+		for ($ii = 0; $ii < 7; $ii ++)
+		{
+			if (($curday == -1) && ($ii == $startdayofweek))
+			{
+				$curday = 1;
+			}
+			if (($curday > 0) && ($curday <= $numberofdays[$month]))
+			{
+				$bgcolor = $ii < 5 ? $class = "class=\"days_week\"" : $class = "class=\"days_weekend\"";
+				$dayheader = "$curday";
+				if (($curday == $today[mday]) && ($year == $today[year]) && ($month == $today[mon]))
+				{
+					$dayheader = "$curday";
+					$class = "class=\"days_today\"";
+				}
+				echo "\t<td ".$class.">";
+				if ($agendaitems[$curday] <> "")
+				{
+					echo "<a href=\"".$_SERVER['PHP_SELF']."?action=view&amp;view=day&amp;day=".$curday."&amp;month=".$month."&amp;year=".$year."\">".$dayheader."</a>";
+				}
+				else
+				{
+					echo $dayheader;
+				}
+				// "a".$dayheader." <span class=\"agendaitem\">".$agendaitems[$curday]."</span>\n";
+				echo "</td>\n";
+				$curday ++;
+			}
+			else
+			{
+				echo "<td>&nbsp;</td>\n";
+			}
+		}
+		echo "</tr>\n";
+	}
+	echo "</table>\n";
+}
+/*============================================================================
+	 display_weekcalendar($agendaitems, $month, $year, $weekdaynames, $monthName)
+  ============================================================================*/
+function display_weekcalendar($agendaitems, $month, $year, $weekdaynames, $monthName)
+{
+	global $DaysShort;
+	global $MonthsLong;
+	// timestamp of today
+	$today = mktime();
+	$day_of_the_week = date("w", $today);
+	$thisday_of_the_week = date("w", $today);
+	// the week number of the year
+	$week_number = date("W", $today);
+	$thisweek_number = date("W", $today);
+	// if we moved to the next / previous week we have to recalculate the $today variable
+	if ($_GET['week'])
+	{
+		$today = mktime(0, 0, 0, 1, 1, $year);
+		$today = $today + (($_GET['week']) * (7 * 24 * 60 * 60));
+		$week_number = date("W", $today);
+	}
+	// calculating the start date of the week
+	// the date of the monday of this week is the timestamp of today minus
+	// number of days that have already passed this week * 24 hours * 60 minutes * 60 seconds
+	$current_day = date("j", $today); // Day of the month without leading zeros (1 to 31) of today
+	$day_of_the_week = date("w", $today); // Numeric representation of the day of the week	0 (for Sunday) through 6 (for Saturday) of today
+	$timestamp_first_date_of_week = $today - (($day_of_the_week -1) * 24 * 60 * 60); // timestamp of the monday of this week
+	$timestamp_last_date_of_week = $today + ((7 - $day_of_the_week) * 24 * 60 * 60); // timestamp of the sunday of this week
+	$backwardsURL = $_SERVER['PHP_SELF']."?coursePath=".$_GET['coursePath']."&amp;courseCode=".$_GET['courseCode']."&amp;action=view&amp;view=week&amp;week=". ($week_number -1);
+	$forewardsURL = $_SERVER['PHP_SELF']."?coursePath=".$_GET['coursePath']."&amp;courseCode=".$_GET['courseCode']."&amp;action=view&amp;view=week&amp;week=". ($week_number +1);
+	echo "<table id=\"agenda_list\">\n";
+	// The title row containing the the week information (week of the year (startdate of week - enddate of week)
+	echo "<tr class=\"title\">\n";
+	echo "<td width=\"10%\"><a href=\"", $backwardsURL, "\">«</a></td>\n";
+	echo "<td colspan=\"5\">".get_lang("Week")." ".$week_number;
+	echo " (".$DaysShort['1']." ".date("j", $timestamp_first_date_of_week)." ".$MonthsLong[date("n", $timestamp_first_date_of_week) - 1]." ".date("Y", $timestamp_first_date_of_week)." - ".$DaysShort['0']." ".date("j", $timestamp_last_date_of_week)." ".$MonthsLong[date("n", $timestamp_last_date_of_week) - 1]." ".date("Y", $timestamp_last_date_of_week).')';
+	echo "</td>";
+	echo "<td width=\"10%\"><a href=\"", $forewardsURL, "\">»</a></td>\n", "</tr>\n";
+	// The second row containing the short names of the days of the week
+	echo "<tr>\n";
+	// this is the Day of the month without leading zeros (1 to 31) of the monday of this week
+	$tmp_timestamp = $timestamp_first_date_of_week;
+	for ($ii = 1; $ii < 8; $ii ++)
+	{
+		echo "\t<td class=\"weekdays\">";
+		if ($ii == $thisday_of_the_week AND (!isset($_GET['week']) OR $_GET['week']==$thisweek_number))
+		{
+			echo "<font color=#CC3300>";
+		}
+		echo $DaysShort[$ii % 7]." ".date("j", $tmp_timestamp)." ".$MonthsLong[date("n", $tmp_timestamp) - 1];
+		if ($ii == $thisday_of_the_week AND (!isset($_GET['week']) OR $_GET['week']==$thisweek_number))
+		{
+			echo "</font>";
+		}
+		echo "</td>\n";
+		// we 24 hours * 60 minutes * 60 seconds to the $tmp_timestamp
+		$array_tmp_timestamp[] = $tmp_timestamp;
+		$tmp_timestamp = $tmp_timestamp + (24 * 60 * 60);
+	}
+	echo "</tr>\n";
+	// the table cells containing all the entries for that day
+	echo "<tr>\n";
+	$counter = 0;
+	foreach ($array_tmp_timestamp as $key => $value)
+	{
+		if ($counter < 5)
+		{
+			$class = "class=\"days_week\"";
+		}
+		else
+		{
+			$class = "class=\"days_weekend\"";
+		}
+		if ($counter == $thisday_of_the_week -1 AND (!isset($_GET['week']) OR $_GET['week']==$thisweek_number))
+		{
+			$class = "class=\"days_today\"";
+		}
+
+		echo "\t<td ".$class.">";
+		echo "<span class=\"agendaitem\">".$agendaitems[date("j", $value)]."&nbsp;</span> ";
+		echo "</td>\n";
+		$counter ++;
+	}
+	echo "</tr>\n";
+	echo "</table>\n";
+}
+/*============================================================================
+	 display_daycalendar($agendaitems, $month, $year, $weekdaynames, $monthName)
+  ============================================================================*/
+// show the mini calender of the given month
+function display_daycalendar($agendaitems, $day, $month, $year, $weekdaynames, $monthName)
+{
+	global $DaysShort, $DaysLong;
+	global $MonthsLong;
+	global $query;
+	global $courseTablePrefix, $dbGlu;
+	// some debug information
+	// echo "dag: ".$day;
+	// echo "maand: ".$month;
+	// echo "jaar: ".$year;
+	// timestamp of today
+	$today = mktime();
+	$nextday = $today + (24 * 60 * 60);
+	$previousday = $today - (24 * 60 * 60);
+	// the week number of the year
+	$week_number = date("W", $today);
+	// if we moved to the next / previous day we have to recalculate the $today variable
+	if ($_GET['day'])
+	{
+		$today = mktime(0, 0, 0, $month, $day, $year);
+		$nextday = $today + (24 * 60 * 60);
+		$previousday = $today - (24 * 60 * 60);
+		$week_number = date("W", $today);
+	}
+	// calculating the start date of the week
+	// the date of the monday of this week is the timestamp of today minus
+	// number of days that have already passed this week * 24 hours * 60 minutes * 60 seconds
+	$current_day = date("j", $today); // Day of the month without leading zeros (1 to 31) of today
+	$day_of_the_week = date("w", $today); // Numeric representation of the day of the week	0 (for Sunday) through 6 (for Saturday) of today
+	//$timestamp_first_date_of_week=$today-(($day_of_the_week-1)*24*60*60); // timestamp of the monday of this week
+	//$timestamp_last_date_of_week=$today+((7-$day_of_the_week)*24*60*60); // timestamp of the sunday of this week
+	// we are loading all the calendar items of all the courses for today
+	echo "<table id=\"agenda_list\">\n";
+	// the forward and backwards url
+	$backwardsURL = $_SERVER['PHP_SELF']."?coursePath=".$_GET['coursePath']."&amp;courseCode=".$_GET['courseCode']."&amp;action=view&amp;view=day&amp;day=".date("j", $previousday)."&amp;month=".date("n", $previousday)."&amp;year=".date("Y", $previousday);
+	$forewardsURL = $_SERVER['PHP_SELF']."?coursePath=".$_GET['coursePath']."&amp;courseCode=".$_GET['courseCode']."&amp;action=view&amp;view=day&amp;day=".date("j", $nextday)."&amp;month=".date("n", $nextday)."&amp;year=".date("Y", $nextday);
+	// The title row containing the day
+	echo "<tr class=\"title\">\n", "<td width=\"10%\"><a href=\"", $backwardsURL, "\">«</a></td>\n", "<td>";
+	echo $DaysLong[$day_of_the_week]." ".date("j", $today)." ".$MonthsLong[date("n", $today) - 1]." ".date("Y", $today);
+	echo "</td>";
+	echo "<td width=\"10%\"><a href=\"", $forewardsURL, "\">»</a></td>\n";
+	echo "</tr>\n";
+	// the rows for each half an hour
+	for ($i = 10; $i < 48; $i ++)
+	{
+		echo "<tr>\n";
+		echo "\t";
+		if ($i % 2 == 0)
+		{
+			$class = "class=\"alternativeBgLight\"";
+			echo ("<td $class valign=\"top\" width=\"75\">". (($i) / 2)." ".get_lang("HourShort")." 00</td>\n");
+		}
+		else
+		{
+			$class = "";
+			echo ("<td valign=\"top\" width=\"75\">". ((($i) / 2) - (1 / 2))." ".get_lang("HourShort")." 30</td>\n");
+		}
+		echo "\t<td $class valign=\"top\" colspan=\"2\">\n";
+		if (is_array($agendaitems[$i]))
+		{
+			foreach ($agendaitems[$i] as $key => $value)
+			{
+				echo $value;
+			}
+		}
+		else
+		{
+			echo $agendaitems[$i];
+		}
+		echo "\t</td>\n";
+		echo "</tr>\n";
+	}
+	echo "</table>\n";
+}
+/*============================================================================
+	 get_day_agendaitems($rootWeb, $query, $month, $year)
+  ============================================================================*/
+// show the monthcalender of the given month
+function get_day_agendaitems($rootWeb, $courses_dbs, $month, $year, $day)
+{
+	global $courseTablePrefix, $dbGlu;
+	global $_uid;
+	$items = array ();
+
+	// get agenda-items for every course
+	//$query=api_sql_query($sql_select_courses);
+	foreach ($courses_dbs as $key => $array_course_info)
+	{
+		//databases of the courses
+		$TABLEAGENDA = Database :: get_course_table(AGENDA_TABLE, $array_course_info["db"]);
+		$TABLE_ITEMPROPERTY = Database :: get_course_table(LAST_TOOL_EDIT_TABLE, $array_course_info["db"]);
+
+		// getting all the groups of the user for the current course
+		$group_memberships = GroupManager :: get_group_ids($array_course_info["db"], $_uid);
+		// if the user is administrator of that course we show all the agenda items
+		if ($array_course_info['status'] == '1')
+		{
+			//echo "course admin";
+			$sqlquery = "SELECT
+										DISTINCT agenda.*, item_property.*
+										FROM ".$TABLEAGENDA." agenda,
+											".$TABLE_ITEMPROPERTY." item_property
+										WHERE `agenda`.`id` = `item_property`.`ref`   ".$show_all_current."
+										AND DAYOFMONTH(start_date)='".$day."' AND MONTH(start_date)='".$month."' AND YEAR(start_date)='".$year."'
+										AND `item_property`.`tool`='".TOOL_CALENDAR_EVENT."'
+										AND `item_property`.`visibility`='1'
+										ORDER BY start_date ".$sort;
+		}
+		// if the user is not an administrator of that course
+		else
+		{
+			//echo "GEEN course admin";
+			if (is_array($group_memberships))
+			{
+				$sqlquery = "SELECT
+													agenda.*, item_property.*
+													FROM ".$TABLEAGENDA." agenda,
+														".$TABLE_ITEMPROPERTY." item_property
+													WHERE `agenda`.`id` = `item_property`.`ref`   ".$show_all_current."
+													AND DAYOFMONTH(start_date)='".$day."' AND MONTH(start_date)='".$month."' AND YEAR(start_date)='".$year."'
+													AND `item_property`.`tool`='".TOOL_CALENDAR_EVENT."'
+													AND	( `item_property`.`to_user_id`='".$_uid."' OR `item_property`.`to_group_id` IN (0, ".implode(", ", $group_memberships).") )
+													AND `item_property`.`visibility`='1'
+													ORDER BY start_date ".$sort;
+			}
+			else
+			{
+				$sqlquery = "SELECT
+													agenda.*, item_property.*
+													FROM ".$TABLEAGENDA." agenda,
+														".$TABLE_ITEMPROPERTY." item_property
+													WHERE `agenda`.`id` = `item_property`.`ref`   ".$show_all_current."
+													AND DAYOFMONTH(start_date)='".$day."' AND MONTH(start_date)='".$month."' AND YEAR(start_date)='".$year."'
+													AND `item_property`.`tool`='".TOOL_CALENDAR_EVENT."'
+													AND ( `item_property`.`to_user_id`='".$_uid."' OR `item_property`.`to_group_id`='0')
+													AND `item_property`.`visibility`='1'
+													ORDER BY start_date ".$sort;
+			}
+		}
+		//$sqlquery = "SELECT * FROM $agendadb WHERE DAYOFMONTH(day)='$day' AND month(day)='$month' AND year(day)='$year'";
+		//echo "abc";
+		//echo $sqlquery;
+		$result = api_sql_query($sqlquery, __FILE__, __LINE__);
+		//echo mysql_num_rows($result);
+		while ($item = mysql_fetch_array($result))
+		{
+			// in the display_daycalendar function we use $i (ranging from 0 to 47) for each halfhour
+			// we want to know for each agenda item for this day to wich halfhour it must be assigned
+			list ($datepart, $timepart) = split(" ", $item['start_date']);
+			list ($year, $month, $day) = explode("-", $datepart);
+			list ($hours, $minutes, $seconds) = explode(":", $timepart);
+
+			$halfhour = 2 * $hours;
+			if ($minutes >= '30')
+			{
+				$halfhour = $halfhour +1;
+			}
+			//$URL = $rootWeb.$mycours["dir"]."/";
+			$URL = $rootWeb."main/calendar/agenda.php?cidReq=".urlencode($array_course_info["code"])."&amp;day=$day&amp;month=$month&amp;year=$year#$day"; // RH  //Patrick Cool: to highlight the relevant agenda item
+			$items[$halfhour][] .= "<i>".$hours.":".$minutes."</i> <a href=\"$URL\" title=\"".$array_course_info['name']."\">".$array_course_info['visual_code']."</a>  ".$item['title']."<br />";
+		}
+	}
+	// sorting by hour for every day
+	/*$agendaitems = array();
+	while (list($agendaday, $tmpitems) = each($items))
+	{
+		sort($tmpitems);
+		while (list($key,$val) = each($tmpitems))
+		{
+			$agendaitems[$agendaday].=$val;
+		}
+	}*/
+	$agendaitems = $items;
+	//print_r($agendaitems);
+	return $agendaitems;
+}
+/*============================================================================
+	 function get_week_agendaitems($rootWeb, $courses_dbs, $month, $year,$day)
+  ============================================================================*/
+function get_week_agendaitems($rootWeb, $courses_dbs, $month, $year, $week = '')
+{
+	global $courseTablePrefix, $dbGlu;
+	global $TABLEAGENDA, $TABLE_ITEMPROPERTY;
+	global $_uid;
+	$items = array ();
+	// The default value of the week
+	if ($week == '')
+	{
+		$week_number = date("W", mktime());
+	}
+	else
+	{
+		$week_number = $week;
+	}
+	$start_end = calculate_start_end_of_week($week_number, $year);
+	$start_filter = $start_end['start']['year']."-".$start_end['start']['month']."-".$start_end['start']['day'];
+	$end_filter = $start_end['end']['year']."-".$start_end['end']['month']."-".$start_end['end']['day'];
+	/*
+	// determine the start and end date
+	// step 1: we calculate a timestamp for a day in this week
+	$random_day_in_week=mktime(0,0,0,1,1,$year)+($week_number)*(7*24*60*60); // we calculate a random day in this week
+	// step 2: we which day this is (0=sunday, 1=monday, ...)
+	$number_day_in_week=date("w",$random_day_in_week);
+	// step 3: we calculate the timestamp of the monday of the week we are in
+	$start_timestamp=$random_day_in_week-(($number_day_in_week-1)*24*60*60);
+	// step 4: we calculate the timestamp of the sunday of the week we are in
+	$end_timestamp=$random_day_in_week+((7-$number_day_in_week+1)*24*60*60)-3600;
+	// step 5: calculating the start_day, end_day, start_month, end_month, start_year, end_year
+	$start_day=date("j",$start_timestamp);
+	$start_month=date("n",$start_timestamp);
+	$start_year=date("Y",$start_timestamp);
+	$end_day=date("j",$end_timestamp);
+	$end_month=date("n",$end_timestamp);
+	$end_year=date("Y",$end_timestamp);
+
+	// in sql statements you have to use year-month-day for date calculations
+	$start_filter=$start_year."-".$start_month."-".$start_day;
+	$end_filter=$end_year."-".$end_month."-".$end_day;
+
+	*/
+	//$start_end_week=calculate_start_end_of_week($week_number, $year);
+	// a little bit of debug information
+	//echo "START: ".date("l dS of F Y H:i:s A",$start_timestamp)."<br />";
+	//echo "END: ".date("l dS of F Y H:i:s A",$end_timestamp)."<br />";
+	// this date is the xth day in the week
+	// if we moved to the next / previous week we have to recalculate the $today variable
+	/*if ($_GET['week'])
+		{
+		$today=mktime(0,0,0,1,1,$year);
+		$today=$today+(($_GET['week']-1)*(7*24*60*60));
+		$week_number=date("W",$today);
+		}*/
+	// get agenda-items for every course
+	foreach ($courses_dbs as $key => $array_course_info)
+	{
+		//databases of the courses
+		$TABLEAGENDA = Database :: get_course_table(AGENDA_TABLE, $array_course_info["db"]);
+		$TABLE_ITEMPROPERTY = Database :: get_course_table(LAST_TOOL_EDIT_TABLE, $array_course_info["db"]);
+
+		// getting all the groups of the user for the current course
+		$group_memberships = GroupManager :: get_group_ids($array_course_info["db"], $_uid);
+
+		// if the user is administrator of that course we show all the agenda items
+		if ($array_course_info['status'] == '1')
+		{
+			//echo "course admin";
+			$sqlquery = "SELECT
+										DISTINCT agenda.*, item_property.*
+										FROM ".$TABLEAGENDA." agenda,
+											".$TABLE_ITEMPROPERTY." item_property
+										WHERE `agenda`.`id` = `item_property`.`ref`   ".$show_all_current."
+										AND start_date>='".$start_filter."' AND start_date<='".$end_filter."'
+										AND `item_property`.`tool`='".TOOL_CALENDAR_EVENT."'
+										AND `item_property`.`visibility`='1'
+										ORDER BY start_date ".$sort;
+		}
+		// if the user is not an administrator of that course
+		else
+		{
+			//echo "GEEN course admin";
+			if (is_array($group_memberships))
+			{
+				$sqlquery = "SELECT
+													agenda.*, item_property.*
+													FROM ".$TABLEAGENDA." agenda,
+														 ".$TABLE_ITEMPROPERTY." item_property
+													WHERE `agenda`.`id` = `item_property`.`ref`   ".$show_all_current."
+													AND start_date>='".$start_filter."' AND start_date<='".$end_filter."'
+													AND `item_property`.`tool`='".TOOL_CALENDAR_EVENT."'
+													AND	( `item_property`.`to_user_id`='".$_uid."' OR `item_property`.`to_group_id` IN (0, ".implode(", ", $group_memberships).") )
+													AND `item_property`.`visibility`='1'
+													ORDER BY start_date ".$sort;
+			}
+			else
+			{
+				$sqlquery = "SELECT
+													agenda.*, item_property.*
+													FROM ".$TABLEAGENDA." agenda,
+														 ".$TABLE_ITEMPROPERTY." item_property
+													WHERE `agenda`.`id` = `item_property`.`ref`   ".$show_all_current."
+													AND start_date>='".$start_filter."' AND start_date<='".$end_filter."'
+													AND `item_property`.`tool`='".TOOL_CALENDAR_EVENT."'
+													AND ( `item_property`.`to_user_id`='".$_uid."' OR `item_property`.`to_group_id`='0')
+													AND `item_property`.`visibility`='1'
+													ORDER BY start_date ".$sort;
+			}
+		}
+		//echo "<pre>".$sqlquery."</pre>";
+		// $sqlquery = "SELECT * FROM $agendadb WHERE (DAYOFMONTH(day)>='$start_day' AND DAYOFMONTH(day)<='$end_day')
+		//				AND (MONTH(day)>='$start_month' AND MONTH(day)<='$end_month')
+		//				AND (YEAR(day)>='$start_year' AND YEAR(day)<='$end_year')";
+		$result = api_sql_query($sqlquery, __FILE__, __LINE__);
+		while ($item = mysql_fetch_array($result))
+		{
+			$agendaday = date("j",strtotime($item['start_date']));
+			$time= date("H:i",strtotime($item['start_date']));
+			$URL = $rootWeb."main/calendar/agenda.php?cidReq=".urlencode($array_course_info["code"])."&amp;day=$agendaday&amp;month=$month&amp;year=$year#$agendaday"; // RH  //Patrick Cool: to highlight the relevant agenda item
+			$items[$agendaday][$item['start_time']] .= "<i>$time</i> <a href=\"$URL\" title=\"".$array_course_info["name"]."\">".$array_course_info["visual_code"]."</a>  ".$item['title']."<br />";
+		}
+	}
+	// sorting by hour for every day
+	$agendaitems = array ();
+	while (list ($agendaday, $tmpitems) = each($items))
+	{
+		sort($tmpitems);
+		while (list ($key, $val) = each($tmpitems))
+		{
+			$agendaitems[$agendaday] .= $val;
+		}
+	}
+	//print_r($agendaitems);
+	return $agendaitems;
+}
+/*============================================================================
+	 show_new_item_form()
+  ============================================================================*/
+// This function shows all the forms that are needed form adding /editing a new personal agenda item
+// when there is no $id passed in the function we are adding a new agenda item, if there is a $id
+// we are editing
+// attention: we have to check that the student is editing an item that belongs to him/her
+function show_new_item_form($id = "")
+{
+	global $year, $MonthsLong;
+	global $TABLE_PERSONAL_AGENDA;
+	global $_uid;
+	// we construct the default time and date data (used if we are not editing a personal agenda item)
+	$today = getdate();
+	$day = $today['mday'];
+	$month = $today['mon'];
+	$year = $today['year'];
+	$hours = $today['hours'];
+	$minutes = $today['minutes'];
+	// if an $id is passed to this function this means we are editing an item
+	// we are loading the information here (we do this after everything else
+	// to overwrite the default information)
+	if ($id <> "")
+	{
+		$sql = "SELECT * FROM ".$TABLE_PERSONAL_AGENDA." WHERE user='".$_uid."' AND id='".$id."'";
+		$result = api_sql_query($sql, __FILE__, __LINE__);
+		$aantal = mysql_num_rows($result);
+		if ($aantal <> 0)
+		{
+			$row = mysql_fetch_array($result);
+			$year = substr($row['date'], 0, 4);
+			$month = substr($row['date'], 5, 2);
+			$day = substr($row['date'], 8, 2);
+			$hours = substr($row['date'], 11, 2);
+			$minutes = substr($row['date'], 14, 2);
+			$title = $row['title'];
+			$text = $row['text'];
+		}
+		else
+		{
+			return false;
+		}
+	}
+	echo "<form method=\"post\" action=\"myagenda.php?action=add_personal_agenda_item&amp;id=$id\" name=\"newedit_form\">\n";
+	echo "<table width=\"100%\" id=\"newedit_form\">\n";
+	echo "\t<tr class=\"title\">\n\t\t<td colspan=\"3\"><h4>";
+	echo ($_GET['action'] == 'edit_personal_agenda_item') ? get_lang("ModifyPersonalCalendarItem") : get_lang("AddPersonalCalendarItem");
+	echo "</h4></td>\n\t</tr>\n";
+	echo "\t<tr class=\"subtitle\">\n\t\t<td>\n";
+	echo "<!-- date: 1 -> 31 -->\n";
+	echo "\t\t".get_lang("Date").": \n";
+	// ********** The form containing the days (0->31) ********** \\
+	echo "<select name=\"frm_day\">\n";
+	// small loop for filling all the dates
+	// 2do: the available dates should be those of the selected month => february is from 1 to 28 (or 29) and not to 31
+	for ($i = 1; $i <= 31; $i ++)
+	{
+		// values have to have double digits
+		if ($i <= 9)
+		{
+			$value = "0".$i;
+		}
+		else
+		{
+			$value = $i;
+		}
+		// the current day is indicated with [] around the date
+		if ($value == $day)
+		{
+			echo "\t\t\t\t <option value=\"".$value."\" selected>".$i."</option>\n";
+		}
+		else
+		{
+			echo "\t\t\t\t <option value=\"".$value."\">".$i."</option>\n";
+		}
+	}
+	echo "</select>\n\n";
+	// ********** The form containing the months (jan->dec) ********** \\
+	echo "<!-- month: january -> december -->\n";
+	echo "<select name=\"frm_month\">\n";
+	for ($i = 1; $i <= 12; $i ++)
+	{
+		// values have to have double digits
+		if ($i <= 9)
+		{
+			$value = "0".$i;
+		}
+		else
+		{
+			$value = $i;
+		}
+		// the current month is indicated with [] around the month name
+		if ($value == $month)
+		{
+			echo "\t<option value=\"".$value."\" selected>".$MonthsLong[$i -1]."</option>\n";
+		}
+		else
+		{
+			echo "\t<option value=\"".$value."\">".$MonthsLong[$i -1]."</option>\n";
+		}
+	}
+	echo "</select>\n\n";
+	// ********** The form containing the years ********** \\
+	echo "<!-- year -->\n";
+	echo "<select name=\"frm_year\">";
+	echo "<option value=\"". ($year -1)."\">". ($year -1)."</option>\n";
+	echo "<option value=\"".$year."\" selected>".$year."</option>\n";
+	for ($i = 1; $i <= 5; $i ++)
+	{
+		$value = $year + $i;
+		echo "\t<option value=\"".$value."\">".$value."</option>\n";
+	}
+	echo "</select>";
+	echo "<a title=\"Kalender\" href=\"javascript:openCalendar('newedit_form', 'frm_')\"><img src=\"../img/calendar_select.gif\" border=\"0\" valign=\"absmiddle\"/></a>";
+	echo "</td><td width=\"50%\">";
+	// ********** The form containing the hours  (00->23) ********** \\
+	echo "<!-- time: hour -->\n";
+	echo get_lang("Time").": \n";
+	echo "<select name=\"frm_hour\">\n";
+	for ($i = 1; $i <= 24; $i ++)
+	{
+		// values have to have double digits
+		if ($i <= 9)
+		{
+			$value = "0".$i;
+		}
+		else
+		{
+			$value = $i;
+		}
+		// the current hour is indicated with [] around the hour
+		if ($hours == $value)
+		{
+			echo "\t\t\t\t<option value=\"".$value."\" selected> ".$value." </option>\n";
+		}
+		else
+		{
+			echo "\t\t\t\t<option value=\"".$value."\"> ".$value." </option>\n";
+		}
+	}
+	echo "</select>";
+	// ********** The form containing the minutes ********** \\
+	echo "<select name=\"frm_minute\">";
+	echo "<option value=\"".$minutes."\">".$minutes."</option>";
+	echo "<option value=\"00\">00</option>";
+	echo "<option value=\"05\">05</option>";
+	echo "<option value=\"10\">10</option>";
+	echo "<option value=\"15\">15</option>";
+	echo "<option value=\"20\">20</option>";
+	echo "<option value=\"25\">25</option>";
+	echo "<option value=\"30\">30</option>";
+	echo "<option value=\"35\">35</option>";
+	echo "<option value=\"40\">40</option>";
+	echo "<option value=\"45\">45</option>";
+	echo "<option value=\"50\">50</option>";
+	echo "<option value=\"55\">55</option>";
+	echo "</select>";
+	echo "</td></tr>";
+	// ********** The title field ********** \\
+	echo "<tr class=\"subtitle\"><td colspan=\"2\">";
+	echo get_lang('Title').': <input type="text" name="frm_title" size="50" value="'.$title.'" />';
+	echo "</td></tr>";
+	// ********** The text field ********** \\
+	echo "<tr><td colspan=\"2\">";
+	api_disp_html_area('frm_content', $text, '300px');
+	echo "</td></tr>";
+	// ********** The Submit button********** \\
+	echo "<tr><td colspan=\"2\">";
+	echo '<input type="submit" name="Submit" value="'.get_lang('Ok').'" />';
+	echo "</td></tr>";
+	echo "</table>\n</form>\n";
+}
+/*============================================================================
+	 store_personal_item($day, $month, $year, $hour, $minute, $course, $title, $content, $id="")
+  ============================================================================*/
+// This function shows all the forms that are needed form adding a new personal agenda item
+function store_personal_item($day, $month, $year, $hour, $minute, $title, $content, $id = "")
+{
+	global $TABLE_PERSONAL_AGENDA;
+	global $_uid;
+	//constructing the date
+	$date = $year."-".$month."-".$day." ".$hour.":".$minute.":00";
+	if ($id <> "")
+	{ // we are updating
+		$sql = "UPDATE ".$TABLE_PERSONAL_AGENDA." SET user='".$_uid."', title='".$title."', text='".$content."', date='".$date."' WHERE id='".$id."'";
+	}
+	else
+	{ // we are adding a new item
+		$sql = "INSERT INTO $TABLE_PERSONAL_AGENDA (user, title, text, date) VALUES ('$_uid','$title', '$content', '$date')";
+	}
+	$result = api_sql_query($sql, __FILE__, __LINE__);
+}
+/*============================================================================
+	 get_courses_of_user()
+  ============================================================================*/
+// This function finds all the courses of the user and returns an array containing the
+// database name of the courses.
+function get_courses_of_user()
+{
+	global $TABLECOURS;
+	global $TABLECOURSUSER;
+	global $_uid;
+	$sql_select_courses = "SELECT course.code k, course.visual_code  vc,
+									course.title i, course.tutor_name t, course.db_name db, course.directory dir, course_rel_user.status status
+			                        FROM    $TABLECOURS       course,
+											$TABLECOURSUSER   course_rel_user
+			                        WHERE course.code = course_rel_user.course_code
+			                        AND   course_rel_user.user_id = '$_uid'";
+	$result = api_sql_query($sql_select_courses);
+	while ($row = mysql_fetch_array($result))
+	{
+		// we only need the database name of the course
+		$courses[] = array ("db" => $row['db'], "code" => $row['k'], "visual_code" => $row['vc'], "title" => $row['i'], "directory" => $row['dir'], "status" => $row['status']);
+	}
+	return $courses;
+}
+/*============================================================================
+	 get_personal_agendaitems($rootWeb, $agendaitems, $month, $year, $day, $week, $type);
+  ============================================================================*/
+// This function retrieves all the personal agenda items and add them to the agenda items found by the other functions.
+function get_personal_agendaitems($rootWeb, $agendaitems, $day = "", $month = "", $year = "", $week = "", $type)
+{
+	global $TABLE_PERSONAL_AGENDA;
+	global $_uid;
+	// 1. creating the SQL statement for getting the personal agenda items in MONTH view
+	if ($type == "month_view" or $type == "") // we are in month view
+	{
+		$sql = "SELECT * FROM ".$TABLE_PERSONAL_AGENDA." WHERE user='".$_uid."' and MONTH(date)='".$month."' AND YEAR(date) = '".$year."'  ORDER BY date ASC";
+	}
+	// 2. creating the SQL statement for getting the personal agenda items in WEEK view
+	if ($type == "week_view") // we are in week view
+	{
+		$start_end_day_of_week = calculate_start_end_of_week($week, $year);
+		$start_day = $start_end_day_of_week['start']['day'];
+		$start_month = $start_end_day_of_week['start']['month'];
+		$start_year = $start_end_day_of_week['start']['year'];
+		$end_day = $start_end_day_of_week['end']['day'];
+		$end_month = $start_end_day_of_week['end']['month'];
+		$end_year = $start_end_day_of_week['end']['year'];
+		// in sql statements you have to use year-month-day for date calculations
+		$start_filter = $start_year."-".$start_month."-".$start_day;
+		$end_filter = $end_year."-".$end_month."-".$end_day;
+		$sql = " SELECT * FROM ".$TABLE_PERSONAL_AGENDA." WHERE user='".$_uid."'
+								AND date>='".$start_filter."' AND date<='".$end_filter."'";
+	}
+	// 3. creating the SQL statement for getting the personal agenda items in DAY view
+	if ($type == "day_view") // we are in day view
+	{
+		// we could use mysql date() function but this is only available from 4.1 and higher
+		$start_filter = $year."-".$month."-".$day." 00:00:01";
+		$end_filter = $year."-".$month."-".$day." 23:59:59";
+		$sql = " SELECT * FROM ".$TABLE_PERSONAL_AGENDA." WHERE user='".$_uid."' AND date>='".$start_filter."' AND date<='".$end_filter."'";
+	}
+	//echo "day:".$day."/";
+	//echo "month:".$month."/";
+	//echo "year:".$year."/";
+	//echo "week:".$week."/";
+	//echo $type."<p>";
+	//echo "<pre>".$sql."</pre>";
+	$result = api_sql_query($sql, __FILE__, __LINE__);
+	while ($item = mysql_fetch_array($result))
+	{
+		// we break the date field in the database into a date and a time part
+		$agenda_db_date = explode(" ", $item[date]);
+		$date = $agenda_db_date[0];
+		$time = $agenda_db_date[1];
+		// we divide the date part into a day, a month and a year
+		$agendadate = explode("-", $date);
+		$year = intval($agendadate[0]);
+		$month = intval($agendadate[1]);
+		$day = intval($agendadate[2]);
+		// we divide the time part into hour, minutes, seconds
+		$agendatime = explode(":", $time);
+		$hour = $agendatime[0];
+		$minute = $agendatime[1];
+		$second = $agendatime[2];
+		// if the student has specified a course we a add a link to that course
+		if ($item['course'] <> "")
+		{
+			$url = $rootWeb."main/calendar/agenda.php?cidReq=".urlencode($item['course'])."&amp;day=$day&amp;month=$month&amp;year=$year#$day"; // RH  //Patrick Cool: to highlight the relevant agenda item
+			$course_link = "<a href=\"$url\" title=\"".$item['course']."\">".$item['course']."</a>";
+		}
+		else
+		{
+			$course_link = "";
+		}
+		// Creating the array that will be returned. If we have week or month view we have an array with the date as the key
+		// if we have a day_view we use a half hour as index => key 33 = 16h30
+		if ($type !== "day_view") // This is the array construction for the WEEK or MONTH view
+		{
+			$agendaitems[$day] .= "<div><i>$hour:$minute</i> $course_link  <a href=\"myagenda.php?action=view&amp;view=personal&amp;day=$day&amp;month=$month&amp;year=$year&amp;id=".$item['id']."#".$item['id']."\" class=\"personal_agenda\">".$item['title']."</a></div>";
+		}
+		else // this is the array construction for the DAY view
+			{
+			$halfhour = 2 * $agendatime['0'];
+			if ($agendatime['1'] >= '30')
+			{
+				$halfhour = $halfhour +1;
+			}
+			$agendaitems[$halfhour] .= "<div><i>$hour:$minute</i> $course_link  <a href=\"myagenda.php?action=view&amp;view=personal&amp;day=$day&amp;month=$month&amp;year=$year&amp;id=".$item['id']."#".$item['id']."\" class=\"personal_agenda\">".$item['title']."</a></div>";
+		}
+	}
+	//print_r($agendaitems);
+	return $agendaitems;
+}
+/*============================================================================
+	 show_personal_agenda()
+  ============================================================================*/
+// This function retrieves all the personal agenda items of the user and shows
+// these items in one list (ordered by date and grouped by month (the month_bar)
+function show_personal_agenda()
+{
+	global $TABLE_PERSONAL_AGENDA;
+	global $MonthsLong;
+	global $_uid;
+	// The SQL statement that retrieves all the personal agenda items of this user
+	$sql = "SELECT * FROM ".$TABLE_PERSONAL_AGENDA." WHERE user='".$_uid."' ORDER BY date DESC";
+	$result = api_sql_query($sql, __FILE__, __LINE__);
+	// variable initialisation
+	$month_bar = "";
+	// starting the table output
+	echo "<table id=\"agenda_list\">\n";
+	// setting the default day, month and year
+	if (!$_GET['day'] AND !$_GET['month'] AND !$_GET['year'])
+	{
+		$today = getdate();
+		$year = $today['year'];
+		$month = $today['mon'];
+		$day = $today['mday'];
+	}
+	if (mysql_num_rows($result) > 0)
+	{
+		while ($myrow = mysql_fetch_array($result))
+		{
+			/*--------------------------------------------------
+					display: the month bar
+			  --------------------------------------------------*/
+			if ($month_bar != date("m", strtotime($myrow["date"])).date("Y", strtotime($myrow["date"])))
+			{
+				$month_bar = date("m", strtotime($myrow["date"])).date("Y", strtotime($myrow["date"]));
+				echo "<tr><td class=\"title\" colspan=\"2\" class=\"month\" valign=\"top\">".$MonthsLong[date("n", strtotime($myrow["date"])) - 1]." ".date("Y", strtotime($myrow["date"]))."</td></tr>\n";
+			}
+			// highlight: if a date in the small calendar is clicked we highlight the relevant items
+			$db_date = (int) date("d", strtotime($myrow["date"])).date("n", strtotime($myrow["date"])).date("Y", strtotime($myrow["date"]));
+			if ($_GET["day"].$_GET["month"].$_GET["year"] <> $db_date)
+			{
+				$style = "data";
+				$text_style = "text";
+			}
+			else
+			{
+				$style = "datanow";
+				$text_style = "text";
+			}
+			/*--------------------------------------------------
+			 			display: date and time
+			  --------------------------------------------------*/
+			echo "\t<tr>\n\t\t";
+			echo "<td class=\"".$style."\">";
+			// adding an internal anchor
+			echo "<a name=\"".$myrow["id"]."\"></a>";
+			echo date("d", strtotime($myrow["date"]))." ".$MonthsLong[date("n", strtotime($myrow["date"])) - 1]." ".date("Y", strtotime($myrow["date"]))."&nbsp;";
+			echo ucfirst(strftime(get_lang("timeNoSecFormat"), strtotime($myrow["date"])));
+			echo "</td></tr>";
+			/*--------------------------------------------------
+			 			display: the title
+			  --------------------------------------------------*/
+			echo "<tr>";
+			echo "<td class=\"".$style."\" colspan='2'>";
+			echo $myrow['title'];
+			echo "\n\t\t</td colspan='2'>\n\t</tr>\n";
+			/*--------------------------------------------------
+			 			display: the content
+			  --------------------------------------------------*/
+			$content = $myrow['text'];
+			$content = make_clickable($content);
+			$content = text_filter($content);
+			echo "\t<tr>\n\t\t<td class=\"".$text_style."\" colspan='2'>";
+			echo $content;
+			echo "</td></tr>";
+			/*--------------------------------------------------
+			 			display: the edit / delete icons
+			  --------------------------------------------------*/
+			echo "\t<tr>\n\t\t<td class=\"".$text_style."\" colspan='2'>";
+			echo "<a href=\"myagenda.php?action=edit_personal_agenda_item&amp;id=".$myrow['id']."\"><img src=\"../img/edit.gif\" border=\"0\" alt=\"".get_lang('Edit')."\" /></a>";
+			echo "<a href=\"".$_SERVER['PHP_SELF']."?action=delete&amp;id=".$myrow['id']."\" onclick=\"javascript:if(!confirm('".addslashes(htmlentities(get_lang('ConfirmYourChoice')))."')) return false;\"><img src=\"../img/delete.gif\" border=\"0\" alt=\"".get_lang('Delete')."\" /></a>";
+			echo "</td></tr>";
+		}
+	}
+	else
+	{
+		echo '<tr><td colspan="2">'.get_lang('NoAgendaItems').'</td></tr>';
+	}
+	echo "</table>\n";
+}
+/*============================================================================
+	 delete_personal_agenda($id)
+  ============================================================================*/
+// This function deletes a personal agenda item
+// There is an additional check to make sure that one cannot delete an item that
+// does not belong to him/her
+function delete_personal_agenda($id)
+{
+	global $TABLE_PERSONAL_AGENDA;
+	global $_uid;
+	if ($id <> '')
+	{
+		$sql = "SELECT * FROM ".$TABLE_PERSONAL_AGENDA." WHERE user='".$_uid."' AND id='".$id."'";
+		$result = api_sql_query($sql, __FILE__, __LINE__);
+		$aantal = mysql_num_rows($result);
+		if ($aantal <> 0)
+		{
+			$sql = "DELETE FROM ".$TABLE_PERSONAL_AGENDA." WHERE user='".$_uid."' AND id='".$id."'";
+			$result = api_sql_query($sql, __FILE__, __LINE__);
+		}
+	}
+}
+/*============================================================================
+	 calculate_start_end_of_week($week_number, $year)
+  ============================================================================*/
+// This function calculates the startdate of the week (monday)
+// and the enddate of the week (sunday)
+// and returns it as an array
+function calculate_start_end_of_week($week_number, $year)
+{
+	// determine the start and end date
+	// step 1: we calculate a timestamp for a day in this week
+	$random_day_in_week = mktime(0, 0, 0, 1, 1, $year) + ($week_number) * (7 * 24 * 60 * 60); // we calculate a random day in this week
+	// step 2: we which day this is (0=sunday, 1=monday, ...)
+	$number_day_in_week = date('w', $random_day_in_week);
+	// step 3: we calculate the timestamp of the monday of the week we are in
+	$start_timestamp = $random_day_in_week - (($number_day_in_week -1) * 24 * 60 * 60);
+	// step 4: we calculate the timestamp of the sunday of the week we are in
+	$end_timestamp = $random_day_in_week + ((7 - $number_day_in_week +1) * 24 * 60 * 60) - 3600;
+	// step 5: calculating the start_day, end_day, start_month, end_month, start_year, end_year
+	$start_day = date('j', $start_timestamp);
+	$start_month = date('n', $start_timestamp);
+	$start_year = date('Y', $start_timestamp);
+	$end_day = date('j', $end_timestamp);
+	$end_month = date('n', $end_timestamp);
+	$end_year = date('Y', $end_timestamp);
+	$start_end_array['start']['day'] = $start_day;
+	$start_end_array['start']['month'] = $start_month;
+	$start_end_array['start']['year'] = $start_year;
+	$start_end_array['end']['day'] = $end_day;
+	$start_end_array['end']['month'] = $end_month;
+	$start_end_array['end']['year'] = $end_year;
+	return $start_end_array;
+}
+?>

+ 82 - 0
main/calendar/print.php

@@ -0,0 +1,82 @@
+<?php
+// setting the language file
+$langFile = "agenda";
+
+$id=$_GET['id'];
+
+if(strstr($id,','))
+{
+	$id=explode(',',$id);
+	$id=array_map('intval',$id);
+	$id=implode(',',$id);
+}
+else
+{
+	$id=intval($id);
+}
+
+// setting the global file that gets the general configuration, the databases, the languages, ...
+include('../inc/global.inc.php');
+
+
+
+$TABLEAGENDA 		= Database::get_course_table(AGENDA_TABLE);
+
+$sql 			= "SELECT * FROM $TABLEAGENDA WHERE id IN($id) ORDER BY start_date DESC";
+$result			= api_sql_query($sql,__FILE__,__LINE__);
+?>
+
+<html>
+<head>
+<title><?php echo get_lang('Print'); ?></title>
+<style type="text/css" media="screen, projection">
+/*<![CDATA[*/
+@import "../css/default.css";
+/*]]>*/
+</style>
+</head>
+<body style="margin: 15px; padding: 0px;">
+
+<center>
+<input type="button" value="<?php echo htmlentities(get_lang('Print')); ?>" onclick="javascript:window.print();" />
+</center>
+<br /><br />
+
+<?php
+while($row=mysql_fetch_array($result))
+{
+	$row['content'] = $row['content'];
+	$row['content'] = make_clickable($row['content']);
+	$row['content'] = text_filter($row['content']);
+	$row['content'] = str_replace('<a ','<a target="_blank" ',$row['content']);
+
+	if(!empty($row['title']))
+	{
+		echo '<b>'.$row['title'].'</b><br /><br />';
+	}
+
+	echo get_lang('StartTime').' : ';
+
+	echo ucfirst(format_locale_date($dateFormatLong,strtotime($row["start_date"])))."&nbsp;&nbsp;&nbsp;";
+	echo ucfirst(strftime($timeNoSecFormat,strtotime($row["start_date"])))."";
+
+	echo '<br />';
+
+	echo get_lang('EndTime').' : ';
+
+	echo ucfirst(format_locale_date($dateFormatLong,strtotime($row["end_date"])))."&nbsp;&nbsp;&nbsp;";
+	echo ucfirst(strftime($timeNoSecFormat,strtotime($row["end_date"])))."";
+
+	echo '<br /><br />';
+
+	echo $row['content'].'<hr size="1" noshade="noshade" />';
+}
+?>
+
+<br /><br />
+<center>
+<input type="button" value="<?php echo htmlentities(get_lang('Print')); ?>" onclick="javascript:window.print();" />
+</center>
+
+</body>
+</html>

+ 159 - 0
main/calendar/tbl_change.js

@@ -0,0 +1,159 @@
+var day;
+var month;
+var year;
+var hour;
+var minute;
+var second;
+var clock_set = 0;
+
+/**
+ * Opens calendar window.
+ *
+ * @param   string      form name
+ * @param   string      field name
+ */
+function openCalendar(form, field) {
+    window.open("./calendar.php", "calendar", "width=220,height=200,status=no");
+	day = eval("document." + form + "." + field + "day.options["+ "document." + form + "." + field + "day.selectedIndex].value");
+    month = eval("document." + form + "." + field + "month.options["+ "document." + form + "." + field + "month.selectedIndex].value");
+   	month = month-1;
+    year = eval("document." + form + "." + field + "year.options["+ "document." + form + "." + field + "year.selectedIndex].value");
+	formName = form;
+	fieldName =field;
+}
+
+/**
+ * Formats number to two digits.
+ *
+ * @param   int number to format.
+ */
+function formatNum2(i, valtype) {
+    f = (i < 10 ? '0' : '') + i;
+    if (valtype && valtype != '') {
+        switch(valtype) {
+            case 'month':
+                f = (f > 12 ? 12 : f);
+                break;
+
+            case 'day':
+                f = (f > 31 ? 31 : f);
+                break;
+        }
+    }
+
+    return f;
+}
+
+/**
+ * Formats number to four digits.
+ *
+ * @param   int number to format.
+ */
+function formatNum4(i) {
+    return (i < 1000 ? i < 100 ? i < 10 ? '000' : '00' : '0' : '') + i;
+}
+
+/**
+ * Initializes calendar window.
+ */
+function initCalendar() {
+    if (!year && !month && !day) {
+		day = window.opener.day;
+		month = window.opener.month;
+		year  = window.opener.year;   
+        if (isNaN(year) || isNaN(month) || isNaN(day) || day == 0) {
+            dt      = new Date();
+            year    = dt.getFullYear();
+            month   = dt.getMonth();
+            day     = dt.getDate();
+        }
+    } else {
+        /* Moving in calendar */
+        if (month > 11) {
+            month = 0;
+            year++;
+        }
+        if (month < 0) {
+            month = 11;
+            year--;
+        }
+    }
+
+    if (document.getElementById) {
+        cnt = document.getElementById("calendar_data");
+    } else if (document.all) {
+        cnt = document.all["calendar_data"];
+    }
+
+    cnt.innerHTML = "";
+
+    str = ""
+
+    //heading table
+    str += '<table class="calendar"><tr><th class="monthyear" width="50%">';
+    str += '<a href="javascript:month--; initCalendar();">&laquo;</a> ';
+    str += month_names[month];
+    str += ' <a href="javascript:month++; initCalendar();">&raquo;</a>';
+    str += '</th><th class="monthyear" width="50%">';
+    str += '<a href="javascript:year--; initCalendar();">&laquo;</a> ';
+    str += year;
+    str += ' <a href="javascript:year++; initCalendar();">&raquo;</a>';
+    str += '</th></tr></table>';
+
+    str += '<table class="calendar"><tr>';
+    for (i = 0; i < 7; i++) {
+        str += "<th  class='daynames'>" + day_names[i] + "</th>";
+    }
+    str += "</tr>";
+
+    var firstDay = new Date(year, month, 1).getDay();
+    var lastDay = new Date(year, month + 1, 0).getDate();
+
+    str += "<tr>";
+
+    dayInWeek = 0;
+    for (i = 0; i < firstDay; i++) {
+        str += "<td>&nbsp;</td>";
+        dayInWeek++;
+    }
+    for (i = 1; i <= lastDay; i++) {
+        if (dayInWeek == 7) {
+            str += "</tr><tr>";
+            dayInWeek = 0;
+        }
+
+        dispmonth = 1 + month;
+        actVal = formatNum4(year) + "-" + formatNum2(dispmonth, 'month') + "-" + formatNum2(i, 'day');
+        if (i == day) {
+            style = ' class="selected"';
+        } else {
+            style = '';
+        }
+        str += "<td" + style + "><a href=\"javascript:returnDate(" + i +","+month+","+year + ");\">" + i + "</a></td>"
+        dayInWeek++;
+    }
+    for (i = dayInWeek; i < 7; i++) {
+        str += "<td>&nbsp;</td>";
+    }
+
+    str += "</tr></table>";
+
+    cnt.innerHTML = str;
+}
+
+/**
+ * Returns date from calendar.
+ *
+ * @param   string     date text
+ */
+function returnDate(d,m,y) {
+	cmd = "window.opener.document."+window.opener.formName+"."+window.opener.fieldName+"day.selectedIndex = "+(d-1);
+	eval(cmd);
+	cmd = "window.opener.document."+window.opener.formName+"."+window.opener.fieldName+"month.selectedIndex = "+m;
+	eval(cmd);
+	date = new Date();
+	year = date.getFullYear()-1;
+	cmd = "window.opener.document."+window.opener.formName+"."+window.opener.fieldName+"year.selectedIndex = "+(y-year);
+	eval(cmd);
+    window.close();
+}

+ 102 - 0
main/chat/chat.php

@@ -0,0 +1,102 @@
+<?php // $Id: chat.php 9832 2006-10-26 12:56:25Z gmludo $
+/*
+==============================================================================
+	Dokeos - elearning and course management software
+
+	Copyright (c) 2004 Dokeos S.A.
+	Copyright (c) 2003 Ghent University (UGent)
+	Copyright (c) 2001 Universite catholique de Louvain (UCL)
+	Copyright (c) Olivier Brouckaert
+
+	For a full list of contributors, see "credits.txt".
+	The full license can be read in "license.txt".
+
+	This program is free software; you can redistribute it and/or
+	modify it under the terms of the GNU General Public License
+	as published by the Free Software Foundation; either version 2
+	of the License, or (at your option) any later version.
+
+	See the GNU General Public License for more details.
+
+	Contact: Dokeos, 181 rue Royale, B-1000 Brussels, Belgium, info@dokeos.com
+==============================================================================
+*/
+/**
+==============================================================================
+*	Frameset of the Chat tool
+*
+*	@author Ludovic Gasc
+*	@package dokeos.chat
+*	@todo improve multi-language support
+*	@todo stock each chat text file into each course
+*	@todo remove duplicate libs (XAJAX, PEAR...)
+==============================================================================
+*/
+/*
+-----------------------------------------------------------
+	Init section
+-----------------------------------------------------------
+*/ 
+$langFile='chat';
+include('../inc/global.inc.php');
+
+$this_section=SECTION_COURSES;
+
+$nameTools=get_lang('Chat');
+if ($_GET["origin"] != 'whoisonline')
+{
+	api_protect_course_script();
+}
+else
+{
+	$origin = $_SESSION['origin'];
+	$target = $_SESSION['target'];
+	$_SESSION['origin']=$_GET["origin"];
+	$_SESSION['target']=$_GET["target"];
+}
+
+/*
+-----------------------------------------------------------
+	Tracking
+-----------------------------------------------------------
+*/ 
+include('../inc/lib/events.lib.inc.php');
+event_access_tool(TOOL_CHAT);
+
+/*
+-----------------------------------------------------------
+	Main section
+-----------------------------------------------------------
+*/
+
+require_once './phpfreechat/src/phpfreechat.class.php';
+
+
+// initialisation of phpfreechat
+$courseinfo = api_get_course_info();
+//print_r($courseinfo);
+$params['serverid'] = (string) $courseinfo['id']; // used to identify the chat
+$params['nick'] = $_SESSION['_user']['firstName'].' '.$_SESSION['_user']['lastName'];
+$params['title'] = $courseinfo['name'];
+//$params['channel'] = $courseinfo['name'];
+$params['frozen_nick'] = true;
+$params['max_nick_len'] = 100;
+$params['height'] = "300px";
+//$params['xajaxpath'] = $rootSys.'main/inc/lib/xajax/';
+// $params['debug'] = true;
+// $params['debugxajax'] = true;
+
+$params['language'] = Database::get_language_isocode($courseinfo['language']).'_'.strtoupper(Database::get_language_isocode($courseinfo['language']));
+// In phpfreechat, some translations depends of the country
+
+$chat = new phpFreeChat($params);
+
+$htmlHeadXtra[] = $chat->printJavascript();
+$htmlHeadXtra[] = $chat->printStyle();
+
+	Display::display_header($nameTools,"Chat");
+
+	$chat->printChat();
+
+	Display::display_footer();
+?>

+ 7 - 0
main/chat/index.html

@@ -0,0 +1,7 @@
+<html>
+<head>
+<meta http-equiv="refresh" content="0; url=chat.php">
+</head>
+<body>
+</body>
+</html>

+ 1 - 0
main/chat/phpfreechat/AUTHORS

@@ -0,0 +1 @@
+Stephane Gully <stephane.gully@gmail.com>

+ 17 - 0
main/chat/phpfreechat/COPYING

@@ -0,0 +1,17 @@
+phpFreeChat a simple, fast, and customizable chat server.
+Copyright © 2006 Stephane Gully <stephane.gully@gmail.com>
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+This library is distributed in the hope that it will be useful, 
+but WITHOUT ANY WARRANTY; without even the implied warranty of 
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details. 
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the
+Free Software Foundation, 51 Franklin St, Fifth Floor,
+Boston, MA  02110-1301  USA

+ 14 - 0
main/chat/phpfreechat/admin/configuration.php

@@ -0,0 +1,14 @@
+<?php
+// TOP //
+include("index_html_top.php");
+?>
+
+<div class="content">
+  <h2>Configuration</h2>
+
+</div>
+
+<?php
+// BOTTOM
+include("index_html_bottom.php");
+?>

+ 556 - 0
main/chat/phpfreechat/admin/htaccess.class.php

@@ -0,0 +1,556 @@
+<?php
+
+/**
+* Class to manage .htaccess file of Apache
+* @author Fred Delaunay <fred@nemako.net>
+*/
+
+class htaccess{
+    var $authType; // authentification type
+    var $authName; // authentification name
+    
+    var $admin_files; // array of files limited to the administrators
+    var $modo_files; // array of files limited to the moderators
+    
+    var $file_Htpasswd;   // .htpasswd file (AuthUserFile)
+    var $file_Htgroup; // .htgroup file (AuthGroupFile)
+    var $file_Htaccess; // .htaccess file
+
+
+    
+    function htaccess(){
+       $this->authType = "Basic";
+       $this->authName = "PhpFreeChat Admin Zone";
+       
+       $this->admin_files = array("admin.php", "admin2.php");
+       $this->modo_files = array("mod.php", "mod2.php");
+              
+
+       $this->file_Htpasswd = dirname(__FILE__)."/.htpasswd";
+	   if(!file_exists($this->file_Htpasswd))
+		  touch($this->file_Htpasswd);
+       $this->file_Htgroup = dirname(__FILE__)."/.htgroup";
+	   if(!file_exists($this->file_Htgroup)) {
+		  touch($this->file_Htgroup);
+		  $this->addGroup("admin");
+		  $this->addGroup("modo");
+	   }
+       $this->file_Htaccess = dirname(__FILE__)."/.htaccess";
+       
+    }
+
+    /***************************************/
+    /*            SET AND GET              */
+    /***************************************/
+
+    /**
+    * Set the AuthType
+    * @param string $authtype - AuthType is Basic or Digest (crypted)
+    */
+    function setAuthType($authtype){
+        $this->authType=$authtype;
+    }
+    /**
+    * Get the AuthType
+    * @return string $authtype - AuthType is Basic or Digest (crypted)
+    */
+    function getAuthType(){
+        return $this->authType;
+    }
+    
+    /**
+    * Set the AuthName message
+    * @param string $authname - AuthName message is the text display in the dialog box
+  	*/
+    function setAuthName($authname){
+        $this->authName=$authname;
+    }
+    /**
+    * Get the AuthName message
+    * @return string $authname - AuthName message is the text display in the dialog box
+  	*/
+    function getAuthName(){
+        return $this->authName;
+    }
+    
+    /**
+    * Set the .htaccess file
+    * @param string $filename - absolute file-path
+    */
+    function set_file_Htaccess($filename){
+        $this->file_Htaccess=$filename;
+    }
+    /**
+    * Get the .htaccess file
+    * @return string $filename - absolute file-path
+    */
+    function get_file_Htaccess(){
+        return $this->file_Htaccess;
+    }
+    
+    /**
+    * Set the .htpasswd file (AuthUserFile)
+    * @param string $filename - absolute file-path
+    */
+    function set_file_Htpasswd($filename){
+        $this->file_Htpasswd=$filename;
+    }
+    /**
+    * Get the .htpasswd file (AuthUserFile)
+    * @return string $filename - absolute file-path
+    */
+    function get_file_Htpasswd(){
+        return $this->file_Htpasswd;
+    }
+        
+    /**
+    * Set the .htgroup file (AuthGroupFile)
+    * @param string $filename - absolute file-path
+    */
+    function set_file_Htgroup($filename){
+        $this->file_Htgroup=$filename;
+    }
+    /**
+    * Get the .htgroup file (AuthGroupFile)
+    * @return string $filename - absolute file-path
+    */
+    function get_file_Htgroup(){
+        return $this->file_Htgroup;
+    }   
+
+
+    /***************************************/
+    /*            USER METHODS             */
+    /***************************************/
+
+
+    /**
+    * Check if the user exists
+    * @param string $username - Username
+    * @return boolean $UserExist - Returns true it the user exists, false if not
+    */
+    function isUser($username){
+        $UserExist = false;
+        $file = fopen($this->file_Htpasswd,"r");
+
+        while($line = fgets($file)){
+            $lineArr=explode(":",$line);
+            if($username==$lineArr[0]){
+                fclose($file);
+                return true; // the user exists
+             }
+        }
+        fclose($file);
+     
+        return false; // the user does not exist
+    }
+
+    /**
+    * Add a user to the password file
+    * @param string $username - Username
+    * @param string $password - Password for Username
+    * @return boolean $created - Returns true if ok, false if the user already exists
+    */
+    function addUser($username,$password){
+        
+        if($this->isUser($username)==false){
+            $file=fopen($this->file_Htpasswd,"a");
+			if(strtolower(substr(getenv("OS"),0,7))!="windows"){
+				$password=crypt($password);
+			}
+            $newLine=$username.":".$password."\n";
+            fputs($file,$newLine);
+            fclose($file);
+            return true;
+        }
+        else{
+            return false; // the user already exists
+        }
+    }
+
+
+    /**
+    * Delete a user in the password file
+    * @param string $username - Username to delete
+    * @return boolean $deleted - Returns true if user have been deleted otherwise false
+    */
+    function delUser($username){
+        // Read names from file
+        $file=fopen($this->file_Htpasswd,"r");
+        $i=0;
+        $deleted = false;
+        while($line=fgets($file)){
+            $lineArr=explode(":",trim($line));
+            if($username!=$lineArr[0]){
+                $newUserlist[$i][0]=$lineArr[0];
+                $newUserlist[$i][1]=$lineArr[1];
+                $i++;
+            }else{
+                $deleted=true;
+            }
+        }
+        fclose($file);
+        
+        if($deleted==true){        
+           if($i==0) { // There are no more users
+              unlink($this->file_Htpasswd);
+              touch($this->file_Htpasswd);
+           }
+           else{ // Writing names back to file (without the user to delete)
+              $file=fopen($this->file_Htpasswd,"w");
+              for($i=0;$i<count($newUserlist);$i++){
+                 fputs($file,$newUserlist[$i][0].":".$newUserlist[$i][1]."\n");
+              }
+              fclose($file);
+           }
+           return true;
+        }
+        else{
+            return false;
+        }
+    }
+    
+    /**
+    * Return an array of all users
+    * @return array $users - 0 if the are no user
+    */
+    function getUsers() {
+	    $file=fopen($this->file_Htpasswd,"r");
+	    for($i=0;$line=fgets($file);$i++) {
+	        $lineArr=explode(":",$line);
+	        if($lineArr[0]!="") {
+		        $userlist[$i]=$lineArr[0];
+	        }
+	    }
+	    fclose($file);
+        if (!empty($userlist)==0)
+          return 0;
+        else
+	      return $userlist;
+    }
+
+    /**
+    * Return the number of users
+    * @return integer - the number of users
+    */
+    function getNumberOfUsers() {
+	    $users=$this->getUsers();
+	    if($users==0)
+	      return 0;
+	    else
+	      return count($users);
+    }
+    
+    /**
+    * Sets a password to the given username
+    * @param string $username - The name of the User for changing password
+    * @param string $password - New Password for the User
+    * @return boolean $isSet - Returns true if password have been set
+    */    
+    function setPasswd($username,$new_password){
+       if($this->isUser($username)==true){
+          $this->delUser($username);
+          $this->addUser($username,$new_password);
+          return true;
+       }
+       else{
+          return false;
+       }
+    }
+
+
+    /***************************************/
+    /*            GROUP METHODS             */
+    /***************************************/
+
+    /**
+    * Check if the group exists
+    * @param string $groupname - Groupname
+    * @return boolean $GroupExist - Returns true it the group exists, false otherwise
+    */
+    function isGroup($groupname){
+        $GroupExist = false;
+        $file = fopen($this->file_Htgroup,"r");
+
+        while($line = fgets($file)){
+            $lineArr=explode(":",trim($line));
+            if($groupname==trim($lineArr[0])){
+                fclose($file);
+                return true; // the group exists
+             }
+        }
+        fclose($file);
+     
+        return false; // the group does not exist
+    }
+
+    /**
+    * Add a group to the group file
+    * @param string $groupname - Groupname
+    * @return boolean $created - Returns false if the group already exists
+    */
+    function addGroup($groupname){
+        
+        if($this->isGroup($groupname)==false){
+            $file=fopen($this->file_Htgroup,"a");
+            $newLine=$groupname.": "."\n"; // Take care, it should not have a space before :
+            fputs($file,$newLine);
+            fclose($file);
+            return true;
+        }
+        else{
+            return false; // the group already exists
+        }
+    }
+
+
+    /**
+    * Delete a group in the group file
+    * @param string $groupname - Groupname to delete
+    * @return boolean $deleted - Returns true if group have been deleted otherwise false
+    */
+    function delGroup($groupname){
+        // Read names from file
+        $file=fopen($this->file_Htgroup,"r");
+        $i=0;
+        $newGrouplist=0;
+        while($line=fgets($file)){
+            $lineArr=explode(":",trim($line));
+            if($groupname!=trim($lineArr[0])){
+                $newGrouplist[$i]=trim($line);
+                $i++;
+            }else{
+                $deleted=true;
+            }
+        }
+        fclose($file);
+
+        if($deleted==true){
+           if($i==0) { // There are no more users
+              unlink($this->file_Htpasswd);
+              touch($this->file_Htpasswd);
+           }
+           else{ // Writing names back to file (without the user to delete)
+              $file=fopen($this->file_Htgroup,"w");
+              for($i=0;$i<count($newGrouplist);$i++){
+                 fputs($file,$newGrouplist[$i]."\n");
+              }
+              fclose($file);
+           }
+           return true;
+        }
+        else{
+            return false;
+        }
+    }
+    
+    /**
+    * Return an array of all groups
+    * @return array $groups
+    */
+    function getGroups() {
+	    $file=fopen($this->file_Htgroup,"r");
+	    for($i=0;$line=fgets($file);$i++) {
+	        $lineArr=explode(":",trim($line));
+	        if($lineArr[0]!="") {
+		        $grouplist[$i]=trim($lineArr[0]);
+	        }
+	    }
+	    fclose($file);
+        if (!empty($grouplist)==0)
+          return 0;
+        else
+	      return $grouplist;
+    }
+    
+    /***************************************/
+    /*       USER AND GROUP METHODs        */
+    /***************************************/
+    
+    /**
+    * Check if the user is in the group
+    * @param string $username - Username
+    * @param string $groupname - Groupname
+    * @return boolean $exist - Returns true it the user is in the group
+    */
+    function isUserInGroup($username,$groupname){
+        $file = fopen($this->file_Htgroup,"r");
+
+        while($line = fgets($file)){
+            $lineArr=explode(":",trim($line));
+            if($groupname==trim($lineArr[0])){
+                
+                $lineArrUser=explode(" ",trim($lineArr[1]));
+                    for($i=0;$i<count($lineArrUser);$i++){
+                        if(trim($lineArrUser[$i])==$username)
+                          fclose($file);
+                          return true; // the user is in the group
+                    }
+                
+            }
+        }
+        fclose($file);
+     
+        return false; // the user in not in the group
+    }
+
+    /**
+    * Add a user to the group file
+    * @param string $username - Username
+    * @param string $groupname - Groupname
+    * @return boolean $created - Returns false if the user is already in the group
+    */
+    function addUserInGroup($username,$groupname){
+        
+        if($this->isGroup($groupname)==false){
+			$this->addGroup($groupname);
+		}
+		
+		if($this->isUserInGroup($username,$groupname)==false){
+			// Read names from file
+			$file = fopen($this->file_Htgroup,"r");
+			$i=0;
+			while($line = fgets($file)){
+				$lineArr=explode(":",trim($line));
+				if($groupname==trim($lineArr[0])){
+					$newlist[$i]=trim($line)." ".$username;
+				}
+				else{
+					$newlist[$i]=trim($line);
+				}
+				$i++;
+			}
+			fclose($file);
+
+	
+			// Writing names back to file (without the user to delete)
+			$file=fopen($this->file_Htgroup,"w");
+			for($i=0;$i<count($newlist);$i++){
+				fputs($file,$newlist[$i]."\n");
+			}
+			fclose($file);
+			return true;
+        }
+        else{
+            return false; // the user is already in the group
+        }
+    }
+
+    /**
+    * Delete a user from the group file
+    * @param string $username - Username
+    * @param string $groupname - Groupname
+    * @return boolean $created - Returns false if the user was not in the group
+    */
+    function delUserFromGroup($username,$groupname){
+        
+		if($this->isUserInGroup($username,$groupname)==true){
+	
+			// Read names from file
+			$file = fopen($this->file_Htgroup,"r");
+			$i=0;
+			while($line = fgets($file)){
+				$lineArr=explode(":",trim($line));
+				if($groupname==trim($lineArr[0])){
+					
+					$lineArrUser=explode(" ",trim($lineArr[1]));
+					$newlist[$i]=$groupname." : ";
+					
+						for($j=0;$j<count($lineArrUser);$j++){
+							if(trim($lineArrUser[$j])!=$username)
+							  $newlist[$i].=$lineArrUser[$j]." ";
+						}
+					
+				}
+				else{
+					$newlist[$i]=trim($line);
+					
+				}
+				$i++;
+			}
+			fclose($file);
+
+	
+			// Writing names back to file (without the user to delete)
+			$file=fopen($this->file_Htgroup,"w");
+			for($i=0;$i<count($newlist);$i++){
+				fputs($file,$newlist[$i]."\n");
+			}
+			fclose($file);
+			return true;
+
+        }
+        else{
+            return false; // the user is not in the group
+        }
+    }
+
+    /**
+    * Return an array of groups from which the user belongs to
+    *  -- Normaly, user belongs to only one group --
+    * @return array $groups or 0 if the user is in none of the groups
+    */
+    function getGroupOfUser($username) {
+	    $file=fopen($this->file_Htgroup,"r");
+	    $i=0;
+	    //$grouplist=0;
+	    while($line = fgets($file)){
+	       $lineArr=explode(":",trim($line));
+		   $lineArrUser=explode(" ",trim($lineArr[1]));
+
+		   for($j=0;$j<count($lineArrUser);$j++){
+				if(trim($lineArrUser[$j])==$username){
+				   $grouplist[$i]=trim($lineArr[0]);
+				   $i++;
+				   }
+	       }
+	    }
+	    fclose($file);
+        if(empty($grouplist))
+	      return 0;
+	    else
+	      return $grouplist;
+    }
+
+    /***************************************/
+    /*      WRITE the .htaccess file       */
+    /***************************************/
+
+
+
+    /**
+    * Writes the .htaccess file
+  	*/
+    function printHtaccess(){
+       $file=fopen($this->file_Htaccess,"w+");
+       fputs($file,"AuthName        \"".$this->authName."\"\n");
+       fputs($file,"AuthType        ".$this->authType."\n");
+       fputs($file,"AuthUserFile    \"".$this->file_Htpasswd."\"\n");
+       fputs($file,"AuthGroupFile    \"".$this->file_Htgroup."\"\n\n");
+
+       fputs($file,"\nrequire valid-user\n");
+       
+       for($i=0;$i<count($this->admin_files);$i++){
+          fputs($file,"\n<Files ".$this->admin_files[$i].">\n");
+          fputs($file,"  require group admin\n");
+          fputs($file,"</Files>\n");
+       }
+
+       for($i=0;$i<count($this->modo_files);$i++){
+          fputs($file,"\n<Files ".$this->modo_files[$i].">\n");
+          fputs($file,"  require group modo\n");
+          fputs($file,"</Files>\n");
+       }
+
+       fclose($file);
+    }
+
+    /**
+    * Deletes the protection of the given directory
+    */
+    function delHtaccess(){
+        unlink($this->file_Htaccess);
+    }
+    
+}
+?>

Alguns ficheiros não foram mostrados porque muitos ficheiros mudaram neste diff