Skip to content

Commit bb7db8c

Browse files
Update API
1 parent 8704ea0 commit bb7db8c

File tree

7 files changed

+315
-0
lines changed

7 files changed

+315
-0
lines changed
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
<?php
2+
3+
use Illuminate\Database\Migrations\Migration;
4+
use Illuminate\Database\Schema\Blueprint;
5+
use Illuminate\Support\Facades\Schema;
6+
7+
return new class () extends Migration {
8+
public function up(): void
9+
{
10+
if (Schema::hasTable('user_settings')) {
11+
return;
12+
}
13+
14+
Schema::create('user_settings', function (Blueprint $table): void {
15+
$table->id();
16+
$table->string('user_type'); // customer, admin, etc.
17+
$table->unsignedBigInteger('user_id');
18+
$table->string('key'); // setting key like 'biometric_enabled', 'notifications', etc.
19+
$table->json('value'); // setting value stored as JSON
20+
$table->timestamps();
21+
22+
$table->unique(['user_type', 'user_id', 'key']);
23+
$table->index(['user_type', 'user_id']);
24+
$table->index('key');
25+
});
26+
}
27+
28+
public function down(): void
29+
{
30+
Schema::dropIfExists('user_settings');
31+
}
32+
};

routes/api.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,10 @@
2626
Route::post('update/avatar', 'ProfileController@updateAvatar');
2727
Route::put('update/password', 'ProfileController@updatePassword');
2828

29+
// Settings endpoints
30+
Route::get('settings', 'ProfileController@getSettings');
31+
Route::put('settings', 'ProfileController@updateSettings');
32+
2933
// Device token management (authenticated endpoints)
3034
Route::get('device-tokens', 'DeviceTokenController@index');
3135
Route::put('device-tokens/{id}', 'DeviceTokenController@update')->wherePrimaryKey();

src/Http/Controllers/AuthenticationController.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
<?php
22

33
namespace Botble\Api\Http\Controllers;
4+
45
use App\Models\User;
56
use Botble\Api\Facades\ApiHelper;
67
use Botble\Api\Http\Requests\CheckEmailRequest;

src/Http/Controllers/ProfileController.php

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,9 @@
33
namespace Botble\Api\Http\Controllers;
44

55
use Botble\Api\Facades\ApiHelper;
6+
use Botble\Api\Http\Requests\UpdateUserSettingsRequest;
67
use Botble\Api\Http\Resources\UserResource;
8+
use Botble\Api\Models\UserSetting;
79
use Botble\Base\Facades\BaseHelper;
810
use Botble\Base\Http\Responses\BaseHttpResponse;
911
use Botble\Media\Facades\RvMedia;
@@ -168,4 +170,92 @@ public function updatePassword(Request $request, BaseHttpResponse $response)
168170

