@ -42,6 +42,11 @@ abstract class AlbumSourceBase
|
|||||||
return self::$albumSourceCache[$fullClassName];
|
return self::$albumSourceCache[$fullClassName];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getConfiguration()
|
||||||
|
{
|
||||||
|
return $this->configuration;
|
||||||
|
}
|
||||||
|
|
||||||
public function setAlbum(Album $album)
|
public function setAlbum(Album $album)
|
||||||
{
|
{
|
||||||
$this->album = $album;
|
$this->album = $album;
|
||||||
|
@ -130,7 +130,19 @@ class AmazonS3Source extends AlbumSourceBase implements IAlbumSource, IAnalysisQ
|
|||||||
*/
|
*/
|
||||||
public function getUrlToPhoto(Photo $photo, $thumbnail = null)
|
public function getUrlToPhoto(Photo $photo, $thumbnail = null)
|
||||||
{
|
{
|
||||||
return $this->getClient()->getObjectUrl($this->configuration->container_name, $this->getPathToPhoto($photo, $thumbnail));
|
$client = $this->getClient();
|
||||||
|
|
||||||
|
if ($this->configuration->s3_signed_urls)
|
||||||
|
{
|
||||||
|
$cmd = $client->getCommand('GetObject', [
|
||||||
|
'Bucket' => $this->configuration->container_name,
|
||||||
|
'Key' => $this->getPathToPhoto($photo, $thumbnail)
|
||||||
|
]);
|
||||||
|
|
||||||
|
return $client->createPresignedRequest($cmd, '+5 minutes')->getUri();
|
||||||
|
}
|
||||||
|
|
||||||
|
return $client->getObjectUrl($this->configuration->container_name, $this->getPathToPhoto($photo, $thumbnail));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -144,7 +156,11 @@ class AmazonS3Source extends AlbumSourceBase implements IAlbumSource, IAnalysisQ
|
|||||||
{
|
{
|
||||||
$photoPath = $this->getPathToPhoto($photo, $thumbnail);
|
$photoPath = $this->getPathToPhoto($photo, $thumbnail);
|
||||||
|
|
||||||
$this->getClient()->upload($this->configuration->container_name, $photoPath, fopen($tempFilename, 'r+'), 'public-read');
|
$uploadAcl = $this->configuration->s3_signed_urls
|
||||||
|
? 'private'
|
||||||
|
: 'public-read';
|
||||||
|
|
||||||
|
$this->getClient()->upload($this->configuration->container_name, $photoPath, fopen($tempFilename, 'r+'), $uploadAcl);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -6,7 +6,6 @@ use App\Album;
|
|||||||
use App\Photo;
|
use App\Photo;
|
||||||
use App\Storage;
|
use App\Storage;
|
||||||
use Guzzle\Http\EntityBody;
|
use Guzzle\Http\EntityBody;
|
||||||
use Symfony\Component\HttpFoundation\File\File;
|
|
||||||
|
|
||||||
interface IAlbumSource
|
interface IAlbumSource
|
||||||
{
|
{
|
||||||
@ -32,6 +31,12 @@ interface IAlbumSource
|
|||||||
*/
|
*/
|
||||||
function fetchPhotoContent(Photo $photo, $thumbnail = null);
|
function fetchPhotoContent(Photo $photo, $thumbnail = null);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the configuration of the source.
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
function getConfiguration();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the name of this album source.
|
* Gets the name of this album source.
|
||||||
* @return string
|
* @return string
|
||||||
|
@ -11,7 +11,6 @@ use App\Facade\Theme;
|
|||||||
use App\Facade\UserConfig;
|
use App\Facade\UserConfig;
|
||||||
use App\Group;
|
use App\Group;
|
||||||
use App\Helpers\DbHelper;
|
use App\Helpers\DbHelper;
|
||||||
use App\Helpers\FileHelper;
|
|
||||||
use App\Helpers\MiscHelper;
|
use App\Helpers\MiscHelper;
|
||||||
use App\Helpers\PermissionsHelper;
|
use App\Helpers\PermissionsHelper;
|
||||||
use App\Http\Controllers\Controller;
|
use App\Http\Controllers\Controller;
|
||||||
@ -74,7 +73,7 @@ class AlbumController extends Controller
|
|||||||
|
|
||||||
if (count($photos) == 0)
|
if (count($photos) == 0)
|
||||||
{
|
{
|
||||||
return redirect(route('albums.show', ['id' => $album->id]));
|
return redirect(route('albums.show', ['album' => $album->id]));
|
||||||
}
|
}
|
||||||
|
|
||||||
return Theme::render('admin.analyse_album', ['album' => $album, 'photos' => $photos, 'queue_token' => $queue_token]);
|
return Theme::render('admin.analyse_album', ['album' => $album, 'photos' => $photos, 'queue_token' => $queue_token]);
|
||||||
@ -171,7 +170,7 @@ class AlbumController extends Controller
|
|||||||
|
|
||||||
$redirect->delete();
|
$redirect->delete();
|
||||||
$request->session()->flash('success', trans('admin.delete_redirect_success_message'));
|
$request->session()->flash('success', trans('admin.delete_redirect_success_message'));
|
||||||
return redirect(route('albums.show', ['id' => $id, 'tab' => 'redirects']));
|
return redirect(route('albums.show', ['album' => $id, 'tab' => 'redirects']));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -706,7 +705,7 @@ class AlbumController extends Controller
|
|||||||
$helper = new PermissionsHelper();
|
$helper = new PermissionsHelper();
|
||||||
$helper->rebuildCache();
|
$helper->rebuildCache();
|
||||||
|
|
||||||
return redirect(route('albums.show', ['id' => $album->id]));
|
return redirect(route('albums.show', ['album' => $album->id]));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function storeRedirect(Requests\StoreAlbumRedirectRequest $request, $id)
|
public function storeRedirect(Requests\StoreAlbumRedirectRequest $request, $id)
|
||||||
@ -721,7 +720,7 @@ class AlbumController extends Controller
|
|||||||
$redirect->save();
|
$redirect->save();
|
||||||
|
|
||||||
$request->session()->flash('success', trans('admin.create_redirect_success_message'));
|
$request->session()->flash('success', trans('admin.create_redirect_success_message'));
|
||||||
return redirect(route('albums.show', ['id' => $id, 'tab' => 'redirects']));
|
return redirect(route('albums.show', ['album' => $id, 'tab' => 'redirects']));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -783,7 +782,7 @@ class AlbumController extends Controller
|
|||||||
|
|
||||||
$request->session()->flash('success', trans('admin.album_saved_successfully', ['name' => $album->name]));
|
$request->session()->flash('success', trans('admin.album_saved_successfully', ['name' => $album->name]));
|
||||||
|
|
||||||
return redirect(route('albums.show', ['id' => $id]));
|
return redirect(route('albums.show', ['album' => $id]));
|
||||||
}
|
}
|
||||||
|
|
||||||
private function createActivityRecord(Album $album, $type, $activityDateTime = null)
|
private function createActivityRecord(Album $album, $type, $activityDateTime = null)
|
||||||
|
@ -134,7 +134,7 @@ class PhotoCommentController extends Controller
|
|||||||
if (count($commentIDs) == 1)
|
if (count($commentIDs) == 1)
|
||||||
{
|
{
|
||||||
// Single comment selected - redirect to the single delete page
|
// Single comment selected - redirect to the single delete page
|
||||||
return redirect(route('comments.delete', ['id' => $commentIDs[0]]));
|
return redirect(route('comments.delete', ['comment' => $commentIDs[0]]));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Show the view to confirm the delete
|
// Show the view to confirm the delete
|
||||||
@ -148,7 +148,7 @@ class PhotoCommentController extends Controller
|
|||||||
if (count($commentIDs) == 1)
|
if (count($commentIDs) == 1)
|
||||||
{
|
{
|
||||||
// Single comment selected - redirect to the single approve page
|
// Single comment selected - redirect to the single approve page
|
||||||
return redirect(route('comments.approve', ['id' => $commentIDs[0]]));
|
return redirect(route('comments.approve', ['comment' => $commentIDs[0]]));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Show the view to confirm the approval
|
// Show the view to confirm the approval
|
||||||
@ -162,7 +162,7 @@ class PhotoCommentController extends Controller
|
|||||||
if (count($commentIDs) == 1)
|
if (count($commentIDs) == 1)
|
||||||
{
|
{
|
||||||
// Single comment selected - redirect to the single reject page
|
// Single comment selected - redirect to the single reject page
|
||||||
return redirect(route('comments.reject', ['id' => $commentIDs[0]]));
|
return redirect(route('comments.reject', ['comment' => $commentIDs[0]]));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Show the view to confirm the rejection
|
// Show the view to confirm the rejection
|
||||||
|
@ -392,7 +392,7 @@ class PhotoController extends Controller
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
return redirect(route('albums.analyse', [
|
return redirect(route('albums.analyse', [
|
||||||
'id' => $album->id,
|
'album' => $album->id,
|
||||||
'queue_token' => $queueUid
|
'queue_token' => $queueUid
|
||||||
]));
|
]));
|
||||||
}
|
}
|
||||||
@ -408,7 +408,7 @@ class PhotoController extends Controller
|
|||||||
if (is_null($request->files->get('archive')))
|
if (is_null($request->files->get('archive')))
|
||||||
{
|
{
|
||||||
$request->session()->flash('error', trans('admin.upload_bulk_no_file'));
|
$request->session()->flash('error', trans('admin.upload_bulk_no_file'));
|
||||||
return redirect(route('albums.show', ['id' => $album->id]));
|
return redirect(route('albums.show', ['album' => $album->id]));
|
||||||
}
|
}
|
||||||
|
|
||||||
$archiveFile = UploadedFile::createFromBase($request->files->get('archive'));
|
$archiveFile = UploadedFile::createFromBase($request->files->get('archive'));
|
||||||
@ -416,7 +416,7 @@ class PhotoController extends Controller
|
|||||||
{
|
{
|
||||||
Log::error('Bulk image upload failed.', ['error' => $archiveFile->getError(), 'reason' => $archiveFile->getErrorMessage()]);
|
Log::error('Bulk image upload failed.', ['error' => $archiveFile->getError(), 'reason' => $archiveFile->getErrorMessage()]);
|
||||||
$request->session()->flash('error', $archiveFile->getErrorMessage());
|
$request->session()->flash('error', $archiveFile->getErrorMessage());
|
||||||
return redirect(route('albums.show', ['id' => $album->id]));
|
return redirect(route('albums.show', ['album' => $album->id]));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create the folder to hold the analysis results if not already present
|
// Create the folder to hold the analysis results if not already present
|
||||||
@ -446,7 +446,7 @@ class PhotoController extends Controller
|
|||||||
|
|
||||||
default:
|
default:
|
||||||
$request->session()->flash('error', sprintf('The file type "%s" is not supported for bulk uploads.', $mimeType));
|
$request->session()->flash('error', sprintf('The file type "%s" is not supported for bulk uploads.', $mimeType));
|
||||||
return redirect(route('albums.show', ['id' => $album->id]));
|
return redirect(route('albums.show', ['album' => $album->id]));
|
||||||
}
|
}
|
||||||
|
|
||||||
$di = new \RecursiveDirectoryIterator($temporaryFolder, \RecursiveDirectoryIterator::SKIP_DOTS);
|
$di = new \RecursiveDirectoryIterator($temporaryFolder, \RecursiveDirectoryIterator::SKIP_DOTS);
|
||||||
@ -523,7 +523,7 @@ class PhotoController extends Controller
|
|||||||
}
|
}
|
||||||
|
|
||||||
return redirect(route('albums.analyse', [
|
return redirect(route('albums.analyse', [
|
||||||
'id' => $album->id,
|
'album' => $album->id,
|
||||||
'queue_token' => $queueUid
|
'queue_token' => $queueUid
|
||||||
]));
|
]));
|
||||||
}
|
}
|
||||||
@ -586,7 +586,7 @@ class PhotoController extends Controller
|
|||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
return redirect(route('albums.show', array('id' => $albumId, 'page' => $request->get('page', 1))));
|
return redirect(route('albums.show', array('album' => $albumId, 'page' => $request->get('page', 1))));
|
||||||
}
|
}
|
||||||
|
|
||||||
private function applyBulkActions(Request $request, Album $album)
|
private function applyBulkActions(Request $request, Album $album)
|
||||||
|
@ -55,12 +55,14 @@ class StorageController extends Controller
|
|||||||
$this->authorizeAccessToAdminPanel('admin:manage-storage');
|
$this->authorizeAccessToAdminPanel('admin:manage-storage');
|
||||||
|
|
||||||
$filesystemDefaultLocation = sprintf('%s/storage/app/albums', dirname(dirname(dirname(dirname(__DIR__)))));
|
$filesystemDefaultLocation = sprintf('%s/storage/app/albums', dirname(dirname(dirname(dirname(__DIR__)))));
|
||||||
|
$storage = new Storage();
|
||||||
|
$storage->s3_signed_urls = true;
|
||||||
|
|
||||||
return Theme::render('admin.create_storage', [
|
return Theme::render('admin.create_storage', [
|
||||||
'album_sources' => UserConfig::albumSources(),
|
'album_sources' => UserConfig::albumSources(),
|
||||||
'filesystem_default_location' => $filesystemDefaultLocation,
|
'filesystem_default_location' => $filesystemDefaultLocation,
|
||||||
'info' => $request->session()->get('info'),
|
'info' => $request->session()->get('info'),
|
||||||
'storage' => new Storage()
|
'storage' => $storage
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -95,6 +97,7 @@ class StorageController extends Controller
|
|||||||
$storage->is_active = true;
|
$storage->is_active = true;
|
||||||
$storage->is_default = (strtolower($request->get('is_default')) == 'on');
|
$storage->is_default = (strtolower($request->get('is_default')) == 'on');
|
||||||
$storage->is_internal = false;
|
$storage->is_internal = false;
|
||||||
|
$storage->s3_signed_urls = (strtolower($request->get('s3_signed_urls')) == 'on');
|
||||||
|
|
||||||
if ($storage->source != 'LocalFilesystemSource' && isset($storage->location))
|
if ($storage->source != 'LocalFilesystemSource' && isset($storage->location))
|
||||||
{
|
{
|
||||||
@ -221,10 +224,12 @@ class StorageController extends Controller
|
|||||||
'access_key',
|
'access_key',
|
||||||
'secret_key',
|
'secret_key',
|
||||||
'b2_bucket_type',
|
'b2_bucket_type',
|
||||||
'access_token'
|
'access_token',
|
||||||
|
's3_signed_urls'
|
||||||
]));
|
]));
|
||||||
$storage->is_active = (strtolower($request->get('is_active')) == 'on');
|
$storage->is_active = (strtolower($request->get('is_active')) == 'on');
|
||||||
$storage->is_default = (strtolower($request->get('is_default')) == 'on');
|
$storage->is_default = (strtolower($request->get('is_default')) == 'on');
|
||||||
|
$storage->s3_signed_urls = (strtolower($request->get('s3_signed_urls')) == 'on');
|
||||||
|
|
||||||
if ($storage->is_default && !$storage->is_active)
|
if ($storage->is_default && !$storage->is_active)
|
||||||
{
|
{
|
||||||
|
@ -2,14 +2,11 @@
|
|||||||
|
|
||||||
namespace App\Http\Controllers\Gallery;
|
namespace App\Http\Controllers\Gallery;
|
||||||
|
|
||||||
use App\Album;
|
|
||||||
use App\AlbumRedirect;
|
use App\AlbumRedirect;
|
||||||
use App\Facade\Theme;
|
use App\Facade\Theme;
|
||||||
use App\Facade\UserConfig;
|
use App\Facade\UserConfig;
|
||||||
use App\Helpers\ConfigHelper;
|
|
||||||
use App\Helpers\DbHelper;
|
use App\Helpers\DbHelper;
|
||||||
use App\Http\Controllers\Controller;
|
use App\Http\Controllers\Controller;
|
||||||
use App\Http\Requests;
|
|
||||||
use App\VisitorHit;
|
use App\VisitorHit;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use Illuminate\Support\Facades\App;
|
use Illuminate\Support\Facades\App;
|
||||||
@ -34,7 +31,7 @@ class AlbumController extends Controller
|
|||||||
}
|
}
|
||||||
|
|
||||||
$album = DbHelper::getAlbumById($redirect->album_id);
|
$album = DbHelper::getAlbumById($redirect->album_id);
|
||||||
return redirect($album->url());
|
return redirect($album->url(), 301);
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->authorizeForUser($this->getUser(), 'view', $album);
|
$this->authorizeForUser($this->getUser(), 'view', $album);
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
namespace App;
|
namespace App;
|
||||||
|
|
||||||
|
use App\AlbumSources\IAlbumSource;
|
||||||
use Illuminate\Database\Eloquent\Model;
|
use Illuminate\Database\Eloquent\Model;
|
||||||
use Illuminate\Notifications\Notifiable;
|
use Illuminate\Notifications\Notifiable;
|
||||||
|
|
||||||
@ -110,9 +111,14 @@ class Photo extends Model
|
|||||||
|
|
||||||
public function thumbnailUrl($thumbnailName = null, $cacheBust = true)
|
public function thumbnailUrl($thumbnailName = null, $cacheBust = true)
|
||||||
{
|
{
|
||||||
$url = $this->album->getAlbumSource()->getUrlToPhoto($this, $thumbnailName);
|
/** @var IAlbumSource $source */
|
||||||
|
$source = $this->album->getAlbumSource();
|
||||||
|
$sourceConfiguration = $source->getConfiguration();
|
||||||
|
|
||||||
if ($cacheBust)
|
$url = $source->getUrlToPhoto($this, $thumbnailName);
|
||||||
|
|
||||||
|
// Cache busting doesn't work with S3 signed URLs
|
||||||
|
if ($cacheBust && !$sourceConfiguration->s3_signed_urls)
|
||||||
{
|
{
|
||||||
// Append the timestamp of the last update to avoid browser caching
|
// Append the timestamp of the last update to avoid browser caching
|
||||||
$theDate = is_null($this->updated_at) ? $this->created_at : $this->updated_at;
|
$theDate = is_null($this->updated_at) ? $this->created_at : $this->updated_at;
|
||||||
|
@ -5,58 +5,54 @@
|
|||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"type": "project",
|
"type": "project",
|
||||||
"require": {
|
"require": {
|
||||||
"php": ">=7.0.0",
|
"php": ">=7.2.0",
|
||||||
"ext-curl": "*",
|
"ext-curl": "*",
|
||||||
"ext-json": "*",
|
"ext-json": "*",
|
||||||
"laravel/framework": "5.5.*",
|
"aws/aws-sdk-php": "^3.134",
|
||||||
"rackspace/php-opencloud": "^1.16",
|
|
||||||
"doctrine/dbal": "^2.5",
|
"doctrine/dbal": "^2.5",
|
||||||
"aws/aws-sdk-php": "^3.19",
|
"laravel/framework": "^6.0",
|
||||||
"laravel/socialite": "^3.0",
|
"laravel/socialite": "^4.3",
|
||||||
"php-amqplib/php-amqplib": "^2.9"
|
"php-amqplib/php-amqplib": "^2.9",
|
||||||
|
"php-opencloud/openstack": "^3.0"
|
||||||
},
|
},
|
||||||
"require-dev": {
|
"require-dev": {
|
||||||
"filp/whoops": "~2.0",
|
"facade/ignition": "^1.4",
|
||||||
"fzaninotto/faker": "~1.4",
|
"fzaninotto/faker": "^1.9.1",
|
||||||
"mockery/mockery": "0.9.*",
|
"mockery/mockery": "^1.0",
|
||||||
"phpunit/phpunit": "~6.0",
|
"phpunit/phpunit": "^8.0"
|
||||||
"symfony/css-selector": "3.1.*",
|
|
||||||
"symfony/dom-crawler": "3.1.*"
|
|
||||||
},
|
},
|
||||||
"autoload": {
|
"autoload": {
|
||||||
"classmap": [
|
"classmap": [
|
||||||
"database"
|
"database/seeds",
|
||||||
|
"database/factories"
|
||||||
],
|
],
|
||||||
"psr-4": {
|
"psr-4": {
|
||||||
"App\\": "app/"
|
"App\\": "app/"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"autoload-dev": {
|
"autoload-dev": {
|
||||||
"classmap": [
|
"psr-4": {
|
||||||
]
|
"Tests\\": "tests/"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
"minimum-stability": "dev",
|
||||||
|
"prefer-stable": true,
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"post-root-package-install": [
|
|
||||||
"php -r \"file_exists('.env') || copy('.env.example', '.env');\""
|
|
||||||
],
|
|
||||||
"post-create-project-cmd": [
|
|
||||||
"php artisan key:generate"
|
|
||||||
],
|
|
||||||
"post-install-cmd": [
|
|
||||||
"Illuminate\\Foundation\\ComposerScripts::postInstall",
|
|
||||||
"php artisan optimize"
|
|
||||||
],
|
|
||||||
"post-update-cmd": [
|
|
||||||
"Illuminate\\Foundation\\ComposerScripts::postUpdate",
|
|
||||||
"php artisan optimize"
|
|
||||||
],
|
|
||||||
"post-autoload-dump": [
|
"post-autoload-dump": [
|
||||||
"Illuminate\\Foundation\\ComposerScripts::postAutoloadDump",
|
"Illuminate\\Foundation\\ComposerScripts::postAutoloadDump",
|
||||||
"@php artisan package:discover"
|
"@php artisan package:discover --ansi"
|
||||||
|
],
|
||||||
|
"post-root-package-install": [
|
||||||
|
"@php -r \"file_exists('.env') || copy('.env.example', '.env');\""
|
||||||
|
],
|
||||||
|
"post-create-project-cmd": [
|
||||||
|
"@php artisan key:generate --ansi"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"config": {
|
"config": {
|
||||||
|
"optimize-autoloader": true,
|
||||||
"preferred-install": "dist",
|
"preferred-install": "dist",
|
||||||
"discard-changes": true
|
"discard-changes": true,
|
||||||
|
"sort-packages": true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
2911
composer.lock
generated
52
config/hashing.php
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
return [
|
||||||
|
|
||||||
|
/*
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| Default Hash Driver
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
| This option controls the default hash driver that will be used to hash
|
||||||
|
| passwords for your application. By default, the bcrypt algorithm is
|
||||||
|
| used; however, you remain free to modify this option if you wish.
|
||||||
|
|
|
||||||
|
| Supported: "bcrypt", "argon"
|
||||||
|
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
'driver' => 'bcrypt',
|
||||||
|
|
||||||
|
/*
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| Bcrypt Options
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
| Here you may specify the configuration options that should be used when
|
||||||
|
| passwords are hashed using the Bcrypt algorithm. This will allow you
|
||||||
|
| to control the amount of time it takes to hash the given password.
|
||||||
|
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
'bcrypt' => [
|
||||||
|
'rounds' => env('BCRYPT_ROUNDS', 10),
|
||||||
|
],
|
||||||
|
|
||||||
|
/*
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| Argon Options
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
| Here you may specify the configuration options that should be used when
|
||||||
|
| passwords are hashed using the Argon algorithm. These will allow you
|
||||||
|
| to control the amount of time it takes to hash the given password.
|
||||||
|
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
'argon' => [
|
||||||
|
'memory' => 1024,
|
||||||
|
'threads' => 2,
|
||||||
|
'time' => 2,
|
||||||
|
],
|
||||||
|
|
||||||
|
];
|
81
config/logging.php
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Monolog\Handler\StreamHandler;
|
||||||
|
|
||||||
|
return [
|
||||||
|
|
||||||
|
/*
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| Default Log Channel
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
| This option defines the default log channel that gets used when writing
|
||||||
|
| messages to the logs. The name specified in this option should match
|
||||||
|
| one of the channels defined in the "channels" configuration array.
|
||||||
|
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
'default' => env('LOG_CHANNEL', 'stack'),
|
||||||
|
|
||||||
|
/*
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| Log Channels
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
| Here you may configure the log channels for your application. Out of
|
||||||
|
| the box, Laravel uses the Monolog PHP logging library. This gives
|
||||||
|
| you a variety of powerful log handlers / formatters to utilize.
|
||||||
|
|
|
||||||
|
| Available Drivers: "single", "daily", "slack", "syslog",
|
||||||
|
| "errorlog", "monolog",
|
||||||
|
| "custom", "stack"
|
||||||
|
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
'channels' => [
|
||||||
|
'stack' => [
|
||||||
|
'driver' => 'stack',
|
||||||
|
'channels' => ['single'],
|
||||||
|
],
|
||||||
|
|
||||||
|
'single' => [
|
||||||
|
'driver' => 'single',
|
||||||
|
'path' => storage_path('logs/laravel.log'),
|
||||||
|
'level' => 'debug',
|
||||||
|
],
|
||||||
|
|
||||||
|
'daily' => [
|
||||||
|
'driver' => 'daily',
|
||||||
|
'path' => storage_path('logs/laravel.log'),
|
||||||
|
'level' => 'debug',
|
||||||
|
'days' => 7,
|
||||||
|
],
|
||||||
|
|
||||||
|
'slack' => [
|
||||||
|
'driver' => 'slack',
|
||||||
|
'url' => env('LOG_SLACK_WEBHOOK_URL'),
|
||||||
|
'username' => 'Laravel Log',
|
||||||
|
'emoji' => ':boom:',
|
||||||
|
'level' => 'critical',
|
||||||
|
],
|
||||||
|
|
||||||
|
'stderr' => [
|
||||||
|
'driver' => 'monolog',
|
||||||
|
'handler' => StreamHandler::class,
|
||||||
|
'with' => [
|
||||||
|
'stream' => 'php://stderr',
|
||||||
|
],
|
||||||
|
],
|
||||||
|
|
||||||
|
'syslog' => [
|
||||||
|
'driver' => 'syslog',
|
||||||
|
'level' => 'debug',
|
||||||
|
],
|
||||||
|
|
||||||
|
'errorlog' => [
|
||||||
|
'driver' => 'errorlog',
|
||||||
|
'level' => 'debug',
|
||||||
|
],
|
||||||
|
],
|
||||||
|
|
||||||
|
];
|
@ -0,0 +1,32 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
|
class AddS3SignedUrlsColumnToStoragesTable extends Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function up()
|
||||||
|
{
|
||||||
|
Schema::table('storages', function (Blueprint $table) {
|
||||||
|
$table->boolean('s3_signed_urls');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function down()
|
||||||
|
{
|
||||||
|
Schema::table('storages', function (Blueprint $table) {
|
||||||
|
$table->dropColumn('s3_signed_urls');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
1
public/svg/403.svg
Normal file
Before Width: | Height: | Size: 6.5 KiB After Width: | Height: | Size: 6.5 KiB |
1
public/svg/404.svg
Normal file
@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 1024 1024"><defs><linearGradient id="a" x1="50.31%" x2="50%" y1="74.74%" y2="0%"><stop offset="0%" stop-color="#FFE98A"/><stop offset="67.7%" stop-color="#B63E59"/><stop offset="100%" stop-color="#68126F"/></linearGradient><circle id="c" cx="603" cy="682" r="93"/><filter id="b" width="203.2%" height="203.2%" x="-51.6%" y="-51.6%" filterUnits="objectBoundingBox"><feOffset in="SourceAlpha" result="shadowOffsetOuter1"/><feGaussianBlur in="shadowOffsetOuter1" result="shadowBlurOuter1" stdDeviation="32"/><feColorMatrix in="shadowBlurOuter1" values="0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 1 0"/></filter><linearGradient id="d" x1="49.48%" x2="49.87%" y1="11.66%" y2="77.75%"><stop offset="0%" stop-color="#F7EAB9"/><stop offset="100%" stop-color="#E5765E"/></linearGradient><linearGradient id="e" x1="91.59%" x2="66.97%" y1="5.89%" y2="100%"><stop offset="0%" stop-color="#A22A50"/><stop offset="100%" stop-color="#EE7566"/></linearGradient><linearGradient id="f" x1="49.48%" x2="49.61%" y1="11.66%" y2="98.34%"><stop offset="0%" stop-color="#F7EAB9"/><stop offset="100%" stop-color="#E5765E"/></linearGradient><linearGradient id="g" x1="78.5%" x2="36.4%" y1="106.76%" y2="26.41%"><stop offset="0%" stop-color="#A22A50"/><stop offset="100%" stop-color="#EE7566"/></linearGradient></defs><g fill="none" fill-rule="evenodd"><rect width="1024" height="1024" fill="url(#a)"/><use fill="black" filter="url(#b)" xlink:href="#c"/><use fill="#FFF6CB" xlink:href="#c"/><g fill="#FFFFFF" opacity=".3" transform="translate(14 23)"><circle cx="203" cy="255" r="3" fill-opacity=".4"/><circle cx="82" cy="234" r="2"/><circle cx="22" cy="264" r="2" opacity=".4"/><circle cx="113" cy="65" r="3"/><circle cx="202" cy="2" r="2"/><circle cx="2" cy="114" r="2"/><circle cx="152" cy="144" r="2"/><circle cx="362" cy="224" r="2"/><circle cx="453" cy="65" r="3" opacity=".4"/><circle cx="513" cy="255" r="3"/><circle cx="593" cy="115" r="3"/><circle cx="803" cy="5" r="3" opacity=".4"/><circle cx="502" cy="134" r="2"/><circle cx="832" cy="204" r="2"/><circle cx="752" cy="114" r="2"/><circle cx="933" cy="255" r="3" opacity=".4"/><circle cx="703" cy="225" r="3"/><circle cx="903" cy="55" r="3"/><circle cx="982" cy="144" r="2"/><circle cx="632" cy="14" r="2"/></g><g transform="translate(0 550)"><path fill="#8E2C15" d="M259 5.47c0 5.33 3.33 9.5 10 12.5s9.67 9.16 9 18.5h1c.67-6.31 1-11.8 1-16.47 8.67 0 13.33-1.33 14-4 .67 4.98 1.67 8.3 3 9.97 1.33 1.66 2 5.16 2 10.5h1c0-5.65.33-9.64 1-11.97 1-3.5 4-10.03-1-14.53S295 7 290 3c-5-4-10-3-13 2s-5 7-9 7-5-3.53-5-5.53c0-2 2-5-1.5-5s-7.5 0-7.5 2c0 1.33 1.67 2 5 2z"/><path fill="url(#d)" d="M1024 390H0V105.08C77.3 71.4 155.26 35 297.4 35c250 0 250.76 125.25 500 125 84.03-.08 160.02-18.2 226.6-40.93V390z"/><path fill="url(#d)" d="M1024 442H0V271.82c137.51-15.4 203.1-50.49 356.67-60.1C555.24 199.3 606.71 86.59 856.74 86.59c72.78 0 124.44 10.62 167.26 25.68V442z"/><path fill="url(#e)" d="M1024 112.21V412H856.91c99.31-86.5 112.63-140.75 39.97-162.78C710.24 192.64 795.12 86.58 856.9 86.58c72.7 0 124.3 10.6 167.09 25.63z"/><path fill="url(#e)" d="M1024 285.32V412H857c99.31-86.6 112.63-140.94 39.97-163L1024 285.32z"/><path fill="url(#f)" d="M0 474V223.93C67.12 190.69 129.55 155 263 155c250 0 331.46 162.6 530 175 107.42 6.71 163-26.77 231-58.92V474H0z"/><path fill="url(#e)" d="M353.02 474H0V223.93C67.12 190.69 129.55 155 263 155c71.14 0 151.5 12.76 151.5 70.5 0 54.5-45.5 79.72-112.5 109-82.26 35.95-54.57 111.68 51.02 139.5z"/><path fill="url(#g)" d="M353.02 474H0v-14.8l302-124.7c-82.26 35.95-54.57 111.68 51.02 139.5z"/></g><g fill="#FFFFFF" opacity=".2" transform="translate(288 523)"><circle cx="250" cy="110" r="110"/><circle cx="420" cy="78" r="60"/><circle cx="70" cy="220" r="70"/></g><g fill="#FFFFFF" fill-rule="nonzero" opacity=".08" transform="translate(135 316)"><path d="M10 80.22a14.2 14.2 0 0 1 20 0 14.2 14.2 0 0 0 20 0l20-19.86a42.58 42.58 0 0 1 60 0l15 14.9a21.3 21.3 0 0 0 30 0 21.3 21.3 0 0 1 30 0l.9.9A47.69 47.69 0 0 1 220 110H0v-5.76c0-9.02 3.6-17.67 10-24.02zm559.1-66.11l5.9-5.86c11.07-11 28.93-11 40 0l10 9.94a14.19 14.19 0 0 0 20 0 14.19 14.19 0 0 1 20 0 16.36 16.36 0 0 0 21.3 1.5l8.7-6.47a33.47 33.47 0 0 1 40 0l4.06 3.03A39.6 39.6 0 0 1 755 48H555a47.77 47.77 0 0 1 14.1-33.89z"/></g></g></svg>
|
Before Width: | Height: | Size: 4.2 KiB After Width: | Height: | Size: 4.2 KiB |
1
public/svg/500.svg
Normal file
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 15 KiB |
1
public/svg/503.svg
Normal file
Before Width: | Height: | Size: 5.4 KiB After Width: | Height: | Size: 5.4 KiB |
@ -323,7 +323,10 @@ return [
|
|||||||
'photos' => 'photo|photos',
|
'photos' => 'photo|photos',
|
||||||
'users' => 'user|users',
|
'users' => 'user|users',
|
||||||
],
|
],
|
||||||
|
'storage_auth_url_label_help' => 'Leave blank to authenticate with Amazon S3. For an S3-compatible provider, enter your provider\'s authentication URL here.',
|
||||||
'storage_backblaze_access_key_id_help' => 'To use your account\'s master key, enter your account ID here.',
|
'storage_backblaze_access_key_id_help' => 'To use your account\'s master key, enter your account ID here.',
|
||||||
|
'storage_s3_signed_urls_help' => 'When enabled, Blue Twilight will upload your photos with a private ACL and will use signed URLs to display the photos to your visitors.',
|
||||||
|
'storage_s3_signed_urls_tooltip' => 'This location is set to use private images with signed URLs.',
|
||||||
'storage_title' => 'Storage Locations',
|
'storage_title' => 'Storage Locations',
|
||||||
'sysinfo_panel' => 'System information',
|
'sysinfo_panel' => 'System information',
|
||||||
'sysinfo_widget' => [
|
'sysinfo_widget' => [
|
||||||
|
@ -115,6 +115,7 @@ return [
|
|||||||
'storage_driver_label' => 'Storage driver:',
|
'storage_driver_label' => 'Storage driver:',
|
||||||
'storage_endpoint_url_label' => 'Endpoint URL (leave blank if using Amazon):',
|
'storage_endpoint_url_label' => 'Endpoint URL (leave blank if using Amazon):',
|
||||||
'storage_location_label' => 'Physical location:',
|
'storage_location_label' => 'Physical location:',
|
||||||
|
'storage_s3_signed_urls' => 'Upload files privately and use signed URLs',
|
||||||
'storage_secret_key_label' => 'Secret key:',
|
'storage_secret_key_label' => 'Secret key:',
|
||||||
'storage_service_name_label' => 'Service name:',
|
'storage_service_name_label' => 'Service name:',
|
||||||
'storage_service_region_label' => 'Region:',
|
'storage_service_region_label' => 'Region:',
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
<li class="breadcrumb-item"><a href="{{ route('home') }}"><i class="fa fa-fw fa-home"></i></a></li>
|
<li class="breadcrumb-item"><a href="{{ route('home') }}"><i class="fa fa-fw fa-home"></i></a></li>
|
||||||
<li class="breadcrumb-item"><a href="{{ route('admin') }}">@lang('navigation.breadcrumb.admin')</a></li>
|
<li class="breadcrumb-item"><a href="{{ route('admin') }}">@lang('navigation.breadcrumb.admin')</a></li>
|
||||||
<li class="breadcrumb-item"><a href="{{ route('albums.index') }}">@lang('navigation.breadcrumb.albums')</a></li>
|
<li class="breadcrumb-item"><a href="{{ route('albums.index') }}">@lang('navigation.breadcrumb.albums')</a></li>
|
||||||
<li class="breadcrumb-item"><a href="{{ route('albums.show', ['id' => $album->id]) }}">{{ $album->name }}</a></li>
|
<li class="breadcrumb-item"><a href="{{ route('albums.show', ['album' => $album->id]) }}">{{ $album->name }}</a></li>
|
||||||
<li class="breadcrumb-item active">@lang('navigation.breadcrumb.metadata_upgrade')</li>
|
<li class="breadcrumb-item active">@lang('navigation.breadcrumb.metadata_upgrade')</li>
|
||||||
@endsection
|
@endsection
|
||||||
|
|
||||||
@ -52,7 +52,7 @@
|
|||||||
<p class="text-danger"><b>@lang('admin.metadata_upgrade.warning')</b></p>
|
<p class="text-danger"><b>@lang('admin.metadata_upgrade.warning')</b></p>
|
||||||
|
|
||||||
<div class="text-right">
|
<div class="text-right">
|
||||||
<a href="{{ route('admin.metadataUpgrade', ['id' => $album->id]) }}" class="btn btn-link">@lang('forms.cancel_action')</a>
|
<a href="{{ route('admin.metadataUpgrade', ['album' => $album->id]) }}" class="btn btn-link">@lang('forms.cancel_action')</a>
|
||||||
<button id="submit-button" type="submit" class="btn btn-primary"><i class="fa fa-fw fa-check"></i> @lang('forms.continue_action')</button>
|
<button id="submit-button" type="submit" class="btn btn-primary"><i class="fa fa-fw fa-check"></i> @lang('forms.continue_action')</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -97,7 +97,7 @@
|
|||||||
app.analyseImage(new AnalyseImageViewModel({
|
app.analyseImage(new AnalyseImageViewModel({
|
||||||
'id': '{{ $photo->id }}',
|
'id': '{{ $photo->id }}',
|
||||||
'name': '{!! addslashes($photo->name) !!}',
|
'name': '{!! addslashes($photo->name) !!}',
|
||||||
'url': '{{ route('photos.re-analyse', ['id' => $photo->id, 'queue_token' => $queue_token]) }}'
|
'url': '{{ route('photos.re-analyse', ['photo' => $photo->id, 'queue_token' => $queue_token]) }}'
|
||||||
}));
|
}));
|
||||||
@endforeach
|
@endforeach
|
||||||
});
|
});
|
||||||
|
@ -50,7 +50,7 @@
|
|||||||
|
|
||||||
<div class="text-right">
|
<div class="text-right">
|
||||||
<a class="btn btn-link" href="{{ $album->url() }}">View album</a>
|
<a class="btn btn-link" href="{{ $album->url() }}">View album</a>
|
||||||
<a class="btn btn-primary" href="{{ route('albums.show', ['id' => $album->id]) }}"><i class="fa fa-fw fa-chevron-left"></i> Back to album settings</a>
|
<a class="btn btn-primary" href="{{ route('albums.show', ['album' => $album->id]) }}"><i class="fa fa-fw fa-chevron-left"></i> Back to album settings</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -69,7 +69,7 @@
|
|||||||
app.analyseImage(new AnalyseImageViewModel({
|
app.analyseImage(new AnalyseImageViewModel({
|
||||||
'id': '{{ $photo->id }}',
|
'id': '{{ $photo->id }}',
|
||||||
'name': '{!! addslashes($photo->name) !!}',
|
'name': '{!! addslashes($photo->name) !!}',
|
||||||
'url': '{{ route('photos.analyse', ['id' => $photo->id, 'queue_token' => $queue_token]) }}'
|
'url': '{{ route('photos.analyse', ['photo' => $photo->id, 'queue_token' => $queue_token]) }}'
|
||||||
}));
|
}));
|
||||||
@endforeach
|
@endforeach
|
||||||
</script>
|
</script>
|
||||||
|
@ -23,7 +23,7 @@
|
|||||||
<form action="{{ route('albums.destroy', [$album->id]) }}" method="POST">
|
<form action="{{ route('albums.destroy', [$album->id]) }}" method="POST">
|
||||||
{{ csrf_field() }}
|
{{ csrf_field() }}
|
||||||
{{ method_field('DELETE') }}
|
{{ method_field('DELETE') }}
|
||||||
<a href="{{ route('albums.show', ['id' => $album->id]) }}" class="btn btn-link">@lang('forms.cancel_action')</a>
|
<a href="{{ route('albums.show', ['album' => $album->id]) }}" class="btn btn-link">@lang('forms.cancel_action')</a>
|
||||||
<button type="submit" class="btn btn-danger"><i class="fa fa-fw fa-trash"></i> @lang('forms.delete_action')</button>
|
<button type="submit" class="btn btn-danger"><i class="fa fa-fw fa-trash"></i> @lang('forms.delete_action')</button>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
@ -75,7 +75,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="text-right">
|
<div class="text-right">
|
||||||
<a href="{{ route('albums.show', ['id' => $album->id]) }}" class="btn btn-link">@lang('forms.cancel_action')</a>
|
<a href="{{ route('albums.show', ['album' => $album->id]) }}" class="btn btn-link">@lang('forms.cancel_action')</a>
|
||||||
<button type="submit" class="btn btn-success"><i class="fa fa-fw fa-check"></i> @lang('forms.save_action')</button>
|
<button type="submit" class="btn btn-success"><i class="fa fa-fw fa-check"></i> @lang('forms.save_action')</button>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
@ -66,11 +66,6 @@
|
|||||||
@include(Theme::viewName('partials.admin_storages_backblaze_b2_options'))
|
@include(Theme::viewName('partials.admin_storages_backblaze_b2_options'))
|
||||||
@endif
|
@endif
|
||||||
|
|
||||||
@if ($storage->source == 'DropboxSource')
|
|
||||||
<hr/>
|
|
||||||
@include(Theme::viewName('partials.admin_storages_dropbox_options'))
|
|
||||||
@endif
|
|
||||||
|
|
||||||
<div class="text-right">
|
<div class="text-right">
|
||||||
<a href="{{ route('storage.index') }}" class="btn btn-default">@lang('forms.cancel_action')</a>
|
<a href="{{ route('storage.index') }}" class="btn btn-default">@lang('forms.cancel_action')</a>
|
||||||
<button type="submit" class="btn btn-success"><i class="fa fa-fw fa-check"></i> @lang('forms.save_action')</button>
|
<button type="submit" class="btn btn-success"><i class="fa fa-fw fa-check"></i> @lang('forms.save_action')</button>
|
||||||
|
@ -45,7 +45,7 @@
|
|||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<p>
|
<p>
|
||||||
{{-- TODO: edit comments <a href="{{ route('comments.edit', ['id' => $comment->id]) }}"><span style="font-size: 1.3em;">{{ $comment->name }}</span></a> --}}
|
{{-- TODO: edit comments <a href="{{ route('comments.edit', ['comment' => $comment->id]) }}"><span style="font-size: 1.3em;">{{ $comment->name }}</span></a> --}}
|
||||||
<span style="font-size: 1.3em;">{{ $comment->name }}</span>
|
<span style="font-size: 1.3em;">{{ $comment->name }}</span>
|
||||||
|
|
||||||
<br/>
|
<br/>
|
||||||
@ -67,16 +67,16 @@
|
|||||||
<div class="btn-toolbar pull-right">
|
<div class="btn-toolbar pull-right">
|
||||||
<div class="btn-group mr-2">
|
<div class="btn-group mr-2">
|
||||||
@if (!$comment->isModerated())
|
@if (!$comment->isModerated())
|
||||||
<a href="{{ route('comments.approve', ['id' => $comment->id]) }}" class="btn btn-outline-info">@lang('forms.approve_action')</a>
|
<a href="{{ route('comments.approve', ['comment' => $comment->id]) }}" class="btn btn-outline-info">@lang('forms.approve_action')</a>
|
||||||
<a href="{{ route('comments.reject', ['id' => $comment->id]) }}" class="btn btn-outline-info">@lang('forms.reject_action')</a>
|
<a href="{{ route('comments.reject', ['comment' => $comment->id]) }}" class="btn btn-outline-info">@lang('forms.reject_action')</a>
|
||||||
@elseif ($comment->isApproved())
|
@elseif ($comment->isApproved())
|
||||||
<a href="{{ route('comments.reject', ['id' => $comment->id]) }}" class="btn btn-outline-info">@lang('forms.reject_action')</a>
|
<a href="{{ route('comments.reject', ['comment' => $comment->id]) }}" class="btn btn-outline-info">@lang('forms.reject_action')</a>
|
||||||
@elseif ($comment->isRejected())
|
@elseif ($comment->isRejected())
|
||||||
<a href="{{ route('comments.approve', ['id' => $comment->id]) }}" class="btn btn-outline-info">@lang('forms.approve_action')</a>
|
<a href="{{ route('comments.approve', ['comment' => $comment->id]) }}" class="btn btn-outline-info">@lang('forms.approve_action')</a>
|
||||||
@endif
|
@endif
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<a href="{{ route('comments.delete', ['id' => $comment->id]) }}" class="btn btn-danger">@lang('forms.delete_action')</a>
|
<a href="{{ route('comments.delete', ['comment' => $comment->id]) }}" class="btn btn-danger">@lang('forms.delete_action')</a>
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
@ -30,11 +30,11 @@
|
|||||||
@foreach ($groups as $group)
|
@foreach ($groups as $group)
|
||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
<a href="{{ route('groups.edit', ['id' => $group->id]) }}"><span style="font-size: 1.3em;">{{ $group->name }}</span></a><br/>
|
<a href="{{ route('groups.edit', ['group' => $group->id]) }}"><span style="font-size: 1.3em;">{{ $group->name }}</span></a><br/>
|
||||||
<span class="{{ $group->users()->count() == 0 ? "text-danger" : "text-success" }}">{{ trans_choice('admin.group_number_users', $group->users()->count()) }}</span>
|
<span class="{{ $group->users()->count() == 0 ? "text-danger" : "text-success" }}">{{ trans_choice('admin.group_number_users', $group->users()->count()) }}</span>
|
||||||
</td>
|
</td>
|
||||||
<td class="text-right">
|
<td class="text-right">
|
||||||
<a href="{{ route('groups.delete', ['id' => $group->id]) }}" class="btn btn-danger">@lang('forms.delete_action')</a>
|
<a href="{{ route('groups.delete', ['group' => $group->id]) }}" class="btn btn-danger">@lang('forms.delete_action')</a>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
@endforeach
|
@endforeach
|
||||||
|
@ -32,20 +32,25 @@
|
|||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
<span style="font-size: 1.3em;">
|
<span style="font-size: 1.3em;">
|
||||||
<a href="{{ route('storage.edit', ['id' => $storage->id]) }}">{{ $storage->name }}</a>
|
<a href="{{ route('storage.edit', ['storage' => $storage->id]) }}">{{ $storage->name }}</a>
|
||||||
@if ($storage->is_default) <i class="fa fa-fw fa-check text-success"></i>@endif
|
@if ($storage->is_default) <i class="fa fa-fw fa-check text-success"></i>@endif
|
||||||
@if (!$storage->is_active) <i class="fa fa-fw fa-minus-circle text-danger"></i>@endif
|
@if (!$storage->is_active) <i class="fa fa-fw fa-minus-circle text-danger"></i>@endif
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span style="color: #888; font-style: italic;">
|
<span style="color: #888; font-style: italic;">
|
||||||
@if ($storage->source == 'LocalFilesystemSource'){{ $storage->location }}@endif
|
@if ($storage->source == 'LocalFilesystemSource'){{ $storage->location }}@endif
|
||||||
@if ($storage->source == 'OpenStackSource'){{ $storage->container_name }} - {{ $storage->service_name }}, {{ $storage->service_region }}@endif
|
@if ($storage->source == 'OpenStackSource'){{ $storage->container_name }} - {{ $storage->service_name }}, {{ $storage->service_region }}@endif
|
||||||
@if ($storage->source == 'AmazonS3Source'){{ $storage->container_name }} - {{ $storage->service_region }}@endif
|
@if ($storage->source == 'AmazonS3Source')
|
||||||
|
{{ $storage->container_name }} - {{ $storage->service_region }}
|
||||||
|
@if ($storage->s3_signed_urls)
|
||||||
|
<i class="fa fa-key ml-2" data-toggle="tooltip" title="@lang('admin.storage_s3_signed_urls_tooltip')"></i>
|
||||||
|
@endif
|
||||||
|
@endif
|
||||||
@if ($storage->source == 'RackspaceSource'){{ $storage->container_name }} - {{ $storage->service_region }}@endif
|
@if ($storage->source == 'RackspaceSource'){{ $storage->container_name }} - {{ $storage->service_region }}@endif
|
||||||
</span>
|
</span>
|
||||||
</td>
|
</td>
|
||||||
<td class="text-right">
|
<td class="text-right">
|
||||||
@if (!$storage->is_internal)
|
@if (!$storage->is_internal)
|
||||||
<a href="{{ route('storage.delete', ['id' => $storage->id]) }}" class="btn btn-danger">@lang('forms.delete_action')</a>
|
<a href="{{ route('storage.delete', ['storage' => $storage->id]) }}" class="btn btn-danger">@lang('forms.delete_action')</a>
|
||||||
@endif
|
@endif
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
@ -81,3 +86,11 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@endsection
|
@endsection
|
||||||
|
|
||||||
|
@push('scripts')
|
||||||
|
<script type="text/javascript">
|
||||||
|
$(function () {
|
||||||
|
$('[data-toggle="tooltip"]').tooltip()
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
@endpush
|
@ -21,7 +21,7 @@
|
|||||||
@foreach ($users as $user)
|
@foreach ($users as $user)
|
||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
<span style="font-size: 1.3em;"><a href="{{ route('users.edit', ['id' => $user->id]) }}">{{ $user->name }}</a>@if ($user->is_admin) <i class="fa fa-fw fa-cog"></i>@endif</span><br/>
|
<span style="font-size: 1.3em;"><a href="{{ route('users.edit', ['user' => $user->id]) }}">{{ $user->name }}</a>@if ($user->is_admin) <i class="fa fa-fw fa-cog"></i>@endif</span><br/>
|
||||||
{{ $user->email }} <a href="mailto:{{ $user->email }}"><i class="fa fa-fw fa-mail-forward"></i></a>
|
{{ $user->email }} <a href="mailto:{{ $user->email }}"><i class="fa fa-fw fa-mail-forward"></i></a>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
@ -30,7 +30,7 @@
|
|||||||
@endif
|
@endif
|
||||||
</td>
|
</td>
|
||||||
<td class="text-right">
|
<td class="text-right">
|
||||||
<a href="{{ route('users.delete', ['id' => $user->id]) }}" class="btn btn-danger">@lang('forms.delete_action')</a>
|
<a href="{{ route('users.delete', ['user' => $user->id]) }}" class="btn btn-danger">@lang('forms.delete_action')</a>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
@endforeach
|
@endforeach
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
@if ($parentAlbum->id == $album->id)
|
@if ($parentAlbum->id == $album->id)
|
||||||
<li class="breadcrumb-item active">{{ $album->name }}</li>
|
<li class="breadcrumb-item active">{{ $album->name }}</li>
|
||||||
@else
|
@else
|
||||||
<li class="breadcrumb-item"><a href="{{ route('albums.show', ['id' => $parentAlbum->id]) }}">{{ $parentAlbum->name }}</a></li>
|
<li class="breadcrumb-item"><a href="{{ route('albums.show', ['album' => $parentAlbum->id]) }}">{{ $parentAlbum->name }}</a></li>
|
||||||
@endif
|
@endif
|
||||||
@endforeach
|
@endforeach
|
||||||
@endsection
|
@endsection
|
||||||
@ -97,12 +97,12 @@
|
|||||||
language.upload_status = '{!! addslashes(trans('admin.upload_file_status_progress')) !!}';
|
language.upload_status = '{!! addslashes(trans('admin.upload_file_status_progress')) !!}';
|
||||||
|
|
||||||
var urls = [];
|
var urls = [];
|
||||||
urls.analyse = '{{ route('albums.analyse', ['id' => $album->id, 'queue_token' => $queue_token]) }}';
|
urls.analyse = '{{ route('albums.analyse', ['album' => $album->id, 'queue_token' => $queue_token]) }}';
|
||||||
urls.delete_photo = '{{ route('photos.destroy', ['id' => 0]) }}';
|
urls.delete_photo = '{{ route('photos.destroy', ['photo' => 0]) }}';
|
||||||
urls.flip_photo = '{{ route('photos.flip', ['id' => 0, 'horizontal' => -1, 'vertical' => -2]) }}';
|
urls.flip_photo = '{{ route('photos.flip', ['photo' => 0, 'horizontal' => -1, 'vertical' => -2]) }}';
|
||||||
urls.move_photo = '{{ route('photos.move', ['photoId' => 0]) }}';
|
urls.move_photo = '{{ route('photos.move', ['photo' => 0]) }}';
|
||||||
urls.regenerate_thumbnails = '{{ route('photos.regenerateThumbnails', ['photoId' => 0]) }}';
|
urls.regenerate_thumbnails = '{{ route('photos.regenerateThumbnails', ['photo' => 0]) }}';
|
||||||
urls.rotate_photo = '{{ route('photos.rotate', ['id' => 0, 'angle' => 1]) }}';
|
urls.rotate_photo = '{{ route('photos.rotate', ['photo' => 0, 'angle' => 1]) }}';
|
||||||
|
|
||||||
var viewModel = new UploadPhotosViewModel('{{ $album->id }}', '{{ $queue_token }}', language, urls);
|
var viewModel = new UploadPhotosViewModel('{{ $album->id }}', '{{ $queue_token }}', language, urls);
|
||||||
var editViewModel = new EditPhotosViewModel('{{ $album->id }}', language, urls);
|
var editViewModel = new EditPhotosViewModel('{{ $album->id }}', language, urls);
|
||||||
|
@ -23,7 +23,7 @@
|
|||||||
<label for="email" class="col-md-4 col-form-label text-md-right">@lang('forms.email_label')</label>
|
<label for="email" class="col-md-4 col-form-label text-md-right">@lang('forms.email_label')</label>
|
||||||
|
|
||||||
<div class="col-md-6">
|
<div class="col-md-6">
|
||||||
<input id="email" type="email" class="form-control{{ $errors->has('email') ? ' is-invalid' : '' }}" name="email" value="{{ $email or old('email') }}" autofocus>
|
<input id="email" type="email" class="form-control{{ $errors->has('email') ? ' is-invalid' : '' }}" name="email" value="{{ $email ?? old('email') }}" autofocus>
|
||||||
|
|
||||||
@if ($errors->has('email'))
|
@if ($errors->has('email'))
|
||||||
<div class="invalid-feedback">
|
<div class="invalid-feedback">
|
||||||
|
@ -13,7 +13,7 @@
|
|||||||
<div class="pull-right">
|
<div class="pull-right">
|
||||||
@can('edit', $album)
|
@can('edit', $album)
|
||||||
<div class="mb-3">
|
<div class="mb-3">
|
||||||
<a class="btn btn-secondary" href="{{ route('albums.show', ['id' => $album->id]) }}"><i class="fa fa-fw fa-eye"></i> @lang('gallery.manage_album_link_2')</a>
|
<a class="btn btn-secondary" href="{{ route('albums.show', ['album' => $album->id]) }}"><i class="fa fa-fw fa-eye"></i> @lang('gallery.manage_album_link_2')</a>
|
||||||
</div>
|
</div>
|
||||||
@endcan
|
@endcan
|
||||||
|
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col">
|
<div class="col">
|
||||||
<div class="pull-right">
|
<div class="pull-right">
|
||||||
<a class="btn btn-secondary" href="{{ route('albums.show', ['id' => $album->id]) }}"><i class="fa fa-fw fa-eye"></i> @lang('gallery.manage_album_link_2')</a>
|
<a class="btn btn-secondary" href="{{ route('albums.show', ['album' => $album->id]) }}"><i class="fa fa-fw fa-eye"></i> @lang('gallery.manage_album_link_2')</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -13,7 +13,7 @@
|
|||||||
<div class="pull-right">
|
<div class="pull-right">
|
||||||
@can('edit', $album)
|
@can('edit', $album)
|
||||||
<div class="mb-3">
|
<div class="mb-3">
|
||||||
<a class="btn btn-secondary" href="{{ route('albums.show', ['id' => $album->id]) }}"><i class="fa fa-fw fa-eye"></i> @lang('gallery.manage_album_link_2')</a>
|
<a class="btn btn-secondary" href="{{ route('albums.show', ['album' => $album->id]) }}"><i class="fa fa-fw fa-eye"></i> @lang('gallery.manage_album_link_2')</a>
|
||||||
</div>
|
</div>
|
||||||
@endcan
|
@endcan
|
||||||
|
|
||||||
|
@ -16,7 +16,7 @@
|
|||||||
<p class="card-text">{!! nl2br(e($album->description)) !!}</p>
|
<p class="card-text">{!! nl2br(e($album->description)) !!}</p>
|
||||||
|
|
||||||
@can('edit', $album)
|
@can('edit', $album)
|
||||||
<a href="{{ route('albums.show', ['id' => $album->id]) }}" class="card-link">@lang('gallery.manage_album_link')</a>
|
<a href="{{ route('albums.show', ['album' => $album->id]) }}" class="card-link">@lang('gallery.manage_album_link')</a>
|
||||||
@endcan
|
@endcan
|
||||||
</div>
|
</div>
|
||||||
<div class="card-footer">
|
<div class="card-footer">
|
||||||
@ -29,7 +29,7 @@
|
|||||||
|
|
||||||
@if (UserConfig::get('social_user_profiles'))
|
@if (UserConfig::get('social_user_profiles'))
|
||||||
<i class="fa fa-fw fa-user ml-2"></i>
|
<i class="fa fa-fw fa-user ml-2"></i>
|
||||||
@can('view', $album->user)
|
@if (\App\User::currentOrAnonymous()->can('view', $album->user))
|
||||||
<a href="{{ $album->user->profileUrl() }}">{{ $album->user->publicDisplayName() }}</a>
|
<a href="{{ $album->user->profileUrl() }}">{{ $album->user->publicDisplayName() }}</a>
|
||||||
@else
|
@else
|
||||||
{{ $album->user->publicDisplayName() }}
|
{{ $album->user->publicDisplayName() }}
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
@foreach ($album->albumParentTree() as $parentAlbum)
|
@foreach ($album->albumParentTree() as $parentAlbum)
|
||||||
@if ($parentAlbum->id == $album->id)
|
@if ($parentAlbum->id == $album->id)
|
||||||
@if (!empty($show_current_link) && $show_current_link)
|
@if (!empty($show_current_link) && $show_current_link)
|
||||||
<li class="breadcrumb-item active"><a href="{{ route('albums.show', ['id' => $album->id]) }}">{{ $album->name }}</a></li>
|
<li class="breadcrumb-item active"><a href="{{ route('albums.show', ['album' => $album->id]) }}">{{ $album->name }}</a></li>
|
||||||
@else
|
@else
|
||||||
<li class="breadcrumb-item active">{{ $album->name }}</li>
|
<li class="breadcrumb-item active">{{ $album->name }}</li>
|
||||||
@endif
|
@endif
|
||||||
@else
|
@else
|
||||||
<li class="breadcrumb-item"><a href="{{ route('albums.show', ['id' => $parentAlbum->id]) }}">{{ $parentAlbum->name }}</a></li>
|
<li class="breadcrumb-item"><a href="{{ route('albums.show', ['album' => $parentAlbum->id]) }}">{{ $parentAlbum->name }}</a></li>
|
||||||
@endif
|
@endif
|
||||||
@endforeach
|
@endforeach
|
@ -55,6 +55,7 @@
|
|||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label class="form-control-label" for="auth-url">@lang('forms.storage_auth_url_label')</label>
|
<label class="form-control-label" for="auth-url">@lang('forms.storage_auth_url_label')</label>
|
||||||
<input type="text" class="form-control{{ $errors->has('auth_url') ? ' is-invalid' : '' }}" id="auth-url" name="auth_url" value="{{ old('auth_url', $storage->auth_url) }}">
|
<input type="text" class="form-control{{ $errors->has('auth_url') ? ' is-invalid' : '' }}" id="auth-url" name="auth_url" value="{{ old('auth_url', $storage->auth_url) }}">
|
||||||
|
<small class="form-text text-muted">@lang('admin.storage_auth_url_label_help')</small>
|
||||||
|
|
||||||
@if ($errors->has('auth_url'))
|
@if ($errors->has('auth_url'))
|
||||||
<div class="invalid-feedback">
|
<div class="invalid-feedback">
|
||||||
@ -62,3 +63,11 @@
|
|||||||
</div>
|
</div>
|
||||||
@endif
|
@endif
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="form-check form-group">
|
||||||
|
<input type="checkbox" class="form-check-input" id="s3-signed-urls" name="s3_signed_urls"@if (old('s3_signed_urls', $storage->s3_signed_urls)) checked="checked"@endif>
|
||||||
|
<label for="s3-signed-urls" class="form-check-label">
|
||||||
|
<strong>@lang('forms.storage_s3_signed_urls')</strong><br>
|
||||||
|
@lang('admin.storage_s3_signed_urls_help')
|
||||||
|
</label>
|
||||||
|
</div>
|
@ -32,7 +32,7 @@
|
|||||||
<hr/>
|
<hr/>
|
||||||
<h5 style="font-weight: bold;">@lang('admin.security_groups_heading')</h5>
|
<h5 style="font-weight: bold;">@lang('admin.security_groups_heading')</h5>
|
||||||
|
|
||||||
<form action="{{ route('albums.set_group_permissions', ['id' => $album->id]) }}" method="post">
|
<form action="{{ route('albums.set_group_permissions', ['album' => $album->id]) }}" method="post">
|
||||||
{{ csrf_field() }}
|
{{ csrf_field() }}
|
||||||
|
|
||||||
@if (count($existing_groups) > 0)
|
@if (count($existing_groups) > 0)
|
||||||
@ -72,7 +72,7 @@
|
|||||||
|
|
||||||
<h5 style="font-weight: bold;">@lang('admin.security_users_heading')</h5>
|
<h5 style="font-weight: bold;">@lang('admin.security_users_heading')</h5>
|
||||||
|
|
||||||
<form action="{{ route('albums.set_user_permissions', ['id' => $album->id]) }}" method="post">
|
<form action="{{ route('albums.set_user_permissions', ['album' => $album->id]) }}" method="post">
|
||||||
{{ csrf_field() }}
|
{{ csrf_field() }}
|
||||||
|
|
||||||
<div id="users-accordion" role="tablist" aria-multiselectable="true">
|
<div id="users-accordion" role="tablist" aria-multiselectable="true">
|
||||||
|
@ -65,7 +65,7 @@
|
|||||||
<div class="card-body bg-light">
|
<div class="card-body bg-light">
|
||||||
<p class="text-danger">@lang('admin.danger_zone_intro')</p>
|
<p class="text-danger">@lang('admin.danger_zone_intro')</p>
|
||||||
<div>
|
<div>
|
||||||
<a href="{{ route('albums.delete', ['id' => $album->id]) }}" class="btn btn-danger">@lang('forms.delete_action')</a>
|
<a href="{{ route('albums.delete', ['album' => $album->id]) }}" class="btn btn-danger">@lang('forms.delete_action')</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -97,7 +97,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="modal-footer" v-if="!isUploadInProgress">
|
<div class="modal-footer" v-if="!isUploadInProgress">
|
||||||
<button type="button" class="btn btn-secondary" data-dismiss="modal" v-if="imagesUploaded === 0">@lang('forms.close_action')</button>
|
<button type="button" class="btn btn-secondary" data-dismiss="modal" v-if="imagesUploaded === 0">@lang('forms.close_action')</button>
|
||||||
<a href="{{ route('albums.analyse', ['id' => $album->id, 'queue_token' => $queue_token]) }}" class="btn btn-primary" v-if="imagesUploaded > 0">@lang('forms.continue_action')</a>
|
<a href="{{ route('albums.analyse', ['album' => $album->id, 'queue_token' => $queue_token]) }}" class="btn btn-primary" v-if="imagesUploaded > 0">@lang('forms.continue_action')</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -22,7 +22,7 @@
|
|||||||
@endif
|
@endif
|
||||||
|
|
||||||
@if (UserConfig::get('social_user_profiles'))
|
@if (UserConfig::get('social_user_profiles'))
|
||||||
@can('view', $childAlbum->user)
|
@if (\App\User::currentOrAnonymous()->can('view', $childAlbum->user))
|
||||||
<a href="{{ $childAlbum->user->profileUrl() }}" data-toggle="tooltip" data-placement="top" title="{{ $childAlbum->user->publicDisplayName() }}"><i class="fa fa-fw fa-user ml-2"></i></a>
|
<a href="{{ $childAlbum->user->profileUrl() }}" data-toggle="tooltip" data-placement="top" title="{{ $childAlbum->user->publicDisplayName() }}"><i class="fa fa-fw fa-user ml-2"></i></a>
|
||||||
@else
|
@else
|
||||||
<i class="fa fa-fw fa-user ml-2" data-toggle="tooltip" data-placement="top" title="{{ $childAlbum->user->publicDisplayName() }}"></i>
|
<i class="fa fa-fw fa-user ml-2" data-toggle="tooltip" data-placement="top" title="{{ $childAlbum->user->publicDisplayName() }}"></i>
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
<td>
|
<td>
|
||||||
<span style="font-size: 1.3em;">
|
<span style="font-size: 1.3em;">
|
||||||
@can('edit', $album)
|
@can('edit', $album)
|
||||||
<a href="{{ route('albums.show', ['id' => $album->id]) }}">{{ $album->name }}</a>
|
<a href="{{ route('albums.show', ['album' => $album->id]) }}">{{ $album->name }}</a>
|
||||||
@endcan
|
@endcan
|
||||||
@cannot('edit', $album)
|
@cannot('edit', $album)
|
||||||
{{ $album->name }} <i class="fa fa-fw fa-lock"></i>
|
{{ $album->name }} <i class="fa fa-fw fa-lock"></i>
|
||||||
@ -27,7 +27,7 @@
|
|||||||
<td class="text-right">
|
<td class="text-right">
|
||||||
<div class="btn-group">
|
<div class="btn-group">
|
||||||
@if ($album->min_metadata_version < $current_metadata_version)
|
@if ($album->min_metadata_version < $current_metadata_version)
|
||||||
<a href="{{ route('albums.metadata', ['id' => $album->id]) }}" class="btn btn-primary">@lang('admin.metadata_upgrade.upgrade_button')</a>
|
<a href="{{ route('albums.metadata', ['album' => $album->id]) }}" class="btn btn-primary">@lang('admin.metadata_upgrade.upgrade_button')</a>
|
||||||
@endcan
|
@endcan
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
<td>
|
<td>
|
||||||
<span style="font-size: 1.3em;">
|
<span style="font-size: 1.3em;">
|
||||||
@can('edit', $album)
|
@can('edit', $album)
|
||||||
<a href="{{ route('albums.show', ['id' => $album->id]) }}">{{ $album->name }}</a>
|
<a href="{{ route('albums.show', ['album' => $album->id]) }}">{{ $album->name }}</a>
|
||||||
@endcan
|
@endcan
|
||||||
@cannot('edit', $album)
|
@cannot('edit', $album)
|
||||||
{{ $album->name }} <i class="fa fa-fw fa-lock"></i>
|
{{ $album->name }} <i class="fa fa-fw fa-lock"></i>
|
||||||
@ -24,10 +24,10 @@
|
|||||||
<td class="text-right">
|
<td class="text-right">
|
||||||
<div class="btn-group">
|
<div class="btn-group">
|
||||||
@can('edit', $album)
|
@can('edit', $album)
|
||||||
<a href="{{ route('albums.edit', ['id' => $album->id]) }}" class="btn btn-secondary">@lang('forms.edit_action')</a>
|
<a href="{{ route('albums.edit', ['album' => $album->id]) }}" class="btn btn-secondary">@lang('forms.edit_action')</a>
|
||||||
@endcan
|
@endcan
|
||||||
@can('delete', $album)
|
@can('delete', $album)
|
||||||
<a href="{{ route('albums.delete', ['id' => $album->id]) }}" class="btn btn-danger">@lang('forms.delete_action')</a>
|
<a href="{{ route('albums.delete', ['album' => $album->id]) }}" class="btn btn-danger">@lang('forms.delete_action')</a>
|
||||||
@endcan
|
@endcan
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
|
1
resources/views/vendor/.gitkeep
vendored
@ -1 +0,0 @@
|
|||||||
|
|
@ -7,7 +7,7 @@
|
|||||||
<table border="0" cellpadding="0" cellspacing="0">
|
<table border="0" cellpadding="0" cellspacing="0">
|
||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
<a href="{{ $url }}" class="button button-{{ $color or 'blue' }}" target="_blank">{{ $slot }}</a>
|
<a href="{{ $url }}" class="button button-{{ $color ?? 'primary' }}" target="_blank">{{ $slot }}</a>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
|
@ -27,7 +27,7 @@
|
|||||||
<tr>
|
<tr>
|
||||||
<td align="center">
|
<td align="center">
|
||||||
<table class="content" width="100%" cellpadding="0" cellspacing="0">
|
<table class="content" width="100%" cellpadding="0" cellspacing="0">
|
||||||
{{ $header or '' }}
|
{{ $header ?? '' }}
|
||||||
|
|
||||||
<!-- Email Body -->
|
<!-- Email Body -->
|
||||||
<tr>
|
<tr>
|
||||||
@ -38,14 +38,14 @@
|
|||||||
<td class="content-cell">
|
<td class="content-cell">
|
||||||
{{ Illuminate\Mail\Markdown::parse($slot) }}
|
{{ Illuminate\Mail\Markdown::parse($slot) }}
|
||||||
|
|
||||||
{{ $subcopy or '' }}
|
{{ $subcopy ?? '' }}
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
||||||
{{ $footer or '' }}
|
{{ $footer ?? '' }}
|
||||||
</table>
|
</table>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
@ -21,7 +21,7 @@
|
|||||||
{{-- Footer --}}
|
{{-- Footer --}}
|
||||||
@slot('footer')
|
@slot('footer')
|
||||||
@component('mail::footer')
|
@component('mail::footer')
|
||||||
Sent using <a href="http://showmy.photos">Blue Twilight</a>. © 2016-{{ date('Y') }} <a href="https://www.andyheathershaw.uk">Andy Heathershaw</a>.
|
Sent using <a href="https://showmy.photos">Blue Twilight</a>. © 2016-{{ date('Y') }} <a href="https://andysh.uk">Andy Heathershaw</a>.
|
||||||
@endcomponent
|
@endcomponent
|
||||||
@endslot
|
@endslot
|
||||||
@endcomponent
|
@endcomponent
|
||||||
|
@ -182,6 +182,7 @@ img {
|
|||||||
.table th {
|
.table th {
|
||||||
border-bottom: 1px solid #EDEFF2;
|
border-bottom: 1px solid #EDEFF2;
|
||||||
padding-bottom: 8px;
|
padding-bottom: 8px;
|
||||||
|
margin: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.table td {
|
.table td {
|
||||||
@ -189,6 +190,7 @@ img {
|
|||||||
font-size: 15px;
|
font-size: 15px;
|
||||||
line-height: 18px;
|
line-height: 18px;
|
||||||
padding: 10px 0;
|
padding: 10px 0;
|
||||||
|
margin: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.content-cell {
|
.content-cell {
|
||||||
@ -216,7 +218,8 @@ img {
|
|||||||
-webkit-text-size-adjust: none;
|
-webkit-text-size-adjust: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.button-blue {
|
.button-blue,
|
||||||
|
.button-primary {
|
||||||
background-color: #3097D1;
|
background-color: #3097D1;
|
||||||
border-top: 10px solid #3097D1;
|
border-top: 10px solid #3097D1;
|
||||||
border-right: 18px solid #3097D1;
|
border-right: 18px solid #3097D1;
|
||||||
@ -224,7 +227,8 @@ img {
|
|||||||
border-left: 18px solid #3097D1;
|
border-left: 18px solid #3097D1;
|
||||||
}
|
}
|
||||||
|
|
||||||
.button-green {
|
.button-green,
|
||||||
|
.button-success {
|
||||||
background-color: #2ab27b;
|
background-color: #2ab27b;
|
||||||
border-top: 10px solid #2ab27b;
|
border-top: 10px solid #2ab27b;
|
||||||
border-right: 18px solid #2ab27b;
|
border-right: 18px solid #2ab27b;
|
||||||
@ -232,7 +236,8 @@ img {
|
|||||||
border-left: 18px solid #2ab27b;
|
border-left: 18px solid #2ab27b;
|
||||||
}
|
}
|
||||||
|
|
||||||
.button-red {
|
.button-red,
|
||||||
|
.button-error {
|
||||||
background-color: #bf5329;
|
background-color: #bf5329;
|
||||||
border-top: 10px solid #bf5329;
|
border-top: 10px solid #bf5329;
|
||||||
border-right: 18px solid #bf5329;
|
border-right: 18px solid #bf5329;
|
||||||
|
@ -21,7 +21,7 @@
|
|||||||
{{-- Footer --}}
|
{{-- Footer --}}
|
||||||
@slot('footer')
|
@slot('footer')
|
||||||
@component('mail::footer')
|
@component('mail::footer')
|
||||||
Sent using [Blue Twilight](http://showmy.photos). © 2016-{{ date('Y') }} [Andy Heathershaw](https://www.andyheathershaw.uk).
|
Sent using [Blue Twilight](https://showmy.photos). © 2016-{{ date('Y') }} [Andy Heathershaw](https://andysh.uk).
|
||||||
@endcomponent
|
@endcomponent
|
||||||
@endslot
|
@endslot
|
||||||
@endcomponent
|
@endcomponent
|
@ -30,51 +30,51 @@ Route::group(['prefix' => 'admin'], function () {
|
|||||||
Route::get('albums/default-permissions', 'Admin\AlbumController@defaultPermissions')->name('albums.defaultPermissions');
|
Route::get('albums/default-permissions', 'Admin\AlbumController@defaultPermissions')->name('albums.defaultPermissions');
|
||||||
Route::post('albums/set-default-group-permissions', 'Admin\AlbumController@setDefaultGroupPermissions')->name('albums.set_default_group_permissions');
|
Route::post('albums/set-default-group-permissions', 'Admin\AlbumController@setDefaultGroupPermissions')->name('albums.set_default_group_permissions');
|
||||||
Route::post('albums/set-default-user-permissions', 'Admin\AlbumController@setDefaultUserPermissions')->name('albums.set_default_user_permissions');
|
Route::post('albums/set-default-user-permissions', 'Admin\AlbumController@setDefaultUserPermissions')->name('albums.set_default_user_permissions');
|
||||||
Route::get('albums/{id}/analyse/{queue_token}', 'Admin\AlbumController@analyse')->name('albums.analyse');
|
Route::get('albums/{album}/analyse/{queue_token}', 'Admin\AlbumController@analyse')->name('albums.analyse');
|
||||||
Route::get('albums/{id}/delete', 'Admin\AlbumController@delete')->name('albums.delete');
|
Route::get('albums/{album}/delete', 'Admin\AlbumController@delete')->name('albums.delete');
|
||||||
Route::get('/albums/{id}/metadata', 'Admin\AlbumController@metadata')->name('albums.metadata');
|
Route::get('/albums/{album}/metadata', 'Admin\AlbumController@metadata')->name('albums.metadata');
|
||||||
Route::post('albums/{id}/set-group-permissions', 'Admin\AlbumController@setGroupPermissions')->name('albums.set_group_permissions');
|
Route::post('albums/{album}/set-group-permissions', 'Admin\AlbumController@setGroupPermissions')->name('albums.set_group_permissions');
|
||||||
Route::post('albums/{id}/set-user-permissions', 'Admin\AlbumController@setUserPermissions')->name('albums.set_user_permissions');
|
Route::post('albums/{album}/set-user-permissions', 'Admin\AlbumController@setUserPermissions')->name('albums.set_user_permissions');
|
||||||
Route::delete('albums/{id}/delete-redirect/{redirectId}', 'Admin\AlbumController@deleteRedirect')->name('albums.delete_redirect');
|
Route::delete('albums/{album}/delete-redirect/{redirectId}', 'Admin\AlbumController@deleteRedirect')->name('albums.delete_redirect');
|
||||||
Route::post('albums/{id}/store-redirect', 'Admin\AlbumController@storeRedirect')->name('albums.store_redirect');
|
Route::post('albums/{album}/store-redirect', 'Admin\AlbumController@storeRedirect')->name('albums.store_redirect');
|
||||||
Route::resource('albums', 'Admin\AlbumController');
|
Route::resource('albums', 'Admin\AlbumController');
|
||||||
|
|
||||||
// Photo management
|
// Photo management
|
||||||
Route::post('photos/analyse/{id}/{queue_token}', 'Admin\PhotoController@analyse')->name('photos.analyse');
|
Route::post('photos/analyse/{photo}/{queue_token}', 'Admin\PhotoController@analyse')->name('photos.analyse');
|
||||||
Route::post('photos/flip/{photoId}/{horizontal}/{vertical}', 'Admin\PhotoController@flip')->name('photos.flip');
|
Route::post('photos/flip/{photo}/{horizontal}/{vertical}', 'Admin\PhotoController@flip')->name('photos.flip');
|
||||||
Route::post('photos/move/{photoId}', 'Admin\PhotoController@move')->name('photos.move');
|
Route::post('photos/move/{photo}', 'Admin\PhotoController@move')->name('photos.move');
|
||||||
Route::post('photos/reanalyse/{id}/{queue_token}', 'Admin\PhotoController@reAnalyse')->name('photos.re-analyse');
|
Route::post('photos/reanalyse/{photo}/{queue_token}', 'Admin\PhotoController@reAnalyse')->name('photos.re-analyse');
|
||||||
Route::post('photos/regenerate-thumbnails/{photoId}', 'Admin\PhotoController@regenerateThumbnails')->name('photos.regenerateThumbnails');
|
Route::post('photos/regenerate-thumbnails/{photo}', 'Admin\PhotoController@regenerateThumbnails')->name('photos.regenerateThumbnails');
|
||||||
Route::post('photos/rotate/{photoId}/{angle}', 'Admin\PhotoController@rotate')->name('photos.rotate');
|
Route::post('photos/rotate/{photo}/{angle}', 'Admin\PhotoController@rotate')->name('photos.rotate');
|
||||||
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/{photo}', 'Admin\PhotoController@updateBulk')->name('photos.updateBulk');
|
||||||
Route::resource('photos', 'Admin\PhotoController');
|
Route::resource('photos', 'Admin\PhotoController');
|
||||||
|
|
||||||
// Label management
|
// Label management
|
||||||
Route::get('labels/{id}/delete', 'Admin\LabelController@delete')->name('labels.delete');
|
Route::get('labels/{label}/delete', 'Admin\LabelController@delete')->name('labels.delete');
|
||||||
Route::resource('labels', 'Admin\LabelController');
|
Route::resource('labels', 'Admin\LabelController');
|
||||||
|
|
||||||
// Storage management
|
// Storage management
|
||||||
Route::get('storage/{id}/delete', 'Admin\StorageController@delete')->name('storage.delete');
|
Route::get('storage/{storage}/delete', 'Admin\StorageController@delete')->name('storage.delete');
|
||||||
Route::resource('storage', 'Admin\StorageController');
|
Route::resource('storage', 'Admin\StorageController');
|
||||||
|
|
||||||
// User management
|
// User management
|
||||||
Route::get('users/{id}/delete', 'Admin\UserController@delete')->name('users.delete');
|
Route::get('users/{user}/delete', 'Admin\UserController@delete')->name('users.delete');
|
||||||
Route::get('users.json', 'Admin\UserController@searchJson')->name('users.searchJson');
|
Route::get('users.json', 'Admin\UserController@searchJson')->name('users.searchJson');
|
||||||
Route::resource('users', 'Admin\UserController');
|
Route::resource('users', 'Admin\UserController');
|
||||||
|
|
||||||
// Group management
|
// Group management
|
||||||
Route::get('groups/{id}/delete', 'Admin\GroupController@delete')->name('groups.delete');
|
Route::get('groups/{group}/delete', 'Admin\GroupController@delete')->name('groups.delete');
|
||||||
Route::resource('groups', 'Admin\GroupController');
|
Route::resource('groups', 'Admin\GroupController');
|
||||||
|
|
||||||
// Comments management
|
// Comments management
|
||||||
Route::get('comments/{id}/approve', 'Admin\PhotoCommentController@approve')->name('comments.approve');
|
Route::get('comments/{comment}/approve', 'Admin\PhotoCommentController@approve')->name('comments.approve');
|
||||||
Route::post('comments/{id}/approve', 'Admin\PhotoCommentController@confirmApprove')->name('comments.confirmApprove');
|
Route::post('comments/{comment}/approve', 'Admin\PhotoCommentController@confirmApprove')->name('comments.confirmApprove');
|
||||||
|
|
||||||
Route::get('comments/{id}/reject', 'Admin\PhotoCommentController@reject')->name('comments.reject');
|
Route::get('comments/{comment}/reject', 'Admin\PhotoCommentController@reject')->name('comments.reject');
|
||||||
Route::post('comments/{id}/reject', 'Admin\PhotoCommentController@confirmReject')->name('comments.confirmReject');
|
Route::post('comments/{comment}/reject', 'Admin\PhotoCommentController@confirmReject')->name('comments.confirmReject');
|
||||||
|
|
||||||
Route::get('comments/{id}/delete', 'Admin\PhotoCommentController@delete')->name('comments.delete');
|
Route::get('comments/{comment}/delete', 'Admin\PhotoCommentController@delete')->name('comments.delete');
|
||||||
|
|
||||||
Route::post('comments/apply-bulk-action', 'Admin\PhotoCommentController@applyBulkAction')->name('comments.applyBulkAction');
|
Route::post('comments/apply-bulk-action', 'Admin\PhotoCommentController@applyBulkAction')->name('comments.applyBulkAction');
|
||||||
Route::post('comments/bulk-action', 'Admin\PhotoCommentController@bulkAction')->name('comments.bulkAction');
|
Route::post('comments/bulk-action', 'Admin\PhotoCommentController@bulkAction')->name('comments.bulkAction');
|
||||||
|
1
storage/framework/cache/.gitignore
vendored
@ -1,2 +1,3 @@
|
|||||||
*
|
*
|
||||||
|
!data/
|
||||||
!.gitignore
|
!.gitignore
|
2
storage/framework/cache/data/.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
*
|
||||||
|
!.gitignore
|