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

conedevelopment / root / 6640056799

25 Oct 2023 12:03PM UTC coverage: 5.498%. Remained the same
6640056799

push

github

iamgergo
wip

1 of 1 new or added line in 1 file covered. (100.0%)

107 of 1946 relevant lines covered (5.5%)

0.05 hits per line

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

0.0
/src/Resources/Resource.php
1
<?php
2

3
namespace Cone\Root\Resources;
4

5
use Cone\Root\Actions\Action;
6
use Cone\Root\Fields\Field;
7
use Cone\Root\Filters\RenderableFilter;
8
use Cone\Root\Interfaces\Form;
9
use Cone\Root\Interfaces\Table;
10
use Cone\Root\Root;
11
use Cone\Root\Traits\AsForm;
12
use Cone\Root\Traits\Authorizable;
13
use Cone\Root\Traits\RegistersRoutes;
14
use Cone\Root\Traits\ResolvesActions;
15
use Cone\Root\Traits\ResolvesColumns;
16
use Cone\Root\Traits\ResolvesFilters;
17
use Cone\Root\Traits\ResolvesWidgets;
18
use Illuminate\Contracts\Pagination\LengthAwarePaginator;
19
use Illuminate\Contracts\Support\Arrayable;
20
use Illuminate\Contracts\Support\MessageBag;
21
use Illuminate\Database\Eloquent\Builder;
22
use Illuminate\Database\Eloquent\Model;
23
use Illuminate\Database\Eloquent\SoftDeletes;
24
use Illuminate\Http\Request;
25
use Illuminate\Routing\Router;
26
use Illuminate\Support\Collection;
27
use Illuminate\Support\Facades\Gate;
28
use Illuminate\Support\Str;
29

