diff options
Diffstat (limited to 'includes/parser/DateFormatter.php')
-rw-r--r-- | includes/parser/DateFormatter.php | 122 |
1 files changed, 85 insertions, 37 deletions
diff --git a/includes/parser/DateFormatter.php b/includes/parser/DateFormatter.php index 9ef11d5e..aa6415e4 100644 --- a/includes/parser/DateFormatter.php +++ b/includes/parser/DateFormatter.php @@ -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; } |