mirror of
https://github.com/alchemy-fr/Phraseanet.git
synced 2025-10-16 14:33:14 +00:00
add configuration systeme
This commit is contained in:
@@ -24,7 +24,13 @@ require_once __DIR__ . '/../../vendor/Silex/vendor/pimple/lib/Pimple.php';
|
||||
class Core extends \Pimple
|
||||
{
|
||||
|
||||
public function __construct($isDev = false)
|
||||
/**
|
||||
*
|
||||
* @var Core\Configuration
|
||||
*/
|
||||
private $conf;
|
||||
|
||||
public function __construct($env)
|
||||
{
|
||||
|
||||
/**
|
||||
@@ -32,14 +38,18 @@ class Core extends \Pimple
|
||||
*/
|
||||
static::initAutoloads();
|
||||
|
||||
|
||||
$this->conf = new Core\Configuration($env);
|
||||
|
||||
$this['Version'] = $this->share(function()
|
||||
{
|
||||
return new Core\Version();
|
||||
});
|
||||
|
||||
$this['EM'] = $this->share(function()
|
||||
|
||||
$conf = $this->conf;
|
||||
$this['EM'] = $this->share(function() use ($conf)
|
||||
{
|
||||
$doctrine = new Core\Service\Doctrine();
|
||||
$doctrine = new Core\Service\Doctrine($conf->getDoctrineConf());
|
||||
return $doctrine->getEntityManager();
|
||||
});
|
||||
|
||||
@@ -91,6 +101,20 @@ class Core extends \Pimple
|
||||
return;
|
||||
}
|
||||
|
||||
private function init()
|
||||
{
|
||||
if ($this->conf->debug)
|
||||
{
|
||||
ini_set('display_errors', 1);
|
||||
error_reporting(E_ALL);
|
||||
\Symfony\Component\HttpKernel\Debug\ErrorHandler::register();
|
||||
}
|
||||
else
|
||||
{
|
||||
ini_set('display_errors', 0);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return Request
|
||||
@@ -291,4 +315,14 @@ class Core extends \Pimple
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
public function getEnv()
|
||||
{
|
||||
return $this->env;
|
||||
}
|
||||
|
||||
public function isDebug()
|
||||
{
|
||||
return $this->conf->debug;
|
||||
}
|
||||
}
|
||||
|
203
lib/Alchemy/Phrasea/Core/Configuration.php
Normal file
203
lib/Alchemy/Phrasea/Core/Configuration.php
Normal file
@@ -0,0 +1,203 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Phraseanet
|
||||
*
|
||||
* (c) 2005-2010 Alchemy
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Alchemy\Phrasea\Core;
|
||||
|
||||
/**
|
||||
*
|
||||
* @package
|
||||
* @license http://opensource.org/licenses/gpl-3.0 GPLv3
|
||||
* @link www.phraseanet.com
|
||||
*/
|
||||
class Configuration
|
||||
{
|
||||
|
||||
public $debug = false;
|
||||
|
||||
protected $dbConf;
|
||||
protected $installed;
|
||||
|
||||
|
||||
public function __construct($envName)
|
||||
{
|
||||
$specifications = new Configuration\PhraseaConfiguration();
|
||||
$parser = new Configuration\Parser\Yaml();
|
||||
|
||||
$handler = new Configuration\EnvironnementHandler($specifications, $parser);
|
||||
|
||||
$configuration = $handler->handle($envName);
|
||||
|
||||
var_dump($configuration);
|
||||
|
||||
exit;
|
||||
}
|
||||
|
||||
public function getMainConfigFileName()
|
||||
{
|
||||
return 'config';
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return \SplFileObject
|
||||
*/
|
||||
public function getMainConfigFile()
|
||||
{
|
||||
return $this->mainConfigFile;
|
||||
}
|
||||
|
||||
public function getDoctrineConf()
|
||||
{
|
||||
return (array) $this->dbConf;
|
||||
}
|
||||
|
||||
public function isInstalled()
|
||||
{
|
||||
return $this->installed;
|
||||
}
|
||||
|
||||
private function loadEnvironnments($env)
|
||||
{
|
||||
$filename = $this->loadFileName($env);
|
||||
|
||||
if (!is_file($filename))
|
||||
throw new \InvalidArgumentException(sprintf('Config file %s do not exist', $filename));
|
||||
|
||||
$envConf = \Symfony\Component\Yaml\Yaml::parse($filename);
|
||||
|
||||
$this->envsConf[] = $envConf;
|
||||
|
||||
if (isset($envConf["extends"]))
|
||||
{
|
||||
$this->loadEnvironnments($envConf["extends"]);
|
||||
}
|
||||
else
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
private function substituteEnvConfToMainConf(Array $mainConf)
|
||||
{
|
||||
foreach (array_reverse($this->envsConf) as $env)
|
||||
{
|
||||
$this->conf = array_replace_recursive($this->conf, $env);
|
||||
}
|
||||
|
||||
$this->conf = array_replace_recursive($mainConf, $this->conf);
|
||||
}
|
||||
|
||||
private function loadFileName($env = 'main')
|
||||
{
|
||||
if ('main' === $env)
|
||||
{
|
||||
return sprintf('%s/%s.yml', $this->configFilePath, $this->getMainConfigFileName());
|
||||
}
|
||||
else
|
||||
{
|
||||
return sprintf('%s/%s_%s.yml', $this->configFilePath, $this->getMainConfigFileName(), $env);
|
||||
}
|
||||
}
|
||||
|
||||
private function getNoneReplacedPath()
|
||||
{
|
||||
return array(
|
||||
array('doctrine', 'dbal')
|
||||
);
|
||||
}
|
||||
|
||||
private function process($env)
|
||||
{
|
||||
$mainConf = \Symfony\Component\Yaml\Yaml::parse($this->loadFileName());
|
||||
|
||||
$this->loadEnvironnments($env);
|
||||
|
||||
$this->substituteEnvConfToMainConf($mainConf);
|
||||
|
||||
$path = array();
|
||||
|
||||
$excludedPath = $pathToProcess = $this->getNoneReplacedPath();
|
||||
|
||||
$confToChange = $this->conf;
|
||||
|
||||
foreach (array_reverse($this->envsConf) as $conf)
|
||||
{
|
||||
foreach ($pathToProcess as $key => $thePath)
|
||||
{
|
||||
$replaceValue = $this->getDataPath($conf, $thePath);
|
||||
|
||||
if (null !== $replaceValue)
|
||||
{
|
||||
$map = function($item, $key) use (&$confToChange, $replaceValue, &$map, &$path, $thePath)
|
||||
{
|
||||
if (count(array_diff($path, $thePath) === 0))
|
||||
{
|
||||
|
||||
$path[] = $key;
|
||||
$replace = function(&$searchArray, $path, $value, $depth = 0) use (&$replace)
|
||||
{
|
||||
foreach ($searchArray as $k => $v)
|
||||
{
|
||||
if ($k === $path[$depth])
|
||||
{
|
||||
array_shift($path);
|
||||
if (is_array($v) && count($path) !== 0)
|
||||
{
|
||||
$replace(&$searchArray[$k], $path, $value, $depth++);
|
||||
}
|
||||
else
|
||||
{
|
||||
$searchArray[$k] = $value;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
$replace($confToChange, $path, $replaceValue);
|
||||
}
|
||||
elseif (is_array($item))
|
||||
{
|
||||
$path[] = $key;
|
||||
array_walk($item, $map);
|
||||
}
|
||||
};
|
||||
|
||||
array_walk($this->conf, $map);
|
||||
unset($pathToProcess[$key]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function getDataPath(Array $data, Array $path)
|
||||
{
|
||||
$found = true;
|
||||
|
||||
for ($x = 0; ($x < count($path) && $found); $x++)
|
||||
{
|
||||
$key = $path[$x];
|
||||
|
||||
if (isset($data[$key]))
|
||||
{
|
||||
$data = $data[$key];
|
||||
}
|
||||
else
|
||||
{
|
||||
$found = false;
|
||||
}
|
||||
}
|
||||
|
||||
if ($found)
|
||||
return $data;
|
||||
else
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,79 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Phraseanet
|
||||
*
|
||||
* (c) 2005-2010 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;
|
||||
|
||||
/**
|
||||
*
|
||||
* @package
|
||||
* @license http://opensource.org/licenses/gpl-3.0 GPLv3
|
||||
* @link www.phraseanet.com
|
||||
*/
|
||||
|
||||
interface ConfigurationSpecification
|
||||
{
|
||||
/**
|
||||
* Keywords to detect extended file
|
||||
*/
|
||||
const EXTENDED_KEYWORD = 'extends';
|
||||
|
||||
/**
|
||||
* Return an array of paths that CAN'T be extended by ONLY one or more of their value
|
||||
* but must be fully replaced with new values
|
||||
*
|
||||
* example:
|
||||
* array(array('PATH', 'TO', 'MY', 'SCOPE1', array('SCOPE2')
|
||||
*
|
||||
* So $extendedConf['PATH']['TO']['MY']['SCOPE'] will fully replace
|
||||
* $mainConf['PATH']['TO']['MY']['SCOPE'];
|
||||
*
|
||||
* @return Array
|
||||
*/
|
||||
public function getNonExtendablePath();
|
||||
|
||||
/**
|
||||
* Return the configuration file from an environnment name
|
||||
*
|
||||
* @return \SplFileObject
|
||||
*/
|
||||
public function getConfFileFromEnvName($name);
|
||||
|
||||
/**
|
||||
* Return the path to the configuration file
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getConfigurationFilePath();
|
||||
|
||||
/**
|
||||
* Return the configurationFile extension
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getConfFileExtension();
|
||||
|
||||
/**
|
||||
* Check wether the environnement $env extends another one
|
||||
*
|
||||
* @param type $env
|
||||
* @return boolean
|
||||
*/
|
||||
public function isExtended(Array $env);
|
||||
|
||||
/**
|
||||
* Return the extends environnement name null if extends nothing
|
||||
*
|
||||
* @param Array an environnement
|
||||
* @return mixed|null
|
||||
*/
|
||||
public function getExtendedEnvName(Array $env);
|
||||
|
||||
}
|
204
lib/Alchemy/Phrasea/Core/Configuration/EnvironnementHandler.php
Normal file
204
lib/Alchemy/Phrasea/Core/Configuration/EnvironnementHandler.php
Normal file
@@ -0,0 +1,204 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Phraseanet
|
||||
*
|
||||
* (c) 2005-2010 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 \Symfony\Component\Yaml\Yaml;
|
||||
|
||||
/**
|
||||
*
|
||||
* @package
|
||||
* @license http://opensource.org/licenses/gpl-3.0 GPLv3
|
||||
* @link www.phraseanet.com
|
||||
*/
|
||||
class EnvironnementHandler
|
||||
{
|
||||
/**
|
||||
* Configuration file specification interface
|
||||
* @var ConfigurationSpecification
|
||||
*/
|
||||
protected $confSpecification;
|
||||
|
||||
/**
|
||||
* A file parser interface
|
||||
* @var Parser\ParserInterface
|
||||
*/
|
||||
protected $parser;
|
||||
|
||||
public function __construct(ConfigurationSpecification $configSpec, Parser\ParserInterface $parser)
|
||||
{
|
||||
$this->confSpecification = $configSpec;
|
||||
$this->parser = $parser;
|
||||
}
|
||||
|
||||
/**
|
||||
* Stacks all envrironnement in $env that extends the loaded configuration file
|
||||
*
|
||||
* @param SplFileObject $file File of the current loaded config file
|
||||
* @param array $envs A stack of conf environnments
|
||||
* @return array
|
||||
*/
|
||||
private function retrieveExtendedEnvFromFile(\SplFileObject $file, Array $envs = array())
|
||||
{
|
||||
$env = $this->parser->parse($file);
|
||||
|
||||
//stack current env to allEnvs
|
||||
$allEnvs[] = $env;
|
||||
|
||||
//check if the loaded environnement extends another configuration file
|
||||
if ($this->confSpecification->isExtended($env))
|
||||
{
|
||||
try
|
||||
{
|
||||
//get extended environnement name
|
||||
$envName = $this->confSpecification->getExtendedEnvName($env);
|
||||
//get extended configuration file
|
||||
$file = $this->confSpecification->getConfFileFromEnvName($envName);
|
||||
//recurse
|
||||
$this->retrieveExtendedEnvFromFile($file, $allEnvs);
|
||||
}
|
||||
catch (\Exception $e)
|
||||
{
|
||||
throw \Exception(sprintf("filename %s not found", $file->getPathname()));
|
||||
}
|
||||
}
|
||||
|
||||
return $allEnvs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the value of a specified data path
|
||||
*
|
||||
* @param array $data The array where the data are stored
|
||||
* @param array $path The Path as an array example : array('path', 'to', 'my', 'value')
|
||||
* @return mixed
|
||||
*/
|
||||
private function getDataPath(Array $data, Array $path)
|
||||
{
|
||||
$found = true;
|
||||
|
||||
for ($x = 0; ($x < count($path) && $found); $x++)
|
||||
{
|
||||
$key = $path[$x];
|
||||
|
||||
if (isset($data[$key]))
|
||||
{
|
||||
$data = $data[$key];
|
||||
}
|
||||
else
|
||||
{
|
||||
$found = false;
|
||||
}
|
||||
}
|
||||
|
||||
return $found ? $data : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle the configuration process and return the final configuration
|
||||
*
|
||||
* @param strinig $name the name of the loaded environnement
|
||||
* @return Array
|
||||
*/
|
||||
public function handle($name)
|
||||
{
|
||||
|
||||
//get the corresepondant file
|
||||
$file = $this->confSpecification->getConfFileFromEnvName($name);
|
||||
|
||||
//get all extended configuration from current env
|
||||
$allEnvs = $this->retrieveExtendedEnvFromFile($file);
|
||||
|
||||
//Last env is the main one
|
||||
$mainEnv = array_pop($allEnvs);
|
||||
|
||||
$excludedPath = $pathToprocess = $this->confSpecification->getNonExtendablePath();
|
||||
|
||||
//at least 2 envs and one path to process
|
||||
if (count($allEnvs) >= 1 && count($excludedPath) >= 1)
|
||||
{
|
||||
foreach ($allEnvs as $currentEnv) // run trought environnements
|
||||
{
|
||||
foreach ($pathToprocess as $kpath => $processedPath) //run throught path
|
||||
{
|
||||
$valueToReplace = $this->getDataPath($currentEnv, $processedPath); //retrive the value to replace
|
||||
|
||||
if (null !== $valueToReplace)
|
||||
{
|
||||
|
||||
// reset current path
|
||||
$currentPath = array();
|
||||
|
||||
//callback to iterate over the main conf environnement and replace value from extended file
|
||||
$map = function($item, $key) use (&$mainEnv, $valueToReplace, &$map, &$currentPath, $processedPath)
|
||||
{
|
||||
if (count(array_diff($processedPath, $currentPath)) === 0) // current path and processed path match
|
||||
{
|
||||
/**
|
||||
* Replace current value of the $currentpath in $searchArray by $value
|
||||
*/
|
||||
$replace = function(&$searchArray, $currentPath, $value) use (&$replace)
|
||||
{
|
||||
foreach ($searchArray as $k => $v)
|
||||
{
|
||||
if ($k === $currentPath[0])
|
||||
{
|
||||
array_shift($currentPath);
|
||||
|
||||
if (is_array($v) && count($currentPath) !== 0)
|
||||
{
|
||||
$replace(&$searchArray[$k], $currentPath, $value);
|
||||
}
|
||||
elseif (count($currentPath) === 0)
|
||||
{
|
||||
$searchArray[$k] = $value;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
$replace($mainEnv, $currentPath, $valueToReplace);
|
||||
}
|
||||
elseif (is_array($item)) // if current item is an array
|
||||
{
|
||||
$currentPath[] = $key; // add item's key to current path
|
||||
|
||||
array_walk($item, $map); // and dig into the current item
|
||||
}
|
||||
else //wrong path
|
||||
{
|
||||
$currentPath = array(); //reset
|
||||
}
|
||||
};
|
||||
|
||||
//run trough the main conf environnement
|
||||
array_walk($mainEnv, $map);
|
||||
|
||||
//once done
|
||||
//reduce the paths to process
|
||||
unset($pathToprocess[$kpath]);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(count($allEnvs) >= 1)
|
||||
{
|
||||
foreach($allEnvs as $extendedEnv)
|
||||
$mainEnv = array_replace_recursive($mainEnv, $extendedEnv);
|
||||
}
|
||||
|
||||
return $mainEnv;
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Phraseanet
|
||||
*
|
||||
* (c) 2005-2010 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\Parser;
|
||||
|
||||
/**
|
||||
*
|
||||
* @package
|
||||
* @license http://opensource.org/licenses/gpl-3.0 GPLv3
|
||||
* @link www.phraseanet.com
|
||||
*/
|
||||
|
||||
interface ParserInterface
|
||||
{
|
||||
/**
|
||||
* Parse the configuration file $file to an array
|
||||
*
|
||||
* @param \SplFileObject $file the file to parse
|
||||
* @return Array
|
||||
*/
|
||||
public function parse(\SplFileObject $file);
|
||||
}
|
39
lib/Alchemy/Phrasea/Core/Configuration/Parser/Yaml.php
Normal file
39
lib/Alchemy/Phrasea/Core/Configuration/Parser/Yaml.php
Normal file
@@ -0,0 +1,39 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Phraseanet
|
||||
*
|
||||
* (c) 2005-2010 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\Parser;
|
||||
|
||||
use Symfony\Component\Yaml\Yaml as SfYaml;
|
||||
/**
|
||||
*
|
||||
* @package
|
||||
* @license http://opensource.org/licenses/gpl-3.0 GPLv3
|
||||
* @link www.phraseanet.com
|
||||
*/
|
||||
|
||||
class Yaml implements ParserInterface
|
||||
{
|
||||
/**
|
||||
*
|
||||
* @Override
|
||||
*/
|
||||
public function parse(\SplFileObject $file)
|
||||
{
|
||||
try
|
||||
{
|
||||
return SfYaml::parse($file->getPathname());
|
||||
}
|
||||
catch(\Exception $e)
|
||||
{
|
||||
throw new \Exception(sprintf('Failed to parse the configuration file %s', $e->getMessage()));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,81 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Phraseanet
|
||||
*
|
||||
* (c) 2005-2010 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;
|
||||
|
||||
/**
|
||||
*
|
||||
* @package
|
||||
* @license http://opensource.org/licenses/gpl-3.0 GPLv3
|
||||
* @link www.phraseanet.com
|
||||
*/
|
||||
class PhraseaConfiguration implements ConfigurationSpecification
|
||||
{
|
||||
|
||||
/**
|
||||
*
|
||||
* @Override
|
||||
*/
|
||||
public function getNonExtendablePath()
|
||||
{
|
||||
return array('doctrine', 'dbal');
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @Override
|
||||
*/
|
||||
public function getConfFileFromEnvName($name)
|
||||
{
|
||||
return new \SplFileObject(sprintf("/%s/config_%s.%s"
|
||||
, $this->getConfigurationFilePath()
|
||||
, $name
|
||||
, $this->getConfFileExtension())
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @Override
|
||||
*/
|
||||
public function getConfigurationFilePath()
|
||||
{
|
||||
return __DIR__ . '/../../../../../config';
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @Override
|
||||
*/
|
||||
public function getConfFileExtension()
|
||||
{
|
||||
return 'yml';
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @Override
|
||||
*/
|
||||
public function isExtended(Array $env)
|
||||
{
|
||||
return isset($env[self::EXTENDED_KEYWORD]);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @Override
|
||||
*/
|
||||
public function getExtendedEnvName(Array $env)
|
||||
{
|
||||
return $this->isExtended($env) ? $env[self::EXTENDED_KEYWORD] : null;
|
||||
}
|
||||
|
||||
}
|
Reference in New Issue
Block a user