Completed
Pull Request — master (#139)
by Sebastian
10:33 queued 07:18
created

FormBuilder   A

Complexity

Total Complexity 20

Size/Duplication

Total Lines 177
Duplicated Lines 0 %

Coupling/Cohesion

Components 3
Dependencies 8

Importance

Changes 0
Metric Value
dl 0
loc 177
rs 10
c 0
b 0
f 0
wmc 20
lcom 3
cbo 8

14 Methods

Rating   Name   Duplication   Size   Complexity  
A openDraftable() 0 12 2
A openButton() 0 8 2
A closeButton() 0 4 1
A redactor() 0 17 2
A checkboxWithLabel() 0 10 1
A datePicker() 0 7 1
A tags() 0 9 1
A category() 0 7 1
A locales() 0 10 1
A media() 0 22 1
B contentBlocks() 0 29 1
A getAssociatedData() 0 9 1
A useInitialValue() 0 11 4
A getLabelForTranslatedField() 0 6 1
1
<?php
2
3
namespace App\Services\Html;
4
5
use Html;
6
use Carbon\Carbon;
7
use App\Models\Tag;
8
use Illuminate\Database\Eloquent\Model;
9
use App\Models\Transformers\MediaTransformer;
10
use Collective\Html\FormBuilder as BaseFormBuilder;
11
use App\Models\Transformers\ContentBlockTransformer;
12
13
class FormBuilder extends BaseFormBuilder
14
{
15
    public function openDraftable(array $options, Model $subject): string
16
    {
17
        $identifier = class_basename($subject).'_'.($subject->isDraft() ? 'new' : $subject->id);
18
19
        $options = array_merge($options, [
20
            'data-autosave' => '',
21
            'name' => $identifier,
22
            'id' => $identifier,
23
        ]);
24
25
        return $this->open($options);
26
    }
27
28
    public function openButton(array $formOptions = [], array $buttonOptions = []): string
29
    {
30
        if (strtolower($formOptions['method'] ?? '') === 'delete') {
31
            $formOptions['data-confirm'] = 'true';
32
        }
33
34
        return $this->open($formOptions).substr(el('button', $buttonOptions, ''), 0, -strlen('</button>'));
35
    }
36
37
    public function closeButton(): string
38
    {
39
        return '</button>'.$this->close();
40
    }
41
42
    public function redactor($subject, string $fieldName, string $locale = '', array $options = []): string
43
    {
44
        $initial = $this->useInitialValue($subject, $fieldName, $locale);
45
        $fieldName = $locale ? translate_field_name($fieldName, $locale) : $fieldName;
46
47
        return $this->textarea(
48
            $fieldName,
49
            $initial,
50
            array_merge($options, [
51
                'data-editor',
52
                'data-editor-medialibrary-url' => action(
53
                    'Back\Api\MediaLibraryController@add',
54
                    [short_class_name($subject), $subject->id, 'redactor']
55
                ),
56
            ])
57
        );
58
    }
59
60
    public function checkboxWithLabel($subject, string $fieldName, string $label, array $options = []): string
61
    {
62
        $options = array_merge(['class' => 'form-control'], $options);
63
64
        return el(
65
            'label.-checkbox',
66
            $this->checkbox($fieldName, 1, $this->useInitialValue($subject, $fieldName), $options)
0 ignored issues
show
Documentation introduced by
$this->useInitialValue($subject, $fieldName) is of type string, but the function expects a boolean|null.

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...
67
            .' '.$label
68
        );
69
    }
70
71
    public function datePicker(string $name, string $value): string
72
    {
73
        return $this->text($name, $value, [
74
            'data-datetimepicker',
75
            'class' => '-datetime',
76
        ]);
77
    }
78
79
    public function tags($subject, string $type, array $options = []): string
80
    {
81
        $tags = Tag::getWithType($type)->pluck('name', 'name')->toArray();
82
        $subjectTags = $subject->tagsWithType($type)->pluck('name', 'name')->toArray();
83
84
        $options = array_merge(['multiple', 'data-select' => 'tags'], $options);
85
86
        return $this->select("{$type}_tags[]", $tags, $subjectTags, $options);
87
    }
88
89
    public function category($subject, $type, array $options = []): string
90
    {
91
        $categories = Tag::getWithType($type)->pluck('name', 'name')->toArray();
92
        $subjectCategory = $subject->tagsWithType($type)->first()->name ?? null;
93
94
        return $this->select("{$type}_tags[]", $categories, $subjectCategory, $options);
95
    }
96
97
    public function locales(array $locales, string $current): string
98
    {
99
        $list = array_reduce($locales, function (array $list, string $locale) {
100
            $list[$locale] = trans("locales.{$locale}");
101
102
            return $list;
103
        }, []);
104
105
        return $this->select('locale', $list, $current, ['data-select' => 'select']);
106
    }
107
108
    public function media($subject, string $collection, string $type, $associated = []): string
109
    {
110
        $initialMedia = fractal()
111
            ->collection($subject->getMedia($collection))
112
            ->transformWith(new MediaTransformer())
113
            ->toJson();
114
115
        $model = collect([
116
            'name' => get_class($subject),
117
            'id' => $subject->id,
118
        ])->toJson();
119
120
        return el('blender-media', [
121
            'collection' => $collection,
122
            'type' => $type,
123
            'upload-url' => action('Back\Api\MediaLibraryController@add'),
124
            ':model' => htmlspecialchars($model),
125
            ':initial' => htmlspecialchars($initialMedia),
126
            ':data' => htmlspecialchars($this->getAssociatedData($associated)),
127
            ':debug' => htmlspecialchars(json_encode(config('app.debug', false))),
128
        ], '');
129
    }
130
131
    public function contentBlocks(Model $subject, string $collectionName, string $editor, array $associated = []): string
132
    {
133
        $initialContentBlocks = fractal()
134
            ->collection($subject->getContentBlocksForCollection($collectionName))
135
            ->transformWith(new ContentBlockTransformer())
136
            ->toJson();
137
138
        $model = collect([
139
            'name' => get_class($subject),
140
            'id' => $subject->id,
141
        ])->toJson();
142
143
        $associatedData = $this->getAssociatedData(array_merge($associated, [
144
            'locales' => config('app.locales'),
145
            'contentLocale' => content_locale(),
146
            'mediaModel' => ContentBlock::class,
147
            'mediaUploadUrl' => action('Back\Api\MediaLibraryController@add'),
148
        ]));
149
150
        return el('blender-content-blocks', [
151
            'collection' => $collectionName,
152
            'editor' => $editor,
153
            'create-url' => action('Back\Api\ContentBlockController@add'),
154
            ':model' => htmlspecialchars($model),
155
            ':input' => htmlspecialchars($initialContentBlocks),
156
            ':data' => htmlspecialchars($associatedData),
157
            ':debug' => htmlspecialchars(json_encode(config('app.debug', false))),
158
        ], '');
159
    }
160
161
    protected function getAssociatedData($associated = []): string
162
    {
163
        $associated = collect($associated);
164
165
        $associated->put('locales', config('app.locales'));
166
        $associated->put('contentLocale', content_locale());
167
168
        return $associated->toJson();
169
    }
170
171
    public function useInitialValue($subject, string $propertyName, string $locale = ''): string
172
    {
173
        $fieldName = $locale ? translate_field_name($propertyName, $locale) : $propertyName;
174
        $value = $locale ? $subject->translate($propertyName, $locale) : $subject->$propertyName;
175
176
        if ($value instanceof Carbon) {
177
            $value = $value->format('d/m/Y');
178
        }
179
180
        return $this->getValueAttribute($fieldName, $value) ?? '';
181
    }
182
183
    public function getLabelForTranslatedField(string $fieldName, string $label, string $locale): string
184
    {
185
        return Html::decode(
186
            $this->label($fieldName, $label.el('span.label_lang', $locale))
187
        );
188
    }
189
}
190