Completed
Push — master ( 3762bd...2b4d4e )
by Tim
12s
created

ProductAttributeObserver::deleteIntAttribute()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 4
ccs 0
cts 4
cp 0
rs 10
c 0
b 0
f 0
cc 1
eloc 2
nc 1
nop 2
crap 2
1
<?php
2
3
/**
4
 * TechDivision\Import\Product\Observers\ProductAttributeObserver
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
18
 * @link      http://www.techdivision.com
19
 */
20
21
namespace TechDivision\Import\Product\Observers;
22
23
use TechDivision\Import\Product\Utils\ColumnKeys;
24
use TechDivision\Import\Product\Utils\MemberNames;
25
use TechDivision\Import\Observers\AbstractAttributeObserver;
26
use TechDivision\Import\Product\Services\ProductBunchProcessorInterface;
27
28
/**
29
 * Observer that creates/updates the product's attributes.
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
35
 * @link      http://www.techdivision.com
36
 */
37
class ProductAttributeObserver extends AbstractAttributeObserver
38
{
39
40
    /**
41
     * The product bunch processor instance.
42
     *
43
     * @var \TechDivision\Import\Product\Services\ProductBunchProcessorInterface
44
     */
45
    protected $productBunchProcessor;
46
47
    /**
48
     * Initialize the observer with the passed product bunch processor instance.
49
     *
50
     * @param \TechDivision\Import\Product\Services\ProductBunchProcessorInterface $productBunchProcessor The product bunch processor instance
51
     */
52
    public function __construct(ProductBunchProcessorInterface $productBunchProcessor)
53
    {
54
        $this->productBunchProcessor = $productBunchProcessor;
55
    }
56
57
    /**
58
     * Return's the product bunch processor instance.
59
     *
60
     * @return \TechDivision\Import\Product\Services\ProductBunchProcessorInterface The product bunch processor instance
61
     */
62
    protected function getProductBunchProcessor()
63
    {
64
        return $this->productBunchProcessor;
65
    }
66
67
    /**
68
     * Return's the PK to create the product => attribute relation.
69
     *
70
     * @return integer The PK to create the relation with
71
     */
72
    protected function getPrimaryKey()
73
    {
74
        return $this->getSubject()->getLastEntityId();
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 getLastEntityId() does only exist in the following implementations of said interface: TechDivision\Import\Observers\EntitySubjectImpl, TechDivision\Import\Plugins\ExportableSubjectImpl, TechDivision\Import\Prod...\AbstractProductSubject, TechDivision\Import\Product\Subjects\BunchSubject, TechDivision\Import\Subjects\ExportableTraitImpl.

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...
75
    }
76
77
    /**
78
     * Return's the PK column name to create the product => attribute relation.
79
     *
80
     * @return string The PK column name
81
     */
82
    protected function getPrimaryKeyMemberName()
83
    {
84
        return MemberNames::ENTITY_ID;
85
    }
86
87
    /**
88
     * Return's the column name that contains the primary key.
89
     *
90
     * @return string the column name that contains the primary key
91
     */
92
    protected function getPrimaryKeyColumnName()
93
    {
94
        return ColumnKeys::SKU;
95
    }
96
97
    /**
98
     * Queries whether or not the passed PK and store view code has already been processed.
99
     *
100
     * @param string $pk            The PK to check been processed
101
     * @param string $storeViewCode The store view code to check been processed
102
     *
103
     * @return boolean TRUE if the PK and store view code has been processed, else FALSE
104
     */
105
    protected function storeViewHasBeenProcessed($pk, $storeViewCode)
106
    {
107
        return $this->getSubject()->storeViewHasBeenProcessed($pk, $storeViewCode);
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 storeViewHasBeenProcessed() does only exist in the following implementations of said interface: TechDivision\Import\Prod...\AbstractProductSubject, TechDivision\Import\Product\Subjects\BunchSubject.

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...
108
    }
109
110
    /**
111
     * Persist's the passed varchar attribute.
112
     *
113
     * @param array $attribute The attribute to persist
114
     *
115
     * @return void
116
     */
117
    protected function persistVarcharAttribute($attribute)
118
    {
119
        $this->getProductBunchProcessor()->persistProductVarcharAttribute($attribute);
120
    }
121
122
    /**
123
     * Persist's the passed integer attribute.
124
     *
125
     * @param array $attribute The attribute to persist
126
     *
127
     * @return void
128
     */
129
    protected function persistIntAttribute($attribute)
130
    {
131
        $this->getProductBunchProcessor()->persistProductIntAttribute($attribute);
132
    }
133
134
    /**
135
     * Persist's the passed decimal attribute.
136
     *
137
     * @param array $attribute The attribute to persist
138
     *
139
     * @return void
140
     */
141
    protected function persistDecimalAttribute($attribute)
142
    {
143
        $this->getProductBunchProcessor()->persistProductDecimalAttribute($attribute);
144
    }
145
146
    /**
147
     * Persist's the passed datetime attribute.
148
     *
149
     * @param array $attribute The attribute to persist
150
     *
151
     * @return void
152
     */
153
    protected function persistDatetimeAttribute($attribute)
154
    {
155
        $this->getProductBunchProcessor()->persistProductDatetimeAttribute($attribute);
156
    }
157
158
    /**
159
     * Persist's the passed text attribute.
160
     *
161
     * @param array $attribute The attribute to persist
162
     *
163
     * @return void
164
     */
165
    protected function persistTextAttribute($attribute)
166
    {
167
        $this->getProductBunchProcessor()->persistProductTextAttribute($attribute);
168
    }
169
170
    /**
171
     * Delete's the datetime attribute with the passed value ID.
172
     *
173
     * @param array       $row  The attributes of the entity to delete
174
     * @param string|null $name The name of the prepared statement that has to be executed
175
     *
176
     * @return void
177
     */
178
    protected function deleteDatetimeAttribute(array $row, $name = null)
179
    {
180
        $this->getProductBunchProcessor()->deleteProductDatetimeAttribute($row, $name);
181
    }
182
183
    /**
184
     * Delete's the decimal attribute with the passed value ID.
185
     *
186
     * @param array       $row  The attributes of the entity to delete
187
     * @param string|null $name The name of the prepared statement that has to be executed
188
     *
189
     * @return void
190
     */
191
    protected function deleteDecimalAttribute(array $row, $name = null)
192
    {
193
        $this->getProductBunchProcessor()->deleteProductDecimalAttribute($row, $name);
194
    }
195
196
    /**
197
     * Delete's the integer attribute with the passed value ID.
198
     *
199
     * @param array       $row  The attributes of the entity to delete
200
     * @param string|null $name The name of the prepared statement that has to be executed
201
     *
202
     * @return void
203
     */
204
    protected function deleteIntAttribute(array $row, $name = null)
205
    {
206
        $this->getProductBunchProcessor()->deleteProductIntAttribute($row, $name);
207
    }
208
209
    /**
210
     * Delete's the text attribute with the passed value ID.
211
     *
212
     * @param array       $row  The attributes of the entity to delete
213
     * @param string|null $name The name of the prepared statement that has to be executed
214
     *
215
     * @return void
216
     */
217
    protected function deleteTextAttribute(array $row, $name = null)
218
    {
219
        $this->getProductBunchProcessor()->deleteProductTextAttribute($row, $name);
220
    }
221
222
    /**
223
     * Delete's the varchar attribute with the passed value ID.
224
     *
225
     * @param array       $row  The attributes of the entity to delete
226
     * @param string|null $name The name of the prepared statement that has to be executed
227
     *
228
     * @return void
229
     */
230
    protected function deleteVarcharAttribute(array $row, $name = null)
231
    {
232
        return $this->getProductBunchProcessor()->deleteProductVarcharAttribute($row, $name);
233
    }
234
}
235