<?php
declare(strict_types=1);
/**
* Pimcore
*
* This source file is available under two different licenses:
* - GNU General Public License version 3 (GPLv3)
* - Pimcore Commercial License (PCL)
* Full copyright and license information is available in
* LICENSE.md which is distributed with this source code.
*
* @copyright Copyright (c) Pimcore GmbH (http://www.pimcore.org)
* @license http://www.pimcore.org/license GPLv3 and PCL
*/
namespace Pimcore\Extension\Bundle\Config;
use Pimcore\Config as PimcoreConfig;
use Pimcore\Extension\Config;
use Symfony\Component\OptionsResolver\Options;
use Symfony\Component\OptionsResolver\OptionsResolver;
/**
* @internal
*
* @deprecated
*/
final class StateConfig
{
/**
* @var OptionsResolver
*/
private static $optionsResolver;
/**
* @var array
*/
private static $optionDefaults = [
'enabled' => false,
'priority' => 10,
'environments' => [],
];
/**
* @var Config
*/
private $config;
/**
* @param Config $config
*/
public function __construct(Config $config)
{
$this->config = $config;
}
/**
* Lists enabled bundles from config
*
* @return array
*/
public function getEnabledBundles(): array
{
$result = [];
$bundles = $this->getBundlesFromConfig();
foreach ($bundles as $bundleName => $options) {
if ($options['enabled']) {
$result[$bundleName] = $options;
}
}
return $result;
}
/**
* Lists enabled bundle names from config
*
* @return array
*/
public function getEnabledBundleNames(): array
{
return array_keys($this->getEnabledBundles());
}
/**
* Loads bundles which are defined in configuration
*
* @return array
*/
private function getBundlesFromConfig(): array
{
$config = $this->config->loadConfig();
if (!isset($config->bundle)) {
return [];
}
$bundles = $config->bundle->toArray();
$result = [];
foreach ($bundles as $bundleName => $options) {
$result[$bundleName] = $this->normalizeOptions($options);
}
return $result;
}
/**
* Returns the normalized bundle state from the extension manager config
*
* @param string $bundle
*
* @return array
*/
public function getState(string $bundle): array
{
$bundles = $this->getBundlesFromConfig();
if (isset($bundles[$bundle])) {
return $bundles[$bundle];
}
return $this->normalizeOptions([]);
}
/**
* Sets the normalized bundle state on the extension manager config
*
* @param string $bundle
* @param array $options
*/
public function setState(string $bundle, array $options)
{
$config = $this->config->loadConfig();
$this->updateBundleState($config, $bundle, $options);
$this->config->saveConfig($config);
}
/**
* Batch update bundle states
*
* @param array $states
*/
public function setStates(array $states)
{
$config = $this->config->loadConfig();
foreach ($states as $bundle => $options) {
$this->updateBundleState($config, $bundle, $options);
}
$this->config->saveConfig($config);
}
private function updateBundleState(PimcoreConfig\Config $config, string $bundle, array $options)
{
if (!isset($config->bundle)) {
$config->bundle = new PimcoreConfig\Config([], true);
}
$state = [];
if (isset($config->bundle->$bundle)) {
$currentState = $config->bundle->$bundle;
if ($currentState instanceof PimcoreConfig\Config) {
$currentState = $currentState->toArray();
}
$state = $this->normalizeOptions($currentState);
}
$state = array_merge($state, $options);
$state = $this->prepareWriteOptions($state);
$config->bundle->$bundle = $state;
}
/**
* Prepares options for writing. If all options besides enabled are the same as the default
* value, just the state will be written as bool,
*
* @param array $options
*
* @return array|bool
*/
private function prepareWriteOptions(array $options)
{
$options = $this->normalizeOptions($options);
$isDefault = true;
foreach (array_keys(self::$optionDefaults) as $option) {
if ('enabled' === $option) {
continue;
}
if ($options[$option] !== static::$optionDefaults[$option]) {
$isDefault = false;
break;
}
}
if ($isDefault) {
return $options['enabled'];
}
return $options;
}
/**
* Normalizes options array as expected in extension manager config
*
* @param array|bool $options
*
* @return array
*/
public function normalizeOptions($options): array
{
if (is_bool($options)) {
$options = ['enabled' => $options];
} elseif (!is_array($options)) {
throw new \InvalidArgumentException(sprintf(
'Expected options as bool or as array, but got %s',
get_debug_type($options)
));
}
$resolver = self::getOptionsResolver();
$options = $resolver->resolve($options);
return $options;
}
private static function getOptionsResolver(): OptionsResolver
{
if (null !== self::$optionsResolver) {
return self::$optionsResolver;
}
$resolver = new OptionsResolver();
$resolver->setDefaults(self::$optionDefaults);
$resolver->setRequired(array_keys(self::$optionDefaults));
$resolver->setAllowedTypes('enabled', 'bool');
$resolver->setAllowedTypes('priority', 'int');
$resolver->setAllowedTypes('environments', 'array');
$resolver->setNormalizer('environments', function (Options $options, $value) {
// normalize to string and trim
$value = array_map(function ($item) {
$item = (string)$item;
$item = trim($item);
return $item;
}, $value);
// remove empty values
$value = array_filter($value, function ($item) {
return !empty($item);
});
return $value;
});
self::$optionsResolver = $resolver;
return self::$optionsResolver;
}
}