Browse Source

geocoder fix and reset callback

euromark 13 years ago
parent
commit
e944504410

+ 2 - 2
Lib/GeocodeLib.php

@@ -446,7 +446,7 @@ class GeocodeLib {
 				}
 
 				if (!empty($this->options['expect'])) {
-					$types = array($accuracy); # TODO: maybe check more than just first?
+					$types = (array)$accuracy;
 
 					$validExpectation = false;
 					foreach ($types as $type) {
@@ -657,7 +657,7 @@ class GeocodeLib {
 	 * fallbacks: cake and php
 	 * note: expects url with json encoded content
 	 * @access private
-	 */
+	 **/
 	protected function _fetch($url) {
 		$this->HttpSocket = new HttpSocketLib($this->use);
 		if ($res = $this->HttpSocket->fetch($url, 'CakePHP Geocode Lib')) {

+ 12 - 12
Model/Behavior/GeocoderBehavior.php

@@ -55,7 +55,6 @@ class GeocoderBehavior extends ModelBehavior {
 		$this->settings[$Model->alias] = array_merge($this->settings[$Model->alias], is_array($settings) ? $settings : array());
 	}
 
-
 	public function beforeValidate(Model $Model) {
 		parent::beforeValidate($Model);
 
@@ -76,7 +75,6 @@ class GeocoderBehavior extends ModelBehavior {
 		return true;
 	}
 
-
 	/**
 	 * Run before a model is saved, used to set up slug for model.
 	 *
@@ -93,7 +91,6 @@ class GeocoderBehavior extends ModelBehavior {
 		$addressfields = array_unique($addressfields);
 
 		// Make sure all address fields are available
-
 		if ($this->settings[$Model->alias]['real']) {
 			foreach ($addressfields as $field) {
 				if (!$Model->hasField($field)) {
@@ -128,12 +125,13 @@ class GeocoderBehavior extends ModelBehavior {
 			if (empty($geocode)) {
 				return false;
 			}
-
+			/*
 			if (!empty($geocode['type']) && !empty($this->settings[$Model->alias]['expect'])) {
 				if (!in_array($geocode['type'], (array)$this->settings[$Model->alias]['expect'])) {
 					return $return;
 				}
 			}
+			*/
 
 			//pr($geocode);
 			//pr($this->Geocode->getResult());
@@ -209,8 +207,8 @@ class GeocoderBehavior extends ModelBehavior {
 	 * Add the distance to this point as a virtual field
 	 *
 	 * @param Model $Model
-	 * @param float $lat
-	 * @param float $lng
+	 * @param string|float $lat Fieldname (Model.lat) or float value
+	 * @param string|float $lng Fieldname (Model.lng) or float value
 	 * @return void
 	 */
 	public function setDistanceAsVirtualField(Model $Model, $lat, $lng, $modelName = null) {
@@ -218,8 +216,10 @@ class GeocoderBehavior extends ModelBehavior {
 	}
 
 	/**
-	 * return a sql snippet for distance calculation on db level using two lat/lng points
+	 * Form a sql snippet for distance calculation on db level using two lat/lng points
 	 *
+	 * @param string|float $lat Fieldname (Model.lat) or float value
+	 * @param string|float $lng Fieldname (Model.lng) or float value
 	 * @return string
 	 */
 	public function distance(Model $Model, $lat, $lng, $fieldLat = null, $fieldLng = null, $modelName = null) {
@@ -235,11 +235,11 @@ class GeocoderBehavior extends ModelBehavior {
 
 		$value = $this->_calculationValue($this->settings[$Model->alias]['unit']);
 
-		return $value . ' * ACOS( COS( PI()/2 - RADIANS(90 - '.$modelName.'.'.$fieldLat.')) * ' .
-			'COS( PI()/2 - RADIANS(90 - '. $lat .')) * ' .
-			'COS( RADIANS('.$modelName.'.'.$fieldLng.') - RADIANS('. $lng .')) + ' .
-			'SIN( PI()/2 - RADIANS(90 - '.$modelName.'.'.$fieldLat.')) * ' .
-			'SIN( PI()/2 - RADIANS(90 - '. $lat . ')))';
+		return $value . ' * ACOS(COS(PI()/2 - RADIANS(90 - '.$modelName.'.'.$fieldLat.')) * ' .
+			'COS(PI()/2 - RADIANS(90 - '. $lat .')) * ' .
+			'COS(RADIANS('.$modelName.'.'.$fieldLng.') - RADIANS('. $lng .')) + ' .
+			'SIN(PI()/2 - RADIANS(90 - '.$modelName.'.'.$fieldLat.')) * ' .
+			'SIN(PI()/2 - RADIANS(90 - '. $lat . ')))';
 	}
 
 	/**

+ 9 - 2
Model/Behavior/ResetBehavior.php

@@ -15,6 +15,7 @@ App::uses('ModelBehavior', 'Model');
  * For performance and memory reasons the records will only be processed in loops (not all at once).
  * If you have time-sensitive data, you can modify the limit of records per loop as well as the
  * timeout in between each loop.
+ * Remember to raise set_time_limit() if you do not run this via CLI.
  *
  * It is recommended to attach this behavior dynamically where needed:
  *
@@ -38,6 +39,7 @@ class ResetBehavior extends ModelBehavior {
 		'validate' => true, // trigger beforeValidate callback
 		'updateTimestamp' => false, // update modified/updated timestamp
 		'scope' => array(), // optional conditions
+		'callback' => null,
 	);
 
 	/**
@@ -106,14 +108,19 @@ class ResetBehavior extends ModelBehavior {
 		while ($rows = $Model->find('all', $params)) {
 			foreach ($rows as $row) {
 				$Model->create();
-				$res = $Model->save($row, $validate, $params['fields']);
+				$fields = $params['fields'];
+				if ($callback) {
+					$Model->{$callback}($row, $fields);
+				}
+
+				$res = $Model->save($row, $validate, $fields);
 				if (!$res) {
 					throw new CakeException(print_r($Model->validationErrors, true));
 				}
 			}
 			$params['page']++;
 			if ($timeout) {
-				set_time_limit((int)$timeout);
+				sleep((int)$timeout);
 			}
 		}
 		return true;

+ 10 - 4
Test/Case/Model/Behavior/GeocoderBehaviorTest.php

@@ -18,19 +18,25 @@ class GeocoderBehaviorTest extends CakeTestCase {
 
 	public function testDistance() {
 		$res = $this->Comment->distance(12, 14);
-		$expected = '6371.04 * ACOS( COS( PI()/2 - RADIANS(90 - Comment.lat)) * COS( PI()/2 - RADIANS(90 - 12)) * COS( RADIANS(Comment.lng) - RADIANS(14)) + SIN( PI()/2 - RADIANS(90 - Comment.lat)) * SIN( PI()/2 - RADIANS(90 - 12)))';
+		$expected = '6371.04 * ACOS(COS(PI()/2 - RADIANS(90 - Comment.lat)) * COS(PI()/2 - RADIANS(90 - 12)) * COS(RADIANS(Comment.lng) - RADIANS(14)) + SIN(PI()/2 - RADIANS(90 - Comment.lat)) * SIN(PI()/2 - RADIANS(90 - 12)))';
 		$this->assertEquals($expected, $res);
 
 		$this->Comment->Behaviors->unload('Geocoder');
 		$this->Comment->Behaviors->load('Tools.Geocoder', array('lat'=>'x', 'lng'=>'y'));
-		$res = $this->Comment->distance(12, 14);
-		$expected = '6371.04 * ACOS( COS( PI()/2 - RADIANS(90 - Comment.x)) * COS( PI()/2 - RADIANS(90 - 12)) * COS( RADIANS(Comment.y) - RADIANS(14)) + SIN( PI()/2 - RADIANS(90 - Comment.x)) * SIN( PI()/2 - RADIANS(90 - 12)))';
+		$res = $this->Comment->distance(12.1, 14.2);
+		$expected = '6371.04 * ACOS(COS(PI()/2 - RADIANS(90 - Comment.x)) * COS(PI()/2 - RADIANS(90 - 12.1)) * COS(RADIANS(Comment.y) - RADIANS(14.2)) + SIN(PI()/2 - RADIANS(90 - Comment.x)) * SIN(PI()/2 - RADIANS(90 - 12.1)))';
+		$this->assertEquals($expected, $res);
+
+		$this->Comment->Behaviors->unload('Geocoder');
+		$this->Comment->Behaviors->load('Tools.Geocoder', array('lat'=>'x', 'lng'=>'y'));
+		$res = $this->Comment->distance('User.lat', 'User.lng');
+		$expected = '6371.04 * ACOS(COS(PI()/2 - RADIANS(90 - Comment.x)) * COS(PI()/2 - RADIANS(90 - User.lat)) * COS(RADIANS(Comment.y) - RADIANS(User.lng)) + SIN(PI()/2 - RADIANS(90 - Comment.x)) * SIN(PI()/2 - RADIANS(90 - User.lat)))';
 		$this->assertEquals($expected, $res);
 	}
 
 	public function testDistanceField() {
 		$res = $this->Comment->distanceField(12, 14);
-		$expected = '6371.04 * ACOS( COS( PI()/2 - RADIANS(90 - Comment.lat)) * COS( PI()/2 - RADIANS(90 - 12)) * COS( RADIANS(Comment.lng) - RADIANS(14)) + SIN( PI()/2 - RADIANS(90 - Comment.lat)) * SIN( PI()/2 - RADIANS(90 - 12))) AS Comment.distance';
+		$expected = '6371.04 * ACOS(COS(PI()/2 - RADIANS(90 - Comment.lat)) * COS(PI()/2 - RADIANS(90 - 12)) * COS(RADIANS(Comment.lng) - RADIANS(14)) + SIN(PI()/2 - RADIANS(90 - Comment.lat)) * SIN(PI()/2 - RADIANS(90 - 12))) AS Comment.distance';
 		$this->assertEquals($expected, $res);
 	}
 

+ 22 - 0
Test/Case/Model/Behavior/ResetBehaviorTest.php

@@ -50,6 +50,21 @@ class ResetBehaviorTest extends MyCakeTestCase {
 		$this->assertTrue($x['MyComment']['updated'] > (date('Y')-1) . '-12-31');
 	}
 
+	public function testResetWithCallback() {
+		$this->Model->Behaviors->unload('Reset');
+		$this->Model->Behaviors->load('Tools.Reset', array('callback' => 'customCallback'));
+
+		$x = $this->Model->find('first', array('conditions' => array('id'=>6)));
+		$this->assertEquals('Second Comment for Second Article', $x['MyComment']['comment']);
+
+		$result = $this->Model->resetRecords();
+		$this->assertTrue($result);
+
+		$x = $this->Model->find('first', array('conditions' => array('id'=>6)));
+		$expected = 'Second Comment for Second Article xyz';
+		$this->assertEquals($expected, $x['MyComment']['comment']);
+	}
+
 }
 
 class MyComment extends AppModel {
@@ -58,4 +73,11 @@ class MyComment extends AppModel {
 
 	public $useTable = 'comments';
 
+	public $displayField = 'comment';
+
+	public function customCallback(&$data, &$fields) {
+		$data[$this->alias][$this->displayField] .= ' xyz';
+		$fields[] = 'some_other_field';
+	}
+
 }