mirror of
https://github.com/alchemy-fr/Phraseanet.git
synced 2025-10-23 18:03:17 +00:00
Merge pull request #1422 from bburnichon/feature/performance-pass
Apply some improvements to cache handling
This commit is contained in:
@@ -18,7 +18,7 @@ interface Cache extends DoctrineCache
|
||||
/**
|
||||
* Sets the namespace
|
||||
*
|
||||
* @param type $namespace
|
||||
* @param string $namespace
|
||||
*/
|
||||
public function setNamespace($namespace);
|
||||
|
||||
@@ -53,7 +53,7 @@ interface Cache extends DoctrineCache
|
||||
* @return string The cached data.
|
||||
* @return FALSE, if no cache entry exists for the given id.
|
||||
*
|
||||
* @throws Alchemy\Phrasea\Cache\Exception if provided key does not exist
|
||||
* @throws Exception if provided key does not exist
|
||||
*/
|
||||
public function get($key);
|
||||
|
||||
@@ -61,7 +61,7 @@ interface Cache extends DoctrineCache
|
||||
* Delete multi cache entries
|
||||
*
|
||||
* @param array $keys contains all keys to delete
|
||||
* @return Alchemy\Phrasea\Cache\Cache
|
||||
* @return Cache
|
||||
*/
|
||||
public function deleteMulti(array $keys);
|
||||
}
|
||||
|
@@ -142,13 +142,4 @@ class Databox implements ControllerProviderInterface, ServiceProviderInterface
|
||||
{
|
||||
$this->getFirewall($app)->requireRightOnSbas($request->attributes->get('databox_id'), 'bas_modify_struct');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Application $app
|
||||
* @return Firewall
|
||||
*/
|
||||
private function getFirewall(Application $app)
|
||||
{
|
||||
return $app['firewall'];
|
||||
}
|
||||
}
|
||||
|
@@ -14,6 +14,7 @@ namespace Alchemy\Phrasea\Core\Configuration;
|
||||
use Alchemy\Phrasea\Cache\Cache;
|
||||
use Alchemy\Phrasea\Model\Entities\Collection;
|
||||
use Alchemy\Phrasea\Model\Entities\Databox;
|
||||
use Assert\Assertion;
|
||||
use Psr\Log\LoggerInterface;
|
||||
|
||||
class AccessRestriction
|
||||
@@ -59,6 +60,25 @@ class AccessRestriction
|
||||
return in_array($databox->get_sbas_id(), $this->cache->fetch('available_databoxes'), true);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \databox[] $databoxes
|
||||
* @return \databox[]
|
||||
*/
|
||||
public function filterAvailableDataboxes(array $databoxes)
|
||||
{
|
||||
Assertion::allIsInstanceOf($databoxes, \databox::class);
|
||||
|
||||
if (!$this->isRestricted()) {
|
||||
return $databoxes;
|
||||
}
|
||||
|
||||
$available = array_flip($this->cache->fetch('available_databoxes'));
|
||||
|
||||
return array_filter($databoxes, function (\databox $databox) use ($available) {
|
||||
return isset($available[$databox->get_sbas_id()]);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if a collection is available given a configuration.
|
||||
*
|
||||
|
@@ -12,6 +12,9 @@
|
||||
namespace Alchemy\Phrasea\Core\Provider;
|
||||
|
||||
use Alchemy\Phrasea\Application as PhraseaApplication;
|
||||
use Alchemy\Phrasea\Databox\CachedDataboxRepository;
|
||||
use Alchemy\Phrasea\Databox\DataboxFactory;
|
||||
use Alchemy\Phrasea\Databox\DbalDataboxRepository;
|
||||
use Silex\Application;
|
||||
use Silex\ServiceProviderInterface;
|
||||
|
||||
@@ -121,6 +124,14 @@ class RepositoriesServiceProvider implements ServiceProviderInterface
|
||||
$app['repo.webhook-delivery'] = $app->share(function (PhraseaApplication $app) {
|
||||
return $app['orm.em']->getRepository('Phraseanet:WebhookEventDelivery');
|
||||
});
|
||||
|
||||
$app['repo.databoxes'] = $app->share(function (PhraseaApplication $app) {
|
||||
$factory = new DataboxFactory($app);
|
||||
$appbox = $app->getApplicationBox();
|
||||
$repository = new DbalDataboxRepository($appbox->get_connection(), $factory);
|
||||
|
||||
return new CachedDataboxRepository($repository, $app['cache'], $appbox->get_cache_key($appbox::CACHE_LIST_BASES), $factory);
|
||||
});
|
||||
}
|
||||
|
||||
public function boot(Application $app)
|
||||
|
72
lib/Alchemy/Phrasea/Databox/CachedDataboxRepository.php
Normal file
72
lib/Alchemy/Phrasea/Databox/CachedDataboxRepository.php
Normal file
@@ -0,0 +1,72 @@
|
||||
<?php
|
||||
/*
|
||||
* This file is part of Phraseanet
|
||||
*
|
||||
* (c) 2005-2015 Alchemy
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
namespace Alchemy\Phrasea\Databox;
|
||||
|
||||
use Doctrine\Common\Cache\Cache;
|
||||
|
||||
final class CachedDataboxRepository implements DataboxRepositoryInterface
|
||||
{
|
||||
/** @var DataboxRepositoryInterface */
|
||||
private $repository;
|
||||
/** @var Cache */
|
||||
private $cache;
|
||||
/** @var string */
|
||||
private $cacheKey;
|
||||
/** @var DataboxFactory */
|
||||
private $factory;
|
||||
|
||||
public function __construct(DataboxRepositoryInterface $repository, Cache $cache, $cacheKey, DataboxFactory $factory)
|
||||
{
|
||||
$this->repository = $repository;
|
||||
$this->cache = $cache;
|
||||
$this->cacheKey = $cacheKey;
|
||||
$this->factory = $factory;
|
||||
}
|
||||
|
||||
public function find($id)
|
||||
{
|
||||
$rows = $this->cache->fetch($this->cacheKey);
|
||||
|
||||
if (isset($rows[$id])) {
|
||||
return $this->factory->create($id, $rows[$id]);
|
||||
}
|
||||
|
||||
return $this->repository->find($id);
|
||||
}
|
||||
|
||||
public function findAll()
|
||||
{
|
||||
$rows = $this->cache->fetch($this->cacheKey);
|
||||
|
||||
if (is_array($rows)) {
|
||||
return $this->factory->createMany($rows);
|
||||
}
|
||||
|
||||
$databoxes = $this->repository->findAll();
|
||||
|
||||
$this->saveCache($databoxes);
|
||||
|
||||
return $databoxes;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \databox[] $databoxes
|
||||
*/
|
||||
private function saveCache(array $databoxes)
|
||||
{
|
||||
$rows = array();
|
||||
|
||||
foreach ($databoxes as $databox) {
|
||||
$rows[$databox->get_sbas_id()] = $databox->getRawData();
|
||||
}
|
||||
|
||||
$this->cache->save($this->cacheKey, $rows);
|
||||
}
|
||||
}
|
51
lib/Alchemy/Phrasea/Databox/DataboxFactory.php
Normal file
51
lib/Alchemy/Phrasea/Databox/DataboxFactory.php
Normal file
@@ -0,0 +1,51 @@
|
||||
<?php
|
||||
/*
|
||||
* This file is part of Phraseanet
|
||||
*
|
||||
* (c) 2005-2015 Alchemy
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
namespace Alchemy\Phrasea\Databox;
|
||||
|
||||
use Alchemy\Phrasea\Application;
|
||||
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
|
||||
|
||||
class DataboxFactory
|
||||
{
|
||||
/** @var Application */
|
||||
private $app;
|
||||
|
||||
public function __construct(Application $app)
|
||||
{
|
||||
$this->app = $app;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $id
|
||||
* @param array $raw
|
||||
* @throws NotFoundHttpException when Databox could not be retrieved from Persistence layer
|
||||
* @return \databox
|
||||
*/
|
||||
public function create($id, array $raw)
|
||||
{
|
||||
return new \databox($this->app, $id, $raw);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $rows
|
||||
* @throws NotFoundHttpException when Databox could not be retrieved from Persistence layer
|
||||
* @return \databox[]
|
||||
*/
|
||||
public function createMany(array $rows)
|
||||
{
|
||||
$databoxes = [];
|
||||
|
||||
foreach ($rows as $id => $raw) {
|
||||
$databoxes[$id] = new \databox($this->app, $id, $raw);
|
||||
}
|
||||
|
||||
return $databoxes;
|
||||
}
|
||||
}
|
24
lib/Alchemy/Phrasea/Databox/DataboxRepositoryInterface.php
Normal file
24
lib/Alchemy/Phrasea/Databox/DataboxRepositoryInterface.php
Normal file
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
/*
|
||||
* This file is part of Phraseanet
|
||||
*
|
||||
* (c) 2005-2015 Alchemy
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
namespace Alchemy\Phrasea\Databox;
|
||||
|
||||
interface DataboxRepositoryInterface
|
||||
{
|
||||
/**
|
||||
* @param int $id
|
||||
* @return \databox
|
||||
*/
|
||||
public function find($id);
|
||||
|
||||
/**
|
||||
* @return \databox[]
|
||||
*/
|
||||
public function findAll();
|
||||
}
|
85
lib/Alchemy/Phrasea/Databox/DbalDataboxRepository.php
Normal file
85
lib/Alchemy/Phrasea/Databox/DbalDataboxRepository.php
Normal file
@@ -0,0 +1,85 @@
|
||||
<?php
|
||||
/*
|
||||
* This file is part of Phraseanet
|
||||
*
|
||||
* (c) 2005-2015 Alchemy
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
namespace Alchemy\Phrasea\Databox;
|
||||
|
||||
use Doctrine\DBAL\Connection;
|
||||
|
||||
final class DbalDataboxRepository implements DataboxRepositoryInterface
|
||||
{
|
||||
/** @var Connection */
|
||||
private $connection;
|
||||
/** @var DataboxFactory */
|
||||
private $factory;
|
||||
|
||||
public function __construct(Connection $connection, DataboxFactory $factory)
|
||||
{
|
||||
$this->connection = $connection;
|
||||
$this->factory = $factory;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $id
|
||||
* @return \databox|null
|
||||
*/
|
||||
public function find($id)
|
||||
{
|
||||
$row = $this->fetchRow($id);
|
||||
|
||||
if (is_array($row)) {
|
||||
return $this->factory->create($id, $row);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \databox[]
|
||||
*/
|
||||
public function findAll()
|
||||
{
|
||||
return $this->factory->createMany($this->fetchRows());
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $id
|
||||
* @return false|array
|
||||
* @throws \Doctrine\DBAL\DBALException
|
||||
*/
|
||||
private function fetchRow($id)
|
||||
{
|
||||
$query = 'SELECT ord, viewname, label_en, label_fr, label_de, label_nl FROM sbas WHERE sbas_id = :id';
|
||||
$statement = $this->connection->prepare($query);
|
||||
$statement->execute(['id' => $id]);
|
||||
$row = $statement->fetch(\PDO::FETCH_ASSOC);
|
||||
$statement->closeCursor();
|
||||
|
||||
return $row;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
* @throws \Doctrine\DBAL\DBALException
|
||||
*/
|
||||
private function fetchRows()
|
||||
{
|
||||
$query = 'SELECT sbas_id, ord, viewname, label_en, label_fr, label_de, label_nl FROM sbas';
|
||||
$statement = $this->connection->prepare($query);
|
||||
$statement->execute();
|
||||
$rows = [];
|
||||
while ($row = $statement->fetch(\PDO::FETCH_ASSOC)) {
|
||||
$id = $row['sbas_id'];
|
||||
unset($row['sbas_id']);
|
||||
$rows[$id] = $row;
|
||||
}
|
||||
$statement->closeCursor();
|
||||
|
||||
return $rows;
|
||||
}
|
||||
}
|
@@ -10,6 +10,8 @@
|
||||
*/
|
||||
|
||||
use Alchemy\Phrasea\Application;
|
||||
use Alchemy\Phrasea\Core\Configuration\AccessRestriction;
|
||||
use Alchemy\Phrasea\Databox\DataboxRepositoryInterface;
|
||||
use Doctrine\ORM\Tools\SchemaTool;
|
||||
use MediaAlchemyst\Alchemyst;
|
||||
use MediaAlchemyst\Specification\Image as ImageSpecification;
|
||||
@@ -358,56 +360,14 @@ class appbox extends base
|
||||
*/
|
||||
public function get_databoxes()
|
||||
{
|
||||
if ($this->databoxes) {
|
||||
return $this->databoxes;
|
||||
if (!$this->databoxes) {
|
||||
$this->databoxes = $this->getAccessRestriction()
|
||||
->filterAvailableDataboxes($this->getDataboxRepository()->findAll());
|
||||
}
|
||||
|
||||
$ret = [];
|
||||
foreach ($this->retrieve_sbas_ids() as $sbas_id) {
|
||||
try {
|
||||
$databox = new \databox($this->app, $sbas_id);
|
||||
if (!$this->app['conf.restrictions']->isDataboxAvailable($databox)) {
|
||||
continue;
|
||||
}
|
||||
$ret[$sbas_id] = $databox;
|
||||
} catch (NotFoundHttpException $e) {
|
||||
$this->app['monolog']->error(sprintf('Databox %s is not reliable.', $sbas_id));
|
||||
}
|
||||
}
|
||||
|
||||
$this->databoxes = $ret;
|
||||
|
||||
return $this->databoxes;
|
||||
}
|
||||
|
||||
protected function retrieve_sbas_ids()
|
||||
{
|
||||
try {
|
||||
$data = $this->get_data_from_cache(self::CACHE_SBAS_IDS);
|
||||
if (is_array($data)) {
|
||||
return $data;
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
|
||||
}
|
||||
$sql = 'SELECT sbas_id FROM sbas';
|
||||
|
||||
$ret = [];
|
||||
|
||||
$stmt = $this->get_connection()->prepare($sql);
|
||||
$stmt->execute();
|
||||
$rs = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
$stmt->closeCursor();
|
||||
|
||||
foreach ($rs as $row) {
|
||||
$ret[] = (int) $row['sbas_id'];
|
||||
}
|
||||
|
||||
$this->set_data_to_cache($ret, self::CACHE_SBAS_IDS);
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
public function get_databox($sbas_id)
|
||||
{
|
||||
$databoxes = $this->get_databoxes();
|
||||
@@ -436,4 +396,20 @@ class appbox extends base
|
||||
|
||||
parent::delete_data_from_cache($option);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return AccessRestriction
|
||||
*/
|
||||
private function getAccessRestriction()
|
||||
{
|
||||
return $this->app['conf.restrictions'];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return DataboxRepositoryInterface
|
||||
*/
|
||||
private function getDataboxRepository()
|
||||
{
|
||||
return $this->app['repo.databoxes'];
|
||||
}
|
||||
}
|
||||
|
@@ -85,6 +85,9 @@ abstract class base implements cache_cacheableInterface
|
||||
return $this->connection;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \Alchemy\Phrasea\Cache\Cache
|
||||
*/
|
||||
public function get_cache()
|
||||
{
|
||||
return $this->app['cache'];
|
||||
@@ -118,7 +121,6 @@ abstract class base implements cache_cacheableInterface
|
||||
phrasea::reset_sbasDatas($appbox);
|
||||
phrasea::reset_baseDatas($appbox);
|
||||
phrasea::clear_sbas_params($this->app);
|
||||
$keys[] = $this->get_cache_key(appbox::CACHE_SBAS_IDS);
|
||||
|
||||
return $this->get_cache()->deleteMulti($keys);
|
||||
}
|
||||
@@ -133,6 +135,11 @@ abstract class base implements cache_cacheableInterface
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $option
|
||||
* @throws Exception
|
||||
* @return string
|
||||
*/
|
||||
public function get_cache_key($option = null)
|
||||
{
|
||||
throw new Exception(__METHOD__ . ' must be defined in extended class');
|
||||
|
1
lib/classes/cache/databox.php
vendored
1
lib/classes/cache/databox.php
vendored
@@ -102,7 +102,6 @@ class cache_databox
|
||||
break;
|
||||
case 'structure':
|
||||
$app->getApplicationBox()->delete_data_from_cache(\appbox::CACHE_LIST_BASES);
|
||||
$app->getApplicationBox()->delete_data_from_cache(\appbox::CACHE_SBAS_IDS);
|
||||
|
||||
$sql = 'DELETE FROM memcached
|
||||
WHERE site_id = :site_id AND type="structure" AND value = :value';
|
||||
|
@@ -23,80 +23,32 @@ use Alchemy\Phrasea\Core\PhraseaTokens;
|
||||
|
||||
class databox extends base
|
||||
{
|
||||
/**
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
/** @var int */
|
||||
protected $id;
|
||||
|
||||
/**
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
/** @var string */
|
||||
protected $structure;
|
||||
|
||||
/**
|
||||
*
|
||||
* @var Array
|
||||
*/
|
||||
/** @var array */
|
||||
protected static $_xpath_thesaurus = [];
|
||||
|
||||
/**
|
||||
*
|
||||
* @var Array
|
||||
*/
|
||||
/** @var array */
|
||||
protected static $_dom_thesaurus = [];
|
||||
|
||||
/**
|
||||
*
|
||||
* @var Array
|
||||
*/
|
||||
/** @var array */
|
||||
protected static $_thesaurus = [];
|
||||
|
||||
/**
|
||||
*
|
||||
* @var Array
|
||||
*/
|
||||
/** @var array */
|
||||
protected $_xpath_structure;
|
||||
|
||||
/**
|
||||
*
|
||||
* @var DOMDocument
|
||||
*/
|
||||
/** @var DOMDocument */
|
||||
protected $_dom_structure;
|
||||
|
||||
/**
|
||||
*
|
||||
* @var DOMDocument
|
||||
*/
|
||||
/** @var DOMDocument */
|
||||
protected $_dom_cterms;
|
||||
|
||||
/**
|
||||
*
|
||||
* @var SimpleXMLElement
|
||||
*/
|
||||
/** @var SimpleXMLElement */
|
||||
protected $_sxml_structure;
|
||||
|
||||
/**
|
||||
*
|
||||
* @var databox_descriptionStructure
|
||||
*/
|
||||
/** @var databox_descriptionStructure */
|
||||
protected $meta_struct;
|
||||
|
||||
/**
|
||||
*
|
||||
* @var databox_subdefsStructure
|
||||
*/
|
||||
/** @var databox_subdefsStructure */
|
||||
protected $subdef_struct;
|
||||
|
||||
/**
|
||||
*
|
||||
* @var SimpleXMLElement
|
||||
*/
|
||||
/** @var SimpleXMLElement */
|
||||
protected static $_sxml_thesaurus = [];
|
||||
|
||||
const BASE_TYPE = self::DATA_BOX;
|
||||
const CACHE_BASE_DATABOX = 'base_infos';
|
||||
const CACHE_META_STRUCT = 'meta_struct';
|
||||
const CACHE_THESAURUS = 'thesaurus';
|
||||
const CACHE_COLLECTIONS = 'collections';
|
||||
@@ -107,13 +59,13 @@ class databox extends base
|
||||
private $labels = [];
|
||||
private $ord;
|
||||
private $viewname;
|
||||
private $loaded = false;
|
||||
|
||||
/**
|
||||
* @param Application $app
|
||||
* @param int $sbas_id
|
||||
* @param array $row
|
||||
*/
|
||||
public function __construct(Application $app, $sbas_id)
|
||||
public function __construct(Application $app, $sbas_id, array $row)
|
||||
{
|
||||
assert(is_int($sbas_id));
|
||||
assert($sbas_id > 0);
|
||||
@@ -140,60 +92,24 @@ class databox extends base
|
||||
$this->user = $params['user'];
|
||||
$this->passwd = $params['password'];
|
||||
$this->dbname = $params['dbname'];
|
||||
}
|
||||
|
||||
private function load()
|
||||
{
|
||||
if ($this->loaded) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
$row = $this->get_data_from_cache(static::CACHE_BASE_DATABOX);
|
||||
} catch (\Exception $e) {
|
||||
$sql = 'SELECT ord, viewname, label_en, label_fr, label_de, label_nl
|
||||
FROM sbas WHERE sbas_id = :sbas_id';
|
||||
$stmt = $this->app->getApplicationBox()->get_connection()->prepare($sql);
|
||||
$stmt->execute(['sbas_id' => $this->id]);
|
||||
$row = $stmt->fetch(\PDO::FETCH_ASSOC);
|
||||
$stmt->closeCursor();
|
||||
|
||||
$this->set_data_to_cache($row, static::CACHE_BASE_DATABOX);
|
||||
}
|
||||
|
||||
if (!$row) {
|
||||
throw new NotFoundHttpException(sprintf('databox %d not found', $this->id));
|
||||
}
|
||||
|
||||
$this->ord = $row['ord'];
|
||||
$this->viewname = $row['viewname'];
|
||||
$this->labels['fr'] = $row['label_fr'];
|
||||
$this->labels['en'] = $row['label_en'];
|
||||
$this->labels['de'] = $row['label_de'];
|
||||
$this->labels['nl'] = $row['label_nl'];
|
||||
|
||||
$this->loaded = true;
|
||||
$this->loadFromRow($row);
|
||||
}
|
||||
|
||||
public function get_viewname()
|
||||
{
|
||||
$this->load();
|
||||
|
||||
return $this->viewname ? : $this->dbname;
|
||||
}
|
||||
|
||||
public function set_viewname($viewname)
|
||||
{
|
||||
$this->load();
|
||||
|
||||
$sql = 'UPDATE sbas SET viewname = :viewname WHERE sbas_id = :sbas_id';
|
||||
|
||||
$stmt = $this->app->getApplicationBox()->get_connection()->prepare($sql);
|
||||
$stmt = $this->get_appbox()->get_connection()->prepare($sql);
|
||||
$stmt->execute([':viewname' => $viewname, ':sbas_id' => $this->id]);
|
||||
$stmt->closeCursor();
|
||||
|
||||
$this->delete_data_from_cache(static::CACHE_BASE_DATABOX);
|
||||
$this->app->getApplicationBox()->delete_data_from_cache(appbox::CACHE_LIST_BASES);
|
||||
$this->get_appbox()->delete_data_from_cache(appbox::CACHE_LIST_BASES);
|
||||
cache_databox::update($this->app, $this->id, 'structure');
|
||||
|
||||
$this->viewname = $viewname;
|
||||
@@ -203,8 +119,6 @@ class databox extends base
|
||||
|
||||
public function get_ord()
|
||||
{
|
||||
$this->load();
|
||||
|
||||
return $this->ord;
|
||||
}
|
||||
|
||||
@@ -213,7 +127,7 @@ class databox extends base
|
||||
*/
|
||||
public function get_appbox()
|
||||
{
|
||||
return $this->app['phraseanet.appbox'];
|
||||
return $this->app->getApplicationBox();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -264,7 +178,7 @@ class databox extends base
|
||||
|
||||
}
|
||||
|
||||
$conn = $this->app->getApplicationBox()->get_connection();
|
||||
$conn = $this->get_appbox()->get_connection();
|
||||
|
||||
$sql = "SELECT b.server_coll_id FROM sbas s, bas b
|
||||
WHERE s.sbas_id = b.sbas_id AND b.sbas_id = :sbas_id
|
||||
@@ -299,8 +213,6 @@ class databox extends base
|
||||
|
||||
public function get_label($code, $substitute = true)
|
||||
{
|
||||
$this->load();
|
||||
|
||||
if (!array_key_exists($code, $this->labels)) {
|
||||
throw new InvalidArgumentException(sprintf('Code %s is not defined', $code));
|
||||
}
|
||||
@@ -314,22 +226,18 @@ class databox extends base
|
||||
|
||||
public function set_label($code, $label)
|
||||
{
|
||||
$this->load();
|
||||
|
||||
if (!array_key_exists($code, $this->labels)) {
|
||||
throw new InvalidArgumentException(sprintf('Code %s is not defined', $code));
|
||||
}
|
||||
|
||||
$sql = "UPDATE sbas SET label_$code = :label
|
||||
WHERE sbas_id = :sbas_id";
|
||||
$stmt = $this->app->getApplicationBox()->get_connection()->prepare($sql);
|
||||
$stmt = $this->get_appbox()->get_connection()->prepare($sql);
|
||||
$stmt->execute([':label' => $label, ':sbas_id' => $this->id]);
|
||||
$stmt->closeCursor();
|
||||
|
||||
$this->labels[$code] = $label;
|
||||
|
||||
$this->delete_data_from_cache(static::CACHE_BASE_DATABOX);
|
||||
|
||||
phrasea::reset_sbasDatas($this->app['phraseanet.appbox']);
|
||||
|
||||
return $this;
|
||||
@@ -533,17 +441,16 @@ class databox extends base
|
||||
$stmt->closeCursor();
|
||||
|
||||
$sql = "DELETE FROM sbas WHERE sbas_id = :sbas_id";
|
||||
$stmt = $this->app->getApplicationBox()->get_connection()->prepare($sql);
|
||||
$stmt = $this->get_appbox()->get_connection()->prepare($sql);
|
||||
$stmt->execute([':sbas_id' => $this->id]);
|
||||
$stmt->closeCursor();
|
||||
|
||||
$sql = "DELETE FROM sbasusr WHERE sbas_id = :sbas_id";
|
||||
$stmt = $this->app->getApplicationBox()->get_connection()->prepare($sql);
|
||||
$stmt = $this->get_appbox()->get_connection()->prepare($sql);
|
||||
$stmt->execute([':sbas_id' => $this->id]);
|
||||
$stmt->closeCursor();
|
||||
|
||||
$this->app->getApplicationBox()->delete_data_from_cache(appbox::CACHE_LIST_BASES);
|
||||
$this->app->getApplicationBox()->delete_data_from_cache(appbox::CACHE_SBAS_IDS);
|
||||
$this->get_appbox()->delete_data_from_cache(appbox::CACHE_LIST_BASES);
|
||||
|
||||
return;
|
||||
}
|
||||
@@ -694,7 +601,6 @@ class databox extends base
|
||||
$databox = $app->findDataboxById($sbas_id);
|
||||
|
||||
$databox->delete_data_from_cache(databox::CACHE_COLLECTIONS);
|
||||
$app->getApplicationBox()->delete_data_from_cache(appbox::CACHE_SBAS_IDS);
|
||||
|
||||
phrasea::reset_sbasDatas($app['phraseanet.appbox']);
|
||||
|
||||
@@ -798,7 +704,7 @@ class databox extends base
|
||||
$stmt->execute();
|
||||
$stmt->closeCursor();
|
||||
|
||||
$this->app->getApplicationBox()->delete_data_from_cache(appbox::CACHE_LIST_BASES);
|
||||
$this->get_appbox()->delete_data_from_cache(appbox::CACHE_LIST_BASES);
|
||||
|
||||
return;
|
||||
}
|
||||
@@ -845,7 +751,7 @@ class databox extends base
|
||||
public function get_mountable_colls()
|
||||
{
|
||||
/** @var Connection $conn */
|
||||
$conn = $this->app->getApplicationBox()->get_connection();
|
||||
$conn = $this->get_appbox()->get_connection();
|
||||
$colls = [];
|
||||
|
||||
$sql = 'SELECT server_coll_id FROM bas WHERE sbas_id = :sbas_id';
|
||||
@@ -888,7 +794,7 @@ class databox extends base
|
||||
public function get_activable_colls()
|
||||
{
|
||||
/** @var Connection $conn */
|
||||
$conn = $this->app->getApplicationBox()->get_connection();
|
||||
$conn = $this->get_appbox()->get_connection();
|
||||
$base_ids = [];
|
||||
|
||||
$sql = 'SELECT base_id FROM bas WHERE sbas_id = :sbas_id AND active = "0"';
|
||||
@@ -932,7 +838,7 @@ class databox extends base
|
||||
|
||||
$this->meta_struct = null;
|
||||
|
||||
$this->app->getApplicationBox()->delete_data_from_cache(appbox::CACHE_LIST_BASES);
|
||||
$this->get_appbox()->delete_data_from_cache(appbox::CACHE_LIST_BASES);
|
||||
$this->delete_data_from_cache(self::CACHE_STRUCTURE);
|
||||
$this->delete_data_from_cache(self::CACHE_META_STRUCT);
|
||||
|
||||
@@ -1062,7 +968,7 @@ class databox extends base
|
||||
*/
|
||||
public function registerAdmin(User $user)
|
||||
{
|
||||
$conn = $this->app->getApplicationBox()->get_connection();
|
||||
$conn = $this->get_appbox()->get_connection();
|
||||
|
||||
$this->app->getAclForUser($user)
|
||||
->give_access_to_sbas([$this->id])
|
||||
@@ -1575,4 +1481,34 @@ class databox extends base
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $row
|
||||
*/
|
||||
private function loadFromRow(array $row)
|
||||
{
|
||||
$this->ord = $row['ord'];
|
||||
$this->viewname = $row['viewname'];
|
||||
$this->labels['fr'] = $row['label_fr'];
|
||||
$this->labels['en'] = $row['label_en'];
|
||||
$this->labels['de'] = $row['label_de'];
|
||||
$this->labels['nl'] = $row['label_nl'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an array that can be used to restore databox.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getRawData()
|
||||
{
|
||||
return [
|
||||
'ord' => $this->ord,
|
||||
'viewname' => $this->viewname,
|
||||
'label_en' => $this->labels['en'],
|
||||
'label_fr' => $this->labels['fr'],
|
||||
'label_de' => $this->labels['de'],
|
||||
'label_nl' => $this->labels['nl'],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
@@ -111,7 +111,8 @@ class DataboxTest extends \PhraseanetAuthenticatedWebTestCase
|
||||
|
||||
$this->setAdmin(true);
|
||||
|
||||
$collection = \collection::create(self::$DI['app'], $databox, self::$DI['app']['phraseanet.appbox'], 'TESTTODELETE');
|
||||
$app = $this->getApplication();
|
||||
$collection = \collection::create($app, $databox, $app['phraseanet.appbox'], 'TESTTODELETE');
|
||||
|
||||
$this->XMLHTTPRequest('POST', '/admin/databox/' . $databox->get_sbas_id() . '/collections/order/', [
|
||||
'order' => [
|
||||
@@ -394,7 +395,8 @@ class DataboxTest extends \PhraseanetAuthenticatedWebTestCase
|
||||
$this->assertTrue(is_object($content));
|
||||
$this->assertObjectHasAttribute('sbas_id', $content, $response->getContent());
|
||||
|
||||
$this->assertTrue(!!self::$DI['app']->getApplicationBox()->is_databox_indexable(new \databox(self::$DI['app'], self::$DI['collection']->get_sbas_id())));
|
||||
$app = $this->getApplication();
|
||||
$this->assertTrue(!!$app->getApplicationBox()->is_databox_indexable($app->findDataboxById(self::$DI['collection']->get_sbas_id())));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -14,13 +14,15 @@ class SubdefsTest extends \PhraseanetAuthenticatedWebTestCase
|
||||
{
|
||||
protected $client;
|
||||
|
||||
protected $databox;
|
||||
protected $databox_id;
|
||||
|
||||
public function setUp()
|
||||
{
|
||||
parent::setUp();
|
||||
$databoxes = self::$DI['app']->getDataboxes();
|
||||
$this->databox = array_shift($databoxes);
|
||||
$databoxes = $this->getApplication()->getDataboxes();
|
||||
// Can not keep databox instance as appbox is cleared
|
||||
$databox = array_shift($databoxes);
|
||||
$this->databox_id = $databox->get_sbas_id();
|
||||
}
|
||||
|
||||
public function getSubdefName()
|
||||
@@ -33,30 +35,31 @@ class SubdefsTest extends \PhraseanetAuthenticatedWebTestCase
|
||||
*/
|
||||
public function testRouteGetSubdef()
|
||||
{
|
||||
self::$DI['client']->request("GET", "/admin/subdefs/" . $this->databox->get_sbas_id() . "/");
|
||||
self::$DI['client']->request("GET", "/admin/subdefs/" . $this->databox_id . "/");
|
||||
$this->assertTrue(self::$DI['client']->getResponse()->isOk());
|
||||
}
|
||||
|
||||
public function testPostRouteAddSubdef()
|
||||
{
|
||||
$name = $this->getSubdefName();
|
||||
self::$DI['client']->request("POST", "/admin/subdefs/" . $this->databox->get_sbas_id() . "/", ['add_subdef' => [
|
||||
self::$DI['client']->request("POST", "/admin/subdefs/" . $this->databox_id . "/", ['add_subdef' => [
|
||||
'class' => 'thumbnail',
|
||||
'name' => $name,
|
||||
'group' => 'image'
|
||||
]]);
|
||||
$this->assertTrue(self::$DI['client']->getResponse()->isRedirect());
|
||||
|
||||
$subdefs = new \databox_subdefsStructure(new \databox(self::$DI['app'], $this->databox->get_sbas_id()), self::$DI['app']['translator']);
|
||||
$app = $this->getApplication();
|
||||
$subdefs = new \databox_subdefsStructure($app->findDataboxById($this->databox_id), $app['translator']);
|
||||
$subdefs->delete_subdef('image', $name);
|
||||
}
|
||||
|
||||
public function testPostRouteDeleteSubdef()
|
||||
{
|
||||
$subdefs = $this->databox->get_subdef_structure();
|
||||
$subdefs = $this->getApplication()->findDataboxById($this->databox_id)->get_subdef_structure();
|
||||
$name = $this->getSubdefName();
|
||||
$subdefs->add_subdef("image", $name, "thumbnail");
|
||||
self::$DI['client']->request("POST", "/admin/subdefs/" . $this->databox->get_sbas_id() . "/", ['delete_subdef' => 'image_' . $name]);
|
||||
self::$DI['client']->request("POST", "/admin/subdefs/" . $this->databox_id . "/", ['delete_subdef' => 'image_' . $name]);
|
||||
$this->assertTrue(self::$DI['client']->getResponse()->isRedirect());
|
||||
try {
|
||||
$subdefs->get_subdef("image", $name);
|
||||
@@ -68,10 +71,10 @@ class SubdefsTest extends \PhraseanetAuthenticatedWebTestCase
|
||||
|
||||
public function testPostRouteAddSubdefWithNoParams()
|
||||
{
|
||||
$subdefs = $this->databox->get_subdef_structure();
|
||||
$subdefs = $this->getApplication()->findDataboxById($this->databox_id)->get_subdef_structure();
|
||||
$name = $this->getSubdefName();
|
||||
$subdefs->add_subdef("image", $name, "thumbnail");
|
||||
self::$DI['client']->request("POST", "/admin/subdefs/" . $this->databox->get_sbas_id() . "/"
|
||||
self::$DI['client']->request("POST", "/admin/subdefs/" . $this->databox_id . "/"
|
||||
, ['subdefs' => [
|
||||
'image_' . $name
|
||||
]
|
||||
@@ -87,7 +90,8 @@ class SubdefsTest extends \PhraseanetAuthenticatedWebTestCase
|
||||
);
|
||||
|
||||
$this->assertTrue(self::$DI['client']->getResponse()->isRedirect());
|
||||
$subdefs = new \databox_subdefsStructure(new \databox(self::$DI['app'], $this->databox->get_sbas_id()), self::$DI['app']['translator']);
|
||||
$app = $this->getApplication();
|
||||
$subdefs = new \databox_subdefsStructure($app->findDataboxById($this->databox_id), $app['translator']);
|
||||
$subdef = $subdefs->get_subdef("image", $name);
|
||||
|
||||
/* @var $subdef \databox_subdef */
|
||||
|
@@ -0,0 +1,117 @@
|
||||
<?php
|
||||
/*
|
||||
* This file is part of Phraseanet
|
||||
*
|
||||
* (c) 2005-2015 Alchemy
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
namespace Alchemy\Tests\Phrasea\Databox;
|
||||
|
||||
use Alchemy\Phrasea\Databox\CachedDataboxRepository;
|
||||
use Alchemy\Phrasea\Databox\DataboxFactory;
|
||||
use Alchemy\Phrasea\Databox\DataboxRepositoryInterface;
|
||||
use Doctrine\Common\Cache\Cache;
|
||||
use Prophecy\Argument;
|
||||
use Prophecy\Prophecy\ObjectProphecy;
|
||||
|
||||
final class CachedDataboxRepositoryTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
/** @var ObjectProphecy */
|
||||
private $cache;
|
||||
private $cacheKey = 'test_key';
|
||||
/** @var ObjectProphecy */
|
||||
private $factory;
|
||||
/** @var ObjectProphecy */
|
||||
private $repository;
|
||||
|
||||
/** @var CachedDataboxRepository */
|
||||
private $sut;
|
||||
|
||||
protected function setUp()
|
||||
{
|
||||
$this->cache = $this->prophesize(Cache::class);
|
||||
$this->repository = $this->prophesize(DataboxRepositoryInterface::class);
|
||||
$this->factory = $this->prophesize(DataboxFactory::class);
|
||||
|
||||
$this->sut = new CachedDataboxRepository(
|
||||
$this->repository->reveal(),
|
||||
$this->cache->reveal(),
|
||||
$this->cacheKey,
|
||||
$this->factory->reveal()
|
||||
);
|
||||
}
|
||||
|
||||
public function testItImplementsDataboxRepositoryInterface()
|
||||
{
|
||||
$this->assertInstanceOf(DataboxRepositoryInterface::class, $this->sut);
|
||||
}
|
||||
|
||||
public function testItFindsASpecificDataboxWhenNotInCache()
|
||||
{
|
||||
$databox = $this->prophesize(\databox::class);
|
||||
|
||||
$this->cache->fetch($this->cacheKey)
|
||||
->willReturn(false);
|
||||
$this->repository->find(42)
|
||||
->willReturn($databox->reveal());
|
||||
|
||||
$this->assertSame($databox->reveal(), $this->sut->find(42));
|
||||
}
|
||||
|
||||
public function testItHydrateDataboxWhenInCache()
|
||||
{
|
||||
$databox = $this->prophesize(\databox::class);
|
||||
|
||||
$this->cache->fetch($this->cacheKey)
|
||||
->willReturn([42 => ['foo' => 'bar']]);
|
||||
$this->repository->find(42)
|
||||
->shouldNotBeCalled();
|
||||
$this->factory->create(42, ['foo' => 'bar'])
|
||||
->willReturn($databox->reveal());
|
||||
|
||||
$this->assertSame($databox->reveal(), $this->sut->find(42));
|
||||
}
|
||||
|
||||
public function testItProperlySaveCacheOnFindAll()
|
||||
{
|
||||
$databox = $this->prophesize(\databox::class);
|
||||
$databox->get_sbas_id()
|
||||
->willReturn(42);
|
||||
$databox->getRawData()
|
||||
->willReturn(['foo' => 'bar']);
|
||||
|
||||
$cache_data = [42 => ['foo' => 'bar']];
|
||||
$databoxes = [42 => $databox->reveal()];
|
||||
|
||||
$this->cache->fetch($this->cacheKey)
|
||||
->willReturn(false);
|
||||
$this->repository->findAll()
|
||||
->willReturn($databoxes);
|
||||
$this->cache->save($this->cacheKey, $cache_data)
|
||||
->shouldBeCalled();
|
||||
|
||||
$this->factory->createMany(Argument::any())
|
||||
->shouldNotBeCalled();
|
||||
|
||||
$this->assertSame($databoxes, $this->sut->findAll());
|
||||
}
|
||||
|
||||
public function testItFindsAllDeclaredDataboxesFromCache()
|
||||
{
|
||||
$databox = $this->prophesize(\databox::class);
|
||||
|
||||
$cache_data = [42 => ['foo' => 'bar']];
|
||||
$databoxes = [42 => $databox->reveal()];
|
||||
|
||||
$this->cache->fetch($this->cacheKey)
|
||||
->willReturn($cache_data);
|
||||
$this->repository->findAll()
|
||||
->shouldNotBeCalled();
|
||||
$this->factory->createMany($cache_data)
|
||||
->willReturn($databoxes);
|
||||
|
||||
$this->assertSame($databoxes, $this->sut->findAll());
|
||||
}
|
||||
}
|
@@ -0,0 +1,102 @@
|
||||
<?php
|
||||
/*
|
||||
* This file is part of Phraseanet
|
||||
*
|
||||
* (c) 2005-2015 Alchemy
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
namespace Alchemy\Tests\Phrasea\Databox;
|
||||
|
||||
use Alchemy\Phrasea\Databox\DataboxFactory;
|
||||
use Alchemy\Phrasea\Databox\DataboxRepositoryInterface;
|
||||
use Alchemy\Phrasea\Databox\DbalDataboxRepository;
|
||||
use Doctrine\DBAL\Connection;
|
||||
use Doctrine\DBAL\Driver\Statement;
|
||||
use Prophecy\Argument;
|
||||
use Prophecy\Prophecy\ObjectProphecy;
|
||||
|
||||
final class DbalDataboxRepositoryTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
/** @var ObjectProphecy */
|
||||
private $connection;
|
||||
/** @var ObjectProphecy */
|
||||
private $factory;
|
||||
/** @var DbalDataboxRepository */
|
||||
private $sut;
|
||||
|
||||
protected function setUp()
|
||||
{
|
||||
$this->connection = $this->prophesize(Connection::class);
|
||||
$this->factory = $this->prophesize(DataboxFactory::class);
|
||||
|
||||
$this->sut = new DbalDataboxRepository($this->connection->reveal(), $this->factory->reveal());
|
||||
}
|
||||
|
||||
public function testItImplementsDataboxRepositoryInterface()
|
||||
{
|
||||
$this->assertInstanceOf(DataboxRepositoryInterface::class, $this->sut);
|
||||
}
|
||||
|
||||
public function testItFindsDataboxProperly()
|
||||
{
|
||||
$databox = $this->prophesize(\databox::class);
|
||||
|
||||
$statement = $this->prophesize(Statement::class);
|
||||
$this->connection
|
||||
->prepare('SELECT ord, viewname, label_en, label_fr, label_de, label_nl FROM sbas WHERE sbas_id = :id')
|
||||
->willReturn($statement->reveal());
|
||||
$statement->execute(['id' => 42])
|
||||
->shouldBeCalled();
|
||||
$statement->fetch(\PDO::FETCH_ASSOC)
|
||||
->willReturn(['foo' => 'bar']);
|
||||
$statement->closeCursor()
|
||||
->shouldBeCalled();
|
||||
|
||||
$this->factory->create(42, ['foo' => 'bar'])
|
||||
->willReturn($databox->reveal());
|
||||
|
||||
$this->assertSame($databox->reveal(), $this->sut->find(42));
|
||||
}
|
||||
|
||||
public function testItReturnsNullOnNonExistentDatabox()
|
||||
{
|
||||
$statement = $this->prophesize(Statement::class);
|
||||
$this->connection
|
||||
->prepare('SELECT ord, viewname, label_en, label_fr, label_de, label_nl FROM sbas WHERE sbas_id = :id')
|
||||
->willReturn($statement->reveal());
|
||||
$statement->execute(['id' => 42])
|
||||
->shouldBeCalled();
|
||||
$statement->fetch(\PDO::FETCH_ASSOC)
|
||||
->willReturn(false);
|
||||
$statement->closeCursor()
|
||||
->shouldBeCalled();
|
||||
|
||||
$this->factory->create(42, Argument::any())
|
||||
->shouldNotBeCalled();
|
||||
|
||||
$this->assertNull($this->sut->find(42));
|
||||
}
|
||||
|
||||
public function testItFindsAllDataboxes()
|
||||
{
|
||||
$databox = $this->prophesize(\databox::class);
|
||||
|
||||
$statement = $this->prophesize(Statement::class);
|
||||
$this->connection
|
||||
->prepare('SELECT sbas_id, ord, viewname, label_en, label_fr, label_de, label_nl FROM sbas')
|
||||
->willReturn($statement->reveal());
|
||||
$statement->execute()
|
||||
->shouldBeCalled();
|
||||
$statement->fetch(\PDO::FETCH_ASSOC)
|
||||
->willReturn(['sbas_id' => 42, 'foo' => 'bar'], false);
|
||||
$statement->closeCursor()
|
||||
->shouldBeCalled();
|
||||
|
||||
$this->factory->createMany([42 => ['foo' => 'bar']])
|
||||
->willReturn([$databox->reveal()]);
|
||||
|
||||
$this->assertSame([$databox->reveal()], $this->sut->findAll());
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user