From 1a08ef18286d6350e661b6419b2dda950a33b288 Mon Sep 17 00:00:00 2001 From: Andy Heathershaw Date: Wed, 7 Sep 2016 21:44:28 +0100 Subject: [PATCH] Added a command to regenerate thumbnails for a single photo or entire album. Photos can now be edited in bulk on the album page. --- .env.example | 23 +--- app/Console/Commands/ProcessUploadCommand.php | 2 - .../Commands/RegenerateThumbnailsCommand.php | 120 ++++++++++++++++++ app/Console/Kernel.php | 4 +- app/Helpers/ConfigHelper.php | 2 + .../Controllers/Admin/AlbumController.php | 43 ++++--- .../Controllers/Admin/PhotoController.php | 31 +++++ .../Controllers/Gallery/AlbumController.php | 7 +- .../Controllers/Gallery/DefaultController.php | 5 +- app/Providers/AppServiceProvider.php | 14 +- .../themes/base/admin/list_albums.blade.php | 5 + .../themes/base/admin/show_album.blade.php | 19 ++- .../views/themes/base/gallery/album.blade.php | 8 +- .../views/themes/base/gallery/index.blade.php | 8 +- .../views/themes/base/gallery/photo.blade.php | 3 + .../partials/single_photo_admin.blade.php | 20 +++ resources/views/themes/bootstrap3/theme.json | 5 + routes/web.php | 1 + 18 files changed, 273 insertions(+), 47 deletions(-) create mode 100644 app/Console/Commands/RegenerateThumbnailsCommand.php create mode 100644 resources/views/themes/base/partials/single_photo_admin.blade.php diff --git a/.env.example b/.env.example index 38d1171..3ba91c8 100644 --- a/.env.example +++ b/.env.example @@ -7,26 +7,9 @@ APP_URL=http://localhost DB_CONNECTION=mysql DB_HOST=127.0.0.1 DB_PORT=3306 -DB_DATABASE=homestead -DB_USERNAME=homestead +DB_DATABASE=blue_twilight +DB_USERNAME=blue_twilight DB_PASSWORD=secret -BROADCAST_DRIVER=log CACHE_DRIVER=file -SESSION_DRIVER=file -QUEUE_DRIVER=sync - -REDIS_HOST=127.0.0.1 -REDIS_PASSWORD=null -REDIS_PORT=6379 - -MAIL_DRIVER=smtp -MAIL_HOST=mailtrap.io -MAIL_PORT=2525 -MAIL_USERNAME=null -MAIL_PASSWORD=null -MAIL_ENCRYPTION=null - -PUSHER_KEY= -PUSHER_SECRET= -PUSHER_APP_ID= +SESSION_DRIVER=file \ No newline at end of file diff --git a/app/Console/Commands/ProcessUploadCommand.php b/app/Console/Commands/ProcessUploadCommand.php index bed3848..da9eed2 100644 --- a/app/Console/Commands/ProcessUploadCommand.php +++ b/app/Console/Commands/ProcessUploadCommand.php @@ -3,14 +3,12 @@ namespace App\Console\Commands; use App\Album; -use App\AlbumSources\IAlbumSource; use App\Helpers\ImageHelper; use App\Helpers\ThemeHelper; use App\Photo; use App\Upload; use App\UploadPhoto; use Illuminate\Console\Command; -use Illuminate\Support\Facades\Storage; class ProcessUploadCommand extends Command { diff --git a/app/Console/Commands/RegenerateThumbnailsCommand.php b/app/Console/Commands/RegenerateThumbnailsCommand.php new file mode 100644 index 0000000..4eec209 --- /dev/null +++ b/app/Console/Commands/RegenerateThumbnailsCommand.php @@ -0,0 +1,120 @@ +imageHelper = $imageHelper; + $this->themeHelper = $themeHelper; + } + + /** + * Execute the console command. + * + * @return mixed + */ + public function handle() + { + $id = intval($this->argument('id')); + if ($this->option('album')) + { + $this->handleAlbum($id); + } + else + { + $this->handlePhoto($id); + } + } + + private function handleAlbum($id) + { + $album = Album::where('id', $id)->first(); + if (is_null($album)) + { + throw new \Exception(sprintf('The album with ID %d could not be found', $id)); + } + + /** @var Photo $photo */ + foreach ($album->photos as $photo) + { + $this->regenerateThumbnailsForPhoto($album, $photo); + } + } + + private function handlePhoto($id) + { + $photo = Photo::where('id', $id)->first(); + if (is_null($photo)) + { + throw new \Exception(sprintf('The photo with ID %d could not be found', $id)); + } + + /** @var Album $album */ + $album = $photo->album; + $this->regenerateThumbnailsForPhoto($album, $photo); + } + + private function regenerateThumbnailsForPhoto(Album $album, Photo $photo) + { + $albumSource = $album->getAlbumSource(); + + $originalPhotoResource = $this->imageHelper->openImage($albumSource->getPathToPhoto($album, $photo), $imageInfo); + if (!is_resource($originalPhotoResource)) + { + throw new \Exception(sprintf('The original image for photo ID %d could not be found', $id)); + } + + $this->output->writeln(sprintf('Generating thumbnails for "%s"...', $photo->file_name)); + + $themeInfo = $this->themeHelper->info(); + $thumbnailsRequired = $themeInfo['thumbnails']; + + /** @var mixed $thumbnail */ + foreach ($thumbnailsRequired as $thumbnail) + { + $generatedThumbnailPath = $this->imageHelper->generateThumbnail($originalPhotoResource, $photo, $thumbnail); + $albumSource->saveThumbnail($album, $photo, $thumbnail, $generatedThumbnailPath); + + $this->output->writeln(sprintf('Thumbnail \'%s\' (%dx%d) created', $thumbnail['name'], $thumbnail['width'], $thumbnail['height'])); + } + } +} \ No newline at end of file diff --git a/app/Console/Kernel.php b/app/Console/Kernel.php index abc7e77..6ece851 100644 --- a/app/Console/Kernel.php +++ b/app/Console/Kernel.php @@ -3,6 +3,7 @@ namespace App\Console; use App\Console\Commands\ProcessUploadCommand; +use App\Console\Commands\RegenerateThumbnailsCommand; use App\Upload; use Illuminate\Console\Scheduling\Schedule; use Illuminate\Foundation\Console\Kernel as ConsoleKernel; @@ -15,7 +16,8 @@ class Kernel extends ConsoleKernel * @var array */ protected $commands = [ - ProcessUploadCommand::class + ProcessUploadCommand::class, + RegenerateThumbnailsCommand::class ]; /** diff --git a/app/Helpers/ConfigHelper.php b/app/Helpers/ConfigHelper.php index 83de8f1..a7a8271 100644 --- a/app/Helpers/ConfigHelper.php +++ b/app/Helpers/ConfigHelper.php @@ -57,6 +57,8 @@ class ConfigHelper 'allow_self_registration' => true, 'app_name' => trans('global.app_name'), 'date_format' => $this->allowedDateFormats()[0], + 'items_per_page' => 12, + 'items_per_page_admin' => 10, 'require_email_verification' => true, 'sender_address' => sprintf('hostmaster@%s', (isset($_SERVER['HTTP_HOST']) ? $_SERVER['HTTP_HOST'] : 'localhost')), 'sender_name' => (is_null($currentAppName) ? trans('global.app_name') : $currentAppName), diff --git a/app/Http/Controllers/Admin/AlbumController.php b/app/Http/Controllers/Admin/AlbumController.php index 5874e87..79cbccc 100644 --- a/app/Http/Controllers/Admin/AlbumController.php +++ b/app/Http/Controllers/Admin/AlbumController.php @@ -4,11 +4,13 @@ namespace app\Http\Controllers\Admin; use App\Album; use App\Facade\Theme; +use App\Facade\UserConfig; use App\Http\Controllers\Controller; use App\Http\Requests; use App\Upload; use Illuminate\Http\Request; use Illuminate\Support\Facades\App; +use Illuminate\Support\Facades\DB; class AlbumController extends Controller { @@ -21,7 +23,9 @@ class AlbumController extends Controller { $this->authorize('admin-access'); - $albums = Album::all()->sortBy('name'); + $albums = Album::orderBy('name') + ->withCount('photos') + ->paginate(UserConfig::get('items_per_page')); return Theme::render('admin.list_albums', [ 'albums' => $albums @@ -49,6 +53,28 @@ class AlbumController extends Controller return Theme::render('admin.delete_album', ['album' => $album]); } + /** + * Display the specified resource. + * + * @param int $id + * @return \Illuminate\Http\Response + */ + public function show(Request $request, $id) + { + $this->authorize('admin-access'); + + $album = AlbumController::loadAlbum($id); + $photos = $album->photos() + ->orderBy(DB::raw('COALESCE(taken_at, created_at)')) + ->paginate(UserConfig::get('items_per_page_admin')); + + return Theme::render('admin.show_album', [ + 'album' => $album, + 'error' => $request->session()->get('error'), + 'photos' => $photos + ]); + } + /** * Store a newly created resource in storage. * @@ -65,21 +91,6 @@ class AlbumController extends Controller return redirect(route('albums.index')); } - /** - * Display the specified resource. - * - * @param int $id - * @return \Illuminate\Http\Response - */ - public function show(Request $request, $id) - { - $this->authorize('admin-access'); - - $album = AlbumController::loadAlbum($id); - - return Theme::render('admin.show_album', ['album' => $album, 'error' => $request->session()->get('error')]); - } - /** * Show the form for editing the specified resource. * diff --git a/app/Http/Controllers/Admin/PhotoController.php b/app/Http/Controllers/Admin/PhotoController.php index c2d98be..75edd8e 100644 --- a/app/Http/Controllers/Admin/PhotoController.php +++ b/app/Http/Controllers/Admin/PhotoController.php @@ -2,6 +2,7 @@ namespace App\Http\Controllers\Admin; +use App\Album; use App\Helpers\MiscHelper; use App\Photo; use App\Upload; @@ -9,6 +10,7 @@ use App\UploadPhoto; use Illuminate\Http\Request; use App\Http\Controllers\Controller; use Illuminate\Http\UploadedFile; +use Illuminate\Support\Facades\App; use Symfony\Component\Finder\Iterator\RecursiveDirectoryIterator; use Symfony\Component\HttpFoundation\File\File; @@ -202,6 +204,35 @@ class PhotoController extends Controller // } + public function updateBulk(Request $request, $albumId) + { + $photos = $request->get('photo'); + + /** @var Album $album */ + $album = Album::where('id', intval($albumId))->first(); + + if (is_null($album)) + { + App::abort(404); + return null; + } + + foreach ($photos as $photoId => $value) + { + /** @var Photo $photo */ + $photo = $album->photos()->where('id', intval($photoId))->first(); + if (is_null($photo)) + { + continue; + } + + $photo->fill($value); + $photo->save(); + } + + return redirect(route('albums.show', array('id' => $albumId))); + } + /** * Remove the specified resource from storage. * diff --git a/app/Http/Controllers/Gallery/AlbumController.php b/app/Http/Controllers/Gallery/AlbumController.php index 0d0ae58..d7f16a2 100644 --- a/app/Http/Controllers/Gallery/AlbumController.php +++ b/app/Http/Controllers/Gallery/AlbumController.php @@ -4,18 +4,21 @@ namespace App\Http\Controllers\Gallery; use App\Album; use App\Facade\Theme; +use App\Facade\UserConfig; use App\Http\Controllers\Controller; use App\Http\Requests; use Illuminate\Http\Request; class AlbumController extends Controller { - public function index(Request $request, $albumUrlAlias) + public function index($albumUrlAlias) { $album = AlbumController::loadAlbum($albumUrlAlias); + $photos = $album->photos()->paginate(UserConfig::get('items_per_page')); return Theme::render('gallery.album', [ - 'album' => $album + 'album' => $album, + 'photos' => $photos ]); } diff --git a/app/Http/Controllers/Gallery/DefaultController.php b/app/Http/Controllers/Gallery/DefaultController.php index 9a33a4c..66acc32 100644 --- a/app/Http/Controllers/Gallery/DefaultController.php +++ b/app/Http/Controllers/Gallery/DefaultController.php @@ -4,6 +4,7 @@ namespace App\Http\Controllers\Gallery; use App\Album; use App\Facade\Theme; +use App\Facade\UserConfig; use App\Http\Controllers\Controller; use Illuminate\Http\Request; @@ -11,7 +12,9 @@ class DefaultController extends Controller { public function index(Request $request) { - $albums = Album::withCount('photos')->get()->sortBy('name'); + $albums = Album::orderBy('name') + ->withCount('photos') + ->paginate(UserConfig::get('items_per_page')); return Theme::render('gallery.index', [ 'albums' => $albums, diff --git a/app/Providers/AppServiceProvider.php b/app/Providers/AppServiceProvider.php index cc1d8e2..39ceaaf 100644 --- a/app/Providers/AppServiceProvider.php +++ b/app/Providers/AppServiceProvider.php @@ -87,8 +87,18 @@ class AppServiceProvider extends ServiceProvider $transport = $swiftMailer->getTransport(); $transport->setHost(UserConfig::get('smtp_server')); $transport->setPort(intval(UserConfig::get('smtp_port'))); - $transport->setUsername(UserConfig::get('smtp_username')); - $transport->setPassword(decrypt(UserConfig::get('smtp_password'))); + + $username = UserConfig::get('smtp_username'); + if (!is_null($username)) + { + $transport->setUsername($username); + } + + $password = UserConfig::get('smtp_password'); + if (!is_null($password)) + { + $transport->setPassword(decrypt($password)); + } if (UserConfig::get('smtp_encryption')) { diff --git a/resources/views/themes/base/admin/list_albums.blade.php b/resources/views/themes/base/admin/list_albums.blade.php index 8ec6b57..a8775a6 100644 --- a/resources/views/themes/base/admin/list_albums.blade.php +++ b/resources/views/themes/base/admin/list_albums.blade.php @@ -27,6 +27,7 @@ {{ $album->name }}

