mirror of
https://github.com/alchemy-fr/Phraseanet.git
synced 2025-10-09 11:03:17 +00:00
377 lines
12 KiB
PHP
377 lines
12 KiB
PHP
<?php
|
|
/**
|
|
* This file is part of Phraseanet
|
|
*
|
|
* (c) 2005-2016 Alchemy
|
|
*
|
|
* For the full copyright and license information, please view the LICENSE
|
|
* file that was distributed with this source code.
|
|
*/
|
|
|
|
namespace Alchemy\Phrasea\Collection;
|
|
|
|
use Alchemy\Phrasea\Application;
|
|
use Alchemy\Phrasea\Authentication\ACLProvider;
|
|
use Alchemy\Phrasea\Collection\Reference\CollectionReference;
|
|
use Alchemy\Phrasea\Databox\DataboxConnectionProvider;
|
|
use Alchemy\Phrasea\Exception\RuntimeException;
|
|
use Alchemy\Phrasea\Model\Entities\User;
|
|
use Alchemy\Phrasea\Model\Repositories\UserRepository;
|
|
use Doctrine\DBAL\Connection;
|
|
|
|
class CollectionService
|
|
{
|
|
/**
|
|
* @var Application
|
|
*/
|
|
private $app;
|
|
|
|
/**
|
|
* @var Connection
|
|
*/
|
|
private $connection;
|
|
|
|
/**
|
|
* @var DataboxConnectionProvider
|
|
*/
|
|
private $connectionProvider;
|
|
|
|
/**
|
|
* @var callable
|
|
*/
|
|
private $userQueryFactory;
|
|
|
|
public function __construct(
|
|
Application $application,
|
|
Connection $connection,
|
|
DataboxConnectionProvider $connectionProvider,
|
|
callable $userQueryFactory
|
|
) {
|
|
$this->app = $application;
|
|
$this->connection = $connection;
|
|
$this->connectionProvider = $connectionProvider;
|
|
$this->userQueryFactory = $userQueryFactory;
|
|
}
|
|
|
|
/**
|
|
* @param Collection $collection
|
|
* @return int|null
|
|
* @throws \Doctrine\DBAL\DBALException
|
|
*/
|
|
public function getRecordCount(Collection $collection)
|
|
{
|
|
$connection = $this->connectionProvider->getConnection($collection->getDataboxId());
|
|
|
|
$sql = "SELECT COALESCE(COUNT(record_id), 0) AS recordCount FROM record WHERE coll_id = :coll_id";
|
|
$stmt = $connection->prepare($sql);
|
|
$stmt->execute([':coll_id' => $collection->getCollectionId()]);
|
|
$rowbas = $stmt->fetch(\PDO::FETCH_ASSOC);
|
|
$stmt->closeCursor();
|
|
|
|
$amount = $rowbas ? (int) $rowbas["recordCount"] : null;
|
|
|
|
return $amount;
|
|
}
|
|
|
|
/**
|
|
* @param Collection $collection
|
|
* @return array
|
|
*/
|
|
public function getRecordDetails(Collection $collection)
|
|
{
|
|
$sql = "SELECT record.coll_id,name,COALESCE(asciiname, CONCAT('_',record.coll_id)) AS asciiname,
|
|
SUM(1) AS n, SUM(size) AS size
|
|
FROM record NATURAL JOIN subdef
|
|
INNER JOIN coll ON record.coll_id=coll.coll_id AND coll.coll_id = :coll_id
|
|
GROUP BY record.coll_id, subdef.name";
|
|
|
|
$connection = $this->connectionProvider->getConnection($collection->getDataboxId());
|
|
|
|
$stmt = $connection->prepare($sql);
|
|
$stmt->execute([':coll_id' => $collection->getCollectionId()]);
|
|
$rs = $stmt->fetchAll(\PDO::FETCH_ASSOC);
|
|
$stmt->closeCursor();
|
|
|
|
$ret = [];
|
|
foreach ($rs as $row) {
|
|
$ret[] = [
|
|
"coll_id" => (int) $row["coll_id"],
|
|
"name" => $row["name"],
|
|
"amount" => (int) $row["n"],
|
|
"size" => (int) $row["size"]];
|
|
}
|
|
|
|
return $ret;
|
|
}
|
|
|
|
/**
|
|
* @param Collection $collection
|
|
* @return $this
|
|
* @throws \Doctrine\DBAL\DBALException
|
|
*/
|
|
public function resetWatermark(Collection $collection)
|
|
{
|
|
$sql = 'SELECT path, file FROM record r INNER JOIN subdef s USING(record_id)
|
|
WHERE r.coll_id = :coll_id AND r.type="image" AND s.name="preview"';
|
|
|
|
$connection = $this->connectionProvider->getConnection($collection->getDataboxId());
|
|
|
|
$stmt = $connection->prepare($sql);
|
|
$stmt->execute([':coll_id' => $collection->getCollectionId()]);
|
|
|
|
while ($row2 = $stmt->fetch(\PDO::FETCH_ASSOC)) {
|
|
@unlink(\p4string::addEndSlash($row2['path']) . 'watermark_' . $row2['file']);
|
|
}
|
|
$stmt->closeCursor();
|
|
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* @param Collection $collection
|
|
* @param int|null $record_id
|
|
* @return $this
|
|
* @throws \Doctrine\DBAL\DBALException
|
|
*/
|
|
public function resetStamp(Collection $collection, $record_id = null)
|
|
{
|
|
$sql = "SELECT path, file FROM record r INNER JOIN subdef s USING(record_id)\n"
|
|
. "WHERE r.coll_id = :coll_id\n"
|
|
. "AND r.type='image' AND s.name IN ('preview', 'document')";
|
|
|
|
$params = [':coll_id' => $collection->getCollectionId()];
|
|
|
|
if ($record_id) {
|
|
$sql .= " AND record_id = :record_id";
|
|
$params[':record_id'] = $record_id;
|
|
}
|
|
|
|
$connection = $this->connectionProvider->getConnection($collection->getDataboxId());
|
|
|
|
$stmt = $connection->prepare($sql);
|
|
$stmt->execute($params);
|
|
|
|
while ($row2 = $stmt->fetch(\PDO::FETCH_ASSOC)) {
|
|
@unlink(\p4string::addEndSlash($row2['path']) . 'stamp_' . $row2['file']);
|
|
}
|
|
$stmt->closeCursor();
|
|
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* @param \databox $databox
|
|
* @param Collection $collection
|
|
* @param CollectionReference $reference
|
|
* @throws \Doctrine\DBAL\DBALException
|
|
*/
|
|
public function delete(\databox $databox, Collection $collection, CollectionReference $reference)
|
|
{
|
|
while ($this->getRecordCount($collection) > 0) {
|
|
$this->emptyCollection($databox, $collection);
|
|
}
|
|
|
|
$connection = $this->connectionProvider->getConnection($collection->getDataboxId());
|
|
|
|
$sql = "DELETE FROM coll WHERE coll_id = :coll_id";
|
|
$stmt = $connection->prepare($sql);
|
|
$stmt->execute([':coll_id' => $collection->getCollectionId()]);
|
|
$stmt->closeCursor();
|
|
|
|
$sql = "DELETE FROM bas WHERE base_id = :base_id";
|
|
$stmt = $this->connection->prepare($sql);
|
|
$stmt->execute([':base_id' => $reference->getBaseId()]);
|
|
$stmt->closeCursor();
|
|
|
|
$sql = "DELETE FROM basusr WHERE base_id = :base_id";
|
|
$stmt = $this->connection->prepare($sql);
|
|
$stmt->execute([':base_id' => $reference->getBaseId()]);
|
|
$stmt->closeCursor();
|
|
|
|
return;
|
|
}
|
|
|
|
/**
|
|
* @param \databox $databox
|
|
* @param Collection $collection
|
|
* @param int $pass_quantity
|
|
* @return $this
|
|
* @throws \Doctrine\DBAL\DBALException
|
|
*/
|
|
public function emptyCollection(\databox $databox, Collection $collection, $pass_quantity = 100)
|
|
{
|
|
$pass_quantity = (int) $pass_quantity > 200 ? 200 : (int) $pass_quantity;
|
|
$pass_quantity = (int) $pass_quantity < 10 ? 10 : (int) $pass_quantity;
|
|
|
|
$sql = "SELECT record_id FROM record WHERE coll_id = :coll_id
|
|
ORDER BY record_id DESC LIMIT 0, " . $pass_quantity;
|
|
|
|
$connection = $this->connectionProvider->getConnection($collection->getDataboxId());
|
|
|
|
$stmt = $connection->prepare($sql);
|
|
$stmt->execute([':coll_id' => $collection->getCollectionId()]);
|
|
$rs = $stmt->fetchAll(\PDO::FETCH_ASSOC);
|
|
$stmt->closeCursor();
|
|
|
|
foreach ($rs as $row) {
|
|
$record = $databox->get_record($row['record_id']);
|
|
$record->delete();
|
|
unset($record);
|
|
}
|
|
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* Get list of the record_id
|
|
*
|
|
* @param Collection $collection
|
|
*
|
|
* @return array
|
|
*/
|
|
public function getCollectionRecordIdList(Collection $collection)
|
|
{
|
|
$sql = "SELECT record_id FROM record WHERE coll_id = :coll_id
|
|
ORDER BY record_id DESC";
|
|
|
|
$connection = $this->connectionProvider->getConnection($collection->getDataboxId());
|
|
|
|
$stmt = $connection->prepare($sql);
|
|
$stmt->execute([':coll_id' => $collection->getCollectionId()]);
|
|
$recordIdsList = $stmt->fetchAll(\PDO::FETCH_COLUMN);
|
|
$stmt->closeCursor();
|
|
|
|
return $recordIdsList;
|
|
}
|
|
|
|
/**
|
|
* @param CollectionReference $reference
|
|
* @return $this
|
|
* @throws \Doctrine\DBAL\DBALException
|
|
*/
|
|
public function unmountCollection(CollectionReference $reference)
|
|
{
|
|
$params = [':base_id' => $reference->getBaseId()];
|
|
|
|
$query = $this->app['phraseanet.user-query'];
|
|
$total = $query->on_base_ids([$reference->getBaseId()])
|
|
->include_phantoms(false)
|
|
->include_special_users(true)
|
|
->include_invite(true)
|
|
->include_templates(true)->get_total();
|
|
$n = 0;
|
|
|
|
while ($n < $total) {
|
|
$results = $query->limit($n, 50)->execute()->get_results();
|
|
|
|
foreach ($results as $user) {
|
|
$this->app->getAclForUser($user)->delete_data_from_cache(\ACL::CACHE_RIGHTS_SBAS);
|
|
$this->app->getAclForUser($user)->delete_data_from_cache(\ACL::CACHE_RIGHTS_BAS);
|
|
}
|
|
|
|
$n+=50;
|
|
}
|
|
|
|
$sql = "DELETE FROM basusr WHERE base_id = :base_id";
|
|
$stmt = $this->connection->prepare($sql);
|
|
$stmt->execute($params);
|
|
$stmt->closeCursor();
|
|
|
|
$sql = "DELETE FROM bas WHERE base_id = :base_id";
|
|
$stmt = $this->connection->prepare($sql);
|
|
$stmt->execute($params);
|
|
$stmt->closeCursor();
|
|
}
|
|
|
|
/**
|
|
* @param CollectionReference $reference
|
|
* @param User $user
|
|
*/
|
|
public function grantAdminRights(CollectionReference $reference, User $user)
|
|
{
|
|
$this->app->getAclForUser($user)->update_rights_to_base(
|
|
$reference->getBaseId(),
|
|
[
|
|
"basusr_infousr" => "", // todo : wtf
|
|
\ACL::CANPUTINALBUM => true,
|
|
\ACL::CANDWNLDHD => true,
|
|
\ACL::NOWATERMARK => true,
|
|
\ACL::CANDWNLDPREVIEW => true,
|
|
\ACL::CANCMD => true,
|
|
\ACL::CANADMIN => true,
|
|
\ACL::ACTIF => true,
|
|
\ACL::CANREPORT => true,
|
|
\ACL::CANPUSH => true,
|
|
\ACL::CANADDRECORD => true,
|
|
\ACL::CANMODIFRECORD => true,
|
|
\ACL::CANDELETERECORD => true,
|
|
\ACL::CHGSTATUS => true,
|
|
\ACL::IMGTOOLS => true,
|
|
\ACL::COLL_MANAGE => true,
|
|
\ACL::COLL_MODIFY_STRUCT => true
|
|
]
|
|
);
|
|
}
|
|
|
|
public function setOrderMasters(CollectionReference $reference, array $userIds)
|
|
{
|
|
|
|
/** @var UserRepository $userRepository */
|
|
$userRepository = $this->app['repo.users'];
|
|
$users = $userRepository->findBy(['id' => $userIds]);
|
|
|
|
$missingAdmins = array_diff($userIds, array_map(function (User $user) {
|
|
return $user->getId();
|
|
}, $users));
|
|
|
|
if (! empty($missingAdmins)) {
|
|
throw new RuntimeException(sprintf('Invalid usrIds provided [%s].', implode(',', $missingAdmins)));
|
|
}
|
|
|
|
$admins = $users;
|
|
|
|
/** @var Connection $conn */
|
|
$conn = $this->app->getApplicationBox()->get_connection();
|
|
$conn->beginTransaction();
|
|
|
|
try {
|
|
$factory = $this->userQueryFactory;
|
|
/** @var \User_Query $userQuery */
|
|
$userQuery = $factory();
|
|
|
|
$result = $userQuery->on_base_ids([ $reference->getBaseId()] )
|
|
->who_have_right([\ACL::ORDER_MASTER])
|
|
->include_templates(true)
|
|
->execute()
|
|
->get_results();
|
|
|
|
/** @var ACLProvider $acl */
|
|
$acl = $this->app['acl'];
|
|
|
|
foreach ($result as $user) {
|
|
$acl->get($user)->update_rights_to_base(
|
|
$reference->getBaseId(),
|
|
[
|
|
\ACL::ORDER_MASTER => false
|
|
]
|
|
);
|
|
}
|
|
|
|
foreach ($admins as $admin) {
|
|
$acl->get($admin)->update_rights_to_base(
|
|
$reference->getBaseId(),
|
|
[
|
|
\ACL::ORDER_MASTER => true
|
|
]
|
|
);
|
|
}
|
|
|
|
$conn->commit();
|
|
} catch (\Exception $e) {
|
|
$conn->rollBack();
|
|
throw $e;
|
|
}
|
|
|
|
}
|
|
}
|