├── .env.example ├── .gitattributes ├── .gitignore ├── app ├── Console │ ├── Commands │ │ └── DeleteExpiredImages.php │ └── Kernel.php ├── Exceptions │ └── Handler.php ├── Http │ ├── Controllers │ │ ├── Admin │ │ │ └── AdminImagesController.php │ │ ├── Auth │ │ │ ├── ActivationController.php │ │ │ ├── ForgotPasswordController.php │ │ │ ├── LoginController.php │ │ │ ├── RegisterController.php │ │ │ └── ResetPasswordController.php │ │ ├── Controller.php │ │ ├── HomeController.php │ │ ├── Image │ │ │ ├── UploadImageController.php │ │ │ └── ViewImagesController.php │ │ └── My │ │ │ └── MyImagesController.php │ ├── Kernel.php │ └── Middleware │ │ ├── AdminMiddleware.php │ │ ├── AjaxMiddleware.php │ │ ├── EncryptCookies.php │ │ ├── RedirectIfAuthenticated.php │ │ ├── TrimStrings.php │ │ └── VerifyCsrfToken.php ├── Jobs │ ├── DeleteImage.php │ └── SendActivationMail.php ├── Mail │ └── ActivateUser.php ├── Models │ ├── Albums.php │ ├── Images.php │ ├── User.php │ └── UserActivation.php ├── Providers │ ├── AppServiceProvider.php │ ├── AuthServiceProvider.php │ ├── BroadcastServiceProvider.php │ ├── EventServiceProvider.php │ └── RouteServiceProvider.php └── Services │ ├── Filer.php │ ├── Guzzler.php │ ├── Imager.php │ └── MetaDataService.php ├── artisan ├── bootstrap ├── app.php ├── autoload.php └── cache │ └── .gitignore ├── composer.json ├── config ├── app.php ├── auth.php ├── broadcasting.php ├── cache.php ├── database.php ├── filesystems.php ├── image.php ├── mail.php ├── queue.php ├── services.php ├── session.php └── view.php ├── database ├── .gitignore ├── factories │ └── ModelFactory.php ├── migrations │ ├── 2014_10_12_000000_create_users_table.php │ ├── 2014_10_12_100000_create_password_resets_table.php │ ├── 2016_06_01_093635_create_images_tables.php │ ├── 2017_03_21_104911_create_user_groups_table.php │ ├── 2017_03_21_111416_create_user_activations_table.php │ ├── 2017_03_21_111636_create_countries_table.php │ ├── 2017_03_22_120019_update_images_table_add_flags.php │ └── 2017_03_22_153420_create_failed_jobs_table.php └── seeds │ └── DatabaseSeeder.php ├── helpers └── helpers.php ├── package.json ├── phpunit.xml ├── public ├── .htaccess ├── css │ └── app.a61a775a0ae2251c98e5.css ├── favicon.ico ├── fonts │ ├── fontawesome-webfont.eot │ ├── fontawesome-webfont.svg │ ├── fontawesome-webfont.ttf │ ├── fontawesome-webfont.woff │ ├── fontawesome-webfont.woff2 │ ├── glyphicons-halflings-regular.eot │ ├── glyphicons-halflings-regular.svg │ ├── glyphicons-halflings-regular.ttf │ ├── glyphicons-halflings-regular.woff │ └── glyphicons-halflings-regular.woff2 ├── images │ ├── continue.gif │ ├── edit.gif │ ├── loading.gif │ ├── not_available-generic.png │ ├── pause.gif │ ├── processing.gif │ ├── retry.gif │ ├── trash.gif │ └── waiting-generic.png ├── index.php ├── js │ └── app.6c2027a726aa56925b75.js ├── mix-manifest.json ├── robots.txt └── web.config ├── readme.md ├── resources ├── assets │ ├── js │ │ ├── app.js │ │ └── init.js │ └── sass │ │ ├── _variables.scss │ │ ├── app.scss │ │ └── imagehost.scss ├── lang │ └── en │ │ ├── auth.php │ │ ├── pagination.php │ │ ├── passwords.php │ │ └── validation.php └── views │ ├── album.blade.php │ ├── auth │ ├── login.blade.php │ ├── passwords │ │ ├── email.blade.php │ │ └── reset.blade.php │ └── register.blade.php │ ├── blocks │ ├── embed.blade.php │ └── fineuploader.blade.php │ ├── emails │ ├── activate-plain.blade.php │ ├── activate.blade.php │ ├── blocks │ │ ├── call-to-action.blade.php │ │ └── style.blade.php │ ├── template-plain.blade.php │ └── template.blade.php │ ├── errors │ ├── 402.blade.php │ ├── 403.blade.php │ ├── 404.blade.php │ ├── 500.blade.php │ ├── 503.blade.php │ └── error.blade.php │ ├── home.blade.php │ ├── image.blade.php │ ├── layouts │ ├── app.blade.php │ └── blocks │ │ ├── footer.blade.php │ │ ├── nav.blade.php │ │ └── notifications.blade.php │ └── my │ ├── albums.blade.php │ ├── images.blade.php │ └── index.blade.php ├── routes ├── api.php ├── channels.php ├── console.php ├── static.php └── web.php ├── server.php ├── storage ├── app │ ├── .gitignore │ └── public │ │ └── .gitignore ├── debugbar │ └── .gitignore ├── framework │ ├── .gitignore │ ├── cache │ │ └── .gitignore │ ├── sessions │ │ └── .gitignore │ ├── testing │ │ └── .gitignore │ └── views │ │ └── .gitignore ├── geoip │ └── .gitignore └── logs │ └── .gitignore ├── tests ├── CreatesApplication.php ├── Feature │ └── ExampleTest.php ├── TestCase.php └── Unit │ └── ExampleTest.php ├── webpack.mix.js └── yarn.lock /.env.example: -------------------------------------------------------------------------------- 1 | APP_ENV=production 2 | APP_KEY= 3 | APP_DEBUG=false 4 | APP_LOG_LEVEL=error 5 | APP_URL='https://example.com' 6 | 7 | APP_STORAGE=local 8 | 9 | SITE_ID=imagez 10 | SITE_NAME='ImageZ' 11 | SITE_CDN='https://example.com' 12 | 13 | DB_CONNECTION=mysql 14 | DB_HOST=127.0.0.1 15 | DB_PORT=3306 16 | DB_DATABASE=database 17 | DB_USERNAME=username 18 | DB_PASSWORD=password 19 | 20 | BROADCAST_DRIVER=log 21 | CACHE_DRIVER=file 22 | SESSION_DRIVER=file 23 | QUEUE_DRIVER=sync 24 | 25 | REDIS_HOST=127.0.0.1 26 | REDIS_PASSWORD=null 27 | REDIS_PORT=6379 28 | 29 | MAIL_DRIVER=mail 30 | MAIL_FROM='noreply@example.com' 31 | 32 | ## AWS SERVER 33 | AWS_KEY= 34 | AWS_SECRET= 35 | AWS_REGION= 36 | AWS_BUCKET= 37 | 38 | API_GOOGLE_RECAPTCHA= 39 | API_GOOGLE_RECAPTCHA_CLIENT= 40 | GOOGLE_ANALYTICS= 41 | 42 | CLOUDFLARE_USERNAME= 43 | CLOUDFLARE_API_KEY= 44 | CLOUDFLARE_ZONE_ID= 45 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | * text=auto 2 | *.css linguist-vendored 3 | *.scss linguist-vendored 4 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /node_modules 2 | /bower_components 3 | /public/storage 4 | /public/hot 5 | /storage/*.key 6 | /vendor 7 | /.idea 8 | Homestead.json 9 | Homestead.yaml 10 | composer.phar 11 | composer.lock 12 | .env 13 | *.map 14 | /maintenance.txt 15 | /yarn-error.log 16 | /.phpstorm.meta.php 17 | /_ide_helper.php 18 | /_ide_helper_models.php 19 | -------------------------------------------------------------------------------- /app/Console/Commands/DeleteExpiredImages.php: -------------------------------------------------------------------------------- 1 | where('expire', '<', carbon())->get(); 25 | if ($albums->count()) { 26 | foreach ($albums as $album) { 27 | if (!empty($album->images)) { 28 | foreach ($album->images as $image) { 29 | $this->info('Deleting - ' . $image->hash); 30 | dispatch(new DeleteImage($image->id)); 31 | } 32 | } 33 | $album->delete(); 34 | } 35 | } 36 | 37 | $images = Images::whereNull('album_id')->where('expire', '<', carbon())->get(); 38 | if ($images->count()) { 39 | foreach ($images as $image) { 40 | $this->info('Deleting - ' . $image->hash); 41 | dispatch(new DeleteImage($image->id)); 42 | } 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /app/Console/Kernel.php: -------------------------------------------------------------------------------- 1 | command('imagez:delete:expired')->everyFiveMinutes(); 29 | } 30 | 31 | /** 32 | * Register the Closure based commands for the application. 33 | * 34 | * @return void 35 | */ 36 | protected function commands() 37 | { 38 | require base_path('routes/console.php'); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /app/Exceptions/Handler.php: -------------------------------------------------------------------------------- 1 | expectsJson()) { 34 | return $this->respondJsonException($request, $exception); 35 | } 36 | 37 | if ($exception instanceof TokenMismatchException) { 38 | return $this->handleTokenMismatch($request, $exception); 39 | } 40 | 41 | return parent::render($request, $exception); 42 | } 43 | 44 | protected function unauthenticated($request, AuthenticationException $exception) 45 | { 46 | if ($request->expectsJson()) { 47 | return response()->json(['error' => 'Unauthenticated.'], 401); 48 | } 49 | 50 | return redirect()->guest(route('login')); 51 | } 52 | 53 | private function respondJsonException($request, $exception) 54 | { 55 | if (method_exists($exception, 'getStatusCode')) { 56 | return response()->json($exception->getMessage(), $exception->getStatusCode()); 57 | } 58 | 59 | if ($exception instanceof AuthorizationException) { 60 | return response()->json('Unauthorized Action', 403); 61 | } 62 | 63 | return response()->json('Internal Server Error', 500); 64 | } 65 | 66 | private function handleTokenMismatch($request, TokenMismatchException $exception) 67 | { 68 | if ($request->expectsJson()) { 69 | return response()->json('Your session has expired. Please try again.', 401); 70 | } 71 | 72 | flash('Your session has expired. Please try again.', 'warning'); 73 | 74 | return redirect()->back()->withInput($request->except('_token')); 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /app/Http/Controllers/Admin/AdminImagesController.php: -------------------------------------------------------------------------------- 1 | filer = app(Filer::class); 27 | $this->imager = app(Imager::class); 28 | } 29 | 30 | public function index() 31 | { 32 | $this->meta->setMeta('Uploads'); 33 | 34 | $data = [ 35 | 'url' => 'admin', 36 | 'albums' => Albums::count(), 37 | 'images' => Images::whereNull('album_id')->count(), 38 | ]; 39 | 40 | return view('my.index', $data); 41 | } 42 | 43 | public function albums() 44 | { 45 | $this->meta->setMeta('Albums'); 46 | 47 | $data = [ 48 | 'url' => 'admin', 49 | 'albums' => Albums::with(['images'])->latest()->paginate(20), 50 | ]; 51 | 52 | return view('my.albums', $data); 53 | } 54 | 55 | public function images() 56 | { 57 | $this->meta->setMeta('Images'); 58 | 59 | $data = [ 60 | 'url' => 'admin', 61 | 'images' => Images::whereNull('album_id')->latest()->paginate(48), 62 | ]; 63 | 64 | return view('my.images', $data); 65 | } 66 | } -------------------------------------------------------------------------------- /app/Http/Controllers/Auth/ActivationController.php: -------------------------------------------------------------------------------- 1 | where('token', $token)->firstOrFail(); 15 | if (!empty($activation->user->id)) { 16 | $activation->user->active = true; 17 | $activation->user->save(); 18 | $activation->delete(); 19 | } 20 | 21 | flash('Email confirmed successfully. You may login now.', 'success'); 22 | } catch (ModelNotFoundException $e) { 23 | flash('Invalid confirmation code or Account already confirmed!', 'error'); 24 | } 25 | 26 | return redirect('login'); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /app/Http/Controllers/Auth/ForgotPasswordController.php: -------------------------------------------------------------------------------- 1 | middleware('guest'); 16 | 17 | parent::__construct(); 18 | 19 | $this->meta->setMeta('Reset Password'); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /app/Http/Controllers/Auth/LoginController.php: -------------------------------------------------------------------------------- 1 | middleware('guest', ['except' => 'logout']); 18 | parent::__construct(); 19 | 20 | $this->meta->setMeta('Login'); 21 | } 22 | 23 | protected function authenticated(Request $request, $user) 24 | { 25 | if (!$user->active) { 26 | flash('This account is not activated, Please check your email for activation link. If you did not receive the activation code, please click "forgot password" link on the login page.', 27 | 'warning'); 28 | 29 | $this->guard()->logout(); 30 | 31 | return redirect('login'); 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /app/Http/Controllers/Auth/RegisterController.php: -------------------------------------------------------------------------------- 1 | middleware('guest'); 26 | 27 | parent::__construct(); 28 | 29 | $this->meta->setMeta('Register'); 30 | } 31 | 32 | public function register(Request $request) 33 | { 34 | $this->validator($request->all())->validate(); 35 | 36 | event(new Registered($user = $this->create($request->all()))); 37 | 38 | return $this->registered($request, $user) 39 | ?: redirect($this->redirectPath()); 40 | } 41 | 42 | protected function registered(Request $request, User $user) 43 | { 44 | $token = hash_hmac('sha256', $user->username . $user->email . str_random(16), config('app.key')); 45 | 46 | UserActivation::create([ 47 | 'user_id' => $user->id, 48 | 'token' => $token, 49 | ]); 50 | 51 | $this->dispatch(new SendActivationMail($user, $token)); 52 | 53 | flash('You have been successfully registered. A confirmation email has been sent to "' . e($user->email) . '" Please confirm your email address, before you login.', 54 | 'info'); 55 | 56 | return redirect('login'); 57 | } 58 | 59 | protected function validator(array $data) 60 | { 61 | return Validator::make($data, [ 62 | 'name' => 'required|max:255', 63 | 'email' => 'required|email|max:255|unique:users', 64 | 'password' => 'required|confirmed|min:8|max:48|password_policy', 65 | ], [ 66 | 'password.password_policy' => 'Choose a stronger password, at least one uppercase letter with number or symbol.', 67 | ]); 68 | } 69 | 70 | protected function create(array $data) 71 | { 72 | return User::create([ 73 | 'group_id' => $this->group_id, 74 | 'name' => $data['name'], 75 | 'email' => $data['email'], 76 | 'password' => bcrypt($data['password']), 77 | ]); 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /app/Http/Controllers/Auth/ResetPasswordController.php: -------------------------------------------------------------------------------- 1 | middleware('guest'); 20 | 21 | parent::__construct(); 22 | 23 | $this->meta->setMeta('Reset Password'); 24 | } 25 | 26 | protected function resetPassword($user, $password) 27 | { 28 | $user->forceFill([ 29 | 'password' => bcrypt($password), 30 | 'remember_token' => Str::random(60), 31 | 'active' => true, 32 | ])->save(); 33 | 34 | UserActivation::where('user_id', $user->id)->delete(); 35 | 36 | $this->guard()->login($user); 37 | } 38 | 39 | protected function rules() 40 | { 41 | return [ 42 | 'token' => 'required', 43 | 'email' => 'required|email', 44 | 'password' => 'required|confirmed|min:6', 45 | ]; 46 | } 47 | 48 | protected function validationErrorMessages() 49 | { 50 | return [ 51 | 'password.password_policy' => 'Choose a stronger password, at least one uppercase letter with number or symbol.', 52 | ]; 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /app/Http/Controllers/Controller.php: -------------------------------------------------------------------------------- 1 | meta = app(MetaDataService::class); 28 | $this->request = app('request'); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /app/Http/Controllers/HomeController.php: -------------------------------------------------------------------------------- 1 | setMeta('ImageZ', 'ImageZ - Free and Secure Image Hosting & Photo Sharing'); 16 | 17 | return view('home'); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /app/Http/Controllers/Image/ViewImagesController.php: -------------------------------------------------------------------------------- 1 | filer = app(Filer::class); 27 | $this->imager = app(Imager::class); 28 | } 29 | 30 | public function album($hash) 31 | { 32 | $album = Albums::where('hash', $hash)->with(['images'])->firstOrFail(); 33 | $images = Images::where('album_id', $album->id)->paginate(20); 34 | $this->meta->setMeta(($album->album_title ? $album->album_title : 'Album ' . $album->hash)); 35 | 36 | return view('album', compact('album', 'images')); 37 | } 38 | 39 | public function image($hash) 40 | { 41 | $extension = str_contains($hash, '.'); 42 | if ($extension) { 43 | return $this->imageFile($hash); 44 | } 45 | 46 | $image = Images::where('hash', $hash)->firstOrFail(); 47 | $this->meta->setMeta(($image->image_title ? $image->image_title : 'Image ' . $image->hash)); 48 | 49 | return view('image', compact('image')); 50 | } 51 | 52 | public function thumbnail($hash) 53 | { 54 | if ($hash) { 55 | return $this->imageFile($hash, true); 56 | } 57 | 58 | abort(404, 'Image Not Found!'); 59 | } 60 | 61 | private function imageFile($filename, $thumb = false) 62 | { 63 | $hash = explode('.', $filename)[0]; 64 | $image = Images::where('hash', $hash)->firstOrFail(); 65 | 66 | $file_content = $this->filer->type('images')->get($filename); 67 | if (empty($file_content)) { 68 | abort(404, 'Image Not Found'); 69 | } 70 | 71 | $image_file = $this->imager->setImage($file_content); 72 | 73 | $response = response($file_content); 74 | if ($thumb) { 75 | $image_file->fit(300, 170); 76 | $response = response($image_file->image->encode()); 77 | } 78 | 79 | $headers = [ 80 | 'Content-Type' => extension_to_mime($image->image_extension), 81 | ]; 82 | 83 | if ($image->private) { 84 | $headers['X-Robots-Tag'] = 'noindex, noarchive'; 85 | } 86 | 87 | if ($image->expire) { 88 | $headers['Cache-Control'] = 'public,max-age=' . (carbon($image->expire)->diffInSeconds()) . ',s-maxage=' . (carbon($image->expire)->diffInSeconds()); 89 | $response->setExpires(carbon($image->expire)); 90 | } else { 91 | $headers['Cache-Control'] = 'public,max-age=' . (3600 * 24 * 30) . ',s-maxage=' . (3600 * 24 * 30); 92 | $response->setExpires(carbon()->addDays(30)); 93 | } 94 | 95 | return $response->withHeaders($headers); 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /app/Http/Controllers/My/MyImagesController.php: -------------------------------------------------------------------------------- 1 | filer = app(Filer::class); 28 | $this->imager = app(Imager::class); 29 | } 30 | 31 | public function index() 32 | { 33 | $this->meta->setMeta('My Uploads'); 34 | 35 | $data = [ 36 | 'url' => 'my', 37 | 'albums' => Albums::where('created_by', Auth::id())->count(), 38 | 'images' => Images::where('created_by', Auth::id())->whereNull('album_id')->count(), 39 | ]; 40 | 41 | return view('my.index', $data); 42 | } 43 | 44 | public function albums() 45 | { 46 | $this->meta->setMeta('My Albums'); 47 | 48 | $data = [ 49 | 'url' => 'my', 50 | 'albums' => Albums::with(['images'])->where('created_by', Auth::id())->latest()->paginate(20), 51 | ]; 52 | 53 | return view('my.albums', $data); 54 | } 55 | 56 | public function images() 57 | { 58 | $this->meta->setMeta('My Images'); 59 | 60 | $data = [ 61 | 'url' => 'my', 62 | 'images' => Images::where('created_by', Auth::id())->whereNull('album_id')->latest()->paginate(48), 63 | ]; 64 | 65 | return view('my.images', $data); 66 | } 67 | } -------------------------------------------------------------------------------- /app/Http/Kernel.php: -------------------------------------------------------------------------------- 1 | [ 30 | \App\Http\Middleware\EncryptCookies::class, 31 | \Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class, 32 | \Illuminate\Session\Middleware\StartSession::class, 33 | // \Illuminate\Session\Middleware\AuthenticateSession::class, 34 | \Illuminate\View\Middleware\ShareErrorsFromSession::class, 35 | \App\Http\Middleware\VerifyCsrfToken::class, 36 | \Illuminate\Routing\Middleware\SubstituteBindings::class, 37 | ], 38 | 39 | 'api' => [ 40 | 'throttle:60,1', 41 | 'bindings', 42 | ], 43 | 44 | 'static' => [], 45 | ]; 46 | 47 | /** 48 | * The application's route middleware. 49 | * 50 | * These middleware may be assigned to groups or used individually. 51 | * 52 | * @var array 53 | */ 54 | protected $routeMiddleware = [ 55 | 'auth' => \Illuminate\Auth\Middleware\Authenticate::class, 56 | 'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class, 57 | 'bindings' => \Illuminate\Routing\Middleware\SubstituteBindings::class, 58 | 'can' => \Illuminate\Auth\Middleware\Authorize::class, 59 | 'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class, 60 | 'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class, 61 | 62 | 'ajax' => \App\Http\Middleware\AjaxMiddleware::class, 63 | 'admin' => \App\Http\Middleware\AdminMiddleware::class, 64 | ]; 65 | } 66 | -------------------------------------------------------------------------------- /app/Http/Middleware/AdminMiddleware.php: -------------------------------------------------------------------------------- 1 | check() && Auth::guard($guard)->user()->group_id == 1) { 21 | return $next($request); 22 | } 23 | 24 | return abort(403, 'Access Denied.'); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /app/Http/Middleware/AjaxMiddleware.php: -------------------------------------------------------------------------------- 1 | environment() != 'local' && !$request->ajax()) { 20 | return response('Not Allowed.', 405); 21 | } 22 | 23 | return $next($request); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /app/Http/Middleware/EncryptCookies.php: -------------------------------------------------------------------------------- 1 | check()) { 21 | return redirect('/'); 22 | } 23 | 24 | return $next($request); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /app/Http/Middleware/TrimStrings.php: -------------------------------------------------------------------------------- 1 | image_id = $image_id; 23 | } 24 | 25 | /** 26 | * Execute the job. 27 | * 28 | * @return void 29 | */ 30 | public function handle() 31 | { 32 | $filer = app(Filer::class); 33 | $guzzler = app(Guzzler::class); 34 | $image = Images::find($this->image_id); 35 | 36 | if ($image) { 37 | try { 38 | $cf = $guzzler->setUrl('https://api.cloudflare.com/client/v4/zones/' . env('CLOUDFLARE_ZONE_ID') . '/purge_cache') 39 | ->request('DELETE', 40 | [ 41 | 'headers' => [ 42 | 'X-Auth-Email' => env('CLOUDFLARE_USERNAME'), 43 | 'X-Auth-Key' => env('CLOUDFLARE_API_KEY'), 44 | 'Content-Type' => 'application/json', 45 | ], 46 | 'json' => [ 47 | 'files' => [ 48 | url('/i/' . $image->hash), 49 | url('/i/' . $image->hash . '.' . $image->image_extension), 50 | url('/t/' . $image->hash . '.' . $image->image_extension), 51 | ], 52 | ] 53 | ]); 54 | } catch (\Exception $e) { 55 | } 56 | 57 | $filer->type('images')->delete($image->hash . '.' . $image->image_extension); 58 | $image->delete(); 59 | } 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /app/Jobs/SendActivationMail.php: -------------------------------------------------------------------------------- 1 | user = $user; 36 | $this->code = $code; 37 | } 38 | 39 | /** 40 | * Execute the job. 41 | * 42 | * @return void 43 | */ 44 | public function handle() 45 | { 46 | if ($this->attempts() > 2) { 47 | $this->delay(min(30 * $this->attempts(), 300)); 48 | } 49 | 50 | Mail::send(new ActivateUser($this->user, $this->code)); 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /app/Mail/ActivateUser.php: -------------------------------------------------------------------------------- 1 | user = $user; 33 | $this->code = $code; 34 | } 35 | 36 | /** 37 | * Build the message. 38 | * 39 | * @return $this 40 | */ 41 | public function build() 42 | { 43 | $this->subject = env('SITE_NAME') . ' - Account Activation Link'; 44 | 45 | return $this->to($this->user->email, $this->user->username) 46 | ->view('emails.activate') 47 | ->text('emails.activate-plain') 48 | ->with([ 49 | 'to' => $this->user->email, 50 | 'subject' => $this->subject, 51 | 'code' => $this->code, 52 | ]); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /app/Models/Albums.php: -------------------------------------------------------------------------------- 1 | hasMany(Images::class, 'album_id', 'id'); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /app/Models/Images.php: -------------------------------------------------------------------------------- 1 | belongsTo(User::class, 'user_id', 'id'); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /app/Providers/AppServiceProvider.php: -------------------------------------------------------------------------------- 1 | app->singleton(\App\Services\MetaDataService::class); 32 | $this->app->singleton(\GeoIp2\Database\Reader::class, function () { 33 | return new \GeoIp2\Database\Reader(storage_path('geoip/geolite2-country.mmdb')); 34 | }); 35 | } 36 | 37 | /** 38 | * Register any application services. 39 | * 40 | * @return void 41 | */ 42 | public function register() 43 | { 44 | if (env('APP_DEBUG') && $this->app->environment() == 'local') { 45 | $this->app->register(\Barryvdh\LaravelIdeHelper\IdeHelperServiceProvider::class); 46 | $this->app->register(\Barryvdh\Debugbar\ServiceProvider::class); 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /app/Providers/AuthServiceProvider.php: -------------------------------------------------------------------------------- 1 | 'App\Policies\ModelPolicy', 16 | ]; 17 | 18 | /** 19 | * Register any authentication / authorization services. 20 | * 21 | * @return void 22 | */ 23 | public function boot() 24 | { 25 | $this->registerPolicies(); 26 | 27 | // 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /app/Providers/BroadcastServiceProvider.php: -------------------------------------------------------------------------------- 1 | [ 16 | 'App\Listeners\EventListener', 17 | ], 18 | ]; 19 | 20 | /** 21 | * Register any events for your application. 22 | * 23 | * @return void 24 | */ 25 | public function boot() 26 | { 27 | parent::boot(); 28 | 29 | // 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /app/Providers/RouteServiceProvider.php: -------------------------------------------------------------------------------- 1 | mapApiRoutes(); 39 | 40 | $this->mapWebRoutes(); 41 | 42 | $this->mapStaticRoutes(); 43 | } 44 | 45 | /** 46 | * Define the "web" routes for the application. 47 | * 48 | * These routes all receive session state, CSRF protection, etc. 49 | * 50 | * @return void 51 | */ 52 | protected function mapWebRoutes() 53 | { 54 | Route::middleware('web') 55 | ->namespace($this->namespace) 56 | ->group(base_path('routes/web.php')); 57 | } 58 | 59 | /** 60 | * Define the "api" routes for the application. 61 | * 62 | * These routes are typically stateless. 63 | * 64 | * @return void 65 | */ 66 | protected function mapApiRoutes() 67 | { 68 | Route::prefix('api') 69 | ->middleware('api') 70 | ->namespace($this->namespace) 71 | ->group(base_path('routes/api.php')); 72 | } 73 | 74 | protected function mapStaticRoutes() 75 | { 76 | Route::middleware('static') 77 | ->namespace($this->namespace) 78 | ->group(base_path('routes/static.php')); 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /app/Services/Filer.php: -------------------------------------------------------------------------------- 1 | manager = app('filesystem'); 24 | 25 | $this->storage_local = $this->manager->disk('local'); 26 | $this->storage_cloud = $this->manager->disk(config('filesystems.cloud')); 27 | $this->storage_tmp = $this->manager->disk('tmp'); 28 | 29 | $this->setStorage(); 30 | } 31 | 32 | /** 33 | * @param string $type 34 | * 35 | * @return self 36 | */ 37 | public function type($type) 38 | { 39 | $this->file_type = $type; 40 | $this->file_path = $type . DIRECTORY_SEPARATOR; 41 | 42 | if ($this->isLocal()) { 43 | $this->full_path = config('filesystems.disks.local.root'); 44 | } 45 | 46 | $this->setStorage(); 47 | 48 | if ($type == 'tmp' || $type == 'temp') { 49 | $this->file_path = ''; 50 | $this->storage = $this->storage_tmp; 51 | $this->full_path = config('filesystems.disks.tmp.root'); 52 | } 53 | 54 | return $this; 55 | } 56 | 57 | /** 58 | * @param string $file 59 | * 60 | * @return string 61 | */ 62 | public function path($file) 63 | { 64 | if ($this->isLocal()) { 65 | return $this->full_path . DIRECTORY_SEPARATOR . $this->file_path . $file; 66 | } 67 | 68 | return $this->file_path . $file; 69 | } 70 | 71 | /** 72 | * @param string $file 73 | * 74 | * @return mixed 75 | */ 76 | public function size($file) 77 | { 78 | if ($this->has($file)) { 79 | return $this->storage->size($this->file_path . $file); 80 | } 81 | 82 | return false; 83 | } 84 | 85 | /** 86 | * @param $file 87 | * 88 | * @return mixed 89 | */ 90 | public function has($file) 91 | { 92 | return $this->storage->exists($this->file_path . $file) ? true : $this->sync($file); 93 | } 94 | 95 | /** 96 | * @param $file 97 | * 98 | * @return mixed 99 | */ 100 | public function get($file) 101 | { 102 | if ($this->has($file)) { 103 | return $this->storage->get($this->file_path . $file); 104 | } 105 | if ($this->sync($file)) { 106 | return $this->storage->get($this->file_path . $file); 107 | } 108 | 109 | return false; 110 | } 111 | 112 | /** 113 | * @param $file 114 | * @param $contents 115 | * 116 | * @return bool 117 | */ 118 | public function put($file, $contents) 119 | { 120 | $saved = $this->storage->put($this->file_path . $file, $contents); 121 | 122 | if ($saved) { 123 | $this->sync($file); 124 | } 125 | 126 | return $saved; 127 | } 128 | 129 | /** 130 | * @param $source 131 | * @param $destination 132 | * 133 | * @return bool 134 | */ 135 | public function copy($source, $destination) 136 | { 137 | $this->storage->copy($source, $this->file_path . $destination); 138 | $this->sync($destination); 139 | } 140 | 141 | /** 142 | * @param $source 143 | * @param $destination 144 | * 145 | * @return bool 146 | */ 147 | public function move($source, $destination) 148 | { 149 | $this->storage->move($source, $this->file_path . $destination); 150 | $this->sync($destination); 151 | } 152 | 153 | /** 154 | * @param $file 155 | * 156 | * @return bool 157 | */ 158 | public function delete($file) 159 | { 160 | if ($this->file_type != 'tmp' && $this->shouldSync()) { 161 | $cloud_delete = false; 162 | if ($this->storage_cloud->exists($this->file_path . $file)) { 163 | $cloud_delete = $this->storage_cloud->delete($this->file_path . $file); 164 | } 165 | $local_delete = false; 166 | if ($this->storage_local->exists($this->file_path . $file)) { 167 | $local_delete = $this->storage_local->delete($this->file_path . $file); 168 | } 169 | 170 | return $cloud_delete || $local_delete; 171 | } 172 | 173 | if ($this->has($file)) { 174 | return $this->storage->delete($this->file_path . $file); 175 | } 176 | 177 | return false; 178 | } 179 | 180 | /** 181 | * @param $file 182 | * 183 | * @return bool 184 | */ 185 | public function sync($file) 186 | { 187 | if ($this->file_type == 'tmp') { 188 | return false; 189 | } 190 | 191 | if ($this->shouldSync()) { 192 | if ($this->storage_local->exists($this->file_path . $file)) { 193 | if ($this->storage_cloud->exists($this->file_path . $file)) { 194 | return true; 195 | } else { 196 | return $this->storage_cloud->put($this->file_path . $file, $this->storage_local->get($this->file_path . $file)); 197 | } 198 | } 199 | if ($this->storage_cloud->exists($this->file_path . $file)) { 200 | if ($this->storage_local->exists($this->file_path . $file)) { 201 | return true; 202 | } else { 203 | return $this->storage_local->put($this->file_path . $file, $this->storage_cloud->get($this->file_path . $file)); 204 | } 205 | } 206 | } 207 | 208 | return false; 209 | } 210 | 211 | protected function isLocal() 212 | { 213 | if ($this->storage_type == 'local' || $this->storage_type == 'localcloud') { 214 | return true; 215 | } 216 | 217 | return false; 218 | } 219 | 220 | protected function shouldSync() 221 | { 222 | if ($this->storage_type == 'localcloud') { 223 | return true; 224 | } 225 | 226 | return false; 227 | } 228 | 229 | private function setStorage() 230 | { 231 | switch (env('APP_STORAGE', 'local')) { 232 | case 'local': 233 | $this->storage = $this->storage_local; 234 | $this->storage_type = 'local'; 235 | break; 236 | case 'localcloud': 237 | $this->storage = $this->storage_local; 238 | $this->storage_type = 'localcloud'; 239 | break; 240 | case 'cloud': 241 | $this->storage = $this->storage_cloud; 242 | $this->storage_type = 'cloud'; 243 | break; 244 | } 245 | } 246 | } 247 | -------------------------------------------------------------------------------- /app/Services/Guzzler.php: -------------------------------------------------------------------------------- 1 | client = new GuzzleClient($config); 63 | } 64 | 65 | /** 66 | * Set URL for HTTP requests. 67 | * 68 | * @param string $url 69 | * 70 | * @return self 71 | */ 72 | public function setUrl($url) 73 | { 74 | $this->url = $url; 75 | 76 | return $this; 77 | } 78 | 79 | /** 80 | * Set basic HTTP authentication. 81 | * 82 | * @param $username string 83 | * @param $password string 84 | * 85 | * @return self 86 | */ 87 | public function setAuth($username, $password) 88 | { 89 | $this->query['auth'] = [$username, $password]; 90 | 91 | return $this; 92 | } 93 | 94 | /** 95 | * Return response headers. 96 | * 97 | * @return array 98 | */ 99 | public function getHeader() 100 | { 101 | return $this->header; 102 | } 103 | 104 | /** 105 | * Return response body. 106 | * 107 | * @return string 108 | */ 109 | public function getBody() 110 | { 111 | return $this->body; 112 | } 113 | 114 | /** 115 | * Cache response keyed by url. 116 | * 117 | * @param $duration 118 | * @param $cache_id 119 | * 120 | * @return self 121 | */ 122 | public function cache($duration, $cache_id = null) 123 | { 124 | $this->cached = $duration; 125 | if ($cache_id) { 126 | $this->cache_id = $this->cache_prefix . $cache_id; 127 | } 128 | 129 | return $this; 130 | } 131 | 132 | /** 133 | * Perform a request. 134 | * 135 | * @param string $method 136 | * @param array $options 137 | * 138 | * @return self 139 | */ 140 | public function request($method, array $options = []) 141 | { 142 | if ($method == 'GET' && $this->getCache()) { 143 | return $this; 144 | } 145 | 146 | $this->response = $this->client->request($method, $this->url, $this->mergeOptions($options)); 147 | $this->status_code = $this->response->getStatusCode(); 148 | $this->header = $this->response->getHeaders(); 149 | $this->body = (string)$this->response->getBody(); 150 | 151 | if ($method == 'GET' && $this->cached) { 152 | $this->putCache(); 153 | } 154 | 155 | return $this; 156 | } 157 | 158 | /** 159 | * Perform get request. 160 | * 161 | * @param array $options 162 | * 163 | * @return self 164 | */ 165 | public function get(array $options = []) 166 | { 167 | return $this->request('GET', $options); 168 | } 169 | 170 | /** 171 | * Perform post request. 172 | * 173 | * @param array $options 174 | * 175 | * @return self 176 | */ 177 | public function post(array $options = []) 178 | { 179 | return $this->request('POST', $options); 180 | } 181 | 182 | /** 183 | * Get the instance as an array. 184 | * 185 | * @return array 186 | */ 187 | public function toArray() 188 | { 189 | if ($this->body && $this->isJson($this->body)) { 190 | return json_decode($this->body, true); 191 | } 192 | 193 | return; 194 | } 195 | 196 | /** 197 | * Convert the object to its JSON representation. 198 | * 199 | * @param int $options 200 | * 201 | * @return string 202 | */ 203 | public function toJson($options = 0) 204 | { 205 | if ($this->body && $this->isJson($this->body)) { 206 | return json_encode(json_decode($this->body)); 207 | } 208 | 209 | return; 210 | } 211 | 212 | /** 213 | * Attach query to the request. 214 | * 215 | * @param array $query 216 | * 217 | * @return self 218 | */ 219 | public function withQuery(array $query) 220 | { 221 | if (!empty($this->query['query'])) { 222 | $this->query['query'] = array_merge($this->query['query'], $query); 223 | 224 | return $this; 225 | } 226 | 227 | $this->query = array_merge($this->query, ['query' => $query]); 228 | 229 | return $this; 230 | } 231 | 232 | /** 233 | * Attach data stream to the request. 234 | * 235 | * @param $body 236 | * 237 | * @return self 238 | */ 239 | public function withBody($body) 240 | { 241 | $this->query = array_merge($this->query, ['body' => $body]); 242 | 243 | return $this; 244 | } 245 | 246 | /** 247 | * Attach form data to the request. 248 | * 249 | * @param array $form ['field_name'=>'value', ...] 250 | * 251 | * @return self 252 | */ 253 | public function withForm(array $form) 254 | { 255 | if (!empty($this->query['form_params'])) { 256 | $this->query['form_params'] = array_merge($this->query['form_params'], $form); 257 | 258 | return $this; 259 | } 260 | 261 | $this->query = array_merge($this->query, ['form_params' => $form]); 262 | 263 | return $this; 264 | } 265 | 266 | /** 267 | * Attach multipart form data to the request. 268 | * 269 | * @param array $form [[name, contents, filename], ...] 270 | * 271 | * @return self 272 | */ 273 | public function withMultiForm(array $form) 274 | { 275 | if (!empty($this->query['multipart'])) { 276 | $this->query['multipart'] = array_merge($this->query['multipart'], $form); 277 | 278 | return $this; 279 | } 280 | 281 | $this->query = array_merge($this->query, ['multipart' => $form]); 282 | 283 | return $this; 284 | } 285 | 286 | /** 287 | * Attach file as multipart form data to the request. 288 | * 289 | * @param array $file [name, contents, filename] 290 | * 291 | * @return self 292 | */ 293 | public function withFile(array $file) 294 | { 295 | return $this->withMultiForm([$file]); 296 | } 297 | 298 | public function getStatusCode() 299 | { 300 | return $this->status_code; 301 | } 302 | 303 | public function unCache() 304 | { 305 | if ($this->cached) { 306 | $this->getCacheId(); 307 | Cache::forget($this->cache_id); 308 | } 309 | } 310 | 311 | private function putCache() 312 | { 313 | if ($this->cached && $this->header && $this->body) { 314 | $this->getCacheId(); 315 | 316 | $data = [ 317 | 'url' => $this->url, 318 | 'query' => $this->query, 319 | 'status_code' => $this->status_code, 320 | 'header' => $this->header, 321 | 'body' => $this->body, 322 | ]; 323 | Cache::put($this->cache_id, $data, $this->cached); 324 | } 325 | } 326 | 327 | private function getCache() 328 | { 329 | if ($this->cached) { 330 | $this->getCacheId(); 331 | 332 | $data = Cache::get($this->cache_id); 333 | if ($data && is_array($data)) { 334 | $this->status_code = $data['status_code']; 335 | $this->query = $data['query']; 336 | $this->header = $data['header']; 337 | $this->body = $data['body']; 338 | 339 | return true; 340 | } 341 | } 342 | 343 | return false; 344 | } 345 | 346 | private function isJson($string) 347 | { 348 | json_decode($string); 349 | 350 | return json_last_error() === JSON_ERROR_NONE; 351 | } 352 | 353 | private function mergeOptions($options) 354 | { 355 | if (!empty($this->query)) { 356 | if (!empty($this->query['multipart']) && !empty($this->query['form_params'])) { 357 | $form_params = $this->query['form_params']; 358 | foreach ($form_params as $key => $value) { 359 | $form_param = [ 360 | 'name' => $key, 361 | 'contents' => $value, 362 | ]; 363 | array_push($this->query['multipart'], $form_param); 364 | } 365 | unset($this->query['form_params']); 366 | } 367 | 368 | return array_merge_recursive($options, $this->query); 369 | } 370 | 371 | return $options; 372 | } 373 | 374 | private function getCacheId() 375 | { 376 | if (empty($this->cache_id)) { 377 | $query_string = ''; 378 | if (!empty($this->query['query'])) { 379 | $query_string = '?' . http_build_query($this->query['query']); 380 | } 381 | $this->cache_id = $this->cache_prefix . md5($this->url . $query_string); 382 | } 383 | } 384 | } 385 | -------------------------------------------------------------------------------- /app/Services/Imager.php: -------------------------------------------------------------------------------- 1 | image->stream($format, $quality); 24 | } 25 | 26 | public function setImage($file, $type = null) 27 | { 28 | $this->type($type); 29 | $this->image = Image::make($file); 30 | 31 | return $this; 32 | } 33 | 34 | public function getColor() 35 | { 36 | return $this->image->resize(1, 1)->pickColor(0, 0, 'hex'); 37 | } 38 | 39 | public function getInfo() 40 | { 41 | return [ 42 | 'mime' => $this->image->mime(), 43 | 'width' => $this->image->width(), 44 | 'height' => $this->image->height(), 45 | 'extension' => $this->image->extension, 46 | 'filename' => $this->image->filename, 47 | 'filesize' => $this->image->filesize(), 48 | ]; 49 | } 50 | 51 | public function crop($width, $height) 52 | { 53 | $this->image->crop($width, $height); 54 | 55 | return $this; 56 | } 57 | 58 | public function resize($width, $height, $aspect_ratio = true, $upscale = true) 59 | { 60 | $this->image->resize($width, $height, function ($constraint) use ($aspect_ratio, $upscale) { 61 | if ($aspect_ratio) { 62 | $constraint->aspectRatio(); 63 | } 64 | if ($upscale) { 65 | $constraint->upsize(); 66 | } 67 | }); 68 | 69 | return $this; 70 | } 71 | 72 | /** 73 | * @param $width 74 | * @param null $height 75 | * @param string $position top-left|top|top-right|left|center|right|bottom-left|bottom|bottom-right 76 | * 77 | * @return $this 78 | */ 79 | public function fit($width, $height = null, $position = 'center') 80 | { 81 | $this->image->fit($width, $height, null, $position); 82 | 83 | return $this; 84 | } 85 | 86 | public function response($format = null, $quality = 90) 87 | { 88 | return $this->image->response($format, $quality); 89 | } 90 | 91 | public function __call($method, $parameters) 92 | { 93 | $this->image = call_user_func_array([$this->image, $method], $parameters); 94 | 95 | return $this; 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /app/Services/MetaDataService.php: -------------------------------------------------------------------------------- 1 | request = $request; 18 | 19 | $this->meta_title = $this->getDefaultTitle(); 20 | $this->setDefaultMeta(); 21 | } 22 | 23 | public function setMeta($page_title = null, $meta_title = null, $description = null, $icon = null) 24 | { 25 | $this->pageTitle($page_title); 26 | $this->metaTitle($meta_title); 27 | if (empty($meta_title)) { 28 | if ($page = $this->request->get('page')) { 29 | if ($page > 1) { 30 | $page_title .= ' (Page ' . $page . ')'; 31 | } 32 | } 33 | 34 | $this->metaTitle($page_title . ' - ' . $this->meta_title); 35 | } 36 | $this->description($description); 37 | $this->icon($icon); 38 | } 39 | 40 | public function setTheme($theme = null, $color = null) 41 | { 42 | } 43 | 44 | public function metaTitle($title = null) 45 | { 46 | if ($title) { 47 | $this->meta_title = $title; 48 | } 49 | 50 | return $this->meta_title; 51 | } 52 | 53 | public function pageTitle($title = null) 54 | { 55 | if ($title) { 56 | $this->page_title = $title; 57 | } 58 | 59 | return $this->page_title; 60 | } 61 | 62 | public function description($description = null) 63 | { 64 | if ($description) { 65 | $this->description = $description; 66 | } 67 | 68 | return $this->description; 69 | } 70 | 71 | public function canonical($url = null) 72 | { 73 | if ($url) { 74 | $this->canonical = $url; 75 | } 76 | 77 | return $this->canonical; 78 | } 79 | 80 | public function icon($icon = null) 81 | { 82 | if ($icon) { 83 | $this->icon = $icon; 84 | } 85 | 86 | return $this->icon; 87 | } 88 | 89 | private function setDefaultMeta() 90 | { 91 | // switch ($this->request->getRequestUri()) { 92 | // case '/login': 93 | // $this->setMeta('Login'); 94 | // break; 95 | // case '/register': 96 | // $this->setMeta('Register'); 97 | // break; 98 | // case '/password/reset': 99 | // $this->setMeta('Reset Password'); 100 | // break; 101 | // } 102 | } 103 | 104 | /** 105 | * @return mixed 106 | */ 107 | private function getDefaultTitle() 108 | { 109 | return env('SITE_NAME') ?: 'Site Name'; 110 | } 111 | } 112 | -------------------------------------------------------------------------------- /artisan: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env php 2 | make(Illuminate\Contracts\Console\Kernel::class); 32 | 33 | $status = $kernel->handle( 34 | $input = new Symfony\Component\Console\Input\ArgvInput, 35 | new Symfony\Component\Console\Output\ConsoleOutput 36 | ); 37 | 38 | /* 39 | |-------------------------------------------------------------------------- 40 | | Shutdown The Application 41 | |-------------------------------------------------------------------------- 42 | | 43 | | Once Artisan has finished running. We will fire off the shutdown events 44 | | so that any final work may be done by the application before we shut 45 | | down the process. This is the last thing to happen to the request. 46 | | 47 | */ 48 | 49 | $kernel->terminate($input, $status); 50 | 51 | exit($status); 52 | -------------------------------------------------------------------------------- /bootstrap/app.php: -------------------------------------------------------------------------------- 1 | singleton( 30 | Illuminate\Contracts\Http\Kernel::class, 31 | App\Http\Kernel::class 32 | ); 33 | 34 | $app->singleton( 35 | Illuminate\Contracts\Console\Kernel::class, 36 | App\Console\Kernel::class 37 | ); 38 | 39 | $app->singleton( 40 | Illuminate\Contracts\Debug\ExceptionHandler::class, 41 | App\Exceptions\Handler::class 42 | ); 43 | 44 | /* 45 | |-------------------------------------------------------------------------- 46 | | Return The Application 47 | |-------------------------------------------------------------------------- 48 | | 49 | | This script returns the application instance. The instance is given to 50 | | the calling script so we can separate the building of the instances 51 | | from the actual running of the application and sending responses. 52 | | 53 | */ 54 | 55 | return $app; 56 | -------------------------------------------------------------------------------- /bootstrap/autoload.php: -------------------------------------------------------------------------------- 1 | =5.6.4", 14 | "laravel/framework": "5.4.*", 15 | "laravel/tinker": "~1.0", 16 | "doctrine/dbal": "2.6.*", 17 | "laravelcollective/html": "5.4.*", 18 | "predis/predis": "1.1.*", 19 | "league/flysystem-aws-s3-v3": "1.0.*", 20 | "guzzlehttp/guzzle": "6.3.*", 21 | "intervention/image": "2.4.*", 22 | "geoip2/geoip2": "2.7.*", 23 | "google/recaptcha": "1.1.*", 24 | "hoa/mime": "3.*" 25 | }, 26 | "require-dev": { 27 | "barryvdh/laravel-debugbar": "^2.4", 28 | "barryvdh/laravel-ide-helper": "^2.4", 29 | "fzaninotto/faker": "~1.4", 30 | "mockery/mockery": "0.9.*", 31 | "phpunit/phpunit": "~5.7" 32 | }, 33 | "autoload": { 34 | "classmap": [ 35 | "database" 36 | ], 37 | "psr-4": { 38 | "App\\": "app/" 39 | }, 40 | "files": [ 41 | "helpers/helpers.php" 42 | ] 43 | }, 44 | "autoload-dev": { 45 | "psr-4": { 46 | "Tests\\": "tests/" 47 | } 48 | }, 49 | "scripts": { 50 | "post-root-package-install": [ 51 | "php -r \"file_exists('.env') || copy('.env.example', '.env');\"" 52 | ], 53 | "post-create-project-cmd": [ 54 | "php artisan key:generate" 55 | ], 56 | "post-install-cmd": [ 57 | "Illuminate\\Foundation\\ComposerScripts::postInstall", 58 | "php artisan optimize" 59 | ], 60 | "post-update-cmd": [ 61 | "Illuminate\\Foundation\\ComposerScripts::postUpdate", 62 | "php artisan optimize", 63 | "wget -qO- http://geolite.maxmind.com/download/geoip/database/GeoLite2-Country.mmdb.gz | gunzip > storage/geoip/geolite2-country.mmdb" 64 | ] 65 | }, 66 | "config": { 67 | "preferred-install": "dist", 68 | "sort-packages": true 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /config/auth.php: -------------------------------------------------------------------------------- 1 | [ 17 | 'guard' => 'web', 18 | 'passwords' => 'users', 19 | ], 20 | 21 | /* 22 | |-------------------------------------------------------------------------- 23 | | Authentication Guards 24 | |-------------------------------------------------------------------------- 25 | | 26 | | Next, you may define every authentication guard for your application. 27 | | Of course, a great default configuration has been defined for you 28 | | here which uses session storage and the Eloquent user provider. 29 | | 30 | | All authentication drivers have a user provider. This defines how the 31 | | users are actually retrieved out of your database or other storage 32 | | mechanisms used by this application to persist your user's data. 33 | | 34 | | Supported: "session", "token" 35 | | 36 | */ 37 | 38 | 'guards' => [ 39 | 'web' => [ 40 | 'driver' => 'session', 41 | 'provider' => 'users', 42 | ], 43 | 44 | 'api' => [ 45 | 'driver' => 'token', 46 | 'provider' => 'users', 47 | ], 48 | ], 49 | 50 | /* 51 | |-------------------------------------------------------------------------- 52 | | User Providers 53 | |-------------------------------------------------------------------------- 54 | | 55 | | All authentication drivers have a user provider. This defines how the 56 | | users are actually retrieved out of your database or other storage 57 | | mechanisms used by this application to persist your user's data. 58 | | 59 | | If you have multiple user tables or models you may configure multiple 60 | | sources which represent each model / table. These sources may then 61 | | be assigned to any extra authentication guards you have defined. 62 | | 63 | | Supported: "database", "eloquent" 64 | | 65 | */ 66 | 67 | 'providers' => [ 68 | 'users' => [ 69 | 'driver' => 'eloquent', 70 | 'model' => App\Models\User::class, 71 | ], 72 | 73 | // 'users' => [ 74 | // 'driver' => 'database', 75 | // 'table' => 'users', 76 | // ], 77 | ], 78 | 79 | /* 80 | |-------------------------------------------------------------------------- 81 | | Resetting Passwords 82 | |-------------------------------------------------------------------------- 83 | | 84 | | You may specify multiple password reset configurations if you have more 85 | | than one user table or model in the application and you want to have 86 | | separate password reset settings based on the specific user types. 87 | | 88 | | The expire time is the number of minutes that the reset token should be 89 | | considered valid. This security feature keeps tokens short-lived so 90 | | they have less time to be guessed. You may change this as needed. 91 | | 92 | */ 93 | 94 | 'passwords' => [ 95 | 'users' => [ 96 | 'provider' => 'users', 97 | 'table' => 'password_resets', 98 | 'expire' => 60, 99 | ], 100 | ], 101 | 102 | ]; 103 | -------------------------------------------------------------------------------- /config/broadcasting.php: -------------------------------------------------------------------------------- 1 | env('BROADCAST_DRIVER', 'null'), 19 | 20 | /* 21 | |-------------------------------------------------------------------------- 22 | | Broadcast Connections 23 | |-------------------------------------------------------------------------- 24 | | 25 | | Here you may define all of the broadcast connections that will be used 26 | | to broadcast events to other systems or over websockets. Samples of 27 | | each available type of connection are provided inside this array. 28 | | 29 | */ 30 | 31 | 'connections' => [ 32 | 33 | 'pusher' => [ 34 | 'driver' => 'pusher', 35 | 'key' => env('PUSHER_APP_KEY'), 36 | 'secret' => env('PUSHER_APP_SECRET'), 37 | 'app_id' => env('PUSHER_APP_ID'), 38 | 'options' => [ 39 | // 40 | ], 41 | ], 42 | 43 | 'redis' => [ 44 | 'driver' => 'redis', 45 | 'connection' => 'default', 46 | ], 47 | 48 | 'log' => [ 49 | 'driver' => 'log', 50 | ], 51 | 52 | 'null' => [ 53 | 'driver' => 'null', 54 | ], 55 | 56 | ], 57 | 58 | ]; 59 | -------------------------------------------------------------------------------- /config/cache.php: -------------------------------------------------------------------------------- 1 | env('CACHE_DRIVER', 'file'), 19 | 20 | /* 21 | |-------------------------------------------------------------------------- 22 | | Cache Stores 23 | |-------------------------------------------------------------------------- 24 | | 25 | | Here you may define all of the cache "stores" for your application as 26 | | well as their drivers. You may even define multiple stores for the 27 | | same cache driver to group types of items stored in your caches. 28 | | 29 | */ 30 | 31 | 'stores' => [ 32 | 33 | 'apc' => [ 34 | 'driver' => 'apc', 35 | ], 36 | 37 | 'array' => [ 38 | 'driver' => 'array', 39 | ], 40 | 41 | 'database' => [ 42 | 'driver' => 'database', 43 | 'table' => 'cache', 44 | 'connection' => null, 45 | ], 46 | 47 | 'file' => [ 48 | 'driver' => 'file', 49 | 'path' => storage_path('framework/cache/data'), 50 | ], 51 | 52 | 'memcached' => [ 53 | 'driver' => 'memcached', 54 | 'persistent_id' => env('MEMCACHED_PERSISTENT_ID'), 55 | 'sasl' => [ 56 | env('MEMCACHED_USERNAME'), 57 | env('MEMCACHED_PASSWORD'), 58 | ], 59 | 'options' => [ 60 | // Memcached::OPT_CONNECT_TIMEOUT => 2000, 61 | ], 62 | 'servers' => [ 63 | [ 64 | 'host' => env('MEMCACHED_HOST', '127.0.0.1'), 65 | 'port' => env('MEMCACHED_PORT', 11211), 66 | 'weight' => 100, 67 | ], 68 | ], 69 | ], 70 | 71 | 'redis' => [ 72 | 'driver' => 'redis', 73 | 'connection' => 'default', 74 | ], 75 | 76 | ], 77 | 78 | /* 79 | |-------------------------------------------------------------------------- 80 | | Cache Key Prefix 81 | |-------------------------------------------------------------------------- 82 | | 83 | | When utilizing a RAM based store such as APC or Memcached, there might 84 | | be other applications utilizing the same cache. So, we'll specify a 85 | | value to get prefixed to all our keys so we can avoid collisions. 86 | | 87 | */ 88 | 89 | 'prefix' => env('SITE_ID', 'laravel'), 90 | 91 | ]; 92 | -------------------------------------------------------------------------------- /config/database.php: -------------------------------------------------------------------------------- 1 | env('DB_CONNECTION', 'mysql'), 17 | 18 | /* 19 | |-------------------------------------------------------------------------- 20 | | Database Connections 21 | |-------------------------------------------------------------------------- 22 | | 23 | | Here are each of the database connections setup for your application. 24 | | Of course, examples of configuring each database platform that is 25 | | supported by Laravel is shown below to make development simple. 26 | | 27 | | 28 | | All database work in Laravel is done through the PHP PDO facilities 29 | | so make sure you have the driver for your particular database of 30 | | choice installed on your machine before you begin development. 31 | | 32 | */ 33 | 34 | 'connections' => [ 35 | 36 | 'sqlite' => [ 37 | 'driver' => 'sqlite', 38 | 'database' => env('DB_DATABASE', database_path('database.sqlite')), 39 | 'prefix' => '', 40 | ], 41 | 42 | 'mysql' => [ 43 | 'driver' => 'mysql', 44 | 'host' => env('DB_HOST', '127.0.0.1'), 45 | 'port' => env('DB_PORT', '3306'), 46 | 'database' => env('DB_DATABASE', 'forge'), 47 | 'username' => env('DB_USERNAME', 'forge'), 48 | 'password' => env('DB_PASSWORD', ''), 49 | 'unix_socket' => env('DB_SOCKET', ''), 50 | 'charset' => 'utf8mb4', 51 | 'collation' => 'utf8mb4_unicode_ci', 52 | 'prefix' => '', 53 | 'strict' => false, 54 | 'engine' => null, 55 | ], 56 | 57 | 'pgsql' => [ 58 | 'driver' => 'pgsql', 59 | 'host' => env('DB_HOST', '127.0.0.1'), 60 | 'port' => env('DB_PORT', '5432'), 61 | 'database' => env('DB_DATABASE', 'forge'), 62 | 'username' => env('DB_USERNAME', 'forge'), 63 | 'password' => env('DB_PASSWORD', ''), 64 | 'charset' => 'utf8', 65 | 'prefix' => '', 66 | 'schema' => 'public', 67 | 'sslmode' => 'prefer', 68 | ], 69 | 70 | ], 71 | 72 | /* 73 | |-------------------------------------------------------------------------- 74 | | Migration Repository Table 75 | |-------------------------------------------------------------------------- 76 | | 77 | | This table keeps track of all the migrations that have already run for 78 | | your application. Using this information, we can determine which of 79 | | the migrations on disk haven't actually been run in the database. 80 | | 81 | */ 82 | 83 | 'migrations' => 'migrations', 84 | 85 | /* 86 | |-------------------------------------------------------------------------- 87 | | Redis Databases 88 | |-------------------------------------------------------------------------- 89 | | 90 | | Redis is an open source, fast, and advanced key-value store that also 91 | | provides a richer set of commands than a typical key-value systems 92 | | such as APC or Memcached. Laravel makes it easy to dig right in. 93 | | 94 | */ 95 | 96 | 'redis' => [ 97 | 98 | 'client' => 'phpredis', 99 | 100 | 'default' => [ 101 | 'host' => env('REDIS_HOST', '127.0.0.1'), 102 | 'password' => env('REDIS_PASSWORD', null), 103 | 'port' => env('REDIS_PORT', 6379), 104 | // 'database' => 0, 105 | 'timeout' => 5, 106 | 'read_timeout' => 60, 107 | ], 108 | 109 | ], 110 | 111 | ]; 112 | -------------------------------------------------------------------------------- /config/filesystems.php: -------------------------------------------------------------------------------- 1 | 'local', 17 | 18 | /* 19 | |-------------------------------------------------------------------------- 20 | | Default Cloud Filesystem Disk 21 | |-------------------------------------------------------------------------- 22 | | 23 | | Many applications store files both locally and in the cloud. For this 24 | | reason, you may specify a default "cloud" driver here. This driver 25 | | will be bound as the Cloud disk implementation in the container. 26 | | 27 | */ 28 | 29 | 'cloud' => 's3', 30 | 31 | /* 32 | |-------------------------------------------------------------------------- 33 | | Filesystem Disks 34 | |-------------------------------------------------------------------------- 35 | | 36 | | Here you may configure as many filesystem "disks" as you wish, and you 37 | | may even configure multiple disks of the same driver. Defaults have 38 | | been setup for each driver as an example of the required options. 39 | | 40 | | Supported Drivers: "local", "ftp", "s3", "rackspace" 41 | | 42 | */ 43 | 44 | 'disks' => [ 45 | 46 | 'local' => [ 47 | 'driver' => 'local', 48 | 'root' => storage_path('app'), 49 | ], 50 | 51 | 'tmp' => [ 52 | 'driver' => 'local', 53 | 'root' => storage_path('app/tmp'), 54 | ], 55 | 56 | 'public' => [ 57 | 'driver' => 'local', 58 | 'root' => storage_path('app/public'), 59 | 'url' => env('APP_URL') . '/storage', 60 | 'visibility' => 'public', 61 | ], 62 | 63 | 's3' => [ 64 | 'driver' => 's3', 65 | 'key' => env('AWS_KEY'), 66 | 'secret' => env('AWS_SECRET'), 67 | 'region' => env('AWS_REGION'), 68 | 'bucket' => env('AWS_BUCKET'), 69 | ], 70 | 71 | ], 72 | 73 | ]; 74 | -------------------------------------------------------------------------------- /config/image.php: -------------------------------------------------------------------------------- 1 | 'gd' 5 | ]; 6 | -------------------------------------------------------------------------------- /config/mail.php: -------------------------------------------------------------------------------- 1 | env('MAIL_DRIVER', 'smtp'), 20 | 21 | /* 22 | |-------------------------------------------------------------------------- 23 | | SMTP Host Address 24 | |-------------------------------------------------------------------------- 25 | | 26 | | Here you may provide the host address of the SMTP server used by your 27 | | applications. A default option is provided that is compatible with 28 | | the Mailgun mail service which will provide reliable deliveries. 29 | | 30 | */ 31 | 32 | 'host' => env('MAIL_HOST', 'smtp.mailgun.org'), 33 | 34 | /* 35 | |-------------------------------------------------------------------------- 36 | | SMTP Host Port 37 | |-------------------------------------------------------------------------- 38 | | 39 | | This is the SMTP port used by your application to deliver e-mails to 40 | | users of the application. Like the host we have set this value to 41 | | stay compatible with the Mailgun e-mail application by default. 42 | | 43 | */ 44 | 45 | 'port' => env('MAIL_PORT', 587), 46 | 47 | /* 48 | |-------------------------------------------------------------------------- 49 | | Global "From" Address 50 | |-------------------------------------------------------------------------- 51 | | 52 | | You may wish for all e-mails sent by your application to be sent from 53 | | the same address. Here, you may specify a name and address that is 54 | | used globally for all e-mails that are sent by your application. 55 | | 56 | */ 57 | 58 | 'from' => [ 59 | 'address' => env('MAIL_FROM', 'hello@example.com'), 60 | 'name' => env('SITE_NAME', 'Example'), 61 | ], 62 | 63 | /* 64 | |-------------------------------------------------------------------------- 65 | | E-Mail Encryption Protocol 66 | |-------------------------------------------------------------------------- 67 | | 68 | | Here you may specify the encryption protocol that should be used when 69 | | the application send e-mail messages. A sensible default using the 70 | | transport layer security protocol should provide great security. 71 | | 72 | */ 73 | 74 | 'encryption' => env('MAIL_ENCRYPTION', 'tls'), 75 | 76 | /* 77 | |-------------------------------------------------------------------------- 78 | | SMTP Server Username 79 | |-------------------------------------------------------------------------- 80 | | 81 | | If your SMTP server requires a username for authentication, you should 82 | | set it here. This will get used to authenticate with your server on 83 | | connection. You may also set the "password" value below this one. 84 | | 85 | */ 86 | 87 | 'username' => env('MAIL_USERNAME'), 88 | 89 | 'password' => env('MAIL_PASSWORD'), 90 | 91 | /* 92 | |-------------------------------------------------------------------------- 93 | | Sendmail System Path 94 | |-------------------------------------------------------------------------- 95 | | 96 | | When using the "sendmail" driver to send e-mails, we will need to know 97 | | the path to where Sendmail lives on this server. A default path has 98 | | been provided here, which will work well on most of your systems. 99 | | 100 | */ 101 | 102 | 'sendmail' => '/usr/sbin/sendmail -bs', 103 | 104 | /* 105 | |-------------------------------------------------------------------------- 106 | | Markdown Mail Settings 107 | |-------------------------------------------------------------------------- 108 | | 109 | | If you are using Markdown based email rendering, you may configure your 110 | | theme and component paths here, allowing you to customize the design 111 | | of the emails. Or, you may simply stick with the Laravel defaults! 112 | | 113 | */ 114 | 115 | 'markdown' => [ 116 | 'theme' => 'default', 117 | 118 | 'paths' => [ 119 | resource_path('views/vendor/mail'), 120 | ], 121 | ], 122 | 123 | ]; 124 | -------------------------------------------------------------------------------- /config/queue.php: -------------------------------------------------------------------------------- 1 | env('QUEUE_DRIVER', 'sync'), 19 | 20 | /* 21 | |-------------------------------------------------------------------------- 22 | | Queue Connections 23 | |-------------------------------------------------------------------------- 24 | | 25 | | Here you may configure the connection information for each server that 26 | | is used by your application. A default configuration has been added 27 | | for each back-end shipped with Laravel. You are free to add more. 28 | | 29 | */ 30 | 31 | 'connections' => [ 32 | 33 | 'sync' => [ 34 | 'driver' => 'sync', 35 | ], 36 | 37 | 'database' => [ 38 | 'driver' => 'database', 39 | 'table' => 'jobs', 40 | 'queue' => 'default', 41 | 'retry_after' => 90, 42 | ], 43 | 44 | 'beanstalkd' => [ 45 | 'driver' => 'beanstalkd', 46 | 'host' => 'localhost', 47 | 'queue' => 'default', 48 | 'retry_after' => 90, 49 | ], 50 | 51 | 'sqs' => [ 52 | 'driver' => 'sqs', 53 | 'key' => 'your-public-key', 54 | 'secret' => 'your-secret-key', 55 | 'prefix' => 'https://sqs.us-east-1.amazonaws.com/your-account-id', 56 | 'queue' => 'your-queue-name', 57 | 'region' => 'us-east-1', 58 | ], 59 | 60 | 'redis' => [ 61 | 'driver' => 'redis', 62 | 'connection' => 'default', 63 | 'queue' => 'default', 64 | 'retry_after' => 90, 65 | ], 66 | 67 | ], 68 | 69 | /* 70 | |-------------------------------------------------------------------------- 71 | | Failed Queue Jobs 72 | |-------------------------------------------------------------------------- 73 | | 74 | | These options configure the behavior of failed queue job logging so you 75 | | can control which database and table are used to store the jobs that 76 | | have failed. You may change them to any database / table you wish. 77 | | 78 | */ 79 | 80 | 'failed' => [ 81 | 'database' => env('DB_CONNECTION', 'mysql'), 82 | 'table' => 'failed_jobs', 83 | ], 84 | 85 | ]; 86 | -------------------------------------------------------------------------------- /config/services.php: -------------------------------------------------------------------------------- 1 | [ 18 | 'domain' => env('MAILGUN_DOMAIN'), 19 | 'secret' => env('MAILGUN_SECRET'), 20 | ], 21 | 22 | 'ses' => [ 23 | 'key' => env('SES_KEY'), 24 | 'secret' => env('SES_SECRET'), 25 | 'region' => 'us-east-1', 26 | ], 27 | 28 | 'sparkpost' => [ 29 | 'secret' => env('SPARKPOST_SECRET'), 30 | ], 31 | 32 | 'stripe' => [ 33 | 'model' => App\Models\User::class, 34 | 'key' => env('STRIPE_KEY'), 35 | 'secret' => env('STRIPE_SECRET'), 36 | ], 37 | 38 | ]; 39 | -------------------------------------------------------------------------------- /config/session.php: -------------------------------------------------------------------------------- 1 | env('SESSION_DRIVER', 'file'), 20 | 21 | /* 22 | |-------------------------------------------------------------------------- 23 | | Session Lifetime 24 | |-------------------------------------------------------------------------- 25 | | 26 | | Here you may specify the number of minutes that you wish the session 27 | | to be allowed to remain idle before it expires. If you want them 28 | | to immediately expire on the browser closing, set that option. 29 | | 30 | */ 31 | 32 | 'lifetime' => 120, 33 | 34 | 'expire_on_close' => false, 35 | 36 | /* 37 | |-------------------------------------------------------------------------- 38 | | Session Encryption 39 | |-------------------------------------------------------------------------- 40 | | 41 | | This option allows you to easily specify that all of your session data 42 | | should be encrypted before it is stored. All encryption will be run 43 | | automatically by Laravel and you can use the Session like normal. 44 | | 45 | */ 46 | 47 | 'encrypt' => false, 48 | 49 | /* 50 | |-------------------------------------------------------------------------- 51 | | Session File Location 52 | |-------------------------------------------------------------------------- 53 | | 54 | | When using the native session driver, we need a location where session 55 | | files may be stored. A default has been set for you but a different 56 | | location may be specified. This is only needed for file sessions. 57 | | 58 | */ 59 | 60 | 'files' => storage_path('framework/sessions'), 61 | 62 | /* 63 | |-------------------------------------------------------------------------- 64 | | Session Database Connection 65 | |-------------------------------------------------------------------------- 66 | | 67 | | When using the "database" or "redis" session drivers, you may specify a 68 | | connection that should be used to manage these sessions. This should 69 | | correspond to a connection in your database configuration options. 70 | | 71 | */ 72 | 73 | 'connection' => null, 74 | 75 | /* 76 | |-------------------------------------------------------------------------- 77 | | Session Database Table 78 | |-------------------------------------------------------------------------- 79 | | 80 | | When using the "database" session driver, you may specify the table we 81 | | should use to manage the sessions. Of course, a sensible default is 82 | | provided for you; however, you are free to change this as needed. 83 | | 84 | */ 85 | 86 | 'table' => 'sessions', 87 | 88 | /* 89 | |-------------------------------------------------------------------------- 90 | | Session Cache Store 91 | |-------------------------------------------------------------------------- 92 | | 93 | | When using the "apc" or "memcached" session drivers, you may specify a 94 | | cache store that should be used for these sessions. This value must 95 | | correspond with one of the application's configured cache stores. 96 | | 97 | */ 98 | 99 | 'store' => null, 100 | 101 | /* 102 | |-------------------------------------------------------------------------- 103 | | Session Sweeping Lottery 104 | |-------------------------------------------------------------------------- 105 | | 106 | | Some session drivers must manually sweep their storage location to get 107 | | rid of old sessions from storage. Here are the chances that it will 108 | | happen on a given request. By default, the odds are 2 out of 100. 109 | | 110 | */ 111 | 112 | 'lottery' => [2, 100], 113 | 114 | /* 115 | |-------------------------------------------------------------------------- 116 | | Session Cookie Name 117 | |-------------------------------------------------------------------------- 118 | | 119 | | Here you may change the name of the cookie used to identify a session 120 | | instance by ID. The name specified here will get used every time a 121 | | new session cookie is created by the framework for every driver. 122 | | 123 | */ 124 | 125 | 'cookie' => 'laravel_session', 126 | 127 | /* 128 | |-------------------------------------------------------------------------- 129 | | Session Cookie Path 130 | |-------------------------------------------------------------------------- 131 | | 132 | | The session cookie path determines the path for which the cookie will 133 | | be regarded as available. Typically, this will be the root path of 134 | | your application but you are free to change this when necessary. 135 | | 136 | */ 137 | 138 | 'path' => '/', 139 | 140 | /* 141 | |-------------------------------------------------------------------------- 142 | | Session Cookie Domain 143 | |-------------------------------------------------------------------------- 144 | | 145 | | Here you may change the domain of the cookie used to identify a session 146 | | in your application. This will determine which domains the cookie is 147 | | available to in your application. A sensible default has been set. 148 | | 149 | */ 150 | 151 | 'domain' => env('SESSION_DOMAIN', null), 152 | 153 | /* 154 | |-------------------------------------------------------------------------- 155 | | HTTPS Only Cookies 156 | |-------------------------------------------------------------------------- 157 | | 158 | | By setting this option to true, session cookies will only be sent back 159 | | to the server if the browser has a HTTPS connection. This will keep 160 | | the cookie from being sent to you if it can not be done securely. 161 | | 162 | */ 163 | 164 | 'secure' => env('SESSION_SECURE_COOKIE', false), 165 | 166 | /* 167 | |-------------------------------------------------------------------------- 168 | | HTTP Access Only 169 | |-------------------------------------------------------------------------- 170 | | 171 | | Setting this value to true will prevent JavaScript from accessing the 172 | | value of the cookie and the cookie will only be accessible through 173 | | the HTTP protocol. You are free to modify this option if needed. 174 | | 175 | */ 176 | 177 | 'http_only' => true, 178 | 179 | ]; 180 | -------------------------------------------------------------------------------- /config/view.php: -------------------------------------------------------------------------------- 1 | [ 17 | resource_path('views'), 18 | ], 19 | 20 | /* 21 | |-------------------------------------------------------------------------- 22 | | Compiled View Path 23 | |-------------------------------------------------------------------------- 24 | | 25 | | This option determines where all the compiled Blade templates will be 26 | | stored for your application. Typically, this is within the storage 27 | | directory. However, as usual, you are free to change this value. 28 | | 29 | */ 30 | 31 | 'compiled' => realpath(storage_path('framework/views')), 32 | 33 | ]; 34 | -------------------------------------------------------------------------------- /database/.gitignore: -------------------------------------------------------------------------------- 1 | *.sqlite 2 | -------------------------------------------------------------------------------- /database/factories/ModelFactory.php: -------------------------------------------------------------------------------- 1 | define(App\User::class, function (Faker\Generator $faker) { 16 | static $password; 17 | 18 | return [ 19 | 'name' => $faker->name, 20 | 'email' => $faker->unique()->safeEmail, 21 | 'password' => $password ?: $password = bcrypt('secret'), 22 | 'remember_token' => str_random(10), 23 | ]; 24 | }); 25 | -------------------------------------------------------------------------------- /database/migrations/2014_10_12_000000_create_users_table.php: -------------------------------------------------------------------------------- 1 | increments('id'); 18 | $table->string('name'); 19 | $table->string('email')->unique(); 20 | $table->string('password'); 21 | $table->rememberToken(); 22 | $table->timestamps(); 23 | }); 24 | 25 | DB::unprepared("INSERT INTO `users` (`id`, `name`, `email`, `password`, `remember_token`, `created_at`, `updated_at`) VALUES (NULL, 'Anonymous', 'anonymous@imagez.to', '', NULL, NULL, NULL);"); 26 | DB::unprepared("INSERT INTO `users` (`id`, `name`, `email`, `password`, `remember_token`, `created_at`, `updated_at`) VALUES (NULL, 'Admin', 'admin@imagez.to', '', NULL, NULL, NULL);"); 27 | } 28 | 29 | /** 30 | * Reverse the migrations. 31 | * 32 | * @return void 33 | */ 34 | public function down() 35 | { 36 | Schema::dropIfExists('users'); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /database/migrations/2014_10_12_100000_create_password_resets_table.php: -------------------------------------------------------------------------------- 1 | string('email')->index(); 18 | $table->string('token'); 19 | $table->timestamp('created_at')->nullable(); 20 | }); 21 | } 22 | 23 | /** 24 | * Reverse the migrations. 25 | * 26 | * @return void 27 | */ 28 | public function down() 29 | { 30 | Schema::dropIfExists('password_resets'); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /database/migrations/2016_06_01_093635_create_images_tables.php: -------------------------------------------------------------------------------- 1 | bigIncrements('id'); 17 | 18 | $table->bigInteger('album_id')->unsigned()->nullable()->default(null); 19 | $table->index('album_id'); 20 | 21 | $table->string('hash')->unique(); 22 | 23 | $table->string('file_hash'); 24 | 25 | $table->string('image_title')->nullable()->default(null); 26 | $table->string('image_description')->nullable()->default(null); 27 | 28 | $table->char('image_extension', '5'); 29 | $table->smallInteger('image_width')->unsigned(); 30 | $table->smallInteger('image_height')->unsigned(); 31 | $table->bigInteger('created_by')->unsigned()->default(1); 32 | $table->index('created_by'); 33 | 34 | $table->timestamps(); 35 | }); 36 | 37 | Schema::create('albums', function (Blueprint $table) { 38 | $table->bigIncrements('id'); 39 | $table->char('hash')->unique(); 40 | $table->string('album_title')->nullable()->default(null); 41 | $table->string('album_description')->nullable()->default(null); 42 | 43 | $table->bigInteger('created_by')->unsigned()->default(1); 44 | $table->index('created_by'); 45 | 46 | $table->timestamps(); 47 | }); 48 | } 49 | 50 | /** 51 | * Reverse the migrations. 52 | * 53 | * @return void 54 | */ 55 | public function down() 56 | { 57 | Schema::drop('albums'); 58 | Schema::drop('images'); 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /database/migrations/2017_03_21_104911_create_user_groups_table.php: -------------------------------------------------------------------------------- 1 | increments('id')->unsigned(); 18 | $table->string('group'); 19 | $table->string('group_code'); 20 | $table->text('description')->nullable(); 21 | }); 22 | 23 | DB::table('user_groups')->delete(); 24 | $user_groups = [ 25 | [ 26 | 'group' => "Super Admin", 27 | 'group_code' => "SU", 28 | ], 29 | [ 30 | 'group' => "Admin", 31 | 'group_code' => "ADMIN", 32 | ], 33 | [ 34 | 'group' => "Moderator", 35 | 'group_code' => "MODERATOR", 36 | ], 37 | [ 38 | 'group' => "Staff", 39 | 'group_code' => "STAFF", 40 | ], 41 | [ 42 | 'group' => "Member", 43 | 'group_code' => "MEMBER", 44 | ], 45 | [ 46 | 'group' => "Banned", 47 | 'group_code' => "BANNED", 48 | ], 49 | [ 50 | 'group' => "Deleted", 51 | 'group_code' => "DELETED", 52 | ], 53 | ]; 54 | DB::table('user_groups')->insert($user_groups); 55 | 56 | Schema::table('users', function (Blueprint $table) { 57 | $table->bigIncrements('id')->change(); 58 | $table->integer('group_id')->unsigned()->after('id'); 59 | $table->boolean('active')->unsigned()->default(false)->after('password'); 60 | }); 61 | 62 | DB::table('users')->update([ 63 | 'active' => true, 64 | 'group_id' => 5, 65 | ]); 66 | 67 | \App\Models\User::where('id', 2)->update(['group_id' => 1]); 68 | 69 | Schema::table('users', function (Blueprint $table) { 70 | $table->foreign('group_id')->references('id')->on('user_groups'); 71 | }); 72 | 73 | Schema::create('user_profile', function (Blueprint $table) { 74 | $table->bigIncrements('id')->unsigned(); 75 | $table->bigInteger('user_id')->unsigned(); 76 | $table->foreign('user_id')->references('id')->on('users')->onDelete('cascade'); 77 | $table->string('name')->nullable(); 78 | $table->mediumText('welcome')->nullable(); 79 | $table->date('birthday')->nullable(); 80 | $table->enum('gender', ['male', 'female', 'other'])->nullable(); 81 | $table->integer('country_id')->nullable(); 82 | $table->string('city')->nullable(); 83 | $table->string('facebook')->nullable(); 84 | $table->string('twitter')->nullable(); 85 | $table->string('signature')->nullable(); 86 | $table->timestamps(); 87 | }); 88 | } 89 | 90 | /** 91 | * Reverse the migrations. 92 | * 93 | * @return void 94 | */ 95 | public function down() 96 | { 97 | Schema::disableForeignKeyConstraints(); 98 | 99 | Schema::table('users', function (Blueprint $table) { 100 | $table->dropForeign(['group_id']); 101 | }); 102 | 103 | Schema::table('users', function (Blueprint $table) { 104 | $table->dropColumn(['group_id', 'active']); 105 | }); 106 | 107 | Schema::enableForeignKeyConstraints(); 108 | 109 | Schema::dropIfExists('user_profile'); 110 | Schema::dropIfExists('user_groups'); 111 | } 112 | } 113 | -------------------------------------------------------------------------------- /database/migrations/2017_03_21_111416_create_user_activations_table.php: -------------------------------------------------------------------------------- 1 | bigIncrements('id'); 18 | $table->bigInteger('user_id')->unsigned()->references('id')->on('users')->onDelete('cascade');; 19 | $table->string('token', 100)->index(); 20 | $table->timestamps(); 21 | }); 22 | } 23 | 24 | /** 25 | * Reverse the migrations. 26 | * 27 | * @return void 28 | */ 29 | public function down() 30 | { 31 | Schema::dropIfExists('user_activations'); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /database/migrations/2017_03_21_111636_create_countries_table.php: -------------------------------------------------------------------------------- 1 | increments('id')->unsigned(); 18 | $table->char('code', 2); 19 | $table->string('country'); 20 | $table->char('continent', 4); 21 | }); 22 | 23 | DB::unprepared("INSERT INTO `countries` (`code`, `country`, `continent`) VALUES 24 | ('AF', 'Afghanistan', 'AS'), 25 | ('AX', 'Aland Islands', 'EU'), 26 | ('AL', 'Albania', 'EU'), 27 | ('DZ', 'Algeria', 'AF'), 28 | ('AS', 'American Samoa', 'OC'), 29 | ('AD', 'Andorra', 'EU'), 30 | ('AO', 'Angola', 'AF'), 31 | ('AI', 'Anguilla', 'NA'), 32 | ('AQ', 'Antarctica', 'AN'), 33 | ('AG', 'Antigua and Barbuda', 'NA'), 34 | ('AR', 'Argentina', 'SA'), 35 | ('AM', 'Armenia', 'AS'), 36 | ('AW', 'Aruba', 'NA'), 37 | ('AU', 'Australia', 'OC'), 38 | ('AT', 'Austria', 'EU'), 39 | ('AZ', 'Azerbaijan', 'AS'), 40 | ('BS', 'Bahamas', 'NA'), 41 | ('BH', 'Bahrain', 'AS'), 42 | ('BD', 'Bangladesh', 'AS'), 43 | ('BB', 'Barbados', 'NA'), 44 | ('BY', 'Belarus', 'EU'), 45 | ('BE', 'Belgium', 'EU'), 46 | ('BZ', 'Belize', 'NA'), 47 | ('BJ', 'Benin', 'AF'), 48 | ('BM', 'Bermuda', 'NA'), 49 | ('BT', 'Bhutan', 'AS'), 50 | ('BO', 'Bolivia', 'SA'), 51 | ('BQ', 'Bonaire, Saint Eustatius and Saba ', 'NA'), 52 | ('BA', 'Bosnia and Herzegovina', 'EU'), 53 | ('BW', 'Botswana', 'AF'), 54 | ('BV', 'Bouvet Island', 'AN'), 55 | ('BR', 'Brazil', 'SA'), 56 | ('IO', 'British Indian Ocean Territory', 'AS'), 57 | ('VG', 'British Virgin Islands', 'NA'), 58 | ('BN', 'Brunei', 'AS'), 59 | ('BG', 'Bulgaria', 'EU'), 60 | ('BF', 'Burkina Faso', 'AF'), 61 | ('BI', 'Burundi', 'AF'), 62 | ('KH', 'Cambodia', 'AS'), 63 | ('CM', 'Cameroon', 'AF'), 64 | ('CA', 'Canada', 'NA'), 65 | ('CV', 'Cape Verde', 'AF'), 66 | ('KY', 'Cayman Islands', 'NA'), 67 | ('CF', 'Central African Republic', 'AF'), 68 | ('TD', 'Chad', 'AF'), 69 | ('CL', 'Chile', 'SA'), 70 | ('CN', 'China', 'AS'), 71 | ('CX', 'Christmas Island', 'AS'), 72 | ('CC', 'Cocos Islands', 'AS'), 73 | ('CO', 'Colombia', 'SA'), 74 | ('KM', 'Comoros', 'AF'), 75 | ('CK', 'Cook Islands', 'OC'), 76 | ('CR', 'Costa Rica', 'NA'), 77 | ('HR', 'Croatia', 'EU'), 78 | ('CU', 'Cuba', 'NA'), 79 | ('CW', 'Curacao', 'NA'), 80 | ('CY', 'Cyprus', 'EU'), 81 | ('CZ', 'Czech Republic', 'EU'), 82 | ('CD', 'Democratic Republic of the Congo', 'AF'), 83 | ('DK', 'Denmark', 'EU'), 84 | ('DJ', 'Djibouti', 'AF'), 85 | ('DM', 'Dominica', 'NA'), 86 | ('DO', 'Dominican Republic', 'NA'), 87 | ('TL', 'East Timor', 'OC'), 88 | ('EC', 'Ecuador', 'SA'), 89 | ('EG', 'Egypt', 'AF'), 90 | ('SV', 'El Salvador', 'NA'), 91 | ('GQ', 'Equatorial Guinea', 'AF'), 92 | ('ER', 'Eritrea', 'AF'), 93 | ('EE', 'Estonia', 'EU'), 94 | ('ET', 'Ethiopia', 'AF'), 95 | ('FK', 'Falkland Islands', 'SA'), 96 | ('FO', 'Faroe Islands', 'EU'), 97 | ('FJ', 'Fiji', 'OC'), 98 | ('FI', 'Finland', 'EU'), 99 | ('FR', 'France', 'EU'), 100 | ('GF', 'French Guiana', 'SA'), 101 | ('PF', 'French Polynesia', 'OC'), 102 | ('TF', 'French Southern Territories', 'AN'), 103 | ('GA', 'Gabon', 'AF'), 104 | ('GM', 'Gambia', 'AF'), 105 | ('GE', 'Georgia', 'AS'), 106 | ('DE', 'Germany', 'EU'), 107 | ('GH', 'Ghana', 'AF'), 108 | ('GI', 'Gibraltar', 'EU'), 109 | ('GR', 'Greece', 'EU'), 110 | ('GL', 'Greenland', 'NA'), 111 | ('GD', 'Grenada', 'NA'), 112 | ('GP', 'Guadeloupe', 'NA'), 113 | ('GU', 'Guam', 'OC'), 114 | ('GT', 'Guatemala', 'NA'), 115 | ('GG', 'Guernsey', 'EU'), 116 | ('GN', 'Guinea', 'AF'), 117 | ('GW', 'GuineaBissau', 'AF'), 118 | ('GY', 'Guyana', 'SA'), 119 | ('HT', 'Haiti', 'NA'), 120 | ('HM', 'Heard Island and McDonald Islands', 'AN'), 121 | ('HN', 'Honduras', 'NA'), 122 | ('HK', 'Hong Kong', 'AS'), 123 | ('HU', 'Hungary', 'EU'), 124 | ('IS', 'Iceland', 'EU'), 125 | ('IN', 'India', 'AS'), 126 | ('ID', 'Indonesia', 'AS'), 127 | ('IR', 'Iran', 'AS'), 128 | ('IQ', 'Iraq', 'AS'), 129 | ('IE', 'Ireland', 'EU'), 130 | ('IM', 'Isle of Man', 'EU'), 131 | ('IL', 'Israel', 'AS'), 132 | ('IT', 'Italy', 'EU'), 133 | ('CI', 'Ivory Coast', 'AF'), 134 | ('JM', 'Jamaica', 'NA'), 135 | ('JP', 'Japan', 'AS'), 136 | ('JE', 'Jersey', 'EU'), 137 | ('JO', 'Jordan', 'AS'), 138 | ('KZ', 'Kazakhstan', 'AS'), 139 | ('KE', 'Kenya', 'AF'), 140 | ('KI', 'Kiribati', 'OC'), 141 | ('XK', 'Kosovo', 'EU'), 142 | ('KW', 'Kuwait', 'AS'), 143 | ('KG', 'Kyrgyzstan', 'AS'), 144 | ('LA', 'Laos', 'AS'), 145 | ('LV', 'Latvia', 'EU'), 146 | ('LB', 'Lebanon', 'AS'), 147 | ('LS', 'Lesotho', 'AF'), 148 | ('LR', 'Liberia', 'AF'), 149 | ('LY', 'Libya', 'AF'), 150 | ('LI', 'Liechtenstein', 'EU'), 151 | ('LT', 'Lithuania', 'EU'), 152 | ('LU', 'Luxembourg', 'EU'), 153 | ('MO', 'Macao', 'AS'), 154 | ('MK', 'Macedonia', 'EU'), 155 | ('MG', 'Madagascar', 'AF'), 156 | ('MW', 'Malawi', 'AF'), 157 | ('MY', 'Malaysia', 'AS'), 158 | ('MV', 'Maldives', 'AS'), 159 | ('ML', 'Mali', 'AF'), 160 | ('MT', 'Malta', 'EU'), 161 | ('MH', 'Marshall Islands', 'OC'), 162 | ('MQ', 'Martinique', 'NA'), 163 | ('MR', 'Mauritania', 'AF'), 164 | ('MU', 'Mauritius', 'AF'), 165 | ('YT', 'Mayotte', 'AF'), 166 | ('MX', 'Mexico', 'NA'), 167 | ('FM', 'Micronesia', 'OC'), 168 | ('MD', 'Moldova', 'EU'), 169 | ('MC', 'Monaco', 'EU'), 170 | ('MN', 'Mongolia', 'AS'), 171 | ('ME', 'Montenegro', 'EU'), 172 | ('MS', 'Montserrat', 'NA'), 173 | ('MA', 'Morocco', 'AF'), 174 | ('MZ', 'Mozambique', 'AF'), 175 | ('MM', 'Myanmar', 'AS'), 176 | ('NA', 'Namibia', 'AF'), 177 | ('NR', 'Nauru', 'OC'), 178 | ('NP', 'Nepal', 'AS'), 179 | ('NL', 'Netherlands', 'EU'), 180 | ('AN', 'Netherlands Antilles', 'NA'), 181 | ('NC', 'New Caledonia', 'OC'), 182 | ('NZ', 'New Zealand', 'OC'), 183 | ('NI', 'Nicaragua', 'NA'), 184 | ('NE', 'Niger', 'AF'), 185 | ('NG', 'Nigeria', 'AF'), 186 | ('NU', 'Niue', 'OC'), 187 | ('NF', 'Norfolk Island', 'OC'), 188 | ('KP', 'North Korea', 'AS'), 189 | ('MP', 'Northern Mariana Islands', 'OC'), 190 | ('NO', 'Norway', 'EU'), 191 | ('OM', 'Oman', 'AS'), 192 | ('PK', 'Pakistan', 'AS'), 193 | ('PW', 'Palau', 'OC'), 194 | ('PS', 'Palestinian Territory', 'AS'), 195 | ('PA', 'Panama', 'NA'), 196 | ('PG', 'Papua New Guinea', 'OC'), 197 | ('PY', 'Paraguay', 'SA'), 198 | ('PE', 'Peru', 'SA'), 199 | ('PH', 'Philippines', 'AS'), 200 | ('PN', 'Pitcairn', 'OC'), 201 | ('PL', 'Poland', 'EU'), 202 | ('PT', 'Portugal', 'EU'), 203 | ('PR', 'Puerto Rico', 'NA'), 204 | ('QA', 'Qatar', 'AS'), 205 | ('CG', 'Republic of the Congo', 'AF'), 206 | ('RE', 'Reunion', 'AF'), 207 | ('RO', 'Romania', 'EU'), 208 | ('RU', 'Russia', 'EU'), 209 | ('RW', 'Rwanda', 'AF'), 210 | ('BL', 'Saint Barthelemy', 'NA'), 211 | ('SH', 'Saint Helena', 'AF'), 212 | ('KN', 'Saint Kitts and Nevis', 'NA'), 213 | ('LC', 'Saint Lucia', 'NA'), 214 | ('MF', 'Saint Martin', 'NA'), 215 | ('PM', 'Saint Pierre and Miquelon', 'NA'), 216 | ('VC', 'Saint Vincent and the Grenadines', 'NA'), 217 | ('WS', 'Samoa', 'OC'), 218 | ('SM', 'San Marino', 'EU'), 219 | ('ST', 'Sao Tome and Principe', 'AF'), 220 | ('SA', 'Saudi Arabia', 'AS'), 221 | ('SN', 'Senegal', 'AF'), 222 | ('RS', 'Serbia', 'EU'), 223 | ('CS', 'Serbia and Montenegro', 'EU'), 224 | ('SC', 'Seychelles', 'AF'), 225 | ('SL', 'Sierra Leone', 'AF'), 226 | ('SG', 'Singapore', 'AS'), 227 | ('SX', 'Sint Maarten', 'NA'), 228 | ('SK', 'Slovakia', 'EU'), 229 | ('SI', 'Slovenia', 'EU'), 230 | ('SB', 'Solomon Islands', 'OC'), 231 | ('SO', 'Somalia', 'AF'), 232 | ('ZA', 'South Africa', 'AF'), 233 | ('GS', 'South Georgia and the South Sandwich Islands', 'AN'), 234 | ('KR', 'South Korea', 'AS'), 235 | ('SS', 'South Sudan', 'AF'), 236 | ('ES', 'Spain', 'EU'), 237 | ('LK', 'Sri Lanka', 'AS'), 238 | ('SD', 'Sudan', 'AF'), 239 | ('SR', 'Suriname', 'SA'), 240 | ('SJ', 'Svalbard and Jan Mayen', 'EU'), 241 | ('SZ', 'Swaziland', 'AF'), 242 | ('SE', 'Sweden', 'EU'), 243 | ('CH', 'Switzerland', 'EU'), 244 | ('SY', 'Syria', 'AS'), 245 | ('TW', 'Taiwan', 'AS'), 246 | ('TJ', 'Tajikistan', 'AS'), 247 | ('TZ', 'Tanzania', 'AF'), 248 | ('TH', 'Thailand', 'AS'), 249 | ('TG', 'Togo', 'AF'), 250 | ('TK', 'Tokelau', 'OC'), 251 | ('TO', 'Tonga', 'OC'), 252 | ('TT', 'Trinidad and Tobago', 'NA'), 253 | ('TN', 'Tunisia', 'AF'), 254 | ('TR', 'Turkey', 'AS'), 255 | ('TM', 'Turkmenistan', 'AS'), 256 | ('TC', 'Turks and Caicos Islands', 'NA'), 257 | ('TV', 'Tuvalu', 'OC'), 258 | ('VI', 'U.S. Virgin Islands', 'NA'), 259 | ('UG', 'Uganda', 'AF'), 260 | ('UA', 'Ukraine', 'EU'), 261 | ('AE', 'United Arab Emirates', 'AS'), 262 | ('GB', 'United Kingdom', 'EU'), 263 | ('US', 'United States', 'NA'), 264 | ('UM', 'United States Minor Outlying Islands', 'OC'), 265 | ('UY', 'Uruguay', 'SA'), 266 | ('UZ', 'Uzbekistan', 'AS'), 267 | ('VU', 'Vanuatu', 'OC'), 268 | ('VA', 'Vatican', 'EU'), 269 | ('VE', 'Venezuela', 'SA'), 270 | ('VN', 'Vietnam', 'AS'), 271 | ('WF', 'Wallis and Futuna', 'OC'), 272 | ('EH', 'Western Sahara', 'AF'), 273 | ('YE', 'Yemen', 'AS'), 274 | ('ZM', 'Zambia', 'AF'), 275 | ('ZW', 'Zimbabwe', 'AF'); 276 | "); 277 | } 278 | 279 | /** 280 | * Reverse the migrations. 281 | * 282 | * @return void 283 | */ 284 | public function down() 285 | { 286 | Schema::dropIfExists('countries'); 287 | } 288 | } 289 | -------------------------------------------------------------------------------- /database/migrations/2017_03_22_120019_update_images_table_add_flags.php: -------------------------------------------------------------------------------- 1 | boolean('adult')->unsigned()->default(false)->after('image_height'); 18 | $table->index('adult'); 19 | $table->boolean('private')->unsigned()->default(true)->after('adult'); 20 | $table->index('private'); 21 | $table->timestamp('expire')->nullable()->after('private'); 22 | $table->text('image_description')->nullable()->change(); 23 | }); 24 | 25 | Schema::table('albums', function (Blueprint $table) { 26 | $table->boolean('adult')->unsigned()->default(false)->after('album_description'); 27 | $table->index('adult'); 28 | $table->boolean('private')->unsigned()->default(true)->after('adult'); 29 | $table->index('private'); 30 | $table->timestamp('expire')->nullable()->after('private'); 31 | $table->text('album_description')->nullable()->change(); 32 | }); 33 | } 34 | 35 | /** 36 | * Reverse the migrations. 37 | * 38 | * @return void 39 | */ 40 | public function down() 41 | { 42 | Schema::table('albums', function (Blueprint $table) { 43 | $table->string('album_description')->nullable()->default(null)->change(); 44 | $table->dropColumn(['adult', 'private', 'expire']); 45 | }); 46 | 47 | Schema::table('images', function (Blueprint $table) { 48 | $table->string('image_description')->nullable()->default(null)->change(); 49 | $table->dropColumn(['adult', 'private', 'expire']); 50 | }); 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /database/migrations/2017_03_22_153420_create_failed_jobs_table.php: -------------------------------------------------------------------------------- 1 | bigIncrements('id'); 18 | $table->text('connection'); 19 | $table->text('queue'); 20 | $table->longText('payload'); 21 | $table->longText('exception'); 22 | $table->timestamp('failed_at')->useCurrent(); 23 | }); 24 | } 25 | 26 | /** 27 | * Reverse the migrations. 28 | * 29 | * @return void 30 | */ 31 | public function down() 32 | { 33 | Schema::dropIfExists('failed_jobs'); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /database/seeds/DatabaseSeeder.php: -------------------------------------------------------------------------------- 1 | call(UsersTableSeeder::class); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /helpers/helpers.php: -------------------------------------------------------------------------------- 1 | flash('flash_message', [ 24 | 'type' => $type, 25 | 'message' => $message, 26 | ]); 27 | } 28 | 29 | function asset_cdn($path) 30 | { 31 | return asset($path); 32 | } 33 | 34 | function human_size($bytes, $decimals = 2) 35 | { 36 | $bytes = (int)$bytes; 37 | $size = [' B', ' KB', ' MB', ' GB', ' TB', ' PB', ' EB', ' ZB', ' YB']; 38 | $factor = (int)floor((strlen($bytes) - 1) / 3); 39 | 40 | return number_format(($bytes / pow(1024, $factor)), $decimals) . @$size[$factor]; 41 | } 42 | 43 | function computer_size($number, $size = null) 44 | { 45 | if (!$size) { 46 | preg_match('/([0-9.]{0,9})\s?([bkmgtpezy]{1,2})/i', $number, $guess_size); 47 | if (isset($guess_size[1]) && isset($guess_size[2])) { 48 | $number = $guess_size[1]; 49 | $size = $guess_size[2]; 50 | } 51 | } 52 | 53 | $size = strtolower($size); 54 | $bytes = (float)$number; 55 | $factors = ['b' => 0, 'kb' => 1, 'mb' => 2, 'gb' => 3, 'tb' => 4, 'pb' => 5, 'eb' => 6, 'zb' => 7, 'yb' => 8]; 56 | 57 | if (isset($factors[$size])) { 58 | return (float)number_format($bytes * pow(1024, $factors[$size]), 2, '.', ''); 59 | } 60 | 61 | return $bytes; 62 | } 63 | 64 | function image_embed_codes($images, $type = null) 65 | { 66 | $embed = ''; 67 | if (!($images instanceof \Illuminate\Support\Collection)) { 68 | $images = [$images]; 69 | } 70 | 71 | foreach ($images as $image) { 72 | $thumb_url = asset_cdn('t/' . $image->hash . '.' . $image->image_extension); 73 | $image_url = asset_cdn('i/' . $image->hash . '.' . $image->image_extension); 74 | if ($type == 'html') { 75 | $embed .= ''; 76 | } elseif ($type == 'bbcode') { 77 | $embed .= '[url=' . $image_url . '][img]' . $thumb_url . '[/img][/url]'; 78 | } else { 79 | $embed .= $image_url . "\n"; 80 | } 81 | } 82 | 83 | $embed = rtrim($embed, "\n"); 84 | 85 | return $embed; 86 | } 87 | 88 | function mime_to_extension($mime) 89 | { 90 | try { 91 | $extension = \Hoa\Mime\Mime::getExtensionsFromMime($mime); 92 | } catch (\Exception $e) { 93 | } 94 | 95 | if (!empty($extension) && is_array($extension)) { 96 | if ($extension[0] == 'jpeg') { 97 | return 'jpg'; 98 | } 99 | 100 | return $extension[0]; 101 | } 102 | 103 | return null; 104 | } 105 | 106 | function extension_to_mime($extension) 107 | { 108 | return \Hoa\Mime\Mime::getMimeFromExtension($extension); 109 | } 110 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "private": true, 3 | "scripts": { 4 | "dev": "cross-env NODE_ENV=development node_modules/webpack/bin/webpack.js --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js", 5 | "watch": "cross-env NODE_ENV=development node_modules/webpack/bin/webpack.js --watch --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js", 6 | "watch-poll": "cross-env NODE_ENV=development node_modules/webpack/bin/webpack.js --watch --watch-poll --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js", 7 | "hot": "cross-env NODE_ENV=development node_modules/webpack-dev-server/bin/webpack-dev-server.js --inline --hot --config=node_modules/laravel-mix/setup/webpack.config.js", 8 | "production": "cross-env NODE_ENV=production node_modules/webpack/bin/webpack.js --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js" 9 | }, 10 | "devDependencies": { 11 | "axios": "^0.15.3", 12 | "bootstrap-sass": "^3.3.7", 13 | "bootswatch": "^3.3.7", 14 | "cross-env": "^3.2.3", 15 | "fine-uploader": "^5.14.1", 16 | "font-awesome": "^4.7.0", 17 | "jquery": "^3.1.1", 18 | "laravel-mix": "^0.8.3", 19 | "lodash": "^4.17.4", 20 | "sweetalert2": "^6.4.4", 21 | "vue": "^2.1.10" 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /phpunit.xml: -------------------------------------------------------------------------------- 1 | 2 | 11 | 12 | 13 | ./tests/Feature 14 | 15 | 16 | 17 | ./tests/Unit 18 | 19 | 20 | 21 | 22 | ./app 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /public/.htaccess: -------------------------------------------------------------------------------- 1 | 2 | 3 | Options -MultiViews 4 | 5 | 6 | RewriteEngine On 7 | 8 | # Redirect Trailing Slashes If Not A Folder... 9 | RewriteCond %{REQUEST_FILENAME} !-d 10 | RewriteRule ^(.*)/$ /$1 [L,R=301] 11 | 12 | # Handle Front Controller... 13 | RewriteCond %{REQUEST_FILENAME} !-d 14 | RewriteCond %{REQUEST_FILENAME} !-f 15 | RewriteRule ^ index.php [L] 16 | 17 | # Handle Authorization Header 18 | RewriteCond %{HTTP:Authorization} . 19 | RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}] 20 | 21 | -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bhutanio/imagehost/341714ad285b224a128602709f924aa1d61d1b86/public/favicon.ico -------------------------------------------------------------------------------- /public/fonts/fontawesome-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bhutanio/imagehost/341714ad285b224a128602709f924aa1d61d1b86/public/fonts/fontawesome-webfont.eot -------------------------------------------------------------------------------- /public/fonts/fontawesome-webfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bhutanio/imagehost/341714ad285b224a128602709f924aa1d61d1b86/public/fonts/fontawesome-webfont.ttf -------------------------------------------------------------------------------- /public/fonts/fontawesome-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bhutanio/imagehost/341714ad285b224a128602709f924aa1d61d1b86/public/fonts/fontawesome-webfont.woff -------------------------------------------------------------------------------- /public/fonts/fontawesome-webfont.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bhutanio/imagehost/341714ad285b224a128602709f924aa1d61d1b86/public/fonts/fontawesome-webfont.woff2 -------------------------------------------------------------------------------- /public/fonts/glyphicons-halflings-regular.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bhutanio/imagehost/341714ad285b224a128602709f924aa1d61d1b86/public/fonts/glyphicons-halflings-regular.eot -------------------------------------------------------------------------------- /public/fonts/glyphicons-halflings-regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bhutanio/imagehost/341714ad285b224a128602709f924aa1d61d1b86/public/fonts/glyphicons-halflings-regular.ttf -------------------------------------------------------------------------------- /public/fonts/glyphicons-halflings-regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bhutanio/imagehost/341714ad285b224a128602709f924aa1d61d1b86/public/fonts/glyphicons-halflings-regular.woff -------------------------------------------------------------------------------- /public/fonts/glyphicons-halflings-regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bhutanio/imagehost/341714ad285b224a128602709f924aa1d61d1b86/public/fonts/glyphicons-halflings-regular.woff2 -------------------------------------------------------------------------------- /public/images/continue.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bhutanio/imagehost/341714ad285b224a128602709f924aa1d61d1b86/public/images/continue.gif -------------------------------------------------------------------------------- /public/images/edit.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bhutanio/imagehost/341714ad285b224a128602709f924aa1d61d1b86/public/images/edit.gif -------------------------------------------------------------------------------- /public/images/loading.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bhutanio/imagehost/341714ad285b224a128602709f924aa1d61d1b86/public/images/loading.gif -------------------------------------------------------------------------------- /public/images/not_available-generic.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bhutanio/imagehost/341714ad285b224a128602709f924aa1d61d1b86/public/images/not_available-generic.png -------------------------------------------------------------------------------- /public/images/pause.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bhutanio/imagehost/341714ad285b224a128602709f924aa1d61d1b86/public/images/pause.gif -------------------------------------------------------------------------------- /public/images/processing.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bhutanio/imagehost/341714ad285b224a128602709f924aa1d61d1b86/public/images/processing.gif -------------------------------------------------------------------------------- /public/images/retry.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bhutanio/imagehost/341714ad285b224a128602709f924aa1d61d1b86/public/images/retry.gif -------------------------------------------------------------------------------- /public/images/trash.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bhutanio/imagehost/341714ad285b224a128602709f924aa1d61d1b86/public/images/trash.gif -------------------------------------------------------------------------------- /public/images/waiting-generic.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bhutanio/imagehost/341714ad285b224a128602709f924aa1d61d1b86/public/images/waiting-generic.png -------------------------------------------------------------------------------- /public/index.php: -------------------------------------------------------------------------------- 1 | 8 | */ 9 | 10 | /* 11 | |-------------------------------------------------------------------------- 12 | | Register The Auto Loader 13 | |-------------------------------------------------------------------------- 14 | | 15 | | Composer provides a convenient, automatically generated class loader for 16 | | our application. We just need to utilize it! We'll simply require it 17 | | into the script here so that we don't have to worry about manual 18 | | loading any of our classes later on. It feels great to relax. 19 | | 20 | */ 21 | 22 | require __DIR__.'/../bootstrap/autoload.php'; 23 | 24 | /* 25 | |-------------------------------------------------------------------------- 26 | | Turn On The Lights 27 | |-------------------------------------------------------------------------- 28 | | 29 | | We need to illuminate PHP development, so let us turn on the lights. 30 | | This bootstraps the framework and gets it ready for use, then it 31 | | will load up this application so that we can run it and send 32 | | the responses back to the browser and delight our users. 33 | | 34 | */ 35 | 36 | $app = require_once __DIR__.'/../bootstrap/app.php'; 37 | 38 | /* 39 | |-------------------------------------------------------------------------- 40 | | Run The Application 41 | |-------------------------------------------------------------------------- 42 | | 43 | | Once we have the application, we can handle the incoming request 44 | | through the kernel, and send the associated response back to 45 | | the client's browser allowing them to enjoy the creative 46 | | and wonderful application we have prepared for them. 47 | | 48 | */ 49 | 50 | $kernel = $app->make(Illuminate\Contracts\Http\Kernel::class); 51 | 52 | $response = $kernel->handle( 53 | $request = Illuminate\Http\Request::capture() 54 | ); 55 | 56 | $response->send(); 57 | 58 | $kernel->terminate($request, $response); 59 | -------------------------------------------------------------------------------- /public/mix-manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "/js/app.js": "/js/app.6c2027a726aa56925b75.js", 3 | "/css/app.css": "/css/app.a61a775a0ae2251c98e5.css" 4 | } -------------------------------------------------------------------------------- /public/robots.txt: -------------------------------------------------------------------------------- 1 | User-agent: * 2 | Disallow: 3 | -------------------------------------------------------------------------------- /public/web.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | ## ImageHost 2 | imagehost is an online Image Hosting platform build using Laravel Framework. 3 | 4 | ### Requirement 5 | - [**PHP**](https://php.net) 5.6.4+ (**7.0** preferred) 6 | - PHP Extensions: openssl, mcrypt and mbstring, phpredis 7 | - Database server: [MySQL](https://www.mysql.com) or [**MariaDB**](https://mariadb.org) 8 | - [Redis](http://redis.io) Server 9 | - [Composer](https://getcomposer.org) 10 | - [Node.js](https://nodejs.org/) with npm 11 | 12 | ### Installation 13 | * clone the repository: `git clone https://github.com/bhutanio/imagehost.git imagehost` 14 | * create a database 15 | * create configuration env file `.env` refer to `.env.example` 16 | * install: `composer install --no-dev` 17 | * setup database tables: `php artisan migrate` 18 | 19 | ### Configuration 20 | #### Image Storage Location 21 | There are 3 locations you can configure using **APP_STORAGE** option in the **.env** file 22 | * ```APP_STORAGE=local``` : store image only in your local storage 23 | * ```APP_STORAGE=localcloud``` : store image in the cloud and keep a local cache 24 | * ```APP_STORAGE=cloud``` : store image only in the cloud 25 | 26 | #### Setup Admin Account 27 | ```bash 28 | php artisan tinker 29 | ``` 30 | ```php 31 | DB::table('users')->where('id', 2)->update(['email'=>'myemail@example.com']); 32 | ``` 33 | Click on **forgot password** link on the **login page** and reset password for your admin user. 34 | 35 | #### Setup Cron Job 36 | ```bash 37 | crontab -e -u www-data 38 | ``` 39 | ```bash 40 | * * * * * php /home/web/imagehost/artisan schedule:run >/dev/null 2>&1 41 | */5 * * * * php /home/web/imagehost/artisan auth:clear-resets >/dev/null 2>&1 42 | ``` 43 | 44 | #### Setup Supervisor 45 | ```bash 46 | nano /etc/supervisor/conf.d/imagehost.conf 47 | ``` 48 | ```bash 49 | [program:imagehost-queue] 50 | process_name=%(program_name)s_%(process_num)02d 51 | command=php /home/web/imagehost/artisan queue:work --sleep=3 --tries=3 52 | autostart=true 53 | autorestart=true 54 | user=www-data 55 | numprocs=2 56 | ``` 57 | 58 | #### Setup Google ReCaptcha 59 | Visit https://www.google.com/recaptcha/admin and register your site 60 | 61 | Get **Site key** and **Secret key**, add them in your .env file 62 | ```$xslt 63 | ... 64 | ## Secret Key 65 | API_GOOGLE_RECAPTCHA='SECRET KEY' 66 | 67 | ## Site Key 68 | API_GOOGLE_RECAPTCHA_CLIENT='SITE KEY' 69 | ... 70 | ``` 71 | 72 | ### License 73 | imagehost is open source software licensed under the [MIT license](http://opensource.org/licenses/MIT). -------------------------------------------------------------------------------- /resources/assets/js/app.js: -------------------------------------------------------------------------------- 1 | // window._ = require('lodash'); 2 | window.$ = window.jQuery = require('jquery'); 3 | // window.axios = require('axios'); 4 | // window.axios.defaults.headers.common = { 5 | // 'X-CSRF-TOKEN': window.Laravel.csrfToken, 6 | // 'X-Requested-With': 'XMLHttpRequest' 7 | // }; 8 | require('bootstrap-sass'); 9 | require("fine-uploader/lib/jquery/traditional"); 10 | 11 | require('./init'); -------------------------------------------------------------------------------- /resources/assets/js/init.js: -------------------------------------------------------------------------------- 1 | if (typeof jQuery === 'undefined') { 2 | throw new Error('Requires jQuery') 3 | } 4 | 5 | import swal from "sweetalert2"; 6 | 7 | const CSRFTOKEN = $('meta[name=_token]').attr('content'); 8 | const BASEURL = $('meta[name=_base_url]').attr('content'); 9 | 10 | +(function ($) { 11 | 'use strict'; 12 | 13 | $(window).on('load resize', function () { 14 | $('#content-area').css('min-height', $(window).height() - ($('header').height() + $('footer').height() + 80) + 'px'); 15 | }); 16 | 17 | // Tooltip 18 | $('[data-toggle="tooltip"]').tooltip({'container': 'body'}); 19 | 20 | // Popover 21 | $('[data-toggle="popover"]').popover(); 22 | 23 | let btn_upload = $('#btn_upload'); 24 | let btn_upload_disable = function () { 25 | if (!btn_upload.prop('disabled')) { 26 | $('input[name="qqfile"]').addClass('disabled').attr('disabled', 'disabled'); 27 | btn_upload.addClass('disabled').attr('disabled', 'disabled').before(' '); 28 | } 29 | }; 30 | let btn_upload_enable = function () { 31 | if (btn_upload.prop('disabled')) { 32 | $('.save-spinner').remove(); 33 | $('input[name="qqfile"]').removeClass('disabled').removeAttribute('disabled'); 34 | btn_upload.removeClass('disabled').removeAttribute('disabled'); 35 | } 36 | }; 37 | 38 | let fuploader = $('#images_fileuploader').fineUploader({ 39 | template: "upload-template", 40 | thumbnails: { 41 | placeholders: { 42 | waitingPath: BASEURL + "/images/waiting-generic.png", 43 | notAvailablePath: BASEURL + "/images/not_available-generic.png" 44 | } 45 | }, 46 | request: { 47 | endpoint: BASEURL + '/image/upload', 48 | params: {_token: CSRFTOKEN} 49 | }, 50 | editFilename: { 51 | enabled: false 52 | }, 53 | retry: { 54 | enableAuto: false 55 | }, 56 | chunking: { 57 | enabled: false 58 | }, 59 | deleteFile: { 60 | enabled: true, 61 | method: "DELETE", 62 | endpoint: BASEURL + '/image/delete', 63 | params: {_token: CSRFTOKEN} 64 | }, 65 | autoUpload: false, 66 | validation: { 67 | allowedExtensions: ['jpeg', 'jpg', 'gif', 'png'], 68 | sizeLimit: 67108864 // 64 Mb 69 | }, 70 | callbacks: { 71 | onError: function (id, name, errorReason) { 72 | let fileEl = fuploader.fineUploader("getItemByFileId", id); 73 | fileEl.find('.upload-error') 74 | .removeClass('hidden') 75 | .find('.error-msg').text('Error: ' + errorReason); 76 | btn_upload_enable(); 77 | }, 78 | 79 | onUpload: function (id, name) { 80 | btn_upload_disable(); 81 | }, 82 | 83 | onComplete: function (id, name, response) { 84 | if (response.success) { 85 | let image_id = response.imageId; 86 | let fileEl = fuploader.fineUploader("getItemByFileId", id), 87 | imageEl = fileEl.find(".uploaded-image"); 88 | 89 | imageEl.html(''); 90 | fuploader.fineUploader("setUuid", id, image_id); 91 | } else { 92 | btn_upload_enable(); 93 | } 94 | }, 95 | 96 | onAllComplete: function (s, f) { 97 | if (s.length > 0) { 98 | $('#form_upload').submit(); 99 | } 100 | } 101 | } 102 | }); 103 | 104 | btn_upload.click(function (e) { 105 | fuploader.fineUploader('uploadStoredFiles'); 106 | e.preventDefault(); 107 | }); 108 | 109 | $('.btn_delete_album, .btn_delete_image').click(function (e) { 110 | let album_id = $(this).data('album-id'); 111 | let image_id = $(this).data('image-id'); 112 | 113 | let delete_type = 'Album'; 114 | let data_id = album_id; 115 | if (!isNaN(image_id)) { 116 | delete_type = 'Image'; 117 | data_id = image_id; 118 | } 119 | 120 | swal({ 121 | title: 'Delete this ' + delete_type + '?', 122 | text: 'Are you sure, you want to delete this ' + delete_type + '?', 123 | type: 'warning', 124 | showCancelButton: true, 125 | confirmButtonText: 'Delete', 126 | cancelButtonText: 'Cancel', 127 | confirmButtonColor: '#d33', 128 | cancelButtonColor: '#3085d6', 129 | allowOutsideClick: false, 130 | showLoaderOnConfirm: true, 131 | preConfirm: function () { 132 | return new Promise(function (resolve, reject) { 133 | return $.ajax({ 134 | url: BASEURL + '/image/delete', 135 | type: 'DELETE', 136 | data: {'_token': CSRFTOKEN, 'action': delete_type, 'id': data_id}, 137 | dataType: 'json' 138 | }).done(function (msg) { 139 | resolve(); 140 | }).fail(function (jqXHR) { 141 | reject('Error: ' + ((jqXHR.responseJSON) ? jqXHR.responseJSON : jqXHR.statusText)); 142 | }); 143 | }); 144 | } 145 | }).then(function () { 146 | swal(delete_type + " Deleted!", delete_type + " deleted successfully.", "success"); 147 | }, function () { 148 | swal.resetDefaults() 149 | }); 150 | 151 | e.preventDefault(); 152 | }) 153 | 154 | })(jQuery); -------------------------------------------------------------------------------- /resources/assets/sass/_variables.scss: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bhutanio/imagehost/341714ad285b224a128602709f924aa1d61d1b86/resources/assets/sass/_variables.scss -------------------------------------------------------------------------------- /resources/assets/sass/app.scss: -------------------------------------------------------------------------------- 1 | // Variables 2 | @import "variables"; 3 | 4 | // Bootstrap 5 | $icon-font-path: "~bootstrap-sass/assets/fonts/bootstrap/"; 6 | @import "node_modules/bootswatch/flatly/variables"; 7 | @import "node_modules/bootstrap-sass/assets/stylesheets/bootstrap"; 8 | @import "node_modules/bootswatch/flatly/bootswatch"; 9 | 10 | // FontAwesome 11 | $fa-font-path: "~font-awesome/fonts"; 12 | @import "node_modules/font-awesome/scss/font-awesome"; 13 | 14 | // Fine-Uploader 15 | @import "node_modules/fine-uploader/fine-uploader/fine-uploader"; 16 | @import "node_modules/fine-uploader/fine-uploader/fine-uploader-new"; 17 | @import "node_modules/fine-uploader/fine-uploader/fine-uploader-gallery"; 18 | 19 | @import "node_modules/sweetalert2/src/sweetalert2"; 20 | 21 | @import "imagehost"; 22 | -------------------------------------------------------------------------------- /resources/assets/sass/imagehost.scss: -------------------------------------------------------------------------------- 1 | @function dynamic-text-color($color) { 2 | @if (lightness( $color ) > 40) { 3 | @return darken($color, 40); 4 | } @else { 5 | @return lighten($color, 40); 6 | } 7 | } 8 | 9 | body { 10 | font-size: ($font-size-base + 1); 11 | font-weight: 300; 12 | margin-top: 80px; 13 | } 14 | 15 | .page-title { 16 | margin-top: 2px; 17 | } 18 | 19 | .block { 20 | display: block; 21 | margin-bottom: 40px; 22 | padding: 20px 40px 60px 40px; 23 | border: 1px solid lighten($well-bg, 5%); 24 | background-color: $well-bg; 25 | :after { 26 | clear: both; 27 | } 28 | } 29 | 30 | .block-box { 31 | text-align: center; 32 | min-height: 200px; 33 | padding: 60px 0; 34 | .glyphicon { 35 | font-size: 48px; 36 | padding: 10px; 37 | } 38 | } 39 | 40 | .block-image { 41 | margin-bottom: 20px; 42 | background-color: lighten($well-bg, 2%); 43 | img { 44 | max-width: 100%; 45 | } 46 | h2, h3 { 47 | margin: 0; 48 | padding: 4px; 49 | font-size: 18px; 50 | } 51 | p { 52 | padding: 4px; 53 | font-size: 14px; 54 | } 55 | } 56 | 57 | .footer-top { 58 | padding: 10px 0; 59 | color: dynamic-text-color($navbar-default-bg); 60 | background: $navbar-default-bg; 61 | } 62 | 63 | .footer-bottom { 64 | margin: 10px 0; 65 | } 66 | 67 | .glyphicon-spin { 68 | -webkit-animation: spin 1000ms infinite linear; 69 | animation: spin 1000ms infinite linear; 70 | } 71 | 72 | @-webkit-keyframes spin { 73 | 0% { 74 | -webkit-transform: rotate(0deg); 75 | transform: rotate(0deg); 76 | } 77 | 100% { 78 | -webkit-transform: rotate(359deg); 79 | transform: rotate(359deg); 80 | } 81 | } 82 | 83 | @keyframes spin { 84 | 0% { 85 | -webkit-transform: rotate(0deg); 86 | transform: rotate(0deg); 87 | } 88 | 100% { 89 | -webkit-transform: rotate(359deg); 90 | transform: rotate(359deg); 91 | } 92 | } 93 | 94 | .shorten-output { 95 | margin-top: 20px; 96 | font-size: $font-size-large; 97 | } 98 | 99 | .panel-heading h1 { 100 | margin: 2px 0; 101 | font-size: $font-size-h3; 102 | } 103 | 104 | .btn_delete_image { 105 | position: absolute; 106 | bottom: 68px; 107 | right: 22px; 108 | @include opacity(0.8); 109 | } -------------------------------------------------------------------------------- /resources/lang/en/auth.php: -------------------------------------------------------------------------------- 1 | 'These credentials do not match our records.', 17 | 'throttle' => 'Too many login attempts. Please try again in :seconds seconds.', 18 | 19 | ]; 20 | -------------------------------------------------------------------------------- /resources/lang/en/pagination.php: -------------------------------------------------------------------------------- 1 | '« Previous', 17 | 'next' => 'Next »', 18 | 19 | ]; 20 | -------------------------------------------------------------------------------- /resources/lang/en/passwords.php: -------------------------------------------------------------------------------- 1 | 'Passwords must be at least six characters and match the confirmation.', 17 | 'reset' => 'Your password has been reset!', 18 | 'sent' => 'We have e-mailed your password reset link!', 19 | 'token' => 'This password reset token is invalid.', 20 | 'user' => "We can't find a user with that e-mail address.", 21 | 22 | ]; 23 | -------------------------------------------------------------------------------- /resources/lang/en/validation.php: -------------------------------------------------------------------------------- 1 | 'The :attribute must be accepted.', 17 | 'active_url' => 'The :attribute is not a valid URL.', 18 | 'after' => 'The :attribute must be a date after :date.', 19 | 'after_or_equal' => 'The :attribute must be a date after or equal to :date.', 20 | 'alpha' => 'The :attribute may only contain letters.', 21 | 'alpha_dash' => 'The :attribute may only contain letters, numbers, and dashes.', 22 | 'alpha_num' => 'The :attribute may only contain letters and numbers.', 23 | 'array' => 'The :attribute must be an array.', 24 | 'before' => 'The :attribute must be a date before :date.', 25 | 'before_or_equal' => 'The :attribute must be a date before or equal to :date.', 26 | 'between' => [ 27 | 'numeric' => 'The :attribute must be between :min and :max.', 28 | 'file' => 'The :attribute must be between :min and :max kilobytes.', 29 | 'string' => 'The :attribute must be between :min and :max characters.', 30 | 'array' => 'The :attribute must have between :min and :max items.', 31 | ], 32 | 'boolean' => 'The :attribute field must be true or false.', 33 | 'confirmed' => 'The :attribute confirmation does not match.', 34 | 'date' => 'The :attribute is not a valid date.', 35 | 'date_format' => 'The :attribute does not match the format :format.', 36 | 'different' => 'The :attribute and :other must be different.', 37 | 'digits' => 'The :attribute must be :digits digits.', 38 | 'digits_between' => 'The :attribute must be between :min and :max digits.', 39 | 'dimensions' => 'The :attribute has invalid image dimensions.', 40 | 'distinct' => 'The :attribute field has a duplicate value.', 41 | 'email' => 'The :attribute must be a valid email address.', 42 | 'exists' => 'The selected :attribute is invalid.', 43 | 'file' => 'The :attribute must be a file.', 44 | 'filled' => 'The :attribute field must have a value.', 45 | 'image' => 'The :attribute must be an image.', 46 | 'in' => 'The selected :attribute is invalid.', 47 | 'in_array' => 'The :attribute field does not exist in :other.', 48 | 'integer' => 'The :attribute must be an integer.', 49 | 'ip' => 'The :attribute must be a valid IP address.', 50 | 'json' => 'The :attribute must be a valid JSON string.', 51 | 'max' => [ 52 | 'numeric' => 'The :attribute may not be greater than :max.', 53 | 'file' => 'The :attribute may not be greater than :max kilobytes.', 54 | 'string' => 'The :attribute may not be greater than :max characters.', 55 | 'array' => 'The :attribute may not have more than :max items.', 56 | ], 57 | 'mimes' => 'The :attribute must be a file of type: :values.', 58 | 'mimetypes' => 'The :attribute must be a file of type: :values.', 59 | 'min' => [ 60 | 'numeric' => 'The :attribute must be at least :min.', 61 | 'file' => 'The :attribute must be at least :min kilobytes.', 62 | 'string' => 'The :attribute must be at least :min characters.', 63 | 'array' => 'The :attribute must have at least :min items.', 64 | ], 65 | 'not_in' => 'The selected :attribute is invalid.', 66 | 'numeric' => 'The :attribute must be a number.', 67 | 'present' => 'The :attribute field must be present.', 68 | 'regex' => 'The :attribute format is invalid.', 69 | 'required' => 'The :attribute field is required.', 70 | 'required_if' => 'The :attribute field is required when :other is :value.', 71 | 'required_unless' => 'The :attribute field is required unless :other is in :values.', 72 | 'required_with' => 'The :attribute field is required when :values is present.', 73 | 'required_with_all' => 'The :attribute field is required when :values is present.', 74 | 'required_without' => 'The :attribute field is required when :values is not present.', 75 | 'required_without_all' => 'The :attribute field is required when none of :values are present.', 76 | 'same' => 'The :attribute and :other must match.', 77 | 'size' => [ 78 | 'numeric' => 'The :attribute must be :size.', 79 | 'file' => 'The :attribute must be :size kilobytes.', 80 | 'string' => 'The :attribute must be :size characters.', 81 | 'array' => 'The :attribute must contain :size items.', 82 | ], 83 | 'string' => 'The :attribute must be a string.', 84 | 'timezone' => 'The :attribute must be a valid zone.', 85 | 'unique' => 'The :attribute has already been taken.', 86 | 'uploaded' => 'The :attribute failed to upload.', 87 | 'url' => 'The :attribute format is invalid.', 88 | 89 | /* 90 | |-------------------------------------------------------------------------- 91 | | Custom Validation Language Lines 92 | |-------------------------------------------------------------------------- 93 | | 94 | | Here you may specify custom validation messages for attributes using the 95 | | convention "attribute.rule" to name the lines. This makes it quick to 96 | | specify a specific custom language line for a given attribute rule. 97 | | 98 | */ 99 | 100 | 'custom' => [ 101 | 'attribute-name' => [ 102 | 'rule-name' => 'custom-message', 103 | ], 104 | ], 105 | 106 | /* 107 | |-------------------------------------------------------------------------- 108 | | Custom Validation Attributes 109 | |-------------------------------------------------------------------------- 110 | | 111 | | The following language lines are used to swap attribute place-holders 112 | | with something more reader friendly such as E-Mail Address instead 113 | | of "email". This simply helps us make messages a little cleaner. 114 | | 115 | */ 116 | 117 | 'attributes' => [], 118 | 119 | ]; 120 | -------------------------------------------------------------------------------- /resources/views/album.blade.php: -------------------------------------------------------------------------------- 1 | @extends('layouts.app') 2 | 3 | @section('header_css') 4 | 5 | 6 | 7 | 8 | 9 | @endsection 10 | 11 | @section('content') 12 |

