Index: trunk/extensions/CategoryTree/CategoryTreePage.php |
— | — | @@ -81,7 +81,7 @@ |
82 | 82 | $parents = $this->tree->renderParents( $title ); |
83 | 83 | |
84 | 84 | if ( $parents == '' ) { |
85 | | - $wgOut->addHtml( wfMsgExt( 'categorytree-nothing-found', 'parseinline' ) ); |
| 85 | + $wgOut->addHtml( wfMsgExt( 'categorytree-no-parent-categories', 'parseinline' ) ); |
86 | 86 | } else { |
87 | 87 | $wgOut->addHtml( $parents ); |
88 | 88 | } |
Index: trunk/extensions/CategoryTree/CategoryTree.i18n.php |
— | — | @@ -43,6 +43,7 @@ |
44 | 44 | 'categorytree-loading' => 'loading…', |
45 | 45 | 'categorytree-nothing-found' => 'nothing found', |
46 | 46 | 'categorytree-no-subcategories' => 'no subcategories', |
| 47 | + 'categorytree-no-parent-categories' => 'no parent categories', |
47 | 48 | 'categorytree-no-pages' => 'no pages or subcategories', |
48 | 49 | 'categorytree-not-found' => 'Category <i>$1</i> not found', |
49 | 50 | 'categorytree-error' => 'Problem loading data.', |
— | — | @@ -610,6 +611,7 @@ |
611 | 612 | 'categorytree-nothing-found' => 'Nichts gefunden', |
612 | 613 | 'categorytree-no-subcategories' => 'Keine Unterkategorien', |
613 | 614 | 'categorytree-no-pages' => 'Keine Seite oder Unterkategorien', |
| 615 | + 'categorytree-no-parent-categories' => 'Keine Oberkategorien', |
614 | 616 | 'categorytree-not-found' => "Kategorie „$1“ nicht gefunden", |
615 | 617 | 'categorytree-error' => 'Probleme beim Laden der Daten.', |
616 | 618 | 'categorytree-retry' => 'Bitte warte einen Moment und versuche es dann erneut.', |
Index: trunk/extensions/CategoryTree/CategoryTree.php |
— | — | @@ -22,6 +22,7 @@ |
23 | 23 | define('CT_MODE_CATEGORIES', 0); |
24 | 24 | define('CT_MODE_PAGES', 10); |
25 | 25 | define('CT_MODE_ALL', 20); |
| 26 | +define('CT_MODE_PARENTS', 100); |
26 | 27 | |
27 | 28 | /** |
28 | 29 | * Constants for use with the hideprefix option, |
— | — | @@ -64,6 +65,7 @@ |
65 | 66 | |
66 | 67 | $wgCategoryTreeExtPath = '/extensions/CategoryTree'; |
67 | 68 | $wgCategoryTreeVersion = '2'; #NOTE: bump this when you change the CSS or JS files! |
| 69 | +$wgCategoryTreeUseCategoryTable = version_compare( $wgVersion, "1.13", '>=' ); |
68 | 70 | |
69 | 71 | $wgCategoryTreeOmitNamespace = CT_HIDEPREFIX_CATEGORIES; |
70 | 72 | $wgCategoryTreeDefaultMode = CT_MODE_CATEGORIES; |
Index: trunk/extensions/CategoryTree/CategoryTree.js |
— | — | @@ -133,6 +133,7 @@ |
134 | 134 | |
135 | 135 | if ( options.mode == 0 ) result= categoryTreeNoSubcategoriesMsg; |
136 | 136 | else if ( options.mode == 10 ) result= categoryTreeNoPagesMsg; |
| 137 | + else if ( options.mode == 100 ) result= categoryTreeNoParentCategoriesMsg; |
137 | 138 | else result= categoryTreeNothingFoundMsg; |
138 | 139 | |
139 | 140 | result+= '</i>'; |
Index: trunk/extensions/CategoryTree/CategoryTreeFunctions.php |
— | — | @@ -31,6 +31,11 @@ |
32 | 32 | } |
33 | 33 | |
34 | 34 | $this->mOptions['mode'] = self::decodeMode( $this->mOptions['mode'] ); |
| 35 | + |
| 36 | + if ( $this->mOptions['mode'] == CT_MODE_PARENTS ) { |
| 37 | + $this->mOptions['namespaces'] = false; #namespace filter makes no sense with CT_MODE_PARENTS |
| 38 | + } |
| 39 | + |
35 | 40 | $this->mOptions['hideprefix'] = self::decodeHidePrefix( $this->mOptions['hideprefix'] ); |
36 | 41 | $this->mOptions['showcount'] = self::decodeBoolean( $this->mOptions['showcount'] ); |
37 | 42 | $this->mOptions['namespaces'] = self::decodeNamespaces( $this->mOptions['namespaces'] ); |
— | — | @@ -52,6 +57,10 @@ |
53 | 58 | return $this->mOptions[$name]; |
54 | 59 | } |
55 | 60 | |
| 61 | + function isInverse( ) { |
| 62 | + return $this->getOption('mode') == CT_MODE_PARENTS; |
| 63 | + } |
| 64 | + |
56 | 65 | static function decodeNamespaces( $nn ) { |
57 | 66 | global $wgContLang; |
58 | 67 | |
— | — | @@ -99,7 +108,8 @@ |
100 | 109 | |
101 | 110 | if ( $mode == 'all' ) $mode = CT_MODE_ALL; |
102 | 111 | else if ( $mode == 'pages' ) $mode = CT_MODE_PAGES; |
103 | | - else if ( $mode == 'categories' ) $mode = CT_MODE_CATEGORIES; |
| 112 | + else if ( $mode == 'categories' || $mode == 'sub' ) $mode = CT_MODE_CATEGORIES; |
| 113 | + else if ( $mode == 'parents' || $mode == 'super' || $mode == 'inverse' ) $mode = CT_MODE_PARENTS; |
104 | 114 | else if ( $mode == 'default' ) $mode = $wgCategoryTreeDefaultOptions['mode']; |
105 | 115 | |
106 | 116 | return (int)$mode; |
— | — | @@ -188,6 +198,7 @@ |
189 | 199 | var categoryTreeLoadingMsg = \"".Xml::escapeJsString(wfMsgNoTrans('categorytree-loading'))."\"; |
190 | 200 | var categoryTreeNothingFoundMsg = \"".Xml::escapeJsString(wfMsgNoTrans('categorytree-nothing-found'))."\"; |
191 | 201 | var categoryTreeNoSubcategoriesMsg = \"".Xml::escapeJsString(wfMsgNoTrans('categorytree-no-subcategories'))."\"; |
| 202 | + var categoryTreeNoParentCategoriesMsg = \"".Xml::escapeJsString(wfMsgNoTrans('categorytree-no-parent-categories'))."\"; |
192 | 203 | var categoryTreeNoPagesMsg = \"".Xml::escapeJsString(wfMsgNoTrans('categorytree-no-pages'))."\"; |
193 | 204 | var categoryTreeErrorMsg = \"".Xml::escapeJsString(wfMsgNoTrans('categorytree-error'))."\"; |
194 | 205 | var categoryTreeRetryMsg = \"".Xml::escapeJsString(wfMsgNoTrans('categorytree-retry'))."\"; |
— | — | @@ -379,7 +390,7 @@ |
380 | 391 | * $title must be a Title object |
381 | 392 | */ |
382 | 393 | function renderChildren( &$title, $depth=1 ) { |
383 | | - global $wgCategoryTreeMaxChildren, $wgVersion; |
| 394 | + global $wgCategoryTreeMaxChildren, $wgCategoryTreeUseCategoryTable; |
384 | 395 | |
385 | 396 | if( $title->getNamespace() != NS_CATEGORY ) { |
386 | 397 | // Non-categories can't have children. :) |
— | — | @@ -388,20 +399,30 @@ |
389 | 400 | |
390 | 401 | $dbr =& wfGetDB( DB_SLAVE ); |
391 | 402 | |
392 | | - |
| 403 | + $inverse = $this->isInverse(); |
393 | 404 | $mode = $this->getOption('mode'); |
394 | 405 | $namespaces = $this->getOption('namespaces'); |
395 | 406 | |
396 | | - #namespace filter. |
397 | | - if ( $namespaces ) { |
398 | | - #NOTE: we assume that the $namespaces array contains only integers! |
399 | | - if ( sizeof( $namespaces ) === 1 ) $nsmatch = ' AND cat.page_namespace = ' . $namespaces[0] . ' '; |
400 | | - else $nsmatch = ' AND cat.page_namespace IN ( ' . implode( ', ', $namespaces ) . ') '; |
| 407 | + if ( $inverse ) { |
| 408 | + $ctJoinCond = ' cl_to = cat.page_title AND cat.page_namespace = ' . NS_CATEGORY; |
| 409 | + $ctWhere = " cl_from = " . $title->getArticleId(); |
| 410 | + $nsmatch = ''; |
401 | 411 | } |
402 | 412 | else { |
403 | | - if ( $mode == CT_MODE_ALL ) $nsmatch = ''; |
404 | | - else if ( $mode == CT_MODE_PAGES ) $nsmatch = ' AND cat.page_namespace != ' . NS_IMAGE; |
405 | | - else $nsmatch = ' AND cat.page_namespace = ' . NS_CATEGORY; |
| 413 | + $ctJoinCond = ' cl_from = cat.page_id '; |
| 414 | + $ctWhere = " cl_to = " . $dbr->addQuotes( $title->getDBkey() ); |
| 415 | + |
| 416 | + #namespace filter. |
| 417 | + if ( $namespaces ) { |
| 418 | + #NOTE: we assume that the $namespaces array contains only integers! decodeNamepsaces makes it so. |
| 419 | + if ( sizeof( $namespaces ) === 1 ) $nsmatch = ' AND cat.page_namespace = ' . $namespaces[0] . ' '; |
| 420 | + else $nsmatch = ' AND cat.page_namespace IN ( ' . implode( ', ', $namespaces ) . ') '; |
| 421 | + } |
| 422 | + else { |
| 423 | + if ( $mode == CT_MODE_ALL ) $nsmatch = ''; |
| 424 | + else if ( $mode == CT_MODE_PAGES ) $nsmatch = ' AND cat.page_namespace != ' . NS_IMAGE; |
| 425 | + else $nsmatch = ' AND cat.page_namespace = ' . NS_CATEGORY; |
| 426 | + } |
406 | 427 | } |
407 | 428 | |
408 | 429 | #additional stuff to be used if "transaltion" by interwiki-links is desired |
— | — | @@ -410,7 +431,7 @@ |
411 | 432 | $transWhere = ''; |
412 | 433 | |
413 | 434 | # fetch member count if possible |
414 | | - $doCount = version_compare( $wgVersion, "1.12", '>' ); |
| 435 | + $doCount = !$inverse && $wgCategoryTreeUseCategoryTable; |
415 | 436 | |
416 | 437 | $countFields = ''; |
417 | 438 | $countJoin = ''; |
— | — | @@ -428,10 +449,10 @@ |
429 | 450 | $transFields |
430 | 451 | $countFields |
431 | 452 | FROM $page as cat |
432 | | - JOIN $categorylinks ON cl_from = cat.page_id |
| 453 | + JOIN $categorylinks ON $ctJoinCond |
433 | 454 | $transJoin |
434 | 455 | $countJoin |
435 | | - WHERE cl_to = " . $dbr->addQuotes( $title->getDBkey() ) . " |
| 456 | + WHERE $ctWhere |
436 | 457 | $nsmatch |
437 | 458 | "./*AND cat.page_is_redirect = 0*/" |
438 | 459 | $transWhere |
— | — | @@ -527,7 +548,11 @@ |
528 | 549 | * $title must be a Title object |
529 | 550 | */ |
530 | 551 | function renderNode( $title, $children = 0, $loadchildren = false ) { |
531 | | - if ( $title->getNamespace() == NS_CATEGORY ) $cat = Category::newFromTitle( $title ); |
| 552 | + global $wgCategoryTreeUseCategoryTable; |
| 553 | + |
| 554 | + if ( $wgCategoryTreeUseCategoryTable && $title->getNamespace() == NS_CATEGORY && !$this->isInverse() ) { |
| 555 | + $cat = Category::newFromTitle( $title ); |
| 556 | + } |
532 | 557 | else $cat = NULL; |
533 | 558 | |
534 | 559 | return $this->renderNodeInfo( $title, $cat, $children, $loadchildren ); |
— | — | @@ -658,6 +683,7 @@ |
659 | 684 | $s .= Xml::openElement( 'i', array( 'class' => 'CategoryTreeNotice' ) ); |
660 | 685 | if ( $mode == CT_MODE_CATEGORIES ) $s .= wfMsgExt( 'categorytree-no-subcategories', 'parsemag'); |
661 | 686 | else if ( $mode == CT_MODE_PAGES ) $s .= wfMsgExt( 'categorytree-no-pages', 'parsemag'); |
| 687 | + else if ( $mode == CT_MODE_PARENTS ) $s .= wfMsgExt( 'categorytree-no-parent-categories', 'parsemag'); |
662 | 688 | else $s .= wfMsgExt( 'categorytree-nothing-found', 'parsemag'); |
663 | 689 | $s .= Xml::closeElement( 'i' ); |
664 | 690 | } else { |