Impossible de supprimer un fichier dans un répertoire

Par lakamark, il y a 8 ans


Bonjour,

Voila je rencontre un petit problème avec mon code.

Ce que je fais

Je teste la soupression d'un fichier attaché lorsque on souprime le contenu parant (Post, Pages, Project etc)

public function testDeleteAttachmentDeleteFile() { $response = $this->callController(); $attachment = $response->json(); $this->assertFileExists($this->getFileForAttachment($attachment)); Attachment::find($attachment['id'])->delete(); $this->assertFileNotExists($this->getFileForAttachment($attachment)); } public function testDeletePostDeleteAllAttachments() { $response = $this->callController(); $attachment = $response->json(); factory(Attachment::class, 3)->create(); $this->assertFileExists($this->getFileForAttachment($attachment)); $this->assertEquals(4, Attachment::count()); Project::first()->delete(); $this->assertFileNotExists($this->getFileForAttachment($attachment)); $this->assertEquals(3, Attachment::count()); }

Ce que je veux

Le fichier dans le répectoire de test dans ce cas il est dans uploads/project/1/sdsdsadd.jpeg sois bien éffacé.

Ce que j'obtiens

Quand je lance les testes j'ai ces erreurs qui s'affiche :

...EFI 6 / 6 (100%) Time: 1.73 seconds, Memory: 22.00MB There was 1 error: 1) Tests\Feature\AttachmentTest::testDeleteAttachmentDeleteFile ErrorException: Array to string conversion /var/www/sitesdev.test/lakamark/app/Attachment.php:48 /var/www/sitesdev.test/lakamark/app/Attachment.php:19 /var/www/sitesdev.test/lakamark/vendor/laravel/framework/src/Illuminate/Events/Dispatcher.php:350 /var/www/sitesdev.test/lakamark/vendor/laravel/framework/src/Illuminate/Events/Dispatcher.php:200 /var/www/sitesdev.test/lakamark/vendor/laravel/framework/src/Illuminate/Events/Dispatcher.php:173 /var/www/sitesdev.test/lakamark/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Concerns/HasEvents.php:148 /var/www/sitesdev.test/lakamark/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Model.php:790 /var/www/sitesdev.test/lakamark/tests/Feature/AttachmentTest.php:97 -- There was 1 failure: 1) Tests\Feature\AttachmentTest::testDeletePostDeleteAllAttachments Failed asserting that file "/var/www/sitesdev.test/lakamark/public/uploads/project/1/lmFlAWFCBblgsyfW77TTSkIVvjvlBkWiTospKXiT.jpeg" does not exist. /var/www/sitesdev.test/lakamark/tests/Feature/AttachmentTest.php:109 ERRORS! Tests: 6, Assertions: 13, Errors: 1, Failures: 1, Incomplete: 1.

Dans mes test j'ai une fonction helper qui permet de réupéré les attributs d'un attachment particulier et d'appeler le controller :

/** * @param $attachment * @return string */ public function getFileForAttachment($attachment) { $stringName = explode('\\', $attachment['attachable_type']); $prefix = lcfirst($stringName[1]); $final = dirname(dirname(__DIR__)) . '/public/uploads/' . $prefix.'/' . $attachment['attachable_id'] . '/' . $attachment['name']; return $final; } // appelle le controller /** * @param array $data * @return \Illuminate\Foundation\Testing\TestResponse */ private function callController($data = []) { $user = $this->createAUser(); $this->be($user); $path = dirname(__DIR__) . '/fixtures/demo.jpg'; $file = new UploadedFile($path, 'demo.jpg', filesize($path), 'image/jpeg', null, true); $project = Project::create(['name' => 'demo', 'content' => 'demo', 'draft' => 0, 'published' => 1]); $default = [ 'attachable_type' => Project::class, 'attachable_id' => $project->id, 'image' => $file, 'user_id' => $user->id ]; return $this->post(route('cloud.attachments.store'), array_merge($default, $data)); }

Dans mon model Attachment j'ai des propriété suivante :

public static function boot() { parent::boot(); self::deleted(function($attachment){ $attachment->deleteFile($attachment); }); } /** * Upload a file * @param string $destination * @param UploadedFile $file * @return $this */ public function uploadFile(string $destination, UploadedFile $file) { $file = $file->storePublicly($destination, ['disk' => 'public']); $this->name = basename($file); return $this; } public function deleteFile() { $type = explode('\\', $this->attachable_type); Storage::disk('public')->delete(public_path(). 'uploads/' . $type . $this->name); } /** Generate an url : eg. uploads/project/1/my_file.jpeg **/ public function getUrlAttribute() { $type = explode('\\', $this->attachable_type); $url = '/uploads/'. lcfirst($type[1]) . '/' . $this->id . '/'. $this->name; return Storage::disk('public')->url($url); }

