Completed
Push — pac-335--slash-handling ( 37874d...fdaa9b )
by Tim
08:32
created

AdditionalAttributeObserver::createObserver()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 9
rs 9.9666
c 0
b 0
f 0
cc 1
nc 1
nop 1
1
<?php
2
3
/**
4
 * TechDivision\Import\Observers\AdditionalAttributeObserver
5
 *
6
 * NOTICE OF LICENSE
7
 *
8
 * This source file is subject to the Open Software License (OSL 3.0)
9
 * that is available through the world-wide-web at this URL:
10
 * http://opensource.org/licenses/osl-3.0.php
11
 *
12
 * PHP version 5
13
 *
14
 * @author    Tim Wagner <[email protected]>
15
 * @copyright 2016 TechDivision GmbH <[email protected]>
16
 * @license   http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
17
 * @link      https://github.com/techdivision/import
18
 * @link      http://www.techdivision.com
19
 */
20
21
namespace TechDivision\Import\Observers;
22
23
use TechDivision\Import\Utils\ColumnKeys;
24
use TechDivision\Import\Subjects\SubjectInterface;
25
use TechDivision\Import\Serializer\SerializerFactoryInterface;
26
27
/**
28
 * Observer that prepares the additional product attribues found in the CSV file
29
 * in the row 'additional_attributes'.
30
 *
31
 * @author    Tim Wagner <[email protected]>
32
 * @copyright 2016 TechDivision GmbH <[email protected]>
33
 * @license   http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
34
 * @link      https://github.com/techdivision/import
35
 * @link      http://www.techdivision.com
36
 */
37
class AdditionalAttributeObserver extends AbstractObserver implements ObserverFactoryInterface
38
{
39
40
    /**
41
     * The serializer used to serializer/unserialize the categories from the path column.
42
     *
43
     * @var \TechDivision\Import\Serializer\SerializerInterface
44
     */
45
    protected $serializer;
46
47
    /**
48
     * The serializer factory instance.
49
     *
50
     * @var \TechDivision\Import\Serializer\SerializerFactoryInterface
51
     */
52
    protected $serializerFactory;
53
54
    /**
55
     * Initialize the subject instance.
56
     *
57
     * @param \TechDivision\Import\Serializer\SerializerFactoryInterface $serializerFactory The serializer factory instance
58
     * @param \TechDivision\Import\Observers\StateDetectorInterface|null $stateDetector     The state detector instance to use
59
     */
60
    public function __construct(
61
        SerializerFactoryInterface $serializerFactory,
62
        StateDetectorInterface $stateDetector = null
63
    ) {
64
65
        // initialize the bunch processor and the attribute loader instance
66
        $this->serializerFactory = $serializerFactory;
67
68
        // pass the state detector to the parent method
69
        parent::__construct($stateDetector);
70
    }
71
72
    /**
73
     * Will be invoked by the observer visitor when a factory has been defined to create the observer instance.
74
     *
75
     * @param \TechDivision\Import\Subjects\SubjectInterface $subject The subject instance
76
     *
77
     * @return \TechDivision\Import\Observers\ObserverInterface The observer instance
78
     */
79
    public function createObserver(SubjectInterface $subject)
80
    {
81
82
        // initialize the serializer instance
83
        $this->serializer = $this->serializerFactory->createSerializer($subject->getConfiguration()->getImportAdapter());
0 ignored issues
show
Documentation introduced by
$subject->getConfiguration()->getImportAdapter() is of type object<TechDivision\Impo...ConfigurationInterface>, but the function expects a object<TechDivision\Impo...ConfigurationInterface>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
84
85
        // return the initialized instance
86
        return $this;
87
    }
88
89
    /**
90
     * Will be invoked by the action on the events the listener has been registered for.
91
     *
92
     * @param \TechDivision\Import\Subjects\SubjectInterface $subject The subject instance
93
     *
94
     * @return array The modified row
95
     * @see \TechDivision\Import\Observers\ObserverInterface::handle()
96
     */
97
    public function handle(SubjectInterface $subject)
98
    {
99
100
        // initialize the row
101
        $this->setSubject($subject);
102
        $this->setRow($subject->getRow());
103
104
        // process the functionality and return the row
105
        $this->process();
106
107
        // return the processed row
108
        return $this->getRow();
109
    }
110
111
    /**
112
     * Process the observer's business logic.
113
     *
114
     * @return array The processed row
115
     */
116
    protected function process()
117
    {
118
119
        // query whether or not the row has additional attributes
120
        if ($additionalAttributes = $this->getValue(ColumnKeys::ADDITIONAL_ATTRIBUTES)) {
121
            // load the subject instance
122
            $subject = $this->getSubject();
123
            // explode the additional attributes
124
            $additionalAttributes = $this->serializer->explode($additionalAttributes);
125
            // iterate over the attributes and append them to the row
126
            foreach ($additionalAttributes as $additionalAttribute) {
0 ignored issues
show
Bug introduced by
The expression $additionalAttributes of type array|null is not guaranteed to be traversable. How about adding an additional type check?

There are different options of fixing this problem.

  1. If you want to be on the safe side, you can add an additional type-check:

    $collection = json_decode($data, true);
    if ( ! is_array($collection)) {
        throw new \RuntimeException('$collection must be an array.');
    }
    
    foreach ($collection as $item) { /** ... */ }
    
  2. If you are sure that the expression is traversable, you might want to add a doc comment cast to improve IDE auto-completion and static analysis:

    /** @var array $collection */
    $collection = json_decode($data, true);
    
    foreach ($collection as $item) { /** .. */ }
    
  3. Mark the issue as a false-positive: Just hover the remove button, in the top-right corner of this issue for more options.

Loading history...
127
                // initialize the option value
128
                $optionValue = '';
129
                // explode the attribute code/option value from the attribute
130
                $exploded = $this->serializer->explode($additionalAttribute, '=');
131
                // initialize attribute code and option value, depending on what we've exploded
132
                if (sizeof($exploded) < 1) {
133
                    continue;
134
                } elseif (sizeof($exploded) === 1) {
135
                    list ($attributeCode) = $exploded;
136
                } else {
137
                    list ($attributeCode, $optionValue) = $exploded;
138
                }
139
140
                // try to load the appropriate key for the value
141
                if ($subject->hasHeader($attributeCode) === false) {
142
                    $subject->addHeader($attributeCode);
143
                }
144
145
                // append/replace the attribute value
146
                $this->setValue($attributeCode, $optionValue);
147
148
                // add a log message in debug mod
149
                if ($subject->isDebugMode()) {
150
                    $subject->getSystemLogger()->debug(
151
                        sprintf(
152
                            'Extract new column "%s" with value "%s" from column "%s" in file %s on line %d',
153
                            $attributeCode,
154
                            $optionValue,
155
                            ColumnKeys::ADDITIONAL_ATTRIBUTES,
156
                            $subject->getFilename(),
157
                            $subject->getLineNumber()
158
                        )
159
                    );
160
                }
161
            }
162
        }
163
    }
164
}
165