/** * this fucntion hast three tasks (depending on $exec): * (1) show an edit dialogue for template fields (exec = edit) * (2) set template parameters to values specified in the query (exec=set)v * (2) preview the source code including any changes of these parameters made in the edit form or with other changes (exec=preview) * (3) save the article with the changed value set or with other changes (exec=save) * "other changes" means that a regexp can be applied to the source text or arbitrary text can be * inserted before or after a pattern occuring in the text */ function updateArticleByRule($title, $text, $rulesText) { // we use ; as command delimiter; \; stands for a semicolon // \n is translated to a real linefeed $rulesText = str_replace(";", '°', $rulesText); $rulesText = str_replace('\\°', ';', $rulesText); $rulesText = str_replace("\\n", "\n", $rulesText); $rules = split('°', $rulesText); $exec = 'edit'; $replaceThis = ''; $replacement = ''; $after = ''; $insertionAfter = ''; $before = ''; $insertionBefore = ''; $template = ''; $parameter = array(); $value = array(); $afterparm = array(); $format = array(); $preview = array(); $save = array(); $tooltip = array(); $optional = array(); $lastCmd = ''; $message = ''; $summary = ''; $editForm = false; $action = ''; $hidden = array(); $legendPage = ''; $instructionPage = ''; $table = ''; $fieldFormat = ''; $nr = -1; foreach ($rules as $rule) { if (preg_match('/^\\s*#/', $rule) > 0) { continue; // # is comment symbol } $rule = preg_replace('/^[\\s]*/', '', $rule); // strip leading white space $cmd = preg_split("/ +/", $rule, 2); if (count($cmd) > 1) { $arg = $cmd[1]; } else { $arg = ''; } $cmd[0] = trim($cmd[0]); // after ... insert ... , before ... insert ... if ($cmd[0] == 'before') { $before = $arg; $lastCmd = 'B'; } if ($cmd[0] == 'after') { $after = $arg; $lastCmd = 'A'; } if ($cmd[0] == 'insert' && $lastCmd != '') { if ($lastCmd == 'A') { $insertionAfter = $arg; } if ($lastCmd == 'B') { $insertionBefore = $arg; } } if ($cmd[0] == 'template') { $template = $arg; } if ($cmd[0] == 'parameter') { $nr++; $parameter[$nr] = $arg; if ($nr > 0) { $afterparm[$nr] = array($parameter[$nr - 1]); $n = $nr - 1; while ($n > 0 && array_key_exists($n, $optional)) { $n--; $afterparm[$nr][] = $parameter[$n]; } } } if ($cmd[0] == 'value') { $value[$nr] = $arg; } if ($cmd[0] == 'format') { $format[$nr] = $arg; } if ($cmd[0] == 'tooltip') { $tooltip[$nr] = $arg; } if ($cmd[0] == 'optional') { $optional[$nr] = true; } if ($cmd[0] == 'afterparm') { $afterparm[$nr] = array($arg); } if ($cmd[0] == 'legend') { $legendPage = $arg; } if ($cmd[0] == 'instruction') { $instructionPage = $arg; } if ($cmd[0] == 'table') { $table = $arg; } if ($cmd[0] == 'field') { $fieldFormat = $arg; } if ($cmd[0] == 'replace') { $replaceThis = $arg; } if ($cmd[0] == 'by') { $replacement = $arg; } if ($cmd[0] == 'editform') { $editForm = $arg; } if ($cmd[0] == 'action') { $action = $arg; } if ($cmd[0] == 'hidden') { $hidden[] = $arg; } if ($cmd[0] == 'preview') { $preview[] = $arg; } if ($cmd[0] == 'save') { $save[] = $arg; } if ($cmd[0] == 'summary') { $summary = $arg; } if ($cmd[0] == 'exec') { $exec = $arg; // desired action (set or edit or preview) } } if ($summary == '') { $summary .= "\nbulk update:"; if ($replaceThis != '') { $summary .= "\n replace {$replaceThis}\n by {$replacement}"; } if ($before != '') { $summary .= "\n before {$before}\n insertionBefore"; } if ($after != '') { $summary .= "\n after {$after}\n insertionAfter"; } } // perform changes to the wiki source text ======================================= if ($replaceThis != '') { $text = preg_replace("{$replaceThis}", $replacement, $text); } if ($insertionBefore != '' && $before != '') { $text = preg_replace("/({$before})/", $insertionBefore . '\\1', $text); } if ($insertionAfter != '' && $after != '') { $text = preg_replace("/({$after})/", '\\1' . $insertionAfter, $text); } // deal with template parameters ================================================= global $wgRequest, $wgUser; if ($template != '') { if ($exec == 'edit') { $tpv = $this->getTemplateParmValues($text, $template); $legendText = ''; if ($legendPage != '') { $legendTitle = ''; global $wgParser, $wgUser; $parser = clone $wgParser; DPLInclude::text($parser, $legendPage, $legendTitle, $legendText); $legendText = preg_replace('/^.*?\\<section\\s+begin\\s*=\\s*legend\\s*\\/\\>/s', '', $legendText); $legendText = preg_replace('/\\<section\\s+end\\s*=\\s*legend\\s*\\/\\>.*/s', '', $legendText); } $instructionText = ''; $instructions = array(); if ($instructionPage != '') { $instructionTitle = ''; global $wgParser, $wgUser; $parser = clone $wgParser; DPLInclude::text($parser, $instructionPage, $instructionTitle, $instructionText); $instructions = $this->getTemplateParmValues($instructionText, 'Template field'); } // construct an edit form containing all template invocations $form = "<html><form method=post action=\"{$action}\" {$editForm}>\n"; foreach ($tpv as $call => $tplValues) { $form .= "<table {$table}>\n"; foreach ($parameter as $nr => $parm) { // try to extract legend from the docs of the template $myToolTip = ''; if (array_key_exists($nr, $tooltip)) { $myToolTip = $tooltip[$nr]; } $myInstruction = ''; $myType = ''; foreach ($instructions as $instruct) { if (array_key_exists('field', $instruct) && $instruct['field'] == $parm) { if (array_key_exists('doc', $instruct)) { $myInstruction = $instruct['doc']; } if (array_key_exists('type', $instruct)) { $myType = $instruct['type']; } break; } } $myFormat = ''; if (array_key_exists($nr, $format)) { $myFormat = $format[$nr]; } $myOptional = array_key_exists($nr, $optional); if ($legendText != '' && $myToolTip == '') { $myToolTip = preg_replace('/^.*\\<section\\s+begin\\s*=\\s*' . preg_quote($parm, '/') . '\\s*\\/\\>/s', '', $legendText); if (strlen($myToolTip) == strlen($legendText)) { $myToolTip = ''; } else { $myToolTip = preg_replace('/\\<section\\s+end\\s*=\\s*' . preg_quote($parm, '/') . '\\s*\\/\\>.*/s', '', $myToolTip); } } $myValue = ''; if (array_key_exists($parm, $tpv[$call])) { $myValue = $tpv[$call][$parm]; } $form .= $this->editTemplateCall($text, $template, $call, $parm, $myType, $myValue, $myFormat, $myToolTip, $myInstruction, $myOptional, $fieldFormat); } $form .= "</table>\n<br /><br />"; } foreach ($hidden as $hide) { $form .= "<input type=hidden " . $hide . " />"; } $form .= "<input type=hidden name=\"token\" value=\"" . $wgUser->editToken() . "\" />"; foreach ($preview as $prev) { $form .= "<input type=submit " . $prev . " /> "; } $form .= "</form></html>\n"; return $form; } elseif ($exec == 'set' || $exec == 'preview') { // loop over all invocations and parameters, this could be improved to enhance performance $matchCount = 10; for ($call = 0; $call < 10; $call++) { foreach ($parameter as $nr => $parm) { // set parameters to values specified in the dpl source or get them from the http request if ($exec == 'set') { $myvalue = $value[$nr]; } else { if ($call >= $matchCount) { break; } $myValue = $wgRequest->getVal(urlencode($call . '_' . $parm), ''); } $myOptional = array_key_exists($nr, $optional); $myAfterParm = array(); if (array_key_exists($nr, $afterparm)) { $myAfterParm = $afterparm[$nr]; } $text = $this->updateTemplateCall($matchCount, $text, $template, $call, $parm, $myValue, $myAfterParm, $myOptional); } if ($exec == 'set') { break; // values taken from dpl text only populate the first invocation } } } } if ($exec == 'set') { return $this->updateArticle($title, $text, $summary); } elseif ($exec == 'preview') { global $wgScriptPath, $wgRequest; $titleX = Title::newFromText($title); $articleX = new Article($titleX); $form = '<html><form id="editform" name="editform" method="post" action="' . $wgScriptPath . '/index.php?title=' . urlencode($title) . '&action=submit" ' . 'enctype="multipart/form-data">' . "\n" . '<input type="hidden" value="" name="wpSection" />' . "\n" . '<input type="hidden" value="' . wfTimestampNow() . '" name="wpStarttime" />' . "\n" . '<input type="hidden" value="' . $articleX->getTimestamp() . '" name="wpEdittime" />' . "\n" . '<input type="hidden" value="" name="wpScrolltop" id="wpScrolltop" />' . "\n" . '<textarea tabindex="1" accesskey="," name="wpTextbox1" id="wpTextbox1" rows="' . $wgUser->getIntOption('rows') . '" cols="' . $wgUser->getIntOption('cols') . '" >' . htmlspecialchars($text) . '</textarea>' . "\n" . '<input type="hidden" name="wpSummary value="' . $summary . '" id="wpSummary" />' . '<input name="wpAutoSummary" type="hidden" value="" />' . '<input id="wpSave" name="wpSave" type="submit" value="Save page" accesskey="s" title="Save your changes [s]" />' . '<input type="hidden" value="' . $wgRequest->getVal('token') . '" name="wpEditToken" />' . "\n" . '</form></html>' . "\n"; return $form; } return 'exec must be one of the following: edit, preview, set'; }