Daniel Werner has submitted this change and it was merged.

Change subject: Remove parsing logic from GeoCoordinateParser and use new 
format specific parsers
......................................................................


Remove parsing logic from GeoCoordinateParser and use new format specific 
parsers

Later need to figure out what to do with this class; probably want to take the 
sub
parsers in the constructor

Change-Id: I30788a3378da3ab3c601c44e5ae0e3c2ad8c80ec
---
M ValueParsers/includes/parsers/GeoCoordinateParser.php
1 file changed, 15 insertions(+), 315 deletions(-)

Approvals:
  Daniel Werner: Verified; Looks good to me, approved
  jenkins-bot: Verified



diff --git a/ValueParsers/includes/parsers/GeoCoordinateParser.php 
b/ValueParsers/includes/parsers/GeoCoordinateParser.php
index a988a24..50e62ad 100644
--- a/ValueParsers/includes/parsers/GeoCoordinateParser.php
+++ b/ValueParsers/includes/parsers/GeoCoordinateParser.php
@@ -106,334 +106,34 @@
         * @throws ParseException
         */
        protected function stringParse( $value ) {
-               $value = $this->getNormalizedNotation( $value );
-
-               $notationType = $this->getCoordinatesType( $value );
-
-               if ( $notationType === false ) {
-                       throw new ParseException( 'Not a geographical 
coordinate' );
-               }
-
-               $coordinates = explode( $this->getOption( 
self::OPT_SEPARATOR_SYMBOL ), $value );
-
-               if ( count( $coordinates ) !== 2 ) {
-                       throw new ParseException( 'A coordinates string with an 
incorrect segment count has made it through validation' );
-               }
-
-               list( $latitude, $longitude ) = $coordinates;
-
-               $latitude = $this->getParsedCoordinate( $notationType, 
$latitude );
-               $longitude = $this->getParsedCoordinate( $notationType, 
$longitude );
-
-               $coordinate = new GeoCoordinateValue( $latitude, $longitude );
-
-               return $coordinate;
-       }
-
-       /**
-        * Parsers a single coordinate (either latitude or longitude) and 
returns it as a float.
-        *
-        * @since 0.1
-        *
-        * @param string $notationType
-        * @param string $coordinate
-        *
-        * @return float
-        *
-        * @throws ParseException
-        */
-       protected function getParsedCoordinate( $notationType, $coordinate ) {
-               $coordinate = $this->resolveDirection( $coordinate );
-
-               switch ( $notationType ) {
-                       case self::TYPE_FLOAT:
-                               return (float)$coordinate;
-                       case self::TYPE_DD:
-                               return $this->parseDDCoordinate( $coordinate );
-                       case self::TYPE_DM:
-                               return $this->parseDMCoordinate( $coordinate );
-                       case self::TYPE_DMS:
-                               return $this->parseDMSCoordinate( $coordinate );
-                       default:
-                               throw new ParseException( 'Invalid coordinate 
type specified' );
-               }
-       }
-
-       /**
-        * Returns the type of the provided coordinates, or false if they are 
invalid.
-        * You can use this as validation function, but be sure to use ===, 
since 0 can be returned.
-        *
-        * @since 0.1
-        *
-        * @param string $coordinates
-        *
-        * @return integer or false
-        */
-       protected function getCoordinatesType( $coordinates ) {
-               switch ( true ) {
-                       case $this->areFloatCoordinates( $coordinates ):
-                               return self::TYPE_FLOAT;
-                               break;
-                       case $this->areDMSCoordinates( $coordinates ):
-                               return self::TYPE_DMS;
-                               break;
-                       case $this->areDDCoordinates( $coordinates ):
-                               return self::TYPE_DD;
-                               break;
-                       case $this->areDMCoordinates( $coordinates ):
-                               return self::TYPE_DM;
-                               break;
-                       default:
-                               return false;
-               }
-       }
-
-       /**
-        * Turns directional notation (N/E/S/W) of a single coordinate into 
non-directional notation (+/-).
-        * This method assumes there are no preceding or tailing spaces.
-        *
-        * @since 0.1
-        *
-        * @param string $coordinate
-        *
-        * @return string
-        */
-       protected function resolveDirection( $coordinate ) {
-               // Get the last char, which could be a direction indicator
-               $lastChar = strtoupper( substr( $coordinate, -1 ) );
-
-               $n = $this->getOption( self::OPT_NORTH_SYMBOL );
-               $e = $this->getOption( self::OPT_EAST_SYMBOL );
-               $s = $this->getOption( self::OPT_SOUTH_SYMBOL );
-               $w = $this->getOption( self::OPT_WEST_SYMBOL );
-
-               // If there is a direction indicator, remove it, and prepend a 
minus sign for south and west directions.
-               // If there is no direction indicator, the coordinate is 
already non-directional and no work is required.
-               if ( in_array( $lastChar, array( $n, $e, $s, $w ) ) ) {
-                       $coordinate = substr( $coordinate, 0, -1 );
-
-                       if ( in_array( $lastChar, array( $s, $w ) ) ) {
-                               $coordinate = '-' . $coordinate;
+               foreach ( $this->getParsers() as $parser ) {
+                       try {
+                               return $parser->parse( $value );
+                       }
+                       catch ( ParseException $parseException ) {
+                               continue;
                        }
                }
 
-               return $coordinate;
+               throw new ParseException( 'The format of the coordinate could 
not be determined. Parsing failed.' );
        }
 
        /**
-        * Returns a normalized version of the coordinate string.
-        *
         * @since 0.1
         *
-        * @param string $coordinates
-        *
-        * @return string
+        * @return  StringValueParser[]
         */
-       protected function getNormalizedNotation( $coordinates ) {
-               $second = $this->getOption( self::OPT_SECOND_SYMBOL );
-               $minute = $this->getOption( self::OPT_MINUTE_SYMBOL );
+       protected function getParsers() {
+               $parsers = array();
 
-               $coordinates = str_replace( array( '°', '°' ), 
$this->getOption( self::OPT_DEGREE_SYMBOL ), $coordinates );
-               $coordinates = str_replace( array( '´', '´' ), 
$second, $coordinates );
-               $coordinates = str_replace( array( '′', '′', '´', 
'′' ), $minute, $coordinates );
-               $coordinates = str_replace( array( '″', '″', 
$minute . $minute, '´´', '′′', '″' ), $second, $coordinates );
+               $parsers[] = new FloatCoordinateParser( $this->options );
+               $parsers[] = new DmsCoordinateParser( $this->options );
+               $parsers[] = new DdCoordinateParser( $this->options );
+               $parsers[] = new DmCoordinateParser( $this->options );
 
-               $coordinates = $this->removeInvalidChars( $coordinates );
-
-               return $coordinates;
+               return $parsers;
        }
 
-       /**
-        * Returns a string with whitespace, control characters and characters 
with ASCII values above 126 removed.
-        *
-        * @since 0.1
-        *
-        * @param string $string
-        *
-        * @return string
-        */
-       protected function removeInvalidChars( $string ) {
-               $filtered = array();
-
-               foreach ( str_split( $string ) as $character ) {
-                       $asciiValue = ord( $character );
-
-                       if ( ( $asciiValue > 32 && $asciiValue < 127 ) || 
$asciiValue == 194 || $asciiValue == 176 ) {
-                               $filtered[] = $character;
-                       }
-               }
-
-               return implode( '', $filtered );
-       }
-
-       /**
-        * Takes a set of coordinates in DMS representation, and returns them 
in float representation.
-        *
-        * @since 0.1
-        *
-        * @param string $coordinate
-        *
-        * @return float
-        */
-       protected function parseDMSCoordinate( $coordinate ) {
-               $isNegative = $coordinate{0} == '-';
-
-               if ( $isNegative ) {
-                       $coordinate = substr( $coordinate, 1 );
-               }
-
-               $degreePosition = strpos( $coordinate, $this->getOption( 
self::OPT_DEGREE_SYMBOL ) );
-               $degrees = substr( $coordinate, 0, $degreePosition );
-
-               $minutePosition = strpos( $coordinate, $this->getOption( 
self::OPT_MINUTE_SYMBOL ) );
-
-               if ( $minutePosition === false ) {
-                       $minutes = 0;
-               }
-               else {
-                       $degSignLength = strlen( $this->getOption( 
self::OPT_DEGREE_SYMBOL ) );
-                       $minuteLength = $minutePosition - $degreePosition - 
$degSignLength;
-                       $minutes = substr( $coordinate, $degreePosition + 
$degSignLength, $minuteLength );
-               }
-
-               $secondPosition = strpos( $coordinate, $this->getOption( 
self::OPT_SECOND_SYMBOL ) );
-
-               if ( $minutePosition === false ) {
-                       $seconds = 0;
-               }
-               else {
-                       $secondLength = $secondPosition - $minutePosition - 1;
-                       $seconds = substr( $coordinate, $minutePosition + 1, 
$secondLength );
-               }
-
-               $coordinate = $degrees + ( $minutes + $seconds / 60 ) / 60;
-
-               if ( $isNegative ) {
-                       $coordinate *= -1;
-               }
-
-               return (float)$coordinate;
-       }
-
-       /**
-        * Takes a set of coordinates in Decimal Degree representation, and 
returns them in float representation.
-        *
-        * @since 0.1
-        *
-        * @param string $coordinate
-        *
-        * @return float
-        */
-       protected function parseDDCoordinate( $coordinate ) {
-               return (float)str_replace( $this->getOption( 
self::OPT_DEGREE_SYMBOL ), '', $coordinate );
-       }
-
-       /**
-        * Takes a set of coordinates in Decimal Minute representation, and 
returns them in float representation.
-        *
-        * @since 0.1
-        *
-        * @param string $coordinate
-        *
-        * @return float
-        */
-       protected function parseDMCoordinate( $coordinate ) {
-               $isNegative = $coordinate{0} == '-';
-
-               if ( $isNegative ) {
-                       $coordinate = substr( $coordinate, 1 );
-               }
-
-               list( $degrees, $minutes ) = explode( $this->getOption( 
self::OPT_DEGREE_SYMBOL ), $coordinate );
-
-               $minutes = substr( $minutes, 0, -1 );
-
-               $coordinate = $degrees + $minutes / 60;
-
-               if ( $isNegative ) {
-                       $coordinate *= -1;
-               }
-
-               return (float)$coordinate;
-       }
-
-       /**
-        * returns whether the coordinates are in float representation.
-        * TODO: nicify
-        *
-        * @since 0.1
-        *
-        * @param string $coordinates
-        *
-        * @return boolean
-        */
-       protected function areFloatCoordinates( $coordinates ) {
-               $sep = $this->getOption( self::OPT_SEPARATOR_SYMBOL );
-
-               $match = preg_match( '/^(-)?\d{1,3}(\.\d{1,20})?' . $sep . 
'(-)?\d{1,3}(\.\d{1,20})?$/i', $coordinates ) // Non-directional
-                       || preg_match( '/^\d{1,3}(\.\d{1,20})?(N|S)' . $sep . 
'\d{1,3}(\.\d{1,20})?(E|W)$/i', $coordinates ); // Directional;
-
-               return $match;
-       }
-
-       /**
-        * returns whether the coordinates are in DMS representation.
-        * TODO: nicify
-        *
-        * @since 0.1
-        *
-        * @param string $coordinates
-        *
-        * @return boolean
-        */
-       protected function areDMSCoordinates( $coordinates ) {
-               $sep = $this->getOption( self::OPT_SEPARATOR_SYMBOL );
-
-               $match = preg_match( 
'/^(-)?(\d{1,3}°)(\d{1,2}(\′|\'))?((\d{1,2}(″|"))?|(\d{1,2}\.\d{1,20}(″|"))?)'
-                       . $sep . 
'(-)?(\d{1,3}°)(\d{1,2}(\′|\'))?((\d{1,2}(″|"))?|(\d{1,2}\.\d{1,20}(″|"))?)$/i',
 $coordinates ) // Non-directional
-                       || preg_match( 
'/^(\d{1,3}°)(\d{1,2}(\′|\'))?((\d{1,2}(″|"))?|(\d{1,2}\.\d{1,20}(″|"))?)(N|S)'
-                               . $sep . 
'(\d{1,3}°)(\d{1,2}(\′|\'))?((\d{1,2}(″|"))?|(\d{1,2}\.\d{1,20}(″|"))?)(E|W)$/i',
 $coordinates ); // Directional
-
-               return $match;
-       }
-
-       /**
-        * returns whether the coordinates are in Decimal Degree representation.
-        * TODO: nicify
-        *
-        * @since 0.1
-        *
-        * @param string $coordinates
-        *
-        * @return boolean
-        */
-       protected function areDDCoordinates( $coordinates ) {
-               $sep = $this->getOption( self::OPT_SEPARATOR_SYMBOL );
-
-               $match = preg_match( '/^(-)?\d{1,3}(|\.\d{1,20})°' . $sep . 
'(-)?\d{1,3}(|\.\d{1,20})°$/i', $coordinates ) // Non-directional
-                       || preg_match( '/^\d{1,3}(|\.\d{1,20})°(N|S)' . $sep . 
'\d{1,3}(|\.\d{1,20})°(E|W)?$/i', $coordinates ); // Directional
-
-               return $match;
-       }
-
-       /**
-        * returns whether the coordinates are in Decimal Minute representation.
-        * TODO: nicify
-        *
-        * @since 0.1
-        *
-        * @param string $coordinates
-        *
-        * @return boolean
-        */
-       protected function areDMCoordinates( $coordinates ) {
-               $sep = $this->getOption( self::OPT_SEPARATOR_SYMBOL );
-
-               $match = preg_match( '/(-)?\d{1,3}°(\d{1,2}(\.\d{1,20}\')?)?' . 
$sep . '(-)?\d{1,3}°(\d{1,2}(\.\d{1,20}\')?)?$/i', $coordinates ) // 
Non-directional
-                       || preg_match( 
'/\d{1,3}°(\d{1,2}(\.\d{1,20}\')?)?(N|S)' . $sep . 
'\d{1,3}°(\d{1,2}(\.\d{1,20}\')?)?(E|W)?$/i', $coordinates ); // Directional
-
-               return $match;
-       }
 
        /**
         * Convenience function for determining if something is a valid 
coordinate string.

-- 
To view, visit https://gerrit.wikimedia.org/r/59076
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings

Gerrit-MessageType: merged
Gerrit-Change-Id: I30788a3378da3ab3c601c44e5ae0e3c2ad8c80ec
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/extensions/DataValues
Gerrit-Branch: master
Gerrit-Owner: Jeroen De Dauw <jeroended...@gmail.com>
Gerrit-Reviewer: Daniel Werner <daniel.wer...@wikimedia.de>
Gerrit-Reviewer: John Erling Blad <jeb...@gmail.com>
Gerrit-Reviewer: Tobias Gritschacher <tobias.gritschac...@wikimedia.de>
Gerrit-Reviewer: jenkins-bot

_______________________________________________
MediaWiki-commits mailing list
MediaWiki-commits@lists.wikimedia.org
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to