Skip to content

Commit

Permalink
change form avatar controller to support different image types
Browse files Browse the repository at this point in the history
  • Loading branch information
PhilReinking committed Aug 30, 2022
1 parent 71f6b87 commit 048f009
Show file tree
Hide file tree
Showing 6 changed files with 104 additions and 34 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -8,45 +8,52 @@
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\Storage;
use App\Http\Requests\FormAvatarRequest;
use App\Http\Requests\FormImageRequest;

class FormAvatarController extends Controller
class FormImagesController extends Controller
{
public function store(FormAvatarRequest $request, Form $form)
public function store(FormImageRequest $request, Form $form)
{
$this->authorize('update', $form);

$file = $request->file('image');
$fieldname = $request->input('type') . '_path';

// if old file, clear that first
if ($form->avatar_path) {
Storage::delete($form->avatar_path);
with(new GlideCache)->clear($form->avatar_path);
if ($form->$fieldname) {
Storage::delete($form->$fieldname);
with(new GlideCache)->clear($form->$fieldname);
}

$file = $request->file('image');

$filename = sprintf("%s.%s.%s", strtolower(Str::random(6)), time(), $file->extension());

// store to filesystem
$file->storeAs($form->uuid, $filename);

// save to form model
$form->avatar_path = join('/', [$form->uuid, $filename]);
$form->$fieldname = join('/', [$form->uuid, $filename]);
$form->save();

return response()->json($form, 201);
}

public function delete(Form $form)
public function delete(Request $request, Form $form)
{
$this->authorize('update', $form);

$request->validate([
'type' => 'required|in:avatar,background',
]);

$fieldname = $request->input('type') . '_path';

// remove image from disk and cache
if ($form->hasAvatar()) {
Storage::delete($form->avatar_path);
if ($form->hasImage($request->input('type'))) {
Storage::delete($form->$fieldname);
$cache = new GlideCache;
$cache->clear($form->avatar_path);
$cache->clear($form->$fieldname);

$form->avatar_path = null;
$form->$fieldname = null;
$form->save();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

use Illuminate\Foundation\Http\FormRequest;

class FormAvatarRequest extends FormRequest
class FormImageRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
Expand All @@ -25,6 +25,7 @@ public function rules()
{
return [
'image' => 'required|image|max:4096',
'type' => 'required|in:avatar,background',
];
}

Expand All @@ -36,7 +37,7 @@ public function rules()
public function attributes()
{
return [
'image' => 'avatar',
'image' => 'image',
];
}
}
10 changes: 6 additions & 4 deletions app/Models/Form.php
Original file line number Diff line number Diff line change
Expand Up @@ -157,18 +157,20 @@ public function responsesCount()
return $result ? $result->response_count : 0;
}

public function hasAvatar()
public function hasImage($type)
{
if (!$this->avatar_path) {
$fieldname = $type . '_path';

if (!$this->$fieldname) {
return false;
}

return Storage::exists($this->avatar_path);
return Storage::exists($this->$fieldname);
}

public function avatarImage()
{
if ($this->hasAvatar()) {
if ($this->hasImage('avatar')) {
return asset('images/' . $this->avatar_path);
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

return new class extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('forms', function (Blueprint $table) {
$table->string('background_path', 1024)->nullable()->after('avatar_path');
});
}
};
8 changes: 4 additions & 4 deletions routes/api.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
use App\Http\Controllers\Api\FormController;
use App\Http\Controllers\Api\ShowFormController;
use App\Http\Controllers\Api\FormBlockController;
use App\Http\Controllers\Api\FormAvatarController;
use App\Http\Controllers\Api\FormImagesController;
use App\Http\Controllers\Api\FormSubmitController;
use App\Http\Controllers\Api\PublishFormController;
use App\Http\Controllers\Api\UnpublishFormController;
Expand Down Expand Up @@ -55,9 +55,9 @@
$router->post('forms/{form}/publish', PublishFormController::class)->name('api.forms.publish');
$router->post('forms/{form}/unpublish', UnpublishFormController::class)->name('api.forms.unpublish');

// Form Avatar Routes
$router->post('forms/{form}/avatar', [FormAvatarController::class, 'store'])->name('api.forms.images.store');
$router->delete('forms/{form}/avatar', [FormAvatarController::class, 'delete'])->name('api.forms.images.delete');
// Form Image Routes
$router->post('forms/{form}/images', [FormImagesController::class, 'store'])->name('api.forms.images.store');
$router->delete('forms/{form}/images', [FormImagesController::class, 'delete'])->name('api.forms.images.delete');

// Block API Routes
$router->get('{form}/blocks', [FormBlockController::class, 'index'])->name('api.blocks.index');
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
use Illuminate\Http\UploadedFile;
use Illuminate\Foundation\Testing\RefreshDatabase;

class AvatarTest extends TestCase
class FormImageTest extends TestCase
{
use RefreshDatabase;

Expand All @@ -22,11 +22,12 @@ public function can_upload_a_single_avatar_image_for_a_form()
$this->actingAs($form->user)
->json('POST', route('api.forms.images.store', $form->uuid), [
'image' => UploadedFile::fake()->image('avatar.jpeg'),
'type' => 'avatar',
])
->assertStatus(201);

$form = $form->fresh();
$this->assertTrue($form->hasAvatar());
$this->assertTrue($form->hasImage('avatar'));
$this->assertNotNull($form->avatar_path);
Storage::assertExists($form->avatar_path);
}
Expand All @@ -41,17 +42,19 @@ public function cannot_upload_avatar_if_wrong_format_or_too_big()
$this->actingAs($form->user)
->json('POST', route('api.forms.images.store', ['form' => $form->uuid]), [
'image' => UploadedFile::fake()->create('avatar.pdf'),
'type' => 'avatar',
])
->assertStatus(422);

// test with too large file
$this->actingAs($form->user)
->json('POST', route('api.forms.images.store', ['form' => $form->uuid]), [
'image' => UploadedFile::fake()->create('avatar.pdf')->size(2500),
'type' => 'avatar',
])
->assertStatus(422);

$this->assertFalse($form->hasAvatar());
$this->assertFalse($form->hasImage('avatar'));
}

/** @test */
Expand All @@ -64,40 +67,77 @@ public function can_delete_an_uploaded_avatar_image_for_a_form()
$this->actingAs($form->user)
->json('POST', route('api.forms.images.store', $form->uuid), [
'image' => UploadedFile::fake()->image('avatar.png'),
'type' => 'avatar',
]);

$form = $form->fresh();
$this->assertTrue($form->hasAvatar());
$this->assertTrue($form->hasImage('avatar'));

// delete image now
$this->actingAs($form->user)
->json('DELETE', route('api.forms.images.store', $form->uuid))
->json('DELETE', route('api.forms.images.store', $form->uuid), [
'type' => 'avatar',
])
->assertStatus(200);

$form = $form->fresh();
$this->assertFalse($form->hasAvatar());
$this->assertFalse($form->hasImage('avatar'));
$this->assertNull($form->avatar_path);
}

/** @test */
public function trying_to_delete_avatar_if_nothing_is_set_does_nothing()
{
$this->withoutExceptionHandling();
Storage::fake();
$form = Form::factory()->create();

// should have no avatar
$this->assertFalse($form->hasAvatar());
$this->assertFalse($form->hasImage('avatar'));
$this->assertNull($form->avatar_path);

// delete image now
$this->actingAs($form->user)
->json('DELETE', route('api.forms.images.store', $form->uuid))
->json('DELETE', route('api.forms.images.store', $form->uuid), [
'type' => 'avatar',
])
->assertStatus(200);

$form = $form->fresh();
// nothing has changed
$this->assertFalse($form->hasAvatar());
$this->assertFalse($form->hasImage('avatar'));
$this->assertNull($form->avatar_path);
}

/** @test */
public function can_upload_a_form_background_image()
{
$form = Form::factory()->create();
Storage::fake();

// test with valid file size
$this->actingAs($form->user)
->json('POST', route('api.forms.images.store', $form->uuid), [
'image' => UploadedFile::fake()->image('background.jpg'),
'type' => 'background',
])

->assertStatus(201);

$form = $form->fresh();
$this->assertTrue($form->hasImage('background'));
$this->assertNotNull($form->background_path);
Storage::assertExists($form->background_path);

// delete image now
$this->actingAs($form->user)
->json('DELETE', route('api.forms.images.store', $form->uuid), [
'type' => 'background',
])
->assertStatus(200);

$form = $form->fresh();
$this->assertFalse($form->hasImage('background'));
$this->assertNull($form->background_path);
Storage::assertMissing($form->background_path);
}
}

0 comments on commit 048f009

Please sign in to comment.