Completed
Push — 18.x ( 2d8dd4...6471c1 )
by Tim
05:17
created

EeProductObserver::persistProduct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 6
ccs 0
cts 4
cp 0
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 1
crap 2
1
<?php
2
3
/**
4
 * TechDivision\Import\Product\Ee\Observers\EeProductObserver
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-ee
18
 * @link      http://www.techdivision.com
19
 */
20
21
namespace TechDivision\Import\Product\Ee\Observers;
22
23
use TechDivision\Import\Ee\Utils\SqlConstants;
24
use TechDivision\Import\Utils\EntityStatus;
25
use TechDivision\Import\Product\Ee\Utils\MemberNames;
26
use TechDivision\Import\Product\Observers\ProductObserver;
27
28
/**
29
 * Observer that create's the product itself for the Magento 2 EE edition.
30
 *
31
 * @author    Tim Wagner <[email protected]>
32
 * @copyright 2016 TechDivision GmbH <[email protected]>
33
 * @license   http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
34
 * @link      https://github.com/techdivision/import-product-ee
35
 * @link      http://www.techdivision.com
36
 */
37
class EeProductObserver extends ProductObserver
38
{
39
40
    /**
41
     * Merge's and return's the entity with the passed attributes and set's the
42
     * passed status.
43
     *
44
     * @param array       $entity        The entity to merge the attributes into
45
     * @param array       $attr          The attributes to be merged
46
     * @param string|null $changeSetName The change set name to use
47
     *
48
     * @return array The merged entity
49
     */
50
    protected function mergeEntity(array $entity, array $attr, $changeSetName = null)
51
    {
52
53
        // temporary persist the entity and row ID
54
        $this->setLastRowId($entity[MemberNames::ROW_ID]);
55
        $this->setLastEntityId($entity[MemberNames::ENTITY_ID]);
56
57
        // merge and return the entity
58
        return parent::mergeEntity($entity, $attr, $changeSetName);
0 ignored issues
show
Unused Code introduced by
The call to ProductObserver::mergeEntity() has too many arguments starting with $changeSetName.

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...
59
    }
60
61
    /**
62
     * Initialize the product with the passed attributes and returns an instance.
63
     *
64
     * @param array $attr The product attributes
65
     *
66
     * @return array The initialized product
67
     */
68
    protected function initializeProduct(array $attr)
69
    {
70
71
        // initialize the product attributes
72
        $attr = parent::initializeProduct($attr);
73
74
        // query whether or not, we found a new product
75
        if ($attr[EntityStatus::MEMBER_NAME] === EntityStatus::STATUS_CREATE) {
76
            // if yes, initialize the additional Magento 2 EE product values
77
            $additionalAttr = array(
78
                MemberNames::ENTITY_ID  => $this->nextIdentifier(),
79
                MemberNames::CREATED_IN => 1,
80
                MemberNames::UPDATED_IN => SqlConstants::MAX_UNIXTIMESTAMP
81
            );
82
83
            // merge and return the attributes
84
            $attr = array_merge($attr, $additionalAttr);
85
        }
86
87
        // otherwise simply return the attributes
88
        return $attr;
89
    }
90
91
    /**
92
     * Persist's the passed product data.
93
     *
94
     * @param array $product The product data to persist
95
     *
96
     * @return void
97
     */
98
    protected function persistProduct($product)
99
    {
100
        // persist the entity and set the entity ID, SKU and attribute set
101
        $this->setLastRowId($this->getProductBunchProcessor()->persistProduct($product));
102
        $this->setLastEntityId($product[MemberNames::ENTITY_ID]);
103
    }
104
105
    /**
106
     * Set's the row ID of the product that has been created recently.
107
     *
108
     * @param string $rowId The row ID
109
     *
110
     * @return void
111
     */
112
    protected function setLastRowId($rowId)
113
    {
114
        $this->getSubject()->setLastRowId($rowId);
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 setLastRowId() does only exist in the following implementations of said interface: TechDivision\Import\Prod...Subjects\EeBunchSubject.

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...
115
    }
116
117
    /**
118
     * Return's the next available product entity ID.
119
     *
120
     * @return integer The next available product entity ID
121
     */
122
    protected function nextIdentifier()
123
    {
124
        return $this->getProductBunchProcessor()->nextIdentifier();
0 ignored issues
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface TechDivision\Import\Prod...BunchProcessorInterface as the method nextIdentifier() does only exist in the following implementations of said interface: TechDivision\Import\Prod...EeProductBunchProcessor.

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...
125
    }
126
}
127