Passed
Push — master ( 9511a8...de0418 )
by Benjamin
07:41 queued 03:07
created

Plugin::_setPluginComponents()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
nc 1
nop 0
dl 0
loc 5
rs 10
c 0
b 0
f 0
1
<?php
2
/**
3
 * @link      https://dukt.net/social/
4
 * @copyright Copyright (c) 2018, Dukt
5
 * @license   https://github.com/dukt/social/blob/v2/LICENSE.md
6
 */
7
8
namespace dukt\social;
9
10
use Craft;
11
use craft\elements\User;
12
use craft\events\ModelEvent;
13
use craft\events\RegisterElementTableAttributesEvent;
14
use craft\events\RegisterUrlRulesEvent;
15
use craft\events\SetElementTableAttributeHtmlEvent;
16
use craft\helpers\UrlHelper;
17
use craft\services\Plugins;
18
use craft\web\twig\variables\CraftVariable;
19
use craft\web\UrlManager;
20
use dukt\social\base\PluginTrait;
21
use dukt\social\models\Settings;
22
use dukt\social\web\assets\login\LoginAsset;
23
use dukt\social\web\twig\variables\SocialVariable;
24
use dukt\social\web\assets\social\SocialAsset;
25
use yii\base\Event;
26
27
/**
28
 * Social plugin class.
29
 *
30
 * @author  Dukt <[email protected]>
31
 * @since   1.0
32
 */
