Issues (45)

src/services/Providers.php (10 issues)

1
<?php
2
/**
3
 * Socializer plugin for Craft CMS 3.x
4
 *
5
 * @link      https://enupal.com/
6
 * @copyright Copyright (c) 2019 Enupal LLC
7
 */
8
9
namespace enupal\socializer\services;
10
11
use Craft;
12
use craft\db\Query;
13
use craft\elements\User;
14
use craft\fields\Dropdown;
15
use craft\fields\Email;
16
use craft\fields\Number;
17
use craft\fields\PlainText;
18
use craft\helpers\UrlHelper;
19
use enupal\socializer\elements\Provider;
20
use enupal\socializer\events\AfterLoginEvent;
21
use enupal\socializer\events\AfterRegisterUserEvent;
22
use enupal\socializer\events\BeforeLoginEvent;
23
use enupal\socializer\events\BeforeRegisterUserEvent;
24
use enupal\socializer\records\Provider as ProviderRecord;
25
use Hybridauth\Provider\Amazon;
26
use Hybridauth\Provider\Apple;
27
use Hybridauth\Provider\Authentiq;
28
use Hybridauth\Provider\BitBucket;
29
use Hybridauth\Provider\Blizzard;
30
use Hybridauth\Provider\Discord;
31
use Hybridauth\Provider\Disqus;
32
use Hybridauth\Provider\Dribbble;
33
use Hybridauth\Provider\Facebook;
34
use Hybridauth\Provider\Foursquare;
35
use Hybridauth\Provider\GitHub;
36
use Hybridauth\Provider\GitLab;
37
use Hybridauth\Provider\Instagram;
38
use Hybridauth\Provider\LinkedIn;
39
use Hybridauth\Provider\Mailru;
0 ignored issues
show
The type Hybridauth\Provider\Mailru 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...
40
use Hybridauth\Provider\Medium;
41
use Hybridauth\Provider\MicrosoftGraph;
42
use Hybridauth\Provider\Odnoklassniki;
0 ignored issues
show
The type Hybridauth\Provider\Odnoklassniki 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...
43
use Hybridauth\Provider\ORCID;
44
use Hybridauth\Provider\QQ;
45
use Hybridauth\Provider\Reddit;
46
use Hybridauth\Provider\Slack;
47
use Hybridauth\Provider\Spotify;
48
use Hybridauth\Provider\StackExchange;
49
use Hybridauth\Provider\Steam;
50
use Hybridauth\Provider\SteemConnect;
51
use Hybridauth\Provider\Strava;
52
use Hybridauth\Provider\Telegram;
53
use Hybridauth\Provider\Tumblr;
54
use Hybridauth\Provider\TwitchTV;
55
use Hybridauth\Provider\Twitter;
56
use Hybridauth\Provider\Google;
57
use Hybridauth\Provider\Vkontakte;
0 ignored issues
show
The type Hybridauth\Provider\Vkontakte 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...
58
use Hybridauth\Provider\WeChat;
59
use Hybridauth\Provider\WindowsLive;
60
use Hybridauth\Provider\WordPress;
61
use Hybridauth\Provider\Yahoo;
62
use Hybridauth\Provider\Yandex;
0 ignored issues
show
The type Hybridauth\Provider\Yandex 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...
63
use Hybridauth\User\Profile;
64
use yii\base\Component;
65
use enupal\socializer\Socializer;
66
use yii\base\NotSupportedException;
67
use yii\db\Exception;
68
69
class Providers extends Component
70
{
71
    /**
72
     * @event BeforeLogin The event that is triggered before a user is logged in
73
     *
74
     * ```php
75
     * use enupal\socializer\events\BeforeLoginEvent;
76
     * use enupal\socializer\services\Providers;
77
     * use yii\base\Event;
78
     *
79
     * Event::on(Providers::class, Providers::EVENT_BEFORE_LOGIN, function(BeforeLoginEvent $e) {
80
     *      $user = $e->user;
81
     *      $userProfile = $e->userProfile;
82
     *      $provider = $e->provider;
83
     *      // set to false to cancel this action
84
     *      $e->isValid = true;
85
     *     // Do something
86
     * });
87
     * ```
88
     */
89
    const EVENT_BEFORE_LOGIN = 'beforeLoginUser';
90
91
    /**
92
     * @event AfterLogin The event that is triggered after a user is logged in
93
     *
94
     * ```php
95
     * use enupal\socializer\events\AfterLoginEvent;
96
     * use enupal\socializer\services\Providers;
97
     * use yii\base\Event;
98
     *
99
     * Event::on(Providers::class, Providers::EVENT_AFTER_LOGIN, function(AfterLoginEvent $e) {
100
     *      $user = $e->user;
101
     *      $userProfile = $e->userProfile;
102
     *      $provider = $e->provider;
103
     *     // Do something
104
     * });
105
     * ```
106
     */
107
    const EVENT_AFTER_LOGIN = 'afterLoginUser';
108
109
    /**
110
     * @event BeforeRegister The event that is triggered before a user is registered
111
     *
112
     * ```php
113
     * use enupal\socializer\events\BeforeRegisterUserEvent;
114
     * use enupal\socializer\services\Providers;
115
     * use yii\base\Event;
116
     *
117
     * Event::on(Providers::class, Providers::EVENT_BEFORE_REGISTER, function(BeforeRegisterUserEvent $e) {
118
     *      $user = $e->user;
119
     *      $userProfile = $e->userProfile;
120
     *      $provider = $e->provider;
121
     *      // set to false to cancel this action
122
     *      $e->isValid = true;
123
     *     // Do something
124
     * });
125
     * ```
126
     */
127
    const EVENT_BEFORE_REGISTER = 'beforeRegisterUser';
128
129
    /**
130
     * @event AfterLogin The event that is triggered after a user is registered
131
     *
132
     * ```php
133
     * use enupal\socializer\events\AfterRegisterUserEvent;
134
     * use enupal\socializer\services\Providers;
135
     * use yii\base\Event;
136
     *
137
     * Event::on(Providers::class, Providers::EVENT_AFTER_ORDER_COMPLETE, function(AfterRegisterUserEvent $e) {
138
     *      $user = $e->user;
139
     *      $user = $e->userProfile;
140
     *      $user = $e->provider;
141
     *     // Do something
142
     * });
143
     * ```
144
     */
145
    const EVENT_AFTER_REGISTER = 'afterRegisterUser';
146
147
    /**
148
     * @param $handle
149
     * @param $options
150
     * @return string
151
     * @throws NotSupportedException
152
     * @throws \yii\base\Exception
153
     */
154
    public function loginUrl($handle, $options = [])
155
    {
156
        $provider = $this->getProviderByHandle($handle);
157
        if (is_null($provider)){
158
            throw new NotSupportedException('Provider not found or disabled: '.$handle);
159
        }
160
161
        $options['provider'] = $handle;
162
163
        return UrlHelper::siteUrl('socializer/login', $options);
164
    }
165
166
    /**
167
     * @return array
168
     */
169
    public function getAllProviderTypes()
170
    {
171
        return [
172
            Apple::class,
173
            Amazon::class,
174
            Authentiq::class,
175
            BitBucket::class,
176
            Blizzard::class,
177
            Discord::class,
178
            Disqus::class,
179
            Dribbble::class,
180
            Facebook::class,
181
            Foursquare::class,
182
            GitHub::class,
183
            GitLab::class,
184
            Google::class,
185
            Instagram::class,
186
            LinkedIn::class,
187
            Medium::class,
188
            MicrosoftGraph::class,
189
            ORCID::class,
190
            Reddit::class,
191
            Slack::class,
192
            Spotify::class,
193
            StackExchange::class,
194
            Steam::class,
195
            Strava::class,
196
            SteemConnect::class,
197
            Telegram::class,
198
            Tumblr::class,
199
            TwitchTV::class,
200
            Twitter::class,
201
            WeChat::class,
202
            WindowsLive::class,
203
            WordPress::class,
204
            Yahoo::class,
205
            QQ::class
206
        ];
207
    }
208
209
    /**
210
     * @return array
211
     */
212
    public function getUserFieldsAsOptions()
213
    {
214
        $user = new User();
215
        $fields = $user->getFieldLayout()->getCustomFields();
216
        $options = [[
217
            'label' => 'None',
218
            'value' => ''
219
        ]];
220
221
        foreach ($fields as $field) {
222
            if (!$this->validateFieldClass($field)){
223
                continue;
224
            }
225
226
            $option = [
227
                'label' => $field->name. ' ('.$field->handle.')',
228
                'value' => $field->handle
229
            ];
230
231
            $options[] = $option;
232
        }
233
234
        return $options;
235
    }
236
237
    /**
238
     * @param $field
239
     * @return bool
240
     */
241
    private function validateFieldClass($field)
242
    {
243
        $fieldClass = get_class($field);
244
245
        $supportedClasses = [
246
          PlainText::class => 1,
247
          Dropdown::class => 1
248
        ];
249
250
        if (isset($supportedClasses[$fieldClass])){
251
            return true;
252
        }
253
254
        return false;
255
    }
256
257
    /**
258
     * @return array
259
     */
260
    public function getUserProfileFieldsAsOptions()
261
    {
262
        return [
263
            [
264
                'label' => 'Email',
265
                'value' => 'email',
266
                'compatibleCraftFields' => [
267
                    PlainText::class
268
                ]
269
            ],
270
            [
271
                'label' => 'Identifier',
272
                'value' => 'identifier',
273
                'compatibleCraftFields' => [
274
                    PlainText::class,
275
                    Dropdown::class
276
                ]
277
            ],
278
            [
279
                'label' => 'Profile URL',
280
                'value' => 'profileURL',
281
                'compatibleCraftFields' => [
282
                    PlainText::class
283
                ]
284
            ],
285
            [
286
                'label' => 'WebSite URL',
287
                'value' => 'webSiteURL',
288
                'compatibleCraftFields' => [
289
                    PlainText::class
290
                ]
291
            ],
292
            [
293
                'label' => 'Photo URL',
294
                'value' => 'photoURL',
295
                'compatibleCraftFields' => [
296
                ]
297
            ],
298
            [
299
                'label' => 'Display Name',
300
                'value' => 'displayName',
301
                'compatibleCraftFields' => [
302
                    PlainText::class,
303
                    Dropdown::class
304
                ]
305
            ],
306
            [
307
                'label' => 'Description',
308
                'value' => 'description',
309
                'compatibleCraftFields' => [
310
                    PlainText::class
311
                ]
312
            ],
313
            [
314
                'label' => 'First Name',
315
                'value' => 'firstName',
316
                'compatibleCraftFields' => [
317
                    PlainText::class
318
                ]
319
            ],
320
            [
321
                'label' => 'Last Name',
322
                'value' => 'lastName',
323
                'compatibleCraftFields' => [
324
                    PlainText::class
325
                ]
326
            ],
327
            [
328
                'label' => 'Gender',
329
                'value' => 'gender',
330
                'compatibleCraftFields' => [
331
                    PlainText::class,
332
                    Dropdown::class
333
                ]
334
            ],
335
            [
336
                'label' => 'Language',
337
                'value' => 'language',
338
                'compatibleCraftFields' => [
339
                    PlainText::class
340
                ]
341
            ],
342
            [
343
                'label' => 'Age',
344
                'value' => 'age',
345
                'compatibleCraftFields' => [
346
                    PlainText::class,
347
                    Number::class
348
                ]
349
            ],
350
            [
351
                'label' => 'Birth Day',
352
                'value' => 'birthDay',
353
                'compatibleCraftFields' => [
354
                    PlainText::class,
355
                    Number::class
356
                ]
357
            ],
358
            [
359
                'label' => 'Birth Month',
360
                'value' => 'birthMonth',
361
                'compatibleCraftFields' => [
362
                    PlainText::class,
363
                    Number::class
364
                ]
365
            ],
366
            [
367
                'label' => 'Birth Year',
368
                'value' => 'birthYear',
369
                'compatibleCraftFields' => [
370
                    PlainText::class,
371
                    Number::class
372
                ]
373
            ],
374
            [
375
                'label' => 'Email Verified',
376
                'value' => 'emailVerified',
377
                'compatibleCraftFields' => [
378
                    PlainText::class,
379
                    Email::class
380
                ]
381
            ],
382
            [
383
                'label' => 'Phone',
384
                'value' => 'phone',
385
                'compatibleCraftFields' => [
386
                    PlainText::class
387
                ]
388
            ],
389
            [
390
                'label' => 'Address',
391
                'value' => 'address',
392
                'compatibleCraftFields' => [
393
                    PlainText::class
394
                ]
395
            ],
396
            [
397
                'label' => 'Country',
398
                'value' => 'country',
399
                'compatibleCraftFields' => [
400
                    PlainText::class,
401
                    Dropdown::class
402
                ]
403
            ],
404
            [
405
                'label' => 'Region',
406
                'value' => 'region',
407
                'compatibleCraftFields' => [
408
                    PlainText::class,
409
                    Dropdown::class
410
                ]
411
            ],
412
            [
413
                'label' => 'City',
414
                'value' => 'city',
415
                'compatibleCraftFields' => [
416
                    PlainText::class,
417
                    Dropdown::class
418
                ]
419
            ],
420
            [
421
                'label' => 'Zip',
422
                'value' => 'zip',
423
                'compatibleCraftFields' => [
424
                    PlainText::class
425
                ]
426
            ],
427
            [
428
                'label' => 'Data (JSON)',
429
                'value' => 'data',
430
                'compatibleCraftFields' => [
431
                    PlainText::class
432
                ]
433
            ]
434
        ];
435
    }
436
437
    /**
438
     * @return array
439
     */
440
    public function getDefaultFieldMapping()
441
    {
442
        $userProfileFields = Socializer::$app->providers->getUserProfileFieldsAsOptions();
443
        $options = [];
444
        foreach ($userProfileFields as $item) {
445
            $option = [
446
                'sourceFormField' => $item['value'],
447
                'targetUserField' => ''
448
            ];
449
            $options[] = $option;
450
        }
451
452
        return $options;
453
    }
454
455
    /**
456
     * @param bool $excludeCreated
457
     * @return array
458
     * @throws \ReflectionException
459
     */
460
    public function getProviderTypesAsOptions($excludeCreated = true)
461
    {
462
        $providers = $this->getAllProviderTypes();
463
464
        if ($excludeCreated){
465
            $providers = $this->getExcludeCreatedProviders();
466
        }
467
468
        $asOptions = [];
469
        foreach ($providers as $provider) {
470
            $option = [
471
                "label" => $this->getClassNameFromNamespace($provider),
472
                "value" => $provider
473
            ];
474
            $asOptions[] = $option;
475
        }
476
477
        return $asOptions;
478
    }
479
480
    /**
481
     * @return array
482
     */
483
    public function getExcludeCreatedProviders()
484
    {
485
        $providerTypes = $this->getAllProviderTypes();
486
        $providers = (new Query())
487
            ->select(['type'])
488
            ->from(["{{%enupalsocializer_providers}}"])
489
            ->all();
490
491
        foreach ($providers as $provider) {
492
            if (($key = array_search($provider["type"], $providerTypes)) !== false) {
493
                unset($providerTypes[$key]);
494
            }
495
        }
496
497
        return $providerTypes;
498
    }
499
500
    /**
501
     * @param $class
502
     * @return string
503
     * @throws \ReflectionException
504
     */
505
    public function getClassNameFromNamespace($class)
506
    {
507
        return (new \ReflectionClass($class))->getShortName();
508
    }
509
510
    /**
511
     * Returns a Provider model if one is found in the database by id
512
     *
513
     * @param int $id
514
     * @param int $siteId
515
     *
516
     * @return null|Provider
517
     */
518
    public function getProviderById(int $id, int $siteId = null)
519
    {
520
        /** @var Provider $provider */
521
        $provider = Craft::$app->getElements()->getElementById($id, Provider::class, $siteId);
522
523
        return $provider;
524
    }
525
526
    /**
527
     * Removes providers and related records from the database given the ids
528
     *
529
     * @param $providers
530
     *
531
     * @return bool
532
     * @throws \Throwable
533
     */
534
    public function deleteProviders($providers): bool
535
    {
536
        foreach ($providers as $key => $providerElement) {
537
            $provider = $this->getProviderById($providerElement->id);
538
539
            if ($provider) {
540
                $this->deleteProvider($provider);
541
            } else {
542
                Craft::error("Can't delete the payment form with id: {$providerElement->id}", __METHOD__);
543
            }
544
        }
545
546
        return true;
547
    }
548
549
    /**
550
     * @param Provider $provider
551
     *
552
     * @return bool
553
     * @throws \Throwable
554
     */
555
    public function deleteProvider(Provider $provider)
556
    {
557
        $transaction = Craft::$app->db->beginTransaction();
558
559
        try {
560
            // Delete the tokens
561
            $tokens = (new Query())
562
                ->select(['id'])
563
                ->from(["{{%enupalsocializer_tokens}}"])
564
                ->where(['providerId' => $provider->id])
565
                ->all();
566
567
            foreach ($tokens as $token) {
568
                Craft::$app->elements->deleteElementById($token['id']);
0 ignored issues
show
The method deleteElementById() does not exist on null. ( Ignorable by Annotation )

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

568
                Craft::$app->elements->/** @scrutinizer ignore-call */ 
569
                                       deleteElementById($token['id']);

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
569
            }
570
571
            // Delete the Provider Element
572
            $success = Craft::$app->elements->deleteElementById($provider->id);
573
574
            if (!$success) {
575
                $transaction->rollback();
576
                Craft::error("Couldn’t delete Provider", __METHOD__);
577
578
                return false;
579
            }
580
581
            $transaction->commit();
582
        } catch (\Exception $e) {
583
            $transaction->rollback();
584
585
            throw $e;
586
        }
587
588
        return true;
589
    }
590
591
    /**
592
     * @param string $handle
593
     * @param int|null $siteId
594
     * @return array|Provider|null
595
     */
596
    public function getProviderByHandle(string $handle, int $siteId = null)
597
    {
598
        $query = Provider::find();
599
        $query->handle($handle);
600
        $query->siteId($siteId);
601
602
        return $query->one();
603
    }
604
605
    /**
606
     * @param string $type
607
     * @param int|null $siteId
608
     * @return array|Provider|null
609
     */
610
    public function getProviderByType(string $type, int $siteId = null)
611
    {
612
        $query = Provider::find();
613
        $query->type($type);
614
        $query->siteId($siteId);
615
616
        return $query->one();
617
    }
618
619
    /**
620
     * @param string $name
621
     * @param string $handle
622
     * @param string $type
623
     *
624
     * @return Provider
625
     * @throws \Exception
626
     * @throws \Throwable
627
     */
628
    public function createNewProvider(string $name, string $handle, string $type): Provider
629
    {
630
        $provider = new Provider();
631
632
        $provider->name = $name;
633
        $provider->handle = $handle;
634
        $provider->type = $type;
635
        $provider->enabled = 0;
636
637
        $this->saveProvider($provider);
638
639
        return $provider;
640
    }
641
642
    /**
643
     * @param Provider $provider
644
     * @return bool
645
     * @throws \Throwable
646
     * @throws \craft\errors\ElementNotFoundException
647
     * @throws \craft\errors\MissingComponentException
648
     * @throws \craft\errors\WrongEditionException
649
     * @throws \yii\base\Exception
650
     */
651
    public function loginOrRegisterUser(Provider $provider)
652
    {
653
        $adapter = $provider->getAdapter();
654
        try {
655
            $adapter->authenticate();
656
        } catch (\Exception $e){
657
            Craft::error("Unable to Authorize user", __METHOD__);
658
            return false;
659
        }
660
661
        $userProfile = $adapter->getUserProfile();
662
        $user = Craft::$app->getUser()->getIdentity();
663
664
        if (!$user){
0 ignored issues
show
$user is of type yii\web\IdentityInterface, thus it always evaluated to true.
Loading history...
665
            $user = $this->retrieveUser($userProfile, $provider);
666
        }
667
668
        if (!$user){
0 ignored issues
show
$user is of type yii\web\IdentityInterface, thus it always evaluated to true.
Loading history...
669
            Craft::error("Not user to login", __METHOD__);
670
            return false;
671
        }
672
673
        Socializer::$app->tokens->registerToken($user, $provider);
674
675
        $user = $this->triggerBeforeLoginUser($user, $provider, $userProfile);
676
677
        if (is_null($user)){
678
            Craft::error("User not valid to login on BeforeLoginEvent", __METHOD__);
679
            return false;
680
        }
681
682
        if (!Craft::$app->getUser()->login($user)) {
683
            Craft::error("Something went wrong while login craft user", __METHOD__);
684
            return false;
685
        }
686
687
        $this->triggerAfterLoginEvent($user, $provider, $userProfile);
688
689
        return true;
690
    }
691
692
    public function triggerBeforeLoginUser($user, $provider, $userProfile)
693
    {
694
        $event = new BeforeLoginEvent([
695
            'user' => $user,
696
            'provider' => $provider,
697
            'userProfile' => $userProfile,
698
        ]);
699
700
        $this->trigger(self::EVENT_BEFORE_LOGIN, $event);
701
        $user = $event->user;
702
703
        if (!$event->isValid) {
704
            return null;
705
        }
706
707
        return $user;
708
    }
709
710
    private function triggerAfterLoginEvent($user, $provider, $userProfile)
711
    {
712
        $event = new AfterLoginEvent([
713
            'user' => $user,
714
            'provider' => $provider,
715
            'userProfile' => $userProfile,
716
        ]);
717
718
        $this->trigger(self::EVENT_AFTER_LOGIN, $event);
719
    }
720
721
    /**
722
     * Register or get existing user
723
     * @param Profile $userProfile
724
     * @param Provider $provider
725
     * @return ?User
726
     * @throws \Throwable
727
     * @throws \craft\errors\ElementNotFoundException
728
     * @throws \craft\errors\WrongEditionException
729
     * @throws \yii\base\Exception
730
     */
731
    private function retrieveUser(Profile $userProfile, Provider $provider): ?User
732
    {
733
        if (is_null($userProfile->email)){
734
            throw new \Exception("Email address is not provided, please check the settings of your application");
735
        }
736
737
        $user = Craft::$app->users->getUserByUsernameOrEmail($userProfile->email);
0 ignored issues
show
The method getUserByUsernameOrEmail() does not exist on null. ( Ignorable by Annotation )

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

737
        /** @scrutinizer ignore-call */ 
738
        $user = Craft::$app->users->getUserByUsernameOrEmail($userProfile->email);

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
738
739
        if ($user) {
740
            return $user;
741
        }
742
        $settings = Socializer::$app->settings->getSettings();
743
744
        if (!$settings->enableUserSignUp){
745
            return null;
746
        }
747
748
        Craft::$app->requireEdition(Craft::Pro);
0 ignored issues
show
Deprecated Code introduced by
The constant Craft::Pro has been deprecated: in 5.0.0. [[\craft\enums\CmsEdition::Pro]] should be used instead. ( Ignorable by Annotation )

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

748
        Craft::$app->requireEdition(/** @scrutinizer ignore-deprecated */ Craft::Pro);

This class constant has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the constant will be removed from the class and what other constant to use instead.

Loading history...
749
750
        $user = new User();
751
        $user->email = $userProfile->email;
752
        $user->username = $userProfile->email;
753
        $user->firstName = $userProfile->firstName;
754
        $user->lastName = $userProfile->lastName;
755
756
        // validate populate
757
        $user = $this->populateUserModel($user, $provider, $userProfile);
758
759
        $event = new BeforeRegisterUserEvent([
760
            'user' => $user,
761
            'provider' => $provider,
762
            'userProfile' => $userProfile,
763
        ]);
764
765
        $this->trigger(self::EVENT_BEFORE_REGISTER, $event);
766
        $user = $event->user;
767
768
        if (!$event->isValid) {
769
            return null;
770
        }
771
772
        if (!Craft::$app->elements->saveElement($user)){
773
            Craft::error("Unable to create user: ".json_encode($user->getErrors()));
774
            throw new \Exception("Something went wrong while creating the user");
775
        }
776
777
        Craft::$app->users->activateUser($user);
778
779
        if ($settings->userGroupId){
780
            $userGroup = Craft::$app->getUserGroups()->getGroupById($settings->userGroupId);
781
            if ($userGroup){
782
                Craft::$app->getUsers()->assignUserToGroups($user->id, [$userGroup->id]);
783
            }
784
        }
785
786
        $this->triggerAfterRegisterEvent($user, $provider, $userProfile);
787
788
        return $user;
789
    }
790
791
    private function triggerAfterRegisterEvent($user, $provider, $userProfile)
792
    {
793
        $event = new AfterRegisterUserEvent([
794
            'user' => $user,
795
            'provider' => $provider,
796
            'userProfile' => $userProfile,
797
        ]);
798
799
        $this->trigger(self::EVENT_AFTER_REGISTER, $event);
800
    }
801
802
    /**
803
     * @param User $user
804
     * @param Provider $provider
805
     * @param Profile $profile
806
     * @return User
807
     */
808
    public function populateUserModel(User $user, Provider $provider, Profile $profile)
809
    {
810
        $settings = Socializer::$app->settings->getSettings();
811
812
        if (!$settings->enableFieldMapping) {
813
            return $user;
814
        }
815
816
        $fieldMapping = Socializer::$app->settings->getGlobalFieldMapping();
817
818
        if ($settings->enableFieldMappingPerProvider) {
819
            $fieldMapping = $provider->fieldMapping ?? $fieldMapping;
820
        }
821
822
        foreach ($fieldMapping as $item) {
823
            if(isset($item['targetUserField']) && $item['targetUserField']){
824
                $profileValue = $profile->{$item['sourceFormField']};
825
                $field = $user->getFieldLayout()->getFieldByHandle($item['targetUserField']);
826
                if ($field){
827
                    $user->setFieldValue($item['targetUserField'], $profileValue);
828
                }
829
            }
830
        }
831
832
        return $user;
833
    }
834
835
836
    /**
837
     * @param $provider Provider
838
     *
839
     * @return bool
840
     * @throws Exception
841
     * @throws \Throwable
842
     */
843
    public function saveProvider(Provider $provider)
844
    {
845
        if ($provider->id) {
846
            $providerRecord = ProviderRecord::findOne($provider->id);
847
848
            if (!$providerRecord) {
0 ignored issues
show
$providerRecord is of type yii\db\ActiveRecord, thus it always evaluated to true.
Loading history...
849
                throw new Exception(Craft::t("enupal-socializer",'No Provider exists with the ID “{id}”', ['id' => $provider->id]));
850
            }
851
        }
852
853
        if (!$provider->validate()) {
854
            return false;
855
        }
856
857
        $transaction = Craft::$app->db->beginTransaction();
858
859
        try {
860
            // Set the field context
861
            Craft::$app->getFields()->fieldContext = $provider->getFieldContext();
862
863
            if (Craft::$app->elements->saveElement($provider)) {
864
                $transaction->commit();
865
            }
866
        } catch (\Exception $e) {
867
            $transaction->rollback();
868
869
            throw $e;
870
        }
871
872
        return true;
873
    }
874
875
    /**
876
     * @param Provider $provider
877
     *
878
     * @return Provider
879
     */
880
    public function populateProviderFromPost(Provider $provider)
881
    {
882
        $request = Craft::$app->getRequest();
883
884
        $postFields = $request->getBodyParam('fields');
885
886
        $provider->setAttributes(/** @scrutinizer ignore-type */
887
            $postFields, false);
888
889
        return $provider;
890
    }
891
}