<commit_before><?php

namespace Oro\Bundle\ApiBundle\Processor\Config\Shared;

use Doctrine\ORM\Mapping\ClassMetadata;

use Oro\Component\ChainProcessor\ContextInterface;
use Oro\Component\ChainProcessor\ProcessorInterface;
use Oro\Bundle\ApiBundle\Processor\Config\ConfigContext;
use Oro\Bundle\ApiBundle\Provider\FieldConfigProvider;
use Oro\Bundle\ApiBundle\Provider\RelationConfigProvider;
use Oro\Bundle\ApiBundle\Util\ConfigUtil;
use Oro\Bundle\ApiBundle\Util\DoctrineHelper;
use Oro\Bundle\EntityBundle\Provider\ExclusionProviderInterface;

class CompleteDefinition implements ProcessorInterface
{
    /** @var DoctrineHelper */
    protected $doctrineHelper;

    /** @var FieldConfigProvider */
    protected $fieldConfigProvider;

    /** @var RelationConfigProvider */
    protected $relationConfigProvider;

    /** @var ExclusionProviderInterface */
    protected $exclusionProvider;

    /**
     * @param DoctrineHelper             $doctrineHelper
     * @param FieldConfigProvider        $fieldConfigProvider
     * @param RelationConfigProvider     $relationConfigProvider
     * @param ExclusionProviderInterface $exclusionProvider
     */
    public function __construct(
        DoctrineHelper $doctrineHelper,
        FieldConfigProvider $fieldConfigProvider,
        RelationConfigProvider $relationConfigProvider,
        ExclusionProviderInterface $exclusionProvider
    ) {
        $this->doctrineHelper         = $doctrineHelper;
        $this->fieldConfigProvider    = $fieldConfigProvider;
        $this->relationConfigProvider = $relationConfigProvider;
        $this->exclusionProvider      = $exclusionProvider;
    }

    /**
     * {@inheritdoc}
     */
    public function process(ContextInterface $context)
    {
        /** @var ConfigContext $context */

        /** @var array|null $definition */
        $definition = $context->getResult();
        if (empty($definition)) {
            // nothing to normalize
            return;
        }

        $fields = ConfigUtil::getArrayValue($definition, ConfigUtil::FIELDS);

        if (!ConfigUtil::isExcludeAll($definition)) {
            $entityClass = $context->getClassName();
            if ($entityClass && $this->doctrineHelper->isManageableEntityClass($entityClass)) {
                $fields = $this->completeDefinition(
                    $fields,
                    $entityClass,
                    $context->getVersion(),
                    $context->getRequestType(),
                    $context->getExtras()
                );
            }
        }

        $context->setResult(
            [
                ConfigUtil::EXCLUSION_POLICY => ConfigUtil::EXCLUSION_POLICY_ALL,
                ConfigUtil::FIELDS           => $fields
            ]
        );
    }

    /**
     * @param array    $definition
     * @param string   $entityClass
     * @param string   $version
     * @param string   $requestType
     * @param string[] $extras
     *
     * @return array
     */
    protected function completeDefinition(
        array $definition,
        $entityClass,
        $version,
        $requestType,
        $extras
    ) {
        $metadata = $this->doctrineHelper->getEntityMetadataForClass($entityClass);

        $definition = $this->getFields($definition, $metadata, $version, $requestType, $extras);
        $definition = $this->getAssociations($definition, $metadata, $version, $requestType, $extras);

        return $definition;
    }

    /**
     * @param array         $definition
     * @param ClassMetadata $metadata
     * @param string        $version
     * @param string        $requestType
     * @param string[]      $extras
     *
     * @return array
     */
    protected function getFields(
        array $definition,
        ClassMetadata $metadata,
        $version,
        $requestType,
        $extras
    ) {
        $fieldNames = $metadata->getFieldNames();
        foreach ($fieldNames as $fieldName) {
            if (array_key_exists($fieldName, $definition)) {
                // already defined
                continue;
            }

            if ($this->exclusionProvider->isIgnoredField($metadata, $fieldName)) {
                $config = [ConfigUtil::EXCLUDE => true];
            } else {
                $config = $this->fieldConfigProvider->getFieldConfig(
                    $metadata->name,
                    $fieldName,
                    $version,
                    $requestType,
                    $extras
                );
            }
            $definition[$fieldName] = $config;
        }

        return $definition;
    }

