<?php
namespace WAM\Bundle\CoreBundle\DependencyInjection;
use phpDocumentor\Reflection\Types\Self_;
use Symfony\Component\Config\Definition\Builder\TreeBuilder;
use Symfony\Component\Config\Definition\ConfigurationInterface;
use WAM\Bundle\CoreBundle\Admin\CategoryAdmin;
use WAM\Bundle\CoreBundle\Admin\PopupAdmin;
use WAM\Bundle\CoreBundle\Admin\TagAdmin;
use WAM\Bundle\CoreBundle\Entity\Context;
use WAM\Bundle\CoreBundle\Exception\OptionsValidateException;
use WAM\Bundle\CoreBundle\Manager\CategoryManager;
use WAM\Bundle\CoreBundle\Manager\ContextManager;
use WAM\Bundle\CoreBundle\Manager\LocaleManager;
use WAM\Bundle\CoreBundle\Manager\PopupManager;
use WAM\Bundle\CoreBundle\Manager\TagManager;
use WAM\Bundle\CoreBundle\Model\Category;
use WAM\Bundle\CoreBundle\Model\Email;
use WAM\Bundle\CoreBundle\Model\Popup;
use WAM\Bundle\CoreBundle\Model\Tag;
use WAM\Bundle\CoreBundle\Util\NumberToken;
/**
* This is the class that validates and merges configuration from your app/config files.
*
* To learn more see {@link http://symfony.com/doc/current/cookbook/bundles/extension.html#cookbook-bundles-extension-config-class}
*/
class Configuration implements ConfigurationInterface
{
const SVG_PATH = '%kernel.root_dir%/Resources/frontend/svg/initial';
const ROBOTS_PATH = '%kernel.root_dir%/public/robots.txt';
const PDF_COMMAND_PATH = '/opt/wkhtmltox/bin/wkhtmltopdf.sh';
const COOKIES_CLASS = 'WAM\Bundle\CoreBundle\Entity\Cookies';
const COOKIES_ADMIN_CLASS = 'WAM\Bundle\CoreBundle\Admin\CookiesAdmin';
const DEFAULT_TAG_CLASS = Tag::class;
const DEFAULT_CATEGORY_CLASS = Category::class;
const DEFAULT_CONTEXT_CLASS = Context::class;
const DEFAULT_CATEGORY_CLASS_ADMIN = CategoryAdmin::class;
const DEFAULT_TAG_CLASS_ADMIN = TagAdmin::class;
const EMAIL_CLASS = Email::class;
const DEFAULT_LOCALE_MATRIX = [
'es' => [
'hreflang' => 'es_ES',
'url' => null,
'label' => 'EspaƱol',
],
];
const DEFAULT_LOCALES = ['es'];
const DEFAULT_LOCALE_SWITCHE_MODE = 'redirect_to_home';
const DEFAULT_ADMIN_LOCALE = 'es';
const DEFAULT_ADMIN_PATH = '/admin';
const DEFAULT_CONFIG_POPUP_ADMIN_CONTROLLER = 'SonataAdminBundle:CRUD';
const DEFAULT_CONFIG_POPUP_ADMIN_TRANSLATION = 'SonataAdminBundle';
const DEFAULT_CONFIG_ORM_ENABLED = true;
const DEFAULT_CONFIG_MODEL_MANAGER_NAME = 'default';
const DEFAULT_MIX_MANIFEST_PATH = '%kernel.project_dir%/public/mix-manifest.json';
const DEFAULT_TRANSLATIONS_PATH = '%kernel.project_dir%/public/translations.json';
/**
* {@inheritdoc}
*/
public function getConfigTreeBuilder()
{
$treeBuilder = new TreeBuilder();
$treeBuilder->root('wam_core')
->children()
->append($this->getLocaleNode())
->append($this->getAdminNode())
->append($this->getConfigNode())
->append($this->getCookiesNode())
->append($this->getEmailNode())
->append($this->getClassificationNode())
->append($this->getStringSequenceGeneratorsNode())
->arrayNode('preview')
->useAttributeAsKey('name')
->prototype('scalar')->end()
->end()
->arrayNode('mix')->addDefaultsIfNotSet()
->children()
->scalarNode('manifest_path')->defaultValue(self::DEFAULT_MIX_MANIFEST_PATH)->end()
->booleanNode('throw_exceptions')->defaultTrue()->end()
->end()
->end()
->scalarNode('privacy_menu_zone')->defaultValue('FORM_PRIVACY')->end()
->scalarNode('svg_folder_path')->defaultValue(self::SVG_PATH)->end()
->scalarNode('robots_path')->defaultValue(self::ROBOTS_PATH)->end()
->scalarNode('translations_path')->defaultValue(self::DEFAULT_TRANSLATIONS_PATH)->end()
->arrayNode('excluded_searchable_managers')->defaultValue([])
->prototype('scalar')->end()
->end()
->arrayNode('pdf')->addDefaultsIfNotSet()
->children()
->scalarNode('command_path')->defaultValue(self::PDF_COMMAND_PATH)
->isRequired()->cannotBeEmpty()
->end()
->end()
->end()
->end()
->end();
return $treeBuilder;
}
public function getCookiesNode()
{
$root = (new TreeBuilder())->root('cookies');
$root->addDefaultsIfNotSet()
->children()
->scalarNode('class')->defaultValue(self::COOKIES_CLASS)->end()
->scalarNode('admin_class')->defaultValue(self::COOKIES_ADMIN_CLASS)->end()
->end()
->end();
return $root;
}
public function getEmailNode()
{
$node = (new TreeBuilder())->root('email');
$node->addDefaultsIfNotSet()
->children()
->scalarNode('class')->defaultValue(self::EMAIL_CLASS)->end()
->arrayNode('types')
->useAttributeAsKey('event', false)
->defaultValue([])
->arrayPrototype()
->children()
->scalarNode('name')->end()
->scalarNode('template_path')->end()
->arrayNode('elements')
->arrayPrototype()
->children()
->scalarNode('name')->end()
->scalarNode('description')->end()
->scalarNode('type')->end()
->end()
->end()
->end()
->arrayNode('variables')
->arrayPrototype()
->children()
->scalarNode('name')->end()
->scalarNode('description')->end()
->end()
->end()
->end()
->end()
->end();
return $node;
}
public function getStringSequenceGeneratorsNode()
{
$root = (new TreeBuilder())->root('string_sequence_generators');
$root->addDefaultsIfNotSet([])
->children()
->arrayNode('sequences')
->useAttributeAsKey('name')
->arrayPrototype()
->children()
->arrayNode('tokens')->defaultValue([])
->prototype('array')
->validate()
->ifTrue(function ($value) {
if (isset($value['max_value'])) {
return NumberToken::class == $value['type']
and (strlen($value['max_value']) != strlen($value['base_value']));
}
return false;
})->thenInvalid('Config "max_value" has to length same as base_value')
->end()
->validate()
->ifTrue(function ($value) {
return NumberToken::class == $value['type']
and (!isset($value['max_value']) or !$value['max_value']);
})->thenInvalid('Config "max_value" for number tokens is required')
->end()
->children()
->scalarNode('token')->isRequired()->cannotBeEmpty()->end()
->scalarNode('type')->isRequired()->cannotBeEmpty()->end()
->scalarNode('base_value')->isRequired()->cannotBeEmpty()->end()
->scalarNode('max_value')->end()
->end()
->end()
->end()
->end()
->end()
->end();
return $root;
}
public function getClassificationNode()
{
$root = (new TreeBuilder())->root('classification');
$root->addDefaultsIfNotSet()
->children()
->arrayNode('class')->addDefaultsIfNotSet()
->children()
->scalarNode('tag')->cannotBeEmpty()
->defaultValue(self::DEFAULT_TAG_CLASS)->end()
->scalarNode('category')->cannotBeEmpty()
->defaultValue(self::DEFAULT_CATEGORY_CLASS)
->end()
->arrayNode('category_mapping')
->prototype('array')
->children()
->scalarNode('key')->end()
->scalarNode('name')->end()
->scalarNode('class')->end()
->end()
->end()
->end()
->scalarNode('context')->cannotBeEmpty()
->defaultValue(self::DEFAULT_CONTEXT_CLASS)->end()
->end()
->end()
->arrayNode('admin')->addDefaultsIfNotSet()
->children()
->scalarNode('tag')->cannotBeEmpty()
->defaultValue(self::DEFAULT_TAG_CLASS_ADMIN)->end()
->scalarNode('category')->cannotBeEmpty()
->defaultValue(self::DEFAULT_CATEGORY_CLASS_ADMIN)->end()
->end()
->end()
->end()
->end();
return $root;
}
public function getLocaleNode()
{
$node = (new TreeBuilder())->root('locale');
$node
->addDefaultsIfNotSet()
->children()
->arrayNode('locales')->defaultValue(self::DEFAULT_LOCALES)
->prototype('scalar')->end()
->end()
->scalarNode('admin_locale')->defaultValue(self::DEFAULT_ADMIN_LOCALE)->end()
->scalarNode('admin_path')->defaultValue(self::DEFAULT_ADMIN_PATH)->end()
->arrayNode('disabled_locales')->defaultValue([])
->prototype('scalar')->end()
->end()
->scalarNode('guess_locale')->defaultFalse()->end()
->enumNode('locale_switcher_mode')->defaultValue(self::DEFAULT_LOCALE_SWITCHE_MODE)
->values(['redirect_to_home', 'redirect_to_same'])
->end()
->arrayNode('fallback')
->addDefaultsIfNotSet()
->children()
->scalarNode(LocaleManager::HREFLANG)->defaultValue('es_ES')->end()
->scalarNode(LocaleManager::URL)->defaultValue('%locale%')->end()
->scalarNode(LocaleManager::INTERNALS)->defaultValue('es')->end()
->end()
->end()
->arrayNode('matrix')->defaultValue(self::DEFAULT_LOCALE_MATRIX)
->useAttributeAsKey('name')
->prototype('array')
->children()
->scalarNode(LocaleManager::HREFLANG)->end()
->scalarNode(LocaleManager::URL)->end()
->scalarNode('label')->isRequired()->end()
->end()
->end()
->end()
->end();
return $node;
}
public function getAdminNode()
{
$node = (new TreeBuilder())->root('admin');
$node
->addDefaultsIfNotSet()
->children()
->arrayNode('excluded_admin_groups')->defaultValue([])
->prototype('scalar')->end()
->end()
->arrayNode('translation')->addDefaultsIfNotSet()
->children()
->scalarNode('default_domain')->defaultValue('messages')->end()
->arrayNode('editable')->addDefaultsIfNotSet()
->children()
->scalarNode('mode')->defaultValue('inline')->end()
->scalarNode('type')->defaultValue('textarea')->end()
->scalarNode('emptytext')->defaultValue('Empty')->end()
->scalarNode('placement')->defaultValue('top')->end()
->end()
->end()
->end()
->end()
->arrayNode('templates')->addDefaultsIfNotSet()
->children()
->scalarNode('preview_form')
->defaultValue('@WAMAdminTheme/CRUD/preview_form.html.twig')->cannotBeEmpty()
->end()
->end()
->end()
->end();
return $node;
}
public function getConfigNode()
{
$rootNode = (new TreeBuilder())->root('config');
$rootNode
->addDefaultsIfNotSet()
->children()
->scalarNode('model_manager_name')->cannotBeEmpty()
->defaultValue(self::DEFAULT_CONFIG_MODEL_MANAGER_NAME)
->end()
->booleanNode('orm_enabled')->defaultValue(self::DEFAULT_CONFIG_ORM_ENABLED)->end()
->end();
return $rootNode;
}
public static function validateOptions($options)
{
self::validateLocaleOptions($options['locale']);
}
public static function validateLocaleOptions(array $options)
{
$accumulator = [];
foreach (LocaleManager::getTypes() as $type) {
$accumulator[$type] = [];
}
// inject the key (locale) as an 'internals' field
foreach ($options['matrix'] as $locale => $localeConfig) {
$options['matrix'][$locale]['internals'] = $locale;
}
foreach ($options['matrix'] as $name => $descriptor) {
foreach (LocaleManager::getTypes() as $type) {
if (isset($accumulator[$type][$descriptor[$type]])) {
throw new OptionsValidateException(sprintf('The identifier `%s` is already used in wam_core.locale.matrix, see `%s` and `%s` keys for `%s` type', $descriptor[$type], $accumulator[$type][$descriptor[$type]], $name, $type));
}
$accumulator[$type][$descriptor[$type]] = $name;
}
}
if (count($options['locales']) != count($options['matrix'])) {
throw new OptionsValidateException(sprintf('The number of declared locales in matrix (%s) element is different than in locales (%s).', implode(',', array_keys($options['matrix'])), implode(',', $options['locales'])));
}
foreach ($options['locales'] as $locale) {
if (!array_key_exists($locale, $options['matrix'])) {
throw new OptionsValidateException(sprintf("The locale '%s' is not defined as a key of the matrix element.", $locale));
}
}
return true;
}
}