mirror of
https://github.com/alchemy-fr/Phraseanet.git
synced 2025-10-23 18:03:17 +00:00
Merge branch 'master' into feature/ansible-provision
This commit is contained in:
@@ -9,11 +9,8 @@ env:
|
||||
php:
|
||||
- 5.5
|
||||
- 5.6
|
||||
- 7.0
|
||||
matrix:
|
||||
fast_finish: true
|
||||
allow_failures:
|
||||
- php: 7.0
|
||||
services:
|
||||
- mysql
|
||||
- memcached
|
||||
|
@@ -27,7 +27,7 @@
|
||||
"bootstrap-sass": "v2.3.2.2",
|
||||
"jquery.lazyload": "~1.9.7",
|
||||
"jquery-treeview": "~1.4.2",
|
||||
"alchemy-embed-medias": "~0.1.0"
|
||||
"alchemy-embed-medias": "~0.2.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"mocha": "latest",
|
||||
|
14
circle.yml
14
circle.yml
@@ -36,14 +36,14 @@ database:
|
||||
override:
|
||||
- mysql -u ubuntu -e 'CREATE DATABASE update39_test;CREATE DATABASE ab_test;CREATE DATABASE db_test;SET @@global.sql_mode=STRICT_ALL_TABLES;SET @@global.max_allowed_packet=33554432;SET @@global.wait_timeout=999999;';
|
||||
post:
|
||||
- "./bin/developer system:uninstall"
|
||||
- "./bin/setup system:install --email=test@phraseanet.com --password=test --db-host=127.0.0.1 --db-user=ubuntu --db-template=fr --db-password= --databox=db_test --appbox=ab_test --server-name=http://127.0.0.1 -y;"
|
||||
- "./bin/developer ini:setup-tests-dbs"
|
||||
- "./bin/console searchengine:index:create"
|
||||
- "./bin/developer phraseanet:regenerate-sqlite"
|
||||
- "./bin/developer phraseanet:generate-js-fixtures"
|
||||
- "./bin/developer system:uninstall -v"
|
||||
- "./bin/setup system:install -v --email=test@phraseanet.com --password=test --db-host=127.0.0.1 --db-user=ubuntu --db-template=fr --db-password= --databox=db_test --appbox=ab_test --server-name=http://127.0.0.1 -y;"
|
||||
- "./bin/developer ini:setup-tests-dbs -v"
|
||||
- "./bin/console searchengine:index:create -v"
|
||||
- "./bin/developer phraseanet:regenerate-sqlite -v"
|
||||
- "./bin/developer phraseanet:generate-js-fixtures -v"
|
||||
|
||||
test:
|
||||
override:
|
||||
- case $CIRCLE_NODE_INDEX in 0) php -d memory_limit=-1 bin/phpunit --exclude-group legacy ;; 1) ./node_modules/.bin/gulp test ;; 2) php -d memory_limit=-1 bin/phpunit --group legacy --exclude-group web ;; 3) php -d memory_limit=-1 bin/phpunit --group web ;; esac:
|
||||
- case $CIRCLE_NODE_INDEX in 0) php -d memory_limit=-1 bin/phpunit --log-junit $CIRCLE_TEST_REPORTS/phpunit/junit.xml --exclude-group legacy ;; 1) ./node_modules/.bin/gulp test ;; 2) php -d memory_limit=-1 bin/phpunit --log-junit $CIRCLE_TEST_REPORTS/phpunit/junit.xml --group legacy --exclude-group web ;; 3) php -d memory_limit=-1 bin/phpunit --log-junit $CIRCLE_TEST_REPORTS/phpunit/junit.xml --group web ;; esac:
|
||||
parallel: true
|
||||
|
@@ -22,10 +22,6 @@
|
||||
"type": "vcs",
|
||||
"url": "https://github.com/alchemy-fr/JMSTranslationBundle"
|
||||
},
|
||||
{
|
||||
"type": "git",
|
||||
"url": "https://github.com/alchemy-fr/symfony-cors"
|
||||
},
|
||||
{
|
||||
"type": "vcs",
|
||||
"url": "https://github.com/alchemy-fr/embed-bundle.git"
|
||||
@@ -34,7 +30,7 @@
|
||||
"require": {
|
||||
"php": ">=5.5",
|
||||
"alchemy-fr/tcpdf-clone": "~6.0",
|
||||
"alchemy/embed-bundle": "~0.1.0",
|
||||
"alchemy/embed-bundle": "^0.2.0",
|
||||
"alchemy/geonames-api-consumer": "~0.1.0",
|
||||
"alchemy/google-plus-api-client": "~0.6.2",
|
||||
"alchemy/mediavorus": "^0.4.4",
|
||||
@@ -68,6 +64,8 @@
|
||||
"jms/serializer": "~0.10",
|
||||
"jms/translation-bundle": "dev-rebase-2015-10-20",
|
||||
"justinrainbow/json-schema": "~1.3",
|
||||
"league/flysystem": "^1.0",
|
||||
"league/flysystem-aws-s3-v2": "^1.0",
|
||||
"media-alchemyst/media-alchemyst": "~0.4",
|
||||
"monolog/monolog": "~1.3",
|
||||
"mrclay/minify": "~2.1.6",
|
||||
@@ -113,7 +111,7 @@
|
||||
"include-path": ["vendor/zend/gdata/library"],
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "4.0.x-dev"
|
||||
"dev-master": "4.1.x-dev"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
967
composer.lock
generated
967
composer.lock
generated
File diff suppressed because it is too large
Load Diff
@@ -11,15 +11,13 @@
|
||||
|
||||
namespace Alchemy\Phrasea;
|
||||
|
||||
use Alchemy\Cors\Options\DefaultProvider;
|
||||
use Alchemy\CorsProvider\CorsServiceProvider;
|
||||
use Alchemy\Geonames\GeonamesServiceProvider;
|
||||
use Alchemy\Phrasea\Application\Environment;
|
||||
use Alchemy\Phrasea\Application\Helper\AclAware;
|
||||
use Alchemy\Phrasea\Application\Helper\ApplicationBoxAware;
|
||||
use Alchemy\Phrasea\Application\Helper\AuthenticatorAware;
|
||||
use Alchemy\Phrasea\Application\RouteLoader;
|
||||
use Alchemy\Phrasea\Authorization\AuthorizationServiceProvider;
|
||||
use Alchemy\Phrasea\Cache\Factory;
|
||||
use Alchemy\Phrasea\Cache\Manager;
|
||||
use Alchemy\Phrasea\Core\Event\Subscriber\BasketSubscriber;
|
||||
use Alchemy\Phrasea\Core\Event\Subscriber\BridgeSubscriber;
|
||||
use Alchemy\Phrasea\Core\Event\Subscriber\ExportSubscriber;
|
||||
@@ -29,6 +27,11 @@ use Alchemy\Phrasea\Core\Event\Subscriber\OrderSubscriber;
|
||||
use Alchemy\Phrasea\Core\Event\Subscriber\PhraseaInstallSubscriber;
|
||||
use Alchemy\Phrasea\Core\Event\Subscriber\RegistrationSubscriber;
|
||||
use Alchemy\Phrasea\Core\Event\Subscriber\ValidationSubscriber;
|
||||
use Alchemy\Phrasea\Core\MetaProvider\DatabaseMetaProvider;
|
||||
use Alchemy\Phrasea\Core\MetaProvider\HttpStackMetaProvider;
|
||||
use Alchemy\Phrasea\Core\MetaProvider\MediaUtilitiesMetaServiceProvider;
|
||||
use Alchemy\Phrasea\Core\MetaProvider\TemplateEngineMetaProvider;
|
||||
use Alchemy\Phrasea\Core\MetaProvider\TranslationMetaProvider;
|
||||
use Alchemy\Phrasea\Core\Middleware\ApiApplicationMiddlewareProvider;
|
||||
use Alchemy\Phrasea\Core\Middleware\BasketMiddlewareProvider;
|
||||
use Alchemy\Phrasea\Core\Middleware\TokenMiddlewareProvider;
|
||||
@@ -43,7 +46,6 @@ use Alchemy\Phrasea\Core\Provider\CacheConnectionServiceProvider;
|
||||
use Alchemy\Phrasea\Core\Provider\CacheServiceProvider;
|
||||
use Alchemy\Phrasea\Core\Provider\ConfigurationServiceProvider;
|
||||
use Alchemy\Phrasea\Core\Provider\ConfigurationTesterServiceProvider;
|
||||
use Alchemy\Phrasea\Core\Provider\ContentNegotiationServiceProvider;
|
||||
use Alchemy\Phrasea\Core\Provider\ConvertersServiceProvider;
|
||||
use Alchemy\Phrasea\Core\Provider\CSVServiceProvider;
|
||||
use Alchemy\Phrasea\Core\Provider\FeedServiceProvider;
|
||||
@@ -54,7 +56,6 @@ use Alchemy\Phrasea\Core\Provider\JMSSerializerServiceProvider;
|
||||
use Alchemy\Phrasea\Core\Provider\LocaleServiceProvider;
|
||||
use Alchemy\Phrasea\Core\Provider\ManipulatorServiceProvider;
|
||||
use Alchemy\Phrasea\Core\Provider\NotificationDelivererServiceProvider;
|
||||
use Alchemy\Phrasea\Core\Provider\ORMServiceProvider;
|
||||
use Alchemy\Phrasea\Core\Provider\PhraseaEventServiceProvider;
|
||||
use Alchemy\Phrasea\Core\Provider\PhraseanetServiceProvider;
|
||||
use Alchemy\Phrasea\Core\Provider\PhraseaVersionServiceProvider;
|
||||
@@ -64,69 +65,45 @@ use Alchemy\Phrasea\Core\Provider\RegistrationServiceProvider;
|
||||
use Alchemy\Phrasea\Core\Provider\RepositoriesServiceProvider;
|
||||
use Alchemy\Phrasea\Core\Provider\SearchEngineServiceProvider;
|
||||
use Alchemy\Phrasea\Core\Provider\SerializerServiceProvider;
|
||||
use Alchemy\Phrasea\Core\Provider\SessionHandlerServiceProvider;
|
||||
use Alchemy\Phrasea\Core\Provider\StatusServiceProvider;
|
||||
use Alchemy\Phrasea\Core\Provider\SubdefServiceProvider;
|
||||
use Alchemy\Phrasea\Core\Provider\TasksServiceProvider;
|
||||
use Alchemy\Phrasea\Core\Provider\TemporaryFilesystemServiceProvider;
|
||||
use Alchemy\Phrasea\Core\Provider\TokensServiceProvider;
|
||||
use Alchemy\Phrasea\Core\Provider\TranslationServiceProvider;
|
||||
use Alchemy\Phrasea\Core\Provider\UnicodeServiceProvider;
|
||||
use Alchemy\Phrasea\Core\Provider\WebhookServiceProvider;
|
||||
use Alchemy\Phrasea\Core\Provider\ZippyServiceProvider;
|
||||
use Alchemy\Phrasea\Core\Provider\WebProfilerServiceProvider as PhraseaWebProfilerServiceProvider;
|
||||
use Alchemy\Phrasea\Exception\InvalidArgumentException;
|
||||
use Alchemy\Phrasea\Filesystem\FilesystemServiceProvider;
|
||||
use Alchemy\Phrasea\Filesystem\ApplicationPathServiceGenerator;
|
||||
use Alchemy\Phrasea\Form\Extension\HelpTypeExtension;
|
||||
use Alchemy\Phrasea\Media\DatafilesResolver;
|
||||
use Alchemy\Phrasea\Media\MediaAccessorResolver;
|
||||
use Alchemy\Phrasea\Media\PermalinkMediaResolver;
|
||||
use Alchemy\Phrasea\Model\Entities\User;
|
||||
use Alchemy\Phrasea\Twig\BytesConverter;
|
||||
use Alchemy\Phrasea\Twig\Camelize;
|
||||
use Alchemy\Phrasea\Twig\Fit;
|
||||
use Alchemy\Phrasea\Twig\JSUniqueID;
|
||||
use Alchemy\Phrasea\Twig\PhraseanetExtension;
|
||||
use Alchemy\Phrasea\Utilities\CachedTranslator;
|
||||
use Dflydev\Silex\Provider\DoctrineOrm\DoctrineOrmServiceProvider;
|
||||
use Doctrine\Common\EventManager;
|
||||
use Doctrine\DBAL\Event\ConnectionEventArgs;
|
||||
use Doctrine\DBAL\Events;
|
||||
use Doctrine\ORM\Configuration;
|
||||
use FFMpeg\FFMpegServiceProvider;
|
||||
use Gedmo\DoctrineExtensions as GedmoExtension;
|
||||
use MediaAlchemyst\MediaAlchemystServiceProvider;
|
||||
use MediaVorus\Media\MediaInterface;
|
||||
use MediaVorus\MediaVorus;
|
||||
use MediaVorus\MediaVorusServiceProvider;
|
||||
use Monolog\Handler\NullHandler;
|
||||
use Monolog\Handler\RotatingFileHandler;
|
||||
use Monolog\Handler\SyslogHandler;
|
||||
use Monolog\Logger;
|
||||
use Monolog\Processor\IntrospectionProcessor;
|
||||
use MP4Box\MP4BoxServiceProvider;
|
||||
use Neutron\ReCaptcha\ReCaptchaServiceProvider;
|
||||
use Neutron\Silex\Provider\FilesystemServiceProvider;
|
||||
use Neutron\Silex\Provider\ImagineServiceProvider;
|
||||
use PHPExiftool\PHPExiftoolServiceProvider;
|
||||
use Silex\Application as SilexApplication;
|
||||
use Silex\Application\TranslationTrait;
|
||||
use Silex\Application\UrlGeneratorTrait;
|
||||
use Silex\ControllerProviderInterface;
|
||||
use Silex\Provider\DoctrineServiceProvider;
|
||||
use Silex\Provider\FormServiceProvider;
|
||||
use Silex\Provider\HttpFragmentServiceProvider;
|
||||
use Silex\Provider\MonologServiceProvider;
|
||||
use Silex\Provider\ServiceControllerServiceProvider;
|
||||
use Silex\Provider\SessionServiceProvider;
|
||||
use Silex\Provider\SwiftmailerServiceProvider;
|
||||
use Silex\Provider\TwigServiceProvider;
|
||||
use Silex\Provider\UrlGeneratorServiceProvider;
|
||||
use Silex\Provider\ValidatorServiceProvider;
|
||||
use Silex\Provider\WebProfilerServiceProvider;
|
||||
use Sorien\Provider\PimpleDumpProvider;
|
||||
use Symfony\Bridge\Twig\Extension\TranslationExtension;
|
||||
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
|
||||
use Symfony\Component\Form\Exception\ExceptionInterface;
|
||||
use Symfony\Component\Form\Exception\FormException;
|
||||
use Symfony\Component\Form\FormBuilderInterface;
|
||||
use Symfony\Component\Form\FormInterface;
|
||||
use Symfony\Component\Form\FormTypeInterface;
|
||||
use Symfony\Component\HttpFoundation\RedirectResponse;
|
||||
use Symfony\Component\HttpFoundation\Session\Storage\Handler\NullSessionHandler;
|
||||
use Symfony\Component\HttpFoundation\Session\Storage\MockArraySessionStorage;
|
||||
use Unoconv\UnoconvServiceProvider;
|
||||
use XPDF\PdfToText;
|
||||
use XPDF\XPDFServiceProvider;
|
||||
@@ -139,6 +116,10 @@ class Application extends SilexApplication
|
||||
use UrlGeneratorTrait;
|
||||
use TranslationTrait;
|
||||
|
||||
const ENV_DEV = 'dev';
|
||||
const ENV_PROD = 'prod';
|
||||
const ENV_TEST = 'test';
|
||||
|
||||
protected static $availableLanguages = [
|
||||
'de' => 'Deutsch',
|
||||
'en' => 'English',
|
||||
@@ -147,38 +128,31 @@ class Application extends SilexApplication
|
||||
];
|
||||
|
||||
private static $flashTypes = ['warning', 'info', 'success', 'error'];
|
||||
|
||||
/**
|
||||
* @var Environment
|
||||
*/
|
||||
private $environment;
|
||||
|
||||
const ENV_DEV = 'dev';
|
||||
const ENV_PROD = 'prod';
|
||||
const ENV_TEST = 'test';
|
||||
|
||||
public function getEnvironment()
|
||||
/**
|
||||
* @param Environment|string $environment
|
||||
*/
|
||||
public function __construct($environment = null)
|
||||
{
|
||||
return $this->environment;
|
||||
}
|
||||
if (is_string($environment)) {
|
||||
$environment = new Environment($environment, false);
|
||||
}
|
||||
|
||||
public function __construct($environment = self::ENV_PROD)
|
||||
{
|
||||
parent::__construct();
|
||||
$this->environment = $environment ?: new Environment(self::ENV_PROD, false);
|
||||
|
||||
error_reporting(-1);
|
||||
|
||||
$this->environment = $environment;
|
||||
parent::__construct([
|
||||
'debug' => $this->environment->isDebug()
|
||||
]);
|
||||
|
||||
$this->setupCharset();
|
||||
$this->setupApplicationPaths();
|
||||
$this->setupConstants();
|
||||
|
||||
$this['debug'] = !in_array($environment, [
|
||||
Application::ENV_PROD,
|
||||
Application::ENV_TEST,
|
||||
]);
|
||||
|
||||
if ($this['debug']) {
|
||||
ini_set('log_errors', 'on');
|
||||
ini_set('error_log', $this['root.path'].'/logs/php_error.log');
|
||||
}
|
||||
if ('allowed' == getenv('APP_CONTAINER_DUMP')) {
|
||||
$this->register(new PimpleDumpProvider());
|
||||
}
|
||||
@@ -191,11 +165,9 @@ class Application extends SilexApplication
|
||||
$this->register(new CacheConnectionServiceProvider());
|
||||
$this->register(new PhraseanetServiceProvider());
|
||||
$this->register(new ConfigurationTesterServiceProvider());
|
||||
$this->register(new DoctrineServiceProvider());
|
||||
$this->setupDBAL();
|
||||
$this->register(new DoctrineOrmServiceProvider());
|
||||
$this->setupOrms();
|
||||
$this->register(new ORMServiceProvider());
|
||||
|
||||
$this->register(new DatabaseMetaProvider());
|
||||
|
||||
$this->register(new BasketMiddlewareProvider());
|
||||
$this->register(new TokenMiddlewareProvider());
|
||||
$this->register(new AccountServiceProvider());
|
||||
@@ -208,25 +180,19 @@ class Application extends SilexApplication
|
||||
$this->register(new ConvertersServiceProvider());
|
||||
$this->register(new CSVServiceProvider());
|
||||
$this->register(new RegistrationServiceProvider());
|
||||
$this->register(new ImagineServiceProvider());
|
||||
$this->setUpImagine();
|
||||
|
||||
$this->register(new JMSSerializerServiceProvider());
|
||||
$this->register(new FFMpegServiceProvider());
|
||||
$this->register(new FeedServiceProvider());
|
||||
$this->register(new FtpServiceProvider());
|
||||
$this->register(new GeonamesServiceProvider());
|
||||
$this->register(new StatusServiceProvider());
|
||||
$this->setupGeonames();
|
||||
$this->register(new MediaAlchemystServiceProvider());
|
||||
$this->setupMediaAlchemyst();
|
||||
$this->register(new MediaVorusServiceProvider());
|
||||
$this->register(new MP4BoxServiceProvider());
|
||||
$this->register(new NotificationDelivererServiceProvider());
|
||||
$this->register(new RepositoriesServiceProvider());
|
||||
$this->register(new ManipulatorServiceProvider());
|
||||
$this->register(new InstallerServiceProvider());
|
||||
$this->register(new PhraseaVersionServiceProvider());
|
||||
$this->register(new PHPExiftoolServiceProvider());
|
||||
|
||||
$this->register(new RandomGeneratorServiceProvider());
|
||||
$this->register(new ReCaptchaServiceProvider());
|
||||
$this->register(new SubdefServiceProvider());
|
||||
@@ -238,37 +204,23 @@ class Application extends SilexApplication
|
||||
$this->register(new BorderManagerServiceProvider());
|
||||
}
|
||||
|
||||
$this->register(new SessionHandlerServiceProvider());
|
||||
$this->register(new SessionServiceProvider(), [
|
||||
'session.test' => $this->getEnvironment() === static::ENV_TEST,
|
||||
'session.storage.options' => ['cookie_lifetime' => 0]
|
||||
]);
|
||||
$this->setupSession();
|
||||
|
||||
$this->register(new SerializerServiceProvider());
|
||||
$this->register(new ServiceControllerServiceProvider());
|
||||
$this->register(new SwiftmailerServiceProvider());
|
||||
$this->setupSwiftMailer();
|
||||
$this->register(new TasksServiceProvider());
|
||||
$this->register(new TemporaryFilesystemServiceProvider());
|
||||
$this->register(new TokensServiceProvider());
|
||||
$this->register(new HttpFragmentServiceProvider());
|
||||
$this->register(new TwigServiceProvider());
|
||||
$this->setupTwig();
|
||||
$this->register(new TranslationServiceProvider(), [
|
||||
'locale_fallbacks' => ['fr'],
|
||||
'translator.cache-options' => [
|
||||
'debug' => $this['debug'],
|
||||
'cache_dir' => $this->share(function($app) {
|
||||
return $app['cache.path'].'/translations';
|
||||
}),
|
||||
],
|
||||
]);
|
||||
$this->setupTranslation();
|
||||
|
||||
$this->register(new TemplateEngineMetaProvider());
|
||||
$this->register(new HttpStackMetaProvider());
|
||||
$this->register(new MediaUtilitiesMetaServiceProvider());
|
||||
$this->register(new TranslationMetaProvider());
|
||||
|
||||
$this->register(new FormServiceProvider());
|
||||
$this->setupForm();
|
||||
$this->register(new UnoconvServiceProvider());
|
||||
$this->register(new UrlGeneratorServiceProvider());
|
||||
$this->setupUrlGenerator();
|
||||
|
||||
$this->register(new UnicodeServiceProvider());
|
||||
$this->register(new ValidatorServiceProvider());
|
||||
$this->register(new XPDFServiceProvider());
|
||||
@@ -277,108 +229,58 @@ class Application extends SilexApplication
|
||||
$this->register(new ManipulatorServiceProvider());
|
||||
$this->register(new PluginServiceProvider());
|
||||
$this->register(new PhraseaEventServiceProvider());
|
||||
$this->register(new ContentNegotiationServiceProvider());
|
||||
$this->register(new CorsServiceProvider(), [
|
||||
'alchemy_cors.debug' => $this['debug'],
|
||||
'alchemy_cors.cache_path' => function (Application $app) {
|
||||
return rtrim($app['cache.path'], '/\\') . '/alchemy_cors.cache.php';
|
||||
},
|
||||
]);
|
||||
$this['phraseanet.api_cors.options_provider'] = function (Application $app) {
|
||||
$paths = [];
|
||||
|
||||
if (isset($app['phraseanet.configuration']['api_cors'])) {
|
||||
$config = $app['phraseanet.configuration']['api_cors'];
|
||||
|
||||
if (isset($config['enabled']) && $config['enabled']) {
|
||||
unset($config['enabled']);
|
||||
|
||||
$paths['/api/v\d+/'] = $config;
|
||||
}
|
||||
}
|
||||
|
||||
return new DefaultProvider($paths, []);
|
||||
};
|
||||
|
||||
$this['alchemy_cors.options_providers'][] = 'phraseanet.api_cors.options_provider';
|
||||
$this->register(new LocaleServiceProvider());
|
||||
$this->setupEventDispatcher();
|
||||
|
||||
$this->register(new WebhookServiceProvider());
|
||||
|
||||
$this['phraseanet.exception_handler'] = $this->share(function ($app) {
|
||||
/** @var PhraseaExceptionHandler $handler */
|
||||
$handler = PhraseaExceptionHandler::register($app['debug']);
|
||||
|
||||
$handler->setTranslator($app['translator']);
|
||||
$handler->setLogger($app['monolog']);
|
||||
|
||||
return $handler;
|
||||
});
|
||||
|
||||
$providers = [
|
||||
'Alchemy\Phrasea\ControllerProvider\Admin\Collection' => [],
|
||||
'Alchemy\Phrasea\ControllerProvider\Admin\ConnectedUsers' => [],
|
||||
'Alchemy\Phrasea\ControllerProvider\Admin\Dashboard' => [],
|
||||
'Alchemy\Phrasea\ControllerProvider\Admin\Databox' => [],
|
||||
'Alchemy\Phrasea\ControllerProvider\Admin\Databoxes' => [],
|
||||
'Alchemy\Phrasea\ControllerProvider\Admin\Feeds' => [],
|
||||
'Alchemy\Phrasea\ControllerProvider\Admin\Fields' => [],
|
||||
'Alchemy\Phrasea\ControllerProvider\Admin\Plugins' => [],
|
||||
'Alchemy\Phrasea\ControllerProvider\Admin\Root' => [],
|
||||
'Alchemy\Phrasea\ControllerProvider\Admin\SearchEngine' => [],
|
||||
'Alchemy\Phrasea\ControllerProvider\Admin\Setup' => [],
|
||||
'Alchemy\Phrasea\ControllerProvider\Admin\Subdefs' => [],
|
||||
'Alchemy\Phrasea\ControllerProvider\Admin\TaskManager' => [],
|
||||
'Alchemy\Phrasea\ControllerProvider\Admin\Users' => [],
|
||||
'Alchemy\Phrasea\ControllerProvider\Client\Root' => [],
|
||||
'Alchemy\Phrasea\ControllerProvider\Datafiles' => [],
|
||||
'Alchemy\Phrasea\ControllerProvider\Lightbox' => [],
|
||||
'Alchemy\Phrasea\ControllerProvider\MediaAccessor' => [],
|
||||
'Alchemy\Phrasea\ControllerProvider\Minifier' => [],
|
||||
'Alchemy\Phrasea\ControllerProvider\Permalink' => [],
|
||||
'Alchemy\Phrasea\ControllerProvider\Prod\BasketProvider' => [],
|
||||
'Alchemy\Phrasea\ControllerProvider\Prod\Bridge' => [],
|
||||
'Alchemy\Phrasea\ControllerProvider\Prod\DoDownload' => [],
|
||||
'Alchemy\Phrasea\ControllerProvider\Prod\Download' => [],
|
||||
'Alchemy\Phrasea\ControllerProvider\Prod\Edit' => [],
|
||||
'Alchemy\Phrasea\ControllerProvider\Prod\Export' => [],
|
||||
'Alchemy\Phrasea\ControllerProvider\Prod\Feed' => [],
|
||||
'Alchemy\Phrasea\ControllerProvider\Prod\Language' => [],
|
||||
'Alchemy\Phrasea\ControllerProvider\Prod\Lazaret' => [],
|
||||
'Alchemy\Phrasea\ControllerProvider\Prod\MoveCollection' => [],
|
||||
'Alchemy\Phrasea\ControllerProvider\Prod\Order' => [],
|
||||
'Alchemy\Phrasea\ControllerProvider\Prod\Printer' => [],
|
||||
'Alchemy\Phrasea\ControllerProvider\Prod\Property' => [],
|
||||
'Alchemy\Phrasea\ControllerProvider\Prod\Push' => [],
|
||||
'Alchemy\Phrasea\ControllerProvider\Prod\Query' => [],
|
||||
'Alchemy\Phrasea\ControllerProvider\Prod\Record' => [],
|
||||
'Alchemy\Phrasea\ControllerProvider\Prod\Root' => [],
|
||||
'Alchemy\Phrasea\ControllerProvider\Prod\Share' => [],
|
||||
'Alchemy\Phrasea\ControllerProvider\Prod\Story' => [],
|
||||
'Alchemy\Phrasea\ControllerProvider\Prod\Tools' => [],
|
||||
'Alchemy\Phrasea\ControllerProvider\Prod\Tooltip' => [],
|
||||
'Alchemy\Phrasea\ControllerProvider\Prod\TOU' => [],
|
||||
'Alchemy\Phrasea\ControllerProvider\Prod\Upload' => [],
|
||||
'Alchemy\Phrasea\ControllerProvider\Prod\UsrLists' => [],
|
||||
'Alchemy\Phrasea\ControllerProvider\Prod\WorkZone' => [],
|
||||
'Alchemy\Phrasea\ControllerProvider\Report\Activity' => [],
|
||||
'Alchemy\Phrasea\ControllerProvider\Report\Information' => [],
|
||||
'Alchemy\Phrasea\ControllerProvider\Report\Root' => [],
|
||||
'Alchemy\Phrasea\ControllerProvider\Root\Account' => [],
|
||||
'Alchemy\Phrasea\ControllerProvider\Root\Developers' => [],
|
||||
'Alchemy\Phrasea\ControllerProvider\Root\Login' => [],
|
||||
'Alchemy\Phrasea\ControllerProvider\Root\Root' => [],
|
||||
'Alchemy\Phrasea\ControllerProvider\Root\RSSFeeds' => [],
|
||||
'Alchemy\Phrasea\ControllerProvider\Root\Session' => [],
|
||||
'Alchemy\Phrasea\ControllerProvider\Setup' => [],
|
||||
'Alchemy\Phrasea\ControllerProvider\Thesaurus\Thesaurus' => [],
|
||||
'Alchemy\Phrasea\ControllerProvider\Thesaurus\Xmlhttp' => [],
|
||||
'Alchemy\Phrasea\ControllerProvider\User\Notifications' => [],
|
||||
'Alchemy\Phrasea\ControllerProvider\User\Preferences' => [],
|
||||
'Alchemy\EmbedProvider\EmbedServiceProvider' => [],
|
||||
'Alchemy\EmbedProvider\OembedServiceProvider' => [],
|
||||
];
|
||||
foreach ($providers as $class => $values) {
|
||||
$this->register(new $class, $values);
|
||||
$resolvers = $this['alchemy_embed.resource_resolvers'];
|
||||
$resolvers['datafile'] = $resolvers->share(function () {
|
||||
return new DatafilesResolver($this->getApplicationBox());
|
||||
});
|
||||
|
||||
$resolvers['permalinks_permalink'] = $resolvers->share(function () {
|
||||
return new PermalinkMediaResolver($this->getApplicationBox());
|
||||
});
|
||||
|
||||
$resolvers['media_accessor'] = $resolvers->share(function () {
|
||||
return new MediaAccessorResolver(
|
||||
$this->getApplicationBox(), $this['controller.media_accessor']
|
||||
);
|
||||
});
|
||||
|
||||
if (self::ENV_DEV === $this->getEnvironment()) {
|
||||
$this->register($p = new WebProfilerServiceProvider(), [
|
||||
'profiler.cache_dir' => $this['cache.path'].'/profiler',
|
||||
]);
|
||||
|
||||
$this->register(new PhraseaWebProfilerServiceProvider());
|
||||
$this->mount('/_profiler', $p);
|
||||
|
||||
if ($this['phraseanet.configuration-tester']->isInstalled()) {
|
||||
$this['db'] = $this->share(function (self $app) {
|
||||
return $app['orm.em']->getConnection();
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function getEnvironment()
|
||||
{
|
||||
return $this->environment->getName();
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads Phraseanet plugins
|
||||
*/
|
||||
@@ -436,113 +338,6 @@ class Application extends SilexApplication
|
||||
return $this->redirect($this->url($route, $parameters));
|
||||
}
|
||||
|
||||
public function setupTwig()
|
||||
{
|
||||
$this['twig'] = $this->share(
|
||||
$this->extend('twig', function (\Twig_Environment $twig, $app) {
|
||||
$twig->setCache($app['cache.path'].'/twig');
|
||||
|
||||
$paths = [];
|
||||
if (file_exists($app['plugin.path'] . '/twig-paths.php')) {
|
||||
$paths = require $app['plugin.path'] . '/twig-paths.php';
|
||||
}
|
||||
|
||||
if ($app['browser']->isTablet() || $app['browser']->isMobile()) {
|
||||
$paths[] = $app['root.path'] . '/config/templates/mobile';
|
||||
$paths[] = $app['root.path'] . '/templates/mobile';
|
||||
$paths['phraseanet'] = $app['root.path'] . '/config/templates/mobile';
|
||||
$paths['phraseanet'] = $app['root.path'] . '/templates/mobile';
|
||||
}
|
||||
|
||||
$paths[] = $app['root.path'] . '/config/templates/web';
|
||||
$paths[] = $app['root.path'] . '/templates/web';
|
||||
$paths['phraseanet'] = $app['root.path'] . '/config/templates/web';
|
||||
$paths['phraseanet'] = $app['root.path'] . '/templates/web';
|
||||
|
||||
foreach ($paths as $namespace => $path) {
|
||||
if (!is_int($namespace)) {
|
||||
$app['twig.loader.filesystem']->addPath($path, $namespace);
|
||||
} else {
|
||||
$app['twig.loader.filesystem']->addPath($path);
|
||||
}
|
||||
}
|
||||
|
||||
$twig->addGlobal('current_date', new \DateTime());
|
||||
|
||||
$twig->addExtension(new \Twig_Extension_Core());
|
||||
$twig->addExtension(new \Twig_Extension_Optimizer());
|
||||
$twig->addExtension(new \Twig_Extension_Escaper());
|
||||
if ($app['debug']) {
|
||||
$twig->addExtension(new \Twig_Extension_Debug());
|
||||
}
|
||||
|
||||
// add filter trans
|
||||
$twig->addExtension(new TranslationExtension($app['translator']));
|
||||
// add filter localizeddate
|
||||
$twig->addExtension(new \Twig_Extensions_Extension_Intl());
|
||||
// add filters truncate, wordwrap, nl2br
|
||||
$twig->addExtension(new \Twig_Extensions_Extension_Text());
|
||||
$twig->addExtension(new JSUniqueID());
|
||||
$twig->addExtension(new Fit());
|
||||
$twig->addExtension(new Camelize());
|
||||
$twig->addExtension(new BytesConverter());
|
||||
$twig->addExtension(new PhraseanetExtension($app));
|
||||
|
||||
$twig->addFilter('serialize', new \Twig_Filter_Function('serialize'));
|
||||
$twig->addFilter('stristr', new \Twig_Filter_Function('stristr'));
|
||||
$twig->addFilter('get_class', new \Twig_Filter_Function('get_class'));
|
||||
$twig->addFilter('stripdoublequotes', new \Twig_Filter_Function('stripdoublequotes'));
|
||||
$twig->addFilter('get_collection_logo', new \Twig_Filter_Function('collection::getLogo'));
|
||||
$twig->addFilter('floor', new \Twig_Filter_Function('floor'));
|
||||
$twig->addFilter('ceil', new \Twig_Filter_Function('ceil'));
|
||||
$twig->addFilter('max', new \Twig_Filter_Function('max'));
|
||||
$twig->addFilter('min', new \Twig_Filter_Function('min'));
|
||||
$twig->addFilter('bas_labels', new \Twig_Filter_Function('phrasea::bas_labels'));
|
||||
$twig->addFilter('sbas_names', new \Twig_Filter_Function('phrasea::sbas_names'));
|
||||
$twig->addFilter('sbas_labels', new \Twig_Filter_Function('phrasea::sbas_labels'));
|
||||
$twig->addFilter('sbas_from_bas', new \Twig_Filter_Function('phrasea::sbasFromBas'));
|
||||
$twig->addFilter('key_exists', new \Twig_Filter_Function('array_key_exists'));
|
||||
$twig->addFilter('round', new \Twig_Filter_Function('round'));
|
||||
$twig->addFilter('count', new \Twig_Filter_Function('count'));
|
||||
$twig->addFilter('formatOctets', new \Twig_Filter_Function('p4string::format_octets'));
|
||||
$twig->addFilter('base_from_coll', new \Twig_Filter_Function('phrasea::baseFromColl'));
|
||||
$twig->addFilter(new \Twig_SimpleFilter('escapeSimpleQuote', function ($value) {
|
||||
return str_replace("'", "\\'", $value);
|
||||
}));
|
||||
|
||||
$twig->addFilter(new \Twig_SimpleFilter('highlight', function (\Twig_Environment $twig, $string) {
|
||||
return str_replace(['[[em]]', '[[/em]]'], ['<em>', '</em>'], $string);
|
||||
}, ['needs_environment' => true,'is_safe' => ['html']]));
|
||||
|
||||
$twig->addFilter(new \Twig_SimpleFilter('linkify', function (\Twig_Environment $twig, $string) {
|
||||
return preg_replace(
|
||||
"(([^']{1})((https?|file):((/{2,4})|(\\{2,4}))[\w:#%/;$()~_?/\-=\\\.&]*)([^']{1}))"
|
||||
, '$1 $2 <a title="' . _('Open the URL in a new window') . '" class="ui-icon ui-icon-extlink" href="$2" style="display:inline;padding:2px 5px;margin:0 4px 0 2px;" target="_blank"> </a>$7'
|
||||
, $string
|
||||
);
|
||||
}, ['needs_environment' => true, 'is_safe' => ['html']]));
|
||||
|
||||
$twig->addFilter(new \Twig_SimpleFilter('bounce', function (\Twig_Environment $twig, $fieldValue, $fieldName, $searchRequest, $sbasId) {
|
||||
// bounce value if it is present in thesaurus as well
|
||||
return "<a class=\"bounce\" onclick=\"bounce('" .$sbasId . "','"
|
||||
. str_replace("'", "\\'",$searchRequest)
|
||||
. "', '"
|
||||
. str_replace("'", "\\'", $fieldName)
|
||||
. "');return(false);\">"
|
||||
. $fieldValue
|
||||
. "</a>";
|
||||
|
||||
}, ['needs_environment' => true, 'is_safe' => ['html']]));
|
||||
|
||||
$twig->addFilter(new \Twig_SimpleFilter('escapeDoubleQuote', function ($value) {
|
||||
return str_replace('"', '\"', $value);
|
||||
}));
|
||||
|
||||
return $twig;
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a flash message for type.
|
||||
*
|
||||
@@ -619,6 +414,14 @@ class Application extends SilexApplication
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function isDebug()
|
||||
{
|
||||
return $this->environment->isDebug();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if a captcha is required for next authentication
|
||||
*
|
||||
@@ -674,75 +477,11 @@ class Application extends SilexApplication
|
||||
*/
|
||||
public function bindRoutes()
|
||||
{
|
||||
$providers = [
|
||||
'/account/' => 'Alchemy\Phrasea\ControllerProvider\Root\Account',
|
||||
'/admin/' => 'Alchemy\Phrasea\ControllerProvider\Admin\Root',
|
||||
'/admin/collection' => 'Alchemy\Phrasea\ControllerProvider\Admin\Collection',
|
||||
'/admin/connected-users' => 'Alchemy\Phrasea\ControllerProvider\Admin\ConnectedUsers',
|
||||
'/admin/dashboard' => 'Alchemy\Phrasea\ControllerProvider\Admin\Dashboard',
|
||||
'/admin/databox' => 'Alchemy\Phrasea\ControllerProvider\Admin\Databox',
|
||||
'/admin/databoxes' => 'Alchemy\Phrasea\ControllerProvider\Admin\Databoxes',
|
||||
'/admin/fields' => 'Alchemy\Phrasea\ControllerProvider\Admin\Fields',
|
||||
'/admin/publications' => 'Alchemy\Phrasea\ControllerProvider\Admin\Feeds',
|
||||
'/admin/plugins' => 'Alchemy\Phrasea\ControllerProvider\Admin\Plugins',
|
||||
'/admin/search-engine' => 'Alchemy\Phrasea\ControllerProvider\Admin\SearchEngine',
|
||||
'/admin/setup' => 'Alchemy\Phrasea\ControllerProvider\Admin\Setup',
|
||||
'/admin/subdefs' => 'Alchemy\Phrasea\ControllerProvider\Admin\Subdefs',
|
||||
'/admin/task-manager' => 'Alchemy\Phrasea\ControllerProvider\Admin\TaskManager',
|
||||
'/admin/users' => 'Alchemy\Phrasea\ControllerProvider\Admin\Users',
|
||||
'/client/' => 'Alchemy\Phrasea\ControllerProvider\Client\Root',
|
||||
'/datafiles' => 'Alchemy\Phrasea\ControllerProvider\Datafiles',
|
||||
'/developers/' => 'Alchemy\Phrasea\ControllerProvider\Root\Developers',
|
||||
'/download/' => 'Alchemy\Phrasea\ControllerProvider\Prod\DoDownload',
|
||||
'/embed/' => 'Alchemy\EmbedProvider\EmbedServiceProvider',
|
||||
'/oembed/' => 'Alchemy\EmbedProvider\OembedServiceProvider',
|
||||
'/feeds/' => 'Alchemy\Phrasea\ControllerProvider\Root\RSSFeeds',
|
||||
'/include/minify' => 'Alchemy\Phrasea\ControllerProvider\Minifier',
|
||||
'/login/' => 'Alchemy\Phrasea\ControllerProvider\Root\Login',
|
||||
'/lightbox' => 'Alchemy\Phrasea\ControllerProvider\Lightbox',
|
||||
'/permalink' => 'Alchemy\Phrasea\ControllerProvider\Permalink',
|
||||
'/prod/baskets' => 'Alchemy\Phrasea\ControllerProvider\Prod\BasketProvider',
|
||||
'/prod/bridge/' => 'Alchemy\Phrasea\ControllerProvider\Prod\Bridge',
|
||||
'/prod/download' => 'Alchemy\Phrasea\ControllerProvider\Prod\Download',
|
||||
'/prod/export/' => 'Alchemy\Phrasea\ControllerProvider\Prod\Export',
|
||||
'/prod/feeds' => 'Alchemy\Phrasea\ControllerProvider\Prod\Feed',
|
||||
'/prod/language' => 'Alchemy\Phrasea\ControllerProvider\Prod\Language',
|
||||
'/prod/lazaret/' => 'Alchemy\Phrasea\ControllerProvider\Prod\Lazaret',
|
||||
'/prod/lists' => 'Alchemy\Phrasea\ControllerProvider\Prod\UsrLists',
|
||||
'/prod/order/' => 'Alchemy\Phrasea\ControllerProvider\Prod\Order',
|
||||
'/prod/printer/' => 'Alchemy\Phrasea\ControllerProvider\Prod\Printer',
|
||||
'/prod/push/' => 'Alchemy\Phrasea\ControllerProvider\Prod\Push',
|
||||
'/prod/query/' => 'Alchemy\Phrasea\ControllerProvider\Prod\Query',
|
||||
'/prod/records/' => 'Alchemy\Phrasea\ControllerProvider\Prod\Record',
|
||||
'/prod/records/edit' => 'Alchemy\Phrasea\ControllerProvider\Prod\Edit',
|
||||
'/prod/records/movecollection' => 'Alchemy\Phrasea\ControllerProvider\Prod\MoveCollection',
|
||||
'/prod/records/property' => 'Alchemy\Phrasea\ControllerProvider\Prod\Property',
|
||||
'/prod/share/' => 'Alchemy\Phrasea\ControllerProvider\Prod\Share',
|
||||
'/prod/story' => 'Alchemy\Phrasea\ControllerProvider\Prod\Story',
|
||||
'/prod/tools/' => 'Alchemy\Phrasea\ControllerProvider\Prod\Tools',
|
||||
'/prod/tooltip' => 'Alchemy\Phrasea\ControllerProvider\Prod\Tooltip',
|
||||
'/prod/TOU/' => 'Alchemy\Phrasea\ControllerProvider\Prod\TOU',
|
||||
'/prod/upload/' => 'Alchemy\Phrasea\ControllerProvider\Prod\Upload',
|
||||
'/prod/WorkZone' => 'Alchemy\Phrasea\ControllerProvider\Prod\WorkZone',
|
||||
'/prod/' => 'Alchemy\Phrasea\ControllerProvider\Prod\Root',
|
||||
'/report/activity' => 'Alchemy\Phrasea\ControllerProvider\Report\Activity',
|
||||
'/report/informations' => 'Alchemy\Phrasea\ControllerProvider\Report\Information',
|
||||
'/report/' => 'Alchemy\Phrasea\ControllerProvider\Report\Root',
|
||||
'/session/' => 'Alchemy\Phrasea\ControllerProvider\Root\Session',
|
||||
'/setup' => 'Alchemy\Phrasea\ControllerProvider\Setup',
|
||||
'/thesaurus' => 'Alchemy\Phrasea\ControllerProvider\Thesaurus\Thesaurus',
|
||||
'/user/notifications/' => 'Alchemy\Phrasea\ControllerProvider\User\Notifications',
|
||||
'/user/preferences/' => 'Alchemy\Phrasea\ControllerProvider\User\Preferences',
|
||||
'/xmlhttp' => 'Alchemy\Phrasea\ControllerProvider\Thesaurus\Xmlhttp',
|
||||
'/' => 'Alchemy\Phrasea\ControllerProvider\Root\Root',
|
||||
];
|
||||
$loader = new RouteLoader();
|
||||
|
||||
// controllers with routes referenced by api
|
||||
$providers[$this['controller.media_accessor.route_prefix']] = 'Alchemy\Phrasea\ControllerProvider\MediaAccessor';
|
||||
foreach ($providers as $prefix => $class) {
|
||||
$this->mount($prefix, new $class);
|
||||
}
|
||||
$loader->registerProviders(RouteLoader::$defaultProviders);
|
||||
|
||||
$loader->bindRoutes($this);
|
||||
$this->bindPluginRoutes('plugin.controller_providers.root');
|
||||
}
|
||||
|
||||
@@ -786,86 +525,53 @@ class Application extends SilexApplication
|
||||
// app root path
|
||||
$this['root.path'] = realpath(__DIR__ . '/../../..');
|
||||
// temporary resources default path such as download zip, quarantined documents etc ..
|
||||
$this['tmp.path'] = $this['root.path'].'/tmp';
|
||||
$this['tmp.path'] = getenv('PHRASEANET_TMP') ?: $this['root.path'].'/tmp';
|
||||
// plugin path
|
||||
$this['plugin.path'] = $dir = $this['root.path'].'/plugins';
|
||||
$this['plugin.path'] = $this['root.path'].'/plugins';
|
||||
// thumbnails path
|
||||
$this['thumbnail.path'] = $dir = $this['root.path'].'/www/thumbnails';
|
||||
$this['thumbnail.path'] = $this['root.path'].'/www/thumbnails';
|
||||
|
||||
// cache path (twig, minify, translations, configuration, doctrine metas serializer metas, profiler etc ...)
|
||||
$this['cache.path'] = $this->share(function() {
|
||||
$defaultPath = $path = $this['root.path'].'/cache';
|
||||
if ($this['phraseanet.configuration']->isSetup()) {
|
||||
$path = $this['conf']->get(['main', 'storage', 'cache'], $path);
|
||||
$factory = new ApplicationPathServiceGenerator();
|
||||
|
||||
$this['cache.path'] = $factory->createDefinition(
|
||||
['main', 'storage', 'cache'],
|
||||
function (Application $app) {
|
||||
return $app['root.path'].'/cache';
|
||||
}
|
||||
$path = $path ?: $defaultPath;
|
||||
|
||||
// ensure path is created
|
||||
$this['filesystem']->mkdir($path);
|
||||
|
||||
return $path;
|
||||
});
|
||||
);
|
||||
$this['cache.paths'] = function (Application $app) {
|
||||
return new \ArrayObject([
|
||||
$app['cache.path'],
|
||||
]);
|
||||
};
|
||||
|
||||
// log path
|
||||
$this['log.path'] = $this->share(function() {
|
||||
$defaultPath = $path = $this['root.path'].'/logs';
|
||||
if ($this['phraseanet.configuration']->isSetup()) {
|
||||
return $this['conf']->get(['main', 'storage', 'log'], $path);
|
||||
$this['log.path'] = $factory->createDefinition(
|
||||
['main', 'storage', 'log'],
|
||||
function (Application $app) {
|
||||
return $app['root.path'].'/logs';
|
||||
}
|
||||
$path = $path ?: $defaultPath;
|
||||
);
|
||||
|
||||
// ensure path is created
|
||||
$this['filesystem']->mkdir($path);
|
||||
|
||||
return $path;
|
||||
});
|
||||
|
||||
// temporary download file path (zip file)
|
||||
$this['tmp.download.path'] = $this->share(function() {
|
||||
$defaultPath = $path = $this['tmp.path'].'/download';
|
||||
if ($this['phraseanet.configuration']->isSetup()) {
|
||||
return $this['conf']->get(['main', 'storage', 'download'], $path);
|
||||
$this['tmp.download.path'] = $factory->createDefinition(
|
||||
['main', 'storage', 'download'],
|
||||
function (Application $app) {
|
||||
return $app['tmp.path'].'/download';
|
||||
}
|
||||
$path = $path ?: $defaultPath;
|
||||
);
|
||||
|
||||
// ensure path is created
|
||||
$this['filesystem']->mkdir($path);
|
||||
|
||||
return $path;
|
||||
});
|
||||
|
||||
// quarantined file path
|
||||
$this['tmp.lazaret.path'] = $this->share(function() {
|
||||
$defaultPath = $path = $this['tmp.path'].'/lazaret';
|
||||
if ($this['phraseanet.configuration']->isSetup()) {
|
||||
return $this['conf']->get(['main', 'storage', 'quarantine'], $path);
|
||||
$this['tmp.lazaret.path'] = $factory->createDefinition(
|
||||
['main', 'storage', 'quarantine'],
|
||||
function (Application $app) {
|
||||
return $app['tmp.path'].'/lazaret';
|
||||
}
|
||||
$path = $path ?: $defaultPath;
|
||||
);
|
||||
|
||||
// ensure path is created
|
||||
$this['filesystem']->mkdir($path);
|
||||
|
||||
return $path;
|
||||
});
|
||||
|
||||
// document caption file path
|
||||
$this['tmp.caption.path'] = $this->share(function() {
|
||||
$defaultPath = $path = $this['tmp.path'].'/caption';
|
||||
if ($this['phraseanet.configuration']->isSetup()) {
|
||||
return $this['conf']->get(['main', 'storage', 'caption'], $path);
|
||||
$this['tmp.caption.path'] = $factory->createDefinition(
|
||||
['main', 'storage', 'caption'],
|
||||
function (Application $app) {
|
||||
return $app['tmp.path'].'/caption';
|
||||
}
|
||||
$path = $path ?: $defaultPath;
|
||||
|
||||
// ensure path is created
|
||||
$this['filesystem']->mkdir($path);
|
||||
|
||||
return $path;
|
||||
});
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -891,98 +597,6 @@ class Application extends SilexApplication
|
||||
}));
|
||||
}
|
||||
|
||||
private function setUpImagine()
|
||||
{
|
||||
$this['imagine.factory'] = $this->share(function (Application $app) {
|
||||
if ($app['conf']->get(['registry', 'executables', 'imagine-driver']) != '') {
|
||||
return $app['conf']->get(['registry', 'executables', 'imagine-driver']);
|
||||
}
|
||||
if (class_exists('\Gmagick')) {
|
||||
return 'gmagick';
|
||||
}
|
||||
if (class_exists('\Imagick')) {
|
||||
return 'imagick';
|
||||
}
|
||||
if (extension_loaded('gd')) {
|
||||
return 'gd';
|
||||
}
|
||||
|
||||
throw new \RuntimeException('No Imagine driver available');
|
||||
});
|
||||
}
|
||||
|
||||
private function setupTranslation()
|
||||
{
|
||||
$this['translator'] = $this->share($this->extend('translator', function (CachedTranslator $translator, Application $app) {
|
||||
$translator->addResource('xlf', __DIR__.'/../../../resources/locales/messages.fr.xlf', 'fr', 'messages');
|
||||
$translator->addResource('xlf', __DIR__.'/../../../resources/locales/validators.fr.xlf', 'fr', 'validators');
|
||||
$translator->addResource('xlf', __DIR__.'/../../../resources/locales/messages.en.xlf', 'en', 'messages');
|
||||
$translator->addResource('xlf', __DIR__.'/../../../resources/locales/validators.en.xlf', 'en', 'validators');
|
||||
$translator->addResource('xlf', __DIR__.'/../../../resources/locales/messages.de.xlf', 'de', 'messages');
|
||||
$translator->addResource('xlf', __DIR__.'/../../../resources/locales/validators.de.xlf', 'de', 'validators');
|
||||
$translator->addResource('xlf', __DIR__.'/../../../resources/locales/messages.nl.xlf', 'nl', 'messages');
|
||||
$translator->addResource('xlf', __DIR__.'/../../../resources/locales/validators.nl.xlf', 'nl', 'validators');
|
||||
|
||||
return $translator;
|
||||
}));
|
||||
}
|
||||
|
||||
private function setupOrms()
|
||||
{
|
||||
$app = $this;
|
||||
|
||||
// Override "orm.cache.configurer" service provided for benefiting
|
||||
// of "phraseanet.cache-service"
|
||||
$app['orm.cache.configurer'] = $app->protect(function($name, Configuration $config, $options) use ($app) {
|
||||
/** @var Manager $service */
|
||||
$service = $app['phraseanet.cache-service'];
|
||||
$config->setMetadataCacheImpl(
|
||||
$service->factory('ORM_metadata', $app['orm.cache.driver'], $app['orm.cache.options'])
|
||||
);
|
||||
$config->setQueryCacheImpl(
|
||||
$service->factory('ORM_query', $app['orm.cache.driver'], $app['orm.cache.options'])
|
||||
);
|
||||
$config->setResultCacheImpl(
|
||||
$service->factory('ORM_result', $app['orm.cache.driver'], $app['orm.cache.options'])
|
||||
);
|
||||
$config->setHydrationCacheImpl(
|
||||
$service->factory('ORM_hydration', $app['orm.cache.driver'], $app['orm.cache.options'])
|
||||
);
|
||||
});
|
||||
$app['orm.proxies_dir'] = $app['root.path'].'/resources/proxies';
|
||||
$app['orm.auto_generate_proxies'] = $app['debug'];
|
||||
$app['orm.proxies_namespace'] = 'Alchemy\Phrasea\Model\Proxies';
|
||||
|
||||
$this['orm.ems'] = $this->share($this->extend('orm.ems', function (\Pimple $ems, $app) {
|
||||
GedmoExtension::registerAnnotations();
|
||||
|
||||
foreach ($ems->keys() as $key) {
|
||||
$app['orm.annotation.register']($key);
|
||||
$connection = $ems[$key]->getConnection();
|
||||
|
||||
$app['connection.pool.manager']->add($connection);
|
||||
|
||||
$types = $app['orm.ems.options'][$key]['types'];
|
||||
$app['dbal.type.register']($connection, $types);
|
||||
}
|
||||
|
||||
return $ems;
|
||||
}));
|
||||
}
|
||||
|
||||
private function setupSession()
|
||||
{
|
||||
$this['session.storage.test'] = $this->share(function (Application $app) {
|
||||
return new MockArraySessionStorage();
|
||||
});
|
||||
|
||||
$this['session.storage.handler'] = $this->share(function (Application $app) {
|
||||
if (!$this['phraseanet.configuration-tester']->isInstalled()) {
|
||||
return new NullSessionHandler();
|
||||
}
|
||||
return $this['session.storage.handler.factory']->create($app['conf']);
|
||||
});
|
||||
}
|
||||
private function setupRecaptacha()
|
||||
{
|
||||
$this['recaptcha.public-key'] = $this->share(function (Application $app) {
|
||||
@@ -1000,38 +614,10 @@ class Application extends SilexApplication
|
||||
private function setupGeonames()
|
||||
{
|
||||
$this['geonames.server-uri'] = $this->share(function (Application $app) {
|
||||
|
||||
return $app['conf']->get(['registry', 'webservices', 'geonames-server'], 'http://geonames.alchemyasp.com/');
|
||||
});
|
||||
}
|
||||
|
||||
private function setupDBAL()
|
||||
{
|
||||
$this['dbs.config'] = $this->share($this->extend('dbs.config', function ($configs, $app) {
|
||||
if ($app->getEnvironment() !== self::ENV_DEV) {
|
||||
return $configs;
|
||||
}
|
||||
|
||||
foreach($configs->keys() as $service) {
|
||||
$app['dbal.config.register.loggers']($configs[$service]);
|
||||
}
|
||||
|
||||
return $configs;
|
||||
}));
|
||||
|
||||
$this['dbs.event_manager'] = $this->share($this->extend('dbs.event_manager', function ($eventManagers, $app) {
|
||||
foreach ($eventManagers->keys() as $name) {
|
||||
/** @var EventManager $eventManager */
|
||||
$eventManager = $eventManagers[$name];
|
||||
$app['dbal.evm.register.listeners']($eventManager);
|
||||
|
||||
$eventManager->addEventListener(Events::postConnect, $this);
|
||||
}
|
||||
|
||||
return $eventManagers;
|
||||
}));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ConnectionEventArgs $args
|
||||
* @throws \Doctrine\DBAL\DBALException
|
||||
@@ -1043,60 +629,6 @@ class Application extends SilexApplication
|
||||
}
|
||||
}
|
||||
|
||||
private function setupMediaAlchemyst()
|
||||
{
|
||||
$this['media-alchemyst.configuration'] = $this->share(function (Application $app) {
|
||||
$configuration = [];
|
||||
|
||||
foreach ([
|
||||
'swftools.pdf2swf.binaries' => 'pdf2swf_binary',
|
||||
'swftools.swfrender.binaries' => 'swf_render_binary',
|
||||
'swftools.swfextract.binaries' => 'swf_extract_binary',
|
||||
'unoconv.binaries' => 'unoconv_binary',
|
||||
'mp4box.binaries' => 'mp4box_binary',
|
||||
'gs.binaries' => 'ghostscript_binary',
|
||||
'ffmpeg.ffmpeg.binaries' => 'ffmpeg_binary',
|
||||
'ffmpeg.ffprobe.binaries' => 'ffprobe_binary',
|
||||
'ffmpeg.ffmpeg.timeout' => 'ffmpeg_timeout',
|
||||
'ffmpeg.ffprobe.timeout' => 'ffprobe_timeout',
|
||||
'gs.timeout' => 'gs_timeout',
|
||||
'mp4box.timeout' => 'mp4box_timeout',
|
||||
'swftools.timeout' => 'swftools_timeout',
|
||||
'unoconv.timeout' => 'unoconv_timeout',
|
||||
] as $parameter => $key) {
|
||||
if ($this['conf']->has(['main', 'binaries', $key])) {
|
||||
$configuration[$parameter] = $this['conf']->get(['main', 'binaries', $key]);
|
||||
}
|
||||
}
|
||||
|
||||
$configuration['ffmpeg.threads'] = $app['conf']->get(['registry', 'executables', 'ffmpeg-threads']) ?: null;
|
||||
$configuration['imagine.driver'] = $app['conf']->get(['registry', 'executables', 'imagine-driver']) ?: null;
|
||||
|
||||
return $configuration;
|
||||
});
|
||||
$this['media-alchemyst.logger'] = $this->share(function (Application $app) {
|
||||
return $app['monolog'];
|
||||
});
|
||||
}
|
||||
|
||||
private function setupUrlGenerator()
|
||||
{
|
||||
$this['url_generator'] = $this->share($this->extend('url_generator', function ($urlGenerator, Application $app) {
|
||||
if ($app['configuration.store']->isSetup()) {
|
||||
$data = parse_url($app['conf']->get('servername'));
|
||||
|
||||
if (isset($data['scheme'])) {
|
||||
$urlGenerator->getContext()->setScheme($data['scheme']);
|
||||
}
|
||||
if (isset($data['host'])) {
|
||||
$urlGenerator->getContext()->setHost($data['host']);
|
||||
}
|
||||
}
|
||||
|
||||
return $urlGenerator;
|
||||
}));
|
||||
}
|
||||
|
||||
private function setupSwiftMailer()
|
||||
{
|
||||
$this['swiftmailer.transport'] = $this->share(function (Application $app) {
|
||||
@@ -1161,8 +693,7 @@ class Application extends SilexApplication
|
||||
private function setupEventDispatcher()
|
||||
{
|
||||
$this['dispatcher'] = $this->share(
|
||||
$this->extend('dispatcher', function ($dispatcher, Application $app) {
|
||||
//$dispatcher->addListener(KernelEvents::RESPONSE, [$app, 'addUTF8Charset'], -128);
|
||||
$this->extend('dispatcher', function (EventDispatcherInterface $dispatcher, Application $app) {
|
||||
$dispatcher->addSubscriber($app['phraseanet.logout-subscriber']);
|
||||
$dispatcher->addSubscriber($app['phraseanet.locale-subscriber']);
|
||||
$dispatcher->addSubscriber($app['phraseanet.content-negotiation-subscriber']);
|
||||
@@ -1190,12 +721,15 @@ class Application extends SilexApplication
|
||||
if (!defined('JETON_MAKE_SUBDEF')) {
|
||||
define('JETON_MAKE_SUBDEF', 0x01);
|
||||
}
|
||||
|
||||
if (!defined('JETON_WRITE_META_DOC')) {
|
||||
define('JETON_WRITE_META_DOC', 0x02);
|
||||
}
|
||||
|
||||
if (!defined('JETON_WRITE_META_SUBDEF')) {
|
||||
define('JETON_WRITE_META_SUBDEF', 0x04);
|
||||
}
|
||||
|
||||
if (!defined('JETON_WRITE_META')) {
|
||||
define('JETON_WRITE_META', 0x06);
|
||||
}
|
||||
@@ -1212,30 +746,8 @@ class Application extends SilexApplication
|
||||
*/
|
||||
public function bindPluginRoutes($routeParameter)
|
||||
{
|
||||
foreach ($this[$routeParameter] as $provider) {
|
||||
$prefix = '';
|
||||
$loader = new RouteLoader();
|
||||
|
||||
if (is_array($provider)) {
|
||||
$providerDefinition = $provider;
|
||||
list($prefix, $provider) = $providerDefinition;
|
||||
}
|
||||
|
||||
if (!is_string($prefix) || !is_string($provider)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$prefix = '/' . ltrim($prefix, '/');
|
||||
if (!isset($this[$provider])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$provider = $this[$provider];
|
||||
|
||||
if (!$provider instanceof ControllerProviderInterface) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$this->mount($prefix, $provider);
|
||||
}
|
||||
$loader->bindPluginRoutes($this, $routeParameter);
|
||||
}
|
||||
}
|
||||
|
@@ -52,10 +52,10 @@ return call_user_func(function ($environment = PhraseaApplication::ENV_PROD) {
|
||||
}));
|
||||
|
||||
$app['phraseanet.content-negotiation.priorities'] = array_merge(
|
||||
['application/json', 'application/yaml', 'text/yaml', 'text/javascript', 'application/javascript'],
|
||||
V1::$extendedContentTypes['json'],
|
||||
V1::$extendedContentTypes['jsonp'],
|
||||
V1::$extendedContentTypes['yaml'],
|
||||
['application/json', 'application/yaml', 'text/yaml', 'text/javascript', 'application/javascript']
|
||||
V1::$extendedContentTypes['yaml']
|
||||
);
|
||||
|
||||
$app['phraseanet.content-negotiation.custom_formats'] = [
|
||||
|
56
lib/Alchemy/Phrasea/Application/ApplicationLoader.php
Normal file
56
lib/Alchemy/Phrasea/Application/ApplicationLoader.php
Normal file
@@ -0,0 +1,56 @@
|
||||
<?php
|
||||
|
||||
namespace Alchemy\Phrasea\Application;
|
||||
|
||||
use Alchemy\Phrasea\Application;
|
||||
use Alchemy\Phrasea\Core\Event\Subscriber\BridgeExceptionSubscriber;
|
||||
use Alchemy\Phrasea\Core\Event\Subscriber\DebuggerSubscriber;
|
||||
use Alchemy\Phrasea\Core\Event\Subscriber\FirewallSubscriber;
|
||||
use Alchemy\Phrasea\Core\Event\Subscriber\JsonRequestSubscriber;
|
||||
use Alchemy\Phrasea\Core\Event\Subscriber\PhraseaExceptionHandlerSubscriber;
|
||||
use Alchemy\Phrasea\Core\Middleware\SetupMiddlewareProvider;
|
||||
use Monolog\Logger;
|
||||
use Symfony\Bridge\Monolog\Processor\WebProcessor;
|
||||
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
|
||||
|
||||
class ApplicationLoader
|
||||
{
|
||||
|
||||
public function buildWebApplication($environment = Application::ENV_PROD, $forceDebug = false)
|
||||
{
|
||||
$env = new Environment($environment, false);
|
||||
$app = new Application($env);
|
||||
|
||||
$app->register(new SetupMiddlewareProvider());
|
||||
$app->loadPlugins();
|
||||
|
||||
$app['exception_handler'] = $app->share(function ($app) {
|
||||
return new PhraseaExceptionHandlerSubscriber($app['phraseanet.exception_handler']);
|
||||
});
|
||||
|
||||
$app['monolog'] = $app->share($app->extend('monolog', function (Logger $monolog) {
|
||||
$monolog->pushProcessor(new WebProcessor());
|
||||
|
||||
return $monolog;
|
||||
}));
|
||||
|
||||
$app->before($app['setup.validate-config'], Application::EARLY_EVENT);
|
||||
$app->bindRoutes();
|
||||
|
||||
$app['dispatcher'] = $app->share(
|
||||
$app->extend('dispatcher', function (EventDispatcherInterface $dispatcher, Application $app) {
|
||||
$dispatcher->addSubscriber(new BridgeExceptionSubscriber($app));
|
||||
$dispatcher->addSubscriber(new FirewallSubscriber());
|
||||
$dispatcher->addSubscriber(new JsonRequestSubscriber());
|
||||
|
||||
if ($app->isDebug()){
|
||||
$dispatcher->addSubscriber(new DebuggerSubscriber($app));
|
||||
}
|
||||
|
||||
return $dispatcher;
|
||||
})
|
||||
);
|
||||
|
||||
return $app;
|
||||
}
|
||||
}
|
42
lib/Alchemy/Phrasea/Application/Environment.php
Normal file
42
lib/Alchemy/Phrasea/Application/Environment.php
Normal file
@@ -0,0 +1,42 @@
|
||||
<?php
|
||||
|
||||
namespace Alchemy\Phrasea\Application;
|
||||
|
||||
use Alchemy\Phrasea\Application;
|
||||
|
||||
class Environment
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $name;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
private $debug = false;
|
||||
|
||||
public function __construct($name, $debug)
|
||||
{
|
||||
$this->name = (string) $name;
|
||||
$this->debug = ((bool) $debug) || ! in_array($name, [
|
||||
Application::ENV_PROD, Application::ENV_TEST
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function isDebug()
|
||||
{
|
||||
return $this->debug;
|
||||
}
|
||||
}
|
@@ -9,6 +9,8 @@
|
||||
*/
|
||||
namespace Alchemy\Phrasea\Application\Helper;
|
||||
|
||||
use Alchemy\Phrasea\Collection\CollectionService;
|
||||
|
||||
trait ApplicationBoxAware
|
||||
{
|
||||
/** @var \appbox|callable */
|
||||
@@ -61,6 +63,14 @@ trait ApplicationBoxAware
|
||||
return $this->applicationBox;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return CollectionService
|
||||
*/
|
||||
public function getCollectionService()
|
||||
{
|
||||
return $this['services.collection'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Find a registered Databoxes.
|
||||
*
|
||||
|
@@ -10,6 +10,7 @@
|
||||
namespace Alchemy\Phrasea\Application\Helper;
|
||||
|
||||
use Alchemy\Phrasea\Http\DeliverDataInterface;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
|
||||
trait DelivererAware
|
||||
{
|
||||
@@ -57,28 +58,15 @@ trait DelivererAware
|
||||
/**
|
||||
* Returns a HTTP Response ready to deliver a binary file
|
||||
*
|
||||
* @param string $file
|
||||
* @param string $filename
|
||||
* @param string $disposition
|
||||
* @param string $file
|
||||
* @param string $filename
|
||||
* @param string $disposition
|
||||
* @param string|null $mimeType
|
||||
* @param integer $cacheDuration
|
||||
* @param integer $cacheDuration
|
||||
* @return Response
|
||||
*/
|
||||
public function deliverFile($file, $filename = null, $disposition = DeliverDataInterface::DISPOSITION_INLINE, $mimeType = null, $cacheDuration = null)
|
||||
{
|
||||
return $this->getDeliverer()->deliverFile($file, $filename, $disposition, $mimeType, $cacheDuration);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a HTTP Response ready to deliver data
|
||||
*
|
||||
* @param string $data
|
||||
* @param string $filename
|
||||
* @param string $mimeType
|
||||
* @param string $disposition
|
||||
* @param integer $cacheDuration
|
||||
*/
|
||||
public function deliverData($data, $filename, $mimeType, $disposition = DeliverDataInterface::DISPOSITION_INLINE, $cacheDuration = null)
|
||||
{
|
||||
return $this->getDeliverer()->deliverData($data, $filename, $disposition, $mimeType, $cacheDuration);
|
||||
}
|
||||
}
|
||||
|
@@ -10,7 +10,6 @@
|
||||
namespace Alchemy\Phrasea\Application\Helper;
|
||||
|
||||
use Neutron\TemporaryFilesystem\Manager;
|
||||
use Neutron\TemporaryFilesystem\TemporaryFilesystemInterface;
|
||||
use Symfony\Component\Filesystem\Filesystem;
|
||||
|
||||
trait FilesystemAware
|
||||
|
@@ -9,80 +9,9 @@
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Alchemy\Phrasea\Application;
|
||||
|
||||
use Alchemy\Phrasea\Application as PhraseaApplication;
|
||||
use Alchemy\Phrasea\Application;
|
||||
use Alchemy\Phrasea\Core\Event\Subscriber\PhraseaExceptionHandlerSubscriber;
|
||||
use Alchemy\Phrasea\Core\Event\Subscriber\BridgeExceptionSubscriber;
|
||||
use Alchemy\Phrasea\Core\Event\Subscriber\FirewallSubscriber;
|
||||
use Alchemy\Phrasea\Core\Event\Subscriber\JsonRequestSubscriber;
|
||||
use Alchemy\Phrasea\Core\Event\Subscriber\DebuggerSubscriber;
|
||||
use Monolog\Logger;
|
||||
use Monolog\Processor\WebProcessor;
|
||||
use Silex\Provider\WebProfilerServiceProvider;
|
||||
use Sorien\Provider\DoctrineProfilerServiceProvider;
|
||||
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
|
||||
return call_user_func(function ($environment = PhraseaApplication::ENV_PROD) {
|
||||
$app = new PhraseaApplication($environment);
|
||||
$app->loadPlugins();
|
||||
|
||||
$app['exception_handler'] = $app->share(function ($app) {
|
||||
return new PhraseaExceptionHandlerSubscriber($app['phraseanet.exception_handler']);
|
||||
});
|
||||
$app['monolog'] = $app->share($app->extend('monolog', function (Logger $monolog) {
|
||||
$monolog->pushProcessor(new WebProcessor());
|
||||
|
||||
return $monolog;
|
||||
}));
|
||||
|
||||
$app->before(function (Request $request) use ($app) {
|
||||
|
||||
if (0 === strpos($request->getPathInfo(), '/setup')) {
|
||||
if (!$app['phraseanet.configuration-tester']->isInstalled()) {
|
||||
if (!$app['phraseanet.configuration-tester']->isBlank()) {
|
||||
if ('setup_upgrade_instructions' !== $app['request']->attributes->get('_route')) {
|
||||
return $app->redirectPath('setup_upgrade_instructions');
|
||||
}
|
||||
}
|
||||
} elseif (!$app['phraseanet.configuration-tester']->isBlank()) {
|
||||
return $app->redirectPath('homepage');
|
||||
}
|
||||
} else {
|
||||
if (false === strpos($request->getPathInfo(), '/include/minify')) {
|
||||
$app['firewall']->requireSetup();
|
||||
}
|
||||
}
|
||||
}, Application::EARLY_EVENT);
|
||||
|
||||
$app->bindRoutes();
|
||||
|
||||
if (PhraseaApplication::ENV_DEV === $app->getEnvironment()) {
|
||||
$app->register($p = new WebProfilerServiceProvider(), [
|
||||
'profiler.cache_dir' => $app['cache.path'].'/profiler',
|
||||
]);
|
||||
$app->mount('/_profiler', $p);
|
||||
|
||||
if ($app['phraseanet.configuration-tester']->isInstalled()) {
|
||||
$app->register(new DoctrineProfilerServiceProvider());
|
||||
$app['db'] = $app->share(function (PhraseaApplication $app) {
|
||||
return $app['orm.em']->getConnection();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
$app['dispatcher'] = $app->share(
|
||||
$app->extend('dispatcher', function (EventDispatcherInterface $dispatcher, PhraseaApplication $app) {
|
||||
$dispatcher->addSubscriber(new BridgeExceptionSubscriber($app));
|
||||
$dispatcher->addSubscriber(new FirewallSubscriber());
|
||||
$dispatcher->addSubscriber(new JsonRequestSubscriber());
|
||||
$dispatcher->addSubscriber(new DebuggerSubscriber($app));
|
||||
|
||||
return $dispatcher;
|
||||
})
|
||||
);
|
||||
|
||||
return $app;
|
||||
}, isset($environment) ? $environment : PhraseaApplication::ENV_PROD);
|
||||
return (new Application\ApplicationLoader())->buildWebApplication(
|
||||
isset($environment) ? $environment : Application::ENV_PROD,
|
||||
isset($forceDebug) ? $forceDebug : false
|
||||
);
|
||||
|
155
lib/Alchemy/Phrasea/Application/RouteLoader.php
Normal file
155
lib/Alchemy/Phrasea/Application/RouteLoader.php
Normal file
@@ -0,0 +1,155 @@
|
||||
<?php
|
||||
|
||||
namespace Alchemy\Phrasea\Application;
|
||||
|
||||
use Alchemy\EmbedProvider\EmbedServiceProvider;
|
||||
use Alchemy\Phrasea\Application;
|
||||
use Alchemy\Phrasea\ControllerProvider as Providers;
|
||||
use Assert\Assertion;
|
||||
use Silex\ControllerProviderInterface;
|
||||
|
||||
class RouteLoader
|
||||
{
|
||||
|
||||
public static $defaultProviders = [
|
||||
'/account/' => Providers\Root\Account::class,
|
||||
'/admin/' => Providers\Admin\Root::class,
|
||||
'/admin/collection' => Providers\Admin\Collection::class,
|
||||
'/admin/connected-users' => Providers\Admin\ConnectedUsers::class,
|
||||
'/admin/dashboard' => Providers\Admin\Dashboard::class,
|
||||
'/admin/databox' => Providers\Admin\Databox::class,
|
||||
'/admin/databoxes' => Providers\Admin\Databoxes::class,
|
||||
'/admin/fields' => Providers\Admin\Fields::class ,
|
||||
'/admin/publications' => Providers\Admin\Feeds::class,
|
||||
'/admin/plugins' => Providers\Admin\Plugins::class,
|
||||
'/admin/search-engine' => Providers\Admin\SearchEngine::class,
|
||||
'/admin/setup' => Providers\Admin\Setup::class,
|
||||
'/admin/subdefs' => Providers\Admin\Subdefs::class,
|
||||
'/admin/task-manager' => Providers\Admin\TaskManager::class,
|
||||
'/admin/users' => Providers\Admin\Users::class,
|
||||
'/client/' => Providers\Client\Root::class,
|
||||
'/datafiles' => Providers\Datafiles::class,
|
||||
'/developers/' => Providers\Root\Developers::class,
|
||||
'/download/' => Providers\Prod\DoDownload::class,
|
||||
'/embed/' => EmbedServiceProvider::class,
|
||||
'/feeds/' => Providers\Root\RSSFeeds::class,
|
||||
'/include/minify' => Providers\Minifier::class,
|
||||
'/login/' => Providers\Root\Login::class,
|
||||
'/lightbox' => Providers\Lightbox::class,
|
||||
'/permalink' => Providers\Permalink::class,
|
||||
'/prod/baskets' => Providers\Prod\BasketProvider::class,
|
||||
'/prod/bridge/' => Providers\Prod\Bridge::class,
|
||||
'/prod/download' => Providers\Prod\Download::class,
|
||||
'/prod/export/' => Providers\Prod\Export::class,
|
||||
'/prod/feeds' => Providers\Prod\Feed::class,
|
||||
'/prod/language' => Providers\Prod\Language::class,
|
||||
'/prod/lazaret/' => Providers\Prod\Lazaret::class,
|
||||
'/prod/lists' => Providers\Prod\UsrLists::class,
|
||||
'/prod/order/' => Providers\Prod\Order::class,
|
||||
'/prod/printer/' => Providers\Prod\Printer::class,
|
||||
'/prod/push/' => Providers\Prod\Push::class,
|
||||
'/prod/query/' => Providers\Prod\Query::class,
|
||||
'/prod/records/' => Providers\Prod\Record::class,
|
||||
'/prod/records/edit' => Providers\Prod\Edit::class,
|
||||
'/prod/records/movecollection' => Providers\Prod\MoveCollection::class,
|
||||
'/prod/records/property' => Providers\Prod\Property::class,
|
||||
'/prod/share/' => Providers\Prod\Share::class,
|
||||
'/prod/story' => Providers\Prod\Story::class,
|
||||
'/prod/tools/' => Providers\Prod\Tools::class,
|
||||
'/prod/tooltip' => Providers\Prod\Tooltip::class,
|
||||
'/prod/TOU/' => Providers\Prod\TOU::class,
|
||||
'/prod/upload/' => Providers\Prod\Upload::class,
|
||||
'/prod/WorkZone' => Providers\Prod\WorkZone::class,
|
||||
'/prod/' => Providers\Prod\Root::class,
|
||||
'/report/activity' => Providers\Report\Activity::class,
|
||||
'/report/informations' => Providers\Report\Information::class,
|
||||
'/report/' => Providers\Report\Root::class,
|
||||
'/session/' => Providers\Root\Session::class,
|
||||
'/setup' => Providers\Setup::class,
|
||||
'/thesaurus' => Providers\Thesaurus\Thesaurus::class,
|
||||
'/user/notifications/' => Providers\User\Notifications::class,
|
||||
'/user/preferences/' => Providers\User\Preferences::class,
|
||||
'/xmlhttp' => Providers\Thesaurus\Xmlhttp::class,
|
||||
'/' => Providers\Root\Root::class,
|
||||
];
|
||||
|
||||
/**
|
||||
* @var string[]
|
||||
*/
|
||||
private $controllerProviders = [];
|
||||
|
||||
/**
|
||||
* @param string $prefix
|
||||
* @param string $providerClass
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
public function registerProvider($prefix, $providerClass)
|
||||
{
|
||||
Assertion::classExists($providerClass);
|
||||
|
||||
$this->controllerProviders[$prefix] = $providerClass;
|
||||
}
|
||||
|
||||
public function registerProviders(array $providers)
|
||||
{
|
||||
foreach ($providers as $prefix => $providerClass) {
|
||||
$this->registerProvider($prefix, $providerClass);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Application $app
|
||||
*/
|
||||
public function bindRoutes(Application $app)
|
||||
{
|
||||
// @todo Move me out of here !
|
||||
// Controllers with routes referenced by api
|
||||
$this->controllerProviders[$app['controller.media_accessor.route_prefix']] = Providers\MediaAccessor::class;
|
||||
|
||||
foreach ($this->controllerProviders as $prefix => $class) {
|
||||
$app->mount($prefix, new $class);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Application $app
|
||||
* @param $routeParameter
|
||||
*/
|
||||
public function bindPluginRoutes(Application $app, $routeParameter)
|
||||
{
|
||||
foreach ($app[$routeParameter] as $providerDefinition) {
|
||||
$prefix = '';
|
||||
$providerKey = $providerDefinition;
|
||||
|
||||
if (is_array($providerDefinition)) {
|
||||
list($prefix, $providerKey) = $providerDefinition;
|
||||
}
|
||||
|
||||
if (! $this->isValidProviderDefinition($app, $prefix, $providerKey)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$prefix = '/' . ltrim($prefix, '/');
|
||||
$provider = $app[$providerKey];
|
||||
|
||||
if (!$provider instanceof ControllerProviderInterface) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$app->mount($prefix, $provider);
|
||||
}
|
||||
}
|
||||
|
||||
private function isValidProviderDefinition(Application $app, $prefix, $provider)
|
||||
{
|
||||
if (!is_string($prefix) || !is_string($provider)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!isset($app[$provider])) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
@@ -333,7 +333,7 @@ class RegistrationService
|
||||
return;
|
||||
}
|
||||
|
||||
$collection = \collection::get_from_base_id($this->app, $baseId);
|
||||
$collection = \collection::getByBaseId($this->app, $baseId);
|
||||
$registrationManipulator->createRegistration($user, $collection);
|
||||
$successfulRegistrations[$baseId] = $collection;
|
||||
});
|
||||
|
@@ -19,8 +19,19 @@ use Alchemy\Phrasea\Border\File;
|
||||
*/
|
||||
abstract class AbstractChecker implements CheckerInterface
|
||||
{
|
||||
/**
|
||||
* @var Application
|
||||
*/
|
||||
protected $app;
|
||||
|
||||
/**
|
||||
* @var \databox[]
|
||||
*/
|
||||
protected $databoxes = [];
|
||||
|
||||
/**
|
||||
* @var \collection[]
|
||||
*/
|
||||
protected $collections = [];
|
||||
|
||||
public function __construct(Application $app)
|
||||
@@ -32,8 +43,8 @@ abstract class AbstractChecker implements CheckerInterface
|
||||
* Restrict the checker to a set of databoxes.
|
||||
* Warning, you can not restrict on both databoxes and collections
|
||||
*
|
||||
* @param databox|array $databoxes A databox or an array of databoxes
|
||||
* @return Boolean
|
||||
* @param \databox[] $databoxes A databox or an array of databoxes
|
||||
* @return bool
|
||||
*
|
||||
* @throws \LogicException If already restricted to collections
|
||||
* @throws \InvalidArgumentException In case invalid databoxes are provided
|
||||
@@ -60,8 +71,8 @@ abstract class AbstractChecker implements CheckerInterface
|
||||
* Restrict the checker to a set of collections.
|
||||
* Warning, you can not restrict on both databoxes and collections
|
||||
*
|
||||
* @param collection|array $collections
|
||||
* @return Boolean
|
||||
* @param \collection[] $collections
|
||||
* @return bool
|
||||
*
|
||||
* @throws \LogicException If already restricted to databoxes
|
||||
* @throws \InvalidArgumentException In case invalid collections are provided
|
||||
@@ -93,6 +104,10 @@ abstract class AbstractChecker implements CheckerInterface
|
||||
*/
|
||||
public function isApplicable(File $file)
|
||||
{
|
||||
if (empty($this->databoxes) && empty($this->collections)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (null === $file->getCollection()) {
|
||||
return true;
|
||||
}
|
||||
|
@@ -134,14 +134,12 @@ class File
|
||||
$metadatas->add(new Metadata(TagFactory::getFromRDFTagname($tagname), $value));
|
||||
}
|
||||
|
||||
/**
|
||||
* PHPExiftool throws exception on some files not supported
|
||||
*/
|
||||
try {
|
||||
$this->app['exiftool.writer']->reset();
|
||||
$this->app['exiftool.writer']->write($this->getFile()->getRealPath(), $metadatas);
|
||||
$writer = $this->app['exiftool.writer'];
|
||||
$writer->reset();
|
||||
$writer->write($this->getFile()->getRealPath(), $metadatas);
|
||||
} catch (PHPExiftoolException $e) {
|
||||
|
||||
// PHPExiftool throws exception on some files not supported
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -11,6 +11,7 @@
|
||||
|
||||
namespace Alchemy\Phrasea\Border;
|
||||
|
||||
use Alchemy\Phrasea\Application;
|
||||
use Alchemy\Phrasea\Border\Checker\CheckerInterface;
|
||||
use Alchemy\Phrasea\Border\Attribute\AttributeInterface;
|
||||
use Alchemy\Phrasea\Exception\RuntimeException;
|
||||
@@ -27,12 +28,9 @@ use Alchemy\Phrasea\Model\Entities\LazaretAttribute;
|
||||
use Alchemy\Phrasea\Model\Entities\LazaretCheck;
|
||||
use Alchemy\Phrasea\Model\Entities\LazaretFile;
|
||||
use Alchemy\Phrasea\Model\Entities\LazaretSession;
|
||||
use MediaAlchemyst\Exception\ExceptionInterface as MediaAlchemystException;
|
||||
use MediaAlchemyst\Specification\Image as ImageSpec;
|
||||
use PHPExiftool\Driver\Metadata\Metadata;
|
||||
use PHPExiftool\Driver\Value\Mono as MonoValue;
|
||||
use PHPExiftool\Driver\Value\Multi;
|
||||
use Silex\Application;
|
||||
use Symfony\Component\Filesystem\Exception\IOException;
|
||||
|
||||
/**
|
||||
@@ -44,6 +42,9 @@ use Symfony\Component\Filesystem\Exception\IOException;
|
||||
*/
|
||||
class Manager
|
||||
{
|
||||
/**
|
||||
* @var CheckerInterface[]
|
||||
*/
|
||||
protected $checkers = [];
|
||||
protected $app;
|
||||
protected $filesystem;
|
||||
@@ -159,7 +160,9 @@ class Manager
|
||||
}
|
||||
|
||||
foreach ($this->checkers as $checker) {
|
||||
$visa->addResponse($checker->check($this->app['orm.em'], $file));
|
||||
if ($checker->isApplicable($file)) {
|
||||
$visa->addResponse($checker->check($this->app['orm.em'], $file));
|
||||
}
|
||||
}
|
||||
|
||||
return $visa;
|
||||
@@ -242,42 +245,11 @@ class Manager
|
||||
return array_values($this->checkers);
|
||||
}
|
||||
|
||||
/**
|
||||
* Find an available Lazaret filename and creates the empty file.
|
||||
*
|
||||
* @param string $filename The desired filename
|
||||
* @param string $suffix A suffix to the filename
|
||||
* @return string The available filename to use
|
||||
*/
|
||||
protected function bookLazaretPathfile($filename, $suffix = '')
|
||||
{
|
||||
$output = $this->app['tmp.path'].'/lazaret/lzrt_' . substr($filename, 0, 3) . '_' . $suffix . '.' . pathinfo($filename, PATHINFO_EXTENSION);
|
||||
$infos = pathinfo($output);
|
||||
$n = 0;
|
||||
|
||||
$this->app['filesystem']->mkdir($this->app['tmp.lazaret.path']);
|
||||
|
||||
while (true) {
|
||||
$output = sprintf('%s/%s-%d%s', $infos['dirname'], $infos['filename'], ++ $n, (isset($infos['extension']) ? '.' . $infos['extension'] : ''));
|
||||
|
||||
try {
|
||||
if ( ! $this->app['filesystem']->exists($output)) {
|
||||
$this->app['filesystem']->touch($output);
|
||||
break;
|
||||
}
|
||||
} catch (IOException $e) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return realpath($output);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a record to Phraseanet
|
||||
*
|
||||
* @param File $file The package file
|
||||
* @return \record_adater
|
||||
* @return \record_adapter
|
||||
*/
|
||||
protected function createRecord(File $file, $nosubdef=false)
|
||||
{
|
||||
@@ -384,21 +356,8 @@ class Manager
|
||||
)
|
||||
);
|
||||
|
||||
$lazaretPathname = $this->bookLazaretPathfile($file->getOriginalName());
|
||||
$lazaretPathnameThumb = $this->bookLazaretPathfile($file->getOriginalName(), 'thumb');
|
||||
|
||||
$this->app['filesystem']->copy($file->getFile()->getRealPath(), $lazaretPathname, true);
|
||||
|
||||
$spec = new ImageSpec();
|
||||
|
||||
$spec->setResizeMode(ImageSpec::RESIZE_MODE_INBOUND_FIXEDRATIO);
|
||||
$spec->setDimensions(375, 275);
|
||||
|
||||
try {
|
||||
$this->app['media-alchemyst']->turnInto($file->getFile()->getPathname(), $lazaretPathnameThumb, $spec);
|
||||
} catch (MediaAlchemystException $e) {
|
||||
|
||||
}
|
||||
$lazaretFilesystemService = $this->app['phraseanet.lazaret_filesystem'];
|
||||
$persistedLazaret = $lazaretFilesystemService->writeLazaret($file);
|
||||
|
||||
$lazaretFile = new LazaretFile();
|
||||
$lazaretFile->setBaseId($file->getCollection()->get_base_id());
|
||||
@@ -408,8 +367,8 @@ class Manager
|
||||
|
||||
$lazaretFile->setForced($forced);
|
||||
|
||||
$lazaretFile->setFilename(pathinfo($lazaretPathname, PATHINFO_BASENAME));
|
||||
$lazaretFile->setThumbFileName(pathinfo($lazaretPathnameThumb, PATHINFO_BASENAME));
|
||||
$lazaretFile->setFilename($persistedLazaret->getFilename());
|
||||
$lazaretFile->setThumbFileName($persistedLazaret->getThumbnailFilename());
|
||||
|
||||
$lazaretFile->setSession($session);
|
||||
|
||||
|
250
lib/Alchemy/Phrasea/Collection/Collection.php
Normal file
250
lib/Alchemy/Phrasea/Collection/Collection.php
Normal file
@@ -0,0 +1,250 @@
|
||||
<?php
|
||||
|
||||
namespace Alchemy\Phrasea\Collection;
|
||||
|
||||
use Alchemy\Phrasea\Collection\Reference\CollectionReference;
|
||||
use PHPExiftool\Exception\LogicException;
|
||||
|
||||
class Collection
|
||||
{
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $databoxId;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $collectionId;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $name;
|
||||
|
||||
/**
|
||||
* @var string[]
|
||||
*/
|
||||
private $labels = [];
|
||||
|
||||
/**
|
||||
* @var string|int[] Binary representation of logo
|
||||
*/
|
||||
private $logo;
|
||||
|
||||
/**
|
||||
* @var \DateTimeInterface
|
||||
*/
|
||||
private $logoUpdatedAt;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $publicWatermark;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $preferences;
|
||||
|
||||
/**
|
||||
* @var CollectionReference
|
||||
*/
|
||||
private $collectionReference;
|
||||
|
||||
public function __construct($databoxId, $collectionId, $name)
|
||||
{
|
||||
$this->databoxId = (int) $databoxId;
|
||||
$this->collectionId = (int) $collectionId;
|
||||
$this->name = (string) $name;
|
||||
$this->preferences = <<<EOT
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<baseprefs>
|
||||
<status>0</status>
|
||||
<sugestedValues></sugestedValues>
|
||||
</baseprefs>
|
||||
EOT;
|
||||
$this->logo = '';
|
||||
$this->labels = array(
|
||||
'en' => '',
|
||||
'fr' => '',
|
||||
'de' => '',
|
||||
'nl' => ''
|
||||
);
|
||||
$this->publicWatermark = '';
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getDataboxId()
|
||||
{
|
||||
return $this->databoxId;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getCollectionId()
|
||||
{
|
||||
return $this->collectionId;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $collectionId
|
||||
*/
|
||||
public function setCollectionId($collectionId)
|
||||
{
|
||||
if ($this->collectionId > 0) {
|
||||
throw new LogicException('Cannot change the ID of an existing collection.');
|
||||
}
|
||||
|
||||
$this->collectionId = (int) $collectionId;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
*/
|
||||
public function setName($name)
|
||||
{
|
||||
$name = trim(strip_tags($name));
|
||||
|
||||
if ($name === '') {
|
||||
throw new \InvalidArgumentException();
|
||||
}
|
||||
|
||||
$this->name = $name;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \string[]
|
||||
*/
|
||||
public function getLabels()
|
||||
{
|
||||
return $this->labels;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \string[] $labels
|
||||
*/
|
||||
public function setLabels($labels)
|
||||
{
|
||||
$this->labels = $labels;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $lang
|
||||
* @param bool $substitute
|
||||
* @return string
|
||||
*/
|
||||
public function getLabel($lang, $substitute = true)
|
||||
{
|
||||
if (!array_key_exists($lang, $this->labels)) {
|
||||
throw new \InvalidArgumentException(sprintf('Code %s is not defined', $lang));
|
||||
}
|
||||
|
||||
if ($substitute) {
|
||||
return isset($this->labels[$lang]) ? $this->labels[$lang] : $this->name;
|
||||
} else {
|
||||
return $this->labels[$lang];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $lang
|
||||
* @param $label
|
||||
*/
|
||||
public function setLabel($lang, $label)
|
||||
{
|
||||
if (!array_key_exists($lang, $this->labels)) {
|
||||
throw new \InvalidArgumentException(sprintf("Language '%s' is not defined.", $lang));
|
||||
}
|
||||
|
||||
$this->labels[$lang] = $label;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \int[]|string|null
|
||||
*/
|
||||
public function getLogo()
|
||||
{
|
||||
return $this->logo;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \int[]|string $logo
|
||||
*/
|
||||
public function setLogo($logo)
|
||||
{
|
||||
$this->logo = $logo;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \DateTimeInterface
|
||||
*/
|
||||
public function getLogoUpdatedAt()
|
||||
{
|
||||
return $this->logoUpdatedAt;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getPublicWatermark()
|
||||
{
|
||||
return $this->publicWatermark;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $publicWatermark
|
||||
*/
|
||||
public function setPublicWatermark($publicWatermark)
|
||||
{
|
||||
if (! in_array($publicWatermark, ['none', 'wm', 'stamp'])) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->publicWatermark = $publicWatermark;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getPreferences()
|
||||
{
|
||||
return $this->preferences;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $preferences
|
||||
*/
|
||||
public function setPreferences($preferences)
|
||||
{
|
||||
$this->preferences = $preferences;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return CollectionReference
|
||||
*/
|
||||
public function getCollectionReference()
|
||||
{
|
||||
return $this->collectionReference;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param CollectionReference $collectionReference
|
||||
*/
|
||||
public function setCollectionReference($collectionReference)
|
||||
{
|
||||
$this->collectionReference = $collectionReference;
|
||||
}
|
||||
}
|
72
lib/Alchemy/Phrasea/Collection/CollectionFactory.php
Normal file
72
lib/Alchemy/Phrasea/Collection/CollectionFactory.php
Normal file
@@ -0,0 +1,72 @@
|
||||
<?php
|
||||
|
||||
namespace Alchemy\Phrasea\Collection;
|
||||
|
||||
use Alchemy\Phrasea\Application;
|
||||
use Alchemy\Phrasea\Collection\Reference\CollectionReference;
|
||||
use Assert\Assertion;
|
||||
|
||||
class CollectionFactory
|
||||
{
|
||||
/**
|
||||
* @var Application
|
||||
*/
|
||||
private $app;
|
||||
|
||||
/**
|
||||
* @param Application $application
|
||||
*/
|
||||
public function __construct(Application $application)
|
||||
{
|
||||
$this->app = $application;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $databoxId
|
||||
* @param CollectionReference $reference
|
||||
* @param array $row
|
||||
* @return \collection
|
||||
*/
|
||||
public function create($databoxId, CollectionReference $reference, array $row)
|
||||
{
|
||||
if ($databoxId != $reference->getDataboxId()) {
|
||||
throw new \InvalidArgumentException('Reference does not belong to given databoxId.');
|
||||
}
|
||||
|
||||
$collection = new Collection($databoxId, $row['coll_id'], $row['asciiname']);
|
||||
|
||||
$collection->setLabel('en', $row['label_en']);
|
||||
$collection->setLabel('fr', $row['label_fr']);
|
||||
$collection->setLabel('de', $row['label_de']);
|
||||
$collection->setLabel('nl', $row['label_nl']);
|
||||
$collection->setLogo($row['logo']);
|
||||
$collection->setPreferences($row['prefs']);
|
||||
$collection->setPublicWatermark($row['pub_wm']);
|
||||
|
||||
return new \collection($this->app, $collection, $reference, $row);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $databoxId
|
||||
* @param CollectionReference[] $collectionReferences
|
||||
* @param array $rows
|
||||
* @return array
|
||||
*/
|
||||
public function createMany($databoxId, $collectionReferences, array $rows)
|
||||
{
|
||||
Assertion::allIsInstanceOf($collectionReferences, CollectionReference::class);
|
||||
|
||||
$collections = [];
|
||||
$indexedReferences = [];
|
||||
|
||||
foreach ($collectionReferences as $reference) {
|
||||
$indexedReferences[$reference->getCollectionId()] = $reference;
|
||||
}
|
||||
|
||||
foreach ($rows as $row) {
|
||||
$collections[$row['coll_id']] = $this->create($databoxId, $indexedReferences[$row['coll_id']], $row);
|
||||
}
|
||||
|
||||
return $collections;
|
||||
}
|
||||
}
|
30
lib/Alchemy/Phrasea/Collection/CollectionRepository.php
Normal file
30
lib/Alchemy/Phrasea/Collection/CollectionRepository.php
Normal file
@@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
namespace Alchemy\Phrasea\Collection;
|
||||
|
||||
interface CollectionRepository
|
||||
{
|
||||
|
||||
/**
|
||||
* @return \collection[]
|
||||
*/
|
||||
public function findAll();
|
||||
|
||||
/**
|
||||
* @param int $collectionId
|
||||
* @return \collection|null
|
||||
*/
|
||||
public function find($collectionId);
|
||||
|
||||
/**
|
||||
* @param Collection $collection
|
||||
* @return void
|
||||
*/
|
||||
public function save(Collection $collection);
|
||||
|
||||
/**
|
||||
* @param Collection $collection
|
||||
* @return void
|
||||
*/
|
||||
public function delete(Collection $collection);
|
||||
}
|
@@ -0,0 +1,12 @@
|
||||
<?php
|
||||
|
||||
namespace Alchemy\Phrasea\Collection;
|
||||
|
||||
interface CollectionRepositoryFactory
|
||||
{
|
||||
/**
|
||||
* @param int $databoxId
|
||||
* @return CollectionRepository
|
||||
*/
|
||||
public function createRepositoryForDatabox($databoxId);
|
||||
}
|
@@ -0,0 +1,99 @@
|
||||
<?php
|
||||
|
||||
namespace Alchemy\Phrasea\Collection;
|
||||
|
||||
use Alchemy\Phrasea\Application;
|
||||
use Alchemy\Phrasea\Collection\Reference\CollectionReferenceRepository;
|
||||
|
||||
class CollectionRepositoryRegistry
|
||||
{
|
||||
|
||||
private $baseIdMap = null;
|
||||
|
||||
/**
|
||||
* @var Application
|
||||
*/
|
||||
private $application;
|
||||
|
||||
/**
|
||||
* @var CollectionRepository[]
|
||||
*/
|
||||
private $repositories = array();
|
||||
|
||||
/**
|
||||
* @var CollectionReferenceRepository
|
||||
*/
|
||||
private $referenceRepository;
|
||||
|
||||
/**
|
||||
* @var CollectionRepositoryFactory
|
||||
*/
|
||||
private $repositoryFactory;
|
||||
|
||||
/**
|
||||
* @param Application $app
|
||||
* @param CollectionRepositoryFactory $collectionRepositoryFactory
|
||||
* @param CollectionReferenceRepository $referenceRepository
|
||||
*/
|
||||
public function __construct(
|
||||
Application $app,
|
||||
CollectionRepositoryFactory $collectionRepositoryFactory,
|
||||
CollectionReferenceRepository $referenceRepository
|
||||
) {
|
||||
$this->application = $app;
|
||||
$this->repositoryFactory = $collectionRepositoryFactory;
|
||||
$this->referenceRepository = $referenceRepository;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $databoxId
|
||||
* @return CollectionRepository
|
||||
*/
|
||||
public function getRepositoryByDatabox($databoxId)
|
||||
{
|
||||
if (!isset($this->repositories[$databoxId])) {
|
||||
$this->repositories[$databoxId] = $this->repositoryFactory->createRepositoryForDatabox($databoxId);
|
||||
}
|
||||
|
||||
return $this->repositories[$databoxId];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $baseId
|
||||
* @return CollectionRepository
|
||||
* @throws \OutOfBoundsException if no repository was found for the given baseId.
|
||||
*/
|
||||
public function getRepositoryByBase($baseId)
|
||||
{
|
||||
if ($this->baseIdMap === null) {
|
||||
$this->loadBaseIdMap();
|
||||
}
|
||||
|
||||
if (isset($this->baseIdMap[$baseId])) {
|
||||
return $this->getRepositoryByDatabox($this->baseIdMap[$baseId]);
|
||||
}
|
||||
|
||||
throw new \OutOfBoundsException('No repository available for given base [baseId: ' . $baseId . ' ].');
|
||||
}
|
||||
|
||||
public function purgeRegistry()
|
||||
{
|
||||
$this->baseIdMap = null;
|
||||
|
||||
$appBox = $this->application->getApplicationBox();
|
||||
|
||||
\phrasea::reset_baseDatas($appBox);
|
||||
\phrasea::reset_sbasDatas($appBox);
|
||||
}
|
||||
|
||||
private function loadBaseIdMap()
|
||||
{
|
||||
$references = $this->referenceRepository->findAll();
|
||||
|
||||
$this->baseIdMap = [];
|
||||
|
||||
foreach ($references as $reference) {
|
||||
$this->baseIdMap[$reference->getBaseId()] = $reference->getDataboxId();
|
||||
}
|
||||
}
|
||||
}
|
266
lib/Alchemy/Phrasea/Collection/CollectionService.php
Normal file
266
lib/Alchemy/Phrasea/Collection/CollectionService.php
Normal file
@@ -0,0 +1,266 @@
|
||||
<?php
|
||||
|
||||
namespace Alchemy\Phrasea\Collection;
|
||||
|
||||
use Alchemy\Phrasea\Application;
|
||||
use Alchemy\Phrasea\Collection\Reference\CollectionReference;
|
||||
use Alchemy\Phrasea\Databox\DataboxConnectionProvider;
|
||||
use Alchemy\Phrasea\Model\Entities\User;
|
||||
use Doctrine\DBAL\Connection;
|
||||
|
||||
class CollectionService
|
||||
{
|
||||
/**
|
||||
* @var Application
|
||||
*/
|
||||
private $app;
|
||||
|
||||
private $connection;
|
||||
|
||||
private $connectionProvider;
|
||||
|
||||
public function __construct(Application $application, Connection $connection, DataboxConnectionProvider $connectionProvider)
|
||||
{
|
||||
$this->app = $application;
|
||||
$this->connection = $connection;
|
||||
$this->connectionProvider = $connectionProvider;
|
||||
}
|
||||
|
||||
/**
|
||||
* @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)
|
||||
WHERE r.coll_id = :coll_id
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* @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)
|
||||
{
|
||||
$rights = [
|
||||
"canputinalbum" => "1",
|
||||
"candwnldhd" => "1",
|
||||
"nowatermark" => "1",
|
||||
"candwnldpreview" => "1",
|
||||
"cancmd" => "1",
|
||||
"canadmin" => "1",
|
||||
"actif" => "1",
|
||||
"canreport" => "1",
|
||||
"canpush" => "1",
|
||||
"basusr_infousr" => "",
|
||||
"canaddrecord" => "1",
|
||||
"canmodifrecord" => "1",
|
||||
"candeleterecord" => "1",
|
||||
"chgstatus" => "1",
|
||||
"imgtools" => "1",
|
||||
"manage" => "1",
|
||||
"modify_struct" => "1"
|
||||
];
|
||||
|
||||
$this->app->getAclForUser($user)->update_rights_to_base($reference->getBaseId(), $rights);
|
||||
}
|
||||
}
|
@@ -0,0 +1,34 @@
|
||||
<?php
|
||||
|
||||
namespace Alchemy\Phrasea\Collection\Factory;
|
||||
|
||||
use Alchemy\Phrasea\Collection\CollectionRepository;
|
||||
use Alchemy\Phrasea\Collection\CollectionRepositoryFactory;
|
||||
use Alchemy\Phrasea\Collection\Repository\ArrayCacheCollectionRepository;
|
||||
|
||||
class ArrayCachedCollectionRepositoryFactory implements CollectionRepositoryFactory
|
||||
{
|
||||
/**
|
||||
* @var CollectionRepositoryFactory
|
||||
*/
|
||||
private $collectionRepositoryFactory;
|
||||
|
||||
/**
|
||||
* @param CollectionRepositoryFactory $collectionRepositoryFactory
|
||||
*/
|
||||
public function __construct(CollectionRepositoryFactory $collectionRepositoryFactory)
|
||||
{
|
||||
$this->collectionRepositoryFactory = $collectionRepositoryFactory;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $databoxId
|
||||
* @return CollectionRepository
|
||||
*/
|
||||
public function createRepositoryForDatabox($databoxId)
|
||||
{
|
||||
$repository = $this->collectionRepositoryFactory->createRepositoryForDatabox($databoxId);
|
||||
|
||||
return new ArrayCacheCollectionRepository($repository);
|
||||
}
|
||||
}
|
@@ -0,0 +1,66 @@
|
||||
<?php
|
||||
|
||||
namespace Alchemy\Phrasea\Collection\Factory;
|
||||
|
||||
use Alchemy\Phrasea\Application;
|
||||
use Alchemy\Phrasea\Collection\CollectionRepository;
|
||||
use Alchemy\Phrasea\Collection\CollectionRepositoryFactory;
|
||||
use Alchemy\Phrasea\Collection\Repository\CachedCollectionRepository;
|
||||
use Doctrine\Common\Cache\Cache;
|
||||
|
||||
class CachedCollectionRepositoryFactory implements CollectionRepositoryFactory
|
||||
{
|
||||
/**
|
||||
* @var Application
|
||||
*/
|
||||
private $application;
|
||||
|
||||
/**
|
||||
* @var CollectionRepositoryFactory
|
||||
*/
|
||||
private $collectionRepositoryFactory;
|
||||
|
||||
/**
|
||||
* @var Cache
|
||||
*/
|
||||
private $cache;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $baseCacheKey;
|
||||
|
||||
/**
|
||||
* @param Application $application
|
||||
* @param CollectionRepositoryFactory $collectionRepositoryFactory
|
||||
* @param Cache $cache
|
||||
* @param string $baseCacheKey
|
||||
*/
|
||||
public function __construct(
|
||||
Application $application,
|
||||
CollectionRepositoryFactory $collectionRepositoryFactory,
|
||||
Cache $cache,
|
||||
$baseCacheKey
|
||||
) {
|
||||
$this->application = $application;
|
||||
$this->collectionRepositoryFactory = $collectionRepositoryFactory;
|
||||
$this->cache = $cache;
|
||||
$this->baseCacheKey = (string)$baseCacheKey;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $databoxId
|
||||
* @return CollectionRepository
|
||||
*/
|
||||
public function createRepositoryForDatabox($databoxId)
|
||||
{
|
||||
$repository = $this->collectionRepositoryFactory->createRepositoryForDatabox($databoxId);
|
||||
|
||||
return new CachedCollectionRepository(
|
||||
$this->application,
|
||||
$repository,
|
||||
$this->cache,
|
||||
$this->baseCacheKey . '.' . $databoxId
|
||||
);
|
||||
}
|
||||
}
|
@@ -0,0 +1,60 @@
|
||||
<?php
|
||||
|
||||
namespace Alchemy\Phrasea\Collection\Factory;
|
||||
|
||||
use Alchemy\Phrasea\Collection\CollectionFactory;
|
||||
use Alchemy\Phrasea\Collection\CollectionRepository;
|
||||
use Alchemy\Phrasea\Collection\CollectionRepositoryFactory;
|
||||
use Alchemy\Phrasea\Collection\Reference\CollectionReferenceRepository;
|
||||
use Alchemy\Phrasea\Collection\Repository\DbalCollectionRepository;
|
||||
use Alchemy\Phrasea\Databox\DataboxConnectionProvider;
|
||||
|
||||
class DbalCollectionRepositoryFactory implements CollectionRepositoryFactory
|
||||
{
|
||||
|
||||
/**
|
||||
* @var CollectionReferenceRepository
|
||||
*/
|
||||
private $collectionReferenceRepository;
|
||||
|
||||
/**
|
||||
* @var DataboxConnectionProvider
|
||||
*/
|
||||
private $databoxConnectionProvider;
|
||||
|
||||
/**
|
||||
* @var CollectionFactory
|
||||
*/
|
||||
private $collectionFactory;
|
||||
|
||||
/**
|
||||
* @param DataboxConnectionProvider $connectionProvider
|
||||
* @param CollectionFactory $collectionFactory
|
||||
* @param CollectionReferenceRepository $referenceRepository
|
||||
*/
|
||||
public function __construct(
|
||||
DataboxConnectionProvider $connectionProvider,
|
||||
CollectionFactory $collectionFactory,
|
||||
CollectionReferenceRepository $referenceRepository
|
||||
) {
|
||||
$this->databoxConnectionProvider = $connectionProvider;
|
||||
$this->collectionFactory = $collectionFactory;
|
||||
$this->collectionReferenceRepository = $referenceRepository;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $databoxId
|
||||
* @return CollectionRepository
|
||||
*/
|
||||
public function createRepositoryForDatabox($databoxId)
|
||||
{
|
||||
$databoxConnection = $this->databoxConnectionProvider->getConnection($databoxId);
|
||||
|
||||
return new DbalCollectionRepository(
|
||||
$databoxId,
|
||||
$databoxConnection,
|
||||
$this->collectionReferenceRepository,
|
||||
$this->collectionFactory
|
||||
);
|
||||
}
|
||||
}
|
@@ -0,0 +1,110 @@
|
||||
<?php
|
||||
|
||||
namespace Alchemy\Phrasea\Collection\Reference;
|
||||
|
||||
class ArrayCacheCollectionReferenceRepository implements CollectionReferenceRepository
|
||||
{
|
||||
/**
|
||||
* @var CollectionReferenceRepository
|
||||
*/
|
||||
private $repository;
|
||||
|
||||
/**
|
||||
* @var null|array
|
||||
*/
|
||||
private $referenceCache = null;
|
||||
|
||||
public function __construct(CollectionReferenceRepository $referenceRepository)
|
||||
{
|
||||
$this->repository = $referenceRepository;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return CollectionReference[]
|
||||
*/
|
||||
public function findAll()
|
||||
{
|
||||
if ($this->referenceCache === null) {
|
||||
$this->referenceCache = $this->repository->findAll();
|
||||
}
|
||||
|
||||
return $this->referenceCache;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $databoxId
|
||||
* @return CollectionReference[]
|
||||
*/
|
||||
public function findAllByDatabox($databoxId)
|
||||
{
|
||||
$references = $this->findAll();
|
||||
$found = array();
|
||||
|
||||
foreach ($references as $reference) {
|
||||
if ($reference->getDataboxId() == $databoxId) {
|
||||
$found[$reference->getBaseId()] = $reference;
|
||||
}
|
||||
}
|
||||
|
||||
return $found;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $baseId
|
||||
* @return CollectionReference|null
|
||||
*/
|
||||
public function find($baseId)
|
||||
{
|
||||
$references = $this->findAll();
|
||||
|
||||
if (isset($references[$baseId])) {
|
||||
return $references[$baseId];
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $databoxId
|
||||
* @param int $collectionId
|
||||
* @return CollectionReference|null
|
||||
*/
|
||||
public function findByCollectionId($databoxId, $collectionId)
|
||||
{
|
||||
$references = $this->findAll();
|
||||
|
||||
foreach ($references as $reference) {
|
||||
if ($reference->getDataboxId() == $databoxId && $reference->getCollectionId() == $collectionId) {
|
||||
return $reference;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param CollectionReference $reference
|
||||
* @return void
|
||||
*/
|
||||
public function save(CollectionReference $reference)
|
||||
{
|
||||
$this->repository->save($reference);
|
||||
|
||||
if ($this->referenceCache !== null) {
|
||||
$this->referenceCache[$reference->getBaseId()] = $reference;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param CollectionReference $reference
|
||||
* @return void
|
||||
*/
|
||||
public function delete(CollectionReference $reference)
|
||||
{
|
||||
$this->repository->delete($reference);
|
||||
|
||||
if ($this->referenceCache !== null) {
|
||||
unset($this->referenceCache[$reference->getBaseId()]);
|
||||
}
|
||||
}
|
||||
}
|
156
lib/Alchemy/Phrasea/Collection/Reference/CollectionReference.php
Normal file
156
lib/Alchemy/Phrasea/Collection/Reference/CollectionReference.php
Normal file
@@ -0,0 +1,156 @@
|
||||
<?php
|
||||
|
||||
namespace Alchemy\Phrasea\Collection\Reference;
|
||||
|
||||
class CollectionReference
|
||||
{
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $baseId;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $databoxId;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $collectionId;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $displayIndex;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
private $isActive;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $alias;
|
||||
|
||||
/**
|
||||
* @param int $baseId
|
||||
* @param int $databoxId
|
||||
* @param int $collectionId
|
||||
* @param int $displayIndex
|
||||
* @param bool $isActive
|
||||
* @param string $alias
|
||||
*/
|
||||
public function __construct($baseId, $databoxId, $collectionId, $displayIndex, $isActive, $alias)
|
||||
{
|
||||
$this->baseId = (int) $baseId;
|
||||
$this->databoxId = (int) $databoxId;
|
||||
$this->collectionId = (int) $collectionId;
|
||||
$this->displayIndex = (int) $displayIndex;
|
||||
$this->isActive = (bool) $isActive;
|
||||
$this->alias = (string) $alias;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getDataboxId()
|
||||
{
|
||||
return $this->databoxId;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getBaseId()
|
||||
{
|
||||
return $this->baseId;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $baseId
|
||||
*/
|
||||
public function setBaseId($baseId)
|
||||
{
|
||||
if ($this->baseId > 0) {
|
||||
throw new \LogicException('Cannot change the baseId of an existing collection reference.');
|
||||
}
|
||||
|
||||
$this->baseId = $baseId;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getCollectionId()
|
||||
{
|
||||
return $this->collectionId;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getDisplayIndex()
|
||||
{
|
||||
return $this->displayIndex;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $index
|
||||
* @return $this
|
||||
*/
|
||||
public function setDisplayIndex($index)
|
||||
{
|
||||
$this->displayIndex = (int) $index;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return boolean
|
||||
*/
|
||||
public function isActive()
|
||||
{
|
||||
return $this->isActive;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return $this
|
||||
*/
|
||||
public function disable()
|
||||
{
|
||||
$this->isActive = false;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return $this
|
||||
*/
|
||||
public function enable()
|
||||
{
|
||||
$this->isActive = true;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getAlias()
|
||||
{
|
||||
return $this->alias;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $alias
|
||||
* @return $this
|
||||
*/
|
||||
public function setAlias($alias)
|
||||
{
|
||||
$this->alias = (string) $alias;
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
@@ -0,0 +1,42 @@
|
||||
<?php
|
||||
|
||||
namespace Alchemy\Phrasea\Collection\Reference;
|
||||
|
||||
interface CollectionReferenceRepository
|
||||
{
|
||||
/**
|
||||
* @return CollectionReference[]
|
||||
*/
|
||||
public function findAll();
|
||||
|
||||
/**
|
||||
* @param int $databoxId
|
||||
* @return CollectionReference[]
|
||||
*/
|
||||
public function findAllByDatabox($databoxId);
|
||||
|
||||
/**
|
||||
* @param int $baseId
|
||||
* @return CollectionReference|null
|
||||
*/
|
||||
public function find($baseId);
|
||||
|
||||
/**
|
||||
* @param int $databoxId
|
||||
* @param int $collectionId
|
||||
* @return CollectionReference|null
|
||||
*/
|
||||
public function findByCollectionId($databoxId, $collectionId);
|
||||
|
||||
/**
|
||||
* @param CollectionReference $reference
|
||||
* @return void
|
||||
*/
|
||||
public function save(CollectionReference $reference);
|
||||
|
||||
/**
|
||||
* @param CollectionReference $reference
|
||||
* @return void
|
||||
*/
|
||||
public function delete(CollectionReference $reference);
|
||||
}
|
@@ -0,0 +1,174 @@
|
||||
<?php
|
||||
|
||||
namespace Alchemy\Phrasea\Collection\Reference;
|
||||
|
||||
use Alchemy\Phrasea\Core\Database\QueryBuilder;
|
||||
use Doctrine\DBAL\Connection;
|
||||
|
||||
class DbalCollectionReferenceRepository implements CollectionReferenceRepository
|
||||
{
|
||||
|
||||
private static $table = 'bas';
|
||||
|
||||
private static $columns = [
|
||||
'base_id' => 'baseId',
|
||||
'sbas_id' => 'databoxId',
|
||||
'server_coll_id' => 'collectionId',
|
||||
'ord' => 'displayIndex',
|
||||
'active' => 'isActive',
|
||||
'aliases' => 'alias'
|
||||
];
|
||||
|
||||
private static $selectQuery = 'SELECT base_id AS baseId, sbas_id AS databoxId, server_coll_id AS collectionId,
|
||||
ord AS displayIndex, active AS isActive, aliases AS alias
|
||||
FROM bas';
|
||||
|
||||
private static $insertQuery = 'INSERT INTO bas (sbas_id, server_coll_id, ord, active, aliases)
|
||||
VALUES (:databoxId, :collectionId,
|
||||
(SELECT COALESCE(MAX(b.ord), 0) + 1 AS ord FROM bas b WHERE b.sbas_id = :databoxId),
|
||||
:isActive, :alias)';
|
||||
|
||||
private static $updateQuery = 'UPDATE bas SET ord = :displayIndex, active = :isActive, aliases = :alias
|
||||
WHERE base_id = :baseId';
|
||||
|
||||
private static $deleteQuery = 'DELETE FROM bas WHERE base_id = :baseId';
|
||||
|
||||
/**
|
||||
* @var Connection
|
||||
*/
|
||||
private $connection;
|
||||
|
||||
/**
|
||||
* @param Connection $connection
|
||||
*/
|
||||
public function __construct(Connection $connection)
|
||||
{
|
||||
$this->connection = $connection;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return CollectionReference[]
|
||||
*/
|
||||
public function findAll()
|
||||
{
|
||||
return $this->createManyReferences($this->connection->fetchAll(self::$selectQuery));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $databoxId
|
||||
* @return CollectionReference[]
|
||||
*/
|
||||
public function findAllByDatabox($databoxId)
|
||||
{
|
||||
$query = self::$selectQuery . ' WHERE sbas_id = :databoxId';
|
||||
$rows = $this->connection->fetchAll($query, [ ':databoxId' => $databoxId ]);
|
||||
|
||||
return $this->createManyReferences($rows);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $baseId
|
||||
* @return CollectionReference|null
|
||||
*/
|
||||
public function find($baseId)
|
||||
{
|
||||
$query = self::$selectQuery . ' WHERE base_id = :baseId';
|
||||
$row = $this->connection->fetchAssoc($query, [ ':baseId' => $baseId ]);
|
||||
|
||||
if ($row !== false) {
|
||||
return $this->createReference($row);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $databoxId
|
||||
* @param int $collectionId
|
||||
* @return CollectionReference|null
|
||||
*/
|
||||
public function findByCollectionId($databoxId, $collectionId)
|
||||
{
|
||||
$query = self::$selectQuery . ' WHERE sbas_id = :databoxId AND server_coll_id = :collectionId';
|
||||
$row = $this->connection->fetchAssoc($query, [ ':databoxId' => $databoxId, ':collectionId' => $collectionId ]);
|
||||
|
||||
if ($row !== false) {
|
||||
return $this->createReference($row);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public function save(CollectionReference $collectionReference)
|
||||
{
|
||||
$query = self::$insertQuery;
|
||||
$isInsert = true;
|
||||
|
||||
$parameters = [
|
||||
'isActive' => $collectionReference->isActive(),
|
||||
'alias' => $collectionReference->getAlias()
|
||||
];
|
||||
|
||||
if ($collectionReference->getBaseId() > 0) {
|
||||
$query = self::$updateQuery;
|
||||
$isInsert = false;
|
||||
|
||||
$parameters['baseId'] = $collectionReference->getBaseId();
|
||||
$parameters['displayIndex'] = $collectionReference->getDisplayIndex();
|
||||
}
|
||||
else {
|
||||
$parameters['databoxId'] = $collectionReference->getDataboxId();
|
||||
$parameters['collectionId'] = $collectionReference->getCollectionId();
|
||||
}
|
||||
|
||||
$this->connection->executeQuery($query, $parameters);
|
||||
|
||||
if ($isInsert) {
|
||||
$collectionReference->setBaseId($this->connection->lastInsertId());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param CollectionReference $collectionReference
|
||||
* @throws \Doctrine\DBAL\DBALException
|
||||
*/
|
||||
public function delete(CollectionReference $collectionReference)
|
||||
{
|
||||
$parameters = [
|
||||
'baseId' => $collectionReference->getBaseId()
|
||||
];
|
||||
|
||||
$this->connection->executeQuery(self::$deleteQuery, $parameters);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $row
|
||||
* @return CollectionReference
|
||||
*/
|
||||
private function createReference(array $row)
|
||||
{
|
||||
return new CollectionReference(
|
||||
$row['baseId'],
|
||||
$row['databoxId'],
|
||||
$row['collectionId'],
|
||||
$row['displayIndex'],
|
||||
$row['isActive'],
|
||||
$row['alias']
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $rows
|
||||
* @return array
|
||||
*/
|
||||
private function createManyReferences($rows)
|
||||
{
|
||||
$references = [];
|
||||
|
||||
foreach ($rows as $row) {
|
||||
$references[$row['baseId']] = $this->createReference($row);
|
||||
}
|
||||
|
||||
return $references;
|
||||
}
|
||||
}
|
@@ -0,0 +1,69 @@
|
||||
<?php
|
||||
|
||||
namespace Alchemy\Phrasea\Collection\Repository;
|
||||
|
||||
use Alchemy\Phrasea\Collection\Collection;
|
||||
use Alchemy\Phrasea\Collection\CollectionRepository;
|
||||
|
||||
class ArrayCacheCollectionRepository implements CollectionRepository
|
||||
{
|
||||
/**
|
||||
* @var CollectionRepository
|
||||
*/
|
||||
private $collectionRepository;
|
||||
|
||||
/**
|
||||
* @var \collection[]
|
||||
*/
|
||||
private $collectionCache = null;
|
||||
|
||||
public function __construct(CollectionRepository $collectionRepository)
|
||||
{
|
||||
$this->collectionRepository = $collectionRepository;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \collection[]
|
||||
*/
|
||||
public function findAll()
|
||||
{
|
||||
if ($this->collectionCache === null) {
|
||||
$this->collectionCache = $this->collectionRepository->findAll();
|
||||
}
|
||||
|
||||
return $this->collectionCache;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $collectionId
|
||||
* @return \collection|null
|
||||
*/
|
||||
public function find($collectionId)
|
||||
{
|
||||
$collections = $this->findAll();
|
||||
|
||||
if (isset($collections[$collectionId])) {
|
||||
return $collections[$collectionId];
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public function save(Collection $collection)
|
||||
{
|
||||
$this->collectionRepository->save($collection);
|
||||
|
||||
if ($this->collectionCache !== null) {
|
||||
$this->collectionCache = null;
|
||||
}
|
||||
}
|
||||
|
||||
public function delete(Collection $collection)
|
||||
{
|
||||
$this->collectionRepository->delete($collection);
|
||||
|
||||
if (isset($this->collectionCache[$collection->getCollectionId()])) {
|
||||
unset($this->collectionCache[$collection->getCollectionId()]);
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,122 @@
|
||||
<?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\Collection\Repository;
|
||||
|
||||
use Alchemy\Phrasea\Application;
|
||||
use Alchemy\Phrasea\Collection\Collection;
|
||||
use Alchemy\Phrasea\Collection\CollectionRepository;
|
||||
use Doctrine\Common\Cache\Cache;
|
||||
|
||||
final class CachedCollectionRepository implements CollectionRepository
|
||||
{
|
||||
|
||||
/**
|
||||
* @var Application
|
||||
*/
|
||||
private $app;
|
||||
|
||||
/**
|
||||
* @var CollectionRepository
|
||||
*/
|
||||
private $repository;
|
||||
|
||||
/**
|
||||
* @var Cache
|
||||
*/
|
||||
private $cache;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $cacheKey;
|
||||
|
||||
/**
|
||||
* @param Application $application
|
||||
* @param CollectionRepository $repository
|
||||
* @param Cache $cache
|
||||
* @param $cacheKey
|
||||
*/
|
||||
public function __construct(Application $application, CollectionRepository $repository, Cache $cache, $cacheKey)
|
||||
{
|
||||
$this->app = $application;
|
||||
$this->repository = $repository;
|
||||
$this->cache = $cache;
|
||||
$this->cacheKey = $cacheKey;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \collection[]
|
||||
*/
|
||||
public function findAll()
|
||||
{
|
||||
$cacheKey = $this->getCacheKey();
|
||||
/** @var \collection[] $collections */
|
||||
$collections = $this->cache->fetch($cacheKey);
|
||||
|
||||
if ($collections === false) {
|
||||
$collections = $this->repository->findAll();
|
||||
$this->putInCache($cacheKey, $collections);
|
||||
} else {
|
||||
foreach ($collections as $collection) {
|
||||
$collection->hydrate($this->app);
|
||||
}
|
||||
}
|
||||
|
||||
return $collections;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $collectionId
|
||||
* @return \collection|null
|
||||
*/
|
||||
public function find($collectionId)
|
||||
{
|
||||
$collections = $this->findAll();
|
||||
|
||||
if (isset($collections[$collectionId])) {
|
||||
return $collections[$collectionId];
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public function save(Collection $collection)
|
||||
{
|
||||
$this->repository->save($collection);
|
||||
|
||||
$cacheKey = $this->getCacheKey();
|
||||
|
||||
$this->cache->delete($cacheKey);
|
||||
}
|
||||
|
||||
public function delete(Collection $collection)
|
||||
{
|
||||
$this->repository->delete($collection);
|
||||
|
||||
$cacheKey = $this->getCacheKey();
|
||||
|
||||
$this->cache->delete($cacheKey);
|
||||
}
|
||||
|
||||
private function putInCache($key, $value)
|
||||
{
|
||||
$this->cache->save($key, $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
private function getCacheKey()
|
||||
{
|
||||
$cacheKey = 'collections:' . hash('sha256', $this->cacheKey);
|
||||
|
||||
return $cacheKey;
|
||||
}
|
||||
}
|
@@ -0,0 +1,172 @@
|
||||
<?php
|
||||
|
||||
namespace Alchemy\Phrasea\Collection\Repository;
|
||||
|
||||
use Alchemy\Phrasea\Collection\Collection;
|
||||
use Alchemy\Phrasea\Collection\CollectionFactory;
|
||||
use Alchemy\Phrasea\Collection\CollectionRepository;
|
||||
use Alchemy\Phrasea\Collection\Reference\CollectionReferenceRepository;
|
||||
use Doctrine\DBAL\Connection;
|
||||
|
||||
class DbalCollectionRepository implements CollectionRepository
|
||||
{
|
||||
|
||||
private static $selectQuery = 'SELECT coll_id, asciiname, label_en, label_fr, label_de, label_nl, prefs, logo, majLogo, pub_wm
|
||||
FROM coll';
|
||||
|
||||
private static $insertQuery = 'INSERT INTO coll (asciiname, prefs, logo) VALUES (:name, :preferences, :logo)';
|
||||
|
||||
private static $updateQuery = 'UPDATE coll SET asciiname = :name, label_en = :labelEn, label_fr = :labelFr,
|
||||
label_de = :labelDe, label_nl = :labelNl, prefs = :preferences, logo = :logo,
|
||||
majLogo = :logoTimestamp, pub_wm = :publicWatermark WHERE coll_id = :collectionId';
|
||||
|
||||
private static $deleteQuery = 'DELETE FROM coll WHERE coll_id = :collectionId';
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $databoxId;
|
||||
|
||||
/**
|
||||
* @var CollectionReferenceRepository
|
||||
*/
|
||||
private $referenceRepository;
|
||||
|
||||
/**
|
||||
* @var Connection
|
||||
*/
|
||||
private $databoxConnection;
|
||||
|
||||
/**
|
||||
* @var CollectionFactory
|
||||
*/
|
||||
private $collectionFactory;
|
||||
|
||||
/**
|
||||
* @param $databoxId
|
||||
* @param Connection $databoxConnection
|
||||
* @param CollectionReferenceRepository $referenceRepository
|
||||
* @param CollectionFactory $collectionFactory
|
||||
*/
|
||||
public function __construct(
|
||||
$databoxId,
|
||||
Connection $databoxConnection,
|
||||
CollectionReferenceRepository $referenceRepository,
|
||||
CollectionFactory $collectionFactory
|
||||
) {
|
||||
$this->databoxId = (int) $databoxId;
|
||||
$this->databoxConnection = $databoxConnection;
|
||||
$this->referenceRepository = $referenceRepository;
|
||||
$this->collectionFactory = $collectionFactory;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \collection[]
|
||||
*/
|
||||
public function findAll()
|
||||
{
|
||||
$references = $this->referenceRepository->findAllByDatabox($this->databoxId);
|
||||
|
||||
if (empty($references)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$parameters = [];
|
||||
|
||||
foreach ($references as $reference) {
|
||||
$parameters[] = $reference->getCollectionId();
|
||||
}
|
||||
|
||||
$query = self::$selectQuery . ' WHERE coll_id IN (:collectionIds)';
|
||||
$parameters = [ 'collectionIds' => $parameters ];
|
||||
$parameterTypes = [ 'collectionIds' => Connection::PARAM_INT_ARRAY ];
|
||||
|
||||
$rows = $this->databoxConnection->fetchAll($query, $parameters, $parameterTypes);
|
||||
|
||||
return $this->collectionFactory->createMany($this->databoxId, $references, $rows);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $baseId
|
||||
* @return \collection|null
|
||||
*/
|
||||
public function find($baseId)
|
||||
{
|
||||
$reference = $this->referenceRepository->find($baseId);
|
||||
|
||||
if ($reference === null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$query = self::$selectQuery . ' WHERE coll_id = :collectionId';
|
||||
$row = $this->databoxConnection->fetchAssoc($query, [ ':collectionId' => $reference->getCollectionId() ]);
|
||||
|
||||
if ($row !== false) {
|
||||
return $this->collectionFactory->create($this->databoxId, $reference, $row);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $databoxId
|
||||
* @param int $collectionId
|
||||
* @return \collection|null
|
||||
*/
|
||||
public function findByCollectionId($databoxId, $collectionId)
|
||||
{
|
||||
$reference = $this->referenceRepository->findByCollectionId($databoxId, $collectionId);
|
||||
|
||||
if ($reference === null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$query = self::$selectQuery . ' WHERE coll_id = :collectionId';
|
||||
$row = $this->databoxConnection->fetchAssoc($query, [ ':collectionId' => $reference->getCollectionId() ]);
|
||||
|
||||
if ($row !== false) {
|
||||
return $this->collectionFactory->create($this->databoxId, $reference, $row);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public function save(Collection $collection)
|
||||
{
|
||||
$isInsert = true;
|
||||
$query = self::$insertQuery;
|
||||
$parameters = array(
|
||||
'name' => $collection->getName(),
|
||||
'preferences' => $collection->getPreferences(),
|
||||
'logo' => $collection->getLogo()
|
||||
);
|
||||
|
||||
if ($collection->getCollectionId() > 0) {
|
||||
$parameters['collectionId'] = $collection->getCollectionId();
|
||||
$parameters['labelEn'] = $collection->getLabel('en', false);
|
||||
$parameters['labelFr'] = $collection->getLabel('fr', false);
|
||||
$parameters['labelDe'] = $collection->getLabel('de', false);
|
||||
$parameters['labelNl'] = $collection->getLabel('nl', false);
|
||||
$parameters['logoTimestamp'] = $collection->getLogoUpdatedAt();
|
||||
$parameters['publicWatermark'] = $collection->getPublicWatermark();
|
||||
|
||||
$query = self::$updateQuery;
|
||||
$isInsert = false;
|
||||
}
|
||||
|
||||
$this->databoxConnection->executeQuery($query, $parameters);
|
||||
|
||||
if ($isInsert) {
|
||||
$collection->setCollectionId($this->databoxConnection->lastInsertId());
|
||||
}
|
||||
}
|
||||
|
||||
public function delete(Collection $collection)
|
||||
{
|
||||
$parameters = [
|
||||
'collectionId' => $collection->getCollectionId()
|
||||
];
|
||||
|
||||
$this->databoxConnection->executeQuery(self::$deleteQuery, $parameters);
|
||||
}
|
||||
}
|
@@ -1,5 +1,4 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Phraseanet
|
||||
*
|
||||
@@ -18,8 +17,6 @@ use Symfony\Component\Console\Input\ArrayInput;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
use Symfony\Component\Console\Input\InputOption;
|
||||
use Symfony\Component\Process\ExecutableFinder;
|
||||
use Symfony\Component\Yaml\Yaml;
|
||||
use Symfony\Component\Process\Process;
|
||||
use vierbergenlars\SemVer\version as SemVer;
|
||||
|
||||
@@ -65,7 +62,7 @@ class IniReset extends Command
|
||||
$dialog = $this->getHelperSet()->get('dialog');
|
||||
$dbName = $dialog->ask(
|
||||
$output,
|
||||
_('Please enter the databox name to reset or create')
|
||||
$this->container['translator']->trans('Please enter the databox name to reset or create')
|
||||
);
|
||||
}
|
||||
} else if ($input->getOption('db-name')) {
|
||||
@@ -75,7 +72,7 @@ class IniReset extends Command
|
||||
}
|
||||
|
||||
$continue = 'y';
|
||||
if (count($dbs['dbs']) > 1 && in_array($dbName, array_map(function($db) { return $db->get_dbname();}, $dbs['dbs']))) {
|
||||
if (count($dbs['dbs']) > 1 && in_array($dbName, array_map(function(\base $db) { return $db->get_dbname();}, $dbs['dbs']))) {
|
||||
if ($interactive) {
|
||||
do {
|
||||
$continue = mb_strtolower($dialog->ask($output, '<question>' .$dbName.' database is going to be truncated, do you want to continue ? (Y/n)</question>', 'Y'));
|
||||
@@ -87,7 +84,7 @@ class IniReset extends Command
|
||||
return;
|
||||
}
|
||||
|
||||
$unmountedDbs = $dbToMount = array_diff(array_map(function($db) { return $db->get_dbname();}, $dbs['dbs']), array($dbName));
|
||||
$unmountedDbs = $dbToMount = array_diff(array_map(function(\base $db) { return $db->get_dbname();}, $dbs['dbs']), array($dbName));
|
||||
|
||||
if (count($unmountedDbs) > 1 && $interactive) {
|
||||
array_unshift($unmountedDbs, 'all');
|
||||
|
@@ -31,60 +31,45 @@ class Uninstaller extends Command
|
||||
protected function doExecute(InputInterface $input, OutputInterface $output)
|
||||
{
|
||||
$root = $this->container['root.path'];
|
||||
$path = $this->container['cache.path'];
|
||||
|
||||
foreach ([
|
||||
$root.'/config/configuration.yml',
|
||||
$root.'/config/services.yml',
|
||||
$root.'/config/connexions.yml',
|
||||
$root.'/config/config.yml',
|
||||
$root.'/config/config.inc',
|
||||
$root.'/config/connexion.inc',
|
||||
$root.'/config/_GV.php',
|
||||
$root.'/config/_GV.php.old',
|
||||
$root.'/config/configuration-compiled.php',
|
||||
] as $file) {
|
||||
if ($this->container['filesystem']->exists($file)) {
|
||||
unlink($file);
|
||||
}
|
||||
}
|
||||
|
||||
foreach ([
|
||||
$paths = [
|
||||
$root . '/config/configuration.yml',
|
||||
$root . '/config/services.yml',
|
||||
$root . '/config/connexions.yml',
|
||||
$root . '/config/config.yml',
|
||||
$root . '/config/config.inc',
|
||||
$root . '/config/connexion.inc',
|
||||
$root . '/config/_GV.php',
|
||||
$root . '/config/_GV.php.old',
|
||||
$root . '/config/configuration-compiled.php',
|
||||
$this->container['tmp.download.path'],
|
||||
$this->container['tmp.lazaret.path'],
|
||||
$this->container['tmp.caption.path'],
|
||||
$this->container['tmp.path'].'/sessions',
|
||||
$this->container['tmp.path'].'/locks',
|
||||
] as $resource) {
|
||||
if (is_dir($resource)) {
|
||||
$finder = new Finder();
|
||||
foreach ($finder->files()->in($resource) as $file) {
|
||||
$this->container['filesystem']->remove($file);
|
||||
}
|
||||
} elseif (is_file($resource)) {
|
||||
$this->container['filesystem']->remove($resource);
|
||||
$this->container['tmp.path'] . '/sessions',
|
||||
$this->container['tmp.path'] . '/locks',
|
||||
$path . '/cache_registry.php',
|
||||
$path . '/cache_registry.yml',
|
||||
$path . '/serializer',
|
||||
$path . '/doctrine',
|
||||
$path . '/twig',
|
||||
$path . '/translations',
|
||||
$path . '/minify',
|
||||
$path . '/profiler',
|
||||
];
|
||||
|
||||
$files = $directories = [];
|
||||
|
||||
foreach ($paths as $path) {
|
||||
if (is_dir($path)) {
|
||||
$directories[] = $path;
|
||||
} elseif (is_file($path)) {
|
||||
$files[] = $path;
|
||||
}
|
||||
}
|
||||
|
||||
$path = $this->container['cache.path'];
|
||||
foreach ([
|
||||
$path.'/cache_registry.php',
|
||||
$path.'/cache_registry.yml',
|
||||
$path.'/serializer',
|
||||
$path.'/doctrine',
|
||||
$path.'/twig',
|
||||
$path.'/translations',
|
||||
$path.'/minify',
|
||||
$path.'/profiler',
|
||||
] as $resource) {
|
||||
if (is_dir($resource)) {
|
||||
$finder = new Finder();
|
||||
foreach ($finder->files()->in($resource) as $file) {
|
||||
$this->container['filesystem']->remove($file);
|
||||
}
|
||||
} elseif (is_file($resource)) {
|
||||
$this->container['filesystem']->remove($resource);
|
||||
}
|
||||
}
|
||||
$this->container['filesystem']->remove($files);
|
||||
$this->container['filesystem']->remove(Finder::create()->in($directories));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@@ -43,7 +43,7 @@ class RecordAdd extends Command
|
||||
protected function doExecute(InputInterface $input, OutputInterface $output)
|
||||
{
|
||||
try {
|
||||
$collection = \collection::get_from_base_id($this->container, $input->getArgument('base_id'));
|
||||
$collection = \collection::getByBaseId($this->container, $input->getArgument('base_id'));
|
||||
} catch (\Exception $e) {
|
||||
throw new \InvalidArgumentException(sprintf('Collection %s is invalid', $input->getArgument('base_id')));
|
||||
}
|
||||
|
@@ -12,6 +12,7 @@
|
||||
namespace Alchemy\Phrasea\Command\Setup;
|
||||
|
||||
use Alchemy\Phrasea\Command\Command;
|
||||
use Alchemy\Phrasea\Databox\DataboxPathExtractor;
|
||||
use Alchemy\Phrasea\Http\H264PseudoStreaming\H264Factory;
|
||||
use Alchemy\Phrasea\Model\Manipulator\TokenManipulator;
|
||||
use Symfony\Component\Console\Input\InputArgument;
|
||||
@@ -36,7 +37,8 @@ class H264MappingGenerator extends Command
|
||||
*/
|
||||
protected function doExecute(InputInterface $input, OutputInterface $output)
|
||||
{
|
||||
$paths = $this->extractPath($this->container->getApplicationBox());
|
||||
$extractor = new DataboxPathExtractor($this->container->getApplicationBox());
|
||||
$paths = $extractor->extractPaths();
|
||||
foreach ($paths as $path) {
|
||||
$this->container['filesystem']->mkdir($path);
|
||||
}
|
||||
@@ -95,22 +97,4 @@ class H264MappingGenerator extends Command
|
||||
|
||||
return ['mount-point' => 'mp4-videos-'.$n, 'directory' => $path, 'passphrase' => $this->container['random.low']->generateString(32, TokenManipulator::LETTERS_AND_NUMBERS)];
|
||||
}
|
||||
|
||||
private function extractPath(\appbox $appbox)
|
||||
{
|
||||
$paths = [];
|
||||
|
||||
foreach ($appbox->get_databoxes() as $databox) {
|
||||
foreach ($databox->get_subdef_structure() as $group => $subdefs) {
|
||||
if ('video' !== $group) {
|
||||
continue;
|
||||
}
|
||||
foreach ($subdefs as $subdef) {
|
||||
$paths[] = $subdef->get_path();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return array_filter(array_unique($paths));
|
||||
}
|
||||
}
|
||||
|
@@ -12,6 +12,7 @@
|
||||
namespace Alchemy\Phrasea\Command\Setup;
|
||||
|
||||
use Alchemy\Phrasea\Command\Command;
|
||||
use Alchemy\Phrasea\Databox\DataboxPathExtractor;
|
||||
use Symfony\Component\Console\Input\InputArgument;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
@@ -35,7 +36,8 @@ class XSendFileMappingGenerator extends Command
|
||||
*/
|
||||
protected function doExecute(InputInterface $input, OutputInterface $output)
|
||||
{
|
||||
$paths = $this->extractPath($this->container->getApplicationBox());
|
||||
$extractor = new DataboxPathExtractor($this->container->getApplicationBox());
|
||||
$paths = $extractor->extractPaths();
|
||||
foreach ($paths as $path) {
|
||||
$this->container['filesystem']->mkdir($path);
|
||||
}
|
||||
@@ -84,20 +86,4 @@ class XSendFileMappingGenerator extends Command
|
||||
|
||||
return ['mount-point' => 'protected_dir_'.$n, 'directory' => $path];
|
||||
}
|
||||
|
||||
private function extractPath(\appbox $appbox)
|
||||
{
|
||||
$paths = [];
|
||||
|
||||
foreach ($appbox->get_databoxes() as $databox) {
|
||||
$paths[] = (string) $databox->get_sxml_structure()->path;
|
||||
foreach ($databox->get_subdef_structure() as $group => $subdefs) {
|
||||
foreach ($subdefs as $subdef) {
|
||||
$paths[] = $subdef->get_path();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return array_filter(array_unique($paths));
|
||||
}
|
||||
}
|
||||
|
@@ -125,7 +125,7 @@ class Step31 implements DatasUpgraderInterface
|
||||
$uuid = Uuid::uuid4();
|
||||
try {
|
||||
$media = $this->app->getMediaFromUri($pathfile);
|
||||
$collection = \collection::get_from_coll_id($this->$app, $databox, (int) $record['coll_id']);
|
||||
$collection = \collection::getByCollectionId($this->$app, $databox, (int) $record['coll_id']);
|
||||
|
||||
$file = new File($this->app, $media, $collection);
|
||||
$uuid = $file->getUUID(true, true);
|
||||
|
@@ -16,7 +16,6 @@ use Alchemy\Phrasea\Application\Helper\DataboxLoggerAware;
|
||||
use Alchemy\Phrasea\Application\Helper\DelivererAware;
|
||||
use Alchemy\Phrasea\Http\DeliverDataInterface;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
|
||||
abstract class AbstractDelivery
|
||||
{
|
||||
@@ -33,26 +32,20 @@ abstract class AbstractDelivery
|
||||
|
||||
public function deliverContent(Request $request, \record_adapter $record, $subdef, $watermark, $stamp)
|
||||
{
|
||||
$file = $record->get_subdef($subdef);
|
||||
$pathOut = $file->get_pathfile();
|
||||
$mediaSubdefinition = $record->get_subdef($subdef);
|
||||
|
||||
if ($watermark === true && $file->get_type() === \media_subdef::TYPE_IMAGE) {
|
||||
$pathOut = \recordutils_image::watermark($this->app, $file);
|
||||
} elseif ($stamp === true && $file->get_type() === \media_subdef::TYPE_IMAGE) {
|
||||
$pathOut = \recordutils_image::stamp($this->app, $file);
|
||||
}
|
||||
$pathOut = $this->tamperProofSubDefinition($mediaSubdefinition, $watermark, $stamp);
|
||||
|
||||
$disposition = $request->query->get('download') ? DeliverDataInterface::DISPOSITION_ATTACHMENT : DeliverDataInterface::DISPOSITION_INLINE;
|
||||
|
||||
/** @var Response $response */
|
||||
$response = $this->deliverFile($pathOut, $file->get_file(), $disposition, $file->get_mime());
|
||||
$response = $this->deliverFile($pathOut, $mediaSubdefinition->get_file(), $disposition, $mediaSubdefinition->get_mime());
|
||||
|
||||
if (in_array($subdef, array('document', 'preview'))) {
|
||||
$response->setPrivate();
|
||||
$this->logView($record, $request);
|
||||
} elseif ($subdef !== 'thumbnail') {
|
||||
try {
|
||||
if ($file->getDataboxSubdef()->get_class() != \databox_subdef::CLASS_THUMBNAIL) {
|
||||
if ($mediaSubdefinition->getDataboxSubdef()->get_class() != \databox_subdef::CLASS_THUMBNAIL) {
|
||||
$response->setPrivate();
|
||||
$this->logView($record, $request);
|
||||
}
|
||||
@@ -81,4 +74,23 @@ abstract class AbstractDelivery
|
||||
// Ignore exception
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \media_subdef $mediaSubdefinition
|
||||
* @param bool $watermark
|
||||
* @param bool $stamp
|
||||
* @return string
|
||||
*/
|
||||
private function tamperProofSubDefinition(\media_subdef $mediaSubdefinition, $watermark, $stamp)
|
||||
{
|
||||
$pathOut = $mediaSubdefinition->getRealPath();
|
||||
|
||||
if ($watermark === true && $mediaSubdefinition->get_type() === \media_subdef::TYPE_IMAGE) {
|
||||
$pathOut = \recordutils_image::watermark($this->app, $mediaSubdefinition);
|
||||
} elseif ($stamp === true && $mediaSubdefinition->get_type() === \media_subdef::TYPE_IMAGE) {
|
||||
$pathOut = \recordutils_image::stamp($this->app, $mediaSubdefinition);
|
||||
}
|
||||
|
||||
return $pathOut;
|
||||
}
|
||||
}
|
||||
|
@@ -33,7 +33,7 @@ class CollectionController extends Controller
|
||||
*/
|
||||
public function getCollection(Request $request, $bas_id)
|
||||
{
|
||||
$collection = \collection::get_from_base_id($this->app, $bas_id);
|
||||
$collection = \collection::getByBaseId($this->app, $bas_id);
|
||||
|
||||
$admins = [];
|
||||
|
||||
@@ -144,7 +144,7 @@ class CollectionController extends Controller
|
||||
$success = false;
|
||||
$msg = $this->app->trans('An error occurred');
|
||||
|
||||
$collection = \collection::get_from_base_id($this->app, $bas_id);
|
||||
$collection = \collection::getByBaseId($this->app, $bas_id);
|
||||
try {
|
||||
if ($collection->get_record_amount() <= 500) {
|
||||
$collection->empty_collection(500);
|
||||
@@ -184,7 +184,7 @@ class CollectionController extends Controller
|
||||
{
|
||||
$success = false;
|
||||
|
||||
$collection = \collection::get_from_base_id($this->app, $bas_id);
|
||||
$collection = \collection::getByBaseId($this->app, $bas_id);
|
||||
|
||||
try {
|
||||
$this->app->getApplicationBox()->write_collection_pic(
|
||||
@@ -224,7 +224,7 @@ class CollectionController extends Controller
|
||||
{
|
||||
$success = false;
|
||||
|
||||
$collection = \collection::get_from_base_id($this->app, $bas_id);
|
||||
$collection = \collection::getByBaseId($this->app, $bas_id);
|
||||
|
||||
try {
|
||||
$this->app->getApplicationBox()->write_collection_pic(
|
||||
@@ -264,7 +264,7 @@ class CollectionController extends Controller
|
||||
{
|
||||
$success = false;
|
||||
|
||||
$collection = \collection::get_from_base_id($this->app, $bas_id);
|
||||
$collection = \collection::getByBaseId($this->app, $bas_id);
|
||||
|
||||
try {
|
||||
$collection->update_logo(null);
|
||||
@@ -323,7 +323,7 @@ class CollectionController extends Controller
|
||||
]);
|
||||
}
|
||||
|
||||
$collection = \collection::get_from_base_id($this->app, $bas_id);
|
||||
$collection = \collection::getByBaseId($this->app, $bas_id);
|
||||
|
||||
try {
|
||||
$this->app->getApplicationBox()->write_collection_pic(
|
||||
@@ -378,7 +378,7 @@ class CollectionController extends Controller
|
||||
]);
|
||||
}
|
||||
|
||||
$collection = \collection::get_from_base_id($this->app, $bas_id);
|
||||
$collection = \collection::getByBaseId($this->app, $bas_id);
|
||||
|
||||
try {
|
||||
$this->app->getApplicationBox()->write_collection_pic(
|
||||
@@ -432,7 +432,7 @@ class CollectionController extends Controller
|
||||
]);
|
||||
}
|
||||
|
||||
$collection = \collection::get_from_base_id($this->app, $bas_id);
|
||||
$collection = \collection::getByBaseId($this->app, $bas_id);
|
||||
|
||||
try {
|
||||
$this->app->getApplicationBox()->write_collection_pic(
|
||||
@@ -468,13 +468,13 @@ class CollectionController extends Controller
|
||||
$success = false;
|
||||
$msg = $this->app->trans('An error occured');
|
||||
|
||||
$collection = \collection::get_from_base_id($this->app, $bas_id);
|
||||
$collection = \collection::getByBaseId($this->app, $bas_id);
|
||||
|
||||
try {
|
||||
if ($collection->get_record_amount() > 0) {
|
||||
$msg = $this->app->trans('Empty the collection before removing');
|
||||
} else {
|
||||
$collection->unmount_collection($this->app);
|
||||
$collection->unmount();
|
||||
$collection->delete();
|
||||
$success = true;
|
||||
$msg = $this->app->trans('Successful removal');
|
||||
@@ -522,10 +522,10 @@ class CollectionController extends Controller
|
||||
{
|
||||
$success = false;
|
||||
|
||||
$collection = \collection::get_from_base_id($this->app, $bas_id);
|
||||
$collection = \collection::getByBaseId($this->app, $bas_id);
|
||||
|
||||
try {
|
||||
$collection->unmount_collection($this->app);
|
||||
$collection->unmount();
|
||||
$success = true;
|
||||
} catch (\Exception $e) {
|
||||
|
||||
@@ -562,7 +562,7 @@ class CollectionController extends Controller
|
||||
|
||||
$success = false;
|
||||
|
||||
$collection = \collection::get_from_base_id($this->app, $bas_id);
|
||||
$collection = \collection::getByBaseId($this->app, $bas_id);
|
||||
|
||||
try {
|
||||
$collection->set_name($name);
|
||||
@@ -594,7 +594,7 @@ class CollectionController extends Controller
|
||||
$this->app->abort(400, $this->app->trans('Invalid labels parameter'));
|
||||
}
|
||||
|
||||
$collection = \collection::get_from_base_id($this->app, $bas_id);
|
||||
$collection = \collection::getByBaseId($this->app, $bas_id);
|
||||
$success = true;
|
||||
|
||||
try {
|
||||
@@ -638,7 +638,7 @@ class CollectionController extends Controller
|
||||
|
||||
$success = false;
|
||||
|
||||
$collection = \collection::get_from_base_id($this->app, $bas_id);
|
||||
$collection = \collection::getByBaseId($this->app, $bas_id);
|
||||
|
||||
try {
|
||||
$collection->set_public_presentation($watermark);
|
||||
@@ -671,7 +671,7 @@ class CollectionController extends Controller
|
||||
{
|
||||
$success = false;
|
||||
|
||||
$collection = \collection::get_from_base_id($this->app, $bas_id);
|
||||
$collection = \collection::getByBaseId($this->app, $bas_id);
|
||||
|
||||
try {
|
||||
$collection->enable($this->app->getApplicationBox());
|
||||
@@ -704,7 +704,7 @@ class CollectionController extends Controller
|
||||
{
|
||||
$success = false;
|
||||
|
||||
$collection = \collection::get_from_base_id($this->app, $bas_id);
|
||||
$collection = \collection::getByBaseId($this->app, $bas_id);
|
||||
|
||||
try {
|
||||
$collection->disable($this->app->getApplicationBox());
|
||||
@@ -736,7 +736,7 @@ class CollectionController extends Controller
|
||||
{
|
||||
/** @var \databox $databox */
|
||||
$databox = $this->app->findDataboxById(\phrasea::sbasFromBas($this->app, $bas_id));
|
||||
$collection = \collection::get_from_base_id($this->app, $bas_id);
|
||||
$collection = \collection::getByBaseId($this->app, $bas_id);
|
||||
$structFields = $suggestedValues = $basePrefs = [];
|
||||
|
||||
/** @var \databox_field $meta */
|
||||
@@ -806,7 +806,7 @@ class CollectionController extends Controller
|
||||
{
|
||||
$success = false;
|
||||
|
||||
$collection = \collection::get_from_base_id($this->app, $bas_id);
|
||||
$collection = \collection::getByBaseId($this->app, $bas_id);
|
||||
$prefs = $request->request->get('str');
|
||||
|
||||
try {
|
||||
@@ -843,7 +843,7 @@ class CollectionController extends Controller
|
||||
*/
|
||||
public function getDetails($bas_id)
|
||||
{
|
||||
$collection = \collection::get_from_base_id($this->app, $bas_id);
|
||||
$collection = \collection::getByBaseId($this->app, $bas_id);
|
||||
|
||||
$out = ['total' => ['totobj' => 0, 'totsiz' => 0, 'mega' => '0', 'giga' => '0'], 'result' => []];
|
||||
|
||||
|
@@ -124,6 +124,10 @@ class DashboardController extends Controller
|
||||
public function addAdmins(Request $request)
|
||||
{
|
||||
$admins = $request->request->get('admins', []);
|
||||
|
||||
// Remove empty values
|
||||
$admins = array_filter($admins);
|
||||
|
||||
if (!is_array($admins) || count($admins) === 0) {
|
||||
$this->app->abort(400, '"admins" parameter must contains at least one value.');
|
||||
}
|
||||
@@ -134,6 +138,15 @@ class DashboardController extends Controller
|
||||
}
|
||||
|
||||
$userRepository = $this->getUserRepository();
|
||||
|
||||
$demotedAdmins = [];
|
||||
|
||||
foreach ($userRepository->findAdmins() as $admin) {
|
||||
if (!in_array($admin->getId(), $admins)) {
|
||||
$demotedAdmins[$admin->getId()] = $admin;
|
||||
}
|
||||
}
|
||||
|
||||
$userRepository->findBy(['id' => $admins]);
|
||||
$admins = array_map(function ($usrId) use ($userRepository) {
|
||||
if (null === $user = $userRepository->find($usrId)) {
|
||||
@@ -145,7 +158,10 @@ class DashboardController extends Controller
|
||||
|
||||
/** @var UserManipulator $userManipulator */
|
||||
$userManipulator = $this->app['manipulator.user'];
|
||||
|
||||
$userManipulator->demote($demotedAdmins);
|
||||
$userManipulator->promote($admins);
|
||||
|
||||
/** @var ACLManipulator $aclManipulator */
|
||||
$aclManipulator = $this->app['manipulator.acl'];
|
||||
$aclManipulator->resetAdminRights($admins);
|
||||
|
@@ -633,7 +633,7 @@ class DataboxController extends Controller
|
||||
{
|
||||
try {
|
||||
foreach ($request->request->get('order', []) as $data) {
|
||||
$collection = \collection::get_from_base_id($this->app, $data['id']);
|
||||
$collection = \collection::getByBaseId($this->app, $data['id']);
|
||||
$collection->set_ord($data['offset']);
|
||||
}
|
||||
$success = true;
|
||||
@@ -712,7 +712,7 @@ class DataboxController extends Controller
|
||||
} catch (\Exception $e) {
|
||||
return $this->app->redirectPath('admin_database_submit_collection', [
|
||||
'databox_id' => $databox_id,
|
||||
'error' => 'error',
|
||||
'error' => $e->getMessage(),
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
@@ -56,7 +56,7 @@ class FeedController extends Controller
|
||||
if ($request->request->get('public') == '1') {
|
||||
$feed->setIsPublic(true);
|
||||
} elseif ($request->request->get('base_id')) {
|
||||
$feed->setCollection(\collection::get_from_base_id($this->app, $request->request->get('base_id')));
|
||||
$feed->setCollection(\collection::getByBaseId($this->app, $request->request->get('base_id')));
|
||||
}
|
||||
|
||||
$publisher->setFeed($feed);
|
||||
@@ -106,7 +106,7 @@ class FeedController extends Controller
|
||||
}
|
||||
|
||||
try {
|
||||
$collection = \collection::get_from_base_id($this->app, $request->request->get('base_id'));
|
||||
$collection = \collection::getByBaseId($this->app, $request->request->get('base_id'));
|
||||
} catch (\Exception $e) {
|
||||
$collection = null;
|
||||
}
|
||||
|
@@ -32,8 +32,7 @@ class RootController extends Controller
|
||||
'module' => 'admin',
|
||||
'events' => $this->app['events-manager'],
|
||||
'module_name' => 'Admin',
|
||||
'notice' => $request->query->get("notice"),
|
||||
'tree' => $this->render('admin/tree.html.twig', $params),
|
||||
'notice' => $request->query->get("notice")
|
||||
], $params));
|
||||
}
|
||||
|
||||
|
@@ -455,7 +455,7 @@ class UserController extends Controller
|
||||
$registrationRepository->getUserRegistrations(
|
||||
$user,
|
||||
array_map(function ($baseId) {
|
||||
return \collection::get_from_base_id($this->app, $baseId);
|
||||
return \collection::getByBaseId($this->app, $baseId);
|
||||
}, $bases)
|
||||
) as $registration) {
|
||||
$registrationManipulator->rejectRegistration($registration);
|
||||
@@ -473,7 +473,7 @@ class UserController extends Controller
|
||||
foreach ($registrationRepository->getUserRegistrations(
|
||||
$user,
|
||||
array_map(function ($baseId) {
|
||||
return \collection::get_from_base_id($this->app, $baseId);
|
||||
return \collection::getByBaseId($this->app, $baseId);
|
||||
}, $bases)
|
||||
) as $registration) {
|
||||
$done[$usr][$registration->getBaseId()] = true;
|
||||
@@ -503,7 +503,7 @@ class UserController extends Controller
|
||||
];
|
||||
|
||||
foreach ($bases as $bas => $isok) {
|
||||
$collection = \collection::get_from_base_id($this->app, $bas);
|
||||
$collection = \collection::getByBaseId($this->app, $bas);
|
||||
$label = $collection->get_label($this->app['locale']);
|
||||
|
||||
if ($isok) {
|
||||
|
@@ -837,7 +837,7 @@ class V1Controller extends Controller
|
||||
return $this->getBadRequestAction($request, 'Missing base_id parameter');
|
||||
}
|
||||
|
||||
$collection = \collection::get_from_base_id($this->app, $request->get('base_id'));
|
||||
$collection = \collection::getByBaseId($this->app, $request->get('base_id'));
|
||||
|
||||
if (!$this->getAclForUser()->has_right_on_base($request->get('base_id'), 'canaddrecord')) {
|
||||
return Result::createError($request, 403, sprintf(
|
||||
@@ -935,7 +935,7 @@ class V1Controller extends Controller
|
||||
$media = $this->app->getMediaFromUri($file->getPathname());
|
||||
$record = $this->findDataboxById($request->get('databox_id'))->get_record($request->get('record_id'));
|
||||
$base_id = $record->getBaseId();
|
||||
$collection = \collection::get_from_base_id($this->app, $base_id);
|
||||
$collection = \collection::getByBaseId($this->app, $base_id);
|
||||
if (!$this->getAclForUser()->has_right_on_base($base_id, 'canaddrecord')) {
|
||||
return Result::createError($request, 403, sprintf(
|
||||
'You do not have access to collection %s', $collection->get_label($this->app['locale.I18n'])
|
||||
@@ -943,7 +943,7 @@ class V1Controller extends Controller
|
||||
}
|
||||
$adapt = ($request->get('adapt')===null || !(\p4field::isno($request->get('adapt'))));
|
||||
$ret['adapt'] = $adapt;
|
||||
$record->substitute_subdef($request->get('name'), $media, $this->app, $adapt);
|
||||
$this->getSubdefSubstituer()->substitute($record, $request->get('name'), $media, $adapt);
|
||||
foreach ($record->get_embedable_medias() as $name => $media) {
|
||||
if ($name == $request->get('name') &&
|
||||
null !== ($subdef = $this->listEmbeddableMedia($request, $record, $media))) {
|
||||
@@ -1611,7 +1611,7 @@ class V1Controller extends Controller
|
||||
$record = $databox->get_record($record_id);
|
||||
|
||||
try {
|
||||
$collection = \collection::get_from_base_id($this->app, $request->get('base_id'));
|
||||
$collection = \collection::getByBaseId($this->app, $request->get('base_id'));
|
||||
$record->move_to_collection($collection, $this->getApplicationBox());
|
||||
|
||||
return Result::create($request, ["record" => $this->listRecord($request, $record)])->createResponse();
|
||||
@@ -2067,7 +2067,7 @@ class V1Controller extends Controller
|
||||
*/
|
||||
protected function createStory($data)
|
||||
{
|
||||
$collection = \collection::get_from_base_id($this->app, $data->{'base_id'});
|
||||
$collection = \collection::getByBaseId($this->app, $data->{'base_id'});
|
||||
|
||||
if (!$this->getAclForUser()->has_right_on_base($collection->get_base_id(), 'canaddrecord')) {
|
||||
$this->app->abort(403, sprintf('You can not create a story on this collection %s', $collection->get_base_id()));
|
||||
@@ -2235,8 +2235,8 @@ class V1Controller extends Controller
|
||||
if (!in_array($name, array('thumbnail', 'preview'))) {
|
||||
continue;
|
||||
}
|
||||
$media = $this->app->getMediaFromUri($value->get_pathfile());
|
||||
$story->substitute_subdef($name, $media, $this->app);
|
||||
$media = $this->app->getMediaFromUri($value->getRealPath());
|
||||
$this->getSubdefSubstituer()->substitute($story, $name, $media);
|
||||
$this->getDataboxLogger($story->getDatabox())->log(
|
||||
$story,
|
||||
\Session_Logger::EVENT_SUBSTITUTE,
|
||||
@@ -2304,7 +2304,7 @@ class V1Controller extends Controller
|
||||
$ret = [ 'success' => true ];
|
||||
}
|
||||
catch (AccountException $exception) {
|
||||
$ret = [ 'success' => false, 'message' => _($exception->getMessage()) ];
|
||||
$ret = [ 'success' => false, 'message' => $this->app->trans($exception->getMessage()) ];
|
||||
}
|
||||
|
||||
return Result::create($request, $ret)->createResponse();
|
||||
@@ -2327,7 +2327,7 @@ class V1Controller extends Controller
|
||||
$service->updatePassword($command, null);
|
||||
$ret = ['success' => true];
|
||||
} catch (AccountException $exception) {
|
||||
$ret = [ 'success' => false, 'message' => _($exception->getMessage()) ];
|
||||
$ret = [ 'success' => false, 'message' => $this->app->trans($exception->getMessage()) ];
|
||||
}
|
||||
} else {
|
||||
$ret = [ 'success' => false, 'message' => (string) $form->getErrorsAsString() ];
|
||||
@@ -2567,4 +2567,12 @@ class V1Controller extends Controller
|
||||
{
|
||||
return $this->app['phraseanet.SE.logger'];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \Alchemy\Phrasea\Media\SubdefSubstituer
|
||||
*/
|
||||
private function getSubdefSubstituer()
|
||||
{
|
||||
return $this->app['subdef.substituer'];
|
||||
}
|
||||
}
|
||||
|
@@ -52,18 +52,7 @@ class MediaAccessorController extends Controller
|
||||
|
||||
public function showAction(Request $request, $token)
|
||||
{
|
||||
try {
|
||||
$token = JWT::decode($token, $this->keyStorage, $this->allowedAlgorithms);
|
||||
} catch (\UnexpectedValueException $exception) {
|
||||
throw new NotFoundHttpException('Resource not found', $exception);
|
||||
} catch (\Exception $exception) {
|
||||
throw new BadRequestHttpException('Invalid token', $exception);
|
||||
}
|
||||
|
||||
if (! isset($token->sdef) || !is_array($token->sdef) || count($token->sdef) !== 3) {
|
||||
throw new BadRequestHttpException('sdef should be a sub-definition identifier.');
|
||||
}
|
||||
list ($sbas_id, $record_id, $subdef) = $token->sdef;
|
||||
list($sbas_id, $record_id, $subdef) = $this->validateToken($token);
|
||||
|
||||
try {
|
||||
$databox = $this->findDataboxById($sbas_id);
|
||||
@@ -93,4 +82,39 @@ class MediaAccessorController extends Controller
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $token
|
||||
* @return object
|
||||
*/
|
||||
public function decodeToken($token)
|
||||
{
|
||||
try {
|
||||
return JWT::decode($token, $this->keyStorage, $this->allowedAlgorithms);
|
||||
} catch (\UnexpectedValueException $exception) {
|
||||
throw new NotFoundHttpException('Resource not found', $exception);
|
||||
} catch (\Exception $exception) {
|
||||
throw new BadRequestHttpException('Invalid token', $exception);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate token and returns triplet containing sbas_id, record_id and subdef.
|
||||
*
|
||||
* @param string|object $token
|
||||
* @return array
|
||||
*/
|
||||
public function validateToken($token)
|
||||
{
|
||||
if (is_string($token)) {
|
||||
$token = $this->decodeToken($token);
|
||||
}
|
||||
|
||||
if (!isset($token->sdef) || !is_array($token->sdef) || count($token->sdef) !== 3) {
|
||||
throw new BadRequestHttpException('sdef should be a sub-definition identifier.');
|
||||
}
|
||||
list ($sbas_id, $record_id, $subdef) = $token->sdef;
|
||||
|
||||
return array($sbas_id, $record_id, $subdef);
|
||||
}
|
||||
}
|
||||
|
@@ -11,11 +11,12 @@
|
||||
namespace Alchemy\Phrasea\Controller;
|
||||
|
||||
use Alchemy\Embed\Media\Media;
|
||||
use Alchemy\Embed\Media\MediaInformation;
|
||||
use Alchemy\Phrasea\Application;
|
||||
use Alchemy\Phrasea\Application\Helper\ApplicationBoxAware;
|
||||
use Alchemy\Phrasea\Authentication\ACLProvider;
|
||||
use Alchemy\Phrasea\Authentication\Authenticator;
|
||||
use Alchemy\Phrasea\Model\Repositories\BasketElementRepository;
|
||||
use Alchemy\Phrasea\Model\Repositories\FeedItemRepository;
|
||||
use Alchemy\Phrasea\Model\Serializer\CaptionSerializer;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
@@ -23,20 +24,19 @@ use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
|
||||
|
||||
class PermalinkController extends AbstractDelivery
|
||||
{
|
||||
use ApplicationBoxAware;
|
||||
|
||||
/** @var ACLProvider */
|
||||
private $acl;
|
||||
/** @var \appbox */
|
||||
private $appbox;
|
||||
/** @var Authenticator */
|
||||
private $authentication;
|
||||
/** @var Media */
|
||||
private $mediaService;
|
||||
|
||||
public function __construct(Application $app, \appbox $appbox, ACLProvider $acl, Authenticator $authenticator, Media $mediaService)
|
||||
public function __construct(Application $app, ACLProvider $acl, Authenticator $authenticator, Media $mediaService)
|
||||
{
|
||||
parent::__construct($app);
|
||||
|
||||
$this->appbox = $appbox;
|
||||
$this->acl = $acl;
|
||||
$this->authentication = $authenticator;
|
||||
$this->mediaService = $mediaService;
|
||||
@@ -44,9 +44,9 @@ class PermalinkController extends AbstractDelivery
|
||||
|
||||
public function getOptionsResponse(Request $request, $sbas_id, $record_id)
|
||||
{
|
||||
$databox = $this->mediaService->getDatabox($sbas_id);
|
||||
$databox = $this->findDataboxById($sbas_id);
|
||||
$token = $request->query->get('token');
|
||||
$record = $this->mediaService->retrieveRecord($databox, $token, $record_id, $request->get('subdef', 'thumbnail'));
|
||||
$record = $this->retrieveRecord($databox, $token, $record_id, $request->get('subdef', 'thumbnail'));
|
||||
|
||||
if (null === $record) {
|
||||
throw new NotFoundHttpException("Record not found");
|
||||
@@ -57,9 +57,9 @@ class PermalinkController extends AbstractDelivery
|
||||
|
||||
public function deliverCaption(Request $request, $sbas_id, $record_id)
|
||||
{
|
||||
$databox = $this->mediaService->getDatabox($sbas_id);
|
||||
$databox = $this->findDataboxById($sbas_id);
|
||||
$token = $request->query->get('token');
|
||||
$record = $this->mediaService->retrieveRecord($databox, $token, $record_id, \databox_subdef::CLASS_THUMBNAIL);
|
||||
$record = $this->retrieveRecord($databox, $token, $record_id, \databox_subdef::CLASS_THUMBNAIL);
|
||||
|
||||
if (null === $record) {
|
||||
throw new NotFoundHttpException("Caption not found");
|
||||
@@ -74,7 +74,38 @@ class PermalinkController extends AbstractDelivery
|
||||
return $this->doDeliverPermaview($sbas_id, $record_id, $request->query->get('token'), $subdef);
|
||||
}
|
||||
|
||||
public function deliverPermaviewOldWay($sbas_id, $record_id, $token, $subdef)
|
||||
private function doDeliverPermaview($sbas_id, $record_id, $token, $subdefName)
|
||||
{
|
||||
$databox = $this->findDataboxById($sbas_id);
|
||||
$record = $this->retrieveRecord($databox, $token, $record_id, $subdefName);
|
||||
$subdef = $record->get_subdef($subdefName);
|
||||
|
||||
$information = $this->mediaService->createMediaInformationFromResourceAndRoute(
|
||||
$subdef,
|
||||
'permalinks_permalink',
|
||||
[
|
||||
'sbas_id' => $sbas_id,
|
||||
'record_id' => $record_id,
|
||||
'subdef' => $subdefName,
|
||||
'label' => $record->get_title(),
|
||||
'token' => $token,
|
||||
]
|
||||
);
|
||||
$metaData = $this->mediaService->getMetaData($information);
|
||||
|
||||
return $this->app['twig']->render('overview.html.twig', [
|
||||
'ogMetaData' => $metaData['ogMetaData'],
|
||||
'subdef' => $subdef,
|
||||
'module_name' => 'overview',
|
||||
'module' => 'overview',
|
||||
'view' => 'overview',
|
||||
'token' => $token,
|
||||
'record' => $record,
|
||||
'recordUrl' => $information->getUrl(),
|
||||
]);
|
||||
}
|
||||
|
||||
public function deliverPermaviewOldWay(Request $request, $sbas_id, $record_id, $token, $subdef)
|
||||
{
|
||||
return $this->doDeliverPermaview($sbas_id, $record_id, $token, $subdef);
|
||||
}
|
||||
@@ -84,35 +115,10 @@ class PermalinkController extends AbstractDelivery
|
||||
return $this->doDeliverPermalink($request, $sbas_id, $record_id, $request->query->get('token'), $subdef);
|
||||
}
|
||||
|
||||
public function deliverPermalinkOldWay(Request $request, $sbas_id, $record_id, $token, $subdef)
|
||||
{
|
||||
return $this->doDeliverPermalink($request, $sbas_id, $record_id, $token, $subdef);
|
||||
}
|
||||
|
||||
private function doDeliverPermaview($sbas_id, $record_id, $token, $subdefName)
|
||||
{
|
||||
|
||||
$databox = $this->mediaService->getDatabox($sbas_id);
|
||||
$record = $this->mediaService->retrieveRecord($databox, $token, $record_id, $subdefName);
|
||||
$metaDatas = $this->mediaService->getMetaDatas($record, $subdefName);
|
||||
$subdef = $record->get_subdef($subdefName);
|
||||
|
||||
return $this->app['twig']->render('overview.html.twig', [
|
||||
'ogMetaDatas' => $metaDatas['ogMetaDatas'],
|
||||
'subdef' => $subdef,
|
||||
'module_name' => 'overview',
|
||||
'module' => 'overview',
|
||||
'view' => 'overview',
|
||||
'token' => $token,
|
||||
'record' => $record,
|
||||
]);
|
||||
}
|
||||
|
||||
private function doDeliverPermalink(Request $request, $sbas_id, $record_id, $token, $subdef)
|
||||
{
|
||||
$databox = $this->mediaService->getDatabox($sbas_id);
|
||||
// $record = $this->retrieveRecord($databox, $token, $record_id, $subdef);
|
||||
$record = $this->mediaService->retrieveRecord($databox, $token, $record_id, $subdef);
|
||||
$databox = $this->findDataboxById($sbas_id);
|
||||
$record = $this->retrieveRecord($databox, $token, $record_id, $subdef);
|
||||
$watermark = $stamp = false;
|
||||
|
||||
if ($this->authentication->isAuthenticated()) {
|
||||
@@ -132,7 +138,7 @@ class PermalinkController extends AbstractDelivery
|
||||
return $this->deliverContentWithCaptionLink($request, $record, $subdef, $watermark, $stamp, $token);
|
||||
}
|
||||
|
||||
$collection = \collection::get_from_base_id($this->app, $record->get_base_id());
|
||||
$collection = \collection::getByBaseId($this->app, $record->get_base_id());
|
||||
switch ($collection->get_pub_wm()) {
|
||||
default:
|
||||
case 'none':
|
||||
@@ -170,4 +176,42 @@ class PermalinkController extends AbstractDelivery
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
public function deliverPermalinkOldWay(Request $request, $sbas_id, $record_id, $token, $subdef)
|
||||
{
|
||||
return $this->doDeliverPermalink($request, $sbas_id, $record_id, $token, $subdef);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \databox $databox
|
||||
* @param string $token
|
||||
* @param int $record_id
|
||||
* @param string $subdef
|
||||
* @return \record_adapter
|
||||
*/
|
||||
private function retrieveRecord(\databox $databox, $token, $record_id, $subdef)
|
||||
{
|
||||
try {
|
||||
$record = $databox->get_record($record_id);
|
||||
$subDefinition = $record->get_subdef($subdef);
|
||||
$permalink = $subDefinition->get_permalink();
|
||||
} catch (\Exception $exception) {
|
||||
throw new NotFoundHttpException('Wrong token.', $exception);
|
||||
}
|
||||
|
||||
if (null === $permalink || !$permalink->get_is_activated()) {
|
||||
throw new NotFoundHttpException('This token has been disabled.');
|
||||
}
|
||||
|
||||
$feedItemsRepository = $this->app['repo.feed-items'];
|
||||
if (in_array($subdef, [\databox_subdef::CLASS_PREVIEW, \databox_subdef::CLASS_THUMBNAIL])
|
||||
&& $feedItemsRepository->isRecordInPublicFeed($databox->get_sbas_id(), $record_id)
|
||||
) {
|
||||
return $record;
|
||||
} elseif ($permalink->get_token() == (string)$token) {
|
||||
return $record;
|
||||
}
|
||||
|
||||
throw new NotFoundHttpException('Wrong token.');
|
||||
}
|
||||
}
|
||||
|
@@ -297,7 +297,7 @@ class EditController extends Controller
|
||||
continue;
|
||||
}
|
||||
|
||||
$media = $this->app->getMediaFromUri($value->get_pathfile());
|
||||
$media = $this->app->getMediaFromUri($value->getRealPath());
|
||||
$this->getSubDefinitionSubstituer()->substitute($reg_record, $name, $media);
|
||||
$this->getDispatcher()->dispatch(PhraseaEvents::RECORD_EDIT, new RecordEdit($reg_record));
|
||||
$this->getDataboxLogger($reg_record->get_databox())->log(
|
||||
|
@@ -58,7 +58,7 @@ class MoveCollectionController extends Controller
|
||||
}
|
||||
|
||||
try {
|
||||
$collection = \collection::get_from_base_id($this->app, $request->request->get('base_id'));
|
||||
$collection = \collection::getByBaseId($this->app, $request->request->get('base_id'));
|
||||
} catch (\Exception_Databox_CollectionNotFound $e) {
|
||||
$datas['message'] = $this->app->trans('Invalid target collection');
|
||||
|
||||
|
@@ -30,13 +30,14 @@ class PropertyController extends Controller
|
||||
|
||||
$records = RecordsRequest::fromRequest($this->app, $request, false, ['chgstatus']);
|
||||
|
||||
if (count($records->databoxes()) > 1) {
|
||||
$databoxes = $records->databoxes();
|
||||
if (count($databoxes) > 1) {
|
||||
return new Response($this->render('prod/actions/Property/index.html.twig', [
|
||||
'records' => $records,
|
||||
]));
|
||||
}
|
||||
|
||||
$databox = current($records->databoxes());
|
||||
$databox = reset($databoxes);
|
||||
$statusStructure = $databox->getStatusStructure();
|
||||
$recordsStatuses = [];
|
||||
|
||||
|
@@ -156,7 +156,11 @@ class QueryController extends Controller
|
||||
. $this->app->trans('%total% reponses', ['%total%' => '<span>'.$result->getTotal().'</span>']) . '</a>';
|
||||
|
||||
$json['infos'] = $infoResult;
|
||||
$json['navigation'] = $string;
|
||||
$json['navigationTpl'] = $string;
|
||||
$json['navigation'] = [
|
||||
'page' => $page,
|
||||
'perPage' => $perPage
|
||||
];
|
||||
|
||||
$prop = null;
|
||||
|
||||
|
@@ -41,35 +41,13 @@ class ShareController extends Controller
|
||||
|
||||
$preview = $record->get_preview();
|
||||
|
||||
if ($preview->get_permalink() !== null) {
|
||||
if (null !== $previewLink = $preview->get_permalink()) {
|
||||
$permalinkUrl = $previewLink->get_url();
|
||||
$permaviewUrl = $previewLink->get_page();
|
||||
$previewWidth = $preview->get_width();
|
||||
$previewHeight = $preview->get_height();
|
||||
|
||||
|
||||
$subdefName = $preview->get_name();
|
||||
$subdef = $record->get_subdef($subdefName);
|
||||
|
||||
switch ($record->getType()) {
|
||||
|
||||
case 'flexpaper':
|
||||
case 'document':
|
||||
case 'audio':
|
||||
case 'video':
|
||||
default:
|
||||
$token = $preview->get_permalink()->get_token();
|
||||
$permalinkUrl = $preview->get_permalink()->get_url();
|
||||
$permaviewUrl = $preview->get_permalink()->get_page();
|
||||
$previewWidth = $preview->get_width();
|
||||
$previewHeight = $preview->get_height();
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
$sbas_id = $record->getDataboxId();
|
||||
$embedUrl = $this->app->url('alchemy_embed_view', [
|
||||
'sbas_id' => $sbas_id,
|
||||
'record_id' => $record_id,
|
||||
'subdefName' => $subdefName,
|
||||
'token' => $token,
|
||||
]);
|
||||
$embedUrl = $this->app->url('alchemy_embed_view', ['url' => (string)$permalinkUrl]);
|
||||
|
||||
$outputVars = [
|
||||
'isAvailable' => true,
|
||||
|
@@ -33,7 +33,7 @@ class StoryController extends Controller
|
||||
|
||||
public function postCreateFormAction(Request $request)
|
||||
{
|
||||
$collection = \collection::get_from_base_id($this->app, $request->request->get('base_id'));
|
||||
$collection = \collection::getByBaseId($this->app, $request->request->get('base_id'));
|
||||
|
||||
if (!$this->getAclForUser()->has_right_on_base($collection->get_base_id(), 'canaddrecord')) {
|
||||
throw new AccessDeniedHttpException('You can not create a story on this collection');
|
||||
|
@@ -83,7 +83,7 @@ class ToolsController extends Controller
|
||||
if (!$record->isStory()) {
|
||||
try {
|
||||
$metadata = $this->getExifToolReader()
|
||||
->files($record->get_subdef('document')->get_pathfile())
|
||||
->files($record->get_subdef('document')->getRealPath())
|
||||
->first()->getMetadatas();
|
||||
} catch (PHPExiftoolException $e) {
|
||||
// ignore
|
||||
|
@@ -133,7 +133,7 @@ class UploadController extends Controller
|
||||
$this->getFilesystem()->rename($uploadedFilename, $renamedFilename);
|
||||
|
||||
$media = $this->app->getMediaFromUri($renamedFilename);
|
||||
$collection = \collection::get_from_base_id($this->app, $base_id);
|
||||
$collection = \collection::getByBaseId($this->app, $base_id);
|
||||
|
||||
$lazaretSession = new LazaretSession();
|
||||
$lazaretSession->setUser($this->getAuthenticatedUser());
|
||||
|
@@ -316,7 +316,7 @@ class AccountController extends Controller
|
||||
if (0 !== count($registrations)) {
|
||||
foreach ($registrations as $baseId) {
|
||||
$this->getRegistrationManipulator()
|
||||
->createRegistration($user, \collection::get_from_base_id($this->app, $baseId));
|
||||
->createRegistration($user, \collection::getByBaseId($this->app, $baseId));
|
||||
}
|
||||
$this->app->addFlash('success', $this->app->trans('Your registration requests have been taken into account.'));
|
||||
}
|
||||
|
@@ -82,7 +82,7 @@ class SessionController extends Controller
|
||||
|
||||
if (in_array($this->getSession()->get('phraseanet.message'), ['1', null])) {
|
||||
if ($this->app['phraseanet.configuration']['main']['maintenance']) {
|
||||
$ret['message'] .= _('The application is going down for maintenance, please logout.');
|
||||
$ret['message'] .= $this->app->trans('The application is going down for maintenance, please logout.');
|
||||
}
|
||||
|
||||
if ($this->getConf()->get(['registry', 'maintenance', 'enabled'], false)) {
|
||||
|
@@ -0,0 +1,106 @@
|
||||
<?php
|
||||
|
||||
namespace Alchemy\Phrasea\ControllerProvider;
|
||||
|
||||
use Alchemy\EmbedProvider\EmbedServiceProvider;
|
||||
use Silex\Application;
|
||||
use Silex\ServiceProviderInterface;
|
||||
|
||||
class ControllerProviderServiceProvider implements ServiceProviderInterface
|
||||
{
|
||||
|
||||
private $controllerProviders = [];
|
||||
|
||||
/**
|
||||
* Registers services on the given app.
|
||||
*
|
||||
* This method should only be used to configure services and parameters.
|
||||
* It should not get services.
|
||||
*/
|
||||
public function register(Application $app)
|
||||
{
|
||||
$this->loadProviders();
|
||||
|
||||
foreach ($this->controllerProviders as $class => $values) {
|
||||
$app->register(new $class, $values);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Bootstraps the application.
|
||||
*
|
||||
* This method is called after all services are registered
|
||||
* and should be used for "dynamic" configuration (whenever
|
||||
* a service must be requested).
|
||||
*/
|
||||
public function boot(Application $app)
|
||||
{
|
||||
// Nothing to do here
|
||||
}
|
||||
|
||||
public function loadProviders()
|
||||
{
|
||||
$this->controllerProviders = [
|
||||
Admin\Collection::class => [],
|
||||
Admin\ConnectedUsers::class => [],
|
||||
Admin\Dashboard::class => [],
|
||||
Admin\Databox::class => [],
|
||||
Admin\Databoxes::class => [],
|
||||
Admin\Feeds::class => [],
|
||||
Admin\Fields::class => [],
|
||||
Admin\Plugins::class => [],
|
||||
Admin\Root::class => [],
|
||||
Admin\SearchEngine::class => [],
|
||||
Admin\Setup::class => [],
|
||||
Admin\Subdefs::class => [],
|
||||
Admin\TaskManager::class => [],
|
||||
Admin\Users::class => [],
|
||||
Client\Root::class => [],
|
||||
Datafiles::class => [],
|
||||
Lightbox::class => [],
|
||||
MediaAccessor::class => [],
|
||||
Minifier::class => [],
|
||||
Permalink::class => [],
|
||||
Prod\BasketProvider::class => [],
|
||||
Prod\Bridge::class => [],
|
||||
Prod\DoDownload::class => [],
|
||||
Prod\Download::class => [],
|
||||
Prod\Edit::class => [],
|
||||
Prod\Export::class => [],
|
||||
Prod\Feed::class => [],
|
||||
Prod\Language::class => [],
|
||||
Prod\Lazaret::class => [],
|
||||
Prod\MoveCollection::class => [],
|
||||
Prod\Order::class => [],
|
||||
Prod\Printer::class => [],
|
||||
Prod\Property::class => [],
|
||||
Prod\Push::class => [],
|
||||
Prod\Query::class => [],
|
||||
Prod\Record::class => [],
|
||||
Prod\Root::class => [],
|
||||
Prod\Share::class => [],
|
||||
Prod\Story::class => [],
|
||||
Prod\Tools::class => [],
|
||||
Prod\Tooltip::class => [],
|
||||
Prod\TOU::class => [],
|
||||
Prod\Upload::class => [],
|
||||
Prod\UsrLists::class => [],
|
||||
Prod\WorkZone::class => [],
|
||||
Report\Activity::class => [],
|
||||
Report\Information::class => [],
|
||||
Report\Root::class => [],
|
||||
Root\Account::class => [],
|
||||
Root\Developers::class => [],
|
||||
Root\Login::class => [],
|
||||
Root\Root::class => [],
|
||||
Root\RSSFeeds::class => [],
|
||||
Root\Session::class => [],
|
||||
Setup::class => [],
|
||||
Thesaurus\Thesaurus::class => [],
|
||||
Thesaurus\Xmlhttp::class => [],
|
||||
User\Notifications::class => [],
|
||||
User\Preferences::class => [],
|
||||
EmbedServiceProvider::class => [],
|
||||
];
|
||||
}
|
||||
}
|
@@ -24,9 +24,15 @@ class Permalink implements ControllerProviderInterface, ServiceProviderInterface
|
||||
public function register(Application $app)
|
||||
{
|
||||
$app['controller.permalink'] = $app->share(function (PhraseaApplication $app) {
|
||||
return (new PermalinkController($app, $app->getApplicationBox(), $app['acl'], $app->getAuthenticator(), $app['alchemy_embed.service.media']))
|
||||
return (new PermalinkController(
|
||||
$app,
|
||||
$app['acl'],
|
||||
$app->getAuthenticator(),
|
||||
$app['alchemy_embed.service.media']
|
||||
))
|
||||
->setDataboxLoggerLocator($app['phraseanet.logger'])
|
||||
->setDelivererLocator(new LazyLocator($app, 'phraseanet.file-serve'))
|
||||
->setApplicationBox($app['phraseanet.appbox'])
|
||||
;
|
||||
});
|
||||
}
|
||||
|
@@ -1,9 +1,8 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
/**
|
||||
* This file is part of Phraseanet
|
||||
*
|
||||
* (c) 2005-2014 Alchemy
|
||||
* (c) 2005-2016 Alchemy
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
@@ -11,37 +10,63 @@
|
||||
|
||||
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
|
||||
{
|
||||
private $conf;
|
||||
private $appbox;
|
||||
private $logger;
|
||||
private $cache;
|
||||
/**
|
||||
* @var PropertyAccess
|
||||
*/
|
||||
private $propertyAccess;
|
||||
|
||||
public function __construct(Cache $cache, PropertyAccess $conf, \appbox $appbox, LoggerInterface $logger)
|
||||
/**
|
||||
* @var \appbox
|
||||
*/
|
||||
private $appbox;
|
||||
|
||||
/**
|
||||
* @var LoggerInterface
|
||||
*/
|
||||
private $logger;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
private $loaded = false;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
private $restricted = false;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $availableDataboxes = [];
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $availableCollections = [];
|
||||
|
||||
public function __construct(PropertyAccess $propertyAccess, \appbox $appbox, LoggerInterface $logger)
|
||||
{
|
||||
$this->conf = $conf;
|
||||
$this->propertyAccess = $propertyAccess;
|
||||
$this->appbox = $appbox;
|
||||
$this->logger = $logger;
|
||||
$this->cache = $cache;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if a configuration is set.
|
||||
*
|
||||
* @return Boolean
|
||||
* @return bool
|
||||
*/
|
||||
public function isRestricted()
|
||||
{
|
||||
$this->load();
|
||||
|
||||
return $this->cache->fetch('restricted');
|
||||
return $this->restricted;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -49,7 +74,7 @@ class AccessRestriction
|
||||
*
|
||||
* @param \databox $databox
|
||||
*
|
||||
* @return Boolean
|
||||
* @return bool
|
||||
*/
|
||||
public function isDataboxAvailable(\databox $databox)
|
||||
{
|
||||
@@ -57,7 +82,7 @@ class AccessRestriction
|
||||
return true;
|
||||
}
|
||||
|
||||
return in_array($databox->get_sbas_id(), $this->cache->fetch('available_databoxes'), true);
|
||||
return in_array($databox->get_sbas_id(), $this->availableDataboxes, true);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -72,7 +97,7 @@ class AccessRestriction
|
||||
return $databoxes;
|
||||
}
|
||||
|
||||
$available = array_flip($this->cache->fetch('available_databoxes'));
|
||||
$available = array_flip($this->availableDataboxes);
|
||||
|
||||
return array_filter($databoxes, function (\databox $databox) use ($available) {
|
||||
return isset($available[$databox->get_sbas_id()]);
|
||||
@@ -84,7 +109,7 @@ class AccessRestriction
|
||||
*
|
||||
* @param \collection $collection
|
||||
*
|
||||
* @return Boolean
|
||||
* @return bool
|
||||
*/
|
||||
public function isCollectionAvailable(\collection $collection)
|
||||
{
|
||||
@@ -92,30 +117,31 @@ class AccessRestriction
|
||||
return true;
|
||||
}
|
||||
|
||||
$availableCollections = $this->cache->fetch('available_collections_'.$collection->get_databox()->get_sbas_id()) ?: [];
|
||||
$availableCollections = isset($this->availableCollections[$collection->get_sbas_id()])
|
||||
? $this->availableCollections[$collection->get_sbas_id()] : [];
|
||||
|
||||
return in_array($collection->get_base_id(), $availableCollections, true);
|
||||
}
|
||||
|
||||
private function load()
|
||||
{
|
||||
if ($this->cache->fetch('loaded')) {
|
||||
if ($this->loaded) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->cache->save('loaded', true);
|
||||
$this->loaded = true;
|
||||
|
||||
$allowedDataboxIds = array_map(function ($dbConf) {
|
||||
return $dbConf['id'];
|
||||
}, $this->conf->get('databoxes', []));
|
||||
}, $this->propertyAccess->get('databoxes', []));
|
||||
|
||||
if (count($allowedDataboxIds) === 0) {
|
||||
$this->cache->save('restricted', false);
|
||||
$this->restricted = false;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$this->cache->save('restricted', true);
|
||||
$this->restricted = true;
|
||||
|
||||
$databoxIds = array_map(function (\databox $databox) { return $databox->get_sbas_id(); }, $this->appbox->get_databoxes());
|
||||
$errors = array_diff($allowedDataboxIds, $databoxIds);
|
||||
@@ -124,18 +150,15 @@ class AccessRestriction
|
||||
$this->logger->error(sprintf('Misconfiguration for allowed databoxes : ids %s do not exist', implode(', ', $errors)));
|
||||
}
|
||||
|
||||
$allowedDataboxIds = array_intersect($allowedDataboxIds, $databoxIds);
|
||||
$this->cache->save('available_databoxes', $allowedDataboxIds);
|
||||
$this->availableDataboxes = array_intersect($allowedDataboxIds, $databoxIds);
|
||||
|
||||
$this->loadCollections();
|
||||
}
|
||||
|
||||
private function loadCollections()
|
||||
{
|
||||
$allowedDataboxIds = $this->cache->fetch('available_databoxes');
|
||||
|
||||
foreach ($this->conf->get('databoxes') as $databox) {
|
||||
if (!in_array($databox['id'], $allowedDataboxIds, true)) {
|
||||
foreach ($this->propertyAccess->get('databoxes') as $databox) {
|
||||
if (!in_array($databox['id'], $this->availableDataboxes, true)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -148,9 +171,7 @@ class AccessRestriction
|
||||
$this->logger->error(sprintf('Misconfiguration for allowed collections : ids %s do not exist', implode(', ', $errors)));
|
||||
}
|
||||
|
||||
$collections = array_intersect($collections, $availableBaseIds);
|
||||
|
||||
$this->cache->save('available_collections_'.$databox['id'], $collections);
|
||||
$this->availableCollections[$databox['id']] = array_intersect($collections, $availableBaseIds);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -33,7 +33,7 @@ class DisplaySettingService
|
||||
'warning_on_delete_story' => 'true',
|
||||
'client_basket_status' => '1',
|
||||
'css' => '000000',
|
||||
'start_page_query' => 'last',
|
||||
'start_page_query' => '',
|
||||
'start_page' => 'QUERY',
|
||||
'rollover_thumbnail' => 'caption',
|
||||
'technical_display' => '1',
|
||||
|
@@ -0,0 +1,120 @@
|
||||
<?php
|
||||
|
||||
namespace Alchemy\Phrasea\Core\Event\Subscriber;
|
||||
|
||||
use Alchemy\Phrasea\Cache\Cache;
|
||||
use Alchemy\Phrasea\Core\Profiler\TraceableCache;
|
||||
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
|
||||
use Symfony\Component\HttpKernel\KernelEvents;
|
||||
|
||||
class CacheStatisticsSubscriber implements EventSubscriberInterface
|
||||
{
|
||||
/**
|
||||
* @var Cache
|
||||
*/
|
||||
private $cache;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $cacheType = '';
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $stats = [];
|
||||
|
||||
/**
|
||||
* @param Cache $cache
|
||||
*/
|
||||
public function __construct(Cache $cache)
|
||||
{
|
||||
$this->cache = $cache;
|
||||
$this->cacheType = $cache->getName();
|
||||
}
|
||||
|
||||
public function getCacheNamespace()
|
||||
{
|
||||
if ($this->cache instanceof TraceableCache) {
|
||||
return $this->cache->getNamespace();
|
||||
}
|
||||
|
||||
return '[ root ]';
|
||||
}
|
||||
|
||||
public function getCallSummary()
|
||||
{
|
||||
if ($this->cache instanceof TraceableCache) {
|
||||
return $this->cache->getSummary();
|
||||
}
|
||||
|
||||
return [
|
||||
'calls' => 0,
|
||||
'hits' => 0,
|
||||
'misses' => 0,
|
||||
'calls_by_type' => [],
|
||||
'calls_by_key' => []
|
||||
];
|
||||
}
|
||||
|
||||
public function getCalls()
|
||||
{
|
||||
if ($this->cache instanceof TraceableCache) {
|
||||
return $this->cache->getCalls();
|
||||
}
|
||||
|
||||
return [];
|
||||
}
|
||||
|
||||
public function getTimeSpent()
|
||||
{
|
||||
if ($this->cache instanceof TraceableCache) {
|
||||
return $this->cache->getTotalTime();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
public function getCacheType()
|
||||
{
|
||||
return $this->cacheType;
|
||||
}
|
||||
|
||||
public function getInitialStats()
|
||||
{
|
||||
return $this->stats;
|
||||
}
|
||||
|
||||
public function getCurrentStats()
|
||||
{
|
||||
return $this->cache->getStats();
|
||||
}
|
||||
|
||||
public function onKernelRequest()
|
||||
{
|
||||
$this->stats = $this->cache->getStats();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array of event names this subscriber wants to listen to.
|
||||
*
|
||||
* The array keys are event names and the value can be:
|
||||
*
|
||||
* * The method name to call (priority defaults to 0)
|
||||
* * An array composed of the method name to call and the priority
|
||||
* * An array of arrays composed of the method names to call and respective
|
||||
* priorities, or 0 if unset
|
||||
*
|
||||
* For instance:
|
||||
*
|
||||
* * array('eventName' => 'methodName')
|
||||
* * array('eventName' => array('methodName', $priority))
|
||||
* * array('eventName' => array(array('methodName1', $priority), array('methodName2'))
|
||||
*
|
||||
* @return array The event names to listen to
|
||||
*/
|
||||
public static function getSubscribedEvents()
|
||||
{
|
||||
return [ KernelEvents::REQUEST => [ 'onKernelRequest', 2048 ] ];
|
||||
}
|
||||
}
|
@@ -37,10 +37,6 @@ class DebuggerSubscriber implements EventSubscriberInterface
|
||||
|
||||
public function checkIp(GetResponseEvent $event)
|
||||
{
|
||||
if (Application::ENV_DEV !== $this->app->getEnvironment()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ($this->app['configuration.store']->isSetup() && $this->app['conf']->has(['debugger', 'allowed-ips'])) {
|
||||
$allowedIps = $this->app['conf']->get(['debugger', 'allowed-ips']);
|
||||
$allowedIps = is_array($allowedIps) ? $allowedIps : [$allowedIps];
|
||||
|
@@ -1,9 +1,8 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Phraseanet
|
||||
*
|
||||
* (c) 2005-2014 Alchemy
|
||||
* (c) 2005-2016 Alchemy
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
@@ -107,9 +106,9 @@ class RegistrationSubscriber extends AbstractNotificationSubscriber
|
||||
{
|
||||
$body = '';
|
||||
$body .= sprintf("Login : %s\n", $registeredUser->getLogin());
|
||||
$body .= sprintf("%s : %s\n", _('admin::compte-utilisateur nom'), $registeredUser->getFirstName());
|
||||
$body .= sprintf("%s : %s\n", _('admin::compte-utilisateur prenom'), $registeredUser->getLastName());
|
||||
$body .= sprintf("%s : %s\n", _('admin::compte-utilisateur email'), $registeredUser->getEmail());
|
||||
$body .= sprintf("%s : %s\n", $this->app->trans('admin::compte-utilisateur nom'), $registeredUser->getFirstName());
|
||||
$body .= sprintf("%s : %s\n", $this->app->trans('admin::compte-utilisateur prenom'), $registeredUser->getLastName());
|
||||
$body .= sprintf("%s : %s\n", $this->app->trans('admin::compte-utilisateur email'), $registeredUser->getEmail());
|
||||
$body .= sprintf("%s/%s\n", $registeredUser->get_job(), $registeredUser->getCompany());
|
||||
|
||||
$readyToSend = false;
|
||||
|
@@ -29,7 +29,7 @@ class TrustedProxySubscriber implements EventSubscriberInterface
|
||||
public static function getSubscribedEvents()
|
||||
{
|
||||
return [
|
||||
KernelEvents::REQUEST => ['setProxyConf', 0],
|
||||
KernelEvents::REQUEST => ['setProxyConf', 1024],
|
||||
];
|
||||
}
|
||||
|
||||
|
102
lib/Alchemy/Phrasea/Core/MetaProvider/DatabaseMetaProvider.php
Normal file
102
lib/Alchemy/Phrasea/Core/MetaProvider/DatabaseMetaProvider.php
Normal file
@@ -0,0 +1,102 @@
|
||||
<?php
|
||||
|
||||
namespace Alchemy\Phrasea\Core\MetaProvider;
|
||||
|
||||
use Alchemy\Phrasea\Application as PhraseaApplication;
|
||||
use Alchemy\Phrasea\Cache\Manager;
|
||||
use Alchemy\Phrasea\Core\Provider\ORMServiceProvider;
|
||||
use Dflydev\Silex\Provider\DoctrineOrm\DoctrineOrmServiceProvider;
|
||||
use Doctrine\DBAL\Events;
|
||||
use Doctrine\ORM\Configuration;
|
||||
use Gedmo\DoctrineExtensions as GedmoExtension;
|
||||
use Silex\Application;
|
||||
use Silex\Provider\DoctrineServiceProvider;
|
||||
use Silex\ServiceProviderInterface;
|
||||
|
||||
class DatabaseMetaProvider implements ServiceProviderInterface
|
||||
{
|
||||
|
||||
public function register(Application $app)
|
||||
{
|
||||
$app->register(new DoctrineServiceProvider());
|
||||
$this->setupDBAL($app);
|
||||
$app->register(new DoctrineOrmServiceProvider());
|
||||
$this->setupOrms($app);
|
||||
$app->register(new ORMServiceProvider());
|
||||
}
|
||||
|
||||
private function setupDBAL(PhraseaApplication $app)
|
||||
{
|
||||
$app['dbs.config'] = $app->share($app->extend('dbs.config', function ($configs, $app) {
|
||||
if (! $app->isDebug()) {
|
||||
return $configs;
|
||||
}
|
||||
|
||||
foreach($configs->keys() as $service) {
|
||||
$app['dbal.config.register.loggers']($configs[$service]);
|
||||
}
|
||||
|
||||
return $configs;
|
||||
}));
|
||||
|
||||
$app['dbs.event_manager'] = $app->share($app->extend('dbs.event_manager', function ($eventManagers, $app) {
|
||||
foreach ($eventManagers->keys() as $name) {
|
||||
/** @var EventManager $eventManager */
|
||||
$eventManager = $eventManagers[$name];
|
||||
$app['dbal.evm.register.listeners']($eventManager);
|
||||
|
||||
$eventManager->addEventListener(Events::postConnect, $app);
|
||||
}
|
||||
|
||||
return $eventManagers;
|
||||
}));
|
||||
}
|
||||
|
||||
private function setupOrms(PhraseaApplication $app)
|
||||
{
|
||||
// Override "orm.cache.configurer" service provided for benefiting
|
||||
// of "phraseanet.cache-service"
|
||||
$app['orm.cache.configurer'] = $app->protect(function($name, Configuration $config, $options) use ($app) {
|
||||
/** @var Manager $service */
|
||||
$service = $app['phraseanet.cache-service'];
|
||||
|
||||
$config->setMetadataCacheImpl(
|
||||
$service->factory('ORM_metadata', $app['orm.cache.driver'], $app['orm.cache.options'])
|
||||
);
|
||||
$config->setQueryCacheImpl(
|
||||
$service->factory('ORM_query', $app['orm.cache.driver'], $app['orm.cache.options'])
|
||||
);
|
||||
$config->setResultCacheImpl(
|
||||
$service->factory('ORM_result', $app['orm.cache.driver'], $app['orm.cache.options'])
|
||||
);
|
||||
$config->setHydrationCacheImpl(
|
||||
$service->factory('ORM_hydration', $app['orm.cache.driver'], $app['orm.cache.options'])
|
||||
);
|
||||
});
|
||||
|
||||
$app['orm.proxies_dir'] = $app['root.path'].'/resources/proxies';
|
||||
$app['orm.auto_generate_proxies'] = $app['debug'];
|
||||
$app['orm.proxies_namespace'] = 'Alchemy\Phrasea\Model\Proxies';
|
||||
|
||||
$app['orm.ems'] = $app->share($app->extend('orm.ems', function (\Pimple $ems, $app) {
|
||||
GedmoExtension::registerAnnotations();
|
||||
|
||||
foreach ($ems->keys() as $key) {
|
||||
$app['orm.annotation.register']($key);
|
||||
$connection = $ems[$key]->getConnection();
|
||||
|
||||
$app['connection.pool.manager']->add($connection);
|
||||
|
||||
$types = $app['orm.ems.options'][$key]['types'];
|
||||
$app['dbal.type.register']($connection, $types);
|
||||
}
|
||||
|
||||
return $ems;
|
||||
}));
|
||||
}
|
||||
|
||||
public function boot(Application $app)
|
||||
{
|
||||
// no-op
|
||||
}
|
||||
}
|
107
lib/Alchemy/Phrasea/Core/MetaProvider/HttpStackMetaProvider.php
Normal file
107
lib/Alchemy/Phrasea/Core/MetaProvider/HttpStackMetaProvider.php
Normal file
@@ -0,0 +1,107 @@
|
||||
<?php
|
||||
|
||||
namespace Alchemy\Phrasea\Core\MetaProvider;
|
||||
|
||||
use Alchemy\Cors\Options\DefaultProvider;
|
||||
use Alchemy\CorsProvider\CorsServiceProvider;
|
||||
use Alchemy\Phrasea\Application as PhraseaApplication;
|
||||
use Alchemy\Phrasea\ControllerProvider\ControllerProviderServiceProvider;
|
||||
use Alchemy\Phrasea\Core\Provider\ContentNegotiationServiceProvider;
|
||||
use Alchemy\Phrasea\Core\Provider\SessionHandlerServiceProvider;
|
||||
use Silex\Application;
|
||||
use Silex\Provider\HttpFragmentServiceProvider;
|
||||
use Silex\Provider\SessionServiceProvider;
|
||||
use Silex\Provider\UrlGeneratorServiceProvider;
|
||||
use Silex\ServiceProviderInterface;
|
||||
use Symfony\Component\HttpFoundation\Session\Storage\Handler\NullSessionHandler;
|
||||
use Symfony\Component\HttpFoundation\Session\Storage\MockArraySessionStorage;
|
||||
use Symfony\Component\Routing\RequestContext;
|
||||
|
||||
class HttpStackMetaProvider implements ServiceProviderInterface
|
||||
{
|
||||
|
||||
public function register(Application $app)
|
||||
{
|
||||
if (! $app instanceof PhraseaApplication) {
|
||||
throw new \LogicException('Expected an instance Alchemy\Phrasea\Application');
|
||||
}
|
||||
|
||||
$app->register(new HttpFragmentServiceProvider());
|
||||
$app->register(new UrlGeneratorServiceProvider());
|
||||
|
||||
$this->setupRequestContext($app);
|
||||
|
||||
$app->register(new SessionHandlerServiceProvider());
|
||||
$app->register(new SessionServiceProvider(), [
|
||||
'session.test' => $app->getEnvironment() === PhraseaApplication::ENV_TEST,
|
||||
'session.storage.options' => ['cookie_lifetime' => 0]
|
||||
]);
|
||||
|
||||
$app['session.storage.test'] = $app->share(function () {
|
||||
return new MockArraySessionStorage();
|
||||
});
|
||||
|
||||
$app['session.storage.handler'] = $app->share(function (Application $app) {
|
||||
if (!$app['phraseanet.configuration-tester']->isInstalled()) {
|
||||
return new NullSessionHandler();
|
||||
}
|
||||
return $app['session.storage.handler.factory']->create($app['conf']);
|
||||
});
|
||||
|
||||
$app->register(new ControllerProviderServiceProvider());
|
||||
|
||||
$this->registerCors($app);
|
||||
}
|
||||
|
||||
public function setupRequestContext(Application $app)
|
||||
{
|
||||
$app['request_context'] = $app->share($app->extend('request_context', function (RequestContext $context, Application $app) {
|
||||
if ($app['configuration.store']->isSetup()) {
|
||||
$data = parse_url($app['conf']->get('servername'));
|
||||
|
||||
if (isset($data['scheme'])) {
|
||||
$context->setScheme($data['scheme']);
|
||||
}
|
||||
if (isset($data['host'])) {
|
||||
$context->setHost($data['host']);
|
||||
}
|
||||
}
|
||||
|
||||
return $context;
|
||||
}));
|
||||
}
|
||||
|
||||
public function registerCors(Application $app)
|
||||
{
|
||||
$app->register(new ContentNegotiationServiceProvider());
|
||||
$app->register(new CorsServiceProvider(), [
|
||||
'alchemy_cors.debug' => $app['debug'],
|
||||
'alchemy_cors.cache_path' => function (Application $app) {
|
||||
return rtrim($app['cache.path'], '/\\') . '/alchemy_cors.cache.php';
|
||||
},
|
||||
]);
|
||||
|
||||
$app['phraseanet.api_cors.options_provider'] = function (Application $app) {
|
||||
$paths = [];
|
||||
|
||||
if (isset($app['phraseanet.configuration']['api_cors'])) {
|
||||
$config = $app['phraseanet.configuration']['api_cors'];
|
||||
|
||||
if (isset($config['enabled']) && $config['enabled']) {
|
||||
unset($config['enabled']);
|
||||
|
||||
$paths['/api/v\d+/'] = $config;
|
||||
}
|
||||
}
|
||||
|
||||
return new DefaultProvider($paths, []);
|
||||
};
|
||||
|
||||
$app['alchemy_cors.options_providers'][] = 'phraseanet.api_cors.options_provider';
|
||||
}
|
||||
|
||||
public function boot(Application $app)
|
||||
{
|
||||
// no-op
|
||||
}
|
||||
}
|
@@ -0,0 +1,53 @@
|
||||
<?php
|
||||
|
||||
namespace Alchemy\Phrasea\Core\MetaProvider;
|
||||
|
||||
use Alchemy\Phrasea\Core\Provider\MediaAlchemystServiceProvider as PhraseanetMediaAlchemystServiceProvider;
|
||||
use FFMpeg\FFMpegServiceProvider;
|
||||
use MediaAlchemyst\MediaAlchemystServiceProvider;
|
||||
use MediaVorus\MediaVorusServiceProvider;
|
||||
use MP4Box\MP4BoxServiceProvider;
|
||||
use Neutron\Silex\Provider\ImagineServiceProvider;
|
||||
use PHPExiftool\PHPExiftoolServiceProvider;
|
||||
use Silex\Application;
|
||||
use Silex\ServiceProviderInterface;
|
||||
|
||||
class MediaUtilitiesMetaServiceProvider implements ServiceProviderInterface
|
||||
{
|
||||
|
||||
public function register(Application $app)
|
||||
{
|
||||
$app->register(new ImagineServiceProvider());
|
||||
$app->register(new FFMpegServiceProvider());
|
||||
$app->register(new MediaAlchemystServiceProvider());
|
||||
$app->register(new PhraseanetMediaAlchemystServiceProvider());
|
||||
$app->register(new MediaVorusServiceProvider());
|
||||
$app->register(new MP4BoxServiceProvider());
|
||||
$app->register(new PHPExiftoolServiceProvider());
|
||||
|
||||
$app['imagine.factory'] = $app->share(function (Application $app) {
|
||||
if ($app['conf']->get(['registry', 'executables', 'imagine-driver']) != '') {
|
||||
return $app['conf']->get(['registry', 'executables', 'imagine-driver']);
|
||||
}
|
||||
|
||||
if (class_exists('\Gmagick')) {
|
||||
return 'gmagick';
|
||||
}
|
||||
|
||||
if (class_exists('\Imagick')) {
|
||||
return 'imagick';
|
||||
}
|
||||
|
||||
if (extension_loaded('gd')) {
|
||||
return 'gd';
|
||||
}
|
||||
|
||||
throw new \RuntimeException('No Imagine driver available');
|
||||
});
|
||||
}
|
||||
|
||||
public function boot(Application $app)
|
||||
{
|
||||
// no-op
|
||||
}
|
||||
}
|
@@ -0,0 +1,23 @@
|
||||
<?php
|
||||
|
||||
namespace Alchemy\Phrasea\Core\MetaProvider;
|
||||
|
||||
use Alchemy\Phrasea\Core\Provider\TwigServiceProvider as PhraseanetTwigServiceProvider;
|
||||
use Silex\Application;
|
||||
use Silex\Provider\TwigServiceProvider;
|
||||
use Silex\ServiceProviderInterface;
|
||||
|
||||
class TemplateEngineMetaProvider implements ServiceProviderInterface
|
||||
{
|
||||
|
||||
public function register(Application $app)
|
||||
{
|
||||
$app->register(new TwigServiceProvider());
|
||||
$app->register(new PhraseanetTwigServiceProvider());
|
||||
}
|
||||
|
||||
public function boot(Application $app)
|
||||
{
|
||||
// no-op
|
||||
}
|
||||
}
|
@@ -0,0 +1,39 @@
|
||||
<?php
|
||||
|
||||
namespace Alchemy\Phrasea\Core\MetaProvider;
|
||||
|
||||
use Alchemy\Phrasea\Core\Provider\TranslationServiceProvider;
|
||||
use Silex\Application;
|
||||
use Silex\ServiceProviderInterface;
|
||||
|
||||
class TranslationMetaProvider implements ServiceProviderInterface
|
||||
{
|
||||
|
||||
public function register(Application $app)
|
||||
{
|
||||
$app->register(new TranslationServiceProvider(), [
|
||||
'locale_fallbacks' => ['fr'],
|
||||
'translator.resources' => [
|
||||
[ 'xlf', __DIR__.'/../../../../../resources/locales/messages.fr.xlf', 'fr', 'messages' ],
|
||||
[ 'xlf', __DIR__.'/../../../../../resources/locales/validators.fr.xlf', 'fr', 'validators' ],
|
||||
[ 'xlf', __DIR__.'/../../../../../resources/locales/messages.en.xlf', 'en', 'messages' ],
|
||||
[ 'xlf', __DIR__.'/../../../../../resources/locales/validators.en.xlf', 'en', 'validators' ],
|
||||
[ 'xlf', __DIR__.'/../../../../../resources/locales/messages.de.xlf', 'de', 'messages' ],
|
||||
[ 'xlf', __DIR__.'/../../../../../resources/locales/validators.de.xlf', 'de', 'validators' ],
|
||||
[ 'xlf', __DIR__.'/../../../../../resources/locales/messages.nl.xlf', 'nl', 'messages' ],
|
||||
[ 'xlf', __DIR__.'/../../../../../resources/locales/validators.nl.xlf', 'nl', 'validators' ]
|
||||
],
|
||||
'translator.cache-options' => [
|
||||
'debug' => $app['debug'],
|
||||
'cache_dir' => $app->share(function($app) {
|
||||
return $app['cache.path'] . '/translations';
|
||||
}),
|
||||
],
|
||||
]);
|
||||
}
|
||||
|
||||
public function boot(Application $app)
|
||||
{
|
||||
// no-op
|
||||
}
|
||||
}
|
@@ -0,0 +1,53 @@
|
||||
<?php
|
||||
|
||||
namespace Alchemy\Phrasea\Core\Middleware;
|
||||
|
||||
use Assert\Assertion;
|
||||
use Silex\Application;
|
||||
use Silex\ServiceProviderInterface;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
|
||||
class SetupMiddlewareProvider implements ServiceProviderInterface
|
||||
{
|
||||
/**
|
||||
* Registers services on the given app.
|
||||
*
|
||||
* This method should only be used to configure services and parameters.
|
||||
* It should not get services.
|
||||
* @param Application $app
|
||||
*/
|
||||
public function register(Application $app)
|
||||
{
|
||||
Assertion::isInstanceOf($app, \Alchemy\Phrasea\Application::class);
|
||||
|
||||
$app['setup.validate-config'] = $app->protect(function (Request $request) use ($app) {
|
||||
if (0 === strpos($request->getPathInfo(), '/setup')) {
|
||||
if (!$app['phraseanet.configuration-tester']->isInstalled()) {
|
||||
if (!$app['phraseanet.configuration-tester']->isBlank()) {
|
||||
if ('setup_upgrade_instructions' !== $app['request']->attributes->get('_route')) {
|
||||
return $app->redirectPath('setup_upgrade_instructions');
|
||||
}
|
||||
}
|
||||
} elseif (!$app['phraseanet.configuration-tester']->isBlank()) {
|
||||
return $app->redirectPath('homepage');
|
||||
}
|
||||
} else {
|
||||
if (false === strpos($request->getPathInfo(), '/include/minify')) {
|
||||
$app['firewall']->requireSetup();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Bootstraps the application.
|
||||
*
|
||||
* This method is called after all services are registered
|
||||
* and should be used for "dynamic" configuration (whenever
|
||||
* a service must be requested).
|
||||
*/
|
||||
public function boot(Application $app)
|
||||
{
|
||||
// no-op
|
||||
}
|
||||
}
|
132
lib/Alchemy/Phrasea/Core/Profiler/CacheDataCollector.php
Normal file
132
lib/Alchemy/Phrasea/Core/Profiler/CacheDataCollector.php
Normal file
@@ -0,0 +1,132 @@
|
||||
<?php
|
||||
|
||||
namespace Alchemy\Phrasea\Core\Profiler;
|
||||
|
||||
use Alchemy\Phrasea\Core\Event\Subscriber\CacheStatisticsSubscriber;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Symfony\Component\HttpKernel\DataCollector\DataCollectorInterface;
|
||||
|
||||
class CacheDataCollector implements DataCollectorInterface
|
||||
{
|
||||
|
||||
/**
|
||||
* @var CacheStatisticsSubscriber
|
||||
*/
|
||||
private $statsListener;
|
||||
|
||||
/**
|
||||
* @var CacheProfile
|
||||
*/
|
||||
private $startProfile;
|
||||
|
||||
/**
|
||||
* @var CacheProfile
|
||||
*/
|
||||
private $endProfile;
|
||||
|
||||
/**
|
||||
* @var CacheProfileSummary
|
||||
*/
|
||||
private $summary;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $timeSpent = 0;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $calls = [];
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $callSummary;
|
||||
|
||||
/**
|
||||
* @param CacheStatisticsSubscriber $cacheStatisticsSubscriber
|
||||
*/
|
||||
public function __construct(CacheStatisticsSubscriber $cacheStatisticsSubscriber)
|
||||
{
|
||||
$this->statsListener = $cacheStatisticsSubscriber;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the name of the collector.
|
||||
*
|
||||
* @return string The collector name
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
return 'cache';
|
||||
}
|
||||
|
||||
/**
|
||||
* Collects data for the given Request and Response.
|
||||
*
|
||||
* @param Request $request A Request instance
|
||||
* @param Response $response A Response instance
|
||||
* @param \Exception $exception An Exception instance
|
||||
*/
|
||||
public function collect(Request $request, Response $response, \Exception $exception = null)
|
||||
{
|
||||
$this->startProfile = new CacheProfile($this->statsListener->getInitialStats() ?: []);
|
||||
$this->endProfile = new CacheProfile($this->statsListener->getCurrentStats() ?: []);
|
||||
|
||||
$this->timeSpent = $this->statsListener->getTimeSpent();
|
||||
$this->calls = $this->statsListener->getCalls();
|
||||
$this->callSummary = $this->statsListener->getCallSummary();
|
||||
|
||||
$this->summary = new CacheProfileSummary(
|
||||
$this->statsListener->getCacheType(),
|
||||
$this->statsListener->getCacheNamespace(),
|
||||
$this->startProfile,
|
||||
$this->endProfile,
|
||||
$this->callSummary
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return CacheProfile
|
||||
*/
|
||||
public function getInitialProfile()
|
||||
{
|
||||
return $this->startProfile;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return CacheProfile
|
||||
*/
|
||||
public function getCurrentProfile()
|
||||
{
|
||||
return $this->endProfile;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getTotalTime()
|
||||
{
|
||||
return $this->timeSpent;
|
||||
}
|
||||
|
||||
public function getCalls()
|
||||
{
|
||||
return $this->calls;
|
||||
}
|
||||
|
||||
public function getCallSummary()
|
||||
{
|
||||
return $this->callSummary;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return CacheProfileSummary
|
||||
*/
|
||||
public function getSummary()
|
||||
{
|
||||
return $this->summary;
|
||||
}
|
||||
}
|
74
lib/Alchemy/Phrasea/Core/Profiler/CacheProfile.php
Normal file
74
lib/Alchemy/Phrasea/Core/Profiler/CacheProfile.php
Normal file
@@ -0,0 +1,74 @@
|
||||
<?php
|
||||
|
||||
namespace Alchemy\Phrasea\Core\Profiler;
|
||||
|
||||
class CacheProfile
|
||||
{
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $serverStats;
|
||||
|
||||
/**
|
||||
* @param array $serverStats
|
||||
*/
|
||||
public function __construct(array $serverStats)
|
||||
{
|
||||
$this->serverStats = array_replace([
|
||||
'hits' => 0,
|
||||
'misses' => 0,
|
||||
'uptime' => 0,
|
||||
'memory_usage' => 0,
|
||||
'memory_available' => 0
|
||||
], $serverStats);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getHits()
|
||||
{
|
||||
return (int) $this->serverStats['hits'];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getMisses()
|
||||
{
|
||||
return (int) $this->serverStats['misses'];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getUptime()
|
||||
{
|
||||
return (int) $this->serverStats['uptime'];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getMemUsage()
|
||||
{
|
||||
return (int) $this->serverStats['memory_usage'];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getMemAvailable()
|
||||
{
|
||||
return (int) $this->serverStats['memory_available'];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getServerStats()
|
||||
{
|
||||
return $this->serverStats;
|
||||
}
|
||||
}
|
153
lib/Alchemy/Phrasea/Core/Profiler/CacheProfileSummary.php
Normal file
153
lib/Alchemy/Phrasea/Core/Profiler/CacheProfileSummary.php
Normal file
@@ -0,0 +1,153 @@
|
||||
<?php
|
||||
|
||||
namespace Alchemy\Phrasea\Core\Profiler;
|
||||
|
||||
class CacheProfileSummary
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $cacheType;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $cacheNamespace;
|
||||
|
||||
/**
|
||||
* @var CacheProfile
|
||||
*/
|
||||
private $initialProfile;
|
||||
|
||||
/**
|
||||
* @var CacheProfile
|
||||
*/
|
||||
private $finalProfile;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $callSummaryData;
|
||||
|
||||
/**
|
||||
* @param string $cacheType
|
||||
* @param string $namespace
|
||||
* @param CacheProfile $initialProfile
|
||||
* @param CacheProfile $finalProfile
|
||||
* @param array $callSummaryData
|
||||
*/
|
||||
public function __construct(
|
||||
$cacheType,
|
||||
$namespace,
|
||||
CacheProfile $initialProfile,
|
||||
CacheProfile $finalProfile,
|
||||
array $callSummaryData
|
||||
) {
|
||||
$this->cacheType = (string)$cacheType;
|
||||
$this->cacheNamespace = (string)$namespace;
|
||||
$this->initialProfile = $initialProfile;
|
||||
$this->finalProfile = $finalProfile;
|
||||
$this->callSummaryData = $callSummaryData;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getCacheType()
|
||||
{
|
||||
return $this->cacheType;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getNamespace()
|
||||
{
|
||||
return $this->cacheNamespace;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getHits()
|
||||
{
|
||||
if (isset($this->callSummaryData['hits'])) {
|
||||
return (int) $this->callSummaryData['hits'];
|
||||
}
|
||||
|
||||
return (int)max(0, $this->finalProfile->getHits() - $this->initialProfile->getHits());
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getMisses()
|
||||
{
|
||||
if (isset($this->callSummaryData['misses'])) {
|
||||
return (int) $this->callSummaryData['misses'];
|
||||
}
|
||||
|
||||
return (int)max(0, $this->finalProfile->getMisses() - $this->initialProfile->getMisses());
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getCalls()
|
||||
{
|
||||
if (isset($this->callSummaryData['calls'])) {
|
||||
return (int) $this->callSummaryData['calls'];
|
||||
}
|
||||
|
||||
return $this->getHits() + $this->getMisses();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return float
|
||||
*/
|
||||
public function getHitRatio()
|
||||
{
|
||||
$calls = $this->getCalls();
|
||||
|
||||
if ($calls == 0) {
|
||||
return (float)0;
|
||||
}
|
||||
|
||||
return $this->getHits() / $calls;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return float
|
||||
*/
|
||||
public function getMissRatio()
|
||||
{
|
||||
$calls = $this->getCalls();
|
||||
|
||||
if ($calls == 0) {
|
||||
return (float)0;
|
||||
}
|
||||
|
||||
return $this->getMisses() / $calls;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getMemUsageDelta()
|
||||
{
|
||||
return $this->finalProfile->getMemUsage() - $this->initialProfile->getMemUsage();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getMemAvailableDelta()
|
||||
{
|
||||
return $this->finalProfile->getMemAvailable() - $this->initialProfile->getMemAvailable();
|
||||
}
|
||||
|
||||
public function getUptimeDelta()
|
||||
{
|
||||
return $this->finalProfile->getUptime() - $this->initialProfile->getUptime();
|
||||
}
|
||||
}
|
341
lib/Alchemy/Phrasea/Core/Profiler/TraceableCache.php
Normal file
341
lib/Alchemy/Phrasea/Core/Profiler/TraceableCache.php
Normal file
@@ -0,0 +1,341 @@
|
||||
<?php
|
||||
|
||||
namespace Alchemy\Phrasea\Core\Profiler;
|
||||
|
||||
use Alchemy\Phrasea\Cache\Cache as PhraseaCache;
|
||||
use Alchemy\Phrasea\Cache\Exception;
|
||||
use Doctrine\Common\Cache\Cache;
|
||||
use Symfony\Component\Stopwatch\Stopwatch;
|
||||
|
||||
class TraceableCache implements Cache, PhraseaCache
|
||||
{
|
||||
|
||||
/**
|
||||
* @var PhraseaCache
|
||||
*/
|
||||
private $cache;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $namespace = '';
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $calls = [];
|
||||
|
||||
private $summary = [
|
||||
'calls' => 0,
|
||||
'hits' => 0,
|
||||
'misses' => 0,
|
||||
'calls_by_type' => [],
|
||||
'calls_by_key' => [],
|
||||
];
|
||||
|
||||
private $stopWatch;
|
||||
|
||||
/*s*
|
||||
* @param PhraseaCache $cache
|
||||
*/
|
||||
public function __construct(PhraseaCache $cache, Stopwatch $stopwatch = null)
|
||||
{
|
||||
$this->cache = $cache;
|
||||
$this->stopWatch = $stopwatch ?: new Stopwatch();
|
||||
}
|
||||
|
||||
private function collect($type, $id, $hit = true, $result = null)
|
||||
{
|
||||
$this->summary['calls']++;
|
||||
$this->summary['hits'] += $hit ? 1 : 0;
|
||||
$this->summary['misses'] += $hit ? 0 : 1;
|
||||
|
||||
if (! array_key_exists($type, $this->summary['calls_by_type'])) {
|
||||
$this->summary['calls_by_type'][$type] = 0;
|
||||
}
|
||||
|
||||
$this->summary['calls_by_type'][$type]++;
|
||||
|
||||
if (! array_key_exists($id, $this->summary['calls_by_key'])) {
|
||||
$this->summary['calls_by_key'][$id] = [
|
||||
'total' => 0,
|
||||
'reads'=> 0,
|
||||
'writes' => 0,
|
||||
'hits' => 0,
|
||||
'misses' => 0
|
||||
];
|
||||
}
|
||||
|
||||
if (! array_key_exists($type, $this->summary['calls_by_key'][$id])) {
|
||||
$this->summary['calls_by_key'][$id][$type] = 0;
|
||||
}
|
||||
$this->summary['calls_by_key'][$id]['hits'] += $hit ? 1 : 0;
|
||||
$this->summary['calls_by_key'][$id]['misses'] += $hit ? 0 : 1;
|
||||
|
||||
$this->summary['calls_by_key'][$id]['reads'] += ($type == 'fetch' || $type == 'contains') ? 1 : 0;
|
||||
$this->summary['calls_by_key'][$id]['writes'] += ($type == 'fetch' || $type == 'contains') ? 0 : 1;
|
||||
|
||||
$this->summary['calls_by_key'][$id]['total']++;
|
||||
|
||||
$lastCall = end($this->calls);
|
||||
$callData = [
|
||||
'type' => $type,
|
||||
'key' => $id,
|
||||
'result' => $result,
|
||||
'hit' => (bool) $hit,
|
||||
'count' => 1
|
||||
];
|
||||
|
||||
if (is_array($lastCall) && $this->compareCalls($lastCall, $callData)) {
|
||||
$lastCall['count']++;
|
||||
$callData = $lastCall;
|
||||
|
||||
array_pop($this->calls);
|
||||
}
|
||||
|
||||
$this->calls[] = $callData;
|
||||
}
|
||||
|
||||
private function compareCalls(array $previousCall, array $currentCall)
|
||||
{
|
||||
$keys = [ 'type', 'key', 'result', 'hit'];
|
||||
|
||||
foreach ($keys as $key) {
|
||||
if ($previousCall[$key] != $currentCall[$key]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getNamespace()
|
||||
{
|
||||
return $this->namespace;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getTotalTime()
|
||||
{
|
||||
return $this->stopWatch->getEvent('cache')->getDuration();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getCalls()
|
||||
{
|
||||
return $this->calls;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getSummary()
|
||||
{
|
||||
return $this->summary;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetches an entry from the cache.
|
||||
*
|
||||
* @param string $id The id of the cache entry to fetch.
|
||||
*
|
||||
* @return mixed The cached data or FALSE, if no cache entry exists for the given id.
|
||||
*/
|
||||
public function fetch($id)
|
||||
{
|
||||
try {
|
||||
$this->stopWatch->start('cache');
|
||||
$value = $this->cache->fetch($id);
|
||||
$this->stopWatch->stop('cache');
|
||||
}
|
||||
catch (\Exception $ex) {
|
||||
$value = false;
|
||||
}
|
||||
|
||||
$this->collect('fetch', $id, $value != false, $value);
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests if an entry exists in the cache.
|
||||
*
|
||||
* @param string $id The cache id of the entry to check for.
|
||||
*
|
||||
* @return bool TRUE if a cache entry exists for the given cache id, FALSE otherwise.
|
||||
*/
|
||||
public function contains($id)
|
||||
{
|
||||
$this->collect('contains', $id);
|
||||
|
||||
$this->stopWatch->start('cache');
|
||||
$result = $this->cache->contains($id);
|
||||
$this->stopWatch->stop('cache');
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Puts data into the cache.
|
||||
*
|
||||
* If a cache entry with the given id already exists, its data will be replaced.
|
||||
*
|
||||
* @param string $id The cache id.
|
||||
* @param mixed $data The cache entry/data.
|
||||
* @param int $lifeTime The lifetime in number of seconds for this cache entry.
|
||||
* If zero (the default), the entry never expires (although it may be deleted from the cache
|
||||
* to make place for other entries).
|
||||
*
|
||||
* @return bool TRUE if the entry was successfully stored in the cache, FALSE otherwise.
|
||||
*/
|
||||
public function save($id, $data, $lifeTime = 0)
|
||||
{
|
||||
$this->collect('save', $id);
|
||||
|
||||
$this->stopWatch->start('cache');
|
||||
$result = $this->cache->save($id, $data, $lifeTime);
|
||||
$this->stopWatch->stop('cache');
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes a cache entry.
|
||||
*
|
||||
* @param string $id The cache id.
|
||||
*
|
||||
* @return bool TRUE if the cache entry was successfully deleted, FALSE otherwise.
|
||||
* Deleting a non-existing entry is considered successful.
|
||||
*/
|
||||
public function delete($id)
|
||||
{
|
||||
$this->collect('delete', $id);
|
||||
|
||||
$this->stopWatch->start('cache');
|
||||
$result = $this->cache->delete($id);
|
||||
$this->stopWatch->stop('cache');
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves cached information from the data store.
|
||||
*
|
||||
* The server's statistics array has the following values:
|
||||
*
|
||||
* - <b>hits</b>
|
||||
* Number of keys that have been requested and found present.
|
||||
*
|
||||
* - <b>misses</b>
|
||||
* Number of items that have been requested and not found.
|
||||
*
|
||||
* - <b>uptime</b>
|
||||
* Time that the server is running.
|
||||
*
|
||||
* - <b>memory_usage</b>
|
||||
* Memory used by this server to store items.
|
||||
*
|
||||
* - <b>memory_available</b>
|
||||
* Memory allowed to use for storage.
|
||||
*
|
||||
* @since 2.2
|
||||
*
|
||||
* @return array|null An associative array with server's statistics if available, NULL otherwise.
|
||||
*/
|
||||
public function getStats()
|
||||
{
|
||||
$this->stopWatch->start('cache');
|
||||
$result = $this->cache->getStats();
|
||||
$this->stopWatch->stop('cache');
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the namespace
|
||||
*
|
||||
* @param string $namespace
|
||||
*/
|
||||
public function setNamespace($namespace)
|
||||
{
|
||||
$this->namespace = $namespace;
|
||||
$this->cache->setNamespace($namespace);
|
||||
}
|
||||
|
||||
/**
|
||||
* Flushes all data contained in the adapter
|
||||
*/
|
||||
public function flushAll()
|
||||
{
|
||||
$this->collect('flush-all', null);
|
||||
$this->stopWatch->start('cache');
|
||||
$this->cache->flushAll();
|
||||
$this->stopWatch->stop('cache');
|
||||
}
|
||||
|
||||
/**
|
||||
* Name of the cache driver
|
||||
* @return string
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
return 'traceable-' . $this->cache->getName();
|
||||
}
|
||||
|
||||
/**
|
||||
* Tell whether the caching system use a server or not
|
||||
* @return boolean
|
||||
*/
|
||||
public function isServer()
|
||||
{
|
||||
return $this->cache->isServer();
|
||||
}
|
||||
|
||||
/**
|
||||
* Tell if the cache system is online
|
||||
* @return boolean
|
||||
*/
|
||||
public function isOnline()
|
||||
{
|
||||
return $this->cache->isOnline();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an entry from the cache.
|
||||
*
|
||||
* @param string $key cache id The id of the cache entry to fetch.
|
||||
*
|
||||
* @return string The cached data.
|
||||
* @return FALSE, if no cache entry exists for the given id.
|
||||
*
|
||||
* @throws Exception if provided key does not exist
|
||||
*/
|
||||
public function get($key)
|
||||
{
|
||||
if ( ! $this->contains($key)) {
|
||||
throw new Exception('Unable to retrieve the value');
|
||||
}
|
||||
|
||||
return $this->fetch($key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete multi cache entries
|
||||
*
|
||||
* @param array $keys contains all keys to delete
|
||||
* @return PhraseaCache
|
||||
*/
|
||||
public function deleteMulti(array $keys)
|
||||
{
|
||||
foreach ($keys as $key) {
|
||||
$this->delete($key);
|
||||
}
|
||||
}
|
||||
}
|
@@ -70,7 +70,7 @@ class BorderManagerServiceProvider implements ServiceProviderInterface
|
||||
$collections = [];
|
||||
foreach ($checker['collections'] as $base_id) {
|
||||
try {
|
||||
$collections[] = \collection::get_from_base_id($app, $base_id);
|
||||
$collections[] = \collection::getByBaseId($app, $base_id);
|
||||
} catch (\Exception $e) {
|
||||
throw new \InvalidArgumentException('Invalid collection option');
|
||||
}
|
||||
|
@@ -69,7 +69,7 @@ class ConfigurationServiceProvider implements ServiceProviderInterface
|
||||
});
|
||||
|
||||
$app['conf.restrictions'] = $app->share(function (SilexApplication $app) {
|
||||
return new AccessRestriction($app['cache'], $app['conf'], $app->getApplicationBox(), $app['monolog']);
|
||||
return new AccessRestriction($app['conf'], $app->getApplicationBox(), $app['monolog']);
|
||||
});
|
||||
}
|
||||
|
||||
|
@@ -15,6 +15,7 @@ use Alchemy\Phrasea\Setup\ConfigurationTester;
|
||||
use Alchemy\Phrasea\Application;
|
||||
use Alchemy\Phrasea\Setup\Version\PreSchemaUpgrade\PreSchemaUpgradeCollection;
|
||||
use Alchemy\Phrasea\Setup\Version\PreSchemaUpgrade\Upgrade39Feeds;
|
||||
use Alchemy\Phrasea\Setup\Version\PreSchemaUpgrade\Upgrade39Sessions;
|
||||
use Alchemy\Phrasea\Setup\Version\PreSchemaUpgrade\Upgrade39Tokens;
|
||||
use Alchemy\Phrasea\Setup\Version\PreSchemaUpgrade\Upgrade39Users;
|
||||
use Silex\Application as SilexApplication;
|
||||
@@ -30,7 +31,7 @@ class ConfigurationTesterServiceProvider implements ServiceProviderInterface
|
||||
});
|
||||
|
||||
$app['phraseanet.pre-schema-upgrader.upgrades'] = $app->share(function () {
|
||||
return [new Upgrade39Feeds(), new Upgrade39Users(), new Upgrade39Tokens()];
|
||||
return [new Upgrade39Feeds(), new Upgrade39Users(), new Upgrade39Tokens(), new Upgrade39Sessions()];
|
||||
});
|
||||
|
||||
$app['phraseanet.pre-schema-upgrader'] = $app->share(function (Application $app) {
|
||||
|
@@ -14,12 +14,11 @@ namespace Alchemy\Phrasea\Core\Provider;
|
||||
use Alchemy\Phrasea\Core\Event\Subscriber\XSendFileSubscriber;
|
||||
use Alchemy\Phrasea\Http\H264PseudoStreaming\H264Factory;
|
||||
use Alchemy\Phrasea\Http\ServeFileResponseFactory;
|
||||
use Alchemy\Phrasea\Http\StaticFile\StaticFileFactory;
|
||||
use Alchemy\Phrasea\Http\StaticFile\StaticMode;
|
||||
use Alchemy\Phrasea\Http\StaticFile\Symlink\SymLinker;
|
||||
use Alchemy\Phrasea\Http\XSendFile\XSendFileFactory;
|
||||
use Silex\Application;
|
||||
use Silex\ServiceProviderInterface;
|
||||
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
|
||||
|
||||
class FileServeServiceProvider implements ServiceProviderInterface
|
||||
{
|
||||
@@ -41,11 +40,11 @@ class FileServeServiceProvider implements ServiceProviderInterface
|
||||
});
|
||||
|
||||
$app['phraseanet.static-file'] = $app->share(function (Application $app) {
|
||||
return new StaticMode(SymLinker::create($app));
|
||||
return new StaticMode($app['phraseanet.thumb-symlinker']);
|
||||
});
|
||||
|
||||
$app['phraseanet.file-serve'] = $app->share(function (Application $app) {
|
||||
return ServeFileResponseFactory::create($app);
|
||||
return new ServeFileResponseFactory($app['unicode']);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -55,7 +54,7 @@ class FileServeServiceProvider implements ServiceProviderInterface
|
||||
public function boot(Application $app)
|
||||
{
|
||||
$app['dispatcher'] = $app->share(
|
||||
$app->extend('dispatcher', function ($dispatcher, Application $app) {
|
||||
$app->extend('dispatcher', function (EventDispatcherInterface $dispatcher, Application $app) {
|
||||
$dispatcher->addSubscriber(new XSendFileSubscriber($app));
|
||||
|
||||
return $dispatcher;
|
||||
|
@@ -0,0 +1,53 @@
|
||||
<?php
|
||||
|
||||
namespace Alchemy\Phrasea\Core\Provider;
|
||||
|
||||
use Silex\Application;
|
||||
use Silex\ServiceProviderInterface;
|
||||
|
||||
class MediaAlchemystServiceProvider implements ServiceProviderInterface
|
||||
{
|
||||
|
||||
public function register(Application $app)
|
||||
{
|
||||
$app['media-alchemyst.configuration'] = $app->share(function (Application $app) {
|
||||
$configuration = [];
|
||||
$parameters = [
|
||||
'swftools.pdf2swf.binaries' => 'pdf2swf_binary',
|
||||
'swftools.swfrender.binaries' => 'swf_render_binary',
|
||||
'swftools.swfextract.binaries' => 'swf_extract_binary',
|
||||
'unoconv.binaries' => 'unoconv_binary',
|
||||
'mp4box.binaries' => 'mp4box_binary',
|
||||
'gs.binaries' => 'ghostscript_binary',
|
||||
'ffmpeg.ffmpeg.binaries' => 'ffmpeg_binary',
|
||||
'ffmpeg.ffprobe.binaries' => 'ffprobe_binary',
|
||||
'ffmpeg.ffmpeg.timeout' => 'ffmpeg_timeout',
|
||||
'ffmpeg.ffprobe.timeout' => 'ffprobe_timeout',
|
||||
'gs.timeout' => 'gs_timeout',
|
||||
'mp4box.timeout' => 'mp4box_timeout',
|
||||
'swftools.timeout' => 'swftools_timeout',
|
||||
'unoconv.timeout' => 'unoconv_timeout',
|
||||
];
|
||||
|
||||
foreach ($parameters as $parameter => $key) {
|
||||
if ($app['conf']->has(['main', 'binaries', $key])) {
|
||||
$configuration[$parameter] = $app['conf']->get(['main', 'binaries', $key]);
|
||||
}
|
||||
}
|
||||
|
||||
$configuration['ffmpeg.threads'] = $app['conf']->get(['registry', 'executables', 'ffmpeg-threads']) ?: null;
|
||||
$configuration['imagine.driver'] = $app['conf']->get(['registry', 'executables', 'imagine-driver']) ?: null;
|
||||
|
||||
return $configuration;
|
||||
});
|
||||
|
||||
$app['media-alchemyst.logger'] = $app->share(function (Application $app) {
|
||||
return $app['monolog'];
|
||||
});
|
||||
}
|
||||
|
||||
public function boot(Application $app)
|
||||
{
|
||||
// no-op
|
||||
}
|
||||
}
|
@@ -41,11 +41,15 @@ class PhraseanetServiceProvider implements ServiceProviderInterface
|
||||
});
|
||||
|
||||
$app['phraseanet.thumb-symlinker'] = $app->share(function (SilexApplication $app) {
|
||||
return SymLinker::create($app);
|
||||
return new SymLinker(
|
||||
$app['phraseanet.thumb-symlinker-encoder'],
|
||||
$app['filesystem'],
|
||||
$app['thumbnail.path']
|
||||
);
|
||||
});
|
||||
|
||||
$app['phraseanet.thumb-symlinker-encoder'] = $app->share(function (SilexApplication $app) {
|
||||
return SymLinkerEncoder::create($app);
|
||||
return new SymLinkerEncoder($app['phraseanet.configuration']['main']['key']);
|
||||
});
|
||||
|
||||
$app['acl'] = $app->share(function (SilexApplication $app) {
|
||||
|
@@ -1,9 +1,8 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
/**
|
||||
* This file is part of Phraseanet
|
||||
*
|
||||
* (c) 2005-2014 Alchemy
|
||||
* (c) 2005-2016 Alchemy
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
@@ -12,12 +11,22 @@
|
||||
namespace Alchemy\Phrasea\Core\Provider;
|
||||
|
||||
use Alchemy\Phrasea\Application as PhraseaApplication;
|
||||
use Alchemy\Phrasea\Collection\CollectionFactory;
|
||||
use Alchemy\Phrasea\Collection\CollectionRepositoryRegistry;
|
||||
use Alchemy\Phrasea\Collection\Factory\ArrayCachedCollectionRepositoryFactory;
|
||||
use Alchemy\Phrasea\Collection\Factory\CachedCollectionRepositoryFactory;
|
||||
use Alchemy\Phrasea\Collection\Factory\DbalCollectionRepositoryFactory;
|
||||
use Alchemy\Phrasea\Collection\Reference\ArrayCacheCollectionReferenceRepository;
|
||||
use Alchemy\Phrasea\Collection\Reference\DbalCollectionReferenceRepository;
|
||||
use Alchemy\Phrasea\Databox\ArrayCacheDataboxRepository;
|
||||
use Alchemy\Phrasea\Databox\CachingDataboxRepositoryDecorator;
|
||||
use Alchemy\Phrasea\Databox\DataboxConnectionProvider;
|
||||
use Alchemy\Phrasea\Databox\DataboxFactory;
|
||||
use Alchemy\Phrasea\Databox\DbalDataboxRepository;
|
||||
use Alchemy\Phrasea\Databox\Field\DataboxFieldFactory;
|
||||
use Alchemy\Phrasea\Databox\Field\DbalDataboxFieldRepository;
|
||||
use Alchemy\Phrasea\Databox\Record\LegacyRecordRepository;
|
||||
use Alchemy\Phrasea\Model\Repositories\BasketRepository;
|
||||
use Silex\Application;
|
||||
use Silex\ServiceProviderInterface;
|
||||
|
||||
@@ -45,7 +54,11 @@ class RepositoriesServiceProvider implements ServiceProviderInterface
|
||||
return $app['orm.em']->getRepository('Phraseanet:Registration');
|
||||
});
|
||||
$app['repo.baskets'] = $app->share(function (PhraseaApplication $app) {
|
||||
return $app['orm.em']->getRepository('Phraseanet:Basket');
|
||||
/** @var BasketRepository $repository */
|
||||
$repository = $app['orm.em']->getRepository('Phraseanet:Basket');
|
||||
$repository->setTranslator($app['translator']);
|
||||
|
||||
return $repository;
|
||||
});
|
||||
$app['repo.basket-elements'] = $app->share(function (PhraseaApplication $app) {
|
||||
return $app['orm.em']->getRepository('Phraseanet:BasketElement');
|
||||
@@ -133,11 +146,21 @@ class RepositoriesServiceProvider implements ServiceProviderInterface
|
||||
});
|
||||
|
||||
$app['repo.databoxes'] = $app->share(function (PhraseaApplication $app) {
|
||||
$factory = new DataboxFactory($app);
|
||||
$appbox = $app->getApplicationBox();
|
||||
$repository = new DbalDataboxRepository($appbox->get_connection(), $factory);
|
||||
|
||||
return new CachingDataboxRepositoryDecorator($repository, $app['cache'], $appbox->get_cache_key($appbox::CACHE_LIST_BASES), $factory);
|
||||
$factory = new DataboxFactory($app);
|
||||
$repository = new CachingDataboxRepositoryDecorator(
|
||||
new DbalDataboxRepository($appbox->get_connection(), $factory),
|
||||
$app['cache'],
|
||||
$appbox->get_cache_key($appbox::CACHE_LIST_BASES),
|
||||
$factory
|
||||
);
|
||||
|
||||
$repository = new ArrayCacheDataboxRepository($repository);
|
||||
|
||||
$factory->setDataboxRepository($repository);
|
||||
|
||||
return $repository;
|
||||
});
|
||||
|
||||
$app['repo.fields.factory'] = $app->protect(function (\databox $databox) use ($app) {
|
||||
@@ -147,9 +170,37 @@ class RepositoriesServiceProvider implements ServiceProviderInterface
|
||||
$app['repo.records.factory'] = $app->protect(function (\databox $databox) use ($app) {
|
||||
return new LegacyRecordRepository($app, $databox);
|
||||
});
|
||||
|
||||
$app['repo.collection-references'] = $app->share(function (PhraseaApplication $app) {
|
||||
$repository = new DbalCollectionReferenceRepository($app->getApplicationBox()->get_connection());
|
||||
|
||||
return new ArrayCacheCollectionReferenceRepository($repository);
|
||||
});
|
||||
$app['repo.collections-registry'] = $app->share(function (PhraseaApplication $app) {
|
||||
$factory = new CollectionFactory($app);
|
||||
$connectionProvider = new DataboxConnectionProvider($app->getApplicationBox());
|
||||
|
||||
$repositoryFactory = new DbalCollectionRepositoryFactory(
|
||||
$connectionProvider,
|
||||
$factory,
|
||||
$app['repo.collection-references']
|
||||
);
|
||||
|
||||
$repositoryFactory = new CachedCollectionRepositoryFactory(
|
||||
$app,
|
||||
$repositoryFactory,
|
||||
$app['cache'],
|
||||
'phrasea.collections'
|
||||
);
|
||||
|
||||
$repositoryFactory = new ArrayCachedCollectionRepositoryFactory($repositoryFactory);
|
||||
|
||||
return new CollectionRepositoryRegistry($app, $repositoryFactory, $app['repo.collection-references']);
|
||||
});
|
||||
}
|
||||
|
||||
public function boot(Application $app)
|
||||
{
|
||||
// no-op
|
||||
}
|
||||
}
|
||||
|
@@ -21,11 +21,14 @@ class SubdefServiceProvider implements ServiceProviderInterface
|
||||
{
|
||||
public function register(SilexApplication $app)
|
||||
{
|
||||
$app['subdef.generator'] = $app->share(function (SilexApplication $app) {
|
||||
return new SubdefGenerator($app, $app['media-alchemyst'], $app['filesystem'], $app['mediavorus'], isset($app['task-manager.logger']) ? $app['task-manager.logger'] : $app['monolog']);
|
||||
$app['subdef.generator'] = $app->share(function (Application $app) {
|
||||
$generator = new SubdefGenerator($app, $app['media-alchemyst'], $app['phraseanet.filesystem'], $app['mediavorus'], isset($app['task-manager.logger']) ? $app['task-manager.logger'] : $app['monolog']);
|
||||
$generator->setDispatcher($app['dispatcher']);
|
||||
|
||||
return $generator;
|
||||
});
|
||||
$app['subdef.substituer'] = $app->share(function (SilexApplication $app) {
|
||||
return new SubdefSubstituer($app, $app['filesystem'], $app['media-alchemyst'], $app['mediavorus'], $app['dispatcher']);
|
||||
$app['subdef.substituer'] = $app->share(function (Application $app) {
|
||||
return new SubdefSubstituer($app, $app['phraseanet.filesystem'], $app['media-alchemyst'], $app['mediavorus'], $app['dispatcher']);
|
||||
});
|
||||
}
|
||||
|
||||
|
@@ -5,6 +5,7 @@ namespace Alchemy\Phrasea\Core\Provider;
|
||||
use Alchemy\Phrasea\Utilities\CachedTranslator;
|
||||
use Silex\Application;
|
||||
use Silex\ServiceProviderInterface;
|
||||
use Symfony\Component\Translation\Loader\PoFileLoader;
|
||||
use Symfony\Component\Translation\MessageSelector;
|
||||
use Symfony\Component\Translation\Loader\ArrayLoader;
|
||||
use JMS\TranslationBundle\Translation\Loader\Symfony\XliffLoader;
|
||||
@@ -36,6 +37,7 @@ class TranslationServiceProvider implements ServiceProviderInterface
|
||||
$translator->addLoader('xliff', new XliffLoader());
|
||||
// to load Phraseanet resources
|
||||
$translator->addLoader('xlf', new XliffLoader());
|
||||
$translator->addLoader('po', new PoFileLoader());
|
||||
|
||||
foreach ($app['translator.domains'] as $domain => $data) {
|
||||
foreach ($data as $locale => $messages) {
|
||||
@@ -43,6 +45,15 @@ class TranslationServiceProvider implements ServiceProviderInterface
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($app['translator.resources'] as $resource) {
|
||||
$translator->addResource(
|
||||
$resource[0],
|
||||
$resource[1],
|
||||
$resource[2],
|
||||
isset($resource[3]) ? $resource[3] : null
|
||||
);
|
||||
}
|
||||
|
||||
return $translator;
|
||||
});
|
||||
|
||||
|
159
lib/Alchemy/Phrasea/Core/Provider/TwigServiceProvider.php
Normal file
159
lib/Alchemy/Phrasea/Core/Provider/TwigServiceProvider.php
Normal file
@@ -0,0 +1,159 @@
|
||||
<?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\Core\Provider;
|
||||
|
||||
use Alchemy\Phrasea\Twig\BytesConverter;
|
||||
use Alchemy\Phrasea\Twig\Camelize;
|
||||
use Alchemy\Phrasea\Twig\Fit;
|
||||
use Alchemy\Phrasea\Twig\JSUniqueID;
|
||||
use Alchemy\Phrasea\Twig\PhraseanetExtension;
|
||||
use Silex\Application;
|
||||
use Silex\ServiceProviderInterface;
|
||||
use Symfony\Bridge\Twig\Extension\TranslationExtension;
|
||||
|
||||
class TwigServiceProvider implements ServiceProviderInterface
|
||||
{
|
||||
|
||||
/**
|
||||
* Registers services on the given app.
|
||||
*
|
||||
* This method should only be used to configure services and parameters.
|
||||
* It should not get services.
|
||||
*/
|
||||
public function register(Application $app)
|
||||
{
|
||||
$app['twig'] = $app->share($app->extend('twig', function (\Twig_Environment $twig, $app) {
|
||||
$twig->setCache($app['cache.path'] . '/twig');
|
||||
|
||||
$paths = [];
|
||||
|
||||
if (file_exists($app['plugin.path'] . '/twig-paths.php')) {
|
||||
$paths = require $app['plugin.path'] . '/twig-paths.php';
|
||||
}
|
||||
|
||||
if ($app['browser']->isTablet() || $app['browser']->isMobile()) {
|
||||
$paths[] = $app['root.path'] . '/config/templates/mobile';
|
||||
$paths[] = $app['root.path'] . '/templates/mobile';
|
||||
$paths['phraseanet'] = $app['root.path'] . '/config/templates/mobile';
|
||||
$paths['phraseanet'] = $app['root.path'] . '/templates/mobile';
|
||||
}
|
||||
|
||||
$paths[] = $app['root.path'] . '/config/templates/web';
|
||||
$paths[] = $app['root.path'] . '/templates/web';
|
||||
$paths['phraseanet'] = $app['root.path'] . '/config/templates/web';
|
||||
$paths['phraseanet'] = $app['root.path'] . '/templates/web';
|
||||
|
||||
foreach ($paths as $namespace => $path) {
|
||||
if (!is_int($namespace)) {
|
||||
$app['twig.loader.filesystem']->addPath($path, $namespace);
|
||||
} else {
|
||||
$app['twig.loader.filesystem']->addPath($path);
|
||||
}
|
||||
}
|
||||
|
||||
$twig->addGlobal('current_date', new \DateTime());
|
||||
|
||||
$this->registerExtensions($twig, $app);
|
||||
$this->registerFilters($twig, $app);
|
||||
|
||||
return $twig;
|
||||
}));
|
||||
}
|
||||
|
||||
private function registerExtensions(\Twig_Environment $twig, Application $app)
|
||||
{
|
||||
$twig->addExtension(new \Twig_Extension_Core());
|
||||
$twig->addExtension(new \Twig_Extension_Optimizer());
|
||||
$twig->addExtension(new \Twig_Extension_Escaper());
|
||||
if ($app['debug']) {
|
||||
$twig->addExtension(new \Twig_Extension_Debug());
|
||||
}
|
||||
|
||||
// add filter trans
|
||||
$twig->addExtension(new TranslationExtension($app['translator']));
|
||||
// add filter localizeddate
|
||||
$twig->addExtension(new \Twig_Extensions_Extension_Intl());
|
||||
// add filters truncate, wordwrap, nl2br
|
||||
$twig->addExtension(new \Twig_Extensions_Extension_Text());
|
||||
$twig->addExtension(new JSUniqueID());
|
||||
$twig->addExtension(new Fit());
|
||||
$twig->addExtension(new Camelize());
|
||||
$twig->addExtension(new BytesConverter());
|
||||
$twig->addExtension(new PhraseanetExtension($app));
|
||||
}
|
||||
|
||||
private function registerFilters(\Twig_Environment $twig, Application $app)
|
||||
{
|
||||
$twig->addFilter('serialize', new \Twig_Filter_Function('serialize'));
|
||||
$twig->addFilter('stristr', new \Twig_Filter_Function('stristr'));
|
||||
$twig->addFilter('get_class', new \Twig_Filter_Function('get_class'));
|
||||
$twig->addFilter('stripdoublequotes', new \Twig_Filter_Function('stripdoublequotes'));
|
||||
$twig->addFilter('get_collection_logo', new \Twig_Filter_Function('collection::getLogo'));
|
||||
$twig->addFilter('floor', new \Twig_Filter_Function('floor'));
|
||||
$twig->addFilter('ceil', new \Twig_Filter_Function('ceil'));
|
||||
$twig->addFilter('max', new \Twig_Filter_Function('max'));
|
||||
$twig->addFilter('min', new \Twig_Filter_Function('min'));
|
||||
$twig->addFilter('bas_labels', new \Twig_Filter_Function('phrasea::bas_labels'));
|
||||
$twig->addFilter('sbas_names', new \Twig_Filter_Function('phrasea::sbas_names'));
|
||||
$twig->addFilter('sbas_labels', new \Twig_Filter_Function('phrasea::sbas_labels'));
|
||||
$twig->addFilter('sbas_from_bas', new \Twig_Filter_Function('phrasea::sbasFromBas'));
|
||||
$twig->addFilter('key_exists', new \Twig_Filter_Function('array_key_exists'));
|
||||
$twig->addFilter('round', new \Twig_Filter_Function('round'));
|
||||
$twig->addFilter('count', new \Twig_Filter_Function('count'));
|
||||
$twig->addFilter('formatOctets', new \Twig_Filter_Function('p4string::format_octets'));
|
||||
$twig->addFilter('base_from_coll', new \Twig_Filter_Function('phrasea::baseFromColl'));
|
||||
$twig->addFilter(new \Twig_SimpleFilter('escapeSimpleQuote', function ($value) {
|
||||
return str_replace("'", "\\'", $value);
|
||||
}));
|
||||
|
||||
$twig->addFilter(new \Twig_SimpleFilter('highlight', function (\Twig_Environment $twig, $string) {
|
||||
return str_replace(['[[em]]', '[[/em]]'], ['<em>', '</em>'], $string);
|
||||
}, ['needs_environment' => true, 'is_safe' => ['html']]));
|
||||
|
||||
$twig->addFilter(new \Twig_SimpleFilter('linkify', function (\Twig_Environment $twig, $string) use ($app) {
|
||||
return preg_replace(
|
||||
"(([^']{1})((https?|file):((/{2,4})|(\\{2,4}))[\w:#%/;$()~_?/\-=\\\.&]*)([^']{1}))"
|
||||
,
|
||||
'$1 $2 <a title="' . $app['translator']->trans('Open the URL in a new window') . '" class="ui-icon ui-icon-extlink" href="$2" style="display:inline;padding:2px 5px;margin:0 4px 0 2px;" target="_blank"> </a>$7'
|
||||
, $string
|
||||
);
|
||||
}, ['needs_environment' => true, 'is_safe' => ['html']]));
|
||||
|
||||
$twig->addFilter(new \Twig_SimpleFilter('bounce',
|
||||
function (\Twig_Environment $twig, $fieldValue, $fieldName, $searchRequest, $sbasId) {
|
||||
// bounce value if it is present in thesaurus as well
|
||||
return "<a class=\"bounce\" onclick=\"bounce('" . $sbasId . "','"
|
||||
. str_replace("'", "\\'", $searchRequest)
|
||||
. "', '"
|
||||
. str_replace("'", "\\'", $fieldName)
|
||||
. "');return(false);\">"
|
||||
. $fieldValue
|
||||
. "</a>";
|
||||
|
||||
}, ['needs_environment' => true, 'is_safe' => ['html']]));
|
||||
|
||||
$twig->addFilter(new \Twig_SimpleFilter('escapeDoubleQuote', function ($value) {
|
||||
return str_replace('"', '\"', $value);
|
||||
}));
|
||||
}
|
||||
|
||||
/**
|
||||
* Bootstraps the application.
|
||||
*
|
||||
* This method is called after all services are registered
|
||||
* and should be used for "dynamic" configuration (whenever
|
||||
* a service must be requested).
|
||||
*/
|
||||
public function boot(Application $app)
|
||||
{
|
||||
// no-op
|
||||
}
|
||||
}
|
133
lib/Alchemy/Phrasea/Core/Provider/WebProfilerServiceProvider.php
Normal file
133
lib/Alchemy/Phrasea/Core/Provider/WebProfilerServiceProvider.php
Normal file
@@ -0,0 +1,133 @@
|
||||
<?php
|
||||
|
||||
namespace Alchemy\Phrasea\Core\Provider;
|
||||
|
||||
use Alchemy\Phrasea\Core\Event\Subscriber\CacheStatisticsSubscriber;
|
||||
use Alchemy\Phrasea\Core\Profiler\CacheDataCollector;
|
||||
use Alchemy\Phrasea\Core\Profiler\TraceableCache;
|
||||
use Doctrine\Common\Cache\Cache;
|
||||
use Doctrine\DBAL\Connection;
|
||||
use Doctrine\DBAL\Logging\DebugStack;
|
||||
use Doctrine\DBAL\Logging\LoggerChain;
|
||||
use Silex\Application;
|
||||
use Silex\ServiceProviderInterface;
|
||||
use Sorien\DataCollector\DoctrineDataCollector;
|
||||
use Sorien\Logger\DbalLogger;
|
||||
use Symfony\Bundle\FrameworkBundle\DataCollector\AjaxDataCollector;
|
||||
use Symfony\Bundle\WebProfilerBundle\EventListener\WebDebugToolbarListener;
|
||||
|
||||
class WebProfilerServiceProvider implements ServiceProviderInterface
|
||||
{
|
||||
|
||||
/**
|
||||
* Registers services on the given app.
|
||||
*
|
||||
* This method should only be used to configure services and parameters.
|
||||
* It should not get services.
|
||||
*/
|
||||
public function register(Application $app)
|
||||
{
|
||||
// Required because the Silex provider is not up to date with Symfony Debug Toolbar
|
||||
$app['web_profiler.toolbar.listener'] = $app->share(
|
||||
$app->extend('web_profiler.toolbar.listener', function () use ($app) {
|
||||
return new WebDebugToolbarListener(
|
||||
$app['twig'],
|
||||
$app['web_profiler.debug_toolbar.intercept_redirects'],
|
||||
2,
|
||||
$app['web_profiler.debug_toolbar.position'],
|
||||
$app['url_generator']
|
||||
);
|
||||
})
|
||||
);
|
||||
|
||||
if (class_exists(AjaxDataCollector::class)) {
|
||||
$app['data_collector.templates'] = $app->share($app->extend('data_collector.templates', function (array $templates) {
|
||||
$templates[] = array('ajax', '@WebProfiler/Collector/ajax.html.twig');
|
||||
|
||||
return $templates;
|
||||
}));
|
||||
|
||||
$app['data_collectors'] = $app->share($app->extend('data_collectors', function ($collectors) use ($app) {
|
||||
$collectors['ajax'] = function () {
|
||||
return new AjaxDataCollector();
|
||||
};
|
||||
|
||||
return $collectors;
|
||||
}));
|
||||
}
|
||||
|
||||
$app['data_collectors.doctrine'] = $app->share(function ($app) {
|
||||
/** @var Connection $db */
|
||||
$db = $app['db'];
|
||||
return new DoctrineDataCollector($db);
|
||||
});
|
||||
|
||||
$app['cache'] = $app->share($app->extend('cache', function (Cache $cache, $app) {
|
||||
$namespace = $app['conf']->get(['main', 'cache', 'options', 'namespace']);
|
||||
$cache = new TraceableCache($cache);
|
||||
|
||||
$cache->setNamespace($namespace);
|
||||
|
||||
return $cache;
|
||||
}));
|
||||
|
||||
$app['data_collector.cache_subscriber'] = $app->share(function ($app) {
|
||||
return new CacheStatisticsSubscriber($app['cache']);
|
||||
});
|
||||
|
||||
$app['data_collectors'] = $app->share($app->extend('data_collectors', function ($collectors) use ($app) {
|
||||
$collectors['db'] = $app->share(function ($app) {
|
||||
/** @var DoctrineDataCollector $collector */
|
||||
$collector = $app['data_collectors.doctrine'];
|
||||
|
||||
$loggerChain = new LoggerChain();
|
||||
$logger = new DebugStack();
|
||||
|
||||
$loggerChain->addLogger($logger);
|
||||
$loggerChain->addLogger(new DbalLogger($app['logger'], $app['stopwatch']));
|
||||
|
||||
/** @var Connection $db */
|
||||
$db = $app['db'];
|
||||
$db->getConfiguration()->setSQLLogger($loggerChain);
|
||||
|
||||
$collector->addLogger($logger);
|
||||
|
||||
return $collector;
|
||||
});
|
||||
|
||||
$collectors['cache'] = $app->share(function ($app) {
|
||||
return new CacheDataCollector($app['data_collector.cache_subscriber']);
|
||||
});
|
||||
|
||||
return $collectors;
|
||||
}));
|
||||
|
||||
$app['data_collector.templates'] = $app->share($app->extend('data_collector.templates', function (array $templates) {
|
||||
$templates[] = array('db', '@DoctrineBundle/Collector/db.html.twig');
|
||||
$templates[] = array('cache', '@PhraseaProfiler/cache.html.twig');
|
||||
|
||||
return $templates;
|
||||
}));
|
||||
|
||||
$app['twig.loader.filesystem'] = $app->share($app->extend('twig.loader.filesystem', function ($loader, $app) {
|
||||
$loader->addPath(
|
||||
$app['root.path'] . '/vendor/sorien/silex-dbal-profiler/src/Sorien/Resources/views',
|
||||
'DoctrineBundle'
|
||||
);
|
||||
$loader->addPath($app['root.path'] . '/templates-profiler/', 'PhraseaProfiler');
|
||||
return $loader;
|
||||
}));
|
||||
}
|
||||
|
||||
/**
|
||||
* Bootstraps the application.
|
||||
*
|
||||
* This method is called after all services are registered
|
||||
* and should be used for "dynamic" configuration (whenever
|
||||
* a service must be requested).
|
||||
*/
|
||||
public function boot(Application $app)
|
||||
{
|
||||
$app['dispatcher']->addSubscriber($app['data_collector.cache_subscriber']);
|
||||
}
|
||||
}
|
23
lib/Alchemy/Phrasea/Core/Provider/WebhookServiceProvider.php
Normal file
23
lib/Alchemy/Phrasea/Core/Provider/WebhookServiceProvider.php
Normal file
@@ -0,0 +1,23 @@
|
||||
<?php
|
||||
|
||||
namespace Alchemy\Phrasea\Core\Provider;
|
||||
|
||||
use Alchemy\Phrasea\Webhook\EventProcessorFactory;
|
||||
use Silex\Application;
|
||||
use Silex\ServiceProviderInterface;
|
||||
|
||||
class WebhookServiceProvider implements ServiceProviderInterface
|
||||
{
|
||||
|
||||
public function register(Application $app)
|
||||
{
|
||||
$app['webhook.processor_factory'] = $app->share(function ($app) {
|
||||
return new EventProcessorFactory($app);
|
||||
});
|
||||
}
|
||||
|
||||
public function boot(Application $app)
|
||||
{
|
||||
// no-op
|
||||
}
|
||||
}
|
136
lib/Alchemy/Phrasea/Databox/ArrayCacheDataboxRepository.php
Normal file
136
lib/Alchemy/Phrasea/Databox/ArrayCacheDataboxRepository.php
Normal file
@@ -0,0 +1,136 @@
|
||||
<?php
|
||||
|
||||
namespace Alchemy\Phrasea\Databox;
|
||||
|
||||
class ArrayCacheDataboxRepository implements DataboxRepository
|
||||
{
|
||||
/**
|
||||
* @var DataboxRepository
|
||||
*/
|
||||
private $repository;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
private $loaded = false;
|
||||
|
||||
/**
|
||||
* @var \databox[]
|
||||
*/
|
||||
private $databoxes = [];
|
||||
|
||||
/**
|
||||
* @param DataboxRepository $repository
|
||||
*/
|
||||
public function __construct(DataboxRepository $repository)
|
||||
{
|
||||
$this->repository = $repository;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $id
|
||||
* @return \databox
|
||||
*/
|
||||
public function find($id)
|
||||
{
|
||||
$this->load();
|
||||
|
||||
if (! isset($this->databoxes[$id])) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $this->databoxes[$id];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \databox[]
|
||||
*/
|
||||
public function findAll()
|
||||
{
|
||||
$this->load();
|
||||
|
||||
return $this->databoxes;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \databox $databox
|
||||
*/
|
||||
public function save(\databox $databox)
|
||||
{
|
||||
$this->clear();
|
||||
|
||||
return $this->repository->save($databox);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \databox $databox
|
||||
*/
|
||||
public function delete(\databox $databox)
|
||||
{
|
||||
$this->clear();
|
||||
|
||||
return $this->repository->delete($databox);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \databox $databox
|
||||
*/
|
||||
public function unmount(\databox $databox)
|
||||
{
|
||||
$this->clear();
|
||||
|
||||
return $this->repository->unmount($databox);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $host
|
||||
* @param $port
|
||||
* @param $user
|
||||
* @param $password
|
||||
* @param $dbname
|
||||
*
|
||||
* @return \databox
|
||||
*/
|
||||
public function mount($host, $port, $user, $password, $dbname)
|
||||
{
|
||||
$this->clear();
|
||||
|
||||
return $this->repository->mount($host, $port, $user, $password, $dbname);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $host
|
||||
* @param $port
|
||||
* @param $user
|
||||
* @param $password
|
||||
* @param $dbname
|
||||
*
|
||||
* @return \databox
|
||||
*/
|
||||
public function create($host, $port, $user, $password, $dbname)
|
||||
{
|
||||
$this->clear();
|
||||
|
||||
return $this->repository->create($host, $port, $user, $password, $dbname);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the memory cache if needed.
|
||||
*/
|
||||
private function load()
|
||||
{
|
||||
if (! $this->loaded) {
|
||||
$this->databoxes = $this->repository->findAll();
|
||||
$this->loaded = true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears the memory cache.
|
||||
*/
|
||||
private function clear()
|
||||
{
|
||||
$this->loaded = false;
|
||||
$this->databoxes = [];
|
||||
}
|
||||
}
|
@@ -22,6 +22,12 @@ final class CachingDataboxRepositoryDecorator implements DataboxRepository
|
||||
/** @var DataboxFactory */
|
||||
private $factory;
|
||||
|
||||
/**
|
||||
* @param DataboxRepository $repository
|
||||
* @param Cache $cache
|
||||
* @param string $cacheKey
|
||||
* @param DataboxFactory $factory
|
||||
*/
|
||||
public function __construct(DataboxRepository $repository, Cache $cache, $cacheKey, DataboxFactory $factory)
|
||||
{
|
||||
$this->repository = $repository;
|
||||
@@ -56,6 +62,63 @@ final class CachingDataboxRepositoryDecorator implements DataboxRepository
|
||||
return $databoxes;
|
||||
}
|
||||
|
||||
public function save(\databox $databox)
|
||||
{
|
||||
$this->clearCache();
|
||||
|
||||
return $this->repository->save($databox);
|
||||
}
|
||||
|
||||
public function delete(\databox $databox)
|
||||
{
|
||||
$this->clearCache();
|
||||
|
||||
return $this->repository->delete($databox);
|
||||
}
|
||||
|
||||
public function unmount(\databox $databox)
|
||||
{
|
||||
$this->clearCache();
|
||||
|
||||
return $this->repository->unmount($databox);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $host
|
||||
* @param $port
|
||||
* @param $user
|
||||
* @param $password
|
||||
* @param $dbname
|
||||
*
|
||||
* @return \databox
|
||||
*/
|
||||
public function mount($host, $port, $user, $password, $dbname)
|
||||
{
|
||||
$databox = $this->repository->mount($host, $port, $user, $password, $dbname);
|
||||
|
||||
$this->clearCache();
|
||||
|
||||
return $databox;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $host
|
||||
* @param $port
|
||||
* @param $user
|
||||
* @param $password
|
||||
* @param $dbname
|
||||
*
|
||||
* @return \databox
|
||||
*/
|
||||
public function create($host, $port, $user, $password, $dbname)
|
||||
{
|
||||
$databox = $this->repository->create($host, $port, $user, $password, $dbname);
|
||||
|
||||
$this->clearCache();
|
||||
|
||||
return $databox;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \databox[] $databoxes
|
||||
*/
|
||||
@@ -69,4 +132,9 @@ final class CachingDataboxRepositoryDecorator implements DataboxRepository
|
||||
|
||||
$this->cache->save($this->cacheKey, $rows);
|
||||
}
|
||||
|
||||
private function clearCache()
|
||||
{
|
||||
$this->cache->delete($this->cacheKey);
|
||||
}
|
||||
}
|
||||
|
23
lib/Alchemy/Phrasea/Databox/DataboxConnectionProvider.php
Normal file
23
lib/Alchemy/Phrasea/Databox/DataboxConnectionProvider.php
Normal file
@@ -0,0 +1,23 @@
|
||||
<?php
|
||||
|
||||
namespace Alchemy\Phrasea\Databox;
|
||||
|
||||
class DataboxConnectionProvider
|
||||
{
|
||||
|
||||
private $applicationBox;
|
||||
|
||||
public function __construct(\appbox $applicationBox)
|
||||
{
|
||||
$this->applicationBox = $applicationBox;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $databoxId
|
||||
* @return \Doctrine\DBAL\Connection
|
||||
*/
|
||||
public function getConnection($databoxId)
|
||||
{
|
||||
return $this->applicationBox->get_databox($databoxId)->get_connection();
|
||||
}
|
||||
}
|
@@ -17,20 +17,33 @@ class DataboxFactory
|
||||
/** @var Application */
|
||||
private $app;
|
||||
|
||||
/** @var DataboxRepository */
|
||||
private $databoxRepository;
|
||||
|
||||
/**
|
||||
* @param Application $app
|
||||
*/
|
||||
public function __construct(Application $app)
|
||||
{
|
||||
$this->app = $app;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $id
|
||||
* @param DataboxRepository $databoxRepository
|
||||
*/
|
||||
public function setDataboxRepository(DataboxRepository $databoxRepository)
|
||||
{
|
||||
$this->databoxRepository = $databoxRepository;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $id
|
||||
* @param array $raw
|
||||
* @throws NotFoundHttpException when Databox could not be retrieved from Persistence layer
|
||||
* @return \databox
|
||||
* @return \databox when Databox could not be retrieved from Persistence layer
|
||||
*/
|
||||
public function create($id, array $raw)
|
||||
{
|
||||
return new \databox($this->app, $id, $raw);
|
||||
return new \databox($this->app, $id, $this->databoxRepository, $raw);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -43,7 +56,7 @@ class DataboxFactory
|
||||
$databoxes = [];
|
||||
|
||||
foreach ($rows as $id => $raw) {
|
||||
$databoxes[$id] = new \databox($this->app, $id, $raw);
|
||||
$databoxes[$id] = new \databox($this->app, $id, $this->databoxRepository, $raw);
|
||||
}
|
||||
|
||||
return $databoxes;
|
||||
|
37
lib/Alchemy/Phrasea/Databox/DataboxPathExtractor.php
Normal file
37
lib/Alchemy/Phrasea/Databox/DataboxPathExtractor.php
Normal file
@@ -0,0 +1,37 @@
|
||||
<?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\Databox;
|
||||
|
||||
class DataboxPathExtractor
|
||||
{
|
||||
/**
|
||||
* @var \appbox
|
||||
*/
|
||||
private $appbox;
|
||||
|
||||
public function __construct(\appbox $appbox)
|
||||
{
|
||||
$this->appbox = $appbox;
|
||||
}
|
||||
|
||||
public function extractPaths()
|
||||
{
|
||||
$paths = [];
|
||||
|
||||
foreach ($this->appbox->get_databoxes() as $databox) {
|
||||
foreach ($databox->get_subdef_structure()->getSubdefGroup('video') as $subdef) {
|
||||
$paths[] = $subdef->get_path();
|
||||
}
|
||||
}
|
||||
|
||||
return array_filter(array_unique($paths));
|
||||
}
|
||||
}
|
@@ -21,4 +21,41 @@ interface DataboxRepository
|
||||
* @return \databox[]
|
||||
*/
|
||||
public function findAll();
|
||||
|
||||
/**
|
||||
* @param \databox $databox
|
||||
*/
|
||||
public function save(\databox $databox);
|
||||
|
||||
/**
|
||||
* @param \databox $databox
|
||||
*/
|
||||
public function delete(\databox $databox);
|
||||
|
||||
/**
|
||||
* @param \databox $databox
|
||||
*/
|
||||
public function unmount(\databox $databox);
|
||||
|
||||
/**
|
||||
* @param $host
|
||||
* @param $port
|
||||
* @param $user
|
||||
* @param $password
|
||||
* @param $dbname
|
||||
*
|
||||
* @return \databox
|
||||
*/
|
||||
public function mount($host, $port, $user, $password, $dbname);
|
||||
|
||||
/**
|
||||
* @param $host
|
||||
* @param $port
|
||||
* @param $user
|
||||
* @param $password
|
||||
* @param $dbname
|
||||
*
|
||||
* @return \databox
|
||||
*/
|
||||
public function create($host, $port, $user, $password, $dbname);
|
||||
}
|
||||
|
@@ -47,6 +47,25 @@ final class DbalDataboxRepository implements DataboxRepository
|
||||
return $this->factory->createMany($this->fetchRows());
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \databox $databox
|
||||
* @return bool
|
||||
*/
|
||||
public function save(\databox $databox)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function delete(\databox $databox)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function unmount(\databox $databox)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $id
|
||||
* @return false|array
|
||||
@@ -82,4 +101,73 @@ final class DbalDataboxRepository implements DataboxRepository
|
||||
|
||||
return $rows;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $host
|
||||
* @param $port
|
||||
* @param $user
|
||||
* @param $password
|
||||
* @param $dbname
|
||||
*
|
||||
* @return \databox
|
||||
*/
|
||||
public function mount($host, $port, $user, $password, $dbname)
|
||||
{
|
||||
$query = 'INSERT INTO sbas (ord, host, port, dbname, sqlengine, user, pwd)
|
||||
SELECT COALESCE(MAX(ord), 0) + 1 AS ord, :host AS host, :port AS port, :dbname AS dbname,
|
||||
"MYSQL" AS sqlengine, :user AS user, :password AS pwd FROM sbas';
|
||||
|
||||
$statement = $this->connection->prepare($query);
|
||||
$statement->execute([
|
||||
':host' => $host,
|
||||
':port' => $port,
|
||||
':dbname' => $dbname,
|
||||
':user' => $user,
|
||||
':password' => $password
|
||||
]);
|
||||
|
||||
$statement->closeCursor();
|
||||
|
||||
return $this->find((int) $this->connection->lastInsertId());
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $host
|
||||
* @param $port
|
||||
* @param $user
|
||||
* @param $password
|
||||
* @param $dbname
|
||||
*
|
||||
* @return \databox
|
||||
*/
|
||||
public function create($host, $port, $user, $password, $dbname)
|
||||
{
|
||||
$params = [
|
||||
':host' => $host,
|
||||
':port' => $port,
|
||||
':user' => $user,
|
||||
':password' => $password,
|
||||
':dbname' => $dbname
|
||||
];
|
||||
|
||||
$query = 'SELECT sbas_id FROM sbas
|
||||
WHERE host = :host AND port = :port AND `user` = :user AND pwd = :password AND dbname = :dbname';
|
||||
$statement = $this->connection->executeQuery($query, $params);
|
||||
|
||||
if ($row = $statement->fetch(\PDO::FETCH_ASSOC)) {
|
||||
return $this->find((int) $row['sbas_id']);
|
||||
}
|
||||
|
||||
$query = 'INSERT INTO sbas (ord, host, port, dbname, sqlengine, user, pwd)
|
||||
SELECT COALESCE(MAX(ord), 0) + 1 AS ord, :host AS host, :port AS port, :dbname AS dbname,
|
||||
"MYSQL" AS sqlengine, :user AS user, :password AS pwd FROM sbas';
|
||||
|
||||
$stmt = $this->connection->prepare($query);
|
||||
$stmt->execute($params);
|
||||
|
||||
$stmt->closeCursor();
|
||||
|
||||
return $this->find((int) $this->connection->lastInsertId());
|
||||
|
||||
}
|
||||
}
|
||||
|
@@ -0,0 +1,38 @@
|
||||
<?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\Filesystem;
|
||||
|
||||
use Alchemy\Phrasea\Application;
|
||||
|
||||
class ApplicationPathServiceGenerator
|
||||
{
|
||||
public function createDefinition(array $key, callable $default)
|
||||
{
|
||||
return function(Application $app) use ($key, $default) {
|
||||
static $path;
|
||||
|
||||
if (null === $path) {
|
||||
$path = ($app['phraseanet.configuration']->isSetup())
|
||||
? $app['conf']->get($key)
|
||||
: null;
|
||||
|
||||
if (null === $path) {
|
||||
$path = $default($app);
|
||||
}
|
||||
|
||||
// ensure path is created
|
||||
$app['filesystem']->mkdir($path);
|
||||
}
|
||||
|
||||
return $path;
|
||||
};
|
||||
}
|
||||
}
|
208
lib/Alchemy/Phrasea/Filesystem/FilesystemService.php
Normal file
208
lib/Alchemy/Phrasea/Filesystem/FilesystemService.php
Normal file
@@ -0,0 +1,208 @@
|
||||
<?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\Filesystem;
|
||||
|
||||
use MediaAlchemyst\Specification\SpecificationInterface;
|
||||
|
||||
class FilesystemService
|
||||
{
|
||||
/**
|
||||
* @var \Symfony\Component\Filesystem\Filesystem
|
||||
*/
|
||||
private $filesystem;
|
||||
|
||||
public function __construct(\Symfony\Component\Filesystem\Filesystem $filesystem)
|
||||
{
|
||||
$this->filesystem = $filesystem;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $repository_path
|
||||
* @return string
|
||||
*/
|
||||
public function directorySpread($repository_path)
|
||||
{
|
||||
$repository_path = \p4string::addEndSlash($repository_path);
|
||||
|
||||
$timestamp = strtotime(date('Y-m-d'));
|
||||
$year = date('Y', $timestamp);
|
||||
$month = date('m', $timestamp);
|
||||
$day = date('d', $timestamp);
|
||||
|
||||
$comp = $year . DIRECTORY_SEPARATOR . $month . DIRECTORY_SEPARATOR . $day . DIRECTORY_SEPARATOR;
|
||||
|
||||
$n = 0;
|
||||
do {
|
||||
$pathout = sprintf('%s%s%05d', $repository_path, $comp, $n++);
|
||||
} while (is_dir($pathout) && iterator_count(new \DirectoryIterator($pathout)) > 100);
|
||||
|
||||
$this->filesystem->mkdir($pathout, 0750);
|
||||
|
||||
return $pathout . DIRECTORY_SEPARATOR;
|
||||
}
|
||||
|
||||
public function exists($path)
|
||||
{
|
||||
return $this->filesystem->exists($path);
|
||||
}
|
||||
|
||||
public function generateSubdefPathname(\record_adapter $record, \databox_subdef $subdef, $oldVersion)
|
||||
{
|
||||
if ($oldVersion) {
|
||||
$pathdest = \p4string::addEndSlash(pathinfo($oldVersion, PATHINFO_DIRNAME));
|
||||
} else {
|
||||
$pathdest = $this->directorySpread($subdef->get_path());
|
||||
}
|
||||
|
||||
return $pathdest . $this->generateSubdefFilename($record, $subdef);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \record_adapter $record
|
||||
* @param string|\SplFileInfo $source
|
||||
* @return string
|
||||
*/
|
||||
public function generateDocumentFilename(\record_adapter $record, $source)
|
||||
{
|
||||
if (!$source instanceof \SplFileInfo) {
|
||||
$source = new \SplFileInfo($source);
|
||||
}
|
||||
|
||||
return $record->getRecordId() . '_document' . strtolower($source->getExtension());
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \record_adapter $record
|
||||
* @param \databox_subdef $subdef
|
||||
* @param string $marker
|
||||
* @return string
|
||||
*/
|
||||
public function generateSubdefFilename(\record_adapter $record, \databox_subdef $subdef, $marker = '')
|
||||
{
|
||||
return $record->getRecordId() . '_' . $marker . $subdef->get_name() . '.' . $this->getExtensionFromSpec($subdef->getSpecs());
|
||||
}
|
||||
|
||||
public function generateSubdefSubstitutionPathname(\record_adapter $record, \databox_subdef $subdef)
|
||||
{
|
||||
$pathdest = $this->directorySpread($subdef->get_path());
|
||||
|
||||
return $pathdest . $this->generateSubdefFilename($record, $subdef, '0_');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \databox $databox
|
||||
* @return string
|
||||
*/
|
||||
public function generateDataboxDocumentBasePath(\databox $databox)
|
||||
{
|
||||
$baseprefs = $databox->get_sxml_structure();
|
||||
|
||||
return $this->directorySpread(\p4string::addEndSlash((string)($baseprefs->path)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Write Media source file with given filename
|
||||
*
|
||||
* @param \databox $databox
|
||||
* @param string $source
|
||||
* @param string $filename
|
||||
*/
|
||||
public function writeMediaSourceFile(\databox $databox, $source, $filename)
|
||||
{
|
||||
$realPath = $this->generateDataboxDocumentBasePath($databox) . $filename;
|
||||
|
||||
$this->filesystem->copy($source, $realPath, true);
|
||||
$this->filesystem->chmod($realPath, 0760);
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy file from source to target
|
||||
*
|
||||
* @param string $source
|
||||
* @param string $target
|
||||
*/
|
||||
public function copy($source, $target)
|
||||
{
|
||||
$this->filesystem->copy($source, $target, true);
|
||||
}
|
||||
|
||||
public function chmod($files, $mode, $umask = 0000, $recursive = false)
|
||||
{
|
||||
$this->filesystem->chmod($files, $mode, $umask, $recursive);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the extension from MediaAlchemyst specs
|
||||
*
|
||||
* @param SpecificationInterface $spec
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function getExtensionFromSpec(SpecificationInterface $spec)
|
||||
{
|
||||
switch ($spec->getType()) {
|
||||
case SpecificationInterface::TYPE_IMAGE:
|
||||
return 'jpg';
|
||||
case SpecificationInterface::TYPE_ANIMATION:
|
||||
return 'gif';
|
||||
case SpecificationInterface::TYPE_AUDIO:
|
||||
return $this->getExtensionFromAudioCodec($spec->getAudioCodec());
|
||||
case SpecificationInterface::TYPE_VIDEO:
|
||||
return $this->getExtensionFromVideoCodec($spec->getVideoCodec());
|
||||
case SpecificationInterface::TYPE_SWF:
|
||||
return 'swf';
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the extension from audiocodec
|
||||
*
|
||||
* @param string $audioCodec
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function getExtensionFromAudioCodec($audioCodec)
|
||||
{
|
||||
switch ($audioCodec) {
|
||||
case 'flac':
|
||||
return 'flac';
|
||||
case 'libvorbis':
|
||||
return 'ogg';
|
||||
case 'libmp3lame':
|
||||
return 'mp3';
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the extension from videocodec
|
||||
*
|
||||
* @param string $videoCodec
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function getExtensionFromVideoCodec($videoCodec)
|
||||
{
|
||||
switch ($videoCodec) {
|
||||
case 'libtheora':
|
||||
return 'ogv';
|
||||
case 'libvpx':
|
||||
return 'webm';
|
||||
case 'libx264':
|
||||
return 'mp4';
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
@@ -1,6 +1,5 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
/**
|
||||
* This file is part of Phraseanet
|
||||
*
|
||||
* (c) 2005-2016 Alchemy
|
||||
@@ -9,26 +8,40 @@
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Alchemy\Phrasea\Core\Provider;
|
||||
namespace Alchemy\Phrasea\Filesystem;
|
||||
|
||||
use Neutron\TemporaryFilesystem\TemporaryFilesystem;
|
||||
use Neutron\TemporaryFilesystem\Manager;
|
||||
use Neutron\TemporaryFilesystem\TemporaryFilesystem;
|
||||
use Silex\Application;
|
||||
use Silex\ServiceProviderInterface;
|
||||
use Symfony\Component\Filesystem\Filesystem;
|
||||
|
||||
class TemporaryFilesystemServiceProvider implements ServiceProviderInterface
|
||||
class FilesystemServiceProvider implements ServiceProviderInterface
|
||||
{
|
||||
public function register(Application $app)
|
||||
{
|
||||
$app['filesystem'] = $app->share(function () {
|
||||
return new Filesystem();
|
||||
});
|
||||
|
||||
$app['temporary-filesystem.temporary-fs'] = $app->share(function (Application $app) {
|
||||
return new TemporaryFilesystem($app['filesystem']);
|
||||
});
|
||||
$app['temporary-filesystem'] = $app->share(function (Application $app) {
|
||||
return new Manager($app['temporary-filesystem.temporary-fs'], $app['filesystem']);
|
||||
});
|
||||
|
||||
$app['phraseanet.filesystem'] = $app->share(function (Application $app) {
|
||||
return new FilesystemService($app['filesystem']);
|
||||
});
|
||||
|
||||
$app['phraseanet.lazaret_filesystem'] = $app->share(function (Application $app) {
|
||||
return new LazaretFilesystemService($app['filesystem'], $app['tmp.lazaret.path'], $app['media-alchemyst']);
|
||||
});
|
||||
}
|
||||
|
||||
public function boot(Application $app)
|
||||
{
|
||||
// no-op
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user