Skip to content

Commit

Permalink
Created a working example in Users CRUD #23
Browse files Browse the repository at this point in the history
  • Loading branch information
Jovert Lota Palonpon committed Apr 4, 2019
1 parent e7fd7c4 commit d070b82
Show file tree
Hide file tree
Showing 8 changed files with 179 additions and 31 deletions.
21 changes: 19 additions & 2 deletions app/Http/Controllers/Api/V1/UsersController.php
Original file line number Diff line number Diff line change
Expand Up @@ -136,9 +136,26 @@ public function restore(Request $request, $id)
*
* @return Illuminate\Http\JsonResponse
*/
public function storeAvatar(Request $request, User $user)
public function storeAvatar(Request $request, User $user) : JsonResponse
{
return response()->json($request->input('avatar'));
if (! $user->upload($request->files->get('avatar'))) {
return response()->json('Unable to process the upload', 422);
}

return response()->json('Uploaded successfully!');
}

/**
* Destroy the user's avatar.
*
* @param Illuminate\Http\Request $request
* @param App\User $user
*
* @return Illuminate\Http\JsonResponse
*/
public function destroyAvatar(Request $request, User $user) : JsonResponse
{
return response()->json($user->destroyUpload());
}

/**
Expand Down
30 changes: 27 additions & 3 deletions app/Traits/UploadsFiles.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,25 +3,49 @@
namespace App\Traits;

use App\Utils\Uploader;
use Illuminate\Http\UploadedFile;

trait UploadsFiles
{
/**
* Handle the upload for the uploader, and update it's attributes.
*
* @param Illuminate\Http\UploadedFile
* @param mixed
*
* @return bool
*/
public function upload(UploadedFile $file)
public function upload($file)
{
$upload = Uploader::upload($this->getDirectory(), $file);

// The upload attributes should be stored.
foreach ($upload as $attribute => $value) {
$this->attributes[$attribute] = $value;
}

// Update the consumer.
return $this->update();
}

/**
* Destroy an upload.
*
* @return bool
*/
public function destroyUpload()
{
$upload = collect($this->attributes)
->only($this->uploadAttributes)
->toArray();

// The upload attributes should be cleared.
foreach ($this->uploadAttributes as $key => $attribute) {
$this->attributes[$attribute] = null;
}

// Remove the file(s) from the disk.
Uploader::destroy($upload);

// Update the consumer.
return $this->update();
}
}
15 changes: 15 additions & 0 deletions app/User.php
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,21 @@ class User extends Authenticatable implements JWTSubject, Uploader
'password', 'remember_token',
];

/**
* The attributes used for uploads.
*
* @var array
*/
protected $uploadAttributes = [
'directory',
'filename',
'original_filename',
'filesize',
'thumbnail_filesize',
'url',
'thumbnail_url'
];

/**
* Get the directory for uploads.
*
Expand Down
34 changes: 29 additions & 5 deletions app/Utils/Uploader.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,23 +5,24 @@
use Image;
use Storage;
use Illuminate\Support\Str;
use Illuminate\Http\UploadedFile;

class Uploader
{
/**
* Put the file into the storage.
*
* @param string $directory
* @param Illuminate\Http\UploadedFile $file
* @param mixed $file
*
* @return array
*/
public static function upload(string $directory, UploadedFile $file)
public static function upload(string $directory, $file)
{
$disk = config('filesystems.default');
$filename = str_random(64).'.'.$file->getClientOriginalExtension();
$original_filename = $file->getClientOriginalName();
$filesize = $file->getSize();
$thumbnail_filesize = null;

// Upload the file
$path = Storage::putFileAs($directory, $file, $filename);
Expand All @@ -42,15 +43,38 @@ public static function upload(string $directory, UploadedFile $file)
$fullThumbnailPath =
"{$fileSystemRoot}/{$thumbnailDirectory}/{$filename}";

Image::make($fullPath)
$image = Image::make($fullPath)
->fit(240)
->save($fullThumbnailPath, 95);

$thumbnail_filesize = Storage::size($thumbnailPath);
$thumbnail_url = Storage::url($thumbnailPath);
}

