@inheritdoc

@throws \Symfony\Component\OptionsResolver\Exception\UndefinedOptionsException
@throws \Symfony\Component\OptionsResolver\Exception\AccessException
555747
protected function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setRequired([
            'content',
            'relation_field',
        ]);

        $resolver->setAllowedTypes('content', SiteContent::class);
        $resolver->setAllowedTypes('relation_field', ['string', 'array']);
        $resolver->setAllowedValues(
            'relation_field',
            function ($fields) {
                if (!is_array($fields)) {
                    return true;
                }

                foreach ($fields as $field) {
                    if (!is_string($field)) {
                        return false;
                    }
                }

                return true;
            }
        );

        $resolver->setDefined('exclude_self');
        $resolver->setAllowedTypes('exclude_self', ['bool']);
        $resolver->setDefaults([
            'exclude_self' => true,
        ]);
    }
1048857
private function getRequestOptionsResolver()
    {
        if (null !== $this->requestOptionsResolver) {
            return $this->requestOptionsResolver;
        }

        $amountValidator = function ($value) {
            return preg_match('~^[0-9]+(\.[0-9]{2,3})?$~', $value);
        };

        $scheduleResolver = new OptionsResolver();
        $scheduleResolver
            ->setRequired(['date', 'amount'])
            ->setAllowedTypes('date', 'string')
            ->setAllowedTypes('amount', 'numeric')
            ->setAllowedValues('date', function ($value) {
                return preg_match('~^[0-9]{2}/[0-9]{2}/[0-9]{4}$~', $value);
            })
            ->setAllowedValues('amount', $amountValidator);

        $resolver = new OptionsResolver();
        $resolver
            ->setRequired([
                'reference',
                'date',
                'amount',
                'currency',
                'email',
                'return_url',
                'success_url',
                'failure_url',
            ])
            ->setDefaults([
                'locale'   => 'FR',
                'comment'  => null,
                'schedule' => [],
                'options'  => [],
            ])
            ->setAllowedTypes('reference', 'string')
            ->setAllowedTypes('date', 'string')
            ->setAllowedTypes('amount', 'numeric')
            ->setAllowedTypes('currency', 'string')
            ->setAllowedTypes('email', 'string')
            ->setAllowedTypes('return_url', 'string')
            ->setAllowedTypes('success_url', 'string')
            ->setAllowedTypes('failure_url', 'string')
            ->setAllowedTypes('comment', 'string')
            ->setAllowedTypes('schedule', 'array')
            ->setAllowedTypes('options', 'array')
            ->setAllowedValues('date', function ($value) {
                return preg_match('~^[0-9]{2}/[0-9]{2}/[0-9]{4}:[0-9]{2}:[0-9]{2}:[0-9]{2}$~', $value);
            })
            ->setAllowedValues('amount', $amountValidator)
            ->setAllowedValues('locale', ['FR', 'EN', 'DE', 'IT', 'ES', 'NL', 'PT'])
            ->setNormalizer('schedule', function (
                /** @noinspection PhpUnusedParameterInspection */
                Options $options, $value
            ) use ($scheduleResolver) {
                $schedule = [];

                foreach ($value as $data) {
                    $schedule[] = $scheduleResolver->resolve($data);
                }

                return $schedule;
            })
            ->setAllowedValues('schedule', function ($value) {
                return empty($value) || (1 < count($value));
            });

        return $this->requestOptionsResolver = $resolver;
    }
584615
public function configureOptions(OptionsResolver $resolver)
    {
        $resolver
            // filter option is required
            ->setRequired('filters')
            ->setAllowedTypes('filters', 'array')

            // sources is required and should be an array
            ->setRequired('sources')
            ->setAllowedTypes('sources', 'array')

            // destination should be a string, no array is allowed for now
            ->setRequired('destinations')
            ->setAllowedTypes('destinations', 'array')

            // debug mode (allow more verbosity)
            ->setDefault('debug', false)
            ->setAllowedTypes('debug', 'boolean')
        ;
    }
206058
private function buildResolver(): OptionsResolver
    {
        $resolver = new OptionsResolver();
        $profile = $this->mapOfProfiles->get($this->currentProfile);

        call_user_func($profile, $resolver);

        return $resolver;
    }
938334
public function configureOptions(OptionsResolver $resolver)
    {
        // user can defined an admin name
        $resolver
            ->setDefault('admin', null)
            ->setDefault('action', null)
            ->setDefault('route', null)
            ->setDefault('url', null)
            ->setDefault('parameters', [])
            ->setDefault('text', '')
            ->setDefault('attr', [])
            ->setDefault('link_attr', [
                'class' => 'nav-link',
            ])
            ->setDefault('items', [])
            ->setDefault('icon', null)
            ->setDefault('link_css_class', 'nav-link')
            ->setNormalizer('admin', function(Options $options, $adminName) {
                // user has to defined either an admin name and an action name, or a route name with optional
                // parameters, or an url
                if (null === $adminName
                    && null === $options->offsetGet('route')
                    && null === $options->offsetGet('url')
                ) {
                    throw new InvalidOptionsException(
                        'You should either defined an admin name, or route name or an uri'
                    );
                }

                return $adminName;
            })
            // if an admin name is set, an action name can provided. This action will be the menu link
            ->setNormalizer('action', function(Options $options, $action) {
                // if an action name is provided, an admin name should be defined too
                if (null !== $action && null === $options->offsetGet('admin')) {
                    throw new InvalidOptionsException(
                        'You should provide an admin name for this action '.$action
                    );
                }

                // default to list action
                if (null !== $options->offsetGet('admin') && null === $action) {
                    $action = 'list';
                }

                return $action;
            })
            ->setAllowedTypes('parameters', 'array')
            ->setNormalizer('attr', function(Options $options, $attr) {
                if (!is_array($attr)) {
                    $attr = [];
                }

                if (empty($attr['id'])) {
                    $attr['id'] = uniqid('admin-menu-');
                }

                if ('horizontal' === $this->position && !key_exists('class', $attr)) {
                    $attr['class'] = 'nav-item';
                }

                return $attr;
            })
            ->setNormalizer('link_attr', function(Options $options, $value) {
                if (!is_array($value)) {
                    $value = [];
                }

                if (!key_exists('class', $value)) {
                    $value['class'] = 'nav-link';
                }

                return $value;
            })
            ->setNormalizer('items', function(Options $options, $items) {
                if (!is_array($items)) {
                    $items = [];
                }
                $resolver = new OptionsResolver();
                $resolvedItems = [];

                foreach ($items as $name => $item) {
                    $itemConfiguration = new MenuItemConfiguration($name, $this->position);
                    $itemConfiguration->configureOptions($resolver);
                    $itemConfiguration->setParameters($resolver->resolve($item));

                    $resolvedItems[$name] = $itemConfiguration;
                }

                return $resolvedItems;
            })
            ->setNormalizer('text', function(Options $options, $text) {
                if (!$text) {
                    // TODO use translation pattern key instead
                    $text = ucfirst($this->name);
                }

                return $text;
            })
        ;
    }
1050793
protected function getOptions()
    {
        if (!is_array($this->arguments['options']) && !($this->arguments['options'] instanceof \Traversable)) {
            return [];
        }
        $options = [];
        foreach ($this->arguments['options'] as $key => $value) {
            if (is_object($value)) {
                if ($this->hasArgument('optionValueField')) {
                    $key = ObjectAccess::getPropertyPath($value, $this->arguments['optionValueField']);
                    if (is_object($key)) {
                        if (method_exists($key, '__toString')) {
                            $key = (string)$key;
                        } else {
                            throw new ViewHelper\Exception('Identifying value for object of class "' . get_class($value) . '" was an object.', 1247827428);
                        }
                    }
                } elseif ($this->persistenceManager->getIdentifierByObject($value) !== null) {
                    $key = $this->persistenceManager->getIdentifierByObject($value);
                } elseif (method_exists($value, '__toString')) {
                    $key = (string)$value;
                } else {
                    throw new ViewHelper\Exception('No identifying value for object of class "' . get_class($value) . '" found.', 1247826696);
                }

                if ($this->hasArgument('optionLabelField')) {
                    $value = ObjectAccess::getPropertyPath($value, $this->arguments['optionLabelField']);
                    if (is_object($value)) {
                        if (method_exists($value, '__toString')) {
                            $value = (string)$value;
                        } else {
                            throw new ViewHelper\Exception('Label value for object of class "' . get_class($value) . '" was an object without a __toString() method.', 1247827553);
                        }
                    }
                } elseif (method_exists($value, '__toString')) {
                    $value = (string)$value;
                } elseif ($this->persistenceManager->getIdentifierByObject($value) !== null) {
                    $value = $this->persistenceManager->getIdentifierByObject($value);
                }
            }

            if ($this->hasArgument('translate')) {
                $value = $this->getTranslatedLabel($key, $value);
            }

            $options[$key] = $value;
        }
        if ($this->arguments['sortByOptionLabel']) {
            asort($options);
        }
        return $options;
    }
161840
protected function configureOptions(OptionsResolver $optionsResolver)
    {
        foreach ($this->constructorArgs as $name => $param) {
            if ($param->isOptional() && $param->isDefaultValueAvailable()) {
                $optionsResolver->setDefault($name, $param->getDefaultValue());
            } else {
                $optionsResolver->setRequired($name);
            }
        }
    }
788575
private function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setRequired([
            'recipient',
            'subject',
            'template',
        ]);

        $resolver->setDefault('from', $this->configuration[0]);
        $resolver->setDefault('bcc', [$this->configuration[1]]);
        $resolver->setDefault('parameters', []);
        $resolver->setDefault('attachments', []);

        $resolver->setAllowedTypes('recipient', ['string', 'array']);
        $resolver->setAllowedTypes('bcc', ['string', 'array']);
//        $resolver->setAllowedTypes('reply_to', ['string', 'array']);
        $resolver->setAllowedTypes('subject', ['string']);
        $resolver->setAllowedTypes('template', ['string']);
        $resolver->setAllowedTypes('parameters', ['array']);
        $resolver->setAllowedTypes('attachments', ['array']);
        $resolver->setAllowedTypes('from', 'string');
    }
50956
public function setOptions(array $options)
    {
        if ($this->frozen) {
            throw new Exception('The options for the field "'.$this->name.'"');
        }
        $this->options = $options;
        $this->frozen = true;
    }
429671
public function configureOptions(OptionsResolver $resolver)
    {
        $multiLanguagesChoiceManage = $this->multiLanguagesChoiceManager;
        $resolver->setDefaults(
            array(
                'multiple' => true,
                'expanded' => true,
                'required' => false,
                'class' => $this->workflowFunctionClass,
                'choice_label' => function (WorkflowFunctionInterface $choice) use ($multiLanguagesChoiceManage) {
                    return $multiLanguagesChoiceManage->choose($choice->getNames());
                },
            )
        );
    }
284293
protected function configureOptions(OptionsResolver $resolver)
    {
        $resolver->remove(['depth', 'parent_location_id', 'subtree']);
        $resolver->setRequired('location');
        $resolver->setAllowedTypes('location', SiteLocation::class);

        $resolver->setDefault('sort', function (Options $options) {
            /** @var \Netgen\EzPlatformSiteApi\API\Values\Location $location */
            $location = $options['location'];
            return $location->innerLocation->getSortClauses();
        });
    }
1354065
protected function configureOptions(OptionsResolver $resolver): void
    {
        // We set object properties' _default_ values to null to ensure we do not create unnecessary objects.
        $resolver->setDefaults([
            static::CONFIG_USER_AGENT_PREFIX => null,
            static::CONFIG_HTTP_CLIENT_BUILDER => null,
            static::CONFIG_JOURNAL => null,
            static::CONFIG_URI_FACTORY => null,
            static::CONFIG_REQUEST_FACTORY => null,
            static::CONFIG_ERROR_FORMATTER => null,
            static::CONFIG_RETRY_PLUGIN_CONFIG => null,
        ]);
        $resolver->setAllowedTypes(static::CONFIG_USER_AGENT_PREFIX, ['null', 'string']);
        $resolver->setAllowedTypes(static::CONFIG_HTTP_CLIENT_BUILDER, ['null', '\Apigee\Edge\HttpClient\Utility\BuilderInterface']);
        $resolver->setAllowedTypes(static::CONFIG_JOURNAL, ['null', '\Apigee\Edge\HttpClient\Utility\JournalInterface']);
        $resolver->setAllowedTypes(static::CONFIG_URI_FACTORY, ['null', '\Http\Message\UriFactory']);
        $resolver->setAllowedTypes(static::CONFIG_REQUEST_FACTORY, ['null', '\Http\Message\RequestFactory']);
        $resolver->setAllowedTypes(static::CONFIG_ERROR_FORMATTER, ['null', '\Http\Message\Formatter']);
        $resolver->setAllowedTypes(static::CONFIG_RETRY_PLUGIN_CONFIG, ['null', 'array']);
    }
247937
protected function resolvePageOptions(array $options = array())
    {
        $resolver = new OptionsResolver;
        $this->setDefaultPageOptions($resolver);

        if (!empty($this->pageOptions)) {
            $resolver->setDefaults($this->pageOptions);
        }

        return $resolver->resolve($options);
    }
591535
public function configureOptionsResolver(OptionsResolver $resolver)
    {
        parent::configureOptionsResolver($resolver);
        $resolver->setRequired([
            self::OPTION_NOSQL_DRIVER,
            self::OPTION_COLLECTION_PREFIX,
            self::OPTION_COLLECTION_NAME,
            self::OPTION_METHOD
        ]);

        $resolver->setAllowedTypes(self::OPTION_COLLECTION_NAME, ['string']);
        $resolver->setAllowedTypes(self::OPTION_COLLECTION_PREFIX, ['string']);
        $resolver->setAllowedTypes(self::OPTION_NOSQL_DRIVER, ['string']);
        $resolver->setAllowedTypes(self::OPTION_METHOD, ['string']);
    }
