Completed
Push — master ( 313f20...c23fe9 )
by Tim
9s
created

AttributeObserverTrait::persistTextAttribute()

Size

Total Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 1
ccs 0
cts 0
cp 0
c 0
b 0
f 0
nc 1
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\LoggerKeys;
24
use TechDivision\Import\Utils\MemberNames;
25
use TechDivision\Import\Utils\EntityStatus;
26
use TechDivision\Import\Utils\StoreViewCodes;
27
use TechDivision\Import\Utils\BackendTypeKeys;
28
use TechDivision\Import\Utils\ConfigurationKeys;
29
30
/**
31
 * Observer that creates/updates the EAV attributes.
32
 *
33
 * @author    Tim Wagner <[email protected]>
34
 * @copyright 2016 TechDivision GmbH <[email protected]>
35
 * @license   http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
36
 * @link      https://github.com/techdivision/import
37
 * @link      http://www.techdivision.com
38
 */
39
trait AttributeObserverTrait
40
{
41
42
    /**
43
     * The ID of the attribute to create the values for.
44
     *
45
     * @var integer
46
     */
47
    protected $attributeId;
48
49
    /**
50
     * The attribute code of the attribute to create the values for.
51
     *
52
     * @var string
53
     */
54
    protected $attributeCode;
55
56
    /**
57
     * The backend type of the attribute to create the values for.
58
     *
59
     * @var string
60
     */
61
    protected $backendType;
62
63
    /**
64
     * The attribute value to process.
65
     *
66
     * @var mixed
67
     */
68
    protected $attributeValue;
69
70
    /**
71
     * The array with the column keys that has to be cleaned up when their values are empty.
72
     *
73
     * @var array
74
     */
75
    protected $cleanUpEmptyColumnKeys;
76
77
    /**
78
     * The entity's existing attribues.
79
     *
80
     * @var array
81
     */
82
    protected $attributes;
83
84
    /**
85
     * The attribute code that has to be processed.
86
     *
87
     * @return string The attribute code
88
     */
89 1
    public function getAttributeCode()
90
    {
91 1
        return $this->attributeCode;
92
    }
93
94
    /**
95
     * The attribute value that has to be processed.
96
     *
97
     * @return string The attribute value
98
     */
99 1
    public function getAttributeValue()
100
    {
101 1
        return $this->attributeValue;
102
    }
103
104
    /**
105
     * Remove all the empty values from the row and return the cleared row.
106
     *
107
     * @return array The cleared row
108
     */
109 7
    protected function clearRow()
110
    {
111
112
        // query whether or not the column keys has been initialized
113 7
        if ($this->cleanUpEmptyColumnKeys === null) {
114
            // initialize the array with the column keys that has to be cleaned-up
115 7
            $this->cleanUpEmptyColumnKeys = array();
116
117
            // query whether or not column names that has to be cleaned up have been configured
118 7
            if ($this->getSubject()->getConfiguration()->hasParam(ConfigurationKeys::CLEAN_UP_EMPTY_COLUMNS)) {
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...
119
                // if yes, load the column names
120
                $cleanUpEmptyColumns = $this->getSubject()->getCleanUpColumns();
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...
121
122
                // translate the column names into column keys
123
                foreach ($cleanUpEmptyColumns as $cleanUpEmptyColumn) {
124
                    if ($this->hasHeader($cleanUpEmptyColumn)) {
0 ignored issues
show
Bug introduced by
It seems like hasHeader() 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...
125
                        $this->cleanUpEmptyColumnKeys[] = $this->getHeader($cleanUpEmptyColumn);
0 ignored issues
show
Bug introduced by
It seems like getHeader() 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...
126
                    }
127
                }
128
            }
129
        }
130
131
        // remove all the empty values from the row, expected the columns has to be cleaned-up
132 7
        return array_filter(
133 7
            $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...
134 7
            function ($value, $key) {
135 7
                return ($value !== null && $value !== '') || in_array($key, $this->cleanUpEmptyColumnKeys);
136 7
            },
137 7
            ARRAY_FILTER_USE_BOTH
138
        );
139
    }
140
141
    /**
142
     * Process the observer's business logic.
143
     *
144
     * @return void
145
     */
146 7
    protected function process()
147
    {
148
149
        // initialize the store view code
150 7
        $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...
151
152
        // load the PK
153 7
        $pk = $this->getValue($this->getPrimaryKeyColumnName());
0 ignored issues
show
Bug introduced by
It seems like getValue() 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...
154
155
        // load the store ID, use the admin store if NO store view code has been set
156 7
        $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...
157
158
        // load the entity's existing attributes
159 7
        $this->getAttributesByPrimaryKeyAndStoreId($this->getPrimaryKey(), $storeId);
160
161
        // load the store view - if no store view has been set, we assume the admin
162
        // store view, which will contain the default (fallback) attribute values
163 7
        $storeViewCode = $this->getSubject()->getStoreViewCode(StoreViewCodes::ADMIN);
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...
164
165
        // query whether or not the row has already been processed
166 7
        if ($this->storeViewHasBeenProcessed($pk, $storeViewCode)) {
167
            // log a message
168
            $this->getSystemLogger()->warning(
169
                $this->appendExceptionSuffix(
0 ignored issues
show
Bug introduced by
It seems like appendExceptionSuffix() 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...
170
                    sprintf(
171
                        'Attributes for %s "%s" + store view code "%s" has already been processed',
172
                        $this->getPrimaryKeyColumnName(),
173
                        $pk,
174
                        $storeViewCode
175
                    )
176
                )
177
            );
178
179
            // return immediately
180
            return;
181
        }
182
183
        // load the attributes by the found attribute set and the backend types
184 7
        $attributes = $this->getAttributes();
185 7
        $backendTypes = $this->getBackendTypes();
186
187
        // load the header keys
188 7
        $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...
189
190
        // remove all the empty values from the row
191 7
        $row = $this->clearRow();
192
193
        // iterate over the attributes and append them to the row
194 7
        foreach ($row as $key => $attributeValue) {
195
            // query whether or not attribute with the found code exists
196 6
            if (!isset($attributes[$attributeCode = $headers[$key]])) {
197
                // log a message in debug mode
198 1
                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...
199 1
                    $this->getSystemLogger()->debug(
200 1
                        $this->appendExceptionSuffix(
0 ignored issues
show
Bug introduced by
It seems like appendExceptionSuffix() 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...
201 1
                            sprintf(
202 1
                                'Can\'t find attribute with attribute code %s',
203 1
                                $attributeCode
204
                            )
205
                        )
206
                    );
207
                }
208
209
                // stop processing
210 1
                continue;
211
0 ignored issues
show
Coding Style introduced by
Blank line found at end of control structure
Loading history...
212
            } else {
213
                // log a message in debug mode
214 5
                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...
215
                // log a message in debug mode
216 2
                    $this->getSystemLogger()->debug(
217 2
                        $this->appendExceptionSuffix(
0 ignored issues
show
Bug introduced by
It seems like appendExceptionSuffix() 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 2
                            sprintf(
219 2
                                'Found attribute with attribute code %s',
220 2
                                $attributeCode
221
                            )
222
                        )
223
                    );
224
                }
225
            }
226
227
            // if yes, load the attribute by its code
228 5
            $attribute = $attributes[$attributeCode];
229
230
            // load the backend type => to find the apropriate entity
231 5
            $backendType = $attribute[MemberNames::BACKEND_TYPE];
232 5
            if ($backendType === null) {
233
                // log a message in debug mode
234 1
                $this->getSystemLogger()->warning(
235 1
                    $this->appendExceptionSuffix(
0 ignored issues
show
Bug introduced by
It seems like appendExceptionSuffix() 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...
236 1
                        sprintf(
237 1
                            'Found EMTPY backend type for attribute %s',
238 1
                            $attributeCode
239
                        )
240
                    )
241
                );
242
                // stop processing
243 1
                continue;
244
            }
245
246
            // do nothing on static backend type
247 4
            if ($backendType === BackendTypeKeys::BACKEND_TYPE_STATIC) {
248 1
                continue;
249
            }
250
251
            // query whether or not we've found a supported backend type
252 3
            if (isset($backendTypes[$backendType])) {
253
                // initialize attribute ID/code and backend type
254 2
                $this->attributeId = $attribute[MemberNames::ATTRIBUTE_ID];
255 2
                $this->attributeCode = $attributeCode;
256 2
                $this->backendType = $backendType;
257
258
                // initialize the persist method for the found backend type
259 2
                list ($persistMethod, , $deleteMethod) = $backendTypes[$backendType];
260
261
                // set the attribute value
262 2
                $this->attributeValue = $attributeValue;
263
264
                // prepare/initialize the attribute value
265 2
                $value = $this->initializeAttribute($this->prepareAttributes());
0 ignored issues
show
Bug introduced by
It seems like $this->prepareAttributes() targeting TechDivision\Import\Obse...it::prepareAttributes() can also be of type null; however, TechDivision\Import\Obse...::initializeAttribute() does only seem to accept array, maybe add an additional type check?

This check looks at variables that are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
266
267
                // query whether or not the entity's value has to be persisted or deleted. if the value is
268
                // an empty string and the status is UPDATE, then the value exists and has to be deleted
269 2
                if ($value[MemberNames::VALUE] === '' && $value[EntityStatus::MEMBER_NAME] === EntityStatus::STATUS_UPDATE) {
270
                    $this->$deleteMethod(array(MemberNames::VALUE_ID => $value[MemberNames::VALUE_ID]));
271 2
                } elseif ($value[MemberNames::VALUE] !== '' && $value[MemberNames::VALUE] !== null) {
272 1
                    $this->$persistMethod($value);
273
                } else {
274
                    // log a debug message, because this should never happen
275 1
                    $this->getSubject()->getSystemLogger()->debug(sprintf('Found empty value for attribute "%s"', $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...
276
                }
277
278
                // continue with the next value
279 2
                continue;
280
            }
281
282
            // log the debug message
283 1
            $this->getSystemLogger()->debug(
284 1
                $this->getSubject()->appendExceptionSuffix(
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...
285 1
                    sprintf(
286 1
                        'Found invalid backend type %s for attribute %s',
287 1
                        $backendType,
288 1
                        $attributeCode
289
                    )
290
                )
291
            );
292
        }
293 7
    }
294
295
    /**
296
     * Prepare the attributes of the entity that has to be persisted.
297
     *
298
     * @return array|null The prepared attributes
299
     */
300 2
    protected function prepareAttributes()
301
    {
302
303
        // laod the callbacks for the actual attribute code
304 2
        $callbacks = $this->getCallbacksByType($this->attributeCode);
305
306
        // invoke the pre-cast callbacks
307 2
        foreach ($callbacks as $callback) {
308 1
            $this->attributeValue = $callback->handle($this);
309
        }
310
311
        // load the ID of the product that has been created recently
312 2
        $lastEntityId = $this->getPrimaryKey();
313
314
        // load the store ID, use the admin store if NO store view code has been set
315 2
        $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...
316
317
        // cast the value based on the backend type
318 2
        $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...
319
320
        // prepare the attribute values
321 2
        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...
322
            array(
323 2
               $this->getPrimaryKeyMemberName() => $lastEntityId,
324 2
                MemberNames::ATTRIBUTE_ID       => $this->attributeId,
325 2
                MemberNames::STORE_ID           => $storeId,
326 2
                MemberNames::VALUE              => $castedValue
327
            )
328
        );
329
    }
