Completed
Push — master ( a3830f...527f9f )
by Tim
9s
created

BundleSubject   B

Complexity

Total Complexity 20

Size/Duplication

Total Lines 285
Duplicated Lines 0 %

Coupling/Cohesion

Components 7
Dependencies 2

Test Coverage

Coverage 0%

Importance

Changes 2
Bugs 0 Features 1
Metric Value
wmc 20
lcom 7
cbo 2
dl 0
loc 285
rs 8.3333
c 2
b 0
f 1
ccs 0
cts 79
cp 0

16 Methods

Rating   Name   Duplication   Size   Complexity  
A setUp() 0 15 1
A resetPositionCounter() 0 4 1
A raisePositionCounter() 0 4 1
A addChildSkuSelectionIdMapping() 0 4 1
A getChildSkuSelectionMapping() 0 4 1
A mapSkuToEntityId() 0 11 2
A mapPriceType() 0 11 2
A getStoreByStoreCode() 0 11 2
A addNameOptionIdMapping() 0 4 1
A exists() 0 4 1
A getLastOptionId() 0 4 1
A getOptionIdForName() 0 11 2
A persistProductBundleOption() 0 4 1
A persistProductBundleOptionValue() 0 4 1
A persistProductBundleSelection() 0 4 1
A persistProductBundleSelectionPrice() 0 4 1
1
<?php
2
3
/**
4
 * TechDivision\Import\Product\Bundle\Subjects\BundleSubject
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-bundle
18
 * @link      http://www.techdivision.com
19
 */
20
21
namespace TechDivision\Import\Product\Bundle\Subjects;
22
23
use TechDivision\Import\Utils\RegistryKeys;
24
use TechDivision\Import\Product\Subjects\AbstractProductSubject;
25
use TechDivision\Import\Product\Bundle\Services\ProductBundleProcessorInterface;
26
27
/**
28
 * A SLSB that handles the process to import product variants.
29
 *
30
 * @author    Tim Wagner <[email protected]>
31
 * @copyright 2016 TechDivision GmbH <[email protected]>
32
 * @license   http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
33
 * @link      https://github.com/techdivision/import-product-bundle
34
 * @link      http://www.techdivision.com
35
 */
