mirror of
https://github.com/alchemy-fr/Phraseanet.git
synced 2025-10-17 23:13:15 +00:00
Refactor getChildren() and get_grouping_parents()
This commit is contained in:
@@ -168,7 +168,7 @@ class RepositoriesServiceProvider implements ServiceProviderInterface
|
|||||||
});
|
});
|
||||||
|
|
||||||
$app['repo.records.factory'] = $app->protect(function (\databox $databox) use ($app) {
|
$app['repo.records.factory'] = $app->protect(function (\databox $databox) use ($app) {
|
||||||
return new LegacyRecordRepository($app, $databox);
|
return new LegacyRecordRepository($app, $databox, $app['conf']->get(['main', 'key']));
|
||||||
});
|
});
|
||||||
|
|
||||||
$app['repo.collection-references'] = $app->share(function (PhraseaApplication $app) {
|
$app['repo.collection-references'] = $app->share(function (PhraseaApplication $app) {
|
||||||
|
@@ -11,19 +11,32 @@ namespace Alchemy\Phrasea\Databox\Record;
|
|||||||
|
|
||||||
use Alchemy\Phrasea\Application;
|
use Alchemy\Phrasea\Application;
|
||||||
use Alchemy\Phrasea\Cache\Exception;
|
use Alchemy\Phrasea\Cache\Exception;
|
||||||
|
use Alchemy\Phrasea\Model\Entities\User;
|
||||||
use Doctrine\DBAL\Connection;
|
use Doctrine\DBAL\Connection;
|
||||||
|
use Doctrine\DBAL\Query\QueryBuilder;
|
||||||
|
|
||||||
class LegacyRecordRepository implements RecordRepository
|
class LegacyRecordRepository implements RecordRepository
|
||||||
{
|
{
|
||||||
/** @var Application */
|
/**
|
||||||
|
* @var Application
|
||||||
|
*/
|
||||||
private $app;
|
private $app;
|
||||||
/** @var \databox */
|
|
||||||
|
/**
|
||||||
|
* @var \databox
|
||||||
|
*/
|
||||||
private $databox;
|
private $databox;
|
||||||
|
|
||||||
public function __construct(Application $app, \databox $databox)
|
/**
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
private $site;
|
||||||
|
|
||||||
|
public function __construct(Application $app, \databox $databox, $site)
|
||||||
{
|
{
|
||||||
$this->app = $app;
|
$this->app = $app;
|
||||||
$this->databox = $databox;
|
$this->databox = $databox;
|
||||||
|
$this->site = $site;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function find($record_id, $number = null)
|
public function find($record_id, $number = null)
|
||||||
@@ -107,30 +120,124 @@ class LegacyRecordRepository implements RecordRepository
|
|||||||
return $this->mapRecordsFromResultSet($result);
|
return $this->mapRecordsFromResultSet($result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function findChildren(array $storyIds, $user = null)
|
||||||
|
{
|
||||||
|
if (!$storyIds) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
$connection = $this->databox->get_connection();
|
||||||
|
|
||||||
|
$selects = $this->getRecordSelects();
|
||||||
|
array_unshift($selects, 's.rid_parent as story_id');
|
||||||
|
|
||||||
|
$builder = $connection->createQueryBuilder();
|
||||||
|
$builder
|
||||||
|
->select($selects)
|
||||||
|
->from('regroup', 's')
|
||||||
|
->innerJoin('s', 'record', 'r', 'r.record_id = s.rid_child')
|
||||||
|
->where(
|
||||||
|
's.rid_parent IN (:storyIds)',
|
||||||
|
'r.parent_record_id = 0'
|
||||||
|
)
|
||||||
|
->setParameter('storyIds', $storyIds, Connection::PARAM_INT_ARRAY)
|
||||||
|
;
|
||||||
|
|
||||||
|
if (null !== $user) {
|
||||||
|
$this->addUserFilter($builder, $user);
|
||||||
|
}
|
||||||
|
|
||||||
|
$data = $connection->fetchAll($builder->getSQL(), $builder->getParameters(), $builder->getParameterTypes());
|
||||||
|
$records = $this->mapRecordsFromResultSet($data);
|
||||||
|
|
||||||
|
$selections = array_map(function () {
|
||||||
|
return new \set_selection($this->app);
|
||||||
|
}, $storyIds);
|
||||||
|
|
||||||
|
|
||||||
|
foreach ($records as $index => $child) {
|
||||||
|
/** @var \set_selection $selection */
|
||||||
|
$selection = $selections[$data[$index]['story_id']];
|
||||||
|
|
||||||
|
$child->setNumber($selection->get_count() + 1);
|
||||||
|
|
||||||
|
$selection->add_element($child);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $selections;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function findParents(array $recordIds, $user = null)
|
||||||
|
{
|
||||||
|
if (!$recordIds) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
$connection = $this->databox->get_connection();
|
||||||
|
|
||||||
|
$builder = $connection->createQueryBuilder();
|
||||||
|
$builder
|
||||||
|
->select($this->getRecordSelects())
|
||||||
|
->from('regroup', 's')
|
||||||
|
->innerJoin('s', 'record', 'r', 'r.record_id = s.rid_parent')
|
||||||
|
->where(
|
||||||
|
's.rid_child IN (:recordIds)',
|
||||||
|
'r.parent_record_id = 1'
|
||||||
|
)
|
||||||
|
->setParameter('recordIds', $recordIds, Connection::PARAM_INT_ARRAY)
|
||||||
|
;
|
||||||
|
|
||||||
|
if (null !== $user) {
|
||||||
|
$this->addUserFilter($builder, $user);
|
||||||
|
}
|
||||||
|
|
||||||
|
$data = $connection->fetchAll($builder->getSQL(), $builder->getParameters(), $builder->getParameterTypes());
|
||||||
|
$stories = $this->mapRecordsFromResultSet($data);
|
||||||
|
|
||||||
|
$selections = array_map(function () {
|
||||||
|
return new \set_selection($this->app);
|
||||||
|
}, $recordIds);
|
||||||
|
|
||||||
|
|
||||||
|
foreach ($stories as $index => $child) {
|
||||||
|
/** @var \set_selection $selection */
|
||||||
|
$selection = $selections[$data[$index]['record_id']];
|
||||||
|
|
||||||
|
$child->setNumber($selection->get_count() + 1);
|
||||||
|
|
||||||
|
$selection->add_element($child);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $selections;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return \Doctrine\DBAL\Query\QueryBuilder
|
* @return QueryBuilder
|
||||||
*/
|
*/
|
||||||
private function createSelectBuilder()
|
private function createSelectBuilder()
|
||||||
{
|
{
|
||||||
$connection = $this->databox->get_connection();
|
return $this->databox->get_connection()->createQueryBuilder()
|
||||||
|
->select($this->getRecordSelects())
|
||||||
return $connection->createQueryBuilder()
|
|
||||||
->select(
|
|
||||||
'coll_id AS collection_id',
|
|
||||||
'record_id',
|
|
||||||
'credate AS created',
|
|
||||||
'uuid',
|
|
||||||
'moddate AS updated',
|
|
||||||
'parent_record_id AS isStory',
|
|
||||||
$connection->quoteIdentifier('type'),
|
|
||||||
'originalname AS originalName',
|
|
||||||
'sha256',
|
|
||||||
'mime',
|
|
||||||
'LPAD(BIN(status), 32, \'0\') as status'
|
|
||||||
)
|
|
||||||
->from('record', 'r');
|
->from('record', 'r');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function getRecordSelects()
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'r.coll_id AS collection_id',
|
||||||
|
'r.record_id',
|
||||||
|
'r.credate AS created',
|
||||||
|
'r.uuid',
|
||||||
|
'r.moddate AS updated',
|
||||||
|
'r.parent_record_id AS isStory',
|
||||||
|
'r.type',
|
||||||
|
'r.originalname AS originalName',
|
||||||
|
'r.sha256',
|
||||||
|
'r.mime',
|
||||||
|
'LPAD(BIN(r.status), 32, \'0\') as status',
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param array $result
|
* @param array $result
|
||||||
* @return \record_adapter[]
|
* @return \record_adapter[]
|
||||||
@@ -139,8 +246,8 @@ class LegacyRecordRepository implements RecordRepository
|
|||||||
{
|
{
|
||||||
$records = [];
|
$records = [];
|
||||||
|
|
||||||
foreach ($result as $row) {
|
foreach ($result as $index => $row) {
|
||||||
$records[] = $this->mapRecordFromResultRow($row);
|
$records[$index] = $this->mapRecordFromResultRow($row);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $records;
|
return $records;
|
||||||
@@ -162,4 +269,29 @@ class LegacyRecordRepository implements RecordRepository
|
|||||||
|
|
||||||
return $record;
|
return $record;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param QueryBuilder $builder
|
||||||
|
* @param int|User $user
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
private function addUserFilter(QueryBuilder $builder, $user)
|
||||||
|
{
|
||||||
|
$subBuilder = $builder->getConnection()->createQueryBuilder();
|
||||||
|
|
||||||
|
$subBuilder
|
||||||
|
->select('1')
|
||||||
|
->from('collusr', 'c')
|
||||||
|
->where(
|
||||||
|
'c.usr_id = :userId',
|
||||||
|
'c.site = :site',
|
||||||
|
'((r.status ^ c.mask_xor) & c.mask_and) = 0',
|
||||||
|
'c.coll_id = r.coll_id'
|
||||||
|
);
|
||||||
|
|
||||||
|
$builder
|
||||||
|
->andWhere(sprintf('EXISTS(%s)', $subBuilder->getSQL()))
|
||||||
|
->setParameter('userId', $user instanceof User ? $user->getId() : (int)$user)
|
||||||
|
->setParameter('site', $this->site);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -9,6 +9,8 @@
|
|||||||
*/
|
*/
|
||||||
namespace Alchemy\Phrasea\Databox\Record;
|
namespace Alchemy\Phrasea\Databox\Record;
|
||||||
|
|
||||||
|
use Alchemy\Phrasea\Model\Entities\User;
|
||||||
|
|
||||||
interface RecordRepository
|
interface RecordRepository
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
@@ -35,4 +37,23 @@ interface RecordRepository
|
|||||||
* @return \record_adapter[]
|
* @return \record_adapter[]
|
||||||
*/
|
*/
|
||||||
public function findByRecordIds(array $recordIds);
|
public function findByRecordIds(array $recordIds);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Find children of each given storyId reachable for given user
|
||||||
|
*
|
||||||
|
* @param int[] $storyIds
|
||||||
|
* @param null|int|User $user
|
||||||
|
* @return \set_selection[]
|
||||||
|
*/
|
||||||
|
public function findChildren(array $storyIds, $user = null);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Find stories containing records
|
||||||
|
*
|
||||||
|
* @param int[] $recordIds
|
||||||
|
* @param null|int|User $user
|
||||||
|
* @return \set_selection[]
|
||||||
|
*/
|
||||||
|
public function findParents(array $recordIds, $user = null);
|
||||||
}
|
}
|
||||||
|
@@ -1549,54 +1549,9 @@ class record_adapter implements RecordInterface, cache_cacheableInterface
|
|||||||
throw new Exception('This record is not a grouping');
|
throw new Exception('This record is not a grouping');
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($this->app->getAuthenticatedUser()) {
|
$selections = $this->getDatabox()->getRecordRepository()->findChildren([$this->getRecordId()]);
|
||||||
$sql = "SELECT record_id\n"
|
|
||||||
. " FROM regroup g\n"
|
|
||||||
. " INNER JOIN\n"
|
|
||||||
. " (record r INNER JOIN collusr c\n"
|
|
||||||
. " ON site = :site\n"
|
|
||||||
. " AND usr_id = :usr_id\n"
|
|
||||||
. " AND c.coll_id = r.coll_id\n"
|
|
||||||
. " AND ((status ^ mask_xor) & mask_and) = 0\n"
|
|
||||||
. " AND r.parent_record_id=0\n"
|
|
||||||
. " )\n"
|
|
||||||
. " ON (g.rid_child = r.record_id AND g.rid_parent = :record_id)\n"
|
|
||||||
. " ORDER BY g.ord ASC, dateadd ASC, record_id ASC";
|
|
||||||
|
|
||||||
$params = [
|
return reset($selections);
|
||||||
':site' => $this->app['conf']->get(['main', 'key']),
|
|
||||||
':usr_id' => $this->app->getAuthenticatedUser()->getId(),
|
|
||||||
':record_id' => $this->getRecordId(),
|
|
||||||
];
|
|
||||||
} else {
|
|
||||||
$sql = "SELECT record_id\n"
|
|
||||||
. " FROM regroup g INNER JOIN record r\n"
|
|
||||||
. " ON (g.rid_child = r.record_id AND g.rid_parent = :record_id)\n"
|
|
||||||
. " ORDER BY g.ord ASC, dateadd ASC, record_id ASC";
|
|
||||||
|
|
||||||
$params = [
|
|
||||||
':record_id' => $this->getRecordId(),
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
$recordIds = $this->getDataboxConnection()->fetchAll($sql, $params);
|
|
||||||
|
|
||||||
$recordIds = array_map(function (array $row) {
|
|
||||||
return $row['record_id'];
|
|
||||||
}, $recordIds);
|
|
||||||
|
|
||||||
$recordRepository = $this->getDatabox()->getRecordRepository();
|
|
||||||
$records = $recordRepository->findByRecordIds($recordIds);
|
|
||||||
|
|
||||||
$set = new set_selection($this->app);
|
|
||||||
$i = 1;
|
|
||||||
|
|
||||||
foreach ($records as $record) {
|
|
||||||
$record->setNumber($i++);
|
|
||||||
$set->add_element($record);
|
|
||||||
}
|
|
||||||
|
|
||||||
return $set;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1604,34 +1559,9 @@ class record_adapter implements RecordInterface, cache_cacheableInterface
|
|||||||
*/
|
*/
|
||||||
public function get_grouping_parents()
|
public function get_grouping_parents()
|
||||||
{
|
{
|
||||||
$sql = "SELECT r.record_id\n"
|
$selections = $this->getDatabox()->getRecordRepository()->findParents([$this->getRecordId()]);
|
||||||
. " FROM regroup g\n"
|
|
||||||
. " INNER JOIN\n"
|
|
||||||
. " (record r INNER JOIN collusr c\n"
|
|
||||||
. " ON site = :site\n"
|
|
||||||
. " AND usr_id = :usr_id\n"
|
|
||||||
. " AND c.coll_id = r.coll_id\n"
|
|
||||||
. " AND ((status ^ mask_xor) & mask_and)=0\n"
|
|
||||||
. " AND r.parent_record_id = 1\n"
|
|
||||||
. " )\n"
|
|
||||||
. " ON (g.rid_parent = r.record_id)\n"
|
|
||||||
. " WHERE rid_child = :record_id";
|
|
||||||
|
|
||||||
$stmt = $this->getDataboxConnection()->prepare($sql);
|
return reset($selections);
|
||||||
$stmt->execute([
|
|
||||||
':site' => $this->app['conf']->get(['main', 'key']),
|
|
||||||
':usr_id' => $this->app->getAuthenticatedUser()->getId(),
|
|
||||||
':record_id' => $this->getRecordId(),
|
|
||||||
]);
|
|
||||||
$rs = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
|
||||||
$stmt->closeCursor();
|
|
||||||
|
|
||||||
$set = new set_selection($this->app);
|
|
||||||
foreach ($rs as $row) {
|
|
||||||
$set->add_element(new record_adapter($this->app, $this->getDataboxId(), $row['record_id']));
|
|
||||||
}
|
|
||||||
|
|
||||||
return $set;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function hasChild(\record_adapter $record)
|
public function hasChild(\record_adapter $record)
|
||||||
|
Reference in New Issue
Block a user