Completed
Push — 17.x ( b10fe2...726eb0 )
by Tim
08:00 queued 06:27
created

AttributeObserverTrait::getPrimaryKeyColumnName()

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
     * @todo Move initialization of $this->cleanUpEmptyColumnKeys to createObserver() method and implement ObserverFactoryInterface
109
     */
110 7
    protected function clearRow()
111
    {
112
113
        // query whether or not the column keys has been initialized
114 7
        if ($this->cleanUpEmptyColumnKeys === null) {
115
            // initialize the array with the column keys that has to be cleaned-up
116 7
            $this->cleanUpEmptyColumnKeys = array();
117
118
            // query whether or not column names that has to be cleaned up have been configured
119 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...
120
                // if yes, load the column names
121
                $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...
122
123
                // translate the column names into column keys
124
                foreach ($cleanUpEmptyColumns as $cleanUpEmptyColumn) {
125
                    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...
126
                        $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...
127
                    }
128
                }
129
            }
130
        }
131
132
        // remove all the empty values from the row, expected the columns has to be cleaned-up
133 7
        foreach ($this->row as $key => $value) {
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
            // query whether or not the value is empty AND the column has NOT to be cleaned-up
135 7
            if (($value === null || $value === '') && in_array($key, $this->cleanUpEmptyColumnKeys) === false) {
136 1
                unset($this->row[$key]);
137
            }
138
        }
139
140
        // finally return the clean row
141 7
        return $this->row;
142
    }
143
144
    /**
145
     * Returns the value(s) of the primary key column(s). As the primary key column can
146
     * also consist of two columns, the return value can be an array also.
147
     *
148
     * @return mixed The primary key value(s)
149
     */
150 7
    protected function getPrimaryKeyValue()
151
    {
152 7
        return $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...
153
    }
154
155
    /**
156
     * Process the observer's business logic.
157
     *
158
     * @return void
159
     */
160 7
    protected function process()
161
    {
162
163
        // initialize the store view code
164 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...
165
166
        // load the store ID, use the admin store if NO store view code has been set
167 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...
168
169
        // load the entity's existing attributes
170 7
        $this->getAttributesByPrimaryKeyAndStoreId($this->getPrimaryKey(), $storeId);
171
172
        // load the store view - if no store view has been set, we assume the admin
173
        // store view, which will contain the default (fallback) attribute values
174 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...
175
176
        // query whether or not the row has already been processed
177 7
        if ($this->storeViewHasBeenProcessed($pk = $this->getPrimaryKeyValue(), $storeViewCode)) {
178
            // log a message
179
            $this->getSystemLogger()->warning(
180
                $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...
181
                    sprintf(
182
                        'Attributes for "%s" "%s" + store view code "%s" has already been processed',
183
                        $this->getPrimaryKeyColumnName(),
184
                        $pk,
185
                        $storeViewCode
186
                    )
187
                )
188
            );
189
190
            // return immediately
191
            return;
192
        }
193
194
        // load the attributes by the found attribute set and the backend types
195 7
        $attributes = $this->getAttributes();
196 7
        $backendTypes = $this->getBackendTypes();
197
198
        // load the header keys
199 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...
200
201
        // remove all the empty values from the row
202 7
        $row = $this->clearRow();
203
204
        // iterate over the attributes and append them to the row
205 7
        foreach ($row as $key => $attributeValue) {
206
            // query whether or not attribute with the found code exists
207 6
            if (!isset($attributes[$attributeCode = $headers[$key]])) {
208
                // log a message in debug mode
209 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...
210 1
                    $this->getSystemLogger()->debug(
211 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...
212 1
                            sprintf(
213 1
                                'Can\'t find attribute with attribute code "%s"',
214
                                $attributeCode
215
                            )
216
                        )
217
                    );
218
                }
219
220
                // stop processing
221 1
                continue;
222
            } else {
223
                // log a message in debug mode
224 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...
225
                // log a message in debug mode
226 2
                    $this->getSystemLogger()->debug(
227 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...
228 2
                            sprintf(
229 2
                                'Found attribute with attribute code "%s"',
230
                                $attributeCode
231
                            )
232
                        )
233
                    );
234
                }
235
            }
236
237
            // if yes, load the attribute by its code
238 5
            $attribute = $attributes[$attributeCode];
239
240
            // load the backend type => to find the apropriate entity
241 5
            $backendType = $attribute[MemberNames::BACKEND_TYPE];
242 5
            if ($backendType === null) {
243
                // log a message in debug mode
244 1
                $this->getSystemLogger()->warning(
245 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...
246 1
                        sprintf(
247 1
                            'Found EMTPY backend type for attribute "%s"',
248
                            $attributeCode
249
                        )
250
                    )
251
                );
252
                // stop processing
