| Index: trunk/phase3/includes/Parser.php |
| — | — | @@ -33,6 +33,9 @@ |
| 34 | 34 | define( 'OT_WIKI', 2 ); |
| 35 | 35 | define( 'OT_MSG' , 3 ); |
| 36 | 36 | |
| | 37 | +# Flags for setFunctionHook |
| | 38 | +define( 'SFH_NO_HASH', 1 ); |
| | 39 | + |
| 37 | 40 | # string parameter for extractTags which will cause it |
| 38 | 41 | # to strip HTML comments in addition to regular |
| 39 | 42 | # <XML>-style tags. This should not be anything we |
| — | — | @@ -100,11 +103,11 @@ |
| 101 | 104 | * @private |
| 102 | 105 | */ |
| 103 | 106 | # Persistent: |
| 104 | | - var $mTagHooks, $mFunctionHooks; |
| | 107 | + var $mTagHooks, $mFunctionHooks, $mFunctionSynonyms, $mVariables; |
| 105 | 108 | |
| 106 | 109 | # Cleared with clearState(): |
| 107 | 110 | var $mOutput, $mAutonumber, $mDTopen, $mStripState = array(); |
| 108 | | - var $mVariables, $mIncludeCount, $mArgStack, $mLastSection, $mInPre; |
| | 111 | + var $mIncludeCount, $mArgStack, $mLastSection, $mInPre; |
| 109 | 112 | var $mInterwikiLinkHolders, $mLinkHolders, $mUniqPrefix; |
| 110 | 113 | var $mTemplates, // cache of already loaded templates, avoids |
| 111 | 114 | // multiple SQL queries for the same string |
| — | — | @@ -128,22 +131,69 @@ |
| 129 | 132 | function Parser() { |
| 130 | 133 | $this->mTagHooks = array(); |
| 131 | 134 | $this->mFunctionHooks = array(); |
| 132 | | - $this->mFunctionSynonyms = array(); |
| 133 | | - $this->clearState(); |
| 134 | | - $this->setHook( 'pre', array( $this, 'renderPreTag' ) ); |
| | 135 | + $this->mFunctionSynonyms = array( 0 => array(), 1 => array() ); |
| | 136 | + $this->mFirstCall = true; |
| 135 | 137 | } |
| 136 | 138 | |
| 137 | 139 | /** |
| | 140 | + * Do various kinds of initialisation on the first call of the parser |
| | 141 | + */ |
| | 142 | + function firstCallInit() { |
| | 143 | + if ( !$this->mFirstCall ) { |
| | 144 | + return; |
| | 145 | + } |
| | 146 | + |
| | 147 | + wfProfileIn( __METHOD__ ); |
| | 148 | + global $wgAllowDisplayTitle, $wgAllowSlowParserFunctions; |
| | 149 | + |
| | 150 | + $this->setHook( 'pre', array( $this, 'renderPreTag' ) ); |
| | 151 | + |
| | 152 | + $this->setFunctionHook( MAG_NS, array( 'CoreParserFunctions', 'ns' ), SFH_NO_HASH ); |
| | 153 | + $this->setFunctionHook( MAG_URLENCODE, array( 'CoreParserFunctions', 'urlencode' ), SFH_NO_HASH ); |
| | 154 | + $this->setFunctionHook( MAG_LCFIRST, array( 'CoreParserFunctions', 'lcfirst' ), SFH_NO_HASH ); |
| | 155 | + $this->setFunctionHook( MAG_UCFIRST, array( 'CoreParserFunctions', 'ucfirst' ), SFH_NO_HASH ); |
| | 156 | + $this->setFunctionHook( MAG_LC, array( 'CoreParserFunctions', 'lc' ), SFH_NO_HASH ); |
| | 157 | + $this->setFunctionHook( MAG_UC, array( 'CoreParserFunctions', 'uc' ), SFH_NO_HASH ); |
| | 158 | + $this->setFunctionHook( MAG_LOCALURL, array( 'CoreParserFunctions', 'localurl' ), SFH_NO_HASH ); |
| | 159 | + $this->setFunctionHook( MAG_LOCALURLE, array( 'CoreParserFunctions', 'localurle' ), SFH_NO_HASH ); |
| | 160 | + $this->setFunctionHook( MAG_FULLURL, array( 'CoreParserFunctions', 'fullurl' ), SFH_NO_HASH ); |
| | 161 | + $this->setFunctionHook( MAG_FULLURLE, array( 'CoreParserFunctions', 'fullurle' ), SFH_NO_HASH ); |
| | 162 | + $this->setFunctionHook( MAG_FORMATNUM, array( 'CoreParserFunctions', 'formatnum' ), SFH_NO_HASH ); |
| | 163 | + $this->setFunctionHook( MAG_GRAMMAR, array( 'CoreParserFunctions', 'grammar' ), SFH_NO_HASH ); |
| | 164 | + $this->setFunctionHook( MAG_PLURAL, array( 'CoreParserFunctions', 'plural' ), SFH_NO_HASH ); |
| | 165 | + $this->setFunctionHook( MAG_NUMBEROFPAGES, array( 'CoreParserFunctions', 'numberofpages' ), SFH_NO_HASH ); |
| | 166 | + $this->setFunctionHook( MAG_NUMBEROFUSERS, array( 'CoreParserFunctions', 'numberofusers' ), SFH_NO_HASH ); |
| | 167 | + $this->setFunctionHook( MAG_NUMBEROFARTICLES, array( 'CoreParserFunctions', 'numberofarticles' ), SFH_NO_HASH ); |
| | 168 | + $this->setFunctionHook( MAG_NUMBEROFFILES, array( 'CoreParserFunctions', 'numberoffiles' ), SFH_NO_HASH ); |
| | 169 | + $this->setFunctionHook( MAG_NUMBEROFADMINS, array( 'CoreParserFunctions', 'numberofadmins' ), SFH_NO_HASH ); |
| | 170 | + $this->setFunctionHook( MAG_LANGUAGE, array( 'CoreParserFunctions', 'language' ), SFH_NO_HASH ); |
| | 171 | + |
| | 172 | + if ( $wgAllowDisplayTitle ) { |
| | 173 | + $this->setFunctionHook( MAG_DISPLAYTITLE, array( 'CoreParserFunctions', 'displaytitle' ), SFH_NO_HASH ); |
| | 174 | + } |
| | 175 | + if ( $wgAllowSlowParserFunctions ) { |
| | 176 | + $this->setFunctionHook( MAG_PAGESINNAMESPACE, array( 'CoreParserFunctions', 'pagesinnamespace' ), SFH_NO_HASH ); |
| | 177 | + } |
| | 178 | + |
| | 179 | + $this->initialiseVariables(); |
| | 180 | + |
| | 181 | + $this->mFirstCall = false; |
| | 182 | + wfProfileOut( __METHOD__ ); |
| | 183 | + } |
| | 184 | + |
| | 185 | + /** |
| 138 | 186 | * Clear Parser state |
| 139 | 187 | * |
| 140 | 188 | * @private |
| 141 | 189 | */ |
| 142 | 190 | function clearState() { |
| | 191 | + if ( $this->mFirstCall ) { |
| | 192 | + $this->firstCallInit(); |
| | 193 | + } |
| 143 | 194 | $this->mOutput = new ParserOutput; |
| 144 | 195 | $this->mAutonumber = 0; |
| 145 | 196 | $this->mLastSection = ''; |
| 146 | 197 | $this->mDTopen = false; |
| 147 | | - $this->mVariables = false; |
| 148 | 198 | $this->mIncludeCount = array(); |
| 149 | 199 | $this->mStripState = array(); |
| 150 | 200 | $this->mArgStack = array(); |
| — | — | @@ -317,6 +367,11 @@ |
| 318 | 368 | function &getTitle() { return $this->mTitle; } |
| 319 | 369 | function getOptions() { return $this->mOptions; } |
| 320 | 370 | |
| | 371 | + function getFunctionLang() { |
| | 372 | + global $wgLang, $wgContLang; |
| | 373 | + return $this->mOptions->getInterfaceMessage() ? $wgLang : $wgContLang; |
| | 374 | + } |
| | 375 | + |
| 321 | 376 | /** |
| 322 | 377 | * Replaces all occurrences of HTML-style comments and the given tags |
| 323 | 378 | * in the text with a random marker and returns teh next text. The output |
| — | — | @@ -2285,6 +2340,7 @@ |
| 2286 | 2341 | $fname = 'Parser::initialiseVariables'; |
| 2287 | 2342 | wfProfileIn( $fname ); |
| 2288 | 2343 | global $wgVariableIDs; |
| | 2344 | + |
| 2289 | 2345 | $this->mVariables = array(); |
| 2290 | 2346 | foreach ( $wgVariableIDs as $id ) { |
| 2291 | 2347 | $mw =& MagicWord::get( $id ); |
| — | — | @@ -2520,9 +2576,6 @@ |
| 2521 | 2577 | $fname = 'Parser::variableSubstitution'; |
| 2522 | 2578 | $varname = $matches[1]; |
| 2523 | 2579 | wfProfileIn( $fname ); |
| 2524 | | - if ( !$this->mVariables ) { |
| 2525 | | - $this->initialiseVariables(); |
| 2526 | | - } |
| 2527 | 2580 | $skip = false; |
| 2528 | 2581 | if ( $this->mOutputType == OT_WIKI ) { |
| 2529 | 2582 | # Do only magic variables prefixed by SUBST |
| — | — | @@ -2661,199 +2714,26 @@ |
| 2662 | 2715 | } |
| 2663 | 2716 | } |
| 2664 | 2717 | |
| 2665 | | - # NS |
| | 2718 | + # Parser functions |
| 2666 | 2719 | if ( !$found ) { |
| 2667 | | - # Check for NS: (namespace expansion) |
| 2668 | | - $mwNs = MagicWord::get( MAG_NS ); |
| 2669 | | - if ( $mwNs->matchStartAndRemove( $part1 ) ) { |
| 2670 | | - if ( intval( $part1 ) || $part1 == "0" ) { |
| 2671 | | - $text = $linestart . $wgContLang->getNsText( intval( $part1 ) ); |
| 2672 | | - $found = true; |
| | 2720 | + wfProfileIn( __METHOD__ . '-pfunc' ); |
| | 2721 | + |
| | 2722 | + $colonPos = strpos( $part1, ':' ); |
| | 2723 | + if ( $colonPos !== false ) { |
| | 2724 | + # Case sensitive functions |
| | 2725 | + $function = substr( $part1, 0, $colonPos ); |
| | 2726 | + if ( isset( $this->mFunctionSynonyms[1][$function] ) ) { |
| | 2727 | + $function = $this->mFunctionSynonyms[1][$function]; |
| 2673 | 2728 | } else { |
| 2674 | | - $param = str_replace( ' ', '_', strtolower( $part1 ) ); |
| 2675 | | - $index = Namespace::getCanonicalIndex( strtolower( $param ) ); |
| 2676 | | - if ( !is_null( $index ) ) { |
| 2677 | | - $text = $linestart . $wgContLang->getNsText( $index ); |
| 2678 | | - $found = true; |
| 2679 | | - } |
| 2680 | | - } |
| 2681 | | - } |
| 2682 | | - } |
| 2683 | | - |
| 2684 | | - # URLENCODE |
| 2685 | | - if( !$found ) { |
| 2686 | | - $urlencode =& MagicWord::get( MAG_URLENCODE ); |
| 2687 | | - if( $urlencode->matchStartAndRemove( $part1 ) ) { |
| 2688 | | - $text = $linestart . urlencode( $part1 ); |
| 2689 | | - $found = true; |
| 2690 | | - } |
| 2691 | | - } |
| 2692 | | - |
| 2693 | | - # LCFIRST, UCFIRST, LC and UC |
| 2694 | | - if ( !$found ) { |
| 2695 | | - $lcfirst =& MagicWord::get( MAG_LCFIRST ); |
| 2696 | | - $ucfirst =& MagicWord::get( MAG_UCFIRST ); |
| 2697 | | - $lc =& MagicWord::get( MAG_LC ); |
| 2698 | | - $uc =& MagicWord::get( MAG_UC ); |
| 2699 | | - if ( $lcfirst->matchStartAndRemove( $part1 ) ) { |
| 2700 | | - $text = $linestart . $wgContLang->lcfirst( $part1 ); |
| 2701 | | - $found = true; |
| 2702 | | - } else if ( $ucfirst->matchStartAndRemove( $part1 ) ) { |
| 2703 | | - $text = $linestart . $wgContLang->ucfirst( $part1 ); |
| 2704 | | - $found = true; |
| 2705 | | - } else if ( $lc->matchStartAndRemove( $part1 ) ) { |
| 2706 | | - $text = $linestart . $wgContLang->lc( $part1 ); |
| 2707 | | - $found = true; |
| 2708 | | - } else if ( $uc->matchStartAndRemove( $part1 ) ) { |
| 2709 | | - $text = $linestart . $wgContLang->uc( $part1 ); |
| 2710 | | - $found = true; |
| 2711 | | - } |
| 2712 | | - } |
| 2713 | | - |
| 2714 | | - # LOCALURL and FULLURL |
| 2715 | | - if ( !$found ) { |
| 2716 | | - $mwLocal =& MagicWord::get( MAG_LOCALURL ); |
| 2717 | | - $mwLocalE =& MagicWord::get( MAG_LOCALURLE ); |
| 2718 | | - $mwFull =& MagicWord::get( MAG_FULLURL ); |
| 2719 | | - $mwFullE =& MagicWord::get( MAG_FULLURLE ); |
| 2720 | | - |
| 2721 | | - |
| 2722 | | - if ( $mwLocal->matchStartAndRemove( $part1 ) ) { |
| 2723 | | - $func = 'getLocalURL'; |
| 2724 | | - } elseif ( $mwLocalE->matchStartAndRemove( $part1 ) ) { |
| 2725 | | - $func = 'escapeLocalURL'; |
| 2726 | | - } elseif ( $mwFull->matchStartAndRemove( $part1 ) ) { |
| 2727 | | - $func = 'getFullURL'; |
| 2728 | | - } elseif ( $mwFullE->matchStartAndRemove( $part1 ) ) { |
| 2729 | | - $func = 'escapeFullURL'; |
| 2730 | | - } else { |
| 2731 | | - $func = false; |
| 2732 | | - } |
| 2733 | | - |
| 2734 | | - if ( $func !== false ) { |
| 2735 | | - $title = Title::newFromText( $part1 ); |
| 2736 | | - # Due to order of execution of a lot of bits, the values might be encoded |
| 2737 | | - # before arriving here; if that's true, then the title can't be created |
| 2738 | | - # and the variable will fail. If we can't get a decent title from the first |
| 2739 | | - # attempt, url-decode and try for a second. |
| 2740 | | - if( is_null( $title ) ) |
| 2741 | | - $title = Title::newFromUrl( urldecode( $part1 ) ); |
| 2742 | | - if ( !is_null( $title ) ) { |
| 2743 | | - if ( $argc > 0 ) { |
| 2744 | | - $text = $linestart . $title->$func( $args[0] ); |
| | 2729 | + # Case insensitive functions |
| | 2730 | + $function = strtolower( $function ); |
| | 2731 | + if ( isset( $this->mFunctionSynonyms[0][$function] ) ) { |
| | 2732 | + $function = $this->mFunctionSynonyms[0][$function]; |
| 2745 | 2733 | } else { |
| 2746 | | - $text = $linestart . $title->$func(); |
| | 2734 | + $function = false; |
| 2747 | 2735 | } |
| 2748 | | - $found = true; |
| 2749 | 2736 | } |
| 2750 | | - } |
| 2751 | | - } |
| 2752 | | - |
| 2753 | | - $lang = $this->mOptions->getInterfaceMessage() ? $wgLang : $wgContLang; |
| 2754 | | - if ( !$found && $argc == 1 ) { |
| 2755 | | - $mwGrammar =& MagicWord::get( MAG_FORMATNUM ); |
| 2756 | | - if ( $mwGrammar->matchStartAndRemove( $part1 ) ) { |
| 2757 | | - $text = $linestart . $lang->formatNum( $args[0] ); |
| 2758 | | - $found = true; |
| 2759 | | - } |
| 2760 | | - } |
| 2761 | | - |
| 2762 | | - |
| 2763 | | - # GRAMMAR |
| 2764 | | - if ( !$found && $argc == 1 ) { |
| 2765 | | - $mwGrammar =& MagicWord::get( MAG_GRAMMAR ); |
| 2766 | | - if ( $mwGrammar->matchStartAndRemove( $part1 ) ) { |
| 2767 | | - $text = $linestart . $lang->convertGrammar( $args[0], $part1 ); |
| 2768 | | - $found = true; |
| 2769 | | - } |
| 2770 | | - } |
| 2771 | | - |
| 2772 | | - # PLURAL |
| 2773 | | - if ( !$found && $argc >= 2 ) { |
| 2774 | | - $mwPluralForm =& MagicWord::get( MAG_PLURAL ); |
| 2775 | | - if ( $mwPluralForm->matchStartAndRemove( $part1 ) ) { |
| 2776 | | - while ( count($args) < 5 ) { $args[] = $args[count($args)-1]; } |
| 2777 | | - $text = $linestart . $lang->convertPlural( $part1, $args[0], $args[1], |
| 2778 | | - $args[2], $args[3], $args[4]); |
| 2779 | | - $found = true; |
| 2780 | | - } |
| 2781 | | - } |
| 2782 | | - |
| 2783 | | - # DISPLAYTITLE |
| 2784 | | - if ( !$found && $argc == 1 && $wgAllowDisplayTitle ) { |
| 2785 | | - $mwDT =& MagicWord::get( MAG_DISPLAYTITLE ); |
| 2786 | | - if ( $mwDT->matchStartAndRemove( $part1 ) ) { |
| 2787 | | - |
| 2788 | | - # Set title in parser output object |
| 2789 | | - $param = $args[0]; |
| 2790 | | - $parserOptions = new ParserOptions; |
| 2791 | | - $local_parser = new Parser (); |
| 2792 | | - $t2 = $local_parser->parse ( $param, $this->mTitle, $parserOptions, false ); |
| 2793 | | - $this->mOutput->mHTMLtitle = $t2->GetText(); |
| 2794 | | - |
| 2795 | | - # Add subtitle |
| 2796 | | - $t = $this->mTitle->getPrefixedText(); |
| 2797 | | - $this->mOutput->mSubtitle .= wfMsg('displaytitle', $t); |
| 2798 | | - $text = "" ; |
| 2799 | | - $found = true ; |
| 2800 | | - } |
| 2801 | | - } |
| 2802 | | - |
| 2803 | | - # NUMBEROFPAGES, NUMBEROFUSERS, NUMBEROFARTICLES, and NUMBEROFFILES |
| 2804 | | - if( !$found ) { |
| 2805 | | - $mwWordsToCheck = array( MAG_NUMBEROFPAGES => 'wfNumberOfPages', |
| 2806 | | - MAG_NUMBEROFUSERS => 'wfNumberOfUsers', |
| 2807 | | - MAG_NUMBEROFARTICLES => 'wfNumberOfArticles', |
| 2808 | | - MAG_NUMBEROFFILES => 'wfNumberOfFiles', |
| 2809 | | - MAG_NUMBEROFADMINS => 'wfNumberOfAdmins' ); |
| 2810 | | - foreach( $mwWordsToCheck as $word => $func ) { |
| 2811 | | - $mwCurrentWord =& MagicWord::get( $word ); |
| 2812 | | - if( $mwCurrentWord->matchStartAndRemove( $part1 ) ) { |
| 2813 | | - $mwRawSuffix =& MagicWord::get( MAG_RAWSUFFIX ); |
| 2814 | | - if( isset( $args[0] ) && $mwRawSuffix->match( $args[0] ) ) { |
| 2815 | | - # Raw and unformatted |
| 2816 | | - $text = $linestart . call_user_func( $func ); |
| 2817 | | - } else { |
| 2818 | | - # Formatted according to the content default |
| 2819 | | - $text = $linestart . $wgContLang->formatNum( call_user_func( $func ) ); |
| 2820 | | - } |
| 2821 | | - $found = true; |
| 2822 | | - } |
| 2823 | | - } |
| 2824 | | - } |
| 2825 | | - |
| 2826 | | - # PAGESINNAMESPACE |
| 2827 | | - if( !$found ) { |
| 2828 | | - $mwPagesInNs =& MagicWord::get( MAG_PAGESINNAMESPACE ); |
| 2829 | | - if( $mwPagesInNs->matchStartAndRemove( $part1 ) ) { |
| 2830 | | - $found = true; |
| 2831 | | - $count = wfPagesInNs( intval( $part1 ) ); |
| 2832 | | - $mwRawSuffix =& MagicWord::get( MAG_RAWSUFFIX ); |
| 2833 | | - if( isset( $args[0] ) && $mwRawSuffix->match( $args[0] ) ) { |
| 2834 | | - $text = $linestart . $count; |
| 2835 | | - } else { |
| 2836 | | - $text = $linestart . $wgContLang->formatNum( $count ); |
| 2837 | | - } |
| 2838 | | - } |
| 2839 | | - } |
| 2840 | | - |
| 2841 | | - # #LANGUAGE: |
| 2842 | | - if( !$found ) { |
| 2843 | | - $mwLanguage =& MagicWord::get( MAG_LANGUAGE ); |
| 2844 | | - if( $mwLanguage->matchStartAndRemove( $part1 ) ) { |
| 2845 | | - $lang = $wgContLang->getLanguageName( strtolower( $part1 ) ); |
| 2846 | | - $text = $linestart . ( $lang != '' ? $lang : $part1 ); |
| 2847 | | - $found = true; |
| 2848 | | - } |
| 2849 | | - } |
| 2850 | | - |
| 2851 | | - # Extensions |
| 2852 | | - if ( !$found && substr( $part1, 0, 1 ) == '#' ) { |
| 2853 | | - $colonPos = strpos( $part1, ':' ); |
| 2854 | | - if ( $colonPos !== false ) { |
| 2855 | | - $function = strtolower( substr( $part1, 1, $colonPos - 1 ) ); |
| 2856 | | - if ( isset( $this->mFunctionSynonyms[$function] ) ) { |
| 2857 | | - $function = $this->mFunctionSynonyms[$function]; |
| | 2737 | + if ( $function ) { |
| 2858 | 2738 | $funcArgs = array_map( 'trim', $args ); |
| 2859 | 2739 | $funcArgs = array_merge( array( &$this, trim( substr( $part1, $colonPos + 1 ) ) ), $funcArgs ); |
| 2860 | 2740 | $result = call_user_func_array( $this->mFunctionHooks[$function], $funcArgs ); |
| — | — | @@ -2862,10 +2742,12 @@ |
| 2863 | 2743 | // The text is usually already parsed, doesn't need triple-brace tags expanded, etc. |
| 2864 | 2744 | //$noargs = true; |
| 2865 | 2745 | //$noparse = true; |
| 2866 | | - |
| | 2746 | + |
| 2867 | 2747 | if ( is_array( $result ) ) { |
| 2868 | | - $text = $linestart . $result[0]; |
| 2869 | | - unset( $result[0] ); |
| | 2748 | + if ( isset( $result[0] ) ) { |
| | 2749 | + $text = $linestart . $result[0]; |
| | 2750 | + unset( $result[0] ); |
| | 2751 | + } |
| 2870 | 2752 | |
| 2871 | 2753 | // Extract flags into the local scope |
| 2872 | 2754 | // This allows callers to set flags such as nowiki, noparse, found, etc. |
| — | — | @@ -2875,6 +2757,7 @@ |
| 2876 | 2758 | } |
| 2877 | 2759 | } |
| 2878 | 2760 | } |
| | 2761 | + wfProfileOut( __METHOD__ . '-pfunc' ); |
| 2879 | 2762 | } |
| 2880 | 2763 | |
| 2881 | 2764 | # Template table test |
| — | — | @@ -3893,22 +3776,43 @@ |
| 3894 | 3777 | * |
| 3895 | 3778 | * @param mixed $id The magic word ID, or (deprecated) the function name. Function names are case-insensitive. |
| 3896 | 3779 | * @param mixed $callback The callback function (and object) to use |
| | 3780 | + * @param integer $flags a combination of the following flags: |
| | 3781 | + * SFH_NO_HASH No leading hash, i.e. {{plural:...}} instead of {{#if:...}} |
| 3897 | 3782 | * |
| 3898 | 3783 | * @return The old callback function for this name, if any |
| 3899 | 3784 | */ |
| 3900 | | - function setFunctionHook( $id, $callback ) { |
| | 3785 | + function setFunctionHook( $id, $callback, $flags = 0 ) { |
| 3901 | 3786 | if( is_string( $id ) ) { |
| 3902 | 3787 | $id = strtolower( $id ); |
| 3903 | 3788 | } |
| 3904 | 3789 | $oldVal = @$this->mFunctionHooks[$id]; |
| 3905 | 3790 | $this->mFunctionHooks[$id] = $callback; |
| | 3791 | + |
| 3906 | 3792 | # Add to function cache |
| 3907 | 3793 | if ( is_int( $id ) ) { |
| 3908 | 3794 | $mw = MagicWord::get( $id ); |
| 3909 | | - $mw->addToArray( $this->mFunctionSynonyms, $id ); |
| | 3795 | + $synonyms = $mw->getSynonyms(); |
| | 3796 | + $sensitive = intval( $mw->isCaseSensitive() ); |
| 3910 | 3797 | } else { |
| 3911 | | - $this->mFunctionSynonyms[$id] = $id; |
| | 3798 | + $synonyms = array( $id ); |
| | 3799 | + $sensitive = 0; |
| 3912 | 3800 | } |
| | 3801 | + |
| | 3802 | + foreach ( $synonyms as $syn ) { |
| | 3803 | + # Case |
| | 3804 | + if ( !$sensitive ) { |
| | 3805 | + $syn = strtolower( $syn ); |
| | 3806 | + } |
| | 3807 | + # Add leading hash |
| | 3808 | + if ( !( $flags & SFH_NO_HASH ) ) { |
| | 3809 | + $syn = '#' . $syn; |
| | 3810 | + } |
| | 3811 | + # Remove trailing colon |
| | 3812 | + if ( substr( $syn, -1, 1 ) == ':' ) { |
| | 3813 | + $syn = substr( $syn, 0, -1 ); |
| | 3814 | + } |
| | 3815 | + $this->mFunctionSynonyms[$sensitive][$syn] = $id; |
| | 3816 | + } |
| 3913 | 3817 | return $oldVal; |
| 3914 | 3818 | } |
| 3915 | 3819 | |
| Index: trunk/phase3/includes/AutoLoader.php |
| — | — | @@ -27,6 +27,7 @@ |
| 28 | 28 | 'ChangesList' => 'includes/ChangesList.php', |
| 29 | 29 | 'OldChangesList' => 'includes/ChangesList.php', |
| 30 | 30 | 'EnhancedChangesList' => 'includes/ChangesList.php', |
| | 31 | + 'CoreParserFunctions' => 'includes/CoreParserFunctions.php', |
| 31 | 32 | 'DBObject' => 'includes/Database.php', |
| 32 | 33 | 'Database' => 'includes/Database.php', |
| 33 | 34 | 'DatabaseMysql' => 'includes/Database.php', |
| Index: trunk/phase3/includes/DefaultSettings.php |
| — | — | @@ -1128,6 +1128,8 @@ |
| 1129 | 1129 | $wgWLCacheTimeout = 3600; |
| 1130 | 1130 | /** Number of links to a page required before it is deemed "wanted" */ |
| 1131 | 1131 | $wgWantedPagesThreshold = 1; |
| | 1132 | +/** Enable slow parser functions */ |
| | 1133 | +$wgAllowSlowParserFunctions = false; |
| 1132 | 1134 | |
| 1133 | 1135 | /** |
| 1134 | 1136 | * To use inline TeX, you need to compile 'texvc' (in the 'math' subdirectory of |
| Index: trunk/phase3/includes/CoreParserFunctions.php |
| — | — | @@ -0,0 +1,150 @@ |
| | 2 | +<?php |
| | 3 | + |
| | 4 | +/** |
| | 5 | + * Various core parser functions, registered in Parser::firstCallInit() |
| | 6 | + */ |
| | 7 | + |
| | 8 | +class CoreParserFunctions { |
| | 9 | + static function ns( $parser, $part1 = '' ) { |
| | 10 | + global $wgContLang; |
| | 11 | + $found = false; |
| | 12 | + if ( intval( $part1 ) || $part1 == "0" ) { |
| | 13 | + $text = $wgContLang->getNsText( intval( $part1 ) ); |
| | 14 | + $found = true; |
| | 15 | + } else { |
| | 16 | + $param = str_replace( ' ', '_', strtolower( $part1 ) ); |
| | 17 | + $index = Namespace::getCanonicalIndex( strtolower( $param ) ); |
| | 18 | + if ( !is_null( $index ) ) { |
| | 19 | + $text = $wgContLang->getNsText( $index ); |
| | 20 | + $found = true; |
| | 21 | + } |
| | 22 | + } |
| | 23 | + if ( $found ) { |
| | 24 | + return $text; |
| | 25 | + } else { |
| | 26 | + return array( 'found' => false ); |
| | 27 | + } |
| | 28 | + } |
| | 29 | + |
| | 30 | + static function urlencode( $parser, $s = '' ) { |
| | 31 | + return urlencode( $s ); |
| | 32 | + } |
| | 33 | + |
| | 34 | + static function lcfirst( $parser, $s = '' ) { |
| | 35 | + global $wgContLang; |
| | 36 | + return $wgContLang->lcfirst( $s ); |
| | 37 | + } |
| | 38 | + |
| | 39 | + static function ucfirst( $parser, $s = '' ) { |
| | 40 | + global $wgContLang; |
| | 41 | + return $wgContLang->ucfirst( $s ); |
| | 42 | + } |
| | 43 | + |
| | 44 | + static function lc( $parser, $s = '' ) { |
| | 45 | + global $wgContLang; |
| | 46 | + return $wgContLang->lc( $s ); |
| | 47 | + } |
| | 48 | + |
| | 49 | + static function uc( $parser, $s = '' ) { |
| | 50 | + global $wgContLang; |
| | 51 | + return $wgContLang->uc( $s ); |
| | 52 | + } |
| | 53 | + |
| | 54 | + static function localurl( $parser, $s = '', $arg = null ) { return self::urlFunction( 'getLocalURL', $s, $arg ); } |
| | 55 | + static function localurle( $parser, $s = '', $arg = null ) { return self::urlFunction( 'escapeLocalURL', $s, $arg ); } |
| | 56 | + static function fullurl( $parser, $s = '', $arg = null ) { return self::urlFunction( 'getFullURL', $s, $arg ); } |
| | 57 | + static function fullurle( $parser, $s = '', $arg = null ) { return self::urlFunction( 'escapeFullURL', $s, $arg ); } |
| | 58 | + |
| | 59 | + static function urlFunction( $func, $s = '', $arg = null ) { |
| | 60 | + $found = false; |
| | 61 | + $title = Title::newFromText( $s ); |
| | 62 | + # Due to order of execution of a lot of bits, the values might be encoded |
| | 63 | + # before arriving here; if that's true, then the title can't be created |
| | 64 | + # and the variable will fail. If we can't get a decent title from the first |
| | 65 | + # attempt, url-decode and try for a second. |
| | 66 | + if( is_null( $title ) ) |
| | 67 | + $title = Title::newFromUrl( urldecode( $s ) ); |
| | 68 | + if ( !is_null( $title ) ) { |
| | 69 | + if ( !is_null( $arg ) ) { |
| | 70 | + $text = $title->$func( $arg ); |
| | 71 | + } else { |
| | 72 | + $text = $title->$func(); |
| | 73 | + } |
| | 74 | + $found = true; |
| | 75 | + } |
| | 76 | + if ( $found ) { |
| | 77 | + return $text; |
| | 78 | + } else { |
| | 79 | + return array( 'found' => false ); |
| | 80 | + } |
| | 81 | + } |
| | 82 | + |
| | 83 | + function formatNum( $parser, $num = '' ) { |
| | 84 | + return $parser->getFunctionLang()->formatNum( $num ); |
| | 85 | + } |
| | 86 | + |
| | 87 | + function grammar( $parser, $case = '', $word = '' ) { |
| | 88 | + return $parser->getFunctionLang()->convertGrammar( $word, $case ); |
| | 89 | + } |
| | 90 | + |
| | 91 | + function plural( $parser, $text = '', $arg0 = null, $arg1 = null, $arg2 = null, $arg3 = null, $arg4 = null ) { |
| | 92 | + return $parser->getFunctionLang()->convertPlural( $text, $arg0, $arg1, $arg2, $arg3, $arg4 ); |
| | 93 | + } |
| | 94 | + |
| | 95 | + function displaytitle( $parser, $param = '' ) { |
| | 96 | + $parserOptions = new ParserOptions; |
| | 97 | + $local_parser = clone $parser; |
| | 98 | + $t2 = $local_parser->parse ( $param, $parser->mTitle, $parserOptions, false ); |
| | 99 | + $parser->mOutput->mHTMLtitle = $t2->GetText(); |
| | 100 | + |
| | 101 | + # Add subtitle |
| | 102 | + $t = $parser->mTitle->getPrefixedText(); |
| | 103 | + $parser->mOutput->mSubtitle .= wfMsg('displaytitle', $t); |
| | 104 | + return ''; |
| | 105 | + } |
| | 106 | + |
| | 107 | + function isRaw( $param ) { |
| | 108 | + static $mwRaw; |
| | 109 | + if ( !$mwRaw ) { |
| | 110 | + $mwRaw =& MagicWord::get( MAG_RAWSUFFIX ); |
| | 111 | + } |
| | 112 | + if ( is_null( $param ) ) { |
| | 113 | + return false; |
| | 114 | + } else { |
| | 115 | + return $mwRaw->match( $param ); |
| | 116 | + } |
| | 117 | + } |
| | 118 | + |
| | 119 | + function statisticsFunction( $func, $raw = null ) { |
| | 120 | + if ( self::isRaw( $raw ) ) { |
| | 121 | + global $wgContLang; |
| | 122 | + return $wgContLang->formatNum( call_user_func( $func ) ); |
| | 123 | + } else { |
| | 124 | + return call_user_func( $func ); |
| | 125 | + } |
| | 126 | + } |
| | 127 | + |
| | 128 | + function numberofpages( $parser, $raw = null ) { return self::statisticsFunction( 'wfNumberOfPages', $raw ); } |
| | 129 | + function numberofusers( $parser, $raw = null ) { return self::statisticsFunction( 'wfNumberOfUsers', $raw ); } |
| | 130 | + function numberofarticles( $parser, $raw = null ) { return self::statisticsFunction( 'wfNumberOfArticles', $raw ); } |
| | 131 | + function numberoffiles( $parser, $raw = null ) { return self::statisticsFunction( 'wfNumberOfFiles', $raw ); } |
| | 132 | + function numberofadmins( $parser, $raw = null ) { return self::statisticsFunction( 'wfNumberOfAdmins', $raw ); } |
| | 133 | + |
| | 134 | + function pagesinnamespace( $parser, $namespace = 0, $raw = null ) { |
| | 135 | + $count = wfPagesInNs( intval( $namespace ) ); |
| | 136 | + if ( self::isRaw( $raw ) ) { |
| | 137 | + global $wgContLang; |
| | 138 | + return $wgContLang->formatNum( $count ); |
| | 139 | + } else { |
| | 140 | + return $count; |
| | 141 | + } |
| | 142 | + } |
| | 143 | + |
| | 144 | + function language( $parser, $arg = '' ) { |
| | 145 | + global $wgContLang; |
| | 146 | + $lang = $wgContLang->getLanguageName( strtolower( $arg ) ); |
| | 147 | + return $lang != '' ? $lang : $arg; |
| | 148 | + } |
| | 149 | +} |
| | 150 | + |
| | 151 | +?> |
| Property changes on: trunk/phase3/includes/CoreParserFunctions.php |
| ___________________________________________________________________ |
| Added: svn:eol-style |
| 1 | 152 | + native |