Misplaced Pages

User:Merge bot/proposedmergers.php: Difference between revisions

Article snapshot taken from Wikipedia with creative commons attribution-sharealike license. Give it a read and then ask your questions in the chat. We can research this topic together.
< User:Merge bot Browse history interactively← Previous editContent deleted Content addedVisualWikitext
Revision as of 23:22, 31 January 2017 editWbm1058 (talk | contribs)Autopatrolled, Administrators264,845 edits v 1.22 – remove Template:Move section portions from. That's in Category:Split maintenance templates, not Category:Merge templates← 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 
(48 intermediate revisions by 3 users not shown)
Line 1: Line 1:
<source lang=php> <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
* Version 1.22
* *
* (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 28:
require_once 'botclasses.php'; // Botclasses.php was written by User:Chris_G and is available under the GNU General Public License require_once 'botclasses.php'; // Botclasses.php was written by User:Chris_G and is available under the GNU General Public License
include("logininfo.php"); include("logininfo.php");

const bot_version = "1.110";
const botuser = "Merge bot";


function templateprocess($processed) { function templateprocess($processed) {
Line 43: 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 48: Line 52:
$processed = preg_replace("/^(Merge from|Merge_from|Merge-from|Include|Mergrefrom|Mergefrom-category|MergeFrom|Mergefrom)/i", "mergefrom", $processed); $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); $processed = preg_replace("/^(Mergefrom-multiple|Multiplemergefrom|Mergefrommultiple|Mergefrommulti|Multimergefrom)/i", "mergefrom", $processed);



# {{Afd-merge from}}, {{Merging from}} # {{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); $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) # 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("/^(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("/^(MergePartial|Merge-multiple-to|Merge to article|Merge_to_article)/i", "mergeto", $processed);
$processed = preg_replace("/^(Mergeto-multiple|Multiplemergeto|Multiplemergeinto|Merge into|Merge_into|MergeTo|Mergeto|Merge2)/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}} # {{Afd-merge to}}
$processed = preg_replace("/^(Afd-merge to|Afd-merge_to|Afd-mergeto|Afdmergeto|AfD-merge to|AfD-merge_to)/i", "mergeto", $processed); $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; 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; $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_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 = ""; $mainsubmission = "";
$skipped = 0;
$counter = array();
$maxcounter = 0;
$submission = array();
$nomatches = array();
$nosplits = array();


echo "Logging in...\n"; echo "Logging in...\n";
$objwiki = new wikipedia(); $objwiki = new wikipedia();
$objwiki->http->useragent = '] php wikibot classes';
$objwiki->login($mbuser, $mbpass); $objwiki->login($mbuser, $mbpass);
echo "...done.\n"; echo "...done.\n";
Line 90: Line 144:
} }


for ($i = 0; $i < count($transcludes); $i++) { // for each page for ($i = 0; $i < count($transcludes); $i++) { // for each page in the category
if ($i > $maxi) { if ($i > $maxi) {
Line 96: 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 105: Line 159:
$getpagefailed = 0; $getpagefailed = 0;
do { do {
$contents = $objwiki->getpage($transcludes); if ($transcludes == $cachepage) {
echo "getpage 1: $transcludes|from cache\n";
$contents = $cachecontents;
}
else {
echo "getpage 1: $transcludes|";
$contents = $objwiki->getpage($transcludes);
}
if ($contents == FALSE) { if ($contents == FALSE) {
echo "\n\n?? getpage failed: " . $transcludes . "\n\n"; echo "\n\n?? getpage failed: " . $transcludes . "\n\n";
Line 117: Line 178:
} while ($contents == FALSE); } while ($contents == FALSE);


if (preg_match_all("/\{{2}\s?(merge|afd-merge|merging|move section)*\}{2}/i", $contents, $raw) == 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 128: Line 189:
} }


$mergetemplates = count($raw1);
if ($mergetemplates > 1) {
echo "$mergetemplates merge templates on $transcludes\n";
print_r($raw1);
}
$takeofflater = 0; $takeofflater = 0;

for ($j = 0; $j < count($raw); $j++) { // for each utterance
for ($j = 0; $j < $mergetemplates; $j++) { // for each merge template on the page
$key = $a . "-" . $i . "-" . $j; $key = $a . "-" . $i . "-" . $j;
$pagename = $transcludes; $pagename = $transcludes;
echo $key . ">> " . $pagename; echo $key . ">> " . $pagename;
$template = templateprocess($raw); $template = templateprocess($raw1);
#echo "Count of raw: " . count($raw) . "\n"; #echo " § " . $template . " §";

$ptemplate = $raw1;
if (isset($contents)) $pcontents = $contents;
else $pcontents = "";
unset($contents); unset($contents);
Line 144: Line 215:
case "mergefrom": case "mergefrom":
$type = "into"; $type = "into";
break;
case "merge":
$type = "with";
break; break;
case "mergeto": case "mergeto":
$type = "to";
break;
case "afd-mergeto":
case "false-positive":
echo " . "]\n"; echo " . "]\n";
unset($pagename); unset($pagename);
$takeofflater += 1; $takeofflater += 1;
break; continue 2;
case "merge":
$type = "with";
break;
default: default:
echo "*** templatesplitfailed: " . $templatesplit . "\n"; echo "*** templatesplitfailed: " . $template . "\n";
print_r($templatesplit); print_r($templatesplit);
$nosplits = $transcludes; $nosplits = $transcludes;
$templatesplitfailed += 1; $templatesplitfailed += 1;
echo " . "]\n";
continue;
unset($pagename);
$takeofflater += 1;
continue 2;
} }
$otherpage = "{{pagelist|nspace=|"; $otherpage = "{{pagelist|nspace=|";
unset($otherpages);
$otherpages = array();
$otherpage_count = 0;


for ($para = 1; $para < count($templatesplit); $para++) { for ($para = 1; $para < count($templatesplit); $para++) {
if (preg_match("/^date=/i", $templatesplit)) { #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);

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=/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("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 180: Line 289:
unset($discuss); unset($discuss);
unset($target); unset($target);
unset($section);
unset($multiplesections); unset($multiplesections);
unset($reason);
$takeofflater += 1; $takeofflater += 1;
continue 2; continue 2;
} }
} }
elseif (preg_match("/^multiplesections=/i", $templatesplit)) { // Template:Mergefrom uses parameter multiplesections; Merge and Mergeto do not 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); $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 { else {
Line 196: Line 318:
unset($discuss); unset($discuss);
unset($target); unset($target);
unset($section);
unset($multiplesections); unset($multiplesections);
unset($reason);
$takeofflater += 1; $takeofflater += 1;
continue 2; continue 2;
} }
else { 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 . "|"; $otherpage .= $templatesplit . "|";
$otherpages = $templatesplit;
$otherpage_count += 1;
} }
} }
Line 208: Line 338:
$otherpage .= "}}"; $otherpage .= "}}";
echo " -- " . $otherpage . "\n"; echo " -- " . $otherpage . "\n";
#print_r($otherpages);


