Skip to content

Commit

Permalink
#223 Added the ability to upload an avatar when creating a user.
Browse files Browse the repository at this point in the history
  • Loading branch information
simba77 committed Jul 5, 2022
1 parent 849491a commit 2cbc6a3
Show file tree
Hide file tree
Showing 6 changed files with 79 additions and 24 deletions.
11 changes: 10 additions & 1 deletion modules/johncms/admin/src/Controllers/Users/UsersController.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
use Johncms\Admin\Resources\Users\UserResource;
use Johncms\Controller\BaseAdminController;
use Johncms\Exceptions\ValidationException;
use Johncms\Files\FileStorage;
use Johncms\Http\Request;
use Johncms\Http\Response\RedirectResponse;
use Johncms\Users\Role;
Expand Down Expand Up @@ -90,12 +91,20 @@ public function create(CreateUserForm $createUserForm): string
/**
* @throws Throwable
*/
public function store(UserManager $userManager, CreateUserForm $createUserForm): string | RedirectResponse
public function store(UserManager $userManager, CreateUserForm $createUserForm, FileStorage $fileStorage): string | RedirectResponse
{
try {
// Validate the form
$createUserForm->validate();
$fields = $createUserForm->getRequestValues();
if (! empty($fields['avatar'])) {
try {
$fields['avatar_id'] = $fileStorage->saveUploadedFile($fields['avatar'], 'users/avatar')->id;
unset($fields['avatar']);
} catch (Throwable) {
}
}

$fields['confirmed'] = true;
$fields['email_confirmed'] = true;
$userManager->create($fields);
Expand Down
16 changes: 16 additions & 0 deletions modules/johncms/admin/src/Forms/CreateUserForm.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
namespace Johncms\Admin\Forms;

use Johncms\Forms\AbstractForm;
use Johncms\Forms\Inputs\InputFile;
use Johncms\Forms\Inputs\InputPassword;
use Johncms\Forms\Inputs\InputText;
use Johncms\Forms\Inputs\Select;
Expand Down Expand Up @@ -88,6 +89,21 @@ protected function prepareFormFields(): array
->setValue($this->getValue('email'))
->setValidationRules($emailValidator);

$fields['avatar'] = (new InputFile())
->setLabel(__('Avatar'))
->setPlaceholder(__('Select Avatar'))
->setNameAndId('avatar')
->setValidationRules(
[
'Optional',
'IsImage' => [
'image/jpeg',
'image/png',
'image/gif',
],
]
);

$fields['name'] = (new InputText())
->setLabel(__('Name'))
->setPlaceholder(__('Enter Name'))
Expand Down
2 changes: 1 addition & 1 deletion modules/johncms/admin/templates/users/create_user.phtml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

$this->layout('system::layout/default');
?>
<form method="post" class="mb-3 mw-750px" action="<?= $data['storeUrl'] ?>">
<form method="post" class="mb-3 mw-750px" action="<?= $data['storeUrl'] ?>" enctype="multipart/form-data">
<?= $this->fetch(
'system::forms/simple_form',
[
Expand Down
17 changes: 17 additions & 0 deletions system/src/Files/Exceptions/FileUploadException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<?php

/**
* This file is part of JohnCMS Content Management System.
*
* @copyright JohnCMS Community
* @license https://opensource.org/licenses/GPL-3.0 GPL-3.0
* @link https://johncms.com JohnCMS Project
*/

declare(strict_types=1);

namespace Johncms\Files\Exceptions;

class FileUploadException extends \RuntimeException
{
}
55 changes: 34 additions & 21 deletions system/src/Files/FileStorage.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
use GuzzleHttp\Psr7\UploadedFile;
use Johncms\Files\Exceptions\BadRequest;
use Johncms\Files\Exceptions\FileNotFound;
use Johncms\Files\Exceptions\FileUploadException;
use Johncms\Http\Request;
use League\Flysystem\FilesystemException;

Expand All @@ -24,47 +25,59 @@ class FileStorage
/**
* Saving files from the request
*
* @param string $field_name
* @param string $working_dir
* @param string $fieldName
* @param string $workingDir
* @param bool $multiple
* @return Models\File|Models\File[]
* @throws FilesystemException
*/
public function saveFromRequest(string $field_name, string $working_dir, bool $multiple = false)
public function saveFromRequest(string $fieldName, string $workingDir, bool $multiple = false): Models\File | array
{
$request_files = di(Request::class)->getUploadedFiles();
if (! array_key_exists($field_name, $request_files)) {
throw new BadRequest(sprintf('There is no file field named "%s" in the request', $field_name));
$requestFiles = di(Request::class)->getUploadedFiles();
if (! array_key_exists($fieldName, $requestFiles)) {
throw new BadRequest(sprintf('There is no file field named "%s" in the request', $fieldName));
}

if ($multiple) {
if (! is_array($request_files[$field_name])) {
if (! is_array($requestFiles[$fieldName])) {
throw new BadRequest('Multiple fields are expected');
}
$uploaded_files = $request_files[$field_name];
$uploadedFiles = $requestFiles[$fieldName];
} else {
$uploaded_files = [$request_files[$field_name]];
$uploadedFiles = [$requestFiles[$fieldName]];
}

$saved_files = [];
/** @var UploadedFile $uploaded_file */
foreach ($uploaded_files as $uploaded_file) {
if ($uploaded_file->getError() !== 0) {
/** @var UploadedFile $uploadedFile */
foreach ($uploadedFiles as $uploadedFile) {
if ($uploadedFile->getError() !== 0) {
continue;
}
$saved_files[] = $this->saveUploadedFile($uploadedFile, $workingDir);
}

$tmp_file = $this->makeTmpName();
$uploaded_file->moveTo($tmp_file);

$saved_files[] = (new File($tmp_file))
->setFileName($uploaded_file->getClientFilename() ?? 'untitled_file')
->setParentDir($working_dir)
->save();
return $multiple ? $saved_files : $saved_files[0];
}

unlink($tmp_file);
/**
* @throws FilesystemException
*/
public function saveUploadedFile(UploadedFile $uploadedFile, string $workingDir): Models\File
{
if ($uploadedFile->getError() !== 0) {
throw new FileUploadException('File upload error');
}

return $multiple ? $saved_files : $saved_files[0];
$tmpName = $this->makeTmpName();
$uploadedFile->moveTo($tmpName);

$savedFile = (new File($tmpName))
->setFileName($uploadedFile->getClientFilename() ?? 'untitled_file')
->setParentDir($workingDir)
->save();

unlink($tmpName);
return $savedFile;
}

/**
Expand Down
2 changes: 1 addition & 1 deletion system/src/Users/UserManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,7 @@ public function checkCredentials(string $username, string $password): User
/**
* @throws FilesystemException
*/
protected function replaceAvatar(User $user, array $fields)
protected function replaceAvatar(User $user, array $fields): void
{
if (! empty($user->avatar_id) && $fields['avatar_id'] !== $user->avatar_id) {
$fileStorage = di(FileStorage::class);
Expand Down

0 comments on commit 2cbc6a3

Please sign in to comment.