Add basket converter

This commit is contained in:
Romain Neutron
2013-11-08 19:13:37 +01:00
parent 21f0df2cfe
commit 3548421160
43 changed files with 711 additions and 544 deletions

View File

@@ -0,0 +1,40 @@
<?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\ACL;
use Alchemy\Phrasea\Model\Entities\Basket;
use User_Adapter;
class BasketACL
{
public function hasAccess(Basket $basket, User_Adapter $user)
{
if ($this->isOwner($basket, $user)) {
return true;
}
if ($basket->getValidation()) {
foreach ($basket->getValidation()->getParticipants() as $participant) {
if ($participant->getUsrId() === $user->get_id()) {
return true;
}
}
}
return false;
}
public function isOwner(Basket $basket, User_Adapter $user)
{
return $basket->getUsrId() === $user->get_id();
}
}

View File

@@ -77,6 +77,8 @@ use Alchemy\Phrasea\Core\Event\Subscriber\LogoutSubscriber;
use Alchemy\Phrasea\Core\Event\Subscriber\PhraseaLocaleSubscriber;
use Alchemy\Phrasea\Core\Event\Subscriber\MaintenanceSubscriber;
use Alchemy\Phrasea\Core\Event\Subscriber\CookiesDisablerSubscriber;
use Alchemy\Phrasea\Core\Middleware\BasketMiddlewareProvider;
use Alchemy\Phrasea\Core\Provider\ACLServiceProvider;
use Alchemy\Phrasea\Core\Provider\AuthenticationManagerServiceProvider;
use Alchemy\Phrasea\Core\Provider\BrowserServiceProvider;
use Alchemy\Phrasea\Core\Provider\BorderManagerServiceProvider;
@@ -195,6 +197,9 @@ class Application extends SilexApplication
ini_set('error_log', $this['root.path'] . '/logs/php_error.log');
}
$this->register(new BasketMiddlewareProvider());
$this->register(new ACLServiceProvider());
$this->register(new AuthenticationManagerServiceProvider());
$this->register(new BorderManagerServiceProvider());
$this->register(new BrowserServiceProvider());

View File