33
class Plugin extends \craft\base\Plugin
34
{
35
    // Traits
36
    // =========================================================================
37
38
    use PluginTrait;
39
40
    // Properties
41
    // =========================================================================
42
43
    /**
44
     * @var bool
45
     */
46
    public $hasCpSettings = true;
47
48
    /**
49
     * @inheritdoc
50
     */
51
    public $minVersionRequired = '1.1.0';
52
53
    // Public Methods
54
    // =========================================================================
55
56
    /**
57
     * @inheritdoc
58
     */
59
    public function init()
60
    {
61
        parent::init();
62
63
        $this->_setPluginComponents();
64
        $this->_registerCpRoutes();
65
        $this->_registerVariable();
66
        $this->_registerEventHandlers();
67
        $this->_registerTableAttributes();
68
        $this->_initLoginAccountsUserPane();
69
    }
70
71
    /**
72
     * @inheritdoc
73
     */
74
    public function getSettingsResponse()
75
    {
76
        $url = UrlHelper::cpUrl('settings/social/loginproviders');
77
78
        Craft::$app->controller->redirect($url);
79
80
        return '';
81
    }
82
83
    /**
84
     * Get OAuth provider config.
85
     *
86
     * @param $handle
87
     *
88
     * @return array
89
     * @throws \yii\base\InvalidConfigException
90
     */
91
    public function getOauthProviderConfig($handle): array
92
    {
93
        $config = [
94
            'options' => $this->getOauthConfigItem($handle, 'options'),
95
            'scope' => $this->getOauthConfigItem($handle, 'scope'),
96
            'authorizationOptions' => $this->getOauthConfigItem($handle, 'authorizationOptions'),
97
        ];
98
99
        $provider = $this->getLoginProviders()->getLoginProvider($handle);
100
101
        if ($provider && !isset($config['options']['redirectUri'])) {
102
            $config['options']['redirectUri'] = $provider->getRedirectUri();
0 ignored issues
show
Bug introduced by
The method getRedirectUri() does not exist on dukt\social\base\LoginProviderInterface. Since it exists in all sub-types, consider adding an abstract or default implementation to dukt\social\base\LoginProviderInterface. ( Ignorable by Annotation )

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

102
            /** @scrutinizer ignore-call */ 
103
            $config['options']['redirectUri'] = $provider->getRedirectUri();
Loading history...
103
        }
104
105
        return $config;
106
    }
107
108
    /**
109
     * Get login provider config.
110
     *
111
     * @param $handle
112
     *
113
     * @return array
114
     */
115
    public function getLoginProviderConfig($handle)
116
    {
117
        $configSettings = Craft::$app->config->getConfigFromFile($this->id);
118
119
        if (isset($configSettings['loginProviders'][$handle])) {
120
            return $configSettings['loginProviders'][$handle];
121
        }
122
123
        return [];
124
    }
125
126
    /**
127
     * Save plugin settings.
128
     *
129
     * @param array $settings
130
     *
131
     * @return bool
132
     */
133
    public function savePluginSettings(array $settings, Plugin $plugin = null)
134
    {
135
        if (!$plugin) {
136
            $plugin = Craft::$app->getPlugins()->getPlugin('social');
137
138
            if ($plugin === null) {
139
                throw new NotFoundHttpException('Plugin not found');
0 ignored issues
show
Bug introduced by
The type dukt\social\NotFoundHttpException 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...
140
            }
141
        }
142
143
        $storedSettings = Craft::$app->plugins->getStoredPluginInfo('social')['settings'];
144
145
        $settings['loginProviders'] = [];
146
147
        if (isset($storedSettings['loginProviders'])) {
148
            $settings['loginProviders'] = $storedSettings['loginProviders'];
149
        }
150
151
        return Craft::$app->getPlugins()->savePluginSettings($plugin, $settings);
152
    }
153
154
    /**
155
     * Save login provider settings.
156
     *
157
     * @param $handle
158
     * @param $providerSettings
159
     *
160
     * @return bool
161
     */
162
    public function saveLoginProviderSettings($handle, $providerSettings)
163
    {
164
        $settings = (array)Plugin::getInstance()->getSettings();
165
        $storedSettings = Craft::$app->plugins->getStoredPluginInfo('social')['settings'];
166
167
        $settings['loginProviders'] = [];
168
169
        if (isset($storedSettings['loginProviders'])) {
170
            $settings['loginProviders'] = $storedSettings['loginProviders'];
171
        }
172
173
        $settings['loginProviders'][$handle] = $providerSettings;
174
175
        $plugin = Craft::$app->getPlugins()->getPlugin('social');
176
177
        return Craft::$app->getPlugins()->savePluginSettings($plugin, $settings);
178
    }
179
180
    // Protected Methods
181
    // =========================================================================
182
183
    /**
184
     * @inheritdoc
185
     */
186
    protected function createSettingsModel()
187
    {
188
        return new Settings();
189
    }
190
191
    // Private Methods
192
    // =========================================================================
193
194
    /**
195
     * Social login for the control panel.
196
     *
197
     * @return null
198
     * @throws \yii\base\InvalidConfigException
199
     */
200
    private function initCpSocialLogin()
201
    {
202
        if (!Craft::$app->getRequest()->getIsConsoleRequest() && $this->settings->enableCpLogin) {
0 ignored issues
show
Bug Best Practice introduced by
The property settings does not exist on dukt\social\Plugin. Since you implemented __get, consider adding a @property annotation.
Loading history...
203
            if (Craft::$app->getRequest()->getIsCpRequest() && Craft::$app->getRequest()->getSegment(1) === 'login') {
204
205
                $loginProviders = $this->loginProviders->getLoginProviders();
206
                $jsLoginProviders = [];
207
208
                foreach ($loginProviders as $loginProvider) {
209
                    $jsLoginProvider = [
210
                        'name' => $loginProvider->getName(),
211
                        'handle' => $loginProvider->getHandle(),
212
                        'url' => $this->getLoginAccounts()->getLoginUrl($loginProvider->getHandle()),
213
                        'iconUrl' => $loginProvider->getIconUrl(),
214
                    ];
215
216
                    array_push($jsLoginProviders, $jsLoginProvider);
217
                }
218
219
                $error = Craft::$app->getSession()->getFlash('error');
220
221
                Craft::$app->getView()->registerAssetBundle(LoginAsset::class);
222
223
                Craft::$app->getView()->registerJs('var socialLoginForm = new Craft.SocialLoginForm(' . json_encode($jsLoginProviders) . ', ' . json_encode($error) . ');');
224
            }
225
        }
226
    }
227
228
    /**
229
     * Initialize login accounts user pane.
230
     *
231
     * @return null
232
     */
233
    private function _initLoginAccountsUserPane()
234
    {
235
        Craft::$app->getView()->hook('cp.users.edit.details', function(&$context) {
236
            if ($context['user']) {
237
                $context['loginAccounts'] = $this->loginAccounts->getLoginAccountsByUserId($context['user']->id);
238
                $context['loginProviders'] = $this->loginProviders->getLoginProviders();
239
240
                Craft::$app->getView()->registerAssetBundle(SocialAsset::class);
241
242
                return Craft::$app->getView()->renderTemplate('social/_components/users/login-accounts-pane', $context);
243
            }
244
        });
245
    }
246
247
    /**
248
     * Get OAuth config item
249
     *
250
     * @param string $providerHandle
251
     * @param string $key
252
     *
253
     * @return array
254
     */
255
    private function getOauthConfigItem(string $providerHandle, string $key): array
256
    {
257
        $configSettings = Craft::$app->config->getConfigFromFile($this->id);
258
259
        if (isset($configSettings['loginProviders'][$providerHandle]['oauth'][$key])) {
260
            return $configSettings['loginProviders'][$providerHandle]['oauth'][$key];
261
        }
262
263
        $storedSettings = Craft::$app->plugins->getStoredPluginInfo($this->id)['settings'];
264
265
        if (isset($storedSettings['loginProviders'][$providerHandle]['oauth'][$key])) {
266
            return $storedSettings['loginProviders'][$providerHandle]['oauth'][$key];
267
        }
268
269
        return [];
270
    }
271
272
    /**
273
     * Set plugin components.
274
     */
275
    private function _setPluginComponents()
276
    {
277
        $this->setComponents([
278
            'loginAccounts' => \dukt\social\services\LoginAccounts::class,
279
            'loginProviders' => \dukt\social\services\LoginProviders::class,
280
        ]);
281
    }
282
283
    /**
284
     * Register CP routes.
285
     */
286
    private function _registerCpRoutes()
287
    {
288
        Event::on(UrlManager::class, UrlManager::EVENT_REGISTER_CP_URL_RULES, function(RegisterUrlRulesEvent $event) {
289
            $rules = [
290
                'social' => 'social/login-accounts/index',
291
292
                'social/loginaccounts' => 'social/loginAccounts/index',
293
                'social/loginaccounts/<userId:\d+>' => 'social/login-accounts/edit',
294
295
                'settings/social' => 'social/login-providers/index',
296
                'settings/social/loginproviders' => 'social/login-providers/index',
297
                'settings/social/loginproviders/<handle:{handle}>' => 'social/login-providers/oauth',
298
                'settings/social/loginproviders/<handle:{handle}>/user-field-mapping' => 'social/login-providers/user-field-mapping',
299
                'settings/social/settings' => 'social/settings/settings',
300
            ];
301
302
            $event->rules = array_merge($event->rules, $rules);
303
        });
304
    }
305
306
    /**
307
     * Register Social template variable.
308
     */
309
    private function _registerVariable()
310
    {
311
        Event::on(CraftVariable::class, CraftVariable::EVENT_INIT, function(Event $event) {
312
            /** @var CraftVariable $variable */
313
            $variable = $event->sender;
314
            $variable->set('social', SocialVariable::class);
315
        });
316
    }
317
318
    /**
319
     * Register Social user table attributes.
320
     */
321
    private function _registerTableAttributes()
322
    {
323
        Event::on(User::class, User::EVENT_REGISTER_TABLE_ATTRIBUTES, function(RegisterElementTableAttributesEvent $event) {
324
            $event->tableAttributes['loginAccounts'] = Craft::t('social', 'Login Accounts');
325
        });
326
327
        Event::on(User::class, User::EVENT_SET_TABLE_ATTRIBUTE_HTML, function(SetElementTableAttributeHtmlEvent $event) {
328
            if ($event->attribute === 'loginAccounts') {
329
                Craft::$app->getView()->registerAssetBundle(SocialAsset::class);
330
                $user = $event->sender;
331
332
                $loginAccounts = $this->getLoginAccounts()->getLoginAccountsByUserId($user->Id);
333
334
                if ($loginAccounts) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $loginAccounts of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
335
                    $event->html = Craft::$app->getView()->renderTemplate('social/_components/users/login-accounts-table-attribute', [
336
                        'loginAccounts' => $loginAccounts,
337
                    ]);
338
                } else {
339
                    $event->html = '';
340
                }
341
            }
342
        });
343
    }
344
345
    /**
346
     * Register event handlers.
347
     */
348
    private function _registerEventHandlers()
349
    {
350
        Event::on(User::class, User::EVENT_AFTER_SAVE, function(ModelEvent $event) {
351
            $user = $event->sender;
352
            $loginAccounts = Plugin::getInstance()->getLoginAccounts()->getLoginAccountsByUserId($user->id);
353
354
            foreach ($loginAccounts as $loginAccount) {
355
                Plugin::getInstance()->getLoginAccounts()->saveLoginAccount($loginAccount);
356
            }
357
        });
358
359
        Event::on(Plugins::class, Plugins::EVENT_AFTER_LOAD_PLUGINS, function() {
360
            $this->initCpSocialLogin();
361
        });
362
    }
363
}
364