You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

1034 lines
35 KiB

  1. <?php
  2. /**
  3. *
  4. */
  5. if(!defined('DOKU_INC')) die();
  6. if(!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN',DOKU_INC.'lib/plugins/');
  7. define('FCK_ACTION_SUBDIR', DOKU_PLUGIN . 'ckgedit/action/');
  8. require_once(DOKU_PLUGIN.'action.php');
  9. require_once(DOKU_PLUGIN.'ckgedit/scripts/setsamesite.php');
  10. class action_plugin_ckgedit_meta extends DokuWiki_Action_Plugin {
  11. var $session_id = false;
  12. var $draft_file;
  13. var $user_rewrite = false;
  14. var $helper;
  15. var $dokuwiki_priority;
  16. var $profile_dwpriority;
  17. var $wiki_text;
  18. var $dw_priority_group;
  19. var $dw_priority_metafn;
  20. var $captcha = false;
  21. var $geshi_dir;
  22. function __construct() {
  23. global $conf;
  24. $this->helper = plugin_load('helper', 'ckgedit');
  25. $this->dokuwiki_priority = false;
  26. $this->dw_priority_group = "NOT_SET";
  27. $this->dw_priority_metafn=metaFN(':ckgedit:dw_priority', '.ser');
  28. if(!file_exists($this->dw_priority_metafn)) {
  29. io_saveFile($this->dw_priority_metafn, serialize(array()));
  30. }
  31. }
  32. /*
  33. * Register its handlers with the dokuwiki's event controller
  34. */
  35. function register(Doku_Event_Handler $controller) {
  36. if($this->helper->is_outOfScope()) return;
  37. $controller->register_hook( 'TPL_METAHEADER_OUTPUT', 'AFTER', $this, 'loadScript');
  38. $controller->register_hook( 'HTML_EDITFORM_INJECTION', 'AFTER', $this, 'preprocess');
  39. $controller->register_hook( 'HTML_EDITFORM_OUTPUT', 'BEFORE', $this, 'insertFormElement');
  40. $controller->register_hook( 'FORM_EDIT_OUTPUT', 'BEFORE', $this, 'insertFormElement');
  41. $controller->register_hook('DOKUWIKI_STARTED', 'BEFORE', $this, 'file_type');
  42. $controller->register_hook('TPL_CONTENT_DISPLAY', 'AFTER', $this, 'setupDWEdit');
  43. $controller->register_hook('DOKUWIKI_STARTED', 'AFTER', $this, 'reset_user_rewrite_check');
  44. $controller->register_hook('DOKUWIKI_DONE', 'BEFORE', $this, 'restore_conf');
  45. $controller->register_hook('AJAX_CALL_UNKNOWN', 'BEFORE', $this,'_ajax_call');
  46. //$controller->register_hook('HTML_UPDATEPROFILEFORM_OUTPUT', 'BEFORE', $this, 'handle_profile_form');
  47. $controller->register_hook('ACTION_SHOW_REDIRECT', 'BEFORE', $this, 'handle_redirect');
  48. }
  49. function handle_redirect(Doku_Event $event, $param) {
  50. global $INPUT;
  51. $ckg_redirect = $INPUT->str('ckgedit_redirect',"");
  52. if($ckg_redirect) $event->data['id'] = $ckg_redirect;
  53. //msg($ckg_redirect);
  54. }
  55. function handle_profile_form(Doku_Event $event, $param) {
  56. if(!$this->getConf('dw_priority')) { return; }
  57. global $INFO;
  58. $client = $_SERVER['REMOTE_USER']; //$INFO['client'];
  59. $ar = unserialize(file_get_contents($this->dw_priority_metafn));
  60. $which = $ar[$client];
  61. $dwed = ""; $cked = "";
  62. if($which == 'N') {
  63. $cked = "checked";
  64. }
  65. else if($which == 'Y') {
  66. $dwed = "checked";
  67. }
  68. $pos = $event->data->findElementByAttribute('type', 'reset');
  69. $_form = '</div></form><br /><form name="ckgeditform" action="#"><div class="no">';
  70. $_form.= '<fieldset ><legend>' . $this->getLang('uprofile_title') .'</legend>';
  71. $_form.= '<label><span><b>DW Editor</b></span> ';
  72. $_form .='<input type="radio" value = "Y" name="cked_selector" ' . $dwed .'></label>&nbsp;';
  73. $_form .='<label><span><b>CK Editor</b></span> ';
  74. $_form .='<input type="radio" value = "N" name="cked_selector" ' . $cked . '></label>';
  75. $_form.= '<br /><label><span><b>User Name: </b></span> ';
  76. $_form.= '<input type="textbox" name="cked_client" disabled value="' . $client .'"/></label>';
  77. $_form.= '<br /><br /><input type="button" value="Save" class="button" ' . "onclick='ckgedit_seteditor_priority(this.form.cked_selector.value,this.form.cked_client.value,this.form.cked_selector);' />&nbsp;";
  78. $_form.= '<input type="reset" value="Reset" class="button" />';
  79. $_form.= '</fieldset>';
  80. $event->data->insertElement($pos+2, $_form);
  81. }
  82. function _ajax_call(Doku_Event $event, $param) {
  83. if ($event->data == 'cked_scaytchk') {
  84. global $lang,$INPUT;
  85. $event->stopPropagation();
  86. $event->preventDefault();
  87. $filename = metaFN('fckl:scayt','.meta');
  88. $msg = $this->locale_xhtml('scayt');
  89. if (!file_exists($filename)) {
  90. io_saveFile($filename,'1');
  91. echo "$msg\n";
  92. return;
  93. }
  94. return;
  95. }
  96. if ($event->data == 'cked_upload') {
  97. global $lang;
  98. $event->stopPropagation();
  99. $event->preventDefault();
  100. global $INPUT;
  101. $id = urldecode($INPUT->str('ckedupl_id'));
  102. $id = str_replace('/', ':',$id);
  103. $this->ajax_debug($id);
  104. $fn = mediaFN($id);
  105. $this->ajax_debug($fn);
  106. $delete = $INPUT->str('ckedupl_del');
  107. if(file_exists($fn)) {
  108. $size = filesize($fn);
  109. $this->ajax_debug("$fn: $size");
  110. }
  111. else $this->ajax_debug("$fn not found");
  112. if($delete && $delete == 'D') {
  113. $size = ""; $ft = "";
  114. $oldf = $id;
  115. $size_tm = $INPUT->str('delsize');
  116. $this->ajax_debug('size_tm='.$size_tm);
  117. if($size_tm != 'undefined' && isset($size_tm)) {
  118. list($size,$ft) = explode(';',$size_tm);
  119. $size=trim($size);
  120. $ft=trim($ft);
  121. $size = '-' . $size;
  122. }
  123. else if(file_exists($fn)) {
  124. if(!$size) {
  125. $size = filesize($fn);
  126. $size = '-' . $size;
  127. }
  128. if(!$ft) {
  129. $ft=filemtime($fn) ;
  130. }
  131. }
  132. else {
  133. $this->ajax_debug("$fn not found");
  134. return;
  135. }
  136. if(isset($ft) && file_exists($fn)) {
  137. $newf = mediaFN($id,$ft);
  138. $this->ajax_debug("newf: $newf fn: $fn");
  139. if(file_exists($fn)){
  140. $this->ajax_debug("old file: $oldf; $fn");
  141. }
  142. else $this->ajax_debug("no old file: $fn");
  143. io_makeFileDir($newf);
  144. if(copy($fn, $newf)) {
  145. $this->ajax_debug("Copying $fn to $newf");
  146. chmod($newf, $conf['fmode']);
  147. $this->ajax_debug("deleting: $fn");
  148. if(!unlink($fn)) $this->ajax_debug("delete failed");
  149. }
  150. else $this->ajax_debug("copy failed");
  151. }
  152. if(file_exists($fn)) {
  153. if(!copy($fn, $newf)) {
  154. $this->ajax_debug ("(2nd try) could not copy $fn to $newf");
  155. return;
  156. }
  157. if(!unlink($fn)) {
  158. $this->ajax_debug ("could not delete $fn");
  159. return;
  160. }
  161. }
  162. addMediaLogEntry($ft, $id, DOKU_CHANGE_TYPE_DELETE, $lang['deleted'],'', null, $size);
  163. }
  164. else addMediaLogEntry(time(), $id, DOKU_CHANGE_TYPE_CREATE, $lang['created'],'', null, $size);
  165. echo 'done';
  166. return;
  167. }
  168. //cked_deletedsize
  169. if ($event->data == 'cked_deletedsize') {
  170. $event->stopPropagation();
  171. $event->preventDefault();
  172. global $INPUT;
  173. $id = urldecode($INPUT->str('cked_delid'));
  174. $fn = mediaFN($id);
  175. if(file_exists($fn)) {
  176. $this->ajax_debug(filesize ($fn) . ';' .filemtime($fn) );
  177. }
  178. else echo ("$fn not found");
  179. return;
  180. }
  181. if ($event->data == 'use_heads') {
  182. $event->stopPropagation();
  183. $event->preventDefault();
  184. global $INPUT;
  185. $page = $INPUT->str('dw_id');
  186. $page = urldecode($page);
  187. $page = ltrim($page, ':');
  188. $t= trim(p_get_first_heading($page));
  189. echo $t;
  190. return;
  191. }
  192. if ($event->data == 'wrap_lang') { // parse and return language file to ckeditor wrap plugin
  193. $event->stopPropagation();
  194. $event->preventDefault();
  195. global $INPUT;
  196. $which = $INPUT->str('lang');
  197. $path = DOKU_PLUGIN . 'wrap/lang/' . $which . '/lang.php';
  198. if(file_exists($path)) {
  199. $data = file($path, FILE_IGNORE_NEW_LINES|FILE_SKIP_EMPTY_LINES );
  200. array_shift($data);
  201. }
  202. else {
  203. $data = array();
  204. }
  205. $result = array();
  206. for($i=0; $i<count($data); $i++) {
  207. list($name, $val) = explode('=',$data[$i]);
  208. $name = str_replace('$lang',"",$name);
  209. $name = trim($name,' ][\'');
  210. if($name == 'picker') $name ='title';
  211. $val = trim($val,' ;\'');
  212. $result[$name] = $val;
  213. }
  214. echo json_encode($result);
  215. return;
  216. }
  217. if ($event->data == 'cked_selector') { //choose profile editor priority
  218. $event->stopPropagation();
  219. $event->preventDefault();
  220. global $INPUT, $USERINFO,$INFO;
  221. if(!isset($USERINFO)) return;
  222. $ar = unserialize(file_get_contents($this->dw_priority_metafn));
  223. $dwp = $INPUT->str('dw_val');
  224. $client = $INPUT->str('dwp_client');
  225. $ar[$client] = $dwp;
  226. $retv = file_put_contents($this->dw_priority_metafn,serialize($ar));
  227. if($retv === false) {
  228. echo $this->dw_priority_metafn;
  229. }
  230. else echo "done";
  231. return;
  232. }
  233. if ($event->data == 'geshi_sel') { //get geshi file names , return as ;; separated string w/o php extensions
  234. $event->stopPropagation();
  235. $event->preventDefault();
  236. if( class_exists('GeSHi')) {
  237. if(defined('GESHI_LANG_ROOT') ) $geshi_dir =GESHI_LANG_ROOT;
  238. }
  239. else {
  240. echo "ENotfound\n";
  241. return ;
  242. }
  243. $gfiles = scandir ($geshi_dir);
  244. $selects = array();
  245. foreach($gfiles as $gfile){
  246. if(is_dir($gfile)) continue;
  247. $gfile = preg_replace("/\.php\n?$/","",$gfile);
  248. $selects[] = $gfile;
  249. }
  250. $selects = implode ( ';;', $selects );
  251. echo $selects;
  252. return;
  253. }
  254. if ($event->data !== 'refresh_save') { // save ckgedit backups in native dw format
  255. return;
  256. }
  257. $event->stopPropagation();
  258. $event->preventDefault();
  259. global $INPUT;
  260. $rsave_id = urldecode($INPUT->str('rsave_id'));
  261. $path = pathinfo($rsave_id);
  262. if($path['extension'] != 'ckgedit') {
  263. echo "failed";
  264. return;
  265. }
  266. $this->wiki_text = urldecode($INPUT->str('wikitext'));
  267. if(!preg_match('/^\s+(\-|\*)/',$this->wiki_text)){
  268. $this->wiki_text = trim($this->wiki_text);
  269. }
  270. /* preserve newlines in code blocks */
  271. $this->wiki_text = preg_replace_callback(
  272. '/(<code>|<file>)(.*?)(<\/code>|<\/file>)/ms',
  273. function($matches) {
  274. return str_replace("\n", "__code_NL__",$matches[0]);
  275. },
  276. $this->wiki_text
  277. );
  278. $this->wiki_text = preg_replace('/^\s*[\r\n]$/ms',"__n__", $this->wiki_text);
  279. $this->wiki_text = preg_replace('/\r/ms',"", $this->wiki_text);
  280. $this->wiki_text = preg_replace('/^\s+(?=\^|\|)/ms',"", $this->wiki_text);
  281. $this->wiki_text = preg_replace('/__n__/',"\n", $this->wiki_text);
  282. $this->wiki_text = str_replace("__code_NL__","\n", $this->wiki_text);
  283. $this->wiki_text .= "\n";
  284. $pos = strpos($this->wiki_text, 'MULTI_PLUGIN_OPEN');
  285. if($pos !== false) {
  286. $this->wiki_text = preg_replace_callback(
  287. '|MULTI_PLUGIN_OPEN.*?MULTI_PLUGIN_CLOSE|ms',
  288. function($matches) {
  289. return preg_replace("/\\\\\\\\/ms","\n",$matches[0]);
  290. },
  291. $this->wiki_text
  292. );
  293. $this->wiki_text = preg_replace_callback(
  294. '|MULTI_PLUGIN_OPEN.*?MULTI_PLUGIN_CLOSE|ms',
  295. function($matches) {
  296. return preg_replace("/^\s+/ms","",$matches[0]);
  297. },
  298. $this->wiki_text
  299. );
  300. }
  301. $this->replace_entities();
  302. $this->wiki_text = preg_replace('/\<\?php/i', '&lt;?php',$this->wiki_text) ;
  303. $this->wiki_text = preg_replace('/\?>/i', '?&gt;',$this->wiki_text) ;
  304. file_put_contents($rsave_id, $this->wiki_text);
  305. echo 'done';
  306. }
  307. function replace_entities() {
  308. global $ents;
  309. $serialized = FCK_ACTION_SUBDIR . 'ent.ser';
  310. $ents = unserialize(file_get_contents($serialized));
  311. $this->wiki_text = preg_replace_callback(
  312. '|(&(\w+);)|',
  313. function($matches) {
  314. global $ents; return $ents[$matches[2]];
  315. },
  316. $this->wiki_text
  317. );
  318. }
  319. function insertFormElement(Doku_Event $event, $param) {
  320. global $FCKG_show_preview;
  321. $param = array();
  322. global $ID;
  323. $dwedit_only = '';
  324. $disabled = '';
  325. $title = $this->getLang('btn_fck_edit');
  326. $dwedit_ns = $this->getConf('dwedit_ns');
  327. if(isset($dwedit_ns) && $dwedit_ns) {
  328. $ns_choices = explode(',',$dwedit_ns);
  329. foreach($ns_choices as $ns) {
  330. $ns = trim($ns);
  331. if(preg_match("/$ns/",$ID)) {
  332. $dwedit_only = 'background-color: #bbb; color: #999';
  333. $disabled = 'disabled';
  334. $title = $this->getLang('btn_dw_edit');
  335. echo "<style type = 'text/css'>#edbtn__preview,#edbtn__save, #edbtn__save { display: inline; } </style>";
  336. break;
  337. }
  338. }
  339. }
  340. $act = $event->data;
  341. if(is_string($act) && $act != 'edit') {
  342. return;
  343. }
  344. // restore preview button if standard DW editor is in place
  345. // $FCKG_show_preview is set in edit.php in the register() function
  346. if($_REQUEST['fck_preview_mode'] != 'nil' && !isset($_COOKIE['FCKG_USE']) && !$FCKG_show_preview) {
  347. echo '<style type="text/css">#edbtn__preview { display:none; }</style>';
  348. }
  349. elseif($FCKG_show_preview) {
  350. echo '<style type="text/css">#edbtn__preview { display: inline; } </style>';
  351. }
  352. else {
  353. echo '<style type="text/css">#edbtn__preview, .btn_show { position:absolute; visibility:hidden; }</style>';
  354. }
  355. global $ckgedit_lang;
  356. if($_REQUEST['fck_preview_mode']== 'preview'){
  357. return;
  358. }
  359. $param = array();
  360. $this->preprocess($event, $param); // create the setDWEditCookie() js function
  361. $button = array
  362. (
  363. '_elem' => 'button',
  364. 'type' => 'submit',
  365. '_action' => 'cancel',
  366. 'value' => $this->getLang('btn_fck_edit'),
  367. 'class' => 'button',
  368. 'id' => 'edbtn__edit',
  369. 'style' => $dwedit_only,
  370. 'disabled' => $disabled,
  371. 'title' => $this->getLang('btn_fck_edit')
  372. );
  373. $pos = strpos($_SERVER['HTTP_USER_AGENT'], 'MSIE');
  374. if($pos === false) {
  375. $button['onclick'] = 'return setDWEditCookie(1, this);';
  376. }
  377. else {
  378. $button['onmousedown'] = 'return setDWEditCookie(1, this);';
  379. }
  380. if(is_a($event->data,\dokuwiki\Form\Form::class)) {
  381. $button = '&nbsp;<button name="do[cancel]" type="submit" class="button" title="' . $title .'" id="edbtn__edit" value="CKG Edit" ' . $disabled. ' style = "' .$dwedit_only.'" onclick="return setDWEditCookie(1, this);"/>CKG Edit</button>&nbsp;';
  382. $pos = $event->data->findPositionByAttribute('type','submit');
  383. $pos+=3;
  384. $event->data->addHTML($button,$pos);
  385. }
  386. else {
  387. $pos = $event->data->findElementByAttribute('type','submit');
  388. $event->data->insertElement(++$pos,$button);
  389. }
  390. return;
  391. }
  392. function preprocess(Doku_Event $event, $param) {
  393. $act = $event->data;
  394. if(is_string($act) && $act != 'edit') {
  395. return;
  396. }
  397. global $INFO, $ckgedit_lang;
  398. $discard = $this->getLang('discard_edits');
  399. echo "<script type='text/javascript'>\n//<![CDATA[ \n";
  400. echo "var useDW_Editor = $this->profile_dwpriority;";
  401. echo "\n //]]> </script>\n";
  402. echo <<<SCRIPT
  403. <script type="text/javascript">
  404. //<![CDATA[
  405. var ckgedit_dwedit_reject = false;
  406. var ckgedit_to_dwedit = false;
  407. function setDWEditCookie(which, e) {
  408. var dom = document.getElementById('ckgedit_mode_type');
  409. if(useDW_Editor) {
  410. document.cookie = 'FCKG_USE=other;expires=0;path=/;SameSite=Lax';
  411. }
  412. else {
  413. document.cookie='FCKG_USE=other;expires=Thu,01-Jan-70 00:00:01 GMT;path=/;SameSite=Lax'
  414. }
  415. if(which == 1) {
  416. if(e && e.form) {
  417. if(e.form['mode']) {
  418. e.form['mode'].value = 'fck';
  419. }
  420. else {
  421. e.form['mode'] = new Object;
  422. e.form['mode'].value = 'fck';
  423. }
  424. }
  425. else dom.value = 'fck';
  426. e.form.submit();
  427. }
  428. else {
  429. document.cookie = 'FCKG_USE=_false_;expires=0;path=/;SameSite=Lax';
  430. dom.value = 'dwiki';
  431. if(JSINFO['chrome_version'] >= 56 && window.dwfckTextChanged) {
  432. }
  433. else if(window.dwfckTextChanged && !window.confirm("$discard")) {
  434. var dom = GetE('dwsave_select');
  435. ckgedit_dwedit_reject=true;
  436. window.dwfckTextChanged = false;
  437. }
  438. }
  439. }
  440. //]]>
  441. </script>
  442. SCRIPT;
  443. }
  444. function check_userfiles() {
  445. global $INFO;
  446. global $conf;
  447. $save_dir = trim($conf['savedir']);
  448. $animal = isset($conf['animal']) ? $conf['animal'] : 'userfiles';
  449. $userfiles = DOKU_PLUGIN . "ckgedit/fckeditor/$animal/";
  450. if(isset($conf['animal']) && $conf['animal'] !== 'userfiles') {
  451. setcookieSameSite('FCK_animal',$animal, $expire, '/');
  452. setcookieSameSite('FCK_animal_inc',$conf['animal_inc'], $expire, '/');
  453. preg_match('#^(.*?' . $conf['animal'] . ')#', $save_dir,$matches);
  454. $save_dir=$matches[1] . '/data/pages';
  455. setcookieSameSite('FCK_farmlocal',$save_dir, $expire, '/');
  456. return;
  457. }
  458. // msg('BASE='. DOKU_BASE);
  459. // msg(DOKU_URL);
  460. // msg('REL='. DOKU_REL);
  461. if(!preg_match('#^\.\/data$#',$save_dir)) {
  462. $data_media = $conf['savedir'] . '/media/';
  463. $domain = trim(DOKU_BASE,'/');
  464. $expire = null;
  465. if(! empty($domain )) {
  466. list($prefix,$mdir) = explode(trim(DOKU_BASE, '/'),$userfiles);
  467. $mdir = ltrim($mdir, '/');
  468. $media_dir = DOKU_BASE . $mdir . 'image/';
  469. }
  470. else $media_dir = '/lib/plugins/ckgedit/fckeditor/'. $animal . '/image/';
  471. setcookieSameSite('FCK_media',$media_dir, $expire, '/');
  472. }
  473. else {
  474. $data_media = DOKU_INC.'data/media/';
  475. }
  476. if($this->getConf('winstyle')) {
  477. $htaccess = $data_media . '.htaccess';
  478. if(!file_exists($htaccess)) {
  479. $security = $userfiles . '.htaccess.security';
  480. if(file_exists($security)) {
  481. if(!copy($security, $htaccess)) {
  482. msg($this->getLang("ws_cantcopy") . $htaccess);
  483. }
  484. else msg($this->getLang("ws_copiedhtaccess"));
  485. }
  486. }
  487. return;
  488. }
  489. if(!is_readable($userfiles) && !is_writable($userfiles)){
  490. msg($this->getLang("userfiles_perm" ) . ' ' . $userfiles) ;
  491. return;
  492. }
  493. $version = io_readFile(DOKU_PLUGIN . 'ckgedit/version');
  494. if(!$version) return;
  495. $meta = metaFN('fckl:symchk','.meta');
  496. $symcheck = io_readFile($meta);
  497. if($symcheck) {
  498. if(trim($version)== trim($symcheck)) { //symlinks should already have been created
  499. return;
  500. }
  501. }
  502. if (function_exists('php_uname')) {
  503. $sys = php_uname() ;
  504. if( preg_match('/Windows/i', $sys) ) {
  505. preg_match('/build\s+(\d+)/',$sys, $matches);
  506. if($matches[1] < 6000) { // we can make symlinks for vista (6000) or later
  507. return;
  508. }
  509. $winlinks = array();
  510. $userfiles = str_replace('/', '\\',$userfiles);
  511. exec("dir " . $userfiles, $output);
  512. foreach($output as $line) {
  513. if(preg_match('/<SYMLINKD>\s+(.*?)\s+\[/i',$line,$matches)) {
  514. $winlinks[] = $matches[1];
  515. }
  516. }
  517. }
  518. }
  519. else if( preg_match('/WINNT/i', PHP_OS) ) { // if we can't get php_uname and a build and this is Windows, just return
  520. return;
  521. }
  522. $show_msg = false;
  523. if($INFO['isadmin'] || $INFO['ismanager'] ) { // only admins and mgrs get messages
  524. $show_msg = true;
  525. }
  526. $link_names = array('flash', 'image', 'media', 'file', 'image');
  527. if(isset($winlinks) && is_array($winlinks) && count($winlinks)) {
  528. $link_names = array_diff($link_names, $winlinks);
  529. }
  530. $links = array();
  531. foreach ($link_names as $ln) {
  532. $links[$ln] = $userfiles . $ln;
  533. }
  534. $bad_create = false;
  535. $successes = array();
  536. if(@file_exists($userfiles)) {
  537. foreach($links as $name => $path) {
  538. if(!is_link($path)) {
  539. if(file_exists($path) && is_file($path) ){
  540. unlink($path);
  541. }
  542. if(file_exists($path) && is_dir($path) ){
  543. rmdir($path);
  544. }
  545. if(!@symlink($data_media,$path) ) {
  546. $bad_create = true;
  547. if($show_msg) msg($this->getLang("sym_not created_1") . " $name link: $path",-1);
  548. }
  549. else {
  550. $successes[] = $name;
  551. }
  552. }
  553. }
  554. }
  555. else {
  556. if($show_msg) {
  557. msg($this->getLang("sym_not created_2") ." $userfiles",-1);
  558. }
  559. }
  560. if($bad_create) {
  561. if($show_msg) {
  562. msg($this->getLang("sym_not created_3") . " $userfiles");
  563. }
  564. }
  565. else {
  566. if(count($successes)) {
  567. $links_created = implode(', ',$successes);
  568. msg($this->getLang("syms_created") . " $links_created",2);
  569. }
  570. }
  571. io_saveFile($meta,$version);
  572. chmod($meta, 0666);
  573. }
  574. function set_session() {
  575. global $USERINFO, $INFO;
  576. global $conf;
  577. global $ID;
  578. global $ACT;
  579. if($this->session_id) return;
  580. $cname = getCacheName($INFO['client'].$ID,'.draft');
  581. $fckl_draft = $cname . '.fckl';
  582. if((isset($ACT) && is_array($ACT)) || isset($_REQUEST['dwedit_preview'])) {
  583. if(isset($ACT['draftdel']) || isset($ACT['cancel']) || isset($_REQUEST['dwedit_preview'])) {
  584. @unlink($fckl_draft);
  585. @unlink($cname);
  586. }
  587. }
  588. if(file_exists($cname)) {
  589. if(file_exists($fckl_draft)) {
  590. unlink($fckl_draft);
  591. }
  592. @rename($cname, $fckl_draft);
  593. }
  594. $session_string = session_id();
  595. $this->session_id = $session_string;
  596. $_SESSION['dwfck_id'] = $session_string;
  597. $default_fb = $this->getConf('default_fb');
  598. if($default_fb == 'none') {
  599. $acl = 255;
  600. }
  601. else {
  602. $acl = auth_quickaclcheck($ID);
  603. }
  604. $_SESSION['dwfck_acl'] = $acl;
  605. if($this->getConf('openfb') || $acl == 255) {
  606. $_SESSION['dwfck_openfb'] = 'y';
  607. }
  608. else {
  609. $_SESSION['dwfck_openfb'] = 'n';
  610. }
  611. $_SESSION['dwfck_grps'] = isset($USERINFO['grps']) ? $USERINFO['grps'] : array();
  612. $_SESSION['dwfck_client'] = $INFO['client'];
  613. $_SESSION['dwfck_sepchar'] = $conf['sepchar'] ;
  614. $_SESSION['dwfck_conf'] = array('sepchar'=> $conf['sepchar'],
  615. 'isadmin'=>($INFO['isadmin'] || $INFO['ismanager']),
  616. 'deaccent'=>$conf['deaccent'], 'useslash'=>$conf['useslash']);
  617. $elems = explode(':', $ID);
  618. array_pop($elems);
  619. $_SESSION['dwfck_ns'] = implode(':',$elems);
  620. $_SESSION['dwfck_top'] = implode('/',$elems);
  621. $_SESSION['dwfck_del'] = $this->getConf('acl_del');
  622. // temp fix for puzzling encoding=url bug in frmresourceslist.html,
  623. // where image loading is processed in GetFileRowHtml()
  624. if(preg_match('/ckgedit:fckeditor:userfiles:image/',$ID)) {
  625. $_SESSION['dwfck_ns'] = "";
  626. $_SESSION['dwfck_top'] = "";
  627. }
  628. $expire = time()+60*60*24*30;
  629. // $expire = null;
  630. setcookieSameSite('FCK_NmSp_acl',$session_string, $expire, '/');
  631. setcookieSameSite('FCK_SCAYT',$this->getConf('scayt'), $expire, '/');
  632. setcookieSameSite('FCK_SCAYT_AUTO',$this->getConf('scayt_auto'), $expire, '/');
  633. $scayt_lang = $this->getConf('scayt_lang');
  634. if(isset($scayt_lang)) {
  635. list($scayt_lang_title,$scayt_lang_code) = explode('/',$scayt_lang);
  636. if($scayt_lang_code!="en_US") {
  637. setcookieSameSite('FCK_SCAYT_LANG',$scayt_lang_code, $expire, '/');
  638. }
  639. }
  640. if ($this->getConf('winstyle')) {
  641. setcookieSameSite('FCKConnector','WIN', $expire, DOKU_BASE);
  642. }
  643. if ($this->dokuwiki_priority && $this->in_dwpriority_group() ) {
  644. if(isset($_COOKIE['FCKG_USE']) && $_COOKIE['FCKG_USE'] == 'other') { //if other go to ckeditor
  645. $expire = time() -60*60*24*30;
  646. setcookieSameSite('FCKG_USE','_false_', $expire, '/');
  647. }
  648. else {
  649. setcookieSameSite('FCKG_USE','_false_', $expire, '/'); //turn off ckeditor
  650. }
  651. }
  652. }
  653. function file_type(Doku_Event $event, $param) {
  654. global $ACT;
  655. global $ID;
  656. global $JSINFO;
  657. global $INPUT;
  658. global $updateVersion;
  659. global $conf, $USERINFO;
  660. if(isset($USERINFO)) {
  661. $this->startup_msg();
  662. }
  663. if((float)$updateVersion >= 51){ // HOGFATHER +
  664. // $conf['plugin']['ckgedit']['allow_ckg_filebrowser'] = 'dokuwiki';
  665. // $conf['plugin']['ckgedit']['default_ckg_filebrowser'] = 'dokuwiki';
  666. }
  667. $auth = auth_quickaclcheck($ID);
  668. $JSINFO['confirm_delete']= $this->getLang('confirm_delete');
  669. $JSINFO['doku_base'] = DOKU_BASE ;
  670. $JSINFO['cg_rev'] = $INPUT->str('rev');
  671. $JSINFO['dw_version'] = (float)$updateVersion;
  672. if(preg_match("/Chrome\/(\d+)/", $_SERVER['HTTP_USER_AGENT'],$cmatch)) {
  673. $JSINFO['chrome_version'] = (float) $cmatch[1];
  674. }
  675. else $JSINFO['chrome_version'] = 0;
  676. $JSINFO['hide_captcha_error'] = $INPUT->str('ckged_captcha_err','none');
  677. $dbl_click_auth = $this->getConf('dw_edit_display');
  678. if($dbl_click_auth == 'none' || empty($_SERVER['REMOTE_USER'])) {
  679. $JSINFO['ckg_dbl_click'] = "";
  680. }
  681. else if($dbl_click_auth == 'all' ||$auth == 255 ) {
  682. $JSINFO['ckg_dbl_click'] = "1";
  683. }
  684. $onoff = $this->getConf('dblclk');
  685. if($onoff == 'off') $JSINFO['ckg_dbl_click'] = "";
  686. $JSINFO['ckg_canonical'] =$conf['canonical'];
  687. $JSINFO['doku_base'] = DOKU_BASE;
  688. $JSINFO['doku_url'] = DOKU_URL;
  689. if($this->helper->has_plugin('tag')) $JSINFO['has_tags'] = "Tag";
  690. if($this->helper->has_plugin('wrap') && ! plugin_isdisabled('wrap')) {
  691. $JSINFO['has_wrap'] = "Wrap";
  692. $wrap_helper = plugin_load('helper','wrap');
  693. if($wrap_helper ) {
  694. $syntaxDiv = $wrap_helper->getConf('syntaxDiv');
  695. if(!empty($syntaxDiv)) {
  696. $JSINFO['wrapDiv'] = $syntaxDiv;
  697. }
  698. else $JSINFO['wrapDiv'] = "";
  699. $syntaxSpan = $wrap_helper->getConf('syntaxSpan');
  700. if(!empty($syntaxSpan)) {
  701. $JSINFO['wrapSpan'] = $syntaxSpan;
  702. }
  703. else $JSINFO['wrapSpan'] = "";
  704. }
  705. }
  706. if(!isset($_COOKIE['ckgEdPaste'])) {
  707. $JSINFO['ckgEdPaste'] = 'off';
  708. }
  709. else {
  710. $JSINFO['ckgEdPaste'] = $_COOKIE['ckgEdPaste'];
  711. }
  712. $JSINFO[ 'rel_links'] = $this->getConf('rel_links');
  713. $JSINFO['ckg_template'] = $conf['template'];
  714. $this->check_userfiles();
  715. $this->profile_dwpriority=($this->dokuwiki_priority && $this->in_dwpriority_group()) ? 1 : 0;
  716. if(isset($_COOKIE['FCK_NmSp'])) $this->set_session();
  717. /* set cookie to pass namespace to FCKeditor's media dialog */
  718. // $expire = time()+60*60*24*30;
  719. $expire = null;
  720. setcookieSameSite('FCK_NmSp',$ID, $expire, '/');
  721. /* Remove TopLevel cookie */
  722. if(isset($_COOKIE['TopLevel'])) {
  723. setcookieSameSite("TopLevel", $_REQUEST['TopLevel'], time()-3600, '/');
  724. }
  725. if(!isset($_REQUEST['id']) || isset($ACT['preview'])) return;
  726. if(isset($_REQUEST['do']) && isset($_REQUEST['do']['edit'])) {
  727. $_REQUEST['do'] = 'edit';
  728. }
  729. }
  730. function loadScript(Doku_Event $event) {
  731. echo <<<SCRIPT
  732. <script type="text/javascript">
  733. //<![CDATA[
  734. function LoadScript( url )
  735. {
  736. document.write( '<scr' + 'ipt type="text/javascript" src="' + url + '"><\/scr' + 'ipt>' ) ;
  737. }
  738. function LoadScriptDefer( url )
  739. {
  740. document.write( '<scr' + 'ipt type="text/javascript" src="' + url + '" defer><\/scr' + 'ipt>' ) ;
  741. }
  742. //]]>
  743. </script>
  744. SCRIPT;
  745. }
  746. /**
  747. * Handle features need for DW Edit:
  748. * 1. Re-label Cancel Button "Exit" when doing a preview
  749. * 2. set up $REQUEST value to identify a preview when in DW Edit , used in
  750. * set_session to remove ckgedit and DW drafts if present after a DW preview
  751. */
  752. function setupDWEdit(Doku_Event $event) {
  753. global $ACT;
  754. // $url = DOKU_URL . 'lib/plugins/ckgedit/scripts/script-cmpr.js';
  755. echo <<<SCRIPT
  756. <script type="text/javascript">
  757. //<![CDATA[
  758. function createRequestValue() {
  759. try{
  760. var inputNode=document.createElement('input');
  761. inputNode.setAttribute('type','hidden');
  762. inputNode.setAttribute('value','yes');
  763. inputNode.setAttribute('name','dwedit_preview');
  764. inputNode.setAttribute('id','dwedit_preview');
  765. var dwform = GetE("dw__editform");
  766. dwform.appendChild(inputNode);
  767. }catch(e) { alert(e); }
  768. }
  769. //]]>
  770. </script>
  771. SCRIPT;
  772. if(isset($_REQUEST['do']) && is_array($_REQUEST['do'])) {
  773. if(isset($_REQUEST['do']['preview'])) {
  774. echo '<script type="text/javascript">';
  775. echo ' var dwform = GetE("dw__editform"); if(dwform["do[draftdel]"]) {dwform["do[draftdel]"].value = "Exit";}';
  776. echo "\ncreateRequestValue()\n";
  777. echo '</script>';
  778. }
  779. }
  780. }
  781. function reset_user_rewrite_check() {
  782. global $ACT;
  783. global $conf;
  784. global $JSINFO,$USERINFO;
  785. if(isset($_COOKIE['FCKG_USE']) && $_COOKIE['FCKG_USE'] =='_false_' ) return;
  786. if($ACT == 'edit') {
  787. $this->user_rewrite = $conf['userewrite'];
  788. $conf['userewrite'] = 0;
  789. }
  790. if((isset($conf['htmlok'])&& $conf['htmlok']) || $this->getConf('htmlblock_ok')) {
  791. $JSINFO['htmlok'] = 1;
  792. }
  793. else $JSINFO['htmlok'] = 0;
  794. }
  795. function startup_msg() {
  796. global $INFO;
  797. global $ACT;
  798. global $updateVersion;
  799. $show_msg = false;
  800. if($INFO['isadmin'] || $INFO['ismanager'] ) { // only admins and mgrs get messages
  801. $show_msg = true;
  802. }
  803. if(!$show_msg) return;
  804. $filename = metaFN('fckl:scayt','.meta');
  805. $msg = $this->locale_xhtml('scayt');
  806. if (!file_exists($filename)) {
  807. io_saveFile($filename,'1');
  808. msg($msg,MSG_MANAGERS_ONLY);
  809. }
  810. else {
  811. if($this->getConf('scayt_auto') != 'off') return;
  812. $this->startup_check_twice($filename, 'scayt');
  813. }
  814. if( (float)$updateVersion < 51) {
  815. return;
  816. }
  817. /*
  818. $filename = metaFN('fckl:hogfather','.meta');
  819. $msg = $this->locale_xhtml('hogfather');
  820. if (!file_exists($filename)) {
  821. io_saveFile($filename,'1');
  822. msg($msg,MSG_MANAGERS_ONLY);
  823. } */
  824. }
  825. function startup_check_twice($filename, $which) {
  826. global $ACT;
  827. if($ACT != 'login') return;
  828. $msg = $this->locale_xhtml($which);
  829. if (file_exists($filename)) {
  830. $reps = io_readFile($filename);
  831. if($reps <2) {
  832. $reminder = $this->getLang('dblclk_reminder');
  833. msg("($reminder) " . $msg,2 );
  834. io_saveFile($filename,$reps+1);
  835. return;
  836. }
  837. }
  838. }
  839. /**
  840. checked for additional dw priority possibilities only if the dw priority option is set to true
  841. */
  842. function in_dwpriority_group() {
  843. global $USERINFO,$INFO;
  844. if(!isset($USERINFO)) return false;
  845. if(empty($this->dw_priority_group)) return true; // all users get dw_priority if no dw_priority group has been set in config
  846. $client = $_SERVER['REMOTE_USER'];
  847. $ar = unserialize(file_get_contents($this->dw_priority_metafn)); // check user profile settings
  848. $expire = time() -60*60*24*30;
  849. if(isset($ar[$client])) {
  850. if($ar[$client] =='Y') return true; // Y = dw_priority selected
  851. if($ar[$client] =='N') {
  852. setcookieSameSite('FCKG_USE','_false_', $expire, '/');
  853. return false; // N = CKEditor selected
  854. }
  855. }
  856. $user_groups = $USERINFO['grps'];
  857. if(in_array($this->dw_priority_group, $user_groups) || in_array("admin", $user_groups)) {
  858. return true;
  859. }
  860. setcookieSameSite('FCKG_USE','_false_', $expire, '/');
  861. return false;
  862. }
  863. function restore_conf() {
  864. global $conf;
  865. global $ACT;
  866. if($ACT == 'edit') { return; }
  867. if($this->user_rewrite !==false) {
  868. $conf['userewrite'] = $this->user_rewrite;
  869. }
  870. }
  871. function ajax_debug($data) {
  872. return;
  873. echo "$data\n";
  874. }
  875. function write_debug($data) {
  876. return;
  877. if (!$handle = fopen(DOKU_INC .'meta.txt', 'a')) {
  878. return;
  879. }
  880. if(is_array($data)) {
  881. $data = print_r($data,true);
  882. }
  883. // Write $somecontent to our opened file.
  884. fwrite($handle, "$data\n");
  885. fclose($handle);
  886. }
  887. }