Issues (368)

src/Admin/Constructor/ConstructorLayout.php (5 issues)

1
<?php
2
3
namespace Arbory\Base\Admin\Constructor;
4
5
use Arbory\Base\Html\Html;
6
use Arbory\Base\Admin\Form;
7
use Arbory\Base\Admin\Layout\Grid;
8
use Arbory\Base\Admin\Panels\Panel;
9
use Arbory\Base\Admin\Widgets\Link;
10
use Arbory\Base\Html\Elements\Content;
11
use Arbory\Base\Admin\Layout\GridLayout;
12
use Arbory\Base\Admin\Layout\LazyRenderer;
13
use Arbory\Base\Services\FieldTypeRegistry;
14
use Arbory\Base\Admin\Layout\AbstractLayout;
15
use Arbory\Base\Admin\Layout\FormLayoutInterface;
16
use Arbory\Base\Admin\Layout\Transformers\AppendTransformer;
17
18
class ConstructorLayout extends AbstractLayout implements FormLayoutInterface
19
{
20
    /**
21
     * @var string
22
     */
23
    protected $modalUrl;
24
25
    /**
26
     * @var Form
27
     */
28
    protected $form;
29
30
    /**
31
     * @var Form\Fields\Constructor
32
     */
33
    protected $field;
34
35
    /**
36
     * @var string
37
     */
38
    protected $name;
39
40
    /**
41
     * @var callable
42
     */
43
    protected $fieldConfigurator;
44
45
    /**
46
     * ConstructorLayout constructor.
47
     *
48
     * @param  string  $name
49
     */
50
    public function __construct($name = 'blocks')
51
    {
52
        $this->name = $name;
53
        $this->fieldConfigurator = function () {
54
            $this->field->setItemRenderer(new Form\Fields\Renderer\Nested\PaneledItemRenderer);
55
            $this->field->addClass('in-layout');
56
            $this->field->sortable($this->getFieldOrderBy());
57
58
            $this->field->setHidden(true);
59
            $this->field->setLabel('');
60
            $this->field->setAllowToAdd(false);
61
        };
62
    }
63
64
    /**
65
     * @return string
66
     */
67
    protected function getFieldOrderBy(): string
68
    {
69
        return $this->field->getOrderBy() ?? 'position';
70
    }
71
72
    /**
73
     * @return Form
74
     */
75
    public function getForm(): Form
76
    {
77
        return $this->form;
78
    }
79
80
    /**
81
     * @param  Form  $form
82
     * @return FormLayoutInterface
83
     */
84
    public function setForm(Form $form): FormLayoutInterface
85
    {
86
        $this->form = $form;
87
88
        return $this;
89
    }
90
91
    /**
92
     * Executes every time before render.
93
     *
94
     * @return mixed
95
     */
96
    public function build()
97
    {
98
        $gridLayout = new GridLayout(new Grid());
99
        $gridLayout->setWidth(9);
100
        $gridLayout->addColumn(3, new LazyRenderer([$this, 'overview']));
101
        $gridLayout->use(new AppendTransformer(new LazyRenderer([$this, 'renderField'])));
0 ignored issues
show
new Arbory\Base\Admin\La...$this, 'renderField'))) of type Arbory\Base\Admin\Layout...rmers\AppendTransformer is incompatible with the type Arbory\Base\Admin\Layout\LayoutInterface|string expected by parameter $layout of Arbory\Base\Admin\Layout\AbstractLayout::use(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

101
        $gridLayout->use(/** @scrutinizer ignore-type */ new AppendTransformer(new LazyRenderer([$this, 'renderField'])));
Loading history...
new Arbory\Base\Admin\La...($this, 'renderField')) of type Arbory\Base\Admin\Layout\LazyRenderer is incompatible with the type Closure|string expected by parameter $content of Arbory\Base\Admin\Layout...nsformer::__construct(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

101
        $gridLayout->use(new AppendTransformer(/** @scrutinizer ignore-type */ new LazyRenderer([$this, 'renderField'])));
Loading history...
102
103
        $this->use($gridLayout);
104
    }
105
106
    /**
107
     * @param  mixed  $content
108
     * @return mixed
109
     */
110
    public function contents($content)
111
    {
112
        return $content;
113
    }
114
115
    /**
116
     * @return Form\Fields\Constructor
117
     */
118
    public function getField(): Form\Fields\Constructor
119
    {
120
        if ($this->field === null) {
121
            $field = $this->form->fields()->findFieldByInputName($this->name);
122
123
            if ($field === null) {
124
                throw new \RuntimeException('Constructor field must be present in constructor layout');
125
            }
126
127
            if ($field) {
0 ignored issues
show
$field is of type Arbory\Base\Admin\Form\Fields\AbstractField, thus it always evaluated to true.
Loading history...
128
                $this->field = $field;
129
            } else {
130
                /**
131
                 * @var FieldTypeRegistry
132
                 */
133
                $registry = app(FieldTypeRegistry::class);
134
135
                $this->field = $registry->resolve('constructor', [$this->name]);
136
            }
137
        }
138
139
        call_user_func($this->fieldConfigurator);
140
141
        return $this->field;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->field could return the type Arbory\Base\Admin\Form\Fields\AbstractField which includes types incompatible with the type-hinted return Arbory\Base\Admin\Form\Fields\Constructor. Consider adding an additional type-check to rule them out.
Loading history...
142
    }
143
144
    /**
145
     * @return Panel
146
     */
147
    public function overview()
148
    {
149
        $panel = new Panel();
150
151
        $panel->setTitle('Overview');
152
        $panel->setContent(new Content([
0 ignored issues
show
array(Arbory\Base\Html\H...uctor-button-wrapper')) of type array<integer,Arbory\Base\Html\Elements\Element> is incompatible with the type Illuminate\Contracts\Support\Arrayable expected by parameter $items of Arbory\Base\Html\Elements\Content::__construct(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

152
        $panel->setContent(new Content(/** @scrutinizer ignore-type */ [
Loading history...
153
            Html::div(
154
                Link::create($this->getModalUrl())
155
                    ->asButton('primary new-constructor-item')
156
                    ->asAjaxbox(true)
157
                    ->withIcon('add')
158
                    ->title(trans('arbory::constructor.new_block_btn'))
159
            )->addClass('constructor-button-wrapper'),
160
        ]))->addClass('overview-panel');
161
162
        return $panel;
163
    }
164
165
    /**
166
     * @return \Closure
167
     */
168
    public function renderField()
169
    {
170
        $constructor = $this->getField();
171
172
        if (! $constructor->getFieldSet()) {
173
            return;
174
        }
175
176
        $styleManager = $constructor->getFieldSet()->getStyleManager();
177
        $opts = $styleManager->newOptions();
178
179
        return $styleManager->render('nested', $constructor, $opts);
180
    }
181
182
    /**
183
     * @return string
184
     */
185
    public function getModalUrl()
186
    {
187
        if ($this->modalUrl) {
188
            return $this->modalUrl;
189
        }
190
191
        return $this->getForm()->getModule()->url(
192
            'dialog',
193
            [
194
                'dialog' => 'constructor_types',
195
                'field' => $this->getField()->getNameSpacedName(),
196
            ]
197
        );
198
    }
199
200
    /**
201
     * @param $url
202
     * @return ConstructorLayout
203
     */
204
    public function setModalUrl($url): self
205
    {
206
        $this->modalUrl = $url;
207
208
        return $this;
209
    }
210
}
211