TierPriceProcessor::setPrimaryKeyUtil()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
eloc 1
c 0
b 0
f 0
dl 0
loc 3
ccs 0
cts 2
cp 0
rs 10
cc 1
nc 1
nop 1
crap 2
1
<?php
2
3
/**
4
 * TechDivision\Import\Product\TierPrice\Services\TierPriceProcessor
5
 *
6
 * PHP version 7
7
 *
8
 * @author    Klaas-Tido Rühl <[email protected]>
9
 * @author    Tim Wagner <[email protected]>
10
 * @copyright 2019 REFUSiON GmbH <[email protected]>
11
 * @license   https://opensource.org/licenses/MIT
12
 * @link      https://github.com/techdivision/import-product-tier-price
13
 * @link      https://www.techdivision.com
14
 * @link      https://www.refusion.com
15
 */
16
17
namespace TechDivision\Import\Product\TierPrice\Services;
18
19
use TechDivision\Import\Dbal\Actions\ActionInterface;
20
use TechDivision\Import\Dbal\Utils\PrimaryKeyUtilInterface;
21
use TechDivision\Import\Dbal\Connection\ConnectionInterface;
22
use TechDivision\Import\Product\TierPrice\Utils\MemberNames;
23
use TechDivision\Import\Product\Repositories\ProductRepositoryInterface;
24
use TechDivision\Import\Product\TierPrice\Repositories\TierPriceRepositoryInterface;
25
26
/**
27
 * Default implementation of tier price processor objects, giving access to CRUD methods.
28
 *
29
 * @author    Klaas-Tido Rühl <[email protected]>
30
 * @author    Tim Wagner <[email protected]>
31
 * @copyright 2019 REFUSiON GmbH <[email protected]>
32
 * @license   https://opensource.org/licenses/MIT
33
 * @link      https://github.com/techdivision/import-product-tier-price
34
 * @link      https://www.techdivision.com
35
 * @link      https://www.refusion.com
36
 */
