Skip to content

Commit fc6f127

Browse files
committed
Initial setup for fieldsets
1 parent d597ec2 commit fc6f127

5 files changed

Lines changed: 209 additions & 87 deletions

File tree

Component/Form/FormViewModel.php

Lines changed: 45 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -2,18 +2,20 @@
22

33
namespace Loki\AdminComponents\Component\Form;
44

5+
use Loki\AdminComponents\Form\Field\Field;
6+
use Loki\AdminComponents\Form\Field\FieldFactory;
7+
use Loki\AdminComponents\Form\FieldResolver;
8+
use Loki\AdminComponents\Form\Fieldset\Fieldset;
9+
use Loki\AdminComponents\Form\Fieldset\FieldsetFactory;
510
use Loki\AdminComponents\Form\ItemConvertorInterface;
11+
use Loki\AdminComponents\Ui\Button;
12+
use Loki\AdminComponents\Ui\ButtonFactory;
13+
use Loki\Components\Component\ComponentViewModel;
614
use Magento\Framework\App\RequestInterface;
715
use Magento\Framework\DataObject;
816
use Magento\Framework\Exception\LocalizedException;
917
use Magento\Framework\ObjectManagerInterface;
1018
use Magento\Framework\UrlFactory;
11-
use Magento\Framework\View\Element\Template;
12-
use Loki\AdminComponents\Form\Field\Field;
13-
use Loki\AdminComponents\Form\Field\FieldFactory;
14-
use Loki\AdminComponents\Ui\Button;
15-
use Loki\AdminComponents\Ui\ButtonFactory;
16-
use Loki\Components\Component\ComponentViewModel;
1719

