mirror of
https://github.com/alchemy-fr/Phraseanet.git
synced 2025-10-18 15:33:15 +00:00
Application bootstrap refactor
- Extract environment properties in Environment class - Replaces initialisation closure by ApplicationLoader class - Removes undesirable error handling/PHP settings modifications
This commit is contained in:
@@ -14,10 +14,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\ControllerProvider\ControllerProviderServiceProvider;
|
||||
use Alchemy\Phrasea\Core\Event\Subscriber\BasketSubscriber;
|
||||
use Alchemy\Phrasea\Core\Event\Subscriber\BridgeSubscriber;
|
||||
use Alchemy\Phrasea\Core\Event\Subscriber\ExportSubscriber;
|
||||
@@ -142,6 +145,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',
|
||||
@@ -150,38 +157,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());
|
||||
}
|
||||
@@ -287,6 +287,7 @@ class Application extends SilexApplication
|
||||
return rtrim($app['cache.path'], '/\\') . '/alchemy_cors.cache.php';
|
||||
},
|
||||
]);
|
||||
|
||||
$this['phraseanet.api_cors.options_provider'] = function (Application $app) {
|
||||
$paths = [];
|
||||
|
||||
@@ -307,78 +308,16 @@ class Application extends SilexApplication
|
||||
$this->register(new LocaleServiceProvider());
|
||||
$this->setupEventDispatcher();
|
||||
$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' => [],
|
||||
];
|
||||
foreach ($providers as $class => $values) {
|
||||
$this->register(new $class, $values);
|
||||
}
|
||||
$this->register(new ControllerProviderServiceProvider());
|
||||
|
||||
$resolvers = $this['alchemy_embed.resource_resolvers'];
|
||||
$resolvers['datafile'] = $resolvers->share(function () {
|
||||
@@ -411,6 +350,11 @@ class Application extends SilexApplication
|
||||
}
|
||||
}
|
||||
|
||||
public function getEnvironment()
|
||||
{
|
||||
return $this->environment->getName();
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads Phraseanet plugins
|
||||
*/
|
||||
@@ -475,6 +419,7 @@ class Application extends SilexApplication
|
||||
$twig->setCache($app['cache.path'].'/twig');
|
||||
|
||||
$paths = [];
|
||||
|
||||
if (file_exists($app['plugin.path'] . '/twig-paths.php')) {
|
||||
$paths = require $app['plugin.path'] . '/twig-paths.php';
|
||||
}
|
||||
@@ -651,6 +596,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
|
||||
*
|
||||
@@ -706,75 +659,12 @@ 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',
|
||||
'/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);
|
||||
|
||||
$this->bindPluginRoutes('plugin.controller_providers.root');
|
||||
$loader->bindRoutes($this);
|
||||
$loader->bindPluginRoutes($this, 'plugin.controller_providers.root');
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -928,12 +818,15 @@ class Application extends SilexApplication
|
||||
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';
|
||||
}
|
||||
@@ -980,6 +873,7 @@ class Application extends SilexApplication
|
||||
$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';
|
||||
@@ -1014,6 +908,7 @@ class Application extends SilexApplication
|
||||
return $this['session.storage.handler.factory']->create($app['conf']);
|
||||
});
|
||||
}
|
||||
|
||||
private function setupRecaptacha()
|
||||
{
|
||||
$this['recaptcha.public-key'] = $this->share(function (Application $app) {
|
||||
@@ -1105,6 +1000,7 @@ class Application extends SilexApplication
|
||||
|
||||
return $configuration;
|
||||
});
|
||||
|
||||
$this['media-alchemyst.logger'] = $this->share(function (Application $app) {
|
||||
return $app['monolog'];
|
||||
});
|
||||
@@ -1220,12 +1116,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);
|
||||
}
|
||||
@@ -1242,30 +1141,6 @@ class Application extends SilexApplication
|
||||
*/
|
||||
public function bindPluginRoutes($routeParameter)
|
||||
{
|
||||
foreach ($this[$routeParameter] as $provider) {
|
||||
$prefix = '';
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
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,65 +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 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();
|
||||
|
||||
$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 $provider) {
|
||||
$prefix = '';
|
||||
$providerKey = $provider;
|
||||
|
||||
if (is_array($provider)) {
|
||||
list($prefix, $providerKey) = $provider;
|
||||
}
|
||||
|
||||
if (! $this->isValidProviderDefinition($app, $prefix, $provider)) {
|
||||
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;
|
||||
}
|
||||
}
|
@@ -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 => [],
|
||||
];
|
||||
}
|
||||
}
|
@@ -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];
|
||||
|
@@ -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->share($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
|
||||
}
|
||||
}
|
48
tests/Alchemy/Tests/Phrasea/Application/RouteLoaderTest.php
Normal file
48
tests/Alchemy/Tests/Phrasea/Application/RouteLoaderTest.php
Normal file
@@ -0,0 +1,48 @@
|
||||
<?php
|
||||
|
||||
namespace Alchemy\Tests\Phrasea\Application;
|
||||
|
||||
use Alchemy\Phrasea\Application;
|
||||
use Alchemy\Phrasea\Application\RouteLoader;
|
||||
use Prophecy\Argument;
|
||||
use Silex\ControllerCollection;
|
||||
use Silex\ControllerProviderInterface;
|
||||
use Silex\Route;
|
||||
|
||||
class RouteLoaderTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
|
||||
/**
|
||||
* @expectedException \InvalidArgumentException
|
||||
*/
|
||||
public function testRegisterProviderWithInvalidClassFails()
|
||||
{
|
||||
$routeLoader = new RouteLoader();
|
||||
|
||||
$routeLoader->registerProvider('test_invalid_class', '\Alchemy\Tests\Phrasea\Application\UndefinedClass');
|
||||
}
|
||||
|
||||
public function testRegisteredProvidersAreMountedInApplication()
|
||||
{
|
||||
$application = $this->prophesize(Application::class);
|
||||
$application->offsetGet(Argument::any())
|
||||
->shouldBeCalled();
|
||||
$application->mount(Argument::any(), Argument::type(ControllerProviderInterface::class))
|
||||
->shouldBeCalled();
|
||||
$application->mount(Argument::exact('mount_prefix'), Argument::type(MockControllerProvider::class))
|
||||
->shouldBeCalled();
|
||||
|
||||
$routeLoader = new RouteLoader();
|
||||
$routeLoader->registerProvider('mount_prefix', MockControllerProvider::class);
|
||||
|
||||
$routeLoader->bindRoutes($application->reveal());
|
||||
}
|
||||
}
|
||||
|
||||
class MockControllerProvider implements ControllerProviderInterface
|
||||
{
|
||||
public function connect(\Silex\Application $app)
|
||||
{
|
||||
return new ControllerCollection(new Route('/'));
|
||||
}
|
||||
}
|
@@ -37,9 +37,11 @@ class DebuggerSubscriberTest extends \PhraseanetTestCase
|
||||
|
||||
$app['conf']->set(['debugger', 'allowed-ips'], $authorized);
|
||||
$app['dispatcher']->addSubscriber(new DebuggerSubscriber($app));
|
||||
|
||||
$app->get('/', function () {
|
||||
return 'success';
|
||||
});
|
||||
|
||||
$app->boot();
|
||||
|
||||
if ($exceptionThrown) {
|
||||
@@ -53,12 +55,12 @@ class DebuggerSubscriberTest extends \PhraseanetTestCase
|
||||
{
|
||||
return [
|
||||
[false, Application::ENV_PROD, '127.0.0.1', []],
|
||||
[false, Application::ENV_PROD, '192.168.0.1', []],
|
||||
[true, Application::ENV_PROD, '192.168.0.1', []],
|
||||
[false, Application::ENV_DEV, '127.0.0.1', []],
|
||||
[true, Application::ENV_DEV, '192.168.0.1', []],
|
||||
[false, Application::ENV_DEV, '192.168.0.1', ['192.168.0.1']],
|
||||
[false, Application::ENV_TEST, '127.0.0.1', []],
|
||||
[false, Application::ENV_TEST, '192.168.0.1', []],
|
||||
[true, Application::ENV_TEST, '192.168.0.1', []],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
@@ -12,9 +12,8 @@
|
||||
use Alchemy\Phrasea\Application;
|
||||
use Symfony\Component\Debug\ErrorHandler;
|
||||
|
||||
require_once __DIR__ . "/../lib/autoload.php";
|
||||
|
||||
error_reporting(0);
|
||||
require_once __DIR__ . "/../lib/autoload.php";
|
||||
|
||||
ErrorHandler::register();
|
||||
|
||||
|
Reference in New Issue
Block a user