diff --git a/lib/Alchemy/Phrasea/Application/Api.php b/lib/Alchemy/Phrasea/Application/Api.php index 06160932b9..55c33d3cd3 100644 --- a/lib/Alchemy/Phrasea/Application/Api.php +++ b/lib/Alchemy/Phrasea/Application/Api.php @@ -66,4 +66,4 @@ return call_user_func(function ($environment = PhraseaApplication::ENV_PROD) { $app['dispatcher']->dispatch(PhraseaEvents::API_LOAD_END, new ApiLoadEndEvent()); return $app; -}, isset($environment) ? $environment : null); +}, isset($environment) ? $environment : PhraseaApplication::ENV_PROD); diff --git a/lib/Alchemy/Phrasea/Application/Root.php b/lib/Alchemy/Phrasea/Application/Root.php index 2a973fc148..e6470185d9 100644 --- a/lib/Alchemy/Phrasea/Application/Root.php +++ b/lib/Alchemy/Phrasea/Application/Root.php @@ -68,4 +68,4 @@ return call_user_func(function ($environment = PhraseaApplication::ENV_PROD) { ); return $app; -}, isset($environment) ? $environment : null); +}, isset($environment) ? $environment : PhraseaApplication::ENV_PROD); diff --git a/lib/Alchemy/Phrasea/Authentication/Authenticator.php b/lib/Alchemy/Phrasea/Authentication/Authenticator.php index 4b532eca79..7752ce2cd8 100644 --- a/lib/Alchemy/Phrasea/Authentication/Authenticator.php +++ b/lib/Alchemy/Phrasea/Authentication/Authenticator.php @@ -149,6 +149,19 @@ class Authenticator */ public function isAuthenticated() { - return $this->session->has('usr_id'); + if (!$this->session->has('usr_id')) { + return false; + } + + if ($this->session->has('session_id')) { + if (null !== $this->em->find('Alchemy\Phrasea\Model\Entities\Session', $this->session->get('session_id'))) { + return true; + } + } + + $this->session->invalidate(); + $this->reinitUser(); + + return false; } } diff --git a/lib/Alchemy/Phrasea/Cache/Factory.php b/lib/Alchemy/Phrasea/Cache/Factory.php index bbebbd04ea..8e1437880e 100644 --- a/lib/Alchemy/Phrasea/Cache/Factory.php +++ b/lib/Alchemy/Phrasea/Cache/Factory.php @@ -45,6 +45,10 @@ class Factory case 'memcachecache': $cache = $this->createMemcache($options); break; + case 'memcached': + case 'memcachecached': + $cache = $this->createMemcached($options); + break; case 'redis': case 'rediscache': $cache = $this->createRedis($options); @@ -131,6 +135,29 @@ class Factory return $cache; } + private function createMemcached($options) + { + if (!extension_loaded('memcached')) { + throw new RuntimeException('The Memcached cache requires the Memcached extension.'); + } + + $host = isset($options['host']) ? $options['host'] : 'localhost'; + $port = isset($options['port']) ? $options['port'] : 11211; + + $memcached = new \Memcached(); + $memcached->addServer($host, $port); + $memcached->getStats(); + + if (\Memcached::RES_SUCCESS !== $memcached->getResultCode()) { + throw new RuntimeException(sprintf("Memcached instance with host '%s' and port '%s' is not reachable", $host, $port)); + } + + $cache = new MemcachedCache(); + $cache->setMemcached($memcached); + + return $cache; + } + private function createApc($options) { if (!extension_loaded('apc')) { diff --git a/lib/Alchemy/Phrasea/Setup/Installer.php b/lib/Alchemy/Phrasea/Setup/Installer.php index 17a2b29c56..bdd7e86366 100644 --- a/lib/Alchemy/Phrasea/Setup/Installer.php +++ b/lib/Alchemy/Phrasea/Setup/Installer.php @@ -113,8 +113,7 @@ class Installer private function createUser($email, $password) { $user = \User_Adapter::create($this->app, $email, $password, $email, true); - - $this->app['session']->set('usr_id', $user->get_id()); + $this->app['authentication']->openAccount($user); return $user; } diff --git a/lib/classes/databox/field.php b/lib/classes/databox/field.php index 6774be8752..6fe166d92b 100644 --- a/lib/classes/databox/field.php +++ b/lib/classes/databox/field.php @@ -235,6 +235,8 @@ class databox_field implements cache_cacheableInterface $this->thumbtitle = $row['thumbtitle']; + $this->loadVocabulary(); + return $this; } diff --git a/templates/web/prod/actions/Bridge/Dailymotion/actioncontainers.html.twig b/templates/web/prod/actions/Bridge/Dailymotion/actioncontainers.html.twig index 0fc7e8dd8d..4abf04be54 100644 --- a/templates/web/prod/actions/Bridge/Dailymotion/actioncontainers.html.twig +++ b/templates/web/prod/actions/Bridge/Dailymotion/actioncontainers.html.twig @@ -1,8 +1,8 @@
- +
diff --git a/templates/web/prod/actions/Bridge/Flickr/actioncontainers.html.twig b/templates/web/prod/actions/Bridge/Flickr/actioncontainers.html.twig index f597e039c3..4abf04be54 100644 --- a/templates/web/prod/actions/Bridge/Flickr/actioncontainers.html.twig +++ b/templates/web/prod/actions/Bridge/Flickr/actioncontainers.html.twig @@ -1,8 +1,8 @@
- +
diff --git a/templates/web/prod/actions/Bridge/Youtube/actioncontainers.html.twig b/templates/web/prod/actions/Bridge/Youtube/actioncontainers.html.twig index 0fc7e8dd8d..4abf04be54 100644 --- a/templates/web/prod/actions/Bridge/Youtube/actioncontainers.html.twig +++ b/templates/web/prod/actions/Bridge/Youtube/actioncontainers.html.twig @@ -1,8 +1,8 @@
- +
diff --git a/templates/web/setup/wrapper.html.twig b/templates/web/setup/wrapper.html.twig index 94752f2fd0..4f7d0a2de0 100644 --- a/templates/web/setup/wrapper.html.twig +++ b/templates/web/setup/wrapper.html.twig @@ -2,7 +2,7 @@ "http://www.w3.org/TR/html4/strict.dtd"> - + diff --git a/tests/Alchemy/Tests/Phrasea/Authentication/AuthenticatorTest.php b/tests/Alchemy/Tests/Phrasea/Authentication/AuthenticatorTest.php index ae2f2eb530..d3135e360d 100644 --- a/tests/Alchemy/Tests/Phrasea/Authentication/AuthenticatorTest.php +++ b/tests/Alchemy/Tests/Phrasea/Authentication/AuthenticatorTest.php @@ -5,6 +5,7 @@ namespace Alchemy\Tests\Phrasea\Authentication; use Alchemy\Phrasea\Application; use Alchemy\Phrasea\Authentication\Authenticator; use Alchemy\Phrasea\Exception\RuntimeException; +use Alchemy\Phrasea\Model\Entities\Session; class AuthenticatorTest extends \PhraseanetPHPUnitAbstract { @@ -33,11 +34,17 @@ class AuthenticatorTest extends \PhraseanetPHPUnitAbstract $app['browser'] = $browser = $this->getBrowserMock(); $app['session'] = $session = $this->getSessionMock(); - $app['EM'] = $em = $this->getEntityManagerMock(); + + $sessionEntity = new Session(); + $sessionEntity->setUsrId($user->get_id()); + $sessionEntity->setUserAgent(''); + $app['EM']->persist($sessionEntity); + $app['EM']->flush(); $session->set('usr_id', $user->get_id()); + $session->set('session_id', $sessionEntity->getId()); - $authenticator = new Authenticator($app, $browser, $session, $em); + $authenticator = new Authenticator($app, $browser, $session, $app['EM']); $this->assertEquals($user, $authenticator->getUser()); } @@ -69,8 +76,7 @@ class AuthenticatorTest extends \PhraseanetPHPUnitAbstract public function testOpenAccount() { $app = new Application(); - - $sessionId = 2442; + $capturedSession = null; $app['browser'] = $browser = $this->getBrowserMock(); $app['session'] = $session = $this->getSessionMock(); @@ -97,11 +103,8 @@ class AuthenticatorTest extends \PhraseanetPHPUnitAbstract $em->expects($this->at(0)) ->method('persist') ->with($this->isInstanceOf('Alchemy\Phrasea\Model\Entities\Session')) - ->will($this->returnCallback(function ($session) use ($sessionId) { - $ref = new \ReflectionObject($session); - $prop = $ref->getProperty('id'); - $prop->setAccessible(true); - $prop->setValue($session, $sessionId); + ->will($this->returnCallback(function ($session) use (&$capturedSession) { + $capturedSession = $session; })); $em->expects($this->at(1)) ->method('flush'); @@ -110,7 +113,7 @@ class AuthenticatorTest extends \PhraseanetPHPUnitAbstract $phsession = $authenticator->openAccount($user); $this->assertInstanceOf('Alchemy\Phrasea\Model\Entities\Session', $phsession); - $this->assertEquals($sessionId, $session->get('session_id')); + $this->assertEquals($capturedSession, $phsession); } /** @@ -129,7 +132,7 @@ class AuthenticatorTest extends \PhraseanetPHPUnitAbstract $usrId = $user->get_id(); $sessionId = 4224242; - $session = new \Alchemy\Phrasea\Model\Entities\Session(); + $session = new Session(); $session->setUsrId($usrId); $ref = new \ReflectionObject($session); @@ -171,7 +174,7 @@ class AuthenticatorTest extends \PhraseanetPHPUnitAbstract $usrId = $user->get_id(); $sessionId = 4224242; - $session = new \Alchemy\Phrasea\Model\Entities\Session(); + $session = new Session(); $session->setUsrId($usrId); $ref = new \ReflectionObject($session); @@ -237,11 +240,17 @@ class AuthenticatorTest extends \PhraseanetPHPUnitAbstract $app['browser'] = $browser = $this->getBrowserMock(); $app['session'] = $session = $this->getSessionMock(); - $app['EM'] = $em = $this->getEntityManagerMock(); + + $sessionEntity = new Session(); + $sessionEntity->setUsrId($user->get_id()); + $sessionEntity->setUserAgent(''); + $app['EM']->persist($sessionEntity); + $app['EM']->flush(); $session->set('usr_id', $user->get_id()); + $session->set('session_id', $sessionEntity->getId()); - $authenticator = new Authenticator($app, $browser, $session, $em); + $authenticator = new Authenticator($app, $browser, $session, $app['EM']); $this->assertTrue($authenticator->isAuthenticated()); } diff --git a/tests/Alchemy/Tests/Phrasea/Cache/FactoryTest.php b/tests/Alchemy/Tests/Phrasea/Cache/FactoryTest.php index 93fd5bb108..cabe7fae2f 100644 --- a/tests/Alchemy/Tests/Phrasea/Cache/FactoryTest.php +++ b/tests/Alchemy/Tests/Phrasea/Cache/FactoryTest.php @@ -28,6 +28,8 @@ class FactoryTest extends \PHPUnit_Framework_TestCase array('arraycache', null, 'Alchemy\Phrasea\Cache\ArrayCache'), array('memcache', 'memcache', 'Alchemy\Phrasea\Cache\MemcacheCache'), array('memcachecache', 'memcache', 'Alchemy\Phrasea\Cache\MemcacheCache'), + array('memcached', 'memcached', 'Alchemy\Phrasea\Cache\MemcachedCache'), + array('memcachecached', 'memcached', 'Alchemy\Phrasea\Cache\MemcachedCache'), array('redis', 'redis', 'Alchemy\Phrasea\Cache\RedisCache'), array('rediscache', 'redis', 'Alchemy\Phrasea\Cache\RedisCache'), array('wincache', 'wincache', 'Alchemy\Phrasea\Cache\WincacheCache'), diff --git a/tests/classes/record/adapterTest.php b/tests/classes/record/adapterTest.php index 5e8f066712..c111e36d97 100644 --- a/tests/classes/record/adapterTest.php +++ b/tests/classes/record/adapterTest.php @@ -198,10 +198,6 @@ class record_adapterTest extends PhraseanetPHPUnitAuthenticatedAbstract public function testGet_rollover_thumbnail() { - if (!extension_loaded('\Gmagick')) { - $this->markTestSkipped('\Gmagick required to build animated gifs'); - } - $this->assertNull(self::$DI['record_1']->get_rollover_thumbnail()); } diff --git a/www/api.php b/www/api.php index ece1f8f827..7e76061a4d 100644 --- a/www/api.php +++ b/www/api.php @@ -9,12 +9,14 @@ * file that was distributed with this source code. */ -use Symfony\Component\HttpKernel\Debug\ErrorHandler; +use Alchemy\Phrasea\Application; +use Symfony\Component\Debug\ErrorHandler; require_once __DIR__ . '/../lib/autoload.php'; ErrorHandler::register(); +$environment = Application::ENV_PROD; $app = require __DIR__ . '/../lib/Alchemy/Phrasea/Application/Api.php'; $app->run(); diff --git a/www/index.php b/www/index.php index 22f1a537a2..f7c746c5c8 100644 --- a/www/index.php +++ b/www/index.php @@ -9,13 +9,14 @@ * file that was distributed with this source code. */ -use Symfony\Component\HttpKernel\Debug\ErrorHandler; +use Alchemy\Phrasea\Application; +use Symfony\Component\Debug\ErrorHandler; require_once __DIR__ . "/../lib/autoload.php"; ErrorHandler::register(); -$environment = 'prod'; +$environment = Application::ENV_PROD; $app = require __DIR__ . '/../lib/Alchemy/Phrasea/Application/Root.php'; $app->run(); diff --git a/www/index_dev.php b/www/index_dev.php index a3119aeb90..dc1472cf9a 100644 --- a/www/index_dev.php +++ b/www/index_dev.php @@ -9,13 +9,14 @@ * file that was distributed with this source code. */ -use Symfony\Component\HttpKernel\Debug\ErrorHandler; +use Alchemy\Phrasea\Application; +use Symfony\Component\Debug\ErrorHandler; require_once __DIR__ . "/../lib/autoload.php"; ErrorHandler::register(); -$environment = 'dev'; +$environment = Application::ENV_DEV; $app = require __DIR__ . '/../lib/Alchemy/Phrasea/Application/Root.php'; $app->run(); diff --git a/www/scripts/apps/admin/fields/views/edit.js b/www/scripts/apps/admin/fields/views/edit.js index 2864f6e4e3..4ae44163d7 100644 --- a/www/scripts/apps/admin/fields/views/edit.js +++ b/www/scripts/apps/admin/fields/views/edit.js @@ -89,11 +89,22 @@ define([ "blur input#tbranch": "fieldChangedAction", "blur input#separator": "fieldChangedAction", "blur input#tag": "tagFieldChangedAction", + "change select#vocabulary-type": "triggerControlledVocabulary", "keyup input.input-label": "labelChangedAction", "change input[type=checkbox]": "fieldChangedAction", "change select": "selectionChangedAction", "click .lng-label a": "_toggleLabels" }, + triggerControlledVocabulary: function(e) { + if ($(e.target, this.$el).find("option:selected").val() === "") { + this.model.set("vocabulary-type", false); + this.render(); + } else if ($("input#vocabulary-restricted", this.$el).length === 0) { + this.model.set("vocabulary-restricted", false); + this.model.set("vocabulary-type", $(e.target, this.$el).find("option:selected").val()); + this.render(); + } + }, selectionChangedAction: function(e) { var field = $(e.target); var data = {}; diff --git a/www/scripts/tests/specs/admin/fields.js b/www/scripts/tests/specs/admin/fields.js index 24224975d4..23a7024abd 100644 --- a/www/scripts/tests/specs/admin/fields.js +++ b/www/scripts/tests/specs/admin/fields.js @@ -225,6 +225,15 @@ define([ assert.isTrue(view.$('input#tag').closest(".control-group").hasClass("error")); }); + + it("should uncheck vocabulary restricted if provided vocabulary is empty", function() { + var view = this.view.render(); + + view.$('input#vocabulary-restricted').attr("checked", true); + view.$('input#vocabulary-type option').first().attr("selected", true); + + assert.isTrue(false === view.$('input#vocabulary-restricted').is(":checked")); + }); }); describe("FieldError Views", function() { diff --git a/www/skins/prod/jquery.edit.js b/www/skins/prod/jquery.edit.js index 2713ad757e..9eadd155d8 100644 --- a/www/skins/prod/jquery.edit.js +++ b/www/skins/prod/jquery.edit.js @@ -1035,7 +1035,7 @@ function cleanTags(string) }, { 'f':">", 't':">" - }, ]; + } ]; for(c in chars2replace) string = string.replace(RegExp(chars2replace[c].f,"g") ,chars2replace[c].t); return string; @@ -1929,6 +1929,10 @@ function startThisEditing(sbas_id,what,regbasprid,ssel) }); } + hsplit1(); + vsplit2() + vsplit1(); + $('#EDIT_TOP', p4.edit.editBox).resizable({ handles : 's', minHeight:100, @@ -1958,7 +1962,7 @@ function startThisEditing(sbas_id,what,regbasprid,ssel) }); $('#EDIT_MID_R') - .css('left', $('#EDIT_MID_R').position().left) + .css('left', $('#EDIT_MID_L').position().left + $('#EDIT_MID_L').width() + 15) .resizable({ handles : 'w', minWidth:200, @@ -2114,10 +2118,6 @@ $('#EDIT_MID_R') ETHSeeker = new EditThesaurusSeeker(p4.edit.sbas_id); - hsplit1(); - vsplit2(); - vsplit1(); - setSizeLimits(); var p = {