37
class TierPriceProcessor implements TierPriceProcessorInterface
38
{
39
40
    /**
41
     * A \PDO connection used to load data and handle CRUD functionality.
42
     *
43
     * @var \TechDivision\Import\Dbal\Connection\ConnectionInterface
44
     */
45
    protected $connection;
46
47
    /**
48
     * The primary key util instance.
49
     *
50
     * @var \TechDivision\Import\Dbal\Utils\PrimaryKeyUtilInterface
51
     */
52
    protected $primaryKeyUtil;
53
54
    /**
55
     * The action for tier price  CRUD methods.
56
     *
57
     * @var \TechDivision\Import\Dbal\Actions\ActionInterface
58
     */
59
    protected $tierPriceAction;
60
61
    /**
62
     * The repository to load the tier prices with.
63
     *
64
     * @var \TechDivision\Import\Product\TierPrice\Repositories\TierPriceRepositoryInterface
65
     */
66
    protected $tierPriceRepository;
67
68
    /**
69
     * Caches the existing tier price records referenced by their unique hash.
70
     *
71
     * @var array
72
     */
73
    protected $tierPricesByHash = null;
74
75
    /**
76
     * The repository to load the products with.
77
     *
78
     * @var \TechDivision\Import\Product\Repositories\ProductRepositoryInterface
79
     */
80
    protected $productRepository;
81
82
    /**
83
     * Initialize the processor with the necessary assembler and repository instances.
84
     *
85
     * @param \TechDivision\Import\Dbal\Connection\ConnectionInterface                         $connection          The \PDO connnection instance
86
     * @param \TechDivision\Import\Dbal\Utils\PrimaryKeyUtilInterface                          $primaryKeyUtil      The primary key util
87
     * @param \TechDivision\Import\Product\TierPrice\Repositories\TierPriceRepositoryInterface $tierPriceRepository The repository to load the tier prices with
88
     * @param \TechDivision\Import\Product\Repositories\ProductRepositoryInterface             $productRepository   The repository to load the products with
89
     * @param \TechDivision\Import\Dbal\Actions\ActionInterface                                $tierPriceAction     The action for tier price  CRUD methods
90
     */
91
    public function __construct(
92
        ConnectionInterface $connection,
93
        PrimaryKeyUtilInterface $primaryKeyUtil,
94
        TierPriceRepositoryInterface $tierPriceRepository,
95
        ProductRepositoryInterface $productRepository,
96
        ActionInterface $tierPriceAction
97
    ) {
98
        $this->setConnection($connection);
99
        $this->setPrimaryKeyUtil($primaryKeyUtil);
100
        $this->setTierPriceRepository($tierPriceRepository);
101
        $this->setProductRepository($productRepository);
102
        $this->setTierPriceAction($tierPriceAction);
103
    }
104
105
    /**
106
     * Set's the passed connection.
107
     *
108
     * @param \TechDivision\Import\Dbal\Connection\ConnectionInterface $connection The connection to set
109
     *
110
     * @return void
111
     */
112
    public function setConnection(ConnectionInterface $connection)
113
    {
114
        $this->connection = $connection;
115
    }
116
117
    /**
118
     * Return's the connection.
119
     *
120
     * @return \TechDivision\Import\Dbal\Connection\ConnectionInterface The connection instance
121
     */
122
    public function getConnection()
123
    {
124
        return $this->connection;
125
    }
126
127
    /**
128
     * Sets the passed primary key util instance.
129
     *
130
     * @param \TechDivision\Import\Dbal\Utils\PrimaryKeyUtilInterface $primaryKeyUtil The primary key util instance
131
     *
132
     * @return void
133
     */
134
    public function setPrimaryKeyUtil(PrimaryKeyUtilInterface $primaryKeyUtil)
135
    {
136
        $this->primaryKeyUtil = $primaryKeyUtil;
137
    }
138
139
    /**
140
     * Returns the primary key util instance.
141
     *
142
     * @return \TechDivision\Import\Dbal\Utils\PrimaryKeyUtilInterface The primary key util instance
143
     */
144
    public function getPrimaryKeyUtil()
145
    {
146
        return $this->primaryKeyUtil;
147
    }
148
149
    /**
150
     * Returns the primary key member name for the actual Magento edition.
151
     *
152
     * @return string The primary key member name
153
     * @see \TechDivision\Import\Dbal\Utils\PrimaryKeyUtilInterface::getPrimaryKeyMemberName()
154
     */
155
    public function getPrimaryKeyMemberName()
156
    {
157
        return $this->getPrimaryKeyUtil()->getPrimaryKeyMemberName();
158
    }
159
160
    /**
161
     * Turns off autocommit mode. While autocommit mode is turned off, changes made to the database via the PDO
162
     * object instance are not committed until you end the transaction by calling ProductProcessor::commit().
163
     * Calling ProductProcessor::rollBack() will roll back all changes to the database and return the connection
164
     * to autocommit mode.
165
     *
166
     * @return boolean Returns TRUE on success or FALSE on failure
167
     * @link http://php.net/manual/en/pdo.begintransaction.php
168
     */
169
    public function beginTransaction()
170
    {
171
        return $this->connection->beginTransaction();
172
    }
173
174
    /**
175
     * Commits a transaction, returning the database connection to autocommit mode until the next call to
176
     * ProductProcessor::beginTransaction() starts a new transaction.
177
     *
178
     * @return boolean Returns TRUE on success or FALSE on failure
179
     * @link http://php.net/manual/en/pdo.commit.php
180
     */
181
    public function commit()
182
    {
183
        return $this->connection->commit();
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->connection->commit() returns the type void which is incompatible with the documented return type boolean.
Loading history...
Bug introduced by
Are you sure the usage of $this->connection->commit() targeting TechDivision\Import\Dbal...tionInterface::commit() seems to always return null.

This check looks for function or method calls that always return null and whose return value is used.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
if ($a->getObject()) {

The method getObject() can return nothing but null, so it makes no sense to use the return value.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
184
    }
185
186
    /**
187
     * Rolls back the current transaction, as initiated by ProductProcessor::beginTransaction().
188
     *
189
     * If the database was set to autocommit mode, this function will restore autocommit mode after it has
190
     * rolled back the transaction.
191
     *
192
     * Some databases, including MySQL, automatically issue an implicit COMMIT when a database definition
193
     * language (DDL) statement such as DROP TABLE or CREATE TABLE is issued within a transaction. The implicit
194
     * COMMIT will prevent you from rolling back any other changes within the transaction boundary.
195
     *
196
     * @return boolean Returns TRUE on success or FALSE on failure
197
     * @link http://php.net/manual/en/pdo.rollback.php
198
     */
199
    public function rollBack()
200
    {
201
        return $this->connection->rollBack();
202
    }
203
204
    /**
205
     * Sets the action with the tier price CRUD methods.
206
     *
207
     * @param \TechDivision\Import\Dbal\Actions\ActionInterface $tierPriceAction The action with the tier price CRUD methods
208
     *
209
     * @return void
210
     */
211
    public function setTierPriceAction(ActionInterface $tierPriceAction)
212
    {
213
        $this->tierPriceAction = $tierPriceAction;
214
    }
215
216
    /**
217
     * Returns the action with the tier price CRUD methods.
218
     *
219
     * @return \TechDivision\Import\Dbal\Actions\ActionInterface The action instance
220
     */
221
    public function getTierPriceAction()
222
    {
223
        return $this->tierPriceAction;
224
    }
225
226
    /**
227
     * Sets the repository to load the tier prices with.
228
     *
229
     * @param \TechDivision\Import\Product\TierPrice\Repositories\TierPriceRepositoryInterface $tierPriceRepository The repository instance
230
     *
231
     * @return void
232
     */
233
    public function setTierPriceRepository(TierPriceRepositoryInterface $tierPriceRepository)
234
    {
235
        $this->tierPriceRepository = $tierPriceRepository;
236
    }
237
238
    /**
239
     * Returns the repository to load the tier prices with.
240
     *
241
     * @return \TechDivision\Import\Product\TierPrice\Repositories\TierPriceRepositoryInterface The repository instance
242
     */
243
    public function getTierPriceRepository()
244
    {
245
        return $this->tierPriceRepository;
246
    }
247
248
    /**
249
     * Sets the repository to load the products with.
250
     *
251
     * @param \TechDivision\Import\Product\Repositories\ProductRepositoryInterface $productRepository The repository instance
252
     *
253
     * @return void
254
     */
255
    public function setProductRepository(ProductRepositoryInterface $productRepository)
256
    {
257
        $this->productRepository = $productRepository;
258
    }
259
260
    /**
261
     * Returns the repository to load the products with.
262
     *
263
     * @return \TechDivision\Import\Product\Repositories\ProductRepositoryInterface The repository instance
264
     */
265
    public function getProductRepository()
266
    {
267
        return $this->productRepository;
268
    }
269
270
    /**
271
     * Load's and return's the product with the passed SKU.
272
     *
273
     * @param string $sku The SKU of the product to load
274
     *
275
     * @return array The product
276
     */
277
    public function loadProduct($sku)
278
    {
279
        return $this->getProductRepository()->findOneBySku($sku);
280
    }
281
282
    /**
283
     * Returns all tier prices.
284
     *
285
     * @return array The array with the tier prices
286
     */
287
    public function loadTierPrices()
288
    {
289
        return $this->getTierPriceRepository()->findAll();
290
    }
291
292
    /**
293
     * Returns the tier price with the given parameters.
294
     *
295
     * @param string  $pk              The PK of the product relation
296
     * @param integer $allGroups       The flag if all groups are affected or not
297
     * @param integer $customerGroupId The customer group ID
298
     * @param integer $qty             The tier price quantity
299
     * @param integer $websiteId       The website ID the tier price is related to
300
     *
301
     * @return array The tier price
302
     */
303
    public function loadTierPriceByPkAndAllGroupsAndCustomerGroupIdAndQtyAndWebsiteId($pk, $allGroups, $customerGroupId, $qty, $websiteId)
304
    {
305
        return $this->getTierPriceRepository()->findOneByPkAndAllGroupsAndCustomerGroupIdAndQtyAndWebsiteId($pk, $allGroups, $customerGroupId, $qty, $websiteId);
306
    }
307
308
    /**
309
     * Persists the tier price with the passed data.
310
     *
311
     * @param array       $row  The tier price to persist
312
     * @param string|null $name The name of the prepared statement that has to be executed
313
     *
314
     * @return string The ID of the persisted entity
315
     */
316
    public function persistTierPrice($row, $name = null)
317
    {
318
        return $this->getTierPriceAction()->persist($row, $name);
0 ignored issues
show
Unused Code introduced by
The call to TechDivision\Import\Dbal...ionInterface::persist() has too many arguments starting with $name. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

318
        return $this->getTierPriceAction()->/** @scrutinizer ignore-call */ persist($row, $name);

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. Please note the @ignore annotation hint above.

Loading history...
Bug introduced by
Are you sure the usage of $this->getTierPriceAction()->persist($row, $name) targeting TechDivision\Import\Dbal...ionInterface::persist() seems to always return null.

This check looks for function or method calls that always return null and whose return value is used.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
if ($a->getObject()) {

The method getObject() can return nothing but null, so it makes no sense to use the return value.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
Bug Best Practice introduced by
The expression return $this->getTierPri...)->persist($row, $name) returns the type void which is incompatible with the documented return type string.
Loading history...
319
    }
320
321
    /**
322
     * Deletes the tierprice with the passed attributes.
323
     *
324
     * @param array       $row  The attributes of the entity to delete
325
     * @param string|null $name The name of the prepared statement that has to be executed
326
     *
327
     * @return void
328
     */
329
    public function deleteTierPrice($row, $name = null)
330
    {
331
        $this->getTierPriceAction()->delete($row, $name);
0 ignored issues
show
Unused Code introduced by
The call to TechDivision\Import\Dbal...tionInterface::delete() has too many arguments starting with $name. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

331
        $this->getTierPriceAction()->/** @scrutinizer ignore-call */ delete($row, $name);

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. Please note the @ignore annotation hint above.

Loading history...
332
    }
333
334
    /**
335
     * Clean-Up the tier prices after an add-update operation.
336
     *
337
     * @param array $processedTierPrices The array with tier prices processed in the actual import
338
     * @param array $pkToSkuMapping      The array with PK => SKU mapping of products processed in the actual import
339
     *
340
     * @return void
341
     */
342
    public function cleanUpTierPrices(array $processedTierPrices, array $pkToSkuMapping)
343
    {
344
345
        // load ALL available tier prices
346
        $availableTierPrices = $this->loadTierPrices();
347
348
        // iterate over the tier prices and delete the obsolete ones
349
        foreach ($availableTierPrices as $tierPrice) {
350
            // if the tier price has been processed, continue
351
            if (isset($processedTierPrices[$tierPrice[MemberNames::VALUE_ID]])) {
352
                continue;
353
            }
354
355
            // if the product has been processed, delete the tier price
356
            if (isset($pkToSkuMapping[$tierPrice[$this->getPrimaryKeyMemberName()]])) {
357
                // delete the tier price, because the entity is part of the import but the tier price is NOT available any more
358
                $this->deleteTierPrice([MemberNames::VALUE_ID => $tierPrice[MemberNames::VALUE_ID]]);
359
            }
360
        }
361
    }
362
}
363