Completed
Push — master ( cd8605...3b7290 )
by
unknown
09:46
created

AttributesConverterHelper::addUnknownAttributes()   C

Complexity

Conditions 7
Paths 4

Size

Total Lines 32
Code Lines 21

Duplication

Lines 0
Ratio 0 %
Metric Value
dl 0
loc 32
rs 6.7272
cc 7
eloc 21
nc 4
nop 2
1
<?php
2
3
namespace OroCRM\Bundle\MagentoBundle\ImportExport\Converter;
4
5
use ReflectionClass;
6
use ReflectionProperty;
7
8
use Doctrine\Common\Util\Inflector;
9
10
use Oro\Bundle\ImportExportBundle\Context\ContextInterface;
11
12
class AttributesConverterHelper
13
{
14
    const ATTRIBUTES_KEY = 'attributes';
15
    const KEY = 'key';
16
    const VALUE = 'value';
17
    const ID_MARK = '_id';
18
    const CHANNEL_KEY = 'channel';
19
    const ENTITY_NAME_KEY = 'entityName';
20
21
    /**
22
     * @param array $importedRecord
23
     * @param ContextInterface|null $context
24
     * @return array
25
     */
26
    public static function addUnknownAttributes(array $importedRecord, ContextInterface $context = null)
27
    {
28
        $channelId = null;
29
        if ($context && $context->hasOption(self::CHANNEL_KEY)) {
30
            $channelId = $context->getOption(self::CHANNEL_KEY);
31
        }
32
33
        $addedAttributes = [];
34
        if (!empty($importedRecord[self::ATTRIBUTES_KEY])) {
35
            foreach ($importedRecord[self::ATTRIBUTES_KEY] as $attribute) {
36
                $name = $attribute[self::KEY];
37
                $value = $attribute[self::VALUE];
38
39
                $isIdentifier = substr($name, -strlen(self::ID_MARK)) === self::ID_MARK;
40
                if ($isIdentifier && $channelId) {
41
                    $name = Inflector::camelize($name);
42
                    $importedRecord = self::addAttribute($importedRecord, $name, $value);
43
                    $addedAttributes[] = $name;
44
45
                    $name = substr($name, 0, strlen($name) - strlen(self::ID_MARK) + 1);
46
                    $value = ['originId' => $value, self::CHANNEL_KEY => ['id' => $channelId]];
47
                }
48
49
                $name = Inflector::camelize($name);
50
                $importedRecord = self::addAttribute($importedRecord, $name, $value);
51
                $addedAttributes[] = $name;
52
            }
53
            unset($importedRecord[self::ATTRIBUTES_KEY]);
54
        }
55
56
        return static::normalizeProperties($importedRecord, $addedAttributes, $context);
57
    }
58
59
    /**
60
     * @param array $importedRecord
61
     * @param string $name
62
     * @param string $value
63
     * @return array
64
     */
65
    public static function addAttribute(array $importedRecord, $name, $value)
66
    {
67
        if (!array_key_exists($name, $importedRecord)) {
68
            $importedRecord[$name] = $value;
69
        }
70
71
        return $importedRecord;
72
    }
73
74
    /**
75
     * Converts properties into correct case
76
     *
77
     * @param array $record
78
     * @param array $properties
79
     * @param ContextInterface|null $context
80
     *
81
     * @return array Normalized record
82
     */
83
    public static function normalizeProperties(array $record, array $properties, ContextInterface $context = null)
84
    {
85
        if (!$properties || !$context || !$context->hasOption(static::ENTITY_NAME_KEY)) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $properties of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
86
            return $record;
87
        }
88
89
        $class = $context->getOption(static::ENTITY_NAME_KEY);
90
        $classRef = new ReflectionClass($class);
91
        $classProperties = array_map(
92
            function (ReflectionProperty $prop) {
93
                return $prop->getName();
94
            },
95
            $classRef->getProperties()
96
        );
97
98
        $classPropertyMap = array_combine(array_map('strtolower', $classProperties), $classProperties);
99
100
        $result = [];
101
        foreach ($record as $key => $value) {
102
            $lkey = strtolower($key);
103
            if (in_array($key, $properties) && array_key_exists($lkey, $classPropertyMap)) {
104
                $result[$classPropertyMap[$lkey]] = $value;
105
            } else {
106
                $result[$key] = $value;
107
            }
108
        }
109
110
        return $result;
111
    }
112
}
113