diff --git a/.gitignore b/.gitignore index 60e9f49..574244d 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,6 @@ *~ +.idea/* tags coverage.db coverage.xml +tests/coverage/* diff --git a/Services/OpenStreetMap/API/V06.php b/Services/OpenStreetMap/API/V06.php index 3276b63..41c0d44 100644 --- a/Services/OpenStreetMap/API/V06.php +++ b/Services/OpenStreetMap/API/V06.php @@ -239,10 +239,10 @@ public function createNode($latitude, $longitude, array $tags = array()) public function getUser() { $config = $this->getConfig()->asArray(); - $url = $config['server'] - . 'api/' - . $config['api_version'] - . '/user/details'; + $url = $config['server'] + . 'api/' + . $config['api_version'] + . '/user/details'; $user = $config['user']; $password = $config['password']; try { @@ -288,13 +288,25 @@ public function getUser() return $obj; } - public function getUserById($id) - { - $config = $this->getConfig()->asArray(); - $url = $config['server'] - . 'api/' - . $config['api_version'] - . '/user/' . $id; + /** + * Get a Services_OpenStreetMap_User object for the specified user. + * + * May return false if the user could not be found for any reason. + * + * @param integer $id User Id. + * + * @see setConfig + * + * @return Services_OpenStreetMap_User + * @throws Services_OpenStreetMap_Exception + */ + public function getUserById($id) + { + $config = $this->getConfig()->asArray(); + $url = $config['server'] + . 'api/' + . $config['api_version'] + . '/user/' . $id; try { $response = $this->getTransport()->getResponse( $url, @@ -313,7 +325,7 @@ public function getUserById($id) $obj = new Services_OpenStreetMap_User(); $obj->setXml(simplexml_load_string($response->getBody())); return $obj; - } + } /** * Get details of specified way diff --git a/Services/OpenStreetMap/OpeningHours.php b/Services/OpenStreetMap/OpeningHours.php new file mode 100644 index 0000000..7c533d3 --- /dev/null +++ b/Services/OpenStreetMap/OpeningHours.php @@ -0,0 +1,225 @@ + + * @license BSD http://www.opensource.org/licenses/bsd-license.php + * @version Release: @package_version@ + * @link OpeningHours.php + * @todo + */ + +/** + * Services_OpenStreetMap_OpeningHours + * + * @category Services + * @package Services_OpenStreetMap + * @author Ken Guest + * @license BSD http://www.opensource.org/licenses/bsd-license.php + * @link OpeningHours.php + */ +class Services_OpenStreetMap_OpeningHours +{ + protected $value; + + /** + * __construct + * + * @param string $value An opening_hours value + * + * @return Services_OpenStreetMap_OpeningHours + */ + public function __construct($value = null) + { + $this->value = $value; + return $this; + } + + /** + * Set opening_hours value. + * + * @param string $value An opening_hours value + * + * @return Services_OpenStreetMap_OpeningHours + */ + public function setValue($value) + { + $this->value = $value; + return $this; + } + + /** + * Return true, false or null depending on whether the [opening hours] + * value explicitly indicates an open, closed or undecided result. + * + * @param double $time A numeric value representing a time. If null, the current time is used. + * + * @link http://wiki.openstreetmap.org/wiki/Key:opening_hours + * @return null|boolean + */ + public function isOpen($time = null) + { + if ($this->value === null) { + return null; + } + if ($this->value == '24/7') { + return true; + } + + if ($time === null) { + $time = time(); + } + if ($this->value == 'sunrise-sunset') { + $sunrise = date_sunrise($time); + $sunset = date_sunset($time); + $starthour = substr($sunrise, 0, 2); + $startmin = substr($sunrise, 3); + $start = $starthour * 60 + $startmin; + $endhour = substr($sunset, 0, 2); + $endmin = substr($sunset, 3); + $end = $endhour * 60 + $endmin; + $d = getdate($time); + $ctime = $d['hours'] * 60 + $d['minutes']; + return ($ctime >= $start && $ctime <= $end ); + } + // other simple test would be sunrise-sunset, but there are also + // offsets that would need to be taken into account. + $rule_sequences = explode(';', $this->value); + foreach ($rule_sequences as $rule_sequence) { + $rule_sequence = trim($rule_sequence); + $portions = explode(' ', $rule_sequence); + $open = $this->_openTimeSpec($portions, $time); + if ($open) { + return true; + } elseif ($open === false) { + return false; + } + } + return false; + } + + /** + * Return true/false/null if a valid portion of an opening_hours value + * indicates whether a venue is open/closed or not incalculable. + * + * @param mixed $portions Part of an opening_hours specification + * @param mixed $time The time to calculate against. + * + * @return null|boolean + */ + private function _openTimeSpec($portions, $time) + { + if ($time === null) { + $time = time(); + } + $day = strtolower(substr(date('D', $time), 0, 2)); + $days = $this->_daySpecToArray($portions[0]); + foreach ($days as $rday) { + if ($rday == $day) { + //day is a match + $time_spec = trim($portions[1]); + if (strpos($time_spec, '-') && (strpos($time_spec, ',') === false)) { + // specified starting and end times for just one range - not + // comma delimited. + $startend_times = explode('-', $time_spec); + $starthour = substr($startend_times[0], 0, 2); + $startmin = substr($startend_times[0], 3); + $start = $starthour * 60 + $startmin; + $endhour = substr($startend_times[1], 0, 2); + $endmin = substr($startend_times[1], 3); + $end = $endhour * 60 + $endmin; + $d = getdate($time); + $ctime = $d['hours'] * 60 + $d['minutes']; + return ($ctime >= $start && $ctime <= $end); + } elseif (strpos($time_spec, '-') && (strpos($time_spec, ','))) { + $times = explode(',', $time_spec); + $d = getdate($time); + $ctime = $d['hours'] * 60 + $d['minutes']; + foreach ($times as $time_spec) { + $startend_times = explode('-', trim($time_spec)); + $starthour = substr($startend_times[0], 0, 2); + $startmin = substr($startend_times[0], 3); + $start = $starthour * 60 + $startmin; + $endhour = substr($startend_times[1], 0, 2); + $endmin = substr($startend_times[1], 3); + $end = $endhour * 60 + $endmin; + if ($ctime >= $start && $ctime <= $end) { + return true; + } + } + return false; + } elseif (preg_match('/^[0-2][0-9]:[0-5][0-9]\+$/', $time_spec)) { + // open-ended. + $starthour = substr($time_spec, 0, 2); + $startmin = substr($time_spec, 3, 2); + $start = $starthour * 60 + $startmin; + $d = getdate($time); + $ctime = $d['hours'] * 60 + $d['minutes']; + if ($ctime < $start) { + return false; + } + } + } + } + } + + /** + * Convert a day list, such as mo-sa, into an array indicating + * which days have been specified. + * + * @param string $day_specification Day list, eg "mo-sa" or "mo,we" + * + * @return array + */ + private function _daySpecToArray($day_specification) + { + $days = array('mo','tu', 'we','th','fr', 'sa', 'su'); + $spec = trim(strtolower($day_specification)); + if ($pos = strpos($spec, '-')) { + $start_day = substr($spec, 0, $pos); + $end_day = substr($spec, $pos + 1); + if ($start_day != 'mo') { + foreach ($days as $day) { + if ($day != $start_day) { + $off = array_shift($days); + } else { + break; + } + } + } + $rdays = array_reverse($days); + if ($end_day != 'su') { + foreach ($rdays as $day) { + if ($day != $end_day) { + $off = array_shift($rdays); + } else { + break; + } + } + $days = array_reverse($rdays); + } + return $days; + } elseif (strlen($spec) == 2) { + if (in_array($spec, $days)) { + return array($spec); + } + } elseif (strpos($spec, ',')) { + $delimited = explode(',', $spec); + $ret = array(); + foreach ($delimited as $item) { + if (in_array($item, $days)) { + $ret[] = $item; + } + } + return $ret; + } + } +} + +// vim:set et ts=4 sw=4: +?> diff --git a/examples/credentials.dist b/examples/credentials.dist new file mode 100644 index 0000000..a69a9ce --- /dev/null +++ b/examples/credentials.dist @@ -0,0 +1,2 @@ +#user:password +fred@example.com:wilma4ever diff --git a/package.xml b/package.xml index 8bbcc68..9d80e65 100644 --- a/package.xml +++ b/package.xml @@ -13,11 +13,11 @@ kguest@php.net yes - 2012-10-02 - + 2012-10-31 + - 0.2.0 - 0.2.0 + 0.1.0 + 0.1.0 alpha @@ -25,7 +25,7 @@ BSD License -Support newly expanded User API. +Initial release of Services_OpenStreetMap - post PEPR process. @@ -81,6 +81,9 @@ Support newly expanded User API. + + + @@ -144,6 +147,9 @@ Support newly expanded User API. + + + @@ -204,6 +210,9 @@ Support newly expanded User API. + + + @@ -234,6 +243,9 @@ Support newly expanded User API. + + + @@ -301,6 +313,9 @@ Support newly expanded User API. + + + @@ -329,6 +344,17 @@ Support newly expanded User API. + + + + + + + + + + + @@ -414,6 +440,9 @@ Support newly expanded User API. + + + @@ -588,6 +617,9 @@ Support newly expanded User API. + + + @@ -640,6 +672,9 @@ Support newly expanded User API. + + + @@ -655,6 +690,9 @@ Support newly expanded User API. + + + @@ -674,15 +712,30 @@ Support newly expanded User API. - + - + + + + + + + + + + + + + + + + @@ -714,48 +767,18 @@ Support newly expanded User API. - 0.0.1 - 0.0.1 + 0.1.0 + 0.1.0 alpha alpha - 2012-02-05 - BSD License - -Initial release - - - - - 0.0.2 - 0.0.2 - - - alpha - alpha - - 2012-03-16 + 2012-10-31 BSD License Initial release of Services_OpenStreetMap - post PEPR process. - - - 0.2.0 - 0.2.0 - - - alpha - alpha - - 2012-10-02 - BSD License - -Support newly expanded User API. - - diff --git a/tests/OpeningHoursTest.php b/tests/OpeningHoursTest.php new file mode 100644 index 0000000..e39032f --- /dev/null +++ b/tests/OpeningHoursTest.php @@ -0,0 +1,44 @@ + + * @license BSD http://www.opensource.org/licenses/bsd-license.php + * @version Release: @package_version@ + * @link OpeningHoursTest.php + */ + +$version = '@package_version@'; +if (strstr($version, 'package_version')) { + set_include_path(dirname(dirname(__FILE__)) . ':' . get_include_path()); +} + +require_once 'Services/OpenStreetMap.php'; + +class OpeningHoursTest extends PHPUnit_Framework_TestCase +{ + public function test() + { + $oh = new Services_OpenStreetMap_OpeningHours('24/7'); + $this->assertTrue($oh->isOpen(time())); + + $oh = new Services_OpenStreetMap_OpeningHours(null); + $this->assertNull($oh->isOpen(time())); + + $oh = new Services_OpenStreetMap_OpeningHours('mo-su: sunrise-sunset'); + $this->assertFalse($oh->isOpen(strtotime('October 24 2012 23:00'))); + + $oh->setValue("Mo 08:00-24:00; Tu-Fr 00:00-24:00;Sa 00:00-22:00; Su 10:00-20:00"); + $this->assertFalse($oh->isOpen(strtotime('October 28 2012 21:00'))); + $this->assertTrue($oh->isOpen(strtotime('October 28 2012 19:55'))); + $this->assertFalse($oh->isOpen(strtotime('October 27 2012 23:00'))); + + } +} + +?>