. */ /** * Doctrine_Template_Geographical * * Easily add created and updated at timestamps to your doctrine records * * @package Doctrine * @subpackage Template * @license http://www.opensource.org/licenses/lgpl-license.php LGPL * @link www.phpdoctrine.com * @since 1.0 * @version $Revision$ * @author Konsta Vesterinen */ class Doctrine_Template_Geographical extends Doctrine_Template { /** * Array of timestampable options * * @var string */ protected $_options = array('latitude' => array('name' => 'latitude', 'type' => 'float', 'size' => 4, 'options' => array()), 'longitude' => array('name' => 'longitude', 'type' => 'float', 'size' => 4, 'options' => array())); /** * __construct * * @param string $array * @return void */ public function __construct(array $options) { $this->_options = Doctrine_Lib::arrayDeepMerge($this->_options, $options); } /** * setTableDefinition * * @return void */ public function setTableDefinition() { $this->hasColumn($this->_options['latitude']['name'], $this->_options['latitude']['type'], $this->_options['latitude']['size'], $this->_options['latitude']['options']); $this->hasColumn($this->_options['longitude']['name'], $this->_options['longitude']['type'], $this->_options['longitude']['size'], $this->_options['longitude']['options']); } public function getDistanceQuery() { $invoker = $this->getInvoker(); $query = $invoker->getTable()->createQuery(); $rootAlias = $query->getRootAlias(); $latName = $this->_options['latitude']['name']; $longName = $this->_options['longitude']['name']; $query->addSelect($rootAlias . '.*'); $sql = "((ACOS(SIN(%s * PI() / 180) * SIN(" . $rootAlias . "." . $latName . " * PI() / 180) + COS(%s * PI() / 180) * COS(" . $rootAlias . "." . $latName . " * PI() / 180) * COS((%s - " . $rootAlias . "." . $longName . ") * PI() / 180)) * 180 / PI()) * 60 * %s) as %s"; $milesSql = sprintf($sql, number_format($invoker->get('latitude'), 1), $invoker->get('latitude'), $invoker->get('longitude'), '1.1515', 'miles'); $query->addSelect($milesSql); $kilometersSql = sprintf($sql, number_format($invoker->get('latitude'), 1), $invoker->get('latitude'), $invoker->get('longitude'), '1.1515 * 1.609344', 'kilometers'); $query->addSelect($kilometersSql); return $query; } public function getDistance(Doctrine_Record $record, $kilometers = false) { $query = $this->getDistanceQuery($kilometers); $conditions = array(); $values = array(); foreach ((array) $record->getTable()->getIdentifier() as $id) { $conditions[] = $query->getRootAlias() . '.' . $id . ' = ?'; $values[] = $record->get($id); } $where = implode(' AND ', $conditions); $query->addWhere($where, $values); $query->limit(1); $result = $query->execute()->getFirst(); if (isset($result['kilometers']) && $result['miles']) { return $kilometers ? $result->get('kilometers'):$result->get('miles'); } else { return 0; } } }