Passed
Pull Request — master (#17)
by Matthew
02:00
created

SalsifyFetchExtension::fetchProduct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 21
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 14
c 1
b 0
f 0
dl 0
loc 21
rs 9.7998
cc 1
nc 1
nop 1
1
<?php
2
3
namespace Dyanmic\Salsify\ORM;
4
5
use Dynamic\Salsify\Model\Fetcher;
6
use Dynamic\Salsify\Model\Mapper;
7
use Dynamic\Salsify\Task\ImportTask;
8
use GuzzleHttp\Client;
9
use SilverStripe\Admin\LeftAndMainExtension;
0 ignored issues
show
Bug introduced by
The type SilverStripe\Admin\LeftAndMainExtension was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
10
use SilverStripe\Core\Config\Config;
11
use SilverStripe\Core\Injector\Injector;
12
use SilverStripe\Forms\Form;
13
use SilverStripe\ORM\DataObject;
14
use SilverStripe\Security\Security;
15
16
/**
17
 * Class LeftAndMainExtension
18
 * @package Dyanmic\Salsify\ORM
19
 * @property-read \SilverStripe\Admin\LeftAndMain|\Dyanmic\Salsify\ORM\SalsifyFetchExtension $owner
20
 */
21
class SalsifyFetchExtension extends LeftAndMainExtension
22
{
23
24
    /**
25
     * @var string
26
     */
27
    const MAPPER_INSTANCE = Mapper::class . '.single';
28
29
    /**
30
     * @var array
31
     */
32
    private static $allowed_actions = [
0 ignored issues
show
introduced by
The private property $allowed_actions is not used, and could be removed.
Loading history...
33
        'salsifyFetch',
34
    ];
35
36
    public function onBeforeInit()
37
    {
38
        if (!Injector::inst()->has($this::MAPPER_INSTANCE)) {
39
            Injector::inst()->load([
40
                $this::MAPPER_INSTANCE => [
41
                    'class' => Mapper::class,
42
                ],
43
            ]);
44
        }
45
    }
46
47
    /**
48
     * @return boolean
49
     */
50
    public function canFetchSalsify()
51
    {
52
        $className = $this->owner->currentPage()->getClassName();
53
54
        if (Injector::inst()->has($this::MAPPER_INSTANCE) && $this->configContainsMapping($className)) {
55
            return true;
56
        }
57
        return false;
58
    }
59
60
    /**
61
     * @param string $className
62
     *
63
     * @return boolean
64
     */
65
    private function configContainsMapping($className)
66
    {
67
        if (!Config::forClass($this::MAPPER_INSTANCE)->get('mapping')) {
68
            return false;
69
        }
70
71
        if (!$this->getClassMapping($className)) {
72
            return false;
73
        }
74
75
        return true;
76
    }
77
78
    /**
79
     * @param string $className
80
     * @return bool|array
81
     */
82
    private function getClassMapping($className)
83
    {
84
        $mapping = Config::forClass($this::MAPPER_INSTANCE)->get('mapping');
85
        if (array_key_exists($className, $mapping)) {
86
            return $mapping[$className];
87
        }
88
        if (array_key_exists('\\' . $className, $mapping)) {
89
            return $mapping['\\' . $className];
90
        }
91
        return false;
92
    }
93
94
    /**
95
     * @param array $data
96
     * @param Form $form
97
     * @return \SilverStripe\Control\HTTPResponse
98
     * @throws \Exception
99
     */
100
    public function salsifyFetch($data, $form)
101
    {
102
        $className = $this->owner->currentPage()->getClassName();
103
104
        $id = $data['ID'];
105
        /** @var DataObject|\Dyanmic\Salsify\ORM\SalsifyIDExtension $record */
106
        $record = DataObject::get_by_id($className, $id);
107
        if ($record && !$record->canEdit()) {
108
            return Security::permissionFailure();
109
        }
110
111
        if (!$record || !$record->SalsifyID) {
0 ignored issues
show
introduced by
$record is of type SilverStripe\ORM\DataObject, thus it always evaluated to true.
Loading history...
112
            $this->owner->httpError(404, "Bad salsify ID: " . (int)$id);
113
        }
114
115
        ImportTask::config()->remove('output');
116
        $data = $this->fetchProduct($record->SalsifyID);
117
        $this->mapData($record, $data);
118
119
        $this->owner->getResponse()->addHeader(
120
            'X-Status',
121
            rawurlencode(_t(__CLASS__ . '.UPDATED', 'Updated.'))
122
        );
123
        return $this->owner->getResponseNegotiator()->respond($this->owner->getRequest());
124
    }
125
126
    /**
127
     * @param string $salsifyID
128
     * @return array|NULL
129
     */
130
    private function fetchProduct($salsifyID)
131
    {
132
        $apiKey = Config::inst()->get(Fetcher::class, 'apiKey');
133
        $timeout = Config::inst()->get(Fetcher::class, 'timeout');
134
        $orgID = Config::inst()->get(Fetcher::class, 'organizationID');
135
136
        $url = "v1/orgs/{$orgID}/products/{$salsifyID}";
137
138
        $client = new Client([
139
            'base_uri' => Fetcher::API_BASE_URL,
140
            'timeout' => $timeout,
141
            'http_errors' => false,
142
            'verify' => true,
143
            'headers' => [
144
                'Authorization' => 'Bearer ' . $apiKey,
145
                'Content-Type' => 'application/json',
146
            ],
147
        ]);
148
149
        $response = $client->get($url);
150
        return json_decode($response->getBody(), true);
151
    }
152
153
    /**
154
     * @param DataObject $record
155
     * @param array $data
156
     * @throws \Exception
157
     */
158
    private function mapData($record, $data)
159
    {
160
        /** @var Mapper $mapper */
161
        $mapper = Injector::inst()->createWithArgs($this::MAPPER_INSTANCE, [
162
            'importerKey' => 'single',
163
        ]);
164
165
        $mapper->mapToObject($record->getClassName(), $this->getClassMapping($record->getClassName()), $data);
0 ignored issues
show
Bug introduced by
It seems like $this->getClassMapping($record->getClassName()) can also be of type boolean; however, parameter $mappings of Dynamic\Salsify\Model\Mapper::mapToObject() does only seem to accept array, maybe add an additional type check? ( Ignorable by Annotation )

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

165
        $mapper->mapToObject($record->getClassName(), /** @scrutinizer ignore-type */ $this->getClassMapping($record->getClassName()), $data);
Loading history...
166
    }
167
}