330
331
    /**
332
     * Initialize the category product with the passed attributes and returns an instance.
333
     *
334
     * @param array $attr The category product attributes
335
     *
336
     * @return array The initialized category product
337
     */
338 2
    protected function initializeAttribute(array $attr)
339
    {
340 2
        return $attr;
341
    }
342
343
    /**
344
     * Return's the array with callbacks for the passed type.
345
     *
346
     * @param string $type The type of the callbacks to return
347
     *
348
     * @return array The callbacks
349
     */
350 2
    protected function getCallbacksByType($type)
351
    {
352 2
        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...
353
    }
354
355
    /**
356
     * Return's mapping for the supported backend types (for the product entity) => persist methods.
357
     *
358
     * @return array The mapping for the supported backend types
359
     */
360 7
    protected function getBackendTypes()
361
    {
362 7
        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...
363
    }
364
365
    /**
366
     * Return's the attributes for the attribute set of the product that has to be created.
367
     *
368
     * @return array The attributes
369
     * @throws \Exception
370
     */
371 7
    protected function getAttributes()
372
    {
373 7
        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...
374
    }
375
376
    /**
377
     * Intializes the existing attributes for the entity with the passed primary key.
378
     *
379
     * @param string  $pk      The primary key of the entity to load the attributes for
380
     * @param integer $storeId The ID of the store view to load the attributes for
381
     *
382
     * @return array The entity attributes
383
     */