{{ meta()->pageTitle() }}

13 | @if(!empty($album->album_description)) 14 |

{{ $album->album_description }}

15 | @endif 16 |
17 |
18 | 19 |
20 |
21 | 22 | @foreach($images as $image) 23 |
24 | @if(!empty($image->image_title)) 25 |

{{ $image->image_title }}

26 | @endif 27 | 28 | @if(!empty($image->image_description)) 29 |

{{ $image->image_description }}

30 | @endif 31 |
32 | @endforeach 33 |
34 |
{!! $images->render() !!}
35 | 36 | @include('blocks.embed', ['image' => $album->images]) 37 | @endsection 38 | -------------------------------------------------------------------------------- /resources/views/auth/login.blade.php: -------------------------------------------------------------------------------- 1 | @extends('layouts.app') 2 | 3 | @section('content') 4 |
5 |
6 |
7 |
8 |

Login

9 |
10 |
11 | {{ csrf_field() }} 12 | 13 |
14 | 15 | 16 |
17 | 18 | 19 | @if ($errors->has('email')) 20 | 21 | {{ $errors->first('email') }} 22 | 23 | @endif 24 |
25 |
26 | 27 |
28 | 29 | 30 |
31 | 32 | 33 | @if ($errors->has('password')) 34 | 35 | {{ $errors->first('password') }} 36 | 37 | @endif 38 |
39 |
40 | 41 |
42 |
43 |
44 | 47 |
48 |
49 |
50 | 51 |
52 |
53 | 56 | 57 | 58 | Forgot Your Password? 59 | 60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 | @endsection 69 | -------------------------------------------------------------------------------- /resources/views/auth/passwords/email.blade.php: -------------------------------------------------------------------------------- 1 | @extends('layouts.app') 2 | 3 | @section('content') 4 |
5 |
6 |
7 |
8 |