    /**
     * @param array         $definition
     * @param ClassMetadata $metadata
     * @param string        $version
     * @param string        $requestType
     * @param string[]      $extras
     *
     * @return array
     */
    protected function getAssociations(
        array $definition,
        ClassMetadata $metadata,
        $version,
        $requestType,
        $extras
    ) {
        $associations = $metadata->getAssociationMappings();
        foreach ($associations as $fieldName => $mapping) {<commit_msg>BAP-9402: Update config normalization processor to set field config even if a field is excluded<commit_after><?php

namespace Oro\Bundle\ApiBundle\Processor\Config\Shared;

use Doctrine\ORM\Mapping\ClassMetadata;

use Oro\Component\ChainProcessor\ContextInterface;
use Oro\Component\ChainProcessor\ProcessorInterface;
use Oro\Bundle\ApiBundle\Processor\Config\ConfigContext;
use Oro\Bundle\ApiBundle\Provider\FieldConfigProvider;
use Oro\Bundle\ApiBundle\Provider\RelationConfigProvider;
use Oro\Bundle\ApiBundle\Util\ConfigUtil;
use Oro\Bundle\ApiBundle\Util\DoctrineHelper;
use Oro\Bundle\EntityBundle\Provider\ExclusionProviderInterface;

class CompleteDefinition implements ProcessorInterface
{
    /** @var DoctrineHelper */
    protected $doctrineHelper;

    /** @var FieldConfigProvider */
    protected $fieldConfigProvider;

    /** @var RelationConfigProvider */
    protected $relationConfigProvider;

    /** @var ExclusionProviderInterface */
    protected $exclusionProvider;

    /**
     * @param DoctrineHelper             $doctrineHelper
     * @param FieldConfigProvider        $fieldConfigProvider
     * @param RelationConfigProvider     $relationConfigProvider
     * @param ExclusionProviderInterface $exclusionProvider
     */
    public function __construct(
        DoctrineHelper $doctrineHelper,
        FieldConfigProvider $fieldConfigProvider,
        RelationConfigProvider $relationConfigProvider,
        ExclusionProviderInterface $exclusionProvider
    ) {
        $this->doctrineHelper         = $doctrineHelper;
        $this->fieldConfigProvider    = $fieldConfigProvider;
        $this->relationConfigProvider = $relationConfigProvider;
        $this->exclusionProvider      = $exclusionProvider;
    }

    /**
     * {@inheritdoc}
     */
    public function process(ContextInterface $context)
    {
        /** @var ConfigContext $context */

        /** @var array|null $definition */
        $definition = $context->getResult();
        if (empty($definition)) {
            // nothing to normalize
            return;
        }

        $fields = ConfigUtil::getArrayValue($definition, ConfigUtil::FIELDS);

        if (!ConfigUtil::isExcludeAll($definition)) {
            $entityClass = $context->getClassName();
            if ($entityClass && $this->doctrineHelper->isManageableEntityClass($entityClass)) {
                $fields = $this->completeDefinition(
                    $fields,
                    $entityClass,
                    $context->getVersion(),
                    $context->getRequestType(),
                    $context->getExtras()
                );
            }
        }

        $context->setResult(
            [
                ConfigUtil::EXCLUSION_POLICY => ConfigUtil::EXCLUSION_POLICY_ALL,
                ConfigUtil::FIELDS           => $fields
            ]
        );
    }

    /**
     * @param array    $definition
     * @param string   $entityClass
     * @param string   $version
     * @param string   $requestType
     * @param string[] $extras
     *
     * @return array
     */
    protected function completeDefinition(
        array $definition,
        $entityClass,
        $version,
        $requestType,
        $extras
    ) {
        $metadata = $this->doctrineHelper->getEntityMetadataForClass($entityClass);

        $definition = $this->getFields($definition, $metadata, $version, $requestType, $extras);
        $definition = $this->getAssociations($definition, $metadata, $version, $requestType, $extras);

        return $definition;
    }

    /**
     * @param array         $definition
     * @param ClassMetadata $metadata
     * @param string        $version
     * @param string        $requestType
     * @param string[]      $extras
     *
     * @return array
     */
    protected function getFields(
        array $definition,
        ClassMetadata $metadata,
        $version,
        $requestType,
        $extras
    ) {
        $fieldNames = $metadata->getFieldNames();
        foreach ($fieldNames as $fieldName) {
            if (array_key_exists($fieldName, $definition)) {
                // already defined
                continue;
            }

            $config = $this->fieldConfigProvider->getFieldConfig(
                $metadata->name,
                $fieldName,
                $version,
                $requestType,
                $extras
            );

            if ($this->exclusionProvider->isIgnoredField($metadata, $fieldName)) {
                $config[ConfigUtil::DEFINITION][ConfigUtil::EXCLUDE] = true;
            }
            $definition[$fieldName] = $config;
        }

        return $definition;
    }

    /**
     * @param array         $definition
     * @param ClassMetadata $metadata
     * @param string        $version
     * @param string        $requestType
     * @param string[]      $extras
     *
     * @return array
     */
    protected function getAssociations(
        array $definition,
        ClassMetadata $metadata,
        $version,
        $requestType,
        $extras
    ) {
        $associations = $metadata->getAssociationMappings();
        foreach ($associations as $fieldName => $mapping) {
{'fraction_non_alphanumeric': 0.10396902226524686, 'fraction_numerical': 0.0003872216844143272, 'mean_word_length': 2.104266826923077, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 58, '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': '1695681', 'n_tokens_mistral': 2664, 'n_tokens_neox': 2578, 'n_words': 504}