36
class BundleSubject extends AbstractProductSubject
37
{
38
39
    /**
40
     * The value for the price type 'fixed'.
41
     *
42
     * @var integer
43
     */
44
    const PRICE_TYPE_FIXED = 0;
45
46
    /**
47
     * The value for the price type 'percent'.
48
     *
49
     * @var integer
50
     */
51
    const PRICE_TYPE_PERCENT = 1;
52
53
    /**
54
     * The mapping for the SKUs to the created entity IDs.
55
     *
56
     * @var array
57
     */
58
    protected $skuEntityIdMapping = array();
59
60
    /**
61
     * The option name => option ID mapping.
62
     *
63
     * @var array
64
     */
65
    protected $nameOptionIdMapping = array();
66
67
    /**
68
     * The ID of the last created selection.
69
     *
70
     * @var integer
71
     */
72
    protected $childSkuSelectionIdMapping = array();
73
74
    /**
75
     * The position counter, if no position for the bundle selection has been specified.
76
     *
77
     * @var integer
78
     */
79
    protected $positionCounter = 1;
80
81
    /**
82
     * The mapping for the price type.
83
     *
84
     * @var array
85
     */
86
    protected $priceTypeMapping = array(
87
        'fixed'   => BundleSubject::PRICE_TYPE_FIXED,
88
        'percent' => BundleSubject::PRICE_TYPE_PERCENT
89
    );
90
91
    /**
92
     * Intializes the previously loaded global data for exactly one variants.
93
     *
94
     * @return void
95
     * @see \Importer\Csv\Actions\ProductImportAction::prepare()
96
     */
97
    public function setUp()
98
    {
99
100
        // invoke the parent method
101
        parent::setUp();
102
103
        // load the entity manager and the registry processor
104
        $registryProcessor = $this->getRegistryProcessor();
105
106
        // load the status of the actual import process
107
        $status = $registryProcessor->getAttribute($this->serial);
108
109
        // load the attribute set we've prepared intially
110
        $this->skuEntityIdMapping = $status[RegistryKeys::SKU_ENTITY_ID_MAPPING];
111
    }
112
113
    /**
114
     * Reset the position counter to 1.
115
     *
116
     * @return void
117
     */
118
    public function resetPositionCounter()
119
    {
120
        $this->positionCounter = 1;
121
    }
122
123
    /**
124
     * Returns the acutal value of the position counter and raise's it by one.
125
     *
126
     * @return integer The actual value of the position counter
127
     */
128
    public function raisePositionCounter()
129
    {
130
        return $this->positionCounter++;
131
    }
132
133
    /**
134
     * Save's the mapping of the child SKU and the selection ID.
135
     *
136
     * @param string  $childSku    The child SKU of the selection
137
     * @param integer $selectionId The selection ID to save
138
     *
139
     * @return void
140
     */
141
    public function addChildSkuSelectionIdMapping($childSku, $selectionId)
142
    {
143
        $this->childSkuSelectionIdMapping[$childSku] = $selectionId;
144
    }
145
146
    /**
147
     * Return's the selection ID for the passed child SKU.
148
     *
149
     * @param string $childSku The child SKU to return the selection ID for
150
     *
151
     * @return integer The last created selection ID
152
     */
153
    public function getChildSkuSelectionMapping($childSku)
154
    {
155
        return $this->childSkuSelectionIdMapping[$childSku];
156
    }
157
158
    /**
159
     * Return the entity ID for the passed SKU.
160
     *
161
     * @param string $sku The SKU to return the entity ID for
162
     *
163
     * @return integer The mapped entity ID
164
     * @throws \Exception Is thrown if the SKU is not mapped yet
165
     */
166
    public function mapSkuToEntityId($sku)
167
    {
168
169
        // query weather or not the SKU has been mapped
170
        if (isset($this->skuEntityIdMapping[$sku])) {
171
            return $this->skuEntityIdMapping[$sku];
172
        }
173
174
        // throw an exception if the SKU has not been mapped yet
175
        throw new \Exception(sprintf('Found not mapped SKU %s', $sku));
176
    }
177
178
    /**
179
     * Return's the mapping for the passed price type.
180
     *
181
     * @param string $priceType The price type to map
182
     *
183
     * @return integer The mapped price type
184
     * @throws \Exception Is thrown, if the passed price type can't be mapped
185
     */
186
    public function mapPriceType($priceType)
187
    {
188
189
        // query whether or not the passed price type is available
190
        if (isset($this->priceTypeMapping[$priceType])) {
191
            return $this->priceTypeMapping[$priceType];
192
        }
193
194
        // throw an exception, if not
195
        throw new \Exception(sprintf('Can\'t find price type %s', $priceType));
196
    }
197
198
    /**
199
     * Return's the store for the passed store code.
200
     *
201
     * @param string $storeCode The store code to return the store for
202
     *
203
     * @return array The requested store
204
     * @throws \Exception Is thrown, if the requested store is not available
205
     */
206
    public function getStoreByStoreCode($storeCode)
207
    {
208
209
        // query whether or not the store with the passed store code exists
210
        if (isset($this->stores[$storeCode])) {
211
            return $this->stores[$storeCode];
212
        }
213
214
        // throw an exception, if not
215
        throw new \Exception(sprintf('Found invalid store code %s', $storeCode));
216
    }
217
218
    /**
219
     * Add's the mapping for the passed name => option ID.
220
     *
221
     * @param string  $name     The name of the option
222
     * @param integer $optionId The created option ID
223
     *
224
     * @return void
225
     */
226
    public function addNameOptionIdMapping($name, $optionId)
227
    {
228
        $this->nameOptionIdMapping[$name] = $optionId;
229
    }
230
231
    /**
232
     * Query whether or not the option with the passed name has already been created.
233
     *
234
     * @param string $name The option name to query for
235
     *
236
     * @return boolean TRUE if the option already exists, else FALSE
237
     */
238
    public function exists($name)
239
    {
240
        return isset($this->nameOptionIdMapping[$name]);
241
    }
242
243
    /**
244
     * Return's the last created option ID.
245
     *
246
     * @return integer $optionId The last created option ID
247
     */
248
    public function getLastOptionId()
249
    {
250
        return end($this->nameOptionIdMapping);
251
    }
252
253
    /**
254
     * Return's the option ID for the passed name.
255
     *
256
     * @param string $name The name to return the option ID for
257
     *
258
     * @return integer The option ID for the passed name
259
     * @throws \Exception Is thrown, if no option ID for the passed name is available
260
     */
261
    public function getOptionIdForName($name)
262
    {
263
264
        // query whether or not an option ID for the passed name is available
265
        if (isset($this->nameOptionIdMapping[$name])) {
266
            return $this->nameOptionIdMapping[$name];
267
        }
268
269
        // throw an exception, if not
270
        throw new \Exception(sprintf('Can\'t find option ID for name %s', $name));
271
    }
272
273
    /**
274
     * Persist's the passed product bundle option data and return's the ID.
275
     *
276
     * @param array $productBundleOption The product bundle option data to persist
277
     *
278
     * @return string The ID of the persisted entity
279
     */
280
    public function persistProductBundleOption($productBundleOption)
281
    {
282
        return $this->getProductProcessor()->persistProductBundleOption($productBundleOption);
0 ignored issues
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface TechDivision\Import\Prod...oductProcessorInterface as the method persistProductBundleOption() does only exist in the following implementations of said interface: TechDivision\Import\Prod...\ProductBundleProcessor.

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
     * Persist's the passed product bundle option value data.
287
     *
288
     * @param array $productBundleOptionValue The product bundle option value data to persist
289
     *
290
     * @return void
291
     */
292
    public function persistProductBundleOptionValue($productBundleOptionValue)
293
    {
294
        return $this->getProductProcessor()->persistProductBundleOptionValue($productBundleOptionValue);
0 ignored issues
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface TechDivision\Import\Prod...oductProcessorInterface as the method persistProductBundleOptionValue() does only exist in the following implementations of said interface: TechDivision\Import\Prod...\ProductBundleProcessor.

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...
295
    }
296
297
    /**
298
     * Persist's the passed product bundle selection data and return's the ID.
299
     *
300
     * @param array $productBundleSelection The product bundle selection data to persist
301
     *
302
     * @return string The ID of the persisted entity
303
     */
304
    public function persistProductBundleSelection($productBundleSelection)
305
    {
306
        return $this->getProductProcessor()->persistProductBundleSelection($productBundleSelection);
0 ignored issues
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface TechDivision\Import\Prod...oductProcessorInterface as the method persistProductBundleSelection() does only exist in the following implementations of said interface: TechDivision\Import\Prod...\ProductBundleProcessor.

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...
307
    }
308
309
    /**
310
     * Persist's the passed product bundle selection price data and return's the ID.
311
     *
312
     * @param array $productBundleSelectionPrice The product bundle selection price data to persist
313
     *
314
     * @return void
315
     */
316
    public function persistProductBundleSelectionPrice($productBundleSelectionPrice)
317
    {
318
        $this->getProductProcessor()->persistProductBundleSelectionPrice($productBundleSelectionPrice);
0 ignored issues
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface TechDivision\Import\Prod...oductProcessorInterface as the method persistProductBundleSelectionPrice() does only exist in the following implementations of said interface: TechDivision\Import\Prod...\ProductBundleProcessor.

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...
319
    }
320
}
321