Reset Password

9 |
10 | @if (session('status')) 11 |
12 | {{ session('status') }} 13 |
14 | @endif 15 | 16 |
17 | {{ csrf_field() }} 18 | 19 |
20 | 21 | 22 |
23 | 24 | 25 | @if ($errors->has('email')) 26 | 27 | {{ $errors->first('email') }} 28 | 29 | @endif 30 |
31 |
32 | 33 |
34 |
35 | 38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 | @endsection 47 | -------------------------------------------------------------------------------- /resources/views/auth/passwords/reset.blade.php: -------------------------------------------------------------------------------- 1 | @extends('layouts.app') 2 | 3 | @section('content') 4 |
5 |
6 |
7 |
8 |
Reset Password
9 | 10 |
11 | @if (session('status')) 12 |
13 | {{ session('status') }} 14 |
15 | @endif 16 | 17 |
18 | {{ csrf_field() }} 19 | 20 | 21 | 22 |
23 | 24 | 25 |
26 | 27 | 28 | @if ($errors->has('email')) 29 | 30 | {{ $errors->first('email') }} 31 | 32 | @endif 33 |
34 |
35 | 36 |
37 | 38 | 39 |
40 | 41 | 42 | @if ($errors->has('password')) 43 | 44 | {{ $errors->first('password') }} 45 | 46 | @endif 47 |
48 |
49 | 50 |
51 | 52 |
53 | 54 | 55 | @if ($errors->has('password_confirmation')) 56 | 57 | {{ $errors->first('password_confirmation') }} 58 | 59 | @endif 60 |
61 |
62 | 63 |
64 |
65 | 68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 | @endsection 77 | -------------------------------------------------------------------------------- /resources/views/auth/register.blade.php: -------------------------------------------------------------------------------- 1 | @extends('layouts.app') 2 | 3 | @section('content') 4 |
5 |
6 |
7 |
8 |

