. */ namespace SP\Config; use DI\Container; use ReflectionObject; use SP\Core\Context\ContextInterface; use SP\Core\Exceptions\ConfigException; use SP\Core\Exceptions\FileNotFoundException; use SP\Services\Config\ConfigBackupService; use SP\Storage\XmlFileStorageInterface; use SP\Storage\XmlHandler; use SP\Util\Util; defined('APP_ROOT') || die(); /** * Esta clase es responsable de leer y escribir la configuración del archivo config.php */ class Config { /** * @var int */ private static $timeUpdated; /** * @var bool */ private static $configLoaded = false; /** * @var ConfigData */ private $configData; /** * @var XmlHandler */ private $fileStorage; /** * @var ContextInterface */ private $context; /** * @var Container */ private $dic; /** * Config constructor. * * @param XmlFileStorageInterface $fileStorage * @param ContextInterface $session * @param Container $dic * @throws ConfigException */ public function __construct(XmlFileStorageInterface $fileStorage, ContextInterface $session, Container $dic) { $this->context = $session; $this->fileStorage = $fileStorage; if (!self::$configLoaded) { $this->configData = new ConfigData(); $this->loadConfigFile(); self::$timeUpdated = $this->configData->getConfigDate(); self::$configLoaded = true; } $this->dic = $dic; } /** * Cargar el archivo de configuración * * @return ConfigData * @throws \SP\Core\Exceptions\ConfigException */ public function loadConfigFile() { ConfigUtil::checkConfigDir(); try { // Mapear el array de elementos de configuración con las propiedades de la clase configData $items = $this->fileStorage->load('config')->getItems(); $reflectionObject = new ReflectionObject($this->configData); foreach ($reflectionObject->getProperties() as $property) { $property->setAccessible(true); if (isset($items[$property->getName()])) { $property->setValue($this->configData, $items[$property->getName()]); } $property->setAccessible(false); } } catch (FileNotFoundException $e) { processException($e); $this->saveConfig($this->configData, false); } catch (\Exception $e) { processException($e); throw new ConfigException($e->getMessage(), ConfigException::CRITICAL, null, $e->getCode(), $e); } return $this->configData; } /** * Guardar la configuración * * @param ConfigData $configData * @param bool $backup * @return Config */ public function saveConfig(ConfigData $configData, $backup = true) { try { if ($backup) { $this->dic->get(ConfigBackupService::class) ->backup(); } $configData->setConfigDate(time()); $configData->setConfigSaver($this->context->getUserData()->getLogin()); $configData->setConfigHash(); $this->fileStorage->setItems($configData); $this->fileStorage->save('config'); } catch (\Exception $e) { processException($e); } return $this; } /** * @return int */ public static function getTimeUpdated() { return self::$timeUpdated; } /** * Commits a config data * * @param ConfigData $configData * @return Config */ public function updateConfig(ConfigData $configData) { $configData->setConfigDate(time()); $configData->setConfigSaver($this->context->getUserData()->getLogin()); $configData->setConfigHash(); $this->configData = $configData; self::$timeUpdated = $configData->getConfigDate(); return $this; } /** * Cargar la configuración desde el archivo * * @param ContextInterface $context * @param bool $reload * @return ConfigData */ public function loadConfig(ContextInterface $context, $reload = false) { $configData = $context->getConfig(); if ($reload === true || $configData === null || time() >= ($context->getConfigTime() + $configData->getSessionTimeout() / 2) ) { return $this->saveConfigInSession($context); } return $configData; } /** * Guardar la configuración en la sesión * * @param ContextInterface $context * @return ConfigData */ private function saveConfigInSession(ContextInterface $context) { $context->setConfig($this->configData); $context->setConfigTime(time()); return $this->configData; } /** * @return ConfigData */ public function getConfigData() { return clone $this->configData; } /** * @throws \Defuse\Crypto\Exception\EnvironmentIsBrokenException */ public function generateUpgradeKey() { if (empty($this->configData->getUpgradeKey())) { debugLog('Generating upgrade key'); return $this->saveConfig($this->configData->setUpgradeKey(Util::generateRandomBytes(16)), false); } return $this; } }