169171
return $response->setMessage(__('Update password successfully!'));
170172
}
173+
174+
/**
175+
* Get user settings
176+
*
177+
* @group Profile
178+
* @authenticated
179+
*/
180+
public function getSettings(Request $request, BaseHttpResponse $response)
181+
{
182+
$user = $request->user();
183+
$userType = $this->getUserType($user);
184+
185+
$settings = UserSetting::getUserSettings($userType, $user->getKey());
186+
187+
// Set default values for common settings
188+
$defaultSettings = [
189+
'biometric_enabled' => false,
190+
'notification_enabled' => true,
191+
'language' => 'en',
192+
'currency' => 'USD',
193+
'theme' => 'light',
194+
'timezone' => 'UTC',
195+
];
196+
197+
$settings = array_merge($defaultSettings, $settings);
198+
199+
return $response->setData($settings);
200+
}
201+
202+
/**
203+
* Update user settings
204+
*
205+
* @bodyParam biometric_enabled boolean Enable/disable biometric authentication.
206+
* @bodyParam notification_enabled boolean Enable/disable notifications.
207+
* @bodyParam language string User's preferred language.
208+
* @bodyParam currency string User's preferred currency.
209+
* @bodyParam theme string User's preferred theme (light, dark, auto).
210+
* @bodyParam timezone string User's timezone.
211+
*
212+
* @group Profile
213+
* @authenticated
214+
*/
215+
public function updateSettings(UpdateUserSettingsRequest $request, BaseHttpResponse $response)
216+
{
217+
try {
218+
$user = $request->user();
219+
$userType = $this->getUserType($user);
220+
221+
$validatedData = $request->validated();
222+
223+
// Update each setting individually
224+
foreach ($validatedData as $key => $value) {
225+
UserSetting::setUserSetting($userType, $user->getKey(), $key, $value);
226+
}
227+
228+
// Get updated settings to return
229+
$updatedSettings = UserSetting::getUserSettings($userType, $user->getKey());
230+
231+
return $response
232+
->setData([
233+
'message' => __('Settings updated successfully!'),
234+
'settings' => $updatedSettings,
235+
])
236+
->setMessage(__('Settings updated successfully!'));
237+
} catch (Exception $ex) {
238+
return $response
239+
->setError()
240+
->setMessage($ex->getMessage());
241+
}
242+
}
243+
244+
/**
245+
* Get user type based on model class
246+
*/
247+
protected function getUserType($user): string
248+
{
249+
$class = get_class($user);
250+
251+
if (str_contains($class, 'Customer')) {
252+
return 'customer';
253+
}
254+
255+
if (str_contains($class, 'User')) {
256+
return 'admin';
257+
}
258+
259+
return 'user';
260+
}
171261
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
<?php
2+
3+
namespace Botble\Api\Http\Requests;
4+
5+
class UpdateUserSettingsRequest extends ApiRequest
6+
{
7+
public function rules(): array
8+
{
9+
return [
10+
'biometric_enabled' => ['sometimes', 'boolean'],
11+
'notification_enabled' => ['sometimes', 'boolean'],
12+
'language' => ['sometimes', 'string', 'max:10'],
13+
'currency' => ['sometimes', 'string', 'max:10'],
14+
'theme' => ['sometimes', 'string', 'in:light,dark,auto'],
15+
'timezone' => ['sometimes', 'string', 'max:50'],
16+
];
17+
}
18+
19+
public function messages(): array
20+
{
21+
return [
22+
'biometric_enabled.boolean' => 'Biometric enabled must be true or false.',
23+
'notification_enabled.boolean' => 'Notification enabled must be true or false.',
24+
'language.string' => 'Language must be a valid string.',
25+
'language.max' => 'Language must not exceed 10 characters.',
26+
'currency.string' => 'Currency must be a valid string.',
27+
'currency.max' => 'Currency must not exceed 10 characters.',
28+
'theme.in' => 'Theme must be one of: light, dark, auto.',
29+
'timezone.string' => 'Timezone must be a valid string.',
30+
'timezone.max' => 'Timezone must not exceed 50 characters.',
31+
];
32+
}
33+
}

src/Http/Resources/UserResource.php

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
namespace Botble\Api\Http\Resources;
44

55
use Botble\ACL\Models\User;
6+
use Botble\Api\Models\UserSetting;
67
use Illuminate\Http\Resources\Json\JsonResource;
78

89
/**
@@ -21,6 +22,24 @@ public function toArray($request): array
2122
$data['last_name'] = $this->last_name;
2223
}
2324

25+
// Get user type for settings
26+
$userType = $this->getUserType();
27+
28+
// Get user settings
29+
$settings = UserSetting::getUserSettings($userType, $this->getKey());
30+
31+
// Set default values for common settings
32+
$defaultSettings = [
33+
'biometric_enabled' => false,
34+
'notification_enabled' => true,
35+
'language' => 'en',
36+
'currency' => 'USD',
37+
'theme' => 'light',
38+
'timezone' => 'UTC',
39+
];
40+
41+
$settings = array_merge($defaultSettings, $settings);
42+
2443
return [
2544
...$data,
2645
'email' => $this->email,
@@ -30,6 +49,25 @@ public function toArray($request): array
3049
'dob' => $this->dob,
3150
'gender' => $this->gender,
3251
'description' => $this->description,
52+
'settings' => $settings,
3353
];
3454
}
55+
56+
/**
57+
* Get user type based on model class
58+
*/
59+
protected function getUserType(): string
60+
{
61+
$class = get_class($this->resource);
62+
63+
if (str_contains($class, 'Customer')) {
64+
return 'customer';
65+
}
66+
67+
if (str_contains($class, 'User')) {
68+
return 'admin';
69+
}
70+
71+
return 'user';
72+
}
3573
}