Register

9 |
10 |
11 | {{ csrf_field() }} 12 | 13 |
14 | 15 | 16 |
17 | 18 | 19 | @if ($errors->has('name')) 20 | 21 | {{ $errors->first('name') }} 22 | 23 | @endif 24 |
25 |
26 | 27 |
28 | 29 | 30 |
31 | 32 | 33 | @if ($errors->has('email')) 34 | 35 | {{ $errors->first('email') }} 36 | 37 | @endif 38 |
39 |
40 | 41 |
42 | 43 | 44 |
45 | 46 | 47 | @if ($errors->has('password')) 48 | 49 | {{ $errors->first('password') }} 50 | 51 | @endif 52 |
53 |
54 | 55 |
56 | 57 | 58 |
59 | 60 |
61 |
62 | 63 |
64 |
65 | 68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 | @endsection 77 | -------------------------------------------------------------------------------- /resources/views/blocks/embed.blade.php: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /resources/views/blocks/fineuploader.blade.php: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /resources/views/emails/activate-plain.blade.php: -------------------------------------------------------------------------------- 1 | @extends('emails.template-plain') 2 | 3 | @section('content') 4 | Hi, 5 | Thank you for signing up on {{ env('SITE_NAME') }}. 6 | To complete your account activation click the link below: 7 | 8 | {{ url('/activate/'.$code) }} 9 | 10 | If the link above does not work, copy and paste it into your browser's address bar. 11 | @endsection 12 | -------------------------------------------------------------------------------- /resources/views/emails/activate.blade.php: -------------------------------------------------------------------------------- 1 | @extends('emails.template') 2 | 3 | @section('content') 4 |

