Merge branch 'master' into PHRAS-2741-worker-service-part1

This commit is contained in:
Nicolas Maillat
2019-09-23 12:23:46 +02:00
committed by GitHub
14 changed files with 208 additions and 133 deletions

View File

@@ -15,12 +15,9 @@ use Alchemy\Phrasea\Core\Configuration\DisplaySettingService;
use Alchemy\Phrasea\Exception\SessionNotFound;
use Alchemy\Phrasea\Feed\Aggregate;
use Alchemy\Phrasea\Helper;
use Alchemy\Phrasea\Model\Entities\UserSetting;
use Alchemy\Phrasea\Helper\WorkZone as WorkzoneHelper;
use Alchemy\Phrasea\Model\Repositories\FeedRepository;
use Symfony\Component\Finder\Finder;
use Symfony\Component\Finder\SplFileInfo;
use Symfony\Component\HttpFoundation\Request;
// use Alchemy\Phrasea\Plugin\ActionBarPluginInterface;
class RootController extends Controller
@@ -43,12 +40,11 @@ class RootController extends Controller
public function indexAction(Request $request) {
try {
\Session_Logger::updateClientInfos($this->app, 1);
} catch (SessionNotFound $e) {
}
catch (SessionNotFound $e) {
return $this->app->redirectPath('logout');
}
$css = [];
$user = $this->getAuthenticatedUser();
$cssfile = $this->getSettings()->getUserSetting($user, 'css');
@@ -110,7 +106,7 @@ class RootController extends Controller
return $this->render('prod/index.html.twig', [
'module_name' => 'Production',
'WorkZone' => new Helper\WorkZone($this->app, $request),
'WorkZone' => new WorkzoneHelper($this->app, $request),
'module_prod' => $helper,
'search_datas' => $helper->get_search_datas(),
'cssfile' => $cssfile,
@@ -123,7 +119,7 @@ class RootController extends Controller
'feeds' => $feeds,
'aggregate' => $aggregate,
'GV_google_api' => $conf->get(['registry', 'webservices', 'google-charts-enabled']),
'geocodingProviders' => $conf->get(['geocoding-providers']),
'geocodingProviders' => $conf->get(['geocoding-providers']),
'search_status' => \databox_status::getSearchStatus($this->app),
'thesau_js_list' => $thjslist,
'thesau_json_sbas' => json_encode($sbas),

View File

@@ -367,15 +367,17 @@ class UploadController extends Controller
$postMaxSize = PHP_INT_MAX;
}
$r = 0;
switch (strtolower(substr($postMaxSize, -1))) {
/** @noinspection PhpMissingBreakStatementInspection */
case 'g':
$postMaxSize *= 1024;
$r += 10;
/** @noinspection PhpMissingBreakStatementInspection */
case 'm':
$postMaxSize *= 1024;
$r += 10;
case 'k':
$postMaxSize *= 1024;
$r += 10;
$postMaxSize = ((int)($postMaxSize))<<$r;
}
return min(UploadedFile::getMaxFilesize(), (int) $postMaxSize);

View File

@@ -522,27 +522,35 @@ class AccountController extends Controller
$list = array_keys($this->app['repo.collections-registry']->getBaseIdMap());
$this->app->getAclForUser($user)->revoke_access_from_bases($list);
try {
$this->app->getAclForUser($user)->revoke_access_from_bases($list);
}
catch (\Exception $e) {
// one or more access could not be revoked ? the user will not be phantom
$this->app->addFlash('error', $this->app->trans('phraseanet::error: failed to revoke some user access'));
}
if ($this->app->getAclForUser($user)->is_phantom()) {
// send confirmation email: the account has been deleted
try {
$receiver = Receiver::fromUser($user);
} catch (InvalidArgumentException $e) {
$this->app->addFlash('error', $this->app->trans('phraseanet::erreur: echec du serveur de mail'));
$mail = MailSuccessAccountDelete::create($this->app, $receiver);
}
catch (InvalidArgumentException $e) {
$this->app->addFlash('error', $this->app->trans('phraseanet::erreur: echec du serveur de mail'));
$mail = null;
}
$mail = MailSuccessAccountDelete::create($this->app, $receiver);
$this->app['manipulator.user']->delete($user);
$this->deliver($mail);
if($mail) {
$this->deliver($mail);
}
$this->getAuthenticator()->closeAccount();
$this->app->addFlash('info', $this->app->trans('phraseanet::account The account has been deleted'));
}
$this->getAuthenticator()->closeAccount();
$this->app->addFlash('info', $this->app->trans('phraseanet::account The account has been deleted'));
}
/**

View File

@@ -94,10 +94,9 @@ class SessionController extends Controller
}
/**
* Check session state
*
* @param Request $request
* @param Request $request
* @return JsonResponse
* @throws \Exception in case "new \DateTime()" fails ?
*/
public function updateSession(Request $request)
{
@@ -120,7 +119,8 @@ class SessionController extends Controller
return $this->app->json($ret);
}
} else {
}
else {
$ret['status'] = 'disconnected';
return $this->app->json($ret);
@@ -128,7 +128,8 @@ class SessionController extends Controller
try {
$this->getApplicationBox()->get_connection();
} catch (\Exception $e) {
}
catch (\Exception $e) {
return $this->app->json($ret);
}
@@ -148,8 +149,9 @@ class SessionController extends Controller
$module->setModuleId($moduleId);
$module->setSession($session);
$manager->persist($module);
} else {
$manager->persist($session->getModuleById($moduleId)->setUpdated(new \DateTime()));
}
else {
$manager->persist($session->getModuleById($moduleId)->setUpdated($now));
}
$manager->persist($session);
@@ -231,7 +233,10 @@ class SessionController extends Controller
*/
private function getBasketRepository()
{
return $this->getEntityManager()->getRepository('Phraseanet:Basket');
/** @var BasketRepository $ret */
$ret = $this->getEntityManager()->getRepository('Phraseanet:Basket');
return $ret;
}
/**

View File

@@ -11,28 +11,29 @@
namespace Alchemy\Phrasea\Helper;
use Doctrine\Common\Collections\ArrayCollection;
use Alchemy\Phrasea\Model\Entities\Basket as BasketEntity;
use Alchemy\Phrasea\Model\Repositories\BasketRepository;
use Alchemy\Phrasea\Model\Repositories\StoryWZRepository;
use Doctrine\Common\Collections\ArrayCollection;
class WorkZone extends Helper
{
const BASKETS = 'baskets';
const STORIES = 'stories';
const BASKETS = 'baskets';
const STORIES = 'stories';
const VALIDATIONS = 'validations';
/**
*
* Returns an ArrayCollection containing three keys :
* - self::BASKETS : an ArrayCollection of the actives baskets
* (Non Archived)
* - self::BASKETS : an ArrayCollection of the actives baskets (Non Archived)
* - self::STORIES : an ArrayCollection of working stories
* - self::VALIDATIONS : the validation people are waiting from me
*
* @return \Doctrine\Common\Collections\ArrayCollection
* @param null|string $sort "date"|"name"
* @return ArrayCollection
*/
public function getContent($sort)
public function getContent($sort = null)
{
/* @var $repo_baskets Alchemy\Phrasea\Model\Repositories\BasketRepository */
/* @var $repo_baskets BasketRepository */
$repo_baskets = $this->app['repo.baskets'];
$sort = in_array($sort, ['date', 'name']) ? $sort : 'name';
@@ -42,7 +43,7 @@ class WorkZone extends Helper
$baskets = $repo_baskets->findActiveByUser($this->app->getAuthenticatedUser(), $sort);
// force creation of a default basket
if (0 === count($baskets)) {
if (count($baskets) === 0) {
$basket = new BasketEntity();
$basket->setName($this->app->trans('Default basket'));
@@ -55,7 +56,7 @@ class WorkZone extends Helper
$validations = $repo_baskets->findActiveValidationByUser($this->app->getAuthenticatedUser(), $sort);
/* @var $repo_stories Alchemy\Phrasea\Model\Repositories\StoryWZRepository */
/* @var $repo_stories StoryWZRepository */
$repo_stories = $this->app['repo.story-wz'];
$stories = $repo_stories->findByUser($this->app, $this->app->getAuthenticatedUser(), $sort);

View File

@@ -61,7 +61,7 @@ class SubdefGenerator
public function generateSubdefs(\record_adapter $record, array $wanted_subdefs = null)
{
if ($record->get_hd_file() !== null) {
if ($record->get_hd_file() !== null && $record->get_hd_file()->getMimeType() == "application/x-indesign") {
$mediaSource = $this->mediavorus->guess($record->get_hd_file()->getPathname());
$metadatas = $mediaSource->getMetadatas();
@@ -69,15 +69,27 @@ class SubdefGenerator
if(!isset($this->tmpFilesystem)){
$this->tmpFilesystem = Manager::create();
}
$tmpDir = $this->tmpFilesystem->createTemporaryDirectory();
$tmpDir = $this->tmpFilesystem->createTemporaryDirectory(0777, 500);
try {
$this->app['filesystem']->dumpFile($tmpDir.'/file.jpg', $metadatas->get('XMP-xmp:PageImage')->getValue()->asString());
$this->tmpFilePath = $tmpDir.'/file.jpg';
} catch (\Exception $e) {
$this->logger->error(sprintf('Unable to write temporary file : %s', $e->getMessage()));
$files = $this->app['exiftool.preview-extractor']->extract($record->get_hd_file()->getPathname(), $tmpDir);
$selected = null;
$size = null;
foreach ($files as $file) {
if ($file->isDir() || $file->isDot()) {
continue;
}
if (is_null($selected) || $file->getSize() > $size) {
$selected = $file->getPathname();
$size = $file->getSize();
}
}
if ($selected) {
$this->tmpFilePath = $selected;
}
}
}

View File

@@ -54,21 +54,24 @@ class BasketRepository extends EntityRepository
/**
* Returns all basket for a given user that are not marked as archived
*
* @param User $user
* @param User $user
* @param null|string $sort
* @return Basket[]
*/
public function findActiveByUser(User $user, $sort = null)
{
$dql = 'SELECT b
FROM Phraseanet:Basket b
LEFT JOIN b.elements e
WHERE b.user = :usr_id
AND b.archived = false';
// checked : 4 usages, "b.elements" is useless
$dql = "SELECT b\n"
. " FROM Phraseanet:Basket b\n"
// . " LEFT JOIN b.elements e\n" //
. " WHERE b.user = :usr_id\n"
. " AND b.archived = false";
if ($sort == 'date') {
$dql .= ' ORDER BY b.created DESC';
} elseif ($sort == 'name') {
$dql .= ' ORDER BY b.name ASC';
$dql .= "\n ORDER BY b.created DESC";
}
elseif ($sort == 'name') {
$dql .= "\n ORDER BY b.name ASC";
}
$query = $this->_em->createQuery($dql);
@@ -80,24 +83,27 @@ class BasketRepository extends EntityRepository
/**
* Returns all unread basket for a given user that are not marked as archived
*
* @param User $user
* @param User $user
* @return Basket[]
*/
public function findUnreadActiveByUser(User $user)
{
$dql = 'SELECT b
FROM Phraseanet:Basket b
JOIN b.elements e
LEFT JOIN b.validation s
LEFT JOIN s.participants p
WHERE b.archived = false
AND (
(b.user = :usr_id_owner AND b.isRead = false)
OR (b.user != :usr_id_ownertwo
AND p.user = :usr_id_participant
AND p.is_aware = false)
)
AND (s.expires IS NULL OR s.expires > CURRENT_TIMESTAMP())';
// checked : 2 usages, "b.elements" is useless
$dql = "SELECT b\n"
. " FROM Phraseanet:Basket b\n"
// . " JOIN b.elements e\n"
. " LEFT JOIN b.validation s\n"
. " LEFT JOIN s.participants p\n"
. " WHERE b.archived = false\n"
. " AND (\n"
. " (b.user = :usr_id_owner AND b.isRead = false)\n"
. " OR \n"
. " (b.user != :usr_id_ownertwo\n"
. " AND p.user = :usr_id_participant\n"
. " AND p.is_aware = false\n"
. " AND s.expires > CURRENT_TIMESTAMP()\n"
. " )\n"
. " )";
$params = [
'usr_id_owner' => $user->getId(),
@@ -115,11 +121,22 @@ class BasketRepository extends EntityRepository
* Returns all baskets that are in validation session not expired and
* where a specified user is participant (not owner)
*
* @param User $user
* @param User $user
* @param null|string $sort
* @return Basket[]
*/
public function findActiveValidationByUser(User $user, $sort = null)
{
// checked : 2 usages, "b.elements" seems useless.
$dql = "SELECT b\n"
. "FROM Phraseanet:Basket b\n"
// . " JOIN b.elements e\n"
// . " JOIN e.validation_datas v\n"
. " JOIN b.validation s\n"
. " JOIN s.participants p\n"
. "WHERE b.user != ?1 AND p.user = ?2\n"
. " AND (s.expires IS NULL OR s.expires > CURRENT_TIMESTAMP())";
$dql = 'SELECT b
FROM Phraseanet:Basket b
JOIN b.elements e
@@ -130,9 +147,9 @@ class BasketRepository extends EntityRepository
AND (s.expires IS NULL OR s.expires > CURRENT_TIMESTAMP()) ';
if ($sort == 'date') {
$dql .= ' ORDER BY b.created DESC';
$dql .= "\nORDER BY b.created DESC";
} elseif ($sort == 'name') {
$dql .= ' ORDER BY b.name ASC';
$dql .= "\nORDER BY b.name ASC";
}
$query = $this->_em->createQuery($dql);
@@ -152,10 +169,11 @@ class BasketRepository extends EntityRepository
*/
public function findUserBasket($basket_id, User $user, $requireOwner)
{
$dql = 'SELECT b
FROM Phraseanet:Basket b
LEFT JOIN b.elements e
WHERE b.id = :basket_id';
// checked : 3 usages, "b.elements e" seems useless
$dql = "SELECT b\n"
. " FROM Phraseanet:Basket b\n"
// . " LEFT JOIN b.elements e\n"
. " WHERE b.id = :basket_id";
$query = $this->_em->createQuery($dql);
$query->setParameters(['basket_id' => $basket_id]);
@@ -188,7 +206,7 @@ class BasketRepository extends EntityRepository
public function findContainingRecordForUser(\record_adapter $record, User $user)
{
// todo : check "e.sbas_id = e.sbas_id" ???
$dql = 'SELECT b
FROM Phraseanet:Basket b
JOIN b.elements e
@@ -210,29 +228,31 @@ class BasketRepository extends EntityRepository
{
switch ($type) {
case self::RECEIVED:
$dql = 'SELECT b
FROM Phraseanet:Basket b
JOIN b.elements e';
// todo : check when called, and if "LEFT JOIN b.elements e" is usefull
$dql = "SELECT b\n"
. "FROM Phraseanet:Basket b\n"
. " JOIN b.elements e\n"
. "WHERE b.user = :usr_id AND b.pusher_id IS NOT NULL";
$params = [
'usr_id' => $user->getId()
];
break;
case self::VALIDATION_DONE:
$dql = 'SELECT b
FROM Phraseanet:Basket b
JOIN b.elements e
JOIN b.validation s
JOIN s.participants p
WHERE b.user != ?1 AND p.user = ?2';
// todo : check when called, and if "LEFT JOIN b.elements e" is usefull
$dql = "SELECT b\n"
. "FROM Phraseanet:Basket b\n"
. " JOIN b.elements e\n"
. " JOIN b.validation s\n"
. " JOIN s.participants p\n"
. "WHERE b.user != ?1 AND p.user = ?2";
$params = [
1 => $user->getId()
, 2 => $user->getId()
1 => $user->getId(),
2 => $user->getId()
];
break;
case self::VALIDATION_SENT:
$dql = 'SELECT b
FROM Phraseanet:Basket b
JOIN b.elements e
JOIN b.validation v
WHERE b.user = :usr_id';
$params = [
@@ -242,7 +262,6 @@ class BasketRepository extends EntityRepository
case self::MYBASKETS:
$dql = 'SELECT b
FROM Phraseanet:Basket b
LEFT JOIN b.elements e
LEFT JOIN b.validation s
LEFT JOIN s.participants p
WHERE (b.user = :usr_id)';
@@ -251,6 +270,7 @@ class BasketRepository extends EntityRepository
];
break;
default:
// todo : check when called, and if "LEFT JOIN b.elements e" is usefull
$dql = 'SELECT b
FROM Phraseanet:Basket b
LEFT JOIN b.elements e
@@ -296,6 +316,7 @@ class BasketRepository extends EntityRepository
*/
public function findActiveValidationAndBasketByUser(User $user, $sort = null)
{
// todo : check caller and if "LEFT JOIN b.elements e" is usefull
$dql = 'SELECT b
FROM Phraseanet:Basket b
LEFT JOIN b.elements e