1820
/**
1921
* @method FormRepository getRepository()
@@ -25,7 +27,9 @@ public function __construct(
2527
protected ButtonFactory $buttonFactory,
2628
protected ObjectManagerInterface $objectManager,
2729
protected FieldFactory $fieldFactory,
30+
protected FieldsetFactory $fieldsetFactory,
2831
protected RequestInterface $request,
32+
protected FieldResolver $fieldResolver,
2933
protected array $itemFilters = [],
3034
) {
3135
}
@@ -89,93 +93,60 @@ public function getButtons(): array
8993
}
9094

9195
/**
92-
* @return Field[]
93-
* @throws LocalizedException
94-
* @todo Move this to Form
96+
* @return Fieldset[]
9597
*/
96-
public function getFields(): array
98+
public function getFieldsets(): array
9799
{
98-
$resourceModel = $this->getRepository()->getResourceModel();
99-
if (!$resourceModel) {
100-
return [];
101-
}
102-
103-
$fieldDefinitions = (array)$this->getBlock()->getFields();
100+
$fieldsets = [];
101+
$fieldsets['base'] = $this->fieldsetFactory->create('base');
104102

105-
$fields = [];
106-
$tableColumns = $resourceModel->getConnection()->describeTable($resourceModel->getMainTable());
107-
108-
foreach ($tableColumns as $tableColumn) {
109-
$columnName = $tableColumn['COLUMN_NAME'];
110-
$fieldType = $this->getFieldTypeCodeFromColumn($tableColumn);
111-
if ($columnName === $resourceModel->getIdFieldName()) {
112-
$fieldType = 'view';
103+
$fieldsetDefinitions = (array)$this->getBlock()->getFieldsets();
104+
foreach ($fieldsetDefinitions as $fieldsetCode => $fieldsetDefinition) {
105+
if (empty($fieldsetCode)) {
106+
$fieldsetCode = 'base';
113107
}
114108

115-
$fieldLabel = $this->getLabelByColumn($tableColumn['COLUMN_NAME']);
116-
$code = $tableColumn['COLUMN_NAME'];
117-
118-
if (empty($fieldType)) {
119-
// @todo: echo 'Unknown field type: '.$tableColumn['DATA_TYPE'];
109+
if (array_key_exists($fieldsetCode, $fieldsets)) {
120110
continue;
121111
}
122112

123-
$block = $this->getBlock()->getLayout()->createBlock(Template::class);
124-
$fieldData = [
125-
'field_type' => $fieldType,
126-
'code' => $code,
127-
'label' => $fieldLabel,
128-
'required' => false,
129-
'sort_order' => 0,
130-
'field_attributes' => [],
131-
'label_attributes' => [],
132-
];
133-
134-
if (array_key_exists($columnName, $fieldDefinitions)) {
135-
$fieldDefinition = (array)$fieldDefinitions[$columnName];
136-
$fieldData = array_merge($fieldData, $fieldDefinition);
137-
}
138-
139-
$fields[] = $this->fieldFactory->create(
140-
$block,
141-
$fieldData,
142-
);
113+
$fieldsets[$fieldsetCode] = $this->fieldsetFactory->create($fieldsetCode, $fieldsetDefinition['label']);
143114
}
144115

145-
usort($fields, function (Field $field1, Field $field2) {
146-
return $field1->getSortOrder() <=> $field2->getSortOrder();
147-
});
148-
149-
return $fields;
150-
}
116+
$fieldDefinitions = (array)$this->getBlock()->getFields();
117+
$fields = $this->fieldResolver->resolve($this->getRepository(), $fieldDefinitions);
151118

152-
private function getFieldTypeCodeFromColumn(array $tableColumn): false|string
153-
{
154-
if ($tableColumn['COLUMN_NAME'] === $this->getRepository()->getPrimaryKey()) {
155-
return 'view';
156-
}
119+
foreach ($fields as $field) {
120+
$fieldsetCode = (string)$field->getFieldset();
157121

158-
if (in_array($tableColumn['DATA_TYPE'], ['datetime'])) {
159-
return 'datetime';
160-
}
122+
if (!empty($fieldsetCode) && array_key_exists($fieldsetCode, $fieldsets)) {
123+
$fieldsets[$fieldsetCode]->addField($field);
124+
continue;
125+
}
161126

162-
if (in_array($tableColumn['DATA_TYPE'], ['date'])) {
163-
return 'date';
127+
$fieldsets['base']->addField($field);
164128
}
165129

166-
if (in_array($tableColumn['DATA_TYPE'], ['tinyint'])) {
167-
return 'switch';
168-
}
130+
return $fieldsets;
131+
}
169132

170-
if (in_array($tableColumn['DATA_TYPE'], ['int'])) {
171-
return 'number';
172-
}
133+
/**
134+
* @return Field[]
135+
* @throws LocalizedException
136+
* @deprecated Use getFieldsets() instead
137+
*/
138+
public function getFields(): array
139+
{
140+
$fields = $this->fieldResolver->resolve(
141+
$this->getRepository(),
142+
(array)$this->getBlock()->getFields(),
143+
);
173144

174-
if (in_array($tableColumn['DATA_TYPE'], ['varchar', 'text', 'smalltext', 'mediumtext'])) {
175-
return 'input';
145+
if (empty($fields)) {
146+
return $fields;
176147
}
177148

178-
return false;
149+
return $fields;
179150
}
180151

181152
private function getIndexUri(): string
@@ -195,14 +166,4 @@ private function getIndexUri(): string
195166

196167
return '*/*/index';
197168
}
198-
199-
private function getLabelByColumn(string $columnName): string
200-
{
201-
$label = (string)__($columnName);
202-
if ($label !== $columnName) {
203-
return $label;
204-
}
205-
206-
return ucfirst(str_replace('_', ' ', $label));
207-
}
208169
}

Form/FieldResolver.php

Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
<?php declare(strict_types=1);
2+
3+
namespace Loki\AdminComponents\Form;
4+
5+
use Loki\AdminComponents\Component\Form\FormRepository;
6+
use Loki\AdminComponents\Form\Field\Field;
7+
use Loki\AdminComponents\Form\Field\FieldFactory;
8+
use Magento\Framework\View\Element\Template;
9+
use Magento\Framework\View\LayoutInterface;
10+
11+
class FieldResolver
12+
{
13+
public function __construct(
14+
private FieldFactory $fieldFactory,
15+
private LayoutInterface $layout,
16+
) {
17+
}
18+
19+
public function resolve(FormRepository $formRepository, array $fieldDefinitions): array
20+
{
21+
$resourceModel = $formRepository->getResourceModel();
22+
if (!$resourceModel) {
23+
return [];
24+
}
25+
26+
$fields = [];
27+
$tableColumns = $resourceModel->getConnection()->describeTable($resourceModel->getMainTable());
28+
29+
foreach ($tableColumns as $tableColumn) {
30+
$columnName = $tableColumn['COLUMN_NAME'];
31+
$fieldType = $this->getFieldTypeCodeFromColumn($formRepository, $tableColumn);
32+
if ($columnName === $resourceModel->getIdFieldName()) {
33+
$fieldType = 'view';
34+
}
35+
36+
$fieldLabel = $this->getLabelByColumn($tableColumn['COLUMN_NAME']);
37+
$code = $tableColumn['COLUMN_NAME'];
38+
39+
if (empty($fieldType)) {
40+
// @todo: echo 'Unknown field type: '.$tableColumn['DATA_TYPE'];
41+
continue;
42+
}
43+
44+
$block = $this->layout->createBlock(Template::class);
45+
$fieldData = [
46+
'field_type' => $fieldType,
47+
'code' => $code,
48+
'label' => $fieldLabel,
49+
'required' => false,
50+
'sort_order' => 0,
51+
'field_attributes' => [],
52+
'label_attributes' => [],
53+
];
54+
55+
if (array_key_exists($columnName, $fieldDefinitions)) {
56+
$fieldDefinition = (array)$fieldDefinitions[$columnName];
57+
$fieldData = array_merge($fieldData, $fieldDefinition);
58+
}
59+
60+
$fields[$code.$fieldData['sort_order']] = $this->fieldFactory->create(
61+
$block,
62+
$fieldData,
63+
);
64+
}
65+
66+
uasort($fields, function (Field $field1, Field $field2) {
67+
return $field1->getSortOrder() <=> $field2->getSortOrder();
68+
});
69+
70+
return $fields;
71+
}
72+
73+
private function getFieldTypeCodeFromColumn(FormRepository $formRepository, array $tableColumn): false|string
74+
{
75+
if ($tableColumn['COLUMN_NAME'] === $formRepository->getPrimaryKey()) {
76+
return 'view';
77+
}
78+
79+
if (in_array($tableColumn['DATA_TYPE'], ['datetime'])) {
80+
return 'datetime';
81+
}
82+
83+
if (in_array($tableColumn['DATA_TYPE'], ['date'])) {
84+
return 'date';
85+
}
86+
87+
if (in_array($tableColumn['DATA_TYPE'], ['tinyint'])) {
88+
return 'switch';
89+
}
90+
91+
if (in_array($tableColumn['DATA_TYPE'], ['int'])) {
92+
return 'number';
93+
}
94+
95+
if (in_array($tableColumn['DATA_TYPE'], ['varchar', 'text', 'smalltext', 'mediumtext'])) {
96+
return 'input';
97+
}
98+
99+
return false;
100+
}
101+
102+
private function getLabelByColumn(string $columnName): string
103+
{
104+
$label = (string)__($columnName);
105+
if ($label !== $columnName) {
106+
return $label;
107+
}
108+
109+
return ucfirst(str_replace('_', ' ', $label));
110+
}
111+
}

Form/Fieldset/Fieldset.php

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,51 @@
33

44
namespace Loki\AdminComponents\Form\Fieldset;
55

6+
use Loki\AdminComponents\Form\Field\Field;
7+
68
class Fieldset
79
{
810
public function __construct(
9-
private string $label,
11+
private string $code,
12+
private string $label = '',
13+
private array $fields = []
1014
) {
1115
}
1216

17+
public function getCode(): string
18+
{
19+
return $this->code;
20+
}
21+
1322
public function getLabel(): string
1423
{
1524
return $this->label;
1625
}
26+
27+
public function hasLabel(): bool
28+
{
29+
return !empty($this->label);
30+
}
31+
32+
public function getFields(): array
33+
{
34+
return $this->fields;
35+
}
36+
37+
public function hasFields(): bool
38+
{
39+
return !empty($this->fields);
40+
}
41+
42+
public function addFields(array $fields): void
43+
{
44+
foreach ($fields as $field) {
45+
$this->addField($field);
46+
}
47+
}
48+
49+
public function addField(Field $field): void
50+
{
51+
$this->fields[] = $field;
52+
}
1753
}

Form/Fieldset/FieldsetFactory.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,10 @@ public function __construct(
1212
) {
1313
}
1414

15-
public function create(string $label, array $fields = []): Fieldset
15+
public function create(string $code, string $label = '', array $fields = []): Fieldset
1616
{
1717
return $this->objectManager->create(Fieldset::class, [
18+
'code' => $code,
1819
'label' => $label,
1920
'fields' => $fields,
2021
]);

view/adminhtml/templates/form.phtml

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,9 +35,20 @@ if (!isset($viewModel)) {
3535
<div class="entry-edit form-inline">
3636
<div class="fieldset-wrapper">
3737
<h1><?= $escaper->escapeHtml($block->getLabel()) ?></h1>
38+
39+
<?php foreach ($viewModel->getFieldsets() as $fieldset): ?>
3840
<div class="admin__fieldset-wrapper-content">
41+
<?php if ($fieldset->hasLabel()): ?>
42+
<div class="fieldset-wrapper-title">
43+
<strong class="admin__collapsible-title">
44+
<?= $escaper->escapeHtml($fieldset->getLabel()) ?>
45+
</strong>
46+
</div>
47+
<?php endif; ?>
48+
49+
<?php if ($fieldset->hasFields()): ?>
3950
<fieldset class="admin__fieldset">
40-
<?php foreach ($viewModel->getFields() as $field) : ?>
51+
<?php foreach ($fieldset->getFields() as $field) : ?>
4152
<?php if (false === $field->isVisible()) continue; ?>
4253
<?= /* @noEscape */ $templateRenderer->html(
4354
$block,
@@ -46,7 +57,9 @@ if (!isset($viewModel)) {
4657
); ?>
4758
<?php endforeach; ?>
4859
</fieldset>
60+
<?php endif; ?>
4961
</div>
62+
<?php endforeach; ?>
5063
</div>
5164
</div>
5265
</div>

0 commit comments

Comments
 (0)