Browse Source

fixes, dynamic overwrite for SluggedBehavior, manualLogin via DirectAuthenticate

euromark 13 years ago
parent
commit
fa53ab5ffa

+ 44 - 14
Controller/Component/CommonComponent.php

@@ -313,18 +313,30 @@ class CommonComponent extends Component {
 	 * @param mixed $default
 	 * @return mixed
 	 */
-	public function getNamedParam($var, $default = '') {
-		return (isset($this->Controller->request->params['named'][$var]))?$this->Controller->request->params['named'][$var] : $default;
+	public function getPassedParam($var, $default = null) {
+		return (isset($this->Controller->request->params['pass'][$var])) ? $this->Controller->request->params['pass'][$var] : $default;
+	}
+
+	/**
+	 * Used to get the value of a named param
+	 * @param mixed $var
+	 * @param mixed $default
+	 * @return mixed
+	 */
+	public function getNamedParam($var, $default = null) {
+		return (isset($this->Controller->request->params['named'][$var])) ? $this->Controller->request->params['named'][$var] : $default;
 	}
 
 	/**
 	 * Used to get the value of a get query
+	 * @deprecated - use request->query() instead
+	 *
 	 * @param mixed $var
 	 * @param mixed $default
 	 * @return mixed
 	 */
-	public function getQueryParam($var, $default = '') {
-		return (isset($this->Controller->request->query[$var]))?$this->Controller->request->query[$var] : $default;
+	public function getQueryParam($var, $default = null) {
+		return (isset($this->Controller->request->query[$var])) ? $this->Controller->request->query[$var] : $default;
 	}
 
 	/**
@@ -365,6 +377,30 @@ class CommonComponent extends Component {
 
 	### Controller Stuff ###
 
+	/**
+	 * Force login for a specific user id
+	 * @see DirectAuthentication auth adapter
+	 *
+	 * @param array $data
+	 * - id
+	 * @return boolean Success
+	 * 2012-11-05 ms
+	 */
+	public function manualLogin($id, $contain = array()) {
+		$requestData = $this->Controller->request->data;
+		$authData = $this->Controller->Auth->authenticate;
+		if (!$contain && !empty($authData['Form']['contain'])) {
+			$contain = $authData['Form']['contain'];
+		}
+
+		$this->Controller->request->data = array('User' => array('id' => $id));
+		$this->Controller->Auth->authenticate = array('Tools.Direct'=>array('contain' => $contain, 'fields'=>array('username' => 'id')));
+		$result = $this->Controller->Auth->login();
+
+		$this->Controller->Auth->authenticate = $authData;
+		$this->Controller->request->data = $requestData;
+		return $result;
+	}
 
 	/**
 	 * Smart Referer Redirect - will try to use an existing referer first
@@ -822,12 +858,6 @@ class CommonComponent extends Component {
 		return Utility::typeCast($type, $value);
 	}
 
-
-
-
-
-
-
 	/**
 	 * try to get group for a multidim array for select boxes
 	 * @param array $array
@@ -1340,16 +1370,16 @@ class CommonComponent extends Component {
 	 * @param int $length (if no type is submitted)
 	 * @return pwd on success, empty string otherwise
 	 * @static
-	 * @deprecated - use RamdomLib
+	 * @deprecated - use RandomLib
 	 * 2009-12-26 ms
 	 */
 	public static function pwd($type = null, $length = null) {
-		App::uses('RamdomLib', 'Tools.Lib');
+		App::uses('RandomLib', 'Tools.Lib');
 		if (!empty($type) && $type == 'user') {
-			return RamdomLib::pronounceablePwd(6);
+			return RandomLib::pronounceablePwd(6);
 		}
 		if (!empty($length)) {
-			return RamdomLib::pronounceablePwd($length);
+			return RandomLib::pronounceablePwd($length);
 		}
 		return '';
 	}

+ 4 - 1
Controller/QloginController.php

@@ -30,7 +30,10 @@ class QloginController extends ToolsAppController {
 	 * main login function
 	 * 2011-07-11 ms
 	 */
-	public function go($key) {
+	public function go($key = null) {
+		if (!$key) {
+			throw new NotFoundException();
+		}
 		$entry = $this->Qlogin->translate($key);
 		$default = '/';
 		if ($this->Session->read('Auth.User.id') && isset($this->Auth->loginRedirect)) {

+ 3 - 8
Lib/CaptchaLib.php

@@ -25,12 +25,6 @@ class CaptchaLib {
 	# what method to use
 	public static $methods = array('hash', 'db', 'session');
 
-
-	public function __construct() {
-
-	}
-
-
 	/**
 	 * @param array $data:
 	 * - captcha_time, result/captcha
@@ -48,8 +42,9 @@ class CaptchaLib {
 		$hashValue = date(FORMAT_DB_DATETIME, (int)$data['captcha_time']).'_';
 		$hashValue .= ($options['checkSession'])?session_id().'_' : '';
 		$hashValue .= ($options['checkIp'])?env('REMOTE_ADDR').'_' : '';
-		$hashValue .= $data['captcha'];
-
+		if ($options['type'] !== 'passive') {
+			$hashValue .= $data['captcha'];
+		}
 		return Security::hash($hashValue, isset($options['hashType']) ? $options['hashType'] : null, $options['salt']);
 	}
 

+ 3 - 0
Lib/Error/MyErrorHandler.php

@@ -128,6 +128,9 @@ class MyErrorHandler extends ErrorHandler {
 	 * 2011-12-21 ms
 	 */
 	public static function traceDetails() {
+		if (strpos($_SERVER['REQUEST_URI'], '/test.php?') === 0) {
+			return null;
+		}
 		$currentUrl = isset($_SERVER['REQUEST_URI']) ? $_SERVER['REQUEST_URI'] : 'n/a';
 		$refererUrl = Utility::getReferer(); //Router::getRequest()->url().'
 		App::uses('CakeSession', 'Model/Datasource');

+ 31 - 3
Lib/MyHelper.php

@@ -18,6 +18,35 @@ class MyHelper extends Helper {
 		parent::__construct($View, $settings);
 	}
 
+/**
+ * Sets the defaults for an input tag.  Will set the
+ * name, value, and id attributes for an array of html attributes. Will also
+ * add a 'form-error' class if the field contains validation errors.
+ *
+ * @param string $field The field name to initialize.
+ * @param array $options Array of options to use while initializing an input field.
+ * @return array Array options for the form input.
+ */
+	protected function _initInputField($field, $options = array()) {
+		if ($field !== null) {
+			$this->setEntity($field);
+		}
+		$options = (array)$options;
+		$normalize = true;
+		if (isset($options['normalize'])) {
+			$normalize = $options['normalize'];
+			unset($options['normalize']);
+		}
+
+		$options = $this->_name($options);
+		$options = $this->value($options);
+		if (!empty($options['value']) && $normalize) {
+			$options['value'] = str_replace(array("\t", "\r\n", "\n"), ' ', $options['value']);
+		}
+		$options = $this->domId($options);
+		return $options;
+	}
+
 	/**
 	 * manually
 	 */
@@ -89,8 +118,8 @@ class MyHelper extends Helper {
 	 *
 	 * @param $content string
 	 * @param $options array
-	 * 'format' STRING: Use the specified TimeHelper method (or format()). FALSE: Generate the datetime. NULL: Do nothing.
-	 * 'datetime' STRING: If 'format' is STRING use as the formatting string. FALSE: Don't generate attribute
+	 * - 'format' STRING: Use the specified TimeHelper method (or format()). FALSE: Generate the datetime. NULL: Do nothing.
+	 * - 'datetime' STRING: If 'format' is STRING use as the formatting string. FALSE: Don't generate attribute
 	 *
 	 * //TODO: fixme
 	 * 2011-07-17 ms
@@ -315,4 +344,3 @@ class MyHelper extends Helper {
 	}
 
 }
-

+ 19 - 19
Lib/MyModel.php

@@ -12,6 +12,7 @@ App::uses('Utility', 'Tools.Utility');
 class MyModel extends Model {
 
 	public $recursive = -1;
+
 	public $actsAs = array('Containable');
 
 
@@ -498,6 +499,7 @@ class MyModel extends Model {
 			}
 		}
 
+
 		# having and group clauses enhancement
 		if (is_array($query) && !empty($query['having']) && !empty($query['group'])) {
 			if (!is_array($query['group'])) {
@@ -506,11 +508,12 @@ class MyModel extends Model {
 			$ds = $this->getDataSource();
 			$having = $ds->conditions($query['having'], true, false);
 			$query['group'][count($query['group']) - 1] .= " HAVING $having";
-		} elseif (is_array($query) && !empty($query['having'])) {
+		} /* elseif (is_array($query) && !empty($query['having'])) {
 			$ds = $this->getDataSource();
 			$having = $ds->conditions($query['having'], true, false);
 			$query['conditions'][] = '1=1 HAVING '.$having;
 		}
+		*/
 
 		# find
 		if (!Configure::read('Cache.disable') && Configure::read('Cache.check') && !empty($query['cache'])) {
@@ -936,28 +939,25 @@ class MyModel extends Model {
 			$fieldValue = $value; // equals: $this->data[$this->alias][$fieldName]
 		}
 
-		/*
-		if (empty($fieldName) || empty($fieldValue)) { // return true, if nothing is transfered (check on that first)
-			return true;
-		}
-		*/
-
 		$conditions = array($this->alias . '.' . $fieldName => $fieldValue, // Model.field => $this->data['Model']['field']
 			$this->alias . '.id !=' => $id, );
 
 		# careful, if fields is not manually filled, the options will be the second param!!! big problem...
-		foreach ((array)$fields as $dependingField) {
-			if (isset($this->data[$this->alias][$dependingField])) { // add ONLY if some content is transfered (check on that first!)
-				$conditions[$this->alias . '.' . $dependingField] = $this->data[$this->alias][$dependingField];
-
-			} elseif (isset($this->data['Validation'][$dependingField])) { // add ONLY if some content is transfered (check on that first!
-				$conditions[$this->alias . '.' . $dependingField] = $this->data['Validation'][$dependingField];
-
-			} elseif (!empty($id)) {
-				# manual query! (only possible on edit)
-				$res = $this->find('first', array('fields' => array($this->alias.'.'.$dependingField), 'conditions' => array($this->alias.'.id' => $this->data[$this->alias]['id'])));
-				if (!empty($res)) {
-					$conditions[$this->alias . '.' . $dependingField] = $res[$this->alias][$dependingField];
+		$fields = (array)$fields;
+		if (!array_key_exists('allowEmpty', $fields)) {
+			foreach ((array)$fields as $dependingField) {
+				if (isset($this->data[$this->alias][$dependingField])) { // add ONLY if some content is transfered (check on that first!)
+					$conditions[$this->alias . '.' . $dependingField] = $this->data[$this->alias][$dependingField];
+
+				} elseif (isset($this->data['Validation'][$dependingField])) { // add ONLY if some content is transfered (check on that first!
+					$conditions[$this->alias . '.' . $dependingField] = $this->data['Validation'][$dependingField];
+
+				} elseif (!empty($id)) {
+					# manual query! (only possible on edit)
+					$res = $this->find('first', array('fields' => array($this->alias.'.'.$dependingField), 'conditions' => array($this->alias.'.id' => $this->data[$this->alias]['id'])));
+					if (!empty($res)) {
+						$conditions[$this->alias . '.' . $dependingField] = $res[$this->alias][$dependingField];
+					}
 				}
 			}
 		}

+ 11 - 1
Model/Behavior/KeyValueBehavior.php

@@ -82,7 +82,16 @@ class KeyValueBehavior extends ModelBehavior {
 			$keyArray = preg_split('/\./', $value[$this->KeyValue->alias]['key'], 2);
 			$detailArray[$keyArray[0]][$keyArray[1]] = $value[$this->KeyValue->alias]['value'];
 		}
-		$detailArray = Set::merge($defaultValues, $detailArray);
+
+		foreach ($defaultValues as $model => $values) {
+			foreach ($values as $valueKey => $val) {
+				if (isset($detailArray[$model][$valueKey])) {
+					continue;
+				}
+				$detailArray[$model][$valueKey] = $val;
+			}
+		}
+
 		if ($section === null) {
 			return $detailArray;
 		}
@@ -132,6 +141,7 @@ class KeyValueBehavior extends ModelBehavior {
 				$newDetail[$this->KeyValue->alias][$foreignKeyField] = $foreignKey;
 				$newDetail[$this->KeyValue->alias][$keyField] = $key;
 				$newDetail[$this->KeyValue->alias][$valueField] = $value;
+				$newDetail[$this->KeyValue->alias]['model'] = $Model->alias;
 				$this->KeyValue->save($newDetail, false);
 			}
 		}

+ 4 - 4
Model/Behavior/PasswordableBehavior.php

@@ -195,7 +195,7 @@ class PasswordableBehavior extends ModelBehavior {
 			$Model->validate[$formFieldRepeat] = $rules['formFieldRepeat'];
 			$Model->validate[$formFieldRepeat]['validateIdentical']['rule'][1] = $formField;
 		}
-		
+
 
 		if ($this->settings[$Model->alias]['current'] && !isset($Model->validate[$formFieldCurrent])) {
 			$Model->validate[$formFieldCurrent] = $rules['formFieldCurrent'];
@@ -213,7 +213,7 @@ class PasswordableBehavior extends ModelBehavior {
 
 	/**
 	 * whitelisting
-	 * 
+	 *
 	 * @todo currently there is a cake core bug that can break functionality here
 	 * (see http://cakephp.lighthouseapp.com/projects/42648/tickets/3071-behavior-validation-methods-broken for details)
 	 * @return bool $success
@@ -234,7 +234,7 @@ class PasswordableBehavior extends ModelBehavior {
 		if ($this->settings[$Model->alias]['current'] && !isset($Model->data[$Model->alias][$formFieldCurrent])) {
 			$Model->data[$Model->alias][$formFieldCurrent] = '';
 		}
-		
+
 		# check if we need to trigger any validation rules
 		if ($this->settings[$Model->alias]['allowEmpty']) {
 			$current = !empty($Model->data[$Model->alias][$formFieldCurrent]);
@@ -256,7 +256,7 @@ class PasswordableBehavior extends ModelBehavior {
 				return true;
 			}
 		}
-		
+
 		# add fields to whitelist!
 		$whitelist = array($this->settings[$Model->alias]['formField'], $this->settings[$Model->alias]['formFieldRepeat']);
 		if ($this->settings[$Model->alias]['current']) {

+ 17 - 5
Model/Behavior/SluggedBehavior.php

@@ -66,11 +66,12 @@ class SluggedBehavior extends ModelBehavior {
 	protected $_defaultSettings = array(
 		'label' => null,
 		'slugField' => 'slug',
+		'overwriteField' => 'overwrite_slug',
 		'mode' => 'url',
 		'separator' => '-',
 		'defaultSuffix' => null,
 		'length' => 100,
-		'overwrite' => true,
+		'overwrite' => false,
 		'unique' => false,
 		'notices' => true,
 		'case' => null,
@@ -110,6 +111,11 @@ class SluggedBehavior extends ModelBehavior {
 	public function setup(Model $Model, $config = array()) {
 		$this->_defaultSettings['notices'] = Configure::read('debug');
 		$this->_defaultSettings['label'] = array($Model->displayField);
+		foreach ($this->_defaultSettings['replace'] as $key => $value) {
+			$this->_defaultSettings['replace'][$key] = __($value);
+		}
+		$this->_defaultSettings = Set::merge($this->_defaultSettings, (array)Configure::read('Slugged'));
+
 		$this->settings[$Model->alias] = Set::merge($this->_defaultSettings, $config);
 		extract($this->settings[$Model->alias]);
 		$label = $this->settings[$Model->alias]['label'] = (array)$label;
@@ -193,6 +199,9 @@ class SluggedBehavior extends ModelBehavior {
 		if ($notices && !$Model->hasField($slugField)) {
 			return true;
 		}
+		if (!$overwrite && !empty($Model->data[$Model->alias][$overwriteField])) {
+			$overwrite = true;
+		}
 		if ($overwrite || !$Model->id) {
 			if ($label) {
 				$somethingToDo = false;
@@ -388,7 +397,7 @@ class SluggedBehavior extends ModelBehavior {
 		if ($mode === 'ascii') {
 			$slug = Inflector::slug($string, $separator);
 		} else {
-			$regex = $this->__regex($mode);
+			$regex = $this->_regex($mode);
 			if ($regex) {
 				$slug = $this->_pregReplace('@[' . $regex . ']@Su', $separator, $string, $encoding);
 			} else {
@@ -483,17 +492,20 @@ class SluggedBehavior extends ModelBehavior {
 			'order' => $Model->displayField . ' ASC',
 			'conditions' => $scope,
 			'recursive' => $recursive,
+			'overwrite' => true,
 		);
 		$params = array_merge($defaults, $params);
 		$count = $Model->find('count', compact('conditions'));
 		$max = ini_get('max_execution_time');
 		if ($max) {
-			set_time_limit (max($max, $count / 100));
+			set_time_limit(max($max, $count / 100));
 		}
 		while ($rows = $Model->find('all', $params)) {
 			foreach ($rows as $row) {
 				$Model->create();
-				$Model->save($row, true, array($slugField));
+				if (!$Model->save($row, true, array($slugField))) {
+					throw new RuntimeException(print_r($Model->validationErrors, true));
+				}
 			}
 			$params['page']++;
 		}
@@ -588,7 +600,7 @@ class SluggedBehavior extends ModelBehavior {
  * @return string a partial regex
  * @access private
  */
-	protected function __regex($mode) {
+	protected function _regex($mode) {
 		$return = '\x00-\x1f\x26\x3c\x7f-\x9f\x{d800}-\x{dfff}\x{fffe}-\x{ffff}';
 		if ($mode === 'display') {
 			return $return;

+ 44 - 1
Test/Case/Model/Behavior/SluggedBehaviorTest.php

@@ -130,7 +130,7 @@ class SluggedBehaviorTest extends CakeTestCase {
 	public function testSlugGenerationBasedOnTrigger() {
 		$this->Model->Behaviors->detach('Slugged');
 		$this->Model->Behaviors->attach('Tools.Slugged', array(
-			'trigger' => 'generateSlug'));
+			'trigger' => 'generateSlug', 'overwrite' => true));
 
 		$this->Model->generateSlug = false;
 		$this->Model->create(array('name' => 'Some Article 25271'));
@@ -144,6 +144,47 @@ class SluggedBehaviorTest extends CakeTestCase {
 	}
 
 /**
+ * Test slug generation with i18n replacement pieces
+ *
+ * @access public
+ * @return void
+ */
+	public function testSlugGenerationI18nReplacementPieces() {
+		$this->Model->Behaviors->detach('Slugged');
+		$this->Model->Behaviors->attach('Tools.Slugged', array(
+			'overwrite' => true));
+
+		$this->Model->create(array('name' => 'Some & More'));
+		$result = $this->Model->save();
+		$this->assertEquals('Some-'.__('and').'-More', $result[$this->Model->alias]['slug']);
+	}
+
+/**
+ * Test dynamic slug overwrite
+ *
+ * @access public
+ * @return void
+ */
+	public function testSlugDynamicOverwrite() {
+		$this->Model->Behaviors->detach('Slugged');
+		$this->Model->Behaviors->attach('Tools.Slugged', array(
+			'overwrite' => false, 'overwriteField' => 'overwrite_my_slug'));
+
+		$this->Model->create();
+		$data = array('name' => 'Some Cool String', 'overwrite_my_slug' => false);
+		$result = $this->Model->save($data);
+		$this->assertEquals('Some-Cool-String', $result[$this->Model->alias]['slug']);
+
+		$data = array('name' => 'Some Cool Other String', 'overwrite_my_slug' => false, 'id' => $this->Model->id);
+		$result = $this->Model->save($data);
+		$this->assertTrue(empty($result[$this->Model->alias]['slug']));
+
+		$data = array('name' => 'Some Cool Other String', 'overwrite_my_slug' => true, 'id' => $this->Model->id);
+		$result = $this->Model->save($data);
+		$this->assertEquals('Some-Cool-Other-String', $result[$this->Model->alias]['slug']);
+	}
+
+/**
  * Test slug generation/update based on scope
  *
  * @access public
@@ -345,6 +386,8 @@ class SluggedBehaviorTest extends CakeTestCase {
  * @access public
  */
 	public function testW3Validity() {
+		$this->skipIf(true);
+
 		$modes = array('display', 'url', 'class', 'id');
 		$modes = array('id'); // overriden
 		$this->Socket = new HttpSocket('http://validator.w3.org:80');

+ 1 - 1
View/Helper/CaptchaHelper.php

@@ -1,5 +1,6 @@
 <?php
 App::uses('AppHelper', 'View/Helper');
+App::uses('CaptchaLib', 'Tools.Lib');
 
 if (!defined('BR')) {
 	define('BR', '<br />');
@@ -40,7 +41,6 @@ class CaptchaHelper extends AppHelper {
 		# Set up an array with the operators that we want to use. With difficulty=1 it is only subtraction and addition.
 		$this->operatorConvert = array(0=>array('+',__('calcPlus')), 1=>array('-',__('calcMinus')), 2=>'*',__('calcTimes'));
 
-		App::uses('CaptchaLib', 'Tools.Lib');
 		$this->settings = array_merge(CaptchaLib::$defaults, $this->defaults);
 		$settings = (array)Configure::read('Captcha');
 		if (!empty($settings)) {

+ 27 - 54
View/Helper/FormExtHelper.php

@@ -58,6 +58,23 @@ class FormExtHelper extends FormHelper { // Maybe FormHelper itself some day?
 		return $this->postLink($title, $url, $options, $confirmMessage);
 	}
 
+/**
+ * Creates a textarea widget.
+ *
+ * ### Options:
+ *
+ * - `escape` - Whether or not the contents of the textarea should be escaped. Defaults to true.
+ *
+ * @param string $fieldName Name of a field, in the form "Modelname.fieldname"
+ * @param array $options Array of HTML attributes, and special options above.
+ * @return string A generated HTML text input element
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/form.html#FormHelper::textarea
+ */
+	public function textarea($fieldName, $options = array()) {
+		$options['normalize'] = false;
+		return parent::textarea($fieldName, $options);
+	}
+
 	/**
 	 * fix for required adding (only manually)
 	 * 2011-11-01 ms
@@ -89,7 +106,7 @@ class FormExtHelper extends FormHelper { // Maybe FormHelper itself some day?
  * - `type` - Force the type of widget you want. e.g. `type => 'select'`
  * - `label` - Either a string label, or an array of options for the label. See FormHelper::label()
  * - `div` - Either `false` to disable the div, or an array of options for the div.
- * See HtmlHelper::div() for more options.
+ *    See HtmlHelper::div() for more options.
  * - `options` - for widgets that take options e.g. radio, select
  * - `error` - control the error message that is produced
  * - `empty` - String or boolean to enable empty select box options.
@@ -97,10 +114,10 @@ class FormExtHelper extends FormHelper { // Maybe FormHelper itself some day?
  * - `after` - Content to place after the label + input.
  * - `between` - Content to place between the label + input.
  * - `format` - format template for element order. Any element that is not in the array, will not be in the output.
- * - Default input format order: array('before', 'label', 'between', 'input', 'after', 'error')
- * - Default checkbox format order: array('before', 'input', 'between', 'label', 'after', 'error')
- * - Hidden input will not be formatted
- * - Radio buttons cannot have the order of input and label elements controlled with these settings.
+ *    - Default input format order: array('before', 'label', 'between', 'input', 'after', 'error')
+ *    - Default checkbox format order: array('before', 'input', 'between', 'label', 'after', 'error')
+ *    - Hidden input will not be formatted
+ *    - Radio buttons cannot have the order of input and label elements controlled with these settings.
  *
  * @param string $fieldName This should be "Modelname.fieldname"
  * @param array $options Each type of input takes different options.
@@ -396,50 +413,6 @@ class FormExtHelper extends FormHelper { // Maybe FormHelper itself some day?
 		return $res;
 	}
 
-
-/** redirect **/
-
-	/**
-	 * @param selectOptions:
-	 * - e.g: array('index'=>true/false, 'view'=>array('url'=>x, 'label'=>y), 'edit'=>'xyz', '/some/url'=>'some label')
-	 * 2010-05-02 ms
-	 */
-	public function redirect($selectOptions = array(), $tagOptions = array()) {
-		$options = array('index'=>'Zurück zur Übersicht', 'view'=>__('View %s', __('Record')), '-1'=>'Auf dieser Seite bleiben');
-
-		foreach ($selectOptions as $key => $text) {
-			if ($text === false) {
-				# deactivate this one
-				if (isset($options[$key])) {
-					unset($options[$key]);
-				}
-				continue;
-			} elseif ($text === true) {
-				# leave it as it is
-			} elseif (is_array($text)) {
-				# own id and label?
-			if (isset($text['url']) && isset($text['label'])) {
-				if (isset($options[$key])) {
-						unset($options[$key]);
-					}
-					$options[$text['url']] = $text['label'];
-			}
-			} else {
-				# url => label
-				$options[$key] = $text;
-			}
-		}
-
-		//$options = array('4'=>'Zum Profil dieses Mitglieds');
-		//$options = array('edit'=>__('Edit %s', __('Record')));
-		//$options = array('add'=>'Einen weiteren Eintrag anlegen');
-
-		//$options[-1] = 'Auf dieser Seite bleiben';
-
-		return $this->input('Form.redirect', array('label'=>'Im Anschluss', 'options'=>$options), $tagOptions);
-	}
-
-
 /** date(time) **/
 
 	//TODO: use http://trentrichardson.com/examples/timepicker/
@@ -1010,11 +983,11 @@ jQuery(\''.$selector.'\').maxlength('.$this->Js->object($settings, array('quoteK
 	 * echo $this->FormExt->buttons($buttons);
 	 * with
 	 * $buttons = array(
-	 * array(
-	 * 'title' => 'Login',
-	 * 'options' => array('type' => 'submit')
-	 * ),
-	 * array(...)
+	 *  array(
+	 *   'title' => 'Login',
+	 *   'options' => array('type' => 'submit')
+	 *  ),
+	 *  array(...)
 	 * );
 	 * @param array $buttons
 	 * @return string $buttonSubmitDiv

+ 16 - 0
View/Helper/GoogleMapV3Helper.php

@@ -167,6 +167,7 @@ class GoogleMapV3Helper extends AppHelper {
 		'autoCenter' => false, # try to fit all markers in (careful, all zooms values are omitted)
 		'autoScript' => false, # let the helper include the necessary js script links
 		'inline' => false, # for scripts
+		'localImages' => false,
 		'https' => null # auto detect
 	);
 
@@ -214,6 +215,13 @@ class GoogleMapV3Helper extends AppHelper {
 		if (!empty($google['staticLng'])) {
 			$this->_defaultOptions['staticMap']['lng'] = $google['staticLng'];
 		}
+		if (isset($google['localImages'])) {
+			if ($google['localImages'] === true) {
+				//$google['localImages'] = IMAGES.'google_map'.DS;
+				$google['localImages'] = Router::url('/img/google_map/', true);
+			}
+			$this->_defaultOptions['localImages'] = $google['localImages'];
+		}
 		$this->_currentOptions = $this->_defaultOptions;
 	}
 
@@ -630,6 +638,14 @@ class GoogleMapV3Helper extends AppHelper {
 		if (!in_array($color, $colors)) {
 			$color = 'red';
 		}
+
+		if (!empty($this->_currentOptions['localImages'])) {
+			$this->setIcons['color'] = $this->_currentOptions['localImages'].'marker%s.png';
+			$this->setIcons['alpha'] = $this->_currentOptions['localImages'].'marker%s%s.png';
+			$this->setIcons['numeric'] = $this->_currentOptions['localImages'].'%s%s.png';
+			$this->setIcons['special'] = $this->_currentOptions['localImages'].'%s.png';
+		}
+
 		if (!empty($char)) {
 			if ($color == 'red') {
 				$color = '';