CheckExtraFieldAuthorsCompanyPlugin   F
last analyzed

Complexity

Total Complexity 66

Size/Duplication

Total Lines 547
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
wmc 66
eloc 233
dl 0
loc 547
rs 3.12
c 0
b 0
f 0

27 Methods

Rating   Name   Duplication   Size   Complexity  
A savePrice() 0 13 1
A saveAuthorsField() 0 15 1
A saveCompanyField() 0 16 2
A saveAuthorLPItem() 0 12 1
A uninstall() 0 20 6
A saveAuthorLp() 0 12 1
A __construct() 0 34 3
A install() 0 8 1
A create() 0 5 2
B setCompanyExtrafieldData() 0 28 7
A getPriceField() 0 11 2
A removeAuthorLpItemField() 0 3 1
A getAuthorLpField() 0 11 2
C deleteQuery() 0 41 12
A removeAuthorLpField() 0 3 1
A removePriceField() 0 3 1
A getCompanyField() 0 10 2
A getAuthorsField() 0 11 2
A removeAuthorsField() 0 3 1
A authorLpFieldExists() 0 6 2
A getInfoExtrafield() 0 14 4
A removeCompanyField() 0 3 1
A getAuthorLpItemField() 0 11 2
A priceFieldExists() 0 6 2
A authorLpItemFieldExists() 0 6 2
A companyFieldExists() 0 6 2
A authorsFieldExists() 0 6 2

How to fix   Complexity   

Complex Class

