<?php
/*
CatScan searches MediaWiki categories.
Copyright (C) 2005, Daniel Kinzler, brightbyte.de
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
define("WS_WEB",true);
require_once( "common/WebInit.php" );
require_once( "WikiAccess.php" );
require_once( "WikiSelector.php" );
require_once( "WikiSenseLocalizer.php" );
require_once( "QCache.php" );
function printWikiLinks($titles, $ns) {
global $wiki;
if (!is_array($titles)) {
$titles= explode('|',$titles);
}
$first = true;
foreach ($titles as $ttl) {
if ($first) $first = false;
else print ", ";
$n = $wiki->asUrlName($ns, $ttl);
print "[[:$n|$ttl]]";
}
}
function printLinks($titles, $ns) {
global $wiki, $terse, $wgCanonicalNamespaceNames;
if (!is_array($titles)) {
$titles= explode('|',$titles);
}
sort($titles);
$s= '';
foreach ($titles as $c) {
if (!$c) continue;
if ($s) $s.= ', ';
$label= escapeHtml(str_replace('_',' ',$c));
if ($wiki && $wiki->baseURL) {
$t= getPrefixedTitle($c, $ns);
$wikiLink= $wiki->baseURL . '?title=' . urlencode($t);
}
else $wikiLink= NULL;
if ($wikiLink) $s.= "<a href='$wikiLink'>$label</a>";
else $s.= $label;
}
print $s;
}
function getPrefixedTitle($title, $ns) {
global $wiki;
$t= $title;
if ($ns) {
$n= $wiki->getNsText($ns);
if (!$n) $n= $ns;
$t= $n . ':' . $t;
}
return $t;
}
$thumbCol= 0;
$maxThumbCol= 4;
function printImageHTML($page, $mode = NULL) {
global $wiki, $commons, $thumbCol, $maxThumbCol;
if ($thumbCol==0) print "\n<tr>\n";
$wikiLink= NULL;
$t= getPrefixedTitle($page->page_title, $page->page_namespace);
$label= escapeHtml(str_replace('_',' ',$page->page_title));
if ($page->on_commons) $w=& $commons;
else $w=& $wiki;
if ($w && $w->baseURL) {
$wikiLink= $w->baseURL . '?title=' . urlencode($t);
}
?>
<td align='center' class='cell'>
<div class='thumb' style='margin-left:auto; margin-right:auto; text-align:center;'>
<?= $w->getThumbnailHTML($page)?>
</div>
<div class='thumblabel'>
<small><a href='<?=$wikiLink?>'><?=$label?></a>
<? if ($page->on_commons) print "(commons)"; ?>
</small>
</div>
<? if (@$page->used_in): ?>
<p class='tags' style='text-align:left;'>
<b>Used in</b>: <? printLinks($page->used_in,NS_MAIN); ?>
</p>
<? endif; ?>
<? if (@$page->cats): ?>
<p class='cats' style='text-align:left;'>
<b>Categories</b>: <? printLinks($page->cats,NS_CATEGORY); ?>
</p>
<? endif; ?>
</td>
<?
$thumbCol+= 1;
if ($thumbCol>=$maxThumbCol) {
print "\n</tr>\n";
$thumbCol= 0;
}
}
function printArticleHTML($page, $mode = NULL) {
global $wiki, $terse, $wsgCatScanText;
$wikiLink= NULL;
$t= getPrefixedTitle($page->page_title, $page->page_namespace);
$label= escapeHtml(str_replace('_',' ',$t));
if ($wiki && $wiki->baseURL) {
$wikiLink= $wiki->baseURL . '?title=' . urlencode($t);
}
$n= NULL;
$class= 'dummy';
if ($mode == 'al' && @$page->tags) $class= 'highlite';
?>
<tr class='leaf'>
<td align='right'>
<? if (@$page->cats): ?>
<span class='cats'>
<? printLinks($page->cats,NS_CATEGORY); ?>
</span>
<? endif; ?>
</td>
<td class='label'>
<span class="<?= $class ?>">
<a href='<?=$wikiLink?>'><?=$label?></a>
<? if (@$page->page_restrictions && preg_match('/edit=(\w+)/',$page->page_restrictions,$m)): ?>
<span class='restrictions restrictions_edit_<?= $m[1] ?>'>
(<?= $wsgCatScanText->msg('restrictions_edit_'.$m[1]) ?>)
</span>
<? endif; ?>
<? if (@$page->page_len): ?>
<span class='tags'>
(<?= $page->page_len ?> bytes)
</span>
<? endif; ?>
<? if (@$page->page_len): ?>
<span class='tags'>
(<?= $page->page_len ?> bytes)
</span>
<? endif; ?>
<? if (@$page->links): ?>
<span class='tags'>
(<?= $page->links ?> links)
</span>
<? endif; ?>
<?
if ($mode=='rc') {
?>
<span class='log'>
<?
print wfTimestamp(TS_DB,$page->rc_timestamp);
print ', ';
print '<b>';
printLinks($page->rc_user_text, NS_USER );
print '</b>';
print ' ';
print '(';
if ($page->rc_type==1) print '<b>new</b>';
else if ($page->rc_type==2) print '<b>moved</b>';
else if ($page->rc_type==3) /*log*/ ;
else {
$lnk= $wikiLink.= '&diff=prev&oldid='.$page->rc_this_oldid;
print "<a href='$lnk'>diff</a>";
}
print ', ';
$lnk= $wikiLink.= '&action=history';
print "<a href='$lnk'>versions</a>";
print ')';
if ($page->rc_comment) {
print ': ';
print '<i>';
print escapeHtml($page->rc_comment);
print '</i>';
}
if ($page->rc_minor) {
print ' (<b>K</b>)';
}
if ($page->rc_bot) {
print ' (<b>bot</b>)';
}
?>
</span>
<?
}
?>
<? if (@$page->tags): ?>
<span class='tags'>
(<?= printLinks($page->tags, $mode == 'cs' ? NS_CATEGORY : NS_TEMPLATE ) ?>)
</span>
<? endif; ?>
</span>
</td>
</tr>
<?
return $n;
}
function printArticleCSV($page) {
print $page->page_namespace;
print "\t";
print $page->page_title;
print "\t";
print @$page->cats;
print "\t";
print @$page->tags;
print "\t";
print @$page->page_id;
if (@$page->rc_last_oldid) {
print "\t";
print $page->rc_last_oldid;
}
if (@$page->rc_this_oldid) {
print "\t";
print $page->rc_this_oldid;
}
print "\r\n";
}
function printArticleWiki($page, $mode) {
global $wiki;
$n = $wiki->asUrlName($page->page_namespace, $page->page_title);
$pre = $page->page_namespace == NS_CATEGORY || $page->page_namespace == NS_IMAGE ? ":" : "";
print "* [[$pre$n]]";
if (@$page->cats) {
print ": ";
printWikiLinks($page->cats, NS_CATEGORY);
}
if (@$page->tags) {
if (@$page->cats) print "; ";
else print ": ";
printWikiLinks($page->tags, $mode == 'cs' ? NS_CATEGORY : NS_TEMPLATE);
}
print "\n";
}
function makeSQLSet($titles) {
global $db;
if (!is_array($titles)) {
$titles= preg_split('! *[;/\|] *!',$titles);
}
$s= '';
foreach ($titles as $t) {
if ($s) $s.= ', ';
$t= wsfDBTitle($t);
$s.= $db->addQuotes($t);
}
return $s;
}
function listArticles( $base, $filter, $mode= 'cs', $inverse= false ) {
global $db, $format, $wiki, $commons;
if (!$filter) { #list all articles in categories
#print "COMMONS DB: ".$commons->dbname;
if ( $mode == 'il') { #categorized images
$sql= "SELECT page_id, page_namespace, page_title, page_restrictions,
group_concat(DISTINCT c.cl_to SEPARATOR '|') as cats,
if(local.img_size IS NULL,1,0) as on_commons,
if(local.img_width IS NOT NULL, local.img_width, commons.img_width) as img_width,
if(local.img_height IS NOT NULL, local.img_height, commons.img_height) as img_height,
if(local.img_size IS NOT NULL, local.img_size, commons.img_size) as img_size,
if(local.img_major_mime IS NOT NULL, local.img_major_mime, commons.img_major_mime) as img_major_mime,
if(local.img_minor_mime IS NOT NULL, local.img_minor_mime, commons.img_minor_mime) as img_minor_mime
FROM page
JOIN categorylinks as c ON c.cl_from = page_id
LEFT JOIN image as local ON page_title = local.img_name
LEFT JOIN ".$commons->dbname.".image as commons ON page_title = commons.img_name
WHERE page_namespace = ".NS_IMAGE." AND c.cl_to in (".makeSQLSet($base).")
GROUP BY page_title
ORDER BY page_title";
}
else if ( $mode == 'iul') { #categorized and used images
/*$sql= "SELECT ".NS_IMAGE." as page_namespace, il_to as page_title,
group_concat(DISTINCT page_title SEPARATOR '|') as used_in,
group_concat(DISTINCT c.cl_to SEPARATOR '|') as cats,
if(local.img_size IS NULL,1,0) as on_commons,
if(local.img_width IS NOT NULL, local.img_width, commons.img_width) as img_width,
if(local.img_height IS NOT NULL, local.img_height, commons.img_height) as img_height,
if(local.img_size IS NOT NULL, local.img_size, commons.img_size) as img_size,
if(local.img_major_mime IS NOT NULL, local.img_major_mime, commons.img_major_mime) as img_major_mime,
if(local.img_minor_mime IS NOT NULL, local.img_minor_mime, commons.img_minor_mime) as img_minor_mime
FROM imagelinks
LEFT JOIN image as local ON il_to = local.img_name
LEFT JOIN ".$commons->dbname.".image as commons ON il_to = commons.img_name
JOIN page ON il_from = page_id
JOIN categorylinks as c ON c.cl_from = page_id
WHERE c.cl_to in (".makeSQLSet($base).")
AND page_namespace = ".NS_MAIN."
AND page_is_redirect = 0
GROUP BY il_to
ORDER BY il_to";*/
$sql= " SELECT page_namespace, page_title, page_restrictions,
group_concat(DISTINCT cat SEPARATOR '|') as cats,
group_concat(DISTINCT art SEPARATOR '|') as used_in,
if(local.img_size IS NULL,1,0) as on_commons,
if(local.img_width IS NOT NULL, local.img_width, commons.img_width) as img_width,
if(local.img_height IS NOT NULL, local.img_height, commons.img_height) as img_height,
if(local.img_size IS NOT NULL, local.img_size, commons.img_size) as img_size,
if(local.img_major_mime IS NOT NULL, local.img_major_mime, commons.img_major_mime) as img_major_mime,
if(local.img_minor_mime IS NOT NULL, local.img_minor_mime, commons.img_minor_mime) as img_minor_mime
FROM
( SELECT page_namespace, page_title, page_restrictions,
NULL as art,
c.cl_to as cat
FROM page
JOIN categorylinks as c ON c.cl_from = page_id
WHERE page_namespace = ".NS_IMAGE." AND c.cl_to in (".makeSQLSet($base).")
UNION
SELECT ".NS_IMAGE." as page_namespace, il_to as page_title,
NULL as page_restrictions, " . /* #FIXME: join with img-page to get page_restrictions field! */ "
page_title as art,
c.cl_to as cat
FROM imagelinks
JOIN page ON il_from = page_id
JOIN categorylinks as c ON c.cl_from = page_id
WHERE c.cl_to in (".makeSQLSet($base).")
AND page_namespace = ".NS_MAIN."
AND page_is_redirect = 0
) as img
LEFT JOIN image as local ON page_title = local.img_name
LEFT JOIN ".$commons->dbname.".image as commons ON page_title = commons.img_name
GROUP BY page_title
ORDER BY page_title";
}
else {
$sql= "SELECT page_id, page_namespace, page_title, page_restrictions,
group_concat(DISTINCT c.cl_to SEPARATOR '|') as cats
FROM page
JOIN categorylinks as c ON c.cl_from = page_id
WHERE c.cl_to in (".makeSQLSet($base).")
GROUP BY page_id
ORDER BY page_title";
}
}
else if ($mode=='rc') {
if (!is_array($filter)) $filter= array('hours'=>$filter);
$h= (int)$filter['hours'];
$t= time() - ($h * 60 * 60);
$t= wfTimestamp(TS_MW,$t);
$where= '';
if (@$filter['nobots']) $where.= ' AND rc_bot = 0 ';
if (@$filter['nominor']) $where.= ' AND rc_minor = 0 ';
if (@$filter['onlynew']) $where.= ' AND rc_new = 1 ';
#print_r($filter);
#TODO: join with page table to get page_restrictions!
$sql= "SELECT rc_title as page_title,
rc_namespace as page_namespace,
rc_cur_id as page_id,
rc_type, rc_timestamp, rc_user_text, rc_comment,
rc_minor, rc_bot, rc_new,
rc_this_oldid, rc_last_oldid,
group_concat(DISTINCT c.cl_to SEPARATOR '|') as cats
FROM ".$wiki->getTableName('recentchanges')."
JOIN categorylinks as c ON c.cl_from = rc_cur_id
WHERE rc_timestamp > ".$db->addQuotes($t)."
$where
AND c.cl_to in (".makeSQLSet($base).")
GROUP BY rc_id
ORDER BY rc_timestamp DESC";
/*$sql= "SELECT page_id, page_namespace, page_title,
group_concat(r.rev_user_text SEPARATOR '|') as users,
group_concat(r.rev_timestamp SEPARATOR '|') as times,
group_concat(r.rev_id SEPARATOR '|') as ids,
group_concat(DISTINCT c.cl_to SEPARATOR '|') as cats
FROM page
JOIN categorylinks as c ON c.cl_from = page_id
JOIN revision as r ON page_latest = r.rev_id
WHERE c.cl_to in (".makeSQLSet($base).")
AND r.rev_timestamp > ".$db->addQuotes($t)."
GROUP BY page_id
ORDER BY page_title";
*/
}
else if ($mode == 'ss') {
/*
$size= (int)$filter;
if ( $inverse ) { #bigger
$where= 'page_len >= '.$size;
}
else { #smaller
$where= 'page_len < '.$size;
}
$sql= "SELECT page_id, page_namespace, page_title, page_len,
group_concat(DISTINCT c.cl_to SEPARATOR '|') as cats
FROM page
JOIN categorylinks as c ON c.cl_from = page_id
WHERE c.cl_to in (".makeSQLSet($base).")
AND page_namespace = ".NS_MAIN."
AND page_is_redirect = 0
AND ".$where."
GROUP BY page_id
ORDER BY page_title";
*/
if (!is_array($filter)) $filter= array('hours'=>$filter);
$size= $filter['size'] ? (int)$filter['size'] : NULL;
$links= $filter['links'] ? (int)$filter['links'] : NULL;
$where= '';
$left= '';
$having= '';
$op= @$filter['stubop'] ? $filter['stubop'] : 'or';
if ($size && $links) {
if ($op=='and') {
$where.= ' page_len < '.$size;
$having.= ' HAVING links < '.$links;
}
else {
$having.= ' HAVING links < '.$links.' OR page_len < '.$size;
}
}
else if ($size) $where.= ' page_len < '.$size;
else if ($links) $having.= ' HAVING links < '.$links;
if ($links) {
$left= 'LEFT ';
if ($where) $where.= ' AND ';
$where.= 'pl_namespace = '.NS_MAIN;
}
$sql= "SELECT page_id, page_namespace, page_title, page_restrictions, page_len,
".($links?"count(DISTINCT t.pl_title) as links, ":"")."
group_concat(DISTINCT c.cl_to SEPARATOR '|') as cats
FROM page
JOIN categorylinks as c ON c.cl_from = page_id
".($links?"$left JOIN pagelinks as t on t.pl_from = page_id ":"")."
WHERE c.cl_to in (".makeSQLSet($base).")
AND page_namespace = ".NS_MAIN."
AND page_is_redirect = 0
AND ".$where."
GROUP BY page_id
$having
ORDER BY page_title";
}
else if ($mode == 'ls') {
$links= (int)$filter;
if ( $inverse ) { #more
$having= 'links >= '.$links;
$left= '';
}
else { #smaller
$having= 'links < '.$links;
$left= 'LEFT ';
}
$sql= "SELECT page_id, page_namespace, page_title, page_restrictions,
group_concat(DISTINCT c.cl_to SEPARATOR '|') as cats,
count(DISTINCT t.pl_title) as links
FROM page
JOIN categorylinks as c ON c.cl_from = page_id
$left JOIN pagelinks as t on t.pl_from = page_id
WHERE c.cl_to in (".makeSQLSet($base).")
AND pl_namespace = ".NS_MAIN."
AND page_namespace = ".NS_MAIN."
AND page_is_redirect = 0
GROUP BY page_id
HAVING $having
ORDER BY page_title";
}
else {
if ( $mode == 'al') { #highlite
$filterHaving= '';
}
else if ( $inverse ) { #without
$filterHaving= 'HAVING tags IS NULL';
}
else { #with
$filterHaving= 'HAVING tags IS NOT NULL';
}
if ( $mode == 'cs' ) {
$sql= "SELECT page_id, page_namespace, page_title, page_restrictions,
group_concat(DISTINCT c.cl_to SEPARATOR '|') as cats,
group_concat(DISTINCT if (t.cl_to in (".makeSQLSet($filter)."), t.cl_to, null) SEPARATOR '|') as tags
FROM page
JOIN categorylinks as c ON c.cl_from = page_id
JOIN categorylinks as t on t.cl_from = page_id
WHERE c.cl_to in (".makeSQLSet($base).")
GROUP BY page_id
$filterHaving
ORDER BY page_title";
}
else {
$left= '';
if ( $mode == 'al' ) $left= 'LEFT';
$sql= "SELECT page_id, page_namespace, page_title, page_restrictions,
group_concat(DISTINCT c.cl_to SEPARATOR '|') as cats,
group_concat(DISTINCT if (t.tl_title in (".makeSQLSet($filter)."), t.tl_title, null) SEPARATOR '|') as tags
FROM page
JOIN categorylinks as c ON c.cl_from = page_id
$left JOIN templatelinks as t on t.tl_from = page_id
WHERE c.cl_to in (".makeSQLSet($base).")
GROUP BY page_id
$filterHaving
ORDER BY page_title";
}
}
if ($format=='html') $sql.= " LIMIT 1000";
#AND page_namespace = ".NS_MAIN."
#print "*** $sql ***";
$res= $db->query($sql, 'getSubcategories');
$c= 0;
if ($format=='html') print "\n<table>\n";
while ($page= $db->fetchObject($res)) {
if ($format=='wiki') printArticleWiki($page, $mode); #FIXME: gallery, if $mode=='il' || $mode=='iul'
else if ($format=='csv') printArticleCSV($page);
else if ($mode=='il' || $mode=='iul') printImageHTML($page);
else printArticleHTML($page, $mode);
$c+= 1;
}
if ($format=='html') {
if ($c==1000) print "<tr><td colspan='2'><p class='error'>Search aborted after 1000 entries!</p></td></tr>";
print "\n</table>\n";
}
$db->freeResult($res);
return $c;
}
function getDeepCategories( $cats, $depth= 2, $max= 512 ) {
global $wsgCatScanText, $db;
if (!is_array($cats)) {
$todo= preg_split('! *[;/\|] *!',$cats);
}
else $todo= $cats;
if ($depth<=1) return $todo;
if ($depth>100) $depth= 100;
if ($max>1024) $max= 1024;
wsfLog($wsgCatScanText->msg('recursing_categories'),LL_INFO);
$key= implode('|',$todo);
$done= array();
$i= 0;
while ($todo && $i<$depth && sizeof($done)<$max) {
$i+= 1;
collectDeepCategories( $todo, $done, "collectDeepCategories($key, $i)", "Subcategories of $key, level $i" );
}
if ($todo && $i<$depth) wsfLog("WARNING: scan aborted after ".sizeof($done)." categories ($i levels)",LL_WARN);
return $done;
}
function collectDeepCategories( &$todo, &$done, $cachekey=NULL, $cachedescr=NULL) {
global $db;
if (!$todo) return array();
$data= false;
$cache= NULL;
if ($cachekey) {
$cache=& QCache::newWithoutQuery($db->getProperty('mDBname'), "collectDeepCategories", $cachedescr, 60*60*24, $cachekey);
#$cache->debug= true;
$data= $cache->load( true );
}
if ( $data===false ) {
$sql= "SELECT page_title
FROM page
JOIN categorylinks ON cl_from = page_id
WHERE cl_to in (" . makeSQLSet($todo) . " )
AND page_namespace = ".NS_CATEGORY."
AND page_is_redirect = 0";
$res= $db->query($sql, 'getDeepCategories');
$found= array();
$data= array();
while ( $row= $db->fetchRow($res) ) {
if ( $cache && $cache->cacheDB ) $data[]= $row;
$found[]= $row['page_title'];
}
$db->freeResult($res);
if ( $cache && $cache->cacheDB ) {
$cache->putData( $data );
}
}
else {
wsfLog("NOTE: using cached results for $cachedescr, {$cache->queryRecord->age} seconds old",LL_WARN);
$found= array();
foreach ($data as $row) {
$found[]= $row['page_title'];
}
}
$done= array_merge($done,$todo);
$todo= array_diff($found,$done);
return $found;
}
function getOnChangeToggleJS($enable, $disable = NULL) {
global $paramFields;
if (is_null($disable)) {
if ($enable) $disable= array_diff($paramFields, $enable);
else $disable= $paramFields;
}
if (!$enable && !$disable) return '';
return ' onchange="'.escapeHtml(getSetDisabledJS($enable,false)).escapeHtml(getSetDisabledJS($disable,true)).'" ';
}
function getSetDisabledJS ($ids, $value) {
if (!$ids) return '';
if ($value) $value= 'true';
else $value= 'false';
$js= 'setDisabled( new Array(';
$first= true;
foreach($ids as $id) {
if ($first) $first= false;
else $js.= ', ';
$js.= '\''.addslashes($id).'\'';
}
$js.="), $value); ";
return $js;
}
$knownLanguages= array('ar', 'bg', 'ca', 'da', 'de', 'el', 'en', 'eo', 'es', 'fi', 'fr', 'gl', 'he', 'hr', 'hu', 'it', 'ja', 'lt', 'mk', 'nds', 'nl', 'pl', 'pt', 'ro', 'ru', 'sk', 'sv', 'th', 'uk', 'vi', 'zh-cn', 'zh-hant');
$wsgCatScanText=& WikiSenseLocalizer::initialize('CatScan', $knownLanguages, $wgRequest->getVal('set-userlang'));
$wikiSelector= new WikiSelector();
$mode= $wgRequest->getVal('mode','cs');
$basecat= $wgRequest->getVal('basecat');
$basedeep= $wgRequest->getVal('basedeep',3);
$tagcat= $wgRequest->getVal('tagcat');
$templates= $wgRequest->getVal('templates');
$tagdeep= $wgRequest->getVal('tagdeep',3);
$untagged= $wgRequest->getVal('untagged');
$size= $wgRequest->getVal('size',512);
$links= $wgRequest->getVal('links',4);
$stubop= $wgRequest->getVal('stubop','or');
$hours= $wgRequest->getVal('hours',12);
$nominor= $wgRequest->getVal('nominor');
$nobots= $wgRequest->getVal('nobots');
$onlynew= $wgRequest->getVal('onlynew');
$filterMode= $wgRequest->getVal('filter','w');
$terse= $wgRequest->getVal('terse');
$conf= $wgRequest->getVal('conf');
$defFormat = $wgRequest->getVal('raw',0) ? 'csv' : 'html';
$format= $wgRequest->getVal('format', $defFormat );
$db= NULL;
if ($basecat) $basecat= trim($basecat);
if ($tagcat) $tagcat= trim($tagcat);
if ($hours && $hours>24*30) $hours= 24*30;
if ($basedeep && $basedeep>100) $basedeep= 100;
if ($tagdeep && $tagdeep>100) $tagdeep= 100;
$doquery= false;
if ( $wikiSelector->domain && $mode ) {
if ($mode=='cs' && $tagcat) {
$doquery= true;
}
else if ($mode=='ts' && $templates) {
$doquery= true;
}
else if ($mode=='ss' && ($size || $links)) {
$doquery= true;
}
else if ($mode=='ls' && $links) {
$doquery= true;
}
else if ($mode=='rc' && $hours) {
$doquery= true;
}
else if ($mode=='cl' || $mode=='al') {
$doquery= true;
}
else if ($mode=='il' || $mode=='iul') {
$doquery= true;
}
}
$commons= NULL;
$wiki= NULL;
if ( $wikiSelector->domain ) {
$wiki= WikiAccess::newInstance($wikiSelector->domain);
if ($wiki) {
$db=& $wiki->wikiDB;
}
if ($mode=='il' || $mode=='iul') {
$commons= WikiAccess::newInstance('commons.wikimedia.org');
}
}
if ($doquery && $format!='html') {
#header("Content-Type: text/csv; charset=utf-8");
header("Content-Type: text/plain; charset=utf-8");
$wsgLogLevel= LL_MUTE;
if ($basedeep && $basedeep>1 && $basecat) $basecat= getDeepCategories($basecat,$basedeep);
if ($tagdeep && $tagdeep>1 && $tagcat) $tagcat= getDeepCategories($tagcat,$tagdeep);
if ($mode=='cs') listArticles( $basecat, $tagcat, $mode );
else if ($mode=='ts') $c= listArticles( $basecat, $templates, $mode, $untagged );
else if ($mode=='ss') $c= listArticles( $basecat, array('size'=>$size, 'links'=>$links, 'stubop'=>$stubop), $mode );
else if ($mode=='ls') $c= listArticles( $basecat, $links, $mode );
else if ($mode=='al') $c= listArticles( $basecat, $templates, $mode );
else if ($mode=='rc') $c= listArticles( $basecat, array('hours'=>$hours, 'onlynew'=>$onlynew, 'nominor'=>$nominor, 'nobots'=>$nobots), $mode );
else if ($mode=='il' || $mode=='iul') $c= listArticles( $basecat, NULL, $mode );
else if ($mode=='cl') {
if (!is_array($basecat)) $basecat= array($basecat);
sort($basecat);
foreach ($basecat as $cat) {
$p= new stdClass();
@$p->page_title= $cat;
@$p->page_namespace= NS_CATEGORY;
if ($format == 'csv') printArticleCSV($p);
else if ($format == 'wiki') printArticleWiki($p, $mode);
}
}
exit;
}
$paramFields= array('tagcat','tagdeep','templates','untagged','size','links','stubop','hours','nobots','nominor','onlynew');
$formats = array(
'html' => $wsgCatScanText->msg('format_html'),
'csv' => $wsgCatScanText->msg('format_csv'),
'wiki' => $wsgCatScanText->msg('format_wiki'),
);
header("Content-Type: text/html; charset=utf-8");
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Cat Scan</title>
<?
if ($doquery) print '<meta name="robots" content="noindex, nofollow"/>';
else print '<meta name="robots" content="nofollow"/>';
?>
<link rel="stylesheet" href="wikisense.css" type="text/css">
<style type='text/css'>
body { font-family: sans-serif; }
.sectionhead { font-weight:bold; white-space:nowrap; }
.parent { font-weight:bold; font-style:italic; }
.leaf { font-weight:normal; margin-left:3ex; }
/* .settings input[type=text] { width:48ex; } */
/* .settings select { font-size:80%; } */
.cell { padding:0.5ex; background-color:#EEEEEE; vertical-align:top; }
.thumb { border:1px solid #AAAAAA; padding:0.5ex; background-color:#EEEEEE; }
.error { font-weight:bold; color:red; }
.loaded { color:black; text-decoration: none; }
.content { margin-left:2ex; }
.links { font-weight:normal; font-size:80%; }
.tags { font-weight:normal; font-style:italic; font-size:72%; background-color:yellow; }
.cell .tags { font-weight:normal; font-style:italic; font-size:72%; background-color:#F0F0FF; }
.log { font-weight:normal; font-style:normal; font-size:72%; }
.cats { font-weight:normal; font-style:italic; font-size:72%; background-color:#F0FFF0; text-align:right; }
.tags a:link { color:inherit; text-decoration:none; }
.cats a:link { color:inherit; text-decoration:none; }
.tags a:visited { color:inherit; text-decoration:none; }
.cats a:visited { color:inherit; text-decoration:none; }
.tags a:hover { text-decoration:underline; }
.cats a:hover { text-decoration:underline; }
.highlite { background-color:yellow; }
.restrictions_edit_sysop { color:#CC0000; font-style:italic; font-weight:bold; }
.restrictions_edit_autoconfirmed { color:#FF6666; font-style:italic; }
img { font-size:72%; }
/*.settings {
border:1px solid #AAAAAA;
background-color: #EEEEEE;
padding:0 1ex 1ex 1ex;
margin:0;
margin-bottom:1ex;
}*/
</style>
<script type="text/javascript">
function setDisabled(ids, disabled) {
if (!document.params) return;
//alert("setDisabled(("+ids+"),"+disabled+")");
for (var n=0; n<ids.length; n++) {
var id= ids[n];
var e= document.params[id];
if (e) {
if (typeof e == 'array') {
for (var m=0; m<e.length; m++) {
e[m].disabled= disabled;
}
}
else e.disabled= disabled;
}
//else alert('NOT FOUND: ['+n+']='+id);
}
}
function init() {
if (!document.params) {
alert("form not found!");
return;
}
for (var n=0; n<document.params.elements.length; n++) {
var e= document.params.elements[n];
if (typeof e == 'array') {
for (var m=0; m<e.length; m++) {
if (e[m].checked) e[m].onchange();
}
}
else if (e.checked) e.onchange();
}
}
</script>
</head>
<body>
<? wsfHeader(); ?>
<div id='content'>
<h1>CatScan</h1>
<? wsfSubtitle('CatScan'); ?>
<?
$lag= wsfGetReplagHTML();
if ($lag) print "<div class='replag'>$lag</div>";
?>
<form action="CategoryIntersect.php" name="params">
<div style='position:relative; top:0; left:0; float:left; margin-left:auto; margin-right:auto;' class='querybox'>
<table class='settings'>
<tr><td>
<?= $wsgCatScanText->msg('wiki') ?>
</td><td>
<? $wikiSelector->printSelector(false); ?>
</td></tr>
<tr><td>
<b><?= $wsgCatScanText->msg('search_in_category') ?></b>
</td><td>
<input type="text" name="basecat" value="<?=escapeHtml($basecat)?>" size="48"/>
<?= $wsgCatScanText->msg('with_depth') ?> <input type="text" name="basedeep" value="<?=escapeHtml($basedeep)?>" size="2"/>
</td></tr>
<tr><td>
<?= printRadioButton('mode','cs',$mode,getOnChangeToggleJS(array('tagcat','tagdeep'))) ?>
<?= $wsgCatScanText->msg('for_pages_by_category') ?>
</td><td>
<input type="text" name="tagcat" value="<?=escapeHtml($tagcat)?>" size="48"/>
<?= $wsgCatScanText->msg('with_depth') ?> <input type="text" name="tagdeep" value="<?=escapeHtml($tagdeep)?>" size="2"/>
</td></tr>
<tr><td>
<?= printRadioButton('mode','ts',$mode,getOnChangeToggleJS(array('templates','untagged'))) ?>
<?= $wsgCatScanText->msg('for_pages_by_template') ?>
</td><td>
<input type="text" name="templates" value="<?=escapeHtml($templates)?>" size="48"/>
<?= $wsgCatScanText->msg('inverse') ?> <? printCheckbox('untagged',$untagged) ?> (<?= $wsgCatScanText->msg('untagged_only') ?>)
</td></tr>
<tr><td>
<?= printRadioButton('mode','al',$mode,getOnChangeToggleJS(array('templates'))) ?>
<?= $wsgCatScanText->msg('for_all_pages') ?>
</td><td>
<small><?= $wsgCatScanText->msg('all_pages_hint') ?></small>
</td></tr>
<tr><td>
<?= printRadioButton('mode','ss',$mode,getOnChangeToggleJS(array('size','links','stubop'))) ?>
<?= $wsgCatScanText->msg('for_stubs') ?>
</td><td>
<?= $wsgCatScanText->msg('having_less_than_x_bytes_1','<input type="text" name="size" value="'.escapeHtml($size).'" size="6"/>') ?>
<select name='stubop'>
<? printOption($wsgCatScanText->msg('and'), 'and', $stubop); ?>
<? printOption($wsgCatScanText->msg('or'), 'or', $stubop); ?>
</select>
<?= $wsgCatScanText->msg('less_than_x_links_1','<input type="text" name="links" value="'.escapeHtml($links).'" size="3"/>') ?>
(<?= $wsgCatScanText->msg('main_namespace_only') ?>)
</td></tr>
<!--<tr><td>
<?/*= printRadioButton('mode','ls',$mode,getOnChangeToggleJS(array('links')))*/ ?>
for articles with less than
</td><td>
<input type="text" name="links" value="<?=escapeHtml($links)?>" size="3"/> links (main namespace only);
</td></tr>-->
<tr><td>
<?= printRadioButton('mode','rc',$mode,getOnChangeToggleJS(array('hours','nominor','nobots','onlynew'))) ?>
<?= $wsgCatScanText->msg('for_changes_in_the_last') ?>
</td><td>
<input type="text" name="hours" value="<?=escapeHtml($hours)?>" size="3"/> <?= $wsgCatScanText->msg('hours') ?>,
<?= $wsgCatScanText->msg('hide_minor') ?> <? printCheckbox('nominor',$nominor) ?>,
<?= $wsgCatScanText->msg('hide_bots') ?> <? printCheckbox('nobots',$nobots) ?>,
<?= $wsgCatScanText->msg('only_new') ?> <? printCheckbox('onlynew',$onlynew) ?>
</td></tr>
<tr><td>
<?= printRadioButton('mode','iul',$mode,getOnChangeToggleJS(NULL)) ?>
<?= $wsgCatScanText->msg('for_all_images') ?>
</td><td>
</td></tr>
<!--
<tr><td>
<?/*= printRadioButton('mode','il',$mode,getOnChangeToggleJS(NULL))*/ ?>
for images in categories
</td><td>
</td></tr>
-->
<tr><td>
<?= printRadioButton('mode','cl',$mode,getOnChangeToggleJS(NULL)) ?>
<?= $wsgCatScanText->msg('for_all_categories') ?>
</td><td>
</td></tr>
<tr><td colspan="2" align="center">
<input type="submit" name="<?= $conf?'configure':'go' ?>" value="<?= $wsgCatScanText->msg('catscan_go') ?>"/>
<label for="format"><?= $wsgCatScanText->msg('select_format'); ?></label> <? printSelector('format', $formats, $format); ?>
<div style='top:-9ex; right:0; position:absolute;'>
<? $wsgCatScanText->printLanguageSelector($knownLanguages); ?>
<input type="submit" name="set-userlang" value="<?= $wsgCatScanText->msg('set_language') ?>"/>
<br/><? $wsgCatScanText->printTranslationLink('CatScan') ?>
</div>
</td></tr>
</table>
</div>
<? if ($terse): ?>
<input type="hidden" name="terse" value="<?= escapeHtml($terse) ?>"/>
<? endif; ?>
</form>
</div>
<script type='text/javascript'>
init();
</script>
<br style='clear:both;'>
<?
flush();
if ($basecat) {
$c= $basecat;
$w= '';
if (is_array($basecat)) {
if (sizeof($basecat)>1) $c= NULL;
else $c= $basecat[0];
}
if (!is_array($basecat) && strpos($basecat,'|')!==false) $c= NULL;
if ($c) $label= $wsgCatScanText->msg('category_as_tree_1', escapeHtml($c));
else $label= $wsgCatScanText->msg('category_tree');
if ($wikiSelector->wikiInfo) $w= $wikiSelector->appendUrlParameters($w);
if ($c) $c= '&cat='.urlencode($c);
print "<p style='font-size:90%'><a href='CategoryTree.php?$w$c'>$label</a></p>";
}
$c= 0;
if ($doquery) {
if ($basedeep && $basedeep>1 && $basecat) $basecat= getDeepCategories($basecat,$basedeep);
if ($tagdeep && $tagdeep>1 && $tagcat) $tagcat= getDeepCategories($tagcat,$tagdeep);
if ($mode=='cs' && $tagcat) {
print '<h3>'.$wsgCatScanText->msg('category_intersection_2',escapeHtml($wgRequest->getVal('basecat')),escapeHtml($wgRequest->getVal('tagcat'))).':</h3>';
$c= listArticles( $basecat, $tagcat, $mode );
}
else if ($mode=='ts' && $templates) {
print '<h3>'.$wsgCatScanText->msg($untagged?'untagged_in_category_2':'tagged_in_category_2',escapeHtml($wgRequest->getVal('basecat')),escapeHtml($wgRequest->getVal('templates'))).':</h3>';
#print '<p style="background-color:#FFFFAA; border:2px solid red; padding:1ex; margin-left:auto; margin-right:auto; width:80%; text-align:center;">
# <b>Warning:</b> there seem to be some problems with the templatelinks table currently.
# Some pages may be reported as untagged, while they are in fact contain a template. This will hopefully be fixed soon. </p>';
$c= listArticles( $basecat, $templates, $mode, $untagged );
}
else if ($mode=='ss' && ($size || $links)) {
if ($size && $links) $s= $wsgCatScanText->msg('stubs_under_4',escapeHtml($wgRequest->getVal('basecat')),escapeHtml($wgRequest->getVal('size')),$wsgCatScanText->msg($stubop),escapeHtml($wgRequest->getVal('links')));
else if ($size) $s= $wsgCatScanText->msg('stubs_by_size_under_2',escapeHtml($wgRequest->getVal('basecat')),escapeHtml($wgRequest->getVal('size')));
else if ($links) $s= $wsgCatScanText->msg('stubs_by_links_under_2',escapeHtml($wgRequest->getVal('basecat')),escapeHtml($wgRequest->getVal('links')));
print "<h3>$s:</h3>";
$c= listArticles( $basecat, array('size'=>$size, 'links'=>$links, 'stubop'=>$stubop), $mode );
}
/*else if ($mode=='ls' && $links) {
print "<h3>$under and have ".(@$more?'at least':'less than')." <i>".escapeHtml($wgRequest->getVal('links'))."</i> links</h3>";
$c= listArticles( $basecat, $links, $mode );
}*/
else if ($mode=='al') {
if ($templates) {
$s= ', '.$wsgCatScanText->msg('highliting_template',escapeHtml($wgRequest->getVal('templates')));
}
else $s= '';
print "<h3>".$wsgCatScanText->msg('articles_under_1',escapeHtml($wgRequest->getVal('basecat'))).$s.":</h3>";
#if ($templates) {
#print '<p style="background-color:#FFFFAA; border:2px solid red; padding:1ex; margin-left:auto; margin-right:auto; width:80%; text-align:center;">
# <b>Warning:</b> there seem to be some problems with the templatelinks table currently.
# Some pages may be reported as untagged, while they are in fact contain a template. This will hopefully be fixed soon. </p>';
#}
$c= listArticles( $basecat, $templates, $mode );
}
else if ($mode=='rc') {
print '<h3>'.$wsgCatScanText->msg('changes_in_2',escapeHtml($wgRequest->getVal('hours')),escapeHtml($wgRequest->getVal('basecat'))).':</h3>';
$c= listArticles( $basecat, array('hours'=>$hours, 'nominor'=>$nominor, 'nobots'=>$nobots, 'onlynew'=>$onlynew), $mode );
}
else if ($mode=='iul') {
print '<h3>'.$wsgCatScanText->msg('images_used_under_1',escapeHtml($wgRequest->getVal('basecat'))).':</h3>';
$c= listArticles( $basecat, NULL, $mode );
}
else if ($mode=='il') {
print '<h3>'.$wsgCatScanText->msg('images_under_1',escapeHtml($wgRequest->getVal('basecat'))).':</h3>';
$c= listArticles( $basecat, NULL, $mode );
}
else if ($mode=='cl') {
print '<h3>'.$wsgCatScanText->msg('categories_under_1',escapeHtml($wgRequest->getVal('basecat'))).':</h3>';
?>
<table>
<?
if (!is_array($basecat)) $basecat= array($basecat);
sort($basecat);
foreach ($basecat as $cat) {
$p= new stdClass();
@$p->page_title= $cat;
@$p->page_namespace= NS_CATEGORY;
printArticleHTML($p,$mode);
}
?>
</table>
<?
}
print "\n<p>";
if ($mode=='cl') {
print $wsgCatScanText->msg('found_categories_1',sizeof($basecat));
}
else if (!$c) {
print $wsgCatScanText->msg('no_matches');
}
else {
print $wsgCatScanText->msg('found_articles_1',$c);
}
print "\n</p>\n";
}
if ($wiki && is_object($wiki)) {
$wiki->close();
}
?>
</div>
<? wsfFooter(false); ?>
</body>
</html>CategoryIntersect.php
application/x-php, 41451 bytes (load raw)

