Issues (45)

src/elements/Provider.php (7 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\elements;
10
11
use Craft;
12
use craft\base\Element;
13
use craft\behaviors\FieldLayoutBehavior;
14
use craft\elements\actions\Restore;
15
use craft\elements\db\ElementQueryInterface;
16
use craft\elements\User;
17
use craft\helpers\UrlHelper;
18
19
use enupal\socializer\elements\actions\Delete;
0 ignored issues
show
The type enupal\socializer\elements\actions\Delete 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...
20
use enupal\socializer\records\Provider as ProviderRecord;
21
use craft\validators\UniqueValidator;
22
use enupal\socializer\elements\db\ProvidersQuery;
23
use enupal\socializer\Socializer;
24
use enupal\socializer\validators\EnabledValidator;
25
use Hybridauth\Adapter\AdapterInterface;
26
use Hybridauth\Provider\Apple;
27
use yii\base\Model;
28
29
/**
30
 * Provider represents a provider element.
31
 *
32
 */
33
class Provider extends Element
34
{
35
    /**
36
     * @var string Name.
37
     */
38
    public $name;
39
40
    /**
41
     * @var string Handle.
42
     */
43
    public $handle;
44
45
    /**
46
     * @var string Type.
47
     */
48
    public $type;
49
50
    /**
51
     * @var string Client ID.
52
     */
53
    public $clientId;
54
55
    /**
56
     * @var string Client Secret.
57
     */
58
    public $clientSecret;
59
60
    /**
61
     * @var string Field Mapping
62
     */
63
    public $fieldMapping;
64
65
    /**
66
     * @inheritdoc
67
     */
68
    public function canView(User $user): bool
69
    {
70
        return true;
71
    }
72
73
    /**
74
     * @inheritdoc
75
     */
76
    public function canDelete(User $user): bool
77
    {
78
        return true;
79
    }
80
81
    /**
82
     * @inheritdoc
83
     */
84
    public function behaviors(): array
85
    {
86
        return array_merge(parent::behaviors(), [
87
            'fieldLayout' => [
88
                'class' => FieldLayoutBehavior::class,
89
                'elementType' => self::class
90
            ],
91
        ]);
92
    }
93
94
    public function init(): void
95
    {
96
        parent::init();
97
98
        $this->setScenario(Model::SCENARIO_DEFAULT);
99
100
        if ($this->fieldMapping && is_string($this->fieldMapping)) {
101
            $this->fieldMapping = json_decode($this->fieldMapping, true);
102
        }
103
    }
104
105
    /**
106
     * Returns the field context this element's content uses.
107
     *
108
     * @access protected
109
     * @return string
110
     */
111
    public function getFieldContext(): string
112
    {
113
        return 'enupalSocializer:' . $this->id;
114
    }
115
116
    /**
117
     * Returns the element type name.
118
     *
119
     * @return string
120
     */
121
    public static function displayName(): string
122
    {
123
        return Craft::t('enupal-socializer','Socializer');
124
    }
125
126
    /**
127
     * @inheritdoc
128
     */
129
    public static function refHandle(): ?string
130
    {
131
        return 'socializer-providers';
132
    }
133
134
    /**
135
     * @inheritdoc
136
     */
137
    public static function hasContent(): bool
138
    {
139
        return true;
140
    }
141
142
    /**
143
     * @inheritdoc
144
     */
145
    public static function hasTitles(): bool
146
    {
147
        return false;
148
    }
149
150
    /**
151
     * @inheritdoc
152
     */
153
    public static function isLocalized(): bool
154
    {
155
        return false;
156
    }
157
158
    /**
159
     * @inheritdoc
160
     */
161
    public static function hasStatuses(): bool
162
    {
163
        return true;
164
    }
165
166
    /**
167
     * @inheritdoc
168
     */
169
    public function getFieldLayout(): ?\craft\models\FieldLayout
170
    {
171
        $behaviors = $this->getBehaviors();
172
        $fieldLayout = $behaviors['fieldLayout'];
173
174
        return $fieldLayout->getFieldLayout();
175
    }
176
177
    /**
178
     * @inheritdoc
179
     */
180
    public function getCpEditUrl(): ?string
181
    {
182
        return UrlHelper::cpUrl(
183
            'enupal-socializer/providers/edit/' . $this->id
184
        );
185
    }
186
187
    /**
188
     * Use the name as the string representation.
189
     *
190
     * @return string
191
     */
192
    public function __toString(): string
193
    {
194
        return $this->name;
195
    }
196
197
    /**
198
     * @inheritdoc
199
     *
200
     * @return ProvidersQuery The newly created [[ProvidersQuery]] instance.
201
     */
202
    public static function find(): ElementQueryInterface
203
    {
204
        return new ProvidersQuery(get_called_class());
205
    }
206
207
    /**
208
     * @inheritdoc
209
     */
210
    protected static function defineSources(string $context = null): array
211
    {
212
        $sources = [
213
            [
214
                'key' => '*',
215
                'label' => Craft::t('enupal-socializer','All Providers'),
216
            ]
217
        ];
218
219
        // @todo add groups
220
221
        return $sources;
222
    }
223
224
    /**
225
     * @inheritdoc
226
     */
227
    protected static function defineActions(string $source = null): array
228
    {
229
        $actions = [];
230
231
        $actions[] = Craft::$app->getElements()->createAction([
232
            'type' => Restore::class,
233
            'successMessage' => 'Providers restored'
234
        ]);
235
236
        return $actions;
237
    }
238
239
    /**
240
     * @inheritdoc
241
     */
242
    protected static function defineSearchableAttributes(): array
243
    {
244
        return ['name', 'type'];
245
    }
246
247
    /**
248
     * @inheritdoc
249
     */
250
    protected static function defineSortOptions(): array
251
    {
252
        $attributes = [
253
            'elements.dateCreated' => Craft::t('enupal-socializer','Date Created'),
254
            'name' => Craft::t('enupal-socializer','Name')
255
        ];
256
257
        return $attributes;
258
    }
259
260
    /**
261
     * @inheritdoc
262
     */
263
    protected static function defineTableAttributes(): array
264
    {
265
        $attributes = [];
266
        $attributes['name'] = ['label' => Craft::t('enupal-socializer','Name')];
267
        $attributes['handle'] = ['label' => Craft::t('enupal-socializer','Handle')];
268
        $attributes['dateCreated'] = ['label' => Craft::t('enupal-socializer','Date Created')];
269
270
        return $attributes;
271
    }
272
273
    /**
274
     * @inheritdoc
275
     */
276
    protected static function defineDefaultTableAttributes(string $source): array
277
    {
278
        $attributes = ['name', 'handle' , 'dateCreated'];
279
280
        return $attributes;
281
    }
282
283
    /**
284
     * @inheritdoc
285
     * @throws \yii\base\InvalidConfigException
286
     * @throws \yii\base\InvalidConfigException
287
     */
288
    protected function attributeHtml(string $attribute): string
289
    {
290
        switch ($attribute) {
291
            case 'dateCreated':
292
                {
293
                    return $this->dateCreated->/** @scrutinizer ignore-call */ format("Y-m-d H:i");
294
                }
295
        }
296
297
        return parent::attributeHtml($attribute);
298
    }
299
300
    /**
301
     * @inheritdoc
302
     */
303
    public function datetimeAttributes(): array
304
    {
305
        $attributes = parent::datetimeAttributes();
306
        $attributes[] = 'dateCreated';
307
        return $attributes;
308
    }
309
310
    /**
311
     * @inheritdoc
312
     * @param bool $isNew
313
     * @throws \Exception
314
     */
315
    public function afterSave(bool $isNew): void
316
    {
317
        $record = new ProviderRecord();
318
319
        if (!$isNew) {
320
            $record = ProviderRecord::findOne($this->id);
321
322
            if (!$record) {
0 ignored issues
show
$record is of type yii\db\ActiveRecord, thus it always evaluated to true.
Loading history...
323
                throw new \Exception('Invalid Provider ID: ' . $this->id);
324
            }
325
        } else {
326
            $record->id = $this->id;
327
        }
328
329
        $record->name = $this->name;
0 ignored issues
show
Bug Best Practice introduced by
The property name does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
330
        $record->type = $this->type;
331
        $record->handle = $this->handle;
332
333
        $record->clientId = $this->clientId;
334
        $record->clientSecret = $this->clientSecret;
335
        $record->fieldMapping = $this->fieldMapping;
336
337
        if (is_array($record->fieldMapping)){
0 ignored issues
show
The condition is_array($record->fieldMapping) is always false.
Loading history...
338
            $record->fieldMapping = json_encode($record->fieldMapping);
339
        };
340
341
        $record->save(false);
342
343
        parent::afterSave($isNew);
344
    }
345
346
    /**
347
     * @return AdapterInterface
348
     */
349
    public function getAdapter()
350
    {
351
        return new $this->type($this->getProviderConfig());
352
    }
353
354
    /**
355
     * @return array
356
     */
357
    private function getProviderConfig()
358
    {
359
        // @todo add event to give a chance to update default config
360
        $config = [
361
            'callback' => Socializer::$app->settings->getCallbackUrl(),
362
            'keys' => [
363
                'id' => $this->getClientId(),
364
                'secret' => $this->getClientSecret()
365
            ],
366
            'includeEmail' => true
367
        ];
368
369
        if ($this->type === Apple::class && Socializer::$app->settings->validateAppleSettings()) {
370
            $configSettings = Socializer::$app->settings->getConfigSettings();
371
372
            if (isset($configSettings['apple'])) {
373
                $config = $configSettings['apple'];
374
                $config['callback'] = Socializer::$app->settings->getCallbackUrl();
375
            }
376
        }
377
378
        return $config;
379
    }
380
381
    /**
382
     * @return string
383
     */
384
    public function getClientId()
385
    {
386
        return Craft::parseEnv($this->clientId);
0 ignored issues
show
Deprecated Code introduced by
The function Craft::parseEnv() has been deprecated: in 3.7.29. [[App::parseEnv()]] 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

386
        return /** @scrutinizer ignore-deprecated */ Craft::parseEnv($this->clientId);

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

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

Loading history...
387
    }
388
389
    /**
390
     * @return string
391
     */
392
    public function getClientSecret()
393
    {
394
        return Craft::parseEnv($this->clientSecret);
0 ignored issues
show
Deprecated Code introduced by
The function Craft::parseEnv() has been deprecated: in 3.7.29. [[App::parseEnv()]] 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

394
        return /** @scrutinizer ignore-deprecated */ Craft::parseEnv($this->clientSecret);

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

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

Loading history...
395
    }
396
397
    /**
398
     * @return array|null
399
     */
400
    public function getCurrentUserToken()
401
    {
402
        return Socializer::$app->tokens->getCurrentUserToken($this->id);
0 ignored issues
show
Bug Best Practice introduced by
The expression return enupal\socializer...entUserToken($this->id) also could return the type craft\base\ElementInterface which is incompatible with the documented return type array|null.
Loading history...
403
    }
404
405
    /**
406
     * @inheritdoc
407
     */
408
    public function rules(): array
409
    {
410
        $rules = parent::rules();
411
        $rules[] = [['name', 'type'], 'required'];
412
        $rules[] = [['name', 'type'], 'string', 'max' => 255];
413
        $rules[] = [['name', 'type'], UniqueValidator::class, 'targetClass' => ProviderRecord::class];
414
        $rules[] = [['name', 'type'], 'required'];
415
        $rules[] = [['clientId'], EnabledValidator::class];
416
417
        return $rules;
418
    }
419
420
    public function isAppleProvider()
421
    {
422
        return $this->type === Apple::class;
423
    }
424
}