src/Models/UserSetting.php

Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
<?php
2+
3+
namespace Botble\Api\Models;
4+
5+
use Botble\Base\Models\BaseModel;
6+
use Botble\Base\Models\Concerns\HasUuidsOrIntegerIds;
7+
use Illuminate\Database\Eloquent\Relations\MorphTo;
8+
9+
class UserSetting extends BaseModel
10+
{
11+
use HasUuidsOrIntegerIds;
12+
13+
protected $table = 'user_settings';
14+
15+
protected $fillable = [
16+
'user_type',
17+
'user_id',
18+
'key',
19+
'value',
20+
];
21+
22+
protected $casts = [
23+
'value' => 'array',
24+
];
25+
26+
public function user(): MorphTo
27+
{
28+
return $this->morphTo('user', 'user_type', 'user_id');
29+
}
30+
31+
/**
32+
* Get a setting value for a user
33+
*/
34+
public static function getUserSetting(string $userType, int $userId, string $key, $default = null)
35+
{
36+
$setting = static::query()
37+
->where('user_type', $userType)
38+
->where('user_id', $userId)
39+
->where('key', $key)
40+
->first();
41+
42+
return $setting ? $setting->value : $default;
43+
}
44+
45+
/**
46+
* Set a setting value for a user
47+
*/
48+
public static function setUserSetting(string $userType, int $userId, string $key, $value): self
49+
{
50+
return static::query()->updateOrCreate(
51+
[
52+
'user_type' => $userType,
53+
'user_id' => $userId,
54+
'key' => $key,
55+
],
56+
[
57+
'value' => $value,
58+
]
59+
);
60+
}
61+
62+
/**
63+
* Get all settings for a user
64+
*/
65+
public static function getUserSettings(string $userType, int $userId): array
66+
{
67+
$settings = static::query()
68+
->where('user_type', $userType)
69+
->where('user_id', $userId)
70+
->get();
71+
72+
$result = [];
73+
foreach ($settings as $setting) {
74+
$result[$setting->key] = $setting->value;
75+
}
76+
77+
return $result;
78+
}
79+
80+
/**
81+
* Set multiple settings for a user
82+
*/
83+
public static function setUserSettings(string $userType, int $userId, array $settings): void
84+
{
85+
foreach ($settings as $key => $value) {
86+
static::setUserSetting($userType, $userId, $key, $value);
87+
}
88+
}
89+
90+
/**
91+
* Delete a setting for a user
92+
*/
93+
public static function deleteUserSetting(string $userType, int $userId, string $key): bool
94+
{
95+
return static::query()
96+
->where('user_type', $userType)
97+
->where('user_id', $userId)
98+
->where('key', $key)
99+
->delete() > 0;
100+
}
101+
102+
/**
103+
* Get biometric setting for a user
104+
*/
105+
public static function getBiometricEnabled(string $userType, int $userId): bool
106+
{
107+
return (bool) static::getUserSetting($userType, $userId, 'biometric_enabled', false);
108+
}
109+
110+
/**
111+
* Set biometric setting for a user
112+
*/
113+
public static function setBiometricEnabled(string $userType, int $userId, bool $enabled): self
114+
{
115+
return static::setUserSetting($userType, $userId, 'biometric_enabled', $enabled);
116+
}
117+
}

0 commit comments

Comments
 (0)