Completed
Push — 10.x ( 7c9279 )
by Tim
03:22
created

VariantSuperAttributeObserver   A

Complexity

Total Complexity 21

Size/Duplication

Total Lines 305
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 3

Test Coverage

Coverage 0%

Importance

Changes 0
Metric Value
wmc 21
lcom 1
cbo 3
dl 0
loc 305
ccs 0
cts 120
cp 0
rs 10
c 0
b 0
f 0

16 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 4 1
A getProductVariantProcessor() 0 4 1
B process() 0 67 5
A prepareProducSuperAttributeAttributes() 0 18 1
A prepareProductSuperAttributeLabelAttributes() 0 21 2
A initializeProductSuperAttribute() 0 4 1
A initializeProductSuperAttributeLabel() 0 4 1
A mapParentSku() 0 4 1
A mapSkuToEntityId() 0 4 1
A setParentId() 0 4 1
A getParentId() 0 4 1
A getStoreByStoreCode() 0 4 1
A getStores() 0 4 1
A getEavAttributeByAttributeCode() 0 4 1
A persistProductSuperAttribute() 0 4 1
A persistProductSuperAttributeLabel() 0 4 1
1
<?php
2
3
/**
4
 * TechDivision\Import\Product\Variant\Observers\VariantSuperAttributeObserver
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-product-variant
18
 * @link      http://www.techdivision.com
19
 */
20
21
namespace TechDivision\Import\Product\Variant\Observers;
22
23
use TechDivision\Import\Utils\StoreViewCodes;
24
use TechDivision\Import\Product\Utils\RelationTypes;
25
use TechDivision\Import\Product\Variant\Utils\ColumnKeys;
26
use TechDivision\Import\Product\Variant\Utils\MemberNames;
27
use TechDivision\Import\Product\Observers\AbstractProductImportObserver;
28
use TechDivision\Import\Product\Variant\Services\ProductVariantProcessorInterface;
29
30
/**
31
 * Oberserver that provides functionality for the product variant super attributes replace operation.
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-product-variant
37
 * @link      http://www.techdivision.com
38
 */