Complex classes like CheckExtraFieldAuthorsCompanyPlugin often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use CheckExtraFieldAuthorsCompanyPlugin, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
/* For licensing terms, see /license.txt */
4
5
class CheckExtraFieldAuthorsCompanyPlugin extends Plugin
6
{
7
    /**
8
     * @var string
9
     */
10
    protected $tblExtraFieldOption;
11
12
    /**
13
     * @var string
14
     */
15
    protected $tblExtraField;
16
17
    /**
18
     * @var bool
19
     */
20
    protected $companyExists;
21
22
    /**
23
     * @var bool
24
     */
25
    protected $authorsExists;
26
27
    /**
28
     * @var bool
29
     */
30
    protected $priceExists;
31
32
    /**
33
     * @var bool
34
     */
35
    protected $authorLpItemExists;
36
37
    /**
38
     * @var bool
39
     */
40
    protected $authorLpExists;
41
42
    /**
43
     * @var array
44
     */
45
    protected $companyField;
46
47
    /**
48
     * @var array
49
     */
50
    protected $authorsField;
51
52
    /**
53
     * @var array
54
     */
55
    protected $priceField;
56
57
    /**
58
     * @var array
59
     */
60
    protected $authorLpItemField;
61
62
    /**
63
     * @var array
64
     */
65
    protected $authorLpField;
66
67
    public function __construct()
68
    {
69
        parent::__construct(
70
            '1.2',
71
            'Carlos Alvarado, Julio Montoya'
72
        );
73
        $this->tblExtraField = Database::get_main_table(TABLE_EXTRA_FIELD);
74
        $this->tblExtraFieldOption = Database::get_main_table(TABLE_EXTRA_FIELD_OPTIONS);
75
        $field = new ExtraField('user');
76
        $companyField = $field->get_handler_field_info_by_field_variable('company');
77
        $this->companyExists = false;
78
        if (!empty($companyField)) {
79
            $this->companyExists = true;
80
            $this->companyField = $companyField;
0 ignored issues
show
Documentation Bug introduced by
It seems like $companyField can also be of type boolean. However, the property $companyField is declared as type array. Maybe add an additional type check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.

For example, imagine you have a variable $accountId that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to the id property of an instance of the Account class. This class holds a proper account, so the id value must no longer be false.

Either this assignment is in error or a type check should be added for that assignment.

class Id
{
    public $id;

    public function __construct($id)
    {
        $this->id = $id;
    }

}

class Account
{
    /** @var  Id $id */
    public $id;
}

$account_id = false;

if (starsAreRight()) {
    $account_id = new Id(42);
}

$account = new Account();
if ($account instanceof Id)
{
    $account->id = $account_id;
}
Loading history...
81
        } else {
82
            $this->companyField = [
83
                'field_type' => ExtraField::FIELD_TYPE_RADIO,
84
                'variable' => 'company',
85
                'display_text' => 'Company',
86
                'default_value' => '',
87
                'field_order' => 0,
88
                'visible_to_self' => 0,
89
                'visible_to_others' => 0,
90
                'changeable' => 1,
91
                'filter' => 1,
92
            ];
93
        }
94
        $field = new ExtraField('lp');
95
        $authorsField = $field->get_handler_field_info_by_field_variable('authors');
96
97
        $this->authorsExists = false;
98
        if (empty($authorsField)) {
99
            $this->authorsExists = true;
100
            $this->authorsField = $authorsField;
101
        }
102
    }
103
104
    /**
105
     * Create a new instance of CheckExtraFieldAuthorsCompanyPlugin.
106
     *
107
     * @return CheckExtraFieldAuthorsCompanyPlugin
108
     */
109
    public static function create()
110
    {
111
        static $result = null;
112
113
        return $result ? $result : $result = new self();
114
    }
115
116
    /**
117
     * Perform the plugin installation.
118
     */
119
    public function install()
120
    {
121
        $this->saveCompanyField();
122
        $this->setCompanyExtrafieldData();
123
        $this->saveAuthorsField();
124
        $this->savePrice();
125
        $this->saveAuthorLPItem();
126
        $this->saveAuthorLp();
127
    }
128
129
    /**
130
     * Save the arrangement for company, it is adjusted internally so that the values match the necessary ones.
131
     */
132
    public function saveCompanyField()
133
    {
134
        $data = $this->companyField;
135
        if (!empty($data)) {
136
            $data['field_type'] = (int) $data['field_type'];
137
            $data['field_order'] = (int) $data['field_order'];
138
            $data['visible_to_self'] = (int) $data['visible_to_self'];
139
            $data['visible_to_others'] = (int) $data['visible_to_others'];
140
            $data['changeable'] = (int) $data['changeable'];
141
            $data['filter'] = (int) $data['filter'];
142
            $data['default_value'] = '';
143
            $data['variable'] = 'company';
144
            $data['visible'] = 1;
145
            $data['display_text'] = strtolower(Database::escape_string($data['display_text']));
146
            $schedule = new ExtraField('user');
147
            $this->companyField['id'] = $schedule->save($data);
148
        }
149
    }
150
151
    /**
152
     * Insert the option fields for company with the generic values Company 1, company 2 and company 3.
153
     */
154
    public function setCompanyExtrafieldData()
155
    {
156
        $companies = [
157
            0 => 'Company 1',
158
            1 => 'Company 2',
159
            2 => 'Company 3',
160
        ];
161
        $companyId = (int) $this->companyField['id'];
162
        if ($companyId != 0) {
163
            for ($i = 0; $i < count($companies); $i++) {
0 ignored issues
show
Performance Best Practice introduced by
It seems like you are calling the size function count() as part of the test condition. You might want to compute the size beforehand, and not on each iteration.

If the size of the collection does not change during the iteration, it is generally a good practice to compute it beforehand, and not on each iteration:

for ($i=0; $i<count($array); $i++) { // calls count() on each iteration
}

// Better
for ($i=0, $c=count($array); $i<$c; $i++) { // calls count() just once
}
Loading history...
164
                $order = $i + 1;
165
                $extraFieldOptionValue = $companies[$i];
166
                if ($companyId != null) {
167
                    $query = "SELECT *
168
                              FROM ".$this->tblExtraFieldOption."
169
                              WHERE
170
                                    option_value = '$extraFieldOptionValue' AND
171
                                    field_id = $companyId";
172
                    $extraFieldOption = Database::fetch_assoc(Database::query($query));
173
                    if (isset($extraFieldOption['id']) && $extraFieldOption['id'] && $extraFieldOption['field_id'] == $companyId) {
174
                        // Update?
175
                    } else {
176
                        $query = "
177
                        INSERT INTO ".$this->tblExtraFieldOption."
178
                            (`field_id`, `option_value`, `display_text`, `priority`, `priority_message`, `option_order`) VALUES
179
                            ( '$companyId', '$extraFieldOptionValue', '$extraFieldOptionValue', NULL, NULL, '$order');
180
                        ";
181
                        Database::query($query);
182
                    }
183
                }
184
            }
185
        }
186
    }
187
188
    /**
189
     * Save the arrangement for authors, it is adjusted internally so that the values match the necessary ones.
190
     */
191
    public function saveAuthorsField()
192
    {
193
        $data = [
194
            'field_type' => ExtraField::FIELD_TYPE_SELECT_MULTIPLE,
195
            'variable' => 'authors',
196
            'display_text' => 'Authors',
197
            'default_value' => '',
198
            'field_order' => 0,
199
            'visible_to_self' => 1,
200
            'visible_to_others' => 0,
201
            'changeable' => 1,
202
            'filter' => 1,
203
        ];
204
        $schedule = new ExtraField('lp');
205
        $schedule->save($data);
206
    }
207
208
    /**
209
     * Save the arrangement for price, it is adjusted internally so that the values match the necessary ones.
210
     */
211
    public function savePrice()
212
    {
213
        $schedule = new ExtraField('lp_item');
214
        $data = [];
215
        $data['visible_to_self'] = 1;
216
        $data['visible_to_others'] = 1;
217
        $data['changeable'] = 1;
218
        $data['filter'] = 0;
219
        $data['variable'] = 'price';
220
        $data['display_text'] = 'SalePrice';
221
        $data['field_type'] = ExtraField::FIELD_TYPE_INTEGER;
222
223
        $schedule->save($data);
224
    }
225
226
    /**
227
     * Save the arrangement for AuthorLPItem, it is adjusted internally so that the values match the necessary ones.
228
     */
229
    public function saveAuthorLPItem()
230
    {
231
        $schedule = new ExtraField('lp_item');
232
        $data = [];
233
        $data['visible_to_self'] = 1;
234
        $data['visible_to_others'] = 0;
235
        $data['changeable'] = 1;
236
        $data['filter'] = 0;
237
        $data['variable'] = 'authorlpitem';
238
        $data['display_text'] = 'LearningPathItemByAuthor';
239
        $data['field_type'] = ExtraField::FIELD_TYPE_SELECT_MULTIPLE;
240
        $schedule->save($data);
241
    }
242
243
    /**
244
     * Save the arrangement for authorlp, it is adjusted internally so that the values match the necessary ones.
245
     */
246
    public function saveAuthorLp()
247
    {
248
        $schedule = new ExtraField('user');
249
        $data = [];
250
        $data['variable'] = 'authorlp';
251
        $data['display_text'] = 'authors';
252
        $data['changeable'] = 1;
253
        $data['visible_to_self'] = 1;
254
        $data['visible_to_others'] = 0;
255
        $data['filter'] = 0;
256
        $data['field_type'] = ExtraField::FIELD_TYPE_CHECKBOX;
257
        $schedule->save($data);
258
    }
259
260
    /**
261
     * Remove the extra fields set by the plugin.
262
     */
263
    public function uninstall()
264
    {
265
        $companyExists = $this->companyFieldExists();
266
        if ($companyExists == true) {
0 ignored issues
show
Coding Style Best Practice introduced by
It seems like you are loosely comparing two booleans. Considering using the strict comparison === instead.

When comparing two booleans, it is generally considered safer to use the strict comparison operator.

Loading history...
267
            // $this->removeCompanyField();
268
        }
269
        $authorsExists = $this->authorsFieldExists();
270
        if ($authorsExists == true) {
0 ignored issues
show
Coding Style Best Practice introduced by
It seems like you are loosely comparing two booleans. Considering using the strict comparison === instead.

When comparing two booleans, it is generally considered safer to use the strict comparison operator.

Loading history...
271
            // $this->removeAuthorsField();
272
        }
273
        $priceExists = $this->priceFieldExists();
274
        if ($priceExists == true) {
0 ignored issues
show
Coding Style Best Practice introduced by
It seems like you are loosely comparing two booleans. Considering using the strict comparison === instead.

When comparing two booleans, it is generally considered safer to use the strict comparison operator.

Loading history...
275
            // $this->>removePriceField();
276
        }
277
        $authorLpItemExists = $this->authorLpItemFieldExists();
278
        if ($authorLpItemExists == true) {
0 ignored issues
show
Coding Style Best Practice introduced by
It seems like you are loosely comparing two booleans. Considering using the strict comparison === instead.

When comparing two booleans, it is generally considered safer to use the strict comparison operator.

Loading history...
279
            // $this->removeAuthorLpItemField();
280
        }
281
        $authorLpExists = $this->authorLpFieldExists();
282
        if ($authorLpExists == true) {
0 ignored issues
show
Coding Style Best Practice introduced by
It seems like you are loosely comparing two booleans. Considering using the strict comparison === instead.

When comparing two booleans, it is generally considered safer to use the strict comparison operator.

Loading history...
283
            // $this->removeAuthorLpField();
284
        }
285
    }
286
287
    /**
288
     * Verify that the "company" field exists in the database.
289
     */
290
    public function companyFieldExists(): bool
291
    {
292
        $this->getCompanyField();
293
        $this->companyExists = (isset($this->companyField['id'])) ? true : false;
294
295
        return $this->companyExists;
296
    }
297
298
    /**
299
     * Returns the content of the extra field "company" if it exists in the database, if not, it returns an arrangement
300
     * with the basic elements for its operation.
301
     *
302
     * @return array
303
     */
304
    public function getCompanyField()
305
    {
306
        $companyField = $this->getInfoExtrafield('company');
307
        if (count($companyField) > 1) {
308
            $this->companyField = $companyField;
309
        } else {
310
            $companyField = $this->companyField;
311
        }
312
313
        return $companyField;
314
    }
315
316
    /**
317
     * Verify that the "authors" field exists in the database.
318
     */
319
    public function authorsFieldExists(): bool
320
    {
321
        $this->getAuthorsField();
322
        $this->authorsExists = (isset($this->authorsField['id'])) ? true : false;
323
324
        return $this->authorsExists;
325
    }
326
327
    /**
328
     * Returns the content of the extra field "authors" if it exists in the database, if not, it returns an arrangement
329
     * with the basic elements for its operation.
330
     *
331
     * @return array
332
     */
333
    public function getAuthorsField()
334
    {
335
        $schedule = new ExtraField('lp');
336
        $data = $schedule->get_handler_field_info_by_field_variable('authors');
337
        if (empty($data)) {
338
            $this->authorsField = $data;
339
        } else {
340
            $data = $this->authorsField;
341
        }
342
343
        return $data;
344
    }
345
346
    /**
347
     * Verify that the "price" field exists in the database.
348
     */
349
    public function priceFieldExists(): bool
350
    {
351
        $this->getPriceField();
352
        $this->priceExists = (isset($this->priceField['id'])) ? true : false;
353
354
        return $this->priceExists;
355
    }
356
357
    /**
358
     * Returns the content of the extra field "price" if it exists in the database, if not, it returns an arrangement
359
     * with the basic elements for its operation.
360
     *
361
     * @return array
362
     */
363
    public function getPriceField()
364
    {
365
        $schedule = new ExtraField('lp_item');
366
        $data = $schedule->get_handler_field_info_by_field_variable('price');
367
        if (empty($data)) {
368
            $this->priceField = $data;
369
        } else {
370
            $data = $this->priceField;
371
        }
372
373
        return $data;
374
    }
375
376
    /**
377
     * Verify that the "authorlpitem" field exists in the database.
378
     */
379
    public function authorLpItemFieldExists(): bool
380
    {
381
        $this->getAuthorLpItemField();
382
        $this->authorLpItemExists = (isset($this->authorLpItemField['id'])) ? true : false;
383
384
        return $this->authorLpItemExists;
385
    }
386
387
    /**
388
     * Returns the content of the extra field "authorlpitem" if it exists in the database, if not, it returns an arrangement
389
     * with the basic elements for its operation.
390
     *
391
     * @return array
392
     */
393
    public function getAuthorLpItemField()
394
    {
395
        $schedule = new ExtraField('lp_item');
396
        $data = $schedule->get_handler_field_info_by_field_variable('authorlpitem');
397
        if (empty($data)) {
398
            $this->authorLpItemField = $data;
399
        } else {
400
            $data = $this->authorLpItemField;
401
        }
402
403
        return $data;
404
    }
405
406
    /**
407
     * Verify that the "authorlp" field exists in the database.
408
     */
409
    public function authorLpFieldExists(): bool
410
    {
411
        $this->getAuthorLpField();
412
        $this->authorLpExists = (isset($this->authorLpField['id'])) ? true : false;
413
414
        return $this->authorLpExists;
415
    }
416
417
    /**
418
     * Returns the content of the extra field "authorlp" if it exists in the database, if not, it returns an arrangement
419
     * with the basic elements for its operation.
420
     *
421
     * @return array
422
     */
423
    public function getAuthorLpField()
424
    {
425
        $field = new ExtraField('user');
426
        $data = $field->get_handler_field_info_by_field_variable('authorlp');
427
        if (empty($data)) {
428
            $this->authorLpField = $data;
429
        } else {
430
            $data = $this->authorLpField;
431
        }
432
433
        return $data;
434
    }
435
436
    /**
437
     * Remove the extra fields "company".
438
     */
439
    public function removeCompanyField()
440
    {
441
        $data = $this->getCompanyField();
442
        // $this->deleteQuery($data);
443
    }
444
445
    /**
446
     * Remove the extra fields "authors".
447
     */
448
    public function removeAuthorsField()
449
    {
450
        $data = $this->getAuthorsField();
451
        // $this->deleteQuery($data);
452
    }
453
454
    /**
455
     * Remove the extra fields "price".
456
     */
457
    public function removePriceField()
458
    {
459
        $data = $this->getPriceField();
460
        // $this->deleteQuery($data);
461
    }
462
463
    /**
464
     * Remove the extra fields "authorlpitem".
465
     */
466
    public function removeAuthorLpItemField()
467
    {
468
        $data = $this->getAuthorLpItemField();
469
        // $this->deleteQuery($data);
470
    }
471
472
    /**
473
     * Remove the extra fields "authorlp".
474
     */
475
    public function removeAuthorLpField()
476
    {
477
        $data = $this->getAuthorLpField();
478
        // $this->deleteQuery($data);
479
    }
480
481
    /**
482
     * Executes fix removal for authors or company.
483
     *
484
     * @param $data
485
     */
486
    protected function deleteQuery($data)
487
    {
488
        $validVariable = false;
489
        $variable = $data['variable'];
490
        $extraFieldTypeInt = (int) $data['extra_field_type'];
491
        $FieldType = (int) $data['field_type'];
492
        $id = (int) $data['id'];
493
        $extraFieldType = null;
494
        switch ($variable) {
495
            case 'company':
496
            case 'authorlp':
497
                $validVariable = true;
498
                $extraFieldType = 'user';
499
                break;
500
            case 'authors':
501
                $validVariable = true;
502
                $extraFieldType = 'lp';
503
                break;
504
            case 'price':
505
            case 'authorlpitem':
506
                $validVariable = true;
507
                $extraFieldType = 'lp_item';
508
                break;
509
        }
510
        if ($variable === 'company') {
511
        } elseif ($variable === 'authors') {
512
        }
513
        if ($validVariable == true && $id != 0 && !empty($extraFieldType)) {
0 ignored issues
show
Coding Style Best Practice introduced by
It seems like you are loosely comparing two booleans. Considering using the strict comparison === instead.

When comparing two booleans, it is generally considered safer to use the strict comparison operator.

Loading history...
514
            $query = "SELECT id
515
                        FROM
516
                            ".$this->tblExtraField."
517
                        WHERE
518
                            id = $id AND
519
                            variable = '$variable' AND
520
                            extra_field_type = $extraFieldTypeInt AND
521
                            field_type = $FieldType
522
                        ";
523
            $data = Database::fetch_assoc(Database::query($query));
524
            if (isset($data['id'])) {
525
                $obj = new ExtraField($extraFieldType);
526
                $obj->delete($data['id']);
527
            }
528
        }
529
    }
530
531
    /**
532
     * Returns the array of an element in the database that matches the variable.
533
     *
534
     * @param string $variableName
535
     *
536
     * @return array
537
     */
538
    protected function getInfoExtrafield($variableName = null)
539
    {
540
        if ($variableName == null) {
0 ignored issues
show
Bug introduced by
It seems like you are loosely comparing $variableName of type null|string against null; this is ambiguous if the string can be empty. Consider using a strict comparison === instead.
Loading history...
541
            return [];
542
        }
543
        $variableName = strtolower(Database::escape_string($variableName));
544
        $tblExtraField = $this->tblExtraField;
545
        $query = "SELECT * FROM $tblExtraField WHERE variable = '$variableName'";
546
        $data = Database::fetch_assoc(Database::query($query));
547
        if ($data == false || !isset($data['display_text'])) {
548
            return [];
549
        }
550
551
        return $data;
552
    }
553
}
554