From: <gem...@li...> - 2013-03-14 15:44:57
|
Revision: 1186 http://sourceforge.net/p/gemstracker/code/1186 Author: matijsdejong Date: 2013-03-14 15:44:54 +0000 (Thu, 14 Mar 2013) Log Message: ----------- Enable 128 bit hashes for ssn Gems_Snippets_ModelFormSnippetAbstract can now switch between tabbed and non-tabbed mode New JavascriptArrayAttribute simplifies common javascript attribute commands Added onblur to text elements Allow algorithms in the project valueHash function Modified Paths: -------------- trunk/library/classes/Gems/Default/RespondentNewAction.php trunk/library/classes/Gems/Model/RespondentModel.php trunk/library/classes/Gems/Model/RespondentNlModel.php trunk/library/classes/Gems/Project/ProjectSettings.php trunk/library/classes/Gems/Snippets/ModelFormSnippetAbstract.php trunk/library/classes/Gems/Snippets/ModelTabFormSnippetGeneric.php trunk/library/classes/MUtil/Html/OnClickArrayAttribute.php trunk/library/classes/MUtil/Model/FormBridge.php trunk/library/classes/MUtil/Validate/Db/UniqueValue.php trunk/library/configs/db/patches.sql trunk/library/configs/db/tables/gems__respondents.30.sql Added Paths: ----------- trunk/library/classes/Gems/Snippets/RespondentFormSnippet.php trunk/library/classes/MUtil/Html/JavascriptArrayAttribute.php Modified: trunk/library/classes/Gems/Default/RespondentNewAction.php =================================================================== --- trunk/library/classes/Gems/Default/RespondentNewAction.php 2013-03-14 13:44:56 UTC (rev 1185) +++ trunk/library/classes/Gems/Default/RespondentNewAction.php 2013-03-14 15:44:54 UTC (rev 1186) @@ -56,14 +56,14 @@ * * @var array Mixed key => value array for snippet initialization */ - protected $createEditParameters = array('resetRoute' => true); + protected $createEditParameters = array('resetRoute' => true, 'useTabbedForm' => true); /** * The snippets used for the create and edit actions. * * @var mixed String or array of snippets name */ - protected $createEditSnippets = 'ModelTabFormSnippetGeneric'; + protected $createEditSnippets = 'RespondentFormSnippet'; /** * The snippets used for the delete action. Modified: trunk/library/classes/Gems/Model/RespondentModel.php =================================================================== --- trunk/library/classes/Gems/Model/RespondentModel.php 2013-03-14 13:44:56 UTC (rev 1185) +++ trunk/library/classes/Gems/Model/RespondentModel.php 2013-03-14 15:44:54 UTC (rev 1186) @@ -55,6 +55,15 @@ const SSN_OPEN = 2; /** + * Determines the algorithm used to hash the social security number + * + * Can be changed is derived classes, set to null to use old md5() method + * + * @var int One of the SSN_ constants + */ + public $hashAlgorithm = 'sha512'; + + /** * Determines how the social security number is stored. * * Can be changed is derived classes. @@ -75,6 +84,12 @@ protected $util; /** + * + * @var Zend_View + */ + public $view; + + /** * Self constructor */ public function __construct() @@ -314,7 +329,13 @@ $ucfirst = new Zend_Filter_Callback('ucfirst'); if ($this->hashSsn !== Gems_Model_RespondentModel::SSN_HIDE) { - $this->set('grs_ssn', 'validator[]', $this->createUniqueValidator('grs_ssn')); + $onblur = new MUtil_Html_JavascriptArrayAttribute('onblur'); + $onblur->addSumbitOnChange('this.value'); + + $this->set('grs_ssn', + 'onblur', $onblur->render($this->view), // Render needed as element does not know HtmlInterface + 'validator[]', $this->createUniqueValidator('grs_ssn') + ); } $this->setIfExists('gr2o_patient_nr', @@ -394,7 +415,7 @@ public function applyHash(&$filterValue, $filterKey) { if ('grs_ssn' === $filterKey) { - $filterValue = $this->project->getValueHash($filterValue); + $filterValue = $this->project->getValueHash($filterValue, $this->hashAlgorithm); } } @@ -457,7 +478,7 @@ public function saveSSN($value, $isNew = false, $name = null, array $context = array()) { if ($value) { - return $this->project->getValueHash($value); + return $this->project->getValueHash($value, $this->hashAlgorithm); } } Modified: trunk/library/classes/Gems/Model/RespondentNlModel.php =================================================================== --- trunk/library/classes/Gems/Model/RespondentNlModel.php 2013-03-14 13:44:56 UTC (rev 1185) +++ trunk/library/classes/Gems/Model/RespondentNlModel.php 2013-03-14 15:44:54 UTC (rev 1186) @@ -103,10 +103,16 @@ { $bsn = new MUtil_Validate_Dutch_Burgerservicenummer(); + $match = '/[^0-9\*]/'; + /* + $m = preg_quote($model->hideSSN(true)); + $match = '/(?>(?(?=' . $m . ')(?!' . $m . ').|[^0-9]))/'; + MUtil_Echo::track($match); + // */ $model->set($fieldName, 'size', 10, 'maxlength', 12, - 'filter', 'Digits', + 'filter', new Zend_Filter_PregReplace(array('match' => $match)), 'validator[]', $bsn); if (APPLICATION_ENV !== 'production') { Modified: trunk/library/classes/Gems/Project/ProjectSettings.php =================================================================== --- trunk/library/classes/Gems/Project/ProjectSettings.php 2013-03-14 13:44:56 UTC (rev 1185) +++ trunk/library/classes/Gems/Project/ProjectSettings.php 2013-03-14 15:44:54 UTC (rev 1186) @@ -94,10 +94,10 @@ } elseif (! is_array($array)) { $array = (array) $array; } - + // Now load default values for (new) keys and merge them with the ones provided by project.ini $projectValues = $array + $this->_getDefaultValues(); - + parent::__construct($projectValues, ArrayObject::ARRAY_AS_PROPS); if (! ($this->offsetExists('name') && $this->offsetGet('name'))) { @@ -106,35 +106,35 @@ $this->offsetSet('multiLocale', $this->offsetExists('locales') && (count($this->offsetGet('locales')) > 1)); } - + /** * Set the default values for all keys. - * - * By doing this, we make sure the settings show up in the project information + * + * By doing this, we make sure the settings show up in the project information * with the defaults even if the settings was not present in the project.ini */ public function _getDefaultValues() { - + return array( '>>> defaults <<<' => '>>> Below are default settings, since they were not found in your project.ini <<<', - + // What to do when user is going to or has answered a survey 'askNextDelay' => -1, // No auto advance 'askDelay' => -1, // No auto advance - + // How to react to false token attempts 'askThrottle' => array( 'period' => 15 * 60, // Detection window: 15 minutes 'threshold' => 15 * 20, // Threshold: 20 requests per minute 'delay' => 10 // Delay: 10 seconds ), - + 'cache' => 'apc', // Use apc cache as default - + 'organization' => array( 'default' => -1 // No default organization - ) + ) ); } @@ -309,8 +309,8 @@ return -1; } - + /** * Returns the public description of this project. * @@ -591,12 +591,13 @@ } /** - * Returns a salted hash on the + * Returns a salted hash optionally using the specified hash algorithm * * @param string $value The value to hash - * @return string The salted hash as a 32-character hexadecimal number. + * @param string $algoritm Optional, hash() algorithm; uses md5() otherwise + * @return string The salted hexadecimal hash, length depending on the algorithm (32 for md5, 128 for sha512. */ - public function getValueHash($value) + public function getValueHash($value, $algorithm = null) { $salt = $this->offsetExists('salt') ? $this->offsetGet('salt') : ''; @@ -607,8 +608,11 @@ } // MUtil_Echo::track($value, md5($salted)); + if (null == $algorithm) { + return md5($salted, false); + } - return md5($salted, false); + return hash($algorithm, $value, false); } /** Modified: trunk/library/classes/Gems/Snippets/ModelFormSnippetAbstract.php =================================================================== --- trunk/library/classes/Gems/Snippets/ModelFormSnippetAbstract.php 2013-03-14 13:44:56 UTC (rev 1185) +++ trunk/library/classes/Gems/Snippets/ModelFormSnippetAbstract.php 2013-03-14 15:44:54 UTC (rev 1186) @@ -92,6 +92,98 @@ protected $routeAction = 'show'; /** + * When true a tabbed form is used. + * + * @var boolean + */ + protected $useTabbedForm = false; + + /** + * Adds elements from the model to the bridge that creates the form. + * + * Overrule this function to add different elements to the browse table, without + * having to recode the core table building code. + * + * @param MUtil_Model_FormBridge $bridge + * @param MUtil_Model_ModelAbstract $model + */ + protected function addFormElements(MUtil_Model_FormBridge $bridge, MUtil_Model_ModelAbstract $model) + { + if (! $this->_form instanceof Gems_TabForm) { + parent::addFormElements($bridge, $model); + return; + } + + //Get all elements in the model if not already done + $this->initItems(); + + // Add 'tooltip' to the allowed displayoptions + $displayOptions = $bridge->getAllowedOptions(MUtil_Model_FormBridge::DISPLAY_OPTIONS); + if (!array_search('tooltip', $displayOptions)) { + $displayOptions[] = 'tooltip'; + } + $bridge->setAllowedOptions(MUtil_Model_FormBridge::DISPLAY_OPTIONS, $displayOptions); + + $tab = 0; + $group = 0; + $oldTab = null; + // MUtil_Echo::track($model->getItemsOrdered()); + foreach ($model->getItemsOrdered() as $name) { + // Get all options at once + $modelOptions = $model->get($name); + $tabName = $model->get($name, 'tab'); + if ($tabName && ($tabName !== $oldTab)) { + $bridge->addTab('tab' . $tab, 'value', $tabName); + $oldTab = $tabName; + $tab++; + } + + if ($model->has($name, 'label')) { + $bridge->add($name); + + if ($theName = $model->get($name, 'startGroup')) { + //We start a new group here! + $groupElements = array(); + $groupElements[] = $name; + $groupName = $theName; + } elseif ($theName = $model->get($name, 'endGroup')) { + //Ok, last element define the group + $groupElements[] = $name; + $bridge->addDisplayGroup('grp_' . $groupElements[0], $groupElements, + 'description', $groupName, + 'showLabels', ($theName == 'showLabels'), + 'class', 'grp' . $group); + $group++; + unset($groupElements); + unset($groupName); + } else { + //If we are in a group, add the elements to the group + if (isset($groupElements)) { + $groupElements[] = $name; + } + } + } else { + $bridge->addHidden($name); + } + unset($this->_items[$name]); + } + } + + /** + * Simple default function for making sure there is a $this->_saveButton. + * + * As the save button is not part of the model - but of the interface - it + * does deserve it's own function. + */ + protected function addSaveButton() + { + if ($this->_form instanceof Gems_TabForm) { + $this->_form->resetContext(); + } + parent::addSaveButton(); + } + + /** * Perform some actions on the form, right before it is displayed but already populated * * Here we add the table display to the form. @@ -100,15 +192,36 @@ */ public function beforeDisplay() { - $table = new MUtil_Html_TableElement(array('class' => $this->class)); - $table->setAsFormLayout($this->_form, true, true); + if ($this->_form instanceof Gems_TabForm) { + if ($links = $this->getMenuList()) { + $element = new MUtil_Form_Element_Html('formLinks'); + $element->setValue($links) + ->setOrder(999) + ->removeDecorator('HtmlTag') + ->removeDecorator('Label') + ->removeDecorator('DtDdWrapper'); +; - // There is only one row with formLayout, so all in output fields get class. - $table['tbody'][0][0]->appendAttrib('class', $this->labelClass); + $this->_form->resetContext(); + $this->_form->addElement($element); - if ($links = $this->getMenuList()) { - $table->tf(); // Add empty cell, no label - $table->tf($links); + if (is_null($this->_form->getDisplayGroup(Gems_TabForm::GROUP_OTHER))) { + $this->_form->addDisplayGroup(array($element), Gems_TabForm::GROUP_OTHER); + } else { + $this->_form->getDisplayGroup(Gems_TabForm::GROUP_OTHER)->addElement($element); + } + } + } else { + $table = new MUtil_Html_TableElement(array('class' => $this->class)); + $table->setAsFormLayout($this->_form, true, true); + + // There is only one row with formLayout, so all in output fields get class. + $table['tbody'][0][0]->appendAttrib('class', $this->labelClass); + + if ($links = $this->getMenuList()) { + $table->tf(); // Add empty cell, no label + $table->tf($links); + } } } @@ -131,9 +244,17 @@ */ protected function createForm($options = null) { - // $form = new Zend_Form($options); - $form = new Gems_Form($options); + if ($this->useTabbedForm) { + $form = new Gems_TabForm($options); + $this->_form = $form; + //Now first add the saveButton as it needs to be outside the tabs + $this->addSaveButton(); + } else { + // $form = new Zend_Form($options); + $form = new Gems_Form($options); + } + return $form; } Modified: trunk/library/classes/Gems/Snippets/ModelTabFormSnippetGeneric.php =================================================================== --- trunk/library/classes/Gems/Snippets/ModelTabFormSnippetGeneric.php 2013-03-14 13:44:56 UTC (rev 1185) +++ trunk/library/classes/Gems/Snippets/ModelTabFormSnippetGeneric.php 2013-03-14 15:44:54 UTC (rev 1186) @@ -48,134 +48,9 @@ class Gems_Snippets_ModelTabFormSnippetGeneric extends Gems_Snippets_ModelFormSnippetGeneric { /** + * When true a tabbed form is used. * - * @var Gems_TabForm + * @var boolean */ - protected $_form; - - /** - * Adds elements from the model to the bridge that creates the form. - * - * Overrule this function to add different elements to the browse table, without - * having to recode the core table building code. - * - * @param MUtil_Model_FormBridge $bridge - * @param MUtil_Model_ModelAbstract $model - */ - protected function addFormElements(MUtil_Model_FormBridge $bridge, MUtil_Model_ModelAbstract $model) - { - //Get all elements in the model if not already done - $this->initItems(); - - // Add 'tooltip' to the allowed displayoptions - $displayOptions = $bridge->getAllowedOptions(MUtil_Model_FormBridge::DISPLAY_OPTIONS); - if (!array_search('tooltip', $displayOptions)) { - $displayOptions[] = 'tooltip'; - } - $bridge->setAllowedOptions(MUtil_Model_FormBridge::DISPLAY_OPTIONS, $displayOptions); - - $tab = 0; - $group = 0; - $oldTab = null; - // MUtil_Echo::track($model->getItemsOrdered()); - foreach ($model->getItemsOrdered() as $name) { - // Get all options at once - $modelOptions = $model->get($name); - $tabName = $model->get($name, 'tab'); - if ($tabName && ($tabName !== $oldTab)) { - $bridge->addTab('tab' . $tab, 'value', $tabName); - $oldTab = $tabName; - $tab++; - } - - if ($model->has($name, 'label')) { - $bridge->add($name); - - if ($theName = $model->get($name, 'startGroup')) { - //We start a new group here! - $groupElements = array(); - $groupElements[] = $name; - $groupName = $theName; - } elseif ($theName = $model->get($name, 'endGroup')) { - //Ok, last element define the group - $groupElements[] = $name; - $bridge->addDisplayGroup('grp_' . $groupElements[0], $groupElements, - 'description', $groupName, - 'showLabels', ($theName == 'showLabels'), - 'class', 'grp' . $group); - $group++; - unset($groupElements); - unset($groupName); - } else { - //If we are in a group, add the elements to the group - if (isset($groupElements)) { - $groupElements[] = $name; - } - } - } else { - $bridge->addHidden($name); - } - unset($this->_items[$name]); - } - } - - /** - * Simple default function for making sure there is a $this->_saveButton. - * - * As the save button is not part of the model - but of the interface - it - * does deserve it's own function. - */ - protected function addSaveButton() - { - $this->_form->resetContext(); - parent::addSaveButton(); - } - - - /** - * Perform some actions on the form, right before it is displayed but already populated - * - * Here we add the table display to the form. - * - * @return Zend_Form - */ - public function beforeDisplay() - { - //If needed, add a row of link buttons to the bottom of the form - $form = $this->_form; - if ($links = $this->getMenuList()) { - $element = new MUtil_Form_Element_Html('formLinks'); - $element->setValue($links); - $element->setOrder(999); - if ($form instanceof Gems_TabForm) { - $form->resetContext(); - } - $form->addElement($element); - $element->removeDecorator('HtmlTag'); - $element->removeDecorator('Label'); - - if (is_null($form->getDisplayGroup(Gems_TabForm::GROUP_OTHER))) { - $form->addDisplayGroup(array($element), Gems_TabForm::GROUP_OTHER); - } else { - $form->getDisplayGroup(Gems_TabForm::GROUP_OTHER)->addElement($element); - } - } - } - - /** - * Creates an empty form. Allows overruling in sub-classes. - * - * @param mixed $options - * @return Gems_TabForm - */ - protected function createForm($options = null) - { - $form = new Gems_TabForm($options); - $this->_form = $form; - - //Now first add the saveButton as it needs to be outside the tabs - $this->addSaveButton(); - - return $form; - } + protected $useTabbedForm = true; } \ No newline at end of file Added: trunk/library/classes/Gems/Snippets/RespondentFormSnippet.php =================================================================== --- trunk/library/classes/Gems/Snippets/RespondentFormSnippet.php (rev 0) +++ trunk/library/classes/Gems/Snippets/RespondentFormSnippet.php 2013-03-14 15:44:54 UTC (rev 1186) @@ -0,0 +1,73 @@ +<?php + +/** + * Copyright (c) 2011, Erasmus MC + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Erasmus MC nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * + * @package Gems + * @subpackage + * @author Matijs de Jong <mj...@ma...> + * @copyright Copyright (c) 2011 Erasmus MC + * @license New BSD License + * @version $Id: RespondentFormSnippet.php$ + */ + +/** + * + * + * @package Gems + * @subpackage + * @copyright Copyright (c) 2011 Erasmus MC + * @license New BSD License + * @since Class available since version 1.5 + */ +class Gems_Snippets_RespondentFormSnippet extends Gems_Snippets_ModelFormSnippetGeneric +{ + /** + * When true a tabbed form is used. + * + * @var boolean + */ + protected $useTabbedForm = true; + + /** + * Hook that loads the form data from $_POST or the model + * + * Or from whatever other source you specify here. + */ + protected function loadFormData() + { + parent::loadFormData(); + + if ($this->createData && $this->request->isPost()) { + if ((! $this->_saveButton) || (! $this->_saveButton->isChecked())) { + if ($this->formData['grs_ssn']) { + // $this->formData['grs_first_name'] = 'Jan'; + } + } + } + } +} Copied: trunk/library/classes/MUtil/Html/JavascriptArrayAttribute.php (from rev 1184, trunk/library/classes/MUtil/Html/OnClickArrayAttribute.php) =================================================================== --- trunk/library/classes/MUtil/Html/JavascriptArrayAttribute.php (rev 0) +++ trunk/library/classes/MUtil/Html/JavascriptArrayAttribute.php 2013-03-14 15:44:54 UTC (rev 1186) @@ -0,0 +1,167 @@ +<?php + +/** + * Copyright (c) 2011, Erasmus MC + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Erasmus MC nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * + * @package MUtil + * @subpackage Html + * @author Matijs de Jong <mj...@ma...> + * @copyright Copyright (c) 2011 Erasmus MC + * @license New BSD License + * @version $Id$ + */ + +/** + * Default attribute for javascript attributes with extra functions for common tasks + * + * @package MUtil + * @subpackage Html + * @copyright Copyright (c) 2011 Erasmus MC + * @license New BSD License + * @since Class available since version MUtil 1.2 + */ +class MUtil_Html_JavascriptArrayAttribute extends MUtil_Html_ArrayAttribute +{ + /** + * String used to glue items together + * + * Empty string as not each array element corresponds to a single command. + * + * @var string + */ + protected $_separator = ''; + + /** + * Specially treated types for a specific subclass + * + * @var array function name => class + */ + protected $_specialTypes = array( + 'addUrl' => 'MUtil_Html_UrlArrayAttribute', + ); + + /** + * + * @param string $type + * @param mixed $arg_array MUtil_Ra::args + */ + public function __construct($type, $arg_array = null) + { + $args = MUtil_Ra::args(func_get_args(), 1); + parent::__construct($type, 'javascript:', $args); + } + + /** + * Add a cancel bubble command + * + * @param boolean $cancelBubble + * @return MUtil_Html_JavascriptArrayAttribute (continuation pattern) + */ + public function addCancelBubble($cancelBubble = true) + { + if ($cancelBubble) { + $this->add("event.cancelBubble = true;"); + } else { + $this->add("event.cancelBubble = false;"); + } + return $this; + } + + /** + * Add single code line + * + * @param mixed $line + * @return MUtil_Html_JavascriptArrayAttribute (continuation pattern) + */ + public function addLine($line_args) + { + $lines = MUtil_Ra::flatten(func_get_args()); + + foreach ($lines as $line) { + $this->add($line); + } + if (! (isset($line) && (';' == substr($line, -1)))) { + $this->add(';'); + } + + return $this; + } + + /** + * Add a form submit + * + * @param string $condition Optional condition for submit + * @return \MUtil_Html_JavascriptArrayAttribute + */ + public function addSumbit($condition = null) + { + if ($condition) { + $this->add("if ($condition) {this.form.submit();}"); + } else { + $this->add('this.form.submit();'); + } + + return $this; + } + + /** + * Add a form submit when a value has changed + * + * @param string $condition Optional extra condition for submit + * @return \MUtil_Html_JavascriptArrayAttribute + */ + public function addSumbitOnChange($condition = null) + { + if ($condition) { + $this->add("if (($condition) && (this.getAttribute('value') != this.value)) {this.form.submit();}"); + } else { + $this->add("if (this.getAttribute('value') != this.value) {this.form.submit();}"); + } + + return $this; + } + + /** + * Add a url open command by specifying only the link + * + * @param mixed $href Anything, e.g. a MUtil_Html_UrlArrayAttribute that the code will transform to an url + * @return MUtil_Html_JavascriptArrayAttribute (continuation pattern) + */ + public function addUrl($href) + { + $last = is_array($this->_values) ? end($this->_values) : null; + if (false === strpos($last, 'location.href')) { + $this->_values[] = "location.href='"; + $this->_values[] = $href; + $this->_values[] = "';"; + } else { + $this->_values[] = $href; + } + + return $this; + } +} \ No newline at end of file Modified: trunk/library/classes/MUtil/Html/OnClickArrayAttribute.php =================================================================== --- trunk/library/classes/MUtil/Html/OnClickArrayAttribute.php 2013-03-14 13:44:56 UTC (rev 1185) +++ trunk/library/classes/MUtil/Html/OnClickArrayAttribute.php 2013-03-14 15:44:54 UTC (rev 1186) @@ -1,6 +1,5 @@ <?php - /** * Copyright (c) 2011, Erasmus MC * All rights reserved. @@ -43,28 +42,14 @@ * @subpackage Html * @copyright Copyright (c) 2011 Erasmus MC * @license New BSD License - * @since Class available since version 1.0 + * @since Class available since MUtil version 1.0 */ -class MUtil_Html_OnClickArrayAttribute extends MUtil_Html_ArrayAttribute +class MUtil_Html_OnClickArrayAttribute extends MUtil_Html_JavascriptArrayAttribute { /** - * String used to glue items together * - * Empty string as not each array element corresponds to a single command. - * - * @var string + * @param mixed $arg_array MUtil_Ra::args */ - protected $_separator = ''; - - /** - * Specially treated types for a specific subclass - * - * @var array function name => class - */ - protected $_specialTypes = array( - 'addUrl' => 'MUtil_Html_UrlArrayAttribute', - ); - public function __construct($arg_array = null) { $args = func_get_args(); @@ -72,41 +57,10 @@ } /** - * Add a cancel bubble command - * - * @param boolean $cancelBubble - * @return MUtil_Html_OnClickArrayAttribute (continuation pattern) + * + * @param array $commands + * @return \self */ - public function addCancelBubble($cancelBubble = true) - { - if ($cancelBubble) { - $this->add("event.cancelBubble = true;"); - } else { - $this->add("event.cancelBubble = false;"); - } - return $this; - } - - /** - * Add a url open command by specifying only the link - * - * @param mixed $href Anything, e.g. a MUtil_Html_UrlArrayAttribute that the code will transform to an url - * @return MUtil_Html_OnClickArrayAttribute (continuation pattern) - */ - public function addUrl($href) - { - $last = is_array($this->_values) ? end($this->_values) : null; - if (false === strpos($last, 'location.href')) { - $this->_values[] = "location.href='"; - $this->_values[] = $href; - $this->_values[] = "';"; - } else { - $this->_values[] = $href; - } - - return $this; - } - public static function onclickAttribute(array $commands = null) { return new self($commands); Modified: trunk/library/classes/MUtil/Model/FormBridge.php =================================================================== --- trunk/library/classes/MUtil/Model/FormBridge.php 2013-03-14 13:44:56 UTC (rev 1185) +++ trunk/library/classes/MUtil/Model/FormBridge.php 2013-03-14 15:44:54 UTC (rev 1186) @@ -95,7 +95,7 @@ self::MULTI_OPTIONS => array('disable', 'multiOptions', 'onchange', 'separator', 'size', 'disableTranslator'), self::PASSWORD_OPTIONS => array('repeatLabel'), self::TAB_OPTIONS => array('value'), - self::TEXT_OPTIONS => array('maxlength', 'minlength', 'onchange', 'onfocus', 'onselect', 'size'), + self::TEXT_OPTIONS => array('maxlength', 'minlength', 'onblur', 'onchange', 'onfocus', 'onselect', 'size'), self::TEXTAREA_OPTIONS => array('cols', 'rows', 'wrap'), ); Modified: trunk/library/classes/MUtil/Validate/Db/UniqueValue.php =================================================================== --- trunk/library/classes/MUtil/Validate/Db/UniqueValue.php 2013-03-14 13:44:56 UTC (rev 1185) +++ trunk/library/classes/MUtil/Validate/Db/UniqueValue.php 2013-03-14 15:44:54 UTC (rev 1186) @@ -1,6 +1,5 @@ <?php - /** * Copyright (c) 2011, Erasmus MC * All rights reserved. @@ -26,22 +25,24 @@ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** * - * @author Matijs de Jong - * @since 1.0 - * @version 1.1 - * @package MUtil + * + * @package MUtil * @subpackage Validate + * @author Matijs de Jong <mj...@ma...> + * @copyright Copyright (c) 2011 Erasmus MC + * @license New BSD License + * @version $Id$ */ /** - * - * @author Matijs de Jong - * @package MUtil + * Unique database validation with provision for the value not being changed + * + * @package MUtil * @subpackage Validate + * @copyright Copyright (c) 2011 Erasmus MC + * @license New BSD License + * @since Class available since MUtil version 1.0 */ class MUtil_Validate_Db_UniqueValue extends Zend_Validate_Db_NoRecordExists { Modified: trunk/library/configs/db/patches.sql =================================================================== --- trunk/library/configs/db/patches.sql 2013-03-14 13:44:56 UTC (rev 1185) +++ trunk/library/configs/db/patches.sql 2013-03-14 15:44:54 UTC (rev 1186) @@ -479,3 +479,7 @@ UPDATE gems__roles SET grl_privileges = CONCAT(grl_privileges, ',pr.contact.gems') WHERE grl_privileges LIKE '%pr.plan.%' AND grl_privileges NOT LIKE '%pr.contact%'; + +-- PATCH: Longer SSN hashes +ALTER TABLE gems__respondents CHANGE grs_ssn + grs_ssn varchar(128) CHARACTER SET 'utf8' COLLATE 'utf8_general_ci'; Modified: trunk/library/configs/db/tables/gems__respondents.30.sql =================================================================== --- trunk/library/configs/db/tables/gems__respondents.30.sql 2013-03-14 13:44:56 UTC (rev 1185) +++ trunk/library/configs/db/tables/gems__respondents.30.sql 2013-03-14 15:44:54 UTC (rev 1186) @@ -2,7 +2,7 @@ CREATE TABLE if not exists gems__respondents ( grs_id_user bigint unsigned not null auto_increment references gems__user_ids (gui_id_user), - grs_ssn varchar(32) CHARACTER SET 'utf8' COLLATE 'utf8_general_ci' + grs_ssn varchar(128) CHARACTER SET 'utf8' COLLATE 'utf8_general_ci' null unique key, grs_iso_lang char(2) CHARACTER SET 'utf8' COLLATE 'utf8_general_ci' not null default 'en', This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |