<commit_before><?php

namespace Oro\Bundle\LayoutBundle\Layout\Block\Extension;

use Symfony\Component\Finder\Expression\Expression;

use Oro\Component\Layout\Block\OptionsResolver\OptionsResolver;
use Oro\Component\Layout\AbstractBlockTypeExtension;
use Oro\Component\Layout\Action;
use Oro\Component\Layout\ArrayOptionValueBuilder;
use Oro\Component\Layout\Block\Type\BaseType;
use Oro\Component\Layout\BlockInterface;
use Oro\Component\Layout\BlockView;
use Oro\Component\Layout\ContextInterface;
use Oro\Component\Layout\DataAccessorInterface;
use Oro\Component\Layout\OptionValueBag;
use Oro\Component\Layout\OptionValueBuilderInterface;
use Oro\Component\Layout\StringOptionValueBuilder;
use Oro\Component\Layout\Block\Type\Options;

/**
 * Automatically converts OptionValueBag to an appropriate data representation
 */
class OptionValueBagExtension extends AbstractBlockTypeExtension
{
    /**
     * {@inheritdoc}
     */
    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults(['resolve_value_bags' => true]);
    }

    /**
     * {@inheritdoc}
     */
    public function normalizeOptions(Options $options, ContextInterface $context, DataAccessorInterface $data)
    {
        if ($options['resolve_value_bags'] && !$this->hasExpression($options)) {
            $this->resolveValueBags($options);
        }
    }

    /**
     * {@inheritdoc}
     */
    public function finishView(BlockView $view, BlockInterface $block, Options $options)
    {
        $exprEvaluate = $block->getContext()->getOr('expressions_evaluate');
        if ($options['resolve_value_bags'] && $exprEvaluate) {
            $this->resolveValueBags($view->vars);
        } elseif (!$exprEvaluate) {
            throw new \InvalidArgumentException('expression should be evaluate');
        }
    }

    /**
     * @param $options
     * @return bool
     */
    protected function hasExpression($options)
    {
        $check = false;
        foreach ($options as $value) {
            if ($value instanceof Expression) {
                return true;
            }
        }
        return $check;
    }

    /**
     * @param array $options
     * @return array
     */
    protected function resolveValueBags(array &$options)
    {
        foreach ($options as $key => $value) {
            if (is_array($value)) {
                $options[$key] = $this->resolveValueBags($value);
            } elseif ($value instanceof OptionValueBag) {
                $options[$key] = $value->buildValue($this->getOptionsBuilder($value, $options));
            }
        }

        return $options;
    }
<commit_msg>BB-4223: Update ExpressionExtension and ExpressionProcessor - optionValueBag on normilize option check in resolvevaluebags expression<commit_after><?php

namespace Oro\Bundle\LayoutBundle\Layout\Block\Extension;

use Symfony\Component\Finder\Expression\Expression;

use Oro\Component\Layout\Block\OptionsResolver\OptionsResolver;
use Oro\Component\Layout\AbstractBlockTypeExtension;
use Oro\Component\Layout\Action;
use Oro\Component\Layout\ArrayOptionValueBuilder;
use Oro\Component\Layout\Block\Type\BaseType;
use Oro\Component\Layout\BlockInterface;
use Oro\Component\Layout\BlockView;
use Oro\Component\Layout\ContextInterface;
use Oro\Component\Layout\DataAccessorInterface;
use Oro\Component\Layout\OptionValueBag;
use Oro\Component\Layout\OptionValueBuilderInterface;
use Oro\Component\Layout\StringOptionValueBuilder;
use Oro\Component\Layout\Block\Type\Options;

/**
 * Automatically converts OptionValueBag to an appropriate data representation
 */
class OptionValueBagExtension extends AbstractBlockTypeExtension
{
    /**
     * {@inheritdoc}
     */
    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults(['resolve_value_bags' => true]);
    }

    /**
     * {@inheritdoc}
     */
    public function normalizeOptions(Options $options, ContextInterface $context, DataAccessorInterface $data)
    {
        if ($options['resolve_value_bags']) {
            $this->resolveValueBags($options, true);
        }
    }

    /**
     * {@inheritdoc}
     */
    public function finishView(BlockView $view, BlockInterface $block, Options $options)
    {
        $exprEvaluate = $block->getContext()->getOr('expressions_evaluate');
        if ($options['resolve_value_bags'] && $exprEvaluate) {
            $this->resolveValueBags($view->vars);
        }
    }

    /**
     * @param array $options
     * @param bool $hasExpression
     *
     * @return array
     */
    protected function resolveValueBags(array &$options, $hasExpression = false)
    {
        foreach ($options as $key => $value) {
            if ($hasExpression && $value instanceof Expression) {
                continue;
            }
            if (is_array($value)) {
                $options[$key] = $this->resolveValueBags($value);
            } elseif ($value instanceof OptionValueBag) {
                $options[$key] = $value->buildValue($this->getOptionsBuilder($value, $options));
            }
        }

        return $options;
    }

{'fraction_non_alphanumeric': 0.11765857478465153, 'fraction_numerical': 0.0007830853563038371, 'mean_word_length': 3.06120826709062, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 26, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2407790', 'n_tokens_mistral': 1401, 'n_tokens_neox': 1370, 'n_words': 262}