Hi,

5 |

Thank you for signing up on {{ env('SITE_NAME') }}.

6 |

To complete your account activation click the button below:

7 | @include('emails.blocks.call-to-action', ['cta_url'=>url('/activate/'.$code),'cta_text'=>'Activate Account']) 8 |

If the button above does not work, copy and paste the link below into your browser's address bar.

9 |

{{ url('/activate/'.$code) }}

10 | @endsection 11 | -------------------------------------------------------------------------------- /resources/views/emails/blocks/call-to-action.blade.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 13 | 14 | 15 |
5 | 6 | 7 | 8 | 9 | 10 | 11 |
{{ $cta_text }}
12 |
-------------------------------------------------------------------------------- /resources/views/emails/blocks/style.blade.php: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /resources/views/emails/template-plain.blade.php: -------------------------------------------------------------------------------- 1 | @section('content') 2 | Hi there, 3 | Sometimes you just want to send a simple HTML email with a simple design and clear call to action. This is it. 4 | 5 | CALL TO ACTION LINK 6 | 7 | This is a really simple email template. Its sole purpose is to get the recipient to click the button with no distractions. 8 | Good luck! Hope it works. 9 | @show 10 | 11 | @section('signature') 12 | Best Regards, 13 | {{ env('SITE_NAME') }} Team. 14 | @show 15 | 16 | @section('footer') 17 | Terms: {{ url('about/terms') }} 18 | Privacy: {{ url('about/privacy-policy') }} 19 | Unsubscribe: {{ url('email/unsubscribe?email='.$to) }} 20 | @show 21 | 22 | @section('disclaimer') 23 | This is a service email for "{{ $to }}" containing necessary account information. Please do not reply to this message. 24 | @show -------------------------------------------------------------------------------- /resources/views/emails/template.blade.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | {{ $subject }} 7 | @include('emails.blocks.style') 8 | 9 | 10 | 11 | 12 | 13 | 60 | 61 | 62 |
  14 |