253 1
                continue;
254
            }
255
256
            // do nothing on static backend type
257 4
            if ($backendType === BackendTypeKeys::BACKEND_TYPE_STATIC) {
258 1
                continue;
259
            }
260
261
            // query whether or not we've found a supported backend type
262 3
            if (isset($backendTypes[$backendType])) {
263
                // initialize attribute ID/code and backend type
264 2
                $this->attributeId = $attribute[MemberNames::ATTRIBUTE_ID];
265 2
                $this->attributeCode = $attributeCode;
266 2
                $this->backendType = $backendType;
267
268
                // initialize the persist method for the found backend type
269 2
                list ($persistMethod, , $deleteMethod) = $backendTypes[$backendType];
270
271
                // set the attribute value
272 2
                $this->attributeValue = $attributeValue;
273
274
                // prepare the attribute vale and query whether or not it has to be persisted
275 2
                if ($this->hasChanges($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...
276
                    // query whether or not the entity's value has to be persisted or deleted. if the value is
277
                    // an empty string and the status is UPDATE, then the value exists and has to be deleted
278
                    // We need to user $attributeValue instead of $value[MemberNames::VALUE] in cases where
279
                    // value was casted by attribute type. E.g. special_price = 0 if value is empty string in CSV
280 2
                    if ($attributeValue === '' && $value[EntityStatus::MEMBER_NAME] === EntityStatus::STATUS_UPDATE) {
281
                        $this->$deleteMethod(array(MemberNames::VALUE_ID => $value[MemberNames::VALUE_ID]));
282 2
                    } elseif ($attributeValue !== '' && $value[MemberNames::VALUE] !== null) {
283 1
                        $this->$persistMethod($value);
284
                    } else {
285
                        // log a debug message, because this should never happen
286 2
                        $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...
287
                    }
288
                } else {
289
                    $this->getSubject()->getSystemLogger()->debug(sprintf('Skip to persist 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...
290
                }
291
292
                // continue with the next value
293 2
                continue;
294
            }
295
296
            // log the debug message
297 1
            $this->getSystemLogger()->debug(
298 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...
299 1
                    sprintf(
300 1
                        'Found invalid backend type %s for attribute "%s"',
301
                        $backendType,
302
                        $attributeCode
303
                    )
304
                )
305
            );
306
        }
307 7
    }
308
309
    /**
310
     * Prepare the attributes of the entity that has to be persisted.
311
     *
312
     * @return array|null The prepared attributes
313
     */
314 2
    protected function prepareAttributes()
315
    {
316
317
        // laod the callbacks for the actual attribute code
318 2
        $callbacks = $this->getCallbacksByType($this->attributeCode);
319
320
        // invoke the pre-cast callbacks
321 2
        foreach ($callbacks as $callback) {
322 1
            $this->attributeValue = $callback->handle($this);
323
        }
324
325
        // load the ID of the product that has been created recently
326 2
        $lastEntityId = $this->getPrimaryKey();
327
328
        // load the store ID, use the admin store if NO store view code has been set
329 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...
330
331
        // cast the value based on the backend type
332 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...
333
334
        // prepare the attribute values
335 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...
336
            array(
337 2
               $this->getPrimaryKeyMemberName() => $lastEntityId,
338 2
                MemberNames::ATTRIBUTE_ID       => $this->attributeId,
339 2
                MemberNames::STORE_ID           => $storeId,
340 2
                MemberNames::VALUE              => $castedValue
341
            )
342
        );
343
    }
344
345
    /**
346
     * Initialize the category product with the passed attributes and returns an instance.
347
     *
348
     * @param array $attr The category product attributes
349
     *
350
     * @return array The initialized category product
351
     */
352 2
    protected function initializeAttribute(array $attr)
353
    {
354 2
        return $attr;
355
    }
356
357
    /**
358
     * Return's the array with callbacks for the passed type.
359
     *
360
     * @param string $type The type of the callbacks to return
361
     *
362
     * @return array The callbacks
363
     */
364 2
    protected function getCallbacksByType($type)
365
    {
366 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...
367
    }
368
369
    /**
370
     * Return's mapping for the supported backend types (for the product entity) => persist methods.
371
     *
372
     * @return array The mapping for the supported backend types
373
     */
374 7
    protected function getBackendTypes()
375
    {
376 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...
377
    }
378
379
    /**
380
     * Return's the attributes for the attribute set of the product that has to be created.
381
     *
382
     * @return array The attributes
383
     * @throws \Exception
384
     */
385 7
    protected function getAttributes()
386
    {
387 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...
388
    }
389
390
    /**
391
     * Intializes the existing attributes for the entity with the passed primary key.
392
     *
393
     * @param string  $pk      The primary key of the entity to load the attributes for
394
     * @param integer $storeId The ID of the store view to load the attributes for
395
     *
396
     * @return array The entity attributes
397
     */
398
    abstract protected function getAttributesByPrimaryKeyAndStoreId($pk, $storeId);
399
400
    /**
401
     * Return's the logger with the passed name, by default the system logger.
402
     *
403
     * @param string $name The name of the requested system logger
404
     *
405
     * @return \Psr\Log\LoggerInterface The logger instance
406
     * @throws \Exception Is thrown, if the requested logger is NOT available
407
     */
408
    abstract protected function getSystemLogger($name = LoggerKeys::SYSTEM);
409
410
    /**
411
     * Return's the PK to create the product => attribute relation.
412
     *
413
     * @return integer The PK to create the relation with
414
     */
415
    abstract protected function getPrimaryKey();
416
417
    /**
418
     * Return's the PK column name to create the product => attribute relation.
419
     *
420
     * @return string The PK column name
421
     */
422
    abstract protected function getPrimaryKeyMemberName();
423
424
    /**
425
     * Return's the column name that contains the primary key.
426
     *
427
     * @return string the column name that contains the primary key
428
     */
429
    abstract protected function getPrimaryKeyColumnName();
430
431
    /**
432
     * Queries whether or not the passed PK and store view code has already been processed.
433
     *
434
     * @param string $pk            The PK to check been processed
435
     * @param string $storeViewCode The store view code to check been processed
436
     *
437
     * @return boolean TRUE if the PK and store view code has been processed, else FALSE
438
     */
439
    abstract protected function storeViewHasBeenProcessed($pk, $storeViewCode);
440
441
    /**
442
     * Persist's the passed varchar attribute.
443
     *
444
     * @param array $attribute The attribute to persist
445
     *
446
     * @return void
447
     */
448
    abstract protected function persistVarcharAttribute($attribute);
449
450
    /**
451
     * Persist's the passed integer attribute.
452
     *
453
     * @param array $attribute The attribute to persist
454
     *
455
     * @return void
456
     */
457
    abstract protected function persistIntAttribute($attribute);
458
459
    /**
460
     * Persist's the passed decimal attribute.
461
     *
462
     * @param array $attribute The attribute to persist
463
     *
464
     * @return void
465
     */
466
    abstract protected function persistDecimalAttribute($attribute);
467
468
    /**
469
     * Persist's the passed datetime attribute.
470
     *
471
     * @param array $attribute The attribute to persist
472
     *
473
     * @return void
474
     */
475
    abstract protected function persistDatetimeAttribute($attribute);
476
477
    /**
478
     * Persist's the passed text attribute.
479
     *
480
     * @param array $attribute The attribute to persist
481
     *
482
     * @return void
483
     */
484
    abstract protected function persistTextAttribute($attribute);
485
486
    /**
487
     * Delete's the datetime attribute with the passed value ID.
488
     *
489
     * @param array       $row  The attributes of the entity to delete
490
     * @param string|null $name The name of the prepared statement that has to be executed
491
     *
492
     * @return void
493
     */
494
    abstract protected function deleteDatetimeAttribute(array $row, $name = null);
495
496
    /**
497
     * Delete's the decimal attribute with the passed value ID.
498
     *
499
     * @param array       $row  The attributes of the entity to delete
500
     * @param string|null $name The name of the prepared statement that has to be executed
501
     *
502
     * @return void
503
     */
504
    abstract protected function deleteDecimalAttribute(array $row, $name = null);
505
506
    /**
507
     * Delete's the integer attribute with the passed value ID.
508
     *
509
     * @param array       $row  The attributes of the entity to delete
510
     * @param string|null $name The name of the prepared statement that has to be executed
511
     *
512
     * @return void
513
     */
514
    abstract protected function deleteIntAttribute(array $row, $name = null);
515
516
    /**
517
     * Delete's the text attribute with the passed value ID.
518
     *
519
     * @param array       $row  The attributes of the entity to delete
520
     * @param string|null $name The name of the prepared statement that has to be executed
521
     *
522
     * @return void
523
     */
524
    abstract protected function deleteTextAttribute(array $row, $name = null);
525
526
    /**
527
     * Delete's the varchar attribute with the passed value ID.
528
     *
529
     * @param array       $row  The attributes of the entity to delete
530
     * @param string|null $name The name of the prepared statement that has to be executed
531
     *
532
     * @return void
533
     */
534
    abstract protected function deleteVarcharAttribute(array $row, $name = null);
535
536
    /**
537
     * Query whether or not the entity has to be processed.
538
     *
539
     * @param array $entity The entity to query for
540
     *
541
     * @return boolean TRUE if the entity has to be processed, else FALSE
542
     */
543
    abstract protected function hasChanges(array $entity);
544
}
545