Completed
Pull Request — master (#114)
by Bart
04:26
created

FieldLayoutBehavior::getFieldLayout()   B

Complexity

Conditions 4
Paths 3

Size

Total Lines 22
Code Lines 15

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 22
rs 8.9197
c 0
b 0
f 0
cc 4
eloc 15
nc 3
nop 1
1
<?php
2
3
namespace NerdsAndCompany\Schematic\Behaviors;
4
5
use Craft;
6
use yii\base\Behavior;
7
use craft\base\Field;
8
use craft\models\FieldLayout;
9
use craft\elements\Entry;
10
11
/**
12
 * Schematic FieldLayout Behavior.
13
 *
14
 * Sync Craft Setups.
15
 *
16
 * @author    Nerds & Company
17
 * @copyright Copyright (c) 2015-2018, Nerds & Company
18
 * @license   MIT
19
 *
20
 * @see      http://www.nerds.company
21
 */
22
class FieldLayoutBehavior extends Behavior
23
{
24
    /**
25
     * Get field layout definition.
26
     *
27
     * @param FieldLayout $fieldLayout
28
     *
29
     * @return array
30
     */
31
    public function getFieldLayoutDefinition(FieldLayout $fieldLayout): array
32
    {
33
        if ($fieldLayout->getTabs()) {
34
            $tabDefinitions = [];
35
36
            foreach ($fieldLayout->getTabs() as $tab) {
37
                $tabDefinitions[$tab->name] = $this->getFieldLayoutFieldsDefinition($tab->getFields());
0 ignored issues
show
Documentation introduced by
$tab->getFields() is of type array<integer,object<craft\base\FieldInterface>>, but the function expects a array<integer,object<craft\base\Field>>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
38
            }
39
40
            return ['tabs' => $tabDefinitions];
41
        }
42
43
        return ['fields' => $this->getFieldLayoutFieldsDefinition($fieldLayout->getFields())];
0 ignored issues
show
Documentation introduced by
$fieldLayout->getFields() is of type array<integer,object<craft\base\FieldInterface>>, but the function expects a array<integer,object<craft\base\Field>>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
44
    }
45
46
    /**
47
     * Get field layout fields definition.
48
     *
49
     * @param Field[] $fields
50
     *
51
     * @return array
52
     */
53
    private function getFieldLayoutFieldsDefinition(array $fields): array
54
    {
55
        $fieldDefinitions = [];
56
57
        foreach ($fields as $field) {
58
            $fieldDefinitions[$field->handle] = $field->required;
59
        }
60
61
        return $fieldDefinitions;
62
    }
63
64
    /**
65
     * Attempt to import a field layout.
66
     *
67
     * @param array $fieldLayoutDef
68
     *
69
     * @return FieldLayout
70
     */
71
    public function getFieldLayout(array $fieldLayoutDef): FieldLayout
72
    {
73
        $layoutFields = [];
74
        $requiredFields = [];
75
76
        if (array_key_exists('tabs', $fieldLayoutDef)) {
77
            foreach ($fieldLayoutDef['tabs'] as $tabName => $tabDef) {
78
                $layoutTabFields = $this->getPrepareFieldLayout($tabDef);
79
                $requiredFields = array_merge($requiredFields, $layoutTabFields['required']);
80
                $layoutFields[$tabName] = $layoutTabFields['fields'];
81
            }
82
        } elseif (array_key_exists('fields', $fieldLayoutDef)) {
83
            $layoutTabFields = $this->getPrepareFieldLayout($fieldLayoutDef);
84
            $requiredFields = $layoutTabFields['required'];
85
            $layoutFields = $layoutTabFields['fields'];
86
        }
87
88
        $fieldLayout = Craft::$app->fields->assembleLayout($layoutFields, $requiredFields);
89
        $fieldLayout->type = Entry::class;
90
91
        return $fieldLayout;
92
    }
93
94
    /**
95
     * Get a prepared fieldLayout for the craft assembleLayout function.
96
     *
97
     * @param array $fieldLayoutDef
98
     *
99
     * @return array
100
     */
101
    private function getPrepareFieldLayout(array $fieldLayoutDef): array
102
    {
103
        $layoutFields = [];
104
        $requiredFields = [];
105
106
        foreach ($fieldLayoutDef as $fieldHandle => $required) {
107
            $field = Craft::$app->fields->getFieldByHandle($fieldHandle);
108
            if ($field instanceof Field) {
109
                $layoutFields[] = $field->id;
110
111
                if ($required) {
112
                    $requiredFields[] = $field->id;
113
                }
114
            }
115
        }
116
117
        return [
118
          'fields' => $layoutFields,
119
          'required' => $requiredFields,
120
        ];
121
    }
122
}
123