• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

conedevelopment / root / 15084089635

17 May 2025 10:00AM UTC coverage: 77.93% (+0.04%) from 77.891%
15084089635

push

github

web-flow
Modernize back-end.yml (#240)

3291 of 4223 relevant lines covered (77.93%)

36.04 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

84.15
/src/Fields/Media.php
1
<?php
2

3
namespace Cone\Root\Fields;
4

5
use Cone\Root\Filters\MediaSearch;
6
use Cone\Root\Filters\RenderableFilter;
7
use Cone\Root\Http\Controllers\MediaController;
8
use Cone\Root\Models\Medium;
9
use Cone\Root\Traits\HasMedia;
10
use Illuminate\Contracts\Pagination\LengthAwarePaginator;
11
use Illuminate\Database\Eloquent\Model;
12
use Illuminate\Http\Request;
13
use Illuminate\Http\UploadedFile;
14
use Illuminate\Routing\Router;
15
use Illuminate\Support\Facades\Config;
16
use Illuminate\Support\Facades\Storage;
17
use Illuminate\Support\Facades\View;
18
use Illuminate\Validation\Rule;
19

20
class Media extends File
21
{
22
    /**
23
     * Indicates if the component is multiple.
24
     */
25
    protected bool $multiple = true;
26

27
    /**
28
     * The Blade template.
29
     */
30
    protected string $template = 'root::fields.media';
31

32
    /**
33
     * Get the route parameter name.
34
     */
35
    public function getRouteParameterName(): string
3✔
36
    {
37
        return 'field';
3✔
38
    }
39

40
    /**
41
     * Get the modal key.
42
     */
43
    public function getModalKey(): string
2✔
44
    {
45
        return sprintf('media-field-%s', $this->getModelAttribute());
2✔
46
    }
47

48
    /**
49
     * Set the multiple attribute.
50
     */
51
    public function multiple(bool $value = true): static
198✔
52
    {
53
        $this->multiple = $value;
198✔
54

55
        return $this;
198✔
56
    }
57

58
    /**
59
     * Get the model.
60
     */
61
    public function getModel(): Model
×
62
    {
63
        return $this->model ?: new class extends Model
×
64
        {
×
65
            use HasMedia;
66
        };
×
67
    }
68

69
    /**
70
     * {@inheritdoc}
71
     */
72
    public function fields(Request $request): array
198✔
73
    {
74
        return [];
198✔
75
    }
76

77
    /**
78
     * {@inheritdoc}
79
     */
80
    public function filters(Request $request): array
3✔
81
    {
82
        return [
3✔
83
            new MediaSearch,
3✔
84
        ];
3✔
85
    }
86

87
    /**
88
     * Paginate the relatable models.
89
     */
90
    public function paginateRelatable(Request $request, Model $model): LengthAwarePaginator
1✔
91
    {
92
        return $this->resolveFilters($request)
1✔
93
            ->apply($request, $this->resolveRelatableQuery($request, $model))
1✔
94
            ->paginate($request->input('per_page'))
1✔
95
            ->withQueryString()
1✔
96
            ->through(function (Medium $related) use ($request, $model): array {
1✔
97
                $option = $this->toOption($request, $model, $related);
×
98

99
                return array_merge($option, [
×
100
                    'html' => View::make('root::fields.file-option', $option)->render(),
×
101
                ]);
×
102
            });
1✔
103
    }
104

105
    /**
106
     * {@inheritdoc}
107
     */
108
    public function persist(Request $request, Model $model, mixed $value): void
3✔
109
    {
110
        $model->saved(function (Model $model) use ($request, $value): void {
3✔
111
            $this->resolveHydrate($request, $model, $value);
3✔
112

113
            $keys = $this->getRelation($model)->sync($value);
3✔
114

115
            if ($this->prunable && ! empty($keys['detached'])) {
3✔
116
                $this->prune($request, $model, $keys['detached']);
×
117
            }
118
        });
3✔
119
    }
120

121
    /**
122
     * Handle the file upload.
123
     */
124
    public function upload(Request $request, Model $model): array
1✔
125
    {
126
        $accept = $this->getAttribute('accept');
1✔
127

128
        $data = $request->validate(['file' => [
1✔
129
            'required',
1✔
130
            'file',
1✔
131
            Rule::when(! is_null($accept), ['mimetypes:'.$accept]),
1✔
132
        ]]);
1✔
133

134
        return $this->store($request, $model, $data['file']);
1✔
135
    }
136

137
    /**
138
     * {@inheritdoc}
139
     */
140
    public function store(Request $request, Model $model, UploadedFile $file): array
1✔
141
    {
142
        $disk = Storage::build([
1✔
143
            'driver' => 'local',
1✔
144
            'root' => Config::get('root.media.tmp_dir'),
1✔
145
        ]);
1✔
146

147
        $disk->append($file->getClientOriginalName(), $file->get());
1✔
148

149
        if ($request->header('X-Chunk-Index') !== $request->header('X-Chunk-Total')) {
1✔
150
            return array_merge($this->toOption($request, $model, new Medium), [
×
151
                'processing' => true,
×
152
                'fileName' => null,
×
153
            ]);
×
154
        }
155

156
        return $this->stored($request, $model, $disk->path($file->getClientOriginalName()));
1✔
157
    }
158

159
    /**
160
     * The routes that should be registered.
161
     */
162
    public function routes(Router $router): void
198✔
163
    {
164
        $router->match(['GET', 'POST', 'DELETE'], '/', MediaController::class);
198✔
165
    }
166

167
    /**
168
     * {@inheritdoc}
169
     */
170
    public function toInput(Request $request, Model $model): array
2✔
171
    {
172
        $data = parent::toInput($request, $model);
2✔
173

174
        $filters = $this->resolveFilters($request)->authorized($request);
2✔
175

176
        return array_merge($data, [
2✔
177
            'modalKey' => $this->getModalKey(),
2✔
178
            'config' => [
2✔
179
                'accept' => $this->getAttribute('accept', '*'),
2✔
180
                'multiple' => $this->multiple,
2✔
181
                'chunk_size' => Config::get('root.media.chunk_size'),
2✔
182
                'query' => $filters->mapToData($request),
2✔
183
            ],
2✔
184
            'selection' => array_map(static fn (array $option): array => array_merge($option, [
2✔
185
                'html' => View::make('root::fields.file-option', $option)->render(),
2✔
186
            ]), $data['options'] ?? []),
2✔
187
            'url' => $this->modelUrl($model),
2✔
188
            'filters' => $filters->renderable()
2✔
189
                ->map(fn (RenderableFilter $filter): array => $filter->toField()
2✔
190
                    ->removeAttribute('name')
2✔
191
                    ->setAttributes([
2✔
192
                        'x-model.debounce.300ms' => $filter->getKey(),
2✔
193
                        'x-bind:readonly' => 'processing',
2✔
194
                    ])
2✔
195
                    ->toInput($request, $this->getRelation($model)->make()))
2✔
196
                ->all(),
2✔
197
        ]);
2✔
198
    }
199
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc