Completed
Pull Request — master (#23)
by Steve
02:25
created

FlexibleContentBuilder::initializeLayout()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 13
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 13
rs 9.4285
cc 2
eloc 7
nc 2
nop 2
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
    public function addLayout($layout, $args = [])
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
     * Configures the layout FieldsBuilder
97
     * @param  FieldsBuilder $layout
98
     * @param  array         $args FieldGroup Configuration
99
     * @return FieldsBuilder Configured Layout
100
     */
101
    protected function initializeLayout(FieldsBuilder $layout, $args = [])
102
    {
103
        $layout->setGroupConfig('name', $layout->getName());
104
        $layout->setGroupConfig('display', 'block');
105
106
        foreach ($args as $key => $value) {
107
            $layout->setGroupConfig($key, $value);
108
        }
109
110
        $layout->setParentContext($this);
111
112
        return $layout;
113
    }
114
115
    /**
116
     * End the current Flexible Content field, return to parent context
117
     * @return Builder
118
     */
119
    public function endFlexibleContent()
120
    {
121
        return $this->getParentContext();
122
    }
123
124
    /**
125
     * Add layout to internal array
126
     * @param  FieldsBuilder $layout
127
     * @return void
128
     */
129
    protected function pushLayout($layout)
130
    {
131
        $this->layouts[] = $layout;
132
    }
133
134
    /**
135
     * @return FieldsBuilder[]
136
     */
137
    public function getLayouts()
138
    {
139
        return $this->layouts;
140
    }
141
142
    /**
143
     * Gerenates the default button label.
144
     * @return string
145
     */
146
    private function getDefaultButtonLabel()
147
    {
148
        return 'Add '.Inflector::singularize($this->getLabel());
149
    }
150
}
151