{{ $album->description }}

+

{{ $album->photos_count }} {{ trans_choice('admin.stats_photos', $album->photos_count) }}

@lang('forms.edit_action') @@ -37,6 +38,10 @@ +
+ {{ $albums->links() }} +
+
@lang('admin.create_album_link')
diff --git a/resources/views/themes/base/admin/show_album.blade.php b/resources/views/themes/base/admin/show_album.blade.php index 6b7920a..468d055 100644 --- a/resources/views/themes/base/admin/show_album.blade.php +++ b/resources/views/themes/base/admin/show_album.blade.php @@ -19,12 +19,29 @@
{{-- Photos --}}
- @if ($album->photos()->count() == 0) + @if (count($photos) == 0)

@lang('admin.album_no_photos_p1')

@lang('admin.album_no_photos_p2')

+ @else + {!! Form::open(['route' => ['photos.updateBulk', $album->id], 'method' => 'PUT']) !!} + + @foreach ($photos as $photo) + @include (Theme::viewName('partials.single_photo_admin')) + @endforeach + +
+ +
+
+ + {!! Form::close() !!} + +
+ {{ $photos->links() }} +
@endif
diff --git a/resources/views/themes/base/gallery/album.blade.php b/resources/views/themes/base/gallery/album.blade.php index acbcfe1..9696690 100644 --- a/resources/views/themes/base/gallery/album.blade.php +++ b/resources/views/themes/base/gallery/album.blade.php @@ -15,11 +15,17 @@ @section('content')
- @foreach ($album->photos as $photo) + @foreach ($photos as $photo)
@endforeach
+ +
+
+ {{ $photos->links() }} +
+
@endsection \ No newline at end of file diff --git a/resources/views/themes/base/gallery/index.blade.php b/resources/views/themes/base/gallery/index.blade.php index 88efc3e..15ee035 100644 --- a/resources/views/themes/base/gallery/index.blade.php +++ b/resources/views/themes/base/gallery/index.blade.php @@ -12,7 +12,7 @@

