create_document.php 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535
  1. <?php // $Id: create_document.php 22259 2009-07-20 18:56:45Z ivantcholakov $
  2. /*
  3. ==============================================================================
  4. Dokeos - elearning and course management software
  5. Copyright (c) 2004-2008 Dokeos SPRL
  6. Copyright (c) 2003 Ghent University (UGent)
  7. Copyright (c) 2001 Universite catholique de Louvain (UCL)
  8. Copyright (c) Olivier Brouckaert
  9. Copyright (c) Bart Mollet, Hogeschool Gent
  10. For a full list of contributors, see "credits.txt".
  11. The full license can be read in "license.txt".
  12. This program is free software; you can redistribute it and/or
  13. modify it under the terms of the GNU General Public License
  14. as published by the Free Software Foundation; either version 2
  15. of the License, or (at your option) any later version.
  16. See the GNU General Public License for more details.
  17. Contact address: Dokeos, rue du Corbeau, 108, B-1030 Brussels, Belgium
  18. Mail: info@dokeos.com
  19. ==============================================================================
  20. */
  21. /**
  22. ==============================================================================
  23. * This file allows creating new html documents with an online WYSIWYG html380
  24. * editor.
  25. *
  26. * @package dokeos.document
  27. ==============================================================================
  28. */
  29. /*
  30. ==============================================================================
  31. INIT SECTION
  32. ==============================================================================
  33. */
  34. // name of the language file that needs to be included
  35. $language_file = 'document';
  36. require_once '../inc/global.inc.php';
  37. $_SESSION['whereami'] = 'document/create';
  38. $this_section = SECTION_COURSES;
  39. $htmlHeadXtra[] = '<script src="'.api_get_path(WEB_LIBRARY_PATH).'javascript/jquery.js" type="text/javascript" language="javascript"></script>'; //jQuery
  40. $htmlHeadXtra[] = '<script type="text/javascript">
  41. function InnerDialogLoaded()
  42. {
  43. /*
  44. var B=new window.frames[0].FCKToolbarButton(\'Templates\',window.frames[0].FCKLang.Templates);
  45. return B.ClickFrame();
  46. */
  47. var isIE = (navigator.appVersion.indexOf(\'MSIE\') != -1) ? true : false ;
  48. var EditorFrame = null ;
  49. if ( !isIE )
  50. {
  51. EditorFrame = window.frames[0] ;
  52. }
  53. else
  54. {
  55. // For this dynamic page window.frames[0] enumerates frames in a different order in IE.
  56. // We need a sure method to locate the frame that contains the online editor.
  57. for ( var i = 0, n = window.frames.length ; i < n ; i++ )
  58. {
  59. if ( window.frames[i].location.toString().indexOf(\'InstanceName=content\') != -1 )
  60. {
  61. EditorFrame = window.frames[i] ;
  62. }
  63. }
  64. }
  65. if ( !EditorFrame )
  66. {
  67. return null ;
  68. }
  69. var B = new EditorFrame.FCKToolbarButton(\'Templates\', EditorFrame.FCKLang.Templates);
  70. return B.ClickFrame();
  71. };
  72. var temp=false;
  73. var temp2=false;
  74. var use_document_title='.api_get_setting('use_document_title').';
  75. var load_default_template = '. ((isset($_POST['submit']) || empty($_SERVER['QUERY_STRING'])) ? 'false' : 'true' ) .';
  76. function launch_templates()
  77. {
  78. //document.getElementById(\'frmModel\').style.display="block";
  79. //document.getElementById(\'content___Frame\').width=\'70%\';
  80. //window.frames[0].FCKToolbarItems.GetItem("Template").Click;
  81. }
  82. function FCKeditor_OnComplete( editorInstance )
  83. {
  84. editorInstance.Events.AttachEvent( \'OnSelectionChange\', check_for_title ) ;
  85. document.getElementById(\'frmModel\').innerHTML = "<iframe style=\'height: 525px; width: 180px;\' scrolling=\'no\' frameborder=\'0\' src=\''.api_get_path(WEB_LIBRARY_PATH).'fckeditor/editor/fckdialogframe.html \'>";
  86. }
  87. function check_for_title()
  88. {
  89. if(temp==true){
  90. // This functions shows that you can interact directly with the editor area
  91. // DOM. In this way you have the freedom to do anything you want with it.
  92. // Get the editor instance that we want to interact with.
  93. var oEditor = FCKeditorAPI.GetInstance(\'content\') ;
  94. // Get the Editor Area DOM (Document object).
  95. var oDOM = oEditor.EditorDocument ;
  96. var iLength ;
  97. var contentText ;
  98. var contentTextArray;
  99. var bestandsnaamNieuw = "";
  100. var bestandsnaamOud = "";
  101. // The are two diffent ways to get the text (without HTML markups).
  102. // It is browser specific.
  103. if( document.all ) // If Internet Explorer.
  104. {
  105. contentText = oDOM.body.innerText ;
  106. }
  107. else // If Gecko.
  108. {
  109. var r = oDOM.createRange() ;
  110. r.selectNodeContents( oDOM.body ) ;
  111. contentText = r.toString() ;
  112. }
  113. var index=contentText.indexOf("/*<![CDATA");
  114. contentText=contentText.substr(0,index);
  115. // Compose title if there is none
  116. contentTextArray = contentText.split(\' \') ;
  117. var x=0;
  118. for(x=0; (x<5 && x<contentTextArray.length); x++)
  119. {
  120. if(x < 4)
  121. {
  122. bestandsnaamNieuw += contentTextArray[x] + \' \';
  123. }
  124. else
  125. {
  126. bestandsnaamNieuw += contentTextArray[x];
  127. }
  128. }
  129. // comment see FS#3335
  130. // if(document.getElementById(\'title_edited\').value == "false")
  131. // {
  132. // document.getElementById(\'filename\').value = bestandsnaamNieuw;
  133. // if(use_document_title){
  134. // document.getElementById(\'title\').value = bestandsnaamNieuw;
  135. // }
  136. // }
  137. }
  138. temp=true;
  139. }
  140. function trim(s)
  141. {
  142. while(s.substring(0,1) == \' \') {
  143. s = s.substring(1,s.length);
  144. }
  145. while(s.substring(s.length-1,s.length) == \' \') {
  146. s = s.substring(0,s.length-1);
  147. }
  148. return s;
  149. }
  150. function check_if_still_empty()
  151. {
  152. if(trim(document.getElementById(\'filename\').value) != "")
  153. {
  154. document.getElementById(\'title_edited\').value = "true";
  155. }
  156. }
  157. function setFocus(){
  158. $("#document_title").focus();
  159. }
  160. $(window).load(function () {
  161. setFocus();
  162. });
  163. </script>';
  164. require_once api_get_path(LIBRARY_PATH).'fileUpload.lib.php';
  165. require_once api_get_path(LIBRARY_PATH).'document.lib.php';
  166. require_once api_get_path(LIBRARY_PATH).'groupmanager.lib.php';
  167. require_once api_get_path(LIBRARY_PATH).'formvalidator/FormValidator.class.php';
  168. $nameTools = get_lang('CreateDocument');
  169. /*
  170. -----------------------------------------------------------
  171. Constants and variables
  172. -----------------------------------------------------------
  173. */
  174. $dir = isset($_GET['dir']) ? Security::remove_XSS($_GET['dir']) : Security::remove_XSS($_POST['dir']); // please do not modify this dirname formatting
  175. /*
  176. ==============================================================================
  177. MAIN CODE
  178. ==============================================================================
  179. */
  180. if (api_is_in_group())
  181. {
  182. $group_properties = GroupManager::get_group_properties($_SESSION['_gid']);
  183. }
  184. if (strstr($dir, '..'))
  185. {
  186. $dir = '/';
  187. }
  188. if ($dir[0] == '.')
  189. {
  190. $dir = substr($dir, 1);
  191. }
  192. if ($dir[0] != '/')
  193. {
  194. $dir = '/'.$dir;
  195. }
  196. if ($dir[strlen($dir) - 1] != '/')
  197. {
  198. $dir .= '/';
  199. }
  200. // Configuration for the FCKEDITOR
  201. $doc_tree= explode('/', $dir);
  202. $count_dir = count($doc_tree) -2; // "2" because at the begin and end there are 2 "/"
  203. // Level correction for group documents.
  204. if (!empty($group_properties['directory']))
  205. {
  206. $count_dir = $count_dir > 0 ? $count_dir - 1 : 0;
  207. }
  208. $relative_url='';
  209. for($i=0;$i<($count_dir);$i++)
  210. {
  211. $relative_url.='../';
  212. }
  213. // we do this in order to avoid the condition in html_editor.php ==> if ($this -> fck_editor->Config['CreateDocumentWebDir']=='' || $this -> fck_editor->Config['CreateDocumentDir']== '')
  214. if ($relative_url== '') {
  215. $relative_url = '/';
  216. }
  217. $is_allowed_to_edit = api_is_allowed_to_edit(null,true);
  218. $html_editor_config = array(
  219. 'ToolbarSet' => ($is_allowed_to_edit ? 'Documents' :'DocumentsStudent'),
  220. 'Width' => '100%',
  221. 'Height' => '600',
  222. 'FullPage' => true,
  223. 'InDocument' => true,
  224. 'CreateDocumentDir' => $relative_url,
  225. 'CreateDocumentWebDir' => (empty($group_properties['directory']))
  226. ? api_get_path('WEB_COURSE_PATH').$_course['path'].'/document/'
  227. : api_get_path('WEB_COURSE_PATH').api_get_course_path().'/document'.$group_properties['directory'].'/',
  228. 'BaseHref' => api_get_path('WEB_COURSE_PATH').$_course['path'].'/document'.$dir
  229. );
  230. $filepath = api_get_path('SYS_COURSE_PATH').$_course['path'].'/document'.$dir;
  231. if (!is_dir($filepath)) {
  232. $filepath = api_get_path('SYS_COURSE_PATH').$_course['path'].'/document/';
  233. $dir = '/';
  234. }
  235. //------------
  236. /**************************************************/
  237. $to_group_id = 0;
  238. if (isset ($_SESSION['_gid']) && $_SESSION['_gid'] != '') {
  239. $req_gid = '&amp;gidReq='.$_SESSION['_gid'];
  240. $interbreadcrumb[] = array ("url" => "../group/group_space.php?gidReq=".$_SESSION['_gid'], "name" => get_lang('GroupSpace'));
  241. $noPHP_SELF = true;
  242. $to_group_id = $_SESSION['_gid'];
  243. $group = GroupManager :: get_group_properties($to_group_id);
  244. $path = explode('/', $dir);
  245. if ('/'.$path[1] != $group['directory']) {
  246. api_not_allowed(true);
  247. }
  248. }
  249. $interbreadcrumb[] = array ("url" => "./document.php?curdirpath=".urlencode($_GET['dir']).$req_gid, "name" => get_lang('Documents'));
  250. if (!$is_allowed_in_course)
  251. api_not_allowed(true);
  252. if (!($is_allowed_to_edit || $_SESSION['group_member_with_upload_rights'])) {
  253. api_not_allowed(true);
  254. }
  255. /*
  256. -----------------------------------------------------------
  257. Header
  258. -----------------------------------------------------------
  259. */
  260. event_access_tool(TOOL_DOCUMENT);
  261. $display_dir = $dir;
  262. if (isset ($group)) {
  263. $display_dir = explode('/', $dir);
  264. unset ($display_dir[0]);
  265. unset ($display_dir[1]);
  266. $display_dir = implode('/', $display_dir);
  267. }
  268. // Create a new form
  269. $form = new FormValidator('create_document');
  270. // form title
  271. $form->addElement('header', '', $nameTools);
  272. $renderer = & $form->defaultRenderer();
  273. // Hidden element with current directory
  274. $form->addElement('hidden', 'dir');
  275. $default['dir'] = $dir;
  276. // Filename
  277. $form->addElement('hidden','title_edited','false','id="title_edited"');
  278. /**
  279. * Check if a document width the choosen filename allready exists
  280. */
  281. function document_exists($filename) {
  282. global $filepath;
  283. $filename = addslashes(trim($filename));
  284. $filename = Security::remove_XSS($filename);
  285. $filename = replace_dangerous_char($filename);
  286. $filename = disable_dangerous_file($filename);
  287. return !file_exists($filepath.$filename.'.html');
  288. }
  289. // Change the default renderer for the filename-field to display the dir and extension
  290. /*
  291. $renderer = & $form->defaultRenderer();
  292. */
  293. //$filename_template = str_replace('{element}', "<tt>$display_dir</tt> {element} <tt>.html</tt>", $renderer->_elementTemplate);
  294. $filename_template = str_replace('{element}', "{element}", $renderer->_elementTemplate);
  295. $renderer->setElementTemplate($filename_template, 'filename');
  296. // initialize group array
  297. $group = array();
  298. // If allowed, add element for document title
  299. if (api_get_setting('use_document_title') == 'true') {
  300. //$group[]= $form->add_textfield('title', get_lang('Title'),true,'class="input_titles" id="title"');
  301. // replace the add_textfield with this
  302. $group[]=$form->createElement('text','title',get_lang('Title'),'class="input_titles" id="document_title"');
  303. //$form->applyFilter('title','trim');
  304. //$form->addRule('title', get_lang('ThisFieldIsRequired'), 'required');
  305. // Added by Ivan Tcholakov, 10-OCT-2009.
  306. $form->addElement('hidden', 'filename', '', array('id' => 'filename'));
  307. //
  308. } else {
  309. //$form->add_textfield('filename', get_lang('FileName'),true,'class="input_titles" id="filename" onblur="check_if_still_empty()"');
  310. // replace the add_textfield with this
  311. $group[]=$form->createElement('text','filename',get_lang('FileName'),'class="input_titles" id="document_title" onblur="check_if_still_empty()"');
  312. //$form->applyFilter('filename','trim');
  313. //$form->addRule('filename', get_lang('ThisFieldIsRequired'), 'required');
  314. //$form->addRule('filename', get_lang('FileExists'), 'callback', 'document_exists');
  315. // Added by Ivan Tcholakov, 10-OCT-2009.
  316. $form->addElement('hidden', 'title', '', array('id' => 'title'));
  317. //
  318. }
  319. /* Show read-only box only in groups */
  320. if(!empty($_SESSION['_gid'])) {
  321. //$renderer->setElementTemplate('<div class="row"><div class="label"></div><div class="formw">{element}{label}</div></div>', 'readonly');
  322. $group[]= $form->createElement('checkbox','readonly','',get_lang('ReadOnly'));
  323. }
  324. // add group to the form
  325. $form->addGroup($group, 'filename_group', api_get_setting('use_document_title') == 'true' ? get_lang('Title') : get_lang('FileName') ,'&nbsp;&nbsp;&nbsp;', false);
  326. $form->addRule('filename_group', get_lang('ThisFieldIsRequired'), 'required');
  327. if (api_get_setting('use_document_title') == 'true') {
  328. $form->addGroupRule('filename_group', array(
  329. 'title' => array(
  330. array(get_lang('ThisFieldIsRequired'), 'required'),
  331. array(get_lang('FileExists'),'callback', 'document_exists')
  332. )
  333. ));
  334. } else {
  335. $form->addGroupRule('filename_group', array(
  336. 'filename' => array(
  337. array(get_lang('ThisFieldIsRequired'), 'required'),
  338. array(get_lang('FileExists'),'callback', 'document_exists')
  339. )
  340. ));
  341. }
  342. $current_session_id = api_get_session_id();
  343. //$form->addElement('style_submit_button', 'submit', get_lang('SaveDocument'), 'class="save"');
  344. // HTML-editor
  345. $renderer->setElementTemplate('<div class="row"><div class="label" id="frmModel" style="overflow: visible;"></div><div class="formw">{element}</div></div>', 'content');
  346. $form->add_html_editor('content','', false, false, $html_editor_config);
  347. // Comment-field
  348. //$form->addElement('textarea', 'comment', get_lang('Comment'), array ('rows' => 5, 'cols' => 50));
  349. $form->addElement('style_submit_button', 'submit', get_lang('langCreateDoc'), 'class="save"');
  350. $form->setDefaults($default);
  351. // HTML
  352. /*
  353. $form->addElement('html','<div id="frmModel" style="display:block; height:525px; width:240px; position:absolute; top:115px; left:1px;"></div>');
  354. */
  355. // If form validates -> save the new document
  356. if ($form->validate()) {
  357. $values = $form->exportValues();
  358. $readonly = isset($values['readonly']) ? 1 : 0;
  359. $values['title']=addslashes(trim($values['title']));
  360. $values['title'] = Security::remove_XSS($values['title']);
  361. $values['title'] = replace_dangerous_char($values['title']);
  362. $values['title'] = disable_dangerous_file($values['title']);
  363. $values['filename'] = addslashes(trim($values['filename']));
  364. $values['filename'] = Security::remove_XSS($values['filename']);
  365. $values['filename'] = replace_dangerous_char($values['filename']);
  366. $values['filename'] = disable_dangerous_file($values['filename']);
  367. if (api_get_setting('use_document_title') != 'true') {
  368. $values['title'] = $values['filename'];
  369. } else {
  370. $values['filename'] = $values['title'];
  371. }
  372. $filename = $values['filename'];
  373. $title = $values['title'];
  374. $extension = 'html';
  375. $texte = $values['content'];
  376. $texte=Security::remove_XSS($texte,COURSEMANAGERLOWSECURITY);
  377. if (!strstr($texte, '/css/frames.css')) {
  378. $texte = str_replace('</head>', '<style> body{margin:10px;}</style> <link rel="stylesheet" href="./css/frames.css" type="text/css" /></head>', $texte);
  379. }
  380. if ($fp = @ fopen($filepath.$filename.'.'.$extension, 'w')) {
  381. $texte = text_filter($texte);
  382. $content = str_replace(api_get_path('WEB_COURSE_PATH'), $_configuration['url_append'].'/courses/', $texte);
  383. // change the path of mp3 to absolute
  384. // first regexp deals with ../../../ urls
  385. // Disabled by Ivan Tcholakov.
  386. //$content = preg_replace("|(flashvars=\"file=)(\.+/)+|","$1".api_get_path(REL_COURSE_PATH).$_course['path'].'/document/',$content);
  387. //second regexp deals with audio/ urls
  388. // Disabled by Ivan Tcholakov.
  389. //$content = preg_replace("|(flashvars=\"file=)([^/]+)/|","$1".api_get_path(REL_COURSE_PATH).$_course['path'].'/document/$2/',$content);
  390. fputs($fp, $content);
  391. fclose($fp);
  392. $files_perm = api_get_setting('permissions_for_new_files');
  393. $files_perm = octdec(!empty($files_perm)?$files_perm:'0770');
  394. chmod($filepath.$filename.'.'.$extension,$files_perm);
  395. $perm = api_get_setting('permissions_for_new_directories');
  396. $perm = octdec(!empty($perm)?$perm:'0770');
  397. if (!is_dir($filepath.'css')) {
  398. mkdir($filepath.'css');
  399. chmod($filepath.'css', $perm);
  400. $doc_id = add_document($_course, $dir.'css', 'folder', 0, 'css');
  401. api_item_property_update($_course, TOOL_DOCUMENT, $doc_id, 'FolderCreated', $_user['user_id'],null,null,null,null,$current_session_id);
  402. api_item_property_update($_course, TOOL_DOCUMENT, $doc_id, 'invisible', $_user['user_id'],null,null,null,null,$current_session_id);
  403. }
  404. if (!is_file($filepath.'css/frames.css')) {
  405. //make a copy of the current css for the new document
  406. copy(api_get_path(SYS_CODE_PATH).'css/'.api_get_setting('stylesheets').'/frames.css', $filepath.'css/frames.css');
  407. $doc_id = add_document($_course, $dir.'css/frames.css', 'file', filesize($filepath.'css/frames.css'), 'frames.css');
  408. api_item_property_update($_course, TOOL_DOCUMENT, $doc_id, 'DocumentAdded', $_user['user_id'],null,null,null,null,$current_session_id);
  409. api_item_property_update($_course, TOOL_DOCUMENT, $doc_id, 'invisible', $_user['user_id'],null,null,null,null,$current_session_id);
  410. }
  411. $file_size = filesize($filepath.$filename.'.'.$extension);
  412. $save_file_path = $dir.$filename.'.'.$extension;
  413. $document_id = add_document($_course, $save_file_path, 'file', $file_size, $filename,null,$readonly);
  414. if ($document_id) {
  415. api_item_property_update($_course, TOOL_DOCUMENT, $document_id, 'DocumentAdded', $_user['user_id'], $to_group_id,null,null,null,$current_session_id);
  416. //update parent folders
  417. item_property_update_on_folder($_course, $_GET['dir'], $_user['user_id']);
  418. $new_comment = isset ($_POST['comment']) ? trim($_POST['comment']) : '';
  419. $new_title = isset ($_POST['title']) ? trim($_POST['title']) : '';
  420. if ($new_comment || $new_title) {
  421. $TABLE_DOCUMENT = Database::get_course_table(TABLE_DOCUMENT);
  422. $ct = '';
  423. if ($new_comment)
  424. $ct .= ", comment='$new_comment'";
  425. if ($new_title)
  426. $ct .= ", title='$new_title'";
  427. Database::query("UPDATE $TABLE_DOCUMENT SET".substr($ct, 1)." WHERE id = '$document_id'", __FILE__, __LINE__);
  428. }
  429. $dir= substr($dir,0,-1);
  430. header('Location: document.php?curdirpath='.urlencode($dir));
  431. exit ();
  432. } else {
  433. Display :: display_header($nameTools, "Doc");
  434. Display :: display_error_message(get_lang('Impossible'));
  435. Display :: display_footer();
  436. }
  437. } else {
  438. Display :: display_header($nameTools, "Doc");
  439. //api_display_tool_title($nameTools);
  440. Display :: display_error_message(get_lang('Impossible'));
  441. Display :: display_footer();
  442. }
  443. } else {
  444. Display :: display_header($nameTools, "Doc");
  445. //api_display_tool_title($nameTools);
  446. // actions
  447. echo '<div class="actions">';
  448. // link back to the documents overview
  449. echo '<a href="document.php?curdirpath='.Security::remove_XSS($_GET['dir']).'">'.Display::return_icon('back.png',get_lang('Back').' '.get_lang('To').' '.get_lang('DocumentsOverview')).get_lang('BackTo').' '.get_lang('DocumentsOverview').'</a>';
  450. echo '</div>';
  451. $form->display();
  452. Display :: display_footer();
  453. }
  454. ?>