return compact([
'directory', 'filename', 'original_filename', 'url', 'thumbnail_url'
'directory',
'filename',
'original_filename',
'filesize',
'thumbnail_filesize',
'url',
'thumbnail_url'
]);
}

/**
* Destroy files from disk.
*
* @param array $upload
*
* @return bool
*/
public static function destroy(array $upload)
{
$path = "{$upload['directory']}/{$upload['filename']}";
$thumbnailPath =
"{$upload['directory']}/thumbnails/{$upload['filename']}";

return Storage::delete([$path, $thumbnailPath]);
}
}
6 changes: 5 additions & 1 deletion database/migrations/2014_10_12_000000_create_users_table.php
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,13 @@ public function up()
$table->date('birthdate', 'Y-m-d')->nullable();
$table->text('address')->nullable();

$table->text('path')->nullable();
$table->string('directory')->nullable();
$table->string('filename')->nullable();
$table->string('original_filename')->nullable();
$table->integer('filesize')->nullable();
$table->integer('thumbnail_filesize')->nullable();
$table->text('url')->nullable();
$table->text('thumbnail_url')->nullable();

$table->string('created_by')->nullable();
$table->string('updated_by')->nullable();
Expand Down
7 changes: 5 additions & 2 deletions resources/js/ui/Dropzone.js
Original file line number Diff line number Diff line change
Expand Up @@ -103,14 +103,15 @@ FileIcon = withStyles(theme => ({
function Dropzone(props) {
const {
classes,
initialFiles,
acceptedFileTypes,
maxFiles,
maxFileSize,
handleUpload,
handleFileRemoved,
} = props;

const [files, setFiles] = useState([]);
const [files, setFiles] = useState(initialFiles);

const getfileRejectedMessage = file => {
let errors = [];
Expand Down Expand Up @@ -145,7 +146,7 @@ function Dropzone(props) {
}

if (removedFile.status === 'uploaded') {
handleFileRemoved(() => {
handleFileRemoved(removedFile, () => {
setFiles(files.filter(file => file.url !== removedFile.url));
});

Expand Down Expand Up @@ -427,6 +428,7 @@ function Dropzone(props) {
}

Dropzone.propTypes = {
initialFiles: PropTypes.array,
acceptedFileTypes: PropTypes.array,
maxFiles: PropTypes.number,
maxFileSize: PropTypes.number,
Expand All @@ -435,6 +437,7 @@ Dropzone.propTypes = {
};

Dropzone.defaultProps = {
initialFiles: [],
acceptedFileTypes: ['image/*'],
maxFiles: 5,
maxFileSize: 1,
Expand Down
21 changes: 14 additions & 7 deletions resources/js/views/__backoffice/users/Create.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,9 @@ import { Profile, Account, Avatar } from './Forms';
class Create extends Component {
state = {
loading: false,
activeStep: 2,
activeStep: 0,
formValues: [],
user: {},
errors: {},
message: {},
};
Expand Down Expand Up @@ -72,7 +73,7 @@ class Create extends Component {
// Instruct the API the current step.
values.step = activeStep;

await User.store({ ...previousValues, ...values });
const user = await User.store({ ...previousValues, ...values });

// After persisting the previous values. Move to the next step...
this.setState(prevState => {
Expand All @@ -93,8 +94,9 @@ class Create extends Component {

return {
loading: false,
message,
formValues,
user,
message,
activeStep: prevState.activeStep + 1,
};
});
Expand All @@ -113,7 +115,14 @@ class Create extends Component {

render() {
const { classes, ...other } = this.props;
const { loading, activeStep, formValues, errors, message } = this.state;
const {
loading,
activeStep,
formValues,
user,
errors,
message,
} = this.state;

const steps = ['Profile', 'Account', 'Avatar'];

Expand Down Expand Up @@ -161,9 +170,7 @@ class Create extends Component {
return (
<Avatar
{...other}
values={{}}
errors={errors}
handleSubmit={this.handleSubmit}
user={user}
handleSkip={() =>
this.props.history.push(
NavigationUtils._route(
Expand Down
Loading

0 comments on commit d070b82

Please sign in to comment.