Completed
Push — master ( e45dbf...3a73d5 )
by Nate
05:43 queued 04:08
created

ManageProviders::saveEnvironments()   A

Complexity

Conditions 5
Paths 8

Size

Total Lines 34

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 30

Importance

Changes 0
Metric Value
dl 0
loc 34
ccs 0
cts 18
cp 0
rs 9.0648
c 0
b 0
f 0
cc 5
nc 8
nop 1
crap 30
1
<?php
2
3
/**
4
 * @copyright  Copyright (c) Flipbox Digital Limited
5
 * @license    https://flipboxfactory.com/software/patron/license
6
 * @link       https://www.flipboxfactory.com/software/patron/
7
 */
8
9
namespace flipbox\patron\services;
10
11
use Craft;
12
use craft\helpers\ArrayHelper;
13
use craft\helpers\Json;
14
use flipbox\ember\helpers\ModelHelper;
15
use flipbox\ember\services\traits\records\AccessorByString;
16
use Flipbox\OAuth2\Client\Provider\Guardian as GuardianProvider;
17
use flipbox\patron\db\ProviderQuery;
18
use flipbox\patron\events\RegisterProviderSettings;
19
use flipbox\patron\Patron;
20
use flipbox\patron\providers\Base;
21
use flipbox\patron\providers\Facebook as FacebookSettings;
22
use flipbox\patron\providers\Guardian as GuardianSettings;
23
use flipbox\patron\providers\SettingsInterface;
24
use flipbox\patron\records\Provider;
25
use flipbox\patron\records\ProviderEnvironment;
26
use League\OAuth2\Client\Provider\Facebook as FacebookProvider;
27
use yii\base\Component;
28
use yii\base\InvalidConfigException;
29
30
/**
31
 * @author Flipbox Factory <[email protected]>
32
 * @since 1.0.0
33
 *
34
 * @method ProviderQuery getQuery($config = [])
35
 * @method Provider create(array $attributes = [])
36
 * @method Provider find($identifier)
37
 * @method Provider get($identifier)
38
 * @method Provider findByString($identifier)
39
 * @method Provider getByString($identifier)
40
 * @method Provider findByCondition($condition = [])
41
 * @method Provider getByCondition($condition = [])
42
 * @method Provider findByCriteria($criteria = [])
43
 * @method Provider getByCriteria($criteria = [])
44
 * @method Provider[] findAllByCondition($condition = [])
45
 * @method Provider[] getAllByCondition($condition = [])
46
 * @method Provider[] findAllByCriteria($criteria = [])
47
 * @method Provider[] getAllByCriteria($criteria = [])
48
 */
