ndieschburg 15 жил өмнө
parent
commit
4efa05e028
100 өөрчлөгдсөн 6455 нэмэгдсэн , 1515 устгасан
  1. 19 8
      documentation/changelog.html
  2. 2 1
      main/admin/add_by_ajax_sub_language.inc.php
  3. 12 33
      main/admin/add_courses_to_session.php
  4. 4 24
      main/admin/add_users_to_session.php
  5. 5 4
      main/admin/admin.class.php
  6. 2 2
      main/admin/course_user_list.php
  7. 2 2
      main/admin/languages.php
  8. 26 17
      main/admin/new_sub_language.php
  9. 8 5
      main/admin/register_sub_language.php
  10. 4 3
      main/auth/inscription.php
  11. 466 466
      main/auth/openid/login.php
  12. 6 30
      main/coursecopy/classes/CourseBuilder.class.php
  13. 4 2
      main/coursecopy/classes/CourseRestorer.class.php
  14. 4 1
      main/css/blue_lagoon/jquery.tabs.css
  15. 13 8
      main/css/cosmic_campus/default.css
  16. 10 8
      main/css/delicious_bordeaux/default.css
  17. 0 8
      main/css/dokeos_blue/default.css
  18. 11 8
      main/css/dokeos_classic/default.css
  19. 11 8
      main/css/dokeos_classic_2D/default.css
  20. 11 7
      main/css/empire_green/default.css
  21. 11 8
      main/css/fruity_orange/default.css
  22. 12 7
      main/css/medical/default.css
  23. 11 7
      main/css/public_admin/default.css
  24. 11 7
      main/css/royal_purple/default.css
  25. 13 12
      main/css/silver_line/default.css
  26. 11 7
      main/css/sober_brown/default.css
  27. 11 7
      main/css/steel_grey/default.css
  28. 11 7
      main/css/tasty_olive/default.css
  29. 14 19
      main/document/slideshowoptions.php
  30. 57 57
      main/dropbox/dropbox_functions.inc.php
  31. 2 8
      main/exercice/adminhp.php
  32. 8 22
      main/exercice/exercice.php
  33. 1 1
      main/exercice/exercise_result.class.php
  34. 30 39
      main/exercice/exercise_submit_modal.php
  35. 12 20
      main/exercice/hotpotatoes.lib.php
  36. 1 1
      main/exercice/showinframes.php
  37. 1 1
      main/exercice/testheaderpage.php
  38. 22 16
      main/forum/forumfunction.inc.php
  39. 1 1
      main/gradebook/gradebook_result.class.php
  40. BIN
      main/img/wiki/assignment.gif
  41. BIN
      main/img/wiki/task.gif
  42. BIN
      main/img/wiki/works.gif
  43. 11 6
      main/inc/global.inc.php
  44. 1 0
      main/inc/lib/add_course.lib.inc.php
  45. 3453 0
      main/inc/lib/asciimath/ASCIIMathML.js
  46. 363 0
      main/inc/lib/asciimath/asciimath.html
  47. 118 0
      main/inc/lib/asciimath/asciimathcalculator.html
  48. 227 0
      main/inc/lib/asciimath/asciimathchanges.txt
  49. 117 0
      main/inc/lib/asciimath/asciimathdemo.html
  50. 76 0
      main/inc/lib/asciimath/asciimathextend.html
  51. 38 0
      main/inc/lib/asciimath/asciimathsample.html
  52. 506 0
      main/inc/lib/asciimath/asciimathsyntax.html
  53. 8 0
      main/inc/lib/asciimath/d.svg
  54. 44 0
      main/inc/lib/asciimath/filter.php
  55. 8 0
      main/inc/lib/asciimath/index.html
  56. 28 0
      main/inc/lib/asciimath/javascript.php
  57. 37 0
      main/inc/lib/asciimath/readme.txt
  58. 3 2
      main/inc/lib/blog.lib.php
  59. 29 4
      main/inc/lib/course.lib.php
  60. 21 38
      main/inc/lib/events.lib.inc.php
  61. 2 2
      main/inc/lib/fckeditor/editor/_source/commandclasses/fck_othercommands.js
  62. 4 4
      main/inc/lib/fckeditor/editor/_source/commandclasses/fcktextcolorcommand.js
  63. 178 178
      main/inc/lib/fckeditor/editor/_source/fckeditorapi.js
  64. 32 0
      main/inc/lib/fckeditor/editor/_source/internals/fck.js
  65. 10 0
      main/inc/lib/fckeditor/editor/_source/internals/fck_gecko.js
  66. 14 4
      main/inc/lib/fckeditor/editor/_source/internals/fck_ie.js
  67. 1 1
      main/inc/lib/fckeditor/editor/_source/internals/fckdialog.js
  68. 38 10
      main/inc/lib/fckeditor/editor/_source/internals/fckdomtools.js
  69. 17 0
      main/inc/lib/fckeditor/editor/_source/internals/fckxhtml.js
  70. 36 0
      main/inc/lib/fckeditor/editor/_source/internals/fckxhtml_ie.js
  71. 1 1
      main/inc/lib/fckeditor/editor/dialog/common/fck_dialog_common.js
  72. 6 1
      main/inc/lib/fckeditor/editor/dialog/fck_about.html
  73. 5 0
      main/inc/lib/fckeditor/editor/dialog/fck_anchor.html
  74. 5 0
      main/inc/lib/fckeditor/editor/dialog/fck_button.html
  75. 5 0
      main/inc/lib/fckeditor/editor/dialog/fck_checkbox.html
  76. 5 0
      main/inc/lib/fckeditor/editor/dialog/fck_colorselector.html
  77. 5 0
      main/inc/lib/fckeditor/editor/dialog/fck_div.html
  78. 22 17
      main/inc/lib/fckeditor/editor/dialog/fck_docprops.html
  79. 1 1
      main/inc/lib/fckeditor/editor/dialog/fck_docprops/fck_document_preview.html
  80. 5 0
      main/inc/lib/fckeditor/editor/dialog/fck_flash.html
  81. 5 0
      main/inc/lib/fckeditor/editor/dialog/fck_form.html
  82. 5 0
      main/inc/lib/fckeditor/editor/dialog/fck_hiddenfield.html
  83. 5 0
      main/inc/lib/fckeditor/editor/dialog/fck_image.html
  84. 5 0
      main/inc/lib/fckeditor/editor/dialog/fck_link.html
  85. 5 0
      main/inc/lib/fckeditor/editor/dialog/fck_listprop.html
  86. 5 0
      main/inc/lib/fckeditor/editor/dialog/fck_paste.html
  87. 5 0
      main/inc/lib/fckeditor/editor/dialog/fck_radiobutton.html
  88. 5 0
      main/inc/lib/fckeditor/editor/dialog/fck_replace.html
  89. 5 0
      main/inc/lib/fckeditor/editor/dialog/fck_select.html
  90. 5 0
      main/inc/lib/fckeditor/editor/dialog/fck_smiley.html
  91. 5 0
      main/inc/lib/fckeditor/editor/dialog/fck_source.html
  92. 5 0
      main/inc/lib/fckeditor/editor/dialog/fck_specialchar.html
  93. 5 0
      main/inc/lib/fckeditor/editor/dialog/fck_spellerpages.html
  94. 0 148
      main/inc/lib/fckeditor/editor/dialog/fck_spellerpages/spellerpages/server-scripts/spellchecker.cfm
  95. 0 181
      main/inc/lib/fckeditor/editor/dialog/fck_spellerpages/spellerpages/server-scripts/spellchecker.pl
  96. 27 22
      main/inc/lib/fckeditor/editor/dialog/fck_table.html
  97. 8 3
      main/inc/lib/fckeditor/editor/dialog/fck_tablecell.html
  98. 5 0
      main/inc/lib/fckeditor/editor/dialog/fck_template.html
  99. 5 0
      main/inc/lib/fckeditor/editor/dialog/fck_textarea.html
  100. 5 0
      main/inc/lib/fckeditor/editor/dialog/fck_textfield.html

+ 19 - 8
documentation/changelog.html

@@ -33,16 +33,27 @@
   <li>An internationalization option has been added for improving sorting in arbitrary language. When the <a href="http://php.net/manual/en/book.intl.php" target="_blank">intl</a> php-extension has been installed, various sorting routines exploit it for better sorting. Rationale: The PHP5 run-time environment does not provide native and reliable way of sorting UTF-8 strings. (FS#306)</li>
   <li>An internationalization option has been added for improving sorting in arbitrary language. When the <a href="http://php.net/manual/en/book.intl.php" target="_blank">intl</a> php-extension has been installed, various sorting routines exploit it for better sorting. Rationale: The PHP5 run-time environment does not provide native and reliable way of sorting UTF-8 strings. (FS#306)</li>
   <li>The installation sript: The page about system requilements has been updated. Also, at the very beginning, a check has been added whether the <a href="http://php.net/manual/en/book.mbstring.php" target="_blank">mbstring</a> php-extension is installed - see <a href="http://dokeos.com/forum/viewtopic.php?t=29548" target="_blank">the related forum topic</a>. (FS#306)</li>
   <li>The installation sript: The page about system requilements has been updated. Also, at the very beginning, a check has been added whether the <a href="http://php.net/manual/en/book.mbstring.php" target="_blank">mbstring</a> php-extension is installed - see <a href="http://dokeos.com/forum/viewtopic.php?t=29548" target="_blank">the related forum topic</a>. (FS#306)</li>
   <li>A new php-based configuration for the online editor has been implemented, see <i>dokeos/main/inc/lib/fckeditor/myconfig.php</i>. Also, toolbar definitions have been split in separate php-files within the directory <i>dokeos/main/inc/lib/fckeditor/toolbars/</i> . Customization of the editor is more convenient and flexible now. (FS#2867)</li>
   <li>A new php-based configuration for the online editor has been implemented, see <i>dokeos/main/inc/lib/fckeditor/myconfig.php</i>. Also, toolbar definitions have been split in separate php-files within the directory <i>dokeos/main/inc/lib/fckeditor/toolbars/</i> . Customization of the editor is more convenient and flexible now. (FS#2867)</li>
-  <li>The online editor: A upgrade from FCKEditor 2.6.4 to <b>FCKEditor 2.6.4.1</b> has been implemented. (FS#4383)</li>
-  <li>The online editor: Several known bug-fixes from FCKEditor 2.6.5 SVN have been implemented, tickets <a href="http://dev.fckeditor.net/ticket/2821" target="_blank">#2821</a>, <a href="http://dev.fckeditor.net/ticket/2856" target="_blank">#2856</a>, <a href="http://dev.fckeditor.net/ticket/2915" target="_blank">#2915</a>, <a href="http://dev.fckeditor.net/ticket/3120" target="_blank">#3120</a>, <a href="http://dev.fckeditor.net/ticket/3181" target="_blank">#3181</a>, <a href="http://dev.fckeditor.net/ticket/3429" target="_blank">#3429</a>, <a href="http://dev.fckeditor.net/ticket/3439" target="_blank">#3439</a>, <a href="http://dev.fckeditor.net/ticket/3880" target="_blank">#3880</a>. (FS#2867)</li>
-  <li>The online editor: The simple file manager, the advanced file manager and the image manager have been integrated by default with the editor's dialog system. Thus, they work faster and in a more secure way. (FS#2867)</li>
-  <li>The online editor: Blocking copy/paste for trainees has been added. The feature is configurable through editing the toolbar definition files within the directory <i>dokeos/main/inc/lib/fckeditor/toolbars/</i> . (FS#2867)</li>
-  <li>The online editor: Preview tabs have been added to the dialogs for inserting video, flv-video, and YouTube video. (FS#2867)</li>
-  <li>The online editor: The <b>audio</b> plugin has been activated by default as an implementation of the "Insert audio / Audio properties" dialog. This new plugin is intended to replace the "MP3" plugin. (FS#2867)</li>
-  <li>The online editor: Configuration of the <b>mimetex</b> plugin has been reworked to gain simplicity. The procedure for configuration has been updated, see <a href="http://www.dokeos.com/forum/viewtopic.php?t=29594" target="_blank">the related forum topic</a>. (FS#2867)</li>
-  <li>The online editor: The toolbar icons have been upgraded to those from CKEditor 3.0. (FS#2867)</li>
+  <li>Online editor: A upgrade from FCKEditor 2.6.4 to <b>FCKEditor 2.6.4.1</b> has been implemented. (FS#4383)</li>
+  <li>Online editor: Several known bug-fixes from FCKEditor 2.6.5 SVN have been implemented, tickets <a href="http://dev.fckeditor.net/ticket/1537" target="_blank">#1537</a>, <a href="http://dev.fckeditor.net/ticket/2156" target="_blank">#2156</a>, <a href="http://dev.fckeditor.net/ticket/2689" target="_blank">#2689</a>, <a href="http://dev.fckeditor.net/ticket/2821" target="_blank">#2821</a>, <a href="http://dev.fckeditor.net/ticket/2856" target="_blank">#2856</a>, <a href="http://dev.fckeditor.net/ticket/2874" target="_blank">#2874</a>, <a href="http://dev.fckeditor.net/ticket/2915" target="_blank">#2915</a>, <a href="http://dev.fckeditor.net/ticket/3120" target="_blank">#3120</a>, <a href="http://dev.fckeditor.net/ticket/3181" target="_blank">#3181</a>, <a href="http://dev.fckeditor.net/ticket/3427" target="_blank">#3427</a>, <a href="http://dev.fckeditor.net/ticket/3429" target="_blank">#3429</a>, <a href="http://dev.fckeditor.net/ticket/3439" target="_blank">#3439</a>, <a href="http://dev.fckeditor.net/ticket/3446" target="_blank">#3446</a>, <a href="http://dev.fckeditor.net/ticket/3481" target="_blank">#3481</a>, <a href="http://dev.fckeditor.net/ticket/3677" target="_blank">#3677</a>, <a href="http://dev.fckeditor.net/ticket/3818" target="_blank">#3818</a>, <a href="http://dev.fckeditor.net/ticket/3880" target="_blank">#3880</a>, <a href="http://dev.fckeditor.net/ticket/3925" target="_blank">#3925</a>. (FS#2867)</li>
+  <li>Online editor: The simple file manager, the advanced file manager and the image manager have been integrated by default with the editor's dialog system. Thus, they work faster and in a more secure way. (FS#2867)</li>
+  <li>Online editor: Blocking copy/paste for trainees has been added. The feature is configurable through editing the toolbar definition files within the directory <i>dokeos/main/inc/lib/fckeditor/toolbars/</i> . (FS#2867)</li>
+  <li>Online editor: Preview tabs have been added to the dialogs for inserting video, flv-video, and YouTube video. (FS#2867)</li>
+  <li>Online editor: The <b>audio</b> plugin has been activated by default as an implementation of the "Insert audio / Audio properties" dialog. This new plugin is intended to replace the "MP3" plugin. (FS#2867)</li>
+  <li>Online editor: Configuration of the <b>mimetex</b> plugin has been reworked to gain simplicity. The procedure for configuration has been updated, see <a href="http://www.dokeos.com/forum/viewtopic.php?t=29594" target="_blank">the related forum topic</a>. (FS#2867)</li>
+  <li>Online editor: A new <b>asciimath</b> plugin for inserting mathematical formulas has been added. It is based on the <a href="http://mathcs.chapman.edu/~jipsen/mathml/asciimath.html" target="_blank">ASCIIMathML.js</a> library. (FS#2867)</li>
+  <li>Online editor: The toolbar icons have been upgraded to those from CKEditor 3.0. (FS#2867)</li>
   <li>A solution has been implemented for fixing the <a href="http://bugs.adobe.com/jira/browse/FP-529" target="_blank">"__flash__removeCallback" bug</a>, which affects the media player on Internet Explorer browser. (FS#4378 and FS#2867)</li>
   <li>A solution has been implemented for fixing the <a href="http://bugs.adobe.com/jira/browse/FP-529" target="_blank">"__flash__removeCallback" bug</a>, which affects the media player on Internet Explorer browser. (FS#4378 and FS#2867)</li>
   <li>Implement new sub-language feature by which language terms redefinition becomes possible through the admin section (FS#4321)</li>
   <li>Implement new sub-language feature by which language terms redefinition becomes possible through the admin section (FS#4321)</li>
+  <li>Social: Added possibility to define RSS feeds inside personal page of social network (need to define an 'rssfeeds' extra user text field)</li>
+  <li>Admin: Added courses from sessions inside AJAX popup of courses list in users list (SVN#22398)</li>
+  <li>Admin: Showing full-length course titles in list of courses while adding to sessions(SVN#22399)</li>
+  <li>Admin: Added session name in title of session edition pages(SVN#22400)</li>
+</ul>
+<br />
+<h3>Known issues</h3>
+<ul>
+  <li></li>
+  <li></li>
 </ul>
 </ul>
 <br />
 <br />
 <h3>Known issues</h3>
 <h3>Known issues</h3>

+ 2 - 1
main/admin/add_by_ajax_sub_language.inc.php

@@ -12,8 +12,9 @@ $new_language=Security::remove_XSS($_POST['new_language']);
 $language_variable=Security::remove_XSS($_POST['variable_language']);
 $language_variable=Security::remove_XSS($_POST['variable_language']);
 $file_language=Security::remove_XSS($_POST['file_language']);
 $file_language=Security::remove_XSS($_POST['file_language']);
 $id_language=Security::remove_XSS($_POST['id']);
 $id_language=Security::remove_XSS($_POST['id']);
+$sub_language_id=Security::remove_XSS($_POST['sublanguage_id']);
  
  
-$all_data_of_language=AdminManager::get_all_information_of_sub_language($_POST['id']);
+$all_data_of_language=AdminManager::get_all_information_of_sub_language($id_language,$sub_language_id);
 $dokeos_path_folder=api_get_path('SYS_LANG_PATH').$all_data_of_language['dokeos_folder'].'/'.$file_language;
 $dokeos_path_folder=api_get_path('SYS_LANG_PATH').$all_data_of_language['dokeos_folder'].'/'.$file_language;
 $all_file_of_directory=AdminManager::get_all_language_variable_in_file($dokeos_path_folder);
 $all_file_of_directory=AdminManager::get_all_language_variable_in_file($dokeos_path_folder);
 AdminManager::add_file_in_language_directory ($dokeos_path_folder);
 AdminManager::add_file_in_language_directory ($dokeos_path_folder);

+ 12 - 33
main/admin/add_courses_to_session.php

@@ -1,26 +1,5 @@
-<?php
-/*
-==============================================================================
-	Dokeos - elearning and course management software
-
-	Copyright (c) 2004-2009 Dokeos SPRL
-	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, rue du Corbeau, 108, B-1030 Brussels, Belgium, info@dokeos.com
-==============================================================================
-*/
+<?php //$id: $
+/* For licensing terms, see /dokeos_license.txt */
 /**
 /**
 ==============================================================================
 ==============================================================================
 *	@package dokeos.admin
 *	@package dokeos.admin
@@ -35,11 +14,11 @@ $language_file='admin';
 $cidReset=true;
 $cidReset=true;
 
 
 // including some necessary dokeos files
 // including some necessary dokeos files
-require('../inc/global.inc.php');
+require '../inc/global.inc.php';
 
 
 // including additonal libraries
 // including additonal libraries
-require_once ('../inc/lib/xajax/xajax.inc.php');
-require_once (api_get_path(LIBRARY_PATH).'sessionmanager.lib.php');
+require_once '../inc/lib/xajax/xajax.inc.php';
+require_once api_get_path(LIBRARY_PATH).'sessionmanager.lib.php';
 $xajax = new xajax();
 $xajax = new xajax();
 //$xajax->debugOn();
 //$xajax->debugOn();
 $xajax -> registerFunction ('search_courses');
 $xajax -> registerFunction ('search_courses');
@@ -164,7 +143,7 @@ function search_courses($needle,$type)
 			while($course = Database :: fetch_array($rs)) {	
 			while($course = Database :: fetch_array($rs)) {	
 				$course_list[] = $course['code'];
 				$course_list[] = $course['code'];
 				$course_title=str_replace("'","\'",$course_title);				
 				$course_title=str_replace("'","\'",$course_title);				
-				$return .= '<option value="'.$course['code'].'">'.$course['title'].' ('.$course['visual_code'].')</option>';				
+				$return .= '<option value="'.$course['code'].'" title="'.htmlspecialchars($course['title'].' ('.$course['visual_code'].')',ENT_QUOTES).'">'.$course['title'].' ('.$course['visual_code'].')</option>';				
 			}
 			}
 			$return .= '</select>';
 			$return .= '</select>';
 			
 			
@@ -301,8 +280,9 @@ echo '<div class="actions">';
 echo $link_add_type_unique.$link_add_type_multiple;
 echo $link_add_type_unique.$link_add_type_multiple;
 echo '</div>';
 echo '</div>';
 
 
-// the form header 
-echo '<div class="row"><div class="form_header">'.$tool_name.'</div></div>';
+// the form header
+$session_info = SessionManager::fetch($id_session);
+echo '<div class="row"><div class="form_header">'.$tool_name.' ('.$session_info['name'].')</div></div>';
 
 
 
 
 /*$sql = 'SELECT COUNT(1) FROM '.$tbl_course;
 /*$sql = 'SELECT COUNT(1) FROM '.$tbl_course;
@@ -436,7 +416,7 @@ else
 	foreach($nosessionCourses as $enreg)
 	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>
+		<option value="<?php echo $enreg['code']; ?>" <?php echo 'title="'.htmlspecialchars($enreg['title'].' ('.$enreg['visual_code'].')',ENT_QUOTES).'"'; if(in_array($enreg['code'],$CourseList)) echo 'selected="selected"'; ?>><?php echo $enreg['title'].' ('.$enreg['visual_code'].')'; ?></option>
 		<?php
 		<?php
 	}
 	}
 	?>  </select></div> <?php
 	?>  </select></div> <?php
@@ -447,8 +427,7 @@ unset($nosessionCourses);
   </select></td>
   </select></td>
   <td width="10%" valign="middle" align="center">
   <td width="10%" valign="middle" align="center">
   <?php
   <?php
-  if($ajax_search)
-  {
+  if ($ajax_search) {
   ?>
   ?>
   	<input type="button" onclick="remove_item(document.getElementById('destination'))" value="<<" />
   	<input type="button" onclick="remove_item(document.getElementById('destination'))" value="<<" />
   <?php
   <?php
@@ -480,7 +459,7 @@ unset($nosessionCourses);
 foreach($sessionCourses as $enreg)
 foreach($sessionCourses as $enreg)
 {	
 {	
 ?>	
 ?>	
-	<option value="<?php echo $enreg['code']; ?>"><?php echo $enreg['title'].' ('.$enreg['visual_code'].')'; ?></option>
+	<option value="<?php echo $enreg['code']; ?>" title="<?php echo htmlspecialchars($enreg['title'].' ('.$enreg['visual_code'].')',ENT_QUOTES); ?>"><?php echo $enreg['title'].' ('.$enreg['visual_code'].')'; ?></option>
 
 
 <?php 
 <?php 
 }
 }

+ 4 - 24
main/admin/add_users_to_session.php

@@ -1,26 +1,5 @@
-<?php
-/*
-==============================================================================
-	Dokeos - elearning and course management software
-
-	Copyright (c) 2004-2009 Dokeos SPRL
-	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, rue du Corbeau, 108, B-1030 Brussels, Belgium, info@dokeos.com
-==============================================================================
-*/
+<?php //$id: $
+/* For licensing terms, see /dokeos_license.txt */
 /**
 /**
 ==============================================================================
 ==============================================================================
 *	@package dokeos.admin
 *	@package dokeos.admin
@@ -275,8 +254,9 @@ if($_POST['form_sent']) {
 	}
 	}
 }
 }
 
 
+$session_info = SessionManager::fetch($id_session);
 Display::display_header($tool_name);
 Display::display_header($tool_name);
-api_display_tool_title($tool_name);
+api_display_tool_title($tool_name.' ('.$session_info['name'].')');
 
 
 $nosessionUsersList = $sessionUsersList = array();
 $nosessionUsersList = $sessionUsersList = array();
 /*$sql = 'SELECT COUNT(1) FROM '.$tbl_user;
 /*$sql = 'SELECT COUNT(1) FROM '.$tbl_user;

+ 5 - 4
main/admin/admin.class.php

@@ -39,11 +39,12 @@ class AdminManager {
     /**
     /**
      * Get all information of sub-language
      * Get all information of sub-language
      * @param Integer The parent id(Language father id)
      * @param Integer The parent id(Language father id)
+     * @param Integer The sub language id
      * @return Array All information about sub-language
      * @return Array All information about sub-language
      */
      */
-	public static function get_all_information_of_sub_language ($parent_id) {
+	public static function get_all_information_of_sub_language ($parent_id,$sub_language_id) {
 		$tbl_admin_languages 	= Database :: get_main_table(TABLE_MAIN_LANGUAGE);	
 		$tbl_admin_languages 	= Database :: get_main_table(TABLE_MAIN_LANGUAGE);	
-		$sql='SELECT * FROM '.$tbl_admin_languages.' WHERE parent_id="'.Database::escape_string($parent_id).'"';
+		$sql='SELECT * FROM '.$tbl_admin_languages.' WHERE parent_id="'.Database::escape_string($parent_id).'" AND id="'.Database::escape_string($sub_language_id).'"';
 		$rs=Database::query($sql,__FILE__,__LINE__);
 		$rs=Database::query($sql,__FILE__,__LINE__);
 		$all_information=array();
 		$all_information=array();
 		while ($row=Database::fetch_array($rs,'ASSOC')) {
 		while ($row=Database::fetch_array($rs,'ASSOC')) {
@@ -123,9 +124,9 @@ class AdminManager {
 	 * @param Integer The parent id
 	 * @param Integer The parent id
 	 * @return void()
 	 * @return void()
 	 */   
 	 */   
-   public static function removed_sub_language ($parent_id) {
+   public static function removed_sub_language ($parent_id,$sub_language_id) {
    		$tbl_admin_languages 	= Database :: get_main_table(TABLE_MAIN_LANGUAGE);		
    		$tbl_admin_languages 	= Database :: get_main_table(TABLE_MAIN_LANGUAGE);		
-		$sql='DELETE FROM '.$tbl_admin_languages.' WHERE parent_id="'.Database::escape_string($parent_id).'"';
+		$sql='DELETE FROM '.$tbl_admin_languages.' WHERE parent_id="'.Database::escape_string($parent_id).'" AND id="'.Database::escape_string($sub_language_id).'" ';
     	$rs=Database::query($sql,__FILE__,__LINE__);
     	$rs=Database::query($sql,__FILE__,__LINE__);
    }
    }
    	/**
    	/**

+ 2 - 2
main/admin/course_user_list.php

@@ -5,7 +5,7 @@ require_once '../inc/lib/course.lib.php';
 $user_id=intval($_POST['user_id']);
 $user_id=intval($_POST['user_id']);
 $list_course_all_info=array();
 $list_course_all_info=array();
 $list_course=array();
 $list_course=array();
-$list_course_all_info=CourseManager::get_courses_list_by_user_id($user_id);
+$list_course_all_info=CourseManager::get_courses_list_by_user_id($user_id,true);
 for ($i=0;$i<count($list_course_all_info);$i++) {
 for ($i=0;$i<count($list_course_all_info);$i++) {
 	$list_course[]=$list_course_all_info[$i]['title'];
 	$list_course[]=$list_course_all_info[$i]['title'];
 }
 }
@@ -25,4 +25,4 @@ if (count($list_course)==0) {
         <td><?php echo api_convert_encoding($list_course[$k],'UTF-8',$charset);?></td>
         <td><?php echo api_convert_encoding($list_course[$k],'UTF-8',$charset);?></td>
     </tr>
     </tr>
 <?php }?>	
 <?php }?>	
-</table>
+</table>

+ 2 - 2
main/admin/languages.php

@@ -264,8 +264,8 @@ while ($row = Database::fetch_array($result_select)) {
 		} else {
 		} else {
 				$allow_use_sub_language='';
 				$allow_use_sub_language='';
 				$all_information_of_sub_language=AdminManager::get_all_information_of_language($row['id']);
 				$all_information_of_sub_language=AdminManager::get_all_information_of_language($row['id']);
-				$allow_add_term_sub_language = "&nbsp;<a href='register_sub_language.php?action=registersublanguage&id=".$all_information_of_sub_language['parent_id']."'>".Display::return_icon('2rightarrow.gif', get_lang('AddWordForTheSubLanguage'),array('width'=>'22','height'=>'22'))."</a>";									
-				$allow_delete_sub_language = "&nbsp;<a href='new_sub_language.php?action=deletesublanguage&id=".$all_information_of_sub_language['parent_id']."'>".Display::return_icon('delete_data.gif', get_lang('DeleteSubLanguage'),array('width'=>'22','height'=>'22'))."</a>";		
+				$allow_add_term_sub_language = "&nbsp;<a href='register_sub_language.php?action=registersublanguage&id=".Security::remove_XSS($all_information_of_sub_language['parent_id'])."&sub_language_id=".Security::remove_XSS($row['id'])."'>".Display::return_icon('2rightarrow.gif', get_lang('AddWordForTheSubLanguage'),array('width'=>'22','height'=>'22'))."</a>";									
+				$allow_delete_sub_language = "&nbsp;<a href='new_sub_language.php?action=deletesublanguage&id=".Security::remove_XSS($all_information_of_sub_language['parent_id'])."&sub_language_id=".Security::remove_XSS($row['id'])."'>".Display::return_icon('delete_data.gif', get_lang('DeleteSubLanguage'),array('width'=>'22','height'=>'22'))."</a>";		
 		}
 		}
 		
 		
 	} else {
 	} else {

+ 26 - 17
main/admin/new_sub_language.php

@@ -109,15 +109,10 @@ function ckeck_if_is_parent_of_sub_language ($parent_id) {
 /**
 /**
  * Get all information of sub-language
  * Get all information of sub-language
  */
  */
-function allow_get_all_information_of_sub_language ($parent_id) {
-	return AdminManager::get_all_information_of_sub_language($parent_id); 
-}
-/**
- * Delete sub-language
- */
-function removed_sub_language ($parent_id) {
-	AdminManager::removed_sub_language($parent_id);
+function allow_get_all_information_of_sub_language ($parent_id,$sub_language_id) {
+	return AdminManager::get_all_information_of_sub_language($parent_id,$sub_language_id); 
 }
 }
+
 /**
 /**
  * Add directory for sub-language 
  * Add directory for sub-language 
  */
  */
@@ -153,7 +148,19 @@ function remove_directory_of_sub_language ($path) {
 }
 }
 /*end declare functions*/
 /*end declare functions*/
 
 
-//add register
+//add data
+
+if (isset($_GET['sub_language_id']) && $_GET['sub_language_id']==strval(intval($_GET['sub_language_id']))) {
+	$language_name=get_name_of_language_by_id($_GET['sub_language_id']);
+		if (check_if_exist_language_by_id ($_GET['sub_language_id'])===true) {
+			$sub_language_id=$_GET['sub_language_id'];
+			$sub_language_id_exist=true;
+		} else {
+			$sub_language_id_exist=false;
+		}
+		
+}
+
 if (isset($_GET['id']) && $_GET['id']==strval(intval($_GET['id']))) {
 if (isset($_GET['id']) && $_GET['id']==strval(intval($_GET['id']))) {
 	$language_name=get_name_of_language_by_id($_GET['id']);
 	$language_name=get_name_of_language_by_id($_GET['id']);
 		if (check_if_exist_language_by_id ($_GET['id'])===true) {
 		if (check_if_exist_language_by_id ($_GET['id'])===true) {
@@ -170,9 +177,9 @@ if (isset($_GET['id']) && $_GET['id']==strval(intval($_GET['id']))) {
 
 
 //removed and register
 //removed and register
 
 
-if (isset($_GET['id']) && $_GET['id']==strval(intval($_GET['id']))) {
-	if (check_if_exist_language_by_id($_GET['id'])===true) {
-	 	$get_all_information=allow_get_all_information_of_sub_language ($_GET['id']);
+if ((isset($_GET['id']) && $_GET['id']==strval(intval($_GET['id']))) && (isset($_GET['sub_language_id']) && $_GET['sub_language_id']==strval(intval($_GET['sub_language_id'])))) {
+	if (check_if_exist_language_by_id($_GET['id'])===true && check_if_exist_language_by_id($_GET['sub_language_id'])===true) {
+	 	$get_all_information=allow_get_all_information_of_sub_language ($_GET['id'],$_GET['sub_language_id']);
 		$original_name=$get_all_information['original_name'];
 		$original_name=$get_all_information['original_name'];
 		$english_name=$get_all_information['english_name'];
 		$english_name=$get_all_information['english_name'];
 		$isocode=$get_all_information['isocode'];
 		$isocode=$get_all_information['isocode'];
@@ -243,15 +250,17 @@ if (isset($_POST['SubmitAddDeleteLanguage'])) {
 	if (is_dir($path)) {
 	if (is_dir($path)) {
 		$rs=remove_directory_of_sub_language($path);
 		$rs=remove_directory_of_sub_language($path);
 		if ($rs===true) {
 		if ($rs===true) {
-			removed_sub_language($parent_id);
+			AdminManager::removed_sub_language($parent_id,$sub_language_id);
+			Display::display_confirmation_message(get_lang('TheSubLanguageHasBeenRemoved'));
 		}
 		}
 		
 		
 	}
 	}
 }
 }
-	
-	if (ckeck_if_is_parent_of_sub_language ($parent_id)===false ) {
+     // ckeck_if_is_parent_of_sub_language($parent_id)===false
+	//
+	if (isset($_GET['action']) && $_GET['action']=='definenewsublanguage') {
 		$text=$language_name;
 		$text=$language_name;
-		$form = new FormValidator('addsublanguage', 'post', 'new_sub_language.php?id='.Security::remove_XSS($_GET['id']));
+		$form = new FormValidator('addsublanguage', 'post', 'new_sub_language.php?id='.Security::remove_XSS($_GET['id']).'&action=definenewsublanguage');
 		$class='add';
 		$class='add';
 		$form->addElement('header', '', $text);			
 		$form->addElement('header', '', $text);			
 		$form->addElement('text', 'original_name', get_lang('OriginalName'),'class="input_titles"');
 		$form->addElement('text', 'original_name', get_lang('OriginalName'),'class="input_titles"');
@@ -266,7 +275,7 @@ if (isset($_POST['SubmitAddDeleteLanguage'])) {
 	} else {
 	} else {
 		if (isset($_GET['action']) && $_GET['action']=='deletesublanguage') {
 		if (isset($_GET['action']) && $_GET['action']=='deletesublanguage') {
 			$text=$language_name;
 			$text=$language_name;
-			$form = new FormValidator('deletesublanguage', 'post', 'new_sub_language.php?id='.Security::remove_XSS($_GET['id']));
+			$form = new FormValidator('deletesublanguage', 'post', 'new_sub_language.php?id='.Security::remove_XSS($_GET['id']).'&sub_language_id='.Security::remove_XSS($_GET['sub_language_id']));
 			$class='minus';
 			$class='minus';
 			$form->addElement('header', '', $text);
 			$form->addElement('header', '', $text);
 			$form->addElement('static', '', get_lang('OriginalName'),$original_name);
 			$form->addElement('static', '', get_lang('OriginalName'),$original_name);

+ 8 - 5
main/admin/register_sub_language.php

@@ -51,6 +51,7 @@ $htmlHeadXtra[] ='<script type="text/javascript">
 		button_name=button_name.split("_");
 		button_name=button_name.split("_");
 		button_name=button_name[1];
 		button_name=button_name[1];
 		is_id=$("#id_hidden_original_file").attr("value");
 		is_id=$("#id_hidden_original_file").attr("value");
+		is_sublanguage_id=$("#id_hidden_sublanguage").attr("value");
 		is_variable_language="$"+button_name;
 		is_variable_language="$"+button_name;
 		is_new_language=$("#txtid_"+button_name).attr("value");
 		is_new_language=$("#txtid_"+button_name).attr("value");
 		if (is_new_language=="undefined") {
 		if (is_new_language=="undefined") {
@@ -66,7 +67,7 @@ $htmlHeadXtra[] ='<script type="text/javascript">
 				},
 				},
 				type: "POST",
 				type: "POST",
 				url: "../admin/add_by_ajax_sub_language.inc.php",
 				url: "../admin/add_by_ajax_sub_language.inc.php",
-				data: "new_language="+is_new_language+"&variable_language="+is_variable_language+"&file_language="+is_file_language+"&id="+is_id,
+				data: "new_language="+is_new_language+"&variable_language="+is_variable_language+"&file_language="+is_file_language+"&id="+is_id+"&sublanguage_id="+is_sublanguage_id,
 				success: function(datos) {
 				success: function(datos) {
 					$("#div_message_information_id").html("<div class=\"confirmation-message\">'.get_lang('TheNewWordHasBeenAdded').'</div>");
 					$("#div_message_information_id").html("<div class=\"confirmation-message\">'.get_lang('TheNewWordHasBeenAdded').'</div>");
 				
 				
@@ -158,8 +159,9 @@ $form->display();
 echo '</div>';*/
 echo '</div>';*/
 
 
 $html.='<div style="float:left" class="actions" >';
 $html.='<div style="float:left" class="actions" >';
-$html.='<form style="float:left" id="Loadlanguage" name="Loadlanguage" method="post" action="register_sub_language.php?id='.Security::remove_XSS($_GET['id']).'&original_file='.$request_file.'" >';
+$html.='<form style="float:left" id="Loadlanguage" name="Loadlanguage" method="post" action="register_sub_language.php?id='.Security::remove_XSS($_GET['id']).'&sub_language_id='.Security::remove_XSS($_GET['sub_language_id']).'&original_file='.$request_file.'" >';
 $html.='<input  type="hidden" name="id_hidden_original_file" id="id_hidden_original_file" value="'.Security::remove_XSS($_REQUEST['id']).'" />';
 $html.='<input  type="hidden" name="id_hidden_original_file" id="id_hidden_original_file" value="'.Security::remove_XSS($_REQUEST['id']).'" />';
+$html.='<input  type="hidden" name="id_hidden_sublanguage" id="id_hidden_sublanguage" value="'.Security::remove_XSS($_REQUEST['sub_language_id']).'" />';
 $html.='<select id="sl_original_file" name="original_file">';
 $html.='<select id="sl_original_file" name="original_file">';
 //$html.='<option value="0">'.get_lang('SelectAChoice').'</option>';
 //$html.='<option value="0">'.get_lang('SelectAChoice').'</option>';
 foreach ($load_array_in_select as $index_radios_results_enabled=>$value_radios_results_enabled) {
 foreach ($load_array_in_select as $index_radios_results_enabled=>$value_radios_results_enabled) {
@@ -171,7 +173,7 @@ $html.='</form>';
 $html.='</div>';
 $html.='</div>';
 
 
 $html.='<div style="float:left" class="actions">';
 $html.='<div style="float:left" class="actions">';
-$html.='<form style="float:left"  id="Searchlanguage" name="Searchlanguage" method="post" action="register_sub_language.php?id='.Security::remove_XSS($_GET['id']).'&original_file='.$request_file.'" >';
+$html.='<form style="float:left"  id="Searchlanguage" name="Searchlanguage" method="post" action="register_sub_language.php?id='.Security::remove_XSS($_GET['id']).'&sub_language_id='.Security::remove_XSS($_GET['sub_language_id']).'&original_file='.$request_file.'" >';
 $html.='&nbsp;'.get_lang('OriginalName').'&nbsp; :&nbsp;';
 $html.='&nbsp;'.get_lang('OriginalName').'&nbsp; :&nbsp;';
 $html.='<input name="txt_search_word" type="text" size="30"  id="txt_search_word" value="" />';
 $html.='<input name="txt_search_word" type="text" size="30"  id="txt_search_word" value="" />';
 $html.='<button name="SubmitSearchLanguage" class="search" type="submit">'.get_lang('Search').'</button>';
 $html.='<button name="SubmitSearchLanguage" class="search" type="submit">'.get_lang('Search').'</button>';
@@ -201,7 +203,8 @@ if (isset($_REQUEST['txt_search_word']) && strlen(trim($_REQUEST['txt_search_wor
 }
 }
 if($search_data===true) { 
 if($search_data===true) { 
 	$parent_id=Security::remove_XSS($_REQUEST['id']);
 	$parent_id=Security::remove_XSS($_REQUEST['id']);
-	$get_all_info_of_sub_language=AdminManager::get_all_information_of_sub_language ($parent_id);
+	$sub_language_id=Security::remove_XSS($_REQUEST['sub_language_id']);
+	$get_all_info_of_sub_language=AdminManager::get_all_information_of_sub_language ($parent_id,$sub_language_id);
 	$dokeos_path_file=api_get_path('SYS_LANG_PATH').$all_data_of_language['dokeos_folder'].'/'.$request_file;	
 	$dokeos_path_file=api_get_path('SYS_LANG_PATH').$all_data_of_language['dokeos_folder'].'/'.$request_file;	
 
 
 	$dokeos_english_path_file=api_get_path('SYS_LANG_PATH').'english/'.$request_file;
 	$dokeos_english_path_file=api_get_path('SYS_LANG_PATH').'english/'.$request_file;
@@ -265,7 +268,7 @@ if (isset($_REQUEST['txt_search_word']) && strlen(trim($_REQUEST['txt_search_wor
 	}
 	}
 }
 }
 }
 }
-$parameters=array('id'=>Security::remove_XSS($_GET['id']),'original_file'=>$request_file);
+$parameters=array('id'=>Security::remove_XSS($_GET['id']),'original_file'=>$request_file,'sub_language_id'=>Security::remove_XSS($_GET['sub_language_id']));
 if (isset($_REQUEST['txt_search_word']) && strlen($_REQUEST['txt_search_word'])>0) {
 if (isset($_REQUEST['txt_search_word']) && strlen($_REQUEST['txt_search_word'])>0) {
 	$parameters['txt_search_word']=Security::remove_XSS($_REQUEST['txt_search_word']);
 	$parameters['txt_search_word']=Security::remove_XSS($_REQUEST['txt_search_word']);
 }
 }

+ 4 - 3
main/auth/inscription.php

@@ -1,5 +1,5 @@
 <?php
 <?php
-// $Id: inscription.php 22368 2009-07-24 23:25:57Z iflorespaz $
+// $Id: inscription.php 22567 2009-08-02 23:10:29Z iflorespaz $
 /*
 /*
 ==============================================================================
 ==============================================================================
 	Dokeos - elearning and course management software
 	Dokeos - elearning and course management software
@@ -317,12 +317,13 @@ if (get_setting('allow_terms_conditions')=='true') {
 	
 	
 	// Version and language //password
 	// Version and language //password
 	$form->addElement('hidden', 'legal_accept_type',$term_preview['version'].':'.$term_preview['language_id']);
 	$form->addElement('hidden', 'legal_accept_type',$term_preview['version'].':'.$term_preview['language_id']);
+	$form->addElement('hidden', 'legal_info',$term_preview['legal_id'].':'.$term_preview['language_id']);	
 	if (isset($_SESSION['info_current_user'][1]) && isset($_SESSION['info_current_user'][2])) {
 	if (isset($_SESSION['info_current_user'][1]) && isset($_SESSION['info_current_user'][2])) {
 		$form->addElement('hidden', 'login',$_SESSION['info_current_user'][1]);
 		$form->addElement('hidden', 'login',$_SESSION['info_current_user'][1]);
-		$form->addElement('hidden', 'password',$_SESSION['info_current_user'][2]);		
+		$form->addElement('hidden', 'password',$_SESSION['info_current_user'][2]);	
 	}
 	}
 	if($term_preview['type'] == 1) {
 	if($term_preview['type'] == 1) {
-		$form->addElement('checkbox', 'legal_accept', null, get_lang('IhaveReadAndAgree').'&nbsp;<a href="inscription.php?legal" target="_blank">'.get_lang('TermsAndConditions').'</a>');		
+		$form->addElement('checkbox', 'legal_accept', null, get_lang('IHaveReadAndAgree').'&nbsp;<a href="inscription.php?legal" target="_blank">'.get_lang('TermsAndConditions').'</a>');		
 		$form->addRule('extra_legal_accept',  get_lang('ThisFieldIsRequired'), 'required');
 		$form->addRule('extra_legal_accept',  get_lang('ThisFieldIsRequired'), 'required');
 	} else {
 	} else {
 		if (!empty($term_preview['content'])) {			
 		if (!empty($term_preview['content'])) {			

+ 466 - 466
main/auth/openid/login.php

@@ -1,467 +1,467 @@
-<?php
-/**
- * OpenID login method
- * 
- * The OpenID login method relies on authentication servers providing a public
- * URL that can confirm the identity of a person, thus avoiding the spread
- * use of password transmissions over non-secure lines (for Dokeos, it is a
- * good way of avoiding password theft)
- */
-/**
- * Initialisation
- */
-require_once('openid.conf.php');
-require_once('openid.lib.php');
-require_once('xrds.lib.php');
-
-function openid_form() 
-{
-	return '<div class="menusection"><span class="menusectioncaption">'.get_lang('OpenIdAuthentication').'</span><form name="openid_login" method="post"><label for="openid_url">'.get_lang('OpenIDURL').' <a href="main/auth/openid/whatis.php" title="'.get_lang('OpenIDWhatIs').'">'.Display::return_icon('info3.gif').'</a></label><input type="text" id="openid_url" name="openid_url" style="background: url(main/img/openid_small_logo.png) no-repeat; background-color: #fff; background-position: 0 50%; padding-left:18px;" value="http://"></input><input type="submit" name="openid_login" value="'.get_lang('Ok').'" /><br /><br /></form></div>';
-}
-
-/**
- * The initial step of OpenID authentication responsible for the following:
- *  - Perform discovery on the claimed OpenID.
- *  - If possible, create an association with the Provider's endpoint.
- *  - Create the authentication request.
- *  - Perform the appropriate redirect.
- *
- * @param $claimed_id The OpenID to authenticate
- * @param $return_to The endpoint to return to from the OpenID Provider
- */
-function openid_begin($claimed_id, $return_to = '', $form_values = array()) 
-{
-
-  $claimed_id = _openid_normalize($claimed_id);
-
-  $services = openid_discovery($claimed_id);
-  if (count($services) == 0) {
-    echo 'Sorry, that is not a valid OpenID. Please ensure you have spelled your ID correctly.';
-    return;
-  }
-
-  $op_endpoint = $services[0]['uri'];
-  // Store the discovered endpoint in the session (so we don't have to rediscover).
-  $_SESSION['openid_op_endpoint'] = $op_endpoint;
-  // Store the claimed_id in the session (for handling delegation).
-  $_SESSION['openid_claimed_id'] = $claimed_id;
-  // Store the login form values so we can pass them to
-  // user_exteral_login later.
-  $_SESSION['openid_user_login_values'] = $form_values;
-
-  // If bcmath is present, then create an association
-  $assoc_handle = '';
-  if (function_exists('bcadd')) {
-    $assoc_handle = openid_association($op_endpoint);
-  }
-
-  // Now that there is an association created, move on
-  // to request authentication from the IdP
-  $identity = (!empty($services[0]['delegate'])) ? $services[0]['delegate'] : $claimed_id;
-  if (isset($services[0]['types']) && is_array($services[0]['types']) && in_array(OPENID_NS_2_0 .'/server', $services[0]['types'])) {
-    $identity = 'http://openid.net/identifier_select/2.0';
-  }
-  $authn_request = openid_authentication_request($claimed_id, $identity, $return_to, $assoc_handle, $services[0]['version']);
-
-  if ($services[0]['version'] == 2) {
-    openid_redirect($op_endpoint, $authn_request);
-  }
-  else {
-    openid_redirect_http($op_endpoint, $authn_request);
-  }
-}
-
-/**
- * Completes OpenID authentication by validating returned data from the OpenID
- * Provider.
- *
- * @param $response Array of returned from the OpenID provider (typically $_REQUEST).
- *
- * @return $response Response values for further processing with
- *   $response['status'] set to one of 'success', 'failed' or 'cancel'.
- */
-function openid_complete($response) 
-{
-  // Default to failed response
-  $response['status'] = 'failed';
-  if (isset($_SESSION['openid_op_endpoint']) && isset($_SESSION['openid_claimed_id'])) {
-    _openid_fix_post($response);
-    $op_endpoint = $_SESSION['openid_op_endpoint'];
-    $claimed_id = $_SESSION['openid_claimed_id'];
-    unset($_SESSION['openid_op_endpoint']);
-    unset($_SESSION['openid_claimed_id']);
-    if (isset($response['openid.mode'])) {
-      if ($response['openid.mode'] == 'cancel') {
-        $response['status'] = 'cancel';
-      }
-      else {
-        if (openid_verify_assertion($op_endpoint, $response)) {
-          $response['openid.identity'] = $claimed_id;
-          $response['status'] = 'success';
-        }
-      }
-    }
-  }
-  return $response;
-}
-
-/**
- * Perform discovery on a claimed ID to determine the OpenID provider endpoint.
- *
- * @param $claimed_id The OpenID URL to perform discovery on.
- *
- * @return Array of services discovered (including OpenID version, endpoint
- * URI, etc).
- */
-function openid_discovery($claimed_id) {
-
-  $services = array();
-
-  $xrds_url = $claimed_id;
-  if (_openid_is_xri($claimed_id)) {
-    $xrds_url = 'http://xri.net/'. $claimed_id;
-  }
-  $url = @parse_url($xrds_url);
-  if ($url['scheme'] == 'http' || $url['scheme'] == 'https') {
-    // For regular URLs, try Yadis resolution first, then HTML-based discovery
-    $headers = array('Accept' => 'application/xrds+xml');
-    //TODO
-    $result = openid_http_request($xrds_url, $headers);
-
-    if (!isset($result->error)) {
-      if (isset($result->headers['Content-Type']) && preg_match("/application\/xrds\+xml/", $result->headers['Content-Type'])) {
-        // Parse XML document to find URL
-        $services = xrds_parse($result->data);
-      }
-      else {
-        $xrds_url = NULL;
-        if (isset($result->headers['X-XRDS-Location'])) {
-          $xrds_url = $result->headers['X-XRDS-Location'];
-        }
-        else {
-          // Look for meta http-equiv link in HTML head
-          $xrds_url = _openid_meta_httpequiv('X-XRDS-Location', $result->data);
-        }
-        if (!empty($xrds_url)) {
-          $headers = array('Accept' => 'application/xrds+xml');
-          //TODO
-          $xrds_result = openid_http_request($xrds_url, $headers);
-          if (!isset($xrds_result->error)) {
-            $services = xrds_parse($xrds_result->data);
-          }
-        }
-      }
-
-      // Check for HTML delegation
-      if (count($services) == 0) {
-        // Look for 2.0 links
-        $uri = _openid_link_href('openid2.provider', $result->data);
-        $delegate = _openid_link_href('openid2.local_id', $result->data);
-        $version = 2;
-
-        // 1.0 links
-        if (empty($uri)) {
-          $uri = _openid_link_href('openid.server', $result->data);
-          $delegate = _openid_link_href('openid.delegate', $result->data);
-          $version = 1;
-        }
-        if (!empty($uri)) {
-          $services[] = array('uri' => $uri, 'delegate' => $delegate, 'version' => $version);
-        }
-      }
-    }
-  }
-  return $services;
-}
-
-/**
- * Attempt to create a shared secret with the OpenID Provider.
- *
- * @param $op_endpoint URL of the OpenID Provider endpoint.
- *
- * @return $assoc_handle The association handle.
- */
-function openid_association($op_endpoint) {
-
-  // Remove Old Associations:
-  //TODO
-  $openid_association = Database::get_main_table(TABLE_MAIN_OPENID_ASSOCIATION);
-  api_sql_query("DELETE FROM $openid_association WHERE created + expires_in < %d", time());
-
-  // Check to see if we have an association for this IdP already
-  $assoc_handle = api_sql_query("SELECT assoc_handle FROM $openid_association WHERE idp_endpoint_uri = '%s'", $op_endpoint);
-  if (Database::num_rows($assoc_handle)<=1) {
-    $mod = OPENID_DH_DEFAULT_MOD;
-    $gen = OPENID_DH_DEFAULT_GEN;
-    $r = _openid_dh_rand($mod);
-    $private = bcadd($r, 1);
-    $public = bcpowmod($gen, $private, $mod);
-
-    // If there is no existing association, then request one
-    $assoc_request = openid_association_request($public);
-    $assoc_message = _openid_encode_message(_openid_create_message($assoc_request));
-    $assoc_headers = array('Content-Type' => 'application/x-www-form-urlencoded; charset=utf-8');
-    //TODO
-    $assoc_result = openid_http_request($op_endpoint, $assoc_headers, 'POST', $assoc_message);
-    if (isset($assoc_result->error)) {
-      return FALSE;
-    }
-
-    $assoc_response = _openid_parse_message($assoc_result->data);
-    if (isset($assoc_response['mode']) && $assoc_response['mode'] == 'error') {
-        return FALSE;
-    }
-
-    if ($assoc_response['session_type'] == 'DH-SHA1') {
-      $spub = _openid_dh_base64_to_long($assoc_response['dh_server_public']);
-      $enc_mac_key = base64_decode($assoc_response['enc_mac_key']);
-      $shared = bcpowmod($spub, $private, $mod);
-      $assoc_response['mac_key'] = base64_encode(_openid_dh_xorsecret($shared, $enc_mac_key));
-    }
-    //TODO
-   	$openid_association = Database::get_main_table(TABLE_MAIN_OPENID_ASSOCIATION);
-    api_sql_query(sprintf("INSERT INTO $openid_association (idp_endpoint_uri, session_type, assoc_handle, assoc_type, expires_in, mac_key, created) VALUES('%s', '%s', '%s', '%s', %d, '%s', %d)",
-             $op_endpoint, $assoc_response['session_type'], $assoc_response['assoc_handle'], $assoc_response['assoc_type'], $assoc_response['expires_in'], $assoc_response['mac_key'], time()));
-
-    $assoc_handle = $assoc_response['assoc_handle'];
-  }
-
-  return $assoc_handle;
-}
-
-/**
- * ?
- */
-function openid_association_request($public) {
-  require_once(api_get_path(SYS_CODE_PATH).'auth/openid/openid.conf.php');
-
-  $request = array(
-    'openid.ns' => OPENID_NS_2_0,
-    'openid.mode' => 'associate',
-    'openid.session_type' => 'DH-SHA1',
-    'openid.assoc_type' => 'HMAC-SHA1'
-  );
-
-  if ($request['openid.session_type'] == 'DH-SHA1' || $request['openid.session_type'] == 'DH-SHA256') {
-    $cpub = _openid_dh_long_to_base64($public);
-    $request['openid.dh_consumer_public'] = $cpub;
-  }
-
-  return $request;
-}
-
-/**
- * 
- */
-function openid_authentication_request($claimed_id, $identity, $return_to = '', $assoc_handle = '', $version = 2) {
-
-  $realm = ($return_to) ? $return_to : api_get_self();
-
-  $ns = ($version == 2) ? OPENID_NS_2_0 : OPENID_NS_1_0;
-  $request =  array(
-    'openid.ns' => $ns,
-    'openid.mode' => 'checkid_setup',
-    'openid.identity' => $identity,
-    'openid.claimed_id' => $claimed_id,
-    'openid.assoc_handle' => $assoc_handle,
-    'openid.return_to' => $return_to,
-  );
-
-  if ($version == 2) {
-    $request['openid.realm'] = $realm;
-  }
-  else {
-    $request['openid.trust_root'] = $realm;
-  }
-
-  // Simple Registration - we don't ask lastname and firstname because the only
-  // available similar data is "fullname" and we would have to guess where to split 
-  $request['openid.sreg.required'] = 'nickname,email';
-  $request['openid.ns.sreg'] = "http://openid.net/extensions/sreg/1.1";
-
-  //$request = array_merge($request, module_invoke_all('openid', 'request', $request));
-  //$request = array_merge($request);
-
-  return $request;
-}
-
-/**
- * Attempt to verify the response received from the OpenID Provider.
- *
- * @param $op_endpoint The OpenID Provider URL.
- * @param $response Array of repsonse values from the provider.
- *
- * @return boolean
- */
-function openid_verify_assertion($op_endpoint, $response) {
-
-  $valid = FALSE;
-
-	//TODO
-  $openid_association = Database::get_main_table(TABLE_MAIN_OPENID_ASSOCIATION);
-  $sql = sprintf("SELECT * FROM $openid_association WHERE assoc_handle = '%s'", $response['openid.assoc_handle']);
-  $res = api_sql_query($sql);
-  $association = Database::fetch_object($res);
-  if ($association && isset($association->session_type)) {
-    $keys_to_sign = explode(',', $response['openid.signed']);
-    $self_sig = _openid_signature($association, $response, $keys_to_sign);
-    if ($self_sig == $response['openid.sig']) {
-      $valid = TRUE;
-    }
-    else {
-      $valid = FALSE;
-    }
-  }
-  else {
-    $request = $response;
-    $request['openid.mode'] = 'check_authentication';
-    $message = _openid_create_message($request);
-    $headers = array('Content-Type' => 'application/x-www-form-urlencoded; charset=utf-8');
-    $result = openid_http_request($op_endpoint, $headers, 'POST', _openid_encode_message($message));
-    if (!isset($result->error)) {
-      $response = _openid_parse_message($result->data);
-      if (strtolower(trim($response['is_valid'])) == 'true') {
-        $valid = TRUE;
-      }
-      else {
-        $valid = FALSE;
-      }
-    }
-  }
-
-  return $valid;
-}
-
-/**
- * Make a HTTP request - This function has been copied straight over from Drupal 6 code (drupal_http_request)
- */
-function openid_http_request($url, $headers = array(), $method = 'GET', $data = NULL, $retry = 3) {
-  $result = new stdClass();
-
-  // Parse the URL and make sure we can handle the schema.
-  $uri = parse_url($url);
-
-  switch ($uri['scheme']) {
-    case 'http':
-      $port = isset($uri['port']) ? $uri['port'] : 80;
-      $host = $uri['host'] . ($port != 80 ? ':'. $port : '');
-      $fp = @fsockopen($uri['host'], $port, $errno, $errstr, 15);
-      break;
-    case 'https':
-      // Note: Only works for PHP 4.3 compiled with OpenSSL.
-      $port = isset($uri['port']) ? $uri['port'] : 443;
-      $host = $uri['host'] . ($port != 443 ? ':'. $port : '');
-      $fp = @fsockopen('ssl://'. $uri['host'], $port, $errno, $errstr, 20);
-      break;
-    default:
-      $result->error = 'invalid schema '. $uri['scheme'];
-      return $result;
-  }
-
-  // Make sure the socket opened properly.
-  if (!$fp) {
-    // When a network error occurs, we make sure that it is a negative number so
-    // it can clash with the HTTP status codes.
-    $result->code = -$errno;
-    $result->error = trim($errstr);
-    return $result;
-  }
-
-  // Construct the path to act on.
-  $path = isset($uri['path']) ? $uri['path'] : '/';
-  if (isset($uri['query'])) {
-    $path .= '?'. $uri['query'];
-  }
-
-  // Create HTTP request.
-  $defaults = array(
-    // RFC 2616: "non-standard ports MUST, default ports MAY be included".
-    // We don't add the port to prevent from breaking rewrite rules checking the
-    // host that do not take into account the port number.
-    'Host' => "Host: $host",
-    'User-Agent' => 'User-Agent: Dokeos (+http://dokeos.com/)',
-    'Content-Length' => 'Content-Length: '. strlen($data)
-  );
-
-  // If the server url has a user then attempt to use basic authentication
-  if (isset($uri['user'])) {
-    $defaults['Authorization'] = 'Authorization: Basic '. base64_encode($uri['user'] . (!empty($uri['pass']) ? ":". $uri['pass'] : ''));
-  }
-
-  foreach ($headers as $header => $value) {
-    $defaults[$header] = $header .': '. $value;
-  }
-
-  $request = $method .' '. $path ." HTTP/1.0\r\n";
-  $request .= implode("\r\n", $defaults);
-  $request .= "\r\n\r\n";
-  if ($data) {
-    $request .= $data ."\r\n";
-  }
-  $result->request = $request;
-
-  fwrite($fp, $request);
-
-  // Fetch response.
-  $response = '';
-  while (!feof($fp) && $chunk = fread($fp, 1024)) {
-    $response .= $chunk;
-  }
-  fclose($fp);
-
-  // Parse response.
-  list($split, $result->data) = explode("\r\n\r\n", $response, 2);
-  $split = preg_split("/\r\n|\n|\r/", $split);
-
-  list($protocol, $code, $text) = explode(' ', trim(array_shift($split)), 3);
-  $result->headers = array();
-
-  // Parse headers.
-  while ($line = trim(array_shift($split))) {
-    list($header, $value) = explode(':', $line, 2);
-    if (isset($result->headers[$header]) && $header == 'Set-Cookie') {
-      // RFC 2109: the Set-Cookie response header comprises the token Set-
-      // Cookie:, followed by a comma-separated list of one or more cookies.
-      $result->headers[$header] .= ','. trim($value);
-    }
-    else {
-      $result->headers[$header] = trim($value);
-    }
-  }
-
-  $responses = array(
-    100 => 'Continue', 101 => 'Switching Protocols',
-    200 => 'OK', 201 => 'Created', 202 => 'Accepted', 203 => 'Non-Authoritative Information', 204 => 'No Content', 205 => 'Reset Content', 206 => 'Partial Content',
-    300 => 'Multiple Choices', 301 => 'Moved Permanently', 302 => 'Found', 303 => 'See Other', 304 => 'Not Modified', 305 => 'Use Proxy', 307 => 'Temporary Redirect',
-    400 => 'Bad Request', 401 => 'Unauthorized', 402 => 'Payment Required', 403 => 'Forbidden', 404 => 'Not Found', 405 => 'Method Not Allowed', 406 => 'Not Acceptable', 407 => 'Proxy Authentication Required', 408 => 'Request Time-out', 409 => 'Conflict', 410 => 'Gone', 411 => 'Length Required', 412 => 'Precondition Failed', 413 => 'Request Entity Too Large', 414 => 'Request-URI Too Large', 415 => 'Unsupported Media Type', 416 => 'Requested range not satisfiable', 417 => 'Expectation Failed',
-    500 => 'Internal Server Error', 501 => 'Not Implemented', 502 => 'Bad Gateway', 503 => 'Service Unavailable', 504 => 'Gateway Time-out', 505 => 'HTTP Version not supported'
-  );
-  // RFC 2616 states that all unknown HTTP codes must be treated the same as the
-  // base code in their class.
-  if (!isset($responses[$code])) {
-    $code = floor($code / 100) * 100;
-  }
-
-  switch ($code) {
-    case 200: // OK
-    case 304: // Not modified
-      break;
-    case 301: // Moved permanently
-    case 302: // Moved temporarily
-    case 307: // Moved temporarily
-      $location = $result->headers['Location'];
-
-      if ($retry) {
-        $result = openid_http_request($result->headers['Location'], $headers, $method, $data, --$retry);
-        $result->redirect_code = $result->code;
-      }
-      $result->redirect_url = $location;
-
-      break;
-    default:
-      $result->error = $text;
-  }
-
-  $result->code = $code;
-  return $result;
+<?php
+/**
+ * OpenID login method
+ * 
+ * The OpenID login method relies on authentication servers providing a public
+ * URL that can confirm the identity of a person, thus avoiding the spread
+ * use of password transmissions over non-secure lines (for Dokeos, it is a
+ * good way of avoiding password theft)
+ */
+/**
+ * Initialisation
+ */
+require_once 'openid.conf.php';
+require_once 'openid.lib.php';
+require_once 'xrds.lib.php';
+
+function openid_form() 
+{
+	return '<div class="menusection"><span class="menusectioncaption">'.get_lang('OpenIdAuthentication').'</span><form name="openid_login" method="post"><label for="openid_url">'.get_lang('OpenIDURL').' <a href="main/auth/openid/whatis.php" title="'.get_lang('OpenIDWhatIs').'">'.Display::return_icon('info3.gif',get_lang('Info')).'</a></label><input type="text" id="openid_url" name="openid_url" style="background: url(main/img/openid_small_logo.png) no-repeat; background-color: #fff; background-position: 0 50%; padding-left:18px;" value="http://"></input><input type="submit" name="openid_login" value="'.get_lang('Enter').'" /><br /><br /></form></div>';
+}
+
+/**
+ * The initial step of OpenID authentication responsible for the following:
+ *  - Perform discovery on the claimed OpenID.
+ *  - If possible, create an association with the Provider's endpoint.
+ *  - Create the authentication request.
+ *  - Perform the appropriate redirect.
+ *
+ * @param $claimed_id The OpenID to authenticate
+ * @param $return_to The endpoint to return to from the OpenID Provider
+ */
+function openid_begin($claimed_id, $return_to = '', $form_values = array()) 
+{
+
+  $claimed_id = _openid_normalize($claimed_id);
+
+  $services = openid_discovery($claimed_id);
+  if (count($services) == 0) {
+    echo 'Sorry, that is not a valid OpenID. Please ensure you have spelled your ID correctly.';
+    return;
+  }
+
+  $op_endpoint = $services[0]['uri'];
+  // Store the discovered endpoint in the session (so we don't have to rediscover).
+  $_SESSION['openid_op_endpoint'] = $op_endpoint;
+  // Store the claimed_id in the session (for handling delegation).
+  $_SESSION['openid_claimed_id'] = $claimed_id;
+  // Store the login form values so we can pass them to
+  // user_exteral_login later.
+  $_SESSION['openid_user_login_values'] = $form_values;
+
+  // If bcmath is present, then create an association
+  $assoc_handle = '';
+  if (function_exists('bcadd')) {
+    $assoc_handle = openid_association($op_endpoint);
+  }
+
+  // Now that there is an association created, move on
+  // to request authentication from the IdP
+  $identity = (!empty($services[0]['delegate'])) ? $services[0]['delegate'] : $claimed_id;
+  if (isset($services[0]['types']) && is_array($services[0]['types']) && in_array(OPENID_NS_2_0 .'/server', $services[0]['types'])) {
+    $identity = 'http://openid.net/identifier_select/2.0';
+  }
+  $authn_request = openid_authentication_request($claimed_id, $identity, $return_to, $assoc_handle, $services[0]['version']);
+
+  if ($services[0]['version'] == 2) {
+    openid_redirect($op_endpoint, $authn_request);
+  }
+  else {
+    openid_redirect_http($op_endpoint, $authn_request);
+  }
+}
+
+/**
+ * Completes OpenID authentication by validating returned data from the OpenID
+ * Provider.
+ *
+ * @param $response Array of returned from the OpenID provider (typically $_REQUEST).
+ *
+ * @return $response Response values for further processing with
+ *   $response['status'] set to one of 'success', 'failed' or 'cancel'.
+ */
+function openid_complete($response) 
+{
+  // Default to failed response
+  $response['status'] = 'failed';
+  if (isset($_SESSION['openid_op_endpoint']) && isset($_SESSION['openid_claimed_id'])) {
+    _openid_fix_post($response);
+    $op_endpoint = $_SESSION['openid_op_endpoint'];
+    $claimed_id = $_SESSION['openid_claimed_id'];
+    unset($_SESSION['openid_op_endpoint']);
+    unset($_SESSION['openid_claimed_id']);
+    if (isset($response['openid.mode'])) {
+      if ($response['openid.mode'] == 'cancel') {
+        $response['status'] = 'cancel';
+      }
+      else {
+        if (openid_verify_assertion($op_endpoint, $response)) {
+          $response['openid.identity'] = $claimed_id;
+          $response['status'] = 'success';
+        }
+      }
+    }
+  }
+  return $response;
+}
+
+/**
+ * Perform discovery on a claimed ID to determine the OpenID provider endpoint.
+ *
+ * @param $claimed_id The OpenID URL to perform discovery on.
+ *
+ * @return Array of services discovered (including OpenID version, endpoint
+ * URI, etc).
+ */
+function openid_discovery($claimed_id) {
+
+  $services = array();
+
+  $xrds_url = $claimed_id;
+  if (_openid_is_xri($claimed_id)) {
+    $xrds_url = 'http://xri.net/'. $claimed_id;
+  }
+  $url = @parse_url($xrds_url);
+  if ($url['scheme'] == 'http' || $url['scheme'] == 'https') {
+    // For regular URLs, try Yadis resolution first, then HTML-based discovery
+    $headers = array('Accept' => 'application/xrds+xml');
+    //TODO
+    $result = openid_http_request($xrds_url, $headers);
+
+    if (!isset($result->error)) {
+      if (isset($result->headers['Content-Type']) && preg_match("/application\/xrds\+xml/", $result->headers['Content-Type'])) {
+        // Parse XML document to find URL
+        $services = xrds_parse($result->data);
+      }
+      else {
+        $xrds_url = NULL;
+        if (isset($result->headers['X-XRDS-Location'])) {
+          $xrds_url = $result->headers['X-XRDS-Location'];
+        }
+        else {
+          // Look for meta http-equiv link in HTML head
+          $xrds_url = _openid_meta_httpequiv('X-XRDS-Location', $result->data);
+        }
+        if (!empty($xrds_url)) {
+          $headers = array('Accept' => 'application/xrds+xml');
+          //TODO
+          $xrds_result = openid_http_request($xrds_url, $headers);
+          if (!isset($xrds_result->error)) {
+            $services = xrds_parse($xrds_result->data);
+          }
+        }
+      }
+
+      // Check for HTML delegation
+      if (count($services) == 0) {
+        // Look for 2.0 links
+        $uri = _openid_link_href('openid2.provider', $result->data);
+        $delegate = _openid_link_href('openid2.local_id', $result->data);
+        $version = 2;
+
+        // 1.0 links
+        if (empty($uri)) {
+          $uri = _openid_link_href('openid.server', $result->data);
+          $delegate = _openid_link_href('openid.delegate', $result->data);
+          $version = 1;
+        }
+        if (!empty($uri)) {
+          $services[] = array('uri' => $uri, 'delegate' => $delegate, 'version' => $version);
+        }
+      }
+    }
+  }
+  return $services;
+}
+
+/**
+ * Attempt to create a shared secret with the OpenID Provider.
+ *
+ * @param $op_endpoint URL of the OpenID Provider endpoint.
+ *
+ * @return $assoc_handle The association handle.
+ */
+function openid_association($op_endpoint) {
+
+  // Remove Old Associations:
+  //TODO
+  $openid_association = Database::get_main_table(TABLE_MAIN_OPENID_ASSOCIATION);
+  api_sql_query("DELETE FROM $openid_association WHERE created + expires_in < %d", time());
+
+  // Check to see if we have an association for this IdP already
+  $assoc_handle = api_sql_query("SELECT assoc_handle FROM $openid_association WHERE idp_endpoint_uri = '%s'", $op_endpoint);
+  if (Database::num_rows($assoc_handle)<=1) {
+    $mod = OPENID_DH_DEFAULT_MOD;
+    $gen = OPENID_DH_DEFAULT_GEN;
+    $r = _openid_dh_rand($mod);
+    $private = bcadd($r, 1);
+    $public = bcpowmod($gen, $private, $mod);
+
+    // If there is no existing association, then request one
+    $assoc_request = openid_association_request($public);
+    $assoc_message = _openid_encode_message(_openid_create_message($assoc_request));
+    $assoc_headers = array('Content-Type' => 'application/x-www-form-urlencoded; charset=utf-8');
+    //TODO
+    $assoc_result = openid_http_request($op_endpoint, $assoc_headers, 'POST', $assoc_message);
+    if (isset($assoc_result->error)) {
+      return FALSE;
+    }
+
+    $assoc_response = _openid_parse_message($assoc_result->data);
+    if (isset($assoc_response['mode']) && $assoc_response['mode'] == 'error') {
+        return FALSE;
+    }
+
+    if ($assoc_response['session_type'] == 'DH-SHA1') {
+      $spub = _openid_dh_base64_to_long($assoc_response['dh_server_public']);
+      $enc_mac_key = base64_decode($assoc_response['enc_mac_key']);
+      $shared = bcpowmod($spub, $private, $mod);
+      $assoc_response['mac_key'] = base64_encode(_openid_dh_xorsecret($shared, $enc_mac_key));
+    }
+    //TODO
+   	$openid_association = Database::get_main_table(TABLE_MAIN_OPENID_ASSOCIATION);
+    api_sql_query(sprintf("INSERT INTO $openid_association (idp_endpoint_uri, session_type, assoc_handle, assoc_type, expires_in, mac_key, created) VALUES('%s', '%s', '%s', '%s', %d, '%s', %d)",
+             $op_endpoint, $assoc_response['session_type'], $assoc_response['assoc_handle'], $assoc_response['assoc_type'], $assoc_response['expires_in'], $assoc_response['mac_key'], time()));
+
+    $assoc_handle = $assoc_response['assoc_handle'];
+  }
+
+  return $assoc_handle;
+}
+
+/**
+ * ?
+ */
+function openid_association_request($public) {
+  require_once(api_get_path(SYS_CODE_PATH).'auth/openid/openid.conf.php');
+
+  $request = array(
+    'openid.ns' => OPENID_NS_2_0,
+    'openid.mode' => 'associate',
+    'openid.session_type' => 'DH-SHA1',
+    'openid.assoc_type' => 'HMAC-SHA1'
+  );
+
+  if ($request['openid.session_type'] == 'DH-SHA1' || $request['openid.session_type'] == 'DH-SHA256') {
+    $cpub = _openid_dh_long_to_base64($public);
+    $request['openid.dh_consumer_public'] = $cpub;
+  }
+
+  return $request;
+}
+
+/**
+ * 
+ */
+function openid_authentication_request($claimed_id, $identity, $return_to = '', $assoc_handle = '', $version = 2) {
+
+  $realm = ($return_to) ? $return_to : api_get_self();
+
+  $ns = ($version == 2) ? OPENID_NS_2_0 : OPENID_NS_1_0;
+  $request =  array(
+    'openid.ns' => $ns,
+    'openid.mode' => 'checkid_setup',
+    'openid.identity' => $identity,
+    'openid.claimed_id' => $claimed_id,
+    'openid.assoc_handle' => $assoc_handle,
+    'openid.return_to' => $return_to,
+  );
+
+  if ($version == 2) {
+    $request['openid.realm'] = $realm;
+  }
+  else {
+    $request['openid.trust_root'] = $realm;
+  }
+
+  // Simple Registration - we don't ask lastname and firstname because the only
+  // available similar data is "fullname" and we would have to guess where to split 
+  $request['openid.sreg.required'] = 'nickname,email';
+  $request['openid.ns.sreg'] = "http://openid.net/extensions/sreg/1.1";
+
+  //$request = array_merge($request, module_invoke_all('openid', 'request', $request));
+  //$request = array_merge($request);
+
+  return $request;
+}
+
+/**
+ * Attempt to verify the response received from the OpenID Provider.
+ *
+ * @param $op_endpoint The OpenID Provider URL.
+ * @param $response Array of repsonse values from the provider.
+ *
+ * @return boolean
+ */
+function openid_verify_assertion($op_endpoint, $response) {
+
+  $valid = FALSE;
+
+	//TODO
+  $openid_association = Database::get_main_table(TABLE_MAIN_OPENID_ASSOCIATION);
+  $sql = sprintf("SELECT * FROM $openid_association WHERE assoc_handle = '%s'", $response['openid.assoc_handle']);
+  $res = api_sql_query($sql);
+  $association = Database::fetch_object($res);
+  if ($association && isset($association->session_type)) {
+    $keys_to_sign = explode(',', $response['openid.signed']);
+    $self_sig = _openid_signature($association, $response, $keys_to_sign);
+    if ($self_sig == $response['openid.sig']) {
+      $valid = TRUE;
+    }
+    else {
+      $valid = FALSE;
+    }
+  }
+  else {
+    $request = $response;
+    $request['openid.mode'] = 'check_authentication';
+    $message = _openid_create_message($request);
+    $headers = array('Content-Type' => 'application/x-www-form-urlencoded; charset=utf-8');
+    $result = openid_http_request($op_endpoint, $headers, 'POST', _openid_encode_message($message));
+    if (!isset($result->error)) {
+      $response = _openid_parse_message($result->data);
+      if (strtolower(trim($response['is_valid'])) == 'true') {
+        $valid = TRUE;
+      }
+      else {
+        $valid = FALSE;
+      }
+    }
+  }
+
+  return $valid;
+}
+
+/**
+ * Make a HTTP request - This function has been copied straight over from Drupal 6 code (drupal_http_request)
+ */
+function openid_http_request($url, $headers = array(), $method = 'GET', $data = NULL, $retry = 3) {
+  $result = new stdClass();
+
+  // Parse the URL and make sure we can handle the schema.
+  $uri = parse_url($url);
+
+  switch ($uri['scheme']) {
+    case 'http':
+      $port = isset($uri['port']) ? $uri['port'] : 80;
+      $host = $uri['host'] . ($port != 80 ? ':'. $port : '');
+      $fp = @fsockopen($uri['host'], $port, $errno, $errstr, 15);
+      break;
+    case 'https':
+      // Note: Only works for PHP 4.3 compiled with OpenSSL.
+      $port = isset($uri['port']) ? $uri['port'] : 443;
+      $host = $uri['host'] . ($port != 443 ? ':'. $port : '');
+      $fp = @fsockopen('ssl://'. $uri['host'], $port, $errno, $errstr, 20);
+      break;
+    default:
+      $result->error = 'invalid schema '. $uri['scheme'];
+      return $result;
+  }
+
+  // Make sure the socket opened properly.
+  if (!$fp) {
+    // When a network error occurs, we make sure that it is a negative number so
+    // it can clash with the HTTP status codes.
+    $result->code = -$errno;
+    $result->error = trim($errstr);
+    return $result;
+  }
+
+  // Construct the path to act on.
+  $path = isset($uri['path']) ? $uri['path'] : '/';
+  if (isset($uri['query'])) {
+    $path .= '?'. $uri['query'];
+  }
+
+  // Create HTTP request.
+  $defaults = array(
+    // RFC 2616: "non-standard ports MUST, default ports MAY be included".
+    // We don't add the port to prevent from breaking rewrite rules checking the
+    // host that do not take into account the port number.
+    'Host' => "Host: $host",
+    'User-Agent' => 'User-Agent: Dokeos (+http://dokeos.com/)',
+    'Content-Length' => 'Content-Length: '. strlen($data)
+  );
+
+  // If the server url has a user then attempt to use basic authentication
+  if (isset($uri['user'])) {
+    $defaults['Authorization'] = 'Authorization: Basic '. base64_encode($uri['user'] . (!empty($uri['pass']) ? ":". $uri['pass'] : ''));
+  }
+
+  foreach ($headers as $header => $value) {
+    $defaults[$header] = $header .': '. $value;
+  }
+
+  $request = $method .' '. $path ." HTTP/1.0\r\n";
+  $request .= implode("\r\n", $defaults);
+  $request .= "\r\n\r\n";
+  if ($data) {
+    $request .= $data ."\r\n";
+  }
+  $result->request = $request;
+
+  fwrite($fp, $request);
+
+  // Fetch response.
+  $response = '';
+  while (!feof($fp) && $chunk = fread($fp, 1024)) {
+    $response .= $chunk;
+  }
+  fclose($fp);
+
+  // Parse response.
+  list($split, $result->data) = explode("\r\n\r\n", $response, 2);
+  $split = preg_split("/\r\n|\n|\r/", $split);
+
+  list($protocol, $code, $text) = explode(' ', trim(array_shift($split)), 3);
+  $result->headers = array();
+
+  // Parse headers.
+  while ($line = trim(array_shift($split))) {
+    list($header, $value) = explode(':', $line, 2);
+    if (isset($result->headers[$header]) && $header == 'Set-Cookie') {
+      // RFC 2109: the Set-Cookie response header comprises the token Set-
+      // Cookie:, followed by a comma-separated list of one or more cookies.
+      $result->headers[$header] .= ','. trim($value);
+    }
+    else {
+      $result->headers[$header] = trim($value);
+    }
+  }
+
+  $responses = array(
+    100 => 'Continue', 101 => 'Switching Protocols',
+    200 => 'OK', 201 => 'Created', 202 => 'Accepted', 203 => 'Non-Authoritative Information', 204 => 'No Content', 205 => 'Reset Content', 206 => 'Partial Content',
+    300 => 'Multiple Choices', 301 => 'Moved Permanently', 302 => 'Found', 303 => 'See Other', 304 => 'Not Modified', 305 => 'Use Proxy', 307 => 'Temporary Redirect',
+    400 => 'Bad Request', 401 => 'Unauthorized', 402 => 'Payment Required', 403 => 'Forbidden', 404 => 'Not Found', 405 => 'Method Not Allowed', 406 => 'Not Acceptable', 407 => 'Proxy Authentication Required', 408 => 'Request Time-out', 409 => 'Conflict', 410 => 'Gone', 411 => 'Length Required', 412 => 'Precondition Failed', 413 => 'Request Entity Too Large', 414 => 'Request-URI Too Large', 415 => 'Unsupported Media Type', 416 => 'Requested range not satisfiable', 417 => 'Expectation Failed',
+    500 => 'Internal Server Error', 501 => 'Not Implemented', 502 => 'Bad Gateway', 503 => 'Service Unavailable', 504 => 'Gateway Time-out', 505 => 'HTTP Version not supported'
+  );
+  // RFC 2616 states that all unknown HTTP codes must be treated the same as the
+  // base code in their class.
+  if (!isset($responses[$code])) {
+    $code = floor($code / 100) * 100;
+  }
+
+  switch ($code) {
+    case 200: // OK
+    case 304: // Not modified
+      break;
+    case 301: // Moved permanently
+    case 302: // Moved temporarily
+    case 307: // Moved temporarily
+      $location = $result->headers['Location'];
+
+      if ($retry) {
+        $result = openid_http_request($result->headers['Location'], $headers, $method, $data, --$retry);
+        $result->redirect_code = $result->code;
+      }
+      $result->redirect_url = $location;
+
+      break;
+    default:
+      $result->error = $text;
+  }
+
+  $result->code = $code;
+  return $result;
 }
 }

+ 6 - 30
main/coursecopy/classes/CourseBuilder.class.php

@@ -1,27 +1,5 @@
-<?php // $Id: CourseBuilder.class.php 22200 2009-07-17 19:47:58Z iflorespaz $
-/*
-==============================================================================
-	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
-==============================================================================
-*/
+<?php
+/* For licensing terms, see /dokeos_license.txt */
 require_once ('Course.class.php');
 require_once ('Course.class.php');
 require_once ('Event.class.php');
 require_once ('Event.class.php');
 require_once ('Link.class.php');
 require_once ('Link.class.php');
@@ -62,6 +40,7 @@ class CourseBuilder
 		$this->course->type = $type;
 		$this->course->type = $type;
 		$this->course->path = api_get_path(SYS_COURSE_PATH).$_course['path'].'/';
 		$this->course->path = api_get_path(SYS_COURSE_PATH).$_course['path'].'/';
 		$this->course->backup_path = api_get_path(SYS_COURSE_PATH).$_course['path'];
 		$this->course->backup_path = api_get_path(SYS_COURSE_PATH).$_course['path'];
+		$this->course->encoding = api_get_system_encoding(); //current platform encoding 
 	}
 	}
 	/**
 	/**
 	 * Get the created course
 	 * Get the created course
@@ -89,14 +68,11 @@ class CourseBuilder
 		$this->build_glossarys();
 		$this->build_glossarys();
 		//TABLE_LINKED_RESOURCES is the "resource" course table, which is deprecated, apparently
 		//TABLE_LINKED_RESOURCES is the "resource" course table, which is deprecated, apparently
 		$table = Database :: get_course_table(TABLE_LINKED_RESOURCES);
 		$table = Database :: get_course_table(TABLE_LINKED_RESOURCES);
-		foreach ($this->course->resources as $type => $resources)
-		{
-			foreach ($resources as $id => $resource)
-			{
+		foreach ($this->course->resources as $type => $resources) {
+			foreach ($resources as $id => $resource) {
 				$sql = "SELECT * FROM ".$table." WHERE source_type = '".$resource->get_type()."' AND source_id = '".$resource->get_id()."'";
 				$sql = "SELECT * FROM ".$table." WHERE source_type = '".$resource->get_type()."' AND source_id = '".$resource->get_id()."'";
 				$res = api_sql_query($sql, __FILE__, __LINE__);
 				$res = api_sql_query($sql, __FILE__, __LINE__);
-				while ($link = Database::fetch_object($res))
-				{
+				while ($link = Database::fetch_object($res)) {
 					$this->course->resources[$type][$id]->add_linked_resource($link->resource_type, $link->resource_id);
 					$this->course->resources[$type][$id]->add_linked_resource($link->resource_type, $link->resource_id);
 				}
 				}
 			}
 			}

+ 4 - 2
main/coursecopy/classes/CourseRestorer.class.php

@@ -82,8 +82,7 @@ class CourseRestorer
 	 * which the resources should be stored. Default: Current Dokeos-course.
 	 * which the resources should be stored. Default: Current Dokeos-course.
 	 */
 	 */
 	function restore($destination_course_code = '')
 	function restore($destination_course_code = '')
-	{
-		
+	{		
 		if ($destination_course_code == '') {
 		if ($destination_course_code == '') {
 			$course_info = api_get_course_info();
 			$course_info = api_get_course_info();
 			$this->course->destination_db = $course_info['dbName'];
 			$this->course->destination_db = $course_info['dbName'];
@@ -93,6 +92,9 @@ class CourseRestorer
 			$this->course->destination_db = $course_info['database'];
 			$this->course->destination_db = $course_info['database'];
 			$this->course->destination_path = $course_info['directory'];
 			$this->course->destination_path = $course_info['directory'];
 		}
 		}
+		// platform encoding
+		$course_charset = $this->course->encoding; 
+		
 		$this->restore_links();
 		$this->restore_links();
 		$this->restore_tool_intro();
 		$this->restore_tool_intro();
 		$this->restore_events();
 		$this->restore_events();

+ 4 - 1
main/css/blue_lagoon/jquery.tabs.css

@@ -31,6 +31,7 @@
 	display: block;
 	display: block;
 	padding: 0 10px;
 	padding: 0 10px;
 	background: url(images/tab.png) no-repeat;
 	background: url(images/tab.png) no-repeat;
+	
 }
 }
 .tabs-nav a {
 .tabs-nav a {
 	position: relative;
 	position: relative;
@@ -61,7 +62,7 @@
 	height: 18px; /* IE 6 treats height as min-height */
 	height: 18px; /* IE 6 treats height as min-height */
 	min-height: 18px;
 	min-height: 18px;
 	padding-top: 6px;
 	padding-top: 6px;
-	padding-right: 0;
+	padding-right: 0;	
 }
 }
 *>.tabs-nav a span { /* hide from IE 6 */
 *>.tabs-nav a span { /* hide from IE 6 */
 	width: auto;
 	width: auto;
@@ -93,4 +94,6 @@
 .tabs-loading em {
 .tabs-loading em {
 	padding: 0 0 0 20px;
 	padding: 0 0 0 20px;
 	background: url(images/loading.gif) no-repeat 0 50%;
 	background: url(images/loading.gif) no-repeat 0 50%;
+	color: #A8A7A7;
+
 }
 }

+ 13 - 8
main/css/cosmic_campus/default.css

@@ -237,10 +237,23 @@ a.breadcrumb0 {
 .courseslist {
 .courseslist {
 	margin-left: -25px;
 	margin-left: -25px;
 }
 }
+
+/* user_portal course list */
 .courses {
 .courses {
 	list-style-type: none;
 	list-style-type: none;
 	margin-bottom: 5px;
 	margin-bottom: 5px;
+	height: 30px;	
 }
 }
+/* user_portal session list */
+.session_course_item .courses {
+	margin-bottom: 5px;
+	height:35px;
+}
+.session_course_item {
+	/* padding: 0px; */
+	margin: 0px;
+}
+
 .courses a {
 .courses a {
 }
 }
 .user_course_category {
 .user_course_category {
@@ -253,14 +266,6 @@ a.breadcrumb0 {
 	padding: 5px;
 	padding: 5px;
 }
 }
 
 
-.session_course_item {
-	/* padding: 0px; */
-	margin: 0px;
-}
-.session_course_item .courses {
-	height:22px;
-}
-
 .menu {
 .menu {
 	float: right;
 	float: right;
 	width: 200px;
 	width: 200px;

+ 10 - 8
main/css/delicious_bordeaux/default.css

@@ -148,6 +148,16 @@ input[type="text"]:focus, input[type="password"]:focus, textarea:focus {
 .courses {
 .courses {
 	list-style-type: none;
 	list-style-type: none;
 	margin-bottom: 5px;
 	margin-bottom: 5px;
+	height: 30px;	
+}
+/* user_portal session list */
+.session_course_item .courses {
+	margin-bottom: 5px;
+	height:35px;
+}
+.session_course_item {
+	/* padding: 0px; */
+	margin: 0px;
 }
 }
 /*****************************************************
 /*****************************************************
  *  HEADER STYLES                                    *
  *  HEADER STYLES                                    *
@@ -1273,14 +1283,6 @@ div.admin_section h4 {
 }
 }
 .session_box_coach {
 .session_box_coach {
 }
 }
-.session_course_item {
-	/* padding: 0px; */
-	margin: 0px;
-}
-
-.session_course_item .courses {
-	height:22px;
-}
 /***************************************************************
 /***************************************************************
  *  DOKEOS CONFIG SETTINGS OF THE PLATFORM ADMIN SECTION 	   *
  *  DOKEOS CONFIG SETTINGS OF THE PLATFORM ADMIN SECTION 	   *
  ***************************************************************/
  ***************************************************************/

+ 0 - 8
main/css/dokeos_blue/default.css

@@ -1273,14 +1273,6 @@ div.admin_section h4 {
 }
 }
 .session_box_coach {
 .session_box_coach {
 }
 }
-.session_course_item {
-	/* padding: 0px; */
-	margin: 0px;
-}
-
-.session_course_item .courses {
-	height:22px;
-}
 /***************************************************************
 /***************************************************************
  *  DOKEOS CONFIG SETTINGS OF THE PLATFORM ADMIN SECTION 	   *
  *  DOKEOS CONFIG SETTINGS OF THE PLATFORM ADMIN SECTION 	   *
  ***************************************************************/
  ***************************************************************/

+ 11 - 8
main/css/dokeos_classic/default.css

@@ -150,7 +150,18 @@ input[text] {
 .courses {
 .courses {
 	list-style-type: none;
 	list-style-type: none;
 	margin-bottom: 5px;
 	margin-bottom: 5px;
+	height: 30px;	
 }
 }
+/* user_portal session list */
+.session_course_item .courses {
+	margin-bottom: 5px;
+	height:35px;
+}
+.session_course_item {
+	/* padding: 0px; */
+	margin: 0px;
+}
+
 /*****************************************************
 /*****************************************************
  *  HEADER STYLES                                    *
  *  HEADER STYLES                                    *
  *****************************************************/
  *****************************************************/
@@ -1327,14 +1338,6 @@ div.admin_section h4 {
 }
 }
 .session_box_coach {
 .session_box_coach {
 }
 }
-.session_course_item {
-	/* padding: 0px; */
-	margin: 0px;
-}
-
-.session_course_item .courses {
-	height:22px;
-}
 /***************************************************************
 /***************************************************************
  *  DOKEOS CONFIG SETTINGS OF THE PLATFORM ADMIN SECTION 	   *
  *  DOKEOS CONFIG SETTINGS OF THE PLATFORM ADMIN SECTION 	   *
  ***************************************************************/
  ***************************************************************/

+ 11 - 8
main/css/dokeos_classic_2D/default.css

@@ -130,7 +130,18 @@ input.link_alike:hover {
 .courses {
 .courses {
 	list-style-type: none;
 	list-style-type: none;
 	margin-bottom: 5px;
 	margin-bottom: 5px;
+	height: 30px;	
 }
 }
+/* user_portal session list */
+.session_course_item .courses {
+	margin-bottom: 5px;
+	height:35px;
+}
+.session_course_item {
+	/* padding: 0px; */
+	margin: 0px;
+}
+
 /*
 /*
 ==============================================================================
 ==============================================================================
 	HEADER STYLES
 	HEADER STYLES
@@ -1318,14 +1329,6 @@ div.admin_section h4 {
 }
 }
 .session_box_coach {
 .session_box_coach {
 }
 }
-.session_course_item {
-	/* padding: 0px; */
-	margin: 0px;
-}
-
-.session_course_item .courses {
-	height:22px;
-}
 /*
 /*
 ==============================================================================
 ==============================================================================
     DOKEOS CONFIG SETTINGS OF THE PLATFORM ADMIN SECTION
     DOKEOS CONFIG SETTINGS OF THE PLATFORM ADMIN SECTION

+ 11 - 7
main/css/empire_green/default.css

@@ -148,7 +148,18 @@ input[type="text"]:focus, input[type="password"]:focus, textarea:focus {
 .courses {
 .courses {
 	list-style-type: none;
 	list-style-type: none;
 	margin-bottom: 5px;
 	margin-bottom: 5px;
+	height: 30px;	
 }
 }
+/* user_portal session list */
+.session_course_item .courses {
+	margin-bottom: 5px;
+	height:35px;
+}
+.session_course_item {
+	/* padding: 0px; */
+	margin: 0px;
+}
+
 /*****************************************************
 /*****************************************************
  *  HEADER STYLES                                    *
  *  HEADER STYLES                                    *
  *****************************************************/
  *****************************************************/
@@ -1273,13 +1284,6 @@ div.admin_section h4 {
 }
 }
 .session_box_coach {
 .session_box_coach {
 }
 }
-.session_course_item {
-	/* padding: 0px; */
-	margin: 0px;
-}
-.session_course_item .courses {
-	height:22px;
-}
 /***************************************************************
 /***************************************************************
  *  DOKEOS CONFIG SETTINGS OF THE PLATFORM ADMIN SECTION 	   *
  *  DOKEOS CONFIG SETTINGS OF THE PLATFORM ADMIN SECTION 	   *
  ***************************************************************/
  ***************************************************************/

+ 11 - 8
main/css/fruity_orange/default.css

@@ -148,7 +148,18 @@ input[type="text"]:focus, input[type="password"]:focus, textarea:focus {
 .courses {
 .courses {
 	list-style-type: none;
 	list-style-type: none;
 	margin-bottom: 5px;
 	margin-bottom: 5px;
+	height: 30px;	
 }
 }
+/* user_portal session list */
+.session_course_item .courses {
+	margin-bottom: 5px;
+	height:35px;
+}
+.session_course_item {
+	/* padding: 0px; */
+	margin: 0px;
+}
+
 /*****************************************************
 /*****************************************************
  *  HEADER STYLES                                    *
  *  HEADER STYLES                                    *
  *****************************************************/
  *****************************************************/
@@ -1273,14 +1284,6 @@ div.admin_section h4 {
 }
 }
 .session_box_coach {
 .session_box_coach {
 }
 }
-.session_course_item {
-	/* padding: 0px; */
-	margin: 0px;
-}
-
-.session_course_item .courses {
-	height:22px;
-}
 /***************************************************************
 /***************************************************************
  *  DOKEOS CONFIG SETTINGS OF THE PLATFORM ADMIN SECTION 	   *
  *  DOKEOS CONFIG SETTINGS OF THE PLATFORM ADMIN SECTION 	   *
  ***************************************************************/
  ***************************************************************/

+ 12 - 7
main/css/medical/default.css

@@ -168,7 +168,18 @@ input[text] {
 .courses {
 .courses {
 	list-style-type: none;
 	list-style-type: none;
 	margin-bottom: 5px;
 	margin-bottom: 5px;
+	height: 30px;	
 }
 }
+/* user_portal session list */
+.session_course_item .courses {
+	margin-bottom: 5px;
+	height:35px;
+}
+.session_course_item {
+	/* padding: 0px; */
+	margin: 0px;
+}
+
 /*****************************************************
 /*****************************************************
  *  HEADER STYLES                                    *
  *  HEADER STYLES                                    *
  *****************************************************/
  *****************************************************/
@@ -1309,13 +1320,7 @@ div.admin_section h4 {
 }
 }
 .session_box_coach {
 .session_box_coach {
 }
 }
-.session_course_item {
-	/* padding: 0px; */
-	margin: 0px;
-}
-.session_course_item .courses {
-	height:22px;
-}
+
 /***************************************************************
 /***************************************************************
  *  DOKEOS CONFIG SETTINGS OF THE PLATFORM ADMIN SECTION 	   *
  *  DOKEOS CONFIG SETTINGS OF THE PLATFORM ADMIN SECTION 	   *
  ***************************************************************/
  ***************************************************************/

+ 11 - 7
main/css/public_admin/default.css

@@ -169,7 +169,18 @@ input[text] {
 .courses {
 .courses {
 	list-style-type: none;
 	list-style-type: none;
 	margin-bottom: 5px;
 	margin-bottom: 5px;
+	height: 30px;	
 }
 }
+/* user_portal session list */
+.session_course_item .courses {
+	margin-bottom: 5px;
+	height:35px;
+}
+.session_course_item {
+	/* padding: 0px; */
+	margin: 0px;
+}
+
 /*****************************************************
 /*****************************************************
  *  HEADER STYLES                                    *
  *  HEADER STYLES                                    *
  *****************************************************/
  *****************************************************/
@@ -1323,13 +1334,6 @@ div.admin_section h4 {
 }
 }
 .session_box_coach {
 .session_box_coach {
 }
 }
-.session_course_item {
-	/* padding: 0px; */
-	margin: 0px;
-}
-.session_course_item .courses {
-	height:22px;
-}
 /***************************************************************
 /***************************************************************
  *  DOKEOS CONFIG SETTINGS OF THE PLATFORM ADMIN SECTION 	   *
  *  DOKEOS CONFIG SETTINGS OF THE PLATFORM ADMIN SECTION 	   *
  ***************************************************************/
  ***************************************************************/

+ 11 - 7
main/css/royal_purple/default.css

@@ -148,7 +148,18 @@ input[type="text"]:focus, input[type="password"]:focus, textarea:focus {
 .courses {
 .courses {
 	list-style-type: none;
 	list-style-type: none;
 	margin-bottom: 5px;
 	margin-bottom: 5px;
+	height: 30px;	
 }
 }
+/* user_portal session list */
+.session_course_item .courses {
+	margin-bottom: 5px;
+	height:35px;
+}
+.session_course_item {
+	/* padding: 0px; */
+	margin: 0px;
+}
+
 /*****************************************************
 /*****************************************************
  *  HEADER STYLES                                    *
  *  HEADER STYLES                                    *
  *****************************************************/
  *****************************************************/
@@ -1273,13 +1284,6 @@ div.admin_section h4 {
 }
 }
 .session_box_coach {
 .session_box_coach {
 }
 }
-.session_course_item {
-	/* padding: 0px; */
-	margin: 0px;
-}
-.session_course_item .courses {
-	height:22px;
-}
 /***************************************************************
 /***************************************************************
  *  DOKEOS CONFIG SETTINGS OF THE PLATFORM ADMIN SECTION 	   *
  *  DOKEOS CONFIG SETTINGS OF THE PLATFORM ADMIN SECTION 	   *
  ***************************************************************/
  ***************************************************************/

+ 13 - 12
main/css/silver_line/default.css

@@ -81,12 +81,20 @@ ul {
 }
 }
 /* user_portal course list */
 /* user_portal course list */
 .courses {
 .courses {
-	font-weight: bold;
-	list-style: none;
-	margin-bottom: .2em;
-	font-family: arial, sans-serif, sans;
-	font-size: 110%;
+	list-style-type: none;
+	margin-bottom: 5px;
+	height: 30px;	
+}
+/* user_portal session list */
+.session_course_item .courses {
+	margin-bottom: 5px;
+	height:35px;
 }
 }
+.session_course_item {
+	/* padding: 0px; */
+	margin: 0px;
+}
+
 #main {
 #main {
 	font-size: 89%;
 	font-size: 89%;
 	width: 96%;
 	width: 96%;
@@ -145,13 +153,6 @@ ul {
 }
 }
 .session_box_coach {
 .session_box_coach {
 }
 }
-.session_course_item {
-	/* padding: 0px; */
-	margin: 0px;
-}
-.session_course_item .courses {
-	height:22px;
-}
 /*
 /*
 ==============================================================================
 ==============================================================================
 	HEADER STYLES
 	HEADER STYLES

+ 11 - 7
main/css/sober_brown/default.css

@@ -170,7 +170,18 @@ input[text] {
 .courses {
 .courses {
 	list-style-type: none;
 	list-style-type: none;
 	margin-bottom: 5px;
 	margin-bottom: 5px;
+	height: 30px;	
 }
 }
+/* user_portal session list */
+.session_course_item .courses {
+	margin-bottom: 5px;
+	height:35px;
+}
+.session_course_item {
+	/* padding: 0px; */
+	margin: 0px;
+}
+
 /*****************************************************
 /*****************************************************
  *  HEADER STYLES                                    *
  *  HEADER STYLES                                    *
  *****************************************************/
  *****************************************************/
@@ -1298,13 +1309,6 @@ div.admin_section h4 {
 }
 }
 .session_box_coach {
 .session_box_coach {
 }
 }
-.session_course_item {
-	/* padding: 0px; */
-	margin: 0px;
-}
-.session_course_item .courses {
-	height:22px;
-}
 /***************************************************************
 /***************************************************************
  *  DOKEOS CONFIG SETTINGS OF THE PLATFORM ADMIN SECTION 	   *
  *  DOKEOS CONFIG SETTINGS OF THE PLATFORM ADMIN SECTION 	   *
  ***************************************************************/
  ***************************************************************/

+ 11 - 7
main/css/steel_grey/default.css

@@ -148,7 +148,18 @@ input[type="text"]:focus, input[type="password"]:focus, textarea:focus {
 .courses {
 .courses {
 	list-style-type: none;
 	list-style-type: none;
 	margin-bottom: 5px;
 	margin-bottom: 5px;
+	height: 30px;	
 }
 }
+/* user_portal session list */
+.session_course_item .courses {
+	margin-bottom: 5px;
+	height:35px;
+}
+.session_course_item {
+	/* padding: 0px; */
+	margin: 0px;
+}
+
 /*****************************************************
 /*****************************************************
  *  HEADER STYLES                                    *
  *  HEADER STYLES                                    *
  *****************************************************/
  *****************************************************/
@@ -1273,13 +1284,6 @@ div.admin_section h4 {
 }
 }
 .session_box_coach {
 .session_box_coach {
 }
 }
-.session_course_item {
-	/* padding: 0px; */
-	margin: 0px;
-}
-.session_course_item .courses {
-	height:22px;
-}
 /***************************************************************
 /***************************************************************
  *  DOKEOS CONFIG SETTINGS OF THE PLATFORM ADMIN SECTION 	   *
  *  DOKEOS CONFIG SETTINGS OF THE PLATFORM ADMIN SECTION 	   *
  ***************************************************************/
  ***************************************************************/

+ 11 - 7
main/css/tasty_olive/default.css

@@ -148,7 +148,18 @@ input[type="text"]:focus, input[type="password"]:focus, textarea:focus {
 .courses {
 .courses {
 	list-style-type: none;
 	list-style-type: none;
 	margin-bottom: 5px;
 	margin-bottom: 5px;
+	height: 30px;	
 }
 }
+/* user_portal session list */
+.session_course_item .courses {
+	margin-bottom: 5px;
+	height:35px;
+}
+.session_course_item {
+	/* padding: 0px; */
+	margin: 0px;
+}
+
 /*****************************************************
 /*****************************************************
  *  HEADER STYLES                                    *
  *  HEADER STYLES                                    *
  *****************************************************/
  *****************************************************/
@@ -1273,13 +1284,6 @@ div.admin_section h4 {
 }
 }
 .session_box_coach {
 .session_box_coach {
 }
 }
-.session_course_item {
-	/* padding: 0px; */
-	margin: 0px;
-}
-.session_course_item .courses {
-	height:22px;
-}
 /***************************************************************
 /***************************************************************
  *  DOKEOS CONFIG SETTINGS OF THE PLATFORM ADMIN SECTION 	   *
  *  DOKEOS CONFIG SETTINGS OF THE PLATFORM ADMIN SECTION 	   *
  ***************************************************************/
  ***************************************************************/

+ 14 - 19
main/document/slideshowoptions.php

@@ -1,4 +1,4 @@
-<?php // $Id: slideshowoptions.php 21107 2009-05-30 16:27:09Z iflorespaz $ 
+<?php // $Id: slideshowoptions.php 22565 2009-08-02 21:12:59Z yannoo $ 
 /*
 /*
 ==============================================================================
 ==============================================================================
 	Dokeos - elearning and course management software
 	Dokeos - elearning and course management software
@@ -158,7 +158,7 @@ echo '</div>';
 		}
 		}
 			?>>
 			?>>
 		</div>
 		</div>
-		<div class="formw"><?php echo get_lang('_no_resizing');?><br><?php echo get_lang('_no_resizing_comment');?>
+		<div class="formw"><?php echo get_lang('_no_resizing');?><br /><?php echo get_lang('_no_resizing_comment');?>
 		</div>
 		</div>
 	</div>
 	</div>
 	
 	
@@ -178,32 +178,28 @@ echo '</div>';
 			?>>
 			?>>
 		</div>
 		</div>
 		<div class="formw">
 		<div class="formw">
-			<?php echo get_lang('_resizing');?><br><?php echo get_lang('_resizing_comment');?><br>
+			<?php echo get_lang('_resizing');?><br /><?php echo get_lang('_resizing_comment');?><br />
         <?php echo get_lang('_width');?>: 
         <?php echo get_lang('_width');?>: 
 	    &nbsp;<input name="width" type="text" id="width" 
 	    &nbsp;<input name="width" type="text" id="width" 
 		<?php 
 		<?php 
-		if ($image_resizing=="resizing")
-			{
+		if ($image_resizing=="resizing") {
 			echo " value='".$width."'";
 			echo " value='".$width."'";
 			echo " class=\"enabled_input\"";
 			echo " class=\"enabled_input\"";
-			}
-		else
-			{echo " class=\"disabled_input\""; }
+	    } else {
+            echo " class=\"disabled_input\""; 
+        }
 		?> >        
 		?> >        
-        <br>
+        <br />
         <?php echo get_lang('_height');?>: 
         <?php echo get_lang('_height');?>: 
         &nbsp;&nbsp;&nbsp;&nbsp;<input name="height" type="text" id="height"
         &nbsp;&nbsp;&nbsp;&nbsp;<input name="height" type="text" id="height"
 		<?php 
 		<?php 
-		if ($image_resizing=="resizing")
-			{
+		if ($image_resizing=="resizing") {
 			echo " value='".$height."'";
 			echo " value='".$height."'";
 			echo " class=\"enabled_input\"";
 			echo " class=\"enabled_input\"";
-			}
-		else
-			{echo " class=\"disabled_input\""; }
-
-		?>
-			>
+		} else {
+            echo " class=\"disabled_input\""; 
+        }
+		?> >
 		</div>
 		</div>
 	</div>	
 	</div>	
 	<div class="row">
 	<div class="row">
@@ -216,5 +212,4 @@ echo '</div>';
 	</div>	
 	</div>	
 </form>
 </form>
 <?php
 <?php
-Display::display_footer();
-?>
+Display::display_footer();

+ 57 - 57
main/dropbox/dropbox_functions.inc.php

@@ -1,12 +1,10 @@
 <?php //$id: $
 <?php //$id: $
 /* For licensing terms, see /dokeos_license.txt */
 /* For licensing terms, see /dokeos_license.txt */
-
 /**
 /**
 * This file contains additional dropbox functions. Initially there were some 
 * This file contains additional dropbox functions. Initially there were some 
 * functions in the init files also but I have moved them over
 * functions in the init files also but I have moved them over
 * to one file 		-- Patrick Cool <patrick.cool@UGent.be>, Ghent University
 * to one file 		-- Patrick Cool <patrick.cool@UGent.be>, Ghent University
 */
 */
-
 /**
 /**
 * This function is a wrapper function for the multiple actions feature.
 * This function is a wrapper function for the multiple actions feature.
 * @return	Mixed	If there is a problem, return a string message, otherwise nothing
 * @return	Mixed	If there is a problem, return a string message, otherwise nothing
@@ -137,13 +135,13 @@ function delete_category($action, $id)
 
 
 	// step 1: delete the category
 	// step 1: delete the category
 	$sql="DELETE FROM ".$dropbox_cnf['tbl_category']." WHERE cat_id='".Database::escape_string($id)."' AND $sentreceived='1'";
 	$sql="DELETE FROM ".$dropbox_cnf['tbl_category']." WHERE cat_id='".Database::escape_string($id)."' AND $sentreceived='1'";
-	$result=api_sql_query($sql);
+	$result=Database::query($sql,__FILE__,__LINE__);
 
 
 	// step 2: delete all the documents in this category
 	// step 2: delete all the documents in this category
 	$sql="SELECT * FROM ".$entries_table." WHERE cat_id='".Database::escape_string($id)."'";
 	$sql="SELECT * FROM ".$entries_table." WHERE cat_id='".Database::escape_string($id)."'";
-	$result=api_sql_query($sql);
+	$result=Database::query($sql,__FILE__,__LINE__);
 
 
-	while ($row=mysql_fetch_array($result))
+	while ($row=Database::fetch_array($result))
 	{
 	{
 		$dropboxfile=new Dropbox_Person( $_user['user_id'], $is_courseAdmin, $is_courseTutor);
 		$dropboxfile=new Dropbox_Person( $_user['user_id'], $is_courseAdmin, $is_courseTutor);
 		if ($action=='deletereceivedcategory')
 		if ($action=='deletereceivedcategory')
@@ -170,8 +168,8 @@ function display_move_form($part, $id, $target=array())
 {
 {
 	echo '<div class="row"><div class="form_header">'.get_lang('MoveFileTo').'</div></div>';
 	echo '<div class="row"><div class="form_header">'.get_lang('MoveFileTo').'</div></div>';
 	echo '<form name="form1" method="post" action="'.api_get_self().'?view_received_category='.$_GET['view_received_category'].'&view_sent_category='.$_GET['view_sent_category'].'&view='.$_GET['view'].'">';
 	echo '<form name="form1" method="post" action="'.api_get_self().'?view_received_category='.$_GET['view_received_category'].'&view_sent_category='.$_GET['view_sent_category'].'&view='.$_GET['view'].'">';
-	echo '<input type="hidden" name="id" value="'.$id.'">';
-	echo '<input type="hidden" name="part" value="'.$part.'">';
+	echo '<input type="hidden" name="id" value="'.Security::remove_XSS($id).'">';
+	echo '<input type="hidden" name="part" value="'.Security::remove_XSS($part).'">';
 	echo '
 	echo '
 			<div class="row">
 			<div class="row">
 				<div class="label">
 				<div class="label">
@@ -227,7 +225,7 @@ function store_move($id, $target, $part)
 						WHERE dest_user_id='".Database::escape_string($_user['user_id'])."'
 						WHERE dest_user_id='".Database::escape_string($_user['user_id'])."'
 						AND file_id='".Database::escape_string($id)."'
 						AND file_id='".Database::escape_string($id)."'
 						";
 						";
-			api_sql_query($sql,__FILE__,__LINE__);
+			Database::query($sql,__FILE__,__LINE__);
 			$return_message=get_lang('ReceivedFileMoved');
 			$return_message=get_lang('ReceivedFileMoved');
 		}
 		}
 		if ($part=='sent')
 		if ($part=='sent')
@@ -236,7 +234,7 @@ function store_move($id, $target, $part)
 						WHERE uploader_id='".Database::escape_string($_user['user_id'])."'
 						WHERE uploader_id='".Database::escape_string($_user['user_id'])."'
 						AND id='".Database::escape_string($id)."'
 						AND id='".Database::escape_string($id)."'
 						";
 						";
-			api_sql_query($sql,__FILE__,__LINE__);
+			Database::query($sql,__FILE__,__LINE__);
 			$return_message=get_lang('SentFileMoved');
 			$return_message=get_lang('SentFileMoved');
 		}
 		}
 	}
 	}
@@ -278,7 +276,7 @@ function display_action_options($part, $categories, $current_category=0)
 		echo '</optgroup>';
 		echo '</optgroup>';
 	}
 	}
 	echo '</select>';
 	echo '</select>';
-	echo '<input type="submit" name="do_actions_'.$part.'" value="'.get_lang('Ok').'" />';
+	echo '<input type="submit" name="do_actions_'.Security::remove_XSS($part).'" value="'.get_lang('Ok').'" />';
 }
 }
 
 
 /**
 /**
@@ -299,7 +297,7 @@ function display_file_checkbox($id, $part)
 	{
 	{
 		$checked='checked';
 		$checked='checked';
 	}
 	}
-	$return_value='<input type="checkbox" name="'.$part.'_'.$id.'" value="'.$id.'" '.$checked.' />';
+	$return_value='<input type="checkbox" name="'.Security::remove_XSS($part).'_'.Security::remove_XSS($id).'" value="'.Security::remove_XSS($id).'" '.$checked.' />';
 	return $return_value;
 	return $return_value;
 }
 }
 
 
@@ -325,8 +323,8 @@ function get_dropbox_categories($filter='')
 
 
 	$sql="SELECT * FROM ".$dropbox_cnf['tbl_category']." WHERE user_id='".$_user['user_id']."'";
 	$sql="SELECT * FROM ".$dropbox_cnf['tbl_category']." WHERE user_id='".$_user['user_id']."'";
 
 
-	$result=api_sql_query($sql);
-	while ($row=mysql_fetch_array($result))
+	$result=Database::query($sql,__FILE__,__LINE__);
+	while ($row=Database::fetch_array($result))
 	{
 	{
 		if(($filter=='sent' AND $row['sent']==1) OR ($filter=='received' AND $row['received']==1) OR $filter=='')
 		if(($filter=='sent' AND $row['sent']==1) OR ($filter=='received' AND $row['received']==1) OR $filter=='')
 		{
 		{
@@ -382,7 +380,7 @@ function store_addcategory()
 	{
 	{
 		// step 3a, we check if the category doesn't already exist
 		// step 3a, we check if the category doesn't already exist
 		$sql="SELECT * FROM ".$dropbox_cnf['tbl_category']." WHERE user_id='".$_user['user_id']."' AND cat_name='".Database::escape_string(Security::remove_XSS($_POST['category_name']))."' AND received='".$received."' AND sent='".$sent."'";
 		$sql="SELECT * FROM ".$dropbox_cnf['tbl_category']." WHERE user_id='".$_user['user_id']."' AND cat_name='".Database::escape_string(Security::remove_XSS($_POST['category_name']))."' AND received='".$received."' AND sent='".$sent."'";
-		$result=api_sql_query($sql);
+		$result=Database::query($sql,__FILE__,__LINE__);
 
 
 
 
 		// step 3b, we add the category if it does not exist yet.
 		// step 3b, we add the category if it does not exist yet.
@@ -390,7 +388,7 @@ function store_addcategory()
 		{
 		{
 			$sql="INSERT INTO ".$dropbox_cnf['tbl_category']." (cat_name, received, sent, user_id)
 			$sql="INSERT INTO ".$dropbox_cnf['tbl_category']." (cat_name, received, sent, user_id)
 					VALUES ('".Database::escape_string(Security::remove_XSS($_POST['category_name']))."', '".Database::escape_string($received)."', '".Database::escape_string($sent)."', '".Database::escape_string($_user['user_id'])."')";
 					VALUES ('".Database::escape_string(Security::remove_XSS($_POST['category_name']))."', '".Database::escape_string($received)."', '".Database::escape_string($sent)."', '".Database::escape_string($_user['user_id'])."')";
-			api_sql_query($sql);
+			Database::query($sql,__FILE__,__LINE__);
 			return array('type' => 'confirmation', 'message'=>get_lang('CategoryStored'));
 			return array('type' => 'confirmation', 'message'=>get_lang('CategoryStored'));
 		}
 		}
 		else
 		else
@@ -403,7 +401,7 @@ function store_addcategory()
 		$sql="UPDATE ".$dropbox_cnf['tbl_category']." SET cat_name='".Database::escape_string(Security::remove_XSS($_POST['category_name']))."', received='".Database::escape_string($received)."' , sent='".Database::escape_string($sent)."'
 		$sql="UPDATE ".$dropbox_cnf['tbl_category']." SET cat_name='".Database::escape_string(Security::remove_XSS($_POST['category_name']))."', received='".Database::escape_string($received)."' , sent='".Database::escape_string($sent)."'
 				WHERE user_id='".Database::escape_string($_user['user_id'])."'
 				WHERE user_id='".Database::escape_string($_user['user_id'])."'
 				AND cat_id='".Database::escape_string(Security::remove_XSS($_POST['edit_id']))."'";
 				AND cat_id='".Database::escape_string(Security::remove_XSS($_POST['edit_id']))."'";
-		api_sql_query($sql);
+		Database::query($sql,__FILE__,__LINE__);
 		return array('type' => 'confirmation', 'message'=>get_lang('CategoryModified'));
 		return array('type' => 'confirmation', 'message'=>get_lang('CategoryModified'));
 	}
 	}
 }
 }
@@ -427,7 +425,7 @@ function display_addcategory_form($category_name='', $id='',$action)
 	{
 	{
 		// retrieve the category we are editing
 		// retrieve the category we are editing
 		$sql="SELECT * FROM ".$dropbox_cnf['tbl_category']." WHERE cat_id='".Database::escape_string($id)."'";
 		$sql="SELECT * FROM ".$dropbox_cnf['tbl_category']." WHERE cat_id='".Database::escape_string($id)."'";
-		$result=api_sql_query($sql);
+		$result=Database::query($sql,__FILE__,__LINE__);
 		$row=Database::fetch_array($result);
 		$row=Database::fetch_array($result);
 
 
 		if ($category_name=='') // after an edit with an error we do not want to return to the original name but the name we already modified. (happens when createinrecievedfiles AND createinsentfiles are not checked)
 		if ($category_name=='') // after an edit with an error we do not want to return to the original name but the name we already modified. (happens when createinrecievedfiles AND createinsentfiles are not checked)
@@ -485,7 +483,7 @@ function display_addcategory_form($category_name='', $id='',$action)
 	{
 	{
 		echo '<span class="form_error">'.get_lang('CategoryAlreadyExistsEditIt').'<span><br />';
 		echo '<span class="form_error">'.get_lang('CategoryAlreadyExistsEditIt').'<span><br />';
 	}	
 	}	
-	echo '			<input type="text" name="category_name" value="'.$category_name.'" />
+	echo '			<input type="text" name="category_name" value="'.Security::remove_XSS($category_name).'" />
 				</div>
 				</div>
 			</div>';
 			</div>';
 	
 	
@@ -503,7 +501,7 @@ function display_addcategory_form($category_name='', $id='',$action)
 					<span class="form_required">*</span> <small>'.get_lang('ThisFieldIsRequired').'</small>
 					<span class="form_required">*</span> <small>'.get_lang('ThisFieldIsRequired').'</small>
 				</div>
 				</div>
 			</div>';	
 			</div>';	
-	echo "</form>";
+	echo '</form>';
 	echo '<div style="clear: both;"></div>';
 	echo '<div style="clear: both;"></div>';
 }
 }
 
 
@@ -520,7 +518,7 @@ function display_add_form()
 	$token = Security::get_token();
 	$token = Security::get_token();
 	$dropbox_person = new Dropbox_Person( $_user['user_id'], $is_courseAdmin, $is_courseTutor);
 	$dropbox_person = new Dropbox_Person( $_user['user_id'], $is_courseAdmin, $is_courseTutor);
 	?>
 	?>
-	<form method="post" action="index.php?view_received_category=<?php echo $_GET['view_received_category']; ?>&view_sent_category=<?php echo $_GET['view_sent_category']; ?>&view=<?php echo $_GET['view']; ?>&<?php echo "origin=$origin"."&".api_get_cidreq(); ?>" enctype="multipart/form-data" onsubmit="return checkForm(this)">
+	<form method="post" action="index.php?view_received_category=<?php echo Security::remove_XSS($_GET['view_received_category']); ?>&view_sent_category=<?php echo Security::remove_XSS($_GET['view_sent_category']); ?>&view=<?php echo Security::remove_XSS($_GET['view']); ?>&<?php echo "origin=$origin"."&".api_get_cidreq(); ?>" enctype="multipart/form-data" onsubmit="return checkForm(this)">
 	
 	
 	<div class="row"><div class="form_header"><?php echo get_lang('UploadNewFile'); ?></div></div>
 	<div class="row"><div class="form_header"><?php echo get_lang('UploadNewFile'); ?></div></div>
 	
 	
@@ -536,7 +534,7 @@ function display_add_form()
 				<?php
 				<?php
 				if ($origin=='learnpath')
 				if ($origin=='learnpath')
 				{
 				{
-					echo "<input type='hidden' name='origin' value='learnpath' />";
+					echo '<input type="hidden" name="origin" value="learnpath" />';
 				}
 				}
 				?>
 				?>
 		</div>
 		</div>
@@ -686,12 +684,12 @@ function getUserNameFromId ( $id)  // RH: Mailing: return 'Mailing ' + id
     {
     {
 	    return dropbox_lang("mailingAsUsername", "noDLTT") . $mailingId;
 	    return dropbox_lang("mailingAsUsername", "noDLTT") . $mailingId;
     }
     }
-
+    $id = intval($id);
     $sql = "SELECT CONCAT(lastname,' ', firstname) AS name
     $sql = "SELECT CONCAT(lastname,' ', firstname) AS name
 			FROM " . dropbox_cnf("tbl_user") . "
 			FROM " . dropbox_cnf("tbl_user") . "
-			WHERE user_id='" . addslashes( $id) . "'";
-    $result = api_sql_query($sql,__FILE__,__LINE__);
-    $res = mysql_fetch_array( $result);
+			WHERE user_id='$id'";
+    $result = Database::query($sql,__FILE__,__LINE__);
+    $res = Database::fetch_array( $result);
 
 
     if ( $res == FALSE) return FALSE;
     if ( $res == FALSE) return FALSE;
     return stripslashes( $res["name"]);
     return stripslashes( $res["name"]);
@@ -703,11 +701,12 @@ function getUserNameFromId ( $id)  // RH: Mailing: return 'Mailing ' + id
 */
 */
 function getLoginFromId ( $id)
 function getLoginFromId ( $id)
 {
 {
+    $id = intval($id);
     $sql = "SELECT username
     $sql = "SELECT username
 			FROM " . dropbox_cnf("tbl_user") . "
 			FROM " . dropbox_cnf("tbl_user") . "
-			WHERE user_id='" . addslashes( $id) . "'";
-    $result =api_sql_query($sql,__FILE__,__LINE__);
-    $res = mysql_fetch_array( $result);
+			WHERE user_id='$id'";
+    $result =Database::query($sql,__FILE__,__LINE__);
+    $res = Database::fetch_array( $result);
     if ( $res == FALSE) return FALSE;
     if ( $res == FALSE) return FALSE;
     return stripslashes( $res["username"]);
     return stripslashes( $res["username"]);
 }
 }
@@ -736,14 +735,14 @@ function removeUnusedFiles( )
 			FROM " . dropbox_cnf("tbl_file") . " f
 			FROM " . dropbox_cnf("tbl_file") . " f
 			LEFT JOIN " . dropbox_cnf("tbl_person") . " p ON f.id = p.file_id
 			LEFT JOIN " . dropbox_cnf("tbl_person") . " p ON f.id = p.file_id
 			WHERE p.user_id IS NULL";
 			WHERE p.user_id IS NULL";
-    $result = api_sql_query($sql,__FILE__,__LINE__);
-    while ( $res = mysql_fetch_array( $result))
+    $result = Database::query($sql,__FILE__,__LINE__);
+    while ( $res = Database::fetch_array( $result))
     {
     {
 		//delete the selected files from the post and file tables
 		//delete the selected files from the post and file tables
         $sql = "DELETE FROM " . dropbox_cnf("tbl_post") . " WHERE file_id='" . $res['id'] . "'";
         $sql = "DELETE FROM " . dropbox_cnf("tbl_post") . " WHERE file_id='" . $res['id'] . "'";
-        $result1 = api_sql_query($sql,__FILE__,__LINE__);
+        $result1 = Database::query($sql,__FILE__,__LINE__);
         $sql = "DELETE FROM " . dropbox_cnf("tbl_file") . " WHERE id='" . $res['id'] . "'";
         $sql = "DELETE FROM " . dropbox_cnf("tbl_file") . " WHERE id='" . $res['id'] . "'";
-        $result1 = api_sql_query($sql,__FILE__,__LINE__);
+        $result1 = Database::query($sql,__FILE__,__LINE__);
 
 
 		//delete file from server
 		//delete file from server
         @unlink( dropbox_cnf("sysPath") . "/" . $res["filename"]);
         @unlink( dropbox_cnf("sysPath") . "/" . $res["filename"]);
@@ -759,19 +758,20 @@ function removeUnusedFiles( )
 * Mailing content files have uploader_id == mailing pseudo_id, a normal recipient,
 * Mailing content files have uploader_id == mailing pseudo_id, a normal recipient,
 * and are visible initially to recipient and pseudo_id.
 * and are visible initially to recipient and pseudo_id.
 *
 *
-* @author Ren Haentjens, Ghent University
+* @author René Haentjens, Ghent University
 *
 *
 * @todo check if this function is still necessary.
 * @todo check if this function is still necessary.
 */
 */
 function getUserOwningThisMailing($mailingPseudoId, $owner = 0, $or_die = '')
 function getUserOwningThisMailing($mailingPseudoId, $owner = 0, $or_die = '')
 {
 {
+    $mailingPseudoId = intval($mailingPseudoId);
     $sql = "SELECT f.uploader_id
     $sql = "SELECT f.uploader_id
 			FROM " . dropbox_cnf("tbl_file") . " f
 			FROM " . dropbox_cnf("tbl_file") . " f
 			LEFT JOIN " . dropbox_cnf("tbl_post") . " p ON f.id = p.file_id
 			LEFT JOIN " . dropbox_cnf("tbl_post") . " p ON f.id = p.file_id
 			WHERE p.dest_user_id = '" . $mailingPseudoId . "'";
 			WHERE p.dest_user_id = '" . $mailingPseudoId . "'";
-    $result = api_sql_query($sql,__FILE__,__LINE__);
+    $result = Database::query($sql,__FILE__,__LINE__);
 
 
-    if (!($res = mysql_fetch_array($result)))
+    if (!($res = Database::fetch_array($result)))
         die(dropbox_lang("generalError")." (code 901)");
         die(dropbox_lang("generalError")." (code 901)");
 
 
     if ($owner == 0) return $res['uploader_id'];
     if ($owner == 0) return $res['uploader_id'];
@@ -791,23 +791,23 @@ function removeMoreIfMailing($file_id)
     //    for all content files, delete mailingPseudoId from person-table
     //    for all content files, delete mailingPseudoId from person-table
     // 2. finding the owner (getUserOwningThisMailing) is no longer possible, so
     // 2. finding the owner (getUserOwningThisMailing) is no longer possible, so
     //    for all content files, replace mailingPseudoId by owner as uploader
     //    for all content files, replace mailingPseudoId by owner as uploader
-
+    $file_id = intval($file_id);
     $sql = "SELECT p.dest_user_id
     $sql = "SELECT p.dest_user_id
 			FROM " . dropbox_cnf("tbl_post") . " p
 			FROM " . dropbox_cnf("tbl_post") . " p
 			WHERE p.file_id = '" . $file_id . "'";
 			WHERE p.file_id = '" . $file_id . "'";
-    $result = api_sql_query($sql,__FILE__,__LINE__);
+    $result = Database::query($sql,__FILE__,__LINE__);
 
 
-    if ( $res = mysql_fetch_array( $result))
+    if ( $res = Database::fetch_array( $result))
     {
     {
 	    $mailingPseudoId = $res['dest_user_id'];
 	    $mailingPseudoId = $res['dest_user_id'];
 	    if ( $mailingPseudoId > dropbox_cnf("mailingIdBase"))
 	    if ( $mailingPseudoId > dropbox_cnf("mailingIdBase"))
 	    {
 	    {
 	        $sql = "DELETE FROM " . dropbox_cnf("tbl_person") . " WHERE user_id='" . $mailingPseudoId . "'";
 	        $sql = "DELETE FROM " . dropbox_cnf("tbl_person") . " WHERE user_id='" . $mailingPseudoId . "'";
-	        $result1 = api_sql_query($sql,__FILE__,__LINE__);
+	        $result1 = Database::query($sql,__FILE__,__LINE__);
 
 
 	        $sql = "UPDATE " . dropbox_cnf("tbl_file") .
 	        $sql = "UPDATE " . dropbox_cnf("tbl_file") .
 	            " SET uploader_id='" . api_get_user_id() . "' WHERE uploader_id='" . $mailingPseudoId . "'";
 	            " SET uploader_id='" . api_get_user_id() . "' WHERE uploader_id='" . $mailingPseudoId . "'";
-	        $result1 = api_sql_query($sql,__FILE__,__LINE__);
+	        $result1 = Database::query($sql,__FILE__,__LINE__);
         }
         }
     }
     }
 }
 }
@@ -817,7 +817,7 @@ function removeMoreIfMailing($file_id)
 *
 *
 * @todo check if this function is still necessary.
 * @todo check if this function is still necessary.
 *
 *
-* @author Ren Haentjens, Ghent University
+* @author René Haentjens, Ghent University
 */
 */
 function dropbox_lang($variable, $notrans = 'DLTT')
 function dropbox_lang($variable, $notrans = 'DLTT')
 {
 {
@@ -1055,13 +1055,14 @@ function display_user_link($user_id, $name='')
 		{
 		{
 			$table_user = Database::get_main_table(TABLE_MAIN_USER);
 			$table_user = Database::get_main_table(TABLE_MAIN_USER);
 			$sql="SELECT * FROM $table_user WHERE user_id='".Database::escape_string($user_id)."'";
 			$sql="SELECT * FROM $table_user WHERE user_id='".Database::escape_string($user_id)."'";
-			$result=api_sql_query($sql,__FILE__,__LINE__);
-			$row=mysql_fetch_array($result);
+			$result=Database::query($sql,__FILE__,__LINE__);
+			$row=Database::fetch_array($result);
 			return "<a href=\"../user/userInfo.php?uInfo=".$row['user_id']."\">".$row['firstname']." ".$row['lastname']."</a>";
 			return "<a href=\"../user/userInfo.php?uInfo=".$row['user_id']."\">".$row['firstname']." ".$row['lastname']."</a>";
 		}
 		}
 		else
 		else
 		{
 		{
-			return "<a href=\"../user/userInfo.php?uInfo=".$user_id."\">".$name."</a>";
+            $user_id = intval($user_id);
+			return "<a href=\"../user/userInfo.php?uInfo=".$user_id."\">".Security::remove_XSS($name)."</a>";
 		}
 		}
 	}
 	}
 	else
 	else
@@ -1101,8 +1102,8 @@ function feedback($array)
 function format_feedback($feedback)
 function format_feedback($feedback)
 {
 {
 	$output.=display_user_link($feedback['author_user_id']);
 	$output.=display_user_link($feedback['author_user_id']);
-	$output.='&nbsp;&nbsp;['.$feedback['feedback_date'].']<br>';
-	$output.='<div style="padding-top:6px">'.nl2br($feedback['feedback']).'</div><hr size="1" noshade/><br>';
+	$output.='&nbsp;&nbsp;['.$feedback['feedback_date'].']<br />';
+	$output.='<div style="padding-top:6px">'.nl2br($feedback['feedback']).'</div><hr size="1" noshade/><br />';
 	return $output;
 	return $output;
 }
 }
 
 
@@ -1122,8 +1123,8 @@ function feedback_form()
 	// we now check if the other users have not delete this document yet. If this is the case then it is useless to see the
 	// we now check if the other users have not delete this document yet. If this is the case then it is useless to see the
 	// add feedback since the other users will never get to see the feedback.
 	// add feedback since the other users will never get to see the feedback.
 	$sql="SELECT * FROM ".$dropbox_cnf["tbl_person"]." WHERE file_id='".Database::escape_string($_GET['id'])."'";
 	$sql="SELECT * FROM ".$dropbox_cnf["tbl_person"]." WHERE file_id='".Database::escape_string($_GET['id'])."'";
-	$result=api_sql_query($sql,__LINE__, __FILE__);
-	$number_users_who_see_file=mysql_num_rows($result);
+	$result=Database::query($sql,__LINE__, __FILE__);
+	$number_users_who_see_file=Database::num_rows($result);
 	if ($number_users_who_see_file>1)
 	if ($number_users_who_see_file>1)
 	{
 	{
 		$return .= '<textarea name="feedback" style="width: 80%; height: 80px;"></textarea><br /><button type="submit" class="add" name="store_feedback" value="'.get_lang('Ok').'" 
 		$return .= '<textarea name="feedback" style="width: 80%; height: 80px;"></textarea><br /><button type="submit" class="add" name="store_feedback" value="'.get_lang('Ok').'" 
@@ -1160,7 +1161,7 @@ function store_feedback()
 	{
 	{
 		$sql="INSERT INTO ".$dropbox_cnf['tbl_feedback']." (file_id, author_user_id, feedback, feedback_date) VALUES
 		$sql="INSERT INTO ".$dropbox_cnf['tbl_feedback']." (file_id, author_user_id, feedback, feedback_date) VALUES
 				('".Database::escape_string($_GET['id'])."','".Database::escape_string($_user['user_id'])."','".Database::escape_string($_POST['feedback'])."',NOW())";
 				('".Database::escape_string($_GET['id'])."','".Database::escape_string($_user['user_id'])."','".Database::escape_string($_POST['feedback'])."',NOW())";
-		api_sql_query($sql);
+		Database::query($sql,__FILE__,__LINE__);
 		return get_lang('DropboxFeedbackStored');
 		return get_lang('DropboxFeedbackStored');
 	}
 	}
 }
 }
@@ -1206,8 +1207,8 @@ function zip_download ($array)
 			WHERE file.id IN (".implode(', ',$array).")
 			WHERE file.id IN (".implode(', ',$array).")
 			AND file.id=person.file_id
 			AND file.id=person.file_id
 			AND person.user_id='".$_user['user_id']."'";
 			AND person.user_id='".$_user['user_id']."'";
-	$result=api_sql_query($sql,__FILE__,__LINE__);
-	while ($row=mysql_fetch_array($result))
+	$result=Database::query($sql,__FILE__,__LINE__);
+	while ($row=Database::fetch_array($result))
 	{
 	{
 		$files[$row['filename']]=array('filename'=>$row['filename'],'title'=>$row['title'], 'author'=>$row['author'], 'description'=>$row['description']);
 		$files[$row['filename']]=array('filename'=>$row['filename'],'title'=>$row['title'], 'author'=>$row['author'], 'description'=>$row['description']);
 	}
 	}
@@ -1454,8 +1455,8 @@ function get_total_number_feedback($file_id='')
 	global $dropbox_cnf;
 	global $dropbox_cnf;
 
 
 	$sql="SELECT COUNT(feedback_id) AS total, file_id FROM ".$dropbox_cnf['tbl_feedback']." GROUP BY file_id";
 	$sql="SELECT COUNT(feedback_id) AS total, file_id FROM ".$dropbox_cnf['tbl_feedback']." GROUP BY file_id";
-	$result=api_sql_query($sql, __FILE__, __LINE__);
-	while ($row=mysql_fetch_array($result))
+	$result=Database::query($sql, __FILE__, __LINE__);
+	while ($row=Database::fetch_array($result))
 	{
 	{
 		$return[$row['file_id']]=$row['total'];
 		$return[$row['file_id']]=$row['total'];
 	}
 	}
@@ -1526,8 +1527,7 @@ function get_last_tool_access($tool, $course_code='', $user_id='')
 				AND access_tool='".Database::escape_string($tool)."'
 				AND access_tool='".Database::escape_string($tool)."'
 				ORDER BY access_date DESC
 				ORDER BY access_date DESC
 				LIMIT 1";
 				LIMIT 1";
-	$result=api_sql_query($sql,__FILE__,__LINE__);
-	$row=mysql_fetch_array($result);
+	$result=Database::query($sql,__FILE__,__LINE__);
+	$row=Database::fetch_array($result);
 	return $row['access_date'];
 	return $row['access_date'];
-}
-?>
+}

+ 2 - 8
main/exercice/adminhp.php

@@ -134,18 +134,12 @@ $lstrComment = GetComment($hotpotatoesName);
 if($lstrComment=="")
 if($lstrComment=="")
 	$lstrComment = GetQuizName($hotpotatoesName,$documentPath);
 	$lstrComment = GetQuizName($hotpotatoesName,$documentPath);
 if($lstrComment=="")
 if($lstrComment=="")
-	$lstrComment = GetFileName($hotpotatoesName,$documentPath);
+	$lstrComment = basename($hotpotatoesName,$documentPath);
 
 
 echo $lstrComment;
 echo $lstrComment;
 echo "\" size=40>&nbsp;";
 echo "\" size=40>&nbsp;";
 echo "<button type=\"submit\" class=\"save\" name=\"submit\" value=\"".get_lang('Ok')."\">".get_lang('Ok')."</button>";
 echo "<button type=\"submit\" class=\"save\" name=\"submit\" value=\"".get_lang('Ok')."\">".get_lang('Ok')."</button>";
 echo "<button type=\"button\" class=\"cancel\" name=\"cancel\" value=\"".get_lang('Cancel')."\" onclick=\"javascript:document.form1.newName.value='';\">".get_lang('Cancel')."</button>";
 echo "<button type=\"button\" class=\"cancel\" name=\"cancel\" value=\"".get_lang('Cancel')."\" onclick=\"javascript:document.form1.newName.value='';\">".get_lang('Cancel')."</button>";
-
 echo "</form>";
 echo "</form>";
 
 
-?>
-<?php
-
-Display::display_footer();
-
-?>
+Display::display_footer();

+ 8 - 22
main/exercice/exercice.php

@@ -836,33 +836,26 @@ if ($show == 'test') {
 ?>
 ?>
 <table class="data_table">
 <table class="data_table">
   <?php
   <?php
-
 	if (($is_allowedToEdit) and ($origin != 'learnpath')) {
 	if (($is_allowedToEdit) and ($origin != 'learnpath')) {
 ?>
 ?>
 	  <tr class="row_odd">
 	  <tr class="row_odd">
 	    <th colspan="3"><?php  echo get_lang('ExerciseName');?></th>
 	    <th colspan="3"><?php  echo get_lang('ExerciseName');?></th>
 	     <th><?php echo get_lang('QuantityQuestions');?></th>
 	     <th><?php echo get_lang('QuantityQuestions');?></th>
 		 <!--<th>--><?php
 		 <!--<th>--><?php
-
 ?>
 ?>
-
 <!--</th>-->
 <!--</th>-->
-		 <th><?php echo get_lang('Modify');?></th>
-	
+		 <th><?php echo get_lang('Modify');?></th>	
 	  </tr>
 	  </tr>
 	  <?php
 	  <?php
-
 	} else {
 	} else {
+		//student only
 ?> <tr>
 ?> <tr>
-	     <th colspan="3"><?php echo get_lang('ExerciseName');?></th>
+	     <th colspan="2"><?php echo get_lang('ExerciseName');?></th>
 	     <th><?php echo get_lang('QuantityQuestions');?></th>
 	     <th><?php echo get_lang('QuantityQuestions');?></th>
-		 <th><?php echo get_lang('State');?></th>
-	
+		 <th><?php echo get_lang('State');?></th>	
 	  </tr>
 	  </tr>
 		<?php
 		<?php
-
 	}
 	}
-
 	// show message if no HP test to show
 	// show message if no HP test to show
 	if (!($nbrExercises + $nbrHpTests)) {
 	if (!($nbrExercises + $nbrHpTests)) {
 ?>
 ?>
@@ -870,7 +863,6 @@ if ($show == 'test') {
 	    <td <?php echo ($is_allowedToEdit?'colspan="6"':'colspan="5"'); ?>><?php echo get_lang("NoEx"); ?></td>
 	    <td <?php echo ($is_allowedToEdit?'colspan="6"':'colspan="5"'); ?>><?php echo get_lang("NoEx"); ?></td>
 	  </tr>
 	  </tr>
 	  <?php
 	  <?php
-
 	}
 	}
 	$i = 1;
 	$i = 1;
 	// while list exercises
 	// while list exercises
@@ -937,32 +929,26 @@ if ($show == 'test') {
 <!--" /></a>-->	    
 <!--" /></a>-->	    
 			<a href="exercice.php?choice=delete&exerciseId=<?php echo $row['id']; ?>" onclick="javascript:if(!confirm('<?php echo addslashes(api_htmlentities(get_lang('AreYouSureToDelete'),ENT_QUOTES,$charset)); echo " ".$row['title']; echo "?"; ?>')) return false;"> <img src="../img/delete.gif" border="0" alt="<?php echo api_htmlentities(get_lang('Delete'),ENT_QUOTES,$charset); ?>" /></a>					
 			<a href="exercice.php?choice=delete&exerciseId=<?php echo $row['id']; ?>" onclick="javascript:if(!confirm('<?php echo addslashes(api_htmlentities(get_lang('AreYouSureToDelete'),ENT_QUOTES,$charset)); echo " ".$row['title']; echo "?"; ?>')) return false;"> <img src="../img/delete.gif" border="0" alt="<?php echo api_htmlentities(get_lang('Delete'),ENT_QUOTES,$charset); ?>" /></a>					
 			<?php
 			<?php
-
 				//if active
 				//if active
 				if ($row['active']) {
 				if ($row['active']) {
 ?>
 ?>
 	      		<a href="exercice.php?choice=disable&page=<?php echo $page; ?>&exerciseId=<?php echo $row['id']; ?>"> <img src="../img/visible.gif" border="0" alt="<?php echo api_htmlentities(get_lang('Deactivate'),ENT_QUOTES,$charset); ?>" /></a>
 	      		<a href="exercice.php?choice=disable&page=<?php echo $page; ?>&exerciseId=<?php echo $row['id']; ?>"> <img src="../img/visible.gif" border="0" alt="<?php echo api_htmlentities(get_lang('Deactivate'),ENT_QUOTES,$charset); ?>" /></a>
 	    		<?php
 	    		<?php
-
 				} else {
 				} else {
 					// else if not active
 					// else if not active
 ?>
 ?>
 	      		<a href="exercice.php?choice=enable&page=<?php echo $page; ?>&exerciseId=<?php echo $row['id']; ?>"> <img src="../img/invisible.gif" border="0" alt="<?php echo api_htmlentities(get_lang('Activate'),ENT_QUOTES,$charset); ?>" /></a>
 	      		<a href="exercice.php?choice=enable&page=<?php echo $page; ?>&exerciseId=<?php echo $row['id']; ?>"> <img src="../img/invisible.gif" border="0" alt="<?php echo api_htmlentities(get_lang('Activate'),ENT_QUOTES,$charset); ?>" /></a>
 	    		<?php
 	    		<?php
-
 				}
 				}
 				echo "</td>";
 				echo "</td>";
 				echo "</tr>\n";
 				echo "</tr>\n";
 			} else { // student only
 			} else { // student only
 ?>
 ?>
 	          <tr>
 	          <tr>
-	            <td><?php echo ($i+($page*$limitExPage)).'.'; ?></td>
-	            <td>&nbsp;</td>
+	            <td><?php echo ($i+($page*$limitExPage)).'.'; ?></td>	            
 	            <?php $row['title']=api_parse_tex($row['title']);?>
 	            <?php $row['title']=api_parse_tex($row['title']);?>
 	            <td><a href="exercice_submit.php?<?php echo api_get_cidreq().$myorigin.$mylpid.$myllpitemid; ?>&exerciseId=<?php echo $row['id']; ?>"><?php echo $row['title']; ?></a></td>
 	            <td><a href="exercice_submit.php?<?php echo api_get_cidreq().$myorigin.$mylpid.$myllpitemid; ?>&exerciseId=<?php echo $row['id']; ?>"><?php echo $row['title']; ?></a></td>
-				 <td align="center"> <?php
-
-
+				<td align="center"> <?php
 				$exid = $row['id'];
 				$exid = $row['id'];
 				//count number exercise questions
 				//count number exercise questions
 				$sqlquery = "SELECT count(*) FROM $TBL_EXERCICE_QUESTION WHERE exercice_id = '" . Database :: escape_string($exid) . "'";
 				$sqlquery = "SELECT count(*) FROM $TBL_EXERCICE_QUESTION WHERE exercice_id = '" . Database :: escape_string($exid) . "'";
@@ -1066,7 +1052,7 @@ if ($show == 'test') {
 
 
 				$title = GetQuizName($path, $documentPath);
 				$title = GetQuizName($path, $documentPath);
 				if ($title == '') {
 				if ($title == '') {
-					$title = GetFileName($path);
+					$title = basename($path);
 				}
 				}
 				// prof only
 				// prof only
 				if ($is_allowedToEdit) {
 				if ($is_allowedToEdit) {
@@ -1345,7 +1331,7 @@ if ($_configuration['tracking_enabled'] && ($show == 'result')) {
 		for ($i = 0; $i < sizeof($hpresults); $i++) {
 		for ($i = 0; $i < sizeof($hpresults); $i++) {
 			$title = GetQuizName($hpresults[$i][1], $documentPath);
 			$title = GetQuizName($hpresults[$i][1], $documentPath);
 			if ($title == '') {
 			if ($title == '') {
-				$title = GetFileName($hpresults[$i][1]);
+				$title = basename($hpresults[$i][1]);
 			}
 			}
 			echo '<tr>';
 			echo '<tr>';
 			if ($is_allowedToEdit) {
 			if ($is_allowedToEdit) {

+ 1 - 1
main/exercice/exercise_result.class.php

@@ -196,7 +196,7 @@ class ExerciseResult
 				$title = GetQuizName($hpresults[$i][1],$document_path);
 				$title = GetQuizName($hpresults[$i][1],$document_path);
 				if ($title =='')
 				if ($title =='')
 				{
 				{
-					$title = GetFileName($hpresults[$i][1]);
+					$title = basename($hpresults[$i][1]);
 				}
 				}
 				if(empty($user_id))
 				if(empty($user_id))
 				{
 				{

+ 30 - 39
main/exercice/exercise_submit_modal.php

@@ -1,4 +1,5 @@
 <?php
 <?php
+/* For licensing terms, see /dokeos_license.txt */
 $language_file=array('exercice');
 $language_file=array('exercice');
 include_once('../inc/global.inc.php');
 include_once('../inc/global.inc.php');
 include api_get_path(INCLUDE_PATH) . 'reduced_header.inc.php';
 include api_get_path(INCLUDE_PATH) . 'reduced_header.inc.php';
@@ -21,41 +22,41 @@ require_once('question.class.php');
 require_once('answer.class.php');
 require_once('answer.class.php');
 require_once('exercise.lib.php');
 require_once('exercise.lib.php');
 
 
-if ( empty ( $exerciseResult ) ) {
+if (empty ($exerciseResult)) {
     $exerciseResult = $_SESSION['exerciseResult'];
     $exerciseResult = $_SESSION['exerciseResult'];
 }
 }
 
 
-if ( empty ( $exerciseResultCoordinates ) ) {
-    $exerciseResultCoordinates = $_REQUEST['exerciseResultCoordinates'];
+if (empty($exerciseResultCoordinates)) {
+    //$exerciseResultCoordinates = $_REQUEST['exerciseResultCoordinates'];
 }
 }
-if ( empty ( $origin ) ) {
-    $origin = $_REQUEST['origin'];
+if (empty($origin)) {
+    $origin = Security::remove_XSS($_REQUEST['origin']);
 }
 }
 
 
 $_SESSION['hotspot_coord']=array();
 $_SESSION['hotspot_coord']=array();
-$newquestionList=$_SESSION['newquestionList'];
-$questionList = $_SESSION['questionList'];
-$exerciseId=$_GET['exerciseId'];
-$exerciseType=$_GET['exerciseType'];
-$questionNum=$_GET['questionnum'];
-$nbrQuestions=$_GET['nbrQuestions'];
+$newquestionList= $_SESSION['newquestionList'];
+$questionList 	= $_SESSION['questionList'];
+$exerciseId		= intval($_GET['exerciseId']);
+$exerciseType	= intval($_GET['exerciseType']);
+$questionNum	= intval($_GET['questionnum']);
+$nbrQuestions	= intval($_GET['nbrQuestions']);
 
 
 //round-up the coordinates
 //round-up the coordinates
 $coords = explode('/',$_GET['hotspot']);
 $coords = explode('/',$_GET['hotspot']);
 $user_array = '';
 $user_array = '';
-foreach ($coords as $coord) {
-    list($x,$y) = explode(';',$coord);
-    $user_array .= round($x).';'.round($y).'/';
+if (is_array($coords) && count($coords)>0){
+	foreach ($coords as $coord) {
+	   	list($x,$y) = explode(';',$coord);
+    	$user_array .= round($x).';'.round($y).'/';
+	}
 }
 }
 $user_array = substr($user_array,0,-1);
 $user_array = substr($user_array,0,-1);
 
 
-if ( isset (  $_GET['choice'] ) ) 
-{ 
-    $choice_value = $_GET['choice'];
+if (isset( $_GET['choice'])){ 
+    $choice_value = intval($_GET['choice']);
 }
 }
 // getting the options by js
 // getting the options by js
-if (empty($choice_value) )
-{
+if (empty($choice_value)) {
 	echo '<script type="text/javascript">'."		
 	echo '<script type="text/javascript">'."		
 		// this works for only radio buttons		
 		// this works for only radio buttons		
 		var f= self.parent.window.document.frm_exercise;
 		var f= self.parent.window.document.frm_exercise;
@@ -95,7 +96,7 @@ if (empty($choice_value) )
 		//alert(choice_js);						
 		//alert(choice_js);						
 								
 								
 	";		
 	";		
-	echo 'window.location.href = "exercise_submit_modal.php?hotspotcoord="+ hotspotcoord + "&hotspot="+ hotspot + "&choice="+ choice_js + "&exerciseId='.$exerciseId.'&questionnum='.$questionNum.'&exerciseType='.$exerciseType.'&origin='.$origin.'gradebook='.$gradebook.'";</script>';
+	echo 'window.location.href = "exercise_submit_modal.php?hotspotcoord="+ hotspotcoord + "&hotspot="+ hotspot + "&choice="+ choice_js + "&exerciseId='.$exerciseId.'&questionnum='.$questionNum.'&exerciseType='.$exerciseType.'&origin='.$origin.'&gradebook='.$gradebook.'";</script>';
 }
 }
 
 
 $choice=array();
 $choice=array();
@@ -111,21 +112,16 @@ if(!is_array($exerciseResult))
 
 
 
 
 // if the user has answered at least one question
 // if the user has answered at least one question
-if(is_array($choice))
-{
-    if($exerciseType == 1)
-    {
+if(is_array($choice)) {
+    if($exerciseType == 1) {
         // $exerciseResult receives the content of the form.
         // $exerciseResult receives the content of the form.
         // Each choice of the student is stored into the array $choice
         // Each choice of the student is stored into the array $choice
         $exerciseResult=$choice; 
         $exerciseResult=$choice; 
-    }
-    else
-    {
+    } else {
         // gets the question ID from $choice. It is the key of the array
         // gets the question ID from $choice. It is the key of the array
         list($key)=array_keys($choice);
         list($key)=array_keys($choice);
         // if the user didn't already answer this question
         // if the user didn't already answer this question
-        if(!isset($exerciseResult[$key]))
-        {
+        if(!isset($exerciseResult[$key])) {
             // stores the user answer into the array
             // stores the user answer into the array
             $exerciseResult[$key]=$choice[$key];   
             $exerciseResult[$key]=$choice[$key];   
         }
         }
@@ -242,8 +238,8 @@ if (!empty($choice_value))
 						//$_SESSION['exerciseResultCoordinates'][$questionId]=$exerciseResultCoordinates;
 						//$_SESSION['exerciseResultCoordinates'][$questionId]=$exerciseResultCoordinates;
 						
 						
 						// we compare only the delineation not the other points
 						// we compare only the delineation not the other points
-						$answer_question= $_SESSION['hotspot_coord'][1];	
-						$answerDestination=  $_SESSION['hotspot_dest'][1];
+						$answer_question	= $_SESSION['hotspot_coord'][1];	
+						$answerDestination	= $_SESSION['hotspot_dest'][1];
 						
 						
                         $poly_user = convert_coordinates($user_answer,'/');
                         $poly_user = convert_coordinates($user_answer,'/');
                         $poly_answer = convert_coordinates($answer_question,'|');
                         $poly_answer = convert_coordinates($answer_question,'|');
@@ -419,8 +415,7 @@ if (!empty($choice_value))
 
 
 $_SESSION['newquestionList']=$newquestionList;
 $_SESSION['newquestionList']=$newquestionList;
 
 
-if ($choice_value==-1)
-{		
+if ($choice_value==-1) {		
 	$links. '<a href="#" onclick="self.parent.tb_remove();">'.get_lang('ChooseAnAnswer').'</a>';
 	$links. '<a href="#" onclick="self.parent.tb_remove();">'.get_lang('ChooseAnAnswer').'</a>';
 }
 }
 
 
@@ -557,15 +552,11 @@ if ($links!='')
 	//echo '<a onclick="self.parent.tb_remove();" href="#" style="float:right;">'.get_lang('Close').'</a>';
 	//echo '<a onclick="self.parent.tb_remove();" href="#" style="float:right;">'.get_lang('Close').'</a>';
 	echo '</div>';
 	echo '</div>';
 	$_SESSION['hot_spot_result']=$message; 
 	$_SESSION['hot_spot_result']=$message; 
-}
-else
-{
-
+} else {
 	$questionNum++;
 	$questionNum++;
 	echo '<script>
 	echo '<script>
 			self.parent.window.location.href = "exercice_submit.php?exerciseId='.$exerciseId.'&questionNum='.$questionNum.'&exerciseType='.$exerciseType.'&origin='.$origin.'";	  		 	
 			self.parent.window.location.href = "exercice_submit.php?exerciseId='.$exerciseId.'&questionNum='.$questionNum.'&exerciseType='.$exerciseType.'&origin='.$origin.'";	  		 	
    			//self.parent.tb_remove();	  	
    			//self.parent.tb_remove();	  	
- 	 	</script>';
-	
+ 	 	</script>';	
 }
 }
 ?>
 ?>

+ 12 - 20
main/exercice/hotpotatoes.lib.php

@@ -54,7 +54,7 @@ function GetQuizName($fname,$fpath) {
 		if (file_exists($fpath.$fname)) {
 		if (file_exists($fpath.$fname)) {
 			if (!($fp = fopen($fpath.$fname, "r"))) {
 			if (!($fp = fopen($fpath.$fname, "r"))) {
 			//die("could not open Quiz input");
 			//die("could not open Quiz input");
-				return GetFileName($fname);
+				return basename($fname);
 			}
 			}
 	
 	
 			$contents = fread($fp, filesize($fpath.$fname));
 			$contents = fread($fp, filesize($fpath.$fname));
@@ -79,12 +79,19 @@ function GetQuizName($fname,$fpath) {
  * Gets the comment about a file from the corresponding database record
  * Gets the comment about a file from the corresponding database record
  * @param	string	File path
  * @param	string	File path
  * @return	string	Comment from the database record
  * @return	string	Comment from the database record
+ * Added conditional to the table if is empty.
  */
  */
-function GetComment($path) {
+function GetComment($path,$course_code='') {
 	global $dbTable;
 	global $dbTable;
+	
+	if (!empty($course_code)) {		
+		$course_info = api_get_course_info($course_code);
+		$dbTable     = Database::get_course_table(TABLE_DOCUMENT,$course_info['dbName']);	
+	}
 	$path = Database::escape_string($path);
 	$path = Database::escape_string($path);
-	$query = "select comment from $dbTable where path='$path'";
+	$query = "select comment from $dbTable where path='$path'";		
 	$result = api_sql_query($query,__FILE__,__LINE__);
 	$result = api_sql_query($query,__FILE__,__LINE__);
+	
 	while ($row = mysql_fetch_array($result)) {
 	while ($row = mysql_fetch_array($result)) {
 		return $row[0];
 		return $row[0];
 	}
 	}
@@ -101,25 +108,11 @@ function SetComment($path,$comment) {
 	global $dbTable;
 	global $dbTable;
 	$path = Database::escape_string($path);
 	$path = Database::escape_string($path);
 	$comment = Database::escape_string($comment);
 	$comment = Database::escape_string($comment);
-	
 	$query = "UPDATE $dbTable set comment='$comment' where path='$path'";
 	$query = "UPDATE $dbTable set comment='$comment' where path='$path'";
 	$result = api_sql_query($query,__FILE__,__LINE__);
 	$result = api_sql_query($query,__FILE__,__LINE__);
 	return "$result";
 	return "$result";
 }
 }
 
 
-/**
- * Get the name of the file from a path (without the extension)
- *
- * This assumes the path is made of elements split by '/', not '\' or '\\'
- * @param	string	Path
- * @return	string	File name
- */
-function GetFileName($fname) {
-	$name = explode('/',$fname);
-	$name = $name[sizeof($name)-1];
-	return $name;
-}
-
 /**
 /**
  * Reads the file contents into a string
  * Reads the file contents into a string
  * @param	string	Urlencoded path
  * @param	string	Urlencoded path
@@ -165,7 +158,6 @@ function WriteFileCont($full_file_path,$content) {
  * Gets the name of an img whose path is given (without directories or extensions)
  * Gets the name of an img whose path is given (without directories or extensions)
  * @param	string	An image tag (<img src="...." ...>)
  * @param	string	An image tag (<img src="...." ...>)
  * @return	string	The image file name or an empty string
  * @return	string	The image file name or an empty string
- * @uses GetFileName No comment
  */
  */
 function GetImgName($imgtag) {	
 function GetImgName($imgtag) {	
     // select src tag from img tag
     // select src tag from img tag
@@ -180,7 +172,7 @@ function GetImgName($imgtag) {
 		if ($src=="") {
 		if ($src=="") {
 			return "";
 			return "";
 		} else {
 		} else {
-			$tmp_src = GetFileName($src) ;
+			$tmp_src = basename($src) ;
 			if ($tmp_src == "") {
 			if ($tmp_src == "") {
 				return $src;
 				return $src;
 			} else {
 			} else {
@@ -304,7 +296,7 @@ function ReplaceImgTag($content) {
 			else {
 			else {
 
 
 				$prehref = $imgname;
 				$prehref = $imgname;
-				$posthref = GetFileName($imgname);
+				$posthref = basename($imgname);
 				$newcontent = str_replace($prehref,$posthref,$newcontent);
 				$newcontent = str_replace($prehref,$posthref,$newcontent);
 			}
 			}
 		}
 		}

+ 1 - 1
main/exercice/showinframes.php

@@ -84,7 +84,7 @@ WriteFileCont($full_file_path.$_user['user_id'].".t.html",$newcontent);
 	$newcontent = str_replace($prehref,$posthref,$newcontent);
 	$newcontent = str_replace($prehref,$posthref,$newcontent);
 */
 */
 
 
-$doc_url = GetFolderPath($doc_url).urlencode(GetFileName($doc_url));
+$doc_url = GetFolderPath($doc_url).urlencode(basename($doc_url));
 //	echo $documentWebPath.$doc_url.$_user['user_id'].".t.html";
 //	echo $documentWebPath.$doc_url.$_user['user_id'].".t.html";
 //	exit;
 //	exit;
 ?>
 ?>

+ 1 - 1
main/exercice/testheaderpage.php

@@ -18,7 +18,7 @@ $my_file=str_replace(array('../','\\..','\\0','..\\'),array('','','',''),urldeco
 
 
 $title = GetQuizName($my_file,$documentPath);
 $title = GetQuizName($my_file,$documentPath);
 if ($title =='') {
 if ($title =='') {
-	$title = GetFileName($my_file);
+	$title = basename($my_file);
 }
 }
 $nameTools = $title;
 $nameTools = $title;
 $noPHP_SELF=true;
 $noPHP_SELF=true;

+ 22 - 16
main/forum/forumfunction.inc.php

@@ -3898,23 +3898,28 @@ function get_thread_user_post($course_db, $thread_id, $user_id )
  	$j=0;
  	$j=0;
 	$forums = get_forums();	
 	$forums = get_forums();	
 	krsort($forums);
 	krsort($forums);
-	$forum_results = '';	
+	$forum_results = '';
+	
  	foreach($forums as $forum) {	
  	foreach($forums as $forum) {	
 		if ($j<=4) { 		
 		if ($j<=4) { 		
-	 		$threads = get_threads($forum['forum_id']); 		
+	 		$threads = get_threads($forum['forum_id']);
+		
 	 		if (is_array($threads)) {	 			
 	 		if (is_array($threads)) {	 			
 	 			/*echo Display::return_icon('forum.gif'); 		
 	 			/*echo Display::return_icon('forum.gif'); 		
 	 			echo $forum['forum_title'];*/
 	 			echo $forum['forum_title'];*/
-	 			$my_course_db=explode('_',$course_db);
-	 			$my_course_code=$my_course_db[1];	 			 
+	 			//$my_course_db=explode('_',$course_db);
+	 			//$my_course_code=$my_course_db[1];
+	 			$my_course_code=CourseManager::get_course_id_by_database_name($course_db);	 			 
 	 			$i=0;
 	 			$i=0;
 	 			$hand_forums = ''; 	
 	 			$hand_forums = ''; 	
 	 			$post_counter = 0;		 			
 	 			$post_counter = 0;		 			
 		 		foreach($threads as $thread) {
 		 		foreach($threads as $thread) {
 		 				if ($i<=4) {
 		 				if ($i<=4) {
 			 				$post_list = get_thread_user_post_limit($course_db, $thread['thread_id'], $user_id, 1);
 			 				$post_list = get_thread_user_post_limit($course_db, $thread['thread_id'], $user_id, 1);
+			 				
 			 				$post_counter = count($post_list);	
 			 				$post_counter = count($post_list);	
 			 				if (is_array($post_list) && count($post_list)>0) {
 			 				if (is_array($post_list) && count($post_list)>0) {
+			 					
 			 					$hand_forums.= '<div id="social-thread">';
 			 					$hand_forums.= '<div id="social-thread">';
 				 				$hand_forums.= Display::return_icon('forumthread.gif'); 	
 				 				$hand_forums.= Display::return_icon('forumthread.gif'); 	
 				 				$hand_forums.= $thread['thread_title'].' ';
 				 				$hand_forums.= $thread['thread_title'].' ';
@@ -3930,17 +3935,18 @@ function get_thread_user_post($course_db, $thread_id, $user_id )
 			 			$hand_forums.= '</div>';
 			 			$hand_forums.= '</div>';
 		 			}	
 		 			}	
 		 			$i++;
 		 			$i++;
-				}
-				if ($post_counter > 0 ) {
-					$forum_results .='<div id="social-forum">';
-	 				$forum_results .='<div class="clear"></div><br />';
-	 				$forum_results .='<div class="actions" style="margin-left:5px;margin-right:5px;">'.Display::return_icon('forum.gif').'&nbsp;&nbsp;&nbsp;&nbsp;'.$forum['forum_title'].'&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<div style="float:right;margin-top:-18px"><a href="../forum/viewforum.php?cidReq='.$my_course_code.'&gidReq=&forum='.$forum['forum_id'].' " >'.get_lang('SeeForum').'</a></div></div>';
-	 				$forum_results .='<br / >';					
-					$forum_results .=$hand_forums;
-					$forum_results .='</div>'; 
-				}
-	 		}	 		
- 		} $j++;		
+				
+					if ($post_counter > 0 ) {
+						$forum_results .='<div id="social-forum">';
+		 				$forum_results .='<div class="clear"></div><br />';
+		 				$forum_results .='<div class="actions" style="margin-left:5px;margin-right:5px;">'.Display::return_icon('forum.gif').'&nbsp;&nbsp;&nbsp;&nbsp;'.$forum['forum_title'].'&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<div style="float:right;margin-top:-18px"><a href="../forum/viewforum.php?cidReq='.$my_course_code.'&gidReq=&forum='.$forum['forum_id'].' " >'.get_lang('SeeForum').'</a></div></div>';
+		 				$forum_results .='<br / >';					
+						$forum_results .=$hand_forums;
+						$forum_results .='</div>'; 
+					}
+	 			}	 		
+ 			} $j++;		
+ 		}
  	}
  	}
  	return $forum_results;
  	return $forum_results;
  }
  }
@@ -3957,7 +3963,7 @@ function get_thread_user_post_limit($course_db, $thread_id, $user_id, $limit=10)
 							AND posts.poster_id='".Database::escape_string($user_id)."'					
 							AND posts.poster_id='".Database::escape_string($user_id)."'					
 						ORDER BY posts.post_id DESC LIMIT $limit ";
 						ORDER BY posts.post_id DESC LIMIT $limit ";
 	$result=api_sql_query($sql, __FILE__, __LINE__);
 	$result=api_sql_query($sql, __FILE__, __LINE__);
-	
+
 	while ($row=Database::fetch_array($result)) {
 	while ($row=Database::fetch_array($result)) {
 		$row['status'] = '1';
 		$row['status'] = '1';
 		$post_list[]=$row;
 		$post_list[]=$row;

+ 1 - 1
main/gradebook/gradebook_result.class.php

@@ -177,7 +177,7 @@ class GradeBookResult
 				$return[$j+$i] = array();
 				$return[$j+$i] = array();
 				$title = GetQuizName($hpresults[$i][1],$document_path);
 				$title = GetQuizName($hpresults[$i][1],$document_path);
 				if ($title =='') {
 				if ($title =='') {
-					$title = GetFileName($hpresults[$i][1]);
+					$title = basename($hpresults[$i][1]);
 				}
 				}
 				if (empty($user_id)) {
 				if (empty($user_id)) {
 					$return[$j+$i]['user'] = $hpresults[$i][0];
 					$return[$j+$i]['user'] = $hpresults[$i][0];

BIN
main/img/wiki/assignment.gif


BIN
main/img/wiki/task.gif


BIN
main/img/wiki/works.gif


+ 11 - 6
main/inc/global.inc.php

@@ -219,6 +219,7 @@ require_once($lib_path.'display.lib.php');
 require_once($lib_path.'text.lib.php');
 require_once($lib_path.'text.lib.php');
 require_once($lib_path.'security.lib.php');
 require_once($lib_path.'security.lib.php');
 require_once($lib_path.'events.lib.inc.php');
 require_once($lib_path.'events.lib.inc.php');
+require_once($lib_path.'media.lib.php');
 
 
 // @todo: this shouldn't be done here. It should be stored correctly during installation
 // @todo: this shouldn't be done here. It should be stored correctly during installation
 if(empty($_configuration['statistics_database']) && $already_installed)
 if(empty($_configuration['statistics_database']) && $already_installed)
@@ -604,16 +605,20 @@ if (is_array($language_files)) {
 			
 			
 			$tbl_admin_languages 	= Database :: get_main_table(TABLE_MAIN_LANGUAGE);	
 			$tbl_admin_languages 	= Database :: get_main_table(TABLE_MAIN_LANGUAGE);	
 			$sql_sub_language='SELECT dokeos_folder FROM '.$tbl_admin_languages.' WHERE parent_id=(SELECT id FROM '.$tbl_admin_languages.' WHERE dokeos_folder="'.Database::escape_string($language_interface).'" AND  ISNULL(parent_id))';
 			$sql_sub_language='SELECT dokeos_folder FROM '.$tbl_admin_languages.' WHERE parent_id=(SELECT id FROM '.$tbl_admin_languages.' WHERE dokeos_folder="'.Database::escape_string($language_interface).'" AND  ISNULL(parent_id))';
+	
 			$rs_sub_language=Database::query($sql_sub_language,__FILE__,__LINE__);
 			$rs_sub_language=Database::query($sql_sub_language,__FILE__,__LINE__);
-			$row_sub_language=Database::result($rs_sub_language,0,'dokeos_folder');
-			
-			$sub_langfile = $langpath.$row_sub_language.'/'.$language_file.'.inc.php';
+			$num_row_sub_language=Database::num_rows($rs_sub_language);
 			
 			
 			if (file_exists($langfile)) {
 			if (file_exists($langfile)) {
-				include $langfile;
-				if (file_exists($sub_langfile)) {
-					include $sub_langfile;
+				include_once $langfile;
+				for ($i=0;$i<$num_row_sub_language;$i++) {
+					$row_sub_language=Database::result($rs_sub_language,$i,'dokeos_folder');
+					$sub_langfile = $langpath.$row_sub_language.'/'.$language_file.'.inc.php';
+					if (file_exists($sub_langfile)) {
+						include_once $sub_langfile;
+					}
 				}
 				}
+				
 			}
 			}
 		}	
 		}	
 	} else {
 	} else {

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

@@ -901,6 +901,7 @@ function update_Db_course($courseDbName)
 	//
 	//
 	$sql = "CREATE TABLE `".$TABLEWIKICONF . "` (
 	$sql = "CREATE TABLE `".$TABLEWIKICONF . "` (
 		page_id int NOT NULL default 0,		
 		page_id int NOT NULL default 0,		
+		task text NOT NULL,
 		feedback1 text NOT NULL,
 		feedback1 text NOT NULL,
 		feedback2 text NOT NULL,
 		feedback2 text NOT NULL,
 		feedback3 text NOT NULL,
 		feedback3 text NOT NULL,

Файлын зөрүү хэтэрхий том тул дарагдсан байна
+ 3453 - 0
main/inc/lib/asciimath/ASCIIMathML.js


+ 363 - 0
main/inc/lib/asciimath/asciimath.html

@@ -0,0 +1,363 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
+          "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<title>ASCIIMathML: Math on the web for everyone</title>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<script type="text/javascript" src="ASCIIMathML.js"></script>
+<style type="text/css">
+#menu, #title, #subtitle, #author, .display {text-align: center}
+body {font-family: Arial; background-color:beige}
+p,table {font-family: Times}
+</style>
+</head>
+<body>
+
+<div id="menu">
+| <a href="asciimath.html">Home Page</a> |
+<a href="asciimathsyntax.html">Syntax</a> |
+<a href="asciimathdemo.html">Try it</a> |
+<a href="asciimathcalculator.html">Calculator</a> |
+<a href="http://mathcs.chapman.edu/~jipsen/mathml/asciimathdownload.html">Download</a> |
+<a href="http://mathcs.chapman.edu/~jipsen/math/index.php/ASCIIMathML/ASCIIMathGraphs.html">Graphs</a> |
+<a href="http://mathcs.chapman.edu/~jipsen/math/index.php/ASCIIMathML/ASCIIMathFAQ.html">ASCIIMath FAQ</a> |
+<a href="http://mathcs.chapman.edu/~jipsen/math/index.php/ASCIIMathML/ASCIIMathMLSandbox.html">Sandbox</a> |
+<a href="http://mathcs.chapman.edu/~jipsen/math/index.php/ASCIIMathML/ASCIIMathCommentsAndSuggestions.html">Comments</a> |
+</div>
+
+<hr/>
+
+<h2 id="title">
+ASCIIMathML.js (ver 2.0): Translating ASCII math notation to MathML
+and graphics</h2>
+
+<h4 align="center">
+Would you or your students like to <i>easily</i> produce
+<i>good-looking</i> math formulas on webpages<br/>
+using a <i>simple</i> calculator-style syntax and your 
+own ASCII or HTML editor?
+<br/>
+Here is a free multi-platform solution (and if you prefer it, 
+LaTeX-style formulas also work).
+</h4>
+
+<center>
+<b><font color="red">Now even easier to use:</font> 
+<font color="green"> just add one line to your 
+HTML file to load ASCIIMathML.js
+</font></b><p>
+ASCIIMathML.js is mentioned on the <a
+href="http://www.w3.org/Math/">MathML</a> page of the <a
+href="http://www.w3.org/">World Wide Web Consortium</a>, also on <a
+href="http://mathforge.net/index.jsp">mathforge.net</a> and <a
+href="http://mathforum.org/library/resource_types/typesetting/">The
+Math Forum.</a>
+</p>
+
+<font color="red"><b>New:</b></font> Now with <b>automatic math recognition</b>
+mode, better LaTeX support and graphics integration<br/>
+A <a href="http://mathcs.chapman.edu/~jipsen/math/index.php/ASCIIMathML/ASCIIMathMLMoodleFilter.html">Moodle filter</a> and a <a href="http://mathcs.chapman.edu/~jipsen/math/index.php/ASCIIMathML/ASCIIMathMLPmWikiCookbook.html">PmWiki cookbook</a> are also available<br/>
+<a href="http://www.pierce.ctc.edu/dlippman/asciimathtex/AMT.html">ASCIIMath Image Fallback Scripts</a> by David Lippman (including a Moodle filter)<br/>
+and a <a href="http://www.maths.nottingham.ac.uk/personal/drw/lm.html">LaTeXMathML</a> version of ASCIIMathML by <a href="http://www.maths.nottingham.ac.uk/personal/drw/">Dr Douglas R. Woodall</a> 
+(<a href="http://www.maths.nott.ac.uk/personal/drw/lmtest.html">examples</a>)
+<br />
+<a href="http://math.chapman.edu/~jipsen/asciencepad/asciencepad.html">ASciencePad</a> is a WYSIWYG editor that integrates
+
+<a href="http://www.tiddlywiki.com/">TiddlyWiki</a>, ASCIIMathML and ASCIIsvg graphs.<br />
+It's free and works locally (no installation or server required).<br />
+Useful information about <a 
+href="http://www.maths.ed.ac.uk/~james/ASCIIMathMLinfo.html">ASCIIMathML</a> 
+by <a href="http://www.maths.ed.ac.uk/~james/">James Gray</a>, including 
+a nice <a href="http://www.maths.ed.ac.uk/~james/ASCIIMathTutorial.html">tutorial</a>.<br />
+ASCIIMathML also works with <a href="http://www.meyerweb.com/eric/tools/s5/">S5</a> (CSS 
+Presentation slide show; <a href="http://math.chapman.edu/~jipsen/talks/MathFest2005/JipsenMathFestSlides2005.html">S5 ASCIIMath example</a>)<br/> 
+
+and in valid
+<a href="http://math.chapman.edu/~jipsen/mathml/asciimathandmathmlsvg.xhtml">
+XHTML pages with standard MathML and SVG</a> in several browsers.
+<br/>
+ASCIIMathML is being used with Movable Type, WordPress, phpBB, and many wikis.
+<br/>
+Also available: A PHP port of ASCIIMathML.js to <a 
+href="http://www.jcphysics.com/ASCIIMath/">ASCIIMathPHP</a> by <a 
+href="mailto:kc56@cornell.edu">Steven Chan</a>.
+</center>
+
+<p>
+
+This is the main page (HTML version) for the ASCIIMathML.js script which allows
+incorporating mathematical formulas on webpages with a minimum of
+fuss (just add one line to a webpage to load the script). 
+If you like what you see, choose <b>Save As...</b> in your browser
+and this page should work equally well locally on your machine.
+</p>
+
+<p class="display">
+<b>
+This page requires Internet Explorer 6 + <a href=
+"http://www.dessci.com/en/products/mathplayer/welcome.asp">MathPlayer</a>
+or Netscape7.1/Mozilla/Firefox.
+</b>
+</p>
+
+<p>
+ASCIIMathML.js is freely available under the <a
+href="http://www.gnu.org/licenses/lgpl.html">GNU Lesser General Public
+License</a>. You can get your own copy from the <a href=
+"http://www.chapman.edu/~jipsen/mathml/asciimathdownload/">ASCIIMathML.js
+download page</a>. The script works with both HTML and XHTML webpages. 
+(The homepage for an XML 
+version is at <a href="asciimath.xml">asciimath.xml</a> but is no 
+longer maintained).
+
+</p>
+
+<p>
+If you use it on a webpage, please send me an email at <a
+href="mailto:jipsen@chapman.edu">jipsen@chapman.edu</a> with the URL
+so that I can add a link to it on the <a 
+href="http://math.chapman.edu/cgi-bin/mathxml.pl?Webpages_that_use_ASCIIMathML.js">users page</a>. 
+(Also send me an
+email if you have problems or would like to provide some feedback.)
+I'm currently using ASCIIMathML on a Wikiserver for lecture notes and
+<!--a href="http://math.chapman.edu/cgi-bin/mathxml.pl?Calculus_Text_Puzzles">Text
+Puzzles</a>. M-->my students are also using it in Moodle
+for writing and reading homework in their calculus class and 
+discrete mathematics class.
+<font color="red">
+If you just want to display MathML on HTML pages using 
+Netscape/Mozilla/Firefox or IE+MathPlayer, have a look at <a 
+href="http://www1.chapman.edu/~jipsen/mathml/mathhtml">mathhtmltest</a>
+(the page includes a 50 line JavaScript program that does the trick).
+</font>
+</p>
+
+<hr/>
+
+<p>
+<b>Let's test the ASCIIMathML.js translator on a simple example.</b>
+</p>
+
+<p>amath
+<b>Example:</b> Solving the quadratic equation. 
+Suppose a x^2+b x+c=0 and a!=0. We first 
+divide by \a to get x^2+b/a x+c/a=0. 
+
+Then we complete the square and obtain x^2+b/a x+(b/(2a))^2-(b/(2a))^2+c/a=0. 
+The first three terms factor to give (x+b/(2a))^2=(b^2)/(4a^2)-c/a.
+Now we take square roots on both sides and get
+x+b/(2a)=+-sqrt((b^2)/(4a^2)-c/a).
+
+Finally we subtract b/(2a) from both sides and simplify to get 
+the two solutions: x_(1,2)=(-b+-sqrt(b^2 - 4a c))/(2a)
+</p>
+endamath
+
+<p>
+<b>Here is the text that was typed in (<font color="red">using the new 
+auto-math-recognize mode</font> started by "a``math"):</b>
+
+</p>
+
+<pre>amath
+<b>Example:</b> Solving the quadratic equation.
+Suppose a x^2+b x+c=0 and a!=0. We first divide by \a to get x^2+b/a x+c/a=0. 
+
+Then we complete the square and obtain x^2+b/a x+(b/(2a))^2-(b/(2a))^2+c/a=0. 
+The first three terms factor to give (x+b/(2a))^2=(b^2)/(4a^2)-c/a.
+Now we take square roots on both sides and get x+b/(2a)=+-sqrt((b^2)/(4a^2)-c/a).
+
+Finally we move the b/(2a) to the right and simplify to get 
+the two solutions: x_(1,2)=(-b+-sqrt(b^2-4a c))/(2a)
+</pre>
+
+<hr/>
+
+<center>
+<b>
+If you don't believe this, copy the text and paste it on the 
+<a href="asciimathdemo.html">ASCIIMathML.js: Try it yourself</a> demo page.
+</b>
+
+</center>
+
+<hr/>
+
+<h4>
+Here are a few more examples:
+</h4>
+
+<table id="examples" border="5" cellpadding="10">
+<tr>
+<th>Type this</th>
+<th>See that</th>
+<th>Comment</th>
+</tr>
+
+<tr>
+<td>\`x^2+y_1+z_12^34\`</td>
+<td>`x^2+y_1+z_12^34`</td>
+<td>subscripts as in TeX, but numbers are treated as a unit</td>
+</tr>
+<tr>
+<td>\`sin^-1(x)\`</td>
+<td>`sin^-1(x)`</td>
+<td>function names are treated as constants</td>
+</tr>
+<tr>
+
+<td>\`d/dxf(x)=lim_(h->0)(f(x+h)-f(x))/h\`</td>
+<td>`d/dxf(x)=lim_(h->0)(f(x+h)-f(x))/h`</td>
+<td>complex subscripts are bracketed, displayed under lim</td>
+</tr>
+<tr>
+<td>\$\frac{d}{dx}f(x)=\lim_{h\to 0}\frac{f(x+h)-f(x)}{h}\$</td>
+<td>$\frac{d}{dx}f(x)=\lim_{h\to 0}\frac{f(x+h)-f(x)}{h}$</td>
+<td>standard LaTeX notation is an alternative</td>
+</tr>
+<tr>
+<td>\`f(x)=sum_(n=0)^oo(f^((n))(a))/(n!)(x-a)^n\`</td>
+
+<td>`f(x)=sum_(n=0)^oo(f^((n))(a))/(n!)(x-a)^n`</td>
+<td>f^((n))(a) must be bracketed, else the numerator is only `a`</td>
+</tr>
+<tr>
+<td>\$f(x)=\sum_{n=0}^\infty\frac{f^{(n)}(a)}{n!}(x-a)^n\$</td>
+<td>$f(x)=\sum_{n=0}^\infty\frac{f^{(n)}(a)}{n!}(x-a)^n$</td>
+<td>standard LaTeX produces the same result</td>
+</tr>
+<tr>
+<td>\`int_0^1f(x)dx\`</td>
+<td>`int_0^1f(x)dx`</td>
+
+<td>subscripts must come before superscripts</td>
+</tr>
+<tr>
+<td>\`[[a,b],[c,d]]((n),(k))\`</td>
+<td>`[[a,b],[c,d]]((n),(k))`</td>
+<td>matrices and column vectors are simple to type</td>
+</tr>
+<tr>
+<td>\`x/x={(1,if x!=0),(text{undefined},if x=0):}\`</td>
+<td>`x/x={(1,if x!=0),(text{undefined},if x=0):}`</td>
+<td>piecewise defined function are based on matrix notation</td>
+
+</tr>
+<tr>
+<td>\`a//b\`</td>
+<td>`a//b`</td>
+<td>use // for inline fractions</td>
+</tr>
+<tr>
+<td>\`(a/b)/(c/d)\`</td>
+<td>`(a/b)/(c/d)`</td>
+<td>with brackets, multiple fraction work as expected</td>
+</tr>
+
+<tr>
+<td>\`a/b/c/d\`</td>
+<td>`a/b/c/d`</td>
+<td>without brackets the parser chooses this particular expression</td>
+</tr>
+<tr>
+<td>\`((a*b))/c\`</td>
+<td>`((a*b))/c`</td>
+<td>only one level of brackets is removed; * gives standard product</td>
+</tr>
+<tr>
+
+<td>\`sqrt sqrt root3x\`</td>
+<td>`sqrt sqrt root3x`</td>
+<td>spaces are optional, only serve to split strings that should not match</td>
+</tr>
+<tr>
+<td>\`<< a,b >> and {:(x,y),(u,v):}\`</td>
+<td>`<< a,b >> and {:(x,y),(u,v):}`</td>
+<td>angle brackets and invisible brackets</td>
+</tr>
+<tr>
+<td>\`(a,b]={x in RR | a < x <= b}\`</td>
+
+<td>`(a,b]={x in RR | a < x <= b}`</td>
+<td>grouping brackets don't have to match</td>
+</tr>
+<tr>
+<td>\`abc-123.45^-1.1\`</td>
+<td>`abc-123.45^-1.1`</td>
+<td>non-tokens are split into single characters,<br/>
+but decimal numbers are parsed with possible sign</td>
+</tr>
+
+<tr>
+<td>\`hat(ab) bar(xy) ulA vec v dotx ddot y\`</td>
+<td>`hat(ab) bar(xy) ulA vec v dotx ddot y`</td>
+<td>accents can be used on any expression (work well in IE)</td>
+</tr>
+<tr>
+<td>\`bb{AB3}.bbb(AB].cc(AB).fr{AB}.tt[AB].sf(AB)\`</td>
+<td>`bb{AB3}.bbb(AB].cc(AB).fr{AB}.tt[AB].sf(AB)`</td>
+<td>font commands; can use any brackets around argument</td>
+</tr>
+<tr>
+
+<td>\`stackrel"def"= or \stackrel{\Delta}{=}" "("or ":=)\`</td>
+<td>`stackrel"def"= or \stackrel{\Delta}{=}" "("or ":=)`</td>
+<td>symbols can be stacked</td>
+</tr>
+<tr>
+<td>\`{::}_(\ 92)^238U\`</td>
+<td>`{::}_(\ 92)^238U`</td>
+<td>prescripts simulated by subsuperscripts</td>
+</tr>
+</table>
+
+<p>
+If you are familiar with MathML, you can appreciate that this ASCII
+input form is less verbose and more readable. If you are familiar with
+TeX, this is still somewhat less cluttered. The aim is to have input
+notation that is close to graphing calculator notation, so that
+students are able to use it on webpages and in emails without having
+to learn another specialized syntax.
+</p>
+
+<p>
+For an explicit description of the input syntax see <a
+href="asciimathsyntax.html">ASCIIMathML.js Syntax and List of
+Constants</a>.
+</p>
+
+<p>
+<b>Acknowledgements:</b> Many thanks to the numerous people who have
+contributed to the fantastic MathML standard. Without such a
+well designed standard, a project like this would be impossible.<br/>
+
+Thanks to the many volunteers who implemented MathML in the
+Gecko layout engine for Netscape7/Mozilla/Firefox.<br/> 
+
+
+Thanks to the people at Design Science for producing the excellent
+MathPlayer plugin and making it freely available.<br/>
+
+Finally, thanks to the designers and implementors of JavaScript.  All
+these tools work together fairly seemlessly to allow us to put
+mathematical formulas on webpages in a convenient and inexpensive way.<br/>
+
+And thanks to Andrew White for making a logo for ASCIIMathML (see below).
+</p>
+<hr/>
+
+<div id="author">
+<a href="http://www.chapman.edu/~jipsen/">Peter Jipsen</a>, 
+<a href="http://www.chapman.edu/">Chapman University</a>, September 2007
+
+<a href="http://validator.w3.org/check/referer"><img border="0"
+src="http://www.w3.org/Icons/valid-html401"
+alt="Valid HTML 4.01!" height="31" width="88"></a>
+</div>
+
+<p><div class="display">
+<a style="color:white" href="../asciimath.html">
+<img src="asciimathml.jpeg" alt="ASCIIMathML"></a>
+</div>
+</body>
+</html>

+ 118 - 0
main/inc/lib/asciimath/asciimathcalculator.html

@@ -0,0 +1,118 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
+          "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<title>ASCIIMath Calculator Demo</title>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<script type="text/javascript" src="ASCIIMathML.js"></script>
+<!--script type="text/javascript">mathfontsize=".9em"</script-->
+<style type="text/css">
+#menu, #title, #subtitle, #author {text-align: center}
+body {font-family: Arial; background-color:beige}
+p,table {font-family: Times}
+</style>
+</head>
+<body>
+
+<div id="menu">
+| <a href="asciimath.html">Home Page</a> |
+<a href="asciimathsyntax.html">Syntax</a> |
+<a href="asciimathdemo.html">Try it</a> |
+<a href="asciimathcalculator.html">Calculator</a> |
+<a href="http://mathcs.chapman.edu/~jipsen/mathml/asciimathdownload.html">Download</a> |
+<a href="http://mathcs.chapman.edu/~jipsen/math/index.php/ASCIIMathML/ASCIIMathGraphs.html">Graphs</a> |
+<a href="http://mathcs.chapman.edu/~jipsen/math/index.php/ASCIIMathML/ASCIIMathFAQ.html">ASCIIMath FAQ</a> |
+<a href="http://mathcs.chapman.edu/~jipsen/math/index.php/ASCIIMathML/ASCIIMathMLSandbox.html">Sandbox</a> |
+<a href="http://mathcs.chapman.edu/~jipsen/math/index.php/ASCIIMathML/ASCIIMathCommentsAndSuggestions.html">Comments</a> |
+</div>
+
+<hr/>
+
+<h2 id="title">
+ASCIIMath Scientific Calculator (ver 1.2)
+</h2>
+
+<h4 align="center">
+A free webpage calculator with live MathML display
+</h4>
+
+<h4 align="center">
+This page requires Internet Explorer 6+<a 
+href="http://www.dessci.com/en/products/mathplayer">MathPlayer</a> 
+or Mozilla/Firefox/Netscape 7+.
+</h4>
+
+<div class="ASCIIMathCalculator"></div>
+
+<p>
+More calculator areas:<br>
+<textarea id="in1" rows="2" cols="40" onkeyup="calculate('in1','out1')">
+2sin^-1(1)</textarea> &nbsp; <span id="out1"></span>
+<p/>
+
+<p>
+<textarea id="in2" rows="2" cols="30" 
+onkeyup="calculate('in2','out2');calculate('in3','out3')">
+a=5; b=4; c=-1; (-b+sqrt(b^2-4a*c))/(2a)
+</textarea> &nbsp; <span id="out2"></span>
+<br/>
+<textarea id="in3" rows="1" cols="30" 
+onkeyup="calculate('in2','out2');calculate('in3','out3')">
+(-b-sqrt(b^2-4a*c))/(2a)</textarea> &nbsp; <span id="out3"></span>
+
+</p>
+
+<p>
+<b>Note that this is dynamic HTML running locally on your machine.</b>
+<br/>
+Right-click on the output to copy or view the MathML code (or have it
+<b>spoken</b> in IE+MathPlayer).
+</p>
+
+<p>
+<b>Some technical remarks:</b> This calculator works only in radians.
+(Multiply angles by pi/180 to convert from degrees to radians.)
+<br/>
+
+The syntax is loosely based on JavaScript and a subset of ASCIIMathML.
+<br/>
+The multiplication symbol * can be omitted after a digit (0-9) 
+or a closing parenthesis.
+<br/>
+Available constants and functions: 
+<br/>
+&nbsp; &nbsp; +, -, *, /, ^, pi, e, sqrt(), ln(), abs(), sign(), 
+floor(), ceil(), n!, C(n,k), ran(a,b,n)
+<br/>
+&nbsp; &nbsp; sin(), cos(), tan(), sin^-1(), cos^-1(), tan^-1(), 
+sinh(), cosh(), tanh(), sinh^-1(), cosh^-1(), tanh^-1()
+<br/>
+&nbsp; &nbsp; sec(), csc(), cot(), sec^-1(), csc^-1(), cot^-1(),
+sech(), csch(), coth(), sech^-1(), csch^-1(), coth^-1()
+
+<br/>
+Values can be assigned to (legal JavaScript) variable names. 
+Use ";" to separate expressions.
+<br/>
+Any number of calculator textareas can be placed anywhere on <b>your own</b> 
+webpages.
+</p>
+ASCIIMathML and this calculator are freely available under the 
+<a href="http://www.gnu.org/licenses/lgpl.html">GNU Lesser General
+Public License</a>. Please include a link to <a
+href="http://asciimathml.sourceforge.net">asciimathml.sourceforge.net</a>
+on any webpage that makes use of them, and send a link of your webpage
+to <a href="mailto:jipsen@chapman.edu">jipsen@chapman.edu</a>.
+
+<hr/>
+
+<div id="author">
+<a href="http://www.chapman.edu/~jipsen/">Peter Jipsen</a>, 
+<a href="http://www.chapman.edu/">Chapman University</a>, May 2007
+
+<a href="http://validator.w3.org/check/referer"><img border="0"
+src="http://www.w3.org/Icons/valid-html401"
+alt="Valid HTML 4.01!" height="31" width="88"></a>
+</div>
+</body>
+</html>

+ 227 - 0
main/inc/lib/asciimath/asciimathchanges.txt

@@ -0,0 +1,227 @@
+Changes file for ASCIIMathML.js
+===============================
+
+Sep 27, 2007 Version 2.0
+(at http://www.chapman.edu/~jipsen/mathml/ASCIIMathML20.js)
+
+- included LaTeXMathML.js and ASCIIsvg.js in the ASCIIMathML script
+
+- changed license to GNU LGPL 2.1
+
+- Added auto-math-recognize mode (amath ... endamath)
+
+- Added some LaTeX environments and simple formatting
+
+- Created Moodle filter and PmWiki cookbook
+
+- Added MathML text labels to SVG graphs
+
+- Fixed SVG cursor tracking in Firefox
+
+- Added stroke/fillopacity to graphs
+
+- Simplified syntax for graph inclusion
+
+- SVG mouseevents are now added in the scope of the graph code
+
+- MathML fontsize can now be magnified relative to surrounding text
+
+-------------------------------
+
+Aug 7, 2005 Version 1.4.7
+(at http://www.chapman.edu/~jipsen/mathml/ASCIIMathML147.js)
+
+- changed IE MathML prefix from mml: to m: (default of MathPlayer, so now
+  <html> works without the xmlns attribute)
+
+- for IE the script now writes out the <object ...> and <?import ...> tags
+  simplifying the header file significantly 
+
+- script now uses a generic onload (by www.brothercake.com) so 
+  no need for onload="translate()" in <body> (but earlier pages still work)
+
+- ASCIIMathML.js can now be used on any HTML page by just adding one line to
+  load the script. So validating your HTML pages is now possible, and use
+  of HTML editors is simple.
+
+- added unparametrized macros: put <script>newcommand("short","long")</script>
+  on your webpage and each occurrence of "short" is replaced by "long"
+
+- added /_ (\angle) and :. (\therefore) as symbols
+
+- made an ASCIIMath plugin for Xinha HTML editor (see editor link on homepage)
+  with instant preview, template popup and builtin calculator
+
+-------------------------------
+
+Apr 23, 2005 Version 1.4.6
+(at http://www.chapman.edu/~jipsen/mathml/ASCIIMathML146.js)
+
+- added "showasciiformulaonhover" variable; if true then pointing at a MathML 
+  expression shows the ascii form that produces the expression
+
+- added "decimalsign" variable; default is "."
+
+- removed "separatetokens" option (to speed up token recognition)
+
+- changed |-, |=, |_, _| to |--, |==, |__, __| to avoid parsing problems
+  e.g. |-x|, |x|=a, ||A||_1 now parse as expected
+
+- changed parser so that "-" is unary if previous token is INFIX
+  e.g. now x^-y works like x^(-y) (but x-y is same as x - y)
+
+- added "spanclassAM" option; invoked by translate(true), all math should
+  then be delimited by <span class="AM">...</span>; translate() works as before
+
+-------------------------------
+
+Jan 30, 2005 Version 1.4.5
+(at http://www.chapman.edu/~jipsen/mathml/ASCIIMathML145.js)
+
+- added TEXT token type for \text{...}, \mbox{...} and "..."
+
+- changed sin, cos, tan, ..., lcm to UNARY type (func); now 1/sinx works
+
+- changed parser so that ^, _ have priority over /
+  now x_1/3^2 works like (x_1)/(3^2)
+
+-------------------------------
+
+Jan 14, 2005 Version 1.4.4
+(at http://www.chapman.edu/~jipsen/mathml/ASCIIMathML144.js)
+
+- added "mathfontfamily" variable (default "serif")
+
+- mathcolor and mathfontfamily can be "" to inherit values of surrounding text
+
+- added "AMdelimiter" variables to set math delimiters (default "`" and "$")
+
+- added LEFTRIGHT token type for "|"; now `|x|` displays like `{:|x|:}`;
+  a single | still parses as \mid e.g. in {x | x > 0}
+
+-------------------------------
+
+Dec 28, 2004 Version 1.4.3
+(at http://www.chapman.edu/~jipsen/mathml/ASCIIMathML143.js)
+
+- added mapsto |->
+
+- fixed a parsing error that was generated by incomplete fractions (1/)
+
+- fixed parsing of negative numbers (<mn>-1</mn> is now translated to
+  <mrow><mo>-</mo><mn>1</mn></mrow>)
+
+- added notifyIfNoMathML flag. If false, no note is inserted at top of page.
+
+- included ASCIIMathCalculator.js: a small script that implements a
+  webpage calculator with live MathML preview
+
+-------------------------------
+
+Nov 12, 2004 Version 1.4.2
+(at http://www.chapman.edu/~jipsen/mathml/ASCIIMathML142.js)
+
+- added constants for: setminus, vdots, ddots, glb, lub
+
+-------------------------------
+
+Aug 16, 2004 Version 1.4.1
+(at http://www.chapman.edu/~jipsen/mathml/ASCIIMathML141.js)
+
+- fixed a typo to make the check for MathML capability work correctly
+
+- added stackrel command (mover in MathML), e.g. stackrel{def}{=}
+
+- added := as binary relation to get spacing right in Mozilla/Firefox/Netscape
+
+-------------------------------
+
+July 13, 2004 Version 1.4
+(at http://www.chapman.edu/~jipsen/mathml/ASCIIMathML4.js)
+
+- cleaned up the js code, thanks to some very helpful suggestions by Alex V. 
+
+- most global variables prefixed with "AM" to avoid conflict with ASCIIsvg.js
+
+- added macro definition ability to define dx, dy, dz, ...
+  e.g. now dx is replaced by {d x}, so `d/dx` can be used rather than `d/(dx)`.
+  Users can add their own (parameterless) macros.
+
+- added check for MathML capability. If absent, inserts note at top of page.
+
+- unmatched right bracket no longer ends expression. E.g. in `cosx]_0^1`
+  the "]" is treated simply as a constant symbol (better to use `{:cosx]_0^1`).
+
+- numeric unicode entity names can be used for unnamed symbols, e.g. `&#x2270;`
+
+-------------------------------
+
+Mar 26, 2004 Version 1.3
+(at http://www.chapman.edu/~jipsen/mathml/ASCIIMathML3.js)
+
+- fixed parser so that unary/binary symbols without arguments are treated 
+  as constants (previously generated js error)
+
+- noticed that ASCIIMathML.js does not require XML, actually works in HTML
+  on multiple browsers (required no change to the script)
+
+- added `"any"` as alternative to `text{any}`
+
+- added  min, max  as standard function names (subscripts go underneath)
+
+- added o. (\odot) as symbol
+
+- added separatetokens flag: lowercase tokens must be separated by nonletters
+  (if true, `sinx` is a sequence of 4 variables, instead use `sin x`)
+  switched off by default, can be switched on (see top of ASCIIMathML.js)
+
+- added (experimental) doubleblankmathdelimiter so  a+b  is same as `a+b`
+  switched off by default, can be switched on (see top of ASCIIMathML.js)
+
+-------------------------------
+
+Feb 8, 2004 Version 1.2
+(at http://www.chapman.edu/~jipsen/mathml/ASCIIMathML2.js)
+
+- added accents: hat bar ul vec dot ddot
+
+- added sans-serif font: sf
+
+- both `...` and $...$ are now allowed as math delimiters
+
+- \$ and \` can now be used to insert $ or ` in plain text
+
+- `a text{ sometext }b` now shows the space around "sometext"
+
+- blocks of ASCIIMathML + text can be enclosed in comments <!-- -->
+  in which case blank lines are converted to paragraph breaks;
+  inside comments the < character can be used (does not cause XML error)
+  (use this "comment mode" with caution; future versions of IE or
+   Mozilla may not display it the same way)
+
+-------------------------------
+
+Jan 9, 2004 Version 1.1
+(at http://www.chapman.edu/~jipsen/mathml/ASCIIMathML1.js)
+
+- added \vdash, \models (actually &vDash;!), \vartheta, \bigwedge, \bigvee,
+  \bigcup, \bigcap, \propto, \oint to symbol table, with ASCII equivalents
+
+- renamed "subset, supset" to their entity names "sube, supe", 
+  added "sub, sup" and their LaTeX equivalents \subset, \supset
+
+- updated webpages
+
+-------------------------------
+
+Jan 6, 2004 Version 1.0 
+(now at http://www.chapman.edu/~jipsen/mathml/ASCIIMathML0.js)
+
+- calligraphic, black board bold and fraktur fonts are finally working 
+  also in Mozilla/Netscape 7
+
+- added a download page
+
+- added GNU GPL notices
+
+===============================

+ 117 - 0
main/inc/lib/asciimath/asciimathdemo.html

@@ -0,0 +1,117 @@
+<html>
+<head>
+<title>ASCIIMathML.js demo</title>
+<script type="text/javascript" src="ASCIIMathML.js"></script>
+<script type="text/javascript">
+translateOnLoad=false;
+function display() {
+  var str = document.getElementById("inputText").value;
+  var outnode = document.getElementById("outputNode");
+  var n = outnode.childNodes.length;
+  for (var i=0; i<n; i++)
+    outnode.removeChild(outnode.firstChild);
+  outnode.appendChild(document.createTextNode(str));
+  AMprocessNode(outnode);
+}
+</script>
+<style type="text/css">
+#menu, #title, #subtitle, #author {text-align: center}
+body {font-family: Arial; background-color:beige;}
+</style>
+</head>
+<body onload="display()">
+
+<div id="menu">
+| <a href="asciimath.html">Home Page</a> |
+<a href="asciimathsyntax.html">Syntax</a> |
+<a href="asciimathdemo.html">Try it</a> |
+<a href="asciimathcalculator.html">Calculator</a> |
+<a href="http://mathcs.chapman.edu/~jipsen/mathml/asciimathdownload.html">Download</a> |
+<a href="http://mathcs.chapman.edu/~jipsen/math/index.php/ASCIIMathML/ASCIIMathGraphs.html">Graphs</a> |
+<a href="http://mathcs.chapman.edu/~jipsen/math/index.php/ASCIIMathML/ASCIIMathFAQ.html">ASCIIMath FAQ</a> |
+<a href="http://mathcs.chapman.edu/~jipsen/math/index.php/ASCIIMathML/ASCIIMathMLSandbox.html">Sandbox</a> |
+<a href="http://mathcs.chapman.edu/~jipsen/math/index.php/ASCIIMathML/ASCIIMathCommentsAndSuggestions.html">Comments</a> |
+</div>
+
+<hr/>
+
+<h2 id="title">
+ASCIIMathML.js: Try it yourself (HTML version)
+</h2>
+
+<center>
+<b>
+This page requires Internet Explorer 6+<a 
+href="http://www.dessci.com/en/products/mathplayer">MathPlayer</a> 
+or Mozilla/Firefox/Netscape 7+.
+</b>
+<p>
+Edit the formulas below (the display updates dynamically).
+If you know (La)TeX formula syntax, you can try some of that as well
+(LaTeX formulas work best when enclosed in $-signs).
+The "amath" token switches on the new auto-math-recognize mode.</p>
+
+<form>
+<textarea id="inputText" rows="10" cols="80" onkeyup="display()">
+amath
+
+Let's try some interesting formulas: E=m c^2
+and e^(i pi)=-1
+and AA x in CC (sin^2x+cos^2x=1)
+and one more: sum_(i=1)^n i^3=((n(n+1))/2)^2
+
+(add your own -- note that text-tokens are only recognized if separated by spaces)
+
+</textarea>
+</form>
+
+<p>
+<div id="outputNode"></div>
+</p>
+
+<hr/>
+<p>
+<b>Note that this is dynamic XHTML running locally on your machine!</b>
+<br>
+Right-click on an output formula to copy or view the MathML code.
+</p>
+</center>
+(Copy and paste the following lines to see what symbols they produce)<br/>
+<b>You can use the following ASCIIMathML constructs:</b> 
+<tt> `(x+1)/(x-1) x^(i+j) x_(ij) sqrt(x) root(n)(x) stackrel(+)(->) text(any) "any"`</tt><br/>
+<b>Operation symbols</b> 
+<tt> `+ - * ** // \\ xx -: @ o+ ox sum prod ^^ ^^^ vv vvv nn nnn uu uuu`</tt><br/>
+<b>Relation symbols</b>
+<tt> `= != &lt; &lt;= > >= -&lt; >- in !in sub sup sube supe -= ~= ~~ prop`</tt><br/>
+<b>Logical symbols</b><tt> `\and \or \not => if iff AA EE _|_ TT |-- |==`</tt><br/>
+<b>Miscellaneous symbols</b> 
+<tt> `int oint del grad +- O/ oo aleph ... cdots \  quad qquad diamond square |__ __| |~ ~| CC NN QQ RR ZZ`</tt><br/>
+<b>Standard functions</b> 
+<tt> `sin cos tan csc sec cot sinh cosh tanh log ln det dim lim mod gcd lcm`</tt><br/>
+<b>Grouping brackets</b><tt> `( ) [ ] { } (: :) {: :}` </tt> 
+<b>Arrows</b><tt> `uarr darr rarr -> larr harr rArr lArr hArr` </tt><br/>
+<b>Accents</b><tt> `hatx barx ulx vecx dotx ddotx` </tt>
+<b>Font commands</b><tt> `bbA bbbA ccA ttA frA sfA` </tt>
+<b>Matrices</b><tt> `[[a,b],[c,d]] ((1,0),(0,1))` </tt><br/>
+<b>Greek letters</b><tt> `alpha beta chi delta Delta epsi eta gamma Gamma
+iota kappa lambda Lambda mu nu omega Omega phi Phi pi Pi psi rho sigma Sigma 
+tau theta Theta upsilon xi Xi zeta`</tt> 
+
+<p>
+This demo page shows that ASCIIMathML.js can be used easily to
+dynamically preview mathematical formulas (client-side). E.g. here is a
+(beta) webpage that can be used to <b><a
+href="http://math.chapman.edu/email/">write and read
+mathematical emails and discussion group articles</a></b>. Since most
+email communication is still done with ASCII text (or at least not yet
+with XHTML), this is a reasonable (and inexpensive) solution for
+communicating with students in online math courses.
+</p>
+
+<hr/>
+<div id="author">
+<a href="http://www.chapman.edu/~jipsen/">Peter Jipsen</a>, 
+<a href="http://www.chapman.edu/">Chapman University</a>, September 2007
+</div>
+</body>
+</html>

+ 76 - 0
main/inc/lib/asciimath/asciimathextend.html

@@ -0,0 +1,76 @@
+<html>
+<head>
+<title>Extending ASCIIMathML</title>
+<script type="text/javascript" src="ASCIIMathML.js"></script>
+
+<script type="text/javascript">
+define("!<=","\u2270")
+define("!>=","\u2271")
+newcommand("\\nle","\u2270")
+newcommand("\\nge","\u2271")
+</script>
+</head>
+<body bgcolor="beige">
+
+<h2>ASCIIMathML.js: Extending the symbol table</h2>
+
+<p>
+The standard symbol table of ASCIIMathML.js does not contain many symbols.
+It can be extended by adding additional symbols on any webpage that 
+requires them. This is done by adding a few lines of JavaScript code.
+
+</p>
+
+<p>
+For example, suppose we want to add symbols for "not less or equal" and
+"not greater or equal".
+</p>
+
+<p>
+We first have to find the four-digit hexadecimal Unicode value for
+these symbols by looking them up at, say, <a
+href="http://www.w3.org/TR/MathML2/chapter6.html#chars.entity.tables">http://www.w3.org/TR/MathML2/chapter6.html#chars.entity.tables</a>
+</p>
+
+<p>
+Next we have to decide what input strings we want to associate with these
+symbols, say "!<=" and "!>=".
+</p>
+
+<p>
+Finally we add the following lines to the head or body of our HTML file:
+<pre style="border-style:groove">&lt;script type="text/javascript">
+define("!<=","\u2270")
+define("!>=","\u2271")
+&lt;/script>
+</pre>
+</p>
+
+<p>
+Here we test the modified symbol table: 
+<tt>\`a !<= b !>= c\`</tt> produces `a !<= b !>= c`
+</p>
+
+<p>To add a symbol to the LaTeX commands, use the following alternate syntax:
+<pre style="border-style:groove">&lt;script type="text/javascript">
+newcommand("\\nle","\u2270")
+newcommand("\\nge","\u2271")
+&lt;/script>
+</pre>
+</p>
+
+<p>
+Now 
+<tt>\$a \nle b \nge c\$</tt> produces $a \nle b \nge c$.
+</p>
+
+<hr/>
+<p>
+If you know the numeric entity reference of the symbol you want to use
+on an ASCIIMathML webpage, you can also refer to the symbol directly
+by using that reference. E.g \`&amp;#x2270;\` produces `&#x2270;`.
+If a symbol is only used occasionally, this is certainly the simplest
+way to include it.
+</p>
+</body>
+</html>

+ 38 - 0
main/inc/lib/asciimath/asciimathsample.html

@@ -0,0 +1,38 @@
+<html xmlns:mml="http://www.w3.org/1998/Math/MathML">
+<head>
+<script type="text/javascript" src="ASCIIMathML.js"></script>
+<title>ASCIIMathML sample page</title>
+</head>
+<body>
+
+<h2>ASCIIMathML.js sample page</h2>
+
+<p>
+Use auto-math-recognize mode (amath here x^2 and text is 
+mixed endamath) or surround ASCIIMath formulas 
+with left-quotes: 
+`sum_(i=1)^n i=(n(n+1))/2` or LaTeX formulas with \$-signs 
+$\int_0^{\pi/2} \sin x\,dx=1$.
+</p>
+
+<p>
+And here is a simple graph:
+
+agraph plot(sin(x)) endagraph
+
+followed by a more elaborate graph (try double-clicking it, also 
+while holding down shift or alt)
+
+agraph
+width=300; height=200; xmin=-5; xmax=5; xscl=1;
+plot((x-2)*(x-1)*x*(x+1)*(x+2)/2,-2.5,2.5);
+endagraph
+</p>
+
+<p>
+Note: this page uses a relative link to ASCIIMathML.js, 
+so the script should be in the same folder as this sample file.
+</p>
+
+</body>
+</html>

+ 506 - 0
main/inc/lib/asciimath/asciimathsyntax.html

@@ -0,0 +1,506 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
+          "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<title>ASCIIMathML: Syntax and constants</title>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<script type="text/javascript" src="ASCIIMathML.js"></script>
+<style type="text/css">
+#menu, #title, #subtitle, #author {text-align: center}
+body {font-family: Arial; background-color:beige}
+p,table {font-family: Times}
+</style>
+</head>
+<body>
+
+<div id="menu">
+| <a href="asciimath.html">Home Page</a> |
+<a href="asciimathsyntax.html">Syntax</a> |
+<a href="asciimathdemo.html">Try it</a> |
+<a href="asciimathcalculator.html">Calculator</a> |
+<a href="http://mathcs.chapman.edu/~jipsen/mathml/asciimathdownload.html">Download</a> |
+<a href="http://mathcs.chapman.edu/~jipsen/math/index.php/ASCIIMathML/ASCIIMathGraphs.html">Graphs</a> |
+<a href="http://mathcs.chapman.edu/~jipsen/math/index.php/ASCIIMathML/ASCIIMathFAQ.html">ASCIIMath FAQ</a> |
+<a href="http://mathcs.chapman.edu/~jipsen/math/index.php/ASCIIMathML/ASCIIMathMLSandbox.html">Sandbox</a> |
+<a href="http://mathcs.chapman.edu/~jipsen/math/index.php/ASCIIMathML/ASCIIMathCommentsAndSuggestions.html">Comments</a> |
+</div>
+
+<hr/>
+
+<h2 id="title">
+ASCIIMathML.js (ver 2.0): Syntax and List of Constants
+</h2>
+
+<h4 id="subtitle">
+The main aims of the ASCIIMathML syntax are: -- 1. close to standard
+mathematical notation -- 2. easy to read -- 3. easy to type
+</h4>
+
+<p>
+You can use your favorite editor to write HTML pages that use this
+JavaScript program. If the page is viewed by a browser that does not
+support MathML or JavaScript, the ASCII formulas are still quite
+readable. Most users will not have to read the technicalities on
+this page. If you type
+</p>
+
+<pre>amath x^2 or a_(m n) or a_{m n} or (x+1)/y or sqrtx endamath</pre>
+
+<p>
+you pretty much get what you expect: amath x^2 or a_(m n) or a_{m n} or
+(x+1)/y or sqrtx endamath. The a``math ... enda``math tokens are used to
+start/stop the <b>new auto-math-recognize mode</b>. Of course one can still use
+the \`...\` back-quotes to delimit math formulas explicitly
+(\$...\$ should only be used for LaTeX formulas). 
+The choice of grouping parenthesis is up to you
+(they don't have to match either). If the displayed expression can be
+parsed uniquely without them, they are omitted. Printing the table of
+constant symbols (below) may be helpful (but is not necessary if you
+know the LaTeX equivalents).
+</p>
+
+<p>
+It is hoped that this simple input format for MathML will further
+encourage its use on the web. The remainder of this page gives a fairly
+detailed specification of the ASCII syntax. <b>The expressions described here
+correspond to a wellspecified subset of Presentation MathML and behave
+in a predictable way.</b>
+</p>
+
+<p>
+The syntax is very permissive and does not generate syntax
+errors. This allows mathematically incorrect expressions to be
+displayed, which is important for teaching purposes. It also causes
+less frustration when previewing formulas.
+</p>
+
+<p>
+The parser uses no operator precedence and only respects the grouping
+brackets, subscripts, superscript, fractions and (square) roots. This
+is done for reasons of efficiency and generality. The resulting MathML
+code can quite easily be processed further to ensure additional syntactic
+requirements of any particular application.
+</p>
+
+<p>
+<b>The grammar:</b> Here is a definition of the grammar used to parse
+ASCIIMathML expressions. In the Backus-Naur form given below, the
+letter on the left of the ::= represents a category of symbols that
+could be one of the possible sequences of symbols listed on the right.
+The vertical bar | separates the alternatives.
+</p>
+
+<pre>c ::= [A-z] | numbers | greek letters | other constant symbols (see below)
+u ::= 'sqrt' | 'text' | 'bb' |     other unary symbols for font commands
+b ::= 'frac' | 'root' | 'stackrel' binary symbols
+l ::= ( | [ | { | (: | {:          left brackets
+r ::= ) | ] | } | :) | :}          right brackets
+S ::= c | lEr | uS | bSS | "any"   simple expression
+E ::= SE | S/S |S_S | S^S | S_S^S  expression (fraction, sub-, super-, subsuperscript)
+</pre>
+
+<p>
+<b>The translation rules:</b> Each terminal symbol is translated into
+a corresponding MathML node. The constants are mostly converted to
+their respective Unicode symbols. The other expressions are converted
+as follows:<br/>
+<table>
+<tr><td>l`S`r</td><td>`to`</td><td>&lt;mrow>l`S`r&lt;/mrow> 
+(note that any pair of brackets can be used to delimit subexpressions, 
+they don't have to match)</td></tr>
+<tr><td>sqrt `S`</td><td>`to`</td><td>&lt;msqrt>`S'`&lt;/msqrt></td></tr>
+
+<tr><td>text `S`</td><td>`to`</td><td>&lt;mtext>`S'`&lt;/mtext></td></tr>
+<tr><td>"any"</td><td>`to`</td><td>&lt;mtext>any&lt;/mtext></td></tr>
+<tr><td>
+frac `S_1` `S_2`</td><td>`to`</td><td>&lt;mfrac>`S_1'` `S_2'`&lt;/mfrac>
+</td></tr>
+<tr><td>
+
+root `S_1` `S_2`</td><td>`to`</td><td>&lt;mroot>`S_2'` `S_1'`&lt;/mroot>
+</td></tr>
+<tr><td>
+stackrel `S_1` `S_2`</td><td>`to`</td><td>&lt;mover>`S_2'` `S_1'`&lt;/mover>
+</td></tr>
+<tr><td>
+`S_1`/`S_2`</td><td>`to`</td><td>&lt;mfrac>`S_1'` `S_2'`&lt;/mfrac>
+</td></tr>
+
+<tr><td>
+`S_1`_`S_2`</td><td>`to`</td><td>&lt;msub>`S_1` `S_2'`&lt;/msub>
+</td></tr>
+<tr><td>
+`S_1`^`S_2`</td><td>`to`</td><td>&lt;msup>`S_1` `S_2'`&lt;/msup>
+</td></tr>
+<tr><td>
+`S_1`_`S_2`^`S_3`</td><td>`to`</td>
+<td>&lt;msubsup>`S_1` `S_2'` `S_3'`&lt;/msubsup> or
+
+&lt;munderover>`S_1` `S_2'` `S_3'`&lt;/munderover> (in some cases)
+</td></tr>
+</table>
+In the rules above, the expression `S'` is the same as `S`, except that if
+`S` has an outer level of brackets, then `S'` is the expression inside 
+these brackets.
+
+<p>
+<b>Matrices:</b> A simple syntax for matrices is also recognized:
+<br/>
+<tt>l(`S_(11)`,...,`S_(1n)`),(...),(`S_(m1)`,...,`S_(mn)`)r</tt>
+&#x00A0; &#x00A0; or &#x00A0; &#x00A0;
+
+<tt>l[`S_(11)`,...,`S_(1n)`],[...],[`S_(m1)`,...,`S_(mn)`]r</tt>.
+<br/>
+
+Here <tt>l</tt> and <tt>r</tt> stand for any of the left and right
+brackets (just like in the grammar they do not have to match). Both of
+these expressions are translated to
+<br/>
+
+&lt;mrow>l&lt;mtable>&lt;mtr>&lt;mtd>`S_(11)`&lt;/mtd>...
+
+&lt;mtd>`S_(1n)`&lt;/mtd>&lt;/mtr>...
+&lt;mtr>&lt;mtd>`S_(m1)`&lt;/mtd>... 
+&lt;mtd>`S_(mn)`&lt;/mtd>&lt;/mtr>&lt;/mtable>r&lt;/mrow>.
+<br/>
+
+For example 
+<tt>{(S_(11),...,S_(1n)),(vdots,ddots,vdots),(S_(m1),...,S_(mn))]</tt>
+displays as `{(S_(11),...,S_(1n)),(vdots,ddots,vdots),(S_(m1),...,S_(mn))]`.
+
+<br/>
+
+Note that each row must have the same number of expressions, and there
+should be at least two rows.
+
+<p>
+<b>Tokenization:</b> The input formula is broken into tokens using a
+"longest matching initial substring search". Suppose the input formula
+has been processed from left to right up to a fixed position. The
+longest string from the list of constants (given below) that matches
+the initial part of the remainder of the formula is the next token. If
+there is no matching string, then the first character of the remainder
+is the next token. The symbol table at the top of the ASCIIMathML.js
+script specifies whether a symbol is a math operator (surrounded by a
+&lt;mo> tag) or a math identifier (surrounded by a &lt;mi> tag). For
+single character tokens, letters are treated as math identifiers, and
+non-alphanumeric characters are treated as math operators. For digits,
+see "Numbers" below.
+
+<p>
+Spaces are significant when they separate characters and thus prevent
+a certain string of characters from matching one of the
+constants. Multiple spaces and end-of-line characters are equivalent
+to a single space.
+</p>
+
+<h4>
+Now for a complete list of constants (<a
+href="http://math.chapman.edu/cgi-bin/mathxml.pl?Complete_list_of_LaTeX_constants">standard
+LaTeX names</a> also work):
+
+</h4> 
+
+<p>
+Numbers: A string of digits, optionally preceded by a minus sign, and
+optionally followed by a decimal point (a period) and another string
+of digits, is parsed as a single token and converted to a MathML
+number, i.e., enclosed with the &lt;mn> tag. If it is not desirable to 
+have a preceding minus sign be part of the number, a space should be inserted.
+Thus <tt>x-1</tt> is converted to &lt;mi>x&lt;/mi>&lt;mn>-1&lt;/mn>, whereas
+<tt>x - 1</tt> is converted to &lt;mi>x&lt;/mi>&lt;mo>-&lt;/mo>&lt;mn>1&lt;/mn>.
+
+</p>
+
+<p>
+Greek letters:
+alpha `alpha`
+beta `beta`
+chi `chi`
+delta `delta`
+Delta `Delta`
+epsilon `epsilon`
+varepsilon `varepsilon`
+eta `eta`
+gamma `gamma`
+Gamma `Gamma`
+iota `iota`
+kappa `kappa`
+lambda `lambda`
+Lambda `Lambda`
+mu `mu`
+nu `nu`
+omega `omega`
+Omega `Omega`
+phi `phi`
+varphi `varphi`
+Phi `Phi`
+pi `pi`
+Pi `Pi`
+psi `psi`
+Psi `Psi`
+rho `rho`
+sigma `sigma`
+Sigma `Sigma`
+tau `tau`
+theta `theta`
+vartheta `vartheta`
+Theta `Theta`
+upsilon `upsilon`
+xi `xi`
+Xi `Xi`
+zeta `zeta`
+</p>
+
+<table border="5" cellpadding="10">
+<tr valign="top"><td>
+Operation symbols
+<table border="5" cellpadding="10">
+<tr><th>Type</th><th>See</th></tr>
+<tr><td>+</td><td>`+`</td></tr>
+<tr><td>-</td><td>`-`</td></tr>
+
+<tr><td>*</td><td>`*`</td></tr>
+<tr><td>**</td><td>`**`</td></tr>
+<tr><td>//</td><td>`//`</td></tr>
+<tr><td>\\</td><td>`\\ `</td></tr>
+<tr><td>xx</td><td>`xx`</td></tr>
+<tr><td>-:</td><td>`-:`</td></tr>
+
+<tr><td>@</td><td>`@`</td></tr>
+<tr><td>o+</td><td>`o+`</td></tr>
+<tr><td>ox</td><td>`ox`</td></tr>
+<tr><td>o.</td><td>`o.`</td></tr>
+<tr><td>sum</td><td>`sum`</td></tr>
+<tr><td>prod</td><td>`prod`</td></tr>
+
+<tr><td>^^</td><td>`^^`</td></tr>
+<tr><td>^^^</td><td>`^^^`</td></tr>
+<tr><td>vv</td><td>`vv`</td></tr>
+<tr><td>vvv</td><td>`vvv`</td></tr>
+<tr><td>nn</td><td>`nn`</td></tr>
+<tr><td>nnn</td><td>`nnn`</td></tr>
+
+<tr><td>uu</td><td>`uu`</td></tr>
+<tr><td>uuu</td><td>`uuu`</td></tr>
+</table>
+</td><td>
+Relation symbols
+<table border="5" cellpadding="10">
+<tr><th>Type</th><th>See</th></tr>
+<tr><td>=</td><td>`=`</td></tr>
+<tr><td>!=</td><td>`!=`</td></tr>
+
+<tr><td>< </td><td>`<`</td></tr>
+<tr><td>></td><td>`>`</td></tr>
+<tr><td><=</td><td>`<=`</td></tr>
+<tr><td>>=</td><td>`>=`</td></tr>
+<tr><td>-<</td><td>`-<`</td></tr>
+
+<tr><td>>-</td><td>`>-`</td></tr>
+<tr><td>in</td><td>`in`</td></tr>
+<tr><td>!in</td><td>`notin`</td></tr>
+<tr><td>sub</td><td>`sub`</td></tr>
+<tr><td>sup</td><td>`sup`</td></tr>
+<tr><td>sube</td><td>`sube`</td></tr>
+
+<tr><td>supe</td><td>`supe`</td></tr>
+<tr><td>-=</td><td>`-=`</td></tr>
+<tr><td>~=</td><td>`~=`</td></tr>
+<tr><td>~~</td><td>`~~`</td></tr>
+<tr><td>prop</td><td>`prop`</td></tr>
+</table>
+</td><td>
+
+Logical symbols
+<table border="5" cellpadding="10">
+<tr><th>Type</th><th>See</th></tr>
+<tr><td>and</td><td>`and`</td></tr>
+<tr><td>or</td><td>`or`</td></tr>
+<tr><td>not</td><td>`not`</td></tr>
+<tr><td>=></td><td>`=>`</td></tr>
+
+<tr><td>if</td><td>`if`</td></tr>
+<tr><td>iff</td><td>`iff`</td></tr>
+<tr><td>AA</td><td>`AA`</td></tr>
+<tr><td>EE</td><td>`EE`</td></tr>
+<tr><td>_|_</td><td>`_|_`</td></tr>
+<tr><td>TT</td><td>`TT`</td></tr>
+
+<tr><td>|--</td><td>`|--`</td></tr>
+<tr><td>|==</td><td>`|==`</td></tr>
+</table>
+<p>
+Grouping brackets
+<table border="5" cellpadding="10">
+<tr><th>Type</th><th>See</th></tr>
+<tr><td>(</td><td>`(`</td></tr>
+<tr><td>)</td><td>`)`</td></tr>
+
+<tr><td>[</td><td>`[`</td></tr>
+<tr><td>]</td><td>`]`</td></tr>
+<tr><td>{</td><td>`{`</td></tr>
+<tr><td>}</td><td>`}`</td></tr>
+<tr><td>(:</td><td>`(:`</td></tr>
+<tr><td>:)</td><td>`:)`</td></tr>
+
+<tr><td>{:</td><td>`{:`</td></tr>
+<tr><td>:}</td><td>`{::}`</td></tr>
+</table>
+
+</td><td>
+Miscellaneous symbols
+<table border="5" cellpadding="10">
+<tr><th>Type</th><th>See</th></tr>
+<tr><td>int</td><td>`int`</td></tr>
+
+<tr><td>oint</td><td>`oint`</td></tr>
+<tr><td>del</td><td>`del`</td></tr>
+<tr><td>grad</td><td>`grad`</td></tr>
+<tr><td>+-</td><td>`+-`</td></tr>
+<tr><td>O/</td><td>`O/`</td></tr>
+<tr><td>oo</td><td>`oo`</td></tr>
+
+<tr><td>aleph</td><td>`aleph`</td></tr>
+<tr><td>/_</td><td>`/_`</td></tr>
+<tr><td>:.</td><td>`:.`</td></tr>
+<tr><td>|...|</td><td>|`...`|</td></tr>
+<tr><td>|cdots|</td><td>|`cdots`|</td></tr>
+<tr><td>vdots</td><td>`vdots`</td></tr>
+
+<tr><td>ddots</td><td>`ddots`</td></tr>
+<tr><td>|\ |</td><td>|`\ `|</td></tr>
+<tr><td>|quad|</td><td>|`quad`|</td></tr>
+<tr><td>diamond</td><td>`diamond`</td></tr>
+<tr><td>square</td><td>`square`</td></tr>
+<tr><td>|__</td><td>`|__`</td></tr>
+
+<tr><td>__|</td><td>`__|`</td></tr>
+<tr><td>|~</td><td>`|~`</td></tr>
+<tr><td>~|</td><td>`~|`</td></tr>
+<tr><td>CC</td><td>`CC`</td></tr>
+<tr><td>NN</td><td>`NN`</td></tr>
+<tr><td>QQ</td><td>`QQ`</td></tr>
+
+<tr><td>RR</td><td>`RR`</td></tr>
+<tr><td>ZZ</td><td>`ZZ`</td></tr>
+</table>
+</td><td>
+Standard functions
+<table border="5" cellpadding="10">
+<tr><th>Type</th><th>See</th></tr>
+<tr><td>sin</td><td>`sin`</td></tr>
+<tr><td>cos</td><td>`cos`</td></tr>
+
+<tr><td>tan</td><td>`tan`</td></tr>
+<tr><td>csc</td><td>`csc`</td></tr>
+<tr><td>sec</td><td>`sec`</td></tr>
+<tr><td>cot</td><td>`cot`</td></tr>
+<tr><td>sinh</td><td>`sinh`</td></tr>
+<tr><td>cosh</td><td>`cosh`</td></tr>
+
+<tr><td>tanh</td><td>`tanh`</td></tr>
+<tr><td>log</td><td>`log`</td></tr>
+<tr><td>ln</td><td>`ln`</td></tr>
+<tr><td>det</td><td>`det`</td></tr>
+<tr><td>dim</td><td>`dim`</td></tr>
+<tr><td>lim</td><td>`lim`</td></tr>
+
+<tr><td>mod</td><td>`mod`</td></tr>
+<tr><td>gcd</td><td>`gcd`</td></tr>
+<tr><td>lcm</td><td>`lcm`</td></tr>
+<tr><td>min</td><td>`min`</td></tr>
+<tr><td>max</td><td>`max`</td></tr>
+</table>
+<p>
+
+Accents
+<table border="5" cellpadding="10">
+<tr><th>Type</th><th>See</th></tr>
+<tr><td>hat x</td><td>`hat x`</td></tr>
+<tr><td>bar x</td><td>`bar x`</td></tr>
+<tr><td>ul x</td><td>`ul x`</td></tr>
+<tr><td>vec x</td><td>`vec x`</td></tr>
+
+<tr><td>dot x</td><td>`dot x`</td></tr>
+<tr><td>ddot x</td><td>`ddot x`</td></tr>
+</table>
+
+</td><td>
+Arrows
+<table border="5" cellpadding="10">
+<tr><th>Type</th><th>See</th></tr>
+<tr><td>uarr</td><td>`uarr`</td></tr>
+
+<tr><td>darr</td><td>`darr`</td></tr>
+<tr><td>rarr</td><td>`rarr`</td></tr>
+<tr><td>-></td><td>`->`</td></tr>
+<tr><td>|-></td><td>`|->`</td></tr>
+<tr><td>larr</td><td>`larr`</td></tr>
+<tr><td>harr</td><td>`harr`</td></tr>
+
+<tr><td>rArr</td><td>`rArr`</td></tr>
+<tr><td>lArr</td><td>`lArr`</td></tr>
+<tr><td>hArr</td><td>`hArr`</td></tr>
+</table>
+<p>
+Font commands
+<table border="5" cellpadding="10">
+<tr><th>Type</th><th>See</th></tr>
+<tr><td>bb A</td><td>`bb A`</td></tr>
+
+<tr><td>bbb A</td><td>`bbb A`</td></tr>
+<tr><td>cc A</td><td>`cc A`</td></tr>
+<tr><td>tt A</td><td>`tt A`</td></tr>
+<tr><td>fr A</td><td>`fr A`</td></tr>
+<tr><td>sf A</td><td>`sf A`</td></tr>
+</table>
+
+</td></tr>
+</table>
+
+<p>
+Of course you may want or need other symbols from the thousands of <a
+href="http://www.ctan.org/tex-archive/info/symbols/comprehensive/symbols-letter.pdf">LaTeX
+symbols</a> or <a
+href="http://www.alanwood.net/unicode/#links">unicode
+symbols</a>. Fortunately ASCIIMathML.js is very <a
+href="asciimathextend.html">easy
+to extend</a>, so you can tailor it to your specific needs. (This
+could be compared to the LaTeX macro files that many users have
+developed over the years.)
+</p>
+
+<!--p>
+Large files with many formulas can take quite some time to display,
+especially on older hardware. To address this problem, there is a
+version ASCIIMathMLite.js that has a shorter symbol table (without the
+LaTeX symbol names) and slightly simplified parser. Send me an email
+at <a href="mailto:jipsen@chapman.edu">jipsen@chapman.edu</a> if you
+would like a copy.
+</p>
+
+<p>
+Another version that also recognizes some <a
+href="http://www.latex-project.org/">LaTeX</a> layout commands and
+(the fairly standard) <a
+href="http://en.wikipedia.org/wiki/Wikipedia:How_to_edit_a_page">Wiki
+formatting codes</a> for ASCII text is in the works. This further
+simplifies producing mathematical content for the web. However such a
+development is less easily justified since there are good free HTML
+editors and the HTML syntax is a well-established standard that is
+simple enough to be coded by hand.
+</p-->
+
+<hr/>
+
+<div id="author">
+<a href="http://www.chapman.edu/~jipsen/">Peter Jipsen</a>, 
+<a href="http://www.chapman.edu/">Chapman University</a>, September 2007
+
+<a href="http://validator.w3.org/check/referer"><img border="0"
+src="http://www.w3.org/Icons/valid-html401"
+alt="Valid HTML 4.01!" height="31" width="88"></a>
+</div>
+</body>
+</html>

+ 8 - 0
main/inc/lib/asciimath/d.svg

@@ -0,0 +1,8 @@
+<?xml version="1.0" standalone="no"?>
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN" 
+  "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
+<svg id="root" xml:space="preserve" width="100%" height="100%" 
+  preserveAspectRatio="xMidYMid meet"
+  xmlns="http://www.w3.org/2000/svg"
+  xmlns:xlink="http:///www.w3.org/1999/xlink">
+</svg>

+ 44 - 0
main/inc/lib/asciimath/filter.php

@@ -0,0 +1,44 @@
+<?PHP
+/////////////////////////////////////////////////////////////////////////////
+//                                                                         //
+// NOTICE OF COPYRIGHT                                                     //
+//                                                                         //
+// Moodle - Filter for converting asciimath notation to MathML             //
+//                                                                         //
+// Copyright (C) 2007 by Peter Jipsen                                      //
+// 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:                            //
+//                                                                         //
+//          http://www.gnu.org/copyleft/gpl.html                           //
+//                                                                         //
+/////////////////////////////////////////////////////////////////////////////
+//-------------------------------------------------------------------------
+// NOTE: This Moodle text filter uses javascript to process ASCIIMath commands
+// embedded in the text.  Math should be surrounded by `...` or $...$
+// or put    amath ... amathoff   around the whole text to use the
+// experimental auto-math-recognize mode.
+//
+// The filter enables the ASCIIMathML.js code to do most of the work. 
+//
+// A copy of ASCIIMathML (version 2.0 or later) is included and
+// automatically loaded in the file asciimath/javascript.php
+//
+//-------------------------------------------------------------------------
+
+$textfilter_function='asciimath_filter';
+if (function_exists($textfilter_function)) {return;}
+
+function asciimath_filter ($courseid, $text) {
+  global $CFG;
+  $text = '<span id="processasciimathinmoodle" class="'.$CFG->wwwroot.'/filter/asciimath/"></span>'.$text;
+  return $text;
+}
+
+?>

+ 8 - 0
main/inc/lib/asciimath/index.html

@@ -0,0 +1,8 @@
+<!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" xml:lang="en" lang="en">
+<head>
+</head>
+<body>
+<br />
+</body>
+</html>

+ 28 - 0
main/inc/lib/asciimath/javascript.php

@@ -0,0 +1,28 @@
+/////////////////////////////////////////////////////////////////////////////
+//                                                                         //
+// NOTICE OF COPYRIGHT                                                     //
+//                                                                         //
+// Moodle - Filter for converting ASCIImath notation to MathML             //
+// Now also handles a larger subset of LaTeX, as well as ASCIIsvg          //
+//                                                                         //
+// Copyright (C) 2007 by Peter Jipsen                                      //
+// 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:                            //
+//                                                                         //
+//          http://www.gnu.org/copyleft/gpl.html                           //
+//                                                                         //
+/////////////////////////////////////////////////////////////////////////////
+
+// if this script url sniffing does not work try setting wwwroot explicitly
+// var wwwroot = "http://path/to/your/moodledir"
+// or copy the ASCIIMathML.js file into this file.
+
+var wwwroot = document.getElementsByTagName("script")[0].src.replace(/((.*?)\/lib\/.*)/,"$2"); 
+document.write('<script src="'+wwwroot+'/filter/asciimath/ASCIIMathML.js"></script>');

+ 37 - 0
main/inc/lib/asciimath/readme.txt

@@ -0,0 +1,37 @@
+ASCIIMathML.js 
+
+Brief Instructions (2007-9-28)
+
+This script can be used in any html page and also in systems like Moodle.
+The license is LGPL (see top of ASCIIMathML.js for more info).
+
+In a html page, just add the following line near the top of your file:
+<script type="text/javascript" src="ASCIIMathML.js"></script>
+
+To install in Moodle, just move this asciimath-x.y.z folder into moodle/filter,
+rename the folder "asciimath" and go to the admin panel Modules->Filters 
+to switch it on.
+
+Then try some ASCIIMath on your webpages: `x/y` 
+
+or LaTeX $\sqrt{x}$ and $$\int_0^1 x^2 dx$$ (only a \emph{subset} works, 
+including a few environments like \begin{theorem}... and \begin{proof})
+
+Try some graphics like agraph plot(sin(x)) endagraph or 
+\begin{graph}plot(sin(x))\end{graph}
+
+Try the auto-math-recognize mode: amath here we can mix x^2 and text endamath
+
+All this is supposed to work in Firefox on many platforms (recommended; 
+you may be asked to install math fonts) and in Internet Explorer (only 
+on WinXP and you have to install MathPlayer and Adobe SVGview).
+
+For more examples, see http://www.chapman.edu/~jipsen/asciimath.html and
+http://mathcs.chapman.edu/~jipsen/math
+
+If you use this script on the web, please send an email to jipsen@chapman.edu
+and put a link to http://www.chapman.edu/~jipsen/asciimath.html on your page.
+
+Best wishes with ASCIIMathML.js
+
+Peter Jipsen

+ 3 - 2
main/inc/lib/blog.lib.php

@@ -3026,11 +3026,12 @@ function get_blog_post_from_user($course_db_name, $user_id) {
 				ORDER BY post.date_creation DESC ";
 				ORDER BY post.date_creation DESC ";
 		$result = api_sql_query($sql, __FILE__, __LINE__);
 		$result = api_sql_query($sql, __FILE__, __LINE__);
 		$return_data = '';
 		$return_data = '';
-		$my_course_info=explode('_',$course_db_name);
+		//$my_course_info=explode('_',$course_db_name);
+		$my_course_id=CourseManager::get_course_id_by_database_name($course_db_name);	
 		if (Database::num_rows($result)!=0) {
 		if (Database::num_rows($result)!=0) {
 			while ($row=Database::fetch_array($result)) {
 			while ($row=Database::fetch_array($result)) {
 				$return_data.=  '<div class="clear"></div><br />';
 				$return_data.=  '<div class="clear"></div><br />';
-	 			$return_data.=  '<div class="actions" style="margin-left:5px;margin-right:5px;">'.$row['title'].'&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<div style="float:right;margin-top:-18px"><a href="../blog/blog.php?blog_id='.$row['blog_id'].'&gidReq=&cidReq='.$my_course_info[1].' " >'.get_lang('SeeBlog').'</a></div></div>';
+	 			$return_data.=  '<div class="actions" style="margin-left:5px;margin-right:5px;"><img src="../img/blog.gif" />'.$row['title'].'&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<div style="float:right;margin-top:-18px"><a href="../blog/blog.php?blog_id='.$row['blog_id'].'&gidReq=&cidReq='.$my_course_id.' " >'.get_lang('SeeBlog').'</a></div></div>';
 	 			$return_data.=  '<br / >';
 	 			$return_data.=  '<br / >';
 				//$return_data.= '<strong>'.$row['title'].'</strong>'; echo '<br>';
 				//$return_data.= '<strong>'.$row['title'].'</strong>'; echo '<br>';
 				$return_data.= $row['full_text'];
 				$return_data.= $row['full_text'];

+ 29 - 4
main/inc/lib/course.lib.php

@@ -1895,18 +1895,32 @@ class CourseManager {
     /**
     /**
      * Get list of courses for a given user
      * Get list of courses for a given user
      * @param int       user ID
      * @param int       user ID
+     * @param boolean   Whether to include courses from session or not
      * @return array    List of codes and db names
      * @return array    List of codes and db names
      * @author isaac flores paz
      * @author isaac flores paz
      */
      */
-	public static function get_courses_list_by_user_id ($user_id) {
+	public static function get_courses_list_by_user_id ($user_id, $include_sessions=false) {
 		$course_list=array();
 		$course_list=array();
+        $codes = array();
+        $user_id = intval($user_id);
 		$tbl_course			 = Database::get_main_table(TABLE_MAIN_COURSE);
 		$tbl_course			 = Database::get_main_table(TABLE_MAIN_COURSE);
 		$tbl_course_rel_user = Database::get_main_table(TABLE_MAIN_COURSE_USER);
 		$tbl_course_rel_user = Database::get_main_table(TABLE_MAIN_COURSE_USER);
-		$sql='SELECT c.code,c.db_name,c.title FROM '.$tbl_course.' c inner join '.$tbl_course_rel_user.' cru on c.code=cru.course_code  WHERE cru.user_id='.Database::escape_string($user_id);
+		$sql='SELECT c.code,c.db_name,c.title FROM '.$tbl_course.' c inner join '.$tbl_course_rel_user.' cru on c.code=cru.course_code  WHERE cru.user_id='.$user_id;
 		$result=api_sql_query($sql,__FILE__,__LINE__);
 		$result=api_sql_query($sql,__FILE__,__LINE__);
 		while ($row=Database::fetch_array($result,'ASSOC')) {
 		while ($row=Database::fetch_array($result,'ASSOC')) {
-			$course_list[]=$row;			
-		}
+			$course_list[]=$row;
+            $codes[] = $row['code'];
+		}
+        if ($include_sessions === true) {
+            $tbl_csu = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
+            $s = "SELECT distinct(c.code),c.db_name,c.title FROM $tbl_csu s, $tbl_course c WHERE id_user = $user_id AND s.course_code=c.code";
+        	$r = Database::query($s,__FILE__,__LINE__);
+            while ($row=Database::fetch_array($r,'ASSOC')) {
+                if (!in_array($row['code'],$codes)) {
+                    $course_list[]=$row;
+                }
+            }
+        }
 		return $course_list;
 		return $course_list;
 	}
 	}
     /**
     /**
@@ -2115,5 +2129,16 @@ class CourseManager {
 		} else {
 		} else {
 			return false; //field not found
 			return false; //field not found
 		}
 		}
+	}
+	/**
+	 * Get the course id of an course by the database name
+	 * @param string The database name
+	 * @return string The course id
+	 */
+	public static function get_course_id_by_database_name ($db_name) {
+	   $t_course = Database::get_main_table(TABLE_MAIN_COURSE);	
+	   $sql='SELECT code FROM '.$t_course.' WHERE db_name="'.Database::escape_string($db_name).'"';
+	   $rs=Database::query($sql,__FILE__,__LINE__);
+	   return Database::result($rs,0,'code');
 	}	
 	}	
 } //end class CourseManager
 } //end class CourseManager

+ 21 - 38
main/inc/lib/events.lib.inc.php

@@ -105,7 +105,6 @@ function event_login()
 				(login_user_id,
 				(login_user_id,
 				 login_ip,
 				 login_ip,
 				 login_date)
 				 login_date)
-
 				 VALUES
 				 VALUES
 					('".$_user['user_id']."',
 					('".$_user['user_id']."',
 					'".Database::escape_string($_SERVER['REMOTE_ADDR'])."',
 					'".Database::escape_string($_SERVER['REMOTE_ADDR'])."',
@@ -135,28 +134,23 @@ function event_access_course()
 	if(api_get_setting('use_session_mode')=='true' && isset($_SESSION['id_session']))
 	if(api_get_setting('use_session_mode')=='true' && isset($_SESSION['id_session']))
 	{
 	{
 		$id_session = intval($_SESSION['id_session']);
 		$id_session = intval($_SESSION['id_session']);
-	}
+	} 
 	else
 	else
 	{
 	{
 		$id_session = 0;
 		$id_session = 0;
 	}
 	}
 
 
 	$reallyNow = time();
 	$reallyNow = time();
-	if ($_user['user_id'])
-	{
+	if ($_user['user_id']) {
 		$user_id = "'".$_user['user_id']."'";
 		$user_id = "'".$_user['user_id']."'";
-	}
-	else // anonymous
-		{
-		$user_id = "NULL";
+	} else {
+		$user_id = "0"; // no one
 	}
 	}
 	$sql = "INSERT INTO ".$TABLETRACK_ACCESS."
 	$sql = "INSERT INTO ".$TABLETRACK_ACCESS."
 				(access_user_id,
 				(access_user_id,
 				 access_cours_code,
 				 access_cours_code,
 				 access_date)
 				 access_date)
-
 				VALUES
 				VALUES
-
 				(".$user_id.",
 				(".$user_id.",
 				'".$_cid."',
 				'".$_cid."',
 				FROM_UNIXTIME(".$reallyNow."))";
 				FROM_UNIXTIME(".$reallyNow."))";
@@ -214,7 +208,7 @@ function event_access_tool($tool, $id_session=0)
 	}
 	}
 
 
 	$reallyNow = time();
 	$reallyNow = time();
-	$user_id = $_user['user_id'] ? "'".$_user['user_id']."'" : "NULL"; // "NULL" is anonymous
+	$user_id = $_user['user_id'] ? "'".$_user['user_id']."'" : "0"; // no one
 	// record information
 	// record information
 	// only if user comes from the course $_cid
 	// only if user comes from the course $_cid
 	//if( eregi($_configuration['root_web'].$_cid,$_SERVER['HTTP_REFERER'] ) )
 	//if( eregi($_configuration['root_web'].$_cid,$_SERVER['HTTP_REFERER'] ) )
@@ -230,9 +224,7 @@ function event_access_tool($tool, $id_session=0)
 							 access_cours_code,
 							 access_cours_code,
 							 access_tool,
 							 access_tool,
 							 access_date)
 							 access_date)
-
 							VALUES
 							VALUES
-
 							(".$user_id.",".// Don't add ' ' around value, it's already done.
 							(".$user_id.",".// Don't add ' ' around value, it's already done.
 					"'".$_cid."' ,
 					"'".$_cid."' ,
 					'".htmlspecialchars($tool, ENT_QUOTES)."',
 					'".htmlspecialchars($tool, ENT_QUOTES)."',
@@ -285,10 +277,8 @@ function event_download($doc_url)
 	if ($_user['user_id'])
 	if ($_user['user_id'])
 	{
 	{
 		$user_id = "'".$_user['user_id']."'";
 		$user_id = "'".$_user['user_id']."'";
-	}
-	else // anonymous
-		{
-		$user_id = "NULL";
+	} else {
+		$user_id = "0";
 	}
 	}
 	$sql = "INSERT INTO ".$TABLETRACK_DOWNLOADS."
 	$sql = "INSERT INTO ".$TABLETRACK_DOWNLOADS."
 				(
 				(
@@ -323,30 +313,23 @@ function event_upload($doc_id)
 	global $_cid;
 	global $_cid;
 	global $TABLETRACK_UPLOADS;
 	global $TABLETRACK_UPLOADS;
 	// if tracking is disabled record nothing
 	// if tracking is disabled record nothing
-	if (!$_configuration['tracking_enabled'])
-	{
+	if (!$_configuration['tracking_enabled']) {
 		return 0;
 		return 0;
 	}
 	}
 
 
 	$reallyNow = time();
 	$reallyNow = time();
-	if ($_user['user_id'])
-	{
+	if (isset($_user['user_id']) && $_user['user_id']!='') {
 		$user_id = "'".$_user['user_id']."'";
 		$user_id = "'".$_user['user_id']."'";
-	}
-	else // anonymous
-		{
-		$user_id = "NULL";
+	} else {
+		$user_id = "0"; // anonymous
 	}
 	}
 	$sql = "INSERT INTO ".$TABLETRACK_UPLOADS."
 	$sql = "INSERT INTO ".$TABLETRACK_UPLOADS."
-				(
-				 upload_user_id,
-				 upload_cours_id,
-				 upload_work_id,
-				 upload_date
+				( upload_user_id,
+				  upload_cours_id,
+				  upload_work_id,
+				  upload_date
 				)
 				)
-
-				VALUES
-				(
+				VALUES (
 				 ".$user_id.",
 				 ".$user_id.",
 				 '".$_cid."',
 				 '".$_cid."',
 				 '".$doc_id."',
 				 '".$doc_id."',
@@ -375,11 +358,11 @@ function event_link($link_id)
 	}
 	}
 
 
 	$reallyNow = time();
 	$reallyNow = time();
-	if ($_user['user_id']) {
+	if (isset($_user['user_id']) && $_user['user_id']!='') {
 		$user_id = "'".Database::escape_string($_user['user_id'])."'";
 		$user_id = "'".Database::escape_string($_user['user_id'])."'";
 	} else {
 	} else {
 		// anonymous
 		// anonymous
-		$user_id = "NULL";
+		$user_id = "0";
 	}
 	}
 	
 	
 	$sql = "INSERT INTO ".$TABLETRACK_LINKS."
 	$sql = "INSERT INTO ".$TABLETRACK_LINKS."
@@ -445,11 +428,11 @@ function create_event_exercice($exo_id)
 	global $_user, $_cid, $_configuration;
 	global $_user, $_cid, $_configuration;
 	$TABLETRACK_EXERCICES = Database::get_statistic_table(TABLE_STATISTIC_TRACK_E_EXERCICES);
 	$TABLETRACK_EXERCICES = Database::get_statistic_table(TABLE_STATISTIC_TRACK_E_EXERCICES);
 	$reallyNow = time();
 	$reallyNow = time();
-	if ($_user['user_id']) {
+	if (isset($_user['user_id']) && $_user['user_id']!='') {
 		$user_id = "'".$_user['user_id']."'";
 		$user_id = "'".$_user['user_id']."'";
 	} else {
 	} else {
 		// anonymous
 		// anonymous
-		$user_id = "NULL";
+		$user_id = "0";
 	}
 	}
 
 
 	if(defined('ENABLED_LIVE_EXERCISE_TRACKING')){
 	if(defined('ENABLED_LIVE_EXERCISE_TRACKING')){
@@ -500,7 +483,7 @@ function exercise_attempt($score,$answer,$quesId,$exeId,$j)
 	}
 	}
 
 
 	$reallyNow = time();
 	$reallyNow = time();
-	if ($_user['user_id'])
+	if (isset($_user['user_id']) && $_user['user_id']!='')
 	{
 	{
 		$user_id = "'".$_user['user_id']."'";
 		$user_id = "'".$_user['user_id']."'";
 	}
 	}

+ 2 - 2
main/inc/lib/fckeditor/editor/_source/commandclasses/fck_othercommands.js

@@ -40,7 +40,7 @@ var FCKDialogCommand = function( name, title, url, width, height, getStateFuncti
 
 
 FCKDialogCommand.prototype.Execute = function()
 FCKDialogCommand.prototype.Execute = function()
 {
 {
-	FCKDialog.OpenDialog( 'FCKDialog_' + this.Name , this.Title, this.Url, this.Width, this.Height, this.CustomValue, null, this.Resizable ) ;
+	FCKDialog.OpenDialog( 'FCKDialog_' + this.Name , this.Title, this.Url, this.Width, this.Height, this.CustomValue, this.Resizable ) ;
 }
 }
 
 
 FCKDialogCommand.prototype.GetState = function()
 FCKDialogCommand.prototype.GetState = function()
@@ -186,7 +186,7 @@ FCKSourceCommand.prototype.Execute = function()
 	{
 	{
 		var iWidth	= FCKConfig.ScreenWidth * 0.65 ;
 		var iWidth	= FCKConfig.ScreenWidth * 0.65 ;
 		var iHeight	= FCKConfig.ScreenHeight * 0.65 ;
 		var iHeight	= FCKConfig.ScreenHeight * 0.65 ;
-		FCKDialog.OpenDialog( 'FCKDialog_Source', FCKLang.Source, 'dialog/fck_source.html', iWidth, iHeight, null, null, true ) ;
+		FCKDialog.OpenDialog( 'FCKDialog_Source', FCKLang.Source, 'dialog/fck_source.html', iWidth, iHeight, null, true ) ;
 	}
 	}
 	else
 	else
 	    FCK.SwitchEditMode() ;
 	    FCK.SwitchEditMode() ;

+ 4 - 4
main/inc/lib/fckeditor/editor/_source/commandclasses/fcktextcolorcommand.js

@@ -193,9 +193,9 @@ FCKTextColorCommand.prototype._CreatePanelBody = function( targetDocument, targe
 		oDiv.innerHTML = '<table width="100%" cellpadding="0" cellspacing="0" border="0"><tr><td nowrap align="center">' + FCKLang.ColorMoreColors + '</td></tr></table>' ;
 		oDiv.innerHTML = '<table width="100%" cellpadding="0" cellspacing="0" border="0"><tr><td nowrap align="center">' + FCKLang.ColorMoreColors + '</td></tr></table>' ;
 
 
 		FCKTools.AddEventListenerEx( oDiv, 'click', FCKTextColorCommand_MoreOnClick, this ) ;
 		FCKTools.AddEventListenerEx( oDiv, 'click', FCKTextColorCommand_MoreOnClick, this ) ;
+	
+		// Dirty hack for Opera, Safari and Firefox 3.
+		if ( !FCKBrowserInfo.IsIE )
+			oDiv.style.width = '96%' ;
 	}
 	}
-
-	// Dirty hack for Opera, Safari and Firefox 3.
-	if ( !FCKBrowserInfo.IsIE )
-		oDiv.style.width = '96%' ;
 }
 }

+ 178 - 178
main/inc/lib/fckeditor/editor/_source/fckeditorapi.js

@@ -1,179 +1,179 @@
-/*
- * FCKeditor - The text editor for Internet - http://www.fckeditor.net
- * Copyright (C) 2003-2009 Frederico Caldeira Knabben
- *
- * == BEGIN LICENSE ==
- *
- * Licensed under the terms of any of the following licenses at your
- * choice:
- *
- *  - GNU General Public License Version 2 or later (the "GPL")
- *    http://www.gnu.org/licenses/gpl.html
- *
- *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
- *    http://www.gnu.org/licenses/lgpl.html
- *
- *  - Mozilla Public License Version 1.1 or later (the "MPL")
- *    http://www.mozilla.org/MPL/MPL-1.1.html
- *
- * == END LICENSE ==
- *
- * Create the FCKeditorAPI object that is available as a global object in
- * the page where the editor is placed in.
- */
-
-var FCKeditorAPI ;
-
-function InitializeAPI()
-{
-	var oParentWindow = window.parent ;
-
-	if ( !( FCKeditorAPI = oParentWindow.FCKeditorAPI ) )
-	{
-		// Make the FCKeditorAPI object available in the parent window. Use
-		// eval so this core runs in the parent's scope and so it will still be
-		// available if the editor instance is removed ("Can't execute code
-		// from a freed script" error).
-
-		// Note: we check the existence of oEditor.GetParentForm because some external
-		// code (like JSON) can extend the Object prototype and we get then extra oEditor
-		// objects that aren't really FCKeditor instances.
-		var sScript =
+/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2009 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * Create the FCKeditorAPI object that is available as a global object in
+ * the page where the editor is placed in.
+ */
+
+var FCKeditorAPI ;
+
+function InitializeAPI()
+{
+	var oParentWindow = window.parent ;
+
+	if ( !( FCKeditorAPI = oParentWindow.FCKeditorAPI ) )
+	{
+		// Make the FCKeditorAPI object available in the parent window. Use
+		// eval so this core runs in the parent's scope and so it will still be
+		// available if the editor instance is removed ("Can't execute code
+		// from a freed script" error).
+
+		// Note: we check the existence of oEditor.GetParentForm because some external
+		// code (like JSON) can extend the Object prototype and we get then extra oEditor
+		// objects that aren't really FCKeditor instances.
+		var sScript =
 			'window.FCKeditorAPI = {' +
 			'window.FCKeditorAPI = {' +
-				'Version : "2.6.4.1",' +
-				'VersionBuild : "23195",' +
-				'Instances : window.FCKeditorAPI && window.FCKeditorAPI.Instances || {},' +
-
-				'GetInstance : function( name )' +
-				'{' +
-					'return this.Instances[ name ];' +
-				'},' +
-
-				'_FormSubmit : function()' +
-				'{' +
-					'for ( var name in FCKeditorAPI.Instances )' +
-					'{' +
-						'var oEditor = FCKeditorAPI.Instances[ name ] ;' +
-						'if ( oEditor.GetParentForm && oEditor.GetParentForm() == this )' +
-							'oEditor.UpdateLinkedField() ;' +
-					'}' +
-					'this._FCKOriginalSubmit() ;' +
-				'},' +
-
-				'_FunctionQueue	: window.FCKeditorAPI && window.FCKeditorAPI._FunctionQueue || {' +
-					'Functions : new Array(),' +
-					'IsRunning : false,' +
-
-					'Add : function( f )' +
-					'{' +
-						'this.Functions.push( f );' +
-						'if ( !this.IsRunning )' +
-							'this.StartNext();' +
-					'},' +
-
-					'StartNext : function()' +
-					'{' +
-						'var aQueue = this.Functions ;' +
-						'if ( aQueue.length > 0 )' +
-						'{' +
-							'this.IsRunning = true;' +
-							'aQueue[0].call();' +
-						'}' +
-						'else ' +
-							'this.IsRunning = false;' +
-					'},' +
-
-					'Remove : function( f )' +
-					'{' +
-						'var aQueue = this.Functions;' +
-						'var i = 0, fFunc;' +
-						'while( (fFunc = aQueue[ i ]) )' +
-						'{' +
-							'if ( fFunc == f )' +
-								'aQueue.splice( i,1 );' +
-							'i++ ;' +
-						'}' +
-						'this.StartNext();' +
-					'}' +
-				'}' +
-			'}' ;
-
-		// In IE, the "eval" function is not always available (it works with
-		// the JavaScript samples, but not with the ASP ones, for example).
-		// So, let's use the execScript instead.
-		if ( oParentWindow.execScript )
-			oParentWindow.execScript( sScript, 'JavaScript' ) ;
-		else
-		{
-			if ( FCKBrowserInfo.IsGecko10 )
-			{
-				// FF 1.0.4 gives an error with the request bellow. The
-				// following seams to work well.
-				eval.call( oParentWindow, sScript ) ;
-			}
-			else if( FCKBrowserInfo.IsAIR )
-			{
-				FCKAdobeAIR.FCKeditorAPI_Evaluate( oParentWindow, sScript ) ;
-			}
-			else if ( FCKBrowserInfo.IsSafari )
-			{
-				// oParentWindow.eval in Safari executes in the calling window
-				// environment, instead of the parent one. The following should
-				// make it work.
-				var oParentDocument = oParentWindow.document ;
-				var eScript = oParentDocument.createElement('script') ;
-				eScript.appendChild( oParentDocument.createTextNode( sScript ) ) ;
-				oParentDocument.documentElement.appendChild( eScript ) ;
-			}
-			else
-				oParentWindow.eval( sScript ) ;
-		}
-
-		FCKeditorAPI = oParentWindow.FCKeditorAPI ;
-
-		// The __Instances properly has been changed to the public Instances,
-		// but we should still have the "deprecated" version of it.
-		FCKeditorAPI.__Instances = FCKeditorAPI.Instances ;
-	}
-
-	// Add the current instance to the FCKeditorAPI's instances collection.
-	FCKeditorAPI.Instances[ FCK.Name ] = FCK ;
-}
-
-// Attach to the form onsubmit event and to the form.submit().
-function _AttachFormSubmitToAPI()
-{
-	// Get the linked field form.
-	var oForm = FCK.GetParentForm() ;
-
-	if ( oForm )
-	{
-		// Attach to the onsubmit event.
-		FCKTools.AddEventListener( oForm, 'submit', FCK.UpdateLinkedField ) ;
-
-		// IE sees oForm.submit function as an 'object'.
-		if ( !oForm._FCKOriginalSubmit && ( typeof( oForm.submit ) == 'function' || ( !oForm.submit.tagName && !oForm.submit.length ) ) )
-		{
-			// Save the original submit.
-			oForm._FCKOriginalSubmit = oForm.submit ;
-
-			// Create our replacement for the submit.
-			oForm.submit = FCKeditorAPI._FormSubmit ;
-		}
-	}
-}
-
-function FCKeditorAPI_Cleanup()
-{
-	if ( window.FCKConfig && FCKConfig.MsWebBrowserControlCompat
-			&& !window.FCKUnloadFlag )
-		return ;
-	delete FCKeditorAPI.Instances[ FCK.Name ] ;
-}
-function FCKeditorAPI_ConfirmCleanup()
-{
-	if ( window.FCKConfig && FCKConfig.MsWebBrowserControlCompat )
-		window.FCKUnloadFlag = true ;
-}
-FCKTools.AddEventListener( window, 'unload', FCKeditorAPI_Cleanup ) ;
-FCKTools.AddEventListener( window, 'beforeunload', FCKeditorAPI_ConfirmCleanup) ;
+				'Version : "2.6.4.1",' +
+				'VersionBuild : "23405",' +
+				'Instances : window.FCKeditorAPI && window.FCKeditorAPI.Instances || {},' +
+
+				'GetInstance : function( name )' +
+				'{' +
+					'return this.Instances[ name ];' +
+				'},' +
+
+				'_FormSubmit : function()' +
+				'{' +
+					'for ( var name in FCKeditorAPI.Instances )' +
+					'{' +
+						'var oEditor = FCKeditorAPI.Instances[ name ] ;' +
+						'if ( oEditor.GetParentForm && oEditor.GetParentForm() == this )' +
+							'oEditor.UpdateLinkedField() ;' +
+					'}' +
+					'this._FCKOriginalSubmit() ;' +
+				'},' +
+
+				'_FunctionQueue	: window.FCKeditorAPI && window.FCKeditorAPI._FunctionQueue || {' +
+					'Functions : new Array(),' +
+					'IsRunning : false,' +
+
+					'Add : function( f )' +
+					'{' +
+						'this.Functions.push( f );' +
+						'if ( !this.IsRunning )' +
+							'this.StartNext();' +
+					'},' +
+
+					'StartNext : function()' +
+					'{' +
+						'var aQueue = this.Functions ;' +
+						'if ( aQueue.length > 0 )' +
+						'{' +
+							'this.IsRunning = true;' +
+							'aQueue[0].call();' +
+						'}' +
+						'else ' +
+							'this.IsRunning = false;' +
+					'},' +
+
+					'Remove : function( f )' +
+					'{' +
+						'var aQueue = this.Functions;' +
+						'var i = 0, fFunc;' +
+						'while( (fFunc = aQueue[ i ]) )' +
+						'{' +
+							'if ( fFunc == f )' +
+								'aQueue.splice( i,1 );' +
+							'i++ ;' +
+						'}' +
+						'this.StartNext();' +
+					'}' +
+				'}' +
+			'}' ;
+
+		// In IE, the "eval" function is not always available (it works with
+		// the JavaScript samples, but not with the ASP ones, for example).
+		// So, let's use the execScript instead.
+		if ( oParentWindow.execScript )
+			oParentWindow.execScript( sScript, 'JavaScript' ) ;
+		else
+		{
+			if ( FCKBrowserInfo.IsGecko10 )
+			{
+				// FF 1.0.4 gives an error with the request bellow. The
+				// following seams to work well.
+				eval.call( oParentWindow, sScript ) ;
+			}
+			else if( FCKBrowserInfo.IsAIR )
+			{
+				FCKAdobeAIR.FCKeditorAPI_Evaluate( oParentWindow, sScript ) ;
+			}
+			else if ( FCKBrowserInfo.IsSafari )
+			{
+				// oParentWindow.eval in Safari executes in the calling window
+				// environment, instead of the parent one. The following should
+				// make it work.
+				var oParentDocument = oParentWindow.document ;
+				var eScript = oParentDocument.createElement('script') ;
+				eScript.appendChild( oParentDocument.createTextNode( sScript ) ) ;
+				oParentDocument.documentElement.appendChild( eScript ) ;
+			}
+			else
+				oParentWindow.eval( sScript ) ;
+		}
+
+		FCKeditorAPI = oParentWindow.FCKeditorAPI ;
+
+		// The __Instances properly has been changed to the public Instances,
+		// but we should still have the "deprecated" version of it.
+		FCKeditorAPI.__Instances = FCKeditorAPI.Instances ;
+	}
+
+	// Add the current instance to the FCKeditorAPI's instances collection.
+	FCKeditorAPI.Instances[ FCK.Name ] = FCK ;
+}
+
+// Attach to the form onsubmit event and to the form.submit().
+function _AttachFormSubmitToAPI()
+{
+	// Get the linked field form.
+	var oForm = FCK.GetParentForm() ;
+
+	if ( oForm )
+	{
+		// Attach to the onsubmit event.
+		FCKTools.AddEventListener( oForm, 'submit', FCK.UpdateLinkedField ) ;
+
+		// IE sees oForm.submit function as an 'object'.
+		if ( !oForm._FCKOriginalSubmit && ( typeof( oForm.submit ) == 'function' || ( !oForm.submit.tagName && !oForm.submit.length ) ) )
+		{
+			// Save the original submit.
+			oForm._FCKOriginalSubmit = oForm.submit ;
+
+			// Create our replacement for the submit.
+			oForm.submit = FCKeditorAPI._FormSubmit ;
+		}
+	}
+}
+
+function FCKeditorAPI_Cleanup()
+{
+	if ( window.FCKConfig && FCKConfig.MsWebBrowserControlCompat
+			&& !window.FCKUnloadFlag )
+		return ;
+	delete FCKeditorAPI.Instances[ FCK.Name ] ;
+}
+function FCKeditorAPI_ConfirmCleanup()
+{
+	if ( window.FCKConfig && FCKConfig.MsWebBrowserControlCompat )
+		window.FCKUnloadFlag = true ;
+}
+FCKTools.AddEventListener( window, 'unload', FCKeditorAPI_Cleanup ) ;
+FCKTools.AddEventListener( window, 'beforeunload', FCKeditorAPI_ConfirmCleanup) ;

+ 32 - 0
main/inc/lib/fckeditor/editor/_source/internals/fck.js

@@ -955,6 +955,38 @@ function _FCK_EditingArea_OnLoad()
 	FCKTools.AddEventListener( FCK.EditorDocument, 'mousemove', _FCK_MouseEventsListener ) ;
 	FCKTools.AddEventListener( FCK.EditorDocument, 'mousemove', _FCK_MouseEventsListener ) ;
 	FCKTools.AddEventListener( FCK.EditorDocument, 'mousedown', _FCK_MouseEventsListener ) ;
 	FCKTools.AddEventListener( FCK.EditorDocument, 'mousedown', _FCK_MouseEventsListener ) ;
 	FCKTools.AddEventListener( FCK.EditorDocument, 'mouseup', _FCK_MouseEventsListener ) ;
 	FCKTools.AddEventListener( FCK.EditorDocument, 'mouseup', _FCK_MouseEventsListener ) ;
+	if ( FCKBrowserInfo.IsSafari )
+	{
+		// #3481: WebKit has a bug with paste where the paste contents may leak
+		// outside table cells. So add padding nodes before and after the paste.
+		FCKTools.AddEventListener( FCK.EditorDocument, 'paste', function( evt )
+		{
+			var range = new FCKDomRange( FCK.EditorWindow );
+			var nodeBefore = FCK.EditorDocument.createTextNode( '\ufeff' );
+			var nodeAfter = FCK.EditorDocument.createElement( 'a' );
+			nodeAfter.id = 'fck_paste_padding';
+			nodeAfter.innerHTML = '&#65279;';
+			range.MoveToSelection();
+			range.DeleteContents();
+
+			// Insert padding nodes.
+			range.InsertNode( nodeBefore );
+			range.Collapse();
+			range.InsertNode( nodeAfter );
+
+			// Move the selection to between the padding nodes.
+			range.MoveToPosition( nodeAfter, 3 );
+			range.Select();
+
+			// Remove the padding nodes after the paste is done.
+			setTimeout( function()
+				{
+					nodeBefore.parentNode.removeChild( nodeBefore );
+					nodeAfter = FCK.EditorDocument.getElementById( 'fck_paste_padding' );
+					nodeAfter.parentNode.removeChild( nodeAfter );
+				}, 0 );
+		} );
+	}
 
 
 	// Most of the CTRL key combos do not work under Safari for onkeydown and onkeypress (See #1119)
 	// Most of the CTRL key combos do not work under Safari for onkeydown and onkeypress (See #1119)
 	// But we can use the keyup event to override some of these...
 	// But we can use the keyup event to override some of these...

+ 10 - 0
main/inc/lib/fckeditor/editor/_source/internals/fck_gecko.js

@@ -375,6 +375,16 @@ FCK.InsertHtml = function( html )
 
 
 		range = new FCKDomRange( this.EditorWindow ) ;
 		range = new FCKDomRange( this.EditorWindow ) ;
 		range.MoveToSelection() ;
 		range.MoveToSelection() ;
+
+		// If the first element (if exists) of the document fragment is a block
+		// element, then split the current block. (#1537)
+		var currentNode = docFrag.RootNode.firstChild ;
+		while ( currentNode && currentNode.nodeType != 1 )
+			currentNode = currentNode.nextSibling ;
+		
+		if ( currentNode && FCKListsLib.BlockElements[ currentNode.nodeName.toLowerCase() ] )
+			range.SplitBlock() ;
+
 		range.DeleteContents() ;
 		range.DeleteContents() ;
 		range.InsertNode( docFrag.RootNode ) ;
 		range.InsertNode( docFrag.RootNode ) ;
 
 

+ 14 - 4
main/inc/lib/fckeditor/editor/_source/internals/fck_ie.js

@@ -172,7 +172,12 @@ FCK.InsertHtml = function( html )
 	oSel.createRange().pasteHTML( html ) ;
 	oSel.createRange().pasteHTML( html ) ;
 
 
 	// Remove the fake node
 	// Remove the fake node
-	FCK.EditorDocument.getElementById('__fakeFCKRemove__').removeNode( true ) ;
+	var fake = FCK.EditorDocument.getElementById('__fakeFCKRemove__') ;
+	// If the span is the only child of a node (so the inserted HTML is beyond that),
+	// remove also that parent that isn't needed. #1537
+	if (fake.parentNode.childNodes.length == 1) 
+		fake = fake.parentNode ;
+	fake.removeNode( true ) ;
 
 
 	FCKDocumentProcessor.Process( FCK.EditorDocument ) ;
 	FCKDocumentProcessor.Process( FCK.EditorDocument ) ;
 
 
@@ -373,22 +378,27 @@ FCK.CreateLink = function( url, noUndo )
 {
 {
 	// Creates the array that will be returned. It contains one or more created links (see #220).
 	// Creates the array that will be returned. It contains one or more created links (see #220).
 	var aCreatedLinks = new Array() ;
 	var aCreatedLinks = new Array() ;
+	var isControl = FCKSelection.GetType() == 'Control' ;
+	var selectedElement = isControl && FCKSelection.GetSelectedElement() ;
 
 
 	// Remove any existing link in the selection.
 	// Remove any existing link in the selection.
-	FCK.ExecuteNamedCommand( 'Unlink', null, false, !!noUndo ) ;
+	// IE BUG: Unlinking a floating control selection that is not inside a link
+	// will collapse the selection. (#3677)
+	if ( !( isControl && !FCKTools.GetElementAscensor( selectedElement, 'a' ) ) )
+		FCK.ExecuteNamedCommand( 'Unlink', null, false, !!noUndo ) ;
 
 
 	if ( url.length > 0 )
 	if ( url.length > 0 )
 	{
 	{
 		// If there are several images, and you try to link each one, all the images get inside the link:
 		// If there are several images, and you try to link each one, all the images get inside the link:
 		// <img><img> -> <a><img></a><img> -> <a><img><img></a> due to the call to 'CreateLink' (bug in IE)
 		// <img><img> -> <a><img></a><img> -> <a><img><img></a> due to the call to 'CreateLink' (bug in IE)
-		if (FCKSelection.GetType() == 'Control')
+		if ( isControl )
 		{
 		{
 			// Create a link
 			// Create a link
 			var oLink = this.EditorDocument.createElement( 'A' ) ;
 			var oLink = this.EditorDocument.createElement( 'A' ) ;
 			oLink.href = url ;
 			oLink.href = url ;
 
 
 			// Get the selected object
 			// Get the selected object
-			var oControl = FCKSelection.GetSelectedElement() ;
+			var oControl = selectedElement ;
 			// Put the link just before the object
 			// Put the link just before the object
 			oControl.parentNode.insertBefore(oLink, oControl) ;
 			oControl.parentNode.insertBefore(oLink, oControl) ;
 			// Move the object inside the link
 			// Move the object inside the link

+ 1 - 1
main/inc/lib/fckeditor/editor/_source/internals/fckdialog.js

@@ -79,7 +79,7 @@ var FCKDialog = ( function()
 		/**
 		/**
 		 * Opens a dialog window using the standard dialog template.
 		 * Opens a dialog window using the standard dialog template.
 		 */
 		 */
-		OpenDialog : function( dialogName, dialogTitle, dialogPage, width, height, customValue, parentWindow, resizable )
+		OpenDialog : function( dialogName, dialogTitle, dialogPage, width, height, customValue, resizable )
 		{
 		{
 			if ( !topDialog )
 			if ( !topDialog )
 				this.DisplayMainCover() ;
 				this.DisplayMainCover() ;

+ 38 - 10
main/inc/lib/fckeditor/editor/_source/internals/fckdomtools.js

@@ -488,18 +488,46 @@ var FCKDomTools =
 
 
 		for ( var i = 0 ; i < attributes.length ; i++ )
 		for ( var i = 0 ; i < attributes.length ; i++ )
 		{
 		{
-			if ( FCKBrowserInfo.IsIE && attributes[i].nodeName == 'class' )
+			if ( FCKBrowserInfo.IsIE ) 
 			{
 			{
-				// IE has a strange bug. If calling removeAttribute('className'),
-				// the attributes collection will still contain the "class"
-				// attribute, which will be marked as "specified", even if the
-				// outerHTML of the element is not displaying the class attribute.
-				// Note : I was not able to reproduce it outside the editor,
-				// but I've faced it while working on the TC of #1391.
-				if ( element.className.length > 0 )
-					return true ;
+				var attributeNodeName = attributes[i].nodeName ;
+
+				if ( attributeNodeName.StartsWith( '_fck' ) ) 
+				{
+					/**
+					 * There are places in the FCKeditor code where HTML element objects
+					 * get values stored as properties (e.g. _fckxhtmljob).  In Internet 
+					 * Explorer, these are interpreted as attempts to set attributes on
+					 * the element.  
+					 *
+					 * http://msdn.microsoft.com/en-us/library/ms533026(VS.85).aspx#Accessing_Element_Pr
+					 *
+					 * Counting these as HTML attributes cripples 
+					 * FCK.Style.RemoveFromRange() once FCK.GetData() has been called.
+					 *
+					 * The above conditional prevents these internal properties being 
+					 * counted as attributes.
+					 *
+					 * refs #2156 and #2834
+					 */
+
+					continue ;
+				}
+
+				if ( attributeNodeName == 'class' ) 
+				{
+					// IE has a strange bug. If calling removeAttribute('className'),
+					// the attributes collection will still contain the "class"
+					// attribute, which will be marked as "specified", even if the
+					// outerHTML of the element is not displaying the class attribute.
+					// Note : I was not able to reproduce it outside the editor,
+					// but I've faced it while working on the TC of #1391.
+					if ( element.className.length > 0 )
+						return true ;
+					continue ;
+				}
 			}
 			}
-			else if ( attributes[i].specified )
+			if ( attributes[i].specified )
 				return true ;
 				return true ;
 		}
 		}
 
 

+ 17 - 0
main/inc/lib/fckeditor/editor/_source/internals/fckxhtml.js

@@ -56,6 +56,23 @@ FCKXHtml.GetXHTML = function( node, includeNode, format )
 	else
 	else
 		this._AppendChildNodes( this.MainNode, node, false ) ;
 		this._AppendChildNodes( this.MainNode, node, false ) ;
 
 
+	/**
+	 * FCKXHtml._AppendNode() marks DOM element objects it has 
+	 * processed by adding a property called _fckxhtmljob, 
+	 * setting it equal to the value of FCKXHtml.CurrentJobNum.  
+	 * On Internet Explorer, if an element object has such a 
+	 * property,  it will show up in the object's attributes 
+	 * NamedNodeMap, and the corresponding Attr object in 
+	 * that collection  will have is specified property set 
+	 * to true.  This trips up code elsewhere that checks to 
+	 * see if an element is free of attributes before proceeding 
+	 * with an edit operation (c.f. FCK.Style.RemoveFromRange())
+	 *	
+	 * refs #2156 and #2834
+	 */
+	if ( FCKBrowserInfo.IsIE )
+		FCKXHtml._RemoveXHtmlJobProperties( node ) ;
+
 	// Get the resulting XHTML as a string.
 	// Get the resulting XHTML as a string.
 	var sXHTML = this._GetMainXmlString() ;
 	var sXHTML = this._GetMainXmlString() ;
 
 

+ 36 - 0
main/inc/lib/fckeditor/editor/_source/internals/fckxhtml_ie.js

@@ -92,6 +92,42 @@ FCKXHtml._AppendAttributes = function( xmlNode, htmlNode, node, nodeName )
 	}
 	}
 }
 }
 
 
+/**
+ * Used to clean up HTML that has been processed FCKXHtml._AppendNode().
+ *
+ * For objects corresponding to HTML elements, Internet Explorer will 
+ * treat a property as if it were an attribute set on that element.
+ *
+ * http://msdn.microsoft.com/en-us/library/ms533026(VS.85).aspx#Accessing_Element_Pr
+ *
+ * FCKXHtml._AppendNode() sets the property _fckxhtmljob on node objects
+ * corresponding HTML elements to mark them as having been processed.
+ * Counting these properties as attributes will cripple style removal
+ * because FCK.Styles.RemoveFromSelection() will not remove an element
+ * as long as it still has attributes.
+ *
+ * refs #2156 and #2834
+ */
+
+FCKXHtml._RemoveXHtmlJobProperties = function ( node ) 
+{
+	// Select only nodes of type ELEMENT_NODE
+	if (!node || !node.nodeType || node.nodeType != 1)
+		return ;
+
+	// Clear the _fckhtmljob attribute.
+	if ( typeof node._fckxhtmljob !== 'undefined' )
+		node.removeAttribute('_fckxhtmljob') ;
+
+	// Recurse upon child nodes.
+	if ( node.hasChildNodes() ) 
+	{
+		var childNodes = node.childNodes ;
+		for ( var i = childNodes.length - 1 ; i >= 0 ; i-- ) 
+			FCKXHtml._RemoveXHtmlJobProperties( childNodes.item(i) ) ;
+	}
+}
+
 // On very rare cases, IE is loosing the "align" attribute for DIV. (right align and apply bulleted list)
 // On very rare cases, IE is loosing the "align" attribute for DIV. (right align and apply bulleted list)
 FCKXHtml.TagProcessors['div'] = function( node, htmlNode )
 FCKXHtml.TagProcessors['div'] = function( node, htmlNode )
 {
 {

+ 1 - 1
main/inc/lib/fckeditor/editor/dialog/common/fck_dialog_common.js

@@ -216,7 +216,7 @@ function OpenFileBrowser( url, width, height )
 	}
 	}
 	else
 	else
 	{
 	{
-		FCKDialog.OpenDialog( 'FCKDialog_FileManager' , FCKLang['BrowseServer'], url, width, height, '', window, true ) ;
+		FCKDialog.OpenDialog( 'FCKDialog_FileManager' , FCKLang['BrowseServer'], url, width, height, '', true ) ;
 	}
 	}
 }
 }
 
 

+ 6 - 1
main/inc/lib/fckeditor/editor/dialog/fck_about.html

@@ -65,6 +65,11 @@ window.onload = function()
 }
 }
 
 
 	</script>
 	</script>
+
+	<style type="text/css">
+		body, td, input, textarea, select, label { font-family: Arial, Verdana, Geneva, helvetica, sans-serif; font-size: 11px; }
+	</style>
+
 </head>
 </head>
 <body style="overflow: hidden">
 <body style="overflow: hidden">
 	<div id="divAbout">
 	<div id="divAbout">
@@ -79,7 +84,7 @@ window.onload = function()
 								<span fcklang="DlgAboutVersion">version</span>
 								<span fcklang="DlgAboutVersion">version</span>
 								<br />
 								<br />
 								<b>2.6.4.1</b><br />
 								<b>2.6.4.1</b><br />
-								Build 23195</td>
+								Build 23405</td>
 						</tr>
 						</tr>
 					</table>
 					</table>
 				</td>
 				</td>

+ 5 - 0
main/inc/lib/fckeditor/editor/dialog/fck_anchor.html

@@ -200,6 +200,11 @@ function ReadjustLinksToAnchor( sCurrent, sNew )
 }
 }
 
 
 		</script>
 		</script>
+
+		<style type="text/css">
+			body, td, input, textarea, select, label { font-family: Arial, Verdana, Geneva, helvetica, sans-serif; font-size: 11px; }
+		</style>
+
 	</head>
 	</head>
 	<body style="overflow: hidden">
 	<body style="overflow: hidden">
 		<table height="100%" width="100%">
 		<table height="100%" width="100%">

+ 5 - 0
main/inc/lib/fckeditor/editor/dialog/fck_button.html

@@ -68,6 +68,11 @@ function Ok()
 }
 }
 
 
 	</script>
 	</script>
+
+	<style type="text/css">
+		body, td, input, textarea, select, label { font-family: Arial, Verdana, Geneva, helvetica, sans-serif; font-size: 11px; }
+	</style>
+
 </head>
 </head>
 <body style="overflow: hidden">
 <body style="overflow: hidden">
 	<table width="100%" style="height: 100%">
 	<table width="100%" style="height: 100%">

+ 5 - 0
main/inc/lib/fckeditor/editor/dialog/fck_checkbox.html

@@ -75,6 +75,11 @@ function Ok()
 }
 }
 
 
 		</script>
 		</script>
+
+		<style type="text/css">
+			body, td, input, textarea, select, label { font-family: Arial, Verdana, Geneva, helvetica, sans-serif; font-size: 11px; }
+		</style>
+
 	</head>
 	</head>
 	<body style="OVERFLOW: hidden" scroll="no">
 	<body style="OVERFLOW: hidden" scroll="no">
 		<table height="100%" width="100%">
 		<table height="100%" width="100%">

+ 5 - 0
main/inc/lib/fckeditor/editor/dialog/fck_colorselector.html

@@ -142,6 +142,11 @@ function Ok()
 	return true ;
 	return true ;
 }
 }
 		</script>
 		</script>
+
+		<style type="text/css">
+			body, td, input, textarea, select, label { font-family: Arial, Verdana, Geneva, helvetica, sans-serif; font-size: 11px; }
+		</style>
+
 	</head>
 	</head>
 	<body onload="OnLoad()" scroll="no" style="OVERFLOW: hidden">
 	<body onload="OnLoad()" scroll="no" style="OVERFLOW: hidden">
 		<table cellpadding="0" cellspacing="0" border="0" width="100%" height="100%">
 		<table cellpadding="0" cellspacing="0" border="0" width="100%" height="100%">

+ 5 - 0
main/inc/lib/fckeditor/editor/dialog/fck_div.html

@@ -319,6 +319,11 @@ function Ok()
 }
 }
 
 
 	</script>
 	</script>
+
+	<style type="text/css">
+		body, td, input, textarea, select, label { font-family: Arial, Verdana, Geneva, helvetica, sans-serif; font-size: 11px; }
+	</style>
+
 </head>
 </head>
 <body style="overflow: hidden">
 <body style="overflow: hidden">
 	<div id="divGeneral">
 	<div id="divGeneral">

+ 22 - 17
main/inc/lib/fckeditor/editor/dialog/fck_docprops.html

@@ -21,11 +21,11 @@
  *
  *
  * Link dialog window.
  * Link dialog window.
 -->
 -->
-<html xmlns="http://www.w3.org/1999/xhtml">
+<html>
 <head>
 <head>
 	<title></title>
 	<title></title>
-	<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
-	<meta content="noindex, nofollow" name="robots" />
+	<meta http-equiv="Content-Type" content="text/html; charset=utf-8" >
+	<meta content="noindex, nofollow" name="robots" >
 	<script src="common/fck_dialog_common.js" type="text/javascript"></script>
 	<script src="common/fck_dialog_common.js" type="text/javascript"></script>
 	<script type="text/javascript">
 	<script type="text/javascript">
 
 
@@ -374,11 +374,11 @@ function SelectColor( wich )
 {
 {
 	switch ( wich )
 	switch ( wich )
 	{
 	{
-		case 'Back'			: oEditor.FCKDialog.OpenDialog( 'FCKDialog_Color', FCKLang.DlgColorTitle, 'dialog/fck_colorselector.html', 410, 320, SelectBackColor, window ) ; return ;
-		case 'ColorText'	: oEditor.FCKDialog.OpenDialog( 'FCKDialog_Color', FCKLang.DlgColorTitle, 'dialog/fck_colorselector.html', 410, 320, SelectColorText, window ) ; return ;
-		case 'ColorLink'	: oEditor.FCKDialog.OpenDialog( 'FCKDialog_Color', FCKLang.DlgColorTitle, 'dialog/fck_colorselector.html', 410, 320, SelectColorLink, window ) ; return ;
-		case 'ColorVisited'	: oEditor.FCKDialog.OpenDialog( 'FCKDialog_Color', FCKLang.DlgColorTitle, 'dialog/fck_colorselector.html', 410, 320, SelectColorVisited, window ) ; return ;
-		case 'ColorActive'	: oEditor.FCKDialog.OpenDialog( 'FCKDialog_Color', FCKLang.DlgColorTitle, 'dialog/fck_colorselector.html', 410, 320, SelectColorActive, window ) ; return ;
+		case 'Back'			: oEditor.FCKDialog.OpenDialog( 'FCKDialog_Color', FCKLang.DlgColorTitle, 'dialog/fck_colorselector.html', 410, 320, SelectBackColor ) ; return ;
+		case 'ColorText'	: oEditor.FCKDialog.OpenDialog( 'FCKDialog_Color', FCKLang.DlgColorTitle, 'dialog/fck_colorselector.html', 410, 320, SelectColorText ) ; return ;
+		case 'ColorLink'	: oEditor.FCKDialog.OpenDialog( 'FCKDialog_Color', FCKLang.DlgColorTitle, 'dialog/fck_colorselector.html', 410, 320, SelectColorLink ) ; return ;
+		case 'ColorVisited'	: oEditor.FCKDialog.OpenDialog( 'FCKDialog_Color', FCKLang.DlgColorTitle, 'dialog/fck_colorselector.html', 410, 320, SelectColorVisited ) ; return ;
+		case 'ColorActive'	: oEditor.FCKDialog.OpenDialog( 'FCKDialog_Color', FCKLang.DlgColorTitle, 'dialog/fck_colorselector.html', 410, 320, SelectColorActive ) ; return ;
 	}
 	}
 }
 }
 
 
@@ -394,6 +394,11 @@ function SetUrl( url )
 }
 }
 
 
 	</script>
 	</script>
+
+	<style type="text/css">
+		body, td, input, textarea, select, label { font-family: Arial, Verdana, Geneva, helvetica, sans-serif; font-size: 11px; }
+	</style>
+
 </head>
 </head>
 <body style="overflow: hidden">
 <body style="overflow: hidden">
 	<table cellspacing="0" cellpadding="0" width="100%" border="0" style="height: 100%">
 	<table cellspacing="0" cellpadding="0" width="100%" border="0" style="height: 100%">
@@ -458,22 +463,22 @@ function SetUrl( url )
 								<span fcklang="DlgDocDocType">Document Type Heading</span><br />
 								<span fcklang="DlgDocDocType">Document Type Heading</span><br />
 								<select id="selDocType" onchange="CheckOther( this, 'txtDocType' );">
 								<select id="selDocType" onchange="CheckOther( this, 'txtDocType' );">
 									<option value="" selected="selected"></option>
 									<option value="" selected="selected"></option>
-									<option value='<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">'>HTML
+									<option value='&lt;!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"&gt;'>HTML
 										4.01 Transitional</option>
 										4.01 Transitional</option>
-									<option value='<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">'>
+									<option value='&lt;!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"&gt;'>
 										HTML 4.01 Strict</option>
 										HTML 4.01 Strict</option>
-									<option value='<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN" "http://www.w3.org/TR/html4/frameset.dtd">'>
+									<option value='&lt;!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN" "http://www.w3.org/TR/html4/frameset.dtd"&gt;'>
 										HTML 4.01 Frameset</option>
 										HTML 4.01 Frameset</option>
-									<option value='<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">'>
+									<option value='&lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&gt;'>
 										XHTML 1.0 Transitional</option>
 										XHTML 1.0 Transitional</option>
-									<option value='<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">'>
+									<option value='&lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"&gt;'>
 										XHTML 1.0 Strict</option>
 										XHTML 1.0 Strict</option>
-									<option value='<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd">'>
+									<option value='&lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd"&gt;'>
 										XHTML 1.0 Frameset</option>
 										XHTML 1.0 Frameset</option>
-									<option value='<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">'>
+									<option value='&lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"&gt;'>
 										XHTML 1.1</option>
 										XHTML 1.1</option>
-									<option value='<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">'>HTML 3.2</option>
-									<option value='<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">'>HTML 2.0</option>
+									<option value='&lt;!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"&gt;'>HTML 3.2</option>
+									<option value='&lt;!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN"&gt;'>HTML 2.0</option>
 									<option value="..." fcklang="DlgOpOther">&lt;Other&gt;</option>
 									<option value="..." fcklang="DlgOpOther">&lt;Other&gt;</option>
 								</select>
 								</select>
 							</td>
 							</td>

+ 1 - 1
main/inc/lib/fckeditor/editor/dialog/fck_docprops/fck_document_preview.html

@@ -26,7 +26,7 @@
 		<title>Document Properties - Preview</title>
 		<title>Document Properties - Preview</title>
 		<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
 		<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
 		<meta name="robots" content="noindex, nofollow">
 		<meta name="robots" content="noindex, nofollow">
-		<script language="javascript">
+		<script type="text/javascript">
 
 
 var eBase = parent.FCK.EditorDocument.getElementsByTagName( 'BASE' ) ;
 var eBase = parent.FCK.EditorDocument.getElementsByTagName( 'BASE' ) ;
 if ( eBase.length > 0 && eBase[0].href.length > 0 )
 if ( eBase.length > 0 && eBase[0].href.length > 0 )

+ 5 - 0
main/inc/lib/fckeditor/editor/dialog/fck_flash.html

@@ -33,6 +33,11 @@
 document.write( FCKTools.GetStyleHtml( GetCommonDialogCss() ) ) ;
 document.write( FCKTools.GetStyleHtml( GetCommonDialogCss() ) ) ;
 
 
 		</script>
 		</script>
+
+		<style type="text/css">
+			body, td, input, textarea, select, label { font-family: Arial, Verdana, Geneva, helvetica, sans-serif; font-size: 11px; }
+		</style>
+
 	</head>
 	</head>
 	<body scroll="no" style="OVERFLOW: hidden">
 	<body scroll="no" style="OVERFLOW: hidden">
 		<div id="divInfo">
 		<div id="divInfo">

+ 5 - 0
main/inc/lib/fckeditor/editor/dialog/fck_form.html

@@ -74,6 +74,11 @@ function Ok()
 }
 }
 
 
 	</script>
 	</script>
+
+	<style type="text/css">
+		body, td, input, textarea, select, label { font-family: Arial, Verdana, Geneva, helvetica, sans-serif; font-size: 11px; }
+	</style>
+
 </head>
 </head>
 <body style="overflow: hidden">
 <body style="overflow: hidden">
 	<table width="100%" style="height: 100%">
 	<table width="100%" style="height: 100%">

+ 5 - 0
main/inc/lib/fckeditor/editor/dialog/fck_hiddenfield.html

@@ -89,6 +89,11 @@ function Ok()
 }
 }
 
 
 	</script>
 	</script>
+
+	<style type="text/css">
+		body, td, input, textarea, select, label { font-family: Arial, Verdana, Geneva, helvetica, sans-serif; font-size: 11px; }
+	</style>
+
 </head>
 </head>
 <body style="overflow: hidden" scroll="no">
 <body style="overflow: hidden" scroll="no">
 	<table height="100%" width="100%">
 	<table height="100%" width="100%">

+ 5 - 0
main/inc/lib/fckeditor/editor/dialog/fck_image.html

@@ -33,6 +33,11 @@
 document.write( FCKTools.GetStyleHtml( GetCommonDialogCss() ) ) ;
 document.write( FCKTools.GetStyleHtml( GetCommonDialogCss() ) ) ;
 
 
 		</script>
 		</script>
+
+	<style type="text/css">
+		body, td, input, textarea, select, label { font-family: Arial, Verdana, Geneva, helvetica, sans-serif; font-size: 11px; }
+	</style>
+
 </head>
 </head>
 <body scroll="no" style="overflow: hidden">
 <body scroll="no" style="overflow: hidden">
 	<div id="divInfo">
 	<div id="divInfo">

+ 5 - 0
main/inc/lib/fckeditor/editor/dialog/fck_link.html

@@ -28,6 +28,11 @@
 		<meta name="robots" content="noindex, nofollow" />
 		<meta name="robots" content="noindex, nofollow" />
 		<script src="common/fck_dialog_common.js" type="text/javascript"></script>
 		<script src="common/fck_dialog_common.js" type="text/javascript"></script>
 		<script src="fck_link/fck_link.js" type="text/javascript"></script>
 		<script src="fck_link/fck_link.js" type="text/javascript"></script>
+
+		<style type="text/css">
+			body, td, input, textarea, select, label { font-family: Arial, Verdana, Geneva, helvetica, sans-serif; font-size: 11px; }
+		</style>
+
 	</head>
 	</head>
 	<body scroll="no" style="OVERFLOW: hidden">
 	<body scroll="no" style="OVERFLOW: hidden">
 		<div id="divInfo" style="DISPLAY: none">
 		<div id="divInfo" style="DISPLAY: none">

+ 5 - 0
main/inc/lib/fckeditor/editor/dialog/fck_listprop.html

@@ -82,6 +82,11 @@ function Ok()
 }
 }
 
 
 	</script>
 	</script>
+
+	<style type="text/css">
+		body, td, input, textarea, select, label { font-family: Arial, Verdana, Geneva, helvetica, sans-serif; font-size: 11px; }
+	</style>
+
 </head>
 </head>
 <body style="overflow: hidden">
 <body style="overflow: hidden">
 	<table width="100%" style="height: 100%">
 	<table width="100%" style="height: 100%">

+ 5 - 0
main/inc/lib/fckeditor/editor/dialog/fck_paste.html

@@ -305,6 +305,11 @@ function CleanWord( oNode, bIgnoreFont, bRemoveStyles )
 
 
 	</script>
 	</script>
 
 
+
+	<style type="text/css">
+		body, td, input, textarea, select, label { font-family: Arial, Verdana, Geneva, helvetica, sans-serif; font-size: 11px; }
+	</style>
+
 </head>
 </head>
 <body style="overflow: hidden">
 <body style="overflow: hidden">
 	<table cellspacing="0" cellpadding="0" width="100%" border="0" style="height: 98%">
 	<table cellspacing="0" cellpadding="0" width="100%" border="0" style="height: 98%">

+ 5 - 0
main/inc/lib/fckeditor/editor/dialog/fck_radiobutton.html

@@ -75,6 +75,11 @@ function Ok()
 }
 }
 
 
 		</script>
 		</script>
+
+		<style type="text/css">
+			body, td, input, textarea, select, label { font-family: Arial, Verdana, Geneva, helvetica, sans-serif; font-size: 11px; }
+		</style>
+
 	</head>
 	</head>
 	<body style="OVERFLOW: hidden" scroll="no">
 	<body style="OVERFLOW: hidden" scroll="no">
 		<table height="100%" width="100%">
 		<table height="100%" width="100%">

+ 5 - 0
main/inc/lib/fckeditor/editor/dialog/fck_replace.html

@@ -577,6 +577,11 @@ window.onunload = function()
 	}
 	}
 }
 }
 	</script>
 	</script>
+
+	<style type="text/css">
+		body, td, input, textarea, select, label { font-family: Arial, Verdana, Geneva, helvetica, sans-serif; font-size: 11px; }
+	</style>
+
 </head>
 </head>
 <body onload="OnLoad()" style="overflow: hidden">
 <body onload="OnLoad()" style="overflow: hidden">
 	<div id="divFind" style="display: none">
 	<div id="divFind" style="display: none">

+ 5 - 0
main/inc/lib/fckeditor/editor/dialog/fck_select.html

@@ -115,6 +115,11 @@ function Ok()
 }
 }
 
 
 		</script>
 		</script>
+
+		<style type="text/css">
+			body, td, input, textarea, select, label { font-family: Arial, Verdana, Geneva, helvetica, sans-serif; font-size: 11px; }
+		</style>
+
 	</head>
 	</head>
 	<body style="overflow: hidden">
 	<body style="overflow: hidden">
 		<table width="100%" height="100%">
 		<table width="100%" height="100%">

+ 5 - 0
main/inc/lib/fckeditor/editor/dialog/fck_smiley.html

@@ -77,6 +77,11 @@ function out(td)
 	td.className = 'DarkBackground Hand' ;
 	td.className = 'DarkBackground Hand' ;
 }
 }
 	</script>
 	</script>
+
+	<style type="text/css">
+		body, td, input, textarea, select, label { font-family: Arial, Verdana, Geneva, helvetica, sans-serif; font-size: 11px; }
+	</style>
+
 </head>
 </head>
 <body style="overflow: hidden">
 <body style="overflow: hidden">
 	<table cellpadding="2" cellspacing="2" align="center" border="0" width="100%" height="100%">
 	<table cellpadding="2" cellspacing="2" align="center" border="0" width="100%" height="100%">

+ 5 - 0
main/inc/lib/fckeditor/editor/dialog/fck_source.html

@@ -57,6 +57,11 @@ function Ok()
 	return true ;
 	return true ;
 }
 }
 		</script>
 		</script>
+
+		<style type="text/css">
+			body, td, input, textarea, select, label { font-family: Arial, Verdana, Geneva, helvetica, sans-serif; font-size: 11px; }
+		</style>
+
 	</head>
 	</head>
 	<body scroll="no" style="OVERFLOW: hidden">
 	<body scroll="no" style="OVERFLOW: hidden">
 		<table width="100%" height="100%">
 		<table width="100%" height="100%">

+ 5 - 0
main/inc/lib/fckeditor/editor/dialog/fck_specialchar.html

@@ -75,6 +75,11 @@ function setDefaults()
 }
 }
 
 
 		</script>
 		</script>
+
+		<style type="text/css">
+			body, td, input, textarea, select, label { font-family: Arial, Verdana, Geneva, helvetica, sans-serif; font-size: 13px; }
+		</style>
+
 	</head>
 	</head>
 	<body onload="setDefaults()" style="overflow: hidden">
 	<body onload="setDefaults()" style="overflow: hidden">
 		<table cellpadding="0" cellspacing="0" width="100%" height="100%">
 		<table cellpadding="0" cellspacing="0" width="100%" height="100%">

+ 5 - 0
main/inc/lib/fckeditor/editor/dialog/fck_spellerpages.html

@@ -62,6 +62,11 @@ function oSpeller_OnFinished( numberOCorrections )
 }
 }
 
 
 		</script>
 		</script>
+
+		<style type="text/css">
+			body, td, input, textarea, select, label { font-family: Arial, Verdana, Geneva, helvetica, sans-serif; font-size: 11px; }
+		</style>
+
 	</head>
 	</head>
 	<body style="OVERFLOW: hidden" scroll="no" style="padding:0px;">
 	<body style="OVERFLOW: hidden" scroll="no" style="padding:0px;">
 		<input type="hidden" id="txtHtml" value="">
 		<input type="hidden" id="txtHtml" value="">

+ 0 - 148
main/inc/lib/fckeditor/editor/dialog/fck_spellerpages/spellerpages/server-scripts/spellchecker.cfm

@@ -1,148 +0,0 @@
-<cfsetting enablecfoutputonly="true">
-<!---
-This code uses a CF User Defined Function and should work in CF version 5.0
-and up without alteration.
-
-Also if you are hosting your site at an ISP, you will have to check with them
-to see if the use of <CFEXECUTE> is allowed. In most cases ISP will not allow
-the use of that tag for security reasons. Clients would be able to access each
-others files in certain cases.
---->
-
-<!--- The following variables values must reflect your installation. --->
-<cfset aspell_dir	  = "C:\Program Files\Aspell\bin">
-<cfset lang         = "en_US">
-<cfset aspell_opts  = "-a --lang=#lang# --encoding=utf-8 -H --rem-sgml-check=alt">
-<cfset tempfile_in  = GetTempFile(GetTempDirectory(), "spell_")>
-<cfset tempfile_out = GetTempFile(GetTempDirectory(), "spell_")>
-<cfset spellercss   = "../spellerStyle.css">
-<cfset word_win_src = "../wordWindow.js">
-
-<cfset form.checktext = form["textinputs[]"]>
-
-<!--- make no difference between URL and FORM scopes --->
-<cfparam name="url.checktext"  default="">
-<cfparam name="form.checktext" default="#url.checktext#">
-
-<!--- Takes care of those pesky smart quotes from MS apps, replaces them with regular quotes --->
-<cfset submitted_text = ReplaceList(form.checktext,"%u201C,%u201D","%22,%22")>
-
-<!--- submitted_text now is ready for processing --->
-
-<!--- use carat on each line to escape possible aspell commands --->
-<cfset text = "">
-<cfset CRLF = Chr(13) & Chr(10)>
-
-<cfloop list="#submitted_text#" index="field" delimiters=",">
-	<cfset text = text & "%"  & CRLF
-                      & "^A" & CRLF
-                      & "!"  & CRLF>
-	<!--- Strip all tags for the text. (by FredCK - #339 / #681) --->
-	<cfset field = REReplace(URLDecode(field), "<[^>]+>", " ", "all")>
-	<cfloop list="#field#" index="line" delimiters="#CRLF#">
-		<cfset text = ListAppend(text, "^" & Trim(JSStringFormat(line)), CRLF)>
-	</cfloop>
-</cfloop>
-
-<!--- create temp file from the submitted text, this will be passed to aspell to be check for misspelled words --->
-<cffile action="write" file="#tempfile_in#" output="#text#" charset="utf-8">
-
-<!--- execute aspell in an UTF-8 console and redirect output to a file. UTF-8 encoding is lost if done differently --->
-<cfexecute name="cmd.exe" arguments='/c type "#tempfile_in#" | "#aspell_dir#\aspell.exe" #aspell_opts# > "#tempfile_out#"' timeout="100"/>
-
-<!--- read output file for further processing --->
-<cffile action="read" file="#tempfile_out#" variable="food" charset="utf-8">
-
-<!--- remove temp files --->
-<cffile action="delete" file="#tempfile_in#">
-<cffile action="delete" file="#tempfile_out#">
-
-<cfset texts = StructNew()>
-<cfset texts.textinputs = "">
-<cfset texts.words      = "">
-<cfset texts.abort      = "">
-
-<!--- Generate Text Inputs --->
-<cfset i = 0>
-<cfloop list="#submitted_text#" index="textinput">
-  <cfset texts.textinputs = ListAppend(texts.textinputs, 'textinputs[#i#] = decodeURIComponent("#textinput#");', CRLF)>
-  <cfset i = i + 1>
-</cfloop>
-
-<!--- Generate Words Lists --->
-<cfset word_cnt  = 0>
-<cfset input_cnt = -1>
-<cfloop list="#food#" index="aspell_line" delimiters="#CRLF#">
-    <cfset leftChar = Left(aspell_line, 1)>
-	<cfif leftChar eq "*">
-			<cfset input_cnt   = input_cnt + 1>
-			<cfset word_cnt    = 0>
-			<cfset texts.words = ListAppend(texts.words, "words[#input_cnt#] = [];", CRLF)>
-			<cfset texts.words = ListAppend(texts.words, "suggs[#input_cnt#] = [];", CRLF)>
-    <cfelse>
-        <cfif leftChar eq "&" or leftChar eq "##">
-			<!--- word that misspelled --->
-			<cfset bad_word    = Trim(ListGetAt(aspell_line, 2, " "))>
-			<cfset bad_word    = Replace(bad_word, "'", "\'", "ALL")>
-			<!--- sugestions --->
-			<cfset sug_list    = Trim(ListRest(aspell_line, ":"))>
-			<cfset sug_list    = ListQualify(Replace(sug_list, "'", "\'", "ALL"), "'")>
-			<!--- javascript --->
-			<cfset texts.words = ListAppend(texts.words, "words[#input_cnt#][#word_cnt#] = '#bad_word#';", CRLF)>
-			<cfset texts.words = ListAppend(texts.words, "suggs[#input_cnt#][#word_cnt#] = [#sug_list#];", CRLF)>
-			<cfset word_cnt    = word_cnt + 1>
-		</cfif>
-     </cfif>
-</cfloop>
-
-<cfif texts.words eq "">
-  <cfset texts.abort = "alert('Spell check complete.\n\nNo misspellings found.'); top.window.close();">
-</cfif>
-
-<cfcontent type="text/html; charset=utf-8">
-
-<cfoutput><html>
-<head>
-<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
-<link rel="stylesheet" type="text/css" href="#spellercss#" />
-<script language="javascript" src="#word_win_src#"></script>
-<script language="javascript">
-var suggs      = new Array();
-var words      = new Array();
-var textinputs = new Array();
-var error;
-
-#texts.textinputs##CRLF#
-#texts.words#
-#texts.abort#
-
-var wordWindowObj = new wordWindow();
-wordWindowObj.originalSpellings = words;
-wordWindowObj.suggestions = suggs;
-wordWindowObj.textInputs = textinputs;
-
-function init_spell() {
-	// check if any error occured during server-side processing
-	if( error ) {
-		alert( error );
-	} else {
-		// call the init_spell() function in the parent frameset
-		if (parent.frames.length) {
-			parent.init_spell( wordWindowObj );
-		} else {
-			alert('This page was loaded outside of a frameset. It might not display properly');
-		}
-	}
-}
-</script>
-
-</head>
-<body onLoad="init_spell();">
-
-<script type="text/javascript">
-wordWindowObj.writeBody();
-</script>
-
-</body>
-</html></cfoutput>
-<cfsetting enablecfoutputonly="false">

+ 0 - 181
main/inc/lib/fckeditor/editor/dialog/fck_spellerpages/spellerpages/server-scripts/spellchecker.pl

@@ -1,181 +0,0 @@
-#!/usr/bin/perl
-
-use CGI qw/ :standard /;
-use File::Temp qw/ tempfile tempdir /;
-
-# my $spellercss = '/speller/spellerStyle.css';					# by FredCK
-my $spellercss = '../spellerStyle.css';							# by FredCK
-# my $wordWindowSrc = '/speller/wordWindow.js';					# by FredCK
-my $wordWindowSrc = '../wordWindow.js';							# by FredCK
-my @textinputs = param( 'textinputs[]' ); # array
-# my $aspell_cmd = 'aspell';									# by FredCK (for Linux)
-my $aspell_cmd = '"C:\Program Files\Aspell\bin\aspell.exe"';	# by FredCK (for Windows)
-my $lang = 'en_US';
-# my $aspell_opts = "-a --lang=$lang --encoding=utf-8";			# by FredCK
-my $aspell_opts = "-a --lang=$lang --encoding=utf-8 -H --rem-sgml-check=alt";		# by FredCK
-my $input_separator = "A";
-
-# set the 'wordtext' JavaScript variable to the submitted text.
-sub printTextVar {
-	for( my $i = 0; $i <= $#textinputs; $i++ ) {
-	        print "textinputs[$i] = decodeURIComponent('" . escapeQuote( $textinputs[$i] ) . "')\n";
-	}
-}
-
-sub printTextIdxDecl {
-	my $idx = shift;
-	print "words[$idx] = [];\n";
-	print "suggs[$idx] = [];\n";
-}
-
-sub printWordsElem {
-	my( $textIdx, $wordIdx, $word ) = @_;
-	print "words[$textIdx][$wordIdx] = '" . escapeQuote( $word ) . "';\n";
-}
-
-sub printSuggsElem {
-	my( $textIdx, $wordIdx, @suggs ) = @_;
-	print "suggs[$textIdx][$wordIdx] = [";
-	for my $i ( 0..$#suggs ) {
-		print "'" . escapeQuote( $suggs[$i] ) . "'";
-		if( $i < $#suggs ) {
-			print ", ";
-		}
-	}
-	print "];\n";
-}
-
-sub printCheckerResults {
-	my $textInputIdx = -1;
-	my $wordIdx = 0;
-	my $unhandledText;
-	# create temp file
-	my $dir = tempdir( CLEANUP => 1 );
-	my( $fh, $tmpfilename ) = tempfile( DIR => $dir );
-
-	# temp file was created properly?
-
-	# open temp file, add the submitted text.
-	for( my $i = 0; $i <= $#textinputs; $i++ ) {
-		$text = url_decode( $textinputs[$i] );
-		# Strip all tags for the text. (by FredCK - #339 / #681)
-		$text =~ s/<[^>]+>/ /g;
-		@lines = split( /\n/, $text );
-		print $fh "\%\n"; # exit terse mode
-		print $fh "^$input_separator\n";
-		print $fh "!\n";  # enter terse mode
-		for my $line ( @lines ) {
-			# use carat on each line to escape possible aspell commands
-			print $fh "^$line\n";
-		}
-
-	}
-	# exec aspell command
-	my $cmd = "$aspell_cmd $aspell_opts < $tmpfilename 2>&1";
-	open ASPELL, "$cmd |" or handleError( "Could not execute `$cmd`\\n$!" ) and return;
-	# parse each line of aspell return
-	for my $ret ( <ASPELL> ) {
-		chomp( $ret );
-		# if '&', then not in dictionary but has suggestions
-		# if '#', then not in dictionary and no suggestions
-		# if '*', then it is a delimiter between text inputs
-		if( $ret =~ /^\*/ ) {
-			$textInputIdx++;
-			printTextIdxDecl( $textInputIdx );
-			$wordIdx = 0;
-
-		} elsif( $ret =~ /^(&|#)/ ) {
-			my @tokens = split( " ", $ret, 5 );
-			printWordsElem( $textInputIdx, $wordIdx, $tokens[1] );
-			my @suggs = ();
-			if( $tokens[4] ) {
-				@suggs = split( ", ", $tokens[4] );
-			}
-			printSuggsElem( $textInputIdx, $wordIdx, @suggs );
-			$wordIdx++;
-		} else {
-			$unhandledText .= $ret;
-		}
-	}
-	close ASPELL or handleError( "Error executing `$cmd`\\n$unhandledText" ) and return;
-}
-
-sub escapeQuote {
-	my $str = shift;
-	$str =~ s/'/\\'/g;
-	return $str;
-}
-
-sub handleError {
-	my $err = shift;
-	print "error = '" . escapeQuote( $err ) . "';\n";
-}
-
-sub url_decode {
-	local $_ = @_ ? shift : $_;
-	defined or return;
-	# change + signs to spaces
-	tr/+/ /;
-	# change hex escapes to the proper characters
-	s/%([a-fA-F0-9]{2})/pack "H2", $1/eg;
-	return $_;
-}
-
-# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
-# Display HTML
-# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
-
-print <<EOF;
-Content-type: text/html; charset=utf-8
-
-<html>
-<head>
-<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
-<link rel="stylesheet" type="text/css" href="$spellercss"/>
-<script src="$wordWindowSrc"></script>
-<script type="text/javascript">
-var suggs = new Array();
-var words = new Array();
-var textinputs = new Array();
-var error;
-EOF
-
-printTextVar();
-
-printCheckerResults();
-
-print <<EOF;
-var wordWindowObj = new wordWindow();
-wordWindowObj.originalSpellings = words;
-wordWindowObj.suggestions = suggs;
-wordWindowObj.textInputs = textinputs;
-
-
-function init_spell() {
-	// check if any error occured during server-side processing
-	if( error ) {
-		alert( error );
-	} else {
-		// call the init_spell() function in the parent frameset
-		if (parent.frames.length) {
-			parent.init_spell( wordWindowObj );
-		} else {
-			error = "This page was loaded outside of a frameset. ";
-			error += "It might not display properly";
-			alert( error );
-		}
-	}
-}
-
-</script>
-
-</head>
-<body onLoad="init_spell();">
-
-<script type="text/javascript">
-wordWindowObj.writeBody();
-</script>
-
-</body>
-</html>
-EOF

+ 27 - 22
main/inc/lib/fckeditor/editor/dialog/fck_table.html

@@ -155,28 +155,6 @@ function Ok()
 	SetAttribute( table, 'cellSpacing'	, GetE('txtCellSpacing').value ) ;
 	SetAttribute( table, 'cellSpacing'	, GetE('txtCellSpacing').value ) ;
 	SetAttribute( table, 'summary'		, GetE('txtSummary').value ) ;
 	SetAttribute( table, 'summary'		, GetE('txtSummary').value ) ;
 
 
-	var eCaption = oEditor.FCKDomTools.GetFirstChild( table, 'CAPTION' ) ;
-
-	if ( document.getElementById('txtCaption').value != '')
-	{
-		if ( !eCaption )
-		{
-			eCaption = oDoc.createElement( 'CAPTION' ) ;
-			table.insertBefore( eCaption, table.firstChild ) ;
-		}
-
-		eCaption.innerHTML = document.getElementById('txtCaption').value ;
-	}
-	else if ( bExists && eCaption )
-	{
-		// TODO: It causes an IE internal error if using removeChild or
-		// table.deleteCaption() (see #505).
-		if ( oEditor.FCKBrowserInfo.IsIE )
-			eCaption.innerHTML = '' ;
-		else
-			eCaption.parentNode.removeChild( eCaption ) ;
-	}
-
 	var headers = GetE('selHeaders').value ;
 	var headers = GetE('selHeaders').value ;
 	if ( bExists )
 	if ( bExists )
 	{
 	{
@@ -307,10 +285,37 @@ function Ok()
 		oEditor.FCK.InsertElement( table ) ;
 		oEditor.FCK.InsertElement( table ) ;
 	}
 	}
 
 
+	var eCaption = oEditor.FCKDomTools.GetFirstChild( table, 'CAPTION' ) ;
+
+	if ( document.getElementById('txtCaption').value != '' )
+	{
+		if ( !eCaption )
+		{
+			eCaption = oDoc.createElement( 'CAPTION' ) ;
+			table.insertBefore( eCaption, table.firstChild ) ;
+		}
+
+		eCaption.innerHTML = document.getElementById('txtCaption').value ;
+	}
+	else if ( bExists && eCaption )
+	{
+		// TODO: It causes an IE internal error if using removeChild or
+		// table.deleteCaption() (see #505).
+		if ( oEditor.FCKBrowserInfo.IsIE )
+			eCaption.innerHTML = '' ;
+		else
+			eCaption.parentNode.removeChild( eCaption ) ;
+	}
+
 	return true ;
 	return true ;
 }
 }
 
 
 	</script>
 	</script>
+
+	<style type="text/css">
+		body, td, input, textarea, select, label { font-family: Arial, Verdana, Geneva, helvetica, sans-serif; font-size: 11px; }
+	</style>
+
 </head>
 </head>
 <body style="overflow: hidden">
 <body style="overflow: hidden">
 	<table id="otable" cellspacing="0" cellpadding="0" width="100%" border="0" style="height: 100%">
 	<table id="otable" cellspacing="0" cellpadding="0" width="100%" border="0" style="height: 100%">

+ 8 - 3
main/inc/lib/fckeditor/editor/dialog/fck_tablecell.html

@@ -139,10 +139,15 @@ function SelectBorderColor( color )
 
 
 function SelectColor( wich )
 function SelectColor( wich )
 {
 {
-	oEditor.FCKDialog.OpenDialog( 'FCKDialog_Color', oEditor.FCKLang.DlgColorTitle, 'dialog/fck_colorselector.html', 410, 320, wich == 'Back' ? SelectBackColor : SelectBorderColor, window ) ;
+	oEditor.FCKDialog.OpenDialog( 'FCKDialog_Color', oEditor.FCKLang.DlgColorTitle, 'dialog/fck_colorselector.html', 410, 320, wich == 'Back' ? SelectBackColor : SelectBorderColor ) ;
 }
 }
 
 
 	</script>
 	</script>
+
+	<style type="text/css">
+		body, td, input, textarea, select, label { font-family: Arial, Verdana, Geneva, helvetica, sans-serif; font-size: 11px; }
+	</style>
+
 </head>
 </head>
 <body scroll="no" style="overflow: hidden">
 <body scroll="no" style="overflow: hidden">
 	<table cellspacing="0" cellpadding="0" width="100%" border="0" height="100%">
 	<table cellspacing="0" cellpadding="0" width="100%" border="0" height="100%">
@@ -224,8 +229,8 @@ function SelectColor( wich )
 									 <span fcklang="DlgCellType">Cell Type</span>:</td>
 									 <span fcklang="DlgCellType">Cell Type</span>:</td>
 									<td colspan="2">
 									<td colspan="2">
 										&nbsp; <select id="selCellType">
 										&nbsp; <select id="selCellType">
-											<option fcklang="DlgCellTypeData" value="td" />Data
-											<option fcklang="DlgCellTypeHeader" value="th" />Header
+											<option fcklang="DlgCellTypeData" value="td">Data</option>
+											<option fcklang="DlgCellTypeHeader" value="th">Header</option>
 										</select>
 										</select>
 								</tr>
 								</tr>
 								<tr>
 								<tr>

+ 5 - 0
main/inc/lib/fckeditor/editor/dialog/fck_template.html

@@ -208,6 +208,11 @@ function SelectTemplate( index )
 }
 }
 
 
 	</script>
 	</script>
+
+	<style type="text/css">
+		body, td, input, textarea, select, label { font-family: Arial, Verdana, Geneva, helvetica, sans-serif; font-size: 11px; }
+	</style>
+
 </head>
 </head>
 <body scroll="no" style="overflow: hidden; background-color: #ffffff;">
 <body scroll="no" style="overflow: hidden; background-color: #ffffff;">
 	<table width="100%" style="height: 100%;" valign="top">
 	<table width="100%" style="height: 100%;" valign="top">

+ 5 - 0
main/inc/lib/fckeditor/editor/dialog/fck_textarea.html

@@ -69,6 +69,11 @@ function Ok()
 }
 }
 
 
 		</script>
 		</script>
+
+	<style type="text/css">
+		body, td, input, textarea, select, label { font-family: Arial, Verdana, Geneva, helvetica, sans-serif; font-size: 11px; }
+	</style>
+
 	</head>
 	</head>
 	<body style="overflow: hidden">
 	<body style="overflow: hidden">
 		<table height="100%" width="100%">
 		<table height="100%" width="100%">

+ 5 - 0
main/inc/lib/fckeditor/editor/dialog/fck_textfield.html

@@ -85,6 +85,11 @@ function Ok()
 }
 }
 
 
 	</script>
 	</script>
+
+	<style type="text/css">
+		body, td, input, textarea, select, label { font-family: Arial, Verdana, Geneva, helvetica, sans-serif; font-size: 11px; }
+	</style>
+
 </head>
 </head>
 <body style="overflow: hidden">
 <body style="overflow: hidden">
 	<table width="100%" style="height: 100%">
 	<table width="100%" style="height: 100%">

Энэ ялгаанд хэт олон файл өөрчлөгдсөн тул зарим файлыг харуулаагүй болно