Adding login to move folders to new locations

parent b99e2af8
<?php
namespace Modules\Media\Events;
use Modules\Media\Entities\File;
class FolderStartedMoving
{
/**
* @var File
*/
public $folder;
/**
* @var array
*/
public $previousData;
public function __construct(File $folder, array $previousData)
{
$this->folder = $folder;
$this->previousData = $previousData;
}
}
<?php
namespace Modules\Media\Events\Handlers;
use Illuminate\Contracts\Filesystem\Factory;
use Modules\Media\Events\FolderStartedMoving;
use Modules\Media\Repositories\FileRepository;
class MoveFolderOnDisk
{
/**
* @var Factory
*/
private $filesystem;
/**
* @var FileRepository
*/
private $file;
public function __construct(Factory $filesystem, FileRepository $file)
{
$this->filesystem = $filesystem;
$this->file = $file;
}
public function handle(FolderStartedMoving $event)
{
$this->moveOriginal($event);
$this->renameDatabaseReferences($event);
}
private function moveOriginal(FolderStartedMoving $event)
{
$this->move($event->previousData['path']->getRelativeUrl(), $event->folder->path->getRelativeUrl());
}
private function renameDatabaseReferences(FolderStartedMoving $event)
{
$previousPath = $event->previousData['path']->getRelativeUrl();
$newPath = $event->folder->path->getRelativeUrl();
$this->replacePathReferences($event->folder->id, $previousPath, $newPath);
}
private function replacePathReferences($folderId, $previousPath, $newPath)
{
$medias = $this->file->allChildrenOf($folderId);
foreach ($medias as $media) {
$oldPath = $media->path->getRelativeUrl();
$media->update([
'path' => str_replace($previousPath, $newPath, $oldPath),
]);
if ($media->isFolder() === true) {
$this->replacePathReferences($media->id, $previousPath, $newPath);
}
}
}
private function move($fromPath, $toPath)
{
$this->filesystem->disk($this->getConfiguredFilesystem())
->move(
$this->getDestinationPath($fromPath),
$this->getDestinationPath($toPath)
);
}
private function getDestinationPath($path) : string
{
if ($this->getConfiguredFilesystem() === 'local') {
return basename(public_path()) . $path;
}
return $path;
}
/**
* @return string
*/
private function getConfiguredFilesystem() : string
{
return config('asgard.media.config.filesystem');
}
}
......@@ -16,6 +16,7 @@ use Modules\Media\Contracts\StoringMedia;
use Modules\Media\Entities\File;
use Modules\Media\Events\FileStartedMoving;
use Modules\Media\Events\FolderIsDeleting;
use Modules\Media\Events\FolderStartedMoving;
use Modules\Media\Events\FolderWasCreated;
use Modules\Media\Events\FolderWasUpdated;
use Modules\Media\Events\Handlers\CreateFolderOnDisk;
......@@ -23,6 +24,7 @@ use Modules\Media\Events\Handlers\DeleteAllChildrenOfFolder;
use Modules\Media\Events\Handlers\DeleteFolderOnDisk;
use Modules\Media\Events\Handlers\HandleMediaStorage;
use Modules\Media\Events\Handlers\MoveFileOnDisk;
use Modules\Media\Events\Handlers\MoveFolderOnDisk;
use Modules\Media\Events\Handlers\RegisterMediaSidebar;
use Modules\Media\Events\Handlers\RemovePolymorphicLink;
use Modules\Media\Events\Handlers\RenameFolderOnDisk;
......@@ -83,6 +85,7 @@ class MediaServiceProvider extends ServiceProvider
$events->listen(FolderIsDeleting::class, DeleteFolderOnDisk::class);
$events->listen(FolderIsDeleting::class, DeleteAllChildrenOfFolder::class);
$events->listen(FileStartedMoving::class, MoveFileOnDisk::class);
$events->listen(FolderStartedMoving::class, MoveFolderOnDisk::class);
$this->app[TagManager::class]->registerNamespace(new File());
$this->registerThumbnails();
......
......@@ -8,6 +8,7 @@ use Modules\Media\Entities\File;
use Modules\Media\Events\FolderIsCreating;
use Modules\Media\Events\FolderIsDeleting;
use Modules\Media\Events\FolderIsUpdating;
use Modules\Media\Events\FolderStartedMoving;
use Modules\Media\Events\FolderWasCreated;
use Modules\Media\Events\FolderWasUpdated;
use Modules\Media\Repositories\FolderRepository;
......@@ -89,6 +90,28 @@ class EloquentFolderRepository extends EloquentBaseRepository implements FolderR
return new NestedFoldersCollection($this->all());
}
public function move(File $folder, File $destination): File
{
$previousData = [
'filename' => $folder->filename,
'path' => $folder->path,
];
$folder->update([
'path' => $this->getNewPathFor($folder->filename, $destination),
'folder_id' => $destination->id,
]);
event(new FolderStartedMoving($folder, $previousData));
return $folder;
}
private function getNewPathFor(string $filename, File $folder)
{
return $folder->path->getRelativeUrl() . '/' . str_slug($filename);
}
/**
* @param array $data
* @return string
......
......@@ -23,4 +23,6 @@ interface FolderRepository extends BaseRepository
public function allChildrenOf(File $folder);
public function allNested() : NestedFoldersCollection;
public function move(File $folder, File $destination) : File;
}
......@@ -330,6 +330,79 @@ final class EloquentFolderRepositoryTest extends MediaTestCase
$this->assertCount(2, File::all());
}
/** @test */
public function it_can_move_folder_in_database()
{
$folder = $this->folder->create(['name' => 'My Folder']);
$folderTwo = $this->folder->create(['name' => 'Future Child folder']);
$this->assertEquals('/assets/media/future-child-folder', $folderTwo->path->getRelativeUrl());
$this->folder->move($folderTwo, $folder);
$this->assertEquals('/assets/media/my-folder/future-child-folder', $folderTwo->path->getRelativeUrl());
}
/** @test */
public function it_can_move_folder_on_disk()
{
$folder = $this->folder->create(['name' => 'My Folder']);
$folderTwo = $this->folder->create(['name' => 'Future Child folder']);
$this->assertTrue($this->app['files']->isDirectory(public_path('/assets/media/future-child-folder')));
$this->folder->move($folderTwo, $folder);
$this->assertTrue(
$this->app['files']->isDirectory(public_path('/assets/media/my-folder/future-child-folder')),
'Folder was not moved'
);
}
/** @test */
public function it_can_move_folder_with_folders_and_files_in_it_database()
{
$mainFolder = $this->folder->create(['name' => 'My Folder']);
$folderTwo = $this->folder->create(['name' => 'Second folder']);
$folderThird = $this->folder->create(['name' => 'Third folder', 'parent_id' => $folderTwo->id]);
$file = app(FileService::class)->store(\Illuminate\Http\UploadedFile::fake()->image('my-file.jpg'), $folderTwo->id);
$fileTwo = app(FileService::class)->store(\Illuminate\Http\UploadedFile::fake()->image('my-other-file.jpg'), $folderThird->id);
$this->assertEquals('/assets/media/second-folder', $folderTwo->path->getRelativeUrl());
$this->assertEquals('/assets/media/second-folder/third-folder', $folderThird->path->getRelativeUrl());
$this->assertEquals('/assets/media/second-folder/my-file.jpg', $file->path->getRelativeUrl());
$this->assertEquals('/assets/media/second-folder/third-folder/my-other-file.jpg', $fileTwo->path->getRelativeUrl());
$this->folder->move($folderTwo, $mainFolder);
$folderTwo->refresh();
$folderThird->refresh();
$file->refresh();
$fileTwo->refresh();
$this->assertEquals('/assets/media/my-folder/second-folder', $folderTwo->path->getRelativeUrl());
$this->assertEquals('/assets/media/my-folder/second-folder/third-folder', $folderThird->path->getRelativeUrl());
$this->assertEquals('/assets/media/my-folder/second-folder/my-file.jpg', $file->path->getRelativeUrl());
$this->assertEquals('/assets/media/my-folder/second-folder/third-folder/my-other-file.jpg', $fileTwo->path->getRelativeUrl());
}
/** @test */
public function it_can_move_folder_with_folders_and_files_in_it_disk()
{
$mainFolder = $this->folder->create(['name' => 'My Folder']);
$folderTwo = $this->folder->create(['name' => 'Second folder']);
$folderThird = $this->folder->create(['name' => 'Third folder', 'parent_id' => $folderTwo->id]);
$file = app(FileService::class)->store(\Illuminate\Http\UploadedFile::fake()->image('my-file.jpg'), $folderTwo->id);
$fileTwo = app(FileService::class)->store(\Illuminate\Http\UploadedFile::fake()->image('my-other-file.jpg'), $folderThird->id);
$this->assertTrue($this->app['files']->isDirectory(public_path('/assets/media/second-folder')));
$this->assertTrue($this->app['files']->isDirectory(public_path('/assets/media/second-folder/third-folder')));
$this->assertTrue($this->app['files']->exists(public_path('/assets/media/second-folder/my-file.jpg')));
$this->assertTrue($this->app['files']->exists(public_path('/assets/media/second-folder/third-folder/my-other-file.jpg')));
$this->folder->move($folderTwo, $mainFolder);
$this->assertTrue($this->app['files']->isDirectory(public_path('/assets/media/my-folder/second-folder')));
$this->assertTrue($this->app['files']->isDirectory(public_path('/assets/media/my-folder/second-folder/third-folder')));
$this->assertTrue($this->app['files']->exists(public_path('/assets/media/my-folder/second-folder/my-file.jpg')));
$this->assertTrue($this->app['files']->exists(public_path('/assets/media/my-folder/second-folder/third-folder/my-other-file.jpg')));
}
private function createFile($fileName = 'random/name.jpg')
{
return File::create([
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment