* (6943) Added PAGESINCATEGORY: magic word
authorBrion Vibber <brion@users.mediawiki.org>
Mon, 7 Apr 2008 22:11:31 +0000 (22:11 +0000)
committerBrion Vibber <brion@users.mediawiki.org>
Mon, 7 Apr 2008 22:11:31 +0000 (22:11 +0000)
Patch by Mr.Z-man, https://bugzilla.wikimedia.org/attachment.cgi?id=4793
Moves some of the 'expensive parser function' tracking to core.

RELEASE-NOTES
includes/CoreParserFunctions.php
includes/DefaultSettings.php
includes/MagicWord.php
includes/Parser.php
languages/messages/MessagesEn.php

index 642172a..7a9a306 100644 (file)
@@ -65,6 +65,8 @@ it from source control: http://www.mediawiki.org/wiki/Download_from_SVN
 * Redesign of Special:Userrights
 * Make rev_deleted log entries more intelligible.
 * Logs are grouped under date headings similar to enhanced changes list
+* (6943) Added PAGESINCATEGORY: magic word
+
 
 === Bug fixes in 1.13 ===
 
index 58caf51..fa7ad54 100644 (file)
@@ -41,6 +41,7 @@ class CoreParserFunctions {
                $parser->setFunctionHook( 'special',          array( __CLASS__, 'special'          ) );
                $parser->setFunctionHook( 'defaultsort',      array( __CLASS__, 'defaultsort'      ), SFH_NO_HASH );
                $parser->setFunctionHook( 'filepath',         array( __CLASS__, 'filepath'         ), SFH_NO_HASH );
+               $parser->setFunctionHook( 'pagesincategory',  array( __CLASS__, 'pagesincategory'  ), SFH_NO_HASH );
                $parser->setFunctionHook( 'tag',              array( __CLASS__, 'tagObj'           ), SFH_OBJECT_ARGS );
 
                if ( $wgAllowDisplayTitle ) {
@@ -214,6 +215,23 @@ class CoreParserFunctions {
        static function pagesinnamespace( $parser, $namespace = 0, $raw = null ) {
                return self::formatRaw( SiteStats::pagesInNs( intval( $namespace ) ), $raw );
        }
+       
+       static function pagesincategory( $parser, $category = '', $raw = null ) {
+               global $wgExpensiveParserFunctionLimit;
+               if ($category == '') {
+                       return 0;
+               }
+               $parser->mExpensiveFunctionCount++;
+               if ($parser->mExpensiveFunctionCount <= $wgExpensiveParserFunctionLimit) {
+                       $category = Category::newFromName($category);
+                       $count = $category->getPageCount();
+                       if ( !$count ) {
+                               $count = 0;
+                       }
+                       return self::formatRaw( $count, $raw );
+               }
+               return 0;
+       }
 
        static function language( $parser, $arg = '' ) {
                global $wgContLang;
index f8a9b5c..26a0752 100644 (file)
@@ -3011,3 +3011,9 @@ $wgPagePropLinkInvalidations = array(
  * Special:Whatlinkshere/RedirectDestination
  */
 $wgMaxRedirectLinksRetrieved = 500;
+
+/**
+* Maximum number of calls to expensive parser functions
+* such as PAGESINCATEGORY.
+*/
+$wgExpensiveParserFunctionLimit = 100;
index 817683a..7c027d4 100644 (file)
@@ -102,6 +102,7 @@ class MagicWord {
                'pagesinnamespace',
                'numberofadmins',
                'defaultsort',
+               'pagesincategory',
        );
        
        /* Array of caching hints for ParserCache */
index afda767..d19f9db 100644 (file)
@@ -102,6 +102,7 @@ class Parser
        var $mIncludeSizes, $mPPNodeCount, $mDefaultSort;
        var $mTplExpandCache; // empty-frame expansion cache
        var $mTplRedirCache, $mTplDomCache, $mHeadings, $mDoubleUnderscores;
+       var $mExpensiveFunctionCount; // number of expensive parser function calls
 
        # Temporary
        # These are variables reset at least once per parse regardless of $clearState
@@ -217,6 +218,7 @@ class Parser
                $this->mDefaultSort = false;
                $this->mHeadings = array();
                $this->mDoubleUnderscores = array();
+               $this->mExpensiveFunctionCount = 0;
 
                # Fix cloning
                if ( isset( $this->mPreprocessor ) && $this->mPreprocessor->parser !== $this ) {
@@ -390,17 +392,31 @@ class Parser
                                array_values( $tidyregs ),
                                $text );
                }
+               global $wgExpensiveParserFunctionLimit;
+               if ( $this->mExpensiveFunctionCount > $wgExpensiveParserFunctionLimit ) {
+                       if ( is_callable( array( $this->mOutput, 'addWarning' ) ) ) {
+                               $warning = wfMsg( 'expensive-parserfunction-warning', $this->mExpensiveFunctionCount, $wgExpensiveParserFunctionLimit );
+                               $this->mOutput->addWarning( $warning );
+                               $cat = Title::makeTitleSafe( NS_CATEGORY, wfMsgForContent( 'expensive-parserfunction-category' ) );
+                               if ( $cat ) {
+                                       $this->mOutput->addCategory( $cat->getDBkey(), $this->getDefaultSort() );
+                               }
+                       }
+               }
 
                wfRunHooks( 'ParserAfterTidy', array( &$this, &$text ) );
 
                # Information on include size limits, for the benefit of users who try to skirt them
                if ( $this->mOptions->getEnableLimitReport() ) {
+                       global $wgExpensiveParserFunctionLimit;
                        $max = $this->mOptions->getMaxIncludeSize();
+                       $PFreport = "Expensive parser function count: {$this->mExpensiveFunctionCount}/$wgExpensiveParserFunctionLimit\n";
                        $limitReport = 
                                "NewPP limit report\n" . 
                                "Preprocessor node count: {$this->mPPNodeCount}/{$this->mOptions->mMaxPPNodeCount}\n" .
                                "Post-expand include size: {$this->mIncludeSizes['post-expand']}/$max bytes\n" .
-                               "Template argument size: {$this->mIncludeSizes['arg']}/$max bytes\n";
+                               "Template argument size: {$this->mIncludeSizes['arg']}/$max bytes\n".
+                               $PFreport;
                        wfRunHooks( 'ParserLimitReport', array( $this, &$limitReport ) );
                        $text .= "\n<!-- \n$limitReport-->\n";
                }
index 5de09fe..c1d33d6 100644 (file)
@@ -338,6 +338,7 @@ $magicWords = array(
        'filepath'               => array( 0,    'FILEPATH:'              ),
        'tag'                    => array( 0,    'tag'                    ),
        'hiddencat'              => array( 1,    '__HIDDENCAT__'          ),
+       'pagesincategory'        => array( 1,    'PAGESINCATEGORY', 'PAGESINCAT' ),
 );
 
 /**
@@ -1128,6 +1129,10 @@ You can go back and edit an existing page, or [[Special:Userlogin|log in or crea
 
 You should consider whether it is appropriate to continue editing this page.
 The deletion log for this page is provided here for convenience:",
+'expensive-parserfunction-warning'  => 'Warning: This page contains too many expensive parser function calls.
+
+It should have less than $2, there are now $1.',
+'expensive-parserfunction-category' => 'Pages with too many expensive parser function calls',
 
 # "Undo" feature
 'undo-success' => 'The edit can be undone. Please check the comparison below to verify that this is what you want to do, and then save the changes below to finish undoing the edit.',