Coverted script import to laravel
This commit is contained in:
parent
a2357435e1
commit
b1d7cfe616
221
app/Console/Commands/Import.php
Normal file
221
app/Console/Commands/Import.php
Normal file
@ -0,0 +1,221 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Console\Commands;
|
||||||
|
|
||||||
|
use Log;
|
||||||
|
use Illuminate\Console\Command;
|
||||||
|
use App\Model\Person;
|
||||||
|
use App\Model\PhotoPerson;
|
||||||
|
use App\Model\Photo;
|
||||||
|
use App\Model\PhotoTag;
|
||||||
|
use App\Model\Tag;
|
||||||
|
|
||||||
|
class Import extends Command
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* The name and signature of the console command.
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $signature = 'photo:import
|
||||||
|
{--dir= : Directory to Parse}
|
||||||
|
{--file= : File to import}
|
||||||
|
{--ignoredupe : Ignore duplicate files}
|
||||||
|
{--deletedupe : Delete duplicate files}
|
||||||
|
{--people= : People to reference in photo}
|
||||||
|
{--tags= : Add tag to photo}';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The console command description.
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $description = 'Import photos into the database';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new command instance.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
parent::__construct();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Execute the console command.
|
||||||
|
*
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
public function handle()
|
||||||
|
{
|
||||||
|
// Make sure we got a directory or a file to import
|
||||||
|
if (is_null($this->option('file')) AND is_null($this->option('dir')))
|
||||||
|
abort(500,'Missing filename, please use --file= OR --dir=');
|
||||||
|
|
||||||
|
Log::info('Processing: '.($this->option('file') ? $this->option('file') : $this->option('dir')));
|
||||||
|
|
||||||
|
$files = [];
|
||||||
|
|
||||||
|
if ($this->option('dir'))
|
||||||
|
{
|
||||||
|
// Remove our trailing slash from the directory.
|
||||||
|
$dir = preg_replace('/\/$/','',$this->option('dir'));
|
||||||
|
|
||||||
|
// Exclude . & .. from the path.
|
||||||
|
$files = array_diff(scandir($dir),array('.','..'));
|
||||||
|
|
||||||
|
// Determine if our dir is releative to where we store data
|
||||||
|
$dir = preg_replace('/^\//','',str_replace(config('photo.dir'),'',$dir));
|
||||||
|
|
||||||
|
// Add our path
|
||||||
|
if ($dir)
|
||||||
|
array_walk($files,function(&$value,$key,$path='') {
|
||||||
|
if ($path) {
|
||||||
|
$value = sprintf('%s/%s',$path,$value);
|
||||||
|
}
|
||||||
|
},$dir);
|
||||||
|
}
|
||||||
|
elseif ($this->option('file'))
|
||||||
|
{
|
||||||
|
$files = array($this->option('file'));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Show a progress bar
|
||||||
|
$bar = $this->output->createProgressBar(count($files));
|
||||||
|
$bar->setFormat("%current%/%max% [%bar%] %percent:3s%% (%memory%) (%remaining%) ");
|
||||||
|
|
||||||
|
$tags = NULL;
|
||||||
|
$t = $p = array();
|
||||||
|
|
||||||
|
// Tags
|
||||||
|
if ($this->option('tags'))
|
||||||
|
{
|
||||||
|
$tags = explode(',',$this->option('tags'));
|
||||||
|
$t = Tag::whereIn('tag',$tags)->get();
|
||||||
|
}
|
||||||
|
|
||||||
|
// People
|
||||||
|
if ($this->option('people'))
|
||||||
|
{
|
||||||
|
$tags = explode(',',$this->option('people'));
|
||||||
|
$p = Person::whereIn('tag',$tags)->get();
|
||||||
|
}
|
||||||
|
|
||||||
|
$c = 0;
|
||||||
|
foreach ($files as $file)
|
||||||
|
{
|
||||||
|
$bar->advance();
|
||||||
|
|
||||||
|
if (preg_match('/@__thumb/',$file) OR preg_match('/\/._/',$file))
|
||||||
|
{
|
||||||
|
$this->warn(sprintf('Ignoring file [%s]',$file));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (! in_array(strtolower(pathinfo($file,PATHINFO_EXTENSION)),config('photo.import.accepted')))
|
||||||
|
{
|
||||||
|
$this->warn(sprintf('Ignoring [%s]',$file));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($this->option('verbose'))
|
||||||
|
$this->info(sprintf('Processing file [%s]',$file));
|
||||||
|
|
||||||
|
$c++;
|
||||||
|
|
||||||
|
$po = Photo::where('filename',$file)->first();
|
||||||
|
|
||||||
|
if (is_null($po))
|
||||||
|
{
|
||||||
|
$po = new Photo;
|
||||||
|
$po->filename = $file;
|
||||||
|
}
|
||||||
|
|
||||||
|
$po->date_taken = strtotime($po->io('exif:DateTime'));
|
||||||
|
$po->subsectime = $po->io('exif:SubSecTimeOriginal');
|
||||||
|
|
||||||
|
$po->signature = $po->io()->getImageSignature();
|
||||||
|
|
||||||
|
$po->make = $po->io('exif:Make');
|
||||||
|
$po->model = $po->io('exif:Model');
|
||||||
|
|
||||||
|
$po->height = $po->io()->getImageheight();
|
||||||
|
$po->width = $po->io()->getImageWidth();
|
||||||
|
$po->orientation = $po->io()->getImageOrientation();
|
||||||
|
|
||||||
|
$po->gps_lat = $po->gps(preg_split('/,\s?/',$po->io()->getImageProperty('exif:GPSLatitude')),$po->io()->getImageProperty('exif:GPSLatitudeRef'));
|
||||||
|
$po->gps_lon = $po->gps(preg_split('/,\s?/',$po->io()->getImageProperty('exif:GPSLongitude')),$po->io()->getImageProperty('exif:GPSLongitudeRef'));
|
||||||
|
|
||||||
|
try {
|
||||||
|
$po->thumbnail = exif_thumbnail($po->file_path());
|
||||||
|
} catch (Exception $e) {
|
||||||
|
// @todo Couldnt get the thumbnail, so we should create one.
|
||||||
|
}
|
||||||
|
|
||||||
|
// If this is a duplicate
|
||||||
|
$x = $po->list_duplicate()->get();
|
||||||
|
if (count($x)) {
|
||||||
|
$skip = FALSE;
|
||||||
|
|
||||||
|
foreach ($x as $o) {
|
||||||
|
// We'll only ignore based on the same signature.
|
||||||
|
if ($po->signature != $o->signature AND ! $po->exists)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if ($this->option('ignoredupe'))
|
||||||
|
{
|
||||||
|
$skip = TRUE;
|
||||||
|
$this->warn(sprintf("Ignoring file [%s], it's the same as [%s] with id %s",$po->file_path(),$o->filename,$o->id));
|
||||||
|
break;
|
||||||
|
|
||||||
|
}
|
||||||
|
elseif ($this->option('deletedupe') AND ($po->filename != $o->filename))
|
||||||
|
{
|
||||||
|
$skip = TRUE;
|
||||||
|
$this->error(sprintf("Deleting file [%s], it's the same as [%s] with id %s and signature [%s]\n",$po->file_path(),$o->filename,$o->id,$po->signature));
|
||||||
|
unlink($po->file_path());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($skip)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
$po->duplicate = '1';
|
||||||
|
$this->warn(sprintf('Image [%s] marked as a duplicate',$file));
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($po->exists)
|
||||||
|
$this->warn(sprintf('Image [%s] already in DB: %s',$file,$po->id));
|
||||||
|
|
||||||
|
$po->save();
|
||||||
|
|
||||||
|
if ($po->wasRecentlyCreated)
|
||||||
|
$this->info(sprintf('Image [%s] stored in DB: %s',$file,$po->id));
|
||||||
|
|
||||||
|
// Record our tags
|
||||||
|
foreach ($t as $o)
|
||||||
|
if (! (new PhotoTag)->where('tag_id','=',$o->id)->where('photo_id','=',$po->id)->count())
|
||||||
|
{
|
||||||
|
$x = new PhotoTag;
|
||||||
|
$x->tag_id = $o->id;
|
||||||
|
$x->photo_id = $po->id;
|
||||||
|
$x->save();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Record our people
|
||||||
|
foreach ($p as $o)
|
||||||
|
if (! (new PhotoPerson)->where('people_id','=',$o->id)->where('photo_id','=',$po->id)->count())
|
||||||
|
{
|
||||||
|
$x = new PhotoPerson;
|
||||||
|
$x->people_id = $o->id;
|
||||||
|
$x->photo_id = $po->id;
|
||||||
|
$x->save();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$bar->finish();
|
||||||
|
|
||||||
|
return $this->info(sprintf('Images processed: %s',$c));
|
||||||
|
}
|
||||||
|
}
|
@ -13,7 +13,7 @@ class Kernel extends ConsoleKernel
|
|||||||
* @var array
|
* @var array
|
||||||
*/
|
*/
|
||||||
protected $commands = [
|
protected $commands = [
|
||||||
// Commands\Inspire::class,
|
Commands\Import::class,
|
||||||
];
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
31
app/Http/Controllers/PhotoController.php
Normal file
31
app/Http/Controllers/PhotoController.php
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Controllers;
|
||||||
|
|
||||||
|
use Illuminate\Http\Response;
|
||||||
|
|
||||||
|
use App\Http\Requests;
|
||||||
|
use App\Model\Photo;
|
||||||
|
|
||||||
|
class PhotoController extends Controller
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Create a new controller instance.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
$this->middleware('guest');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function info($id)
|
||||||
|
{
|
||||||
|
return view('photo.view', ['photo'=> Photo::findOrFail($id)]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function thumbnail($id)
|
||||||
|
{
|
||||||
|
return (new Response(Photo::findOrFail($id)->thumbnail()))->header('Content-Type','image/jpg');
|
||||||
|
}
|
||||||
|
}
|
@ -1,5 +1,7 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|--------------------------------------------------------------------------
|
|--------------------------------------------------------------------------
|
||||||
| Application Routes
|
| Application Routes
|
||||||
@ -14,3 +16,8 @@
|
|||||||
Route::get('/', function () {
|
Route::get('/', function () {
|
||||||
return view('welcome');
|
return view('welcome');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Route::auth();
|
||||||
|
|
||||||
|
Route::get('/info/{id}', 'PhotoController@info')->where('id', '[0-9]+');;
|
||||||
|
Route::get('/thumbnail/{id}', 'PhotoController@thumbnail')->where('id', '[0-9]+');;
|
||||||
|
9
app/Model/Person.php
Normal file
9
app/Model/Person.php
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Model;
|
||||||
|
|
||||||
|
use Illuminate\Database\Eloquent\Model;
|
||||||
|
|
||||||
|
class Person extends Model
|
||||||
|
{
|
||||||
|
}
|
135
app/Model/Photo.php
Normal file
135
app/Model/Photo.php
Normal file
@ -0,0 +1,135 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Model;
|
||||||
|
|
||||||
|
use DB;
|
||||||
|
use Illuminate\Database\Eloquent\Model;
|
||||||
|
|
||||||
|
class Photo extends Model
|
||||||
|
{
|
||||||
|
protected $table = 'photo';
|
||||||
|
|
||||||
|
// Imagick Object
|
||||||
|
private $_io;
|
||||||
|
|
||||||
|
// How should the image be rotated, based on the value of orientation
|
||||||
|
private $_rotate = [
|
||||||
|
3=>180,
|
||||||
|
6=>90,
|
||||||
|
8=>-90,
|
||||||
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine the new name for the image
|
||||||
|
*/
|
||||||
|
public function file_path($short=FALSE,$new=FALSE) {
|
||||||
|
$file = $this->filename;
|
||||||
|
|
||||||
|
if ($new)
|
||||||
|
$file = sprintf('%s.%s',((is_null($this->date_taken) OR ! $this->date_taken)
|
||||||
|
? sprintf('UNKNOWN/%07s',$this->file_path_id())
|
||||||
|
: sprintf('%s_%03s',date('Y/m/d-His',$this->date_taken),$this->subsectime).($this->subsectime ? '' : sprintf('-%05s',$this->id))),$this->type());
|
||||||
|
|
||||||
|
return (($short OR preg_match('/^\//',$file)) ? '' : config('photo.dir').DIRECTORY_SEPARATOR).$file;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function gps(array $coordinate,$hemisphere) {
|
||||||
|
if (! $coordinate OR ! $hemisphere)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
for ($i=0; $i<3; $i++) {
|
||||||
|
$part = explode('/', $coordinate[$i]);
|
||||||
|
|
||||||
|
if (count($part) == 1)
|
||||||
|
$coordinate[$i] = $part[0];
|
||||||
|
|
||||||
|
elseif (count($part) == 2)
|
||||||
|
$coordinate[$i] = floatval($part[0])/floatval($part[1]);
|
||||||
|
|
||||||
|
else
|
||||||
|
$coordinate[$i] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
list($degrees, $minutes, $seconds) = $coordinate;
|
||||||
|
|
||||||
|
$sign = ($hemisphere == 'W' || $hemisphere == 'S') ? -1 : 1;
|
||||||
|
|
||||||
|
return round($sign*($degrees+$minutes/60+$seconds/3600),$degrees > 100 ? 3 : 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return an Imagick object or attribute
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public function io($attr=NULL) {
|
||||||
|
if (is_null($this->_io))
|
||||||
|
$this->_io = new \Imagick($this->file_path());
|
||||||
|
|
||||||
|
return is_null($attr) ? $this->_io : $this->_io->getImageProperty($attr);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Rotate the image
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
private function rotate(\Imagick $imo)
|
||||||
|
{
|
||||||
|
if (array_key_exists($this->orientation,$this->_rotate))
|
||||||
|
$imo->rotateImage(new \ImagickPixel('none'),$this->_rotate[$this->orientation]);
|
||||||
|
|
||||||
|
return $imo->getImageBlob();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the image's thumbnail
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public function thumbnail($rotate=TRUE)
|
||||||
|
{
|
||||||
|
if (! $this->thumbnail)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if (! $rotate OR ! array_key_exists($this->orientation,$this->_rotate) OR ! extension_loaded('imagick'))
|
||||||
|
return $this->thumbnail;
|
||||||
|
|
||||||
|
$imo = new \Imagick();
|
||||||
|
$imo->readImageBlob($this->thumbnail);
|
||||||
|
|
||||||
|
return $this->rotate($imo);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function list_duplicate() {
|
||||||
|
$po = DB::table('photo');
|
||||||
|
|
||||||
|
if ($this->id)
|
||||||
|
$po->where('id','!=',$this->id);
|
||||||
|
|
||||||
|
// Ignore photo's pending removal.
|
||||||
|
$po->where(function($query) {
|
||||||
|
$query->where('remove','!=',TRUE)
|
||||||
|
->orWhere('remove','=',NULL);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Where the signature is the same
|
||||||
|
$po->where(function($query) {
|
||||||
|
$query->where('signature','=',$this->signature);
|
||||||
|
|
||||||
|
// Or they have the same time taken with the same camera
|
||||||
|
if ($this->date_taken AND ($this->model OR $this->make)) {
|
||||||
|
$query->orWhere(function($query) {
|
||||||
|
$query->where('date_taken','=',$this->date_taken ? $this->date_taken : NULL);
|
||||||
|
$query->where('subsectime','=',$this->subsectime ? $this->subsectime : NULL);
|
||||||
|
|
||||||
|
if (! is_null($this->model))
|
||||||
|
$query->where('model','=',$this->model);
|
||||||
|
|
||||||
|
if (! is_null($this->make))
|
||||||
|
$query->where('make','=',$this->make);
|
||||||
|
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return $po;
|
||||||
|
}
|
||||||
|
}
|
9
app/Model/PhotoPerson.php
Normal file
9
app/Model/PhotoPerson.php
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Model;
|
||||||
|
|
||||||
|
use Illuminate\Database\Eloquent\Model;
|
||||||
|
|
||||||
|
class PhotoPerson extends Model
|
||||||
|
{
|
||||||
|
}
|
15
app/Model/PhotoTag.php
Normal file
15
app/Model/PhotoTag.php
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Model;
|
||||||
|
|
||||||
|
use Illuminate\Database\Eloquent\Model;
|
||||||
|
|
||||||
|
class PhotoTag extends Model
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* The table associated with the model.
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $table = 'photo_tag';
|
||||||
|
}
|
9
app/Model/Tag.php
Normal file
9
app/Model/Tag.php
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Model;
|
||||||
|
|
||||||
|
use Illuminate\Database\Eloquent\Model;
|
||||||
|
|
||||||
|
class Tag extends Model
|
||||||
|
{
|
||||||
|
}
|
@ -1,10 +0,0 @@
|
|||||||
<?php defined('SYSPATH') or die('No direct script access.');
|
|
||||||
|
|
||||||
class Controller_Welcome extends Controller {
|
|
||||||
|
|
||||||
public function action_index()
|
|
||||||
{
|
|
||||||
HTTP::redirect('photo');
|
|
||||||
}
|
|
||||||
|
|
||||||
} // End Welcome
|
|
@ -1,14 +0,0 @@
|
|||||||
<?php defined('SYSPATH') or die('No direct access allowed.');
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This class supports Albums.
|
|
||||||
*
|
|
||||||
* @package Photo
|
|
||||||
* @category Models
|
|
||||||
* @author Deon George
|
|
||||||
* @copyright (c) 2014 Deon George
|
|
||||||
* @license http://dev.leenooks.net/license.html
|
|
||||||
*/
|
|
||||||
class Model_Album extends ORM {
|
|
||||||
}
|
|
||||||
?>
|
|
@ -185,6 +185,8 @@ class Model_Photo extends ORM {
|
|||||||
|
|
||||||
return join('|',array_keys($result));
|
return join('|',array_keys($result));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
private function rotate(Imagick $imo) {
|
private function rotate(Imagick $imo) {
|
||||||
switch ($this->orientation) {
|
switch ($this->orientation) {
|
||||||
case 3: $imo->rotateImage(new ImagickPixel('none'),180);
|
case 3: $imo->rotateImage(new ImagickPixel('none'),180);
|
||||||
@ -195,6 +197,7 @@ class Model_Photo extends ORM {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
public function rotation() {
|
public function rotation() {
|
||||||
switch ($this->orientation) {
|
switch ($this->orientation) {
|
||||||
@ -211,6 +214,7 @@ class Model_Photo extends ORM {
|
|||||||
return sprintf('%s...%s',substr($signature,0,$chars),substr($signature,-1*$chars));
|
return sprintf('%s...%s',substr($signature,0,$chars),substr($signature,-1*$chars));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
public function thumbnail($rotate=TRUE) {
|
public function thumbnail($rotate=TRUE) {
|
||||||
if (! $this->thumbnail)
|
if (! $this->thumbnail)
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -224,6 +228,7 @@ class Model_Photo extends ORM {
|
|||||||
|
|
||||||
return $imo->getImageBlob();
|
return $imo->getImageBlob();
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
public function thumbnail_sig() {
|
public function thumbnail_sig() {
|
||||||
return md5($this->thumbnail()).':'.strlen($this->thumbnail());
|
return md5($this->thumbnail()).':'.strlen($this->thumbnail());
|
||||||
|
@ -1,14 +0,0 @@
|
|||||||
<?php defined('SYSPATH') or die('No direct access allowed.');
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This class supports Tags.
|
|
||||||
*
|
|
||||||
* @package Photo
|
|
||||||
* @category Models
|
|
||||||
* @author Deon George
|
|
||||||
* @copyright (c) 2014 Deon George
|
|
||||||
* @license http://dev.leenooks.net/license.html
|
|
||||||
*/
|
|
||||||
class Model_Photo_People extends ORM {
|
|
||||||
}
|
|
||||||
?>
|
|
@ -1,14 +0,0 @@
|
|||||||
<?php defined('SYSPATH') or die('No direct access allowed.');
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This class supports Tags.
|
|
||||||
*
|
|
||||||
* @package Photo
|
|
||||||
* @category Models
|
|
||||||
* @author Deon George
|
|
||||||
* @copyright (c) 2014 Deon George
|
|
||||||
* @license http://dev.leenooks.net/license.html
|
|
||||||
*/
|
|
||||||
class Model_Photo_Tag extends ORM {
|
|
||||||
}
|
|
||||||
?>
|
|
@ -1,14 +0,0 @@
|
|||||||
<?php defined('SYSPATH') or die('No direct access allowed.');
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This class supports Tags.
|
|
||||||
*
|
|
||||||
* @package Photo
|
|
||||||
* @category Models
|
|
||||||
* @author Deon George
|
|
||||||
* @copyright (c) 2014 Deon George
|
|
||||||
* @license http://dev.leenooks.net/license.html
|
|
||||||
*/
|
|
||||||
class Model_Tags extends ORM {
|
|
||||||
}
|
|
||||||
?>
|
|
@ -1,186 +0,0 @@
|
|||||||
<?php defined('SYSPATH') or die('No direct access allowed.');
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Import photo to the database
|
|
||||||
*
|
|
||||||
* @package Photo
|
|
||||||
* @category Tasks
|
|
||||||
* @author Deon George
|
|
||||||
* @copyright (c) 2014 Deon George
|
|
||||||
* @license http://dev.leenooks.net/license.html
|
|
||||||
*/
|
|
||||||
class Task_Photo_Import extends Minion_Task {
|
|
||||||
private $_log = '/tmp/photo_import.txt';
|
|
||||||
|
|
||||||
private $_accepted = array(
|
|
||||||
'jpg',
|
|
||||||
);
|
|
||||||
|
|
||||||
protected $_options = array(
|
|
||||||
'dir'=>NULL, // Directory of Photos to Import
|
|
||||||
'file'=>NULL, // Photo File to Import
|
|
||||||
'tags'=>NULL,
|
|
||||||
'people'=>NULL,
|
|
||||||
'ignoredupe'=>FALSE, // Skip duplicate photos
|
|
||||||
'deletedupe'=>FALSE, // Skip duplicate photos
|
|
||||||
'verbose'=>FALSE, // Photo File to Import
|
|
||||||
);
|
|
||||||
|
|
||||||
private function _adddir(&$value,$key,$path='') {
|
|
||||||
if ($path)
|
|
||||||
$value = sprintf('%s/%s',$path,$value);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected function _execute(array $params) {
|
|
||||||
$tags = NULL;
|
|
||||||
$t = $p = array();
|
|
||||||
|
|
||||||
if (is_null($params['file']) AND is_null($params['dir']) OR ($params['file'] AND $params['dir']))
|
|
||||||
throw new Kohana_Exception('Missing filename, please use --file= OR --dir=');
|
|
||||||
|
|
||||||
if ($params['dir']) {
|
|
||||||
$files = array_diff(scandir($params['dir']),array('.','..'));
|
|
||||||
|
|
||||||
array_walk($files,'static::_adddir',$params['dir']);
|
|
||||||
|
|
||||||
} else
|
|
||||||
$files = array($params['file']);
|
|
||||||
|
|
||||||
// Tags
|
|
||||||
if ($params['tags']) {
|
|
||||||
$tags = explode(',',$params['tags']);
|
|
||||||
$t = ORM::factory('Tags')->where('tag','IN',$tags)->find_all();
|
|
||||||
}
|
|
||||||
|
|
||||||
// People
|
|
||||||
if ($params['people']) {
|
|
||||||
$tags = explode(',',$params['people']);
|
|
||||||
$p = ORM::factory('People')->where('tag','IN',$tags)->find_all();
|
|
||||||
}
|
|
||||||
|
|
||||||
$c = 0;
|
|
||||||
foreach ($files as $file) {
|
|
||||||
if ($params['verbose'])
|
|
||||||
printf("Processing file [%s]\n",$file);
|
|
||||||
|
|
||||||
if (preg_match('/@__thumb/',$file) OR preg_match('/\/._/',$file)) {
|
|
||||||
$this->writelog(sprintf("Ignoring file [%s]\n",$file));
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (! in_array(strtolower(pathinfo($file,PATHINFO_EXTENSION)),$this->_accepted)) {
|
|
||||||
$this->writelog(sprintf("Ignoring file [%s]\n",$file));
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
$c++;
|
|
||||||
|
|
||||||
$po = ORM::factory('Photo',array('filename'=>$file));
|
|
||||||
|
|
||||||
if (! $po->loaded())
|
|
||||||
$po->filename = realpath($file);
|
|
||||||
|
|
||||||
$po->date_taken = $this->dbcol(strtotime($po->io('exif:DateTime')));
|
|
||||||
$po->signature = $this->dbcol($po->io()->getImageSignature());
|
|
||||||
$po->make = $this->dbcol($po->io('exif:Make'));
|
|
||||||
$po->model = $this->dbcol($po->io('exif:Model'));
|
|
||||||
$po->height = $this->dbcol($po->io()->getImageheight());
|
|
||||||
$po->width = $this->dbcol($po->io()->getImageWidth());
|
|
||||||
$po->orientation = $this->dbcol($po->io()->getImageOrientation());
|
|
||||||
$po->subsectime = $this->dbcol($po->io('exif:SubSecTimeOriginal'));
|
|
||||||
|
|
||||||
$po->gps_lat = $this->dbcol($po->gps(preg_split('/,\s?/',$po->io()->getImageProperty('exif:GPSLatitude')),$po->io()->getImageProperty('exif:GPSLatitudeRef')));
|
|
||||||
$po->gps_lon = $this->dbcol($po->gps(preg_split('/,\s?/',$po->io()->getImageProperty('exif:GPSLongitude')),$po->io()->getImageProperty('exif:GPSLongitudeRef')));
|
|
||||||
|
|
||||||
try {
|
|
||||||
$po->thumbnail = $this->dbcol(exif_thumbnail($po->filename));
|
|
||||||
} catch (Exception $e) {
|
|
||||||
}
|
|
||||||
|
|
||||||
switch ($params['verbose']) {
|
|
||||||
case 1:
|
|
||||||
print_r($po->what_changed());
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 2:
|
|
||||||
print_r($po->io()->getImageProperties());
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
$x = $po->list_duplicate()->find_all();
|
|
||||||
if (count($x)) {
|
|
||||||
$skip = FALSE;
|
|
||||||
|
|
||||||
foreach ($x as $o) {
|
|
||||||
# We'll only ignore based on the same signature.
|
|
||||||
if ($params['ignoredupe'] AND ($po->signature == $o->signature)) {
|
|
||||||
$skip = TRUE;
|
|
||||||
$this->writelog(sprintf("Ignore file [%s], it's the same as [%s (%s)]\n",$po->filename,$o->id,$o->file_path()));
|
|
||||||
break;
|
|
||||||
|
|
||||||
} elseif ($params['deletedupe'] AND ($po->signature == $o->signature) AND ($po->filename != $o->filename)) {
|
|
||||||
$skip = TRUE;
|
|
||||||
$this->writelog(sprintf("Delete file [%s], it's the same as [%s (%s)] with signature [%s]\n",$po->filename,$o->id,$o->file_path(),$po->signature));
|
|
||||||
unlink($file);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
unset($x);
|
|
||||||
|
|
||||||
if ($skip)
|
|
||||||
continue;
|
|
||||||
else
|
|
||||||
$po->duplicate = '1';
|
|
||||||
}
|
|
||||||
|
|
||||||
if (! $po->changed())
|
|
||||||
$this->writelog(sprintf("Image [%s] already in DB: %s\n",$file,$po->id));
|
|
||||||
|
|
||||||
$po->save();
|
|
||||||
|
|
||||||
if ($po->saved())
|
|
||||||
$this->writelog(sprintf("Image [%s] stored in DB: %s\n",$file,$po->id));
|
|
||||||
|
|
||||||
// Record our tags
|
|
||||||
foreach ($t as $o) {
|
|
||||||
$x = ORM::factory('Photo_Tag')->where('tag_id','=',$o->id)->where('photo_id','=',$po->id)->find();
|
|
||||||
$x->tag_id = $o->id;
|
|
||||||
$x->photo_id = $po->id;
|
|
||||||
$x->save();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Record our people
|
|
||||||
foreach ($p as $o) {
|
|
||||||
$x = ORM::factory('Photo_People',array('people_id'=>$o->id,'photo_id'=>$po->id));
|
|
||||||
$x->people_id = $o->id;
|
|
||||||
$x->photo_id = $po->id;
|
|
||||||
$x->save();
|
|
||||||
}
|
|
||||||
|
|
||||||
unset($po);
|
|
||||||
unset($x);
|
|
||||||
unset($o);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($c > 1)
|
|
||||||
return sprintf("Images processed: %s\n",$c);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Force the return of a string or NULL
|
|
||||||
private function dbcol($val,$noval=NULL) {
|
|
||||||
return $val ? (string)$val : $noval;
|
|
||||||
}
|
|
||||||
|
|
||||||
private function writelog($msg) {
|
|
||||||
if (! $this->_log)
|
|
||||||
return;
|
|
||||||
|
|
||||||
static $fh = NULL;
|
|
||||||
|
|
||||||
if (is_null($fh))
|
|
||||||
$fh = fopen($this->_log,'a+');
|
|
||||||
|
|
||||||
fwrite($fh,$msg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
?>
|
|
@ -13,7 +13,9 @@
|
|||||||
"mockery/mockery": "0.9.*",
|
"mockery/mockery": "0.9.*",
|
||||||
"phpunit/phpunit": "~4.0",
|
"phpunit/phpunit": "~4.0",
|
||||||
"symfony/css-selector": "2.8.*|3.0.*",
|
"symfony/css-selector": "2.8.*|3.0.*",
|
||||||
"symfony/dom-crawler": "2.8.*|3.0.*"
|
"symfony/dom-crawler": "2.8.*|3.0.*",
|
||||||
|
"xethron/migrations-generator": "dev-l5",
|
||||||
|
"way/generators": "dev-feature/laravel-five-stable"
|
||||||
},
|
},
|
||||||
"autoload": {
|
"autoload": {
|
||||||
"classmap": [
|
"classmap": [
|
||||||
@ -46,5 +48,11 @@
|
|||||||
},
|
},
|
||||||
"config": {
|
"config": {
|
||||||
"preferred-install": "dist"
|
"preferred-install": "dist"
|
||||||
|
},
|
||||||
|
"repositories": {
|
||||||
|
"repo-name": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "git@github.com:jamisonvalenta/Laravel-4-Generators.git"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
502
composer.lock
generated
502
composer.lock
generated
@ -4,8 +4,8 @@
|
|||||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
|
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
|
||||||
"This file is @generated automatically"
|
"This file is @generated automatically"
|
||||||
],
|
],
|
||||||
"hash": "c284a9c122da36c99a8b6597bdce7aa6",
|
"hash": "06f9a4d19eda3cf3c92386077c05117c",
|
||||||
"content-hash": "8b1485987e7c5949da82435d403e52e8",
|
"content-hash": "e32614d49ea2fa40cc882537b7125da4",
|
||||||
"packages": [
|
"packages": [
|
||||||
{
|
{
|
||||||
"name": "classpreloader/classpreloader",
|
"name": "classpreloader/classpreloader",
|
||||||
@ -1780,6 +1780,354 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"packages-dev": [
|
"packages-dev": [
|
||||||
|
{
|
||||||
|
"name": "doctrine/annotations",
|
||||||
|
"version": "v1.2.7",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/doctrine/annotations.git",
|
||||||
|
"reference": "f25c8aab83e0c3e976fd7d19875f198ccf2f7535"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/doctrine/annotations/zipball/f25c8aab83e0c3e976fd7d19875f198ccf2f7535",
|
||||||
|
"reference": "f25c8aab83e0c3e976fd7d19875f198ccf2f7535",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"doctrine/lexer": "1.*",
|
||||||
|
"php": ">=5.3.2"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"doctrine/cache": "1.*",
|
||||||
|
"phpunit/phpunit": "4.*"
|
||||||
|
},
|
||||||
|
"type": "library",
|
||||||
|
"extra": {
|
||||||
|
"branch-alias": {
|
||||||
|
"dev-master": "1.3.x-dev"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"autoload": {
|
||||||
|
"psr-0": {
|
||||||
|
"Doctrine\\Common\\Annotations\\": "lib/"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Roman Borschel",
|
||||||
|
"email": "roman@code-factory.org"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Benjamin Eberlei",
|
||||||
|
"email": "kontakt@beberlei.de"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Guilherme Blanco",
|
||||||
|
"email": "guilhermeblanco@gmail.com"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Jonathan Wage",
|
||||||
|
"email": "jonwage@gmail.com"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Johannes Schmitt",
|
||||||
|
"email": "schmittjoh@gmail.com"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "Docblock Annotations Parser",
|
||||||
|
"homepage": "http://www.doctrine-project.org",
|
||||||
|
"keywords": [
|
||||||
|
"annotations",
|
||||||
|
"docblock",
|
||||||
|
"parser"
|
||||||
|
],
|
||||||
|
"time": "2015-08-31 12:32:49"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "doctrine/cache",
|
||||||
|
"version": "v1.6.0",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/doctrine/cache.git",
|
||||||
|
"reference": "f8af318d14bdb0eff0336795b428b547bd39ccb6"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/doctrine/cache/zipball/f8af318d14bdb0eff0336795b428b547bd39ccb6",
|
||||||
|
"reference": "f8af318d14bdb0eff0336795b428b547bd39ccb6",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"php": "~5.5|~7.0"
|
||||||
|
},
|
||||||
|
"conflict": {
|
||||||
|
"doctrine/common": ">2.2,<2.4"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"phpunit/phpunit": "~4.8|~5.0",
|
||||||
|
"predis/predis": "~1.0",
|
||||||
|
"satooshi/php-coveralls": "~0.6"
|
||||||
|
},
|
||||||
|
"type": "library",
|
||||||
|
"extra": {
|
||||||
|
"branch-alias": {
|
||||||
|
"dev-master": "1.6.x-dev"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"Doctrine\\Common\\Cache\\": "lib/Doctrine/Common/Cache"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Roman Borschel",
|
||||||
|
"email": "roman@code-factory.org"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Benjamin Eberlei",
|
||||||
|
"email": "kontakt@beberlei.de"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Guilherme Blanco",
|
||||||
|
"email": "guilhermeblanco@gmail.com"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Jonathan Wage",
|
||||||
|
"email": "jonwage@gmail.com"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Johannes Schmitt",
|
||||||
|
"email": "schmittjoh@gmail.com"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "Caching library offering an object-oriented API for many cache backends",
|
||||||
|
"homepage": "http://www.doctrine-project.org",
|
||||||
|
"keywords": [
|
||||||
|
"cache",
|
||||||
|
"caching"
|
||||||
|
],
|
||||||
|
"time": "2015-12-31 16:37:02"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "doctrine/collections",
|
||||||
|
"version": "v1.3.0",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/doctrine/collections.git",
|
||||||
|
"reference": "6c1e4eef75f310ea1b3e30945e9f06e652128b8a"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/doctrine/collections/zipball/6c1e4eef75f310ea1b3e30945e9f06e652128b8a",
|
||||||
|
"reference": "6c1e4eef75f310ea1b3e30945e9f06e652128b8a",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"php": ">=5.3.2"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"phpunit/phpunit": "~4.0"
|
||||||
|
},
|
||||||
|
"type": "library",
|
||||||
|
"extra": {
|
||||||
|
"branch-alias": {
|
||||||
|
"dev-master": "1.2.x-dev"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"autoload": {
|
||||||
|
"psr-0": {
|
||||||
|
"Doctrine\\Common\\Collections\\": "lib/"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Roman Borschel",
|
||||||
|
"email": "roman@code-factory.org"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Benjamin Eberlei",
|
||||||
|
"email": "kontakt@beberlei.de"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Guilherme Blanco",
|
||||||
|
"email": "guilhermeblanco@gmail.com"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Jonathan Wage",
|
||||||
|
"email": "jonwage@gmail.com"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Johannes Schmitt",
|
||||||
|
"email": "schmittjoh@gmail.com"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "Collections Abstraction library",
|
||||||
|
"homepage": "http://www.doctrine-project.org",
|
||||||
|
"keywords": [
|
||||||
|
"array",
|
||||||
|
"collections",
|
||||||
|
"iterator"
|
||||||
|
],
|
||||||
|
"time": "2015-04-14 22:21:58"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "doctrine/common",
|
||||||
|
"version": "v2.6.1",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/doctrine/common.git",
|
||||||
|
"reference": "a579557bc689580c19fee4e27487a67fe60defc0"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/doctrine/common/zipball/a579557bc689580c19fee4e27487a67fe60defc0",
|
||||||
|
"reference": "a579557bc689580c19fee4e27487a67fe60defc0",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"doctrine/annotations": "1.*",
|
||||||
|
"doctrine/cache": "1.*",
|
||||||
|
"doctrine/collections": "1.*",
|
||||||
|
"doctrine/inflector": "1.*",
|
||||||
|
"doctrine/lexer": "1.*",
|
||||||
|
"php": "~5.5|~7.0"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"phpunit/phpunit": "~4.8|~5.0"
|
||||||
|
},
|
||||||
|
"type": "library",
|
||||||
|
"extra": {
|
||||||
|
"branch-alias": {
|
||||||
|
"dev-master": "2.7.x-dev"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"Doctrine\\Common\\": "lib/Doctrine/Common"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Roman Borschel",
|
||||||
|
"email": "roman@code-factory.org"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Benjamin Eberlei",
|
||||||
|
"email": "kontakt@beberlei.de"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Guilherme Blanco",
|
||||||
|
"email": "guilhermeblanco@gmail.com"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Jonathan Wage",
|
||||||
|
"email": "jonwage@gmail.com"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Johannes Schmitt",
|
||||||
|
"email": "schmittjoh@gmail.com"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "Common Library for Doctrine projects",
|
||||||
|
"homepage": "http://www.doctrine-project.org",
|
||||||
|
"keywords": [
|
||||||
|
"annotations",
|
||||||
|
"collections",
|
||||||
|
"eventmanager",
|
||||||
|
"persistence",
|
||||||
|
"spl"
|
||||||
|
],
|
||||||
|
"time": "2015-12-25 13:18:31"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "doctrine/dbal",
|
||||||
|
"version": "v2.5.4",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/doctrine/dbal.git",
|
||||||
|
"reference": "abbdfd1cff43a7b99d027af3be709bc8fc7d4769"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/doctrine/dbal/zipball/abbdfd1cff43a7b99d027af3be709bc8fc7d4769",
|
||||||
|
"reference": "abbdfd1cff43a7b99d027af3be709bc8fc7d4769",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"doctrine/common": ">=2.4,<2.7-dev",
|
||||||
|
"php": ">=5.3.2"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"phpunit/phpunit": "4.*",
|
||||||
|
"symfony/console": "2.*"
|
||||||
|
},
|
||||||
|
"suggest": {
|
||||||
|
"symfony/console": "For helpful console commands such as SQL execution and import of files."
|
||||||
|
},
|
||||||
|
"bin": [
|
||||||
|
"bin/doctrine-dbal"
|
||||||
|
],
|
||||||
|
"type": "library",
|
||||||
|
"extra": {
|
||||||
|
"branch-alias": {
|
||||||
|
"dev-master": "2.5.x-dev"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"autoload": {
|
||||||
|
"psr-0": {
|
||||||
|
"Doctrine\\DBAL\\": "lib/"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Roman Borschel",
|
||||||
|
"email": "roman@code-factory.org"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Benjamin Eberlei",
|
||||||
|
"email": "kontakt@beberlei.de"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Guilherme Blanco",
|
||||||
|
"email": "guilhermeblanco@gmail.com"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Jonathan Wage",
|
||||||
|
"email": "jonwage@gmail.com"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "Database Abstraction Layer",
|
||||||
|
"homepage": "http://www.doctrine-project.org",
|
||||||
|
"keywords": [
|
||||||
|
"database",
|
||||||
|
"dbal",
|
||||||
|
"persistence",
|
||||||
|
"queryobject"
|
||||||
|
],
|
||||||
|
"time": "2016-01-05 22:11:12"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "doctrine/instantiator",
|
"name": "doctrine/instantiator",
|
||||||
"version": "1.0.5",
|
"version": "1.0.5",
|
||||||
@ -1834,6 +2182,60 @@
|
|||||||
],
|
],
|
||||||
"time": "2015-06-14 21:17:01"
|
"time": "2015-06-14 21:17:01"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "doctrine/lexer",
|
||||||
|
"version": "v1.0.1",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/doctrine/lexer.git",
|
||||||
|
"reference": "83893c552fd2045dd78aef794c31e694c37c0b8c"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/doctrine/lexer/zipball/83893c552fd2045dd78aef794c31e694c37c0b8c",
|
||||||
|
"reference": "83893c552fd2045dd78aef794c31e694c37c0b8c",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"php": ">=5.3.2"
|
||||||
|
},
|
||||||
|
"type": "library",
|
||||||
|
"extra": {
|
||||||
|
"branch-alias": {
|
||||||
|
"dev-master": "1.0.x-dev"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"autoload": {
|
||||||
|
"psr-0": {
|
||||||
|
"Doctrine\\Common\\Lexer\\": "lib/"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Roman Borschel",
|
||||||
|
"email": "roman@code-factory.org"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Guilherme Blanco",
|
||||||
|
"email": "guilhermeblanco@gmail.com"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Johannes Schmitt",
|
||||||
|
"email": "schmittjoh@gmail.com"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "Base library for a lexer that can be used in Top-Down, Recursive Descent Parsers.",
|
||||||
|
"homepage": "http://www.doctrine-project.org",
|
||||||
|
"keywords": [
|
||||||
|
"lexer",
|
||||||
|
"parser"
|
||||||
|
],
|
||||||
|
"time": "2014-09-09 13:34:57"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "fzaninotto/faker",
|
"name": "fzaninotto/faker",
|
||||||
"version": "v1.6.0",
|
"version": "v1.6.0",
|
||||||
@ -3101,6 +3503,45 @@
|
|||||||
"homepage": "https://symfony.com",
|
"homepage": "https://symfony.com",
|
||||||
"time": "2016-06-14 11:18:07"
|
"time": "2016-06-14 11:18:07"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "way/generators",
|
||||||
|
"version": "dev-feature/laravel-five-stable",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "git@github.com:jamisonvalenta/Laravel-4-Generators.git",
|
||||||
|
"reference": "a358bb44f517e2b3c1fd4f848f2646857c75b3a4"
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"illuminate/support": "~5.0",
|
||||||
|
"php": ">=5.4.0"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"behat/behat": "~2.5.1",
|
||||||
|
"behat/mink": "~1.5.0",
|
||||||
|
"behat/mink-extension": "~1.2.0",
|
||||||
|
"behat/mink-goutte-driver": "~1.0.9",
|
||||||
|
"behat/mink-selenium2-driver": "~1.1.1",
|
||||||
|
"phpspec/phpspec": "~2.0",
|
||||||
|
"phpunit/phpunit": "~3.7"
|
||||||
|
},
|
||||||
|
"type": "library",
|
||||||
|
"autoload": {
|
||||||
|
"psr-0": {
|
||||||
|
"Way\\Generators": "src/"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Jeffrey Way",
|
||||||
|
"email": "jeffrey@jeffrey-way.com"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "Rapidly generate resources, migrations, models, and much more.",
|
||||||
|
"time": "2015-02-17 06:26:25"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "webmozart/assert",
|
"name": "webmozart/assert",
|
||||||
"version": "1.0.2",
|
"version": "1.0.2",
|
||||||
@ -3149,11 +3590,66 @@
|
|||||||
"validate"
|
"validate"
|
||||||
],
|
],
|
||||||
"time": "2015-08-24 13:29:44"
|
"time": "2015-08-24 13:29:44"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "xethron/migrations-generator",
|
||||||
|
"version": "dev-l5",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/Xethron/migrations-generator.git",
|
||||||
|
"reference": "e5e86efb5731e6859ea0d96a806159f9f2c26ce1"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/Xethron/migrations-generator/zipball/e5e86efb5731e6859ea0d96a806159f9f2c26ce1",
|
||||||
|
"reference": "e5e86efb5731e6859ea0d96a806159f9f2c26ce1",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"doctrine/dbal": "~2.4",
|
||||||
|
"illuminate/support": ">=4.1",
|
||||||
|
"php": ">=5.4.0",
|
||||||
|
"way/generators": "dev-feature/laravel-five-stable"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"illuminate/cache": ">=4.1.0",
|
||||||
|
"illuminate/console": ">=4.1.0",
|
||||||
|
"mockery/mockery": ">=0.9.0",
|
||||||
|
"phpunit/phpunit": ">=4.0.0"
|
||||||
|
},
|
||||||
|
"type": "library",
|
||||||
|
"autoload": {
|
||||||
|
"psr-0": {
|
||||||
|
"Xethron\\MigrationsGenerator": "src/"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Bernhard Breytenbach",
|
||||||
|
"email": "bernhard@coffeecode.co.za"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "Generates Laravel Migrations from an existing database",
|
||||||
|
"keywords": [
|
||||||
|
"artisan",
|
||||||
|
"generator",
|
||||||
|
"laravel",
|
||||||
|
"migration",
|
||||||
|
"migrations"
|
||||||
|
],
|
||||||
|
"time": "2015-02-23 05:43:08"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"aliases": [],
|
"aliases": [],
|
||||||
"minimum-stability": "stable",
|
"minimum-stability": "stable",
|
||||||
"stability-flags": [],
|
"stability-flags": {
|
||||||
|
"xethron/migrations-generator": 20,
|
||||||
|
"way/generators": 20
|
||||||
|
},
|
||||||
"prefer-stable": false,
|
"prefer-stable": false,
|
||||||
"prefer-lowest": false,
|
"prefer-lowest": false,
|
||||||
"platform": {
|
"platform": {
|
||||||
|
@ -52,7 +52,7 @@ return [
|
|||||||
|
|
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
'timezone' => 'UTC',
|
'timezone' => 'Australia/Melbourne',
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|--------------------------------------------------------------------------
|
|--------------------------------------------------------------------------
|
||||||
@ -158,6 +158,8 @@ return [
|
|||||||
App\Providers\EventServiceProvider::class,
|
App\Providers\EventServiceProvider::class,
|
||||||
App\Providers\RouteServiceProvider::class,
|
App\Providers\RouteServiceProvider::class,
|
||||||
|
|
||||||
|
Way\Generators\GeneratorsServiceProvider::class,
|
||||||
|
Xethron\MigrationsGenerator\MigrationsGeneratorServiceProvider::class,
|
||||||
],
|
],
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
9
config/photo.php
Normal file
9
config/photo.php
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
return [
|
||||||
|
'dir'=>'/var/www/sites/co.dlcm.p/store',
|
||||||
|
'import'=>[
|
||||||
|
'accepted'=>['jpg'],
|
||||||
|
'log'=>'/tmp/import.log',
|
||||||
|
],
|
||||||
|
];
|
48
database/migrations/2016_06_03_055603_create_photo_table.php
Normal file
48
database/migrations/2016_06_03_055603_create_photo_table.php
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
|
||||||
|
class CreatePhotoTable extends Migration {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function up()
|
||||||
|
{
|
||||||
|
Schema::create('photo', function(Blueprint $table)
|
||||||
|
{
|
||||||
|
$table->bigInteger('id', true);
|
||||||
|
$table->timestamps();
|
||||||
|
$table->integer('date_taken')->nullable();
|
||||||
|
$table->smallInteger('subsectime')->nullable();
|
||||||
|
$table->string('filename', 128);
|
||||||
|
$table->string('signature', 64)->nullable();
|
||||||
|
$table->string('make', 32)->nullable();
|
||||||
|
$table->string('model', 32)->nullable();
|
||||||
|
$table->integer('height')->nullable();
|
||||||
|
$table->integer('width')->nullable();
|
||||||
|
$table->integer('orientation')->nullable();
|
||||||
|
$table->float('gps_lat', 10, 0)->nullable();
|
||||||
|
$table->float('gps_lon', 10, 0)->nullable();
|
||||||
|
$table->binary('thumbnail', 65535)->nullable();
|
||||||
|
$table->boolean('duplicate')->nullable();
|
||||||
|
$table->boolean('remove')->nullable();
|
||||||
|
$table->boolean('flag')->nullable();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function down()
|
||||||
|
{
|
||||||
|
Schema::drop('photo');
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,35 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
|
||||||
|
class CreatePeopleTable extends Migration {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function up()
|
||||||
|
{
|
||||||
|
Schema::create('people', function(Blueprint $table)
|
||||||
|
{
|
||||||
|
$table->integer('id', true);
|
||||||
|
$table->string('tag', 16)->unique('tag_UNIQUE');
|
||||||
|
$table->string('name', 64)->nullable();
|
||||||
|
$table->integer('date_birth')->nullable();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function down()
|
||||||
|
{
|
||||||
|
Schema::drop('people');
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,36 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
|
||||||
|
class CreatePhotoPeopleTable extends Migration {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function up()
|
||||||
|
{
|
||||||
|
Schema::create('photo_people', function(Blueprint $table)
|
||||||
|
{
|
||||||
|
$table->bigInteger('id', true);
|
||||||
|
$table->timestamps();
|
||||||
|
$table->integer('people_id');
|
||||||
|
$table->bigInteger('photo_id')->index('fk_pp_ph_idx');
|
||||||
|
$table->unique(['people_id','photo_id'], 'UNIQUE');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function down()
|
||||||
|
{
|
||||||
|
Schema::drop('photo_people');
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,36 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
|
||||||
|
class CreatePhotoTagTable extends Migration {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function up()
|
||||||
|
{
|
||||||
|
Schema::create('photo_tag', function(Blueprint $table)
|
||||||
|
{
|
||||||
|
$table->bigInteger('id', true);
|
||||||
|
$table->timestamps();
|
||||||
|
$table->bigInteger('photo_id');
|
||||||
|
$table->bigInteger('tag_id')->index('pt_t_idx');
|
||||||
|
$table->unique(['photo_id','tag_id'], 'UNIQUE');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function down()
|
||||||
|
{
|
||||||
|
Schema::drop('photo_tag');
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
34
database/migrations/2016_06_03_055604_create_tags_table.php
Normal file
34
database/migrations/2016_06_03_055604_create_tags_table.php
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
|
||||||
|
class CreateTagsTable extends Migration {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function up()
|
||||||
|
{
|
||||||
|
Schema::create('tags', function(Blueprint $table)
|
||||||
|
{
|
||||||
|
$table->bigInteger('id', true);
|
||||||
|
$table->string('tag', 16)->unique('tag_UNIQUE');
|
||||||
|
$table->string('description', 45)->nullable();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function down()
|
||||||
|
{
|
||||||
|
Schema::drop('tags');
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,37 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
|
||||||
|
class AddForeignKeysToPhotoPeopleTable extends Migration {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function up()
|
||||||
|
{
|
||||||
|
Schema::table('photo_people', function(Blueprint $table)
|
||||||
|
{
|
||||||
|
$table->foreign('people_id', 'fk_pp_p')->references('id')->on('people')->onUpdate('NO ACTION')->onDelete('NO ACTION');
|
||||||
|
$table->foreign('photo_id', 'fk_pp_ph')->references('id')->on('photo')->onUpdate('NO ACTION')->onDelete('NO ACTION');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function down()
|
||||||
|
{
|
||||||
|
Schema::table('photo_people', function(Blueprint $table)
|
||||||
|
{
|
||||||
|
$table->dropForeign('fk_pp_p');
|
||||||
|
$table->dropForeign('fk_pp_ph');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,37 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
|
||||||
|
class AddForeignKeysToPhotoTagTable extends Migration {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function up()
|
||||||
|
{
|
||||||
|
Schema::table('photo_tag', function(Blueprint $table)
|
||||||
|
{
|
||||||
|
$table->foreign('photo_id', 'fk_pt_p')->references('id')->on('photo')->onUpdate('NO ACTION')->onDelete('NO ACTION');
|
||||||
|
$table->foreign('tag_id', 'fk_pt_t')->references('id')->on('tags')->onUpdate('NO ACTION')->onDelete('NO ACTION');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function down()
|
||||||
|
{
|
||||||
|
Schema::table('photo_tag', function(Blueprint $table)
|
||||||
|
{
|
||||||
|
$table->dropForeign('fk_pt_p');
|
||||||
|
$table->dropForeign('fk_pt_t');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
1
resources/views/auth/emails/password.blade.php
Normal file
1
resources/views/auth/emails/password.blade.php
Normal file
@ -0,0 +1 @@
|
|||||||
|
Click here to reset your password: <a href="{{ $link = url('password/reset', $token).'?email='.urlencode($user->getEmailForPasswordReset()) }}"> {{ $link }} </a>
|
66
resources/views/auth/login.blade.php
Normal file
66
resources/views/auth/login.blade.php
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
@extends('layouts.app')
|
||||||
|
|
||||||
|
@section('content')
|
||||||
|
<div class="container">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-8 col-md-offset-2">
|
||||||
|
<div class="panel panel-default">
|
||||||
|
<div class="panel-heading">Login</div>
|
||||||
|
<div class="panel-body">
|
||||||
|
<form class="form-horizontal" role="form" method="POST" action="{{ url('/login') }}">
|
||||||
|
{{ csrf_field() }}
|
||||||
|
|
||||||
|
<div class="form-group{{ $errors->has('email') ? ' has-error' : '' }}">
|
||||||
|
<label for="email" class="col-md-4 control-label">E-Mail Address</label>
|
||||||
|
|
||||||
|
<div class="col-md-6">
|
||||||
|
<input id="email" type="email" class="form-control" name="email" value="{{ old('email') }}">
|
||||||
|
|
||||||
|
@if ($errors->has('email'))
|
||||||
|
<span class="help-block">
|
||||||
|
<strong>{{ $errors->first('email') }}</strong>
|
||||||
|
</span>
|
||||||
|
@endif
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group{{ $errors->has('password') ? ' has-error' : '' }}">
|
||||||
|
<label for="password" class="col-md-4 control-label">Password</label>
|
||||||
|
|
||||||
|
<div class="col-md-6">
|
||||||
|
<input id="password" type="password" class="form-control" name="password">
|
||||||
|
|
||||||
|
@if ($errors->has('password'))
|
||||||
|
<span class="help-block">
|
||||||
|
<strong>{{ $errors->first('password') }}</strong>
|
||||||
|
</span>
|
||||||
|
@endif
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<div class="col-md-6 col-md-offset-4">
|
||||||
|
<div class="checkbox">
|
||||||
|
<label>
|
||||||
|
<input type="checkbox" name="remember"> Remember Me
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<div class="col-md-6 col-md-offset-4">
|
||||||
|
<button type="submit" class="btn btn-primary">
|
||||||
|
<i class="fa fa-btn fa-sign-in"></i> Login
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<a class="btn btn-link" href="{{ url('/password/reset') }}">Forgot Your Password?</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
@endsection
|
47
resources/views/auth/passwords/email.blade.php
Normal file
47
resources/views/auth/passwords/email.blade.php
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
@extends('layouts.app')
|
||||||
|
|
||||||
|
<!-- Main Content -->
|
||||||
|
@section('content')
|
||||||
|
<div class="container">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-8 col-md-offset-2">
|
||||||
|
<div class="panel panel-default">
|
||||||
|
<div class="panel-heading">Reset Password</div>
|
||||||
|
<div class="panel-body">
|
||||||
|
@if (session('status'))
|
||||||
|
<div class="alert alert-success">
|
||||||
|
{{ session('status') }}
|
||||||
|
</div>
|
||||||
|
@endif
|
||||||
|
|
||||||
|
<form class="form-horizontal" role="form" method="POST" action="{{ url('/password/email') }}">
|
||||||
|
{{ csrf_field() }}
|
||||||
|
|
||||||
|
<div class="form-group{{ $errors->has('email') ? ' has-error' : '' }}">
|
||||||
|
<label for="email" class="col-md-4 control-label">E-Mail Address</label>
|
||||||
|
|
||||||
|
<div class="col-md-6">
|
||||||
|
<input id="email" type="email" class="form-control" name="email" value="{{ old('email') }}">
|
||||||
|
|
||||||
|
@if ($errors->has('email'))
|
||||||
|
<span class="help-block">
|
||||||
|
<strong>{{ $errors->first('email') }}</strong>
|
||||||
|
</span>
|
||||||
|
@endif
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<div class="col-md-6 col-md-offset-4">
|
||||||
|
<button type="submit" class="btn btn-primary">
|
||||||
|
<i class="fa fa-btn fa-envelope"></i> Send Password Reset Link
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
@endsection
|
70
resources/views/auth/passwords/reset.blade.php
Normal file
70
resources/views/auth/passwords/reset.blade.php
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
@extends('layouts.app')
|
||||||
|
|
||||||
|
@section('content')
|
||||||
|
<div class="container">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-8 col-md-offset-2">
|
||||||
|
<div class="panel panel-default">
|
||||||
|
<div class="panel-heading">Reset Password</div>
|
||||||
|
|
||||||
|
<div class="panel-body">
|
||||||
|
<form class="form-horizontal" role="form" method="POST" action="{{ url('/password/reset') }}">
|
||||||
|
{{ csrf_field() }}
|
||||||
|
|
||||||
|
<input type="hidden" name="token" value="{{ $token }}">
|
||||||
|
|
||||||
|
<div class="form-group{{ $errors->has('email') ? ' has-error' : '' }}">
|
||||||
|
<label for="email" class="col-md-4 control-label">E-Mail Address</label>
|
||||||
|
|
||||||
|
<div class="col-md-6">
|
||||||
|
<input id="email" type="email" class="form-control" name="email" value="{{ $email or old('email') }}">
|
||||||
|
|
||||||
|
@if ($errors->has('email'))
|
||||||
|
<span class="help-block">
|
||||||
|
<strong>{{ $errors->first('email') }}</strong>
|
||||||
|
</span>
|
||||||
|
@endif
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group{{ $errors->has('password') ? ' has-error' : '' }}">
|
||||||
|
<label for="password" class="col-md-4 control-label">Password</label>
|
||||||
|
|
||||||
|
<div class="col-md-6">
|
||||||
|
<input id="password" type="password" class="form-control" name="password">
|
||||||
|
|
||||||
|
@if ($errors->has('password'))
|
||||||
|
<span class="help-block">
|
||||||
|
<strong>{{ $errors->first('password') }}</strong>
|
||||||
|
</span>
|
||||||
|
@endif
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group{{ $errors->has('password_confirmation') ? ' has-error' : '' }}">
|
||||||
|
<label for="password-confirm" class="col-md-4 control-label">Confirm Password</label>
|
||||||
|
<div class="col-md-6">
|
||||||
|
<input id="password-confirm" type="password" class="form-control" name="password_confirmation">
|
||||||
|
|
||||||
|
@if ($errors->has('password_confirmation'))
|
||||||
|
<span class="help-block">
|
||||||
|
<strong>{{ $errors->first('password_confirmation') }}</strong>
|
||||||
|
</span>
|
||||||
|
@endif
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<div class="col-md-6 col-md-offset-4">
|
||||||
|
<button type="submit" class="btn btn-primary">
|
||||||
|
<i class="fa fa-btn fa-refresh"></i> Reset Password
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
@endsection
|
82
resources/views/auth/register.blade.php
Normal file
82
resources/views/auth/register.blade.php
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
@extends('layouts.app')
|
||||||
|
|
||||||
|
@section('content')
|
||||||
|
<div class="container">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-8 col-md-offset-2">
|
||||||
|
<div class="panel panel-default">
|
||||||
|
<div class="panel-heading">Register</div>
|
||||||
|
<div class="panel-body">
|
||||||
|
<form class="form-horizontal" role="form" method="POST" action="{{ url('/register') }}">
|
||||||
|
{{ csrf_field() }}
|
||||||
|
|
||||||
|
<div class="form-group{{ $errors->has('name') ? ' has-error' : '' }}">
|
||||||
|
<label for="name" class="col-md-4 control-label">Name</label>
|
||||||
|
|
||||||
|
<div class="col-md-6">
|
||||||
|
<input id="name" type="text" class="form-control" name="name" value="{{ old('name') }}">
|
||||||
|
|
||||||
|
@if ($errors->has('name'))
|
||||||
|
<span class="help-block">
|
||||||
|
<strong>{{ $errors->first('name') }}</strong>
|
||||||
|
</span>
|
||||||
|
@endif
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group{{ $errors->has('email') ? ' has-error' : '' }}">
|
||||||
|
<label for="email" class="col-md-4 control-label">E-Mail Address</label>
|
||||||
|
|
||||||
|
<div class="col-md-6">
|
||||||
|
<input id="email" type="email" class="form-control" name="email" value="{{ old('email') }}">
|
||||||
|
|
||||||
|
@if ($errors->has('email'))
|
||||||
|
<span class="help-block">
|
||||||
|
<strong>{{ $errors->first('email') }}</strong>
|
||||||
|
</span>
|
||||||
|
@endif
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group{{ $errors->has('password') ? ' has-error' : '' }}">
|
||||||
|
<label for="password" class="col-md-4 control-label">Password</label>
|
||||||
|
|
||||||
|
<div class="col-md-6">
|
||||||
|
<input id="password" type="password" class="form-control" name="password">
|
||||||
|
|
||||||
|
@if ($errors->has('password'))
|
||||||
|
<span class="help-block">
|
||||||
|
<strong>{{ $errors->first('password') }}</strong>
|
||||||
|
</span>
|
||||||
|
@endif
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group{{ $errors->has('password_confirmation') ? ' has-error' : '' }}">
|
||||||
|
<label for="password-confirm" class="col-md-4 control-label">Confirm Password</label>
|
||||||
|
|
||||||
|
<div class="col-md-6">
|
||||||
|
<input id="password-confirm" type="password" class="form-control" name="password_confirmation">
|
||||||
|
|
||||||
|
@if ($errors->has('password_confirmation'))
|
||||||
|
<span class="help-block">
|
||||||
|
<strong>{{ $errors->first('password_confirmation') }}</strong>
|
||||||
|
</span>
|
||||||
|
@endif
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<div class="col-md-6 col-md-offset-4">
|
||||||
|
<button type="submit" class="btn btn-primary">
|
||||||
|
<i class="fa fa-btn fa-user"></i> Register
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
@endsection
|
16
resources/views/common/errors.blade.php
Normal file
16
resources/views/common/errors.blade.php
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
<!-- resources/views/common/errors.blade.php -->
|
||||||
|
|
||||||
|
@if (count($errors) > 0)
|
||||||
|
<!-- Form Error List -->
|
||||||
|
<div class="alert alert-danger">
|
||||||
|
<strong>Whoops! Something went wrong!</strong>
|
||||||
|
|
||||||
|
<br><br>
|
||||||
|
|
||||||
|
<ul>
|
||||||
|
@foreach ($errors->all() as $error)
|
||||||
|
<li>{{ $error }}</li>
|
||||||
|
@endforeach
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
@endif
|
82
resources/views/layouts/app.blade.php
Normal file
82
resources/views/layouts/app.blade.php
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
|
||||||
|
<title>Laravel</title>
|
||||||
|
|
||||||
|
<!-- Fonts -->
|
||||||
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.5.0/css/font-awesome.min.css" integrity="sha384-XdYbMnZ/QjLh6iI4ogqCTaIjrFk87ip+ekIjefZch0Y+PvJ8CDYtEs1ipDmPorQ+" crossorigin="anonymous">
|
||||||
|
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Lato:100,300,400,700">
|
||||||
|
|
||||||
|
<!-- Styles -->
|
||||||
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.6/css/bootstrap.min.css" integrity="sha384-1q8mTJOASx8j1Au+a5WDVnPi2lkFfwwEAa8hDDdjZlpLegxhjVME1fgjWPGmkzs7" crossorigin="anonymous">
|
||||||
|
{{-- <link href="{{ elixir('css/app.css') }}" rel="stylesheet"> --}}
|
||||||
|
|
||||||
|
<style>
|
||||||
|
body {
|
||||||
|
font-family: 'Lato';
|
||||||
|
}
|
||||||
|
|
||||||
|
.fa-btn {
|
||||||
|
margin-right: 6px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body id="app-layout">
|
||||||
|
<nav class="navbar navbar-default navbar-static-top">
|
||||||
|
<div class="container">
|
||||||
|
<div class="navbar-header">
|
||||||
|
|
||||||
|
<!-- Collapsed Hamburger -->
|
||||||
|
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#app-navbar-collapse">
|
||||||
|
<span class="sr-only">Toggle Navigation</span>
|
||||||
|
<span class="icon-bar"></span>
|
||||||
|
<span class="icon-bar"></span>
|
||||||
|
<span class="icon-bar"></span>
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<!-- Branding Image -->
|
||||||
|
<a class="navbar-brand" href="{{ url('/') }}">
|
||||||
|
Laravel
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="collapse navbar-collapse" id="app-navbar-collapse">
|
||||||
|
<!-- Left Side Of Navbar -->
|
||||||
|
<ul class="nav navbar-nav">
|
||||||
|
<li><a href="{{ url('/home') }}">Home</a></li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<!-- Right Side Of Navbar -->
|
||||||
|
<ul class="nav navbar-nav navbar-right">
|
||||||
|
<!-- Authentication Links -->
|
||||||
|
@if (Auth::guest())
|
||||||
|
<li><a href="{{ url('/login') }}">Login</a></li>
|
||||||
|
<li><a href="{{ url('/register') }}">Register</a></li>
|
||||||
|
@else
|
||||||
|
<li class="dropdown">
|
||||||
|
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-expanded="false">
|
||||||
|
{{ Auth::user()->name }} <span class="caret"></span>
|
||||||
|
</a>
|
||||||
|
|
||||||
|
<ul class="dropdown-menu" role="menu">
|
||||||
|
<li><a href="{{ url('/logout') }}"><i class="fa fa-btn fa-sign-out"></i>Logout</a></li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
@endif
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</nav>
|
||||||
|
|
||||||
|
@yield('content')
|
||||||
|
|
||||||
|
<!-- JavaScripts -->
|
||||||
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.3/jquery.min.js" integrity="sha384-I6F5OKECLVtK/BL+8iSLDEHowSAfUo76ZL9+kGAgTRdiByINKJaqTPH/QVNS1VDb" crossorigin="anonymous"></script>
|
||||||
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.6/js/bootstrap.min.js" integrity="sha384-0mSbJDEHialfmuBBQP6A4Qrprq5OVfW37PRR3j5ELqxss1yVqOtnepnHVP9aJ7xS" crossorigin="anonymous"></script>
|
||||||
|
{{-- <script src="{{ elixir('js/app.js') }}"></script> --}}
|
||||||
|
</body>
|
||||||
|
</html>
|
17
resources/views/photo/view.blade.php
Normal file
17
resources/views/photo/view.blade.php
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
@extends('layouts.app')
|
||||||
|
|
||||||
|
@section('content')
|
||||||
|
<div class="container">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-10 col-md-offset-1">
|
||||||
|
<div class="panel panel-default">
|
||||||
|
<div class="panel-heading">Photo <?php echo $photo->id; ?></div>
|
||||||
|
|
||||||
|
<div class="panel-body">
|
||||||
|
<img src="/thumbnail/<?php echo $photo->id; ?>">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
@endsection
|
@ -1,45 +1,17 @@
|
|||||||
<!DOCTYPE html>
|
@extends('layouts.app')
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<title>Laravel</title>
|
|
||||||
|
|
||||||
<link href="https://fonts.googleapis.com/css?family=Lato:100" rel="stylesheet" type="text/css">
|
@section('content')
|
||||||
|
<div class="container">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-10 col-md-offset-1">
|
||||||
|
<div class="panel panel-default">
|
||||||
|
<div class="panel-heading">Welcome</div>
|
||||||
|
|
||||||
<style>
|
<div class="panel-body">
|
||||||
html, body {
|
Your Application's Landing Page.
|
||||||
height: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
body {
|
|
||||||
margin: 0;
|
|
||||||
padding: 0;
|
|
||||||
width: 100%;
|
|
||||||
display: table;
|
|
||||||
font-weight: 100;
|
|
||||||
font-family: 'Lato';
|
|
||||||
}
|
|
||||||
|
|
||||||
.container {
|
|
||||||
text-align: center;
|
|
||||||
display: table-cell;
|
|
||||||
vertical-align: middle;
|
|
||||||
}
|
|
||||||
|
|
||||||
.content {
|
|
||||||
text-align: center;
|
|
||||||
display: inline-block;
|
|
||||||
}
|
|
||||||
|
|
||||||
.title {
|
|
||||||
font-size: 96px;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<div class="container">
|
|
||||||
<div class="content">
|
|
||||||
<div class="title">Laravel 5</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</body>
|
</div>
|
||||||
</html>
|
</div>
|
||||||
|
</div>
|
||||||
|
@endsection
|
||||||
|
Loading…
Reference in New Issue
Block a user