384
    abstract protected function getAttributesByPrimaryKeyAndStoreId($pk, $storeId);
385
386
    /**
387
     * Return's the logger with the passed name, by default the system logger.
388
     *
389
     * @param string $name The name of the requested system logger
390
     *
391
     * @return \Psr\Log\LoggerInterface The logger instance
392
     * @throws \Exception Is thrown, if the requested logger is NOT available
393
     */
394
    abstract protected function getSystemLogger($name = LoggerKeys::SYSTEM);
395
396
    /**
397
     * Return's the PK to create the product => attribute relation.
398
     *
399
     * @return integer The PK to create the relation with
400
     */
401
    abstract protected function getPrimaryKey();
402
403
    /**
404
     * Return's the PK column name to create the product => attribute relation.
405
     *
406
     * @return string The PK column name
407
     */
408
    abstract protected function getPrimaryKeyMemberName();
409
410
    /**
411
     * Return's the column name that contains the primary key.
412
     *
413
     * @return string the column name that contains the primary key
414
     */
415
    abstract protected function getPrimaryKeyColumnName();
416
417
    /**
418
     * Queries whether or not the passed PK and store view code has already been processed.
419
     *
420
     * @param string $pk            The PK to check been processed
421
     * @param string $storeViewCode The store view code to check been processed
422
     *
423
     * @return boolean TRUE if the PK and store view code has been processed, else FALSE
424
     */
