Started working on support for uploading photos
This commit is contained in:
parent
67bfecd2b3
commit
9360d8bbbe
@ -16,7 +16,7 @@ class Album extends Model
|
|||||||
* @var array
|
* @var array
|
||||||
*/
|
*/
|
||||||
protected $fillable = [
|
protected $fillable = [
|
||||||
'name', 'description'
|
'name', 'description', 'url_alias'
|
||||||
];
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -31,7 +31,19 @@ class Album extends Model
|
|||||||
{
|
{
|
||||||
$this->name = $request->get('name');
|
$this->name = $request->get('name');
|
||||||
$this->description = $request->get('description');
|
$this->description = $request->get('description');
|
||||||
|
$this->generateAlias();
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function generateAlias()
|
||||||
|
{
|
||||||
|
$this->url_alias = ucfirst(preg_replace('/[^a-z0-9\-]/', '-', strtolower($this->name)));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getUploadDisk()
|
||||||
|
{
|
||||||
|
// TODO allow albums to specify a storage location
|
||||||
|
return 'local';
|
||||||
|
}
|
||||||
}
|
}
|
80
app/Console/Commands/ProcessUploadCommand.php
Normal file
80
app/Console/Commands/ProcessUploadCommand.php
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Console\Commands;
|
||||||
|
|
||||||
|
use App\Album;
|
||||||
|
use App\Photo;
|
||||||
|
use App\Upload;
|
||||||
|
use App\UploadPhoto;
|
||||||
|
use Illuminate\Console\Command;
|
||||||
|
use Illuminate\Support\Facades\Storage;
|
||||||
|
|
||||||
|
class ProcessUploadCommand extends Command
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* The name and signature of the console command.
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $signature = 'twilight:process-uploads';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The console command description.
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $description = 'Processes uploads made through the web application.';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new command instance.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
parent::__construct();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Execute the console command.
|
||||||
|
*
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
public function handle()
|
||||||
|
{
|
||||||
|
$uploadsToProcess = Upload::where([
|
||||||
|
['is_completed', false],
|
||||||
|
['is_processing', false]
|
||||||
|
])
|
||||||
|
->orderBy('created_at', 'desc')
|
||||||
|
->get();
|
||||||
|
|
||||||
|
foreach ($uploadsToProcess as $upload)
|
||||||
|
{
|
||||||
|
$this->output->writeln(sprintf('Processing upload #%d', $upload->id));
|
||||||
|
$this->handleUpload($upload);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private function handleUpload(Upload $upload)
|
||||||
|
{
|
||||||
|
$photos = $upload->uploadPhotos;
|
||||||
|
foreach ($photos as $photo)
|
||||||
|
{
|
||||||
|
$this->handlePhoto($photo);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private function handlePhoto(UploadPhoto $uploadPhoto)
|
||||||
|
{
|
||||||
|
$photo = $uploadPhoto->photo;
|
||||||
|
$this->output->writeln(sprintf('Analysing photo #%d: %s', $photo->id, $photo->name));
|
||||||
|
|
||||||
|
$album = $photo->album;
|
||||||
|
|
||||||
|
$photoFile = Storage::path(sprintf('albums/%s/%s', $album->url_alias, $photo->file_name), $album->getUploadDisk());
|
||||||
|
dump($photoFile);
|
||||||
|
|
||||||
|
dump(@exif_read_data($photoFile));
|
||||||
|
}
|
||||||
|
}
|
@ -2,6 +2,8 @@
|
|||||||
|
|
||||||
namespace App\Console;
|
namespace App\Console;
|
||||||
|
|
||||||
|
use App\Console\Commands\ProcessUploadCommand;
|
||||||
|
use App\Upload;
|
||||||
use Illuminate\Console\Scheduling\Schedule;
|
use Illuminate\Console\Scheduling\Schedule;
|
||||||
use Illuminate\Foundation\Console\Kernel as ConsoleKernel;
|
use Illuminate\Foundation\Console\Kernel as ConsoleKernel;
|
||||||
|
|
||||||
@ -13,7 +15,7 @@ class Kernel extends ConsoleKernel
|
|||||||
* @var array
|
* @var array
|
||||||
*/
|
*/
|
||||||
protected $commands = [
|
protected $commands = [
|
||||||
//
|
ProcessUploadCommand::class
|
||||||
];
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -24,8 +26,11 @@ class Kernel extends ConsoleKernel
|
|||||||
*/
|
*/
|
||||||
protected function schedule(Schedule $schedule)
|
protected function schedule(Schedule $schedule)
|
||||||
{
|
{
|
||||||
// $schedule->command('inspire')
|
$schedule->command('twilight:process-uploads')
|
||||||
// ->hourly();
|
->everyMinute()
|
||||||
|
->when(function () {
|
||||||
|
return (Upload::where('is_completed', 0)->count() > 0);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -73,7 +73,7 @@ class ThemeHelper
|
|||||||
{
|
{
|
||||||
$themeName = ThemeHelper::DEFAULT_THEME;
|
$themeName = ThemeHelper::DEFAULT_THEME;
|
||||||
|
|
||||||
$currentTheme = Configuration::all()->where('key', 'theme')->first();
|
$currentTheme = Configuration::where('key', 'theme')->first();
|
||||||
if (!is_null($currentTheme))
|
if (!is_null($currentTheme))
|
||||||
{
|
{
|
||||||
$themeName = $currentTheme->value;
|
$themeName = $currentTheme->value;
|
||||||
|
@ -43,7 +43,7 @@ class AlbumController extends Controller
|
|||||||
{
|
{
|
||||||
$this->authorize('admin-access');
|
$this->authorize('admin-access');
|
||||||
|
|
||||||
$album = $this->loadAlbum($id);
|
$album = AlbumController::loadAlbum($id);
|
||||||
|
|
||||||
return Theme::render('admin.delete_album', ['album' => $album]);
|
return Theme::render('admin.delete_album', ['album' => $album]);
|
||||||
}
|
}
|
||||||
@ -74,7 +74,7 @@ class AlbumController extends Controller
|
|||||||
{
|
{
|
||||||
$this->authorize('admin-access');
|
$this->authorize('admin-access');
|
||||||
|
|
||||||
$album = $this->loadAlbum($id);
|
$album = AlbumController::loadAlbum($id);
|
||||||
|
|
||||||
return Theme::render('admin.show_album', ['album' => $album]);
|
return Theme::render('admin.show_album', ['album' => $album]);
|
||||||
}
|
}
|
||||||
@ -89,7 +89,7 @@ class AlbumController extends Controller
|
|||||||
{
|
{
|
||||||
$this->authorize('admin-access');
|
$this->authorize('admin-access');
|
||||||
|
|
||||||
$album = $this->loadAlbum($id);
|
$album = AlbumController::loadAlbum($id);
|
||||||
|
|
||||||
return Theme::render('admin.edit_album', ['album' => $album]);
|
return Theme::render('admin.edit_album', ['album' => $album]);
|
||||||
}
|
}
|
||||||
@ -105,7 +105,7 @@ class AlbumController extends Controller
|
|||||||
{
|
{
|
||||||
$this->authorize('admin-access');
|
$this->authorize('admin-access');
|
||||||
|
|
||||||
$album = $this->loadAlbum($id);
|
$album = AlbumController::loadAlbum($id);
|
||||||
$album->fromRequest($request)->save();
|
$album->fromRequest($request)->save();
|
||||||
|
|
||||||
return Theme::render('admin.show_album', ['album' => $album]);
|
return Theme::render('admin.show_album', ['album' => $album]);
|
||||||
@ -127,9 +127,13 @@ class AlbumController extends Controller
|
|||||||
return redirect(route('albums.index'));
|
return redirect(route('albums.index'));
|
||||||
}
|
}
|
||||||
|
|
||||||
private function loadAlbum($id)
|
/**
|
||||||
|
* @param $id
|
||||||
|
* @return Album
|
||||||
|
*/
|
||||||
|
public static function loadAlbum($id)
|
||||||
{
|
{
|
||||||
$album = Album::all()->where('id', intval($id))->first();
|
$album = Album::where('id', intval($id))->first();
|
||||||
if (is_null($album))
|
if (is_null($album))
|
||||||
{
|
{
|
||||||
App::abort(404);
|
App::abort(404);
|
||||||
|
126
app/Http/Controllers/Admin/PhotoController.php
Normal file
126
app/Http/Controllers/Admin/PhotoController.php
Normal file
@ -0,0 +1,126 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Controllers\Admin;
|
||||||
|
|
||||||
|
use App\Album;
|
||||||
|
use App\Photo;
|
||||||
|
use App\Upload;
|
||||||
|
use App\UploadPhoto;
|
||||||
|
use Illuminate\Http\File;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
|
||||||
|
use App\Http\Requests;
|
||||||
|
use App\Http\Controllers\Controller;
|
||||||
|
use Illuminate\Http\UploadedFile;
|
||||||
|
use Illuminate\Support\Facades\Storage;
|
||||||
|
|
||||||
|
class PhotoController extends Controller
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Display a listing of the resource.
|
||||||
|
*
|
||||||
|
* @return \Illuminate\Http\Response
|
||||||
|
*/
|
||||||
|
public function index()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show the form for creating a new resource.
|
||||||
|
*
|
||||||
|
* @return \Illuminate\Http\Response
|
||||||
|
*/
|
||||||
|
public function create()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Store a newly created resource in storage.
|
||||||
|
*
|
||||||
|
* @param \Illuminate\Http\Request $request
|
||||||
|
* @return \Illuminate\Http\Response
|
||||||
|
*/
|
||||||
|
public function store(Request $request)
|
||||||
|
{
|
||||||
|
$this->authorize('admin-access');
|
||||||
|
|
||||||
|
/** @var UploadedFile $photoFile */
|
||||||
|
$photoFile = UploadedFile::createFromBase($request->files->get('photo'));
|
||||||
|
|
||||||
|
// Load the linked album
|
||||||
|
$album = AlbumController::loadAlbum($request->get('album_id'));
|
||||||
|
|
||||||
|
$storageLocation = sprintf('albums/%s', $album->url_alias);
|
||||||
|
|
||||||
|
/** @var \SplFileInfo $savedFile */
|
||||||
|
$savedFilePath = $photoFile->store($storageLocation, $album->getUploadDisk());
|
||||||
|
|
||||||
|
$photo = new Photo();
|
||||||
|
$photo->album_id = $album->id;
|
||||||
|
$photo->name = $photoFile->getClientOriginalName();
|
||||||
|
$photo->file_name = basename($savedFilePath);
|
||||||
|
$photo->mime_type = $photoFile->getClientMimeType();
|
||||||
|
$photo->file_size = $photoFile->getSize();
|
||||||
|
$photo->save();
|
||||||
|
|
||||||
|
$upload = new Upload();
|
||||||
|
$upload->is_completed = false;
|
||||||
|
$upload->is_processing = false;
|
||||||
|
$upload->number_photos = 1;
|
||||||
|
$upload->save();
|
||||||
|
|
||||||
|
$uploadPhoto = new UploadPhoto();
|
||||||
|
$uploadPhoto->upload_id = $upload->id;
|
||||||
|
$uploadPhoto->photo_id = $photo->id;
|
||||||
|
$uploadPhoto->save();
|
||||||
|
|
||||||
|
exit();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
}
|
||||||
|
}
|
33
app/Photo.php
Normal file
33
app/Photo.php
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App;
|
||||||
|
|
||||||
|
use Illuminate\Database\Eloquent\Model;
|
||||||
|
use Illuminate\Notifications\Notifiable;
|
||||||
|
|
||||||
|
class Photo extends Model
|
||||||
|
{
|
||||||
|
use Notifiable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The attributes that are mass assignable.
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
protected $fillable = [
|
||||||
|
'album_id', 'name', 'description', 'file_name', 'mime_type', 'file_size'
|
||||||
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The attributes that should be hidden for arrays.
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
protected $hidden = [
|
||||||
|
];
|
||||||
|
|
||||||
|
public function album()
|
||||||
|
{
|
||||||
|
return $this->belongsTo(Album::class);
|
||||||
|
}
|
||||||
|
}
|
@ -4,6 +4,7 @@ namespace App\Providers;
|
|||||||
|
|
||||||
use App\Facade\Theme;
|
use App\Facade\Theme;
|
||||||
use App\Helpers\ThemeHelper;
|
use App\Helpers\ThemeHelper;
|
||||||
|
use Illuminate\Database\QueryException;
|
||||||
use Illuminate\Support\Facades\View;
|
use Illuminate\Support\Facades\View;
|
||||||
use Illuminate\Support\ServiceProvider;
|
use Illuminate\Support\ServiceProvider;
|
||||||
|
|
||||||
@ -21,7 +22,14 @@ class AppServiceProvider extends ServiceProvider
|
|||||||
return new ThemeHelper();
|
return new ThemeHelper();
|
||||||
});
|
});
|
||||||
|
|
||||||
$this->addThemeInfoToView();
|
try
|
||||||
|
{
|
||||||
|
$this->addThemeInfoToView();
|
||||||
|
}
|
||||||
|
catch (QueryException $ex)
|
||||||
|
{
|
||||||
|
// When running migrations, the configuration table may not exist - so ignore and continue
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
33
app/Upload.php
Normal file
33
app/Upload.php
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App;
|
||||||
|
|
||||||
|
use Illuminate\Database\Eloquent\Model;
|
||||||
|
use Illuminate\Notifications\Notifiable;
|
||||||
|
|
||||||
|
class Upload extends Model
|
||||||
|
{
|
||||||
|
use Notifiable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The attributes that are mass assignable.
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
protected $fillable = [
|
||||||
|
'is_completed', 'is_processing', 'number_photos', 'number_successful', 'number_failed'
|
||||||
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The attributes that should be hidden for arrays.
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
protected $hidden = [
|
||||||
|
];
|
||||||
|
|
||||||
|
public function uploadPhotos()
|
||||||
|
{
|
||||||
|
return $this->hasMany(UploadPhoto::class);
|
||||||
|
}
|
||||||
|
}
|
33
app/UploadPhoto.php
Normal file
33
app/UploadPhoto.php
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App;
|
||||||
|
|
||||||
|
use Illuminate\Database\Eloquent\Model;
|
||||||
|
use Illuminate\Notifications\Notifiable;
|
||||||
|
|
||||||
|
class UploadPhoto extends Model
|
||||||
|
{
|
||||||
|
use Notifiable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The attributes that are mass assignable.
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
protected $fillable = [
|
||||||
|
'upload_id', 'photo_id'
|
||||||
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The attributes that should be hidden for arrays.
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
protected $hidden = [
|
||||||
|
];
|
||||||
|
|
||||||
|
public function photo()
|
||||||
|
{
|
||||||
|
return $this->belongsTo(Photo::class);
|
||||||
|
}
|
||||||
|
}
|
@ -56,8 +56,8 @@ return [
|
|||||||
'driver' => 'mysql',
|
'driver' => 'mysql',
|
||||||
'host' => env('DB_HOST', 'localhost'),
|
'host' => env('DB_HOST', 'localhost'),
|
||||||
'port' => env('DB_PORT', '3306'),
|
'port' => env('DB_PORT', '3306'),
|
||||||
'database' => env('DB_DATABASE', 'forge'),
|
'database' => env('DB_DATABASE', 'blue_twilight'),
|
||||||
'username' => env('DB_USERNAME', 'forge'),
|
'username' => env('DB_USERNAME', 'blue_twilight'),
|
||||||
'password' => env('DB_PASSWORD', ''),
|
'password' => env('DB_PASSWORD', ''),
|
||||||
'charset' => 'utf8',
|
'charset' => 'utf8',
|
||||||
'collation' => 'utf8_unicode_ci',
|
'collation' => 'utf8_unicode_ci',
|
||||||
@ -70,8 +70,8 @@ return [
|
|||||||
'driver' => 'pgsql',
|
'driver' => 'pgsql',
|
||||||
'host' => env('DB_HOST', 'localhost'),
|
'host' => env('DB_HOST', 'localhost'),
|
||||||
'port' => env('DB_PORT', '5432'),
|
'port' => env('DB_PORT', '5432'),
|
||||||
'database' => env('DB_DATABASE', 'forge'),
|
'database' => env('DB_DATABASE', 'blue_twilight'),
|
||||||
'username' => env('DB_USERNAME', 'forge'),
|
'username' => env('DB_USERNAME', 'blue_twilight'),
|
||||||
'password' => env('DB_PASSWORD', ''),
|
'password' => env('DB_PASSWORD', ''),
|
||||||
'charset' => 'utf8',
|
'charset' => 'utf8',
|
||||||
'prefix' => '',
|
'prefix' => '',
|
||||||
|
@ -30,6 +30,6 @@ class CreateUsersTable extends Migration
|
|||||||
*/
|
*/
|
||||||
public function down()
|
public function down()
|
||||||
{
|
{
|
||||||
Schema::drop('users');
|
Schema::dropIfExists('users');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -27,6 +27,6 @@ class CreatePasswordResetsTable extends Migration
|
|||||||
*/
|
*/
|
||||||
public function down()
|
public function down()
|
||||||
{
|
{
|
||||||
Schema::drop('password_resets');
|
Schema::dropIfExists('password_resets');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -17,6 +17,7 @@ class CreateAlbumsTable extends Migration
|
|||||||
$table->increments('id');
|
$table->increments('id');
|
||||||
$table->string('name');
|
$table->string('name');
|
||||||
$table->text('description');
|
$table->text('description');
|
||||||
|
$table->string('url_alias');
|
||||||
$table->timestamps();
|
$table->timestamps();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -28,6 +29,6 @@ class CreateAlbumsTable extends Migration
|
|||||||
*/
|
*/
|
||||||
public function down()
|
public function down()
|
||||||
{
|
{
|
||||||
Schema::drop('albums');
|
Schema::dropIfExists('albums');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -28,6 +28,6 @@ class CreateConfigTable extends Migration
|
|||||||
*/
|
*/
|
||||||
public function down()
|
public function down()
|
||||||
{
|
{
|
||||||
Schema::drop('configuration');
|
Schema::dropIfExists('configuration');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,41 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
|
||||||
|
class CreatePhotosTable extends Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function up()
|
||||||
|
{
|
||||||
|
Schema::create('photos', function (Blueprint $table) {
|
||||||
|
$table->bigIncrements('id');
|
||||||
|
$table->unsignedInteger('album_id');
|
||||||
|
$table->string('name');
|
||||||
|
$table->string('description')->default('');
|
||||||
|
$table->string('file_name');
|
||||||
|
$table->string('mime_type');
|
||||||
|
$table->unsignedBigInteger('file_size');
|
||||||
|
$table->timestamps();
|
||||||
|
|
||||||
|
$table->foreign('album_id')
|
||||||
|
->references('id')->on('albums')
|
||||||
|
->onDelete('no action');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function down()
|
||||||
|
{
|
||||||
|
Schema::dropIfExists('photos');
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,36 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
|
||||||
|
class CreateUploadsTable extends Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function up()
|
||||||
|
{
|
||||||
|
Schema::create('uploads', function (Blueprint $table) {
|
||||||
|
$table->increments('id');
|
||||||
|
$table->boolean('is_completed');
|
||||||
|
$table->boolean('is_processing');
|
||||||
|
$table->integer('number_photos')->default(0);
|
||||||
|
$table->integer('number_successful')->default(0);
|
||||||
|
$table->integer('number_failed')->default(0);
|
||||||
|
$table->timestamps();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function down()
|
||||||
|
{
|
||||||
|
Schema::dropIfExists('uploads');
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,40 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
|
||||||
|
class CreateUploadPhotosTable extends Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function up()
|
||||||
|
{
|
||||||
|
Schema::create('upload_photos', function (Blueprint $table) {
|
||||||
|
$table->bigIncrements('id');
|
||||||
|
$table->unsignedInteger('upload_id');
|
||||||
|
$table->unsignedBigInteger('photo_id');
|
||||||
|
$table->timestamps();
|
||||||
|
|
||||||
|
$table->foreign('upload_id')
|
||||||
|
->references('id')->on('uploads')
|
||||||
|
->onDelete('cascade');
|
||||||
|
$table->foreign('photo_id')
|
||||||
|
->references('id')->on('photos')
|
||||||
|
->onDelete('cascade');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function down()
|
||||||
|
{
|
||||||
|
Schema::dropIfExists('upload_photos');
|
||||||
|
}
|
||||||
|
}
|
6
public/themes/base/css/app.css
vendored
6
public/themes/base/css/app.css
vendored
@ -6,4 +6,10 @@
|
|||||||
|
|
||||||
.form-actions {
|
.form-actions {
|
||||||
text-align: right;
|
text-align: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tab-content {
|
||||||
|
border: solid 1px #ddd;
|
||||||
|
border-top: 0;
|
||||||
|
padding: 10px;
|
||||||
}
|
}
|
@ -6,5 +6,6 @@ return [
|
|||||||
'description_label' => 'Description:',
|
'description_label' => 'Description:',
|
||||||
'edit_action' => 'Edit',
|
'edit_action' => 'Edit',
|
||||||
'name_label' => 'Name:',
|
'name_label' => 'Name:',
|
||||||
|
'upload_action' => 'Upload',
|
||||||
'save_action' => 'Save Changes'
|
'save_action' => 'Save Changes'
|
||||||
];
|
];
|
@ -32,8 +32,8 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-actions">
|
<div class="form-actions">
|
||||||
{!! Form::submit(trans('forms.create_action'), ['class' => 'btn btn-success']) !!}
|
|
||||||
<a href="{{ route('admin') }}" class="btn btn-default">@lang('forms.cancel_action')</a>
|
<a href="{{ route('admin') }}" class="btn btn-default">@lang('forms.cancel_action')</a>
|
||||||
|
{!! Form::submit(trans('forms.create_action'), ['class' => 'btn btn-success']) !!}
|
||||||
</div>
|
</div>
|
||||||
{!! Form::close() !!}
|
{!! Form::close() !!}
|
||||||
</div>
|
</div>
|
||||||
|
@ -32,8 +32,8 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-actions">
|
<div class="form-actions">
|
||||||
{!! Form::submit(trans('forms.save_action'), ['class' => 'btn btn-success']) !!}
|
|
||||||
<a href="{{ route('albums.show', ['id' => $album->id]) }}" class="btn btn-default">@lang('forms.cancel_action')</a>
|
<a href="{{ route('albums.show', ['id' => $album->id]) }}" class="btn btn-default">@lang('forms.cancel_action')</a>
|
||||||
|
{!! Form::submit(trans('forms.save_action'), ['class' => 'btn btn-success']) !!}
|
||||||
</div>
|
</div>
|
||||||
{!! Form::close() !!}
|
{!! Form::close() !!}
|
||||||
</div>
|
</div>
|
||||||
|
@ -8,6 +8,42 @@
|
|||||||
<h1>{{ $album->name }}</h1>
|
<h1>{{ $album->name }}</h1>
|
||||||
<p>{{ $album->description }}</p>
|
<p>{{ $album->description }}</p>
|
||||||
<hr/>
|
<hr/>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
{{-- Nav tabs --}}
|
||||||
|
<ul class="nav nav-tabs" role="tablist">
|
||||||
|
<li role="presentation" class="active"><a href="#upload-tab" aria-controls="upload-tab" role="tab" data-toggle="tab"><i class="fa fa-fw fa-upload"></i> Upload</a></li>
|
||||||
|
<li role="presentation"><a href="#settings-tab" aria-controls="settings-tab" role="tab" data-toggle="tab"><i class="fa fa-fw fa-cog"></i> Settings</a></li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
{{-- Tab panes --}}
|
||||||
|
<div class="tab-content">
|
||||||
|
<div role="tabpanel" class="tab-pane active" id="upload-tab">
|
||||||
|
<h4>Upload a single image</h4>
|
||||||
|
|
||||||
|
{!! Form::open(['route' => 'photos.store', 'method' => 'POST', 'files' => true]) !!}
|
||||||
|
{!! Form::hidden('album_id', $album->id) !!}
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
{!! Form::file('photo', ['class' => 'control-label']) !!}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
{!! Form::submit(trans('forms.upload_action'), ['class' => 'btn btn-success']) !!}
|
||||||
|
</div>
|
||||||
|
{!! Form::close() !!}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div role="tabpanel" class="tab-pane" id="settings-tab">
|
||||||
|
<h4>Settings</h4>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="btn-toolbar" style="margin-top: 30px;">
|
||||||
|
<a href="{{ route('albums.edit', ['id' => $album->id]) }}" class="btn btn-default">@lang('forms.edit_action')</a>
|
||||||
|
<a href="{{ route('albums.delete', ['id' => $album->id]) }}" class="btn btn-danger">@lang('forms.delete_action')</a>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -22,4 +22,5 @@ Route::group(['prefix' => 'admin'], function () {
|
|||||||
|
|
||||||
Route::get('albums/{id}/delete', 'Admin\AlbumController@delete')->name('albums.delete');
|
Route::get('albums/{id}/delete', 'Admin\AlbumController@delete')->name('albums.delete');
|
||||||
Route::resource('albums', 'Admin\AlbumController');
|
Route::resource('albums', 'Admin\AlbumController');
|
||||||
|
Route::resource('photos', 'Admin\PhotoController');
|
||||||
});
|
});
|
Loading…
Reference in New Issue
Block a user