feat(user-profile): add avatar upload functionality and update UserProfile entity
This commit is contained in:
@@ -6,8 +6,10 @@ use App\Auth\Entity\User;
|
||||
use App\Auth\Repository\UserRepository;
|
||||
use App\Shared\Constant\ErrorCodes;
|
||||
use App\Shared\Controller\BaseController;
|
||||
use App\Shared\Service\FileValidatorService;
|
||||
use App\UserProfile\Entity\UserProfile;
|
||||
use App\UserProfile\Repository\UserProfileRepository;
|
||||
use Symfony\Component\Uid\Uuid;
|
||||
use Symfony\Component\HttpFoundation\JsonResponse;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\Routing\Attribute\Route;
|
||||
@@ -22,8 +24,64 @@ class UserProfileController extends BaseController
|
||||
public function __construct(
|
||||
private readonly UserProfileRepository $repository,
|
||||
private readonly UserRepository $userRepository,
|
||||
private readonly FileValidatorService $fileValidator,
|
||||
private readonly string $projectDir,
|
||||
) {}
|
||||
|
||||
#[OA\Post(
|
||||
path: '/api/v1/user-profile/avatar',
|
||||
summary: 'Upload the current user\'s profile avatar',
|
||||
security: [['bearerAuth' => []]],
|
||||
requestBody: new OA\RequestBody(
|
||||
required: true,
|
||||
content: new OA\MediaType(
|
||||
mediaType: 'application/octet-stream',
|
||||
schema: new OA\Schema(type: 'string', format: 'binary')
|
||||
)
|
||||
),
|
||||
responses: [
|
||||
new OA\Response(response: 200, description: 'Avatar uploaded'),
|
||||
new OA\Response(response: 422, description: 'Invalid file'),
|
||||
]
|
||||
)]
|
||||
#[Route('/api/v1/user-profile/avatar', methods: ['POST'])]
|
||||
public function uploadAvatar(Request $request, #[CurrentUser] User $user): JsonResponse
|
||||
{
|
||||
$profile = $this->repository->findByUser($user) ?? new UserProfile($user);
|
||||
|
||||
$content = $request->getContent();
|
||||
if ($content === '') {
|
||||
return $this->error(ErrorCodes::ERR_VALIDATION_001, 'فایلی ارسال نشده است', 422);
|
||||
}
|
||||
$disposition = $request->headers->get('Content-Disposition', '');
|
||||
preg_match('/filename=["\']?([^"\';\s]+)["\']?/i', $disposition, $m);
|
||||
$filename = $m[1] ?? 'avatar.jpg';
|
||||
|
||||
$tmpPath = sys_get_temp_dir() . '/' . uniqid('avatar_', true);
|
||||
file_put_contents($tmpPath, $content);
|
||||
|
||||
try {
|
||||
$safeFilename = $this->fileValidator->sanitizeFilename($filename);
|
||||
$this->fileValidator->detectMimeType($tmpPath);
|
||||
|
||||
$year = date('Y'); $month = date('m');
|
||||
$dir = $this->projectDir . '/public/uploads/avatars/' . $year . '-' . $month;
|
||||
if (!is_dir($dir)) mkdir($dir, 0755, true);
|
||||
|
||||
$storedName = uniqid('', true) . '_' . $safeFilename;
|
||||
rename($tmpPath, $dir . '/' . $storedName);
|
||||
|
||||
$url = '/uploads/avatars/' . $year . '-' . $month . '/' . $storedName;
|
||||
$profile->setAvatar($url);
|
||||
$this->repository->save($profile);
|
||||
|
||||
return $this->success(['avatar' => $url, 'url' => $url]);
|
||||
} catch (\Throwable $e) {
|
||||
if (file_exists($tmpPath)) unlink($tmpPath);
|
||||
return $this->error(ErrorCodes::ERR_VALIDATION_001, $e->getMessage(), 422);
|
||||
}
|
||||
}
|
||||
|
||||
#[Route('/api/v1/user-profile', methods: ['POST'])]
|
||||
public function create(Request $request, #[CurrentUser] User $user): JsonResponse
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user