30
abstract class Resource implements Arrayable, Form, Table
31
{
32
    use AsForm;
33
    use Authorizable;
34
    use RegistersRoutes {
35
        RegistersRoutes::registerRoutes as __registerRoutes;
36
    }
37
    use ResolvesActions;
38
    use ResolvesColumns;
39
    use ResolvesFilters;
40
    use ResolvesWidgets;
41

42
    /**
43
     * The model class.
44
     */
45
    protected string $model;
46

47
    /**
48
     * The relations to eager load on every query.
49
     */
50
    protected array $with = [];
51

52
    /**
53
     * The relations to eager load on every query.
54
     */
55
    protected array $withCount = [];
56

57
    /**
58
     * The icon for the resource.
59
     */
60
    protected string $icon = 'archive';
61

62
    /**
63
     * Boot the resource.
64
     */
65
    public function boot(Root $root): void
66
    {
67
        $root->routes(function (Router $router) use ($root): void {
×
68
            $this->registerRoutes($root->app['request'], $router);
×
69
        });
×
70
    }
71

72
    /**
73
     * Get the model for the resource.
74
     */
75
    public function getModel(): string
76
    {
77
        return $this->model;
×
78
    }
79

80
    /**
81
     * Get the key.
82
     */
83
    public function getKey(): string
84
    {
85
        return Str::of($this->getModel())->classBasename()->plural()->kebab()->value();
×
86
    }
87

88
    /**
89
     * Get the URI key.
90
     */
91
    public function getUriKey(): string
92
    {
93
        return $this->getKey();
×
94
    }
95

96
    /**
97
     * Get the route parameter name.
98
     */
99
    public function getRouteParameterName(): string
100
    {
101
        return '_resource';
×
102
    }
103

104
    /**
105
     * Get the name.
106
     */
107
    public function getName(): string
108
    {
109
        return __(Str::of($this->getModel())->classBasename()->headline()->plural()->value());
×
110
    }
111

112
    /**
113
     * Get the model name.
114
     */
115
    public function getModelName(): string
116
    {
117
        return __(Str::of($this->getModel())->classBasename()->value());
×
118
    }
119

120
    /**
121
     * Get the model instance.
122
     */
123
    public function getModelInstance(): Model
124
    {
125
        return new ($this->getModel());
×
126
    }
127

128
    /**
129
     * Set the resource icon.
130
     */
131
    public function icon(string $icon): static
132
    {
133
        $this->icon = $icon;
×
134

135
        return $this;
×
136
    }
137

138
    /**
139
     * Get the resource icon.
140
     */
141
    public function getIcon(): string
142
    {
143
        return $this->icon;
×
144
    }
145

146
    /**
147
     * Get the policy for the model.
148
     */
149
    public function getPolicy(): mixed
150
    {
151
        return Gate::getPolicyFor($this->getModel());
×
152
    }
153

154
    /**
155
     * Set the relations to eagerload.
156
     */
157
    public function with(array $relations): static
158
    {
159
        $this->with = $relations;
×
160

161
        return $this;
×
162
    }
163

164
    /**
165
     * Set the relation counts to eagerload.
166
     */
167
    public function withCount(array $relations): static
168
    {
169
        $this->withCount = $relations;
×
170

171
        return $this;
×
172
    }
173

174
    /**
175
     * Make a new Eloquent query instance.
176
     */
177
    public function query(): Builder
178
    {
179
        return $this->getModelInstance()->newQuery()->with($this->with)->withCount($this->withCount);
×
180
    }
181

182
    /**
183
     * Resolve the query for the given request.
184
     */
185
    public function resolveQuery(Request $request): Builder
186
    {
187
        return $this->query();
×
188
    }
189

190
    /**
191
     * Resolve the filtered query for the given request.
192
     */
193
    public function resolveFilteredQuery(Request $request): Builder
194
    {
195
        return $this->resolveFilters($request)->apply($request, $this->resolveQuery($request));
×
196
    }
197

198
    /**
199
     * Resolve the route binding query.
200
     */
201
    public function resolveRouteBindingQuery(Request $request): Builder
202
    {
203
        return $this->resolveQuery($request)->when(
×
204
            $this->isSoftDeletable(),
×
205
            static function (Builder $query): Builder {
×
206
                return $query->withTrashed();
×
207
            }
×
208
        );
×
209
    }
210

211
    /**
212
     * Resolve the resource model for a bound value.
213
     */
214
    public function resolveRouteBinding(Request $request, string $id): Model
215
    {
216
        return $this->resolveRouteBindingQuery($request)->findOrFail($id);
×
217
    }
218

219
    /**
220
     * Determine if the model soft deletable.
221
     */
222
    public function isSoftDeletable(): bool
223
    {
224
        return in_array(SoftDeletes::class, class_uses_recursive($this->getModel()));
×
225
    }
226

227
    /**
228
     * Get the URL for the given model.
229
     */
230
    public function modelUrl(Model $model): string
231
    {
232
        return sprintf('%s/%s', $this->getUri(), $model->exists ? $model->getRouteKey() : '');
×
233
    }
234

235
    /**
236
     * Handle the callback for the field resolution.
237
     */
238
    protected function resolveField(Request $request, Field $field): void
239
    {
240
        $field->setAttribute('form', $this->getKey());
×
241
        $field->resolveErrorsUsing(fn (Request $request): MessageBag => $this->errors($request));
×
242
    }
243

244
    /**
245
     * Handle the callback for the action resolution.
246
     */
247
    protected function resolveAction(Request $request, Action $action): void
248
    {
249
        $action->setQuery($this->resolveFilteredQuery($request));
×
250
    }
251

252
    /**
253
     * Get the per page options.
254
     */
255
    public function getPerPageOptions(): array
256
    {
257
        return Collection::make([$this->getModelInstance()->getPerPage()])
×
258
            ->merge([15, 25, 50, 100])
×
259
            ->filter()
×
260
            ->unique()
×
261
            ->values()
×
262
            ->toArray();
×
263
    }
264

265
    /**
266
     * Perform the query and the pagination.
267
     */
268
    public function paginate(Request $request): LengthAwarePaginator
269
    {
270
        return $this->resolveFilteredQuery($request)
×
271
            ->latest()
×
272
            ->paginate($request->input('per_page'))
×
273
            ->withQueryString()
×
274
            ->through(function (Model $model) use ($request): array {
×
275
                return [
×
276
                    'id' => $model->getKey(),
×
277
                    'cells' => $this->resolveColumns($request)->mapToCells($request, $model),
×
278
                ];
×
279
            });
×
280
    }
281

282
    /**
283
     * Register the routes.
284
     */
285
    public function registerRoutes(Request $request, Router $router): void
286
    {
287
        $this->__registerRoutes($request, $router);
×
288

289
        $router->prefix($this->getUriKey())->group(function (Router $router) use ($request): void {
×
290
            $this->resolveActions($request)->registerRoutes($request, $router);
×
291
            $this->resolveFields($request)->registerRoutes($request, $router);
×
292
        });
×
293
    }
294

295
    /**
296
     * Get the instance as an array.
297
     */
298
    public function toArray(): array
299
    {
300
        return [
×
301
            'icon' => $this->getIcon(),
×
302
            'key' => $this->getKey(),
×
303
            'model' => $this->getModel(),
×
304
            'modelName' => $this->getModelName(),
×
305
            'name' => $this->getName(),
×
306
            'uriKey' => $this->getUriKey(),
×
307
            'url' => $this->getUri(),
×
308
        ];
×
309
    }
310

311
    /**
312
     * Get the index representation of the resource.
313
     */
314
    public function toIndex(Request $request): array
315
    {
316
        return array_merge($this->toArray(), [
×
317
            'title' => $this->getName(),
×
318
            'columns' => $this->resolveColumns($request)->mapToHeads($request),
×
319
            'actions' => $this->resolveActions($request)->mapToTableComponents($request),
×
320
            'data' => $this->paginate($request),
×
321
            'widgets' => $this->resolveWidgets($request)->all(),
×
322
            'perPageOptions' => $this->getPerPageOptions(),
×
323
            'filters' => $this->resolveFilters($request)
×
324
                ->renderable()
×
325
                ->map(function (RenderableFilter $filter) use ($request): array {
×
326
                    return $filter->toField()->toFormComponent($request, $this->getModelInstance());
×
327
                })
×
328
                ->all(),
×
329
            'activeFilters' => $this->resolveFilters($request)->active($request)->count(),
×
330
        ]);
×
331
    }
332

333
    /**
334
     * Get the create representation of the resource.
335
     */
336
    public function toCreate(Request $request): array
337
    {
338
        return array_merge($this->toArray(), [
×
339
            'title' => __('Create :model', ['model' => $this->getModelName()]),
×
340
            'model' => $model = $this->getModelInstance(),
×
341
            'action' => $this->getUri(),
×
342
            'method' => 'POST',
×
343
            'fields' => $this->resolveFields($request)->mapToFormComponents($request, $model),
×
344
        ]);
×
345
    }
346

347
    /**
348
     * Get the edit representation of the resource.
349
     */
350
    public function toEdit(Request $request, Model $model): array
351
    {
352
        return array_merge($this->toArray(), [
×
353
            'title' => '',
×
354
            'model' => $model,
×
355
            'action' => $this->modelUrl($model),
×
356
            'method' => 'PATCH',
×
357
            'fields' => $this->resolveFields($request)->mapToFormComponents($request, $model),
×
358
        ]);
×
359
    }
360
}
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

© 2026 Coveralls, Inc