1+ <?php
2+
3+ namespace Kroderdev \LaravelMicroserviceCore \Models ;
4+
5+ use Illuminate \Database \Eloquent \Model as BaseModel ;
6+ use Illuminate \Pagination \LengthAwarePaginator ;
7+ use Illuminate \Support \Collection ;
8+ use Illuminate \Support \Str ;
9+ use Kroderdev \LaravelMicroserviceCore \Contracts \ApiGatewayClientInterface ;
10+ use Kroderdev \LaravelMicroserviceCore \Interfaces \ApiModelContract ;
11+ use Kroderdev \LaravelMicroserviceCore \Traits \ApiModelTrait ;
12+
13+ abstract class Model extends BaseModel implements ApiModelContract
14+ {
15+ use ApiModelTrait;
16+
17+ /**
18+ * Endpoint for this model. Defaults to plural kebab of the class name.
19+ */
20+ protected static string $ endpoint = '' ;
21+
22+ /**
23+ * Return the endpoint for the model.
24+ */
25+ protected static function endpoint (): string
26+ {
27+ if (static ::$ endpoint !== '' ) {
28+ return static ::$ endpoint ;
29+ }
30+
31+ return '/ ' . Str::kebab (Str::pluralStudly (class_basename (static ::class)));
32+ }
33+
34+ /**
35+ * Get the ApiGateway client instance.
36+ */
37+ protected static function client (): ApiGatewayClientInterface
38+ {
39+ return app (ApiGatewayClientInterface::class);
40+ }
41+
42+ /**
43+ * Get all models.
44+ */
45+ public static function all ($ columns = ['* ' ]): Collection
46+ {
47+ $ response = static ::client ()->get (static ::endpoint ());
48+ $ data = static ::parseResponse ($ response );
49+
50+ return static ::fromCollection ($ data ['data ' ] ?? $ data );
51+ }
52+
53+ /**
54+ * Find a model by its primary key.
55+ */
56+ public static function find ($ id , $ columns = ['* ' ]): ?self
57+ {
58+ $ response = static ::client ()->get (static ::endpoint () . '/ ' . $ id );
59+ $ data = static ::parseResponse ($ response );
60+
61+ return static ::fromResponse ($ data );
62+ }
63+
64+ /**
65+ * Paginate models from the API.
66+ */
67+ public static function paginate ($ perPage = 15 , $ columns = ['* ' ], $ pageName = 'page ' , $ page = null ): LengthAwarePaginator
68+ {
69+ $ page = $ page ?: LengthAwarePaginator::resolveCurrentPage ($ pageName );
70+ $ query = [$ pageName => $ page , 'per_page ' => $ perPage ];
71+ $ response = static ::client ()->get (static ::endpoint (), $ query );
72+ $ data = static ::parseResponse ($ response );
73+
74+ return static ::fromPaginatedResponse ($ data );
75+ }
76+
77+ /**
78+ * Create a model via the API.
79+ */
80+ public static function create (array $ attributes = []): self |null
81+ {
82+ $ response = static ::client ()->post (static ::endpoint (), $ attributes );
83+ $ data = static ::parseResponse ($ response );
84+
85+ return static ::fromResponse ($ data );
86+ }
87+
88+ /**
89+ * Save the model via the API.
90+ */
91+ public function save (array $ options = []): bool
92+ {
93+ if ($ this ->exists ) {
94+ $ response = static ::client ()->put (static ::endpoint () . '/ ' . $ this ->getKey (), $ this ->attributesToArray ());
95+ } else {
96+ $ response = static ::client ()->post (static ::endpoint (), $ this ->attributesToArray ());
97+ }
98+
99+ $ data = static ::parseResponse ($ response );
100+ if ($ fresh = static ::fromResponse ($ data )) {
101+ $ this ->fill ($ fresh ->attributesToArray ());
102+ $ this ->exists = true ;
103+ $ this ->syncOriginal ();
104+ }
105+
106+ return true ;
107+ }
108+
109+ /**
110+ * Delete the model via the API.
111+ */
112+ public function delete (): bool
113+ {
114+ $ response = static ::client ()->delete (static ::endpoint () . '/ ' . $ this ->getKey ());
115+
116+ if (is_object ($ response ) && method_exists ($ response , 'successful ' )) {
117+ return $ response ->successful ();
118+ }
119+
120+ return true ;
121+ }
122+
123+ /**
124+ * Refresh the model from the API.
125+ */
126+ public function refresh (): static
127+ {
128+ $ response = static ::client ()->get (static ::endpoint () . '/ ' . $ this ->getKey ());
129+ $ data = static ::parseResponse ($ response );
130+ if ($ fresh = static ::fromResponse ($ data )) {
131+ $ this ->fill ($ fresh ->attributesToArray ());
132+ $ this ->syncOriginal ();
133+ }
134+
135+ return $ this ;
136+ }
137+
138+ /**
139+ * Normalize different response types to array.
140+ */
141+ protected static function parseResponse ($ response ): array
142+ {
143+ if ($ response === null ) {
144+ return [];
145+ }
146+
147+ if (is_array ($ response )) {
148+ return $ response ;
149+ }
150+
151+ if ($ response instanceof Collection) {
152+ return $ response ->toArray ();
153+ }
154+
155+ if (method_exists ($ response , 'json ' )) {
156+ return $ response ->json ();
157+ }
158+
159+ return (array ) $ response ;
160+ }
161+ }
0 commit comments