Added the ability to create storage locations and set those as the album source when creating a new album
This commit is contained in:
parent
fde988e359
commit
48b43c3dd2
@ -19,7 +19,7 @@ class Album extends Model
|
|||||||
* @var array
|
* @var array
|
||||||
*/
|
*/
|
||||||
protected $fillable = [
|
protected $fillable = [
|
||||||
'name', 'description', 'url_alias', 'is_private', 'user_id'
|
'name', 'description', 'url_alias', 'is_private', 'user_id', 'storage_id'
|
||||||
];
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
29
app/AlbumSources/AlbumSourceBase.php
Normal file
29
app/AlbumSources/AlbumSourceBase.php
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace app\AlbumSources;
|
||||||
|
|
||||||
|
use App\Album;
|
||||||
|
use App\Storage;
|
||||||
|
|
||||||
|
abstract class AlbumSourceBase
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var Album
|
||||||
|
*/
|
||||||
|
protected $album;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var Storage
|
||||||
|
*/
|
||||||
|
protected $configuration;
|
||||||
|
|
||||||
|
public function setAlbum(Album $album)
|
||||||
|
{
|
||||||
|
$this->album = $album;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setConfiguration(Storage $configuration)
|
||||||
|
{
|
||||||
|
$this->configuration = $configuration;
|
||||||
|
}
|
||||||
|
}
|
@ -22,6 +22,12 @@ interface IAlbumSource
|
|||||||
*/
|
*/
|
||||||
function deleteThumbnail(Photo $photo, $thumbnail = null);
|
function deleteThumbnail(Photo $photo, $thumbnail = null);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the name of this album source.
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
function getName();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the absolute path to the given photo file.
|
* Gets the absolute path to the given photo file.
|
||||||
* @param Photo $photo Photo to get the path to.
|
* @param Photo $photo Photo to get the path to.
|
||||||
|
@ -12,24 +12,8 @@ use Symfony\Component\HttpFoundation\File\File;
|
|||||||
* Driver for managing files on the local filesystem.
|
* Driver for managing files on the local filesystem.
|
||||||
* @package App\AlbumSources
|
* @package App\AlbumSources
|
||||||
*/
|
*/
|
||||||
class LocalFilesystemSource implements IAlbumSource
|
class LocalFilesystemSource extends AlbumSourceBase implements IAlbumSource
|
||||||
{
|
{
|
||||||
/**
|
|
||||||
* @var Album
|
|
||||||
*/
|
|
||||||
private $album;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @var string
|
|
||||||
*/
|
|
||||||
private $parentFolder;
|
|
||||||
|
|
||||||
public function __construct(Album $album, $parentFolder)
|
|
||||||
{
|
|
||||||
$this->album = $album;
|
|
||||||
$this->parentFolder = $parentFolder;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function deleteAlbumContents()
|
public function deleteAlbumContents()
|
||||||
{
|
{
|
||||||
if (file_exists($this->getPathToAlbum()) && is_dir($this->getPathToAlbum()))
|
if (file_exists($this->getPathToAlbum()) && is_dir($this->getPathToAlbum()))
|
||||||
@ -48,6 +32,11 @@ class LocalFilesystemSource implements IAlbumSource
|
|||||||
return '_originals';
|
return '_originals';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getName()
|
||||||
|
{
|
||||||
|
return 'global.album_sources.filesystem';
|
||||||
|
}
|
||||||
|
|
||||||
public function getPathToPhoto(Photo $photo, $thumbnail = null)
|
public function getPathToPhoto(Photo $photo, $thumbnail = null)
|
||||||
{
|
{
|
||||||
if (is_null($thumbnail))
|
if (is_null($thumbnail))
|
||||||
@ -95,7 +84,7 @@ class LocalFilesystemSource implements IAlbumSource
|
|||||||
|
|
||||||
private function getPathToAlbum()
|
private function getPathToAlbum()
|
||||||
{
|
{
|
||||||
return sprintf('%s/%s', $this->parentFolder, $this->album->url_alias);
|
return sprintf('%s/%s', $this->configuration->location, $this->album->url_alias);
|
||||||
}
|
}
|
||||||
|
|
||||||
private function recursiveDelete($directory)
|
private function recursiveDelete($directory)
|
||||||
|
@ -2,6 +2,9 @@
|
|||||||
|
|
||||||
namespace App\Helpers;
|
namespace App\Helpers;
|
||||||
|
|
||||||
|
use App\Album;
|
||||||
|
use App\AlbumSources\IAlbumSource;
|
||||||
|
use App\AlbumSources\LocalFilesystemSource;
|
||||||
use App\Configuration;
|
use App\Configuration;
|
||||||
|
|
||||||
class ConfigHelper
|
class ConfigHelper
|
||||||
@ -16,6 +19,24 @@ class ConfigHelper
|
|||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function albumSources()
|
||||||
|
{
|
||||||
|
$results = [];
|
||||||
|
|
||||||
|
$classes = [
|
||||||
|
LocalFilesystemSource::class
|
||||||
|
];
|
||||||
|
foreach ($classes as $class)
|
||||||
|
{
|
||||||
|
/** @var IAlbumSource $instance */
|
||||||
|
$instance = new $class;
|
||||||
|
$key = basename(str_replace('\\', '/', $class));
|
||||||
|
$results[$key] = trans($instance->getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
return $results;
|
||||||
|
}
|
||||||
|
|
||||||
public function allowedThemeNames()
|
public function allowedThemeNames()
|
||||||
{
|
{
|
||||||
$results = [];
|
$results = [];
|
||||||
|
@ -10,6 +10,7 @@ use App\Http\Controllers\Controller;
|
|||||||
use App\Http\Requests;
|
use App\Http\Requests;
|
||||||
use App\Photo;
|
use App\Photo;
|
||||||
use App\Services\PhotoService;
|
use App\Services\PhotoService;
|
||||||
|
use App\Storage;
|
||||||
use App\Upload;
|
use App\Upload;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use Illuminate\Support\Facades\App;
|
use Illuminate\Support\Facades\App;
|
||||||
@ -45,7 +46,18 @@ class AlbumController extends Controller
|
|||||||
{
|
{
|
||||||
$this->authorize('admin-access');
|
$this->authorize('admin-access');
|
||||||
|
|
||||||
return Theme::render('admin.create_album');
|
$albumSources = [];
|
||||||
|
foreach (Storage::all()->sortBy('name') as $storage)
|
||||||
|
{
|
||||||
|
$albumSources[$storage->id] = $storage->name;
|
||||||
|
}
|
||||||
|
|
||||||
|
$defaultSourceId = Storage::where('is_default', true)->limit(1)->first();
|
||||||
|
|
||||||
|
return Theme::render('admin.create_album', [
|
||||||
|
'album_sources' => $albumSources,
|
||||||
|
'default_storage_id' => (!is_null($defaultSourceId) ? $defaultSourceId->id : 0)
|
||||||
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function delete($id)
|
public function delete($id)
|
||||||
@ -166,7 +178,7 @@ class AlbumController extends Controller
|
|||||||
$this->authorize('admin-access');
|
$this->authorize('admin-access');
|
||||||
|
|
||||||
$album = new Album();
|
$album = new Album();
|
||||||
$album->fill($request->only(['name', 'description']));
|
$album->fill($request->only(['name', 'description', 'storage_id']));
|
||||||
|
|
||||||
$album->is_private = (strtolower($request->get('is_private')) == 'on');
|
$album->is_private = (strtolower($request->get('is_private')) == 'on');
|
||||||
$album->user_id = Auth::user()->id;
|
$album->user_id = Auth::user()->id;
|
||||||
|
133
app/Http/Controllers/Admin/StorageController.php
Normal file
133
app/Http/Controllers/Admin/StorageController.php
Normal file
@ -0,0 +1,133 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Controllers\Admin;
|
||||||
|
|
||||||
|
use App\Facade\Theme;
|
||||||
|
use App\Facade\UserConfig;
|
||||||
|
use App\Storage;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
|
||||||
|
use App\Http\Requests;
|
||||||
|
use App\Http\Controllers\Controller;
|
||||||
|
|
||||||
|
class StorageController extends Controller
|
||||||
|
{
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
$this->middleware('auth');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Display a listing of the resource.
|
||||||
|
*
|
||||||
|
* @return \Illuminate\Http\Response
|
||||||
|
*/
|
||||||
|
public function index()
|
||||||
|
{
|
||||||
|
$this->authorize('admin-access');
|
||||||
|
|
||||||
|
$storageLocations = Storage::orderBy('name')
|
||||||
|
->paginate(UserConfig::get('items_per_page'));
|
||||||
|
|
||||||
|
return Theme::render('admin.list_storage', [
|
||||||
|
'storageLocations' => $storageLocations
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show the form for creating a new resource.
|
||||||
|
*
|
||||||
|
* @return \Illuminate\Http\Response
|
||||||
|
*/
|
||||||
|
public function create()
|
||||||
|
{
|
||||||
|
$this->authorize('admin-access');
|
||||||
|
|
||||||
|
$filesystemDefaultLocation = sprintf('%s/storage/app/albums', dirname(dirname(dirname(dirname(__DIR__)))));
|
||||||
|
|
||||||
|
return Theme::render('admin.create_storage', [
|
||||||
|
'album_sources' => UserConfig::albumSources(),
|
||||||
|
'filesystem_default_location' => $filesystemDefaultLocation
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Store a newly created resource in storage.
|
||||||
|
*
|
||||||
|
* @param \Illuminate\Http\Request $request
|
||||||
|
* @return \Illuminate\Http\Response
|
||||||
|
*/
|
||||||
|
public function store(Requests\StoreStorageRequest $request)
|
||||||
|
{
|
||||||
|
$this->authorize('admin-access');
|
||||||
|
|
||||||
|
$storage = new Storage();
|
||||||
|
$storage->fill($request->only(['name', 'source', 'location']));
|
||||||
|
|
||||||
|
$storage->is_default = (strtolower($request->get('is_default')) == 'on');
|
||||||
|
$storage->save();
|
||||||
|
|
||||||
|
if ($storage->is_default)
|
||||||
|
{
|
||||||
|
// If this storage is flagged as default, remove all others
|
||||||
|
foreach (Storage::all() as $otherStorage)
|
||||||
|
{
|
||||||
|
if ($otherStorage->id == $storage->id)
|
||||||
|
{
|
||||||
|
// Ignore the one just created
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$otherStorage->is_default = false;
|
||||||
|
$otherStorage->save();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return redirect(route('storage.index'));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Display the specified resource.
|
||||||
|
*
|
||||||
|
* @param int $id
|
||||||
|
* @return \Illuminate\Http\Response
|
||||||
|
*/
|
||||||
|
//public function show($id)
|
||||||
|
//{
|
||||||
|
//
|
||||||
|
//}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show the form for editing the specified resource.
|
||||||
|
*
|
||||||
|
* @param int $id
|
||||||
|
* @return \Illuminate\Http\Response
|
||||||
|
*/
|
||||||
|
public function edit($id)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update the specified resource in storage.
|
||||||
|
*
|
||||||
|
* @param \Illuminate\Http\Request $request
|
||||||
|
* @param int $id
|
||||||
|
* @return \Illuminate\Http\Response
|
||||||
|
*/
|
||||||
|
public function update(Request $request, $id)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove the specified resource from storage.
|
||||||
|
*
|
||||||
|
* @param int $id
|
||||||
|
* @return \Illuminate\Http\Response
|
||||||
|
*/
|
||||||
|
public function destroy($id)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
}
|
||||||
|
}
|
@ -4,19 +4,45 @@ namespace App\Http\Middleware;
|
|||||||
|
|
||||||
use App\Helpers\MiscHelper;
|
use App\Helpers\MiscHelper;
|
||||||
use Closure;
|
use Closure;
|
||||||
|
use Illuminate\Foundation\Application;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
|
|
||||||
class CheckMaxPostSizeExceeded
|
class CheckMaxPostSizeExceeded
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* The application instance.
|
||||||
|
*
|
||||||
|
* @var \Illuminate\Foundation\Application
|
||||||
|
*/
|
||||||
|
protected $app;
|
||||||
|
|
||||||
protected $exclude = [
|
protected $exclude = [
|
||||||
'/admin/photos/analyse/*',
|
'/admin/photos/analyse/*',
|
||||||
'/admin/photos/regenerate-thumbnails/*'
|
'/admin/photos/regenerate-thumbnails/*'
|
||||||
];
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new middleware instance.
|
||||||
|
*
|
||||||
|
* @param \Illuminate\Foundation\Application $app
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function __construct(Application $app)
|
||||||
|
{
|
||||||
|
$this->app = $app;
|
||||||
|
}
|
||||||
|
|
||||||
public function handle(Request $request, Closure $next)
|
public function handle(Request $request, Closure $next)
|
||||||
{
|
{
|
||||||
if ($request->method() == 'POST' && !$this->shouldExclude($request))
|
if (
|
||||||
|
$this->isRunningInConsole() ||
|
||||||
|
$this->isReading($request) ||
|
||||||
|
$this->shouldPassThrough($request)
|
||||||
|
)
|
||||||
{
|
{
|
||||||
|
return $next($request);
|
||||||
|
}
|
||||||
|
|
||||||
// Check post limit and see if it may have been exceeded
|
// Check post limit and see if it may have been exceeded
|
||||||
$postLimit = MiscHelper::convertToBytes(ini_get('post_max_size'));
|
$postLimit = MiscHelper::convertToBytes(ini_get('post_max_size'));
|
||||||
|
|
||||||
@ -28,12 +54,27 @@ class CheckMaxPostSizeExceeded
|
|||||||
$request->session()->flash('error', trans('global.post_max_exceeded'));
|
$request->session()->flash('error', trans('global.post_max_exceeded'));
|
||||||
return back();
|
return back();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return $next($request);
|
return $next($request);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function shouldExclude(Request $request)
|
protected function isRunningInConsole()
|
||||||
|
{
|
||||||
|
return $this->app->runningInConsole();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine if the HTTP request uses a ‘read’ verb.
|
||||||
|
*
|
||||||
|
* @param \Illuminate\Http\Request $request
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
protected function isReading(Request $request)
|
||||||
|
{
|
||||||
|
return in_array($request->method(), ['HEAD', 'GET', 'OPTIONS']);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function shouldPassThrough(Request $request)
|
||||||
{
|
{
|
||||||
foreach ($this->exclude as $exclude)
|
foreach ($this->exclude as $exclude)
|
||||||
{
|
{
|
||||||
|
@ -26,6 +26,7 @@ class StoreAlbumRequest extends FormRequest
|
|||||||
return [
|
return [
|
||||||
'description' => '',
|
'description' => '',
|
||||||
'name' => 'required|unique:albums|max:255',
|
'name' => 'required|unique:albums|max:255',
|
||||||
|
'storage_id' => 'required'
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
31
app/Http/Requests/StoreStorageRequest.php
Normal file
31
app/Http/Requests/StoreStorageRequest.php
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Requests;
|
||||||
|
|
||||||
|
use Illuminate\Foundation\Http\FormRequest;
|
||||||
|
|
||||||
|
class StoreStorageRequest extends FormRequest
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Determine if the user is authorized to make this request.
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function authorize()
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the validation rules that apply to the request.
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function rules()
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'name' => 'required|unique:storages|max:255',
|
||||||
|
'source' => 'required|max:255',
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
@ -64,6 +64,11 @@ class AppServiceProvider extends ServiceProvider
|
|||||||
|
|
||||||
private function checkIfInstalled()
|
private function checkIfInstalled()
|
||||||
{
|
{
|
||||||
|
if ($this->app->runningInConsole())
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
if ($_SERVER['REQUEST_URI'] == '/install')
|
if ($_SERVER['REQUEST_URI'] == '/install')
|
||||||
{
|
{
|
||||||
$baseDirectory = dirname(dirname(__DIR__));
|
$baseDirectory = dirname(dirname(__DIR__));
|
||||||
|
20
app/Storage.php
Normal file
20
app/Storage.php
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App;
|
||||||
|
|
||||||
|
use Illuminate\Database\Eloquent\Model;
|
||||||
|
use Illuminate\Notifications\Notifiable;
|
||||||
|
|
||||||
|
class Storage extends Model
|
||||||
|
{
|
||||||
|
use Notifiable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The attributes that are mass assignable.
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
protected $fillable = [
|
||||||
|
'name', 'source', 'is_default', 'location'
|
||||||
|
];
|
||||||
|
}
|
@ -0,0 +1,35 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
|
||||||
|
class CreateStoragesTable extends Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function up()
|
||||||
|
{
|
||||||
|
Schema::create('storages', function (Blueprint $table) {
|
||||||
|
$table->increments('id');
|
||||||
|
$table->string('name');
|
||||||
|
$table->string('source', 100);
|
||||||
|
$table->boolean('is_default');
|
||||||
|
$table->string('location');
|
||||||
|
$table->timestamps();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function down()
|
||||||
|
{
|
||||||
|
Schema::dropIfExists('storages');
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,37 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
|
||||||
|
class AddAlbumStorageColumn extends Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function up()
|
||||||
|
{
|
||||||
|
Schema::table('albums', function (Blueprint $table) {
|
||||||
|
$table->unsignedInteger('storage_id');
|
||||||
|
|
||||||
|
$table->foreign('storage_id')
|
||||||
|
->references('id')->on('storages')
|
||||||
|
->onDelete('no action');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function down()
|
||||||
|
{
|
||||||
|
Schema::table('albums', function (Blueprint $table) {
|
||||||
|
$table->dropForeign('albums_storage_id_foreign');
|
||||||
|
$table->dropColumn('storage_id');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
@ -91,6 +91,13 @@ function AnalyseImageViewModel(image_info)
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function StorageLocationsViewModel()
|
||||||
|
{
|
||||||
|
var self = this;
|
||||||
|
|
||||||
|
self.selectedLocation = ko.observable(true);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This file is used by admin/show_album.blade.php to handle photo uploads.
|
* This file is used by admin/show_album.blade.php to handle photo uploads.
|
||||||
* @param album_id ID of the album the photos are being uploaded to
|
* @param album_id ID of the album the photos are being uploaded to
|
||||||
|
@ -14,6 +14,8 @@ return [
|
|||||||
'create_album' => 'Create a photo album',
|
'create_album' => 'Create a photo album',
|
||||||
'create_album_intro' => 'Photo albums contain individual photographs together in the same way as a physical photo album or memory book.',
|
'create_album_intro' => 'Photo albums contain individual photographs together in the same way as a physical photo album or memory book.',
|
||||||
'create_album_intro2' => 'Complete the form below to create a photo album.',
|
'create_album_intro2' => 'Complete the form below to create a photo album.',
|
||||||
|
'create_storage' => 'Create storage location',
|
||||||
|
'create_storage_intro' => 'Complete the form below to create a new storage location to hold your photos. You can then select this storage location when you create an album.',
|
||||||
'delete_album' => 'Delete album :name',
|
'delete_album' => 'Delete album :name',
|
||||||
'delete_album_confirm' => 'Are you sure you want to permanently delete this album and all its contents?',
|
'delete_album_confirm' => 'Are you sure you want to permanently delete this album and all its contents?',
|
||||||
'delete_album_warning' => 'This is a permanent action that cannot be undone!',
|
'delete_album_warning' => 'This is a permanent action that cannot be undone!',
|
||||||
@ -26,6 +28,9 @@ return [
|
|||||||
],
|
],
|
||||||
'no_albums_text' => 'You have no photo albums yet. Click the button below to create one.',
|
'no_albums_text' => 'You have no photo albums yet. Click the button below to create one.',
|
||||||
'no_albums_title' => 'No Photo Albums',
|
'no_albums_title' => 'No Photo Albums',
|
||||||
|
'no_storages_text' => 'You need a storage location to store your uploaded photographs.',
|
||||||
|
'no_storages_text2' => 'This can be on your server\'s local filesystem or a cloud location such as Amazon S3 or Rackspace.',
|
||||||
|
'no_storages_title' => 'No storage locations defined',
|
||||||
'open_album' => 'Open album',
|
'open_album' => 'Open album',
|
||||||
'photo_actions' => [
|
'photo_actions' => [
|
||||||
'delete' => 'Delete',
|
'delete' => 'Delete',
|
||||||
@ -34,7 +39,6 @@ return [
|
|||||||
'rotate_right' => 'Rotate right'
|
'rotate_right' => 'Rotate right'
|
||||||
],
|
],
|
||||||
'settings_image_protection' => 'Image Protection',
|
'settings_image_protection' => 'Image Protection',
|
||||||
'settings_link' => 'Settings',
|
|
||||||
'settings_recaptcha' => 'reCAPTCHA settings',
|
'settings_recaptcha' => 'reCAPTCHA settings',
|
||||||
'settings_save_action' => 'Update Settings',
|
'settings_save_action' => 'Update Settings',
|
||||||
'settings_saved_message' => 'The settings were updated successfully.',
|
'settings_saved_message' => 'The settings were updated successfully.',
|
||||||
@ -46,6 +50,7 @@ return [
|
|||||||
'photos' => 'photo|photos',
|
'photos' => 'photo|photos',
|
||||||
'users' => 'user|users',
|
'users' => 'user|users',
|
||||||
],
|
],
|
||||||
|
'storage_title' => 'Storage Locations',
|
||||||
'sysinfo_panel' => 'System information',
|
'sysinfo_panel' => 'System information',
|
||||||
'sysinfo_widget' => [
|
'sysinfo_widget' => [
|
||||||
'app_version' => 'Blue Twilight version:',
|
'app_version' => 'Blue Twilight version:',
|
||||||
|
@ -1,11 +1,13 @@
|
|||||||
<?php
|
<?php
|
||||||
return [
|
return [
|
||||||
|
'album_source_label' => 'Storage location:',
|
||||||
'apply_action' => 'Apply',
|
'apply_action' => 'Apply',
|
||||||
'bulk_edit_photos_label' => 'Bulk edit selected photos:',
|
'bulk_edit_photos_label' => 'Bulk edit selected photos:',
|
||||||
'bulk_edit_photos_placeholder' => 'Select an action',
|
'bulk_edit_photos_placeholder' => 'Select an action',
|
||||||
'cancel_action' => 'Cancel',
|
'cancel_action' => 'Cancel',
|
||||||
'continue_action' => 'Continue',
|
'continue_action' => 'Continue',
|
||||||
'create_action' => 'Create',
|
'create_action' => 'Create',
|
||||||
|
'default_storage_label' => 'Use as the default storage location for new albums',
|
||||||
'delete_action' => 'Delete',
|
'delete_action' => 'Delete',
|
||||||
'description_label' => 'Description:',
|
'description_label' => 'Description:',
|
||||||
'edit_action' => 'Edit',
|
'edit_action' => 'Edit',
|
||||||
@ -23,6 +25,8 @@ return [
|
|||||||
'settings_hotlink_protection_help' => 'With this option enabled, direct linking to images is not allowed. Photos can only be viewed through Blue Twilight.',
|
'settings_hotlink_protection_help' => 'With this option enabled, direct linking to images is not allowed. Photos can only be viewed through Blue Twilight.',
|
||||||
'settings_restrict_originals_download' => 'Restrict access to original images',
|
'settings_restrict_originals_download' => 'Restrict access to original images',
|
||||||
'settings_restrict_originals_download_help' => 'With this option enabled, only the photo\'s owner can download the original high-resolution images.',
|
'settings_restrict_originals_download_help' => 'With this option enabled, only the photo\'s owner can download the original high-resolution images.',
|
||||||
|
'storage_driver_label' => 'Storage driver:',
|
||||||
|
'storage_location_label' => 'Physical location:',
|
||||||
'upload_action' => 'Upload',
|
'upload_action' => 'Upload',
|
||||||
'save_action' => 'Save Changes'
|
'save_action' => 'Save Changes'
|
||||||
];
|
];
|
@ -1,5 +1,8 @@
|
|||||||
<?php
|
<?php
|
||||||
return [
|
return [
|
||||||
|
'album_sources' => [
|
||||||
|
'filesystem' => 'Local filesystem'
|
||||||
|
],
|
||||||
'app_name' => 'Blue Twilight',
|
'app_name' => 'Blue Twilight',
|
||||||
'post_max_exceeded' => 'Your upload exceeded the maximum size the web server is configured to allow. Please check the value of the "post_max_size" parameter in php.ini.',
|
'post_max_exceeded' => 'Your upload exceeded the maximum size the web server is configured to allow. Please check the value of the "post_max_size" parameter in php.ini.',
|
||||||
'units' => [
|
'units' => [
|
||||||
|
@ -5,9 +5,11 @@ return [
|
|||||||
'albums' => 'Albums',
|
'albums' => 'Albums',
|
||||||
'create_album' => 'Create album',
|
'create_album' => 'Create album',
|
||||||
'delete_album' => 'Delete album',
|
'delete_album' => 'Delete album',
|
||||||
|
'create_storage' => 'Create storage',
|
||||||
'edit_album' => 'Edit album',
|
'edit_album' => 'Edit album',
|
||||||
'home' => 'Gallery',
|
'home' => 'Gallery',
|
||||||
'settings' => 'Settings',
|
'settings' => 'Settings',
|
||||||
|
'storage' => 'Storage',
|
||||||
'users' => 'Users'
|
'users' => 'Users'
|
||||||
],
|
],
|
||||||
'navbar' => [
|
'navbar' => [
|
||||||
|
@ -44,6 +44,11 @@
|
|||||||
{!! Form::textarea('description', old('description'), ['class' => 'form-control']) !!}
|
{!! Form::textarea('description', old('description'), ['class' => 'form-control']) !!}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
{!! Form::label('storage_id', trans('forms.album_source_label'), ['class' => 'control-label']) !!}
|
||||||
|
{!! Form::select('storage_id', $album_sources, old('storage_id', $default_storage_id), ['class' => 'form-control']) !!}
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="checkbox">
|
<div class="checkbox">
|
||||||
<label>
|
<label>
|
||||||
<input type="checkbox" name="is_private">
|
<input type="checkbox" name="is_private">
|
||||||
|
77
resources/views/themes/base/admin/create_storage.blade.php
Normal file
77
resources/views/themes/base/admin/create_storage.blade.php
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
@extends('themes.base.layout')
|
||||||
|
@section('title', trans('admin.create_storage'))
|
||||||
|
|
||||||
|
@section('breadcrumb')
|
||||||
|
<div class="breadcrumb">
|
||||||
|
<div class="container">
|
||||||
|
<ol class="breadcrumb">
|
||||||
|
<li><a href="{{ route('home') }}">@lang('navigation.breadcrumb.home')</a></li>
|
||||||
|
<li><a href="{{ route('admin') }}">@lang('navigation.breadcrumb.admin')</a></li>
|
||||||
|
<li><a href="{{ route('storage.index') }}">@lang('navigation.breadcrumb.storage')</a></li>
|
||||||
|
<li class="active">@lang('navigation.breadcrumb.create_storage')</li>
|
||||||
|
</ol>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
@endsection
|
||||||
|
|
||||||
|
@section('content')
|
||||||
|
<div class="container">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-xs-12">
|
||||||
|
<h1>@lang('admin.create_storage')</h1>
|
||||||
|
<p>@lang('admin.create_storage_intro')</p>
|
||||||
|
<hr/>
|
||||||
|
|
||||||
|
@if (count($errors) > 0)
|
||||||
|
<div class="alert alert-danger">
|
||||||
|
<ul>
|
||||||
|
@foreach ($errors->all() as $error)
|
||||||
|
<li>{{ $error }}</li>
|
||||||
|
@endforeach
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
@endif
|
||||||
|
|
||||||
|
{!! Form::open(['route' => 'storage.store', 'method' => 'POST']) !!}
|
||||||
|
<div class="form-group">
|
||||||
|
{!! Form::label('name', trans('forms.name_label'), ['class' => 'control-label']) !!}
|
||||||
|
{!! Form::text('name', old('name'), ['class' => 'form-control']) !!}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
{!! Form::label('source', trans('forms.album_source_label'), ['class' => 'control-label']) !!}
|
||||||
|
{!! Form::select('source', $album_sources, old('source'), ['class' => 'form-control', 'data-bind' => 'value: selectedLocation']) !!}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="storage-options">
|
||||||
|
<div id="local-filesystem" data-bind="visible: selectedLocation() == 'LocalFilesystemSource'">
|
||||||
|
<div class="form-group">
|
||||||
|
{!! Form::label('location', trans('forms.storage_driver_label'), ['class' => 'control-label']) !!}
|
||||||
|
{!! Form::text('location', old('location', $filesystem_default_location), ['class' => 'form-control']) !!}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="checkbox">
|
||||||
|
<label>
|
||||||
|
<input type="checkbox" name="is_default">
|
||||||
|
<strong>@lang('forms.default_storage_label')</strong>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-actions">
|
||||||
|
<a href="{{ route('albums.index') }}" class="btn btn-default">@lang('forms.cancel_action')</a>
|
||||||
|
{!! Form::submit(trans('forms.create_action'), ['class' => 'btn btn-success']) !!}
|
||||||
|
</div>
|
||||||
|
{!! Form::close() !!}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
@endsection
|
||||||
|
|
||||||
|
@push('scripts')
|
||||||
|
<script type="text/javascript">
|
||||||
|
var viewModel = new StorageLocationsViewModel();
|
||||||
|
ko.applyBindings(viewModel);
|
||||||
|
</script>
|
||||||
|
@endpush
|
58
resources/views/themes/base/admin/list_storage.blade.php
Normal file
58
resources/views/themes/base/admin/list_storage.blade.php
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
@extends('themes.base.layout')
|
||||||
|
@section('title', trans('admin.storage_title'))
|
||||||
|
|
||||||
|
@section('breadcrumb')
|
||||||
|
<div class="breadcrumb">
|
||||||
|
<div class="container">
|
||||||
|
<ol class="breadcrumb">
|
||||||
|
<li><a href="{{ route('home') }}">@lang('navigation.breadcrumb.home')</a></li>
|
||||||
|
<li><a href="{{ route('admin') }}">@lang('navigation.breadcrumb.admin')</a></li>
|
||||||
|
<li class="active">@lang('navigation.breadcrumb.storage')</li>
|
||||||
|
</ol>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
@endsection
|
||||||
|
|
||||||
|
@section('content')
|
||||||
|
<div class="container">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-xs-12">
|
||||||
|
@if (count($storageLocations) == 0)
|
||||||
|
<div class="text-center">
|
||||||
|
<h4 class="text-danger"><b>@lang('admin.no_storages_title')</b></h4>
|
||||||
|
<p>@lang('admin.no_storages_text')</p>
|
||||||
|
<p>@lang('admin.no_storages_text2')</p>
|
||||||
|
<p style="margin-top: 40px;">
|
||||||
|
<a href="{{ route('storage.create') }}" class="btn btn-lg btn-success">@lang('admin.create_storage')</a>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
@else
|
||||||
|
<table class="table table-hover table-striped">
|
||||||
|
<tbody>
|
||||||
|
@foreach ($storageLocations as $storage)
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<span style="font-size: 1.3em;">{{ $storage->name }}@if ($storage->is_default) <i class="fa fa-fw fa-check text-success"></i>@endif</span><br/>
|
||||||
|
{{ $storage->location }}
|
||||||
|
</td>
|
||||||
|
<td class="text-right">
|
||||||
|
<a href="{{ route('storage.edit', ['id' => $storage->id]) }}" class="btn btn-default">@lang('forms.edit_action')</a>
|
||||||
|
<a href="{{ route('storage.delete', ['id' => $storage->id]) }}" class="btn btn-danger">@lang('forms.delete_action')</a>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
@endforeach
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<div class="text-center">
|
||||||
|
{{ $storageLocations->links() }}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="pull-right" style="margin-top: 10px;">
|
||||||
|
<a href="{{ route('storage.create') }}" class="btn btn-success"><i class="fa fa-fw fa-plus"></i> @lang('admin.create_storage')</a>
|
||||||
|
</div>
|
||||||
|
@endif
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
@endsection
|
@ -4,7 +4,8 @@
|
|||||||
<ul class="nav nav-pills">
|
<ul class="nav nav-pills">
|
||||||
<li role="presentation"><a href="{{ route('albums.index') }}"><i class="fa fa-fw fa-picture-o"></i> @lang('navigation.breadcrumb.albums')</a></li>
|
<li role="presentation"><a href="{{ route('albums.index') }}"><i class="fa fa-fw fa-picture-o"></i> @lang('navigation.breadcrumb.albums')</a></li>
|
||||||
<li role="presentation"><a href="#"><i class="fa fa-fw fa-user"></i> @lang('navigation.breadcrumb.users')</a></li>
|
<li role="presentation"><a href="#"><i class="fa fa-fw fa-user"></i> @lang('navigation.breadcrumb.users')</a></li>
|
||||||
<li role="presentation"><a href="{{ route('admin.settings') }}"><i class="fa fa-fw fa-cog"></i> @lang('admin.settings_link')</a></li>
|
<li role="presentation"><a href="{{ route('admin.settings') }}"><i class="fa fa-fw fa-cog"></i> @lang('navigation.breadcrumb.settings')</a></li>
|
||||||
|
<li role="presentation"><a href="{{ route('storage.index') }}"><i class="fa fa-fw fa-folder"></i> @lang('navigation.breadcrumb.storage')</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
@ -32,6 +32,10 @@ Route::group(['prefix' => 'admin'], function () {
|
|||||||
Route::post('photos/store-bulk', 'Admin\PhotoController@storeBulk')->name('photos.storeBulk');
|
Route::post('photos/store-bulk', 'Admin\PhotoController@storeBulk')->name('photos.storeBulk');
|
||||||
Route::put('photos/update-bulk/{albumId}', 'Admin\PhotoController@updateBulk')->name('photos.updateBulk');
|
Route::put('photos/update-bulk/{albumId}', 'Admin\PhotoController@updateBulk')->name('photos.updateBulk');
|
||||||
Route::resource('photos', 'Admin\PhotoController');
|
Route::resource('photos', 'Admin\PhotoController');
|
||||||
|
|
||||||
|
// Storage management
|
||||||
|
Route::get('storage/{id}/delete', 'Admin\StorageController@delete')->name('storage.delete');
|
||||||
|
Route::resource('storage', 'Admin\StorageController');
|
||||||
});
|
});
|
||||||
|
|
||||||
// Gallery
|
// Gallery
|
||||||
|
Loading…
Reference in New Issue
Block a user