diff --git a/app/Events/Company/CompanyWasDeleted.php b/app/Events/Company/CompanyWasDeleted.php new file mode 100644 index 000000000000..60a6172bff86 --- /dev/null +++ b/app/Events/Company/CompanyWasDeleted.php @@ -0,0 +1,42 @@ +company = $company; + } + + /** + * Get the channels the event should broadcast on. + * + * @return \Illuminate\Broadcasting\Channel|array + */ + public function broadcastOn() + { + return new PrivateChannel('channel-name'); + } +} diff --git a/app/Jobs/Util/UploadFile.php b/app/Jobs/Util/UploadFile.php index 7014f039daa5..5ffe81751b26 100644 --- a/app/Jobs/Util/UploadFile.php +++ b/app/Jobs/Util/UploadFile.php @@ -33,10 +33,10 @@ class UploadFile implements ShouldQueue const PROPERTIES = [ self::IMAGE => [ - 'path' => 'public/images', + 'path' => 'images', ], self::DOCUMENT => [ - 'path' => 'public/documents', + 'path' => 'documents', ] ]; @@ -66,8 +66,13 @@ class UploadFile implements ShouldQueue */ public function handle() : ?Document { + $path = self::PROPERTIES[$this->type]['path']; + + if ($this->company) + $path = sprintf('%s/%s', $this->company->company_key, self::PROPERTIES[$this->type]['path']); + $instance = Storage::disk($this->disk)->putFileAs( - self::PROPERTIES[$this->type]['path'], $this->file, $this->file->hashName() + $path, $this->file, $this->file->hashName() ); if (in_array($this->file->extension(), ['jpg', 'jpeg', 'png', 'gif', 'bmp', 'tiff', 'psd'])) { @@ -110,7 +115,7 @@ class UploadFile implements ShouldQueue if (empty(Document::$types[$documentType])) { return 'Unsupported file type'; } - + $preview = ''; if (in_array($this->file->getClientOriginalExtension(), ['jpg', 'jpeg', 'png', 'gif', 'bmp', 'tiff', 'psd'])) { diff --git a/app/Listeners/Document/DeleteCompanyDocuments.php b/app/Listeners/Document/DeleteCompanyDocuments.php new file mode 100644 index 000000000000..4dedb47e4c3f --- /dev/null +++ b/app/Listeners/Document/DeleteCompanyDocuments.php @@ -0,0 +1,42 @@ +company->company_key); + + // Remove all files & folders, under company's path. + // This will delete directory itself, as well. + // In case we want to remove the content of folder, we should use $fs->cleanDirectory(); + $filesystem = new Filesystem(); + $filesystem->deleteDirectory($path); + + Document::whereCompanyId($event->company->id)->delete(); + } +} diff --git a/app/Models/Company.php b/app/Models/Company.php index 84eb41c2338a..4a749d5b72ed 100644 --- a/app/Models/Company.php +++ b/app/Models/Company.php @@ -12,6 +12,7 @@ namespace App\Models; use App\DataMapper\CompanySettings; +use App\Events\Company\CompanyWasDeleted; use App\Models\Account; use App\Models\Client; use App\Models\CompanyGateway; @@ -66,6 +67,10 @@ class Company extends BaseModel protected $presenter = 'App\Models\Presenters\CompanyPresenter'; + protected $dispatchesEvents = [ + 'deleted' => CompanyWasDeleted::class, + ]; + protected $fillable = [ 'fill_products', 'industry_id', @@ -367,6 +372,6 @@ class Company extends BaseModel //else the env variable for selfhosted // return $this->slack_webhook_url; - + } } diff --git a/app/Providers/EventServiceProvider.php b/app/Providers/EventServiceProvider.php index c8c2e13604a3..2cd657f52614 100644 --- a/app/Providers/EventServiceProvider.php +++ b/app/Providers/EventServiceProvider.php @@ -12,6 +12,7 @@ namespace App\Providers; use App\Events\Client\ClientWasCreated; +use App\Events\Company\CompanyWasDeleted; use App\Events\Contact\ContactLoggedIn; use App\Events\Credit\CreditWasMarkedSent; use App\Events\Invoice\InvoiceWasCreated; @@ -32,6 +33,7 @@ use App\Listeners\Activity\PaymentDeletedActivity; use App\Listeners\Activity\PaymentRefundedActivity; use App\Listeners\Activity\PaymentVoidedActivity; use App\Listeners\Contact\UpdateContactLastLogin; +use App\Listeners\Document\DeleteCompanyDocuments; use App\Listeners\Invoice\CreateInvoiceActivity; use App\Listeners\Invoice\CreateInvoiceHtmlBackup; use App\Listeners\Invoice\CreateInvoiceInvitation; @@ -61,7 +63,7 @@ class EventServiceProvider extends ServiceProvider ], // [3] \Codedge\Updater\Events\UpdateSucceeded::class => [ \Codedge\Updater\Listeners\SendUpdateSucceededNotification::class - ], + ], UserWasCreated::class => [ SendVerificationNotification::class, ], @@ -106,7 +108,7 @@ class EventServiceProvider extends ServiceProvider CreditWasMarkedSent::class => [ ], - + //Invoices InvoiceWasMarkedSent::class => [ CreateInvoiceHtmlBackup::class, @@ -131,9 +133,12 @@ class EventServiceProvider extends ServiceProvider ], InvitationWasViewed::class => [ - InvitationViewedListener::class + InvitationViewedListener::class + ], + + CompanyWasDeleted::class => [ + DeleteCompanyDocuments::class, ], - ]; /** diff --git a/tests/Unit/CompanyDocumentsTest.php b/tests/Unit/CompanyDocumentsTest.php new file mode 100644 index 000000000000..78393949b2df --- /dev/null +++ b/tests/Unit/CompanyDocumentsTest.php @@ -0,0 +1,55 @@ +makeTestData(); + + $this->withoutMiddleware( + ThrottleRequests::class + ); + } + + + public function testCompanyDocumentExists() + { + $original_count = Document::whereCompanyId($this->company->id)->count(); + + $image = UploadedFile::fake()->image('avatar.jpg'); + + $document = UploadFile::dispatchNow( + $image, UploadFile::IMAGE, $this->user, $this->company, $this->invoice + ); + + $this->assertNotNull($document); + + $this->assertGreaterThan($original_count, Document::whereCompanyId($this->company->id)->count()); + + $company_key = $this->company->company_key; + + $this->company->delete(); + + $this->assertEquals(0, Document::whereCompanyId($this->company->id)->count()); + + $path = sprintf('%s/%s', storage_path('app/public'), $company_key); + + $this->assertFalse(file_exists($path)); + } +}