<?php
/*
CategoryTree shows the category structure of a MediaWiki
as a dynamic tree.
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( "WikiSelector.php" );
require_once( "WikiSenseLocalizer.php" );
function printSection($cat, $name, $node, $stub, $articles = false) {
global $wsgCatTreeText;
if ($stub) {
$js= "javascript:expandNode('".addslashes($cat)."','$node');";
$txt= "+";
}
else {
$js= "javascript:collapseNode('".addslashes($cat)."','$node');";
$txt= "–";
}
global $wikiInfo, $sectionLoadURL, $terse, $terseTarget;
$label= escapeHtml(str_replace('_',' ',$cat));
if ($name) {
$name= str_replace(' ','_',$name);
$name= preg_replace('/^.*?:/','',$name); #ugly hack to strip leading "Category:"
}
if ($name && $name!=$cat) $label.= ' <i class="translation">['.escapeHtml(str_replace('_',' ',$name)).']</i>';
$wikiLink= NULL;
if ($wikiInfo && $wikiInfo->baseURL) {
$wikiLink= $wikiInfo->baseURL . '?title=Category:' . urlencode($cat);
}
$n= NULL;
?>
<div class='section' id='<?="section-$node"?>'>
<div class='sectionhead'>
[<a href="<?=$js?>" id='<?="link-$node"?>' title='load' <?= $stub ? "" : "class='loaded'" ?>><?=$txt?></a>]
<? if ($terse): ?>
<span class='label'>
<a href='<?=$wikiLink?>' <?= $terseTarget ?>><?=$label?></a>
</span>
<span class='links'>
<a href="<?="$sectionLoadURL&cat=".urlencode($cat)?>" target='_self'>^</a>
</span>
<? else: ?>
<span class='label'>
<?=$label?>
</span>
<span class='links'>
[<a href='<?=$wikiLink?>'><?=escapeHtml($wikiInfo->family)?></a>]
[<a href="<?="$sectionLoadURL&cat=".urlencode($cat)?>"><?= $wsgCatTreeText->msg('open_link') ?></a>]
</span>
<? endif; ?>
</div>
<div class='content' id='<?="content-$node"?>' style='<?= $stub ? "display:none" : "display:block" ?>'>
<? if (!$stub) $n= printSectionChildren($cat, $node, $articles); ?>
</div>
</div>
<?
return $n;
}
function printArticle($namespace, $title, $name, $tags= NULL) {
global $wikiInfo, $sectionLoadURL, $terse, $terseTarget, $filterMode;
global $wgCanonicalNamespaceNames;
$label= escapeHtml(str_replace('_',' ',$title));
if ($name) $name= str_replace(' ','_',$name);
if ($name && $name!=$title) $label.= ' <i>['.escapeHtml(str_replace('_',' ',$name)).']</i>';
$wikiLink= NULL;
if ($wikiInfo && $wikiInfo->baseURL) {
if ($namespace) {
$ns= @$wgCanonicalNamespaceNames[$namespace];
if (!$ns) $ns= getCustomNsText($wikiInfo->domain, $namespace);
if (!$ns) $ns= $namespace;
$title= "$ns:$title";
$label= escapeHtml(str_replace('_',' ',$ns)).':'.$label;
}
$wikiLink= $wikiInfo->baseURL . '?title=' . urlencode($title);
}
$n= NULL;
$class= 'dummy';
if ($filterMode == 'h' && $tags) $class= 'highlite';
?>
<div class='leaf'>
<span class='<?= $class ?>'>
<? if ($terse): ?>
<span class='label'>
<a href='<?=$wikiLink?>' <?= $terseTarget ?>><?=$label?></a>
</span>
<? else: ?>
<span class='label'>
<?=$label?>
</span>
<span class='links'>
[<a href='<?=$wikiLink?>'><?=escapeHtml($wikiInfo->family)?></a>]
</span>
<? endif; ?>
<? if ($tags): ?>
<span class='tags'>
(<?= escapeHtml($tags); ?>)
</span>
<? endif; ?>
</span>
</div>
<?
return $n;
}
function printParents( $cat, $decorate = false ) {
$parents= getCategories( $cat );
$ptext= '';
global $sectionLoadURL;
if ( $parents ) {
$first= true;
foreach ($parents as $p) {
if ($first) $first= false;
else if (!$decorate) $ptext.= ", ";
$u= "$sectionLoadURL&cat=".urlencode($p);
if ($decorate) $ptext.= "^";
$ptext.= "<a href='$u' target='_self' class='parent'>".escapeHtml(str_replace('_',' ',$p))."</a>";
if ($decorate) $ptext.= "<br/>";
}
$ptext= " $ptext";
}
print $ptext;
}
function printSectionChildren($cat, $node, $articles= false) {
$cats= getSubcategories($cat,$articles);
$n= 0;
foreach ($cats as $c) {
$n+= 1;
if ($c['page_namespace']==NS_CATEGORY) printSection($c['page_title'],@$c['trans_name'],"$node.$n",true,$articles);
else printArticle($c['page_namespace'],$c['page_title'],@$c['trans_name'],@$c['tags']);
}
return $n;
}
function getSubcategories( $cat, $articles= false ) {
global $db;
global $transFields, $transJoin, $transWhere;
if ($cat==NULL || $cat=='*') {
$sql= "SELECT cat.page_namespace, cat.page_title $transFields
FROM page as cat
LEFT JOIN categorylinks as c ON c.cl_from = cat.page_id
JOIN categorylinks as m ON m.cl_to = cat.page_title
JOIN page as p ON m.cl_from = p.page_id
$transJoin
WHERE cat.page_namespace = ".NS_CATEGORY."
AND cat.page_is_redirect = 0
AND c.cl_from IS NULL
AND p.page_namespace = ".NS_CATEGORY."
$transWhere
GROUP BY cat.page_id
ORDER BY cat.page_title";
}
/*else if ($articles && $filterMode && $filterCats) {
$fc= preg_split('! *[;/\|] *!',$filterCats);
$tags= '';
foreach ($fc as $tag) {
if ($tags) $tags.= ',';
$tags.= $db->addQuotes(wsfDBTitle($tag));
}
if ( $filterMode == 'h' ) { #highlite
$filterHaving= '';
}
else if ( $filterMode == 'w' ) { #with
$filterHaving= 'HAVING tags IS NOT NULL';
}
else if ( $filterMode == 'o' ) { #without
$filterHaving= 'HAVING tags IS NULL';
}
$sql= "SELECT page_namespace, page_title, '<cat>' as tags
FROM page
JOIN categorylinks ON cl_from = page_id
WHERE cl_to = " . $db->addQuotes($cat) . "
AND page_namespace = ".NS_CATEGORY."
AND page_is_redirect = 0
UNION
SELECT page_namespace, page_title, group_concat( if (t.cl_to in ($tags), 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 = " . $db->addQuotes($cat) . "
AND page_namespace = ".NS_MAIN."
GROUP BY page_id
$filterHaving
ORDER BY page_namespace DESC, page_title";
}*/
else {
#TODO: more flexible filter!
$nsmatch= $articles ? " AND cat.page_namespace != " . NS_IMAGE : " AND cat.page_namespace = " . NS_CATEGORY;
$sql= "SELECT cat.page_namespace, cat.page_title $transFields
FROM page as cat
JOIN categorylinks ON cl_from = cat.page_id
$transJoin
WHERE cl_to = " . $db->addQuotes($cat) . "
$nsmatch
AND cat.page_is_redirect = 0
$transWhere
ORDER BY cat.page_namespace DESC, cat.page_title";
}
#print "*** $sql ***";
$res= $db->query($sql, 'getSubcategories');
$cats= array();
while ($row= $db->fetchRow($res)) {
$cats[]= wsfStripIntKeys($row);
}
$db->freeResult($res);
return $cats;
}
function getCategories( $page, $ns = NS_CATEGORY ) {
global $db;
global $transFields, $transJoin, $transWhere;
$sql= "SELECT cl_to as title $transFields
FROM page as cat
JOIN categorylinks ON cl_from = cat.page_id
$transJoin
WHERE cat.page_title = " . $db->addQuotes($page) . "
AND cat.page_namespace = " . NS_CATEGORY . "
$transWhere
ORDER BY title";
$res= $db->query($sql, 'getCategories');
$cats= array();
while ($row= $db->fetchRow($res)) {
$cats[]= $row['title'];
}
$db->freeResult($res);
return $cats;
}
$knownLanguages= array('ca', 'cs', 'da', 'de', 'en', 'es', 'fr', 'hr', 'hu', 'it', 'nl', 'no', 'pl', 'pt', 'ro', 'ru', 'sk', 'sq', 'sv', 'th', 'tr', 'vi', 'zh', 'zh-cn', 'zh-yue');
$wsgCatTreeText=& WikiSenseLocalizer::initialize('CategoryTree', $knownLanguages, $wgRequest->getVal('set-userlang'));
$wikiSelector= new WikiSelector();
$cat= $wgRequest->getVal('cat');
$node= $wgRequest->getVal('node');
$terse= $wgRequest->getVal('terse');
$conf= $wgRequest->getVal('conf');
$art= $wgRequest->getVal('art');
$filterCats= $wgRequest->getVal('fc');
$viewMode= $wgRequest->getVal('m','c');
if ($art) $viewMode= 'a';
$filterMode= false;
if ($viewMode == 'c') {
$art= false;
}
else {
$art= 'on';
if (!$filterCats) $viewMode= 'a';
if ($viewMode != 'a') {
$filterMode= $viewMode;
}
}
if (!$cat && $wikiSelector->wikiInfo) {
$cat= $wikiSelector->wikiInfo->root_category;
}
if ($cat) $cat= wsfDBTitle($cat);
$paramURL= $_SERVER["PHP_SELF"].'?';
$paramURL= $wikiSelector->appendUrlParameters($paramURL);
addURLParam($paramURL,'m',$viewMode);
addURLParam($paramURL,'fc',$filterCats);
addURLParam($paramURL,'art',$art);
addURLParam($paramURL,'userlang',$wsgUserLang);
$sectionLoadURL= $paramURL;
addURLParam($sectionLoadURL,'terse',$terse);
$db= NULL;
if ($cat) $cat= trim($cat);
if ( $cat && $wikiSelector->domain ) {
$wikiInfo= getWikiInfoFromDomain($wikiSelector->domain);
if ($wikiInfo) $db= openConnection($wikiInfo->dbURL);
/*
if ($db && $wsgUserLang && ($transTable= @$wsgLanguageLinkTables[$wikiSelector->domain])) {
if (strpos($transTable,'.')===false && $wsgAuxWikiDB) {
$transDB= $wsgAuxWikiDB;
if ($idx=strrpos($transDB,'/')) $transDB= substr($transDB,$idx+1);
$transTable= $transDB.'.'.$transTable;
}
$transFields= ', LAN.to_title as trans_name ';
$transJoin= ' LEFT JOIN '.$transTable.' AS LAN ON cat.page_id = LAN.page_id AND LAN.to_lang = '.$db->addQuotes($wsgUserLang);
$transWhere= '';
}
*/
if ($db && $wsgUserLang) {
$transFields= ', LAN.ll_title as trans_name ';
$transJoin= ' LEFT JOIN langlinks AS LAN ON cat.page_id = LAN.ll_from AND LAN.ll_lang = '.$db->addQuotes($wsgUserLang);
$transWhere= '';
}
else {
$transFields= '';
$transJoin= '';
$transWhere= '';
}
}
$terseTarget= NULL;
if ($terse) {
if ($wsgBrowser['msie']) $terseTarget= '_main';
else if ($wsgBrowser['opera']) $terseTarget= '_content';
else if ($wsgBrowser['mozilla']) $terseTarget= '_content';
else if ($wsgBrowser['khtml']) $terseTarget= '_content';
if ($terseTarget) $terseTarget= " target='$terseTarget'";
}
header("Content-Type: text/html; charset=utf-8");
if ($cat && $node) {
$n= printSectionChildren($cat,$node,$art);
if (!$n) {
if ($art) {
if ($filterMode=='w' || $filterMode=='o' ) print "<i class='empty'>no matching articles or subcategories.</i>";
else print "<i class='empty'>".$wsgCatTreeText->msg('no_articles_or_subcat')."</i>";
}
else print "<i class='empty'>".$wsgCatTreeText->msg('no_subcat')."</i>";
}
$db->close();
exit;
}
?>
<!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>Category Tree</title>
<?
if ($db || $cat || $conf || $terse) print '<meta name="robots" content="noindex, nofollow"/>';
else print '<meta name="robots" content="nofollow"/>';
?>
<? if (!$terse): ?>
<link rel="stylesheet" href="wikisense.css" type="text/css">
<? endif; ?>
<style type='text/css'>
<? if ($terse): ?>
body { font-family: sans-serif; font-size:80%; background-color:#f9f9f9; padding:0.5ex; margin:0; }
.p { margin:0; padding-top:0; padding-bottom:0.3ex; }
.h3 { margin:0; padding-top:0.3ex; padding-bottom:0.6ex; }
.sectionhead { font-weight:normal; white-space:nowrap; padding-top: 0.5em; }
.parent { font-weight:normal; font-style:italic; }
.leaf { font-weight:normal; white-space:nowrap; margin-left:3ex; padding-top: 0.5em; }
.settings { font-size:80%; }
.settings input[type=text] { width:24ex; font-size:inherit; }
.settings select { font-size:inherit; }
.links { font-weight:normal; font-size:80%; font-weight:bold; }
<? else: ?>
body { font-family: sans-serif; font-size:14px; }
.sectionhead { font-weight:bold; white-space:nowrap; }
.parent { font-weight:bold; font-style:italic; }
.leaf { font-weight:normal; white-space:nowrap; margin-left:3ex; }
.settings input[type=text] { }
.links { font-weight:normal; font-size:80%; }
<? endif ?>
.error { font-weight:bold; color:red; }
.parents { font-size:95%; }
.tree { font-size:95%; }
.loaded { color:black; text-decoration: none; }
.content { margin-left:2ex; }
.tags { font-weight:normal; font-style:italic; font-size:80%; background-color:yellow; }
.highlite { background-color:yellow; }
.translation { font-weight:normal; font-style:italic; }
.settings {
border:1px solid #AAAAAA;
background-color: #EEEEEE;
padding:0 1ex 1ex 1ex;
margin:0;
margin-bottom:1ex;
}
</style>
<script type="text/javascript" src="CategoryTree.js"></script>
<script type="text/javascript">
<!--
var sectionLoadURL= "<?=str_replace('&','&',$sectionLoadURL)?>";
//-->
</script>
<script type="text/javascript">
<!--
function install_sidebar(lnk, name, url) {
if (typeof window.external == "object") {
window.external.AddFavorite('javascript:void(_search=open(\''+url+'\',\'_search\'))', name);
}
else if ((typeof window.sidebar == "object") && (typeof window.sidebar.addPanel == "function")) {
window.sidebar.addPanel (name,url,"");
}
else if ( window.opera ) {
lnk.href= url;
lnk.rel= "sidebar";
lnk.title= name;
//document.write("<a href=\"" + url + "\" title=\"" + name + "\" rel=\"sidebar\">" + name + "</a>");
}
else {
alert ("Your browser is not supported. Please try to create the sidebar manually.");
}
}
//-->
</script>
</head>
<body>
<? if (!$terse): ?>
<? wsfHeader(); ?>
<div id='content' class='centerbox'>
<? endif; ?>
<div style='margin:0; padding:0;'>
<form action="CategoryTree.php">
<?
$scanURL= 'CategoryIntersect.php?';
$scanURL= $wikiSelector->appendUrlParameters($scanURL);
addURLParam($scanURL,'basecat',$cat);
?>
<? if (!$terse || $conf): ?>
<? if (!$terse): ?>
<h2>Category Tree</h2>
<? wsfSubtitle( 'CategoryTree' ) ?>
<p style='font-size:80%;'><?= $wsgCatTreeText->msg('top_note') ?>
</p>
<? endif; ?>
<div style='position:relative;'>
<table class='settings' style="margin-left:auto; margin-right:auto;">
<tr><td>
<?= $wsgCatTreeText->msg('wiki') ?>:
</td><td>
<? $wikiSelector->printSelector(false); ?>
</td></tr>
<tr><td>
<?= $wsgCatTreeText->msg('category') ?>:
</td><td>
<input type="text" name="cat" size="48" value="<?=escapeHtml($cat)?>"/>
</td></tr>
<tr><td><?= $wsgCatTreeText->msg('filter') ?>:
</td><td>
<select name='m'>
<? printOption($wsgCatTreeText->msg('filter_categories'), 'c', $viewMode); ?>
<? printOption($wsgCatTreeText->msg('filter_articles'), 'a', $viewMode); ?>
<!-- <? #printOption('highlite tagged articles', 'h', $viewMode); ?>
<? #printOption('show tagged articles', 'w', $viewMode); ?>
<? #printOption('show untagged articles', 'o', $viewMode); ?> -->
</select>
</td></tr>
<!--
<tr><td>
Tags:
</td><td>
<input type="text" name="fc" value="<?=escapeHtml($filterCats)?>"/>
</td></tr>
-->
<tr><td colspan="2" align="center">
<input type="submit" name="<?= $conf?'configure':'go' ?>" value="<?= $wsgCatTreeText->msg('go_load') ?>"/>
<div style='top:-16ex; right:0; position:absolute; text-align:left;'>
<? $wsgCatTreeText->printLanguageSelector($knownLanguages); ?>
<input type="submit" name="set-userlang" value="<?= $wsgCatTreeText->msg('set_language') ?>"/>
<br/><? $wsgCatTreeText->printTranslationLink('CategoryTree') ?>
<?
$lag= wsfGetReplagHTML();
if ($lag) print "<div class='replag'>$lag</div>";
?>
</div>
</td></tr>
</table>
</div>
<p style="background-color:yellow; padding:1ex;">
This page is <b>deprecated!</b> CategoryTree is now integrated directly into all Wikimedia projects,
just look at any category page. Category trees can also be integrated directly into wiki pages, see
<a href="http://meta.wikimedia.org/wiki/CategoryTree_extension">meta:CategoryTree_extension</a> for details.
CategoryTree is also available for other wikis as a MediaWiki extension - see the link above for instructions.
</p>
<input type="hidden" name="terse" value="<?= escapeHtml($terse) ?>"/>
<p><a href='<?=$scanURL?>' <?= $terseTarget ?>><?= $wsgCatTreeText->msg('scan_category_1',escapeHtml($cat))?></a></p>
<? else: ?>
<?
$fullURL= $paramURL;
addURLParam($fullURL,'cat',$cat);
$confURL= $paramURL;
addURLParam($confURL,'cat',$cat);
addURLParam($confURL,'conf','on');
addURLParam($confURL,'terse',$terse);
?>
<table style='width:100%; margin:0; padding:0;'>
<tr>
<td style='width:50%; font-size:90%; text-align:left; vertical-align:top;'>
<b><?= $wikiInfo ? escapeHtml($wikiInfo->domain) : ''; ?></b>
<!-- <br/>
<i><a href='<?=$confURL?>' target='_self'>configure</a></i> -->
</td>
<td style='width:50%; font-size:90%; text-align:right; vertical-align:top;'>
<a href='<?=$fullURL?>' <?= $terseTarget ?>><?= $wsgCatTreeText->msg('full_link')?></a> >>
</td>
</tr>
</table>
<p style='margin:0; padding:1ex 0 0 0; font-size:80%;'>
<input type="text" size="16" name="cat" style='font-size:100%;' value="<?=escapeHtml($cat)?>"/> <input type="submit" style='font-size:100%;' value="<?= $wsgCatTreeText->msg('go_load')?>"/>
<br/>
<?
$artURL= $_SERVER["PHP_SELF"].'?';
$artURL= $wikiSelector->appendUrlParameters($artURL);
addURLParam($artURL,'cat',$cat);
addURLParam($artURL,'art',$art?'':'on');
addURLParam($artURL,'terse',$terse);
if ($art) print "<a href='$artURL' target='_self'>".$wsgCatTreeText->msg('hide_articles_link')."</a>";
else print "<a href='$artURL' target='_self'>".$wsgCatTreeText->msg('show_articles_link')."</a>";
?>
|
<a href='<?=$scanURL?>' <?= $terseTarget ?>><?= $wsgCatTreeText->msg('scan_category_link') ?></i></a>
</p>
<input type="hidden" name="terse" value="on"/>
<? $wikiSelector->printHiddenFields(false); ?>
<input type="hidden" name="fc" value="<?= escapeHtml($filterCats) ?>"/>
<input type="hidden" name="m" value="<?= escapeHtml($viewMode) ?>"/>
<? endif; ?>
</form>
</div>
<?
$n= 0;
if ($cat && $db && !$conf) {
$barURL= $sectionLoadURL;
addURLParam($barURL,'cat',$cat);
addURLParam($barURL,'terse','on');
$barURL= "http://".$_SERVER["SERVER_NAME"].$barURL;
$ttl= "$cat ({$wikiSelector->domain})";
?>
<div>
<? if (!$terse): ?>
<p style='font-size:90%; font-style:italic;'><?= $wsgCatTreeText->msg('sidebar') ?>:
[<a href="<?= $barURL?>"><?= $wsgCatTreeText->msg('view_link') ?></a>],
[<a href="<?= $barURL ?>" title='<?= $ttl?>' rel="sidebar"><?= $wsgCatTreeText->msg('install_link') ?> (Opera, Firefox)</a>]
[<a href="javascript:install_sidebar(this,'<?= $ttl?>','<?= $barURL?>')"><?= $wsgCatTreeText->msg('install_link') ?> (IE, Mozilla, etc)</a>]
</p>
<h3><?= $wsgCatTreeText->msg('category') ?>: <?=escapeHtml(str_replace('_',' ',$cat))?></h3>
<p class='parents'>
<?= $wsgCatTreeText->msg('parent_categories') ?>: <? printParents($cat); ?>
</p>
<? else: ?>
<p class='parents' style='margin:0; padding:0; padding-bottom:0.5ex;'>
<? printParents($cat,true); ?>
</p>
<? endif; ?>
</div>
<div class='tree'>
<?
#FIXME: get translation for root cat - check that root cat exists.
$n= printSection($cat,NULL,'r',false,$art);
if (!$n) {
print "<i>".$wsgCatTreeText->msg('error_nothing_found')."</i>";
}
?>
</div>
<?
}
if ($db) {
$db->close();
}
?>
<? if (!$terse): ?>
</div>
<? wsfFooter(false); ?>
<? endif; ?>
</body>
</html>CategoryTree.php
application/x-php, 23143 bytes (load raw)

