function macro_Edit($formatter, $value, $options = '') { global $DBInfo; $options['mode'] = !empty($options['mode']) ? $options['mode'] : ''; $edit_rows = $DBInfo->edit_rows ? $DBInfo->edit_rows : 16; $cols = get_textarea_cols(); $use_js = preg_match('/Lynx|w3m|links/', $_SERVER['HTTP_USER_AGENT']) ? 0 : 1; $rows = (!empty($options['rows']) and $options['rows'] > 5) ? $options['rows'] : $edit_rows; $rows = $rows < 60 ? $rows : $edit_rows; $cols = (!empty($options['cols']) and $options['cols'] > 60) ? $options['cols'] : $cols; $text = !empty($options['savetext']) ? $options['savetext'] : ''; $editlog = !empty($options['editlog']) ? $options['editlog'] : ""; if (empty($editlog) and !empty($options['comment'])) { $editlog = _stripslashes($options['comment']); } $editlog = _html_escape($editlog); $args = explode(',', $value); if (in_array('nohints', $args)) { $options['nohints'] = 1; } if (in_array('nomenu', $args)) { $options['nomenu'] = 1; } $preview = !empty($options['preview']) ? $options['preview'] : 0; if ($options['action'] == 'edit') { $saveaction = 'savepage'; } else { $saveaction = $options['action']; } $extraform = !empty($formatter->_extra_form) ? $formatter->_extra_form : ''; $options['notmpl'] = isset($options['notmpl']) ? $options['notmpl'] : 0; $form = ''; if (!$options['notmpl'] and (!empty($options['template']) or !$formatter->page->exists()) and !$preview) { $options['linkto'] = "?action=edit&template="; $options['limit'] = -1; $tmpls = macro_TitleSearch($formatter, $DBInfo->template_regex, $options); if ($tmpls) { $tmpls = '<div>' . _("Use one of the following templates as an initial release :\n") . $tmpls; $tmpls .= sprintf(_("To create your own templates, add a page with '%s' pattern."), $DBInfo->template_regex) . "\n</div>\n"; } if (isset($options['tmpls'])) { $options['tmpls'] = $tmpls; $tmpls = ''; } } $merge_btn = _("Merge"); $merge_btn2 = _("Merge manually"); $merge_btn3 = _("Ignore conflicts"); $extra = ''; if (!empty($options['conflict'])) { $extra = '<span class="button"><input type="submit" class="button" name="button_merge" value="' . $merge_btn . '" /></span>'; if ($options['conflict'] == 2) { $extra .= ' <span class="button"><input type="submit" class="button" name="manual_merge" value="' . $merge_btn2 . '" /></span>'; if ($DBInfo->use_forcemerge) { $extra .= ' <span class="button"><input type="submit" class="button" name="force_merge" value="' . $merge_btn3 . '" /></span>'; } } } $hidden = ''; if (!empty($options['section'])) { $hidden = '<input type="hidden" name="section" value="' . $options['section'] . '" />'; } if (!empty($options['mode'])) { $hidden = '<input type="hidden" name="mode" value="' . $options['mode'] . '" />'; } # make a edit form if (empty($options['simple'])) { $form .= "<a id='editor'></a>\n"; } if (isset($DBInfo->use_preview_anchor)) { $preview_anchor = '#preview'; } else { $preview_anchor = ''; } if (isset($options['page'][0])) { $previewurl = $formatter->link_url(_rawurlencode($options['page']), $preview_anchor); } else { $previewurl = $formatter->link_url($formatter->page->urlname, $preview_anchor); } $menu = ''; $sep = ''; if (empty($DBInfo->use_resizer) and (empty($options['noresizer']) or !$use_js)) { $sep = ' | '; $menu = $formatter->link_to("?action=edit&rows=" . ($rows - 3), _("ReduceEditor")); $menu .= $sep . $formatter->link_to("?action=edit&rows=" . ($rows + 3), _("EnlargeEditor")); } if (empty($options['nomenu'])) { $menu .= $sep . $formatter->link_tag('InterWiki', "", _("InterWiki")); $sep = ' | '; $menu .= $sep . $formatter->link_tag('HelpOnEditing', "", _("HelpOnEditing")); } $form .= $menu; $ajax = ''; $js = ''; if (!empty($options['action_mode']) and $options['action_mode'] == 'ajax') { $ajax = " onsubmit='savePage(this);return false'"; } $formh = sprintf('<form id="editform" method="post" action="%s"' . $ajax . '>', $previewurl); if ($text) { $raw_body = preg_replace("/\r\n|\r/", "\n", $text); } else { if (!empty($options['template'])) { $p = new WikiPage($options['template']); $raw_body = preg_replace("/\r\n|\r/", "\n", $p->get_raw_body()); } else { if (isset($formatter->_raw_body)) { # low level XXX $raw_body = preg_replace("/\r\n|\r/", "\n", $formatter->_raw_body); } else { if ($options['mode'] != 'edit' and $formatter->page->exists()) { $raw_body = preg_replace("/\r\n|\r/", "\n", $formatter->page->_get_raw_body()); if (isset($options['section'])) { $sections = _get_sections($raw_body); if ($sections[$options['section']]) { $raw_body = $sections[$options['section']]; } #else ignore } } else { $raw_body = ''; if (!empty($options['orig_pagename'])) { $raw_body = "#title {$options['orig_pagename']}\n"; } if (strpos($options['page'], ' ') > 0) { #$raw_body="#title $options[page]\n"; $options['page'] = '["' . $options['page'] . '"]'; } $guide = sprintf(_("Describe %s here"), $options['page']); if (empty($DBInfo->use_edit_placeholder)) { $raw_body .= $guide; $guide = ''; } else { $guide = ' placeholder="' . _html_escape($guide) . '"'; } $js = <<<EOF <script type="text/javascript"> /*<![CDATA[*/ (function() { function selectGuide() { var txtarea = document.getElementById('editor-textarea'); if (!txtarea) return; txtarea.focus(); var txt = txtarea.value; var pos = 0; if (txt.indexOf('#title ') == 0) { pos = txt.indexOf("\\n") + 1; } var end = txt.length; if (txtarea.selectionStart || txtarea.selectionStart == '0') { // goto txtarea.selectionStart = pos; txtarea.selectionEnd = end; } else if (document.selection && !is_gecko && !is_opera) { // IE var r = document.selection.createRange(); var range = r.duplicate(); range.moveStart('character', pos); range.moveEnd('character', end - pos); r.setEndPoint('StartToStart', range); range.select(); } } var oldOnLoad = window.onLoad; window.onload = function() { try { oldOnLoad() } catch(e) {}; selectGuide(); } })(); /*]]>*/ </script> EOF; } } } } $summary_guide = ''; if (!empty($options['.minorfix'])) { $summary_guide = _("This ia a minor edit."); } if (empty($DBInfo->use_edit_placeholder)) { $summary_guide = ''; } else { $summary_guide = ' placeholder="' . _html_escape($summary_guide) . '"'; } # for conflict check if (!empty($options['datestamp'])) { $datestamp = $options['datestamp']; } else { if (!empty($formatter->_mtime)) { # low level control XXX $datestamp = $formatter->_mtime; } else { $datestamp = $formatter->page->mtime(); } } if (!empty($DBInfo->use_savepage_hash)) { // generate hash $ticket = getTicket($datestamp . $DBInfo->user->id, $_SERVER['REMOTE_ADDR']); $hash = md5($ticket); $hidden .= "\n<input type=\"hidden\" name=\"hash\" value=\"" . $hash . "\" />\n"; } $raw_body = str_replace(array("&", "<"), array("&", "<"), $raw_body); # get categories $select_category = ''; if (!empty($DBInfo->use_category) and empty($options['nocategories'])) { $categories = $DBInfo->getLikePages($DBInfo->category_regex, -1); if ($categories) { $select_category = "<label for='category-select'>" . _("Category") . "</label><select id='category-select' name='category' tabindex='4'>\n"; $mlen = 0; $opts = ''; foreach ($categories as $category) { $len = mb_strwidth($category); $category = _html_escape($category); if ($len > $mlen) { $mlen = $len; } $opts .= "<option value=\"{$category}\">{$category}</option>\n"; } $lab = _(" Select "); $len = intval(($mlen - mb_strwidth($lab)) / 2); $pad = str_repeat('-', $len); $select_category .= "<option value=''>" . $pad . $lab . $pad . "</option>\n" . $opts; $select_category .= "</select>\n"; } } $extra_check = ''; if (empty($options['minor']) and !empty($DBInfo->use_minoredit)) { $user =& $DBInfo->user; # get from COOKIE VARS if (!empty($DBInfo->owners) and in_array($user->id, $DBInfo->owners)) { $extra_check = ' ' . _("Minor edit") . "<input type='checkbox' tabindex='3' name='minor' />"; } } $captcha = ''; if ($use_js and !empty($DBInfo->use_ticket) and $options['id'] == 'Anonymous') { $msg = _("Refresh"); $seed = md5(base64_encode(time())); $ticketimg = $formatter->link_url($formatter->page->urlname, '?action=ticket&__seed=' . $seed . '&t='); $onclick = " onclick=\"document.getElementById('captcha_img').src ='" . $ticketimg . "'+ Math.random()\""; $captcha = <<<EXTRA <div class='captcha' style='float:right'><div><span class='captchaImg'><img id="captcha_img" src="{$ticketimg}" alt="captcha" /></span></div> <button type='button' class='refresh-icon'{$onclick}><span>{$msg}</span></button><input type="text" tabindex="2" size="10" name="check" /> <input type="hidden" name="__seed" value="{$seed}" /></div> EXTRA; } $summary_msg = _("Summary"); $wysiwyg_btn = ''; $skip_preview = ''; if (empty($options['simple'])) { $preview_btn = '<span class="button"><input type="submit" class="button" tabindex="6" name="button_preview" class="preview-button" value="' . _("Preview") . '" /></span>'; $changes_btn = ''; if ($formatter->page->exists()) { $changes_btn = ' <span class="button"><input type="submit" class="button" tabindex="6" name="button_changes" class="preview-button" value="' . _("Show changes") . '" /></span>'; } if ($preview and empty($options['conflict'])) { $skip_preview = ' ' . $formatter->link_to('#preview', _("Skip to preview"), ' class="preview-anchor"'); } if (!empty($DBInfo->use_wikiwyg)) { $confirm = 'false'; if (!empty($DBInfo->wikiwyg_confirm)) { $confirm = 'null'; } $wysiwyg_msg = _("GUI"); $wysiwyg_btn .= ' <button type="button" tabindex="7"' . ' onclick="javascript:sectionEdit(null,' . $confirm . ',null)" ><span>' . $wysiwyg_msg . '</span></button>'; } $summary = <<<EOS <span id='edit-summary'><label for='input-summary'>{$summary_msg}</label><input name="comment" id='input-summary' value="{$editlog}" size="60" maxlength="128" tabindex="2" {$summary_guide} />{$extra_check}</span> EOS; $emailform = ''; if (!empty($DBInfo->anonymous_friendly) and $options['id'] == 'Anonymous') { $useremail = isset($DBInfo->user->verified_email) ? $DBInfo->user->verified_email : ''; if ($useremail) { $email_msg = _("E-Mail"); $send_msg = sprintf(_("Send mail to %s"), "<span class='email'>" . $useremail . "</span>"); #<label for='input-email'>$email_msg</label> #<span id='edit-email'><label for='input-email'>$email_msg</label><input name="email" id='input-email' value="$useremail" size="40" maxlength="60" tabindex="3" /></span> $emailform = <<<EOS {$send_msg} <input type='checkbox' tabindex='3' checked='checked' name='cc' /> EOS; } } // show contributor license agreement form $ok_agreement = true; if (!empty($DBInfo->use_agreement)) { if ($options['id'] != 'Anonymous') { $ok_agreement = !empty($DBInfo->user->info['join_agreement']) && $DBInfo->user->info['join_agreement'] == 'agree'; if ($ok_agreement && !empty($DBInfo->agreement_version)) { $ok_agreement = $DBInfo->user->info['join_agreement_version'] == $DBInfo->agreement_version; } } else { $ok_agreement = false; } } if (!$ok_agreement) { if ($options['id'] != 'Anonymous') { if (!empty($DBInfo->contributor_license_agreement)) { $agree_msg = $DBInfo->contributor_license_agreement; } else { $agree_msg = _("Agree to the contributor license agreement on this wiki"); } } else { if (!empty($DBInfo->irrevocable_contribution_agreement)) { $agree_msg = $DBInfo->irrevocable_contribution_agreement; } else { $agree_msg = _("Agree to the contribution agreement for Anonymous doner"); } } $emailform .= <<<EOS {$agree_msg} <input type='checkbox' tabindex='3' checked='checked' name='license_agree' /> EOS; } if (isset($emailform[0])) { $emailform = '<div id="contribution_agreement">' . $emailform . '</div>'; } } $save_msg = _("Save"); if ($use_js and !empty($DBInfo->use_resizer)) { if ($DBInfo->use_resizer == 1) { $resizer = <<<EOS <script type="text/javascript" language='javascript'> /*<![CDATA[*/ function resize(obj,val) { rows= obj.savetext.rows; rows+=val; if (rows > 60) rows=16; else if (rows < 5) rows=16; obj.savetext.rows=rows; } var resizer=document.createElement('div'); resizer.setAttribute('id','wikiResize'); resizer.innerHTML="<input type='button' class='inc' value='+' onclick='resize(this.form,3)' />\\n<input type='button' class='dec' value='-' onclick='resize(this.form,-3)' />"; var toolbar=document.getElementById('toolbar'); if (toolbar) { toolbar.insertBefore(resizer, toolbar.firstChild); } else { var editor=document.getElementById('wikiEditor'); editor.insertBefore(resizer, editor.firstChild); } /*]]>*/ </script> EOS; } else { $formatter->register_javascripts('textarea.js'); } } $form .= <<<EOS <div id="editor_area"> {$formh} <div class="resizable-textarea" style='position:relative'><!-- IE hack --> <div id="save_state"></div> <textarea id="editor-textarea" wrap="virtual" name="savetext" tabindex="1" rows="{$rows}" cols="{$cols}" class="wiki resizable"{$guide}>{$raw_body}</textarea> {$captcha} </div> {$extraform} <div id="editor_info"> <ul> <li>{$summary} {$emailform}</li> <li>{$select_category} <span> <input type="hidden" name="action" value="{$saveaction}" /> <input type="hidden" name="datestamp" value="{$datestamp}" /> {$hidden} <span class="button"><input type="submit" class='save-button' tabindex="5" accesskey="x" value="{$save_msg}" /></span> <!-- <input type="reset" value="Reset" /> --> {$preview_btn}{$changes_btn}{$wysiwyg_btn}{$skip_preview} {$extra} </span> </li></ul> </div> </form> </div> EOS; if (empty($options['nohints'])) { $form .= $formatter->macro_repl('EditHints'); } if (empty($options['simple'])) { $form .= "<a id='preview'></a>"; } return $form . $resizer . $js . $tmpls; }
function do_comment($formatter, $options = array()) { global $DBInfo; if (!$DBInfo->security->writable($options)) { $formatter->preview = 1; $options['title'] = _("Page is not writable"); return do_invalid($formatter, $options); } else { if (!$DBInfo->hasPage($options['page'])) { $options['err'] = _("You are not allowed to add a comment."); $options['title'] = _("Page does not exists"); return do_invalid($formatter, $options); } } if (!empty($options['usemeta'])) { $use_meta = 1; } $cols = get_textarea_cols(); $rows = (!empty($options['rows']) and $options['rows'] > 5) ? $options['rows'] : 8; $cols = (!empty($options['cols']) and $options['cols'] > 60) ? $options['cols'] : $cols; $url = $formatter->link_url($formatter->page->urlname); $button_preview = !empty($options['button_preview']) ? $options['button_preview'] : 0; $use_any = 0; if (!empty($DBInfo->use_textbrowsers)) { if (is_string($DBInfo->use_textbrowsers)) { $use_any = preg_match('/' . $DBInfo->use_textbrowsers . '/', $_SERVER['HTTP_USER_AGENT']) ? 1 : 0; } else { $use_any = preg_match('/Lynx|w3m|links/', $_SERVER['HTTP_USER_AGENT']) ? 1 : 0; } } $ok_ticket = 0; if (empty($use_any) and !empty($DBInfo->use_ticket) and $options['id'] == 'Anonymous') { if ($options['__seed'] and $options['check']) { $mycheck = getTicket($options['__seed'], $_SERVER['REMOTE_ADDR'], 4); if ($mycheck == $options['check']) { $ok_ticket = 1; } else { $options['msg'] = _("Invalid ticket !"); $button_preview = 1; } } else { if (!$button_preview) { $options['msg'] = _("You need a ticket !"); } $button_preview = 1; } } else { $ok_ticket = 1; } if ($options['savetext']) { $savetext = _stripslashes($options['savetext']); $savetext = str_replace("\r", "", $savetext); $savetext = rtrim($savetext); #$savetext=str_replace("<","<",$savetext); } if (!empty($savetext) and empty($button_preview) and !empty($DBInfo->spam_filter)) { $text = $savetext; $fts = preg_split('/(\\||,)/', $DBInfo->spam_filter); foreach ($fts as $ft) { $text = $formatter->filter_repl($ft, $text, $options); } if ($text != $savetext) { $button_preview = 1; $options['msg'] = _("Sorry, can not save page because some messages are blocked in this wiki."); } } if (!empty($button_preview) && !empty($options['savetext'])) { if (empty($options['action_mode']) or $options['action_mode'] != 'ajax') { $formatter->send_header("", $options); $formatter->send_title(_("Preview comment"), "", $options); $formatter->send_page($savetext . "\n----"); $options['savetext'] = $savetext; print macro_Comment($formatter, '', $options); print $formatter->macro_repl('EditHints'); $formatter->send_footer("", $options); } return false; } else { if (empty($savetext)) { if (empty($options['action_mode']) or $options['action_mode'] != 'ajax') { $formatter->send_header("", $options); $formatter->send_title(_("Add comment"), "", $options); print macro_Comment($formatter, '', $options); print $formatter->macro_repl('EditHints'); $formatter->send_footer("", $options); } return false; } } $datestamp = $options['datestamp']; if ($formatter->page->mtime() > $datestamp) { $options['msg'] = ''; if (empty($options['action_mode']) or $options['action_mode'] != 'ajax') { $formatter->send_header('', $options); $formatter->send_title(_("Error: Don't make a clone!"), '', $options); $formatter->send_footer('', $options); } return false; } $body = $formatter->page->get_raw_body(); if ($options['id'] == 'Anonymous') { $id = $options['name'] ? _stripslashes($options['name']) : $_SERVER['REMOTE_ADDR']; } else { $id = $options['id']; } if (!empty($use_meta)) { $date = gmdate('Y-m-d H:i:s') . ' GMT'; $savetext = rtrim($savetext) . "\n"; $boundary = strtoupper(md5("COMMENT")); # XXX $idx = 1; if (preg_match_all('/-{4}(?:' . $boundary . ')?\\nComment-Id:\\s*(\\d+)\\n/m', $body, $m)) { $idx = $m[1][sizeof($m[1]) - 1] + 1; } if ($options['id'] != 'Anonymous') { $id = '@USERNAME@'; } $meta = <<<META Comment-Id: {$idx} From: {$id} Date: {$date} META; $savetext = "----" . $boundary . "\n{$meta}\n\n{$savetext}\n"; } else { if (!empty($options['nosig'])) { $savetext = "----\n{$savetext}\n"; } else { if ($options['id'] == 'Anonymous') { $savetext = "----\n{$savetext} -- {$id} @DATE@\n"; } else { $savetext = "----\n{$savetext} @SIG@\n"; } } } while ($options['comment_id']) { list($nth, $dum, $v) = explode(',', base64_decode($options['comment_id']), 3); if ($v) { $check = '[[' . $dum . '(' . $v . ')]]'; } else { $check = '[[' . $dum . ']]'; } if ($v) { $check2 = '<<' . $dum . '(' . $v . ')>>'; } else { $check2 = '<<' . $dum . '>>'; } if (is_numeric($nth)) { $raw = str_replace("\n", "", $body); $chunk = preg_split("/({{{.+}}})/U", $raw, -1, PREG_SPLIT_DELIM_CAPTURE); // FIXME $nc = ''; $k = 1; $i = 1; foreach ($chunk as $c) { if ($k % 2) { $nc .= $c; } else { $nc .= "" . $i . ""; $blocks[$i] = str_replace("", "\n", $c); ++$i; } $k++; } $nc = str_replace("", "\n", $nc); if (preg_match_all('/(?!\\!)(?:\\<\\<|\\[\\[)Comment(?:.*?)(?:\\]\\]|>>)/', $nc, $m)) { if (count($m[0]) == 1) { break; } } $chunk = preg_split('/((?!\\!)(?:\\<\\<|\\[\\[).+(?:\\]\\]|>>))/U', $nc, -1, PREG_SPLIT_DELIM_CAPTURE); $nnc = ''; $ii = 1; $matched = 0; for ($j = 0, $sz = sizeof($chunk); $j < $sz; ++$j) { if (($j + 1) % 2) { $nnc .= $chunk[$j]; } else { if ($nth == $ii) { $new = $savetext . $chunk[$j]; if ($check != $chunk[$j] and $check2 != $chunk[$j]) { break; } $nnc .= $new; $matched = 1; } else { $nnc .= $chunk[$j]; } ++$ii; } } if (!empty($blocks)) { $formatter->_array_callback($blocks, true); $nnc = preg_replace_callback("/(\\d+)/", array(&$formatter, '_array_callback'), $nnc); } } if (!empty($matched)) { $body = $nnc; } break; } if (empty($matched)) { if ($options['comment_id'] and preg_match("/^((?:\\[\\[|\\<\\<)Comment\\(" . $options['comment_id'] . "\\)(?:\\]\\]|>>))/m", $body, $m)) { $str = $m[1]; $body = preg_replace('/' . preg_quote($str) . '/', $savetext . $str, $body, 1); } else { if (preg_match("/\n##Comment\n/i", $body)) { $body = preg_replace("/\n##Comment\n/i", "\n##Comment\n{$savetext}", $body, 1); } else { if (preg_match("/^((\\[\\[|\\<\\<)Comment(\\([^\\)]*\\))?(\\]\\]|>>)/m", $body)) { $body = preg_replace("/^((\\[\\[|\\<\\<)Comment(\\([^\\)]*\\))?(\\]\\]|>>))/m", $savetext . "\\1", $body, 1); } else { $body .= $savetext; } } } } $formatter->page->write($body); $DBInfo->savePage($formatter->page, "Comment added", $options); if ($options['action_mode'] == 'ajax') { return true; } $options['msg'] = sprintf(_("%s is commented successfully"), $formatter->link_tag($formatter->page->urlname, "?action=show", $options['page'])); $title = _("Comment added successfully"); $myrefresh = ''; if ($DBInfo->use_save_refresh) { $sec = $DBInfo->use_save_refresh - 1; $lnk = $formatter->link_url($formatter->page->urlname, "?action=show"); $myrefresh = 'Refresh: ' . $sec . '; url=' . qualifiedURL($lnk); } $formatter->send_header($myrefresh, $options); $formatter->send_title($title, '', $options); $opt['pagelinks'] = 1; # re-generates pagelinks $formatter->send_page('', $opt); $formatter->send_footer('', $options); return; }