Completed
Push — master ( cacecb...cf44a0 )
by Mario
04:48
created

WorksWithFileUploads::updateOrCreateFileHasOne()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 8
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 5
dl 0
loc 8
c 0
b 0
f 0
rs 10
cc 2
nc 2
nop 4
1
<?php
2
3
namespace RafflesArgentina\ResourceController\Traits;
4
5
use Lang;
6
use Storage;
7
8
use Symfony\Component\HttpFoundation\File\UploadedFile;
9
use Symfony\Component\HttpFoundation\File\Exception\UploadException;
10
11
use Illuminate\Database\Eloquent\Model;
12
use Illuminate\Database\Eloquent\Relations\Relation;
13
use Illuminate\Http\Request;
14
15
trait WorksWithFileUploads
16
{
17
    /**
18
     * Upload request files and update or create relations handling array type request data.
19
     *
20
     * @param Request     $request      The Request object.
21
     * @param Model       $model        The eloquent model.
22
     * @param string|null $relativePath The file uploads relative path.
23
     *
24
     * @return Request
25
     */
26
    public function uploadFiles(Request $request, Model $model, $relativePath = null)
27
    {
28
        if (!$relativePath) {
29
            $relativePath = $this->getDefaultRelativePath();
30
        }
31
32
        $data = $request->request->all();
33
34
        $fileBag = $request->files;
35
        foreach ($fileBag->all() as $name => $parameters) {
36
            $this->_checkFileRelationExists($model, $name);
37
            $relation = $model->{$name}();
0 ignored issues
show
Unused Code introduced by
The assignment to $relation is dead and can be removed.
Loading history...
38
39
            foreach ($parameters as $index => $file) {
40
                if (!$file->isValid()) {
41
                    throw new UploadException($file->getError());
42
                }
43
44
                $filename = $this->getFilename($file);
45
                $destination = $this->getStoragePath($relativePath);
46
                $this->moveUploadedFile($file, $filename, $destination);
47
48
                $location = $relativePath.$filename;
49
50
                if (count($fileBag->get($name)) > 1) {
51
                    $data[$name][$index] = [$this->getLocationColumn() => $location];
52
                } else {
53
                    $data[$name][$this->getLocationColumn()] = $location;
54
                }
55
56
                $request->merge($data);
57
            }
58
        }
59
60
        return $request;
61
    }
62
63
    /**
64
     * Get the name of the file.
65
     *
66
     * @param UploadedFile $uploadedFile The UploadedFile object.
67
     *
68
     * @return string
69
     */
70
    protected function getFilename(UploadedFile $uploadedFile)
71
    {
72
        $extension = $uploadedFile->guessExtension();
73
        $filename = str_random().'.'.$extension;
74
75
        return $filename;
76
    }
77
78
    /**
79
     * Get storage path for the configured driver.
80
     *
81
     * @param string $relativePath The relative path.
82
     *
83
     * @return string
84
     */
85
    protected function getStoragePath($relativePath)
86
    {
87
        return Storage::disk()->getDriver()->getAdapter()->getPathPrefix().$relativePath;
88
    }
89
90
    /**
91
     * Move the uploaded file to specified filename and destination.
92
     *
93
     * @param UploadedFile $uploadedFile The UploadedFile object.
94
     * @param string       $filename     The name of the file.
95
     * @param string       $destination  The file destination.
96
     *
97
     * @return \Symfony\Component\HttpFoundation\File\File
98
     */
99
    protected function moveUploadedFile($uploadedFile, $filename, $destination)
100
    {
101
        return $uploadedFile->move($destination, $filename);
102
    }
103
104
    /**
105
     * Get location column.
106
     *
107
     * @return string
108
     */
109
    protected function getLocationColumn()
110
    {
111
        return 'location';
112
    }
113
114
    /**
115
     * Get default relative path.
116
     *
117
     * @return string
118
     */
119
    protected function getDefaultRelativePath()
120
    {
121
        return 'uploads/';
122
    }
123
124
    /**
125
     * Throw an exception if request file is not named after an existent relation.
126
     *
127
     * @param Model  $model        The eloquent model.
128
     * @param string $relationName The eloquent relation name.
129
     *
130
     * @throws UploadException
131
     *
132
     * @return void
133
     */
134
    private function _checkFileRelationExists(Model $model, $relationName)
135
    {
136
        if (!method_exists($model, $relationName) || !$model->{$relationName}() instanceof Relation) {
137
            if (Lang::has('resource-controller.filerelationinexistent')) {
138
                $message = trans('resource-controller.filerelationinexistent', ['relationName' => $relationName]);
139
            } else {
140
                $message = "Request file '{$relationName}' is not named after an existent relation.";
141
            }
142
            throw new UploadException($message);
143
        }
144
    }
145
}
146