15 | 16 | 17 | 36 | 37 |
18 | 19 | 20 | 33 | 34 |
21 | @section('content') 22 |

Hi there,

23 |

Sometimes you just want to send a simple HTML email with a simple design and clear call to action. This is it.

24 | @include('emails.blocks.call-to-action', ['cta_url'=>url('/'),'cta_text'=>'Call to Action']) 25 |

This is a really simple email template. Its sole purpose is to get the recipient to click the button with no distractions.

26 |

Good luck! Hope it works.

27 | @show 28 | @section('signature') 29 |

Best Regards,

30 |

{{ env('SITE_NAME') }} Team.

31 | @show 32 |
35 |
38 | 58 |
59 |
63 | 64 | -------------------------------------------------------------------------------- /resources/views/errors/402.blade.php: -------------------------------------------------------------------------------- 1 | @extends('errors.error') 2 | 3 | @section('page_title') 4 | @endsection 5 | 6 | @section('error_title') 7 | Error 402: {{ $exception->getMessage() ?: 'Limit Exceeded!' }} 8 | @endsection 9 | 10 | @section('error_message') 11 |

You have exceeded your limits.

12 | @endsection 13 | -------------------------------------------------------------------------------- /resources/views/errors/403.blade.php: -------------------------------------------------------------------------------- 1 | @extends('errors.error') 2 | 3 | @section('page_title') 4 | @endsection 5 | 6 | @section('error_title') 7 | Error 403: Access Denied! 8 | @endsection 9 | 10 | @section('error_message') 11 |