39
class VariantSuperAttributeObserver extends AbstractProductImportObserver
40
{
41
42
    /**
43
     * The ID of the actual store to use.
44
     *
45
     * @var integer
46
     */
47
    protected $storeId;
48
49
    /**
50
     * The EAV attribute to handle.
51
     *
52
     * @var array
53
     */
54
    protected $eavAttribute;
55
56
    /**
57
     * The tempoarary stored product super attribute ID.
58
     *
59
     * @var integer
60
     */
61
    protected $productSuperAttributeId;
62
63
    /**
64
     * The product variant processor instance.
65
     *
66
     * @var \TechDivision\Import\Product\Variant\Services\ProductVariantProcessorInterface
67
     */
68
    protected $productVariantProcessor;
69
70
    /**
71
     * Initialize the observer with the passed product variant processor instance.
72
     *
73
     * @param \TechDivision\Import\Product\Variant\Services\ProductVariantProcessorInterface $productVariantProcessor The product variant processor instance
74
     */
75
    public function __construct(ProductVariantProcessorInterface $productVariantProcessor)
76
    {
77
        $this->productVariantProcessor = $productVariantProcessor;
78
    }
79
80
    /**
81
     * Return's the product variant processor instance.
82
     *
83
     * @return \TechDivision\Import\Product\Variant\Services\ProductVariantProcessorInterface The product variant processor instance
84
     */
85
    protected function getProductVariantProcessor()
86
    {
87
        return $this->productVariantProcessor;
88
    }
89
90
    /**
91
     * Process the observer's business logic.
92
     *
93
     * @return array The processed row
94
     */
95
    protected function process()
96
    {
97
98
        // extract the child SKU and attribute code from the row
99
        $parentSku = $this->getValue(ColumnKeys::VARIANT_PARENT_SKU);
100
        $attributeCode = $this->getValue(ColumnKeys::VARIANT_ATTRIBUTE_CODE);
101
102
        // query whether or not the super attribute has already been processed
103
        if ($this->hasBeenProcessedRelation($parentSku, $attributeCode, RelationTypes::VARIANT_SUPER_ATTRIBUTE)) {
104
            return;
105
        }
106
107
        // prepare the store view code
108
        $this->prepareStoreViewCode($this->getRow());
0 ignored issues
show
Unused Code introduced by
The call to VariantSuperAttributeObs...:prepareStoreViewCode() has too many arguments starting with $this->getRow().

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
Deprecated Code introduced by
The method TechDivision\Import\Obse...:prepareStoreViewCode() has been deprecated with message: Will be removed with version 1.0.0, use subject method instead

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
109
110
        // preserve the parent ID
111
        $this->setParentId($this->mapParentSku($parentSku));
112
113
        // load the store and set the store ID
114
        $store = $this->getStoreByStoreCode($this->getStoreViewCode(StoreViewCodes::ADMIN));
0 ignored issues
show
Deprecated Code introduced by
The method TechDivision\Import\Obse...ver::getStoreViewCode() has been deprecated with message: Will be removed with version 1.0.0, use subject method instead

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
115
        $this->storeId = $store[MemberNames::STORE_ID];
116
117
        try {
118
            // load the EAV attribute with the found attribute code
119
            $this->eavAttribute = $this->getEavAttributeByAttributeCode($attributeCode);
120
        } catch (\Exception $e) {
121
            throw $this->wrapException(array(ColumnKeys::VARIANT_ATTRIBUTE_CODE), $e);
0 ignored issues
show
Documentation introduced by
array(\TechDivision\Impo...VARIANT_ATTRIBUTE_CODE) is of type array<integer,?>, but the function expects a string.

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

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

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

function acceptsInteger($int) { }

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

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
Deprecated Code introduced by
The method TechDivision\Import\Obse...server::wrapException() has been deprecated with message: Will be removed with version 1.0.0, use subject method instead

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
122
        }
123
124
        try {
125
            // initialize and save the super attribute
126
            $productSuperAttribute = $this->initializeProductSuperAttribute($this->prepareProducSuperAttributeAttributes());
127
            $this->productSuperAttributeId = $this->persistProductSuperAttribute($productSuperAttribute);
0 ignored issues
show
Documentation Bug introduced by
The property $productSuperAttributeId was declared of type integer, but $this->persistProductSup...$productSuperAttribute) is of type string. Maybe add a type cast?

This check looks for assignments to scalar types that may be of the wrong type.

To ensure the code behaves as expected, it may be a good idea to add an explicit type cast.

$answer = 42;

$correct = false;

$correct = (bool) $answer;
Loading history...
128
129
            // initialize and save the super attribute label
130
            $productSuperAttributeLabel = $this->initializeProductSuperAttributeLabel($this->prepareProductSuperAttributeLabelAttributes());
131
            $this->persistProductSuperAttributeLabel($productSuperAttributeLabel);
132
133
            // mark the super attribute as processed
134
            $this->addProcessedRelation($parentSku, $attributeCode, RelationTypes::VARIANT_SUPER_ATTRIBUTE);
135
        } catch (\Exception $e) {
136
            // prepare a more detailed error message
137
            $message = $this->appendExceptionSuffix(
0 ignored issues
show
Deprecated Code introduced by
The method TechDivision\Import\Obse...appendExceptionSuffix() has been deprecated with message: Will be removed with version 1.0.0, use subject method instead

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
138
                sprintf(
139
                    'Super attribute for SKU %s and attribute %s can\'t be created',
140
                    $parentSku,
141
                    $attributeCode
142
                )
143
            );
144
145
            // if we're NOT in debug mode, re-throw a more detailed exception
146
            $wrappedException = $this->wrapException(
0 ignored issues
show
Deprecated Code introduced by
The method TechDivision\Import\Obse...server::wrapException() has been deprecated with message: Will be removed with version 1.0.0, use subject method instead

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
147
                array(ColumnKeys::VARIANT_PARENT_SKU, ColumnKeys::VARIANT_ATTRIBUTE_CODE),
0 ignored issues
show
Documentation introduced by
array(\TechDivision\Impo...VARIANT_ATTRIBUTE_CODE) is of type array<integer,?>, but the function expects a string.

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

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

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

function acceptsInteger($int) { }

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

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
148
                new \Exception($message, null, $e)
149
            );
150
151
            // query whether or not, debug mode is enabled
152
            if ($this->isDebugMode()) {
0 ignored issues
show
Deprecated Code introduced by
The method TechDivision\Import\Obse...Observer::isDebugMode() has been deprecated with message: Will be removed with version 1.0.0, use subject method instead

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
153
                // log a warning and return immediately
154
                $this->getSystemLogger()->warning($wrappedException->getMessage());
155
                return;
156
            }
157
158
            // else, throw the exception
159
            throw $wrappedException;
160
        }
161
    }
