create profile api's with tests
This commit is contained in:
107
app/Facades/File/File.php
Normal file
107
app/Facades/File/File.php
Normal file
@@ -0,0 +1,107 @@
|
||||
<?php
|
||||
|
||||
namespace App\Facades\File;
|
||||
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
use Illuminate\Http\File as HttpFile;
|
||||
use Illuminate\Http\UploadedFile;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
class File
|
||||
{
|
||||
public function save(HttpFile|UploadedFile $file, string $path, string $name = null, string $disk = 'public'): string
|
||||
{
|
||||
return Storage::disk($disk)->putFileAs(
|
||||
$path,
|
||||
$file,
|
||||
$name ?? Str::uuid() . '.' . $file->extension()
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $filePath
|
||||
* @param bool $url_is_absolute
|
||||
* @param string $disk
|
||||
* @return void
|
||||
* @throws \InvalidArgumentException when filePath is empty.
|
||||
*/
|
||||
public function delete(string $filePath, bool $url_is_absolute = false, string $disk = 'public'): void
|
||||
{
|
||||
if (!$filePath){
|
||||
throw new \InvalidArgumentException('File path is invalid.');
|
||||
}
|
||||
|
||||
if ($url_is_absolute) {
|
||||
$needle = 'storage/';
|
||||
$pos = strpos($filePath, $needle);
|
||||
$filePath = substr($filePath, $pos + strlen($needle));
|
||||
}
|
||||
|
||||
if (Storage::disk($disk)->exists($filePath)) {
|
||||
Storage::disk($disk)->delete($filePath);
|
||||
}
|
||||
}
|
||||
|
||||
public function deleteContent($file_path): bool
|
||||
{
|
||||
if (file_exists($file_path)) {
|
||||
file_put_contents($file_path, '');
|
||||
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public function tail($file_path, $lines = 100, $buffer = 2048): bool|string
|
||||
{
|
||||
// Open file
|
||||
$file = @fopen($file_path, "rb");
|
||||
if ($file === false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Jump to last character
|
||||
fseek($file, -1, SEEK_END);
|
||||
|
||||
// Read it and adjust line number if necessary
|
||||
// (Otherwise the result would be wrong if file doesn't end with a blank line)
|
||||
if (fread($file, 1) != "\n") {
|
||||
$lines -= 1;
|
||||
}
|
||||
|
||||
// Start reading
|
||||
$output = '';
|
||||
$chunk = '';
|
||||
|
||||
// While we would like more
|
||||
while (ftell($file) > 0 && $lines >= 0) {
|
||||
|
||||
// Figure out how far back we should jump
|
||||
$seek = min(ftell($file), $buffer);
|
||||
|
||||
// Do the jump (backwards, relative to where we are)
|
||||
fseek($file, -$seek, SEEK_CUR);
|
||||
|
||||
// Read a chunk and prepend it to our output
|
||||
$output = ($chunk = fread($file, $seek)) . $output;
|
||||
|
||||
// Jump back to where we started reading
|
||||
fseek($file, -mb_strlen($chunk, '8bit'), SEEK_CUR);
|
||||
|
||||
// Decrease our line counter
|
||||
$lines -= substr_count($chunk, "\n");
|
||||
}
|
||||
|
||||
// While we have too many lines
|
||||
// (Because of buffer size we might have read too many)
|
||||
while ($lines++ < 0) {
|
||||
|
||||
// Find first newline and remove all text before that
|
||||
$output = substr($output, strpos($output, "\n") + 1);
|
||||
}
|
||||
|
||||
// Close file and return
|
||||
fclose($file);
|
||||
return trim($output);
|
||||
}
|
||||
}
|
||||
13
app/Facades/File/FileFacade.php
Normal file
13
app/Facades/File/FileFacade.php
Normal file
@@ -0,0 +1,13 @@
|
||||
<?php
|
||||
|
||||
namespace App\Facades\File;
|
||||
|
||||
use Illuminate\Support\Facades\Facade;
|
||||
|
||||
class FileFacade extends Facade
|
||||
{
|
||||
protected static function getFacadeAccessor(): string
|
||||
{
|
||||
return 'file';
|
||||
}
|
||||
}
|
||||
78
app/Http/Controllers/V3/ProfileController.php
Normal file
78
app/Http/Controllers/V3/ProfileController.php
Normal file
@@ -0,0 +1,78 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\V3;
|
||||
|
||||
use App\Facades\File\FileFacade;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Requests\V3\Profile\ChangePasswordRequest;
|
||||
use App\Http\Requests\V3\Profile\EditRequest;
|
||||
use App\Http\Traits\ApiResponse;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Support\Facades\Hash;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
|
||||
class ProfileController extends Controller
|
||||
{
|
||||
use ApiResponse;
|
||||
public function info(): JsonResponse
|
||||
{
|
||||
$user = Auth::user();
|
||||
|
||||
return $this->successResponse([
|
||||
'username' => $user->username,
|
||||
'first_name' => $user->first_name,
|
||||
'last_name' => $user->last_name,
|
||||
'name' => $user->name,
|
||||
'last_login' => $user->last_login,
|
||||
'major' => $user->major,
|
||||
'degree' => $user->degree,
|
||||
'mobile' => $user->mobile,
|
||||
'avatar' => $user->avatar,
|
||||
]);
|
||||
}
|
||||
|
||||
public function edit(EditRequest $request): JsonResponse
|
||||
{
|
||||
$user = Auth::user();
|
||||
|
||||
if ($request->has('avatar'))
|
||||
{
|
||||
if ($user->avatar) {
|
||||
FileFacade::delete($user->avatar);
|
||||
}
|
||||
$destinationPath = 'avatar/' . $user->username;
|
||||
$filename = time() .".". $request->file('avatar')->getClientOriginalExtension();
|
||||
$avatar = FileFacade::save($request->avatar, $destinationPath, $filename);
|
||||
}
|
||||
|
||||
$user->update([
|
||||
'first_name' => $request->first_name,
|
||||
'last_name' => $request->last_name,
|
||||
'major' => $request->major,
|
||||
'degree' => $request->degree,
|
||||
'mobile' => $request->mobile,
|
||||
'avatar' => $avatar ?? $user->avatar
|
||||
]);
|
||||
|
||||
return $this->successResponse();
|
||||
}
|
||||
|
||||
public function changePassword(ChangePasswordRequest $request): JsonResponse
|
||||
{
|
||||
$user = Auth::user();
|
||||
|
||||
if (! Hash::check($request->current_password, $user->password))
|
||||
{
|
||||
return $this->errorResponse(__('messages.incorrect_current_password'));
|
||||
}
|
||||
|
||||
$user->update([
|
||||
'password' => Hash::make($request->new_password)
|
||||
]);
|
||||
|
||||
return $this->successResponse();
|
||||
|
||||
}
|
||||
}
|
||||
29
app/Http/Requests/V3/Profile/ChangePasswordRequest.php
Normal file
29
app/Http/Requests/V3/Profile/ChangePasswordRequest.php
Normal file
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Requests\V3\Profile;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class ChangePasswordRequest extends FormRequest
|
||||
{
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*/
|
||||
public function authorize(): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array<string, \Illuminate\Contracts\Validation\ValidationRule|array<mixed>|string>
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
'current_password' => 'required|string|regex:/^(?=.*[a-zA-Z])(?=.*\d).+$/|min:8',
|
||||
'new_password' => 'required|string|regex:/^(?=.*[a-zA-Z])(?=.*\d).+$/|min:8',
|
||||
];
|
||||
}
|
||||
}
|
||||
33
app/Http/Requests/V3/Profile/EditRequest.php
Normal file
33
app/Http/Requests/V3/Profile/EditRequest.php
Normal file
@@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Requests\V3\Profile;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class EditRequest extends FormRequest
|
||||
{
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*/
|
||||
public function authorize(): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array<string, \Illuminate\Contracts\Validation\ValidationRule|array<mixed>|string>
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
'first_name' => 'required|string',
|
||||
'last_name' => 'required|string',
|
||||
'degree' => 'required',
|
||||
'major' => 'required',
|
||||
'mobile' => 'required|regex:/^09\d{9}$/|numeric|digits:11',
|
||||
'avatar' => 'mimes:png,jpg,jpeg|max:2048'
|
||||
];
|
||||
}
|
||||
}
|
||||
30
app/Providers/FileServiceProvider.php
Normal file
30
app/Providers/FileServiceProvider.php
Normal file
@@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
namespace App\Providers;
|
||||
|
||||
use App\Facades\File\File;
|
||||
use Illuminate\Support\ServiceProvider;
|
||||
|
||||
class FileServiceProvider extends ServiceProvider
|
||||
{
|
||||
/**
|
||||
* Register services.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function register(): void
|
||||
{
|
||||
$this->app->bind('file', function () {
|
||||
return new File();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Bootstrap services.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function boot()
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -69,8 +69,8 @@ class RouteServiceProvider extends ServiceProvider
|
||||
->group(base_path('routes/v2.php'));
|
||||
|
||||
Route::prefix('api/v3')
|
||||
->name('v3')
|
||||
->middleware('web', 'auth', 'confirmUser')
|
||||
->name('v3.')
|
||||
->middleware(['web', 'auth', 'confirmUser'])
|
||||
->namespace($this->namespace)
|
||||
->group(base_path('routes/v3.php'));
|
||||
Route::prefix('api')
|
||||
|
||||
Reference in New Issue
Block a user