* (bug 4582) Provide preference-based autoformatting of unlinked dates with the datef...
authorAndrew Garrett <werdna@users.mediawiki.org>
Tue, 10 Mar 2009 01:07:47 +0000 (01:07 +0000)
committerAndrew Garrett <werdna@users.mediawiki.org>
Tue, 10 Mar 2009 01:07:47 +0000 (01:07 +0000)
  parser function.

includes/parser/CoreParserFunctions.php
includes/parser/DateFormatter.php
languages/messages/MessagesEn.php

index 9c90d1b..8371451 100644 (file)
@@ -67,6 +67,7 @@ class CoreParserFunctions {
                $parser->setFunctionHook( 'subjectpagename',  array( __CLASS__, 'subjectpagename'  ), SFH_NO_HASH );
                $parser->setFunctionHook( 'subjectpagenamee', array( __CLASS__, 'subjectpagenamee' ), SFH_NO_HASH );
                $parser->setFunctionHook( 'tag',              array( __CLASS__, 'tagObj'           ), SFH_OBJECT_ARGS );
+               $parser->setFunctionHook( 'formatdate',           array( __CLASS__, 'formatDate'           ), SFH_NO_HASH );
 
                if ( $wgAllowDisplayTitle ) {
                        $parser->setFunctionHook( 'displaytitle', array( __CLASS__, 'displaytitle' ), SFH_NO_HASH );
@@ -87,6 +88,14 @@ class CoreParserFunctions {
                        return array( 'found' => false );
                }
        }
+       
+       static function formatDate( $parser, $date ) {
+               $df = DateFormatter::getInstance();
+               
+               $pref = $parser->mOptions->getDateFormat();
+               $date = $df->reformat( $pref, $date, false );
+               return $date;
+       }
 
        static function ns( $parser, $part1 = '' ) {
                global $wgContLang;
index 814c9ac..d2153f0 100644 (file)
@@ -41,11 +41,11 @@ class DateFormatter
                $this->regexTrail = '(?![a-z])/iu';
 
                # Partial regular expressions
-               $this->prxDM = '\[\[(\d{1,2})[ _](' . $this->monthNames . ')]]';
-               $this->prxMD = '\[\[(' . $this->monthNames . ')[ _](\d{1,2})]]';
-               $this->prxY = '\[\[(\d{1,4}([ _]BC|))]]';
-               $this->prxISO1 = '\[\[(-?\d{4})]]-\[\[(\d{2})-(\d{2})]]';
-               $this->prxISO2 = '\[\[(-?\d{4})-(\d{2})-(\d{2})]]';
+               $this->prxDM = '\[\[(\d{1,2})[ _](' . $this->monthNames . ')\]\]';
+               $this->prxMD = '\[\[(' . $this->monthNames . ')[ _](\d{1,2})\]\]';
+               $this->prxY = '\[\[(\d{1,4}([ _]BC|))\]\]';
+               $this->prxISO1 = '\[\[(-?\d{4})]]-\[\[(\d{2})-(\d{2})\]\]';
+               $this->prxISO2 = '\[\[(-?\d{4})-(\d{2})-(\d{2})\]\]';
 
                # Real regular expressions
                $this->regexes[self::DMY] = "/{$this->prxDM} *,? *{$this->prxY}{$this->regexTrail}";
@@ -117,7 +117,7 @@ class DateFormatter
         * @param $preference String: User preference
         * @param $text String: Text to reformat
         */
-       function reformat( $preference, $text ) {
+       function reformat( $preference, $text, $linked = true ) {
                if ( isset( $this->preferences[$preference] ) ) {
                        $preference = $this->preferences[$preference];
                } else {
@@ -138,7 +138,17 @@ class DateFormatter
                                # Default
                                $this->mTarget = $i;
                        }
-                       $text = preg_replace_callback( $this->regexes[$i], array( &$this, 'replace' ), $text );
+                       $regex = $this->regexes[$i];
+                       
+                       // Horrible hack
+                       if (!$linked) {
+                               $regex = str_replace( array( '\[\[', '\]\]' ), '', $regex );
+                       }
+                       
+                       // Another horrible hack
+                       $this->mLinked = $linked;
+                       $text = preg_replace_callback( $regex, array( &$this, 'replace' ), $text );
+                       unset($this->mLinked);
                }
                return $text;
        }
@@ -148,6 +158,10 @@ class DateFormatter
         */
        function replace( $matches ) {
                # Extract information from $matches
+               $linked = true;
+               if ( isset( $this->mLinked ) )
+                       $linked = $this->mLinked;
+               
                $bits = array();
                $key = $this->keys[$this->mSource];
                for ( $p=0; $p < strlen($key); $p++ ) {
@@ -156,43 +170,50 @@ class DateFormatter
                        }
                }
                
-               return $this->formatDate( $bits );
+               return $this->formatDate( $bits, $linked );
        }
        
-       function formatDate( $bits ) {
+       function formatDate( $bits, $link = true ) {
                $format = $this->targets[$this->mTarget];
+               
+               if (!$link) {
+                       // strip piped links
+                       $format = preg_replace( '/\[\[[^|]+\|([^\]]+)\]\]/', '$1', $format );
+                       // strip remaining links
+                       $format = str_replace( array( '[[', ']]' ), '', $format );
+               }
 
                # Construct new date
                $text = '';
                $fail = false;
                
                // Pre-generate y/Y stuff because we need the year for the <span> title.
-               if ( !isset( $bits['y'] ) )
+               if ( !isset( $bits['y'] ) && isset( $bits['Y'] ) )
                        $bits['y'] = $this->makeIsoYear( $bits['Y'] );
-               if ( !isset( $bits['Y'] ) )
+               if ( !isset( $bits['Y'] ) && isset( $bits['y'] ) )
                        $bits['Y'] = $this->makeNormalYear( $bits['y'] );
+                       
+               if ( !isset( $bits['m'] ) ) {
+                       $m = $this->makeIsoMonth( $bits['F'] );
+                       if ( !$m || $m == '00' ) {
+                               $fail = true;
+                       } else {
+                               $bits['m'] = $m;
+                       }
+               }
+               
+               if ( !isset($bits['d']) ) {
+                       $bits['d'] = sprintf( '%02d', $bits['j'] );
+               }
 
                for ( $p=0; $p < strlen( $format ); $p++ ) {
                        $char = $format{$p};
                        switch ( $char ) {
                                case 'd': # ISO day of month
-                                       if ( !isset($bits['d']) ) {
-                                               $text .= sprintf( '%02d', $bits['j'] );
-                                       } else {
-                                               $text .= $bits['d'];
-                                       }
+                                       $text .= $bits['d'];
                                        break;
                                case 'm': # ISO month
-                                       if ( !isset($bits['m']) ) {
-                                               $m = $this->makeIsoMonth( $bits['F'] );
-                                               if ( !$m || $m == '00' ) {
-                                                       $fail = true;
-                                               } else {
-                                                       $text .= $m;
-                                               }
-                                       } else {
-                                               $text .= $bits['m'];
-                                       }
+                                       $text .= $bits['m'];
                                        break;
                                case 'y': # ISO year
                                        $text .= $bits['y'];
@@ -228,7 +249,12 @@ class DateFormatter
                        $text = $matches[0];
                }
                
-               $isoDate = $bits['y'].$bits['m'].$bits['d'];
+               $isoBits = array();
+               if ( isset($bits['y']) )
+                       $isoBits[] = $bits['y'];
+               $isoBits[] = $bits['m'];
+               $isoBits[] = $bits['d'];
+               $isoDate = implode( '-', $isoBits );;
                
                // Output is not strictly HTML (it's wikitext), but <span> is whitelisted.
                $text = Xml::tags( 'span',
index 7b687f4..7ff5222 100644 (file)
@@ -338,6 +338,7 @@ $magicWords = array(
        'numberingroup'          => array( 1,    'NUMBERINGROUP', 'NUMINGROUP' ),
        'staticredirect'         => array( 1,    '__STATICREDIRECT__'     ),
        'protectionlevel'        => array( 1,    'PROTECTIONLEVEL'        ),
+       'formatdate'                     => array( 0,    'formatdate', 'dateformat' ),
 );
 
 /**