162
163
    /**
164
     * Prepare the product super attribute attributes that has to be persisted.
165
     *
166
     * @return array The prepared product attribute attributes
167
     */
168
    protected function prepareProducSuperAttributeAttributes()
169
    {
170
171
        // load the parent ID
172
        $parentId = $this->getParentId();
173
174
        // load the attribute ID
175
        $attributeId = $this->eavAttribute[MemberNames::ATTRIBUTE_ID];
176
177
        // initialize the attributes and return them
178
        return $this->initializeEntity(
179
            array(
180
                MemberNames::PRODUCT_ID   => $parentId,
181
                MemberNames::ATTRIBUTE_ID => $attributeId,
182
                MemberNames::POSITION     => 0
183
            )
184
        );
185
    }
186
187
    /**
188
     * Prepare the product super attribute label attributes that has to be persisted.
189
     *
190
     * @return array The prepared product super attribute label attributes
191
     */
192
    protected function prepareProductSuperAttributeLabelAttributes()
193
    {
194
195
        // extract the parent/child ID as well as option value and variation label from the row
196
        $variationLabel = $this->getValue(ColumnKeys::VARIANT_VARIATION_LABEL);
197
198
        // query whether or not we've to create super attribute labels
199
        if (empty($variationLabel)) {
200
            $variationLabel = $this->eavAttribute[MemberNames::FRONTENT_LABEL];
201
        }
202
203
        // initialize the attributes and return them
204
        return $this->initializeEntity(
205
            array(
206
                MemberNames::PRODUCT_SUPER_ATTRIBUTE_ID => $this->productSuperAttributeId,
207
                MemberNames::STORE_ID                   => $this->storeId,
208
                MemberNames::USE_DEFAULT                => 0,
209
                MemberNames::VALUE                      => $variationLabel
210
            )
211
        );
212
    }
213
214
    /**
215
     * Initialize the product super attribute with the passed attributes and returns an instance.
216
     *
217
     * @param array $attr The product super attribute attributes
218
     *
219
     * @return array The initialized product super attribute
220
     */
221
    protected function initializeProductSuperAttribute(array $attr)
222
    {
223
        return $attr;
224
    }
225
226
    /**
227
     * Initialize the product super attribute label with the passed attributes and returns an instance.
228
     *
229
     * @param array $attr The product super attribute label attributes
230
     *
231
     * @return array The initialized product super attribute label
232
     */
233
    protected function initializeProductSuperAttributeLabel(array $attr)
234
    {
235
        return $attr;
236
    }
237
238
    /**
239
     * Map's the passed SKU of the parent product to it's PK.
240
     *
241
     * @param string $parentSku The SKU of the parent product
242
     *
243
     * @return integer The primary key used to create relations
244
     */
245
    protected function mapParentSku($parentSku)
246
    {
247
        return $this->mapSkuToEntityId($parentSku);
248
    }
249
250
    /**
251
     * Return the entity ID for the passed SKU.
252
     *
253
     * @param string $sku The SKU to return the entity ID for
254
     *
255
     * @return integer The mapped entity ID
256
     * @throws \Exception Is thrown if the SKU is not mapped yet
257
     */
258
    protected function mapSkuToEntityId($sku)
259
    {
260
        return $this->getSubject()->mapSkuToEntityId($sku);
0 ignored issues
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface TechDivision\Import\Subjects\SubjectInterface as the method mapSkuToEntityId() does only exist in the following implementations of said interface: TechDivision\Import\Prod...Subjects\VariantSubject.

Let’s take a look at an example:

interface User
{
    /** @return string */
    public function getPassword();
}

class MyUser implements User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different implementation of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the interface:

    interface User
    {
        /** @return string */
        public function getPassword();
    
        /** @return string */
        public function getDisplayName();
    }
    
Loading history...
261
    }
262
263
    /**
264
     * Set's the ID of the parent product to relate the variant with.
265
     *
266
     * @param integer $parentId The ID of the parent product
267
     *
268
     * @return void
269
     */
270
    protected function setParentId($parentId)
