Passed
Push — master ( e1e679...09e224 )
by Quentin
10:29
created

HandleBrowsers::getFormFieldsForRelatedBrowser()   A

Complexity

Conditions 4
Paths 1

Size

Total Lines 15
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 20

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 4
eloc 12
c 1
b 0
f 0
nc 1
nop 2
dl 0
loc 15
ccs 0
cts 12
cp 0
crap 20
rs 9.8666
1
<?php
2
3
namespace A17\Twill\Repositories\Behaviors;
4
5
use A17\Twill\Models\Behaviors\HasMedias;
6
use Illuminate\Support\Str;
7
8
trait HandleBrowsers
9
{
10
    /**
11
     * All browsers used in the model, as an array of browser names:
12
     * [
13
     *  'books',
14
     *  'publications'
15
     * ].
16
     *
17
     * When only the browser name is given here, its rest information will be inferred from the name.
18
     * Each browser's detail can also be override with an array
19
     * [
20
     *  'books',
21
     *  'publication' => [
22
     *      'routePrefix' => 'collections',
23
     *      'titleKey' => 'name'
24
     *  ]
25
     * ]
26
     *
27
     * @var string|array(array)|array(mix(string|array))
28
     */
29
    protected $browsers = [];
30
31
    /**
32
     * @param \A17\Twill\Models\Model $object
33
     * @param array $fields
34
     * @return void
35
     */
36 27
    public function afterSaveHandleBrowsers($object, $fields)
37
    {
38 27
        foreach ($this->getBrowsers() as $browser) {
39
            $this->updateBrowser($object, $fields, $browser['relation'], $browser['positionAttribute'], $browser['browserName']);
40
        }
41 27
    }
42
43
    /**
44
     * @param \A17\Twill\Models\Model $object
45
     * @param array $fields
46
     * @return array
47
     */
48 5
    public function getFormFieldsHandleBrowsers($object, $fields)
49
    {
50 5
        foreach ($this->getBrowsers() as $browser) {
51
            $fields['browsers'][$browser['browserName']] = $this->getFormFieldsForBrowser($object, $browser['relation'], $browser['routePrefix'], $browser['titleKey'], $browser['moduleName']);
52
        }
53
54 5
        return $fields;
55
    }
56
57
    /**
58
     * @param \A17\Twill\Models\Model $object
59
     * @param array $fields
60
     * @param string $relationship
61
     * @param string $positionAttribute
62
     * @return void
63
     */
64
    public function updateBrowser($object, $fields, $relationship, $positionAttribute = 'position', $browserName = null)
65
    {
66
        $browserName = $browserName ?? $relationship;
67
        $fieldsHasElements = isset($fields['browsers'][$browserName]) && !empty($fields['browsers'][$browserName]);
68
        $relatedElements = $fieldsHasElements ? $fields['browsers'][$browserName] : [];
69
        $relatedElementsWithPosition = [];
70
        $position = 1;
71
        foreach ($relatedElements as $relatedElement) {
72
            $relatedElementsWithPosition[$relatedElement['id']] = [$positionAttribute => $position++];
73
        }
74
75
        $object->$relationship()->sync($relatedElementsWithPosition);
76
    }
77
78
    /**
79
     * @param \A17\Twill\Models\Model $object
80
     * @param array $fields
81
     * @param string $relationship
82
     * @param string $positionAttribute
83
     * @return void
84
     */
85
    public function updateOrderedBelongsTomany($object, $fields, $relationship, $positionAttribute = 'position')
86
    {
87
        $this->updateBrowser($object, $fields, $relationship, $positionAttribute);
88
    }
89
90
    /**
91
     * @param mixed $object
92
     * @param array $fields
93
     * @param string $browserName
94
     * @return void
95
     */
96
    public function updateRelatedBrowser($object, $fields, $browserName)
97
    {
98
        $object->saveRelated($fields['browsers'][$browserName] ?? [], $browserName);
99
    }
100
101
    /**
102
     * @param \A17\Twill\Models\Model $object
103
     * @param string $relation
104
     * @param string|null $routePrefix
105
     * @param string $titleKey
106
     * @param string|null $moduleName
107
     * @return array
108
     */
109
    public function getFormFieldsForBrowser($object, $relation, $routePrefix = null, $titleKey = 'title', $moduleName = null)
110
    {
111
        return $object->$relation->map(function ($relatedElement) use ($titleKey, $routePrefix, $relation, $moduleName) {
112
            return [
113
                'id' => $relatedElement->id,
114
                'name' => $relatedElement->titleInBrowser ?? $relatedElement->$titleKey,
115
                'edit' => moduleRoute($moduleName ?? $relation, $routePrefix ?? '', 'edit', $relatedElement->id),
116
                'endpointType' => $relatedElement->getMorphClass(),
117
            ] + (classHasTrait($relatedElement, HasMedias::class) ? [
118
                'thumbnail' => $relatedElement->defaultCmsImage(['w' => 100, 'h' => 100]),
119
            ] : []);
120
        })->toArray();
121
    }
122
123
    /**
124
     * @param \A17\Twill\Models\Model $object
125
     * @param string $relation
126
     * @return array
127
     */
128
    public function getFormFieldsForRelatedBrowser($object, $relation)
129
    {
130
        return $object->getRelated($relation)->map(function ($relatedElement) {
131
            return ($relatedElement != null) ? [
132
                'id' => $relatedElement->id,
133
                'name' => $relatedElement->titleInBrowser ?? $relatedElement->title,
134
                'endpointType' => $relatedElement->getMorphClass(),
135
            ] + (empty($relatedElement->adminEditUrl) ? [] : [
136
                'edit' => $relatedElement->adminEditUrl,
137
            ]) + (classHasTrait($relatedElement, HasMedias::class) ? [
138
                'thumbnail' => $relatedElement->defaultCmsImage(['w' => 100, 'h' => 100]),
139
            ] : []) : [];
140
        })->reject(function ($item) {
141
            return empty($item);
142
        })->values()->toArray();
143
    }
144
145
    /**
146
     * Get all browser' detail info from the $browsers attribute.
147
     * The missing information will be inferred by convention of Twill.
148
     *
149
     * @return Illuminate\Support\Collection
0 ignored issues
show
Bug introduced by
The type A17\Twill\Repositories\B...nate\Support\Collection was not found. Did you mean Illuminate\Support\Collection? If so, make sure to prefix the type with \.
Loading history...
150
     */
151 28
    protected function getBrowsers()
152
    {
153
        return collect($this->browsers)->map(function ($browser, $key) {
154
            $browserName = is_string($browser) ? $browser : $key;
155
            $moduleName = !empty($browser['moduleName']) ? $browser['moduleName'] : $this->inferModuleNameFromBrowserName($browserName);
156
            
157
            return [
158
                'relation' => !empty($browser['relation']) ? $browser['relation'] : $this->inferRelationFromBrowserName($browserName),
159
                'routePrefix' => isset($browser['routePrefix']) ? $browser['routePrefix'] : null,
160
                'titleKey' => !empty($browser['titleKey']) ? $browser['titleKey'] : 'title',
161
                'moduleName' => $moduleName,
162
                'model' => !empty($browser['model']) ? $browser['model'] : $this->inferModelFromModuleName($moduleName),
163
                'positionAttribute' => !empty($browser['positionAttribute']) ? $browser['positionAttribute'] : 'position',
164
                'browserName' => $browserName,
165
            ];
166 28
        })->values();
167
    }
168
169
    /**
170
     * The relation name shoud be lower camel case, ex. userGroup, contactOffice
171
     *
172
     * @param  string $browserName
173
     *
174
     * @return string
175
     */
176
    protected function inferRelationFromBrowserName(string $browserName): string
177
    {
178
        return Str::camel($browserName);
179
    }
180
181
    /**
182
     * The model name should be singular upper camel case, ex. User, ArticleType
183
     *
184
     * @param  string $moduleName
185
     *
186
     * @return string
187
     */
188
    protected function inferModelFromModuleName(string $moduleName): string
189
    {
190
        return Str::studly(Str::singular($moduleName));
191
    }
192
193
    /**
194
     * The module name should be plural lower camel case 
195
     *
196
     * @param  mixed $string
197
     * @param  mixed $browserName
198
     *
199
     * @return string
200
     */
201
    protected function inferModuleNameFromBrowserName(string $browserName): string
202
    {
203
        return Str::camel(Str::plural($browserName));
204
    }
205
}
206