425
    abstract protected function storeViewHasBeenProcessed($pk, $storeViewCode);
426
427
    /**
428
     * Persist's the passed varchar attribute.
429
     *
430
     * @param array $attribute The attribute to persist
431
     *
432
     * @return void
433
     */
434
    abstract protected function persistVarcharAttribute($attribute);
435
436
    /**
437
     * Persist's the passed integer attribute.
438
     *
439
     * @param array $attribute The attribute to persist
440
     *
441
     * @return void
442
     */
443
    abstract protected function persistIntAttribute($attribute);
444
445
    /**
446
     * Persist's the passed decimal attribute.
447
     *
448
     * @param array $attribute The attribute to persist
449
     *
450
     * @return void
451
     */
452
    abstract protected function persistDecimalAttribute($attribute);
453
454
    /**
455
     * Persist's the passed datetime attribute.
456
     *
457
     * @param array $attribute The attribute to persist
458
     *
459
     * @return void
460
     */
461
    abstract protected function persistDatetimeAttribute($attribute);
462
463
    /**
464
     * Persist's the passed text attribute.
465
     *
466
     * @param array $attribute The attribute to persist
467
     *
468
     * @return void
469
     */
470
    abstract protected function persistTextAttribute($attribute);
471
472
    /**
473
     * Delete's the datetime attribute with the passed value ID.
474
     *
475
     * @param array       $row  The attributes of the entity to delete
476
     * @param string|null $name The name of the prepared statement that has to be executed
477
     *
478
     * @return void
479
     */
480
    abstract protected function deleteDatetimeAttribute(array $row, $name = null);
481
482
    /**
483
     * Delete's the decimal attribute with the passed value ID.
484
     *
485
     * @param array       $row  The attributes of the entity to delete
486
     * @param string|null $name The name of the prepared statement that has to be executed
487
     *
488
     * @return void
489
     */
490
    abstract protected function deleteDecimalAttribute(array $row, $name = null);
491
492
    /**
493
     * Delete's the integer attribute with the passed value ID.
494
     *
495
     * @param array       $row  The attributes of the entity to delete
496
     * @param string|null $name The name of the prepared statement that has to be executed
497
     *
498
     * @return void
499
     */
500
    abstract protected function deleteIntAttribute(array $row, $name = null);
501
502
    /**
503
     * Delete's the text attribute with the passed value ID.
504
     *
505
     * @param array       $row  The attributes of the entity to delete
506
     * @param string|null $name The name of the prepared statement that has to be executed
507
     *
508
     * @return void
509
     */
510
    abstract protected function deleteTextAttribute(array $row, $name = null);
511
512
    /**
513
     * Delete's the varchar attribute with the passed value ID.
514
     *
515
     * @param array       $row  The attributes of the entity to delete
516
     * @param string|null $name The name of the prepared statement that has to be executed
517
     *
518
     * @return void
519
     */
520
    abstract protected function deleteVarcharAttribute(array $row, $name = null);
521
}
522