fix: delete files using file_manager when deleting episode and podcast

- add deleteAll method to file manager
- refactor deletePodcastImageSizes and
deletePersonImagesSizes implementations
This commit is contained in:
Yassine Doghri 2023-03-30 13:23:10 +00:00
parent 7e1a470ba4
commit 41d8efe6e7
6 changed files with 1795 additions and 1748 deletions

View File

@ -911,9 +911,11 @@ class EpisodeController extends BaseController
$episodeMediaList[] = $this->episode->cover; $episodeMediaList[] = $this->episode->cover;
} }
$mediaModel = new MediaModel();
//delete episode media records from database //delete episode media records from database
foreach ($episodeMediaList as $episodeMedia) { foreach ($episodeMediaList as $episodeMedia) {
if ($episodeMedia !== null && ! $episodeMedia->delete()) { if ($episodeMedia !== null && ! $mediaModel->delete($episodeMedia->id)) {
$db->transRollback(); $db->transRollback();
return redirect() return redirect()
->back() ->back()

View File

@ -31,6 +31,7 @@ use Modules\Analytics\Models\AnalyticsPodcastModel;
use Modules\Analytics\Models\AnalyticsWebsiteByBrowserModel; use Modules\Analytics\Models\AnalyticsWebsiteByBrowserModel;
use Modules\Analytics\Models\AnalyticsWebsiteByEntryPageModel; use Modules\Analytics\Models\AnalyticsWebsiteByEntryPageModel;
use Modules\Analytics\Models\AnalyticsWebsiteByRefererModel; use Modules\Analytics\Models\AnalyticsWebsiteByRefererModel;
use Modules\Media\FileManagers\FileManagerInterface;
use Modules\Media\Models\MediaModel; use Modules\Media\Models\MediaModel;
class PodcastController extends BaseController class PodcastController extends BaseController
@ -497,8 +498,10 @@ class PodcastController extends BaseController
$episodeMediaList[] = $podcastEpisode->cover; $episodeMediaList[] = $podcastEpisode->cover;
} }
$mediaModel = new MediaModel();
foreach ($episodeMediaList as $episodeMedia) { foreach ($episodeMediaList as $episodeMedia) {
if ($episodeMedia !== null && ! $episodeMedia->delete()) { if ($episodeMedia !== null && ! $mediaModel->delete($episodeMedia->id)) {
$db->transRollback(); $db->transRollback();
return redirect() return redirect()
->back() ->back()
@ -538,8 +541,10 @@ class PodcastController extends BaseController
]; ];
} }
$mediaModel = new MediaModel();
foreach ($podcastMediaList as $podcastMedia) { foreach ($podcastMediaList as $podcastMedia) {
if ($podcastMedia['file'] !== null && ! $podcastMedia['file']->delete()) { if ($podcastMedia['file'] !== null && ! $mediaModel->delete($podcastMedia['file']->id)) {
$db->transRollback(); $db->transRollback();
return redirect() return redirect()
->back() ->back()
@ -587,15 +592,12 @@ class PodcastController extends BaseController
$db->transComplete(); $db->transComplete();
/** @var FileManagerInterface $fileManager */
$fileManager = service('file_manager');
//delete podcast media files and folder //delete podcast media files and folder
$folder = 'podcasts/' . $this->podcast->handle; $folder = 'podcasts/' . $this->podcast->handle;
if (! $fileManager->deleteAll($folder)) {
$mediaRoot = config('App')
->mediaRoot . '/' . $folder;
helper('filesystem');
if (! delete_files($mediaRoot) || ! rmdir($mediaRoot)) {
return redirect()->route('podcast-list') return redirect()->route('podcast-list')
->with('message', lang('Podcast.messages.deleteSuccess', [ ->with('message', lang('Podcast.messages.deleteSuccess', [
'podcast_handle' => $this->podcast->handle, 'podcast_handle' => $this->podcast->handle,

View File

@ -51,7 +51,7 @@ class FS implements FileManagerInterface
{ {
helper('media'); helper('media');
return unlink(media_path_absolute($key)); return @unlink(media_path_absolute($key));
} }
public function getUrl(string $key): string public function getUrl(string $key): string
@ -89,23 +89,8 @@ class FS implements FileManagerInterface
public function deletePodcastImageSizes(string $podcastHandle): bool public function deletePodcastImageSizes(string $podcastHandle): bool
{ {
helper('media');
$allPodcastImagesPaths = [];
foreach (['jpg', 'jpeg', 'png', 'webp'] as $ext) { foreach (['jpg', 'jpeg', 'png', 'webp'] as $ext) {
$images = glob(media_path_absolute("/podcasts/{$podcastHandle}/*_*{$ext}")); $this->deleteAll("podcasts/{$podcastHandle}", "*_*{$ext}");
if (! $images) {
return false;
}
array_push($allPodcastImagesPaths, ...$images);
}
foreach ($allPodcastImagesPaths as $podcastImagePath) {
if (is_file($podcastImagePath)) {
unlink($podcastImagePath);
}
} }
return true; return true;
@ -113,23 +98,34 @@ class FS implements FileManagerInterface
public function deletePersonImagesSizes(): bool public function deletePersonImagesSizes(): bool
{ {
helper('media');
$allPersonsImagesPaths = [];
foreach (['jpg', 'jpeg', 'png', 'webp'] as $ext) { foreach (['jpg', 'jpeg', 'png', 'webp'] as $ext) {
$images = glob(media_path_absolute("/persons/*_*{$ext}")); $this->deleteAll('persons', "*_*{$ext}");
if (! $images) {
return false;
}
array_push($allPersonsImagesPaths, ...$images);
} }
foreach ($allPersonsImagesPaths as $personImagePath) { return true;
if (is_file($personImagePath)) { }
unlink($personImagePath);
} public function deleteAll(string $prefix, string $pattern = '*'): bool
{
helper('media');
// delete all in folder?
if ($pattern === '*') {
helper('filesystem');
return delete_files(media_path_absolute($prefix), true);
}
$prefix = rtrim($prefix, '/') . '/';
$imagePaths = glob(media_path_absolute($prefix . $pattern));
if (! $imagePaths) {
return true;
}
foreach ($imagePaths as $imagePath) {
@unlink($imagePath);
} }
return true; return true;

View File

@ -24,5 +24,7 @@ interface FileManagerInterface
public function deletePersonImagesSizes(): bool; public function deletePersonImagesSizes(): bool;
public function deleteAll(string $prefix, string $pattern = '*'): bool;
public function isHealthy(): bool; public function isHealthy(): bool;
} }

View File

@ -88,7 +88,7 @@ class S3 implements FileManagerInterface
} }
// delete old object // delete old object
return $this->delete($this->prefixKey($oldKey)); return $this->delete($oldKey);
} }
public function getFileContents(string $key): string public function getFileContents(string $key): string
@ -108,44 +108,8 @@ class S3 implements FileManagerInterface
public function deletePodcastImageSizes(string $podcastHandle): bool public function deletePodcastImageSizes(string $podcastHandle): bool
{ {
$results = $this->s3->getPaginator('ListObjectsV2', [ foreach (['jpg', 'jpeg', 'png', 'webp'] as $ext) {
'Bucket' => $this->config->s3['bucket'], $this->deleteAll('podcasts/' . $podcastHandle, "*_*{$ext}");
'Prefix' => $this->prefixKey('podcasts/' . $podcastHandle . '/'),
]);
$keys = [];
foreach ($results as $result) {
$key = array_map(static function ($object) {
return $object['Key'];
}, $result['Contents']);
$prefixedPodcasts = $this->prefixKey('podcasts');
array_push(
$keys,
...preg_grep("~^{$prefixedPodcasts}\/{$podcastHandle}\/.*_.*.\.(jpe?g|png|webp)$~", $key)
);
}
$objectsToDelete = array_map(static function ($key): array {
return [
'Key' => $key,
];
}, $keys);
if ($objectsToDelete === []) {
return true;
}
try {
$this->s3->deleteObjects([
'Bucket' => $this->config->s3['bucket'],
'Delete' => [
'Objects' => $objectsToDelete,
],
]);
} catch (Exception) {
return false;
} }
return true; return true;
@ -153,27 +117,37 @@ class S3 implements FileManagerInterface
public function deletePersonImagesSizes(): bool public function deletePersonImagesSizes(): bool
{ {
$results = $this->s3->getPaginator('ListObjectsV2', [ foreach (['jpg', 'jpeg', 'png', 'webp'] as $ext) {
'Bucket' => $this->config->s3['bucket'], $this->deleteAll('persons', "*_*{$ext}");
'prefix' => $this->prefixKey('persons/'),
]);
$keys = [];
foreach ($results as $result) {
$key = array_map(static function ($object) {
return $object['Key'];
}, $result['Contents']);
$prefixedPersons = $this->prefixKey('persons');
array_push($keys, ...preg_grep("~^{$prefixedPersons}\/.*_.*.\.(jpe?g|png|webp)$~", $key));
} }
$objectsToDelete = array_map(static function ($key): array { return true;
return [ }
'Key' => $key,
]; public function deleteAll(string $prefix, ?string $pattern = '*'): bool
}, $keys); {
$prefix = rtrim($this->prefixKey($prefix), '/') . '/'; // make sure that there is a trailing slash
$pattern = $prefix . $pattern;
$results = $this->s3->getPaginator('ListObjectsV2', [
'Bucket' => $this->config->s3['bucket'],
'prefix' => $prefix,
]);
$objectsToDelete = [];
foreach ($results as $result) {
if ($result['Contents'] === null) {
continue;
}
foreach ($result['Contents'] as $object) {
if (fnmatch($pattern, $object['Key'])) {
$objectsToDelete[] = [
'Key' => $object['Key'],
];
}
}
}
if ($objectsToDelete === []) { if ($objectsToDelete === []) {
return true; return true;

File diff suppressed because it is too large Load Diff