Skip to content
This repository has been archived by the owner on Jan 31, 2020. It is now read-only.

Introducing GPSPoint Validator #18

Closed
wants to merge 11 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
131 changes: 131 additions & 0 deletions src/GpsPoint.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
<?php
/**
* Zend Framework (http://framework.zend.com/)
*
* @link http://github.com/zendframework/zf2 for the canonical source repository
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/

namespace Zend\Validator;

final class GpsPoint extends AbstractValidator
{

const OUT_OF_BOUNDS = 'gpsPointOutOfBounds';
const CONVERT_ERROR = 'gpsPointConvertError';
const INCOMPLETE_COORDINATE = 'gpsPointIncompleteCoordinate';

/**
* @var array
*/
protected $messageTemplates = [
'gpsPointOutOfBounds' => '%value% is out of Bounds.',
'gpsPointConvertError' => '%value% can not converted into a Decimal Degree Value.',
'gpsPointIncompleteCoordinate' => '%value% did not provided a complete Coordinate',
];

/**
* Returns true if and only if $value meets the validation requirements
*
* If $value fails validation, then this method returns false, and
* getMessages() will return an array of messages that explain why the
* validation failed.
*
* @param mixed $value
* @return bool
* @throws Exception\RuntimeException If validation of $value is impossible
*/
public function isValid($value)
{
if (strpos($value, ',') === false) {
$this->error(GpsPoint::INCOMPLETE_COORDINATE, $value);
return false;
}

list($lat, $long) = explode(',', $value);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't the explode have the third argument 2 to ensure no more than 2 values are returned?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@weierophinney Yes, it's cleaner. But should i make this change, because it was already merged.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I made the change during merge, iirc.
On Jul 17, 2015 6:56 AM, "zf2timo" notifications@github.com wrote:

In src/GpsPoint.php
#18 (comment)
:

  • \* If $value fails validation, then this method returns false, and
    
  • \* getMessages() will return an array of messages that explain why the
    
  • \* validation failed.
    
  • *
    
  • \* @param  mixed $value
    
  • \* @return bool
    
  • \* @throws Exception\RuntimeException If validation of $value is impossible
    
  • */
    
  • public function isValid($value)
  • {
  •    if (strpos($value, ',') === false) {
    
  •        $this->error(GpsPoint::INCOMPLETE_COORDINATE, $value);
    
  •        return false;
    
  •    }
    
  •    list($lat, $long) = explode(',', $value);
    

@weierophinney https://github.com/weierophinney Yes, it's cleaner. But
should i make this change, because it was already merged.


Reply to this email directly or view it on GitHub
https://github.com/zendframework/zend-validator/pull/18/files#r34882834.


if ($this->isValidCoordinate($lat, 90.0000) && $this->isValidCoordinate($long, 180.000)) {
return true;
}

return false;
}

/**
* @param string $value
* @param $maxBoundary
* @return bool
*/
private function isValidCoordinate($value, $maxBoundary)
{
$this->value = $value;

$value = $this->removeWhiteSpace($value);
if ($this->isDMSValue($value)) {
$value = $this->convertValue($value);
} else {
$value = $this->removeDegreeSign($value);
}

if ($value === false || $value === null) {
$this->error(self::CONVERT_ERROR);
return false;
}

$doubleLatitude = (double)$value;

if ($doubleLatitude <= $maxBoundary && $doubleLatitude >= $maxBoundary * -1) {
return true;
}

$this->error(self::OUT_OF_BOUNDS);
return false;
}

/**
* Determines if the give value is a Degrees Minutes Second Definition
*
* @param $value
* @return bool
*/
private function isDMSValue($value)
{
return preg_match('/([°\'"]+[NESW])/', $value) > 0;
}


/**
* @param string $value
* @return bool|string
*/
private function convertValue($value)
{
$matches = [];
$result = preg_match_all('/(\d{1,3})°(\d{1,2})\'(\d{1,2}[\.\d]{0,6})"[NESW]/i', $value, $matches);

if ($result === false || $result === 0) {
return false;
}

return $matches[1][0] + $matches[2][0]/60 + ((double)$matches[3][0])/3600;
}

/**
* @param string $value
* @return string
*/
private function removeWhiteSpace($value)
{
return preg_replace('/\s/', '', $value);
}

/**
* @param string $value
* @return string
*/
private function removeDegreeSign($value)
{
return str_replace('°', '', $value);
}
}
83 changes: 83 additions & 0 deletions test/GPSPointTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
<?php
/**
* Zend Framework (http://framework.zend.com/)
*
* @link http://github.com/zendframework/zf2 for the canonical source repository
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/

namespace ZendTest\Validator;

use Zend\Validator\GpsPoint;


/**
* @group Zend_Validator
*/
class GPSPointTest extends \PHPUnit_Framework_TestCase
{

/**
* @var GpsPoint
*/
protected $validator;

public function setUp()
{
$this->validator = new GpsPoint();
}


/**
* @dataProvider basicDataProvider
* @covers \Zend\Validator\GPSPoint::isValid
*/
public function testBasic($gpsPoint)
{
$this->assertTrue($this->validator->isValid($gpsPoint));
}

/**
* @covers \Zend\Validator\GPSPoint::isValid
*/
public function testBoundariesAreRespected()
{
$this->assertFalse($this->validator->isValid('181.8897,-77.0089'));
$this->assertFalse($this->validator->isValid('38.8897,-181.0089'));
$this->assertFalse($this->validator->isValid('-181.8897,-77.0089'));
$this->assertFalse($this->validator->isValid('38.8897,181.0089'));
}

/**
* @covers \Zend\Validator\GPSPoint::isValid
* @dataProvider ErrorMessageTestValues
*/
public function testErrorsSetOnOccur($value, $messageKey, $messageValue)
{
$this->assertFalse($this->validator->isValid($value));
$messages = $this->validator->getMessages();
$this->assertArrayHasKey($messageKey, $messages);
$this->assertContains($messageValue, $messages[$messageKey]);
}

public function basicDataProvider()
{
return [
['38° 53\' 23" N, 77° 00\' 32" W'],
['15° 22\' 20.137" S, 35° 35\' 14.686" E'],
['65° 4\' 36.434" N,-22.728867530822754'],
['38.8897°, -77.0089°'],
['38.8897,-77.0089']
];
}

public function ErrorMessageTestValues()
{
return [
['63 47 24.691 N, 18 2 54.363 W', GpsPoint::OUT_OF_BOUNDS, '63 47 24.691 N'],
['° \' " N,° \' " E', GpsPoint::CONVERT_ERROR, '° \' " N'],
['° \' " N', GpsPoint::INCOMPLETE_COORDINATE, '° \' " N'],
];
}
}