mirror of
https://github.com/alchemy-fr/Phraseanet.git
synced 2025-10-18 07:23:13 +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) {
|
||||
return new LegacyRecordRepository($app, $databox);
|
||||
return new LegacyRecordRepository($app, $databox, $app['conf']->get(['main', 'key']));
|
||||
});
|
||||
|
||||
$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\Cache\Exception;
|
||||
use Alchemy\Phrasea\Model\Entities\User;
|
||||
use Doctrine\DBAL\Connection;
|
||||
use Doctrine\DBAL\Query\QueryBuilder;
|
||||
|
||||
class LegacyRecordRepository implements RecordRepository
|
||||
{
|
||||
/** @var Application */
|
||||
/**
|
||||
* @var Application
|
||||
*/
|
||||
private $app;
|
||||
/** @var \databox */
|
||||
|
||||
/**
|
||||
* @var \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->databox = $databox;
|
||||
$this->site = $site;
|
||||
}
|
||||
|
||||
public function find($record_id, $number = null)
|
||||
@@ -107,30 +120,124 @@ class LegacyRecordRepository implements RecordRepository
|
||||
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()
|
||||
{
|
||||
$connection = $this->databox->get_connection();
|
||||
|
||||
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'
|
||||
)
|
||||
return $this->databox->get_connection()->createQueryBuilder()
|
||||
->select($this->getRecordSelects())
|
||||
->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
|
||||
* @return \record_adapter[]
|
||||
@@ -139,8 +246,8 @@ class LegacyRecordRepository implements RecordRepository
|
||||
{
|
||||
$records = [];
|
||||
|
||||
foreach ($result as $row) {
|
||||
$records[] = $this->mapRecordFromResultRow($row);
|
||||
foreach ($result as $index => $row) {
|
||||
$records[$index] = $this->mapRecordFromResultRow($row);
|
||||
}
|
||||
|
||||
return $records;
|
||||
@@ -162,4 +269,29 @@ class LegacyRecordRepository implements RecordRepository
|
||||
|
||||
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;
|
||||
|
||||
use Alchemy\Phrasea\Model\Entities\User;
|
||||
|
||||
interface RecordRepository
|
||||
{
|
||||
/**
|
||||
@@ -35,4 +37,23 @@ interface RecordRepository
|
||||
* @return \record_adapter[]
|
||||
*/
|
||||
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');
|
||||
}
|
||||
|
||||
if ($this->app->getAuthenticatedUser()) {
|
||||
$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";
|
||||
$selections = $this->getDatabox()->getRecordRepository()->findChildren([$this->getRecordId()]);
|
||||
|
||||
$params = [
|
||||
':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;
|
||||
return reset($selections);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1604,34 +1559,9 @@ class record_adapter implements RecordInterface, cache_cacheableInterface
|
||||
*/
|
||||
public function get_grouping_parents()
|
||||
{
|
||||
$sql = "SELECT r.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 = 1\n"
|
||||
. " )\n"
|
||||
. " ON (g.rid_parent = r.record_id)\n"
|
||||
. " WHERE rid_child = :record_id";
|
||||
$selections = $this->getDatabox()->getRecordRepository()->findParents([$this->getRecordId()]);
|
||||
|
||||
$stmt = $this->getDataboxConnection()->prepare($sql);
|
||||
$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;
|
||||
return reset($selections);
|
||||
}
|
||||
|
||||
public function hasChild(\record_adapter $record)
|
||||
|
Reference in New Issue
Block a user