From b9ffb5a7e9911e186d9df408b278bd9b9475ab7a Mon Sep 17 00:00:00 2001 From: Andrew Garrett Date: Tue, 10 Mar 2009 01:07:47 +0000 Subject: [PATCH] * (bug 4582) Provide preference-based autoformatting of unlinked dates with the dateformat parser function. --- includes/parser/CoreParserFunctions.php | 9 +++ includes/parser/DateFormatter.php | 80 ++++++++++++++++--------- languages/messages/MessagesEn.php | 1 + 3 files changed, 63 insertions(+), 27 deletions(-) diff --git a/includes/parser/CoreParserFunctions.php b/includes/parser/CoreParserFunctions.php index 9c90d1bed5..83714517ba 100644 --- a/includes/parser/CoreParserFunctions.php +++ b/includes/parser/CoreParserFunctions.php @@ -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; diff --git a/includes/parser/DateFormatter.php b/includes/parser/DateFormatter.php index 814c9ac2b6..d2153f0163 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}"; @@ -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 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 is whitelisted. $text = Xml::tags( 'span', diff --git a/languages/messages/MessagesEn.php b/languages/messages/MessagesEn.php index 7b687f4a8f..7ff5222be3 100644 --- a/languages/messages/MessagesEn.php +++ b/languages/messages/MessagesEn.php @@ -338,6 +338,7 @@ $magicWords = array( 'numberingroup' => array( 1, 'NUMBERINGROUP', 'NUMINGROUP' ), 'staticredirect' => array( 1, '__STATICREDIRECT__' ), 'protectionlevel' => array( 1, 'PROTECTIONLEVEL' ), + 'formatdate' => array( 0, 'formatdate', 'dateformat' ), ); /** -- 2.20.1