Completed
Pull Request — master (#114)
by Bart
09:33 queued 07:46
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
namespace NerdsAndCompany\Schematic\Behaviors;
3
4
use Craft;
5
use yii\base\Behavior;
6
use craft\base\Field;
7
use craft\models\FieldLayout;
8
use craft\elements\Entry;
9
10
/**
11
 * Schematic FieldLayout Behavior.
12
 *
13
 * Sync Craft Setups.
14
 *
15
 * @author    Nerds & Company
16
 * @copyright Copyright (c) 2015-2018, Nerds & Company
17
 * @license   MIT
18
 *
19
 * @see      http://www.nerds.company
20
 */
21
class FieldLayoutBehavior extends Behavior
22
{
23
    /**
24
     * Get field layout definition.
25
     *
26
     * @param FieldLayout $fieldLayout
27
     *
28
     * @return array
29
     */
30
    public function getFieldLayoutDefinition(FieldLayout $fieldLayout)
31
    {
32
        if ($fieldLayout->getTabs()) {
33
            $tabDefinitions = [];
34
35
            foreach ($fieldLayout->getTabs() as $tab) {
36
                $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...
37
            }
38
39
            return ['tabs' => $tabDefinitions];
40
        }
41
42
        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...
43
    }
44
45
    /**
46
     * Get field layout fields definition.
47
     *
48
     * @param Field[] $fields
49
     *
50
     * @return array
51
     */
52
    private function getFieldLayoutFieldsDefinition(array $fields)
53
    {
54
        $fieldDefinitions = [];
55
56
        foreach ($fields as $field) {
57
            $fieldDefinitions[$field->handle] = $field->required;
58
        }
59
60
        return $fieldDefinitions;
61
    }
62
63
    /**
64
     * Attempt to import a field layout.
65
     *
66
     * @param array $fieldLayoutDef
67
     *
68
     * @return FieldLayout
69
     */
70
    public function getFieldLayout(array $fieldLayoutDef)
71
    {
72
        $layoutFields = [];
73
        $requiredFields = [];
74
75
        if (array_key_exists('tabs', $fieldLayoutDef)) {
76
            foreach ($fieldLayoutDef['tabs'] as $tabName => $tabDef) {
77
                $layoutTabFields = $this->getPrepareFieldLayout($tabDef);
78
                $requiredFields = array_merge($requiredFields, $layoutTabFields['required']);
79
                $layoutFields[$tabName] = $layoutTabFields['fields'];
80
            }
81
        } elseif (array_key_exists('fields', $fieldLayoutDef)) {
82
            $layoutTabFields = $this->getPrepareFieldLayout($fieldLayoutDef);
83
            $requiredFields = $layoutTabFields['required'];
84
            $layoutFields = $layoutTabFields['fields'];
85
        }
86
87
        $fieldLayout = Craft::$app->fields->assembleLayout($layoutFields, $requiredFields);
88
        $fieldLayout->type = Entry::class;
89
90
        return $fieldLayout;
91
    }
92
93
    /**
94
     * Get a prepared fieldLayout for the craft assembleLayout function.
95
     *
96
     * @param array $fieldLayoutDef
97
     *
98
     * @return array
99
     */
100
    private function getPrepareFieldLayout(array $fieldLayoutDef)
101
    {
102
        $layoutFields = [];
103
        $requiredFields = [];
104
105
        foreach ($fieldLayoutDef as $fieldHandle => $required) {
106
            $field = Craft::$app->fields->getFieldByHandle($fieldHandle);
107
            if ($field instanceof Field) {
108
                $layoutFields[] = $field->id;
109
110
                if ($required) {
111
                    $requiredFields[] = $field->id;
112
                }
113
            }
114
        }
115
116
        return [
117
          'fields' => $layoutFields,
118
          'required' => $requiredFields,
119
        ];
120
    }
121
}
122