Merge pull request #816 from romainneutron/fix-736

[3.8] Fix #736 : Re-inject phraseanet rights after collection creation in case of PhraseaEngine
This commit is contained in:
Romain Neutron
2013-12-03 08:59:34 -08:00
14 changed files with 196 additions and 10 deletions

View File

@@ -12,6 +12,8 @@
namespace Alchemy\Phrasea\Command;
use Alchemy\Phrasea\Command\Command;
use Alchemy\Phrasea\Core\Event\CollectionCreateEvent;
use Alchemy\Phrasea\Core\PhraseaEvents;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Input\InputInterface;
@@ -65,5 +67,7 @@ class CreateCollection extends Command
}
\User_Adapter::reset_sys_admins_rights($this->container);
$this->container['dispatcher']->dispatch(PhraseaEvents::COLLECTION_CREATE, new CollectionCreateEvent($new_collection));
}
}

View File

@@ -11,6 +11,8 @@
namespace Alchemy\Phrasea\Controller\Admin;
use Alchemy\Phrasea\Core\Event\CollectionCreateEvent;
use Alchemy\Phrasea\Core\PhraseaEvents;
use Silex\Application;
use Silex\ControllerProviderInterface;
use Symfony\Component\HttpFoundation\Request;
@@ -1058,6 +1060,8 @@ class Databox implements ControllerProviderInterface
}
}
$app['dispatcher']->dispatch(PhraseaEvents::COLLECTION_CREATE, new CollectionCreateEvent($collection));
return $app->redirectPath('admin_display_collection', array('bas_id' => $collection->get_base_id(), 'success' => 1, 'reload-tree' => 1));
} catch (\Exception $e) {
return $app->redirectPath('admin_database_submit_collection', array('databox_id' => $databox_id, 'error' => 'error'));

View File

@@ -1034,8 +1034,6 @@ class Login implements ControllerProviderInterface
$response = $this->generateAuthResponse($app, $app['browser'], $request->request->get('redirect'));
$response->headers->clearCookie('invite-usr-id');
$user->ACL()->inject_rights();
if ($request->cookies->has('postlog') && $request->cookies->get('postlog') == '1') {
if (!$user->is_guest() && $request->cookies->has('invite-usr_id')) {
if ($user->get_id() != $inviteUsrId = $request->cookies->get('invite-usr_id')) {

View File

@@ -0,0 +1,32 @@
<?php
/*
* This file is part of Phraseanet
*
* (c) 2005-2013 Alchemy
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Alchemy\Phrasea\Core\Event;
use Alchemy\Phrasea\Authentication\Context;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\EventDispatcher\Event as SfEvent;
class CollectionCreateEvent extends SfEvent
{
private $collection;
public function __construct(\collection $collection)
{
$this->collection = $collection;
}
public function getCollection()
{
return $this->collection;
}
}

View File

@@ -23,4 +23,6 @@ final class PhraseaEvents
const API_LOAD_START = 'api.load.start';
const API_LOAD_END = 'api.load.end';
const API_RESULT = 'api.result';
const COLLECTION_CREATE = 'collection.create';
}

View File

@@ -23,24 +23,38 @@ class SearchEngineServiceProvider implements ServiceProviderInterface
public function register(Application $app)
{
$app['phraseanet.SE'] = $app->share(function ($app) {
$engineClass = $app['phraseanet.configuration']['main']['search-engine']['type'];
$engineOptions = $app['phraseanet.configuration']['main']['search-engine']['options'];
if (!class_exists($engineClass) || $engineClass instanceof SearchEngineInterface) {
throw new InvalidArgumentException(sprintf('%s is not valid SearchEngineInterface', $engineClass));
}
return $engineClass::create($app, $engineOptions);
return $app['phraseanet.SE.engine-class']::create($app, $engineOptions);
});
$app['phraseanet.SE.logger'] = $app->share(function (Application $app) {
return new SearchEngineLogger($app);
});
$app['phraseanet.SE.engine-class'] = $app->share(function ($app) {
$engineClass = $app['phraseanet.configuration']['main']['search-engine']['type'];
if (!class_exists($engineClass) || $engineClass instanceof SearchEngineInterface) {
throw new InvalidArgumentException(sprintf('%s is not valid SearchEngineInterface', $engineClass));
}
return $engineClass;
});
$app['phraseanet.SE.subscriber'] = $app->share(function ($app) {
return $app['phraseanet.SE.engine-class']::createSubscriber($app);
});
}
public function boot(Application $app)
{
}
$app['dispatcher'] = $app->share(
$app->extend('dispatcher', function ($dispatcher, Application $app) {
$dispatcher->addSubscriber($app['phraseanet.SE.subscriber']);
return $dispatcher;
})
);
}
}

View File

@@ -506,6 +506,16 @@ class PhraseaEngine implements SearchEngineInterface
return $html ;
}
/**
* {@inheritdoc}
*
* @return PhraseaEngineSubscriber
*/
public static function createSubscriber(Application $app)
{
return new PhraseaEngineSubscriber($app);
}
/**
* {@inheritdoc}
*

View File

@@ -0,0 +1,72 @@
<?php
/*
* This file is part of Phraseanet
*
* (c) 2005-2013 Alchemy
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Alchemy\Phrasea\SearchEngine\Phrasea;
use Alchemy\Phrasea\Application;
use Alchemy\Phrasea\Core\Event\CollectionCreateEvent;
use Alchemy\Phrasea\Core\Event\PostAuthenticate;
use Alchemy\Phrasea\Core\PhraseaEvents;
use Alchemy\Phrasea\SearchEngine\SearchEngineOptions;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
class PhraseaEngineSubscriber implements EventSubscriberInterface
{
private $app;
public function __construct(Application $app)
{
$this->app = $app;
}
public function onAuthenticate(PostAuthenticate $event)
{
$event->getUser()->ACL()->inject_rights();
}
public function onCollectionCreate(CollectionCreateEvent $event)
{
$sql = 'SELECT u.usr_id, c.session_id
FROM (usr u, Sessions s, basusr b)
LEFT JOIN cache c ON (c.usr_id = u.usr_id)
WHERE u.model_of = 0 AND u.usr_login NOT LIKE "(#deleted%"
AND b.base_id = :base_id AND b.usr_id = u.usr_id AND b.actif=1
AND s.usr_id = u.usr_id';
$stmt = $this->app['phraseanet.appbox']->get_connection()->prepare($sql);
$stmt->execute(array(':base_id' => $event->getCollection()->get_base_id()));
$rows = $stmt->fetchAll(\PDO::FETCH_ASSOC);
$stmt->closeCursor();
$initialized = false;
foreach ($rows as $row) {
$user = \User_Adapter::getInstance($row['usr_id'], $this->app);
$user->ACL()->inject_rights();
if (null !== $row['session_id']) {
if (!$initialized) {
$this->app['phraseanet.SE']->initialize();
$initialized = true;
}
phrasea_clear_cache($row['session_id']);
phrasea_close_session($row['session_id']);
}
}
}
public static function getSubscribedEvents()
{
return array(
PhraseaEvents::POST_AUTHENTICATE => array('onAuthenticate', 0),
PhraseaEvents::COLLECTION_CREATE => array('onCollectionCreate', 0),
);
}
}

View File

@@ -15,6 +15,7 @@ use Alchemy\Phrasea\Application;
use Alchemy\Phrasea\SearchEngine\SearchEngineOptions;
use Alchemy\Phrasea\SearchEngine\SearchEngineResult;
use Alchemy\Phrasea\Exception\RuntimeException;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Doctrine\Common\Collections\ArrayCollection;
interface SearchEngineInterface
@@ -231,6 +232,13 @@ interface SearchEngineInterface
*/
public function clearAllCache(\DateTime $date = null);
/**
* Returns a subscriber
*
* @return EventSubscriberInterface
*/
public static function createSubscriber(Application $app);
/**
* Creates the adapter.
*

View File

@@ -12,6 +12,7 @@
namespace Alchemy\Phrasea\SearchEngine\SphinxSearch;
use Alchemy\Phrasea\Application;
use Alchemy\Phrasea\SearchEngine\Phrasea\SphinxSearchEngineSubscriber;
use Alchemy\Phrasea\SearchEngine\SearchEngineInterface;
use Alchemy\Phrasea\SearchEngine\SearchEngineOptions;
use Alchemy\Phrasea\SearchEngine\SearchEngineResult;
@@ -572,6 +573,16 @@ class SphinxSearchEngine implements SearchEngineInterface
return $this;
}
/**
* {@inheritdoc}
*
* @return SphinxSearchEngineSubscriber
*/
public static function createSubscriber(Application $app)
{
return new SphinxSearchEngineSubscriber();
}
/**
* {@inheritdoc}
*

View File

@@ -0,0 +1,22 @@
<?php
/*
* This file is part of Phraseanet
*
* (c) 2005-2013 Alchemy
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Alchemy\Phrasea\SearchEngine\Phrasea;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
class SphinxSearchEngineSubscriber implements EventSubscriberInterface
{
public static function getSubscribedEvents()
{
return array();
}
}

View File

@@ -27,6 +27,7 @@ class PhraseaEngineTest extends SearchEngineAbstractTest
public function initialize()
{
self::$searchEngine = PhraseaEngine::create(self::$DI['app']);
self::$searchEngineClass = 'Alchemy\Phrasea\SearchEngine\Phrasea\PhraseaEngine';
}
protected function updateIndex(array $stemms = array())

View File

@@ -10,6 +10,7 @@ abstract class SearchEngineAbstractTest extends \PhraseanetPHPUnitAuthenticatedA
{
protected $options;
protected static $searchEngine;
protected static $searchEngineClass;
protected static $initialized = false;
public function setUp()
@@ -764,6 +765,12 @@ abstract class SearchEngineAbstractTest extends \PhraseanetPHPUnitAuthenticatedA
}
}
public function testCreateSubscriber()
{
$classname = self::$searchEngineClass;
$this->assertInstanceOf('Symfony\Component\EventDispatcher\EventSubscriberInterface', $classname::createSubscriber(self::$DI['app']));
}
abstract public function initialize();
abstract public function testAutocomplete();

View File

@@ -74,6 +74,7 @@ class SphinxSearchEngineTest extends SearchEngineAbstractTest
self::$searchd->run();
self::$searchEngine = SphinxSearchEngine::create($app, $app['phraseanet.configuration']['main']['search-engine']['options']);
self::$searchEngineClass = 'Alchemy\Phrasea\SearchEngine\SphinxSearch\SphinxSearchEngine';
}
public function setUp()