Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
18 / 18
100.00% covered (success)
100.00%
3 / 3
CRAP
100.00% covered (success)
100.00%
1 / 1
Read
100.00% covered (success)
100.00%
18 / 18
100.00% covered (success)
100.00%
3 / 3
6
100.00% covered (success)
100.00%
1 / 1
 read
100.00% covered (success)
100.00%
16 / 16
100.00% covered (success)
100.00%
1 / 1
4
 modifyReadQuery
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 afterRead
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
1<?php
2
3declare(strict_types=1);
4
5namespace DevToolbelt\LaravelFastCrud\Actions;
6
7use Illuminate\Database\Eloquent\Builder;
8use Illuminate\Database\Eloquent\Model;
9use Illuminate\Http\JsonResponse;
10use Illuminate\Support\Str;
11use Psr\Http\Message\ResponseInterface;
12
13/**
14 * Provides the read (GET by ID) action for CRUD controllers.
15 *
16 * Retrieves a single model instance by its identifier field (configurable).
17 *
18 * @method string modelClassName() Returns the Eloquent model class name
19 * @method JsonResponse|ResponseInterface answerInvalidUuid() Returns invalid UUID error response
20 * @method JsonResponse|ResponseInterface answerRecordNotFound() Returns not found error response
21 * @method JsonResponse|ResponseInterface answerSuccess(array $data, array $meta = []) Returns success response
22 */
23trait Read
24{
25    /**
26     * Retrieves a single record by its identifier field.
27     *
28     * @param string $id The identifier value of the record
29     * @param string|null $method Model serialization method (default from config or 'toArray')
30     * @return JsonResponse|ResponseInterface JSON response with the record data or error response
31     */
32    public function read(string $id, ?string $method = null): JsonResponse|ResponseInterface
33    {
34        $method = $method ?? config('devToolbelt.fast-crud.read.method', 'toArray');
35        $findField = config('devToolbelt.fast-crud.read.find_field')
36            ?? config('devToolbelt.fast-crud.global.find_field', 'id');
37
38        $isUuid = config('devToolbelt.fast-crud.read.find_field_is_uuid')
39            ?? config('devToolbelt.fast-crud.global.find_field_is_uuid', false);
40
41        if ($isUuid && !Str::isUuid($id)) {
42            return $this->answerInvalidUuid();
43        }
44
45        $modelName = $this->modelClassName();
46        $query = $modelName::query()->where($findField, $id);
47        $this->modifyReadQuery($query);
48
49        /** @var Model|null $record */
50        $record = $query->first();
51
52        if ($record === null) {
53            return $this->answerRecordNotFound();
54        }
55
56        $response = $this->answerSuccess($record->{$method}());
57        $this->afterRead($record);
58
59        return $response;
60    }
61
62    /**
63     * Hook to modify the read query before execution.
64     *
65     * Override this method to add eager loading, additional conditions,
66     * or scopes to the query.
67     *
68     * @param Builder $query The query builder instance
69     *
70     * @example
71     * ```php
72     * protected function modifyReadQuery(Builder $query): void
73     * {
74     *     $query->with(['category', 'tags']);
75     * }
76     * ```
77     */
78    protected function modifyReadQuery(Builder $query): void
79    {
80    }
81
82    /**
83     * Hook called after the record has been read and response prepared.
84     *
85     * Override this method to perform post-read actions,
86     * such as logging, analytics, or cache warming.
87     *
88     * @param Model $record The model instance that was read
89     */
90    protected function afterRead(Model $record): void
91    {
92    }
93}