You are not authorized to access this page.

12 | @endsection 13 | -------------------------------------------------------------------------------- /resources/views/errors/404.blade.php: -------------------------------------------------------------------------------- 1 | @extends('errors.error') 2 | 3 | @section('page_title') 4 | @endsection 5 | 6 | @section('error_title') 7 | Error 404: Page not found! 8 | @endsection 9 | -------------------------------------------------------------------------------- /resources/views/errors/500.blade.php: -------------------------------------------------------------------------------- 1 | @extends('errors.error') 2 | 3 | @section('page_title') 4 | @endsection 5 | 6 | @section('error_title') 7 | Error 500: Internal Server Error! 8 | @endsection 9 | 10 | @section('error_message') 11 |

Our server encountered an internal error.
Error has been logged and reported to the System Administrator.

12 | @endsection 13 | -------------------------------------------------------------------------------- /resources/views/errors/503.blade.php: -------------------------------------------------------------------------------- 1 | @extends('errors.error') 2 | 3 | @section('page_title') 4 | @endsection 5 | 6 | @section('content') 7 |
8 |
9 |

Temporarily down for maintenance!

10 |
11 |

The hamsters powering our server are taking a break.
They should be back in couple of minutes.

12 |
13 |
14 | @endsection 15 | -------------------------------------------------------------------------------- /resources/views/errors/error.blade.php: -------------------------------------------------------------------------------- 1 | @extends('layouts.app') 2 | 3 | @section('content') 4 |
5 |
6 |
7 |

8 | @section('error_title') 9 | {{ meta()->pageTitle() }}: Page not found! 10 | @show 11 |

12 |
13 | @section('error_message') 14 |

The requested URL was not found on this server. Make sure that the Web site address displayed in the address bar of your browser is spelled and formatted correctly.

15 | @show 16 |

17 | @section('button_back') 18 | Go Back 19 | @show 20 | @section('button_home') 21 | Go to Home Page 22 | @show 23 |

24 |
25 |
26 |
27 | @endsection -------------------------------------------------------------------------------- /resources/views/home.blade.php: -------------------------------------------------------------------------------- 1 | @extends('layouts.app') 2 | 3 | @section('content') 4 |
5 |

Upload and share images securely with {{ env('SITE_NAME') }}!

6 |

Select the images and click upload.

7 | 8 | {!! Form::open(['files'=>true, 'url'=>url('image/create'), 'id'=>'form_upload', 'class' => 'form-horizontal', 'role'=>'form']) !!} 9 | 10 |
11 |
12 |
13 |
14 |
15 | 16 |
17 |
18 | {!! Form::text('title', null, ['class' => 'form-control', 'placeholder'=>'Image/Album Title']) !!} 19 |
20 |
21 | 22 |
23 |
24 | {!! Form::textarea('description', null, ['class' => 'form-control', 'rows'=>'3', 'placeholder'=>'Image/Album Description']) !!} 25 |
26 |
27 | 28 |
29 |
30 |
31 |
32 |
33 |
34 |

Is this image Safe for Work?

35 |
36 |
37 |
38 |
39 | 40 |
41 |
42 | 43 |
44 |

Should this image be hidden from search engines?

45 |
46 | 47 |
48 |
49 |
50 | {!! Form::select('expire', [ 51 | 0 => 'Never', 52 | 10 => '10 Minutes', 53 | 60 => '1 Hour', 54 | 1440 => '1 Day', 55 | 10080 => '1 Week', 56 | 43800 => '1 Month', 57 | ], null, ['class'=>'form-control']) !!} 58 |
59 |
60 |

This image will be deleted after?

61 |
62 |
63 | 64 |
65 |
66 | {!! Form::submit('Upload', ['id'=>'btn_upload', 'class'=>'btn btn-info']) !!} 67 |
68 |
69 | 70 | {!! Form::close() !!} 71 |
72 | @include('blocks.fineuploader') 73 | @endsection 74 | -------------------------------------------------------------------------------- /resources/views/image.blade.php: -------------------------------------------------------------------------------- 1 | @extends('layouts.app') 2 | 3 | @section('header_css') 4 | 5 | 6 | 7 | 8 | 9 | @endsection 10 | 11 | @section('content') 12 |

{{ meta()->pageTitle() }}

13 | @if(!empty($image->image_description)) 14 |

{{ $image->image_description }}

15 | @endif 16 |
17 |
18 | 19 |
20 |
21 | 22 |
23 | 24 |
25 |
26 | 27 | @include('blocks.embed') 28 | @endsection 29 | -------------------------------------------------------------------------------- /resources/views/layouts/app.blade.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | {{ meta()->metaTitle() }} 10 | @if(meta()->description()) 11 | 12 | @endif 13 | 14 | @yield('header_css') 15 | 16 | 17 | 18 |
19 | @include('layouts.blocks.nav') 20 |
21 | 22 |
23 | @include('layouts.blocks.notifications') 24 | @yield('content') 25 |
26 | 27 | @include('layouts.blocks.footer') 28 | 29 | 30 | @yield('footer_js') 31 | 32 | 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /resources/views/layouts/blocks/footer.blade.php: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /resources/views/layouts/blocks/nav.blade.php: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /resources/views/layouts/blocks/notifications.blade.php: -------------------------------------------------------------------------------- 1 | @if (!empty($errors) && count($errors->all()) > 0) 2 |
3 | 4 |

Please check the form below for errors

5 |
6 | @endif 7 | 8 | @if($flash_message = session()->get('flash_message')) 9 |
10 | 11 |

{{ $flash_message['message'] }}

12 |
13 | @endif -------------------------------------------------------------------------------- /resources/views/my/albums.blade.php: -------------------------------------------------------------------------------- 1 | @extends('layouts.app') 2 | 3 | @section('content') 4 |

{{ meta()->pageTitle() }}

5 |
6 | @if($albums->count()) 7 | @foreach($albums as $album) 8 |
9 | 10 |

11 | {{ ($album->album_title ? $album->album_title : 'Album '.$album->hash) }} 12 | ({{ $album->images->count() }} Images) 13 |

14 | @foreach($album->images->slice(0,6) as $image) 15 | 16 | @endforeach 17 |

{{ $album->album_description or '' }}

18 |
19 | @endforeach 20 | @endif 21 |
22 |
{!! $albums->render() !!}
23 | @endsection -------------------------------------------------------------------------------- /resources/views/my/images.blade.php: -------------------------------------------------------------------------------- 1 | @extends('layouts.app') 2 | 3 | @section('content') 4 |

{{ meta()->pageTitle() }}

5 |
6 | @if($images->count()) 7 |
8 | @foreach($images as $image) 9 |
10 | {{ $image->image_title }} 11 | 12 |
13 | @endforeach 14 |
15 |
16 | @endif 17 |
18 |
{!! $images->render() !!}
19 | @endsection -------------------------------------------------------------------------------- /resources/views/my/index.blade.php: -------------------------------------------------------------------------------- 1 | @extends('layouts.app') 2 | 3 | @section('content') 4 |
5 |

{{ meta()->pageTitle() }}

6 |
7 |

Albums : {{ $albums }}

8 |

Images : {{ $images }}

9 |
10 |
11 | @endsection -------------------------------------------------------------------------------- /routes/api.php: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bhutanio/imagehost/341714ad285b224a128602709f924aa1d61d1b86/routes/api.php -------------------------------------------------------------------------------- /routes/channels.php: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bhutanio/imagehost/341714ad285b224a128602709f924aa1d61d1b86/routes/channels.php -------------------------------------------------------------------------------- /routes/console.php: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bhutanio/imagehost/341714ad285b224a128602709f924aa1d61d1b86/routes/console.php -------------------------------------------------------------------------------- /routes/static.php: -------------------------------------------------------------------------------- 1 | 'auth'], function () { 4 | Route::group(['prefix' => 'my'], function () { 5 | Route::get('/', 'My\MyImagesController@index'); 6 | Route::get('albums', 'My\MyImagesController@albums'); 7 | Route::get('images', 'My\MyImagesController@images'); 8 | }); 9 | 10 | Route::group(['prefix' => 'admin', 'middleware' => 'admin'], function () { 11 | Route::get('/', 'Admin\AdminImagesController@index'); 12 | Route::get('albums', 'Admin\AdminImagesController@albums'); 13 | Route::get('images', 'Admin\AdminImagesController@images'); 14 | }); 15 | }); 16 | 17 | Auth::routes(); 18 | Route::get('activate/{token}', 'Auth\ActivationController@activate'); 19 | 20 | Route::post('image/upload', 'Image\UploadImageController@ajaxUpload')->middleware(['ajax']); 21 | Route::delete('image/delete', 'Image\UploadImageController@ajaxDelete')->middleware(['ajax']); 22 | 23 | Route::post('image/create', 'Image\UploadImageController@create'); 24 | 25 | Route::get('/', 'HomeController@index'); 26 | -------------------------------------------------------------------------------- /server.php: -------------------------------------------------------------------------------- 1 | 8 | */ 9 | 10 | $uri = urldecode( 11 | parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH) 12 | ); 13 | 14 | // This file allows us to emulate Apache's "mod_rewrite" functionality from the 15 | // built-in PHP web server. This provides a convenient way to test a Laravel 16 | // application without having installed a "real" web server software here. 17 | if ($uri !== '/' && file_exists(__DIR__.'/public'.$uri)) { 18 | return false; 19 | } 20 | 21 | require_once __DIR__.'/public/index.php'; 22 | -------------------------------------------------------------------------------- /storage/app/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !public/ 3 | !.gitignore 4 | -------------------------------------------------------------------------------- /storage/app/public/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | -------------------------------------------------------------------------------- /storage/debugbar/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore -------------------------------------------------------------------------------- /storage/framework/.gitignore: -------------------------------------------------------------------------------- 1 | config.php 2 | routes.php 3 | schedule-* 4 | compiled.php 5 | services.json 6 | events.scanned.php 7 | routes.scanned.php 8 | down 9 | -------------------------------------------------------------------------------- /storage/framework/cache/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | -------------------------------------------------------------------------------- /storage/framework/sessions/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | -------------------------------------------------------------------------------- /storage/framework/testing/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | -------------------------------------------------------------------------------- /storage/framework/views/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | -------------------------------------------------------------------------------- /storage/geoip/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore -------------------------------------------------------------------------------- /storage/logs/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | -------------------------------------------------------------------------------- /tests/CreatesApplication.php: -------------------------------------------------------------------------------- 1 | make(Kernel::class)->bootstrap(); 19 | 20 | return $app; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /tests/Feature/ExampleTest.php: -------------------------------------------------------------------------------- 1 | get('/'); 20 | 21 | $response->assertStatus(200); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /tests/TestCase.php: -------------------------------------------------------------------------------- 1 | assertTrue(true); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /webpack.mix.js: -------------------------------------------------------------------------------- 1 | const {mix} = require('laravel-mix'); 2 | 3 | /* 4 | |-------------------------------------------------------------------------- 5 | | Mix Asset Management 6 | |-------------------------------------------------------------------------- 7 | | 8 | | Mix provides a clean, fluent API for defining some Webpack build steps 9 | | for your Laravel application. By default, we are compiling the Sass 10 | | file for the application as well as bundling up all the JS files. 11 | | 12 | */ 13 | 14 | mix.js('resources/assets/js/app.js', 'public/js') 15 | .sass('resources/assets/sass/app.scss', 'public/css') 16 | .version(); 17 | --------------------------------------------------------------------------------