if ($date == "") { for ($ii = 0; $ii < count($otherpages); $ii++) {
$date = date("F Y"); $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);
}
}
}
}
}
}
}
} }

elseif ($date != $monthyear) {
if ($otherpage == "{{pagelist|nspace=|}}") {
echo "\nAnother date: " . $date . " not " . $monthyear . "\n";
$nopartners = $transcludes;
unset($pagename);
unset($type); $nopartner += 1;
unset($date); if ($templatesplit == "mergeto") $type = "to ?";
}
unset($discuss);
else if (substr($otherpage,0,22) == "{{pagelist|nspace=wikt") {
unset($target);
#echo "\nwikt:\n";
unset($multiplesections);
}
$takeofflater += 1;
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 ($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 236: Line 600:
$j = $j - $takeofflater; $j = $j - $takeofflater;


if (count($transcludes) > 0) {
$mainsubmission .= "* ]\n";
$mainsubmission .= "* ]\n";
}
else {
echo "\n*** Category is empty ***\n\n";
}
} }
else { else {
Line 253: 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] .= "# . "]] Request to merge ''']''' with '''" . $otherpage . "''' to ''' . "]]''' ([[" .
"{{merge log entry|1=]|2=$otherpage|3=]]|talk=$discuss|type=with|reason=$reason}}\n";
# $discuss . "|Discuss]])\n";
$submission] .= "{{merge log entry|1=]|2=$otherpage|3=]]|talk=$discuss|type=with}}\n";
} }
else { else {
#$submission] .= "# . "]] Request to merge ''']''' with '''" . $otherpage . "''' ( . "|Discuss]])\n"; $submission] .= "{{merge log entry|1=]|2=$otherpage|talk=$discuss|type=with|reason=$reason}}\n";
$submission] .= "{{merge log entry|1=]|2=$otherpage|talk=$discuss|type=with}}\n";
} }
break; break;
case "into": // merge-from case "into": // merge-from
#$submission] .= "# ''' . "]]''' Request to merge '''" . $otherpage . "''' into ''']''' ( . "|Discuss]])\n"; $submission] .= "{{merge log entry|1=$otherpage|2=]|talk=$discuss|type=into|reason=$reason}}\n";
break;
$submission] .= "{{merge log entry|1=$otherpage|2=]|talk=$discuss|type=into}}\n";
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; break;
default: default:
echo "\n*error* " . $type . "\n"; echo "\n*error* " . $type . "\n";
break; // use "continue 2"?
continue;
}
if ($otherpage == "{{pagelist|nspace=|}}") {
$nopartners = $title;
$nopartner += 1;
} }


$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 290: 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"; #echo $content . "\n";
$objwiki->edit("Misplaced Pages:Proposed mergers/Log/" . $log,$content,"Updating list of proposed mergers",false,true); $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 309: 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";
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"; echo "\nMission accomplished.\n\n";


?> ?>
</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";
?>