~ubuntu-branches/ubuntu/saucy/mediawiki-extensions/saucy

« back to all changes in this revision

Viewing changes to extensions/CategoryTree.php

  • Committer: Bazaar Package Importer
  • Author(s): Romain Beauxis
  • Date: 2010-05-04 15:13:35 UTC
  • mfrom: (0.1.1 experimental)
  • Revision ID: james.westby@ubuntu.com-20100504151335-54qeucg3ec108q28
Tags: 2.2
* Added Replaces:/Conflicts: to allow a proper upgrade.
Closes: #580066
* Fixed package descriptions.
Closes: #579667
* Patched mediawiki-extensions-fckeditor to make it work with
  php 5.3. The fix may not be perfect but at least it work.
  Not closing the bug (#579822) for now..

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
<?php
2
 
 
3
 
/**
4
 
 * Setup and Hooks for the CategoryTree extension, an AJAX based gadget
5
 
 * to display the category structure of a wiki
6
 
 *
7
 
 * @addtogroup Extensions
8
 
 * @author Daniel Kinzler, brightbyte.de
9
 
 * @copyright © 2006-2008 Daniel Kinzler and others
10
 
 * @license GNU General Public Licence 2.0 or later
11
 
 */
12
 
 
13
 
if( !defined( 'MEDIAWIKI' ) ) {
14
 
        echo( "This file is an extension to the MediaWiki software and cannot be used standalone.\n" );
15
 
        die( 1 );
16
 
}
17
 
 
18
 
/**
19
 
* Constants for use with the mode,
20
 
* defining what should be shown in the tree
21
 
*/
22
 
define('CT_MODE_CATEGORIES', 0);
23
 
define('CT_MODE_PAGES', 10);
24
 
define('CT_MODE_ALL', 20);
25
 
define('CT_MODE_PARENTS', 100);
26
 
 
27
 
/**
28
 
* Constants for use with the hideprefix option,
29
 
* defining when the namespace prefix should be hidden
30
 
*/
31
 
define('CT_HIDEPREFIX_NEVER', 0);
32
 
define('CT_HIDEPREFIX_ALWAYS', 10);
33
 
define('CT_HIDEPREFIX_CATEGORIES', 20);
34
 
define('CT_HIDEPREFIX_AUTO', 30);
35
 
 
36
 
/**
37
 
 * Options:
38
 
 *
39
 
 * $wgCategoryTreeMaxChildren - maximum number of children shown in a tree node. Default is 200
40
 
 * $wgCategoryTreeAllowTag - enable <categorytree> tag. Default is true.
41
 
 * $wgCategoryTreeDynamicTag - loads the first level of the tree in a <categorytag> dynamically.
42
 
 *                             This way, the cache does not need to be disabled. Default is false.
43
 
 * $wgCategoryTreeDisableCache - disabled the parser cache for pages with a <categorytree> tag. Default is true.
44
 
 * $wgCategoryTreeUseCache - enable HTTP cache for anon users. Default is false.
45
 
 * $wgCategoryTreeMaxDepth - maximum value for depth argument; An array that maps mode values to
46
 
 *                           the maximum depth acceptable for the depth option.
47
 
 *                           Per default, the "categories" mode has a max depth of 2,
48
 
 *                           all other modes have a max depth of 1.
49
 
 * $wgCategoryTreeDefaultOptions - default options for the <categorytree> tag.
50
 
 * $wgCategoryTreeCategoryPageOptions - options to apply on category pages.
51
 
 * $wgCategoryTreeSpecialPageOptions - options to apply on Special:CategoryTree.
52
 
 */
53
 
 
54
 
$wgCategoryTreeMaxChildren = 200;
55
 
$wgCategoryTreeAllowTag = true;
56
 
$wgCategoryTreeDisableCache = true;
57
 
$wgCategoryTreeDynamicTag = false;
58
 
$wgCategoryTreeHTTPCache = false;
59
 
#$wgCategoryTreeUnifiedView = true;
60
 
$wgCategoryTreeMaxDepth = array(CT_MODE_PAGES => 1, CT_MODE_ALL => 1, CT_MODE_CATEGORIES => 2);
61
 
 
62
 
# Set $wgCategoryTreeForceHeaders to true to force the JS and CSS headers for CategoryTree to be included on every page. 
63
 
# May be usefull for using CategoryTree from within system messages, in the sidebar, or a custom skin.
64
 
$wgCategoryTreeForceHeaders = false; 
65
 
$wgCategoryTreeSidebarRoot = NULL;
66
 
$wgCategoryTreeHijackPageCategories = false; # EXPERIMENTAL! NOT YET FOR PRODUCTION USE! Main problem is general HTML/CSS layout cruftiness.
67
 
 
68
 
$wgCategoryTreeExtPath = '/extensions/CategoryTree';
69
 
$wgCategoryTreeVersion = '5';  #NOTE: bump this when you change the CSS or JS files!
70
 
$wgCategoryTreeUseCategoryTable = version_compare( $wgVersion, "1.13", '>=' );
71
 
 
72
 
$wgCategoryTreeOmitNamespace = CT_HIDEPREFIX_CATEGORIES;
73
 
$wgCategoryTreeDefaultMode = CT_MODE_CATEGORIES;
74
 
$wgCategoryTreeDefaultOptions = array(); #Default values for most options. ADD NEW OPTIONS HERE!
75
 
$wgCategoryTreeDefaultOptions['mode'] = NULL; # will be set to $wgCategoryTreeDefaultMode in efCategoryTree(); compatibility quirk
76
 
$wgCategoryTreeDefaultOptions['hideprefix'] = NULL; # will be set to $wgCategoryTreeDefaultMode in efCategoryTree(); compatibility quirk
77
 
$wgCategoryTreeDefaultOptions['showcount'] = false;
78
 
$wgCategoryTreeDefaultOptions['namespaces'] = false; # false means "no filter"
79
 
 
80
 
$wgCategoryTreeCategoryPageMode = CT_MODE_CATEGORIES;
81
 
$wgCategoryTreeCategoryPageOptions = array(); #Options to be used for category pages
82
 
$wgCategoryTreeCategoryPageOptions['mode'] = NULL; # will be set to $wgCategoryTreeDefaultMode in efCategoryTree(); compatibility quirk
83
 
$wgCategoryTreeCategoryPageOptions['showcount'] = true;
84
 
 
85
 
$wgCategoryTreeSpecialPageOptions = array(); #Options to be used for Special:CategoryTree
86
 
$wgCategoryTreeSpecialPageOptions['showcount'] = true;
87
 
 
88
 
$wgCategoryTreeSidebarOptions = array(); #Options to be used in the sidebar (for use with $wgCategoryTreeSidebarRoot)
89
 
$wgCategoryTreeSidebarOptions['mode'] = CT_MODE_CATEGORIES;
90
 
$wgCategoryTreeSidebarOptions['hideprefix'] = CT_HIDEPREFIX_CATEGORIES;
91
 
$wgCategoryTreeSidebarOptions['showcount'] = false;
92
 
$wgCategoryTreeSidebarOptions['hideroot'] = true;
93
 
$wgCategoryTreeSidebarOptions['namespaces'] = false; 
94
 
$wgCategoryTreeSidebarOptions['depth'] = 1;
95
 
 
96
 
$wgCategoryTreePageCategoryOptions = array(); #Options to be used in the sidebar (for use with $wgCategoryTreePageCategories)
97
 
$wgCategoryTreePageCategoryOptions['mode'] = CT_MODE_PARENTS;
98
 
$wgCategoryTreePageCategoryOptions['hideprefix'] = CT_HIDEPREFIX_CATEGORIES;
99
 
$wgCategoryTreePageCategoryOptions['showcount'] = false;
100
 
$wgCategoryTreePageCategoryOptions['hideroot'] = false;
101
 
$wgCategoryTreePageCategoryOptions['namespaces'] = false;
102
 
$wgCategoryTreePageCategoryOptions['depth'] = 0;
103
 
#$wgCategoryTreePageCategoryOptions['class'] = 'CategoryTreeInlineNode';
104
 
 
105
 
$wgExtensionAliasesFiles['CategoryTree'] = dirname(__FILE__) . '/CategoryTreePage.i18n.alias.php';
106
 
 
107
 
/**
108
 
 * Register extension setup hook and credits
109
 
 */
110
 
$wgExtensionFunctions[] = 'efCategoryTree';
111
 
$wgExtensionCredits['specialpage'][] = array(
112
 
        'name' => 'CategoryTree',
113
 
        'svn-date' => '$LastChangedDate: 2009-03-09 12:54:39 +0100 (lun 09 mar 2009) $',
114
 
        'svn-revision' => '$LastChangedRevision: 48218 $',
115
 
        'author' => 'Daniel Kinzler',
116
 
        'url' => 'http://www.mediawiki.org/wiki/Extension:CategoryTree',
117
 
        'description' => 'Dynamically navigate the category structure',
118
 
        'descriptionmsg' => 'categorytree-desc',
119
 
);
120
 
$wgExtensionCredits['parserhook'][] = array(
121
 
        'name' => 'CategoryTree',
122
 
        'svn-date' => '$LastChangedDate: 2009-03-09 12:54:39 +0100 (lun 09 mar 2009) $',
123
 
        'svn-revision' => '$LastChangedRevision: 48218 $',
124
 
        'author' => 'Daniel Kinzler',
125
 
        'url' => 'http://www.mediawiki.org/wiki/Extension:CategoryTree',
126
 
        'description' => 'Dynamically navigate the category structure',
127
 
        'descriptionmsg' => 'categorytree-desc',
128
 
);
129
 
 
130
 
/**
131
 
 * Register the special page
132
 
 */
133
 
$dir = dirname(__FILE__) . '/';
134
 
$wgExtensionMessagesFiles['CategoryTree'] = $dir . 'CategoryTree.i18n.php';
135
 
$wgAutoloadClasses['CategoryTreePage'] = $dir . 'CategoryTreePage.php';
136
 
$wgAutoloadClasses['CategoryTree'] = $dir . 'CategoryTreeFunctions.php';
137
 
$wgAutoloadClasses['CategoryTreeCategoryPage'] = $dir . 'CategoryPageSubclass.php';
138
 
$wgSpecialPages['CategoryTree'] = 'CategoryTreePage';
139
 
$wgSpecialPageGroups['CategoryTree'] = 'pages';
140
 
#$wgHooks['SkinTemplateTabs'][] = 'efCategoryTreeInstallTabs';
141
 
$wgHooks['ArticleFromTitle'][] = 'efCategoryTreeArticleFromTitle';
142
 
$wgHooks['LanguageGetMagic'][] = 'efCategoryTreeGetMagic';
143
 
 
144
 
/**
145
 
 * register Ajax function
146
 
 */
147
 
$wgAjaxExportList[] = 'efCategoryTreeAjaxWrapper';
148
 
 
149
 
/**
150
 
 * Hook it up
151
 
 */
152
 
function efCategoryTree() {
153
 
        global $wgUseAjax, $wgHooks, $wgOut;
154
 
        global $wgCategoryTreeDefaultOptions, $wgCategoryTreeDefaultMode, $wgCategoryTreeOmitNamespace;
155
 
        global $wgCategoryTreeCategoryPageOptions, $wgCategoryTreeCategoryPageMode;
156
 
        global $wgCategoryTreeSidebarRoot, $wgCategoryTreeForceHeaders, $wgCategoryTreeHijackPageCategories;
157
 
 
158
 
        # Abort if AJAX is not enabled
159
 
        if ( !$wgUseAjax ) {
160
 
                wfDebug( 'efCategoryTree: $wgUseAjax is not enabled, aborting extension setup.' );
161
 
                return;
162
 
        }
163
 
 
164
 
        if ( $wgCategoryTreeSidebarRoot ) {
165
 
                $wgCategoryTreeForceHeaders = true; # needed on every page anyway
166
 
                $wgHooks['SkinTemplateOutputPageBeforeExec'][] = 'efCategoryTreeSkinTemplateOutputPageBeforeExec';
167
 
        }
168
 
 
169
 
        if ( $wgCategoryTreeHijackPageCategories ) {
170
 
                $wgCategoryTreeForceHeaders = true; # needed on almost every page anyway
171
 
                $wgHooks['OutputPageMakeCategoryLinks'][] = 'efCategoryTreeOutputPageMakeCategoryLinks';
172
 
                $wgHooks['SkinJoinCategoryLinks'][] = 'efCategoryTreeSkinJoinCategoryLinks';
173
 
        }
174
 
 
175
 
        if ( defined( 'MW_SUPPORTS_PARSERFIRSTCALLINIT' ) ) {
176
 
                $wgHooks['ParserFirstCallInit'][] = 'efCategoryTreeSetHooks';
177
 
        } else {
178
 
                efCategoryTreeSetHooks();
179
 
        }
180
 
 
181
 
        if ( !isset( $wgCategoryTreeDefaultOptions['mode'] ) || is_null( $wgCategoryTreeDefaultOptions['mode'] ) ) {
182
 
                $wgCategoryTreeDefaultOptions['mode'] = $wgCategoryTreeDefaultMode;
183
 
        }
184
 
 
185
 
        if ( !isset( $wgCategoryTreeDefaultOptions['hideprefix'] ) || is_null( $wgCategoryTreeDefaultOptions['hideprefix'] ) ) {
186
 
                $wgCategoryTreeDefaultOptions['hideprefix'] = $wgCategoryTreeOmitNamespace;
187
 
        }
188
 
 
189
 
        if ( !isset( $wgCategoryTreeCategoryPageOptions['mode'] ) || is_null( $wgCategoryTreeCategoryPageOptions['mode'] ) ) {
190
 
                $wgCategoryTreeCategoryPageOptions['mode'] = $wgCategoryTreeCategoryPageMode;
191
 
        }
192
 
 
193
 
        if ( $wgCategoryTreeForceHeaders ) {
194
 
                CategoryTree::setHeaders( $wgOut );
195
 
        }
196
 
        else {
197
 
                $wgHooks['OutputPageParserOutput'][] = 'efCategoryTreeParserOutput';
198
 
        }
199
 
}
200
 
 
201
 
function efCategoryTreeSetHooks() {
202
 
        global $wgParser, $wgCategoryTreeAllowTag;
203
 
        if ( $wgCategoryTreeAllowTag ) {
204
 
                $wgParser->setHook( 'categorytree' , 'efCategoryTreeParserHook' );
205
 
                $wgParser->setFunctionHook( 'categorytree' , 'efCategoryTreeParserFunction' );
206
 
        }
207
 
        return true;
208
 
}
209
 
 
210
 
/**
211
 
* Hook magic word
212
 
*/
213
 
function efCategoryTreeGetMagic( &$magicWords, $langCode ) {
214
 
        global $wgUseAjax, $wgCategoryTreeAllowTag;
215
 
 
216
 
        if ( $wgUseAjax && $wgCategoryTreeAllowTag ) {
217
 
                //XXX: should we allow a local alias?
218
 
                $magicWords['categorytree'] = array( 0, 'categorytree' );
219
 
        }
220
 
 
221
 
        return true;
222
 
}
223
 
 
224
 
/**
225
 
 * Entry point for Ajax, registered in $wgAjaxExportList.
226
 
 * The $enc parameter determins how the $options is decoded into a PHP array.
227
 
 * If $enc is not given, '' is asumed, which simulates the old call interface,
228
 
 * namely, only providing the mode name or number.
229
 
 * This loads CategoryTreeFunctions.php and calls CategoryTree::ajax()
230
 
 */
231
 
function efCategoryTreeAjaxWrapper( $category, $options, $enc = '' ) {
232
 
        global $wgCategoryTreeHTTPCache, $wgSquidMaxage, $wgUseSquid;
233
 
 
234
 
        if ( is_string( $options ) ) {
235
 
                $options = CategoryTree::decodeOptions( $options, $enc );
236
 
        }
237
 
 
238
 
        $depth = isset( $options['depth'] ) ? (int)$options['depth'] : 1;
239
 
 
240
 
        $ct = new CategoryTree( $options, true );
241
 
        $depth = efCategoryTreeCapDepth( $ct->getOption('mode'), $depth );
242
 
        $response = $ct->ajax( $category, $depth );
243
 
 
244
 
        if ( $wgCategoryTreeHTTPCache && $wgSquidMaxage && $wgUseSquid ) {
245
 
                $response->setCacheDuration( $wgSquidMaxage );
246
 
                $response->setVary( 'Accept-Encoding, Cookie' ); #cache for anons only
247
 
                #TODO: purge the squid cache when a category page is invalidated
248
 
        }
249
 
 
250
 
        return $response;
251
 
}
252
 
 
253
 
/**
254
 
 * Internal function to cap depth
255
 
 */
256
 
 
257
 
function efCategoryTreeCapDepth( $mode, $depth ) {
258
 
        global $wgCategoryTreeMaxDepth;
259
 
 
260
 
        if (is_numeric($depth))
261
 
                $depth = intval($depth);
262
 
        else return 1;
263
 
 
264
 
        if (is_array($wgCategoryTreeMaxDepth)) {
265
 
                $max = isset($wgCategoryTreeMaxDepth[$mode]) ? $wgCategoryTreeMaxDepth[$mode] : 1;
266
 
        } elseif (is_numeric($wgCategoryTreeMaxDepth)) {
267
 
                $max = $wgCategoryTreeMaxDepth;
268
 
        } else {
269
 
                wfDebug( 'efCategoryTreeCapDepth: $wgCategoryTreeMaxDepth is invalid.' );
270
 
                $max = 1;
271
 
        }
272
 
 
273
 
        return min($depth, $max);
274
 
}
275
 
 
276
 
/**
277
 
 * Entry point for the {{#categorytree}} tag parser function.
278
 
 * This is a wrapper around efCategoryTreeParserHook
279
 
 */
280
 
function efCategoryTreeParserFunction( &$parser ) {
281
 
        $params = func_get_args();
282
 
        array_shift( $params ); //first is &$parser, strip it
283
 
 
284
 
        //first user-supplied parameter must be category name
285
 
        if ( !$params ) return ''; //no category specified, return nothing
286
 
        $cat = array_shift( $params );
287
 
 
288
 
        //build associative arguments from flat parameter list
289
 
        $argv = array();
290
 
        foreach ( $params as $p ) {
291
 
                if ( preg_match('/^\s*(\S.*?)\s*=\s*(.*?)\s*$/', $p, $m) ) {
292
 
                        $k = $m[1];
293
 
                        $v = preg_replace('/^"\s*(.*?)\s*"$/', '$1', $m[2]); //strip any quotes enclusing the value
294
 
                }
295
 
                else {
296
 
                        $k = trim($p);
297
 
                        $v = true;
298
 
                }
299
 
 
300
 
                $argv[$k] = $v;
301
 
        }
302
 
 
303
 
        //now handle just like a <categorytree> tag
304
 
        $html = efCategoryTreeParserHook( $cat, $argv, $parser );
305
 
        return array( $html, 'noparse' => true, 'isHTML' => true );
306
 
}
307
 
 
308
 
/**
309
 
 * Hook implementation for injecting a category tree into the sidebar.
310
 
 * Registered automatically if $wgCategoryTreeSidebarRoot is set to a category name.
311
 
 */
312
 
function efCategoryTreeSkinTemplateOutputPageBeforeExec( &$skin, &$tpl ) {
313
 
        global $wgCategoryTreeSidebarRoot, $wgCategoryTreeSidebarOptions;
314
 
        
315
 
        $html = efCategoryTreeParserHook( $wgCategoryTreeSidebarRoot, $wgCategoryTreeSidebarOptions );
316
 
        if ( $html ) $tpl->data['sidebar']['categorytree-portlet'] = $html; //requires MW 1.13, r36917
317
 
 
318
 
        return true;
319
 
}
320
 
 
321
 
 
322
 
/**
323
 
 * Entry point for the <categorytree> tag parser hook.
324
 
 * This loads CategoryTreeFunctions.php and calls CategoryTree::getTag()
325
 
 */
326
 
function efCategoryTreeParserHook( $cat, $argv, $parser = NULL, $allowMissing = false ) {
327
 
        global $wgOut;
328
 
 
329
 
        if ( $parser ) {
330
 
                $parser->mOutput->mCategoryTreeTag = true; # flag for use by efCategoryTreeParserOutput
331
 
        }
332
 
        else {
333
 
                CategoryTree::setHeaders( $wgOut );
334
 
        }
335
 
 
336
 
        $ct = new CategoryTree( $argv );
337
 
 
338
 
        $attr = Sanitizer::validateTagAttributes( $argv, 'div' );
339
 
 
340
 
        $hideroot = isset( $argv[ 'hideroot' ] ) ? CategoryTree::decodeBoolean( $argv[ 'hideroot' ] ) : null;
341
 
        $onlyroot = isset( $argv[ 'onlyroot' ] ) ? CategoryTree::decodeBoolean( $argv[ 'onlyroot' ] ) : null;
342
 
        $depthArg = isset( $argv[ 'depth' ] ) ? (int)$argv[ 'depth' ] : null;
343
 
 
344
 
        $depth = efCategoryTreeCapDepth( $ct->getOption( 'mode' ), $depthArg );
345
 
        if ( $onlyroot ) $depth = 0;
346
 
 
347
 
        return $ct->getTag( $parser, $cat, $hideroot, $attr, $depth, $allowMissing );
348
 
}
349
 
 
350
 
/**
351
 
* Hook callback that injects messages and things into the <head> tag
352
 
* Does nothing if $parserOutput->mCategoryTreeTag is not set
353
 
*/
354
 
function efCategoryTreeParserOutput( &$outputPage, $parserOutput )  {
355
 
        if ( !empty( $parserOutput->mCategoryTreeTag ) ) {
356
 
                CategoryTree::setHeaders( $outputPage );
357
 
        }
358
 
        return true;
359
 
}
360
 
 
361
 
/**
362
 
 * ArticleFromTitle hook, override category page handling
363
 
 */
364
 
function efCategoryTreeArticleFromTitle( &$title, &$article ) {
365
 
        if ( $title->getNamespace() == NS_CATEGORY ) {
366
 
                $article = new CategoryTreeCategoryPage( $title );
367
 
        }
368
 
        return true;
369
 
}
370
 
 
371
 
/**
372
 
 * OutputPageMakeCategoryLinks hook, override category links
373
 
 */
374
 
function efCategoryTreeOutputPageMakeCategoryLinks( &$out, &$categories, &$links ) {
375
 
        global $wgContLang, $wgCategoryTreePageCategoryOptions;
376
 
 
377
 
        $ct = new CategoryTree( $wgCategoryTreePageCategoryOptions );
378
 
 
379
 
        foreach ( $categories as $category => $type ) {
380
 
                $links[$type][] = efCategoryTreeParserHook( $category, $wgCategoryTreePageCategoryOptions, NULL, true );
381
 
        }
382
 
 
383
 
        return false;
384
 
}
385
 
 
386
 
 
387
 
function efCategoryTreeSkinJoinCategoryLinks( &$skin, &$links, &$result ) {
388
 
        $embed = '<div class="CategoryTreePretendInlineMSIE CategoryTreeCategoryBarItem">';
389
 
        $pop = '</div>';
390
 
        $sep = ' ';
391
 
 
392
 
#       $result = '<div class="CategoryTreeCatBarWrapper" style="border:1px solid blue">' . $embed . implode ( "{$pop} {$sep} {$embed}" , $links ) . $pop . '</div>';
393
 
        $result = $embed . implode ( "{$pop} {$sep} {$embed}" , $links ) . $pop;
394
 
 
395
 
        return false;
396
 
}
 
 
b'\\ No newline at end of file'