2014-05-14 23:24:20 +10:00
|
|
|
<?php namespace System\Traits;
|
|
|
|
|
2015-02-13 22:57:55 +11:00
|
|
|
use Yaml;
|
2014-05-14 23:24:20 +10:00
|
|
|
use File;
|
|
|
|
use Lang;
|
2014-05-17 22:10:01 +10:00
|
|
|
use Event;
|
2015-01-28 18:03:35 +11:00
|
|
|
use SystemException;
|
2014-05-17 22:10:01 +10:00
|
|
|
use stdClass;
|
2018-07-05 14:07:38 -07:00
|
|
|
use Config;
|
2014-05-14 23:24:20 +10:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Config Maker Trait
|
|
|
|
* Adds configuration based methods to a class
|
|
|
|
*
|
2014-08-29 19:23:09 +10:00
|
|
|
* @package october\system
|
2014-05-14 23:24:20 +10:00
|
|
|
* @author Alexey Bobkov, Samuel Georges
|
|
|
|
*/
|
|
|
|
trait ConfigMaker
|
|
|
|
{
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @var string Specifies a path to the config directory.
|
|
|
|
*/
|
2014-08-03 11:57:51 +10:00
|
|
|
protected $configPath;
|
2014-05-14 23:24:20 +10:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Reads the contents of the supplied file and applies it to this object.
|
2016-01-23 15:37:15 -05:00
|
|
|
* @param array $configFile
|
|
|
|
* @param array $requiredConfig
|
|
|
|
* @return array|stdClass
|
2014-05-14 23:24:20 +10:00
|
|
|
*/
|
|
|
|
public function makeConfig($configFile = [], $requiredConfig = [])
|
|
|
|
{
|
2015-03-06 20:37:05 +11:00
|
|
|
if (!$configFile) {
|
|
|
|
$configFile = [];
|
|
|
|
}
|
|
|
|
|
2014-05-14 23:24:20 +10:00
|
|
|
/*
|
2014-06-20 17:59:19 +10:00
|
|
|
* Config already made
|
2014-05-14 23:24:20 +10:00
|
|
|
*/
|
2014-06-20 17:59:19 +10:00
|
|
|
if (is_object($configFile)) {
|
|
|
|
$config = $configFile;
|
2014-11-01 12:00:45 +11:00
|
|
|
}
|
2014-06-20 17:59:19 +10:00
|
|
|
/*
|
|
|
|
* Embedded config
|
|
|
|
*/
|
2014-11-01 12:00:45 +11:00
|
|
|
elseif (is_array($configFile)) {
|
2014-06-20 17:59:19 +10:00
|
|
|
$config = $this->makeConfigFromArray($configFile);
|
2014-11-01 12:00:45 +11:00
|
|
|
}
|
2014-05-17 22:10:01 +10:00
|
|
|
/*
|
2014-06-20 17:59:19 +10:00
|
|
|
* Process config from file contents
|
2014-05-17 22:10:01 +10:00
|
|
|
*/
|
2014-11-01 12:00:45 +11:00
|
|
|
else {
|
2014-10-18 11:58:50 +02:00
|
|
|
if (isset($this->controller) && method_exists($this->controller, 'getConfigPath')) {
|
2014-06-20 17:59:19 +10:00
|
|
|
$configFile = $this->controller->getConfigPath($configFile);
|
2014-11-01 12:00:45 +11:00
|
|
|
}
|
|
|
|
else {
|
2014-06-20 17:59:19 +10:00
|
|
|
$configFile = $this->getConfigPath($configFile);
|
2014-10-18 11:58:50 +02:00
|
|
|
}
|
2014-06-20 17:59:19 +10:00
|
|
|
|
2014-10-18 11:58:50 +02:00
|
|
|
if (!File::isFile($configFile)) {
|
|
|
|
throw new SystemException(Lang::get(
|
|
|
|
'system::lang.config.not_found',
|
|
|
|
['file' => $configFile, 'location' => get_called_class()]
|
|
|
|
));
|
|
|
|
}
|
2014-06-20 17:59:19 +10:00
|
|
|
|
|
|
|
$config = Yaml::parse(File::get($configFile));
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Extensibility
|
|
|
|
*/
|
|
|
|
$publicFile = File::localToPublic($configFile);
|
|
|
|
if ($results = Event::fire('system.extendConfigFile', [$publicFile, $config])) {
|
|
|
|
foreach ($results as $result) {
|
2014-10-18 11:58:50 +02:00
|
|
|
if (!is_array($result)) {
|
|
|
|
continue;
|
|
|
|
}
|
2014-06-20 17:59:19 +10:00
|
|
|
$config = array_merge($config, $result);
|
|
|
|
}
|
2014-05-17 22:10:01 +10:00
|
|
|
}
|
|
|
|
|
2014-06-20 17:59:19 +10:00
|
|
|
$config = $this->makeConfigFromArray($config);
|
|
|
|
}
|
2014-05-14 23:24:20 +10:00
|
|
|
|
2014-06-20 17:59:19 +10:00
|
|
|
/*
|
|
|
|
* Validate required configuration
|
|
|
|
*/
|
2014-05-14 23:24:20 +10:00
|
|
|
foreach ($requiredConfig as $property) {
|
2014-10-18 11:58:50 +02:00
|
|
|
if (!property_exists($config, $property)) {
|
|
|
|
throw new SystemException(Lang::get(
|
|
|
|
'system::lang.config.required',
|
|
|
|
['property' => $property, 'location' => get_called_class()]
|
|
|
|
));
|
|
|
|
}
|
2014-05-14 23:24:20 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
return $config;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2019-03-18 14:08:47 -06:00
|
|
|
* Makes a config object from an array, making the first level keys properties of a new object.
|
2019-07-18 22:50:37 +08:00
|
|
|
*
|
2014-05-17 18:08:01 +02:00
|
|
|
* @param array $configArray Config array.
|
2016-01-23 15:37:15 -05:00
|
|
|
* @return stdClass The config object
|
2014-05-14 23:24:20 +10:00
|
|
|
*/
|
|
|
|
public function makeConfigFromArray($configArray = [])
|
|
|
|
{
|
2016-02-13 14:41:17 +11:00
|
|
|
$object = new stdClass;
|
2014-05-14 23:24:20 +10:00
|
|
|
|
2014-10-18 11:58:50 +02:00
|
|
|
if (!is_array($configArray)) {
|
2014-05-14 23:24:20 +10:00
|
|
|
return $object;
|
2014-10-18 11:58:50 +02:00
|
|
|
}
|
2014-05-14 23:24:20 +10:00
|
|
|
|
|
|
|
foreach ($configArray as $name => $value) {
|
2019-03-18 14:08:47 -06:00
|
|
|
$object->{$name} = $value;
|
2014-05-14 23:24:20 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
return $object;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Locates a file based on it's definition. If the file starts with
|
2016-02-13 14:41:17 +11:00
|
|
|
* the ~ symbol it will be returned in context of the application base path,
|
2014-05-14 23:24:20 +10:00
|
|
|
* otherwise it will be returned in context of the config path.
|
|
|
|
* @param string $fileName File to load.
|
|
|
|
* @param mixed $configPath Explicitly define a config path.
|
|
|
|
* @return string Full path to the config file.
|
|
|
|
*/
|
|
|
|
public function getConfigPath($fileName, $configPath = null)
|
|
|
|
{
|
2014-10-18 11:58:50 +02:00
|
|
|
if (!isset($this->configPath)) {
|
2014-05-14 23:24:20 +10:00
|
|
|
$this->configPath = $this->guessConfigPath();
|
2014-10-18 11:58:50 +02:00
|
|
|
}
|
2014-05-14 23:24:20 +10:00
|
|
|
|
2014-10-18 11:58:50 +02:00
|
|
|
if (!$configPath) {
|
2014-05-14 23:24:20 +10:00
|
|
|
$configPath = $this->configPath;
|
2014-10-18 11:58:50 +02:00
|
|
|
}
|
2014-05-14 23:24:20 +10:00
|
|
|
|
2015-05-30 15:54:47 +10:00
|
|
|
$fileName = File::symbolizePath($fileName);
|
2014-05-14 23:24:20 +10:00
|
|
|
|
2018-07-05 14:07:38 -07:00
|
|
|
if (File::isLocalPath($fileName) ||
|
|
|
|
(!Config::get('cms.restrictBaseDir', true) && realpath($fileName) !== false)
|
|
|
|
) {
|
2014-05-14 23:24:20 +10:00
|
|
|
return $fileName;
|
2014-10-18 11:58:50 +02:00
|
|
|
}
|
2014-05-14 23:24:20 +10:00
|
|
|
|
2014-10-18 11:58:50 +02:00
|
|
|
if (!is_array($configPath)) {
|
2014-05-14 23:24:20 +10:00
|
|
|
$configPath = [$configPath];
|
2014-10-18 11:58:50 +02:00
|
|
|
}
|
2014-05-14 23:24:20 +10:00
|
|
|
|
|
|
|
foreach ($configPath as $path) {
|
|
|
|
$_fileName = $path . '/' . $fileName;
|
2014-10-18 11:58:50 +02:00
|
|
|
if (File::isFile($_fileName)) {
|
2016-01-23 15:37:15 -05:00
|
|
|
return $_fileName;
|
2014-10-18 11:58:50 +02:00
|
|
|
}
|
2014-05-14 23:24:20 +10:00
|
|
|
}
|
|
|
|
|
2016-02-13 14:41:17 +11:00
|
|
|
return $fileName;
|
2014-05-14 23:24:20 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Guess the package path for the called class.
|
|
|
|
* @param string $suffix An extra path to attach to the end
|
|
|
|
* @return string
|
|
|
|
*/
|
|
|
|
public function guessConfigPath($suffix = '')
|
|
|
|
{
|
|
|
|
$class = get_called_class();
|
|
|
|
return $this->guessConfigPathFrom($class, $suffix);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Guess the package path from a specified class.
|
|
|
|
* @param string $class Class to guess path from.
|
|
|
|
* @param string $suffix An extra path to attach to the end
|
|
|
|
* @return string
|
|
|
|
*/
|
|
|
|
public function guessConfigPathFrom($class, $suffix = '')
|
|
|
|
{
|
2014-09-29 13:12:34 +10:00
|
|
|
$classFolder = strtolower(class_basename($class));
|
2014-05-14 23:24:20 +10:00
|
|
|
$classFile = realpath(dirname(File::fromClass($class)));
|
2018-08-15 19:23:12 +02:00
|
|
|
return $classFile ? $classFile . '/' . $classFolder . $suffix : null;
|
2014-05-14 23:24:20 +10:00
|
|
|
}
|
2017-04-17 09:55:50 +10:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Merges two configuration sources, either prepared or not, and returns
|
|
|
|
* them as a single configuration object.
|
|
|
|
* @param mixed $configA
|
|
|
|
* @param mixed $configB
|
|
|
|
* @return stdClass The config object
|
|
|
|
*/
|
|
|
|
public function mergeConfig($configA, $configB)
|
|
|
|
{
|
|
|
|
$configA = $this->makeConfig($configA);
|
|
|
|
|
|
|
|
$configB = $this->makeConfig($configB);
|
|
|
|
|
|
|
|
return (object) array_merge((array) $configA, (array) $configB);
|
|
|
|
}
|
2014-10-18 11:58:50 +02:00
|
|
|
}
|