Merge pull request #965 from romainneutron/host-configuration

[3.9] Add configuration per host
This commit is contained in:
Nicolas Le Goff
2014-02-24 12:30:26 +01:00
44 changed files with 1051 additions and 440 deletions

View File

@@ -11,7 +11,6 @@
namespace Alchemy\Phrasea\Border; namespace Alchemy\Phrasea\Border;
use Alchemy\Phrasea\Core\Configuration\Configuration;
use Alchemy\Phrasea\Core\Configuration\PropertyAccess; use Alchemy\Phrasea\Core\Configuration\PropertyAccess;
use MediaVorus\Utils\AudioMimeTypeGuesser; use MediaVorus\Utils\AudioMimeTypeGuesser;
use MediaVorus\Utils\PostScriptMimeTypeGuesser; use MediaVorus\Utils\PostScriptMimeTypeGuesser;
@@ -24,12 +23,10 @@ class MimeGuesserConfiguration
{ {
/** @var PropertyAccess */ /** @var PropertyAccess */
private $conf; private $conf;
private $store;
public function __construct(PropertyAccess $conf, Configuration $store) public function __construct(PropertyAccess $conf)
{ {
$this->conf = $conf; $this->conf = $conf;
$this->store = $store;
} }
/** /**
@@ -45,8 +42,6 @@ class MimeGuesserConfiguration
$guesser->register(new AudioMimeTypeGuesser()); $guesser->register(new AudioMimeTypeGuesser());
$guesser->register(new VideoMimeTypeGuesser()); $guesser->register(new VideoMimeTypeGuesser());
if ($this->store->isSetup()) {
$guesser->register(new CustomExtensionGuesser($this->conf->get(['border-manager', 'extension-mapping'], []))); $guesser->register(new CustomExtensionGuesser($this->conf->get(['border-manager', 'extension-mapping'], [])));
} }
} }
}

View File

@@ -65,8 +65,11 @@ class RegenerateSqliteDb extends Command
} }
try { try {
$dbParams = $this->container['configuration.store']->getTestConnectionParameters(); $dbParams = [
$dbParams['path'] = $source; 'driver' => 'pdo_sqlite',
'path' => $source,
'charset' => 'UTF8',
];
$this->container->register(new ORMServiceProvider()); $this->container->register(new ORMServiceProvider());
$this->container['EM.dbal-conf'] = $dbParams; $this->container['EM.dbal-conf'] = $dbParams;

View File

@@ -183,7 +183,7 @@ class TaskManager implements ControllerProviderInterface
$task = $app['manipulator.task']->create( $task = $app['manipulator.task']->create(
$job->getName(), $job->getName(),
$job->getJobId(), $job->getJobId(),
$job->getEditor()->getDefaultSettings($app['configuration.store']), $job->getEditor()->getDefaultSettings($app['conf']),
$job->getEditor()->getDefaultPeriod() $job->getEditor()->getDefaultPeriod()
); );

View File

@@ -185,7 +185,10 @@ class Configuration implements ConfigurationInterface
$this->delete(); $this->delete();
$this->dumpFile($this->config, $this->loadFile(__DIR__ . static::CONFIG_REF), 0600); $this->dumpFile($this->config, $this->loadFile(__DIR__ . static::CONFIG_REF), 0600);
return $this->getConfig(); // force rewrite
$this->getConfig();
return $this;
} }
/** /**
@@ -201,15 +204,6 @@ class Configuration implements ConfigurationInterface
return $this->autoReload; return $this->autoReload;
} }
public function getTestConnectionParameters()
{
return [
'driver' => 'pdo_sqlite',
'path' => '/tmp/db.sqlite',
'charset' => 'UTF8',
];
}
private function loadDefaultConfiguration() private function loadDefaultConfiguration()
{ {
return $this->parser->parse($this->loadFile(__DIR__ . static::CONFIG_REF)); return $this->parser->parse($this->loadFile(__DIR__ . static::CONFIG_REF));

View File

@@ -0,0 +1,235 @@
<?php
/*
* This file is part of Phraseanet
*
* (c) 2005-2014 Alchemy
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Alchemy\Phrasea\Core\Configuration;
use Alchemy\Phrasea\Exception\RuntimeException;
class HostConfiguration implements ConfigurationInterface
{
private $configuration;
private $cache;
private $host;
public function __construct(ConfigurationInterface $configuration)
{
$this->configuration = $configuration;
$this->cache = $configuration->isSetup() ? $this->configuration->getConfig() : [];
}
/**
* Sets the host name to switch on.
*
* @param $host
*/
public function setHost($host)
{
$this->host = trim(strtolower($host));
if ('' === $this->host) {
$this->merge();
return;
}
if (!isset($this->cache['hosts-configuration'])) {
$this->merge();
return;
}
foreach ($this->cache['hosts-configuration'] as $hostConf) {
if (!isset($hostConf['servername'])) {
continue;
}
if ($this->match($this->host, $hostConf['servername'])) {
$this->merge($hostConf);
break;
}
if (!isset($hostConf['hosts'])) {
continue;
}
foreach ((array) $hostConf['hosts'] as $hostname) {
if ($this->match($this->host, $hostname)) {
$this->merge($hostConf);
break 2;
}
}
}
}
/**
* {@inheritdoc}
*/
public function offsetExists($offset)
{
return isset($this->cache[$offset]);
}
/**
* {@inheritdoc}
*/
public function offsetSet($offset, $value)
{
$this->configuration[$offset] = $value;
$this->cache = $this->configuration->getConfig();
$this->setHost($this->host);
}
/**
* {@inheritdoc}
*/
public function offsetGet($offset)
{
return $this->cache[$offset];
}
/**
* {@inheritdoc}
*/
public function offsetUnset($offset)
{
$this->configuration->offsetUnset($offset);
$this->cache = $this->configuration->getConfig();
$this->setHost($this->host);
}
/**
* {@inheritdoc}
*/
public function initialize()
{
$this->configuration->initialize();
$this->cache = $this->configuration->getConfig();
$this->setHost($this->host);
return $this;
}
/**
* {@inheritdoc}
*/
public function delete()
{
$this->configuration->delete();
$this->cache = [];
$this->setHost($this->host);
return $this;
}
/**
* {@inheritdoc}
*/
public function isSetup()
{
return $this->configuration->isSetup();
}
/**
* {@inheritdoc}
*/
public function setDefault($name)
{
$this->configuration->setDefault($name);
$this->cache = $this->configuration->getConfig();
$this->setHost($this->host);
return $this;
}
/**
* {@inheritdoc}
*/
public function getConfig()
{
if (empty($this->cache)) {
throw new RuntimeException('Configuration is not set up.');
}
return $this->cache;
}
/**
* {@inheritdoc}
*/
public function setConfig(array $config)
{
$this->configuration->setConfig($config);
$this->cache = $this->configuration->getConfig();
$this->setHost($this->host);
return $this;
}
/**
* {@inheritdoc}
*/
public function compileAndWrite()
{
$this->configuration->compileAndWrite();
$this->cache = $this->configuration->getConfig();
$this->setHost($this->host);
}
private function match($host, $hostname)
{
return $this->removeHostPrefix($host) === $this->removeHostPrefix($hostname);
}
private function removeHostPrefix($hostname)
{
$data = parse_url($hostname);
if (!isset($data['host'])) {
return $hostname;
}
if (!isset($data['path']) || '/' === $data['path']) {
return strtolower(rtrim($data['host'], '/'));
} else {
return strtolower($data['host'].$data['path']);
}
}
private function merge(array $subConf = [])
{
if (!$this->configuration->isSetup()) {
$this->cache = [];
return;
}
$config = $this->configuration->getConfig();
if (empty($subConf)) {
$this->cache = $config;
return;
}
foreach (array_keys($subConf) as $property) {
if (in_array($property, ['main', 'xsendfile', 'hosts-configuration', 'databoxes'])) {
continue;
}
$data = isset($config[$property]) ? $config[$property] : (is_array($subConf[$property]) ? [] : null);
if (is_array($data)) {
$data = array_replace_recursive($data, $subConf[$property]);
} else {
$data = $subConf[$property];
}
$config[$property] = $data;
}
$this->cache = $config;
}
}

View File

@@ -0,0 +1,50 @@
<?php
/*
* This file is part of Phraseanet
*
* (c) 2005-2014 Alchemy
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Alchemy\Phrasea\Core\Event\Subscriber;
use Alchemy\Phrasea\Core\Configuration\HostConfiguration;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpKernel\Event\FinishRequestEvent;
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
use Symfony\Component\HttpKernel\KernelEvents;
class ConfigurationLoaderSubscriber implements EventSubscriberInterface
{
private $configuration;
public function __construct(HostConfiguration $configuration)
{
$this->configuration = $configuration;
}
public static function getSubscribedEvents()
{
return [
KernelEvents::REQUEST => [
['loadConfiguration', 255],
],
KernelEvents::FINISH_REQUEST => [
['unloadConfiguration', 255],
],
];
}
public function loadConfiguration(GetResponseEvent $event)
{
$this->configuration->setHost($event->getRequest()->getHost());
}
public function unloadConfiguration(FinishRequestEvent $event)
{
$this->configuration->setHost(null);
}
}

View File

@@ -11,7 +11,7 @@
namespace Alchemy\Phrasea\Core\Event\Subscriber; namespace Alchemy\Phrasea\Core\Event\Subscriber;
use Alchemy\Phrasea\Core\Configuration\Configuration; use Alchemy\Phrasea\Core\Configuration\ConfigurationInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface; use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpKernel\Event\GetResponseEvent; use Symfony\Component\HttpKernel\Event\GetResponseEvent;
use Symfony\Component\HttpKernel\KernelEvents; use Symfony\Component\HttpKernel\KernelEvents;
@@ -21,7 +21,7 @@ class TrustedProxySubscriber implements EventSubscriberInterface
{ {
private $configuration; private $configuration;
public function __construct(Configuration $configuration) public function __construct(ConfigurationInterface $configuration)
{ {
$this->configuration = $configuration; $this->configuration = $configuration;
} }

View File

@@ -100,12 +100,14 @@ class BorderManagerServiceProvider implements ServiceProviderInterface
}); });
$app['border-manager.mime-guesser-configuration'] = $app->share(function (Application $app) { $app['border-manager.mime-guesser-configuration'] = $app->share(function (Application $app) {
return new MimeGuesserConfiguration($app['conf'], $app['configuration.store']); return new MimeGuesserConfiguration($app['conf']);
}); });
} }
public function boot(Application $app) public function boot(Application $app)
{ {
if ($app['configuration.store']->isSetup()) {
$app['border-manager.mime-guesser-configuration']->register(); $app['border-manager.mime-guesser-configuration']->register();
} }
} }
}

View File

@@ -13,9 +13,11 @@ namespace Alchemy\Phrasea\Core\Provider;
use Alchemy\Phrasea\Core\Configuration\Configuration; use Alchemy\Phrasea\Core\Configuration\Configuration;
use Alchemy\Phrasea\Core\Configuration\DisplaySettingService; use Alchemy\Phrasea\Core\Configuration\DisplaySettingService;
use Alchemy\Phrasea\Core\Configuration\HostConfiguration;
use Alchemy\Phrasea\Core\Configuration\PropertyAccess; use Alchemy\Phrasea\Core\Configuration\PropertyAccess;
use Alchemy\Phrasea\Core\Configuration\Compiler; use Alchemy\Phrasea\Core\Configuration\Compiler;
use Alchemy\Phrasea\Core\Configuration\RegistryManipulator; use Alchemy\Phrasea\Core\Configuration\RegistryManipulator;
use Alchemy\Phrasea\Core\Event\Subscriber\ConfigurationLoaderSubscriber;
use Silex\Application as SilexApplication; use Silex\Application as SilexApplication;
use Silex\ServiceProviderInterface; use Silex\ServiceProviderInterface;
use Symfony\Component\Yaml\Yaml; use Symfony\Component\Yaml\Yaml;
@@ -35,13 +37,13 @@ class ConfigurationServiceProvider implements ServiceProviderInterface
$app['phraseanet.configuration.config-compiled-path'] = $app['root.path'] . '/tmp/configuration-compiled.php'; $app['phraseanet.configuration.config-compiled-path'] = $app['root.path'] . '/tmp/configuration-compiled.php';
$app['configuration.store'] = $app->share(function (SilexApplication $app) { $app['configuration.store'] = $app->share(function (SilexApplication $app) {
return new Configuration( return new HostConfiguration(new Configuration(
$app['phraseanet.configuration.yaml-parser'], $app['phraseanet.configuration.yaml-parser'],
$app['phraseanet.configuration.compiler'], $app['phraseanet.configuration.compiler'],
$app['phraseanet.configuration.config-path'], $app['phraseanet.configuration.config-path'],
$app['phraseanet.configuration.config-compiled-path'], $app['phraseanet.configuration.config-compiled-path'],
$app['debug'] $app['debug']
); ));
}); });
$app['registry.manipulator'] = $app->share(function (SilexApplication $app) { $app['registry.manipulator'] = $app->share(function (SilexApplication $app) {
@@ -69,6 +71,7 @@ class ConfigurationServiceProvider implements ServiceProviderInterface
{ {
$app['dispatcher'] = $app->share( $app['dispatcher'] = $app->share(
$app->extend('dispatcher', function ($dispatcher, SilexApplication $app) { $app->extend('dispatcher', function ($dispatcher, SilexApplication $app) {
$dispatcher->addSubscriber(new ConfigurationLoaderSubscriber($app['configuration.store']));
$dispatcher->addSubscriber(new TrustedProxySubscriber($app['configuration.store'])); $dispatcher->addSubscriber(new TrustedProxySubscriber($app['configuration.store']));
return $dispatcher; return $dispatcher;

View File

@@ -49,7 +49,7 @@ class TasksServiceProvider implements ServiceProviderInterface
}); });
$app['task-manager.status'] = $app->share(function (Application $app) { $app['task-manager.status'] = $app->share(function (Application $app) {
return new TaskManagerStatus($app['configuration.store']); return new TaskManagerStatus($app['conf']);
}); });
$app['task-manager.live-information'] = $app->share(function (Application $app) { $app['task-manager.live-information'] = $app->share(function (Application $app) {

View File

@@ -40,9 +40,7 @@ abstract class AbstractConfigurationPanel implements ConfigurationPanelInterface
*/ */
public function saveConfiguration(array $configuration) public function saveConfiguration(array $configuration)
{ {
$conf = $this->conf->getConfig(); $this->conf->set(['main', 'search-engine', 'options'], $configuration);
$conf['main']['search-engine']['options'] = $configuration;
$this->conf->setConfig($conf);
return $this; return $this;
} }

View File

@@ -12,15 +12,15 @@
namespace Alchemy\Phrasea\SearchEngine\Elastic; namespace Alchemy\Phrasea\SearchEngine\Elastic;
use Alchemy\Phrasea\Application; use Alchemy\Phrasea\Application;
use Alchemy\Phrasea\Core\Configuration\PropertyAccess;
use Alchemy\Phrasea\SearchEngine\AbstractConfigurationPanel; use Alchemy\Phrasea\SearchEngine\AbstractConfigurationPanel;
use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Request;
use Alchemy\Phrasea\Core\Configuration\ConfigurationInterface;
class ConfigurationPanel extends AbstractConfigurationPanel class ConfigurationPanel extends AbstractConfigurationPanel
{ {
private $searchEngine; private $searchEngine;
public function __construct(ElasticSearchEngine $engine, ConfigurationInterface $conf) public function __construct(ElasticSearchEngine $engine, PropertyAccess $conf)
{ {
$this->searchEngine = $engine; $this->searchEngine = $engine;
$this->conf = $conf; $this->conf = $conf;
@@ -62,6 +62,6 @@ class ConfigurationPanel extends AbstractConfigurationPanel
*/ */
public function getConfiguration() public function getConfiguration()
{ {
return isset($this->conf['main']['search-engine']['options']) ? $this->conf['main']['search-engine']['options'] : []; return $this->conf->get(['main', 'search-engine', 'options'], []);
} }
} }

View File

@@ -94,7 +94,7 @@ class ElasticSearchEngine implements SearchEngineInterface
public function getConfigurationPanel() public function getConfigurationPanel()
{ {
if (!$this->configurationPanel) { if (!$this->configurationPanel) {
$this->configurationPanel = new ConfigurationPanel($this, $this->app['configuration.store']); $this->configurationPanel = new ConfigurationPanel($this, $this->app['conf']);
} }
return $this->configurationPanel; return $this->configurationPanel;

View File

@@ -12,16 +12,16 @@
namespace Alchemy\Phrasea\SearchEngine\Phrasea; namespace Alchemy\Phrasea\SearchEngine\Phrasea;
use Alchemy\Phrasea\Application; use Alchemy\Phrasea\Application;
use Alchemy\Phrasea\Core\Configuration\PropertyAccess;
use Alchemy\Phrasea\SearchEngine\AbstractConfigurationPanel; use Alchemy\Phrasea\SearchEngine\AbstractConfigurationPanel;
use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Request;
use Alchemy\Phrasea\Core\Configuration\ConfigurationInterface;
class ConfigurationPanel extends AbstractConfigurationPanel class ConfigurationPanel extends AbstractConfigurationPanel
{ {
protected $charsets; protected $charsets;
protected $searchEngine; protected $searchEngine;
public function __construct(PhraseaEngine $engine, ConfigurationInterface $conf) public function __construct(PhraseaEngine $engine, PropertyAccess $conf)
{ {
$this->searchEngine = $engine; $this->searchEngine = $engine;
$this->conf = $conf; $this->conf = $conf;
@@ -75,7 +75,7 @@ class ConfigurationPanel extends AbstractConfigurationPanel
*/ */
public function getConfiguration() public function getConfiguration()
{ {
$configuration = isset($this->conf['main']['search-engine']['options']) ? $this->conf['main']['search-engine']['options'] : []; $configuration = $this->conf->get(['main', 'search-engine', 'options'], []);
if (!is_array($configuration)) { if (!is_array($configuration)) {
$configuration = []; $configuration = [];

View File

@@ -223,7 +223,7 @@ class PhraseaEngine implements SearchEngineInterface
public function getConfigurationPanel() public function getConfigurationPanel()
{ {
if (!$this->configurationPanel) { if (!$this->configurationPanel) {
$this->configurationPanel = new ConfigurationPanel($this, $this->app['configuration.store']); $this->configurationPanel = new ConfigurationPanel($this, $this->app['conf']);
} }
return $this->configurationPanel; return $this->configurationPanel;

View File

@@ -11,11 +11,11 @@
namespace Alchemy\Phrasea\SearchEngine\SphinxSearch; namespace Alchemy\Phrasea\SearchEngine\SphinxSearch;
use Alchemy\Phrasea\Core\Configuration\PropertyAccess;
use Alchemy\Phrasea\SearchEngine\AbstractConfigurationPanel; use Alchemy\Phrasea\SearchEngine\AbstractConfigurationPanel;
use Alchemy\Phrasea\Application; use Alchemy\Phrasea\Application;
use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Finder\Finder; use Symfony\Component\Finder\Finder;
use Alchemy\Phrasea\Core\Configuration\ConfigurationInterface;
class ConfigurationPanel extends AbstractConfigurationPanel class ConfigurationPanel extends AbstractConfigurationPanel
{ {
@@ -24,7 +24,7 @@ class ConfigurationPanel extends AbstractConfigurationPanel
protected $charsets; protected $charsets;
protected $searchEngine; protected $searchEngine;
public function __construct(SphinxSearchEngine $engine, ConfigurationInterface $conf) public function __construct(SphinxSearchEngine $engine, PropertyAccess $conf)
{ {
$this->searchEngine = $engine; $this->searchEngine = $engine;
$this->conf = $conf; $this->conf = $conf;
@@ -86,23 +86,11 @@ class ConfigurationPanel extends AbstractConfigurationPanel
*/ */
public function getConfiguration() public function getConfiguration()
{ {
$configuration = isset($this->conf['main']['search-engine']['options']) ? $this->conf['main']['search-engine']['options'] : []; $configuration = $this->conf->get(['main', 'search-engine', 'options'], []);
return self::populateConfiguration($configuration); return self::populateConfiguration($configuration);
} }
/**
* {@inheritdoc}
*/
public function saveConfiguration(array $configuration)
{
$conf = $this->conf->getConfig();
$conf['main']['search-engine']['options'] = $configuration;
$this->conf->setConfig($conf);
return $this;
}
/** /**
* Returns all the charset Sphinx Search supports * Returns all the charset Sphinx Search supports
* *

View File

@@ -173,7 +173,7 @@ class SphinxSearchEngine implements SearchEngineInterface
public function getConfigurationPanel() public function getConfigurationPanel()
{ {
if (!$this->configurationPanel) { if (!$this->configurationPanel) {
$this->configurationPanel = new ConfigurationPanel($this, $this->app['configuration.store']); $this->configurationPanel = new ConfigurationPanel($this, $this->app['conf']);
} }
return $this->configurationPanel; return $this->configurationPanel;

View File

@@ -97,7 +97,7 @@ class Installer
$this->app['manipulator.task']->create( $this->app['manipulator.task']->create(
$job->getName(), $job->getName(),
$job->getJobId(), $job->getJobId(),
$job->getEditor()->getDefaultSettings($this->app['configuration.store']), $job->getEditor()->getDefaultSettings($this->app['conf']),
$job->getEditor()->getDefaultPeriod() $job->getEditor()->getDefaultPeriod()
); );
} }
@@ -173,7 +173,7 @@ class Installer
private function createConfigFile(Connection $abConn, $serverName, $binaryData) private function createConfigFile(Connection $abConn, $serverName, $binaryData)
{ {
$config = $this->app['configuration.store']->initialize(); $config = $this->app['configuration.store']->initialize()->getConfig();
$config['main']['database']['host'] = $abConn->getHost(); $config['main']['database']['host'] = $abConn->getHost();
$config['main']['database']['port'] = $abConn->getPort(); $config['main']['database']['port'] = $abConn->getPort();

View File

@@ -12,6 +12,7 @@
namespace Alchemy\Phrasea\Setup\Version\Migration; namespace Alchemy\Phrasea\Setup\Version\Migration;
use Alchemy\Phrasea\Application; use Alchemy\Phrasea\Application;
use Alchemy\Phrasea\Core\Configuration\Configuration;
class Migration35 implements MigrationInterface class Migration35 implements MigrationInterface
{ {
@@ -29,7 +30,7 @@ class Migration35 implements MigrationInterface
throw new \LogicException('Required config files not found'); throw new \LogicException('Required config files not found');
} }
$config = $this->app['configuration.store']->initialize(); $config = $this->app['configuration.store']->initialize()->getConfig();
foreach ($config['registration-fields'] as $key => $field) { foreach ($config['registration-fields'] as $key => $field) {
$config['registration-fields'][$key]['required'] = (boolean) $field['required']; $config['registration-fields'][$key]['required'] = (boolean) $field['required'];

View File

@@ -11,7 +11,7 @@
namespace Alchemy\Phrasea\TaskManager\Editor; namespace Alchemy\Phrasea\TaskManager\Editor;
use Alchemy\Phrasea\Core\Configuration\ConfigurationInterface; use Alchemy\Phrasea\Core\Configuration\PropertyAccess;
class ArchiveEditor extends AbstractEditor class ArchiveEditor extends AbstractEditor
{ {
@@ -34,7 +34,7 @@ class ArchiveEditor extends AbstractEditor
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
public function getDefaultSettings(ConfigurationInterface $config = null) public function getDefaultSettings(PropertyAccess $config = null)
{ {
return <<<EOF return <<<EOF
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>

View File

@@ -11,7 +11,7 @@
namespace Alchemy\Phrasea\TaskManager\Editor; namespace Alchemy\Phrasea\TaskManager\Editor;
use Alchemy\Phrasea\Core\Configuration\ConfigurationInterface; use Alchemy\Phrasea\Core\Configuration\PropertyAccess;
class DefaultEditor extends AbstractEditor class DefaultEditor extends AbstractEditor
{ {
@@ -34,7 +34,7 @@ class DefaultEditor extends AbstractEditor
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
public function getDefaultSettings(ConfigurationInterface $config = null) public function getDefaultSettings(PropertyAccess $config = null)
{ {
return <<<EOF return <<<EOF
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>

View File

@@ -12,7 +12,7 @@
namespace Alchemy\Phrasea\TaskManager\Editor; namespace Alchemy\Phrasea\TaskManager\Editor;
use Alchemy\Phrasea\Application; use Alchemy\Phrasea\Application;
use Alchemy\Phrasea\Core\Configuration\ConfigurationInterface; use Alchemy\Phrasea\Core\Configuration\PropertyAccess;
use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException; use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
@@ -53,11 +53,11 @@ interface EditorInterface
* Configuration is used to populate the default configuration with * Configuration is used to populate the default configuration with
* configuration values. * configuration values.
* *
* @param Configuration $config * @param PropertyAccess $config
* *
* @return string An XML string * @return string An XML string
*/ */
public function getDefaultSettings(ConfigurationInterface $config = null); public function getDefaultSettings(PropertyAccess $config = null);
/** /**
* Returns the default period of the job. * Returns the default period of the job.

View File

@@ -11,7 +11,7 @@
namespace Alchemy\Phrasea\TaskManager\Editor; namespace Alchemy\Phrasea\TaskManager\Editor;
use Alchemy\Phrasea\Core\Configuration\ConfigurationInterface; use Alchemy\Phrasea\Core\Configuration\PropertyAccess;
class FtpEditor extends AbstractEditor class FtpEditor extends AbstractEditor
{ {
@@ -34,7 +34,7 @@ class FtpEditor extends AbstractEditor
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
public function getDefaultSettings(ConfigurationInterface $config = null) public function getDefaultSettings(PropertyAccess $config = null)
{ {
return <<<EOF return <<<EOF
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>

View File

@@ -11,7 +11,7 @@
namespace Alchemy\Phrasea\TaskManager\Editor; namespace Alchemy\Phrasea\TaskManager\Editor;
use Alchemy\Phrasea\Core\Configuration\ConfigurationInterface; use Alchemy\Phrasea\Core\Configuration\PropertyAccess;
class FtpPullEditor extends AbstractEditor class FtpPullEditor extends AbstractEditor
{ {
@@ -34,7 +34,7 @@ class FtpPullEditor extends AbstractEditor
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
public function getDefaultSettings(ConfigurationInterface $config = null) public function getDefaultSettings(PropertyAccess $config = null)
{ {
return <<<EOF return <<<EOF
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>

View File

@@ -11,7 +11,7 @@
namespace Alchemy\Phrasea\TaskManager\Editor; namespace Alchemy\Phrasea\TaskManager\Editor;
use Alchemy\Phrasea\Core\Configuration\ConfigurationInterface; use Alchemy\Phrasea\Core\Configuration\PropertyAccess;
class PhraseanetIndexerEditor extends AbstractEditor class PhraseanetIndexerEditor extends AbstractEditor
{ {
@@ -35,18 +35,16 @@ class PhraseanetIndexerEditor extends AbstractEditor
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
public function getDefaultSettings(ConfigurationInterface $config = null) public function getDefaultSettings(PropertyAccess $config = null)
{ {
if (null !== $config) { if (null !== $config) {
$database = $config['main']['database'];
return '<?xml version="1.0" encoding="UTF-8"?> return '<?xml version="1.0" encoding="UTF-8"?>
<tasksettings> <tasksettings>
<host>'.$database['host'].'</host> <host>'.$config->get(['main', 'database', 'host']).'</host>
<port>'.$database['port'].'</port> <port>'.$config->get(['main', 'database', 'port']).'</port>
<base>'.$database['dbname'].'</base> <base>'.$config->get(['main', 'database', 'dbname']).'</base>
<user>'.$database['user'].'</user> <user>'.$config->get(['main', 'database', 'user']).'</user>
<password>'.$database['password'].'</password> <password>'.$config->get(['main', 'database', 'password']).'</password>
<socket>25200</socket> <socket>25200</socket>
<nolog>0</nolog> <nolog>0</nolog>
<clng></clng> <clng></clng>

View File

@@ -12,7 +12,7 @@
namespace Alchemy\Phrasea\TaskManager\Editor; namespace Alchemy\Phrasea\TaskManager\Editor;
use Alchemy\Phrasea\Application; use Alchemy\Phrasea\Application;
use Alchemy\Phrasea\Core\Configuration\ConfigurationInterface; use Alchemy\Phrasea\Core\Configuration\PropertyAccess;
use Alchemy\Phrasea\TaskManager\Job\RecordMoverJob; use Alchemy\Phrasea\TaskManager\Job\RecordMoverJob;
use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
@@ -74,7 +74,7 @@ class RecordMoverEditor extends AbstractEditor
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
public function getDefaultSettings(ConfigurationInterface $config = null) public function getDefaultSettings(PropertyAccess $config = null)
{ {
return <<<EOF return <<<EOF
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>

View File

@@ -11,7 +11,7 @@
namespace Alchemy\Phrasea\TaskManager\Editor; namespace Alchemy\Phrasea\TaskManager\Editor;
use Alchemy\Phrasea\Core\Configuration\ConfigurationInterface; use Alchemy\Phrasea\Core\Configuration\PropertyAccess;
class SubdefsEditor extends AbstractEditor class SubdefsEditor extends AbstractEditor
{ {
@@ -34,7 +34,7 @@ class SubdefsEditor extends AbstractEditor
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
public function getDefaultSettings(ConfigurationInterface $config = null) public function getDefaultSettings(PropertyAccess $config = null)
{ {
return <<<EOF return <<<EOF
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>

View File

@@ -11,7 +11,7 @@
namespace Alchemy\Phrasea\TaskManager\Editor; namespace Alchemy\Phrasea\TaskManager\Editor;
use Alchemy\Phrasea\Core\Configuration\ConfigurationInterface; use Alchemy\Phrasea\Core\Configuration\PropertyAccess;
class WriteMetadataEditor extends AbstractEditor class WriteMetadataEditor extends AbstractEditor
{ {
@@ -34,7 +34,7 @@ class WriteMetadataEditor extends AbstractEditor
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
public function getDefaultSettings(ConfigurationInterface $config = null) public function getDefaultSettings(PropertyAccess $config = null)
{ {
return <<<EOF return <<<EOF
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>

View File

@@ -11,7 +11,7 @@
namespace Alchemy\Phrasea\TaskManager; namespace Alchemy\Phrasea\TaskManager;
use Alchemy\Phrasea\Core\Configuration\ConfigurationInterface; use Alchemy\Phrasea\Core\Configuration\PropertyAccess;
/** /**
* Gets and Sets the Task Manager status * Gets and Sets the Task Manager status
@@ -24,7 +24,7 @@ class TaskManagerStatus
const STATUS_STARTED = 'started'; const STATUS_STARTED = 'started';
const STATUS_STOPPED = 'stopped'; const STATUS_STOPPED = 'stopped';
public function __construct(ConfigurationInterface $conf) public function __construct(PropertyAccess $conf)
{ {
$this->conf = $conf; $this->conf = $conf;
} }
@@ -64,34 +64,26 @@ class TaskManagerStatus
{ {
$this->ensureConfigurationSchema(); $this->ensureConfigurationSchema();
return $this->conf['main']['task-manager']['status']; return $this->conf->get(['main', 'task-manager', 'status']);
} }
private function setStatus($status) private function setStatus($status)
{ {
$this->ensureConfigurationSchema(); $this->ensureConfigurationSchema();
$mainConf = $this->conf['main']; $this->conf->set(['main', 'task-manager', 'status'], $status);
$mainConf['task-manager']['status'] = $status;
$this->conf['main'] = $mainConf;
} }
private function ensureConfigurationSchema() private function ensureConfigurationSchema()
{ {
if (!isset($this->conf['main']['task-manager'])) { if (!$this->conf->has(['main', 'task-manager'])) {
$mainConf = $this->conf['main']; $this->conf->set(['main', 'task-manager'], ['status' => static::STATUS_STARTED]);
$mainConf['task-manager'] = ['status' => static::STATUS_STARTED];
$this->conf['main'] = $mainConf;
return; return;
} }
if (!isset($this->conf['main']['task-manager']['status'])) { if (!$this->conf->has(['main', 'task-manager', 'status'])) {
$mainConf = $this->conf['main']; $this->conf->set(['main', 'task-manager', 'status'], static::STATUS_STARTED);
$mainConf['task-manager']['status'] = static::STATUS_STARTED; } elseif (!$this->isValidStatus($this->conf->get(['main', 'task-manager', 'status']))) {
$this->conf['main'] = $mainConf; $this->conf->set(['main', 'task-manager'], ['status' => static::STATUS_STARTED]);
} elseif (!$this->isValidStatus($this->conf['main']['task-manager']['status'])) {
$mainConf = $this->conf['main'];
$mainConf['task-manager']['status'] = static::STATUS_STARTED;
$this->conf['main'] = $mainConf;
} }
} }

View File

@@ -199,9 +199,7 @@ class API_V1_result
$this->app['dispatcher']->dispatch(PhraseaEvents::API_RESULT, new ApiResultEvent()); $this->app['dispatcher']->dispatch(PhraseaEvents::API_RESULT, new ApiResultEvent());
$conf = $this->app['configuration.store']; if ($this->app['conf']->get(['main', 'api-timers'], false)) {
if (isset($conf['main']['api-timers']) && true === $conf['main']['api-timers']) {
$ret['timers'] = $this->app['api.timers']->toArray(); $ret['timers'] = $this->app['api.timers']->toArray();
} }

View File

@@ -56,7 +56,10 @@ class patch_380alpha3b implements patchInterface
*/ */
public function apply(base $appbox, Application $app) public function apply(base $appbox, Application $app)
{ {
$app['configuration.store']->setDefault('main', 'search-engine'); $app['conf']->set(['main', 'search-engine'], [
'type' => 'Alchemy\Phrasea\SearchEngine\Phrasea\PhraseaEngine',
'options' => [],
]);
return true; return true;
} }

View File

@@ -13,7 +13,6 @@ use Alchemy\Phrasea\Application;
use Alchemy\Phrasea\Model\Entities\FtpExport; use Alchemy\Phrasea\Model\Entities\FtpExport;
use Alchemy\Phrasea\Model\Entities\FtpExportElement; use Alchemy\Phrasea\Model\Entities\FtpExportElement;
use Gedmo\Timestampable\TimestampableListener; use Gedmo\Timestampable\TimestampableListener;
use Doctrine\ORM\NoResultException;
class patch_390alpha6a extends patchAbstract class patch_390alpha6a extends patchAbstract
{ {

View File

@@ -6,331 +6,21 @@ use Alchemy\Phrasea\Core\Configuration\Configuration;
use Alchemy\Phrasea\Core\Configuration\Compiler; use Alchemy\Phrasea\Core\Configuration\Compiler;
use Symfony\Component\Yaml\Yaml; use Symfony\Component\Yaml\Yaml;
class ConfigurationTest extends \PhraseanetTestCase class ConfigurationTest extends ConfigurationTestCase
{ {
private $compiled; protected function provideConfiguration($confFile, $compiledFile = null, Compiler $compiler = null, Yaml $yaml = null, $autoreload = false)
public function setUp()
{ {
parent::setUp(); if (null === $compiledFile) {
$this->compiled = __DIR__ . '/Fixtures/configuration-compiled.php'; $compiledFile = $this->compiled;
$this->clean();
} }
public function tearDown() if (null === $yaml) {
{
$this->clean();
parent::tearDown();
}
private function clean()
{
copy(__DIR__ . '/..' . Configuration::CONFIG_REF, __DIR__ . '/Fixtures/configuration.yml');
if (is_file($this->compiled)) {
unlink($this->compiled);
}
}
/**
* @expectedException \Alchemy\Phrasea\Exception\RuntimeException
*/
public function testGetConfigInvalidConfig()
{
$config = __DIR__ . '/Fixtures/configuration-unknown.yml';
$compiled = $this->compiled;
$yaml = new Yaml(); $yaml = new Yaml();
}
if (null === $compiler) {
$compiler = new Compiler(); $compiler = new Compiler();
$conf = new Configuration($yaml, $compiler, $config, $compiled, false);
$conf->getConfig();
} }
public function testInitialize() return new Configuration($yaml, $compiler, $confFile, $compiledFile, $autoreload);
{
$configFile = __DIR__ . '/Fixtures/configuration-unknown.yml';
if (is_file($configFile)) {
unlink($configFile);
}
$compiled = $this->compiled;
$yaml = new Yaml();
$compiler = new Compiler();
$conf = new Configuration($yaml, $compiler, $configFile, $compiled, false);
$config = $conf->initialize();
$this->assertArrayHasKey('main', $config);
$this->assertFileExists($compiled);
$this->assertFileExists($configFile);
unlink($configFile);
}
/**
* @expectedException \Alchemy\Phrasea\Exception\RuntimeException
*/
public function testInitializeWrongPath()
{
$configFile = __DIR__ . '/Fixtures/configuration.yml';
$compiled = __DIR__ . '/path/to/unknwon/folder/file.php';
$yaml = new Yaml();
$compiler = new Compiler();
$conf = new Configuration($yaml, $compiler, $configFile, $compiled, false);
$conf->initialize();
}
public function testArrayAccess()
{
$config = __DIR__ . '/Fixtures/configuration.yml';
$compiled = $this->compiled;
$compiler = new Compiler();
$yaml = new Yaml();
$conf = new Configuration($yaml, $compiler, $config, $compiled, false);
$this->assertEquals('sql-host', $conf['main']['database']['host']);
$conf['extra-key'] = 'extra-value';
$this->assertEquals('extra-value', $conf['extra-key']);
$updated = $yaml->parse($config);
$this->assertEquals('extra-value', $updated['extra-key']);
$this->assertTrue(isset($conf['extra-key']));
unset($conf['extra-key']);
$this->assertFalse(isset($conf['extra-key']));
$updated = $yaml->parse($config);
$this->assertFalse(isset($updated['extra-key']));
}
public function testDelete()
{
$config = __DIR__ . '/Fixtures/configuration.yml';
$compiled = $this->compiled;
$yaml = new Yaml();
$compiler = new Compiler();
$conf = new Configuration($yaml, $compiler, $config, $compiled, false);
$conf->initialize();
$conf->delete();
$this->assertFileNotExists($compiled);
}
public function testIsSetup()
{
$config = __DIR__ . '/Fixtures/configuration-setup.yml';
$compiled = $this->compiled;
@unlink($config);
$compiler = new Compiler();
$yaml = new Yaml();
$conf = new Configuration($yaml, $compiler, $config, $compiled, false);
$this->assertFalse($conf->isSetup());
$conf->initialize();
$this->assertTrue($conf->isSetup());
}
public function testSetdefault()
{
$configFile = __DIR__ . '/Fixtures/configuration.yml';
$compiled = $this->compiled;
$compiler = new Compiler();
$yaml = new Yaml();
$conf = new Configuration($yaml, $compiler, $configFile, $compiled, false);
$conf->initialize();
$config = $conf->getConfig();
unset($config['main']);
$conf->setConfig($config);
$updated = $yaml->parse($configFile);
$this->assertFalse(isset($updated['main']));
$conf->setDefault('main');
$updated = $yaml->parse($configFile);
$this->assertTrue(isset($updated['main']));
}
public function testSetdefaultRecursive()
{
$configFile = __DIR__ . '/Fixtures/configuration.yml';
$compiled = $this->compiled;
$compiler = new Compiler();
$yaml = new Yaml();
$conf = new Configuration($yaml, $compiler, $configFile, $compiled, false);
$conf->initialize();
$config = $conf->getConfig();
unset($config['main']['cache']);
$conf->setConfig($config);
$updated = $yaml->parse($configFile);
$this->assertFalse(isset($updated['main']['cache']));
$conf->setDefault('main', 'cache');
$updated = $yaml->parse($configFile);
$this->assertTrue(isset($updated['main']['cache']));
}
/**
* @expectedException \Alchemy\Phrasea\Exception\InvalidArgumentException
*/
public function testSetdefaultInvalidKey()
{
$configFile = __DIR__ . '/Fixtures/configuration.yml';
$compiled = $this->compiled;
$compiler = new Compiler();
$yaml = new Yaml();
$conf = new Configuration($yaml, $compiler, $configFile, $compiled, false);
$conf->setDefault('unexistant key');
}
public function testGetConfig()
{
$configFile = __DIR__ . '/Fixtures/configuration.yml';
$compiled = $this->compiled;
$compiler = new Compiler();
$yaml = new Yaml();
$conf = new Configuration($yaml, $compiler, $configFile, $compiled, false);
$conf->initialize();
$updated = $yaml->parse(file_get_contents($configFile));
$this->assertEquals($updated, $conf->getConfig());
}
public function testSetConfig()
{
$configFile = __DIR__ . '/Fixtures/configuration.yml';
$compiled = $this->compiled;
$compiler = new Compiler();
$yaml = new Yaml();
$conf = new Configuration($yaml, $compiler, $configFile, $compiled, false);
$conf->setConfig(['main' => 'boule']);
$updated = $yaml->parse(file_get_contents($configFile));
$this->assertEquals(['main' => 'boule'], $conf->getConfig());
}
public function testCompilNever()
{
$configFile = __DIR__ . '/Fixtures/configuration.yml';
$compiled = $this->compiled;
$yaml = new Yaml();
$compiler = new Compiler();
file_put_contents($this->compiled, $compiler->compile($yaml->parse($configFile)));
$compiler = $this->getMockBuilder('Alchemy\Phrasea\Core\Configuration\Compiler')
->disableOriginalConstructor()
->getMock();
$compiler->expects($this->never())
->method('compile');
$yaml = $this->getMockBuilder('Symfony\Component\Yaml\Yaml')
->disableOriginalConstructor()
->getMock();
$yaml::staticExpects($this->never())
->method('parse');
$conf = new Configuration($yaml, $compiler, $configFile, $compiled, false);
$conf->getConfig();
$conf->getConfig();
$conf->getConfig();
$conf['main'];
$conf['main'];
$conf['main'];
}
public function testCompilInDebugMode()
{
$configFile = __DIR__ . '/Fixtures/configuration.yml';
$compiled = $this->compiled;
$yaml = new Yaml();
$compiler = new Compiler();
file_put_contents($this->compiled, $compiler->compile($yaml->parse($configFile)));
// compilation is older than config
touch($this->compiled, time()-2);
touch($configFile, time()-1);
clearstatcache();
$compiler = $this->getMockBuilder('Alchemy\Phrasea\Core\Configuration\Compiler')
->disableOriginalConstructor()
->getMock();
$compiler->expects($this->once())
->method('compile')
->with(['main' => 'tiptop'])
->will($this->returnValue('<?php return ["main" => "tiptop"];'));
$yaml = $this->getMockBuilder('Symfony\Component\Yaml\Yaml')
->disableOriginalConstructor()
->getMock();
$yaml::staticExpects($this->once())
->method('parse')
->will($this->returnValue(['main' => 'tiptop']));
$conf = new Configuration($yaml, $compiler, $configFile, $compiled, true);
$this->assertSame(['main' => 'tiptop'], $conf->getConfig());
$this->assertSame(['main' => 'tiptop'], $conf->getConfig());
$this->assertSame(['main' => 'tiptop'], $conf->getConfig());
$this->assertSame('tiptop', $conf['main']);
$this->assertSame('tiptop', $conf['main']);
$this->assertSame('tiptop', $conf['main']);
}
public function testGetTestConnectionConf()
{
$configFile = __DIR__ . '/Fixtures/configuration.yml';
$compiled = $this->compiled;
$yaml = new Yaml();
$compiler = new Compiler();
$conf = new Configuration($yaml, $compiler, $configFile, $compiled, true);
$data = $conf->getTestConnectionParameters();
$this->assertArrayHasKey('driver', $data);
$this->assertArrayHasKey('path', $data);
$this->assertArrayHasKey('charset', $data);
}
public function testCompileAndWrite()
{
$configFile = __DIR__ . '/Fixtures/configuration.yml';
$compiled = $this->compiled;
$yaml = new Yaml();
$compiler = new Compiler();
$conf = new Configuration($yaml, $compiler, $configFile, $compiled, false);
// triggers initialization
$this->assertFalse(isset($conf['bim']));
file_put_contents($configFile, "\nbim: bam\n", FILE_APPEND);
$this->assertFalse(isset($conf['bim']));
$conf->compileAndWrite();
$this->assertTrue(isset($conf['bim']));
$this->assertEquals('bam', $conf['bim']);
} }
} }

View File

@@ -0,0 +1,281 @@
<?php
namespace Alchemy\Tests\Phrasea\Core\Configuration;
use Alchemy\Phrasea\Core\Configuration\Configuration;
use Alchemy\Phrasea\Core\Configuration\Compiler;
use Symfony\Component\Yaml\Yaml;
abstract class ConfigurationTestCase extends \PhraseanetTestCase
{
protected $compiled;
public function setUp()
{
parent::setUp();
$this->compiled = __DIR__ . '/Fixtures/configuration-compiled.php';
$this->clean();
}
public function tearDown()
{
$this->clean();
parent::tearDown();
}
private function clean()
{
copy(__DIR__ . '/..' . Configuration::CONFIG_REF, __DIR__ . '/Fixtures/configuration.yml');
if (is_file($this->compiled)) {
unlink($this->compiled);
}
}
abstract protected function provideConfiguration($confFile, $compiledFile = null, Compiler $compiler = null, Yaml $yaml = null);
/**
* @expectedException \Alchemy\Phrasea\Exception\RuntimeException
*/
public function testGetConfigInvalidConfig()
{
$config = __DIR__ . '/Fixtures/configuration-unknown.yml';
$conf = $this->provideConfiguration($config);
$conf->getConfig();
}
public function testInitialize()
{
$configFile = __DIR__ . '/Fixtures/configuration-unknown.yml';
if (is_file($configFile)) {
unlink($configFile);
}
$compiled = $this->compiled;
$conf = $this->provideConfiguration($configFile);
$this->assertSame($conf, $conf->initialize());
$config = $conf->getConfig();
$this->assertArrayHasKey('main', $config);
$this->assertFileExists($compiled);
$this->assertFileExists($configFile);
unlink($configFile);
}
/**
* @expectedException \Alchemy\Phrasea\Exception\RuntimeException
*/
public function testInitializeWrongPath()
{
$configFile = __DIR__ . '/Fixtures/configuration.yml';
$compiled = __DIR__ . '/path/to/unknwon/folder/file.php';
$conf = $this->provideConfiguration($configFile, $compiled);
$conf->initialize();
}
public function testArrayAccess()
{
$config = __DIR__ . '/Fixtures/configuration.yml';
$yaml = new Yaml();
$conf = $this->provideConfiguration($config);
$this->assertEquals('sql-host', $conf['main']['database']['host']);
$conf['extra-key'] = 'extra-value';
$this->assertEquals('extra-value', $conf['extra-key']);
$updated = $yaml->parse($config);
$this->assertEquals('extra-value', $updated['extra-key']);
$this->assertTrue(isset($conf['extra-key']));
unset($conf['extra-key']);
$this->assertFalse(isset($conf['extra-key']));
$updated = $yaml->parse($config);
$this->assertFalse(isset($updated['extra-key']));
}
public function testDelete()
{
$config = __DIR__ . '/Fixtures/configuration.yml';
$compiled = $this->compiled;
$conf = $this->provideConfiguration($config);
$conf->initialize();
$conf->delete();
$this->assertFileNotExists($compiled);
}
public function testIsSetup()
{
$config = __DIR__ . '/Fixtures/configuration-setup.yml';
@unlink($config);
$conf = $this->provideConfiguration($config);
$this->assertFalse($conf->isSetup());
$conf->initialize();
$this->assertTrue($conf->isSetup());
}
public function testSetdefault()
{
$configFile = __DIR__ . '/Fixtures/configuration.yml';
$yaml = new Yaml();
$conf = $this->provideConfiguration($configFile);
$conf->initialize();
$config = $conf->getConfig();
unset($config['main']);
$conf->setConfig($config);
$updated = $yaml->parse($configFile);
$this->assertFalse(isset($updated['main']));
$conf->setDefault('main');
$updated = $yaml->parse($configFile);
$this->assertTrue(isset($updated['main']));
}
public function testSetdefaultRecursive()
{
$configFile = __DIR__ . '/Fixtures/configuration.yml';
$yaml = new Yaml();
$conf = $this->provideConfiguration($configFile);
$conf->initialize();
$config = $conf->getConfig();
unset($config['main']['cache']);
$conf->setConfig($config);
$updated = $yaml->parse($configFile);
$this->assertFalse(isset($updated['main']['cache']));
$conf->setDefault('main', 'cache');
$updated = $yaml->parse($configFile);
$this->assertTrue(isset($updated['main']['cache']));
}
/**
* @expectedException \Alchemy\Phrasea\Exception\InvalidArgumentException
*/
public function testSetdefaultInvalidKey()
{
$configFile = __DIR__ . '/Fixtures/configuration.yml';
$conf = $this->provideConfiguration($configFile);
$conf->setDefault('unexistant key');
}
public function testGetConfig()
{
$configFile = __DIR__ . '/Fixtures/configuration.yml';
$yaml = new Yaml();
$conf = $this->provideConfiguration($configFile);
$conf->initialize();
$updated = $yaml->parse(file_get_contents($configFile));
$this->assertEquals($updated, $conf->getConfig());
}
public function testSetConfig()
{
$configFile = __DIR__ . '/Fixtures/configuration.yml';
$yaml = new Yaml();
$conf = $this->provideConfiguration($configFile);
$conf->setConfig(['main' => 'boule']);
$updated = $yaml->parse(file_get_contents($configFile));
$this->assertEquals(['main' => 'boule'], $conf->getConfig());
}
public function testCompilNever()
{
$configFile = __DIR__ . '/Fixtures/configuration.yml';
$yaml = new Yaml();
$compiler = new Compiler();
file_put_contents($this->compiled, $compiler->compile($yaml->parse($configFile)));
$compiler = $this->getMockBuilder('Alchemy\Phrasea\Core\Configuration\Compiler')
->disableOriginalConstructor()
->getMock();
$compiler->expects($this->never())
->method('compile');
$yaml = $this->getMockBuilder('Symfony\Component\Yaml\Yaml')
->disableOriginalConstructor()
->getMock();
$yaml::staticExpects($this->never())
->method('parse');
$conf = $this->provideConfiguration($configFile, null, $compiler, $yaml);
$conf->getConfig();
$conf->getConfig();
$conf->getConfig();
$conf['main'];
$conf['main'];
$conf['main'];
}
public function testCompilInDebugMode()
{
$configFile = __DIR__ . '/Fixtures/configuration.yml';
$yaml = new Yaml();
$compiler = new Compiler();
file_put_contents($this->compiled, $compiler->compile($yaml->parse($configFile)));
// compilation is older than config
touch($this->compiled, time()-2);
touch($configFile, time()-1);
clearstatcache();
$compiler = $this->getMockBuilder('Alchemy\Phrasea\Core\Configuration\Compiler')
->disableOriginalConstructor()
->getMock();
$compiler->expects($this->once())
->method('compile')
->with(['main' => 'tiptop'])
->will($this->returnValue('<?php return ["main" => "tiptop"];'));
$yaml = $this->getMockBuilder('Symfony\Component\Yaml\Yaml')
->disableOriginalConstructor()
->getMock();
$yaml::staticExpects($this->once())
->method('parse')
->will($this->returnValue(['main' => 'tiptop']));
$conf = $this->provideConfiguration($configFile, null, $compiler, $yaml, true);
$this->assertSame(['main' => 'tiptop'], $conf->getConfig());
$this->assertSame(['main' => 'tiptop'], $conf->getConfig());
$this->assertSame(['main' => 'tiptop'], $conf->getConfig());
$this->assertSame('tiptop', $conf['main']);
$this->assertSame('tiptop', $conf['main']);
$this->assertSame('tiptop', $conf['main']);
}
public function testCompileAndWrite()
{
$configFile = __DIR__ . '/Fixtures/configuration.yml';
$conf = $this->provideConfiguration($configFile);
// triggers initialization
$this->assertFalse(isset($conf['bim']));
file_put_contents($configFile, "\nbim: bam\n", FILE_APPEND);
$this->assertFalse(isset($conf['bim']));
$conf->compileAndWrite();
$this->assertTrue(isset($conf['bim']));
$this->assertEquals('bam', $conf['bim']);
}
}

View File

@@ -28,6 +28,29 @@ main:
search-engine: search-engine:
type: Alchemy\Phrasea\SearchEngine\Phrasea\PhraseaEngine type: Alchemy\Phrasea\SearchEngine\Phrasea\PhraseaEngine
options: [] options: []
task-manager:
status: started
logger:
max-files: 10
enabled: true
level: INFO
listener:
protocol: tcp
host: 127.0.0.1
port: 6660
linger: 500
websocket-server:
host: local.phrasea
port: 9090
ip: 0.0.0.0
subscriber:
protocol: tcp
host: 127.0.0.1
port: 13598
session:
type: 'file'
options: []
ttl: 86400
binaries: binaries:
ghostscript_binary: null ghostscript_binary: null
php_binary: null php_binary: null
@@ -75,6 +98,7 @@ debugger:
allowed-ips: [] allowed-ips: []
border-manager: border-manager:
enabled: true enabled: true
extension-mapping: { }
checkers: checkers:
- -
type: Checker\Sha256 type: Checker\Sha256

View File

@@ -0,0 +1,275 @@
servername: 'http://local.phrasea/'
languages:
available: []
default: 'fr'
hosts-configuration:
dedicated:
servername: 'http://local.dedicated-host'
main:
maintenance: true
registry:
general:
title: Hosted Man !
border-manager:
enabled: false
main:
maintenance: false
database:
host: 'sql-host'
port: 3306
user: 'sql-user'
password: 'sql-password'
dbname: ab_phraseanet
driver: pdo_mysql
charset: UTF8
database-test:
driver: pdo_sqlite
path: '/tmp/db.sqlite'
charset: UTF8
api-timers: false
cache:
type: MemcacheCache
options:
host: localhost
port: 11211
opcodecache:
type: ArrayCache
options: []
search-engine:
type: Alchemy\Phrasea\SearchEngine\Phrasea\PhraseaEngine
options: []
task-manager:
status: started
logger:
max-files: 10
enabled: true
level: INFO
listener:
protocol: tcp
host: 127.0.0.1
port: 6660
linger: 500
websocket-server:
host: local.phrasea
port: 9090
ip: 0.0.0.0
subscriber:
protocol: tcp
host: 127.0.0.1
port: 13598
session:
type: 'file'
options: []
ttl: 86400
binaries:
ghostscript_binary: null
php_binary: null
swf_extract_binary: null
pdf2swf_binary: null
swf_render_binary: null
unoconv_binary: null
ffmpeg_binary: null
ffprobe_binary: null
mp4box_binary: null
pdftotext_binary: null
recess_binary: null
phraseanet_indexer: null
ffmpeg_timeout: 3600
ffprobe_timeout: 60
gs_timeout: 60
mp4box_timeout: 60
swftools_timeout: 60
unoconv_timeout: 60
task-manager:
status: started
listener:
protocol: tcp
host: 127.0.0.1
port: 6700
storage:
subdefs:
default-dir: null
bridge:
youtube:
enabled: false
client_id: null
client_secret: null
developer_key: null
flickr:
enabled: false
client_id: null
client_secret: null
dailymotion:
enabled: false
client_id: null
client_secret: null
trusted-proxies: []
debugger:
allowed-ips: []
border-manager:
enabled: true
extension-mapping: { }
checkers:
-
type: Checker\Sha256
enabled: true
-
type: Checker\UUID
enabled: true
-
type: Checker\Colorspace
enabled: false
options:
colorspaces: [cmyk, grayscale, rgb]
-
type: Checker\Dimension
enabled: false
options:
width: 80
height: 160
-
type: Checker\Extension
enabled: false
options:
extensions: [jpg, jpeg, bmp, tif, gif, png, pdf, doc, odt, mpg, mpeg, mov, avi, xls, flv, mp3, mp2]
-
type: Checker\Filename
enabled: false
options:
sensitive: true
-
type: Checker\MediaType
enabled: false
options:
mediatypes: [Audio, Document, Flash, Image, Video]
authentication:
auto-create:
templates: { }
captcha:
enabled: true
trials-before-display: 9
providers:
facebook:
enabled: false
options:
app-id: ''
secret: ''
twitter:
enabled: false
options:
consumer-key: ''
consumer-secret: ''
google-plus:
enabled: false
options:
client-id: ''
client-secret: ''
github:
enabled: false
options:
client-id: ''
client-secret: ''
viadeo:
enabled: false
options:
client-id: ''
client-secret: ''
linkedin:
enabled: false
options:
client-id: ''
client-secret: ''
registration-fields:
-
name: company
required: true
-
name: firstname
required: true
-
name: geonameid
required: true
xsendfile:
enabled: false
type: nginx
mapping: []
plugins: []
registry:
general:
title: SuperPhraseanet
keywords: ''
description: ''
analytics: ''
allow-indexation: true
home-presentation-mode: COOLIRIS
modules:
thesaurus: true
stories: true
doc-substitution: false
thumb-substitution: false
anonymous-report: false
actions:
download-max-size: 120
validation-reminder-days: 2
validation-expiration-days: 10
auth-required-for-export: true
tou-validation-required-for-export: false
export-title-choice: false
default-export-title: support@alchemy.fr
social-tools: none
ftp:
ftp-enabled: true
ftp-user-access: false
registration:
auto-select-collections: true
auto-register-enabled: false
classic:
search-tab: 1
adv-search-tab: 2
topics-tab: 0
active-tab: 1
render-topics: tree
stories-preview: true
basket-rollover: true
collection-presentation: checkbox
basket-size-display: true
auto-show-proposals: true
collection-display: true
maintenance:
message: 'May the force be with you'
enabled: false
api-clients:
navigator-enabled: false
office-enabled: true
webservices:
google-charts-enabled: true
geonames-server: 'http://geonames.alchemyasp.com/'
captchas-enabled: false
recaptcha-public-key: ''
recaptcha-private-key: ''
captcha-enabled: false
executables:
h264-streaming-enabled: false
auth-token-directory: ''
auth-token-directory-path: ''
auth-token-passphrase: ''
php-conf-path: ''
imagine-driver: ''
ffmpeg-threads: 2
pdf-max-pages: 5
searchengine:
min-letters-truncation: 1
default-query: all
default-query-type: '0'
email:
emitter-email: phraseanet@example.com
prefix: ''
smtp-enabled: false
smtp-auth-enabled: false
smtp-host: ''
smtp-port: ''
smtp-secure-mode: '0'
smtp-user: ''
smtp-password: ''
admin-email: support@alchemy.fr
user-settings: { }

View File

@@ -28,6 +28,29 @@ main:
search-engine: search-engine:
type: Alchemy\Phrasea\SearchEngine\Phrasea\PhraseaEngine type: Alchemy\Phrasea\SearchEngine\Phrasea\PhraseaEngine
options: [] options: []
task-manager:
status: started
logger:
max-files: 10
enabled: true
level: INFO
listener:
protocol: tcp
host: 127.0.0.1
port: 6660
linger: 500
websocket-server:
host: local.phrasea
port: 9090
ip: 0.0.0.0
subscriber:
protocol: tcp
host: 127.0.0.1
port: 13598
session:
type: 'file'
options: []
ttl: 86400
binaries: binaries:
ghostscript_binary: null ghostscript_binary: null
php_binary: null php_binary: null
@@ -75,6 +98,7 @@ debugger:
allowed-ips: [] allowed-ips: []
border-manager: border-manager:
enabled: true enabled: true
extension-mapping: { }
checkers: checkers:
- -
type: Checker\Sha256 type: Checker\Sha256

View File

@@ -0,0 +1,52 @@
<?php
namespace Alchemy\Tests\Phrasea\Core\Configuration;
use Alchemy\Phrasea\Core\Configuration\Compiler;
use Alchemy\Phrasea\Core\Configuration\Configuration;
use Alchemy\Phrasea\Core\Configuration\HostConfiguration;
use Symfony\Component\Yaml\Yaml;
class HostConfigurationTest extends ConfigurationTestCase
{
protected function provideConfiguration($confFile, $compiledFile = null, Compiler $compiler = null, Yaml $yaml = null, $autoreload = false)
{
if (null === $compiledFile) {
$compiledFile = $this->compiled;
}
if (null === $yaml) {
$yaml = new Yaml();
}
if (null === $compiler) {
$compiler = new Compiler();
}
return new HostConfiguration(
new Configuration($yaml, $compiler, $confFile, $compiledFile, $autoreload)
);
}
public function testSetHost()
{
$conf = $this->provideConfiguration(__DIR__ . '/Fixtures/configuration-with-hosts.yml');
$conf->setHost('http://local.dedicated-host');
$this->assertEquals('Hosted Man !', \igorw\get_in($conf->getConfig(), ['registry', 'general', 'title']));
$this->assertEquals('http://local.dedicated-host', \igorw\get_in($conf->getConfig(), ['servername']));
$this->assertFalse(\igorw\get_in($conf->getConfig(), ['main', 'maintenance']));
$this->assertFalse(\igorw\get_in($conf->getConfig(), ['border-manager', 'enabled']));
$conf->setHost('local.dedicated-host');
$this->assertEquals('Hosted Man !', \igorw\get_in($conf->getConfig(), ['registry', 'general', 'title']));
$this->assertEquals('http://local.dedicated-host', \igorw\get_in($conf->getConfig(), ['servername']));
$this->assertFalse(\igorw\get_in($conf->getConfig(), ['main', 'maintenance']));
$this->assertFalse(\igorw\get_in($conf->getConfig(), ['border-manager', 'enabled']));
$conf->setHost(null);
$this->assertEquals('SuperPhraseanet', \igorw\get_in($conf->getConfig(), ['registry', 'general', 'title']));
$this->assertEquals('http://local.phrasea/', \igorw\get_in($conf->getConfig(), ['servername']));
$this->assertFalse(\igorw\get_in($conf->getConfig(), ['main', 'maintenance']));
$this->assertTrue(\igorw\get_in($conf->getConfig(), ['border-manager', 'enabled']));
}
}

View File

@@ -17,7 +17,7 @@ class ConfigurationServiceProviderTest extends ServiceProviderTestCase
[ [
'Alchemy\Phrasea\Core\Provider\ConfigurationServiceProvider', 'Alchemy\Phrasea\Core\Provider\ConfigurationServiceProvider',
'configuration.store', 'configuration.store',
'Alchemy\\Phrasea\\Core\\Configuration\\Configuration' 'Alchemy\\Phrasea\\Core\\Configuration\\HostConfiguration'
], ],
[ [
'Alchemy\Phrasea\Core\Provider\ConfigurationServiceProvider', 'Alchemy\Phrasea\Core\Provider\ConfigurationServiceProvider',
@@ -27,7 +27,7 @@ class ConfigurationServiceProviderTest extends ServiceProviderTestCase
[ [
'Alchemy\Phrasea\Core\Provider\ConfigurationServiceProvider', 'Alchemy\Phrasea\Core\Provider\ConfigurationServiceProvider',
'phraseanet.configuration', 'phraseanet.configuration',
'Alchemy\\Phrasea\\Core\\Configuration\\Configuration' 'Alchemy\\Phrasea\\Core\\Configuration\\HostConfiguration'
], ],
[ [
'Alchemy\Phrasea\Core\Provider\ConfigurationServiceProvider', 'Alchemy\Phrasea\Core\Provider\ConfigurationServiceProvider',

View File

@@ -9,6 +9,6 @@ class PhraseaConfigurationPanelTest extends ConfigurationPanelAbstractTest
{ {
public function getPanel() public function getPanel()
{ {
return new ConfigurationPanel(new PhraseaEngine(self::$DI['app']), self::$DI['app']['configuration.store']); return new ConfigurationPanel(new PhraseaEngine(self::$DI['app']), self::$DI['app']['conf']);
} }
} }

View File

@@ -9,7 +9,7 @@ class SphinxSearchConfigurationPanelTest extends ConfigurationPanelAbstractTest
{ {
public function getPanel() public function getPanel()
{ {
return new ConfigurationPanel(new SphinxSearchEngine(self::$DI['app'], 'localhost', 9306, 'localhost', 9308), self::$DI['app']['configuration.store']); return new ConfigurationPanel(new SphinxSearchEngine(self::$DI['app'], 'localhost', 9306, 'localhost', 9308), self::$DI['app']['conf']);
} }
public function testGetAVailableCharsets() public function testGetAVailableCharsets()

View File

@@ -43,7 +43,7 @@ abstract class EditorTestCase extends \PhraseanetTestCase
$editor = $this->getEditor(); $editor = $this->getEditor();
$dom = new \DOMDocument(); $dom = new \DOMDocument();
$dom->strictErrorChecking = true; $dom->strictErrorChecking = true;
$this->assertTrue(false !== $dom->loadXML($editor->getDefaultSettings(self::$DI['app']['configuration.store']))); $this->assertTrue(false !== $dom->loadXML($editor->getDefaultSettings(self::$DI['app']['conf'])));
} }
public function testGetDefaultSettingsWithoutConfiguration() public function testGetDefaultSettingsWithoutConfiguration()

View File

@@ -2,6 +2,7 @@
namespace Alchemy\Tests\Phrasea\TaskManager; namespace Alchemy\Tests\Phrasea\TaskManager;
use Alchemy\Phrasea\Core\Configuration\PropertyAccess;
use Alchemy\Phrasea\TaskManager\TaskManagerStatus; use Alchemy\Phrasea\TaskManager\TaskManagerStatus;
use Alchemy\Tests\Phrasea\MockArrayConf; use Alchemy\Tests\Phrasea\MockArrayConf;
@@ -16,7 +17,7 @@ class TaskManagerStatusTest extends \PhraseanetTestCase
$expected = $conf->getConfig(); $expected = $conf->getConfig();
$expected['main']['task-manager']['status'] = TaskManagerStatus::STATUS_STARTED; $expected['main']['task-manager']['status'] = TaskManagerStatus::STATUS_STARTED;
$status = new TaskManagerStatus($conf); $status = new TaskManagerStatus(new PropertyAccess($conf));
$status->start(); $status->start();
$this->assertEquals($expected, $conf->getConfig()); $this->assertEquals($expected, $conf->getConfig());
@@ -45,7 +46,7 @@ class TaskManagerStatusTest extends \PhraseanetTestCase
$expected = $conf->getConfig(); $expected = $conf->getConfig();
$expected['main']['task-manager']['status'] = TaskManagerStatus::STATUS_STOPPED; $expected['main']['task-manager']['status'] = TaskManagerStatus::STATUS_STOPPED;
$status = new TaskManagerStatus($conf); $status = new TaskManagerStatus(new PropertyAccess($conf));
$status->stop(); $status->stop();
$this->assertEquals($expected, $conf->getConfig()); $this->assertEquals($expected, $conf->getConfig());
@@ -56,7 +57,7 @@ class TaskManagerStatusTest extends \PhraseanetTestCase
*/ */
public function testIsRunning($data, $expectedStatus, $isRunning) public function testIsRunning($data, $expectedStatus, $isRunning)
{ {
$conf = new MockArrayConf($data); $conf = new PropertyAccess(new MockArrayConf($data));
$status = new TaskManagerStatus($conf); $status = new TaskManagerStatus($conf);
$this->assertEquals($isRunning, $status->isRunning()); $this->assertEquals($isRunning, $status->isRunning());
} }
@@ -77,7 +78,7 @@ class TaskManagerStatusTest extends \PhraseanetTestCase
*/ */
public function testGetStatus($data, $expectedStatus, $isRunning) public function testGetStatus($data, $expectedStatus, $isRunning)
{ {
$conf = new MockArrayConf($data); $conf = new PropertyAccess(new MockArrayConf($data));
$status = new TaskManagerStatus($conf); $status = new TaskManagerStatus($conf);
$this->assertEquals($expectedStatus, $status->getStatus()); $this->assertEquals($expectedStatus, $status->getStatus());
} }

View File

@@ -15,10 +15,15 @@ class patch_380alpha3bTest extends \PhraseanetTestCase
$app = self::$DI['app']; $app = self::$DI['app'];
$app['configuration.store'] = $this->getMock('Alchemy\Phrasea\Core\Configuration\ConfigurationInterface'); $app['conf'] = $this->getMockBuilder('Alchemy\Phrasea\Core\Configuration\PropertyAccess')
$app['configuration.store']->expects($this->once()) ->disableOriginalConstructor()
->method('setDefault') ->getMock();
->with('main', 'search-engine'); $app['conf']->expects($this->once())
->method('set')
->with(['main', 'search-engine'], [
'type' => 'Alchemy\Phrasea\SearchEngine\Phrasea\PhraseaEngine',
'options' => [],
]);
$this->assertTrue($patch->apply($appbox, $app)); $this->assertTrue($patch->apply($appbox, $app));
} }