Passed
Pull Request — master (#84)
by
unknown
03:18
created

FlexibleContentBuilder::endFlexibleContent()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 4
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 0
1
<?php
2
3
namespace StoutLogic\AcfBuilder;
4
5
use Doctrine\Common\Inflector\Inflector;
6
7
/**
8
 * Create a configuration array for an ACF Flexible Content field.
9
 * A flexible content field can have many different `layouts` which are
10
 * groups of fields.
11
 */
12
class FlexibleContentBuilder extends FieldBuilder
13
{
14
    /**
15
     * @var array
16
     */
17
    private $layouts = [];
18
19
    /**
20
     * @param string $name Field name
21
     * @param string $type Field name
22
     * @param array $config Field configuration
23
     */
24
    public function __construct($name, $type = 'flexible_content', $config = [])
25
    {
26
        parent::__construct($name, $type, $config);
27
28
        if (!isset($config['button_label'])) {
29
            $this->setConfig('button_label', $this->getDefaultButtonLabel());
30
        }
31
    }
32
33
    /**
34
     * Return a configuration array
35
     * @return array
36
     */
37
    public function build()
38
    {
39
        return array_merge(parent::build(), [
40
            'layouts' => $this->buildLayouts(),
41
        ]);
42
    }
43
44
    /**
45
     * Return a configuration array for each layout
46
     * @return array
47
     */
48
    private function buildLayouts()
49
    {
50
        return array_map(function ($layout) {
51
            $layout = ($layout instanceof Builder) ? $layout->build() : $layout;
52
            return $this->transformLayout($layout);
53
        }, $this->getLayouts());
54
    }
55
56
    /**
57
     * Apply transformations to a layout
58
     * @param  array $layout Layout configuration array
59
     * @return array Transformed layout configuration array
60
     */
61
    private function transformLayout($layout)
62
    {
63
        $layoutTransform = new Transform\FlexibleContentLayout($this);
64
        $namespaceTransform = new Transform\NamespaceFieldKey($this);
65
66
        return
67
            $namespaceTransform->transform(
68
                $layoutTransform->transform($layout)
69
            );
70
    }
71
72
    /**
73
     * Add a layout, which is a FieldsBuilder. `addLayout` can be chained to add
74
     * multiple layouts to the Flexible Content field.
75
     * @param string|FieldsBuilder $layout layout name.
76
     * Alternatively supply a FieldsBuilder to reuse existing fields. The name
77
     * will be inferred from the FieldsBuilder's name.
78
     * @param array $args filed configuration
79
     * @return FieldsBuilder
80
     */
81 View Code Duplication
    public function addLayout($layout, $args = [])
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
82
    {
83
        if ($layout instanceof FieldsBuilder) {
84
            $layout = clone $layout;
85
        } else {
86
            $layout = new FieldsBuilder($layout, $args);
87
        }
88
89
        $layout = $this->initializeLayout($layout, $args);
90
        $this->pushLayout($layout);
91
92
        return $layout;
93
    }
94
95
    /**
96
     * Add multiple layouts either via an array or from another builder
97
     * @param FieldsBuilder|array $layouts
98
     * @return $this
99
     */
100 View Code Duplication
    public function addLayouts($layouts)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
101
    {
102
        foreach ($layouts as $layout) {
0 ignored issues
show
Bug introduced by
The expression $layouts of type object<StoutLogic\AcfBuilder\FieldsBuilder>|array is not guaranteed to be traversable. How about adding an additional type check?

There are different options of fixing this problem.

  1. If you want to be on the safe side, you can add an additional type-check:

    $collection = json_decode($data, true);
    if ( ! is_array($collection)) {
        throw new \RuntimeException('$collection must be an array.');
    }
    
    foreach ($collection as $item) { /** ... */ }
    
  2. If you are sure that the expression is traversable, you might want to add a doc comment cast to improve IDE auto-completion and static analysis:

    /** @var array $collection */
    $collection = json_decode($data, true);
    
    foreach ($collection as $item) { /** .. */ }
    
  3. Mark the issue as a false-positive: Just hover the remove button, in the top-right corner of this issue for more options.

Loading history...
103
            if ($layout instanceof FieldsBuilder) {
104
                $layout = clone $layout;
105
            } else {
106
                $layout = new FieldsBuilder($layout);
107
            }
108
            $layout = $this->initializeLayout($layout);
109
            $this->pushLayout($layout);
110
        }
111
        return $this;
112
    }
113
114
    /**
115
     * Configures the layout FieldsBuilder
116
     * @param  FieldsBuilder $layout
117
     * @param  array         $args FieldGroup Configuration
118
     * @return FieldsBuilder Configured Layout
119
     */
120
    protected function initializeLayout(FieldsBuilder $layout, $args = [])
121
    {
122
        $layout->setGroupConfig('name', $layout->getName());
123
        $layout->setGroupConfig('display', 'block');
124
125
        foreach ($args as $key => $value) {
126
            $layout->setGroupConfig($key, $value);
127
        }
128
129
        $layout->setParentContext($this);
130
131
        return $layout;
132
    }
133
134
    /**
135
     * End the current Flexible Content field, return to parent context
136
     * @return Builder
137
     */
138
    public function endFlexibleContent()
139
    {
140
        return $this->getParentContext();
141
    }
142
143
    /**
144
     * Add layout to internal array
145
     * @param  FieldsBuilder $layout
146
     * @return void
147
     */
148
    protected function pushLayout($layout)
149
    {
150
        $this->layouts[] = $layout;
151
    }
152
153
    /**
154
     * @return FieldsBuilder[]
155
     */
156
    public function getLayouts()
157
    {
158
        return $this->layouts;
159
    }
160
161
    /**
162
     * Gerenates the default button label.
163
     * @return string
164
     */
165
    private function getDefaultButtonLabel()
166
    {
167
        return 'Add ' . Inflector::singularize($this->getLabel());
168
    }
169
}
170