Completed
Push — 13.x ( 6ef6a1...0de302 )
by Tim
04:41
created

MediaGalleryValueObserver::isParentImage()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4

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
nc 1
nop 1
crap 2
1
<?php
2
3
/**
4
 * TechDivision\Import\Product\Media\Observers\MediaGalleryValueObserver
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-media
18
 * @link      http://www.techdivision.com
19
 */
20
21
namespace TechDivision\Import\Product\Media\Observers;
22
23
use TechDivision\Import\Utils\StoreViewCodes;
24
use TechDivision\Import\Product\Media\Utils\ColumnKeys;
25
use TechDivision\Import\Product\Media\Utils\MemberNames;
26
use TechDivision\Import\Product\Observers\AbstractProductImportObserver;
27
use TechDivision\Import\Product\Media\Services\ProductMediaProcessorInterface;
28
29
/**
30
 * Observer that creates/updates the product's media gallery value information.
31
 *
32
 * @author    Tim Wagner <[email protected]>
33
 * @copyright 2016 TechDivision GmbH <[email protected]>
34
 * @license   http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
35
 * @link      https://github.com/techdivision/import-product-media
36
 * @link      http://www.techdivision.com
37
 */
38
class MediaGalleryValueObserver extends AbstractProductImportObserver
39
{
40
41
    /**
42
     * The product media processor instance.
43
     *
44
     * @var \TechDivision\Import\Product\Media\Services\ProductMediaProcessorInterface
45
     */
46
    protected $productMediaProcessor;
47
48
    /**
49
     * Initialize the observer with the passed product media processor instance.
50
     *
51
     * @param \TechDivision\Import\Product\Media\Services\ProductMediaProcessorInterface $productMediaProcessor The product media processor instance
52
     */
53
    public function __construct(ProductMediaProcessorInterface $productMediaProcessor)
54
    {
55
        $this->productMediaProcessor = $productMediaProcessor;
56
    }
57
58
    /**
59
     * Return's the product media processor instance.
60
     *
61
     * @return \TechDivision\Import\Product\Media\Services\ProductMediaProcessorInterface The product media processor instance
62
     */
63
    protected function getProductMediaProcessor()
64
    {
65
        return $this->productMediaProcessor;
66
    }
67
68
    /**
69
     * Process the observer's business logic.
70
     *
71
     * @return array The processed row
72
     */
73
    protected function process()
74
    {
75
76
        // initialize and persist the product media gallery value
77
        $productMediaGalleryValue = $this->initializeProductMediaGalleryValue($this->prepareAttributes());
78
        $this->persistProductMediaGalleryValue($productMediaGalleryValue);
79
    }
80
81
    /**
82
     * Prepare the product media gallery value that has to be persisted.
83
     *
84
     * @return array The prepared product media gallery value attributes
85
     */
86
    protected function prepareAttributes()
87
    {
88
89
        try {
90
            // try to load the product SKU and map it the entity ID
91
            $parentId= $this->getValue(ColumnKeys::IMAGE_PARENT_SKU, null, array($this, 'mapParentSku'));
92
        } catch (\Exception $e) {
93
            throw $this->wrapException(array(ColumnKeys::IMAGE_PARENT_SKU), $e);
0 ignored issues
show
Documentation introduced by
array(\TechDivision\Impo...Keys::IMAGE_PARENT_SKU) is of type array<integer,?>, but the function expects a string.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
Deprecated Code introduced by
The method TechDivision\Import\Obse...server::wrapException() has been deprecated with message: Will be removed with version 1.0.0, use subject method instead

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
94
        }
95
96
        // load the store ID
97
        $storeId = $this->getRowStoreId(StoreViewCodes::ADMIN);
98
99
        // load the value ID and the position counter
100
        $valueId = $this->getParentValueId();
101
        $position = $this->raisePositionCounter();
102
103
        // load the image label
104
        $imageLabel = $this->getValue(ColumnKeys::IMAGE_LABEL);
105
106
        // load the flag that decides whether or not an image should be hidden on product page
107
        $hideFromProductPage = $this->getValue(ColumnKeys::HIDE_FROM_PRODUCT_PAGE);
108
109
        // prepare the media gallery value
110
        return $this->initializeEntity(
111
            array(
112
                MemberNames::VALUE_ID    => $valueId,
113
                MemberNames::STORE_ID    => $storeId,
114
                MemberNames::ENTITY_ID   => $parentId,
115
                MemberNames::LABEL       => $imageLabel,
116
                MemberNames::POSITION    => $position,
117
                MemberNames::DISABLED    => $hideFromProductPage
118
            )
119
        );
120
    }
121
122
    /**
123
     * Initialize the product media gallery value with the passed attributes and returns an instance.
124
     *
125
     * @param array $attr The product media gallery value attributes
126
     *
127
     * @return array The initialized product media gallery value
128
     */
129
    protected function initializeProductMediaGalleryValue(array $attr)
130
    {
131
        return $attr;
132
    }
133
134
    /**
135
     * Return's the store ID of the actual row, or of the default store
136
     * if no store view code is set in the CSV file.
137
     *
138
     * @param string|null $default The default store view code to use, if no store view code is set in the CSV file
139
     *
140
     * @return integer The ID of the actual store
141
     * @throws \Exception Is thrown, if the store with the actual code is not available
142
     */
143
    protected function getRowStoreId($default = null)
144
    {
145
        return $this->getSubject()->getRowStoreId($default);
0 ignored issues
show
Bug introduced by
The method getRowStoreId() does not exist on TechDivision\Import\Subjects\SubjectInterface. Did you maybe mean getRow()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
146
    }
147
148
    /**
149
     * Map's the passed SKU of the parent product to it's PK.
150
     *
151
     * @param string $parentSku The SKU of the parent product
152
     *
153
     * @return integer The primary key used to create relations
154
     */
155
    protected function mapParentSku($parentSku)
156
    {
157
        return $this->mapSkuToEntityId($parentSku);
158
    }
159
160
    /**
161
     * Return the entity ID for the passed SKU.
162
     *
163
     * @param string $sku The SKU to return the entity ID for
164
     *
165
     * @return integer The mapped entity ID
166
     * @throws \Exception Is thrown if the SKU is not mapped yet
167
     */
168
    protected function mapSkuToEntityId($sku)
169
    {
170
        return $this->getSubject()->mapSkuToEntityId($sku);
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 mapSkuToEntityId() does only exist in the following implementations of said interface: TechDivision\Import\Prod...a\Subjects\MediaSubject.

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...
171
    }
172
173
    /**
174
     * Return's the value ID of the created media gallery entry.
175
     *
176
     * @return integer The ID of the created media gallery entry
177
     */
178
    protected function getParentValueId()
179
    {
180
        return $this->getSubject()->getParentValueId();
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 getParentValueId() does only exist in the following implementations of said interface: TechDivision\Import\Prod...a\Subjects\MediaSubject.

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...
181
    }
182
183
    /**
184
     * Return's the store for the passed store code.
185
     *
186
     * @param string $storeCode The store code to return the store for
187
     *
188
     * @return array The requested store
189
     * @throws \Exception Is thrown, if the requested store is not available
190
     */
191
    protected function getStoreByStoreCode($storeCode)
192
    {
193
        return $this->getSubject()->getStoreByStoreCode($storeCode);
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 getStoreByStoreCode() does only exist in the following implementations of said interface: TechDivision\Import\Prod...a\Subjects\MediaSubject.

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...
194
    }
195
196
    /**
197
     * Returns the acutal value of the position counter and raise's it by one.
198
     *
199
     * @return integer The actual value of the position counter
200
     */
201
    protected function raisePositionCounter()
202
    {
203
        return $this->getSubject()->raisePositionCounter();
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 raisePositionCounter() does only exist in the following implementations of said interface: TechDivision\Import\Prod...a\Subjects\MediaSubject.

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...
204
    }
205
206
    /**
207
     * Persist's the passed product media gallery value data.
208
     *
209
     * @param array $productMediaGalleryValue The product media gallery value data to persist
210
     *
211
     * @return void
212
     */
213
    protected function persistProductMediaGalleryValue($productMediaGalleryValue)
214
    {
215
        $this->getProductMediaProcessor()->persistProductMediaGalleryValue($productMediaGalleryValue);
216
    }
217
}
218