Completed
Push — master ( 0b658a...cae295 )
by
unknown
54:13
created

UpdateActivityContactFields   A

Complexity

Total Complexity 18

Size/Duplication

Total Lines 110
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 6

Importance

Changes 1
Bugs 0 Features 0
Metric Value
wmc 18
lcom 1
cbo 6
dl 0
loc 110
rs 10
c 1
b 0
f 0

4 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 9 1
A process() 0 18 3
B isSupportedEntity() 0 27 6
C updateFields() 0 24 8
1
<?php
2
3
namespace OroCRM\Bundle\ActivityContactBundle\Api\Processor\Config;
4
5
use Oro\Component\ChainProcessor\ContextInterface;
6
use Oro\Component\ChainProcessor\ProcessorInterface;
7
use Oro\Bundle\ApiBundle\Config\EntityDefinitionConfig;
8
use Oro\Bundle\ApiBundle\Processor\Config\ConfigContext;
9
use Oro\Bundle\EntityConfigBundle\Config\ConfigManager;
10
use OroCRM\Bundle\ActivityContactBundle\EntityConfig\ActivityScope;
11
use OroCRM\Bundle\ActivityContactBundle\Model\TargetExcludeList;
12
use OroCRM\Bundle\ActivityContactBundle\Provider\ActivityContactProvider;
13
14
/**
15
 * Renames "contacting activity" (ac_*) fields to have more readable names.
16
 * Exclude these fields for "update" action because they are calculated automatically
17
 * and should not be updated manually.
18
 */
19
class UpdateActivityContactFields implements ProcessorInterface
20
{
21
    /** @var ConfigManager */
22
    protected $configManager;
23
24
    /** @var  ActivityContactProvider */
25
    protected $activityContactProvider;
26
27
    /** @var string[] */
28
    protected $excludedActions;
29
30
    /**
31
     * @param ConfigManager           $configManager
32
     * @param ActivityContactProvider $activityContactProvider
33
     * @param string                  $excludedActions
34
     */
35
    public function __construct(
36
        ConfigManager $configManager,
37
        ActivityContactProvider $activityContactProvider,
38
        $excludedActions
39
    ) {
40
        $this->configManager = $configManager;
41
        $this->activityContactProvider = $activityContactProvider;
42
        $this->excludedActions = $excludedActions;
0 ignored issues
show
Documentation Bug introduced by
It seems like $excludedActions of type string is incompatible with the declared type array<integer,string> of property $excludedActions.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
43
    }
44
45
    /**
46
     * {@inheritdoc}
47
     */
48
    public function process(ContextInterface $context)
49
    {
50
        /** @var ConfigContext $context */
51
52
        $definition = $context->getResult();
53
        if (!$definition->isExcludeAll()) {
54
            // expected completed config
55
            return;
56
        }
57
58
        $entityClass = $context->getClassName();
59
        if (!$this->isSupportedEntity($entityClass)) {
60
            // an entity is not supported
61
            return;
62
        }
63
64
        $this->updateFields($definition, $context->getTargetAction());
0 ignored issues
show
Bug introduced by
It seems like $definition defined by $context->getResult() on line 52 can be null; however, OroCRM\Bundle\ActivityCo...tFields::updateFields() does not accept null, maybe add an additional type check?

Unless you are absolutely sure that the expression can never be null because of other conditions, we strongly recommend to add an additional type check to your code:

/** @return stdClass|null */
function mayReturnNull() { }

function doesNotAcceptNull(stdClass $x) { }

// With potential error.
function withoutCheck() {
    $x = mayReturnNull();
    doesNotAcceptNull($x); // Potential error here.
}

// Safe - Alternative 1
function withCheck1() {
    $x = mayReturnNull();
    if ( ! $x instanceof stdClass) {
        throw new \LogicException('$x must be defined.');
    }
    doesNotAcceptNull($x);
}

// Safe - Alternative 2
function withCheck2() {
    $x = mayReturnNull();
    if ($x instanceof stdClass) {
        doesNotAcceptNull($x);
    }
}
Loading history...
65
    }
66
67
    /**
68
     * @param string $entityClass
69
     *
70
     * @return bool
71
     */
72
    protected function isSupportedEntity($entityClass)
73
    {
74
        if (!$this->configManager->hasConfig($entityClass)) {
75
            // only extended entities are supported
76
            return false;
77
        }
78
        if (!$this->configManager->getEntityConfig('extend', $entityClass)->is('is_extend')) {
79
            // only extended entities are supported
80
            return false;
81
        }
82
        if (TargetExcludeList::isExcluded($entityClass)) {
83
            // skip excluded entities
84
            return false;
85
        }
86
        $activities = $this->configManager->getEntityConfig('activity', $entityClass)->get('activities');
87
        if (empty($activities)) {
88
            // entity should be associated with at least one activity
89
            return false;
90
        }
91
        $contactingActivities = $this->activityContactProvider->getSupportedActivityClasses();
92
        if (!array_intersect($contactingActivities, $activities)) {
93
            // an entity does not have supported activity
94
            return false;
95
        }
96
97
        return true;
98
    }
99
100
    /**
101
     * @param EntityDefinitionConfig $definition
102
     * @param string|null            $targetAction
103
     */
104
    protected function updateFields(EntityDefinitionConfig $definition, $targetAction)
105
    {
106
        $renameMap = [
107
            ActivityScope::LAST_CONTACT_DATE     => 'lastContactedDate',
108
            ActivityScope::LAST_CONTACT_DATE_IN  => 'lastContactedDateIn',
109
            ActivityScope::LAST_CONTACT_DATE_OUT => 'lastContactedDateOut',
110
            ActivityScope::CONTACT_COUNT         => 'timesContacted',
111
            ActivityScope::CONTACT_COUNT_IN      => 'timesContactedIn',
112
            ActivityScope::CONTACT_COUNT_OUT     => 'timesContactedOut',
113
        ];
114
        foreach ($renameMap as $fieldName => $resultFieldName) {
115
            if ($definition->hasField($fieldName) && !$definition->hasField($resultFieldName)) {
116
                $field = $definition->getField($fieldName);
117
                if (!$field->hasPropertyPath()) {
118
                    $definition->removeField($fieldName);
119
                    $field->setPropertyPath($fieldName);
120
                    $definition->addField($resultFieldName, $field);
121
                }
122
                if ('update' === $targetAction && !$field->hasExcluded() && !$field->isExcluded()) {
123
                    $field->setExcluded();
124
                }
125
            }
126
        }
127
    }
128
}
129