create_document.php 18 KB

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