diff --git a/lib/Alchemy/Phrasea/Command/CreateCollection.php b/lib/Alchemy/Phrasea/Command/CreateCollection.php index 4c48e1d350..0f43cc09fd 100644 --- a/lib/Alchemy/Phrasea/Command/CreateCollection.php +++ b/lib/Alchemy/Phrasea/Command/CreateCollection.php @@ -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; @@ -62,5 +64,7 @@ class CreateCollection extends Command $this->container['manipulator.acl']->resetAdminRights(array_map(function ($id) use ($app) { return \User_Adapter::getInstance($id, $app); }, array_keys(\User_Adapter::get_sys_admins($this->container)))); + + $this->container['dispatcher']->dispatch(PhraseaEvents::COLLECTION_CREATE, new CollectionCreateEvent($new_collection)); } } diff --git a/lib/Alchemy/Phrasea/Controller/Admin/Databox.php b/lib/Alchemy/Phrasea/Controller/Admin/Databox.php index 108bb4ff5c..4933537375 100644 --- a/lib/Alchemy/Phrasea/Controller/Admin/Databox.php +++ b/lib/Alchemy/Phrasea/Controller/Admin/Databox.php @@ -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; @@ -806,6 +808,8 @@ class Databox implements ControllerProviderInterface } } + $app['dispatcher']->dispatch(PhraseaEvents::COLLECTION_CREATE, new CollectionCreateEvent($collection)); + return $app->redirectPath('admin_display_collection', ['bas_id' => $collection->get_base_id(), 'success' => 1, 'reload-tree' => 1]); } catch (\Exception $e) { return $app->redirectPath('admin_database_submit_collection', ['databox_id' => $databox_id, 'error' => 'error']); diff --git a/lib/Alchemy/Phrasea/Controller/Admin/Subdefs.php b/lib/Alchemy/Phrasea/Controller/Admin/Subdefs.php index d65e401ec7..25532fd68e 100644 --- a/lib/Alchemy/Phrasea/Controller/Admin/Subdefs.php +++ b/lib/Alchemy/Phrasea/Controller/Admin/Subdefs.php @@ -56,7 +56,7 @@ class Subdefs implements ControllerProviderInterface if ($delete_subdef) { - $delete_subef = explode('_', $delete_subdef); + $delete_subef = explode('_', $delete_subdef, 2); $group = $delete_subef[0]; $name = $delete_subef[1]; $subdefs = $databox->get_subdef_structure(); @@ -78,10 +78,10 @@ class Subdefs implements ControllerProviderInterface $options = []; - $post_sub_ex = explode('_', $post_sub); + $post_sub_ex = explode('_', $post_sub, 2); - $group = array_shift($post_sub_ex); - $name = implode('_', $post_sub_ex); + $group = $post_sub_ex[0]; + $name = $post_sub_ex[1]; $class = $request->request->get($post_sub . '_class'); $downloadable = $request->request->get($post_sub . '_downloadable'); diff --git a/lib/Alchemy/Phrasea/Controller/Root/Login.php b/lib/Alchemy/Phrasea/Controller/Root/Login.php index e70f362af5..6d12eb6d51 100644 --- a/lib/Alchemy/Phrasea/Controller/Root/Login.php +++ b/lib/Alchemy/Phrasea/Controller/Root/Login.php @@ -1032,8 +1032,6 @@ class Login implements ControllerProviderInterface $response = $this->generateAuthResponse($app, $app['browser'], $request->request->get('redirect')); $response->headers->clearCookie('invite-usr-id'); - $app['acl']->get($user)->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')) { diff --git a/lib/Alchemy/Phrasea/Core/Event/CollectionCreateEvent.php b/lib/Alchemy/Phrasea/Core/Event/CollectionCreateEvent.php new file mode 100644 index 0000000000..9a5d44a1c8 --- /dev/null +++ b/lib/Alchemy/Phrasea/Core/Event/CollectionCreateEvent.php @@ -0,0 +1,29 @@ +collection = $collection; + } + + public function getCollection() + { + return $this->collection; + } +} diff --git a/lib/Alchemy/Phrasea/Core/PhraseaEvents.php b/lib/Alchemy/Phrasea/Core/PhraseaEvents.php index 46e2b8ac48..32390cadad 100644 --- a/lib/Alchemy/Phrasea/Core/PhraseaEvents.php +++ b/lib/Alchemy/Phrasea/Core/PhraseaEvents.php @@ -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'; } diff --git a/lib/Alchemy/Phrasea/Core/Provider/SearchEngineServiceProvider.php b/lib/Alchemy/Phrasea/Core/Provider/SearchEngineServiceProvider.php index 91285c5e28..fefa7bd6c0 100644 --- a/lib/Alchemy/Phrasea/Core/Provider/SearchEngineServiceProvider.php +++ b/lib/Alchemy/Phrasea/Core/Provider/SearchEngineServiceProvider.php @@ -23,24 +23,38 @@ class SearchEngineServiceProvider implements ServiceProviderInterface public function register(Application $app) { $app['phraseanet.SE'] = $app->share(function ($app) { - - $engineClass = $app['conf']->get(['main', 'search-engine', 'type']); $engineOptions = $app['conf']->get(['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['conf']->get(['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; + }) + ); + } } diff --git a/lib/Alchemy/Phrasea/Model/Repositories/BasketRepository.php b/lib/Alchemy/Phrasea/Model/Repositories/BasketRepository.php index e67d772b2f..14ab582aa8 100644 --- a/lib/Alchemy/Phrasea/Model/Repositories/BasketRepository.php +++ b/lib/Alchemy/Phrasea/Model/Repositories/BasketRepository.php @@ -11,6 +11,7 @@ namespace Alchemy\Phrasea\Model\Repositories; +use Alchemy\Phrasea\Application; use Alchemy\Phrasea\Model\Entities\Basket; use Doctrine\ORM\EntityRepository; diff --git a/lib/Alchemy/Phrasea/SearchEngine/Phrasea/PhraseaEngine.php b/lib/Alchemy/Phrasea/SearchEngine/Phrasea/PhraseaEngine.php index bdc01e1256..e5e71dcd14 100644 --- a/lib/Alchemy/Phrasea/SearchEngine/Phrasea/PhraseaEngine.php +++ b/lib/Alchemy/Phrasea/SearchEngine/Phrasea/PhraseaEngine.php @@ -508,6 +508,16 @@ class PhraseaEngine implements SearchEngineInterface return $html ; } + /** + * {@inheritdoc} + * + * @return PhraseaEngineSubscriber + */ + public static function createSubscriber(Application $app) + { + return new PhraseaEngineSubscriber($app); + } + /** * {@inheritdoc} * diff --git a/lib/Alchemy/Phrasea/SearchEngine/Phrasea/PhraseaEngineSubscriber.php b/lib/Alchemy/Phrasea/SearchEngine/Phrasea/PhraseaEngineSubscriber.php new file mode 100644 index 0000000000..bbdd71deb5 --- /dev/null +++ b/lib/Alchemy/Phrasea/SearchEngine/Phrasea/PhraseaEngineSubscriber.php @@ -0,0 +1,71 @@ +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), + ); + } +} diff --git a/lib/Alchemy/Phrasea/SearchEngine/SearchEngineInterface.php b/lib/Alchemy/Phrasea/SearchEngine/SearchEngineInterface.php index 621bf619dd..5939b69f19 100644 --- a/lib/Alchemy/Phrasea/SearchEngine/SearchEngineInterface.php +++ b/lib/Alchemy/Phrasea/SearchEngine/SearchEngineInterface.php @@ -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; use Alchemy\Phrasea\Model\Entities\FeedEntry; @@ -232,6 +233,13 @@ interface SearchEngineInterface */ public function clearAllCache(\DateTime $date = null); + /** + * Returns a subscriber + * + * @return EventSubscriberInterface + */ + public static function createSubscriber(Application $app); + /** * Creates the adapter. * diff --git a/lib/Alchemy/Phrasea/SearchEngine/SphinxSearch/SphinxSearchEngine.php b/lib/Alchemy/Phrasea/SearchEngine/SphinxSearch/SphinxSearchEngine.php index ef694eaefd..5a33bc16ea 100644 --- a/lib/Alchemy/Phrasea/SearchEngine/SphinxSearch/SphinxSearchEngine.php +++ b/lib/Alchemy/Phrasea/SearchEngine/SphinxSearch/SphinxSearchEngine.php @@ -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; @@ -573,6 +574,16 @@ class SphinxSearchEngine implements SearchEngineInterface return $this; } + /** + * {@inheritdoc} + * + * @return SphinxSearchEngineSubscriber + */ + public static function createSubscriber(Application $app) + { + return new SphinxSearchEngineSubscriber(); + } + /** * {@inheritdoc} * diff --git a/lib/Alchemy/Phrasea/SearchEngine/SphinxSearch/SphinxSearchEngineSubscriber.php b/lib/Alchemy/Phrasea/SearchEngine/SphinxSearch/SphinxSearchEngineSubscriber.php new file mode 100644 index 0000000000..3c0ebcb921 --- /dev/null +++ b/lib/Alchemy/Phrasea/SearchEngine/SphinxSearch/SphinxSearchEngineSubscriber.php @@ -0,0 +1,22 @@ +