Completed
Push — develop ( e45dbf...2d4657 )
by Nate
04:34
created

ManageProviders::saveEnvironments()   A

Complexity

Conditions 5
Paths 8

Size

Total Lines 37

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 30

Importance

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