winter/modules/system/traits/ConfigMaker.php

165 lines
4.8 KiB
PHP
Raw Normal View History

2014-05-14 23:24:20 +10:00
<?php namespace System\Traits;
use Str;
use File;
use Lang;
2014-05-17 22:10:01 +10:00
use Event;
2014-05-14 23:24:20 +10:00
use October\Rain\Support\Yaml;
use System\Classes\SystemException;
use Backend\Classes\Controller;
2014-05-17 22:10:01 +10:00
use stdClass;
2014-05-14 23:24:20 +10:00
/**
* Config Maker Trait
* Adds configuration based methods to a class
*
* @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.
*/
protected $configPath;
2014-05-14 23:24:20 +10:00
/**
* Reads the contents of the supplied file and applies it to this object.
*/
public function makeConfig($configFile = [], $requiredConfig = [])
{
/*
* Config already made
2014-05-14 23:24:20 +10:00
*/
if (is_object($configFile)) {
$config = $configFile;
}
2014-05-14 23:24:20 +10:00
/*
* Embedded config
*/
elseif (is_array($configFile)) {
$config = $this->makeConfigFromArray($configFile);
}
2014-05-17 22:10:01 +10:00
/*
* Process config from file contents
2014-05-17 22:10:01 +10:00
*/
else {
if (isset($this->controller) && method_exists($this->controller, 'getConfigPath'))
$configFile = $this->controller->getConfigPath($configFile);
else
$configFile = $this->getConfigPath($configFile);
if (!File::isFile($configFile))
throw new SystemException(Lang::get('system::lang.config.not_found', ['file' => $configFile, 'location' => get_called_class()]));
$config = Yaml::parse(File::get($configFile));
/*
* Extensibility
*/
$publicFile = File::localToPublic($configFile);
if ($results = Event::fire('system.extendConfigFile', [$publicFile, $config])) {
foreach ($results as $result) {
if (!is_array($result)) continue;
$config = array_merge($config, $result);
}
2014-05-17 22:10:01 +10:00
}
$config = $this->makeConfigFromArray($config);
}
2014-05-14 23:24:20 +10:00
/*
* Validate required configuration
*/
2014-05-14 23:24:20 +10:00
foreach ($requiredConfig as $property) {
if (!property_exists($config, $property))
throw new SystemException(Lang::get('system::lang.config.required', ['property' => $property, 'location' => get_called_class()]));
}
return $config;
}
/**
* Makes a config object from an array, making the first level keys properties a new object.
* Property values are converted to camelCase and are not set if one already exists.
2014-05-17 18:08:01 +02:00
* @param array $configArray Config array.
2014-05-14 23:24:20 +10:00
* @return stdObject The config object
*/
public function makeConfigFromArray($configArray = [])
{
$object = new stdClass();
if (!is_array($configArray))
return $object;
foreach ($configArray as $name => $value) {
$_name = camel_case($name);
$object->{$name} = $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
* an "at symbol", it will be returned in context of the application base path,
* 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)
{
if (!isset($this->configPath))
$this->configPath = $this->guessConfigPath();
if (!$configPath)
$configPath = $this->configPath;
2014-09-29 12:32:41 +10:00
$fileName = File::symbolizePath($fileName, $fileName);
2014-05-14 23:24:20 +10:00
2014-09-29 12:59:14 +10:00
if (File::isLocalPath($fileName) || realpath($fileName) !== false)
2014-05-14 23:24:20 +10:00
return $fileName;
if (!is_array($configPath))
$configPath = [$configPath];
foreach ($configPath as $path) {
$_fileName = $path . '/' . $fileName;
if (File::isFile($_fileName))
break;
}
return $_fileName;
}
/**
* 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 = '')
{
$classFolder = strtolower(Str::getRealClass($class));
$classFile = realpath(dirname(File::fromClass($class)));
$guessedPath = $classFile ? $classFile . '/' . $classFolder . $suffix : null;
return $guessedPath;
}
2014-05-14 23:24:20 +10:00
}