Completed
Push — master ( 4ae46d...aeadee )
by Gilmar
24:03
created

Manager::hydratePriceSchedule()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 11
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 6

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 11
ccs 0
cts 0
cp 0
rs 9.4285
cc 2
eloc 6
nc 2
nop 1
crap 6
1
<?php
2
3
/*
4
 * This file is part of gpupo/netshoes-sdk
5
 * Created by Gilmar Pupo <[email protected]>
6
 * For the information of copyright and license you should read the file
7
 * LICENSE which is distributed with this source code.
8
 * Para a informação dos direitos autorais e de licença você deve ler o arquivo
9
 * LICENSE que é distribuído com este código-fonte.
10
 * Para obtener la información de los derechos de autor y la licencia debe leer
11
 * el archivo LICENSE que se distribuye con el código fuente.
12
 * For more information, see <http://www.g1mr.com/>.
13
 */
14
15
namespace Gpupo\NetshoesSdk\Entity\Product\Sku;
16
17
use Gpupo\CommonSdk\Entity\EntityInterface;
18
use Gpupo\CommonSdk\Exception\ManagerException;
19
use Gpupo\NetshoesSdk\Entity\AbstractManager;
20
21
class Manager extends AbstractManager
22
{
23
    protected $entity = 'Sku';
24
25
    /**
26
     * @codeCoverageIgnore
27
     */
28
    protected function setUp()
29
    {
30
        $this->maps = include 'map.config.php';
31
    }
32
33
    /**
34
     * @return Gpupo\Common\Entity\CollectionAbstract|null
35
     */
36 1
    public function findById($itemId)
37
    {
38 1
        $response = $this->perform($this->factoryMap('findById', [
39 1
            'productId' => $itemId,
40 1
            'itemId'    => $itemId,
41
        ]));
42
43 1
        $data = $this->processResponse($response);
44
45 1
        if (empty($data)) {
46
            return;
47
        }
48
49 1
        $sku = new Item($data->toArray());
50
51 1
        return $this->hydrate($sku);
52
    }
53
54
    protected function getDetail(EntityInterface $sku, $type)
55
    {
56
        $response = $this->perform($this->factoryMap('get'.$type, ['sku' => $sku->getId()]));
57
        $className = 'Gpupo\NetshoesSdk\Entity\Product\Sku\\'.$type;
58
        $data = $this->processResponse($response);
59
60
        $o = new $className($data->toArray());
61
62
        $this->getLogger()->addInfo('Detail', [
63
            'sku'       => $sku->getId(),
64
            'typ'       => $type,
65
            'response'  => $data,
66
            'className' => $className,
67
            'object'    => $o,
68
        ]);
69
70
        return $o;
71
    }
72
73
    protected function getPriceScheduleCollection(EntityInterface $sku)
74
    {
75
        try {
76
            $response = $this->perform($this->factoryMap('getPriceSchedule', ['sku' => $sku->getId()]));
77
            $data = $this->processResponse($response);
78
79
            if (empty($data)) {
80
                throw new ManagerException('No price schedule on SKU #'.$sku->getId());
81
            }
82
        } catch (ManagerException $e) {
83
            $this->getLogger()->addError($e->getMessage());
84
85
            return;
86
        }
87
88
        $collection = new PriceScheduleCollection($data->toArray());
89
90
        return $collection;
91
    }
92
93
    public function add(EntityInterface $entity, $productId)
94
    {
95
        return $this->execute($this->factoryMap('add', [
96
            'productId' => $productId,
97
        ]), $entity->toJson());
98
    }
99
100 1
    public function saveDetail(Item $sku, $type)
101
    {
102 1
        $json = $sku->toJson($type);
103 1
        $map = $this->factoryMap('save'.$type, ['sku' => $sku->getId()]);
104
105 1
        return $this->execute($map, $json);
106
    }
107
108
    protected function hydratePriceSchedule(EntityInterface $sku)
109
    {
110
        $ps = $this->getPriceScheduleCollection($sku);
111
112
        $sku->setPriceSchedule(false);
0 ignored issues
show
Bug introduced by
The method setPriceSchedule() does not seem to exist on object<Gpupo\CommonSdk\Entity\EntityInterface>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
113
        if ($ps instanceof PriceScheduleCollection) {
114
            $sku->setPriceSchedule($ps->getCurrent());
0 ignored issues
show
Bug introduced by
The method setPriceSchedule() does not seem to exist on object<Gpupo\CommonSdk\Entity\EntityInterface>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
115
        }
116
117
        return $sku;
118
    }
119
120
    protected function hydrate(EntityInterface $sku)
121
    {
122
        $sku->setPrice($this->getDetail($sku, 'Price'))
0 ignored issues
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface Gpupo\CommonSdk\Entity\EntityInterface as the method setPrice() does only exist in the following implementations of said interface: Gpupo\NetshoesSdk\Entity\Product\Sku\Price.

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...
123
            ->setStock($this->getDetail($sku, 'Stock'))
124
            ->setStatus($this->getDetail($sku, 'Status'));
125
126 1
        //return $this->hydratePriceSchedule($sku);
127
        return $sku;
128 1
    }
129
130
    /**
131 1
     * {@inheritdoc}
132
     */
133
    public function update(EntityInterface $entity, EntityInterface $existent = null)
134
    {
135
        parent::update($entity, $existent);
136
137 1
        $response = [
138 1
            'sku'      => $entity->getId(),
139
            'bypassed' => [],
140
            'code'     => [],
141 1
            'updated'  => [],
142
        ];
143 1
144
        foreach (['updateInfo', 'updateDetails'] as $method) {
145
            $response = $this->$method($entity, $existent, $response);
146 2
        }
147
148 2
        $this->log('info', 'Operação de Atualização', $response);
149
150
        return $response;
151
    }
152 2
153 1
    public function updateInfo(Item $entity, $existent = null, array $response = [])
154
    {
155 1
        $compare = $this->attributesDiff($entity, $existent, ['name', 'color',
156
            'size', 'gender', 'eanIsbn', 'images', 'video', 'height',
157
            'width', 'depth', 'weight', ]);
158 1
159 1
        if (false === $compare) {
160 1
            $response['bypassed'][] = 'info';
161 1
162
            return $response;
163 1
        }
164
165
        $map = $this->factoryMap('update', ['itemId' => $entity->getId(), 'sku' => $entity->getId()]);
166 2
        $operation = $this->execute($map, $entity->toJson());
167
        $response['code']['info'] = $operation->getHttpStatusCode();
168
        $response['updated'][] = 'info';
169 2
170
        return $response;
171
    }
172
173
    public function updateDetails(Item $entity, Item $existent = null, array $response = [])
174 2
    {
175
        foreach ([
176 2
            'Status' => ['active'],
177 2
            'Stock' => ['available'],
178 1
            'Price' => ['price'],
179 1
            'PriceSchedule' => ['priceTo'],
180
        ] as $key => $attributes) {
181
            $getter = 'get'.$key;
182
183 1
            if (!empty($existent)) {
184 1
                if (false === $this->attributesDiff($entity->$getter(), $existent->$getter(), $attributes)) {
185
                    $response['bypassed'][] = $key;
186
                    continue;
187 2
                }
188
            }
189
190
            $response['code'][$key] = $this->saveDetail($entity, $key)->getHttpStatusCode();
191
            $response['updated'][] = $key;
192
        }
193
194
        return $response;
195
    }
196
}
197