271
    {
272
        $this->getSubject()->setParentId($parentId);
0 ignored issues
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface TechDivision\Import\Subjects\SubjectInterface as the method setParentId() does only exist in the following implementations of said interface: TechDivision\Import\Prod...Subjects\VariantSubject.

Let’s take a look at an example:

interface User
{
    /** @return string */
    public function getPassword();
}

class MyUser implements User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different implementation of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the interface:

    interface User
    {
        /** @return string */
        public function getPassword();
    
        /** @return string */
        public function getDisplayName();
    }
    
Loading history...
273
    }
274
275
    /**
276
     * Return's the ID of the parent product to relate the variant with.
277
     *
278
     * @return integer The ID of the parent product
279
     */
280
    protected function getParentId()
281
    {
282
        return $this->getSubject()->getParentId();
0 ignored issues
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface TechDivision\Import\Subjects\SubjectInterface as the method getParentId() does only exist in the following implementations of said interface: TechDivision\Import\Prod...Subjects\VariantSubject.

Let’s take a look at an example:

interface User
{
    /** @return string */
    public function getPassword();
}

class MyUser implements User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different implementation of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the interface:

    interface User
    {
        /** @return string */
        public function getPassword();
    
        /** @return string */
        public function getDisplayName();
    }
    
Loading history...
283
    }
284
285
    /**
286
     * Return's the store for the passed store code.
287
     *
288
     * @param string $storeCode The store code to return the store for
289
     *
290
     * @return array The requested store
291
     * @throws \Exception Is thrown, if the requested store is not available
292
     */
293
    protected function getStoreByStoreCode($storeCode)
294
    {
295
        return $this->getSubject()->getStoreByStoreCode($storeCode);
0 ignored issues
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface TechDivision\Import\Subjects\SubjectInterface as the method getStoreByStoreCode() does only exist in the following implementations of said interface: TechDivision\Import\Prod...Subjects\VariantSubject.

Let’s take a look at an example:

interface User
{
    /** @return string */
    public function getPassword();
}

class MyUser implements User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different implementation of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the interface:

    interface User
    {
        /** @return string */
        public function getPassword();
    
        /** @return string */
        public function getDisplayName();
    }
    
Loading history...
296
    }
297
298
    /**
299
     * Return's an array with the available stores.
300
     *
301
     * @return array The available stores
302
     */
303
    protected function getStores()
304
    {
305
        return $this->getSubject()->getStores();
0 ignored issues
show
Bug introduced by
The method getStores() does not seem to exist on object<TechDivision\Impo...jects\SubjectInterface>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
306
    }
307
308
    /**
309
     * Return's the first EAV attribute for the passed attribute code.
310
     *
311
     * @param string $attributeCode The attribute code
312
     *
313
     * @return array The array with the EAV attribute
314
     */
315
    protected function getEavAttributeByAttributeCode($attributeCode)
316
    {
317
        return $this->getSubject()->getEavAttributeByAttributeCode($attributeCode);
0 ignored issues
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface TechDivision\Import\Subjects\SubjectInterface as the method getEavAttributeByAttributeCode() does only exist in the following implementations of said interface: TechDivision\Import\Observers\EntitySubjectImpl, TechDivision\Import\Prod...\AbstractProductSubject, TechDivision\Import\Product\Subjects\BunchSubject, TechDivision\Import\Prod...Subjects\VariantSubject, TechDivision\Import\Subjects\AbstractEavSubject.

Let’s take a look at an example:

interface User
{
    /** @return string */
    public function getPassword();
}

class MyUser implements User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different implementation of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the interface:

    interface User
    {
        /** @return string */
        public function getPassword();
    
        /** @return string */
        public function getDisplayName();
    }
    
Loading history...
318
    }
319
320
    /**
321
     * Persist's the passed product super attribute data and return's the ID.
322
     *
323
     * @param array $productSuperAttribute The product super attribute data to persist
324
     *
325
     * @return void
326
     */
327
    protected function persistProductSuperAttribute($productSuperAttribute)
328
    {
329
        return $this->getProductVariantProcessor()->persistProductSuperAttribute($productSuperAttribute);
330
    }
331
332
    /**
333
     * Persist's the passed product super attribute label data and return's the ID.
334
     *
335
     * @param array $productSuperAttributeLabel The product super attribute label data to persist
336
     *
337
     * @return void
338
     */
339
    protected function persistProductSuperAttributeLabel($productSuperAttributeLabel)
340
    {
341
        return $this->getProductVariantProcessor()->persistProductSuperAttributeLabel($productSuperAttributeLabel);
342
    }
343
}
344