Completed
Pull Request — master (#5)
by Tim
04:05
created

LinkSubject::getProductLinkAttribute()   A

Complexity

Conditions 4
Paths 3

Size

Total Lines 13
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 20

Importance

Changes 0
Metric Value
dl 0
loc 13
ccs 0
cts 10
cp 0
rs 9.2
c 0
b 0
f 0
cc 4
eloc 5
nc 3
nop 2
crap 20
1
<?php
2
3
/**
4
 * TechDivision\Import\Product\Link\Subjects\LinkSubject
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-link
18
 * @link      http://www.techdivision.com
19
 */
20
21
namespace TechDivision\Import\Product\Link\Subjects;
22
23
use TechDivision\Import\Utils\RegistryKeys;
24
use TechDivision\Import\Product\Link\Utils\MemberNames;
25
use TechDivision\Import\Product\Subjects\AbstractProductSubject;
26
27
/**
28
 * A subject implementation the process to import product links.
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-link
34
 * @link      http://www.techdivision.com
35
 */
36
class LinkSubject extends AbstractProductSubject
37
{
38
39
    /**
40
     * The temporary persisted last link ID.
41
     *
42
     * @var integer
43
     */
44
    protected $lastLinkId;
45
46
    /**
47
     * The available link types.
48
     *
49
     * @var array
50
     */
51
    protected $linkTypes = array();
52
53
    /**
54
     * The available link attributes.
55
     *
56
     * @var array
57
     */
58
    protected $linkAttributes = array();
59
60
    /**
61
     * The mapping for the SKUs to the created entity IDs.
62
     *
63
     * @var array
64
     */
65
    protected $skuEntityIdMapping = array();
66
67
    /**
68
     * Intializes the previously loaded global data for exactly one variants.
69
     *
70
     * @return void
71
     * @see \Importer\Csv\Actions\ProductImportAction::prepare()
72
     */
73
    public function setUp()
74
    {
75
76
        // invoke the parent method
77
        parent::setUp();
78
79
        // load the entity manager and the registry processor
80
        $registryProcessor = $this->getRegistryProcessor();
81
82
        // load the status of the actual import process
83
        $status = $registryProcessor->getAttribute($this->getSerial());
84
85
        // load the attribute set we've prepared intially
86
        $this->skuEntityIdMapping = $status[RegistryKeys::SKU_ENTITY_ID_MAPPING];
87
88
        // load the link types/attributes we've initialized before
89
        $this->linkTypes = $status[RegistryKeys::GLOBAL_DATA][RegistryKeys::LINK_TYPES];
90
        $this->linkAttributes = $status[RegistryKeys::GLOBAL_DATA][RegistryKeys::LINK_ATTRIBUTES];
91
    }
92
93
    /**
94
     * Temporary persist the last link ID.
95
     *
96
     * @param integer $lastLinkId The last link ID
97
     *
98
     * @return void
99
     */
100
    public function setLastLinkId($lastLinkId)
101
    {
102
        $this->lastLinkId = $lastLinkId;
103
    }
104
105
    /**
106
     * Load the temporary persisted the last link ID.
107
     *
108
     * @return integer The last link ID
109
     */
110
    public function getLastLinkId()
111
    {
112
        return $this->lastLinkId;
113
    }
114
115
    /**
116
     * Return the entity ID for the passed SKU.
117
     *
118
     * @param string $sku The SKU to return the entity ID for
119
     *
120
     * @return integer The mapped entity ID
121
     * @throws \Exception Is thrown if the SKU is not mapped yet
122
     */
123
    public function mapSkuToEntityId($sku)
124
    {
125
126
        // query weather or not the SKU has been mapped
127
        if (isset($this->skuEntityIdMapping[$sku])) {
128
            return $this->skuEntityIdMapping[$sku];
129
        }
130
131
        // throw an exception if the SKU has not been mapped yet
132
        throw new \Exception(sprintf('Found not mapped SKU %s', $sku));
133
    }
134
135
    /**
136
     * Return's the link type ID for the passed link type code.
137
     *
138
     * @param string $linkTypeCode The link type code to return the link type ID for
139
     *
140
     * @return integer The mapped link type ID
141
     * @throws \Exception Is thrown if the link type code is not mapped yet
142
     */
143
    public function mapLinkTypeCodeToLinkTypeId($linkTypeCode)
144
    {
145
146
        // query weather or not the link type code has been mapped
147
        if (isset($this->linkTypes[$linkTypeCode])) {
148
            return $this->linkTypes[$linkTypeCode][MemberNames::LINK_TYPE_ID];
149
        }
150
151
        // throw an exception if the link type code has not been mapped yet
152
        throw new \Exception(sprintf('Found not mapped link type code %s', $linkTypeCode));
153
    }
154
155
    /**
156
     * Return's the link attribute for the passed link type ID and attribute code.
157
     *
158
     * @param integer $linkTypeId    The link type
159
     * @param string  $attributeCode The attribute code
160
     *
161
     * @return array The link attribute
162
     */
163
    public function getProductLinkAttribute($linkTypeId, $attributeCode)
164
    {
165
166
        // try to load the link attribute with the passed link type ID and attribute code
167
        foreach ($this->linkAttributes as $linkAttribute) {
168
            if ($linkAttribute[MemberNames::LINK_TYPE_ID] === $linkTypeId &&
169
                $linkAttribute[MemberNames::PRODUCT_LINK_ATTRIBUTE_CODE] === $attributeCode
170
            ) {
171
                // return the matching link attribute
172
                return $linkAttribute;
173
            }
174
        }
175
    }
176
177
    /**
178
     * Load's the link with the passed product/linked product/link type ID.
179
     *
180
     * @param integer $productId       The product ID of the link to load
181
     * @param integer $linkedProductId The linked product ID of the link to load
182
     * @param integer $linkTypeId      The link type ID of the product to load
183
     *
184
     * @return array The link
185
     */
186
    public function loadProductLink($productId, $linkedProductId, $linkTypeId)
187
    {
188
        return $this->getProductProcessor()->loadProductLink($productId, $linkedProductId, $linkTypeId);
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 loadProductLink() does only exist in the following implementations of said interface: TechDivision\Import\Prod...es\ProductLinkProcessor.

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...
189
    }
190
191
    /**
192
     * Return's the product link attribute integer value with the passed product link attribute/link ID.
193
     *
194
     * @param integer $productLinkAttributeId The product link attribute ID of the attributes
195
     * @param integer $linkId                 The link ID of the attribute
196
     *
197
     * @return array The product link attribute integer value
198
     */
199
    public function loadProductLinkAttributeInt($productLinkAttributeId, $linkId)
200
    {
201
        return $this->getProductProcessor()->loadProductLinkAttributeInt($productLinkAttributeId, $linkId);
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 loadProductLinkAttributeInt() does only exist in the following implementations of said interface: TechDivision\Import\Prod...es\ProductLinkProcessor.

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...
202
    }
203
204
    /**
205
     * Persist's the passed product link data and return's the ID.
206
     *
207
     * @param array $productLink The product link data to persist
208
     *
209
     * @return string The ID of the persisted entity
210
     */
211
    public function persistProductLink($productLink)
212
    {
213
        return $this->getProductProcessor()->persistProductLink($productLink);
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 persistProductLink() does only exist in the following implementations of said interface: TechDivision\Import\Prod...es\ProductLinkProcessor.

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...
214
    }
215
216
    /**
217
     * Persist's the passed product link attribute integer data.
218
     *
219
     * @param array $productLinkAttributeInt The product link attribute integer data to persist
220
     *
221
     * @return string The ID of the persisted entity
222
     */
223
    public function persistProductLinkAttributeInt($productLinkAttributeInt)
224
    {
225
        $this->getProductProcessor()->persistProductLinkAttributeInt($productLinkAttributeInt);
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 persistProductLinkAttributeInt() does only exist in the following implementations of said interface: TechDivision\Import\Prod...es\ProductLinkProcessor.

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...
226
    }
227
}
228