@@ -17,6 +17,7 @@ use Alchemy\Phrasea\Authentication\Context;
use Alchemy\Phrasea\Core\Event\PreAuthenticate;
use Alchemy\Phrasea\Core\Event\ApiOAuth2StartEvent;
use Alchemy\Phrasea\Core\Event\ApiOAuth2EndEvent;
use Alchemy\Phrasea\Model\Entities\Basket;
use Silex\Application as SilexApplication;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\Request;
@@ -88,7 +89,7 @@ class V1 implements ControllerProviderInterface
$app['dispatcher']->dispatch(PhraseaEvents::API_OAUTH2_END, new ApiOAuth2EndEvent());
return;
}, 256);
});
/**
* OAuth log process
@@ -604,11 +605,14 @@ class V1 implements ControllerProviderInterface
* BASKET_ID : required INT
*
*/
$controllers->get('/baskets/{basket_id}/content/', function (SilexApplication $app, $basket_id) {
return $app['api']->get_basket($app['request'], $basket_id)->get_response();
})->assert('basket_id', '\d+');
$controllers->get('/baskets/{basket}/content/', function (SilexApplication $app, Basket $basket) {
return $app['api']->get_basket($app['request'], $basket)->get_response();
})
->before($app['middleware.basket.converter'])
->before($app['middleware.basket.user-access'])
->assert('basket', '\d+');
$controllers->get('/baskets/{wrong_basket_id}/content/', $bad_request_exception);
$controllers->get('/baskets/{wrong_basket}/content/', $bad_request_exception);
/**
* Route : /baskets/BASKET_ID/settitle/
@@ -619,13 +623,16 @@ class V1 implements ControllerProviderInterface
* BASKET_ID : required INT
*
*/
$controllers->post('/baskets/{basket_id}/setname/', function (SilexApplication $app, $basket_id) {
$controllers->post('/baskets/{basket}/setname/', function (SilexApplication $app, Basket $basket) {
return $app['api']
->set_basket_title($app['request'], $basket_id)
->set_basket_title($app['request'], $basket)
->get_response();
})->assert('basket_id', '\d+');
})
->before($app['middleware.basket.converter'])
->before($app['middleware.basket.user-is-owner'])
->assert('basket', '\d+');
$controllers->post('/baskets/{wrong_basket_id}/setname/', $bad_request_exception);
$controllers->post('/baskets/{wrong_basket}/setname/', $bad_request_exception);
/**
* Route : /baskets/BASKET_ID/setdescription/
@@ -636,13 +643,16 @@ class V1 implements ControllerProviderInterface
* BASKET_ID : required INT
*
*/
$controllers->post('/baskets/{basket_id}/setdescription/', function (SilexApplication $app, $basket_id) {
$controllers->post('/baskets/{basket}/setdescription/', function (SilexApplication $app, Basket $basket) {
return $app['api']
->set_basket_description($app['request'], $basket_id)
->set_basket_description($app['request'], $basket)
->get_response();
})->assert('basket_id', '\d+');
})
->before($app['middleware.basket.converter'])
->before($app['middleware.basket.user-is-owner'])
->assert('basket', '\d+');
$controllers->post('/baskets/{wrong_basket_id}/setdescription/', $bad_request_exception);
$controllers->post('/baskets/{wrong_basket}/setdescription/', $bad_request_exception);
/**
* Route : /baskets/BASKET_ID/delete/
@@ -653,11 +663,14 @@ class V1 implements ControllerProviderInterface
* BASKET_ID : required INT
*
*/
$controllers->post('/baskets/{basket_id}/delete/', function (SilexApplication $app, $basket_id) {
return $app['api']->delete_basket($app['request'], $basket_id)->get_response();
})->assert('basket_id', '\d+');
$controllers->post('/baskets/{basket}/delete/', function (SilexApplication $app, Basket $basket) {
return $app['api']->delete_basket($app['request'], $basket)->get_response();
})
->before($app['middleware.basket.converter'])
->before($app['middleware.basket.user-is-owner'])
->assert('basket', '\d+');
$controllers->post('/baskets/{wrong_basket_id}/delete/', $bad_request_exception);
$controllers->post('/baskets/{wrong_basket}/delete/', $bad_request_exception);
/**
* Route : /feeds/list/

View File

@@ -86,9 +86,8 @@ class Baskets implements ControllerProviderInterface
public function deleteBasket(Application $app, Request $request)
{
try {
$repository = $app['EM']->getRepository('Alchemy\Phrasea\Model\Entities\Basket');
/* @var $repository Alchemy\Phrasea\Model\Repositories\BasketRepository */
$basket = $repository->findUserBasket($app, $request->request->get('courChuId'), $app['authentication']->getUser(), true);
$basket = $app['converter.basket']->convert($request->request->get('courChuId'));
$app['acl.basket']->isOwner($basket, $app['authentication']->getUser());
$app['EM']->remove($basket);
$app['EM']->flush();
@@ -137,11 +136,9 @@ class Baskets implements ControllerProviderInterface
*/
public function addElementToBasket(Application $app, Request $request)
{
$repository = $app['EM']->getRepository('Alchemy\Phrasea\Model\Entities\Basket');
/* @var $repository Alchemy\Phrasea\Model\Repositories\BasketRepository */
$basket = $repository->findUserBasket($app, $request->request->get('courChuId'), $app['authentication']->getUser(), true);
$basket = $app['converter.basket']->convert($request->request->get('courChuId'));
$app['acl.basket']->isOwner($basket, $app['authentication']->getUser());
if ($basket) {
try {
$record = new \record_adapter($app, $request->request->get('sbas'), $request->request->get('p0'));
@@ -156,7 +153,6 @@ class Baskets implements ControllerProviderInterface
} catch (\Exception $e) {
}
}
return $app->redirectPath('get_client_baskets', array(
'courChuId' => $basket ? $basket->getId() : ''
@@ -181,7 +177,8 @@ class Baskets implements ControllerProviderInterface
}
if ('' !== $selectedBasketId) {
$selectedBasket = $app['EM']->getRepository('Alchemy\Phrasea\Model\Entities\Basket')->findUserBasket($app, $selectedBasketId, $app['authentication']->getUser(), true);
$selectedBasket = $app['converter.basket']->convert($selectedBasketId);
$app['acl.basket']->isOwner($selectedBasket, $app['authentication']->getUser());
}
$basketCollections = $baskets->partition(function ($key, $basket) {

View File

@@ -57,14 +57,17 @@ class Lightbox implements ControllerProviderInterface
break;
case \random::TYPE_VALIDATE:
case \random::TYPE_VIEW:
return $app->redirectPath('lightbox_validation', array('ssel_id' => $datas['datas']));
return $app->redirectPath('lightbox_validation', array('basket' => $datas['datas']));
break;
}
});
$controllers->before(function (Request $request) use ($app) {
$app['firewall']->requireAuthentication();
});
})
// Silex\Route::convert is not used as this should be done prior the before middleware
->before($app['middleware.basket.converter'])
->before($app['middleware.basket.user-access']);
$controllers->get('/', function (SilexApplication $app) {
try {
@@ -75,8 +78,6 @@ class Lightbox implements ControllerProviderInterface
$repository = $app['EM']->getRepository('Alchemy\Phrasea\Model\Entities\Basket');
/* @var $repository Alchemy\Phrasea\Model\Repositories\BasketRepository */
$basket_collection = array_merge(
$repository->findActiveByUser($app['authentication']->getUser())
, $repository->findActiveValidationByUser($app['authentication']->getUser())
@@ -117,7 +118,6 @@ class Lightbox implements ControllerProviderInterface
->assert('sselcont_id', '\d+');
$controllers->get('/ajax/LOAD_BASKET_ELEMENT/{sselcont_id}/', function (SilexApplication $app, $sselcont_id) {
/* @var $repository Alchemy\Phrasea\Model\Repositories\BasketElementRepository */
$repository = $app['EM']->getRepository('Alchemy\Phrasea\Model\Entities\BasketElement');
$BasketElement = $repository->findUserElement($sselcont_id, $app['authentication']->getUser());
@@ -201,7 +201,7 @@ class Lightbox implements ControllerProviderInterface
->assert('entry_id', '\d+')
->assert('item_id', '\d+');
$controllers->get('/validate/{ssel_id}/', function (SilexApplication $app, $ssel_id) {
$controllers->get('/validate/{basket}/', function (SilexApplication $app, $basket) {
try {
\Session_Logger::updateClientInfos($app, 6);
@@ -211,17 +211,10 @@ class Lightbox implements ControllerProviderInterface
$repository = $app['EM']->getRepository('Alchemy\Phrasea\Model\Entities\Basket');
/* @var $repository Alchemy\Phrasea\Model\Repositories\BasketRepository */
$basket_collection = $repository->findActiveValidationAndBasketByUser(
$app['authentication']->getUser()
);
$basket = $repository->findUserBasket(
$app, $ssel_id
, $app['authentication']->getUser()
, false
);
if ($basket->getIsRead() === false) {
$basket = $app['EM']->merge($basket);
$basket->setIsRead(true);
@@ -253,9 +246,9 @@ class Lightbox implements ControllerProviderInterface
return $response;
})
->bind('lightbox_validation')
->assert('ssel_id', '\d+');
->assert('basket', '\d+');
$controllers->get('/compare/{ssel_id}/', function (SilexApplication $app, $ssel_id) {
$controllers->get('/compare/{basket}/', function (SilexApplication $app, Basket $basket) {
try {
\Session_Logger::updateClientInfos($app, 6);
@@ -265,17 +258,10 @@ class Lightbox implements ControllerProviderInterface
$repository = $app['EM']->getRepository('Alchemy\Phrasea\Model\Entities\Basket');
/* @var $repository Alchemy\Phrasea\Model\Repositories\BasketRepository */
$basket_collection = $repository->findActiveValidationAndBasketByUser(
$app['authentication']->getUser()
);
$basket = $repository->findUserBasket(
$app, $ssel_id
, $app['authentication']->getUser()
, false
);
if ($basket->getIsRead() === false) {
$basket = $app['EM']->merge($basket);
$basket->setIsRead(true);
@@ -307,7 +293,7 @@ class Lightbox implements ControllerProviderInterface
return $response;
})
->bind('lightbox_compare')
->assert('ssel_id', '\d+');
->assert('basket', '\d+');
$controllers->get('/feeds/entry/{entry_id}/', function (SilexApplication $app, $entry_id) {
@@ -344,26 +330,12 @@ class Lightbox implements ControllerProviderInterface
->bind('lightbox_feed_entry')
->assert('entry_id', '\d+');
$controllers->get('/ajax/LOAD_REPORT/{ssel_id}/', function (SilexApplication $app, $ssel_id) {
$controllers->get('/ajax/LOAD_REPORT/{basket}/', function (SilexApplication $app, Basket $basket) {
$template = 'lightbox/basket_content_report.html.twig';
$repository = $app['EM']->getRepository('Alchemy\Phrasea\Model\Entities\Basket');
/* @var $repository Alchemy\Phrasea\Model\Repositories\BasketRepository */
$basket = $repository->findUserBasket(
$app, $ssel_id
, $app['authentication']->getUser()
, false
);
$response = new Response($app['twig']->render($template, array('basket' => $basket)));
$response->setCharset('UTF-8');
return $response;
return new Response($app['twig']->render('lightbox/basket_content_report.html.twig', array('basket' => $basket)));
})
->bind('lightbox_ajax_report')
->assert('ssel_id', '\d+');
->assert('basket', '\d+');
$controllers->post('/ajax/SET_NOTE/{sselcont_id}/', function (SilexApplication $app, $sselcont_id) {
$output = array('error' => true, 'datas' => _('Erreur lors de l\'enregistrement des donnees'));
@@ -375,7 +347,6 @@ class Lightbox implements ControllerProviderInterface
Return new Response('You must provide a note value', 400);
}
/* @var $repository Alchemy\Phrasea\Model\Repositories\BasketElementRepository */
$repository = $app['EM']->getRepository('Alchemy\Phrasea\Model\Entities\BasketElement');
$basket_element = $repository->findUserElement($sselcont_id, $app['authentication']->getUser());
@@ -425,7 +396,6 @@ class Lightbox implements ControllerProviderInterface
$repository = $app['EM']->getRepository('Alchemy\Phrasea\Model\Entities\BasketElement');
/* @var $repository Alchemy\Phrasea\Model\Repositories\BasketElementRepository */
$basket_element = $repository->findUserElement(
$sselcont_id
, $app['authentication']->getUser()
@@ -468,20 +438,11 @@ class Lightbox implements ControllerProviderInterface
->bind('lightbox_ajax_set_element_agreement')
->assert('sselcont_id', '\d+');
$controllers->post('/ajax/SET_RELEASE/{ssel_id}/', function (SilexApplication $app, $ssel_id) {
$repository = $app['EM']->getRepository('Alchemy\Phrasea\Model\Entities\Basket');
$controllers->post('/ajax/SET_RELEASE/{basket}/', function (SilexApplication $app, Basket $basket) {
$datas = array('error' => true, 'datas' => '');
try {
/* @var $repository Alchemy\Phrasea\Model\Repositories\BasketRepository */
$basket = $repository->findUserBasket(
$app, $ssel_id
, $app['authentication']->getUser()
, false
);
if (!$basket->getValidation()) {
throw new ControllerException('There is no validation session attached to this basket');
}
@@ -536,7 +497,7 @@ class Lightbox implements ControllerProviderInterface
return $app->json($datas);
})
->bind('lightbox_ajax_set_release')
->assert('ssel_id', '\d+');
->assert('basket', '\d+');
return $controllers;
}

View File

@@ -34,49 +34,62 @@ class BasketController implements ControllerProviderInterface
$controllers = $app['controllers_factory'];
$controllers->before(function (Request $request) use ($app) {
$controllers
->before(function (Request $request, Application $app) {
$app['firewall']->requireAuthentication();
});
})
// Silex\Route::convert is not used as this should be done prior the before middleware
->before($app['middleware.basket.converter'])
->before($app['middleware.basket.user-access']);
$controllers->get('/{basket_id}/', 'controller.prod.basket:displayBasket')
$controllers->get('/{basket}/', 'controller.prod.basket:displayBasket')
->bind('prod_baskets_basket')
->assert('basket_id', '\d+');
->assert('basket', '\d+');
$controllers->post('/', 'controller.prod.basket:createBasket')
->bind('prod_baskets');
$controllers->post('/{basket_id}/delete/', 'controller.prod.basket:deleteBasket')
->assert('basket_id', '\d+')
->bind('basket_delete');
$controllers->post('/{basket}/delete/', 'controller.prod.basket:deleteBasket')
->assert('basket', '\d+')
->bind('basket_delete')
->before($app['middleware.basket.user-is-owner']);
$controllers->post('/{basket_id}/delete/{basket_element_id}/', 'controller.prod.basket:removeBasketElement')
$controllers->post('/{basket}/delete/{basket_element_id}/', 'controller.prod.basket:removeBasketElement')
->bind('prod_baskets_basket_element_remove')
->assert('basket_id', '\d+')
->assert('basket_element_id', '\d+');
->assert('basket', '\d+')
->assert('basket_element_id', '\d+')
->before($app['middleware.basket.user-is-owner']);
$controllers->post('/{basket_id}/update/', 'controller.prod.basket:updateBasket')
$controllers->post('/{basket}/update/', 'controller.prod.basket:updateBasket')
->bind('prod_baskets_basket_update')
->assert('basket_id', '\d+');
->assert('basket', '\d+')
->before($app['middleware.basket.user-is-owner']);
$controllers->get('/{basket_id}/update/', 'controller.prod.basket:displayUpdateForm')
->assert('basket_id', '\d+');
$controllers->get('/{basket}/update/', 'controller.prod.basket:displayUpdateForm')
->assert('basket', '\d+')
->before($app['middleware.basket.user-is-owner']);
$controllers->get('/{basket_id}/reorder/', 'controller.prod.basket:displayReorderForm')
->assert('basket_id', '\d+')
->bind('prod_baskets_basket_reorder');
$controllers->get('/{basket}/reorder/', 'controller.prod.basket:displayReorderForm')
->assert('basket', '\d+')
->bind('prod_baskets_basket_reorder')
->before($app['middleware.basket.user-is-owner']);
$controllers->post('/{basket_id}/reorder/', 'controller.prod.basket:reorder')
->assert('basket_id', '\d+');
$controllers->post('/{basket}/reorder/', 'controller.prod.basket:reorder')
->assert('basket', '\d+')
->before($app['middleware.basket.user-is-owner']);
$controllers->post('/{basket_id}/archive/', 'controller.prod.basket:archiveBasket')
$controllers->post('/{basket}/archive/', 'controller.prod.basket:archiveBasket')
->bind('prod_baskets_basket_archive')
->assert('basket_id', '\d+');
->assert('basket', '\d+')
->before($app['middleware.basket.user-is-owner']);
$controllers->post('/{basket_id}/addElements/', 'controller.prod.basket:addElements')
->assert('basket_id', '\d+');
$controllers->post('/{basket}/addElements/', 'controller.prod.basket:addElements')
->assert('basket', '\d+')
->before($app['middleware.basket.user-is-owner']);
$controllers->post('/{basket_id}/stealElements/', 'controller.prod.basket:stealElements')
->assert('basket_id', '\d+');
$controllers->post('/{basket}/stealElements/', 'controller.prod.basket:stealElements')
->assert('basket', '\d+')
->before($app['middleware.basket.user-is-owner']);
$controllers->get('/create/', 'controller.prod.basket:displayCreateForm')
->bind('prod_baskets_create');
@@ -84,11 +97,8 @@ class BasketController implements ControllerProviderInterface
return $controllers;
}
public function displayBasket(Application $app, Request $request, $basket_id)
public function displayBasket(Application $app, Request $request, BasketEntity $basket)
{
$basket = $app['EM']->getRepository('Alchemy\Phrasea\Model\Entities\Basket')
->findUserBasket($app, $basket_id, $app['authentication']->getUser(), false);
if ($basket->getIsRead() === false) {
$basket->setIsRead(true);
$app['EM']->flush();
@@ -111,9 +121,6 @@ class BasketController implements ControllerProviderInterface
public function createBasket(Application $app, Request $request)
{
$request = $app['request'];
/* @var $request \Symfony\Component\HttpFoundation\Request */
$Basket = new BasketEntity();
$Basket->setName($request->request->get('name', ''));
@@ -144,7 +151,7 @@ class BasketController implements ControllerProviderInterface
$app['EM']->flush();
if ($request->getRequestFormat() == 'json') {
if ($request->getRequestFormat() === 'json') {
$data = array(
'success' => true
, 'message' => _('Basket created')
@@ -155,15 +162,12 @@ class BasketController implements ControllerProviderInterface
return $app->json($data);
} else {
return $app->redirectPath('prod_baskets_basket', array('basket_id' => $Basket->getId()));
return $app->redirectPath('prod_baskets_basket', array('basket' => $Basket->getId()));
}
}
public function deleteBasket(Application $app, Request $request, $basket_id)
public function deleteBasket(Application $app, Request $request, BasketEntity $basket)
{
$basket = $app['EM']->getRepository('Alchemy\Phrasea\Model\Entities\Basket')
->findUserBasket($app, $basket_id, $app['authentication']->getUser(), true);
$app['EM']->remove($basket);
$app['EM']->flush();
@@ -172,21 +176,18 @@ class BasketController implements ControllerProviderInterface
, 'message' => _('Basket has been deleted')
);
if ($request->getRequestFormat() == 'json') {
if ($request->getRequestFormat() === 'json') {
return $app->json($data);
} else {
return $app->redirectPath('prod_workzone_show');
}
}
public function removeBasketElement(Application $app, Request $request, $basket_id, $basket_element_id)
public function removeBasketElement(Application $app, Request $request, BasketEntity $basket, $basket_element_id)
{
$basket = $app['EM']->getRepository('Alchemy\Phrasea\Model\Entities\Basket')
->findUserBasket($app, $basket_id, $app['authentication']->getUser(), true);
foreach ($basket->getElements() as $basket_element) {
/* @var $basket_element BasketElement */
if ($basket_element->getId() == $basket_element_id) {
if ($basket_element->getId() === (int) $basket_element_id) {
$app['EM']->remove($basket_element);
}
}
@@ -198,21 +199,18 @@ class BasketController implements ControllerProviderInterface
, 'message' => _('Record removed from basket')
);
if ($request->getRequestFormat() == 'json') {
if ($request->getRequestFormat() === 'json') {
return $app->json($data);
} else {
return $app->redirectPath('prod_workzone_show');
}
}
public function updateBasket(Application $app, Request $request, $basket_id)
public function updateBasket(Application $app, Request $request, BasketEntity $basket)
{
$success = false;
try {
$basket = $app['EM']->getRepository('Alchemy\Phrasea\Model\Entities\Basket')
->findUserBasket($app, $basket_id, $app['authentication']->getUser(), true);
$basket->setName($request->request->get('name', ''));
$basket->setDescription($request->request->get('description'));
@@ -232,41 +230,30 @@ class BasketController implements ControllerProviderInterface
$data = array(
'success' => $success
, 'message' => $msg
, 'basket' => array('id' => $basket_id)
, 'basket' => array('id' => $basket->getId())
);
if ($request->getRequestFormat() == 'json') {
if ($request->getRequestFormat() === 'json') {
return $app->json($data);
} else {
return $app->redirectPath('prod_workzone_show');
}
}
public function displayUpdateForm(Application $app, $basket_id)
public function displayUpdateForm(Application $app, BasketEntity $basket)
{
$basket = $app['EM']
->getRepository('Alchemy\Phrasea\Model\Entities\Basket')
->findUserBasket($app, $basket_id, $app['authentication']->getUser(), true);
return $app['twig']->render('prod/Baskets/Update.html.twig', array('basket' => $basket));
}
public function displayReorderForm(Application $app, $basket_id)
public function displayReorderForm(Application $app, BasketEntity $basket)
{
$basket = $app['EM']
->getRepository('Alchemy\Phrasea\Model\Entities\Basket')
->findUserBasket($app, $basket_id, $app['authentication']->getUser(), true);
return $app['twig']->render('prod/Baskets/Reorder.html.twig', array('basket' => $basket));
}
public function reorder(Application $app, $basket_id)
public function reorder(Application $app, BasketEntity $basket)
{
$ret = array('success' => false, 'message' => _('An error occured'));
try {
$basket = $app['EM']->getRepository('Alchemy\Phrasea\Model\Entities\Basket')
->findUserBasket($app, $basket_id, $app['authentication']->getUser(), true);
$order = $app['request']->request->get('element');
/* @var $basket BasketEntity */
@@ -287,11 +274,8 @@ class BasketController implements ControllerProviderInterface
return $app->json($ret);
}
public function archiveBasket(Application $app, Request $request, $basket_id)
public function archiveBasket(Application $app, Request $request, BasketEntity $basket)
{
$basket = $app['EM']->getRepository('Alchemy\Phrasea\Model\Entities\Basket')
->findUserBasket($app, $basket_id, $app['authentication']->getUser(), true);
$archive_status = (Boolean) $request->query->get('archive');
$basket->setArchived($archive_status);
@@ -311,18 +295,15 @@ class BasketController implements ControllerProviderInterface
, 'message' => $message
);
if ($request->getRequestFormat() == 'json') {
if ($request->getRequestFormat() === 'json') {
return $app->json($data);
} else {
return $app->redirectPath('prod_workzone_show');
}
}
public function addElements(Application $app, Request $request, $basket_id)
public function addElements(Application $app, Request $request, BasketEntity $basket)
{
$basket = $app['EM']->getRepository('Alchemy\Phrasea\Model\Entities\Basket')
->findUserBasket($app, $basket_id, $app['authentication']->getUser(), true);
$n = 0;
$records = RecordsRequest::fromRequest($app, $request, true);
@@ -362,18 +343,15 @@ class BasketController implements ControllerProviderInterface
, 'message' => sprintf(_('%d records added'), $n)
);
if ($request->getRequestFormat() == 'json') {
if ($request->getRequestFormat() === 'json') {
return $app->json($data);
} else {
return $app->redirectPath('prod_workzone_show');
}
}
public function stealElements(Application $app, Request $request, $basket_id)
public function stealElements(Application $app, Request $request, BasketEntity $basket)
{
$basket = $app['EM']->getRepository('Alchemy\Phrasea\Model\Entities\Basket')
->findUserBasket($app, $basket_id, $app['authentication']->getUser(), true);
$n = 0;
foreach ($request->request->get('elements') as $bask_element_id) {
@@ -384,6 +362,7 @@ class BasketController implements ControllerProviderInterface
continue;
}
$basket_element->getBasket()->removeElement($basket_element);
$basket_element->setBasket($basket);
$basket->addElement($basket_element);
$n++;
@@ -396,7 +375,7 @@ class BasketController implements ControllerProviderInterface
, 'message' => sprintf(_('%d records moved'), $n)
);
if ($request->getRequestFormat() == 'json') {
if ($request->getRequestFormat() === 'json') {
return $app->json($data);
} else {
return $app->redirectPath('prod_workzone_show');

View File

@@ -221,7 +221,7 @@ class Push implements ControllerProviderInterface
$app['EM']->flush();
$url = $app->url('lightbox_compare', array(
'ssel_id' => $Basket->getId(),
'basket' => $Basket->getId(),
'LOG' => $app['tokens']->getUrlToken(
\random::TYPE_VIEW,
$user_receiver->get_id(),
@@ -419,7 +419,7 @@ class Push implements ControllerProviderInterface
$app['EM']->flush();
$url = $app->url('lightbox_validation', array(
'ssel_id' => $Basket->getId(),
'basket' => $Basket->getId(),
'LOG' => $app['tokens']->getUrlToken(
\random::TYPE_VALIDATE,
$participant_user->get_id(),

View File

@@ -11,6 +11,7 @@
namespace Alchemy\Phrasea\Controller\Prod;
use Alchemy\Phrasea\Model\Entities\Basket;
use Alchemy\Phrasea\SearchEngine\SearchEngineOptions;
use Symfony\Component\HttpFoundation\Request;
use Silex\Application;
@@ -33,8 +34,10 @@ class Tooltip implements ControllerProviderInterface
$app['firewall']->requireAuthentication();
});
$controllers->post('/basket/{basket_id}/', 'controller.prod.tooltip:displayBasket')
->assert('basket_id', '\d+')
$controllers->post('/basket/{basket}/', 'controller.prod.tooltip:displayBasket')
->assert('basket', '\d+')
->before($app['middleware.basket.converter'])
->before($app['middleware.basket.user-access'])
->bind('prod_tooltip_basket');
$controllers->post('/Story/{sbas_id}/{record_id}/', 'controller.prod.tooltip:displayStory')
@@ -79,11 +82,8 @@ class Tooltip implements ControllerProviderInterface
return $controllers;
}
public function displayBasket(Application $app, $basket_id)
public function displayBasket(Application $app, Basket $basket)
{
$basket = $app['EM']->getRepository('Alchemy\Phrasea\Model\Entities\Basket')
->findUserBasket($app, $basket_id, $app['authentication']->getUser(), false);
return $app['twig']->render('prod/Tooltip/Basket.html.twig', array('basket' => $basket));
}

View File

@@ -11,11 +11,12 @@
namespace Alchemy\Phrasea\Controller\Prod;
use Alchemy\Phrasea\Model\Entities\Basket;
use Alchemy\Phrasea\Model\Entities\StoryWZ;
use Alchemy\Phrasea\Helper\WorkZone as WorkzoneHelper;
use Silex\Application;
use Silex\ControllerProviderInterface;
use Symfony\Component\HttpFoundation\Request;
use Alchemy\Phrasea\Helper\WorkZone as WorkzoneHelper;
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
@@ -35,7 +36,10 @@ class WorkZone implements ControllerProviderInterface
$controllers->before(function (Request $request) use ($app) {
$app['firewall']->requireAuthentication();
});
})
// Silex\Route::convert is not used as this should be done prior the before middleware
->before($app['middleware.basket.converter'])
->before($app['middleware.basket.user-access']);;
$controllers->get('/', 'controller.prod.workzone:displayWorkzone')
->bind('prod_workzone_show');
@@ -46,9 +50,9 @@ class WorkZone implements ControllerProviderInterface
$controllers->get('/Browse/Search/', 'controller.prod.workzone:browserSearch')
->bind('prod_workzone_search');
$controllers->get('/Browse/Basket/{basket_id}/', 'controller.prod.workzone:browseBasket')
$controllers->get('/Browse/Basket/{basket}/', 'controller.prod.workzone:browseBasket')
->bind('prod_workzone_basket')
->assert('basket_id', '\d+');
->assert('basket', '\d+');
$controllers->post('/attachStories/', 'controller.prod.workzone:attachStories');
@@ -113,12 +117,8 @@ class WorkZone implements ControllerProviderInterface
return $app['twig']->render('prod/WorkZone/Browser/Results.html.twig', $params);
}
public function browseBasket(Application $app, Request $request, $basket_id)
public function browseBasket(Application $app, Request $request, Basket $basket)
{
$basket = $app['EM']
->getRepository('Alchemy\Phrasea\Model\Entities\Basket')
->findUserBasket($app, $basket_id, $app['authentication']->getUser(), false);
return $app['twig']->render('prod/WorkZone/Browser/Basket.html.twig', array('Basket' => $basket));
}

View File

@@ -206,9 +206,8 @@ class RecordsRequest extends ArrayCollection
$basket = null;
if ($request->get('ssel')) {
$repository = $app['EM']->getRepository('Alchemy\Phrasea\Model\Entities\Basket');
$basket = $repository->findUserBasket($app, $request->get('ssel'), $app['authentication']->getUser(), false);
$basket = $app['converter.basket']->convert($request->get('ssel'));
$app['acl.basket']->hasAccess($basket, $app['authentication']->getUser());
foreach ($basket->getElements() as $basket_element) {
$received[$basket_element->getRecord($app)->get_serialize_key()] = $basket_element->getRecord($app);

View File

@@ -852,7 +852,7 @@ class Login implements ControllerProviderInterface
'ssel_id' => $basketId,
'from' => $validationSession->getInitiatorId(),
'validate_id' => $validationSession->getId(),
'url' => $app->url('lightbox_validation', array('ssel_id' => $basketId, 'LOG' => $token)),
'url' => $app->url('lightbox_validation', array('basket' => $basketId, 'LOG' => $token)),
));
$participant->setReminded(new \DateTime('now'));

View File

@@ -0,0 +1,47 @@
<?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\Middleware;
use Silex\Application;
use Silex\ServiceProviderInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
class BasketMiddlewareProvider implements ServiceProviderInterface
{
public function register(Application $app)
{
$app['middleware.basket.converter'] = $app->protect(function (Request $request, Application $app) {
if ($request->attributes->has('basket')) {
$request->attributes->set('basket', $app['converter.basket']->convert($request->attributes->get('basket')));
}
});
$app['middleware.basket.user-access'] = $app->protect(function (Request $request, Application $app) {
if ($request->attributes->has('basket')) {
if (!$app['acl.basket']->hasAccess($request->attributes->get('basket'), $app['authentication']->getUser())) {
throw new AccessDeniedHttpException('Current user does not have access to the basket');
}
}
});
$app['middleware.basket.user-is-owner'] = $app->protect(function (Request $request, Application $app) {
if (!$app['acl.basket']->isOwner($request->attributes->get('basket'), $app['authentication']->getUser())) {
throw new AccessDeniedHttpException('Only basket owner can modify the basket');
}
});
}
public function boot(Application $app)
{
}
}

View File

@@ -0,0 +1,30 @@
<?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\Provider;
use Alchemy\Phrasea\ACL\BasketACL;
use Silex\Application;
use Silex\ServiceProviderInterface;
class ACLServiceProvider implements ServiceProviderInterface
{
public function register(Application $app)
{
$app['acl.basket'] = $app->share(function ($app) {
return new BasketACL();
});
}
public function boot(Application $app)
{
}
}

View File

@@ -11,6 +11,7 @@
namespace Alchemy\Phrasea\Core\Provider;
use Alchemy\Phrasea\Model\Converter\BasketConverter;
use Alchemy\Phrasea\Model\Converter\TaskConverter;
use Silex\Application;
use Silex\ServiceProviderInterface;
@@ -22,6 +23,10 @@ class ConvertersServiceProvider implements ServiceProviderInterface
$app['converter.task'] = $app->share(function ($app) {
return new TaskConverter($app['EM']);
});
$app['converter.basket'] = $app->share(function ($app) {
return new BasketConverter($app['EM']);
});
}
public function boot(Application $app)

View File

@@ -113,10 +113,8 @@ class Helper extends \Alchemy\Phrasea\Helper\Helper
$this->selection = new \set_selection($app);
if (trim($Request->get('ssel')) !== '') {
$repository = $app['EM']->getRepository('Alchemy\Phrasea\Model\Entities\Basket');
/* @var $$repository Alchemy\Phrasea\Model\\Repositories\BasketRepository */
$Basket = $repository->findUserBasket($this->app, $Request->get('ssel'), $app['authentication']->getUser(), false);
$Basket = $app['converter.basket']->convert($Request->get('ssel'));
$app['acl.basket']->hasAccess($Basket, $app['authentication']->getUser());
$this->selection->load_basket($Basket);

View File

@@ -0,0 +1,40 @@
<?php
/*
* This file is part of Phraseanet
*
* (c) 2005-2010 Alchemy
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Alchemy\Phrasea\Model\Converter;
use Alchemy\Phrasea\Model\Entities\Basket;
use Doctrine\Common\Persistence\ObjectManager;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
class BasketConverter implements ConverterInterface
{
private $om;
public function __construct(ObjectManager $om)
{
$this->om = $om;
}
/**
* {@inheritdoc}
*
* @return Basket
*/
public function convert($id)
{
if (null === $basket = $this->om->find('Alchemy\Phrasea\Model\Entities\Basket', (int) $id)) {
throw new NotFoundHttpException(sprintf('Basket %s not found.', $id));
}
return $basket;
}
}

View File

@@ -119,51 +119,6 @@ class BasketRepository extends EntityRepository
return $query->getResult();
}
/**
* Find a basket specified by his basket_id and his owner
*
* @throws NotFoundHttpException
* @throws AccessDeniedHttpException
* @param type $basket_id
* @param \User_Adapter $user
* @return Basket
*/
public function findUserBasket(Application $app, $basket_id, \User_Adapter $user, $requireOwner)
{
$dql = 'SELECT b
FROM Alchemy\Phrasea\Model\Entities\Basket b
LEFT JOIN b.elements e
WHERE b.id = :basket_id';
$query = $this->_em->createQuery($dql);
$query->setParameters(array('basket_id' => $basket_id));
$basket = $query->getOneOrNullResult();
/* @var $basket Basket */
if (null === $basket) {
throw new NotFoundHttpException(_('Basket is not found'));
}
if ($basket->getOwner($app)->get_id() != $user->get_id()) {
$participant = false;
if ($basket->getValidation() && !$requireOwner) {
try {
$basket->getValidation()->getParticipant($user, $app);
$participant = true;
} catch (\Exception $e) {
}
}
if (!$participant) {
throw new AccessDeniedHttpException(_('You have not access to this basket'));
}
}
return $basket;
}
public function findContainingRecordForUser(\record_adapter $record, \User_Adapter $user)
{

View File

@@ -9,6 +9,7 @@
* file that was distributed with this source code.
*/
use Alchemy\Phrasea\Model\Entities\Basket;
use Symfony\Component\HttpFoundation\Request;
use Silex\Application;
@@ -203,7 +204,7 @@ interface API_V1_Interface
* BASKET_ID : required INT
*
*/
public function delete_basket(Request $request, $basket_id);
public function delete_basket(Request $request, Basket $basket);
/**
* Route : /baskets/BASKET_ID/content/FORMAT/
@@ -214,7 +215,7 @@ interface API_V1_Interface
* BASKET_ID : required INT
*
*/
public function get_basket(Request $request, $basket_id);
public function get_basket(Request $request, Basket $basket);
/**
* Route : /baskets/BASKET_ID/title/FORMAT/
@@ -225,7 +226,7 @@ interface API_V1_Interface
* BASKET_ID : required INT
*
*/
public function set_basket_title(Request $request, $basket_id);
public function set_basket_title(Request $request, Basket $basket);
/**
* Route : /baskets/BASKET_ID/description/FORMAT/
@@ -236,7 +237,7 @@ interface API_V1_Interface
* BASKET_ID : required INT
*
*/
public function set_basket_description(Request $request, $basket_id);
public function set_basket_description(Request $request, Basket $basket);
/**
* Route : /publications/list/FORMAT/

View File

@@ -1297,17 +1297,12 @@ class API_V1_adapter extends API_V1_Abstract
* Delete a basket
*
* @param Request $request
* @param int $basket_id
* @param Basket $basket
* @return array
*/
public function delete_basket(Request $request, $basket_id)
public function delete_basket(Request $request, Basket $basket)
{
$repository = $this->app['EM']->getRepository('Alchemy\Phrasea\Model\Entities\Basket');
/* @var $repository Alchemy\Phrasea\Model\Repositories\BasketRepository */
$Basket = $repository->findUserBasket($this->app, $basket_id, $this->app['authentication']->getUser(), true);
$this->app['EM']->remove($Basket);
$this->app['EM']->remove($basket);
$this->app['EM']->flush();
return $this->search_baskets($request);
@@ -1317,23 +1312,17 @@ class API_V1_adapter extends API_V1_Abstract
* Retrieve a basket
*
* @param Request $request
* @param int $basket_id
* @param Basket $basket
* @return API_V1_result
*/
public function get_basket(Request $request, $basket_id)
public function get_basket(Request $request, Basket $basket)
{
$result = new API_V1_result($this->app, $request, $this);
$repository = $this->app['EM']->getRepository('Alchemy\Phrasea\Model\Entities\Basket');
/* @var $repository Alchemy\Phrasea\Model\Repositories\BasketRepository */
$Basket = $repository->findUserBasket($this->app, $basket_id, $this->app['authentication']->getUser(), false);
$result->set_datas(
array(
"basket" => $this->list_basket($Basket),
"basket_elements" => $this->list_basket_content($Basket)
"basket" => $this->list_basket($basket),
"basket_elements" => $this->list_basket_content($basket)
)
);
@@ -1414,26 +1403,19 @@ class API_V1_adapter extends API_V1_Abstract
* Change the name of one basket
*
* @param Request $request
* @param int $basket_id
* @param Basket $basket
* @return API_V1_result
*/
public function set_basket_title(Request $request, $basket_id)
public function set_basket_title(Request $request, Basket $basket)
{
$result = new API_V1_result($this->app, $request, $this);
$name = $request->get('name');
$basket->setName($request->get('name'));
$repository = $this->app['EM']->getRepository('Alchemy\Phrasea\Model\Entities\Basket');
/* @var $repository Alchemy\Phrasea\Model\Repositories\BasketRepository */
$Basket = $repository->findUserBasket($this->app, $basket_id, $this->app['authentication']->getUser(), true);
$Basket->setName($name);
$this->app['EM']->merge($Basket);
$this->app['EM']->persist($basket);
$this->app['EM']->flush();
$result->set_datas(array("basket" => $this->list_basket($Basket)));
$result->set_datas(array("basket" => $this->list_basket($basket)));
return $result;
}
@@ -1442,26 +1424,19 @@ class API_V1_adapter extends API_V1_Abstract
* Change the description of one basket
*
* @param Request $request
* @param type $basket_id
* @param Basket $basket
* @return API_V1_result
*/
public function set_basket_description(Request $request, $basket_id)
public function set_basket_description(Request $request, Basket $basket)
{
$result = new API_V1_result($this->app, $request, $this);
$desc = $request->get('description');
$basket->setDescription($request->get('description'));
$repository = $this->app['EM']->getRepository('Alchemy\Phrasea\Model\Entities\Basket');
/* @var $repository Alchemy\Phrasea\Model\Repositories\BasketRepository */
$Basket = $repository->findUserBasket($this->app, $basket_id, $this->app['authentication']->getUser(), true);
$Basket->setDescription($desc);
$this->app['EM']->merge($Basket);
$this->app['EM']->persist($basket);
$this->app['EM']->flush();
$result->set_datas(array("basket" => $this->list_basket($Basket)));
$result->set_datas(array("basket" => $this->list_basket($basket)));
return $result;
}

View File

@@ -114,7 +114,7 @@ class eventsmanager_notify_orderdeliver extends eventsmanager_notifyAbstract
if ($readyToSend) {
$url = $this->app->url('lightbox_compare', array(
'ssel_id' => $basket->getId(),
'basket' => $basket->getId(),
'LOG' => $this->app['tokens']->getUrlToken(
\random::TYPE_VIEW,
$user_to->get_id(),
@@ -159,9 +159,7 @@ class eventsmanager_notify_orderdeliver extends eventsmanager_notifyAbstract
$sender = User_Adapter::getInstance($from, $this->app)->get_display_name();
try {
$repository = $this->app['EM']->getRepository('Alchemy\Phrasea\Model\Entities\Basket');
$basket = $repository->findUserBasket($this->app, $ssel_id, $this->app['authentication']->getUser(), false);
$basket = $this->app['converter.basket']->convert($ssel_id);
} catch (Exception $e) {
return array();
}

View File

@@ -146,17 +146,14 @@ class eventsmanager_notify_validate extends eventsmanager_notifyAbstract
$sender = User_Adapter::getInstance($from, $this->app)->get_display_name();
try {
$repository = $this->app['EM']->getRepository('Alchemy\Phrasea\Model\Entities\Basket');
$basket = $repository->findUserBasket($this->app, $ssel_id, $this->app['authentication']->getUser(), false);
$basket = $this->app['converter.basket']->convert($ssel_id);
$basket_name = trim($basket->getName()) ? : _('Une selection');
} catch (Exception $e) {
$basket_name = _('Une selection');
}
$bask_link = '<a href="'
. $this->app->url('lightbox_validation', array('ssel_id' => (string) $sx->ssel_id))
. $this->app->url('lightbox_validation', array('basket' => (string) $sx->ssel_id))
. '" target="_blank">'
. $basket_name . '</a>';

View File

@@ -140,9 +140,7 @@ class eventsmanager_notify_validationdone extends eventsmanager_notifyAbstract
$sender = $registered_user->get_display_name();
try {
$repository = $this->app['EM']->getRepository('Alchemy\Phrasea\Model\Entities\Basket');
$basket = $repository->findUserBasket($this->app, $ssel_id, $this->app['authentication']->getUser(), false);
$basket = $this->app['converter.basket']->convert($ssel_id);
} catch (Exception $e) {
return array();
}

View File

@@ -145,10 +145,7 @@ class eventsmanager_notify_validationreminder extends eventsmanager_notifyAbstra
$sender = User_Adapter::getInstance($from, $this->app)->get_display_name();
try {
$repository = $this->app['EM']->getRepository('Alchemy\Phrasea\Model\Entities\Basket');
$basket = $repository->findUserBasket($this->app, $ssel_id, $this->app['authentication']->getUser(), false);
$basket = $this->app['converter.basket']->convert($ssel_id);
$basket_name = trim($basket->getName()) ? : _('Une selection');
} catch (Exception $e) {
$basket_name = _('Une selection');

View File

@@ -144,10 +144,8 @@ class record_preview extends record_adapter
break;
case "BASK":
$repository = $app['EM']->getRepository('Alchemy\Phrasea\Model\Entities\Basket');
/* @var $repository Alchemy\Phrasea\Model\Repositories\BasketRepository */
$Basket = $repository->findUserBasket($app, $contId, $app['authentication']->getUser(), false);
$Basket = $app['converter.basket']->convert($contId);
$app['acl.basket']->hasAccess($Basket, $app['authentication']->getUser());
/* @var $Basket Basket */
$this->container = $Basket;

View File

@@ -58,10 +58,9 @@ class set_export extends set_abstract
}
if ($sstid != "") {
$repository = $app['EM']->getRepository('Alchemy\Phrasea\Model\Entities\Basket');
$Basket = $app['converter.basket']->convert($sstid);
$app['acl.basket']->hasAccess($Basket, $app['authentication']->getUser());
/* @var $repository Alchemy\Phrasea\Model\Repositories\BasketRepository */
$Basket = $repository->findUserBasket($this->app, $sstid, $app['authentication']->getUser(), false);
$this->exportName = str_replace(array(' ', '\\', '/'), '_', $Basket->getName()) . "_" . date("Y-n-d");
foreach ($Basket->getElements() as $basket_element) {

View File

@@ -29,7 +29,7 @@
{% set record = basket_element.getRecord(app) %}
<div data-role="page" id="page">
<div data-role="header">
<a href="{{ path('lightbox_validation', { 'ssel_id' : basket_element.getBasket().getId() }) }}" data-rel="back" data-icon="arrow-l">Back</a>
<a href="{{ path('lightbox_validation', { 'basket' : basket_element.getBasket().getId() }) }}" data-rel="back" data-icon="arrow-l">Back</a>
<h1>{{basket_element.getOrd()}} - {{record.get_title()}}</h1>
<a rel="external" href="{{ path('lightbox') }}" data-icon="home" data-iconpos="notext" data-direction="reverse" class="ui-btn-right jqm-home">Home</a>
</div>

View File

@@ -94,7 +94,7 @@
{% if basket.getElements().first() %}
<img src="{{ basket.getElements().first().getRecord(app).get_thumbnail.get_url()}}" />
{% endif %}
<h3><a href="{{ path('lightbox_validation', { 'ssel_id' : basket.getId() }) }}">{{basket.getName()}}</a></h3>
<h3><a href="{{ path('lightbox_validation', { 'basket' : basket.getId() }) }}">{{basket.getName()}}</a></h3>
<p>{{ basket.getDescription() }}</p>
<span class="ui-li-count">{{ basket_length }}</span>
</li>
@@ -123,7 +123,7 @@
{% if basket.getElements().first() %}
<img src="{{ basket.getElements().first().getRecord(app).get_thumbnail.get_url()}}" />
{% endif %}
<h3><a href="{{ path('lightbox_validation', { 'ssel_id' : basket.getId() }) }}">{{ basket.getName() }}</a></h3>
<h3><a href="{{ path('lightbox_validation', { 'basket' : basket.getId() }) }}">{{ basket.getName() }}</a></h3>
<p>{{ basket.getDescription() }}</p>
<span class="ui-li-count">{{basket_length}}</span>
</li>

View File

@@ -9,7 +9,7 @@
</select>
<button type="button" class="autoorder btn btn-inverse">{% trans 'Re-ordonner' %}</button>
<button type="button" class="reverseorder btn btn-inverse">{% trans 'Inverser' %}</button>
<form name="reorder" method="POST" action="{{ path('prod_baskets_basket_reorder', { 'basket_id' : basket.getId() }) }}" style="display:inline;">
<form name="reorder" method="POST" action="{{ path('prod_baskets_basket_reorder', { 'basket' : basket.getId() }) }}" style="display:inline;">
{% for element in basket.getElements() %}
<input type="hidden" name="element[{{ element.getId() }}]" value="{{ element.getOrd() }}"/>
{% endfor %}

View File

@@ -1,5 +1,5 @@
<div>
<form action="{{ path('prod_baskets_basket_update', { 'basket_id' : basket.getId()}) }}" method="POST" id="basket-rename-box">
<form action="{{ path('prod_baskets_basket_update', { 'basket' : basket.getId()}) }}" method="POST" id="basket-rename-box">
<label style="margin:5px 0 0 0;">{% trans 'panier:: nom' %}</label>
<input type="text" name="name" value="{{ basket.getName() }}" style="width:98%;" />
<label style="margin:5px 0 0 0;">{% trans 'panier:: description' %}</label>

View File

@@ -12,12 +12,12 @@
<h1 class="title">
<img class="loader" src="/skins/prod/Basket/Browser/loader.gif" />
{% if Basket.getValidation() is empty or Basket.getValidation().isInitiator(app['authentication'].getUser()) %}
<a href="{{ path('prod_baskets_basket_archive', { 'basket_id' : Basket.getId(), 'archive' : 1 }) }}" class="archiver archive_toggler" style="display:{{ Basket.getArchived ? 'none' : '' }};">
<a href="{{ path('prod_baskets_basket_archive', { 'basket' : Basket.getId(), 'archive' : 1 }) }}" class="archiver archive_toggler" style="display:{{ Basket.getArchived ? 'none' : '' }};">
<span>
<img src="/skins/prod/Basket/Browser/archive.png"/>
</span>
</a>
<a href="{{ path('prod_baskets_basket_archive', { 'basket_id' : Basket.getId(), 'archive' : 0 }) }}" class="unarchiver archive_toggler" style="display:{{ Basket.getArchived ? '' : 'none' }};">
<a href="{{ path('prod_baskets_basket_archive', { 'basket' : Basket.getId(), 'archive' : 0 }) }}" class="unarchiver archive_toggler" style="display:{{ Basket.getArchived ? '' : 'none' }};">
<span>
<img src="/skins/prod/Basket/Browser/archived.png"/>
</span>

View File

@@ -34,7 +34,7 @@
<div class="PNB" style="right:10px">
{% for Basket in Baskets %}
<div class="result {% if loop.index is odd %}odd{% endif %}">
<a href="{{ path('basket_delete', {basket_id: Basket.getId()}) }}" class="delete-basket close" title="{% trans %}Delete basket{% endtrans %}" style="color:#fff;padding:2px">×</a>
<a href="{{ path('basket_delete', {basket: Basket.getId()}) }}" class="delete-basket close" title="{% trans %}Delete basket{% endtrans %}" style="color:#fff;padding:2px">×</a>
<div class="PNB10" style="right:15px;">
<table>
<tr>
@@ -51,18 +51,18 @@
<h1 class="title">
<img class="loader" src="/skins/prod/Basket/Browser/loader.gif" />
{% if Basket.getValidation() is empty or Basket.getValidation().isInitiator(app['authentication'].getUser()) %}
<a href="{{ path('prod_baskets_basket_archive', { 'basket_id' : Basket.getId(), 'archive' : 1 }) }}" class="archiver archive_toggler" style="display:{{ Basket.getArchived ? 'none' : '' }};">
<a href="{{ path('prod_baskets_basket_archive', { 'basket' : Basket.getId(), 'archive' : 1 }) }}" class="archiver archive_toggler" style="display:{{ Basket.getArchived ? 'none' : '' }};">
<span>
<img src="/skins/prod/Basket/Browser/archive.png"/>
</span>
</a>
<a href="{{ path('prod_baskets_basket_archive', { 'basket_id' : Basket.getId(), 'archive' : 0 }) }}" class="unarchiver archive_toggler" style="display:{{ Basket.getArchived ? '' : 'none' }};">
<a href="{{ path('prod_baskets_basket_archive', { 'basket' : Basket.getId(), 'archive' : 0 }) }}" class="unarchiver archive_toggler" style="display:{{ Basket.getArchived ? '' : 'none' }};">
<span>
<img src="/skins/prod/Basket/Browser/archived.png"/>
</span>
</a>
{% endif %}
<a class="basket_link" href="{{ path('prod_workzone_basket', { basket_id : Basket.getId() }) }}">
<a class="basket_link" href="{{ path('prod_workzone_basket', { basket : Basket.getId() }) }}">
{{ Basket.getName() }}
</a>
</h1>

View File

@@ -11,12 +11,12 @@
{% for basket in content.get(constant('\\Alchemy\\Phrasea\\Helper\\WorkZone::VALIDATIONS')) %}
<div tooltipsrc="{{ path('prod_tooltip_basket', { 'basket_id' : basket.getId() }) }}"
<div tooltipsrc="{{ path('prod_tooltip_basket', { 'basket' : basket.getId() }) }}"
id="SSTT_{{basket.getId()}}"
class="basketTips ui-accordion-header ui-state-default
ui-corner-all header SSTT basket {% if not basket.getIsRead() %}unread{% endif %}
{% if basket.getId() == selected_id and selected_type == 'basket' %}active{% endif %}">
<a class="workzone-menu-title" href="{{ path('prod_baskets_basket', { 'basket_id' : basket.getId() }) }}">
<a class="workzone-menu-title" href="{{ path('prod_baskets_basket', { 'basket' : basket.getId() }) }}">
<span>
<img src='/skins/icons/basket.gif' title=''/>
{{basket.getName()}}
@@ -55,13 +55,13 @@
</div>
<div title="" class="context-menu-item">
<div class="context-menu-item-inner">
<a href="{{ path('lightbox_compare', { 'ssel_id' : basket.getId() }) }}" target="_blank">Lightbox</a>
<a href="{{ path('lightbox_compare', { 'basket' : basket.getId() }) }}" target="_blank">Lightbox</a>
</div>
</div>
{% if basket.getValidation() %}
<div title="" class="context-menu-item">
<a target="_blank" href="{{ path('lightbox_validation', { 'ssel_id' : basket.getId() }) }}">
<a target="_blank" href="{{ path('lightbox_validation', { 'basket' : basket.getId() }) }}">
<div class="context-menu-item-inner">
{% trans 'action::Valider' %}
</div>
@@ -86,12 +86,12 @@
{% for basket in content.get(constant('\\Alchemy\\Phrasea\\Helper\\WorkZone::BASKETS')) %}
<div tooltipsrc="{{ path('prod_tooltip_basket', { 'basket_id' : basket.getId() }) }}"
<div tooltipsrc="{{ path('prod_tooltip_basket', { 'basket' : basket.getId() }) }}"
id="SSTT_{{basket.getId()}}"
class="basketTips ui-accordion-header ui-state-default
ui-corner-all header SSTT basket {% if not basket.getIsRead() %}unread{% endif %}
{% if basket.getId() == selected_id and selected_type == 'basket' %}active{% endif %}">
<a class="workzone-menu-title" href="{{ path('prod_baskets_basket', { 'basket_id' : basket.getId() }) }}" style="">
<a class="workzone-menu-title" href="{{ path('prod_baskets_basket', { 'basket' : basket.getId() }) }}" style="">
<span>
<img src='/skins/icons/basket.gif' title=''/>
{{basket.getName()}}
@@ -140,12 +140,12 @@
</div>
<div title="" class="context-menu-item">
<div class="context-menu-item-inner">
<a href="{{ path('lightbox_compare', { 'ssel_id' : basket.getId() }) }}" target="_blank">Lightbox</a>
<a href="{{ path('lightbox_compare', { 'basket' : basket.getId() }) }}" target="_blank">Lightbox</a>
</div>
</div>
<div title="" class="context-menu-item">
<div class="context-menu-item-inner">
<a class="dialog small-dialog" title="{% trans 'action::renommer' %}" href="{{ path('prod_baskets_basket_update', { 'basket_id' : basket.getId()}) }}">
<a class="dialog small-dialog" title="{% trans 'action::renommer' %}" href="{{ path('prod_baskets_basket_update', { 'basket' : basket.getId()}) }}">
{% trans 'action::renommer' %}
</a>
</div>
@@ -153,7 +153,7 @@
{% if basket.getValidation() %}
<div title="" class="context-menu-item">
<a target="_blank" href="{{ path('lightbox_validation', { 'ssel_id' : basket.getId() }) }}">
<a target="_blank" href="{{ path('lightbox_validation', { 'basket' : basket.getId() }) }}">
<div class="context-menu-item-inner">
{% trans 'action::Valider' %}
</div>
@@ -176,7 +176,7 @@
<div title="" class="context-menu-item">
<div class="context-menu-item-inner">
<a class="dialog" title="{% trans 'Re-ordonner' %}" href="{{ path('prod_baskets_basket_reorder', { 'basket_id' : basket.getId() }) }}">
<a class="dialog" title="{% trans 'Re-ordonner' %}" href="{{ path('prod_baskets_basket_reorder', { 'basket' : basket.getId() }) }}">
{% trans 'Re-ordonner' %}
</a>
</div>
@@ -310,7 +310,7 @@
href="{{ path('prod_stories_story_remove_element', { 'sbas_id' : container.get_sbas_id(), 'record_id' : container.get_record_id(), 'child_sbas_id' : record.get_sbas_id(), 'child_record_id' : record.get_record_id() }) }}"
{% elseif wz_scope == 'basket' %}
id="WZEL_{{ container.getId() }}_{{ record.get_sbas_id() }}_{{ record.get_record_id() }}"
href="{{ path('prod_baskets_basket_element_remove', { 'basket_id' : container.getId(), 'basket_element_id' : contained.getId()}) }}"
href="{{ path('prod_baskets_basket_element_remove', { 'basket' : container.getId(), 'basket_element_id' : contained.getId()}) }}"
{% elseif wz_scope == 'basket' %}
href="#"
{% endif %}

View File

@@ -10,7 +10,7 @@
class="baskDeleter WorkZoneElementRemover" title="{% trans 'Remove from basket' %}"
data-context="reg_train_basket"
onclick="remove_from_basket($(this), false);return false;"
href="{{ path('prod_baskets_basket_element_remove', { 'basket_id' : record.get_container().getId(), 'basket_element_id' : record.get_original_item().getId()}) }}">
href="{{ path('prod_baskets_basket_element_remove', { 'basket' : record.get_container().getId(), 'basket_element_id' : record.get_original_item().getId()}) }}">
</a>
{% endif %}

View File

@@ -0,0 +1,64 @@
<?php
namespace Alchemy\Tests\Phrasea\ACL;
use Alchemy\Phrasea\ACL\BasketACL;
class BasketACLTest extends \PhraseanetPHPUnitAbstract
{
public function testOwnerIsOwner()
{
$basket = $this->insertOneBasketEnv();
$acl = new BasketACL();
$this->assertTrue($acl->isOwner($basket, self::$DI['user']));
}
public function testParticipantIsNotAnOwner()
{
$basket = $this->insertOneBasketEnv();
$acl = new BasketACL();
$this->assertFalse($acl->isOwner($basket, self::$DI['user_alt1']));
}
public function testUserIsNotTheOwner()
{
$basket = $this->insertOneBasket();
$acl = new BasketACL();
$this->assertFalse($acl->isOwner($basket, self::$DI['user_alt1']));
}
public function testOwnerHasAccessInValidationEnv()
{
$basket = $this->insertOneBasketEnv();
$acl = new BasketACL();
$this->assertTrue($acl->hasAccess($basket, self::$DI['user']));
}
public function testOwnerHasAccess()
{
$basket = $this->insertOneBasket();
$acl = new BasketACL();
$this->assertTrue($acl->hasAccess($basket, self::$DI['user']));
}
public function testParticipantHasAccess()
{
$basket = $this->insertOneBasketEnv();
$acl = new BasketACL();
$this->assertTrue($acl->hasAccess($basket, self::$DI['user_alt1']));
}
public function testUserHasNotAccess()
{
$basket = $this->insertOneBasket();
$acl = new BasketACL();
$this->assertFalse($acl->hasAccess($basket, self::$DI['user_alt1']));
}
}

View File

@@ -3,6 +3,8 @@
namespace Alchemy\Tests\Phrasea\Controller\Prod;
use Alchemy\Phrasea\Application;
use Alchemy\Phrasea\Model\Entities\Basket;
use Alchemy\Phrasea\Model\Entities\BasketElement;
class ControllerBasketTest extends \PhraseanetWebTestCaseAuthenticatedAbstract
{
@@ -57,7 +59,6 @@ class ControllerBasketTest extends \PhraseanetWebTestCaseAuthenticatedAbstract
$result = $query->getResult();
$basket = array_shift($result);
/* @var $basket \Alchemy\Phrasea\Model\Entities\Basket */
$this->assertEquals(2, $basket->getElements()->count());
}
@@ -96,7 +97,6 @@ class ControllerBasketTest extends \PhraseanetWebTestCaseAuthenticatedAbstract
$crawler = self::$DI['client']->request('GET', $route);
$response = self::$DI['client']->getResponse();
$this->assertEquals(200, $response->getStatusCode());
$filter = "form[action='/prod/baskets/']";
@@ -112,48 +112,39 @@ class ControllerBasketTest extends \PhraseanetWebTestCaseAuthenticatedAbstract
public function testBasketGet()
{
$basket = $this->insertOneBasket();
$route = sprintf('/prod/baskets/%s/', $basket->getId());
$crawler = self::$DI['client']->request('GET', $route);
self::$DI['client']->request('GET', $route);
$response = self::$DI['client']->getResponse();
$this->assertEquals(200, $response->getStatusCode());
}
public function testBasketGetAccessDenied()
{
$basket = $this->insertOneBasket(self::$DI['user_alt1']);
$route = sprintf('/prod/baskets/%s/', $basket->getId());
self::$DI['client']->request('GET', $route);
$response = self::$DI['client']->getResponse();
$this->assertEquals(403, $response->getStatusCode());
}
public function testBasketDeleteElementPost()
{
$basket = $this->insertOneBasket();
$basketElement = $this->insertOneBasketElement();
$basket = $basketElement->getBasket();
$record = self::$DI['record_1'];
$basket_element = new \Alchemy\Phrasea\Model\Entities\BasketElement();
$basket_element->setBasket($basket);
$basket_element->setRecord($record);
$basket_element->setLastInBasket();
$basket->addElement($basket_element);
self::$DI['app']['EM']->persist($basket);
self::$DI['app']['EM']->flush();
$this->assertEquals(1, $basket->getElements()->count());
$route = sprintf(
"/prod/baskets/%s/delete/%s/", $basket->getId(), $basket_element->getId()
"/prod/baskets/%s/delete/%s/", $basket->getId(), $basketElement->getId()
);
$crawler = self::$DI['client']->request('POST', $route);
self::$DI['client']->request('POST', $route);
$response = self::$DI['client']->getResponse();
self::$DI['app']['EM']->refresh($basket);
$this->assertEquals(302, $response->getStatusCode());
$this->assertEquals(0, $basket->getElements()->count());
}
public function testBasketDeleteElementPostJSON()
public function testBasketDeldeteElementPostJSON()
{
$basket = $this->insertOneBasket();
@@ -173,60 +164,51 @@ class ControllerBasketTest extends \PhraseanetWebTestCaseAuthenticatedAbstract
"/prod/baskets/%s/delete/%s/", $basket->getId(), $basket_element->getId()
);
$crawler = self::$DI['client']->request(
self::$DI['client']->request(
'POST', $route, array(), array(), array(
"HTTP_ACCEPT" => "application/json")
);
$response = self::$DI['client']->getResponse();
self::$DI['app']['EM']->refresh($basket);
$this->assertEquals(200, $response->getStatusCode());
$this->assertEquals(0, $basket->getElements()->count());
}
public function testBasketDeletePostUnauthorized()
{
$basket = $this->insertOneBasket(self::$DI['user_alt1']);
$route = sprintf('/prod/baskets/%s/delete/', $basket->getId());
self::$DI['client']->request('POST', $route);
$response = self::$DI['client']->getResponse();
$this->assertEquals(403, $response->getStatusCode());
$query = self::$DI['app']['EM']->createQuery('SELECT COUNT(b.id) FROM \Alchemy\Phrasea\Model\Entities\Basket b');
$count = $query->getSingleScalarResult();
$this->assertEquals(1, $count);
}
public function testBasketDeletePost()
{
$basket = $this->insertOneBasket();
$route = sprintf('/prod/baskets/%s/delete/', $basket->getId());
$crawler = self::$DI['client']->request('POST', $route);
self::$DI['client']->request('POST', $route);
$response = self::$DI['client']->getResponse();
$query = self::$DI['app']['EM']->createQuery('SELECT COUNT(b.id) FROM \Alchemy\Phrasea\Model\Entities\Basket b');
$count = $query->getSingleScalarResult();
$this->assertEquals(0, $count);
$this->assertEquals(302, $response->getStatusCode());
}
public function testBasketDeletePostJSON()
{
$basket = $this->insertOneBasket();
$route = sprintf('/prod/baskets/%s/delete/', $basket->getId());
$crawler = self::$DI['client']->request(
'POST', $route, array(), array(), array(
"HTTP_ACCEPT" => "application/json")
);
self::$DI['client']->getRequest()->setRequestFormat('json');
self::$DI['client']->request('POST', $route, array(), array(), array("HTTP_ACCEPT" => "application/json"));
$response = self::$DI['client']->getResponse();
$query = self::$DI['app']['EM']->createQuery('SELECT COUNT(b.id) FROM \Alchemy\Phrasea\Model\Entities\Basket b');
$count = $query->getSingleScalarResult();
$this->assertEquals(0, $count);
$this->assertEquals(200, $response->getStatusCode());
}
@@ -236,29 +218,24 @@ class ControllerBasketTest extends \PhraseanetWebTestCaseAuthenticatedAbstract
$route = sprintf('/prod/baskets/%s/update/', $basket->getId());
$crawler = self::$DI['client']->request(
self::$DI['client']->request(
'POST', $route, array(
'name' => 'new_name',
'description' => 'new_desc')
);
$response = self::$DI['client']->getResponse();
$basket = self::$DI['app']['EM']->getRepository('Alchemy\Phrasea\Model\Entities\Basket')->find($basket->getId());
$this->assertEquals('new_name', $basket->getName());
$this->assertEquals('new_desc', $basket->getDescription());
$this->assertEquals(302, $response->getStatusCode());
}
public function testBasketUpdatePostJSON()
{
$basket = $this->insertOneBasket();
$route = sprintf('/prod/baskets/%s/update/', $basket->getId());
$crawler = self::$DI['client']->request(
self::$DI['client']->request(
'POST', $route, array(
'name' => 'new_name',
'description' => 'new_desc'
@@ -267,12 +244,8 @@ class ControllerBasketTest extends \PhraseanetWebTestCaseAuthenticatedAbstract
);
$response = self::$DI['client']->getResponse();
$basket = self::$DI['app']['EM']->getRepository('Alchemy\Phrasea\Model\Entities\Basket')->find($basket->getId());
$this->assertEquals('new_name', $basket->getName());
$this->assertEquals('new_desc', $basket->getDescription());
$this->assertEquals(200, $response->getStatusCode());
}
@@ -283,13 +256,11 @@ class ControllerBasketTest extends \PhraseanetWebTestCaseAuthenticatedAbstract
$route = sprintf("/prod/baskets/%s/reorder/", $basket->getId());
$crawler = self::$DI['client']->request("GET", $route);
$response = self::$DI['client']->getResponse();
$this->assertEquals(200, $response->getStatusCode());
foreach ($basket->getElements() as $elements) {
$filter = sprintf("form[action='/prod/baskets/%s/reorder/']", $elements->getId());
$filter = sprintf("form[action='/prod/baskets/%s/reorder/'] input[name='element[%s]']", $basket->getId(), $elements->getId());
$this->assertEquals(1, $crawler->filter($filter)->count());
}
}
@@ -307,46 +278,27 @@ class ControllerBasketTest extends \PhraseanetWebTestCaseAuthenticatedAbstract
);
$response = self::$DI['client']->getResponse();
$this->assertEquals(200, $response->getStatusCode());
$filter = "form[action='/prod/baskets/" . $basket->getId() . "/update/']";
$this->assertEquals($crawler->filter($filter)->count(), 1);
$node = $crawler
->filter('input[name=name]');
$node = $crawler->filter('input[name=name]');
$this->assertEquals($basket->getName(), $node->attr('value'));
$node = $crawler
->filter('textarea[name=description]');
$node = $crawler->filter('textarea[name=description]');
$this->assertEquals($basket->getDescription(), $node->text());
}
public function testBasketArchivedPost()
{
$basket = $this->insertOneBasket();
$route = sprintf('/prod/baskets/%s/archive/?archive=1', $basket->getId());
$crawler = self::$DI['client']->request('POST', $route);
$response = self::$DI['client']->getResponse();
$basket = self::$DI['app']['EM']->getRepository('Alchemy\Phrasea\Model\Entities\Basket')->find($basket->getId());
self::$DI['client']->request('POST', $route);
$this->assertTrue($basket->getArchived());
$route = sprintf('/prod/baskets/%s/archive/?archive=0', $basket->getId());
$crawler = self::$DI['client']->request('POST', $route);
self::$DI['client']->request('POST', $route);
$response = self::$DI['client']->getResponse();
self::$DI['app']['EM']->refresh($basket);
$this->assertFalse($basket->getArchived());
$this->assertEquals(302, $response->getStatusCode());
}
@@ -356,31 +308,24 @@ class ControllerBasketTest extends \PhraseanetWebTestCaseAuthenticatedAbstract
$route = sprintf('/prod/baskets/%s/archive/?archive=1', $basket->getId());
$crawler = self::$DI['client']->request(
self::$DI['client']->request(
'POST', $route, array(), array(), array(
"HTTP_ACCEPT" => "application/json"
)
);
$response = self::$DI['client']->getResponse();
$basket = self::$DI['app']['EM']->getRepository('Alchemy\Phrasea\Model\Entities\Basket')->find($basket->getId());
$this->assertTrue($basket->getArchived());
$route = sprintf('/prod/baskets/%s/archive/?archive=0', $basket->getId());
$crawler = self::$DI['client']->request(
self::$DI['client']->request(
'POST', $route, array(), array(), array(
"HTTP_ACCEPT" => "application/json"
)
);
$response = self::$DI['client']->getResponse();
self::$DI['app']['EM']->refresh($basket);
$this->assertFalse($basket->getArchived());
$this->assertEquals(200, $response->getStatusCode());
}
@@ -406,9 +351,6 @@ class ControllerBasketTest extends \PhraseanetWebTestCaseAuthenticatedAbstract
$response = self::$DI['client']->getResponse();
$this->assertEquals(302, $response->getStatusCode());
$basket = self::$DI['app']['EM']->getRepository('Alchemy\Phrasea\Model\Entities\Basket')->find($basket->getId());
$this->assertEquals(2, $basket->getElements()->count());
}
@@ -461,13 +403,8 @@ class ControllerBasketTest extends \PhraseanetWebTestCaseAuthenticatedAbstract
$response = self::$DI['client']->getResponse();
$this->assertEquals(302, $response->getStatusCode());
$basket = self::$DI['app']['EM']->getRepository('Alchemy\Phrasea\Model\Entities\Basket')->find($basket->getId());
$this->assertEquals(2, $basket->getElements()->count());
$datas = self::$DI['app']['EM']->getRepository('Alchemy\Phrasea\Model\Entities\ValidationData')->findAll();
$this->assertTrue($countDatas < count($datas), 'assert that ' . count($datas) . ' > ' . $countDatas);
}
@@ -484,7 +421,7 @@ class ControllerBasketTest extends \PhraseanetWebTestCaseAuthenticatedAbstract
$lst = implode(';', $records);
$crawler = self::$DI['client']->request(
self::$DI['client']->request(
'POST', $route, array(
'lst' => $lst
), array(), array(
@@ -494,8 +431,6 @@ class ControllerBasketTest extends \PhraseanetWebTestCaseAuthenticatedAbstract
$response = self::$DI['client']->getResponse();
$basket = self::$DI['app']['EM']->getRepository('Alchemy\Phrasea\Model\Entities\Basket')->find($basket->getId());
$this->assertEquals(200, $response->getStatusCode());
$this->assertEquals(2, $basket->getElements()->count());
@@ -521,13 +456,8 @@ class ControllerBasketTest extends \PhraseanetWebTestCaseAuthenticatedAbstract
$this->assertTrue($response->isRedirect());
$basket = self::$DI['app']['EM']->getRepository('Alchemy\Phrasea\Model\Entities\Basket')->find($Basket_1->getId());
$this->assertInstanceOf('\Alchemy\Phrasea\Model\Entities\Basket', $basket);
$this->assertEquals(0, $basket->getElements()->count());
$basket = self::$DI['app']['EM']->getRepository('Alchemy\Phrasea\Model\Entities\Basket')->find($Basket_2->getId());
$this->assertInstanceOf('\Alchemy\Phrasea\Model\Entities\Basket', $basket);
$this->assertEquals(1, $basket->getElements()->count());
$this->assertEquals(0, $Basket_1->getElements()->count());
$this->assertEquals(1, $Basket_2->getElements()->count());
}
public function testRouteStealElementsJson()
@@ -559,54 +489,37 @@ class ControllerBasketTest extends \PhraseanetWebTestCaseAuthenticatedAbstract
$this->assertArrayHasKey('success', $datas);
$this->assertTrue($datas['success']);
$basket = self::$DI['app']['EM']->getRepository('Alchemy\Phrasea\Model\Entities\Basket')->find($Basket_1->getId());
$this->assertInstanceOf('\Alchemy\Phrasea\Model\Entities\Basket', $basket);
$this->assertEquals(0, $basket->getElements()->count());
$basket = self::$DI['app']['EM']->getRepository('Alchemy\Phrasea\Model\Entities\Basket')->find($Basket_2->getId());
$this->assertInstanceOf('\Alchemy\Phrasea\Model\Entities\Basket', $basket);
$this->assertEquals(1, $basket->getElements()->count());
$this->assertEquals(0, $Basket_1->getElements()->count());
$this->assertEquals(1, $Basket_2->getElements()->count());
}
/**
* Test when i remove a basket, all relations are removed too :
* - basket elements
* - validations sessions
* - validation participants
*/
public function testRemoveBasket()
{
$basket = $this->insertOneBasketEnv();
$basket = self::$DI['app']['EM']->find("Alchemy\Phrasea\Model\Entities\Basket", $basket->getId());
$route = sprintf('/prod/baskets/%s/delete/', $basket->getId());
self::$DI['client']->request('POST', $route, array(), array(), array("HTTP_ACCEPT" => "application/json"));
self::$DI['app']['EM']->remove($basket);
self::$DI['app']['EM']->flush();
$response = self::$DI['client']->getResponse();
$this->assertEquals(200, $response->getStatusCode());
$datas = (array) json_decode($response->getContent());
$this->assertArrayHasKey('message', $datas);
$this->assertArrayHasKey('success', $datas);
$this->assertTrue($datas['success']);
$query = self::$DI['app']['EM']->createQuery('SELECT COUNT(v.id) FROM \Alchemy\Phrasea\Model\Entities\ValidationParticipant v');
$this->assertEquals(0, $query->getSingleScalarResult());
$count = $query->getSingleScalarResult();
$this->assertEquals(0, $count);
$query = self::$DI['app']['EM']->createQuery(
'SELECT COUNT(b.id) FROM \Alchemy\Phrasea\Model\Entities\BasketElement b'
);
$count = $query->getSingleScalarResult();
$this->assertEquals(0, $count);
$query = self::$DI['app']['EM']->createQuery('SELECT COUNT(b.id) FROM \Alchemy\Phrasea\Model\Entities\BasketElement b');
$this->assertEquals(0, $query->getSingleScalarResult());
$query = self::$DI['app']['EM']->createQuery('SELECT COUNT(v.id) FROM \Alchemy\Phrasea\Model\Entities\ValidationSession v');
$count = $query->getSingleScalarResult();
$this->assertEquals(0, $count);
$this->assertEquals(0, $query->getSingleScalarResult());
$query = self::$DI['app']['EM']->createQuery('SELECT COUNT(b.id) FROM \Alchemy\Phrasea\Model\Entities\Basket b');
$count = $query->getSingleScalarResult();
$this->assertEquals(0, $count);
$this->assertEquals(0, $query->getSingleScalarResult());
}
}

View File

@@ -0,0 +1,77 @@
<?php
namespace Alchemy\Tests\Phrasea\Core\Middleware;
use Alchemy\Phrasea\Core\Middleware\BasketMiddlewareProvider;
use Symfony\Component\HttpFoundation\Request;
class BasketMiddlewareProviderTest extends MiddlewareProviderTestCase
{
public function provideDescription()
{
return array(
array(
'Alchemy\Phrasea\Core\Middleware\BasketMiddlewareProvider',
'middleware.basket.converter'
),
array(
'Alchemy\Phrasea\Core\Middleware\BasketMiddlewareProvider',
'middleware.basket.user-access'
),
array(
'Alchemy\Phrasea\Core\Middleware\BasketMiddlewareProvider',
'middleware.basket.user-is-owner'
),
);
}
public function testConverterWithNoParameter()
{
$this->authenticate(self::$DI['app']);
self::$DI['app']->register(new BasketMiddlewareProvider());
$request = new Request();
call_user_func(self::$DI['app']['middleware.basket.converter'], $request, self::$DI['app']);
$this->assertNull($request->attributes->get('basket'));
}
public function testConverterWithBasketParameter()
{
$this->authenticate(self::$DI['app']);
self::$DI['app']->register(new BasketMiddlewareProvider());
$request = new Request();
$basket = $this->insertOneBasket(self::$DI['user']);
$request->attributes->set('basket', $basket->getId());
call_user_func(self::$DI['app']['middleware.basket.converter'], $request, self::$DI['app']);
$this->assertSame($basket, $request->attributes->get('basket'));
}
public function testUserAccessWithNoParameter()
{
$this->authenticate(self::$DI['app']);
self::$DI['app']->register(new BasketMiddlewareProvider());
$request = new Request();
call_user_func(self::$DI['app']['middleware.basket.user-access'], $request, self::$DI['app']);
$this->assertNull($request->attributes->get('basket'));
}
public function testUserAccessWithBasketOwner()
{
$this->authenticate(self::$DI['app']);
self::$DI['app']->register(new BasketMiddlewareProvider());
$request = new Request();
$basket = $this->insertOneBasket(self::$DI['user']);
$request->attributes->set('basket', $basket);
call_user_func(self::$DI['app']['middleware.basket.user-access'], $request, self::$DI['app']);
}
public function testUserAccessWithoutBasketOwner()
{
$this->authenticate(self::$DI['app']);
self::$DI['app']->register(new BasketMiddlewareProvider());
$request = new Request();
$basket = $this->insertOneBasket(self::$DI['user_alt1']);
$request->attributes->set('basket', $basket);
$this->setExpectedException('Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException', 'Current user does not have access to the basket');
call_user_func(self::$DI['app']['middleware.basket.user-access'], $request, self::$DI['app']);
}
}

View File

@@ -0,0 +1,26 @@
<?php
namespace Alchemy\Tests\Phrasea\Core\Middleware;
use Alchemy\Phrasea\Application;
use Symfony\Component\HttpFoundation\Request;
abstract class MiddlewareProviderTestCase extends \PhraseanetPHPUnitAbstract
{
/**
* @test
* @dataProvider provideDescription
*/
public function differentInstancesShouldBereturnedEveryTime($service, $key)
{
self::$DI['app']->register(new $service());
$instance1 = self::$DI['app'][$key];
$instance2 = self::$DI['app'][$key];
$this->assertTrue(is_callable($instance1));
$this->assertSame($instance1, $instance2);
}
abstract public function provideDescription();
}

View File

@@ -0,0 +1,23 @@
<?php
namespace Alchemy\Tests\Phrasea\Core\Provider;
use Alchemy\Phrasea\Application as PhraseaApplication;
use Alchemy\Phrasea\Core\Provider\TokensServiceProvider;
use Alchemy\Phrasea\Core\Provider\AuthenticationManagerServiceProvider;
use Alchemy\Phrasea\Core\Provider\ConfigurationServiceProvider;
use Silex\Application;
class ACLServiceProvidertest extends ServiceProviderTestCase
{
public function provideServiceDescription()
{
return array(
array(
'Alchemy\Phrasea\Core\Provider\ACLServiceProvider',
'acl.basket',
'Alchemy\\Phrasea\\ACL\\BasketACL',
),
);
}
}

View File

@@ -12,6 +12,11 @@ class ConvertersServiceProvidertest extends ServiceProviderTestCase
'converter.task',
'Alchemy\Phrasea\Controller\Converter\TaskConverter'
),
array(
'Alchemy\Phrasea\Core\Provider\ConvertersServiceProvider',
'converter.basket',
'Alchemy\Phrasea\Controller\Converter\BasketConverter'
),
);
}
}

View File

@@ -16,7 +16,7 @@ abstract class ServiceProviderTestCase extends \PhraseanetPHPUnitAbstract
$instance2 = self::$DI['app'][$key];
$this->assertInstanceof($classname, $instance1);
$this->assertEquals($instance1, $instance2);
$this->assertSame($instance1, $instance2);
}
abstract public function provideServiceDescription();

View File

@@ -0,0 +1,27 @@
<?php
namespace Alchemy\Phrasea\Model\Converter;
use Alchemy\Phrasea\Model\Converter\BasketConverter;
use Alchemy\Phrasea\Model\Entities\Task;
class BasketConverterTest extends \PhraseanetPHPUnitAbstract
{
public function testConvert()
{
$basket = $this->insertOneBasket();
$converter = new BasketConverter(self::$DI['app']['EM']);
$this->assertSame($basket, $converter->convert($basket->getId()));
}
/**
* @expectedException Symfony\Component\HttpKernel\Exception\NotFoundHttpException
* @expectedExceptionMessage Basket prout not found.
*/
public function testConvertFailure()
{
$converter = new BasketConverter(self::$DI['app']['EM']);
$converter->convert('prout');
}
}

View File

@@ -5,6 +5,8 @@ use Alchemy\Phrasea\Application;
use Alchemy\Phrasea\Border\File;
use Doctrine\Common\DataFixtures\Loader;
use Alchemy\Phrasea\Model\Entities\AggregateToken;
use Alchemy\Phrasea\Model\Entities\Basket;
use Alchemy\Phrasea\Model\Entities\BasketElement;
use Alchemy\Phrasea\Model\Entities\Feed;
use Alchemy\Phrasea\Model\Entities\FeedEntry;
use Alchemy\Phrasea\Model\Entities\FeedItem;
@@ -12,6 +14,8 @@ use Alchemy\Phrasea\Model\Entities\FeedToken;
use Alchemy\Phrasea\Model\Entities\Session;
use Alchemy\Phrasea\Model\Entities\Task;
use Alchemy\Phrasea\Model\Entities\User;
use Alchemy\Phrasea\Model\Entities\ValidationSession;
use Alchemy\Phrasea\Model\Entities\ValidationParticipant;
use Silex\WebTestCase;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Client;
@@ -329,22 +333,17 @@ abstract class PhraseanetPHPUnitAbstract extends WebTestCase
*
* @return \Alchemy\Phrasea\Model\Entities\Basket
*/
protected function insertOneBasket()
protected function insertOneBasket(\User_Adapter $user = null)
{
try {
$basketFixture = new PhraseaFixture\Basket\LoadOneBasket();
$basket = new Basket();
$basket->setOwner($user ?: self::$DI['user']);
$basket->setName('test');
$basket->setName('description test');
$basketFixture->setUser(self::$DI['user']);
self::$DI['app']['EM']->persist($basket);
self::$DI['app']['EM']->flush();
$loader = new Loader();
$loader->addFixture($basketFixture);
$this->insertFixtureInDatabase($loader);
return $basketFixture->basket;
} catch (\Exception $e) {
$this->fail('Fail load one Basket : ' . $e->getMessage());
}
return $basket;
}
/**
@@ -591,28 +590,21 @@ abstract class PhraseanetPHPUnitAbstract extends WebTestCase
}
/**
*
* @return \Alchemy\Phrasea\Model\Entities\BasketElement
*/
protected function insertOneBasketElement()
protected function insertOneBasketElement(\User_Adapter $user = null, \record_adapter $record = null)
{
$basket = $this->insertOneBasket();
$element = new BasketElement();
$element->setRecord($record ?: self::$DI['record_1']);
$basketElement = new \Alchemy\Phrasea\Model\Entities\BasketElement();
$basketElement->setRecord(self::$DI['record_1']);
$basketElement->setBasket($basket);
$basket = $this->insertOneBasket($user);
$basket->addElement($element);
$element->setBasket($basket);
$basket->addElement($basketElement);
self::$DI['app']['EM']->persist($element);
self::$DI['app']['EM']->flush();
$em = self::$DI['app']['EM'];
$em->persist($basketElement);
$em->merge($basket);
$em->flush();
return $basketElement;
return $element;
}
/**
@@ -673,26 +665,39 @@ abstract class PhraseanetPHPUnitAbstract extends WebTestCase
*/
protected function insertOneBasketEnv()
{
try {
$basketFixture = new PhraseaFixture\Basket\LoadOneBasketEnv();
$basket = new Basket();
$basket->setName('test');
$basket->setDescription('description');
$basket->setOwner(self::$DI['user']);
self::$DI['app']['EM']->persist($basket);
$basketFixture->setUser(self::$DI['user']);
$basketFixture->addParticipant(self::$DI['user_alt1']);
$basketFixture->addParticipant(self::$DI['user_alt2']);
$basketFixture->addElement(self::$DI['record_1']);
$basketFixture->addElement(self::$DI['record_2']);
$loader = new Loader();
$loader->addFixture($basketFixture);
$this->insertFixtureInDatabase($loader);
return $basketFixture->basket;
} catch (\Exception $e) {
$this->fail('Fail load one Basket context : ' . $e->getMessage());
foreach (array(self::$DI['record_1'], self::$DI['record_2']) as $record) {
$basketElement = new BasketElement();
$basketElement->setRecord($record);
$basketElement->setBasket($basket);
$basket->addElement($basketElement);
self::$DI['app']['EM']->persist($basketElement);
}
$validationSession = new ValidationSession();
$validationSession->setBasket($basket);
$basket->setValidation($validationSession);
$expires = new \DateTime();
$expires->modify('+1 week');
$validationSession->setExpires($expires);
$validationSession->setInitiator(self::$DI['user']);
foreach (array(self::$DI['user_alt1'], self::$DI['user_alt2']) as $user) {
$validationParticipant = new ValidationParticipant();
$validationParticipant->setUser($user);
$validationParticipant->setSession($validationSession);
$validationSession->addParticipant($validationParticipant);
self::$DI['app']['EM']->persist($validationParticipant);
}
self::$DI['app']['EM']->flush();
return $basket;
}
/**

View File

@@ -557,12 +557,10 @@ class API_V1_adapterTest extends PhraseanetPHPUnitAuthenticatedAbstract
$this->assertArrayHasKey('basket', $response['response']);
$em = self::$DI['app']['EM'];
$repo = $em->getRepository('\Alchemy\Phrasea\Model\Entities\Basket');
/* @var $repo Alchemy\Phrasea\Model\Repositories\BasketRepository */
$basket = $repo->findUserBasket(self::$DI['app'], $response['response']['basket']['basket_id'], self::$DI['app']['authentication']->getUser(), true);
$basket = self::$DI['app']['converter.basket']->convert($response['response']['basket']['basket_id']);
self::$DI['app']['acl.basket']->isOwner($basket, self::$DI['app']['authentication']->getUser());
$this->assertTrue($basket instanceof \Alchemy\Phrasea\Model\Entities\Basket);
$em->remove($basket);
$em->flush();
}
@@ -581,20 +579,17 @@ class API_V1_adapterTest extends PhraseanetPHPUnitAuthenticatedAbstract
$em->persist($Basket);
$em->flush();
$ssel_id = $Basket->getId();
$request = new Request(array(), array(), array(), array(), array(), array('HTTP_Accept' => 'application/json'));
$result = $this->object->delete_basket($request, $ssel_id);
$result = $this->object->delete_basket($request, $Basket);
$this->assertEquals(200, $result->get_http_code());
$this->assertEquals('application/json', $result->get_content_type());
$this->assertTrue(is_array(json_decode($result->format(), true)));
$repo = $em->getRepository('\Alchemy\Phrasea\Model\Entities\Basket');
try {
$repo->findUserBasket(self::$DI['app'], $ssel_id, $user, true);
$basket = self::$DI['app']['converter.basket']->convert($Basket->getId());
self::$DI['app']['acl.basket']->isOwner($basket, $user);
$this->fail('An exception should have been raised');
} catch (NotFoundHttpException $e) {
} catch (\Exception $e) {
}
}
@@ -606,7 +601,7 @@ class API_V1_adapterTest extends PhraseanetPHPUnitAuthenticatedAbstract
$basket = $this->insertOneBasket();
$request = new Request(array(), array(), array(), array(), array(), array('HTTP_Accept' => 'application/json'));
$result = $this->object->get_basket($request, $basket->getId());
$result = $this->object->get_basket($request, $basket);
$this->assertEquals(200, $result->get_http_code());
$this->assertEquals('application/json', $result->get_content_type());
$this->assertTrue(is_array(json_decode($result->format(), true)));
@@ -619,7 +614,7 @@ class API_V1_adapterTest extends PhraseanetPHPUnitAuthenticatedAbstract
$basket = $this->insertOneBasket();
$request = new Request(array(), array(), array('name' => 'PROUTO'), array(), array(), array('HTTP_Accept' => 'application/json'));
$result = $this->object->set_basket_title($request, $basket->getId());
$result = $this->object->set_basket_title($request, $basket);
$this->assertEquals(200, $result->get_http_code());
$this->assertEquals('application/json', $result->get_content_type());
$this->assertTrue(is_array(json_decode($result->format(), true)));
@@ -638,7 +633,7 @@ class API_V1_adapterTest extends PhraseanetPHPUnitAuthenticatedAbstract
$basket = $this->insertOneBasket();
$request = new Request(array(), array(), array('description' => 'une belle description'), array(), array(), array('HTTP_Accept' => 'application/json'));
$result = $this->object->set_basket_description($request, $basket->getId());
$result = $this->object->set_basket_description($request, $basket);
$this->assertEquals(200, $result->get_http_code());
$this->assertEquals('application/json', $result->get_content_type());
$this->assertTrue(is_array(json_decode($result->format(), true)));