177552
public function configureOptions (OptionsResolver $resolver)
    {
        $allRoles = $this->roleCollection->getAllAvailableRoles();
        $allRoleKeys = array_keys($allRoles);

        $resolver->setDefaults([
            "roles_with_tags" => [],
            "choices" => function(Options $options) use ($allRoleKeys, $allRoles)
            {
                // if no tags are selected, just return all roles
                if (empty($options["roles_with_tags"]))
                {
                    return array_combine($allRoleKeys, $allRoleKeys);
                }

                // if tags are selected, only use the choices with the given tags
                $choices = [];

                foreach ($allRoles as $roleKey => $role)
                {
                    if (!empty(array_intersect($options["roles_with_tags"], $role->getTags())))
                    {
                        $choices[$roleKey] = $roleKey;
                    }
                }

                return $choices;
            },
            "choices_as_values" => true,
            "choice_label" => function ($choiceValue, $choiceKey, $index) use ($allRoles)
            {
                return $allRoles[$choiceKey]->getTitle();
            },
            "choice_attr" => function ($choiceValue, $choiceKey, $index) use ($allRoles)
            {
                return [
                    "data-role-description" => $allRoles[$choiceKey]->getDescription(),
                ];
            },
        ]);

        $resolver->setAllowedTypes("roles_with_tags", ["array"]);
    }
430538
public function configureOptions(OptionsResolver $resolver)
    {
        $resolver
            ->setDefaults(
                [
                    'limit_per_page' => 10,
                    'default_sort_column' => 'id',
                    'default_sort_order' => 'asc',
                    'show_actions_column' => true,
                ]
            )
            ->setAllowedTypes('limit_per_page', 'integer')
            ->setAllowedTypes('default_sort_column', 'string')
            ->setAllowedTypes('default_sort_order', 'string')
            ->setAllowedTypes('show_actions_column', 'boolean')
            ->setAllowedValues('default_sort_order', ['asc', 'desc']);
    }
982565
private function getOptionsResolverFunctionDeclaration()
    {

        // get required properties
        $required = [];
        $optional = [];
        $allowedValues = [];

        // optional
        foreach( $this->entity->dataTypes as $name => $dataType ) {

            // is required
            if( !$dataType->getDefault() and !$dataType->isNullable() ) {
                $required[] = $name;
            } else {
                $optional[] = $name;
            }

            // set allowed values (currently only works for enums)
            if( $dataType->isEnum($enumName) ) {
                // At the moment this is bugged in Symfony.Don't think it is of vital importance. Ignoring for now.
                # $allowedValues[$name] = $enumName;
            }

        }

        // allowed values declaration
        $allowedValuesPhp = '';
        if( $allowedValues ) {
            $allowedValuesPhp = "\n\$resolver->setAllowedValues(\n    array(\n";
            // at the moment this enum supported only
            foreach( $allowedValues as $column => $enumName ) {
                $allowedValuesPhp .= sprintf(
                    '        %s => Enum::getValues(%s),%s',
                    Php::varExport( $column ),
                    Php::varExport( $enumName ),
                    "\n"
                );
            }
            $allowedValuesPhp .= "    )\n);";
            $allowedValuesPhp = new Format( $allowedValuesPhp );
        }

        // require block
        $requiredPhp = new Format();
        if( $required ) {
            $requiredPhp = "\n\$resolver->setRequired(\n" . (new Format(Php::varExport( $required )))->indent(4) . "\n);";
            $requiredPhp = new Format($requiredPhp);
            $requiredPhp->indent(24);
        }

        // optional
        $optionalPhp = new Format();
        if( $optional ) {
            $optionalPhp = "\n\$resolver->setOptional(\n" . (new Format(Php::varExport( $optional )))->indent(4) . "\n);";
            $optionalPhp = new Format($optionalPhp);
            $optionalPhp->indent(24);
        }

        $this->class->addUses('Symfony\Component\OptionsResolver\OptionsResolver');
        $this->class->classComponents[] = new FunctionDeclaration(
            'resolverGet',
            new Sformatf( <<<'PHP'
                /**
                 * Resolver getter. Singleton
                 * @return Symfony\Component\Options\Resolver
                 */
                public function resolverGet()
                {
                    // do we already have a resolver instance
                    if( !$this->resolver ) {

                        $resolver = new OptionsResolver();%s%s%s
                        $this->resolver = $resolver;

                    }
                    return $this->resolver;
                }
PHP
                , $requiredPhp,
                $optionalPhp,
                $allowedValuesPhp
            )
        );

        $this->class->classComponents[] = new VariableDeclaration(
            'resolver',
            new SFormatf( <<<'PHP'
                /**
                 * Options Resolver
                 * @var array
                 */
                private $resolver;
PHP
            )
        );

    }