From: <gem...@li...> - 2011-10-18 16:35:41
|
Revision: 113 http://gemstracker.svn.sourceforge.net/gemstracker/?rev=113&view=rev Author: matijsdejong Date: 2011-10-18 16:35:34 +0000 (Tue, 18 Oct 2011) Log Message: ----------- Modified Paths: -------------- branches/newUser/classes/Gems/Cookies.php branches/newUser/classes/Gems/Default/IndexAction.php branches/newUser/classes/Gems/Loader/LoaderAbstract.php branches/newUser/classes/Gems/Loader.php branches/newUser/classes/GemsEscort.php branches/newUser/configs/db/patches.sql Added Paths: ----------- branches/newUser/ Modified: branches/newUser/classes/Gems/Cookies.php =================================================================== --- trunk/library/classes/Gems/Cookies.php 2011-10-17 13:51:03 UTC (rev 112) +++ branches/newUser/classes/Gems/Cookies.php 2011-10-18 16:35:34 UTC (rev 113) @@ -1,63 +1,86 @@ <?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. - * - * @author Matijs de Jong - * @since 1.0 - * @version $Id$ + +/** + * 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 Gems * @subpackage Cookies + * @author Matijs de Jong <mj...@ma...> * @copyright Copyright (c) 2011 Erasmus MC * @license New BSD License + * @version $Id$ */ /** * Static Gems cookie utilities - * - * @author Matijs de Jong + * * @package Gems * @subpackage Cookies * @copyright Copyright (c) 2011 Erasmus MC * @license New BSD License + * @since Class available since version 1.0 */ class Gems_Cookies { const LOCALE_COOKIE = 'gems_locale'; - public static function get(Zend_Controller_Request_Abstract $request, $name) + /** + * Get a specific cookie from the request. + * + * @param Zend_Controller_Request_Abstract $request + * @param string $name + * @param mixed $default + * @return mixed Cookie value + */ + public static function get(Zend_Controller_Request_Abstract $request, $name, $default = null) { - return $request->getCookie($name); + return $request->getCookie($name, $default); } + /** + * Get the current locale from the cookie. + * + * @param Zend_Controller_Request_Abstract $request + * @return string The current locale + */ public static function getLocale(Zend_Controller_Request_Abstract $request) { return self::get($request, self::LOCALE_COOKIE); } + /** + * Store this cookie in a generic save method that works for both sub-directory + * installations and own url installations. + * + * @param string $name Name of the cookie + * @param mixed $value Value to set + * @param int $days Number of days to keep this cookie + * @param string $basepath The folder of the domain, if any. + * @return boolean True if the cookie was stored. + */ public static function set($name, $value, $days = 30, $basepath = '/') { // Gems uses the empty string when the base path is '/' @@ -69,6 +92,13 @@ return setcookie($name, $value, time() + ($days * 86400), $basepath); } + /** + * Store the locale in a cookie. + * + * @param string $locale Locale to store + * @param string $basepath The folder of the domain, if any. + * @return boolean True if the cookie was stored. + */ public static function setLocale($locale, $basepath = '/') { // Set the cookie for 30 days Modified: branches/newUser/classes/Gems/Default/IndexAction.php =================================================================== --- trunk/library/classes/Gems/Default/IndexAction.php 2011-10-17 13:51:03 UTC (rev 112) +++ branches/newUser/classes/Gems/Default/IndexAction.php 2011-10-18 16:35:34 UTC (rev 113) @@ -92,6 +92,21 @@ $form->setMethod('post'); $form->setDescription(sprintf($this->_('Login to %s application'), $this->project->name)); + if ($this->escort instanceof Gems_Project_Organization_SingleOrganizationInterface) { + $element = new Zend_Form_Element_Hidden('organization'); + $element->setValue($this->escort->getRespondentOrganization()); + } else { + $element = new Zend_Form_Element_Select('organization'); + $element->setLabel($this->_('Organization')); + $element->setMultiOptions($this->util->getDbLookup()->getOrganizations()); + $element->setRequired(true); + + if (! $this->_request->isPost()) { + $element->setValue($this->escort->getCurrentOrganization()); + } + } + $form->addElement($element); + // Veld inlognaam $element = new Zend_Form_Element_Text('userlogin'); $element->setLabel($this->_('Username')); @@ -130,7 +145,7 @@ return $form; } - // Dummy: always rerouted by Gems + // Dummy: always rerouted by GemsEscort public function indexAction() { } public function loginAction() @@ -138,11 +153,17 @@ if (isset($this->session->user_id)) { $this->_reroute(array('controller' => 'respondent')); } + // MUtil_Echo::track(get_class($this->loader->getUser('super', null))); $form = $this->_getLoginForm(); if ($this->_request->isPost()) { if ($form->isValid($_POST, false)) { + /* + if ($user = $this->loader->getUser($_POST['userlogin'], $_POST['organization'])) { + + } // */ + if (isset($this->project->admin) && $this->project->admin['user'] == $_POST['userlogin'] && $this->project->admin['pwd'] == $_POST['password']) { $this->session->user_id = 2000; $this->session->user_name = $_POST['userlogin']; Modified: branches/newUser/classes/Gems/Loader/LoaderAbstract.php =================================================================== --- trunk/library/classes/Gems/Loader/LoaderAbstract.php 2011-10-17 13:51:03 UTC (rev 112) +++ branches/newUser/classes/Gems/Loader/LoaderAbstract.php 2011-10-18 16:35:34 UTC (rev 113) @@ -154,7 +154,7 @@ { // echo '_loadClassPath: ' . $this->cascade . '-' . $classname . '-' . ($create ? 1 : 0) . "<br/>\n"; // debug_print_backtrace(); - // MUtil_Echo::r($filepath, $classname, $this->cascade); + // MUtil_Echo::track($filepath, $classname, $this->cascade); if (file_exists($filepath)) { if (! class_exists($classname)) { Modified: branches/newUser/classes/Gems/Loader.php =================================================================== --- trunk/library/classes/Gems/Loader.php 2011-10-17 13:51:03 UTC (rev 112) +++ branches/newUser/classes/Gems/Loader.php 2011-10-18 16:35:34 UTC (rev 113) @@ -90,6 +90,12 @@ /** * + * @var Gems_User_UserLoader + */ + protected $userLoader; + + /** + * * @var Gems_Util */ protected $util; @@ -177,6 +183,28 @@ /** * + * @param string $login_name + * @param int $organization Only used when more than one organization uses this $login_name + * @return Gems_User_UserInterface + */ + public function getUser($login_name, $organization) + { + $loader = $this->getUserLoader(); + + return $loader->getUser($login_name, $organization); + } + + /** + * + * @return Gems_User_UserLoader + */ + protected function getUserLoader() + { + return $this->_getClass('userLoader', 'User_UserLoader'); + } + + /** + * * @return Gems_Util */ public function getUtil() Modified: branches/newUser/classes/GemsEscort.php =================================================================== --- trunk/library/classes/GemsEscort.php 2011-10-17 13:51:03 UTC (rev 112) +++ branches/newUser/classes/GemsEscort.php 2011-10-18 16:35:34 UTC (rev 113) @@ -207,7 +207,7 @@ * * Use $this->acl to access afterwards * - * @return Zend_View + * @return MUtil_Acl */ protected function _initAcl() { Modified: branches/newUser/configs/db/patches.sql =================================================================== --- trunk/library/configs/db/patches.sql 2011-10-17 13:51:03 UTC (rev 112) +++ branches/newUser/configs/db/patches.sql 2011-10-18 16:35:34 UTC (rev 113) @@ -203,4 +203,14 @@ -- PATCH: Assign maintenance mode toggle to super role UPDATE gems__roles SET grl_privileges = CONCAT(grl_privileges,',pr.maintenance') WHERE grl_name = 'super' AND grl_privileges NOT LIKE '%pr.maintenance%'; --- GEMS VERSION: 42 \ No newline at end of file +-- GEMS VERSION: 42 +-- PATCH: New user login structure +INSERT INTO gems__users (gsu_id_user, gsu_login, gsu_id_organization, gsu_user_class, gsu_active, + gsu_password, gsu_failed_logins, gsu_last_failed, gsu_reset_key, gsu_reset_requested, gsu_reset_required, + gsu_changed, gsu_changed_by, gsu_created, gsu_created_by) + SELECT grs_id_user, gr2o_patient_nr, gr2o_id_organization, 'RespondentUser', CASE WHEN gr2o_reception_code = 'OK' THEN 1 ELSE 0 END, + NULL, 0, NULL, NULL, NULL, 0, + gr2o_changed, gr2o_changed_by, gr2o_created, gr2o_created_by + FROM gems__respondents INNER JOIN gems__respondent2org ON grs_id_user = gr2o_id_user + INNER JOIN gems__organizations ON gr2o_id_organization = gor_id_organization + WHERE gor_name = 'HCU / Xpert Clinic'; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <gem...@li...> - 2011-11-03 17:45:42
|
Revision: 175 http://gemstracker.svn.sourceforge.net/gemstracker/?rev=175&view=rev Author: matijsdejong Date: 2011-11-03 17:45:34 +0000 (Thu, 03 Nov 2011) Log Message: ----------- Modified Paths: -------------- branches/newUser2/classes/Gems/Auth.php branches/newUser2/classes/Gems/Default/CronAction.php branches/newUser2/classes/Gems/Default/IndexAction.php branches/newUser2/classes/Gems/Default/OptionAction.php branches/newUser2/classes/Gems/Default/RespondentAction.php branches/newUser2/classes/Gems/Default/StaffAction.php branches/newUser2/classes/Gems/Default/SurveyMaintenanceAction.php branches/newUser2/classes/Gems/Default/TokenPlanAction.php branches/newUser2/classes/Gems/Loader/LoaderAbstract.php branches/newUser2/classes/Gems/Loader.php branches/newUser2/classes/Gems/Menu/MenuAbstract.php branches/newUser2/classes/Gems/Model/UserModel.php branches/newUser2/classes/Gems/Model.php branches/newUser2/classes/Gems/Project/ProjectSettings.php branches/newUser2/classes/Gems/User/RespondentUser.php branches/newUser2/classes/Gems/User/StaffUser.php branches/newUser2/classes/Gems/User/UserLoader.php branches/newUser2/classes/Gems/Util/DbLookup.php branches/newUser2/classes/Gems/Validate/GemsPasswordUsername.php branches/newUser2/classes/GemsEscort.php branches/newUser2/classes/MUtil/Registry/Source.php branches/newUser2/configs/db/patches.sql branches/newUser2/configs/db/tables/gems__organizations.20.sql branches/newUser2/configs/db/tables/gems__staff.20.sql branches/newUser2/configs/db/tables/gems__users.10.sql Added Paths: ----------- branches/newUser2/ branches/newUser2/configs/db/tables/gems__user_ids.10.sql branches/newUser2/configs/db/tables/gems__user_logins.10.sql branches/newUser2/configs/db/tables/gems__user_passwords.50.sql Removed Paths: ------------- branches/newUser2/configs/db_multi_layout/ Property changes on: branches/newUser2 ___________________________________________________________________ Added: svn:mergeinfo + /branches/newUser:113-150 Modified: branches/newUser2/classes/Gems/Auth.php =================================================================== --- trunk/library/classes/Gems/Auth.php 2011-11-03 17:40:33 UTC (rev 174) +++ branches/newUser2/classes/Gems/Auth.php 2011-11-03 17:45:34 UTC (rev 175) @@ -98,8 +98,8 @@ * Lookup last failed login and number of failed logins */ try { - $sql = "SELECT gsu_failed_logins, UNIX_TIMESTAMP(gsu_last_failed) - AS gsu_last_failed FROM gems__users WHERE gsu_login = ?"; + $sql = "SELECT gus_failed_logins, UNIX_TIMESTAMP(gus_last_failed) + AS gus_last_failed FROM gems__users WHERE gus_login = ?"; $results = $this->db->fetchRow($sql, array($username)); } catch (Zend_Db_Exception $zde) { //If we need to apply a db patch, just use a default value @@ -107,10 +107,10 @@ MUtil_Echo::r(GemsEscort::getInstance()->translate->_('Please update the database')); } - $delay = pow($results['gsu_failed_logins'], $this->_delayFactor); - $remaining = ($results['gsu_last_failed'] + $delay) - time(); + $delay = pow($results['gus_failed_logins'], $this->_delayFactor); + $remaining = ($results['gus_last_failed'] + $delay) - time(); - if ($results['gsu_failed_logins'] > 0 && $remaining > 0) { + if ($results['gus_failed_logins'] > 0 && $remaining > 0) { //$this->_obscureValue = false; $result = $this->_error(self::ERROR_PASSWORD_DELAY, ceil($remaining / 60)); } Modified: branches/newUser2/classes/Gems/Default/CronAction.php =================================================================== --- trunk/library/classes/Gems/Default/CronAction.php 2011-11-03 17:40:33 UTC (rev 174) +++ branches/newUser2/classes/Gems/Default/CronAction.php 2011-11-03 17:45:34 UTC (rev 175) @@ -125,7 +125,7 @@ */ protected function getUserLogin($userId) { - return $this->db->fetchOne("SELECT gsu_login FROM gems__users WHERE gsu_id_user = ?", $userId); + return $this->db->fetchOne("SELECT gus_login FROM gems__users WHERE gus_id_user = ?", $userId); } public function indexAction() Modified: branches/newUser2/classes/Gems/Default/IndexAction.php =================================================================== --- trunk/library/classes/Gems/Default/IndexAction.php 2011-11-03 17:40:33 UTC (rev 174) +++ branches/newUser2/classes/Gems/Default/IndexAction.php 2011-11-03 17:45:34 UTC (rev 175) @@ -74,7 +74,7 @@ * @return Zend_Auth_Adapter_Interface */ protected function _getAuthAdapter($formValues) { - $adapter = new Zend_Auth_Adapter_DbTable($this->db, 'gems__users', 'gsu_login', 'gsu_password'); + $adapter = new Zend_Auth_Adapter_DbTable($this->db, 'gems__users', 'gus_login', 'gus_password'); $adapter->setIdentity($formValues['userlogin']); $adapter->setCredential($this->escort->passwordHash(null, $formValues['password'], false)); return $adapter; @@ -203,7 +203,7 @@ $result = $auth->authenticate($adapter, $_POST['userlogin']); // Allow login using old password. - if ((! $result->isValid()) && ($userid = $this->db->fetchOne("SELECT gsu_id_user FROM gems__users WHERE gsu_active = 1 AND gsu_password IS NULL AND gsu_login = ?", $_POST['userlogin']))) { + if ((! $result->isValid()) && ($userid = $this->db->fetchOne("SELECT gus_id_user FROM gems__users WHERE gus_active = 1 AND gus_password IS NULL AND gus_login = ?", $_POST['userlogin']))) { $adapter = new Zend_Auth_Adapter_DbTable($this->db, 'gems__staff', 'gsf_id_user', 'gsf_password'); $adapter->setIdentity($userid); @@ -309,19 +309,19 @@ } if ($this->_request->isPost() && $form->isValid($_POST)) { - $sql = $this->db->quoteInto("SELECT gsu_id_user, gsf_email, gsu_reset_key, DATEDIFF(NOW(), gsu_reset_requested) AS gsf_days FROM gems__users INNER JOIN gems__staff ON gsu_id_user = gsf_id_user WHERE gsu_login = ?", $_POST['userlogin']); + $sql = $this->db->quoteInto("SELECT gus_id_user, gsf_email, gus_reset_key, DATEDIFF(NOW(), gus_reset_requested) AS gsf_days FROM gems__users INNER JOIN gems__staff ON gus_id_user = gsf_id_user WHERE gus_login = ?", $_POST['userlogin']); $result = $this->db->fetchRow($sql); if (empty($result) || empty($result['gsf_email'])) { $this->addMessage($this->_('No such user found or no e-mail address known')); - } else if (!empty($result['gsu_reset_key']) && $result['gsf_days'] < 1) { + } else if (!empty($result['gus_reset_key']) && $result['gsf_days'] < 1) { $this->addMessage($this->_('Reset e-mail already sent, please try again after 24 hours')); } else { $email = $result['gsf_email']; $key = md5(time() . $email); $url = $this->util->getCurrentURI('index/resetpassword/key/' . $key); - $this->db->update('gems__users', array('gsu_reset_key' => $key, 'gsu_reset_requested' => new Zend_Db_Expr('NOW()')), 'gsu_id_user = ' . $result['gsu_id_user']); + $this->db->update('gems__users', array('gus_reset_key' => $key, 'gus_reset_requested' => new Zend_Db_Expr('NOW()')), 'gus_id_user = ' . $result['gus_id_user']); $mail->setSubject('Password reset requested'); $mail->setBodyText('To reset your password, please click this link: ' . $url); @@ -337,7 +337,7 @@ } } } else if ($key = $this->_request->getParam('key')) { - $sql = $this->db->quoteInto("SELECT gsu_id_user, gsf_email FROM gems__users INNER JOIN gems__staff ON gsu_id_user = gsf_id_user WHERE gsu_reset_key = ?", $key); + $sql = $this->db->quoteInto("SELECT gus_id_user, gsf_email FROM gems__users INNER JOIN gems__staff ON gus_id_user = gsf_id_user WHERE gus_reset_key = ?", $key); $result = $this->db->fetchRow($sql); if (!empty($result)) { @@ -353,7 +353,7 @@ try { $mail->send(); $this->addMessage($this->_('An e-mail was sent containing your new password')); - $this->db->update('gems__users', array('gsu_reset_key' => new Zend_Db_Expr('NULL'), 'gsu_reset_requested' => new Zend_Db_Expr('NULL'), 'gsu_password' => $passwordHash), 'gsu_id_user = ' . $result['gsu_id_user']); + $this->db->update('gems__users', array('gus_reset_key' => new Zend_Db_Expr('NULL'), 'gus_reset_requested' => new Zend_Db_Expr('NULL'), 'gus_password' => $passwordHash), 'gus_id_user = ' . $result['gus_id_user']); $this->_reroute(array('action' => 'index'), true); } catch (Exception $e) { $this->addMessage($this->_('Unable to send e-mail')); Modified: branches/newUser2/classes/Gems/Default/OptionAction.php =================================================================== --- trunk/library/classes/Gems/Default/OptionAction.php 2011-11-03 17:40:33 UTC (rev 174) +++ branches/newUser2/classes/Gems/Default/OptionAction.php 2011-11-03 17:45:34 UTC (rev 175) @@ -61,10 +61,10 @@ */ protected function addFormElements(MUtil_Model_FormBridge $bridge, MUtil_Model_ModelAbstract $model, array $data, $new = false) { - $bridge->addHidden( 'gsu_id_user'); - $bridge->addHidden( 'gsu_id_organization'); + $bridge->addHidden( 'gus_id_user'); + $bridge->addHidden( 'gus_id_organization'); $bridge->addHidden( 'gsf_id_user'); - $bridge->addExhibitor('gsu_login', array('size' => 15, 'minlength' => 4)); + $bridge->addExhibitor('gus_login', array('size' => 15, 'minlength' => 4)); $bridge->addText( 'gsf_first_name'); $bridge->addText( 'gsf_surname_prefix'); $bridge->addText( 'gsf_last_name'); @@ -77,7 +77,7 @@ public function afterSave(array $data, $isNew) { - $this->escort->loadLoginInfo($data['gsu_login']); + $this->escort->loadLoginInfo($data['gus_login']); } public function changePasswordAction() @@ -87,7 +87,7 @@ *************/ $form = $this->createForm(); - $sql = "SELECT CASE WHEN gsu_password IS NULL THEN 0 ELSE 1 END FROM gems__users WHERE gsu_id_user = ? AND gsu_id_organization = ?"; + $sql = "SELECT CASE WHEN gus_password IS NULL THEN 0 ELSE 1 END FROM gems__users WHERE gus_id_user = ? AND gus_id_organization = ?"; if ($this->db->fetchOne($sql, array($this->session->user_id, $this->session->user_organization_id))) { // Veld current password $element = new Zend_Form_Element_Password('old_password'); @@ -131,9 +131,9 @@ ****************/ if ($this->_request->isPost() && $form->isValid($_POST)) { - $data['gsu_id_user'] = $this->session->user_id; - $data['gsu_id_organization'] = $this->session->user_organization_id; - $data['gsu_password'] = $this->escort->passwordHash(null, $_POST['new_password']); + $data['gus_id_user'] = $this->session->user_id; + $data['gus_id_organization'] = $this->session->user_organization_id; + $data['gus_password'] = $this->escort->passwordHash(null, $_POST['new_password']); $this->getModel()->save($data); @@ -185,10 +185,10 @@ */ public function createModel($detailed, $action) { - $model = new Gems_Model_UserModel('staff', 'gems__staff', array('gsu_id_user' => 'gsf_id_user'), 'gsf'); + $model = new Gems_Model_UserModel('staff', 'gems__staff', array('gus_id_user' => 'gsf_id_user'), 'gsf'); $model->copyKeys(); - $model->set('gsu_login', 'label', $this->_('Login Name')); + $model->set('gus_login', 'label', $this->_('Login Name')); $model->set('gsf_email', 'label', $this->_('E-Mail')); $model->set('gsf_first_name', 'label', $this->_('First name')); $model->set('gsf_surname_prefix', 'label', $this->_('Surname prefix'), 'description', 'de, van der, \'t, etc...'); @@ -201,7 +201,7 @@ public function editAction() { - $this->getModel()->setFilter(array('gsu_id_user' => $this->session->user_id)); + $this->getModel()->setFilter(array('gus_id_user' => $this->session->user_id)); if ($form = $this->processForm()) { $this->html->h3(sprintf($this->_('Options'), $this->getTopic())); Modified: branches/newUser2/classes/Gems/Default/RespondentAction.php =================================================================== --- trunk/library/classes/Gems/Default/RespondentAction.php 2011-11-03 17:40:33 UTC (rev 174) +++ branches/newUser2/classes/Gems/Default/RespondentAction.php 2011-11-03 17:45:34 UTC (rev 175) @@ -326,8 +326,8 @@ $values = $this->db->fetchPairs(" SELECT gsf_id_user, CONCAT(gsf_last_name, ', ', COALESCE(CONCAT(gsf_first_name, ' '), ''), COALESCE(gsf_surname_prefix, '')) AS name - FROM (gems__users INNER JOIN gems__staff ON gsu_id_user = gsf_id_user) INNER JOIN gems__groups ON gsf_id_primary_group = ggp_id_group - WHERE gsu_active=1 AND gsu_id_organization = ? AND ggp_role = 'physician' + FROM (gems__users INNER JOIN gems__staff ON gus_id_user = gsf_id_user) INNER JOIN gems__groups ON gsf_id_primary_group = ggp_id_group + WHERE gus_active=1 AND gus_id_organization = ? AND ggp_role = 'physician' ORDER BY 2", $organizationId); $session->physicians = $values; Modified: branches/newUser2/classes/Gems/Default/StaffAction.php =================================================================== --- trunk/library/classes/Gems/Default/StaffAction.php 2011-11-03 17:40:33 UTC (rev 174) +++ branches/newUser2/classes/Gems/Default/StaffAction.php 2011-11-03 17:45:34 UTC (rev 175) @@ -44,7 +44,7 @@ */ class Gems_Default_StaffAction extends Gems_Controller_BrowseEditAction { - public $filterStandard = array('gsu_active' => 1); + public $filterStandard = array('gus_active' => 1); public $sortKey = array('name' => SORT_ASC); protected $_instanceId; @@ -96,28 +96,28 @@ if ($new) { $model->set('gsf_id_primary_group', 'default', $dbLookup->getDefaultGroup()); } else { - $model->set('gsu_password', 'description', $this->_('Enter only when changing')); - $model->setSaveWhenNotNull('gsu_password'); + $model->set('gus_password', 'description', $this->_('Enter only when changing')); + $model->setSaveWhenNotNull('gus_password'); } - $model->setOnSave('gsu_password', array($this->escort, 'passwordHash')); + $model->setOnSave('gus_password', array($this->escort, 'passwordHash')); $ucfirst = new Zend_Filter_Callback('ucfirst'); - $bridge->addHidden( 'gsu_id_user'); + $bridge->addHidden( 'gus_id_user'); $bridge->addHidden( 'gsf_id_user'); // Needed for e-mail validation - $bridge->addHidden( 'gsu_user_class'); - $bridge->addText( 'gsu_login', 'size', 15, 'minlength', 4, - 'validator', $model->createUniqueValidator('gsu_login')); + $bridge->addHidden( 'gus_user_class'); + $bridge->addText( 'gus_login', 'size', 15, 'minlength', 4, + 'validator', $model->createUniqueValidator('gus_login')); // Can the organization be changed? if ($this->escort->hasPrivilege('pr.staff.edit.all')) { - $bridge->addHiddenMulti($model->getKeyCopyName('gsu_id_organization')); - $bridge->addSelect('gsu_id_organization'); + $bridge->addHiddenMulti($model->getKeyCopyName('gus_id_organization')); + $bridge->addSelect('gus_id_organization'); } else { - $bridge->addExhibitor('gsu_id_organization'); + $bridge->addExhibitor('gus_id_organization'); } - $bridge->addPassword('gsu_password', + $bridge->addPassword('gus_password', 'label', $this->_('Password'), 'minlength', $this->project->passwords['MinimumLength'], // 'renderPassword', true, @@ -141,15 +141,15 @@ public function afterFormLoad(array &$data, $isNew) { - if (array_key_exists('gsu_login', $data)) { - $this->_instanceId = $data['gsu_login']; + if (array_key_exists('gus_login', $data)) { + $this->_instanceId = $data['gus_login']; } $sql = "SELECT ggp_id_group,ggp_role FROM gems__groups WHERE ggp_id_group = " . (int) $data['gsf_id_primary_group']; $groups = $this->db->fetchPairs($sql); if (! ($this->escort->hasPrivilege('pr.staff.edit.all') || - $data['gsu_id_organization'] == $this->escort->getCurrentOrganization())) { + $data['gus_id_organization'] == $this->escort->getCurrentOrganization())) { throw new Zend_Exception($this->_('You are not allowed to edit this staff member.')); } } @@ -169,21 +169,22 @@ { // MUtil_Model::$verbose = true; - $model = new Gems_Model_UserModel('staff', 'gems__staff', array('gsu_id_user' => 'gsf_id_user'), 'gsf'); + /* $model = new Gems_Model_UserModel('staff', 'gems__staff', array('gus_id_user' => 'gsf_id_user'), 'gsf'); if ($detailed) { $model->copyKeys(); } - //$model->resetOrder(); + //$model->resetOrder(); */ + $model = $this->loader->getModels()->getStaffModel(); - $model->set('gsu_login', 'label', $this->_('Login')); + $model->set('gus_login', 'label', $this->_('Login')); $model->set('name', 'label', $this->_('Name'), 'column_expression', "CONCAT(COALESCE(CONCAT(gsf_last_name, ', '), '-, '), COALESCE(CONCAT(gsf_first_name, ' '), ''), COALESCE(gsf_surname_prefix, ''))"); $model->set('gsf_email', 'label', $this->_('E-Mail'), 'itemDisplay', 'MUtil_Html_AElement::ifmail'); if ($detailed || $this->escort->hasPrivilege('pr.staff.see.all')) { - $this->menu->getParameterSource()->offsetSet('gsu_id_organization', $this->escort->getCurrentOrganization()); + $this->menu->getParameterSource()->offsetSet('gus_id_organization', $this->escort->getCurrentOrganization()); - $model->set('gsu_id_organization', 'label', $this->_('Organization'), + $model->set('gus_id_organization', 'label', $this->_('Organization'), 'multiOptions', $this->util->getDbLookup()->getOrganizations(), 'default', $this->escort->getCurrentOrganization()); } @@ -192,12 +193,12 @@ $model->set('gsf_gender', 'label', $this->_('Gender'), 'multiOptions', $this->util->getTranslated()->getGenders()); if ($detailed) { - $model->set('gsu_user_class', 'default', 'StaffUser'); + $model->set('gus_user_class', 'default', Gems_User_UserLoader::USER_STAFF); $model->set('gsf_iso_lang', 'label', $this->_('Language'), 'multiOptions', $this->util->getLocalized()->getLanguages()); $model->set('gsf_logout_on_survey', 'label', $this->_('Logout on survey'), 'multiOptions', $this->util->getTranslated()->getYesNo()); } - $model->setDeleteValues('gsu_active', 0); + $model->setDeleteValues('gus_active', 0); return $model; } @@ -208,8 +209,8 @@ if ($this->escort->hasPrivilege('pr.staff.see.all')) { // Select organization - $options = array('' => $this->_('(all organizations)')) + $this->getModel()->get('gsu_id_organization', 'multiOptions'); - $select = new Zend_Form_Element_Select('gsu_id_organization', array('multiOptions' => $options)); + $options = array('' => $this->_('(all organizations)')) + $this->getModel()->get('gus_id_organization', 'multiOptions'); + $select = new Zend_Form_Element_Select('gus_id_organization', array('multiOptions' => $options)); // Position as second element $search = array_shift($elements); @@ -234,7 +235,7 @@ $filter = parent::getDataFilter($data); if (! $this->escort->hasPrivilege('pr.staff.see.all')) { - $filter['gsu_id_organization'] = $this->escort->getCurrentOrganization(); + $filter['gus_id_organization'] = $this->escort->getCurrentOrganization(); } return $filter; } @@ -264,8 +265,8 @@ // Model filter has now been set. $data = $this->getModel()->loadFirst(); - $this->_setParam('gsu_id_organization', $data['gsu_id_organization']); - $this->menu->getParameterSource()->offsetSet('gsu_id_organization', $data['gsu_id_organization']); + $this->_setParam('gus_id_organization', $data['gus_id_organization']); + $this->menu->getParameterSource()->offsetSet('gus_id_organization', $data['gus_id_organization']); } return parent::getShowTable($columns, $filter, $sort); } Modified: branches/newUser2/classes/Gems/Default/SurveyMaintenanceAction.php =================================================================== --- trunk/library/classes/Gems/Default/SurveyMaintenanceAction.php 2011-11-03 17:40:33 UTC (rev 174) +++ branches/newUser2/classes/Gems/Default/SurveyMaintenanceAction.php 2011-11-03 17:45:34 UTC (rev 175) @@ -318,7 +318,7 @@ // Hence the unexpected order of the tables in the JoinModel. $model = new Gems_Model_JoinModel('surveys', 'gems__tracks'); $model->addTable('gems__rounds', array('gro_id_track' => 'gtr_id_track', 'gtr_track_type' => new Zend_Db_Expr("'S'"))); - $model->addRightTable('gems__surveys', array('gsu_id_survey' => 'gro_id_survey'), 'gsu'); + $model->addRightTable('gems__surveys', array('gsu_id_survey' => 'gro_id_survey'), 'gus'); $model->addTable('gems__sources', array('gsu_id_source'=>'gso_id_source')); $model->setKeysToTable('gems__surveys'); @@ -330,9 +330,8 @@ $model->addColumn(new Zend_Db_Expr('NULL'), 'create_stand_alone'); } } else { - $model = new Gems_Model_JoinModel('surveys', 'gems__surveys', 'gsu'); + $model = new Gems_Model_JoinModel('surveys', 'gems__surveys', 'gus'); $model->addTable('gems__sources', array('gsu_id_source'=>'gso_id_source')); - } $model->addColumn( Modified: branches/newUser2/classes/Gems/Default/TokenPlanAction.php =================================================================== --- trunk/library/classes/Gems/Default/TokenPlanAction.php 2011-11-03 17:40:33 UTC (rev 174) +++ branches/newUser2/classes/Gems/Default/TokenPlanAction.php 2011-11-03 17:45:34 UTC (rev 175) @@ -351,7 +351,7 @@ COALESCE(gems__staff.gsf_first_name, ''), COALESCE(CONCAT(' ', gems__staff.gsf_surname_prefix), '') ) AS gsf_name - FROM (gems__users INNER JOIN gems__staff ON gsu_id_user = gsf_id_user) INNER JOIN gems__respondent2track ON gsu_id_user = gr2t_created_by + FROM (gems__users INNER JOIN gems__staff ON gus_id_user = gsf_id_user) INNER JOIN gems__respondent2track ON gus_id_user = gr2t_created_by WHERE gr2t_id_organization = $orgId AND gsu_active = 1 AND gr2t_active = 1"; Modified: branches/newUser2/classes/Gems/Loader/LoaderAbstract.php =================================================================== --- trunk/library/classes/Gems/Loader/LoaderAbstract.php 2011-11-03 17:40:33 UTC (rev 174) +++ branches/newUser2/classes/Gems/Loader/LoaderAbstract.php 2011-11-03 17:45:34 UTC (rev 175) @@ -84,7 +84,7 @@ /** * - * @param type $container A container acting as source fro MUtil_Registry_Source + * @param mixed $container A container acting as source for MUtil_Registry_Source * @param array $dirs The directories where to look for requested classes */ public function __construct($container, array $dirs) Modified: branches/newUser2/classes/Gems/Loader.php =================================================================== --- trunk/library/classes/Gems/Loader.php 2011-11-03 17:40:33 UTC (rev 174) +++ branches/newUser2/classes/Gems/Loader.php 2011-11-03 17:45:34 UTC (rev 175) @@ -119,6 +119,17 @@ /** * + * @return Gems_User_User + */ + public function getCurrentUser($login_name, $organization) + { + $loader = $this->getUserLoader(); + + return $loader->getCurrentUser(); + } + + /** + * * @return gems_Events */ public function getEvents() @@ -184,8 +195,8 @@ /** * * @param string $login_name - * @param int $organization Only used when more than one organization uses this $login_name - * @return Gems_User_UserAbstract + * @param int $organization + * @return Gems_User_User */ public function getUser($login_name, $organization) { Modified: branches/newUser2/classes/Gems/Menu/MenuAbstract.php =================================================================== --- trunk/library/classes/Gems/Menu/MenuAbstract.php 2011-11-03 17:40:33 UTC (rev 174) +++ branches/newUser2/classes/Gems/Menu/MenuAbstract.php 2011-11-03 17:45:34 UTC (rev 175) @@ -385,8 +385,8 @@ $editPage = $page->addEditAction()->setModelParameters(2); $delPage = $page->addDeleteAction()->setModelParameters(2); if (! $this->escort->hasPrivilege('pr.staff.edit.all')) { - $editPage->setParameterFilter('gsu_id_organization', $this->escort->getCurrentOrganization()); - $delPage->setParameterFilter('gsu_id_organization', $this->escort->getCurrentOrganization()); + $editPage->setParameterFilter('gus_id_organization', $this->escort->getCurrentOrganization()); + $delPage->setParameterFilter('gus_id_organization', $this->escort->getCurrentOrganization()); } return $page; Modified: branches/newUser2/classes/Gems/Model/UserModel.php =================================================================== --- trunk/library/classes/Gems/Model/UserModel.php 2011-11-03 17:40:33 UTC (rev 174) +++ branches/newUser2/classes/Gems/Model/UserModel.php 2011-11-03 17:45:34 UTC (rev 175) @@ -67,7 +67,7 @@ parent::__construct($name, 'gems__users', (null === $saveable ? $fieldPrefix : $saveable)); if ($fieldPrefix) { - Gems_Model::setChangeFieldsByPrefix($this, 'gsu'); + Gems_Model::setChangeFieldsByPrefix($this, 'gus'); } if ($secondTable) { @@ -94,7 +94,7 @@ // Make it a number $out = intval($out); - } while ($db->fetchOne('SELECT gsu_id_user FROM gems__users WHERE gsu_id_user = ?', $out)); + } while ($db->fetchOne('SELECT gus_id_user FROM gems__users WHERE gus_id_user = ?', $out)); return $out; } @@ -109,9 +109,9 @@ */ public function save(array $newValues, array $filter = null, array $saveTables = null) { - if (! (isset($newValues['gsu_id_user']) && $newValues['gsu_id_user'])) { + if (! (isset($newValues['gus_id_user']) && $newValues['gus_id_user'])) { // Load a new user id if needed - $newValues['gsu_id_user'] = $this->_createUserId(); + $newValues['gus_id_user'] = $this->_createUserId(); } return parent::save($newValues, $filter, $saveTables); Modified: branches/newUser2/classes/Gems/Model.php =================================================================== --- trunk/library/classes/Gems/Model.php 2011-11-03 17:40:33 UTC (rev 174) +++ branches/newUser2/classes/Gems/Model.php 2011-11-03 17:45:34 UTC (rev 175) @@ -61,28 +61,99 @@ /** * + * @var Zend_Db_Adapter_Abstract + */ + protected $db; + + /** + * * @var Gems_Loader */ protected $loader; /** + * Field name in respondent model containing the login id. + * + * @var string + */ + public $respondentLoginIdField = 'gr2o_patient_nr'; + + /** * @var Zend_Translate */ protected $translate; /** + * The length of a user id. + * + * @var int + */ + protected $userIdLen = 8; + + /** * @var Gems_Util */ protected $util; /** + * Function that automatically fills changed, changed_by, created and created_by fields with a certain prefix. + * + * @param Gems_Model_JoinModel $model + * @param string $loginField Field that links to login field. + * @param string $organizationField Field that links to the organization field. + */ + public function addAsUserLogin(Gems_Model_JoinModel $model, $loginField, $organizationField) + { + $model->addTable('gems__user_logins', array($loginField => 'gul_login', $organizationField => 'gul_id_organization'), 'gul'); + } + + /** + * Create a Gems project wide unique user id + * + * @param string $name + * @param mixed $value + * @param boolean $isNew + * @return int + */ + public function createGemsUserId($name, $value, $isNew) + { + if ($isNew || (null === $value)) { + $creationTime = new Zend_Db_Expr('CURRENT_TIMESTAMP'); + + do { + $out = mt_rand(1, 9); + for ($i = 1; $i < $this->userIdLen; $i++) { + $out .= mt_rand(0, 9); + } + // Make it a number + $out = intval($out); + + try { + if (0 === $this->db->insert('gems__user_logins', array('gui_id_user' => $out, 'gui_created' => $creationTime))) { + $out = null; + } + } catch (Zend_Db_Exception $e) { + $out = null; + } + } while (null === $out); + + return $out; + } + } + + /** * Load project specific model or general Gems model otherwise * * @return Gems_Model_RespondentModel */ public function createRespondentModel() { - return $this->_loadClass('RespondentModel', true); + $model = $this->_loadClass('RespondentModel', true); + + $this->addAsUserLogin($model, $this->respondentLoginIdField, 'gr2o_id_organization'); + $this->setAsGemsUserId($model, 'grs_id_user'); + + return $model; } /** @@ -133,7 +204,32 @@ return $model; } + public function getStaffModel() + { + $model = new Gems_Model_JoinModel('staff', 'gems__staff', 'gsf'); + + $this->addAsUserLogin($model, 'gsf_login', 'gsf_id_organization'); + $this->setAsGemsUserId($model, 'gsf_id_user'); + + return $model; + } + /** + * Set a field in this model as a gems unique user id + * + * @param MUtil_Model_DatabaseModelAbstract $model + * @param string $idField Field that uses global id. + */ + public function setAsGemsUserId(MUtil_Model_DatabaseModelAbstract $model, $idField) + { + // Make sure field is added to save when not there + $model->setAutoSave($idField); + + // Make sure the fields get a userid when empty + $model->setOnSave($idField, array($this, 'createGemsUserId')); + } + + /** * Function that automatically fills changed, changed_by, created and created_by fields with a certain prefix. * * @param MUtil_Model_DatabaseModelAbstract $model Modified: branches/newUser2/classes/Gems/Project/ProjectSettings.php =================================================================== --- trunk/library/classes/Gems/Project/ProjectSettings.php 2011-11-03 17:40:33 UTC (rev 174) +++ branches/newUser2/classes/Gems/Project/ProjectSettings.php 2011-11-03 17:45:34 UTC (rev 175) @@ -47,6 +47,14 @@ class Gems_Project_ProjectSettings extends ArrayObject { /** + * The minimum length for the password of a super admin + * on a production server. + * + * @var int + */ + protected $minimumSuperPasswordLength = 10; + + /** * Array of required keys. Give a string value for root keys * or name => array() values for required subs keys. * @@ -123,6 +131,14 @@ throw new Gems_Exception_Coding($error); } + $superPassword = $this->getSuperAdminPassword(); + if ((APPLICATION_ENV === 'production') && $this->getSuperAdminName() && $superPassword) { + if (strlen($superPassword) < $this->minimumSuperPasswordLength) { + $error = sprintf("Project setting 'admin.pwd' is shorter than %d characters. That is not allowed.", $this->minimumSuperPasswordLength); + throw new Gems_Exception_Coding($error); + } + } + if (! ($this->offsetExists('name') && $this->offsetGet('name'))) { $this->offsetSet('name', GEMS_PROJECT_NAME); } @@ -131,6 +147,30 @@ } /** + * Returns the super admin name, if any + * + * @return string + */ + public function getSuperAdminName() + { + if (isset($this->admin['user'])) { + return $this->admin['user']; + } + } + + /** + * Returns the super admin password, if any + * + * @return string + */ + public function getSuperAdminPassword() + { + if (isset($this->admin['pwd'])) { + return $this->admin['pwd']; + } + } + + /** * Returns a salted hash on the * * @param string $value The value to hash Modified: branches/newUser2/classes/Gems/User/RespondentUser.php =================================================================== --- trunk/library/classes/Gems/User/RespondentUser.php 2011-11-03 17:40:33 UTC (rev 174) +++ branches/newUser2/classes/Gems/User/RespondentUser.php 2011-11-03 17:45:34 UTC (rev 175) @@ -39,9 +39,9 @@ * * -- PATCH: New user login structure -INSERT INTO gems__users (gsu_id_user, gsu_login, gsu_id_organization, gsu_user_class, gsu_active, - gsu_password, gsu_failed_logins, gsu_last_failed, gsu_reset_key, gsu_reset_requested, gsu_reset_required, - gsu_changed, gsu_changed_by, gsu_created, gsu_created_by) +INSERT INTO gems__users (gus_id_user, gus_login, gus_id_organization, gus_user_class, gus_active, + gus_password, gus_failed_logins, gus_last_failed, gus_reset_key, gus_reset_requested, gus_reset_required, + gus_changed, gus_changed_by, gus_created, gus_created_by) SELECT grs_id_user, gr2o_patient_nr, gr2o_id_organization, 'RespondentUser', CASE WHEN gr2o_reception_code = 'OK' THEN 1 ELSE 0 END, NULL, 0, NULL, NULL, NULL, 0, gr2o_changed, gr2o_changed_by, gr2o_created, gr2o_created_by Modified: branches/newUser2/classes/Gems/User/StaffUser.php =================================================================== --- trunk/library/classes/Gems/User/StaffUser.php 2011-11-03 17:40:33 UTC (rev 174) +++ branches/newUser2/classes/Gems/User/StaffUser.php 2011-11-03 17:45:34 UTC (rev 175) @@ -55,13 +55,13 @@ { $select = new Zend_Db_Select($this->db); $select->from('gems__users') - ->join('gems__staff', 'gsu_login = gsf_id_user') + ->join('gems__staff', 'gus_login = gsf_id_user') ->join('gems__groups', 'gsf_id_primary_group = ggp_id_group') - ->join('gems__organizations', 'gsu_id_organization = gor_id_organization') + ->join('gems__organizations', 'gus_id_organization = gor_id_organization') ->where('ggp_group_active = 1') ->where('gor_active = 1') - ->where('gsu_active = 1') - ->where('gsu_login = ?', $this->getLoginName()) + ->where('gus_active = 1') + ->where('gus_login = ?', $this->getLoginName()) ->limit(1); return $select; Modified: branches/newUser2/classes/Gems/User/UserLoader.php =================================================================== --- trunk/library/classes/Gems/User/UserLoader.php 2011-11-03 17:40:33 UTC (rev 174) +++ branches/newUser2/classes/Gems/User/UserLoader.php 2011-11-03 17:45:34 UTC (rev 175) @@ -47,6 +47,14 @@ class Gems_User_UserLoader extends Gems_Loader_TargetLoaderAbstract { /** + * User class constants + */ + const USER_NOLOGIN = 'NoLogin'; + const USER_OLD_STAFF = 'OldStaffUser'; + const USER_PROJECT = 'ProjectUser'; + const USER_STAFF = 'StaffUser'; + + /** * Allows sub classes of Gems_Loader_LoaderAbstract to specify the subdirectory where to look for. * * @var string $cascade An optional subdirectory where this subclass always loads from. @@ -55,51 +63,211 @@ /** * + * @var Zend_Db_Adapter_Abstract + */ + protected $db; + + /** + * * @var Gems_Project_ProjectSettings */ protected $project; + /** + * + * @param mixed $container A container acting as source for MUtil_Registry_Source + * @param array $dirs The directories where to look for requested classes + */ + public final function __construct($container, array $dirs) + { + parent::__construct($container, $dirs); + // Make sure Gems_User_User gets userLoader variable. + $this->addRegistryContainer(array('userLoader' => $this)); + } + /** + * Get the currently loggin in user * + * @return Gems_User_User */ - public function getCurrentUser() + public final function getCurrentUser() { static $currentUser; if (! $currentUser) { - $currentUser = Gems_User_UserAbstract::getCurrentUser(); + $currentUser = $this->_loadClass('User', true, array(Gems_User_User::getCurrentUserData())); + } - if (! $currentUser) { - $currentUser = $this->_loadClass('NoLoginUser', true, array(null, null)); + return $currentUser; + } - $currentUser->setAsCurrentUser(); - } + protected function getOldStaffUser($login_name, $organization) + { + /** + * Read the needed parameters from the different tables, lots of renames for backward + * compatibility + */ + $select = new Zend_Db_Select($this->db); + $select->from('gems__staff', array('user_id'=>'gsf_id_user', + 'user_login'=>'gsf_login', + //don't expose the password hash + //'user_password'=>'gsf_password', + 'user_email'=>'gsf_email', + 'user_group'=>'gsf_id_primary_group', + 'user_locale'=>'gsf_iso_lang', + 'user_logout'=>'gsf_logout_on_survey')) + ->columns(array('user_name'=>"(concat(coalesce(concat(`gems__staff`.`gsf_first_name`,_utf8' '),_utf8''),coalesce(concat(`gems__staff`.`gsf_surname_prefix`,_utf8' '),_utf8''),coalesce(`gems__staff`.`gsf_last_name`,_utf8'')))")) + ->join('gems__groups', 'gsf_id_primary_group = ggp_id_group', array('user_role'=>'ggp_role')) + ->join('gems__organizations', 'gsf_id_organization = gor_id_organization', + array( + 'user_organization_id'=>'gor_id_organization', + 'user_organization_name'=>'gor_name')) + ->where('ggp_group_active = 1') + ->where('gor_active = 1') + ->where('gsf_active = 1') + ->where('gsf_login = ?') + ->limit(1); + + //For a multi-layout project we need to select the appropriate style too + $select2 = clone $select; + $select2->columns(array('user_style' => 'gor_style'), 'gems__organizations'); + + try { + // Fails before patch has run... + return $this->db->fetchRow($select2, array($userName), Zend_Db::FETCH_ASSOC); + + } catch (Zend_Db_Exception $e) { + // So then we try the old method + return $this->db->fetchRow($select, array($userName), Zend_Db::FETCH_ASSOC); } + } - return $currentUser; + /** + * Overrule this function to handle your own - project + * specific = user classes. + * + * @param string $class Class name returned by getUserClass() + * @param string $login_name + * @param int $organization + * @return array + */ + protected function getProjectClassUser($class, $login_name, $organization) + { + throw new Gems_Exception_Coding(sprintf("Unknown user class '%s' found for user '%s'.", $class, $login_name)); } /** * * @param string $login_name - * @param int $organization Only used when more than one organization uses this $login_name - * @return Gems_User_UserAbstract + * @param int $organization + * @return array */ - public function getUser($login_name, $organization) + protected function getProjectUser($login_name, $organization) { - if ($this->isProjectUser($login_name)) { - return $this->loadProjectUser($login_name, $organization); - } + return array( + 'user_id' => 2000, + 'user_name' => $login_name, + 'user_group' => 800, + 'user_role' => 'master', + 'user_style' => 'gems', + 'user_organization_id' => $organization, + 'user_organization_name' => 'SUPER ADMIN', + 'allowedOrgs' => array($organization => 'SUPER ADMIN'), + ); } protected function isProjectUser($login_name) { - return isset($this->project->admin['user']) && ($this->project->admin['user'] == $login_name); + return $this->project->getSuperAdminName() == $login_name; } - protected function loadProjectUser($login_name, $organization) + protected function getStaffUser($login_name, $organization) { - return $this->_getClass('ProjectSuperUser', null, array($login_name, $organization)); + $select = new Zend_Db_Select($this->db); + $select->from('gems__users', array('user_id' => 'gus_id_user', + 'user_login' => 'gus_login', + //don't expose the password hash + //'user_password'=>'gus_password', + )) + ->join('gems__staff', 'gus_id_user = gsf_id_user', array( + 'user_email'=>'gsf_email', + 'user_group'=>'gsf_id_primary_group', + 'user_locale'=>'gsf_iso_lang', + 'user_logout'=>'gsf_logout_on_survey')) + ->columns(array('user_name'=>"(concat(coalesce(concat(`gems__staff`.`gsf_first_name`,_utf8' '),_utf8''),coalesce(concat(`gems__staff`.`gsf_surname_prefix`,_utf8' '),_utf8''),coalesce(`gems__staff`.`gsf_last_name`,_utf8'')))")) + ->join('gems__groups', 'gsf_id_primary_group = ggp_id_group', array('user_role'=>'ggp_role')) + ->join('gems__organizations', 'gus_id_organization = gor_id_organization', + array( + 'user_organization_id'=>'gor_id_organization', + 'user_organization_name'=>'gor_name', + 'user_style' => 'gor_style')) + ->where('ggp_group_active = 1') + ->where('gor_active = 1') + ->where('gus_active = 1') + ->where('gus_login = ?') + ->limit(1); + + return $this->db->fetchRow($select, array($userName), Zend_Db::FETCH_ASSOC); } + + /** + * Returns a user object, that may be empty if no user exist. + * + * @param string $login_name + * @param int $organization + * @return Gems_User_User or null when the user does not exist + */ + public final function getUser($login_name, $organization) + { + $class = $this->getUserClass($login_name, $organization); + switch ($class) { + case self::USER_PROJECT: + $values = $this->getProjectUser($login_name, $organization); + break; + + case self::USER_STAFF: + $values = $this->getStaffUser($login_name, $organization); + break; + + case self::USER_OLD_STAFF: + $values = $this->getOldStaffUser($login_name, $organization); + break; + + case self::USER_NOLOGIN: + case null; + case false; + return null; + + default: + $values = $this->getProjectClassUser($class, $login_name, $organization); + } + + $values['user_class'] = $class; + + return $this->_loadClass('User', true, array($values)); + } + + /** + * Returns the user class, can be overloaded by subclasses. + * + * @param string $login_name + * @param int $organization + * @return string + */ + protected function getUserClass($login_name, $organization) + { + if ($this->isProjectUser($login_name)) { + return self::USER_PROJECT; + } + + try { + $sql = "SELECT gus_user_class FROM gems__users WHERE gus_active = 1 AND gus_login = ? AND gus_id_organization = ?"; + return $this->db->fetchOne($sql, array($login_name, $organization)); + + } catch (Zend_Db_Exception $e) { + // Fail over for pre 1.5 projects + return self::USER_OLD_STAFF; + } + } } Modified: branches/newUser2/classes/Gems/Util/DbLookup.php =================================================================== --- trunk/library/classes/Gems/Util/DbLookup.php 2011-11-03 17:40:33 UTC (rev 174) +++ branches/newUser2/classes/Gems/Util/DbLookup.php 2011-11-03 17:45:34 UTC (rev 175) @@ -105,7 +105,7 @@ if (! $data) { $data = $this->db->fetchPairs("SELECT gsf_id_user, CONCAT(COALESCE(gsf_last_name, '-'), ', ', COALESCE(gsf_first_name, ''), COALESCE(CONCAT(' ', gsf_surname_prefix), '')) - FROM gems__users INNER JOIN gems__staff ON gsu_id_user = gsf_id_user WHERE gsu_active = 1 ORDER BY gsf_last_name, gsf_first_name, gsf_surname_prefix"); + FROM gems__users INNER JOIN gems__staff ON gus_id_user = gsf_id_user WHERE gus_active = 1 ORDER BY gsf_last_name, gsf_first_name, gsf_surname_prefix"); } return $data; Modified: branches/newUser2/classes/Gems/Validate/GemsPasswordUsername.php =================================================================== --- trunk/library/classes/Gems/Validate/GemsPasswordUsername.php 2011-11-03 17:40:33 UTC (rev 174) +++ branches/newUser2/classes/Gems/Validate/GemsPasswordUsername.php 2011-11-03 17:45:34 UTC (rev 175) @@ -86,7 +86,7 @@ */ public function __construct($usernameField, $passwordField, Zend_Db_Adapter_Abstract $adapter = null, $delayFactor = null) { - parent::__construct('gems__users', 'gsu_login', null, $adapter); + parent::__construct('gems__users', 'gus_login', null, $adapter); $this->_usernameField = $usernameField; $this->_passwordField = $passwordField; @@ -137,7 +137,7 @@ } } - $condition = $this->_adapter->quoteIdentifier('gsu_password') . ' = ?'; + $condition = $this->_adapter->quoteIdentifier('gus_password') . ' = ?'; $this->_exclude = $this->_adapter->quoteInto($condition, md5($password)); try { @@ -145,8 +145,8 @@ * Lookup last failed login and number of failed logins */ try { - $sql = "SELECT gsu_failed_logins, UNIX_TIMESTAMP(gsu_last_failed) - AS gsu_last_failed FROM {$this->_table} WHERE gsu_login = ?"; + $sql = "SELECT gus_failed_logins, UNIX_TIMESTAMP(gus_last_failed) + AS gus_last_failed FROM {$this->_table} WHERE gus_login = ?"; $results = $this->_adapter->fetchRow($sql, array($username)); } catch (Zend_Db_Exception $zde) { //If we need to apply a db patch, just use a default value @@ -154,10 +154,10 @@ MUtil_Echo::r(GemsEscort::getInstance()->translate->_('Please update the database')); } - $delay = pow($results['gsu_failed_logins'], $this->_delayFactor); - $remaining = ($results['gsu_last_failed'] + $delay) - time(); + $delay = pow($results['gus_failed_logins'], $this->_delayFactor); + $remaining = ($results['gus_last_failed'] + $delay) - time(); - if ($results['gsu_failed_logins'] > 0 && $remaining > 0) { + if ($results['gus_failed_logins'] > 0 && $remaining > 0) { $this->_obscureValue = false; $this->_error(self::ERROR_PASSWORD_DELAY, ceil($remaining / 60)); return false; Modified: branches/newUser2/classes/GemsEscort.php =================================================================== --- trunk/library/classes/GemsEscort.php 2011-11-03 17:40:33 UTC (rev 174) +++ branches/newUser2/classes/GemsEscort.php 2011-11-03 17:45:34 UTC (rev 175) @@ -921,7 +921,7 @@ * Reset number of failed logins */ try { - $sql = "UPDATE gems__users SET gsu_failed_logins = 0, gsu_last_failed = NULL WHERE gsu_login = ?"; + $sql = "UPDATE gems__users SET gus_failed_logins = 0, gus_last_failed = NULL WHERE gus_login = ?"; $this->db->query($sql, array($userName)); } catch (Exception $e) { // swallow exception @@ -935,7 +935,7 @@ */ try { if (isset($_POST['userlogin'])) { - $sql = "UPDATE gems__users SET gsu_failed_logins = gsu_failed_logins + 1, gsu_last_failed = NOW() WHERE gsu_login = ?"; + $sql = "UPDATE gems__users SET gus_failed_logins = gus_failed_logins + 1, gus_last_failed = NOW() WHERE gus_login = ?"; $this->db->query($sql, array($_POST['userlogin'])); } } catch (Exception $e) { @@ -1268,24 +1268,24 @@ * compatibility */ $select = new Zend_Db_Select($this->db); - $select->from('gems__users', array('user_id' => 'gsu_id_user', - 'user_login' => 'gsu_login', + $select->from('gems__users', array('user_id' => 'gus_id_user', + 'user_login' => 'gus_login', //don't expose the password hash - //'user_password'=>'gsu_password', + //'user_password'=>'gus_password', )) - ->join('gems__staff', 'gsu_id_user = gsf_id_user', array( + ->join('gems__staff', 'gus_id_user = gsf_id_user', array( 'user_email'=>'gsf_email', 'user_group'=>'gsf_id_primary_group', 'user_locale'=>'gsf_iso_lang', 'user_logout'=>'gsf_logout_on_survey')) ->columns(array('user_name'=>"(concat(coalesce(concat(`gems__staff`.`gsf_first_name`,_utf8' '),_utf8''),coalesce(concat(`gems__staff`.`gsf_surname_prefix`,_utf8' '),_utf8''),coalesce(`gems__staff`.`gsf_last_name`,_utf8'')))")) ->join('gems__groups', 'gsf_id_primary_group = ggp_id_group', array('user_role'=>'ggp_role')) - ->join('gems__organizations', 'gsu_id_organization = gor_id_organization', + ->join('gems__organizations', 'gus_id_organization = gor_id_organization', array('user_organization_id'=>'gor_id_organization', 'user_organization_name'=>'gor_name')) ->where('ggp_group_active = ?', 1) ->where('gor_active = ?', 1) - ->where('gsu_active = ?', 1) - ->where('gsu_login = ?', $userName) + ->where('gus_active = ?', 1) + ->where('gus_login = ?', $userName) ->limit(1); //For a multi-layout project we need to select the appropriate style too Modified: branches/newUser2/classes/MUtil/Registry/Source.php =================================================================== --- trunk/library/classes/MUtil/Registry/Source.php 2011-11-03 17:40:33 UTC (rev 174) +++ branches/newUser2/classes/MUtil/Registry/Source.php 2011-11-03 17:45:34 UTC (rev 175) @@ -3,7 +3,7 @@ /** * 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 @@ -14,7 +14,7 @@ * * 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 @@ -97,14 +97,14 @@ } } } - + return false; } /** * Adds an extra source container to this object. - * - * @param mixed $container + * + * @param mixed $container Zend_Config, array or ArrayObject * @param string $name An optional name to identify the container * @return MUtil_Registry_Source */ @@ -156,7 +156,7 @@ public function removeRegistryContainer($name) { unset($this->_containers[$name]); - + return $this; } } Modified: branches/newUser2/configs/db/patches.sql =================================================================== --- trunk/library/configs/db/patches.sql 2011-11-03 17:40:33 UTC (rev 174) +++ branches/newUser2/configs/db/patches.sql 2011-11-03 17:45:34 UTC (rev 175) @@ -219,37 +219,37 @@ -- PATCH: New user login structure CREATE TABLE if not exists gems__users ( - gsu_id_user bigint unsigned not null, - gsu_id_organization bigint not null references gems__organizations (gor_id_organization), + gus_id_user bigint unsigned not null, + gus_id_organization bigint not null references gems__organizations (gor_id_organization), - gsu_login varchar(30) CHARACTER SET 'utf8' COLLATE 'utf8_general_ci' not null, + gus_login varchar(30) CHARACTER SET 'utf8' COLLATE 'utf8_general_ci' not null, - gsu_user_class varchar(30) CHARACTER SET 'utf8' COLLATE 'utf8_general_ci' not null, - gsu_active boolean not null default 1, + gus_user_class varchar(30) CHARACTER SET 'utf8' COLLATE 'utf8_general_ci' not null, + gus_active boolean not null default 1, -- Common fields for standard 'store password in Gems' logins - -- Not every gsu_user_class will use them - gsu_password varchar(32) CHARACTER SET 'utf8' COLLATE 'utf8_general_ci' null, - gsu_failed_logins int(11) unsigned not null default 0, - gsu_last_failed timestamp null, - gsu_reset_key varchar(64) CHARACTER SET 'utf8' COLLATE 'utf8_general_ci' null, - gsu_reset_requested timestamp null, - gsu_reset_required boolean not null default 0, + -- Not every gus_user_class will use them + gus_password varchar(32) CHARACTER SET 'utf8' COLLATE 'utf8_general_ci' null, + gus_failed_logins int(11) unsigned not null default 0, + gus_last_failed timestamp null, + gus_reset_key varchar(64) CHARACTER SET 'utf8' COLLATE 'utf8_general_ci' null, + gus_reset_requested timestamp null, + gus_reset_required boolean not null default 0, - gsu_changed timestamp not null default current_timestamp on update current_timestamp, - gsu_changed_by bigint unsigned not null, - gsu_created timestamp not null, - gsu_created_by bigint unsigned not null, + gus_changed timestamp not null default current_timestamp on update current_timestamp, + gus_changed_by bigint unsigned not null, + gus_created timestamp not null, + gus_created_by bigint unsigned not null, - PRIMARY KEY (gsu_id_user, gsu_id_organization), - UNIQUE (gsu_login, gsu_id_organization) + PRIMARY KEY (gus_id_user, gus_id_organization), + UNIQUE (gus_login, gus_id_organization) ) ENGINE=InnoDB CHARACTER SET 'utf8' COLLATE 'utf8_general_ci'; -INSERT INTO gems__users (gsu_id_user, gsu_login, gsu_id_organization, gsu_user_class, gsu_active, - gsu_password, gsu_failed_logins, gsu_last_failed, gsu_reset_key, gsu_reset_requested, gsu_reset_required, - gsu_changed, gsu_changed_by, gsu_created, gsu_created_by) +INSERT INTO gems__users (gus_id_user, gus_login, gus_id_organization, gus_user_class, gus_active, + gus_password, gus_failed_logins, gus_last_failed, gus_reset_key, gus_reset_requested, gus_reset_required, + gus_changed, gus_changed_by, gus_created, gus_created_by) SELECT gsf_id_user, gsf_login, gsf_id_organization, 'StaffUser', gsf_active, NULL, gsf_failed_logins, gsf_last_failed, gsf_reset_key, 0, 1, gsf_changed, gsf_changed_by, gsf_created, gsf_created_by @@ -263,6 +263,8 @@ CHANGE `gsf_password` `gsf_password` VARCHAR( 32 ) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, CHANGE `gsf_id_organization` `gsf_id_organization` BIGINT( 20 ) NULL DEFAULT NULL; +ALTER TABLE gems__organizations ADD gor_style varchar(15) CHARACTER SET 'utf8' COLLATE 'utf8_general_ci' not null default 'gems' AFTER gor_signature; + -- PATCH: Extra information for track fields ALTER TABLE gems__track_fields ADD gtf_field_code varchar(20) CHARACTER SET 'utf8' COLLATE 'utf8_general_ci' null AFTER gtf_field_name, ADD gtf_field_description varchar(200) CHARACTER SET 'utf8' COLLATE 'utf8_general_ci' null AFTER gtf_field_code, Modified: branches/newUser2/configs/db/tables/gems__organizations.20.sql =================================================================== --- trunk/library/configs/db/tables/gems__organizations.20.sql 2011-11-03 17:40:33 UTC (rev 174) +++ branches/newUser2/configs/db/tables/gems__organizations.20.sql 2011-11-03 17:45:34 UTC (rev 175) @@ -13,7 +13,7 @@ gor_welcome text CHARACTER SET 'utf8' COLLATE 'utf8_general_ci', gor_signature text CHARACTER SET 'utf8' COLLATE 'utf8_general_ci', - -- gor_style varchar(15) CHARACTER SET 'utf8' COLLATE 'utf8_general_ci' not null default 'gems', + gor_style varchar(15) CHARACTER SET 'utf8' COLLATE 'utf8_general_ci' not null default 'gems', gor_iso_lang char(2) CHARACTER S... [truncated message content] |
From: <gem...@li...> - 2011-11-14 13:00:47
|
Revision: 210 http://gemstracker.svn.sourceforge.net/gemstracker/?rev=210&view=rev Author: matijsdejong Date: 2011-11-14 13:00:40 +0000 (Mon, 14 Nov 2011) Log Message: ----------- No longer in use Added Paths: ----------- branches/merged/newUser/ Removed Paths: ------------- branches/newUser/ Property changes on: branches/merged/newUser ___________________________________________________________________ Added: svn:mergeinfo + /trunk/library:114-122,125-139,142-144,147 This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <gem...@li...> - 2011-11-14 13:01:40
|
Revision: 211 http://gemstracker.svn.sourceforge.net/gemstracker/?rev=211&view=rev Author: matijsdejong Date: 2011-11-14 13:01:31 +0000 (Mon, 14 Nov 2011) Log Message: ----------- Reintegrated Added Paths: ----------- branches/merged/newUser2/ Removed Paths: ------------- branches/newUser2/ Property changes on: branches/merged/newUser2 ___________________________________________________________________ Added: svn:mergeinfo + /branches/newUser:113-150 /trunk/library:176-190,192-195 This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <gem...@li...> - 2012-02-08 12:11:31
|
Revision: 460 http://gemstracker.svn.sourceforge.net/gemstracker/?rev=460&view=rev Author: matijsdejong Date: 2012-02-08 12:11:21 +0000 (Wed, 08 Feb 2012) Log Message: ----------- Modified Paths: -------------- branches/tmplib/classes/Gems/Controller/BrowseEditAction.php branches/tmplib/classes/Gems/Html.php branches/tmplib/classes/Gems/Snippets/TokenModelSnippetAbstract.php branches/tmplib/classes/Gems/Tracker/Engine/StepEngineAbstract.php branches/tmplib/classes/Gems/Tracker/Engine/TrackEngineAbstract.php branches/tmplib/classes/Gems/Tracker/Model/StandardTokenModel.php branches/tmplib/classes/MUtil/Model/FormBridge.php branches/tmplib/configs/db/patches.sql branches/tmplib/configs/db/tables/gems__rounds.40.sql branches/tmplib/snippets/RespondentTokenSnippet.php branches/tmplib/snippets/ShowRoundStepSnippet.php branches/tmplib/snippets/TrackSurveyOverviewSnippet.php branches/tmplib/snippets/TrackTokenOverviewSnippet.php Added Paths: ----------- branches/tmplib/ Property changes on: branches/tmplib ___________________________________________________________________ Added: svn:mergeinfo + /branches/1.5.0-pulse/library:306-344,346 /branches/newUser:113-150 /branches/newUser2:175-207 /branches/userloader:259-324 /tags/1.5.0beta1/library:305 Modified: branches/tmplib/classes/Gems/Controller/BrowseEditAction.php =================================================================== --- branches/1.5.x/library/classes/Gems/Controller/BrowseEditAction.php 2012-02-07 15:38:49 UTC (rev 459) +++ branches/tmplib/classes/Gems/Controller/BrowseEditAction.php 2012-02-08 12:11:21 UTC (rev 460) @@ -186,11 +186,16 @@ protected function addBrowseTableColumns(MUtil_Model_TableBridge $bridge, MUtil_Model_ModelAbstract $model) { // Add edit button if allowed, otherwise show, again if allowed - if ($menuItem = $this->findAllowedMenuItem('edit', 'show')) { + if ($menuItem = $this->findAllowedMenuItem('show')) { $bridge->addItemLink($menuItem->toActionLinkLower($this->getRequest(), $bridge)); } parent::addBrowseTableColumns($bridge, $model); + + // Add edit button if allowed, otherwise show, again if allowed + if ($menuItem = $this->findAllowedMenuItem('edit')) { + $bridge->addItemLink($menuItem->toActionLinkLower($this->getRequest(), $bridge)); + } } /** @@ -959,7 +964,12 @@ $table->setOnEmpty(sprintf($this->_('Unknown %s.'), $this->getTopic(1))); $table->setRepeater($repeater); $table->tfrow($this->createMenuLinks($this->menuShowIncludeLevel), array('class' => 'centerAlign')); + + if ($menuItem = $this->findAllowedMenuItem('edit')) { + $table->tbody()->onclick = array('location.href=\'', $menuItem->toHRefAttribute($this->getRequest()), '\';'); + } + $this->html[] = $table; } } Modified: branches/tmplib/classes/Gems/Html.php =================================================================== --- branches/1.5.x/library/classes/Gems/Html.php 2012-02-07 15:38:49 UTC (rev 459) +++ branches/tmplib/classes/Gems/Html.php 2012-02-08 12:11:21 UTC (rev 460) @@ -1,49 +1,49 @@ <?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. - */ - + /** - * File description of Gems_Html + * Copyright (c) 2011, Erasmus MC + * All rights reserved. * - * @author Matijs de Jong <mj...@ma...> - * @since 1.0 - * @version 1.4 - * @package Gems + * 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 Gems * @subpackage Html + * @author Matijs de Jong <mj...@ma...> + * @copyright Copyright (c) 2011 Erasmus MC + * @license New BSD License + * @version $Id$ */ /** - * Class description of Gems_Html + * Gems specific Html elements and settings * - * @author Matijs de Jong <mj...@ma...> - * @package Gems + * @package Gems * @subpackage Html + * @copyright Copyright (c) 2011 Erasmus MC + * @license New BSD License + * @since Class available since version 1.0 */ class Gems_Html { @@ -87,6 +87,7 @@ // Set the image directories MUtil_Html_ImgElement::addImageDir('gems/images'); + MUtil_Html_ImgElement::addImageDir('gems/icons'); $escort = GemsEscort::getInstance(); if (isset($escort->project->imagedir)) { MUtil_Html_ImgElement::addImageDir($escort->project->imagedir); @@ -146,7 +147,7 @@ } else { $args['class'] = new MUtil_Html_ClassArrayAttribute('browselink'); } - + // MUtil_Echo::r($args); $pager = new MUtil_Html_PagePanel($panel_args); Modified: branches/tmplib/classes/Gems/Snippets/TokenModelSnippetAbstract.php =================================================================== --- branches/1.5.x/library/classes/Gems/Snippets/TokenModelSnippetAbstract.php 2012-02-07 15:38:49 UTC (rev 459) +++ branches/tmplib/classes/Gems/Snippets/TokenModelSnippetAbstract.php 2012-02-08 12:11:21 UTC (rev 460) @@ -54,6 +54,26 @@ */ public $loader; + protected function addTokenLinks(MUtil_Model_TableBridge $bridge) + { + $title = MUtil_Html::create()->strong($this->_('+')); + + $showLinks[] = $this->createMenuLink($bridge, 'track', 'show', $title); + $showLinks[] = $this->createMenuLink($bridge, 'survey', 'show', $title); + + // Remove nulls + $showLinks = array_filter($showLinks); + + if ($showLinks) { + foreach ($showLinks as $showLink) { + if ($showLink) { + $showLink->title = array($this->_('Token'), $bridge->gto_id_token->strtoupper()); + } + } + } + $bridge->addItemLink($showLinks); + } + /** * Creates the model * @@ -71,10 +91,12 @@ 'calc_valid_from', 'gto_valid_from'); $model->addColumn( - 'CASE WHEN gto_completion_time IS NULL THEN gto_id_token ELSE NULL END', + 'CASE WHEN gto_completion_time IS NULL AND grc_success = 1 AND gto_valid_from <= CURRENT_TIMESTAMP AND gto_completion_time IS NULL AND (gto_valid_until IS NULL OR gto_valid_until >= CURRENT_TIMESTAMP) THEN gto_id_token ELSE NULL END', 'calc_id_token', 'gto_id_token'); - + $model->addColumn( + 'CASE WHEN gto_completion_time IS NULL AND grc_success = 1 AND gto_valid_from <= CURRENT_TIMESTAMP AND gto_completion_time IS NULL AND gto_valid_until < CURRENT_TIMESTAMP THEN 1 ELSE 0 END', + 'was_missed'); return $model; } Modified: branches/tmplib/classes/Gems/Tracker/Engine/StepEngineAbstract.php =================================================================== --- branches/1.5.x/library/classes/Gems/Tracker/Engine/StepEngineAbstract.php 2012-02-07 15:38:49 UTC (rev 459) +++ branches/tmplib/classes/Gems/Tracker/Engine/StepEngineAbstract.php 2012-02-08 12:11:21 UTC (rev 460) @@ -438,6 +438,7 @@ $model->set('gro_id_survey'); $model->set('gro_round_description'); $model->set('gro_id_order'); + $model->set('gro_icon_file'); // Calculate valid from $model->set('valid_after', 'elementClass', 'html', 'label', ' ', 'value', MUTil_Html::create()->h4($this->_('Valid from calculation'))); Modified: branches/tmplib/classes/Gems/Tracker/Engine/TrackEngineAbstract.php =================================================================== --- branches/1.5.x/library/classes/Gems/Tracker/Engine/TrackEngineAbstract.php 2012-02-07 15:38:49 UTC (rev 459) +++ branches/tmplib/classes/Gems/Tracker/Engine/TrackEngineAbstract.php 2012-02-08 12:11:21 UTC (rev 460) @@ -112,6 +112,12 @@ protected $util; /** + * + * @var Zend_View + */ + protected $view; + + /** * Copy from Zend_Translate_Adapter * * Translates the given string @@ -191,6 +197,27 @@ } /** + * Returns a list of available icons under 'htdocs/pulse/icons' + * @return string[] + */ + protected function _getAvailableIcons() + { + $icons = array(); + $iterator = new DirectoryIterator(realpath(GEMS_WEB_DIR . '/gems/icons')); + + foreach ($iterator as $fileinfo) { + if ($fileinfo->isFile()) { + // $icons[$fileinfo->getFilename()] = $fileinfo->getFilename(); + $filename = $fileinfo->getFilename(); + $url = $this->view->baseUrl() . MUtil_Html_ImgElement::getImageDir($filename); + $icons[$fileinfo->getFilename()] = MUtil_Html::create('span', $filename, array('style' => 'background: transparent url(' . $url . $filename . ') center right no-repeat; padding-right: 20px;')); + } + } + + return $icons; + } + + /** * Update the track, both in the database and in memory. * * @param array $values The values that this token should be set to @@ -707,17 +734,29 @@ } $model->set('gro_id_survey', 'label', $this->_('Survey'), 'multiOptions', $this->util->getTrackData()->getAllSurveysAndDescriptions()); + $model->set('gro_icon_file', 'label', $this->_('Icon')); $model->set('gro_id_order', 'label', $this->_('Order'), 'default', 10, 'validators[]', $model->createUniqueValidator(array('gro_id_order', 'gro_id_track'))); $model->set('gro_round_description', 'label', $this->_('Description'), 'size', '30'); //, 'minlength', 4, 'required', true); $model->set('gro_changed_event', 'label', $this->_('After change'), 'multiOptions', $this->events->listRoundChangedEvents()); $model->set('gro_active', 'label', $this->_('Active'), 'multiOptions', $this->util->getTranslated()->getYesNo(), 'elementClass', 'checkbox'); - if ($action == 'create') { - $this->_ensureRounds(); + switch ($action) { + case 'create': + $this->_ensureRounds(); - if ($this->_rounds && ($round = end($this->_rounds))) { - $model->set('gro_id_order', 'default', $round['gro_id_order'] + 10); - } + if ($this->_rounds && ($round = end($this->_rounds))) { + $model->set('gro_id_order', 'default', $round['gro_id_order'] + 10); + } + // Intentional fall through + // break; + case 'edit': + $model->set('gro_icon_file', 'multiOptions', $this->util->getTranslated()->getEmptyDropdownArray() + $this->_getAvailableIcons()); + break; + + default: + $model->set('gro_icon_file', 'formatFunction', array('MUtil_Html_ImgElement', 'imgFile')); + break; + } return $model; Modified: branches/tmplib/classes/Gems/Tracker/Model/StandardTokenModel.php =================================================================== --- branches/1.5.x/library/classes/Gems/Tracker/Model/StandardTokenModel.php 2012-02-07 15:38:49 UTC (rev 459) +++ branches/tmplib/classes/Gems/Tracker/Model/StandardTokenModel.php 2012-02-08 12:11:21 UTC (rev 460) @@ -167,10 +167,16 @@ } //If we are allowed to see who filled out a survey, modify the model accordingly - if (GemsEscort::getInstance()->hasPrivilege('pr.respondent.who')) { + $escort = GemsEscort::getInstance(); + if ($escort->hasPrivilege('pr.respondent.who')) { $this->addLeftTable('gems__staff', array('gto_by' => 'gems__staff_2.gsf_id_user')); $this->addColumn('CASE WHEN gems__staff_2.gsf_id_user IS NULL THEN ggp_name ELSE COALESCE(CONCAT_WS(" ", CONCAT(COALESCE(gems__staff_2.gsf_last_name,"-"),","), gems__staff_2.gsf_first_name, gems__staff_2.gsf_surname_prefix)) END', 'ggp_name'); } + if ($escort->hasPrivilege('pr.respondent.result')) { + $this->addColumn('gto_result', 'calc_result', 'gto_result'); + } else { + $this->addColumn('NULL', 'calc_result', 'gto_result'); + } $this->useTokenAsKey(); } Modified: branches/tmplib/classes/MUtil/Model/FormBridge.php =================================================================== --- branches/1.5.x/library/classes/MUtil/Model/FormBridge.php 2012-02-07 15:38:49 UTC (rev 459) +++ branches/tmplib/classes/MUtil/Model/FormBridge.php 2012-02-08 12:11:21 UTC (rev 460) @@ -553,7 +553,7 @@ $options = $this->_mergeOptions($name, $options, self::DISPLAY_OPTIONS, self::MULTI_OPTIONS); - $element = new Zend_Form_Element_Select($name, $options); + $element = new MUtil_Form_Element_Select($name, $options); return $this->_addToForm($name, $element); } @@ -603,7 +603,7 @@ $options = $this->_mergeOptions($name, $options, self::DISPLAY_OPTIONS, self::MULTI_OPTIONS); - $element = new Zend_Form_Element_Multiselect($name, $options); + $element = new MUtil_Form_Element_Multiselect($name, $options); return $this->_addToForm($name, $element); } Modified: branches/tmplib/configs/db/patches.sql =================================================================== --- branches/1.5.x/library/configs/db/patches.sql 2012-02-07 15:38:49 UTC (rev 459) +++ branches/tmplib/configs/db/patches.sql 2012-02-08 12:11:21 UTC (rev 460) @@ -364,4 +364,7 @@ -- PATCH: Default userdefinition per organization ALTER TABLE gems__organizations ADD `gor_user_class` VARCHAR( 30 ) NOT NULL DEFAULT 'StaffUser' AFTER `gor_code`; -ALTER TABLE `gems__radius_config` CHANGE `grcfg_ip` `grcfg_ip` VARCHAR( 39 ) CHARACTER SET utf8 COLLATE utf8_unicode_ci NULL \ No newline at end of file +ALTER TABLE `gems__radius_config` CHANGE `grcfg_ip` `grcfg_ip` VARCHAR( 39 ) CHARACTER SET utf8 COLLATE utf8_unicode_ci NULL + +-- PATCH: Add icon field to rounds +ALTER TABLE `gems__rounds` ADD gro_icon_file VARCHAR(100) CHARACTER SET 'utf8' COLLATE 'utf8_general_ci' null AFTER `gro_round_description`; Modified: branches/tmplib/configs/db/tables/gems__rounds.40.sql =================================================================== --- branches/1.5.x/library/configs/db/tables/gems__rounds.40.sql 2012-02-07 15:38:49 UTC (rev 459) +++ branches/tmplib/configs/db/tables/gems__rounds.40.sql 2012-02-08 12:11:21 UTC (rev 460) @@ -12,6 +12,7 @@ gro_survey_name varchar(100) CHARACTER SET 'utf8' COLLATE 'utf8_general_ci' not null, gro_round_description varchar(100) CHARACTER SET 'utf8' COLLATE 'utf8_general_ci' null, + gro_icon_file VARCHAR(100) CHARACTER SET 'utf8' COLLATE 'utf8_general_ci' null, gro_changed_event varchar(64) CHARACTER SET 'utf8' COLLATE 'utf8_general_ci' null, -- depreciated Modified: branches/tmplib/snippets/RespondentTokenSnippet.php =================================================================== --- branches/1.5.x/library/snippets/RespondentTokenSnippet.php 2012-02-07 15:38:49 UTC (rev 459) +++ branches/tmplib/snippets/RespondentTokenSnippet.php 2012-02-08 12:11:21 UTC (rev 460) @@ -104,6 +104,8 @@ $roundDescription[] = $HTML->if($bridge->calc_round_description, $HTML->small(' [', $bridge->calc_round_description, ']')); $roundDescription[] = $HTML->small(' [', $bridge->createSortLink('calc_round_description'), ']'); + $roundIcon[] = MUtil_Lazy::iif($bridge->gro_icon_file, MUtil_Html::create('img', array('src' => $bridge->gro_icon_file, 'class' => 'icon'))); + if ($menuItem = $this->findMenuItem('track', 'show-track')) { $href = $menuItem->toHRefAttribute($this->request, $bridge); $track1 = $HTML->if($bridge->calc_track_name, $HTML->a($href, $bridge->calc_track_name)); @@ -120,7 +122,7 @@ // $bridge->colgroup(array('span' => 3, 'width' => '9em')); $bridge->addMultiSort($track); - $bridge->addMultiSort('gsu_survey_name', $roundDescription); + $bridge->addMultiSort('gsu_survey_name', $roundDescription, $roundIcon); $bridge->addSortable('ggp_name'); $bridge->addSortable('calc_used_date', null, $HTML->if($bridge->is_completed, 'disabled date', 'enabled date')); $bridge->addSortable('gto_changed'); @@ -135,10 +137,6 @@ $bridge->useRowHref = false; - $title = $HTML->strong($this->_('+')); - - $showLinks[] = $this->createMenuLink($bridge, 'track', 'show', $title); - $showLinks[] = $this->createMenuLink($bridge, 'survey', 'show', $title); $actionLinks[] = $this->createMenuLink($bridge, 'track', 'answer'); $actionLinks[] = $this->createMenuLink($bridge, 'survey', 'answer'); $actionLinks[] = array( @@ -149,18 +147,13 @@ // MUtil_Lazy::comp($bridge->val1, '==', $bridge->val2)->if($bridge->val3, 'broehaha'); // Remove nulls - $showLinks = array_filter($showLinks); $actionLinks = array_filter($actionLinks); - if ($showLinks || $actionLinks) { - foreach ($showLinks as $showLink) { - if ($showLink) { - $showLink->title = array($this->_('Token'), $bridge->gto_id_token->strtoupper()); - } - } + if ($actionLinks) { $bridge->addItemLink($actionLinks); - $bridge->addItemLink($showLinks); } + + $this->addTokenLinks($bridge); } /** Modified: branches/tmplib/snippets/ShowRoundStepSnippet.php =================================================================== --- branches/1.5.x/library/snippets/ShowRoundStepSnippet.php 2012-02-07 15:38:49 UTC (rev 459) +++ branches/tmplib/snippets/ShowRoundStepSnippet.php 2012-02-08 12:11:21 UTC (rev 460) @@ -94,6 +94,7 @@ $bridge->addItem('gro_id_survey'); $bridge->addItem('gro_round_description'); $bridge->addItem('gro_id_order'); + $bridge->addItem('gro_icon_file'); $bridge->addItem($model->get('valid_after', 'value')); $this->_addIf(array('grp_valid_after_source', 'grp_valid_after_id', 'grp_valid_after_field'), $bridge, $model); @@ -109,6 +110,13 @@ $bridge->addItem('gro_active'); $bridge->addItem('gro_changed_event'); + + $menuItem = $this->menu->find(array( + $this->request->getControllerKey() => $this->request->getControllerName(), + $this->request->getActionKey() => 'edit')); + if ($menuItem) { + $bridge->tbody()->onclick = array('location.href=\'', $menuItem->toHRefAttribute($this->request), '\';'); + } } /** Modified: branches/tmplib/snippets/TrackSurveyOverviewSnippet.php =================================================================== --- branches/1.5.x/library/snippets/TrackSurveyOverviewSnippet.php 2012-02-07 15:38:49 UTC (rev 459) +++ branches/tmplib/snippets/TrackSurveyOverviewSnippet.php 2012-02-08 12:11:21 UTC (rev 460) @@ -105,7 +105,10 @@ $table->addColumn($link->toActionLinkLower($trackRepeater)); } - $table->addColumn($trackRepeater->gsu_survey_name, $this->_('Survey')); + $surveyName[] = $trackRepeater->gsu_survey_name; + $surveyName[] = MUtil_Lazy::iif($trackRepeater->gro_icon_file, MUtil_Html::create('img', array('src' => $trackRepeater->gro_icon_file, 'class' => 'icon'))); + + $table->addColumn($surveyName, $this->_('Survey')); $table->addColumn($trackRepeater->gro_round_description, $this->_('Details')); $table->addColumn($trackRepeater->ggp_name, $this->_('By')); $table->addColumn($trackRepeater->gsu_survey_description->call(array(__CLASS__, 'oneLine')), @@ -116,7 +119,7 @@ private function getRepeater($trackId) { $sql = " - SELECT gro_id_round, gro_id_track, gro_round_description, gro_valid_after, gro_valid_for, gro_used_date, gro_active, + SELECT gro_id_round, gro_id_track, gro_round_description, gro_icon_file, gro_valid_after, gro_valid_for, gro_used_date, gro_active, gsu_id_survey, gsu_survey_name, gsu_survey_description, gsu_survey_pdf, gsu_active, ggp_name FROM gems__rounds LEFT JOIN gems__surveys ON gro_id_survey = gsu_id_survey Modified: branches/tmplib/snippets/TrackTokenOverviewSnippet.php =================================================================== --- branches/1.5.x/library/snippets/TrackTokenOverviewSnippet.php 2012-02-07 15:38:49 UTC (rev 459) +++ branches/tmplib/snippets/TrackTokenOverviewSnippet.php 2012-02-08 12:11:21 UTC (rev 460) @@ -103,7 +103,8 @@ $showLinks = array_filter($showLinks); // Columns - $bridge->addSortable('gsu_survey_name'); + $bridge->addSortable('gsu_survey_name') + ->append(MUtil_Lazy::iif($bridge->gro_icon_file, MUtil_Html::create('img', array('src' => $bridge->gro_icon_file, 'class' => 'icon')))); $bridge->addSortable('gto_round_description'); $bridge->addSortable('ggp_name'); $bridge->addSortable('gto_valid_from', null, 'date'); @@ -133,7 +134,6 @@ } $bridge->addItemLink($showLinks); } - } /** This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |