Completed
Push — 1.9 ( d8eb28...5c3e2e )
by
unknown
61:52 queued 29s
created

ActivityContactConfigDumperExtension::supports()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %
Metric Value
dl 0
loc 4
rs 10
cc 1
eloc 2
nc 1
nop 1
1
<?php
2
3
namespace OroCRM\Bundle\ActivityContactBundle\Tools;
4
5
use Oro\Bundle\EntityConfigBundle\Config\ConfigInterface;
6
use Oro\Bundle\EntityConfigBundle\Config\ConfigManager;
7
use Oro\Bundle\EntityConfigBundle\Provider\ConfigProvider;
8
use Oro\Bundle\EntityExtendBundle\Tools\ExtendConfigDumper;
9
use Oro\Bundle\EntityExtendBundle\Tools\DumperExtensions\AbstractEntityConfigDumperExtension;
10
11
use OroCRM\Bundle\ActivityContactBundle\EntityConfig\ActivityScope;
12
use OroCRM\Bundle\ActivityContactBundle\Model\TargetExcludeList;
13
use OroCRM\Bundle\ActivityContactBundle\Provider\ActivityContactProvider;
14
15
class ActivityContactConfigDumperExtension extends AbstractEntityConfigDumperExtension
16
{
17
    /** @var ConfigManager */
18
    protected $configManager;
19
20
    /** @var  ActivityContactProvider */
21
    protected $activityContactProvider;
22
23
    /**
24
     * @param ConfigManager           $configManager
25
     * @param ActivityContactProvider $activityContactProvider
26
     */
27
    public function __construct(ConfigManager $configManager, ActivityContactProvider $activityContactProvider)
28
    {
29
        $this->configManager           = $configManager;
30
        $this->activityContactProvider = $activityContactProvider;
31
    }
32
33
    /**
34
     * {@inheritdoc}
35
     */
36
    public function supports($actionType)
37
    {
38
        return $actionType === ExtendConfigDumper::ACTION_PRE_UPDATE;
39
    }
40
41
    /**
42
     * {@inheritdoc}
43
     */
44
    public function preUpdate()
45
    {
46
        /** @var ConfigProvider $extendConfigProvider */
47
        $extendConfigProvider = $this->configManager->getProvider('extend');
48
        /** @var ConfigProvider $activityConfigProvider */
49
        $activityConfigProvider = $this->configManager->getProvider('activity');
50
51
        $contactingActivityClasses = $this->activityContactProvider->getSupportedActivityClasses();
52
53
        $entityConfigs = $extendConfigProvider->getConfigs();
54
        foreach ($entityConfigs as $entityConfig) {
55
            if ($entityConfig->is('is_extend')) {
56
                $entityClassName = $entityConfig->getId()->getClassName();
57
                // Skipp excluded entity
58
                if (TargetExcludeList::isExcluded($entityClassName)) {
59
                    continue;
60
                }
61
62
                /**
63
                 * Check if entity has any activity from contact activities group
64
                 */
65
                $entityActivities = $activityConfigProvider->getConfig($entityClassName)->get('activities');
66
                if (!$entityActivities
67
                    || !array_intersect($contactingActivityClasses, $entityActivities)
68
                ) {
69
                    continue;
70
                }
71
72
                /** @var ConfigInterface[] $entityFields */
73
                $entityFields     = $extendConfigProvider->getConfigs($entityClassName);
74
                $entityFieldNames = array_map(
75
                    function (ConfigInterface $item) {
76
                        return $item->getId()->getFieldName();
0 ignored issues
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface Oro\Bundle\EntityConfigB...ig\Id\ConfigIdInterface as the method getFieldName() does only exist in the following implementations of said interface: Oro\Bundle\EntityConfigB...Config\Id\FieldConfigId.

Let’s take a look at an example:

interface User
{
    /** @return string */
    public function getPassword();
}

class MyUser implements User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different implementation of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the interface:

    interface User
    {
        /** @return string */
        public function getPassword();
    
        /** @return string */
        public function getDisplayName();
    }
    
Loading history...
77
                    },
78
                    $entityFields
79
                );
80
81
                /**
82
                 * Check if entity already has all needed fields.
83
                 * If at least one is not present we should check and add it too.
84
                 */
85
                if (false === (bool) array_diff(
86
                    array_keys(ActivityScope::$fieldsConfiguration),
87
                    array_intersect($entityFieldNames, array_keys(ActivityScope::$fieldsConfiguration))
88
                )) {
89
                    continue;
90
                }
91
92
                foreach (ActivityScope::$fieldsConfiguration as $fieldName => $fieldConfig) {
93
                    if (!in_array($fieldName, $entityFieldNames)) {
94
                        $this->configManager->createConfigFieldModel(
95
                            $entityClassName,
96
                            $fieldName,
97
                            $fieldConfig['type'],
98
                            $fieldConfig['mode']
99
                        );
100
101
                        $this->updateConfigs($entityClassName, $fieldName, $fieldConfig['options']);
102
                    }
103
                }
104
            }
105
        }
106
    }
107
108
    /**
109
     * @param string $className
110
     * @param array  $options
111
     * @param string $fieldName
112
     */
113
    protected function updateConfigs($className, $fieldName, $options)
114
    {
115
        foreach ($options as $scope => $scopeValues) {
116
            $config     = $this->configManager->getProvider($scope)->getConfig($className, $fieldName);
117
            $hasChanges = false;
118
            foreach ($scopeValues as $code => $val) {
119
                if (!$config->is($code, $val)) {
120
                    $config->set($code, $val);
121
                    $hasChanges = true;
122
                }
123
            }
124
            if ($hasChanges) {
125
                $this->configManager->persist($config);
126
            }
127
        }
128
    }
129
}
130