Dans le trait que j'ajoute au model où il va le comportement des fichiers attaché :

public static function bootAttachableConcern () { self::deleted(function ($subject) { foreach($subject->attachments()->get() as $attachment) { $attachment->deleteFile(); } $subject->attachments()->delete(); }); } public function attachments(){ return $this->morphMany(Attachment::class, 'attachable'); }

Je sais pas d'où vient cette erreur. Merci de votre aide en avance.

5 réponses

tom49, il y a 8 ans

Regarde comment mocker ta facade storage, sa devraity résoudre ton problème

Doc Laravel

joshow, il y a 8 ans

C'est plutôt du côté de la façade File qu'il faut regarder. Il suffit dans le genre :

use Illuminate\Support\Facades\File; ... File::delete(app_path('tests/'.$path));
lakamark, il y a 8 ans

Bonjour,
Désolé, de vous faire attendre. J'ai réssuit à réglé une partie du problème. Le teste testDeleteAttachmentDeleteFile() où j'ai eu une erreur "Array to string conviction" c'est réglé. Par contre le deuxième teste testDeleteProjectDeleteAllAttachments() Vérifie dès que le contenu parent (Post, page, video, etc) est surpprimer supprime les attachments et surprime les fichiers. J'ai cette erreur :

PHPUnit 6.5.5 by Sebastian Bergmann and contributors. ....FI 6 / 6 (100%) Time: 2.85 seconds, Memory: 22.00MB There was 1 failure: 1) Tests\Feature\AttachmentTest::testDeleteProjectDeleteAllAttachments Failed asserting that file "/var/www/sitesdev.test/lakamark/public/uploads/project/1/uqzAm0vOXDn8jDKsSaPPRNh3alNbP2E4Y4i2b6QS.jpeg" does not exist. /var/www/sitesdev.test/lakamark/tests/Feature/AttachmentTest.php:108 FAILURES! Tests: 6, Assertions: 14, Failures: 1, Incomplete: 1.

Je voi t que le répectoire demandé existe bien dans le dossier uploads :

![](https://image.prntscr.com/image/rh6RgQA7RrGROCRxJntSFQ.png

https://image.prntscr.com/image/rh6RgQA7RrGROCRxJntSFQ.png

J'ai fait un peut de "refactory" dans mon model Attachment j'ai faite une fonction qui génére le chemain ou le fichier va être télécharger.

/** * Generate a directory in public folder : * /public/uploads/example/1/your_file.jpg * @return string */ private function generateDirectory() { $model = explode("\\", $this->attachable_type); $id = $this->attachable_id; $ds = DIRECTORY_SEPARATOR; $url = 'uploads' . $ds . lcfirst($model[1]) . $ds . $id . $ds; return $url; }

Ensuite dans mes autre fonction j'ai fait ceci:

/** * Upload a file * @param UploadedFile $file * @return $this */ public function uploadFile(UploadedFile $file) { $path = $this->generateDirectory(); $file = $file->storePublicly($path, ['disk' => 'public']); $this->name = basename($file); return $this; } public function getUrlAttribute() { $url = $this->generateDirectory() . $this->name; return Storage::disk('public')->url($url); } public function deleteFile() { $url = $this->generateDirectory() . $this->name; Storage::disk('public')->delete($url); }

Quand je debug ma fonction deleteFile() ça me retourne le bon chemain :

PHPUnit 6.5.5 by Sebastian Bergmann and contributors. ..."uploads/project/1/KzBYgh6NBDrLYgV5jGQdgsBB1Ckyc6mpPQPzsMmQ.jpeg"

Pourquoi qu'il ne réussit pas à trouver le fichier? J'utilise cette fonction generateDirectory() quand je téléverse (upload) le fichier. Tout mes autre tests passe au vert sauf celui-ci.

Merci de vos répone.

lakamark, il y a 8 ans

J'ai débuguer ma fonction qui soccupe de supprimer un fichier la fonction deleteFile() Je vois bien le fichier est bien effacer dans la répectoire :

Avant :
https://image.prntscr.com/image/rh6RgQA7RrGROCRxJntSFQ.png

Après :
https://image.prntscr.com/image/xvDw4ccORgC7pUVTXN8xjw.png

Je ne vois pas pourquoi le teste ne passe pas. Ça me dit toujours test échoué. Je ne comprend pas d'où viens le problème.

lakamark, il y a 8 ans

Finalement, j'avais mal nomé mon fichier AttachableConcern.php. Celui-ci était j'amais apellé. Mon système entièrement testé. Je suis certain de son fonctionement. Merci pour vos réponse. Je ferme le sujet.