Revision as of 23:12, 10 April 2020 editWbm1058 (talk | contribs)Autopatrolled, Administrators264,845 editsm v 1.91 – fix indents← Previous edit | Latest revision as of 14:02, 29 November 2024 edit undoJLaTondre (talk | contribs)Administrators45,016 edits rv by restoring prior versionTag: Manual revert | ||
(21 intermediate revisions by 3 users not shown) | |||
Line 1: | Line 1: | ||
< |
<syntaxhighlight lang=php> | ||
<?php | <?php | ||
/** proposedmergers.php - To generate lists of proposed page mergers on Misplaced Pages | /** proposedmergers.php - To generate lists of proposed page mergers on Misplaced Pages | ||
* | * | ||
* (c) 2009 James Hare - http://en.wikipedia.org/User:Harej | * (c) 2009 James Hare - http://en.wikipedia.org/User:Harej | ||
* (c) 2013-2022 Bill - http://en.wikipedia.org/User:wbm1058 | |||
* | * | ||
* This program is free software; you can redistribute it and/or modify | * This program is free software; you can redistribute it and/or modify | ||
Line 28: | Line 29: | ||
include("logininfo.php"); | include("logininfo.php"); | ||
const bot_version = "1. |
const bot_version = "1.110"; | ||
const botuser = "Merge bot"; | const botuser = "Merge bot"; | ||
Line 45: | Line 46: | ||
# {{Merging}} | # {{Merging}} | ||
$processed = preg_replace("/^(Mergingsectionto|Merging|Merging to|Merging_to)(.*)\|\s*dir\s*\=\s*from/i", "mergefrom$2", $processed); | |||
$processed = preg_replace("/^(Mergingsectionto|Merging|Merging to|Merging_to)/i", "merge", $processed); | $processed = preg_replace("/^(Mergingsectionto|Merging|Merging to|Merging_to)/i", "merge", $processed); | ||
Line 73: | Line 75: | ||
echo "Bot version: " . bot_version . "\n"; | echo "Bot version: " . bot_version . "\n"; | ||
$j = 0; | |||
$takeofflater = 0; | |||
$maxi = 0; | |||
$cachepage = ""; | |||
$discuss = array(); | |||
$target = array(); | |||
$section = array(); | |||
$multiplesections = array(); | |||
$reason = array(); | |||
$othernamespace = 0; | $othernamespace = 0; | ||
$matchfailed = 0; | $matchfailed = 0; | ||
$templatesplitfailed = 0; | $templatesplitfailed = 0; | ||
$nopartner = 0; | $nopartner = 0; | ||
$nopartners = array(); | |||
$no_direction = 0; | |||
$no_directions = array(); | |||
$conflict = 0; | |||
$conflicts = array(); | |||
$mismatched_date = 0; | $mismatched_date = 0; | ||
$mismatched_dates = array(); | $mismatched_dates = array(); | ||
Line 89: | Line 105: | ||
$diffcase = 0; | $diffcase = 0; | ||
$diffcases = array(); | $diffcases = array(); | ||
$redir_no_reciprocal = 0; | |||
$redir_no_reciprocals = array(); | |||
$page_moved = 0; | |||
$pages_moved = array(); | |||
$other_redirect = 0; | |||
$other_redirects = array(); | |||
$selfmerge = 0; | $selfmerge = 0; | ||
$targetself = 0; | |||
$noname = 0; | $noname = 0; | ||
$wikt = 0; | $wikt = 0; | ||
$mainsubmission = ""; | $mainsubmission = ""; | ||
$skipped = 0; | |||
$counter = array(); | |||
$maxcounter = 0; | |||
$submission = array(); | |||
$nomatches = array(); | |||
$nosplits = array(); | |||
echo "Logging in...\n"; | echo "Logging in...\n"; | ||
Line 121: | Line 150: | ||
} | } | ||
if (preg_match("/^((User|Misplaced Pages|File|MediaWiki|Template|Help|Category|Portal)(( |_)talk)?|Talk):/", $transcludes)) { | if (preg_match("/^((User|Misplaced Pages|File|MediaWiki|Template|Help|Category|Portal|Draft)(( |_)talk)?|Talk):/", $transcludes)) { | ||
echo "\n\n?? Other namespace: " . $transcludes . "\n\n"; | echo "\n\n?? Other namespace: " . $transcludes . "\n\n"; | ||
$others = $transcludes; | $others = $transcludes; | ||
Line 149: | Line 178: | ||
} while ($contents == FALSE); | } while ($contents == FALSE); | ||
if (preg_match_all("/\{{2}\s?(merge|afd-merge|merging|move section)*\}{2}/i", $contents, $raw1) == 0) { | if (preg_match_all("/\{{2}\s?(merge|proposed merge|afd-merge|merging|move section)*\}{2}/i", $contents, $raw1) == 0) { | ||
#echo "contents:\n"; | #echo "contents:\n"; | ||
#echo "$contents"; | #echo "$contents"; | ||
Line 173: | Line 202: | ||
echo $key . ">> " . $pagename; | echo $key . ">> " . $pagename; | ||
$template = templateprocess($raw1); | $template = templateprocess($raw1); | ||
#echo " § " . $template . " §"; | |||
$ptemplate = $raw1; | $ptemplate = $raw1; | ||
$pcontents = $contents; | if (isset($contents)) $pcontents = $contents; | ||
else $pcontents = ""; | |||
unset($contents); | unset($contents); | ||
Line 214: | Line 245: | ||
for ($para = 1; $para < count($templatesplit); $para++) { | for ($para = 1; $para < count($templatesplit); $para++) { | ||
|
#echo "\n" . $para . ") " . $templatesplit . "\n"; | ||
if (preg_match("/^date\s*=/i", $templatesplit)) { | |||
$date = str_replace("date=", "", $templatesplit); | $date = str_replace("date=", "", $templatesplit); | ||
$date = str_replace("_", " ", $date); | $date = str_replace("_", " ", $date); | ||
Line 237: | Line 269: | ||
} | } | ||
} | } | ||
elseif (preg_match("/^(discuss|discussion)=/i", $templatesplit)) { | elseif (preg_match("/^(discuss|discussion|talk)\s*=/i", $templatesplit)) { | ||
$discuss = str_replace("discuss=", "", $templatesplit); | $discuss = str_replace("discuss=", "", $templatesplit); | ||
$discuss = str_replace("discussion=", "", $discuss); | $discuss = str_replace("discussion=", "", $discuss); | ||
$discuss = str_replace("talk=", "", $discuss); | |||
} | } | ||
elseif (preg_match("/^target=/i", $templatesplit)) { | elseif (preg_match("/^target\s*=/i", $templatesplit)) { | ||
$target = str_replace("target=", "", $templatesplit); | $target = str_replace("target=", "", $templatesplit); | ||
if ($target == $transcludes) { | |||
echo "\n** error ** Page " . $transcludes . " proposed merge target is itself\n"; | |||
$targetself += 1; | |||
} | |||
if (in_array($target, $pagename)) { | if (in_array($target, $pagename)) { | ||
Line 258: | Line 296: | ||
} | } | ||
} | } | ||
elseif (preg_match("/^section=/i", $templatesplit)) { | elseif (preg_match("/^section\s*=/i", $templatesplit)) { | ||
$section = str_replace("section=", "", $templatesplit); | $section = str_replace("section=", "", $templatesplit); | ||
} | } | ||
elseif (preg_match("/^multiplesections=/i", $templatesplit)) { |
elseif (preg_match("/^multiplesections\s*=/i", $templatesplit)) { | ||
// Template:Mergefrom uses parameter multiplesections; Merge and Mergeto do not | |||
$multiplesections = str_replace("multiplesections=", "", $templatesplit); | $multiplesections = str_replace("multiplesections=", "", $templatesplit); | ||
} | } | ||
elseif (preg_match("/^ |
elseif (preg_match("/^dir\s*=/i", $templatesplit)) { // Template:Merging | ||
} | |||
elseif (preg_match("/^(reason|comment)\s*=/i", $templatesplit)) { | |||
$reason = str_replace("reason=", "", $templatesplit); | $reason = str_replace("reason=", "", $templatesplit); | ||
$reasons = $pagename . " …… " . $reason; | $reasons = $pagename . " …… " . $reason; | ||
Line 286: | Line 327: | ||
if (preg_match("/^(1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20)=/i", $templatesplit)) { | if (preg_match("/^(1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20)=/i", $templatesplit)) { | ||
echo "\nNumbered parameter(s):" . $templatesplit; | echo "\nNumbered parameter(s):" . $templatesplit; | ||
$templatesplit = |
$templatesplit = preg_replace("/(1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20)=/", "", $templatesplit); | ||
} | } | ||
$otherpage .= $templatesplit . "|"; | $otherpage .= $templatesplit . "|"; | ||
Line 310: | Line 351: | ||
$new_template = substr_replace($ptemplate, $otherpages, $pos, strlen($otherpages)); | $new_template = substr_replace($ptemplate, $otherpages, $pos, strlen($otherpages)); | ||
$pcontents = str_replace($ptemplate,$new_template,$pcontents); | $pcontents = str_replace($ptemplate,$new_template,$pcontents); | ||
if ( |
if ($pcontents == "") { | ||
echo "\n??Problem replacing underscores with spaces in merge template\n"; | |||
} | |||
else if ($objwiki->nobots($transcludes,botuser,$pcontents) == true) { | |||
echo "\nReplacing underscores with spaces in merge template\n"; | |||
$objwiki->edit($transcludes,$pcontents,"Replace underscores with spaces in merge template",true,true); | $objwiki->edit($transcludes,$pcontents,"Replace underscores with spaces in merge template",true,true); | ||
} | |||
} | } | ||
Line 333: | Line 379: | ||
if ($new_template !== $ptemplate) { | if ($new_template !== $ptemplate) { | ||
$pcontents = str_replace($ptemplate,$new_template,$pcontents); | $pcontents = str_replace($ptemplate,$new_template,$pcontents); | ||
if ( |
if ($pcontents == "") { | ||
echo "\n??Problem removing redundant pipe in merge template\n"; | |||
} | |||
else if ($objwiki->nobots($transcludes,botuser,$pcontents) == true) { | |||
echo "\nRemoving redundant pipe in merge template\n"; | |||
$objwiki->edit($transcludes,$pcontents,"Remove redundant pipe in merge template",true,true); | $objwiki->edit($transcludes,$pcontents,"Remove redundant pipe in merge template",true,true); | ||
} | |||
} | } | ||
} | } | ||
Line 352: | Line 403: | ||
} | } | ||
else { | else { | ||
if (preg_match("/^((User|Misplaced Pages|File|MediaWiki|Template|Help|Category|Portal|Draft)(( |_)talk)?|Talk):/", $otherpages) | |||
and $break == 0) { | |||
echo "\n\n? Other namespace: " . $otherpages . "\n\n"; | |||
$others = $otherpages; | |||
$othernamespace += 1; | |||
} | |||
echo "getpage 2: $otherpages|"; | echo "getpage 2: $otherpages|"; | ||
$pagecontents = $objwiki->getpage($otherpages); | $pagecontents = $objwiki->getpage($otherpages); | ||
if (preg_match_all("/\{{2}\s?(merge|afd-merge|merging|move section)*\}{2}/i", $pagecontents, $raw2) == 0) { | if (preg_match_all("/\{{2}\s?(merge|afd-merge|merging|move section)*\}{2}/i", $pagecontents, $raw2) == 0 and $break == 0) { | ||
echo "*** Merge tag not found on " . $otherpages. " *2*\n"; | echo "*** Merge tag not found on " . $otherpages . " *2*\n"; | ||
$no_reciprocal += 1; | $no_reciprocal += 1; | ||
} | } | ||
$cachepage = $otherpages; | $cachepage = $otherpages; | ||
$cachecontents = $pagecontents; | if (isset($pagecontents)) $cachecontents = $pagecontents; | ||
else $cachecontents = ""; | |||
$break += 1; | $break += 1; | ||
} | } | ||
} | } | ||
if (preg_match("/^\#REDIRECT(\s*|:)\{2}/i", $pagecontents, $redirect)) { | if (isset($pagecontents) and preg_match("/^\#REDIRECT(\s*|:)\{2}/i", $pagecontents, $redirect)) { | ||
echo "\n*** " . $pagename. ": PAGE " . $otherpages . " IS A REDIRECT!! ***\n"; | echo "\n*** " . $pagename. ": PAGE " . $otherpages . " IS A REDIRECT!! ***\n"; | ||
echo $pagecontents . "\n\n"; | echo $pagecontents . "\n\n"; | ||
Line 374: | Line 432: | ||
$target = trim($target); | $target = trim($target); | ||
if ($target == |
if (strpos($target,"#") !== false) { | ||
|
$len = strpos($target,"#"); | ||
if ($len == 0) $targetpage = $target; | |||
else $targetpage = substr($target,0,$len); // strip section links | |||
} | |||
else $targetpage = $target; | |||
if ($targetpage == $pagename) { | |||
echo $otherpages . " redirects to " . $target . " -- may have been merged\n\n"; | |||
$maybes = $pagename . ":: " . $otherpages; | $maybes = $pagename . ":: " . $otherpages; | ||
$maybe +=1; | $maybe +=1; | ||
Line 387: | Line 452: | ||
$new_template = substr_replace($ptemplate, $target, $pos, strlen($otherpages)); | $new_template = substr_replace($ptemplate, $target, $pos, strlen($otherpages)); | ||
$pcontents = str_replace($ptemplate,$new_template,$pcontents); | $pcontents = str_replace($ptemplate,$new_template,$pcontents); | ||
if ( |
if ($pcontents == "") { | ||
echo "\n??Problem bypassing redirect in merge template – DIFFCAPS\n"; | |||
} | |||
else if ($objwiki->nobots($transcludes,botuser,$pcontents) == true) { | |||
echo "\nBypassing redirect in merge template – DIFFCAPS\n"; | |||
$objwiki->edit($transcludes,$pcontents,"Bypass redirect in merge template – DIFFCAPS",true,true); | $objwiki->edit($transcludes,$pcontents,"Bypass redirect in merge template – DIFFCAPS",true,true); | ||
} | |||
} | |||
} | |||
else { | |||
echo "getpage 4: $targetpage|"; | |||
$pagecontents = $objwiki->getpage($targetpage); | |||
if (preg_match_all("/\{{2}\s?(merge|afd-merge|merging|move section)*\}{2}/i", $pagecontents, $raw4) == 0) { | |||
echo "*** Merge tag not found on target page " . $targetpage. " *4*\n"; | |||
$redir_no_reciprocals = $pagename . ":: " . $otherpages; | |||
$redir_no_reciprocal += 1; | |||
} | |||
else { | |||
echo "*** Merge tag found on target page " . $targetpage. " *4* " . $raw4 . "\n"; | |||
$pos = stripos($raw4,$pagename); | |||
if ($pos === false) { | |||
echo " ** " . $pagename . " not found!\n"; | |||
$other_redirects = $pagename . ":: " . $otherpages; | |||
$other_redirect += 1; | |||
} | |||
else { | |||
echo " ** found " . $pagename . "\n"; | |||
$pages_moved = $pagename . ":: " . $otherpages; | |||
$page_moved += 1; | |||
$pos = strpos($ptemplate, $otherpages); | |||
if ($pos !== false) { | |||
$new_template = substr_replace($ptemplate, $target, $pos, strlen($otherpages)); | |||
$pcontents = str_replace($ptemplate,$new_template,$pcontents); | |||
echo "\n$pcontents\n"; | |||
if ($pcontents == "") { | |||
echo "\n??Problem bypassing redirect in merge template – apparently " . $otherpages . | |||
" moved to " . $target . "\n"; | |||
} | |||
else if ($objwiki->nobots($transcludes,botuser,$pcontents) == true) { | |||
echo "\nBypassing redirect in merge template – apparently " . $otherpages . " moved to " . $target . "\n"; | |||
$objwiki->edit($transcludes,$pcontents,"Bypass redirect in merge template – apparently " . | |||
$otherpages . " moved to " . $target,true,true); | |||
} | |||
} | |||
} | |||
} | } | ||
} | } | ||
} | } | ||
Line 431: | Line 538: | ||
} | } | ||
if (preg_match_all("/\{{2}\s?(merge|afd-merge|merging|move section)*\}{2}/i", $pagecontents, $raw) !== 0) { | if (isset($pagecontents) and preg_match_all("/\{{2}\s?(merge|afd-merge|merging|move section)*\}{2}/i", $pagecontents, $raw) !== 0) { | ||
$reciprocal = FALSE; | $reciprocal = FALSE; | ||
for ($jraw = 0; $jraw < count($raw); $jraw++) { | for ($jraw = 0; $jraw < count($raw); $jraw++) { | ||
Line 441: | Line 548: | ||
else { | else { | ||
echo " ** found " . $pagename; | echo " ** found " . $pagename; | ||
$ |
$reciprocal_template = templateprocess($raw); | ||
echo "\n§ " . $reciprocal_template . " § "; | |||
$reciprocal_templatesplit = array_map('trim',explode("|", $reciprocal_template)); | |||
echo $reciprocal_templatesplit; | |||
switch ($reciprocal_templatesplit) { | |||
case "merge": | |||
echo "\n% Reciprocal direction not specified\n"; | |||
$no_directions = $pagename . " ==> " . $otherpages; | |||
$no_direction += 1; | |||
case "mergefrom": | |||
case "false-positive": | |||
$reciprocal = TRUE; | |||
break; | |||
case "mergeto": | |||
echo "\n!! Conflicting tags !!\n"; | |||
$conflicts = $pagename . " <===> " . $otherpages; | |||
$conflict += 1; | |||
break; | |||
default: | |||
echo "\n!! Unexpected: " . $templatesplit; | |||
} | |||
} | } | ||
} | } | ||
Line 460: | Line 587: | ||
} | } | ||
if ($discuss == "") |
if (!array_key_exists($key, $discuss)) { // ($discuss == "") | ||
if (preg_match("/^(User|Misplaced Pages|Image|File|MediaWiki|Template|Help|Category|Portal):/i",$transcludes,$m)) { | if (preg_match("/^(User|Misplaced Pages|Image|File|MediaWiki|Template|Help|Category|Portal):/i",$transcludes,$m)) { | ||
$discuss = str_replace($m,$m.' talk',$transcludes); | $discuss = str_replace($m,$m.' talk',$transcludes); | ||
Line 495: | Line 622: | ||
foreach ($pagename as $key => $title) { | foreach ($pagename as $key => $title) { | ||
if ($counter] > $maxcounter) { | if (array_key_exists($date, $counter) and $counter] > $maxcounter) { | ||
$maxcounter = $counter]; | $maxcounter = $counter]; | ||
} | } | ||
if (!array_key_exists($date, $submission)) $submission] = ""; | |||
if (!array_key_exists($key, $reason)) $reason = ""; | |||
switch ($type) { | switch ($type) { | ||
case "with": // regular merge | case "with": // regular merge | ||
if ($target != "") |
if (array_key_exists($key, $target)) { // ($target != "") | ||
$submission] .= |
$submission] .= | ||
"{{merge log entry|1=]|2=$otherpage|3=]]|talk=$discuss|type=with|reason=$reason}}\n"; | |||
} | } | ||
else { | else { | ||
$submission] .= "{{merge log entry|1=]|2=$otherpage|talk=$discuss|type=with}}\n"; | $submission] .= "{{merge log entry|1=]|2=$otherpage|talk=$discuss|type=with|reason=$reason}}\n"; | ||
} | } | ||
break; | break; | ||
case "into": // merge-from | case "into": // merge-from | ||
$submission] .= "{{merge log entry|1=$otherpage|2=]|talk=$discuss|type=into}}\n"; | $submission] .= "{{merge log entry|1=$otherpage|2=]|talk=$discuss|type=into|reason=$reason}}\n"; | ||
break; | break; | ||
case "to": // merge-to | case "to": // merge-to | ||
$submission] .= "{{merge log entry|1=]|2=$otherpage|talk=$discuss|type=into}}\n"; | $submission] .= "{{merge log entry|1=]|2=$otherpage|talk=$discuss|type=into|reason=$reason}}\n"; | ||
break; | break; | ||
case "to ?": // no partner | case "to ?": // no partner | ||
$submission] .= "{{merge log entry|1=]|2=?|talk=$discuss|type=into}}\n"; | $submission] .= "{{merge log entry|1=]|2=?|talk=$discuss|type=into|reason=$reason}}\n"; | ||
break; | break; | ||
default: | default: | ||
Line 521: | Line 651: | ||
break; // use "continue 2"? | break; // use "continue 2"? | ||
} | } | ||
$counter] += 1; | if (array_key_exists($date, $counter)) $counter] += 1; | ||
else $counter] = 1; | |||
echo $date . " | " . $counter] . ") " . $key . " ++ " . $title. "\n"; | echo $date . " | " . $counter] . ") " . $key . " ++ " . $title. "\n"; | ||
} | } | ||
Line 529: | Line 660: | ||
foreach ($submission as $log => $content) { | foreach ($submission as $log => $content) { | ||
echo "Updating> " . $log. "\n"; | if ($log != "") { | ||
echo "Updating> " . $log. "\n"; | |||
#echo $content . "\n"; | |||
$objwiki->edit("Misplaced Pages:Proposed mergers/Log/" . $log,$content,"Updating list of proposed mergers",false,true); | |||
} | |||
else echo "\n? Error, null log specification: " . $content . "\n\n"; | |||
} | } | ||
Line 548: | Line 682: | ||
print_r($nosplits); | print_r($nosplits); | ||
echo "\nNo partner: " . $nopartner . "\n"; | echo "\nNo partner: " . $nopartner . "\n"; | ||
print_r($nopartners); | if ($nopartner > 0) print_r($nopartners); | ||
echo "\nReciprocal direction not specified: " . $no_direction . "\n"; | |||
if ($no_direction > 0) print_r($no_directions); | |||
echo "\nConflicting tags: " . $conflict . "\n"; | |||
if ($conflict > 0) print_r($conflicts); | |||
echo "\nPages with multiple proposal dates: " . $mismatched_date . "\n"; | echo "\nPages with multiple proposal dates: " . $mismatched_date . "\n"; | ||
print_r($mismatched_dates); | if ($mismatched_date > 0) print_r($mismatched_dates); | ||
echo "\nPages where reasons are given in the template: " . $reason_count . "\n"; | echo "\nPages where reasons are given in the template: " . $reason_count . "\n"; | ||
print_r($reasons); | if ($reason_count > 0) print_r($reasons); | ||
echo "\nOther pages which are blank or don't exist: " . $blank . "\n"; | echo "\nOther pages which are blank or don't exist: " . $blank . "\n"; | ||
print_r($blanks); | if ($blank > 0) print_r($blanks); | ||
echo "\nOther pages which are redirects: " . $redirects; | echo "\nOther pages which are redirects: " . $redirects; | ||
echo "\n Maybe merged: " . $maybe . "\n"; | echo "\n Maybe merged: " . $maybe . "\n"; | ||
print_r($maybes); | if ($maybe > 0) print_r($maybes); | ||
echo "\n Cases differ: " . $diffcase . "\n"; | echo "\n Cases differ: " . $diffcase . "\n"; | ||
print_r($diffcases); | if ($diffcase > 0) print_r($diffcases); | ||
echo "\n Pages moved: " . $page_moved . "\n"; | |||
if ($page_moved > 0) print_r($pages_moved); | |||
echo "\n Other redirects: " . $other_redirect . "\n"; | |||
if ($other_redirect > 0) print_r($other_redirects); | |||
echo "\n Redirect with no reciprocal tags: " . $redir_no_reciprocal . "\n"; | |||
print_r($redir_no_reciprocals); | |||
echo "\nMerge-to targets without reciprocal merge tags: " . $no_reciprocal . "\n"; | echo "\nMerge-to targets without reciprocal merge tags: " . $no_reciprocal . "\n"; | ||
echo "\nSelf-merges: " . $selfmerge . "\n"; | echo "\nSelf-merges: " . $selfmerge . "\n"; | ||
echo "\nSpecified |target is the page itself: " . $targetself . "\n"; | |||
echo "\nNo name specified: " . $noname . "\n"; | echo "\nNo name specified: " . $noname . "\n"; | ||
echo "\nWiktionary merges: " . $wikt . "\n"; | echo "\nWiktionary merges: " . $wikt . "\n"; | ||
Line 567: | Line 712: | ||
?> | ?> | ||
</syntaxhighlight> | |||
</source> |
Latest revision as of 14:02, 29 November 2024
<?php /** proposedmergers.php - To generate lists of proposed page mergers on Misplaced Pages * * (c) 2009 James Hare - http://en.wikipedia.org/User:Harej * (c) 2013-2022 Bill - http://en.wikipedia.org/User:wbm1058 * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * * Developers (add your self here if you worked on the code): * James Hare - ] - Wrote everything * WBM - ] - March/April 2013 updates **/ ini_set("display_errors", 1); error_reporting(E_ALL ^ E_NOTICE); require_once 'botclasses.php'; // Botclasses.php was written by User:Chris_G and is available under the GNU General Public License include("logininfo.php"); const bot_version = "1.110"; const botuser = "Merge bot"; function templateprocess($processed) { echo " :: " . $processed; $processed = preg_replace("/\s?\|\s?/", "|", $processed); $processed = preg_replace("/\{{2}\s?/", "", $processed); $processed = preg_replace("/\s?\}{2}/", "", $processed); $processed = preg_replace("/\s?=\s?/", "=", $processed); # Redirects to {{Merge}} (14 aliases) $processed = preg_replace("/^(Mergewith|Merge with|Merge_with|MergeVfD|Mergesplit|MergeSplit|Merge)/i", "merge", $processed); $processed = preg_replace("/^(Mergedisputed|MergeDisputed|Merge-disputed|Merge disputed|Merge_disputed)/i", "merge", $processed); $processed = preg_replace("/^(Merge-multiple|Mergemulti|Mergetomultiple-with|Multimerge)/i", "merge", $processed); $processed = preg_replace("/^(Proposed merge|Proposed_merge)/i", "merge", $processed); # {{Merging}} $processed = preg_replace("/^(Mergingsectionto|Merging|Merging to|Merging_to)(.*)\|\s*dir\s*\=\s*from/i", "mergefrom$2", $processed); $processed = preg_replace("/^(Mergingsectionto|Merging|Merging to|Merging_to)/i", "merge", $processed); # Redirects to {{Merge from}} (11 aliases) $processed = preg_replace("/^(Merge from|Merge_from|Merge-from|Include|Mergrefrom|Mergefrom-category|MergeFrom|Mergefrom)/i", "mergefrom", $processed); $processed = preg_replace("/^(Mergefrom-multiple|Multiplemergefrom|Mergefrommultiple|Mergefrommulti|Multimergefrom)/i", "mergefrom", $processed); # {{Afd-merge from}}, {{Merging from}} $processed = preg_replace("/^(Afd-merge from|Afd-merge_from|Afd-mergefrom|Afdmergefrom|Merging from|Merging_from|Mergingfrom)/i", "mergefrom", $processed); # Redirects to {{Merge to}} (15 aliases) and {{Merge school}} (1 alias) $processed = preg_replace("/^(Merge to|Merge_to|Merge-to|Mergeinto|MergetoCat|Mergelist|Mergeto-disputed)/i", "mergeto", $processed); $processed = preg_replace("/^(MergePartial|Merge-multiple-to|Merge to article|Merge_to_article)/i", "mergeto", $processed); $processed = preg_replace("/^(Mergeto-multiple|Multiplemergeto|Multiplemergeinto|Merge into|Merge_into|Merge-into|MergeTo|Mergeto|Merge2)/i", "mergeto", $processed); $processed = preg_replace("/^(Merge school|Merge_school|Merge-school)/i", "mergeto", $processed); # {{Afd-merge to}} $processed = preg_replace("/^(Afd-merge to|Afd-merge_to|Afd-mergeto|Afdmergeto|AfD-merge to|AfD-merge_to)/i", "afd-mergeto", $processed); # {{Merge portions from}} // This is really a splitting template, not a merging template $processed = preg_replace("/^(Merge portions from|Merge_portions_from|Move portions from|Move_portions_from)/i", "false-positive", $processed); return $processed; } echo "PHP version: " . PHP_VERSION . "\n"; #phpinfo(); echo "Bot version: " . bot_version . "\n"; $j = 0; $takeofflater = 0; $maxi = 0; $cachepage = ""; $discuss = array(); $target = array(); $section = array(); $multiplesections = array(); $reason = array(); $othernamespace = 0; $matchfailed = 0; $templatesplitfailed = 0; $nopartner = 0; $nopartners = array(); $no_direction = 0; $no_directions = array(); $conflict = 0; $conflicts = array(); $mismatched_date = 0; $mismatched_dates = array(); $reason_count = 0; $reasons = array(); $blank = 0; $blanks = array(); $no_reciprocal = 0; $redirects = 0; $maybe = 0; $maybes = array(); $diffcase = 0; $diffcases = array(); $redir_no_reciprocal = 0; $redir_no_reciprocals = array(); $page_moved = 0; $pages_moved = array(); $other_redirect = 0; $other_redirects = array(); $selfmerge = 0; $targetself = 0; $noname = 0; $wikt = 0; $mainsubmission = ""; $skipped = 0; $counter = array(); $maxcounter = 0; $submission = array(); $nomatches = array(); $nosplits = array(); echo "Logging in...\n"; $objwiki = new wikipedia(); $objwiki->http->useragent = '] php wikibot classes'; $objwiki->login($mbuser, $mbpass); echo "...done.\n"; $mergemonths = $objwiki->categorymembers("Category:Articles to be merged"); print_r($mergemonths); for ($a = 0; $a < count($mergemonths); $a++) { // for each month #if (preg_match("/Category:Articles to be merged/", $mergemonths)) { if (preg_match("/Category:Articles to be merged from/", $mergemonths)) { echo "\n__________\n" . $a . ": " . $mergemonths . "\n"; $transcludes = $objwiki->categorymembers($mergemonths); #print_r($transcludes); $monthyear = str_replace("Category:Articles to be merged from ", "", $mergemonths, $repcount); if ($repcount == 0) { $monthyear = str_replace("Category:", "", $mergemonths); } for ($i = 0; $i < count($transcludes); $i++) { // for each page in the category if ($i > $maxi) { $maxi = $i; } if (preg_match("/^((User|Misplaced Pages|File|MediaWiki|Template|Help|Category|Portal|Draft)(( |_)talk)?|Talk):/", $transcludes)) { echo "\n\n?? Other namespace: " . $transcludes . "\n\n"; $others = $transcludes; $othernamespace += 1; continue; } $getpagefailed = 0; do { if ($transcludes == $cachepage) { echo "getpage 1: $transcludes|from cache\n"; $contents = $cachecontents; } else { echo "getpage 1: $transcludes|"; $contents = $objwiki->getpage($transcludes); } if ($contents == FALSE) { echo "\n\n?? getpage failed: " . $transcludes . "\n\n"; $getpagefailed += 1; if ($getpagefailed == 5) { die("getpage Error"); } sleep(10); continue; } } while ($contents == FALSE); if (preg_match_all("/\{{2}\s?(merge|proposed merge|afd-merge|merging|move section)*\}{2}/i", $contents, $raw1) == 0) { #echo "contents:\n"; #echo "$contents"; #echo "\n"; unset($contents); echo "\n\n?? Match failed: " . $transcludes . "\n\n"; $nomatches = $transcludes; $matchfailed += 1; continue; } $mergetemplates = count($raw1); if ($mergetemplates > 1) { echo "$mergetemplates merge templates on $transcludes\n"; print_r($raw1); } $takeofflater = 0; for ($j = 0; $j < $mergetemplates; $j++) { // for each merge template on the page $key = $a . "-" . $i . "-" . $j; $pagename = $transcludes; echo $key . ">> " . $pagename; $template = templateprocess($raw1); #echo " § " . $template . " §"; $ptemplate = $raw1; if (isset($contents)) $pcontents = $contents; else $pcontents = ""; unset($contents); $templatesplit = array_map('trim',explode("|", $template)); echo " " . $templatesplit; switch ($templatesplit) { case "mergefrom": $type = "into"; break; case "merge": $type = "with"; break; case "mergeto": $type = "to"; break; case "afd-mergeto": case "false-positive": echo " . "]\n"; unset($pagename); $takeofflater += 1; continue 2; default: echo "*** templatesplitfailed: " . $template . "\n"; print_r($templatesplit); $nosplits = $transcludes; $templatesplitfailed += 1; echo " . "]\n"; unset($pagename); $takeofflater += 1; continue 2; } $otherpage = "{{pagelist|nspace=|"; unset($otherpages); $otherpages = array(); $otherpage_count = 0; for ($para = 1; $para < count($templatesplit); $para++) { #echo "\n" . $para . ") " . $templatesplit . "\n"; if (preg_match("/^date\s*=/i", $templatesplit)) { $date = str_replace("date=", "", $templatesplit); $date = str_replace("_", " ", $date); if ($date != $monthyear) { if (in_array($transcludes, $mismatched_dates) == FALSE) { $mismatched_dates = $transcludes; $mismatched_date += 1; } echo " Another date: " . $date . " not " . $monthyear; echo " . "]\n"; unset($pagename); unset($type); unset($date); unset($discuss); unset($target); unset($section); unset($multiplesections); unset($reason); $takeofflater += 1; continue 2; } } elseif (preg_match("/^(discuss|discussion|talk)\s*=/i", $templatesplit)) { $discuss = str_replace("discuss=", "", $templatesplit); $discuss = str_replace("discussion=", "", $discuss); $discuss = str_replace("talk=", "", $discuss); } elseif (preg_match("/^target\s*=/i", $templatesplit)) { $target = str_replace("target=", "", $templatesplit); if ($target == $transcludes) { echo "\n** error ** Page " . $transcludes . " proposed merge target is itself\n"; $targetself += 1; } if (in_array($target, $pagename)) { echo " . "]\n"; unset($pagename); unset($type); unset($date); unset($discuss); unset($target); unset($section); unset($multiplesections); unset($reason); $takeofflater += 1; continue 2; } } elseif (preg_match("/^section\s*=/i", $templatesplit)) { $section = str_replace("section=", "", $templatesplit); } elseif (preg_match("/^multiplesections\s*=/i", $templatesplit)) { // Template:Mergefrom uses parameter multiplesections; Merge and Mergeto do not $multiplesections = str_replace("multiplesections=", "", $templatesplit); } elseif (preg_match("/^dir\s*=/i", $templatesplit)) { // Template:Merging } elseif (preg_match("/^(reason|comment)\s*=/i", $templatesplit)) { $reason = str_replace("reason=", "", $templatesplit); $reasons = $pagename . " …… " . $reason; $reason_count += 1; } else { if (in_array($templatesplit, $pagename)) { echo " . "]\n"; unset($pagename); unset($type); unset($date); unset($discuss); unset($target); unset($section); unset($multiplesections); unset($reason); $takeofflater += 1; continue 2; } else { if (preg_match("/^(1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20)=/i", $templatesplit)) { echo "\nNumbered parameter(s):" . $templatesplit; $templatesplit = preg_replace("/(1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20)=/", "", $templatesplit); } $otherpage .= $templatesplit . "|"; $otherpages = $templatesplit; $otherpage_count += 1; } } } $otherpage .= "}}"; echo " -- " . $otherpage . "\n"; #print_r($otherpages); for ($ii = 0; $ii < count($otherpages); $ii++) { $break = 0; $pagecontents = ""; if (str_replace ("_"," ",$otherpages) != $otherpages) { echo "\n$otherpages has underscores\n"; $pos = strpos($ptemplate, $otherpages); $otherpages = str_replace ("_"," ",$otherpages); if ($pos !== false) { $new_template = substr_replace($ptemplate, $otherpages, $pos, strlen($otherpages)); $pcontents = str_replace($ptemplate,$new_template,$pcontents); if ($pcontents == "") { echo "\n??Problem replacing underscores with spaces in merge template\n"; } else if ($objwiki->nobots($transcludes,botuser,$pcontents) == true) { echo "\nReplacing underscores with spaces in merge template\n"; $objwiki->edit($transcludes,$pcontents,"Replace underscores with spaces in merge template",true,true); } } } if (strpos($otherpages,"#") !== false) { $len = strpos($otherpages,"#"); if ($len == 0) $mp = $pagename; else $mp = substr($otherpages,0,$len); // strip section links } else $mp = $otherpages; if ($pagename == $mp) { echo "\n***** PAGE " . $mp . " PROPOSED FOR SELF-MERGE *****\n\n"; $selfmerge += 1; } else if ($mp == "") { echo "\n**** Pagename not specified ****" . $ptemplate . "\n\n"; $noname += 1; $new_template = str_replace ("||","|",$ptemplate); if ($new_template !== $ptemplate) { $pcontents = str_replace($ptemplate,$new_template,$pcontents); if ($pcontents == "") { echo "\n??Problem removing redundant pipe in merge template\n"; } else if ($objwiki->nobots($transcludes,botuser,$pcontents) == true) { echo "\nRemoving redundant pipe in merge template\n"; $objwiki->edit($transcludes,$pcontents,"Remove redundant pipe in merge template",true,true); } } } else if (preg_match("/^(Wiktionary|Wikt):/i",$otherpages)) { echo "\n*** Wiktionary merge: " . $otherpages . " ***\n\n"; $wikt += 1; $otherpage = preg_replace("/nspace=/", "nspace=wikt", $otherpage); } else { while ($pagecontents == "") { if ($break == 5) { echo "\n*** " . $pagename . ": PAGE " . $otherpages . " IS BLANK OR DOES NOT EXIST ***\n\n"; $blanks = $pagename . ":: " . $otherpages; unset($pagecontents); $blank += 1; break; } else { if (preg_match("/^((User|Misplaced Pages|File|MediaWiki|Template|Help|Category|Portal|Draft)(( |_)talk)?|Talk):/", $otherpages) and $break == 0) { echo "\n\n? Other namespace: " . $otherpages . "\n\n"; $others = $otherpages; $othernamespace += 1; } echo "getpage 2: $otherpages|"; $pagecontents = $objwiki->getpage($otherpages); if (preg_match_all("/\{{2}\s?(merge|afd-merge|merging|move section)*\}{2}/i", $pagecontents, $raw2) == 0 and $break == 0) { echo "*** Merge tag not found on " . $otherpages . " *2*\n"; $no_reciprocal += 1; } $cachepage = $otherpages; if (isset($pagecontents)) $cachecontents = $pagecontents; else $cachecontents = ""; $break += 1; } } if (isset($pagecontents) and preg_match("/^\#REDIRECT(\s*|:)\{2}/i", $pagecontents, $redirect)) { echo "\n*** " . $pagename. ": PAGE " . $otherpages . " IS A REDIRECT!! ***\n"; echo $pagecontents . "\n\n"; $redirects += 1; preg_match("/(?<=\{2}))/i", $redirect, $target); echo "Target: " . $target . "\n"; $target = ucfirst($target); $target = str_replace ("_"," ",$target); $target = trim($target); if (strpos($target,"#") !== false) { $len = strpos($target,"#"); if ($len == 0) $targetpage = $target; else $targetpage = substr($target,0,$len); // strip section links } else $targetpage = $target; if ($targetpage == $pagename) { echo $otherpages . " redirects to " . $target . " -- may have been merged\n\n"; $maybes = $pagename . ":: " . $otherpages; $maybe +=1; } else if (strtoupper($otherpages) == strtoupper($target)) { echo "Case difference\n"; $diffcases = $pagename . ":: " . $otherpages . " vs. " . $target; $diffcase += 1; $pos = strpos($ptemplate, $otherpages); if ($pos !== false) { $new_template = substr_replace($ptemplate, $target, $pos, strlen($otherpages)); $pcontents = str_replace($ptemplate,$new_template,$pcontents); if ($pcontents == "") { echo "\n??Problem bypassing redirect in merge template – DIFFCAPS\n"; } else if ($objwiki->nobots($transcludes,botuser,$pcontents) == true) { echo "\nBypassing redirect in merge template – DIFFCAPS\n"; $objwiki->edit($transcludes,$pcontents,"Bypass redirect in merge template – DIFFCAPS",true,true); } } } else { echo "getpage 4: $targetpage|"; $pagecontents = $objwiki->getpage($targetpage); if (preg_match_all("/\{{2}\s?(merge|afd-merge|merging|move section)*\}{2}/i", $pagecontents, $raw4) == 0) { echo "*** Merge tag not found on target page " . $targetpage. " *4*\n"; $redir_no_reciprocals = $pagename . ":: " . $otherpages; $redir_no_reciprocal += 1; } else { echo "*** Merge tag found on target page " . $targetpage. " *4* " . $raw4 . "\n"; $pos = stripos($raw4,$pagename); if ($pos === false) { echo " ** " . $pagename . " not found!\n"; $other_redirects = $pagename . ":: " . $otherpages; $other_redirect += 1; } else { echo " ** found " . $pagename . "\n"; $pages_moved = $pagename . ":: " . $otherpages; $page_moved += 1; $pos = strpos($ptemplate, $otherpages); if ($pos !== false) { $new_template = substr_replace($ptemplate, $target, $pos, strlen($otherpages)); $pcontents = str_replace($ptemplate,$new_template,$pcontents); echo "\n$pcontents\n"; if ($pcontents == "") { echo "\n??Problem bypassing redirect in merge template – apparently " . $otherpages . " moved to " . $target . "\n"; } else if ($objwiki->nobots($transcludes,botuser,$pcontents) == true) { echo "\nBypassing redirect in merge template – apparently " . $otherpages . " moved to " . $target . "\n"; $objwiki->edit($transcludes,$pcontents,"Bypass redirect in merge template – apparently " . $otherpages . " moved to " . $target,true,true); } } } } } } } } if ($otherpage == "{{pagelist|nspace=|}}") { $nopartners = $transcludes; $nopartner += 1; if ($templatesplit == "mergeto") $type = "to ?"; } else if (substr($otherpage,0,22) == "{{pagelist|nspace=wikt") { #echo "\nwikt:\n"; } else if ($templatesplit == "mergeto") { $break = 0; $pagecontents = ""; while ($pagecontents == "") { if ($break == 5) { echo "\n*** " . $pagename . ": PAGE " . $otherpages . " is BLANK or DOES NOT EXIST ***\n\n"; unset($pagecontents); break; } else { if ($otherpages == $cachepage) { echo "getpage 3: $otherpages|from cache\n"; $pagecontents = $cachecontents; } else { echo "getpage 3: $otherpages|"; $pagecontents = $objwiki->getpage($otherpages); if (preg_match_all("/\{{2}\s?(merge|afd-merge|merging|move section)*\}{2}/i", $pagecontents, $raw3) == 0) { echo "*** Merge tag not found on " . $otherpages. " *3*\n"; $no_reciprocal += 1; } } $break += 1; } } if (isset($pagecontents) and preg_match_all("/\{{2}\s?(merge|afd-merge|merging|move section)*\}{2}/i", $pagecontents, $raw) !== 0) { $reciprocal = FALSE; for ($jraw = 0; $jraw < count($raw); $jraw++) { echo "(" . $jraw . ") " . $raw; $pos = stripos($raw,$pagename); if ($pos === false) { echo " ** " . $pagename . " not found!"; } else { echo " ** found " . $pagename; $reciprocal_template = templateprocess($raw); echo "\n§ " . $reciprocal_template . " § "; $reciprocal_templatesplit = array_map('trim',explode("|", $reciprocal_template)); echo $reciprocal_templatesplit; switch ($reciprocal_templatesplit) { case "merge": echo "\n% Reciprocal direction not specified\n"; $no_directions = $pagename . " ==> " . $otherpages; $no_direction += 1; case "mergefrom": case "false-positive": $reciprocal = TRUE; break; case "mergeto": echo "\n!! Conflicting tags !!\n"; $conflicts = $pagename . " <===> " . $otherpages; $conflict += 1; break; default: echo "\n!! Unexpected: " . $templatesplit; } } } if ($reciprocal == FALSE) { echo "\n*** Reciprocal merge tag not found on " . $otherpages. " ***\n"; $no_reciprocal += 1; } else { echo "\n"; echo "mergeto target: " . $otherpage . " ◆ " . $otherpages; echo " . "]\n"; unset($pagename); unset($type); $takeofflater += 1; continue; } } } if (!array_key_exists($key, $discuss)) { // ($discuss == "") if (preg_match("/^(User|Misplaced Pages|Image|File|MediaWiki|Template|Help|Category|Portal):/i",$transcludes,$m)) { $discuss = str_replace($m,$m.' talk',$transcludes); } else { $discuss = "Talk:" . $transcludes; } } } } $j = $j - $takeofflater; if (count($transcludes) > 0) { $mainsubmission .= "* ]\n"; } else { echo "\n*** Category is empty ***\n\n"; } } else { echo "\n" . $a . ": Skipped: " . $mergemonths . "\n"; $skipped += 1; } } if (count($pagename) < 1) { echo "No pagenames! Exiting."; die(); } echo "\n*** Preparing Updates ***\n\n"; print_r($pagename); foreach ($pagename as $key => $title) { if (array_key_exists($date, $counter) and $counter] > $maxcounter) { $maxcounter = $counter]; } if (!array_key_exists($date, $submission)) $submission] = ""; if (!array_key_exists($key, $reason)) $reason = ""; switch ($type) { case "with": // regular merge if (array_key_exists($key, $target)) { // ($target != "") $submission] .= "{{merge log entry|1=]|2=$otherpage|3=]]|talk=$discuss|type=with|reason=$reason}}\n"; } else { $submission] .= "{{merge log entry|1=]|2=$otherpage|talk=$discuss|type=with|reason=$reason}}\n"; } break; case "into": // merge-from $submission] .= "{{merge log entry|1=$otherpage|2=]|talk=$discuss|type=into|reason=$reason}}\n"; break; case "to": // merge-to $submission] .= "{{merge log entry|1=]|2=$otherpage|talk=$discuss|type=into|reason=$reason}}\n"; break; case "to ?": // no partner $submission] .= "{{merge log entry|1=]|2=?|talk=$discuss|type=into|reason=$reason}}\n"; break; default: echo "\n*error* " . $type . "\n"; break; // use "continue 2"? } if (array_key_exists($date, $counter)) $counter] += 1; else $counter] = 1; echo $date . " | " . $counter] . ") " . $key . " ++ " . $title. "\n"; } echo "\n\n*** Posting Updates ***\n\n"; foreach ($submission as $log => $content) { if ($log != "") { echo "Updating> " . $log. "\n"; #echo $content . "\n"; $objwiki->edit("Misplaced Pages:Proposed mergers/Log/" . $log,$content,"Updating list of proposed mergers",false,true); } else echo "\n? Error, null log specification: " . $content . "\n\n"; } echo "Updating Misplaced Pages:Proposed mergers/Log\n"; $objwiki->edit("Misplaced Pages:Proposed mergers/Log",$mainsubmission,"Updating list of logs",true,true); echo "done.\n"; echo "\nCategory members skipped: " . $skipped; echo "\nMaximum pages in a category: " . $maxi; echo "\nMaximum items on a report page: " . $maxcounter; echo "\nOther namespaces skipped: " . $othernamespace . "\n"; print_r($others); echo "\nPattern match failed: " . $matchfailed . "\n"; print_r($nomatches); echo "\nTemplatesplit failed: " . $templatesplitfailed . "\n"; print_r($nosplits); echo "\nNo partner: " . $nopartner . "\n"; if ($nopartner > 0) print_r($nopartners); echo "\nReciprocal direction not specified: " . $no_direction . "\n"; if ($no_direction > 0) print_r($no_directions); echo "\nConflicting tags: " . $conflict . "\n"; if ($conflict > 0) print_r($conflicts); echo "\nPages with multiple proposal dates: " . $mismatched_date . "\n"; if ($mismatched_date > 0) print_r($mismatched_dates); echo "\nPages where reasons are given in the template: " . $reason_count . "\n"; if ($reason_count > 0) print_r($reasons); echo "\nOther pages which are blank or don't exist: " . $blank . "\n"; if ($blank > 0) print_r($blanks); echo "\nOther pages which are redirects: " . $redirects; echo "\n Maybe merged: " . $maybe . "\n"; if ($maybe > 0) print_r($maybes); echo "\n Cases differ: " . $diffcase . "\n"; if ($diffcase > 0) print_r($diffcases); echo "\n Pages moved: " . $page_moved . "\n"; if ($page_moved > 0) print_r($pages_moved); echo "\n Other redirects: " . $other_redirect . "\n"; if ($other_redirect > 0) print_r($other_redirects); echo "\n Redirect with no reciprocal tags: " . $redir_no_reciprocal . "\n"; print_r($redir_no_reciprocals); echo "\nMerge-to targets without reciprocal merge tags: " . $no_reciprocal . "\n"; echo "\nSelf-merges: " . $selfmerge . "\n"; echo "\nSpecified |target is the page itself: " . $targetself . "\n"; echo "\nNo name specified: " . $noname . "\n"; echo "\nWiktionary merges: " . $wikt . "\n"; echo "\nMission accomplished.\n\n"; ?>