Completed
Push — master ( 7dfda5...6b6b2c )
by Tim
10s
created

AttributeObserverTrait::getRowStoreId()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 4
ccs 0
cts 4
cp 0
rs 10
c 0
b 0
f 0
cc 1
eloc 2
nc 1
nop 1
crap 2
1
<?php
2
3
/**
4
 * TechDivision\Import\Observers\AttributeObserverTrait
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\MemberNames;
24
use TechDivision\Import\Utils\StoreViewCodes;
25
use TechDivision\Import\Utils\BackendTypeKeys;
26
27
/**
28
 * Observer that creates/updates the EAV attributes.
29
 *
30
 * @author    Tim Wagner <[email protected]>
31
 * @copyright 2016 TechDivision GmbH <[email protected]>
32
 * @license   http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
33
 * @link      https://github.com/techdivision/import
34
 * @link      http://www.techdivision.com
35
 */
36
trait AttributeObserverTrait
37
{
38
39
    /**
40
     * The ID of the attribute to create the values for.
41
     *
42
     * @var integer
43
     */
44
    protected $attributeId;
45
46
    /**
47
     * The attribute code of the attribute to create the values for.
48
     *
49
     * @var string
50
     */
51
    protected $attributeCode;
52
53
    /**
54
     * The backend type of the attribute to create the values for.
55
     *
56
     * @var string
57
     */
58
    protected $backendType;
59
60
    /**
61
     * The attribute value to process.
62
     *
63
     * @var mixed
64
     */
65
    protected $attributeValue;
66
67
    /**
68
     * Process the observer's business logic.
69
     *
70
     * @return void
71
     */
72
    protected function process()
73
    {
74
75
        // initialize the store view code
76
        $this->prepareStoreViewCode();
0 ignored issues
show
Bug introduced by
It seems like prepareStoreViewCode() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
77
78
        // load the attributes by the found attribute set and the backend types
79
        $attributes = $this->getAttributes();
80
        $backendTypes = $this->getBackendTypes();
81
82
        // remove all the empty values from the row
83
        $row = array_filter(
84
            $this->row,
0 ignored issues
show
Bug introduced by
The property row does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
85
            function ($value, $key) {
0 ignored issues
show
Unused Code introduced by
The parameter $key is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
86
                return ($value !== null && $value !== '');
87
            },
88
            ARRAY_FILTER_USE_BOTH
89
        );
90
91
        // load the header keys
92
        $headers = array_flip($this->getHeaders());
0 ignored issues
show
Bug introduced by
It seems like getHeaders() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
93
94
        // iterate over the attributes and append them to the row
95
        foreach ($row as $key => $attributeValue) {
96
            // query whether or not attribute with the found code exists
97
            if (!isset($attributes[$attributeCode = $headers[$key]])) {
98
                // log a message in debug mode
99
                if ($this->isDebugMode()) {
0 ignored issues
show
Bug introduced by
It seems like isDebugMode() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
100
                    $this->getSystemLogger()->debug(
0 ignored issues
show
Bug introduced by
It seems like getSystemLogger() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
101
                        sprintf(
102
                            'Can\'t find attribute with attribute code %s in file %s on line %d',
103
                            $attributeCode,
104
                            $this->getFilename(),
0 ignored issues
show
Bug introduced by
It seems like getFilename() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
105
                            $this->getLineNumber()
0 ignored issues
show
Bug introduced by
It seems like getLineNumber() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
106
                        )
107
                    );
108
                }
109
110
                // stop processing
111
                continue;
112
0 ignored issues
show
Coding Style introduced by
Blank line found at end of control structure
Loading history...
113
            } else {
114
                // log a message in debug mode
115
                if ($this->isDebugMode()) {
0 ignored issues
show
Bug introduced by
It seems like isDebugMode() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
116
                    $this->getSystemLogger()->debug(
0 ignored issues
show
Bug introduced by
It seems like getSystemLogger() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
117
                        sprintf(
118
                            'Found attribute with attribute code %s in file %s on line %d',
119
                            $attributeCode,
120
                            $this->getFilename(),
0 ignored issues
show
Bug introduced by
It seems like getFilename() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
121
                            $this->getLineNumber()
0 ignored issues
show
Bug introduced by
It seems like getLineNumber() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
122
                        )
123
                    );
124
                }
125
            }
126
127
            // if yes, load the attribute by its code
128
            $attribute = $attributes[$attributeCode];
129
130
            // load the backend type => to find the apropriate entity
131
            $backendType = $attribute[MemberNames::BACKEND_TYPE];
132
            if ($backendType == null) {
133
                $this->getSystemLogger()->warning(
0 ignored issues
show
Bug introduced by
It seems like getSystemLogger() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
134
                    sprintf(
135
                        'Found EMTPY backend type for attribute %s in file %s on line %d',
136
                        $attributeCode,
137
                        $this->getFilename(),
0 ignored issues
show
Bug introduced by
It seems like getFilename() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
138
                        $this->getLineNumber()
0 ignored issues
show
Bug introduced by
It seems like getLineNumber() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
139
                    )
140
                );
141
                continue;
142
            }
143
144
            // do nothing on static backend type
145
            if ($backendType === BackendTypeKeys::BACKEND_TYPE_STATIC) {
146
                continue;
147
            }
148
149
            // query whether or not we've found a supported backend type
150
            if (isset($backendTypes[$backendType])) {
151
                // initialize attribute ID/code and backend type
152
                $this->attributeId = $attribute[MemberNames::ATTRIBUTE_ID];
153
                $this->attributeCode = $attributeCode;
154
                $this->backendType = $backendType;
155
156
                // initialize the persist method for the found backend type
157
                list ($persistMethod, ) = $backendTypes[$backendType];
158
159
                // set the attribute value
160
                $this->attributeValue = $attributeValue;
161
162
                // try to prepare the attribute values
163
                if ($attr = $this->prepareAttributes()) {
164
                    // initialize and persist the attribute
165
                    $entity = $this->initializeAttribute($attr);
166
                    $this->$persistMethod($entity);
167
                }
168
169
                // continue with the next value
170
                continue;
171
            }
172
173
            // log the debug message
174
            $this->getSystemLogger()->debug(
0 ignored issues
show
Bug introduced by
It seems like getSystemLogger() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
175
                sprintf(
176
                    'Found invalid backend type %s for attribute %s in file %s on line %s',
177
                    $this->backendType,
178
                    $this->attributeCode,
179
                    $this->getFilename(),
0 ignored issues
show
Bug introduced by
It seems like getFilename() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
180
                    $this->getLineNumber()
0 ignored issues
show
Bug introduced by
It seems like getLineNumber() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
181
                )
182
            );
183
        }
184
    }
185
186
    /**
187
     * Prepare the attributes of the entity that has to be persisted.
188
     *
189
     * @return array|null The prepared attributes
190
     */
191
    protected function prepareAttributes()
192
    {
193
194
        // laod the callbacks for the actual attribute code
195
        $callbacks = $this->getCallbacksByType($this->attributeCode);
196
197
        // invoke the pre-cast callbacks
198
        foreach ($callbacks as $callback) {
199
            $this->attributeValue = $callback->handle($this->attributeCode, $this->attributeValue);
200
        }
201
202
        // query whether or not the attribute has been be processed by the callbacks
203
        if ($this->attributeValue === null) {
204
            return;
205
        }
206
207
        // load the ID of the product that has been created recently
208
        $lastEntityId = $this->getPrimaryKey();
209
210
        // load the store ID
211
        $storeId = $this->getRowStoreId(StoreViewCodes::ADMIN);
0 ignored issues
show
Bug introduced by
It seems like getRowStoreId() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
212
213
        // cast the value based on the backend type
214
        $castedValue = $this->castValueByBackendType($this->backendType, $this->attributeValue);
0 ignored issues
show
Bug introduced by
It seems like castValueByBackendType() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
215
216
        // prepare the attribute values
217
        return $this->initializeEntity(
0 ignored issues
show
Bug introduced by
It seems like initializeEntity() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
218
            array(
219
                MemberNames::ENTITY_ID    => $lastEntityId,
220
                MemberNames::ATTRIBUTE_ID => $this->attributeId,
221
                MemberNames::STORE_ID     => $storeId,
222
                MemberNames::VALUE        => $castedValue
223
            )
224
        );
225
    }
226
227
    /**
228
     * Initialize the category product with the passed attributes and returns an instance.
229
     *
230
     * @param array $attr The category product attributes
231
     *
232
     * @return array The initialized category product
233
     */
234
    protected function initializeAttribute(array $attr)
235
    {
236
        return $attr;
237
    }
238
239
    /**
240
     * Return's the PK to create the product => attribute relation.
241
     *
242
     * @return integer The PK to create the relation with
243
     */
244
    protected function getPrimaryKey()
245
    {
246
        return $this->getLastEntityId();
0 ignored issues
show
Bug introduced by
It seems like getLastEntityId() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
247
    }
248
249
    /**
250
     * Map the passed attribute code, if a header mapping exists and return the
251
     * mapped mapping.
252
     *
253
     * @param string $attributeCode The attribute code to map
254
     *
255
     * @return string The mapped attribute code, or the original one
256
     */
257
    protected function mapAttributeCodeByHeaderMapping($attributeCode)
258
    {
259
        return $this->getSubject()->mapAttributeCodeByHeaderMapping($attributeCode);
0 ignored issues
show
Bug introduced by
It seems like getSubject() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
260
    }
261
262
    /**
263
     * Return's the array with callbacks for the passed type.
264
     *
265
     * @param string $type The type of the callbacks to return
266
     *
267
     * @return array The callbacks
268
     */
269
    protected function getCallbacksByType($type)
270
    {
271
        return $this->getSubject()->getCallbacksByType($type);
0 ignored issues
show
Bug introduced by
It seems like getSubject() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
272
    }
273
274
    /**
275
     * Return's mapping for the supported backend types (for the product entity) => persist methods.
276
     *
277
     * @return array The mapping for the supported backend types
278
     */
279
    protected function getBackendTypes()
280
    {
281
        return $this->getSubject()->getBackendTypes();
0 ignored issues
show
Bug introduced by
It seems like getSubject() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
282
    }
283
284
    /**
285
     * Return's the attributes for the attribute set of the product that has to be created.
286
     *
287
     * @return array The attributes
288
     * @throws \Exception
289
     */
290
    protected function getAttributes()
291
    {
292
        return $this->getSubject()->getAttributes();
0 ignored issues
show
Bug introduced by
It seems like getSubject() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
293
    }
294
}
295