Browse Source

Added a command to regenerate thumbnails for a single photo or entire album. Photos can now be edited in bulk on the album page.

tags/1.1.2
Andy Heathershaw 3 years ago
parent
commit
1a08ef1828

+ 3
- 20
.env.example View File

@@ -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

+ 0
- 2
app/Console/Commands/ProcessUploadCommand.php View File

@@ -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
{

+ 120
- 0
app/Console/Commands/RegenerateThumbnailsCommand.php View File

@@ -0,0 +1,120 @@
<?php

namespace App\Console\Commands;

use App\Album;
use App\Helpers\ImageHelper;
use App\Helpers\ThemeHelper;
use App\Photo;
use Illuminate\Console\Command;

class RegenerateThumbnailsCommand extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'twilight:regenerate-thumbnails {--album} {id}';

/**
* The console command description.
*
* @var string
*/
protected $description = 'Recreates thumbnails for an image or an album.';

/**
* @var ImageHelper
*/
private $imageHelper;

/**
* @var ThemeHelper
*/
private $themeHelper;

/**
* Create a new command instance.
*
* @return void
*/
public function __construct(ImageHelper $imageHelper, ThemeHelper $themeHelper)
{
parent::__construct();

$this->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']));
}
}
}

+ 3
- 1
app/Console/Kernel.php View File

@@ -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
];

/**

+ 2
- 0
app/Helpers/ConfigHelper.php View File

@@ -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),

+ 24
- 13
app/Http/Controllers/Admin/AlbumController.php View File

@@ -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
@@ -50,34 +54,41 @@ class AlbumController extends Controller
}

/**
* Store a newly created resource in storage.
* Display the specified resource.
*
* @param \Illuminate\Http\Request $request
* @param int $id
* @return \Illuminate\Http\Response
*/
public function store(Requests\StoreAlbumRequest $request)
public function show(Request $request, $id)
{
$this->authorize('admin-access');

$album = new Album();
$album->fromRequest($request)->save();

return redirect(route('albums.index'));
$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
]);
}

/**
* Display the specified resource.
* Store a newly created resource in storage.
*
* @param int $id
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\Response
*/
public function show(Request $request, $id)
public function store(Requests\StoreAlbumRequest $request)
{
$this->authorize('admin-access');

$album = AlbumController::loadAlbum($id);
$album = new Album();
$album->fromRequest($request)->save();

return Theme::render('admin.show_album', ['album' => $album, 'error' => $request->session()->get('error')]);
return redirect(route('albums.index'));
}

/**

+ 31
- 0
app/Http/Controllers/Admin/PhotoController.php View File

@@ -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.
*

+ 5
- 2
app/Http/Controllers/Gallery/AlbumController.php View File

@@ -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
]);
}


+ 4
- 1
app/Http/Controllers/Gallery/DefaultController.php View File

@@ -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,

+ 12
- 2
app/Providers/AppServiceProvider.php View File

@@ -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'))
{

+ 5
- 0
resources/views/themes/base/admin/list_albums.blade.php View File

@@ -27,6 +27,7 @@
<td>
<span style="font-size: 1.3em;"><a href="{{ route('albums.show', ['id' => $album->id]) }}">{{ $album->name }}</a></span><br/>
<p>{{ $album->description }}</p>
<p style="margin-bottom: 0;"><b>{{ $album->photos_count }}</b> {{ trans_choice('admin.stats_photos', $album->photos_count) }}</p>
</td>
<td class="text-right">
<a href="{{ route('albums.edit', ['id' => $album->id]) }}" class="btn btn-default">@lang('forms.edit_action')</a>
@@ -37,6 +38,10 @@
</tbody>
</table>

<div class="text-center">
{{ $albums->links() }}
</div>

<div style="margin-top: 10px;">
<a href="{{ route('albums.create') }}" class="btn btn-success"><i class="fa fa-fw fa-plus"></i> @lang('admin.create_album_link')</a>
</div>

+ 18
- 1
resources/views/themes/base/admin/show_album.blade.php View File

@@ -19,12 +19,29 @@
<div class="tab-content">
{{-- Photos --}}
<div role="tabpanel" class="tab-pane active" id="photos-tab">
@if ($album->photos()->count() == 0)
@if (count($photos) == 0)
<div class="text-center" style="margin-top: 30px;">
<h4 class="text-danger"><b>@lang('admin.album_no_photos_p1')</b></h4>
<p>@lang('admin.album_no_photos_p2')</p>
<p style="margin-top: 30px;"><button id="upload-button" class="btn btn-lg btn-success">@lang('admin.album_no_photos_button')</button></p>
</div>
@else
{!! Form::open(['route' => ['photos.updateBulk', $album->id], 'method' => 'PUT']) !!}

@foreach ($photos as $photo)
@include (Theme::viewName('partials.single_photo_admin'))
@endforeach

<div class="pull-right">
<button type="submit" class="btn btn-success">@lang('forms.save_action')</button>
</div>
<div class="clearfix"></div>

{!! Form::close() !!}

<div class="text-center">
{{ $photos->links() }}
</div>
@endif
</div>


+ 7
- 1
resources/views/themes/base/gallery/album.blade.php View File

@@ -15,11 +15,17 @@
@section('content')
<div class="container">
<div class="row">
@foreach ($album->photos as $photo)
@foreach ($photos as $photo)
<div class="col-xs-12 col-sm-4">
<a href="{{ $photo->url() }}"><img src="{{ $photo->thumbnailUrl('preview') }}" alt="" class="img-thumbnail"/></a>
</div>
@endforeach
</div>

<div class="row" style="margin-top: 15px;">
<div class="col-xs-12 text-center">
{{ $photos->links() }}
</div>
</div>
</div>
@endsection

+ 7
- 1
resources/views/themes/base/gallery/index.blade.php View File

@@ -12,7 +12,7 @@
<p class="text-center">
@php($albumUrl = $album->thumbnailUrl('preview'))
@if (strlen($albumUrl) > 0)
<img class="img-responsive" src="{{ $albumUrl }}"/>
<a href="{{ $album->url() }}"><img class="img-responsive" src="{{ $albumUrl }}"/></a>
@endif
</p>
<p>{{ $album->description }}</p>
@@ -26,5 +26,11 @@
</div>
@endforeach
</div>

<div class="row" style="margin-top: 15px;">
<div class="col-xs-12 text-center">
{{ $albums->links() }}
</div>
</div>
</div>
@endsection

+ 3
- 0
resources/views/themes/base/gallery/photo.blade.php View File

@@ -18,6 +18,9 @@
<div class="row">
<div class="col-xs-12">
<h1>{{ $photo->name }}</h1>
@if (strlen($photo->description) > 0)
<p>{{ $photo->description }}</p>
@endif
</div>
</div>


+ 20
- 0
resources/views/themes/base/partials/single_photo_admin.blade.php View File

@@ -0,0 +1,20 @@
@php ($field_prefix = sprintf('photo[%d]', $photo->id))
<hr/>
<div class="photo row">
<div class="col-xs-12 col-sm-2 text-center">
<a href="{{ $photo->thumbnailUrl() }}" target="_blank">
<img src="{{ $photo->thumbnailUrl('admin-preview') }}" style="max-width: 100%;"/>
</a>
</div>
<div class="col-xs-12 col-sm-10">
<div class="form-group">
{!! Form::label($field_prefix . '[name]', trans('forms.name_label'), ['class' => 'control-label']) !!}
{!! Form::text($field_prefix . '[name]', old('name', $photo->name), ['class' => 'form-control']) !!}
</div>

<div class="form-group">
{!! 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]) !!}
</div>
</div>
</div>

+ 5
- 0
resources/views/themes/bootstrap3/theme.json View File

@@ -14,6 +14,11 @@
"name": "preview",
"height": 300,
"width": 400
},
{
"name": "admin-preview",
"height": 112,
"width": 150
}
]
}

+ 1
- 0
routes/web.php View File

@@ -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');
});


Loading…
Cancel
Save