49
class ManageProviders extends Component
50
{
51
    use AccessorByString;
52
53
    /**
54
     * @inheritdoc
55
     */
56 3
    public function init()
57
    {
58 3
        parent::init();
59
60
        // Register setting handlers for providers
61 3
        RegisterProviderSettings::on(
62 3
            GuardianProvider::class,
63 3
            RegisterProviderSettings::REGISTER_SETTINGS,
64 1
            function (RegisterProviderSettings $event) {
65
                $event->class = GuardianSettings::class;
66 3
            }
67
        );
68
69 3
        RegisterProviderSettings::on(
70 3
            FacebookProvider::class,
71 3
            RegisterProviderSettings::REGISTER_SETTINGS,
72 1
            function (RegisterProviderSettings $event) {
73
                $event->class = FacebookSettings::class;
74 3
            }
75
        );
76 3
    }
77
78
    /**
79
     * @inheritdoc
80
     */
81
    public static function recordClass(): string
82
    {
83
        return Provider::class;
84
    }
85
86
    /**
87
     * @inheritdoc
88
     */
89
    public static function stringProperty(): string
90
    {
91
        return 'handle';
92
    }
93
94
    /**
95
     * @param array $config
96
     * @return array
97
     */
98
    protected function prepareQueryConfig($config = [])
99
    {
100
        if (!is_array($config)) {
101
            $config = ArrayHelper::toArray($config, [], true);
102
        }
103
104
        // Allow disabled when managing
105
        if (!array_key_exists('enabled', $config)) {
106
            $config['enabled'] = null;
107
        }
108
109
        // Allow all environments when managing
110
        if (!array_key_exists('environment', $config)) {
111
            $config['environment'] = null;
112
        }
113
114
        return $config;
115
    }
116
117
    /**
118
     * @param Provider $provider
119
     * @param array $settings
120
     * @return SettingsInterface
121
     * @throws InvalidConfigException
122
     */
123
    public function resolveSettings(Provider $provider, $settings = []): SettingsInterface
124
    {
125
        return $this->createSettings($provider->class, $settings);
126
    }
127
128
    /**
129
     * @param string $providerClass
130
     * @return mixed
131
     */
132
    protected function resolveSettingsClass(string $providerClass = null): string
133
    {
134
        if (null === $providerClass) {
135
            return Base::class;
136
        }
137
138
        $event = new RegisterProviderSettings();
139
140
        RegisterProviderSettings::trigger(
141
            $providerClass,
142
            RegisterProviderSettings::REGISTER_SETTINGS,
143
            $event
144
        );
145
146
        if (!$this->isSettingsInstance($event->class)) {
147
            return Base::class;
148
        }
149
150
        return $event->class;
151
    }
152
153
    /**
154
     * Check settings instance
155
     *
156
     * @param $class
157
     * @return bool
158
     */
159
    private function isSettingsInstance($class): bool
160
    {
161
        return $class instanceof SettingsInterface || is_subclass_of($class, SettingsInterface::class);
162
    }
163
164
    /**
165
     * @param $providerClass
166
     * @param array $settings
167
     * @return SettingsInterface
168
     * @throws InvalidConfigException
169
     */
170
    protected function createSettings($providerClass, $settings = []): SettingsInterface
171
    {
172
        if (is_string($settings)) {
173
            $settings = Json::decodeIfJson($settings);
174
        }
175
176
        if (!is_array($settings)) {
177
            $settings = ArrayHelper::toArray($settings, [], true);
178
        }
179
180
        $settings['class'] = $this->resolveSettingsClass($providerClass);
181
182
        /** @var SettingsInterface $model */
183
        $model = ModelHelper::create($settings, SettingsInterface::class);
184
185
        return $model;
186
    }
187
188
189
    /*******************************************
190
     * ENVIRONMENTS
191
     *******************************************/
192
193
    /**
194
     * @param Provider $provider
195
     * @return bool
196
     * @throws \Throwable
197
     * @throws \yii\db\StaleObjectException
198
     */
199
    public function saveEnvironments(Provider $provider)
200
    {
201
        $successful = true;
202
203
        /** @var ProviderEnvironment[] $allRecords */
204
        $allRecords = $provider->getEnvironments()
205
            ->all();
206
207
        foreach ($this->resolveEnvironments($provider) as $model) {
208
            ArrayHelper::remove($allRecords, $model->environment);
209
            $model->providerId = $provider->getId();
210
211
            if (!$model->save()) {
212
                $successful = false;
213
                // Log the errors
214
                $error = Craft::t(
215
                    'patron',
216
                    "Couldn't save environment due to validation errors:"
217
                );
218
                foreach ($model->getFirstErrors() as $attributeError) {
219
                    $error .= "\n- " . Craft::t('patron', $attributeError);
220
                }
221
222
                $provider->addError('sites', $error);
223
            }
224
        }
225
226
        // Delete old records
227
        foreach ($allRecords as $record) {
228
            $record->delete();
229
        }
230
231
        return $successful;
232
    }
233
234
    /**
235
     * @param Provider $provider
236
     * @return ProviderEnvironment[]
237
     */
238
    protected function defaultEnvironments(Provider $provider): array
239
    {
240
        $environments = [];
241
242
        foreach (Patron::getInstance()->getSettings()->getDefaultEnvironments() as $environment) {
243
            $environments[$environment] = new ProviderEnvironment([
244
                'providerId' => $provider->getId(),
245
                'environment' => $environment
246
            ]);
247
        }
248
249
        return $environments;
250
    }
251
252
    /**
253
     * @param Provider $provider
254
     * @return array
255
     */
256
    protected function resolveEnvironments(Provider $provider): array
257
    {
258
        $environments = $provider->environments;
259
260
        if (empty($environments)) {
261
            $environments = $this->defaultEnvironments($provider);
262
        }
263
264
        return $environments;
265
    }
266
267
268
    /*******************************************
269
     * STATES
270
     *******************************************/
271
272
    /**
273
     * @param Provider $record
274
     * @return bool
275
     */
276
    public function disable(Provider $record)
277
    {
278
        $record->enabled = false;
279
        return $record->save(true, ['enabled']);
280
    }
281
282
    /**
283
     * @param Provider $record
284
     * @return bool
285
     */
286
    public function enable(Provider $record)
287
    {
288
        $record->enabled = true;
289
        return $record->save(true, ['enabled']);
290
    }
291
}
292