]> scripts.mit.edu Git - autoinstalls/mediawiki.git/blobdiff - includes/parser/DateFormatter.php
MediaWiki 1.15.0
[autoinstalls/mediawiki.git] / includes / parser / DateFormatter.php
index 9ef11d5e35ff7fd91a4aa1d8681c9993ae678cc5..aa6415e47aedb52ccf29fa7e594ebf329a9ec2f9 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}";
@@ -96,9 +96,11 @@ class DateFormatter
        }
 
        /**
-        * @static
+        * Get a DateFormatter object
+        *
+        * @return DateFormatter object
         */
-       function &getInstance() {
+       public static function &getInstance() {
                global $wgMemc;
                static $dateFormatter = false;
                if ( !$dateFormatter ) {
@@ -112,10 +114,14 @@ class DateFormatter
        }
 
        /**
-        * @param string $preference User preference
-        * @param string $text Text to reformat
+        * @param $preference String: User preference
+        * @param $text String: Text to reformat
         */
-       function reformat( $preference, $text ) {
+       function reformat( $preference, $text, $options = array('linked') ) {
+       
+               $linked = in_array( 'linked', $options );
+               $match_whole = in_array( 'match-whole', $options );
+               
                if ( isset( $this->preferences[$preference] ) ) {
                        $preference = $this->preferences[$preference];
                } else {
@@ -136,7 +142,24 @@ 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 );
+                       }
+                       
+                       if ($match_whole) {
+                               // Let's hope this works
+                               $regex = preg_replace( '!^/!', '/^', $regex );
+                               $regex = str_replace( $this->regexTrail,
+                                       '$'.$this->regexTrail, $regex );
+                       }
+                       
+                       // Another horrible hack
+                       $this->mLinked = $linked;
+                       $text = preg_replace_callback( $regex, array( &$this, 'replace' ), $text );
+                       unset($this->mLinked);
                }
                return $text;
        }
@@ -146,6 +169,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++ ) {
@@ -153,41 +180,54 @@ class DateFormatter
                                $bits[$key{$p}] = $matches[$p+1];
                        }
                }
-
+               
+               return $this->formatDate( $bits, $linked );
+       }
+       
+       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'] ) && isset( $bits['Y'] ) )
+                       $bits['y'] = $this->makeIsoYear( $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
-                                       if ( !isset( $bits['y'] ) ) {
-                                               $text .= $this->makeIsoYear( $bits['Y'] );
-                                       } else {
-                                               $text .= $bits['y'];
-                                       }
+                                       $text .= $bits['y'];
                                        break;
                                case 'j': # ordinary day of month
                                        if ( !isset($bits['j']) ) {
@@ -210,11 +250,7 @@ class DateFormatter
                                        }
                                        break;
                                case 'Y': # ordinary (optional BC) year
-                                       if ( !isset( $bits['Y'] ) ) {
-                                               $text .= $this->makeNormalYear( $bits['y'] );
-                                       } else {
-                                               $text .= $bits['Y'];
-                                       }
+                                       $text .= $bits['Y'];
                                        break;
                                default:
                                        $text .= $char;
@@ -223,6 +259,18 @@ class DateFormatter
                if ( $fail ) {
                        $text = $matches[0];
                }
+               
+               $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',
+                                       array( 'class' => 'mw-formatted-date', 'title' => $isoDate ), $text );
+               
                return $text;
        }