Completed
Push — master ( b2dde5...ebfb32 )
by
unknown
05:48
created

StoreController::mapTranslatableData()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 19

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 19
rs 9.6333
c 0
b 0
f 0
cc 4
nc 4
nop 2
1
<?php
2
3
namespace BBSLab\NovaTranslation\Http\Controllers\TranslatableResource;
4
5
use BBSLab\NovaTranslation\Models\Locale;
6
use BBSLab\NovaTranslation\Resources\TranslatableResource;
7
use Illuminate\Support\Facades\DB;
8
use Laravel\Nova\Actions\ActionEvent;
9
use Laravel\Nova\Fields\Field;
10
use Laravel\Nova\Fields\FieldCollection;
11
use Laravel\Nova\Http\Controllers\ResourceStoreController;
12
use Laravel\Nova\Http\Requests\CreateResourceRequest;
13
14
class StoreController extends ResourceStoreController
15
{
16
    /**
17
     * {@inheritdoc}
18
     */
19
    public function handle(CreateResourceRequest $request)
20
    {
21
        $resource = $request->resource();
22
23
        if (is_subclass_of($resource, TranslatableResource::class)) {
24
            $resource::authorizeToCreate($request);
25
            $resource::validateForCreation($request);
26
27
            $model = DB::transaction(function () use ($request, $resource) {
28
                $models = $this->storeTranslatable($request, $resource);
29
30
                /** @var \BBSLab\NovaTranslation\Models\Locale $currentLocale */
31
                $currentLocale = Locale::query()->select('id')->where('iso', '=', app()->getLocale())->first();
0 ignored issues
show
Bug introduced by
The method select() does not exist on Illuminate\Database\Eloquent\Builder. Did you maybe mean createSelectWithConstraint()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
32
33
                return $models[$currentLocale->id];
34
            });
35
36
            return response()->json([
37
                'id' => $model->getKey(),
38
                'resource' => $model->attributesToArray(),
39
                'redirect' => $resource::redirectAfterCreate($request, $request->newResourceWith($model)),
40
            ], 201);
41
        } else {
42
            return parent::handle($request);
43
        }
44
    }
45
46
    /**
47
     * Store translatable.
48
     *
49
     * @param  \Laravel\Nova\Http\Requests\CreateResourceRequest  $request
50
     * @param  string  $resource
51
     * @return \Illuminate\Database\Eloquent\Model
52
     */
53
    protected function storeTranslatable(CreateResourceRequest $request, string $resource)
54
    {
55
        $model = $resource::newModel();
56
57
        $creationFields = (new $resource($model))->creationFields($request);
58
        $translatedData = $this->mapTranslatableData($request, $creationFields);
59
60
        $translatedModels = [];
61
        foreach ($translatedData as $localeId => $fields) {
62
            $translationId = $fields['translation_id'];
63
            unset($fields['translation_id']);
64
65
            $translatedModels[$localeId] = $resource::newModel();
66
            foreach ($fields as $field => $value) {
67
                $translatedModels[$localeId]->$field = $value;
68
            }
69
70
            if ($request->viaRelationship()) {
71
                $request->findParentModelOrFail()->{$request->viaRelationship}()->save($translatedModels[$localeId]);
72
                // @TODO... Check for Translation entry for new created model
73
            } else {
74
                $translatedModels[$localeId]->save();
75
                $translatedModels[$localeId]->upsertTranslationEntry($localeId, $translationId);
76
            }
77
78
            ActionEvent::forResourceCreate($request->user(), $translatedModels[$localeId])->save();
79
80
            // @TODO...
81
            // collect($callbacks)->each->__invoke();
82
        }
83
84
        return $translatedModels;
85
    }
86
87
    /**
88
     * Map translatable data.
89
     *
90
     * @param  \Laravel\Nova\Http\Requests\CreateResourceRequest  $request
91
     * @param  \Laravel\Nova\Fields\FieldCollection  $fields
92
     * @return array
93
     */
94
    protected function mapTranslatableData(CreateResourceRequest $request, FieldCollection $fields)
95
    {
96
        $translatedData = [];
97
98
        foreach ($fields as $panel) {
99
            foreach ($panel['fields'] as $field) {
100
                /** @var \Laravel\Nova\Fields\Field $field */
101
                $localeId = $field->meta()['localeId'];
102
                if (! isset($translatedData[$localeId])) {
103
                    $translatedData[$localeId] = [];
104
                }
105
106
                $attribute = $this->translatableAttribute($field, $localeId);
107
                $translatedData[$localeId][$attribute] = $request->input($attribute.'.'.$localeId);
108
            }
109
        }
110
111
        return $translatedData;
112
    }
113
114
    /**
115
     * Return translatable attribute name.
116
     *
117
     * @param  \Laravel\Nova\Fields\Field  $field
118
     * @param  int  $localeId
119
     * @return string
120
     */
121
    protected function translatableAttribute(Field $field, int $localeId)
122
    {
123
        return substr($field->attribute, 0, strpos($field->attribute, '['.$localeId.']'));
124
    }
125
}
126