@php($albumUrl = $album->thumbnailUrl('preview')) @if (strlen($albumUrl) > 0) - + @endif

{{ $album->description }}

@@ -26,5 +26,11 @@
@endforeach + +
+
+ {{ $albums->links() }} +
+
@endsection \ No newline at end of file diff --git a/resources/views/themes/base/gallery/photo.blade.php b/resources/views/themes/base/gallery/photo.blade.php index d609bf6..8160cd3 100644 --- a/resources/views/themes/base/gallery/photo.blade.php +++ b/resources/views/themes/base/gallery/photo.blade.php @@ -18,6 +18,9 @@

{{ $photo->name }}

+ @if (strlen($photo->description) > 0) +

{{ $photo->description }}

+ @endif
diff --git a/resources/views/themes/base/partials/single_photo_admin.blade.php b/resources/views/themes/base/partials/single_photo_admin.blade.php new file mode 100644 index 0000000..ddc7121 --- /dev/null +++ b/resources/views/themes/base/partials/single_photo_admin.blade.php @@ -0,0 +1,20 @@ +@php ($field_prefix = sprintf('photo[%d]', $photo->id)) +
+
+
+ + + +
+
+
+ {!! Form::label($field_prefix . '[name]', trans('forms.name_label'), ['class' => 'control-label']) !!} + {!! Form::text($field_prefix . '[name]', old('name', $photo->name), ['class' => 'form-control']) !!} +
+ +
+ {!! Form::label($field_prefix . '[description]', trans('forms.description_label'), ['class' => 'control-label']) !!} + {!! Form::textarea($field_prefix . '[description]', old('name', $photo->description), ['class' => 'form-control', 'rows' => 4]) !!} +
+
+
\ No newline at end of file diff --git a/resources/views/themes/bootstrap3/theme.json b/resources/views/themes/bootstrap3/theme.json index 943053c..7904c4f 100644 --- a/resources/views/themes/bootstrap3/theme.json +++ b/resources/views/themes/bootstrap3/theme.json @@ -14,6 +14,11 @@ "name": "preview", "height": 300, "width": 400 + }, + { + "name": "admin-preview", + "height": 112, + "width": 150 } ] } \ No newline at end of file diff --git a/routes/web.php b/routes/web.php index 589364b..28ca5db 100644 --- a/routes/web.php +++ b/routes/web.php @@ -28,6 +28,7 @@ Route::group(['prefix' => 'admin'], function () { // Photo management Route::post('photos/store-bulk', 'Admin\PhotoController@storeBulk')->name('photos.storeBulk'); + Route::put('photos/update-bulk/{albumId}', 'Admin\PhotoController@updateBulk')->name('photos.updateBulk'); Route::resource('photos', 'Admin\PhotoController'); });