Completed
Push — master ( 7eddf3...c0b944 )
by Tim
13s
created

AttributeObserverTrait::deleteDatetimeAttribute()

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