From: <gem...@li...> - 2012-01-24 09:27:45
|
Revision: 417 http://gemstracker.svn.sourceforge.net/gemstracker/?rev=417&view=rev Author: mennodekker Date: 2012-01-24 09:27:34 +0000 (Tue, 24 Jan 2012) Log Message: ----------- Fix for eventcalculation integer detection and another method tested Modified Paths: -------------- trunk/library/classes/Gems/Event/EventCalculations.php trunk/test/classes/Gems/Event/Gems_Event_EventCalculationsTest.php Modified: trunk/library/classes/Gems/Event/EventCalculations.php =================================================================== --- trunk/library/classes/Gems/Event/EventCalculations.php 2012-01-23 15:27:41 UTC (rev 416) +++ trunk/library/classes/Gems/Event/EventCalculations.php 2012-01-24 09:27:34 UTC (rev 417) @@ -95,7 +95,7 @@ * @param mixed $fieldNames An array of those names that should be used or a string that should occur in all names that have to be selected. * @return float */ - protected function averageInt(array $tokenAnswers, $fieldNames) + public function averageInt(array $tokenAnswers, $fieldNames) { if (is_string($fieldNames)) { $fieldNames = $this->_arrayFindName($tokenAnswers, $fieldNames); @@ -104,7 +104,7 @@ $count = 0; $sum = 0; foreach ($fieldNames as $name) { - if (isset($tokenAnswers[$name]) && is_int(intval($tokenAnswers[$name]))) { + if (isset($tokenAnswers[$name]) && (is_int($tokenAnswers[$name]) || (string) intval($tokenAnswers[$name]) === $tokenAnswers[$name])) { $count++; $sum += intval($tokenAnswers[$name]); } @@ -214,8 +214,8 @@ $sum = 0; foreach ($fieldNames as $name) { - if (isset($tokenAnswers[$name]) && intval($tokenAnswers[$name])== $tokenAnswers[$name]) { - $sum += $tokenAnswers[$name]; + if (isset($tokenAnswers[$name]) && (is_int($tokenAnswers[$name]) || (string) intval($tokenAnswers[$name]) === $tokenAnswers[$name])) { + $sum += intval($tokenAnswers[$name]); } } return $sum; Modified: trunk/test/classes/Gems/Event/Gems_Event_EventCalculationsTest.php =================================================================== --- trunk/test/classes/Gems/Event/Gems_Event_EventCalculationsTest.php 2012-01-23 15:27:41 UTC (rev 416) +++ trunk/test/classes/Gems/Event/Gems_Event_EventCalculationsTest.php 2012-01-24 09:27:34 UTC (rev 417) @@ -20,6 +20,29 @@ $this->object = new Gems_Event_EventCalculations(); } + public function testAverageInt() { + $tokenAnswers = array( + 'fld_1' => 1, + 'fld_2' => '2', + 'fld_3' => 1.5, //not integer + 'fld_4' => 'a', //not integer + 'fld_5' => 1.4, //not integer + 'fld_6' => 1.6, //not integer + '1_fld_7' => 6, //for fieldname test + '1_fld_8' => -1, //for fieldname test + 'notme' => 2 //for fieldname test + ); + + //Initial check (1+2 / 2) + $this->assertEquals(1.5, $this->object->averageInt($tokenAnswers, array('fld_1', 'fld_2'))); + + //Check if non-int will be left out (1+2 / 2) + $this->assertEquals(1.5, $this->object->averageInt($tokenAnswers, array('fld_1', 'fld_2', 'fld_3', 'fld_4'))); + + //Supply a string to test if the right fields get added (1+2+6-1 / 4) + $this->assertEquals(2, $this->object->averageInt($tokenAnswers, 'fld')); + } + public function testReverseCode1() { $this->assertEquals(10, $this->object->reverseCode(1, 1, 10)); $this->assertEquals(9, $this->object->reverseCode(2, 1, 10)); @@ -32,12 +55,14 @@ public function testSumInt() { $tokenAnswers = array( - 'fld_1'=>1, - 'fld_2'=>'2', - 'fld_3'=>1.5, //not integer - 'fld_4'=>'a', //not integer - 'fld_5'=>1.4, //not integer - 'fld_6'=>1.6 //not integer + 'fld_1' => 1, + 'fld_2' => '2', + 'fld_3' => 1.5, //not integer + 'fld_4' => 'a', //not integer + 'fld_5' => 1.4, //not integer + 'fld_6' => 1.6, //not integer + '1_fld_7' => 2, //for fieldname test + 'notme' => 2 //for fieldname test ); //Initial check @@ -46,9 +71,13 @@ //Check if non-int will be left out $this->assertEquals(3, $this->object->sumInt($tokenAnswers, array('fld_1', 'fld_2', 'fld_3'))); $this->assertEquals(3, $this->object->sumInt($tokenAnswers, array('fld_1', 'fld_2', 'fld_4'))); + //Make sure there are no rounding issues $this->assertEquals(3, $this->object->sumInt($tokenAnswers, array('fld_1', 'fld_2', 'fld_5'))); $this->assertEquals(3, $this->object->sumInt($tokenAnswers, array('fld_1', 'fld_2', 'fld_6'))); + + //Supply a string to test if the right fields get added + $this->assertEquals(5, $this->object->sumInt($tokenAnswers, 'fld')); } /** This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <gem...@li...> - 2012-02-20 14:44:38
|
Revision: 503 http://gemstracker.svn.sourceforge.net/gemstracker/?rev=503&view=rev Author: mennodekker Date: 2012-02-20 14:44:29 +0000 (Mon, 20 Feb 2012) Log Message: ----------- Merged revision(s) 485, 489 from tags/1.5.1: Forgot to include the upgrade :) ........ Fixing padding on #header_bar #login element ........ Modified Paths: -------------- trunk/library/classes/Gems/Upgrades.php trunk/new_project/htdocs/gems/css/gems-new.css Property Changed: ---------------- trunk/ trunk/library/ Property changes on: trunk ___________________________________________________________________ Modified: svn:mergeinfo - /branches/1.5.0-pulse:306-430,467 /branches/1.5.x:426-455,458-472,475-481 /tags/1.5.0beta1:305 + /branches/1.5.0-pulse:306-430,467 /branches/1.5.x:426-455,458-472,475-481 /tags/1.5.0beta1:305 /tags/1.5.1:485,489 Property changes on: trunk/library ___________________________________________________________________ Modified: svn:mergeinfo - /branches/1.5.0-pulse/library:306-344,346,467 /branches/1.5.x/library:426-455,458-472,475-481 /branches/newUser:113-150 /branches/newUser2:175-207 /branches/userloader:259-324 /tags/1.5.0beta1/library:305 + /branches/1.5.0-pulse/library:306-344,346,467 /branches/1.5.x/library:426-455,458-472,475-481 /branches/newUser:113-150 /branches/newUser2:175-207 /branches/userloader:259-324 /tags/1.5.0beta1/library:305 /tags/1.5.1/library:485,489 Modified: trunk/library/classes/Gems/Upgrades.php =================================================================== --- trunk/library/classes/Gems/Upgrades.php 2012-02-20 14:13:20 UTC (rev 502) +++ trunk/library/classes/Gems/Upgrades.php 2012-02-20 14:44:29 UTC (rev 503) @@ -56,6 +56,7 @@ $this->setContext('gems'); //And add our patches $this->register('Upgrade143to15', 'Upgrade from 1.43 to 1.5'); + $this->register('Upgrade15to151', 'Upgrade from 1.5.0. to 1.5.1'); } @@ -99,4 +100,17 @@ return true; } + + /** + * To upgrade to 1.5.1 just execute patchlevel 44 + */ + public function Upgrade15to151() + { + $this->addMessage(sprintf($this->_('Executing patchlevel %d'),44)); + $this->patcher->executePatch(44); + + $this->invalidateCache(); + + return true; + } } \ No newline at end of file Modified: trunk/new_project/htdocs/gems/css/gems-new.css =================================================================== --- trunk/new_project/htdocs/gems/css/gems-new.css 2012-02-20 14:13:20 UTC (rev 502) +++ trunk/new_project/htdocs/gems/css/gems-new.css 2012-02-20 14:44:29 UTC (rev 503) @@ -367,7 +367,7 @@ padding: 0px; } -#header_bar #contact { +#header_bar #contact, #header_bar #login { position: relative; padding: 5px 5px 0 5px; } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <gem...@li...> - 2012-03-08 15:44:45
|
Revision: 538 http://gemstracker.svn.sourceforge.net/gemstracker/?rev=538&view=rev Author: mennodekker Date: 2012-03-08 15:44:35 +0000 (Thu, 08 Mar 2012) Log Message: ----------- Fixed unit tests, added tests and updated default project.ini also added consentDefault to let a project overrule the global default 'Unknown' Modified Paths: -------------- trunk/library/classes/Gems/User/User.php trunk/library/classes/Gems/Util.php trunk/library/classes/GemsEscort.php trunk/new_project/application/configs/project.ini trunk/test/bootstrap.php trunk/test/classes/Gems/UtilTest.php Modified: trunk/library/classes/Gems/User/User.php =================================================================== --- trunk/library/classes/Gems/User/User.php 2012-03-08 10:40:53 UTC (rev 537) +++ trunk/library/classes/Gems/User/User.php 2012-03-08 15:44:35 UTC (rev 538) @@ -601,7 +601,8 @@ if ($menuItem) { // Prevent redirecting to the current page. if (! ($menuItem->is('controller', $request->getControllerName()) && $menuItem->is('action', $request->getActionName()))) { - echo $menuItem->get('label') . '<br/>'; + //Probably a debug statement so commented out MD20120308 + //echo $menuItem->get('label') . '<br/>'; $redirector = Zend_Controller_Action_HelperBroker::getStaticHelper('redirector'); $redirector->gotoRoute($menuItem->toRouteUrl($request), null, true); Modified: trunk/library/classes/Gems/Util.php =================================================================== --- trunk/library/classes/Gems/Util.php 2012-03-08 10:40:53 UTC (rev 537) +++ trunk/library/classes/Gems/Util.php 2012-03-08 15:44:35 UTC (rev 538) @@ -113,15 +113,33 @@ } + /** + * Retrieve the consentCODE to use for rejected responses by the survey system + * The mapping of actual consents to consentCODEs is done in the gems__consents table + * + * @return string Default value is 'do not use' + * @throws Gems_Exception_Coding + */ public function getConsentRejected() { + if (isset($this->project->consentRejected)) { + return $this->project->consentRejected; + } + if (isset($this->project->concentRejected)) { + throw new Gems_Exception_Coding('project.ini setting was changed from "concentRejected" to "consentRejected", please update your project.ini'); return $this->project->concentRejected; } return 'do not use'; } + /** + * Retrieve the array of possible consentCODEs to use for responses by the survey system + * The mapping of actual consents to consentCODEs is done in the gems__consents table + * + * @return array Default consent codes are 'do not use' and 'consent given' + */ public function getConsentTypes() { if (isset($this->project->consentTypes)) { @@ -172,7 +190,23 @@ } /** + * Get the default user consent * + * This is de consent description from gems__consents, not the consentCODE + * + * @return string + */ + public function getDefaultConsent() + { + if (isset($this->project->consentDefault)) { + return $this->project->consentDefault; + } + + return 'Unkown'; + } + + /** + * * @return Gems_Util_DbLookup */ public function getDbLookup() Modified: trunk/library/classes/GemsEscort.php =================================================================== --- trunk/library/classes/GemsEscort.php 2012-03-08 10:40:53 UTC (rev 537) +++ trunk/library/classes/GemsEscort.php 2012-03-08 15:44:35 UTC (rev 538) @@ -1488,9 +1488,6 @@ */ public function routeShutdown(Zend_Controller_Request_Abstract $request) { - // Npow is a good time to check for required values - $this->project->checkRequiredValues(); - $loader = $this->getLoader(); $user = $loader->getCurrentUser(); @@ -1502,6 +1499,10 @@ $this->menu = $loader->createMenu($this); $this->_updateVariable('menu'); + // Now is a good time to check for required values + // Moved down here to prevent unit test from failing on missing salt + $this->project->checkRequiredValues(); + $source = $this->menu->getParameterSource(); $this->getLoader()->getOrganization()->applyToMenuSource($source); Modified: trunk/new_project/application/configs/project.ini =================================================================== --- trunk/new_project/application/configs/project.ini 2012-03-08 10:40:53 UTC (rev 537) +++ trunk/new_project/application/configs/project.ini 2012-03-08 15:44:35 UTC (rev 538) @@ -187,7 +187,7 @@ layoutPrepare.dojo = 0 layoutPrepare.jQuery = 1 -layoutPrepare.login.class = rightFloat +layoutPrepareArgs.login.class = rightFloat ;layoutPrepareArgs.contact.class = rightFloat layoutPrepareArgs.time.class = rightFloat layoutPrepareArgs.user.class = rightFloat @@ -276,6 +276,13 @@ tokens.from = 01; tokens.to = ol; +;--------------------------------------------------------- +; CONSENT SECTION +;--------------------------------------------------------- +consentRejected = 'do not use' +consentTypes = 'do not use|consent given' +consentDefault = 'Unknown' ;Default setup makes this 'do not use' + [testing : production] admin.user = superadmin admin.pwd = superadmin Modified: trunk/test/bootstrap.php =================================================================== --- trunk/test/bootstrap.php 2012-03-08 10:40:53 UTC (rev 537) +++ trunk/test/bootstrap.php 2012-03-08 15:44:35 UTC (rev 538) @@ -42,12 +42,12 @@ * Setup environment */ define('GEMS_WEB_DIR', dirname(__FILE__)); -define('GEMS_ROOT_DIR', '../new_project'); -define('GEMS_LIBRARY_DIR', '../library'); +define('GEMS_ROOT_DIR', realpath(dirname(__FILE__) . '/../new_project')); +define('GEMS_LIBRARY_DIR', realpath(dirname(__FILE__) . '/../library')); define('GEMS_PROJECT_NAME', 'newProject'); define('GEMS_PROJECT_NAME_UC', ucfirst(GEMS_PROJECT_NAME)); define('APPLICATION_ENV', 'testing'); -define('APPLICATION_PATH', realpath(dirname(__FILE__) . '/' . GEMS_ROOT_DIR . '/application')); +define('APPLICATION_PATH', GEMS_ROOT_DIR . '/application'); $GLOBALS['GEMS_DIRS'] = array( GEMS_PROJECT_NAME_UC => APPLICATION_PATH . '/classes', @@ -62,6 +62,7 @@ set_include_path( $path . '/library/classes' . PATH_SEPARATOR . GEMS_ROOT_DIR . '/application/classes' . PATH_SEPARATOR . + GEMS_WEB_DIR . '/classes' . PATH_SEPARATOR . get_include_path()); // Set up autoload. Modified: trunk/test/classes/Gems/UtilTest.php =================================================================== --- trunk/test/classes/Gems/UtilTest.php 2012-03-08 10:40:53 UTC (rev 537) +++ trunk/test/classes/Gems/UtilTest.php 2012-03-08 15:44:35 UTC (rev 538) @@ -1,4 +1,5 @@ <?php +require_once 'IndexControllerTest.php'; /** * Copyright (c) 2011, Erasmus MC @@ -38,6 +39,8 @@ /** * Test class for Gems_Util * + * As this class depends on all sorts of stuff being loaded we extend the IndexControllerTest + * * @author Michiel Rook <mi...@to...> * @package Gems * @subpackage Util @@ -45,32 +48,115 @@ * @license New BSD License * @since Class available since version 1.0 */ -class Gems_UtilTest extends PHPUnit_Framework_TestCase +class Gems_UtilTest extends IndexControllerTest//Zend_Test_PHPUnit_ControllerTestCase { - public function testAllowedIP1() { + /** + * @var Gems_Util + */ + protected $object; + + public function setUp() + { + parent::setUp(); + + //Fix errors in the default config + $this->_fixSetup(); + + //Now load the object we are going to test + $this->object = GemsEscort::getInstance()->loader->getUtil(); + } + + public function testAllowedIP1() + { $this->assertTrue(Gems_Util::isAllowedIP('10.0.0.1', '10.0.0.0-10.0.0.255')); } - public function testAllowedIP2() { + public function testAllowedIP2() + { $this->assertFalse(Gems_Util::isAllowedIP('10.0.1.1', '10.0.0.0-10.0.0.255')); } - public function testAllowedIP3() { + public function testAllowedIP3() + { $this->assertTrue(Gems_Util::isAllowedIP('127.0.0.1', '127.0.0.1')); } - public function testAllowedIP4() { + public function testAllowedIP4() + { $this->assertFalse(Gems_Util::isAllowedIP('127.0.0.1', '192.168.0.1')); } - public function testAllowedIP5() { + public function testAllowedIP5() + { $this->assertTrue(Gems_Util::isAllowedIP('127.0.0.1', '192.168.0.1|127.0.0.1')); } - - public function testAllowedIPEmptyRange() { + + public function testAllowedIPEmptyRange() + { $this->assertTrue(Gems_Util::isAllowedIP('127.0.0.1', '')); } + public function testConsentTypes() + { + //check the ini file to be the default + $expected = array( + 'do not use' => 'do not use', + 'consent given' => 'consent given' + ); + $actual = $this->object->getConsentTypes(); + $this->assertEquals($expected, $actual); + + //Check if we can read from an altered ini file + $project = GemsEscort::getInstance()->project; + $project->consentTypes = 'test|test2|test3'; + $expected = array( + 'test' => 'test', + 'test2' => 'test2', + 'test3' => 'test3', + ); + $actual = $this->object->getConsentTypes(); + $this->assertEquals($expected, $actual); + + //Check for class default when not found in ini + unset($project->consentTypes); + $expected = array( + 'do not use' => 'do not use', + 'consent given' => 'consent given' + ); + $actual = $this->object->getConsentTypes(); + $this->assertEquals($expected, $actual); + } + + public function testConsentRejected() + { + //Check the ini default + $expected = 'do not use'; + $actual = $this->object->getConsentRejected(); + $this->assertEquals($expected, $actual); + + //Check if we can read from an altered ini file + $project = GemsEscort::getInstance()->project; + $expected = 'test'; + $project->consentRejected = $expected; + $actual = $this->object->getConsentRejected(); + $this->assertEquals($expected, $actual); + + //Check for class default when not found in ini + unset($project->consentRejected); + $expected = 'do not use'; + $actual = $this->object->getConsentRejected(); + $this->assertEquals($expected, $actual); + + //Check for incorrect spelling used before 1.5.2 + unset($project->consentRejected); + $project->concentRejected = 'test2'; + try { + $actual = $this->object->getConsentRejected(); + } catch (Exception $e) { + } + $this->assertInstanceOf('Gems_Exception_Coding', $e, 'No failure on misspelled concentRejected in project.ini'); + } + /** * Tears down the fixture, for example, closes a network connection. * This method is called after a test is executed. This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <gem...@li...> - 2012-04-12 09:35:52
|
Revision: 613 http://gemstracker.svn.sourceforge.net/gemstracker/?rev=613&view=rev Author: matijsdejong Date: 2012-04-12 09:35:42 +0000 (Thu, 12 Apr 2012) Log Message: ----------- Merged fix 612 in 1.5.3 rc 2 Modified Paths: -------------- trunk/library/classes/Gems/Util.php Property Changed: ---------------- trunk/ trunk/library/ Property changes on: trunk ___________________________________________________________________ Modified: svn:mergeinfo - /branches/1.5.0-pulse:306-430,467 /branches/1.5.x:426-455,458-472,475-481 /tags/1.5.0beta1:305 /tags/1.5.1:485,489,509-510 + /branches/1.5.0-pulse:306-430,467 /branches/1.5.x:426-455,458-472,475-481 /tags/1.5.0beta1:305 /tags/1.5.1:485,489,509-510 /tags/1.5.3-rc2:612 Property changes on: trunk/library ___________________________________________________________________ Modified: svn:mergeinfo - /branches/1.5.0-pulse/library:306-344,346,467 /branches/1.5.x/library:426-455,458-472,475-481 /branches/newUser:113-150 /branches/newUser2:175-207 /branches/userloader:259-324 /tags/1.5.0beta1/library:305 /tags/1.5.1/library:485,489,509-510,534 + /branches/1.5.0-pulse/library:306-344,346,467 /branches/1.5.x/library:426-455,458-472,475-481 /branches/newUser:113-150 /branches/newUser2:175-207 /branches/userloader:259-324 /tags/1.5.0beta1/library:305 /tags/1.5.1/library:485,489,509-510,534 /tags/1.5.3-rc2/library:612 Modified: trunk/library/classes/Gems/Util.php =================================================================== --- trunk/library/classes/Gems/Util.php 2012-04-12 09:29:25 UTC (rev 612) +++ trunk/library/classes/Gems/Util.php 2012-04-12 09:35:42 UTC (rev 613) @@ -199,7 +199,7 @@ return $this->project->consentDefault; } - return 'Unkown'; + return 'Unknown'; } /** This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <gem...@li...> - 2012-04-12 12:34:43
|
Revision: 615 http://gemstracker.svn.sourceforge.net/gemstracker/?rev=615&view=rev Author: matijsdejong Date: 2012-04-12 12:34:32 +0000 (Thu, 12 Apr 2012) Log Message: ----------- Merged revision(s) 614 from tags/1.5.3-rc2: At organization level Url_base was not always shown Upgrades showed warning Password checker had security leak in that username was show during password reset BrowseEditAction did not pass empty parameters on correctly, so moved filter on empty values from RequestCache ........ Modified Paths: -------------- trunk/library/classes/Gems/Controller/BrowseEditAction.php trunk/library/classes/Gems/Default/OrganizationAction.php trunk/library/classes/Gems/Upgrades.php trunk/library/classes/Gems/User/PasswordChecker.php trunk/library/classes/Gems/Util/RequestCache.php Property Changed: ---------------- trunk/ trunk/library/ Property changes on: trunk ___________________________________________________________________ Modified: svn:mergeinfo - /branches/1.5.0-pulse:306-430,467 /branches/1.5.x:426-455,458-472,475-481 /tags/1.5.0beta1:305 /tags/1.5.1:485,489,509-510 /tags/1.5.3-rc2:612 + /branches/1.5.0-pulse:306-430,467 /branches/1.5.x:426-455,458-472,475-481 /tags/1.5.0beta1:305 /tags/1.5.1:485,489,509-510 /tags/1.5.3-rc2:612,614 Property changes on: trunk/library ___________________________________________________________________ Modified: svn:mergeinfo - /branches/1.5.0-pulse/library:306-344,346,467 /branches/1.5.x/library:426-455,458-472,475-481 /branches/newUser:113-150 /branches/newUser2:175-207 /branches/userloader:259-324 /tags/1.5.0beta1/library:305 /tags/1.5.1/library:485,489,509-510,534 /tags/1.5.3-rc2/library:612 + /branches/1.5.0-pulse/library:306-344,346,467 /branches/1.5.x/library:426-455,458-472,475-481 /branches/newUser:113-150 /branches/newUser2:175-207 /branches/userloader:259-324 /tags/1.5.0beta1/library:305 /tags/1.5.1/library:485,489,509-510,534 /tags/1.5.3-rc2/library:612,614 Modified: trunk/library/classes/Gems/Controller/BrowseEditAction.php =================================================================== --- trunk/library/classes/Gems/Controller/BrowseEditAction.php 2012-04-12 12:01:29 UTC (rev 614) +++ trunk/library/classes/Gems/Controller/BrowseEditAction.php 2012-04-12 12:34:32 UTC (rev 615) @@ -597,9 +597,10 @@ * @param boolean $includeDefaults Include the default values (yes for filtering, no for urls * @param string $sourceAction The action to get the cache from if not the current one. * @param boolean $readonly Optional, tell the cache not to store any new values + * @param boolean $filterEmpty Optional, filter empty values from cache * @return array */ - public function getCachedRequestData($includeDefaults = true, $sourceAction = null, $readonly = false) + public function getCachedRequestData($includeDefaults = true, $sourceAction = null, $readonly = false, $filterEmpty = true) { if (! $this->requestCache) { $this->requestCache = $this->util->getRequestCache($sourceAction, $readonly); @@ -614,6 +615,16 @@ if ($includeDefaults) { $data = $data + $this->getDefaultSearchData(); } + if ($filterEmpty) { + // Clean up empty values + // + // We do this here because empty values can be valid filters that overrule the default + foreach ($data as $key => $value) { + if ((is_array($value) && empty($value)) || (is_string($value) && 0 === strlen($value))) { + unset($data[$key]); + } + } + } return $data; } @@ -964,7 +975,7 @@ $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()), '\';'); } Modified: trunk/library/classes/Gems/Default/OrganizationAction.php =================================================================== --- trunk/library/classes/Gems/Default/OrganizationAction.php 2012-04-12 12:01:29 UTC (rev 614) +++ trunk/library/classes/Gems/Default/OrganizationAction.php 2012-04-12 12:34:32 UTC (rev 615) @@ -119,15 +119,15 @@ 'label', $this->_('Style'), 'multiOptions', MUtil_Lazy::call(array($this->escort, 'getStyles')) ); - $model->setIfExists('gor_url_base', - 'label', $this->_("Default url's"), - 'size', 50, - 'description', sprintf($this->_("Always switch to this organization when %s is accessed from one of these space separated url's. The first is used for mails."), $this->project->getName()) - ); - if ($detailed) { - $model->setIfExists('gor_url_base', 'filter', 'TrailingSlash'); - } } + $model->setIfExists('gor_url_base', + 'label', $this->_("Default url's"), + 'size', 50, + 'description', sprintf($this->_("Always switch to this organization when %s is accessed from one of these space separated url's. The first is used for mails."), $this->project->getName()) + ); + if ($detailed) { + $model->setIfExists('gor_url_base', 'filter', 'TrailingSlash'); + } $model->set( 'gor_iso_lang', 'label', $this->_('Language'), 'multiOptions', $this->util->getLocalized()->getLanguages(), 'default', 'nl' Modified: trunk/library/classes/Gems/Upgrades.php =================================================================== --- trunk/library/classes/Gems/Upgrades.php 2012-04-12 12:01:29 UTC (rev 614) +++ trunk/library/classes/Gems/Upgrades.php 2012-04-12 12:34:32 UTC (rev 615) @@ -55,10 +55,10 @@ //Now set the context $this->setContext('gems'); //And add our patches - $this->register('Upgrade143to15', 'Upgrade from 1.4.3 to 1.5.0'); - $this->register('Upgrade15to151', 'Upgrade from 1.5.0 to 1.5.1'); - $this->register('Upgrade151to152', 'Upgrade from 1.5.1 to 1.5.2'); - $this->register('Upgrade152to153', 'Upgrade from 1.5.2 to 1.5.3'); + $this->register(array($this, 'Upgrade143to150'), 'Upgrade from 1.4.3 to 1.5.0'); + $this->register(array($this, 'Upgrade150to151'), 'Upgrade from 1.5.0 to 1.5.1'); + $this->register(array($this, 'Upgrade151to152'), 'Upgrade from 1.5.1 to 1.5.2'); + $this->register(array($this, 'Upgrade152to153'), 'Upgrade from 1.5.2 to 1.5.3'); } @@ -67,7 +67,7 @@ * 1. execute db patches 42 and 43 * 2. create new tables */ - public function Upgrade143to15() + public function Upgrade143to150() { $this->_batch->addTask('Db_ExecutePatch', 42); $this->_batch->addTask('Db_ExecutePatch', 43); @@ -90,7 +90,7 @@ /** * To upgrade to 1.5.1 just execute patchlevel 44 */ - public function Upgrade15to151() + public function Upgrade150to151() { $this->_batch->addTask('Db_ExecutePatch', 44); Modified: trunk/library/classes/Gems/User/PasswordChecker.php =================================================================== --- trunk/library/classes/Gems/User/PasswordChecker.php 2012-04-12 12:01:29 UTC (rev 614) +++ trunk/library/classes/Gems/User/PasswordChecker.php 2012-04-12 12:34:32 UTC (rev 615) @@ -185,7 +185,7 @@ $lpwd = strtolower($password); if ((false !== strpos($lpwd, strtolower($this->user->getLoginName()))) || (null === $password)) { - $this->_addError(sprintf($this->translate->_('should not contain your login name "%s"'), $this->user->getLoginName())); + $this->_addError($this->translate->_('should not contain your login name')); } } } Modified: trunk/library/classes/Gems/Util/RequestCache.php =================================================================== --- trunk/library/classes/Gems/Util/RequestCache.php 2012-04-12 12:01:29 UTC (rev 614) +++ trunk/library/classes/Gems/Util/RequestCache.php 2012-04-12 12:34:32 UTC (rev 615) @@ -270,7 +270,7 @@ unset($params[$key]); } } - // MUtil_Echo::r($params); + // MUtil_Echo::track($params); $this->setProgramParams($params); @@ -290,19 +290,13 @@ } /** - * Ste the keys stored fot this cache + * Set the keys stored fot this cache * * @param array $programParams * @return Gems_Util_RequestCache (continuation pattern) */ public function setProgramParams(array $programParams) { - foreach ($programParams as $key => $value) { - if ((is_array($value) && empty($value)) || (is_string($value) && 0 === strlen($value))) { - unset($programParams[$key]); - } - } - // Store result $this->_programParams = $programParams; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <gem...@li...> - 2012-04-12 13:50:33
|
Revision: 617 http://gemstracker.svn.sourceforge.net/gemstracker/?rev=617&view=rev Author: matijsdejong Date: 2012-04-12 13:50:23 +0000 (Thu, 12 Apr 2012) Log Message: ----------- Merged revision(s) 616 from tags/1.5.3-rc2: TokenPlan did not confirm to token return policy, resulted in strange behaviour Removed familiar Dutch words (use of 'je') ........ Modified Paths: -------------- trunk/library/classes/Gems/Default/TokenPlanAction.php trunk/library/languages/default-en.mo trunk/library/languages/default-en.po trunk/library/languages/default-nl.mo trunk/library/languages/default-nl.po Property Changed: ---------------- trunk/ trunk/library/ Property changes on: trunk ___________________________________________________________________ Modified: svn:mergeinfo - /branches/1.5.0-pulse:306-430,467 /branches/1.5.x:426-455,458-472,475-481 /tags/1.5.0beta1:305 /tags/1.5.1:485,489,509-510 /tags/1.5.3-rc2:612,614 + /branches/1.5.0-pulse:306-430,467 /branches/1.5.x:426-455,458-472,475-481 /tags/1.5.0beta1:305 /tags/1.5.1:485,489,509-510 /tags/1.5.3-rc2:612,614,616 Property changes on: trunk/library ___________________________________________________________________ Modified: svn:mergeinfo - /branches/1.5.0-pulse/library:306-344,346,467 /branches/1.5.x/library:426-455,458-472,475-481 /branches/newUser:113-150 /branches/newUser2:175-207 /branches/userloader:259-324 /tags/1.5.0beta1/library:305 /tags/1.5.1/library:485,489,509-510,534 /tags/1.5.3-rc2/library:612,614 + /branches/1.5.0-pulse/library:306-344,346,467 /branches/1.5.x/library:426-455,458-472,475-481 /branches/newUser:113-150 /branches/newUser2:175-207 /branches/userloader:259-324 /tags/1.5.0beta1/library:305 /tags/1.5.1/library:485,489,509-510,534 /tags/1.5.3-rc2/library:612,614,616 Modified: trunk/library/classes/Gems/Default/TokenPlanAction.php =================================================================== --- trunk/library/classes/Gems/Default/TokenPlanAction.php 2012-04-12 13:46:35 UTC (rev 616) +++ trunk/library/classes/Gems/Default/TokenPlanAction.php 2012-04-12 13:50:23 UTC (rev 617) @@ -344,7 +344,7 @@ if (($this->escort instanceof Gems_Project_Organization_MultiOrganizationInterface)) { $availableOrganizations = $this->util->getDbLookup()->getOrganizationsWithRespondents(); $allowedOrganizations = $this->loader->getCurrentUser()->getAllowedOrganizations(); - + $options = array_intersect($availableOrganizations, $allowedOrganizations); $elements[] = $this->_createSelectElement('gto_id_organization', $options); @@ -488,6 +488,9 @@ return $this->_('Token planning'); } + /** + * Default overview action + */ public function indexAction() { // MUtil_Model::$verbose = true; @@ -497,4 +500,19 @@ parent::indexAction(); } + + /** + * Initialize translate and html objects + * + * Called from {@link __construct()} as final step of object instantiation. + * + * @return void + */ + public function init() + { + parent::init(); + + // Tell the system where to return to after a survey has been taken + $this->loader->getCurrentUser()->setSurveyReturn($this->getRequest()); + } } Modified: trunk/library/languages/default-en.mo =================================================================== (Binary files differ) Modified: trunk/library/languages/default-en.po =================================================================== --- trunk/library/languages/default-en.po 2012-04-12 13:46:35 UTC (rev 616) +++ trunk/library/languages/default-en.po 2012-04-12 13:50:23 UTC (rev 617) @@ -2,7 +2,7 @@ msgstr "" "Project-Id-Version: GemsTracker EN\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2012-04-08 16:56+0100\n" +"POT-Creation-Date: 2012-04-12 15:06+0100\n" "PO-Revision-Date: \n" "Last-Translator: Matijs de Jong <mj...@ma...>\n" "Language-Team: Erasmus MGZ <mat...@ma...>\n" @@ -484,61 +484,61 @@ msgid "No %s found" msgstr "No %s found" -#: classes/Gems/Controller/BrowseEditAction.php:662 +#: classes/Gems/Controller/BrowseEditAction.php:673 #: classes/Gems/Default/ExportAction.php:234 #, php-format msgid "No %s found." msgstr "No %s found." -#: classes/Gems/Controller/BrowseEditAction.php:780 +#: classes/Gems/Controller/BrowseEditAction.php:791 msgid "Are you sure?" msgstr "Are you sure?" -#: classes/Gems/Controller/BrowseEditAction.php:796 +#: classes/Gems/Controller/BrowseEditAction.php:807 #: classes/Gems/Default/DatabaseAction.php:187 #: classes/Gems/Default/DatabaseAction.php:499 msgid "Yes" msgstr "Yes" -#: classes/Gems/Controller/BrowseEditAction.php:797 +#: classes/Gems/Controller/BrowseEditAction.php:808 #: classes/Gems/Default/DatabaseAction.php:188 #: classes/Gems/Default/DatabaseAction.php:500 msgid "No" msgstr "No" -#: classes/Gems/Controller/BrowseEditAction.php:850 +#: classes/Gems/Controller/BrowseEditAction.php:861 #, php-format msgid "Unknown %s requested" msgstr "Unknown %s requested" -#: classes/Gems/Controller/BrowseEditAction.php:873 +#: classes/Gems/Controller/BrowseEditAction.php:884 #, php-format msgid "New %1$s..." msgstr "New %1$s..." -#: classes/Gems/Controller/BrowseEditAction.php:881 +#: classes/Gems/Controller/BrowseEditAction.php:892 msgid "Save" msgstr "Save" -#: classes/Gems/Controller/BrowseEditAction.php:917 +#: classes/Gems/Controller/BrowseEditAction.php:928 #, php-format msgid "%2$u %1$s saved" msgstr "%2$u %1$s saved" -#: classes/Gems/Controller/BrowseEditAction.php:920 +#: classes/Gems/Controller/BrowseEditAction.php:931 msgid "No changes to save." msgstr "No changes to save." -#: classes/Gems/Controller/BrowseEditAction.php:929 +#: classes/Gems/Controller/BrowseEditAction.php:940 msgid "Input error! No changes saved!" msgstr "Input error! No changes saved!" -#: classes/Gems/Controller/BrowseEditAction.php:957 +#: classes/Gems/Controller/BrowseEditAction.php:968 #, php-format msgid "Show %s" msgstr "Show %s" -#: classes/Gems/Controller/BrowseEditAction.php:964 +#: classes/Gems/Controller/BrowseEditAction.php:975 #, php-format msgid "Unknown %s." msgstr "Unknown %s." @@ -616,22 +616,22 @@ msgid "The number zero and the letter O are treated as the same; the same goes for the number one and the letter L." msgstr "The number zero and the letter O are treated as the same; the same goes for the number one and the letter L." -#: classes/Gems/Default/AskAction.php:132 +#: classes/Gems/Default/AskAction.php:131 #, php-format msgid "Thank you for answering. At the moment we have no further surveys for you to take." msgstr "Thank you for answering. At the moment we have no further surveys for you to take." -#: classes/Gems/Default/AskAction.php:134 +#: classes/Gems/Default/AskAction.php:133 #, php-format msgid "The survey for token %s has been answered and no further surveys are open." msgstr "The survey for token %s has been answered and no further surveys are open." -#: classes/Gems/Default/AskAction.php:141 +#: classes/Gems/Default/AskAction.php:140 #, php-format msgid "The token %s does not exist (any more)." msgstr "The token %s does not exist (any more)." -#: classes/Gems/Default/AskAction.php:243 +#: classes/Gems/Default/AskAction.php:241 #, php-format msgid "The survey for token %s is no longer active." msgstr "The survey for token %s is no longer active." @@ -1489,11 +1489,11 @@ msgid "Style" msgstr "Style" -#: classes/Gems/Default/OrganizationAction.php:123 +#: classes/Gems/Default/OrganizationAction.php:124 msgid "Default url's" msgstr "Default url's" -#: classes/Gems/Default/OrganizationAction.php:125 +#: classes/Gems/Default/OrganizationAction.php:126 #, php-format msgid "Always switch to this organization when %s is accessed from one of these space separated url's. The first is used for mails." msgstr "Always switch to this organization when %s is accessed from one of these space separated url's. The first is used for mails." @@ -3592,9 +3592,8 @@ msgstr "should not contain non alphanumeric characters" #: classes/Gems/User/PasswordChecker.php:188 -#, php-format -msgid "should not contain your login name \"%s\"" -msgstr "should not contain your login name \"%s\"" +msgid "should not contain your login name" +msgstr "should not contain your login name" #: classes/Gems/User/PasswordChecker.php:207 #, php-format Modified: trunk/library/languages/default-nl.mo =================================================================== (Binary files differ) Modified: trunk/library/languages/default-nl.po =================================================================== --- trunk/library/languages/default-nl.po 2012-04-12 13:46:35 UTC (rev 616) +++ trunk/library/languages/default-nl.po 2012-04-12 13:50:23 UTC (rev 617) @@ -2,7 +2,7 @@ msgstr "" "Project-Id-Version: GemsTracker NL\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2012-04-08 16:56+0100\n" +"POT-Creation-Date: 2012-04-12 15:06+0100\n" "PO-Revision-Date: \n" "Last-Translator: Matijs de Jong <mj...@ma...>\n" "Language-Team: Erasmus MGZ <mat...@ma...>\n" @@ -484,61 +484,61 @@ msgid "No %s found" msgstr "Geen %s gevonden" -#: classes/Gems/Controller/BrowseEditAction.php:662 +#: classes/Gems/Controller/BrowseEditAction.php:673 #: classes/Gems/Default/ExportAction.php:234 #, php-format msgid "No %s found." msgstr "Geen %s gevonden." -#: classes/Gems/Controller/BrowseEditAction.php:780 +#: classes/Gems/Controller/BrowseEditAction.php:791 msgid "Are you sure?" msgstr "Weet u het zeker?" -#: classes/Gems/Controller/BrowseEditAction.php:796 +#: classes/Gems/Controller/BrowseEditAction.php:807 #: classes/Gems/Default/DatabaseAction.php:187 #: classes/Gems/Default/DatabaseAction.php:499 msgid "Yes" msgstr "Ja" -#: classes/Gems/Controller/BrowseEditAction.php:797 +#: classes/Gems/Controller/BrowseEditAction.php:808 #: classes/Gems/Default/DatabaseAction.php:188 #: classes/Gems/Default/DatabaseAction.php:500 msgid "No" msgstr "Nee" -#: classes/Gems/Controller/BrowseEditAction.php:850 +#: classes/Gems/Controller/BrowseEditAction.php:861 #, php-format msgid "Unknown %s requested" msgstr "Onjuist %s verzoek" -#: classes/Gems/Controller/BrowseEditAction.php:873 +#: classes/Gems/Controller/BrowseEditAction.php:884 #, php-format msgid "New %1$s..." msgstr "Nieuwe %1$s..." -#: classes/Gems/Controller/BrowseEditAction.php:881 +#: classes/Gems/Controller/BrowseEditAction.php:892 msgid "Save" msgstr "Opslaan" -#: classes/Gems/Controller/BrowseEditAction.php:917 +#: classes/Gems/Controller/BrowseEditAction.php:928 #, php-format msgid "%2$u %1$s saved" msgstr "%2$u %1$s opgeslagen" -#: classes/Gems/Controller/BrowseEditAction.php:920 +#: classes/Gems/Controller/BrowseEditAction.php:931 msgid "No changes to save." msgstr "Geen verandering om op te slaan." -#: classes/Gems/Controller/BrowseEditAction.php:929 +#: classes/Gems/Controller/BrowseEditAction.php:940 msgid "Input error! No changes saved!" msgstr "Invoer fout! Veranderingen niet opgeslagen!" -#: classes/Gems/Controller/BrowseEditAction.php:957 +#: classes/Gems/Controller/BrowseEditAction.php:968 #, php-format msgid "Show %s" msgstr "Toon %s" -#: classes/Gems/Controller/BrowseEditAction.php:964 +#: classes/Gems/Controller/BrowseEditAction.php:975 #, php-format msgid "Unknown %s." msgstr "%s is onbekend." @@ -551,7 +551,7 @@ #: classes/Gems/Controller/ModelSnippetActionAbstract.php:236 #, php-format msgid "Do you want to delete this %s?" -msgstr "Weet je zeker dat deze %s verwijderd moet worden?" +msgstr "Weet u zeker dat deze %s verwijderd moet worden?" #: classes/Gems/Controller/ModelSnippetActionAbstract.php:256 #, php-format @@ -616,22 +616,22 @@ msgid "The number zero and the letter O are treated as the same; the same goes for the number one and the letter L." msgstr "Er wordt geen verschil gemaakt tussen het getal nul en de letter O en ook niet tussen het getal één en de letter L." -#: classes/Gems/Default/AskAction.php:132 +#: classes/Gems/Default/AskAction.php:131 #, php-format msgid "Thank you for answering. At the moment we have no further surveys for you to take." msgstr "Dank u voor uw antwoorden. Op dit moment hebben we geen vragenlijsten meer voor u." -#: classes/Gems/Default/AskAction.php:134 +#: classes/Gems/Default/AskAction.php:133 #, php-format msgid "The survey for token %s has been answered and no further surveys are open." msgstr "De vragenlijst met het kenmerk %s is beantwoord en er staan verder geen vragenlijsten open." -#: classes/Gems/Default/AskAction.php:141 +#: classes/Gems/Default/AskAction.php:140 #, php-format msgid "The token %s does not exist (any more)." msgstr "Het kenmerk %s bestaat niet (meer)." -#: classes/Gems/Default/AskAction.php:243 +#: classes/Gems/Default/AskAction.php:241 #, php-format msgid "The survey for token %s is no longer active." msgstr "De vragenlijst voor kenmerk %s is niet meer in gebruik." @@ -931,8 +931,8 @@ #: classes/Gems/Default/DatabaseAction.php:489 msgid "Are you sure you want to create it?" msgid_plural "Are you sure you want to create them all?" -msgstr[0] "Weet je zeker dat je dat object wil aanmaken?" -msgstr[1] "Weet je zeker dat je ze allemaal wil aanmaken?" +msgstr[0] "Weet u zeker dat u dit wil aanmaken?" +msgstr[1] "Weet u zeker dat u deze allemaal wil aanmaken?" #: classes/Gems/Default/DatabaseAction.php:502 msgid "All database objects exist. There is nothing to create." @@ -1489,11 +1489,11 @@ msgid "Style" msgstr "Stijl" -#: classes/Gems/Default/OrganizationAction.php:123 +#: classes/Gems/Default/OrganizationAction.php:124 msgid "Default url's" msgstr "Standaard url's" -#: classes/Gems/Default/OrganizationAction.php:125 +#: classes/Gems/Default/OrganizationAction.php:126 #, php-format msgid "Always switch to this organization when %s is accessed from one of these space separated url's. The first is used for mails." msgstr "Altijd naar deze organisatie overschakelen als %s vanaf één van deze door spatie gescheiden url's wordt aangeroepen. De eerste url wordt gebruikt voor emails." @@ -2414,7 +2414,7 @@ #: classes/Gems/Default/TrackAction.php:410 msgid "Do you want to delete this track?" -msgstr "Weet je zeker dat dit traject verwijderd moet worden?" +msgstr "Weet u zeker dat dit traject verwijderd moet worden?" #: classes/Gems/Default/TrackAction.php:412 msgid "Delete track" @@ -3592,9 +3592,8 @@ msgstr "mag alleen letters en cijfers bevatten" #: classes/Gems/User/PasswordChecker.php:188 -#, php-format -msgid "should not contain your login name \"%s\"" -msgstr "mag niet je gebruikersnaam \"%s\" bevatten" +msgid "should not contain your login name" +msgstr "mag niet uw gebruikersnaam bevatten" #: classes/Gems/User/PasswordChecker.php:207 #, php-format @@ -3888,7 +3887,7 @@ #: classes/MUtil/Snippets/ModelYesNoDeleteSnippetAbstract.php:108 msgid "Do you really want to delete this item?" -msgstr "Weet je zeker dat dit item verwijderd moet worden?" +msgstr "Weet u zeker dat dit item verwijderd moet worden?" #: languages/FakeTranslations.php:40 msgid "Value is required and can't be empty" This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <gem...@li...> - 2012-07-23 13:31:46
|
Revision: 868 http://gemstracker.svn.sourceforge.net/gemstracker/?rev=868&view=rev Author: matijsdejong Date: 2012-07-23 13:31:34 +0000 (Mon, 23 Jul 2012) Log Message: ----------- Made fluid layout default for new project Modified Paths: -------------- trunk/new_project/application/configs/application.ini Added Paths: ----------- trunk/library/layouts/scripts/gems-fluid.phtml Removed Paths: ------------- trunk/library/layouts/scripts/gems-fluid2.phtml trunk/new_project/htdocs/gems/css/gems-fixed.css trunk/new_project/htdocs/gems/css/gems-fluid.css trunk/new_project/htdocs/gems/css/gems-fluid2.css Added: trunk/library/layouts/scripts/gems-fluid.phtml =================================================================== --- trunk/library/layouts/scripts/gems-fluid.phtml (rev 0) +++ trunk/library/layouts/scripts/gems-fluid.phtml 2012-07-23 13:31:34 UTC (rev 868) @@ -0,0 +1,74 @@ +<?php echo $this->doctype(); ?> +<html <?php echo 'xmlns="http://www.w3.org/1999/xhtml" xml:lang="'.$this->locale.'"' ?> lang="<?php echo $this->locale; ?>"> +<head> + <base href="<?php echo $this->serverUrl() . $this->baseUrl() ?>"/> + <?php + echo $this->headMeta(); + echo $this->headTitle(); + echo $this->headLink(); + echo $this->headStyle(); + + // Check if jQuery library is needed + if ($this->jQuery) { + echo $this->jQuery(); + //Error message for when jQuery can not be loaded + /*echo "<script> + if (typeof jQuery == 'undefined') { + document.writeln('<div class=\"errors\">The site requires external JavaScript from another domain, which is blocked or failed to load.</div>'); + } + </script>";*/ + } + + // Check if dojo library is needed + if ($this->dojoTheme) { + // Echo out the dojo <script> tags + echo $this->dojo(); + } + ?> + </head> +<body<?php if (isset($this->dojoTheme)) { echo " class='" . $this->dojoTheme . "' "; } ?>> + <div id="all"> + <div id="header"><?php if ($this->header) { echo $this->header->render($this); }?></div> + <div id="header_bar"><?php if ($this->header_bar) { echo $this->header_bar->render($this); } ?></div> +<?php + if ($this->navigation || $this->menuHtml): +?> + <div id="wrapper"> + <div class="main"> + <div id="main" ><?php + if ($this->main) { + echo $this->main->render($this); + } + echo $this->layout()->content; ?> + </div> + <div id="menu"><?php + echo $this->navigation()->menu(); + echo $this->menuHtml; + ?> + </div> + </div> + </div><?php + else: + ?> + <div id="wrapper" class="main fullwidth"> + <div><?php + if ($this->main) { + echo $this->main->render($this); + } + echo $this->layout()->content; + ?> </div> + </div><?php + endif; + ?> + <div id="footer"><?php + if ($this->footer) { + echo $this->footer->render($this); + } + ?> + </div> + </div><?php +echo MUtil_Echo::out(); +echo $this->headScript(); +echo $this->inlineScript(); +?></body> +</html> \ No newline at end of file Deleted: trunk/library/layouts/scripts/gems-fluid2.phtml =================================================================== --- trunk/library/layouts/scripts/gems-fluid2.phtml 2012-07-23 10:52:21 UTC (rev 867) +++ trunk/library/layouts/scripts/gems-fluid2.phtml 2012-07-23 13:31:34 UTC (rev 868) @@ -1,74 +0,0 @@ -<?php echo $this->doctype(); ?> -<html <?php echo 'xmlns="http://www.w3.org/1999/xhtml" xml:lang="'.$this->locale.'"' ?> lang="<?php echo $this->locale; ?>"> -<head> - <base href="<?php echo $this->serverUrl() . $this->baseUrl() ?>"/> - <?php - echo $this->headMeta(); - echo $this->headTitle(); - echo $this->headLink(); - echo $this->headStyle(); - - // Check if jQuery library is needed - if ($this->jQuery) { - echo $this->jQuery(); - //Error message for when jQuery can not be loaded - /*echo "<script> - if (typeof jQuery == 'undefined') { - document.writeln('<div class=\"errors\">The site requires external JavaScript from another domain, which is blocked or failed to load.</div>'); - } - </script>";*/ - } - - // Check if dojo library is needed - if ($this->dojoTheme) { - // Echo out the dojo <script> tags - echo $this->dojo(); - } - ?> - </head> -<body<?php if (isset($this->dojoTheme)) { echo " class='" . $this->dojoTheme . "' "; } ?>> - <div id="all"> - <div id="header"><?php if ($this->header) { echo $this->header->render($this); }?></div> - <div id="header_bar"><?php if ($this->header_bar) { echo $this->header_bar->render($this); } ?></div> -<?php - if ($this->navigation || $this->menuHtml): -?> - <div id="wrapper"> - <div class="main"> - <div id="main" ><?php - if ($this->main) { - echo $this->main->render($this); - } - echo $this->layout()->content; ?> - </div> - <div id="menu"><?php - echo $this->navigation()->menu(); - echo $this->menuHtml; - ?> - </div> - </div> - </div><?php - else: - ?> - <div id="wrapper" class="main fullwidth"> - <div><?php - if ($this->main) { - echo $this->main->render($this); - } - echo $this->layout()->content; - ?> </div> - </div><?php - endif; - ?> - <div id="footer"><?php - if ($this->footer) { - echo $this->footer->render($this); - } - ?> - </div> - </div><?php -echo MUtil_Echo::out(); -echo $this->headScript(); -echo $this->inlineScript(); -?></body> -</html> \ No newline at end of file Modified: trunk/new_project/application/configs/application.ini =================================================================== --- trunk/new_project/application/configs/application.ini 2012-07-23 10:52:21 UTC (rev 867) +++ trunk/new_project/application/configs/application.ini 2012-07-23 13:31:34 UTC (rev 868) @@ -14,7 +14,7 @@ resources.db.params.password = PASSWD resources.db.isDefaultTableAdapter = true resources.frontController.controllerDirectory = GEMS_PROJECT_PATH "/controllers" -resources.layout.layout = "gemsnew" +resources.layout.layout = "gems-fluid" resources.layout.layoutPath = GEMS_LIBRARY_DIR "/layouts/scripts" firebug.log = 0 Deleted: trunk/new_project/htdocs/gems/css/gems-fixed.css =================================================================== --- trunk/new_project/htdocs/gems/css/gems-fixed.css 2012-07-23 10:52:21 UTC (rev 867) +++ trunk/new_project/htdocs/gems/css/gems-fixed.css 2012-07-23 13:31:34 UTC (rev 868) @@ -1,30 +0,0 @@ -/* Fluid width css */ - -/* Load common css */ -@import url('gems-new.css'); - -/* General styles */ -#all { - margin:0 auto; - padding:0; - border:0; /* This removes the border around the viewport in old versions of IE */ - width:1012px; - overflow: hidden; -} - -/* fixed with for header/footer */ -#header, -#header_bar, -#footer { - clear: both; - width: 1012px; -} - -#main { - width: 842px; - overflow-x: auto; -} - -table.browser, table.timeTable { - width: 830px; /* otherwise no shadow on the right visible */ -} \ No newline at end of file Deleted: trunk/new_project/htdocs/gems/css/gems-fluid.css =================================================================== --- trunk/new_project/htdocs/gems/css/gems-fluid.css 2012-07-23 10:52:21 UTC (rev 867) +++ trunk/new_project/htdocs/gems/css/gems-fluid.css 2012-07-23 13:31:34 UTC (rev 868) @@ -1,24 +0,0 @@ -/* Fluid width css */ - -/* Load common css */ -@import url('gems-new.css'); - -/* General styles */ -#all { - margin:0; - padding:0; - border:0; /* This removes the border around the viewport in old versions of IE */ - width:100%; - min-width:600px; /* Minimum width of layout - remove line if not required */ - /* The min-width property does not work in old versions of Internet Explorer */ -} - -#header, #footer, #header_bar, .zend_echo { - clear:both; - float:left; - width:100%; -} - -table.browser, table.timeTable { - width: 99%; /* to show shadows, 1% off */ -} \ No newline at end of file Deleted: trunk/new_project/htdocs/gems/css/gems-fluid2.css =================================================================== --- trunk/new_project/htdocs/gems/css/gems-fluid2.css 2012-07-23 10:52:21 UTC (rev 867) +++ trunk/new_project/htdocs/gems/css/gems-fluid2.css 2012-07-23 13:31:34 UTC (rev 868) @@ -1,686 +0,0 @@ -/* Fluid width css */ - -/* General styles */ -#all { - margin:0; - padding:0; - border:0; /* This removes the border around the viewport in old versions of IE */ - width:100%; - min-width:600px; /* Minimum width of layout - remove line if not required */ - /* The min-width property does not work in old versions of Internet Explorer */ -} - -#header, #footer, #header_bar, .zend_echo { - clear: both; - float: left; - width: 100%; -} - -#main { - width: 81%; -} - -#main, #menu { - margin: 0.5em 0.5%; /* margin margin margin margin + menu_abs_width */ -} - -#menu { - margin-top: 1em; - width: 16%; -} - -table.browser, table.timeTable { - width: 99%; /* to show shadows, 1% off */ -} - -/* Adapted common css: should move to one file */ - - - -/* Links */ -a { - text-decoration: none; -} - -.actionlink { - white-space: nowrap; -} - -a.actionlink { - font-style: normal; - text-decoration: none; -} - -a.actionlink + a.actionlink, -a.actionlink + span.actionlink, -span.actionlink + a.actionlink, -span.actionlink + span.actionlink { - margin-left: 1em; -} - -span.actionlink { - font-style: italic; -} - -a:hover { - text-decoration: underline; -} - -a[href^="mailto:"] { - background: transparent url(../images/mail.png) no-repeat scroll right center; - padding-right: 20px; -} - -a:hover[href^="mailto:"] { - text-decoration: underline !important; -} - -a.globe { - background: transparent url(../images/globe.png) no-repeat scroll right center; - padding-right: 20px; -} - -a.pdf { - background: transparent url(../images/pdf_small.gif) no-repeat scroll right center; - padding-right: 20px !important; -} - -body { - margin: 0; - padding: 0; -} - -button.ui-datepicker-trigger { - margin: 0 0.25em 0 0.25em; - padding: 0; - vertical-align: middle; -} - -.centerAlign { - text-align: center; -} - -.currentRow { - background-color: aqua; - border: 3px solid darkblue !important; -} - -.deleted { - color: #888888; - font-style: italic; - text-decoration: line-through; /* Bug in Firefox: line-through remains on for descending inline elements */ -} - -.icon { - float: right; - padding-right: 4px; -} - -input[disabled], .disabled { - color: #737373; - font-style: italic; -} - -input[disabled] { - color: #000000; - background: #EBEBE4; -} - -input[readonly] { - background: #EBEBE4; -} - -div, img, li, p, ul { - margin: 0; - padding: 0; -} - -div.buttons { - margin: 0.5em 0; -} - -.zend_echo, .errors { - background: #FAF8CC; - margin: 2px; - padding: 0.25em 0.5em; - border: 1px solid; -} - -.tableSpecial, -.zend_echo, -.errors, -.ui-tabs-nav-item.taberror span { - color: #DD0000; - font-weight: bold; -} - -.errors { - border-radius: 6px; - -moz-border-radius: 6px; - -webkit-border-radius: 6px; - display: inline-block; -} - -dd .errors { - display: block; -} - -ul.errors { - padding-left: 1.5em; - padding-right: 0.5em; -} - -/* Header/footer styles */ -#footer { - margin-bottom: 10px; -} - -#footer div, #header_bar div, #header_bar span { - padding: 1px 3px 2px 3px; -} - -.fullwidth > div { - margin: 0px 5px; /* provide a little 'air' on full-width */ -} - -h1, h2, h3 { - margin: 0.5em 0 0.25em 0; - padding: 0; -} - -h4 { - margin: 0.125em 0; - padding: 0; -} - -#header_bar { - padding: 0px; -} - -#header_bar #contact .dropdownContent { - display: none; -} - -#header_bar #contact:hover .dropdownContent { - display: block; - float: right; - left: -120%; - line-height: 110%; - list-style-type: none; - position: absolute; - text-align: right; - width: 200%; -} - -#header_bar #contact .dropdownContent a { - display: inline-block; - width: 100%; -} - -#header h1 { - margin-top: 0; -} - -#header_bar #organizations { - float:left; - height: 1.7em; - padding-top: 2px; - overflow: hidden; -} - -#header_bar #organizations input, #header_bar #organizations select { margin: 1px; padding: 0px; font-size: 100%;} - -#login .logout { - margin-left: 0.5em; -} - -img { - border: 0 solid transparent; -} - -.indent { - margin-left: 4em; - margin-right: 4em; -} - -.indentLeft { - padding-left: 3em; -} - -input.token_copy { - background-color: #EEEEEE; -} - -label.required { - font-weight: bold; -} - -.leftFloat { - float: left; - margin-right: 0.4em; -} - -.logFile { - border: 2px solid #888888; - /* border-right: 0px transparent; */ - padding: 1px 0 1px 3px; - height: 500px; - overflow: auto; - width: 99%; -} - -.mailpreview { - background-color: #FEFEFE; - border: 3px groove #888888; - margin: 2px 1px; - padding: 2px 0.5em; -} - -#main { - float: right; - /* *padding + *overflow to use only in IE 6 */ - *overflow-x: auto; - *padding-bottom: 25px; -} - -#main_full_width { - background: transparent; - margin-bottom: 10px; - padding: 10px 5px 0 5px; -} - -#main form dd { - display: inline-block; - *display: inline; - margin: 0 10px; -} - -#main form dt { - margin: 0; -} - -#main form dt label { - clear: left; - float: left; - margin: 0 0.25em 0 0; -} - -#main ul { - margin-bottom: 0.75em; - margin-top: 0.75em; -} - -#main #tabContainer ul { - margin-bottom: 0em; - margin-top: 0em; -} - -#main .tooldock .toolbox ul { - margin-bottom: 0; - margin-top: 0; -} - -#menu { - float: left; - padding: 0 0 10px 10px; - word-wrap: break-word; /* IE only feature */ -} - -#menu .navigation { - margin-left: 10px; -} - -#menu .navigation .active { - font-weight: bold; -} - -#menu ul { - margin-bottom: 0; -} - -#menu ul li ul { - margin: 0 0 0.25em 1em; -} - -#menu ul li a { - display: block; - *height: 1%; /* IE 6 Fix */ - margin: 0; - padding: 0; - *width: 115px; /* IE 6 Fix */ -} - -#menu ul li a.breakBefore { - border-top: 1px dotted; - margin: 3px 4px 0 0; - padding: 2px 0 0 0; -} - -#menu ul li a.noParameters { - font-style: italic; -} - -#menu .navigation .active ul li { - font-weight: normal; -} - -#menu .navigation .active ul li.active { - font-weight: bold; -} - -.middleAlign { - vertical-align: middle; -} - -p.description { - display: inline; - font-size: 0.75em; - padding: 2px 6px; -} - -p.info { - margin: 0.75em 0; -} - -.periodSlider { - margin: 0.5em; -} - -.print-only { display: none; } - -.rightAlign { - text-align: right; -} - -.rightFloat { - float: right; - margin-left: 0.4em; -} - -.search { - line-height: 250%; - margin: 0.5em 0; -} - -.search input { - margin: 0 0.2em; -} - -.search .inputgroup { - border: 2px solid; - border-bottom-radius: 6px; - -moz-border-radius: 6px; - -webkit-border-radius: 6px; - clear: both; - float: left; - line-height: 125%; - margin: 0 auto 0.25em 0; - padding: 0.25em 0.5em 0.25em; -} - -.search select { - width: 16em; -} - -.search select.minimal { - width: auto; -} - -select { - max-width: 48em; -} - -select option[value=''], select[value=''] { - color: #737373; - font-style: italic; -} - -.separator { - color: grey; - font-weight: normal; -} - -.smallTime { - font-size: 80%; - font-style: italic; -} - -.sortAsc, .sortAscSelected, .sortDescSelected { - line-height: 1.3em; - padding-bottom: 7px; -} - -.sortAsc:hover, .sortAscSelected, .sortDescSelected:hover { - background: transparent url(../images/sort_asc.png) no-repeat scroll center bottom; -} - -a.sortAscSelected:hover, a.sortDescSelected { - background: transparent url(../images/sort_desc.png) no-repeat scroll center bottom; -} - -span.thetooltip { - display: none; -} - -.sponsoring { - font-size: 80%; - margin: 5em auto 0 auto; - padding: 2px; - text-align: center; -} - -table, td, th { - empty-cells: show; - margin: 0; - overflow: visible; - padding: 0; -} - -table.displayer, table.browser, table.timeTable { - border-collapse: collapse; - border-spacing: 0; - clear: both; - margin: 0 0 0.5em 0; -} - -table.formTable td.label { - padding-top: 4px; - vertical-align: top; -} - -table.formTable td[colspan="2"].label { - text-align: left; -} - -table tr[onclick]:hover, -table td[onclick]:hover, -table th[onclick]:hover { - cursor: pointer; -} - -table .question { - text-indent: -1em; - padding-left: 1em; -} - -table .question_sub { - padding-left: 1em; -} - -table td, table th { - padding: 2px 4px; - vertical-align: top; -} - -table td.selectedColumn, table th.selectedColumn { - border-left: 2px solid; - border-right: 2px solid; -} - -table tfoot td.selectedColumn, table tfoot th.selectedColumn { - border-bottom: 2px solid; -} - -table td.date, table td.token { - white-space: pre; - /* width: 7em; */ -} - -table td.timeResult, table th.timeResult { - width: 5em; -} - -table th { - text-align: left; -} - -table tr.selectedRow td.selectedColumn { - border-bottom: 2px solid; - font-weight: bold; -} - -table tr.selectedRow td.selectedColumn, table thead th.selectedColumn { - border-top: 2px solid; -} - -table.timeTable th a, table.timeTable td a { - color: inherit; -} - -.tab-displaygroup { - float: left; - margin-right: 5px; - /* optionally set a fixed with here for aligning */ -} - -.tab-displaygroup label { - display: inline-block; /* otherwise with won't be applied */ - width: 5em; -} - -.tab-displaygroup input, -.tab-displaygroup select -{ - /* Set a default with so things will align */ - max-width: 6em; -} - -.tabrow { - margin: 0.5em 0 0 0; - *margin-top: 0; - padding: 0; - *padding-top: 0.5em; -} - -.tabrow .tab { - border: 1px solid #000; - border-bottom-width: 0px; - float: left; - margin: 1px 0.5em 0 0; - padding: 0.2em; - text-align: center; - width: 8em; -} - -.tabrow .tab.active { - border: 2px solid #000; - border-bottom-width: 0px; - font-weight: bold; - margin-top: 0; -} - -.tabrow .tab a { - display: block; - margin: 0; - padding: 0; - width: 100%; -} - -.toolbox { - display: inline; - margin: 0.5em 0 0 0.5em; - position: relative; -} - -.toolbox .toolanchor { - display: inline-block; -} - -.toolbox a.toolanchor { - font-weight: bold; -} - -.toolbox ul { - display: none; - list-style-type: none; - position: absolute; - z-index: 100; -} - -.toolbox:hover ul { - display: inline; - max-height: 18.5em; - left: 0; - overflow: auto; - position: absolute; - top: 1.2em; -} - -.toolbox ul li { - list-style-type: none; - margin: 1px 3px; -} - -.toolbox ul li a.add { - display: inline-block; - margin: 1px 0; - overflow: hidden; - padding: 1px 2px; -} - -.toolbox ul li a.right { - width: 16px; -} - - -.toolbox ul li a:hover { - text-decoration: none; -} - - -.tooldock { - padding: 5px; -} - -.tooltip { - background: #FFFFCC; - border: 1px solid #e8f5fd; - padding: 3px 5px; - color: black; - font-size: .8em; - z-index: 10; /* otherwise invisible */ -} - -td.tracksList { - width: 25%; -} - -td .tracksList { - height: 10em; - overflow: auto; -} - -.tracksList p { - margin-bottom: 0.25em; -} - -#wrapper { - position:relative; /* This fixes the IE7 overflow hidden bug and stops the layout jumping out of place */ - clear:both; - float:left; - width:100%; /* width of whole page */ -} - -.zend_echo { - font-weight: normal; -} This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <gem...@li...> - 2012-07-24 09:29:28
|
Revision: 871 http://gemstracker.svn.sourceforge.net/gemstracker/?rev=871&view=rev Author: mennodekker Date: 2012-07-24 09:29:17 +0000 (Tue, 24 Jul 2012) Log Message: ----------- Introduced a switch for cache settings in project.ini Modified Paths: -------------- trunk/library/classes/Gems/Project/ProjectSettings.php trunk/library/classes/GemsEscort.php trunk/new_project/application/configs/project.ini Modified: trunk/library/classes/Gems/Project/ProjectSettings.php =================================================================== --- trunk/library/classes/Gems/Project/ProjectSettings.php 2012-07-24 08:57:06 UTC (rev 870) +++ trunk/library/classes/Gems/Project/ProjectSettings.php 2012-07-24 09:29:17 UTC (rev 871) @@ -243,6 +243,22 @@ } /** + * Get the specified cache method from project settings + * + * @return string + */ + public function getCache() + { + if ($this->offsetExists('cache')) { + $cache = $this->offsetGet('cache'); + } else { + $cache = 'apc'; + } + + return $cache; + } + + /** * Returns an (optional) default organization from the project settings * * @return int Organization number or -1 when not set @@ -326,11 +342,11 @@ /** * Get the logLevel to use with the Gems_Log - * + * * Default settings is for development and testing environment to use Zend_Log::DEBUG and * for all other environments to use the Zend_Log::ERR level. This can be overruled by * specifying a logLevel in the project.ini - * + * * Using a level higher than Zend_Log::ERR will output full error messages, traces and request * info to the logfile. Please be aware that this might introduce a security risk as passwords * might be written to the logfile in plain text. @@ -489,4 +505,4 @@ { return isset($this['password']['initialPassword']); } -} +} \ No newline at end of file Modified: trunk/library/classes/GemsEscort.php =================================================================== --- trunk/library/classes/GemsEscort.php 2012-07-24 08:57:06 UTC (rev 870) +++ trunk/library/classes/GemsEscort.php 2012-07-24 09:29:17 UTC (rev 871) @@ -149,13 +149,17 @@ */ protected function _initCache() { + $this->bootstrap('project'); + + $useCache = $this->getResource('project')->getCache(); + $cache = null; $exists = false; $cachePrefix = GEMS_PROJECT_NAME . '_'; // Check if APC extension is loaded - if( extension_loaded('apc') ) { + if($useCache === 'apc' && extension_loaded('apc') ) { $cacheBackend = 'Apc'; $cacheBackendOptions = array(); //Add path to the prefix as APC is a SHARED cache @@ -174,7 +178,7 @@ } } - if ($exists) { + if ($exists && $useCache <> 'none') { /** * automatic_cleaning_factor disables automatic cleaning of the cache and should get rid of * random delays on heavy traffic sites with File cache. Apc does @@ -1801,4 +1805,4 @@ return $result; } -} +} \ No newline at end of file Modified: trunk/new_project/application/configs/project.ini =================================================================== --- trunk/new_project/application/configs/project.ini 2012-07-24 08:57:06 UTC (rev 870) +++ trunk/new_project/application/configs/project.ini 2012-07-24 09:29:17 UTC (rev 871) @@ -299,15 +299,27 @@ ; ; where %s %s is respecitively the input (url) and ; the output (file) -export.pdfExportCommand = +export.pdfExportCommand = +;--------------------------------------------------------- +; PERFORMANCE +; Define what kind of cache to use. Choose from: +; apc (shared) memory cache, can sometimes be slow due to limited available +; memory in shared environments +; file When filesystem is fast enough or apc is not available +; none No cache - good for development +;--------------------------------------------------------- +cache = "apc" + [testing : production] +cache = "file" admin.user = superadmin admin.pwd = superadmin email.bounce = 1 [development : production] +cache = "none" admin.user = superadmin admin.pwd = superadmin This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <gem...@li...> - 2012-07-24 11:14:13
|
Revision: 875 http://gemstracker.svn.sourceforge.net/gemstracker/?rev=875&view=rev Author: mennodekker Date: 2012-07-24 11:14:04 +0000 (Tue, 24 Jul 2012) Log Message: ----------- Added changelogs to upgrade controller with upgrade permission, a separate privilige is used for the button only project changelog (click on version number in footer) Added initial upgrade level for new projects Modified Paths: -------------- trunk/library/classes/Gems/Default/ProjectInformationAction.php trunk/library/classes/Gems/Menu.php trunk/library/classes/Gems/Upgrades.php Added Paths: ----------- trunk/new_project/var/settings/upgrades.ini Modified: trunk/library/classes/Gems/Default/ProjectInformationAction.php =================================================================== --- trunk/library/classes/Gems/Default/ProjectInformationAction.php 2012-07-24 10:48:15 UTC (rev 874) +++ trunk/library/classes/Gems/Default/ProjectInformationAction.php 2012-07-24 11:14:04 UTC (rev 875) @@ -110,9 +110,14 @@ public function changelogAction() { - $this->_showText($this->_('Changelog'), APPLICATION_PATH . '/changelog.txt'); + $this->_showText(sprintf($this->_('Changelog %s'), $this->escort->project->name), APPLICATION_PATH . '/changelog.txt'); } + public function changeloggtAction() + { + $this->_showText(sprintf($this->_('Changelog %s'), 'GemsTracker'), GEMS_LIBRARY_DIR . '/changelog.txt'); + } + public function errorsAction() { $this->logger->shutdown(); Modified: trunk/library/classes/Gems/Menu.php =================================================================== --- trunk/library/classes/Gems/Menu.php 2012-07-24 10:48:15 UTC (rev 874) +++ trunk/library/classes/Gems/Menu.php 2012-07-24 11:14:04 UTC (rev 875) @@ -217,6 +217,8 @@ //UPGRADES CONTROLLER $page = $setup->addPage($this->_('Upgrade'), 'pr.upgrade', 'upgrade', 'index'); + $page->addPage(sprintf($this->_('Changelog %s'), 'GemsTracker'), 'pr.upgrade', 'project-information', 'changeloggt'); + $page->addPage(sprintf($this->_('Changelog %s'), GEMS_PROJECT_NAME), 'pr.upgrade', 'project-information', 'changelog'); $show = $page->addAction($this->_('Show'), null, 'show')->setNamedParameters('id','context'); $page->addAction($this->_('Execute all'), 'pr.upgrade.all', 'execute-all')->setModelParameters(1); $show->addActionButton($this->_('Execute this'), 'pr.upgrade.one', 'execute-one')->setModelParameters(1)->addNamedParameters('from','from','to','to'); Modified: trunk/library/classes/Gems/Upgrades.php =================================================================== --- trunk/library/classes/Gems/Upgrades.php 2012-07-24 10:48:15 UTC (rev 874) +++ trunk/library/classes/Gems/Upgrades.php 2012-07-24 11:14:04 UTC (rev 875) @@ -61,6 +61,16 @@ $this->register(array($this, 'Upgrade151to152'), 'Upgrade from 1.5.1 to 1.5.2'); $this->register(array($this, 'Upgrade152to153'), 'Upgrade from 1.5.2 to 1.5.3'); $this->register(array($this, 'Upgrade153to154'), 'Upgrade from 1.5.3 to 1.5.4'); + $this->register(array($this, 'Upgrade154to155'), 'Upgrade from 1.5.4 to 1.5.5'); + + /** + * To have the new_project updated to the highest level, update + * + * /new_project/var/settings/upgrades.ini + * + * to have the right index for this context, normally when no index set on register + * it will start counting at 1. + */ } @@ -128,4 +138,16 @@ return true; } + + /** + * To upgrade to 1.5.5 just execute patchlevel 48 + */ + public function Upgrade154to155() + { + $this->_batch->addTask('Db_ExecutePatch', 48); + + $this->_batch->addTask('Echo', $this->_('Make sure to read the changelog as it contains important instructions')); + + return true; + } } \ No newline at end of file Added: trunk/new_project/var/settings/upgrades.ini =================================================================== --- trunk/new_project/var/settings/upgrades.ini (rev 0) +++ trunk/new_project/var/settings/upgrades.ini 2012-07-24 11:14:04 UTC (rev 875) @@ -0,0 +1 @@ +gems = 6 \ No newline at end of file This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <gem...@li...> - 2012-08-29 14:03:34
|
Revision: 909 http://gemstracker.svn.sourceforge.net/gemstracker/?rev=909&view=rev Author: matijsdejong Date: 2012-08-29 14:03:22 +0000 (Wed, 29 Aug 2012) Log Message: ----------- WordParser now accepts double quotes as quotes as well Extra code comments New tests for MUtil/Ra.php and MUtil/Parser/Sql/WordsParser.php Modified Paths: -------------- trunk/library/classes/MUtil/Parser/Sql/WordsParser.php trunk/library/classes/MUtil/Ra.php trunk/test/classes/MUtil/RaTest.php Added Paths: ----------- trunk/test/classes/MUtil/Parser/ trunk/test/classes/MUtil/Parser/Sql/ trunk/test/classes/MUtil/Parser/Sql/WordsParserTest.php Modified: trunk/library/classes/MUtil/Parser/Sql/WordsParser.php =================================================================== --- trunk/library/classes/MUtil/Parser/Sql/WordsParser.php 2012-08-29 13:55:13 UTC (rev 908) +++ trunk/library/classes/MUtil/Parser/Sql/WordsParser.php 2012-08-29 14:03:22 UTC (rev 909) @@ -56,25 +56,22 @@ const MODE_COMMA = 3; const MODE_SEMI_COLON = 4; const MODE_QUOTED_STRING = 100; - const MODE_LINE_COMMENT = 101; - const MODE_ACCESS_NAME = 102; + const MODE_DOUBLE_QUOTED_STRING = 101; + const MODE_LINE_COMMENT = 102; + const MODE_ACCESS_NAME = 104; const MODE_MULTI_LINE_COMMENT = 201; - private $make_word_function; - private $len; - private $len_minus_1; - private $line; - private $pos; - private $start; - private $statement; + private $_makeWordFunction; + private $_len; + private $_lenMinusOne; + private $_line; + private $_pos; + private $_start; + private $_statement; /** * - * @param unknown_type $statements The sql statements to parse - * @param unknown_type $make_word_function aq function in the form: self::makeWord($word, $is_word, $start_line, $start_char) - * @return unknown_type - * - * $make_word_function should be a function accepting these + * $makeWordFunction should be a function accepting these * parameters and returning an object that should be added to * the array returned as a result from splitStatement(): * @@ -82,46 +79,50 @@ * * The default implementations does returns an array of words, * throwing out the positional and word information. + * + * @param string $statements The sql statements to parse + * @param callable $makeWordFunction A function with the parameters: + * function($word, $is_word, $start_line, $start_char) */ - public function __construct($statements, $make_word_function = null) + public function __construct($statements, $makeWordFunction = null) { - $this->statement = $statements; - $this->len = strlen($statements); - $this->len_minus_1 = $this->len - 1; - $this->line = 1; - $this->pos = 1; - $this->start = 0; - if ($make_word_function) { - $this->make_word_function = $make_word_function; + $this->_statement = $statements; + $this->_len = strlen($statements); + $this->_lenMinusOne = $this->_len - 1; + $this->_line = 1; + $this->_pos = 1; + $this->_start = 0; + if ($makeWordFunction) { + $this->_makeWordFunction = $makeWordFunction; } else { - $this->make_word_function = array(__CLASS__, 'makeWord'); + $this->_makeWordFunction = array(__CLASS__, 'makeWord'); } } private function findCharEnd($i, $char, $start_line = 0, $start_pos = 0) { if ($start_line == 0) { - $start_line = $this->line; - $start_pos = $this->pos; + $start_line = $this->_line; + $start_pos = $this->_pos; } - while ((++$i < $this->len) && ($this->statement[$i] != $char)) { + while ((++$i < $this->_len) && ($this->_statement[$i] != $char)) { $this->setLine($i); // Check for escape - if ($this->statement[$i] == '\\') { + if ($this->_statement[$i] == '\\') { $i++; - $this->pos++; + $this->_pos++; } } - if ($i >= $this->len) { + if ($i >= $this->_len) { throw new MUtil_Parser_Sql_WordsParserException('Opening '.$char.' does not close', $start_line, $start_pos); } // Check for character repeat - if (($i < $this->len_minus_1) && ($this->statement[$i + 1] == $char)) { - $this->pos += 2; + if (($i < $this->_lenMinusOne) && ($this->_statement[$i + 1] == $char)) { + $this->_pos += 2; return $this->findCharEnd($i + 1, $char, $start_line, $start_pos); } @@ -135,15 +136,15 @@ $char2 = $chars[1]; if ($start_line == 0) { - $start_line = $this->line; - $start_pos = $this->pos; + $start_line = $this->_line; + $start_pos = $this->_pos; } - while ((++$i < $this->len_minus_1) && (! (($this->statement[$i] == $char1) && ($this->statement[$i + 1] == $char2)))) { + while ((++$i < $this->_lenMinusOne) && (! (($this->_statement[$i] == $char1) && ($this->_statement[$i + 1] == $char2)))) { $this->setLine($i); } - if ($i >= $this->len) { + if ($i >= $this->_len) { throw new MUtil_Parser_Sql_WordsParserException('Opening '.$chars.' does not close', $start_line, $start_pos); } @@ -154,14 +155,14 @@ private function findLineEnd($i) { - $epos = strpos($this->statement, "\n", $i + 1); + $epos = strpos($this->_statement, "\n", $i + 1); if ($epos === false) { - return $this->len; + return $this->_len; } // One less on Windows line end - if ($this->statement[$epos - 1] == "\r") { + if ($this->_statement[$epos - 1] == "\r") { return $epos - 2; } return $epos - 1; @@ -187,7 +188,7 @@ private function mode($i) { - switch ($this->statement[$i]) { + switch ($this->_statement[$i]) { case ' ': case "\n": case "\t": @@ -195,6 +196,8 @@ return self::MODE_WHITESPACE; case '\'': return self::MODE_QUOTED_STRING; + case '"': + return self::MODE_DOUBLE_QUOTED_STRING; case ',': return self::MODE_COMMA; case ';': @@ -207,17 +210,17 @@ case '[': return self::MODE_ACCESS_NAME; case '-': - if (($i < $this->len_minus_1) && ($this->statement[$i + 1] == '-')) { + if (($i < $this->_lenMinusOne) && ($this->_statement[$i + 1] == '-')) { return self::MODE_LINE_COMMENT; } case '/': - if (($i < $this->len_minus_1) && ($this->statement[$i + 1] == '*') && ($this->statement[$i] != '-')) { + if (($i < $this->_lenMinusOne) && ($this->_statement[$i + 1] == '*') && ($this->_statement[$i] != '-')) { return self::MODE_MULTI_LINE_COMMENT; } default: // Last ditch check - if (ctype_space($this->statement[$i])) { + if (ctype_space($this->_statement[$i])) { return self::MODE_WHITESPACE; } @@ -261,19 +264,25 @@ private function setLine($i) { - if ($this->statement[$i] == "\n") { - $this->line++; - $this->pos = 0; + if ($this->_statement[$i] == "\n") { + $this->_line++; + $this->_pos = 0; } else { - $this->pos++; + $this->_pos++; } } - public function splitStatement($keep_comments = true) + /** + * Split the next statement into word parts + * + * @param boolean $keepComments When false comment statements are removed from the output + * @return array Of sql 'words' + */ + public function splitStatement($keepComments = true) { - $i = $this->start; + $i = $this->_start; - if ($i >= $this->len) { + if ($i >= $this->_len) { return; } @@ -281,6 +290,9 @@ case self::MODE_QUOTED_STRING: $i = $this->findCharEnd($i, '\''); break; + case self::MODE_DOUBLE_QUOTED_STRING: + $i = $this->findCharEnd($i, '"'); + break; case self::MODE_LINE_COMMENT: $i = $this->findLineEnd($i) + 1; break; @@ -293,12 +305,12 @@ } $last = null; $mode_start = $i; - $mode_start_line = $this->line; - $mode_start_char = $this->pos; + $mode_start_line = $this->_line; + $mode_start_char = $this->_pos; $sql = array(); - while ($i < $this->len) { + while ($i < $this->_len) { // Take care of positioning $this->setLine($i); @@ -307,17 +319,20 @@ $next_mode = $this->mode($i); if (($this_mode != $next_mode) || self::modeIsOneChar($this_mode)) { - if ($keep_comments || self::modeNotComment($this_mode)) { - $sql[] = call_user_func($this->make_word_function, substr($this->statement, $mode_start, $i - $mode_start), self::modeIsWord($this_mode), $mode_start_line, $mode_start_char); + if ($keepComments || self::modeNotComment($this_mode)) { + $sql[] = call_user_func($this->_makeWordFunction, substr($this->_statement, $mode_start, $i - $mode_start), self::modeIsWord($this_mode), $mode_start_line, $mode_start_char); } $mode_start = $i; - $mode_start_line = $this->line; - $mode_start_char = $this->pos; + $mode_start_line = $this->_line; + $mode_start_char = $this->_pos; switch ($next_mode) { case self::MODE_QUOTED_STRING: $i = $this->findCharEnd($i, '\''); break; + case self::MODE_DOUBLE_QUOTED_STRING: + $i = $this->findCharEnd($i, '"'); + break; case self::MODE_LINE_COMMENT: $i = $this->findLineEnd($i); break; @@ -328,7 +343,7 @@ $i = $this->findCharsEnd($i, '*/'); break; case self::MODE_SEMI_COLON: - $this->start = $i + 1; + $this->_start = $i + 1; return $sql; } } @@ -337,22 +352,32 @@ } // BUG WARNING: Use $next_mode in this line because the while loop has just // exited, so the current mode is the next mode. - if ($sql && ($keep_comments || self::modeNotComment($next_mode))) { - $sql[] = call_user_func($this->make_word_function, substr($this->statement, $mode_start, $i - $mode_start), self::modeIsWord($this_mode), $mode_start_line, $mode_start_char); + if ($sql && ($keepComments || self::modeNotComment($next_mode))) { + $sql[] = call_user_func($this->_makeWordFunction, substr($this->_statement, $mode_start, $i - $mode_start), self::modeIsWord($this_mode), $mode_start_line, $mode_start_char); } - $this->start = $this->len; + $this->_start = $this->_len; return $sql; } - public static function splitStatements($statements, $keep_comments = true, $make_strings = true, $make_word_function = null) + /** + * Split the whole input into statements + * + * @param string $statements One or more SQL statements separated by ';' semicolumns + * @param boolean $keepComments When false comment statements are removed from the output + * @param boolean $makeStrings Return the individual statements as (trimmed) strings instead of arrays + * @param callable $makeWordFunction A function with the parameters: + * function($word, $is_word, $start_line, $start_char) + * @return array Of statements + */ + public static function splitStatements($statements, $keepComments = true, $makeStrings = true, $makeWordFunction = null) { - $parser = new self($statements, $make_word_function); + $parser = new self($statements, $makeWordFunction); $stmts = array(); - while ($stmt = $parser->splitStatement($keep_comments)) { - if ($make_strings) { + while ($stmt = $parser->splitStatement($keepComments)) { + if ($makeStrings) { $sql = implode('', $stmt); if (strlen(trim($sql))) { Modified: trunk/library/classes/MUtil/Ra.php =================================================================== --- trunk/library/classes/MUtil/Ra.php 2012-08-29 13:55:13 UTC (rev 908) +++ trunk/library/classes/MUtil/Ra.php 2012-08-29 14:03:22 UTC (rev 909) @@ -375,7 +375,7 @@ * * @param string $index Index of the column to extract * @param array $input A nested array from which we extract a column - * @param int $mode RELAXED means a v + * @param int $mode STRICT means missing values are returned as 'null' * @return array An array containing the requested column */ public static function column($index, array $input, $mode = self::RELAXED) Added: trunk/test/classes/MUtil/Parser/Sql/WordsParserTest.php =================================================================== --- trunk/test/classes/MUtil/Parser/Sql/WordsParserTest.php (rev 0) +++ trunk/test/classes/MUtil/Parser/Sql/WordsParserTest.php 2012-08-29 14:03:22 UTC (rev 909) @@ -0,0 +1,140 @@ +<?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 MUtil + * @subpackage Parser + * @author Matijs de Jong <mj...@ma...> + * @copyright Copyright (c) 2011 Erasmus MC + * @license New BSD License + * @version $Id$ + */ + +require_once 'PHPUnit/Framework/TestCase.php'; + +/** + * + * + * @package MUtil + * @subpackage Parser + * @copyright Copyright (c) 2011 Erasmus MC + * @license New BSD License + * @since Class available since version 1.5 + */ +class WordsParserTest extends PHPUnit_Framework_TestCase +{ + /** + * + * @var MUtil_Parser_Sql_WordsParser + */ + protected $_parser; + + /** + * Test script containing all kind of comments, quoted values, etc... + * + * @var string + */ + protected $_sql = " +SELECT /* comment */ Something as [Really Something] FROM Nothing; + +-- Hi Mom + +UPDATE Nothing SET Something = '\" /* -- bla' WHERE SomethingElse = \"'quoted'\"; + +-- Bye mom +"; + + /** + * Result array output without comments, contains the full whitespace + * + * This shows you how the raw split is performed + * + * @var array + */ + protected $_sqlOutputArray = array( + array(" +", "SELECT", " ", // Here was a comment + " ", "Something", " ", "as", " ", "[Really Something]", " ", "FROM", " ", "Nothing"), + array(" + +", // another comment +" + +", "UPDATE", " ", "Nothing", " ", "SET", " ", "Something", " ", "=", " ", "'\" /* -- bla'", " ", + "WHERE", " ", "SomethingElse", " ", "=", " ", "\"'quoted'\""), + array(" + +", // Third comment +" +")); + + /** + * Result string output without comments + * + * @var array + */ + protected $_sqlOutputString = array( + "SELECT Something as [Really Something] FROM Nothing", + "UPDATE Nothing SET Something = '\" /* -- bla' WHERE SomethingElse = \"'quoted'\""); + + public function setUp() + { + $this->_parser = new MUtil_Parser_Sql_WordsParser($this->_sql); + } + + public function testParse() + { + $result = $this->_parser->splitStatement(false); + $this->assertEquals($result[1], 'SELECT'); + $this->assertCount(13, $result); + } + + public function testParseComment() + { + $result = $this->_parser->splitStatement(true); + $this->assertEquals($result[3], '/* comment */'); + $this->assertCount(14, $result); + } + + public function testSplitAllArray() + { + $result = MUtil_Parser_Sql_WordsParser::splitStatements($this->_sql, false, false); + $this->assertCount(3, $result); + // $this->assertEquals($result[0], $this->_sqlOutputArray[0]); + // $this->assertEquals($result[1], $this->_sqlOutputArray[1]); + // $this->assertEquals($result[2], $this->_sqlOutputArray[2]); + $this->assertEquals($result, $this->_sqlOutputArray); + } + + public function testSplitAllString() + { + $result = MUtil_Parser_Sql_WordsParser::splitStatements($this->_sql, false, true); + $this->assertCount(2, $result); + $this->assertEquals($result, $this->_sqlOutputString); + } +} Modified: trunk/test/classes/MUtil/RaTest.php =================================================================== --- trunk/test/classes/MUtil/RaTest.php 2012-08-29 13:55:13 UTC (rev 908) +++ trunk/test/classes/MUtil/RaTest.php 2012-08-29 14:03:22 UTC (rev 909) @@ -11,27 +11,69 @@ */ class MUtil_RaTest extends PHPUnit_Framework_TestCase { - public function testFlatten() + protected $_columnTest = array( + 'r1' => array('c1' => 1, 'c2' => 'c1'), + 'r2' => array('c1' => 2, 'c2' => 'c2'), + 'r3' => array('c1' => 3), + ); + + public function testArgsDouble() { - $args = MUtil_Ra::args(array(0 => array(0 => 'f', 1 => array('o' => '0', 0 => 'b')), 1 => array('a' => array('r' => 'r')))); - $this->assertEquals($args, array(0 => 'f', 'o' => '0', 1 => 'b', 'a' => array('r' => 'r'))); - } - - public function testDouble() - { $args = MUtil_Ra::args(array(array('a' => 'b'), array('a' => 'c'))); $this->assertEquals($args, array('a' => 'c')); } - - public function testSkipOrName() + + public function testArgsSkipOrName() { $args = MUtil_Ra::args(array(0 => array(0 => 'f', 1 => array('o' => '0', 0 => 'b')), 1 => array('a' => array('r' => 'r'))), 1); $this->assertEquals($args, array('a' => array('r' => 'r'))); } - - public function testDefaults() + + public function testArgsDefaults() { $args = MUtil_Ra::args(array('r1'), array('class1', 'class2'), array('class1' => 'odd', 'class2' => 'even')); $this->assertEquals($args, array('class1' => 'r1', 'class2' => 'even')); } + + public function testBraceKeys() + { + $args = MUtil_Ra::braceKeys(array(0 => 'a', 'b' => 'c'), '{', '}'); + $this->assertEquals($args, array('{0}' => 'a', '{b}' => 'c')); + } + + public function testBraceKeysLeftOnly() + { + $args = MUtil_Ra::braceKeys(array(0 => 'a', 'b' => 'c'), '"'); + $this->assertEquals($args, array('"0"' => 'a', '"b"' => 'c')); + } + + public function testColumnRelaxed() + { + $args = MUtil_Ra::column('c2', $this->_columnTest, MUtil_Ra::RELAXED); + $this->assertEquals($args, array('r1' => 'c1', 'r2' => 'c2')); + } + + public function testColumnRelaxedEmpty() + { + $args = MUtil_Ra::column('c3', $this->_columnTest, MUtil_Ra::RELAXED); + $this->assertEmpty($args); + } + + public function testColumnRelaxedSkips() + { + $args = MUtil_Ra::column('c2', $this->_columnTest, MUtil_Ra::RELAXED); + $this->assertNotContains('r3', array_keys($args)); + } + + public function testColumnStrict() + { + $args = MUtil_Ra::column('c2', $this->_columnTest, MUtil_Ra::STRICT); + $this->assertEquals($args, array('r1' => 'c1', 'r2' => 'c2', 'r3' => null)); + } + + public function testFlatten() + { + $args = MUtil_Ra::args(array(0 => array(0 => 'f', 1 => array('o' => '0', 0 => 'b')), 1 => array('a' => array('r' => 'r')))); + $this->assertEquals($args, array(0 => 'f', 'o' => '0', 1 => 'b', 'a' => array('r' => 'r'))); + } } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <gem...@li...> - 2012-08-30 15:21:45
|
Revision: 919 http://gemstracker.svn.sourceforge.net/gemstracker/?rev=919&view=rev Author: matijsdejong Date: 2012-08-30 15:21:34 +0000 (Thu, 30 Aug 2012) Log Message: ----------- Added TableModel fetch and insert tests Added Paths: ----------- trunk/test/classes/MUtil/Model/TableModelTest.php trunk/test/classes/MUtil/Model/TableModelTest.sql trunk/test/classes/MUtil/Model/TableModelTest.xml Property Changed: ---------------- trunk/scripts/ Property changes on: trunk/scripts ___________________________________________________________________ Added: svn:ignore + docs gems.lint reports tmp Added: trunk/test/classes/MUtil/Model/TableModelTest.php =================================================================== --- trunk/test/classes/MUtil/Model/TableModelTest.php (rev 0) +++ trunk/test/classes/MUtil/Model/TableModelTest.php 2012-08-30 15:21:34 UTC (rev 919) @@ -0,0 +1,117 @@ +<?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 MUtil + * @subpackage Model + * @author Matijs de Jong <mj...@ma...> + * @copyright Copyright (c) 2011 Erasmus MC + * @license New BSD License + * @version $Id$ + */ + +/** + * + * + * @package MUtil + * @subpackage Model + * @copyright Copyright (c) 2011 Erasmus MC + * @license New BSD License + * @since Class available since version 1.5.6 + */ +class MUtil_Model_TableModelTest extends Zend_Test_PHPUnit_DatabaseTestCase +{ + /** + * + * @var PHPUnit_Extensions_Database_DB_IDatabaseConnection + */ + private $_connectionMock; + + /** + * + * @var MUtil_Model_TableModel + */ + private $_model; + + /** + * Returns the test database connection. + * + * @return PHPUnit_Extensions_Database_DB_IDatabaseConnection + */ + protected function getConnection() + { + if($this->_connectionMock == null) { + $connection = Zend_Db::factory('Pdo_Sqlite', array('dbname' => ':memory:', 'username' => 'test')); + + $sql = file_get_contents(str_replace('.php', '.sql', __FILE__)); + $stmt = $connection->query($sql); + $this->_connectionMock = $this->createZendDbConnection( + $connection, 'zfunittests' + ); + Zend_Db_Table_Abstract::setDefaultAdapter($connection); + } + + return $this->_connectionMock; + } + + /** + * Returns the test dataset. + * + * @return PHPUnit_Extensions_Database_DataSet_IDataSet + */ + protected function getDataSet() + { + return $this->createFlatXMLDataSet(str_replace('.php', '.xml', __FILE__)); + } + + protected function getModel() + { + if (! $this->_model) { + $this->_model = new MUtil_Model_TableModel('t1'); + } + + return $this->_model; + } + + public function testHasFirstRow() + { + $model = $this->getModel(); + $rows = $model->load(); + $this->assertCount(1, $rows); + } + + public function testInsertARow() + { + $model = $this->getModel(); + $result = $model->save(array('id' => null, 'c1' => "col1-2", 'c2' => "col2-2")); + $this->assertEquals(2, $result['id']); + + $rows = $model->load(); + $this->assertCount(2, $rows); + } +} Added: trunk/test/classes/MUtil/Model/TableModelTest.sql =================================================================== --- trunk/test/classes/MUtil/Model/TableModelTest.sql (rev 0) +++ trunk/test/classes/MUtil/Model/TableModelTest.sql 2012-08-30 15:21:34 UTC (rev 919) @@ -0,0 +1,6 @@ + +CREATE TABLE t1 ( + id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, + c1 VARCHAR(10), + c2 VARCHAR(10) +) Added: trunk/test/classes/MUtil/Model/TableModelTest.xml =================================================================== --- trunk/test/classes/MUtil/Model/TableModelTest.xml (rev 0) +++ trunk/test/classes/MUtil/Model/TableModelTest.xml 2012-08-30 15:21:34 UTC (rev 919) @@ -0,0 +1,4 @@ +<?xml version="1.0" encoding="ISO-8859-1"?> +<dataset> + <t1 id="1" c1="col1-1" c2="col2-1" /> +</dataset> \ No newline at end of file This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <gem...@li...> - 2012-09-13 13:08:29
|
Revision: 941 http://gemstracker.svn.sourceforge.net/gemstracker/?rev=941&view=rev Author: matijsdejong Date: 2012-09-13 13:08:17 +0000 (Thu, 13 Sep 2012) Log Message: ----------- Fixed #563; database patches now work correctly Removed obsolete references to gems__languages Corrected references to gems__track to gems__tracks Phing now outputs two SQL while database creation scripts: one for tests using sql lite and one for ER diagramming tools Modified Paths: -------------- trunk/library/configs/db/tables/gems__organizations.20.sql trunk/library/configs/db/tables/gems__radius_config.999.sql trunk/library/configs/db/tables/gems__respondent2track.40.sql trunk/library/configs/db/tables/gems__respondents.30.sql trunk/library/configs/db/tables/gems__roles.20.sql trunk/library/configs/db/tables/gems__round_periods.50.sql trunk/library/configs/db/tables/gems__rounds.40.sql trunk/library/configs/db/tables/gems__staff.20.sql trunk/library/configs/db/tables/gems__tokens.200.sql trunk/library/configs/db/tables/gems__user_logins.10.sql trunk/library/configs/db/tables/gems__user_passwords.50.sql trunk/scripts/build.xml trunk/test/data/gems__respondents.sql Added Paths: ----------- trunk/test/data/sqllite/ trunk/test/data/sqllite/create-lite.sql Property Changed: ---------------- trunk/scripts/ Modified: trunk/library/configs/db/tables/gems__organizations.20.sql =================================================================== --- trunk/library/configs/db/tables/gems__organizations.20.sql 2012-09-12 18:45:41 UTC (rev 940) +++ trunk/library/configs/db/tables/gems__organizations.20.sql 2012-09-13 13:08:17 UTC (rev 941) @@ -1,3 +1,4 @@ + CREATE TABLE if not exists gems__organizations ( gor_id_organization bigint unsigned not null auto_increment, @@ -18,8 +19,7 @@ gor_signature text CHARACTER SET 'utf8' COLLATE 'utf8_general_ci' null, gor_style varchar(15) CHARACTER SET 'utf8' COLLATE 'utf8_general_ci' not null default 'gems', - gor_iso_lang char(2) CHARACTER SET 'utf8' COLLATE 'utf8_general_ci' - not null default 'en' references gems__languages (gml_iso_lang), + gor_iso_lang char(2) CHARACTER SET 'utf8' COLLATE 'utf8_general_ci' not null default 'en', gor_has_login boolean not null default 1, gor_has_respondents boolean not null default 0, @@ -34,12 +34,12 @@ gor_created_by bigint unsigned not null, PRIMARY KEY(gor_id_organization), - UNIQUE (gor_code) + KEY (gor_code) ) ENGINE=InnoDB AUTO_INCREMENT = 70 CHARACTER SET 'utf8' COLLATE 'utf8_general_ci'; -INSERT ignore INTO `gems__organizations` (`gor_id_organization`, `gor_name`, gor_changed, gor_changed_by, gor_created, gor_created_by) +INSERT ignore INTO gems__organizations (gor_id_organization, gor_name, gor_changed, gor_changed_by, gor_created, gor_created_by) VALUES (70, 'New organization', CURRENT_TIMESTAMP, 0, CURRENT_TIMESTAMP, 0); Modified: trunk/library/configs/db/tables/gems__radius_config.999.sql =================================================================== --- trunk/library/configs/db/tables/gems__radius_config.999.sql 2012-09-12 18:45:41 UTC (rev 940) +++ trunk/library/configs/db/tables/gems__radius_config.999.sql 2012-09-13 13:08:17 UTC (rev 941) @@ -1,3 +1,4 @@ + CREATE TABLE IF NOT EXISTS `gems__radius_config` ( `grcfg_id` bigint(11) NOT NULL auto_increment, `grcfg_id_organization` bigint(11) NOT NULL, Modified: trunk/library/configs/db/tables/gems__respondent2track.40.sql =================================================================== --- trunk/library/configs/db/tables/gems__respondent2track.40.sql 2012-09-12 18:45:41 UTC (rev 940) +++ trunk/library/configs/db/tables/gems__respondent2track.40.sql 2012-09-13 13:08:17 UTC (rev 941) @@ -1,7 +1,7 @@ CREATE TABLE if not exists gems__respondent2track ( gr2t_id_respondent_track bigint unsigned not null auto_increment, - + gr2t_id_user bigint unsigned not null references gems__respondents (grs_id_user), gr2t_id_track int unsigned not null references gems__tracks (gtr_id_track), @@ -9,15 +9,16 @@ gr2t_start_date datetime null, gr2t_end_date datetime null, - gr2t_id_organization bigint unsigned not null + gr2t_id_organization bigint unsigned not null references gems__organizations (gor_id_organization), gr2t_active boolean not null default 1, gr2t_count int unsigned not null default 0, gr2t_completed int unsigned not null default 0, - + gr2t_reception_code varchar(20) CHARACTER SET 'utf8' COLLATE 'utf8_general_ci' default 'OK' not null references gems__reception_codes (grc_id_reception_code), + gr2t_comment varchar(250) CHARACTER SET 'utf8' COLLATE 'utf8_general_ci' null, gr2t_changed timestamp not null default current_timestamp on update current_timestamp, gr2t_changed_by bigint unsigned not null, Modified: trunk/library/configs/db/tables/gems__respondents.30.sql =================================================================== --- trunk/library/configs/db/tables/gems__respondents.30.sql 2012-09-12 18:45:41 UTC (rev 940) +++ trunk/library/configs/db/tables/gems__respondents.30.sql 2012-09-13 13:08:17 UTC (rev 941) @@ -1,6 +1,6 @@ CREATE TABLE if not exists gems__respondents ( - grs_id_user bigint unsigned not null auto_increment, + grs_id_user bigint unsigned not null auto_increment references gems__user_ids (gui_id_user), -- grs_login varchar(20) CHARACTER SET 'utf8' COLLATE 'utf8_general_ci' -- null unique key, @@ -29,8 +29,7 @@ -- references gems_staff (grs_id_user), -- grs_id_primary_group bigint unsigned -- references gems__groups (umg_id_group), - grs_iso_lang char(2) CHARACTER SET 'utf8' COLLATE 'utf8_general_ci' - not null default 'en' references gems__languages (gml_iso_lang), + grs_iso_lang char(2) CHARACTER SET 'utf8' COLLATE 'utf8_general_ci' not null default 'en', grs_email varchar(100) CHARACTER SET 'utf8' COLLATE 'utf8_general_ci' null, Modified: trunk/library/configs/db/tables/gems__roles.20.sql =================================================================== --- trunk/library/configs/db/tables/gems__roles.20.sql 2012-09-12 18:45:41 UTC (rev 940) +++ trunk/library/configs/db/tables/gems__roles.20.sql 2012-09-13 13:08:17 UTC (rev 941) @@ -33,4 +33,4 @@ ('physician','physician','','staff', CURRENT_TIMESTAMP, 1, CURRENT_TIMESTAMP, 1), ('researcher','researcher','pr.project-information.changelog,pr.contact,pr.export,pr.plan.token,pr.plan.respondent,pr.plan.overview,pr.option.password,pr.option.edit,pr.organization-switch,pr.islogin','guest', CURRENT_TIMESTAMP, 1, CURRENT_TIMESTAMP, 1), ('admin','admin','pr.consent,pr.consent.create,pr.consent.edit,pr.group,pr.role,pr.mail,pr.mail.create,pr.mail.delete,pr.mail.edit,pr.mail.log,pr.organization,pr.organization-switch,pr.plan.overview.excel,pr.plan.respondent,pr.plan.respondent.excel,pr.plan.token.excel,pr.project-information,pr.reception,pr.reception.create,pr.reception.edit,pr.respondent.choose-org,pr.respondent.delete,pr.respondent.result,pr.source,pr.staff.create,pr.staff.delete,pr.staff.edit,pr.staff.see.all,pr.survey-maintenance,pr.track-maintenance,pr.token.mail.freetext','staff,researcher,security', CURRENT_TIMESTAMP, 1, CURRENT_TIMESTAMP, 1), - ('super','super','pr.consent.delete,pr.country,pr.country.create,pr.country.delete,pr.country.edit,pr.database,pr.database.create,pr.database.delete,pr.database.edit,pr.database.execute,pr.database.patches,pr.group.create,pr.group.edit,pr.language,pr.mail.server,pr.mail.server.create,pr.mail.server.delete,pr.mail.server.edit,pr.organization.create,pr.organization.edit,pr.plan.choose-org,pr.plan.mail-as-application,pr.reception.delete,pr.role.create,pr.role.edit,pr.source.create,pr.source.edit,pr.source.synchronize,pr.source.synchronize-all,pr.staff.edit.all,pr.survey-maintenance.edit,pr.track-maintenance.create,pr.track-maintenance.edit,pr.maintenance','admin', CURRENT_TIMESTAMP, 1, CURRENT_TIMESTAMP, 1); + ('super','super','pr.consent.delete,pr.country,pr.country.create,pr.country.delete,pr.country.edit,pr.database,pr.database.create,pr.database.delete,pr.database.edit,pr.database.execute,pr.database.patches,pr.group.create,pr.group.edit,pr.language,pr.mail.server,pr.mail.server.create,pr.mail.server.delete,pr.mail.server.edit,pr.organization.create,pr.organization.edit,pr.plan.choose-org,pr.plan.mail-as-application,pr.reception.delete,pr.respondent.multiorg,pr.role.create,pr.role.edit,pr.source.create,pr.source.edit,pr.source.synchronize,pr.source.synchronize-all,pr.staff.edit.all,pr.survey-maintenance.edit,pr.track-maintenance.create,pr.track-maintenance.edit,pr.maintenance','admin', CURRENT_TIMESTAMP, 1, CURRENT_TIMESTAMP, 1); Modified: trunk/library/configs/db/tables/gems__round_periods.50.sql =================================================================== --- trunk/library/configs/db/tables/gems__round_periods.50.sql 2012-09-12 18:45:41 UTC (rev 940) +++ trunk/library/configs/db/tables/gems__round_periods.50.sql 2012-09-13 13:08:17 UTC (rev 941) @@ -2,14 +2,14 @@ CREATE TABLE if not exists gems__round_periods ( grp_id_round bigint unsigned not null references gems__rounds (gro_id_round), - grp_valid_after_id bigint unsigned null + grp_valid_after_id bigint unsigned null references gems__rounds (gro_id_round), grp_valid_after_source varchar(12) CHARACTER SET 'utf8' COLLATE 'utf8_general_ci' not null default 'tok', grp_valid_after_field varchar(64) CHARACTER SET 'utf8' COLLATE 'utf8_general_ci' not null default 'gto_valid_from', grp_valid_after_unit char(1) CHARACTER SET 'utf8' COLLATE 'utf8_general_ci' not null default 'M', grp_valid_after_length int not null default 0, - grp_valid_for_id bigint unsigned null + grp_valid_for_id bigint unsigned null references gems__rounds (gro_id_round), grp_valid_for_source varchar(12) CHARACTER SET 'utf8' COLLATE 'utf8_general_ci' not null default 'nul', grp_valid_for_field varchar(64) CHARACTER SET 'utf8' COLLATE 'utf8_general_ci' null default null, @@ -26,10 +26,10 @@ ENGINE=InnoDB auto_increment = 40000 CHARACTER SET 'utf8' COLLATE 'utf8_general_ci'; - -INSERT INTO gems__round_periods - (grp_id_round, +INSERT INTO gems__round_periods + (grp_id_round, + grp_valid_after_id, grp_valid_after_source, grp_valid_after_field, grp_valid_after_unit, grp_valid_after_length, grp_valid_for_id, grp_valid_for_source, grp_valid_for_field, grp_valid_for_unit, grp_valid_for_length, @@ -38,48 +38,48 @@ SELECT r1.gro_id_round AS grp_id_round, r2.gro_id_round AS grp_valid_after_id, - CASE + CASE WHEN r2.gro_id_round IS NULL THEN 'rtr' WHEN r1.gro_used_date = 'A' THEN 'tok' WHEN r1.gro_used_date = 'C' THEN 'tok' WHEN r1.gro_used_date = 'F' AND (gsu_followup_field IS NULL OR gsu_followup_field = 'submitdate') THEN 'tok' ELSE 'ans' - END as grp_valid_after_source, - CASE + END as grp_valid_after_source, + CASE WHEN r2.gro_id_round IS NULL THEN 'gr2t_start_date' WHEN r1.gro_used_date = 'A' THEN 'gto_valid_from' WHEN r1.gro_used_date = 'C' THEN 'gto_completion_time' WHEN r1.gro_used_date = 'F' AND (gsu_followup_field IS NULL OR gsu_followup_field = 'submitdate') THEN 'gto_completion_time' ELSE gsu_followup_field - END as grp_valid_after_field, - coalesce(substring(r1.gro_valid_after, 1, 1), 'M') AS grp_valid_after_unit, + END as grp_valid_after_field, + coalesce(substring(r1.gro_valid_after, 1, 1), 'M') AS grp_valid_after_unit, coalesce(convert(substring(r1.gro_valid_after, 2), signed), 0) AS grp_valid_after_length, r1.gro_id_round AS grp_valid_for_id, - CASE - WHEN coalesce(convert(substring(r1.gro_valid_for, 2), signed), 0) = 0 THEN 'nul' - ELSE 'tok' - END AS grp_valid_for_source, - CASE - WHEN coalesce(convert(substring(r1.gro_valid_for, 2), signed), 0) = 0 THEN null - ELSE 'gto_valid_from' - END AS grp_valid_for_field, - coalesce(substring(r1.gro_valid_for, 1, 1), 'M') AS grp_valid_for_unit, + CASE + WHEN coalesce(convert(substring(r1.gro_valid_for, 2), signed), 0) = 0 THEN 'nul' + ELSE 'tok' + END AS grp_valid_for_source, + CASE + WHEN coalesce(convert(substring(r1.gro_valid_for, 2), signed), 0) = 0 THEN null + ELSE 'gto_valid_from' + END AS grp_valid_for_field, + coalesce(substring(r1.gro_valid_for, 1, 1), 'M') AS grp_valid_for_unit, coalesce(convert(substring(r1.gro_valid_for, 2), signed), 0) AS grp_valid_for_length, r1.gro_changed, r1.gro_changed_by, r1.gro_created, r1.gro_created_by FROM gems__rounds AS r1 INNER JOIN gems__tracks ON r1.gro_id_track = gtr_id_track - LEFT JOIN (gems__rounds AS r2 + LEFT JOIN (gems__rounds AS r2 INNER JOIN gems__surveys ON r2.gro_id_survey = gsu_id_survey) - ON r1.gro_id_track = r2.gro_id_track AND r1.gro_id_order > r2.gro_id_order - AND r2.gro_id_order = + ON r1.gro_id_track = r2.gro_id_track AND r1.gro_id_order > r2.gro_id_order + AND r2.gro_id_order = (SELECT MAX(r3.gro_id_order) FROM gems__rounds AS r3 WHERE r1.gro_id_track = r3.gro_id_track AND r1.gro_id_order > r3.gro_id_order) WHERE gtr_track_type = 'T' AND gtr_track_model = 'TrackModel' ORDER BY r1.gro_id_round; -INSERT INTO gems__round_periods - (grp_id_round, +INSERT INTO gems__round_periods + (grp_id_round, grp_valid_after_id, grp_valid_after_source, grp_valid_after_field, grp_valid_after_unit, grp_valid_after_length, @@ -88,40 +88,40 @@ SELECT r1.gro_id_round AS grp_id_round, r2.gro_id_round AS grp_valid_after_id, - CASE + CASE WHEN r2.gro_id_round IS NULL THEN 'rtr' WHEN r1.gro_used_date = 'A' THEN 'tok' WHEN r1.gro_used_date = 'C' THEN 'tok' WHEN r1.gro_used_date = 'F' AND (gsu_followup_field IS NULL OR gsu_followup_field = 'submitdate') THEN 'tok' ELSE 'ans' - END as grp_valid_after_source, - CASE + END as grp_valid_after_source, + CASE WHEN r2.gro_id_round IS NULL THEN 'gr2t_start_date' WHEN r1.gro_used_date = 'A' THEN 'gto_valid_from' WHEN r1.gro_used_date = 'C' THEN 'gto_completion_time' WHEN r1.gro_used_date = 'F' AND (gsu_followup_field IS NULL OR gsu_followup_field = 'submitdate') THEN 'gto_completion_time' ELSE gsu_followup_field - END as grp_valid_after_field, - coalesce(substring(r1.gro_valid_after, 1, 1), 'M') AS grp_valid_after_unit, + END as grp_valid_after_field, + coalesce(substring(r1.gro_valid_after, 1, 1), 'M') AS grp_valid_after_unit, coalesce(convert(substring(r1.gro_valid_after, 2), signed), 0) AS grp_valid_after_length, r1.gro_id_round AS grp_valid_for_id, - CASE - WHEN coalesce(convert(substring(r1.gro_valid_for, 2), signed), 0) = 0 THEN 'nul' - ELSE 'tok' - END AS grp_valid_for_source, - CASE - WHEN coalesce(convert(substring(r1.gro_valid_for, 2), signed), 0) = 0 THEN null - ELSE 'gto_valid_from' - END AS grp_valid_for_field, - coalesce(substring(r1.gro_valid_for, 1, 1), 'M') AS grp_valid_for_unit, + CASE + WHEN coalesce(convert(substring(r1.gro_valid_for, 2), signed), 0) = 0 THEN 'nul' + ELSE 'tok' + END AS grp_valid_for_source, + CASE + WHEN coalesce(convert(substring(r1.gro_valid_for, 2), signed), 0) = 0 THEN null + ELSE 'gto_valid_from' + END AS grp_valid_for_field, + coalesce(substring(r1.gro_valid_for, 1, 1), 'M') AS grp_valid_for_unit, coalesce(convert(substring(r1.gro_valid_for, 2), signed), 0) AS grp_valid_for_length, r1.gro_changed, r1.gro_changed_by, r1.gro_created, r1.gro_created_by FROM gems__rounds AS r1 INNER JOIN gems__tracks ON r1.gro_id_track = gtr_id_track - LEFT JOIN (gems__rounds AS r2 + LEFT JOIN (gems__rounds AS r2 INNER JOIN gems__surveys ON r2.gro_id_survey = gsu_id_survey) - ON r1.gro_id_track = r2.gro_id_track AND r1.gro_used_date_order = r2.gro_id_order + ON r1.gro_id_track = r2.gro_id_track AND r1.gro_used_date_order = r2.gro_id_order WHERE gtr_track_type = 'T' AND gtr_track_model = 'NewTrackModel' ORDER BY r1.gro_id_round; Modified: trunk/library/configs/db/tables/gems__rounds.40.sql =================================================================== --- trunk/library/configs/db/tables/gems__rounds.40.sql 2012-09-12 18:45:41 UTC (rev 940) +++ trunk/library/configs/db/tables/gems__rounds.40.sql 2012-09-13 13:08:17 UTC (rev 941) @@ -2,7 +2,7 @@ CREATE TABLE if not exists gems__rounds ( gro_id_round bigint unsigned not null auto_increment, - gro_id_track bigint unsigned not null references gems__track (gtr_id_track), + gro_id_track bigint unsigned not null references gems__tracks (gtr_id_track), gro_id_order int not null default 10, gro_id_survey bigint unsigned not null references gems__surveys (gsu_id_survey), Modified: trunk/library/configs/db/tables/gems__staff.20.sql =================================================================== --- trunk/library/configs/db/tables/gems__staff.20.sql 2012-09-12 18:45:41 UTC (rev 940) +++ trunk/library/configs/db/tables/gems__staff.20.sql 2012-09-13 13:08:17 UTC (rev 941) @@ -18,12 +18,10 @@ gsf_id_primary_group bigint unsigned references gems__groups (ggp_id_group), - gsf_iso_lang char(2) CHARACTER SET 'utf8' COLLATE 'utf8_general_ci' - not null default 'nl' references gems__languages (gml_iso_lang), + gsf_iso_lang char(2) CHARACTER SET 'utf8' COLLATE 'utf8_general_ci' not null default 'en', gsf_logout_on_survey boolean not null default 0, - gsf_email varchar(100) CHARACTER SET 'utf8' COLLATE 'utf8_general_ci' - unique key, + gsf_email varchar(100) CHARACTER SET 'utf8' COLLATE 'utf8_general_ci', gsf_first_name varchar(30) CHARACTER SET 'utf8' COLLATE 'utf8_general_ci', gsf_surname_prefix varchar(10) CHARACTER SET 'utf8' COLLATE 'utf8_general_ci', @@ -54,9 +52,10 @@ gsf_created timestamp not null, gsf_created_by bigint unsigned not null, - PRIMARY KEY(gsf_id_user), - UNIQUE KEY(gsf_login, gsf_id_organization), - UNIQUE KEY(gsf_reset_key) + PRIMARY KEY (gsf_id_user), + UNIQUE KEY (gsf_login, gsf_id_organization), + UNIQUE KEY (gsf_reset_key) + KEY (gsf_email) ) ENGINE=InnoDB AUTO_INCREMENT = 2001 Modified: trunk/library/configs/db/tables/gems__tokens.200.sql =================================================================== --- trunk/library/configs/db/tables/gems__tokens.200.sql 2012-09-12 18:45:41 UTC (rev 940) +++ trunk/library/configs/db/tables/gems__tokens.200.sql 2012-09-13 13:08:17 UTC (rev 941) @@ -13,7 +13,7 @@ gto_id_organization bigint unsigned not null references gems__organizations (gor_id_organization), gto_id_track bigint unsigned not null - references gems__track (gtr_id_track), + references gems__tracks (gtr_id_track), -- values initially filled from gems__rounds, but that may get different values later on gto_id_survey bigint unsigned not null references gems__surveys (gsu_id_survey), @@ -54,6 +54,7 @@ INDEX (gto_id_track), INDEX (gto_id_round), INDEX (gto_in_source), + INDEX (gto_reception_code), INDEX (gto_id_respondent_track, gto_round_order), INDEX (gto_valid_from, gto_valid_until), INDEX (gto_completion_time) Modified: trunk/library/configs/db/tables/gems__user_logins.10.sql =================================================================== --- trunk/library/configs/db/tables/gems__user_logins.10.sql 2012-09-12 18:45:41 UTC (rev 940) +++ trunk/library/configs/db/tables/gems__user_logins.10.sql 2012-09-13 13:08:17 UTC (rev 941) @@ -4,7 +4,7 @@ CREATE TABLE if not exists gems__user_logins ( gul_id_user bigint unsigned not null auto_increment, - gul_login varchar(30) CHARACTER SET 'utf8' COLLATE 'utf8_general_ci' not null, + gul_login varchar(30) CHARACTER SET 'utf8' COLLATE 'utf8_general_ci' not null references gems__staff (gsf_login), gul_id_organization bigint not null references gems__organizations (gor_id_organization), gul_user_class varchar(30) CHARACTER SET 'utf8' COLLATE 'utf8_general_ci' not null default 'NoLogin', Modified: trunk/library/configs/db/tables/gems__user_passwords.50.sql =================================================================== --- trunk/library/configs/db/tables/gems__user_passwords.50.sql 2012-09-12 18:45:41 UTC (rev 940) +++ trunk/library/configs/db/tables/gems__user_passwords.50.sql 2012-09-13 13:08:17 UTC (rev 941) @@ -14,7 +14,8 @@ gup_created timestamp not null, gup_created_by bigint unsigned not null, - PRIMARY KEY (gup_id_user) + PRIMARY KEY (gup_id_user), + UNIQUE KEY (gup_reset_key) ) ENGINE=InnoDB CHARACTER SET 'utf8' COLLATE 'utf8_general_ci'; Property changes on: trunk/scripts ___________________________________________________________________ Modified: svn:ignore - depend-chart_map.shtml depend-overview_map.shtml docs gems.lint reports tmp + depend-chart_map.shtml depend-overview_map.shtml docs gems.lint reports sql tmp Modified: trunk/scripts/build.xml =================================================================== --- trunk/scripts/build.xml 2012-09-12 18:45:41 UTC (rev 940) +++ trunk/scripts/build.xml 2012-09-13 13:08:17 UTC (rev 941) @@ -5,20 +5,75 @@ <include name="MUtil/**/*.php"/> <include name="GemsEscort.php"/> </fileset> - + + <fileset id="sql-creation-scripts" dir="../library/configs/db/tables"> + <include name="*.sql"/> + </fileset> + <!-- Clean up generated files --> <target name="clean"> <delete file="gems.lint"/> <delete dir="docs"/> <delete dir="reports"/> + <delete dir="sql"/> </target> - - <!-- Prepare workspace --> + + <!-- Prepare workspace --> <target name="prepare"> <mkdir dir="reports"/> <mkdir dir="docs"/> + <mkdir dir="sql"/> </target> - + + <!-- Merge SQL creation scripts --> + <target name="sql-merge"> + <delete file="sql/create-all.sql"/> + <append destFile="sql/create-all.sql"> + <fileset refid="sql-creation-scripts"/> + <filterchain> + <iconvfilter inputencoding="ISO-8859-1" outputencoding="UTF-8" /> + <replaceregexp> + <!-- MySQL Workbench does not know the BOOLEAN type --> + <regexp pattern="(\s)BOOLEAN(\s)" replace="\1TINYINT(1)\2" ignoreCase="true"/> + </replaceregexp> + </filterchain> + </append> + </target> + + <!-- Merge SQL creation scripts --> + <target name="sql-lite"> + <mkdir dir="../test/data/sqllite/"/> + <delete file="../test/data/sqllite/create-lite.sql"/> + <append destFile="../test/data/sqllite/create-lite.sql"> + <fileset refid="sql-creation-scripts"/> + <filterchain> + <replaceregexp> + <!-- MySQL Workbench does not know the BOOLEAN type --> + <regexp pattern="\`([^\`]*)\`" replace='"\1"' ignoreCase="false"/> + <regexp pattern="CREATE\s+TABLE\s+if\s+not\s+exists\s+" replace="CREATE TABLE " ignoreCase="true"/> + <regexp pattern="AUTO_INCREMENT\s*=\s*\d+\s*" replace="" ignoreCase="true"/> + <regexp pattern="AUTO_INCREMENT" replace="AUTOINCREMENT" ignoreCase="true"/> + <regexp pattern="(\sUNIQUE)\s+KEY(\s+|,|\()" replace="\1\2" ignoreCase="true"/> + <regexp pattern="(\sUNIQUE\s)\s*[^\s(]+\s+\(" replace="\1(" ignoreCase="true"/> + <regexp pattern=",\s*INDEX\s*\([^)]+\)" replace="" ignoreCase="true"/> + <regexp pattern="(\s)BOOLEAN(\s)" replace="\1TINYINT(1)\2" ignoreCase="true"/> + <regexp pattern="ENGINE=[^\s,;]+\s*" replace="" ignoreCase="true"/> + <regexp pattern="CHARACTER\s+SET\s+[^\s,;]+\s*" replace="" ignoreCase="true"/> + <regexp pattern="COLLATE\s+[^\s,;]+\s*" replace="" ignoreCase="true"/> + <regexp pattern="ENUM\s[^)]+\)\s*" replace="" ignoreCase="true"/> + <regexp pattern="SET\s[^)]+\)\s*" replace="" ignoreCase="true"/> + <regexp pattern="UNSIGNED\s*" replace="" ignoreCase="true"/> + <regexp pattern="(\s)(DATETIME|DATE|TIMESTAMP)(\s|,)" replace="\1TEXT\3" ignoreCase="true"/> + <regexp pattern="\s+DEFAULT\s+NULL(\s+|,)" replace="\1" ignoreCase="true"/> + <regexp pattern="(?:(\s+NOT\s+NULL)|\s+NULL)([\s,])" replace="\1\2" ignoreCase="true"/> + <regexp pattern="\s+ON\s+UPDATE\s+CURRENT_TIMESTAMP" replace="" ignoreCase="true"/> + <regexp pattern="\s+REFERENCES\s+[^\s]+\s+\([^)]+\)\s*" replace="" ignoreCase="true"/> + <!-- regexp pattern="\s+REFERENCES\s+[^\s,]+\s*" replace="" ignoreCase="true"/ --> + </replaceregexp> + </filterchain> + </append> + </target> + <!-- Run lint --> <target name="lint"> <phplint haltonfailure="true" cachefile="gems.lint"> @@ -34,14 +89,14 @@ <fileset refid="library"/> </docblox> </target> - + <!-- Gather metrics --> <target name="build-metrics"> <phpmd> <formatter type="html" outfile="reports/pmd.html"/> <fileset refid="library"/> </phpmd> - + <phpdepend> <logger type="jdepend-chart" outfile="reports/depend-chart.html"/> @@ -52,7 +107,7 @@ <fileset refid="library"/> </phpdepend> </target> - + <!-- Run PHP CodeSniffer --> <target name="build-phpcs"> <phpcodesniffer standard="gems.xml"> @@ -62,7 +117,7 @@ <formatter type="summary" outfile="reports/phpcs-summary.txt"/> </phpcodesniffer> - + <copy file="reports/checkstyle.xml" tofile="reports/checkstyle.html"> <filterchain> @@ -70,7 +125,7 @@ </filterchain> </copy> </target> - + <!-- Main target --> - <target name="build" depends="lint,prepare,build-phpcs,build-docs,build-metrics"/> + <target name="build" depends="lint,prepare,sql-merge,sql-lite,build-phpcs,build-docs,build-metrics"/> </project> \ No newline at end of file Modified: trunk/test/data/gems__respondents.sql =================================================================== --- trunk/test/data/gems__respondents.sql 2012-09-12 18:45:41 UTC (rev 940) +++ trunk/test/data/gems__respondents.sql 2012-09-13 13:08:17 UTC (rev 941) @@ -1,18 +1,17 @@ CREATE TABLE gems__respondents ( grs_id_user bigint unsigned not null, - grs_ssn varchar(32) + grs_ssn varchar(32) null unique, - grs_iso_lang char(2) - not null default 'en' references gems__languages (gml_iso_lang), + grs_iso_lang char(2) not null default 'en', grs_email varchar(100) null, grs_first_name varchar(30) , grs_surname_prefix varchar(10) , grs_last_name varchar(50) , - grs_gender char(1) + grs_gender char(1) not null default 'U', grs_birthday date, Added: trunk/test/data/sqllite/create-lite.sql =================================================================== --- trunk/test/data/sqllite/create-lite.sql (rev 0) +++ trunk/test/data/sqllite/create-lite.sql 2012-09-13 13:08:17 UTC (rev 941) @@ -0,0 +1,971 @@ + +CREATE TABLE gems__consents ( + gco_description varchar(20) not null, + gco_order smallint not null default 10, + gco_code varchar(20) not null default 'do not use', + + gco_changed TEXT not null default current_timestamp, + gco_changed_by bigint not null, + gco_created TEXT not null, + gco_created_by bigint not null, + + PRIMARY KEY (gco_description) + ) + ; + + +INSERT INTO gems__consents + (gco_description, gco_order, gco_code, gco_changed, gco_changed_by, gco_created, gco_created_by) + VALUES + ('Yes', 10, 'consent given', CURRENT_TIMESTAMP, 1, CURRENT_TIMESTAMP, 1), + ('No', 20, 'do not use', CURRENT_TIMESTAMP, 1, CURRENT_TIMESTAMP, 1), + ('Unknown', 30, 'do not use', CURRENT_TIMESTAMP, 1, CURRENT_TIMESTAMP, 1); + +CREATE TABLE gems__groups ( + ggp_id_group bigint not null AUTOINCREMENT, + ggp_name varchar(30) not null, + ggp_description varchar(50) not null, + + ggp_role varchar(150) not null default 'respondent', + -- The ggp_role value(s) determines someones roles as not null default 1, + ggp_staff_members TINYINT(1) not null default 0, + ggp_respondent_members TINYINT(1) not null default 1, + ggp_allowed_ip_ranges text, + + ggp_changed TEXT not null default current_timestamp, + ggp_changed_by bigint not null, + ggp_created TEXT not null, + ggp_created_by bigint not null, + + PRIMARY KEY(ggp_id_group) + ) + ; + +-- Default group +INSERT ignore INTO gems__groups + (ggp_id_group, ggp_name, ggp_description, ggp_role, ggp_group_active, ggp_staff_members, ggp_respondent_members, ggp_changed_by, ggp_created, ggp_created_by) + VALUES + (800, 'Super Administrators', 'Super administrators with access to the whole site', 'super', 1, 1, 0, 0, current_timestamp, 0); + + -- ggp_group_rights = '*' gives access to all pages. + + +CREATE TABLE gems__log_respondent_communications ( + grco_id_action bigint not null AUTOINCREMENT, + + grco_id_to bigint not null, + grco_id_by bigint default 0, + grco_organization bigint not null, + + grco_id_token varchar(9), + + grco_method varchar(12) not null, + grco_topic varchar(120) not null, + grco_address varchar(120), + grco_sender varchar(120), + grco_comments varchar(120), + + grco_id_message bigint, + + grco_changed TEXT not null default current_timestamp, + grco_changed_by bigint not null, + grco_created TEXT not null, + grco_created_by bigint not null, + + PRIMARY KEY (grco_id_action) + ) + ; + + +CREATE TABLE gems__mail_jobs ( + gmj_id_job bigint not null AUTOINCREMENT, + + gmj_id_message bigint not null, + + gmj_id_user_as bigint not null, + + gmj_active TINYINT(1) not null default 1, + + -- O Use organization from address + -- S Use site from address + -- U Use gmj_id_user_as from address + -- F Fixed gmj_from_fixed + gmj_from_method varchar(1) not null, + gmj_from_fixed varchar(254), + + -- M => multiple per respondent, one for each token + -- O => One per respondent, mark all tokens as send + -- A => Send only one token, do not mark + gmj_process_method varchar(1) not null, + + -- N => notmailed + -- R => reminder + gmj_filter_mode varchar(1) not null, + gmj_filter_days_between int not null default 7, + + -- Optional filters + gmj_id_organization bigint, + gmj_id_track int, + gmj_id_survey int, + + gmj_changed TEXT not null default current_timestamp, + gmj_changed_by bigint not null, + gmj_created TEXT not null default '0000-00-00 00:00:00', + gmj_created_by bigint not null, + + PRIMARY KEY (gmj_id_job) + ) + ; + +CREATE TABLE gems__mail_servers ( + gms_from varchar(100) not null, + + gms_server varchar(100) not null, + gms_port smallint not null default 25, + gms_ssl tinyint not null default 0, + gms_user varchar(100), + gms_password varchar(100), + + gms_changed TEXT not null default current_timestamp, + gms_changed_by bigint not null, + gms_created TEXT not null default '0000-00-00 00:00:00', + gms_created_by bigint not null, + + PRIMARY KEY (gms_from) + ) + ; + + +CREATE TABLE gems__mail_templates ( + gmt_id_message bigint not null AUTOINCREMENT, + + gmt_subject varchar(100) not null, + gmt_body text not null, + + -- Yes, quick and dirty, will correct later (probably) + gmt_organizations varchar(250) , + + gmt_changed TEXT not null default current_timestamp, + gmt_changed_by bigint not null, + gmt_created TEXT not null default '0000-00-00 00:00:00', + gmt_created_by bigint not null, + + PRIMARY KEY (gmt_id_message), + UNIQUE (gmt_subject) + ) + ; + +INSERT INTO gems__mail_templates (gmt_subject, gmt_body, gmt_changed, gmt_changed_by, gmt_created, gmt_created_by) + VALUES + ('Questions for your treatement at {organization}', 'Dear {greeting}, + +Recently you visited [b]{organization}[/b] for treatment. For your proper treatment you are required to answer some questions. + +Click on [url={token_url}]this link[/url] to start or go to [url]{site_ask_url}[/url] and enter your token "{token}". + +{organization_signature}', CURRENT_TIMESTAMP, 1, CURRENT_TIMESTAMP, 1), + ('Reminder: your treatement at {organization}', 'Dear {greeting}, + +We remind you that for your proper treatment at [b]{organization}[/b] you are required to answer some questions. + +Click on [url={token_url}]this link[/url] to start or go to [url]{site_ask_url}[/url] and enter your token "{token}". + +{organization_signature}', CURRENT_TIMESTAMP, 1, CURRENT_TIMESTAMP, 1); + +CREATE TABLE gems__organizations ( + gor_id_organization bigint not null AUTOINCREMENT, + + gor_name varchar(50) not null, + gor_code varchar(20), + gor_user_class varchar(30) not null default 'StaffUser', + gor_location varchar(50), + gor_url varchar(127), + gor_url_base varchar(1270), + gor_task varchar(50), + + -- A commy separated list of organization numbers that can look at respondents in this organization + gor_accessible_by text, + + gor_contact_name varchar(50), + gor_contact_email varchar(127), + gor_welcome text, + gor_signature text, + + gor_style varchar(15) not null default 'gems', + gor_iso_lang char(2) not null default 'en', + + gor_has_login TINYINT(1) not null default 1, + gor_has_respondents TINYINT(1) not null default 0, + gor_add_respondents TINYINT(1) not null default 1, + gor_respondent_group bigint, + gor_allowed_ip_ranges text, + gor_active TINYINT(1) not null default 1, + + gor_changed TEXT not null default current_timestamp, + gor_changed_by bigint not null, + gor_created TEXT not null, + gor_created_by bigint not null, + + PRIMARY KEY(gor_id_organization), + UNIQUE (gor_code) + ) + ; + +INSERT ignore INTO "gems__organizations" ("gor_id_organization", "gor_name", gor_changed, gor_changed_by, gor_created, gor_created_by) + VALUES + (70, 'New organization', CURRENT_TIMESTAMP, 0, CURRENT_TIMESTAMP, 0); + +CREATE TABLE gems__patches ( + gpa_id_patch int not null AUTOINCREMENT, + + gpa_level int not null default 0, + gpa_location varchar(100) not null, + gpa_name varchar(30) not null, + gpa_order int not null default 0, + + gpa_sql text not null, + + gpa_executed TINYINT(1) not null default 0, + gpa_completed TINYINT(1) not null default 0, + + gpa_result varchar(255), + + gpa_changed TEXT not null default current_timestamp, + gpa_created TEXT, + + PRIMARY KEY (gpa_id_patch), + UNIQUE (gpa_level, gpa_location, gpa_name, gpa_order) + ) + ; + + +CREATE TABLE gems__patch_levels ( + gpl_level int not null unique, + + gpl_created TEXT not null default current_timestamp, + + PRIMARY KEY (gpl_level) + ) + ; + +INSERT INTO gems__patch_levels (gpl_level, gpl_created) + VALUES + (48, CURRENT_TIMESTAMP); + +CREATE TABLE "gems__radius_config" ( + "grcfg_id" bigint(11) NOT NULL AUTOINCREMENT, + "grcfg_id_organization" bigint(11) NOT NULL, + "grcfg_ip" varchar(39), + "grcfg_port" int(5), + "grcfg_secret" varchar(32), + PRIMARY KEY ("grcfg_id") +) DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci; +CREATE TABLE gems__reception_codes ( + grc_id_reception_code varchar(20) not null, + grc_description varchar(40) not null, + + grc_success TINYINT(1) not null default 0, + + grc_for_surveys tinyint not null default 0, + grc_redo_survey tinyint not null default 0, + grc_for_tracks TINYINT(1) not null default 0, + grc_for_respondents TINYINT(1) not null default 0, + grc_overwrite_answers TINYINT(1) not null default 0, + grc_active TINYINT(1) not null default 1, + + grc_changed TEXT not null default current_timestamp, + grc_changed_by bigint not null, + grc_created TEXT not null, + grc_created_by bigint not null, + + PRIMARY KEY (grc_id_reception_code) + ) + ; + +INSERT INTO gems__reception_codes (grc_id_reception_code, grc_description, grc_success, + grc_for_surveys, grc_redo_survey, grc_for_tracks, grc_for_respondents, grc_overwrite_answers, grc_active, + grc_changed, grc_changed_by, grc_created, grc_created_by) + VALUES + ('OK', '', 1, 1, 0, 1, 1, 0, 1, CURRENT_TIMESTAMP, 1, CURRENT_TIMESTAMP, 1), + ('skip', 'Skipped by calculation', 0, 1, 0, 0, 0, 1, 0, CURRENT_TIMESTAMP, 1, CURRENT_TIMESTAMP, 1), + ('stop', 'Stop surveys', 0, 2, 0, 0, 0, 0, 1, CURRENT_TIMESTAMP, 1, CURRENT_TIMESTAMP, 1); + +CREATE TABLE gems__respondent2org ( + gr2o_patient_nr varchar(7) not null, + gr2o_id_organization bigint not null, + + gr2o_id_user bigint not null, + + -- gr2o_id_physician bigint + --, + + -- gr2o_treatment varchar(200), + -- gr2o_comments text, + + gr2o_consent varchar(20) not null default 'Unknown', + gr2o_reception_code varchar(20) default 'OK' not null, + + gr2o_opened TEXT not null default current_timestamp, + gr2o_opened_by bigint not null, + gr2o_changed TEXT not null, + gr2o_changed_by bigint not null, + gr2o_created TEXT not null, + gr2o_created_by bigint not null, + + PRIMARY KEY (gr2o_patient_nr, gr2o_id_organization), + UNIQUE (gr2o_id_user, gr2o_id_organization) + ) + ; + + +CREATE TABLE gems__respondent2track ( + gr2t_id_respondent_track bigint not null AUTOINCREMENT, + + gr2t_id_user bigint not null, + gr2t_id_track int not null, + + gr2t_track_info varchar(250) , + gr2t_start_date TEXT, + gr2t_end_date TEXT, + + gr2t_id_organization bigint not null, + + gr2t_active TINYINT(1) not null default 1, + gr2t_count int not null default 0, + gr2t_completed int not null default 0, + + gr2t_reception_code varchar(20) default 'OK' not null, + + gr2t_changed TEXT not null default current_timestamp, + gr2t_changed_by bigint not null, + gr2t_created TEXT not null, + gr2t_created_by bigint not null, + + PRIMARY KEY (gr2t_id_respondent_track) + ) + ; + + +CREATE TABLE gems__respondent2track2field ( + gr2t2f_id_respondent_track bigint not null, + gr2t2f_id_field bigint not null, + + gr2t2f_value text, + + gr2t2f_changed TEXT not null default current_timestamp, + gr2t2f_changed_by bigint not null, + gr2t2f_created TEXT not null, + gr2t2f_created_by bigint not null, + + PRIMARY KEY(gr2t2f_id_respondent_track,gr2t2f_id_field) + ) + ; + + +CREATE TABLE gems__respondents ( + grs_id_user bigint not null AUTOINCREMENT, + + -- grs_login varchar(20) -- unique, + -- grs_password varchar(64) not null, + + grs_ssn varchar(32) unique, + +-- Naam +-- Adres +-- Woonplaats +-- Tel. nr +-- geb. datum +-- aandoening (code bijv: ICD9, DBC etc) +-- aangedaan lichaamsdeel +-- uitgevoerde behandeling +-- hand dominantie +-- behandelend arts +-- beroep/ hobby's +-- OK/ behandel datum +-- email + -- grs_staff TINYINT(1) not null default 0, + -- grs_respondent TINYINT(1) not null default 1, + -- grs_active TINYINT(1) not null default 1, + -- grs_id_supervisor bigint default 1 + --, + -- grs_id_primary_group bigint --, + grs_iso_lang char(2) not null default 'en', + + grs_email varchar(100), + + grs_first_name varchar(30) , + grs_surname_prefix varchar(10) , + grs_last_name varchar(50) , + grs_gender char(1) not null default 'U', + -- grs_dexterity char(1) -- not null default 'U', + grs_birthday TEXT, + -- grs_function varchar(40) , + + grs_address_1 varchar(80) , + grs_address_2 varchar(80) , + grs_zipcode varchar(10) , + grs_city varchar(40) , + -- grs_region varchar(40) , + grs_iso_country char(2) not null default 'NL', + grs_phone_1 varchar(25) , + -- grs_phone_2 varchar(25) , + -- grs_phone_3 varchar(25) , + + -- grs_id_reception_code bigint not null default 1 + --, + + grs_changed TEXT not null default current_timestamp, + grs_changed_by bigint not null, + grs_created TEXT not null, + grs_created_by bigint not null, + + PRIMARY KEY(grs_id_user) + ) + ; + + +CREATE TABLE gems__roles ( + grl_id_role bigint not null AUTOINCREMENT, + grl_name varchar(30) not null, + grl_description varchar(50) not null, + + grl_parents text, + -- The grl_parents is a comma-separated list of parents for this role + + grl_privileges text, + -- The grl_privilege is a comma-separated list of privileges for this role + + grl_changed TEXT not null default current_timestamp, + grl_changed_by bigint not null, + grl_created TEXT not null, + grl_created_by bigint not null, + + PRIMARY KEY(grl_id_role) + ) + ; + +-- default roles/privileges + +INSERT INTO gems__roles (grl_name, grl_description, grl_privileges, grl_parents, grl_changed, grl_changed_by, grl_created, grl_created_by) + VALUES + ('nologin','nologin','pr.contact.bugs,pr.contact.support,pr.nologin','', CURRENT_TIMESTAMP, 1, CURRENT_TIMESTAMP, 1), + ('guest','guest','pr.ask,pr.contact.bugs,pr.contact.support,pr.islogin,pr.respondent','', CURRENT_TIMESTAMP, 1, CURRENT_TIMESTAMP, 1), + ('respondent','respondent','','guest', CURRENT_TIMESTAMP, 1, CURRENT_TIMESTAMP, 1), + ('security','security','','guest', CURRENT_TIMESTAMP, 1, CURRENT_TIMESTAMP, 1), + ('staff','staff','pr.option.edit,pr.option.password,pr.plan,pr.plan.overview,pr.plan.token,pr.project,pr.project.questions,pr.respondent.create,pr.respondent.edit,pr.respondent.who,pr.setup,pr.staff,pr.survey,pr.survey.create,pr.token,pr.token.answers,pr.token.delete,pr.token.edit,pr.token.mail,pr.token.print,pr.track,pr.track.create,pr.track.delete,pr.track.edit,pr.respondent.reportdeath','guest', CURRENT_TIMESTAMP, 1, CURRENT_TIMESTAMP, 1), + ('physician','physician','','staff', CURRENT_TIMESTAMP, 1, CURRENT_TIMESTAMP, 1), + ('researcher','researcher','pr.project-information.changelog,pr.contact,pr.export,pr.plan.token,pr.plan.respondent,pr.plan.overview,pr.option.password,pr.option.edit,pr.organization-switch,pr.islogin','guest', CURRENT_TIMESTAMP, 1, CURRENT_TIMESTAMP, 1), + ('admin','admin','pr.consent,pr.consent.create,pr.consent.edit,pr.group,pr.role,pr.mail,pr.mail.create,pr.mail.delete,pr.mail.edit,pr.mail.log,pr.organization,pr.organization-switch,pr.plan.overview.excel,pr.plan.respondent,pr.plan.respondent.excel,pr.plan.token.excel,pr.project-information,pr.reception,pr.reception.create,pr.reception.edit,pr.respondent.choose-org,pr.respondent.delete,pr.respondent.result,pr.source,pr.staff.create,pr.staff.delete,pr.staff.edit,pr.staff.see.all,pr.survey-maintenance,pr.track-maintenance,pr.token.mail.freetext','staff,researcher,security', CURRENT_TIMESTAMP, 1, CURRENT_TIMESTAMP, 1), + ('super','super','pr.consent.delete,pr.country,pr.country.create,pr.country.delete,pr.country.edit,pr.database,pr.database.create,pr.database.delete,pr.database.edit,pr.database.execute,pr.database.patches,pr.group.create,pr.group.edit,pr.language,pr.mail.server,pr.mail.server.create,pr.mail.server.delete,pr.mail.server.edit,pr.organization.create,pr.organization.edit,pr.plan.choose-org,pr.plan.mail-as-application,pr.reception.delete,pr.role.create,pr.role.edit,pr.source.create,pr.source.edit,pr.source.synchronize,pr.source.synchronize-all,pr.staff.edit.all,pr.survey-maintenance.edit,pr.track-maintenance.create,pr.track-maintenance.edit,pr.maintenance','admin', CURRENT_TIMESTAMP, 1, CURRENT_TIMESTAMP, 1); + +CREATE TABLE gems__rounds ( + gro_id_round bigint not null AUTOINCREMENT, + + gro_id_track bigint not null, + gro_id_order int not null default 10, + + gro_id_survey bigint not null, + + -- Survey_name is a temp copy from __surveys, needed by me to keep an overview as + -- long as no track editor exists. + gro_survey_name varchar(100) not null, + + gro_round_description varchar(100), + gro_icon_file VARCHAR(100), + gro_changed_event varchar(128), + gro_display_event varchar(128), + + -- depreciated + gro_valid_after char(6) , + gro_valid_for char(6) , + gro_used_date char(1) not null default 'A', + gro_used_date_order int(4) default 10, + gro_used_date_field varchar(16), + -- end of depreciated + + gro_active TINYINT(1) not null default 1, + + gro_changed TEXT not null default current_timestamp, + gro_changed_by bigint not null, + gro_created TEXT not null, + gro_created_by bigint not null, + + PRIMARY KEY (gro_id_round) + ) + ; + + +CREATE TABLE gems__round_periods ( + grp_id_round bigint not null, + + grp_valid_after_id bigint, + grp_valid_after_source varchar(12) not null default 'tok', + grp_valid_after_field varchar(64) not null default 'gto_valid_from', + grp_valid_after_unit char(1) not null default 'M', + grp_valid_after_length int not null default 0, + + grp_valid_for_id bigint, + grp_valid_for_source varchar(12) not null default 'nul', + grp_valid_for_field varchar(64), + grp_valid_for_unit char(1) not null default 'M', + grp_valid_for_length int not null default 0, + + grp_changed TEXT not null default current_timestamp, + grp_changed_by bigint not null, + grp_created TEXT not null, + grp_created_by bigint not null, + + PRIMARY KEY (grp_id_round) + ) + ; + +INSERT INTO gems__round_periods + (grp_id_round, + + grp_valid_after_id, grp_valid_after_source, grp_valid_after_field, grp_valid_after_unit, grp_valid_after_length, + + grp_valid_for_id, grp_valid_for_source, grp_valid_for_field, grp_valid_for_unit, grp_valid_for_length, + + grp_changed, grp_changed_by, grp_created, grp_created_by) + SELECT r1.gro_id_round AS grp_id_round, + + r2.gro_id_round AS grp_valid_after_id, + CASE + WHEN r2.gro_id_round IS THEN 'rtr' + WHEN r1.gro_used_date = 'A' THEN 'tok' + WHEN r1.gro_used_date = 'C' THEN 'tok' + WHEN r1.gro_used_date = 'F' AND (gsu_followup_field IS OR gsu_followup_field = 'submitdate') THEN 'tok' + ELSE 'ans' + END as grp_valid_after_source, + CASE + WHEN r2.gro_id_round IS THEN 'gr2t_start_date' + WHEN r1.gro_used_date = 'A' THEN 'gto_valid_from' + WHEN r1.gro_used_date = 'C' THEN 'gto_completion_time' + WHEN r1.gro_used_date = 'F' AND (gsu_followup_field IS OR gsu_followup_field = 'submitdate') THEN 'gto_completion_time' + ELSE gsu_followup_field + END as grp_valid_after_field, + coalesce(substring(r1.gro_valid_after, 1, 1), 'M') AS grp_valid_after_unit, + coalesce(convert(substring(r1.gro_valid_after, 2), signed), 0) AS grp_valid_after_length, + + r1.gro_id_round AS grp_valid_for_id, + CASE + WHEN coalesce(convert(substring(r1.gro_valid_for, 2), signed), 0) = 0 THEN 'nul' + ELSE 'tok' + END AS grp_valid_for_source, + CASE + WHEN coalesce(convert(substring(r1.gro_valid_for, 2), signed), 0) = 0 THEN + ELSE 'gto_valid_from' + END AS grp_valid_for_field, + coalesce(substring(r1.gro_valid_for, 1, 1), 'M') AS grp_valid_for_unit, + coalesce(convert(substring(r1.gro_valid_for, 2), signed), 0) AS grp_valid_for_length, + + r1.gro_changed, r1.gro_changed_by, r1.gro_created, r1.gro_created_by + FROM gems__rounds AS r1 + INNER JOIN gems__tracks ON r1.gro_id_track = gtr_id_track + LEFT JOIN (gems__rounds AS r2 + INNER JOIN gems__surveys ON r2.gro_id_survey = gsu_id_survey) + ON r1.gro_id_track = r2.gro_id_track AND r1.gro_id_order > r2.gro_id_order + AND r2.gro_id_order = + (SELECT MAX(r3.gro_id_order) FROM gems__rounds AS r3 WHERE r1.gro_id_track = r3.gro_id_track AND r1.gro_id_order > r3.gro_id_order) + WHERE gtr_track_type = 'T' AND gtr_track_model = 'TrackModel' + ORDER BY r1.gro_id_round; + +INSERT INTO gems__round_periods + (grp_id_round, + + grp_valid_after_id, grp_valid_after_source, grp_valid_after_field, grp_valid_after_unit, grp_valid_after_length, + + grp_valid_for_id, grp_valid_for_source, grp_valid_for_field, grp_valid_for_unit, grp_valid_for_length, + grp_changed, grp_changed_by, grp_created, grp_created_by) + SELECT r1.gro_id_round AS grp_id_round, + + r2.gro_id_round AS grp_valid_after_id, + CASE + WHEN r2.gro_id_round IS THEN 'rtr' + WHEN r1.gro_used_date = 'A' THEN 'tok' + WHEN r1.gro_used_date = 'C' THEN 'tok' + WHEN r1.gro_used_date = 'F' AND (gsu_followup_field IS OR gsu_followup_field = 'submitdate') THEN 'tok' + ELSE 'ans' + END as grp_valid_after_source, + CASE + WHEN r2.gro_id_round IS THEN 'gr2t_start_date' + WHEN r1.gro_used_date = 'A' THEN 'gto_valid_from' + WHEN r1.gro_used_date = 'C' THEN 'gto_completion_time' + WHEN r1.gro_used_date = 'F' AND (gsu_followup_field IS OR gsu_followup_field = 'submitdate') THEN 'gto_completion_time' + ELSE gsu_followup_field + END as grp_valid_after_field, + coalesce(substring(r1.gro_valid_after, 1, 1), 'M') AS grp_valid_after_unit, + coalesce(convert(substring(r1.gro_valid_after, 2), signed), 0) AS grp_valid_after_length, + + r1.gro_id_round AS grp_valid_for_id, + CASE + WHEN coalesce(convert(substring(r1.gro_valid_for, 2), signed), 0) = 0 THEN 'nul' + ELSE 'tok' + END AS grp_valid_for_source, + CASE + WHEN coalesce(convert(substring(r1.gro_valid_for, 2), signed), 0) = 0 THEN + ELSE 'gto_valid_from' + END AS grp_valid_for_field, + coalesce(substring(r1.gro_valid_for, 1, 1), 'M') AS grp_valid_for_unit, + coalesce(convert(substring(r1.gro_valid_for, 2), signed), 0) AS grp_valid_for_length, + + r1.gro_changed, r1.gro_changed_by, r1.gro_created, r1.gro_created_by + FROM gems__rounds AS r1 + INNER JOIN gems__tracks ON r1.gro_id_track = gtr_id_track + LEFT JOIN (gems__rounds AS r2 + INNER JOIN gems__surveys ON r2.gro_id_survey = gsu_id_survey) + ON r1.gro_id_track = r2.gro_id_track AND r1.gro_used_date_order = r2.gro_id_order + WHERE gtr_track_type = 'T' AND gtr_track_model = 'NewTrackModel' + ORDER BY r1.gro_id_round; + +CREATE TABLE "gems__sources" ( + "gso_id_source" int(10) NOT NULL AUTOINCREMENT, + "gso_source_name" varchar(40) NOT NULL, + + "gso_ls_url" varchar(255) NOT NULL, + "gso_ls_class" varchar(60) NOT NULL default 'Gems_Source_LimeSurvey1m9Database', + "gso_ls_adapter" varchar(20), + "gso_ls_dbhost" varchar(127), + "gso_ls_database" varchar(127), + "gso_ls_table_prefix" varchar(127), + "gso_ls_username" varchar(64), + "gso_ls_password" varchar(255), + "gso_ls_charset" varchar(8), + + "gso_active" tinyint(1) NOT NULL default '1', + + "gso_status" varchar(20), + "gso_last_synch" TEXT, + + "gso_changed" TEXT NOT NULL default CURRENT_TIMESTAMP, + "gso_changed_by" bigint(20) NOT NULL, + "gso_created" TEXT NOT NULL default '0000-00-00 00:00:00', + "gso_created_by" bigint(20) NOT NULL, + + PRIMARY KEY ("gso_id_source"), + UNIQUE ("gso_source_name"), + UNIQUE ("gso_ls_url") +) +DEFAULT CHARSET=utf8; +-- Table containing the project staff +-- +CREATE TABLE gems__staff ( + gsf_id_user bigint not null, + + gsf_login varchar(20) not null, + gsf_id_organization bigint not null, + + gsf_active TINYINT(1) default 1, + + -- depreciated + gsf_password varchar(32), + gsf_failed_logins int(11) default 0, + gsf_last_failed TEXT, + -- end depreciated + + + gsf_id_primary_group bigint, + gsf_iso_lang char(2) not null default 'en', + gsf_logout_on_survey TINYINT(1) not null default 0, + + gsf_email varchar(100) unique, + + gsf_first_name varchar(30) , + gsf_surname_prefix varchar(10) , + gsf_last_name varchar(30) , + gsf_gender char(1) not null default 'U', + -- gsf_birthday TEXT, + -- gsf_function varchar(40) , + + -- gsf_address_1 varchar(80) , + -- gsf_address_2 varchar(80) , + -- gsf_zipcode varchar(10) , + -- gsf_city varchar(40) , + -- gsf_region varchar(40) , + -- gsf_iso_country char(2) --, + gsf_phone_1 varchar(25) , + -- gsf_phone_2 varchar(25) , + -- gsf_phone_3 varchar(25) , + + -- depreciated + gsf_reset_key varchar(64), + gsf_reset_req TEXT, + -- end depreciated + + gsf_changed TEXT not null default current_timestamp, + gsf_changed_by bigint not null, + gsf_created TEXT not null, + gsf_created_by bigint not null, + + PRIMARY KEY(gsf_id_user), + UNIQUE(gsf_login, gsf_id_organization), + UNIQUE(gsf_reset_key) + ) + ; + + +CREATE TABLE gems__staff2groups ( + gs2g_id_user bigint not null, + gs2g_id_group bigint not null, + + gs2g_active TINYINT(1) not null default 1, + + gs2g_changed TEXT not null default current_timestamp, + gs2g_changed_by bigint not null, + gs2g_created TEXT not null, + gs2g_created_by bigint not null, + + PRIMARY KEY (gs2g_id_user, gs2g_id_group) + ) + ; + + + +CREATE TABLE gems__surveys ( + gsu_id_survey int not null AUTOINCREMENT, + gsu_survey_name varchar(100) not null, + gsu_survey_description varchar(100) , + + gsu_surveyor_id int(11), + gsu_surveyor_active TINYINT(1) not null default 1, + + -- depreciated + gsu_survey_table varchar(64) , + gsu_token_table varchar(64) , + -- end depreciated + + gsu_survey_pdf varchar(128) , + gsu_beforeanswering_event varchar(128) , + gsu_completed_event varchar(128) , + gsu_display_event varchar(128) , + + gsu_id_source int not null, + gsu_active TINYINT(1) not null default 0, + gsu_status varchar(127) , + + -- depreciated + gsu_staff TINYINT(1) not null default 0, + -- end depreciated + + gsu_id_primary_group bigint, + + -- depreciated + gsu_id_user_field varchar(20) , + gsu_completion_field varchar(20) not null default 'submitdate', + gsu_followup_field varchar(20) not null default 'submitdate', + -- end depreciated + + gsu_result_field varchar(20) , + gsu_duration varchar(50) , + + gsu_code varchar(64), + + gsu_changed TEXT not null default current_timestamp, + gsu_changed_by bigint not null, + gsu_created TEXT not null, + gsu_created_by bigint not null, + + PRIMARY KEY(gsu_id_survey) + ) + ; + + +CREATE TABLE gems__tokens ( + gto_id_token varchar(9) not null, + + gto_id_respondent_track bigint not null, + gto_id_round bigint not null, + + -- non-changing fields calculated from previous two: + gto_id_respondent bigint not null, + gto_id_organization bigint not null, + gto_id_track bigint not null, + + -- values initially filled from gems__rounds, but that may get different values later on + gto_id_survey bigint not null, + + -- values initially filled from gems__rounds, but that might get different values later on, but but not now + gto_round_order int not null default 10, + gto_round_description varchar(100), + + -- real data + gto_valid_from TEXT, + gto_valid_until TEXT, + gto_mail_sent_date TEXT, + gto_mail_sent_num int(11) not null default 0, + gto_next_mail_date TEXT, + + gto_start_time TEXT, + gto_in_source TINYINT(1) not null default 0, + gto_by bigint(20), + + gto_completion_time TEXT, + gto_duration_in_sec bigint(20), + gto_followup_date TEXT, -- depreciated + gto_result varchar(20) , + + gto_comment varchar(250), + gto_reception_code varchar(20) default 'OK' not null, + + gto_return_url varchar(250), + + gto_changed TEXT not null default current_timestamp, + gto_changed_by bigint not null, + gto_created TEXT not null, + gto_created_by bigint not null, + + PRIMARY KEY (gto_id_token) + ) + ; + + +CREATE TABLE gems__token_attempts ( + gta_id_attempt bigint not null AUTOINCREMENT, + gta_id_token varchar(9) not null, + gta_ip... [truncated message content] |
From: <gem...@li...> - 2012-09-13 14:09:35
|
Revision: 942 http://gemstracker.svn.sourceforge.net/gemstracker/?rev=942&view=rev Author: matijsdejong Date: 2012-09-13 14:09:24 +0000 (Thu, 13 Sep 2012) Log Message: ----------- Some more small fixes for database Made workbench file for DB Modified Paths: -------------- trunk/library/configs/db/tables/gems__radius_config.999.sql trunk/library/configs/db/tables/gems__staff.20.sql trunk/library/docs/Gems_MySQL_WorkBench.mwb trunk/scripts/build.xml trunk/test/data/sqllite/create-lite.sql Modified: trunk/library/configs/db/tables/gems__radius_config.999.sql =================================================================== --- trunk/library/configs/db/tables/gems__radius_config.999.sql 2012-09-13 13:08:17 UTC (rev 941) +++ trunk/library/configs/db/tables/gems__radius_config.999.sql 2012-09-13 14:09:24 UTC (rev 942) @@ -1,9 +1,13 @@ -CREATE TABLE IF NOT EXISTS `gems__radius_config` ( - `grcfg_id` bigint(11) NOT NULL auto_increment, - `grcfg_id_organization` bigint(11) NOT NULL, - `grcfg_ip` varchar(39) collate utf8_unicode_ci default NULL, - `grcfg_port` int(5) default NULL, - `grcfg_secret` varchar(32) collate utf8_unicode_ci default NULL, - PRIMARY KEY (`grcfg_id`) -) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci; \ No newline at end of file +CREATE TABLE if not exists gems__radius_config ( + grcfg_id bigint(11) NOT NULL auto_increment, + grcfg_id_organization bigint(11) NOT NULL references gems__organizations (gor_id_organization), + grcfg_ip varchar(39) collate utf8_unicode_ci default NULL, + grcfg_port int(5) default NULL, + grcfg_secret varchar(32) collate utf8_unicode_ci default NULL, + + PRIMARY KEY (grcfg_id) + ) +ENGINE=MyISAM +DEFAULT CHARSET=utf8 +COLLATE=utf8_unicode_ci; \ No newline at end of file Modified: trunk/library/configs/db/tables/gems__staff.20.sql =================================================================== --- trunk/library/configs/db/tables/gems__staff.20.sql 2012-09-13 13:08:17 UTC (rev 941) +++ trunk/library/configs/db/tables/gems__staff.20.sql 2012-09-13 14:09:24 UTC (rev 942) @@ -54,7 +54,7 @@ PRIMARY KEY (gsf_id_user), UNIQUE KEY (gsf_login, gsf_id_organization), - UNIQUE KEY (gsf_reset_key) + UNIQUE KEY (gsf_reset_key), KEY (gsf_email) ) ENGINE=InnoDB Modified: trunk/library/docs/Gems_MySQL_WorkBench.mwb =================================================================== (Binary files differ) Modified: trunk/scripts/build.xml =================================================================== --- trunk/scripts/build.xml 2012-09-13 13:08:17 UTC (rev 941) +++ trunk/scripts/build.xml 2012-09-13 14:09:24 UTC (rev 942) @@ -58,8 +58,11 @@ <regexp pattern=",\s*INDEX\s*\([^)]+\)" replace="" ignoreCase="true"/> <regexp pattern="(\s)BOOLEAN(\s)" replace="\1TINYINT(1)\2" ignoreCase="true"/> <regexp pattern="ENGINE=[^\s,;]+\s*" replace="" ignoreCase="true"/> - <regexp pattern="CHARACTER\s+SET\s+[^\s,;]+\s*" replace="" ignoreCase="true"/> - <regexp pattern="COLLATE\s+[^\s,;]+\s*" replace="" ignoreCase="true"/> + <regexp pattern="DEFAULT\s+CHARACTER\s+SET\s*" replace="CHARACTER SET " ignoreCase="true"/> + <regexp pattern="DEFAULT\s+CHARSET\s*" replace="CHARACTER SET " ignoreCase="true"/> + <regexp pattern="CHARACTER\s+SET\s*[^\s,;]+\s*" replace="" ignoreCase="true"/> + <regexp pattern="CHARSET\s*[^\s,;]+\s*" replace="" ignoreCase="true"/> + <regexp pattern="COLLATE\s*[^\s,;]+\s*" replace="" ignoreCase="true"/> <regexp pattern="ENUM\s[^)]+\)\s*" replace="" ignoreCase="true"/> <regexp pattern="SET\s[^)]+\)\s*" replace="" ignoreCase="true"/> <regexp pattern="UNSIGNED\s*" replace="" ignoreCase="true"/> Modified: trunk/test/data/sqllite/create-lite.sql =================================================================== --- trunk/test/data/sqllite/create-lite.sql 2012-09-13 13:08:17 UTC (rev 941) +++ trunk/test/data/sqllite/create-lite.sql 2012-09-13 14:09:24 UTC (rev 942) @@ -207,11 +207,11 @@ gor_created_by bigint not null, PRIMARY KEY(gor_id_organization), - UNIQUE (gor_code) + KEY (gor_code) ) ; -INSERT ignore INTO "gems__organizations" ("gor_id_organization", "gor_name", gor_changed, gor_changed_by, gor_created, gor_created_by) +INSERT ignore INTO gems__organizations (gor_id_organization, gor_name, gor_changed, gor_changed_by, gor_created, gor_created_by) VALUES (70, 'New organization', CURRENT_TIMESTAMP, 0, CURRENT_TIMESTAMP, 0); @@ -252,14 +252,16 @@ VALUES (48, CURRENT_TIMESTAMP); -CREATE TABLE "gems__radius_config" ( - "grcfg_id" bigint(11) NOT NULL AUTOINCREMENT, - "grcfg_id_organization" bigint(11) NOT NULL, - "grcfg_ip" varchar(39), - "grcfg_port" int(5), - "grcfg_secret" varchar(32), - PRIMARY KEY ("grcfg_id") -) DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci; +CREATE TABLE gems__radius_config ( + grcfg_id bigint(11) NOT NULL AUTOINCREMENT, + grcfg_id_organization bigint(11) NOT NULL, + grcfg_ip varchar(39), + grcfg_port int(5), + grcfg_secret varchar(32), + + PRIMARY KEY (grcfg_id) + ) +; CREATE TABLE gems__reception_codes ( grc_id_reception_code varchar(20) not null, grc_description varchar(40) not null, @@ -320,7 +322,7 @@ CREATE TABLE gems__respondent2track ( gr2t_id_respondent_track bigint not null AUTOINCREMENT, - + gr2t_id_user bigint not null, gr2t_id_track int not null, @@ -333,8 +335,9 @@ gr2t_active TINYINT(1) not null default 1, gr2t_count int not null default 0, gr2t_completed int not null default 0, - + gr2t_reception_code varchar(20) default 'OK' not null, + gr2t_comment varchar(250), gr2t_changed TEXT not null default current_timestamp, gr2t_changed_by bigint not null, @@ -456,7 +459,7 @@ ('physician','physician','','staff', CURRENT_TIMESTAMP, 1, CURRENT_TIMESTAMP, 1), ('researcher','researcher','pr.project-information.changelog,pr.contact,pr.export,pr.plan.token,pr.plan.respondent,pr.plan.overview,pr.option.password,pr.option.edit,pr.organization-switch,pr.islogin','guest', CURRENT_TIMESTAMP, 1, CURRENT_TIMESTAMP, 1), ('admin','admin','pr.consent,pr.consent.create,pr.consent.edit,pr.group,pr.role,pr.mail,pr.mail.create,pr.mail.delete,pr.mail.edit,pr.mail.log,pr.organization,pr.organization-switch,pr.plan.overview.excel,pr.plan.respondent,pr.plan.respondent.excel,pr.plan.token.excel,pr.project-information,pr.reception,pr.reception.create,pr.reception.edit,pr.respondent.choose-org,pr.respondent.delete,pr.respondent.result,pr.source,pr.staff.create,pr.staff.delete,pr.staff.edit,pr.staff.see.all,pr.survey-maintenance,pr.track-maintenance,pr.token.mail.freetext','staff,researcher,security', CURRENT_TIMESTAMP, 1, CURRENT_TIMESTAMP, 1), - ('super','super','pr.consent.delete,pr.country,pr.country.create,pr.country.delete,pr.country.edit,pr.database,pr.database.create,pr.database.delete,pr.database.edit,pr.database.execute,pr.database.patches,pr.group.create,pr.group.edit,pr.language,pr.mail.server,pr.mail.server.create,pr.mail.server.delete,pr.mail.server.edit,pr.organization.create,pr.organization.edit,pr.plan.choose-org,pr.plan.mail-as-application,pr.reception.delete,pr.role.create,pr.role.edit,pr.source.create,pr.source.edit,pr.source.synchronize,pr.source.synchronize-all,pr.staff.edit.all,pr.survey-maintenance.edit,pr.track-maintenance.create,pr.track-maintenance.edit,pr.maintenance','admin', CURRENT_TIMESTAMP, 1, CURRENT_TIMESTAMP, 1); + ('super','super','pr.consent.delete,pr.country,pr.country.create,pr.country.delete,pr.country.edit,pr.database,pr.database.create,pr.database.delete,pr.database.edit,pr.database.execute,pr.database.patches,pr.group.create,pr.group.edit,pr.language,pr.mail.server,pr.mail.server.create,pr.mail.server.delete,pr.mail.server.edit,pr.organization.create,pr.organization.edit,pr.plan.choose-org,pr.plan.mail-as-application,pr.reception.delete,pr.respondent.multiorg,pr.role.create,pr.role.edit,pr.source.create,pr.source.edit,pr.source.synchronize,pr.source.synchronize-all,pr.staff.edit.all,pr.survey-maintenance.edit,pr.track-maintenance.create,pr.track-maintenance.edit,pr.maintenance','admin', CURRENT_TIMESTAMP, 1, CURRENT_TIMESTAMP, 1); CREATE TABLE gems__rounds ( gro_id_round bigint not null AUTOINCREMENT, @@ -630,7 +633,7 @@ "gso_ls_table_prefix" varchar(127), "gso_ls_username" varchar(64), "gso_ls_password" varchar(255), - "gso_ls_charset" varchar(8), + "gso_ls_varchar(8), "gso_active" tinyint(1) NOT NULL default '1', @@ -646,7 +649,7 @@ UNIQUE ("gso_source_name"), UNIQUE ("gso_ls_url") ) -DEFAULT CHARSET=utf8; +; -- Table containing the project staff -- CREATE TABLE gems__staff ( @@ -668,7 +671,7 @@ gsf_iso_lang char(2) not null default 'en', gsf_logout_on_survey TINYINT(1) not null default 0, - gsf_email varchar(100) unique, + gsf_email varchar(100) , gsf_first_name varchar(30) , gsf_surname_prefix varchar(10) , @@ -697,9 +700,10 @@ gsf_created TEXT not null, gsf_created_by bigint not null, - PRIMARY KEY(gsf_id_user), - UNIQUE(gsf_login, gsf_id_organization), - UNIQUE(gsf_reset_key) + PRIMARY KEY (gsf_id_user), + UNIQUE (gsf_login, gsf_id_organization), + UNIQUE (gsf_reset_key), + KEY (gsf_email) ) ; @@ -966,6 +970,7 @@ gup_created TEXT not null, gup_created_by bigint not null, - PRIMARY KEY (gup_id_user) + PRIMARY KEY (gup_id_user), + UNIQUE (gup_reset_key) ) ; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <gem...@li...> - 2012-09-21 07:54:42
|
Revision: 950 http://gemstracker.svn.sourceforge.net/gemstracker/?rev=950&view=rev Author: mennodekker Date: 2012-09-21 07:54:32 +0000 (Fri, 21 Sep 2012) Log Message: ----------- Fixes for sql-lite script generator: charset is also a fieldname, key and autoincrement are not allowed Fix for ; in gems__user_login_attempts table description Modified Paths: -------------- trunk/library/configs/db/tables/gems__user_login_attempts.10.sql trunk/scripts/build.xml Modified: trunk/library/configs/db/tables/gems__user_login_attempts.10.sql =================================================================== --- trunk/library/configs/db/tables/gems__user_login_attempts.10.sql 2012-09-20 13:42:35 UTC (rev 949) +++ trunk/library/configs/db/tables/gems__user_login_attempts.10.sql 2012-09-21 07:54:32 UTC (rev 950) @@ -1,5 +1,5 @@ --- Table for keeping track of fail;ed login attempts +-- Table for keeping track of failed login attempts -- CREATE TABLE if not exists gems__user_login_attempts ( gula_login varchar(30) CHARACTER SET 'utf8' COLLATE 'utf8_general_ci' not null, Modified: trunk/scripts/build.xml =================================================================== --- trunk/scripts/build.xml 2012-09-20 13:42:35 UTC (rev 949) +++ trunk/scripts/build.xml 2012-09-21 07:54:32 UTC (rev 950) @@ -53,15 +53,18 @@ <regexp pattern="CREATE\s+TABLE\s+if\s+not\s+exists\s+" replace="CREATE TABLE " ignoreCase="true"/> <regexp pattern="AUTO_INCREMENT\s*=\s*\d+\s*" replace="" ignoreCase="true"/> <regexp pattern="AUTO_INCREMENT" replace="AUTOINCREMENT" ignoreCase="true"/> + <regexp pattern="AUTOINCREMENT" replace="" ignoreCase="true"/> <regexp pattern="(\sUNIQUE)\s+KEY(\s+|,|\()" replace="\1\2" ignoreCase="true"/> <regexp pattern="(\sUNIQUE\s)\s*[^\s(]+\s+\(" replace="\1(" ignoreCase="true"/> <regexp pattern=",\s*INDEX\s*\([^)]+\)" replace="" ignoreCase="true"/> + <regexp pattern=",\s*[^PRIMARY]\sKEY\s*\([^)]+\)" replace="" multiline="true" ignoreCase="true"/> + <regexp pattern="/\*.*\*/" replace="" multiline="true" ignoreCase="true"/> <regexp pattern="(\s)BOOLEAN(\s)" replace="\1TINYINT(1)\2" ignoreCase="true"/> <regexp pattern="ENGINE=[^\s,;]+\s*" replace="" ignoreCase="true"/> <regexp pattern="DEFAULT\s+CHARACTER\s+SET\s*" replace="CHARACTER SET " ignoreCase="true"/> <regexp pattern="DEFAULT\s+CHARSET\s*" replace="CHARACTER SET " ignoreCase="true"/> <regexp pattern="CHARACTER\s+SET\s*[^\s,;]+\s*" replace="" ignoreCase="true"/> - <regexp pattern="CHARSET\s*[^\s,;]+\s*" replace="" ignoreCase="true"/> + <regexp pattern="CHARSET\s+[^\s,;]+\s*" replace="" ignoreCase="true"/> <regexp pattern="COLLATE\s*[^\s,;]+\s*" replace="" ignoreCase="true"/> <regexp pattern="ENUM\s[^)]+\)\s*" replace="" ignoreCase="true"/> <regexp pattern="SET\s[^)]+\)\s*" replace="" ignoreCase="true"/> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <gem...@li...> - 2012-10-25 12:21:46
|
Revision: 995 http://gemstracker.svn.sourceforge.net/gemstracker/?rev=995&view=rev Author: matijsdejong Date: 2012-10-25 12:21:35 +0000 (Thu, 25 Oct 2012) Log Message: ----------- Added unit tests for MUtil_String Modified Paths: -------------- trunk/library/classes/MUtil/String.php Added Paths: ----------- trunk/test/classes/MUtil/StringTest.php Modified: trunk/library/classes/MUtil/String.php =================================================================== --- trunk/library/classes/MUtil/String.php 2012-10-25 11:54:36 UTC (rev 994) +++ trunk/library/classes/MUtil/String.php 2012-10-25 12:21:35 UTC (rev 995) @@ -81,7 +81,7 @@ } /** - * Return the part after $input and $filter stopped being the same + * Return the part after $input and $filter have stopped being the same * * stripStringLeft('abcdef', 'abcx') => 'def' * Added: trunk/test/classes/MUtil/StringTest.php =================================================================== --- trunk/test/classes/MUtil/StringTest.php (rev 0) +++ trunk/test/classes/MUtil/StringTest.php 2012-10-25 12:21:35 UTC (rev 995) @@ -0,0 +1,131 @@ +<?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 MUtil + * @subpackage String + * @author Matijs de Jong <mj...@ma...> + * @copyright Copyright (c) 2011 Erasmus MC + * @license New BSD License + * @version $Id$ + */ + +require_once 'PHPUnit/Framework/TestCase.php'; + +/** + * Unit test for class MUtil_String + * + * @package MUtil + * @subpackage String + * @copyright Copyright (c) 2011 Erasmus MC + * @license New BSD License + * @since Class available since version 1.5.7 + */ +class MUtil_StringTest extends PHPUnit_Framework_TestCase +{ + /** + * Return empty string if charFilters hit on first character + */ + public function testBeforeCharsReturnNone() + { + $result = MUtil_String::beforeChars('abcdef', 'rara'); + $this->assertEquals($result, ''); + } + + /** + * Return part of the input when charFilters hits later + */ + public function testBeforeCharsReturnPart() + { + $result = MUtil_String::beforeChars('abcdef', 'god'); + $this->assertEquals($result, 'abc'); + } + + /** + * Return the whole input if no charFilters characters where there + */ + public function testBeforeCharsReturnAll() + { + $result = MUtil_String::beforeChars('abcdef', 'xyz'); + $this->assertEquals($result, 'abcdef'); + } + + /** + * Return true when the needle is contained in the haystack + */ + public function testContainsIndeed() + { + $result = MUtil_String::contains('abcdefg', 'def'); + $this->assertEquals($result, true); + } + + /** + * Return true when the needle is contained in the haystack, starting at the first character + */ + public function testContainsIndeedStart() + { + $result = MUtil_String::contains('abcdef', 'abc'); + $this->assertEquals($result, true); + } + + /** + * Return false when the needle is not contained in the haystack + */ + public function testContainsNot() + { + $result = MUtil_String::contains('abcdef', 'xyz'); + $this->assertEquals($result, false); + } + + /** + * Remove the characters where both strings are the same + */ + public function testStripStringLeftRemovepartFilter() + { + $result = MUtil_String::stripStringLeft('abcdef', 'abcx'); + $this->assertEquals($result, 'def'); + } + + /** + * Remove the characters where the input string starts with the filter + */ + public function testStripStringLeftRemoveWholeFilter() + { + $result = MUtil_String::stripStringLeft('abcdef', 'abc'); + $this->assertEquals($result, 'def'); + } + + /** + * Remove nothing as both strings have no common starting characters + */ + public function teststripStringLeftNothing() + { + $result = MUtil_String::stripStringLeft('abcdef', 'xabc'); + $this->assertEquals($result, 'abcdef'); + } +} This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <gem...@li...> - 2012-10-31 16:59:00
|
Revision: 1001 http://gemstracker.svn.sourceforge.net/gemstracker/?rev=1001&view=rev Author: matijsdejong Date: 2012-10-31 16:58:48 +0000 (Wed, 31 Oct 2012) Log Message: ----------- Added new string functions with tests Some more small renderer speedups Modified Paths: -------------- trunk/library/classes/MUtil/Html/ElementDecorator.php trunk/library/classes/MUtil/Html/HtmlElement.php trunk/library/classes/MUtil/Html/RepeatRenderer.php trunk/library/classes/MUtil/String.php trunk/test/classes/MUtil/StringTest.php Modified: trunk/library/classes/MUtil/Html/ElementDecorator.php =================================================================== --- trunk/library/classes/MUtil/Html/ElementDecorator.php 2012-10-31 15:43:33 UTC (rev 1000) +++ trunk/library/classes/MUtil/Html/ElementDecorator.php 2012-10-31 16:58:48 UTC (rev 1001) @@ -128,7 +128,7 @@ if ($prologue instanceof MUtil_Html_HtmlInterface) { $prologue = $prologue->render($view); } else { - $prologue = MUtil_Html::getrenderer()->renderAny($view, $prologue); + $prologue = MUtil_Html::getRenderer()->renderAny($view, $prologue); } } else { $prologue = ''; Modified: trunk/library/classes/MUtil/Html/HtmlElement.php =================================================================== --- trunk/library/classes/MUtil/Html/HtmlElement.php 2012-10-31 15:43:33 UTC (rev 1000) +++ trunk/library/classes/MUtil/Html/HtmlElement.php 2012-10-31 16:58:48 UTC (rev 1001) @@ -1056,11 +1056,11 @@ */ protected function renderContent(Zend_View_Abstract $view) { + $renderer = MUtil_Html::getRenderer(); if ($this->_content) { if ($this->_repeater && (! $this->_repeatTags)) { if ($this->_repeater->__start()) { $html = null; - $renderer = MUtil_Html::getRenderer(); while ($this->_repeater->__next()) { $html .= implode('', $renderer->renderArray($view, $this->_content)); } @@ -1068,13 +1068,13 @@ return $html; } - } elseif ($content = MUtil_Html::getRenderer()->renderArray($view, $this->_content)) { + } elseif ($content = $renderer->renderArray($view, $this->_content)) { return implode('', $content); } } if ($this->_onEmptyContent) { - return MUtil_Html::getRenderer()->renderAny($view, $this->_onEmptyContent); + return $renderer->renderAny($view, $this->_onEmptyContent); } return null; Modified: trunk/library/classes/MUtil/Html/RepeatRenderer.php =================================================================== --- trunk/library/classes/MUtil/Html/RepeatRenderer.php 2012-10-31 15:43:33 UTC (rev 1000) +++ trunk/library/classes/MUtil/Html/RepeatRenderer.php 2012-10-31 16:58:48 UTC (rev 1001) @@ -1,10 +1,9 @@ <?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 @@ -15,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 @@ -26,59 +25,60 @@ * 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 Html + * @author Matijs de Jong <mj...@ma...> + * @copyright Copyright (c) 2011 Erasmus MC + * @license New BSD License + * @version $Id$ */ /** * RepeatRenderer wraps itself around some content and returns at rendering * time that content repeated multiple times or the $_emptyContent when the * repeater is empty. - * - * Most of the functions are the just to implement the ElementInterface and + * + * Most of the functions are the just to implement the ElementInterface and * are nothing but a stub to the internal content. These functions will * throw errors if you try to use them in ways that the actual $_content does * not allow. * * @see MUtil_Lazy_Repeatable - * - * @author Matijs de Jong - * @package MUtil + * + * @package MUtil * @subpackage Html + * @copyright Copyright (c) 2011 Erasmus MC + * @license New BSD License + * @since Class available since version 1.0 */ class MUtil_Html_RepeatRenderer implements MUtil_Html_ElementInterface { /** * The content to be repeated. - * - * @var mixed + * + * @var mixed */ protected $_content; - + /** * The content to show when the $_repeater returns no data. - * + * * @var mixed Optional */ protected $_emptyContent; - + /** * Any content to mixed between the instances of content. - * + * * @var mixed Optional */ protected $_glue; - + /** * The repeater containing a dataset - * + * * @var MUtil_Lazy_RepeatableInterface */ protected $_repeater; @@ -161,7 +161,7 @@ /** * Renders the element into a html string - * + * * The $view is used to correctly encode and escape the output * * @param Zend_View_Abstract $view @@ -169,22 +169,22 @@ */ public function render(Zend_View_Abstract $view) { + $renderer = MUtil_Html::getRenderer(); if ($this->hasRepeater() && $this->_content) { $data = $this->getRepeater(); if ($data->__start()) { $html = array(); - $renderer = MUtil_Html::getRenderer(); while ($data->__next()) { $html[] = $renderer->renderAny($view, $this->_content); } if ($html) { - return implode(MUtil_Html::getRenderer()->renderAny($view, $this->_glue), $html); + return implode($renderer->renderAny($view, $this->_glue), $html); } } } if ($this->_emptyContent) { - return MUtil_Html::getRenderer()->renderAny($view, $this->_emptyContent); + return $renderer->renderAny($view, $this->_emptyContent); } return null; Modified: trunk/library/classes/MUtil/String.php =================================================================== --- trunk/library/classes/MUtil/String.php 2012-10-31 15:43:33 UTC (rev 1000) +++ trunk/library/classes/MUtil/String.php 2012-10-31 16:58:48 UTC (rev 1001) @@ -81,6 +81,32 @@ } /** + * Returns true if haystack ends with needle or needle is empty + * + * @param string $haystack The string to search in + * @param string $needle The string to search for + * @param boolean $caseInSensitive When true a case insensitive compare is performed + * @return boolean + */ + public static function endsWith($haystack, $needle, $caseInSensitive = false) + { + $len = strlen($needle); + if ($len == 0) { + return true; + } + + if ((strlen($haystack) < $len)) { + return false; + } + + if ($caseInSensitive) { + return strtolower(substr($haystack, -$len)) === strtolower($needle); + } + + return substr($haystack, -$len) === (string) $needle; + } + + /** * Split a string whereever the callback returns true (including * the character that returns true. * @@ -119,6 +145,32 @@ } /** + * Returns true if haystack starts with needle or needle is empty + * + * @param string $haystack The string to search in + * @param string $needle The string to search for + * @param boolean $caseInSensitive When true a case insensitive compare is performed + * @return boolean + */ + public static function startsWith($haystack, $needle, $caseInSensitive = false) + { + $len = strlen($needle); + if ($len == 0) { + return true; + } + + if ((strlen($haystack) < $len)) { + return false; + } + + if ($caseInSensitive) { + return strtolower(substr($haystack, 0, $len)) === strtolower($needle); + } + + return substr($haystack, 0, $len) === (string) $needle; + } + + /** * Return the part after $input and $filter have stopped being the same * * stripStringLeft('abcdef', 'abcx') => 'def' Modified: trunk/test/classes/MUtil/StringTest.php =================================================================== --- trunk/test/classes/MUtil/StringTest.php 2012-10-31 15:43:33 UTC (rev 1000) +++ trunk/test/classes/MUtil/StringTest.php 2012-10-31 16:58:48 UTC (rev 1001) @@ -103,6 +103,69 @@ } /** + * Haystack ends with needle but wrong case + */ + public function testEndsWithCaseFalse() + { + $result = MUtil_String::endsWith('abcdef', 'deF'); + $this->assertEquals($result, false); + } + + /** + * Haystack does not end with needle + */ + public function testEndsWithFalse() + { + $result = MUtil_String::endsWith('abcdef', 'xdef'); + $this->assertEquals($result, false); + } + + /** + * Needle is empty + */ + public function testEndsWithNeedleEmpty() + { + $result = MUtil_String::endsWith('abcdef', ''); + $this->assertEquals($result, true); + } + + /** + * Needle is longer than haystack + */ + public function testEndsWithNeedleLonger() + { + $result = MUtil_String::endsWith('abc', 'abcdef'); + $this->assertEquals($result, false); + } + + /** + * Haystack ends with needle that is number (should work) + */ + public function testEndsWithNumber() + { + $result = MUtil_String::endsWith('abc10', 10); + $this->assertEquals($result, true); + } + + /** + * Haystack ends with needle but only case insensitively + */ + public function testEndsWithNoCaseTrue() + { + $result = MUtil_String::endsWith('abCdef', 'Def', true); + $this->assertEquals($result, true); + } + + /** + * Haystack ends with needle + */ + public function testEndsWithTrue() + { + $result = MUtil_String::endsWith('abcdef', 'def'); + $this->assertEquals($result, true); + } + + /** * Test a default callback usage */ public function testSplitOnCharCallbackDefault() @@ -179,6 +242,69 @@ } /** + * Haystack starts with needle but wrong case + */ + public function testStartsWithCaseFalse() + { + $result = MUtil_String::startsWith('abcdef', 'abC'); + $this->assertEquals($result, false); + } + + /** + * Haystack does not start with needle + */ + public function testStartsWithFalse() + { + $result = MUtil_String::startsWith('abcdef', 'abcx'); + $this->assertEquals($result, false); + } + + /** + * Needle is empty + */ + public function testStartsWithNeedleEmpty() + { + $result = MUtil_String::startsWith('abcdef', ''); + $this->assertEquals($result, true); + } + + /** + * Needle is longer + */ + public function testStartsWithNeedleLonger() + { + $result = MUtil_String::startsWith('abc', 'abcdef'); + $this->assertEquals($result, false); + } + + /** + * Haystack starts with numberic needle that is the same (is allowed) + */ + public function testStartsWithNumber() + { + $result = MUtil_String::startsWith('10abc', 10); + $this->assertEquals($result, true); + } + + /** + * Haystack starts with needle, but only case-insentivile + */ + public function testStartsWithNoCaseTrue() + { + $result = MUtil_String::startsWith('abCdef', 'abC', true); + $this->assertEquals($result, true); + } + + /** + * Haystack starts with needle + */ + public function testStartsWithTrue() + { + $result = MUtil_String::startsWith('abcdef', 'abc'); + $this->assertEquals($result, true); + } + + /** * Remove the characters where both strings are the same */ public function testStripStringLeftRemovepartFilter() @@ -199,7 +325,7 @@ /** * Remove nothing as both strings have no common starting characters */ - public function teststripStringLeftNothing() + public function testStripStringLeftNothing() { $result = MUtil_String::stripStringLeft('abcdef', 'xabc'); $this->assertEquals($result, 'abcdef'); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <gem...@li...> - 2012-11-09 14:08:13
|
Revision: 1010 http://gemstracker.svn.sourceforge.net/gemstracker/?rev=1010&view=rev Author: matijsdejong Date: 2012-11-09 14:08:03 +0000 (Fri, 09 Nov 2012) Log Message: ----------- New isBase64 function Modified Paths: -------------- trunk/library/classes/MUtil/String.php trunk/test/classes/MUtil/StringTest.php Modified: trunk/library/classes/MUtil/String.php =================================================================== --- trunk/library/classes/MUtil/String.php 2012-11-09 12:13:47 UTC (rev 1009) +++ trunk/library/classes/MUtil/String.php 2012-11-09 14:08:03 UTC (rev 1010) @@ -107,6 +107,26 @@ } /** + * Test if a string is a valid base64 string. + * + * This test is only performed based on character inputand + * does perform an actual decoding to be sure. + * + * @param string $input + * @return boolean + */ + public static function isBase64($input) + { + if (0 === (strlen($input) % 4)) { + if (preg_match('/^[A-Za-z0-9+\\/]{2,}={0,2}$/', $input)) { + return true; + } + } + + return false; + } + + /** * Split a string whereever the callback returns true (including * the character that returns true. * Modified: trunk/test/classes/MUtil/StringTest.php =================================================================== --- trunk/test/classes/MUtil/StringTest.php 2012-11-09 12:13:47 UTC (rev 1009) +++ trunk/test/classes/MUtil/StringTest.php 2012-11-09 14:08:03 UTC (rev 1010) @@ -166,6 +166,88 @@ } /** + * An invalid base 64 string + */ + public function testIsBase64False() + { + $result = MUtil_String::isBase64('YW55IGNhcm5hbCBwbGVhc3=y'); + $this->assertEquals($result, false); + } + + /** + * An invalid base 64 string that is not a multiple of 4 characters + */ + public function testIsBase64FalseLength() + { + $result = MUtil_String::isBase64('a=b&c=d'); + $this->assertEquals($result, false); + } + + /** + * A valid base 64 string ending with '=' + */ + public function testIsBase64Is1() + { + $result = MUtil_String::isBase64('YW55IGN+cm5hbCBwbGVhc3U='); + $this->assertEquals($result, true); + } + + /** + * A valid base 64 string ending with '==' + */ + public function testIsBase64Is2() + { + $result = MUtil_String::isBase64('YW55IGNh/m5hbCBwbGVhcw=='); + $this->assertEquals($result, true); + } + + /** + * An invalid base 64 string ending with '===' + */ + public function testIsBase64Is3() + { + $result = MUtil_String::isBase64('YW55IGNhcm5hbCBwbGVhc==='); + $this->assertEquals($result, false); + } + + /** + * A valid base 64 string + */ + public function testIsBase64NoIs() + { + $result = MUtil_String::isBase64('YW55IGNhcm5hbCBwbGVhc3Vy'); + $this->assertEquals($result, true); + } + + /** + * A valid base 64 string + */ + public function testIsBase64Plus() + { + $result = MUtil_String::isBase64('YW55I+Nhcm5+bCBwbGVhc3Vy'); + $this->assertEquals($result, true); + } + + /** + * A valid base 64 string + */ + public function testIsBase64Slash() + { + $result = MUtil_String::isBase64('YW55I/Nhcm5/bCBwbGVhc3Vy'); + $this->assertEquals($result, true); + } + + /** + * A valid base 64 string + */ + public function testIsBase64SlashPlus() + { + $result = MUtil_String::isBase64('YW55I+Nhcm5+bC/w/GVhc3Vy'); + $this->assertEquals($result, true); + } + + + /** * Test a default callback usage */ public function testSplitOnCharCallbackDefault() This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <gem...@li...> - 2012-11-22 15:59:58
|
Revision: 1037 http://gemstracker.svn.sourceforge.net/gemstracker/?rev=1037&view=rev Author: matijsdejong Date: 2012-11-22 15:59:49 +0000 (Thu, 22 Nov 2012) Log Message: ----------- Added decimal functions provided by Roel Added Paths: ----------- trunk/library/classes/MUtil/Dec.php trunk/test/classes/MUtil/DecTest.php Added: trunk/library/classes/MUtil/Dec.php =================================================================== --- trunk/library/classes/MUtil/Dec.php (rev 0) +++ trunk/library/classes/MUtil/Dec.php 2012-11-22 15:59:49 UTC (rev 1037) @@ -0,0 +1,87 @@ +<?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 MUtil + * @subpackage Math + * @author Matijs de Jong <mj...@ma...> + * @copyright Copyright (c) 2011 Erasmus MC + * @license New BSD License + * @version $Id$ + */ + +/** + * Decimal calculation utilities + * + * RF: winbill at hotmail dot com 16-Dec-2010 09:31 + * There are issues around float rounding/flooring, + * use of intermediate typecasting to string (strval) avoids problems + * + * jolyon at mways dot co dot uk 10-Aug-2004 11:41 + * The thing to remember here is that the way a float stores a value makes it + * very easy for these kind of things to happen. When 79.99 is multiplied + * by 100, the actual value stored in the float is probably something like + * 7998.9999999999999999999999999999999999, PHP would print out 7999 when the + * value is displayed but floor would therefore round this down to 7998. + * + * + * @package MUtil + * @subpackage Math + * @copyright Copyright (c) 2011 Erasmus MC + * @license New BSD License + * @since Class available since version 1.5 + */ +class MUtil_Dec +{ + /** + * Get the floor using the specified precision + * + * @param float $number + * @param int $precision + * @return float + */ + public static function floor($number, $precision) + { + $coefficient = pow(10,$precision); + return floor(strval($number*$coefficient))/$coefficient; + } + + /** + * Get the ceiling using the specified precision + * + * @param float $number + * @param int $precision + * @return float + */ + public static function ceil($number, $precision) + { + $coefficient = pow(10,$precision); + return ceil(strval($number*$coefficient))/$coefficient; + } + +} Added: trunk/test/classes/MUtil/DecTest.php =================================================================== --- trunk/test/classes/MUtil/DecTest.php (rev 0) +++ trunk/test/classes/MUtil/DecTest.php 2012-11-22 15:59:49 UTC (rev 1037) @@ -0,0 +1,113 @@ +<?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 MUtil + * @subpackage Dec + * @author Matijs de Jong <mj...@ma...> + * @copyright Copyright (c) 2011 Erasmus MC + * @license New BSD License + * @version $Id$ + */ + +require_once 'PHPUnit/Framework/TestCase.php'; + +/** + * Unit test for class MUtil_String + * + * @package MUtil + * @subpackage Dec + * @copyright Copyright (c) 2011 Erasmus MC + * @license New BSD License + * @since Class available since version 1.5.7 + */ +class MUtil_DecTest extends PHPUnit_Framework_TestCase +{ + /** + * Dataprovider + * + * @return array + */ + public static function forCeiling() + { + return array( + array(10.49825, 1, 10.5), + array(10.99825, 1, 11.0), + array(10.09825, 1, 10.1), + array(10.09825, 2, 10.10), + array(10.09825, 3, 10.099), + array(79.99*100, 0, 7999), + array(79.99*100, -1, 8000), + array((10.02-10)*100, 1, 2.0), + ); + } + + /** + * Dataprovider + * + * @return array + */ + public static function forFloor() + { + return array( + array(10.49825, 1, 10.4), + array(10.99825, 1, 10.9), + array(10.09825, 1, 10.0), + array(10.09825, 2, 10.09), + array(10.09825, 3, 10.098), + array(79.99*100, 0, 7999), + array(79.99*100, -1, 7990), + array((10.02-10)*100, 1, 2.0), + ); + } + + /** + * + * @dataProvider forCeiling + * @param float $float + * @param int $precision + * @param float $output + */ + public function testCeil($float, $precision, $output) + { + $this->assertEquals($output, MUtil_Dec::ceil($float, $precision)); + } + + /** + * + * @dataProvider forFloor + * @param float $float + * @param int $precision + * @param float $output + */ + public function testFloor($float, $precision, $output) + { + $this->assertEquals($output, MUtil_Dec::floor($float, $precision)); + } +} This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <gem...@li...> - 2012-12-06 12:38:41
|
Revision: 1055 http://gemstracker.svn.sourceforge.net/gemstracker/?rev=1055&view=rev Author: mennodekker Date: 2012-12-06 12:38:27 +0000 (Thu, 06 Dec 2012) Log Message: ----------- Merged revision(s) 1053-1054 from branches/receptioncodes: Added onLoad for date fields + make save call the onload for the return values Modified Paths: -------------- trunk/library/classes/MUtil/Model/DatabaseModelAbstract.php trunk/library/classes/MUtil/Model/JoinModel.php trunk/library/classes/MUtil/Model/ModelAbstract.php trunk/library/classes/MUtil/Model/TableModel.php Property Changed: ---------------- trunk/ trunk/library/ Property changes on: trunk ___________________________________________________________________ Modified: svn:mergeinfo - /branches/1.5.0-pulse:306-430,467 /branches/1.5.x:426-455,458-472,475-481 /tags/1.5.0beta1:305 /tags/1.5.1:485,489,509-510 /tags/1.5.3-rc2:612,614,616,618 + /branches/1.5.0-pulse:306-430,467 /branches/1.5.x:426-455,458-472,475-481 /branches/receptioncodes:1053-1054 /tags/1.5.0beta1:305 /tags/1.5.1:485,489,509-510 /tags/1.5.3-rc2:612,614,616,618 Property changes on: trunk/library ___________________________________________________________________ Modified: svn:mergeinfo - /branches/1.5.0-pulse/library:306-344,346,467 /branches/1.5.x/library:426-455,458-472,475-481 /branches/newUser:113-150 /branches/newUser2:175-207 /branches/userloader:259-324 /tags/1.5.0beta1/library:305 /tags/1.5.1/library:485,489,509-510,534 /tags/1.5.3-rc2/library:612,614,616,618 /tags/1.5.6-pulse20121012/library:986 + /branches/1.5.0-pulse/library:306-344,346,467 /branches/1.5.x/library:426-455,458-472,475-481 /branches/newUser:113-150 /branches/newUser2:175-207 /branches/receptioncodes/library:1053-1054 /branches/userloader:259-324 /tags/1.5.0beta1/library:305 /tags/1.5.1/library:485,489,509-510,534 /tags/1.5.3-rc2/library:612,614,616,618 /tags/1.5.6-pulse20121012/library:986 Modified: trunk/library/classes/MUtil/Model/DatabaseModelAbstract.php =================================================================== --- trunk/library/classes/MUtil/Model/DatabaseModelAbstract.php 2012-12-06 12:20:24 UTC (rev 1054) +++ trunk/library/classes/MUtil/Model/DatabaseModelAbstract.php 2012-12-06 12:38:27 UTC (rev 1055) @@ -332,6 +332,7 @@ $finfo['type'] = MUtil_Model::TYPE_DATE; $this->set($name, 'storageFormat', 'yyyy-MM-dd'); $this->setOnSave($name, array($this, 'formatSaveDate')); + $this->setOnLoad($name, array($this, 'formatLoadDate')); break; case 'datetime': @@ -339,12 +340,14 @@ $finfo['type'] = MUtil_Model::TYPE_DATETIME; $this->set($name, 'storageFormat', 'yyyy-MM-dd HH:mm:ss'); $this->setOnSave($name, array($this, 'formatSaveDate')); + $this->setOnLoad($name, array($this, 'formatLoadDate')); break; case 'time': $finfo['type'] = MUtil_Model::TYPE_TIME; $this->set($name, 'storageFormat', 'HH:mm:ss'); $this->setOnSave($name, array($this, 'formatSaveDate')); + $this->setOnLoad($name, array($this, 'formatLoadDate')); break; case 'int': @@ -670,6 +673,32 @@ throw new MUtil_Model_ModelException("Cannot create UniqueValue validator as no table was defined for field $name."); } + + /** + * A ModelAbstract->setOnLoad() function that takes care of transforming a + * dateformat read from the database to a Zend_Date format + * + * If empty or Zend_Db_Expression (after save) it will return just the value + * currently there are no checks for a valid date format. + * + * @see MUtil_Model_ModelAbstract + * + * @param mixed $value The value being saved + * @param boolean $isNew True when a new item is being saved + * @param string $name The name of the current field + * @param array $context Optional, the other values being saved + * @return MUtil_Date|Zend_Db_Expr|string + */ + public function formatLoadDate($value, $isNew = false, $name = null, array $context = array()) + { + // If not empty or zend_db_expression and not already a zend date, we + // transform to a Zend_Date using the ISO_8601 format + if (!empty($value) && !($value instanceof Zend_Date) && !($value instanceof Zend_Db_Expr)) { + $tmpDate = new MUtil_Date($value, Zend_Date::ISO_8601); + return $tmpDate; + } + return $value; + } /** * A ModelAbstract->setOnSave() function that returns the input Modified: trunk/library/classes/MUtil/Model/JoinModel.php =================================================================== --- trunk/library/classes/MUtil/Model/JoinModel.php 2012-12-06 12:20:24 UTC (rev 1054) +++ trunk/library/classes/MUtil/Model/JoinModel.php 2012-12-06 12:38:27 UTC (rev 1055) @@ -373,6 +373,9 @@ if ($this->getChanged() > $oldChanged) { $this->setChanged(++$oldChanged); } + + // Handle possible onLoad + $newValues = $this->processAfterLoad($newValues); return $newValues; } Modified: trunk/library/classes/MUtil/Model/ModelAbstract.php =================================================================== --- trunk/library/classes/MUtil/Model/ModelAbstract.php 2012-12-06 12:20:24 UTC (rev 1054) +++ trunk/library/classes/MUtil/Model/ModelAbstract.php 2012-12-06 12:38:27 UTC (rev 1055) @@ -152,8 +152,10 @@ */ protected function _filterDataAfterLoad(array $data, $new = false) { - foreach ($data as $name => $value) { - $data[$name] = $this->getOnLoad($value, $new, $name, $data); + if ($this->getMeta(self::LOAD_TRANSFORMER)) { + foreach ($data as $name => $value) { + $data[$name] = $this->getOnLoad($value, $new, $name, $data); + } } return $data; Modified: trunk/library/classes/MUtil/Model/TableModel.php =================================================================== --- trunk/library/classes/MUtil/Model/TableModel.php 2012-12-06 12:20:24 UTC (rev 1054) +++ trunk/library/classes/MUtil/Model/TableModel.php 2012-12-06 12:38:27 UTC (rev 1055) @@ -119,6 +119,10 @@ { // $this->_saveTableData returns the new row values, including any automatic changes. // add $newValues to throw nothing away. - return $this->_saveTableData($this->_table, $newValues, $filter, parent::SAVE_MODE_ALL) + $newValues; + $updatedValues = $this->_saveTableData($this->_table, $newValues, $filter, parent::SAVE_MODE_ALL) + $newValues; + + // Handle possible onLoad + $updatedValues = $this->processAfterLoad($updatedValues); + return $updatedValues; } } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <gem...@li...> - 2013-01-03 08:22:13
|
Revision: 1086 http://gemstracker.svn.sourceforge.net/gemstracker/?rev=1086&view=rev Author: mennodekker Date: 2013-01-03 08:22:06 +0000 (Thu, 03 Jan 2013) Log Message: ----------- Replaced GEMS_PROJECT_PATH with APPLICATION_PATH and updated changelog.txt Modified Paths: -------------- trunk/library/changelog.txt trunk/new_project/application/configs/application.ini Modified: trunk/library/changelog.txt =================================================================== --- trunk/library/changelog.txt 2013-01-02 14:04:56 UTC (rev 1085) +++ trunk/library/changelog.txt 2013-01-03 08:22:06 UTC (rev 1086) @@ -1,6 +1,6 @@ Important changes from 1.5.7 => 1.6 ============================================================ -Defined constant GEMS_PROJECT_PATH removed from code +Defined constant GEMS_PROJECT_PATH removed from code (update at least your application.ini and use APPLICATION_PATH instead) Moved date_default_timezone_set to index.php (can generate warnings) Important changes from 1.5.6 => 1.5.7 Modified: trunk/new_project/application/configs/application.ini =================================================================== --- trunk/new_project/application/configs/application.ini 2013-01-02 14:04:56 UTC (rev 1085) +++ trunk/new_project/application/configs/application.ini 2013-01-03 08:22:06 UTC (rev 1086) @@ -13,7 +13,7 @@ resources.db.params.username = USER resources.db.params.password = PASSWD resources.db.isDefaultTableAdapter = true -resources.frontController.controllerDirectory = GEMS_PROJECT_PATH "/controllers" +resources.frontController.controllerDirectory = APPLICATION_PATH "/controllers" resources.layout.layout = "gems-fluid" resources.layout.layoutPath = GEMS_LIBRARY_DIR "/layouts/scripts" This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <gem...@li...> - 2013-01-10 17:08:56
|
Revision: 1093 http://gemstracker.svn.sourceforge.net/gemstracker/?rev=1093&view=rev Author: matijsdejong Date: 2013-01-10 17:08:49 +0000 (Thu, 10 Jan 2013) Log Message: ----------- Updated tests and default installation to 1.6 Modified Paths: -------------- trunk/new_project/application/configs/application.ini trunk/test/bootstrap.php trunk/test/library/Gems/Test/DbTestAbstract.php trunk/test/library/Gems/Test/TestAbstract.php trunk/test/library/project-bootstrap.php Modified: trunk/new_project/application/configs/application.ini =================================================================== --- trunk/new_project/application/configs/application.ini 2013-01-10 16:43:36 UTC (rev 1092) +++ trunk/new_project/application/configs/application.ini 2013-01-10 17:08:49 UTC (rev 1093) @@ -5,6 +5,8 @@ bootstrap.path = "NewProject/Escort.php" bootstrap.class = "NewProject_Escort" +loaderDirs.NewProject = APPLICATION_PATH "/classes/NewProject" +loaderDirs.Gems = GEMS_LIBRARY_DIR "/classes/Gems" ; resources.db.adapter = PDO_MYSQL resources.db.adapter = Mysqli resources.db.params.charset = utf8 @@ -31,3 +33,4 @@ phpSettings.display_startup_errors = 1 phpSettings.display_errors = 1 firebug.log = 1 +zfdebug.activate = 0 Modified: trunk/test/bootstrap.php =================================================================== --- trunk/test/bootstrap.php 2013-01-10 16:43:36 UTC (rev 1092) +++ trunk/test/bootstrap.php 2013-01-10 17:08:49 UTC (rev 1093) @@ -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 @@ -25,7 +25,7 @@ * 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. - * + * * Unit test bootstrap * * @author Michiel Rook <mi...@to...> @@ -33,10 +33,7 @@ * @package Gems */ -// Needed for strict on >= PHP 5.1.2 -if (version_compare(phpversion(), '5.1.2') > 0) { - date_default_timezone_set('Europe/Amsterdam'); -} +date_default_timezone_set('Europe/Amsterdam'); /** * Setup environment @@ -49,11 +46,6 @@ define('APPLICATION_ENV', 'development'); define('APPLICATION_PATH', GEMS_ROOT_DIR . '/application'); -$GLOBALS['GEMS_DIRS'] = array( - GEMS_PROJECT_NAME_UC => APPLICATION_PATH . '/classes', - 'Gems' => GEMS_LIBRARY_DIR . '/classes' -); - /** * Setup include path */ Modified: trunk/test/library/Gems/Test/DbTestAbstract.php =================================================================== --- trunk/test/library/Gems/Test/DbTestAbstract.php 2013-01-10 16:43:36 UTC (rev 1092) +++ trunk/test/library/Gems/Test/DbTestAbstract.php 2013-01-10 17:08:49 UTC (rev 1093) @@ -70,14 +70,14 @@ protected function setUp() { parent::setUp(); - - global $GEMS_DIRS; $this->db = $this->getConnection()->getConnection(); Zend_Registry::set('db', $this->db); - $this->loader = new Gems_Loader(Zend_Registry::getInstance(), $GEMS_DIRS); + $settings = new Zend_Config_Ini(GEMS_ROOT_DIR . '/application/configs/application.ini', APPLICATION_ENV); + $sa = $settings->toArray(); + $this->loader = new Gems_Loader(Zend_Registry::getInstance(), $sa['loaderDirs']); Zend_Registry::set('loader', $this->loader); } Modified: trunk/test/library/Gems/Test/TestAbstract.php =================================================================== --- trunk/test/library/Gems/Test/TestAbstract.php 2013-01-10 16:43:36 UTC (rev 1092) +++ trunk/test/library/Gems/Test/TestAbstract.php 2013-01-10 17:08:49 UTC (rev 1093) @@ -53,7 +53,7 @@ * @var Gems_Loader */ protected $loader = null; - + /** * @var Zend_Db */ @@ -63,25 +63,25 @@ * @var Gems_Tracker */ protected $tracker = null; - + /** * Sets up the fixture, for example, opens a network connection. * This method is called before a test is executed. */ protected function setUp() { - global $GEMS_DIRS; - $this->db = Zend_Db::factory('pdo_sqlite', array('dbname'=>':memory:')); - + Zend_Registry::set('db', $this->db); - - $this->loader = new Gems_Loader(Zend_Registry::getInstance(), $GEMS_DIRS); - + + $settings = new Zend_Config_Ini(GEMS_ROOT_DIR . '/application/configs/application.ini', APPLICATION_ENV); + $sa = $settings->toArray(); + $this->loader = new Gems_Loader(Zend_Registry::getInstance(), $sa['loaderDirs']); + Zend_Registry::set('loader', $this->loader); - + $this->tracker = $this->loader->getTracker(); - + Zend_Registry::set('tracker', $this->tracker); } } Modified: trunk/test/library/project-bootstrap.php =================================================================== --- trunk/test/library/project-bootstrap.php 2013-01-10 16:43:36 UTC (rev 1092) +++ trunk/test/library/project-bootstrap.php 2013-01-10 17:08:49 UTC (rev 1093) @@ -16,11 +16,6 @@ define('APPLICATION_ENV', 'development'); define('APPLICATION_PATH', GEMS_ROOT_DIR . '/application'); -$GLOBALS['GEMS_DIRS'] = array( - GEMS_PROJECT_NAME_UC => APPLICATION_PATH . '/classes', - 'Gems' => GEMS_LIBRARY_DIR . '/classes' -); - /** * Setup include path */ This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <gem...@li...> - 2013-03-14 11:45:15
|
Revision: 1183 http://sourceforge.net/p/gemstracker/code/1183 Author: matijsdejong Date: 2013-03-14 11:45:12 +0000 (Thu, 14 Mar 2013) Log Message: ----------- The default GemsTracker installation is now international The default NewProject is setup for Dutch respondents Modified Paths: -------------- trunk/library/configs/db/tables/gems__respondent2org.50.sql trunk/library/configs/db/tables/gems__respondents.30.sql trunk/library/controllers/RespondentController.php Added Paths: ----------- trunk/new_project/application/classes/NewProject/Model/ trunk/new_project/application/classes/NewProject/Model/RespondentModel.php trunk/new_project/application/configs/db/ trunk/new_project/application/configs/db/tables/ Modified: trunk/library/configs/db/tables/gems__respondent2org.50.sql =================================================================== --- trunk/library/configs/db/tables/gems__respondent2org.50.sql 2013-03-14 11:27:20 UTC (rev 1182) +++ trunk/library/configs/db/tables/gems__respondent2org.50.sql 2013-03-14 11:45:12 UTC (rev 1183) @@ -10,7 +10,7 @@ -- gr2o_id_physician bigint unsigned null -- references gems_staff (gsf_id_user), - gr2o_treatment varchar(200) CHARACTER SET 'utf8' COLLATE 'utf8_general_ci' null, + -- gr2o_treatment varchar(200) CHARACTER SET 'utf8' COLLATE 'utf8_general_ci' null, gr2o_comments text CHARACTER SET 'utf8' COLLATE 'utf8_general_ci' null, gr2o_consent varchar(20) CHARACTER SET 'utf8' COLLATE 'utf8_general_ci' not null default 'Unknown' Modified: trunk/library/configs/db/tables/gems__respondents.30.sql =================================================================== --- trunk/library/configs/db/tables/gems__respondents.30.sql 2013-03-14 11:27:20 UTC (rev 1182) +++ trunk/library/configs/db/tables/gems__respondents.30.sql 2013-03-14 11:45:12 UTC (rev 1183) @@ -10,7 +10,7 @@ grs_email varchar(100) CHARACTER SET 'utf8' COLLATE 'utf8_general_ci' null, grs_first_name varchar(30) CHARACTER SET 'utf8' COLLATE 'utf8_general_ci', - grs_surname_prefix varchar(10) CHARACTER SET 'utf8' COLLATE 'utf8_general_ci', + -- grs_surname_prefix varchar(10) CHARACTER SET 'utf8' COLLATE 'utf8_general_ci', grs_last_name varchar(50) CHARACTER SET 'utf8' COLLATE 'utf8_general_ci', grs_gender char(1) CHARACTER SET 'utf8' COLLATE 'utf8_general_ci' not null default 'U', Modified: trunk/library/controllers/RespondentController.php =================================================================== --- trunk/library/controllers/RespondentController.php 2013-03-14 11:27:20 UTC (rev 1182) +++ trunk/library/controllers/RespondentController.php 2013-03-14 11:45:12 UTC (rev 1183) @@ -1,6 +1,5 @@ <?php - /** * Copyright (c) 2011, Erasmus MC * All rights reserved. @@ -26,8 +25,23 @@ * 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 Default + * @author Matijs de Jong <mj...@ma...> + * @copyright Copyright (c) 2011 Erasmus MC + * @license New BSD License + * @version $Id$ */ -class RespondentController extends Gems_Default_RespondentAction +/** + * Stub for RespondentNewAction, that allows overrulling of this controller in a project. + * + * @package Gems + * @subpackage Default + * @copyright Copyright (c) 2011 Erasmus MC + * @license New BSD License + * @since Class available since version 1.0 + */ +class RespondentController extends Gems_Default_RespondentNewAction { } \ No newline at end of file Added: trunk/new_project/application/classes/NewProject/Model/RespondentModel.php =================================================================== --- trunk/new_project/application/classes/NewProject/Model/RespondentModel.php (rev 0) +++ trunk/new_project/application/classes/NewProject/Model/RespondentModel.php 2013-03-14 11:45:12 UTC (rev 1183) @@ -0,0 +1,77 @@ +<?php + +/** + * Copyright (c) 2012, 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 Model + * @author Matijs de Jong <mj...@ma...> + * @copyright Copyright (c) 2012 Erasmus MC + * @license New BSD License + * @version $id: RespondentModel.php 203 2012-01-01t 12:51:32Z matijs $ + */ + +/** + * Default inmplementation of Dutch respondent model + * + * @package Gems + * @subpackage Model + * @copyright Copyright (c) 2012 Erasmus MC + * @license New BSD License + * @since Class available since version 1.6 + */ +class NewProject_Model_RespondentModel extends Gems_Model_RespondentNlModel +{ + /** + * Set those settings needed for the detailed display + * + * @param mixed $locale The locale for the settings + * @return \Gems_Model_RespondentModel + */ + public function applyDetailSettings($locale = null) + { + parent::applyDetailSettings($locale); + + // $translator = $this->translate->getAdapter(); + // $this->setIfExists('grs_phone_2', 'label', $translator->_('Mobile phone')); + + return $this; + } + + /** + * Set those values needed for editing + * + * @param mixed $locale The locale for the settings + * @return \Gems_Model_RespondentModel + * / + public function applyEditSettings($locale = null) + { + parent::applyEditSettings($locale); + + return $this; + } // */ +} This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <gem...@li...> - 2013-03-22 14:02:21
|
Revision: 1203 http://sourceforge.net/p/gemstracker/code/1203 Author: mennodekker Date: 2013-03-22 14:02:16 +0000 (Fri, 22 Mar 2013) Log Message: ----------- Initial checking of OpenRosa survey source (not tested to work yet) Modified Paths: -------------- trunk/library/classes/Gems/Menu.php trunk/library/classes/Gems/Model.php trunk/library/classes/GemsEscort.php trunk/new_project/application/configs/application.ini Added Paths: ----------- trunk/library/classes/Gems/Default/OpenrosaAction.php trunk/library/classes/OpenRosa/ trunk/library/classes/OpenRosa/Model/ trunk/library/classes/OpenRosa/Model/OpenRosaFormModel.php trunk/library/classes/OpenRosa/Tracker/ trunk/library/classes/OpenRosa/Tracker/Source/ trunk/library/classes/OpenRosa/Tracker/Source/OpenRosa/ trunk/library/classes/OpenRosa/Tracker/Source/OpenRosa/Form.php trunk/library/classes/OpenRosa/Tracker/Source/OpenRosa/Model.php trunk/library/classes/OpenRosa/Tracker/Source/OpenRosa.php trunk/library/controllers/OpenrosaController.php trunk/new_project/var/settings/pwd.txt Added: trunk/library/classes/Gems/Default/OpenrosaAction.php =================================================================== --- trunk/library/classes/Gems/Default/OpenrosaAction.php (rev 0) +++ trunk/library/classes/Gems/Default/OpenrosaAction.php 2013-03-22 14:02:16 UTC (rev 1203) @@ -0,0 +1,422 @@ +<?php + +/** + * Handles call like an openRosa compliant server. Implements the api as described on + * https://bitbucket.org/javarosa/javarosa/wiki/OpenRosaAPI + * + * To implement, place the controller in the right directory and allow access without login to the + * following actions: + * formList - Lists the forms available + * submission - Handles receiving a submitted form + * download - Download a form + */ +class Gems_Default_OpenrosaAction extends Gems_Controller_BrowseEditAction +{ + /** + * This holds the path to the location where the form definitions will be stored. + * Will be set on init to: GEMS_ROOT_DIR . '/var/uploads/openrosa/forms/'; + * + * @var string + */ + public $formDir; + + /** + * This holds the path to the location where the uploaded responses and their + * backups will be stored. + * + * Will be set on init to: GEMS_ROOT_DIR . '/var/uploads/openrosa/'; + * + * @var string + */ + public $responseDir; + + /** + * @var Zend_Auth + */ + protected $auth; + + /** + * This lists the actions that need http-auth. Only applies to the actions that + * the openRosa application needs. + * + * ODK Collect: http://code.google.com/p/opendatakit/wiki/ODKCollect + * + * @var array Array of actions + */ + protected $authActions = array('formlist', 'submission', 'download'); + + /** + * This can be used to generate barcodes, use the action + * + * /openrosa/barcode/code/<tokenid> + * + * example: + * /openrosa/barocde/code/22pq-grkq + * + * The image will be a png + */ + public function barcodeAction() + { + $code = $this->getRequest()->getParam('code', 'empty'); + Zend_Layout::getMvcInstance()->disableLayout(); + $this->_helper->viewRenderer->setNoRender(); + + $barcodeOptions = array('text' => $code); + $rendererOptions = array(); + $barcode = Zend_Barcode::render('code128', 'image', $barcodeOptions, $rendererOptions); + $barcode->render(); + } + + protected function createModel($detailed, $action) + { + $model = $this->loader->getModels()->getOpenRosaFormModel(); + + $model->set('TABLE_ROWS', 'label', $this->_('Responses'), 'elementClass', 'Exhibitor'); + + return $model; + } + + /** + * This action should serve the right form to the downloading application + * it should also handle expiration / availability of forms + */ + public function downloadAction() + { + $filename = $this->getRequest()->getParam('form'); + $filename = basename($filename); //Strip paths + + $file = $this->formDir . $filename; + + if (!empty($filename) && file_exists($file)) { + $this->getHelper('layout')->disableLayout(); + $this->getResponse()->setHeader('Content-Type', 'application/xml; charset=utf-8'); + header('Content-Description: File Transfer'); + header('Content-Type: application/octet-stream'); + header('Content-Disposition: attachment; filename="' . $filename . '"'); + header('Content-Transfer-Encoding: binary'); + header('Expires: 0'); + header('Cache-Control: must-revalidate, post-check=0, pre-check=0'); + header('Pragma: public'); + header('Content-Length: ' . filesize($file)); + ob_clean(); + flush(); + readfile($file); + exit; + } else { + $this->getResponse()->setHttpResponseCode(404); + $this->html->div("form $filename not found"); + } + } + + /** + * Accessible via formList as defined in the menu and standard for openRosa clients + */ + public function formlistAction() + { + //first create the baseurl of the form http(s)://projecturl/openrosa/download/form/ + $helper = new Zend_View_Helper_ServerUrl(); + $baseUrl = $helper->serverUrl() . Zend_Controller_Front::getInstance()->getBaseUrl() . '/openrosa/download/form/'; + + //As we don't have forms defined yet, we pass in an array, but ofcourse this should be dynamic + //and come from a helper method + $model = $this->getModel(); + $rawForms = $model->load(array('gof_form_active'=>1)); + foreach($rawForms as $form) { + $forms[] = array( + 'formID' => $form['gof_form_id'], + 'name' => $form['gof_form_title'], + 'version' => $form['gof_form_version'], + 'hash' => md5($form['gof_form_id'].$form['gof_form_version']), + 'downloadUrl' => $baseUrl . $form['gof_form_xml'] + ); + } + + //Now make it a rosaresponse + $this->makeRosaResponse(); + + $xml = $this->getXml('xforms xmlns="http://openrosa.org/xforms/xformsList"'); + foreach ($forms as $form) { + $xform = $xml->addChild('xform'); + foreach ($form as $key => $value) { + $xform->addChild($key, $value); + } + } + + echo $xml->asXML(); + } + + public function getTopic($count = 1) + { + return 'OpenRosa Form'; + } + + public function getTopicTitle() + { + return 'OpenRosa Forms'; + } + + /** + * Create an xml response + * + * @param string $rootNode + * @return SimpleXMLElement + */ + protected function getXml($rootNode) + { + $this->getResponse()->setHeader('Content-Type', 'text/xml; charset=utf-8'); + + $xml = simplexml_load_string("<?xml version='1.0' encoding='utf-8'?><$rootNode />"); + + return $xml; + } + + public function init() + { + parent::init(); + + $this->responseDir = GEMS_ROOT_DIR . '/var/uploads/openrosa/'; + $this->formDir = $this->responseDir . 'forms/'; + } + + /** + * Each rosa response should have the x-openrosa-version header and disable the layout to allow + * for xml repsonses if needed. We don't need a menu etc. on the openrosa responses + */ + protected function makeRosaResponse() + { + $this->getHelper('layout')->disableLayout(); + $this->getResponse()->setHeader('X-OpenRosa-Version', '1.0'); + } + + /** + * Handles receiving and storing the data from a form, files are stored on actual upload process + * this only handles storing form data and can be used for resubmission too. + * + * @param type $xmlFile + * @return string DeviceID or false on failure + */ + private function processReceivedForm($answerXmlFile) + { + //Log what we received + $log = Gems_Log::getLogger(); + //$log->log(print_r($xmlFile, true), Zend_Log::ERR); + + $xml = simplexml_load_file($answerXmlFile); + + $formId = $xml->attributes()->id; + $formVersion = $xml->attributes()->version; + //Lookup what form belongs to this formId and then save + $model = $this->getModel(); + $filter = array( + //'gof_form_active' => 1, + 'gof_form_id' => $formId, + 'gof_form_version' => $formVersion, + ); + if ($formData = $model->loadFirst($filter)) { + $form = new OpenRosa_Tracker_Source_OpenRosa_Form($this->formDir . $formData['gof_form_xml']); + $form->saveAnswer($answerXmlFile); + + $deviceId = $xml->DeviceId[0]; + return $deviceId; + } else { + return false; + } + } + + + /** + * Implements HTTP Basic auth + */ + public function preDispatch() + { + parent::preDispatch(); + + $action = strtolower($this->getRequest()->getActionName()); + if (in_array($action, $this->authActions)) { + $auth = Zend_Auth::getInstance(); + $this->auth = $auth; + + if (!$auth->hasIdentity()) { + $config = array( + 'accept_schemes' => 'basic', + 'realm' => GEMS_PROJECT_NAME, + 'nonce_timeout' => 3600, + ); + $adapter = new Zend_Auth_Adapter_Http($config); + $basicResolver = new Zend_Auth_Adapter_Http_Resolver_File(); + + //This is a basic resolver, use username:realm:password + //@@TODO: move to a better db stored authentication system + + $basicResolver->setFile(GEMS_ROOT_DIR . '/var/settings/pwd.txt'); + $adapter->setBasicResolver($basicResolver); + $request = $this->getRequest(); + $response = $this->getResponse(); + + assert($request instanceof Zend_Controller_Request_Http); + assert($response instanceof Zend_Controller_Response_Http); + + $adapter->setRequest($request); + $adapter->setResponse($response); + + $result = $auth->authenticate($adapter); + + if (!$result->isValid()) { + $adapter->getResponse()->sendResponse(); + print 'Unauthorized'; + exit; + } + } + } + } + + public function scanAction() + { + $model = $this->getModel(); + + //Perform a scan of the form directory, to update the database of forms + $eDir = dir($this->formDir); + + $formCnt = 0; + $addCnt = 0; + while (false !== ($filename = $eDir->read())) { + if (substr($filename, -4) == '.xml') { + $formCnt++; + $form = new OpenRosa_Tracker_Source_OpenRosa_Form($this->formDir . $filename); + $filter['gof_form_id'] = $form->getFormID(); + $filter['gof_form_version'] = $form->getFormVersion(); + $forms = $model->load($filter); + + if (!$forms) { + $newValues = array(); + $newValues['gof_id'] = null; + $newValues['gof_form_id'] = $form->getFormID(); + $newValues['gof_form_version'] = $form->getFormVersion(); + $newValues['gof_form_title'] = $form->getTitle(); + $newValues['gof_form_xml'] = $filename; + $newValues = $model->save($newValues); + MUtil_Echo::r($newValues, 'added form'); + $addCnt++; + } + } + } + + $cache = GemsEscort::getInstance()->cache; + $cache->clean(); + + $this->html[] = sprintf('Checked %s forms and added %s forms', $formCnt, $addCnt); + } + + public function scanresponsesAction() + { + $model = $this->getModel(); + + //Perform a scan of the form directory, to update the database of forms + $eDir = dir($this->responseDir); + + $formCnt = 0; + $addCnt = 0; + $rescan = $this->getRequest()->getParam('rescan', false); + while (false !== ($filename = $eDir->read())) { + $ext = substr($filename, -4); + if ($ext == '.xml' || ($ext == '.bak' && $rescan)) { + if ($rescan) { + $oldname = $filename; + $filename = substr($oldname, 0, -4) . '.xml'; + rename($this->responseDir . $oldname, $this->responseDir . $filename); + } + $files[] = $filename; + $formCnt++; + } + } + + foreach ($files as $filename) { + $result = $this->processReceivedForm($this->responseDir . $filename); + if ($result !== false) { + $addCnt++; + } + } + $cache = GemsEscort::getInstance()->cache; + $cache->clean(); + + $this->html[] = sprintf('Checked %s responses and added %s responses', $formCnt, $addCnt); + } + + /** + * Accepts the form + * + * Takes two roundtrips: + * - first we get a HEAD request that should be answerd with + * responsecode 204 + * - then we get a post that only submits $_FILES (so actual $_POST will be empty) + * this will be an xml file for the actuel response and optionally images and/or video + * proper responses are + * 201 received and stored + * 202 received ok, not stored + */ + public function submissionAction() + { + $this->makeRosaResponse(); + + if ($this->getRequest()->isHead()) { + $this->getResponse()->setHttpResponseCode(204); + } elseif ($this->getRequest()->isPost()) { + //Post + // We get $_FILES variable holding the formresults as xml and all possible + // attachments like photo's and video's + $upload = new Zend_File_Transfer_Adapter_Http(); + + // We should really add some validators here see http://framework.zend.com/manual/en/zend.file.transfer.validators.html + // Returns all known internal file information + $files = $upload->getFileInfo(); + + foreach ($files as $file => $info) { + // file uploaded ? + if (!$upload->isUploaded($file)) { + print "Why haven't you uploaded the file ?"; + continue; + } + + // validators are ok ? + if (!$upload->isValid($file)) { + print "Sorry but $file is not what we wanted"; + continue; + } + } + + //Dit moet een filter worden (rename filter) http://framework.zend.com/manual/en/zend.file.transfer.filters.html + $upload->setDestination($this->responseDir); + + //Hier moeten we denk ik eerst de xml_submission_file uitlezen, en daar + //iets mee doen + if ($upload->receive('xml_submission_file')) { + $xmlFile = $upload->getFileInfo('xml_submission_file'); + $answerXmlFile = $xmlFile['xml_submission_file']['tmp_name']; + $deviceId = $this->processReceivedForm($answerXmlFile); + if ($deviceId === false) { + //form not accepted! + foreach ($xml->children() as $child) { + $log->log($child->getName() . ' -> ' . $child, Zend_Log::ERR); + } + } else { + //$log->log(print_r($files, true), Zend_Log::ERR); + //$log->log($deviceId, Zend_Log::ERR); + foreach ($upload->getFileInfo() as $file => $info) { + if ($info['received'] != 1) { + //Rename to deviceid_md5(time)_filename + //@@TODO: move to form subdir, for better separation + $upload->addFilter('Rename', $deviceId . '_' . md5(time()) . '_' . $info['name'], $file); + } + } + + //Now receive the other files + if (!$upload->receive()) { + $messages = $upload->getMessages(); + echo implode("\n", $messages); + } + $this->getResponse()->setHttpResponseCode(201); //Form received ok + } + } + } + } +} \ No newline at end of file Modified: trunk/library/classes/Gems/Menu.php =================================================================== --- trunk/library/classes/Gems/Menu.php 2013-03-22 13:17:27 UTC (rev 1202) +++ trunk/library/classes/Gems/Menu.php 2013-03-22 14:02:16 UTC (rev 1203) @@ -224,6 +224,9 @@ $logMaint = $page->addPage($this->_('Maintenance'), 'pr.log.maintenance', 'log-maintenance'); $logMaint->addAutofilterAction(); $logMaint->addEditAction('pr.log.maintenance'); + + // OpenRosa + $this->addOpenRosaContainer($this->_('OpenRosa')); return $setup; } @@ -274,6 +277,26 @@ } } + + /** + * Shortcut function to add all items needed for OpenRosa + * + * Should be enabled in application.ini by using useOpenRosa = 1 + * + * @param string $label Label for the container + */ + public function addOpenRosaContainer($label) + { + if ($this->escort->getOption('useOpenRosa')) { + $page = $this->addBrowsePage($label, 'pr.openrosa','openrosa'); + $page->addButtonOnly($this->_('Scan FormDefs'), 'pr.openrosa.scan', 'openrosa', 'scan'); + $page->addButtonOnly($this->_('Scan Responses'), 'pr.openrosa.scan', 'openrosa', 'scanresponses'); + $this->addPage(null, null, 'openrosa', 'submission'); + $this->addPage(null, null, 'openrosa', 'formList'); //mind the capital L here + $this->addPage(null, null, 'openrosa', 'download'); + $this->addPage(null, null, 'openrosa', 'barcode'); // For barcode rendering + } + } /** * Shortcut function to create the respondent page. Modified: trunk/library/classes/Gems/Model.php =================================================================== --- trunk/library/classes/Gems/Model.php 2013-03-22 13:17:27 UTC (rev 1202) +++ trunk/library/classes/Gems/Model.php 2013-03-22 14:02:16 UTC (rev 1203) @@ -177,7 +177,21 @@ return $model; } + + /** + * Returns the OpenRosaFormModel + * + * It is special since it can show how many responses each table has + * + * @return OpenRosa_Model_OpenRosaFormModel + */ + public function getOpenRosaFormModel() + { + $model = $this->_loadClass('OpenRosaFormModel', true); + return $model; + } + /** * Load the organization model * Modified: trunk/library/classes/GemsEscort.php =================================================================== --- trunk/library/classes/GemsEscort.php 2013-03-22 13:17:27 UTC (rev 1202) +++ trunk/library/classes/GemsEscort.php 2013-03-22 14:02:16 UTC (rev 1203) @@ -430,6 +430,25 @@ return $locale; } + + /** + * Initialize the OpenRosa survey source + * + * @param Zend_Controller_Action $actionController + */ + public function _initOpenRosa(Zend_Controller_Action $actionController = null) + { + if ($this->getOption('useOpenRosa')) { + // First handle dependencies + $this->bootstrap(array('db', 'loader', 'util')); + + /** + * Add Source for OpenRosa + */ + $tracker = $this->loader->getTracker(); + $tracker->addSourceClasses(array('OpenRosa'=>'OpenRosa form')); + } + } /** Added: trunk/library/classes/OpenRosa/Model/OpenRosaFormModel.php =================================================================== --- trunk/library/classes/OpenRosa/Model/OpenRosaFormModel.php (rev 0) +++ trunk/library/classes/OpenRosa/Model/OpenRosaFormModel.php 2013-03-22 14:02:16 UTC (rev 1203) @@ -0,0 +1,96 @@ +<?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. + * + * Short description of file + * + * @package Gems + * @subpackage + * @copyright Copyright (c) 2011 Erasmus MC + * @license New BSD License + * @version $Id: Sample.php 215 2011-07-12 08:52:54Z michiel $ + */ + +/** + * Short description for OpenRosaFormModel + * + * Long description for class OpenRosaFormModel (if any)... + * + * @package Gems + * @subpackage Sample + * @copyright Copyright (c) 2011 Erasmus MC + * @license New BSD License + * @since Class available since version 1.0 + * @deprecated Class deprecated since version 2.0 + */ +class OpenRosa_Model_OpenRosaFormModel extends Gems_Model_JoinModel +{ + /** + * + * @var Zend_Translate_Adapter + */ + public $translate; + + public function __construct() + { + parent::__construct('orf', 'gems__openrosaforms', 'gof'); + } + + public function afterRegistry() + { + parent::afterRegistry(); + + $this->setIfExists('gof_form_id', 'label', $this->translate->_('FormID')); + $this->setIfExists('gof_form_version', 'label', $this->translate->_('Version')); + $this->setIfExists('gof_form_title', 'label', $this->translate->_('Name')); + $this->setIfExists('gof_form_active', 'label', $this->translate->_('Active'), 'elementClass', 'checkbox'); + } + + /** + * Get a select statement using a filter and sort + * + * Modified to add the information schema, only possible like this since + * the table has no primary key and can not be added using normal joins + * + * @param array $filter + * @param array $sort + * @return Zend_Db_Table_Select + */ + public function _createSelect($filter = null, $sort = null) + { + $select = parent::_createSelect($filter, $sort); + + $config = $select->getAdapter()->getConfig(); + if (isset($config['dbname'])) { + $constraint = $select->getAdapter()->quoteInto(' AND TABLE_SCHEMA=?', $config['dbname']); + } else { + $constraint = ''; + } + $select->joinLeft('INFORMATION_SCHEMA.TABLES', "table_name = convert(concat_ws('_','gems__orf_', REPLACE(gof_form_id,'.','_'),gof_form_version) USING utf8)" . $constraint, array('TABLE_ROWS')); + return $select; + } +} \ No newline at end of file Added: trunk/library/classes/OpenRosa/Tracker/Source/OpenRosa/Form.php =================================================================== --- trunk/library/classes/OpenRosa/Tracker/Source/OpenRosa/Form.php (rev 0) +++ trunk/library/classes/OpenRosa/Tracker/Source/OpenRosa/Form.php 2013-03-22 14:02:16 UTC (rev 1203) @@ -0,0 +1,497 @@ +<?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. + * + * Helper for OpenRosa forms + * + * It supports a subset of OpenRosa forms and provides a bridge between GemsTracker + * models and the xml-formdefinition. + * + * @package Gems + * @subpackage OpenRosa + * @copyright Copyright (c) 2011 Erasmus MC + * @license New BSD License + * @version $Id: Sample.php 215 2011-07-12 08:52:54Z michiel $ + */ + +/** + * Helper for OpenRosa forms + * + * It supports a subset of OpenRosa forms and provides a bridge between GemsTracker + * models and the xml-formdefinition. + * + * @package Gems + * @subpackage OpenRosa + * @copyright Copyright (c) 2011 Erasmus MC + * @license New BSD License + * @since Class available since version 1.0 + * @deprecated Class deprecated since version 2.0 + */ +class OpenRosa_Tracker_Source_OpenRosa_Form +{ + /** + * @var Gems_Model_JoinModel + */ + private $model; + private $bind; + private $instance; + private $body; + private $deviceIdField; + private $formID; + private $formVersion; + private $title; + + /** + * @var SimpleXmlElement + */ + private $_xml; + + /** + * Create an OpenRosaForm from an existing filename + * + * @param string $file the sanitized filename (absolute path) + */ + public function __construct($file) + { + $this->translate = Zend_Registry::getInstance()->get('Zend_Translate'); + if (!file_exists($file)) { + throw new Gems_Exception_Coding(sprintf($this->translate->_('File not found: %s'), $file)); + } + + //We read the xml file + $xml = simplexml_load_file($file); + if ($xml === false) { + throw new Gems_Exception_Coding(sprintf($this->translate->_('Could not read form definition for form %s'), $file)); + } + $this->_xml = $xml; + + //For working with the namespaces: + //$xml->children('h', true)->head->children()->model->bind + //use namespace h children for the root element, and find h:head, then use no namespace children + //and find model->bind so we get h:head/model/bind elements + $this->bind = $this->flattenBind($this->_xml->children('h', true)->head->children()->model->bind); + $this->body = $this->flattenBody($xml->children('h', true)->body->children(), $context = ''); + $this->instance = $this->flattenInstance($this->_xml->children('h', true)->head->children()->model->instance->data->children()); + } + + private function createTable() + { + $tableName = $this->getTableName(); + $tablePrefix = 'orf'; + $db = Zend_Registry::getInstance()->get('db'); + + $sql = 'CREATE TABLE IF NOT EXISTS ' . $db->quoteIdentifier($tableName) . ' (' + . $db->quoteIdentifier($tablePrefix . '_id') . " bigint(20) NOT NULL auto_increment,\n"; + + foreach ($this->instance as $name => $element) { + $bindName = str_replace('_', '/', '_data_' . $name); + $bindInfo = $this->bind[$bindName]; + + $field = array(); + switch ($bindInfo['type']) { + case 'date': + case 'dateTime': + $field['type'] = 'datetime'; + $field['size'] = ''; + break; + + case 'barcode': + // The token field + $field['size'] = 32; + $field['type'] = 'varchar'; + $field['size'] = '(' . $field['size'] . ')'; + + case 'string': + // Always make it text + $field['type'] = 'text'; + $field['size'] = ''; + break; + + case 'select': + //A multi select + $field['size'] = '(1)'; + $field['type'] = 'int'; + $items = $this->body[$bindName]['item']; + foreach ($items as $key => $value) { + $multiName = $name . '_' . $key; + $sql .= " " . $db->quoteIdentifier($multiName) . " {$field['type']}{$field['size']} DEFAULT 0 NOT NULL,\n"; + } + //So we don't get an extra field + unset($field['type']); + break; + + case 'select1': + //Select one, size can be as a small as largest answeroption + $items = $this->body[$bindName]['item']; + $field['size'] = 1; + foreach ($items as $key => $value) { + if (strlen($key) > $field['size']) { + $field['size'] = strlen($key); + } + } + $field['type'] = 'varchar'; + $field['size'] = '(' . $field['size'] . ')'; + break; + + case 'int': + $field['type'] = 'bigint'; + $field['size'] = '(20)'; + + case 'decimal': + $field['type'] = 'float'; + $field['size'] = ''; + + default: + $field['type'] = 'varchar'; + $field['size'] = 5; + $field['size'] = '(' . $field['size'] . ')'; + } + + if (isset($field['type'])) { + $sql .= " " . $db->quoteIdentifier($name) . " {$field['type']}{$field['size']} DEFAULT NULL,\n"; + } + } + + $sql .= $db->quoteIdentifier($tablePrefix . '_changed') . " timestamp NOT NULL,\n" + . $db->quoteIdentifier($tablePrefix . '_changed_by') . " bigint(20) NOT NULL,\n" + . $db->quoteIdentifier($tablePrefix . '_created') . " timestamp NOT NULL,\n" + . $db->quoteIdentifier($tablePrefix . '_created_by') . " bigint(20) NOT NULL,\n" + . 'PRIMARY KEY (`' . $tablePrefix . '_id`)) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;'; + + $db->query($sql); + + return new Gems_Model_JoinModel($this->getFormID(), $tableName, $tablePrefix); + } + + private function flattenBind($xml) + { + foreach ($xml as $name => $element) { + $attributes = array(); + foreach ($element->attributes() as $name => $value) { + $attributes[$name] = (string) $value; + if ($name == 'nodeset') { + $ref = (string) $value; + } + } + foreach ($element->attributes('jr', true) as $name => $value) { + $attributes['jr'] [$name] = (string) $value; + } + $output[$ref] = $attributes; + } + + return $output; + } + + /** + * Return flattend element + * + * @param SimpleXMLElement $xml + * @param type $context + */ + private function flattenBody($xml, $context = '') + { + foreach ($xml as $elementName => $element) { + //Check ref first + $elementContext = $context; + foreach ($element->attributes() as $name => $value) { + if ($name == 'ref') { + if (!empty($elementContext)) { + $elementContext .= '/'; + } else { + $elementContext = '/data/'; + } + if (substr($value, 0, 1) == '/') { + $elementContext = ''; + } + $elementContext .= $value; + break; + } + } + $result['context'] = $elementContext; + $result['name'] = $element->getName(); + + //elementName can be label, hint, or a sub element (group, input, select, select1 + switch ($elementName) { + case 'label': + $result['label'] = (string) $element; + break; + + case 'hint': + $result['hint'] = (string) $element; + break; + + case 'value': + $result['value'] = (string) $element; + break; + + case 'input': + case 'select': + case 'select1': + //has only value and label but repeated, add value/label pairs in array + $rawItem = $this->flattenBody($element, $elementContext); + $rawItem['context'] = $elementContext; + $rawItem['name'] = $element->getName(); + $result[$rawItem['context']] = $rawItem; + break; + + case 'item': + //has only value and label but repeated, add value/label pairs in array + $rawItem = $this->flattenBody($element->children(), $elementContext); + unset($rawItem['context']); + unset($rawItem['name']); + $result['item'][$rawItem['value']] = $rawItem['label']; + break; + + case 'group': + default: + unset($result['context']); + unset($result['name']); + $subarray = $this->flattenBody($element->children(), $elementContext); + unset($subarray['context']); + unset($subarray['label']); + unset($subarray['hint']); + unset($subarray['name']); + $result = $result + $subarray; + break; + } + } + + return $result; + } + + private function flattenInstance($xml, $parent = '') + { + $output = array(); + foreach ($xml as $name => $element) { + if (!empty($parent)) { + $elementName = $parent . '_' . $name; + } else { + $elementName = $name; + } + if (count($element->children()) > 0) { + $output = $output + $this->flattenInstance($element, $elementName); + } else { + $output[$elementName] = (string) $element; + } + } + return $output; + } + + /** + * Returns what field (path) contains the attributes jr:preload="property" jr:preloadParams="deviceid" + * from the moden -> bind elements + * + * @return string + */ + public function getDeviceIdField() + { + if (empty($this->deviceIdField)) { + foreach ($this->_xml->children('h', true)->head->children()->model->bind as $bind) { + if ($presets = $bind->attributes('jr', true)) { + foreach ($presets as $key => $value) { + if ($value == 'deviceid') { + $this->deviceIdField = $bind->attributes()->nodeset; + break; + } + } + } + } + } + + return $this->deviceIdField; + } + + /** + * Returns the formID from the instance element id attribute + * + * @return string + */ + public function getFormID() + { + if (empty($this->formID)) { + foreach ($this->_xml->children('h', true)->head->children()->model->instance->children() as $name => $element) { + if (!empty($element->attributes()->id)) { + $this->formID = $element->attributes()->id; + break; + } + } + } + + return $this->formID; + } + + /** + * Returns the formVersion from the instance element version attribute + * + * @return string + */ + public function getFormVersion() + { + if (empty($this->formVersion)) { + foreach ($this->_xml->children('h', true)->head->children()->model->instance->children() as $name => $element) { + if (!empty($element->attributes()->version)) { + $this->formVersion = $element->attributes()->version; + break; + } + } + } + + return $this->formVersion; + + } + + /** + * @return Gems_Model_JoinModel + */ + public function getModel() + { + if (empty($this->model)) { + try { + $model = new Gems_Model_JoinModel($this->getFormID(), $this->getTableName(), 'orf'); + } catch (Exception $exc) { + //Failed, now create the table as it obviously doesn't exists + $model = $this->createTable(); + } + + //Now we have the table, let's add some multi options etc. + $checkBox[1] = $this->translate->_('Checked'); + $checkbox[0] = $this->translate->_('Not checked'); + foreach ($this->instance as $name => $element) { + $bindName = str_replace('_', '/', '_data_' . $name); + $bindInfo = $this->bind[$bindName]; + + switch ($bindInfo['type']) { + case 'select': + //A multi select + $items = $this->body[$bindName]['item']; + foreach ($items as $key => $value) { + $multiName = $name . '_' . $key; + $label = sprintf('%s [%s]', $this->body[$bindName]['label'], $value); + $model->set($multiName, 'multiOptions', $checkBox, 'label', $label); + } + break; + + case 'select1': + $items = $this->body[$bindName]['item']; + $model->set($name, 'multiOptions', $items); + default: + $label = null; + if (array_key_exists($bindName, $this->body)) { + if (array_key_exists('label', $this->body[$bindName])) { + $label = $this->body[$bindName]['label']; + if (array_key_exists('hint', $this->body[$bindName])) { + $label = sprintf('%s (%s)', $label, $this->body[$bindName]['hint']); + } + $model->set($name, 'label', $label); + } + } + break; + } + } + $this->model = $model; + } + + return $this->model; + } + + public function getTableName() + { + $tableName = str_replace('.', '_', 'gems__orf__' . $this->getFormID() . '_' . $this->getFormVersion()); + + return $tableName; + } + + /** + * Returns the form title from the h:title element + * + * @return string + */ + public function getTitle() + { + if (empty($this->title)) { + $this->title = $this->_xml->children('h', true)->head->children('h', true)->title; + } + + return $this->title; + } + + public function saveAnswer($file, $remove = true) + { + if (!file_exists($file)) { + throw new Gems_Exception_Coding(sprintf($this->translate->_('File not found: %s'), $file)); + } + + //We read the xml file + $xml = simplexml_load_file($file); + if ($xml === false) { + throw new Gems_Exception_Coding(sprintf($this->translate->_('Could not read form definition for form %s'), $file)); + } + + $formId = (string) $xml->attributes()->id; + if ($formId != $this->getFormID()) { + //Can not save to this object as it is a different form! + throw new Gems_Exception_Coding(sprintf($this->translate->_('Response is for a different formId: %s <-> %s'), $formId, $this->getFormID())); + } + + $answers = $this->flattenInstance($xml); + //Now we should parse the response, extract the options given for a (multi)select + foreach ($this->instance as $name => $element) { + $bindName = str_replace('_', '/', '_data_' . $name); + $bindInfo = $this->bind[$bindName]; + + if ($bindInfo['type'] == 'dateTime') { + $answers[$name] = new Zend_Date($answers[$name], Zend_Date::ISO_8601); + } + if ($bindInfo['type'] == 'select') { + //A multi select + $items = explode(' ', $answers[$name]); + foreach ($items as $idx => $key) { + $multiName = $name . '_' . $key; + $answers[$multiName] = 1; + } + unset($answers[$name]); + } + } + + $answers['orf_id'] = null; + $model = $this->getModel(); + $answers = $model->save($answers); + if ($model->getChanged() && $remove) { + $log = Gems_Log::getLogger(); + $log->log($file . '-->' . substr($file, 0, -3) . 'bak', Zend_Log::ERR); + rename($file, substr($file, 0, -3) . 'bak'); + } + // @@TODO: make hook for respondentID lookup too + if (isset($answers['token'])) { + // We receveid a form linked to a token, signal the 'inSource' for this token. + $loader = GemsEscort::getInstance()->getLoader(); + $token = $loader->getTracker()->getToken($answers['token']); + $token->getUrl($loader->getCurrentUser()->getLocale(), $loader->getCurrentUser()->getUserId()); + } + + return $answers; + } +} \ No newline at end of file Added: trunk/library/classes/OpenRosa/Tracker/Source/OpenRosa/Model.php =================================================================== --- trunk/library/classes/OpenRosa/Tracker/Source/OpenRosa/Model.php (rev 0) +++ trunk/library/classes/OpenRosa/Tracker/Source/OpenRosa/Model.php 2013-03-22 14:02:16 UTC (rev 1203) @@ -0,0 +1,67 @@ +<?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 Zsd + * @subpackage Tracker + * @copyright Copyright (c) 2011 Erasmus MC + * @license New BSD License + * @version $Id: DbSourceSurveyModel.php 223 2011-12-19 09:48:15Z 175780 $ + */ + +/** + * More correctly a Survey ANSWERS Model as it adds answers to token information + * + * @package Zsd + * @subpackage Tracker + * @copyright Copyright (c) 2011 Erasmus MC + * @license New BSD License + * @since Class available since version 1.5 + */ +class OpenRosa_Tracker_Source_OpenRosa_Model extends Gems_Tracker_SurveyModel +{ + public function addAnswers(array $inputRows) + { + $tokens = MUtil_Ra::column('gto_id_token', $inputRows); + + $answerRows = $this->source->getRawTokenAnswerRows(array('token' => $tokens), $this->survey->getSurveyId()); + $emptyRow = array_fill_keys($this->getItemNames(), null); + $resultRows = array(); + + $answerTokens = MUtil_Ra::column('token', $answerRows); + + foreach ($inputRows as $row) { + $tokenId = $row['gto_id_token']; + $idx = array_search($tokenId, $answerTokens); + if ($idx !== false && isset($answerRows[$idx])) { + $resultRows[$tokenId] = $row + $answerRows[$idx] + $emptyRow; + } else { + $resultRows[$tokenId] = $row + $emptyRow; + } + } + return $resultRows; + } +} \ No newline at end of file Added: trunk/library/classes/OpenRosa/Tracker/Source/OpenRosa.php =================================================================== --- trunk/library/classes/OpenRosa/Tracker/Source/OpenRosa.php (rev 0) +++ trunk/library/classes/OpenRosa/Tracker/Source/OpenRosa.php 2013-03-22 14:02:16 UTC (rev 1203) @@ -0,0 +1,302 @@ +<?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. + * + * Short description of file + * + * @package Gems + * @subpackage + * @copyright Copyright (c) 2011 Erasmus MC + * @license New BSD License + * @version $Id: Sample.php 215 2011-07-12 08:52:54Z michiel $ + */ + +/** + * Short description for OpenRosaSource + * + * Long description for class OpenRosaSource (if any)... + * + * @package Gems + * @subpackage Sample + * @copyright Copyright (c) 2011 Erasmus MC + * @license New BSD License + * @since Class available since version 1.0 + * @deprecated Class deprecated since version 2.0 + */ +class OpenRosa_Tracker_Source_OpenRosa extends Gems_Tracker_Source_SourceAbstract +{ + /** + * This holds the path to the location where the form definitions will be stored. + * Will be set on init to: GEMS_ROOT_DIR . '/var/uploads/openrosa/forms/'; + * + * @var string + */ + public $formDir; + + public function __construct(array $sourceData, Zend_Db_Adapter_Abstract $gemsDb) + { + parent::__construct($sourceData, $gemsDb); + $this->formDir = GEMS_ROOT_DIR . '/var/uploads/openrosa/forms/'; + } + + /** + * Returns the source surveyId for a given Gems survey Id + * + * @param type $surveyId + * @return type + */ + private function _getSid($surveyId) + { + return $this->tracker->getSurvey($surveyId)->getSourceSurveyId(); + } + + //put your code here + public function checkSourceActive($userId) + { + $active = true; + + $values['gso_active'] = $active ? 1 : 0; + $values['gso_status'] = $active ? 'Active' : 'Inactive'; + $values['gso_last_synch'] = new Zend_Db_Expr('CURRENT_TIMESTAMP'); + + $this->_updateSource($values, $userId); + + return $active; + } + + public function copyTokenToSource(Gems_Tracker_Token $token, $language, $surveyId, $sourceSurveyId = null) + { + // Maybe insert meta data here? + } + + public function getAnswerDateTime($fieldName, Gems_Tracker_Token $token, $surveyId, $sourceSurveyId = null) + { + + } + + public function getCompletionTime(Gems_Tracker_Token $token, $surveyId, $sourceSurveyId = null) + { + + } + + public function getDatesList($language, $surveyId, $sourceSurveyId = null) + { + + } + + public function getQuestionInformation($language, $surveyId, $sourceSurveyId = null) + { + $survey = $this->getSurvey($surveyId, $sourceSurveyId); + $model = $survey->getModel(); + $result = array(); + + foreach($model->getItemsOrdered() as $name) { + if ($label = $model->get($name, 'label')) { + $result[$name]['question'] = $label; + if ($answers = $model->get($name, 'multiOptions')) { + $result[$name]['answers'] = $answers; + } + } + } + + return $result; + } + + public function getQuestionList($language, $surveyId, $sourceSurveyId = null) + { + $survey = $this->getSurvey($surveyId, $sourceSurveyId); + $model = $survey->getModel(); + $result = array(); + + foreach($model->getItemsOrdered() as $name) { + if ($label = $model->get($name, 'label')) { + $result[$name] = $label; + } + } + + return $result; + } + + public function getRawTokenAnswerRow($tokenId, $surveyId, $sourceSurveyId = null) + { + $survey = $this->getSurvey($surveyId, $sourceSurveyId); + $model = $survey->getModel(); + + $result = $model->loadFirst(array('token' => $tokenId)); + return $result; + } + + public function getRawTokenAnswerRows(array $filter, $surveyId, $sourceSurveyId = null) + { + $survey = $this->getSurvey($surveyId, $sourceSurveyId); + $model = $survey->getModel(); + + $result = $model->load(); + + if ($result) { + return $result; + } + return array(); + } + + public function getStartTime(Gems_Tracker_Token $token, $surveyId, $sourceSurveyId = null) + { + + } + + public function getSurvey($surveyId, $sourceSurveyId = null) + { + if (is_null($sourceSurveyId)) { + $sourceSurveyId = $this->_getSid($surveyId); + } + + $surveyInfo = $this->getSurveyInfo($sourceSurveyId); + $survey = new OpenRosa_Tracker_Source_OpenRosa_Form($this->formDir . $surveyInfo['gof_form_xml']); + + return $survey; + } + + /** + * Return info about the survey (row from gems__openrosaforms) + * + * @param int $sourceSurveyId + * @return array + */ + public function getSurveyInfo($sourceSurveyId) + { + $db = $this->getSourceDatabase(); + + $select = $db->select(); + $select->from('gems__openrosaforms') + ->where('gof_id = ?', $sourceSurveyId); + + return $db->fetchRow($select); + } + + public function getSurveyAnswerModel(Gems_Tracker_Survey $survey, $language = null, $sourceSurveyId = null) + { + if (null === $sourceSurveyId) { + $sourceSurveyId = $this->_getSid($survey->getSurveyId()); + } + + $surveyModel = $this->getSurvey($survey->getSurveyId(), $sourceSurveyId)->getModel(); + $model = new OpenRosa_Tracker_Source_OpenRosa_Model($survey, $this); + $questionsList = $this->getQuestionList($language, $survey->getSurveyId(), $sourceSurveyId); + foreach($questionsList as $item => $question) { + $allOptions = $surveyModel->get($item); + $allowed = array_fill_keys(array('storageFormat', 'dateFormat', 'label', 'multiOptions', 'maxlength', 'type'),1); + $options = array_intersect_key($allOptions, $allowed); + + $options['label'] = strip_tags($question); + + //Should also do something to get the better titles... + $model->set($item, $options); + } + + return $model; + } + + public function getTokenUrl(Gems_Tracker_Token $token, $language, $surveyId, $sourceSurveyId) + { + // There is no url, so return null + return; + } + + public function inSource(Gems_Tracker_Token $token, $surveyId, $sourceSurveyId = null) + { + // The token is always in source + return true; + } + + public function isCompleted(Gems_Tracker_Token $token, $surveyId, $sourceSurveyId = null) + { + $result = $this->getRawTokenAnswerRow($token->getTokenId(), $surveyId); + $completed = !empty($result); + + return $completed; + } + + public function setRawTokenAnswers(Gems_Tracker_Token $token, array $answers, $surveyId, $sourceSurveyId = null) + { + + } + + public function synchronizeSurveys($userId) + { + // Surveys in LS + $db = $this->getSourceDatabase(); + + $select = $db->select(); + $select->from('gems__openrosaforms'); + + $openRosaSurveys = $db->fetchAssoc($select); + + if (!$openRosaSurveys) { + //If no surveys present, just use an empty array as array_combine fails + $openRosaSurveys = array(); + } else { + $openRosaSurveyIds = array_combine(array_keys($openRosaSurveys), array_keys($openRosaSurveys)); + } + + // Surveys in Gems + $gemsSurveys = $this->_getGemsSurveysForSynchronisation(); + + foreach ($gemsSurveys as $surveyId => $sourceSurveyId) { + $survey = $this->tracker->getSurveyBySourceId($sourceSurveyId, $this->getId()); + if (isset($openRosaSurveyIds[$sourceSurveyId])) { + // Exists + $values['gsu_survey_name'] = $openRosaSurveys[$sourceSurveyId]['gof_form_title'] . ' [' . $openRosaSurveys[$sourceSurveyId]['gof_form_version'] . ']'; + $values['gsu_surveyor_active'] = $openRosaSurveys[$sourceSurveyId]['gof_form_active']; + $values['gsu_status'] = 'Ok'; + } else { + // No longer exists + $values['gsu_surveyor_active'] = 0; + $values['gsu_status'] = 'No longer exists'; + } + + $survey->saveSurvey($values, $userId); + } + + foreach (array_diff($openRosaSurveyIds, $gemsSurveys) as $sourceSurveyId) { + // New survey + $values = array(); + $values['gsu_survey_name'] = $openRosaSurveys[$sourceSurveyId]['gof_form_title'] . ' [' . $openRosaSurveys[$sourceSurveyId]['gof_form_version'] . ']'; + $values['gsu_surveyor_active'] = $openRosaSurveys[$sourceSurveyId]['gof_form_active']; + $values['gsu_active'] = 0; + $values['gsu_status'] = ''; + + $survey = $this->tracker->getSurveyBySourceId($sourceSurveyId, $this->getId()); + $survey->exists = false; + $survey->saveSurvey($values, $userId); + } + } + + public function updateConsent(Gems_Tracker_Token $token, $surveyId, $sourceSurveyId = null, $consentCode = null) + { + + } +} \ No newline at end of file Added: trunk/library/controllers/OpenrosaController.php =================================================================== --- trunk/library/controllers/OpenrosaController.php (rev 0) +++ trunk/library/controllers/OpenrosaController.php 2013-03-22 14:02:16 UTC (rev 1203) @@ -0,0 +1,49 @@ +<?php + +/** + * Copyright (c) 2012, 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 WA... [truncated message content] |
From: <gem...@li...> - 2013-04-18 14:52:04
|
Revision: 1238 http://sourceforge.net/p/gemstracker/code/1238 Author: matijsdejong Date: 2013-04-18 14:51:58 +0000 (Thu, 18 Apr 2013) Log Message: ----------- Fixed array index warning Text corrections on index.php Restored project.ini Modified Paths: -------------- trunk/library/classes/GemsEscort.php trunk/new_project/htdocs/index.php Added Paths: ----------- trunk/new_project/application/configs/project.ini Modified: trunk/library/classes/GemsEscort.php =================================================================== --- trunk/library/classes/GemsEscort.php 2013-04-17 16:29:37 UTC (rev 1237) +++ trunk/library/classes/GemsEscort.php 2013-04-18 14:51:58 UTC (rev 1238) @@ -638,8 +638,9 @@ protected function _initZFDebug() { if ((APPLICATION_ENV === 'production') || + (! isset($_SERVER['HTTP_USER_AGENT'])) || (false !== strpos($_SERVER['HTTP_USER_AGENT'], 'MSIE 6.'))) { - // Never on on production systems, never for IE 6 + // Never on on production systems, never on command line, never for IE 6 return; } Added: trunk/new_project/application/configs/project.ini =================================================================== --- trunk/new_project/application/configs/project.ini (rev 0) +++ trunk/new_project/application/configs/project.ini 2013-04-18 14:51:58 UTC (rev 1238) @@ -0,0 +1,350 @@ +[production] +name = GEMS_PROJECT_NAME_UC +description = GEMS_PROJECT_NAME_UC +;longDescr = "" +;longDescrNl = "" + +;--------------------------------------------------- +; Hash encryption salt. REQUIRED! +; +; Use e.g. http://www.random.org/strings/ to create. +; +; Put %s somewhere within the salt to mix the value +; in the salt. +;--------------------------------------------------- +salt = + +;---------------------------------------------------------- +; The non database super user +; +; On production pwd should be empty or longer than 10 chars +; and quoted if it contains special characters. +;---------------------------------------------------------- +admin.user = superadmin +admin.pwd = PASSWD +;admin.ipRanges = 10.0.0.0-10.255.255.255;192.168.0.0-192.168.255.255 + +css.gems = gems/css/gems-fluid.css +css.print.url = gems/css/gems_print.css +css.print.media = print +imagedir = gems/images +imagedir = gems/images +css.local = basic/basic.css +favicon = basic/basic.ico +jquerycss = basic/jquery-basic.css + +contact.bugsUrl = http://gemstracker.org/mantis +contact.docsUrl = http://gemstracker.org/wiki/doku.php +;contact.forumUrl = http://gemstracker.org/wiki/doku.php +contact.gemsUrl = http://gemstracker.org/ +contact.manualUrl = "http://gemstracker.org/wiki/doku.php?id=userzone:userdoc:start" +;contact.supportUrl = http://gemstracker.org/wiki/doku.php + +databaseFileEncoding = ISO-8859-1 + +;------------------------------------------------------- +; SESSION SECTION +; +; idleTimeout +; +; Lifetime of the session (determines the expiration of +; the session namespace(s)). +; If not set, defaults to 1800 seconds = 30 minutes. +; +;------------------------------------------------------- + +session.idleTimeout = 1800 + +;------------------------------------------------------- +; ASK THROTTLE SECTION +; +; Sets values that control the throttling (slowdowns to +; combat brute-force attacks) of the ask / token +; controller. +; +; askThrottle.period +; +; Look for failed token attempts in from now to +; X seconds ago. +; +; askThrottle.threshold +; +; If the number of failed token attempts exceeds this +; number, starting throttling. +; +; askThrottle.delay +; +; Throttle by delaying each request by X seconds. +; +;------------------------------------------------------- + +askThrottle.period = 900 +askThrottle.threshold = 300 +askThrottle.delay = 10 + +;------------------------------------------------------- +; ASK DELAY SECTION +; +; askDelay +; +; When no askDelay is specified or is -1 the user will see +; greeting screen were he or she will a have to click +; on a button to fill in a survey. +; +; With the askDelay is > 0 then greeting screen will +; be shown (with the button) but after the specified +; number of seconds the survey will load automatically. +; +; With an askDelay of 0 seconds the survey will load +; automatically. +; +; askNextDelay +; +; askNextDelay works the same but applies to the wait +; after the user completed a survey while another survey +; is available. +;------------------------------------------------------- + +; askDelay = 10 +; askNextDelay = 0 + +;------------------------------------------------------- +; E-MAIL SECTION +; +; USE +; +; Here you can set three global e-mail settings: +; +; bcc = BCC every sent mail to this address. +; block = Block any sending of mail. +; bounce = When set to 1 all mails are not sent to the +; suplied TO address, but redirects them to +; the FROM not respondent address. This allows +; testing without altering respondent e-mail +; addresses. +; site = Supply a general site FROM address. +;------------------------------------------------------- + +; email.bcc = +email.block = 0 +email.bounce = 0 +; email.site = + +;------------------------------------------------------- +; LAYOUT SECTION +; +; USE +; +; For each layout item with a value other than 0 there +; must exist a _layout{Item}() method in GemsEscort or +; the {Project}Escort.php class specified in +; {Project}Application.ini file. +; +; Items are loaded in the order specified below. Order +; may be important, e.g. navigation should be called +; before crumbs. +; +; INPUT +; +; This method is called with layoutPrepareArgs.{Item} +; in an array. +; +; Both layoutPrepare and layoutPrepareArgs can be +; changed at runtime before GemsEscort.postDispatch() +; is called. +; +; OUTPUT: +; +; The result (if any) is stored as a $view property. +; When the item value is a number, the name will be +; the item name. +; When the item value is a string, then it is stored +; in a MUtil_Html_Sequence view property with that +; string as name. The sequence is created on demand. +;------------------------------------------------------- + +layoutPrepare.title = 1 +layoutPrepare.projectName = header +layoutPrepare.login = header_bar +layoutPrepare.contact = 0 +layoutPrepare.localeSet = header_bar +layoutPrepare.organizationSwitcher = header_bar +layoutPrepare.version = footer +layoutPrepare.user = footer +layoutPrepare.time = 0 +layoutPrepare.menuHtml = 1 +layoutPrepare.navigation = 0 +layoutPrepare.crumbs = main +layoutPrepare.messages = main +layoutPrepare.css = 1 +layoutPrepare.favicon = 1 +layoutPrepare.dojo = 0 +layoutPrepare.jQuery = 1 + +layoutPrepareArgs.login.class = rightFloat +;layoutPrepareArgs.contact.class = rightFloat +layoutPrepareArgs.time.class = rightFloat +layoutPrepareArgs.user.class = rightFloat +layoutPrepareArgs.version.class = leftFloat +layoutPrepareArgs.localeSet.class = leftFloat + +;------------------------------------------------------- +; LOCALE SECTION +; +; Specify a default locale and locales for each of the +; supported languages. +;------------------------------------------------------- + +locale.default = "en" +locales.en = "en" +locales.nl = "nl" + +;------------------------------------------------------- +; ORGANIZATION SECTION +; +; Specify a default organization for a project. Allows +; all user to login when this organization is choosen. +;------------------------------------------------------- + +; organization.default = 70 + +;---------------------------------------------------------------------- +; PASSWORD SECTION +; +; Allows default setting of initial password for new users: +; password.firstPassword = sesame +;---------------------------------------------------------------------- + +;password.initialPassword = sesame + +;---------------------------------------------------------------------- +; PASSWORDS SECTION +; +; The last key must be a function name in your PasswordChecker class. +; That function must accept as parameters the array value and the +; password. +; +; In between keys can contain case insensitive organization codes, user +; roles and user definition names in any order and can overrule previous +; defined values. +; BEWARE keep keys in fixed array order: +; passwords.staff.mgz.capsCount = 1 +; passwords.mgz.staff.lowerCount = 1 +; passwords.staff.mgz.lowerCount = 2 +; will be processed as: +; passwords.staff.mgz.capsCount = 1 +; passwords.staff.mgz.lowerCount = 2 +; passwords.mgz.staff.lowerCount = 1 +;---------------------------------------------------------------------- + +passwords.notTheName = 1 +passwords.guest.minLength = 6 +passwords.staff.capsCount = 1 +passwords.staff.lowerCount = 1 +passwords.staff.minLength = 8 +passwords.staff.numCount = 0 +passwords.staff.notAlphaCount = 1 +passwords.staff.notAlphaNumCount = 0 + +;------------------------------------------------------- +; TOKEN SECTION +; +; chars: characters allowed in a token. +; format: format string to show to user for input of +; token. The \ backslash is used as escape +; character for characters that are fixed. +; from: commonly mistaken input characters to correct. +; to: characters to translate from characters to. +; case: optional: 1|0. If the token should be +; treated case sensitive. If missing the token +; is case sensitive when chars contains +; uppercase characters. +; reuse: days tokens can be used: +; -1 = not at all +; 0 = only today (default and required for looping) +; 1 = only up to yesterdays tokens +;------------------------------------------------------- + +tokens.chars = 23456789abcdefghijklmnopqrstuvwxyz +tokens.format = XXXX\-XXXX; +tokens.from = 01; +tokens.to = ol; + +;--------------------------------------------------------- +; CONSENT SECTION +;--------------------------------------------------------- +consentRejected = 'do not use' +consentTypes = 'do not use|consent given' +consentDefault = 'Unknown' ;Default setup makes this 'do not use' + +;--------------------------------------------------------- +; LOGLEVEL SECTION +;--------------------------------------------------------- +; Use the loglevels as defined in Zend_Log to define the highest level of errors to log +; +; 0 Emergency: system is unusable +; 1 Alert: action must be taken immediately +; 2 Critical: critical conditions +; 3 Error: error conditions +; 4 Warning: warning conditions +; 5 Notice: normal but significant condition +; 6 Informational: informational messages +; 7 Debug: debug messages +; +; Defaults for production are 3 (error) and 7 (debug) for testing and development, uncomment the +; line below to use a custom setting +;logLevel = 6; + +;--------------------------------------------------------- +; EXPORT SECTION +;--------------------------------------------------------- +; Command line to the pdf export binary (such as +; wkhtmltopdf, Phantom.js or similar) +; +; Use as follows: +; export.pdfExportCommand = '/bin/wkhtmltopdf %s %s' +; +; where %s %s is respecitively the input (url) and +; the output (file) +export.pdfExportCommand = + +;--------------------------------------------------------- +; PERFORMANCE +; Define what kind of cache to use. Choose from: +; apc (shared) memory cache, can sometimes be slow due to limited available +; memory in shared environments +; file When filesystem is fast enough or apc is not available +; none No cache - good for development +;--------------------------------------------------------- +cache = "apc" + +[testing : production] +cache = "file" +admin.user = superadmin +admin.pwd = superadmin + +email.bounce = 1 + +passwords.notTheName = 0 +passwords.staff.minLength = 6 + +[demo : production] +admin.user = superadmin +admin.pwd = superadmin + +email.bounce = 1 + +[development : production] +cache = "none" +admin.user = superadmin +admin.pwd = superadmin + +email.bounce = 1 + +passwords.notTheName = 0 +passwords.staff.capsCount = 0 +passwords.staff.lowerCount = 0 +passwords.staff.minLength = 6 +passwords.staff.numCount = 0 +passwords.staff.notAlphaCount = 0 +passwords.staff.notAlphaNumCount = 0 Modified: trunk/new_project/htdocs/index.php =================================================================== --- trunk/new_project/htdocs/index.php 2013-04-17 16:29:37 UTC (rev 1237) +++ trunk/new_project/htdocs/index.php 2013-04-18 14:51:58 UTC (rev 1238) @@ -30,14 +30,14 @@ /** * Project root file * - * Gemms specific startup + * Gems specific startup * - Defines GEMS project constants using Erasmus MC directory setup. * - Loads database login data. * - Goto pre_bootstrap.php * * @author Matijs de Jong <mj...@ma...> * @since 1.0 - * @version 0.9 + * @version 1.6 * @package Gems * @subpackage boot */ This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |