Passed
Push — master ( 606bf7...dde9c0 )
by Matthew
01:54
created

SalsifyFetchExtension::getClassMapping()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 10
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 6
c 1
b 0
f 0
dl 0
loc 10
rs 10
cc 3
nc 3
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 Dynamic\Salsify\Traits\InstanceCreator;
9
use GuzzleHttp\Client;
10
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...
11
use SilverStripe\Forms\Form;
12
use SilverStripe\ORM\DataObject;
13
use SilverStripe\Security\Security;
14
15
/**
16
 * Class LeftAndMainExtension
17
 * @package Dyanmic\Salsify\ORM
18
 * @property-read \SilverStripe\Admin\LeftAndMain|\Dyanmic\Salsify\ORM\SalsifyFetchExtension $owner
19
 */
20
class SalsifyFetchExtension extends LeftAndMainExtension
21
{
22
    use InstanceCreator;
23
24
    /**
25
     * @var bool
26
     */
27
    private $noChannel = true;
0 ignored issues
show
introduced by
The private property $noChannel is not used, and could be removed.
Loading history...
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
    /**
37
     * @return string
38
     */
39
    protected function getImporterKey()
40
    {
41
        return 'single';
42
    }
43
44
    /**
45
     *
46
     */
47
    public function onBeforeInit()
48
    {
49
        $this->createServices();
50
    }
51
52
    /**
53
     * @return boolean
54
     * @throws \Exception
55
     */
56
    public function canFetchSalsify()
57
    {
58
        $className = $this->owner->currentPage()->getClassName();
59
60
        // Only allow when product has a salsify id and has a single mapping config
61
        if ($this->owner->currentPage()->SalsifyID &&
62
            $this->hasService(Mapper::class) &&
63
            $this->configContainsMapping($className) &&
64
            $this->getFetcher()->config()->get('organizationID')
65
        ) {
66
            return true;
67
        }
68
        return false;
69
    }
70
71
    /**
72
     * @param string $className
73
     *
74
     * @return boolean
75
     * @throws \Exception
76
     */
77
    private function configContainsMapping($className)
78
    {
79
        if (!$this->getMapper()->config()->get('mapping')) {
80
            return false;
81
        }
82
83
        if (!$this->getClassMapping($className)) {
84
            return false;
85
        }
86
87
        return true;
88
    }
89
90
    /**
91
     * @param string $className
92
     * @return bool|array
93
     * @throws \Exception
94
     */
95
    private function getClassMapping($className)
96
    {
97
        $mapping = $this->getMapper()->config()->get('mapping');
98
        if (array_key_exists($className, $mapping)) {
99
            return $mapping[$className];
100
        }
101
        if (array_key_exists('\\' . $className, $mapping)) {
102
            return $mapping['\\' . $className];
103
        }
104
        return false;
105
    }
106
107
    /**
108
     * @param array $data
109
     * @param Form $form
110
     * @return \SilverStripe\Control\HTTPResponse
111
     * @throws \Exception
112
     */
113
    public function salsifyFetch($data, $form)
114
    {
115
        $className = $this->owner->currentPage()->getClassName();
116
117
        $id = $data['ID'];
118
        /** @var DataObject|\Dyanmic\Salsify\ORM\SalsifyIDExtension $record */
119
        $record = DataObject::get_by_id($className, $id);
120
        if ($record && !$record->canEdit()) {
121
            return Security::permissionFailure();
122
        }
123
124
        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...
125
            $this->owner->httpError(404, "Bad salsify ID: " . (int)$id);
126
        }
127
128
        ImportTask::config()->remove('output');
129
        $data = $this->fetchProduct($record->SalsifyID);
130
        $this->mapData($record, $data);
131
132
        $this->owner->getResponse()->addHeader(
133
            'X-Status',
134
            rawurlencode(_t(__CLASS__ . '.UPDATED', 'Updated.'))
135
        );
136
        return $this->owner->getResponseNegotiator()->respond($this->owner->getRequest());
137
    }
138
139
    /**
140
     * @param string $salsifyID
141
     * @return array|NULL
142
     * @throws \Exception
143
     */
144
    private function fetchProduct($salsifyID)
145
    {
146
147
        $apiKey = $this->getFetcher()->config()->get('apiKey');
148
        $timeout = $this->getFetcher()->config()->get('timeout');
149
        $orgID = $this->getFetcher()->config()->get('organizationID');
150
151
        $url = "v1/orgs/{$orgID}/products/{$salsifyID}";
152
153
        $client = new Client([
154
            'base_uri' => Fetcher::API_BASE_URL,
155
            'timeout' => $timeout,
156
            'http_errors' => false,
157
            'verify' => true,
158
            'headers' => [
159
                'Authorization' => 'Bearer ' . $apiKey,
160
                'Content-Type' => 'application/json',
161
            ],
162
        ]);
163
164
        $response = $client->get($url);
165
        return json_decode($response->getBody(), true);
166
    }
167
168
    /**
169
     * @param DataObject $record
170
     * @param array $data
171
     * @throws \Exception
172
     */
173
    private function mapData($record, $data)
174
    {
175
        $this->getMapper()->mapToObject(
176
            $record->getClassName(),
177
            $this->getClassMapping($record->getClassName()),
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

177
            /** @scrutinizer ignore-type */ $this->getClassMapping($record->getClassName()),
Loading history...
178
            $data
179
        );
180
    }
181
}
182